From 385e2f2378dcd1f251c6dc6a58c998409ad67c6c Mon Sep 17 00:00:00 2001 From: Mikhail Kuryshev Date: Thu, 2 Jul 2026 13:46:50 +0200 Subject: [PATCH] chore(sdk): TSSDK-57 remove processRunItem & processApplicationRun return responses from SAMIA as is, instead export helper functions for querying progress, status, et cetera --- .../sdk/src/entities/application-run/index.ts | 2 + .../process-application-run.spec.ts | 125 ------------------ .../process-application-run.ts | 22 --- .../sdk/src/entities/application-run/types.ts | 18 --- packages/sdk/src/entities/run-item/index.ts | 2 + .../run-item/process-run-item.spec.ts | 89 ------------- .../src/entities/run-item/process-run-item.ts | 21 --- packages/sdk/src/entities/run-item/types.ts | 16 --- packages/sdk/src/index.ts | 9 +- packages/sdk/src/platform-sdk.test.ts | 22 --- packages/sdk/src/platform-sdk.ts | 27 ++-- 11 files changed, 18 insertions(+), 335 deletions(-) create mode 100644 packages/sdk/src/entities/application-run/index.ts delete mode 100644 packages/sdk/src/entities/application-run/process-application-run.spec.ts delete mode 100644 packages/sdk/src/entities/application-run/process-application-run.ts create mode 100644 packages/sdk/src/entities/run-item/index.ts delete mode 100644 packages/sdk/src/entities/run-item/process-run-item.spec.ts delete mode 100644 packages/sdk/src/entities/run-item/process-run-item.ts diff --git a/packages/sdk/src/entities/application-run/index.ts b/packages/sdk/src/entities/application-run/index.ts new file mode 100644 index 0000000..ea3ee92 --- /dev/null +++ b/packages/sdk/src/entities/application-run/index.ts @@ -0,0 +1,2 @@ +export type { RunStatus } from './types.js'; +export { getRunProgress, getRunStatus, canDownloadRunItems } from './utils.js'; diff --git a/packages/sdk/src/entities/application-run/process-application-run.spec.ts b/packages/sdk/src/entities/application-run/process-application-run.spec.ts deleted file mode 100644 index b007ae5..0000000 --- a/packages/sdk/src/entities/application-run/process-application-run.spec.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { processApplicationRun } from './process-application-run.js'; -import type { RunReadResponse } from '../../generated/index.js'; - -function buildRun( - overrides: Partial> & { - statistics?: Partial; - } = {} -): RunReadResponse { - return { - run_id: 'run-1', - application_id: 'app-1', - version_number: '1.0.0', - state: overrides.state ?? 'PENDING', - output: overrides.output ?? 'NONE', - termination_reason: overrides.termination_reason ?? null, - error_code: null, - error_message: null, - submitted_at: '2026-01-01T00:00:00Z', - submitted_by: 'user-1', - statistics: { - item_count: 0, - item_pending_count: 0, - item_processing_count: 0, - item_user_error_count: 0, - item_system_error_count: 0, - item_skipped_count: 0, - item_succeeded_count: 0, - ...overrides.statistics, - }, - } as RunReadResponse; -} - -describe('processApplicationRun', () => { - it('should preserve all original RunReadResponse fields', () => { - const raw = buildRun({ state: 'PENDING' }); - const result = processApplicationRun(raw); - - expect(result.run_id).toBe(raw.run_id); - expect(result.application_id).toBe(raw.application_id); - expect(result.version_number).toBe(raw.version_number); - expect(result.state).toBe(raw.state); - expect(result.statistics).toEqual(raw.statistics); - }); - - it('should add progress property for a PENDING run with no items', () => { - const result = processApplicationRun(buildRun({ state: 'PENDING' })); - expect(result.progress).toBe(0); - }); - - it('should add status property for a PENDING run', () => { - const result = processApplicationRun(buildRun({ state: 'PENDING' })); - expect(result.status).toBe('PENDING'); - }); - - it('should add can_download property for a PENDING run', () => { - const result = processApplicationRun(buildRun({ state: 'PENDING' })); - expect(result.can_download).toBe(false); - }); - - it('should compute correct values for a completed run', () => { - const raw = buildRun({ - state: 'TERMINATED', - termination_reason: 'ALL_ITEMS_PROCESSED', - output: 'FULL', - statistics: { item_count: 10, item_succeeded_count: 10 }, - }); - const result = processApplicationRun(raw); - - expect(result.progress).toBe(100); - expect(result.status).toBe('COMPLETED'); - expect(result.can_download).toBe(true); - }); - - it('should compute correct values for a run completed with errors', () => { - const raw = buildRun({ - state: 'TERMINATED', - termination_reason: 'ALL_ITEMS_PROCESSED', - output: 'PARTIAL', - statistics: { - item_count: 10, - item_succeeded_count: 7, - item_user_error_count: 3, - }, - }); - const result = processApplicationRun(raw); - - expect(result.progress).toBe(100); - expect(result.status).toBe('COMPLETED_WITH_ERRORS'); - expect(result.can_download).toBe(true); - }); - - it('should compute correct values for a canceled run', () => { - const raw = buildRun({ - state: 'TERMINATED', - termination_reason: 'CANCELED_BY_USER', - statistics: { - item_count: 10, - item_succeeded_count: 3, - }, - }); - const result = processApplicationRun(raw); - - expect(result.progress).toBe(30); - expect(result.status).toBe('CANCELED'); - expect(result.can_download).toBe(false); - }); - - it('should compute correct values for a processing run', () => { - const raw = buildRun({ - state: 'PROCESSING', - statistics: { - item_count: 20, - item_succeeded_count: 8, - item_processing_count: 4, - item_pending_count: 8, - }, - }); - const result = processApplicationRun(raw); - - expect(result.progress).toBe(40); - expect(result.status).toBe('PROCESSING'); - expect(result.can_download).toBe(false); - }); -}); diff --git a/packages/sdk/src/entities/application-run/process-application-run.ts b/packages/sdk/src/entities/application-run/process-application-run.ts deleted file mode 100644 index 7397041..0000000 --- a/packages/sdk/src/entities/application-run/process-application-run.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ApplicationRun } from './types.js'; -import { RunReadResponse } from '../../generated/index.js'; -import { getRunProgress, getRunStatus, canDownloadRunItems } from './utils.js'; - -/** - * Transform a raw {@link RunReadResponse} from the API into an enriched - * {@link ApplicationRun} by computing derived properties (progress, status, can_download). - * - * This is the single entry-point used by `PlatformSDKHttp` methods to map API - * responses before returning them to consumers. - * - * @param run - Raw run response from the API - * @returns Enriched run entity with computed properties spread onto the original response - */ -export const processApplicationRun = (run: RunReadResponse): ApplicationRun => { - return { - ...run, - progress: getRunProgress(run), - status: getRunStatus(run), - can_download: canDownloadRunItems(run), - }; -}; diff --git a/packages/sdk/src/entities/application-run/types.ts b/packages/sdk/src/entities/application-run/types.ts index 52b0092..ee30e42 100644 --- a/packages/sdk/src/entities/application-run/types.ts +++ b/packages/sdk/src/entities/application-run/types.ts @@ -1,21 +1,3 @@ -import { RunReadResponse } from '../../generated/index.js'; - -/** - * Enriched application run entity that extends the raw API response - * with computed properties derived from run state and statistics. - * - * Returned by `PlatformSDKHttp.listApplicationRuns()` and `PlatformSDKHttp.getRun()` - * instead of the raw `RunReadResponse`. - */ -export interface ApplicationRun extends RunReadResponse { - /** Percentage of items processed (0–100), computed from run statistics. */ - progress: number; - /** Human-readable status derived from `state` and `termination_reason`. */ - status: RunStatus; - /** Whether the run's result items are available for download. */ - can_download: boolean; -} - /** Derived run status that simplifies the raw `state` + `termination_reason` combination. */ export type RunStatus = | 'PENDING' diff --git a/packages/sdk/src/entities/run-item/index.ts b/packages/sdk/src/entities/run-item/index.ts new file mode 100644 index 0000000..0d8faac --- /dev/null +++ b/packages/sdk/src/entities/run-item/index.ts @@ -0,0 +1,2 @@ +export { canDownloadItem, getItemStatus } from './utils.js'; +export type { ItemStatus } from './types.js'; diff --git a/packages/sdk/src/entities/run-item/process-run-item.spec.ts b/packages/sdk/src/entities/run-item/process-run-item.spec.ts deleted file mode 100644 index 6e0e09e..0000000 --- a/packages/sdk/src/entities/run-item/process-run-item.spec.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { processRunItem } from './process-run-item.js'; -import type { ItemResultReadResponse } from '../../generated/index.js'; - -function buildItem( - overrides: Partial> = {} -): ItemResultReadResponse { - return { - item_id: 'item-1', - external_id: 'slide_1', - custom_metadata: null, - state: overrides.state ?? 'PENDING', - output: 'NONE', - termination_reason: overrides.termination_reason ?? undefined, - error_code: null, - error_message: null, - input_artifacts: [], - output_artifacts: [], - } as ItemResultReadResponse; -} - -describe('processRunItem', () => { - it('should preserve all original ItemResultReadResponse fields', () => { - const raw = buildItem({ state: 'PENDING' }); - const result = processRunItem(raw); - - expect(result.item_id).toBe(raw.item_id); - expect(result.external_id).toBe(raw.external_id); - expect(result.state).toBe(raw.state); - expect(result.output_artifacts).toEqual(raw.output_artifacts); - }); - - it('should add status and can_download for a PENDING item', () => { - const result = processRunItem(buildItem({ state: 'PENDING' })); - - expect(result.status).toBe('PENDING'); - expect(result.can_download).toBe(false); - }); - - it('should add status and can_download for a PROCESSING item', () => { - const result = processRunItem(buildItem({ state: 'PROCESSING' })); - - expect(result.status).toBe('PROCESSING'); - expect(result.can_download).toBe(false); - }); - - it('should mark a successfully terminated item as COMPLETED and downloadable', () => { - const result = processRunItem( - buildItem({ state: 'TERMINATED', termination_reason: 'SUCCEEDED' }) - ); - - expect(result.status).toBe('COMPLETED'); - expect(result.can_download).toBe(true); - }); - - it('should mark a SYSTEM_ERROR terminated item as FAILED and not downloadable', () => { - const result = processRunItem( - buildItem({ state: 'TERMINATED', termination_reason: 'SYSTEM_ERROR' }) - ); - - expect(result.status).toBe('FAILED'); - expect(result.can_download).toBe(false); - }); - - it('should mark a USER_ERROR terminated item as FAILED and not downloadable', () => { - const result = processRunItem( - buildItem({ state: 'TERMINATED', termination_reason: 'USER_ERROR' }) - ); - - expect(result.status).toBe('FAILED'); - expect(result.can_download).toBe(false); - }); - - it('should mark a SKIPPED terminated item as SKIPPED and not downloadable', () => { - const result = processRunItem( - buildItem({ state: 'TERMINATED', termination_reason: 'SKIPPED' }) - ); - - expect(result.status).toBe('SKIPPED'); - expect(result.can_download).toBe(false); - }); - - it('should mark a terminated item with no termination reason as UNKNOWN and not downloadable', () => { - const result = processRunItem(buildItem({ state: 'TERMINATED' })); - - expect(result.status).toBe('UNKNOWN'); - expect(result.can_download).toBe(false); - }); -}); diff --git a/packages/sdk/src/entities/run-item/process-run-item.ts b/packages/sdk/src/entities/run-item/process-run-item.ts deleted file mode 100644 index 4017011..0000000 --- a/packages/sdk/src/entities/run-item/process-run-item.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ItemResultReadResponse } from '../../generated/index.js'; -import { ApplicationRunItem } from './types.js'; -import { canDownloadItem, getItemStatus } from './utils.js'; - -/** - * Transform a raw {@link ItemResultReadResponse} from the API into an enriched - * {@link ApplicationRunItem} by computing derived properties (status, can_download). - * - * This is the single entry-point used by `PlatformSDKHttp.listRunResults()` to - * map API responses before returning them to consumers. - * - * @param item - Raw item response from the API - * @returns Enriched item entity with computed properties spread onto the original response - */ -export const processRunItem = (item: ItemResultReadResponse): ApplicationRunItem => { - return { - ...item, - status: getItemStatus(item), - can_download: canDownloadItem(item), - }; -}; diff --git a/packages/sdk/src/entities/run-item/types.ts b/packages/sdk/src/entities/run-item/types.ts index fb60b3b..e45442f 100644 --- a/packages/sdk/src/entities/run-item/types.ts +++ b/packages/sdk/src/entities/run-item/types.ts @@ -1,18 +1,2 @@ -import { ItemResultReadResponse } from '../../generated/index.js'; - -/** - * Enriched run-item entity that extends the raw API response - * with computed properties derived from item state and termination reason. - * - * Returned by `PlatformSDKHttp.listRunResults()` instead of the raw - * `ItemResultReadResponse`. - */ -export interface ApplicationRunItem extends ItemResultReadResponse { - /** Whether the item's output artifact is available for download. */ - can_download: boolean; - /** Human-readable status derived from `state` and `termination_reason`. */ - status: string; -} - /** Derived item status that simplifies the raw `state` + `termination_reason` combination. */ export type ItemStatus = 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'SKIPPED' | 'UNKNOWN'; diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 7ea9f31..c929e16 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -6,16 +6,13 @@ export * from './generated/index.js'; // Export error classes export { BaseError, AuthenticationError, APIError, ConfigurationError } from './errors.js'; -export type { ApplicationRun } from './entities/application-run/types.js'; -export { processApplicationRun } from './entities/application-run/process-application-run.js'; export { getRunProgress, getRunStatus, canDownloadRunItems, -} from './entities/application-run/utils.js'; -export type { ApplicationRunItem, ItemStatus } from './entities/run-item/types.js'; -export { processRunItem } from './entities/run-item/process-run-item.js'; -export { canDownloadItem, getItemStatus } from './entities/run-item/utils.js'; + type RunStatus, +} from './entities/application-run/index.js'; +export { canDownloadItem, getItemStatus, type ItemStatus } from './entities/run-item/index.js'; // Export main SDK and types export { PlatformSDKHttp, diff --git a/packages/sdk/src/platform-sdk.test.ts b/packages/sdk/src/platform-sdk.test.ts index 8c8064e..56fdb2f 100644 --- a/packages/sdk/src/platform-sdk.test.ts +++ b/packages/sdk/src/platform-sdk.test.ts @@ -202,14 +202,6 @@ describe('PlatformSDK', () => { expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('run_id'); expect(result[0]).toHaveProperty('state'); - - // Enriched ApplicationRun properties - expect(result[0]).toHaveProperty('progress'); - expect(result[0]).toHaveProperty('status'); - expect(result[0]).toHaveProperty('can_download'); - expect(typeof result[0].progress).toBe('number'); - expect(typeof result[0].status).toBe('string'); - expect(typeof result[0].can_download).toBe('boolean'); }); it('should list application runs with filters successfully', async () => { @@ -247,14 +239,6 @@ describe('PlatformSDK', () => { expect(result).toHaveProperty('run_id'); expect(result).toHaveProperty('state'); expect(result).toHaveProperty('version_number'); - - // Enriched ApplicationRun properties - expect(result).toHaveProperty('progress'); - expect(result).toHaveProperty('status'); - expect(result).toHaveProperty('can_download'); - expect(typeof result.progress).toBe('number'); - expect(typeof result.status).toBe('string'); - expect(typeof result.can_download).toBe('boolean'); }); it('should handle get run failure', async () => { @@ -301,12 +285,6 @@ describe('PlatformSDK', () => { expect(result[0]).toHaveProperty('item_id'); expect(result[0]).toHaveProperty('state'); expect(result[0]).toHaveProperty('external_id'); - - // Enriched ApplicationRunItem properties - expect(result[0]).toHaveProperty('status'); - expect(result[0]).toHaveProperty('can_download'); - expect(typeof result[0].status).toBe('string'); - expect(typeof result[0].can_download).toBe('boolean'); }); it('should list run results failure', async () => { diff --git a/packages/sdk/src/platform-sdk.ts b/packages/sdk/src/platform-sdk.ts index 8606230..229a715 100644 --- a/packages/sdk/src/platform-sdk.ts +++ b/packages/sdk/src/platform-sdk.ts @@ -2,20 +2,18 @@ import packageJson from '../package.json' with { type: 'json' }; import { ApplicationReadResponse, ApplicationReadShortResponse, + ItemResultReadResponse, ItemState, ItemTerminationReason, PublicApi, RunCreationRequest, RunCreationResponse, + RunReadResponse, VersionReadResponse, } from './generated/index.js'; import { APIError, AuthenticationError, UnexpectedError } from './errors.js'; import { isAxiosError } from 'axios'; import z from 'zod'; -import { processApplicationRun } from './entities/application-run/process-application-run.js'; -import { ApplicationRun } from './entities/application-run/types.js'; -import { processRunItem } from './entities/run-item/process-run-item.js'; -import { ApplicationRunItem } from './entities/run-item/types.js'; import { downloadWithRetry } from './utils/downloadWithRetry.js'; import type { Readable } from 'node:stream'; @@ -122,9 +120,9 @@ export interface PlatformSDK { pageSize?: number; customMetadata?: string; sort?: string[]; - }): Promise; + }): Promise; createApplicationRun(request: RunCreationRequest): Promise; - getRun(applicationRunId: string): Promise; + getRun(applicationRunId: string): Promise; cancelApplicationRun(applicationRunId: string): Promise; listRunResults( applicationRunId: string, @@ -136,7 +134,7 @@ export interface PlatformSDK { state?: ItemState; terminationReason?: ItemTerminationReason; } - ): Promise; + ): Promise; getApplicationVersionDetails( applicationId: string, version: string @@ -381,7 +379,7 @@ export class PlatformSDKHttp implements PlatformSDK { sort?: string[]; page?: number; pageSize?: number; - }): Promise { + }): Promise { const client = await this.#getClient(); try { const response = await client.listRunsV1RunsGet({ @@ -393,8 +391,7 @@ export class PlatformSDKHttp implements PlatformSDK { pageSize: options?.pageSize, }); - // Enrich each raw RunReadResponse with computed properties - return response.data.map(processApplicationRun); + return response.data; } catch (error) { handleRequestError(error); } @@ -475,15 +472,14 @@ export class PlatformSDKHttp implements PlatformSDK { * } * ``` */ - async getRun(applicationRunId: string): Promise { + async getRun(applicationRunId: string): Promise { const client = await this.#getClient(); try { const response = await client.getRunV1RunsRunIdGet({ runId: applicationRunId, }); - // Enrich raw RunReadResponse with computed properties - return processApplicationRun(response.data); + return response.data; } catch (error) { handleRequestError(error); } @@ -574,7 +570,7 @@ export class PlatformSDKHttp implements PlatformSDK { state?: ItemState; terminationReason?: ItemTerminationReason; } = {} - ): Promise { + ): Promise { const client = await this.#getClient(); try { const response = await client.listRunItemsV1RunsRunIdItemsGet({ @@ -587,8 +583,7 @@ export class PlatformSDKHttp implements PlatformSDK { terminationReason, }); - // Enrich each raw ItemResultReadResponse with computed properties - return response.data.map(processRunItem); + return response.data; } catch (error) { handleRequestError(error); }