Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,146 @@
import {createToolsTypeDefinition} from './type-generation.js'
import {createIntentsTypeDefinition, createToolsTypeDefinition} from './type-generation.js'
import {AbortError} from '@shopify/cli-kit/node/error'
import {describe, expect, test} from 'vitest'

describe('createIntentsTypeDefinition', () => {
test('returns empty string when intents array is empty', async () => {
// When
const result = await createIntentsTypeDefinition([])

// Then
expect(result).toBe('')
})

test('generates request and response types for a single intent schema', async () => {
// Given
const intents = [
{
action: 'create',
type: 'application/email',
inputSchema: {
type: 'object',
properties: {
recipient: {type: 'string'},
},
required: ['recipient'],
},
outputSchema: {
type: 'object',
properties: {
success: {type: 'boolean'},
},
},
},
]

// When
const result = await createIntentsTypeDefinition(intents)

// Then
expect(result).toBe(`interface CreateApplicationEmailIntentInput {
recipient: string;
[k: string]: unknown;
}

type CreateApplicationEmailIntentValue = unknown
interface CreateApplicationEmailIntentOutput {
success?: boolean;
[k: string]: unknown;
}

interface CreateApplicationEmailIntentRequest {
action: "create";
type: "application/email";
data: CreateApplicationEmailIntentInput;
value?: CreateApplicationEmailIntentValue;
}

interface ShopifyGeneratedIntentResponse<Data = unknown> {
ok(data?: Data): Promise<void>;
}

interface ShopifyGeneratedIntentsApi<Request = unknown, ResponseData = unknown> {
request: Request;
response?: ShopifyGeneratedIntentResponse<ResponseData>;
}

type ShopifyGeneratedIntentVariants =
| ShopifyGeneratedIntentsApi<CreateApplicationEmailIntentRequest, CreateApplicationEmailIntentOutput>
`)
})

test('supports multiple intents with value schemas', async () => {
// Given
const intents = [
{
action: 'create',
type: 'application/email',
inputSchema: {
type: 'object',
properties: {
recipient: {type: 'string'},
},
},
},
{
action: 'edit',
type: 'shopify/Product',
valueSchema: {
type: 'string',
},
inputSchema: {
type: 'object',
properties: {
title: {type: 'string'},
},
},
outputSchema: {
type: 'object',
properties: {
id: {type: 'string'},
},
},
},
]

// When
const result = await createIntentsTypeDefinition(intents)

// Then
expect(result).toContain('interface CreateApplicationEmailIntentRequest')
expect(result).toContain('type CreateApplicationEmailIntentOutput = unknown')
expect(result).toContain('interface EditShopifyProductIntentRequest')
expect(result).toContain('type EditShopifyProductIntentValue = string')
expect(result).toContain('response?: ShopifyGeneratedIntentResponse<ResponseData>;')
expect(result).toContain(
'ShopifyGeneratedIntentsApi<EditShopifyProductIntentRequest, EditShopifyProductIntentOutput>',
)
})

test('throws AbortError when intent action/type pairs are duplicated', async () => {
// Given
const intents = [
{
action: 'create',
type: 'application/email',
inputSchema: {type: 'object'},
},
{
action: 'create',
type: 'application/email',
inputSchema: {type: 'object'},
},
]

// When & Then
await expect(createIntentsTypeDefinition(intents)).rejects.toThrow(
new AbortError(
'Intent "create:application/email" is defined multiple times. Intents must be unique within a target.',
),
)
})
})

describe('createToolsTypeDefinition', () => {
test('returns empty string when tools array is empty', async () => {
// When
Expand Down
Loading
Loading