@pokash/n8n-nodes-optima-rest-api 1.2.0 → 1.3.0

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.
@@ -491,7 +491,7 @@ class OptimaRestApi {
491
491
  displayName: 'SQL Filter',
492
492
  name: 'filtrSQL',
493
493
  type: 'string',
494
- required: true,
494
+ required: false,
495
495
  displayOptions: {
496
496
  show: {
497
497
  resource: ['print'],
@@ -500,7 +500,7 @@ class OptimaRestApi {
500
500
  },
501
501
  default: '',
502
502
  placeholder: 'TrN_TrnId = 123',
503
- description: 'SQL filter to select documents',
503
+ description: 'SQL filter to select documents (e.g. "TrN_TrNID = 123" or "EDN_EDNId = 1002")',
504
504
  },
505
505
  // Print Format ID
506
506
  {
@@ -517,6 +517,46 @@ class OptimaRestApi {
517
517
  default: 1,
518
518
  description: 'ID of the print format from Optima',
519
519
  },
520
+ // Print Dynamic Parameters
521
+ {
522
+ displayName: 'Dynamic Parameters',
523
+ name: 'dynamicParameters',
524
+ type: 'fixedCollection',
525
+ typeOptions: {
526
+ multipleValues: true,
527
+ },
528
+ displayOptions: {
529
+ show: {
530
+ resource: ['print'],
531
+ operation: ['printDocument'],
532
+ },
533
+ },
534
+ default: {},
535
+ placeholder: 'Add Parameter',
536
+ description: 'Dynamic parameters passed to the print template',
537
+ options: [
538
+ {
539
+ name: 'parameter',
540
+ displayName: 'Parameter',
541
+ values: [
542
+ {
543
+ displayName: 'Name',
544
+ name: 'name',
545
+ type: 'string',
546
+ default: '',
547
+ description: 'Parameter name as defined in the print template',
548
+ },
549
+ {
550
+ displayName: 'Value',
551
+ name: 'value',
552
+ type: 'string',
553
+ default: '',
554
+ description: 'Parameter value',
555
+ },
556
+ ],
557
+ },
558
+ ],
559
+ },
520
560
  ],
521
561
  };
522
562
  }
@@ -531,16 +571,16 @@ class OptimaRestApi {
531
571
  // Create unique cache key based on credentials
532
572
  const loginModel = credentials.loginModel || 'subscription';
533
573
  const cacheKey = `${gatewayUrl}:${credentials.username}:${credentials.company}:${loginModel}`;
534
- // Check if we have a valid cached token
535
- const cached = tokenCache.get(cacheKey);
536
- const now = Date.now();
537
- let token;
538
- if (cached && cached.expiresAt > now) {
539
- // Token still valid, use from cache
540
- token = cached.token;
541
- }
542
- else {
543
- // Token expired or doesn't exist, authenticate
574
+ // Helper function to get or refresh authentication token
575
+ const getAuthToken = async (forceRefresh = false) => {
576
+ // Check cache unless forced refresh
577
+ if (!forceRefresh) {
578
+ const cached = tokenCache.get(cacheKey);
579
+ const now = Date.now();
580
+ if (cached && cached.expiresAt > now) {
581
+ return cached.token;
582
+ }
583
+ }
544
584
  // Build login body based on selected model
545
585
  const loginBody = {
546
586
  username: credentials.username,
@@ -548,11 +588,9 @@ class OptimaRestApi {
548
588
  company: credentials.company,
549
589
  };
550
590
  if (loginModel === 'subscription') {
551
- // Subscription model (Optima 2026+)
552
591
  loginBody.subscriptionPackages = credentials.subscriptionPackages || 'Podstawowy';
553
592
  }
554
593
  else {
555
- // Traditional modules model
556
594
  loginBody.modules = credentials.modules || 'KP';
557
595
  }
558
596
  const loginResponse = await this.helpers.request({
@@ -561,11 +599,43 @@ class OptimaRestApi {
561
599
  body: loginBody,
562
600
  json: true,
563
601
  });
564
- token = loginResponse.Token;
602
+ const token = loginResponse.Token;
565
603
  // Cache token for 50 minutes (assuming 60 min expiry, refresh 10 min early)
604
+ const now = Date.now();
566
605
  const expiresAt = now + (50 * 60 * 1000);
567
606
  tokenCache.set(cacheKey, { token, expiresAt });
568
- }
607
+ return token;
608
+ };
609
+ // Helper function to make authenticated API requests with automatic retry on 401
610
+ const makeAuthenticatedRequest = async (requestOptions) => {
611
+ var _a;
612
+ // Get token
613
+ let token = await getAuthToken();
614
+ // Add authorization header
615
+ const options = {
616
+ ...requestOptions,
617
+ headers: {
618
+ ...requestOptions.headers,
619
+ Authorization: `Bearer ${token}`,
620
+ },
621
+ };
622
+ try {
623
+ // Try the request
624
+ return await this.helpers.request(options);
625
+ }
626
+ catch (error) {
627
+ // Check if it's a 401 error
628
+ if (error.statusCode === 401 || ((_a = error.response) === null || _a === void 0 ? void 0 : _a.statusCode) === 401) {
629
+ // Token expired/invalid - refresh and retry once
630
+ token = await getAuthToken(true);
631
+ // Retry with new token
632
+ options.headers.Authorization = `Bearer ${token}`;
633
+ return await this.helpers.request(options);
634
+ }
635
+ // Re-throw other errors
636
+ throw error;
637
+ }
638
+ };
569
639
  for (let i = 0; i < items.length; i++) {
570
640
  try {
571
641
  if (resource === 'customer') {
@@ -589,12 +659,9 @@ class OptimaRestApi {
589
659
  const url = queryString
590
660
  ? `${gatewayUrl}/api/customer?${queryString}`
591
661
  : `${gatewayUrl}/api/customer`;
592
- const response = await this.helpers.request({
662
+ const response = await makeAuthenticatedRequest({
593
663
  method: 'GET',
594
664
  url,
595
- headers: {
596
- Authorization: `Bearer ${token}`,
597
- },
598
665
  json: true,
599
666
  });
600
667
  // API returns { Success: true, Customers: [...], TotalCount: ... }
@@ -661,12 +728,9 @@ class OptimaRestApi {
661
728
  }
662
729
  else if (operation === 'create') {
663
730
  const customerData = JSON.parse(this.getNodeParameter('customerData', i));
664
- const response = await this.helpers.request({
731
+ const response = await makeAuthenticatedRequest({
665
732
  method: 'POST',
666
733
  url: `${gatewayUrl}/api/customer`,
667
- headers: {
668
- Authorization: `Bearer ${token}`,
669
- },
670
734
  body: customerData,
671
735
  json: true,
672
736
  });
@@ -683,12 +747,9 @@ class OptimaRestApi {
683
747
  const customerData = JSON.parse(this.getNodeParameter('customerData', i));
684
748
  // Add ID to the customer data for PUT request
685
749
  customerData.ID = customerId;
686
- const response = await this.helpers.request({
750
+ const response = await makeAuthenticatedRequest({
687
751
  method: 'PUT',
688
752
  url: `${gatewayUrl}/api/customer`,
689
- headers: {
690
- Authorization: `Bearer ${token}`,
691
- },
692
753
  body: customerData,
693
754
  json: true,
694
755
  });
@@ -702,12 +763,9 @@ class OptimaRestApi {
702
763
  }
703
764
  else if (operation === 'delete') {
704
765
  const customerId = this.getNodeParameter('customerId', i);
705
- await this.helpers.request({
766
+ await makeAuthenticatedRequest({
706
767
  method: 'DELETE',
707
768
  url: `${gatewayUrl}/api/customer/${customerId}`,
708
- headers: {
709
- Authorization: `Bearer ${token}`,
710
- },
711
769
  json: true,
712
770
  });
713
771
  const result = {
@@ -723,12 +781,9 @@ class OptimaRestApi {
723
781
  if (operation === 'createInvoice') {
724
782
  const documentType = this.getNodeParameter('documentType', i);
725
783
  const documentData = JSON.parse(this.getNodeParameter('documentData', i));
726
- const response = await this.helpers.request({
784
+ const response = await makeAuthenticatedRequest({
727
785
  method: 'POST',
728
786
  url: `${gatewayUrl}/api/Documents/Invoice/${documentType}`,
729
- headers: {
730
- Authorization: `Bearer ${token}`,
731
- },
732
787
  body: documentData,
733
788
  json: true,
734
789
  });
@@ -743,12 +798,9 @@ class OptimaRestApi {
743
798
  else if (operation === 'createAdditionalRecord') {
744
799
  const recordType = this.getNodeParameter('recordType', i);
745
800
  const recordData = JSON.parse(this.getNodeParameter('recordData', i));
746
- const response = await this.helpers.request({
801
+ const response = await makeAuthenticatedRequest({
747
802
  method: 'POST',
748
803
  url: `${gatewayUrl}/api/Documents/AdditionalRecords/${recordType}`,
749
- headers: {
750
- Authorization: `Bearer ${token}`,
751
- },
752
804
  body: recordData,
753
805
  json: true,
754
806
  });
@@ -773,12 +825,9 @@ class OptimaRestApi {
773
825
  };
774
826
  const dictConfig = dictionaryEndpoints[operation];
775
827
  if (dictConfig) {
776
- const response = await this.helpers.request({
828
+ const response = await makeAuthenticatedRequest({
777
829
  method: 'GET',
778
830
  url: `${gatewayUrl}/api/${dictConfig.endpoint}`,
779
- headers: {
780
- Authorization: `Bearer ${token}`,
781
- },
782
831
  json: true,
783
832
  });
784
833
  // API returns { Success: true, [DataKey]: [...], TotalCount: ... }
@@ -855,12 +904,9 @@ class OptimaRestApi {
855
904
  const url = queryString
856
905
  ? `${gatewayUrl}/api/product?${queryString}`
857
906
  : `${gatewayUrl}/api/product`;
858
- const response = await this.helpers.request({
907
+ const response = await makeAuthenticatedRequest({
859
908
  method: 'GET',
860
909
  url,
861
- headers: {
862
- Authorization: `Bearer ${token}`,
863
- },
864
910
  json: true,
865
911
  });
866
912
  // API returns { Success: true, Products: [...], TotalCount: ... }
@@ -928,18 +974,26 @@ class OptimaRestApi {
928
974
  }
929
975
  else if (resource === 'print') {
930
976
  if (operation === 'printDocument') {
931
- const filtrSQL = this.getNodeParameter('filtrSQL', i);
977
+ const filtrSQL = this.getNodeParameter('filtrSQL', i, '');
932
978
  const formatId = this.getNodeParameter('formatId', i);
979
+ const dynamicParamsRaw = this.getNodeParameter('dynamicParameters', i, {});
933
980
  const requestBody = {
934
981
  FormatId: formatId,
935
- FiltrSQL: filtrSQL,
936
982
  };
937
- const response = await this.helpers.request({
983
+ if (filtrSQL) {
984
+ requestBody.FiltrSQL = filtrSQL;
985
+ }
986
+ if (dynamicParamsRaw.parameter) {
987
+ const params = dynamicParamsRaw.parameter;
988
+ const dynamicParameters = {};
989
+ for (const p of params) {
990
+ dynamicParameters[p.name] = p.value;
991
+ }
992
+ requestBody.DynamicParameters = dynamicParameters;
993
+ }
994
+ const response = await makeAuthenticatedRequest({
938
995
  method: 'POST',
939
996
  url: `${gatewayUrl}/api/Documents/Print`,
940
- headers: {
941
- Authorization: `Bearer ${token}`,
942
- },
943
997
  body: requestBody,
944
998
  json: false,
945
999
  encoding: null, // Get binary data (PDF file)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pokash/n8n-nodes-optima-rest-api",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "n8n node for Comarch Optima REST API integration",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",