diff --git a/packages/cli/fixtures/pricing-monthly-annual/agentic.config.ts b/packages/cli/fixtures/pricing-monthly-annual/agentic.config.ts index 938e87ba..782a0440 100644 --- a/packages/cli/fixtures/pricing-monthly-annual/agentic.config.ts +++ b/packages/cli/fixtures/pricing-monthly-annual/agentic.config.ts @@ -30,7 +30,7 @@ export default defineConfig({ }, { name: 'Basic Annual', - slug: 'basic-annual', // invalid duplicate slug + slug: 'basic-annual', interval: 'year', lineItems: [ { diff --git a/packages/cli/src/lib/__snapshots__/load-agentic-config.test.ts.snap b/packages/cli/src/lib/__snapshots__/load-agentic-config.test.ts.snap index c7a27663..46d4f8dc 100644 --- a/packages/cli/src/lib/__snapshots__/load-agentic-config.test.ts.snap +++ b/packages/cli/src/lib/__snapshots__/load-agentic-config.test.ts.snap @@ -54,6 +54,24 @@ exports[`loadAgenticConfig > basic-raw-free-ts 1`] = ` } `; +exports[`loadAgenticConfig > invalid: invalid-name-0 1`] = `[ZodValidationError: Validation error: Invalid project name "Test Invalid Name 0". Must be lower kebab-case with no spaces between 2 and 64 characters. at "name"]`; + +exports[`loadAgenticConfig > invalid: invalid-name-1 1`] = `[ZodValidationError: Validation error: Invalid project name "Test-Invalid-Name-1". Must be lower kebab-case with no spaces between 2 and 64 characters. at "name"]`; + +exports[`loadAgenticConfig > invalid: invalid-name-2 1`] = `[ZodValidationError: Validation error: Invalid project name "test_invalid_name_2". Must be lower kebab-case with no spaces between 2 and 64 characters. at "name"]`; + +exports[`loadAgenticConfig > invalid: invalid-name-3 1`] = `[ZodValidationError: Validation error: Required at "name"]`; + +exports[`loadAgenticConfig > invalid: invalid-name-4 1`] = `[ZodValidationError: Validation error: Invalid project name "@foo/bar". Must be lower kebab-case with no spaces between 2 and 64 characters. at "name"]`; + +exports[`loadAgenticConfig > invalid: invalid-origin-url-0 1`] = `[Error: Invalid originUrl: must be a valid https URL]`; + +exports[`loadAgenticConfig > invalid: invalid-origin-url-1 1`] = `[ZodValidationError: Validation error: Invalid url at "originUrl"]`; + +exports[`loadAgenticConfig > invalid: invalid-origin-url-2 1`] = `[ZodValidationError: Validation error: Required at "originUrl"]`; + +exports[`loadAgenticConfig > invalid: invalid-origin-url-3 1`] = `[ZodValidationError: Validation error: Invalid url at "originUrl"]`; + exports[`loadAgenticConfig > invalid: pricing-base-inconsistent 1`] = `[ZodValidationError: Validation error: Invalid PricingPlanLineItem "base": reserved "base" LineItems must have "licensed" usage type. at "pricingPlans[1].lineItems[0]"]`; exports[`loadAgenticConfig > invalid: pricing-custom-inconsistent 1`] = `[Error: Invalid pricingPlans: all PricingPlans which contain the same LineItems (by slug "custom") must have the same usage type ("licensed" or "metered").]`; @@ -136,6 +154,82 @@ exports[`loadAgenticConfig > pricing-3-plans 1`] = ` } `; +exports[`loadAgenticConfig > pricing-custom-0 1`] = ` +{ + "name": "test-pricing-custom-0", + "originAdapter": { + "location": "external", + "type": "raw", + }, + "originUrl": "https://httpbin.org", + "pricingIntervals": [ + "month", + "year", + ], + "pricingPlans": [ + { + "lineItems": [ + { + "amount": 0, + "slug": "base", + "usageType": "licensed", + }, + ], + "name": "Free", + "slug": "free", + }, + { + "interval": "month", + "lineItems": [ + { + "amount": 500, + "interval": "month", + "slug": "base", + "usageType": "licensed", + }, + { + "billingScheme": "per_unit", + "interval": "month", + "rateLimit": { + "interval": 2592000, + "maxPerInterval": 1000, + }, + "slug": "custom", + "unitAmount": 100, + "usageType": "metered", + }, + ], + "name": "Basic Monthly", + "slug": "basic-monthly", + }, + { + "interval": "year", + "lineItems": [ + { + "amount": 4800, + "interval": "year", + "slug": "base", + "usageType": "licensed", + }, + { + "billingScheme": "per_unit", + "interval": "year", + "rateLimit": { + "interval": 2592000, + "maxPerInterval": 1500, + }, + "slug": "custom", + "unitAmount": 80, + "usageType": "metered", + }, + ], + "name": "Basic Annual", + "slug": "basic-annual", + }, + ], +} +`; + exports[`loadAgenticConfig > pricing-freemium 1`] = ` { "name": "test-pricing-freemium", diff --git a/packages/cli/src/lib/load-agentic-config.test.ts b/packages/cli/src/lib/load-agentic-config.test.ts index 59384b3d..cd6c9104 100644 --- a/packages/cli/src/lib/load-agentic-config.test.ts +++ b/packages/cli/src/lib/load-agentic-config.test.ts @@ -11,7 +11,8 @@ const fixtures = [ 'pricing-freemium', 'pricing-pay-as-you-go', 'pricing-3-plans', - 'pricing-monthly-annual' + 'pricing-monthly-annual', + 'pricing-custom-0' ] const invalidFixtures = [ @@ -21,7 +22,16 @@ const invalidFixtures = [ 'pricing-empty-1', 'pricing-empty-2', 'pricing-duplicate-0', - 'pricing-duplicate-1' + 'pricing-duplicate-1', + 'invalid-origin-url-0', + 'invalid-origin-url-1', + 'invalid-origin-url-2', + 'invalid-origin-url-3', + 'invalid-name-0', + 'invalid-name-1', + 'invalid-name-2', + 'invalid-name-3', + 'invalid-name-4' ] const fixturesDir = path.join( diff --git a/packages/cli/src/lib/validate-agentic-config.ts b/packages/cli/src/lib/validate-agentic-config.ts index 983d610e..5a39956a 100644 --- a/packages/cli/src/lib/validate-agentic-config.ts +++ b/packages/cli/src/lib/validate-agentic-config.ts @@ -32,6 +32,8 @@ export async function validateAgenticConfig( parsedOriginUrl.protocol === 'https:', 'Invalid originUrl: must be a valid https URL' ) + + assert(parsedOriginUrl.hostname, 'Invalid originUrl: must be a valid URL') } catch (err) { throw new Error('Invalid originUrl: must be a valid https URL', { cause: err