n8n-nodes-didar-crm 0.0.19 → 0.0.20

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.
@@ -49,6 +49,8 @@ const CaseOps = __importStar(require("./case"));
49
49
  const case_1 = require("./case");
50
50
  const ProductOps = __importStar(require("./product"));
51
51
  const product_1 = require("./product");
52
+ // Supplementary (Base Info)
53
+ const supplementary_1 = require("./supplementary");
52
54
  class DidarCrm {
53
55
  constructor() {
54
56
  this.methods = {
@@ -85,6 +87,7 @@ class DidarCrm {
85
87
  { name: 'Note', value: 'note' },
86
88
  { name: 'Case', value: 'case' },
87
89
  { name: 'Product', value: 'product' },
90
+ { name: 'Supplementary', value: 'supplementary' }
88
91
  ],
89
92
  default: 'deal',
90
93
  description: 'Choose the entity to act on.',
@@ -139,6 +142,7 @@ class DidarCrm {
139
142
  options: [
140
143
  { name: 'Create', value: 'create', action: 'Create an activity' },
141
144
  { name: 'Update', value: 'update', action: 'Update an activity by Id' },
145
+ { name: 'Search', value: 'search', action: 'Search activities' }
142
146
  ],
143
147
  default: 'create',
144
148
  description: 'Select the action to perform on the selected resource.',
@@ -163,6 +167,7 @@ class DidarCrm {
163
167
  options: [
164
168
  { name: 'Create', value: 'create', action: 'Create a case' },
165
169
  { name: 'Update', value: 'update', action: 'Update a case by ID' },
170
+ { name: 'Search', value: 'search', action: 'Search cases' }
166
171
  ],
167
172
  default: 'create',
168
173
  description: 'Select the action to perform on the selected resource.',
@@ -176,10 +181,23 @@ class DidarCrm {
176
181
  { name: 'Create', value: 'create', action: 'Create a product' },
177
182
  { name: 'Update', value: 'update', action: 'Update a product by ID' },
178
183
  { name: 'Get by Codes', value: 'getByCodes', action: 'Get products by list of codes' },
184
+ { name: 'Search', value: 'search', description: 'Search products' },
179
185
  ],
180
186
  default: 'create',
181
187
  description: 'Select the action to perform on the selected resource.',
182
188
  },
189
+ {
190
+ displayName: 'Operation',
191
+ name: 'operation',
192
+ type: 'options',
193
+ displayOptions: {
194
+ show: { resource: ['supplementary'] },
195
+ },
196
+ options: [
197
+ { name: 'Get Base Info', value: 'getBaseInfo', action: 'Fetch base information' },
198
+ ],
199
+ default: 'getBaseInfo',
200
+ },
183
201
  // Deal properties (imported)
184
202
  ...deal_1.dealCreateProperties,
185
203
  ...deal_1.dealUpdateProperties,
@@ -198,16 +216,21 @@ class DidarCrm {
198
216
  // Activity properties (imported)
199
217
  ...activity_1.activityCreateProperties,
200
218
  ...activity_1.activityUpdateProperties,
219
+ ...activity_1.activitySearchProperties,
201
220
  // Note properties (imported)
202
221
  ...note_1.noteCreateProperties,
203
222
  ...note_1.noteUpdateProperties,
204
223
  // Case properties (imported)
205
224
  ...case_1.caseCreateProperties,
206
225
  ...case_1.caseUpdateProperties,
226
+ ...case_1.caseSearchProperties,
207
227
  // Product properties (imported)
208
228
  ...product_1.productCreateProperties,
209
229
  ...product_1.productUpdateProperties,
210
230
  ...product_1.productGetByCodesProperties,
231
+ ...product_1.productSearchProperties,
232
+ // somewhere after Operation property
233
+ ...supplementary_1.getBaseInfoProperties,
211
234
  ],
212
235
  };
213
236
  }
@@ -280,6 +303,10 @@ class DidarCrm {
280
303
  await ActivityOps.activityUpdate.call(this, i, returnData);
281
304
  continue;
282
305
  }
306
+ if (operation === 'search') {
307
+ await ActivityOps.activitySearch.call(this, i, returnData);
308
+ continue;
309
+ }
283
310
  }
284
311
  if (resource === 'note') {
285
312
  if (operation === 'create') {
@@ -300,6 +327,10 @@ class DidarCrm {
300
327
  await CaseOps.caseUpdate.call(this, i, returnData);
301
328
  continue;
302
329
  }
330
+ if (operation === 'search') {
331
+ await CaseOps.caseSearch.call(this, i, returnData);
332
+ continue;
333
+ }
303
334
  }
304
335
  if (resource === 'product') {
305
336
  if (operation === 'create') {
@@ -314,6 +345,16 @@ class DidarCrm {
314
345
  await ProductOps.productGetByCodes.call(this, i, returnData);
315
346
  continue;
316
347
  }
348
+ if (operation === 'search') {
349
+ await ProductOps.productSearch.call(this, i, returnData);
350
+ continue;
351
+ }
352
+ }
353
+ if (resource === 'supplementary') {
354
+ if (operation === 'getBaseInfo') {
355
+ await supplementary_1.getBaseInfo.call(this, i, returnData);
356
+ continue;
357
+ }
317
358
  }
318
359
  }
319
360
  return [returnData];
@@ -2,3 +2,5 @@ export { activityCreate } from './create.operation';
2
2
  export { activityCreateProperties } from './create.properties';
3
3
  export { activityUpdate } from './update.operation';
4
4
  export { activityUpdateProperties } from './update.properties';
5
+ export { activitySearch } from './search.operation';
6
+ export { activitySearchProperties } from './search.properties';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.activityUpdateProperties = exports.activityUpdate = exports.activityCreateProperties = exports.activityCreate = void 0;
3
+ exports.activitySearchProperties = exports.activitySearch = exports.activityUpdateProperties = exports.activityUpdate = exports.activityCreateProperties = exports.activityCreate = void 0;
4
4
  var create_operation_1 = require("./create.operation");
5
5
  Object.defineProperty(exports, "activityCreate", { enumerable: true, get: function () { return create_operation_1.activityCreate; } });
6
6
  var create_properties_1 = require("./create.properties");
@@ -9,3 +9,7 @@ var update_operation_1 = require("./update.operation");
9
9
  Object.defineProperty(exports, "activityUpdate", { enumerable: true, get: function () { return update_operation_1.activityUpdate; } });
10
10
  var update_properties_1 = require("./update.properties");
11
11
  Object.defineProperty(exports, "activityUpdateProperties", { enumerable: true, get: function () { return update_properties_1.activityUpdateProperties; } });
12
+ var search_operation_1 = require("./search.operation");
13
+ Object.defineProperty(exports, "activitySearch", { enumerable: true, get: function () { return search_operation_1.activitySearch; } });
14
+ var search_properties_1 = require("./search.properties");
15
+ Object.defineProperty(exports, "activitySearchProperties", { enumerable: true, get: function () { return search_properties_1.activitySearchProperties; } });
@@ -0,0 +1,2 @@
1
+ import type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
2
+ export declare function activitySearch(this: IExecuteFunctions, i: number, returnData: INodeExecutionData[]): Promise<INodeExecutionData[]>;
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.activitySearch = activitySearch;
4
+ const http_1 = require("../../lib/http");
5
+ async function activitySearch(i, returnData) {
6
+ var _a, _b, _c;
7
+ // ===== Helpers =====
8
+ const uniq = (arr) => Array.from(new Set(arr.map(s => s.trim()).filter(Boolean)));
9
+ const parseIdList = (input) => {
10
+ const out = [];
11
+ const pushFromString = (raw) => {
12
+ if (!raw)
13
+ return;
14
+ const s = raw.trim();
15
+ if (!s)
16
+ return;
17
+ // [Array: [ ... ]]
18
+ const arrayLabel = s.match(/^\s*\[Array:\s*(\[[\s\S]*\])\s*\]\s*$/i);
19
+ if (arrayLabel) {
20
+ try {
21
+ const arr = JSON.parse(arrayLabel[1]);
22
+ recur(arr);
23
+ return;
24
+ }
25
+ catch { }
26
+ }
27
+ // JSON array
28
+ if (/^\s*\[/.test(s)) {
29
+ try {
30
+ const arr = JSON.parse(s);
31
+ recur(arr);
32
+ return;
33
+ }
34
+ catch {
35
+ throw new Error('Invalid JSON array.');
36
+ }
37
+ }
38
+ // CSV / ; / newline
39
+ s.split(/[\n,;]+/).map(t => t.trim()).filter(Boolean).forEach(t => out.push(t));
40
+ };
41
+ const recur = (val) => {
42
+ var _a, _b;
43
+ if (val == null)
44
+ return;
45
+ if (Array.isArray(val)) {
46
+ val.forEach(recur);
47
+ return;
48
+ }
49
+ switch (typeof val) {
50
+ case 'string':
51
+ pushFromString(val);
52
+ return;
53
+ case 'number':
54
+ case 'boolean':
55
+ out.push(String(val));
56
+ return;
57
+ case 'object': {
58
+ const obj = val;
59
+ if (val instanceof Set) {
60
+ recur(Array.from(val));
61
+ return;
62
+ }
63
+ if (val instanceof Map) {
64
+ recur(Array.from(val.values()));
65
+ return;
66
+ }
67
+ if (obj === null || obj === void 0 ? void 0 : obj.values) {
68
+ recur(obj.values);
69
+ return;
70
+ }
71
+ if (obj === null || obj === void 0 ? void 0 : obj.Value) {
72
+ recur(obj.Value);
73
+ return;
74
+ }
75
+ const s = ((_b = (_a = obj === null || obj === void 0 ? void 0 : obj.toString) === null || _a === void 0 ? void 0 : _a.call(obj)) !== null && _b !== void 0 ? _b : '').toString();
76
+ if (s)
77
+ pushFromString(s);
78
+ return;
79
+ }
80
+ default: return;
81
+ }
82
+ };
83
+ recur(input);
84
+ return uniq(out);
85
+ };
86
+ const toBoolIfSet = (v) => {
87
+ if (v === '' || v === undefined)
88
+ return undefined;
89
+ return v === 1 ? true : false; // 1 => true, -1 => false
90
+ };
91
+ // ===== Main fields =====
92
+ // ActivityTypeIds (select/manual)
93
+ const typeMode = this.getNodeParameter('ActivityTypeMode', i, 'select');
94
+ const typeSel = this.getNodeParameter('ActivityTypeIdsSelect', i, []);
95
+ const typeMan = this.getNodeParameter('ActivityTypeIdsManual', i, []);
96
+ const activityTypeIds = parseIdList(typeMode === 'select' ? typeSel : typeMan);
97
+ // Owner
98
+ const ownerMode = this.getNodeParameter('OwnerMode', i, 'select');
99
+ const ownerSel = this.getNodeParameter('OwnerIdSelect', i, '');
100
+ const ownerMan = this.getNodeParameter('OwnerIdManual', i, '');
101
+ const ownerId = ownerMode === 'select' ? ownerSel : ownerMan;
102
+ // ContactIds
103
+ const contactIdsInput = this.getNodeParameter('ContactIds', i, []);
104
+ const contactIds = parseIdList(contactIdsInput);
105
+ // Deal / Case (simple)
106
+ const dealId = this.getNodeParameter('DealId', i, '').trim();
107
+ const caseId = this.getNodeParameter('CaseId', i, '').trim();
108
+ // ===== Additional =====
109
+ const add = this.getNodeParameter('additionalFields', i, {}) || {};
110
+ const fromDate = (_a = add.FromDate) !== null && _a !== void 0 ? _a : '1800-01-01T00:00:00.000Z';
111
+ const toDate = (_b = add.ToDate) !== null && _b !== void 0 ? _b : '9999-12-28T20:30:00.000Z';
112
+ // Creator (select/manual)
113
+ const creatorMode = this.getNodeParameter('CreatorMode', i, 'select');
114
+ const creatorSel = this.getNodeParameter('CreatorIdSelect', i, '');
115
+ const creatorMan = this.getNodeParameter('CreatorIdManual', i, '');
116
+ const creatorId = creatorMode === 'select' ? creatorSel : creatorMan;
117
+ // Flags (IsDone / IsDeleted) with Not set / True(1) / False(-1)
118
+ const isDoneOpt = add.IsDone;
119
+ const isDeletedOpt = add.IsDeleted;
120
+ const isDone = toBoolIfSet(isDoneOpt);
121
+ const isDeleted = toBoolIfSet(isDeletedOpt);
122
+ // TagIds
123
+ const tagIdsInput = add.TagIds;
124
+ const tagIds = parseIdList(tagIdsInput);
125
+ const limit = typeof add.Limit === 'number' ? add.Limit : 10;
126
+ const from = 0;
127
+ // ===== Build payload =====
128
+ const body = {
129
+ FromDate: fromDate,
130
+ ToDate: toDate,
131
+ SortType: 1, // ثابت و غیرنمایشی
132
+ From: from,
133
+ Limit: limit,
134
+ };
135
+ if (activityTypeIds.length)
136
+ body['ActivityTypeIds'] = activityTypeIds;
137
+ if (ownerId)
138
+ body['OwnerId'] = ownerId;
139
+ if (creatorId)
140
+ body['CreatorId'] = creatorId;
141
+ if (typeof isDone === 'boolean')
142
+ body['IsDone'] = isDone;
143
+ if (typeof isDeleted === 'boolean')
144
+ body['IsDeleted'] = isDeleted;
145
+ if (dealId)
146
+ body['DealId'] = dealId;
147
+ if (caseId)
148
+ body['CaseId'] = caseId;
149
+ if (contactIds.length)
150
+ body['ContactIds'] = contactIds;
151
+ if (tagIds.length)
152
+ body['TagIds'] = tagIds;
153
+ // ===== Request =====
154
+ const resp = await (0, http_1.didarRequest)(this, i, {
155
+ method: 'POST',
156
+ path: '/api/activity/search',
157
+ body,
158
+ });
159
+ const out = ((_c = resp === null || resp === void 0 ? void 0 : resp.Response) !== null && _c !== void 0 ? _c : resp);
160
+ returnData.push({ json: { search_respons: out, criteria: body } });
161
+ return returnData;
162
+ }
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const activitySearchProperties: INodeProperties[];
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.activitySearchProperties = void 0;
4
+ const showForActivitySearch = { show: { resource: ['activity'], operation: ['search'] } };
5
+ exports.activitySearchProperties = [
6
+ // ===== Main fields (ordered) =====
7
+ // ActivityTypeIds (Select/Manual, multi)
8
+ {
9
+ displayName: 'Activity Types Input Mode',
10
+ name: 'ActivityTypeMode',
11
+ type: 'options',
12
+ options: [
13
+ { name: 'Select from list (multi)', value: 'select' },
14
+ { name: 'Enter IDs manually', value: 'manual' },
15
+ ],
16
+ default: 'select',
17
+ displayOptions: showForActivitySearch,
18
+ description: 'Choose how to provide activity type IDs (optional).',
19
+ },
20
+ {
21
+ displayName: 'Activity Types',
22
+ name: 'ActivityTypeIdsSelect',
23
+ type: 'options',
24
+ typeOptions: { loadOptionsMethod: 'getActivityTypes', multipleValues: true },
25
+ default: [],
26
+ displayOptions: { show: { ...showForActivitySearch.show, ActivityTypeMode: ['select'] } },
27
+ description: 'Select one or more activity types (leave empty to ignore).',
28
+ },
29
+ {
30
+ displayName: 'Activity Type IDs (Manual)',
31
+ name: 'ActivityTypeIdsManual',
32
+ type: 'string',
33
+ typeOptions: { multipleValues: true },
34
+ default: [],
35
+ displayOptions: { show: { ...showForActivitySearch.show, ActivityTypeMode: ['manual'] } },
36
+ description: 'Enter IDs as CSV / JSON array / [Array: [...]] / multi-lines.',
37
+ },
38
+ // Owner (select/manual)
39
+ {
40
+ displayName: 'Owner Input Mode',
41
+ name: 'OwnerMode',
42
+ type: 'options',
43
+ options: [
44
+ { name: 'Select from list', value: 'select' },
45
+ { name: 'Enter ID manually', value: 'manual' },
46
+ ],
47
+ default: 'select',
48
+ displayOptions: showForActivitySearch,
49
+ description: 'Choose how to filter by owner (optional).',
50
+ },
51
+ {
52
+ displayName: 'Owner',
53
+ name: 'OwnerIdSelect',
54
+ type: 'options',
55
+ typeOptions: { loadOptionsMethod: 'getUsers' },
56
+ default: '',
57
+ displayOptions: { show: { ...showForActivitySearch.show, OwnerMode: ['select'] } },
58
+ description: 'Select the owner user (leave empty to ignore).',
59
+ },
60
+ {
61
+ displayName: 'Owner ID',
62
+ name: 'OwnerIdManual',
63
+ type: 'string',
64
+ default: '',
65
+ displayOptions: { show: { ...showForActivitySearch.show, OwnerMode: ['manual'] } },
66
+ description: 'Enter owner user ID manually (leave empty to ignore).',
67
+ },
68
+ // ContactIds
69
+ {
70
+ displayName: 'Contact IDs',
71
+ name: 'ContactIds',
72
+ type: 'string',
73
+ typeOptions: { multipleValues: true },
74
+ default: [],
75
+ displayOptions: showForActivitySearch,
76
+ description: 'Contact IDs (CSV / JSON array / [Array: [...]] / multi-lines).',
77
+ },
78
+ // DealId / CaseId (simple strings)
79
+ {
80
+ displayName: 'Deal ID',
81
+ name: 'DealId',
82
+ type: 'string',
83
+ default: '',
84
+ displayOptions: showForActivitySearch,
85
+ description: 'Filter by a specific deal (optional).',
86
+ },
87
+ {
88
+ displayName: 'Case ID',
89
+ name: 'CaseId',
90
+ type: 'string',
91
+ default: '',
92
+ displayOptions: showForActivitySearch,
93
+ description: 'Filter by a specific case (optional).',
94
+ },
95
+ // Creator (select/manual)
96
+ {
97
+ displayName: 'Creator Input Mode',
98
+ name: 'CreatorMode',
99
+ type: 'options',
100
+ options: [
101
+ { name: 'Select from list', value: 'select' },
102
+ { name: 'Enter ID manually', value: 'manual' },
103
+ ],
104
+ default: 'select',
105
+ displayOptions: showForActivitySearch,
106
+ description: 'Choose how to filter by creator (optional).',
107
+ },
108
+ {
109
+ displayName: 'Creator',
110
+ name: 'CreatorIdSelect',
111
+ type: 'options',
112
+ typeOptions: { loadOptionsMethod: 'getUsers' },
113
+ default: '',
114
+ displayOptions: { show: { ...showForActivitySearch.show, CreatorMode: ['select'] } },
115
+ description: 'Select the creator user (leave empty to ignore).',
116
+ },
117
+ {
118
+ displayName: 'Creator ID',
119
+ name: 'CreatorIdManual',
120
+ type: 'string',
121
+ default: '',
122
+ displayOptions: { show: { ...showForActivitySearch.show, CreatorMode: ['manual'] } },
123
+ description: 'Enter creator user ID manually (leave empty to ignore).',
124
+ },
125
+ // ===== Additional filters =====
126
+ {
127
+ displayName: 'Additional Filters',
128
+ name: 'additionalFields',
129
+ type: 'collection',
130
+ placeholder: 'Add filter',
131
+ default: {},
132
+ displayOptions: showForActivitySearch,
133
+ options: [
134
+ // ثابت‌ها / پیش‌فرض‌ها
135
+ {
136
+ displayName: 'From Date',
137
+ name: 'FromDate',
138
+ type: 'dateTime',
139
+ default: '1800-01-01T00:00:00.000Z',
140
+ description: 'Lower bound date.',
141
+ },
142
+ {
143
+ displayName: 'To Date',
144
+ name: 'ToDate',
145
+ type: 'dateTime',
146
+ default: '9999-12-28T20:30:00.000Z',
147
+ description: 'Upper bound date.',
148
+ },
149
+ // IsDone / IsDeleted (Not set / True / False) — در operation به boolean تبدیل می‌کنیم
150
+ {
151
+ displayName: 'Is Done',
152
+ name: 'IsDone',
153
+ type: 'options',
154
+ options: [
155
+ { name: 'Not set', value: '' },
156
+ { name: 'True (1)', value: 1 },
157
+ { name: 'False (-1)', value: -1 },
158
+ ],
159
+ default: '',
160
+ description: 'Filter by completion flag (optional).',
161
+ },
162
+ {
163
+ displayName: 'Is Deleted',
164
+ name: 'IsDeleted',
165
+ type: 'options',
166
+ options: [
167
+ { name: 'Not set', value: '' },
168
+ { name: 'True (1)', value: 1 },
169
+ { name: 'False (-1)', value: -1 },
170
+ ],
171
+ default: '',
172
+ description: 'Filter by deletion flag (optional).',
173
+ },
174
+ // TagIds
175
+ {
176
+ displayName: 'Tag IDs',
177
+ name: 'TagIds',
178
+ type: 'string',
179
+ typeOptions: { multipleValues: true },
180
+ default: [],
181
+ description: 'Tag IDs (CSV / JSON array / [Array: [...]] / multi-lines).',
182
+ },
183
+ // Pagination
184
+ {
185
+ displayName: 'Limit',
186
+ name: 'Limit',
187
+ type: 'number',
188
+ default: 10,
189
+ description: 'Number of results to return.',
190
+ },
191
+ ],
192
+ },
193
+ ];
@@ -2,3 +2,5 @@ export { caseCreate } from './create.operation';
2
2
  export { caseCreateProperties } from './create.properties';
3
3
  export { caseUpdate } from './update.operation';
4
4
  export { caseUpdateProperties } from './update.properties';
5
+ export { caseSearch } from './search.operation';
6
+ export { caseSearchProperties } from './search.properties';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.caseUpdateProperties = exports.caseUpdate = exports.caseCreateProperties = exports.caseCreate = void 0;
3
+ exports.caseSearchProperties = exports.caseSearch = exports.caseUpdateProperties = exports.caseUpdate = exports.caseCreateProperties = exports.caseCreate = void 0;
4
4
  // nodes/case/index.ts
5
5
  var create_operation_1 = require("./create.operation");
6
6
  Object.defineProperty(exports, "caseCreate", { enumerable: true, get: function () { return create_operation_1.caseCreate; } });
@@ -10,3 +10,7 @@ var update_operation_1 = require("./update.operation");
10
10
  Object.defineProperty(exports, "caseUpdate", { enumerable: true, get: function () { return update_operation_1.caseUpdate; } });
11
11
  var update_properties_1 = require("./update.properties");
12
12
  Object.defineProperty(exports, "caseUpdateProperties", { enumerable: true, get: function () { return update_properties_1.caseUpdateProperties; } });
13
+ var search_operation_1 = require("./search.operation");
14
+ Object.defineProperty(exports, "caseSearch", { enumerable: true, get: function () { return search_operation_1.caseSearch; } });
15
+ var search_properties_1 = require("./search.properties");
16
+ Object.defineProperty(exports, "caseSearchProperties", { enumerable: true, get: function () { return search_properties_1.caseSearchProperties; } });
@@ -0,0 +1,2 @@
1
+ import type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
2
+ export declare function caseSearch(this: IExecuteFunctions, i: number, returnData: INodeExecutionData[]): Promise<INodeExecutionData[]>;
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.caseSearch = caseSearch;
4
+ const http_1 = require("../../lib/http");
5
+ async function caseSearch(i, returnData) {
6
+ var _a, _b, _c;
7
+ // Helpers
8
+ const uniq = (arr) => Array.from(new Set(arr.map(s => s.trim()).filter(Boolean)));
9
+ const parseIdList = (input) => {
10
+ const out = [];
11
+ const pushFromString = (raw) => {
12
+ if (!raw)
13
+ return;
14
+ const s = raw.trim();
15
+ if (!s)
16
+ return;
17
+ // Handles `[Array: [ ... ]]`
18
+ const arrayLabel = s.match(/^\s*\[Array:\s*(\[[\s\S]*\])\s*\]\s*$/i);
19
+ if (arrayLabel) {
20
+ try {
21
+ const arr = JSON.parse(arrayLabel[1]);
22
+ recur(arr);
23
+ return;
24
+ }
25
+ catch { }
26
+ }
27
+ // Handles direct JSON arrays like `["a","b"]`
28
+ if (/^\s*\[/.test(s)) {
29
+ try {
30
+ const arr = JSON.parse(s);
31
+ recur(arr);
32
+ return;
33
+ }
34
+ catch {
35
+ throw new Error('Invalid JSON array.');
36
+ }
37
+ }
38
+ // Split by common separators
39
+ s.split(/[\n,;]+/).map(t => t.trim()).filter(Boolean).forEach(t => out.push(t));
40
+ };
41
+ const recur = (val) => {
42
+ var _a, _b;
43
+ if (val == null)
44
+ return;
45
+ if (Array.isArray(val)) {
46
+ val.forEach(recur);
47
+ return;
48
+ }
49
+ switch (typeof val) {
50
+ case 'string':
51
+ pushFromString(val);
52
+ return;
53
+ case 'number':
54
+ case 'boolean':
55
+ out.push(String(val));
56
+ return;
57
+ case 'object': {
58
+ const obj = val;
59
+ if (val instanceof Set) {
60
+ recur(Array.from(val));
61
+ return;
62
+ }
63
+ if (val instanceof Map) {
64
+ recur(Array.from(val.values()));
65
+ return;
66
+ }
67
+ if (obj === null || obj === void 0 ? void 0 : obj.values) {
68
+ recur(obj.values);
69
+ return;
70
+ }
71
+ if (obj === null || obj === void 0 ? void 0 : obj.Value) {
72
+ recur(obj.Value);
73
+ return;
74
+ }
75
+ const s = ((_b = (_a = obj === null || obj === void 0 ? void 0 : obj.toString) === null || _a === void 0 ? void 0 : _a.call(obj)) !== null && _b !== void 0 ? _b : '').toString();
76
+ if (s)
77
+ pushFromString(s);
78
+ return;
79
+ }
80
+ default: return;
81
+ }
82
+ };
83
+ recur(input);
84
+ return uniq(out);
85
+ };
86
+ const parseJsonFlexible = (val) => {
87
+ if (val == null || val === '')
88
+ return [];
89
+ if (Array.isArray(val))
90
+ return val;
91
+ if (typeof val === 'string') {
92
+ const s = val.trim();
93
+ if (!s)
94
+ return [];
95
+ const m = s.match(/^\s*\[Array:\s*(\[[\s\S]*\])\s*\]\s*$/i);
96
+ if (m) {
97
+ try {
98
+ return JSON.parse(m[1]);
99
+ }
100
+ catch {
101
+ throw new Error('Invalid JSON in Custom Fields.');
102
+ }
103
+ }
104
+ try {
105
+ const parsed = JSON.parse(s);
106
+ return Array.isArray(parsed) ? parsed : [];
107
+ }
108
+ catch {
109
+ throw new Error('Invalid JSON in Custom Fields.');
110
+ }
111
+ }
112
+ return [];
113
+ };
114
+ // --- Main fields ---
115
+ const keywords = this.getNodeParameter('Keywords', i, '').trim();
116
+ // Owner (select/manual) — optional
117
+ const ownerMode = this.getNodeParameter('OwnerMode', i, 'select');
118
+ const ownerSel = this.getNodeParameter('OwnerIdSelect', i, '');
119
+ const ownerMan = this.getNodeParameter('OwnerIdManual', i, '');
120
+ const ownerId = ownerMode === 'select' ? ownerSel : ownerMan;
121
+ // ContactIds
122
+ const contactIdsInput = this.getNodeParameter('ContactIds', i, []);
123
+ const contactIds = parseIdList(contactIdsInput);
124
+ // Additional
125
+ const add = this.getNodeParameter('additionalFields', i, {}) || {};
126
+ const searchFromTime = (_a = add.SearchFromTime) !== null && _a !== void 0 ? _a : '1000-01-01T00:00:00.000Z';
127
+ const searchToTime = (_b = add.SearchToTime) !== null && _b !== void 0 ? _b : '9999-12-01T00:00:00.000Z';
128
+ const customFields = parseJsonFlexible(add.CustomFields);
129
+ const limit = typeof add.Limit === 'number' ? add.Limit : 10;
130
+ const from = 0;
131
+ // Build Criteria with only provided filters
132
+ const criteria = {
133
+ SearchTimeField: 1,
134
+ SearchFromTime: searchFromTime,
135
+ SearchToTime: searchToTime,
136
+ };
137
+ if (keywords)
138
+ criteria['Keywords'] = keywords;
139
+ if (ownerId)
140
+ criteria['OwnerId'] = ownerId;
141
+ if (contactIds.length)
142
+ criteria['ContactIds'] = contactIds;
143
+ if (customFields === null || customFields === void 0 ? void 0 : customFields.length)
144
+ criteria['CustomFields'] = customFields;
145
+ const body = { Criteria: criteria, From: from, Limit: limit };
146
+ // --- Request ---
147
+ const resp = await (0, http_1.didarRequest)(this, i, {
148
+ method: 'POST',
149
+ path: '/api/Case/search',
150
+ body,
151
+ });
152
+ const out = ((_c = resp === null || resp === void 0 ? void 0 : resp.Response) !== null && _c !== void 0 ? _c : resp);
153
+ // Return with criteria for debugging
154
+ returnData.push({ json: { search_respons: out, criteria: body } });
155
+ return returnData;
156
+ }
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const caseSearchProperties: INodeProperties[];
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.caseSearchProperties = void 0;
4
+ const showForCaseSearch = { show: { resource: ['case'], operation: ['search'] } };
5
+ exports.caseSearchProperties = [
6
+ // ===== Main fields =====
7
+ {
8
+ displayName: 'Keywords',
9
+ name: 'Keywords',
10
+ type: 'string',
11
+ default: '',
12
+ required: false,
13
+ displayOptions: showForCaseSearch,
14
+ description: 'Free-text search (optional).',
15
+ },
16
+ // Owner (select/manual)
17
+ {
18
+ displayName: 'Owner Input Mode',
19
+ name: 'OwnerMode',
20
+ type: 'options',
21
+ options: [
22
+ { name: 'Select from list', value: 'select' },
23
+ { name: 'Enter ID manually', value: 'manual' },
24
+ ],
25
+ default: 'select',
26
+ displayOptions: showForCaseSearch,
27
+ description: 'Choose how to filter by owner (optional).',
28
+ },
29
+ {
30
+ displayName: 'Owner',
31
+ name: 'OwnerIdSelect',
32
+ type: 'options',
33
+ typeOptions: { loadOptionsMethod: 'getUsers' },
34
+ default: '',
35
+ displayOptions: { show: { ...showForCaseSearch.show, OwnerMode: ['select'] } },
36
+ description: 'Select the owner user (leave empty to ignore).',
37
+ },
38
+ {
39
+ displayName: 'Owner ID',
40
+ name: 'OwnerIdManual',
41
+ type: 'string',
42
+ default: '',
43
+ displayOptions: { show: { ...showForCaseSearch.show, OwnerMode: ['manual'] } },
44
+ description: 'Enter the owner user ID manually (leave empty to ignore).',
45
+ },
46
+ // ===== Additional filters =====
47
+ {
48
+ displayName: 'Additional Filters',
49
+ name: 'additionalFields',
50
+ type: 'collection',
51
+ placeholder: 'Add filter',
52
+ default: {},
53
+ displayOptions: showForCaseSearch,
54
+ options: [
55
+ {
56
+ displayName: 'Search From Time',
57
+ name: 'SearchFromTime',
58
+ type: 'dateTime',
59
+ default: '1000-01-01T00:00:00.000Z',
60
+ description: 'Lower bound for the selected time field.',
61
+ },
62
+ {
63
+ displayName: 'Search To Time',
64
+ name: 'SearchToTime',
65
+ type: 'dateTime',
66
+ default: '9999-12-01T00:00:00.000Z',
67
+ description: 'Upper bound for the selected time field.',
68
+ },
69
+ {
70
+ displayName: 'Contact IDs',
71
+ name: 'ContactIds',
72
+ type: 'string',
73
+ typeOptions: { multipleValues: true },
74
+ default: [],
75
+ description: 'One or more contact IDs (optional). Accepts multiple, CSV/newlines, JSON array, or expression returning array.',
76
+ },
77
+ {
78
+ displayName: 'Custom Fields (JSON)',
79
+ name: 'CustomFields',
80
+ type: 'json',
81
+ default: '[]',
82
+ description: 'JSON array of custom field filters (optional).',
83
+ },
84
+ {
85
+ displayName: 'Limit',
86
+ name: 'Limit',
87
+ type: 'number',
88
+ default: 10,
89
+ description: 'Number of results to return.',
90
+ },
91
+ ],
92
+ },
93
+ ];
@@ -4,3 +4,5 @@ export { productUpdate } from './update.operation';
4
4
  export { productUpdateProperties } from './update.properties';
5
5
  export { productGetByCodes } from './getByCodes.operation';
6
6
  export { productGetByCodesProperties } from './getByCodes.properties';
7
+ export { productSearch } from './search.operation';
8
+ export { productSearchProperties } from './search.properties';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.productGetByCodesProperties = exports.productGetByCodes = exports.productUpdateProperties = exports.productUpdate = exports.productCreateProperties = exports.productCreate = void 0;
3
+ exports.productSearchProperties = exports.productSearch = exports.productGetByCodesProperties = exports.productGetByCodes = exports.productUpdateProperties = exports.productUpdate = exports.productCreateProperties = exports.productCreate = void 0;
4
4
  // nodes/product/index.ts
5
5
  var create_operation_1 = require("./create.operation");
6
6
  Object.defineProperty(exports, "productCreate", { enumerable: true, get: function () { return create_operation_1.productCreate; } });
@@ -14,3 +14,7 @@ var getByCodes_operation_1 = require("./getByCodes.operation");
14
14
  Object.defineProperty(exports, "productGetByCodes", { enumerable: true, get: function () { return getByCodes_operation_1.productGetByCodes; } });
15
15
  var getByCodes_properties_1 = require("./getByCodes.properties");
16
16
  Object.defineProperty(exports, "productGetByCodesProperties", { enumerable: true, get: function () { return getByCodes_properties_1.productGetByCodesProperties; } });
17
+ var search_operation_1 = require("./search.operation");
18
+ Object.defineProperty(exports, "productSearch", { enumerable: true, get: function () { return search_operation_1.productSearch; } });
19
+ var search_properties_1 = require("./search.properties");
20
+ Object.defineProperty(exports, "productSearchProperties", { enumerable: true, get: function () { return search_properties_1.productSearchProperties; } });
@@ -0,0 +1,2 @@
1
+ import type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
2
+ export declare function productSearch(this: IExecuteFunctions, i: number, returnData: INodeExecutionData[]): Promise<INodeExecutionData[]>;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.productSearch = productSearch;
4
+ const http_1 = require("../../lib/http");
5
+ async function productSearch(i, returnData) {
6
+ var _a;
7
+ // پارامترها
8
+ const keywords = this.getNodeParameter('Keywords', i, '').trim();
9
+ const limit = this.getNodeParameter('Limit', i, 10);
10
+ const from = 0;
11
+ // بدنه
12
+ const criteria = {};
13
+ if (keywords)
14
+ criteria['Keywords'] = keywords;
15
+ const body = {
16
+ Criteria: criteria,
17
+ From: from,
18
+ Limit: limit,
19
+ };
20
+ // درخواست
21
+ const resp = await (0, http_1.didarRequest)(this, i, {
22
+ method: 'POST',
23
+ path: '/api/product/search',
24
+ body,
25
+ });
26
+ const out = ((_a = resp === null || resp === void 0 ? void 0 : resp.Response) !== null && _a !== void 0 ? _a : resp);
27
+ // خروجی
28
+ returnData.push({ json: { search_response: out, criteria: body } });
29
+ return returnData;
30
+ }
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const productSearchProperties: INodeProperties[];
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.productSearchProperties = void 0;
4
+ const showForProductSearch = { show: { resource: ['product'], operation: ['search'] } };
5
+ exports.productSearchProperties = [
6
+ {
7
+ displayName: 'Keywords',
8
+ name: 'Keywords',
9
+ type: 'string',
10
+ default: '',
11
+ displayOptions: showForProductSearch,
12
+ description: 'Search term to match product fields.',
13
+ },
14
+ {
15
+ displayName: 'Limit',
16
+ name: 'Limit',
17
+ type: 'number',
18
+ typeOptions: { minValue: 1, maxValue: 100 },
19
+ default: 10,
20
+ displayOptions: showForProductSearch,
21
+ description: 'Maximum number of results to return.',
22
+ },
23
+ ];
@@ -0,0 +1,2 @@
1
+ import type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
2
+ export declare function getBaseInfo(this: IExecuteFunctions, i: number, returnData: INodeExecutionData[]): Promise<INodeExecutionData[]>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBaseInfo = getBaseInfo;
4
+ const http_1 = require("../../lib/http");
5
+ async function getBaseInfo(i, returnData) {
6
+ var _a;
7
+ const dataset = this.getNodeParameter('dataset', i);
8
+ const map = {
9
+ pipelines: { path: '/api/pipeline/list/0', method: 'POST' },
10
+ activityTypes: { path: '/api/activity/GetActivityType', method: 'POST' },
11
+ customFields: { path: '/api/customfield/GetCustomfieldList', method: 'POST' },
12
+ productCategories: { path: '/api/product/categories', method: 'POST' },
13
+ };
14
+ const conf = map[dataset];
15
+ if (!conf)
16
+ throw new Error('Unsupported dataset.');
17
+ const resp = await (0, http_1.didarRequest)(this, i, {
18
+ method: conf.method || 'POST',
19
+ path: conf.path,
20
+ body: {}, // these endpoints are POST even if body is empty
21
+ });
22
+ // Always return full payload (no limiting)
23
+ const data = ((_a = resp === null || resp === void 0 ? void 0 : resp.Response) !== null && _a !== void 0 ? _a : resp);
24
+ returnData.push({ json: { dataset, data } });
25
+ return returnData;
26
+ }
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const getBaseInfoProperties: INodeProperties[];
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBaseInfoProperties = void 0;
4
+ const showForGetBaseInfo = { show: { resource: ['supplementary'], operation: ['getBaseInfo'] } };
5
+ exports.getBaseInfoProperties = [
6
+ {
7
+ displayName: 'Dataset',
8
+ name: 'dataset',
9
+ type: 'options',
10
+ options: [
11
+ { name: 'Pipelines', value: 'pipelines' },
12
+ { name: 'Activity Types', value: 'activityTypes' },
13
+ { name: 'Custom Fields', value: 'customFields' },
14
+ { name: 'Product Categories', value: 'productCategories' },
15
+ ],
16
+ default: 'pipelines',
17
+ displayOptions: showForGetBaseInfo,
18
+ description: 'Choose which base information to fetch.',
19
+ },
20
+ ];
@@ -0,0 +1,2 @@
1
+ export { getBaseInfo } from './get-base-info.operation';
2
+ export { getBaseInfoProperties } from './get-base-info.properties';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBaseInfoProperties = exports.getBaseInfo = void 0;
4
+ var get_base_info_operation_1 = require("./get-base-info.operation");
5
+ Object.defineProperty(exports, "getBaseInfo", { enumerable: true, get: function () { return get_base_info_operation_1.getBaseInfo; } });
6
+ var get_base_info_properties_1 = require("./get-base-info.properties");
7
+ Object.defineProperty(exports, "getBaseInfoProperties", { enumerable: true, get: function () { return get_base_info_properties_1.getBaseInfoProperties; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-didar-crm",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "Didar CRM nodes for n8n (Trigger + Deal.create)",
5
5
  "author": "You",
6
6
  "license": "MIT",