mirror of
https://github.com/sasjs/server.git
synced 2025-12-10 11:24:35 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5758bcd392 | ||
|
|
9e53470947 | ||
|
|
81f6605249 | ||
|
|
0b45402946 | ||
|
|
9ac3191891 | ||
|
|
cd00aa2af8 | ||
|
|
0147bcb701 |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -2,6 +2,22 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [0.0.38](https://github.com/sasjs/server/compare/v0.0.37...v0.0.38) (2022-03-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* quick fix for executables ([9e53470](https://github.com/sasjs/server/commit/9e53470947350f4b8d835a2cb6b70e3dabf247c4))
|
||||
|
||||
### [0.0.37](https://github.com/sasjs/server/compare/v0.0.36...v0.0.37) (2022-03-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* appStream html view ([cd00aa2](https://github.com/sasjs/server/commit/cd00aa2af8c7e0df851050a02152dfeddaec7b0f))
|
||||
* moved macros from codebase to drive ([9ac3191](https://github.com/sasjs/server/commit/9ac3191891bf53ff07135ccec6ddc83b34ea871a))
|
||||
* **webin:** closes [#99](https://github.com/sasjs/server/issues/99) ([0147bcb](https://github.com/sasjs/server/commit/0147bcb701a209266144147a3746baf1eb1ccc63))
|
||||
|
||||
### [0.0.36](https://github.com/sasjs/server/compare/v0.0.35...v0.0.36) (2022-03-21)
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import cors from 'cors'
|
||||
|
||||
import {
|
||||
connectDB,
|
||||
copySASjsCore,
|
||||
getWebBuildFolderPath,
|
||||
loadAppStreamConfig,
|
||||
sasJSCoreMacros,
|
||||
@@ -42,6 +43,8 @@ const onError: ErrorRequestHandler = (err, req, res, next) => {
|
||||
}
|
||||
|
||||
export default setProcessVariables().then(async () => {
|
||||
await copySASjsCore()
|
||||
|
||||
// loading these modules after setting up variables due to
|
||||
// multer's usage of process var process.driveLoc
|
||||
const { setupRoutes } = await import('./routes/setupRoutes')
|
||||
|
||||
@@ -13,9 +13,9 @@ import {
|
||||
extractHeaders,
|
||||
generateFileUploadSasCode,
|
||||
getTmpFilesFolderPath,
|
||||
getTmpMacrosPath,
|
||||
HTTPHeaders,
|
||||
isDebugOn,
|
||||
sasJSCoreMacros
|
||||
isDebugOn
|
||||
} from '../../utils'
|
||||
|
||||
export interface ExecutionVars {
|
||||
@@ -106,7 +106,7 @@ export class ExecutionController {
|
||||
`
|
||||
|
||||
program = `
|
||||
options insert=(SASAUTOS="${sasJSCoreMacros}");
|
||||
options insert=(SASAUTOS="${getTmpMacrosPath()}");
|
||||
|
||||
/* runtime vars */
|
||||
${varStatments}
|
||||
|
||||
@@ -11,7 +11,7 @@ const style = `<style>
|
||||
justify-content: center;
|
||||
}
|
||||
.app-container .app {
|
||||
width: 100px;
|
||||
width: 150px;
|
||||
margin: 10px;
|
||||
overflow: hidden;
|
||||
border-radius: 10px 10px 0 0;
|
||||
@@ -19,6 +19,7 @@ const style = `<style>
|
||||
}
|
||||
.app-container .app img{
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>`
|
||||
|
||||
|
||||
8
api/src/utils/copySASjsCore.ts
Normal file
8
api/src/utils/copySASjsCore.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { copy } from '@sasjs/utils'
|
||||
|
||||
import { getTmpMacrosPath, sasJSCoreMacros } from '.'
|
||||
|
||||
export const copySASjsCore = async () => {
|
||||
const macrosDrivePath = getTmpMacrosPath()
|
||||
await copy(sasJSCoreMacros, macrosDrivePath)
|
||||
}
|
||||
@@ -18,6 +18,8 @@ export const getTmpFolderPath = () => process.driveLoc
|
||||
export const getTmpAppStreamConfigPath = () =>
|
||||
path.join(getTmpFolderPath(), 'appStreamConfig.json')
|
||||
|
||||
export const getTmpMacrosPath = () => path.join(getTmpFolderPath(), 'sasjscore')
|
||||
|
||||
export const getTmpUploadsPath = () => path.join(getTmpFolderPath(), 'uploads')
|
||||
|
||||
export const getTmpFilesFolderPath = () =>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
export * from './appStreamConfig'
|
||||
export * from './connectDB'
|
||||
export * from './copySASjsCore'
|
||||
export * from './extractHeaders'
|
||||
export * from './file'
|
||||
export * from './generateAccessToken'
|
||||
export * from './generateAuthCode'
|
||||
export * from './generateRefreshToken'
|
||||
export * from './isDebugOn'
|
||||
export * from './getCertificates'
|
||||
export * from './getDesktopFields'
|
||||
export * from './isDebugOn'
|
||||
export * from './parseLogToArray'
|
||||
export * from './removeTokensInDB'
|
||||
export * from './saveTokensInDB'
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import { getTmpSessionsFolderPath } from '.'
|
||||
import { MulterFile } from '../types/Upload'
|
||||
import { listFilesInFolder } from '@sasjs/utils'
|
||||
|
||||
interface FilenameMapSingle {
|
||||
fieldName: string
|
||||
originalName: string
|
||||
}
|
||||
|
||||
interface FilenamesMap {
|
||||
[key: string]: FilenameMapSingle
|
||||
}
|
||||
|
||||
interface UploadedFiles extends FilenameMapSingle {
|
||||
fileref: string
|
||||
filepath: string
|
||||
count: number
|
||||
}
|
||||
|
||||
/**
|
||||
* It will create an object that maps hashed file names to the original names
|
||||
* @param files array of files to be mapped
|
||||
@@ -12,10 +24,13 @@ import { listFilesInFolder } from '@sasjs/utils'
|
||||
export const makeFilesNamesMap = (files: MulterFile[]) => {
|
||||
if (!files) return null
|
||||
|
||||
const filesNamesMap: { [key: string]: string } = {}
|
||||
const filesNamesMap: FilenamesMap = {}
|
||||
|
||||
for (let file of files) {
|
||||
filesNamesMap[file.filename] = file.originalname
|
||||
filesNamesMap[file.filename] = {
|
||||
fieldName: file.fieldname,
|
||||
originalName: file.originalname
|
||||
}
|
||||
}
|
||||
|
||||
return filesNamesMap
|
||||
@@ -28,17 +43,12 @@ export const makeFilesNamesMap = (files: MulterFile[]) => {
|
||||
* @returns generated sas code
|
||||
*/
|
||||
export const generateFileUploadSasCode = async (
|
||||
filesNamesMap: any,
|
||||
filesNamesMap: FilenamesMap,
|
||||
sasSessionFolder: string
|
||||
): Promise<string> => {
|
||||
let uploadSasCode = ''
|
||||
let fileCount = 0
|
||||
let uploadedFilesMap: {
|
||||
fileref: string
|
||||
filepath: string
|
||||
filename: string
|
||||
count: number
|
||||
}[] = []
|
||||
const uploadedFiles: UploadedFiles[] = []
|
||||
|
||||
const sasSessionFolderList: string[] = await listFilesInFolder(
|
||||
sasSessionFolder
|
||||
@@ -50,31 +60,32 @@ export const generateFileUploadSasCode = async (
|
||||
if (fileName.includes('req_file')) {
|
||||
fileCount++
|
||||
|
||||
uploadedFilesMap.push({
|
||||
uploadedFiles.push({
|
||||
fileref: `_sjs${fileCountString}`,
|
||||
filepath: `${sasSessionFolder}/${fileName}`,
|
||||
filename: filesNamesMap[fileName],
|
||||
originalName: filesNamesMap[fileName].originalName,
|
||||
fieldName: filesNamesMap[fileName].fieldName,
|
||||
count: fileCount
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
for (let uploadedMap of uploadedFilesMap) {
|
||||
uploadSasCode += `\nfilename ${uploadedMap.fileref} "${uploadedMap.filepath}";`
|
||||
for (const uploadedFile of uploadedFiles) {
|
||||
uploadSasCode += `\nfilename ${uploadedFile.fileref} "${uploadedFile.filepath}";`
|
||||
}
|
||||
|
||||
uploadSasCode += `\n%let _WEBIN_FILE_COUNT=${fileCount};`
|
||||
|
||||
for (let uploadedMap of uploadedFilesMap) {
|
||||
uploadSasCode += `\n%let _WEBIN_FILENAME${uploadedMap.count}=${uploadedMap.filename};`
|
||||
for (const uploadedFile of uploadedFiles) {
|
||||
uploadSasCode += `\n%let _WEBIN_FILENAME${uploadedFile.count}=${uploadedFile.originalName};`
|
||||
}
|
||||
|
||||
for (let uploadedMap of uploadedFilesMap) {
|
||||
uploadSasCode += `\n%let _WEBIN_FILEREF${uploadedMap.count}=${uploadedMap.fileref};`
|
||||
for (const uploadedFile of uploadedFiles) {
|
||||
uploadSasCode += `\n%let _WEBIN_FILEREF${uploadedFile.count}=${uploadedFile.fileref};`
|
||||
}
|
||||
|
||||
for (let uploadedMap of uploadedFilesMap) {
|
||||
uploadSasCode += `\n%let _WEBIN_NAME${uploadedMap.count}=${uploadedMap.filepath};`
|
||||
for (const uploadedFile of uploadedFiles) {
|
||||
uploadSasCode += `\n%let _WEBIN_NAME${uploadedFile.count}=${uploadedFile.fieldName};`
|
||||
}
|
||||
|
||||
if (fileCount > 0) {
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "server",
|
||||
"version": "0.0.36",
|
||||
"version": "0.0.38",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "server",
|
||||
"version": "0.0.36",
|
||||
"version": "0.0.38",
|
||||
"devDependencies": {
|
||||
"prettier": "^2.3.1",
|
||||
"standard-version": "^9.3.2"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "server",
|
||||
"version": "0.0.36",
|
||||
"version": "0.0.38",
|
||||
"description": "NodeJS wrapper for calling the SAS binary executable",
|
||||
"repository": "https://github.com/sasjs/server",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
|
||||
|
||||
### testing upload file example
|
||||
POST http://localhost:5000/SASjsApi/stp/execute/?_program=/Public/app/viya/services/editors/loadfile&table=DCCONFIG.MPE_X_TEST
|
||||
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarynkYOqevUMKZrXeAy
|
||||
|
||||
------WebKitFormBoundarynkYOqevUMKZrXeAy
|
||||
Content-Disposition: form-data; name="file"; filename="DCCONFIG.MPE_X_TEST.xlsx"
|
||||
Content-Disposition: form-data; name="fileSome11"; filename="DCCONFIG.MPE_X_TEST.xlsx"
|
||||
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
|
||||
|
||||
------WebKitFormBoundarynkYOqevUMKZrXeAy
|
||||
Content-Disposition: form-data; name="file"; filename="DCCONFIG.MPE_X_TEST.xlsx.csv"
|
||||
Content-Disposition: form-data; name="fileSome22"; filename="DCCONFIG.MPE_X_TEST.xlsx.csv"
|
||||
Content-Type: application/csv
|
||||
|
||||
_____DELETE__THIS__RECORD_____,PRIMARY_KEY_FIELD,SOME_CHAR,SOME_DROPDOWN,SOME_NUM,SOME_DATE,SOME_DATETIME,SOME_TIME,SOME_SHORTNUM,SOME_BESTNUM
|
||||
|
||||
Reference in New Issue
Block a user