Skip to content
Merged
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
30 changes: 30 additions & 0 deletions src/utils/toolProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ export class ToolPropertyBuilder implements McpToolProperty {
return this;
}

/**
* Set the property type to double
*/
double(): ToolPropertyBuilder {
this.property.propertyType = 'number';
return this;
}

/**
* Set the property type to long
*/
long(): ToolPropertyBuilder {
this.property.propertyType = 'number';
return this;
}

/**
* Set the property type to number
*/
Expand Down Expand Up @@ -165,6 +181,20 @@ export const arg = {
return new ToolPropertyBuilder().number();
},

/**
* Start building a long property
*/
long(): ToolPropertyBuilder {
return new ToolPropertyBuilder().long();
},

/**
* Start building a double property
*/
double(): ToolPropertyBuilder {
return new ToolPropertyBuilder().double();
},

/**
* Start building a boolean property
*/
Expand Down
83 changes: 81 additions & 2 deletions test/converters/toMcpToolTriggerOptionsToRpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ describe('converToMcpToolTriggerOptionsToRpc', () => {
booleanProp: arg.boolean().describe('A boolean property'),
objectProp: arg.object().describe('An object property').optional(),
integerProp: arg.integer().describe('An integer property'),
longProp: arg.long().describe('A long property'),
doubleProp: arg.double().describe('A double property').optional(),
};

const input: McpToolTriggerOptions = {
Expand All @@ -135,13 +137,26 @@ describe('converToMcpToolTriggerOptionsToRpc', () => {
expect(() => JSON.parse(result.toolProperties || '')).to.not.throw();

const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[];
expect(parsedProperties).to.have.length(5);
expect(parsedProperties).to.have.length(7);

// Verify long and double properties are correctly converted
const longProp = parsedProperties.find((p) => p.propertyName === 'longProp');
expect(longProp?.propertyType).to.equal('number');
expect(longProp?.description).to.equal('A long property');
expect(longProp?.isRequired).to.equal(true);

const doubleProp = parsedProperties.find((p) => p.propertyName === 'doubleProp');
expect(doubleProp?.propertyType).to.equal('number');
expect(doubleProp?.description).to.equal('A double property');
expect(doubleProp?.isRequired).to.equal(false);
});

it('should handle array properties correctly', () => {
const toolProperties: Args = {
stringArray: arg.string().describe('A string array').asArray().optional(),
numberArray: arg.number().describe('A number array').asArray(),
longArray: arg.long().describe('A long array').asArray(),
doubleArray: arg.double().describe('A double array').asArray().optional(),
};

const input: McpToolTriggerOptions = {
Expand All @@ -156,7 +171,71 @@ describe('converToMcpToolTriggerOptionsToRpc', () => {
expect(() => JSON.parse(result.toolProperties || '')).to.not.throw();

const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[];
expect(parsedProperties).to.have.length(2);
expect(parsedProperties).to.have.length(4);

// Verify long and double array properties
const longArray = parsedProperties.find((p) => p.propertyName === 'longArray');
expect(longArray?.propertyType).to.equal('number');
expect(longArray?.isArray).to.equal(true);
expect(longArray?.isRequired).to.equal(true);

const doubleArray = parsedProperties.find((p) => p.propertyName === 'doubleArray');
expect(doubleArray?.propertyType).to.equal('number');
expect(doubleArray?.isArray).to.equal(true);
expect(doubleArray?.isRequired).to.equal(false);
});

it('should handle long and double property types specifically', () => {
const toolProperties: Args = {
longValue: arg.long().describe('A long integer value'),
doubleValue: arg.double().describe('A double precision value').optional(),
longArrayValue: arg.long().asArray().describe('Array of long values'),
doubleArrayValue: arg.double().asArray().describe('Array of double values').optional(),
};

const input: McpToolTriggerOptions = {
toolName: 'long-double-tool',
description: 'A tool testing long and double types',
toolProperties: toolProperties,
};

const result = converToMcpToolTriggerOptionsToRpc(input);

expect(result.toolProperties).to.be.a('string');
expect(() => JSON.parse(result.toolProperties || '')).to.not.throw();

const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[];
expect(parsedProperties).to.have.length(4);

// Test individual long property
const longProp = parsedProperties.find((p) => p.propertyName === 'longValue');
expect(longProp).to.not.be.undefined;
expect(longProp?.propertyType).to.equal('number');
expect(longProp?.description).to.equal('A long integer value');
expect(longProp?.isRequired).to.equal(true);
expect(longProp?.isArray).to.equal(false);

// Test individual double property
const doubleProp = parsedProperties.find((p) => p.propertyName === 'doubleValue');
expect(doubleProp).to.not.be.undefined;
expect(doubleProp?.propertyType).to.equal('number');
expect(doubleProp?.description).to.equal('A double precision value');
expect(doubleProp?.isRequired).to.equal(false);
expect(doubleProp?.isArray).to.equal(false);

// Test long array property
const longArrayProp = parsedProperties.find((p) => p.propertyName === 'longArrayValue');
expect(longArrayProp).to.not.be.undefined;
expect(longArrayProp?.propertyType).to.equal('number');
expect(longArrayProp?.isArray).to.equal(true);
expect(longArrayProp?.isRequired).to.equal(true);

// Test double array property
const doubleArrayProp = parsedProperties.find((p) => p.propertyName === 'doubleArrayValue');
expect(doubleArrayProp).to.not.be.undefined;
expect(doubleArrayProp?.propertyType).to.equal('number');
expect(doubleArrayProp?.isArray).to.equal(true);
expect(doubleArrayProp?.isRequired).to.equal(false);
});
});

Expand Down
59 changes: 59 additions & 0 deletions test/toolArrayProperties.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,16 @@ describe('isArray property support', () => {
const booleanArray = arg.boolean().asArray().describe('Boolean array');
const objectArray = arg.object().asArray().describe('Object array');
const integerArray = arg.integer().asArray().describe('Integer array');
const longArray = arg.long().asArray().describe('Long array');
const doubleArray = arg.double().asArray().describe('Double array');

expect(stringArray.isArray).to.equal(true);
expect(numberArray.isArray).to.equal(true);
expect(booleanArray.isArray).to.equal(true);
expect(objectArray.isArray).to.equal(true);
expect(integerArray.isArray).to.equal(true);
expect(longArray.isArray).to.equal(true);
expect(doubleArray.isArray).to.equal(true);
});

it('supports seamless property access after desc()', () => {
Expand Down Expand Up @@ -115,4 +119,59 @@ describe('isArray property support', () => {
const builder = arg.string();
expect(builder.description).to.equal(''); // Should default to empty string
});

it('long and double property types work correctly', () => {
const longProp = arg.long().describe('A long number property');
const doubleProp = arg.double().describe('A double precision property').optional();

// Test long property
expect(longProp.propertyType).to.equal('number');
expect(longProp.description).to.equal('A long number property');
expect(longProp.isRequired).to.equal(true);
expect(longProp.isArray).to.equal(false);

// Test double property
expect(doubleProp.propertyType).to.equal('number');
expect(doubleProp.description).to.equal('A double precision property');
expect(doubleProp.isRequired).to.equal(false);
expect(doubleProp.isArray).to.equal(false);
});

it('long and double properties work with convertToolProperties', () => {
const toolProps = {
longValue: arg.long().describe('Long integer value'),
doubleValue: arg.double().describe('Double precision value').optional(),
longArray: arg.long().asArray().describe('Array of long values'),
doubleArray: arg.double().asArray().describe('Array of double values').optional(),
};

const converted = convertToolProperties(toolProps);

expect(converted).to.have.lengthOf(4);

// Test long property
const longProp = converted.find((p) => p.propertyName === 'longValue');
expect(longProp?.propertyType).to.equal('number');
expect(longProp?.description).to.equal('Long integer value');
expect(longProp?.isRequired).to.equal(true);
expect(longProp?.isArray).to.equal(false);

// Test double property
const doubleProp = converted.find((p) => p.propertyName === 'doubleValue');
expect(doubleProp?.propertyType).to.equal('number');
expect(doubleProp?.description).to.equal('Double precision value');
expect(doubleProp?.isRequired).to.equal(false);
expect(doubleProp?.isArray).to.equal(false);

// Test long array
const longArrayProp = converted.find((p) => p.propertyName === 'longArray');
expect(longArrayProp?.propertyType).to.equal('number');
expect(longArrayProp?.isArray).to.equal(true);

// Test double array
const doubleArrayProp = converted.find((p) => p.propertyName === 'doubleArray');
expect(doubleArrayProp?.propertyType).to.equal('number');
expect(doubleArrayProp?.isArray).to.equal(true);
expect(doubleArrayProp?.isRequired).to.equal(false);
});
});
Loading