Skip to content
Draft
45 changes: 44 additions & 1 deletion packages/app/src/cli/models/extensions/schemas.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {BaseSchema, MAX_UID_LENGTH} from './schemas.js'
import {BaseSchema, MAX_UID_LENGTH, NewExtensionPointsSchema} from './schemas.js'
import {describe, expect, test} from 'vitest'

const validUIDTestCases = [
Expand Down Expand Up @@ -29,6 +29,49 @@ const invalidUIDTestCases = [
['-----', "UID can't start or end with a hyphen"],
]

describe('NewExtensionPointsSchema', () => {
const extensionPoint = {
target: 'pos.app.ready.data',
module: './src/index.ts',
}

test('accepts free-form intercept event names for Core to validate', () => {
const result = NewExtensionPointsSchema.safeParse([
{
...extensionPoint,
capabilities: {intercepts: ['beforecheckout', 'future:event']},
},
])

expect(result.success).toBe(true)
})

test('rejects non-string intercept event names', () => {
const result = NewExtensionPointsSchema.safeParse([
{
...extensionPoint,
capabilities: {intercepts: ['beforecheckout', 1]},
},
])

expect(result.success).toBe(false)
})

test('rejects duplicate intercept event names', () => {
const result = NewExtensionPointsSchema.safeParse([
{
...extensionPoint,
capabilities: {intercepts: ['beforecheckout', 'beforecheckout']},
},
])

expect(result.success).toBe(false)
if (!result.success) {
expect(result.error.issues[0]?.message).toBe('Intercept events must be unique: beforecheckout')
}
})
})

describe('UIDSchema', () => {
describe('valid UIDs', () => {
test.each(validUIDTestCases)('accepts %s (%s)', (uid) => {
Expand Down
11 changes: 11 additions & 0 deletions packages/app/src/cli/models/extensions/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,19 @@ export const ExtensionsArraySchema = zod.object({
extensions: zod.array(zod.any()).optional(),
})

const InterceptEventsSchema = zod.array(zod.string()).superRefine((events, context) => {
const duplicates = [...new Set(events.filter((event, index) => events.indexOf(event) !== index))]
if (duplicates.length > 0) {
context.addIssue({
code: zod.ZodIssueCode.custom,
message: `Intercept events must be unique: ${duplicates.join(', ')}`,
})
}
})

const TargetCapabilitiesSchema = zod.object({
allow_direct_linking: zod.boolean().optional(),
intercepts: InterceptEventsSchema.optional(),
})

const ShouldRenderSchema = zod.object({
Expand Down
Loading