From 1ec6e5e04b32b9b9642416e8ca56fcacdfa01cfc Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Mon, 19 May 2025 16:26:44 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9A=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api-v1/deployments/create-deployment.ts | 11 ++++-- .../validate-deployment-origin-adapter.ts | 38 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 apps/api/src/lib/deployments/validate-deployment-origin-adapter.ts diff --git a/apps/api/src/api-v1/deployments/create-deployment.ts b/apps/api/src/api-v1/deployments/create-deployment.ts index 20f96afc..6321325a 100644 --- a/apps/api/src/api-v1/deployments/create-deployment.ts +++ b/apps/api/src/api-v1/deployments/create-deployment.ts @@ -6,6 +6,7 @@ import { db, eq, schema } from '@/db' import { acl } from '@/lib/acl' import { publishDeployment } from '@/lib/deployments/publish-deployment' import { resolveDeploymentVersion } from '@/lib/deployments/resolve-deployment-version' +import { validateDeploymentOriginAdapter } from '@/lib/deployments/validate-deployment-origin-adapter' import { ensureAuthUser } from '@/lib/ensure-auth-user' import { openapiAuthenticatedSecuritySchemas, @@ -13,7 +14,7 @@ import { openapiErrorResponse409, openapiErrorResponses } from '@/lib/openapi-utils' -import { assert, parseZodSchema, sha256 } from '@/lib/utils' +import { assert, parseZodSchema, pick, sha256 } from '@/lib/utils' import { createDeploymentQuerySchema } from './schemas' @@ -62,8 +63,6 @@ export function registerV1DeploymentsCreateDeployment( // validatePricingPlans(ctx, pricingPlans) - // TODO: validate OpenAPI origin schema - const project = await db.query.projects.findFirst({ where: eq(schema.projects.id, projectId), with: { @@ -99,6 +98,12 @@ export function registerV1DeploymentsCreateDeployment( }) } + // Validate OpenAPI originUrl and originAdapter + await validateDeploymentOriginAdapter({ + ...pick(body, 'originUrl', 'originAdapter'), + deploymentId + }) + let [[deployment]] = await db.transaction(async (tx) => { return Promise.all([ // Create the deployment diff --git a/apps/api/src/lib/deployments/validate-deployment-origin-adapter.ts b/apps/api/src/lib/deployments/validate-deployment-origin-adapter.ts new file mode 100644 index 00000000..ffa0f20e --- /dev/null +++ b/apps/api/src/lib/deployments/validate-deployment-origin-adapter.ts @@ -0,0 +1,38 @@ +import type { DeploymentOriginAdapter } from '@/db/schema' +import { assert } from '@/lib/utils' + +export async function validateDeploymentOriginAdapter({ + deploymentId, + originUrl, + originAdapter +}: { + deploymentId: string + originUrl: string + originAdapter: DeploymentOriginAdapter +}): Promise { + assert( + originUrl, + 400, + `Origin URL is required for deployment "${deploymentId}"` + ) + + if (originAdapter.type === 'openapi') { + // TODO: Validate OpenAPI spec + assert( + originAdapter.spec, + 400, + `OpenAPI spec is required for deployment "${deploymentId}"` + ) + + // TODO: Validate OpenAPI spec version is the same as `originAdapter.version` + + // TODO: Remove origin servers from the OpenAPI spec and if they exist, ensure + // that `originUrl` matches. + } else { + assert( + originAdapter.type === 'raw', + 400, + `Invalid origin adapter type "${originAdapter.type}" for deployment "${deploymentId}"` + ) + } +}