@whiteslove/parsing-lexicon 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +137 -137
  3. package/index.d.ts +374 -374
  4. package/package.json +77 -75
  5. package/src/central-asia-locations.js +211 -211
  6. package/src/central-asia.js +233 -233
  7. package/src/contact.d.ts +44 -44
  8. package/src/contact.js +159 -159
  9. package/src/countries.js +175 -175
  10. package/src/country-context.d.ts +10 -10
  11. package/src/country-context.js +22 -22
  12. package/src/currency.d.ts +14 -14
  13. package/src/currency.js +66 -66
  14. package/src/geo.js +169 -169
  15. package/src/geography-central-asia.js +42 -42
  16. package/src/geography-detection.d.ts +14 -14
  17. package/src/geography-detection.js +64 -64
  18. package/src/geography-display.d.ts +13 -13
  19. package/src/geography-display.js +113 -113
  20. package/src/geography.js +210 -210
  21. package/src/hiring-advanced.js +147 -147
  22. package/src/hiring-candidate-fields.d.ts +9 -9
  23. package/src/hiring-candidate-fields.js +92 -92
  24. package/src/hiring-context.d.ts +64 -64
  25. package/src/hiring-context.js +412 -412
  26. package/src/hiring-language-extensions.d.ts +19 -19
  27. package/src/hiring-language-extensions.js +139 -139
  28. package/src/hiring-languages.js +135 -135
  29. package/src/hiring-location-fields.d.ts +3 -3
  30. package/src/hiring-location-fields.js +53 -53
  31. package/src/hiring-professions-ro.js +191 -191
  32. package/src/hiring-professions.js +437 -437
  33. package/src/hiring-requirements.d.ts +16 -16
  34. package/src/hiring-requirements.js +170 -170
  35. package/src/hiring-salary-context.d.ts +27 -27
  36. package/src/hiring-salary-context.js +76 -76
  37. package/src/hiring-semantics.d.ts +29 -29
  38. package/src/hiring-semantics.js +218 -218
  39. package/src/hiring-skills.d.ts +21 -21
  40. package/src/hiring-skills.js +315 -315
  41. package/src/hiring-source-aliases.d.ts +32 -32
  42. package/src/hiring-source-aliases.js +185 -185
  43. package/src/hiring-source-semantics.d.ts +31 -31
  44. package/src/hiring-source-semantics.js +293 -293
  45. package/src/hiring-temporal.d.ts +15 -15
  46. package/src/hiring-temporal.js +67 -67
  47. package/src/hiring-vacancy-fields.d.ts +5 -5
  48. package/src/hiring-vacancy-fields.js +23 -23
  49. package/src/hiring-work-semantics.d.ts +34 -34
  50. package/src/hiring-work-semantics.js +72 -72
  51. package/src/hiring.js +180 -180
  52. package/src/housing-address.d.ts +18 -18
  53. package/src/housing-address.js +217 -210
  54. package/src/housing-commercial.d.ts +1 -0
  55. package/src/housing-commercial.js +9 -0
  56. package/src/housing-context.d.ts +36 -36
  57. package/src/housing-context.js +183 -183
  58. package/src/housing-features.js +30 -30
  59. package/src/housing-intent.d.ts +9 -9
  60. package/src/housing-intent.js +132 -132
  61. package/src/housing-listing-fields.js +131 -131
  62. package/src/housing-money.d.ts +7 -7
  63. package/src/housing-money.js +102 -102
  64. package/src/housing-source-aliases.d.ts +8 -8
  65. package/src/housing-source-aliases.js +51 -51
  66. package/src/housing-structured.d.ts +55 -55
  67. package/src/housing-structured.js +219 -219
  68. package/src/housing.js +200 -200
  69. package/src/index.js +45 -44
  70. package/src/kz-location-extensions.js +307 -307
  71. package/src/landmarks.js +21 -21
  72. package/src/lexicon-core.js +58 -58
  73. package/src/location-merge.js +106 -106
  74. package/src/locations.js +456 -456
  75. package/src/money-core.d.ts +10 -10
  76. package/src/money-core.js +81 -81
  77. package/src/money-lexicon.d.ts +5 -5
  78. package/src/money-lexicon.js +79 -79
  79. package/src/money.js +154 -154
  80. package/src/normalization.js +384 -384
  81. package/src/odesa-metropolitan.js +144 -144
  82. package/src/romania-geography.js +47 -47
  83. package/src/tashkent-colloquial.js +80 -72
  84. package/src/tashkent-housing-geography.d.ts +38 -38
  85. package/src/tashkent-housing-geography.js +211 -211
  86. package/src/tashkent-pois.js +215 -215
  87. package/src/tashkent-residential-complexes.js +272 -272
  88. package/src/ua-location-extensions-major.js +118 -118
  89. package/src/ua-location-extensions-metro.js +9 -9
  90. package/src/ua-location-extensions-regional.js +246 -246
  91. package/src/ua-secondary-cities.d.ts +2 -2
  92. package/src/ua-secondary-cities.js +57 -57
  93. package/src/ukraine.js +75 -75
  94. package/src/uz-location-extensions.js +259 -259
@@ -1,67 +1,67 @@
1
- export const HIRING_MONTHS = Object.freeze({
2
- январь: 0, января: 0, february: 1, февраль: 1, февраля: 1,
3
- март: 2, марта: 2, april: 3, апрель: 3, апреля: 3,
4
- may: 4, май: 4, мая: 4, june: 5, июнь: 5, июня: 5,
5
- july: 6, июль: 6, июля: 6, august: 7, август: 7, августа: 7,
6
- september: 8, сентябрь: 8, сентября: 8, october: 9, октябрь: 9, октября: 9,
7
- november: 10, ноябрь: 10, ноября: 10, december: 11, декабрь: 11, декабря: 11,
8
- ianuarie: 0, februarie: 1, martie: 2, aprilie: 3, mai: 4, iunie: 5,
9
- iulie: 6, august: 7, septembrie: 8, octombrie: 9, noiembrie: 10, decembrie: 11,
10
- січня: 0, лютого: 1, березня: 2, квітня: 3, травня: 4, червня: 5,
11
- липня: 6, серпня: 7, вересня: 8, жовтня: 9, листопада: 10, грудня: 11,
12
- });
13
-
14
- export const UNICODE_LEFT_BOUNDARY = '(?<![\\p{L}\\p{N}])';
15
- export const UNICODE_RIGHT_BOUNDARY = '(?![\\p{L}\\p{N}])';
16
- export const TODAY_RE = new RegExp(`${UNICODE_LEFT_BOUNDARY}(?:сегодня|сьогодні|bugun|today|astăzi|azi)${UNICODE_RIGHT_BOUNDARY}`, 'iu');
17
- export const YESTERDAY_RE = new RegExp(`${UNICODE_LEFT_BOUNDARY}(?:вчера|вчора|kecha|yesterday|ieri)${UNICODE_RIGHT_BOUNDARY}`, 'iu');
18
- export const HOURS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,3})\\s*(?:ч\\.?|час(?:а|ов)?|год(?:ину|ини)|soat|hours?|hrs?|ore|oră)${UNICODE_RIGHT_BOUNDARY}`, 'iu');
19
- export const DAYS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,3})\\s*(?:дн(?:я|ей|і|ів)?|день|days?|kun|zile|zi)${UNICODE_RIGHT_BOUNDARY}`, 'iu');
20
- export const AGO_SUFFIX = '(?:\\s*(?:назад|тому|раніше|oldin|ago|în urmă))';
21
- export const WEEKS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,2})\\s*(?:недел(?:ю|и|ь)|тижн(?:ів|і|я)|hafta|weeks?|săptămân\\p{L}*)${AGO_SUFFIX}`, 'iu');
22
- export const MONTHS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,2})\\s*(?:мес(?:яц\\p{L}*)?\\.?|міс(?:яц\\p{L}*)?\\.?|oy|months?|lun\\p{L}*)${AGO_SUFFIX}`, 'iu');
23
- export const YEARS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,2})\\s*(?:год(?:а|ов)?|лет|рік|рок(?:и|ів)|yil|years?|ani|an)${AGO_SUFFIX}`, 'iu');
24
-
25
- export function parseHiringActivityDate(value, now = new Date()) {
26
- const text = String(value || '');
27
- if (TODAY_RE.test(text)) return now.toISOString();
28
- if (YESTERDAY_RE.test(text)) return new Date(now.getTime() - 86_400_000).toISOString();
29
- const absolute = text.match(/(?<![\p{L}\p{N}])(\d{1,2})\s+([\p{L}]+),?\s+(20\d{2})(?![\p{L}\p{N}])/iu);
30
- if (absolute) {
31
- const month = HIRING_MONTHS[absolute[2].toLocaleLowerCase('ru')];
32
- if (month != null) return new Date(Date.UTC(Number(absolute[3]), month, Number(absolute[1]), 12)).toISOString();
33
- }
34
- const dotted = text.match(/(?<![\d])(\d{1,2})[./-](\d{1,2})[./-](20\d{2})(?![\d])/);
35
- if (dotted) return new Date(Date.UTC(Number(dotted[3]), Number(dotted[2]) - 1, Number(dotted[1]), 12)).toISOString();
36
- const hours = text.match(HOURS_AGO_RE);
37
- if (hours) return new Date(now.getTime() - Number(hours[1]) * 3_600_000).toISOString();
38
- const days = text.match(DAYS_AGO_RE);
39
- if (days) return new Date(now.getTime() - Number(days[1]) * 86_400_000).toISOString();
40
- const weeks = text.match(WEEKS_AGO_RE);
41
- if (weeks) return new Date(now.getTime() - Number(weeks[1]) * 7 * 86_400_000).toISOString();
42
- const months = text.match(MONTHS_AGO_RE);
43
- if (months) return new Date(now.getTime() - Number(months[1]) * 30 * 86_400_000).toISOString();
44
- const years = text.match(YEARS_AGO_RE);
45
- if (years) return new Date(now.getTime() - Number(years[1]) * 365 * 86_400_000).toISOString();
46
- return null;
47
- }
48
-
49
- export function parseHiringDayMonthDate(value, now = new Date()) {
50
- const text = String(value || '');
51
- const match = text.match(new RegExp(`${UNICODE_LEFT_BOUNDARY}(\\d{1,2})\\s+(\\p{L}+)${UNICODE_RIGHT_BOUNDARY}`, 'iu'));
52
- if (!match) return null;
53
- const month = HIRING_MONTHS[match[2].toLocaleLowerCase('ru')];
54
- if (month == null) return null;
55
- const day = Number(match[1]);
56
- let time = Date.UTC(now.getUTCFullYear(), month, day, 12);
57
- if (time > now.getTime() + 48 * 60 * 60 * 1000) time = Date.UTC(now.getUTCFullYear() - 1, month, day, 12);
58
- return new Date(time).toISOString();
59
- }
60
-
61
- const DEADLINE_MARKER_RE = /(?:application\s+deadline|apply\s+by|closing\s+date|deadline|дедлайн|срок(?:\s+подачи)?|термін(?:\s+подання)?)[\s:–—-]{0,8}([^.;\n]{3,55})/iu;
62
- const DEADLINE_DATE_RE = /\b(?:\d{4}-\d{2}-\d{2}|\d{1,2}[./-]\d{1,2}[./-]\d{2,4}|\d{1,2}\s+(?:jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|jun(?:e)?|jul(?:y)?|aug(?:ust)?|sep(?:tember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?|янв\p{L}*|фев\p{L}*|мар\p{L}*|апр\p{L}*|ма[йя]|июн\p{L}*|июл\p{L}*|авг\p{L}*|сен\p{L}*|окт\p{L}*|ноя\p{L}*|дек\p{L}*)\.?\s+\d{2,4})\b/iu;
63
-
64
- export function extractHiringDeadline(value) {
65
- const marker = DEADLINE_MARKER_RE.exec(String(value || ''));
66
- return marker?.[1]?.match(DEADLINE_DATE_RE)?.[0]?.trim() || null;
67
- }
1
+ export const HIRING_MONTHS = Object.freeze({
2
+ январь: 0, января: 0, february: 1, февраль: 1, февраля: 1,
3
+ март: 2, марта: 2, april: 3, апрель: 3, апреля: 3,
4
+ may: 4, май: 4, мая: 4, june: 5, июнь: 5, июня: 5,
5
+ july: 6, июль: 6, июля: 6, august: 7, август: 7, августа: 7,
6
+ september: 8, сентябрь: 8, сентября: 8, october: 9, октябрь: 9, октября: 9,
7
+ november: 10, ноябрь: 10, ноября: 10, december: 11, декабрь: 11, декабря: 11,
8
+ ianuarie: 0, februarie: 1, martie: 2, aprilie: 3, mai: 4, iunie: 5,
9
+ iulie: 6, august: 7, septembrie: 8, octombrie: 9, noiembrie: 10, decembrie: 11,
10
+ січня: 0, лютого: 1, березня: 2, квітня: 3, травня: 4, червня: 5,
11
+ липня: 6, серпня: 7, вересня: 8, жовтня: 9, листопада: 10, грудня: 11,
12
+ });
13
+
14
+ export const UNICODE_LEFT_BOUNDARY = '(?<![\\p{L}\\p{N}])';
15
+ export const UNICODE_RIGHT_BOUNDARY = '(?![\\p{L}\\p{N}])';
16
+ export const TODAY_RE = new RegExp(`${UNICODE_LEFT_BOUNDARY}(?:сегодня|сьогодні|bugun|today|astăzi|azi)${UNICODE_RIGHT_BOUNDARY}`, 'iu');
17
+ export const YESTERDAY_RE = new RegExp(`${UNICODE_LEFT_BOUNDARY}(?:вчера|вчора|kecha|yesterday|ieri)${UNICODE_RIGHT_BOUNDARY}`, 'iu');
18
+ export const HOURS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,3})\\s*(?:ч\\.?|час(?:а|ов)?|год(?:ину|ини)|soat|hours?|hrs?|ore|oră)${UNICODE_RIGHT_BOUNDARY}`, 'iu');
19
+ export const DAYS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,3})\\s*(?:дн(?:я|ей|і|ів)?|день|days?|kun|zile|zi)${UNICODE_RIGHT_BOUNDARY}`, 'iu');
20
+ export const AGO_SUFFIX = '(?:\\s*(?:назад|тому|раніше|oldin|ago|în urmă))';
21
+ export const WEEKS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,2})\\s*(?:недел(?:ю|и|ь)|тижн(?:ів|і|я)|hafta|weeks?|săptămân\\p{L}*)${AGO_SUFFIX}`, 'iu');
22
+ export const MONTHS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,2})\\s*(?:мес(?:яц\\p{L}*)?\\.?|міс(?:яц\\p{L}*)?\\.?|oy|months?|lun\\p{L}*)${AGO_SUFFIX}`, 'iu');
23
+ export const YEARS_AGO_RE = new RegExp(`(?:^|\\s)(\\d{1,2})\\s*(?:год(?:а|ов)?|лет|рік|рок(?:и|ів)|yil|years?|ani|an)${AGO_SUFFIX}`, 'iu');
24
+
25
+ export function parseHiringActivityDate(value, now = new Date()) {
26
+ const text = String(value || '');
27
+ if (TODAY_RE.test(text)) return now.toISOString();
28
+ if (YESTERDAY_RE.test(text)) return new Date(now.getTime() - 86_400_000).toISOString();
29
+ const absolute = text.match(/(?<![\p{L}\p{N}])(\d{1,2})\s+([\p{L}]+),?\s+(20\d{2})(?![\p{L}\p{N}])/iu);
30
+ if (absolute) {
31
+ const month = HIRING_MONTHS[absolute[2].toLocaleLowerCase('ru')];
32
+ if (month != null) return new Date(Date.UTC(Number(absolute[3]), month, Number(absolute[1]), 12)).toISOString();
33
+ }
34
+ const dotted = text.match(/(?<![\d])(\d{1,2})[./-](\d{1,2})[./-](20\d{2})(?![\d])/);
35
+ if (dotted) return new Date(Date.UTC(Number(dotted[3]), Number(dotted[2]) - 1, Number(dotted[1]), 12)).toISOString();
36
+ const hours = text.match(HOURS_AGO_RE);
37
+ if (hours) return new Date(now.getTime() - Number(hours[1]) * 3_600_000).toISOString();
38
+ const days = text.match(DAYS_AGO_RE);
39
+ if (days) return new Date(now.getTime() - Number(days[1]) * 86_400_000).toISOString();
40
+ const weeks = text.match(WEEKS_AGO_RE);
41
+ if (weeks) return new Date(now.getTime() - Number(weeks[1]) * 7 * 86_400_000).toISOString();
42
+ const months = text.match(MONTHS_AGO_RE);
43
+ if (months) return new Date(now.getTime() - Number(months[1]) * 30 * 86_400_000).toISOString();
44
+ const years = text.match(YEARS_AGO_RE);
45
+ if (years) return new Date(now.getTime() - Number(years[1]) * 365 * 86_400_000).toISOString();
46
+ return null;
47
+ }
48
+
49
+ export function parseHiringDayMonthDate(value, now = new Date()) {
50
+ const text = String(value || '');
51
+ const match = text.match(new RegExp(`${UNICODE_LEFT_BOUNDARY}(\\d{1,2})\\s+(\\p{L}+)${UNICODE_RIGHT_BOUNDARY}`, 'iu'));
52
+ if (!match) return null;
53
+ const month = HIRING_MONTHS[match[2].toLocaleLowerCase('ru')];
54
+ if (month == null) return null;
55
+ const day = Number(match[1]);
56
+ let time = Date.UTC(now.getUTCFullYear(), month, day, 12);
57
+ if (time > now.getTime() + 48 * 60 * 60 * 1000) time = Date.UTC(now.getUTCFullYear() - 1, month, day, 12);
58
+ return new Date(time).toISOString();
59
+ }
60
+
61
+ const DEADLINE_MARKER_RE = /(?:application\s+deadline|apply\s+by|closing\s+date|deadline|дедлайн|срок(?:\s+подачи)?|термін(?:\s+подання)?)[\s:–—-]{0,8}([^.;\n]{3,55})/iu;
62
+ const DEADLINE_DATE_RE = /\b(?:\d{4}-\d{2}-\d{2}|\d{1,2}[./-]\d{1,2}[./-]\d{2,4}|\d{1,2}\s+(?:jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|jun(?:e)?|jul(?:y)?|aug(?:ust)?|sep(?:tember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?|янв\p{L}*|фев\p{L}*|мар\p{L}*|апр\p{L}*|ма[йя]|июн\p{L}*|июл\p{L}*|авг\p{L}*|сен\p{L}*|окт\p{L}*|ноя\p{L}*|дек\p{L}*)\.?\s+\d{2,4})\b/iu;
63
+
64
+ export function extractHiringDeadline(value) {
65
+ const marker = DEADLINE_MARKER_RE.exec(String(value || ''));
66
+ return marker?.[1]?.match(DEADLINE_DATE_RE)?.[0]?.trim() || null;
67
+ }
@@ -1,5 +1,5 @@
1
- export type HiringEducation = 'doctorate' | 'master' | 'bachelor' | 'higher' | 'secondary';
2
- export type HiringApplicationLanguage = 'English' | 'Russian' | 'Ukrainian' | 'Uzbek' | 'Kazakh' | 'Romanian';
3
-
4
- export function detectHiringEducation(value: unknown): HiringEducation | null;
5
- export function detectApplicationLanguage(value: unknown): HiringApplicationLanguage | null;
1
+ export type HiringEducation = 'doctorate' | 'master' | 'bachelor' | 'higher' | 'secondary';
2
+ export type HiringApplicationLanguage = 'English' | 'Russian' | 'Ukrainian' | 'Uzbek' | 'Kazakh' | 'Romanian';
3
+
4
+ export function detectHiringEducation(value: unknown): HiringEducation | null;
5
+ export function detectApplicationLanguage(value: unknown): HiringApplicationLanguage | null;
@@ -1,23 +1,23 @@
1
- import { detectDegreeLevel } from './hiring-requirements.js';
2
-
3
- export function detectHiringEducation(value) {
4
- const text = String(value || '');
5
- const degree = detectDegreeLevel(text);
6
- if (degree) return degree;
7
- if (/higher education|высшее образование|вища освіта|олий маълумот/iu.test(text)) return 'higher';
8
- return null;
9
- }
10
-
11
- export function detectApplicationLanguage(value) {
12
- const text = String(value || '');
13
- const match = /(?:submit|send|provide|отправ\p{L}*|пришл\p{L}*|направ\p{L}*|подай\p{L}*|надішл\p{L}*)[^.;\n]{0,35}(?:application|resume|résumé|cv|резюме)[^.;\n]{0,20}[^\p{L}\p{N}](?:in|на|у|в)\s+(english|russian|ukrainian|uzbek|kazakh|romanian|английском|русском|украинском|українською|українській|узбекском|казахском|румынском)(?![\p{L}\p{N}])/iu.exec(text);
14
- if (!match?.[1]) return null;
15
- const language = match[1].toLowerCase();
16
- if (/english|англий/.test(language)) return 'English';
17
- if (/russian|русск/.test(language)) return 'Russian';
18
- if (/ukrain|укра/.test(language)) return 'Ukrainian';
19
- if (/uzbek|узбек/.test(language)) return 'Uzbek';
20
- if (/kazakh|казах/.test(language)) return 'Kazakh';
21
- if (/romanian|румын/.test(language)) return 'Romanian';
22
- return null;
23
- }
1
+ import { detectDegreeLevel } from './hiring-requirements.js';
2
+
3
+ export function detectHiringEducation(value) {
4
+ const text = String(value || '');
5
+ const degree = detectDegreeLevel(text);
6
+ if (degree) return degree;
7
+ if (/higher education|высшее образование|вища освіта|олий маълумот/iu.test(text)) return 'higher';
8
+ return null;
9
+ }
10
+
11
+ export function detectApplicationLanguage(value) {
12
+ const text = String(value || '');
13
+ const match = /(?:submit|send|provide|отправ\p{L}*|пришл\p{L}*|направ\p{L}*|подай\p{L}*|надішл\p{L}*)[^.;\n]{0,35}(?:application|resume|résumé|cv|резюме)[^.;\n]{0,20}[^\p{L}\p{N}](?:in|на|у|в)\s+(english|russian|ukrainian|uzbek|kazakh|romanian|английском|русском|украинском|українською|українській|узбекском|казахском|румынском)(?![\p{L}\p{N}])/iu.exec(text);
14
+ if (!match?.[1]) return null;
15
+ const language = match[1].toLowerCase();
16
+ if (/english|англий/.test(language)) return 'English';
17
+ if (/russian|русск/.test(language)) return 'Russian';
18
+ if (/ukrain|укра/.test(language)) return 'Ukrainian';
19
+ if (/uzbek|узбек/.test(language)) return 'Uzbek';
20
+ if (/kazakh|казах/.test(language)) return 'Kazakh';
21
+ if (/romanian|румын/.test(language)) return 'Romanian';
22
+ return null;
23
+ }
@@ -1,34 +1,34 @@
1
- export type HiringEmploymentType =
2
- | 'full_time'
3
- | 'part_time'
4
- | 'contract'
5
- | 'project'
6
- | 'freelance'
7
- | 'temporary'
8
- | 'internship'
9
- | 'volunteer'
10
- | 'seasonal';
11
-
12
- export type HiringWorkMode = 'remote' | 'hybrid' | 'onsite';
13
-
14
- export type HiringWorkSchedule =
15
- | 'fiveTwo'
16
- | 'twoTwo'
17
- | 'sixOne'
18
- | 'threeThree'
19
- | 'oneThree'
20
- | 'twentyFourFortyEight'
21
- | 'shift'
22
- | 'flexible'
23
- | 'day'
24
- | 'night'
25
- | 'rotational';
26
-
27
- export type HiringProbationKind = 'probation' | 'noProbation' | 'paidProbation' | 'unpaidProbation';
28
- export type HiringExperienceRequirement = 'noExperience' | 'experienceRequired';
29
-
30
- export function detectEmploymentTypes(value: unknown): readonly HiringEmploymentType[];
31
- export function detectWorkModes(value: unknown): readonly HiringWorkMode[];
32
- export function detectWorkSchedules(value: unknown): readonly HiringWorkSchedule[];
33
- export function detectProbation(value: unknown): HiringProbationKind | null;
34
- export function detectExperienceRequirement(value: unknown): HiringExperienceRequirement | null;
1
+ export type HiringEmploymentType =
2
+ | 'full_time'
3
+ | 'part_time'
4
+ | 'contract'
5
+ | 'project'
6
+ | 'freelance'
7
+ | 'temporary'
8
+ | 'internship'
9
+ | 'volunteer'
10
+ | 'seasonal';
11
+
12
+ export type HiringWorkMode = 'remote' | 'hybrid' | 'onsite';
13
+
14
+ export type HiringWorkSchedule =
15
+ | 'fiveTwo'
16
+ | 'twoTwo'
17
+ | 'sixOne'
18
+ | 'threeThree'
19
+ | 'oneThree'
20
+ | 'twentyFourFortyEight'
21
+ | 'shift'
22
+ | 'flexible'
23
+ | 'day'
24
+ | 'night'
25
+ | 'rotational';
26
+
27
+ export type HiringProbationKind = 'probation' | 'noProbation' | 'paidProbation' | 'unpaidProbation';
28
+ export type HiringExperienceRequirement = 'noExperience' | 'experienceRequired';
29
+
30
+ export function detectEmploymentTypes(value: unknown): readonly HiringEmploymentType[];
31
+ export function detectWorkModes(value: unknown): readonly HiringWorkMode[];
32
+ export function detectWorkSchedules(value: unknown): readonly HiringWorkSchedule[];
33
+ export function detectProbation(value: unknown): HiringProbationKind | null;
34
+ export function detectExperienceRequirement(value: unknown): HiringExperienceRequirement | null;
@@ -1,72 +1,72 @@
1
- import { findCanonical } from './normalization.js';
2
- import {
3
- EMPLOYMENT_TYPES,
4
- EXPERIENCE_REQUIREMENTS,
5
- PROBATION_TERMS,
6
- SCHEDULE_TERMS,
7
- WORK_MODES,
8
- } from './hiring.js';
9
- import { parseExperience, WORK_SCHEDULE_EXTENSIONS } from './hiring-advanced.js';
10
-
11
- const EMPLOYMENT_OUTPUT = Object.freeze({
12
- fullTime: 'full_time',
13
- partTime: 'part_time',
14
- contract: 'contract',
15
- project: 'project',
16
- freelance: 'freelance',
17
- temporary: 'temporary',
18
- internship: 'internship',
19
- volunteer: 'volunteer',
20
- seasonal: 'seasonal',
21
- });
22
-
23
- const PROBATION_MATCH_ORDER = Object.freeze([
24
- PROBATION_TERMS.paid,
25
- PROBATION_TERMS.unpaid,
26
- PROBATION_TERMS.noProbation,
27
- PROBATION_TERMS.probation,
28
- ]);
29
-
30
- function collectCanonical(text, entries) {
31
- const values = [];
32
- for (const entry of entries) {
33
- if (!findCanonical(text, [entry], { partial: true })) continue;
34
- if (!values.includes(entry.canonical)) values.push(entry.canonical);
35
- }
36
- return values;
37
- }
38
-
39
- export function detectEmploymentTypes(value) {
40
- return Object.freeze(
41
- collectCanonical(String(value || ''), EMPLOYMENT_TYPES)
42
- .map((canonical) => EMPLOYMENT_OUTPUT[canonical])
43
- .filter(Boolean),
44
- );
45
- }
46
-
47
- export function detectWorkModes(value) {
48
- return Object.freeze(collectCanonical(String(value || ''), WORK_MODES));
49
- }
50
-
51
- export function detectWorkSchedules(value) {
52
- return Object.freeze(collectCanonical(String(value || ''), [...SCHEDULE_TERMS, ...WORK_SCHEDULE_EXTENSIONS]));
53
- }
54
-
55
- export function detectProbation(value) {
56
- const text = String(value || '');
57
- for (const entry of PROBATION_MATCH_ORDER) {
58
- if (findCanonical(text, [entry], { partial: true })) return entry.canonical;
59
- }
60
- return null;
61
- }
62
-
63
- export function detectExperienceRequirement(value) {
64
- const text = String(value || '');
65
- const parsed = parseExperience(text);
66
- if (parsed?.requirement === 'none') return 'noExperience';
67
- if (parsed?.requirement === 'required') return 'experienceRequired';
68
- for (const entry of Object.values(EXPERIENCE_REQUIREMENTS)) {
69
- if (findCanonical(text, [entry], { partial: true })) return entry.canonical;
70
- }
71
- return null;
72
- }
1
+ import { findCanonical } from './normalization.js';
2
+ import {
3
+ EMPLOYMENT_TYPES,
4
+ EXPERIENCE_REQUIREMENTS,
5
+ PROBATION_TERMS,
6
+ SCHEDULE_TERMS,
7
+ WORK_MODES,
8
+ } from './hiring.js';
9
+ import { parseExperience, WORK_SCHEDULE_EXTENSIONS } from './hiring-advanced.js';
10
+
11
+ const EMPLOYMENT_OUTPUT = Object.freeze({
12
+ fullTime: 'full_time',
13
+ partTime: 'part_time',
14
+ contract: 'contract',
15
+ project: 'project',
16
+ freelance: 'freelance',
17
+ temporary: 'temporary',
18
+ internship: 'internship',
19
+ volunteer: 'volunteer',
20
+ seasonal: 'seasonal',
21
+ });
22
+
23
+ const PROBATION_MATCH_ORDER = Object.freeze([
24
+ PROBATION_TERMS.paid,
25
+ PROBATION_TERMS.unpaid,
26
+ PROBATION_TERMS.noProbation,
27
+ PROBATION_TERMS.probation,
28
+ ]);
29
+
30
+ function collectCanonical(text, entries) {
31
+ const values = [];
32
+ for (const entry of entries) {
33
+ if (!findCanonical(text, [entry], { partial: true })) continue;
34
+ if (!values.includes(entry.canonical)) values.push(entry.canonical);
35
+ }
36
+ return values;
37
+ }
38
+
39
+ export function detectEmploymentTypes(value) {
40
+ return Object.freeze(
41
+ collectCanonical(String(value || ''), EMPLOYMENT_TYPES)
42
+ .map((canonical) => EMPLOYMENT_OUTPUT[canonical])
43
+ .filter(Boolean),
44
+ );
45
+ }
46
+
47
+ export function detectWorkModes(value) {
48
+ return Object.freeze(collectCanonical(String(value || ''), WORK_MODES));
49
+ }
50
+
51
+ export function detectWorkSchedules(value) {
52
+ return Object.freeze(collectCanonical(String(value || ''), [...SCHEDULE_TERMS, ...WORK_SCHEDULE_EXTENSIONS]));
53
+ }
54
+
55
+ export function detectProbation(value) {
56
+ const text = String(value || '');
57
+ for (const entry of PROBATION_MATCH_ORDER) {
58
+ if (findCanonical(text, [entry], { partial: true })) return entry.canonical;
59
+ }
60
+ return null;
61
+ }
62
+
63
+ export function detectExperienceRequirement(value) {
64
+ const text = String(value || '');
65
+ const parsed = parseExperience(text);
66
+ if (parsed?.requirement === 'none') return 'noExperience';
67
+ if (parsed?.requirement === 'required') return 'experienceRequired';
68
+ for (const entry of Object.values(EXPERIENCE_REQUIREMENTS)) {
69
+ if (findCanonical(text, [entry], { partial: true })) return entry.canonical;
70
+ }
71
+ return null;
72
+ }