n8n-nodes-prestashop8 1.2.0 → 1.2.3
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/dist/nodes/PrestaShop8/PrestaShop8.node.description.js +36 -8
- package/dist/nodes/PrestaShop8/PrestaShop8.node.js +145 -83
- package/dist/nodes/PrestaShop8/fieldMappings.d.ts +28 -0
- package/dist/nodes/PrestaShop8/fieldMappings.js +76 -0
- package/dist/nodes/PrestaShop8/types.d.ts +1 -0
- package/dist/nodes/PrestaShop8/types.js +4 -2
- package/dist/nodes/PrestaShop8/utils.js +17 -58
- package/package.json +1 -1
|
@@ -154,16 +154,23 @@ exports.PrestaShop8Description = {
|
|
|
154
154
|
placeholder: '[id_DESC] ou [name_ASC]',
|
|
155
155
|
description: 'Sort criteria (e.g. [id_DESC], [name_ASC], [date_add_DESC])',
|
|
156
156
|
},
|
|
157
|
+
{
|
|
158
|
+
displayName: 'Date Format',
|
|
159
|
+
name: 'dateFormat',
|
|
160
|
+
type: 'boolean',
|
|
161
|
+
default: false,
|
|
162
|
+
description: 'Enable date processing in filters (adds date=1 parameter)',
|
|
163
|
+
},
|
|
157
164
|
],
|
|
158
165
|
},
|
|
159
|
-
// Display options (always visible for list/search operations)
|
|
166
|
+
// Display options (always visible for list/search/getById operations)
|
|
160
167
|
{
|
|
161
168
|
displayName: 'Display',
|
|
162
169
|
name: 'display',
|
|
163
170
|
type: 'options',
|
|
164
171
|
displayOptions: {
|
|
165
172
|
show: {
|
|
166
|
-
operation: ['list', 'search'],
|
|
173
|
+
operation: ['list', 'search', 'getById'],
|
|
167
174
|
},
|
|
168
175
|
},
|
|
169
176
|
options: [
|
|
@@ -193,7 +200,7 @@ exports.PrestaShop8Description = {
|
|
|
193
200
|
type: 'string',
|
|
194
201
|
displayOptions: {
|
|
195
202
|
show: {
|
|
196
|
-
operation: ['list', 'search'],
|
|
203
|
+
operation: ['list', 'search', 'getById'],
|
|
197
204
|
display: ['custom'],
|
|
198
205
|
},
|
|
199
206
|
},
|
|
@@ -226,9 +233,13 @@ exports.PrestaShop8Description = {
|
|
|
226
233
|
name: 'field',
|
|
227
234
|
type: 'string',
|
|
228
235
|
default: '',
|
|
229
|
-
required: true,
|
|
230
236
|
placeholder: 'name, reference, price, etc.',
|
|
231
237
|
description: 'Name of field to filter. Examples: name, reference, price, active, id_manufacturer, etc.',
|
|
238
|
+
displayOptions: {
|
|
239
|
+
hide: {
|
|
240
|
+
operator: ['CUSTOM'],
|
|
241
|
+
},
|
|
242
|
+
},
|
|
232
243
|
},
|
|
233
244
|
{
|
|
234
245
|
displayName: 'Operator',
|
|
@@ -237,16 +248,33 @@ exports.PrestaShop8Description = {
|
|
|
237
248
|
options: types_1.FILTER_OPERATORS,
|
|
238
249
|
default: '=',
|
|
239
250
|
noDataExpression: true,
|
|
240
|
-
description: 'Comparison operator for filtering.
|
|
251
|
+
description: 'Comparison operator for filtering. Custom allows you to write your own filter expression.',
|
|
241
252
|
},
|
|
242
253
|
{
|
|
243
254
|
displayName: 'Value',
|
|
244
255
|
name: 'value',
|
|
245
256
|
type: 'string',
|
|
246
257
|
default: '',
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
258
|
+
placeholder: 'search value or interval',
|
|
259
|
+
description: 'Value to search for. Examples: "Product Name", "1" (active), "29.99" (price). For Equal/Not Equal: use "10,20" for intervals (becomes [10,20]).',
|
|
260
|
+
displayOptions: {
|
|
261
|
+
hide: {
|
|
262
|
+
operator: ['IS_EMPTY', 'IS_NOT_EMPTY', 'CUSTOM'],
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
displayName: 'Custom Filter Expression',
|
|
268
|
+
name: 'customFilter',
|
|
269
|
+
type: 'string',
|
|
270
|
+
default: '',
|
|
271
|
+
placeholder: 'filter[name]=[Product]%',
|
|
272
|
+
description: 'Complete filter expression in PrestaShop format. Example: filter[name]=[Product]%, filter[price]=>[100], etc.',
|
|
273
|
+
displayOptions: {
|
|
274
|
+
show: {
|
|
275
|
+
operator: ['CUSTOM'],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
250
278
|
},
|
|
251
279
|
],
|
|
252
280
|
},
|
|
@@ -28,31 +28,18 @@ const n8n_workflow_1 = require("n8n-workflow");
|
|
|
28
28
|
const PrestaShop8_node_description_1 = require("./PrestaShop8.node.description");
|
|
29
29
|
const types_1 = require("./types");
|
|
30
30
|
const utils_1 = require("./utils");
|
|
31
|
-
|
|
32
|
-
function buildHeaders(rawMode) {
|
|
33
|
-
const headers = {};
|
|
34
|
-
if (rawMode) {
|
|
35
|
-
// En mode Raw, demandons explicitement le XML
|
|
36
|
-
headers['Output-Format'] = 'XML';
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
headers['Output-Format'] = 'JSON';
|
|
40
|
-
}
|
|
41
|
-
return headers;
|
|
42
|
-
}
|
|
31
|
+
const fieldMappings_1 = require("./fieldMappings");
|
|
43
32
|
/**
|
|
44
|
-
* Build
|
|
33
|
+
* Build HTTP request options with appropriate headers (consolidated)
|
|
45
34
|
*/
|
|
46
35
|
function buildHttpOptions(method, url, credentials, rawMode, timeout, body) {
|
|
47
36
|
const headers = {};
|
|
48
|
-
//
|
|
49
|
-
if (body &&
|
|
37
|
+
// Add Content-Type for requests with body (POST, PATCH, PUT)
|
|
38
|
+
if (body && ['POST', 'PATCH', 'PUT'].includes(method)) {
|
|
50
39
|
headers['Content-Type'] = 'application/xml';
|
|
51
40
|
}
|
|
52
|
-
// Add Output-Format
|
|
53
|
-
|
|
54
|
-
headers['Output-Format'] = 'JSON';
|
|
55
|
-
}
|
|
41
|
+
// Add Output-Format header based on mode
|
|
42
|
+
headers['Output-Format'] = rawMode ? 'XML' : 'JSON';
|
|
56
43
|
return {
|
|
57
44
|
method,
|
|
58
45
|
url,
|
|
@@ -108,35 +95,7 @@ async function executeHttpRequest(helpers, options, credentials, rawMode, operat
|
|
|
108
95
|
*/
|
|
109
96
|
function collectRequiredFields(executeFunctions, resource, itemIndex) {
|
|
110
97
|
const fieldsToCreate = [];
|
|
111
|
-
const
|
|
112
|
-
products: {
|
|
113
|
-
productName: 'name-1',
|
|
114
|
-
productPrice: 'price',
|
|
115
|
-
productCategoryId: 'id_category_default'
|
|
116
|
-
},
|
|
117
|
-
categories: {
|
|
118
|
-
categoryName: 'name-1',
|
|
119
|
-
categoryParentId: 'id_parent'
|
|
120
|
-
},
|
|
121
|
-
customers: {
|
|
122
|
-
customerFirstname: 'firstname',
|
|
123
|
-
customerLastname: 'lastname',
|
|
124
|
-
customerEmail: 'email'
|
|
125
|
-
},
|
|
126
|
-
addresses: {
|
|
127
|
-
addressFirstname: 'firstname',
|
|
128
|
-
addressLastname: 'lastname',
|
|
129
|
-
addressAddress1: 'address1',
|
|
130
|
-
addressCity: 'city',
|
|
131
|
-
addressCountryId: 'id_country',
|
|
132
|
-
addressCustomerId: 'id_customer'
|
|
133
|
-
},
|
|
134
|
-
manufacturers: {
|
|
135
|
-
manufacturerName: 'name',
|
|
136
|
-
manufacturerActive: 'active'
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
const mappings = fieldMappings[resource];
|
|
98
|
+
const mappings = (0, fieldMappings_1.getFieldMappingsForResource)(resource);
|
|
140
99
|
if (mappings) {
|
|
141
100
|
for (const [inputName, fieldName] of Object.entries(mappings)) {
|
|
142
101
|
const value = executeFunctions.getNodeParameter(inputName, itemIndex, '');
|
|
@@ -311,12 +270,20 @@ class PrestaShop8 {
|
|
|
311
270
|
const advancedOptions = this.getNodeParameter('advancedOptions', i, {});
|
|
312
271
|
const display = this.getNodeParameter('display', i, 'full');
|
|
313
272
|
const customFields = this.getNodeParameter('customFields', i, '');
|
|
314
|
-
const displayValue = display
|
|
315
|
-
|
|
273
|
+
const displayValue = (0, utils_1.processDisplayParameter)(display, resource, customFields);
|
|
274
|
+
const urlParams = {
|
|
316
275
|
limit: advancedOptions.limit,
|
|
317
276
|
sort: advancedOptions.sort,
|
|
318
|
-
|
|
319
|
-
|
|
277
|
+
};
|
|
278
|
+
// Add date=1 parameter if Date Format option is enabled
|
|
279
|
+
if (advancedOptions.dateFormat) {
|
|
280
|
+
urlParams.date = 1;
|
|
281
|
+
}
|
|
282
|
+
// Only add display parameter if not null (minimal mode returns null)
|
|
283
|
+
if (displayValue !== null) {
|
|
284
|
+
urlParams.display = displayValue;
|
|
285
|
+
}
|
|
286
|
+
requestUrl = (0, utils_1.buildUrlWithFilters)(`${credentials.baseUrl}/${resource}`, urlParams, rawMode);
|
|
320
287
|
const timeout = this.getNodeParameter('options.timeout', i, 30000);
|
|
321
288
|
const neverError = this.getNodeParameter('options.response.neverError', i, false);
|
|
322
289
|
const includeResponseHeaders = this.getNodeParameter('options.response.includeResponseHeaders', i, false);
|
|
@@ -331,7 +298,7 @@ class PrestaShop8 {
|
|
|
331
298
|
username: credentials.apiKey,
|
|
332
299
|
password: ''
|
|
333
300
|
},
|
|
334
|
-
headers:
|
|
301
|
+
headers: buildHttpOptions('GET', requestUrl, credentials, rawMode, timeout || 30000).headers,
|
|
335
302
|
timeout: timeout || 30000,
|
|
336
303
|
transformResponse: [(data) => data],
|
|
337
304
|
validateStatus: neverError ? () => true : undefined // Accept all status codes if neverError is true
|
|
@@ -339,7 +306,7 @@ class PrestaShop8 {
|
|
|
339
306
|
requestDebugInfo = captureRequestDebugInfo({
|
|
340
307
|
method: 'GET',
|
|
341
308
|
url: requestUrl,
|
|
342
|
-
headers:
|
|
309
|
+
headers: buildHttpOptions('GET', requestUrl, credentials, rawMode, timeout || 30000).headers,
|
|
343
310
|
timeout: timeout
|
|
344
311
|
}, credentials, rawMode, operation, resource);
|
|
345
312
|
requestHeaders = requestDebugInfo.headers;
|
|
@@ -402,13 +369,18 @@ class PrestaShop8 {
|
|
|
402
369
|
}
|
|
403
370
|
case 'getById': {
|
|
404
371
|
const id = this.getNodeParameter('id', i);
|
|
405
|
-
const
|
|
372
|
+
const display = this.getNodeParameter('display', i, 'full');
|
|
373
|
+
const customFields = this.getNodeParameter('customFields', i, '');
|
|
406
374
|
if (!id) {
|
|
407
375
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'ID required for this operation');
|
|
408
376
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
377
|
+
const displayValue = (0, utils_1.processDisplayParameter)(display, resource, customFields);
|
|
378
|
+
const urlParams = {};
|
|
379
|
+
// Only add display parameter if not null (minimal mode returns null)
|
|
380
|
+
if (displayValue !== null) {
|
|
381
|
+
urlParams.display = displayValue;
|
|
382
|
+
}
|
|
383
|
+
requestUrl = (0, utils_1.buildUrlWithFilters)(`${credentials.baseUrl}/${resource}/${id}`, urlParams, rawMode);
|
|
412
384
|
const timeout = this.getNodeParameter('options.timeout', i, 30000);
|
|
413
385
|
const neverError = this.getNodeParameter('options.response.neverError', i, false);
|
|
414
386
|
const includeResponseHeaders = this.getNodeParameter('options.response.includeResponseHeaders', i, false);
|
|
@@ -537,6 +509,11 @@ class PrestaShop8 {
|
|
|
537
509
|
const advancedOptions = this.getNodeParameter('advancedOptions', i, {});
|
|
538
510
|
const display = this.getNodeParameter('display', i, 'full');
|
|
539
511
|
const customFields = this.getNodeParameter('customFields', i, '');
|
|
512
|
+
// Debug: Log the filters parameter structure
|
|
513
|
+
const showRequestInfo = this.getNodeParameter('options.request.showRequestInfo', i, false);
|
|
514
|
+
if (showRequestInfo) {
|
|
515
|
+
console.log('DEBUG - filtersParam:', JSON.stringify(filtersParam, null, 2));
|
|
516
|
+
}
|
|
540
517
|
const filters = filtersParam.filter || [];
|
|
541
518
|
if (!filters.length) {
|
|
542
519
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one filter is required for search');
|
|
@@ -544,38 +521,123 @@ class PrestaShop8 {
|
|
|
544
521
|
// Build filter parameters for URL
|
|
545
522
|
const filterParams = {};
|
|
546
523
|
for (const filter of filters) {
|
|
547
|
-
if (
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
524
|
+
if (showRequestInfo) {
|
|
525
|
+
console.log('DEBUG - Processing filter:', JSON.stringify(filter, null, 2));
|
|
526
|
+
}
|
|
527
|
+
// Handle CUSTOM filter operator
|
|
528
|
+
if (filter.operator === 'CUSTOM') {
|
|
529
|
+
if (filter.customFilter && filter.customFilter.trim()) {
|
|
530
|
+
// Add custom filter directly to URL without any interpretation
|
|
531
|
+
// User writes exactly what they want: date=1, filter[name]=test, etc.
|
|
532
|
+
const customFilter = filter.customFilter.trim();
|
|
533
|
+
// Parse the custom filter to extract key=value pairs for URL construction
|
|
534
|
+
const parts = customFilter.split('&');
|
|
535
|
+
for (const part of parts) {
|
|
536
|
+
const [key, value] = part.split('=', 2);
|
|
537
|
+
if (key && value !== undefined) {
|
|
538
|
+
filterParams[key.trim()] = value.trim();
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
const key = `filter[${filter.field}]`;
|
|
545
|
+
// Handle different operators with correct PrestaShop formats
|
|
546
|
+
switch (filter.operator) {
|
|
547
|
+
case '=':
|
|
548
|
+
if (filter.value && filter.value.trim()) {
|
|
549
|
+
const value = filter.value.trim();
|
|
550
|
+
// Check if value contains comma for interval (e.g., "10,20" → "[10,20]")
|
|
551
|
+
if (value.includes(',') && !value.startsWith('[')) {
|
|
552
|
+
filterParams[key] = `[${value}]`;
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
filterParams[key] = `[${value}]`;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
break;
|
|
559
|
+
case '!=':
|
|
560
|
+
if (filter.value && filter.value.trim()) {
|
|
561
|
+
const value = filter.value.trim();
|
|
562
|
+
// Check if value contains comma for interval (e.g., "10,20" → "![10,20]")
|
|
563
|
+
if (value.includes(',') && !value.startsWith('[')) {
|
|
564
|
+
filterParams[key] = `![${value}]`;
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
filterParams[key] = `![${value}]`;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
break;
|
|
571
|
+
case '>':
|
|
572
|
+
if (filter.value && filter.value.trim()) {
|
|
573
|
+
filterParams[key] = `>[${filter.value}]`;
|
|
574
|
+
}
|
|
575
|
+
break;
|
|
576
|
+
case '>=':
|
|
577
|
+
if (filter.value && filter.value.trim()) {
|
|
578
|
+
filterParams[key] = `>=[${filter.value}]`;
|
|
579
|
+
}
|
|
580
|
+
break;
|
|
581
|
+
case '<':
|
|
582
|
+
if (filter.value && filter.value.trim()) {
|
|
583
|
+
filterParams[key] = `<[${filter.value}]`;
|
|
584
|
+
}
|
|
585
|
+
break;
|
|
586
|
+
case '<=':
|
|
587
|
+
if (filter.value && filter.value.trim()) {
|
|
588
|
+
filterParams[key] = `<=[${filter.value}]`;
|
|
589
|
+
}
|
|
590
|
+
break;
|
|
591
|
+
case 'CONTAINS':
|
|
592
|
+
if (filter.value && filter.value.trim()) {
|
|
593
|
+
filterParams[key] = `%[${filter.value}]%`;
|
|
594
|
+
}
|
|
595
|
+
break;
|
|
596
|
+
case 'BEGINS':
|
|
597
|
+
if (filter.value && filter.value.trim()) {
|
|
558
598
|
filterParams[key] = `[${filter.value}]%`;
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
599
|
+
}
|
|
600
|
+
break;
|
|
601
|
+
case 'ENDS':
|
|
602
|
+
if (filter.value && filter.value.trim()) {
|
|
603
|
+
filterParams[key] = `%[${filter.value}]`;
|
|
604
|
+
}
|
|
605
|
+
break;
|
|
606
|
+
case 'IS_EMPTY':
|
|
607
|
+
filterParams[key] = `[]`;
|
|
608
|
+
break;
|
|
609
|
+
case 'IS_NOT_EMPTY':
|
|
610
|
+
filterParams[key] = `![]`;
|
|
611
|
+
break;
|
|
612
|
+
default:
|
|
613
|
+
if (filter.value && filter.value.trim()) {
|
|
567
614
|
filterParams[key] = `[${filter.value}]`;
|
|
568
|
-
|
|
615
|
+
}
|
|
569
616
|
}
|
|
570
617
|
}
|
|
571
618
|
// Handle display parameter
|
|
572
619
|
const displayValue = (0, utils_1.processDisplayParameter)(display, resource, customFields);
|
|
573
|
-
|
|
620
|
+
const urlParams = {
|
|
574
621
|
...filterParams,
|
|
575
622
|
limit: advancedOptions.limit,
|
|
576
623
|
sort: advancedOptions.sort,
|
|
577
|
-
|
|
578
|
-
|
|
624
|
+
};
|
|
625
|
+
// Add date=1 parameter if Date Format option is enabled
|
|
626
|
+
if (advancedOptions.dateFormat) {
|
|
627
|
+
urlParams.date = 1;
|
|
628
|
+
}
|
|
629
|
+
// Only add display parameter if not null (minimal mode returns null)
|
|
630
|
+
if (displayValue !== null) {
|
|
631
|
+
urlParams.display = displayValue;
|
|
632
|
+
}
|
|
633
|
+
if (showRequestInfo) {
|
|
634
|
+
console.log('DEBUG - Final filterParams:', JSON.stringify(filterParams, null, 2));
|
|
635
|
+
console.log('DEBUG - Final urlParams:', JSON.stringify(urlParams, null, 2));
|
|
636
|
+
}
|
|
637
|
+
requestUrl = (0, utils_1.buildUrlWithFilters)(`${credentials.baseUrl}/${resource}`, urlParams, rawMode);
|
|
638
|
+
if (showRequestInfo) {
|
|
639
|
+
console.log('DEBUG - Final URL:', requestUrl);
|
|
640
|
+
}
|
|
579
641
|
const timeout = this.getNodeParameter('options.timeout', i, 30000);
|
|
580
642
|
const neverError = this.getNodeParameter('options.response.neverError', i, false);
|
|
581
643
|
const includeResponseHeaders = this.getNodeParameter('options.response.includeResponseHeaders', i, false);
|
|
@@ -590,7 +652,7 @@ class PrestaShop8 {
|
|
|
590
652
|
username: credentials.apiKey,
|
|
591
653
|
password: ''
|
|
592
654
|
},
|
|
593
|
-
headers:
|
|
655
|
+
headers: buildHttpOptions('GET', requestUrl, credentials, rawMode, timeout || 30000).headers,
|
|
594
656
|
timeout: timeout || 30000,
|
|
595
657
|
transformResponse: [(data) => data],
|
|
596
658
|
validateStatus: neverError ? () => true : undefined // Accept all status codes if neverError is true
|
|
@@ -598,7 +660,7 @@ class PrestaShop8 {
|
|
|
598
660
|
requestDebugInfo = captureRequestDebugInfo({
|
|
599
661
|
method: 'GET',
|
|
600
662
|
url: requestUrl,
|
|
601
|
-
headers:
|
|
663
|
+
headers: buildHttpOptions('GET', requestUrl, credentials, rawMode, timeout || 30000).headers,
|
|
602
664
|
timeout: timeout
|
|
603
665
|
}, credentials, rawMode, operation, resource);
|
|
604
666
|
requestHeaders = requestDebugInfo.headers;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized field mappings for PrestaShop resources
|
|
3
|
+
* Eliminates duplication between node and utils files
|
|
4
|
+
*/
|
|
5
|
+
export interface FieldMapping {
|
|
6
|
+
[inputName: string]: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ResourceFieldMappings {
|
|
9
|
+
[resource: string]: FieldMapping;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Input field name to PrestaShop field name mappings for CREATE operations
|
|
13
|
+
*/
|
|
14
|
+
export declare const CREATE_FIELD_MAPPINGS: ResourceFieldMappings;
|
|
15
|
+
/**
|
|
16
|
+
* CamelCase to PrestaShop field name mappings for UPDATE operations
|
|
17
|
+
*/
|
|
18
|
+
export declare const CAMELCASE_TO_PRESTASHOP_MAPPINGS: {
|
|
19
|
+
[key: string]: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Convert camelCase field name to PrestaShop format
|
|
23
|
+
*/
|
|
24
|
+
export declare function convertFromCamelCase(fieldName: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Get field mappings for a specific resource
|
|
27
|
+
*/
|
|
28
|
+
export declare function getFieldMappingsForResource(resource: string): FieldMapping | null;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Centralized field mappings for PrestaShop resources
|
|
4
|
+
* Eliminates duplication between node and utils files
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getFieldMappingsForResource = exports.convertFromCamelCase = exports.CAMELCASE_TO_PRESTASHOP_MAPPINGS = exports.CREATE_FIELD_MAPPINGS = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Input field name to PrestaShop field name mappings for CREATE operations
|
|
10
|
+
*/
|
|
11
|
+
exports.CREATE_FIELD_MAPPINGS = {
|
|
12
|
+
products: {
|
|
13
|
+
productName: 'name-1',
|
|
14
|
+
productPrice: 'price',
|
|
15
|
+
productCategoryId: 'id_category_default'
|
|
16
|
+
},
|
|
17
|
+
categories: {
|
|
18
|
+
categoryName: 'name-1',
|
|
19
|
+
categoryParentId: 'id_parent'
|
|
20
|
+
},
|
|
21
|
+
customers: {
|
|
22
|
+
customerFirstname: 'firstname',
|
|
23
|
+
customerLastname: 'lastname',
|
|
24
|
+
customerEmail: 'email'
|
|
25
|
+
},
|
|
26
|
+
addresses: {
|
|
27
|
+
addressFirstname: 'firstname',
|
|
28
|
+
addressLastname: 'lastname',
|
|
29
|
+
addressAddress1: 'address1',
|
|
30
|
+
addressCity: 'city',
|
|
31
|
+
addressCountryId: 'id_country',
|
|
32
|
+
addressCustomerId: 'id_customer'
|
|
33
|
+
},
|
|
34
|
+
manufacturers: {
|
|
35
|
+
manufacturerName: 'name',
|
|
36
|
+
manufacturerActive: 'active'
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* CamelCase to PrestaShop field name mappings for UPDATE operations
|
|
41
|
+
*/
|
|
42
|
+
exports.CAMELCASE_TO_PRESTASHOP_MAPPINGS = {
|
|
43
|
+
'manufacturerId': 'id_manufacturer',
|
|
44
|
+
'categoryId': 'id_category',
|
|
45
|
+
'supplierId': 'id_supplier',
|
|
46
|
+
'customerId': 'id_customer',
|
|
47
|
+
'addressId': 'id_address',
|
|
48
|
+
'countryId': 'id_country',
|
|
49
|
+
'stateId': 'id_state',
|
|
50
|
+
'zoneId': 'id_zone',
|
|
51
|
+
'currencyId': 'id_currency',
|
|
52
|
+
'languageId': 'id_language',
|
|
53
|
+
'groupId': 'id_group',
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Convert camelCase field name to PrestaShop format
|
|
57
|
+
*/
|
|
58
|
+
function convertFromCamelCase(fieldName) {
|
|
59
|
+
// Check specific mappings first
|
|
60
|
+
if (exports.CAMELCASE_TO_PRESTASHOP_MAPPINGS[fieldName]) {
|
|
61
|
+
return exports.CAMELCASE_TO_PRESTASHOP_MAPPINGS[fieldName];
|
|
62
|
+
}
|
|
63
|
+
// Generic camelCase to snake_case conversion
|
|
64
|
+
return fieldName
|
|
65
|
+
.replace(/([A-Z])/g, '_$1')
|
|
66
|
+
.toLowerCase()
|
|
67
|
+
.replace(/^_/, ''); // Remove leading underscore
|
|
68
|
+
}
|
|
69
|
+
exports.convertFromCamelCase = convertFromCamelCase;
|
|
70
|
+
/**
|
|
71
|
+
* Get field mappings for a specific resource
|
|
72
|
+
*/
|
|
73
|
+
function getFieldMappingsForResource(resource) {
|
|
74
|
+
return exports.CREATE_FIELD_MAPPINGS[resource] || null;
|
|
75
|
+
}
|
|
76
|
+
exports.getFieldMappingsForResource = getFieldMappingsForResource;
|
|
@@ -360,8 +360,10 @@ exports.FILTER_OPERATORS = [
|
|
|
360
360
|
{ name: '≥ Greater than or equal to', value: '>=' },
|
|
361
361
|
{ name: '< Less than', value: '<' },
|
|
362
362
|
{ name: '≤ Less than or equal to', value: '<=' },
|
|
363
|
-
{ name: '∋ Contains', value: '
|
|
364
|
-
{ name: '∌ Does not contain', value: 'NOT LIKE' },
|
|
363
|
+
{ name: '∋ Contains', value: 'CONTAINS' },
|
|
365
364
|
{ name: '↦ Starts with', value: 'BEGINS' },
|
|
366
365
|
{ name: '↤ Ends with', value: 'ENDS' },
|
|
366
|
+
{ name: '∅ Is Empty', value: 'IS_EMPTY' },
|
|
367
|
+
{ name: '∄ Is not Empty', value: 'IS_NOT_EMPTY' },
|
|
368
|
+
{ name: '⚙️ Custom Filter', value: 'CUSTOM' },
|
|
367
369
|
];
|
|
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.validateDataForResource = exports.validateFieldsForCreate = exports.REQUIRED_FIELDS_BY_RESOURCE = exports.buildUpdateXml = exports.buildCreateXml = exports.buildUrlWithFilters = exports.parseXmlToJson = exports.buildPrestashopXml = exports.simplifyPrestashopResponse = exports.processResponseForMode = exports.processDisplayParameter = exports.processSortParameter = exports.extractPrestashopError = void 0;
|
|
27
27
|
const xml2js = __importStar(require("xml2js"));
|
|
28
28
|
const js2xmlparser = __importStar(require("js2xmlparser"));
|
|
29
|
+
const fieldMappings_1 = require("./fieldMappings");
|
|
29
30
|
/**
|
|
30
31
|
* Clean error message by removing PHP warnings and debug info
|
|
31
32
|
*/
|
|
@@ -67,10 +68,8 @@ function extractPrestashopError(error) {
|
|
|
67
68
|
// If it's an axios error with response
|
|
68
69
|
if (error.response && error.response.data) {
|
|
69
70
|
const data = error.response.data;
|
|
70
|
-
// Debug logging for complex error structures
|
|
71
|
-
|
|
72
|
-
console.log('PrestaShop Error Structure:', JSON.stringify(data, null, 2));
|
|
73
|
-
}
|
|
71
|
+
// Debug logging for complex error structures (only in debug mode)
|
|
72
|
+
// Note: Removed console.log to prevent production log pollution
|
|
74
73
|
// Try to parse XML error response
|
|
75
74
|
if (typeof data === 'string' && data.includes('<error>')) {
|
|
76
75
|
const errorMatch = data.match(/<error><!\[CDATA\[(.+?)\]\]><\/error>/);
|
|
@@ -342,7 +341,7 @@ function convertSimplifiedToPrestaShop(data, resource) {
|
|
|
342
341
|
const converted = {};
|
|
343
342
|
const associations = {};
|
|
344
343
|
for (const [key, value] of Object.entries(data)) {
|
|
345
|
-
const prestashopKey = convertFromCamelCase(key);
|
|
344
|
+
const prestashopKey = (0, fieldMappings_1.convertFromCamelCase)(key);
|
|
346
345
|
// Detect associations (arrays of IDs)
|
|
347
346
|
if (Array.isArray(value) && value.every(v => typeof v === 'number' || typeof v === 'string')) {
|
|
348
347
|
associations[prestashopKey] = {
|
|
@@ -359,38 +358,7 @@ function convertSimplifiedToPrestaShop(data, resource) {
|
|
|
359
358
|
}
|
|
360
359
|
return converted;
|
|
361
360
|
}
|
|
362
|
-
|
|
363
|
-
* Converts camelCase to snake_case with PrestaShop prefixes
|
|
364
|
-
*/
|
|
365
|
-
function convertFromCamelCase(fieldName) {
|
|
366
|
-
// Map certain special fields
|
|
367
|
-
const fieldMappings = {
|
|
368
|
-
'manufacturerId': 'id_manufacturer',
|
|
369
|
-
'categoryId': 'id_category',
|
|
370
|
-
'supplierId': 'id_supplier',
|
|
371
|
-
'customerId': 'id_customer',
|
|
372
|
-
'orderId': 'id_order',
|
|
373
|
-
'productId': 'id_product',
|
|
374
|
-
'carrierId': 'id_carrier',
|
|
375
|
-
'currencyId': 'id_currency',
|
|
376
|
-
'languageId': 'id_language',
|
|
377
|
-
'shopId': 'id_shop',
|
|
378
|
-
'taxId': 'id_tax',
|
|
379
|
-
'zoneId': 'id_zone',
|
|
380
|
-
'countryId': 'id_country',
|
|
381
|
-
'stateId': 'id_state',
|
|
382
|
-
'addressId': 'id_address',
|
|
383
|
-
'groupId': 'id_group',
|
|
384
|
-
};
|
|
385
|
-
if (fieldMappings[fieldName]) {
|
|
386
|
-
return fieldMappings[fieldName];
|
|
387
|
-
}
|
|
388
|
-
// Generic camelCase to snake_case conversion
|
|
389
|
-
return fieldName
|
|
390
|
-
.replace(/([A-Z])/g, '_$1')
|
|
391
|
-
.toLowerCase()
|
|
392
|
-
.replace(/^_/, '');
|
|
393
|
-
}
|
|
361
|
+
// convertFromCamelCase function moved to fieldMappings.ts for centralization
|
|
394
362
|
/**
|
|
395
363
|
* Obtient tous les champs string pour CDATA
|
|
396
364
|
*/
|
|
@@ -429,30 +397,21 @@ exports.parseXmlToJson = parseXmlToJson;
|
|
|
429
397
|
function buildUrlWithFilters(baseUrl, options, rawMode) {
|
|
430
398
|
const url = new URL(baseUrl);
|
|
431
399
|
const params = new URLSearchParams();
|
|
432
|
-
//
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
if (
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
400
|
+
// Add all parameters from options object
|
|
401
|
+
for (const [key, value] of Object.entries(options)) {
|
|
402
|
+
if (value !== null && value !== undefined && value !== '') {
|
|
403
|
+
if (key === 'sort') {
|
|
404
|
+
// Special handling for sort parameter
|
|
405
|
+
const normalizedSort = processSortParameter(String(value));
|
|
406
|
+
if (normalizedSort)
|
|
407
|
+
params.append('sort', normalizedSort);
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
// Add all other parameters as-is (including custom user parameters)
|
|
411
|
+
params.append(key, String(value));
|
|
443
412
|
}
|
|
444
413
|
}
|
|
445
414
|
}
|
|
446
|
-
// Add other parameters
|
|
447
|
-
if (options.limit)
|
|
448
|
-
params.append('limit', options.limit);
|
|
449
|
-
if (options.sort) {
|
|
450
|
-
const normalizedSort = processSortParameter(options.sort);
|
|
451
|
-
if (normalizedSort)
|
|
452
|
-
params.append('sort', normalizedSort);
|
|
453
|
-
}
|
|
454
|
-
if (options.display !== null && options.display !== undefined)
|
|
455
|
-
params.append('display', options.display);
|
|
456
415
|
// Ajouter output_format seulement si pas en mode Raw
|
|
457
416
|
if (!rawMode) {
|
|
458
417
|
params.append('output_format', 'JSON');
|
package/package.json
CHANGED