1
0
mirror of https://github.com/sasjs/adapter.git synced 2026-01-03 10:40:06 +00:00

Compare commits

..

4 Commits

Author SHA1 Message Date
Allan Bowe
b49010cfe5 Merge pull request #847 from sasjs/update_20250821
feat: h54s Tables() compatibility
2025-08-22 12:11:34 +01:00
Trevor Moody
fd6fad9b07 feat: h54s Tables() compatibility 2025-08-22 10:24:02 +01:00
Allan Bowe
8a10c229d6 Merge pull request #846 from sasjs/form-data-vulnerabilities
Update vulnerable form-data to v4.0.4
2025-07-23 13:38:35 +01:00
M
66462fcc50 fix: update vulnerable form-data to v4.0.4 2025-07-23 13:35:49 +02:00
8 changed files with 101 additions and 17 deletions

36
package-lock.json generated
View File

@@ -11,7 +11,7 @@
"@sasjs/utils": "3.5.2",
"axios": "1.8.2",
"axios-cookiejar-support": "5.0.5",
"form-data": "4.0.0",
"form-data": "4.0.4",
"https": "1.0.0",
"tough-cookie": "4.1.3"
},
@@ -4096,7 +4096,6 @@
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -5204,7 +5203,6 @@
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
@@ -5459,7 +5457,6 @@
},
"node_modules/es-define-property": {
"version": "1.0.1",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -5467,7 +5464,6 @@
},
"node_modules/es-errors": {
"version": "1.3.0",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -5480,7 +5476,6 @@
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@@ -5489,6 +5484,21 @@
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es6-promisify": {
"version": "7.0.0",
"dev": true,
@@ -6046,11 +6056,15 @@
}
},
"node_modules/form-data": {
"version": "4.0.0",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
@@ -6147,7 +6161,6 @@
},
"node_modules/function-bind": {
"version": "1.1.2",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -6171,7 +6184,6 @@
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -6204,7 +6216,6 @@
},
"node_modules/get-proto": {
"version": "1.0.1",
"dev": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
@@ -6343,7 +6354,6 @@
},
"node_modules/gopd": {
"version": "1.2.0",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -6404,7 +6414,6 @@
},
"node_modules/has-symbols": {
"version": "1.1.0",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -6415,7 +6424,6 @@
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
@@ -6450,7 +6458,6 @@
},
"node_modules/hasown": {
"version": "2.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
@@ -8639,7 +8646,6 @@
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"

View File

@@ -82,7 +82,7 @@
"@sasjs/utils": "3.5.2",
"axios": "1.8.2",
"axios-cookiejar-support": "5.0.5",
"form-data": "4.0.0",
"form-data": "4.0.4",
"https": "1.0.0",
"tough-cookie": "4.1.3"
}

View File

@@ -9,7 +9,8 @@ import {
ErrorResponse,
LoginOptions,
LoginResult,
ExecutionQuery
ExecutionQuery,
Tables
} from './types'
import { SASViyaApiClient } from './SASViyaApiClient'
import { SAS9ApiClient } from './SAS9ApiClient'
@@ -1240,4 +1241,15 @@ export default class SASjs {
public setVerboseMode = (verboseMode: VerboseMode) => {
this.requestClient?.setVerboseMode(verboseMode)
}
/**
* Create a tables class containing one or more tables to be sent to
* SAS.
* @param table - initial table data
* @param macroName - macro name
* @returns Tables class
*/
Tables(table: Record<string, any>, macroName: string) {
return new Tables(table, macroName)
}
}

28
src/types/Tables.spec.ts Normal file
View File

@@ -0,0 +1,28 @@
import SASjs from '../SASjs'
describe('Tables - basic coverage', () => {
const adapter = new SASjs()
it('should throw an error if first argument is not an array', () => {
expect(() => adapter.Tables({}, 'test')).toThrow('First argument')
})
it('should throw an error if second argument is not a string', () => {
// @ts-expect-error
expect(() => adapter.Tables([], 1234)).toThrow('Second argument')
})
it('should throw an error if macro name ends with a number', () => {
expect(() => adapter.Tables([], 'test1')).toThrow('number at the end')
})
it('should throw an error if no arguments are passed', () => {
// @ts-expect-error
expect(() => adapter.Tables()).toThrow('Missing arguments')
})
it('should create Tables class successfully with _tables property', () => {
const tables = adapter.Tables([], 'test')
expect(tables).toHaveProperty('_tables')
})
})

29
src/types/Tables.ts Normal file
View File

@@ -0,0 +1,29 @@
import { ArgumentError } from './errors'
export class Tables {
_tables: { [macroName: string]: Record<string, any> }
constructor(table: Record<string, any>, macroName: string) {
this._tables = {}
this.add(table, macroName)
}
add(table: Record<string, any> | null, macroName: string) {
if (table && macroName) {
if (!(table instanceof Array)) {
throw new ArgumentError('First argument must be array')
}
if (typeof macroName !== 'string') {
throw new ArgumentError('Second argument must be string')
}
if (!isNaN(Number(macroName[macroName.length - 1]))) {
throw new ArgumentError('Macro name cannot have number at the end')
}
} else {
throw new ArgumentError('Missing arguments')
}
this._tables[macroName] = table
}
}

View File

@@ -0,0 +1,7 @@
export class ArgumentError extends Error {
constructor(public message: string) {
super(message)
this.name = 'ArgumentError'
Object.setPrototypeOf(this, ArgumentError.prototype)
}
}

View File

@@ -1,3 +1,4 @@
export * from './ArgumentError'
export * from './AuthorizeError'
export * from './CertificateError'
export * from './ComputeJobExecutionError'

View File

@@ -15,3 +15,4 @@ export * from './PollOptions'
export * from './WriteStream'
export * from './ExecuteScript'
export * from './errors'
export * from './Tables'