@things-factory/integration-sftp 4.3.660 → 4.3.668
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +369 -0
- package/dist-server/controllers/herbalife/herbalife.js +9 -5
- package/dist-server/controllers/herbalife/herbalife.js.map +1 -1
- package/dist-server/controllers/index.js +1 -0
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/controllers/sftp-api/index.js +7 -0
- package/dist-server/controllers/sftp-api/index.js.map +1 -1
- package/dist-server/controllers/yltc/apis/create-yltc-inventory-report.js +40 -0
- package/dist-server/controllers/yltc/apis/create-yltc-inventory-report.js.map +1 -0
- package/dist-server/controllers/yltc/apis/echo.js +19 -0
- package/dist-server/controllers/yltc/apis/echo.js.map +1 -0
- package/dist-server/controllers/yltc/apis/index.js +19 -0
- package/dist-server/controllers/yltc/apis/index.js.map +1 -0
- package/dist-server/controllers/yltc/index.js +34 -0
- package/dist-server/controllers/yltc/index.js.map +1 -0
- package/dist-server/controllers/yltc/platform-action.js +30 -0
- package/dist-server/controllers/yltc/platform-action.js.map +1 -0
- package/dist-server/controllers/yltc/yltc.js +71 -0
- package/dist-server/controllers/yltc/yltc.js.map +1 -0
- package/dist-server/service/sftp/sftp-mutation.js +15 -8
- package/dist-server/service/sftp/sftp-mutation.js.map +1 -1
- package/dist-server/service/sftp/sftp.js +41 -0
- package/dist-server/service/sftp/sftp.js.map +1 -1
- package/dist-server/sftp-const.js +36 -2
- package/dist-server/sftp-const.js.map +1 -1
- package/dist-server/storage/providers/ftp-storage.provider.js +178 -0
- package/dist-server/storage/providers/ftp-storage.provider.js.map +1 -0
- package/dist-server/storage/providers/local-storage.provider.js +153 -0
- package/dist-server/storage/providers/local-storage.provider.js.map +1 -0
- package/dist-server/storage/providers/s3-storage.provider.js +181 -0
- package/dist-server/storage/providers/s3-storage.provider.js.map +1 -0
- package/dist-server/storage/providers/sftp-storage.provider.js +133 -0
- package/dist-server/storage/providers/sftp-storage.provider.js.map +1 -0
- package/dist-server/storage/storage-factory.js +55 -0
- package/dist-server/storage/storage-factory.js.map +1 -0
- package/dist-server/storage/storage-manager.js +86 -0
- package/dist-server/storage/storage-manager.js.map +1 -0
- package/dist-server/storage/storage-provider.interface.js +3 -0
- package/dist-server/storage/storage-provider.interface.js.map +1 -0
- package/dist-server/util/file-formatters.js +100 -0
- package/dist-server/util/file-formatters.js.map +1 -0
- package/dist-server/util/generate-files.js +77 -17
- package/dist-server/util/generate-files.js.map +1 -1
- package/dist-server/util/get-permitted-directories.js +9 -5
- package/dist-server/util/get-permitted-directories.js.map +1 -1
- package/package.json +6 -3
- package/server/controllers/herbalife/herbalife.ts +11 -6
- package/server/controllers/index.ts +1 -0
- package/server/controllers/sftp-api/index.ts +3 -0
- package/server/controllers/yltc/apis/create-yltc-inventory-report.ts +37 -0
- package/server/controllers/yltc/apis/echo.ts +14 -0
- package/server/controllers/yltc/apis/index.ts +2 -0
- package/server/controllers/yltc/index.ts +7 -0
- package/server/controllers/yltc/platform-action.ts +34 -0
- package/server/controllers/yltc/yltc.ts +93 -0
- package/server/service/sftp/sftp-mutation.ts +16 -10
- package/server/service/sftp/sftp.ts +34 -0
- package/server/sftp-const.ts +41 -1
- package/server/storage/providers/ftp-storage.provider.ts +177 -0
- package/server/storage/providers/local-storage.provider.ts +159 -0
- package/server/storage/providers/s3-storage.provider.ts +214 -0
- package/server/storage/providers/sftp-storage.provider.ts +157 -0
- package/server/storage/storage-factory.ts +62 -0
- package/server/storage/storage-manager.ts +103 -0
- package/server/storage/storage-provider.interface.ts +42 -0
- package/server/util/file-formatters.ts +97 -0
- package/server/util/generate-files.ts +79 -17
- package/server/util/get-permitted-directories.ts +11 -7
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseCSV = exports.formatData = exports.formatAsXML = exports.formatAsCSV = void 0;
|
|
4
|
+
const xml_js_1 = require("xml-js");
|
|
5
|
+
function formatDateYMD(date) {
|
|
6
|
+
const y = date.getFullYear();
|
|
7
|
+
const m = String(date.getMonth() + 1).padStart(2, '0');
|
|
8
|
+
const d = String(date.getDate()).padStart(2, '0');
|
|
9
|
+
return `${y}-${m}-${d}`;
|
|
10
|
+
}
|
|
11
|
+
function normalizeDateLikeValue(value) {
|
|
12
|
+
if (value instanceof Date) {
|
|
13
|
+
return formatDateYMD(value);
|
|
14
|
+
}
|
|
15
|
+
if (typeof value === 'string') {
|
|
16
|
+
// Heuristic: ISO-like or timezone string → format as YYYY-MM-DD
|
|
17
|
+
if (/^(\d{4}-\d{2}-\d{2})([T\s].*)?$/.test(value) || /GMT/.test(value)) {
|
|
18
|
+
const t = new Date(value);
|
|
19
|
+
if (!isNaN(t.getTime()))
|
|
20
|
+
return formatDateYMD(t);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
function formatAsCSV(data) {
|
|
26
|
+
if (!data || data.length === 0)
|
|
27
|
+
return '';
|
|
28
|
+
const headers = Object.keys(data[0]);
|
|
29
|
+
const lines = [headers.join(',')];
|
|
30
|
+
for (const row of data) {
|
|
31
|
+
const line = headers
|
|
32
|
+
.map(h => {
|
|
33
|
+
const raw = row[h];
|
|
34
|
+
const value = normalizeDateLikeValue(raw);
|
|
35
|
+
if (value === null || value === undefined)
|
|
36
|
+
return '';
|
|
37
|
+
return typeof value === 'string' ? `"${value}"` : value;
|
|
38
|
+
})
|
|
39
|
+
.join(',');
|
|
40
|
+
lines.push(line);
|
|
41
|
+
}
|
|
42
|
+
return lines.join('\n');
|
|
43
|
+
}
|
|
44
|
+
exports.formatAsCSV = formatAsCSV;
|
|
45
|
+
function formatAsXML(data, rootName = 'rows', rowName = 'row') {
|
|
46
|
+
// Normalize date-like values in a deep-copy manner
|
|
47
|
+
const normalized = data.map(row => {
|
|
48
|
+
const obj = {};
|
|
49
|
+
for (const [k, v] of Object.entries(row)) {
|
|
50
|
+
obj[k] = normalizeDateLikeValue(v);
|
|
51
|
+
}
|
|
52
|
+
return obj;
|
|
53
|
+
});
|
|
54
|
+
const wrapped = {
|
|
55
|
+
[rootName]: {
|
|
56
|
+
_attributes: {},
|
|
57
|
+
[rowName]: normalized
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return (0, xml_js_1.js2xml)(wrapped, { compact: true, spaces: 2 });
|
|
61
|
+
}
|
|
62
|
+
exports.formatAsXML = formatAsXML;
|
|
63
|
+
function formatData(data, type = 'csv') {
|
|
64
|
+
switch (type) {
|
|
65
|
+
case 'csv':
|
|
66
|
+
return formatAsCSV(data);
|
|
67
|
+
case 'xml':
|
|
68
|
+
return formatAsXML(data);
|
|
69
|
+
case 'xlsx':
|
|
70
|
+
// TODO: implement excel generation using a lightweight lib if needed
|
|
71
|
+
// returning CSV as a placeholder to avoid new deps
|
|
72
|
+
return formatAsCSV(data);
|
|
73
|
+
default:
|
|
74
|
+
return formatAsCSV(data);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.formatData = formatData;
|
|
78
|
+
// Simple CSV parser (does not handle embedded commas/newlines/escaped quotes)
|
|
79
|
+
function parseCSV(csvContent) {
|
|
80
|
+
const lines = csvContent.trim().split('\n');
|
|
81
|
+
if (lines.length < 2)
|
|
82
|
+
return [];
|
|
83
|
+
const headers = lines[0].split(',').map(h => h.trim());
|
|
84
|
+
const result = [];
|
|
85
|
+
for (let i = 1; i < lines.length; i++) {
|
|
86
|
+
const values = lines[i].split(',').map(v => v.trim());
|
|
87
|
+
const row = {};
|
|
88
|
+
headers.forEach((header, index) => {
|
|
89
|
+
let value = values[index] || '';
|
|
90
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
91
|
+
value = value.slice(1, -1);
|
|
92
|
+
}
|
|
93
|
+
row[header] = value;
|
|
94
|
+
});
|
|
95
|
+
result.push(row);
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
exports.parseCSV = parseCSV;
|
|
100
|
+
//# sourceMappingURL=file-formatters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-formatters.js","sourceRoot":"","sources":["../../server/util/file-formatters.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,89 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateFiles = void 0;
|
|
4
|
-
require("../
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
const storage_manager_1 = require("../storage/storage-manager");
|
|
5
|
+
const env_1 = require("@things-factory/env");
|
|
6
|
+
async function generateFiles(params, storageConfig) {
|
|
7
|
+
const storageManager = storage_manager_1.StorageManager.getInstance();
|
|
8
|
+
// Primary target config (SFTP or caller-provided)
|
|
9
|
+
const primaryConfig = storageConfig || require('@things-factory/env').config.get('sftpFileStorage');
|
|
10
|
+
// Optional archive config to S3 (uses sftpFileStorage in config when type is 's3')
|
|
11
|
+
const archiveConfig = (() => {
|
|
12
|
+
try {
|
|
13
|
+
const cfg = require('@things-factory/env').config.get('sftpFileStorage');
|
|
14
|
+
return cfg && cfg.type === 's3' ? cfg : null;
|
|
15
|
+
}
|
|
16
|
+
catch (_) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
})();
|
|
20
|
+
env_1.logger.info(`generateFiles: primary=${primaryConfig.type} archive=${archiveConfig ? archiveConfig.type + ':' + archiveConfig.bucketName : 'disabled'}`);
|
|
21
|
+
const sleep = (ms) => new Promise(res => setTimeout(res, ms));
|
|
9
22
|
for (let i = 0; i < params.length; i++) {
|
|
10
23
|
let param = params[i];
|
|
11
24
|
const { uploadPath, content, title } = param;
|
|
12
|
-
|
|
13
|
-
fs.mkdirSync(fileDirectory);
|
|
14
|
-
}
|
|
15
|
-
const filePath = fileDirectory + '/' + title;
|
|
16
|
-
fs.writeFile(filePath, content, function (err) {
|
|
17
|
-
if (err)
|
|
18
|
-
throw err;
|
|
19
|
-
console.log('File is created successfully.');
|
|
20
|
-
});
|
|
25
|
+
// Ensure remote directory exists before upload (skip when empty string or undefined)
|
|
21
26
|
if (uploadPath) {
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
let attempts = 0;
|
|
28
|
+
while (true) {
|
|
29
|
+
try {
|
|
30
|
+
await storageManager.createDirectory(primaryConfig, uploadPath);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
attempts++;
|
|
35
|
+
if (attempts >= 3) {
|
|
36
|
+
env_1.logger.warn(`createDirectory failed for ${uploadPath}: ${(e === null || e === void 0 ? void 0 : e.message) || e}`);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
await sleep(200 * attempts);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Compose remote relative path (under basePath when configured)
|
|
44
|
+
const remotePath = `${uploadPath ? uploadPath + '/' : ''}${title}`.replace(/\/+/, '/').replace(/\/+/, '/');
|
|
45
|
+
// Upload to primary
|
|
46
|
+
if (primaryConfig.type === 'sftp') {
|
|
47
|
+
// Stream upload with retries to reduce connection issues
|
|
48
|
+
const { Readable } = require('stream');
|
|
49
|
+
let attempts = 0;
|
|
50
|
+
while (true) {
|
|
51
|
+
try {
|
|
52
|
+
const dataStream = Readable.from([content]);
|
|
53
|
+
await storageManager.uploadFile(primaryConfig, {
|
|
54
|
+
stream: dataStream,
|
|
55
|
+
filename: title,
|
|
56
|
+
uploadPath: uploadPath || ''
|
|
57
|
+
});
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
attempts++;
|
|
62
|
+
if (attempts >= 3) {
|
|
63
|
+
env_1.logger.warn(`SFTP upload failed for ${title} to ${uploadPath || '(root)'}: ${(e === null || e === void 0 ? void 0 : e.message) || e}`);
|
|
64
|
+
throw e;
|
|
65
|
+
}
|
|
66
|
+
await sleep(300 * attempts);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Direct write for non-SFTP providers
|
|
72
|
+
await storageManager.writeFile(primaryConfig, remotePath, content, 'utf-8');
|
|
73
|
+
}
|
|
74
|
+
// Optional: archive a copy to S3 under <platform>/
|
|
75
|
+
if (archiveConfig) {
|
|
76
|
+
const platformPrefix = (param.platform || '').toString().trim();
|
|
77
|
+
const archiveKey = `${platformPrefix}/${title}`;
|
|
78
|
+
env_1.logger.info(`generateFiles: archiving to S3 key=${archiveKey}`);
|
|
79
|
+
try {
|
|
80
|
+
await storageManager.writeFile(archiveConfig, archiveKey, content, 'utf-8');
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
env_1.logger.warn(`S3 archive failed for ${title}: ${(e === null || e === void 0 ? void 0 : e.message) || e}`);
|
|
84
|
+
}
|
|
24
85
|
}
|
|
25
86
|
}
|
|
26
|
-
fs.rm(fileDirectory, { recursive: true });
|
|
27
87
|
return true;
|
|
28
88
|
}
|
|
29
89
|
exports.generateFiles = generateFiles;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-files.js","sourceRoot":"","sources":["../../server/util/generate-files.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"generate-files.js","sourceRoot":"","sources":["../../server/util/generate-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.readFile = exports.getPermittedDirectories = void 0;
|
|
4
|
-
require("../
|
|
4
|
+
const storage_manager_1 = require("../storage/storage-manager");
|
|
5
5
|
const sftp_const_1 = require("../sftp-const");
|
|
6
|
-
async function getPermittedDirectories(params, context) {
|
|
7
|
-
const
|
|
6
|
+
async function getPermittedDirectories(params, context, storageConfig) {
|
|
7
|
+
const storageManager = storage_manager_1.StorageManager.getInstance();
|
|
8
|
+
const config = storageConfig || (0, sftp_const_1.getSftpStorageConfig)();
|
|
9
|
+
const sftpDirectories = await storageManager.readFolders(config, params);
|
|
8
10
|
return sftpDirectories;
|
|
9
11
|
}
|
|
10
12
|
exports.getPermittedDirectories = getPermittedDirectories;
|
|
11
|
-
async function readFile(fileKey) {
|
|
12
|
-
const
|
|
13
|
+
async function readFile(fileKey, storageConfig) {
|
|
14
|
+
const storageManager = storage_manager_1.StorageManager.getInstance();
|
|
15
|
+
const config = storageConfig || (0, sftp_const_1.getSftpStorageConfig)();
|
|
16
|
+
const file = await storageManager.readFile(config, fileKey, 'utf-8');
|
|
13
17
|
return file;
|
|
14
18
|
}
|
|
15
19
|
exports.readFile = readFile;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-permitted-directories.js","sourceRoot":"","sources":["../../server/util/get-permitted-directories.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"get-permitted-directories.js","sourceRoot":"","sources":["../../server/util/get-permitted-directories.ts"],"names":[],"mappings":";;;AAAA,gEAA2D;AAE3D,8CAAoD;AAE7C,KAAK,UAAU,uBAAuB,CAAC,MAAW,EAAE,OAAY,EAAE,aAA6B;IACpG,MAAM,cAAc,GAAG,gCAAc,CAAC,WAAW,EAAE,CAAA;IACnD,MAAM,MAAM,GAAG,aAAa,IAAI,IAAA,iCAAoB,GAAE,CAAA;IACtD,MAAM,eAAe,GAAU,MAAM,cAAc,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE/E,OAAO,eAAe,CAAA;AACxB,CAAC;AAND,0DAMC;AAEM,KAAK,UAAU,QAAQ,CAAC,OAAY,EAAE,aAA6B;IACxE,MAAM,cAAc,GAAG,gCAAc,CAAC,WAAW,EAAE,CAAA;IACnD,MAAM,MAAM,GAAG,aAAa,IAAI,IAAA,iCAAoB,GAAE,CAAA;IACtD,MAAM,IAAI,GAAQ,MAAM,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IAEzE,OAAO,IAAI,CAAA;AACb,CAAC;AAND,4BAMC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/integration-sftp",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.668",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -26,10 +26,13 @@
|
|
|
26
26
|
"@things-factory/auth-base": "^4.3.591",
|
|
27
27
|
"@things-factory/biz-base": "^4.3.595",
|
|
28
28
|
"@things-factory/env": "^4.3.591",
|
|
29
|
-
"@things-factory/integration-fulfillment": "^4.3.
|
|
29
|
+
"@things-factory/integration-fulfillment": "^4.3.667",
|
|
30
30
|
"@things-factory/shell": "^4.3.591",
|
|
31
31
|
"aws-sdk": "^2.960.0",
|
|
32
|
+
"ftp": "^0.3.10",
|
|
33
|
+
"ssh2": "^1.11.0",
|
|
34
|
+
"ssh2-sftp-client": "^7.0.0",
|
|
32
35
|
"xml-js": "^1.6.11"
|
|
33
36
|
},
|
|
34
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "7bbcb83fbb36a1599002781f95e5904cc8dd453a"
|
|
35
38
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import '../../sftp-s3'
|
|
2
|
-
|
|
3
1
|
import { xml2js } from 'xml-js'
|
|
2
|
+
import { config } from '@things-factory/env'
|
|
4
3
|
|
|
5
4
|
import { Sftp } from '../../service'
|
|
6
|
-
import {
|
|
5
|
+
import { StorageManager } from '../../storage/storage-manager'
|
|
7
6
|
import { generateFiles } from '../../util/generate-files'
|
|
8
7
|
|
|
9
8
|
const debug = require('debug')('things-factory:integration-sftp:herbalife')
|
|
@@ -11,10 +10,16 @@ const debug = require('debug')('things-factory:integration-sftp:herbalife')
|
|
|
11
10
|
export type HerbalifeConfig = {}
|
|
12
11
|
|
|
13
12
|
export class Herbalife {
|
|
14
|
-
|
|
13
|
+
private storageManager = StorageManager.getInstance()
|
|
14
|
+
private sftpConfig: any
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
// Get the SFTP configuration from config
|
|
18
|
+
this.sftpConfig = config.get('sftpFileStorage')
|
|
19
|
+
}
|
|
15
20
|
|
|
16
21
|
async get(path: string, data: any = {}) {
|
|
17
|
-
const fileResult: any = await
|
|
22
|
+
const fileResult: any = await this.storageManager.readFile(this.sftpConfig, path, 'utf-8')
|
|
18
23
|
const item: any = xml2js(fileResult, {
|
|
19
24
|
compact: true
|
|
20
25
|
})
|
|
@@ -46,7 +51,7 @@ export class Herbalife {
|
|
|
46
51
|
content
|
|
47
52
|
})
|
|
48
53
|
}
|
|
49
|
-
await generateFiles(params)
|
|
54
|
+
await generateFiles(params, this.sftpConfig)
|
|
50
55
|
|
|
51
56
|
return sftp
|
|
52
57
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function createYLTCInventoryReport() {
|
|
2
|
+
return {
|
|
3
|
+
method: 'post',
|
|
4
|
+
path: '{folderPath}',
|
|
5
|
+
denormalize(req) {
|
|
6
|
+
const { sftp, title, backupTitle, content, backupPath, contentType } = req
|
|
7
|
+
const { folderPath, platform } = sftp
|
|
8
|
+
|
|
9
|
+
// Values used by platform-action substitute() for path placeholders
|
|
10
|
+
const resource = {
|
|
11
|
+
folderPath: folderPath || ''
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Build payload with required fields only
|
|
15
|
+
const payload: any = {
|
|
16
|
+
sftp,
|
|
17
|
+
title,
|
|
18
|
+
content,
|
|
19
|
+
contentType,
|
|
20
|
+
folderPath,
|
|
21
|
+
platform
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Include optionals only when present
|
|
25
|
+
if (backupTitle) payload.backupTitle = backupTitle
|
|
26
|
+
if (backupPath) payload.backupPath = backupPath
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
resource,
|
|
30
|
+
payload
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
normalize(res) {
|
|
34
|
+
return res
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Yltc } from './yltc'
|
|
2
|
+
|
|
3
|
+
function substitute(path, obj) {
|
|
4
|
+
var props = []
|
|
5
|
+
var re = /{([^}]+)}/g
|
|
6
|
+
var text
|
|
7
|
+
|
|
8
|
+
while ((text = re.exec(path))) {
|
|
9
|
+
props.push(text[1])
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
var result = path
|
|
13
|
+
props.forEach(prop => {
|
|
14
|
+
let value = obj[prop.trim()]
|
|
15
|
+
result = result.replace(`{${prop}}`, value === undefined ? '' : value)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
return result
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const action = async ({ method = 'get', path, request }) => {
|
|
22
|
+
const client = new Yltc()
|
|
23
|
+
|
|
24
|
+
const { resource = {}, payload = {} } = request
|
|
25
|
+
|
|
26
|
+
path = substitute(path, resource)
|
|
27
|
+
|
|
28
|
+
var response = await client[method](path, payload)
|
|
29
|
+
if (response.errors) {
|
|
30
|
+
throw response
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return response
|
|
34
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { config } from '@things-factory/env'
|
|
2
|
+
import { Sftp } from '../../service'
|
|
3
|
+
import { StorageManager } from '../../storage/storage-manager'
|
|
4
|
+
import { StorageConfig } from '../../storage/storage-provider.interface'
|
|
5
|
+
import { generateFiles } from '../../util/generate-files'
|
|
6
|
+
import { formatData, SupportedContentType, parseCSV } from '../../util/file-formatters'
|
|
7
|
+
export class Yltc {
|
|
8
|
+
private storageManager = StorageManager.getInstance()
|
|
9
|
+
|
|
10
|
+
constructor() {}
|
|
11
|
+
|
|
12
|
+
private buildRuntimeConfigFromSftp(sftp?: Sftp): StorageConfig {
|
|
13
|
+
if (sftp && (sftp.host || sftp.username || sftp.password)) {
|
|
14
|
+
return {
|
|
15
|
+
type: 'sftp',
|
|
16
|
+
host: (sftp as any).host,
|
|
17
|
+
port: (sftp as any).port,
|
|
18
|
+
username: (sftp as any).username,
|
|
19
|
+
password: (sftp as any).password,
|
|
20
|
+
basePath: (sftp as any).basePath || (sftp as any).folderPath, // fallback to folderPath if basePath is not provided
|
|
21
|
+
timeout: (sftp as any).timeout,
|
|
22
|
+
retries: (sftp as any).retries
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Fallback to external config if Sftp entity does not carry connection info
|
|
26
|
+
return config.get('sftpExternal') || config.get('sftpFileStorage')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async get(path: string, data: any = {}) {
|
|
30
|
+
const runtimeConfig: StorageConfig = this.buildRuntimeConfigFromSftp(data?.sftp)
|
|
31
|
+
const fileResult: any = await this.storageManager.readFile(runtimeConfig, path, 'utf-8')
|
|
32
|
+
|
|
33
|
+
// Check if file is CSV and parse accordingly
|
|
34
|
+
if (path.toLowerCase().endsWith('.csv')) {
|
|
35
|
+
return parseCSV(fileResult)
|
|
36
|
+
} else {
|
|
37
|
+
// Fallback to XML parsing for backward compatibility
|
|
38
|
+
const { xml2js } = require('xml-js')
|
|
39
|
+
const item: any = xml2js(fileResult, {
|
|
40
|
+
compact: true
|
|
41
|
+
})
|
|
42
|
+
return { ...item }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async post(path: string, data: any = {}) {
|
|
47
|
+
const {
|
|
48
|
+
title,
|
|
49
|
+
backupTitle,
|
|
50
|
+
content,
|
|
51
|
+
sftp,
|
|
52
|
+
backupPath,
|
|
53
|
+
contentType = 'csv' // Default to CSV
|
|
54
|
+
}: {
|
|
55
|
+
title: string
|
|
56
|
+
backupTitle: string
|
|
57
|
+
content: string | any[]
|
|
58
|
+
sftp: Sftp
|
|
59
|
+
backupPath: string
|
|
60
|
+
contentType?: SupportedContentType
|
|
61
|
+
} = data
|
|
62
|
+
|
|
63
|
+
const runtimeConfig: StorageConfig = this.buildRuntimeConfigFromSftp(sftp)
|
|
64
|
+
|
|
65
|
+
let params: any[] = []
|
|
66
|
+
|
|
67
|
+
const body = Array.isArray(content) ? formatData(content, contentType) : content
|
|
68
|
+
|
|
69
|
+
// Ensure extension matches content type
|
|
70
|
+
const ext = contentType === 'xml' ? '.xml' : contentType === 'xlsx' ? '.xlsx' : '.csv'
|
|
71
|
+
const normalizedTitle = title.endsWith(ext) ? title : `${title}${ext}`
|
|
72
|
+
|
|
73
|
+
// If basePath is configured, uploading to basePath root requires empty uploadPath
|
|
74
|
+
const mainUploadPath = (runtimeConfig as any).basePath ? '' : path
|
|
75
|
+
|
|
76
|
+
const platformPrefix: string = ((sftp as any)?.platform || (data as any)?.platform || '').toString().trim()
|
|
77
|
+
|
|
78
|
+
params.push({
|
|
79
|
+
title: normalizedTitle,
|
|
80
|
+
uploadPath: mainUploadPath,
|
|
81
|
+
content: body,
|
|
82
|
+
platform: platformPrefix
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
if (backupPath && backupTitle) {
|
|
86
|
+
const normalizedBackupTitle = backupTitle.endsWith(ext) ? backupTitle : `${backupTitle}${ext}`
|
|
87
|
+
params.push({ title: normalizedBackupTitle, uploadPath: backupPath, content: body, platform: platformPrefix })
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await generateFiles(params, runtimeConfig)
|
|
91
|
+
return sftp
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import '../../sftp-s3'
|
|
2
|
-
|
|
3
1
|
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
|
4
2
|
import { EntityManager, getConnection, In } from 'typeorm'
|
|
5
3
|
|
|
@@ -8,13 +6,17 @@ import { FulfillmentAPI, FulFillmentCenter } from '@things-factory/integration-f
|
|
|
8
6
|
import { Domain } from '@things-factory/shell'
|
|
9
7
|
|
|
10
8
|
import { SftpAPI } from '../../controllers'
|
|
11
|
-
import { FAILEDDATAPATH,
|
|
9
|
+
import { FAILEDDATAPATH, SUBMITDATAPATH, SUCCESSDATAPATH, getSftpStorageConfig } from '../../sftp-const'
|
|
10
|
+
import { StorageManager } from '../../storage/storage-manager'
|
|
12
11
|
import { getPermittedDirectories } from '../../util'
|
|
13
12
|
import { Sftp } from './sftp'
|
|
14
13
|
import { NewSftp, SftpPatch } from './sftp-type'
|
|
15
14
|
|
|
16
15
|
@Resolver(Sftp)
|
|
17
16
|
export class SftpMutation {
|
|
17
|
+
private storageManager = StorageManager.getInstance()
|
|
18
|
+
private sftpConfig = getSftpStorageConfig()
|
|
19
|
+
|
|
18
20
|
@Directive('@transaction')
|
|
19
21
|
@Mutation(returns => Sftp, { description: 'To create new Sftp' })
|
|
20
22
|
async createSftp(@Arg('sftp') sftp: NewSftp, @Ctx() context: any): Promise<Sftp> {
|
|
@@ -130,7 +132,7 @@ export class SftpMutation {
|
|
|
130
132
|
|
|
131
133
|
for (var i = 0; i < sftpUsers.length; i++) {
|
|
132
134
|
const sftpUser: Sftp = sftpUsers[i]
|
|
133
|
-
processSftp(sftpUser, context, customerBizplace.id)
|
|
135
|
+
processSftp(sftpUser, context, customerBizplace.id, this.storageManager, this.sftpConfig)
|
|
134
136
|
}
|
|
135
137
|
})
|
|
136
138
|
|
|
@@ -151,7 +153,7 @@ export class SftpMutation {
|
|
|
151
153
|
if (sftps.length === 0) return
|
|
152
154
|
for (const sftp of sftps) {
|
|
153
155
|
const customerBizplace = await getCustomerBizplace(sftp.domainId, tx)
|
|
154
|
-
await processSftp(sftp, context, customerBizplace.id)
|
|
156
|
+
await processSftp(sftp, context, customerBizplace.id, this.storageManager, this.sftpConfig)
|
|
155
157
|
}
|
|
156
158
|
})
|
|
157
159
|
} catch (e) {
|
|
@@ -161,13 +163,17 @@ export class SftpMutation {
|
|
|
161
163
|
}
|
|
162
164
|
}
|
|
163
165
|
|
|
164
|
-
export async function processSftp(sftpUser, context, customerBizplaceId) {
|
|
166
|
+
export async function processSftp(sftpUser, context, customerBizplaceId, storageManager?, sftpConfig?) {
|
|
167
|
+
// Use provided storage manager or get singleton instance
|
|
168
|
+
const manager = storageManager || StorageManager.getInstance()
|
|
169
|
+
const config = sftpConfig || getSftpStorageConfig()
|
|
170
|
+
|
|
165
171
|
const fulfilmentCenter: FulFillmentCenter = sftpUser.fulfillmentCenter
|
|
166
172
|
const isDevelopment: boolean = sftpUser.isDevelopment
|
|
167
173
|
const folderPath: string = sftpUser.folderPath
|
|
168
174
|
const folderType: string = isDevelopment ? 'dev' : 'prd'
|
|
169
175
|
let initialDataPath: string = `${sftpUser.folderPath}/${folderType}${SUBMITDATAPATH}/`
|
|
170
|
-
const results: any[] = await getPermittedDirectories({ path: initialDataPath }, context)
|
|
176
|
+
const results: any[] = await getPermittedDirectories({ path: initialDataPath }, context, config)
|
|
171
177
|
const filesDirectories: any[] = results.filter(result => result.Size > 0)
|
|
172
178
|
|
|
173
179
|
for await (let fileDirectory of filesDirectories) {
|
|
@@ -206,7 +212,7 @@ export async function processSftp(sftpUser, context, customerBizplaceId) {
|
|
|
206
212
|
source: (dataPath += fileString),
|
|
207
213
|
destination: (successPath += fileString)
|
|
208
214
|
}
|
|
209
|
-
await
|
|
215
|
+
await manager.moveFile(config, movePaths)
|
|
210
216
|
}
|
|
211
217
|
}
|
|
212
218
|
} else {
|
|
@@ -214,14 +220,14 @@ export async function processSftp(sftpUser, context, customerBizplaceId) {
|
|
|
214
220
|
source: (dataPath += fileString),
|
|
215
221
|
destination: (failedPath += fileString)
|
|
216
222
|
}
|
|
217
|
-
await
|
|
223
|
+
await manager.moveFile(config, movePaths)
|
|
218
224
|
}
|
|
219
225
|
} catch (e) {
|
|
220
226
|
let movePaths = {
|
|
221
227
|
source: (dataPath += fileString),
|
|
222
228
|
destination: (failedPath += fileString)
|
|
223
229
|
}
|
|
224
|
-
await
|
|
230
|
+
await manager.moveFile(config, movePaths)
|
|
225
231
|
}
|
|
226
232
|
}
|
|
227
233
|
}
|