diff --git a/.git-hooks/commit-msg b/.git-hooks/commit-msg index 003f76b..cb3bd89 100755 --- a/.git-hooks/commit-msg +++ b/.git-hooks/commit-msg @@ -6,7 +6,7 @@ GREEN="\033[1;32m" # temporary file which holds the message). commit_message=$(cat "$1") -if (echo "$commit_message" | grep -Eq "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z0-9 \-\*]+\))?!?: .+$") then +if (echo "$commit_message" | grep -Eq "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z0-9 -\*]+\))?!?: .+$") then echo "${GREEN} ✔ Commit message meets Conventional Commit standards" exit 0 fi diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index dcd9d92..a8dbc9f 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -1,4 +1,4 @@ -import { isRelativePath, isUri, isUrl, rootFolderNotFound } from './utils' +import { isRelativePath, isUri, isUrl } from './utils' import * as NodeFormData from 'form-data' import { Job, @@ -11,7 +11,7 @@ import { JobDefinition, PollOptions } from './types' -import { JobExecutionError } from './types/errors' +import { JobExecutionError, RootFolderNotFoundError } from './types/errors' import { SessionManager } from './SessionManager' import { ContextManager } from './ContextManager' import { SasAuthResponse, MacroVar, AuthConfig } from '@sasjs/utils/types' @@ -381,7 +381,11 @@ export class SASViyaApiClient { ) const newFolderName = `${parentFolderPath.split('/').pop()}` if (newParentFolderPath === '') { - rootFolderNotFound(parentFolderPath, this.serverUrl, accessToken) + throw new RootFolderNotFoundError( + parentFolderPath, + this.serverUrl, + accessToken + ) } logger.info( `Creating parent folder:\n'${newFolderName}' in '${newParentFolderPath}'` diff --git a/src/test/utils/throwError.spec.ts b/src/test/utils/throwError.spec.ts deleted file mode 100644 index 363ebfb..0000000 --- a/src/test/utils/throwError.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { rootFolderNotFound } from '../../utils' - -describe('root folder not found', () => { - it('when access token is provided, error message should contain scope of accessToken', () => { - const token = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJzY29wZS0xIiwic2NvcGUtMiJdfQ.ktqPL2ulln-8Asa2jSV9QCfDYmQuNk4tNKopxJR5xZs' - let error - try { - rootFolderNotFound('/myProject', 'https://analytium.co.uk', token) - } catch (err) { - error = err.message - } - expect(error).toContain('scope-1') - expect(error).toContain('scope-2') - }) -}) diff --git a/src/types/errors/RootFolderNotFoundError.spec.ts b/src/types/errors/RootFolderNotFoundError.spec.ts new file mode 100644 index 0000000..a27e071 --- /dev/null +++ b/src/types/errors/RootFolderNotFoundError.spec.ts @@ -0,0 +1,40 @@ +import { RootFolderNotFoundError } from './RootFolderNotFoundError' + +describe('RootFolderNotFoundError', () => { + it('when access token is provided, error message should contain the scopes in the token', () => { + const token = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJzY29wZS0xIiwic2NvcGUtMiJdfQ.ktqPL2ulln-8Asa2jSV9QCfDYmQuNk4tNKopxJR5xZs' + + const error = new RootFolderNotFoundError( + '/myProject', + 'https://analytium.co.uk', + token + ) + + expect(error).toBeInstanceOf(RootFolderNotFoundError) + expect(error.message).toContain('scope-1') + expect(error.message).toContain('scope-2') + }) + + it('when access token is not provided, error message should not contain scopes', () => { + const error = new RootFolderNotFoundError( + '/myProject', + 'https://analytium.co.uk' + ) + + expect(error).toBeInstanceOf(RootFolderNotFoundError) + expect(error.message).not.toContain( + 'Your access token contains the following scopes' + ) + }) + + it('should include the folder path and SASDrive URL in the message', () => { + const folderPath = '/myProject' + const serverUrl = 'https://analytium.co.uk' + const error = new RootFolderNotFoundError(folderPath, serverUrl) + + expect(error).toBeInstanceOf(RootFolderNotFoundError) + expect(error.message).toContain(folderPath) + expect(error.message).toContain(`${serverUrl}/SASDrive`) + }) +}) diff --git a/src/types/errors/RootFolderNotFoundError.ts b/src/types/errors/RootFolderNotFoundError.ts new file mode 100644 index 0000000..f5f032e --- /dev/null +++ b/src/types/errors/RootFolderNotFoundError.ts @@ -0,0 +1,24 @@ +import { decodeToken } from '@sasjs/utils/auth' + +export class RootFolderNotFoundError extends Error { + constructor( + parentFolderPath: string, + serverUrl: string, + accessToken?: string + ) { + let message: string = + `Root folder ${parentFolderPath} was not found.` + + `\nPlease check ${serverUrl}/SASDrive.` + + `\nIf the folder DOES exist then it is likely a permission problem.\n` + if (accessToken) { + const decodedToken = decodeToken(accessToken) + let scope = decodedToken.scope + scope = scope.map((element) => '* ' + element) + message += + `Your access token contains the following scopes:\n` + scope.join('\n') + } + super(message) + this.name = 'RootFolderNotFoundError' + Object.setPrototypeOf(this, RootFolderNotFoundError.prototype) + } +} diff --git a/src/types/errors/index.ts b/src/types/errors/index.ts index f8595d4..cca1a97 100644 --- a/src/types/errors/index.ts +++ b/src/types/errors/index.ts @@ -7,3 +7,4 @@ export * from './LoginRequiredError' export * from './NotFoundError' export * from './ErrorResponse' export * from './NoSessionStateError' +export * from './RootFolderNotFoundError' diff --git a/src/utils/index.ts b/src/utils/index.ts index 6501f54..2a05d63 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -15,4 +15,3 @@ export * from './parseWeboutResponse' export * from './fetchLogByChunks' export * from './getValidJson' export * from './parseViyaDebugResponse' -export * from './throwError' diff --git a/src/utils/throwError.ts b/src/utils/throwError.ts deleted file mode 100644 index c054e10..0000000 --- a/src/utils/throwError.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DecodedToken, decodeToken } from '@sasjs/utils' - -export const rootFolderNotFound = ( - parentFolderPath: string, - serverUrl: string, - accessToken?: string -) => { - let error: string = `Root folder ${parentFolderPath} was not found\nPlease check ${serverUrl}/SASDrive\nIf folder DOES exist then it is likely a permission problem\n` - if (accessToken) { - const decodedToken: DecodedToken = decodeToken(accessToken) - let scope = decodedToken.scope - scope = scope.map((element) => '* ' + element) - error += - `The following scopes are contained in access token:\n` + scope.join('\n') - } - throw new Error(error) -}