resume-parser-ats 1.1.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.
@@ -0,0 +1,608 @@
1
+ "use strict";
2
+ /**
3
+ * Step 1–4: Resume Parsing Engine
4
+ *
5
+ * Implements the full OpenResume algorithm:
6
+ * Step 1: Read text items from PDF
7
+ * Step 2: Group text items into lines
8
+ * Step 3: Group lines into sections
9
+ * Step 4: Extract resume attributes from sections via feature scoring
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.extractTextItemsFromPDF = extractTextItemsFromPDF;
49
+ exports.extractTextItemsFromRawText = extractTextItemsFromRawText;
50
+ exports.groupTextItemsIntoLines = groupTextItemsIntoLines;
51
+ exports.groupLinesIntoSections = groupLinesIntoSections;
52
+ exports.parseResume = parseResume;
53
+ const fs_1 = __importDefault(require("fs"));
54
+ // ---------------------------------------------------------------------------
55
+ // Step 1: Read text items from PDF
56
+ // ---------------------------------------------------------------------------
57
+ /**
58
+ * Extract text items from raw resume text (simplified version).
59
+ *
60
+ * In a full implementation this would use pdfjs-dist to extract
61
+ * text items with position, bold, and newline metadata from a PDF.
62
+ * Here we simulate the extraction from raw text input.
63
+ */
64
+ async function extractTextItemsFromPDF(filePath) {
65
+ const warnings = [];
66
+ try {
67
+ // In production: use pdfjs-dist to read the PDF and extract text items
68
+ // with (x1, x2, y, bold, newLine) metadata.
69
+ //
70
+ // const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.js");
71
+ // const doc = await pdfjsLib.getDocument(filePath).promise;
72
+ // ... iterate pages, get textContent, map to TextItem[]
73
+ //
74
+ // For now we fall back to a simplified extraction:
75
+ const fs = await Promise.resolve().then(() => __importStar(require("fs")));
76
+ const pdfBuffer = fs.readFileSync(filePath);
77
+ // Attempt to extract text from the PDF buffer using a simple approach.
78
+ // The full implementation should use pdfjs-dist for accurate positioning.
79
+ const text = pdfBuffer.toString("latin1");
80
+ // Extract readable text portions (simplified heuristic)
81
+ const textItems = [];
82
+ const lines = text
83
+ .split(/[\r\n]+/)
84
+ .filter((l) => l.trim().length > 0);
85
+ let y = 800;
86
+ for (const line of lines) {
87
+ const cleanLine = line.replace(/[^\x20-\x7E]/g, "").trim();
88
+ if (cleanLine.length === 0)
89
+ continue;
90
+ // Determine if line is likely a section header
91
+ const isBold = /^[A-Z\s/&]+$/.test(cleanLine) && cleanLine.length < 40;
92
+ const isSectionTitle = isBold && cleanLine.length > 2;
93
+ textItems.push({
94
+ text: cleanLine,
95
+ x1: 36,
96
+ x2: 36 + cleanLine.length * 5,
97
+ y: y,
98
+ bold: isSectionTitle,
99
+ newLine: true,
100
+ });
101
+ y -= 14;
102
+ }
103
+ if (textItems.length === 0) {
104
+ warnings.push("Could not extract any text items from the PDF. The file may be image-based or corrupted.");
105
+ }
106
+ return { items: textItems, warnings };
107
+ }
108
+ catch (error) {
109
+ const message = error instanceof Error ? error.message : String(error);
110
+ warnings.push(`Error reading PDF: ${message}`);
111
+ return { items: [], warnings };
112
+ }
113
+ }
114
+ /**
115
+ * Fallback: parse text items from raw text input
116
+ *
117
+ * Heuristics for determining bold/section-title:
118
+ * 1. Known section headers (EDUCATION, EXPERIENCE, etc.) → bold + section title
119
+ * 2. Short ALL-CAPS lines (≤ 40 chars) → bold (but NOT a section title if
120
+ * they look like a name — i.e., only letters, spaces, periods, and → )
121
+ * 3. First non-empty line is treated as the candidate name → bold, NOT section title
122
+ */
123
+ function extractTextItemsFromRawText(rawText) {
124
+ const lines = rawText.split(/\n/);
125
+ const items = [];
126
+ let y = 800;
127
+ // Detect which line is likely the name (first non-empty line that is NOT a section title)
128
+ let firstNameLine = null;
129
+ for (const line of lines) {
130
+ const trimmed = line.trim();
131
+ if (trimmed.length === 0)
132
+ continue;
133
+ if (!SECTION_TITLE_KEYWORDS.includes(trimmed.toUpperCase())) {
134
+ firstNameLine = trimmed;
135
+ break;
136
+ }
137
+ }
138
+ for (const line of lines) {
139
+ const trimmed = line.trim();
140
+ if (trimmed.length === 0)
141
+ continue;
142
+ const upperTrimmed = trimmed.toUpperCase();
143
+ const isKnownSection = SECTION_TITLE_KEYWORDS.includes(upperTrimmed);
144
+ const isAllCapsShort = /^[A-Z\s/&]+$/.test(trimmed) && trimmed.length <= 40 && trimmed.length > 2;
145
+ const looksLikeName = /^[A-Z][a-zA-Z\s\.]+$/.test(trimmed) && trimmed.length > 2 && trimmed.length < 50;
146
+ const isFirstName = firstNameLine !== null && trimmed === firstNameLine;
147
+ // Determine bold and section-title flags
148
+ let bold = false;
149
+ if (isKnownSection) {
150
+ // Known section headers are always section titles
151
+ bold = true;
152
+ }
153
+ else if (isAllCapsShort && !looksLikeName && !isFirstName) {
154
+ // Short ALL-CAPS that don't look like names → bold, section title
155
+ bold = true;
156
+ }
157
+ else if (isFirstName && looksLikeName) {
158
+ // First line that looks like a name → bold, NOT a section title
159
+ bold = true;
160
+ }
161
+ else if (isAllCapsShort) {
162
+ // Could be a name in all caps — bold but not a section title
163
+ bold = true;
164
+ }
165
+ items.push({
166
+ text: trimmed,
167
+ x1: 36,
168
+ x2: 36 + trimmed.length * 5,
169
+ y,
170
+ bold,
171
+ newLine: true,
172
+ });
173
+ y -= 14;
174
+ }
175
+ return items;
176
+ }
177
+ // ---------------------------------------------------------------------------
178
+ // Step 2: Group text items into lines
179
+ // ---------------------------------------------------------------------------
180
+ /**
181
+ * Merge adjacent text items on the same Y-coordinate if their horizontal
182
+ * distance is smaller than the average character width.
183
+ */
184
+ function groupTextItemsIntoLines(items) {
185
+ if (items.length === 0)
186
+ return [];
187
+ // Calculate average character width
188
+ const charWidthItems = items.filter((i) => !i.bold && i.text.trim().length > 0);
189
+ let totalWidth = 0;
190
+ let totalChars = 0;
191
+ for (const item of charWidthItems) {
192
+ totalWidth += item.x2 - item.x1;
193
+ totalChars += item.text.length;
194
+ }
195
+ const avgCharWidth = totalChars > 0 ? totalWidth / totalChars : 5;
196
+ // Group items by Y-coordinate (same line)
197
+ const yGroups = new Map();
198
+ const yTolerance = 3; // Pixels tolerance for same line
199
+ const sortedItems = [...items].sort((a, b) => b.y - a.y); // Top to bottom
200
+ const yKeys = [];
201
+ for (const item of sortedItems) {
202
+ let matched = false;
203
+ for (const key of yKeys) {
204
+ if (Math.abs(item.y - key) <= yTolerance) {
205
+ yGroups.get(key).push(item);
206
+ matched = true;
207
+ break;
208
+ }
209
+ }
210
+ if (!matched) {
211
+ yKeys.push(item.y);
212
+ yGroups.set(item.y, [item]);
213
+ }
214
+ }
215
+ // Sort groups by Y (top to bottom)
216
+ yKeys.sort((a, b) => b - a);
217
+ const lines = [];
218
+ for (const yKey of yKeys) {
219
+ const groupItems = yGroups.get(yKey);
220
+ // Sort items left to right
221
+ groupItems.sort((a, b) => a.x1 - b.x1);
222
+ // Merge adjacent items
223
+ const merged = [];
224
+ for (const item of groupItems) {
225
+ if (merged.length === 0) {
226
+ merged.push({ ...item });
227
+ continue;
228
+ }
229
+ const prev = merged[merged.length - 1];
230
+ const distance = item.x1 - prev.x2;
231
+ if (distance < avgCharWidth && !item.newLine) {
232
+ // Merge with previous item
233
+ prev.text += item.text;
234
+ prev.x2 = item.x2;
235
+ }
236
+ else {
237
+ // Add separator and new item
238
+ merged.push({ ...item });
239
+ }
240
+ }
241
+ const lineText = merged.map((i) => i.text).join(" ").trim();
242
+ lines.push({
243
+ lineNumber: lines.length + 1,
244
+ text: lineText,
245
+ items: merged,
246
+ y: yKey,
247
+ });
248
+ }
249
+ return lines;
250
+ }
251
+ // ---------------------------------------------------------------------------
252
+ // Step 3: Group lines into sections
253
+ // ---------------------------------------------------------------------------
254
+ /** Known section title keywords for fallback heuristic */
255
+ const SECTION_TITLE_KEYWORDS = [
256
+ "PROFILE", "SUMMARY", "OBJECTIVE", "ABOUT", "ABOUT ME",
257
+ "EDUCATION", "ACADEMIC", "DEGREES", "ACADEMICS",
258
+ "EXPERIENCE", "WORK EXPERIENCE", "EMPLOYMENT", "PROFESSIONAL EXPERIENCE",
259
+ "WORK HISTORY", "CAREER HISTORY",
260
+ "SKILLS", "TECHNICAL SKILLS", "COMPETENCIES", "AREAS OF EXPERTISE",
261
+ "PROJECTS", "PORTFOLIO", "PERSONAL PROJECTS",
262
+ "CERTIFICATIONS", "LICENSES", "HONORS", "AWARDS", "HONORS & AWARDS",
263
+ "VOLUNTEER", "VOLUNTEER EXPERIENCE", "COMMUNITY", "COMMUNITY SERVICE",
264
+ "LEADERSHIP", "LEADERSHIP EXPERIENCE",
265
+ "PUBLICATIONS", "RESEARCH", "RESEARCH EXPERIENCE",
266
+ "INTERESTS", "ACTIVITIES", "HOBBIES", "EXTRACURRICULAR",
267
+ "LANGUAGES", "REFERENCES",
268
+ ];
269
+ /**
270
+ * Determine if a line is a section title.
271
+ * Primary heuristic: only text item, bold, all UPPERCASE.
272
+ * Fallback heuristic: keyword match.
273
+ */
274
+ function isSectionTitle(line) {
275
+ const text = line.text.trim();
276
+ const upperText = text.toUpperCase();
277
+ // Fallback heuristic first: exact keyword match (handles raw-text case cleanly)
278
+ const cleanUpper = upperText.replace(/[^A-Z\s/&]/g, "").trim();
279
+ if (SECTION_TITLE_KEYWORDS.includes(cleanUpper)) {
280
+ return true;
281
+ }
282
+ // Primary heuristic: only text item, bold, all UPPERCASE
283
+ // But exclude names — "Leo Leopard" etc. should NOT be detected as section titles
284
+ if (line.items.length === 1 && line.items[0].bold && /^[A-Z\s/&]+$/.test(text)) {
285
+ // If it looks like a name (mixed case or typical name pattern), it's not a section title
286
+ if (/^[A-Z][a-zA-Z\s\.]+$/.test(text) && text.length < 50) {
287
+ return false;
288
+ }
289
+ return true;
290
+ }
291
+ return false;
292
+ }
293
+ /**
294
+ * Group lines into sections based on section titles.
295
+ */
296
+ function groupLinesIntoSections(lines) {
297
+ if (lines.length === 0)
298
+ return [];
299
+ const sections = [];
300
+ let currentSection = { title: "PROFILE", lines: [] };
301
+ for (const line of lines) {
302
+ if (isSectionTitle(line)) {
303
+ // Save the current section if it has lines
304
+ if (currentSection.lines.length > 0) {
305
+ sections.push(currentSection);
306
+ }
307
+ currentSection = { title: line.text.trim().toUpperCase(), lines: [] };
308
+ }
309
+ else {
310
+ currentSection.lines.push(line);
311
+ }
312
+ }
313
+ // Push the last section
314
+ if (currentSection.lines.length > 0) {
315
+ sections.push(currentSection);
316
+ }
317
+ return sections;
318
+ }
319
+ // --- Profile feature sets ---
320
+ const NAME_FEATURE_SETS = [
321
+ { match: (text) => /^[a-zA-Z\s\.]+$/.test(text), score: 3 },
322
+ { match: (_text, item) => item.bold, score: 2 },
323
+ { match: (text) => text === text.toUpperCase() && /[A-Z]/.test(text), score: 2 },
324
+ { match: (text) => text.includes("@"), score: -4 },
325
+ { match: (text) => /\d/.test(text), score: -4 },
326
+ { match: (text) => text.includes(","), score: -4 },
327
+ { match: (text) => text.includes("/"), score: -4 },
328
+ ];
329
+ const EMAIL_FEATURE_SETS = [
330
+ { match: (text) => /\S+@\S+\.\S+/.test(text), score: 4 },
331
+ { match: (text) => /^[a-zA-Z\s\.]+$/.test(text) && !text.includes("@"), score: -1 },
332
+ { match: (text) => /\d/.test(text) && !text.includes("@"), score: -2 },
333
+ { match: (text) => text.includes("@"), score: 4 },
334
+ ];
335
+ const PHONE_FEATURE_SETS = [
336
+ { match: (text) => /\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}/.test(text), score: 4 },
337
+ { match: (text) => /^[a-zA-Z\s\.]+$/.test(text), score: -4 },
338
+ { match: (text) => text.includes("@"), score: -4 },
339
+ { match: (text) => /\d/.test(text) && !/\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}/.test(text), score: -1 },
340
+ ];
341
+ const LOCATION_FEATURE_SETS = [
342
+ { match: (text) => /[A-Z][a-zA-Z\s]+,\s*[A-Z]{2}/.test(text), score: 4 },
343
+ { match: (text) => text.includes("@"), score: -4 },
344
+ { match: (text) => !text.includes(","), score: -2 },
345
+ ];
346
+ const URL_FEATURE_SETS = [
347
+ { match: (text) => /\S+\.[a-z]+\/\S+/.test(text), score: 4 },
348
+ { match: (text) => /https?:\/\//i.test(text), score: 4 },
349
+ { match: (text) => /linkedin\.com/i.test(text), score: 4 },
350
+ { match: (text) => /github\.com/i.test(text), score: 4 },
351
+ { match: (text) => /^[a-zA-Z\s\.]+$/.test(text), score: -4 },
352
+ ];
353
+ // --- Education / Experience feature sets ---
354
+ const SCHOOL_KEYWORDS = /college|university|school|institute|academy|faculty/i;
355
+ const DEGREE_KEYWORDS = /associate|bachelor|master|doctorate|b\.s\.|b\.a\.|m\.s\.|m\.a\.|ph\.d|bsc|msc|ba|ma|mba|bs|ms/i;
356
+ const GPA_REGEX = /[0-4]\.\d{1,2}/;
357
+ const DATE_REGEX = /(?:19|20)\d{2}/;
358
+ const JOB_TITLE_KEYWORDS = /analyst|engineer|intern|manager|developer|coordinator|director|associate|consultant|specialist|lead|architect|designer|administrator|assistant|officer|executive|president|vice|chief|head|supervisor|technician|clerk|trainee|volunteer/i;
359
+ // --- Feature scoring function ---
360
+ function computeFeatureScore(text, item, featureSets) {
361
+ let totalScore = 0;
362
+ for (const fs of featureSets) {
363
+ if (fs.match(text, item)) {
364
+ totalScore += fs.score;
365
+ }
366
+ }
367
+ return totalScore;
368
+ }
369
+ /**
370
+ * From a list of text items, find the one with the highest feature score
371
+ * for a given set of feature sets.
372
+ */
373
+ function extractBestMatch(items, featureSets) {
374
+ let bestScore = -Infinity;
375
+ let bestText = null;
376
+ for (const item of items) {
377
+ const text = item.text.trim();
378
+ if (text.length === 0)
379
+ continue;
380
+ const score = computeFeatureScore(text, item, featureSets);
381
+ if (score > bestScore) {
382
+ bestScore = score;
383
+ bestText = text;
384
+ }
385
+ }
386
+ return bestScore > 0 ? bestText : null;
387
+ }
388
+ // --- Subsection detection ---
389
+ /**
390
+ * Detect subsection boundaries within a section.
391
+ * Primary: vertical line gap > typical line gap × 1.4
392
+ * Fallback: text item is bolded
393
+ */
394
+ function detectSubsections(section) {
395
+ const { lines } = section;
396
+ if (lines.length === 0)
397
+ return [];
398
+ // Calculate typical line gap
399
+ const gaps = [];
400
+ for (let i = 1; i < lines.length; i++) {
401
+ gaps.push(Math.abs(lines[i].y - lines[i - 1].y));
402
+ }
403
+ const typicalGap = gaps.length > 0
404
+ ? gaps.sort((a, b) => a - b)[Math.floor(gaps.length / 2)]
405
+ : 14;
406
+ const subsectionGapThreshold = typicalGap * 1.4;
407
+ // Split lines into subsections
408
+ const subsections = [];
409
+ let currentSubsection = [lines[0]];
410
+ for (let i = 1; i < lines.length; i++) {
411
+ const gap = Math.abs(lines[i].y - lines[i - 1].y);
412
+ const isBoldStart = lines[i].items.some((item) => item.bold);
413
+ if (gap > subsectionGapThreshold || (isBoldStart && currentSubsection.length > 1)) {
414
+ subsections.push(currentSubsection);
415
+ currentSubsection = [lines[i]];
416
+ }
417
+ else {
418
+ currentSubsection.push(lines[i]);
419
+ }
420
+ }
421
+ subsections.push(currentSubsection);
422
+ return subsections;
423
+ }
424
+ // --- Section-specific extractors ---
425
+ function extractProfile(sections) {
426
+ const profileSection = sections.find((s) => s.title === "PROFILE");
427
+ if (!profileSection) {
428
+ // Try SUMMARY or OBJECTIVE
429
+ const fallback = sections.find((s) => ["SUMMARY", "OBJECTIVE", "ABOUT"].includes(s.title));
430
+ if (fallback) {
431
+ return extractProfileFromSection(fallback);
432
+ }
433
+ return { name: null, email: null, phone: null, location: null, url: null, summary: null };
434
+ }
435
+ return extractProfileFromSection(profileSection);
436
+ }
437
+ function extractProfileFromSection(section) {
438
+ const allItems = section.lines.flatMap((l) => l.items);
439
+ const allTexts = allItems.map((i) => i.text.trim()).filter((t) => t.length > 0);
440
+ const name = extractBestMatch(allItems, NAME_FEATURE_SETS);
441
+ const email = extractBestMatch(allItems, EMAIL_FEATURE_SETS);
442
+ const phone = extractBestMatch(allItems, PHONE_FEATURE_SETS);
443
+ const location = extractBestMatch(allItems, LOCATION_FEATURE_SETS);
444
+ const url = extractBestMatch(allItems, URL_FEATURE_SETS);
445
+ // Summary: everything that isn't name/email/phone/location/url
446
+ const summaryTexts = allTexts.filter((t) => t !== name &&
447
+ t !== email &&
448
+ t !== phone &&
449
+ t !== location &&
450
+ t !== url &&
451
+ !SECTION_TITLE_KEYWORDS.includes(t.toUpperCase().replace(/[^A-Z\s/&]/g, "").trim()));
452
+ const summary = summaryTexts.length > 0 ? summaryTexts.join(" ") : null;
453
+ return { name, email, phone, location, url, summary };
454
+ }
455
+ function extractEducation(sections) {
456
+ const eduSection = sections.find((s) => ["EDUCATION", "ACADEMIC", "DEGREES", "ACADEMICS"].includes(s.title));
457
+ if (!eduSection)
458
+ return [];
459
+ const subsections = detectSubsections(eduSection);
460
+ const educations = [];
461
+ for (const sub of subsections) {
462
+ const allItems = sub.flatMap((l) => l.items);
463
+ const allTexts = allItems.map((i) => i.text.trim()).filter((t) => t.length > 0);
464
+ // Find school
465
+ const school = allTexts.find((t) => SCHOOL_KEYWORDS.test(t)) || null;
466
+ // Find degree
467
+ const degree = allTexts.find((t) => DEGREE_KEYWORDS.test(t)) || null;
468
+ // Find GPA
469
+ const gpa = allTexts.find((t) => GPA_REGEX.test(t)) || null;
470
+ // Find date
471
+ const date = allTexts.find((t) => DATE_REGEX.test(t)) || null;
472
+ // Find descriptions (bullet points)
473
+ const descriptions = allTexts.filter((t) => t !== school &&
474
+ t !== degree &&
475
+ t !== gpa &&
476
+ t !== date &&
477
+ !SECTION_TITLE_KEYWORDS.includes(t.toUpperCase()));
478
+ educations.push({ school, degree, gpa, date, descriptions });
479
+ }
480
+ return educations;
481
+ }
482
+ function extractExperience(sections) {
483
+ const expSection = sections.find((s) => [
484
+ "EXPERIENCE", "WORK EXPERIENCE", "EMPLOYMENT",
485
+ "PROFESSIONAL EXPERIENCE", "WORK HISTORY", "CAREER HISTORY",
486
+ "VOLUNTEER", "VOLUNTEER EXPERIENCE", "COMMUNITY",
487
+ "COMMUNITY SERVICE",
488
+ ].includes(s.title));
489
+ if (!expSection)
490
+ return [];
491
+ const subsections = detectSubsections(expSection);
492
+ const experiences = [];
493
+ for (const sub of subsections) {
494
+ const allItems = sub.flatMap((l) => l.items);
495
+ const allTexts = allItems.map((i) => i.text.trim()).filter((t) => t.length > 0);
496
+ // Find company (bolded or no job title match)
497
+ const company = allTexts.find((t) => {
498
+ const item = allItems.find((i) => i.text.trim() === t);
499
+ return item?.bold && !JOB_TITLE_KEYWORDS.test(t);
500
+ }) || null;
501
+ // Find job title
502
+ const jobTitle = allTexts.find((t) => JOB_TITLE_KEYWORDS.test(t)) || null;
503
+ // Find date
504
+ const date = allTexts.find((t) => DATE_REGEX.test(t)) || null;
505
+ // Descriptions (bullet points)
506
+ const descriptions = allTexts.filter((t) => t !== company &&
507
+ t !== jobTitle &&
508
+ t !== date &&
509
+ !SECTION_TITLE_KEYWORDS.includes(t.toUpperCase()));
510
+ experiences.push({ company, jobTitle, date, descriptions });
511
+ }
512
+ return experiences;
513
+ }
514
+ function extractSkills(sections) {
515
+ const skillSection = sections.find((s) => ["SKILLS", "TECHNICAL SKILLS", "COMPETENCIES", "AREAS OF EXPERTISE"].includes(s.title));
516
+ if (!skillSection)
517
+ return [];
518
+ const allTexts = skillSection.lines.flatMap((l) => l.items.map((i) => i.text.trim()).filter((t) => t.length > 0));
519
+ const descriptions = allTexts.filter((t) => !SECTION_TITLE_KEYWORDS.includes(t.toUpperCase()));
520
+ return [{ descriptions }];
521
+ }
522
+ function extractProjects(sections) {
523
+ const projSection = sections.find((s) => ["PROJECTS", "PORTFOLIO", "PERSONAL PROJECTS"].includes(s.title));
524
+ if (!projSection)
525
+ return [];
526
+ const subsections = detectSubsections(projSection);
527
+ const projects = [];
528
+ for (const sub of subsections) {
529
+ const allTexts = sub.flatMap((l) => l.items.map((i) => i.text.trim()).filter((t) => t.length > 0));
530
+ const name = allTexts[0] || null;
531
+ const date = allTexts.find((t) => DATE_REGEX.test(t)) || null;
532
+ const descriptions = allTexts.filter((t) => t !== name && t !== date && !SECTION_TITLE_KEYWORDS.includes(t.toUpperCase()));
533
+ projects.push({ name, date, descriptions });
534
+ }
535
+ return projects;
536
+ }
537
+ // ---------------------------------------------------------------------------
538
+ // Main parse function
539
+ // ---------------------------------------------------------------------------
540
+ function parseResume(input) {
541
+ const warnings = [];
542
+ const stepsCompleted = [];
543
+ let textItems;
544
+ // Step 1: Extract text items
545
+ if (input.rawText) {
546
+ textItems = extractTextItemsFromRawText(input.rawText);
547
+ stepsCompleted.push(1);
548
+ }
549
+ else if (input.filePath) {
550
+ // For synchronous version we use the raw text approach;
551
+ // in production this would be async with pdfjs-dist
552
+ try {
553
+ const content = fs_1.default.readFileSync(input.filePath, "utf-8");
554
+ textItems = extractTextItemsFromRawText(content);
555
+ stepsCompleted.push(1);
556
+ }
557
+ catch {
558
+ warnings.push(`Could not read file: ${input.filePath}`);
559
+ textItems = [];
560
+ }
561
+ }
562
+ else {
563
+ warnings.push("No input provided. Please provide either filePath or rawText.");
564
+ return {
565
+ success: false,
566
+ data: {
567
+ profile: { name: null, email: null, phone: null, location: null, url: null, summary: null },
568
+ education: [],
569
+ experience: [],
570
+ skills: [],
571
+ projects: [],
572
+ sections: [],
573
+ rawTextItems: [],
574
+ lines: [],
575
+ },
576
+ metadata: { parserVersion: "1.0.0", stepsCompleted: [], warnings },
577
+ };
578
+ }
579
+ // Step 2: Group text items into lines
580
+ const lines = groupTextItemsIntoLines(textItems);
581
+ stepsCompleted.push(2);
582
+ // Step 3: Group lines into sections
583
+ const sections = groupLinesIntoSections(lines);
584
+ stepsCompleted.push(3);
585
+ // Step 4: Extract resume attributes from sections
586
+ const profile = extractProfile(sections);
587
+ const education = extractEducation(sections);
588
+ const experience = extractExperience(sections);
589
+ const skills = extractSkills(sections);
590
+ const projects = extractProjects(sections);
591
+ stepsCompleted.push(4);
592
+ const parsedResume = {
593
+ profile,
594
+ education,
595
+ experience,
596
+ skills,
597
+ projects,
598
+ sections,
599
+ rawTextItems: textItems,
600
+ lines,
601
+ };
602
+ return {
603
+ success: true,
604
+ data: parsedResume,
605
+ metadata: { parserVersion: "1.0.0", stepsCompleted, warnings },
606
+ };
607
+ }
608
+ //# sourceMappingURL=parse-resume.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-resume.js","sourceRoot":"","sources":["../../../src/tools/parse-resume.ts"],"names":[],"mappings":"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"}