feat: Digital Ocean App connection and App Platform secret sync (#4203)

* fix: save wip

* feat: final impl

* feat: docs

* Update backend/src/services/app-connection/digital-ocean/digital-ocean-connection-service.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* chore: remove empty conflict files

* Update backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update frontend/src/components/secret-syncs/forms/schemas/digital-ocean-app-platform-sync-destination-schema.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update frontend/src/components/secret-syncs/forms/schemas/digital-ocean-app-platform-sync-destination-schema.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/DigitalOceanAppPlatformSyncFields.tsx

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update backend/src/services/secret-sync/digital-ocean-app-platform/digital-ocean-app-platform-sync-schemas.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix: lint

* fix: api client

* fix: lint and types

* fix: typecheck lint

* fix: docs

* fix: docs

* fix: linting

---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
Sid
2025-07-23 19:59:29 +05:30
committed by GitHub
co-authored by greptile-apps[bot]
parent 95b997c100
commit ab56a69d59
90 changed files with 1363 additions and 8 deletions
@@ -0,0 +1 @@
export * from "./queries";
@@ -0,0 +1,37 @@
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "@app/hooks/api/appConnections";
import { TDigitalOceanApp } from "./types";
const digitalOceanAppPlatformConnectionKeys = {
all: [...appConnectionKeys.all, "digitalOceanAppPlatform"] as const,
listAccounts: (connectionId: string) =>
[...digitalOceanAppPlatformConnectionKeys.all, "workspace-scopes", connectionId] as const
};
export const useDigitalOceanConnectionListApps = (
connectionId: string,
options?: Omit<
UseQueryOptions<
TDigitalOceanApp[],
unknown,
TDigitalOceanApp[],
ReturnType<typeof digitalOceanAppPlatformConnectionKeys.listAccounts>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: digitalOceanAppPlatformConnectionKeys.listAccounts(connectionId),
queryFn: async () => {
const { data } = await apiRequest.get<{ apps: TDigitalOceanApp[] }>(
`/api/v1/app-connections/digital-ocean/${connectionId}/apps`
);
return data.apps;
},
...options
});
};
@@ -0,0 +1,16 @@
export type TDigitalOceanAppPlatformVariable = {
key: string;
value: string;
type: "SECRET" | "GENERAL";
};
export type TDigitalOceanApp = {
id: string;
spec: {
name: string;
services: Array<{
name: string;
}>;
envs?: TDigitalOceanAppPlatformVariable[];
};
};
@@ -33,5 +33,6 @@ export enum AppConnection {
Railway = "railway",
Checkly = "checkly",
Supabase = "supabase",
DigitalOcean = "digital-ocean",
Okta = "okta"
}
@@ -152,6 +152,10 @@ export type TSupabaseConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Supabase;
};
export type TDigitalOceanConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.DigitalOcean;
};
export type TOktaConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Okta;
};
@@ -188,6 +192,7 @@ export type TAppConnectionOption =
| TZabbixConnectionOption
| TRailwayConnectionOption
| TChecklyConnectionOption
| TDigitalOceanConnectionOption
| TOktaConnectionOption;
export type TAppConnectionOptionMap = {
@@ -225,5 +230,6 @@ export type TAppConnectionOptionMap = {
[AppConnection.Railway]: TRailwayConnectionOption;
[AppConnection.Checkly]: TChecklyConnectionOption;
[AppConnection.Supabase]: TSupabaseConnectionOption;
[AppConnection.DigitalOcean]: TDigitalOceanConnectionOption;
[AppConnection.Okta]: TOktaConnectionOption;
};
@@ -0,0 +1,14 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
export enum DigitalOceanConnectionMethod {
ApiToken = "api-token"
}
export type TDigitalOceanConnection = TRootAppConnection & {
app: AppConnection.DigitalOcean;
method: DigitalOceanConnectionMethod.ApiToken;
credentials: {
apiToken: string;
};
};
@@ -12,6 +12,7 @@ import { TCamundaConnection } from "./camunda-connection";
import { TChecklyConnection } from "./checkly-connection";
import { TCloudflareConnection } from "./cloudflare-connection";
import { TDatabricksConnection } from "./databricks-connection";
import { TDigitalOceanConnection } from "./digital-ocean";
import { TFlyioConnection } from "./flyio-connection";
import { TGcpConnection } from "./gcp-connection";
import { TGitHubConnection } from "./github-connection";
@@ -107,6 +108,7 @@ export type TAppConnection =
| TRailwayConnection
| TChecklyConnection
| TSupabaseConnection
| TDigitalOceanConnection
| TOktaConnection;
export type TAvailableAppConnection = Pick<TAppConnection, "name" | "id">;
@@ -178,5 +180,6 @@ export type TAppConnectionMap = {
[AppConnection.Railway]: TRailwayConnection;
[AppConnection.Checkly]: TChecklyConnection;
[AppConnection.Supabase]: TSupabaseConnection;
[AppConnection.DigitalOcean]: TDigitalOceanConnection;
[AppConnection.Okta]: TOktaConnection;
};
@@ -26,6 +26,7 @@ export enum SecretSync {
Zabbix = "zabbix",
Railway = "railway",
Checkly = "checkly",
DigitalOceanAppPlatform = "digital-ocean-app-platform",
Bitbucket = "bitbucket"
}
@@ -0,0 +1,17 @@
/* eslint-disable @typescript-eslint/no-empty-object-type */
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { SecretSync } from "@app/hooks/api/secretSyncs";
import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync";
export type TDigitalOceanAppPlatformSync = TRootSecretSync & {
destination: SecretSync.DigitalOceanAppPlatform;
destinationConfig: {
appId: string;
appName: string;
};
connection: {
app: AppConnection.DigitalOcean;
name: string;
id: string;
};
};
@@ -14,6 +14,7 @@ import { TChecklySync } from "./checkly-sync";
import { TCloudflarePagesSync } from "./cloudflare-pages-sync";
import { TCloudflareWorkersSync } from "./cloudflare-workers-sync";
import { TDatabricksSync } from "./databricks-sync";
import { TDigitalOceanAppPlatformSync } from "./digital-ocean-app-platform-sync";
import { TFlyioSync } from "./flyio-sync";
import { TGcpSync } from "./gcp-sync";
import { TGitHubSync } from "./github-sync";
@@ -65,6 +66,7 @@ export type TSecretSync =
| TRailwaySync
| TChecklySync
| TSupabaseSync
| TDigitalOceanAppPlatformSync
| TBitbucketSync;
export type TListSecretSyncs = { secretSyncs: TSecretSync[] };