feat(jobs): onboard getOutput method [PLT-100430]#320
feat(jobs): onboard getOutput method [PLT-100430]#320ninja-shreyash wants to merge 8 commits intomainfrom
Conversation
b808850 to
7826b36
Compare
7826b36 to
a25b635
Compare
fbb8164 to
84476d4
Compare
|
@claude review |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
Resolved all AI review comments |
|
@claude review. Dont repeat the previous comments since I have already resolved what needed to be resolved. |
This comment was marked as resolved.
This comment was marked as resolved.
|
- Add blobResponse.ok check before JSON.parse in downloadOutputFile - Wrap JSON.parse in try/catch for both inline and file output paths - Make folderId optional in JobGetOutputOptions (verified against Swagger) - Remove folderId validation block (createHeaders filters undefined) - Fix JSDoc: .data → .items, add JobState enum, fix param descriptions - Replace (job: any) with Record<string, unknown> in transform - Remove unused JOB_ENDPOINTS.GET_BY_ID constant - Integration tests: console.warn+return → throw/continue pattern - Unit tests: move vi.unstubAllGlobals() to afterEach - Add blobResponse.ok to fetch mocks, add folderId-optional test - Clarify v0/v1 init mode rule in rules.md - Fix e2e-testing.md cleanup policy precedence Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a5a48c0 to
5340053
Compare
|
| * Methods available on job response objects. | ||
| * These are bound to the job data and delegate to the service. | ||
| */ | ||
| export interface JobMethods { |
There was a problem hiding this comment.
nit : put JobMethods after all methods are defined and above createJobMethods
| * } | ||
| * ``` | ||
| */ | ||
| getOutput(options: JobGetOutputOptions): Promise<Record<string, unknown> | null>; |
There was a problem hiding this comment.
JobGetOutputOptions only contains one field which is jobKey.
jobKey itself is not an optional parameter. Shouldn't it be : getOutput(jobKey: string)
with no options?
| */ | ||
| private async fetchJobByKey( | ||
| jobKey: string | ||
| ): Promise<{ OutputArguments: string | null; OutputFile: string | null } | null> { |
There was a problem hiding this comment.
create an interface for the return type in internal-types
| * Service for interacting with UiPath Orchestrator Jobs API | ||
| */ | ||
| export class JobService extends FolderScopedService implements JobServiceModel { | ||
| private attachmentService: AttachmentService; |
There was a problem hiding this comment.
nit : add comments like this -
| try { | ||
| return JSON.parse(job.OutputArguments) as Record<string, unknown>; | ||
| } catch { | ||
| throw new ValidationError({ message: `Failed to parse job output arguments as JSON` }); |
There was a problem hiding this comment.
this isn't really a validation error. Validation errors are on user inputs.
| /** | ||
| * The unique key (GUID) of the job to retrieve output from | ||
| */ | ||
| jobKey: string; |
There was a problem hiding this comment.
if jobkey is not optional and required then it doesnt needs to be in options.
we should have getOutput(jobKey: string)
There was a problem hiding this comment.
update the skill as well
| const blobHeaders: Record<string, string> = | ||
| blobAccess.headers && 'keys' in blobAccess.headers | ||
| ? arrayDictionaryToRecord(blobAccess.headers as unknown as { keys: string[]; values: string[] }) | ||
| : (blobAccess.headers as Record<string, string>) ?? {}; |
There was a problem hiding this comment.
why is this needed here? isn't blobAccess.headers, already typed to be Record<string, string> in the attachment service?
| * | ||
| * @example | ||
| * ```typescript | ||
| * const allJobs = await jobs.getAll({ folderId: <folderId> }); |
There was a problem hiding this comment.
i cant see folderid in options
There was a problem hiding this comment.
| * @example | ||
| * ```typescript | ||
| * // Get output using bound method | ||
| * const allJobs = await jobs.getAll({ folderId: <folderId> }); |
| * const completedJob = allJobs.items.find(j => j.state === JobState.Successful); | ||
| * | ||
| * if (completedJob) { | ||
| * const output = await completedJob.getOutput(); |
There was a problem hiding this comment.
these dont get reflected in doc, instead in job getall method add this comment
|
i can see that outputarguments are coming as null in job getall call , but the outputarguments do exisit for that job, if you call get job by key.
you can reproduce the same with jobkey 4d75a122-ab90-4f6e-b64f-9e6daa610b1d for this job: can you please check this? |
| } | ||
| }); | ||
|
|
||
| it('should handle job with or without output', async () => { |
There was a problem hiding this comment.
does this test add any value over the one above?
There was a problem hiding this comment.
shouldn't there be tests/unit/models/orchestrator/jobs.test.ts to test the bound method as well.
| const rawJob = { | ||
| Id: 123, | ||
| Key: JOB_TEST_CONSTANTS.JOB_KEY, | ||
| State: 'Successful', | ||
| CreationTime: '2026-01-01T00:00:00Z', | ||
| }; |
There was a problem hiding this comment.
const rawJob = createMockRawJob(); ?
| const getOutputOptions = { | ||
| jobKey: JOB_TEST_CONSTANTS.JOB_KEY, | ||
| }; |
There was a problem hiding this comment.
Type request objects in tests.
| }); | ||
|
|
||
| // Mock getValidToken on the ApiClient | ||
| mockApiClient.getValidToken = vi.fn().mockResolvedValue(TEST_CONSTANTS.DEFAULT_ACCESS_TOKEN); |
There was a problem hiding this comment.
why is this inline and not part of setup?
Output arguments won't be returned in getAll call. That's intentional. Each job can have huge outputs and returning that in a getAll call is not performant/not needed. |




Method Added
jobs.getOutput()getOutput(options: JobGetOutputOptions): Promise<Record<string, unknown> | null>Endpoint Called
getOutput()/orchestrator_/odata/Jobs(with$filter=Key eq <jobKey>)OR.JobsorOR.Jobs.ReadgetOutput()/orchestrator_/odata/Attachments({key})(for file-based output)OR.JobsorOR.Jobs.ReadFolderScopedService— setsX-UIPATH-OrganizationUnitIdheader whenfolderIdis providedgetOutput()is a composite method: fetches job by Key filter → resolves output via inlineOutputArgumentsJSON or blob download from Attachments APIfolderIdis optional (verified against Orchestrator Swagger)Example Usage
API Response vs SDK Response
Composition flow
Internal types (not exported)
RawBlobFileAccessRawAttachmentResponseFiles
src/utils/constants/endpoints/orchestrator.tssrc/models/orchestrator/jobs.types.tssrc/models/orchestrator/jobs.internal-types.tssrc/models/orchestrator/jobs.models.tssrc/services/orchestrator/jobs/jobs.tstests/unit/services/orchestrator/jobs.test.ts(16 tests)tests/integration/shared/orchestrator/jobs.integration.test.ts(6 tests)tests/utils/constants/jobs.tsdocs/oauth-scopes.mdagent_docs/rules.md(v0/v1 rule clarification).claude/skills/sdk-verify/SKILL.md,.claude/skills/onboard-api/references/e2e-testing.md(cleanup policy fix)Refs PLT-100430
🤖 Auto-generated using onboarding skills