mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge pull request #403 from Dokploy/98-connect-multiple-github-organizations
Feat(Git Providers): support for github, gitlab, bitbucket
This commit is contained in:
3116
apps/docs/api.json
3116
apps/docs/api.json
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,11 @@
|
|||||||
"reference-api/reference-registry",
|
"reference-api/reference-registry",
|
||||||
"reference-api/reference-security",
|
"reference-api/reference-security",
|
||||||
"reference-api/reference-settings",
|
"reference-api/reference-settings",
|
||||||
|
"reference-api/reference-sshKey",
|
||||||
|
"reference-api/reference-gitProvider",
|
||||||
|
"reference-api/reference-bitbucket",
|
||||||
|
"reference-api/reference-github",
|
||||||
|
"reference-api/reference-gitlab",
|
||||||
"reference-api/reference-user"
|
"reference-api/reference-user"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"email"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"email"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Format: `"email"`</span>
|
<span>Format: `"email"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"authId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"authId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -320,7 +320,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"token"} type={"string"} required={true} deprecated={false}>
|
<Property name={"token"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"userId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"userId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -439,11 +439,11 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"accesedProjects"} type={"array of string"} required={true} deprecated={undefined}>
|
<Property name={"accesedProjects"} type={"array<string>"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"accesedServices"} type={"array of string"} required={true} deprecated={undefined}>
|
<Property name={"accesedServices"} type={"array<string>"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -459,6 +459,14 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"canAccessToSSHKeys"} type={"boolean"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"canAccessToGitProviders"} type={"boolean"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
| ----------- | ----------- |
|
| ----------- | ----------- |
|
||||||
| `200` | Successful response |
|
| `200` | Successful response |
|
||||||
@@ -488,7 +496,9 @@ curl -X POST "http://localhost:3000/api/admin.assignPermissions" \
|
|||||||
],
|
],
|
||||||
"canAccessToTraefikFiles": true,
|
"canAccessToTraefikFiles": true,
|
||||||
"canAccessToDocker": true,
|
"canAccessToDocker": true,
|
||||||
"canAccessToAPI": true
|
"canAccessToAPI": true,
|
||||||
|
"canAccessToSSHKeys": true,
|
||||||
|
"canAccessToGitProviders": true
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -552,382 +562,4 @@ export interface Response {
|
|||||||
|
|
||||||
</API>
|
</API>
|
||||||
|
|
||||||
<API>
|
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/admin.cleanGithubApp"}>
|
|
||||||
|
|
||||||
## admin-cleanGithubApp
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
|
||||||
|
|
||||||
In: `header`
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
| Status code | Description |
|
|
||||||
| ----------- | ----------- |
|
|
||||||
| `200` | Successful response |
|
|
||||||
| `default` | Error response |
|
|
||||||
|
|
||||||
</APIInfo>
|
|
||||||
|
|
||||||
<APIExample>
|
|
||||||
|
|
||||||
<Requests items={["cURL","JavaScript"]}>
|
|
||||||
|
|
||||||
<Request value={"cURL"}>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://localhost:3000/api/admin.cleanGithubApp"
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
<Request value={"JavaScript"}>
|
|
||||||
|
|
||||||
```js
|
|
||||||
fetch("http://localhost:3000/api/admin.cleanGithubApp", {
|
|
||||||
method: "POST"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
</Requests>
|
|
||||||
|
|
||||||
<Responses items={["default"]}>
|
|
||||||
|
|
||||||
<Response value={"default"}>
|
|
||||||
|
|
||||||
<ResponseTypes>
|
|
||||||
|
|
||||||
<ExampleResponse>
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "string",
|
|
||||||
"code": "string",
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"message": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</ExampleResponse>
|
|
||||||
|
|
||||||
<TypeScriptResponse>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface Response {
|
|
||||||
message: string;
|
|
||||||
code: string;
|
|
||||||
issues?: {
|
|
||||||
message: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TypeScriptResponse>
|
|
||||||
|
|
||||||
</ResponseTypes>
|
|
||||||
|
|
||||||
</Response>
|
|
||||||
|
|
||||||
</Responses>
|
|
||||||
|
|
||||||
</APIExample>
|
|
||||||
|
|
||||||
</API>
|
|
||||||
|
|
||||||
<API>
|
|
||||||
|
|
||||||
<APIInfo method={"GET"} route={"/admin.getRepositories"}>
|
|
||||||
|
|
||||||
## admin-getRepositories
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
|
||||||
|
|
||||||
In: `header`
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
| Status code | Description |
|
|
||||||
| ----------- | ----------- |
|
|
||||||
| `200` | Successful response |
|
|
||||||
| `default` | Error response |
|
|
||||||
|
|
||||||
</APIInfo>
|
|
||||||
|
|
||||||
<APIExample>
|
|
||||||
|
|
||||||
<Requests items={["cURL","JavaScript"]}>
|
|
||||||
|
|
||||||
<Request value={"cURL"}>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X GET "http://localhost:3000/api/admin.getRepositories"
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
<Request value={"JavaScript"}>
|
|
||||||
|
|
||||||
```js
|
|
||||||
fetch("http://localhost:3000/api/admin.getRepositories", {
|
|
||||||
method: "GET"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
</Requests>
|
|
||||||
|
|
||||||
<Responses items={["default"]}>
|
|
||||||
|
|
||||||
<Response value={"default"}>
|
|
||||||
|
|
||||||
<ResponseTypes>
|
|
||||||
|
|
||||||
<ExampleResponse>
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "string",
|
|
||||||
"code": "string",
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"message": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</ExampleResponse>
|
|
||||||
|
|
||||||
<TypeScriptResponse>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface Response {
|
|
||||||
message: string;
|
|
||||||
code: string;
|
|
||||||
issues?: {
|
|
||||||
message: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TypeScriptResponse>
|
|
||||||
|
|
||||||
</ResponseTypes>
|
|
||||||
|
|
||||||
</Response>
|
|
||||||
|
|
||||||
</Responses>
|
|
||||||
|
|
||||||
</APIExample>
|
|
||||||
|
|
||||||
</API>
|
|
||||||
|
|
||||||
<API>
|
|
||||||
|
|
||||||
<APIInfo method={"GET"} route={"/admin.getBranches"}>
|
|
||||||
|
|
||||||
## admin-getBranches
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
|
||||||
|
|
||||||
In: `header`
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
### Query Parameters
|
|
||||||
|
|
||||||
<Property name={"repo"} type={"string"} required={true} deprecated={false}>
|
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
<Property name={"owner"} type={"string"} required={true} deprecated={false}>
|
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
| Status code | Description |
|
|
||||||
| ----------- | ----------- |
|
|
||||||
| `200` | Successful response |
|
|
||||||
| `default` | Error response |
|
|
||||||
|
|
||||||
</APIInfo>
|
|
||||||
|
|
||||||
<APIExample>
|
|
||||||
|
|
||||||
<Requests items={["cURL","JavaScript"]}>
|
|
||||||
|
|
||||||
<Request value={"cURL"}>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X GET "http://localhost:3000/api/admin.getBranches?repo=string&owner=string"
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
<Request value={"JavaScript"}>
|
|
||||||
|
|
||||||
```js
|
|
||||||
fetch("http://localhost:3000/api/admin.getBranches?repo=string&owner=string", {
|
|
||||||
method: "GET"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
</Requests>
|
|
||||||
|
|
||||||
<Responses items={["default"]}>
|
|
||||||
|
|
||||||
<Response value={"default"}>
|
|
||||||
|
|
||||||
<ResponseTypes>
|
|
||||||
|
|
||||||
<ExampleResponse>
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "string",
|
|
||||||
"code": "string",
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"message": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</ExampleResponse>
|
|
||||||
|
|
||||||
<TypeScriptResponse>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface Response {
|
|
||||||
message: string;
|
|
||||||
code: string;
|
|
||||||
issues?: {
|
|
||||||
message: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TypeScriptResponse>
|
|
||||||
|
|
||||||
</ResponseTypes>
|
|
||||||
|
|
||||||
</Response>
|
|
||||||
|
|
||||||
</Responses>
|
|
||||||
|
|
||||||
</APIExample>
|
|
||||||
|
|
||||||
</API>
|
|
||||||
|
|
||||||
<API>
|
|
||||||
|
|
||||||
<APIInfo method={"GET"} route={"/admin.haveGithubConfigured"}>
|
|
||||||
|
|
||||||
## admin-haveGithubConfigured
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
|
||||||
|
|
||||||
In: `header`
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
| Status code | Description |
|
|
||||||
| ----------- | ----------- |
|
|
||||||
| `200` | Successful response |
|
|
||||||
| `default` | Error response |
|
|
||||||
|
|
||||||
</APIInfo>
|
|
||||||
|
|
||||||
<APIExample>
|
|
||||||
|
|
||||||
<Requests items={["cURL","JavaScript"]}>
|
|
||||||
|
|
||||||
<Request value={"cURL"}>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X GET "http://localhost:3000/api/admin.haveGithubConfigured"
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
<Request value={"JavaScript"}>
|
|
||||||
|
|
||||||
```js
|
|
||||||
fetch("http://localhost:3000/api/admin.haveGithubConfigured", {
|
|
||||||
method: "GET"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
</Requests>
|
|
||||||
|
|
||||||
<Responses items={["default"]}>
|
|
||||||
|
|
||||||
<Response value={"default"}>
|
|
||||||
|
|
||||||
<ResponseTypes>
|
|
||||||
|
|
||||||
<ExampleResponse>
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "string",
|
|
||||||
"code": "string",
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"message": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</ExampleResponse>
|
|
||||||
|
|
||||||
<TypeScriptResponse>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface Response {
|
|
||||||
message: string;
|
|
||||||
code: string;
|
|
||||||
issues?: {
|
|
||||||
message: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TypeScriptResponse>
|
|
||||||
|
|
||||||
</ResponseTypes>
|
|
||||||
|
|
||||||
</Response>
|
|
||||||
|
|
||||||
</Responses>
|
|
||||||
|
|
||||||
</APIExample>
|
|
||||||
|
|
||||||
</API>
|
|
||||||
|
|
||||||
</Root>
|
</Root>
|
||||||
@@ -25,7 +25,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -750,6 +750,10 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"buildArgs"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
| ----------- | ----------- |
|
| ----------- | ----------- |
|
||||||
| `200` | Successful response |
|
| `200` | Successful response |
|
||||||
@@ -767,7 +771,8 @@ In: `header`
|
|||||||
curl -X POST "http://localhost:3000/api/application.saveEnvironment" \
|
curl -X POST "http://localhost:3000/api/application.saveEnvironment" \
|
||||||
-d '{
|
-d '{
|
||||||
"applicationId": "string",
|
"applicationId": "string",
|
||||||
"env": "string"
|
"env": "string",
|
||||||
|
"buildArgs": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -853,7 +858,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"buildType"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"buildType"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"dockerfile" | "heroku_buildpacks" | "paketo_buildpacks" | "nixpacks"`</span>
|
<span>Value in: `"dockerfile" | "heroku_buildpacks" | "paketo_buildpacks" | "nixpacks" | "static"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -861,6 +866,14 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"dockerContextPath"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"publishDirectory"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
| ----------- | ----------- |
|
| ----------- | ----------- |
|
||||||
| `200` | Successful response |
|
| `200` | Successful response |
|
||||||
@@ -879,7 +892,9 @@ curl -X POST "http://localhost:3000/api/application.saveBuildType" \
|
|||||||
-d '{
|
-d '{
|
||||||
"applicationId": "string",
|
"applicationId": "string",
|
||||||
"buildType": "dockerfile",
|
"buildType": "dockerfile",
|
||||||
"dockerfile": "string"
|
"dockerfile": "string",
|
||||||
|
"dockerContextPath": "string",
|
||||||
|
"publishDirectory": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -979,6 +994,10 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubId"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
| ----------- | ----------- |
|
| ----------- | ----------- |
|
||||||
| `200` | Successful response |
|
| `200` | Successful response |
|
||||||
@@ -999,7 +1018,8 @@ curl -X POST "http://localhost:3000/api/application.saveGithubProvider" \
|
|||||||
"repository": "string",
|
"repository": "string",
|
||||||
"branch": "string",
|
"branch": "string",
|
||||||
"owner": "string",
|
"owner": "string",
|
||||||
"buildPath": "string"
|
"buildPath": "string",
|
||||||
|
"githubId": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1065,6 +1085,266 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/application.saveGitlabProvider"}>
|
||||||
|
|
||||||
|
## application-saveGitlabProvider
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabBranch"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabBuildPath"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabOwner"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabRepository"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabProjectId"} type={"number | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabPathNamespace"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/application.saveGitlabProvider" \
|
||||||
|
-d '{
|
||||||
|
"applicationId": "string",
|
||||||
|
"gitlabBranch": "string",
|
||||||
|
"gitlabBuildPath": "string",
|
||||||
|
"gitlabOwner": "string",
|
||||||
|
"gitlabRepository": "string",
|
||||||
|
"gitlabId": "string",
|
||||||
|
"gitlabProjectId": 0,
|
||||||
|
"gitlabPathNamespace": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/application.saveGitlabProvider", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/application.saveBitbucketProvider"}>
|
||||||
|
|
||||||
|
## application-saveBitbucketProvider
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"bitbucketBranch"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketBuildPath"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketOwner"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketRepository"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string | null"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/application.saveBitbucketProvider" \
|
||||||
|
-d '{
|
||||||
|
"bitbucketBranch": "string",
|
||||||
|
"bitbucketBuildPath": "string",
|
||||||
|
"bitbucketOwner": "string",
|
||||||
|
"bitbucketRepository": "string",
|
||||||
|
"bitbucketId": "string",
|
||||||
|
"applicationId": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/application.saveBitbucketProvider", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/application.saveDockerProvider"}>
|
<APIInfo method={"POST"} route={"/application.saveDockerProvider"}>
|
||||||
|
|
||||||
## application-saveDockerProvider
|
## application-saveDockerProvider
|
||||||
@@ -1210,6 +1490,10 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"customGitSSHKeyId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
| ----------- | ----------- |
|
| ----------- | ----------- |
|
||||||
| `200` | Successful response |
|
| `200` | Successful response |
|
||||||
@@ -1229,7 +1513,8 @@ curl -X POST "http://localhost:3000/api/application.saveGitProdiver" \
|
|||||||
"customGitBranch": "string",
|
"customGitBranch": "string",
|
||||||
"applicationId": "string",
|
"applicationId": "string",
|
||||||
"customGitBuildPath": "string",
|
"customGitBuildPath": "string",
|
||||||
"customGitUrl": "string"
|
"customGitUrl": "string",
|
||||||
|
"customGitSSHKeyId": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1295,206 +1580,6 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/application.generateSSHKey"}>
|
|
||||||
|
|
||||||
## application-generateSSHKey
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
|
||||||
|
|
||||||
In: `header`
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
### Request Body
|
|
||||||
|
|
||||||
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
| Status code | Description |
|
|
||||||
| ----------- | ----------- |
|
|
||||||
| `200` | Successful response |
|
|
||||||
| `default` | Error response |
|
|
||||||
|
|
||||||
</APIInfo>
|
|
||||||
|
|
||||||
<APIExample>
|
|
||||||
|
|
||||||
<Requests items={["cURL","JavaScript"]}>
|
|
||||||
|
|
||||||
<Request value={"cURL"}>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://localhost:3000/api/application.generateSSHKey" \
|
|
||||||
-d '{
|
|
||||||
"applicationId": "string"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
<Request value={"JavaScript"}>
|
|
||||||
|
|
||||||
```js
|
|
||||||
fetch("http://localhost:3000/api/application.generateSSHKey", {
|
|
||||||
method: "POST"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
</Requests>
|
|
||||||
|
|
||||||
<Responses items={["default"]}>
|
|
||||||
|
|
||||||
<Response value={"default"}>
|
|
||||||
|
|
||||||
<ResponseTypes>
|
|
||||||
|
|
||||||
<ExampleResponse>
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "string",
|
|
||||||
"code": "string",
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"message": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</ExampleResponse>
|
|
||||||
|
|
||||||
<TypeScriptResponse>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface Response {
|
|
||||||
message: string;
|
|
||||||
code: string;
|
|
||||||
issues?: {
|
|
||||||
message: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TypeScriptResponse>
|
|
||||||
|
|
||||||
</ResponseTypes>
|
|
||||||
|
|
||||||
</Response>
|
|
||||||
|
|
||||||
</Responses>
|
|
||||||
|
|
||||||
</APIExample>
|
|
||||||
|
|
||||||
</API>
|
|
||||||
|
|
||||||
<API>
|
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/application.removeSSHKey"}>
|
|
||||||
|
|
||||||
## application-removeSSHKey
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
|
||||||
|
|
||||||
In: `header`
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
### Request Body
|
|
||||||
|
|
||||||
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
| Status code | Description |
|
|
||||||
| ----------- | ----------- |
|
|
||||||
| `200` | Successful response |
|
|
||||||
| `default` | Error response |
|
|
||||||
|
|
||||||
</APIInfo>
|
|
||||||
|
|
||||||
<APIExample>
|
|
||||||
|
|
||||||
<Requests items={["cURL","JavaScript"]}>
|
|
||||||
|
|
||||||
<Request value={"cURL"}>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://localhost:3000/api/application.removeSSHKey" \
|
|
||||||
-d '{
|
|
||||||
"applicationId": "string"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
<Request value={"JavaScript"}>
|
|
||||||
|
|
||||||
```js
|
|
||||||
fetch("http://localhost:3000/api/application.removeSSHKey", {
|
|
||||||
method: "POST"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
</Requests>
|
|
||||||
|
|
||||||
<Responses items={["default"]}>
|
|
||||||
|
|
||||||
<Response value={"default"}>
|
|
||||||
|
|
||||||
<ResponseTypes>
|
|
||||||
|
|
||||||
<ExampleResponse>
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "string",
|
|
||||||
"code": "string",
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"message": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</ExampleResponse>
|
|
||||||
|
|
||||||
<TypeScriptResponse>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface Response {
|
|
||||||
message: string;
|
|
||||||
code: string;
|
|
||||||
issues?: {
|
|
||||||
message: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TypeScriptResponse>
|
|
||||||
|
|
||||||
</ResponseTypes>
|
|
||||||
|
|
||||||
</Response>
|
|
||||||
|
|
||||||
</Responses>
|
|
||||||
|
|
||||||
</APIExample>
|
|
||||||
|
|
||||||
</API>
|
|
||||||
|
|
||||||
<API>
|
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/application.markRunning"}>
|
<APIInfo method={"POST"} route={"/application.markRunning"}>
|
||||||
|
|
||||||
## application-markRunning
|
## application-markRunning
|
||||||
@@ -1611,13 +1696,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1633,6 +1718,10 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"buildArgs"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
<Property name={"memoryReservation"} type={"number | null"} required={false} deprecated={undefined}>
|
<Property name={"memoryReservation"} type={"number | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
@@ -1671,7 +1760,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"sourceType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"sourceType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"github" | "docker" | "git"`</span>
|
<span>Value in: `"github" | "docker" | "git"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1695,6 +1784,46 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabProjectId"} type={"number | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabRepository"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabOwner"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabBranch"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabBuildPath"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabPathNamespace"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketRepository"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketOwner"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketBranch"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketBuildPath"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
<Property name={"username"} type={"string | null"} required={false} deprecated={undefined}>
|
<Property name={"username"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
@@ -1719,7 +1848,7 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"customGitSSHKey"} type={"string | null"} required={false} deprecated={undefined}>
|
<Property name={"customGitSSHKeyId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1727,11 +1856,19 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"dockerContextPath"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"dropBuildPath"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
<Property name={"healthCheckSwarm"} type={"object | null"} required={false} deprecated={undefined}>
|
<Property name={"healthCheckSwarm"} type={"object | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<ObjectCollapsible name={"healthCheckSwarm"}>
|
<ObjectCollapsible name={"healthCheckSwarm"}>
|
||||||
|
|
||||||
<Property name={"Test"} type={"array of string"} required={false} deprecated={undefined}>
|
<Property name={"Test"} type={"array<string>"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1783,13 +1920,13 @@ In: `header`
|
|||||||
|
|
||||||
<ObjectCollapsible name={"placementSwarm"}>
|
<ObjectCollapsible name={"placementSwarm"}>
|
||||||
|
|
||||||
<Property name={"Constraints"} type={"array of string"} required={false} deprecated={undefined}>
|
<Property name={"Constraints"} type={"array<string>"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"Preferences"} type={"array of object"} required={false} deprecated={undefined}>
|
<Property name={"Preferences"} type={"array<object>"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<ObjectCollapsible name={"Preferences"}>
|
<ObjectCollapsible name={"Object 1"}>
|
||||||
|
|
||||||
<Property name={"Spread"} type={"object"} required={true} deprecated={undefined}>
|
<Property name={"Spread"} type={"object"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
@@ -1811,9 +1948,9 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"Platforms"} type={"array of object"} required={false} deprecated={undefined}>
|
<Property name={"Platforms"} type={"array<object>"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<ObjectCollapsible name={"Platforms"}>
|
<ObjectCollapsible name={"Object 1"}>
|
||||||
|
|
||||||
<Property name={"Architecture"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"Architecture"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
@@ -1959,15 +2096,15 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"networkSwarm"} type={"array of object | null"} required={false} deprecated={undefined}>
|
<Property name={"networkSwarm"} type={"array<object> | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<ObjectCollapsible name={"networkSwarm"}>
|
<ObjectCollapsible name={"Object 1"}>
|
||||||
|
|
||||||
<Property name={"Target"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"Target"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"Aliases"} type={"array of string"} required={false} deprecated={undefined}>
|
<Property name={"Aliases"} type={"array<string>"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1989,13 +2126,17 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"buildType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"buildType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"dockerfile" | "heroku_buildpacks" | "paketo_buildpacks" | "nixpacks"`</span>
|
<span>Value in: `"dockerfile" | "heroku_buildpacks" | "paketo_buildpacks" | "nixpacks" | "static"`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"publishDirectory"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -2011,6 +2152,18 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
| ----------- | ----------- |
|
| ----------- | ----------- |
|
||||||
| `200` | Successful response |
|
| `200` | Successful response |
|
||||||
@@ -2032,6 +2185,7 @@ curl -X POST "http://localhost:3000/api/application.update" \
|
|||||||
"appName": "string",
|
"appName": "string",
|
||||||
"description": "string",
|
"description": "string",
|
||||||
"env": "string",
|
"env": "string",
|
||||||
|
"buildArgs": "string",
|
||||||
"memoryReservation": 0,
|
"memoryReservation": 0,
|
||||||
"memoryLimit": 0,
|
"memoryLimit": 0,
|
||||||
"cpuReservation": 0,
|
"cpuReservation": 0,
|
||||||
@@ -2047,14 +2201,26 @@ curl -X POST "http://localhost:3000/api/application.update" \
|
|||||||
"branch": "string",
|
"branch": "string",
|
||||||
"buildPath": "string",
|
"buildPath": "string",
|
||||||
"autoDeploy": true,
|
"autoDeploy": true,
|
||||||
|
"gitlabProjectId": 0,
|
||||||
|
"gitlabRepository": "string",
|
||||||
|
"gitlabOwner": "string",
|
||||||
|
"gitlabBranch": "string",
|
||||||
|
"gitlabBuildPath": "string",
|
||||||
|
"gitlabPathNamespace": "string",
|
||||||
|
"bitbucketRepository": "string",
|
||||||
|
"bitbucketOwner": "string",
|
||||||
|
"bitbucketBranch": "string",
|
||||||
|
"bitbucketBuildPath": "string",
|
||||||
"username": "string",
|
"username": "string",
|
||||||
"password": "string",
|
"password": "string",
|
||||||
"dockerImage": "string",
|
"dockerImage": "string",
|
||||||
"customGitUrl": "string",
|
"customGitUrl": "string",
|
||||||
"customGitBranch": "string",
|
"customGitBranch": "string",
|
||||||
"customGitBuildPath": "string",
|
"customGitBuildPath": "string",
|
||||||
"customGitSSHKey": "string",
|
"customGitSSHKeyId": "string",
|
||||||
"dockerfile": "string",
|
"dockerfile": "string",
|
||||||
|
"dockerContextPath": "string",
|
||||||
|
"dropBuildPath": "string",
|
||||||
"healthCheckSwarm": {
|
"healthCheckSwarm": {
|
||||||
"Test": [
|
"Test": [
|
||||||
"string"
|
"string"
|
||||||
@@ -2132,9 +2298,13 @@ curl -X POST "http://localhost:3000/api/application.update" \
|
|||||||
"replicas": 0,
|
"replicas": 0,
|
||||||
"applicationStatus": "idle",
|
"applicationStatus": "idle",
|
||||||
"buildType": "dockerfile",
|
"buildType": "dockerfile",
|
||||||
|
"publishDirectory": "string",
|
||||||
"createdAt": "string",
|
"createdAt": "string",
|
||||||
"registryId": "string",
|
"registryId": "string",
|
||||||
"projectId": "string"
|
"projectId": "string",
|
||||||
|
"githubId": "string",
|
||||||
|
"gitlabId": "string",
|
||||||
|
"bitbucketId": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"email"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"email"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Format: `"email"`</span>
|
<span>Format: `"email"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `8`</span>
|
<span>Minimum length: `8`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `8`</span>
|
<span>Minimum length: `8`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"token"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"token"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -248,13 +248,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"email"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"email"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Format: `"email"`</span>
|
<span>Format: `"email"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `8`</span>
|
<span>Minimum length: `8`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -551,7 +551,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"rol"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"rol"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"admin" | "user"`</span>
|
<span>Value in: `"admin" | "user"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -869,7 +869,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"id"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"id"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -883,7 +883,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"rol"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"rol"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"admin" | "user"`</span>
|
<span>Value in: `"admin" | "user"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1104,13 +1104,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"pin"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"pin"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `6`</span>
|
<span>Minimum length: `6`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"secret"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"secret"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1213,7 +1213,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"pin"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"pin"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `6`</span>
|
<span>Minimum length: `6`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"prefix"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"prefix"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"database"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"database"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseType"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"databaseType"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"postgres" | "mariadb" | "mysql" | "mongo"`</span>
|
<span>Value in: `"postgres" | "mariadb" | "mysql" | "mongo"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"prefix"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"prefix"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"database"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"database"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
779
apps/docs/content/docs/api/reference-api/reference-bitbucket.mdx
Normal file
779
apps/docs/content/docs/api/reference-api/reference-bitbucket.mdx
Normal file
@@ -0,0 +1,779 @@
|
|||||||
|
---
|
||||||
|
title: bitbucket
|
||||||
|
full: true
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Root, API, APIInfo, APIExample, Responses, Response, ResponseTypes, ExampleResponse, TypeScriptResponse, Property, ObjectCollapsible, Requests, Request } from "fumadocs-ui/components/api";
|
||||||
|
|
||||||
|
<Root>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/bitbucket.create"}>
|
||||||
|
|
||||||
|
## bitbucket-create
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketUsername"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"appPassword"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketWorkspaceName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitProviderId"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"authId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/bitbucket.create" \
|
||||||
|
-d '{
|
||||||
|
"bitbucketId": "string",
|
||||||
|
"bitbucketUsername": "string",
|
||||||
|
"appPassword": "string",
|
||||||
|
"bitbucketWorkspaceName": "string",
|
||||||
|
"gitProviderId": "string",
|
||||||
|
"authId": "string",
|
||||||
|
"name": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/bitbucket.create", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/bitbucket.one"}>
|
||||||
|
|
||||||
|
## bitbucket-one
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/bitbucket.one?bitbucketId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/bitbucket.one?bitbucketId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/bitbucket.bitbucketProviders"}>
|
||||||
|
|
||||||
|
## bitbucket-bitbucketProviders
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/bitbucket.bitbucketProviders"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/bitbucket.bitbucketProviders", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/bitbucket.getBitbucketRepositories"}>
|
||||||
|
|
||||||
|
## bitbucket-getBitbucketRepositories
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/bitbucket.getBitbucketRepositories?bitbucketId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/bitbucket.getBitbucketRepositories?bitbucketId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/bitbucket.getBitbucketBranches"}>
|
||||||
|
|
||||||
|
## bitbucket-getBitbucketBranches
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"owner"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"repo"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string"} required={false} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/bitbucket.getBitbucketBranches?owner=string&repo=string&bitbucketId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/bitbucket.getBitbucketBranches?owner=string&repo=string&bitbucketId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/bitbucket.testConnection"}>
|
||||||
|
|
||||||
|
## bitbucket-testConnection
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketUsername"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"workspaceName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/bitbucket.testConnection" \
|
||||||
|
-d '{
|
||||||
|
"bitbucketId": "string",
|
||||||
|
"bitbucketUsername": "string",
|
||||||
|
"workspaceName": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/bitbucket.testConnection", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/bitbucket.update"}>
|
||||||
|
|
||||||
|
## bitbucket-update
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketUsername"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"appPassword"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketWorkspaceName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitProviderId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/bitbucket.update" \
|
||||||
|
-d '{
|
||||||
|
"bitbucketId": "string",
|
||||||
|
"bitbucketUsername": "string",
|
||||||
|
"appPassword": "string",
|
||||||
|
"bitbucketWorkspaceName": "string",
|
||||||
|
"gitProviderId": "string",
|
||||||
|
"name": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/bitbucket.update", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
</Root>
|
||||||
@@ -29,19 +29,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"certificateData"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"certificateData"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"privateKey"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"privateKey"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"certificateId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"certificateId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"certificateId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"certificateId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"composeType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"docker-compose" | "stack"`</span>
|
<span>Value in: `"docker-compose" | "stack"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -278,13 +278,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"sourceType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"sourceType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"git" | "github" | "raw"`</span>
|
<span>Value in: `"git" | "github" | "gitlab" | "bitbucket" | "raw"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"composeType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"composeType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"docker-compose" | "stack"`</span>
|
<span>Value in: `"docker-compose" | "stack"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -304,6 +304,38 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabProjectId"} type={"number | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabRepository"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabOwner"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabBranch"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabPathNamespace"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketRepository"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketOwner"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketBranch"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
<Property name={"customGitUrl"} type={"string | null"} required={false} deprecated={undefined}>
|
<Property name={"customGitUrl"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
@@ -312,7 +344,7 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"customGitSSHKey"} type={"string | null"} required={false} deprecated={undefined}>
|
<Property name={"customGitSSHKeyId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -322,13 +354,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composePath"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"composePath"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"composeStatus"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"composeStatus"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -340,6 +372,18 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"bitbucketId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
| ----------- | ----------- |
|
| ----------- | ----------- |
|
||||||
| `200` | Successful response |
|
| `200` | Successful response |
|
||||||
@@ -369,14 +413,25 @@ curl -X POST "http://localhost:3000/api/compose.update" \
|
|||||||
"owner": "string",
|
"owner": "string",
|
||||||
"branch": "string",
|
"branch": "string",
|
||||||
"autoDeploy": true,
|
"autoDeploy": true,
|
||||||
|
"gitlabProjectId": 0,
|
||||||
|
"gitlabRepository": "string",
|
||||||
|
"gitlabOwner": "string",
|
||||||
|
"gitlabBranch": "string",
|
||||||
|
"gitlabPathNamespace": "string",
|
||||||
|
"bitbucketRepository": "string",
|
||||||
|
"bitbucketOwner": "string",
|
||||||
|
"bitbucketBranch": "string",
|
||||||
"customGitUrl": "string",
|
"customGitUrl": "string",
|
||||||
"customGitBranch": "string",
|
"customGitBranch": "string",
|
||||||
"customGitSSHKey": "string",
|
"customGitSSHKeyId": "string",
|
||||||
"command": "string",
|
"command": "string",
|
||||||
"composePath": "string",
|
"composePath": "string",
|
||||||
"composeStatus": "idle",
|
"composeStatus": "idle",
|
||||||
"projectId": "string",
|
"projectId": "string",
|
||||||
"createdAt": "string"
|
"createdAt": "string",
|
||||||
|
"githubId": "string",
|
||||||
|
"gitlabId": "string",
|
||||||
|
"bitbucketId": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -458,7 +513,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -560,7 +615,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -646,9 +701,9 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"GET"} route={"/compose.allServices"}>
|
<APIInfo method={"GET"} route={"/compose.loadServices"}>
|
||||||
|
|
||||||
## compose-allServices
|
## compose-loadServices
|
||||||
|
|
||||||
### Authorization
|
### Authorization
|
||||||
|
|
||||||
@@ -662,7 +717,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"type"} type={"Any properties in not unknown, string"} required={false} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Default: `"cache"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -680,7 +741,7 @@ In: `header`
|
|||||||
<Request value={"cURL"}>
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X GET "http://localhost:3000/api/compose.allServices?composeId=string"
|
curl -X GET "http://localhost:3000/api/compose.loadServices?composeId=string&type=cache"
|
||||||
```
|
```
|
||||||
|
|
||||||
</Request>
|
</Request>
|
||||||
@@ -688,7 +749,7 @@ curl -X GET "http://localhost:3000/api/compose.allServices?composeId=string"
|
|||||||
<Request value={"JavaScript"}>
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
```js
|
```js
|
||||||
fetch("http://localhost:3000/api/compose.allServices?composeId=string", {
|
fetch("http://localhost:3000/api/compose.loadServices?composeId=string&type=cache", {
|
||||||
method: "GET"
|
method: "GET"
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@@ -745,6 +806,108 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/compose.fetchSourceType"}>
|
||||||
|
|
||||||
|
## compose-fetchSourceType
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/compose.fetchSourceType" \
|
||||||
|
-d '{
|
||||||
|
"composeId": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/compose.fetchSourceType", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/compose.randomizeCompose"}>
|
<APIInfo method={"POST"} route={"/compose.randomizeCompose"}>
|
||||||
|
|
||||||
## compose-randomizeCompose
|
## compose-randomizeCompose
|
||||||
@@ -761,7 +924,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -852,6 +1015,105 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/compose.getConvertedCompose"}>
|
||||||
|
|
||||||
|
## compose-getConvertedCompose
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/compose.getConvertedCompose?composeId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/compose.getConvertedCompose?composeId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/compose.deploy"}>
|
<APIInfo method={"POST"} route={"/compose.deploy"}>
|
||||||
|
|
||||||
## compose-deploy
|
## compose-deploy
|
||||||
@@ -868,7 +1130,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -970,7 +1232,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1072,7 +1334,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1174,7 +1436,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1257,108 +1519,6 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/compose.generateSSHKey"}>
|
|
||||||
|
|
||||||
## compose-generateSSHKey
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
|
||||||
|
|
||||||
In: `header`
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
### Request Body
|
|
||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
| Status code | Description |
|
|
||||||
| ----------- | ----------- |
|
|
||||||
| `200` | Successful response |
|
|
||||||
| `default` | Error response |
|
|
||||||
|
|
||||||
</APIInfo>
|
|
||||||
|
|
||||||
<APIExample>
|
|
||||||
|
|
||||||
<Requests items={["cURL","JavaScript"]}>
|
|
||||||
|
|
||||||
<Request value={"cURL"}>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://localhost:3000/api/compose.generateSSHKey" \
|
|
||||||
-d '{
|
|
||||||
"composeId": "string"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
<Request value={"JavaScript"}>
|
|
||||||
|
|
||||||
```js
|
|
||||||
fetch("http://localhost:3000/api/compose.generateSSHKey", {
|
|
||||||
method: "POST"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
</Requests>
|
|
||||||
|
|
||||||
<Responses items={["default"]}>
|
|
||||||
|
|
||||||
<Response value={"default"}>
|
|
||||||
|
|
||||||
<ResponseTypes>
|
|
||||||
|
|
||||||
<ExampleResponse>
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "string",
|
|
||||||
"code": "string",
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"message": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</ExampleResponse>
|
|
||||||
|
|
||||||
<TypeScriptResponse>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface Response {
|
|
||||||
message: string;
|
|
||||||
code: string;
|
|
||||||
issues?: {
|
|
||||||
message: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TypeScriptResponse>
|
|
||||||
|
|
||||||
</ResponseTypes>
|
|
||||||
|
|
||||||
</Response>
|
|
||||||
|
|
||||||
</Responses>
|
|
||||||
|
|
||||||
</APIExample>
|
|
||||||
|
|
||||||
</API>
|
|
||||||
|
|
||||||
<API>
|
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/compose.refreshToken"}>
|
<APIInfo method={"POST"} route={"/compose.refreshToken"}>
|
||||||
|
|
||||||
## compose-refreshToken
|
## compose-refreshToken
|
||||||
@@ -1375,7 +1535,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1461,108 +1621,6 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/compose.removeSSHKey"}>
|
|
||||||
|
|
||||||
## compose-removeSSHKey
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
|
||||||
|
|
||||||
In: `header`
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
### Request Body
|
|
||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={undefined}>
|
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
| Status code | Description |
|
|
||||||
| ----------- | ----------- |
|
|
||||||
| `200` | Successful response |
|
|
||||||
| `default` | Error response |
|
|
||||||
|
|
||||||
</APIInfo>
|
|
||||||
|
|
||||||
<APIExample>
|
|
||||||
|
|
||||||
<Requests items={["cURL","JavaScript"]}>
|
|
||||||
|
|
||||||
<Request value={"cURL"}>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://localhost:3000/api/compose.removeSSHKey" \
|
|
||||||
-d '{
|
|
||||||
"composeId": "string"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
<Request value={"JavaScript"}>
|
|
||||||
|
|
||||||
```js
|
|
||||||
fetch("http://localhost:3000/api/compose.removeSSHKey", {
|
|
||||||
method: "POST"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</Request>
|
|
||||||
|
|
||||||
</Requests>
|
|
||||||
|
|
||||||
<Responses items={["default"]}>
|
|
||||||
|
|
||||||
<Response value={"default"}>
|
|
||||||
|
|
||||||
<ResponseTypes>
|
|
||||||
|
|
||||||
<ExampleResponse>
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "string",
|
|
||||||
"code": "string",
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"message": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</ExampleResponse>
|
|
||||||
|
|
||||||
<TypeScriptResponse>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface Response {
|
|
||||||
message: string;
|
|
||||||
code: string;
|
|
||||||
issues?: {
|
|
||||||
message: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TypeScriptResponse>
|
|
||||||
|
|
||||||
</ResponseTypes>
|
|
||||||
|
|
||||||
</Response>
|
|
||||||
|
|
||||||
</Responses>
|
|
||||||
|
|
||||||
</APIExample>
|
|
||||||
|
|
||||||
</API>
|
|
||||||
|
|
||||||
<API>
|
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/compose.deployTemplate"}>
|
<APIInfo method={"POST"} route={"/compose.deployTemplate"}>
|
||||||
|
|
||||||
## compose-deployTemplate
|
## compose-deployTemplate
|
||||||
@@ -1583,7 +1641,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"id"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"id"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1759,4 +1817,95 @@ export interface Response {
|
|||||||
|
|
||||||
</API>
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/compose.getTags"}>
|
||||||
|
|
||||||
|
## compose-getTags
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/compose.getTags"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/compose.getTags", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
</Root>
|
</Root>
|
||||||
@@ -25,7 +25,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"applicationId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -567,7 +567,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"containerId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"containerId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -213,9 +213,13 @@ In: `header`
|
|||||||
|
|
||||||
### Query Parameters
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"appType"} type={"Any properties in string, string"} required={false} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={false}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -233,7 +237,7 @@ In: `header`
|
|||||||
<Request value={"cURL"}>
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X GET "http://localhost:3000/api/docker.getContainersByAppNameMatch?appName=string"
|
curl -X GET "http://localhost:3000/api/docker.getContainersByAppNameMatch?appType=stack&appName=string"
|
||||||
```
|
```
|
||||||
|
|
||||||
</Request>
|
</Request>
|
||||||
@@ -241,7 +245,7 @@ curl -X GET "http://localhost:3000/api/docker.getContainersByAppNameMatch?appNam
|
|||||||
<Request value={"JavaScript"}>
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
```js
|
```js
|
||||||
fetch("http://localhost:3000/api/docker.getContainersByAppNameMatch?appName=string", {
|
fetch("http://localhost:3000/api/docker.getContainersByAppNameMatch?appType=stack&appName=string", {
|
||||||
method: "GET"
|
method: "GET"
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@@ -314,7 +318,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={false}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,31 +25,49 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"host"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"host"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"path"} type={"string | null"} required={true} deprecated={undefined}>
|
<Property name={"path"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"port"} type={"number | null"} required={true} deprecated={undefined}>
|
<Property name={"port"} type={"number | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum: `1`</span>
|
||||||
|
|
||||||
|
<span>Maximum: `65535`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"https"} type={"boolean"} required={true} deprecated={undefined}>
|
<Property name={"https"} type={"boolean"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"applicationId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"certificateType"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"certificateType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"letsencrypt" | "none"`</span>
|
<span>Value in: `"letsencrypt" | "none"`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"composeId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"serviceName"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"domainType"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Value in: `"compose" | "application"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -71,10 +89,13 @@ curl -X POST "http://localhost:3000/api/domain.create" \
|
|||||||
-d '{
|
-d '{
|
||||||
"host": "string",
|
"host": "string",
|
||||||
"path": "string",
|
"path": "string",
|
||||||
"port": 0,
|
"port": 1,
|
||||||
"https": true,
|
"https": true,
|
||||||
"applicationId": "string",
|
"applicationId": "string",
|
||||||
"certificateType": "letsencrypt"
|
"certificateType": "letsencrypt",
|
||||||
|
"composeId": "string",
|
||||||
|
"serviceName": "string",
|
||||||
|
"domainType": "compose"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -237,9 +258,9 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/domain.generateDomain"}>
|
<APIInfo method={"GET"} route={"/domain.byComposeId"}>
|
||||||
|
|
||||||
## domain-generateDomain
|
## domain-byComposeId
|
||||||
|
|
||||||
### Authorization
|
### Authorization
|
||||||
|
|
||||||
@@ -249,9 +270,11 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
### Request Body
|
### Query Parameters
|
||||||
|
|
||||||
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"composeId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -269,10 +292,7 @@ In: `header`
|
|||||||
<Request value={"cURL"}>
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST "http://localhost:3000/api/domain.generateDomain" \
|
curl -X GET "http://localhost:3000/api/domain.byComposeId?composeId=string"
|
||||||
-d '{
|
|
||||||
"applicationId": "string"
|
|
||||||
}'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</Request>
|
</Request>
|
||||||
@@ -280,8 +300,8 @@ curl -X POST "http://localhost:3000/api/domain.generateDomain" \
|
|||||||
<Request value={"JavaScript"}>
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
```js
|
```js
|
||||||
fetch("http://localhost:3000/api/domain.generateDomain", {
|
fetch("http://localhost:3000/api/domain.byComposeId?composeId=string", {
|
||||||
method: "POST"
|
method: "GET"
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -337,9 +357,9 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/domain.generateWildcard"}>
|
<APIInfo method={"POST"} route={"/domain.generateDomain"}>
|
||||||
|
|
||||||
## domain-generateWildcard
|
## domain-generateDomain
|
||||||
|
|
||||||
### Authorization
|
### Authorization
|
||||||
|
|
||||||
@@ -351,7 +371,9 @@ In: `header`
|
|||||||
|
|
||||||
### Request Body
|
### Request Body
|
||||||
|
|
||||||
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -369,9 +391,9 @@ In: `header`
|
|||||||
<Request value={"cURL"}>
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST "http://localhost:3000/api/domain.generateWildcard" \
|
curl -X POST "http://localhost:3000/api/domain.generateDomain" \
|
||||||
-d '{
|
-d '{
|
||||||
"applicationId": "string"
|
"appName": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -380,7 +402,7 @@ curl -X POST "http://localhost:3000/api/domain.generateWildcard" \
|
|||||||
<Request value={"JavaScript"}>
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
```js
|
```js
|
||||||
fetch("http://localhost:3000/api/domain.generateWildcard", {
|
fetch("http://localhost:3000/api/domain.generateDomain", {
|
||||||
method: "POST"
|
method: "POST"
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@@ -451,35 +473,47 @@ In: `header`
|
|||||||
|
|
||||||
### Request Body
|
### Request Body
|
||||||
|
|
||||||
<Property name={"domainId"} type={"string"} required={true} deprecated={undefined}>
|
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
|
||||||
|
|
||||||
</Property>
|
|
||||||
|
|
||||||
<Property name={"host"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"host"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"path"} type={"string | null"} required={true} deprecated={undefined}>
|
<Property name={"path"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"port"} type={"number | null"} required={true} deprecated={undefined}>
|
<Property name={"port"} type={"number | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum: `1`</span>
|
||||||
|
|
||||||
|
<span>Maximum: `65535`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"https"} type={"boolean"} required={true} deprecated={undefined}>
|
<Property name={"https"} type={"boolean"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"certificateType"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"certificateType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"letsencrypt" | "none"`</span>
|
<span>Value in: `"letsencrypt" | "none"`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"serviceName"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"domainType"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Value in: `"compose" | "application"`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"domainId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -499,12 +533,14 @@ In: `header`
|
|||||||
```bash
|
```bash
|
||||||
curl -X POST "http://localhost:3000/api/domain.update" \
|
curl -X POST "http://localhost:3000/api/domain.update" \
|
||||||
-d '{
|
-d '{
|
||||||
"domainId": "string",
|
|
||||||
"host": "string",
|
"host": "string",
|
||||||
"path": "string",
|
"path": "string",
|
||||||
"port": 0,
|
"port": 1,
|
||||||
"https": true,
|
"https": true,
|
||||||
"certificateType": "letsencrypt"
|
"certificateType": "letsencrypt",
|
||||||
|
"serviceName": "string",
|
||||||
|
"domainType": "compose",
|
||||||
|
"domainId": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -586,8 +622,6 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"domainId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"domainId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
@@ -685,8 +719,6 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"domainId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"domainId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
| Status code | Description |
|
| Status code | Description |
|
||||||
|
|||||||
@@ -0,0 +1,203 @@
|
|||||||
|
---
|
||||||
|
title: gitProvider
|
||||||
|
full: true
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Root, API, APIInfo, APIExample, Responses, Response, ResponseTypes, ExampleResponse, TypeScriptResponse, Property, ObjectCollapsible, Requests, Request } from "fumadocs-ui/components/api";
|
||||||
|
|
||||||
|
<Root>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/gitProvider.getAll"}>
|
||||||
|
|
||||||
|
## gitProvider-getAll
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/gitProvider.getAll"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitProvider.getAll", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/gitProvider.remove"}>
|
||||||
|
|
||||||
|
## gitProvider-remove
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"gitProviderId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/gitProvider.remove" \
|
||||||
|
-d '{
|
||||||
|
"gitProviderId": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitProvider.remove", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
</Root>
|
||||||
661
apps/docs/content/docs/api/reference-api/reference-github.mdx
Normal file
661
apps/docs/content/docs/api/reference-api/reference-github.mdx
Normal file
@@ -0,0 +1,661 @@
|
|||||||
|
---
|
||||||
|
title: github
|
||||||
|
full: true
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Root, API, APIInfo, APIExample, Responses, Response, ResponseTypes, ExampleResponse, TypeScriptResponse, Property, ObjectCollapsible, Requests, Request } from "fumadocs-ui/components/api";
|
||||||
|
|
||||||
|
<Root>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/github.one"}>
|
||||||
|
|
||||||
|
## github-one
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"githubId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/github.one?githubId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/github.one?githubId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/github.getGithubRepositories"}>
|
||||||
|
|
||||||
|
## github-getGithubRepositories
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"githubId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/github.getGithubRepositories?githubId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/github.getGithubRepositories?githubId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/github.getGithubBranches"}>
|
||||||
|
|
||||||
|
## github-getGithubBranches
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"repo"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"owner"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubId"} type={"string"} required={false} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/github.getGithubBranches?repo=string&owner=string&githubId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/github.getGithubBranches?repo=string&owner=string&githubId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/github.githubProviders"}>
|
||||||
|
|
||||||
|
## github-githubProviders
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/github.githubProviders"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/github.githubProviders", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/github.testConnection"}>
|
||||||
|
|
||||||
|
## github-testConnection
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"githubId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/github.testConnection" \
|
||||||
|
-d '{
|
||||||
|
"githubId": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/github.testConnection", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/github.update"}>
|
||||||
|
|
||||||
|
## github-update
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"githubId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubAppName"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubAppId"} type={"number | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubClientId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubClientSecret"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubInstallationId"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubPrivateKey"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"githubWebhookSecret"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitProviderId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/github.update" \
|
||||||
|
-d '{
|
||||||
|
"githubId": "string",
|
||||||
|
"githubAppName": "string",
|
||||||
|
"githubAppId": 0,
|
||||||
|
"githubClientId": "string",
|
||||||
|
"githubClientSecret": "string",
|
||||||
|
"githubInstallationId": "string",
|
||||||
|
"githubPrivateKey": "string",
|
||||||
|
"githubWebhookSecret": "string",
|
||||||
|
"gitProviderId": "string",
|
||||||
|
"name": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/github.update", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
</Root>
|
||||||
816
apps/docs/content/docs/api/reference-api/reference-gitlab.mdx
Normal file
816
apps/docs/content/docs/api/reference-api/reference-gitlab.mdx
Normal file
@@ -0,0 +1,816 @@
|
|||||||
|
---
|
||||||
|
title: gitlab
|
||||||
|
full: true
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Root, API, APIInfo, APIExample, Responses, Response, ResponseTypes, ExampleResponse, TypeScriptResponse, Property, ObjectCollapsible, Requests, Request } from "fumadocs-ui/components/api";
|
||||||
|
|
||||||
|
<Root>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/gitlab.create"}>
|
||||||
|
|
||||||
|
## gitlab-create
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"applicationId"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"redirectUri"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"secret"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"accessToken"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"refreshToken"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"groupName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"expiresAt"} type={"number | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitProviderId"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"authId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/gitlab.create" \
|
||||||
|
-d '{
|
||||||
|
"gitlabId": "string",
|
||||||
|
"applicationId": "string",
|
||||||
|
"redirectUri": "string",
|
||||||
|
"secret": "string",
|
||||||
|
"accessToken": "string",
|
||||||
|
"refreshToken": "string",
|
||||||
|
"groupName": "string",
|
||||||
|
"expiresAt": 0,
|
||||||
|
"gitProviderId": "string",
|
||||||
|
"authId": "string",
|
||||||
|
"name": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitlab.create", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/gitlab.one"}>
|
||||||
|
|
||||||
|
## gitlab-one
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/gitlab.one?gitlabId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitlab.one?gitlabId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/gitlab.gitlabProviders"}>
|
||||||
|
|
||||||
|
## gitlab-gitlabProviders
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/gitlab.gitlabProviders"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitlab.gitlabProviders", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/gitlab.getGitlabRepositories"}>
|
||||||
|
|
||||||
|
## gitlab-getGitlabRepositories
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/gitlab.getGitlabRepositories?gitlabId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitlab.getGitlabRepositories?gitlabId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/gitlab.getGitlabBranches"}>
|
||||||
|
|
||||||
|
## gitlab-getGitlabBranches
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"id"} type={"number"} required={false} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"owner"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"repo"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string"} required={false} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/gitlab.getGitlabBranches?id=0&owner=string&repo=string&gitlabId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitlab.getGitlabBranches?id=0&owner=string&repo=string&gitlabId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/gitlab.testConnection"}>
|
||||||
|
|
||||||
|
## gitlab-testConnection
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"groupName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/gitlab.testConnection" \
|
||||||
|
-d '{
|
||||||
|
"gitlabId": "string",
|
||||||
|
"groupName": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitlab.testConnection", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/gitlab.update"}>
|
||||||
|
|
||||||
|
## gitlab-update
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"gitlabId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"applicationId"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"redirectUri"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"secret"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"accessToken"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"refreshToken"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"groupName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"expiresAt"} type={"number | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"gitProviderId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/gitlab.update" \
|
||||||
|
-d '{
|
||||||
|
"gitlabId": "string",
|
||||||
|
"applicationId": "string",
|
||||||
|
"redirectUri": "string",
|
||||||
|
"secret": "string",
|
||||||
|
"accessToken": "string",
|
||||||
|
"refreshToken": "string",
|
||||||
|
"groupName": "string",
|
||||||
|
"expiresAt": 0,
|
||||||
|
"gitProviderId": "string",
|
||||||
|
"name": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/gitlab.update", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
</Root>
|
||||||
@@ -25,19 +25,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"mariadb:6"`</span>
|
<span>Default: `"mariadb:6"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -55,13 +55,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"databaseName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"databaseUser"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"databaseUser"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -681,7 +681,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -993,7 +993,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1096,19 +1096,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"mariadbId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"mariadbId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1118,13 +1118,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseName"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"databaseName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"databaseUser"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"databaseUser"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1138,7 +1138,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"mariadb:6"`</span>
|
<span>Default: `"mariadb:6"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1172,7 +1172,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,19 +25,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"mongo:15"`</span>
|
<span>Default: `"mongo:15"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseUser"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"databaseUser"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -669,7 +669,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -776,7 +776,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1084,19 +1084,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"mongoId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"mongoId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1106,7 +1106,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseUser"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"databaseUser"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1116,7 +1116,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"mongo:15"`</span>
|
<span>Default: `"mongo:15"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1150,7 +1150,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"type"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"type"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"bind" | "volume" | "file"`</span>
|
<span>Value in: `"bind" | "volume" | "file"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -43,21 +43,25 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"mountPath"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"mountPath"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"serviceType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"serviceType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"application"`</span>
|
<span>Default: `"application"`</span>
|
||||||
|
|
||||||
<span>Value in: `"application" | "postgres" | "mysql" | "mariadb" | "mongo" | "redis" | "compose"`</span>
|
<span>Value in: `"application" | "postgres" | "mysql" | "mariadb" | "mongo" | "redis" | "compose"`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"filePath"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"serviceId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"serviceId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -83,6 +87,7 @@ curl -X POST "http://localhost:3000/api/mounts.create" \
|
|||||||
"content": "string",
|
"content": "string",
|
||||||
"mountPath": "string",
|
"mountPath": "string",
|
||||||
"serviceType": "application",
|
"serviceType": "application",
|
||||||
|
"filePath": "string",
|
||||||
"serviceId": "string"
|
"serviceId": "string"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
@@ -362,13 +367,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"mountId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"mountId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"type"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"type"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"bind" | "volume" | "file"`</span>
|
<span>Value in: `"bind" | "volume" | "file"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -380,21 +385,25 @@ In: `header`
|
|||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"filePath"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
<Property name={"content"} type={"string | null"} required={false} deprecated={undefined}>
|
<Property name={"content"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"serviceType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"serviceType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"application"`</span>
|
<span>Default: `"application"`</span>
|
||||||
|
|
||||||
<span>Value in: `"application" | "postgres" | "mysql" | "mariadb" | "mongo" | "redis" | "compose"`</span>
|
<span>Value in: `"application" | "postgres" | "mysql" | "mariadb" | "mongo" | "redis" | "compose"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"mountPath"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"mountPath"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -446,6 +455,7 @@ curl -X POST "http://localhost:3000/api/mounts.update" \
|
|||||||
"type": "bind",
|
"type": "bind",
|
||||||
"hostPath": "string",
|
"hostPath": "string",
|
||||||
"volumeName": "string",
|
"volumeName": "string",
|
||||||
|
"filePath": "string",
|
||||||
"content": "string",
|
"content": "string",
|
||||||
"serviceType": "application",
|
"serviceType": "application",
|
||||||
"mountPath": "string",
|
"mountPath": "string",
|
||||||
|
|||||||
@@ -25,19 +25,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"mysql:8"`</span>
|
<span>Default: `"mysql:8"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -51,13 +51,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"databaseName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"databaseUser"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"databaseUser"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -681,7 +681,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -788,7 +788,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1096,19 +1096,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"mysqlId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"mysqlId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1118,13 +1118,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseName"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"databaseName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"databaseUser"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"databaseUser"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1138,7 +1138,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"mysql:8"`</span>
|
<span>Default: `"mysql:8"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1172,7 +1172,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
1957
apps/docs/content/docs/api/reference-api/reference-notification.mdx
Normal file
1957
apps/docs/content/docs/api/reference-api/reference-notification.mdx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,15 +33,15 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"protocol"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"protocol"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"tcp"`</span>
|
<span>Default: `"tcp"`</span>
|
||||||
|
|
||||||
<span>Value in: `"tcp" | "udp"`</span>
|
<span>Value in: `"tcp" | "udp"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"applicationId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"portId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"portId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"portId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"portId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"portId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"portId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -361,9 +361,9 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"protocol"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"protocol"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"tcp"`</span>
|
<span>Default: `"tcp"`</span>
|
||||||
|
|
||||||
<span>Value in: `"tcp" | "udp"`</span>
|
<span>Value in: `"tcp" | "udp"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -35,13 +35,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"databaseName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"databaseUser"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"databaseUser"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"postgres:15"`</span>
|
<span>Default: `"postgres:15"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -674,7 +674,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1087,13 +1087,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"postgresId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"postgresId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1103,13 +1103,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"databaseName"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"databaseName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"databaseUser"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"databaseUser"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1123,7 +1123,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"postgres:15"`</span>
|
<span>Default: `"postgres:15"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1157,7 +1157,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"projectId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"projectId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"projectId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"projectId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -434,7 +434,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"projectId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"projectId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"regex"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"regex"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"replacement"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"replacement"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"redirectId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"redirectId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"redirectId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"redirectId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -345,19 +345,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"redirectId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"redirectId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"regex"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"regex"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"replacement"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"replacement"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"redis:8"`</span>
|
<span>Default: `"redis:8"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -357,7 +357,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -769,7 +769,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1077,19 +1077,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"redisId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"redisId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"appName"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"appName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1103,7 +1103,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"dockerImage"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"redis:8"`</span>
|
<span>Default: `"redis:8"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1141,7 +1141,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"applicationStatus"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
<span>Value in: `"idle" | "running" | "done" | "error"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -25,19 +25,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"registryName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryType"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"registryType"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"selfHosted" | "cloud"`</span>
|
<span>Value in: `"selfHosted" | "cloud"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"registryId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -260,13 +260,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"registryId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"registryName"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"registryName"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -276,19 +276,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"username"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"username"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"password"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"registryUrl"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"registryUrl"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -298,13 +298,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"registryType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"selfHosted" | "cloud"`</span>
|
<span>Value in: `"selfHosted" | "cloud"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"adminId"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"adminId"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -505,7 +505,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"registryId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -604,19 +604,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryName"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"registryName"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -626,7 +626,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryType"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"registryType"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Value in: `"selfHosted" | "cloud"`</span>
|
<span>Value in: `"selfHosted" | "cloud"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -737,19 +737,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"registryUrl"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"registryUrl"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"securityId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"securityId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"securityId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"securityId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -340,19 +340,19 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"securityId"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"securityId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"username"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"password"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -191,6 +191,106 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/settings.toggleDashboard"}>
|
||||||
|
|
||||||
|
## settings-toggleDashboard
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"enableDashboard"} type={"boolean"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/settings.toggleDashboard" \
|
||||||
|
-d '{
|
||||||
|
"enableDashboard": true
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/settings.toggleDashboard", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"POST"} route={"/settings.cleanUnusedImages"}>
|
<APIInfo method={"POST"} route={"/settings.cleanUnusedImages"}>
|
||||||
|
|
||||||
## settings-cleanUnusedImages
|
## settings-cleanUnusedImages
|
||||||
@@ -952,9 +1052,9 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"certificateType"} type={"string"} required={false} deprecated={undefined}>
|
<Property name={"certificateType"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Default: `"none"`</span>
|
<span>Default: `"none"`</span>
|
||||||
|
|
||||||
<span>Value in: `"letsencrypt" | "none"`</span>
|
<span>Value in: `"letsencrypt" | "none"`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1340,7 +1440,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"traefikConfig"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"traefikConfig"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1533,7 +1633,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"traefikConfig"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"traefikConfig"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -1726,7 +1826,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"traefikConfig"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"traefikConfig"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -2192,13 +2292,13 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"path"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"path"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property name={"traefikConfig"} type={"string"} required={true} deprecated={undefined}>
|
<Property name={"traefikConfig"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -2301,7 +2401,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"path"} type={"string"} required={true} deprecated={false}>
|
<Property name={"path"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -2384,6 +2484,97 @@ export interface Response {
|
|||||||
|
|
||||||
<API>
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/settings.getIp"}>
|
||||||
|
|
||||||
|
## settings-getIp
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/settings.getIp"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/settings.getIp", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
<APIInfo method={"GET"} route={"/settings.getOpenApiDocument"}>
|
<APIInfo method={"GET"} route={"/settings.getOpenApiDocument"}>
|
||||||
|
|
||||||
## settings-getOpenApiDocument
|
## settings-getOpenApiDocument
|
||||||
@@ -2473,4 +2664,286 @@ export interface Response {
|
|||||||
|
|
||||||
</API>
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/settings.readTraefikEnv"}>
|
||||||
|
|
||||||
|
## settings-readTraefikEnv
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/settings.readTraefikEnv"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/settings.readTraefikEnv", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/settings.writeTraefikEnv"}>
|
||||||
|
|
||||||
|
## settings-writeTraefikEnv
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"env"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/settings.writeTraefikEnv" \
|
||||||
|
-d '{
|
||||||
|
"env": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/settings.writeTraefikEnv", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/settings.haveTraefikDashboardPortEnabled"}>
|
||||||
|
|
||||||
|
## settings-haveTraefikDashboardPortEnabled
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/settings.haveTraefikDashboardPortEnabled"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/settings.haveTraefikDashboardPortEnabled", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
</Root>
|
</Root>
|
||||||
634
apps/docs/content/docs/api/reference-api/reference-sshKey.mdx
Normal file
634
apps/docs/content/docs/api/reference-api/reference-sshKey.mdx
Normal file
@@ -0,0 +1,634 @@
|
|||||||
|
---
|
||||||
|
title: sshKey
|
||||||
|
full: true
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Root, API, APIInfo, APIExample, Responses, Response, ResponseTypes, ExampleResponse, TypeScriptResponse, Property, ObjectCollapsible, Requests, Request } from "fumadocs-ui/components/api";
|
||||||
|
|
||||||
|
<Root>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/sshKey.create"}>
|
||||||
|
|
||||||
|
## sshKey-create
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"name"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"description"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"publicKey"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"privateKey"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/sshKey.create" \
|
||||||
|
-d '{
|
||||||
|
"name": "string",
|
||||||
|
"description": "string",
|
||||||
|
"publicKey": "string",
|
||||||
|
"privateKey": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/sshKey.create", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/sshKey.remove"}>
|
||||||
|
|
||||||
|
## sshKey-remove
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"sshKeyId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/sshKey.remove" \
|
||||||
|
-d '{
|
||||||
|
"sshKeyId": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/sshKey.remove", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/sshKey.one"}>
|
||||||
|
|
||||||
|
## sshKey-one
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
<Property name={"sshKeyId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/sshKey.one?sshKeyId=string"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/sshKey.one?sshKeyId=string", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"GET"} route={"/sshKey.all"}>
|
||||||
|
|
||||||
|
## sshKey-all
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:3000/api/sshKey.all"
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/sshKey.all", {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/sshKey.generate"}>
|
||||||
|
|
||||||
|
## sshKey-generate
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"type"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Value in: `"rsa" | "ed25519"`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/sshKey.generate" \
|
||||||
|
-d '{
|
||||||
|
"type": "rsa"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/sshKey.generate", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
<API>
|
||||||
|
|
||||||
|
<APIInfo method={"POST"} route={"/sshKey.update"}>
|
||||||
|
|
||||||
|
## sshKey-update
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
<Property name={"Authorization"} type={"Bearer <token>"} required={true}>
|
||||||
|
|
||||||
|
In: `header`
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
### Request Body
|
||||||
|
|
||||||
|
<Property name={"name"} type={"string"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"description"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"lastUsedAt"} type={"string | null"} required={false} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
<Property name={"sshKeyId"} type={"string"} required={true} deprecated={undefined}>
|
||||||
|
|
||||||
|
</Property>
|
||||||
|
|
||||||
|
| Status code | Description |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| `200` | Successful response |
|
||||||
|
| `default` | Error response |
|
||||||
|
|
||||||
|
</APIInfo>
|
||||||
|
|
||||||
|
<APIExample>
|
||||||
|
|
||||||
|
<Requests items={["cURL","JavaScript"]}>
|
||||||
|
|
||||||
|
<Request value={"cURL"}>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:3000/api/sshKey.update" \
|
||||||
|
-d '{
|
||||||
|
"name": "string",
|
||||||
|
"description": "string",
|
||||||
|
"lastUsedAt": "string",
|
||||||
|
"sshKeyId": "string"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
<Request value={"JavaScript"}>
|
||||||
|
|
||||||
|
```js
|
||||||
|
fetch("http://localhost:3000/api/sshKey.update", {
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</Request>
|
||||||
|
|
||||||
|
</Requests>
|
||||||
|
|
||||||
|
<Responses items={["default"]}>
|
||||||
|
|
||||||
|
<Response value={"default"}>
|
||||||
|
|
||||||
|
<ResponseTypes>
|
||||||
|
|
||||||
|
<ExampleResponse>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "string",
|
||||||
|
"code": "string",
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"message": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</ExampleResponse>
|
||||||
|
|
||||||
|
<TypeScriptResponse>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface Response {
|
||||||
|
message: string;
|
||||||
|
code: string;
|
||||||
|
issues?: {
|
||||||
|
message: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TypeScriptResponse>
|
||||||
|
|
||||||
|
</ResponseTypes>
|
||||||
|
|
||||||
|
</Response>
|
||||||
|
|
||||||
|
</Responses>
|
||||||
|
|
||||||
|
</APIExample>
|
||||||
|
|
||||||
|
</API>
|
||||||
|
|
||||||
|
</Root>
|
||||||
@@ -116,7 +116,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"authId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"authId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ In: `header`
|
|||||||
|
|
||||||
<Property name={"userId"} type={"string"} required={true} deprecated={false}>
|
<Property name={"userId"} type={"string"} required={true} deprecated={false}>
|
||||||
|
|
||||||
<span>Minimum length: `1`</span>
|
<span>Minimum length: `1`</span>
|
||||||
|
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,30 @@ description: Learn how to use providers in your application.
|
|||||||
Dokploy offers several deployment methods, streamlining the process whether you're utilizing GitHub, any Git provider, Docker, or automated deployments.
|
Dokploy offers several deployment methods, streamlining the process whether you're utilizing GitHub, any Git provider, Docker, or automated deployments.
|
||||||
|
|
||||||
- GitHub
|
- GitHub
|
||||||
|
- Gitlab
|
||||||
|
- Bitbucket
|
||||||
- Git (Any Git Provider)
|
- Git (Any Git Provider)
|
||||||
- Docker
|
- Docker
|
||||||
|
|
||||||
## GitHub
|
## GitHub
|
||||||
|
|
||||||
Deploying via GitHub is straightforward:
|
Deploying via GitHub:
|
||||||
|
|
||||||
1. Configure your GitHub repository in the `/dashboard/settings/server`.
|
1. Configure your GitHub repository in the `/dashboard/settings/git-providers`.
|
||||||
|
2. When creating an application, Dokploy automatically retrieves the available repositories and branches.
|
||||||
|
|
||||||
|
## Gitlab
|
||||||
|
|
||||||
|
Deploying via Gitlab:
|
||||||
|
|
||||||
|
1. Configure your Gitlab repository in the `/dashboard/settings/git-providers`.
|
||||||
|
2. When creating an application, Dokploy automatically retrieves the available repositories and branches.
|
||||||
|
|
||||||
|
## Bitbucket
|
||||||
|
|
||||||
|
Deploying via Bitbucket:
|
||||||
|
|
||||||
|
1. Configure your Bitbucket repository in the `/dashboard/settings/git-providers`.
|
||||||
2. When creating an application, Dokploy automatically retrieves the available repositories and branches.
|
2. When creating an application, Dokploy automatically retrieves the available repositories and branches.
|
||||||
|
|
||||||
## Git
|
## Git
|
||||||
@@ -27,11 +43,21 @@ For deployments from any Git repository, whether public or private, you can use
|
|||||||
|
|
||||||
For private repositories, authenticate using SSH. We provide a lock icon to generate an SSH key.
|
For private repositories, authenticate using SSH. We provide a lock icon to generate an SSH key.
|
||||||
|
|
||||||
<ImageZoom src="/assets/dokploy-ssh-key.png" width={800} height={630} className="rounded-lg"/>
|
<ImageZoom
|
||||||
|
src="/assets/dokploy-ssh-key.png"
|
||||||
|
width={800}
|
||||||
|
height={630}
|
||||||
|
className="rounded-lg"
|
||||||
|
/>
|
||||||
|
|
||||||
You can then copy the SSH key and paste it into the settings of your account.
|
You can then copy the SSH key and paste it into the settings of your account.
|
||||||
|
|
||||||
<ImageZoom src="/assets/private-repository.png" width={800} height={630} className="rounded-lg"/>
|
<ImageZoom
|
||||||
|
src="/assets/private-repository.png"
|
||||||
|
width={800}
|
||||||
|
height={630}
|
||||||
|
className="rounded-lg"
|
||||||
|
/>
|
||||||
|
|
||||||
This enables you to pull repositories from your private repository, a method consistent across nearly all providers.
|
This enables you to pull repositories from your private repository, a method consistent across nearly all providers.
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,20 @@ Key Steps:
|
|||||||
1. Add the service to the `dokploy-network`.
|
1. Add the service to the `dokploy-network`.
|
||||||
2. Use Traefik labels to configure routing.
|
2. Use Traefik labels to configure routing.
|
||||||
|
|
||||||
|
import { Callout } from "fumadocs-ui/components/callout";
|
||||||
|
|
||||||
|
<Callout title="Attention" type="info">
|
||||||
|
Since v0.7.0 Dokploy support domains natively. This means that you can
|
||||||
|
configure your domain directly in the Dokploy UI, without doing the rest of
|
||||||
|
the steps.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
Example Scenario
|
Example Scenario
|
||||||
|
|
||||||
Let's consider an application with three components: a frontend, a backend, and a database. We'll start with a basic Docker Compose file and then enhance it with domain configuration.
|
Let's consider an application with three components: a frontend, a backend, and a database. We'll start with a basic Docker Compose file and then enhance it with domain configuration.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '3.8'
|
version: "3.8"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
frontend:
|
frontend:
|
||||||
@@ -60,7 +68,7 @@ volumes:
|
|||||||
First, we'll add the dokploy-network to our services:
|
First, we'll add the dokploy-network to our services:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '3.8'
|
version: "3.8"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
frontend:
|
frontend:
|
||||||
@@ -90,28 +98,8 @@ Step 2: Configuring Traefik Labels
|
|||||||
|
|
||||||
Now, let's add Traefik labels to route domains to our services. We'll focus on the frontend and backend services:
|
Now, let's add Traefik labels to route domains to our services. We'll focus on the frontend and backend services:
|
||||||
|
|
||||||
{/* It is necessary to add these labels:
|
|
||||||
|
|
||||||
1. `traefik.enable=true`
|
|
||||||
This label tells Traefik that this service should be routed by Traefik.
|
|
||||||
2. `traefik.http.routers.<UNIQUE-RULE>.rule=Host('your-domain.dokploy.com')`
|
|
||||||
This label tells Traefik that the domain to be used is `your-domain.dokploy.com`
|
|
||||||
3. `traefik.http.routers.<UNIQUE-RULE>.entrypoints=web`
|
|
||||||
This label tells Traefik that the service should be accessible via the `http` protocol.
|
|
||||||
4. `traefik.http.services.<UNIQUE-RULE>.loadbalancer.server.port=3000`
|
|
||||||
This label tells Traefik that the port to be used is `3000`
|
|
||||||
|
|
||||||
Note: For loadbalancer.server.port, ensure you assign the port that your service is using. It's important to note that you do not need to expose the port like this:
|
|
||||||
|
|
||||||
Nota: en el loadbalancer.server.port asegurate de asignar el puerto que tu servicio esta utilizando, y alcaramos no es necesario que expongas el puerto de esta manera
|
|
||||||
|
|
||||||
'3000:3000' esto es incorrecto, unicamente debes de asignar el puerto que tu servicio esta utilizando, en este caso `3000`
|
|
||||||
|
|
||||||
asegurate de crear los registros `A` que apunten a tu dominio, esto hazlo desde tu DNS provider. */}
|
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '3.8'
|
version: "3.8"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
frontend:
|
frontend:
|
||||||
@@ -165,22 +153,19 @@ networks:
|
|||||||
|
|
||||||
Understanding Traefik Labels
|
Understanding Traefik Labels
|
||||||
|
|
||||||
|
1. `traefik.enable=true` Enables Traefik routing for the service.
|
||||||
1. `traefik.enable=true` Enables Traefik routing for the service.
|
|
||||||
2. `traefik.http.routers.<UNIQUE-RULE>.rule=Host('your-domain.dokploy.com')` Specifies the domain for the service
|
2. `traefik.http.routers.<UNIQUE-RULE>.rule=Host('your-domain.dokploy.com')` Specifies the domain for the service
|
||||||
3. `traefik.http.routers.<UNIQUE-RULE>.entrypoints=web` Sets the service to be accessible via HTTP.
|
3. `traefik.http.routers.<UNIQUE-RULE>.entrypoints=web` Sets the service to be accessible via HTTP.
|
||||||
4. `traefik.http.services.<UNIQUE-RULE>.loadbalancer.server.port=3000` Specifies the port your service is using internally.
|
4. `traefik.http.services.<UNIQUE-RULE>.loadbalancer.server.port=3000` Specifies the port your service is using internally.
|
||||||
|
|
||||||
**Note**: Replace `<UNIQUE-RULE>` with a unique identifier for each service (e.g., frontend-app, backend-app, etc.).
|
**Note**: Replace `<UNIQUE-RULE>` with a unique identifier for each service (e.g., frontend-app, backend-app, etc.).
|
||||||
|
|
||||||
|
|
||||||
## Important Considerations
|
## Important Considerations
|
||||||
|
|
||||||
1. **Port Exposure**: Use `expose` instead of `ports` to expose ports to the host machine. This ensures that the ports are not exposed to the host machine.
|
1. **Port Exposure**: Use `expose` instead of `ports` to expose ports to the host machine. This ensures that the ports are not exposed to the host machine.
|
||||||
2. **DNS Configuration**: Ensure you create `A` records pointing to your domain in your DNS Provider Settings.
|
2. **DNS Configuration**: Ensure you create `A` records pointing to your domain in your DNS Provider Settings.
|
||||||
3. **HTTPS**: For HTTPS, you can use Let's Encrypt or other SSL/TLS certificates.
|
3. **HTTPS**: For HTTPS, you can use Let's Encrypt or other SSL/TLS certificates.
|
||||||
|
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
With these configurations in place, you're now ready to deploy your application using Docker Compose. This setup should be sufficient to get your services up and running with custom domain routing through Traefik.
|
With these configurations in place, you're now ready to deploy your application using Docker Compose. This setup should be sufficient to get your services up and running with custom domain routing through Traefik.
|
||||||
|
|||||||
@@ -6,14 +6,30 @@ description: "Learn how to use Docker Compose with Dokploy"
|
|||||||
Dokploy offers several deployment methods, streamlining the process whether you're utilizing GitHub, any Git provider, Raw, or automated deployments.
|
Dokploy offers several deployment methods, streamlining the process whether you're utilizing GitHub, any Git provider, Raw, or automated deployments.
|
||||||
|
|
||||||
- GitHub
|
- GitHub
|
||||||
|
- Gitlab
|
||||||
|
- Bitbucket
|
||||||
- Git (Any Git Provider)
|
- Git (Any Git Provider)
|
||||||
- Raw
|
- Raw
|
||||||
|
|
||||||
## GitHub
|
## GitHub
|
||||||
|
|
||||||
Deploying via GitHub is straightforward:
|
Deploying via GitHub:
|
||||||
|
|
||||||
1. Configure your GitHub repository in the `/dashboard/settings/server`.
|
1. Configure your GitHub repository in the `/dashboard/settings/git-providers`.
|
||||||
|
2. When creating an application, Dokploy automatically retrieves the available repositories and branches.
|
||||||
|
|
||||||
|
## Gitlab
|
||||||
|
|
||||||
|
Deploying via Gitlab:
|
||||||
|
|
||||||
|
1. Configure your Gitlab repository in the `/dashboard/settings/git-providers`.
|
||||||
|
2. When creating an application, Dokploy automatically retrieves the available repositories and branches.
|
||||||
|
|
||||||
|
## Bitbucket
|
||||||
|
|
||||||
|
Deploying via Bitbucket:
|
||||||
|
|
||||||
|
1. Configure your Bitbucket repository in the `/dashboard/settings/git-providers`.
|
||||||
2. When creating an application, Dokploy automatically retrieves the available repositories and branches.
|
2. When creating an application, Dokploy automatically retrieves the available repositories and branches.
|
||||||
|
|
||||||
## Git
|
## Git
|
||||||
@@ -27,15 +43,24 @@ For deployments from any Git repository, whether public or private, you can use
|
|||||||
|
|
||||||
For private repositories, authenticate using SSH. We provide a lock icon to generate an SSH key.
|
For private repositories, authenticate using SSH. We provide a lock icon to generate an SSH key.
|
||||||
|
|
||||||
<ImageZoom src="/assets/dokploy-ssh-compose.png" width={800} height={630} className="rounded-lg"/>
|
<ImageZoom
|
||||||
|
src="/assets/dokploy-ssh-compose.png"
|
||||||
|
width={800}
|
||||||
|
height={630}
|
||||||
|
className="rounded-lg"
|
||||||
|
/>
|
||||||
|
|
||||||
You can then copy the SSH key and paste it into the settings of your account.
|
You can then copy the SSH key and paste it into the settings of your account.
|
||||||
|
|
||||||
<ImageZoom src="/assets/private-repository.png" width={800} height={630} className="rounded-lg"/>
|
<ImageZoom
|
||||||
|
src="/assets/private-repository.png"
|
||||||
|
width={800}
|
||||||
|
height={630}
|
||||||
|
className="rounded-lg"
|
||||||
|
/>
|
||||||
|
|
||||||
This enables you to pull repositories from your private repository, a method consistent across nearly all providers.
|
This enables you to pull repositories from your private repository, a method consistent across nearly all providers.
|
||||||
|
|
||||||
|
|
||||||
## Raw
|
## Raw
|
||||||
|
|
||||||
You specify a docker compose file directly in the code editor and trigger a deployment.
|
You specify a docker compose file directly in the code editor and trigger a deployment.
|
||||||
@@ -16,16 +16,9 @@ const baseAdmin: Admin = {
|
|||||||
createdAt: "",
|
createdAt: "",
|
||||||
authId: "",
|
authId: "",
|
||||||
adminId: "string",
|
adminId: "string",
|
||||||
githubAppId: null,
|
|
||||||
githubAppName: null,
|
|
||||||
serverIp: null,
|
serverIp: null,
|
||||||
certificateType: "none",
|
certificateType: "none",
|
||||||
host: null,
|
host: null,
|
||||||
githubClientId: null,
|
|
||||||
githubClientSecret: null,
|
|
||||||
githubInstallationId: null,
|
|
||||||
githubPrivateKey: null,
|
|
||||||
githubWebhookSecret: null,
|
|
||||||
letsEncryptEmail: null,
|
letsEncryptEmail: null,
|
||||||
sshPrivateKey: null,
|
sshPrivateKey: null,
|
||||||
enableDockerCleanup: false,
|
enableDockerCleanup: false,
|
||||||
|
|||||||
@@ -12,7 +12,20 @@ const baseApp: ApplicationNested = {
|
|||||||
branch: null,
|
branch: null,
|
||||||
buildArgs: null,
|
buildArgs: null,
|
||||||
buildPath: "/",
|
buildPath: "/",
|
||||||
|
gitlabPathNamespace: "",
|
||||||
buildType: "nixpacks",
|
buildType: "nixpacks",
|
||||||
|
bitbucketBranch: "",
|
||||||
|
bitbucketBuildPath: "",
|
||||||
|
bitbucketId: "",
|
||||||
|
bitbucketRepository: "",
|
||||||
|
bitbucketOwner: "",
|
||||||
|
githubId: "",
|
||||||
|
gitlabProjectId: 0,
|
||||||
|
gitlabBranch: "",
|
||||||
|
gitlabBuildPath: "",
|
||||||
|
gitlabId: "",
|
||||||
|
gitlabRepository: "",
|
||||||
|
gitlabOwner: "",
|
||||||
command: null,
|
command: null,
|
||||||
cpuLimit: null,
|
cpuLimit: null,
|
||||||
cpuReservation: null,
|
cpuReservation: null,
|
||||||
|
|||||||
@@ -0,0 +1,378 @@
|
|||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Command,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandInput,
|
||||||
|
CommandItem,
|
||||||
|
} from "@/components/ui/command";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { CheckIcon, ChevronsUpDown } from "lucide-react";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const BitbucketProviderSchema = z.object({
|
||||||
|
buildPath: z.string().min(1, "Path is required").default("/"),
|
||||||
|
repository: z
|
||||||
|
.object({
|
||||||
|
repo: z.string().min(1, "Repo is required"),
|
||||||
|
owner: z.string().min(1, "Owner is required"),
|
||||||
|
})
|
||||||
|
.required(),
|
||||||
|
branch: z.string().min(1, "Branch is required"),
|
||||||
|
bitbucketId: z.string().min(1, "Bitbucket Provider is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
type BitbucketProvider = z.infer<typeof BitbucketProviderSchema>;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
applicationId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SaveBitbucketProvider = ({ applicationId }: Props) => {
|
||||||
|
const { data: bitbucketProviders } =
|
||||||
|
api.bitbucket.bitbucketProviders.useQuery();
|
||||||
|
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||||
|
|
||||||
|
const { mutateAsync, isLoading: isSavingBitbucketProvider } =
|
||||||
|
api.application.saveBitbucketProvider.useMutation();
|
||||||
|
|
||||||
|
const form = useForm<BitbucketProvider>({
|
||||||
|
defaultValues: {
|
||||||
|
buildPath: "/",
|
||||||
|
repository: {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
},
|
||||||
|
bitbucketId: "",
|
||||||
|
branch: "",
|
||||||
|
},
|
||||||
|
resolver: zodResolver(BitbucketProviderSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const repository = form.watch("repository");
|
||||||
|
const bitbucketId = form.watch("bitbucketId");
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: repositories,
|
||||||
|
isLoading: isLoadingRepositories,
|
||||||
|
error,
|
||||||
|
isError,
|
||||||
|
} = api.bitbucket.getBitbucketRepositories.useQuery(
|
||||||
|
{
|
||||||
|
bitbucketId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!bitbucketId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
fetchStatus,
|
||||||
|
status,
|
||||||
|
} = api.bitbucket.getBitbucketBranches.useQuery(
|
||||||
|
{
|
||||||
|
owner: repository?.owner,
|
||||||
|
repo: repository?.repo,
|
||||||
|
bitbucketId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!repository?.owner && !!repository?.repo && !!bitbucketId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data) {
|
||||||
|
form.reset({
|
||||||
|
branch: data.bitbucketBranch || "",
|
||||||
|
repository: {
|
||||||
|
repo: data.bitbucketRepository || "",
|
||||||
|
owner: data.bitbucketOwner || "",
|
||||||
|
},
|
||||||
|
buildPath: data.bitbucketBuildPath || "/",
|
||||||
|
bitbucketId: data.bitbucketId || "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [form.reset, data, form]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: BitbucketProvider) => {
|
||||||
|
await mutateAsync({
|
||||||
|
bitbucketBranch: data.branch,
|
||||||
|
bitbucketRepository: data.repository.repo,
|
||||||
|
bitbucketOwner: data.repository.owner,
|
||||||
|
bitbucketBuildPath: data.buildPath,
|
||||||
|
bitbucketId: data.bitbucketId,
|
||||||
|
applicationId,
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
toast.success("Service Provided Saved");
|
||||||
|
await refetch();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error to save the Bitbucket provider");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-4 py-3"
|
||||||
|
>
|
||||||
|
{error && (
|
||||||
|
<AlertBlock type="error">Repositories: {error.message}</AlertBlock>
|
||||||
|
)}
|
||||||
|
<div className="grid md:grid-cols-2 gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="bitbucketId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Bitbucket Account</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={(value) => {
|
||||||
|
field.onChange(value);
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
defaultValue={field.value}
|
||||||
|
value={field.value}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a Bitbucket Account" />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{bitbucketProviders?.map((bitbucketProvider) => (
|
||||||
|
<SelectItem
|
||||||
|
key={bitbucketProvider.bitbucketId}
|
||||||
|
value={bitbucketProvider.bitbucketId}
|
||||||
|
>
|
||||||
|
{bitbucketProvider.gitProvider.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="repository"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Repository</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
className={cn(
|
||||||
|
"w-full justify-between !bg-input",
|
||||||
|
!field.value && "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{isLoadingRepositories
|
||||||
|
? "Loading...."
|
||||||
|
: field.value.owner
|
||||||
|
? repositories?.find(
|
||||||
|
(repo) => repo.name === field.value.repo,
|
||||||
|
)?.name
|
||||||
|
: "Select repository"}
|
||||||
|
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput
|
||||||
|
placeholder="Search repository..."
|
||||||
|
className="h-9"
|
||||||
|
/>
|
||||||
|
{isLoadingRepositories && (
|
||||||
|
<span className="py-6 text-center text-sm">
|
||||||
|
Loading Repositories....
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<CommandEmpty>No repositories found.</CommandEmpty>
|
||||||
|
<ScrollArea className="h-96">
|
||||||
|
<CommandGroup>
|
||||||
|
{repositories?.map((repo) => (
|
||||||
|
<CommandItem
|
||||||
|
value={repo.url}
|
||||||
|
key={repo.url}
|
||||||
|
onSelect={() => {
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: repo.owner.username as string,
|
||||||
|
repo: repo.name,
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{repo.name}
|
||||||
|
<CheckIcon
|
||||||
|
className={cn(
|
||||||
|
"ml-auto h-4 w-4",
|
||||||
|
repo.name === field.value.repo
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</ScrollArea>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
{form.formState.errors.repository && (
|
||||||
|
<p className={cn("text-sm font-medium text-destructive")}>
|
||||||
|
Repository is required
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="branch"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="block w-full">
|
||||||
|
<FormLabel>Branch</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
className={cn(
|
||||||
|
" w-full justify-between !bg-input",
|
||||||
|
!field.value && "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{status === "loading" && fetchStatus === "fetching"
|
||||||
|
? "Loading...."
|
||||||
|
: field.value
|
||||||
|
? branches?.find(
|
||||||
|
(branch) => branch.name === field.value,
|
||||||
|
)?.name
|
||||||
|
: "Select branch"}
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput
|
||||||
|
placeholder="Search branch..."
|
||||||
|
className="h-9"
|
||||||
|
/>
|
||||||
|
{status === "loading" && fetchStatus === "fetching" && (
|
||||||
|
<span className="py-6 text-center text-sm text-muted-foreground">
|
||||||
|
Loading Branches....
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{!repository?.owner && (
|
||||||
|
<span className="py-6 text-center text-sm text-muted-foreground">
|
||||||
|
Select a repository
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<ScrollArea className="h-96">
|
||||||
|
<CommandEmpty>No branch found.</CommandEmpty>
|
||||||
|
|
||||||
|
<CommandGroup>
|
||||||
|
{branches?.map((branch) => (
|
||||||
|
<CommandItem
|
||||||
|
value={branch.name}
|
||||||
|
key={branch.commit.sha}
|
||||||
|
onSelect={() => {
|
||||||
|
form.setValue("branch", branch.name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{branch.name}
|
||||||
|
<CheckIcon
|
||||||
|
className={cn(
|
||||||
|
"ml-auto h-4 w-4",
|
||||||
|
branch.name === field.value
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</ScrollArea>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</Popover>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="buildPath"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Build Path</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="/" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full justify-end">
|
||||||
|
<Button
|
||||||
|
isLoading={isSavingBitbucketProvider}
|
||||||
|
type="submit"
|
||||||
|
className="w-fit"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -21,6 +21,13 @@ import {
|
|||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
} from "@/components/ui/popover";
|
} from "@/components/ui/popover";
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
@@ -39,6 +46,7 @@ const GithubProviderSchema = z.object({
|
|||||||
})
|
})
|
||||||
.required(),
|
.required(),
|
||||||
branch: z.string().min(1, "Branch is required"),
|
branch: z.string().min(1, "Branch is required"),
|
||||||
|
githubId: z.string().min(1, "Github Provider is required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
type GithubProvider = z.infer<typeof GithubProviderSchema>;
|
type GithubProvider = z.infer<typeof GithubProviderSchema>;
|
||||||
@@ -48,6 +56,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const SaveGithubProvider = ({ applicationId }: Props) => {
|
export const SaveGithubProvider = ({ applicationId }: Props) => {
|
||||||
|
const { data: githubProviders } = api.github.githubProviders.useQuery();
|
||||||
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||||
|
|
||||||
const { mutateAsync, isLoading: isSavingGithubProvider } =
|
const { mutateAsync, isLoading: isSavingGithubProvider } =
|
||||||
@@ -60,26 +69,38 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
|
|||||||
owner: "",
|
owner: "",
|
||||||
repo: "",
|
repo: "",
|
||||||
},
|
},
|
||||||
|
githubId: "",
|
||||||
branch: "",
|
branch: "",
|
||||||
},
|
},
|
||||||
resolver: zodResolver(GithubProviderSchema),
|
resolver: zodResolver(GithubProviderSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
const repository = form.watch("repository");
|
const repository = form.watch("repository");
|
||||||
|
const githubId = form.watch("githubId");
|
||||||
|
|
||||||
const { data: repositories, isLoading: isLoadingRepositories } =
|
const { data: repositories, isLoading: isLoadingRepositories } =
|
||||||
api.admin.getRepositories.useQuery();
|
api.github.getGithubRepositories.useQuery(
|
||||||
|
{
|
||||||
|
githubId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!githubId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: branches,
|
data: branches,
|
||||||
fetchStatus,
|
fetchStatus,
|
||||||
status,
|
status,
|
||||||
} = api.admin.getBranches.useQuery(
|
} = api.github.getGithubBranches.useQuery(
|
||||||
{
|
{
|
||||||
owner: repository?.owner,
|
owner: repository?.owner,
|
||||||
repo: repository?.repo,
|
repo: repository?.repo,
|
||||||
|
githubId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!repository?.owner && !!repository?.repo && !!githubId,
|
||||||
},
|
},
|
||||||
{ enabled: !!repository?.owner && !!repository?.repo },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -91,6 +112,7 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
|
|||||||
owner: data.owner || "",
|
owner: data.owner || "",
|
||||||
},
|
},
|
||||||
buildPath: data.buildPath || "/",
|
buildPath: data.buildPath || "/",
|
||||||
|
githubId: data.githubId || "",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [form.reset, data, form]);
|
}, [form.reset, data, form]);
|
||||||
@@ -102,6 +124,7 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
|
|||||||
applicationId,
|
applicationId,
|
||||||
owner: data.repository.owner,
|
owner: data.repository.owner,
|
||||||
buildPath: data.buildPath,
|
buildPath: data.buildPath,
|
||||||
|
githubId: data.githubId,
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
toast.success("Service Provided Saved");
|
toast.success("Service Provided Saved");
|
||||||
@@ -120,6 +143,45 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
|
|||||||
className="grid w-full gap-4 py-3"
|
className="grid w-full gap-4 py-3"
|
||||||
>
|
>
|
||||||
<div className="grid md:grid-cols-2 gap-4">
|
<div className="grid md:grid-cols-2 gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="githubId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Github Account</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={(value) => {
|
||||||
|
field.onChange(value);
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
defaultValue={field.value}
|
||||||
|
value={field.value}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a Github Account" />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{githubProviders?.map((githubProvider) => (
|
||||||
|
<SelectItem
|
||||||
|
key={githubProvider.githubId}
|
||||||
|
value={githubProvider.githubId}
|
||||||
|
>
|
||||||
|
{githubProvider.gitProvider.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="repository"
|
name="repository"
|
||||||
|
|||||||
@@ -0,0 +1,394 @@
|
|||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Command,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandInput,
|
||||||
|
CommandItem,
|
||||||
|
} from "@/components/ui/command";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { CheckIcon, ChevronsUpDown } from "lucide-react";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const GitlabProviderSchema = z.object({
|
||||||
|
buildPath: z.string().min(1, "Path is required").default("/"),
|
||||||
|
repository: z
|
||||||
|
.object({
|
||||||
|
repo: z.string().min(1, "Repo is required"),
|
||||||
|
owner: z.string().min(1, "Owner is required"),
|
||||||
|
gitlabPathNamespace: z.string().min(1),
|
||||||
|
id: z.number().nullable(),
|
||||||
|
})
|
||||||
|
.required(),
|
||||||
|
branch: z.string().min(1, "Branch is required"),
|
||||||
|
gitlabId: z.string().min(1, "Gitlab Provider is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
type GitlabProvider = z.infer<typeof GitlabProviderSchema>;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
applicationId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SaveGitlabProvider = ({ applicationId }: Props) => {
|
||||||
|
const { data: gitlabProviders } = api.gitlab.gitlabProviders.useQuery();
|
||||||
|
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||||
|
|
||||||
|
const { mutateAsync, isLoading: isSavingGitlabProvider } =
|
||||||
|
api.application.saveGitlabProvider.useMutation();
|
||||||
|
|
||||||
|
const form = useForm<GitlabProvider>({
|
||||||
|
defaultValues: {
|
||||||
|
buildPath: "/",
|
||||||
|
repository: {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
gitlabPathNamespace: "",
|
||||||
|
id: null,
|
||||||
|
},
|
||||||
|
gitlabId: "",
|
||||||
|
branch: "",
|
||||||
|
},
|
||||||
|
resolver: zodResolver(GitlabProviderSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const repository = form.watch("repository");
|
||||||
|
const gitlabId = form.watch("gitlabId");
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: repositories,
|
||||||
|
isLoading: isLoadingRepositories,
|
||||||
|
error,
|
||||||
|
} = api.gitlab.getGitlabRepositories.useQuery(
|
||||||
|
{
|
||||||
|
gitlabId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!gitlabId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
fetchStatus,
|
||||||
|
status,
|
||||||
|
} = api.gitlab.getGitlabBranches.useQuery(
|
||||||
|
{
|
||||||
|
owner: repository?.owner,
|
||||||
|
repo: repository?.repo,
|
||||||
|
id: repository?.id || 0,
|
||||||
|
gitlabId: gitlabId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!repository?.owner && !!repository?.repo && !!gitlabId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data) {
|
||||||
|
form.reset({
|
||||||
|
branch: data.gitlabBranch || "",
|
||||||
|
repository: {
|
||||||
|
repo: data.gitlabRepository || "",
|
||||||
|
owner: data.gitlabOwner || "",
|
||||||
|
gitlabPathNamespace: data.gitlabPathNamespace || "",
|
||||||
|
id: data.gitlabProjectId,
|
||||||
|
},
|
||||||
|
buildPath: data.gitlabBuildPath || "/",
|
||||||
|
gitlabId: data.gitlabId || "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [form.reset, data, form]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: GitlabProvider) => {
|
||||||
|
await mutateAsync({
|
||||||
|
gitlabBranch: data.branch,
|
||||||
|
gitlabRepository: data.repository.repo,
|
||||||
|
gitlabOwner: data.repository.owner,
|
||||||
|
gitlabBuildPath: data.buildPath,
|
||||||
|
gitlabId: data.gitlabId,
|
||||||
|
applicationId,
|
||||||
|
gitlabProjectId: data.repository.id,
|
||||||
|
gitlabPathNamespace: data.repository.gitlabPathNamespace,
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
toast.success("Service Provided Saved");
|
||||||
|
await refetch();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error to save the gitlab provider");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-4 py-3"
|
||||||
|
>
|
||||||
|
{error && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
<div className="grid md:grid-cols-2 gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="gitlabId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Gitlab Account</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={(value) => {
|
||||||
|
field.onChange(value);
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
id: null,
|
||||||
|
gitlabPathNamespace: "",
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
defaultValue={field.value}
|
||||||
|
value={field.value}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a Gitlab Account" />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{gitlabProviders?.map((gitlabProvider) => (
|
||||||
|
<SelectItem
|
||||||
|
key={gitlabProvider.gitlabId}
|
||||||
|
value={gitlabProvider.gitlabId}
|
||||||
|
>
|
||||||
|
{gitlabProvider.gitProvider.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="repository"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Repository</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
className={cn(
|
||||||
|
"w-full justify-between !bg-input",
|
||||||
|
!field.value && "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{isLoadingRepositories
|
||||||
|
? "Loading...."
|
||||||
|
: field.value.owner
|
||||||
|
? repositories?.find(
|
||||||
|
(repo) => repo.name === field.value.repo,
|
||||||
|
)?.name
|
||||||
|
: "Select repository"}
|
||||||
|
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput
|
||||||
|
placeholder="Search repository..."
|
||||||
|
className="h-9"
|
||||||
|
/>
|
||||||
|
{isLoadingRepositories && (
|
||||||
|
<span className="py-6 text-center text-sm">
|
||||||
|
Loading Repositories....
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<CommandEmpty>No repositories found.</CommandEmpty>
|
||||||
|
<ScrollArea className="h-96">
|
||||||
|
<CommandGroup>
|
||||||
|
{repositories && repositories.length === 0 && (
|
||||||
|
<CommandEmpty>
|
||||||
|
No repositories found.
|
||||||
|
</CommandEmpty>
|
||||||
|
)}
|
||||||
|
{repositories?.map((repo) => {
|
||||||
|
return (
|
||||||
|
<CommandItem
|
||||||
|
value={repo.url}
|
||||||
|
key={repo.url}
|
||||||
|
onSelect={() => {
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: repo.owner.username as string,
|
||||||
|
repo: repo.name,
|
||||||
|
id: repo.id,
|
||||||
|
gitlabPathNamespace: repo.url,
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{repo.name}
|
||||||
|
<CheckIcon
|
||||||
|
className={cn(
|
||||||
|
"ml-auto h-4 w-4",
|
||||||
|
repo.name === field.value.repo
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CommandItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</CommandGroup>
|
||||||
|
</ScrollArea>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
{form.formState.errors.repository && (
|
||||||
|
<p className={cn("text-sm font-medium text-destructive")}>
|
||||||
|
Repository is required
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="branch"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="block w-full">
|
||||||
|
<FormLabel>Branch</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
className={cn(
|
||||||
|
" w-full justify-between !bg-input",
|
||||||
|
!field.value && "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{status === "loading" && fetchStatus === "fetching"
|
||||||
|
? "Loading...."
|
||||||
|
: field.value
|
||||||
|
? branches?.find(
|
||||||
|
(branch) => branch.name === field.value,
|
||||||
|
)?.name
|
||||||
|
: "Select branch"}
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput
|
||||||
|
placeholder="Search branch..."
|
||||||
|
className="h-9"
|
||||||
|
/>
|
||||||
|
{status === "loading" && fetchStatus === "fetching" && (
|
||||||
|
<span className="py-6 text-center text-sm text-muted-foreground">
|
||||||
|
Loading Branches....
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{!repository?.owner && (
|
||||||
|
<span className="py-6 text-center text-sm text-muted-foreground">
|
||||||
|
Select a repository
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<ScrollArea className="h-96">
|
||||||
|
<CommandEmpty>No branch found.</CommandEmpty>
|
||||||
|
|
||||||
|
<CommandGroup>
|
||||||
|
{branches?.map((branch) => (
|
||||||
|
<CommandItem
|
||||||
|
value={branch.name}
|
||||||
|
key={branch.commit.id}
|
||||||
|
onSelect={() => {
|
||||||
|
form.setValue("branch", branch.name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{branch.name}
|
||||||
|
<CheckIcon
|
||||||
|
className={cn(
|
||||||
|
"ml-auto h-4 w-4",
|
||||||
|
branch.name === field.value
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</ScrollArea>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</Popover>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="buildPath"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Build Path</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="/" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full justify-end">
|
||||||
|
<Button
|
||||||
|
isLoading={isSavingGitlabProvider}
|
||||||
|
type="submit"
|
||||||
|
className="w-fit"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,23 +1,34 @@
|
|||||||
import { SaveDockerProvider } from "@/components/dashboard/application/general/generic/save-docker-provider";
|
import { SaveDockerProvider } from "@/components/dashboard/application/general/generic/save-docker-provider";
|
||||||
import { SaveGitProvider } from "@/components/dashboard/application/general/generic/save-git-provider";
|
import { SaveGitProvider } from "@/components/dashboard/application/general/generic/save-git-provider";
|
||||||
import { SaveGithubProvider } from "@/components/dashboard/application/general/generic/save-github-provider";
|
import { SaveGithubProvider } from "@/components/dashboard/application/general/generic/save-github-provider";
|
||||||
|
import {
|
||||||
|
BitbucketIcon,
|
||||||
|
DockerIcon,
|
||||||
|
GitIcon,
|
||||||
|
GithubIcon,
|
||||||
|
GitlabIcon,
|
||||||
|
} from "@/components/icons/data-tools-icons";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { GitBranch, LockIcon } from "lucide-react";
|
import { GitBranch, LockIcon, UploadCloud } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { SaveBitbucketProvider } from "./save-bitbucket-provider";
|
||||||
import { SaveDragNDrop } from "./save-drag-n-drop";
|
import { SaveDragNDrop } from "./save-drag-n-drop";
|
||||||
|
import { SaveGitlabProvider } from "./save-gitlab-provider";
|
||||||
|
|
||||||
type TabState = "github" | "docker" | "git" | "drop";
|
type TabState = "github" | "docker" | "git" | "drop" | "gitlab" | "bitbucket";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShowProviderForm = ({ applicationId }: Props) => {
|
export const ShowProviderForm = ({ applicationId }: Props) => {
|
||||||
const { data: haveGithubConfigured } =
|
const { data: githubProviders } = api.github.githubProviders.useQuery();
|
||||||
api.admin.haveGithubConfigured.useQuery();
|
const { data: gitlabProviders } = api.gitlab.gitlabProviders.useQuery();
|
||||||
|
const { data: bitbucketProviders } =
|
||||||
|
api.bitbucket.bitbucketProviders.useQuery();
|
||||||
|
|
||||||
const { data: application } = api.application.one.useQuery({ applicationId });
|
const { data: application } = api.application.one.useQuery({ applicationId });
|
||||||
const [tab, setSab] = useState<TabState>(application?.sourceType || "github");
|
const [tab, setSab] = useState<TabState>(application?.sourceType || "github");
|
||||||
@@ -44,43 +55,104 @@ export const ShowProviderForm = ({ applicationId }: Props) => {
|
|||||||
setSab(e as TabState);
|
setSab(e as TabState);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TabsList className="grid w-fit grid-cols-4 bg-transparent">
|
<div className="flex flex-row items-center justify-between w-full gap-4">
|
||||||
<TabsTrigger
|
<TabsList className="md:grid md:w-fit md:grid-cols-7 max-md:overflow-x-scroll justify-start bg-transparent overflow-y-hidden">
|
||||||
value="github"
|
<TabsTrigger
|
||||||
className="rounded-none border-b-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
value="github"
|
||||||
>
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
Github
|
>
|
||||||
</TabsTrigger>
|
<GithubIcon className="size-4 text-current fill-current" />
|
||||||
<TabsTrigger
|
Github
|
||||||
value="docker"
|
</TabsTrigger>
|
||||||
className="rounded-none border-b-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
<TabsTrigger
|
||||||
>
|
value="gitlab"
|
||||||
Docker
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
</TabsTrigger>
|
>
|
||||||
<TabsTrigger
|
<GitlabIcon className="size-4 text-current fill-current" />
|
||||||
value="git"
|
Gitlab
|
||||||
className="rounded-none border-b-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
</TabsTrigger>
|
||||||
>
|
<TabsTrigger
|
||||||
Git
|
value="bitbucket"
|
||||||
</TabsTrigger>
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
<TabsTrigger
|
>
|
||||||
value="drop"
|
<BitbucketIcon className="size-4 text-current fill-current" />
|
||||||
className="rounded-none border-b-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
Bitbucket
|
||||||
>
|
</TabsTrigger>
|
||||||
Drop
|
<TabsTrigger
|
||||||
</TabsTrigger>
|
value="docker"
|
||||||
</TabsList>
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
|
>
|
||||||
|
<DockerIcon className="size-5 text-current" />
|
||||||
|
Docker
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger
|
||||||
|
value="git"
|
||||||
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
|
>
|
||||||
|
<GitIcon />
|
||||||
|
Git
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger
|
||||||
|
value="drop"
|
||||||
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
|
>
|
||||||
|
<UploadCloud className="size-5 text-current" />
|
||||||
|
Drop
|
||||||
|
</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
</div>
|
||||||
|
|
||||||
<TabsContent value="github" className="w-full p-2">
|
<TabsContent value="github" className="w-full p-2">
|
||||||
{haveGithubConfigured ? (
|
{githubProviders && githubProviders?.length > 0 ? (
|
||||||
<SaveGithubProvider applicationId={applicationId} />
|
<SaveGithubProvider applicationId={applicationId} />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center gap-3">
|
<div className="flex flex-col items-center gap-3 min-h-[15vh] justify-center">
|
||||||
<LockIcon className="size-8 text-muted-foreground" />
|
<GithubIcon className="size-8 text-muted-foreground" />
|
||||||
<span className="text-base text-muted-foreground">
|
<span className="text-base text-muted-foreground">
|
||||||
To deploy using GitHub, you need to configure your account
|
To deploy using GitHub, you need to configure your account
|
||||||
first. Please, go to{" "}
|
first. Please, go to{" "}
|
||||||
<Link
|
<Link
|
||||||
href="/dashboard/settings/server"
|
href="/dashboard/settings/git-providers"
|
||||||
|
className="text-foreground"
|
||||||
|
>
|
||||||
|
Settings
|
||||||
|
</Link>{" "}
|
||||||
|
to do so.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="gitlab" className="w-full p-2">
|
||||||
|
{gitlabProviders && gitlabProviders?.length > 0 ? (
|
||||||
|
<SaveGitlabProvider applicationId={applicationId} />
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col items-center gap-3 min-h-[15vh] justify-center">
|
||||||
|
<GitlabIcon className="size-8 text-muted-foreground" />
|
||||||
|
<span className="text-base text-muted-foreground">
|
||||||
|
To deploy using GitLab, you need to configure your account
|
||||||
|
first. Please, go to{" "}
|
||||||
|
<Link
|
||||||
|
href="/dashboard/settings/git-providers"
|
||||||
|
className="text-foreground"
|
||||||
|
>
|
||||||
|
Settings
|
||||||
|
</Link>{" "}
|
||||||
|
to do so.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="bitbucket" className="w-full p-2">
|
||||||
|
{bitbucketProviders && bitbucketProviders?.length > 0 ? (
|
||||||
|
<SaveBitbucketProvider applicationId={applicationId} />
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col items-center gap-3 min-h-[15vh] justify-center">
|
||||||
|
<BitbucketIcon className="size-8 text-muted-foreground" />
|
||||||
|
<span className="text-base text-muted-foreground">
|
||||||
|
To deploy using Bitbucket, you need to configure your account
|
||||||
|
first. Please, go to{" "}
|
||||||
|
<Link
|
||||||
|
href="/dashboard/settings/git-providers"
|
||||||
className="text-foreground"
|
className="text-foreground"
|
||||||
>
|
>
|
||||||
Settings
|
Settings
|
||||||
@@ -93,6 +165,7 @@ export const ShowProviderForm = ({ applicationId }: Props) => {
|
|||||||
<TabsContent value="docker" className="w-full p-2">
|
<TabsContent value="docker" className="w-full p-2">
|
||||||
<SaveDockerProvider applicationId={applicationId} />
|
<SaveDockerProvider applicationId={applicationId} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="git" className="w-full p-2">
|
<TabsContent value="git" className="w-full p-2">
|
||||||
<SaveGitProvider applicationId={applicationId} />
|
<SaveGitProvider applicationId={applicationId} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|||||||
@@ -166,7 +166,13 @@ export const AddDomainCompose = ({
|
|||||||
<DialogTitle>Domain</DialogTitle>
|
<DialogTitle>Domain</DialogTitle>
|
||||||
<DialogDescription>{dictionary.dialogDescription}</DialogDescription>
|
<DialogDescription>{dictionary.dialogDescription}</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
<div className="flex flex-col gap-4">
|
||||||
|
<AlertBlock type="info">
|
||||||
|
Deploy is required to apply changes after creating or updating a
|
||||||
|
domain.
|
||||||
|
</AlertBlock>
|
||||||
|
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
</div>
|
||||||
|
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
|
|||||||
@@ -0,0 +1,380 @@
|
|||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Command,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandInput,
|
||||||
|
CommandItem,
|
||||||
|
} from "@/components/ui/command";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { CheckIcon, ChevronsUpDown } from "lucide-react";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const BitbucketProviderSchema = z.object({
|
||||||
|
composePath: z.string().min(1),
|
||||||
|
repository: z
|
||||||
|
.object({
|
||||||
|
repo: z.string().min(1, "Repo is required"),
|
||||||
|
owner: z.string().min(1, "Owner is required"),
|
||||||
|
})
|
||||||
|
.required(),
|
||||||
|
branch: z.string().min(1, "Branch is required"),
|
||||||
|
bitbucketId: z.string().min(1, "Bitbucket Provider is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
type BitbucketProvider = z.infer<typeof BitbucketProviderSchema>;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
composeId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SaveBitbucketProviderCompose = ({ composeId }: Props) => {
|
||||||
|
const { data: bitbucketProviders } =
|
||||||
|
api.bitbucket.bitbucketProviders.useQuery();
|
||||||
|
const { data, refetch } = api.compose.one.useQuery({ composeId });
|
||||||
|
|
||||||
|
const { mutateAsync, isLoading: isSavingBitbucketProvider } =
|
||||||
|
api.compose.update.useMutation();
|
||||||
|
|
||||||
|
const form = useForm<BitbucketProvider>({
|
||||||
|
defaultValues: {
|
||||||
|
composePath: "./docker-compose.yml",
|
||||||
|
repository: {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
},
|
||||||
|
bitbucketId: "",
|
||||||
|
branch: "",
|
||||||
|
},
|
||||||
|
resolver: zodResolver(BitbucketProviderSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const repository = form.watch("repository");
|
||||||
|
const bitbucketId = form.watch("bitbucketId");
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: repositories,
|
||||||
|
isLoading: isLoadingRepositories,
|
||||||
|
error,
|
||||||
|
isError,
|
||||||
|
} = api.bitbucket.getBitbucketRepositories.useQuery(
|
||||||
|
{
|
||||||
|
bitbucketId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!bitbucketId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
fetchStatus,
|
||||||
|
status,
|
||||||
|
} = api.bitbucket.getBitbucketBranches.useQuery(
|
||||||
|
{
|
||||||
|
owner: repository?.owner,
|
||||||
|
repo: repository?.repo,
|
||||||
|
bitbucketId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!repository?.owner && !!repository?.repo && !!bitbucketId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data) {
|
||||||
|
form.reset({
|
||||||
|
branch: data.bitbucketBranch || "",
|
||||||
|
repository: {
|
||||||
|
repo: data.bitbucketRepository || "",
|
||||||
|
owner: data.bitbucketOwner || "",
|
||||||
|
},
|
||||||
|
composePath: data.composePath,
|
||||||
|
bitbucketId: data.bitbucketId || "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [form.reset, data, form]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: BitbucketProvider) => {
|
||||||
|
await mutateAsync({
|
||||||
|
bitbucketBranch: data.branch,
|
||||||
|
bitbucketRepository: data.repository.repo,
|
||||||
|
bitbucketOwner: data.repository.owner,
|
||||||
|
bitbucketId: data.bitbucketId,
|
||||||
|
composePath: data.composePath,
|
||||||
|
composeId,
|
||||||
|
sourceType: "bitbucket",
|
||||||
|
composeStatus: "idle",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
toast.success("Service Provided Saved");
|
||||||
|
await refetch();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error to save the Bitbucket provider");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-4 py-3"
|
||||||
|
>
|
||||||
|
{error && (
|
||||||
|
<AlertBlock type="error">Repositories: {error.message}</AlertBlock>
|
||||||
|
)}
|
||||||
|
<div className="grid md:grid-cols-2 gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="bitbucketId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Bitbucket Account</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={(value) => {
|
||||||
|
field.onChange(value);
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
defaultValue={field.value}
|
||||||
|
value={field.value}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a Bitbucket Account" />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{bitbucketProviders?.map((bitbucketProvider) => (
|
||||||
|
<SelectItem
|
||||||
|
key={bitbucketProvider.bitbucketId}
|
||||||
|
value={bitbucketProvider.bitbucketId}
|
||||||
|
>
|
||||||
|
{bitbucketProvider.gitProvider.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="repository"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Repository</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
className={cn(
|
||||||
|
"w-full justify-between !bg-input",
|
||||||
|
!field.value && "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{isLoadingRepositories
|
||||||
|
? "Loading...."
|
||||||
|
: field.value.owner
|
||||||
|
? repositories?.find(
|
||||||
|
(repo) => repo.name === field.value.repo,
|
||||||
|
)?.name
|
||||||
|
: "Select repository"}
|
||||||
|
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput
|
||||||
|
placeholder="Search repository..."
|
||||||
|
className="h-9"
|
||||||
|
/>
|
||||||
|
{isLoadingRepositories && (
|
||||||
|
<span className="py-6 text-center text-sm">
|
||||||
|
Loading Repositories....
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<CommandEmpty>No repositories found.</CommandEmpty>
|
||||||
|
<ScrollArea className="h-96">
|
||||||
|
<CommandGroup>
|
||||||
|
{repositories?.map((repo) => (
|
||||||
|
<CommandItem
|
||||||
|
value={repo.url}
|
||||||
|
key={repo.url}
|
||||||
|
onSelect={() => {
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: repo.owner.username as string,
|
||||||
|
repo: repo.name,
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{repo.name}
|
||||||
|
<CheckIcon
|
||||||
|
className={cn(
|
||||||
|
"ml-auto h-4 w-4",
|
||||||
|
repo.name === field.value.repo
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</ScrollArea>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
{form.formState.errors.repository && (
|
||||||
|
<p className={cn("text-sm font-medium text-destructive")}>
|
||||||
|
Repository is required
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="branch"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="block w-full">
|
||||||
|
<FormLabel>Branch</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
className={cn(
|
||||||
|
" w-full justify-between !bg-input",
|
||||||
|
!field.value && "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{status === "loading" && fetchStatus === "fetching"
|
||||||
|
? "Loading...."
|
||||||
|
: field.value
|
||||||
|
? branches?.find(
|
||||||
|
(branch) => branch.name === field.value,
|
||||||
|
)?.name
|
||||||
|
: "Select branch"}
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput
|
||||||
|
placeholder="Search branch..."
|
||||||
|
className="h-9"
|
||||||
|
/>
|
||||||
|
{status === "loading" && fetchStatus === "fetching" && (
|
||||||
|
<span className="py-6 text-center text-sm text-muted-foreground">
|
||||||
|
Loading Branches....
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{!repository?.owner && (
|
||||||
|
<span className="py-6 text-center text-sm text-muted-foreground">
|
||||||
|
Select a repository
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<ScrollArea className="h-96">
|
||||||
|
<CommandEmpty>No branch found.</CommandEmpty>
|
||||||
|
|
||||||
|
<CommandGroup>
|
||||||
|
{branches?.map((branch) => (
|
||||||
|
<CommandItem
|
||||||
|
value={branch.name}
|
||||||
|
key={branch.commit.sha}
|
||||||
|
onSelect={() => {
|
||||||
|
form.setValue("branch", branch.name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{branch.name}
|
||||||
|
<CheckIcon
|
||||||
|
className={cn(
|
||||||
|
"ml-auto h-4 w-4",
|
||||||
|
branch.name === field.value
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</ScrollArea>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</Popover>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="composePath"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Compose Path</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="docker-compose.yml" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full justify-end">
|
||||||
|
<Button
|
||||||
|
isLoading={isSavingBitbucketProvider}
|
||||||
|
type="submit"
|
||||||
|
className="w-fit"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -21,6 +21,13 @@ import {
|
|||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
} from "@/components/ui/popover";
|
} from "@/components/ui/popover";
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
@@ -39,6 +46,7 @@ const GithubProviderSchema = z.object({
|
|||||||
})
|
})
|
||||||
.required(),
|
.required(),
|
||||||
branch: z.string().min(1, "Branch is required"),
|
branch: z.string().min(1, "Branch is required"),
|
||||||
|
githubId: z.string().min(1, "Github Provider is required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
type GithubProvider = z.infer<typeof GithubProviderSchema>;
|
type GithubProvider = z.infer<typeof GithubProviderSchema>;
|
||||||
@@ -48,6 +56,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const SaveGithubProviderCompose = ({ composeId }: Props) => {
|
export const SaveGithubProviderCompose = ({ composeId }: Props) => {
|
||||||
|
const { data: githubProviders } = api.github.githubProviders.useQuery();
|
||||||
const { data, refetch } = api.compose.one.useQuery({ composeId });
|
const { data, refetch } = api.compose.one.useQuery({ composeId });
|
||||||
|
|
||||||
const { mutateAsync, isLoading: isSavingGithubProvider } =
|
const { mutateAsync, isLoading: isSavingGithubProvider } =
|
||||||
@@ -60,26 +69,38 @@ export const SaveGithubProviderCompose = ({ composeId }: Props) => {
|
|||||||
owner: "",
|
owner: "",
|
||||||
repo: "",
|
repo: "",
|
||||||
},
|
},
|
||||||
|
githubId: "",
|
||||||
branch: "",
|
branch: "",
|
||||||
},
|
},
|
||||||
resolver: zodResolver(GithubProviderSchema),
|
resolver: zodResolver(GithubProviderSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
const repository = form.watch("repository");
|
const repository = form.watch("repository");
|
||||||
|
const githubId = form.watch("githubId");
|
||||||
|
|
||||||
const { data: repositories, isLoading: isLoadingRepositories } =
|
const { data: repositories, isLoading: isLoadingRepositories } =
|
||||||
api.admin.getRepositories.useQuery();
|
api.github.getGithubRepositories.useQuery(
|
||||||
|
{
|
||||||
|
githubId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!githubId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: branches,
|
data: branches,
|
||||||
fetchStatus,
|
fetchStatus,
|
||||||
status,
|
status,
|
||||||
} = api.admin.getBranches.useQuery(
|
} = api.github.getGithubBranches.useQuery(
|
||||||
{
|
{
|
||||||
owner: repository?.owner,
|
owner: repository?.owner,
|
||||||
repo: repository?.repo,
|
repo: repository?.repo,
|
||||||
|
githubId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!repository?.owner && !!repository?.repo && !!githubId,
|
||||||
},
|
},
|
||||||
{ enabled: !!repository?.owner && !!repository?.repo },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -91,19 +112,21 @@ export const SaveGithubProviderCompose = ({ composeId }: Props) => {
|
|||||||
owner: data.owner || "",
|
owner: data.owner || "",
|
||||||
},
|
},
|
||||||
composePath: data.composePath,
|
composePath: data.composePath,
|
||||||
|
githubId: data.githubId || "",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [form.reset, data, form]);
|
}, [form.reset, data, form]);
|
||||||
|
|
||||||
const onSubmit = async (data: GithubProvider) => {
|
const onSubmit = async (data: GithubProvider) => {
|
||||||
console.log(data);
|
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
branch: data.branch,
|
branch: data.branch,
|
||||||
repository: data.repository.repo,
|
repository: data.repository.repo,
|
||||||
composeId: composeId,
|
composeId,
|
||||||
owner: data.repository.owner,
|
owner: data.repository.owner,
|
||||||
sourceType: "github",
|
|
||||||
composePath: data.composePath,
|
composePath: data.composePath,
|
||||||
|
githubId: data.githubId,
|
||||||
|
sourceType: "github",
|
||||||
|
composeStatus: "idle",
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
toast.success("Service Provided Saved");
|
toast.success("Service Provided Saved");
|
||||||
@@ -122,6 +145,45 @@ export const SaveGithubProviderCompose = ({ composeId }: Props) => {
|
|||||||
className="grid w-full gap-4 py-3"
|
className="grid w-full gap-4 py-3"
|
||||||
>
|
>
|
||||||
<div className="grid md:grid-cols-2 gap-4">
|
<div className="grid md:grid-cols-2 gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="githubId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Github Account</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={(value) => {
|
||||||
|
field.onChange(value);
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
defaultValue={field.value}
|
||||||
|
value={field.value}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a Github Account" />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{githubProviders?.map((githubProvider) => (
|
||||||
|
<SelectItem
|
||||||
|
key={githubProvider.githubId}
|
||||||
|
value={githubProvider.githubId}
|
||||||
|
>
|
||||||
|
{githubProvider.gitProvider.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="repository"
|
name="repository"
|
||||||
@@ -278,7 +340,6 @@ export const SaveGithubProviderCompose = ({ composeId }: Props) => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="composePath"
|
name="composePath"
|
||||||
|
|||||||
@@ -0,0 +1,396 @@
|
|||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Command,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandInput,
|
||||||
|
CommandItem,
|
||||||
|
} from "@/components/ui/command";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { CheckIcon, ChevronsUpDown } from "lucide-react";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const GitlabProviderSchema = z.object({
|
||||||
|
composePath: z.string().min(1),
|
||||||
|
repository: z
|
||||||
|
.object({
|
||||||
|
repo: z.string().min(1, "Repo is required"),
|
||||||
|
owner: z.string().min(1, "Owner is required"),
|
||||||
|
id: z.number().nullable(),
|
||||||
|
gitlabPathNamespace: z.string().min(1),
|
||||||
|
})
|
||||||
|
.required(),
|
||||||
|
branch: z.string().min(1, "Branch is required"),
|
||||||
|
gitlabId: z.string().min(1, "Gitlab Provider is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
type GitlabProvider = z.infer<typeof GitlabProviderSchema>;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
composeId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SaveGitlabProviderCompose = ({ composeId }: Props) => {
|
||||||
|
const { data: gitlabProviders } = api.gitlab.gitlabProviders.useQuery();
|
||||||
|
const { data, refetch } = api.compose.one.useQuery({ composeId });
|
||||||
|
|
||||||
|
const { mutateAsync, isLoading: isSavingGitlabProvider } =
|
||||||
|
api.compose.update.useMutation();
|
||||||
|
|
||||||
|
const form = useForm<GitlabProvider>({
|
||||||
|
defaultValues: {
|
||||||
|
composePath: "./docker-compose.yml",
|
||||||
|
repository: {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
gitlabPathNamespace: "",
|
||||||
|
id: null,
|
||||||
|
},
|
||||||
|
gitlabId: "",
|
||||||
|
branch: "",
|
||||||
|
},
|
||||||
|
resolver: zodResolver(GitlabProviderSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const repository = form.watch("repository");
|
||||||
|
const gitlabId = form.watch("gitlabId");
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: repositories,
|
||||||
|
isLoading: isLoadingRepositories,
|
||||||
|
error,
|
||||||
|
} = api.gitlab.getGitlabRepositories.useQuery(
|
||||||
|
{
|
||||||
|
gitlabId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!gitlabId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
fetchStatus,
|
||||||
|
status,
|
||||||
|
} = api.gitlab.getGitlabBranches.useQuery(
|
||||||
|
{
|
||||||
|
owner: repository?.owner,
|
||||||
|
repo: repository?.repo,
|
||||||
|
id: repository?.id || 0,
|
||||||
|
gitlabId: gitlabId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!repository?.owner && !!repository?.repo && !!gitlabId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data) {
|
||||||
|
form.reset({
|
||||||
|
branch: data.gitlabBranch || "",
|
||||||
|
repository: {
|
||||||
|
repo: data.gitlabRepository || "",
|
||||||
|
owner: data.gitlabOwner || "",
|
||||||
|
id: data.gitlabProjectId,
|
||||||
|
gitlabPathNamespace: data.gitlabPathNamespace || "",
|
||||||
|
},
|
||||||
|
composePath: data.composePath,
|
||||||
|
gitlabId: data.gitlabId || "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [form.reset, data, form]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: GitlabProvider) => {
|
||||||
|
await mutateAsync({
|
||||||
|
gitlabBranch: data.branch,
|
||||||
|
gitlabRepository: data.repository.repo,
|
||||||
|
gitlabOwner: data.repository.owner,
|
||||||
|
composePath: data.composePath,
|
||||||
|
gitlabId: data.gitlabId,
|
||||||
|
composeId,
|
||||||
|
gitlabProjectId: data.repository.id,
|
||||||
|
gitlabPathNamespace: data.repository.gitlabPathNamespace,
|
||||||
|
sourceType: "gitlab",
|
||||||
|
composeStatus: "idle",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
toast.success("Service Provided Saved");
|
||||||
|
await refetch();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error to save the gitlab provider");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-4 py-3"
|
||||||
|
>
|
||||||
|
{error && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
<div className="grid md:grid-cols-2 gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="gitlabId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Gitlab Account</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={(value) => {
|
||||||
|
field.onChange(value);
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: "",
|
||||||
|
repo: "",
|
||||||
|
gitlabPathNamespace: "",
|
||||||
|
id: null,
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
defaultValue={field.value}
|
||||||
|
value={field.value}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a Gitlab Account" />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{gitlabProviders?.map((gitlabProvider) => (
|
||||||
|
<SelectItem
|
||||||
|
key={gitlabProvider.gitlabId}
|
||||||
|
value={gitlabProvider.gitlabId}
|
||||||
|
>
|
||||||
|
{gitlabProvider.gitProvider.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="repository"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="md:col-span-2 flex flex-col">
|
||||||
|
<FormLabel>Repository</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
className={cn(
|
||||||
|
"w-full justify-between !bg-input",
|
||||||
|
!field.value && "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{isLoadingRepositories
|
||||||
|
? "Loading...."
|
||||||
|
: field.value.owner
|
||||||
|
? repositories?.find(
|
||||||
|
(repo) => repo.name === field.value.repo,
|
||||||
|
)?.name
|
||||||
|
: "Select repository"}
|
||||||
|
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput
|
||||||
|
placeholder="Search repository..."
|
||||||
|
className="h-9"
|
||||||
|
/>
|
||||||
|
{isLoadingRepositories && (
|
||||||
|
<span className="py-6 text-center text-sm">
|
||||||
|
Loading Repositories....
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<CommandEmpty>No repositories found.</CommandEmpty>
|
||||||
|
<ScrollArea className="h-96">
|
||||||
|
<CommandGroup>
|
||||||
|
{repositories && repositories.length === 0 && (
|
||||||
|
<CommandEmpty>
|
||||||
|
No repositories found.
|
||||||
|
</CommandEmpty>
|
||||||
|
)}
|
||||||
|
{repositories?.map((repo) => {
|
||||||
|
return (
|
||||||
|
<CommandItem
|
||||||
|
value={repo.url}
|
||||||
|
key={repo.url}
|
||||||
|
onSelect={() => {
|
||||||
|
form.setValue("repository", {
|
||||||
|
owner: repo.owner.username as string,
|
||||||
|
repo: repo.name,
|
||||||
|
id: repo.id,
|
||||||
|
gitlabPathNamespace: repo.url,
|
||||||
|
});
|
||||||
|
form.setValue("branch", "");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{repo.name}
|
||||||
|
<CheckIcon
|
||||||
|
className={cn(
|
||||||
|
"ml-auto h-4 w-4",
|
||||||
|
repo.name === field.value.repo
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CommandItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</CommandGroup>
|
||||||
|
</ScrollArea>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
{form.formState.errors.repository && (
|
||||||
|
<p className={cn("text-sm font-medium text-destructive")}>
|
||||||
|
Repository is required
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="branch"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="block w-full">
|
||||||
|
<FormLabel>Branch</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
className={cn(
|
||||||
|
" w-full justify-between !bg-input",
|
||||||
|
!field.value && "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{status === "loading" && fetchStatus === "fetching"
|
||||||
|
? "Loading...."
|
||||||
|
: field.value
|
||||||
|
? branches?.find(
|
||||||
|
(branch) => branch.name === field.value,
|
||||||
|
)?.name
|
||||||
|
: "Select branch"}
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput
|
||||||
|
placeholder="Search branch..."
|
||||||
|
className="h-9"
|
||||||
|
/>
|
||||||
|
{status === "loading" && fetchStatus === "fetching" && (
|
||||||
|
<span className="py-6 text-center text-sm text-muted-foreground">
|
||||||
|
Loading Branches....
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{!repository?.owner && (
|
||||||
|
<span className="py-6 text-center text-sm text-muted-foreground">
|
||||||
|
Select a repository
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<ScrollArea className="h-96">
|
||||||
|
<CommandEmpty>No branch found.</CommandEmpty>
|
||||||
|
|
||||||
|
<CommandGroup>
|
||||||
|
{branches?.map((branch) => (
|
||||||
|
<CommandItem
|
||||||
|
value={branch.name}
|
||||||
|
key={branch.commit.id}
|
||||||
|
onSelect={() => {
|
||||||
|
form.setValue("branch", branch.name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{branch.name}
|
||||||
|
<CheckIcon
|
||||||
|
className={cn(
|
||||||
|
"ml-auto h-4 w-4",
|
||||||
|
branch.name === field.value
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</ScrollArea>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</Popover>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="composePath"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Compose Path</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="docker-compose.yml" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full justify-end">
|
||||||
|
<Button
|
||||||
|
isLoading={isSavingGitlabProvider}
|
||||||
|
type="submit"
|
||||||
|
className="w-fit"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,22 +1,32 @@
|
|||||||
|
import {
|
||||||
|
BitbucketIcon,
|
||||||
|
GitIcon,
|
||||||
|
GithubIcon,
|
||||||
|
GitlabIcon,
|
||||||
|
} from "@/components/icons/data-tools-icons";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { GitBranch, LockIcon } from "lucide-react";
|
import { CodeIcon, GitBranch, LockIcon } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { ComposeFileEditor } from "../compose-file-editor";
|
import { ComposeFileEditor } from "../compose-file-editor";
|
||||||
import { ShowConvertedCompose } from "../show-converted-compose";
|
import { ShowConvertedCompose } from "../show-converted-compose";
|
||||||
|
import { SaveBitbucketProviderCompose } from "./save-bitbucket-provider-compose";
|
||||||
import { SaveGitProviderCompose } from "./save-git-provider-compose";
|
import { SaveGitProviderCompose } from "./save-git-provider-compose";
|
||||||
import { SaveGithubProviderCompose } from "./save-github-provider-compose";
|
import { SaveGithubProviderCompose } from "./save-github-provider-compose";
|
||||||
|
import { SaveGitlabProviderCompose } from "./save-gitlab-provider-compose";
|
||||||
|
|
||||||
type TabState = "github" | "git" | "raw";
|
type TabState = "github" | "git" | "raw" | "gitlab" | "bitbucket";
|
||||||
interface Props {
|
interface Props {
|
||||||
composeId: string;
|
composeId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShowProviderFormCompose = ({ composeId }: Props) => {
|
export const ShowProviderFormCompose = ({ composeId }: Props) => {
|
||||||
const { data: haveGithubConfigured } =
|
const { data: githubProviders } = api.github.githubProviders.useQuery();
|
||||||
api.admin.haveGithubConfigured.useQuery();
|
const { data: gitlabProviders } = api.gitlab.gitlabProviders.useQuery();
|
||||||
|
const { data: bitbucketProviders } =
|
||||||
|
api.bitbucket.bitbucketProviders.useQuery();
|
||||||
|
|
||||||
const { data: compose } = api.compose.one.useQuery({ composeId });
|
const { data: compose } = api.compose.one.useQuery({ composeId });
|
||||||
const [tab, setSab] = useState<TabState>(compose?.sourceType || "github");
|
const [tab, setSab] = useState<TabState>(compose?.sourceType || "github");
|
||||||
@@ -44,38 +54,97 @@ export const ShowProviderFormCompose = ({ composeId }: Props) => {
|
|||||||
setSab(e as TabState);
|
setSab(e as TabState);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TabsList className="grid w-fit grid-cols-4 bg-transparent">
|
<div className="flex flex-row items-center justify-between w-full gap-4">
|
||||||
<TabsTrigger
|
<TabsList className="md:grid md:w-fit md:grid-cols-5 max-md:overflow-x-scroll justify-start bg-transparent overflow-y-hidden">
|
||||||
value="github"
|
<TabsTrigger
|
||||||
className="rounded-none border-b-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
value="github"
|
||||||
>
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
Github
|
>
|
||||||
</TabsTrigger>
|
<GithubIcon className="size-4 text-current fill-current" />
|
||||||
|
Github
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger
|
||||||
|
value="gitlab"
|
||||||
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
|
>
|
||||||
|
<GitlabIcon className="size-4 text-current fill-current" />
|
||||||
|
Gitlab
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger
|
||||||
|
value="bitbucket"
|
||||||
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
|
>
|
||||||
|
<BitbucketIcon className="size-4 text-current fill-current" />
|
||||||
|
Bitbucket
|
||||||
|
</TabsTrigger>
|
||||||
|
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="git"
|
value="git"
|
||||||
className="rounded-none border-b-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
>
|
>
|
||||||
Git
|
<GitIcon />
|
||||||
</TabsTrigger>
|
Git
|
||||||
<TabsTrigger
|
</TabsTrigger>
|
||||||
value="raw"
|
<TabsTrigger
|
||||||
className="rounded-none border-b-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
value="raw"
|
||||||
>
|
className="rounded-none border-b-2 gap-2 border-b-transparent data-[state=active]:border-b-2 data-[state=active]:border-b-border"
|
||||||
Raw
|
>
|
||||||
</TabsTrigger>
|
<CodeIcon className="size-4 " />
|
||||||
</TabsList>
|
Raw
|
||||||
|
</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
</div>
|
||||||
<TabsContent value="github" className="w-full p-2">
|
<TabsContent value="github" className="w-full p-2">
|
||||||
{haveGithubConfigured ? (
|
{githubProviders && githubProviders?.length > 0 ? (
|
||||||
<SaveGithubProviderCompose composeId={composeId} />
|
<SaveGithubProviderCompose composeId={composeId} />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center gap-3">
|
<div className="flex flex-col items-center gap-3 min-h-[15vh] justify-center">
|
||||||
<LockIcon className="size-8 text-muted-foreground" />
|
<GithubIcon className="size-8 text-muted-foreground" />
|
||||||
<span className="text-base text-muted-foreground">
|
<span className="text-base text-muted-foreground">
|
||||||
To deploy using GitHub, you need to configure your account
|
To deploy using GitHub, you need to configure your account
|
||||||
first. Please, go to{" "}
|
first. Please, go to{" "}
|
||||||
<Link
|
<Link
|
||||||
href="/dashboard/settings/server"
|
href="/dashboard/settings/git-providers"
|
||||||
|
className="text-foreground"
|
||||||
|
>
|
||||||
|
Settings
|
||||||
|
</Link>{" "}
|
||||||
|
to do so.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="gitlab" className="w-full p-2">
|
||||||
|
{gitlabProviders && gitlabProviders?.length > 0 ? (
|
||||||
|
<SaveGitlabProviderCompose composeId={composeId} />
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col items-center gap-3 min-h-[15vh] justify-center">
|
||||||
|
<GitlabIcon className="size-8 text-muted-foreground" />
|
||||||
|
<span className="text-base text-muted-foreground">
|
||||||
|
To deploy using GitLab, you need to configure your account
|
||||||
|
first. Please, go to{" "}
|
||||||
|
<Link
|
||||||
|
href="/dashboard/settings/git-providers"
|
||||||
|
className="text-foreground"
|
||||||
|
>
|
||||||
|
Settings
|
||||||
|
</Link>{" "}
|
||||||
|
to do so.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="bitbucket" className="w-full p-2">
|
||||||
|
{bitbucketProviders && bitbucketProviders?.length > 0 ? (
|
||||||
|
<SaveBitbucketProviderCompose composeId={composeId} />
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col items-center gap-3 min-h-[15vh] justify-center">
|
||||||
|
<BitbucketIcon className="size-8 text-muted-foreground" />
|
||||||
|
<span className="text-base text-muted-foreground">
|
||||||
|
To deploy using Bitbucket, you need to configure your account
|
||||||
|
first. Please, go to{" "}
|
||||||
|
<Link
|
||||||
|
href="/dashboard/settings/git-providers"
|
||||||
className="text-foreground"
|
className="text-foreground"
|
||||||
>
|
>
|
||||||
Settings
|
Settings
|
||||||
|
|||||||
@@ -0,0 +1,229 @@
|
|||||||
|
import {
|
||||||
|
BitbucketIcon,
|
||||||
|
GithubIcon,
|
||||||
|
GitlabIcon,
|
||||||
|
} from "@/components/icons/data-tools-icons";
|
||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { CardContent } from "@/components/ui/card";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { useUrl } from "@/utils/hooks/use-url";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { ExternalLink } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const Schema = z.object({
|
||||||
|
name: z.string().min(1, {
|
||||||
|
message: "Name is required",
|
||||||
|
}),
|
||||||
|
username: z.string().min(1, {
|
||||||
|
message: "Username is required",
|
||||||
|
}),
|
||||||
|
password: z.string().min(1, {
|
||||||
|
message: "App Password is required",
|
||||||
|
}),
|
||||||
|
workspaceName: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Schema = z.infer<typeof Schema>;
|
||||||
|
|
||||||
|
export const AddBitbucketProvider = () => {
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const url = useUrl();
|
||||||
|
const { mutateAsync, error, isError } = api.bitbucket.create.useMutation();
|
||||||
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
|
const router = useRouter();
|
||||||
|
const form = useForm<Schema>({
|
||||||
|
defaultValues: {
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
workspaceName: "",
|
||||||
|
},
|
||||||
|
resolver: zodResolver(Schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.reset({
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
workspaceName: "",
|
||||||
|
});
|
||||||
|
}, [form, isOpen]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: Schema) => {
|
||||||
|
await mutateAsync({
|
||||||
|
bitbucketUsername: data.username,
|
||||||
|
appPassword: data.password,
|
||||||
|
bitbucketWorkspaceName: data.workspaceName || "",
|
||||||
|
authId: auth?.id || "",
|
||||||
|
name: data.name || "",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await utils.gitProvider.getAll.invalidate();
|
||||||
|
toast.success("Bitbucket configured successfully");
|
||||||
|
setIsOpen(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error configuring Bitbucket");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
className="flex items-center space-x-1 bg-blue-700 text-white hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
<BitbucketIcon />
|
||||||
|
<span>Bitbucket</span>
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-2xl overflow-y-auto max-h-screen">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle className="flex items-center gap-2">
|
||||||
|
Bitbucket Provider <BitbucketIcon className="size-5" />
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
id="hook-form-add-bitbucket"
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-1"
|
||||||
|
>
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<p className="text-muted-foreground text-sm">
|
||||||
|
To integrate your Bitbucket account, you need to create a new
|
||||||
|
App Password in your Bitbucket settings. Follow these steps:
|
||||||
|
</p>
|
||||||
|
<ol className="list-decimal list-inside text-sm text-muted-foreground">
|
||||||
|
<li className="flex flex-row gap-2 items-center">
|
||||||
|
Create new App Password{" "}
|
||||||
|
<Link
|
||||||
|
href="https://bitbucket.org/account/settings/app-passwords/new"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<ExternalLink className="w-fit text-primary size-4" />
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
When creating the App Password, ensure you grant the
|
||||||
|
following permissions:
|
||||||
|
<ul className="list-disc list-inside ml-4">
|
||||||
|
<li>Account: Read</li>
|
||||||
|
<li>Workspace membership: Read</li>
|
||||||
|
<li>Projects: Read</li>
|
||||||
|
<li>Repositories: Read</li>
|
||||||
|
<li>Pull requests: Read</li>
|
||||||
|
<li>Webhooks: Read and write</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
After creating, you'll receive an App Password. Copy it and
|
||||||
|
paste it below along with your Bitbucket username.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Name</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Random Name eg(my-personal-account)"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="username"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Bitbucket Username</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Your Bitbucket username"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="password"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>App Password</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
type="password"
|
||||||
|
placeholder="ATBBPDYUC94nR96Nj7Cqpp4pfwKk03573DD2"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="workspaceName"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Workspace Name (Optional)</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="For organization accounts"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button isLoading={form.formState.isSubmitting}>
|
||||||
|
Configure Bitbucket
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
import { BitbucketIcon } from "@/components/icons/data-tools-icons";
|
||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { CardContent } from "@/components/ui/card";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { Edit } from "lucide-react";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const Schema = z.object({
|
||||||
|
name: z.string().min(1, {
|
||||||
|
message: "Name is required",
|
||||||
|
}),
|
||||||
|
username: z.string().min(1, {
|
||||||
|
message: "Username is required",
|
||||||
|
}),
|
||||||
|
workspaceName: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Schema = z.infer<typeof Schema>;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
bitbucketId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EditBitbucketProvider = ({ bitbucketId }: Props) => {
|
||||||
|
const { data: bitbucket } = api.bitbucket.one.useQuery(
|
||||||
|
{
|
||||||
|
bitbucketId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!bitbucketId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const { mutateAsync, error, isError } = api.bitbucket.update.useMutation();
|
||||||
|
const { mutateAsync: testConnection, isLoading } =
|
||||||
|
api.bitbucket.testConnection.useMutation();
|
||||||
|
const form = useForm<Schema>({
|
||||||
|
defaultValues: {
|
||||||
|
username: "",
|
||||||
|
workspaceName: "",
|
||||||
|
},
|
||||||
|
resolver: zodResolver(Schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const username = form.watch("username");
|
||||||
|
const workspaceName = form.watch("workspaceName");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.reset({
|
||||||
|
username: bitbucket?.bitbucketUsername || "",
|
||||||
|
workspaceName: bitbucket?.bitbucketWorkspaceName || "",
|
||||||
|
name: bitbucket?.gitProvider.name || "",
|
||||||
|
});
|
||||||
|
}, [form, isOpen]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: Schema) => {
|
||||||
|
await mutateAsync({
|
||||||
|
bitbucketId,
|
||||||
|
gitProviderId: bitbucket?.gitProviderId || "",
|
||||||
|
bitbucketUsername: data.username,
|
||||||
|
bitbucketWorkspaceName: data.workspaceName || "",
|
||||||
|
name: data.name || "",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await utils.gitProvider.getAll.invalidate();
|
||||||
|
toast.success("Bitbucket updated successfully");
|
||||||
|
setIsOpen(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error to update Bitbucket");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant="ghost">
|
||||||
|
<Edit className="size-4" />
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-2xl overflow-y-auto max-h-screen">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle className="flex items-center gap-2">
|
||||||
|
Update Bitbucket Provider <BitbucketIcon className="size-5" />
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
id="hook-form-add-bitbucket"
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-1"
|
||||||
|
>
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Name</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Random Name eg(my-personal-account)"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="username"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Bitbucket Username</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Your Bitbucket username"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="workspaceName"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Workspace Name (Optional)</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="For organization accounts"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex w-full justify-end gap-4 mt-4">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant={"secondary"}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onClick={async () => {
|
||||||
|
await testConnection({
|
||||||
|
bitbucketId,
|
||||||
|
bitbucketUsername: username,
|
||||||
|
workspaceName: workspaceName,
|
||||||
|
})
|
||||||
|
.then(async (message) => {
|
||||||
|
toast.info(`Message: ${message}`);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
toast.error(`Error: ${error.message}`);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Test Connection
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" isLoading={form.formState.isSubmitting}>
|
||||||
|
Update
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
import { GithubIcon } from "@/components/icons/data-tools-icons";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { CardContent } from "@/components/ui/card";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { useUrl } from "@/utils/hooks/use-url";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export const AddGithubProvider = () => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const url = useUrl();
|
||||||
|
const { data } = api.auth.get.useQuery();
|
||||||
|
const [manifest, setManifest] = useState("");
|
||||||
|
const [isOrganization, setIsOrganization] = useState(false);
|
||||||
|
const [organizationName, setOrganization] = useState("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const url = document.location.origin;
|
||||||
|
const manifest = JSON.stringify(
|
||||||
|
{
|
||||||
|
redirect_url: `${origin}/api/providers/github/setup?authId=${data?.id}`,
|
||||||
|
name: `Dokploy-${format(new Date(), "yyyy-MM-dd")}`,
|
||||||
|
url: origin,
|
||||||
|
hook_attributes: {
|
||||||
|
url: `${url}/api/deploy/github`,
|
||||||
|
},
|
||||||
|
callback_urls: [`${origin}/api/providers/github/setup`],
|
||||||
|
public: false,
|
||||||
|
request_oauth_on_install: true,
|
||||||
|
default_permissions: {
|
||||||
|
contents: "read",
|
||||||
|
metadata: "read",
|
||||||
|
emails: "read",
|
||||||
|
pull_requests: "write",
|
||||||
|
},
|
||||||
|
default_events: ["pull_request", "push"],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
|
||||||
|
setManifest(manifest);
|
||||||
|
}, [data?.id]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant="secondary" className="flex items-center space-x-1">
|
||||||
|
<GithubIcon />
|
||||||
|
<span>Github</span>
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-2xl ">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle className="flex items-center gap-2">
|
||||||
|
Github Provider <GithubIcon className="size-5" />
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<div id="hook-form-add-project" className="grid w-full gap-1">
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<div className="flex flex-col ">
|
||||||
|
<p className="text-muted-foreground text-sm">
|
||||||
|
To integrate your GitHub account with our services, you'll need
|
||||||
|
to create and install a GitHub app. This process is
|
||||||
|
straightforward and only takes a few minutes. Click the button
|
||||||
|
below to get started.
|
||||||
|
</p>
|
||||||
|
<div className="mt-4 flex flex-col gap-4">
|
||||||
|
<div className="flex flex-row gap-4">
|
||||||
|
<span>Organization?</span>
|
||||||
|
<Switch
|
||||||
|
checked={isOrganization}
|
||||||
|
onCheckedChange={(checked) => setIsOrganization(checked)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isOrganization && (
|
||||||
|
<Input
|
||||||
|
required
|
||||||
|
placeholder="Organization name"
|
||||||
|
onChange={(e) => setOrganization(e.target.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
action={
|
||||||
|
isOrganization
|
||||||
|
? `https://github.com/organizations/${organizationName}/settings/apps/new?state=gh_init:${data?.id}`
|
||||||
|
: `https://github.com/settings/apps/new?state=gh_init:${data?.id}`
|
||||||
|
}
|
||||||
|
method="post"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="manifest"
|
||||||
|
id="manifest"
|
||||||
|
defaultValue={manifest}
|
||||||
|
className="invisible"
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div className="flex w-full justify-end">
|
||||||
|
<Button
|
||||||
|
disabled={isOrganization && organizationName.length < 1}
|
||||||
|
type="submit"
|
||||||
|
className="self-end"
|
||||||
|
>
|
||||||
|
Create GitHub App
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
import { GithubIcon } from "@/components/icons/data-tools-icons";
|
||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { CardContent } from "@/components/ui/card";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { Edit } from "lucide-react";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const Schema = z.object({
|
||||||
|
name: z.string().min(1, {
|
||||||
|
message: "Name is required",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Schema = z.infer<typeof Schema>;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
githubId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EditGithubProvider = ({ githubId }: Props) => {
|
||||||
|
const { data: github } = api.github.one.useQuery(
|
||||||
|
{
|
||||||
|
githubId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!githubId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const { mutateAsync, error, isError } = api.github.update.useMutation();
|
||||||
|
const { mutateAsync: testConnection, isLoading } =
|
||||||
|
api.github.testConnection.useMutation();
|
||||||
|
const form = useForm<Schema>({
|
||||||
|
defaultValues: {
|
||||||
|
name: "",
|
||||||
|
},
|
||||||
|
resolver: zodResolver(Schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.reset({
|
||||||
|
name: github?.gitProvider.name || "",
|
||||||
|
});
|
||||||
|
}, [form, isOpen]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: Schema) => {
|
||||||
|
await mutateAsync({
|
||||||
|
githubId,
|
||||||
|
name: data.name || "",
|
||||||
|
gitProviderId: github?.gitProviderId || "",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await utils.gitProvider.getAll.invalidate();
|
||||||
|
toast.success("Github updated successfully");
|
||||||
|
setIsOpen(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error to update Github");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant="ghost">
|
||||||
|
<Edit className="size-4" />
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-2xl overflow-y-auto max-h-screen">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle className="flex items-center gap-2">
|
||||||
|
Update Github Provider <GithubIcon className="size-5" />
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
id="hook-form-add-github"
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-1"
|
||||||
|
>
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Name</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Random Name eg(my-personal-account)"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex w-full justify-end gap-4 mt-4">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant={"secondary"}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onClick={async () => {
|
||||||
|
await testConnection({
|
||||||
|
githubId,
|
||||||
|
})
|
||||||
|
.then(async (message) => {
|
||||||
|
toast.info(`Message: ${message}`);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
toast.error(`Error: ${error.message}`);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Test Connection
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" isLoading={form.formState.isSubmitting}>
|
||||||
|
Update
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
import { GitlabIcon } from "@/components/icons/data-tools-icons";
|
||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { CardContent } from "@/components/ui/card";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { useUrl } from "@/utils/hooks/use-url";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
|
||||||
|
import { ExternalLink } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const Schema = z.object({
|
||||||
|
name: z.string().min(1, {
|
||||||
|
message: "Name is required",
|
||||||
|
}),
|
||||||
|
applicationId: z.string().min(1, {
|
||||||
|
message: "Application ID is required",
|
||||||
|
}),
|
||||||
|
applicationSecret: z.string().min(1, {
|
||||||
|
message: "Application Secret is required",
|
||||||
|
}),
|
||||||
|
|
||||||
|
redirectUri: z.string().min(1, {
|
||||||
|
message: "Redirect URI is required",
|
||||||
|
}),
|
||||||
|
groupName: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Schema = z.infer<typeof Schema>;
|
||||||
|
|
||||||
|
export const AddGitlabProvider = () => {
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const url = useUrl();
|
||||||
|
const { data: auth } = api.auth.get.useQuery();
|
||||||
|
const { mutateAsync, error, isError } = api.gitlab.create.useMutation();
|
||||||
|
const webhookUrl = `${url}/api/providers/gitlab/callback`;
|
||||||
|
|
||||||
|
const form = useForm<Schema>({
|
||||||
|
defaultValues: {
|
||||||
|
applicationId: "",
|
||||||
|
applicationSecret: "",
|
||||||
|
groupName: "",
|
||||||
|
redirectUri: webhookUrl,
|
||||||
|
},
|
||||||
|
resolver: zodResolver(Schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.reset({
|
||||||
|
applicationId: "",
|
||||||
|
applicationSecret: "",
|
||||||
|
groupName: "",
|
||||||
|
redirectUri: webhookUrl,
|
||||||
|
});
|
||||||
|
}, [form, isOpen]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: Schema) => {
|
||||||
|
await mutateAsync({
|
||||||
|
applicationId: data.applicationId || "",
|
||||||
|
secret: data.applicationSecret || "",
|
||||||
|
groupName: data.groupName || "",
|
||||||
|
authId: auth?.id || "",
|
||||||
|
name: data.name || "",
|
||||||
|
redirectUri: data.redirectUri || "",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await utils.gitProvider.getAll.invalidate();
|
||||||
|
toast.success("GitLab created successfully");
|
||||||
|
setIsOpen(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error configuring GitLab");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="default"
|
||||||
|
className="flex items-center space-x-1 bg-purple-700 text-white hover:bg-purple-600"
|
||||||
|
>
|
||||||
|
<GitlabIcon />
|
||||||
|
<span>GitLab</span>
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-2xl overflow-y-auto max-h-screen ">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle className="flex items-center gap-2">
|
||||||
|
GitLab Provider <GitlabIcon className="size-5" />
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
id="hook-form-add-gitlab"
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-1"
|
||||||
|
>
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<p className="text-muted-foreground text-sm">
|
||||||
|
To integrate your GitLab account, you need to create a new
|
||||||
|
application in your GitLab settings. Follow these steps:
|
||||||
|
</p>
|
||||||
|
<ol className="list-decimal list-inside text-sm text-muted-foreground">
|
||||||
|
<li className="flex flex-row gap-2 items-center">
|
||||||
|
Go to your GitLab profile settings{" "}
|
||||||
|
<Link
|
||||||
|
href="https://gitlab.com/-/profile/applications"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<ExternalLink className="w-fit text-primary size-4" />
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>Navigate to Applications</li>
|
||||||
|
<li>
|
||||||
|
Create a new application with the following details:
|
||||||
|
<ul className="list-disc list-inside ml-4">
|
||||||
|
<li>Name: Dokploy</li>
|
||||||
|
<li>
|
||||||
|
Redirect URI:{" "}
|
||||||
|
<span className="text-primary">{webhookUrl}</span>{" "}
|
||||||
|
</li>
|
||||||
|
<li>Scopes: api, read_user, read_repository</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
After creating, you'll receive an Application ID and Secret,
|
||||||
|
copy them and paste them below.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Name</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Random Name eg(my-personal-account)"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="redirectUri"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Redirect URI</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
disabled
|
||||||
|
placeholder="Random Name eg(my-personal-account)"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="applicationId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Application ID</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="Application ID" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="applicationSecret"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Application Secret</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
type="password"
|
||||||
|
placeholder="Application Secret"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="groupName"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Group Name (Optional)</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="For organization/group access"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button isLoading={form.formState.isSubmitting}>
|
||||||
|
Configure GitLab App
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
import { GitlabIcon } from "@/components/icons/data-tools-icons";
|
||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { CardContent } from "@/components/ui/card";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { useUrl } from "@/utils/hooks/use-url";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { Edit } from "lucide-react";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const Schema = z.object({
|
||||||
|
name: z.string().min(1, {
|
||||||
|
message: "Name is required",
|
||||||
|
}),
|
||||||
|
groupName: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Schema = z.infer<typeof Schema>;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
gitlabId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EditGitlabProvider = ({ gitlabId }: Props) => {
|
||||||
|
const { data: gitlab } = api.gitlab.one.useQuery(
|
||||||
|
{
|
||||||
|
gitlabId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!gitlabId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const { mutateAsync, error, isError } = api.gitlab.update.useMutation();
|
||||||
|
const { mutateAsync: testConnection, isLoading } =
|
||||||
|
api.gitlab.testConnection.useMutation();
|
||||||
|
const form = useForm<Schema>({
|
||||||
|
defaultValues: {
|
||||||
|
groupName: "",
|
||||||
|
name: "",
|
||||||
|
},
|
||||||
|
resolver: zodResolver(Schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const groupName = form.watch("groupName");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.reset({
|
||||||
|
groupName: gitlab?.groupName || "",
|
||||||
|
name: gitlab?.gitProvider.name || "",
|
||||||
|
});
|
||||||
|
}, [form, isOpen]);
|
||||||
|
|
||||||
|
const onSubmit = async (data: Schema) => {
|
||||||
|
await mutateAsync({
|
||||||
|
gitlabId,
|
||||||
|
gitProviderId: gitlab?.gitProviderId || "",
|
||||||
|
groupName: data.groupName || "",
|
||||||
|
name: data.name || "",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await utils.gitProvider.getAll.invalidate();
|
||||||
|
toast.success("Gitlab updated successfully");
|
||||||
|
setIsOpen(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error("Error to update Gitlab");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant="ghost">
|
||||||
|
<Edit className="size-4" />
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-2xl overflow-y-auto max-h-screen">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle className="flex items-center gap-2">
|
||||||
|
Update GitLab Provider <GitlabIcon className="size-5" />
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
id="hook-form-add-bitbucket"
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="grid w-full gap-1"
|
||||||
|
>
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Name</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Random Name eg(my-personal-account)"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="groupName"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Group Name (Optional)</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="For organization/group access"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex w-full justify-end gap-4 mt-4">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant={"secondary"}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onClick={async () => {
|
||||||
|
await testConnection({
|
||||||
|
gitlabId,
|
||||||
|
groupName: groupName || "",
|
||||||
|
})
|
||||||
|
.then(async (message) => {
|
||||||
|
toast.info(`Message: ${message}`);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
toast.error(`Error: ${error.message}`);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Test Connection
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" isLoading={form.formState.isSubmitting}>
|
||||||
|
Update
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -17,31 +17,40 @@ import {
|
|||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from "@/components/ui/tooltip";
|
} from "@/components/ui/tooltip";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { InfoIcon } from "lucide-react";
|
import { InfoIcon, TrashIcon } from "lucide-react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export const RemoveGithubApp = () => {
|
interface Props {
|
||||||
const { refetch } = api.auth.get.useQuery();
|
gitProviderId: string;
|
||||||
|
gitProviderType: "github" | "gitlab" | "bitbucket";
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RemoveGitProvider = ({
|
||||||
|
gitProviderId,
|
||||||
|
gitProviderType,
|
||||||
|
}: Props) => {
|
||||||
const utils = api.useUtils();
|
const utils = api.useUtils();
|
||||||
const { mutateAsync } = api.admin.cleanGithubApp.useMutation();
|
const { mutateAsync } = api.gitProvider.remove.useMutation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button variant="destructive">
|
<Button variant="ghost">
|
||||||
Remove Current Github App
|
<TrashIcon className="size-4 text-muted-destructive" />
|
||||||
<TooltipProvider delayDuration={0}>
|
{gitProviderType === "github" && (
|
||||||
<Tooltip>
|
<TooltipProvider delayDuration={0}>
|
||||||
<TooltipTrigger asChild>
|
<Tooltip>
|
||||||
<InfoIcon className="size-4 fill-muted-destructive text-muted-destructive" />
|
<TooltipTrigger asChild>
|
||||||
</TooltipTrigger>
|
<InfoIcon className="size-4 fill-muted-destructive text-muted-destructive" />
|
||||||
<TooltipContent>
|
</TooltipTrigger>
|
||||||
We recommend deleting the GitHub app first, and then removing
|
<TooltipContent>
|
||||||
the current one from here.
|
We recommend deleting the GitHub app first, and then removing
|
||||||
</TooltipContent>
|
the current one from here.
|
||||||
</Tooltip>
|
</TooltipContent>
|
||||||
</TooltipProvider>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
@@ -56,15 +65,15 @@ export const RemoveGithubApp = () => {
|
|||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||||
<AlertDialogAction
|
<AlertDialogAction
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync()
|
await mutateAsync({
|
||||||
|
gitProviderId: gitProviderId,
|
||||||
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
await refetch();
|
utils.gitProvider.getAll.invalidate();
|
||||||
utils.admin.one.invalidate();
|
toast.success("Git Provider deleted succesfully.");
|
||||||
await utils.admin.haveGithubConfigured.invalidate();
|
|
||||||
toast.success("Github application deleted succesfully.");
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error to delete your github application.");
|
toast.error("Error to delete your git provider.");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
import {
|
||||||
|
BitbucketIcon,
|
||||||
|
GitIcon,
|
||||||
|
GithubIcon,
|
||||||
|
GitlabIcon,
|
||||||
|
} from "@/components/icons/data-tools-icons";
|
||||||
|
import { buttonVariants } from "@/components/ui/button";
|
||||||
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { useUrl } from "@/utils/hooks/use-url";
|
||||||
|
import { formatDate } from "date-fns";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { AddBitbucketProvider } from "./bitbucket/add-bitbucket-provider";
|
||||||
|
import { EditBitbucketProvider } from "./bitbucket/edit-bitbucket-provider";
|
||||||
|
import { AddGithubProvider } from "./github/add-github-provider";
|
||||||
|
import { EditGithubProvider } from "./github/edit-github-provider";
|
||||||
|
import { AddGitlabProvider } from "./gitlab/add-gitlab-provider";
|
||||||
|
import { EditGitlabProvider } from "./gitlab/edit-gitlab-provider";
|
||||||
|
import { RemoveGitProvider } from "./remove-git-provider";
|
||||||
|
|
||||||
|
export const ShowGitProviders = () => {
|
||||||
|
const { data } = api.gitProvider.getAll.useQuery();
|
||||||
|
|
||||||
|
const url = useUrl();
|
||||||
|
|
||||||
|
const getGitlabUrl = (clientId: string, gitlabId: string) => {
|
||||||
|
const redirectUri = `${url}/api/providers/gitlab/callback?gitlabId=${gitlabId}`;
|
||||||
|
|
||||||
|
const scope = "api read_user read_repository";
|
||||||
|
|
||||||
|
const authUrl = `https://gitlab.com/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${encodeURIComponent(scope)}`;
|
||||||
|
|
||||||
|
return authUrl;
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="p-6 space-y-6">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<h1 className="text-2xl font-bold">Git Providers</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect your Git provider for authentication.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Card className=" bg-transparent">
|
||||||
|
<CardContent className="p-4">
|
||||||
|
<div className="flex gap-4 sm:flex-row flex-col w-full">
|
||||||
|
<AddGithubProvider />
|
||||||
|
<AddGitlabProvider />
|
||||||
|
<AddBitbucketProvider />
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<div className="grid gap-4 sm:grid-cols-1 md:grid-cols-1">
|
||||||
|
{data && data.length === 0 && (
|
||||||
|
<div className="flex flex-col items-center gap-3 min-h-[25vh] justify-center">
|
||||||
|
<GitIcon className="size-8" />
|
||||||
|
<span className="text-base text-muted-foreground">
|
||||||
|
No Git Providers found. To add a provider, create a new one such
|
||||||
|
as GitHub, GitLab, or Bitbucket.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{data?.map((gitProvider, index) => {
|
||||||
|
const isGithub = gitProvider.providerType === "github";
|
||||||
|
const isGitlab = gitProvider.providerType === "gitlab";
|
||||||
|
const isBitbucket = gitProvider.providerType === "bitbucket";
|
||||||
|
const haveGithubRequirements =
|
||||||
|
gitProvider.providerType === "github" &&
|
||||||
|
gitProvider.github?.githubPrivateKey &&
|
||||||
|
gitProvider.github?.githubAppId &&
|
||||||
|
gitProvider.github?.githubInstallationId;
|
||||||
|
|
||||||
|
const haveGitlabRequirements =
|
||||||
|
gitProvider.gitlab?.accessToken && gitProvider.gitlab?.refreshToken;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="space-y-4"
|
||||||
|
key={`${gitProvider.gitProviderId}-${index}`}
|
||||||
|
>
|
||||||
|
<Card className="flex sm:flex-row max-sm:gap-2 flex-col justify-between items-center p-4 h-full bg-transparent">
|
||||||
|
<div className="flex items-center space-x-4 w-full">
|
||||||
|
{gitProvider.providerType === "github" && (
|
||||||
|
<GithubIcon className="w-6 h-6" />
|
||||||
|
)}
|
||||||
|
{gitProvider.providerType === "gitlab" && (
|
||||||
|
<GitlabIcon className="w-6 h-6" />
|
||||||
|
)}
|
||||||
|
{gitProvider.providerType === "bitbucket" && (
|
||||||
|
<BitbucketIcon className="w-6 h-6" />
|
||||||
|
)}
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<p className="font-medium">
|
||||||
|
{gitProvider.providerType === "github"
|
||||||
|
? "GitHub"
|
||||||
|
: gitProvider.providerType === "gitlab"
|
||||||
|
? "GitLab"
|
||||||
|
: "Bitbucket"}
|
||||||
|
</p>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
{gitProvider.name}
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Created{" "}
|
||||||
|
{formatDate(
|
||||||
|
gitProvider.createdAt,
|
||||||
|
"yyyy-MM-dd hh:mm:ss a",
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex sm:gap-4 sm:flex-row flex-col">
|
||||||
|
{!haveGithubRequirements && isGithub && (
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<Link
|
||||||
|
href={`${gitProvider?.github?.githubAppName}/installations/new?state=gh_setup:${gitProvider?.github.githubId}`}
|
||||||
|
className={buttonVariants({ className: "w-fit" })}
|
||||||
|
>
|
||||||
|
Install
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{haveGithubRequirements && isGithub && (
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<Link
|
||||||
|
href={`${gitProvider?.github?.githubAppName}`}
|
||||||
|
target="_blank"
|
||||||
|
className={buttonVariants({
|
||||||
|
className: "w-fit",
|
||||||
|
variant: "secondary",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<span className="text-sm">Manage</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!haveGitlabRequirements && isGitlab && (
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<Link
|
||||||
|
href={getGitlabUrl(
|
||||||
|
gitProvider.gitlab?.applicationId || "",
|
||||||
|
gitProvider.gitlab?.gitlabId || "",
|
||||||
|
)}
|
||||||
|
target="_blank"
|
||||||
|
className={buttonVariants({
|
||||||
|
className: "w-fit",
|
||||||
|
variant: "secondary",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<span className="text-sm">Install</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="flex flex-row gap-1">
|
||||||
|
{isBitbucket && (
|
||||||
|
<EditBitbucketProvider
|
||||||
|
bitbucketId={gitProvider.bitbucket.bitbucketId}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isGitlab && haveGitlabRequirements && (
|
||||||
|
<EditGitlabProvider
|
||||||
|
gitlabId={gitProvider.gitlab.gitlabId}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isGithub && haveGithubRequirements && (
|
||||||
|
<EditGithubProvider
|
||||||
|
githubId={gitProvider.github.githubId}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<RemoveGitProvider
|
||||||
|
gitProviderId={gitProvider.gitProviderId}
|
||||||
|
gitProviderType={gitProvider.providerType}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
import { Button, buttonVariants } from "@/components/ui/button";
|
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from "@/components/ui/card";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Switch } from "@/components/ui/switch";
|
|
||||||
import { api } from "@/utils/api";
|
|
||||||
import { format } from "date-fns";
|
|
||||||
import { BadgeCheck } from "lucide-react";
|
|
||||||
import Link from "next/link";
|
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { RemoveGithubApp } from "./remove-github-app";
|
|
||||||
|
|
||||||
export const GithubSetup = () => {
|
|
||||||
const [isOrganization, setIsOrganization] = useState(false);
|
|
||||||
const { data: haveGithubConfigured } =
|
|
||||||
api.admin.haveGithubConfigured.useQuery();
|
|
||||||
const [manifest, setManifest] = useState<string>("");
|
|
||||||
const [organizationName, setOrganization] = useState<string>("");
|
|
||||||
const { data } = api.admin.one.useQuery();
|
|
||||||
useEffect(() => {
|
|
||||||
const url = document.location.origin;
|
|
||||||
const manifest = JSON.stringify(
|
|
||||||
{
|
|
||||||
redirect_url: `${origin}/api/redirect?authId=${data?.authId}`,
|
|
||||||
name: `Dokploy-${format(new Date(), "yyyy-MM-dd")}`,
|
|
||||||
url: origin,
|
|
||||||
hook_attributes: {
|
|
||||||
url: `${url}/api/deploy/github`,
|
|
||||||
// url: `${origin}/api/webhook`, // Aquí especificas la URL del endpoint de tu webhook
|
|
||||||
},
|
|
||||||
callback_urls: [`${origin}/api/redirect`], // Los URLs de callback para procesos de autenticación
|
|
||||||
public: false,
|
|
||||||
request_oauth_on_install: true,
|
|
||||||
default_permissions: {
|
|
||||||
contents: "read",
|
|
||||||
metadata: "read",
|
|
||||||
emails: "read",
|
|
||||||
pull_requests: "write",
|
|
||||||
},
|
|
||||||
default_events: ["pull_request", "push"],
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
4,
|
|
||||||
);
|
|
||||||
|
|
||||||
setManifest(manifest);
|
|
||||||
}, [data?.authId]);
|
|
||||||
return (
|
|
||||||
<Card className="bg-transparent">
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle className="text-xl">Configure Github </CardTitle>
|
|
||||||
<CardDescription>
|
|
||||||
Setup your github account to access to your repositories.
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent className="h-full space-y-2">
|
|
||||||
{haveGithubConfigured ? (
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<span className="text-muted-foreground text-sm">
|
|
||||||
Github account configured succesfully.
|
|
||||||
</span>
|
|
||||||
<BadgeCheck className="size-4 text-green-700" />
|
|
||||||
</div>
|
|
||||||
<div className="flex items-end gap-4 flex-wrap">
|
|
||||||
<RemoveGithubApp />
|
|
||||||
<Link
|
|
||||||
href={`${data?.githubAppName}`}
|
|
||||||
target="_blank"
|
|
||||||
className={buttonVariants({
|
|
||||||
className: "w-fit",
|
|
||||||
variant: "secondary",
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<span className="text-sm">Manage Github App</span>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
{data?.githubAppName ? (
|
|
||||||
<div className="flex w-fit flex-col gap-4">
|
|
||||||
<span className="text-muted-foreground">
|
|
||||||
You've successfully created a github app named{" "}
|
|
||||||
<strong>{data.githubAppName}</strong>! The next step is to
|
|
||||||
install this app in your GitHub account.
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div className="flex flex-row gap-4">
|
|
||||||
<Link
|
|
||||||
href={`${
|
|
||||||
data.githubAppName
|
|
||||||
}/installations/new?state=gh_setup:${data?.authId}`}
|
|
||||||
className={buttonVariants({ className: "w-fit" })}
|
|
||||||
>
|
|
||||||
Install Github App
|
|
||||||
</Link>
|
|
||||||
<RemoveGithubApp />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<p className="text-muted-foreground text-sm">
|
|
||||||
To integrate your GitHub account with our services, you'll
|
|
||||||
need to create and install a GitHub app. This process is
|
|
||||||
straightforward and only takes a few minutes. Click the
|
|
||||||
button below to get started.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-4 flex flex-col gap-4">
|
|
||||||
<div className="flex flex-row gap-4">
|
|
||||||
<span>Organization?</span>
|
|
||||||
<Switch
|
|
||||||
checked={isOrganization}
|
|
||||||
onCheckedChange={(checked) => setIsOrganization(checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{isOrganization && (
|
|
||||||
<Input
|
|
||||||
required
|
|
||||||
placeholder="Organization name"
|
|
||||||
onChange={(e) => setOrganization(e.target.value)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form
|
|
||||||
action={
|
|
||||||
isOrganization
|
|
||||||
? `https://github.com/organizations/${organizationName}/settings/apps/new?state=gh_init:${data?.authId}`
|
|
||||||
: `https://github.com/settings/apps/new?state=gh_init:${data?.authId}`
|
|
||||||
}
|
|
||||||
method="post"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
name="manifest"
|
|
||||||
id="manifest"
|
|
||||||
defaultValue={manifest}
|
|
||||||
className="invisible"
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
disabled={isOrganization && organizationName.length < 1}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Create GitHub App
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { api } from "@/utils/api";
|
|
||||||
import React from "react";
|
|
||||||
import { AppearanceForm } from "./appearance-form";
|
|
||||||
import { ShowCertificates } from "./certificates/show-certificates";
|
|
||||||
import { ShowDestinations } from "./destination/show-destinations";
|
|
||||||
import { GithubSetup } from "./github/github-setup";
|
|
||||||
import { ProfileForm } from "./profile/profile-form";
|
|
||||||
import { ShowUsers } from "./users/show-users";
|
|
||||||
import { WebDomain } from "./web-domain";
|
|
||||||
import { WebServer } from "./web-server";
|
|
||||||
|
|
||||||
export const ShowSettings = () => {
|
|
||||||
const { data } = api.auth.get.useQuery();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"mt-6 md:grid flex flex-col gap-4 pb-20 md:grid-cols-2",
|
|
||||||
data?.rol === "user" && "col-span-2",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div className={cn(data?.rol === "user" && "col-span-2")}>
|
|
||||||
<ProfileForm />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{data?.rol === "admin" && (
|
|
||||||
<>
|
|
||||||
<GithubSetup />
|
|
||||||
<AppearanceForm />
|
|
||||||
<ShowDestinations />
|
|
||||||
<ShowCertificates />
|
|
||||||
<WebDomain />
|
|
||||||
<WebServer />
|
|
||||||
<ShowUsers />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -40,6 +40,7 @@ const addPermissions = z.object({
|
|||||||
canAccessToDocker: z.boolean().optional().default(false),
|
canAccessToDocker: z.boolean().optional().default(false),
|
||||||
canAccessToAPI: z.boolean().optional().default(false),
|
canAccessToAPI: z.boolean().optional().default(false),
|
||||||
canAccessToSSHKeys: z.boolean().optional().default(false),
|
canAccessToSSHKeys: z.boolean().optional().default(false),
|
||||||
|
canAccessToGitProviders: z.boolean().optional().default(false),
|
||||||
});
|
});
|
||||||
|
|
||||||
type AddPermissions = z.infer<typeof addPermissions>;
|
type AddPermissions = z.infer<typeof addPermissions>;
|
||||||
@@ -84,6 +85,7 @@ export const AddUserPermissions = ({ userId }: Props) => {
|
|||||||
canAccessToDocker: data.canAccessToDocker,
|
canAccessToDocker: data.canAccessToDocker,
|
||||||
canAccessToAPI: data.canAccessToAPI,
|
canAccessToAPI: data.canAccessToAPI,
|
||||||
canAccessToSSHKeys: data.canAccessToSSHKeys,
|
canAccessToSSHKeys: data.canAccessToSSHKeys,
|
||||||
|
canAccessToGitProviders: data.canAccessToGitProviders,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [form, form.formState.isSubmitSuccessful, form.reset, data]);
|
}, [form, form.formState.isSubmitSuccessful, form.reset, data]);
|
||||||
@@ -101,6 +103,7 @@ export const AddUserPermissions = ({ userId }: Props) => {
|
|||||||
canAccessToDocker: data.canAccessToDocker,
|
canAccessToDocker: data.canAccessToDocker,
|
||||||
canAccessToAPI: data.canAccessToAPI,
|
canAccessToAPI: data.canAccessToAPI,
|
||||||
canAccessToSSHKeys: data.canAccessToSSHKeys,
|
canAccessToSSHKeys: data.canAccessToSSHKeys,
|
||||||
|
canAccessToGitProviders: data.canAccessToGitProviders,
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
toast.success("Permissions updated");
|
toast.success("Permissions updated");
|
||||||
@@ -293,6 +296,26 @@ export const AddUserPermissions = ({ userId }: Props) => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="canAccessToGitProviders"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-3 shadow-sm">
|
||||||
|
<div className="space-y-0.5">
|
||||||
|
<FormLabel>Access to Git Providers</FormLabel>
|
||||||
|
<FormDescription>
|
||||||
|
Allow to users to access to the Git Providers section
|
||||||
|
</FormDescription>
|
||||||
|
</div>
|
||||||
|
<FormControl>
|
||||||
|
<Switch
|
||||||
|
checked={field.value}
|
||||||
|
onCheckedChange={field.onChange}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="accesedProjects"
|
name="accesedProjects"
|
||||||
|
|||||||
@@ -60,7 +60,9 @@ export const EditTraefikEnv = ({ children }: Props) => {
|
|||||||
}, [form, form.reset, data]);
|
}, [form, form.reset, data]);
|
||||||
|
|
||||||
const onSubmit = async (data: Schema) => {
|
const onSubmit = async (data: Schema) => {
|
||||||
await mutateAsync(data.env)
|
await mutateAsync({
|
||||||
|
env: data.env,
|
||||||
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
toast.success("Traefik Env Updated");
|
toast.success("Traefik Env Updated");
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { cn } from "@/lib/utils";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
// https://worldvectorlogo.com/downloaded/redis Ref
|
// https://worldvectorlogo.com/downloaded/redis Ref
|
||||||
@@ -155,3 +156,118 @@ export const RedisIcon = ({ className }: Props) => {
|
|||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const GitlabIcon = ({ className }: Props) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
aria-label="gitlab"
|
||||||
|
height="14"
|
||||||
|
viewBox="0 0 24 22"
|
||||||
|
width="14"
|
||||||
|
className={cn("fill-white text-white", className)}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M1.279 8.29L.044 12.294c-.117.367 0 .78.325 1.014l11.323 8.23-.009-.012-.03-.039L1.279 8.29zM22.992 13.308a.905.905 0 00.325-1.014L22.085 8.29 11.693 21.52l11.299-8.212z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M1.279 8.29l10.374 13.197.03.039.01-.006L22.085 8.29H1.28z"
|
||||||
|
fill="currentColor"
|
||||||
|
opacity="0.4"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M15.982 8.29l-4.299 13.236-.004.011.014-.017L22.085 8.29h-6.103zM7.376 8.29H1.279l10.374 13.197L7.376 8.29z"
|
||||||
|
fill="currentColor"
|
||||||
|
opacity="0.6"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M18.582.308l-2.6 7.982h6.103L19.48.308c-.133-.41-.764-.41-.897 0zM1.279 8.29L3.88.308c.133-.41.764-.41.897 0l2.6 7.982H1.279z"
|
||||||
|
fill="currentColor"
|
||||||
|
opacity="0.4"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GithubIcon = ({ className }: Props) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
aria-label="github"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 14 14"
|
||||||
|
width="18"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M7 .175c-3.872 0-7 3.128-7 7 0 3.084 2.013 5.71 4.79 6.65.35.066.482-.153.482-.328v-1.181c-1.947.415-2.363-.941-2.363-.941-.328-.81-.787-1.028-.787-1.028-.634-.438.044-.416.044-.416.7.044 1.071.722 1.071.722.635 1.072 1.641.766 2.035.59.066-.459.24-.765.437-.94-1.553-.175-3.193-.787-3.193-3.456 0-.766.262-1.378.721-1.881-.065-.175-.306-.897.066-1.86 0 0 .59-.197 1.925.722a6.754 6.754 0 0 1 1.75-.24c.59 0 1.203.087 1.75.24 1.335-.897 1.925-.722 1.925-.722.372.963.131 1.685.066 1.86.46.48.722 1.115.722 1.88 0 2.691-1.641 3.282-3.194 3.457.24.219.481.634.481 1.29v1.926c0 .197.131.415.481.328C11.988 12.884 14 10.259 14 7.175c0-3.872-3.128-7-7-7z"
|
||||||
|
fill="#fff"
|
||||||
|
fillRule="nonzero"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const BitbucketIcon = ({ className }: Props) => {
|
||||||
|
return (
|
||||||
|
<svg height="14" viewBox="-2 -2 65 59" width="14" className={className}>
|
||||||
|
<defs>
|
||||||
|
<linearGradient
|
||||||
|
id="bitbucket-:R7aq37rqjt7rrrmpjtuj7l9qjtsr:"
|
||||||
|
x1="104.953%"
|
||||||
|
x2="46.569%"
|
||||||
|
y1="21.921%"
|
||||||
|
y2="75.234%"
|
||||||
|
>
|
||||||
|
<stop offset="7%" stopColor="currentColor" stopOpacity=".4" />
|
||||||
|
<stop offset="100%" stopColor="currentColor" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<path
|
||||||
|
d="M59.696 18.86h-18.77l-3.15 18.39h-13L9.426 55.47a2.71 2.71 0 001.75.66h40.74a2 2 0 002-1.68l5.78-35.59z"
|
||||||
|
fill="url(#bitbucket-:R7aq37rqjt7rrrmpjtuj7l9qjtsr:)"
|
||||||
|
fillRule="nonzero"
|
||||||
|
transform="translate(-.026 .82)"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M2 .82a2 2 0 00-2 2.32l8.49 51.54a2.7 2.7 0 00.91 1.61 2.71 2.71 0 001.75.66l15.76-18.88H24.7l-3.47-18.39h38.44l2.7-16.53a2 2 0 00-2-2.32L2 .82z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="nonzero"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DockerIcon = ({ className }: Props) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
height="24"
|
||||||
|
viewBox="-.557 117.607 598.543 423.631"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<g fill="#0091e2">
|
||||||
|
<path d="m592.162 277.804c-1.664-1.37-16.642-12.597-48.815-12.597-8.321 0-16.92.822-25.24 2.191-6.102-41.898-41.327-62.162-42.714-63.257l-8.598-4.93-5.547 7.942c-6.934 10.68-12.204 22.729-15.255 35.052-5.824 23.824-2.219 46.279 9.985 65.447-14.7 8.216-38.553 10.133-43.545 10.406h-393.853c-10.262 0-18.583 8.216-18.583 18.348-.554 33.956 5.27 67.912 17.197 99.951 13.59 35.052 33.838 61.067 59.91 76.95 29.4 17.799 77.383 27.931 131.468 27.931 24.408 0 48.815-2.19 72.946-6.572 33.56-6.025 65.734-17.526 95.412-34.23a260.485 260.485 0 0 0 64.902-52.577c31.342-34.778 49.925-73.663 63.515-108.167h5.547c34.116 0 55.195-13.418 66.844-24.92 7.766-7.12 13.59-15.882 17.751-25.74l2.497-7.12z" />
|
||||||
|
<path d="m55.193 306.83h52.698c2.497 0 4.716-1.916 4.716-4.654v-46.553c0-2.465-1.942-4.655-4.716-4.655h-52.698c-2.496 0-4.715 1.916-4.715 4.655v46.553c.277 2.738 2.219 4.655 4.715 4.655zm72.668 0h52.699c2.496 0 4.715-1.916 4.715-4.654v-46.553c0-2.465-1.942-4.655-4.715-4.655h-52.7c-2.496 0-4.715 1.916-4.715 4.655v46.553c.278 2.738 2.22 4.655 4.715 4.655m74.055 0h52.699c2.496 0 4.715-1.917 4.715-4.655v-46.553c0-2.465-1.942-4.655-4.715-4.655h-52.699c-2.496 0-4.715 1.916-4.715 4.655v46.553c0 2.738 1.942 4.655 4.715 4.655zm72.946 0h52.699c2.496 0 4.715-1.917 4.715-4.655v-46.553c0-2.465-1.942-4.655-4.715-4.655h-52.699c-2.496 0-4.715 1.916-4.715 4.655v46.553c0 2.738 2.219 4.655 4.715 4.655zm-147-66.543h52.698c2.496 0 4.715-2.19 4.715-4.655v-46.553c0-2.465-1.942-4.656-4.715-4.656h-52.699c-2.496 0-4.715 1.917-4.715 4.656v46.553c.278 2.464 2.22 4.655 4.715 4.655m74.055 0h52.699c2.496 0 4.715-2.19 4.715-4.655v-46.553c0-2.465-1.942-4.656-4.715-4.656h-52.699c-2.496 0-4.715 1.917-4.715 4.656v46.553c0 2.464 1.942 4.655 4.715 4.655m72.946 0h52.699c2.496 0 4.715-2.19 4.715-4.655v-46.553c0-2.465-2.22-4.656-4.715-4.656h-52.699c-2.496 0-4.715 1.917-4.715 4.656v46.553c0 2.464 2.219 4.655 4.715 4.655m0-66.817h52.699c2.496 0 4.715-1.917 4.715-4.655v-46.553c0-2.465-2.22-4.656-4.715-4.656h-52.699c-2.496 0-4.715 1.917-4.715 4.656v46.553c0 2.464 2.219 4.655 4.715 4.655m73.5 133.36h52.699c2.496 0 4.715-1.917 4.715-4.655v-46.553c0-2.465-1.941-4.655-4.715-4.655h-52.698c-2.497 0-4.716 1.916-4.716 4.655v46.553c.278 2.738 2.22 4.655 4.716 4.655" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GitIcon = ({ className }: Props) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
preserveAspectRatio="xMinYMin meet"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M251.172 116.594L139.4 4.828c-6.433-6.437-16.873-6.437-23.314 0l-23.21 23.21 29.443 29.443c6.842-2.312 14.688-.761 20.142 4.693 5.48 5.489 7.02 13.402 4.652 20.266l28.375 28.376c6.865-2.365 14.786-.835 20.269 4.657 7.663 7.66 7.663 20.075 0 27.74-7.665 7.666-20.08 7.666-27.749 0-5.764-5.77-7.188-14.235-4.27-21.336l-26.462-26.462-.003 69.637a19.82 19.82 0 0 1 5.188 3.71c7.663 7.66 7.663 20.076 0 27.747-7.665 7.662-20.086 7.662-27.74 0-7.663-7.671-7.663-20.086 0-27.746a19.654 19.654 0 0 1 6.421-4.281V94.196a19.378 19.378 0 0 1-6.421-4.281c-5.806-5.798-7.202-14.317-4.227-21.446L81.47 39.442l-76.64 76.635c-6.44 6.443-6.44 16.884 0 23.322l111.774 111.768c6.435 6.438 16.873 6.438 23.316 0l111.251-111.249c6.438-6.44 6.438-16.887 0-23.324"
|
||||||
|
fill="#DE4C36"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ export const SettingsLayout = ({ children }: Props) => {
|
|||||||
icon: KeyRound,
|
icon: KeyRound,
|
||||||
href: "/dashboard/settings/ssh-keys",
|
href: "/dashboard/settings/ssh-keys",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Git ",
|
||||||
|
label: "",
|
||||||
|
icon: GitBranch,
|
||||||
|
href: "/dashboard/settings/git-providers",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "Users",
|
title: "Users",
|
||||||
label: "",
|
label: "",
|
||||||
@@ -89,6 +95,16 @@ export const SettingsLayout = ({ children }: Props) => {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
...(user?.canAccessToGitProviders
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
title: "Git",
|
||||||
|
label: "",
|
||||||
|
icon: GitBranch,
|
||||||
|
href: "/dashboard/settings/git-providers",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -102,6 +118,7 @@ import {
|
|||||||
Activity,
|
Activity,
|
||||||
Bell,
|
Bell,
|
||||||
Database,
|
Database,
|
||||||
|
GitBranch,
|
||||||
KeyRound,
|
KeyRound,
|
||||||
type LucideIcon,
|
type LucideIcon,
|
||||||
Route,
|
Route,
|
||||||
|
|||||||
142
apps/dokploy/drizzle/0033_white_hawkeye.sql
Normal file
142
apps/dokploy/drizzle/0033_white_hawkeye.sql
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "public"."gitProviderType" AS ENUM('github', 'gitlab', 'bitbucket');
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TYPE "sourceType" ADD VALUE 'gitlab';--> statement-breakpoint
|
||||||
|
ALTER TYPE "sourceType" ADD VALUE 'bitbucket';--> statement-breakpoint
|
||||||
|
ALTER TYPE "sourceTypeCompose" ADD VALUE 'gitlab';--> statement-breakpoint
|
||||||
|
ALTER TYPE "sourceTypeCompose" ADD VALUE 'bitbucket';--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "git_provider" (
|
||||||
|
"gitProviderId" text PRIMARY KEY NOT NULL,
|
||||||
|
"name" text NOT NULL,
|
||||||
|
"providerType" "gitProviderType" DEFAULT 'github' NOT NULL,
|
||||||
|
"createdAt" text NOT NULL,
|
||||||
|
"authId" text NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "bitbucket" (
|
||||||
|
"bitbucketId" text PRIMARY KEY NOT NULL,
|
||||||
|
"bitbucketUsername" text,
|
||||||
|
"appPassword" text,
|
||||||
|
"bitbucketWorkspaceName" text,
|
||||||
|
"gitProviderId" text NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "github" (
|
||||||
|
"githubId" text PRIMARY KEY NOT NULL,
|
||||||
|
"githubAppName" text,
|
||||||
|
"githubAppId" integer,
|
||||||
|
"githubClientId" text,
|
||||||
|
"githubClientSecret" text,
|
||||||
|
"githubInstallationId" text,
|
||||||
|
"githubPrivateKey" text,
|
||||||
|
"githubWebhookSecret" text,
|
||||||
|
"gitProviderId" text NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "gitlab" (
|
||||||
|
"gitlabId" text PRIMARY KEY NOT NULL,
|
||||||
|
"application_id" text,
|
||||||
|
"redirect_uri" text,
|
||||||
|
"secret" text,
|
||||||
|
"access_token" text,
|
||||||
|
"refresh_token" text,
|
||||||
|
"group_name" text,
|
||||||
|
"expires_at" integer,
|
||||||
|
"gitProviderId" text NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "gitlabProjectId" integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "gitlabRepository" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "gitlabOwner" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "gitlabBranch" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "gitlabBuildPath" text DEFAULT '/';--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "gitlabPathNamespace" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "bitbucketRepository" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "bitbucketOwner" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "bitbucketBranch" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "bitbucketBuildPath" text DEFAULT '/';--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "githubId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "gitlabId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "application" ADD COLUMN "bitbucketId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "user" ADD COLUMN "canAccessToGitProviders" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "gitlabProjectId" integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "gitlabRepository" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "gitlabOwner" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "gitlabBranch" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "gitlabPathNamespace" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "bitbucketRepository" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "bitbucketOwner" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "bitbucketBranch" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "githubId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "gitlabId" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "compose" ADD COLUMN "bitbucketId" text;--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "git_provider" ADD CONSTRAINT "git_provider_authId_auth_id_fk" FOREIGN KEY ("authId") REFERENCES "public"."auth"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "bitbucket" ADD CONSTRAINT "bitbucket_gitProviderId_git_provider_gitProviderId_fk" FOREIGN KEY ("gitProviderId") REFERENCES "public"."git_provider"("gitProviderId") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "github" ADD CONSTRAINT "github_gitProviderId_git_provider_gitProviderId_fk" FOREIGN KEY ("gitProviderId") REFERENCES "public"."git_provider"("gitProviderId") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "gitlab" ADD CONSTRAINT "gitlab_gitProviderId_git_provider_gitProviderId_fk" FOREIGN KEY ("gitProviderId") REFERENCES "public"."git_provider"("gitProviderId") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "application" ADD CONSTRAINT "application_githubId_github_githubId_fk" FOREIGN KEY ("githubId") REFERENCES "public"."github"("githubId") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "application" ADD CONSTRAINT "application_gitlabId_gitlab_gitlabId_fk" FOREIGN KEY ("gitlabId") REFERENCES "public"."gitlab"("gitlabId") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "application" ADD CONSTRAINT "application_bitbucketId_bitbucket_bitbucketId_fk" FOREIGN KEY ("bitbucketId") REFERENCES "public"."bitbucket"("bitbucketId") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "compose" ADD CONSTRAINT "compose_githubId_github_githubId_fk" FOREIGN KEY ("githubId") REFERENCES "public"."github"("githubId") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "compose" ADD CONSTRAINT "compose_gitlabId_gitlab_gitlabId_fk" FOREIGN KEY ("gitlabId") REFERENCES "public"."gitlab"("gitlabId") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "compose" ADD CONSTRAINT "compose_bitbucketId_bitbucket_bitbucketId_fk" FOREIGN KEY ("bitbucketId") REFERENCES "public"."bitbucket"("bitbucketId") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "admin" DROP COLUMN IF EXISTS "githubAppId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "admin" DROP COLUMN IF EXISTS "githubAppName";--> statement-breakpoint
|
||||||
|
ALTER TABLE "admin" DROP COLUMN IF EXISTS "githubClientId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "admin" DROP COLUMN IF EXISTS "githubClientSecret";--> statement-breakpoint
|
||||||
|
ALTER TABLE "admin" DROP COLUMN IF EXISTS "githubInstallationId";--> statement-breakpoint
|
||||||
|
ALTER TABLE "admin" DROP COLUMN IF EXISTS "githubPrivateKey";--> statement-breakpoint
|
||||||
|
ALTER TABLE "admin" DROP COLUMN IF EXISTS "githubWebhookSecret";
|
||||||
3539
apps/dokploy/drizzle/meta/0033_snapshot.json
Normal file
3539
apps/dokploy/drizzle/meta/0033_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -232,6 +232,13 @@
|
|||||||
"when": 1723705257806,
|
"when": 1723705257806,
|
||||||
"tag": "0032_flashy_shadow_king",
|
"tag": "0032_flashy_shadow_king",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 33,
|
||||||
|
"version": "6",
|
||||||
|
"when": 1725250322137,
|
||||||
|
"tag": "0033_white_hawkeye",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -66,6 +66,18 @@ export default async function handler(
|
|||||||
res.status(301).json({ message: "Branch Not Match" });
|
res.status(301).json({ message: "Branch Not Match" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (sourceType === "gitlab") {
|
||||||
|
const branchName = extractBranchName(req.headers, req.body);
|
||||||
|
if (!branchName || branchName !== application.gitlabBranch) {
|
||||||
|
res.status(301).json({ message: "Branch Not Match" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (sourceType === "bitbucket") {
|
||||||
|
const branchName = extractBranchName(req.headers, req.body);
|
||||||
|
if (!branchName || branchName !== application.bitbucketBranch) {
|
||||||
|
res.status(301).json({ message: "Branch Not Match" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { findAdmin } from "@/server/api/services/admin";
|
import { findAdmin } from "@/server/api/services/admin";
|
||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import { applications, compose } from "@/server/db/schema";
|
import { applications, compose, github } from "@/server/db/schema";
|
||||||
import type { DeploymentJob } from "@/server/queues/deployments-queue";
|
import type { DeploymentJob } from "@/server/queues/deployments-queue";
|
||||||
import { myQueue } from "@/server/queues/queueSetup";
|
import { myQueue } from "@/server/queues/queueSetup";
|
||||||
import { Webhooks } from "@octokit/webhooks";
|
import { Webhooks } from "@octokit/webhooks";
|
||||||
@@ -19,17 +19,30 @@ export default async function handler(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!admin.githubWebhookSecret) {
|
const signature = req.headers["x-hub-signature-256"];
|
||||||
res.status(200).json({ message: "Github Webhook Secret not set" });
|
const githubBody = req.body;
|
||||||
|
|
||||||
|
if (!githubBody?.installation.id) {
|
||||||
|
res.status(400).json({ message: "Github Installation not found" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const webhooks = new Webhooks({
|
const githubResult = await db.query.github.findFirst({
|
||||||
secret: admin.githubWebhookSecret,
|
where: eq(github.githubInstallationId, githubBody.installation.id),
|
||||||
});
|
});
|
||||||
|
|
||||||
const signature = req.headers["x-hub-signature-256"];
|
if (!githubResult) {
|
||||||
const github = req.body;
|
res.status(400).json({ message: "Github Installation not found" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!githubResult.githubWebhookSecret) {
|
||||||
|
res.status(400).json({ message: "Github Webhook Secret not set" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const webhooks = new Webhooks({
|
||||||
|
secret: githubResult.githubWebhookSecret,
|
||||||
|
});
|
||||||
|
|
||||||
const verified = await webhooks.verify(
|
const verified = await webhooks.verify(
|
||||||
JSON.stringify(github),
|
JSON.stringify(github),
|
||||||
@@ -52,8 +65,8 @@ export default async function handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const branchName = github?.ref?.replace("refs/heads/", "");
|
const branchName = githubBody?.ref?.replace("refs/heads/", "");
|
||||||
const repository = github?.repository?.name;
|
const repository = githubBody?.repository?.name;
|
||||||
const deploymentTitle = extractCommitMessage(req.headers, req.body);
|
const deploymentTitle = extractCommitMessage(req.headers, req.body);
|
||||||
const deploymentHash = extractHash(req.headers, req.body);
|
const deploymentHash = extractHash(req.headers, req.body);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import { createGithub } from "@/server/api/services/github";
|
||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import { admins } from "@/server/db/schema";
|
import { github } from "@/server/db/schema";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
import { Octokit } from "octokit";
|
import { Octokit } from "octokit";
|
||||||
@@ -17,10 +18,12 @@ export default async function handler(
|
|||||||
) {
|
) {
|
||||||
const { code, state, installation_id, setup_action }: Query =
|
const { code, state, installation_id, setup_action }: Query =
|
||||||
req.query as Query;
|
req.query as Query;
|
||||||
|
|
||||||
if (!code) {
|
if (!code) {
|
||||||
return res.status(400).json({ error: "Missing code parameter" });
|
return res.status(400).json({ error: "Missing code parameter" });
|
||||||
}
|
}
|
||||||
const [action, authId] = state?.split(":");
|
const [action, value] = state?.split(":");
|
||||||
|
// Value could be the authId or the githubProviderId
|
||||||
|
|
||||||
if (action === "gh_init") {
|
if (action === "gh_init") {
|
||||||
const octokit = new Octokit({});
|
const octokit = new Octokit({});
|
||||||
@@ -31,27 +34,25 @@ export default async function handler(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = await db
|
await createGithub({
|
||||||
.update(admins)
|
name: data.name,
|
||||||
.set({
|
githubAppName: data.html_url,
|
||||||
githubAppId: data.id,
|
githubAppId: data.id,
|
||||||
githubAppName: data.html_url,
|
githubClientId: data.client_id,
|
||||||
githubClientId: data.client_id,
|
githubClientSecret: data.client_secret,
|
||||||
githubClientSecret: data.client_secret,
|
githubWebhookSecret: data.webhook_secret,
|
||||||
githubWebhookSecret: data.webhook_secret,
|
githubPrivateKey: data.pem,
|
||||||
githubPrivateKey: data.pem,
|
authId: value as string,
|
||||||
})
|
});
|
||||||
.where(eq(admins.authId, authId as string))
|
|
||||||
.returning();
|
|
||||||
} else if (action === "gh_setup") {
|
} else if (action === "gh_setup") {
|
||||||
await db
|
await db
|
||||||
.update(admins)
|
.update(github)
|
||||||
.set({
|
.set({
|
||||||
githubInstallationId: installation_id,
|
githubInstallationId: installation_id,
|
||||||
})
|
})
|
||||||
.where(eq(admins.authId, authId as string))
|
.where(eq(github.githubId, value as string))
|
||||||
.returning();
|
.returning();
|
||||||
}
|
}
|
||||||
|
|
||||||
res.redirect(307, "/dashboard/settings/server");
|
res.redirect(307, "/dashboard/settings/git-providers");
|
||||||
}
|
}
|
||||||
@@ -8,9 +8,9 @@ export default async function handler(
|
|||||||
const xGitHubEvent = req.headers["x-github-event"];
|
const xGitHubEvent = req.headers["x-github-event"];
|
||||||
|
|
||||||
if (xGitHubEvent === "ping") {
|
if (xGitHubEvent === "ping") {
|
||||||
res.redirect(307, "/dashboard/settings");
|
res.redirect(307, "/dashboard/settings/git-providers");
|
||||||
} else {
|
} else {
|
||||||
res.redirect(307, "/dashboard/settings");
|
res.redirect(307, "/dashboard/settings/git-providers");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.setHeader("Allow", ["POST"]);
|
res.setHeader("Allow", ["POST"]);
|
||||||
44
apps/dokploy/pages/api/providers/gitlab/callback.ts
Normal file
44
apps/dokploy/pages/api/providers/gitlab/callback.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { findGitlabById, updateGitlab } from "@/server/api/services/gitlab";
|
||||||
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
export default async function handler(
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse,
|
||||||
|
) {
|
||||||
|
const { code, gitlabId } = req.query;
|
||||||
|
|
||||||
|
if (!code || Array.isArray(code)) {
|
||||||
|
return res.status(400).json({ error: "Missing or invalid code" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const gitlab = await findGitlabById(gitlabId as string);
|
||||||
|
|
||||||
|
const response = await fetch("https://gitlab.com/oauth/token", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
},
|
||||||
|
body: new URLSearchParams({
|
||||||
|
client_id: gitlab.applicationId as string,
|
||||||
|
client_secret: gitlab.secret as string,
|
||||||
|
code: code as string,
|
||||||
|
grant_type: "authorization_code",
|
||||||
|
redirect_uri: `${gitlab.redirectUri}?gitlabId=${gitlabId}`,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (!result.access_token || !result.refresh_token) {
|
||||||
|
return res.status(400).json({ error: "Missing or invalid code" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const expiresAt = Math.floor(Date.now() / 1000) + result.expires_in;
|
||||||
|
await updateGitlab(gitlab.gitlabId, {
|
||||||
|
accessToken: result.access_token,
|
||||||
|
refreshToken: result.refresh_token,
|
||||||
|
expiresAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.redirect(307, "/dashboard/settings/git-providers");
|
||||||
|
}
|
||||||
81
apps/dokploy/pages/dashboard/settings/git-providers.tsx
Normal file
81
apps/dokploy/pages/dashboard/settings/git-providers.tsx
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { ShowGitProviders } from "@/components/dashboard/settings/git/show-git-providers";
|
||||||
|
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||||
|
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
||||||
|
import { appRouter } from "@/server/api/root";
|
||||||
|
import { validateRequest } from "@/server/auth/auth";
|
||||||
|
import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||||
|
import type { GetServerSidePropsContext } from "next";
|
||||||
|
import React, { type ReactElement } from "react";
|
||||||
|
import superjson from "superjson";
|
||||||
|
|
||||||
|
const Page = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-4 w-full">
|
||||||
|
<ShowGitProviders />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
|
|
||||||
|
Page.getLayout = (page: ReactElement) => {
|
||||||
|
return (
|
||||||
|
<DashboardLayout tab={"settings"}>
|
||||||
|
<SettingsLayout>{page}</SettingsLayout>
|
||||||
|
</DashboardLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export async function getServerSideProps(
|
||||||
|
ctx: GetServerSidePropsContext<{ serviceId: string }>,
|
||||||
|
) {
|
||||||
|
const { user, session } = await validateRequest(ctx.req, ctx.res);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
redirect: {
|
||||||
|
permanent: true,
|
||||||
|
destination: "/",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const { req, res } = ctx;
|
||||||
|
const helpers = createServerSideHelpers({
|
||||||
|
router: appRouter,
|
||||||
|
ctx: {
|
||||||
|
req: req as any,
|
||||||
|
res: res as any,
|
||||||
|
db: null as any,
|
||||||
|
session: session,
|
||||||
|
user: user,
|
||||||
|
},
|
||||||
|
transformer: superjson,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await helpers.project.all.prefetch();
|
||||||
|
const auth = await helpers.auth.get.fetch();
|
||||||
|
|
||||||
|
if (auth.rol === "user") {
|
||||||
|
const user = await helpers.user.byAuthId.fetch({
|
||||||
|
authId: auth.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user.canAccessToGitProviders) {
|
||||||
|
return {
|
||||||
|
redirect: {
|
||||||
|
permanent: true,
|
||||||
|
destination: "/",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
trpcState: helpers.dehydrate(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
props: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { GithubSetup } from "@/components/dashboard/settings/github/github-setup";
|
|
||||||
import { WebDomain } from "@/components/dashboard/settings/web-domain";
|
import { WebDomain } from "@/components/dashboard/settings/web-domain";
|
||||||
import { WebServer } from "@/components/dashboard/settings/web-server";
|
import { WebServer } from "@/components/dashboard/settings/web-server";
|
||||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||||
@@ -11,7 +10,6 @@ const Page = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4 w-full">
|
<div className="flex flex-col gap-4 w-full">
|
||||||
<WebDomain />
|
<WebDomain />
|
||||||
<GithubSetup />
|
|
||||||
<WebServer />
|
<WebServer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { createTRPCRouter } from "../api/trpc";
|
|||||||
import { adminRouter } from "./routers/admin";
|
import { adminRouter } from "./routers/admin";
|
||||||
import { applicationRouter } from "./routers/application";
|
import { applicationRouter } from "./routers/application";
|
||||||
import { backupRouter } from "./routers/backup";
|
import { backupRouter } from "./routers/backup";
|
||||||
|
import { bitbucketRouter } from "./routers/bitbucket";
|
||||||
import { certificateRouter } from "./routers/certificate";
|
import { certificateRouter } from "./routers/certificate";
|
||||||
import { clusterRouter } from "./routers/cluster";
|
import { clusterRouter } from "./routers/cluster";
|
||||||
import { composeRouter } from "./routers/compose";
|
import { composeRouter } from "./routers/compose";
|
||||||
@@ -10,6 +11,9 @@ import { deploymentRouter } from "./routers/deployment";
|
|||||||
import { destinationRouter } from "./routers/destination";
|
import { destinationRouter } from "./routers/destination";
|
||||||
import { dockerRouter } from "./routers/docker";
|
import { dockerRouter } from "./routers/docker";
|
||||||
import { domainRouter } from "./routers/domain";
|
import { domainRouter } from "./routers/domain";
|
||||||
|
import { gitProviderRouter } from "./routers/git-provider";
|
||||||
|
import { githubRouter } from "./routers/github";
|
||||||
|
import { gitlabRouter } from "./routers/gitlab";
|
||||||
import { mariadbRouter } from "./routers/mariadb";
|
import { mariadbRouter } from "./routers/mariadb";
|
||||||
import { mongoRouter } from "./routers/mongo";
|
import { mongoRouter } from "./routers/mongo";
|
||||||
import { mountRouter } from "./routers/mount";
|
import { mountRouter } from "./routers/mount";
|
||||||
@@ -58,6 +62,10 @@ export const appRouter = createTRPCRouter({
|
|||||||
cluster: clusterRouter,
|
cluster: clusterRouter,
|
||||||
notification: notificationRouter,
|
notification: notificationRouter,
|
||||||
sshKey: sshRouter,
|
sshKey: sshRouter,
|
||||||
|
gitProvider: gitProviderRouter,
|
||||||
|
bitbucket: bitbucketRouter,
|
||||||
|
gitlab: gitlabRouter,
|
||||||
|
github: githubRouter,
|
||||||
});
|
});
|
||||||
|
|
||||||
// export type definition of API
|
// export type definition of API
|
||||||
|
|||||||
@@ -3,28 +3,18 @@ import {
|
|||||||
apiAssignPermissions,
|
apiAssignPermissions,
|
||||||
apiCreateUserInvitation,
|
apiCreateUserInvitation,
|
||||||
apiFindOneToken,
|
apiFindOneToken,
|
||||||
apiGetBranches,
|
|
||||||
apiRemoveUser,
|
apiRemoveUser,
|
||||||
users,
|
users,
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
import { haveGithubRequirements } from "@/server/utils/providers/github";
|
|
||||||
import { createAppAuth } from "@octokit/auth-app";
|
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { Octokit } from "octokit";
|
|
||||||
import {
|
import {
|
||||||
createInvitation,
|
createInvitation,
|
||||||
findAdmin,
|
findAdmin,
|
||||||
getUserByToken,
|
getUserByToken,
|
||||||
removeUserByAuthId,
|
removeUserByAuthId,
|
||||||
updateAdmin,
|
|
||||||
} from "../services/admin";
|
} from "../services/admin";
|
||||||
import {
|
import { adminProcedure, createTRPCRouter, publicProcedure } from "../trpc";
|
||||||
adminProcedure,
|
|
||||||
createTRPCRouter,
|
|
||||||
protectedProcedure,
|
|
||||||
publicProcedure,
|
|
||||||
} from "../trpc";
|
|
||||||
|
|
||||||
export const adminRouter = createTRPCRouter({
|
export const adminRouter = createTRPCRouter({
|
||||||
one: adminProcedure.query(async () => {
|
one: adminProcedure.query(async () => {
|
||||||
@@ -83,91 +73,4 @@ export const adminRouter = createTRPCRouter({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
cleanGithubApp: adminProcedure.mutation(async ({ ctx }) => {
|
|
||||||
try {
|
|
||||||
return await updateAdmin(ctx.user.authId, {
|
|
||||||
githubAppName: "",
|
|
||||||
githubClientId: "",
|
|
||||||
githubClientSecret: "",
|
|
||||||
githubInstallationId: "",
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "BAD_REQUEST",
|
|
||||||
message: "Error to delete this github app",
|
|
||||||
cause: error,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
getRepositories: protectedProcedure.query(async () => {
|
|
||||||
const admin = await findAdmin();
|
|
||||||
|
|
||||||
const completeRequirements = haveGithubRequirements(admin);
|
|
||||||
|
|
||||||
if (!completeRequirements) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "BAD_REQUEST",
|
|
||||||
message: "Admin need to setup correctly github account",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const octokit = new Octokit({
|
|
||||||
authStrategy: createAppAuth,
|
|
||||||
auth: {
|
|
||||||
appId: admin.githubAppId,
|
|
||||||
privateKey: admin.githubPrivateKey,
|
|
||||||
installationId: admin.githubInstallationId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const repositories = (await octokit.paginate(
|
|
||||||
octokit.rest.apps.listReposAccessibleToInstallation,
|
|
||||||
)) as unknown as Awaited<
|
|
||||||
ReturnType<typeof octokit.rest.apps.listReposAccessibleToInstallation>
|
|
||||||
>["data"]["repositories"];
|
|
||||||
|
|
||||||
return repositories;
|
|
||||||
}),
|
|
||||||
getBranches: protectedProcedure
|
|
||||||
.input(apiGetBranches)
|
|
||||||
.query(async ({ input }) => {
|
|
||||||
const admin = await findAdmin();
|
|
||||||
|
|
||||||
const completeRequirements = haveGithubRequirements(admin);
|
|
||||||
|
|
||||||
if (!completeRequirements) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "BAD_REQUEST",
|
|
||||||
message: "Admin need to setup correctly github account",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const octokit = new Octokit({
|
|
||||||
authStrategy: createAppAuth,
|
|
||||||
auth: {
|
|
||||||
appId: admin.githubAppId,
|
|
||||||
privateKey: admin.githubPrivateKey,
|
|
||||||
installationId: admin.githubInstallationId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const branches = (await octokit.paginate(
|
|
||||||
octokit.rest.repos.listBranches,
|
|
||||||
{
|
|
||||||
owner: input.owner,
|
|
||||||
repo: input.repo,
|
|
||||||
},
|
|
||||||
)) as unknown as Awaited<
|
|
||||||
ReturnType<typeof octokit.rest.repos.listBranches>
|
|
||||||
>["data"];
|
|
||||||
|
|
||||||
return branches;
|
|
||||||
}),
|
|
||||||
haveGithubConfigured: protectedProcedure.query(async () => {
|
|
||||||
const adminResponse = await findAdmin();
|
|
||||||
|
|
||||||
return haveGithubRequirements(adminResponse);
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ import {
|
|||||||
apiFindMonitoringStats,
|
apiFindMonitoringStats,
|
||||||
apiFindOneApplication,
|
apiFindOneApplication,
|
||||||
apiReloadApplication,
|
apiReloadApplication,
|
||||||
|
apiSaveBitbucketProvider,
|
||||||
apiSaveBuildType,
|
apiSaveBuildType,
|
||||||
apiSaveDockerProvider,
|
apiSaveDockerProvider,
|
||||||
apiSaveEnvironmentVariables,
|
apiSaveEnvironmentVariables,
|
||||||
apiSaveGitProvider,
|
apiSaveGitProvider,
|
||||||
apiSaveGithubProvider,
|
apiSaveGithubProvider,
|
||||||
|
apiSaveGitlabProvider,
|
||||||
apiUpdateApplication,
|
apiUpdateApplication,
|
||||||
applications,
|
applications,
|
||||||
} from "@/server/db/schema/application";
|
} from "@/server/db/schema/application";
|
||||||
@@ -207,6 +209,39 @@ export const applicationRouter = createTRPCRouter({
|
|||||||
owner: input.owner,
|
owner: input.owner,
|
||||||
buildPath: input.buildPath,
|
buildPath: input.buildPath,
|
||||||
applicationStatus: "idle",
|
applicationStatus: "idle",
|
||||||
|
githubId: input.githubId,
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
saveGitlabProvider: protectedProcedure
|
||||||
|
.input(apiSaveGitlabProvider)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
await updateApplication(input.applicationId, {
|
||||||
|
gitlabRepository: input.gitlabRepository,
|
||||||
|
gitlabOwner: input.gitlabOwner,
|
||||||
|
gitlabBranch: input.gitlabBranch,
|
||||||
|
gitlabBuildPath: input.gitlabBuildPath,
|
||||||
|
sourceType: "gitlab",
|
||||||
|
applicationStatus: "idle",
|
||||||
|
gitlabId: input.gitlabId,
|
||||||
|
gitlabProjectId: input.gitlabProjectId,
|
||||||
|
gitlabPathNamespace: input.gitlabPathNamespace,
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
saveBitbucketProvider: protectedProcedure
|
||||||
|
.input(apiSaveBitbucketProvider)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
await updateApplication(input.applicationId, {
|
||||||
|
bitbucketRepository: input.bitbucketRepository,
|
||||||
|
bitbucketOwner: input.bitbucketOwner,
|
||||||
|
bitbucketBranch: input.bitbucketBranch,
|
||||||
|
bitbucketBuildPath: input.bitbucketBuildPath,
|
||||||
|
sourceType: "bitbucket",
|
||||||
|
applicationStatus: "idle",
|
||||||
|
bitbucketId: input.bitbucketId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as bcrypt from "bcrypt";
|
||||||
import { db } from "../../db";
|
import { db } from "../../db";
|
||||||
|
import { getUserByToken } from "../services/admin";
|
||||||
import {
|
import {
|
||||||
createAdmin,
|
createAdmin,
|
||||||
createUser,
|
createUser,
|
||||||
@@ -61,6 +62,13 @@ export const authRouter = createTRPCRouter({
|
|||||||
.input(apiCreateUser)
|
.input(apiCreateUser)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
try {
|
try {
|
||||||
|
const token = await getUserByToken(input.token);
|
||||||
|
if (token.isExpired) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Invalid token",
|
||||||
|
});
|
||||||
|
}
|
||||||
const newUser = await createUser(input);
|
const newUser = await createUser(input);
|
||||||
const session = await lucia.createSession(newUser?.authId || "", {});
|
const session = await lucia.createSession(newUser?.authId || "", {});
|
||||||
ctx.res.appendHeader(
|
ctx.res.appendHeader(
|
||||||
|
|||||||
82
apps/dokploy/server/api/routers/bitbucket.ts
Normal file
82
apps/dokploy/server/api/routers/bitbucket.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc";
|
||||||
|
import { db } from "@/server/db";
|
||||||
|
import {
|
||||||
|
apiBitbucketTestConnection,
|
||||||
|
apiCreateBitbucket,
|
||||||
|
apiFindBitbucketBranches,
|
||||||
|
apiFindOneBitbucket,
|
||||||
|
apiUpdateBitbucket,
|
||||||
|
} from "@/server/db/schema";
|
||||||
|
import {
|
||||||
|
getBitbucketBranches,
|
||||||
|
getBitbucketRepositories,
|
||||||
|
testBitbucketConnection,
|
||||||
|
} from "@/server/utils/providers/bitbucket";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import {
|
||||||
|
createBitbucket,
|
||||||
|
findBitbucketById,
|
||||||
|
updateBitbucket,
|
||||||
|
} from "../services/bitbucket";
|
||||||
|
|
||||||
|
export const bitbucketRouter = createTRPCRouter({
|
||||||
|
create: protectedProcedure
|
||||||
|
.input(apiCreateBitbucket)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
try {
|
||||||
|
return await createBitbucket(input);
|
||||||
|
} catch (error) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Error to create this bitbucket provider",
|
||||||
|
cause: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
one: protectedProcedure
|
||||||
|
.input(apiFindOneBitbucket)
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
return await findBitbucketById(input.bitbucketId);
|
||||||
|
}),
|
||||||
|
bitbucketProviders: protectedProcedure.query(async () => {
|
||||||
|
const result = await db.query.bitbucket.findMany({
|
||||||
|
with: {
|
||||||
|
gitProvider: true,
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
bitbucketId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}),
|
||||||
|
|
||||||
|
getBitbucketRepositories: protectedProcedure
|
||||||
|
.input(apiFindOneBitbucket)
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
return await getBitbucketRepositories(input.bitbucketId);
|
||||||
|
}),
|
||||||
|
getBitbucketBranches: protectedProcedure
|
||||||
|
.input(apiFindBitbucketBranches)
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
return await getBitbucketBranches(input);
|
||||||
|
}),
|
||||||
|
testConnection: protectedProcedure
|
||||||
|
.input(apiBitbucketTestConnection)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
try {
|
||||||
|
const result = await testBitbucketConnection(input);
|
||||||
|
|
||||||
|
return `Found ${result} repositories`;
|
||||||
|
} catch (error) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: error instanceof Error ? error?.message : `Error: ${error}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
update: protectedProcedure
|
||||||
|
.input(apiUpdateBitbucket)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
return await updateBitbucket(input.bitbucketId, input);
|
||||||
|
}),
|
||||||
|
});
|
||||||
31
apps/dokploy/server/api/routers/git-provider.ts
Normal file
31
apps/dokploy/server/api/routers/git-provider.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc";
|
||||||
|
import { db } from "@/server/db";
|
||||||
|
import { apiRemoveGitProvider, gitProvider } from "@/server/db/schema";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { asc, desc } from "drizzle-orm";
|
||||||
|
import { removeGitProvider } from "../services/git-provider";
|
||||||
|
|
||||||
|
export const gitProviderRouter = createTRPCRouter({
|
||||||
|
getAll: protectedProcedure.query(async () => {
|
||||||
|
return await db.query.gitProvider.findMany({
|
||||||
|
with: {
|
||||||
|
gitlab: true,
|
||||||
|
bitbucket: true,
|
||||||
|
github: true,
|
||||||
|
},
|
||||||
|
orderBy: desc(gitProvider.createdAt),
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
remove: protectedProcedure
|
||||||
|
.input(apiRemoveGitProvider)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
try {
|
||||||
|
return await removeGitProvider(input.gitProviderId);
|
||||||
|
} catch (error) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Error to delete this git provider",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
});
|
||||||
71
apps/dokploy/server/api/routers/github.ts
Normal file
71
apps/dokploy/server/api/routers/github.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc";
|
||||||
|
import { db } from "@/server/db";
|
||||||
|
import {
|
||||||
|
apiFindGithubBranches,
|
||||||
|
apiFindOneGithub,
|
||||||
|
apiUpdateGithub,
|
||||||
|
} from "@/server/db/schema";
|
||||||
|
import {
|
||||||
|
getGithubBranches,
|
||||||
|
getGithubRepositories,
|
||||||
|
} from "@/server/utils/providers/github";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { updateGitProvider } from "../services/git-provider";
|
||||||
|
import { findGithubById, haveGithubRequirements } from "../services/github";
|
||||||
|
|
||||||
|
export const githubRouter = createTRPCRouter({
|
||||||
|
one: protectedProcedure.input(apiFindOneGithub).query(async ({ input }) => {
|
||||||
|
return await findGithubById(input.githubId);
|
||||||
|
}),
|
||||||
|
getGithubRepositories: protectedProcedure
|
||||||
|
.input(apiFindOneGithub)
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
return await getGithubRepositories(input.githubId);
|
||||||
|
}),
|
||||||
|
getGithubBranches: protectedProcedure
|
||||||
|
.input(apiFindGithubBranches)
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
return await getGithubBranches(input);
|
||||||
|
}),
|
||||||
|
githubProviders: protectedProcedure.query(async () => {
|
||||||
|
const result = await db.query.github.findMany({
|
||||||
|
with: {
|
||||||
|
gitProvider: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const filtered = result
|
||||||
|
.filter((provider) => haveGithubRequirements(provider))
|
||||||
|
.map((provider) => {
|
||||||
|
return {
|
||||||
|
githubId: provider.githubId,
|
||||||
|
gitProvider: {
|
||||||
|
...provider.gitProvider,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}),
|
||||||
|
|
||||||
|
testConnection: protectedProcedure
|
||||||
|
.input(apiFindOneGithub)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
try {
|
||||||
|
const result = await getGithubRepositories(input.githubId);
|
||||||
|
return `Found ${result.length} repositories`;
|
||||||
|
} catch (err) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: err instanceof Error ? err?.message : `Error: ${err}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
update: protectedProcedure
|
||||||
|
.input(apiUpdateGithub)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
await updateGitProvider(input.gitProviderId, {
|
||||||
|
name: input.name,
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
});
|
||||||
93
apps/dokploy/server/api/routers/gitlab.ts
Normal file
93
apps/dokploy/server/api/routers/gitlab.ts
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc";
|
||||||
|
import {
|
||||||
|
apiCreateGitlab,
|
||||||
|
apiFindGitlabBranches,
|
||||||
|
apiFindOneGitlab,
|
||||||
|
apiGitlabTestConnection,
|
||||||
|
apiUpdateGitlab,
|
||||||
|
} from "@/server/db/schema";
|
||||||
|
|
||||||
|
import { db } from "@/server/db";
|
||||||
|
import {
|
||||||
|
getGitlabBranches,
|
||||||
|
getGitlabRepositories,
|
||||||
|
haveGitlabRequirements,
|
||||||
|
testGitlabConnection,
|
||||||
|
} from "@/server/utils/providers/gitlab";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { updateGitProvider } from "../services/git-provider";
|
||||||
|
import { createGitlab, findGitlabById, updateGitlab } from "../services/gitlab";
|
||||||
|
|
||||||
|
export const gitlabRouter = createTRPCRouter({
|
||||||
|
create: protectedProcedure
|
||||||
|
.input(apiCreateGitlab)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
try {
|
||||||
|
return await createGitlab(input);
|
||||||
|
} catch (error) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Error to create this gitlab provider",
|
||||||
|
cause: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
one: protectedProcedure.input(apiFindOneGitlab).query(async ({ input }) => {
|
||||||
|
return await findGitlabById(input.gitlabId);
|
||||||
|
}),
|
||||||
|
gitlabProviders: protectedProcedure.query(async () => {
|
||||||
|
const result = await db.query.gitlab.findMany({
|
||||||
|
with: {
|
||||||
|
gitProvider: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const filtered = result
|
||||||
|
.filter((provider) => haveGitlabRequirements(provider))
|
||||||
|
.map((provider) => {
|
||||||
|
return {
|
||||||
|
gitlabId: provider.gitlabId,
|
||||||
|
gitProvider: {
|
||||||
|
...provider.gitProvider,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}),
|
||||||
|
getGitlabRepositories: protectedProcedure
|
||||||
|
.input(apiFindOneGitlab)
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
return await getGitlabRepositories(input.gitlabId);
|
||||||
|
}),
|
||||||
|
|
||||||
|
getGitlabBranches: protectedProcedure
|
||||||
|
.input(apiFindGitlabBranches)
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
return await getGitlabBranches(input);
|
||||||
|
}),
|
||||||
|
testConnection: protectedProcedure
|
||||||
|
.input(apiGitlabTestConnection)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
try {
|
||||||
|
const result = await testGitlabConnection(input);
|
||||||
|
|
||||||
|
return `Found ${result} repositories`;
|
||||||
|
} catch (error) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: error instanceof Error ? error?.message : `Error: ${error}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
update: protectedProcedure
|
||||||
|
.input(apiUpdateGitlab)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
if (input.name) {
|
||||||
|
await updateGitProvider(input.gitProviderId, {
|
||||||
|
name: input.name,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await updateGitlab(input.gitlabId, input);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
});
|
||||||
@@ -301,6 +301,10 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
"mongo",
|
"mongo",
|
||||||
"mariadb",
|
"mariadb",
|
||||||
"sshRouter",
|
"sshRouter",
|
||||||
|
"gitProvider",
|
||||||
|
"bitbucket",
|
||||||
|
"github",
|
||||||
|
"gitlab",
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -322,9 +326,9 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
writeTraefikEnv: adminProcedure
|
writeTraefikEnv: adminProcedure
|
||||||
.input(z.string())
|
.input(z.object({ env: z.string() }))
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
const envs = prepareEnvironmentVariables(input);
|
const envs = prepareEnvironmentVariables(input.env);
|
||||||
await initializeTraefik({
|
await initializeTraefik({
|
||||||
env: envs,
|
env: envs,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -129,13 +129,9 @@ export const getUserByToken = async (token: string) => {
|
|||||||
message: "Invitation not found",
|
message: "Invitation not found",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
const isExpired = isAfter(now, new Date(user.expirationDate));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
isExpired,
|
isExpired: user.isRegistered,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import { createDeployment, updateDeploymentStatus } from "./deployment";
|
|||||||
|
|
||||||
import { sendBuildErrorNotifications } from "@/server/utils/notifications/build-error";
|
import { sendBuildErrorNotifications } from "@/server/utils/notifications/build-error";
|
||||||
import { sendBuildSuccessNotifications } from "@/server/utils/notifications/build-success";
|
import { sendBuildSuccessNotifications } from "@/server/utils/notifications/build-success";
|
||||||
|
import { cloneBitbucketRepository } from "@/server/utils/providers/bitbucket";
|
||||||
|
import { cloneGitlabRepository } from "@/server/utils/providers/gitlab";
|
||||||
import { validUniqueServerAppName } from "./project";
|
import { validUniqueServerAppName } from "./project";
|
||||||
export type Application = typeof applications.$inferSelect;
|
export type Application = typeof applications.$inferSelect;
|
||||||
|
|
||||||
@@ -81,6 +83,9 @@ export const findApplicationById = async (applicationId: string) => {
|
|||||||
security: true,
|
security: true,
|
||||||
ports: true,
|
ports: true,
|
||||||
registry: true,
|
registry: true,
|
||||||
|
gitlab: true,
|
||||||
|
github: true,
|
||||||
|
bitbucket: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!application) {
|
if (!application) {
|
||||||
@@ -141,7 +146,6 @@ export const deployApplication = async ({
|
|||||||
}) => {
|
}) => {
|
||||||
const application = await findApplicationById(applicationId);
|
const application = await findApplicationById(applicationId);
|
||||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.projectId}/services/application/${application.applicationId}?tab=deployments`;
|
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.projectId}/services/application/${application.applicationId}?tab=deployments`;
|
||||||
const admin = await findAdmin();
|
|
||||||
const deployment = await createDeployment({
|
const deployment = await createDeployment({
|
||||||
applicationId: applicationId,
|
applicationId: applicationId,
|
||||||
title: titleLog,
|
title: titleLog,
|
||||||
@@ -150,7 +154,13 @@ export const deployApplication = async ({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (application.sourceType === "github") {
|
if (application.sourceType === "github") {
|
||||||
await cloneGithubRepository(admin, application, deployment.logPath);
|
await cloneGithubRepository(application, deployment.logPath);
|
||||||
|
await buildApplication(application, deployment.logPath);
|
||||||
|
} else if (application.sourceType === "gitlab") {
|
||||||
|
await cloneGitlabRepository(application, deployment.logPath);
|
||||||
|
await buildApplication(application, deployment.logPath);
|
||||||
|
} else if (application.sourceType === "bitbucket") {
|
||||||
|
await cloneBitbucketRepository(application, deployment.logPath);
|
||||||
await buildApplication(application, deployment.logPath);
|
await buildApplication(application, deployment.logPath);
|
||||||
} else if (application.sourceType === "docker") {
|
} else if (application.sourceType === "docker") {
|
||||||
await buildDocker(application, deployment.logPath);
|
await buildDocker(application, deployment.logPath);
|
||||||
@@ -214,6 +224,10 @@ export const rebuildApplication = async ({
|
|||||||
try {
|
try {
|
||||||
if (application.sourceType === "github") {
|
if (application.sourceType === "github") {
|
||||||
await buildApplication(application, deployment.logPath);
|
await buildApplication(application, deployment.logPath);
|
||||||
|
} else if (application.sourceType === "gitlab") {
|
||||||
|
await buildApplication(application, deployment.logPath);
|
||||||
|
} else if (application.sourceType === "bitbucket") {
|
||||||
|
await buildApplication(application, deployment.logPath);
|
||||||
} else if (application.sourceType === "docker") {
|
} else if (application.sourceType === "docker") {
|
||||||
await buildDocker(application, deployment.logPath);
|
await buildDocker(application, deployment.logPath);
|
||||||
} else if (application.sourceType === "git") {
|
} else if (application.sourceType === "git") {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export const createUser = async (input: typeof apiCreateUser._type) => {
|
|||||||
.update(users)
|
.update(users)
|
||||||
.set({
|
.set({
|
||||||
isRegistered: true,
|
isRegistered: true,
|
||||||
expirationDate: new Date().toISOString(),
|
expirationDate: undefined,
|
||||||
})
|
})
|
||||||
.where(eq(users.token, input.token))
|
.where(eq(users.token, input.token))
|
||||||
.returning()
|
.returning()
|
||||||
|
|||||||
88
apps/dokploy/server/api/services/bitbucket.ts
Normal file
88
apps/dokploy/server/api/services/bitbucket.ts
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import { db } from "@/server/db";
|
||||||
|
import {
|
||||||
|
type apiCreateBitbucket,
|
||||||
|
type apiUpdateBitbucket,
|
||||||
|
bitbucket,
|
||||||
|
gitProvider,
|
||||||
|
} from "@/server/db/schema";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
|
||||||
|
export type Bitbucket = typeof bitbucket.$inferSelect;
|
||||||
|
|
||||||
|
export const createBitbucket = async (
|
||||||
|
input: typeof apiCreateBitbucket._type,
|
||||||
|
) => {
|
||||||
|
return await db.transaction(async (tx) => {
|
||||||
|
const newGitProvider = await tx
|
||||||
|
.insert(gitProvider)
|
||||||
|
.values({
|
||||||
|
providerType: "bitbucket",
|
||||||
|
authId: input.authId,
|
||||||
|
name: input.name,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
|
||||||
|
if (!newGitProvider) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Error to create the git provider",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await tx
|
||||||
|
.insert(bitbucket)
|
||||||
|
.values({
|
||||||
|
...input,
|
||||||
|
gitProviderId: newGitProvider?.gitProviderId,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const findBitbucketById = async (bitbucketId: string) => {
|
||||||
|
const bitbucketProviderResult = await db.query.bitbucket.findFirst({
|
||||||
|
where: eq(bitbucket.bitbucketId, bitbucketId),
|
||||||
|
with: {
|
||||||
|
gitProvider: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!bitbucketProviderResult) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Bitbucket Provider not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitbucketProviderResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateBitbucket = async (
|
||||||
|
bitbucketId: string,
|
||||||
|
input: typeof apiUpdateBitbucket._type,
|
||||||
|
) => {
|
||||||
|
return await db.transaction(async (tx) => {
|
||||||
|
const result = await tx
|
||||||
|
.update(bitbucket)
|
||||||
|
.set({
|
||||||
|
...input,
|
||||||
|
})
|
||||||
|
.where(eq(bitbucket.bitbucketId, bitbucketId))
|
||||||
|
.returning();
|
||||||
|
|
||||||
|
if (input.name) {
|
||||||
|
await tx
|
||||||
|
.update(gitProvider)
|
||||||
|
.set({
|
||||||
|
name: input.name,
|
||||||
|
})
|
||||||
|
.where(eq(gitProvider.gitProviderId, input.gitProviderId))
|
||||||
|
.returning();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result[0];
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -5,17 +5,18 @@ import { type apiCreateCompose, compose } from "@/server/db/schema";
|
|||||||
import { generateAppName } from "@/server/db/schema/utils";
|
import { generateAppName } from "@/server/db/schema/utils";
|
||||||
import { buildCompose } from "@/server/utils/builders/compose";
|
import { buildCompose } from "@/server/utils/builders/compose";
|
||||||
import { cloneCompose, loadDockerCompose } from "@/server/utils/docker/domain";
|
import { cloneCompose, loadDockerCompose } from "@/server/utils/docker/domain";
|
||||||
import type { ComposeSpecification } from "@/server/utils/docker/types";
|
|
||||||
import { sendBuildErrorNotifications } from "@/server/utils/notifications/build-error";
|
import { sendBuildErrorNotifications } from "@/server/utils/notifications/build-error";
|
||||||
import { sendBuildSuccessNotifications } from "@/server/utils/notifications/build-success";
|
import { sendBuildSuccessNotifications } from "@/server/utils/notifications/build-success";
|
||||||
import { execAsync } from "@/server/utils/process/execAsync";
|
import { execAsync } from "@/server/utils/process/execAsync";
|
||||||
|
import { cloneBitbucketRepository } from "@/server/utils/providers/bitbucket";
|
||||||
import { cloneGitRepository } from "@/server/utils/providers/git";
|
import { cloneGitRepository } from "@/server/utils/providers/git";
|
||||||
import { cloneGithubRepository } from "@/server/utils/providers/github";
|
import { cloneGithubRepository } from "@/server/utils/providers/github";
|
||||||
|
import { cloneGitlabRepository } from "@/server/utils/providers/gitlab";
|
||||||
import { createComposeFile } from "@/server/utils/providers/raw";
|
import { createComposeFile } from "@/server/utils/providers/raw";
|
||||||
import { generatePassword } from "@/templates/utils";
|
import { generatePassword } from "@/templates/utils";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { findAdmin, getDokployUrl } from "./admin";
|
import { getDokployUrl } from "./admin";
|
||||||
import { createDeploymentCompose, updateDeploymentStatus } from "./deployment";
|
import { createDeploymentCompose, updateDeploymentStatus } from "./deployment";
|
||||||
import { validUniqueServerAppName } from "./project";
|
import { validUniqueServerAppName } from "./project";
|
||||||
|
|
||||||
@@ -92,6 +93,9 @@ export const findComposeById = async (composeId: string) => {
|
|||||||
deployments: true,
|
deployments: true,
|
||||||
mounts: true,
|
mounts: true,
|
||||||
domains: true,
|
domains: true,
|
||||||
|
github: true,
|
||||||
|
gitlab: true,
|
||||||
|
bitbucket: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -151,7 +155,6 @@ export const deployCompose = async ({
|
|||||||
descriptionLog: string;
|
descriptionLog: string;
|
||||||
}) => {
|
}) => {
|
||||||
const compose = await findComposeById(composeId);
|
const compose = await findComposeById(composeId);
|
||||||
const admin = await findAdmin();
|
|
||||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${compose.projectId}/services/compose/${compose.composeId}?tab=deployments`;
|
const buildLink = `${await getDokployUrl()}/dashboard/project/${compose.projectId}/services/compose/${compose.composeId}?tab=deployments`;
|
||||||
const deployment = await createDeploymentCompose({
|
const deployment = await createDeploymentCompose({
|
||||||
composeId: composeId,
|
composeId: composeId,
|
||||||
@@ -161,7 +164,11 @@ export const deployCompose = async ({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (compose.sourceType === "github") {
|
if (compose.sourceType === "github") {
|
||||||
await cloneGithubRepository(admin, compose, deployment.logPath, true);
|
await cloneGithubRepository(compose, deployment.logPath);
|
||||||
|
} else if (compose.sourceType === "gitlab") {
|
||||||
|
await cloneGitlabRepository(compose, deployment.logPath);
|
||||||
|
} else if (compose.sourceType === "bitbucket") {
|
||||||
|
await cloneBitbucketRepository(compose, deployment.logPath);
|
||||||
} else if (compose.sourceType === "git") {
|
} else if (compose.sourceType === "git") {
|
||||||
await cloneGitRepository(compose, deployment.logPath, true);
|
await cloneGitRepository(compose, deployment.logPath, true);
|
||||||
} else if (compose.sourceType === "raw") {
|
} else if (compose.sourceType === "raw") {
|
||||||
|
|||||||
29
apps/dokploy/server/api/services/git-provider.ts
Normal file
29
apps/dokploy/server/api/services/git-provider.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { db } from "@/server/db";
|
||||||
|
import { type apiCreateGithub, gitProvider, github } from "@/server/db/schema";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
|
||||||
|
export type GitProvider = typeof gitProvider.$inferSelect;
|
||||||
|
|
||||||
|
export const removeGitProvider = async (gitProviderId: string) => {
|
||||||
|
const result = await db
|
||||||
|
.delete(gitProvider)
|
||||||
|
.where(eq(gitProvider.gitProviderId, gitProviderId))
|
||||||
|
.returning();
|
||||||
|
|
||||||
|
return result[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateGitProvider = async (
|
||||||
|
gitProviderId: string,
|
||||||
|
input: Partial<GitProvider>,
|
||||||
|
) => {
|
||||||
|
return await db
|
||||||
|
.update(gitProvider)
|
||||||
|
.set({
|
||||||
|
...input,
|
||||||
|
})
|
||||||
|
.where(eq(gitProvider.gitProviderId, gitProviderId))
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
};
|
||||||
75
apps/dokploy/server/api/services/github.ts
Normal file
75
apps/dokploy/server/api/services/github.ts
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import { db } from "@/server/db";
|
||||||
|
import { type apiCreateGithub, gitProvider, github } from "@/server/db/schema";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
|
||||||
|
export type Github = typeof github.$inferSelect;
|
||||||
|
export const createGithub = async (input: typeof apiCreateGithub._type) => {
|
||||||
|
return await db.transaction(async (tx) => {
|
||||||
|
const newGitProvider = await tx
|
||||||
|
.insert(gitProvider)
|
||||||
|
.values({
|
||||||
|
providerType: "github",
|
||||||
|
authId: input.authId,
|
||||||
|
name: input.name,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
|
||||||
|
if (!newGitProvider) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Error to create the git provider",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return await tx
|
||||||
|
.insert(github)
|
||||||
|
.values({
|
||||||
|
...input,
|
||||||
|
gitProviderId: newGitProvider?.gitProviderId,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const findGithubById = async (githubId: string) => {
|
||||||
|
const githubProviderResult = await db.query.github.findFirst({
|
||||||
|
where: eq(github.githubId, githubId),
|
||||||
|
with: {
|
||||||
|
gitProvider: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!githubProviderResult) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Github Provider not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return githubProviderResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const haveGithubRequirements = (github: Github) => {
|
||||||
|
return !!(
|
||||||
|
github?.githubAppId &&
|
||||||
|
github?.githubPrivateKey &&
|
||||||
|
github?.githubInstallationId
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateGithub = async (
|
||||||
|
githubId: string,
|
||||||
|
input: Partial<Github>,
|
||||||
|
) => {
|
||||||
|
return await db
|
||||||
|
.update(github)
|
||||||
|
.set({
|
||||||
|
...input,
|
||||||
|
})
|
||||||
|
.where(eq(github.githubId, githubId))
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
};
|
||||||
76
apps/dokploy/server/api/services/gitlab.ts
Normal file
76
apps/dokploy/server/api/services/gitlab.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { db } from "@/server/db";
|
||||||
|
import {
|
||||||
|
type apiCreateGitlab,
|
||||||
|
type bitbucket,
|
||||||
|
gitProvider,
|
||||||
|
type github,
|
||||||
|
gitlab,
|
||||||
|
} from "@/server/db/schema";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
|
||||||
|
export type Github = typeof github.$inferSelect;
|
||||||
|
export type Bitbucket = typeof bitbucket.$inferSelect;
|
||||||
|
export type Gitlab = typeof gitlab.$inferSelect;
|
||||||
|
|
||||||
|
export const createGitlab = async (input: typeof apiCreateGitlab._type) => {
|
||||||
|
return await db.transaction(async (tx) => {
|
||||||
|
const newGitProvider = await tx
|
||||||
|
.insert(gitProvider)
|
||||||
|
.values({
|
||||||
|
providerType: "gitlab",
|
||||||
|
authId: input.authId,
|
||||||
|
name: input.name,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
|
||||||
|
if (!newGitProvider) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Error to create the git provider",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await tx
|
||||||
|
.insert(gitlab)
|
||||||
|
.values({
|
||||||
|
...input,
|
||||||
|
gitProviderId: newGitProvider?.gitProviderId,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const findGitlabById = async (gitlabId: string) => {
|
||||||
|
const gitlabProviderResult = await db.query.gitlab.findFirst({
|
||||||
|
where: eq(gitlab.gitlabId, gitlabId),
|
||||||
|
with: {
|
||||||
|
gitProvider: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!gitlabProviderResult) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Gitlab Provider not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return gitlabProviderResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateGitlab = async (
|
||||||
|
gitlabId: string,
|
||||||
|
input: Partial<Gitlab>,
|
||||||
|
) => {
|
||||||
|
return await db
|
||||||
|
.update(gitlab)
|
||||||
|
.set({
|
||||||
|
...input,
|
||||||
|
})
|
||||||
|
.where(eq(gitlab.gitlabId, gitlabId))
|
||||||
|
.returning()
|
||||||
|
.then((response) => response[0]);
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { relations } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
import { boolean, integer, pgTable, text } from "drizzle-orm/pg-core";
|
import { boolean, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -13,17 +13,9 @@ export const admins = pgTable("admin", {
|
|||||||
.notNull()
|
.notNull()
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
.$defaultFn(() => nanoid()),
|
.$defaultFn(() => nanoid()),
|
||||||
|
|
||||||
githubAppId: integer("githubAppId"),
|
|
||||||
githubAppName: text("githubAppName"),
|
|
||||||
serverIp: text("serverIp"),
|
serverIp: text("serverIp"),
|
||||||
certificateType: certificateType("certificateType").notNull().default("none"),
|
certificateType: certificateType("certificateType").notNull().default("none"),
|
||||||
host: text("host"),
|
host: text("host"),
|
||||||
githubClientId: text("githubClientId"),
|
|
||||||
githubClientSecret: text("githubClientSecret"),
|
|
||||||
githubInstallationId: text("githubInstallationId"),
|
|
||||||
githubPrivateKey: text("githubPrivateKey"),
|
|
||||||
githubWebhookSecret: text("githubWebhookSecret"),
|
|
||||||
letsEncryptEmail: text("letsEncryptEmail"),
|
letsEncryptEmail: text("letsEncryptEmail"),
|
||||||
sshPrivateKey: text("sshPrivateKey"),
|
sshPrivateKey: text("sshPrivateKey"),
|
||||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||||
@@ -46,12 +38,6 @@ export const adminsRelations = relations(admins, ({ one, many }) => ({
|
|||||||
|
|
||||||
const createSchema = createInsertSchema(admins, {
|
const createSchema = createInsertSchema(admins, {
|
||||||
adminId: z.string(),
|
adminId: z.string(),
|
||||||
githubAppName: z.string().optional(),
|
|
||||||
githubClientId: z.string().optional(),
|
|
||||||
githubClientSecret: z.string().optional(),
|
|
||||||
githubInstallationId: z.string().optional(),
|
|
||||||
githubPrivateKey: z.string().optional(),
|
|
||||||
githubAppId: z.number().optional(),
|
|
||||||
enableDockerCleanup: z.boolean().optional(),
|
enableDockerCleanup: z.boolean().optional(),
|
||||||
sshPrivateKey: z.string().optional(),
|
sshPrivateKey: z.string().optional(),
|
||||||
certificateType: z.enum(["letsencrypt", "none"]).default("none"),
|
certificateType: z.enum(["letsencrypt", "none"]).default("none"),
|
||||||
@@ -82,10 +68,6 @@ export const apiTraefikConfig = z.object({
|
|||||||
traefikConfig: z.string().min(1),
|
traefikConfig: z.string().min(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const apiGetBranches = z.object({
|
|
||||||
repo: z.string().min(1),
|
|
||||||
owner: z.string().min(1),
|
|
||||||
});
|
|
||||||
export const apiModifyTraefikConfig = z.object({
|
export const apiModifyTraefikConfig = z.object({
|
||||||
path: z.string().min(1),
|
path: z.string().min(1),
|
||||||
traefikConfig: z.string().min(1),
|
traefikConfig: z.string().min(1),
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { generatePassword } from "@/templates/utils";
|
|
||||||
import { relations } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
boolean,
|
boolean,
|
||||||
@@ -11,6 +10,7 @@ import {
|
|||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { bitbucket, github, gitlab } from ".";
|
||||||
import { deployments } from "./deployment";
|
import { deployments } from "./deployment";
|
||||||
import { domains } from "./domain";
|
import { domains } from "./domain";
|
||||||
import { mounts } from "./mount";
|
import { mounts } from "./mount";
|
||||||
@@ -27,6 +27,8 @@ export const sourceType = pgEnum("sourceType", [
|
|||||||
"docker",
|
"docker",
|
||||||
"git",
|
"git",
|
||||||
"github",
|
"github",
|
||||||
|
"gitlab",
|
||||||
|
"bitbucket",
|
||||||
"drop",
|
"drop",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -126,6 +128,18 @@ export const applications = pgTable("application", {
|
|||||||
branch: text("branch"),
|
branch: text("branch"),
|
||||||
buildPath: text("buildPath").default("/"),
|
buildPath: text("buildPath").default("/"),
|
||||||
autoDeploy: boolean("autoDeploy").$defaultFn(() => true),
|
autoDeploy: boolean("autoDeploy").$defaultFn(() => true),
|
||||||
|
// Gitlab
|
||||||
|
gitlabProjectId: integer("gitlabProjectId"),
|
||||||
|
gitlabRepository: text("gitlabRepository"),
|
||||||
|
gitlabOwner: text("gitlabOwner"),
|
||||||
|
gitlabBranch: text("gitlabBranch"),
|
||||||
|
gitlabBuildPath: text("gitlabBuildPath").default("/"),
|
||||||
|
gitlabPathNamespace: text("gitlabPathNamespace"),
|
||||||
|
// Bitbucket
|
||||||
|
bitbucketRepository: text("bitbucketRepository"),
|
||||||
|
bitbucketOwner: text("bitbucketOwner"),
|
||||||
|
bitbucketBranch: text("bitbucketBranch"),
|
||||||
|
bitbucketBuildPath: text("bitbucketBuildPath").default("/"),
|
||||||
// Docker
|
// Docker
|
||||||
username: text("username"),
|
username: text("username"),
|
||||||
password: text("password"),
|
password: text("password"),
|
||||||
@@ -169,6 +183,15 @@ export const applications = pgTable("application", {
|
|||||||
projectId: text("projectId")
|
projectId: text("projectId")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||||
|
githubId: text("githubId").references(() => github.githubId, {
|
||||||
|
onDelete: "set null",
|
||||||
|
}),
|
||||||
|
gitlabId: text("gitlabId").references(() => gitlab.gitlabId, {
|
||||||
|
onDelete: "set null",
|
||||||
|
}),
|
||||||
|
bitbucketId: text("bitbucketId").references(() => bitbucket.bitbucketId, {
|
||||||
|
onDelete: "set null",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const applicationsRelations = relations(
|
export const applicationsRelations = relations(
|
||||||
@@ -192,6 +215,18 @@ export const applicationsRelations = relations(
|
|||||||
fields: [applications.registryId],
|
fields: [applications.registryId],
|
||||||
references: [registry.registryId],
|
references: [registry.registryId],
|
||||||
}),
|
}),
|
||||||
|
github: one(github, {
|
||||||
|
fields: [applications.githubId],
|
||||||
|
references: [github.githubId],
|
||||||
|
}),
|
||||||
|
gitlab: one(gitlab, {
|
||||||
|
fields: [applications.gitlabId],
|
||||||
|
references: [gitlab.gitlabId],
|
||||||
|
}),
|
||||||
|
bitbucket: one(bitbucket, {
|
||||||
|
fields: [applications.bitbucketId],
|
||||||
|
references: [bitbucket.bitbucketId],
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -369,6 +404,31 @@ export const apiSaveGithubProvider = createSchema
|
|||||||
branch: true,
|
branch: true,
|
||||||
owner: true,
|
owner: true,
|
||||||
buildPath: true,
|
buildPath: true,
|
||||||
|
githubId: true,
|
||||||
|
})
|
||||||
|
.required();
|
||||||
|
|
||||||
|
export const apiSaveGitlabProvider = createSchema
|
||||||
|
.pick({
|
||||||
|
applicationId: true,
|
||||||
|
gitlabBranch: true,
|
||||||
|
gitlabBuildPath: true,
|
||||||
|
gitlabOwner: true,
|
||||||
|
gitlabRepository: true,
|
||||||
|
gitlabId: true,
|
||||||
|
gitlabProjectId: true,
|
||||||
|
gitlabPathNamespace: true,
|
||||||
|
})
|
||||||
|
.required();
|
||||||
|
|
||||||
|
export const apiSaveBitbucketProvider = createSchema
|
||||||
|
.pick({
|
||||||
|
bitbucketBranch: true,
|
||||||
|
bitbucketBuildPath: true,
|
||||||
|
bitbucketOwner: true,
|
||||||
|
bitbucketRepository: true,
|
||||||
|
bitbucketId: true,
|
||||||
|
applicationId: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ export const apiCreateUser = createSchema
|
|||||||
.pick({
|
.pick({
|
||||||
password: true,
|
password: true,
|
||||||
id: true,
|
id: true,
|
||||||
|
token: true,
|
||||||
})
|
})
|
||||||
.required()
|
.required()
|
||||||
.extend({
|
.extend({
|
||||||
|
|||||||
64
apps/dokploy/server/db/schema/bitbucket.ts
Normal file
64
apps/dokploy/server/db/schema/bitbucket.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { relations } from "drizzle-orm";
|
||||||
|
import { pgTable, text } from "drizzle-orm/pg-core";
|
||||||
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { gitProvider } from "./git-provider";
|
||||||
|
|
||||||
|
export const bitbucket = pgTable("bitbucket", {
|
||||||
|
bitbucketId: text("bitbucketId")
|
||||||
|
.notNull()
|
||||||
|
.primaryKey()
|
||||||
|
.$defaultFn(() => nanoid()),
|
||||||
|
bitbucketUsername: text("bitbucketUsername"),
|
||||||
|
appPassword: text("appPassword"),
|
||||||
|
bitbucketWorkspaceName: text("bitbucketWorkspaceName"),
|
||||||
|
gitProviderId: text("gitProviderId")
|
||||||
|
.notNull()
|
||||||
|
.references(() => gitProvider.gitProviderId, { onDelete: "cascade" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const bitbucketProviderRelations = relations(bitbucket, ({ one }) => ({
|
||||||
|
gitProvider: one(gitProvider, {
|
||||||
|
fields: [bitbucket.gitProviderId],
|
||||||
|
references: [gitProvider.gitProviderId],
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const createSchema = createInsertSchema(bitbucket);
|
||||||
|
|
||||||
|
export const apiCreateBitbucket = createSchema.extend({
|
||||||
|
bitbucketUsername: z.string().optional(),
|
||||||
|
appPassword: z.string().optional(),
|
||||||
|
bitbucketWorkspaceName: z.string().optional(),
|
||||||
|
gitProviderId: z.string().optional(),
|
||||||
|
authId: z.string().min(1),
|
||||||
|
name: z.string().min(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiFindOneBitbucket = createSchema
|
||||||
|
.extend({
|
||||||
|
bitbucketId: z.string().min(1),
|
||||||
|
})
|
||||||
|
.pick({ bitbucketId: true });
|
||||||
|
|
||||||
|
export const apiBitbucketTestConnection = createSchema
|
||||||
|
.extend({
|
||||||
|
bitbucketId: z.string().min(1),
|
||||||
|
bitbucketUsername: z.string().optional(),
|
||||||
|
workspaceName: z.string().optional(),
|
||||||
|
})
|
||||||
|
.pick({ bitbucketId: true, bitbucketUsername: true, workspaceName: true });
|
||||||
|
|
||||||
|
export const apiFindBitbucketBranches = z.object({
|
||||||
|
owner: z.string(),
|
||||||
|
repo: z.string(),
|
||||||
|
bitbucketId: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiUpdateBitbucket = createSchema.extend({
|
||||||
|
bitbucketId: z.string().min(1),
|
||||||
|
name: z.string().min(1),
|
||||||
|
bitbucketUsername: z.string().optional(),
|
||||||
|
bitbucketWorkspaceName: z.string().optional(),
|
||||||
|
});
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import { sshKeys } from "@/server/db/schema/ssh-key";
|
import { sshKeys } from "@/server/db/schema/ssh-key";
|
||||||
import { relations } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
import { boolean, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
import { boolean, integer, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { bitbucket, github, gitlab } from ".";
|
||||||
import { deployments } from "./deployment";
|
import { deployments } from "./deployment";
|
||||||
import { domains } from "./domain";
|
import { domains } from "./domain";
|
||||||
import { mounts } from "./mount";
|
import { mounts } from "./mount";
|
||||||
@@ -14,6 +15,8 @@ import { generateAppName } from "./utils";
|
|||||||
export const sourceTypeCompose = pgEnum("sourceTypeCompose", [
|
export const sourceTypeCompose = pgEnum("sourceTypeCompose", [
|
||||||
"git",
|
"git",
|
||||||
"github",
|
"github",
|
||||||
|
"gitlab",
|
||||||
|
"bitbucket",
|
||||||
"raw",
|
"raw",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -39,6 +42,16 @@ export const compose = pgTable("compose", {
|
|||||||
owner: text("owner"),
|
owner: text("owner"),
|
||||||
branch: text("branch"),
|
branch: text("branch"),
|
||||||
autoDeploy: boolean("autoDeploy").$defaultFn(() => true),
|
autoDeploy: boolean("autoDeploy").$defaultFn(() => true),
|
||||||
|
// Gitlab
|
||||||
|
gitlabProjectId: integer("gitlabProjectId"),
|
||||||
|
gitlabRepository: text("gitlabRepository"),
|
||||||
|
gitlabOwner: text("gitlabOwner"),
|
||||||
|
gitlabBranch: text("gitlabBranch"),
|
||||||
|
gitlabPathNamespace: text("gitlabPathNamespace"),
|
||||||
|
// Bitbucket
|
||||||
|
bitbucketRepository: text("bitbucketRepository"),
|
||||||
|
bitbucketOwner: text("bitbucketOwner"),
|
||||||
|
bitbucketBranch: text("bitbucketBranch"),
|
||||||
// Git
|
// Git
|
||||||
customGitUrl: text("customGitUrl"),
|
customGitUrl: text("customGitUrl"),
|
||||||
customGitBranch: text("customGitBranch"),
|
customGitBranch: text("customGitBranch"),
|
||||||
@@ -48,7 +61,6 @@ export const compose = pgTable("compose", {
|
|||||||
onDelete: "set null",
|
onDelete: "set null",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
//
|
|
||||||
command: text("command").notNull().default(""),
|
command: text("command").notNull().default(""),
|
||||||
//
|
//
|
||||||
composePath: text("composePath").notNull().default("./docker-compose.yml"),
|
composePath: text("composePath").notNull().default("./docker-compose.yml"),
|
||||||
@@ -59,6 +71,16 @@ export const compose = pgTable("compose", {
|
|||||||
createdAt: text("createdAt")
|
createdAt: text("createdAt")
|
||||||
.notNull()
|
.notNull()
|
||||||
.$defaultFn(() => new Date().toISOString()),
|
.$defaultFn(() => new Date().toISOString()),
|
||||||
|
|
||||||
|
githubId: text("githubId").references(() => github.githubId, {
|
||||||
|
onDelete: "set null",
|
||||||
|
}),
|
||||||
|
gitlabId: text("gitlabId").references(() => gitlab.gitlabId, {
|
||||||
|
onDelete: "set null",
|
||||||
|
}),
|
||||||
|
bitbucketId: text("bitbucketId").references(() => bitbucket.bitbucketId, {
|
||||||
|
onDelete: "set null",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const composeRelations = relations(compose, ({ one, many }) => ({
|
export const composeRelations = relations(compose, ({ one, many }) => ({
|
||||||
@@ -73,6 +95,18 @@ export const composeRelations = relations(compose, ({ one, many }) => ({
|
|||||||
references: [sshKeys.sshKeyId],
|
references: [sshKeys.sshKeyId],
|
||||||
}),
|
}),
|
||||||
domains: many(domains),
|
domains: many(domains),
|
||||||
|
github: one(github, {
|
||||||
|
fields: [compose.githubId],
|
||||||
|
references: [github.githubId],
|
||||||
|
}),
|
||||||
|
gitlab: one(gitlab, {
|
||||||
|
fields: [compose.gitlabId],
|
||||||
|
references: [gitlab.gitlabId],
|
||||||
|
}),
|
||||||
|
bitbucket: one(bitbucket, {
|
||||||
|
fields: [compose.bitbucketId],
|
||||||
|
references: [bitbucket.bitbucketId],
|
||||||
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createSchema = createInsertSchema(compose, {
|
const createSchema = createInsertSchema(compose, {
|
||||||
|
|||||||
57
apps/dokploy/server/db/schema/git-provider.ts
Normal file
57
apps/dokploy/server/db/schema/git-provider.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { relations } from "drizzle-orm";
|
||||||
|
import { pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { auth } from "./auth";
|
||||||
|
import { bitbucket } from "./bitbucket";
|
||||||
|
import { github } from "./github";
|
||||||
|
import { gitlab } from "./gitlab";
|
||||||
|
|
||||||
|
export const gitProviderType = pgEnum("gitProviderType", [
|
||||||
|
"github",
|
||||||
|
"gitlab",
|
||||||
|
"bitbucket",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const gitProvider = pgTable("git_provider", {
|
||||||
|
gitProviderId: text("gitProviderId")
|
||||||
|
.notNull()
|
||||||
|
.primaryKey()
|
||||||
|
.$defaultFn(() => nanoid()),
|
||||||
|
name: text("name").notNull(),
|
||||||
|
providerType: gitProviderType("providerType").notNull().default("github"),
|
||||||
|
createdAt: text("createdAt")
|
||||||
|
.notNull()
|
||||||
|
.$defaultFn(() => new Date().toISOString()),
|
||||||
|
authId: text("authId")
|
||||||
|
.notNull()
|
||||||
|
.references(() => auth.id, { onDelete: "cascade" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
|
||||||
|
github: one(github, {
|
||||||
|
fields: [gitProvider.gitProviderId],
|
||||||
|
references: [github.gitProviderId],
|
||||||
|
}),
|
||||||
|
gitlab: one(gitlab, {
|
||||||
|
fields: [gitProvider.gitProviderId],
|
||||||
|
references: [gitlab.gitProviderId],
|
||||||
|
}),
|
||||||
|
bitbucket: one(bitbucket, {
|
||||||
|
fields: [gitProvider.gitProviderId],
|
||||||
|
references: [bitbucket.gitProviderId],
|
||||||
|
}),
|
||||||
|
auth: one(auth, {
|
||||||
|
fields: [gitProvider.authId],
|
||||||
|
references: [auth.id],
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const createSchema = createInsertSchema(gitProvider);
|
||||||
|
|
||||||
|
export const apiRemoveGitProvider = createSchema
|
||||||
|
.extend({
|
||||||
|
gitProviderId: z.string().min(1),
|
||||||
|
})
|
||||||
|
.pick({ gitProviderId: true });
|
||||||
62
apps/dokploy/server/db/schema/github.ts
Normal file
62
apps/dokploy/server/db/schema/github.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { relations } from "drizzle-orm";
|
||||||
|
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { gitProvider } from "./git-provider";
|
||||||
|
|
||||||
|
export const github = pgTable("github", {
|
||||||
|
githubId: text("githubId")
|
||||||
|
.notNull()
|
||||||
|
.primaryKey()
|
||||||
|
.$defaultFn(() => nanoid()),
|
||||||
|
githubAppName: text("githubAppName"),
|
||||||
|
githubAppId: integer("githubAppId"),
|
||||||
|
githubClientId: text("githubClientId"),
|
||||||
|
githubClientSecret: text("githubClientSecret"),
|
||||||
|
githubInstallationId: text("githubInstallationId"),
|
||||||
|
githubPrivateKey: text("githubPrivateKey"),
|
||||||
|
githubWebhookSecret: text("githubWebhookSecret"),
|
||||||
|
gitProviderId: text("gitProviderId")
|
||||||
|
.notNull()
|
||||||
|
.references(() => gitProvider.gitProviderId, { onDelete: "cascade" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const githubProviderRelations = relations(github, ({ one }) => ({
|
||||||
|
gitProvider: one(gitProvider, {
|
||||||
|
fields: [github.gitProviderId],
|
||||||
|
references: [gitProvider.gitProviderId],
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const createSchema = createInsertSchema(github);
|
||||||
|
export const apiCreateGithub = createSchema.extend({
|
||||||
|
githubAppName: z.string().optional(),
|
||||||
|
githubAppId: z.number().optional(),
|
||||||
|
githubClientId: z.string().optional(),
|
||||||
|
githubClientSecret: z.string().optional(),
|
||||||
|
githubInstallationId: z.string().optional(),
|
||||||
|
githubPrivateKey: z.string().optional(),
|
||||||
|
githubWebhookSecret: z.string().nullable(),
|
||||||
|
gitProviderId: z.string().optional(),
|
||||||
|
name: z.string().min(1),
|
||||||
|
authId: z.string().min(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiFindGithubBranches = z.object({
|
||||||
|
repo: z.string().min(1),
|
||||||
|
owner: z.string().min(1),
|
||||||
|
githubId: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiFindOneGithub = createSchema
|
||||||
|
.extend({
|
||||||
|
githubId: z.string().min(1),
|
||||||
|
})
|
||||||
|
.pick({ githubId: true });
|
||||||
|
|
||||||
|
export const apiUpdateGithub = createSchema.extend({
|
||||||
|
githubId: z.string().min(1),
|
||||||
|
name: z.string().min(1),
|
||||||
|
gitProviderId: z.string().min(1),
|
||||||
|
});
|
||||||
70
apps/dokploy/server/db/schema/gitlab.ts
Normal file
70
apps/dokploy/server/db/schema/gitlab.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import { relations } from "drizzle-orm";
|
||||||
|
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { gitProvider } from "./git-provider";
|
||||||
|
|
||||||
|
export const gitlab = pgTable("gitlab", {
|
||||||
|
gitlabId: text("gitlabId")
|
||||||
|
.notNull()
|
||||||
|
.primaryKey()
|
||||||
|
.$defaultFn(() => nanoid()),
|
||||||
|
applicationId: text("application_id"),
|
||||||
|
redirectUri: text("redirect_uri"),
|
||||||
|
secret: text("secret"),
|
||||||
|
accessToken: text("access_token"),
|
||||||
|
refreshToken: text("refresh_token"),
|
||||||
|
groupName: text("group_name"),
|
||||||
|
expiresAt: integer("expires_at"),
|
||||||
|
gitProviderId: text("gitProviderId")
|
||||||
|
.notNull()
|
||||||
|
.references(() => gitProvider.gitProviderId, { onDelete: "cascade" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const gitlabProviderRelations = relations(gitlab, ({ one }) => ({
|
||||||
|
gitProvider: one(gitProvider, {
|
||||||
|
fields: [gitlab.gitProviderId],
|
||||||
|
references: [gitProvider.gitProviderId],
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const createSchema = createInsertSchema(gitlab);
|
||||||
|
|
||||||
|
export const apiCreateGitlab = createSchema.extend({
|
||||||
|
applicationId: z.string().optional(),
|
||||||
|
secret: z.string().optional(),
|
||||||
|
groupName: z.string().optional(),
|
||||||
|
gitProviderId: z.string().optional(),
|
||||||
|
redirectUri: z.string().optional(),
|
||||||
|
authId: z.string().min(1),
|
||||||
|
name: z.string().min(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiFindOneGitlab = createSchema
|
||||||
|
.extend({
|
||||||
|
gitlabId: z.string().min(1),
|
||||||
|
})
|
||||||
|
.pick({ gitlabId: true });
|
||||||
|
|
||||||
|
export const apiGitlabTestConnection = createSchema
|
||||||
|
.extend({
|
||||||
|
groupName: z.string().optional(),
|
||||||
|
})
|
||||||
|
.pick({ gitlabId: true, groupName: true });
|
||||||
|
|
||||||
|
export const apiFindGitlabBranches = z.object({
|
||||||
|
id: z.number().optional(),
|
||||||
|
owner: z.string(),
|
||||||
|
repo: z.string(),
|
||||||
|
gitlabId: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiUpdateGitlab = createSchema.extend({
|
||||||
|
applicationId: z.string().optional(),
|
||||||
|
secret: z.string().optional(),
|
||||||
|
groupName: z.string().optional(),
|
||||||
|
redirectUri: z.string().optional(),
|
||||||
|
name: z.string().min(1),
|
||||||
|
gitlabId: z.string().min(1),
|
||||||
|
});
|
||||||
@@ -23,3 +23,7 @@ export * from "./compose";
|
|||||||
export * from "./registry";
|
export * from "./registry";
|
||||||
export * from "./notification";
|
export * from "./notification";
|
||||||
export * from "./ssh-key";
|
export * from "./ssh-key";
|
||||||
|
export * from "./git-provider";
|
||||||
|
export * from "./bitbucket";
|
||||||
|
export * from "./github";
|
||||||
|
export * from "./gitlab";
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ export const users = pgTable("user", {
|
|||||||
canDeleteServices: boolean("canDeleteServices").notNull().default(false),
|
canDeleteServices: boolean("canDeleteServices").notNull().default(false),
|
||||||
canAccessToDocker: boolean("canAccessToDocker").notNull().default(false),
|
canAccessToDocker: boolean("canAccessToDocker").notNull().default(false),
|
||||||
canAccessToAPI: boolean("canAccessToAPI").notNull().default(false),
|
canAccessToAPI: boolean("canAccessToAPI").notNull().default(false),
|
||||||
|
canAccessToGitProviders: boolean("canAccessToGitProviders")
|
||||||
|
.notNull()
|
||||||
|
.default(false),
|
||||||
canAccessToTraefikFiles: boolean("canAccessToTraefikFiles")
|
canAccessToTraefikFiles: boolean("canAccessToTraefikFiles")
|
||||||
.notNull()
|
.notNull()
|
||||||
.default(false),
|
.default(false),
|
||||||
@@ -109,6 +112,7 @@ export const apiAssignPermissions = createSchema
|
|||||||
canAccessToDocker: true,
|
canAccessToDocker: true,
|
||||||
canAccessToAPI: true,
|
canAccessToAPI: true,
|
||||||
canAccessToSSHKeys: true,
|
canAccessToSSHKeys: true,
|
||||||
|
canAccessToGitProviders: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
|
||||||
|
|||||||
@@ -18,15 +18,7 @@ export type ComposeNested = InferResultType<
|
|||||||
>;
|
>;
|
||||||
export const buildCompose = async (compose: ComposeNested, logPath: string) => {
|
export const buildCompose = async (compose: ComposeNested, logPath: string) => {
|
||||||
const writeStream = createWriteStream(logPath, { flags: "a" });
|
const writeStream = createWriteStream(logPath, { flags: "a" });
|
||||||
const {
|
const { sourceType, appName, mounts, composeType, domains } = compose;
|
||||||
sourceType,
|
|
||||||
appName,
|
|
||||||
mounts,
|
|
||||||
composeType,
|
|
||||||
env,
|
|
||||||
composePath,
|
|
||||||
domains,
|
|
||||||
} = compose;
|
|
||||||
try {
|
try {
|
||||||
const command = createCommand(compose);
|
const command = createCommand(compose);
|
||||||
await writeDomainsToCompose(compose, domains);
|
await writeDomainsToCompose(compose, domains);
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import fs, { existsSync, readFileSync, writeSync } from "node:fs";
|
import fs, { existsSync, readFileSync } from "node:fs";
|
||||||
import { writeFile } from "node:fs/promises";
|
import { writeFile } from "node:fs/promises";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import type { Compose } from "@/server/api/services/compose";
|
import type { Compose } from "@/server/api/services/compose";
|
||||||
import type { Domain } from "@/server/api/services/domain";
|
import type { Domain } from "@/server/api/services/domain";
|
||||||
import { COMPOSE_PATH } from "@/server/constants";
|
import { COMPOSE_PATH } from "@/server/constants";
|
||||||
import { dump, load } from "js-yaml";
|
import { dump, load } from "js-yaml";
|
||||||
|
import { cloneRawBitbucketRepository } from "../providers/bitbucket";
|
||||||
import { cloneGitRawRepository } from "../providers/git";
|
import { cloneGitRawRepository } from "../providers/git";
|
||||||
import { cloneRawGithubRepository } from "../providers/github";
|
import { cloneRawGithubRepository } from "../providers/github";
|
||||||
|
import { cloneRawGitlabRepository } from "../providers/gitlab";
|
||||||
import { createComposeFileRaw } from "../providers/raw";
|
import { createComposeFileRaw } from "../providers/raw";
|
||||||
import type {
|
import type {
|
||||||
ComposeSpecification,
|
ComposeSpecification,
|
||||||
@@ -17,6 +19,10 @@ import type {
|
|||||||
export const cloneCompose = async (compose: Compose) => {
|
export const cloneCompose = async (compose: Compose) => {
|
||||||
if (compose.sourceType === "github") {
|
if (compose.sourceType === "github") {
|
||||||
await cloneRawGithubRepository(compose);
|
await cloneRawGithubRepository(compose);
|
||||||
|
} else if (compose.sourceType === "gitlab") {
|
||||||
|
await cloneRawGitlabRepository(compose);
|
||||||
|
} else if (compose.sourceType === "bitbucket") {
|
||||||
|
await cloneRawBitbucketRepository(compose);
|
||||||
} else if (compose.sourceType === "git") {
|
} else if (compose.sourceType === "git") {
|
||||||
await cloneGitRawRepository(compose);
|
await cloneGitRawRepository(compose);
|
||||||
} else if (compose.sourceType === "raw") {
|
} else if (compose.sourceType === "raw") {
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ export const getBuildAppDirectory = (application: Application) => {
|
|||||||
|
|
||||||
if (sourceType === "github") {
|
if (sourceType === "github") {
|
||||||
buildPath = application?.buildPath || "";
|
buildPath = application?.buildPath || "";
|
||||||
|
} else if (sourceType === "gitlab") {
|
||||||
|
buildPath = application?.gitlabBuildPath || "";
|
||||||
|
} else if (sourceType === "bitbucket") {
|
||||||
|
buildPath = application?.bitbucketBuildPath || "";
|
||||||
} else if (sourceType === "drop") {
|
} else if (sourceType === "drop") {
|
||||||
buildPath = application?.dropBuildPath || "";
|
buildPath = application?.dropBuildPath || "";
|
||||||
} else if (sourceType === "git") {
|
} else if (sourceType === "git") {
|
||||||
|
|||||||
262
apps/dokploy/server/utils/providers/bitbucket.ts
Normal file
262
apps/dokploy/server/utils/providers/bitbucket.ts
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
import { createWriteStream } from "node:fs";
|
||||||
|
import { join } from "node:path";
|
||||||
|
import { findBitbucketById } from "@/server/api/services/bitbucket";
|
||||||
|
import type { Compose } from "@/server/api/services/compose";
|
||||||
|
import { APPLICATIONS_PATH, COMPOSE_PATH } from "@/server/constants";
|
||||||
|
import type {
|
||||||
|
apiBitbucketTestConnection,
|
||||||
|
apiFindBitbucketBranches,
|
||||||
|
} from "@/server/db/schema";
|
||||||
|
import type { InferResultType } from "@/server/types/with";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { recreateDirectory } from "../filesystem/directory";
|
||||||
|
import { spawnAsync } from "../process/spawnAsync";
|
||||||
|
|
||||||
|
export type ApplicationWithBitbucket = InferResultType<
|
||||||
|
"applications",
|
||||||
|
{ bitbucket: true }
|
||||||
|
>;
|
||||||
|
|
||||||
|
export type ComposeWithBitbucket = InferResultType<
|
||||||
|
"compose",
|
||||||
|
{ bitbucket: true }
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const cloneBitbucketRepository = async (
|
||||||
|
entity: ApplicationWithBitbucket | ComposeWithBitbucket,
|
||||||
|
logPath: string,
|
||||||
|
isCompose = false,
|
||||||
|
) => {
|
||||||
|
const writeStream = createWriteStream(logPath, { flags: "a" });
|
||||||
|
const {
|
||||||
|
appName,
|
||||||
|
bitbucketRepository,
|
||||||
|
bitbucketOwner,
|
||||||
|
bitbucketBranch,
|
||||||
|
bitbucketId,
|
||||||
|
bitbucket,
|
||||||
|
} = entity;
|
||||||
|
|
||||||
|
if (!bitbucketId) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Bitbucket Provider not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
|
||||||
|
const outputPath = join(basePath, appName, "code");
|
||||||
|
await recreateDirectory(outputPath);
|
||||||
|
const repoclone = `bitbucket.org/${bitbucketOwner}/${bitbucketRepository}.git`;
|
||||||
|
const cloneUrl = `https://${bitbucket?.bitbucketUsername}:${bitbucket?.appPassword}@${repoclone}`;
|
||||||
|
try {
|
||||||
|
writeStream.write(`\nCloning Repo ${repoclone} to ${outputPath}: ✅\n`);
|
||||||
|
await spawnAsync(
|
||||||
|
"git",
|
||||||
|
[
|
||||||
|
"clone",
|
||||||
|
"--branch",
|
||||||
|
bitbucketBranch!,
|
||||||
|
"--depth",
|
||||||
|
"1",
|
||||||
|
cloneUrl,
|
||||||
|
outputPath,
|
||||||
|
"--progress",
|
||||||
|
],
|
||||||
|
(data) => {
|
||||||
|
if (writeStream.writable) {
|
||||||
|
writeStream.write(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
writeStream.write(`\nCloned ${repoclone} to ${outputPath}: ✅\n`);
|
||||||
|
} catch (error) {
|
||||||
|
writeStream.write(`ERROR Clonning: ${error}: ❌`);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
writeStream.end();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const cloneRawBitbucketRepository = async (entity: Compose) => {
|
||||||
|
const {
|
||||||
|
appName,
|
||||||
|
bitbucketRepository,
|
||||||
|
bitbucketOwner,
|
||||||
|
bitbucketBranch,
|
||||||
|
bitbucketId,
|
||||||
|
} = entity;
|
||||||
|
|
||||||
|
if (!bitbucketId) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Bitbucket Provider not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const bitbucketProvider = await findBitbucketById(bitbucketId);
|
||||||
|
const basePath = COMPOSE_PATH;
|
||||||
|
const outputPath = join(basePath, appName, "code");
|
||||||
|
await recreateDirectory(outputPath);
|
||||||
|
const repoclone = `bitbucket.org/${bitbucketOwner}/${bitbucketRepository}.git`;
|
||||||
|
const cloneUrl = `https://${bitbucketProvider?.bitbucketUsername}:${bitbucketProvider?.appPassword}@${repoclone}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await spawnAsync("git", [
|
||||||
|
"clone",
|
||||||
|
"--branch",
|
||||||
|
bitbucketBranch!,
|
||||||
|
"--depth",
|
||||||
|
"1",
|
||||||
|
cloneUrl,
|
||||||
|
outputPath,
|
||||||
|
"--progress",
|
||||||
|
]);
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getBitbucketRepositories = async (bitbucketId?: string) => {
|
||||||
|
if (!bitbucketId) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const bitbucketProvider = await findBitbucketById(bitbucketId);
|
||||||
|
|
||||||
|
const username =
|
||||||
|
bitbucketProvider.bitbucketWorkspaceName ||
|
||||||
|
bitbucketProvider.bitbucketUsername;
|
||||||
|
const url = `https://api.bitbucket.org/2.0/repositories/${username}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Basic ${Buffer.from(`${bitbucketProvider.bitbucketUsername}:${bitbucketProvider.appPassword}`).toString("base64")}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: `Failed to fetch repositories: ${response.statusText}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
const mappedData = data.values.map((repo: any) => {
|
||||||
|
return {
|
||||||
|
name: repo.name,
|
||||||
|
url: repo.links.html.href,
|
||||||
|
owner: {
|
||||||
|
username: repo.workspace.slug,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return mappedData as {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
owner: {
|
||||||
|
username: string;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getBitbucketBranches = async (
|
||||||
|
input: typeof apiFindBitbucketBranches._type,
|
||||||
|
) => {
|
||||||
|
if (!input.bitbucketId) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||||
|
const { owner, repo } = input;
|
||||||
|
const url = `https://api.bitbucket.org/2.0/repositories/${owner}/${repo}/refs/branches`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Basic ${Buffer.from(`${bitbucketProvider.bitbucketUsername}:${bitbucketProvider.appPassword}`).toString("base64")}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: `HTTP error! status: ${response.status}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
const mappedData = data.values.map((branch: any) => {
|
||||||
|
return {
|
||||||
|
name: branch.name,
|
||||||
|
commit: {
|
||||||
|
sha: branch.target.hash,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return mappedData as {
|
||||||
|
name: string;
|
||||||
|
commit: {
|
||||||
|
sha: string;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const testBitbucketConnection = async (
|
||||||
|
input: typeof apiBitbucketTestConnection._type,
|
||||||
|
) => {
|
||||||
|
const bitbucketProvider = await findBitbucketById(input.bitbucketId);
|
||||||
|
|
||||||
|
if (!bitbucketProvider) {
|
||||||
|
throw new Error("Bitbucket provider not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
const { bitbucketUsername, workspaceName } = input;
|
||||||
|
|
||||||
|
const username = workspaceName || bitbucketUsername;
|
||||||
|
|
||||||
|
const url = `https://api.bitbucket.org/2.0/repositories/${username}`;
|
||||||
|
try {
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Basic ${Buffer.from(`${bitbucketProvider.bitbucketUsername}:${bitbucketProvider.appPassword}`).toString("base64")}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: `Failed to fetch repositories: ${response.statusText}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
const mappedData = data.values.map((repo: any) => {
|
||||||
|
return {
|
||||||
|
name: repo.name,
|
||||||
|
url: repo.links.html.href,
|
||||||
|
owner: {
|
||||||
|
username: repo.workspace.slug,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}) as [];
|
||||||
|
|
||||||
|
return mappedData.length;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user