From 4cae9b54724a042c36ab796d0914d16bdd822434 Mon Sep 17 00:00:00 2001 From: mulahasanovic Date: Wed, 13 May 2026 14:09:47 +0200 Subject: [PATCH] feat(debug): add viya debug log parser - parse JSON from inline blob --- src/job-execution/WebJobExecutor.ts | 14 ++++--- src/utils/index.ts | 1 + src/utils/parseViyaLogDebugResponse.ts | 18 ++++++++ .../spec/parseViyaLogDebugResponse.spec.ts | 41 +++++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 src/utils/parseViyaLogDebugResponse.ts create mode 100644 src/utils/spec/parseViyaLogDebugResponse.spec.ts diff --git a/src/job-execution/WebJobExecutor.ts b/src/job-execution/WebJobExecutor.ts index 5ce8da0..d4e8f25 100644 --- a/src/job-execution/WebJobExecutor.ts +++ b/src/job-execution/WebJobExecutor.ts @@ -16,6 +16,7 @@ import { SASViyaApiClient } from '../SASViyaApiClient' import { isRelativePath, parseSasViyaDebugResponse, + parseSasViyaLogDebugResponse, appendExtraResponseAttributes, parseWeboutResponse, getFormData, @@ -188,11 +189,14 @@ export class WebJobExecutor extends BaseJobExecutor { if (config.debug) { switch (this.serverType) { case ServerType.SasViya: - jsonResponse = await parseSasViyaDebugResponse( - res.result, - this.requestClient, - this.serverUrl - ) + jsonResponse = + config.useComputeApi === null && config.runAsTask === true + ? await parseSasViyaLogDebugResponse(res.result) + : await parseSasViyaDebugResponse( + res.result, + this.requestClient, + this.serverUrl + ) break case ServerType.Sas9: jsonResponse = diff --git a/src/utils/index.ts b/src/utils/index.ts index 2a2b405..ac11428 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -15,6 +15,7 @@ export * from './parseGeneratedCode' export * from './parseSasViyaLog' export * from './parseSourceCode' export * from './parseViyaDebugResponse' +export * from './parseViyaLogDebugResponse' export * from './parseWeboutResponse' export * from './serialize' export * from './splitChunks' diff --git a/src/utils/parseViyaLogDebugResponse.ts b/src/utils/parseViyaLogDebugResponse.ts new file mode 100644 index 0000000..96bfc7f --- /dev/null +++ b/src/utils/parseViyaLogDebugResponse.ts @@ -0,0 +1,18 @@ +import { getValidJson } from './getValidJson' + +/** + * When querying a Viya job using the Web approach with _DEBUG=log (used when + * runAsTask is true), the webout JSON is inlined into the response via: + * var blob = new Blob([`{...}`], {type: 'application/json'}); + * No follow-up request is needed — extract and parse the JSON directly. + */ +export const parseSasViyaLogDebugResponse = async (response: string) => { + const blobMatch = response.match( + /new Blob\(\[`([\s\S]*?)`\],\s*\{type:\s*'application\/json'\}\)/ + ) + if (!blobMatch) { + throw new Error('Unable to find webout blob in debug log response.') + } + + return getValidJson(blobMatch[1]) +} diff --git a/src/utils/spec/parseViyaLogDebugResponse.spec.ts b/src/utils/spec/parseViyaLogDebugResponse.spec.ts new file mode 100644 index 0000000..08c5c56 --- /dev/null +++ b/src/utils/spec/parseViyaLogDebugResponse.spec.ts @@ -0,0 +1,41 @@ +import { parseSasViyaLogDebugResponse } from '../parseViyaLogDebugResponse' + +describe('parseSasViyaLogDebugResponse', () => { + it('should extract and parse JSON from inline Blob', async () => { + const resultData = { message: 'success' } + const response = `` + + const result = await parseSasViyaLogDebugResponse(response) + + expect(result).toEqual(resultData) + }) + + it('should extract and parse multiline JSON from inline Blob', async () => { + const resultData = { + SYSDATE: '13MAY26', + SYSCC: '0', + saslibs: [{ LIBRARYREF: 'FORMATS' }] + } + const response = `` + + const result = await parseSasViyaLogDebugResponse(response) + + expect(result).toEqual(resultData) + }) + + it('should throw an error if blob is not found', async () => { + const response = `No blob here` + + await expect(parseSasViyaLogDebugResponse(response)).rejects.toThrow( + 'Unable to find webout blob in debug log response.' + ) + }) +})