diff --git a/src/toolset/api/control.ts b/src/toolset/api/control.ts index 74edded..12b9460 100644 --- a/src/toolset/api/control.ts +++ b/src/toolset/api/control.ts @@ -134,7 +134,9 @@ export class ToolControlAPI { const response = await client.listToolsetsWithOptions(input, headers || {}, runtime); - logger.debug(`API listToolsets called, Request ID: ${response.body?.requestId}`); + logger.debug( + `API listToolsets called, Request ID: ${response?.headers?.['x-acs-request-id']}` + ); if (!response.body) { throw new Error('Empty response body'); diff --git a/src/toolset/toolset.ts b/src/toolset/toolset.ts index c2bd5d1..4e506a4 100644 --- a/src/toolset/toolset.ts +++ b/src/toolset/toolset.ts @@ -7,7 +7,7 @@ import { Config } from '../utils/config'; import { logger } from '../utils/log'; -import { updateObjectProperties } from '../utils/resource'; +import { listAllResourcesFunction, updateObjectProperties } from '../utils/resource'; import { ToolSetCreateInput, @@ -50,6 +50,8 @@ export class ToolSet implements ToolSetData { return new ToolSetClient(); } + uniqIdCallback = () => this.name; + /** * Create a new ToolSet */ @@ -77,48 +79,70 @@ export class ToolSet implements ToolSetData { /** * List ToolSets */ - static async list(input?: ToolSetListInput, config?: Config): Promise { - return await ToolSet.getClient().list({ input, config }); - } - /** - * List all ToolSets with pagination - */ - static async listAll( - options?: { prefix?: string; labels?: Record }, - config?: Config - ): Promise { - const toolsets: ToolSet[] = []; - const pageSize = 50; - - // eslint-disable-next-line no-constant-condition - while (true) { - const result = await ToolSet.list( - { - prefix: options?.prefix, - labels: options?.labels, - pageSize, - }, - config - ); - - toolsets.push(...result); + static list: /** + * @deprecated + */ + | ((input?: ToolSetListInput, config?: Config) => Promise) + /** + * 枚举 ToolSet 列表 / List ToolSet list + */ + | ((params?: { input?: ToolSetListInput; config?: Config }) => Promise) = async ( + ...args: any + ): Promise => { + let input: ToolSetListInput | undefined; + let config: Config | undefined; + + if (args.length >= 1 && 'input' in args[0]) { + input = args[0].input; + } else { + input = args[0]; + } - if (result.length < pageSize) { - break; - } + if (args.length >= 1 && 'config' in args[0]) { + config = args[0].config; + } else if (args.length > 1 && args[1] instanceof Config) { + config = args[1]; } - // Deduplicate - const seen = new Set(); - return toolsets.filter(t => { - if (!t.uid || seen.has(t.uid)) { - return false; - } - seen.add(t.uid); - return true; + return await this.getClient().list({ + input: { + ...input, + } as ToolSetListInput, + config, }); - } + }; + + static listAll: /** + * @deprecated + */ + | (( + options?: { prefix?: string; labels?: Record }, + config?: Config + ) => Promise) + /** + * 枚举 ToolSet 列表 / List ToolSet list + */ + | ((params?: { input?: ToolSetListInput; config?: Config }) => Promise) = async ( + ...args: any + ) => { + let input: ToolSetListInput | undefined; + let config: Config | undefined; + + if (args.length >= 1 && 'input' in args[0]) { + input = args[0].input; + } else { + input = args[0]; + } + + if (args.length >= 1 && 'config' in args[0]) { + config = args[0].config; + } else if (args.length > 1 && args[1] instanceof Config) { + config = args[1]; + } + + return await listAllResourcesFunction(this.list as any)({ ...input, config }); + }; /** * Update a ToolSet by Name diff --git a/tests/unittests/toolset/toolset-resource.test.ts b/tests/unittests/toolset/toolset-resource.test.ts index 6527e13..ad6926f 100644 --- a/tests/unittests/toolset/toolset-resource.test.ts +++ b/tests/unittests/toolset/toolset-resource.test.ts @@ -356,8 +356,8 @@ describe('ToolSet Module', () => { describe('listAll', () => { it('should list all toolsets with pagination and deduplication', async () => { mockToolSetClient.list.mockResolvedValue([ - { name: 'toolset-1', uid: 'uid-1' }, - { name: 'toolset-2', uid: 'uid-2' }, + new ToolSet({ name: 'toolset-1', uid: 'uid-1' }), + new ToolSet({ name: 'toolset-2', uid: 'uid-2' }), ]); const result = await ToolSet.listAll(); @@ -365,21 +365,10 @@ describe('ToolSet Module', () => { expect(result.length).toBeGreaterThanOrEqual(1); }); - it('should deduplicate by uid', async () => { - mockToolSetClient.list.mockResolvedValue([ - { name: 'toolset-1', uid: 'uid-1' }, - { name: 'toolset-1-dup', uid: 'uid-1' }, // Same uid - ]); - - const result = await ToolSet.listAll(); - - expect(result).toHaveLength(1); - }); - it('should filter out items without uid', async () => { mockToolSetClient.list.mockResolvedValue([ - { name: 'toolset-1', uid: 'uid-1' }, - { name: 'toolset-no-uid' }, // No uid + new ToolSet({ name: 'toolset-1' }), + new ToolSet({ name: 'toolset-1' }), // No uid ]); const result = await ToolSet.listAll(); @@ -389,7 +378,9 @@ describe('ToolSet Module', () => { }); it('should support prefix and labels options', async () => { - mockToolSetClient.list.mockResolvedValue([{ name: 'my-toolset', uid: 'uid-1' }]); + mockToolSetClient.list.mockResolvedValue([ + new ToolSet({ name: 'my-toolset', uid: 'uid-1' }), + ]); const result = await ToolSet.listAll({ prefix: 'my-',