diff --git a/package-lock.json b/package-lock.json index e241b7f..cb95543 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "name": "@sasjs/adapter", "license": "ISC", "dependencies": { - "@sasjs/utils": "^2.25.4", + "@sasjs/utils": "^2.27.1", "axios": "^0.21.1", "axios-cookiejar-support": "^1.0.1", "form-data": "^4.0.0", @@ -1187,9 +1187,9 @@ } }, "node_modules/@sasjs/utils": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.25.4.tgz", - "integrity": "sha512-LTWExtHp4g3VcLLCUMyeeyTXEAZawSQngmJ3/2Z93ysxpeu2/NS7lGG/ERGCQb2snbqmXK8dkZmfg44Tn4Qebw==", + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.27.1.tgz", + "integrity": "sha512-CYTQwEj89cc7H3tGiQQcyDkZYaWRc1HZJpOF8o2RHYS37fIAOy0SyyJdq6mcQ74Nb1u5AmFXPFIvnRCMEcTYeQ==", "dependencies": { "@types/fs-extra": "^9.0.11", "@types/prompts": "^2.0.13", @@ -1199,7 +1199,11 @@ "fs-extra": "^10.0.0", "jwt-decode": "^3.1.2", "prompts": "^2.4.1", + "rimraf": "^3.0.2", "valid-url": "^1.0.9" + }, + "engines": { + "node": ">=15" } }, "node_modules/@semantic-release/commit-analyzer": { @@ -2157,7 +2161,6 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/base": { @@ -2259,7 +2262,6 @@ }, "node_modules/brace-expansion": { "version": "1.1.11", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2741,7 +2743,6 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, "license": "MIT" }, "node_modules/consola": { @@ -4113,7 +4114,6 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -4243,7 +4243,6 @@ }, "node_modules/glob": { "version": "7.1.7", - "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -4657,7 +4656,6 @@ }, "node_modules/inflight": { "version": "1.0.6", - "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -4666,7 +4664,6 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, "license": "ISC" }, "node_modules/ini": { @@ -7610,7 +7607,6 @@ }, "node_modules/minimatch": { "version": "3.0.4", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -11007,7 +11003,6 @@ }, "node_modules/once": { "version": "1.4.0", - "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -11242,7 +11237,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11776,7 +11770,6 @@ }, "node_modules/rimraf": { "version": "3.0.2", - "dev": true, "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -13853,7 +13846,6 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { @@ -14791,9 +14783,9 @@ } }, "@sasjs/utils": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.25.4.tgz", - "integrity": "sha512-LTWExtHp4g3VcLLCUMyeeyTXEAZawSQngmJ3/2Z93ysxpeu2/NS7lGG/ERGCQb2snbqmXK8dkZmfg44Tn4Qebw==", + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.27.1.tgz", + "integrity": "sha512-CYTQwEj89cc7H3tGiQQcyDkZYaWRc1HZJpOF8o2RHYS37fIAOy0SyyJdq6mcQ74Nb1u5AmFXPFIvnRCMEcTYeQ==", "requires": { "@types/fs-extra": "^9.0.11", "@types/prompts": "^2.0.13", @@ -14803,6 +14795,7 @@ "fs-extra": "^10.0.0", "jwt-decode": "^3.1.2", "prompts": "^2.4.1", + "rimraf": "^3.0.2", "valid-url": "^1.0.9" } }, @@ -15504,8 +15497,7 @@ } }, "balanced-match": { - "version": "1.0.2", - "dev": true + "version": "1.0.2" }, "base": { "version": "0.11.2", @@ -15570,7 +15562,6 @@ }, "brace-expansion": { "version": "1.1.11", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -15892,8 +15883,7 @@ "dev": true }, "concat-map": { - "version": "0.0.1", - "dev": true + "version": "0.0.1" }, "consola": { "version": "2.15.3" @@ -16846,8 +16836,7 @@ } }, "fs.realpath": { - "version": "1.0.0", - "dev": true + "version": "1.0.0" }, "fsevents": { "version": "2.3.2", @@ -16938,7 +16927,6 @@ }, "glob": { "version": "7.1.7", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -17186,15 +17174,13 @@ }, "inflight": { "version": "1.0.6", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { - "version": "2.0.4", - "dev": true + "version": "2.0.4" }, "ini": { "version": "1.3.8", @@ -19219,7 +19205,6 @@ }, "minimatch": { "version": "3.0.4", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -21534,7 +21519,6 @@ }, "once": { "version": "1.4.0", - "dev": true, "requires": { "wrappy": "1" } @@ -21688,8 +21672,7 @@ "dev": true }, "path-is-absolute": { - "version": "1.0.1", - "dev": true + "version": "1.0.1" }, "path-key": { "version": "3.1.1", @@ -22020,7 +22003,6 @@ }, "rimraf": { "version": "3.0.2", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -23403,8 +23385,7 @@ } }, "wrappy": { - "version": "1.0.2", - "dev": true + "version": "1.0.2" }, "write-file-atomic": { "version": "3.0.3", diff --git a/package.json b/package.json index 756785b..640e244 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ }, "main": "index.js", "dependencies": { - "@sasjs/utils": "^2.25.4", + "@sasjs/utils": "^2.27.1", "axios": "^0.21.1", "axios-cookiejar-support": "^1.0.1", "form-data": "^4.0.0", diff --git a/src/api/viya/pollJobState.ts b/src/api/viya/pollJobState.ts index 6d66244..3f033a5 100644 --- a/src/api/viya/pollJobState.ts +++ b/src/api/viya/pollJobState.ts @@ -5,7 +5,7 @@ import { RequestClient } from '../../request/RequestClient' import { JobStatePollError } from '../../types/errors' import { generateTimestamp } from '@sasjs/utils/time' import { saveLog } from './saveLog' -import { createWriteStream } from '@sasjs/utils/file' +import { createWriteStream, isFolder } from '@sasjs/utils/file' import { WriteStream } from 'fs' import { Link } from '../../types' @@ -53,12 +53,20 @@ export async function pollJobState( let logFileStream if (pollOptions?.streamLog) { - const logFileName = `${postedJob.name || 'job'}-${generateTimestamp()}.log` - const logFilePath = `${ - pollOptions?.logFolderPath || process.cwd() - }/${logFileName}` + const logPath = pollOptions?.logFolderPath || process.cwd() + const isFolderPath = await isFolder(logPath) + if (isFolderPath) { + const logFileName = `${ + postedJob.name || 'job' + }-${generateTimestamp()}.log` + const logFilePath = `${ + pollOptions?.logFolderPath || process.cwd() + }/${logFileName}` - logFileStream = await createWriteStream(logFilePath) + logFileStream = await createWriteStream(logFilePath) + } else { + logFileStream = await createWriteStream(logPath) + } } let result = await doPoll( diff --git a/src/api/viya/spec/pollJobState.spec.ts b/src/api/viya/spec/pollJobState.spec.ts index a415b98..7c82d06 100644 --- a/src/api/viya/spec/pollJobState.spec.ts +++ b/src/api/viya/spec/pollJobState.spec.ts @@ -1,4 +1,5 @@ import { Logger, LogLevel } from '@sasjs/utils' +import * as path from 'path' import * as fileModule from '@sasjs/utils/file' import { RequestClient } from '../../../request/RequestClient' import { mockAuthConfig, mockJob } from './mockResponses' @@ -85,6 +86,35 @@ describe('pollJobState', () => { expect(saveLogModule.saveLog).toHaveBeenCalledTimes(2) }) + it('should use the given log path if it points to a file', async () => { + mockSimplePoll() + + await pollJobState(requestClient, mockJob, false, mockAuthConfig, { + ...defaultPollOptions, + streamLog: true, + logFolderPath: path.join(__dirname, 'test.log') + }) + + expect(fileModule.createWriteStream).toHaveBeenCalledWith( + path.join(__dirname, 'test.log') + ) + }) + + it('should generate a log file path with a timestamp if it points to a folder', async () => { + mockSimplePoll() + + await pollJobState(requestClient, mockJob, false, mockAuthConfig, { + ...defaultPollOptions, + streamLog: true, + logFolderPath: path.join(__dirname) + }) + + expect(fileModule.createWriteStream).not.toHaveBeenCalledWith(__dirname) + expect(fileModule.createWriteStream).toHaveBeenCalledWith( + expect.stringContaining(__dirname + '/20') + ) + }) + it('should not attempt to fetch and save the log after each poll when streamLog is false', async () => { mockSimplePoll()