@dereekb/zoho 12.6.21 → 13.0.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.
Files changed (66) hide show
  1. package/LICENSE +1 -1
  2. package/index.cjs.js +1763 -2531
  3. package/index.esm.js +1655 -2524
  4. package/nestjs/index.cjs.js +598 -0
  5. package/nestjs/index.esm.js +582 -0
  6. package/nestjs/package.json +19 -3
  7. package/nestjs/src/lib/accounts/accounts.config.d.ts +32 -0
  8. package/nestjs/src/lib/crm/crm.api.d.ts +43 -0
  9. package/nestjs/src/lib/crm/crm.config.d.ts +10 -0
  10. package/nestjs/src/lib/crm/crm.module.d.ts +24 -0
  11. package/nestjs/src/lib/crm/index.d.ts +3 -0
  12. package/nestjs/src/lib/recruit/recruit.api.d.ts +7 -7
  13. package/package.json +14 -7
  14. package/src/lib/accounts/accounts.api.d.ts +1 -1
  15. package/src/lib/accounts/accounts.error.api.d.ts +2 -2
  16. package/src/lib/crm/crm.api.d.ts +430 -0
  17. package/src/lib/crm/crm.api.notes.d.ts +40 -0
  18. package/src/lib/crm/crm.api.tags.d.ts +160 -0
  19. package/src/lib/crm/crm.config.d.ts +24 -0
  20. package/src/lib/crm/crm.criteria.d.ts +19 -0
  21. package/src/lib/crm/crm.d.ts +325 -0
  22. package/src/lib/crm/crm.error.api.d.ts +52 -0
  23. package/src/lib/crm/crm.factory.d.ts +22 -0
  24. package/src/lib/crm/crm.notes.d.ts +48 -0
  25. package/src/lib/crm/crm.tags.d.ts +40 -0
  26. package/src/lib/crm/index.d.ts +10 -0
  27. package/src/lib/index.d.ts +1 -0
  28. package/src/lib/recruit/index.d.ts +0 -1
  29. package/src/lib/recruit/recruit.api.candidates.d.ts +6 -6
  30. package/src/lib/recruit/recruit.api.d.ts +102 -22
  31. package/src/lib/recruit/recruit.api.notes.d.ts +30 -6
  32. package/src/lib/recruit/recruit.api.tags.d.ts +30 -6
  33. package/src/lib/recruit/recruit.criteria.d.ts +8 -44
  34. package/src/lib/recruit/recruit.d.ts +7 -3
  35. package/src/lib/recruit/recruit.error.api.d.ts +7 -3
  36. package/src/lib/shared/criteria.d.ts +55 -0
  37. package/src/lib/shared/criteria.util.d.ts +10 -0
  38. package/src/lib/zoho.error.api.d.ts +64 -6
  39. package/src/lib/zoho.type.d.ts +1 -18
  40. package/nestjs/CHANGELOG.md +0 -459
  41. package/nestjs/README.md +0 -11
  42. package/nestjs/src/index.js +0 -5
  43. package/nestjs/src/index.js.map +0 -1
  44. package/nestjs/src/lib/accounts/accounts.api.js +0 -37
  45. package/nestjs/src/lib/accounts/accounts.api.js.map +0 -1
  46. package/nestjs/src/lib/accounts/accounts.config.js +0 -50
  47. package/nestjs/src/lib/accounts/accounts.config.js.map +0 -1
  48. package/nestjs/src/lib/accounts/accounts.service.js +0 -240
  49. package/nestjs/src/lib/accounts/accounts.service.js.map +0 -1
  50. package/nestjs/src/lib/accounts/index.js +0 -7
  51. package/nestjs/src/lib/accounts/index.js.map +0 -1
  52. package/nestjs/src/lib/index.js +0 -7
  53. package/nestjs/src/lib/index.js.map +0 -1
  54. package/nestjs/src/lib/recruit/index.js +0 -7
  55. package/nestjs/src/lib/recruit/index.js.map +0 -1
  56. package/nestjs/src/lib/recruit/recruit.api.js +0 -130
  57. package/nestjs/src/lib/recruit/recruit.api.js.map +0 -1
  58. package/nestjs/src/lib/recruit/recruit.config.js +0 -16
  59. package/nestjs/src/lib/recruit/recruit.config.js.map +0 -1
  60. package/nestjs/src/lib/recruit/recruit.module.js +0 -61
  61. package/nestjs/src/lib/recruit/recruit.module.js.map +0 -1
  62. package/nestjs/src/lib/zoho.config.js +0 -52
  63. package/nestjs/src/lib/zoho.config.js.map +0 -1
  64. package/src/lib/recruit/recruit.criteria.util.d.ts +0 -10
  65. /package/{index.cjs.d.ts → index.d.ts} +0 -0
  66. /package/{index.esm.d.ts → nestjs/index.d.ts} +0 -0
package/index.esm.js CHANGED
@@ -1,2263 +1,1517 @@
1
+ import 'core-js/modules/es.iterator.constructor.js';
2
+ import 'core-js/modules/es.iterator.filter.js';
3
+ import 'core-js/modules/es.iterator.for-each.js';
1
4
  import { getNextPageNumber, isStandardInternetAccessibleWebsiteUrl, escapeStringCharactersFunction, filterMaybeArrayValues, asArray, MS_IN_MINUTE, joinStringsWithCommas, separateValues, resetPeriodPromiseRateLimiter, MS_IN_SECOND } from '@dereekb/util';
2
- import { fetchPageFactory, FetchResponseError, makeUrlSearchParams, parseFetchFileResponse, FetchRequestFactoryError, rateLimitedFetchHandler, fetchJsonFunction, returnNullHandleFetchJsonParseErrorFunction, fetchApiFetchService } from '@dereekb/util/fetch';
5
+ import { fetchPageFactory, FetchResponseError, makeUrlSearchParams, parseFetchFileResponse, FetchRequestFactoryError, rateLimitedFetchHandler, fetchApiFetchService, fetchJsonFunction, returnNullHandleFetchJsonParseErrorFunction } from '@dereekb/util/fetch';
6
+ import 'core-js/modules/es.iterator.flat-map.js';
7
+ import 'core-js/modules/es.iterator.map.js';
3
8
  import { BaseError } from 'make-error';
9
+ import 'core-js/modules/es.set.difference.v2.js';
10
+ import 'core-js/modules/es.set.symmetric-difference.v2.js';
11
+ import 'core-js/modules/es.set.union.v2.js';
4
12
 
5
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
6
-
7
- var check = function (it) {
8
- return it && it.Math === Math && it;
9
- };
10
-
11
- // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
12
- var global$b =
13
- // eslint-disable-next-line es/no-global-this -- safe
14
- check(typeof globalThis == 'object' && globalThis) ||
15
- check(typeof window == 'object' && window) ||
16
- // eslint-disable-next-line no-restricted-globals -- safe
17
- check(typeof self == 'object' && self) ||
18
- check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
19
- check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
20
- // eslint-disable-next-line no-new-func -- fallback
21
- (function () { return this; })() || Function('return this')();
22
-
23
- var objectGetOwnPropertyDescriptor = {};
24
-
25
- var fails$c = function (exec) {
26
- try {
27
- return !!exec();
28
- } catch (error) {
29
- return true;
30
- }
31
- };
32
-
33
- var fails$b = fails$c;
34
-
35
- // Detect IE8's incomplete defineProperty implementation
36
- var descriptors = !fails$b(function () {
37
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
38
- return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7;
39
- });
40
-
41
- var fails$a = fails$c;
42
-
43
- var functionBindNative = !fails$a(function () {
44
- // eslint-disable-next-line es/no-function-prototype-bind -- safe
45
- var test = (function () { /* empty */ }).bind();
46
- // eslint-disable-next-line no-prototype-builtins -- safe
47
- return typeof test != 'function' || test.hasOwnProperty('prototype');
48
- });
49
-
50
- var NATIVE_BIND$2 = functionBindNative;
51
-
52
- var call$c = Function.prototype.call;
53
-
54
- var functionCall = NATIVE_BIND$2 ? call$c.bind(call$c) : function () {
55
- return call$c.apply(call$c, arguments);
56
- };
57
-
58
- var objectPropertyIsEnumerable = {};
59
-
60
- var $propertyIsEnumerable = {}.propertyIsEnumerable;
61
- // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
62
- var getOwnPropertyDescriptor$2 = Object.getOwnPropertyDescriptor;
63
-
64
- // Nashorn ~ JDK8 bug
65
- var NASHORN_BUG = getOwnPropertyDescriptor$2 && !$propertyIsEnumerable.call({ 1: 2 }, 1);
66
-
67
- // `Object.prototype.propertyIsEnumerable` method implementation
68
- // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
69
- objectPropertyIsEnumerable.f = NASHORN_BUG ? function propertyIsEnumerable(V) {
70
- var descriptor = getOwnPropertyDescriptor$2(this, V);
71
- return !!descriptor && descriptor.enumerable;
72
- } : $propertyIsEnumerable;
73
-
74
- var createPropertyDescriptor$3 = function (bitmap, value) {
13
+ /**
14
+ * Returns an empty ZohoPageResult that is typed to R and has no more records/results.
15
+ */
16
+ function emptyZohoPageResult() {
75
17
  return {
76
- enumerable: !(bitmap & 1),
77
- configurable: !(bitmap & 2),
78
- writable: !(bitmap & 4),
79
- value: value
80
- };
81
- };
82
-
83
- var NATIVE_BIND$1 = functionBindNative;
84
-
85
- var FunctionPrototype$1 = Function.prototype;
86
- var call$b = FunctionPrototype$1.call;
87
- var uncurryThisWithBind = NATIVE_BIND$1 && FunctionPrototype$1.bind.bind(call$b, call$b);
88
-
89
- var functionUncurryThis = NATIVE_BIND$1 ? uncurryThisWithBind : function (fn) {
90
- return function () {
91
- return call$b.apply(fn, arguments);
18
+ data: [],
19
+ info: {
20
+ page: 1,
21
+ per_page: 100,
22
+ // default value
23
+ count: 0,
24
+ more_records: false
25
+ }
92
26
  };
93
- };
94
-
95
- var uncurryThis$a = functionUncurryThis;
96
-
97
- var toString$1 = uncurryThis$a({}.toString);
98
- var stringSlice$1 = uncurryThis$a(''.slice);
99
-
100
- var classofRaw$2 = function (it) {
101
- return stringSlice$1(toString$1(it), 8, -1);
102
- };
103
-
104
- var uncurryThis$9 = functionUncurryThis;
105
- var fails$9 = fails$c;
106
- var classof$3 = classofRaw$2;
107
-
108
- var $Object$4 = Object;
109
- var split = uncurryThis$9(''.split);
110
-
111
- // fallback for non-array-like ES3 and non-enumerable old V8 strings
112
- var indexedObject = fails$9(function () {
113
- // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
114
- // eslint-disable-next-line no-prototype-builtins -- safe
115
- return !$Object$4('z').propertyIsEnumerable(0);
116
- }) ? function (it) {
117
- return classof$3(it) === 'String' ? split(it, '') : $Object$4(it);
118
- } : $Object$4;
119
-
120
- // we can't use just `it == null` since of `document.all` special case
121
- // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec
122
- var isNullOrUndefined$3 = function (it) {
123
- return it === null || it === undefined;
124
- };
125
-
126
- var isNullOrUndefined$2 = isNullOrUndefined$3;
127
-
128
- var $TypeError$b = TypeError;
129
-
130
- // `RequireObjectCoercible` abstract operation
131
- // https://tc39.es/ecma262/#sec-requireobjectcoercible
132
- var requireObjectCoercible$2 = function (it) {
133
- if (isNullOrUndefined$2(it)) throw new $TypeError$b("Can't call method on " + it);
134
- return it;
135
- };
136
-
137
- // toObject with fallback for non-array-like ES3 strings
138
- var IndexedObject = indexedObject;
139
- var requireObjectCoercible$1 = requireObjectCoercible$2;
140
-
141
- var toIndexedObject$4 = function (it) {
142
- return IndexedObject(requireObjectCoercible$1(it));
143
- };
144
-
145
- // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
146
- var documentAll = typeof document == 'object' && document.all;
147
-
148
- // `IsCallable` abstract operation
149
- // https://tc39.es/ecma262/#sec-iscallable
150
- // eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing
151
- var isCallable$e = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) {
152
- return typeof argument == 'function' || argument === documentAll;
153
- } : function (argument) {
154
- return typeof argument == 'function';
155
- };
156
-
157
- var isCallable$d = isCallable$e;
158
-
159
- var isObject$6 = function (it) {
160
- return typeof it == 'object' ? it !== null : isCallable$d(it);
161
- };
162
-
163
- var global$a = global$b;
164
- var isCallable$c = isCallable$e;
165
-
166
- var aFunction = function (argument) {
167
- return isCallable$c(argument) ? argument : undefined;
168
- };
169
-
170
- var getBuiltIn$3 = function (namespace, method) {
171
- return arguments.length < 2 ? aFunction(global$a[namespace]) : global$a[namespace] && global$a[namespace][method];
172
- };
173
-
174
- var uncurryThis$8 = functionUncurryThis;
175
-
176
- var objectIsPrototypeOf = uncurryThis$8({}.isPrototypeOf);
177
-
178
- var engineUserAgent = typeof navigator != 'undefined' && String(navigator.userAgent) || '';
179
-
180
- var global$9 = global$b;
181
- var userAgent = engineUserAgent;
182
-
183
- var process = global$9.process;
184
- var Deno = global$9.Deno;
185
- var versions = process && process.versions || Deno && Deno.version;
186
- var v8 = versions && versions.v8;
187
- var match, version;
188
-
189
- if (v8) {
190
- match = v8.split('.');
191
- // in old Chrome, versions of V8 isn't V8 = Chrome / 10
192
- // but their correct versions are not interesting for us
193
- version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);
27
+ }
28
+ /**
29
+ * Creates a FetchPageFactory using the input ZohoFetchPageFetchFunction.
30
+ *
31
+ * @param fetch
32
+ * @param defaults
33
+ * @returns
34
+ */
35
+ function zohoFetchPageFactory(fetch, defaults) {
36
+ return fetchPageFactory({
37
+ ...defaults,
38
+ fetch,
39
+ readFetchPageResultInfo: function (result) {
40
+ return {
41
+ hasNext: result.info?.more_records ?? false // if no info is returned, assume something wrong and there are no more records
42
+ };
43
+ },
44
+ buildInputForNextPage: function (pageResult, input, options) {
45
+ return {
46
+ ...input,
47
+ page: getNextPageNumber(pageResult),
48
+ per_page: options.maxItemsPerPage ?? input.per_page
49
+ };
50
+ }
51
+ });
194
52
  }
195
53
 
196
- // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
197
- // so check `userAgent` even if `.v8` exists, but 0
198
- if (!version && userAgent) {
199
- match = userAgent.match(/Edge\/(\d+)/);
200
- if (!match || match[1] >= 74) {
201
- match = userAgent.match(/Chrome\/(\d+)/);
202
- if (match) version = +match[1];
54
+ const ZOHO_RECRUIT_SERVICE_NAME = 'recruit';
55
+ function zohoRecruitConfigApiUrl(input) {
56
+ switch (input) {
57
+ case 'sandbox':
58
+ return 'https://recruitsandbox.zoho.com/recruit';
59
+ case 'production':
60
+ return 'https://recruit.zoho.com/recruit';
61
+ default:
62
+ return input;
203
63
  }
204
64
  }
205
65
 
206
- var engineV8Version = version;
207
-
208
- /* eslint-disable es/no-symbol -- required for testing */
209
- var V8_VERSION = engineV8Version;
210
- var fails$8 = fails$c;
211
- var global$8 = global$b;
212
-
213
- var $String$3 = global$8.String;
214
-
215
- // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing
216
- var symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$8(function () {
217
- var symbol = Symbol('symbol detection');
218
- // Chrome 38 Symbol has incorrect toString conversion
219
- // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
220
- // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
221
- // of course, fail.
222
- return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
223
- // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
224
- !Symbol.sham && V8_VERSION && V8_VERSION < 41;
225
- });
226
-
227
- /* eslint-disable es/no-symbol -- required for testing */
228
- var NATIVE_SYMBOL$1 = symbolConstructorDetection;
229
-
230
- var useSymbolAsUid = NATIVE_SYMBOL$1
231
- && !Symbol.sham
232
- && typeof Symbol.iterator == 'symbol';
233
-
234
- var getBuiltIn$2 = getBuiltIn$3;
235
- var isCallable$b = isCallable$e;
236
- var isPrototypeOf$2 = objectIsPrototypeOf;
237
- var USE_SYMBOL_AS_UID$1 = useSymbolAsUid;
238
-
239
- var $Object$3 = Object;
240
-
241
- var isSymbol$2 = USE_SYMBOL_AS_UID$1 ? function (it) {
242
- return typeof it == 'symbol';
243
- } : function (it) {
244
- var $Symbol = getBuiltIn$2('Symbol');
245
- return isCallable$b($Symbol) && isPrototypeOf$2($Symbol.prototype, $Object$3(it));
246
- };
247
-
248
- var $String$2 = String;
66
+ /**
67
+ * Candidates module name
68
+ */
69
+ const ZOHO_RECRUIT_CANDIDATES_MODULE = 'Candidates';
70
+ /**
71
+ * Job Openings module name
72
+ */
73
+ const ZOHO_RECRUIT_JOB_OPENINGS_MODULE = 'Job_Openings';
74
+ /**
75
+ * Notes module name
76
+ */
77
+ const ZOHO_RECRUIT_NOTES_MODULE = 'Notes';
78
+ /**
79
+ * Emails module name
80
+ */
81
+ const ZOHO_RECRUIT_EMAILS_MODULE = 'Emails';
82
+ /**
83
+ * Attachments module name
84
+ */
85
+ const ZOHO_RECRUIT_ATTACHMENTS_MODULE = 'Attachments';
86
+ /**
87
+ * Returns true if it is a valid ZohoRecruitValidUrl.
88
+ */
89
+ const isZohoRecruitValidUrl = isStandardInternetAccessibleWebsiteUrl;
90
+ const ZOHO_RECRUIT_RECORD_ATTACHMENT_METADATA_ATTACH_TYPE_RESUME = 'Resume';
249
91
 
250
- var tryToString$3 = function (argument) {
251
- try {
252
- return $String$2(argument);
253
- } catch (error) {
254
- return 'Object';
92
+ /**
93
+ * Can search up to 10 criteria at a time.
94
+ *
95
+ * https://www.zoho.com/crm/developer/docs/api/v8/search-records.html
96
+ * https://www.zoho.com/recruit/developer-guide/apiv2/search-records.html
97
+ *
98
+ * "You can search for a maximum of 10 criteria (with the same or different column) with equals and starts_with conditions."
99
+ */
100
+ const MAX_ZOHO_SEARCH_MODULE_RECORDS_CRITERIA = 10;
101
+ /**
102
+ * Creates a ZohoSearchRecordsCriteriaString from a ZohoSearchRecordsCriteriaTree.
103
+ *
104
+ * If the input tree is empty, returns undefined.
105
+ */
106
+ function zohoSearchRecordsCriteriaString(input) {
107
+ let result;
108
+ if (input != null) {
109
+ switch (typeof input) {
110
+ case 'string':
111
+ result = input;
112
+ break;
113
+ case 'object':
114
+ let tree;
115
+ if (Array.isArray(input)) {
116
+ tree = {
117
+ and: [input]
118
+ };
119
+ } else {
120
+ tree = input;
121
+ }
122
+ result = zohoSearchRecordsCriteriaStringForTree(tree);
123
+ break;
124
+ }
255
125
  }
256
- };
257
-
258
- var isCallable$a = isCallable$e;
259
- var tryToString$2 = tryToString$3;
260
-
261
- var $TypeError$a = TypeError;
262
-
263
- // `Assert: IsCallable(argument) is true`
264
- var aCallable$7 = function (argument) {
265
- if (isCallable$a(argument)) return argument;
266
- throw new $TypeError$a(tryToString$2(argument) + ' is not a function');
267
- };
268
-
269
- var aCallable$6 = aCallable$7;
270
- var isNullOrUndefined$1 = isNullOrUndefined$3;
271
-
272
- // `GetMethod` abstract operation
273
- // https://tc39.es/ecma262/#sec-getmethod
274
- var getMethod$4 = function (V, P) {
275
- var func = V[P];
276
- return isNullOrUndefined$1(func) ? undefined : aCallable$6(func);
277
- };
278
-
279
- var call$a = functionCall;
280
- var isCallable$9 = isCallable$e;
281
- var isObject$5 = isObject$6;
282
-
283
- var $TypeError$9 = TypeError;
284
-
285
- // `OrdinaryToPrimitive` abstract operation
286
- // https://tc39.es/ecma262/#sec-ordinarytoprimitive
287
- var ordinaryToPrimitive$1 = function (input, pref) {
288
- var fn, val;
289
- if (pref === 'string' && isCallable$9(fn = input.toString) && !isObject$5(val = call$a(fn, input))) return val;
290
- if (isCallable$9(fn = input.valueOf) && !isObject$5(val = call$a(fn, input))) return val;
291
- if (pref !== 'string' && isCallable$9(fn = input.toString) && !isObject$5(val = call$a(fn, input))) return val;
292
- throw new $TypeError$9("Can't convert object to primitive value");
293
- };
294
-
295
- var sharedStore = {exports: {}};
296
-
297
- var isPure = false;
298
-
299
- var global$7 = global$b;
300
-
301
- // eslint-disable-next-line es/no-object-defineproperty -- safe
302
- var defineProperty$2 = Object.defineProperty;
303
-
304
- var defineGlobalProperty$3 = function (key, value) {
305
- try {
306
- defineProperty$2(global$7, key, { value: value, configurable: true, writable: true });
307
- } catch (error) {
308
- global$7[key] = value;
309
- } return value;
310
- };
311
-
312
- var globalThis$1 = global$b;
313
- var defineGlobalProperty$2 = defineGlobalProperty$3;
314
-
315
- var SHARED = '__core-js_shared__';
316
- var store$3 = sharedStore.exports = globalThis$1[SHARED] || defineGlobalProperty$2(SHARED, {});
317
-
318
- (store$3.versions || (store$3.versions = [])).push({
319
- version: '3.36.1',
320
- mode: 'global',
321
- copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)',
322
- license: 'https://github.com/zloirock/core-js/blob/v3.36.1/LICENSE',
323
- source: 'https://github.com/zloirock/core-js'
126
+ return result;
127
+ }
128
+ function zohoSearchRecordsCriteriaStringForTree(tree) {
129
+ function convertToString(value) {
130
+ let result;
131
+ if (typeof value === 'object') {
132
+ // array of criteria entries
133
+ if (Array.isArray(value)) {
134
+ result = value.map(zohoSearchRecordsCriteriaEntryToCriteriaString);
135
+ } else if (value) {
136
+ // criteria tree that first needs to be converted to a string
137
+ result = zohoSearchRecordsCriteriaStringForTree(value);
138
+ }
139
+ } else {
140
+ result = value;
141
+ }
142
+ return result;
143
+ }
144
+ function mergeStringValues(values, type) {
145
+ return values.length > 1 ? `(${values.join(type)})` : values[0]; // wrap in and values
146
+ }
147
+ function mergeValues(values, type) {
148
+ const allStrings = filterMaybeArrayValues(values.map(convertToString)).flatMap(asArray);
149
+ return mergeStringValues(allStrings, type);
150
+ }
151
+ const orValues = tree.or ? mergeValues(tree.or, 'or') : undefined;
152
+ let result = orValues;
153
+ if (tree.and) {
154
+ result = mergeValues([mergeValues(tree.and, 'and'), orValues], 'and');
155
+ }
156
+ return result;
157
+ }
158
+ /**
159
+ * Escape used for ZohoSearchRecordsCriteriaString
160
+ */
161
+ const escapeZohoFieldValueForCriteriaString = escapeStringCharactersFunction({
162
+ /**
163
+ * Parenthesis and commas must be escaped using a backslash
164
+ */
165
+ escapeTargets: ['(', ')', ','],
166
+ escapeCharacter: char => `\\\\${char}`
324
167
  });
168
+ /**
169
+ * Converts the input entry to a ZohoSearchRecordsCriteriaString. Properly escapes any parenthesis or commas.
170
+ *
171
+ * @param entry
172
+ * @returns
173
+ */
174
+ function zohoSearchRecordsCriteriaEntryToCriteriaString(entry) {
175
+ const escapedValue = escapeZohoFieldValueForCriteriaString(entry.value);
176
+ return `(${entry.field}:${entry.filter}:${escapedValue})`;
177
+ }
325
178
 
326
- var sharedStoreExports = sharedStore.exports;
327
-
328
- var store$2 = sharedStoreExports;
329
-
330
- var shared$3 = function (key, value) {
331
- return store$2[key] || (store$2[key] = value || {});
332
- };
333
-
334
- var requireObjectCoercible = requireObjectCoercible$2;
335
-
336
- var $Object$2 = Object;
337
-
338
- // `ToObject` abstract operation
339
- // https://tc39.es/ecma262/#sec-toobject
340
- var toObject$3 = function (argument) {
341
- return $Object$2(requireObjectCoercible(argument));
342
- };
343
-
344
- var uncurryThis$7 = functionUncurryThis;
345
- var toObject$2 = toObject$3;
346
-
347
- var hasOwnProperty = uncurryThis$7({}.hasOwnProperty);
348
-
349
- // `HasOwnProperty` abstract operation
350
- // https://tc39.es/ecma262/#sec-hasownproperty
351
- // eslint-disable-next-line es/no-object-hasown -- safe
352
- var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) {
353
- return hasOwnProperty(toObject$2(it), key);
354
- };
355
-
356
- var uncurryThis$6 = functionUncurryThis;
357
-
358
- var id = 0;
359
- var postfix = Math.random();
360
- var toString = uncurryThis$6(1.0.toString);
179
+ /**
180
+ * Can search up to 10 criteria at a time.
181
+ *
182
+ * https://www.zoho.com/recruit/developer-guide/apiv2/search-records.html
183
+ *
184
+ * "You can search for a maximum of 10 criteria (with the same or different column) with equals and starts_with conditions."
185
+ */
186
+ const MAX_ZOHO_RECRUIT_SEARCH_MODULE_RECORDS_CRITERIA = MAX_ZOHO_SEARCH_MODULE_RECORDS_CRITERIA;
187
+ const zohoRecruitSearchRecordsCriteriaString = zohoSearchRecordsCriteriaString;
188
+ const zohoRecruitSearchRecordsCriteriaStringForTree = zohoSearchRecordsCriteriaStringForTree;
189
+ const zohoRecruitSearchRecordsCriteriaEntryToCriteriaString = zohoSearchRecordsCriteriaEntryToCriteriaString;
361
190
 
362
- var uid$2 = function (key) {
363
- return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);
364
- };
365
-
366
- var global$6 = global$b;
367
- var shared$2 = shared$3;
368
- var hasOwn$8 = hasOwnProperty_1;
369
- var uid$1 = uid$2;
370
- var NATIVE_SYMBOL = symbolConstructorDetection;
371
- var USE_SYMBOL_AS_UID = useSymbolAsUid;
372
-
373
- var Symbol$1 = global$6.Symbol;
374
- var WellKnownSymbolsStore = shared$2('wks');
375
- var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1['for'] || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid$1;
376
-
377
- var wellKnownSymbol$8 = function (name) {
378
- if (!hasOwn$8(WellKnownSymbolsStore, name)) {
379
- WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$8(Symbol$1, name)
380
- ? Symbol$1[name]
381
- : createWellKnownSymbol('Symbol.' + name);
382
- } return WellKnownSymbolsStore[name];
383
- };
384
-
385
- var call$9 = functionCall;
386
- var isObject$4 = isObject$6;
387
- var isSymbol$1 = isSymbol$2;
388
- var getMethod$3 = getMethod$4;
389
- var ordinaryToPrimitive = ordinaryToPrimitive$1;
390
- var wellKnownSymbol$7 = wellKnownSymbol$8;
391
-
392
- var $TypeError$8 = TypeError;
393
- var TO_PRIMITIVE = wellKnownSymbol$7('toPrimitive');
394
-
395
- // `ToPrimitive` abstract operation
396
- // https://tc39.es/ecma262/#sec-toprimitive
397
- var toPrimitive$1 = function (input, pref) {
398
- if (!isObject$4(input) || isSymbol$1(input)) return input;
399
- var exoticToPrim = getMethod$3(input, TO_PRIMITIVE);
400
- var result;
401
- if (exoticToPrim) {
402
- if (pref === undefined) pref = 'default';
403
- result = call$9(exoticToPrim, input, pref);
404
- if (!isObject$4(result) || isSymbol$1(result)) return result;
405
- throw new $TypeError$8("Can't convert object to primitive value");
191
+ /**
192
+ * Default place-holder used by the ZohoServerFetchResponseDataArrayError class.
193
+ */
194
+ const ZOHO_DATA_ARRAY_BLANK_ERROR_CODE = '__internal_data_array_blank_error';
195
+ /**
196
+ * Returns true if the input value is a ZohoServerErrorResponseDataArrayRef.
197
+ *
198
+ * @param value
199
+ * @returns
200
+ */
201
+ function isZohoServerErrorResponseDataArrayRef(value) {
202
+ return Array.isArray(value?.data);
203
+ }
204
+ /**
205
+ * A code used in some cases to denote success.
206
+ */
207
+ const ZOHO_SUCCESS_CODE = 'SUCCESS';
208
+ /**
209
+ * Lowercase status code
210
+ */
211
+ const ZOHO_SUCCESS_STATUS = 'success';
212
+ /**
213
+ * Set in the status field
214
+ */
215
+ const ZOHO_ERROR_STATUS = 'error';
216
+ function zohoServerErrorData(error) {
217
+ const errorType = typeof error;
218
+ let errorData;
219
+ if (errorType === 'object') {
220
+ errorData = error;
221
+ } else {
222
+ errorData = {
223
+ code: error,
224
+ message: ''
225
+ };
406
226
  }
407
- if (pref === undefined) pref = 'number';
408
- return ordinaryToPrimitive(input, pref);
409
- };
410
-
411
- var toPrimitive = toPrimitive$1;
412
- var isSymbol = isSymbol$2;
413
-
414
- // `ToPropertyKey` abstract operation
415
- // https://tc39.es/ecma262/#sec-topropertykey
416
- var toPropertyKey$2 = function (argument) {
417
- var key = toPrimitive(argument, 'string');
418
- return isSymbol(key) ? key : key + '';
419
- };
420
-
421
- var global$5 = global$b;
422
- var isObject$3 = isObject$6;
423
-
424
- var document$1 = global$5.document;
425
- // typeof document.createElement is 'object' in old IE
426
- var EXISTS$1 = isObject$3(document$1) && isObject$3(document$1.createElement);
427
-
428
- var documentCreateElement$1 = function (it) {
429
- return EXISTS$1 ? document$1.createElement(it) : {};
430
- };
431
-
432
- var DESCRIPTORS$a = descriptors;
433
- var fails$7 = fails$c;
434
- var createElement = documentCreateElement$1;
435
-
436
- // Thanks to IE8 for its funny defineProperty
437
- var ie8DomDefine = !DESCRIPTORS$a && !fails$7(function () {
438
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
439
- return Object.defineProperty(createElement('div'), 'a', {
440
- get: function () { return 7; }
441
- }).a !== 7;
442
- });
443
-
444
- var DESCRIPTORS$9 = descriptors;
445
- var call$8 = functionCall;
446
- var propertyIsEnumerableModule = objectPropertyIsEnumerable;
447
- var createPropertyDescriptor$2 = createPropertyDescriptor$3;
448
- var toIndexedObject$3 = toIndexedObject$4;
449
- var toPropertyKey$1 = toPropertyKey$2;
450
- var hasOwn$7 = hasOwnProperty_1;
451
- var IE8_DOM_DEFINE$1 = ie8DomDefine;
452
-
453
- // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
454
- var $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
455
-
456
- // `Object.getOwnPropertyDescriptor` method
457
- // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
458
- objectGetOwnPropertyDescriptor.f = DESCRIPTORS$9 ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O, P) {
459
- O = toIndexedObject$3(O);
460
- P = toPropertyKey$1(P);
461
- if (IE8_DOM_DEFINE$1) try {
462
- return $getOwnPropertyDescriptor$1(O, P);
463
- } catch (error) { /* empty */ }
464
- if (hasOwn$7(O, P)) return createPropertyDescriptor$2(!call$8(propertyIsEnumerableModule.f, O, P), O[P]);
465
- };
466
-
467
- var objectDefineProperty = {};
468
-
469
- var DESCRIPTORS$8 = descriptors;
470
- var fails$6 = fails$c;
471
-
472
- // V8 ~ Chrome 36-
473
- // https://bugs.chromium.org/p/v8/issues/detail?id=3334
474
- var v8PrototypeDefineBug = DESCRIPTORS$8 && fails$6(function () {
475
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
476
- return Object.defineProperty(function () { /* empty */ }, 'prototype', {
477
- value: 42,
478
- writable: false
479
- }).prototype !== 42;
480
- });
481
-
482
- var isObject$2 = isObject$6;
483
-
484
- var $String$1 = String;
485
- var $TypeError$7 = TypeError;
486
-
487
- // `Assert: Type(argument) is Object`
488
- var anObject$e = function (argument) {
489
- if (isObject$2(argument)) return argument;
490
- throw new $TypeError$7($String$1(argument) + ' is not an object');
491
- };
492
-
493
- var DESCRIPTORS$7 = descriptors;
494
- var IE8_DOM_DEFINE = ie8DomDefine;
495
- var V8_PROTOTYPE_DEFINE_BUG$1 = v8PrototypeDefineBug;
496
- var anObject$d = anObject$e;
497
- var toPropertyKey = toPropertyKey$2;
498
-
499
- var $TypeError$6 = TypeError;
500
- // eslint-disable-next-line es/no-object-defineproperty -- safe
501
- var $defineProperty = Object.defineProperty;
502
- // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
503
- var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
504
- var ENUMERABLE = 'enumerable';
505
- var CONFIGURABLE$1 = 'configurable';
506
- var WRITABLE = 'writable';
507
-
508
- // `Object.defineProperty` method
509
- // https://tc39.es/ecma262/#sec-object.defineproperty
510
- objectDefineProperty.f = DESCRIPTORS$7 ? V8_PROTOTYPE_DEFINE_BUG$1 ? function defineProperty(O, P, Attributes) {
511
- anObject$d(O);
512
- P = toPropertyKey(P);
513
- anObject$d(Attributes);
514
- if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {
515
- var current = $getOwnPropertyDescriptor(O, P);
516
- if (current && current[WRITABLE]) {
517
- O[P] = Attributes.value;
518
- Attributes = {
519
- configurable: CONFIGURABLE$1 in Attributes ? Attributes[CONFIGURABLE$1] : current[CONFIGURABLE$1],
520
- enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],
521
- writable: false
522
- };
227
+ return errorData;
228
+ }
229
+ /**
230
+ * Zoho Server Error
231
+ */
232
+ class ZohoServerError extends BaseError {
233
+ get code() {
234
+ return this.error.code;
235
+ }
236
+ constructor(error) {
237
+ super(error.message);
238
+ this.error = void 0;
239
+ this.error = error;
240
+ }
241
+ }
242
+ /**
243
+ * Zoho Server Error that includes the FetchResponseError
244
+ */
245
+ class ZohoServerFetchResponseError extends ZohoServerError {
246
+ constructor(data, errorResponseData, responseError) {
247
+ super(data);
248
+ this.data = void 0;
249
+ this.errorResponseData = void 0;
250
+ this.responseError = void 0;
251
+ this.data = data;
252
+ this.errorResponseData = errorResponseData;
253
+ this.responseError = responseError;
254
+ }
255
+ }
256
+ /**
257
+ * Used as a transient error for situations where there are potentially multiple errors within the data array returned.
258
+ *
259
+ * Zoho CRM returns a non-200 error as a result, but generally there is a partial success that can occur, with both
260
+ * the successful and errored results returned within the data.
261
+ */
262
+ class ZohoServerFetchResponseDataArrayError extends ZohoServerFetchResponseError {
263
+ constructor(errorResponseData, responseError) {
264
+ super({
265
+ code: ZOHO_DATA_ARRAY_BLANK_ERROR_CODE,
266
+ message: 'Check data for individual errors.'
267
+ }, errorResponseData, responseError);
268
+ }
269
+ get errorDataArray() {
270
+ return this.errorResponseData.data;
271
+ }
272
+ }
273
+ /**
274
+ * Creates a logZohoServerErrorFunction that logs the error to console.
275
+ *
276
+ * @param zohoApiNamePrefix Prefix to use when logging. I.E. ZohoRecruitError, etc.
277
+ * @returns
278
+ */
279
+ function logZohoServerErrorFunction(zohoApiNamePrefix, options) {
280
+ const {
281
+ logDataArrayErrors = false
282
+ } = options ?? {};
283
+ return error => {
284
+ if (error instanceof ZohoServerFetchResponseDataArrayError && !logDataArrayErrors) ; else if (error instanceof ZohoServerFetchResponseError) {
285
+ console.log(`${zohoApiNamePrefix}Error(${error.responseError.response.status}): `, {
286
+ error,
287
+ errorData: error.data
288
+ });
289
+ } else if (error instanceof ZohoServerError) {
290
+ console.log(`${zohoApiNamePrefix}Error(code:${error.code}): `, {
291
+ error
292
+ });
293
+ } else {
294
+ console.log(`${zohoApiNamePrefix}Error(name:${error.name}): `, {
295
+ error
296
+ });
523
297
  }
524
- } return $defineProperty(O, P, Attributes);
525
- } : $defineProperty : function defineProperty(O, P, Attributes) {
526
- anObject$d(O);
527
- P = toPropertyKey(P);
528
- anObject$d(Attributes);
529
- if (IE8_DOM_DEFINE) try {
530
- return $defineProperty(O, P, Attributes);
531
- } catch (error) { /* empty */ }
532
- if ('get' in Attributes || 'set' in Attributes) throw new $TypeError$6('Accessors not supported');
533
- if ('value' in Attributes) O[P] = Attributes.value;
534
- return O;
535
- };
536
-
537
- var DESCRIPTORS$6 = descriptors;
538
- var definePropertyModule$4 = objectDefineProperty;
539
- var createPropertyDescriptor$1 = createPropertyDescriptor$3;
540
-
541
- var createNonEnumerableProperty$3 = DESCRIPTORS$6 ? function (object, key, value) {
542
- return definePropertyModule$4.f(object, key, createPropertyDescriptor$1(1, value));
543
- } : function (object, key, value) {
544
- object[key] = value;
545
- return object;
546
- };
547
-
548
- var makeBuiltIn$3 = {exports: {}};
549
-
550
- var DESCRIPTORS$5 = descriptors;
551
- var hasOwn$6 = hasOwnProperty_1;
552
-
553
- var FunctionPrototype = Function.prototype;
554
- // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
555
- var getDescriptor = DESCRIPTORS$5 && Object.getOwnPropertyDescriptor;
556
-
557
- var EXISTS = hasOwn$6(FunctionPrototype, 'name');
558
- // additional protection from minified / mangled / dropped function names
559
- var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';
560
- var CONFIGURABLE = EXISTS && (!DESCRIPTORS$5 || (DESCRIPTORS$5 && getDescriptor(FunctionPrototype, 'name').configurable));
561
-
562
- var functionName = {
563
- EXISTS: EXISTS,
564
- PROPER: PROPER,
565
- CONFIGURABLE: CONFIGURABLE
566
- };
567
-
568
- var uncurryThis$5 = functionUncurryThis;
569
- var isCallable$8 = isCallable$e;
570
- var store$1 = sharedStoreExports;
571
-
572
- var functionToString = uncurryThis$5(Function.toString);
573
-
574
- // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper
575
- if (!isCallable$8(store$1.inspectSource)) {
576
- store$1.inspectSource = function (it) {
577
- return functionToString(it);
578
298
  };
579
299
  }
580
-
581
- var inspectSource$1 = store$1.inspectSource;
582
-
583
- var global$4 = global$b;
584
- var isCallable$7 = isCallable$e;
585
-
586
- var WeakMap$1 = global$4.WeakMap;
587
-
588
- var weakMapBasicDetection = isCallable$7(WeakMap$1) && /native code/.test(String(WeakMap$1));
589
-
590
- var shared$1 = shared$3;
591
- var uid = uid$2;
592
-
593
- var keys = shared$1('keys');
594
-
595
- var sharedKey$3 = function (key) {
596
- return keys[key] || (keys[key] = uid(key));
597
- };
598
-
599
- var hiddenKeys$4 = {};
600
-
601
- var NATIVE_WEAK_MAP = weakMapBasicDetection;
602
- var global$3 = global$b;
603
- var isObject$1 = isObject$6;
604
- var createNonEnumerableProperty$2 = createNonEnumerableProperty$3;
605
- var hasOwn$5 = hasOwnProperty_1;
606
- var shared = sharedStoreExports;
607
- var sharedKey$2 = sharedKey$3;
608
- var hiddenKeys$3 = hiddenKeys$4;
609
-
610
- var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
611
- var TypeError$1 = global$3.TypeError;
612
- var WeakMap = global$3.WeakMap;
613
- var set, get, has;
614
-
615
- var enforce = function (it) {
616
- return has(it) ? get(it) : set(it, {});
617
- };
618
-
619
- var getterFor = function (TYPE) {
620
- return function (it) {
621
- var state;
622
- if (!isObject$1(it) || (state = get(it)).type !== TYPE) {
623
- throw new TypeError$1('Incompatible receiver, ' + TYPE + ' required');
624
- } return state;
625
- };
626
- };
627
-
628
- if (NATIVE_WEAK_MAP || shared.state) {
629
- var store = shared.state || (shared.state = new WeakMap());
630
- /* eslint-disable no-self-assign -- prototype methods protection */
631
- store.get = store.get;
632
- store.has = store.has;
633
- store.set = store.set;
634
- /* eslint-enable no-self-assign -- prototype methods protection */
635
- set = function (it, metadata) {
636
- if (store.has(it)) throw new TypeError$1(OBJECT_ALREADY_INITIALIZED);
637
- metadata.facade = it;
638
- store.set(it, metadata);
639
- return metadata;
640
- };
641
- get = function (it) {
642
- return store.get(it) || {};
643
- };
644
- has = function (it) {
645
- return store.has(it);
646
- };
647
- } else {
648
- var STATE = sharedKey$2('state');
649
- hiddenKeys$3[STATE] = true;
650
- set = function (it, metadata) {
651
- if (hasOwn$5(it, STATE)) throw new TypeError$1(OBJECT_ALREADY_INITIALIZED);
652
- metadata.facade = it;
653
- createNonEnumerableProperty$2(it, STATE, metadata);
654
- return metadata;
655
- };
656
- get = function (it) {
657
- return hasOwn$5(it, STATE) ? it[STATE] : {};
300
+ /**
301
+ * Wraps a ConfiguredFetch to support handling errors returned by fetch.
302
+ *
303
+ * @param fetch
304
+ * @returns
305
+ */
306
+ function handleZohoErrorFetchFactory(parseZohoError, defaultLogError) {
307
+ return (fetch, logError = defaultLogError, onError) => {
308
+ return async (x, y) => {
309
+ try {
310
+ return await fetch(x, y); // await to catch thrown errors
311
+ } catch (e) {
312
+ if (e instanceof FetchResponseError) {
313
+ const error = await parseZohoError(e);
314
+ if (error) {
315
+ logError(error); // log before throwing.
316
+ onError?.(error); // perform a task
317
+ throw error;
318
+ }
319
+ }
320
+ throw e;
321
+ }
322
+ };
658
323
  };
659
- has = function (it) {
660
- return hasOwn$5(it, STATE);
324
+ }
325
+ /**
326
+ * FetchJsonInterceptJsonResponseFunction that intercepts a 200 response that actually contains a ZohoServerError and throws a ZohoServerError for the error handling to catch.
327
+ */
328
+ function interceptZohoErrorResponseFactory(parseZohoServerErrorResponseData) {
329
+ return (json, response) => {
330
+ const error = json?.error;
331
+ if (error != null) {
332
+ const responseError = new FetchResponseError(response);
333
+ if (responseError) {
334
+ const parsedError = parseZohoServerErrorResponseData(json, responseError);
335
+ if (parsedError) {
336
+ throw parsedError;
337
+ }
338
+ }
339
+ }
340
+ return json;
661
341
  };
662
342
  }
343
+ // MARK: Parsed Errors
344
+ /**
345
+ * Error in the following (but not limited to) cases:
346
+ * - An extra parameter is provided
347
+ */
348
+ const ZOHO_INTERNAL_ERROR_CODE = 'INTERNAL_ERROR';
349
+ /**
350
+ * Error code for when an invalid oauth token is provided.
351
+ */
352
+ const ZOHO_INVALID_TOKEN_ERROR_CODE = 'INVALID_TOKEN';
353
+ class ZohoInvalidTokenError extends ZohoServerFetchResponseError {}
354
+ /**
355
+ * Error code for when a failure occured for the given action
356
+ */
357
+ const ZOHO_FAILURE_ERROR_CODE = 'FAILURE';
358
+ /**
359
+ * Error when the Zoho API returns an internal error
360
+ */
361
+ class ZohoInternalError extends ZohoServerFetchResponseError {}
362
+ /**
363
+ * Error in the following cases:
364
+ * - Authorization is not properly constructed ("Invalid Ticket Id")
365
+ * - OAuth token is expired ("Invalid OAuthtoken")
366
+ */
367
+ const ZOHO_INVALID_AUTHORIZATION_ERROR_CODE = '4834';
368
+ /**
369
+ * Error when the Zoho API returns an invalid authorization error code.
370
+ */
371
+ class ZohoInvalidAuthorizationError extends ZohoServerFetchResponseError {}
372
+ /**
373
+ * Error in the following cases:
374
+ * - Search query is invalid
375
+ */
376
+ const ZOHO_INVALID_QUERY_ERROR_CODE = 'INVALID_QUERY';
377
+ class ZohoInvalidQueryError extends ZohoServerFetchResponseError {
378
+ get details() {
379
+ return this.error.details;
380
+ }
381
+ }
382
+ /**
383
+ * Error when a mandatory field is missing.
384
+ */
385
+ const ZOHO_MANDATORY_NOT_FOUND_ERROR_CODE = 'MANDATORY_NOT_FOUND';
386
+ /**
387
+ * Error when a duplicate record is found with a matching unique field value.
388
+ */
389
+ const ZOHO_DUPLICATE_DATA_ERROR_CODE = 'DUPLICATE_DATA';
390
+ /**
391
+ * Error when some passed data is invalid.
392
+ */
393
+ const ZOHO_INVALID_DATA_ERROR_CODE = 'INVALID_DATA';
394
+ /**
395
+ * Error when too many requests are made in a short period of time.
396
+ */
397
+ const ZOHO_TOO_MANY_REQUESTS_ERROR_CODE = 'TOO_MANY_REQUESTS';
398
+ /**
399
+ * The status code that Zoho uses to indicates that too many requests have been made in a short period of time.
400
+ */
401
+ const ZOHO_TOO_MANY_REQUESTS_HTTP_STATUS_CODE = 429;
402
+ const ZOHO_RATE_LIMIT_LIMIT_HEADER = 'X-RATELIMIT-LIMIT';
403
+ const ZOHO_RATE_LIMIT_REMAINING_HEADER = 'X-RATELIMIT-REMAINING';
404
+ const ZOHO_RATE_LIMIT_RESET_HEADER = 'X-RATELIMIT-RESET';
405
+ const DEFAULT_ZOHO_API_RATE_LIMIT = 100;
406
+ const DEFAULT_ZOHO_API_RATE_LIMIT_RESET_PERIOD = MS_IN_MINUTE;
407
+ function zohoRateLimitHeaderDetails(headers) {
408
+ const limitHeader = headers.get(ZOHO_RATE_LIMIT_LIMIT_HEADER);
409
+ const remainingHeader = headers.get(ZOHO_RATE_LIMIT_REMAINING_HEADER);
410
+ const resetHeader = headers.get(ZOHO_RATE_LIMIT_RESET_HEADER);
411
+ let result = null;
412
+ if (limitHeader != null && remainingHeader != null && resetHeader != null) {
413
+ const limit = Number(limitHeader);
414
+ const remaining = Number(remainingHeader);
415
+ const reset = Number(resetHeader);
416
+ const resetAt = new Date(reset);
417
+ result = {
418
+ limit,
419
+ remaining,
420
+ reset,
421
+ resetAt
422
+ };
423
+ }
424
+ return result;
425
+ }
426
+ class ZohoTooManyRequestsError extends ZohoServerFetchResponseError {
427
+ get headerDetails() {
428
+ return zohoRateLimitHeaderDetails(this.responseError.response.headers);
429
+ }
430
+ }
431
+ /**
432
+ * Function that parses/transforms a ZohoServerErrorResponseData into a general ZohoServerError or other known error type.
433
+ *
434
+ * @param errorResponseData
435
+ * @param responseError
436
+ * @returns
437
+ */
438
+ function parseZohoServerErrorResponseData(errorResponseData, responseError) {
439
+ let result;
440
+ if (isZohoServerErrorResponseDataArrayRef(errorResponseData)) {
441
+ result = new ZohoServerFetchResponseDataArrayError(errorResponseData, responseError);
442
+ } else {
443
+ const error = tryFindZohoServerErrorData(errorResponseData, responseError);
444
+ if (error) {
445
+ const errorData = zohoServerErrorData(error);
446
+ switch (errorData.code) {
447
+ case ZOHO_INTERNAL_ERROR_CODE:
448
+ result = new ZohoInternalError(errorData, errorResponseData, responseError);
449
+ break;
450
+ case ZOHO_INVALID_TOKEN_ERROR_CODE:
451
+ result = new ZohoInvalidTokenError(errorData, errorResponseData, responseError);
452
+ break;
453
+ case ZOHO_INVALID_AUTHORIZATION_ERROR_CODE:
454
+ result = new ZohoInvalidAuthorizationError(errorData, errorResponseData, responseError);
455
+ break;
456
+ case ZOHO_INVALID_QUERY_ERROR_CODE:
457
+ result = new ZohoInvalidQueryError(errorData, errorResponseData, responseError);
458
+ break;
459
+ case ZOHO_TOO_MANY_REQUESTS_ERROR_CODE:
460
+ result = new ZohoTooManyRequestsError(errorData, errorResponseData, responseError);
461
+ break;
462
+ default:
463
+ result = new ZohoServerFetchResponseError(errorData, errorResponseData, responseError);
464
+ break;
465
+ }
466
+ }
467
+ }
468
+ return result;
469
+ }
470
+ /**
471
+ * Attempts to retrieve an ZohoServerErrorResponseDataError from the input.
472
+ *
473
+ * Non-200 errors returned by the Zoho API are returned as the object directly instead of as an ZohoServerErrorResponseData directly.
474
+ * Zoho CRM returns a ZohoServerErrorResponseDataArrayRef value for errors.
475
+ *
476
+ * @param errorResponseData
477
+ * @param responseError
478
+ * @returns
479
+ */
480
+ function tryFindZohoServerErrorData(errorResponseData, responseError) {
481
+ const error = errorResponseData.error ?? errorResponseData.data?.[0] ?? (!responseError.response.ok ? errorResponseData : undefined);
482
+ return error;
483
+ }
663
484
 
664
- var internalState = {
665
- set: set,
666
- get: get,
667
- has: has,
668
- enforce: enforce,
669
- getterFor: getterFor
670
- };
671
-
672
- var uncurryThis$4 = functionUncurryThis;
673
- var fails$5 = fails$c;
674
- var isCallable$6 = isCallable$e;
675
- var hasOwn$4 = hasOwnProperty_1;
676
- var DESCRIPTORS$4 = descriptors;
677
- var CONFIGURABLE_FUNCTION_NAME = functionName.CONFIGURABLE;
678
- var inspectSource = inspectSource$1;
679
- var InternalStateModule$1 = internalState;
680
-
681
- var enforceInternalState = InternalStateModule$1.enforce;
682
- var getInternalState = InternalStateModule$1.get;
683
- var $String = String;
684
- // eslint-disable-next-line es/no-object-defineproperty -- safe
685
- var defineProperty$1 = Object.defineProperty;
686
- var stringSlice = uncurryThis$4(''.slice);
687
- var replace = uncurryThis$4(''.replace);
688
- var join = uncurryThis$4([].join);
689
-
690
- var CONFIGURABLE_LENGTH = DESCRIPTORS$4 && !fails$5(function () {
691
- return defineProperty$1(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;
692
- });
693
-
694
- var TEMPLATE = String(String).split('String');
695
-
696
- var makeBuiltIn$2 = makeBuiltIn$3.exports = function (value, name, options) {
697
- if (stringSlice($String(name), 0, 7) === 'Symbol(') {
698
- name = '[' + replace($String(name), /^Symbol\(([^)]*)\).*$/, '$1') + ']';
485
+ /**
486
+ * Error code for when two records are already associated with each other.
487
+ *
488
+ * Example being a candidate and a job opening are already associated.
489
+ */
490
+ const ZOHO_RECRUIT_ALREADY_ASSOCIATED_ERROR_CODE = 'ALREADY_ASSOCIATED';
491
+ /**
492
+ * Thrown when a record with the given id has no content. Typically also means it does not exist.
493
+ */
494
+ class ZohoRecruitRecordNoContentError extends BaseError {
495
+ constructor(moduleName, recordId) {
496
+ super(`There was no content or matching records for the content. It may not exist.`);
497
+ this.moduleName = void 0;
498
+ this.recordId = void 0;
499
+ this.moduleName = moduleName;
500
+ this.recordId = recordId;
699
501
  }
700
- if (options && options.getter) name = 'get ' + name;
701
- if (options && options.setter) name = 'set ' + name;
702
- if (!hasOwn$4(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {
703
- if (DESCRIPTORS$4) defineProperty$1(value, 'name', { value: name, configurable: true });
704
- else value.name = name;
502
+ }
503
+ class ZohoRecruitRecordCrudError extends ZohoServerError {}
504
+ class ZohoRecruitRecordCrudMandatoryFieldNotFoundError extends ZohoRecruitRecordCrudError {}
505
+ class ZohoRecruitRecordCrudDuplicateDataError extends ZohoRecruitRecordCrudError {}
506
+ class ZohoRecruitRecordCrudInvalidDataError extends ZohoRecruitRecordCrudError {
507
+ get invalidFieldDetails() {
508
+ return this.error.details;
705
509
  }
706
- if (CONFIGURABLE_LENGTH && options && hasOwn$4(options, 'arity') && value.length !== options.arity) {
707
- defineProperty$1(value, 'length', { value: options.arity });
510
+ }
511
+ class ZohoRecruitRecordCrudNoMatchingRecordError extends ZohoRecruitRecordCrudInvalidDataError {}
512
+ function zohoRecruitRecordCrudError(error) {
513
+ let result;
514
+ switch (error.code) {
515
+ case ZOHO_INVALID_DATA_ERROR_CODE:
516
+ const invalidDataError = new ZohoRecruitRecordCrudInvalidDataError(error);
517
+ if (invalidDataError.invalidFieldDetails['id']) {
518
+ result = new ZohoRecruitRecordCrudNoMatchingRecordError(error);
519
+ } else {
520
+ result = invalidDataError;
521
+ }
522
+ break;
523
+ case ZOHO_MANDATORY_NOT_FOUND_ERROR_CODE:
524
+ result = new ZohoRecruitRecordCrudMandatoryFieldNotFoundError(error);
525
+ break;
526
+ case ZOHO_DUPLICATE_DATA_ERROR_CODE:
527
+ result = new ZohoRecruitRecordCrudDuplicateDataError(error);
528
+ break;
529
+ default:
530
+ result = new ZohoRecruitRecordCrudError(error);
531
+ break;
708
532
  }
709
- try {
710
- if (options && hasOwn$4(options, 'constructor') && options.constructor) {
711
- if (DESCRIPTORS$4) defineProperty$1(value, 'prototype', { writable: false });
712
- // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable
713
- } else if (value.prototype) value.prototype = undefined;
714
- } catch (error) { /* empty */ }
715
- var state = enforceInternalState(value);
716
- if (!hasOwn$4(state, 'source')) {
717
- state.source = join(TEMPLATE, typeof name == 'string' ? name : '');
718
- } return value;
719
- };
720
-
721
- // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
722
- // eslint-disable-next-line no-extend-native -- required
723
- Function.prototype.toString = makeBuiltIn$2(function toString() {
724
- return isCallable$6(this) && getInternalState(this).source || inspectSource(this);
725
- }, 'toString');
726
-
727
- var makeBuiltInExports = makeBuiltIn$3.exports;
728
-
729
- var isCallable$5 = isCallable$e;
730
- var definePropertyModule$3 = objectDefineProperty;
731
- var makeBuiltIn$1 = makeBuiltInExports;
732
- var defineGlobalProperty$1 = defineGlobalProperty$3;
733
-
734
- var defineBuiltIn$3 = function (O, key, value, options) {
735
- if (!options) options = {};
736
- var simple = options.enumerable;
737
- var name = options.name !== undefined ? options.name : key;
738
- if (isCallable$5(value)) makeBuiltIn$1(value, name, options);
739
- if (options.global) {
740
- if (simple) O[key] = value;
741
- else defineGlobalProperty$1(key, value);
742
- } else {
743
- try {
744
- if (!options.unsafe) delete O[key];
745
- else if (O[key]) simple = true;
746
- } catch (error) { /* empty */ }
747
- if (simple) O[key] = value;
748
- else definePropertyModule$3.f(O, key, {
749
- value: value,
750
- enumerable: false,
751
- configurable: !options.nonConfigurable,
752
- writable: !options.nonWritable
753
- });
754
- } return O;
755
- };
756
-
757
- var objectGetOwnPropertyNames = {};
758
-
759
- var ceil = Math.ceil;
760
- var floor = Math.floor;
761
-
762
- // `Math.trunc` method
763
- // https://tc39.es/ecma262/#sec-math.trunc
764
- // eslint-disable-next-line es/no-math-trunc -- safe
765
- var mathTrunc = Math.trunc || function trunc(x) {
766
- var n = +x;
767
- return (n > 0 ? floor : ceil)(n);
768
- };
769
-
770
- var trunc = mathTrunc;
771
-
772
- // `ToIntegerOrInfinity` abstract operation
773
- // https://tc39.es/ecma262/#sec-tointegerorinfinity
774
- var toIntegerOrInfinity$2 = function (argument) {
775
- var number = +argument;
776
- // eslint-disable-next-line no-self-compare -- NaN check
777
- return number !== number || number === 0 ? 0 : trunc(number);
778
- };
779
-
780
- var toIntegerOrInfinity$1 = toIntegerOrInfinity$2;
781
-
782
- var max = Math.max;
783
- var min$1 = Math.min;
784
-
785
- // Helper for a popular repeating case of the spec:
786
- // Let integer be ? ToInteger(index).
787
- // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
788
- var toAbsoluteIndex$1 = function (index, length) {
789
- var integer = toIntegerOrInfinity$1(index);
790
- return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
791
- };
792
-
793
- var toIntegerOrInfinity = toIntegerOrInfinity$2;
794
-
795
- var min = Math.min;
796
-
797
- // `ToLength` abstract operation
798
- // https://tc39.es/ecma262/#sec-tolength
799
- var toLength$1 = function (argument) {
800
- var len = toIntegerOrInfinity(argument);
801
- return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
802
- };
803
-
804
- var toLength = toLength$1;
805
-
806
- // `LengthOfArrayLike` abstract operation
807
- // https://tc39.es/ecma262/#sec-lengthofarraylike
808
- var lengthOfArrayLike$3 = function (obj) {
809
- return toLength(obj.length);
810
- };
811
-
812
- var toIndexedObject$2 = toIndexedObject$4;
813
- var toAbsoluteIndex = toAbsoluteIndex$1;
814
- var lengthOfArrayLike$2 = lengthOfArrayLike$3;
815
-
816
- // `Array.prototype.{ indexOf, includes }` methods implementation
817
- var createMethod = function (IS_INCLUDES) {
818
- return function ($this, el, fromIndex) {
819
- var O = toIndexedObject$2($this);
820
- var length = lengthOfArrayLike$2(O);
821
- if (length === 0) return !IS_INCLUDES && -1;
822
- var index = toAbsoluteIndex(fromIndex, length);
823
- var value;
824
- // Array#includes uses SameValueZero equality algorithm
825
- // eslint-disable-next-line no-self-compare -- NaN check
826
- if (IS_INCLUDES && el !== el) while (length > index) {
827
- value = O[index++];
828
- // eslint-disable-next-line no-self-compare -- NaN check
829
- if (value !== value) return true;
830
- // Array#indexOf ignores holes, Array#includes - not
831
- } else for (;length > index; index++) {
832
- if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
833
- } return !IS_INCLUDES && -1;
533
+ return result;
534
+ }
535
+ function assertZohoRecruitRecordDataArrayResultHasContent(moduleName, recordId) {
536
+ return x => {
537
+ if (x == null || !x.data?.length) {
538
+ throw new ZohoRecruitRecordNoContentError(moduleName, recordId);
539
+ } else {
540
+ return x;
541
+ }
834
542
  };
835
- };
836
-
837
- var arrayIncludes = {
838
- // `Array.prototype.includes` method
839
- // https://tc39.es/ecma262/#sec-array.prototype.includes
840
- includes: createMethod(true),
841
- // `Array.prototype.indexOf` method
842
- // https://tc39.es/ecma262/#sec-array.prototype.indexof
843
- indexOf: createMethod(false)
844
- };
845
-
846
- var uncurryThis$3 = functionUncurryThis;
847
- var hasOwn$3 = hasOwnProperty_1;
848
- var toIndexedObject$1 = toIndexedObject$4;
849
- var indexOf = arrayIncludes.indexOf;
850
- var hiddenKeys$2 = hiddenKeys$4;
851
-
852
- var push = uncurryThis$3([].push);
853
-
854
- var objectKeysInternal = function (object, names) {
855
- var O = toIndexedObject$1(object);
856
- var i = 0;
857
- var result = [];
858
- var key;
859
- for (key in O) !hasOwn$3(hiddenKeys$2, key) && hasOwn$3(O, key) && push(result, key);
860
- // Don't enum bug & hidden keys
861
- while (names.length > i) if (hasOwn$3(O, key = names[i++])) {
862
- ~indexOf(result, key) || push(result, key);
543
+ }
544
+ const logZohoRecruitErrorToConsole = logZohoServerErrorFunction('ZohoRecruit');
545
+ async function parseZohoRecruitError(responseError) {
546
+ const data = await responseError.response.json().catch(x => undefined);
547
+ let result;
548
+ if (data) {
549
+ result = parseZohoRecruitServerErrorResponseData(data, responseError);
863
550
  }
864
551
  return result;
865
- };
866
-
867
- // IE8- don't enum bug keys
868
- var enumBugKeys$3 = [
869
- 'constructor',
870
- 'hasOwnProperty',
871
- 'isPrototypeOf',
872
- 'propertyIsEnumerable',
873
- 'toLocaleString',
874
- 'toString',
875
- 'valueOf'
876
- ];
877
-
878
- var internalObjectKeys$1 = objectKeysInternal;
879
- var enumBugKeys$2 = enumBugKeys$3;
880
-
881
- var hiddenKeys$1 = enumBugKeys$2.concat('length', 'prototype');
882
-
883
- // `Object.getOwnPropertyNames` method
884
- // https://tc39.es/ecma262/#sec-object.getownpropertynames
885
- // eslint-disable-next-line es/no-object-getownpropertynames -- safe
886
- objectGetOwnPropertyNames.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
887
- return internalObjectKeys$1(O, hiddenKeys$1);
888
- };
889
-
890
- var objectGetOwnPropertySymbols = {};
891
-
892
- // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe
893
- objectGetOwnPropertySymbols.f = Object.getOwnPropertySymbols;
894
-
895
- var getBuiltIn$1 = getBuiltIn$3;
896
- var uncurryThis$2 = functionUncurryThis;
897
- var getOwnPropertyNamesModule = objectGetOwnPropertyNames;
898
- var getOwnPropertySymbolsModule = objectGetOwnPropertySymbols;
899
- var anObject$c = anObject$e;
900
-
901
- var concat = uncurryThis$2([].concat);
902
-
903
- // all object keys, includes non-enumerable and symbols
904
- var ownKeys$1 = getBuiltIn$1('Reflect', 'ownKeys') || function ownKeys(it) {
905
- var keys = getOwnPropertyNamesModule.f(anObject$c(it));
906
- var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
907
- return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;
908
- };
909
-
910
- var hasOwn$2 = hasOwnProperty_1;
911
- var ownKeys = ownKeys$1;
912
- var getOwnPropertyDescriptorModule = objectGetOwnPropertyDescriptor;
913
- var definePropertyModule$2 = objectDefineProperty;
552
+ }
553
+ function parseZohoRecruitServerErrorResponseData(errorResponseData, responseError) {
554
+ let result;
555
+ const error = tryFindZohoServerErrorData(errorResponseData, responseError);
556
+ if (error) {
557
+ const errorData = zohoServerErrorData(error);
558
+ switch (errorData.code) {
559
+ // TODO: Add recruit-specific error codes here.
560
+ default:
561
+ result = parseZohoServerErrorResponseData(errorResponseData, responseError);
562
+ break;
563
+ }
564
+ }
565
+ return result;
566
+ }
567
+ const interceptZohoRecruit200StatusWithErrorResponse = interceptZohoErrorResponseFactory(parseZohoRecruitServerErrorResponseData);
568
+ const handleZohoRecruitErrorFetch = handleZohoErrorFetchFactory(parseZohoRecruitError, logZohoRecruitErrorToConsole);
569
+ // MARK: Compat
570
+ /**
571
+ * @deprecated Use assertZohoRecruitRecordDataArrayResultHasContent instead.
572
+ */
573
+ const assertRecordDataArrayResultHasContent = assertZohoRecruitRecordDataArrayResultHasContent;
914
574
 
915
- var copyConstructorProperties$1 = function (target, source, exceptions) {
916
- var keys = ownKeys(source);
917
- var defineProperty = definePropertyModule$2.f;
918
- var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
919
- for (var i = 0; i < keys.length; i++) {
920
- var key = keys[i];
921
- if (!hasOwn$2(target, key) && !(exceptions && hasOwn$2(exceptions, key))) {
922
- defineProperty(target, key, getOwnPropertyDescriptor(source, key));
575
+ // MARK: Insert/Update/Upsert Response
576
+ /**
577
+ * The maximum number of records allowed for most CRUD functions.
578
+ *
579
+ * This is a limit enforced by the Zoho Recruit API
580
+ */
581
+ const ZOHO_RECRUIT_CRUD_FUNCTION_MAX_RECORDS_LIMIT = 100;
582
+ /**
583
+ * The APIs for Insert, Upsert, and Update have the same structure.
584
+ *
585
+ * @returns
586
+ */
587
+ function updateRecordLikeFunction$1(context, fetchUrlPrefix, fetchMethod) {
588
+ return ({
589
+ data,
590
+ module
591
+ }) => context.fetchJson(`/v2/${module}${fetchUrlPrefix}`, zohoRecruitApiFetchJsonInput(fetchMethod, {
592
+ data: asArray(data)
593
+ })).then(x => {
594
+ const isInputMultipleItems = Array.isArray(data);
595
+ const result = zohoRecruitMultiRecordResult(asArray(data), x.data);
596
+ if (isInputMultipleItems) {
597
+ return result;
598
+ } else {
599
+ const {
600
+ successItems,
601
+ errorItems
602
+ } = result;
603
+ if (errorItems[0] != null) {
604
+ throw zohoRecruitRecordCrudError(errorItems[0].result);
605
+ } else {
606
+ return successItems[0].result.details;
607
+ }
608
+ }
609
+ });
610
+ }
611
+ /**
612
+ * Inserts one or more records into Recruit.
613
+ *
614
+ * https://www.zoho.com/recruit/developer-guide/apiv2/insert-records.html
615
+ *
616
+ * @param context
617
+ * @returns
618
+ */
619
+ function zohoRecruitInsertRecord(context) {
620
+ return updateRecordLikeFunction$1(context, '', 'POST');
621
+ }
622
+ /**
623
+ * Updates or inserts one or more records in Recruit.
624
+ *
625
+ * https://www.zoho.com/recruit/developer-guide/apiv2/upsert-records.html
626
+ *
627
+ * @param context
628
+ * @returns
629
+ */
630
+ function zohoRecruitUpsertRecord(context) {
631
+ return updateRecordLikeFunction$1(context, '/upsert', 'POST');
632
+ }
633
+ /**
634
+ * Updates one or more records in Recruit.
635
+ *
636
+ * https://www.zoho.com/recruit/developer-guide/apiv2/update-records.html
637
+ *
638
+ * @param context
639
+ * @returns
640
+ */
641
+ function zohoRecruitUpdateRecord(context) {
642
+ return updateRecordLikeFunction$1(context, '', 'PUT');
643
+ }
644
+ /**
645
+ * Deletes one or more records from the given module.
646
+ *
647
+ * https://www.zoho.com/recruit/developer-guide/apiv2/delete-records.html
648
+ *
649
+ * @param context
650
+ * @returns ZohoRecruitDeleteRecordFunction
651
+ */
652
+ function zohoRecruitDeleteRecord(context) {
653
+ return ({
654
+ ids,
655
+ module,
656
+ wf_trigger
657
+ }) => {
658
+ return context.fetchJson(`/v2/${module}?${makeUrlSearchParams({
659
+ ids,
660
+ wf_trigger
661
+ })}`, zohoRecruitApiFetchJsonInput('DELETE')).then(zohoRecruitChangeObjectLikeResponseSuccessAndErrorPairs);
662
+ };
663
+ }
664
+ /**
665
+ * Retrieves a specific record from the given module.
666
+ *
667
+ * https://www.zoho.com/recruit/developer-guide/apiv2/get-records.html
668
+ *
669
+ * @param context
670
+ * @returns
671
+ */
672
+ function zohoRecruitGetRecordById(context) {
673
+ return input => context.fetchJson(`/v2/${input.module}/${input.id}`, zohoRecruitApiFetchJsonInput('GET')).then(assertZohoRecruitRecordDataArrayResultHasContent(input.module)).then(x => x.data[0]);
674
+ }
675
+ /**
676
+ * Retrieves records from the given module. Used for paginating across all records.
677
+ *
678
+ * https://www.zoho.com/recruit/developer-guide/apiv2/get-records.html
679
+ *
680
+ * @param context
681
+ * @returns
682
+ */
683
+ function zohoRecruitGetRecords(context) {
684
+ return input => context.fetchJson(`/v2/${input.module}?${zohoRecruitUrlSearchParamsMinusModule(input).toString()}`, zohoRecruitApiFetchJsonInput('GET'));
685
+ }
686
+ /**
687
+ * Searches records from the given module.
688
+ *
689
+ * https://www.zoho.com/recruit/developer-guide/apiv2/search-records.html
690
+ *
691
+ * @param context
692
+ * @returns
693
+ */
694
+ function zohoRecruitSearchRecords(context) {
695
+ function searchRecordsUrlSearchParams(input) {
696
+ const baseInput = {
697
+ ...input
698
+ };
699
+ delete baseInput.criteria;
700
+ if (input.criteria != null) {
701
+ const criteriaString = zohoRecruitSearchRecordsCriteriaString(input.criteria);
702
+ baseInput.criteria = criteriaString;
923
703
  }
704
+ if (!baseInput.word && !input.criteria && !input.email && !input.phone) {
705
+ throw new Error('At least one of word, criteria, email, or phone must be provided');
706
+ }
707
+ const urlParams = zohoRecruitUrlSearchParamsMinusModule(baseInput);
708
+ return urlParams;
924
709
  }
925
- };
926
-
927
- var fails$4 = fails$c;
928
- var isCallable$4 = isCallable$e;
929
-
930
- var replacement = /#|\.prototype\./;
931
-
932
- var isForced$1 = function (feature, detection) {
933
- var value = data[normalize(feature)];
934
- return value === POLYFILL ? true
935
- : value === NATIVE ? false
936
- : isCallable$4(detection) ? fails$4(detection)
937
- : !!detection;
938
- };
939
-
940
- var normalize = isForced$1.normalize = function (string) {
941
- return String(string).replace(replacement, '.').toLowerCase();
942
- };
943
-
944
- var data = isForced$1.data = {};
945
- var NATIVE = isForced$1.NATIVE = 'N';
946
- var POLYFILL = isForced$1.POLYFILL = 'P';
947
-
948
- var isForced_1 = isForced$1;
949
-
950
- var global$2 = global$b;
951
- var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
952
- var createNonEnumerableProperty$1 = createNonEnumerableProperty$3;
953
- var defineBuiltIn$2 = defineBuiltIn$3;
954
- var defineGlobalProperty = defineGlobalProperty$3;
955
- var copyConstructorProperties = copyConstructorProperties$1;
956
- var isForced = isForced_1;
957
-
958
- /*
959
- options.target - name of the target object
960
- options.global - target is the global object
961
- options.stat - export as static methods of target
962
- options.proto - export as prototype methods of target
963
- options.real - real prototype method for the `pure` version
964
- options.forced - export even if the native feature is available
965
- options.bind - bind methods to the target, required for the `pure` version
966
- options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
967
- options.unsafe - use the simple assignment of property instead of delete + defineProperty
968
- options.sham - add a flag to not completely full polyfills
969
- options.enumerable - export as enumerable property
970
- options.dontCallGetSet - prevent calling a getter on target
971
- options.name - the .name of the function if it does not match the key
972
- */
973
- var _export = function (options, source) {
974
- var TARGET = options.target;
975
- var GLOBAL = options.global;
976
- var STATIC = options.stat;
977
- var FORCED, target, key, targetProperty, sourceProperty, descriptor;
978
- if (GLOBAL) {
979
- target = global$2;
980
- } else if (STATIC) {
981
- target = global$2[TARGET] || defineGlobalProperty(TARGET, {});
982
- } else {
983
- target = global$2[TARGET] && global$2[TARGET].prototype;
984
- }
985
- if (target) for (key in source) {
986
- sourceProperty = source[key];
987
- if (options.dontCallGetSet) {
988
- descriptor = getOwnPropertyDescriptor$1(target, key);
989
- targetProperty = descriptor && descriptor.value;
990
- } else targetProperty = target[key];
991
- FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
992
- // contained in target
993
- if (!FORCED && targetProperty !== undefined) {
994
- if (typeof sourceProperty == typeof targetProperty) continue;
995
- copyConstructorProperties(sourceProperty, targetProperty);
710
+ return input => context.fetchJson(`/v2/${input.module}/search?${searchRecordsUrlSearchParams(input).toString()}`, zohoRecruitApiFetchJsonInput('GET')).then(x => x ?? {
711
+ data: [],
712
+ info: {
713
+ more_records: false
996
714
  }
997
- // add a flag to not completely full polyfills
998
- if (options.sham || (targetProperty && targetProperty.sham)) {
999
- createNonEnumerableProperty$1(sourceProperty, 'sham', true);
715
+ });
716
+ }
717
+ function zohoRecruitSearchRecordsPageFactory(context) {
718
+ return zohoFetchPageFactory(zohoRecruitSearchRecords(context));
719
+ }
720
+ /**
721
+ * Creates a ZohoRecruitGetRelatedRecordsFunctionFactory, which can be used to create ZohoRecruitGetRelatedRecordsFunction<T> that targets retrieving related records of a given type.
722
+ *
723
+ * https://www.zoho.com/recruit/developer-guide/apiv2/get-related-records.html
724
+ *
725
+ * @param context the ZohoRecruitContext to use
726
+ * @returns a ZohoRecruitGetRelatedRecordsFunctionFactory
727
+ */
728
+ function zohoRecruitGetRelatedRecordsFunctionFactory(context) {
729
+ return config => {
730
+ const {
731
+ targetModule,
732
+ returnEmptyRecordsInsteadOfNull = true
733
+ } = config;
734
+ return input => context.fetchJson(`/v2/${input.module}/${input.id}/${targetModule}?${zohoRecruitUrlSearchParamsMinusIdAndModule(input, input.filter).toString()}`, zohoRecruitApiFetchJsonInput('GET')).then(x => x ?? (returnEmptyRecordsInsteadOfNull !== false ? emptyZohoPageResult() : x));
735
+ };
736
+ }
737
+ function zohoRecruitGetEmailsForRecord(context) {
738
+ return zohoRecruitGetRelatedRecordsFunctionFactory(context)({
739
+ targetModule: ZOHO_RECRUIT_EMAILS_MODULE
740
+ });
741
+ }
742
+ function zohoRecruitGetEmailsForRecordPageFactory(context) {
743
+ return zohoFetchPageFactory(zohoRecruitGetEmailsForRecord(context));
744
+ }
745
+ function zohoRecruitGetAttachmentsForRecord(context) {
746
+ return zohoRecruitGetRelatedRecordsFunctionFactory(context)({
747
+ targetModule: ZOHO_RECRUIT_ATTACHMENTS_MODULE
748
+ });
749
+ }
750
+ function zohoRecruitGetAttachmentsForRecordPageFactory(context) {
751
+ return zohoFetchPageFactory(zohoRecruitGetAttachmentsForRecord(context));
752
+ }
753
+ /**
754
+ * Maximum attachment size allowed by Zoho Recruit.
755
+ *
756
+ * 20MB
757
+ */
758
+ const ZOHO_RECRUIT_ATTACHMENT_MAX_SIZE = 20 * 1024 * 1024;
759
+ /**
760
+ * Uploads an attachment to a record.
761
+ *
762
+ * https://www.zoho.com/recruit/developer-guide/apiv2/upload-attachment.html
763
+ *
764
+ * @param context
765
+ * @returns
766
+ */
767
+ function zohoRecruitUploadAttachmentForRecord(context) {
768
+ return input => {
769
+ const {
770
+ attachmentCategoryId,
771
+ attachmentCategoryName,
772
+ formData
773
+ } = input;
774
+ const urlParams = {
775
+ attachments_category_id: joinStringsWithCommas(attachmentCategoryId),
776
+ attachments_category: joinStringsWithCommas(attachmentCategoryName),
777
+ attachment_url: input.attachmentUrl
778
+ };
779
+ if (!urlParams.attachments_category_id?.length && !urlParams.attachments_category?.length) {
780
+ throw new Error('attachmentCategoryId or attachmentCategoryName must be provided and not empty.');
1000
781
  }
1001
- defineBuiltIn$2(target, key, sourceProperty, options);
1002
- }
1003
- };
1004
-
1005
- var classof$2 = classofRaw$2;
1006
-
1007
- // `IsArray` abstract operation
1008
- // https://tc39.es/ecma262/#sec-isarray
1009
- // eslint-disable-next-line es/no-array-isarray -- safe
1010
- var isArray$1 = Array.isArray || function isArray(argument) {
1011
- return classof$2(argument) === 'Array';
1012
- };
1013
-
1014
- var DESCRIPTORS$3 = descriptors;
1015
- var isArray = isArray$1;
1016
-
1017
- var $TypeError$5 = TypeError;
1018
- // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
1019
- var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
1020
-
1021
- // Safari < 13 does not throw an error in this case
1022
- var SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS$3 && !function () {
1023
- // makes no sense without proper strict mode support
1024
- if (this !== undefined) return true;
1025
- try {
1026
- // eslint-disable-next-line es/no-object-defineproperty -- safe
1027
- Object.defineProperty([], 'length', { writable: false }).length = 1;
1028
- } catch (error) {
1029
- return error instanceof TypeError;
1030
- }
1031
- }();
1032
-
1033
- var arraySetLength = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) {
1034
- if (isArray(O) && !getOwnPropertyDescriptor(O, 'length').writable) {
1035
- throw new $TypeError$5('Cannot set read only .length');
1036
- } return O.length = length;
1037
- } : function (O, length) {
1038
- return O.length = length;
1039
- };
1040
-
1041
- var $TypeError$4 = TypeError;
1042
- var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991
1043
-
1044
- var doesNotExceedSafeInteger$1 = function (it) {
1045
- if (it > MAX_SAFE_INTEGER) throw $TypeError$4('Maximum allowed index exceeded');
1046
- return it;
1047
- };
1048
-
1049
- var $$5 = _export;
1050
- var toObject$1 = toObject$3;
1051
- var lengthOfArrayLike$1 = lengthOfArrayLike$3;
1052
- var setArrayLength = arraySetLength;
1053
- var doesNotExceedSafeInteger = doesNotExceedSafeInteger$1;
1054
- var fails$3 = fails$c;
1055
-
1056
- var INCORRECT_TO_LENGTH = fails$3(function () {
1057
- return [].push.call({ length: 0x100000000 }, 1) !== 4294967297;
1058
- });
1059
-
1060
- // V8 <= 121 and Safari <= 15.4; FF < 23 throws InternalError
1061
- // https://bugs.chromium.org/p/v8/issues/detail?id=12681
1062
- var properErrorOnNonWritableLength = function () {
1063
- try {
1064
- // eslint-disable-next-line es/no-object-defineproperty -- safe
1065
- Object.defineProperty([], 'length', { writable: false }).push();
1066
- } catch (error) {
1067
- return error instanceof TypeError;
1068
- }
1069
- };
1070
-
1071
- var FORCED$1 = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength();
1072
-
1073
- // `Array.prototype.push` method
1074
- // https://tc39.es/ecma262/#sec-array.prototype.push
1075
- $$5({ target: 'Array', proto: true, arity: 1, forced: FORCED$1 }, {
1076
- // eslint-disable-next-line no-unused-vars -- required for `.length`
1077
- push: function push(item) {
1078
- var O = toObject$1(this);
1079
- var len = lengthOfArrayLike$1(O);
1080
- var argCount = arguments.length;
1081
- doesNotExceedSafeInteger(len + argCount);
1082
- for (var i = 0; i < argCount; i++) {
1083
- O[len] = arguments[i];
1084
- len++;
782
+ if (formData != null) {
783
+ delete urlParams.attachment_url;
1085
784
  }
1086
- setArrayLength(O, len);
1087
- return len;
1088
- }
1089
- });
1090
-
1091
- var isPrototypeOf$1 = objectIsPrototypeOf;
1092
-
1093
- var $TypeError$3 = TypeError;
1094
-
1095
- var anInstance$1 = function (it, Prototype) {
1096
- if (isPrototypeOf$1(Prototype, it)) return it;
1097
- throw new $TypeError$3('Incorrect invocation');
1098
- };
1099
-
1100
- var fails$2 = fails$c;
1101
-
1102
- var correctPrototypeGetter = !fails$2(function () {
1103
- function F() { /* empty */ }
1104
- F.prototype.constructor = null;
1105
- // eslint-disable-next-line es/no-object-getprototypeof -- required for testing
1106
- return Object.getPrototypeOf(new F()) !== F.prototype;
1107
- });
1108
-
1109
- var hasOwn$1 = hasOwnProperty_1;
1110
- var isCallable$3 = isCallable$e;
1111
- var toObject = toObject$3;
1112
- var sharedKey$1 = sharedKey$3;
1113
- var CORRECT_PROTOTYPE_GETTER = correctPrototypeGetter;
1114
-
1115
- var IE_PROTO$1 = sharedKey$1('IE_PROTO');
1116
- var $Object$1 = Object;
1117
- var ObjectPrototype = $Object$1.prototype;
1118
-
1119
- // `Object.getPrototypeOf` method
1120
- // https://tc39.es/ecma262/#sec-object.getprototypeof
1121
- // eslint-disable-next-line es/no-object-getprototypeof -- safe
1122
- var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER ? $Object$1.getPrototypeOf : function (O) {
1123
- var object = toObject(O);
1124
- if (hasOwn$1(object, IE_PROTO$1)) return object[IE_PROTO$1];
1125
- var constructor = object.constructor;
1126
- if (isCallable$3(constructor) && object instanceof constructor) {
1127
- return constructor.prototype;
1128
- } return object instanceof $Object$1 ? ObjectPrototype : null;
1129
- };
1130
-
1131
- var makeBuiltIn = makeBuiltInExports;
1132
- var defineProperty = objectDefineProperty;
1133
-
1134
- var defineBuiltInAccessor$1 = function (target, name, descriptor) {
1135
- if (descriptor.get) makeBuiltIn(descriptor.get, name, { getter: true });
1136
- if (descriptor.set) makeBuiltIn(descriptor.set, name, { setter: true });
1137
- return defineProperty.f(target, name, descriptor);
1138
- };
1139
-
1140
- var DESCRIPTORS$2 = descriptors;
1141
- var definePropertyModule$1 = objectDefineProperty;
1142
- var createPropertyDescriptor = createPropertyDescriptor$3;
1143
-
1144
- var createProperty$1 = function (object, key, value) {
1145
- if (DESCRIPTORS$2) definePropertyModule$1.f(object, key, createPropertyDescriptor(0, value));
1146
- else object[key] = value;
1147
- };
1148
-
1149
- var objectDefineProperties = {};
1150
-
1151
- var internalObjectKeys = objectKeysInternal;
1152
- var enumBugKeys$1 = enumBugKeys$3;
1153
-
1154
- // `Object.keys` method
1155
- // https://tc39.es/ecma262/#sec-object.keys
1156
- // eslint-disable-next-line es/no-object-keys -- safe
1157
- var objectKeys$1 = Object.keys || function keys(O) {
1158
- return internalObjectKeys(O, enumBugKeys$1);
1159
- };
1160
-
1161
- var DESCRIPTORS$1 = descriptors;
1162
- var V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug;
1163
- var definePropertyModule = objectDefineProperty;
1164
- var anObject$b = anObject$e;
1165
- var toIndexedObject = toIndexedObject$4;
1166
- var objectKeys = objectKeys$1;
1167
-
1168
- // `Object.defineProperties` method
1169
- // https://tc39.es/ecma262/#sec-object.defineproperties
1170
- // eslint-disable-next-line es/no-object-defineproperties -- safe
1171
- objectDefineProperties.f = DESCRIPTORS$1 && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O, Properties) {
1172
- anObject$b(O);
1173
- var props = toIndexedObject(Properties);
1174
- var keys = objectKeys(Properties);
1175
- var length = keys.length;
1176
- var index = 0;
1177
- var key;
1178
- while (length > index) definePropertyModule.f(O, key = keys[index++], props[key]);
1179
- return O;
1180
- };
1181
-
1182
- var getBuiltIn = getBuiltIn$3;
1183
-
1184
- var html$1 = getBuiltIn('document', 'documentElement');
1185
-
1186
- /* global ActiveXObject -- old IE, WSH */
1187
- var anObject$a = anObject$e;
1188
- var definePropertiesModule = objectDefineProperties;
1189
- var enumBugKeys = enumBugKeys$3;
1190
- var hiddenKeys = hiddenKeys$4;
1191
- var html = html$1;
1192
- var documentCreateElement = documentCreateElement$1;
1193
- var sharedKey = sharedKey$3;
1194
-
1195
- var GT = '>';
1196
- var LT = '<';
1197
- var PROTOTYPE = 'prototype';
1198
- var SCRIPT = 'script';
1199
- var IE_PROTO = sharedKey('IE_PROTO');
1200
-
1201
- var EmptyConstructor = function () { /* empty */ };
1202
-
1203
- var scriptTag = function (content) {
1204
- return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
1205
- };
1206
-
1207
- // Create object with fake `null` prototype: use ActiveX Object with cleared prototype
1208
- var NullProtoObjectViaActiveX = function (activeXDocument) {
1209
- activeXDocument.write(scriptTag(''));
1210
- activeXDocument.close();
1211
- var temp = activeXDocument.parentWindow.Object;
1212
- activeXDocument = null; // avoid memory leak
1213
- return temp;
1214
- };
1215
-
1216
- // Create object with fake `null` prototype: use iframe Object with cleared prototype
1217
- var NullProtoObjectViaIFrame = function () {
1218
- // Thrash, waste and sodomy: IE GC bug
1219
- var iframe = documentCreateElement('iframe');
1220
- var JS = 'java' + SCRIPT + ':';
1221
- var iframeDocument;
1222
- iframe.style.display = 'none';
1223
- html.appendChild(iframe);
1224
- // https://github.com/zloirock/core-js/issues/475
1225
- iframe.src = String(JS);
1226
- iframeDocument = iframe.contentWindow.document;
1227
- iframeDocument.open();
1228
- iframeDocument.write(scriptTag('document.F=Object'));
1229
- iframeDocument.close();
1230
- return iframeDocument.F;
1231
- };
1232
-
1233
- // Check for document.domain and active x support
1234
- // No need to use active x approach when document.domain is not set
1235
- // see https://github.com/es-shims/es5-shim/issues/150
1236
- // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
1237
- // avoid IE GC bug
1238
- var activeXDocument;
1239
- var NullProtoObject = function () {
1240
- try {
1241
- activeXDocument = new ActiveXObject('htmlfile');
1242
- } catch (error) { /* ignore */ }
1243
- NullProtoObject = typeof document != 'undefined'
1244
- ? document.domain && activeXDocument
1245
- ? NullProtoObjectViaActiveX(activeXDocument) // old IE
1246
- : NullProtoObjectViaIFrame()
1247
- : NullProtoObjectViaActiveX(activeXDocument); // WSH
1248
- var length = enumBugKeys.length;
1249
- while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
1250
- return NullProtoObject();
1251
- };
1252
-
1253
- hiddenKeys[IE_PROTO] = true;
1254
-
1255
- // `Object.create` method
1256
- // https://tc39.es/ecma262/#sec-object.create
1257
- // eslint-disable-next-line es/no-object-create -- safe
1258
- var objectCreate = Object.create || function create(O, Properties) {
1259
- var result;
1260
- if (O !== null) {
1261
- EmptyConstructor[PROTOTYPE] = anObject$a(O);
1262
- result = new EmptyConstructor();
1263
- EmptyConstructor[PROTOTYPE] = null;
1264
- // add "__proto__" for Object.getPrototypeOf polyfill
1265
- result[IE_PROTO] = O;
1266
- } else result = NullProtoObject();
1267
- return Properties === undefined ? result : definePropertiesModule.f(result, Properties);
1268
- };
1269
-
1270
- var fails$1 = fails$c;
1271
- var isCallable$2 = isCallable$e;
1272
- var isObject = isObject$6;
1273
- var getPrototypeOf$1 = objectGetPrototypeOf;
1274
- var defineBuiltIn$1 = defineBuiltIn$3;
1275
- var wellKnownSymbol$6 = wellKnownSymbol$8;
1276
-
1277
- var ITERATOR$3 = wellKnownSymbol$6('iterator');
1278
- var BUGGY_SAFARI_ITERATORS = false;
1279
-
1280
- // `%IteratorPrototype%` object
1281
- // https://tc39.es/ecma262/#sec-%iteratorprototype%-object
1282
- var IteratorPrototype$2, PrototypeOfArrayIteratorPrototype, arrayIterator;
1283
-
1284
- /* eslint-disable es/no-array-prototype-keys -- safe */
1285
- if ([].keys) {
1286
- arrayIterator = [].keys();
1287
- // Safari 8 has buggy iterators w/o `next`
1288
- if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;
1289
- else {
1290
- PrototypeOfArrayIteratorPrototype = getPrototypeOf$1(getPrototypeOf$1(arrayIterator));
1291
- if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype$2 = PrototypeOfArrayIteratorPrototype;
1292
- }
785
+ const url = `https://recruitsandbox.zoho.com/recruit/v2/${input.module}/${input.id}/${ZOHO_RECRUIT_ATTACHMENTS_MODULE}?${makeUrlSearchParams(urlParams).toString()}`;
786
+ let response;
787
+ if (urlParams.attachment_url) {
788
+ response = context.fetch(url, {
789
+ method: 'POST'
790
+ });
791
+ } else if (formData != null) {
792
+ throw new Error('unsupported currently. Use the attachmentUrl parameter instead.');
793
+ // There is something weird going on with sending requests this way and zoho's server is rejecting it.
794
+ /*
795
+ response = context.fetch(url, {
796
+ method: 'POST',
797
+ headers: {
798
+ 'Content-Type': 'multipart/form-data',
799
+ 'content-length': '210'
800
+ },
801
+ body: formData
802
+ });
803
+ */
804
+ /*
805
+ const fullUrl = (context.config.apiUrl as string) + url;
806
+ const accessToken = await context.accessTokenStringFactory();
807
+ response = fetch(fullUrl, {
808
+ headers: {
809
+ Authorization: `Bearer ${accessToken}`
810
+ },
811
+ body: formData,
812
+ method: 'POST'
813
+ });
814
+ console.log({ response });
815
+ */
816
+ } else {
817
+ throw new Error('body or attachmentUrl must be provided.');
818
+ }
819
+ return response;
820
+ };
1293
821
  }
1294
-
1295
- var NEW_ITERATOR_PROTOTYPE = !isObject(IteratorPrototype$2) || fails$1(function () {
1296
- var test = {};
1297
- // FF44- legacy iterators case
1298
- return IteratorPrototype$2[ITERATOR$3].call(test) !== test;
1299
- });
1300
-
1301
- if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype$2 = {};
1302
-
1303
- // `%IteratorPrototype%[@@iterator]()` method
1304
- // https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator
1305
- if (!isCallable$2(IteratorPrototype$2[ITERATOR$3])) {
1306
- defineBuiltIn$1(IteratorPrototype$2, ITERATOR$3, function () {
1307
- return this;
822
+ /**
823
+ * Downloads an attachment from a record.
824
+ *
825
+ * https://www.zoho.com/recruit/developer-guide/apiv2/download-attachments.html
826
+ *
827
+ * @param context
828
+ * @returns
829
+ */
830
+ function zohoRecruitDownloadAttachmentForRecord(context) {
831
+ return input => context.fetch(`/v2/${input.module}/${input.id}/${ZOHO_RECRUIT_ATTACHMENTS_MODULE}/${input.attachment_id}`, {
832
+ method: 'GET'
833
+ }).then(parseFetchFileResponse);
834
+ }
835
+ /**
836
+ * Deletes an attachment from a record.
837
+ *
838
+ * https://www.zoho.com/recruit/developer-guide/apiv2/delete-attachments.html
839
+ *
840
+ * @param context
841
+ * @returns
842
+ */
843
+ function zohoRecruitDeleteAttachmentFromRecord(context) {
844
+ return input => context.fetch(`/v2/${input.module}/${input.id}/${ZOHO_RECRUIT_ATTACHMENTS_MODULE}/${input.attachment_id}`, {
845
+ method: 'DELETE'
1308
846
  });
1309
847
  }
1310
-
1311
- var iteratorsCore = {
1312
- IteratorPrototype: IteratorPrototype$2,
1313
- BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS
1314
- };
1315
-
1316
- var $$4 = _export;
1317
- var global$1 = global$b;
1318
- var anInstance = anInstance$1;
1319
- var anObject$9 = anObject$e;
1320
- var isCallable$1 = isCallable$e;
1321
- var getPrototypeOf = objectGetPrototypeOf;
1322
- var defineBuiltInAccessor = defineBuiltInAccessor$1;
1323
- var createProperty = createProperty$1;
1324
- var fails = fails$c;
1325
- var hasOwn = hasOwnProperty_1;
1326
- var wellKnownSymbol$5 = wellKnownSymbol$8;
1327
- var IteratorPrototype$1 = iteratorsCore.IteratorPrototype;
1328
- var DESCRIPTORS = descriptors;
1329
-
1330
- var CONSTRUCTOR = 'constructor';
1331
- var ITERATOR$2 = 'Iterator';
1332
- var TO_STRING_TAG$3 = wellKnownSymbol$5('toStringTag');
1333
-
1334
- var $TypeError$2 = TypeError;
1335
- var NativeIterator = global$1[ITERATOR$2];
1336
-
1337
- // FF56- have non-standard global helper `Iterator`
1338
- var FORCED = !isCallable$1(NativeIterator)
1339
- || NativeIterator.prototype !== IteratorPrototype$1
1340
- // FF44- non-standard `Iterator` passes previous tests
1341
- || !fails(function () { NativeIterator({}); });
1342
-
1343
- var IteratorConstructor = function Iterator() {
1344
- anInstance(this, IteratorPrototype$1);
1345
- if (getPrototypeOf(this) === IteratorPrototype$1) throw new $TypeError$2('Abstract class Iterator not directly constructable');
1346
- };
1347
-
1348
- var defineIteratorPrototypeAccessor = function (key, value) {
1349
- if (DESCRIPTORS) {
1350
- defineBuiltInAccessor(IteratorPrototype$1, key, {
1351
- configurable: true,
1352
- get: function () {
1353
- return value;
1354
- },
1355
- set: function (replacement) {
1356
- anObject$9(this);
1357
- if (this === IteratorPrototype$1) throw new $TypeError$2("You can't redefine this property");
1358
- if (hasOwn(this, key)) this[key] = replacement;
1359
- else createProperty(this, key, replacement);
848
+ class ZohoRecruitExecuteRestApiFunctionError extends BaseError {
849
+ constructor(error) {
850
+ super(`An error occured during the execution of the function. Code: ${error.code}, Message: ${error.message}`);
851
+ this.error = void 0;
852
+ this.error = error;
853
+ }
854
+ }
855
+ /**
856
+ * Creates a ZohoRecruitExecuteRestApiFunctionFunction
857
+ *
858
+ * OAuth Details:
859
+ * - https://www.zoho.com/crm/developer/docs/functions/serverless-fn-oauth.html#OAuth2
860
+ * - There is no documentation for ZohoRecruit specifically, but it seems to behave the same way
861
+ * - You will need the following scopes: ZohoRecruit.functions.execute.READ,ZohoRecruit.functions.execute.CREATE
862
+ *
863
+ * @param context
864
+ * @returns
865
+ */
866
+ function zohoRecruitExecuteRestApiFunction(context) {
867
+ return input => {
868
+ const inputSearchParams = makeUrlSearchParams(input.params);
869
+ const inputSearchParamsString = inputSearchParams.toString();
870
+ const isSpecificRequest = Boolean(input.apiKey);
871
+ const urlParams = (isSpecificRequest ? `auth_type=apikey&zapikey=${input.apiKey}` : 'auth_type=oauth') + (inputSearchParamsString ? `&${inputSearchParamsString}` : '');
872
+ const relativeUrl = `/v2/functions/${input.functionName}/actions/execute?${urlParams}`;
873
+ const baseUrl = isSpecificRequest && input.apiUrl != null ? zohoRecruitConfigApiUrl(input.apiUrl) : '';
874
+ const url = `${baseUrl}${relativeUrl}`;
875
+ return context.fetchJson(url, zohoRecruitApiFetchJsonInput('POST')).then(x => {
876
+ if (x.code === 'success') {
877
+ return x.details;
878
+ } else {
879
+ throw new ZohoRecruitExecuteRestApiFunctionError(x);
1360
880
  }
1361
881
  });
1362
- } else IteratorPrototype$1[key] = value;
1363
- };
1364
-
1365
- if (!hasOwn(IteratorPrototype$1, TO_STRING_TAG$3)) defineIteratorPrototypeAccessor(TO_STRING_TAG$3, ITERATOR$2);
1366
-
1367
- if (FORCED || !hasOwn(IteratorPrototype$1, CONSTRUCTOR) || IteratorPrototype$1[CONSTRUCTOR] === Object) {
1368
- defineIteratorPrototypeAccessor(CONSTRUCTOR, IteratorConstructor);
882
+ };
1369
883
  }
1370
-
1371
- IteratorConstructor.prototype = IteratorPrototype$1;
1372
-
1373
- // `Iterator` constructor
1374
- // https://github.com/tc39/proposal-iterator-helpers
1375
- $$4({ global: true, constructor: true, forced: FORCED }, {
1376
- Iterator: IteratorConstructor
1377
- });
1378
-
1379
- // `GetIteratorDirect(obj)` abstract operation
1380
- // https://tc39.es/proposal-iterator-helpers/#sec-getiteratordirect
1381
- var getIteratorDirect$5 = function (obj) {
1382
- return {
1383
- iterator: obj,
1384
- next: obj.next,
1385
- done: false
884
+ // MARK: Util
885
+ function zohoRecruitUrlSearchParamsMinusModule(...input) {
886
+ return makeUrlSearchParams(input, {
887
+ omitKeys: 'module'
888
+ });
889
+ }
890
+ function zohoRecruitUrlSearchParamsMinusIdAndModule(...input) {
891
+ return makeUrlSearchParams(input, {
892
+ omitKeys: ['id', 'module']
893
+ });
894
+ }
895
+ /**
896
+ * @deprecated use makeUrlSearchParams instead.
897
+ */
898
+ const zohoRecruitUrlSearchParams = makeUrlSearchParams;
899
+ function zohoRecruitApiFetchJsonInput(method, body) {
900
+ const result = {
901
+ method,
902
+ body: body ?? undefined
1386
903
  };
1387
- };
1388
-
1389
- var defineBuiltIn = defineBuiltIn$3;
1390
-
1391
- var defineBuiltIns$1 = function (target, src, options) {
1392
- for (var key in src) defineBuiltIn(target, key, src[key], options);
1393
- return target;
1394
- };
1395
-
1396
- // `CreateIterResultObject` abstract operation
1397
- // https://tc39.es/ecma262/#sec-createiterresultobject
1398
- var createIterResultObject$1 = function (value, done) {
1399
- return { value: value, done: done };
1400
- };
1401
-
1402
- var call$7 = functionCall;
1403
- var anObject$8 = anObject$e;
1404
- var getMethod$2 = getMethod$4;
1405
-
1406
- var iteratorClose$4 = function (iterator, kind, value) {
1407
- var innerResult, innerError;
1408
- anObject$8(iterator);
1409
- try {
1410
- innerResult = getMethod$2(iterator, 'return');
1411
- if (!innerResult) {
1412
- if (kind === 'throw') throw value;
1413
- return value;
904
+ return result;
905
+ }
906
+ function zohoRecruitChangeObjectLikeResponseSuccessAndErrorPairs(response) {
907
+ const {
908
+ data
909
+ } = response;
910
+ const successItems = [];
911
+ const errorItems = [];
912
+ data.forEach(x => {
913
+ if (x.status === ZOHO_SUCCESS_STATUS) {
914
+ successItems.push(x);
915
+ } else {
916
+ errorItems.push(x);
1414
917
  }
1415
- innerResult = call$7(innerResult, iterator);
1416
- } catch (error) {
1417
- innerError = true;
1418
- innerResult = error;
1419
- }
1420
- if (kind === 'throw') throw value;
1421
- if (innerError) throw innerResult;
1422
- anObject$8(innerResult);
1423
- return value;
1424
- };
1425
-
1426
- var call$6 = functionCall;
1427
- var create = objectCreate;
1428
- var createNonEnumerableProperty = createNonEnumerableProperty$3;
1429
- var defineBuiltIns = defineBuiltIns$1;
1430
- var wellKnownSymbol$4 = wellKnownSymbol$8;
1431
- var InternalStateModule = internalState;
1432
- var getMethod$1 = getMethod$4;
1433
- var IteratorPrototype = iteratorsCore.IteratorPrototype;
1434
- var createIterResultObject = createIterResultObject$1;
1435
- var iteratorClose$3 = iteratorClose$4;
1436
-
1437
- var TO_STRING_TAG$2 = wellKnownSymbol$4('toStringTag');
1438
- var ITERATOR_HELPER = 'IteratorHelper';
1439
- var WRAP_FOR_VALID_ITERATOR = 'WrapForValidIterator';
1440
- var setInternalState = InternalStateModule.set;
1441
-
1442
- var createIteratorProxyPrototype = function (IS_ITERATOR) {
1443
- var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER);
1444
-
1445
- return defineBuiltIns(create(IteratorPrototype), {
1446
- next: function next() {
1447
- var state = getInternalState(this);
1448
- // for simplification:
1449
- // for `%WrapForValidIteratorPrototype%.next` our `nextHandler` returns `IterResultObject`
1450
- // for `%IteratorHelperPrototype%.next` - just a value
1451
- if (IS_ITERATOR) return state.nextHandler();
1452
- try {
1453
- var result = state.done ? undefined : state.nextHandler();
1454
- return createIterResultObject(result, state.done);
1455
- } catch (error) {
1456
- state.done = true;
1457
- throw error;
1458
- }
1459
- },
1460
- 'return': function () {
1461
- var state = getInternalState(this);
1462
- var iterator = state.iterator;
1463
- state.done = true;
1464
- if (IS_ITERATOR) {
1465
- var returnMethod = getMethod$1(iterator, 'return');
1466
- return returnMethod ? call$6(returnMethod, iterator) : createIterResultObject(undefined, true);
1467
- }
1468
- if (state.inner) try {
1469
- iteratorClose$3(state.inner.iterator, 'normal');
1470
- } catch (error) {
1471
- return iteratorClose$3(iterator, 'throw', error);
1472
- }
1473
- iteratorClose$3(iterator, 'normal');
1474
- return createIterResultObject(undefined, true);
918
+ });
919
+ const result = {
920
+ ...response,
921
+ successItems,
922
+ errorItems
923
+ };
924
+ return result;
925
+ }
926
+ function zohoRecruitMultiRecordResult(input, results) {
927
+ const successItems = [];
928
+ const errorItems = [];
929
+ input.forEach((x, i) => {
930
+ const result = results[i];
931
+ if (result.status === ZOHO_SUCCESS_STATUS) {
932
+ successItems.push({
933
+ input: x,
934
+ result: result
935
+ });
936
+ } else {
937
+ errorItems.push({
938
+ input: x,
939
+ result: result
940
+ });
1475
941
  }
1476
942
  });
1477
- };
1478
-
1479
- var WrapForValidIteratorPrototype = createIteratorProxyPrototype(true);
1480
- var IteratorHelperPrototype = createIteratorProxyPrototype(false);
1481
-
1482
- createNonEnumerableProperty(IteratorHelperPrototype, TO_STRING_TAG$2, 'Iterator Helper');
1483
-
1484
- var iteratorCreateProxy = function (nextHandler, IS_ITERATOR) {
1485
- var IteratorProxy = function Iterator(record, state) {
1486
- if (state) {
1487
- state.iterator = record.iterator;
1488
- state.next = record.next;
1489
- } else state = record;
1490
- state.type = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER;
1491
- state.nextHandler = nextHandler;
1492
- state.counter = 0;
1493
- state.done = false;
1494
- setInternalState(this, state);
943
+ const result = {
944
+ successItems,
945
+ errorItems
1495
946
  };
947
+ return result;
948
+ }
949
+ /**
950
+ * @deprecated Use zohoRecruitInsertRecord instead.
951
+ */
952
+ const insertRecord = zohoRecruitInsertRecord;
953
+ /**
954
+ * @deprecated Use zohoRecruitUpdateRecord instead.
955
+ */
956
+ const updateRecord = zohoRecruitUpdateRecord;
957
+ /**
958
+ * @deprecated Use zohoRecruitUpsertRecord instead.
959
+ */
960
+ const upsertRecord = zohoRecruitUpsertRecord;
961
+ /**
962
+ * @deprecated Use zohoRecruitDeleteRecord instead.
963
+ */
964
+ const deleteRecord = zohoRecruitDeleteRecord;
965
+ /**
966
+ * @deprecated Use zohoRecruitGetRecordById instead.
967
+ */
968
+ const getRecordById = zohoRecruitGetRecordById;
969
+ /**
970
+ * @deprecated Use zohoRecruitGetRecords instead.
971
+ */
972
+ const getRecords = zohoRecruitGetRecords;
973
+ /**
974
+ * @deprecated Use zohoRecruitSearchRecords instead.
975
+ */
976
+ const searchRecords = zohoRecruitSearchRecords;
977
+ /**
978
+ * @deprecated Use zohoRecruitSearchRecordsPageFactory instead.
979
+ */
980
+ const searchRecordsPageFactory = zohoRecruitSearchRecordsPageFactory;
981
+ /**
982
+ * @deprecated Use zohoRecruitGetRelatedRecordsFunctionFactory instead.
983
+ */
984
+ const getRelatedRecordsFunctionFactory = zohoRecruitGetRelatedRecordsFunctionFactory;
985
+ /**
986
+ * @deprecated Use zohoRecruitGetEmailsForRecord instead.
987
+ */
988
+ const getEmailsForRecord = zohoRecruitGetEmailsForRecord;
989
+ /**
990
+ * @deprecated Use zohoRecruitGetEmailsForRecordPageFactory instead.
991
+ */
992
+ const getEmailsForRecordPageFactory = zohoRecruitGetEmailsForRecordPageFactory;
993
+ /**
994
+ * @deprecated Use zohoRecruitGetAttachmentsForRecord instead.
995
+ */
996
+ const getAttachmentsForRecord = zohoRecruitGetAttachmentsForRecord;
997
+ /**
998
+ * @deprecated Use zohoRecruitGetAttachmentsForRecordPageFactory instead.
999
+ */
1000
+ const getAttachmentsForRecordPageFactory = zohoRecruitGetAttachmentsForRecordPageFactory;
1001
+ /**
1002
+ * @deprecated Use zohoRecruitUploadAttachmentForRecord instead.
1003
+ */
1004
+ const uploadAttachmentForRecord = zohoRecruitUploadAttachmentForRecord;
1005
+ /**
1006
+ * @deprecated Use zohoRecruitDownloadAttachmentForRecord instead.
1007
+ */
1008
+ const downloadAttachmentForRecord = zohoRecruitDownloadAttachmentForRecord;
1009
+ /**
1010
+ * @deprecated Use zohoRecruitDeleteAttachmentFromRecord instead.
1011
+ */
1012
+ const deleteAttachmentFromRecord = zohoRecruitDeleteAttachmentFromRecord;
1013
+ /**
1014
+ * @deprecated Use zohoRecruitExecuteRestApiFunction instead.
1015
+ */
1016
+ const executeRestApiFunction = zohoRecruitExecuteRestApiFunction;
1496
1017
 
1497
- IteratorProxy.prototype = IS_ITERATOR ? WrapForValidIteratorPrototype : IteratorHelperPrototype;
1498
-
1499
- return IteratorProxy;
1500
- };
1501
-
1502
- var anObject$7 = anObject$e;
1503
- var iteratorClose$2 = iteratorClose$4;
1504
-
1505
- // call something on iterator step with safe closing on error
1506
- var callWithSafeIterationClosing$2 = function (iterator, fn, value, ENTRIES) {
1507
- try {
1508
- return ENTRIES ? fn(anObject$7(value)[0], value[1]) : fn(value);
1509
- } catch (error) {
1510
- iteratorClose$2(iterator, 'throw', error);
1511
- }
1512
- };
1513
-
1514
- var $$3 = _export;
1515
- var call$5 = functionCall;
1516
- var aCallable$5 = aCallable$7;
1517
- var anObject$6 = anObject$e;
1518
- var getIteratorDirect$4 = getIteratorDirect$5;
1519
- var createIteratorProxy$2 = iteratorCreateProxy;
1520
- var callWithSafeIterationClosing$1 = callWithSafeIterationClosing$2;
1521
- var IS_PURE$2 = isPure;
1522
-
1523
- var IteratorProxy$2 = createIteratorProxy$2(function () {
1524
- var iterator = this.iterator;
1525
- var predicate = this.predicate;
1526
- var next = this.next;
1527
- var result, done, value;
1528
- while (true) {
1529
- result = anObject$6(call$5(next, iterator));
1530
- done = this.done = !!result.done;
1531
- if (done) return;
1532
- value = result.value;
1533
- if (callWithSafeIterationClosing$1(iterator, predicate, [value, this.counter++], true)) return value;
1534
- }
1535
- });
1536
-
1537
- // `Iterator.prototype.filter` method
1538
- // https://github.com/tc39/proposal-iterator-helpers
1539
- $$3({ target: 'Iterator', proto: true, real: true, forced: IS_PURE$2 }, {
1540
- filter: function filter(predicate) {
1541
- anObject$6(this);
1542
- aCallable$5(predicate);
1543
- return new IteratorProxy$2(getIteratorDirect$4(this), {
1544
- predicate: predicate
1018
+ /**
1019
+ * Associates one or more candidates with one or more job openings.
1020
+ *
1021
+ * https://www.zoho.com/recruit/developer-guide/apiv2/associate-candidate.html
1022
+ *
1023
+ * @param context
1024
+ * @returns
1025
+ */
1026
+ function zohoRecruitAssociateCandidateRecordsWithJobOpenings(context) {
1027
+ return input => context.fetchJson(`/v2/${ZOHO_RECRUIT_CANDIDATES_MODULE}/actions/associate`, zohoRecruitApiFetchJsonInput('PUT', {
1028
+ data: asArray(input)
1029
+ })).then(x => {
1030
+ const resultInputMap = x.data.map(() => input); // assign "input" to each value for now
1031
+ const result = zohoRecruitMultiRecordResult(resultInputMap, x.data);
1032
+ const {
1033
+ included: alreadyAssociatedErrorItems,
1034
+ excluded: otherErrorItems
1035
+ } = separateValues(result.errorItems, x => {
1036
+ return x.result.code === ZOHO_FAILURE_ERROR_CODE && x.result.details.error[0].code === ZOHO_RECRUIT_ALREADY_ASSOCIATED_ERROR_CODE;
1037
+ });
1038
+ return {
1039
+ ...result,
1040
+ errorItems: otherErrorItems,
1041
+ alreadyAssociatedErrorItems,
1042
+ allErrorItems: result.errorItems
1043
+ };
1044
+ });
1045
+ }
1046
+ function zohoRecruitSearchAssociatedRecords(context) {
1047
+ return input => {
1048
+ return context.fetchJson(`/v2/${input.module}/${input.id}/associate?${zohoRecruitUrlSearchParamsMinusIdAndModule(input).toString()}`, zohoRecruitApiFetchJsonInput('GET')).then(x => {
1049
+ const result = x ?? emptyZohoPageResult();
1050
+ return result;
1545
1051
  });
1546
- }
1547
- });
1548
-
1549
- var classofRaw$1 = classofRaw$2;
1550
- var uncurryThis$1 = functionUncurryThis;
1551
-
1552
- var functionUncurryThisClause = function (fn) {
1553
- // Nashorn bug:
1554
- // https://github.com/zloirock/core-js/issues/1128
1555
- // https://github.com/zloirock/core-js/issues/1130
1556
- if (classofRaw$1(fn) === 'Function') return uncurryThis$1(fn);
1557
- };
1558
-
1559
- var uncurryThis = functionUncurryThisClause;
1560
- var aCallable$4 = aCallable$7;
1561
- var NATIVE_BIND = functionBindNative;
1562
-
1563
- var bind$1 = uncurryThis(uncurryThis.bind);
1564
-
1565
- // optional / simple context binding
1566
- var functionBindContext = function (fn, that) {
1567
- aCallable$4(fn);
1568
- return that === undefined ? fn : NATIVE_BIND ? bind$1(fn, that) : function (/* ...args */) {
1569
- return fn.apply(that, arguments);
1570
1052
  };
1571
- };
1572
-
1573
- var iterators = {};
1574
-
1575
- var wellKnownSymbol$3 = wellKnownSymbol$8;
1576
- var Iterators$1 = iterators;
1577
-
1578
- var ITERATOR$1 = wellKnownSymbol$3('iterator');
1579
- var ArrayPrototype = Array.prototype;
1580
-
1581
- // check on default Array iterator
1582
- var isArrayIteratorMethod$1 = function (it) {
1583
- return it !== undefined && (Iterators$1.Array === it || ArrayPrototype[ITERATOR$1] === it);
1584
- };
1585
-
1586
- var wellKnownSymbol$2 = wellKnownSymbol$8;
1587
-
1588
- var TO_STRING_TAG$1 = wellKnownSymbol$2('toStringTag');
1589
- var test = {};
1590
-
1591
- test[TO_STRING_TAG$1] = 'z';
1592
-
1593
- var toStringTagSupport = String(test) === '[object z]';
1594
-
1595
- var TO_STRING_TAG_SUPPORT = toStringTagSupport;
1596
- var isCallable = isCallable$e;
1597
- var classofRaw = classofRaw$2;
1598
- var wellKnownSymbol$1 = wellKnownSymbol$8;
1599
-
1600
- var TO_STRING_TAG = wellKnownSymbol$1('toStringTag');
1601
- var $Object = Object;
1602
-
1603
- // ES3 wrong here
1604
- var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments';
1605
-
1606
- // fallback for IE11 Script Access Denied error
1607
- var tryGet = function (it, key) {
1608
- try {
1609
- return it[key];
1610
- } catch (error) { /* empty */ }
1611
- };
1612
-
1613
- // getting tag from ES6+ `Object.prototype.toString`
1614
- var classof$1 = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {
1615
- var O, tag, result;
1616
- return it === undefined ? 'Undefined' : it === null ? 'Null'
1617
- // @@toStringTag case
1618
- : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag
1619
- // builtinTag case
1620
- : CORRECT_ARGUMENTS ? classofRaw(O)
1621
- // ES3 arguments fallback
1622
- : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result;
1623
- };
1624
-
1625
- var classof = classof$1;
1626
- var getMethod = getMethod$4;
1627
- var isNullOrUndefined = isNullOrUndefined$3;
1628
- var Iterators = iterators;
1629
- var wellKnownSymbol = wellKnownSymbol$8;
1630
-
1631
- var ITERATOR = wellKnownSymbol('iterator');
1632
-
1633
- var getIteratorMethod$3 = function (it) {
1634
- if (!isNullOrUndefined(it)) return getMethod(it, ITERATOR)
1635
- || getMethod(it, '@@iterator')
1636
- || Iterators[classof(it)];
1637
- };
1638
-
1639
- var call$4 = functionCall;
1640
- var aCallable$3 = aCallable$7;
1641
- var anObject$5 = anObject$e;
1642
- var tryToString$1 = tryToString$3;
1643
- var getIteratorMethod$2 = getIteratorMethod$3;
1644
-
1645
- var $TypeError$1 = TypeError;
1646
-
1647
- var getIterator$1 = function (argument, usingIterator) {
1648
- var iteratorMethod = arguments.length < 2 ? getIteratorMethod$2(argument) : usingIterator;
1649
- if (aCallable$3(iteratorMethod)) return anObject$5(call$4(iteratorMethod, argument));
1650
- throw new $TypeError$1(tryToString$1(argument) + ' is not iterable');
1651
- };
1652
-
1653
- var bind = functionBindContext;
1654
- var call$3 = functionCall;
1655
- var anObject$4 = anObject$e;
1656
- var tryToString = tryToString$3;
1657
- var isArrayIteratorMethod = isArrayIteratorMethod$1;
1658
- var lengthOfArrayLike = lengthOfArrayLike$3;
1659
- var isPrototypeOf = objectIsPrototypeOf;
1660
- var getIterator = getIterator$1;
1661
- var getIteratorMethod$1 = getIteratorMethod$3;
1662
- var iteratorClose$1 = iteratorClose$4;
1663
-
1664
- var $TypeError = TypeError;
1665
-
1666
- var Result = function (stopped, result) {
1667
- this.stopped = stopped;
1668
- this.result = result;
1669
- };
1670
-
1671
- var ResultPrototype = Result.prototype;
1672
-
1673
- var iterate$1 = function (iterable, unboundFunction, options) {
1674
- var that = options && options.that;
1675
- var AS_ENTRIES = !!(options && options.AS_ENTRIES);
1676
- var IS_RECORD = !!(options && options.IS_RECORD);
1677
- var IS_ITERATOR = !!(options && options.IS_ITERATOR);
1678
- var INTERRUPTED = !!(options && options.INTERRUPTED);
1679
- var fn = bind(unboundFunction, that);
1680
- var iterator, iterFn, index, length, result, next, step;
1681
-
1682
- var stop = function (condition) {
1683
- if (iterator) iteratorClose$1(iterator, 'normal', condition);
1684
- return new Result(true, condition);
1053
+ }
1054
+ function zohoRecruitSearchCandidateAssociatedJobOpeningRecords(context) {
1055
+ const searchAssociatedRecordsFactory = zohoRecruitSearchAssociatedRecords(context);
1056
+ return input => {
1057
+ return searchAssociatedRecordsFactory({
1058
+ ...input,
1059
+ module: ZOHO_RECRUIT_CANDIDATES_MODULE
1060
+ });
1685
1061
  };
1686
-
1687
- var callFn = function (value) {
1688
- if (AS_ENTRIES) {
1689
- anObject$4(value);
1690
- return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]);
1691
- } return INTERRUPTED ? fn(value, stop) : fn(value);
1062
+ }
1063
+ function zohoRecruitSearchCandidateAssociatedJobOpeningRecordsPageFactory(context) {
1064
+ return zohoFetchPageFactory(zohoRecruitSearchCandidateAssociatedJobOpeningRecords(context));
1065
+ }
1066
+ function zohoRecruitSearchJobOpeningAssociatedCandidateRecords(context, jobOpeningModuleName = ZOHO_RECRUIT_JOB_OPENINGS_MODULE) {
1067
+ const searchAssociatedRecordsFactory = zohoRecruitSearchAssociatedRecords(context);
1068
+ return input => {
1069
+ return searchAssociatedRecordsFactory({
1070
+ ...input,
1071
+ module: jobOpeningModuleName
1072
+ });
1692
1073
  };
1074
+ }
1075
+ function zohoRecruitSearchJobOpeningAssociatedCandidateRecordsPageFactory(context) {
1076
+ return zohoFetchPageFactory(zohoRecruitSearchJobOpeningAssociatedCandidateRecords(context));
1077
+ }
1693
1078
 
1694
- if (IS_RECORD) {
1695
- iterator = iterable.iterator;
1696
- } else if (IS_ITERATOR) {
1697
- iterator = iterable;
1698
- } else {
1699
- iterFn = getIteratorMethod$1(iterable);
1700
- if (!iterFn) throw new $TypeError(tryToString(iterable) + ' is not iterable');
1701
- // optimisation for array iterators
1702
- if (isArrayIteratorMethod(iterFn)) {
1703
- for (index = 0, length = lengthOfArrayLike(iterable); length > index; index++) {
1704
- result = callFn(iterable[index]);
1705
- if (result && isPrototypeOf(ResultPrototype, result)) return result;
1706
- } return new Result(false);
1707
- }
1708
- iterator = getIterator(iterable, iterFn);
1709
- }
1710
-
1711
- next = IS_RECORD ? iterable.next : iterator.next;
1712
- while (!(step = call$3(next, iterator)).done) {
1713
- try {
1714
- result = callFn(step.value);
1715
- } catch (error) {
1716
- iteratorClose$1(iterator, 'throw', error);
1717
- }
1718
- if (typeof result == 'object' && result && isPrototypeOf(ResultPrototype, result)) return result;
1719
- } return new Result(false);
1720
- };
1721
-
1722
- var $$2 = _export;
1723
- var iterate = iterate$1;
1724
- var aCallable$2 = aCallable$7;
1725
- var anObject$3 = anObject$e;
1726
- var getIteratorDirect$3 = getIteratorDirect$5;
1727
-
1728
- // `Iterator.prototype.forEach` method
1729
- // https://github.com/tc39/proposal-iterator-helpers
1730
- $$2({ target: 'Iterator', proto: true, real: true }, {
1731
- forEach: function forEach(fn) {
1732
- anObject$3(this);
1733
- aCallable$2(fn);
1734
- var record = getIteratorDirect$3(this);
1735
- var counter = 0;
1736
- iterate(record, function (value) {
1737
- fn(value, counter++);
1738
- }, { IS_RECORD: true });
1739
- }
1740
- });
1741
-
1742
- /**
1743
- * Returns an empty ZohoPageResult that is typed to R and has no more records/results.
1744
- */
1745
- function emptyZohoPageResult() {
1746
- return {
1747
- data: [],
1748
- info: {
1749
- page: 1,
1750
- per_page: 100,
1751
- // default value
1752
- count: 0,
1753
- more_records: false
1754
- }
1755
- };
1079
+ function zohoRecruitCreateNotes(context) {
1080
+ return input => context.fetchJson(`/v2/${ZOHO_RECRUIT_NOTES_MODULE}`, zohoRecruitApiFetchJsonInput('POST', {
1081
+ data: input.data
1082
+ })).then(x => {
1083
+ return zohoRecruitMultiRecordResult(asArray(input.data), x.data);
1084
+ });
1085
+ }
1086
+ function zohoRecruitDeleteNotes(context) {
1087
+ return input => context.fetchJson(`/v2/${ZOHO_RECRUIT_NOTES_MODULE}?${makeUrlSearchParams({
1088
+ ids: input.ids
1089
+ })}`, zohoRecruitApiFetchJsonInput('DELETE')).then(x => {
1090
+ return zohoRecruitMultiRecordResult(asArray(input.ids), x.data);
1091
+ });
1756
1092
  }
1757
- /**
1758
- * Creates a FetchPageFactory using the input ZohoFetchPageFetchFunction.
1759
- *
1760
- * @param fetch
1761
- * @param defaults
1762
- * @returns
1763
- */
1764
- function zohoFetchPageFactory(fetch, defaults) {
1765
- return fetchPageFactory({
1766
- ...defaults,
1767
- fetch,
1768
- readFetchPageResultInfo: function (result) {
1769
- return {
1770
- hasNext: result.info?.more_records ?? false // if no info is returned, assume something wrong and there are no more records
1771
- };
1772
- },
1773
- buildInputForNextPage: function (pageResult, input, options) {
1774
- return {
1775
- ...input,
1776
- page: getNextPageNumber(pageResult),
1777
- per_page: options.maxItemsPerPage ?? input.per_page
1778
- };
1779
- }
1093
+ function zohoRecruitGetNotesForRecord(context) {
1094
+ return zohoRecruitGetRelatedRecordsFunctionFactory(context)({
1095
+ targetModule: ZOHO_RECRUIT_NOTES_MODULE
1780
1096
  });
1781
1097
  }
1782
-
1783
- const ZOHO_RECRUIT_SERVICE_NAME = 'recruit';
1784
- function zohoRecruitConfigApiUrl(input) {
1785
- switch (input) {
1786
- case 'sandbox':
1787
- return 'https://recruitsandbox.zoho.com/recruit';
1788
- case 'production':
1789
- return 'https://recruit.zoho.com/recruit';
1790
- default:
1791
- return input;
1792
- }
1098
+ function zohoRecruitGetNotesForRecordPageFactory(context) {
1099
+ return zohoFetchPageFactory(zohoRecruitGetNotesForRecord(context));
1793
1100
  }
1794
-
1795
- /**
1796
- * Candidates module name
1797
- */
1798
- const ZOHO_RECRUIT_CANDIDATES_MODULE = 'Candidates';
1101
+ function zohoRecruitCreateNotesForRecord(context) {
1102
+ const createNotesInstance = zohoRecruitCreateNotes(context);
1103
+ return input => {
1104
+ const {
1105
+ module: se_module,
1106
+ id: Parent_Id,
1107
+ notes
1108
+ } = input;
1109
+ const createNotesRequest = {
1110
+ data: asArray(notes).map(x => ({
1111
+ ...x,
1112
+ se_module,
1113
+ Parent_Id
1114
+ }))
1115
+ };
1116
+ return createNotesInstance(createNotesRequest);
1117
+ };
1118
+ }
1119
+ // MARK: Compat
1799
1120
  /**
1800
- * Job Openings module name
1121
+ * @deprecated Use zohoRecruitCreateNotes instead.
1801
1122
  */
1802
- const ZOHO_RECRUIT_JOB_OPENINGS_MODULE = 'Job_Openings';
1123
+ const createNotes = zohoRecruitCreateNotes;
1803
1124
  /**
1804
- * Notes module name
1125
+ * @deprecated Use zohoRecruitDeleteNotes instead.
1805
1126
  */
1806
- const ZOHO_RECRUIT_NOTES_MODULE = 'Notes';
1127
+ const deleteNotes = zohoRecruitDeleteNotes;
1807
1128
  /**
1808
- * Emails module name
1129
+ * @deprecated Use zohoRecruitGetNotesForRecord instead.
1809
1130
  */
1810
- const ZOHO_RECRUIT_EMAILS_MODULE = 'Emails';
1131
+ const getNotesForRecord = zohoRecruitGetNotesForRecord;
1811
1132
  /**
1812
- * Attachments module name
1133
+ * @deprecated Use zohoRecruitGetNotesForRecordPageFactory instead.
1813
1134
  */
1814
- const ZOHO_RECRUIT_ATTACHMENTS_MODULE = 'Attachments';
1135
+ const getNotesForRecordPageFactory = zohoRecruitGetNotesForRecordPageFactory;
1815
1136
  /**
1816
- * Returns true if it is a valid ZohoRecruitValidUrl.
1137
+ * @deprecated Use zohoRecruitCreateNotesForRecord instead.
1817
1138
  */
1818
- const isZohoRecruitValidUrl = isStandardInternetAccessibleWebsiteUrl;
1819
- const ZOHO_RECRUIT_RECORD_ATTACHMENT_METADATA_ATTACH_TYPE_RESUME = 'Resume';
1820
-
1821
- var call$2 = functionCall;
1822
- var anObject$2 = anObject$e;
1823
- var getIteratorDirect$2 = getIteratorDirect$5;
1824
- var getIteratorMethod = getIteratorMethod$3;
1825
-
1826
- var getIteratorFlattenable$1 = function (obj, stringHandling) {
1827
- if (!stringHandling || typeof obj !== 'string') anObject$2(obj);
1828
- var method = getIteratorMethod(obj);
1829
- return getIteratorDirect$2(anObject$2(method !== undefined ? call$2(method, obj) : obj));
1830
- };
1831
-
1832
- var $$1 = _export;
1833
- var call$1 = functionCall;
1834
- var aCallable$1 = aCallable$7;
1835
- var anObject$1 = anObject$e;
1836
- var getIteratorDirect$1 = getIteratorDirect$5;
1837
- var getIteratorFlattenable = getIteratorFlattenable$1;
1838
- var createIteratorProxy$1 = iteratorCreateProxy;
1839
- var iteratorClose = iteratorClose$4;
1840
- var IS_PURE$1 = isPure;
1841
-
1842
- var IteratorProxy$1 = createIteratorProxy$1(function () {
1843
- var iterator = this.iterator;
1844
- var mapper = this.mapper;
1845
- var result, inner;
1139
+ const createNotesForRecord = zohoRecruitCreateNotesForRecord;
1846
1140
 
1847
- while (true) {
1848
- if (inner = this.inner) try {
1849
- result = anObject$1(call$1(inner.next, inner.iterator));
1850
- if (!result.done) return result.value;
1851
- this.inner = null;
1852
- } catch (error) { iteratorClose(iterator, 'throw', error); }
1853
-
1854
- result = anObject$1(call$1(this.next, iterator));
1855
-
1856
- if (this.done = !!result.done) return;
1857
-
1858
- try {
1859
- this.inner = getIteratorFlattenable(mapper(result.value, this.counter++), false);
1860
- } catch (error) { iteratorClose(iterator, 'throw', error); }
1861
- }
1862
- });
1863
-
1864
- // `Iterator.prototype.flatMap` method
1865
- // https://github.com/tc39/proposal-iterator-helpers
1866
- $$1({ target: 'Iterator', proto: true, real: true, forced: IS_PURE$1 }, {
1867
- flatMap: function flatMap(mapper) {
1868
- anObject$1(this);
1869
- aCallable$1(mapper);
1870
- return new IteratorProxy$1(getIteratorDirect$1(this), {
1871
- mapper: mapper,
1872
- inner: null
1141
+ function zohoRecruitCreateTagsForModule(context) {
1142
+ return input => context.fetchJson(`/v2/settings/tags?${makeUrlSearchParams({
1143
+ module: input.module
1144
+ })}`, zohoRecruitApiFetchJsonInput('POST', {
1145
+ tags: asArray(input.tags)
1146
+ })).then(x => {
1147
+ const result = zohoRecruitMultiRecordResult(asArray(input.tags), x.tags);
1148
+ const {
1149
+ included: duplicateErrorItems,
1150
+ excluded: otherErrorItems
1151
+ } = separateValues(result.errorItems, x => {
1152
+ return x.result.code === ZOHO_DUPLICATE_DATA_ERROR_CODE;
1873
1153
  });
1874
- }
1875
- });
1876
-
1877
- var call = functionCall;
1878
- var aCallable = aCallable$7;
1879
- var anObject = anObject$e;
1880
- var getIteratorDirect = getIteratorDirect$5;
1881
- var createIteratorProxy = iteratorCreateProxy;
1882
- var callWithSafeIterationClosing = callWithSafeIterationClosing$2;
1883
-
1884
- var IteratorProxy = createIteratorProxy(function () {
1885
- var iterator = this.iterator;
1886
- var result = anObject(call(this.next, iterator));
1887
- var done = this.done = !!result.done;
1888
- if (!done) return callWithSafeIterationClosing(iterator, this.mapper, [result.value, this.counter++], true);
1889
- });
1890
-
1891
- // `Iterator.prototype.map` method
1892
- // https://github.com/tc39/proposal-iterator-helpers
1893
- var iteratorMap = function map(mapper) {
1894
- anObject(this);
1895
- aCallable(mapper);
1896
- return new IteratorProxy(getIteratorDirect(this), {
1897
- mapper: mapper
1154
+ return {
1155
+ ...result,
1156
+ errorItems: otherErrorItems,
1157
+ duplicateErrorItems,
1158
+ allErrorItems: result.errorItems
1159
+ };
1898
1160
  });
1899
- };
1900
-
1901
- var $ = _export;
1902
- var map = iteratorMap;
1903
- var IS_PURE = isPure;
1904
-
1905
- // `Iterator.prototype.map` method
1906
- // https://github.com/tc39/proposal-iterator-helpers
1907
- $({ target: 'Iterator', proto: true, real: true, forced: IS_PURE }, {
1908
- map: map
1909
- });
1910
-
1911
- /**
1912
- * Can search up to 10 criteria at a time.
1913
- *
1914
- * https://www.zoho.com/recruit/developer-guide/apiv2/search-records.html
1915
- *
1916
- * "You can search for a maximum of 10 criteria (with the same or different column) with equals and starts_with conditions."
1917
- */
1918
- const MAX_ZOHO_RECRUIT_SEARCH_MODULE_RECORDS_CRITERIA = 10;
1919
- /**
1920
- * Creates a ZohoRecruitSearchRecordsCriteriaString from a ZohoRecruitSearchRecordsCriteriaTree.
1921
- *
1922
- * If the input tree is empty, returns undefined.
1923
- */
1924
- function zohoRecruitSearchRecordsCriteriaString(input) {
1925
- let result;
1926
- if (input != null) {
1927
- switch (typeof input) {
1928
- case 'string':
1929
- result = input;
1930
- break;
1931
- case 'object':
1932
- let tree;
1933
- if (Array.isArray(input)) {
1934
- tree = {
1935
- and: [input]
1936
- };
1937
- } else {
1938
- tree = input;
1939
- }
1940
- result = zohoRecruitSearchRecordsCriteriaStringForTree(tree);
1941
- break;
1942
- }
1943
- }
1944
- return result;
1945
- }
1946
- function zohoRecruitSearchRecordsCriteriaStringForTree(tree) {
1947
- function convertToString(value) {
1948
- let result;
1949
- if (typeof value === 'object') {
1950
- // array of criteria entries
1951
- if (Array.isArray(value)) {
1952
- result = value.map(zohoRecruitSearchRecordsCriteriaEntryToCriteriaString);
1953
- } else if (value) {
1954
- // criteria tree that first needs to be converted to a string
1955
- result = zohoRecruitSearchRecordsCriteriaStringForTree(value);
1956
- }
1957
- } else {
1958
- result = value;
1959
- }
1960
- return result;
1961
- }
1962
- function mergeStringValues(values, type) {
1963
- return values.length > 1 ? `(${values.join(type)})` : values[0]; // wrap in and values
1964
- }
1965
- function mergeValues(values, type) {
1966
- const allStrings = filterMaybeArrayValues(values.map(convertToString)).flatMap(asArray);
1967
- return mergeStringValues(allStrings, type);
1968
- }
1969
- const orValues = tree.or ? mergeValues(tree.or, 'or') : undefined;
1970
- let result = orValues;
1971
- if (tree.and) {
1972
- result = mergeValues([mergeValues(tree.and, 'and'), orValues], 'and');
1973
- }
1974
- return result;
1975
1161
  }
1976
1162
  /**
1977
- * Escape used for ZohoRecruitSearchRecordsCriteriaString
1978
- */
1979
- const escapeZohoFieldValueForCriteriaString = escapeStringCharactersFunction({
1980
- /**
1981
- * Parenthesis and commas must be escaped using a backslash
1982
- */
1983
- escapeTargets: ['(', ')', ','],
1984
- escapeCharacter: char => `\\${char}`
1985
- });
1986
- /**
1987
- * Converts the input entry to a ZohoRecruitSearchRecordsCriteriaString. Properly escapes any parenthesis or commas.
1163
+ * Returns the list of tags within a module.
1988
1164
  *
1989
- * @param entry
1165
+ * https://www.zoho.com/recruit/developer-guide/apiv2/get-tag-list.html
1166
+ *
1167
+ * @param context
1990
1168
  * @returns
1991
1169
  */
1992
- function zohoRecruitSearchRecordsCriteriaEntryToCriteriaString(entry) {
1993
- const escapedValue = escapeZohoFieldValueForCriteriaString(entry.value);
1994
- return `(${entry.field}:${entry.filter}:${escapedValue})`;
1995
- }
1996
-
1997
- /**
1998
- * A code used in some cases to denote success.
1999
- */
2000
- const ZOHO_SUCCESS_CODE = 'SUCCESS';
2001
- /**
2002
- * Lowercase status code
2003
- */
2004
- const ZOHO_SUCCESS_STATUS = 'success';
2005
- /**
2006
- * Set in the status field
2007
- */
2008
- const ZOHO_ERROR_STATUS = 'error';
2009
- function zohoServerErrorData(error) {
2010
- const errorType = typeof error;
2011
- let errorData;
2012
- if (errorType === 'object') {
2013
- errorData = error;
2014
- } else {
2015
- errorData = {
2016
- code: error,
2017
- message: ''
1170
+ function zohoRecruitGetTagsForModule(context) {
1171
+ return input => context.fetchJson(`/v2/settings/tags?${makeUrlSearchParams({
1172
+ module: input.module,
1173
+ my_tags: input.my_tags
1174
+ })}`, zohoRecruitApiFetchJsonInput('GET')).then(x => {
1175
+ // NOTE: This doesn't follow the api documentation, and instead is a normal page result except it has "tags" instead of "data".
1176
+ return {
1177
+ ...x,
1178
+ data: x.tags
2018
1179
  };
2019
- }
2020
- return errorData;
1180
+ });
2021
1181
  }
2022
- /**
2023
- * Zoho Server Error
2024
- */
2025
- class ZohoServerError extends BaseError {
2026
- get code() {
2027
- return this.error.code;
2028
- }
2029
- constructor(error) {
2030
- super(error.message);
2031
- this.error = void 0;
2032
- this.error = error;
2033
- }
1182
+ function zohoRecruitGetTagsForModulePageFactory(context) {
1183
+ return zohoFetchPageFactory(zohoRecruitGetTagsForModule(context));
2034
1184
  }
1185
+ // MARK: Add Tag To Record
2035
1186
  /**
2036
- * Zoho Server Error that includes the FetchResponseError
1187
+ * Limit enforced by Zoho Recruit
2037
1188
  */
2038
- class ZohoServerFetchResponseError extends ZohoServerError {
2039
- constructor(data, responseError) {
2040
- super(data);
2041
- this.data = void 0;
2042
- this.responseError = void 0;
2043
- this.data = data;
2044
- this.responseError = responseError;
2045
- }
2046
- }
1189
+ const ZOHO_RECRUIT_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED = 100;
2047
1190
  /**
2048
- * Creates a logZohoServerErrorFunction that logs the error to console.
1191
+ * Adds one or more tags to one or more records.
2049
1192
  *
2050
- * @param zohoApiNamePrefix Prefix to use when logging. I.E. ZohoRecruitError, etc.
2051
- * @returns
2052
- */
2053
- function logZohoServerErrorFunction(zohoApiNamePrefix) {
2054
- return error => {
2055
- if (error instanceof ZohoServerFetchResponseError) {
2056
- console.log(`${zohoApiNamePrefix}Error(${error.responseError.response.status}): `, {
2057
- error,
2058
- errorData: error.data
2059
- });
2060
- } else if (error instanceof ZohoServerError) {
2061
- console.log(`${zohoApiNamePrefix}Error(code:${error.code}): `, {
2062
- error
2063
- });
2064
- } else {
2065
- console.log(`${zohoApiNamePrefix}Error(name:${error.name}): `, {
2066
- error
2067
- });
1193
+ * https://www.zoho.com/recruit/developer-guide/apiv2/add-tags.html
1194
+ *
1195
+ * @param context
1196
+ * @returns
1197
+ */
1198
+ function zohoRecruitAddTagsToRecords(context) {
1199
+ return input => {
1200
+ if (Array.isArray(input.ids) && input.ids.length > ZOHO_RECRUIT_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED) {
1201
+ throw new Error(`Cannot add tags to more than ${ZOHO_RECRUIT_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED} records at once.`);
2068
1202
  }
1203
+ return context.fetchJson(`/v2/${ZOHO_RECRUIT_CANDIDATES_MODULE}/actions/add_tags?${makeUrlSearchParams({
1204
+ tag_names: input.tag_names,
1205
+ ids: input.ids
1206
+ })}`, zohoRecruitApiFetchJsonInput('POST')).then(x => {
1207
+ const resultInputMap = x.data.map(() => input); // assign "input" to each value for now
1208
+ return zohoRecruitMultiRecordResult(resultInputMap, x.data);
1209
+ });
2069
1210
  };
2070
1211
  }
1212
+ // MARK: Remove Tag From Record
2071
1213
  /**
2072
- * Wraps a ConfiguredFetch to support handling errors returned by fetch.
1214
+ * Limit enforced by Zoho Recruit
1215
+ */
1216
+ const ZOHO_RECRUIT_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED = 100;
1217
+ /**
1218
+ * Removes one or more tags from one or more records.
2073
1219
  *
2074
- * @param fetch
1220
+ * https://www.zoho.com/recruit/developer-guide/apiv2/remove-tags.html
1221
+ *
1222
+ * @param context
2075
1223
  * @returns
2076
1224
  */
2077
- function handleZohoErrorFetchFactory(parseZohoError, defaultLogError) {
2078
- return (fetch, logError = defaultLogError, onError) => {
2079
- return async (x, y) => {
2080
- try {
2081
- return await fetch(x, y); // await to catch thrown errors
2082
- } catch (e) {
2083
- if (e instanceof FetchResponseError) {
2084
- const error = await parseZohoError(e);
2085
- if (error) {
2086
- logError(error); // log before throwing.
2087
- onError?.(error); // perform a task
2088
- throw error;
2089
- }
2090
- }
2091
- throw e;
2092
- }
2093
- };
1225
+ function zohoRecruitRemoveTagsFromRecords(context) {
1226
+ return input => {
1227
+ if (Array.isArray(input.ids) && input.ids.length > ZOHO_RECRUIT_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED) {
1228
+ throw new Error(`Cannot remove tags from more than ${ZOHO_RECRUIT_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED} records at once.`);
1229
+ }
1230
+ return context.fetchJson(`/v2/${ZOHO_RECRUIT_CANDIDATES_MODULE}/actions/remove_tags?${makeUrlSearchParams({
1231
+ tag_names: input.tag_names,
1232
+ ids: input.ids
1233
+ })}`, zohoRecruitApiFetchJsonInput('POST')).then(x => {
1234
+ const resultInputMap = x.data.map(() => input); // assign "input" to each value for now
1235
+ return zohoRecruitMultiRecordResult(resultInputMap, x.data);
1236
+ });
2094
1237
  };
2095
1238
  }
1239
+ // MARK: Compat
2096
1240
  /**
2097
- * FetchJsonInterceptJsonResponseFunction that intercepts a 200 response that actually contains a ZohoServerError and throws a ZohoServerError for the error handling to catch.
1241
+ * @deprecated Use zohoRecruitCreateTagsForModule instead.
2098
1242
  */
2099
- function interceptZohoErrorResponseFactory(parseZohoServerErrorResponseData) {
2100
- return (json, response) => {
2101
- const error = json?.error;
2102
- if (error != null) {
2103
- const responseError = new FetchResponseError(response);
2104
- if (responseError) {
2105
- const parsedError = parseZohoServerErrorResponseData(json, responseError);
2106
- if (parsedError) {
2107
- throw parsedError;
2108
- }
2109
- }
2110
- }
2111
- return json;
2112
- };
2113
- }
2114
- // MARK: Parsed Errors
1243
+ const createTagsForModule = zohoRecruitCreateTagsForModule;
2115
1244
  /**
2116
- * Error in the following (but not limited to) cases:
2117
- * - An extra parameter is provided
1245
+ * @deprecated Use zohoRecruitGetTagsForModule instead.
2118
1246
  */
2119
- const ZOHO_INTERNAL_ERROR_CODE = 'INTERNAL_ERROR';
1247
+ const getTagsForModule = zohoRecruitGetTagsForModule;
2120
1248
  /**
2121
- * Error code for when an invalid oauth token is provided.
1249
+ * @deprecated Use zohoRecruitGetTagsForModulePageFactory instead.
2122
1250
  */
2123
- const ZOHO_INVALID_TOKEN_ERROR_CODE = 'INVALID_TOKEN';
2124
- class ZohoInvalidTokenError extends ZohoServerFetchResponseError {}
1251
+ const getTagsForModulePageFactory = zohoRecruitGetTagsForModulePageFactory;
2125
1252
  /**
2126
- * Error code for when a failure occured for the given action
1253
+ * @deprecated Use zohoRecruitAddTagsToRecords instead.
2127
1254
  */
2128
- const ZOHO_FAILURE_ERROR_CODE = 'FAILURE';
1255
+ const addTagsToRecords = zohoRecruitAddTagsToRecords;
2129
1256
  /**
2130
- * Error when the Zoho API returns an internal error
1257
+ * @deprecated Use zohoRecruitRemoveTagsFromRecords instead.
2131
1258
  */
2132
- class ZohoInternalError extends ZohoServerFetchResponseError {}
1259
+ const removeTagsFromRecords = zohoRecruitRemoveTagsFromRecords;
1260
+
2133
1261
  /**
2134
1262
  * Error in the following cases:
2135
- * - Authorization is not properly constructed ("Invalid Ticket Id")
2136
- * - OAuth token is expired ("Invalid OAuthtoken")
1263
+ * - the refresh token string is invalid
2137
1264
  */
2138
- const ZOHO_INVALID_AUTHORIZATION_ERROR_CODE = '4834';
1265
+ const ZOHO_ACCOUNTS_INVALID_CODE_ERROR_CODE = 'invalid_code';
1266
+ const ZOHO_ACCOUNTS_INVALID_CLIENT_ERROR_CODE = 'invalid_client';
2139
1267
  /**
2140
- * Error when the Zoho API returns an invalid authorization error code.
1268
+ * Thrown if the call to the Zoho API creating an access token using a refresh token fails.
2141
1269
  */
2142
- class ZohoInvalidAuthorizationError extends ZohoServerFetchResponseError {}
1270
+ class ZohoAccountsAccessTokenError extends FetchRequestFactoryError {
1271
+ constructor(errorCode) {
1272
+ super(`ZohoAccountsAccessTokenError: ${errorCode}`);
1273
+ this.errorCode = void 0;
1274
+ this.errorCode = errorCode;
1275
+ }
1276
+ }
1277
+ /**
1278
+ * Thrown if a valid ZohoAccessToken cannot be retrieved successfully.
1279
+ */
1280
+ class ZohoAccountsAuthFailureError extends FetchRequestFactoryError {
1281
+ constructor(reason) {
1282
+ super(`Failed to retrieve proper authentication for the API call. Reason: ${reason}`);
1283
+ this.reason = void 0;
1284
+ this.reason = reason;
1285
+ }
1286
+ }
1287
+ const logZohoAccountsErrorToConsole = logZohoServerErrorFunction('ZohoAccounts');
1288
+ async function parseZohoAccountsError(responseError) {
1289
+ const data = await responseError.response.json().catch(x => undefined);
1290
+ let result;
1291
+ if (data) {
1292
+ result = parseZohoAccountsServerErrorResponseData(data, responseError);
1293
+ }
1294
+ return result;
1295
+ }
1296
+ function parseZohoAccountsServerErrorResponseData(errorResponseData, responseError) {
1297
+ let result;
1298
+ const error = errorResponseData.error;
1299
+ if (error) {
1300
+ const errorData = zohoServerErrorData(error);
1301
+ switch (errorData.code) {
1302
+ case ZOHO_ACCOUNTS_INVALID_CODE_ERROR_CODE:
1303
+ case ZOHO_ACCOUNTS_INVALID_CLIENT_ERROR_CODE:
1304
+ result = new ZohoAccountsAccessTokenError(errorData.code);
1305
+ break;
1306
+ default:
1307
+ result = parseZohoServerErrorResponseData(errorResponseData, responseError);
1308
+ break;
1309
+ }
1310
+ }
1311
+ return result;
1312
+ }
1313
+ const interceptZohoAccounts200StatusWithErrorResponse = interceptZohoErrorResponseFactory(parseZohoAccountsServerErrorResponseData);
1314
+ const handleZohoAccountsErrorFetch = handleZohoErrorFetchFactory(parseZohoAccountsError, logZohoAccountsErrorToConsole);
1315
+
1316
+ /**
1317
+ * Generates a new ZohoAccessTokenStringFactory.
1318
+ */
1319
+ function zohoAccessTokenStringFactory(zohoAccessTokenFactory) {
1320
+ return async () => {
1321
+ const token = await zohoAccessTokenFactory();
1322
+ if (!token?.accessToken) {
1323
+ throw new ZohoAccountsAuthFailureError();
1324
+ }
1325
+ return token.accessToken;
1326
+ };
1327
+ }
1328
+
1329
+ const DEFAULT_ZOHO_RATE_LIMITED_TOO_MANY_REQUETS_LOG_FUNCTION = headers => {
1330
+ console.warn(`zohoRateLimitedFetchHandler(): Too many requests made. The limit is ${headers.limit} requests per reset period. Will be reset at ${headers.resetAt}.`);
1331
+ };
1332
+ function zohoRateLimitedFetchHandler(config) {
1333
+ const onTooManyRequests = config?.onTooManyRequests !== false ? config?.onTooManyRequests ?? DEFAULT_ZOHO_RATE_LIMITED_TOO_MANY_REQUETS_LOG_FUNCTION : undefined;
1334
+ const defaultLimit = config?.maxRateLimit ?? DEFAULT_ZOHO_API_RATE_LIMIT;
1335
+ const defaultResetPeriod = config?.resetPeriod ?? DEFAULT_ZOHO_API_RATE_LIMIT_RESET_PERIOD;
1336
+ function configForLimit(limit, resetAt) {
1337
+ return {
1338
+ limit: defaultLimit,
1339
+ startLimitAt: Math.ceil(limit / 10),
1340
+ // can do 10% of the requests of the limit before rate limiting begins
1341
+ cooldownRate: 1.2 * (limit / (defaultResetPeriod / MS_IN_SECOND)),
1342
+ exponentRate: 1.08,
1343
+ maxWaitTime: MS_IN_SECOND * 10,
1344
+ resetPeriod: defaultResetPeriod,
1345
+ resetAt
1346
+ };
1347
+ }
1348
+ const defaultConfig = configForLimit(defaultLimit);
1349
+ const rateLimiter = resetPeriodPromiseRateLimiter(defaultConfig);
1350
+ return rateLimitedFetchHandler({
1351
+ rateLimiter,
1352
+ updateWithResponse: function (response, fetchResponseError) {
1353
+ const hasLimitHeader = response.headers.has(ZOHO_RATE_LIMIT_REMAINING_HEADER);
1354
+ let shouldRetry = false;
1355
+ let enabled = false;
1356
+ if (hasLimitHeader) {
1357
+ const headerDetails = zohoRateLimitHeaderDetails(response.headers);
1358
+ if (headerDetails) {
1359
+ const {
1360
+ limit,
1361
+ resetAt,
1362
+ remaining
1363
+ } = headerDetails;
1364
+ if (limit !== defaultLimit) {
1365
+ const newConfig = configForLimit(limit, resetAt);
1366
+ rateLimiter.setConfig(newConfig, false);
1367
+ }
1368
+ rateLimiter.setRemainingLimit(remaining);
1369
+ rateLimiter.setNextResetAt(resetAt);
1370
+ enabled = true;
1371
+ // only retry if it's a TOO MANY REQUESTS error
1372
+ if (response.status === ZOHO_TOO_MANY_REQUESTS_HTTP_STATUS_CODE) {
1373
+ shouldRetry = true;
1374
+ try {
1375
+ onTooManyRequests?.(headerDetails, response, fetchResponseError);
1376
+ } catch (e) {}
1377
+ }
1378
+ }
1379
+ }
1380
+ rateLimiter.setEnabled(enabled);
1381
+ return shouldRetry;
1382
+ }
1383
+ });
1384
+ }
1385
+
1386
+ function zohoRecruitFactory(factoryConfig) {
1387
+ const {
1388
+ accountsContext
1389
+ } = factoryConfig;
1390
+ const accessTokenStringFactory = zohoAccessTokenStringFactory(accountsContext.loadAccessToken);
1391
+ const fetchHandler = zohoRateLimitedFetchHandler(factoryConfig.rateLimiterConfig);
1392
+ const {
1393
+ logZohoServerErrorFunction,
1394
+ fetchFactory = input => fetchApiFetchService.makeFetch({
1395
+ baseUrl: input.apiUrl,
1396
+ baseRequest: async () => ({
1397
+ headers: {
1398
+ 'Content-Type': 'application/json',
1399
+ Authorization: `Bearer ${await accessTokenStringFactory()}`
1400
+ }
1401
+ }),
1402
+ fetchHandler,
1403
+ timeout: 20 * 1000,
1404
+ // 20 second timeout
1405
+ requireOkResponse: true,
1406
+ // enforce ok response
1407
+ useTimeout: true // use timeout
1408
+ })
1409
+ } = factoryConfig;
1410
+ return config => {
1411
+ if (!config.apiUrl) {
1412
+ throw new Error('ZohoConfig missing api url.');
1413
+ }
1414
+ const apiUrl = zohoRecruitConfigApiUrl(config.apiUrl);
1415
+ const baseFetch = fetchFactory({
1416
+ apiUrl
1417
+ });
1418
+ const fetch = handleZohoRecruitErrorFetch(baseFetch, logZohoServerErrorFunction, x => {
1419
+ if (x instanceof ZohoInvalidTokenError) {
1420
+ accountsContext.loadAccessToken.resetAccessToken();
1421
+ }
1422
+ });
1423
+ const fetchJson = fetchJsonFunction(fetch, {
1424
+ interceptJsonResponse: interceptZohoRecruit200StatusWithErrorResponse,
1425
+ // intercept errors that return status 200
1426
+ handleFetchJsonParseErrorFunction: returnNullHandleFetchJsonParseErrorFunction
1427
+ });
1428
+ const recruitContext = {
1429
+ fetch,
1430
+ fetchJson,
1431
+ accessTokenStringFactory,
1432
+ config: {
1433
+ ...config,
1434
+ apiUrl
1435
+ },
1436
+ zohoRateLimiter: fetchHandler._rateLimiter
1437
+ };
1438
+ const zohoRecruit = {
1439
+ recruitContext
1440
+ };
1441
+ return zohoRecruit;
1442
+ };
1443
+ }
1444
+
2143
1445
  /**
2144
- * Error in the following cases:
2145
- * - Search query is invalid
1446
+ * Maximum length of ZohoRecruitTagName
2146
1447
  */
2147
- const ZOHO_INVALID_QUERY_ERROR_CODE = 'INVALID_QUERY';
2148
- class ZohoInvalidQueryError extends ZohoServerFetchResponseError {
2149
- get details() {
2150
- return this.error.details;
1448
+ const ZOHO_RECRUIT_TAG_NAME_MAX_LENGTH = 25;
1449
+
1450
+ const ZOHO_CRM_SERVICE_NAME = 'crm';
1451
+ function zohoCrmConfigApiUrl(input) {
1452
+ switch (input) {
1453
+ case 'sandbox':
1454
+ return 'https://crmsandbox.zoho.com/crm';
1455
+ case 'production':
1456
+ return 'https://www.zohoapis.com/crm';
1457
+ default:
1458
+ return input;
2151
1459
  }
2152
1460
  }
1461
+
2153
1462
  /**
2154
- * Error when a mandatory field is missing.
1463
+ * Leads module name
2155
1464
  */
2156
- const ZOHO_MANDATORY_NOT_FOUND_ERROR_CODE = 'MANDATORY_NOT_FOUND';
1465
+ const ZOHO_CRM_LEADS_MODULE = 'Leads';
2157
1466
  /**
2158
- * Error when a duplicate record is found with a matching unique field value.
1467
+ * Contacts module name
2159
1468
  */
2160
- const ZOHO_DUPLICATE_DATA_ERROR_CODE = 'DUPLICATE_DATA';
1469
+ const ZOHO_CRM_CONTACTS_MODULE = 'Contacts';
2161
1470
  /**
2162
- * Error when some passed data is invalid.
1471
+ * Tasks module name
2163
1472
  */
2164
- const ZOHO_INVALID_DATA_ERROR_CODE = 'INVALID_DATA';
1473
+ const ZOHO_CRM_TASKS_MODULE = 'Tasks';
2165
1474
  /**
2166
- * Error when too many requests are made in a short period of time.
1475
+ * Notes module name
2167
1476
  */
2168
- const ZOHO_TOO_MANY_REQUESTS_ERROR_CODE = 'TOO_MANY_REQUESTS';
1477
+ const ZOHO_CRM_NOTES_MODULE = 'Notes';
2169
1478
  /**
2170
- * The status code that Zoho uses to indicates that too many requests have been made in a short period of time.
1479
+ * Emails module name
2171
1480
  */
2172
- const ZOHO_TOO_MANY_REQUESTS_HTTP_STATUS_CODE = 429;
2173
- const ZOHO_RATE_LIMIT_LIMIT_HEADER = 'X-RATELIMIT-LIMIT';
2174
- const ZOHO_RATE_LIMIT_REMAINING_HEADER = 'X-RATELIMIT-REMAINING';
2175
- const ZOHO_RATE_LIMIT_RESET_HEADER = 'X-RATELIMIT-RESET';
2176
- const DEFAULT_ZOHO_API_RATE_LIMIT = 100;
2177
- const DEFAULT_ZOHO_API_RATE_LIMIT_RESET_PERIOD = MS_IN_MINUTE;
2178
- function zohoRateLimitHeaderDetails(headers) {
2179
- const limitHeader = headers.get(ZOHO_RATE_LIMIT_LIMIT_HEADER);
2180
- const remainingHeader = headers.get(ZOHO_RATE_LIMIT_REMAINING_HEADER);
2181
- const resetHeader = headers.get(ZOHO_RATE_LIMIT_RESET_HEADER);
2182
- let result = null;
2183
- if (limitHeader != null && remainingHeader != null && resetHeader != null) {
2184
- const limit = Number(limitHeader);
2185
- const remaining = Number(remainingHeader);
2186
- const reset = Number(resetHeader);
2187
- const resetAt = new Date(reset);
2188
- result = {
2189
- limit,
2190
- remaining,
2191
- reset,
2192
- resetAt
2193
- };
2194
- }
2195
- return result;
2196
- }
2197
- class ZohoTooManyRequestsError extends ZohoServerFetchResponseError {
2198
- get headerDetails() {
2199
- return zohoRateLimitHeaderDetails(this.responseError.response.headers);
2200
- }
2201
- }
1481
+ const ZOHO_CRM_EMAILS_MODULE = 'Emails';
2202
1482
  /**
2203
- * Function that parses/transforms a ZohoServerErrorResponseData into a general ZohoServerError or other known error type.
2204
- *
2205
- * @param errorResponseData
2206
- * @param responseError
2207
- * @returns
1483
+ * Attachments module name
2208
1484
  */
2209
- function parseZohoServerErrorResponseData(errorResponseData, responseError) {
2210
- let result;
2211
- const error = tryFindZohoServerErrorData(errorResponseData, responseError);
2212
- if (error) {
2213
- const errorData = zohoServerErrorData(error);
2214
- switch (errorData.code) {
2215
- case ZOHO_INTERNAL_ERROR_CODE:
2216
- result = new ZohoInternalError(errorData, responseError);
2217
- break;
2218
- case ZOHO_INVALID_TOKEN_ERROR_CODE:
2219
- result = new ZohoInvalidTokenError(errorData, responseError);
2220
- break;
2221
- case ZOHO_INVALID_AUTHORIZATION_ERROR_CODE:
2222
- result = new ZohoInvalidAuthorizationError(errorData, responseError);
2223
- break;
2224
- case ZOHO_INVALID_QUERY_ERROR_CODE:
2225
- result = new ZohoInvalidQueryError(errorData, responseError);
2226
- break;
2227
- case ZOHO_TOO_MANY_REQUESTS_ERROR_CODE:
2228
- result = new ZohoTooManyRequestsError(errorData, responseError);
2229
- break;
2230
- default:
2231
- result = new ZohoServerFetchResponseError(errorData, responseError);
2232
- break;
2233
- }
2234
- }
2235
- return result;
2236
- }
1485
+ const ZOHO_CRM_ATTACHMENTS_MODULE = 'Attachments';
2237
1486
  /**
2238
- * Attempts to retrieve an ZohoServerErrorResponseDataError from the input.
1487
+ * Returns true if it is a valid ZohoCrmValidUrl.
1488
+ */
1489
+ const isZohoCrmValidUrl = isStandardInternetAccessibleWebsiteUrl;
1490
+ const ZOHO_CRM_RECORD_ATTACHMENT_METADATA_ATTACH_TYPE_RESUME = 'Resume';
1491
+
1492
+ /**
1493
+ * Can search up to 10 criteria at a time.
2239
1494
  *
2240
- * Non-200 errors returned by the Zoho API are returned as the object directly instead of as an ZohoServerErrorResponseData directly.
1495
+ * https://www.zoho.com/crm/developer/docs/api/v8/search-records.html
2241
1496
  *
2242
- * @param errorResponseData
2243
- * @param responseError
2244
- * @returns
1497
+ * "You can search for a maximum of 10 criteria (with the same or different column) with equals and starts_with conditions."
2245
1498
  */
2246
- function tryFindZohoServerErrorData(errorResponseData, responseError) {
2247
- const error = errorResponseData.error ?? (!responseError.response.ok ? errorResponseData : undefined);
2248
- return error;
2249
- }
1499
+ const MAX_ZOHO_CRM_SEARCH_MODULE_RECORDS_CRITERIA = MAX_ZOHO_SEARCH_MODULE_RECORDS_CRITERIA;
1500
+ const zohoCrmSearchRecordsCriteriaString = zohoSearchRecordsCriteriaString;
1501
+ const zohoCrmSearchRecordsCriteriaStringForTree = zohoSearchRecordsCriteriaStringForTree;
1502
+ const escapeZohoCrmFieldValueForCriteriaString = escapeZohoFieldValueForCriteriaString;
1503
+ const zohoCrmSearchRecordsCriteriaEntryToCriteriaString = zohoSearchRecordsCriteriaEntryToCriteriaString;
2250
1504
 
2251
1505
  /**
2252
1506
  * Error code for when two records are already associated with each other.
2253
1507
  *
2254
1508
  * Example being a candidate and a job opening are already associated.
2255
1509
  */
2256
- const ZOHO_RECRUIT_ALREADY_ASSOCIATED_ERROR_CODE = 'ALREADY_ASSOCIATED';
1510
+ const ZOHO_CRM_ALREADY_ASSOCIATED_ERROR_CODE = 'ALREADY_ASSOCIATED';
2257
1511
  /**
2258
1512
  * Thrown when a record with the given id has no content. Typically also means it does not exist.
2259
1513
  */
2260
- class ZohoRecruitRecordNoContentError extends BaseError {
1514
+ class ZohoCrmRecordNoContentError extends BaseError {
2261
1515
  constructor(moduleName, recordId) {
2262
1516
  super(`There was no content or matching records for the content. It may not exist.`);
2263
1517
  this.moduleName = void 0;
@@ -2266,63 +1520,65 @@ class ZohoRecruitRecordNoContentError extends BaseError {
2266
1520
  this.recordId = recordId;
2267
1521
  }
2268
1522
  }
2269
- class ZohoRecruitRecordCrudError extends ZohoServerError {}
2270
- class ZohoRecruitRecordCrudMandatoryFieldNotFoundError extends ZohoRecruitRecordCrudError {}
2271
- class ZohoRecruitRecordCrudDuplicateDataError extends ZohoRecruitRecordCrudError {}
2272
- class ZohoRecruitRecordCrudInvalidDataError extends ZohoRecruitRecordCrudError {
1523
+ class ZohoCrmRecordCrudError extends ZohoServerError {}
1524
+ class ZohoCrmRecordCrudMandatoryFieldNotFoundError extends ZohoCrmRecordCrudError {}
1525
+ class ZohoCrmRecordCrudDuplicateDataError extends ZohoCrmRecordCrudError {}
1526
+ class ZohoCrmRecordCrudInvalidDataError extends ZohoCrmRecordCrudError {
2273
1527
  get invalidFieldDetails() {
2274
1528
  return this.error.details;
2275
1529
  }
2276
1530
  }
2277
- class ZohoRecruitRecordCrudNoMatchingRecordError extends ZohoRecruitRecordCrudInvalidDataError {}
2278
- function zohoRecruitRecordCrudError(error) {
1531
+ class ZohoCrmRecordCrudNoMatchingRecordError extends ZohoCrmRecordCrudInvalidDataError {}
1532
+ function zohoCrmRecordCrudError(error) {
2279
1533
  let result;
2280
1534
  switch (error.code) {
2281
1535
  case ZOHO_INVALID_DATA_ERROR_CODE:
2282
- const invalidDataError = new ZohoRecruitRecordCrudInvalidDataError(error);
2283
- if (invalidDataError.invalidFieldDetails['id']) {
2284
- result = new ZohoRecruitRecordCrudNoMatchingRecordError(error);
1536
+ const invalidDataError = new ZohoCrmRecordCrudInvalidDataError(error);
1537
+ if (invalidDataError.invalidFieldDetails.api_name === 'id') {
1538
+ result = new ZohoCrmRecordCrudNoMatchingRecordError(error);
2285
1539
  } else {
2286
1540
  result = invalidDataError;
2287
1541
  }
2288
1542
  break;
2289
1543
  case ZOHO_MANDATORY_NOT_FOUND_ERROR_CODE:
2290
- result = new ZohoRecruitRecordCrudMandatoryFieldNotFoundError(error);
1544
+ result = new ZohoCrmRecordCrudMandatoryFieldNotFoundError(error);
2291
1545
  break;
2292
1546
  case ZOHO_DUPLICATE_DATA_ERROR_CODE:
2293
- result = new ZohoRecruitRecordCrudDuplicateDataError(error);
1547
+ result = new ZohoCrmRecordCrudDuplicateDataError(error);
2294
1548
  break;
2295
1549
  default:
2296
- result = new ZohoRecruitRecordCrudError(error);
1550
+ result = new ZohoCrmRecordCrudError(error);
2297
1551
  break;
2298
1552
  }
2299
1553
  return result;
2300
1554
  }
2301
- function assertRecordDataArrayResultHasContent(moduleName, recordId) {
1555
+ function assertZohoCrmRecordDataArrayResultHasContent(moduleName, recordId) {
2302
1556
  return x => {
2303
1557
  if (x == null || !x.data?.length) {
2304
- throw new ZohoRecruitRecordNoContentError(moduleName, recordId);
1558
+ throw new ZohoCrmRecordNoContentError(moduleName, recordId);
2305
1559
  } else {
2306
1560
  return x;
2307
1561
  }
2308
1562
  };
2309
1563
  }
2310
- const logZohoRecruitErrorToConsole = logZohoServerErrorFunction('ZohoRecruit');
2311
- async function parseZohoRecruitError(responseError) {
1564
+ const logZohoCrmErrorToConsole = logZohoServerErrorFunction('ZohoCrm', {
1565
+ logDataArrayErrors: false
1566
+ });
1567
+ async function parseZohoCrmError(responseError) {
2312
1568
  const data = await responseError.response.json().catch(x => undefined);
2313
1569
  let result;
2314
1570
  if (data) {
2315
- result = parseZohoRecruitServerErrorResponseData(data, responseError);
1571
+ result = parseZohoCrmServerErrorResponseData(data, responseError);
2316
1572
  }
2317
1573
  return result;
2318
1574
  }
2319
- function parseZohoRecruitServerErrorResponseData(errorResponseData, responseError) {
1575
+ function parseZohoCrmServerErrorResponseData(errorResponseData, responseError) {
2320
1576
  let result;
2321
1577
  const error = tryFindZohoServerErrorData(errorResponseData, responseError);
2322
1578
  if (error) {
2323
1579
  const errorData = zohoServerErrorData(error);
2324
1580
  switch (errorData.code) {
2325
- // TODO: Add recruit-specific error codes here.
1581
+ // TODO: Add crm-specific error codes here.
2326
1582
  default:
2327
1583
  result = parseZohoServerErrorResponseData(errorResponseData, responseError);
2328
1584
  break;
@@ -2330,16 +1586,16 @@ function parseZohoRecruitServerErrorResponseData(errorResponseData, responseErro
2330
1586
  }
2331
1587
  return result;
2332
1588
  }
2333
- const interceptZohoRecruit200StatusWithErrorResponse = interceptZohoErrorResponseFactory(parseZohoRecruitServerErrorResponseData);
2334
- const handleZohoRecruitErrorFetch = handleZohoErrorFetchFactory(parseZohoRecruitError, logZohoRecruitErrorToConsole);
1589
+ const interceptZohoCrm200StatusWithErrorResponse = interceptZohoErrorResponseFactory(parseZohoCrmServerErrorResponseData);
1590
+ const handleZohoCrmErrorFetch = handleZohoErrorFetchFactory(parseZohoCrmError, logZohoCrmErrorToConsole);
2335
1591
 
2336
1592
  // MARK: Insert/Update/Upsert Response
2337
1593
  /**
2338
1594
  * The maximum number of records allowed for most CRUD functions.
2339
1595
  *
2340
- * This is a limit enforced by the Zoho Recruit API
1596
+ * This is a limit enforced by the Zoho Crm API
2341
1597
  */
2342
- const ZOHO_RECRUIT_CRUD_FUNCTION_MAX_RECORDS_LIMIT = 100;
1598
+ const ZOHO_CRM_CRUD_FUNCTION_MAX_RECORDS_LIMIT = 100;
2343
1599
  /**
2344
1600
  * The APIs for Insert, Upsert, and Update have the same structure.
2345
1601
  *
@@ -2349,11 +1605,11 @@ function updateRecordLikeFunction(context, fetchUrlPrefix, fetchMethod) {
2349
1605
  return ({
2350
1606
  data,
2351
1607
  module
2352
- }) => context.fetchJson(`/v2/${module}${fetchUrlPrefix}`, zohoRecruitApiFetchJsonInput(fetchMethod, {
1608
+ }) => context.fetchJson(`/v8/${module}${fetchUrlPrefix}`, zohoCrmApiFetchJsonInput(fetchMethod, {
2353
1609
  data: asArray(data)
2354
- })).then(x => {
1610
+ })).catch(zohoCrmCatchZohoCrmChangeObjectLikeResponseError).then(x => {
2355
1611
  const isInputMultipleItems = Array.isArray(data);
2356
- const result = zohoRecruitMultiRecordResult(asArray(data), x.data);
1612
+ const result = zohoCrmMultiRecordResult(asArray(data), x.data);
2357
1613
  if (isInputMultipleItems) {
2358
1614
  return result;
2359
1615
  } else {
@@ -2362,7 +1618,7 @@ function updateRecordLikeFunction(context, fetchUrlPrefix, fetchMethod) {
2362
1618
  errorItems
2363
1619
  } = result;
2364
1620
  if (errorItems[0] != null) {
2365
- throw zohoRecruitRecordCrudError(errorItems[0].result);
1621
+ throw zohoCrmRecordCrudError(errorItems[0].result);
2366
1622
  } else {
2367
1623
  return successItems[0].result.details;
2368
1624
  }
@@ -2370,162 +1626,169 @@ function updateRecordLikeFunction(context, fetchUrlPrefix, fetchMethod) {
2370
1626
  });
2371
1627
  }
2372
1628
  /**
2373
- * Inserts one or more records into Recruit.
1629
+ * Inserts one or more records into Crm.
2374
1630
  *
2375
- * https://www.zoho.com/recruit/developer-guide/apiv2/insert-records.html
1631
+ * https://www.zoho.com/crm/developer-guide/apiv2/insert-records.html
2376
1632
  *
2377
1633
  * @param context
2378
1634
  * @returns
2379
1635
  */
2380
- function insertRecord(context) {
1636
+ function zohoCrmInsertRecord(context) {
2381
1637
  return updateRecordLikeFunction(context, '', 'POST');
2382
1638
  }
2383
1639
  /**
2384
- * Updates or inserts one or more records in Recruit.
1640
+ * Updates or inserts one or more records in Crm.
2385
1641
  *
2386
- * https://www.zoho.com/recruit/developer-guide/apiv2/upsert-records.html
1642
+ * https://www.zoho.com/crm/developer-guide/apiv2/upsert-records.html
2387
1643
  *
2388
1644
  * @param context
2389
1645
  * @returns
2390
1646
  */
2391
- function upsertRecord(context) {
1647
+ function zohoCrmUpsertRecord(context) {
2392
1648
  return updateRecordLikeFunction(context, '/upsert', 'POST');
2393
1649
  }
2394
1650
  /**
2395
- * Updates one or more records in Recruit.
1651
+ * Updates one or more records in Crm.
2396
1652
  *
2397
- * https://www.zoho.com/recruit/developer-guide/apiv2/update-records.html
1653
+ * https://www.zoho.com/crm/developer-guide/apiv2/update-records.html
2398
1654
  *
2399
1655
  * @param context
2400
1656
  * @returns
2401
1657
  */
2402
- function updateRecord(context) {
1658
+ function zohoCrmUpdateRecord(context) {
2403
1659
  return updateRecordLikeFunction(context, '', 'PUT');
2404
1660
  }
2405
1661
  /**
2406
1662
  * Deletes one or more records from the given module.
2407
1663
  *
2408
- * https://www.zoho.com/recruit/developer-guide/apiv2/delete-records.html
1664
+ * https://www.zoho.com/crm/developer-guide/apiv2/delete-records.html
2409
1665
  *
2410
1666
  * @param context
2411
- * @returns ZohoRecruitDeleteRecordFunction
1667
+ * @returns ZohoCrmDeleteRecordFunction
2412
1668
  */
2413
- function deleteRecord(context) {
1669
+ function zohoCrmDeleteRecord(context) {
2414
1670
  return ({
2415
1671
  ids,
2416
1672
  module,
2417
1673
  wf_trigger
2418
1674
  }) => {
2419
- return context.fetchJson(`/v2/${module}?${makeUrlSearchParams({
1675
+ return context.fetchJson(`/v8/${module}?${makeUrlSearchParams({
2420
1676
  ids,
2421
1677
  wf_trigger
2422
- })}`, zohoRecruitApiFetchJsonInput('DELETE')).then(zohoRecruitChangeObjectLikeResponseSuccessAndErrorPairs);
1678
+ })}`, zohoCrmApiFetchJsonInput('DELETE')).catch(zohoCrmCatchZohoCrmChangeObjectLikeResponseError).then(zohoCrmChangeObjectLikeResponseSuccessAndErrorPairs);
2423
1679
  };
2424
1680
  }
2425
1681
  /**
2426
1682
  * Retrieves a specific record from the given module.
2427
1683
  *
2428
- * https://www.zoho.com/recruit/developer-guide/apiv2/get-records.html
1684
+ * https://www.zoho.com/crm/developer-guide/apiv2/get-records.html
2429
1685
  *
2430
1686
  * @param context
2431
1687
  * @returns
2432
1688
  */
2433
- function getRecordById(context) {
2434
- return input => context.fetchJson(`/v2/${input.module}/${input.id}`, zohoRecruitApiFetchJsonInput('GET')).then(assertRecordDataArrayResultHasContent(input.module)).then(x => x.data[0]);
1689
+ function zohoCrmGetRecordById(context) {
1690
+ return input => context.fetchJson(`/v8/${input.module}/${input.id}`, zohoCrmApiFetchJsonInput('GET')).then(assertZohoCrmRecordDataArrayResultHasContent(input.module)).then(x => x.data[0]);
2435
1691
  }
2436
1692
  /**
2437
1693
  * Retrieves records from the given module. Used for paginating across all records.
2438
1694
  *
2439
- * https://www.zoho.com/recruit/developer-guide/apiv2/get-records.html
1695
+ * https://www.zoho.com/crm/developer-guide/apiv2/get-records.html
2440
1696
  *
2441
1697
  * @param context
2442
1698
  * @returns
2443
1699
  */
2444
- function getRecords(context) {
2445
- return input => context.fetchJson(`/v2/${input.module}?${zohoRecruitUrlSearchParamsMinusModule(input).toString()}`, zohoRecruitApiFetchJsonInput('GET'));
1700
+ function zohoCrmGetRecords(context) {
1701
+ return input => context.fetchJson(`/v8/${input.module}?${zohoCrmUrlSearchParamsMinusModule(input).toString()}`, zohoCrmApiFetchJsonInput('GET'));
2446
1702
  }
2447
1703
  /**
2448
1704
  * Searches records from the given module.
2449
1705
  *
2450
- * https://www.zoho.com/recruit/developer-guide/apiv2/search-records.html
1706
+ * https://www.zoho.com/crm/developer-guide/apiv2/search-records.html
2451
1707
  *
2452
1708
  * @param context
2453
1709
  * @returns
2454
1710
  */
2455
- function searchRecords(context) {
1711
+ function zohoCrmSearchRecords(context) {
2456
1712
  function searchRecordsUrlSearchParams(input) {
2457
1713
  const baseInput = {
2458
1714
  ...input
2459
1715
  };
2460
1716
  delete baseInput.criteria;
2461
1717
  if (input.criteria != null) {
2462
- const criteriaString = zohoRecruitSearchRecordsCriteriaString(input.criteria);
1718
+ const criteriaString = zohoCrmSearchRecordsCriteriaString(input.criteria);
2463
1719
  baseInput.criteria = criteriaString;
2464
1720
  }
2465
- if (!baseInput.word && !input.criteria && !input.email && !input.phone) {
2466
- throw new Error('At least one of word, criteria, email, or phone must be provided');
1721
+ if (!baseInput.word && !input.cvid && !input.criteria && !input.email && !input.phone) {
1722
+ throw new Error('At least one of word, cvid, criteria, email, or phone must be provided');
2467
1723
  }
2468
- const urlParams = zohoRecruitUrlSearchParamsMinusModule(baseInput);
1724
+ const urlParams = zohoCrmUrlSearchParamsMinusModule(baseInput);
2469
1725
  return urlParams;
2470
1726
  }
2471
- return input => context.fetchJson(`/v2/${input.module}/search?${searchRecordsUrlSearchParams(input).toString()}`, zohoRecruitApiFetchJsonInput('GET')).then(x => x ?? {
1727
+ return input => context.fetchJson(`/v8/${input.module}/search?${searchRecordsUrlSearchParams(input).toString()}`, zohoCrmApiFetchJsonInput('GET')).then(x => x ?? {
2472
1728
  data: [],
2473
1729
  info: {
2474
1730
  more_records: false
2475
1731
  }
2476
1732
  });
2477
1733
  }
2478
- function searchRecordsPageFactory(context) {
2479
- return zohoFetchPageFactory(searchRecords(context));
1734
+ function zohoCrmSearchRecordsPageFactory(context) {
1735
+ return zohoFetchPageFactory(zohoCrmSearchRecords(context));
2480
1736
  }
2481
1737
  /**
2482
- * Creates a ZohoRecruitGetRelatedRecordsFunctionFactory, which can be used to create ZohoRecruitGetRelatedRecordsFunction<T> that targets retrieving related records of a given type.
1738
+ * Creates a ZohoCrmGetRelatedRecordsFunctionFactory, which can be used to create ZohoCrmGetRelatedRecordsFunction<T> that targets retrieving related records of a given type.
2483
1739
  *
2484
- * https://www.zoho.com/recruit/developer-guide/apiv2/get-related-records.html
1740
+ * https://www.zoho.com/crm/developer-guide/apiv2/get-related-records.html
2485
1741
  *
2486
- * @param context the ZohoRecruitContext to use
2487
- * @returns a ZohoRecruitGetRelatedRecordsFunctionFactory
1742
+ * @param context the ZohoCrmContext to use
1743
+ * @returns a ZohoCrmGetRelatedRecordsFunctionFactory
2488
1744
  */
2489
- function getRelatedRecordsFunctionFactory(context) {
1745
+ function zohoCrmGetRelatedRecordsFunctionFactory(context) {
2490
1746
  return config => {
2491
1747
  const {
2492
1748
  targetModule,
2493
1749
  returnEmptyRecordsInsteadOfNull = true
2494
1750
  } = config;
2495
- return input => context.fetchJson(`/v2/${input.module}/${input.id}/${targetModule}?${zohoRecruitUrlSearchParamsMinusIdAndModule(input, input.filter).toString()}`, zohoRecruitApiFetchJsonInput('GET')).then(x => x ?? (returnEmptyRecordsInsteadOfNull !== false ? emptyZohoPageResult() : x));
1751
+ return input => context.fetchJson(`/v8/${input.module}/${input.id}/${targetModule}?${zohoCrmUrlSearchParamsMinusIdAndModule(input, input.filter).toString()}`, zohoCrmApiFetchJsonInput('GET')).then(x => x ?? (returnEmptyRecordsInsteadOfNull !== false ? emptyZohoPageResult() : x));
2496
1752
  };
2497
1753
  }
2498
- function getEmailsForRecord(context) {
2499
- return getRelatedRecordsFunctionFactory(context)({
2500
- targetModule: ZOHO_RECRUIT_EMAILS_MODULE
1754
+ function zohoCrmGetEmailsForRecord(context) {
1755
+ const getEmailsFactory = zohoCrmGetRelatedRecordsFunctionFactory(context)({
1756
+ targetModule: ZOHO_CRM_EMAILS_MODULE
1757
+ });
1758
+ return input => getEmailsFactory(input).then(x => {
1759
+ const data = x.data ?? x.Emails;
1760
+ return {
1761
+ ...x,
1762
+ data
1763
+ };
2501
1764
  });
2502
1765
  }
2503
- function getEmailsForRecordPageFactory(context) {
2504
- return zohoFetchPageFactory(getEmailsForRecord(context));
1766
+ function zohoCrmGetEmailsForRecordPageFactory(context) {
1767
+ return zohoFetchPageFactory(zohoCrmGetEmailsForRecord(context));
2505
1768
  }
2506
- function getAttachmentsForRecord(context) {
2507
- return getRelatedRecordsFunctionFactory(context)({
2508
- targetModule: ZOHO_RECRUIT_ATTACHMENTS_MODULE
1769
+ function zohoCrmGetAttachmentsForRecord(context) {
1770
+ return zohoCrmGetRelatedRecordsFunctionFactory(context)({
1771
+ targetModule: ZOHO_CRM_ATTACHMENTS_MODULE
2509
1772
  });
2510
1773
  }
2511
- function getAttachmentsForRecordPageFactory(context) {
2512
- return zohoFetchPageFactory(getAttachmentsForRecord(context));
1774
+ function zohoCrmGetAttachmentsForRecordPageFactory(context) {
1775
+ return zohoFetchPageFactory(zohoCrmGetAttachmentsForRecord(context));
2513
1776
  }
2514
1777
  /**
2515
- * Maximum attachment size allowed by Zoho Recruit.
1778
+ * Maximum attachment size allowed by Zoho Crm.
2516
1779
  *
2517
1780
  * 20MB
2518
1781
  */
2519
- const ZOHO_RECRUIT_ATTACHMENT_MAX_SIZE = 20 * 1024 * 1024;
1782
+ const ZOHO_CRM_ATTACHMENT_MAX_SIZE = 20 * 1024 * 1024;
2520
1783
  /**
2521
1784
  * Uploads an attachment to a record.
2522
1785
  *
2523
- * https://www.zoho.com/recruit/developer-guide/apiv2/upload-attachment.html
1786
+ * https://www.zoho.com/crm/developer-guide/apiv2/upload-attachment.html
2524
1787
  *
2525
1788
  * @param context
2526
1789
  * @returns
2527
1790
  */
2528
- function uploadAttachmentForRecord(context) {
1791
+ function zohoCrmUploadAttachmentForRecord(context) {
2529
1792
  return input => {
2530
1793
  const {
2531
1794
  attachmentCategoryId,
@@ -2543,7 +1806,7 @@ function uploadAttachmentForRecord(context) {
2543
1806
  if (formData != null) {
2544
1807
  delete urlParams.attachment_url;
2545
1808
  }
2546
- const url = `https://recruitsandbox.zoho.com/recruit/v2/${input.module}/${input.id}/${ZOHO_RECRUIT_ATTACHMENTS_MODULE}?${makeUrlSearchParams(urlParams).toString()}`;
1809
+ const url = `https://crmsandbox.zoho.com/crm/v8/${input.module}/${input.id}/${ZOHO_CRM_ATTACHMENTS_MODULE}?${makeUrlSearchParams(urlParams).toString()}`;
2547
1810
  let response;
2548
1811
  if (urlParams.attachment_url) {
2549
1812
  response = context.fetch(url, {
@@ -2583,30 +1846,30 @@ function uploadAttachmentForRecord(context) {
2583
1846
  /**
2584
1847
  * Downloads an attachment from a record.
2585
1848
  *
2586
- * https://www.zoho.com/recruit/developer-guide/apiv2/download-attachments.html
1849
+ * https://www.zoho.com/crm/developer-guide/apiv2/download-attachments.html
2587
1850
  *
2588
1851
  * @param context
2589
1852
  * @returns
2590
1853
  */
2591
- function downloadAttachmentForRecord(context) {
2592
- return input => context.fetch(`/v2/${input.module}/${input.id}/${ZOHO_RECRUIT_ATTACHMENTS_MODULE}/${input.attachment_id}`, {
1854
+ function zohoCrmDownloadAttachmentForRecord(context) {
1855
+ return input => context.fetch(`/v8/${input.module}/${input.id}/${ZOHO_CRM_ATTACHMENTS_MODULE}/${input.attachment_id}`, {
2593
1856
  method: 'GET'
2594
1857
  }).then(parseFetchFileResponse);
2595
1858
  }
2596
1859
  /**
2597
1860
  * Deletes an attachment from a record.
2598
1861
  *
2599
- * https://www.zoho.com/recruit/developer-guide/apiv2/delete-attachments.html
1862
+ * https://www.zoho.com/crm/developer-guide/apiv2/delete-attachments.html
2600
1863
  *
2601
1864
  * @param context
2602
1865
  * @returns
2603
1866
  */
2604
- function deleteAttachmentFromRecord(context) {
2605
- return input => context.fetch(`/v2/${input.module}/${input.id}/${ZOHO_RECRUIT_ATTACHMENTS_MODULE}/${input.attachment_id}`, {
1867
+ function zohoCrmDeleteAttachmentFromRecord(context) {
1868
+ return input => context.fetch(`/v8/${input.module}/${input.id}/${ZOHO_CRM_ATTACHMENTS_MODULE}/${input.attachment_id}`, {
2606
1869
  method: 'DELETE'
2607
1870
  });
2608
1871
  }
2609
- class ZohoRecruitExecuteRestApiFunctionError extends BaseError {
1872
+ class ZohoCrmExecuteRestApiFunctionError extends BaseError {
2610
1873
  constructor(error) {
2611
1874
  super(`An error occured during the execution of the function. Code: ${error.code}, Message: ${error.message}`);
2612
1875
  this.error = void 0;
@@ -2614,41 +1877,41 @@ class ZohoRecruitExecuteRestApiFunctionError extends BaseError {
2614
1877
  }
2615
1878
  }
2616
1879
  /**
2617
- * Creates a ZohoRecruitExecuteRestApiFunctionFunction
1880
+ * Creates a ZohoCrmExecuteRestApiFunctionFunction
2618
1881
  *
2619
1882
  * OAuth Details:
2620
1883
  * - https://www.zoho.com/crm/developer/docs/functions/serverless-fn-oauth.html#OAuth2
2621
- * - There is no documentation for ZohoRecruit specifically, but it seems to behave the same way
2622
- * - You will need the following scopes: ZohoRecruit.functions.execute.READ,ZohoRecruit.functions.execute.CREATE
1884
+ * - There is no documentation for ZohoCrm specifically, but it seems to behave the same way
1885
+ * - You will need the following scopes: ZohoCrm.functions.execute.READ,ZohoCrm.functions.execute.CREATE
2623
1886
  *
2624
1887
  * @param context
2625
1888
  * @returns
2626
1889
  */
2627
- function executeRestApiFunction(context) {
1890
+ function zohoCrmExecuteRestApiFunction(context) {
2628
1891
  return input => {
2629
1892
  const inputSearchParams = makeUrlSearchParams(input.params);
2630
1893
  const inputSearchParamsString = inputSearchParams.toString();
2631
1894
  const isSpecificRequest = Boolean(input.apiKey);
2632
1895
  const urlParams = (isSpecificRequest ? `auth_type=apikey&zapikey=${input.apiKey}` : 'auth_type=oauth') + (inputSearchParamsString ? `&${inputSearchParamsString}` : '');
2633
- const relativeUrl = `/v2/functions/${input.functionName}/actions/execute?${urlParams}`;
2634
- const baseUrl = isSpecificRequest && input.apiUrl != null ? zohoRecruitConfigApiUrl(input.apiUrl) : '';
1896
+ const relativeUrl = `/v8/functions/${input.functionName}/actions/execute?${urlParams}`;
1897
+ const baseUrl = isSpecificRequest && input.apiUrl != null ? zohoCrmConfigApiUrl(input.apiUrl) : '';
2635
1898
  const url = `${baseUrl}${relativeUrl}`;
2636
- return context.fetchJson(url, zohoRecruitApiFetchJsonInput('POST')).then(x => {
1899
+ return context.fetchJson(url, zohoCrmApiFetchJsonInput('POST')).then(x => {
2637
1900
  if (x.code === 'success') {
2638
1901
  return x.details;
2639
1902
  } else {
2640
- throw new ZohoRecruitExecuteRestApiFunctionError(x);
1903
+ throw new ZohoCrmExecuteRestApiFunctionError(x);
2641
1904
  }
2642
1905
  });
2643
1906
  };
2644
1907
  }
2645
1908
  // MARK: Util
2646
- function zohoRecruitUrlSearchParamsMinusModule(...input) {
1909
+ function zohoCrmUrlSearchParamsMinusModule(...input) {
2647
1910
  return makeUrlSearchParams(input, {
2648
1911
  omitKeys: 'module'
2649
1912
  });
2650
1913
  }
2651
- function zohoRecruitUrlSearchParamsMinusIdAndModule(...input) {
1914
+ function zohoCrmUrlSearchParamsMinusIdAndModule(...input) {
2652
1915
  return makeUrlSearchParams(input, {
2653
1916
  omitKeys: ['id', 'module']
2654
1917
  });
@@ -2656,143 +1919,105 @@ function zohoRecruitUrlSearchParamsMinusIdAndModule(...input) {
2656
1919
  /**
2657
1920
  * @deprecated use makeUrlSearchParams instead.
2658
1921
  */
2659
- const zohoRecruitUrlSearchParams = makeUrlSearchParams;
2660
- function zohoRecruitApiFetchJsonInput(method, body) {
1922
+ const zohoCrmUrlSearchParams = makeUrlSearchParams;
1923
+ function zohoCrmApiFetchJsonInput(method, body) {
2661
1924
  const result = {
2662
1925
  method,
2663
1926
  body: body ?? undefined
2664
1927
  };
2665
1928
  return result;
2666
1929
  }
2667
- function zohoRecruitChangeObjectLikeResponseSuccessAndErrorPairs(response) {
2668
- const {
2669
- data
2670
- } = response;
2671
- const successItems = [];
2672
- const errorItems = [];
2673
- data.forEach(x => {
2674
- if (x.status === ZOHO_SUCCESS_STATUS) {
2675
- successItems.push(x);
2676
- } else {
2677
- errorItems.push(x);
2678
- }
2679
- });
2680
- const result = {
2681
- ...response,
2682
- successItems,
2683
- errorItems
2684
- };
2685
- return result;
2686
- }
2687
- function zohoRecruitMultiRecordResult(input, results) {
2688
- const successItems = [];
2689
- const errorItems = [];
2690
- input.forEach((x, i) => {
2691
- const result = results[i];
2692
- if (result.status === ZOHO_SUCCESS_STATUS) {
2693
- successItems.push({
2694
- input: x,
2695
- result: result
2696
- });
2697
- } else {
2698
- errorItems.push({
2699
- input: x,
2700
- result: result
2701
- });
2702
- }
2703
- });
2704
- const result = {
2705
- successItems,
2706
- errorItems
2707
- };
2708
- return result;
2709
- }
2710
-
1930
+ // MARK: Results
2711
1931
  /**
2712
- * Associates one or more candidates with one or more job openings.
1932
+ * Catches ZohoServerFetchResponseDataArrayError and returns the error data array as the response data, as each data element will have the error details.
2713
1933
  *
2714
- * https://www.zoho.com/recruit/developer-guide/apiv2/associate-candidate.html
2715
- *
2716
- * @param context
2717
- * @returns
1934
+ * Use to catch errors from functions that return ZohoCrmChangeObjectLikeResponse and pass the result to zohoCrmChangeObjectLikeResponseSuccessAndErrorPairs.
2718
1935
  */
2719
- function associateCandidateRecordsWithJobOpenings(context) {
2720
- return input => context.fetchJson(`/v2/${ZOHO_RECRUIT_CANDIDATES_MODULE}/actions/associate`, zohoRecruitApiFetchJsonInput('PUT', {
2721
- data: asArray(input)
2722
- })).then(x => {
2723
- const resultInputMap = x.data.map(() => input); // assign "input" to each value for now
2724
- const result = zohoRecruitMultiRecordResult(resultInputMap, x.data);
2725
- const {
2726
- included: alreadyAssociatedErrorItems,
2727
- excluded: otherErrorItems
2728
- } = separateValues(result.errorItems, x => {
2729
- return x.result.code === ZOHO_FAILURE_ERROR_CODE && x.result.details.error[0].code === ZOHO_RECRUIT_ALREADY_ASSOCIATED_ERROR_CODE;
2730
- });
2731
- return {
2732
- ...result,
2733
- errorItems: otherErrorItems,
2734
- alreadyAssociatedErrorItems,
2735
- allErrorItems: result.errorItems
1936
+ function zohoCrmCatchZohoCrmChangeObjectLikeResponseError(e) {
1937
+ let result;
1938
+ if (e instanceof ZohoServerFetchResponseDataArrayError) {
1939
+ result = {
1940
+ data: e.errorDataArray
2736
1941
  };
2737
- });
2738
- }
2739
- function searchAssociatedRecords(context) {
2740
- return input => {
2741
- return context.fetchJson(`/v2/${input.module}/${input.id}/associate?${zohoRecruitUrlSearchParamsMinusIdAndModule(input).toString()}`, zohoRecruitApiFetchJsonInput('GET')).then(x => {
2742
- const result = x ?? emptyZohoPageResult();
2743
- return result;
2744
- });
2745
- };
1942
+ } else {
1943
+ throw e;
1944
+ }
1945
+ return result;
2746
1946
  }
2747
- function searchCandidateAssociatedJobOpeningRecords(context) {
2748
- const searchAssociatedRecordsFactory = searchAssociatedRecords(context);
2749
- return input => {
2750
- return searchAssociatedRecordsFactory({
2751
- ...input,
2752
- module: ZOHO_RECRUIT_CANDIDATES_MODULE
2753
- });
1947
+ function zohoCrmChangeObjectLikeResponseSuccessAndErrorPairs(response) {
1948
+ const {
1949
+ data
1950
+ } = response;
1951
+ const successItems = [];
1952
+ const errorItems = [];
1953
+ data.forEach(x => {
1954
+ if (x.status === ZOHO_SUCCESS_STATUS) {
1955
+ successItems.push(x);
1956
+ } else {
1957
+ errorItems.push(x);
1958
+ }
1959
+ });
1960
+ const result = {
1961
+ ...response,
1962
+ successItems,
1963
+ errorItems
2754
1964
  };
1965
+ return result;
2755
1966
  }
2756
- function searchCandidateAssociatedJobOpeningRecordsPageFactory(context) {
2757
- return zohoFetchPageFactory(searchCandidateAssociatedJobOpeningRecords(context));
2758
- }
2759
- function searchJobOpeningAssociatedCandidateRecords(context, jobOpeningModuleName = ZOHO_RECRUIT_JOB_OPENINGS_MODULE) {
2760
- const searchAssociatedRecordsFactory = searchAssociatedRecords(context);
2761
- return input => {
2762
- return searchAssociatedRecordsFactory({
2763
- ...input,
2764
- module: jobOpeningModuleName
2765
- });
1967
+ function zohoCrmMultiRecordResult(input, results) {
1968
+ const successItems = [];
1969
+ const errorItems = [];
1970
+ input.forEach((x, i) => {
1971
+ const result = results[i];
1972
+ if (result.status === ZOHO_SUCCESS_STATUS) {
1973
+ successItems.push({
1974
+ input: x,
1975
+ result: result
1976
+ });
1977
+ } else {
1978
+ errorItems.push({
1979
+ input: x,
1980
+ result: result
1981
+ });
1982
+ }
1983
+ });
1984
+ const result = {
1985
+ successItems,
1986
+ errorItems
2766
1987
  };
2767
- }
2768
- function searchJobOpeningAssociatedCandidateRecordsPageFactory(context) {
2769
- return zohoFetchPageFactory(searchJobOpeningAssociatedCandidateRecords(context));
1988
+ return result;
2770
1989
  }
2771
1990
 
2772
- function createNotes(context) {
2773
- return input => context.fetchJson(`/v2/${ZOHO_RECRUIT_NOTES_MODULE}`, zohoRecruitApiFetchJsonInput('POST', {
1991
+ function zohoCrmCreateNotes(context) {
1992
+ return input => context.fetchJson(`/v2/${ZOHO_CRM_NOTES_MODULE}`, zohoCrmApiFetchJsonInput('POST', {
2774
1993
  data: input.data
2775
1994
  })).then(x => {
2776
- return zohoRecruitMultiRecordResult(asArray(input.data), x.data);
1995
+ return zohoCrmMultiRecordResult(asArray(input.data), x.data);
2777
1996
  });
2778
1997
  }
2779
- function deleteNotes(context) {
2780
- return input => context.fetchJson(`/v2/${ZOHO_RECRUIT_NOTES_MODULE}?${makeUrlSearchParams({
1998
+ function zohoCrmDeleteNotes(context) {
1999
+ return input => context.fetchJson(`/v2/${ZOHO_CRM_NOTES_MODULE}?${makeUrlSearchParams({
2781
2000
  ids: input.ids
2782
- })}`, zohoRecruitApiFetchJsonInput('DELETE')).then(x => {
2783
- return zohoRecruitMultiRecordResult(asArray(input.ids), x.data);
2001
+ })}`, zohoCrmApiFetchJsonInput('DELETE')).then(x => {
2002
+ return zohoCrmMultiRecordResult(asArray(input.ids), x.data);
2784
2003
  });
2785
2004
  }
2786
- function getNotesForRecord(context) {
2787
- return getRelatedRecordsFunctionFactory(context)({
2788
- targetModule: ZOHO_RECRUIT_NOTES_MODULE
2005
+ function zohoCrmGetNotesForRecord(context) {
2006
+ return zohoCrmGetRelatedRecordsFunctionFactory(context)({
2007
+ targetModule: ZOHO_CRM_NOTES_MODULE
2789
2008
  });
2790
2009
  }
2791
- function getNotesForRecordPageFactory(context) {
2792
- return zohoFetchPageFactory(getNotesForRecord(context));
2010
+ function zohoCrmGetNotesForRecordPageFactory(context) {
2011
+ return zohoFetchPageFactory(zohoCrmGetNotesForRecord(context));
2793
2012
  }
2794
- function createNotesForRecord(context) {
2795
- const createNotesInstance = createNotes(context);
2013
+ /**
2014
+ * https://www.zoho.com/crm/developer/docs/api/v8/create-notes.html
2015
+ *
2016
+ * @param context
2017
+ * @returns
2018
+ */
2019
+ function zohoCrmCreateNotesForRecord(context) {
2020
+ const createNotesInstance = zohoCrmCreateNotes(context);
2796
2021
  return input => {
2797
2022
  const {
2798
2023
  module: se_module,
@@ -2810,13 +2035,27 @@ function createNotesForRecord(context) {
2810
2035
  };
2811
2036
  }
2812
2037
 
2813
- function createTagsForModule(context) {
2814
- return input => context.fetchJson(`/v2/settings/tags?${makeUrlSearchParams({
2038
+ function zohoCrmCreateTagsForModule(context) {
2039
+ return input => context.fetchJson(`/v8/settings/tags?${makeUrlSearchParams({
2815
2040
  module: input.module
2816
- })}`, zohoRecruitApiFetchJsonInput('POST', {
2041
+ })}`, zohoCrmApiFetchJsonInput('POST', {
2817
2042
  tags: asArray(input.tags)
2818
- })).then(x => {
2819
- const result = zohoRecruitMultiRecordResult(asArray(input.tags), x.tags);
2043
+ })).catch(e => {
2044
+ let result;
2045
+ if (e instanceof ZohoServerFetchResponseError) {
2046
+ const tags = e.data?.tags;
2047
+ if (Array.isArray(tags)) {
2048
+ result = {
2049
+ tags
2050
+ };
2051
+ }
2052
+ }
2053
+ if (!result) {
2054
+ throw e;
2055
+ }
2056
+ return result;
2057
+ }).then(x => {
2058
+ const result = zohoCrmMultiRecordResult(asArray(input.tags), x.tags);
2820
2059
  const {
2821
2060
  included: duplicateErrorItems,
2822
2061
  excluded: otherErrorItems
@@ -2831,19 +2070,32 @@ function createTagsForModule(context) {
2831
2070
  };
2832
2071
  });
2833
2072
  }
2073
+ /**
2074
+ * Deletes a single tag by ID.
2075
+ *
2076
+ * Note: A tag cannot be deleted if it is associated with any configuration (e.g. Workflow Rules).
2077
+ *
2078
+ * https://www.zoho.com/crm/developer/docs/api/v8/delete-tag.html
2079
+ *
2080
+ * @param context
2081
+ * @returns
2082
+ */
2083
+ function zohoCrmDeleteTag(context) {
2084
+ return input => context.fetchJson(`/v8/settings/tags/${input.id}`, zohoCrmApiFetchJsonInput('DELETE')).then(x => x.tags);
2085
+ }
2834
2086
  /**
2835
2087
  * Returns the list of tags within a module.
2836
2088
  *
2837
- * https://www.zoho.com/recruit/developer-guide/apiv2/get-tag-list.html
2089
+ * https://www.zoho.com/crm/developer-guide/apiv2/get-tag-list.html
2838
2090
  *
2839
2091
  * @param context
2840
2092
  * @returns
2841
2093
  */
2842
- function getTagsForModule(context) {
2843
- return input => context.fetchJson(`/v2/settings/tags?${makeUrlSearchParams({
2094
+ function zohoCrmGetTagsForModule(context) {
2095
+ return input => context.fetchJson(`/v8/settings/tags?${makeUrlSearchParams({
2844
2096
  module: input.module,
2845
2097
  my_tags: input.my_tags
2846
- })}`, zohoRecruitApiFetchJsonInput('GET')).then(x => {
2098
+ })}`, zohoCrmApiFetchJsonInput('GET')).then(x => {
2847
2099
  // NOTE: This doesn't follow the api documentation, and instead is a normal page result except it has "tags" instead of "data".
2848
2100
  return {
2849
2101
  ...x,
@@ -2851,209 +2103,74 @@ function getTagsForModule(context) {
2851
2103
  };
2852
2104
  });
2853
2105
  }
2854
- function getTagsForModulePageFactory(context) {
2855
- return zohoFetchPageFactory(getTagsForModule(context));
2106
+ function zohoCrmGetTagsForModulePageFactory(context) {
2107
+ return zohoFetchPageFactory(zohoCrmGetTagsForModule(context));
2856
2108
  }
2857
2109
  // MARK: Add Tag To Record
2858
2110
  /**
2859
- * Limit enforced by Zoho Recruit
2111
+ * Limit enforced by Zoho Crm
2860
2112
  */
2861
- const ZOHO_RECRUIT_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED = 100;
2113
+ const ZOHO_CRM_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED = 100;
2862
2114
  /**
2863
2115
  * Adds one or more tags to one or more records.
2864
2116
  *
2865
- * https://www.zoho.com/recruit/developer-guide/apiv2/add-tags.html
2117
+ * https://www.zoho.com/crm/developer-guide/apiv2/add-tags.html
2866
2118
  *
2867
2119
  * @param context
2868
2120
  * @returns
2869
2121
  */
2870
- function addTagsToRecords(context) {
2122
+ function zohoCrmAddTagsToRecords(context) {
2871
2123
  return input => {
2872
- if (Array.isArray(input.ids) && input.ids.length > ZOHO_RECRUIT_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED) {
2873
- throw new Error(`Cannot add tags to more than ${ZOHO_RECRUIT_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED} records at once.`);
2874
- }
2875
- return context.fetchJson(`/v2/${ZOHO_RECRUIT_CANDIDATES_MODULE}/actions/add_tags?${makeUrlSearchParams({
2876
- tag_names: input.tag_names,
2877
- ids: input.ids
2878
- })}`, zohoRecruitApiFetchJsonInput('POST')).then(x => {
2124
+ return context.fetchJson(`/v8/${input.module}/actions/add_tags`, zohoCrmApiFetchJsonInput('POST', zohoCrmAddTagsToRecordsRequestBody(input))).then(x => {
2879
2125
  const resultInputMap = x.data.map(() => input); // assign "input" to each value for now
2880
- return zohoRecruitMultiRecordResult(resultInputMap, x.data);
2126
+ return zohoCrmMultiRecordResult(resultInputMap, x.data);
2127
+ });
2128
+ };
2129
+ }
2130
+ function zohoCrmAddTagsToRecordsRequestBody(input) {
2131
+ if (Array.isArray(input.ids) && input.ids.length > ZOHO_CRM_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED) {
2132
+ throw new Error(`Cannot add/remove tags from more than ${ZOHO_CRM_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED} records at once.`);
2133
+ }
2134
+ const tags = [...asArray(input.tags)];
2135
+ const tagNames = new Set(tags.map(x => x.name));
2136
+ if (input.tag_names) {
2137
+ asArray(input.tag_names).forEach(x => {
2138
+ if (!tagNames.has(x)) {
2139
+ tags.push({
2140
+ name: x
2141
+ });
2142
+ tagNames.add(x);
2143
+ }
2881
2144
  });
2145
+ }
2146
+ return {
2147
+ tags,
2148
+ ids: asArray(input.ids)
2882
2149
  };
2883
2150
  }
2884
2151
  // MARK: Remove Tag From Record
2885
2152
  /**
2886
- * Limit enforced by Zoho Recruit
2153
+ * Limit enforced by Zoho Crm
2887
2154
  */
2888
- const ZOHO_RECRUIT_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED = 100;
2155
+ const ZOHO_CRM_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED = 100;
2889
2156
  /**
2890
2157
  * Removes one or more tags from one or more records.
2891
2158
  *
2892
- * https://www.zoho.com/recruit/developer-guide/apiv2/remove-tags.html
2159
+ * https://www.zoho.com/crm/developer-guide/apiv2/remove-tags.html
2893
2160
  *
2894
2161
  * @param context
2895
2162
  * @returns
2896
2163
  */
2897
- function removeTagsFromRecords(context) {
2164
+ function zohoCrmRemoveTagsFromRecords(context) {
2898
2165
  return input => {
2899
- if (Array.isArray(input.ids) && input.ids.length > ZOHO_RECRUIT_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED) {
2900
- throw new Error(`Cannot remove tags from more than ${ZOHO_RECRUIT_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED} records at once.`);
2901
- }
2902
- return context.fetchJson(`/v2/${ZOHO_RECRUIT_CANDIDATES_MODULE}/actions/remove_tags?${makeUrlSearchParams({
2903
- tag_names: input.tag_names,
2904
- ids: input.ids
2905
- })}`, zohoRecruitApiFetchJsonInput('POST')).then(x => {
2166
+ return context.fetchJson(`/v8/${input.module}/actions/remove_tags`, zohoCrmApiFetchJsonInput('POST', zohoCrmAddTagsToRecordsRequestBody(input))).then(x => {
2906
2167
  const resultInputMap = x.data.map(() => input); // assign "input" to each value for now
2907
- return zohoRecruitMultiRecordResult(resultInputMap, x.data);
2168
+ return zohoCrmMultiRecordResult(resultInputMap, x.data);
2908
2169
  });
2909
2170
  };
2910
2171
  }
2911
2172
 
2912
- /**
2913
- * Creates a ZohoRecruitSearchRecordsCriteriaEntryArray from an array of emails.
2914
- *
2915
- * @param emails Email or array of emails to search for.
2916
- * @param field Optional field name to use. Defaults to 'Email'.
2917
- * @returns Array of ZohoRecruitSearchRecordsCriteriaEntry
2918
- */
2919
- function zohoRecruitSearchRecordsCriteriaEntriesForEmails(emails, field = 'Email') {
2920
- const allEmails = asArray(emails);
2921
- return allEmails.map(email => {
2922
- const emailCriteria = {
2923
- field,
2924
- filter: 'equals',
2925
- value: email
2926
- };
2927
- return emailCriteria;
2928
- });
2929
- }
2930
-
2931
- /**
2932
- * Error in the following cases:
2933
- * - the refresh token string is invalid
2934
- */
2935
- const ZOHO_ACCOUNTS_INVALID_CODE_ERROR_CODE = 'invalid_code';
2936
- const ZOHO_ACCOUNTS_INVALID_CLIENT_ERROR_CODE = 'invalid_client';
2937
- /**
2938
- * Thrown if the call to the Zoho API creating an access token using a refresh token fails.
2939
- */
2940
- class ZohoAccountsAccessTokenError extends FetchRequestFactoryError {
2941
- constructor(errorCode) {
2942
- super(`ZohoAccountsAccessTokenError: ${errorCode}`);
2943
- this.errorCode = void 0;
2944
- this.errorCode = errorCode;
2945
- }
2946
- }
2947
- /**
2948
- * Thrown if a valid ZohoAccessToken cannot be retrieved successfully.
2949
- */
2950
- class ZohoAccountsAuthFailureError extends FetchRequestFactoryError {
2951
- constructor(reason) {
2952
- super(`Failed to retrieve proper authentication for the API call. Reason: ${reason}`);
2953
- this.reason = void 0;
2954
- this.reason = reason;
2955
- }
2956
- }
2957
- const logZohoAccountsErrorToConsole = logZohoServerErrorFunction('ZohoAccounts');
2958
- async function parseZohoAccountsError(responseError) {
2959
- const data = await responseError.response.json().catch(x => undefined);
2960
- let result;
2961
- if (data) {
2962
- result = parseZohoAccountsServerErrorResponseData(data, responseError);
2963
- }
2964
- return result;
2965
- }
2966
- function parseZohoAccountsServerErrorResponseData(errorResponseData, responseError) {
2967
- let result;
2968
- const error = errorResponseData.error;
2969
- if (error) {
2970
- const errorData = zohoServerErrorData(error);
2971
- switch (errorData.code) {
2972
- case ZOHO_ACCOUNTS_INVALID_CODE_ERROR_CODE:
2973
- case ZOHO_ACCOUNTS_INVALID_CLIENT_ERROR_CODE:
2974
- result = new ZohoAccountsAccessTokenError(errorData.code);
2975
- break;
2976
- default:
2977
- result = parseZohoServerErrorResponseData(errorResponseData, responseError);
2978
- break;
2979
- }
2980
- }
2981
- return result;
2982
- }
2983
- const interceptZohoAccounts200StatusWithErrorResponse = interceptZohoErrorResponseFactory(parseZohoAccountsServerErrorResponseData);
2984
- const handleZohoAccountsErrorFetch = handleZohoErrorFetchFactory(parseZohoAccountsError, logZohoAccountsErrorToConsole);
2985
-
2986
- /**
2987
- * Generates a new ZohoAccessTokenStringFactory.
2988
- */
2989
- function zohoAccessTokenStringFactory(zohoAccessTokenFactory) {
2990
- return async () => {
2991
- const token = await zohoAccessTokenFactory();
2992
- if (!token?.accessToken) {
2993
- throw new ZohoAccountsAuthFailureError();
2994
- }
2995
- return token.accessToken;
2996
- };
2997
- }
2998
-
2999
- const DEFAULT_ZOHO_RATE_LIMITED_TOO_MANY_REQUETS_LOG_FUNCTION = headers => {
3000
- console.warn(`zohoRateLimitedFetchHandler(): Too many requests made. The limit is ${headers.limit} requests per reset period. Will be reset at ${headers.resetAt}.`);
3001
- };
3002
- function zohoRateLimitedFetchHandler(config) {
3003
- const onTooManyRequests = config?.onTooManyRequests !== false ? config?.onTooManyRequests ?? DEFAULT_ZOHO_RATE_LIMITED_TOO_MANY_REQUETS_LOG_FUNCTION : undefined;
3004
- const defaultLimit = config?.maxRateLimit ?? DEFAULT_ZOHO_API_RATE_LIMIT;
3005
- const defaultResetPeriod = config?.resetPeriod ?? DEFAULT_ZOHO_API_RATE_LIMIT_RESET_PERIOD;
3006
- function configForLimit(limit, resetAt) {
3007
- return {
3008
- limit: defaultLimit,
3009
- startLimitAt: Math.ceil(limit / 10),
3010
- // can do 10% of the requests of the limit before rate limiting begins
3011
- cooldownRate: 1.2 * (limit / (defaultResetPeriod / MS_IN_SECOND)),
3012
- exponentRate: 1.08,
3013
- maxWaitTime: MS_IN_SECOND * 10,
3014
- resetPeriod: defaultResetPeriod,
3015
- resetAt
3016
- };
3017
- }
3018
- const defaultConfig = configForLimit(defaultLimit);
3019
- const rateLimiter = resetPeriodPromiseRateLimiter(defaultConfig);
3020
- return rateLimitedFetchHandler({
3021
- rateLimiter,
3022
- updateWithResponse: function (response, fetchResponseError) {
3023
- const hasLimitHeader = response.headers.has(ZOHO_RATE_LIMIT_REMAINING_HEADER);
3024
- let shouldRetry = false;
3025
- let enabled = false;
3026
- if (hasLimitHeader) {
3027
- const headerDetails = zohoRateLimitHeaderDetails(response.headers);
3028
- if (headerDetails) {
3029
- const {
3030
- limit,
3031
- resetAt,
3032
- remaining
3033
- } = headerDetails;
3034
- if (limit !== defaultLimit) {
3035
- const newConfig = configForLimit(limit, resetAt);
3036
- rateLimiter.setConfig(newConfig, false);
3037
- }
3038
- rateLimiter.setRemainingLimit(remaining);
3039
- rateLimiter.setNextResetAt(resetAt);
3040
- enabled = true;
3041
- // only retry if it's a TOO MANY REQUESTS error
3042
- if (response.status === ZOHO_TOO_MANY_REQUESTS_HTTP_STATUS_CODE) {
3043
- shouldRetry = true;
3044
- try {
3045
- onTooManyRequests?.(headerDetails, response, fetchResponseError);
3046
- } catch (e) {}
3047
- }
3048
- }
3049
- }
3050
- rateLimiter.setEnabled(enabled);
3051
- return shouldRetry;
3052
- }
3053
- });
3054
- }
3055
-
3056
- function zohoRecruitFactory(factoryConfig) {
2173
+ function zohoCrmFactory(factoryConfig) {
3057
2174
  const {
3058
2175
  accountsContext
3059
2176
  } = factoryConfig;
@@ -3081,21 +2198,21 @@ function zohoRecruitFactory(factoryConfig) {
3081
2198
  if (!config.apiUrl) {
3082
2199
  throw new Error('ZohoConfig missing api url.');
3083
2200
  }
3084
- const apiUrl = zohoRecruitConfigApiUrl(config.apiUrl);
2201
+ const apiUrl = zohoCrmConfigApiUrl(config.apiUrl);
3085
2202
  const baseFetch = fetchFactory({
3086
2203
  apiUrl
3087
2204
  });
3088
- const fetch = handleZohoRecruitErrorFetch(baseFetch, logZohoServerErrorFunction, x => {
2205
+ const fetch = handleZohoCrmErrorFetch(baseFetch, logZohoServerErrorFunction, x => {
3089
2206
  if (x instanceof ZohoInvalidTokenError) {
3090
2207
  accountsContext.loadAccessToken.resetAccessToken();
3091
2208
  }
3092
2209
  });
3093
2210
  const fetchJson = fetchJsonFunction(fetch, {
3094
- interceptJsonResponse: interceptZohoRecruit200StatusWithErrorResponse,
2211
+ interceptJsonResponse: interceptZohoCrm200StatusWithErrorResponse,
3095
2212
  // intercept errors that return status 200
3096
2213
  handleFetchJsonParseErrorFunction: returnNullHandleFetchJsonParseErrorFunction
3097
2214
  });
3098
- const recruitContext = {
2215
+ const crmContext = {
3099
2216
  fetch,
3100
2217
  fetchJson,
3101
2218
  accessTokenStringFactory,
@@ -3105,25 +2222,39 @@ function zohoRecruitFactory(factoryConfig) {
3105
2222
  },
3106
2223
  zohoRateLimiter: fetchHandler._rateLimiter
3107
2224
  };
3108
- const zohoRecruit = {
3109
- recruitContext
2225
+ const zohoCrm = {
2226
+ crmContext
3110
2227
  };
3111
- return zohoRecruit;
2228
+ return zohoCrm;
3112
2229
  };
3113
2230
  }
3114
2231
 
3115
2232
  /**
3116
- * Maximum length of ZohoRecruitTagName
2233
+ * Maximum length of ZohoCrmTagName
3117
2234
  */
3118
- const ZOHO_RECRUIT_TAG_NAME_MAX_LENGTH = 25;
2235
+ const ZOHO_CRM_TAG_NAME_MAX_LENGTH = 25;
3119
2236
 
3120
2237
  /**
3121
2238
  * Trades a refresh token for a new AccessToken
3122
2239
  * @param context
3123
2240
  * @returns
3124
2241
  */
3125
- function accessToken(context) {
3126
- return input => context.fetchJson(`/oauth/v2/token?grant_type=refresh_token&client_id=${input?.client?.clientId ?? context.config.clientId}&client_secret=${input?.client?.clientSecret ?? context.config.clientSecret}&refresh_token=${input?.refreshToken ?? context.config.refreshToken}`, zohoAccountsApiFetchJsonInput('POST'));
2242
+ function zohoAccountsAccessToken(context) {
2243
+ return input => {
2244
+ const {
2245
+ clientId: configClientId,
2246
+ clientSecret: configClientSecret,
2247
+ refreshToken: configRefreshToken
2248
+ } = context.config;
2249
+ const {
2250
+ client,
2251
+ refreshToken: inputRefreshToken
2252
+ } = input ?? {};
2253
+ const clientId = client?.clientId ?? configClientId;
2254
+ const clientSecret = client?.clientSecret ?? configClientSecret;
2255
+ const refreshToken = inputRefreshToken ?? configRefreshToken;
2256
+ return context.fetchJson(`/oauth/v2/token?grant_type=refresh_token&client_id=${clientId}&client_secret=${clientSecret}&refresh_token=${refreshToken}`, zohoAccountsApiFetchJsonInput('POST'));
2257
+ };
3127
2258
  }
3128
2259
  function zohoAccountsApiFetchJsonInput(method, body) {
3129
2260
  const result = {
@@ -3190,7 +2321,7 @@ function zohoAccountsFactory(factoryConfig) {
3190
2321
  api_domain,
3191
2322
  scope,
3192
2323
  expires_in
3193
- } = await accessToken(accountsContext)();
2324
+ } = await zohoAccountsAccessToken(accountsContext)();
3194
2325
  const result = {
3195
2326
  accessToken: access_token,
3196
2327
  apiDomain: api_domain,
@@ -3293,4 +2424,4 @@ function zohoDateTimeString(date) {
3293
2424
  return isoDate.substring(0, isoDate.length - 5) + 'Z';
3294
2425
  }
3295
2426
 
3296
- export { DEFAULT_ZOHO_API_RATE_LIMIT, DEFAULT_ZOHO_API_RATE_LIMIT_RESET_PERIOD, DEFAULT_ZOHO_RATE_LIMITED_TOO_MANY_REQUETS_LOG_FUNCTION, MAX_ZOHO_RECRUIT_SEARCH_MODULE_RECORDS_CRITERIA, ZOHO_ACCOUNTS_INVALID_CLIENT_ERROR_CODE, ZOHO_ACCOUNTS_INVALID_CODE_ERROR_CODE, ZOHO_ACCOUNTS_US_API_URL, ZOHO_DUPLICATE_DATA_ERROR_CODE, ZOHO_ERROR_STATUS, ZOHO_FAILURE_ERROR_CODE, ZOHO_INTERNAL_ERROR_CODE, ZOHO_INVALID_AUTHORIZATION_ERROR_CODE, ZOHO_INVALID_DATA_ERROR_CODE, ZOHO_INVALID_QUERY_ERROR_CODE, ZOHO_INVALID_TOKEN_ERROR_CODE, ZOHO_MANDATORY_NOT_FOUND_ERROR_CODE, ZOHO_RATE_LIMIT_LIMIT_HEADER, ZOHO_RATE_LIMIT_REMAINING_HEADER, ZOHO_RATE_LIMIT_RESET_HEADER, ZOHO_RECRUIT_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED, ZOHO_RECRUIT_ALREADY_ASSOCIATED_ERROR_CODE, ZOHO_RECRUIT_ATTACHMENTS_MODULE, ZOHO_RECRUIT_ATTACHMENT_MAX_SIZE, ZOHO_RECRUIT_CANDIDATES_MODULE, ZOHO_RECRUIT_CRUD_FUNCTION_MAX_RECORDS_LIMIT, ZOHO_RECRUIT_EMAILS_MODULE, ZOHO_RECRUIT_JOB_OPENINGS_MODULE, ZOHO_RECRUIT_NOTES_MODULE, ZOHO_RECRUIT_RECORD_ATTACHMENT_METADATA_ATTACH_TYPE_RESUME, ZOHO_RECRUIT_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED, ZOHO_RECRUIT_SERVICE_NAME, ZOHO_RECRUIT_TAG_NAME_MAX_LENGTH, ZOHO_SUCCESS_CODE, ZOHO_SUCCESS_STATUS, ZOHO_TOO_MANY_REQUESTS_ERROR_CODE, ZOHO_TOO_MANY_REQUESTS_HTTP_STATUS_CODE, ZohoAccountsAccessTokenError, ZohoAccountsAuthFailureError, ZohoInternalError, ZohoInvalidAuthorizationError, ZohoInvalidQueryError, ZohoInvalidTokenError, ZohoRecruitExecuteRestApiFunctionError, ZohoRecruitRecordCrudDuplicateDataError, ZohoRecruitRecordCrudError, ZohoRecruitRecordCrudInvalidDataError, ZohoRecruitRecordCrudMandatoryFieldNotFoundError, ZohoRecruitRecordCrudNoMatchingRecordError, ZohoRecruitRecordNoContentError, ZohoServerError, ZohoServerFetchResponseError, ZohoTooManyRequestsError, accessToken, addTagsToRecords, assertRecordDataArrayResultHasContent, associateCandidateRecordsWithJobOpenings, createNotes, createNotesForRecord, createTagsForModule, deleteAttachmentFromRecord, deleteNotes, deleteRecord, downloadAttachmentForRecord, emptyZohoPageResult, escapeZohoFieldValueForCriteriaString, executeRestApiFunction, getAttachmentsForRecord, getAttachmentsForRecordPageFactory, getEmailsForRecord, getEmailsForRecordPageFactory, getNotesForRecord, getNotesForRecordPageFactory, getRecordById, getRecords, getRelatedRecordsFunctionFactory, getTagsForModule, getTagsForModulePageFactory, handleZohoAccountsErrorFetch, handleZohoErrorFetchFactory, handleZohoRecruitErrorFetch, insertRecord, interceptZohoAccounts200StatusWithErrorResponse, interceptZohoErrorResponseFactory, interceptZohoRecruit200StatusWithErrorResponse, isZohoRecruitValidUrl, logZohoAccountsErrorToConsole, logZohoRecruitErrorToConsole, logZohoServerErrorFunction, parseZohoAccountsError, parseZohoAccountsServerErrorResponseData, parseZohoRecruitError, parseZohoRecruitServerErrorResponseData, parseZohoServerErrorResponseData, removeTagsFromRecords, safeZohoDateTimeString, searchAssociatedRecords, searchCandidateAssociatedJobOpeningRecords, searchCandidateAssociatedJobOpeningRecordsPageFactory, searchJobOpeningAssociatedCandidateRecords, searchJobOpeningAssociatedCandidateRecordsPageFactory, searchRecords, searchRecordsPageFactory, tryFindZohoServerErrorData, updateRecord, uploadAttachmentForRecord, upsertRecord, zohoAccessTokenStringFactory, zohoAccountsApiFetchJsonInput, zohoAccountsConfigApiUrl, zohoAccountsFactory, zohoAccountsZohoAccessTokenFactory, zohoDateTimeString, zohoFetchPageFactory, zohoRateLimitHeaderDetails, zohoRateLimitedFetchHandler, zohoRecruitApiFetchJsonInput, zohoRecruitChangeObjectLikeResponseSuccessAndErrorPairs, zohoRecruitConfigApiUrl, zohoRecruitFactory, zohoRecruitMultiRecordResult, zohoRecruitRecordCrudError, zohoRecruitSearchRecordsCriteriaEntriesForEmails, zohoRecruitSearchRecordsCriteriaEntryToCriteriaString, zohoRecruitSearchRecordsCriteriaString, zohoRecruitSearchRecordsCriteriaStringForTree, zohoRecruitUrlSearchParams, zohoRecruitUrlSearchParamsMinusIdAndModule, zohoRecruitUrlSearchParamsMinusModule, zohoServerErrorData };
2427
+ export { DEFAULT_ZOHO_API_RATE_LIMIT, DEFAULT_ZOHO_API_RATE_LIMIT_RESET_PERIOD, DEFAULT_ZOHO_RATE_LIMITED_TOO_MANY_REQUETS_LOG_FUNCTION, MAX_ZOHO_CRM_SEARCH_MODULE_RECORDS_CRITERIA, MAX_ZOHO_RECRUIT_SEARCH_MODULE_RECORDS_CRITERIA, ZOHO_ACCOUNTS_INVALID_CLIENT_ERROR_CODE, ZOHO_ACCOUNTS_INVALID_CODE_ERROR_CODE, ZOHO_ACCOUNTS_US_API_URL, ZOHO_CRM_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED, ZOHO_CRM_ALREADY_ASSOCIATED_ERROR_CODE, ZOHO_CRM_ATTACHMENTS_MODULE, ZOHO_CRM_ATTACHMENT_MAX_SIZE, ZOHO_CRM_CONTACTS_MODULE, ZOHO_CRM_CRUD_FUNCTION_MAX_RECORDS_LIMIT, ZOHO_CRM_EMAILS_MODULE, ZOHO_CRM_LEADS_MODULE, ZOHO_CRM_NOTES_MODULE, ZOHO_CRM_RECORD_ATTACHMENT_METADATA_ATTACH_TYPE_RESUME, ZOHO_CRM_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED, ZOHO_CRM_SERVICE_NAME, ZOHO_CRM_TAG_NAME_MAX_LENGTH, ZOHO_CRM_TASKS_MODULE, ZOHO_DATA_ARRAY_BLANK_ERROR_CODE, ZOHO_DUPLICATE_DATA_ERROR_CODE, ZOHO_ERROR_STATUS, ZOHO_FAILURE_ERROR_CODE, ZOHO_INTERNAL_ERROR_CODE, ZOHO_INVALID_AUTHORIZATION_ERROR_CODE, ZOHO_INVALID_DATA_ERROR_CODE, ZOHO_INVALID_QUERY_ERROR_CODE, ZOHO_INVALID_TOKEN_ERROR_CODE, ZOHO_MANDATORY_NOT_FOUND_ERROR_CODE, ZOHO_RATE_LIMIT_LIMIT_HEADER, ZOHO_RATE_LIMIT_REMAINING_HEADER, ZOHO_RATE_LIMIT_RESET_HEADER, ZOHO_RECRUIT_ADD_TAGS_TO_RECORDS_MAX_IDS_ALLOWED, ZOHO_RECRUIT_ALREADY_ASSOCIATED_ERROR_CODE, ZOHO_RECRUIT_ATTACHMENTS_MODULE, ZOHO_RECRUIT_ATTACHMENT_MAX_SIZE, ZOHO_RECRUIT_CANDIDATES_MODULE, ZOHO_RECRUIT_CRUD_FUNCTION_MAX_RECORDS_LIMIT, ZOHO_RECRUIT_EMAILS_MODULE, ZOHO_RECRUIT_JOB_OPENINGS_MODULE, ZOHO_RECRUIT_NOTES_MODULE, ZOHO_RECRUIT_RECORD_ATTACHMENT_METADATA_ATTACH_TYPE_RESUME, ZOHO_RECRUIT_REMOVE_TAGS_FROM_RECORDS_MAX_IDS_ALLOWED, ZOHO_RECRUIT_SERVICE_NAME, ZOHO_RECRUIT_TAG_NAME_MAX_LENGTH, ZOHO_SUCCESS_CODE, ZOHO_SUCCESS_STATUS, ZOHO_TOO_MANY_REQUESTS_ERROR_CODE, ZOHO_TOO_MANY_REQUESTS_HTTP_STATUS_CODE, ZohoAccountsAccessTokenError, ZohoAccountsAuthFailureError, ZohoCrmExecuteRestApiFunctionError, ZohoCrmRecordCrudDuplicateDataError, ZohoCrmRecordCrudError, ZohoCrmRecordCrudInvalidDataError, ZohoCrmRecordCrudMandatoryFieldNotFoundError, ZohoCrmRecordCrudNoMatchingRecordError, ZohoCrmRecordNoContentError, ZohoInternalError, ZohoInvalidAuthorizationError, ZohoInvalidQueryError, ZohoInvalidTokenError, ZohoRecruitExecuteRestApiFunctionError, ZohoRecruitRecordCrudDuplicateDataError, ZohoRecruitRecordCrudError, ZohoRecruitRecordCrudInvalidDataError, ZohoRecruitRecordCrudMandatoryFieldNotFoundError, ZohoRecruitRecordCrudNoMatchingRecordError, ZohoRecruitRecordNoContentError, ZohoServerError, ZohoServerFetchResponseDataArrayError, ZohoServerFetchResponseError, ZohoTooManyRequestsError, addTagsToRecords, assertRecordDataArrayResultHasContent, assertZohoCrmRecordDataArrayResultHasContent, assertZohoRecruitRecordDataArrayResultHasContent, createNotes, createNotesForRecord, createTagsForModule, deleteAttachmentFromRecord, deleteNotes, deleteRecord, downloadAttachmentForRecord, emptyZohoPageResult, escapeZohoCrmFieldValueForCriteriaString, executeRestApiFunction, getAttachmentsForRecord, getAttachmentsForRecordPageFactory, getEmailsForRecord, getEmailsForRecordPageFactory, getNotesForRecord, getNotesForRecordPageFactory, getRecordById, getRecords, getRelatedRecordsFunctionFactory, getTagsForModule, getTagsForModulePageFactory, handleZohoAccountsErrorFetch, handleZohoCrmErrorFetch, handleZohoErrorFetchFactory, handleZohoRecruitErrorFetch, insertRecord, interceptZohoAccounts200StatusWithErrorResponse, interceptZohoCrm200StatusWithErrorResponse, interceptZohoErrorResponseFactory, interceptZohoRecruit200StatusWithErrorResponse, isZohoCrmValidUrl, isZohoRecruitValidUrl, isZohoServerErrorResponseDataArrayRef, logZohoAccountsErrorToConsole, logZohoCrmErrorToConsole, logZohoRecruitErrorToConsole, logZohoServerErrorFunction, parseZohoAccountsError, parseZohoAccountsServerErrorResponseData, parseZohoCrmError, parseZohoCrmServerErrorResponseData, parseZohoRecruitError, parseZohoRecruitServerErrorResponseData, parseZohoServerErrorResponseData, removeTagsFromRecords, safeZohoDateTimeString, searchRecords, searchRecordsPageFactory, tryFindZohoServerErrorData, updateRecord, uploadAttachmentForRecord, upsertRecord, zohoAccessTokenStringFactory, zohoAccountsAccessToken, zohoAccountsApiFetchJsonInput, zohoAccountsConfigApiUrl, zohoAccountsFactory, zohoAccountsZohoAccessTokenFactory, zohoCrmAddTagsToRecords, zohoCrmAddTagsToRecordsRequestBody, zohoCrmApiFetchJsonInput, zohoCrmCatchZohoCrmChangeObjectLikeResponseError, zohoCrmChangeObjectLikeResponseSuccessAndErrorPairs, zohoCrmConfigApiUrl, zohoCrmCreateNotes, zohoCrmCreateNotesForRecord, zohoCrmCreateTagsForModule, zohoCrmDeleteAttachmentFromRecord, zohoCrmDeleteNotes, zohoCrmDeleteRecord, zohoCrmDeleteTag, zohoCrmDownloadAttachmentForRecord, zohoCrmExecuteRestApiFunction, zohoCrmFactory, zohoCrmGetAttachmentsForRecord, zohoCrmGetAttachmentsForRecordPageFactory, zohoCrmGetEmailsForRecord, zohoCrmGetEmailsForRecordPageFactory, zohoCrmGetNotesForRecord, zohoCrmGetNotesForRecordPageFactory, zohoCrmGetRecordById, zohoCrmGetRecords, zohoCrmGetRelatedRecordsFunctionFactory, zohoCrmGetTagsForModule, zohoCrmGetTagsForModulePageFactory, zohoCrmInsertRecord, zohoCrmMultiRecordResult, zohoCrmRecordCrudError, zohoCrmRemoveTagsFromRecords, zohoCrmSearchRecords, zohoCrmSearchRecordsCriteriaEntryToCriteriaString, zohoCrmSearchRecordsCriteriaString, zohoCrmSearchRecordsCriteriaStringForTree, zohoCrmSearchRecordsPageFactory, zohoCrmUpdateRecord, zohoCrmUploadAttachmentForRecord, zohoCrmUpsertRecord, zohoCrmUrlSearchParams, zohoCrmUrlSearchParamsMinusIdAndModule, zohoCrmUrlSearchParamsMinusModule, zohoDateTimeString, zohoFetchPageFactory, zohoRateLimitHeaderDetails, zohoRateLimitedFetchHandler, zohoRecruitAddTagsToRecords, zohoRecruitApiFetchJsonInput, zohoRecruitAssociateCandidateRecordsWithJobOpenings, zohoRecruitChangeObjectLikeResponseSuccessAndErrorPairs, zohoRecruitConfigApiUrl, zohoRecruitCreateNotes, zohoRecruitCreateNotesForRecord, zohoRecruitCreateTagsForModule, zohoRecruitDeleteAttachmentFromRecord, zohoRecruitDeleteNotes, zohoRecruitDeleteRecord, zohoRecruitDownloadAttachmentForRecord, zohoRecruitExecuteRestApiFunction, zohoRecruitFactory, zohoRecruitGetAttachmentsForRecord, zohoRecruitGetAttachmentsForRecordPageFactory, zohoRecruitGetEmailsForRecord, zohoRecruitGetEmailsForRecordPageFactory, zohoRecruitGetNotesForRecord, zohoRecruitGetNotesForRecordPageFactory, zohoRecruitGetRecordById, zohoRecruitGetRecords, zohoRecruitGetRelatedRecordsFunctionFactory, zohoRecruitGetTagsForModule, zohoRecruitGetTagsForModulePageFactory, zohoRecruitInsertRecord, zohoRecruitMultiRecordResult, zohoRecruitRecordCrudError, zohoRecruitRemoveTagsFromRecords, zohoRecruitSearchAssociatedRecords, zohoRecruitSearchCandidateAssociatedJobOpeningRecords, zohoRecruitSearchCandidateAssociatedJobOpeningRecordsPageFactory, zohoRecruitSearchJobOpeningAssociatedCandidateRecords, zohoRecruitSearchJobOpeningAssociatedCandidateRecordsPageFactory, zohoRecruitSearchRecords, zohoRecruitSearchRecordsCriteriaEntryToCriteriaString, zohoRecruitSearchRecordsCriteriaString, zohoRecruitSearchRecordsCriteriaStringForTree, zohoRecruitSearchRecordsPageFactory, zohoRecruitUpdateRecord, zohoRecruitUploadAttachmentForRecord, zohoRecruitUpsertRecord, zohoRecruitUrlSearchParams, zohoRecruitUrlSearchParamsMinusIdAndModule, zohoRecruitUrlSearchParamsMinusModule, zohoServerErrorData };