@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.
Files changed (68) hide show
  1. package/CHANGELOG.md +369 -0
  2. package/dist-server/controllers/herbalife/herbalife.js +9 -5
  3. package/dist-server/controllers/herbalife/herbalife.js.map +1 -1
  4. package/dist-server/controllers/index.js +1 -0
  5. package/dist-server/controllers/index.js.map +1 -1
  6. package/dist-server/controllers/sftp-api/index.js +7 -0
  7. package/dist-server/controllers/sftp-api/index.js.map +1 -1
  8. package/dist-server/controllers/yltc/apis/create-yltc-inventory-report.js +40 -0
  9. package/dist-server/controllers/yltc/apis/create-yltc-inventory-report.js.map +1 -0
  10. package/dist-server/controllers/yltc/apis/echo.js +19 -0
  11. package/dist-server/controllers/yltc/apis/echo.js.map +1 -0
  12. package/dist-server/controllers/yltc/apis/index.js +19 -0
  13. package/dist-server/controllers/yltc/apis/index.js.map +1 -0
  14. package/dist-server/controllers/yltc/index.js +34 -0
  15. package/dist-server/controllers/yltc/index.js.map +1 -0
  16. package/dist-server/controllers/yltc/platform-action.js +30 -0
  17. package/dist-server/controllers/yltc/platform-action.js.map +1 -0
  18. package/dist-server/controllers/yltc/yltc.js +71 -0
  19. package/dist-server/controllers/yltc/yltc.js.map +1 -0
  20. package/dist-server/service/sftp/sftp-mutation.js +15 -8
  21. package/dist-server/service/sftp/sftp-mutation.js.map +1 -1
  22. package/dist-server/service/sftp/sftp.js +41 -0
  23. package/dist-server/service/sftp/sftp.js.map +1 -1
  24. package/dist-server/sftp-const.js +36 -2
  25. package/dist-server/sftp-const.js.map +1 -1
  26. package/dist-server/storage/providers/ftp-storage.provider.js +178 -0
  27. package/dist-server/storage/providers/ftp-storage.provider.js.map +1 -0
  28. package/dist-server/storage/providers/local-storage.provider.js +153 -0
  29. package/dist-server/storage/providers/local-storage.provider.js.map +1 -0
  30. package/dist-server/storage/providers/s3-storage.provider.js +181 -0
  31. package/dist-server/storage/providers/s3-storage.provider.js.map +1 -0
  32. package/dist-server/storage/providers/sftp-storage.provider.js +133 -0
  33. package/dist-server/storage/providers/sftp-storage.provider.js.map +1 -0
  34. package/dist-server/storage/storage-factory.js +55 -0
  35. package/dist-server/storage/storage-factory.js.map +1 -0
  36. package/dist-server/storage/storage-manager.js +86 -0
  37. package/dist-server/storage/storage-manager.js.map +1 -0
  38. package/dist-server/storage/storage-provider.interface.js +3 -0
  39. package/dist-server/storage/storage-provider.interface.js.map +1 -0
  40. package/dist-server/util/file-formatters.js +100 -0
  41. package/dist-server/util/file-formatters.js.map +1 -0
  42. package/dist-server/util/generate-files.js +77 -17
  43. package/dist-server/util/generate-files.js.map +1 -1
  44. package/dist-server/util/get-permitted-directories.js +9 -5
  45. package/dist-server/util/get-permitted-directories.js.map +1 -1
  46. package/package.json +6 -3
  47. package/server/controllers/herbalife/herbalife.ts +11 -6
  48. package/server/controllers/index.ts +1 -0
  49. package/server/controllers/sftp-api/index.ts +3 -0
  50. package/server/controllers/yltc/apis/create-yltc-inventory-report.ts +37 -0
  51. package/server/controllers/yltc/apis/echo.ts +14 -0
  52. package/server/controllers/yltc/apis/index.ts +2 -0
  53. package/server/controllers/yltc/index.ts +7 -0
  54. package/server/controllers/yltc/platform-action.ts +34 -0
  55. package/server/controllers/yltc/yltc.ts +93 -0
  56. package/server/service/sftp/sftp-mutation.ts +16 -10
  57. package/server/service/sftp/sftp.ts +34 -0
  58. package/server/sftp-const.ts +41 -1
  59. package/server/storage/providers/ftp-storage.provider.ts +177 -0
  60. package/server/storage/providers/local-storage.provider.ts +159 -0
  61. package/server/storage/providers/s3-storage.provider.ts +214 -0
  62. package/server/storage/providers/sftp-storage.provider.ts +157 -0
  63. package/server/storage/storage-factory.ts +62 -0
  64. package/server/storage/storage-manager.ts +103 -0
  65. package/server/storage/storage-provider.interface.ts +42 -0
  66. package/server/util/file-formatters.ts +97 -0
  67. package/server/util/generate-files.ts +79 -17
  68. 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("../sftp-s3");
5
- const sftp_const_1 = require("../sftp-const");
6
- const fs = require('fs');
7
- async function generateFiles(params) {
8
- const fileDirectory = './uploaded-files';
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
- if (!fs.existsSync(fileDirectory)) {
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
- const stream = fs.createReadStream(filePath);
23
- await sftp_const_1.SFTPFILESTORAGE.uploadFile({ stream, filename: title, uploadPath });
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,sBAAmB;AAEnB,8CAA+C;AAE/C,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAEjB,KAAK,UAAU,aAAa,CAAC,MAAa;IAC/C,MAAM,aAAa,GAAG,kBAAkB,CAAA;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,KAAK,GAAQ,MAAM,CAAC,CAAC,CAAC,CAAA;QAC1B,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;QAE5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;YACjC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;SAC5B;QAED,MAAM,QAAQ,GAAG,aAAa,GAAG,GAAG,GAAG,KAAK,CAAA;QAE5C,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG;YAC3C,IAAI,GAAG;gBAAE,MAAM,GAAG,CAAA;YAClB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAA;QAEF,IAAI,UAAU,EAAE;YACd,MAAM,MAAM,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAA;YAC5C,MAAM,4BAAe,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAA;SAC1E;KACF;IAED,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEzC,OAAO,IAAI,CAAA;AACb,CAAC;AA1BD,sCA0BC"}
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("../sftp-s3");
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 sftpDirectories = await sftp_const_1.SFTPFILESTORAGE.readFolders(params);
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 file = await sftp_const_1.SFTPFILESTORAGE.readFile(fileKey, 'utf-8');
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,sBAAmB;AAEnB,8CAA+C;AAExC,KAAK,UAAU,uBAAuB,CAAC,MAAW,EAAE,OAAY;IACrE,MAAM,eAAe,GAAU,MAAM,4BAAe,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IAExE,OAAO,eAAe,CAAA;AACxB,CAAC;AAJD,0DAIC;AAEM,KAAK,UAAU,QAAQ,CAAC,OAAY;IACzC,MAAM,IAAI,GAAQ,MAAM,4BAAe,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAElE,OAAO,IAAI,CAAA;AACb,CAAC;AAJD,4BAIC"}
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.660",
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.660",
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": "d5c870cd06b2fcacea68ba21baadd244e4532b99"
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 { SFTPFILESTORAGE } from '../../sftp-const'
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
- constructor() {}
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 SFTPFILESTORAGE.readFile(path, 'utf-8')
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
  }
@@ -1,3 +1,4 @@
1
1
  import './herbalife'
2
+ import './yltc'
2
3
 
3
4
  export * from './sftp-api'
@@ -36,4 +36,7 @@ export class SftpAPI {
36
36
 
37
37
  @api
38
38
  static createSerialNumber(sftp, req): any {}
39
+
40
+ @api
41
+ static createYLTCInventoryReport(sftp, req): any {}
39
42
  }
@@ -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,14 @@
1
+ export function echo() {
2
+ return {
3
+ path: '/echo',
4
+ denormalize(req) {
5
+ return { ...req }
6
+ },
7
+ normalize(res) {
8
+ return { ...res }
9
+ },
10
+ action({ store, method, path, request, platformAction }) {
11
+ return { ...request }
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,2 @@
1
+ export * from './echo'
2
+ export * from './create-yltc-inventory-report'
@@ -0,0 +1,7 @@
1
+ import { SftpAPI } from '../sftp-api'
2
+ import * as APIS from './apis'
3
+ import { action } from './platform-action'
4
+
5
+ export * from './yltc'
6
+
7
+ SftpAPI.registerPlatform('yltc', action, APIS)
@@ -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, SFTPFILESTORAGE, SUBMITDATAPATH, SUCCESSDATAPATH } from '../../sftp-const'
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 SFTPFILESTORAGE.moveFile(movePaths)
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 SFTPFILESTORAGE.moveFile(movePaths)
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 SFTPFILESTORAGE.moveFile(movePaths)
230
+ await manager.moveFile(config, movePaths)
225
231
  }
226
232
  }
227
233
  }