From b390872f71ef25a844149811d884c56328b3320a Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Sun, 25 May 2025 23:45:11 +0700 Subject: [PATCH] =?UTF-8?q?=E2=98=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pricing-duplicate-0/agentic.config.ts | 33 ++++++++++ .../pricing-duplicate-1/agentic.config.ts | 24 +++++++ .../invalid/pricing-empty-0/agentic.config.ts | 20 ++++++ .../invalid/pricing-empty-1/agentic.config.ts | 13 ++++ .../invalid/pricing-empty-2/agentic.config.ts | 7 ++ .../pricing-monthly-annual/agentic.config.ts | 44 +++++++++++++ .../load-agentic-config.test.ts.snap | 64 +++++++++++++++++++ .../cli/src/lib/load-agentic-config.test.ts | 10 ++- .../src/agentic-project-config-schema.ts | 8 ++- 9 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 packages/cli/fixtures/invalid/pricing-duplicate-0/agentic.config.ts create mode 100644 packages/cli/fixtures/invalid/pricing-duplicate-1/agentic.config.ts create mode 100644 packages/cli/fixtures/invalid/pricing-empty-0/agentic.config.ts create mode 100644 packages/cli/fixtures/invalid/pricing-empty-1/agentic.config.ts create mode 100644 packages/cli/fixtures/invalid/pricing-empty-2/agentic.config.ts create mode 100644 packages/cli/fixtures/pricing-monthly-annual/agentic.config.ts diff --git a/packages/cli/fixtures/invalid/pricing-duplicate-0/agentic.config.ts b/packages/cli/fixtures/invalid/pricing-duplicate-0/agentic.config.ts new file mode 100644 index 00000000..7ba21f35 --- /dev/null +++ b/packages/cli/fixtures/invalid/pricing-duplicate-0/agentic.config.ts @@ -0,0 +1,33 @@ +import { defineConfig } from '@agentic/platform-schemas' + +export default defineConfig({ + name: 'test-pricing-duplicate-0', + originUrl: 'https://httpbin.org', + pricingIntervals: ['month', 'year'], + pricingPlans: [ + { + name: 'Basic', + slug: 'basic', + interval: 'month', + lineItems: [ + { + slug: 'custom', + usageType: 'licensed', + amount: 100 + } + ] + }, + { + name: 'Basic', + slug: 'basic', // invalid duplicate slug + interval: 'year', + lineItems: [ + { + slug: 'custom', + usageType: 'licensed', + amount: 70 + } + ] + } + ] +}) diff --git a/packages/cli/fixtures/invalid/pricing-duplicate-1/agentic.config.ts b/packages/cli/fixtures/invalid/pricing-duplicate-1/agentic.config.ts new file mode 100644 index 00000000..9ce1a174 --- /dev/null +++ b/packages/cli/fixtures/invalid/pricing-duplicate-1/agentic.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from '@agentic/platform-schemas' + +export default defineConfig({ + name: 'test-pricing-duplicate-1', + originUrl: 'https://httpbin.org', + pricingPlans: [ + { + name: 'Basic', + slug: 'basic', + lineItems: [ + { + slug: 'custom', + usageType: 'licensed', + amount: 100 + }, + { + slug: 'custom', + usageType: 'licensed', + amount: 200 + } + ] + } + ] +}) diff --git a/packages/cli/fixtures/invalid/pricing-empty-0/agentic.config.ts b/packages/cli/fixtures/invalid/pricing-empty-0/agentic.config.ts new file mode 100644 index 00000000..da784f7c --- /dev/null +++ b/packages/cli/fixtures/invalid/pricing-empty-0/agentic.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from '@agentic/platform-schemas' + +export default defineConfig({ + name: 'test-pricing-empty-0', + originUrl: 'https://httpbin.org', + pricingIntervals: [] as any, // this is invalid + pricingPlans: [ + { + name: 'Basic', + slug: 'basic', + lineItems: [ + { + slug: 'base', + usageType: 'licensed', + amount: 499 // $4.99 USD + } + ] + } + ] +}) diff --git a/packages/cli/fixtures/invalid/pricing-empty-1/agentic.config.ts b/packages/cli/fixtures/invalid/pricing-empty-1/agentic.config.ts new file mode 100644 index 00000000..6670cbcf --- /dev/null +++ b/packages/cli/fixtures/invalid/pricing-empty-1/agentic.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from '@agentic/platform-schemas' + +export default defineConfig({ + name: 'test-pricing-empty-1', + originUrl: 'https://httpbin.org', + pricingPlans: [ + { + name: 'Basic', + slug: 'basic', + lineItems: [] as any // this is invalid + } + ] +}) diff --git a/packages/cli/fixtures/invalid/pricing-empty-2/agentic.config.ts b/packages/cli/fixtures/invalid/pricing-empty-2/agentic.config.ts new file mode 100644 index 00000000..b066e0c7 --- /dev/null +++ b/packages/cli/fixtures/invalid/pricing-empty-2/agentic.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from '@agentic/platform-schemas' + +export default defineConfig({ + name: 'test-pricing-empty-2', + originUrl: 'https://httpbin.org', + pricingPlans: [] as any // this is invalid +}) diff --git a/packages/cli/fixtures/pricing-monthly-annual/agentic.config.ts b/packages/cli/fixtures/pricing-monthly-annual/agentic.config.ts new file mode 100644 index 00000000..938e87ba --- /dev/null +++ b/packages/cli/fixtures/pricing-monthly-annual/agentic.config.ts @@ -0,0 +1,44 @@ +import { defineConfig } from '@agentic/platform-schemas' + +export default defineConfig({ + name: 'test-pricing-monthly-annual', + originUrl: 'https://httpbin.org', + pricingIntervals: ['month', 'year'], + pricingPlans: [ + { + name: 'Free', + slug: 'free', + lineItems: [ + { + slug: 'custom', + usageType: 'licensed', + amount: 0 + } + ] + }, + { + name: 'Basic Monthly', + slug: 'basic-monthly', + interval: 'month', + lineItems: [ + { + slug: 'custom', + usageType: 'licensed', + amount: 100 + } + ] + }, + { + name: 'Basic Annual', + slug: 'basic-annual', // invalid duplicate slug + interval: 'year', + lineItems: [ + { + slug: 'custom', + usageType: 'licensed', + amount: 70 + } + ] + } + ] +}) 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 da92d390..c7a27663 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 @@ -58,6 +58,16 @@ exports[`loadAgenticConfig > invalid: pricing-base-inconsistent 1`] = `[ZodValid 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").]`; +exports[`loadAgenticConfig > invalid: pricing-duplicate-0 1`] = `[Error: Invalid pricingPlans: duplicate PricingPlan slugs. All PricingPlan slugs must be unique (e.g. "free", "starter-monthly", "pro-annual", etc).]`; + +exports[`loadAgenticConfig > invalid: pricing-duplicate-1 1`] = `[Error: Invalid pricingPlan "basic": duplicate line-item slugs]`; + +exports[`loadAgenticConfig > invalid: pricing-empty-0 1`] = `[ZodValidationError: Validation error: Must contain at least one pricing interval at "pricingIntervals"]`; + +exports[`loadAgenticConfig > invalid: pricing-empty-1 1`] = `[ZodValidationError: Validation error: Array must contain at least 1 element(s) at "pricingPlans[0].lineItems"]`; + +exports[`loadAgenticConfig > invalid: pricing-empty-2 1`] = `[ZodValidationError: Validation error: Must contain at least one PricingPlan at "pricingPlans"]`; + exports[`loadAgenticConfig > pricing-3-plans 1`] = ` { "name": "test-pricing-3-plans", @@ -167,6 +177,60 @@ exports[`loadAgenticConfig > pricing-freemium 1`] = ` } `; +exports[`loadAgenticConfig > pricing-monthly-annual 1`] = ` +{ + "name": "test-pricing-monthly-annual", + "originAdapter": { + "location": "external", + "type": "raw", + }, + "originUrl": "https://httpbin.org", + "pricingIntervals": [ + "month", + "year", + ], + "pricingPlans": [ + { + "lineItems": [ + { + "amount": 0, + "slug": "custom", + "usageType": "licensed", + }, + ], + "name": "Free", + "slug": "free", + }, + { + "interval": "month", + "lineItems": [ + { + "amount": 100, + "interval": "month", + "slug": "custom", + "usageType": "licensed", + }, + ], + "name": "Basic Monthly", + "slug": "basic-monthly", + }, + { + "interval": "year", + "lineItems": [ + { + "amount": 70, + "interval": "year", + "slug": "custom", + "usageType": "licensed", + }, + ], + "name": "Basic Annual", + "slug": "basic-annual", + }, + ], +} +`; + exports[`loadAgenticConfig > pricing-pay-as-you-go 1`] = ` { "name": "test-pricing-pay-as-you-go", diff --git a/packages/cli/src/lib/load-agentic-config.test.ts b/packages/cli/src/lib/load-agentic-config.test.ts index d6567462..59384b3d 100644 --- a/packages/cli/src/lib/load-agentic-config.test.ts +++ b/packages/cli/src/lib/load-agentic-config.test.ts @@ -10,12 +10,18 @@ const fixtures = [ 'basic-raw-free-json', 'pricing-freemium', 'pricing-pay-as-you-go', - 'pricing-3-plans' + 'pricing-3-plans', + 'pricing-monthly-annual' ] const invalidFixtures = [ 'pricing-base-inconsistent', - 'pricing-custom-inconsistent' + 'pricing-custom-inconsistent', + 'pricing-empty-0', + 'pricing-empty-1', + 'pricing-empty-2', + 'pricing-duplicate-0', + 'pricing-duplicate-1' ] const fixturesDir = path.join( diff --git a/packages/schemas/src/agentic-project-config-schema.ts b/packages/schemas/src/agentic-project-config-schema.ts index 159d1fcd..535150f1 100644 --- a/packages/schemas/src/agentic-project-config-schema.ts +++ b/packages/schemas/src/agentic-project-config-schema.ts @@ -115,7 +115,13 @@ NOTE: Agentic currently only supports \`external\` API servers. If you'd like to * LineItems must specify their `interval` property to differentiate between * different pricing intervals. */ - pricingIntervals: z.array(pricingIntervalSchema).optional().default(['month']) + pricingIntervals: z + .array(pricingIntervalSchema) + .nonempty({ + message: 'Must contain at least one pricing interval' + }) + .optional() + .default(['month']) }) export type AgenticProjectConfigInput = z.input<