@encodeagent/platform-helper-util 1.2508.1241505
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -0
- package/dist/__tests__/core.test.d.ts +5 -0
- package/dist/__tests__/core.test.d.ts.map +1 -0
- package/dist/__tests__/core.test.js +128 -0
- package/dist/__tests__/core.test.js.map +1 -0
- package/dist/__tests__/shortid.test.d.ts +5 -0
- package/dist/__tests__/shortid.test.d.ts.map +1 -0
- package/dist/__tests__/shortid.test.js +72 -0
- package/dist/__tests__/shortid.test.js.map +1 -0
- package/dist/__tests__/slug.test.d.ts +5 -0
- package/dist/__tests__/slug.test.d.ts.map +1 -0
- package/dist/__tests__/slug.test.js +31 -0
- package/dist/__tests__/slug.test.js.map +1 -0
- package/dist/__tests__/token.test.d.ts +5 -0
- package/dist/__tests__/token.test.d.ts.map +1 -0
- package/dist/__tests__/token.test.js +49 -0
- package/dist/__tests__/token.test.js.map +1 -0
- package/dist/__tests__/uuid.test.d.ts +5 -0
- package/dist/__tests__/uuid.test.d.ts.map +1 -0
- package/dist/__tests__/uuid.test.js +42 -0
- package/dist/__tests__/uuid.test.js.map +1 -0
- package/dist/__tests__/value-of-object.test.d.ts +5 -0
- package/dist/__tests__/value-of-object.test.d.ts.map +1 -0
- package/dist/__tests__/value-of-object.test.js +49 -0
- package/dist/__tests__/value-of-object.test.js.map +1 -0
- package/dist/ai/llm.d.ts +90 -0
- package/dist/ai/llm.d.ts.map +1 -0
- package/dist/ai/llm.js +524 -0
- package/dist/ai/llm.js.map +1 -0
- package/dist/ai/model.d.ts +14 -0
- package/dist/ai/model.d.ts.map +1 -0
- package/dist/ai/model.js +120 -0
- package/dist/ai/model.js.map +1 -0
- package/dist/ai/types.d.ts +85 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +15 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/ai/util.d.ts +28 -0
- package/dist/ai/util.d.ts.map +1 -0
- package/dist/ai/util.js +43 -0
- package/dist/ai/util.js.map +1 -0
- package/dist/auth.d.ts +34 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +568 -0
- package/dist/auth.js.map +1 -0
- package/dist/colors.d.ts +79 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +492 -0
- package/dist/colors.js.map +1 -0
- package/dist/constants.d.ts +86 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +2578 -0
- package/dist/constants.js.map +1 -0
- package/dist/core.d.ts +337 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +1165 -0
- package/dist/core.js.map +1 -0
- package/dist/cost.d.ts +35 -0
- package/dist/cost.d.ts.map +1 -0
- package/dist/cost.js +143 -0
- package/dist/cost.js.map +1 -0
- package/dist/file.d.ts +55 -0
- package/dist/file.d.ts.map +1 -0
- package/dist/file.js +273 -0
- package/dist/file.js.map +1 -0
- package/dist/html.d.ts +44 -0
- package/dist/html.d.ts.map +1 -0
- package/dist/html.js +420 -0
- package/dist/html.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +313 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.d.ts +20 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +38 -0
- package/dist/markdown.js.map +1 -0
- package/dist/metadata.d.ts +39 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +110 -0
- package/dist/metadata.js.map +1 -0
- package/dist/record.d.ts +67 -0
- package/dist/record.d.ts.map +1 -0
- package/dist/record.js +404 -0
- package/dist/record.js.map +1 -0
- package/dist/shortid.d.ts +42 -0
- package/dist/shortid.d.ts.map +1 -0
- package/dist/shortid.js +42 -0
- package/dist/shortid.js.map +1 -0
- package/dist/slug.d.ts +24 -0
- package/dist/slug.d.ts.map +1 -0
- package/dist/slug.js +43 -0
- package/dist/slug.js.map +1 -0
- package/dist/token.d.ts +34 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +20 -0
- package/dist/token.js.map +1 -0
- package/dist/tree.d.ts +27 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +193 -0
- package/dist/tree.js.map +1 -0
- package/dist/types.d.ts +270 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/dist/uuid.d.ts +25 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +32 -0
- package/dist/uuid.js.map +1 -0
- package/dist/value-of-object.d.ts +25 -0
- package/dist/value-of-object.d.ts.map +1 -0
- package/dist/value-of-object.js +123 -0
- package/dist/value-of-object.js.map +1 -0
- package/dist/web-content.d.ts +54 -0
- package/dist/web-content.d.ts.map +1 -0
- package/dist/web-content.js +268 -0
- package/dist/web-content.js.map +1 -0
- package/dist/web.d.ts +36 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +162 -0
- package/dist/web.js.map +1 -0
- package/package.json +68 -0
package/dist/core.js
ADDED
|
@@ -0,0 +1,1165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Core utility functions including global object handling, environment detection, validation, string manipulation, and caching utilities
|
|
4
|
+
* @copyright PrimeObjects Software Inc. (C) 2024 All Rights Reserved
|
|
5
|
+
* @author EncodeAgent Team.
|
|
6
|
+
* @copyright © 2024 PrimeObjects Software Inc. All rights reserved.
|
|
7
|
+
* @license Proprietary - Subject to PrimeObjects License Agreements
|
|
8
|
+
* @contact encode.agent@primeobjects.com
|
|
9
|
+
* @website https://www.encodeagent.com/
|
|
10
|
+
*
|
|
11
|
+
* This software contains proprietary and confidential information of
|
|
12
|
+
* PrimeObjects Software Inc. Any reproduction or distribution of this
|
|
13
|
+
* software, in whole or in part, without written permission of
|
|
14
|
+
* PrimeObjects Software Inc. is strictly prohibited.
|
|
15
|
+
*
|
|
16
|
+
* Unauthorized copying of this file, via any medium, is strictly prohibited.
|
|
17
|
+
* This file is proprietary and confidential.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.setCacheByGroupId = exports.resetCacheByGroupId = exports.removeCache = exports.setCache = exports.getCache = exports.findLanguage = exports.findGender = exports.findCountry = exports.deepFlatten = exports.formatJSONString = exports.readableFileSize = exports.formatText = exports.numberWithCommas = exports.formatNumberBMK = exports.shortenNumber = exports.groupItems = exports.removeNoValueProperty = exports.isObjectString = exports.isObject = exports.shortenString = exports.formatString = exports.getUTCMaxISOString = exports.getUTCISOString = exports.getMaxTimestamp = exports.getTimestamp = exports.isPassword = exports.isEmail = exports.checkToTrue = exports.ttl = exports.serialNumber = exports.getDateTimeString = exports.timeDiff = exports.getSubObject = exports.base64ToJson = exports.jsonToBase64 = exports.isEmptyString = exports.isPhoneNumber = exports.isGuid = exports.isNonEmptyString = exports.stringToColor = exports.doNothing = exports.getPropName = exports.setLibTrack = exports.libTrackIsOn = exports.setAppTrack = exports.appTrackIsOn = exports.getGlobalEnv = exports.getGlobalObject = exports.getProcess = exports.getWindow = void 0;
|
|
21
|
+
exports.toTitle = exports.getObjsDifference = exports.wait = exports.isGoodJSON = exports.parseString = exports.generateBatchArray = exports.calculateSurcharge = exports.convertToOneParagraph = exports.trimNewLine = exports.getLastDayOfTheWeek = exports.getFirstDayOfTheWeek = exports.isFloatString = exports.isIntegerString = exports.isBooleanString = exports.isNumberString = exports.convertEnumToArray = exports.isEmptyGuid = exports.sameGuid = exports.cleanGuid = exports.removeCacheByGroupId = exports.getCacheByGroupId = void 0;
|
|
22
|
+
const lodash_1 = require("lodash");
|
|
23
|
+
// import { isValidNumber } from "libphonenumber-js";
|
|
24
|
+
const constants_1 = require("./constants");
|
|
25
|
+
/**
|
|
26
|
+
* Gets the global window object if available, otherwise returns empty object
|
|
27
|
+
* @returns {IWindow | Record<string, never>} Window object or empty object
|
|
28
|
+
* @example
|
|
29
|
+
* const win = getWindow();
|
|
30
|
+
* if ('document' in win) {
|
|
31
|
+
* // Browser environment
|
|
32
|
+
* }
|
|
33
|
+
*/
|
|
34
|
+
const getWindow = () => {
|
|
35
|
+
return typeof window !== "undefined" ? window : {};
|
|
36
|
+
};
|
|
37
|
+
exports.getWindow = getWindow;
|
|
38
|
+
/**
|
|
39
|
+
* Gets the Node.js process object if available, otherwise returns empty object
|
|
40
|
+
* @returns {IProcess | Record<string, never>} Process object or empty object
|
|
41
|
+
* @example
|
|
42
|
+
* const proc = getProcess();
|
|
43
|
+
* if ('env' in proc) {
|
|
44
|
+
* // Node.js environment
|
|
45
|
+
* }
|
|
46
|
+
*/
|
|
47
|
+
const getProcess = () => {
|
|
48
|
+
return typeof process !== "undefined" ? process : {};
|
|
49
|
+
};
|
|
50
|
+
exports.getProcess = getProcess;
|
|
51
|
+
/**
|
|
52
|
+
* Gets the appropriate global object for the current environment
|
|
53
|
+
* @returns {GlobalObject} Global object (window in browser, process in Node.js)
|
|
54
|
+
* @example
|
|
55
|
+
* const global = getGlobalObject();
|
|
56
|
+
* console.log('env' in global ? 'Node.js' : 'Browser');
|
|
57
|
+
*/
|
|
58
|
+
const getGlobalObject = () => {
|
|
59
|
+
if (typeof window !== "undefined")
|
|
60
|
+
return window;
|
|
61
|
+
if (typeof process !== "undefined")
|
|
62
|
+
return process;
|
|
63
|
+
return {};
|
|
64
|
+
};
|
|
65
|
+
exports.getGlobalObject = getGlobalObject;
|
|
66
|
+
/**
|
|
67
|
+
* Gets environment variables from the global object
|
|
68
|
+
* @returns {NodeJS.ProcessEnv | undefined} Environment variables object or undefined
|
|
69
|
+
* @example
|
|
70
|
+
* const env = getGlobalEnv();
|
|
71
|
+
* const port = env?.PORT || '3000';
|
|
72
|
+
*/
|
|
73
|
+
const getGlobalEnv = () => {
|
|
74
|
+
const global = (0, exports.getGlobalObject)();
|
|
75
|
+
return 'env' in global ? global.env : undefined;
|
|
76
|
+
};
|
|
77
|
+
exports.getGlobalEnv = getGlobalEnv;
|
|
78
|
+
/**
|
|
79
|
+
* Checks if application tracking is enabled
|
|
80
|
+
* @returns {boolean} True if app tracking is enabled
|
|
81
|
+
* @example
|
|
82
|
+
* if (appTrackIsOn()) {
|
|
83
|
+
* console.log('Tracking enabled');
|
|
84
|
+
* }
|
|
85
|
+
*/
|
|
86
|
+
const appTrackIsOn = () => {
|
|
87
|
+
const global = (0, exports.getGlobalObject)();
|
|
88
|
+
// Check direct property
|
|
89
|
+
if ('APP_TRACK' in global) {
|
|
90
|
+
const value = String(global.APP_TRACK).toLowerCase();
|
|
91
|
+
if (value === 'true')
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
// Check environment variables
|
|
95
|
+
const env = (0, exports.getGlobalEnv)();
|
|
96
|
+
if (env?.APP_TRACK?.toLowerCase() === 'true')
|
|
97
|
+
return true;
|
|
98
|
+
return false;
|
|
99
|
+
};
|
|
100
|
+
exports.appTrackIsOn = appTrackIsOn;
|
|
101
|
+
/**
|
|
102
|
+
* Sets the application tracking flag
|
|
103
|
+
* @param {boolean} value - Whether to enable app tracking
|
|
104
|
+
* @example
|
|
105
|
+
* setAppTrack(true); // Enable tracking
|
|
106
|
+
*/
|
|
107
|
+
const setAppTrack = (value) => {
|
|
108
|
+
const global = (0, exports.getGlobalObject)();
|
|
109
|
+
global.APP_TRACK = value;
|
|
110
|
+
};
|
|
111
|
+
exports.setAppTrack = setAppTrack;
|
|
112
|
+
/**
|
|
113
|
+
* Checks if library tracking is enabled
|
|
114
|
+
* @returns {boolean} True if library tracking is enabled
|
|
115
|
+
* @example
|
|
116
|
+
* if (libTrackIsOn()) {
|
|
117
|
+
* console.log('Library tracking enabled');
|
|
118
|
+
* }
|
|
119
|
+
*/
|
|
120
|
+
const libTrackIsOn = () => {
|
|
121
|
+
const global = (0, exports.getGlobalObject)();
|
|
122
|
+
// Check direct property
|
|
123
|
+
if ('LIB_TRACK' in global) {
|
|
124
|
+
const value = String(global.LIB_TRACK).toLowerCase();
|
|
125
|
+
if (value === 'true')
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
// Check environment variables
|
|
129
|
+
const env = (0, exports.getGlobalEnv)();
|
|
130
|
+
if (env?.LIB_TRACK?.toLowerCase() === 'true')
|
|
131
|
+
return true;
|
|
132
|
+
return false;
|
|
133
|
+
};
|
|
134
|
+
exports.libTrackIsOn = libTrackIsOn;
|
|
135
|
+
/**
|
|
136
|
+
* Sets the library tracking flag
|
|
137
|
+
* @param {boolean} value - Whether to enable library tracking
|
|
138
|
+
* @example
|
|
139
|
+
* setLibTrack(false); // Disable library tracking
|
|
140
|
+
*/
|
|
141
|
+
const setLibTrack = (value) => {
|
|
142
|
+
const global = (0, exports.getGlobalObject)();
|
|
143
|
+
global.LIB_TRACK = value;
|
|
144
|
+
};
|
|
145
|
+
exports.setLibTrack = setLibTrack;
|
|
146
|
+
/**
|
|
147
|
+
* Converts a string to a valid property name in camelCase
|
|
148
|
+
* @param {string} s - Input string to convert
|
|
149
|
+
* @returns {string} Camel case property name
|
|
150
|
+
* @throws {Error} When input string is empty or invalid
|
|
151
|
+
* @example
|
|
152
|
+
* getPropName('user name') // returns 'userName'
|
|
153
|
+
* getPropName('API-KEY') // returns 'apiKey'
|
|
154
|
+
*/
|
|
155
|
+
const getPropName = (s) => {
|
|
156
|
+
if (!s || typeof s !== 'string') {
|
|
157
|
+
throw new Error('Input must be a non-empty string');
|
|
158
|
+
}
|
|
159
|
+
const cleaned = s.replace(/[^a-zA-Z0-9]/g, " ").replace(/[ ]{2,}/gi, " ").trim();
|
|
160
|
+
if (!cleaned) {
|
|
161
|
+
throw new Error('Input string must contain at least one alphanumeric character');
|
|
162
|
+
}
|
|
163
|
+
return (0, exports.formatText)(cleaned, "camel");
|
|
164
|
+
};
|
|
165
|
+
exports.getPropName = getPropName;
|
|
166
|
+
/**
|
|
167
|
+
* Utility function to handle TypeScript unused variable warnings
|
|
168
|
+
* @param {T} o - Any value to return unchanged
|
|
169
|
+
* @returns {T} The input value unchanged
|
|
170
|
+
* @template T
|
|
171
|
+
* @example
|
|
172
|
+
* const unused = doNothing(someVariable); // Prevents TS unused variable warning
|
|
173
|
+
*/
|
|
174
|
+
const doNothing = (o) => {
|
|
175
|
+
return o;
|
|
176
|
+
};
|
|
177
|
+
exports.doNothing = doNothing;
|
|
178
|
+
/**
|
|
179
|
+
* Converts a string to a consistent HSL color
|
|
180
|
+
* @param {string} str - Input string to convert to color
|
|
181
|
+
* @param {number} [s=50] - Saturation value (0-100)
|
|
182
|
+
* @param {number} [l=50] - Lightness value (0-100)
|
|
183
|
+
* @returns {string | null} HSL color string or null if invalid input
|
|
184
|
+
* @example
|
|
185
|
+
* stringToColor('user123', 70, 60) // returns 'hsl(245, 70%, 60%)'
|
|
186
|
+
* stringToColor('admin', 80) // returns 'hsl(123, 80%, 50%)'
|
|
187
|
+
*/
|
|
188
|
+
const stringToColor = (str, s = 50, l = 50) => {
|
|
189
|
+
if (!str || typeof str !== 'string') {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
// Validate saturation and lightness values
|
|
193
|
+
const saturation = Math.max(0, Math.min(100, s));
|
|
194
|
+
const lightness = Math.max(0, Math.min(100, l));
|
|
195
|
+
let hash = 0;
|
|
196
|
+
for (let i = 0; i < str.length; i++) {
|
|
197
|
+
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
198
|
+
}
|
|
199
|
+
const hue = Math.abs(hash) % 360;
|
|
200
|
+
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
|
201
|
+
};
|
|
202
|
+
exports.stringToColor = stringToColor;
|
|
203
|
+
/**
|
|
204
|
+
* Checks if a value is a non-empty string
|
|
205
|
+
* @param {unknown} s - Value to check
|
|
206
|
+
* @param {boolean} [trim=false] - Whether to trim whitespace before checking
|
|
207
|
+
* @returns {boolean} True if value is a non-empty string
|
|
208
|
+
* @example
|
|
209
|
+
* isNonEmptyString('hello') // returns true
|
|
210
|
+
* isNonEmptyString(' ', true) // returns false
|
|
211
|
+
* isNonEmptyString(' ', false) // returns true
|
|
212
|
+
*/
|
|
213
|
+
const isNonEmptyString = (s, trim = false) => {
|
|
214
|
+
if (!(0, lodash_1.isString)(s)) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
return trim ? s.trim().length > 0 : s.length > 0;
|
|
218
|
+
};
|
|
219
|
+
exports.isNonEmptyString = isNonEmptyString;
|
|
220
|
+
/**
|
|
221
|
+
* Validates if a string is a valid GUID/UUID format
|
|
222
|
+
* @param {unknown} s - Value to validate
|
|
223
|
+
* @param {boolean} [allowNilEmpty=false] - Whether to allow null/empty values
|
|
224
|
+
* @returns {boolean} True if valid GUID format
|
|
225
|
+
* @example
|
|
226
|
+
* isGuid('550e8400-e29b-41d4-a716-446655440000') // returns true
|
|
227
|
+
* isGuid('{550e8400-e29b-41d4-a716-446655440000}') // returns true
|
|
228
|
+
* isGuid('invalid-guid') // returns false
|
|
229
|
+
*/
|
|
230
|
+
const isGuid = (s, allowNilEmpty = false) => {
|
|
231
|
+
if (allowNilEmpty && !(0, exports.isNonEmptyString)(s))
|
|
232
|
+
return true;
|
|
233
|
+
if (!(0, exports.isNonEmptyString)(s))
|
|
234
|
+
return false;
|
|
235
|
+
const pattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
236
|
+
const cleaned = s.replace(/[{}]/g, "").toLowerCase();
|
|
237
|
+
return pattern.test(cleaned);
|
|
238
|
+
};
|
|
239
|
+
exports.isGuid = isGuid;
|
|
240
|
+
// export const isPhoneNumberAdvanced = (s: any): boolean => {
|
|
241
|
+
// if (!isNonEmptyString(s)) return false;
|
|
242
|
+
// return isValidNumber(s.trim().replace(/ /g, ""));
|
|
243
|
+
// };
|
|
244
|
+
//[E.164][1] format +16175551212
|
|
245
|
+
/**
|
|
246
|
+
* Validates if a string is a valid phone number format
|
|
247
|
+
* @param {string} value - Phone number string to validate
|
|
248
|
+
* @param {boolean} [allowNilEmpty=false] - Whether to allow null/empty values
|
|
249
|
+
* @returns {boolean} True if valid phone number format
|
|
250
|
+
* @example
|
|
251
|
+
* isPhoneNumber('(555) 123-4567') // returns true
|
|
252
|
+
* isPhoneNumber('+1 555 123 4567') // returns true
|
|
253
|
+
* isPhoneNumber('invalid') // returns false
|
|
254
|
+
*/
|
|
255
|
+
const isPhoneNumber = (value, allowNilEmpty = false) => {
|
|
256
|
+
if (allowNilEmpty && !(0, exports.isNonEmptyString)(value))
|
|
257
|
+
return true;
|
|
258
|
+
if (!(0, exports.isNonEmptyString)(value))
|
|
259
|
+
return false;
|
|
260
|
+
let cleanValue = value;
|
|
261
|
+
// Remove country code prefix if present
|
|
262
|
+
if (cleanValue.startsWith("+")) {
|
|
263
|
+
const parts = cleanValue.split(" ");
|
|
264
|
+
parts.shift(); // Remove country code
|
|
265
|
+
cleanValue = parts.join(" ");
|
|
266
|
+
}
|
|
267
|
+
// Extract only digits
|
|
268
|
+
const digits = cleanValue.match(/\d/g);
|
|
269
|
+
if (!digits)
|
|
270
|
+
return false;
|
|
271
|
+
const numericOnly = digits.join("");
|
|
272
|
+
// Validate US phone number format (10 digits)
|
|
273
|
+
const pattern = /^[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/;
|
|
274
|
+
return pattern.test(numericOnly);
|
|
275
|
+
};
|
|
276
|
+
exports.isPhoneNumber = isPhoneNumber;
|
|
277
|
+
/**
|
|
278
|
+
* Checks if a value is an empty string
|
|
279
|
+
* @param {unknown} s - Value to check
|
|
280
|
+
* @param {boolean} [trim=false] - Whether to trim whitespace before checking
|
|
281
|
+
* @returns {boolean} True if value is an empty string
|
|
282
|
+
* @example
|
|
283
|
+
* isEmptyString('') // returns true
|
|
284
|
+
* isEmptyString(' ', true) // returns true
|
|
285
|
+
* isEmptyString('hello') // returns false
|
|
286
|
+
*/
|
|
287
|
+
const isEmptyString = (s, trim = false) => {
|
|
288
|
+
if ((0, lodash_1.isNil)(s) || !(0, lodash_1.isString)(s)) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
return trim ? s.trim().length === 0 : s.length === 0;
|
|
292
|
+
};
|
|
293
|
+
exports.isEmptyString = isEmptyString;
|
|
294
|
+
/**
|
|
295
|
+
* Converts a JSON object to Base64 encoded string
|
|
296
|
+
* @param {Record<string, any>} object - Object to encode
|
|
297
|
+
* @returns {string} Base64 encoded string
|
|
298
|
+
* @throws {Error} When object cannot be serialized or Buffer is not available
|
|
299
|
+
* @example
|
|
300
|
+
* jsonToBase64({ name: 'John', age: 30 }) // returns 'eyJuYW1lIjoiSm9obiIsImFnZSI6MzB9'
|
|
301
|
+
*/
|
|
302
|
+
const jsonToBase64 = (object) => {
|
|
303
|
+
if (!object || typeof object !== 'object') {
|
|
304
|
+
throw new Error('Input must be a valid object');
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
const json = JSON.stringify(object);
|
|
308
|
+
// Check if Buffer is available (Node.js environment)
|
|
309
|
+
if (typeof Buffer !== 'undefined') {
|
|
310
|
+
return Buffer.from(json).toString('base64');
|
|
311
|
+
}
|
|
312
|
+
// Fallback for browser environment
|
|
313
|
+
if (typeof btoa !== 'undefined') {
|
|
314
|
+
return btoa(json);
|
|
315
|
+
}
|
|
316
|
+
throw new Error('Base64 encoding not available in this environment');
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
throw new Error(`Failed to encode object to Base64: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
exports.jsonToBase64 = jsonToBase64;
|
|
323
|
+
/**
|
|
324
|
+
* Converts a Base64 encoded string back to JSON object
|
|
325
|
+
* @param {string} base64 - Base64 encoded string
|
|
326
|
+
* @returns {any} Parsed JSON object
|
|
327
|
+
* @throws {Error} When base64 string is invalid or cannot be parsed
|
|
328
|
+
* @example
|
|
329
|
+
* base64ToJson('eyJuYW1lIjoiSm9obiIsImFnZSI6MzB9') // returns { name: 'John', age: 30 }
|
|
330
|
+
*/
|
|
331
|
+
const base64ToJson = (base64) => {
|
|
332
|
+
if (!(0, exports.isNonEmptyString)(base64)) {
|
|
333
|
+
throw new Error('Input must be a non-empty Base64 string');
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
let json;
|
|
337
|
+
// Check if Buffer is available (Node.js environment)
|
|
338
|
+
if (typeof Buffer !== 'undefined') {
|
|
339
|
+
json = Buffer.from(base64, 'base64').toString();
|
|
340
|
+
}
|
|
341
|
+
else if (typeof atob !== 'undefined') {
|
|
342
|
+
// Fallback for browser environment
|
|
343
|
+
json = atob(base64);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
throw new Error('Base64 decoding not available in this environment');
|
|
347
|
+
}
|
|
348
|
+
return JSON.parse(json);
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
throw new Error(`Failed to decode Base64 to JSON: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
exports.base64ToJson = base64ToJson;
|
|
355
|
+
/**
|
|
356
|
+
* Extracts specified properties from an object into a new object
|
|
357
|
+
* @param {Record<string, any> | null | undefined} obj - Source object
|
|
358
|
+
* @param {string} props - Comma-separated property names to extract
|
|
359
|
+
* @returns {Record<string, any> | undefined} New object with extracted properties
|
|
360
|
+
* @throws {Error} When props string is invalid
|
|
361
|
+
* @example
|
|
362
|
+
* getSubObject({ a: 1, b: 2, c: 3 }, 'a, b') // returns { a: 1, b: 2 }
|
|
363
|
+
* @deprecated Consider using object destructuring or lodash.pick instead
|
|
364
|
+
*/
|
|
365
|
+
const getSubObject = (obj, props) => {
|
|
366
|
+
if ((0, lodash_1.isNil)(obj))
|
|
367
|
+
return undefined;
|
|
368
|
+
if (!(0, exports.isNonEmptyString)(props)) {
|
|
369
|
+
throw new Error('Props must be a non-empty string');
|
|
370
|
+
}
|
|
371
|
+
try {
|
|
372
|
+
// Safer alternative to eval - manually parse and extract properties
|
|
373
|
+
const propNames = props.split(',').map(p => p.trim()).filter(p => p.length > 0);
|
|
374
|
+
const result = {};
|
|
375
|
+
for (const propName of propNames) {
|
|
376
|
+
if (propName in obj) {
|
|
377
|
+
result[propName] = obj[propName];
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return result;
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
throw new Error(`Failed to extract properties: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
exports.getSubObject = getSubObject;
|
|
387
|
+
/**
|
|
388
|
+
* Calculates the time difference between two dates
|
|
389
|
+
* @param {Date} d1 - First date (later date for positive result)
|
|
390
|
+
* @param {Date} d2 - Second date (earlier date for positive result)
|
|
391
|
+
* @param {string} type - Unit of time difference (second, minute, hour)
|
|
392
|
+
* @returns {number} Time difference in specified units
|
|
393
|
+
* @throws {Error} When dates are invalid
|
|
394
|
+
* @example
|
|
395
|
+
* timeDiff(new Date('2023-01-02'), new Date('2023-01-01'), 'hour') // returns 24
|
|
396
|
+
* timeDiff(new Date('2023-01-01 12:30'), new Date('2023-01-01 12:00'), 'minute') // returns 30
|
|
397
|
+
*/
|
|
398
|
+
const timeDiff = (d1, d2, type) => {
|
|
399
|
+
if (!(d1 instanceof Date) || !(d2 instanceof Date)) {
|
|
400
|
+
throw new Error('Both parameters must be valid Date objects');
|
|
401
|
+
}
|
|
402
|
+
if ((0, lodash_1.isNaN)(d1.getTime()) || (0, lodash_1.isNaN)(d2.getTime())) {
|
|
403
|
+
throw new Error('Both dates must be valid');
|
|
404
|
+
}
|
|
405
|
+
const diffT = d1.getTime() - d2.getTime();
|
|
406
|
+
if (type === "second" || type === "sec" || type === "s") {
|
|
407
|
+
return Math.floor(diffT / 1000);
|
|
408
|
+
}
|
|
409
|
+
if (type === "minute" || type === "min" || type === "m") {
|
|
410
|
+
return Math.floor(diffT / 1000 / 60);
|
|
411
|
+
}
|
|
412
|
+
if (type === "hour" || type === "hr" || type === "h") {
|
|
413
|
+
return Math.floor(diffT / 1000 / 60 / 60);
|
|
414
|
+
}
|
|
415
|
+
// Default: return milliseconds
|
|
416
|
+
return diffT;
|
|
417
|
+
};
|
|
418
|
+
exports.timeDiff = timeDiff;
|
|
419
|
+
/**
|
|
420
|
+
* Formats a date into a string with customizable delimiter and parts
|
|
421
|
+
* @param {Date} [dt] - Date to format (defaults to current date)
|
|
422
|
+
* @param {string} [delimiter="-"] - Character to use as delimiter
|
|
423
|
+
* @param {string} [part="full"] - Which part of the date to return
|
|
424
|
+
* @returns {string} Formatted date string
|
|
425
|
+
* @example
|
|
426
|
+
* getDateTimeString() // returns "2023-01-01-12-30-45-123"
|
|
427
|
+
* getDateTimeString(new Date(), "_", "date") // returns "2023_01_01"
|
|
428
|
+
*/
|
|
429
|
+
const getDateTimeString = (dt, delimiter = "-", part = "full") => {
|
|
430
|
+
const date = dt || new Date();
|
|
431
|
+
if (!(date instanceof Date) || (0, lodash_1.isNaN)(date.getTime())) {
|
|
432
|
+
throw new Error('Invalid date provided');
|
|
433
|
+
}
|
|
434
|
+
let formatted = date
|
|
435
|
+
.toISOString()
|
|
436
|
+
.replace("T", "-")
|
|
437
|
+
.replace(/:/g, "-")
|
|
438
|
+
.replace("Z", "")
|
|
439
|
+
.replace(/\./g, "-");
|
|
440
|
+
const parts = formatted.split("-");
|
|
441
|
+
switch (part) {
|
|
442
|
+
case "date":
|
|
443
|
+
formatted = `${parts[0]}-${parts[1]}-${parts[2]}`;
|
|
444
|
+
break;
|
|
445
|
+
case "time":
|
|
446
|
+
formatted = `${parts[3]}-${parts[4]}-${parts[5]}`;
|
|
447
|
+
break;
|
|
448
|
+
case "ms":
|
|
449
|
+
formatted = parts[6] || "000";
|
|
450
|
+
break;
|
|
451
|
+
default:
|
|
452
|
+
// Keep full format
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
return delimiter === "-" ? formatted : formatted.replace(/-/g, delimiter);
|
|
456
|
+
};
|
|
457
|
+
exports.getDateTimeString = getDateTimeString;
|
|
458
|
+
/**
|
|
459
|
+
* Generates a unique serial number based on current timestamp
|
|
460
|
+
* @returns {string} Generated serial number
|
|
461
|
+
* @example
|
|
462
|
+
* serialNumber() // returns "20230101123045123456"
|
|
463
|
+
*/
|
|
464
|
+
const serialNumber = () => {
|
|
465
|
+
const now = new Date();
|
|
466
|
+
const utcTime = new Date(now.getTime() + now.getTimezoneOffset() * 60000);
|
|
467
|
+
let timeString = utcTime.toISOString()
|
|
468
|
+
.replace(/-/g, "")
|
|
469
|
+
.replace(/:/g, "")
|
|
470
|
+
.replace("Z", "")
|
|
471
|
+
.replace("T", "")
|
|
472
|
+
.replace(/\./g, "");
|
|
473
|
+
const chars = timeString.substring(1).split("");
|
|
474
|
+
let result = "";
|
|
475
|
+
let index = 0;
|
|
476
|
+
while (index < chars.length) {
|
|
477
|
+
const current = parseInt(chars[index]);
|
|
478
|
+
const next = index < chars.length - 1 ? parseInt(chars[index + 1]) : 0;
|
|
479
|
+
const combined = current * 10 + next;
|
|
480
|
+
if (combined <= 9) {
|
|
481
|
+
result += current.toString();
|
|
482
|
+
index += 1;
|
|
483
|
+
}
|
|
484
|
+
else if (combined >= 10 && combined < 36) {
|
|
485
|
+
result += String.fromCharCode("a".charCodeAt(0) + combined - 10);
|
|
486
|
+
index += 2;
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
result += current.toString();
|
|
490
|
+
index += 1;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return result;
|
|
494
|
+
};
|
|
495
|
+
exports.serialNumber = serialNumber;
|
|
496
|
+
/**
|
|
497
|
+
* Calculates a TTL (Time To Live) timestamp in seconds
|
|
498
|
+
* @param {number} [mins=60] - Minutes to add to current time
|
|
499
|
+
* @returns {number} Unix timestamp in seconds
|
|
500
|
+
* @example
|
|
501
|
+
* ttl(30) // returns current timestamp + 30 minutes in seconds
|
|
502
|
+
* ttl() // returns current timestamp + 60 minutes in seconds
|
|
503
|
+
*/
|
|
504
|
+
const ttl = (mins = 60) => {
|
|
505
|
+
if (!(0, lodash_1.isNumber)(mins) || mins < 0) {
|
|
506
|
+
mins = 60;
|
|
507
|
+
}
|
|
508
|
+
const nowInSeconds = Math.floor(Date.now() / 1000);
|
|
509
|
+
return nowInSeconds + mins * 60;
|
|
510
|
+
};
|
|
511
|
+
exports.ttl = ttl;
|
|
512
|
+
const checkToTrue = (js, props) => {
|
|
513
|
+
if (!(0, lodash_1.isObject)(props))
|
|
514
|
+
props = {};
|
|
515
|
+
try {
|
|
516
|
+
const func = (0, lodash_1.isFunction)(props.jsEvalFunction)
|
|
517
|
+
? props.jsEvalFunction(js)
|
|
518
|
+
: null;
|
|
519
|
+
if (!(0, lodash_1.isFunction)(func)) {
|
|
520
|
+
if (func)
|
|
521
|
+
return true;
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
if (func(props))
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
catch (ex) {
|
|
529
|
+
console.error("Error when evaluating checkToTrue", { ex, js });
|
|
530
|
+
}
|
|
531
|
+
return false;
|
|
532
|
+
};
|
|
533
|
+
exports.checkToTrue = checkToTrue;
|
|
534
|
+
const isEmail = (s, allowNilEmpty) => {
|
|
535
|
+
if (allowNilEmpty && !(0, exports.isNonEmptyString)(s))
|
|
536
|
+
return true;
|
|
537
|
+
let email = s ?? "";
|
|
538
|
+
if (email.indexOf(" ") >= 0)
|
|
539
|
+
return false;
|
|
540
|
+
if ((0, exports.isNonEmptyString)(email))
|
|
541
|
+
email = email.trim().replace(/[+]/g, "");
|
|
542
|
+
const pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
|
|
543
|
+
return pattern.test(email);
|
|
544
|
+
};
|
|
545
|
+
exports.isEmail = isEmail;
|
|
546
|
+
const isPassword = (s, settings) => {
|
|
547
|
+
if (!(0, lodash_1.isObject)(settings))
|
|
548
|
+
settings = {};
|
|
549
|
+
const needLowerCaseLetter = settings.needLowerCaseLetter ??
|
|
550
|
+
constants_1.DEFAULT_PASSWORD_RULE.needLowerCaseLetter;
|
|
551
|
+
const needUpperCaseLetter = settings.needUpperCaseLetter ??
|
|
552
|
+
constants_1.DEFAULT_PASSWORD_RULE.needUpperCaseLetter;
|
|
553
|
+
const needDigit = settings.needDigit ?? constants_1.DEFAULT_PASSWORD_RULE.needDigit;
|
|
554
|
+
const needSpecialChar = settings.needSpecialChar ?? constants_1.DEFAULT_PASSWORD_RULE.needSpecialChar;
|
|
555
|
+
const allowNilEmpty = settings.allowNilEmpty;
|
|
556
|
+
if (allowNilEmpty && !(0, exports.isNonEmptyString)(s))
|
|
557
|
+
return true;
|
|
558
|
+
let v = s ?? "";
|
|
559
|
+
const minLen = settings.minLen && settings.minLen > 5 ? settings.minLen : 8;
|
|
560
|
+
if ((0, exports.isNonEmptyString)(v))
|
|
561
|
+
v = v.trim().replace(/ /g, "");
|
|
562
|
+
if (v.length < minLen)
|
|
563
|
+
return false;
|
|
564
|
+
let result = true;
|
|
565
|
+
if (needDigit) {
|
|
566
|
+
result = new RegExp(/^(?=.*[\d])[\w!\-@#$%.^&*]+$/).test(v);
|
|
567
|
+
if (!result)
|
|
568
|
+
console.log("Password does not contain digit.");
|
|
569
|
+
}
|
|
570
|
+
if (result && needUpperCaseLetter) {
|
|
571
|
+
result = new RegExp(/^(?=.*[A-Z])[\w!\-@#$%.^&*]+$/).test(v);
|
|
572
|
+
if (!result)
|
|
573
|
+
console.log("Password does not contain uppercase letter.");
|
|
574
|
+
}
|
|
575
|
+
if (result && needLowerCaseLetter) {
|
|
576
|
+
result = new RegExp(/^(?=.*[a-z])[\w!\-@#$%.^&*]+$/).test(v);
|
|
577
|
+
if (!result)
|
|
578
|
+
console.log("Password does not contain lowercase letter.");
|
|
579
|
+
}
|
|
580
|
+
if (result && needSpecialChar) {
|
|
581
|
+
result = new RegExp(/^(?=.*[!\-@#$%?:;~=`"',_<>(){}\.\/\]\[\\\|\+^&*])[\w?=.*[!\-@#$%?:;~=`"',_<>(){}\.\/\]\[\\\|\+^&*]+$/).test(v);
|
|
582
|
+
if (!result)
|
|
583
|
+
console.log("Password does not contain special character.");
|
|
584
|
+
}
|
|
585
|
+
return result;
|
|
586
|
+
};
|
|
587
|
+
exports.isPassword = isPassword;
|
|
588
|
+
const getTimestamp = (dt) => {
|
|
589
|
+
return dt ? new Date(dt).getTime() : new Date().getTime();
|
|
590
|
+
};
|
|
591
|
+
exports.getTimestamp = getTimestamp;
|
|
592
|
+
const getMaxTimestamp = () => {
|
|
593
|
+
return new Date("9999-12-31T23:59:59.999Z").getTime();
|
|
594
|
+
};
|
|
595
|
+
exports.getMaxTimestamp = getMaxTimestamp;
|
|
596
|
+
const getUTCISOString = (dt, minutesDiff) => {
|
|
597
|
+
if (!dt)
|
|
598
|
+
dt = new Date();
|
|
599
|
+
if (minutesDiff === undefined)
|
|
600
|
+
minutesDiff = 0;
|
|
601
|
+
if ((0, lodash_1.isNumber)(minutesDiff))
|
|
602
|
+
dt.setMinutes(dt.getMinutes() + minutesDiff);
|
|
603
|
+
return dt.toISOString();
|
|
604
|
+
};
|
|
605
|
+
exports.getUTCISOString = getUTCISOString;
|
|
606
|
+
const getUTCMaxISOString = () => {
|
|
607
|
+
return (0, exports.getUTCISOString)(new Date("9999-12-31T23:59:59.999Z"), 0);
|
|
608
|
+
};
|
|
609
|
+
exports.getUTCMaxISOString = getUTCMaxISOString;
|
|
610
|
+
const formatString = (...args) => {
|
|
611
|
+
if (args.length == 0)
|
|
612
|
+
return null;
|
|
613
|
+
let s = args[0];
|
|
614
|
+
for (let i = 1; i < args.length; i++) {
|
|
615
|
+
s = s.replace(/\{0\}/g, args[i]);
|
|
616
|
+
}
|
|
617
|
+
return s;
|
|
618
|
+
};
|
|
619
|
+
exports.formatString = formatString;
|
|
620
|
+
const shortenString = (s, l) => {
|
|
621
|
+
return s.length <= l ? s : `${s.substring(0, l)} ...`;
|
|
622
|
+
};
|
|
623
|
+
exports.shortenString = shortenString;
|
|
624
|
+
//the isObject from lodash will cause error from typescript
|
|
625
|
+
//this one will not
|
|
626
|
+
const isObject = (v) => {
|
|
627
|
+
return (0, lodash_1.isObject)(v) ? true : false;
|
|
628
|
+
};
|
|
629
|
+
exports.isObject = isObject;
|
|
630
|
+
const isObjectString = (s) => {
|
|
631
|
+
try {
|
|
632
|
+
JSON.parse(s);
|
|
633
|
+
return true;
|
|
634
|
+
}
|
|
635
|
+
catch {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
exports.isObjectString = isObjectString;
|
|
640
|
+
const removeNoValueProperty = (data, removeEmptyString) => {
|
|
641
|
+
if ((0, lodash_1.isArray)(data)) {
|
|
642
|
+
return (0, lodash_1.without)((0, lodash_1.map)(data, (r) => {
|
|
643
|
+
return r === undefined ||
|
|
644
|
+
r === null ||
|
|
645
|
+
(r === "" && removeEmptyString)
|
|
646
|
+
? null
|
|
647
|
+
: (0, lodash_1.isObject)(r)
|
|
648
|
+
? (0, exports.removeNoValueProperty)(r, removeEmptyString)
|
|
649
|
+
: r;
|
|
650
|
+
}), null);
|
|
651
|
+
}
|
|
652
|
+
for (const p in data) {
|
|
653
|
+
const v = data[p];
|
|
654
|
+
if (v === undefined || v === null || (v === "" && removeEmptyString)) {
|
|
655
|
+
delete data[p];
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
if ((0, lodash_1.isArray)(v)) {
|
|
659
|
+
data[p] = (0, lodash_1.without)((0, lodash_1.map)(v, (r) => {
|
|
660
|
+
return r === undefined ||
|
|
661
|
+
r === null ||
|
|
662
|
+
(r === "" && removeEmptyString)
|
|
663
|
+
? null
|
|
664
|
+
: (0, lodash_1.isObject)(r)
|
|
665
|
+
? (0, exports.removeNoValueProperty)(r, removeEmptyString)
|
|
666
|
+
: r;
|
|
667
|
+
}), null);
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
if ((0, lodash_1.isObject)(v)) {
|
|
671
|
+
data[p] = (0, exports.removeNoValueProperty)(v, removeEmptyString);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return data;
|
|
677
|
+
};
|
|
678
|
+
exports.removeNoValueProperty = removeNoValueProperty;
|
|
679
|
+
const groupItems = (data, groups, propNameForItemGroup, propNameForItemSort) => {
|
|
680
|
+
if (!((0, lodash_1.isArray)(data) && data.length > 0))
|
|
681
|
+
return [];
|
|
682
|
+
propNameForItemGroup = propNameForItemGroup
|
|
683
|
+
? propNameForItemGroup
|
|
684
|
+
: "group";
|
|
685
|
+
propNameForItemSort = propNameForItemSort
|
|
686
|
+
? propNameForItemSort
|
|
687
|
+
: "fullName";
|
|
688
|
+
const result = (0, lodash_1.map)(groups, (group) => {
|
|
689
|
+
return {
|
|
690
|
+
...group,
|
|
691
|
+
data: (0, lodash_1.sortBy)((0, lodash_1.without)((0, lodash_1.map)(data, (item) => {
|
|
692
|
+
return propNameForItemGroup &&
|
|
693
|
+
item[propNameForItemGroup] == group.id
|
|
694
|
+
? item
|
|
695
|
+
: null;
|
|
696
|
+
}), null), (item) => {
|
|
697
|
+
return propNameForItemSort && item[propNameForItemSort];
|
|
698
|
+
})
|
|
699
|
+
};
|
|
700
|
+
});
|
|
701
|
+
return result;
|
|
702
|
+
};
|
|
703
|
+
exports.groupItems = groupItems;
|
|
704
|
+
const shortenNumber = (num, fractionDigits) => {
|
|
705
|
+
if (!(0, lodash_1.isNumber)(fractionDigits) ||
|
|
706
|
+
((0, lodash_1.isNumber)(fractionDigits) && fractionDigits < 0))
|
|
707
|
+
fractionDigits = 1;
|
|
708
|
+
const lookup = [
|
|
709
|
+
{ value: 1, symbol: "" },
|
|
710
|
+
{ value: 1e3, symbol: "K" },
|
|
711
|
+
{ value: 1e6, symbol: "M" },
|
|
712
|
+
{ value: 1e9, symbol: "G" },
|
|
713
|
+
{ value: 1e12, symbol: "T" },
|
|
714
|
+
{ value: 1e15, symbol: "P" },
|
|
715
|
+
{ value: 1e18, symbol: "E" }
|
|
716
|
+
];
|
|
717
|
+
//const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
|
|
718
|
+
const item = lookup
|
|
719
|
+
.slice()
|
|
720
|
+
.reverse()
|
|
721
|
+
.find(function (item) {
|
|
722
|
+
return num >= item.value;
|
|
723
|
+
});
|
|
724
|
+
return item
|
|
725
|
+
? item && (num / item.value).toFixed(fractionDigits) + item.symbol
|
|
726
|
+
: "0";
|
|
727
|
+
};
|
|
728
|
+
exports.shortenNumber = shortenNumber;
|
|
729
|
+
const formatNumberBMK = (v) => {
|
|
730
|
+
if (!(0, lodash_1.isNumber)(v) || !v)
|
|
731
|
+
return "";
|
|
732
|
+
if (v > 1000000000)
|
|
733
|
+
return `${(0, exports.numberWithCommas)(Math.round(v / 100000000) / 10)}B`;
|
|
734
|
+
if (v > 1000000)
|
|
735
|
+
return `${(0, exports.numberWithCommas)(Math.round(v / 100000) / 10)}M`;
|
|
736
|
+
if (v > 1000)
|
|
737
|
+
return `${(0, exports.numberWithCommas)(Math.round(v / 100) / 10)}K`;
|
|
738
|
+
return `${v}`;
|
|
739
|
+
};
|
|
740
|
+
exports.formatNumberBMK = formatNumberBMK;
|
|
741
|
+
const numberWithCommas = (x) => {
|
|
742
|
+
if (!(0, lodash_1.isNumber)(x) && !((0, lodash_1.isString)(x) && x.length > 0))
|
|
743
|
+
return null;
|
|
744
|
+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
745
|
+
};
|
|
746
|
+
exports.numberWithCommas = numberWithCommas;
|
|
747
|
+
const formatText = (text, format) => {
|
|
748
|
+
switch (format) {
|
|
749
|
+
case "lower":
|
|
750
|
+
return text.toLowerCase();
|
|
751
|
+
case "upper":
|
|
752
|
+
return text.toUpperCase();
|
|
753
|
+
case "capital":
|
|
754
|
+
case "capital-first":
|
|
755
|
+
return (0, lodash_1.capitalize)(text);
|
|
756
|
+
case "capital-all":
|
|
757
|
+
return (0, lodash_1.map)(text.split(" "), lodash_1.capitalize).join(" ");
|
|
758
|
+
case "initials":
|
|
759
|
+
return (0, lodash_1.map)(text.split(" "), (t) => t.length > 0 ? t.charAt(0) : "").join(" ");
|
|
760
|
+
case "camel":
|
|
761
|
+
return (0, lodash_1.camelCase)(text);
|
|
762
|
+
default:
|
|
763
|
+
return text;
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
exports.formatText = formatText;
|
|
767
|
+
const readableFileSize = (fileSizeInBytes) => {
|
|
768
|
+
if (!(0, lodash_1.isNumber)(fileSizeInBytes))
|
|
769
|
+
return "";
|
|
770
|
+
let i = -1;
|
|
771
|
+
const byteUnits = [" KB", " MB", " GB", " TB", "PB", "EB", "ZB", "YB"];
|
|
772
|
+
do {
|
|
773
|
+
fileSizeInBytes = fileSizeInBytes / 1024;
|
|
774
|
+
i++;
|
|
775
|
+
} while (fileSizeInBytes > 1024);
|
|
776
|
+
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
|
|
777
|
+
};
|
|
778
|
+
exports.readableFileSize = readableFileSize;
|
|
779
|
+
const formatJSONString = (c) => {
|
|
780
|
+
const jsonValue = (0, exports.isNonEmptyString)(c) ? JSON.parse(c) : c;
|
|
781
|
+
try {
|
|
782
|
+
return JSON.stringify(jsonValue, null, 4);
|
|
783
|
+
}
|
|
784
|
+
catch (ex) {
|
|
785
|
+
//console.log({ v, ex })
|
|
786
|
+
}
|
|
787
|
+
return JSON.stringify(jsonValue);
|
|
788
|
+
};
|
|
789
|
+
exports.formatJSONString = formatJSONString;
|
|
790
|
+
const deepFlatten = (array) => {
|
|
791
|
+
let result = [];
|
|
792
|
+
array.forEach(function (elem) {
|
|
793
|
+
if (Array.isArray(elem)) {
|
|
794
|
+
result = result.concat((0, exports.deepFlatten)(elem));
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
result.push(elem);
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
return result;
|
|
801
|
+
};
|
|
802
|
+
exports.deepFlatten = deepFlatten;
|
|
803
|
+
const findCountry = (codeOrName, resultFormat) => {
|
|
804
|
+
const country = (0, lodash_1.find)(constants_1.COUNTRIES, (c) => {
|
|
805
|
+
return (c.name.toLocaleLowerCase() == codeOrName.toLowerCase() ||
|
|
806
|
+
c.code.toLocaleLowerCase() == codeOrName.toLowerCase() ||
|
|
807
|
+
c.code3.toLocaleLowerCase() == codeOrName.toLowerCase());
|
|
808
|
+
});
|
|
809
|
+
if (!country)
|
|
810
|
+
return undefined;
|
|
811
|
+
switch (resultFormat) {
|
|
812
|
+
case "PicklistOption": {
|
|
813
|
+
return {
|
|
814
|
+
text: country?.name,
|
|
815
|
+
value: country?.code
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
default: {
|
|
819
|
+
return country;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
};
|
|
823
|
+
exports.findCountry = findCountry;
|
|
824
|
+
const findGender = (textOrValue) => {
|
|
825
|
+
return (0, lodash_1.find)(constants_1.GENDERS, (c) => {
|
|
826
|
+
return (c.text.toLowerCase() == textOrValue.toLowerCase() ||
|
|
827
|
+
c.value.toLowerCase() == textOrValue.toLowerCase());
|
|
828
|
+
});
|
|
829
|
+
};
|
|
830
|
+
exports.findGender = findGender;
|
|
831
|
+
const findLanguage = (codeOrName, resultFormat) => {
|
|
832
|
+
const language = (0, lodash_1.find)(constants_1.LANGUAGES, (c) => {
|
|
833
|
+
let found = c.name.toLowerCase() == codeOrName.trim().toLowerCase() ||
|
|
834
|
+
c.code.toLowerCase() == codeOrName.trim().toLowerCase();
|
|
835
|
+
if (!found) {
|
|
836
|
+
const names = c.name.split(",");
|
|
837
|
+
found =
|
|
838
|
+
names.length > 1 &&
|
|
839
|
+
!(0, lodash_1.isNil)((0, lodash_1.find)(names, (name) => {
|
|
840
|
+
return (name.trim().toLowerCase() ==
|
|
841
|
+
codeOrName.trim().toLowerCase());
|
|
842
|
+
}));
|
|
843
|
+
}
|
|
844
|
+
return found;
|
|
845
|
+
});
|
|
846
|
+
if (!language)
|
|
847
|
+
return undefined;
|
|
848
|
+
switch (resultFormat) {
|
|
849
|
+
case "PicklistOption": {
|
|
850
|
+
return {
|
|
851
|
+
text: language?.name,
|
|
852
|
+
value: language?.code
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
default: {
|
|
856
|
+
return language;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
exports.findLanguage = findLanguage;
|
|
861
|
+
const getCache = (key, defaultValue) => {
|
|
862
|
+
if (!(0, exports.isNonEmptyString)(key))
|
|
863
|
+
return undefined;
|
|
864
|
+
const g = (0, exports.getGlobalObject)();
|
|
865
|
+
if (!(0, exports.isObject)(g.localCache))
|
|
866
|
+
g.localCache = {};
|
|
867
|
+
const cacheData = g.localCache[key];
|
|
868
|
+
if ((0, lodash_1.isNil)(cacheData))
|
|
869
|
+
return defaultValue;
|
|
870
|
+
const { data, ttl } = cacheData;
|
|
871
|
+
if ((0, lodash_1.isInteger)(ttl) && Date.now() > data.ttl * 1000) {
|
|
872
|
+
(0, exports.removeCache)(key);
|
|
873
|
+
return !(0, lodash_1.isNil)(defaultValue) ? defaultValue : undefined;
|
|
874
|
+
}
|
|
875
|
+
return !(0, lodash_1.isNil)(data)
|
|
876
|
+
? data
|
|
877
|
+
: !(0, lodash_1.isNil)(defaultValue)
|
|
878
|
+
? defaultValue
|
|
879
|
+
: undefined;
|
|
880
|
+
};
|
|
881
|
+
exports.getCache = getCache;
|
|
882
|
+
const setCache = (key, data, expireMinutes) => {
|
|
883
|
+
const g = (0, exports.getGlobalObject)();
|
|
884
|
+
if (!(0, exports.isNonEmptyString)(key))
|
|
885
|
+
return;
|
|
886
|
+
if (!(0, exports.isObject)(g.localCache))
|
|
887
|
+
g.localCache = {};
|
|
888
|
+
if ((0, lodash_1.isNil)(data))
|
|
889
|
+
return (0, exports.removeCache)(key);
|
|
890
|
+
if (!(0, lodash_1.isNil)(expireMinutes) &&
|
|
891
|
+
(0, lodash_1.isInteger)(expireMinutes) &&
|
|
892
|
+
expireMinutes > 0) {
|
|
893
|
+
g.localCache[key] = {
|
|
894
|
+
data,
|
|
895
|
+
ttl: (0, exports.ttl)(expireMinutes)
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
g.localCache[key] = { data };
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
exports.setCache = setCache;
|
|
903
|
+
const removeCache = (key) => {
|
|
904
|
+
const g = (0, exports.getGlobalObject)();
|
|
905
|
+
if (!(0, exports.isObject)(g.localCache))
|
|
906
|
+
g.localCache = {};
|
|
907
|
+
delete g.localCache[key];
|
|
908
|
+
};
|
|
909
|
+
exports.removeCache = removeCache;
|
|
910
|
+
const resetCacheByGroupId = (groupId) => {
|
|
911
|
+
(0, exports.removeCache)(groupId);
|
|
912
|
+
};
|
|
913
|
+
exports.resetCacheByGroupId = resetCacheByGroupId;
|
|
914
|
+
const setCacheByGroupId = (groupId, key, value) => {
|
|
915
|
+
const groupCache = (0, exports.getCache)(groupId) ?? {};
|
|
916
|
+
groupCache[key] = value;
|
|
917
|
+
(0, exports.setCache)(groupId, groupCache);
|
|
918
|
+
};
|
|
919
|
+
exports.setCacheByGroupId = setCacheByGroupId;
|
|
920
|
+
const getCacheByGroupId = (groupId, key) => {
|
|
921
|
+
const groupCache = (0, exports.getCache)(groupId) ?? {};
|
|
922
|
+
return groupCache[key];
|
|
923
|
+
};
|
|
924
|
+
exports.getCacheByGroupId = getCacheByGroupId;
|
|
925
|
+
const removeCacheByGroupId = (groupId, key) => {
|
|
926
|
+
const groupCache = (0, exports.getCache)(groupId) ?? {};
|
|
927
|
+
delete groupCache[key];
|
|
928
|
+
(0, exports.setCache)(groupId, groupCache);
|
|
929
|
+
};
|
|
930
|
+
exports.removeCacheByGroupId = removeCacheByGroupId;
|
|
931
|
+
const cleanGuid = (v) => {
|
|
932
|
+
return !v
|
|
933
|
+
? ""
|
|
934
|
+
: (v + "")
|
|
935
|
+
.replace("{", "")
|
|
936
|
+
.replace("}", "")
|
|
937
|
+
.replace(/_/g, "-")
|
|
938
|
+
.trim()
|
|
939
|
+
.toLowerCase();
|
|
940
|
+
};
|
|
941
|
+
exports.cleanGuid = cleanGuid;
|
|
942
|
+
const sameGuid = (a, b) => {
|
|
943
|
+
return (0, exports.cleanGuid)(a) === (0, exports.cleanGuid)(b);
|
|
944
|
+
};
|
|
945
|
+
exports.sameGuid = sameGuid;
|
|
946
|
+
const isEmptyGuid = (v) => {
|
|
947
|
+
return (0, exports.sameGuid)(v, constants_1.GUID_EMPTY);
|
|
948
|
+
};
|
|
949
|
+
exports.isEmptyGuid = isEmptyGuid;
|
|
950
|
+
const convertEnumToArray = (thisEnum) => {
|
|
951
|
+
let result = [];
|
|
952
|
+
let i = Object.keys(thisEnum).length / 2;
|
|
953
|
+
for (let key in thisEnum) {
|
|
954
|
+
i--;
|
|
955
|
+
if (i < 0)
|
|
956
|
+
result.push({ key, value: thisEnum[key] });
|
|
957
|
+
}
|
|
958
|
+
return result;
|
|
959
|
+
};
|
|
960
|
+
exports.convertEnumToArray = convertEnumToArray;
|
|
961
|
+
const isNumberString = (s, allowNilEmpty) => {
|
|
962
|
+
if (allowNilEmpty && !(0, exports.isNonEmptyString)(s))
|
|
963
|
+
return true;
|
|
964
|
+
const v = s ?? "";
|
|
965
|
+
return (!(0, lodash_1.isNaN)(v) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
|
|
966
|
+
!(0, lodash_1.isNaN)(parseFloat(v)) // ...and ensure strings of whitespace fail
|
|
967
|
+
);
|
|
968
|
+
};
|
|
969
|
+
exports.isNumberString = isNumberString;
|
|
970
|
+
const isBooleanString = (s, allowNilEmpty) => {
|
|
971
|
+
if (allowNilEmpty && !(0, exports.isNonEmptyString)(s))
|
|
972
|
+
return true;
|
|
973
|
+
const v = s ?? "";
|
|
974
|
+
return v.toLowerCase() == "true" || v.toLowerCase() == "false";
|
|
975
|
+
};
|
|
976
|
+
exports.isBooleanString = isBooleanString;
|
|
977
|
+
const isIntegerString = (s, allowNilEmpty) => {
|
|
978
|
+
if (allowNilEmpty && !(0, exports.isNonEmptyString)(s))
|
|
979
|
+
return true;
|
|
980
|
+
if (!(0, exports.isNumberString)(s, allowNilEmpty))
|
|
981
|
+
return false;
|
|
982
|
+
const v = s ?? "";
|
|
983
|
+
return !(0, lodash_1.isNaN)(parseInt(v)) && /^-?\d+?$/.test(v);
|
|
984
|
+
};
|
|
985
|
+
exports.isIntegerString = isIntegerString;
|
|
986
|
+
const isFloatString = (s, allowNilEmpty) => {
|
|
987
|
+
if (allowNilEmpty && !(0, exports.isNonEmptyString)(s))
|
|
988
|
+
return true;
|
|
989
|
+
if (!(0, exports.isNumberString)(s, allowNilEmpty))
|
|
990
|
+
return false;
|
|
991
|
+
const v = s ?? "";
|
|
992
|
+
return !(0, lodash_1.isNaN)(parseFloat(v)) && /^-?\d+(?:[.]\d*?)?$/.test(v);
|
|
993
|
+
};
|
|
994
|
+
exports.isFloatString = isFloatString;
|
|
995
|
+
const getFirstDayOfTheWeek = (ts, setToFirstSecond) => {
|
|
996
|
+
const dt = new Date(ts);
|
|
997
|
+
dt.setDate(dt.getDate() - dt.getDay());
|
|
998
|
+
if (setToFirstSecond) {
|
|
999
|
+
dt.setHours(0, 0, 0, 0);
|
|
1000
|
+
}
|
|
1001
|
+
return dt.getTime();
|
|
1002
|
+
};
|
|
1003
|
+
exports.getFirstDayOfTheWeek = getFirstDayOfTheWeek;
|
|
1004
|
+
const getLastDayOfTheWeek = (ts, setToLastSecond) => {
|
|
1005
|
+
const dt = new Date(ts);
|
|
1006
|
+
dt.setDate(dt.getDate() + 6 - dt.getDay());
|
|
1007
|
+
if (setToLastSecond) {
|
|
1008
|
+
dt.setHours(23, 59, 59, 59);
|
|
1009
|
+
}
|
|
1010
|
+
return dt.getTime();
|
|
1011
|
+
};
|
|
1012
|
+
exports.getLastDayOfTheWeek = getLastDayOfTheWeek;
|
|
1013
|
+
const trimNewLine = (content) => {
|
|
1014
|
+
const chars = content.split("");
|
|
1015
|
+
while (chars[0] == "\n") {
|
|
1016
|
+
chars.shift();
|
|
1017
|
+
}
|
|
1018
|
+
while (chars[chars.length - 1] == "\n") {
|
|
1019
|
+
chars.pop();
|
|
1020
|
+
}
|
|
1021
|
+
return chars.join("");
|
|
1022
|
+
};
|
|
1023
|
+
exports.trimNewLine = trimNewLine;
|
|
1024
|
+
const convertToOneParagraph = (content) => {
|
|
1025
|
+
return (0, exports.trimNewLine)(content)
|
|
1026
|
+
.replace(new RegExp(`(\n){2,}`, "g"), "\n")
|
|
1027
|
+
.replace(/\n/g, " ")
|
|
1028
|
+
.replace(new RegExp(`( ){2,}`, "g"), " ")
|
|
1029
|
+
.trim();
|
|
1030
|
+
};
|
|
1031
|
+
exports.convertToOneParagraph = convertToOneParagraph;
|
|
1032
|
+
/**
|
|
1033
|
+
* Calculates surcharge amount based on configuration
|
|
1034
|
+
* @param {number} value - Base value to calculate surcharge on
|
|
1035
|
+
* @param {ISurcharge} surcharge - Surcharge configuration
|
|
1036
|
+
* @returns {number} Calculated surcharge amount
|
|
1037
|
+
* @throws {Error} When value is negative or surcharge config is invalid
|
|
1038
|
+
* @example
|
|
1039
|
+
* calculateSurcharge(100, { type: 'percentage', value: 10 }) // returns 10
|
|
1040
|
+
* calculateSurcharge(100, { type: 'number', value: 5 }) // returns 5
|
|
1041
|
+
*/
|
|
1042
|
+
const calculateSurcharge = (value, surcharge) => {
|
|
1043
|
+
if (typeof value !== 'number' || value < 0) {
|
|
1044
|
+
throw new Error('Value must be a non-negative number');
|
|
1045
|
+
}
|
|
1046
|
+
if (!surcharge || typeof surcharge.value !== 'number' || surcharge.value < 0) {
|
|
1047
|
+
throw new Error('Invalid surcharge configuration');
|
|
1048
|
+
}
|
|
1049
|
+
if (!['percentage', 'number'].includes(surcharge.type)) {
|
|
1050
|
+
throw new Error('Surcharge type must be "percentage" or "number"');
|
|
1051
|
+
}
|
|
1052
|
+
return surcharge.type === "percentage"
|
|
1053
|
+
? value * surcharge.value * 0.01
|
|
1054
|
+
: surcharge.value;
|
|
1055
|
+
};
|
|
1056
|
+
exports.calculateSurcharge = calculateSurcharge;
|
|
1057
|
+
const generateBatchArray = (list, size, func) => {
|
|
1058
|
+
const result = [];
|
|
1059
|
+
const items = (0, lodash_1.map)(list, (c) => {
|
|
1060
|
+
return func ? func(c) : c;
|
|
1061
|
+
});
|
|
1062
|
+
for (let i = 0; i < items.length; i += size) {
|
|
1063
|
+
const batch = items.slice(i, i + size);
|
|
1064
|
+
result.push(batch);
|
|
1065
|
+
}
|
|
1066
|
+
return result;
|
|
1067
|
+
};
|
|
1068
|
+
exports.generateBatchArray = generateBatchArray;
|
|
1069
|
+
const parseString = (input) => {
|
|
1070
|
+
// Check if the input is a boolean
|
|
1071
|
+
if (input.toLowerCase() === "true") {
|
|
1072
|
+
return true;
|
|
1073
|
+
}
|
|
1074
|
+
else if (input.toLowerCase() === "false") {
|
|
1075
|
+
return false;
|
|
1076
|
+
}
|
|
1077
|
+
// Check if the input is a number
|
|
1078
|
+
const numberValue = Number(input);
|
|
1079
|
+
if (!(0, lodash_1.isNaN)(numberValue)) {
|
|
1080
|
+
return numberValue;
|
|
1081
|
+
}
|
|
1082
|
+
// If it's neither a boolean nor a number, return the string itself
|
|
1083
|
+
return input;
|
|
1084
|
+
};
|
|
1085
|
+
exports.parseString = parseString;
|
|
1086
|
+
const isGoodJSON = (json) => {
|
|
1087
|
+
return !(0, lodash_1.isNil)(json) && !(0, lodash_1.isError)((0, lodash_1.attempt)(JSON.parse, json));
|
|
1088
|
+
};
|
|
1089
|
+
exports.isGoodJSON = isGoodJSON;
|
|
1090
|
+
const wait = (ms) => {
|
|
1091
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1092
|
+
};
|
|
1093
|
+
exports.wait = wait;
|
|
1094
|
+
const getObjsDifference = (obj1, obj2, path = "") => {
|
|
1095
|
+
let diffs = [];
|
|
1096
|
+
const allKeys = new Set([
|
|
1097
|
+
...Object.keys(obj1),
|
|
1098
|
+
...Object.keys(obj2)
|
|
1099
|
+
]);
|
|
1100
|
+
for (let key of allKeys) {
|
|
1101
|
+
const fullPath = path ? `${path}.${key}` : key;
|
|
1102
|
+
const val1 = obj1[key];
|
|
1103
|
+
const val2 = obj2[key];
|
|
1104
|
+
if (!(key in obj1)) {
|
|
1105
|
+
diffs.push({ type: "added", key: fullPath, value: val2 });
|
|
1106
|
+
}
|
|
1107
|
+
else if (!(key in obj2)) {
|
|
1108
|
+
diffs.push({ type: "removed", key: fullPath, value: val1 });
|
|
1109
|
+
}
|
|
1110
|
+
else if (typeof val1 === "object" &&
|
|
1111
|
+
typeof val2 === "object" &&
|
|
1112
|
+
val1 &&
|
|
1113
|
+
val2) {
|
|
1114
|
+
diffs.push(...(0, exports.getObjsDifference)(val1, val2, fullPath));
|
|
1115
|
+
}
|
|
1116
|
+
else if (val1 !== val2) {
|
|
1117
|
+
diffs.push({
|
|
1118
|
+
type: "changed",
|
|
1119
|
+
key: fullPath,
|
|
1120
|
+
from: val1,
|
|
1121
|
+
to: val2
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
return diffs;
|
|
1126
|
+
};
|
|
1127
|
+
exports.getObjsDifference = getObjsDifference;
|
|
1128
|
+
const toTitle = (str) => {
|
|
1129
|
+
const minorWords = new Set([
|
|
1130
|
+
"a",
|
|
1131
|
+
"an",
|
|
1132
|
+
"and",
|
|
1133
|
+
"as",
|
|
1134
|
+
"at",
|
|
1135
|
+
"but",
|
|
1136
|
+
"by",
|
|
1137
|
+
"for",
|
|
1138
|
+
"in",
|
|
1139
|
+
"nor",
|
|
1140
|
+
"of",
|
|
1141
|
+
"on",
|
|
1142
|
+
"or",
|
|
1143
|
+
"so",
|
|
1144
|
+
"the",
|
|
1145
|
+
"to",
|
|
1146
|
+
"up",
|
|
1147
|
+
"yet"
|
|
1148
|
+
]);
|
|
1149
|
+
// Split string into words
|
|
1150
|
+
const wordList = (0, lodash_1.words)((0, lodash_1.toLower)(str), /[A-Za-z0-9]+/g);
|
|
1151
|
+
// Capitalize words, except minor words (unless first or last)
|
|
1152
|
+
const result = wordList.map((word, index) => {
|
|
1153
|
+
if (index === 0 ||
|
|
1154
|
+
index === lodash_1.words.length - 1 ||
|
|
1155
|
+
!minorWords.has(word)) {
|
|
1156
|
+
return (0, lodash_1.capitalize)(word);
|
|
1157
|
+
}
|
|
1158
|
+
else {
|
|
1159
|
+
return word.toLowerCase();
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1162
|
+
return result.join(" ");
|
|
1163
|
+
};
|
|
1164
|
+
exports.toTitle = toTitle;
|
|
1165
|
+
//# sourceMappingURL=core.js.map
|