@ixiam/n8n-nodes-civicrm 1.1.41 → 2.1.2

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.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CiviCrm = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
4
5
  const GenericFunctions_1 = require("../transport/GenericFunctions");
5
6
  const resources_1 = require("./descriptions/resources");
6
7
  const generic_1 = require("./descriptions/generic");
@@ -59,8 +60,9 @@ class CiviCrm {
59
60
  'Includes dynamic mapping of email, phone, address and location types.\n' +
60
61
  'Includes birth_date validation and JSON filters for GET MANY.\n',
61
62
  defaults: { name: 'CiviCRM' },
62
- inputs: ['main'],
63
- outputs: ['main'],
63
+ subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
64
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
65
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
64
66
  // @ts-ignore
65
67
  usableAsTool: true,
66
68
  // @ts-ignore
@@ -559,12 +561,11 @@ class CiviCrm {
559
561
  this.methods = {
560
562
  loadOptions: {
561
563
  async loadOptionValues() {
562
- const { url, apiKey } = (await this.getCredentials('civiCrmApi'));
563
- const res = await this.helpers.httpRequest({
564
+ const { baseUrl } = (await this.getCredentials('civiCrmApi'));
565
+ const res = await this.helpers.httpRequestWithAuthentication.call(this, 'civiCrmApi', {
564
566
  method: 'POST',
565
- url: `${url.replace(/\/$/, '')}/civicrm/ajax/api4/OptionValue/get`,
567
+ url: `${baseUrl.replace(/\/$/, '')}/civicrm/ajax/api4/OptionValue/get`,
566
568
  headers: {
567
- Authorization: `Bearer ${apiKey}`,
568
569
  'Content-Type': 'application/x-www-form-urlencoded',
569
570
  },
570
571
  body: { params: JSON.stringify({ limit: 50, select: ['id', 'label'] }) },
@@ -588,496 +589,505 @@ class CiviCrm {
588
589
  const out = [];
589
590
  const resource = this.getNodeParameter('resource', 0);
590
591
  const operation = this.getNodeParameter('operation', 0);
591
- // Custom API call: generic passthrough to any API4 entity/action
592
- if (resource === 'customApi') {
593
- const entity = this.getNodeParameter('customEntity', 0);
594
- const action = this.getNodeParameter('customAction', 0);
595
- const paramsJson = this.getNodeParameter('customParamsJson', 0, '');
596
- let params = {};
597
- if (paramsJson) {
598
- try {
599
- params = JSON.parse(paramsJson);
600
- }
601
- catch (error) {
602
- throw new Error('Invalid JSON in "Params (JSON)"');
603
- }
604
- }
605
- const res = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/${action}`, params);
606
- // Return the raw API4 response so advanced users can work with values and metadata
607
- out.push({
608
- json: res,
609
- pairedItem: { item: 0 },
610
- });
611
- return [out];
612
- }
613
- const entity = ENTITY_MAP[resource];
592
+ const entity = resource !== 'customApi' ? ENTITY_MAP[resource] : '';
614
593
  for (let i = 0; i < items.length; i++) {
615
- const emailLocationParam = this.getNodeParameter('emailLocation', i, 'Work');
616
- const phoneLocationParam = this.getNodeParameter('phoneLocation', i, 'Work');
617
- const addressLocationParam = this.getNodeParameter('addressLocation', i, 'Home');
618
- const isPrimaryEmail = this.getNodeParameter('isPrimaryEmail', i, true);
619
- const isPrimaryPhone = this.getNodeParameter('isPrimaryPhone', i, true);
620
- const isPrimaryAddress = this.getNodeParameter('isPrimaryAddress', i, true);
621
- let emailLocationName = emailLocationParam;
622
- let phoneLocationName = phoneLocationParam;
623
- let addressLocationName = addressLocationParam;
624
- /* ======================================================
625
- GET
626
- ====================================================== */
627
- if (operation === 'get') {
628
- const id = this.getNodeParameter('id', i);
629
- const params = resource === 'contact'
630
- ? {
631
- where: [['id', '=', id]],
632
- limit: 1,
633
- select: [
634
- 'id',
635
- 'display_name',
636
- 'first_name',
637
- 'last_name',
638
- 'organization_name',
639
- 'legal_name',
640
- 'contact_type',
641
- 'gender_id',
642
- 'gender_id:name',
643
- 'birth_date',
644
- ],
645
- chain: {
646
- emails: ['Email', 'get', { where: [['contact_id', '=', '$id']] }],
647
- phones: ['Phone', 'get', { where: [['contact_id', '=', '$id']] }],
648
- addresses: ['Address', 'get', { where: [['contact_id', '=', '$id']] }],
649
- },
650
- }
651
- : {
652
- where: [['id', '=', id]],
653
- limit: 1,
654
- select: ['id', 'name', 'title', 'subject', 'display_name'],
655
- };
656
- const res = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/get`, params);
657
- out.push({
658
- json: (_b = (_a = res === null || res === void 0 ? void 0 : res.values) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : {},
659
- pairedItem: { item: i },
660
- });
661
- continue;
662
- }
663
- /* ======================================================
664
- GET MANY
665
- ====================================================== */
666
- if (operation === 'getMany') {
667
- const limit = this.getNodeParameter('limit', i, 100);
668
- const returnAll = this.getNodeParameter('returnAll', i, false);
669
- const whereJson = this.getNodeParameter('whereJson', i, '');
670
- let where = [];
671
- if (whereJson) {
672
- try {
673
- where = JSON.parse(whereJson);
674
- }
675
- catch (error) {
676
- throw new Error('Invalid JSON in whereJson');
594
+ try {
595
+ // Custom API call: generic passthrough to any API4 entity/action
596
+ if (resource === 'customApi') {
597
+ const customEntity = this.getNodeParameter('customEntity', i);
598
+ const action = this.getNodeParameter('customAction', i);
599
+ const paramsJson = this.getNodeParameter('customParamsJson', i, '');
600
+ let params = {};
601
+ if (paramsJson) {
602
+ try {
603
+ params = JSON.parse(paramsJson);
604
+ }
605
+ catch (error) {
606
+ throw new Error('Invalid JSON in "Params (JSON)"');
607
+ }
677
608
  }
609
+ const res = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${customEntity}/${action}`, params);
610
+ // Return the raw API4 response so advanced users can work with values and metadata
611
+ out.push({
612
+ json: res,
613
+ pairedItem: { item: i },
614
+ });
615
+ continue;
678
616
  }
679
- if (resource === 'contact') {
680
- const contactType = this.getNodeParameter('contactType', i, '');
681
- if (contactType)
682
- where.push(['contact_type', '=', contactType]);
617
+ const emailLocationParam = this.getNodeParameter('emailLocation', i, 'Work');
618
+ const phoneLocationParam = this.getNodeParameter('phoneLocation', i, 'Work');
619
+ const addressLocationParam = this.getNodeParameter('addressLocation', i, 'Home');
620
+ const isPrimaryEmail = this.getNodeParameter('isPrimaryEmail', i, true);
621
+ const isPrimaryPhone = this.getNodeParameter('isPrimaryPhone', i, true);
622
+ const isPrimaryAddress = this.getNodeParameter('isPrimaryAddress', i, true);
623
+ let emailLocationName = emailLocationParam;
624
+ let phoneLocationName = phoneLocationParam;
625
+ let addressLocationName = addressLocationParam;
626
+ /* ======================================================
627
+ GET
628
+ ====================================================== */
629
+ if (operation === 'get') {
630
+ const id = this.getNodeParameter('id', i);
631
+ const params = resource === 'contact'
632
+ ? {
633
+ where: [['id', '=', id]],
634
+ limit: 1,
635
+ select: [
636
+ 'id',
637
+ 'display_name',
638
+ 'first_name',
639
+ 'last_name',
640
+ 'organization_name',
641
+ 'legal_name',
642
+ 'contact_type',
643
+ 'gender_id',
644
+ 'gender_id:name',
645
+ 'birth_date',
646
+ ],
647
+ chain: {
648
+ emails: ['Email', 'get', { where: [['contact_id', '=', '$id']] }],
649
+ phones: ['Phone', 'get', { where: [['contact_id', '=', '$id']] }],
650
+ addresses: ['Address', 'get', { where: [['contact_id', '=', '$id']] }],
651
+ },
652
+ }
653
+ : {
654
+ where: [['id', '=', id]],
655
+ limit: 1,
656
+ select: ['id', 'name', 'title', 'subject', 'display_name'],
657
+ };
658
+ const res = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/get`, params);
659
+ out.push({
660
+ json: (_b = (_a = res === null || res === void 0 ? void 0 : res.values) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : {},
661
+ pairedItem: { item: i },
662
+ });
663
+ continue;
683
664
  }
684
- const params = resource === 'contact'
685
- ? {
686
- where,
687
- select: [
688
- 'id',
689
- 'display_name',
690
- 'first_name',
691
- 'last_name',
692
- 'organization_name',
693
- 'legal_name',
694
- 'contact_type',
695
- 'gender_id',
696
- 'gender_id:name',
697
- 'birth_date',
698
- ],
699
- chain: {
700
- emails: ['Email', 'get', { where: [['contact_id', '=', '$id']] }],
701
- phones: ['Phone', 'get', { where: [['contact_id', '=', '$id']] }],
702
- addresses: ['Address', 'get', { where: [['contact_id', '=', '$id']] }],
703
- },
665
+ /* ======================================================
666
+ GET MANY
667
+ ====================================================== */
668
+ if (operation === 'getMany') {
669
+ const limit = this.getNodeParameter('limit', i, 100);
670
+ const returnAll = this.getNodeParameter('returnAll', i, false);
671
+ const whereJson = this.getNodeParameter('whereJson', i, '');
672
+ let where = [];
673
+ if (whereJson) {
674
+ try {
675
+ where = JSON.parse(whereJson);
676
+ }
677
+ catch (error) {
678
+ throw new Error('Invalid JSON in whereJson');
679
+ }
680
+ }
681
+ if (resource === 'contact') {
682
+ const contactType = this.getNodeParameter('contactType', i, '');
683
+ if (contactType)
684
+ where.push(['contact_type', '=', contactType]);
685
+ }
686
+ const params = resource === 'contact'
687
+ ? {
688
+ where,
689
+ select: [
690
+ 'id',
691
+ 'display_name',
692
+ 'first_name',
693
+ 'last_name',
694
+ 'organization_name',
695
+ 'legal_name',
696
+ 'contact_type',
697
+ 'gender_id',
698
+ 'gender_id:name',
699
+ 'birth_date',
700
+ ],
701
+ chain: {
702
+ emails: ['Email', 'get', { where: [['contact_id', '=', '$id']] }],
703
+ phones: ['Phone', 'get', { where: [['contact_id', '=', '$id']] }],
704
+ addresses: ['Address', 'get', { where: [['contact_id', '=', '$id']] }],
705
+ },
706
+ }
707
+ : {
708
+ where,
709
+ select: ['id', 'name', 'title', 'subject', 'display_name'],
710
+ };
711
+ if (returnAll) {
712
+ let offset = 0;
713
+ const page = 500;
714
+ let hasMore = true;
715
+ while (hasMore) {
716
+ const r = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/get`, { ...params, limit: page, offset });
717
+ const vals = (_c = r === null || r === void 0 ? void 0 : r.values) !== null && _c !== void 0 ? _c : [];
718
+ for (const v of vals) {
719
+ out.push({
720
+ json: v,
721
+ pairedItem: { item: i },
722
+ });
723
+ }
724
+ if (vals.length < page) {
725
+ hasMore = false;
726
+ }
727
+ else {
728
+ offset += page;
729
+ }
730
+ }
704
731
  }
705
- : {
706
- where,
707
- select: ['id', 'name', 'title', 'subject', 'display_name'],
708
- };
709
- if (returnAll) {
710
- let offset = 0;
711
- const page = 500;
712
- let hasMore = true;
713
- while (hasMore) {
714
- const r = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/get`, { ...params, limit: page, offset });
715
- const vals = (_c = r === null || r === void 0 ? void 0 : r.values) !== null && _c !== void 0 ? _c : [];
732
+ else {
733
+ const r = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/get`, { ...params, limit });
734
+ const vals = (_d = r === null || r === void 0 ? void 0 : r.values) !== null && _d !== void 0 ? _d : [];
716
735
  for (const v of vals) {
717
736
  out.push({
718
737
  json: v,
719
738
  pairedItem: { item: i },
720
739
  });
721
740
  }
722
- if (vals.length < page) {
723
- hasMore = false;
724
- }
725
- else {
726
- offset += page;
727
- }
728
- }
729
- }
730
- else {
731
- const r = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/get`, { ...params, limit });
732
- const vals = (_d = r === null || r === void 0 ? void 0 : r.values) !== null && _d !== void 0 ? _d : [];
733
- for (const v of vals) {
734
- out.push({
735
- json: v,
736
- pairedItem: { item: i },
737
- });
738
- }
739
- }
740
- continue;
741
- }
742
- /* ======================================================
743
- DELETE
744
- ====================================================== */
745
- if (operation === 'delete') {
746
- const id = this.getNodeParameter('id', i);
747
- const r = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/delete`, {
748
- where: [['id', '=', id]],
749
- });
750
- out.push({
751
- json: {
752
- success: true,
753
- message: `${entity} ${id} deleted`,
754
- deleted_id: id,
755
- api_response: r,
756
- },
757
- pairedItem: { item: i },
758
- });
759
- continue;
760
- }
761
- /* ======================================================
762
- CREATE / UPDATE
763
- ====================================================== */
764
- const isCreate = operation === 'create';
765
- const id = !isCreate ? this.getNodeParameter('id', i) : undefined;
766
- const pairs = this.getNodeParameter('fields.field', i, []);
767
- const values = {};
768
- const emailData = {};
769
- const phoneData = {};
770
- const addressData = {};
771
- let locationTypeMap = {};
772
- if (resource === 'contact') {
773
- locationTypeMap = await getLocationTypeMap.call(this);
774
- }
775
- for (const p of pairs) {
776
- if (!p.fieldName)
777
- continue;
778
- const key = p.fieldName.trim();
779
- const rawVal = convertValue(p.fieldValue);
780
- const val = rawVal;
781
- /* Email simple */
782
- if (key === 'email') {
783
- if (val !== '' && val !== null && val !== undefined) {
784
- emailData.email = val;
785
741
  }
786
742
  continue;
787
743
  }
788
- if (key.startsWith('email.')) {
789
- if (val !== '' && val !== null && val !== undefined) {
790
- emailData[key.replace(/^email\./, '')] = val;
791
- }
744
+ /* ======================================================
745
+ DELETE
746
+ ====================================================== */
747
+ if (operation === 'delete') {
748
+ const id = this.getNodeParameter('id', i);
749
+ const r = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/delete`, {
750
+ where: [['id', '=', id]],
751
+ });
752
+ out.push({
753
+ json: {
754
+ success: true,
755
+ message: `${entity} ${id} deleted`,
756
+ deleted_id: id,
757
+ api_response: r,
758
+ },
759
+ pairedItem: { item: i },
760
+ });
792
761
  continue;
793
762
  }
794
- /* Phone simple */
795
- if (key === 'phone') {
796
- if (val !== '' && val !== null && val !== undefined) {
797
- phoneData.phone = val;
798
- }
799
- continue;
763
+ /* ======================================================
764
+ CREATE / UPDATE
765
+ ====================================================== */
766
+ const isCreate = operation === 'create';
767
+ const id = !isCreate ? this.getNodeParameter('id', i) : undefined;
768
+ const pairs = this.getNodeParameter('fields.field', i, []);
769
+ const values = {};
770
+ const emailData = {};
771
+ const phoneData = {};
772
+ const addressData = {};
773
+ let locationTypeMap = {};
774
+ if (resource === 'contact') {
775
+ locationTypeMap = await getLocationTypeMap.call(this);
800
776
  }
801
- if (key.startsWith('phone.')) {
802
- if (val !== '' && val !== null && val !== undefined) {
803
- phoneData[key.replace(/^phone\./, '')] = val;
777
+ for (const p of pairs) {
778
+ if (!p.fieldName)
779
+ continue;
780
+ const key = p.fieldName.trim();
781
+ const rawVal = convertValue(p.fieldValue);
782
+ const val = rawVal;
783
+ /* Email simple */
784
+ if (key === 'email') {
785
+ if (val !== '' && val !== null && val !== undefined) {
786
+ emailData.email = val;
787
+ }
788
+ continue;
804
789
  }
805
- continue;
806
- }
807
- /* Address */
808
- if (key.startsWith('address.')) {
809
- if (val !== '' && val !== null && val !== undefined) {
810
- addressData[key.replace(/^address\./, '')] = val;
790
+ if (key.startsWith('email.')) {
791
+ if (val !== '' && val !== null && val !== undefined) {
792
+ emailData[key.replace(/^email\./, '')] = val;
793
+ }
794
+ continue;
811
795
  }
812
- continue;
813
- }
814
- /* Prefijo dinámico */
815
- const segments = key.split('.');
816
- if (segments.length >= 2 && resource === 'contact') {
817
- const prefixRaw = segments[0];
818
- const root = segments[1];
819
- const subfield = segments.slice(2).join('.') || '';
820
- const normalizedPrefix = normalizeLocationKey(prefixRaw);
821
- const mappedLocationName = locationTypeMap[normalizedPrefix];
822
- if (root === 'email' || root === 'phone' || root === 'address') {
823
- if (mappedLocationName) {
824
- if (root === 'email')
825
- emailLocationName = mappedLocationName;
826
- if (root === 'phone')
827
- phoneLocationName = mappedLocationName;
828
- if (root === 'address')
829
- addressLocationName = mappedLocationName;
796
+ /* Phone simple */
797
+ if (key === 'phone') {
798
+ if (val !== '' && val !== null && val !== undefined) {
799
+ phoneData.phone = val;
830
800
  }
831
- if (root === 'email') {
832
- if (val !== '' && val !== null && val !== undefined) {
833
- if (!subfield)
834
- emailData.email = val;
835
- else
836
- emailData[subfield] = val;
837
- }
838
- continue;
801
+ continue;
802
+ }
803
+ if (key.startsWith('phone.')) {
804
+ if (val !== '' && val !== null && val !== undefined) {
805
+ phoneData[key.replace(/^phone\./, '')] = val;
839
806
  }
840
- if (root === 'phone') {
841
- if (val !== '' && val !== null && val !== undefined) {
842
- if (!subfield)
843
- phoneData.phone = val;
844
- else
845
- phoneData[subfield] = val;
846
- }
847
- continue;
807
+ continue;
808
+ }
809
+ /* Address */
810
+ if (key.startsWith('address.')) {
811
+ if (val !== '' && val !== null && val !== undefined) {
812
+ addressData[key.replace(/^address\./, '')] = val;
848
813
  }
849
- if (root === 'address') {
850
- if (val !== '' && val !== null && val !== undefined) {
851
- if (subfield)
852
- addressData[subfield] = val;
814
+ continue;
815
+ }
816
+ /* Dynamic prefix: resolve location type from field name */
817
+ const segments = key.split('.');
818
+ if (segments.length >= 2 && resource === 'contact') {
819
+ const prefixRaw = segments[0];
820
+ const root = segments[1];
821
+ const subfield = segments.slice(2).join('.') || '';
822
+ const normalizedPrefix = normalizeLocationKey(prefixRaw);
823
+ const mappedLocationName = locationTypeMap[normalizedPrefix];
824
+ if (root === 'email' || root === 'phone' || root === 'address') {
825
+ if (mappedLocationName) {
826
+ if (root === 'email')
827
+ emailLocationName = mappedLocationName;
828
+ if (root === 'phone')
829
+ phoneLocationName = mappedLocationName;
830
+ if (root === 'address')
831
+ addressLocationName = mappedLocationName;
832
+ }
833
+ if (root === 'email') {
834
+ if (val !== '' && val !== null && val !== undefined) {
835
+ if (!subfield)
836
+ emailData.email = val;
837
+ else
838
+ emailData[subfield] = val;
839
+ }
840
+ continue;
841
+ }
842
+ if (root === 'phone') {
843
+ if (val !== '' && val !== null && val !== undefined) {
844
+ if (!subfield)
845
+ phoneData.phone = val;
846
+ else
847
+ phoneData[subfield] = val;
848
+ }
849
+ continue;
850
+ }
851
+ if (root === 'address') {
852
+ if (val !== '' && val !== null && val !== undefined) {
853
+ if (subfield)
854
+ addressData[subfield] = val;
855
+ }
856
+ continue;
853
857
  }
854
- continue;
855
858
  }
856
859
  }
857
- }
858
- /* gender */
859
- if (key === 'gender' || key === 'gender_id') {
860
- if (val !== '' && val !== null && val !== undefined) {
861
- values.gender_id = val;
860
+ /* gender */
861
+ if (key === 'gender' || key === 'gender_id') {
862
+ if (val !== '' && val !== null && val !== undefined) {
863
+ values.gender_id = val;
864
+ }
865
+ continue;
862
866
  }
863
- continue;
864
- }
865
- /* birth_date */
866
- if (key === 'birth_date' || key === 'birth') {
867
+ /* birth_date */
868
+ if (key === 'birth_date' || key === 'birth') {
869
+ if (val !== '' && val !== null && val !== undefined) {
870
+ values.birth_date = normalizeBirthDate(String(val));
871
+ }
872
+ continue;
873
+ }
874
+ /* default */
867
875
  if (val !== '' && val !== null && val !== undefined) {
868
- values.birth_date = normalizeBirthDate(String(val));
876
+ values[key] = val;
869
877
  }
870
- continue;
871
- }
872
- /* default */
873
- if (val !== '' && val !== null && val !== undefined) {
874
- values[key] = val;
875
878
  }
876
- }
877
- /* Contact type */
878
- const contactType = this.getNodeParameter('contactType', i, '');
879
- if (resource === 'contact' && contactType) {
880
- values.contact_type = contactType;
881
- }
882
- /* CREATE/UPDATE contact */
883
- let contactId = id;
884
- if (isCreate) {
885
- const r = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Contact/create', { values });
886
- contactId = (_f = (_e = r === null || r === void 0 ? void 0 : r.values) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.id;
887
- if (!contactId)
888
- throw new Error('Failed to create contact.');
889
- }
890
- else {
891
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/update`, {
892
- values,
893
- where: [['id', '=', contactId]],
894
- });
895
- }
896
- /* SUBENTITIES */
897
- if (resource === 'contact') {
898
- if (isCreate && isPrimaryEmail) {
899
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/delete', {
900
- where: [
901
- ['contact_id', '=', contactId],
902
- ['is_primary', '=', true],
903
- ],
904
- });
879
+ /* Contact type */
880
+ const contactType = this.getNodeParameter('contactType', i, '');
881
+ if (resource === 'contact' && contactType) {
882
+ values.contact_type = contactType;
905
883
  }
906
- if (isCreate && isPrimaryPhone) {
907
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/delete', {
908
- where: [
909
- ['contact_id', '=', contactId],
910
- ['is_primary', '=', true],
911
- ],
912
- });
884
+ /* CREATE/UPDATE contact */
885
+ let contactId = id;
886
+ if (isCreate) {
887
+ const r = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Contact/create', { values });
888
+ contactId = (_f = (_e = r === null || r === void 0 ? void 0 : r.values) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.id;
889
+ if (!contactId)
890
+ throw new Error('Failed to create contact.');
913
891
  }
914
- if (isCreate && isPrimaryAddress) {
915
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/delete', {
916
- where: [
917
- ['contact_id', '=', contactId],
918
- ['is_primary', '=', true],
919
- ],
892
+ else {
893
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/update`, {
894
+ values,
895
+ where: [['id', '=', contactId]],
920
896
  });
921
897
  }
922
- if (Object.keys(emailData).length) {
923
- if (isCreate) {
924
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/create', {
925
- values: {
926
- ...emailData,
927
- contact_id: contactId,
928
- is_primary: isPrimaryEmail,
929
- 'location_type_id:name': emailLocationName,
930
- },
898
+ /* SUBENTITIES */
899
+ if (resource === 'contact') {
900
+ if (isCreate && isPrimaryEmail) {
901
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/delete', {
902
+ where: [
903
+ ['contact_id', '=', contactId],
904
+ ['is_primary', '=', true],
905
+ ],
931
906
  });
932
907
  }
933
- else {
934
- const existingEmail = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/get', {
908
+ if (isCreate && isPrimaryPhone) {
909
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/delete', {
935
910
  where: [
936
911
  ['contact_id', '=', contactId],
937
- ['location_type_id:name', '=', emailLocationName],
912
+ ['is_primary', '=', true],
913
+ ],
914
+ });
915
+ }
916
+ if (isCreate && isPrimaryAddress) {
917
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/delete', {
918
+ where: [
919
+ ['contact_id', '=', contactId],
920
+ ['is_primary', '=', true],
938
921
  ],
939
- limit: 1,
940
- select: ['id'],
941
922
  });
942
- const existingEmailId = (_h = (_g = existingEmail === null || existingEmail === void 0 ? void 0 : existingEmail.values) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.id;
943
- if (existingEmailId) {
944
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/update', {
923
+ }
924
+ if (Object.keys(emailData).length) {
925
+ if (isCreate) {
926
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/create', {
945
927
  values: {
946
- id: existingEmailId,
947
928
  ...emailData,
948
929
  contact_id: contactId,
949
930
  is_primary: isPrimaryEmail,
931
+ 'location_type_id:name': emailLocationName,
950
932
  },
951
933
  });
952
934
  }
953
935
  else {
954
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/create', {
955
- values: {
956
- ...emailData,
957
- contact_id: contactId,
958
- is_primary: isPrimaryEmail,
959
- 'location_type_id:name': emailLocationName,
960
- },
936
+ const existingEmail = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/get', {
937
+ where: [
938
+ ['contact_id', '=', contactId],
939
+ ['location_type_id:name', '=', emailLocationName],
940
+ ],
941
+ limit: 1,
942
+ select: ['id'],
961
943
  });
944
+ const existingEmailId = (_h = (_g = existingEmail === null || existingEmail === void 0 ? void 0 : existingEmail.values) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.id;
945
+ if (existingEmailId) {
946
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/update', {
947
+ values: {
948
+ id: existingEmailId,
949
+ ...emailData,
950
+ contact_id: contactId,
951
+ is_primary: isPrimaryEmail,
952
+ },
953
+ });
954
+ }
955
+ else {
956
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Email/create', {
957
+ values: {
958
+ ...emailData,
959
+ contact_id: contactId,
960
+ is_primary: isPrimaryEmail,
961
+ 'location_type_id:name': emailLocationName,
962
+ },
963
+ });
964
+ }
962
965
  }
963
966
  }
964
- }
965
- if (Object.keys(phoneData).length) {
966
- if (isCreate) {
967
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/create', {
968
- values: {
969
- ...phoneData,
970
- contact_id: contactId,
971
- is_primary: isPrimaryPhone,
972
- 'location_type_id:name': phoneLocationName,
973
- },
974
- });
975
- }
976
- else {
977
- const existingPhone = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/get', {
978
- where: [
979
- ['contact_id', '=', contactId],
980
- ['location_type_id:name', '=', phoneLocationName],
981
- ],
982
- limit: 1,
983
- select: ['id'],
984
- });
985
- const existingPhoneId = (_k = (_j = existingPhone === null || existingPhone === void 0 ? void 0 : existingPhone.values) === null || _j === void 0 ? void 0 : _j[0]) === null || _k === void 0 ? void 0 : _k.id;
986
- if (existingPhoneId) {
987
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/update', {
967
+ if (Object.keys(phoneData).length) {
968
+ if (isCreate) {
969
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/create', {
988
970
  values: {
989
- id: existingPhoneId,
990
971
  ...phoneData,
991
972
  contact_id: contactId,
992
973
  is_primary: isPrimaryPhone,
974
+ 'location_type_id:name': phoneLocationName,
993
975
  },
994
976
  });
995
977
  }
996
978
  else {
997
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/create', {
998
- values: {
999
- ...phoneData,
1000
- contact_id: contactId,
1001
- is_primary: isPrimaryPhone,
1002
- 'location_type_id:name': phoneLocationName,
1003
- },
979
+ const existingPhone = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/get', {
980
+ where: [
981
+ ['contact_id', '=', contactId],
982
+ ['location_type_id:name', '=', phoneLocationName],
983
+ ],
984
+ limit: 1,
985
+ select: ['id'],
1004
986
  });
987
+ const existingPhoneId = (_k = (_j = existingPhone === null || existingPhone === void 0 ? void 0 : existingPhone.values) === null || _j === void 0 ? void 0 : _j[0]) === null || _k === void 0 ? void 0 : _k.id;
988
+ if (existingPhoneId) {
989
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/update', {
990
+ values: {
991
+ id: existingPhoneId,
992
+ ...phoneData,
993
+ contact_id: contactId,
994
+ is_primary: isPrimaryPhone,
995
+ },
996
+ });
997
+ }
998
+ else {
999
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Phone/create', {
1000
+ values: {
1001
+ ...phoneData,
1002
+ contact_id: contactId,
1003
+ is_primary: isPrimaryPhone,
1004
+ 'location_type_id:name': phoneLocationName,
1005
+ },
1006
+ });
1007
+ }
1005
1008
  }
1006
1009
  }
1007
- }
1008
- if (Object.keys(addressData).length) {
1009
- if (isCreate) {
1010
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/create', {
1011
- values: {
1012
- ...addressData,
1013
- contact_id: contactId,
1014
- is_primary: isPrimaryAddress,
1015
- 'location_type_id:name': addressLocationName,
1016
- },
1017
- });
1018
- }
1019
- else {
1020
- const existingAddress = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/get', {
1021
- where: [
1022
- ['contact_id', '=', contactId],
1023
- ['location_type_id:name', '=', addressLocationName],
1024
- ],
1025
- limit: 1,
1026
- select: ['id'],
1027
- });
1028
- const existingAddressId = (_m = (_l = existingAddress === null || existingAddress === void 0 ? void 0 : existingAddress.values) === null || _l === void 0 ? void 0 : _l[0]) === null || _m === void 0 ? void 0 : _m.id;
1029
- if (existingAddressId) {
1030
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/update', {
1010
+ if (Object.keys(addressData).length) {
1011
+ if (isCreate) {
1012
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/create', {
1031
1013
  values: {
1032
- id: existingAddressId,
1033
1014
  ...addressData,
1034
1015
  contact_id: contactId,
1035
1016
  is_primary: isPrimaryAddress,
1017
+ 'location_type_id:name': addressLocationName,
1036
1018
  },
1037
1019
  });
1038
1020
  }
1039
1021
  else {
1040
- await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/create', {
1041
- values: {
1042
- ...addressData,
1043
- contact_id: contactId,
1044
- is_primary: isPrimaryAddress,
1045
- 'location_type_id:name': addressLocationName,
1046
- },
1022
+ const existingAddress = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/get', {
1023
+ where: [
1024
+ ['contact_id', '=', contactId],
1025
+ ['location_type_id:name', '=', addressLocationName],
1026
+ ],
1027
+ limit: 1,
1028
+ select: ['id'],
1047
1029
  });
1030
+ const existingAddressId = (_m = (_l = existingAddress === null || existingAddress === void 0 ? void 0 : existingAddress.values) === null || _l === void 0 ? void 0 : _l[0]) === null || _m === void 0 ? void 0 : _m.id;
1031
+ if (existingAddressId) {
1032
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/update', {
1033
+ values: {
1034
+ id: existingAddressId,
1035
+ ...addressData,
1036
+ contact_id: contactId,
1037
+ is_primary: isPrimaryAddress,
1038
+ },
1039
+ });
1040
+ }
1041
+ else {
1042
+ await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', '/civicrm/ajax/api4/Address/create', {
1043
+ values: {
1044
+ ...addressData,
1045
+ contact_id: contactId,
1046
+ is_primary: isPrimaryAddress,
1047
+ 'location_type_id:name': addressLocationName,
1048
+ },
1049
+ });
1050
+ }
1048
1051
  }
1049
1052
  }
1050
1053
  }
1054
+ /* FINAL GET */
1055
+ const res = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/get`, {
1056
+ where: [['id', '=', contactId]],
1057
+ select: [
1058
+ 'id',
1059
+ 'display_name',
1060
+ 'first_name',
1061
+ 'last_name',
1062
+ 'organization_name',
1063
+ 'legal_name',
1064
+ 'contact_type',
1065
+ 'gender_id',
1066
+ 'gender_id:name',
1067
+ 'birth_date',
1068
+ ],
1069
+ ...(resource === 'contact'
1070
+ ? {
1071
+ chain: {
1072
+ emails: ['Email', 'get', { where: [['contact_id', '=', '$id']] }],
1073
+ phones: ['Phone', 'get', { where: [['contact_id', '=', '$id']] }],
1074
+ addresses: ['Address', 'get', { where: [['contact_id', '=', '$id']] }],
1075
+ },
1076
+ }
1077
+ : {}),
1078
+ });
1079
+ out.push({
1080
+ json: (_p = (_o = res === null || res === void 0 ? void 0 : res.values) === null || _o === void 0 ? void 0 : _o[0]) !== null && _p !== void 0 ? _p : {},
1081
+ pairedItem: { item: i },
1082
+ });
1083
+ }
1084
+ catch (error) {
1085
+ if (this.continueOnFail()) {
1086
+ out.push({ json: { error: error instanceof Error ? error.message : String(error) }, pairedItem: { item: i } });
1087
+ continue;
1088
+ }
1089
+ throw error;
1051
1090
  }
1052
- /* FINAL GET */
1053
- const res = await GenericFunctions_1.civicrmApiRequest.call(this, 'POST', `/civicrm/ajax/api4/${entity}/get`, {
1054
- where: [['id', '=', contactId]],
1055
- select: [
1056
- 'id',
1057
- 'display_name',
1058
- 'first_name',
1059
- 'last_name',
1060
- 'organization_name',
1061
- 'legal_name',
1062
- 'contact_type',
1063
- 'gender_id',
1064
- 'gender_id:name',
1065
- 'birth_date',
1066
- ],
1067
- ...(resource === 'contact'
1068
- ? {
1069
- chain: {
1070
- emails: ['Email', 'get', { where: [['contact_id', '=', '$id']] }],
1071
- phones: ['Phone', 'get', { where: [['contact_id', '=', '$id']] }],
1072
- addresses: ['Address', 'get', { where: [['contact_id', '=', '$id']] }],
1073
- },
1074
- }
1075
- : {}),
1076
- });
1077
- out.push({
1078
- json: (_p = (_o = res === null || res === void 0 ? void 0 : res.values) === null || _o === void 0 ? void 0 : _o[0]) !== null && _p !== void 0 ? _p : {},
1079
- pairedItem: { item: i },
1080
- });
1081
1091
  }
1082
1092
  return [out];
1083
1093
  }