diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 72e9fa6..f7f2856 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -12,6 +12,7 @@ import { Context, ContextAllAttributes, Folder, + File, EditContextInput, JobDefinition, PollOptions @@ -532,6 +533,55 @@ export class SASViyaApiClient { .then((res) => res.result) } + /** + * Creates a file. Path to or URI of the parent folder is required. + * @param fileName - the name of the new file. + * @param content - the content of the new file. + * @param parentFolderPath - the full path to the parent folder. If not + * provided, the parentFolderUri must be provided. + * @param parentFolderUri - the URI (eg /folders/folders/UUID) of the parent + * folder. If not provided, the parentFolderPath must be provided. + * @param accessToken - an access token for authorizing the request. + */ + public async createFile( + fileName: string, + content: string = '', + parentFolderPath?: string, + parentFolderUri?: string, + accessToken?: string + ): Promise { + if (!parentFolderPath && !parentFolderUri) { + throw new Error('Path or URI of the parent folder is required.') + } + + if (!parentFolderUri && parentFolderPath) { + parentFolderUri = await this.getFolderUri(parentFolderPath, accessToken) + } + + const headers = { + Accept: 'application/vnd.sas.file+json', + 'Content-Disposition': `filename="${fileName}";` + } + + const mimeType = /.html$/.test(fileName) + ? 'text/html' + : /.css$/.test(fileName) + ? 'text/css' + : /.js/.test(fileName) + ? 'text/javascript' + : 'text/plain' + + return ( + await this.requestClient.post( + `/files/files?parentFolderUri=${parentFolderUri}&typeDefName=file#rawUpload`, + content, + accessToken, + mimeType, + headers + ) + ).result + } + /** * Creates a folder. Path to or URI of the parent folder is required. * @param folderName - the name of the new folder. diff --git a/src/SASjs.ts b/src/SASjs.ts index 4d9c71c..df5c515 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -299,6 +299,41 @@ export default class SASjs { ) } + /** + * Creates a file at SAS file system. + * @param fileName - name of the file to be created. + * @param content - content of the file to be created. + * @param parentFolderPath - the full path (eg `/Public/example/myFolder`) of the parent folder. + * @param parentFolderUri - the URI of the parent folder. + * @param accessToken - the access token to authorizing the request. + * @param sasApiClient - a client for interfacing with SAS API. + * @param isForced - flag that indicates if target folder already exists, it and all subfolders have to be deleted. Applicable for SAS VIYA only. + */ + public async createFile( + fileName: string, + content: string, + parentFolderPath: string, + parentFolderUri?: string, + accessToken?: string, + sasApiClient?: SASViyaApiClient + ) { + if (sasApiClient) + return await sasApiClient.createFile( + fileName, + content, + parentFolderPath, + parentFolderUri, + accessToken + ) + return await this.sasViyaApiClient!.createFile( + fileName, + content, + parentFolderPath, + parentFolderUri, + accessToken + ) + } + /** * Fetches a folder from the SAS file system. * @param folderPath - path of the folder to be fetched. @@ -867,6 +902,16 @@ export default class SASjs { isForced ) break + case 'file': + await this.createFile( + member.name, + member.code, + parentFolder, + undefined, + accessToken, + sasApiClient + ) + break case 'service': await this.createJobDefinition( member.name, diff --git a/src/types/File.ts b/src/types/File.ts new file mode 100644 index 0000000..a1afe32 --- /dev/null +++ b/src/types/File.ts @@ -0,0 +1,8 @@ +import { Link } from './Link' + +export interface File { + id: string + name: string + parentUri: string + links: Link[] +} diff --git a/src/types/index.ts b/src/types/index.ts index 36ee543..313aef2 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,6 +1,7 @@ export * from './Context' export * from './CsrfToken' export * from './Folder' +export * from './File' export * from './Job' export * from './JobDefinition' export * from './JobResult'