@whiteslove/parsing-lexicon 0.7.5 → 0.7.6
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/package.json +1 -1
- package/src/hiring-ats.d.ts +1 -1
- package/src/hiring-ats.js +4 -1
- package/src/hiring-requirements.js +1 -1
package/package.json
CHANGED
package/src/hiring-ats.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HiringSeniority, DegreeLevel, DegreeField } from './hiring-requirements.js';
|
|
2
2
|
export type HiringAtsProfile = Readonly<{ raw: string; skills: Set<string>; skillEvidence: Map<string, number>; terms?: Set<string>; experienceYears?: number; seniority?: HiringSeniority; degreeLevel?: DegreeLevel; degreeFields: Set<DegreeField>; requiresUsSponsorship?: boolean }>;
|
|
3
|
-
export type HiringAtsJob = Readonly<{ title: string; description?: string; tags?: string[]; skills?: string[]; niceToHave?: string[]; experienceMinYears?: number; seniority?: string | null; education?: string; country?: string; location?: string }>;
|
|
3
|
+
export type HiringAtsJob = Readonly<{ title: string; description?: string; tags?: string[]; skills?: string[]; niceToHave?: string[]; experienceMinYears?: number; seniority?: string | null; education?: string; country?: string; location?: string; sponsorshipEvidence?: string[] }>;
|
|
4
4
|
export function buildHiringAtsProfile(cvText: unknown, options?: { fuzzySkills?: boolean; referenceDate?: Date }): HiringAtsProfile;
|
|
5
5
|
export function scoreHiringAts(profileOrCv: HiringAtsProfile | string, job: HiringAtsJob, options?: { fuzzySkills?: boolean; referenceDate?: Date }): Readonly<{ score: number; fitScore: number; eligible: boolean; blockers: readonly { code: string; label: string; critical: boolean }[]; breakdown: Readonly<{ skills: number; experience: number; seniority: number; scope: number; education: number; relevance: number }>; matched: readonly string[]; missing: readonly string[] }>;
|
|
6
6
|
export function hiringAtsScoreColor(score: number): string;
|
package/src/hiring-ats.js
CHANGED
|
@@ -137,7 +137,10 @@ export function scoreHiringAts(profileOrCv, job, options = {}) {
|
|
|
137
137
|
const relevance = extractTerms(keywordSource).size ? Math.round(coverage(profile.terms || extractTerms(profile.raw), extractTerms(keywordSource)) * 100) : 60;
|
|
138
138
|
const breakdown = Object.freeze({ skills, experience: experience.score, seniority: seniority.score, scope: scope.score, education: education.score, relevance });
|
|
139
139
|
let fitScore = Math.round(skills * .30 + experience.score * .20 + seniority.score * .20 + scope.score * .15 + education.score * .10 + relevance * .05);
|
|
140
|
-
|
|
140
|
+
// Source-specific ATS ingestion can supply the wording that established a
|
|
141
|
+
// sponsorship policy separately from the rendered description. It remains
|
|
142
|
+
// input evidence, not consumer-side parsing logic.
|
|
143
|
+
const usText = `${job?.location || ''} ${title} ${description} ${tagText} ${(job?.sponsorshipEvidence || []).join(' ')}`;
|
|
141
144
|
const visaBlocked = (job?.country || '').toUpperCase() === 'US' || detectCountryCodeFromText(usText) === 'US'
|
|
142
145
|
? profile.requiresUsSponsorship === true && isNoSponsorshipRequirement(usText) : false;
|
|
143
146
|
const blockers = visaBlocked ? [Object.freeze({ code: 'visa_sponsorship', label: 'Visa sponsorship unavailable', critical: true })] : [];
|
|
@@ -72,7 +72,7 @@ export function requiresUsSponsorship(value) {
|
|
|
72
72
|
|
|
73
73
|
export function isNoSponsorshipRequirement(value) {
|
|
74
74
|
const text = String(value || '');
|
|
75
|
-
return /(?:\bno\s+(?:visa\s+|immigration\s+|employment\s+)?sponsorship\b|\b(?:will\s+not|cannot|can't|unable\s+to|not\s+able\s+to)\s+sponsor\b|\bwithout\s+(?:the\s+need\s+for\s+)?(?:current\s+or\s+future\s+)?(?:employer\s+|visa\s+)?sponsorship\b|\bmust\s+(?:be\s+)?(?:legally\s+)?authoriz\w+\s+to\s+work[^.!?]{0,100}\bwithout\s+(?:current\s+or\s+future\s+)?sponsorship\b|\bsponsorship\s+(?:is\s+)?not\s+(?:available|provided|offered)\b|\bmay\s+not\s+be\s+able\s+to\b[^\n!?]{0,450}\b(?:sponsor|support|provide)\b[^\n!?]{0,180}\bsponsorship\b|\b(?:will|can|may)\s+not\b[^\n!?]{0,220}\b(?:sponsor|support|provide)\b[^\n!?]{0,160}\bsponsorship\b|\bnot\s+(?:currently\s+)?(?:able\s+to\s+)?(?:sponsor|support|provide)\b[^\n!?]{0,160}\bsponsorship\b)/i.test(text);
|
|
75
|
+
return /(?:\bno\s+(?:visa\s+|immigration\s+|employment\s+)?sponsorship\b|\b(?:will\s+not|cannot|can't|unable\s+to|not\s+able\s+to)\s+sponsor\b|\b(?:does|do)\s+not\s+(?:offer|provide|support)\s+(?:current\s+or\s+future\s+)?(?:visa\s+|employment\s+)?sponsorship\b|\bwithout\s+(?:the\s+need\s+for\s+)?(?:current\s+or\s+future\s+)?(?:employer\s+|visa\s+)?sponsorship\b|\bmust\s+(?:be\s+)?(?:legally\s+)?authoriz\w+\s+to\s+work[^.!?]{0,100}\bwithout\s+(?:current\s+or\s+future\s+)?sponsorship\b|\bsponsorship\s+(?:is\s+)?not\s+(?:available|provided|offered)\b|\bmay\s+not\s+be\s+able\s+to\b[^\n!?]{0,450}\b(?:sponsor|support|provide)\b[^\n!?]{0,180}\bsponsorship\b|\b(?:will|can|may)\s+not\b[^\n!?]{0,220}\b(?:sponsor|support|provide)\b[^\n!?]{0,160}\bsponsorship\b|\bnot\s+(?:currently\s+)?(?:able\s+to\s+)?(?:sponsor|support|provide)\b[^\n!?]{0,160}\bsponsorship\b)/i.test(text);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
const REQUIRED_MARKER_RE = /\b(requirements?|qualifications?|minimum qualifications?|required skills?|must[- ]?have|you have|what (?:we|you) (?:are looking for|need|bring)|you(?:'|’)ll need|who you are|ideal candidate|what makes you a fit)\b|требован|квалификац|обязательн|необходим(?:о|ые|ый)|что мы (?:жд[её]м|ожидаем)|кого мы ищем|вимог|кваліфікац|обов['’]?язков|необхідн|кого ми шукаємо/i;
|