@things-factory/integration-sftp 4.3.660 → 4.3.667

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
package/CHANGELOG.md CHANGED
@@ -5,4 +5,373 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
6
  and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## Overview
9
+
10
+ This guide explains how to migrate from the current S3-only SFTP integration to support multiple storage providers including external SFTP servers.
11
+
12
+ ## New Architecture
13
+
14
+ The new system uses a provider-based architecture with the following components:
15
+
16
+ 1. **StorageProvider Interface** - Common contract for all storage providers
17
+ 2. **StorageFactory** - Creates appropriate provider instances
18
+ 3. **StorageManager** - Singleton manager for provider lifecycle
19
+ 4. **Provider Implementations** - S3, SFTP, FTP, Local storage providers
20
+
21
+ ## Migration Steps
22
+
23
+ ### 1. Update Configuration
24
+
25
+ **Old Configuration (S3 only):**
26
+
27
+ ```javascript
28
+ // config/sftp.js
29
+ module.exports = {
30
+ sftpFileStorage: {
31
+ type: 's3',
32
+ accessKeyId: 'your-access-key',
33
+ secretAccessKey: 'your-secret-key',
34
+ bucketName: 'your-bucket'
35
+ }
36
+ }
37
+ ```
38
+
39
+ **New Configuration (Multi-provider):**
40
+
41
+ ```javascript
42
+ // config/sftp.js
43
+ module.exports = {
44
+ sftpFileStorage: {
45
+ // For S3 (existing)
46
+ type: 's3',
47
+ accessKeyId: 'your-access-key',
48
+ secretAccessKey: 'your-secret-key',
49
+ bucketName: 'your-bucket',
50
+ region: 'us-east-1'
51
+ },
52
+
53
+ // For External SFTP Server
54
+ sftpExternal: {
55
+ type: 'sftp',
56
+ host: 'sftp.example.com',
57
+ port: 22,
58
+ username: 'sftp-user',
59
+ password: 'sftp-password', // or use privateKey
60
+ privateKey: '/path/to/private/key',
61
+ basePath: '/remote/path',
62
+ timeout: 30000,
63
+ retries: 3
64
+ },
65
+
66
+ // For FTP Server
67
+ ftpServer: {
68
+ type: 'ftp',
69
+ host: 'ftp.example.com',
70
+ port: 21,
71
+ username: 'ftp-user',
72
+ password: 'ftp-password',
73
+ basePath: '/remote/path',
74
+ secure: false // true for FTPS
75
+ },
76
+
77
+ // For Local Storage
78
+ localStorage: {
79
+ type: 'local',
80
+ basePath: './storage'
81
+ }
82
+ }
83
+ ```
84
+
85
+ ### 2. Update Code Usage
86
+
87
+ **Old Usage:**
88
+
89
+ ```typescript
90
+ import { SFTPFILESTORAGE } from './sftp-const'
91
+
92
+ // Read file
93
+ const content = await SFTPFILESTORAGE.readFile(path, 'utf-8')
94
+
95
+ // Upload file
96
+ await SFTPFILESTORAGE.uploadFile({ stream, filename, uploadPath })
97
+ ```
98
+
99
+ **New Usage:**
100
+
101
+ ```typescript
102
+ import { StorageManager } from './storage/storage-manager'
103
+ import { config } from '@things-factory/env'
104
+
105
+ const storageManager = StorageManager.getInstance()
106
+
107
+ // Get configuration
108
+ const sftpConfig = config.get('sftpExternal')
109
+
110
+ // Read file
111
+ const content = await storageManager.readFile(sftpConfig, path, 'utf-8')
112
+
113
+ // Upload file
114
+ await storageManager.uploadFile(sftpConfig, { stream, filename, uploadPath })
115
+ ```
116
+
117
+ ### 3. Update Existing Code
118
+
119
+ Replace direct `SFTPFILESTORAGE` usage with `StorageManager`:
120
+
121
+ ```typescript
122
+ // Old code in sftp-mutation.ts
123
+ const results: any[] = await getPermittedDirectories({ path: initialDataPath }, context)
124
+
125
+ // New code
126
+ import { StorageManager } from '../storage/storage-manager'
127
+ const storageManager = StorageManager.getInstance()
128
+ const sftpConfig = config.get('sftpFileStorage') // or your specific config
129
+ const results: any[] = await storageManager.readFolders(sftpConfig, { path: initialDataPath })
130
+ ```
131
+
132
+ ### 4. Update Platform Implementations
133
+
134
+ **Old Herbalife Platform:**
135
+
136
+ ```typescript
137
+ // server/controllers/herbalife/herbalife.ts
138
+ async get(path: string, data: any = {}) {
139
+ const fileResult: any = await SFTPFILESTORAGE.readFile(path, 'utf-8')
140
+ // ...
141
+ }
142
+ ```
143
+
144
+ **New Herbalife Platform:**
145
+
146
+ ```typescript
147
+ // server/controllers/herbalife/herbalife.ts
148
+ import { StorageManager } from '../../storage/storage-manager'
149
+ import { config } from '@things-factory/env'
150
+
151
+ export class Herbalife {
152
+ private storageManager = StorageManager.getInstance()
153
+ private sftpConfig = config.get('sftpFileStorage') // or specific config
154
+
155
+ async get(path: string, data: any = {}) {
156
+ const fileResult: any = await this.storageManager.readFile(this.sftpConfig, path, 'utf-8')
157
+ // ...
158
+ }
159
+ }
160
+ ```
161
+
162
+ ## Configuration Examples
163
+
164
+ ### External SFTP Server
165
+
166
+ ```javascript
167
+ {
168
+ type: 'sftp',
169
+ host: 'sftp.company.com',
170
+ port: 22,
171
+ username: 'integration-user',
172
+ password: 'secure-password',
173
+ basePath: '/incoming/orders',
174
+ timeout: 30000,
175
+ retries: 3
176
+ }
177
+ ```
178
+
179
+ ### SFTP with Private Key
180
+
181
+ ```javascript
182
+ {
183
+ type: 'sftp',
184
+ host: 'sftp.company.com',
185
+ port: 22,
186
+ username: 'integration-user',
187
+ privateKey: fs.readFileSync('/path/to/private/key'),
188
+ basePath: '/incoming/orders',
189
+ timeout: 30000
190
+ }
191
+ ```
192
+
193
+ ### FTP Server
194
+
195
+ ```javascript
196
+ {
197
+ type: 'ftp',
198
+ host: 'ftp.company.com',
199
+ port: 21,
200
+ username: 'ftp-user',
201
+ password: 'ftp-password',
202
+ basePath: '/orders',
203
+ secure: false // true for FTPS
204
+ }
205
+ ```
206
+
207
+ ## Error Handling
208
+
209
+ The new system provides better error handling:
210
+
211
+ ```typescript
212
+ try {
213
+ const content = await storageManager.readFile(config, path, 'utf-8')
214
+ } catch (error) {
215
+ if (error.message.includes('Failed to connect')) {
216
+ // Connection error
217
+ logger.error('Storage connection failed:', error)
218
+ } else if (error.message.includes('File not found')) {
219
+ // File not found
220
+ logger.warn('File not found:', path)
221
+ } else {
222
+ // Other errors
223
+ logger.error('Storage operation failed:', error)
224
+ }
225
+ }
226
+ ```
227
+
228
+ ## Testing
229
+
230
+ Test different providers:
231
+
232
+ ```typescript
233
+ // Test S3
234
+ const s3Config = { type: 's3', bucketName: 'test-bucket', ... }
235
+ await storageManager.writeFile(s3Config, '/test.txt', 'Hello S3')
236
+
237
+ // Test SFTP
238
+ const sftpConfig = { type: 'sftp', host: 'test-sftp.com', ... }
239
+ await storageManager.writeFile(sftpConfig, '/test.txt', 'Hello SFTP')
240
+
241
+ // Test Local
242
+ const localConfig = { type: 'local', basePath: './test-storage' }
243
+ await storageManager.writeFile(localConfig, '/test.txt', 'Hello Local')
244
+ ```
245
+
246
+ ## Performance Considerations
247
+
248
+ 1. **Connection Pooling**: The StorageManager maintains provider connections
249
+ 2. **Lazy Loading**: Providers are created only when needed
250
+ 3. **Resource Cleanup**: Call `disconnectAll()` on application shutdown
251
+
252
+ ## Security
253
+
254
+ 1. **Credentials**: Store sensitive credentials in environment variables
255
+ 2. **Private Keys**: Use file paths or environment variables for private keys
256
+ 3. **Network Security**: Use FTPS for FTP connections when possible
257
+ 4. **Access Control**: Implement proper file permissions on SFTP servers
258
+
259
+ ## Troubleshooting
260
+
261
+ ### Common Issues
262
+
263
+ 1. **Connection Timeout**: Increase `timeout` in configuration
264
+ 2. **Authentication Failed**: Check credentials and key permissions
265
+ 3. **Path Issues**: Ensure `basePath` is correctly configured
266
+ 4. **Permission Denied**: Check file/directory permissions on remote servers
267
+
268
+ ### Debug Mode
269
+
270
+ Enable debug logging:
271
+
272
+ ```typescript
273
+ import { logger } from '@things-factory/env'
274
+ logger.level = 'debug'
275
+ ```
276
+
277
+ ## Backward Compatibility
278
+
279
+ The old `SFTPFILESTORAGE` object is still available for backward compatibility, but it's recommended to migrate to the new system for better maintainability and extensibility.
280
+
281
+ ## Migration Addendum (SFTP DB config, formatters, and direct remote writes)
282
+
283
+ ### 5. Store SFTP connection in DB (Sftp entity)
284
+
285
+ New columns were added to the `sftps` table so credentials and connection parameters can be managed per record instead of via config files.
286
+
287
+ - Columns: `password text`, `port integer`, `base_path text`, `timeout integer`, `retries integer`
288
+ - One-time SQL migration (PostgreSQL):
289
+
290
+ ```sql
291
+ BEGIN;
292
+ ALTER TABLE public.sftps
293
+ ADD COLUMN IF NOT EXISTS password text,
294
+ ADD COLUMN IF NOT EXISTS port integer,
295
+ ADD COLUMN IF NOT EXISTS base_path text,
296
+ ADD COLUMN IF NOT EXISTS timeout integer,
297
+ ADD COLUMN IF NOT EXISTS retries integer;
298
+
299
+ -- Optional backfill from folder_path
300
+ UPDATE public.sftps
301
+ SET base_path = folder_path
302
+ WHERE base_path IS NULL
303
+ AND folder_path IS NOT NULL;
304
+ COMMIT;
305
+ ```
306
+
307
+ At runtime, the uploader now builds a `StorageConfig` from the `Sftp` entity when possible (fallback to `sftpExternal` if the record has no credentials). Populate `host`, `port`, `username`, `password`, `basePath`, `timeout`, `retries` in the `sftps` row(s).
308
+
309
+ ### 6. Standardized file formatting (CSV/XML/XLSX)
310
+
311
+ Formatting is centralized in `server/util/file-formatters.ts`:
312
+
313
+ - `formatData(data, contentType)` → returns a CSV/XML string (XLSX currently falls back to CSV)
314
+ - `formatAsCSV`, `formatAsXML`, `parseCSV` helpers
315
+ - Dates are normalized to `YYYY-MM-DD` for CSV/XML when values are `Date` or date-like strings
316
+
317
+ Platform uploaders (e.g., `Yltc.post`) now accept either raw data arrays or preformatted strings and choose the correct extension based on `contentType`.
318
+
319
+ ### 7. API payload adjustments
320
+
321
+ When calling `SftpAPI.createYLTCInventoryReport`, send:
322
+
323
+ - Required: `title` (without extension), `content` (raw array or string), `contentType` (e.g., `'csv'`)
324
+ - Optional: `backupTitle`, `backupPath` (only include if you actually want a backup file)
325
+
326
+ The denormalizer omits undefined optionals so they don’t appear in logs.
327
+
328
+ ### 8. Direct remote writes (no local temp files)
329
+
330
+ The upload utility no longer writes to a local `uploaded-files` directory. Files are written directly to the remote storage:
331
+
332
+ - Ensures remote directory (when `uploadPath` is provided)
333
+ - Builds remote path as `<uploadPath>/<title>` and calls `StorageManager.writeFile(...)`
334
+ - If a provider `basePath` is configured, an empty `uploadPath` writes to the base path root (e.g., `/Staging`)
335
+
336
+ ### 9. Path and environment notes
337
+
338
+ - With `basePath` set (e.g., `/Staging`), pass an empty `uploadPath` to write directly under that folder
339
+ - If you need subfolders, pass `uploadPath: 'subdir'` and the uploader will create it if missing
340
+
341
+ ### 10. Troubleshooting
342
+
343
+ - Enable debug: `DEBUG=things-factory:integration-sftp:*` to see connect and upload traces
344
+ - Look for lines like: `upload content prepared: type=string, contentType=csv, length=..., preview=report_date,...`
345
+ - Connection diagnostics log whether a password/privateKey is present without exposing secrets
346
+
347
+ ### 11. S3 archival of generated files
348
+
349
+ When uploads run via a platform uploader (e.g., YLTC), a best-effort archive copy of the generated file can be written to S3 if `sftpFileStorage` is configured with `type: 's3'`.
350
+
351
+ - Archive key format: `<platform>/<filename>`
352
+ - The `<platform>` prefix is taken from the `platform` column of the `sftps` table row used during the upload (e.g., `yltc`).
353
+ - If `platform` is empty or not provided, a fallback of `yltc` is used.
354
+ - This archive write is independent of the primary upload (SFTP or otherwise). Any S3 archive failure is logged but will not block the main upload.
355
+ - Ensure `sftpFileStorage` includes the correct bucket and region, and that IAM has `s3:PutObject` permission on `arn:aws:s3:::<bucket>/*`. If your bucket enforces server-side encryption, set the following optional fields:
356
+ - `serverSideEncryption: 'AES256'` or `serverSideEncryption: 'aws:kms'`
357
+ - `sseKmsKeyId: '<your-kms-key-arn>'` (when using KMS)
358
+
359
+ Example `sftpFileStorage` for S3 archival:
360
+
361
+ ```js
362
+ // config.development.js
363
+ module.exports = {
364
+ sftpFileStorage: {
365
+ type: 's3',
366
+ accessKeyId: '...',
367
+ secretAccessKey: '...',
368
+ bucketName: 'operato-sftp',
369
+ region: 'ap-southeast-1'
370
+ // optional if bucket enforces SSE
371
+ // serverSideEncryption: 'AES256',
372
+ // sseKmsKeyId: '<kms-key-arn>'
373
+ }
374
+ }
375
+ ```
376
+
8
377
  <!-- ## [Unreleased] -->
@@ -1,15 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Herbalife = void 0;
4
- require("../../sftp-s3");
5
4
  const xml_js_1 = require("xml-js");
6
- const sftp_const_1 = require("../../sftp-const");
5
+ const env_1 = require("@things-factory/env");
6
+ const storage_manager_1 = require("../../storage/storage-manager");
7
7
  const generate_files_1 = require("../../util/generate-files");
8
8
  const debug = require('debug')('things-factory:integration-sftp:herbalife');
9
9
  class Herbalife {
10
- constructor() { }
10
+ constructor() {
11
+ this.storageManager = storage_manager_1.StorageManager.getInstance();
12
+ // Get the SFTP configuration from config
13
+ this.sftpConfig = env_1.config.get('sftpFileStorage');
14
+ }
11
15
  async get(path, data = {}) {
12
- const fileResult = await sftp_const_1.SFTPFILESTORAGE.readFile(path, 'utf-8');
16
+ const fileResult = await this.storageManager.readFile(this.sftpConfig, path, 'utf-8');
13
17
  const item = (0, xml_js_1.xml2js)(fileResult, {
14
18
  compact: true
15
19
  });
@@ -32,7 +36,7 @@ class Herbalife {
32
36
  content
33
37
  });
34
38
  }
35
- await (0, generate_files_1.generateFiles)(params);
39
+ await (0, generate_files_1.generateFiles)(params, this.sftpConfig);
36
40
  return sftp;
37
41
  }
38
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"herbalife.js","sourceRoot":"","sources":["../../../server/controllers/herbalife/herbalife.ts"],"names":[],"mappings":";;;AAAA,yBAAsB;AAEtB,mCAA+B;AAG/B,iDAAkD;AAClD,8DAAyD;AAEzD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,2CAA2C,CAAC,CAAA;AAI3E,MAAa,SAAS;IACpB,gBAAe,CAAC;IAEhB,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,OAAY,EAAE;QACpC,MAAM,UAAU,GAAQ,MAAM,4BAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACrE,MAAM,IAAI,GAAQ,IAAA,eAAM,EAAC,UAAU,EAAE;YACnC,OAAO,EAAE,IAAI;SACd,CAAC,CAAA;QACF,MAAM,MAAM,qBAAa,IAAI,CAAE,CAAA;QAC/B,OAAO,MAAM,CAAA;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAY,EAAE;QACrC,MAAM,EACJ,KAAK,EACL,WAAW,EACX,OAAO,EACP,IAAI,EACJ,UAAU,EACX,GAA4F,IAAI,CAAA;QAEjG,IAAI,MAAM,GAAU;YAClB;gBACE,KAAK;gBACL,UAAU,EAAE,IAAI;gBAChB,OAAO;aACR;SACF,CAAA;QAED,IAAI,UAAU,EAAE;YACd,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,WAAW;gBAClB,UAAU,EAAE,UAAU;gBACtB,OAAO;aACR,CAAC,CAAA;SACH;QACD,MAAM,IAAA,8BAAa,EAAC,MAAM,CAAC,CAAA;QAE3B,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAxCD,8BAwCC"}
1
+ {"version":3,"file":"herbalife.js","sourceRoot":"","sources":["../../../server/controllers/herbalife/herbalife.ts"],"names":[],"mappings":";;;AAAA,mCAA+B;AAC/B,6CAA4C;AAG5C,mEAA8D;AAC9D,8DAAyD;AAEzD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,2CAA2C,CAAC,CAAA;AAI3E,MAAa,SAAS;IAIpB;QAHQ,mBAAc,GAAG,gCAAc,CAAC,WAAW,EAAE,CAAA;QAInD,yCAAyC;QACzC,IAAI,CAAC,UAAU,GAAG,YAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,OAAY,EAAE;QACpC,MAAM,UAAU,GAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;QAC1F,MAAM,IAAI,GAAQ,IAAA,eAAM,EAAC,UAAU,EAAE;YACnC,OAAO,EAAE,IAAI;SACd,CAAC,CAAA;QACF,MAAM,MAAM,qBAAa,IAAI,CAAE,CAAA;QAC/B,OAAO,MAAM,CAAA;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAY,EAAE;QACrC,MAAM,EACJ,KAAK,EACL,WAAW,EACX,OAAO,EACP,IAAI,EACJ,UAAU,EACX,GAA4F,IAAI,CAAA;QAEjG,IAAI,MAAM,GAAU;YAClB;gBACE,KAAK;gBACL,UAAU,EAAE,IAAI;gBAChB,OAAO;aACR;SACF,CAAA;QAED,IAAI,UAAU,EAAE;YACd,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,WAAW;gBAClB,UAAU,EAAE,UAAU;gBACtB,OAAO;aACR,CAAC,CAAA;SACH;QACD,MAAM,IAAA,8BAAa,EAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;QAE5C,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AA9CD,8BA8CC"}
@@ -15,5 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  require("./herbalife");
18
+ require("./yltc");
18
19
  __exportStar(require("./sftp-api"), exports);
19
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uBAAoB;AAEpB,6CAA0B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uBAAoB;AACpB,kBAAe;AAEf,6CAA0B"}
@@ -34,6 +34,7 @@ class SftpAPI {
34
34
  static getOutboundOrder(sftp, req) { }
35
35
  static createShipment(sftp, req) { }
36
36
  static createSerialNumber(sftp, req) { }
37
+ static createYLTCInventoryReport(sftp, req) { }
37
38
  }
38
39
  SftpAPI.platforms = {};
39
40
  __decorate([
@@ -60,5 +61,11 @@ __decorate([
60
61
  __metadata("design:paramtypes", [Object, Object]),
61
62
  __metadata("design:returntype", Object)
62
63
  ], SftpAPI, "createSerialNumber", null);
64
+ __decorate([
65
+ decorators_1.api,
66
+ __metadata("design:type", Function),
67
+ __metadata("design:paramtypes", [Object, Object]),
68
+ __metadata("design:returntype", Object)
69
+ ], SftpAPI, "createYLTCInventoryReport", null);
63
70
  exports.SftpAPI = SftpAPI;
64
71
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/controllers/sftp-api/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAAuC;AAEvC,2CAAoC;AACpC,6CAAkC;AAElC,MAAa,OAAO;IAGlB,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI;QACxC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;YACxB,MAAM;YACN,IAAI;SACL,CAAA;IACH,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,IAAI;QACrB,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;QACrB,MAAM,UAAU,GAAG,IAAA,uBAAa,EAAC,cAAI,CAAC,CAAA;QACtC,OAAO,MAAM,UAAU,CAAC,OAAO,CAAC;YAC9B,KAAK,EAAE,EAAE,EAAE,EAAE;YACb,SAAS,EAAE,CAAC,QAAQ,CAAC;SACtB,CAAC,CAAA;IACJ,CAAC;IAGM,AAAP,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;IAGvB,AAAP,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;IAGnC,AAAP,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;IAGjC,AAAP,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;;AA/BrC,iBAAS,GAAG,EAAE,CAAA;AAsBd;IADN,gBAAG;;;;yBAC0B;AAGvB;IADN,gBAAG;;;;qCACsC;AAGnC;IADN,gBAAG;;;;mCACoC;AAGjC;IADN,gBAAG;;;;uCACwC;AAhC9C,0BAiCC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/controllers/sftp-api/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAAuC;AAEvC,2CAAoC;AACpC,6CAAkC;AAElC,MAAa,OAAO;IAGlB,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI;QACxC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;YACxB,MAAM;YACN,IAAI;SACL,CAAA;IACH,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,IAAI;QACrB,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;QACrB,MAAM,UAAU,GAAG,IAAA,uBAAa,EAAC,cAAI,CAAC,CAAA;QACtC,OAAO,MAAM,UAAU,CAAC,OAAO,CAAC;YAC9B,KAAK,EAAE,EAAE,EAAE,EAAE;YACb,SAAS,EAAE,CAAC,QAAQ,CAAC;SACtB,CAAC,CAAA;IACJ,CAAC;IAGM,AAAP,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;IAGvB,AAAP,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;IAGnC,AAAP,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;IAGjC,AAAP,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;IAGrC,AAAP,MAAM,CAAC,yBAAyB,CAAC,IAAI,EAAE,GAAG,IAAQ,CAAC;;AAlC5C,iBAAS,GAAG,EAAE,CAAA;AAsBd;IADN,gBAAG;;;;yBAC0B;AAGvB;IADN,gBAAG;;;;qCACsC;AAGnC;IADN,gBAAG;;;;mCACoC;AAGjC;IADN,gBAAG;;;;uCACwC;AAGrC;IADN,gBAAG;;;;8CAC+C;AAnCrD,0BAoCC"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createYLTCInventoryReport = void 0;
4
+ function createYLTCInventoryReport() {
5
+ return {
6
+ method: 'post',
7
+ path: '{folderPath}',
8
+ denormalize(req) {
9
+ const { sftp, title, backupTitle, content, backupPath, contentType } = req;
10
+ const { folderPath, platform } = sftp;
11
+ // Values used by platform-action substitute() for path placeholders
12
+ const resource = {
13
+ folderPath: folderPath || ''
14
+ };
15
+ // Build payload with required fields only
16
+ const payload = {
17
+ sftp,
18
+ title,
19
+ content,
20
+ contentType,
21
+ folderPath,
22
+ platform
23
+ };
24
+ // Include optionals only when present
25
+ if (backupTitle)
26
+ payload.backupTitle = backupTitle;
27
+ if (backupPath)
28
+ payload.backupPath = backupPath;
29
+ return {
30
+ resource,
31
+ payload
32
+ };
33
+ },
34
+ normalize(res) {
35
+ return res;
36
+ }
37
+ };
38
+ }
39
+ exports.createYLTCInventoryReport = createYLTCInventoryReport;
40
+ //# sourceMappingURL=create-yltc-inventory-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-yltc-inventory-report.js","sourceRoot":"","sources":["../../../../server/controllers/yltc/apis/create-yltc-inventory-report.ts"],"names":[],"mappings":";;;AAAA,SAAgB,yBAAyB;IACvC,OAAO;QACL,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,cAAc;QACpB,WAAW,CAAC,GAAG;YACb,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,GAAG,CAAA;YAC1E,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;YAErC,oEAAoE;YACpE,MAAM,QAAQ,GAAG;gBACf,UAAU,EAAE,UAAU,IAAI,EAAE;aAC7B,CAAA;YAED,0CAA0C;YAC1C,MAAM,OAAO,GAAQ;gBACnB,IAAI;gBACJ,KAAK;gBACL,OAAO;gBACP,WAAW;gBACX,UAAU;gBACV,QAAQ;aACT,CAAA;YAED,sCAAsC;YACtC,IAAI,WAAW;gBAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAA;YAClD,IAAI,UAAU;gBAAE,OAAO,CAAC,UAAU,GAAG,UAAU,CAAA;YAE/C,OAAO;gBACL,QAAQ;gBACR,OAAO;aACR,CAAA;QACH,CAAC;QACD,SAAS,CAAC,GAAG;YACX,OAAO,GAAG,CAAA;QACZ,CAAC;KACF,CAAA;AACH,CAAC;AApCD,8DAoCC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.echo = void 0;
4
+ function echo() {
5
+ return {
6
+ path: '/echo',
7
+ denormalize(req) {
8
+ return Object.assign({}, req);
9
+ },
10
+ normalize(res) {
11
+ return Object.assign({}, res);
12
+ },
13
+ action({ store, method, path, request, platformAction }) {
14
+ return Object.assign({}, request);
15
+ }
16
+ };
17
+ }
18
+ exports.echo = echo;
19
+ //# sourceMappingURL=echo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"echo.js","sourceRoot":"","sources":["../../../../server/controllers/yltc/apis/echo.ts"],"names":[],"mappings":";;;AAAA,SAAgB,IAAI;IAClB,OAAO;QACL,IAAI,EAAE,OAAO;QACb,WAAW,CAAC,GAAG;YACb,yBAAY,GAAG,EAAE;QACnB,CAAC;QACD,SAAS,CAAC,GAAG;YACX,yBAAY,GAAG,EAAE;QACnB,CAAC;QACD,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE;YACrD,yBAAY,OAAO,EAAE;QACvB,CAAC;KACF,CAAA;AACH,CAAC;AAbD,oBAaC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./echo"), exports);
18
+ __exportStar(require("./create-yltc-inventory-report"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../server/controllers/yltc/apis/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAsB;AACtB,iEAA8C"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const sftp_api_1 = require("../sftp-api");
30
+ const APIS = __importStar(require("./apis"));
31
+ const platform_action_1 = require("./platform-action");
32
+ __exportStar(require("./yltc"), exports);
33
+ sftp_api_1.SftpAPI.registerPlatform('yltc', platform_action_1.action, APIS);
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/controllers/yltc/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0CAAqC;AACrC,6CAA8B;AAC9B,uDAA0C;AAE1C,yCAAsB;AAEtB,kBAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,wBAAM,EAAE,IAAI,CAAC,CAAA"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.action = void 0;
4
+ const yltc_1 = require("./yltc");
5
+ function substitute(path, obj) {
6
+ var props = [];
7
+ var re = /{([^}]+)}/g;
8
+ var text;
9
+ while ((text = re.exec(path))) {
10
+ props.push(text[1]);
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
+ return result;
18
+ }
19
+ const action = async ({ method = 'get', path, request }) => {
20
+ const client = new yltc_1.Yltc();
21
+ const { resource = {}, payload = {} } = request;
22
+ path = substitute(path, resource);
23
+ var response = await client[method](path, payload);
24
+ if (response.errors) {
25
+ throw response;
26
+ }
27
+ return response;
28
+ };
29
+ exports.action = action;
30
+ //# sourceMappingURL=platform-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-action.js","sourceRoot":"","sources":["../../../server/controllers/yltc/platform-action.ts"],"names":[],"mappings":";;;AAAA,iCAA6B;AAE7B,SAAS,UAAU,CAAC,IAAI,EAAE,GAAG;IAC3B,IAAI,KAAK,GAAG,EAAE,CAAA;IACd,IAAI,EAAE,GAAG,YAAY,CAAA;IACrB,IAAI,IAAI,CAAA;IAER,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE;QAC7B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;KACpB;IAED,IAAI,MAAM,GAAG,IAAI,CAAA;IACjB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACnB,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAC5B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IACxE,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AAEM,MAAM,MAAM,GAAG,KAAK,EAAE,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;IAChE,MAAM,MAAM,GAAG,IAAI,WAAI,EAAE,CAAA;IAEzB,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,OAAO,CAAA;IAE/C,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IAEjC,IAAI,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAClD,IAAI,QAAQ,CAAC,MAAM,EAAE;QACnB,MAAM,QAAQ,CAAA;KACf;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAbY,QAAA,MAAM,UAalB"}