diff --git a/src/SASjs.ts b/src/SASjs.ts index 33f05d1..40ccb15 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -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, macroName: string) { + return new Tables(table, macroName) + } } diff --git a/src/types/Tables.spec.ts b/src/types/Tables.spec.ts new file mode 100644 index 0000000..6165e2f --- /dev/null +++ b/src/types/Tables.spec.ts @@ -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') + }) +}) diff --git a/src/types/Tables.ts b/src/types/Tables.ts new file mode 100644 index 0000000..b23e5e3 --- /dev/null +++ b/src/types/Tables.ts @@ -0,0 +1,29 @@ +import { ArgumentError } from './errors' + +export class Tables { + _tables: { [macroName: string]: Record } + + constructor(table: Record, macroName: string) { + this._tables = {} + + this.add(table, macroName) + } + + add(table: Record | 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 + } +} diff --git a/src/types/errors/ArgumentError.ts b/src/types/errors/ArgumentError.ts new file mode 100644 index 0000000..1589687 --- /dev/null +++ b/src/types/errors/ArgumentError.ts @@ -0,0 +1,7 @@ +export class ArgumentError extends Error { + constructor(public message: string) { + super(message) + this.name = 'ArgumentError' + Object.setPrototypeOf(this, ArgumentError.prototype) + } +} diff --git a/src/types/errors/index.ts b/src/types/errors/index.ts index 7bd386b..3719c7d 100644 --- a/src/types/errors/index.ts +++ b/src/types/errors/index.ts @@ -1,3 +1,4 @@ +export * from './ArgumentError' export * from './AuthorizeError' export * from './CertificateError' export * from './ComputeJobExecutionError' diff --git a/src/types/index.ts b/src/types/index.ts index a3a6978..a87cc77 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -15,3 +15,4 @@ export * from './PollOptions' export * from './WriteStream' export * from './ExecuteScript' export * from './errors' +export * from './Tables'