diff --git a/package-lock.json b/package-lock.json index 8d960a8..88a521b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,29 @@ "vitest": "^4.1.5" } }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", @@ -697,7 +720,6 @@ "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~6.20.0" } @@ -748,7 +770,6 @@ "integrity": "sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.48.1", "@typescript-eslint/types": "8.48.1", @@ -1092,7 +1113,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1593,7 +1613,6 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -1837,7 +1856,6 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -2284,7 +2302,6 @@ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.14.tgz", "integrity": "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==", "license": "MIT", - "peer": true, "engines": { "node": ">=16.9.0" } @@ -3187,7 +3204,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -3816,7 +3832,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3890,7 +3905,6 @@ "integrity": "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", @@ -4159,7 +4173,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/src/handlers/list-xero-contacts.handler.ts b/src/handlers/list-xero-contacts.handler.ts index fa6821e..0020eb3 100644 --- a/src/handlers/list-xero-contacts.handler.ts +++ b/src/handlers/list-xero-contacts.handler.ts @@ -4,7 +4,7 @@ import { XeroClientResponse } from "../types/tool-response.js"; import { formatError } from "../helpers/format-error.js"; import { getClientHeaders } from "../helpers/get-client-headers.js"; -async function getContacts(page?: number, searchTerm?: string): Promise { +async function getContacts(page?: number, searchTerm?: string, pageSize?: number): Promise { await xeroClient.authenticate(); const contacts = await xeroClient.accountingApi.getContacts( @@ -17,7 +17,7 @@ async function getContacts(page?: number, searchTerm?: string): Promise > { try { - const contacts = await getContacts(page, searchTerm); + const contacts = await getContacts(page, searchTerm, pageSize); return { result: contacts, diff --git a/src/handlers/list-xero-credit-notes.handler.ts b/src/handlers/list-xero-credit-notes.handler.ts index d5d36bd..38636e0 100644 --- a/src/handlers/list-xero-credit-notes.handler.ts +++ b/src/handlers/list-xero-credit-notes.handler.ts @@ -7,6 +7,7 @@ import { getClientHeaders } from "../helpers/get-client-headers.js"; async function getCreditNotes( contactId: string | undefined, page: number, + pageSize: number = 10, ): Promise { await xeroClient.authenticate(); @@ -17,7 +18,7 @@ async function getCreditNotes( "UpdatedDateUTC DESC", // order page, // page undefined, // unitdp - 10, // pageSize + pageSize, // pageSize getClientHeaders(), ); @@ -30,9 +31,10 @@ async function getCreditNotes( export async function listXeroCreditNotes( page: number = 1, contactId?: string, + pageSize: number = 10, ): Promise> { try { - const creditNotes = await getCreditNotes(contactId, page); + const creditNotes = await getCreditNotes(contactId, page, pageSize); return { result: creditNotes, diff --git a/src/handlers/list-xero-invoices.handler.ts b/src/handlers/list-xero-invoices.handler.ts index 1eb3f26..8029a10 100644 --- a/src/handlers/list-xero-invoices.handler.ts +++ b/src/handlers/list-xero-invoices.handler.ts @@ -8,6 +8,7 @@ async function getInvoices( invoiceNumbers: string[] | undefined, contactIds: string[] | undefined, page: number, + pageSize: number = 10, ): Promise { await xeroClient.authenticate(); @@ -25,7 +26,7 @@ async function getInvoices( false, // createdByMyApp undefined, // unitdp false, // summaryOnly - 10, // pageSize + pageSize, // pageSize undefined, // searchTerm getClientHeaders(), ); @@ -39,9 +40,10 @@ export async function listXeroInvoices( page: number = 1, contactIds?: string[], invoiceNumbers?: string[], + pageSize: number = 10, ): Promise> { try { - const invoices = await getInvoices(invoiceNumbers, contactIds, page); + const invoices = await getInvoices(invoiceNumbers, contactIds, page, pageSize); return { result: invoices, diff --git a/src/handlers/list-xero-manual-journals.handler.ts b/src/handlers/list-xero-manual-journals.handler.ts index def5419..e922f53 100644 --- a/src/handlers/list-xero-manual-journals.handler.ts +++ b/src/handlers/list-xero-manual-journals.handler.ts @@ -8,6 +8,7 @@ async function getManualJournals( page: number, manualJournalId?: string, modifiedAfter?: string, + pageSize: number = 10, ): Promise { await xeroClient.authenticate(); @@ -27,7 +28,7 @@ async function getManualJournals( undefined, "UpdatedDateUTC DESC", page, - 10, // pageSize + pageSize, // pageSize getClientHeaders(), ); @@ -41,12 +42,14 @@ export async function listXeroManualJournals( page: number = 1, manualJournalId?: string, modifiedAfter?: string, + pageSize: number = 10, ): Promise> { try { const manualJournals = await getManualJournals( page, manualJournalId, modifiedAfter, + pageSize, ); return { diff --git a/src/handlers/list-xero-payments.handler.ts b/src/handlers/list-xero-payments.handler.ts index 29deee8..81a046e 100644 --- a/src/handlers/list-xero-payments.handler.ts +++ b/src/handlers/list-xero-payments.handler.ts @@ -6,6 +6,7 @@ import { getClientHeaders } from "../helpers/get-client-headers.js"; async function getPayments( page: number = 1, + pageSize: number = 10, { invoiceNumber, invoiceId, @@ -46,7 +47,7 @@ async function getPayments( where, "UpdatedDateUTC DESC", // order page, // page - 10, // pageSize + pageSize, // pageSize getClientHeaders(), // options ); @@ -69,9 +70,10 @@ export async function listXeroPayments( paymentId?: string; reference?: string; }, + pageSize: number = 10, ): Promise> { try { - const payments = await getPayments(page, { + const payments = await getPayments(page, pageSize, { invoiceNumber, invoiceId, paymentId, diff --git a/src/tools/list/list-contacts.tool.ts b/src/tools/list/list-contacts.tool.ts index 7d02275..3f9b8b9 100644 --- a/src/tools/list/list-contacts.tool.ts +++ b/src/tools/list/list-contacts.tool.ts @@ -10,10 +10,11 @@ const ListContactsTool = CreateXeroTool( If not provided, the first page will be returned. If 100 contacts are returned, \ call this tool again with the next page number."), searchTerm: z.string().optional().describe("Search parameter that performs a case-insensitive text search across the Name, FirstName, LastName, ContactNumber and EmailAddress fields"), + pageSize: z.number().min(1).max(100).default(10).optional().describe("Number of results per page (1-100, default 10)"), }, async (params) => { - const { page, searchTerm } = params; - const response = await listXeroContacts(page, searchTerm); + const { page, searchTerm, pageSize } = params; + const response = await listXeroContacts(page, searchTerm, pageSize); if (response.isError) { return { diff --git a/src/tools/list/list-credit-notes.tool.ts b/src/tools/list/list-credit-notes.tool.ts index 1eff5b1..2138abb 100644 --- a/src/tools/list/list-credit-notes.tool.ts +++ b/src/tools/list/list-credit-notes.tool.ts @@ -14,9 +14,10 @@ const ListCreditNotesTool = CreateXeroTool( { page: z.number(), contactId: z.string().optional(), + pageSize: z.number().min(1).max(100).default(10).optional().describe("Number of results per page (1-100, default 10)"), }, - async ({ page, contactId }) => { - const response = await listXeroCreditNotes(page, contactId); + async ({ page, contactId, pageSize }) => { + const response = await listXeroCreditNotes(page, contactId, pageSize); if (response.error !== null) { return { content: [ diff --git a/src/tools/list/list-invoices.tool.ts b/src/tools/list/list-invoices.tool.ts index ac400fc..7b01750 100644 --- a/src/tools/list/list-invoices.tool.ts +++ b/src/tools/list/list-invoices.tool.ts @@ -14,14 +14,15 @@ const ListInvoicesTool = CreateXeroTool( and the contact or invoice number if one was provided in the previous call.", { page: z.number(), + pageSize: z.number().min(1).max(100).default(10).optional().describe("Number of results per page (1-100, default 10)"), contactIds: z.array(z.string()).optional(), invoiceNumbers: z .array(z.string()) .optional() .describe("If provided, invoice line items will also be returned"), }, - async ({ page, contactIds, invoiceNumbers }) => { - const response = await listXeroInvoices(page, contactIds, invoiceNumbers); + async ({ page, pageSize, contactIds, invoiceNumbers }) => { + const response = await listXeroInvoices(page, contactIds, invoiceNumbers, pageSize); if (response.error !== null) { return { content: [ diff --git a/src/tools/list/list-manual-journals.tool.ts b/src/tools/list/list-manual-journals.tool.ts index 672fc0f..2a75eda 100644 --- a/src/tools/list/list-manual-journals.tool.ts +++ b/src/tools/list/list-manual-journals.tool.ts @@ -23,6 +23,7 @@ If they want the next page, call this tool again with the next page number, modi "Optional date YYYY-MM-DD to filter journals modified after this date", ), page: z.number().optional().describe("Optional page number for pagination"), + pageSize: z.number().min(1).max(100).default(10).optional().describe("Number of results per page (1-100, default 10)"), // TODO: where, order }, async (args) => { @@ -30,6 +31,7 @@ If they want the next page, call this tool again with the next page number, modi args?.page, args?.manualJournalId, args?.modifiedAfter, + args?.pageSize, ); if (response.isError) { diff --git a/src/tools/list/list-payments.tool.ts b/src/tools/list/list-payments.tool.ts index b283fd2..76f2b71 100644 --- a/src/tools/list/list-payments.tool.ts +++ b/src/tools/list/list-payments.tool.ts @@ -48,18 +48,19 @@ const ListPaymentsTool = CreateXeroTool( If many payments are returned, ask the user if they want to see the next page.`, { page: z.number().default(1), + pageSize: z.number().min(1).max(100).default(10).optional().describe("Number of results per page (1-100, default 10)"), invoiceNumber: z.string().optional(), invoiceId: z.string().optional(), paymentId: z.string().optional(), reference: z.string().optional(), }, - async ({ page, invoiceNumber, invoiceId, paymentId, reference }) => { + async ({ page, pageSize, invoiceNumber, invoiceId, paymentId, reference }) => { const response = await listXeroPayments(page, { invoiceNumber, invoiceId, paymentId, reference, - }); + }, pageSize); if (response.error !== null) { return {