@thejob/util 1.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 (91) hide show
  1. package/dist/cjs/common/constants.d.ts +2 -0
  2. package/dist/cjs/common/constants.d.ts.map +1 -0
  3. package/dist/cjs/common/constants.js +2 -0
  4. package/dist/cjs/common/index.d.ts +4 -0
  5. package/dist/cjs/common/index.d.ts.map +1 -0
  6. package/dist/cjs/common/index.js +19 -0
  7. package/dist/cjs/common/types.d.ts +2 -0
  8. package/dist/cjs/common/types.d.ts.map +1 -0
  9. package/dist/cjs/common/types.js +17 -0
  10. package/dist/cjs/common/utils.d.ts +95 -0
  11. package/dist/cjs/common/utils.d.ts.map +1 -0
  12. package/dist/cjs/common/utils.js +402 -0
  13. package/dist/cjs/completeness/completeness.d.ts +2 -0
  14. package/dist/cjs/completeness/completeness.d.ts.map +1 -0
  15. package/dist/cjs/completeness/completeness.js +119 -0
  16. package/dist/cjs/completeness/index.d.ts +2 -0
  17. package/dist/cjs/completeness/index.d.ts.map +1 -0
  18. package/dist/cjs/completeness/index.js +17 -0
  19. package/dist/cjs/date/index.d.ts +2 -0
  20. package/dist/cjs/date/index.d.ts.map +1 -0
  21. package/dist/cjs/date/index.js +17 -0
  22. package/dist/cjs/date/utils.d.ts +14 -0
  23. package/dist/cjs/date/utils.d.ts.map +1 -0
  24. package/dist/cjs/date/utils.js +70 -0
  25. package/dist/cjs/index.d.ts +7 -0
  26. package/dist/cjs/index.d.ts.map +1 -0
  27. package/dist/cjs/index.js +22 -0
  28. package/dist/cjs/job/index.d.ts +2 -0
  29. package/dist/cjs/job/index.d.ts.map +1 -0
  30. package/dist/cjs/job/index.js +17 -0
  31. package/dist/cjs/job/utils.d.ts +2 -0
  32. package/dist/cjs/job/utils.d.ts.map +1 -0
  33. package/dist/cjs/job/utils.js +2 -0
  34. package/dist/cjs/job-application/index.d.ts +2 -0
  35. package/dist/cjs/job-application/index.d.ts.map +1 -0
  36. package/dist/cjs/job-application/index.js +17 -0
  37. package/dist/cjs/job-application/utils.d.ts +3 -0
  38. package/dist/cjs/job-application/utils.d.ts.map +1 -0
  39. package/dist/cjs/job-application/utils.js +19 -0
  40. package/dist/cjs/user/index.d.ts +2 -0
  41. package/dist/cjs/user/index.d.ts.map +1 -0
  42. package/dist/cjs/user/index.js +17 -0
  43. package/dist/cjs/user/utils.d.ts +8 -0
  44. package/dist/cjs/user/utils.d.ts.map +1 -0
  45. package/dist/cjs/user/utils.js +18 -0
  46. package/dist/esm/common/constants.d.ts +2 -0
  47. package/dist/esm/common/constants.d.ts.map +1 -0
  48. package/dist/esm/common/constants.js +1 -0
  49. package/dist/esm/common/index.d.ts +4 -0
  50. package/dist/esm/common/index.d.ts.map +1 -0
  51. package/dist/esm/common/index.js +3 -0
  52. package/dist/esm/common/types.d.ts +2 -0
  53. package/dist/esm/common/types.d.ts.map +1 -0
  54. package/dist/esm/common/types.js +16 -0
  55. package/dist/esm/common/utils.d.ts +95 -0
  56. package/dist/esm/common/utils.d.ts.map +1 -0
  57. package/dist/esm/common/utils.js +372 -0
  58. package/dist/esm/completeness/completeness.d.ts +2 -0
  59. package/dist/esm/completeness/completeness.d.ts.map +1 -0
  60. package/dist/esm/completeness/completeness.js +118 -0
  61. package/dist/esm/completeness/index.d.ts +2 -0
  62. package/dist/esm/completeness/index.d.ts.map +1 -0
  63. package/dist/esm/completeness/index.js +1 -0
  64. package/dist/esm/date/index.d.ts +2 -0
  65. package/dist/esm/date/index.d.ts.map +1 -0
  66. package/dist/esm/date/index.js +1 -0
  67. package/dist/esm/date/utils.d.ts +14 -0
  68. package/dist/esm/date/utils.d.ts.map +1 -0
  69. package/dist/esm/date/utils.js +61 -0
  70. package/dist/esm/index.d.ts +7 -0
  71. package/dist/esm/index.d.ts.map +1 -0
  72. package/dist/esm/index.js +6 -0
  73. package/dist/esm/job/index.d.ts +2 -0
  74. package/dist/esm/job/index.d.ts.map +1 -0
  75. package/dist/esm/job/index.js +1 -0
  76. package/dist/esm/job/utils.d.ts +2 -0
  77. package/dist/esm/job/utils.d.ts.map +1 -0
  78. package/dist/esm/job/utils.js +1 -0
  79. package/dist/esm/job-application/index.d.ts +2 -0
  80. package/dist/esm/job-application/index.d.ts.map +1 -0
  81. package/dist/esm/job-application/index.js +1 -0
  82. package/dist/esm/job-application/utils.d.ts +3 -0
  83. package/dist/esm/job-application/utils.d.ts.map +1 -0
  84. package/dist/esm/job-application/utils.js +15 -0
  85. package/dist/esm/user/index.d.ts +2 -0
  86. package/dist/esm/user/index.d.ts.map +1 -0
  87. package/dist/esm/user/index.js +1 -0
  88. package/dist/esm/user/utils.d.ts +8 -0
  89. package/dist/esm/user/utils.d.ts.map +1 -0
  90. package/dist/esm/user/utils.js +14 -0
  91. package/package.json +52 -0
@@ -0,0 +1,372 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { ExperienceLevel, ProficiencyLevel, UserCompletenessSchema, } from "@thejob/schema";
3
+ import { customAlphabet } from "nanoid";
4
+ export const removeEmpty = (obj) => {
5
+ // Check if the value is an object and not null
6
+ if (obj !== null && typeof obj === "object") {
7
+ // Iterate over each key in the object
8
+ for (const key in obj) {
9
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
10
+ const value = obj[key];
11
+ // Recursively remove empty properties from nested objects
12
+ if (typeof value === "object" && value !== null) {
13
+ obj[key] = removeEmpty(value);
14
+ }
15
+ // Remove the property if it's null, undefined, or an empty string, array, or object
16
+ if (value === null ||
17
+ value === undefined ||
18
+ value === "" ||
19
+ (typeof value === "object" && Object.keys(value).length === 0)) {
20
+ delete obj[key];
21
+ }
22
+ }
23
+ }
24
+ }
25
+ return obj;
26
+ };
27
+ export const deepEqual = (obj1, obj2) => {
28
+ return (JSON.stringify(removeEmpty(obj1)) === JSON.stringify(removeEmpty(obj2)));
29
+ };
30
+ // export const getYupDefaults = <T>(schema: any) => {
31
+ // const defaultValues: any = {};
32
+ // for (const key in schema.fields) {
33
+ // const field = schema.fields[key];
34
+ // if (field?.type === "object") {
35
+ // defaultValues[key] = getYupDefaults(field); // Recursively get defaults for nested objects
36
+ // } else {
37
+ // defaultValues[key] = field.default ? field.getDefault() : undefined; // Use `getDefault` to get default value
38
+ // }
39
+ // }
40
+ // return defaultValues as T;
41
+ // };
42
+ const replaceEmptyObjectsWithNull = (obj) => {
43
+ if (typeof obj !== "object" || obj === null) {
44
+ return obj;
45
+ }
46
+ if (Array.isArray(obj)) {
47
+ return obj.map((item) => replaceEmptyObjectsWithNull(item));
48
+ }
49
+ const newObj = {};
50
+ let isEmpty = true;
51
+ for (const key in obj) {
52
+ if (obj.hasOwnProperty(key)) {
53
+ const value = replaceEmptyObjectsWithNull(obj[key]);
54
+ newObj[key] = value;
55
+ if (typeof value === "object" &&
56
+ value !== null &&
57
+ Object.keys(value).length > 0) {
58
+ isEmpty = false;
59
+ }
60
+ else if (typeof value !== "undefined" &&
61
+ value !== null &&
62
+ value !== "") {
63
+ isEmpty = false;
64
+ }
65
+ }
66
+ }
67
+ return isEmpty && Object.keys(obj).length > 0 ? null : newObj;
68
+ };
69
+ export const getYupDefaults = (schema) => {
70
+ const defaultValues = schema.getDefault();
71
+ return replaceEmptyObjectsWithNull(defaultValues);
72
+ };
73
+ export const getFormDefaultValues = (inputValue, // TODO: Use react hook form default values type definition,,
74
+ onComplete = () => null) => {
75
+ const isCallable = typeof inputValue === "function";
76
+ return async () => {
77
+ const values = isCallable ? await inputValue() : inputValue;
78
+ onComplete(values);
79
+ return values;
80
+ };
81
+ };
82
+ export const proficiencyLevelToRating = (level) => {
83
+ switch (level) {
84
+ case ProficiencyLevel.BasicAwareness:
85
+ return 1;
86
+ case ProficiencyLevel.Beginner:
87
+ return 2;
88
+ case ProficiencyLevel.Intermediate:
89
+ return 3;
90
+ case ProficiencyLevel.Advanced:
91
+ return 4;
92
+ case ProficiencyLevel.Expert:
93
+ return 5;
94
+ default:
95
+ return 0;
96
+ }
97
+ };
98
+ export const slugify = (str) => {
99
+ str = str?.trim(); // trim leading/trailing white space
100
+ str = str
101
+ ?.replace(/([a-z0-9])([A-Z])/g, "$1-$2") // Convert camelCase to camel-Case
102
+ .toLowerCase() // convert string to lowercase
103
+ .replace(/[^a-z0-9 -]/g, "") // remove any non-alphanumeric characters
104
+ .replace(/\s+/g, "-") // replace spaces with hyphens
105
+ .replace(/-+/g, "-"); // remove consecutive hyphens
106
+ return str;
107
+ };
108
+ export const getShortId = (size = 12) => {
109
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
110
+ const nanoid = customAlphabet(alphabet, 12);
111
+ return nanoid(size);
112
+ };
113
+ export const minifyString = (seed, length = 10) => {
114
+ let alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
115
+ function createRandom() {
116
+ let a = 1664525;
117
+ let c = 1013904223;
118
+ let m = Math.pow(2, 32);
119
+ let state = 0;
120
+ for (let i = 0; i < seed.length; i++) {
121
+ state += seed.charCodeAt(i);
122
+ }
123
+ return function () {
124
+ state = (a * state + c) % m;
125
+ return state;
126
+ };
127
+ }
128
+ let random = createRandom();
129
+ let generatedString = "";
130
+ for (let i = 0; i < length; i++) {
131
+ let randomIndex = random() % alphabet.length;
132
+ generatedString += alphabet[randomIndex];
133
+ }
134
+ return generatedString;
135
+ };
136
+ /**
137
+ * Extracts the ID from a given string pattern.
138
+ * Assumes the ID is the last segment after the final hyphen.
139
+ *
140
+ * @param input - The string to extract the ID from.
141
+ * @returns The extracted ID or null if not found.
142
+ */
143
+ export const extractShortID = (slug) => {
144
+ // Match the last hyphen followed by one or more characters
145
+ const match = slug.match(/-(\w+)$/);
146
+ // Return the first capturing group if a match is found
147
+ return match ? match[1] : null;
148
+ };
149
+ export const allResults = async (promises) => {
150
+ const results = await Promise.allSettled(promises);
151
+ return results.map((result) => result.status === "fulfilled" ? result.value : { error: result.reason });
152
+ };
153
+ export const sleep = async (duration) => {
154
+ return new Promise((resolve) => {
155
+ setTimeout(() => {
156
+ resolve({});
157
+ }, duration);
158
+ });
159
+ };
160
+ export const hasOtherValue = (input) => {
161
+ return (input?.value === "others" ||
162
+ (Array.isArray(input?.value) && input?.value.includes("others")));
163
+ };
164
+ export const fromWithOtherValue = (input, displayFn = (value) => value) => {
165
+ if (!input)
166
+ return "Not avaiable";
167
+ if (hasOtherValue(input)) {
168
+ return input.otherValue || "Not Available";
169
+ }
170
+ else {
171
+ return displayFn(input);
172
+ }
173
+ };
174
+ export const isJSON = (value) => {
175
+ try {
176
+ JSON.parse(value);
177
+ return true;
178
+ }
179
+ catch (error) {
180
+ return false;
181
+ }
182
+ };
183
+ export const displayByName = (option) => {
184
+ return option?.name;
185
+ };
186
+ export const displayLocation = (location, display) => {
187
+ const { city, state, country, address } = location || {};
188
+ let keywords = [];
189
+ if (display === "address") {
190
+ keywords = [address];
191
+ }
192
+ else if (display === "medium") {
193
+ keywords = [city, state, country];
194
+ }
195
+ else if (display === "small") {
196
+ keywords = [city, country];
197
+ }
198
+ else {
199
+ keywords = [country];
200
+ }
201
+ const result = keywords.filter((value) => !!value).join(", ");
202
+ return result || "Not Available";
203
+ };
204
+ /**
205
+ * Generates a random integer between two given values (inclusive).
206
+ *
207
+ * @param {number} min - The minimum value (inclusive).
208
+ * @param {number} max - The maximum value (inclusive).
209
+ * @returns {number} A random integer between min and max.
210
+ */
211
+ export const getRandomInt = (min, max) => {
212
+ if (min > max) {
213
+ throw new Error("Min value must be less than or equal to max value.");
214
+ }
215
+ const minCeiled = Math.ceil(min);
216
+ const maxFloored = Math.floor(max);
217
+ return Math.floor(Math.random() * (maxFloored - minCeiled + 1)) + minCeiled;
218
+ };
219
+ /**
220
+ * Generates a random floating-point number between two given values (inclusive).
221
+ *
222
+ * @param {number} min - The minimum value (inclusive).
223
+ * @param {number} max - The maximum value (inclusive).
224
+ * @returns {number} A random floating-point number between min and max.
225
+ */
226
+ export const getRandomFloat = (min, max) => {
227
+ if (min > max) {
228
+ throw new Error("Min value must be less than or equal to max value.");
229
+ }
230
+ return Math.random() * (max - min) + min;
231
+ };
232
+ export const displayNameLabel = (name, type = "full") => {
233
+ if (!name) {
234
+ return "Not available";
235
+ }
236
+ if (typeof name === "string") {
237
+ return name;
238
+ }
239
+ const { first, last } = name;
240
+ if (type === "full") {
241
+ return `${first} ${last}`;
242
+ }
243
+ else if (type === "first") {
244
+ return first;
245
+ }
246
+ else if (type === "last") {
247
+ return last;
248
+ }
249
+ else {
250
+ return "Render Failed";
251
+ }
252
+ };
253
+ export const displayMobileNumberLabel = (mobileNumber, options) => {
254
+ const { number, country } = mobileNumber;
255
+ const { name, dial_code } = country;
256
+ if (!options?.countryName) {
257
+ return `${dial_code} ${number}`;
258
+ }
259
+ return `${name} (${dial_code}) ${number}`;
260
+ };
261
+ export const toPositiveWholeNumber = (value) => {
262
+ if (typeof value !== "number") {
263
+ return 0;
264
+ }
265
+ const wholePercentage = Math.round(value); // Round to the nearest whole number
266
+ return wholePercentage < 0 ? 0 : wholePercentage; // Ensure the value is positive
267
+ };
268
+ export const formatNumberToKMB = (num) => {
269
+ if (num < 1000) {
270
+ return num.toString();
271
+ }
272
+ else if (num < 1000000) {
273
+ return (num / 1000).toFixed(1) + "K";
274
+ }
275
+ else if (num < 1000000000) {
276
+ return (num / 1000000).toFixed(1) + "M";
277
+ }
278
+ else {
279
+ return (num / 1000000000).toFixed(1) + "B";
280
+ }
281
+ };
282
+ export const formatCountWithLabel = (count, options) => {
283
+ const { singularLabel, pluralLabel, zeroCountLabel } = options;
284
+ if (count === undefined || count === 0) {
285
+ return zeroCountLabel || `No ${pluralLabel}`;
286
+ }
287
+ else {
288
+ const formattedCount = formatNumberToKMB(count);
289
+ const label = count > 1 ? pluralLabel : singularLabel;
290
+ return `${formattedCount} ${label}`;
291
+ }
292
+ };
293
+ /**
294
+ * Recursively parses a dirty fields object to detect if the form or a specific field is dirty.
295
+ *
296
+ * @param dirtyFields The object representing the dirty state of form fields.
297
+ * @param fieldName (Optional) The name of a specific field to check for dirtiness.
298
+ * @returns True if the form or the specified field is dirty, false otherwise.
299
+ */
300
+ export const isFormDirty = (dirtyFields, //PickFrom<FormState<any>, "dirtyFields">,
301
+ fieldName) => {
302
+ if (fieldName) {
303
+ const field = dirtyFields[fieldName];
304
+ if (typeof field === "boolean") {
305
+ return field;
306
+ }
307
+ else if (typeof field === "object" && field !== null) {
308
+ // If the field is an object or array, recursively check its contents
309
+ return isFormDirty(field);
310
+ }
311
+ return false; // FieldName not found or not a boolean/object
312
+ }
313
+ // If no fieldName is provided, check the entire form
314
+ for (const key in dirtyFields) {
315
+ if (Object.prototype.hasOwnProperty.call(dirtyFields, key)) {
316
+ const value = dirtyFields[key];
317
+ if (typeof value === "boolean") {
318
+ if (value === true) {
319
+ return true; // Found a dirty boolean field
320
+ }
321
+ }
322
+ else if (typeof value === "object" && value !== null) {
323
+ // Recursively check nested objects or arrays
324
+ if (isFormDirty(value)) {
325
+ return true;
326
+ }
327
+ }
328
+ }
329
+ }
330
+ return false; // No dirty fields found
331
+ };
332
+ /**
333
+ * Extracts the root path of each error within the 'inner' property of the input object.
334
+ *
335
+ * @param data The input object containing error details.
336
+ * @returns An array of strings, where each string is the root path of an error.
337
+ */
338
+ export const getErrorRootPaths = (data) => {
339
+ const rootPaths = [];
340
+ if (data && Array.isArray(data.inner)) {
341
+ data.inner.forEach((errorDetail) => {
342
+ if (errorDetail.path) {
343
+ // The root path is typically the first part before the dot
344
+ const rootPath = errorDetail.path.split(".")[0];
345
+ if (rootPath && !rootPaths.includes(rootPath)) {
346
+ rootPaths.push(rootPath);
347
+ }
348
+ }
349
+ });
350
+ }
351
+ return rootPaths;
352
+ };
353
+ export const getRequiredUserInformation = (completeness, skip = []) => {
354
+ try {
355
+ UserCompletenessSchema.omit(skip).validateSync(completeness, {
356
+ abortEarly: false,
357
+ });
358
+ return [];
359
+ }
360
+ catch (error) {
361
+ return getErrorRootPaths(error);
362
+ }
363
+ };
364
+ export const getRequiredInformationByUser = (user, completeness) => {
365
+ if (user.experienceLevel === ExperienceLevel.Student ||
366
+ user.experienceLevel === ExperienceLevel.Entry) {
367
+ return getRequiredUserInformation(completeness, ["workExperiences"]);
368
+ }
369
+ else {
370
+ return getRequiredUserInformation(completeness);
371
+ }
372
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=completeness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completeness.d.ts","sourceRoot":"","sources":["../../../src/completeness/completeness.ts"],"names":[],"mappings":""}
@@ -0,0 +1,118 @@
1
+ const extractFields = (schema, prefix = "", includeOptionals = false) => {
2
+ if (!schema?.fields)
3
+ return [];
4
+ const schemaFields = schema.fields;
5
+ let extractedFields = [];
6
+ const processField = (key, fieldSchema, currentPath) => {
7
+ const isRequired = !fieldSchema.spec?.optional;
8
+ const type = fieldSchema.type;
9
+ const innerType = fieldSchema.innerType?.type;
10
+ if (!isRequired && !includeOptionals)
11
+ return;
12
+ if (type === "array") {
13
+ const minItems = fieldSchema.tests?.find((t) => t.OPTIONS?.name === "min")?.OPTIONS
14
+ ?.params?.min || 0;
15
+ const itemSchema = fieldSchema.innerType;
16
+ // Handle required array items
17
+ for (let i = 0; i < minItems; i++) {
18
+ const indexPath = `${currentPath}.${i}`;
19
+ const itemFields = extractFields(itemSchema, indexPath, includeOptionals);
20
+ extractedFields.push(...itemFields);
21
+ if (itemFields.length === 0) {
22
+ extractedFields.push({ key: indexPath, required: true });
23
+ }
24
+ }
25
+ // Handle optional array items
26
+ if (includeOptionals) {
27
+ const optionalFields = extractFields(itemSchema, currentPath, includeOptionals).map((f) => ({ ...f, key: `${f.key}[]`, required: false }));
28
+ extractedFields.push(...optionalFields);
29
+ }
30
+ }
31
+ else if (type === "object" || innerType === "object") {
32
+ const targetSchema = type === "object" ? fieldSchema : fieldSchema.innerType;
33
+ const nestedFields = extractFields(targetSchema, currentPath, includeOptionals);
34
+ extractedFields.push(...nestedFields);
35
+ }
36
+ else {
37
+ extractedFields.push({ key: currentPath, required: isRequired });
38
+ }
39
+ };
40
+ for (const key in schemaFields) {
41
+ const fieldSchema = schemaFields[key];
42
+ if (!fieldSchema)
43
+ continue;
44
+ const currentPath = prefix ? `${prefix}.${key}` : key;
45
+ processField(key, fieldSchema, currentPath);
46
+ }
47
+ return extractedFields;
48
+ };
49
+ export {};
50
+ // const getValueByPath = (data: any, path: string) => {
51
+ // const parts = path.replace("[]", "").split(".");
52
+ // return parts.reduce((acc, part) => {
53
+ // if (acc === undefined || acc === null) return undefined;
54
+ // const match = part.match(/^(\d+)$/);
55
+ // if (match && match[1]) {
56
+ // const index = parseInt(match[1]);
57
+ // return Array.isArray(acc) ? acc[index] : undefined;
58
+ // }
59
+ // return acc[part];
60
+ // }, data);
61
+ // };
62
+ // export const getCompletenessScore = <T>(
63
+ // schema: any,
64
+ // data: T | T[],
65
+ // options: CompletenessOptions = { includeOptionals: false }
66
+ // ): CompletenessScore => {
67
+ // const { includeOptionals = false, emptyArrayScore } = options;
68
+ // if (Array.isArray(data)) {
69
+ // if (data.length === 0) {
70
+ // return {
71
+ // score: emptyArrayScore === "perfect" ? 100 : 0,
72
+ // completedSteps: 0,
73
+ // totalSteps: 0,
74
+ // children: [],
75
+ // };
76
+ // }
77
+ // const children = data.map((item) =>
78
+ // getCompletenessScore(schema, item, options)
79
+ // );
80
+ // const contentScore =
81
+ // children.reduce((sum, child) => sum + child.score, 0) / children.length;
82
+ // return {
83
+ // score: Math.round(contentScore),
84
+ // completedSteps: children.reduce((sum, c) => sum + c.completedSteps, 0),
85
+ // totalSteps: children.reduce((sum, c) => sum + c.totalSteps, 0),
86
+ // children,
87
+ // };
88
+ // }
89
+ // const fields = extractFields(schema, "", includeOptionals);
90
+ // const requiredFields = fields.filter((f) => f.required);
91
+ // const totalSteps = includeOptionals ? fields.length : requiredFields.length;
92
+ // let completedSteps = 0;
93
+ // const meta = {
94
+ // steps: fields.map((f) => f.key),
95
+ // completed: [] as string[],
96
+ // incomplete: [] as string[],
97
+ // };
98
+ // fields.forEach(({ key, required }) => {
99
+ // const value = getValueByPath(data, key);
100
+ // const exists = value !== undefined && value !== null && value !== "";
101
+ // if (exists) {
102
+ // meta.completed.push(key);
103
+ // if (includeOptionals || required) completedSteps++;
104
+ // } else {
105
+ // if (includeOptionals || required) meta.incomplete.push(key);
106
+ // }
107
+ // });
108
+ // const score =
109
+ // totalSteps > 0 ? Math.floor((completedSteps / totalSteps) * 100) : 100;
110
+ // return {
111
+ // score,
112
+ // completedSteps: includeOptionals
113
+ // ? completedSteps
114
+ // : Math.min(completedSteps, requiredFields.length),
115
+ // totalSteps,
116
+ // meta,
117
+ // };
118
+ // };
@@ -0,0 +1,2 @@
1
+ export * from "./completeness";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/completeness/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./completeness";
@@ -0,0 +1,2 @@
1
+ export * from "./utils";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/date/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./utils";
@@ -0,0 +1,14 @@
1
+ import { DateRangeOption } from "@thejob/schema";
2
+ import dayjs, { Dayjs } from "dayjs";
3
+ export declare const toDayJS: ({ date, dateFormat, strict, utc, }?: {
4
+ date?: string | Dayjs;
5
+ dateFormat?: string;
6
+ strict?: boolean;
7
+ utc?: boolean;
8
+ }) => dayjs.Dayjs;
9
+ export declare const dateAgo: (value: number | string | Date) => string;
10
+ export declare const dateRangeOptionToDateRange: (option: DateRangeOption) => {
11
+ startDate: string | undefined;
12
+ endDate: string | undefined;
13
+ };
14
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/date/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAoB,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAQrC,eAAO,MAAM,OAAO,GAAI,qCAKrB;IACD,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACV,gBASL,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,GAAG,MAAM,GAAG,IAAI,WAEpD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,QAAQ,eAAe;;;CA4CjE,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { DateRangeOption, SystemDateFormat } from "@thejob/schema";
2
+ import dayjs from "dayjs";
3
+ import localizedFormat from "dayjs/plugin/localizedFormat";
4
+ import relativeTime from "dayjs/plugin/relativeTime";
5
+ import customParseFormat from "dayjs/plugin/customParseFormat";
6
+ dayjs.extend(relativeTime);
7
+ dayjs.extend(localizedFormat);
8
+ dayjs.extend(customParseFormat);
9
+ export const toDayJS = ({ date, dateFormat = SystemDateFormat, strict = false, utc = false, } = {}) => {
10
+ return dayjs(date, {
11
+ utc,
12
+ format: dateFormat,
13
+ }, strict);
14
+ };
15
+ export const dateAgo = (value) => {
16
+ return dayjs(value).fromNow();
17
+ };
18
+ export const dateRangeOptionToDateRange = (option) => {
19
+ const today = toDayJS({ utc: true });
20
+ let dateRange = {
21
+ startDate: undefined,
22
+ endDate: undefined,
23
+ };
24
+ switch (option) {
25
+ case DateRangeOption.LastMonth:
26
+ dateRange = {
27
+ startDate: today.subtract(1, "month"), //.startOf("month"),
28
+ endDate: today,
29
+ };
30
+ break;
31
+ case DateRangeOption.LastWeek:
32
+ dateRange = {
33
+ startDate: today.subtract(1, "week"), //.startOf("week"),
34
+ endDate: today, //.endOf("week"),
35
+ };
36
+ break;
37
+ case DateRangeOption.Last_3_Days:
38
+ dateRange = {
39
+ startDate: today.subtract(3, "days"),
40
+ endDate: today,
41
+ };
42
+ break;
43
+ case DateRangeOption.Last_24_Hours:
44
+ dateRange = {
45
+ startDate: today.subtract(24, "hours"),
46
+ endDate: today,
47
+ };
48
+ break;
49
+ case DateRangeOption.Any:
50
+ default:
51
+ dateRange = {
52
+ startDate: undefined,
53
+ endDate: undefined,
54
+ };
55
+ break;
56
+ }
57
+ return {
58
+ startDate: dateRange.startDate?.format(SystemDateFormat),
59
+ endDate: dateRange.endDate?.format(SystemDateFormat),
60
+ };
61
+ };
@@ -0,0 +1,7 @@
1
+ export * from "./common";
2
+ export * from "./completeness";
3
+ export * from "./user";
4
+ export * from "./date";
5
+ export * from "./job";
6
+ export * from "./job-application";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from "./common";
2
+ export * from "./completeness";
3
+ export * from "./user";
4
+ export * from "./date";
5
+ export * from "./job";
6
+ export * from "./job-application";
@@ -0,0 +1,2 @@
1
+ export * from "./utils";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/job/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./utils";
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/job/utils.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from "./utils";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/job-application/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./utils";
@@ -0,0 +1,3 @@
1
+ import { JobApplicationScore } from "@thejob/schema";
2
+ export declare const jobApplicationScoreToLabel: (score: JobApplicationScore) => "Exceptional" | "Qualified" | "Potential" | "Not Recommended" | "Unknown";
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/job-application/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD,eAAO,MAAM,0BAA0B,GAAI,OAAO,mBAAmB,8EAapE,CAAC"}