From 27ef5754b3c0184838bc813e0806505590e8d452 Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Sun, 25 May 2025 23:02:13 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cli/src/lib/validate-agentic-config.ts | 21 ++++++++--- packages/schemas/package.json | 1 + .../src/agentic-project-config-schema.ts | 36 ++++++++++++++----- packages/validators/src/validators.test.ts | 3 +- packages/validators/src/validators.ts | 2 +- pnpm-lock.yaml | 3 ++ 6 files changed, 51 insertions(+), 15 deletions(-) diff --git a/packages/cli/src/lib/validate-agentic-config.ts b/packages/cli/src/lib/validate-agentic-config.ts index 26593182..690a6d23 100644 --- a/packages/cli/src/lib/validate-agentic-config.ts +++ b/packages/cli/src/lib/validate-agentic-config.ts @@ -1,5 +1,5 @@ import type { ZodTypeDef } from 'zod' -import { assert, parseZodSchema } from '@agentic/platform-core' +import { assert, HttpError, parseZodSchema } from '@agentic/platform-core' import { type AgenticProjectConfigInput, type AgenticProjectConfigOutput, @@ -16,9 +16,7 @@ export async function validateAgenticConfig( AgenticProjectConfigInput >(agenticProjectConfigSchema, inputConfig) - console.log('config', config) - - const { pricingIntervals, pricingPlans } = config + const { pricingIntervals, pricingPlans, originUrl } = config assert( pricingPlans?.length, 400, @@ -30,6 +28,21 @@ export async function validateAgenticConfig( 'Invalid pricingIntervals: must be a non-empty array' ) + try { + const parsedOriginUrl = new URL(originUrl) + assert( + parsedOriginUrl.protocol === 'https:', + 400, + 'Invalid originUrl: must be a valid https URL' + ) + } catch (err) { + throw new HttpError({ + message: 'Invalid originUrl: must be a valid https URL', + statusCode: 400, + cause: err + }) + } + { // Validate pricing interval const pricingIntervalsSet = new Set(pricingIntervals) diff --git a/packages/schemas/package.json b/packages/schemas/package.json index 8d2f69e0..6afe73a1 100644 --- a/packages/schemas/package.json +++ b/packages/schemas/package.json @@ -23,6 +23,7 @@ }, "dependencies": { "@agentic/platform-core": "workspace:*", + "@agentic/platform-validators": "workspace:*", "@hono/zod-openapi": "^0.19.6", "zod": "catalog:" }, diff --git a/packages/schemas/src/agentic-project-config-schema.ts b/packages/schemas/src/agentic-project-config-schema.ts index c168bf9b..159d1fcd 100644 --- a/packages/schemas/src/agentic-project-config-schema.ts +++ b/packages/schemas/src/agentic-project-config-schema.ts @@ -1,3 +1,4 @@ +import { validators } from '@agentic/platform-validators' import { z } from '@hono/zod-openapi' import { @@ -14,8 +15,8 @@ import { // - origin adapter openapi schema path, url, or in-place definition // - optional stripe webhooks // - optional response header config (custom headers, immutability for caching, etc) -// - optional version // - optional agentic version +// - optional version export const defaultFreePricingPlan = { name: 'Free', @@ -27,16 +28,31 @@ export const defaultFreePricingPlan = { amount: 0 } ] -} as const satisfies PricingPlan +} as const satisfies Readonly export const agenticProjectConfigSchema = z.object({ - /** Required name of the project. */ - name: z.string().describe('Name of the project.'), + /** + * Required name of the project. + * + * Must be lower kebab-case with no spaces and between 2 and 64 characters. + * + * @example "my-project" + * @example "linkedin-resolver-23" + */ + name: z + .string() + .describe('Name of the project.') + .refine( + (name) => validators.projectName(name), + (name) => ({ + message: `Invalid project name "${name}". Must be lower kebab-case with no spaces between 2 and 64 characters.` + }) + ), - /** Optional one-sentence description of the project. */ + /** Optional short description of the project. */ description: z .string() - .describe('A one-sentence description of the project.') + .describe('A short description of the project.') .optional(), /** Optional readme documenting the project (supports GitHub-flavored markdown). */ @@ -47,14 +63,16 @@ export const agenticProjectConfigSchema = z.object({ ) .optional(), - /** Optional URL to the source code for the project. */ + /** Optional URL to the source code of the project. */ sourceUrl: z .string() .url() .optional() - .describe('Optional URL to the source code for the project.'), + .describe('Optional URL to the source code of the project.'), - /** Optional logo image URL to use for the project. Logos should have a square aspect ratio. */ + /** + * Optional logo image URL to use for the project. Logos should have a square aspect ratio. + */ iconUrl: z .string() .url() diff --git a/packages/validators/src/validators.test.ts b/packages/validators/src/validators.test.ts index 36372ba4..c940087b 100644 --- a/packages/validators/src/validators.test.ts +++ b/packages/validators/src/validators.test.ts @@ -43,13 +43,14 @@ test('password failure', () => { }) test('projectName success', () => { + expect(validators.projectName('ai')).toBe(true) expect(validators.projectName('aaa')).toBe(true) expect(validators.projectName('hello-world')).toBe(true) expect(validators.projectName('123-abc')).toBe(true) }) test('projectName failure', () => { - expect(validators.projectName('aa')).toBe(false) + expect(validators.projectName('a')).toBe(false) expect(validators.projectName('hello_world')).toBe(false) expect(validators.projectName('a_bc')).toBe(false) expect(validators.projectName('abc.')) diff --git a/packages/validators/src/validators.ts b/packages/validators/src/validators.ts index c53c5203..d3f67e79 100644 --- a/packages/validators/src/validators.ts +++ b/packages/validators/src/validators.ts @@ -5,7 +5,7 @@ import isRelativeUrl from 'is-relative-url' export const usernameRe = /^[a-zA-Z0-9-]{1,64}$/ export const passwordRe = /^.{3,1024}$/ -export const projectNameRe = /^[a-z0-9-]{3,64}$/ +export const projectNameRe = /^[a-z0-9-]{2,64}$/ export const deploymentHashRe = /^[a-z0-9]{8}$/ export const projectRe = /^[a-zA-Z0-9-]{1,64}\/[a-z0-9-]{3,64}$/ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b9b0acb7..a06ef9fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -325,6 +325,9 @@ importers: '@agentic/platform-core': specifier: workspace:* version: link:../core + '@agentic/platform-validators': + specifier: workspace:* + version: link:../validators '@hono/zod-openapi': specifier: ^0.19.6 version: 0.19.6(hono@4.7.9)(zod@3.24.4)