import { createId } from "@paralleldrive/cuid2"; import { defaultCertification, defaultEducation, defaultExperience, defaultLanguage, defaultProfile, defaultProject, defaultResumeData, defaultSkill, ResumeData, resumeDataSchema, } from "@reactive-resume/schema"; import { extractUrl, Json, parseCSV } from "@reactive-resume/utils"; import * as JSZip from "jszip"; import { Schema } from "zod"; import { Parser } from "../interfaces/parser"; import { LinkedIn, linkedInSchema } from "./schema"; export * from "./schema"; export class LinkedInParser implements Parser { schema: Schema; constructor() { this.schema = linkedInSchema; } async readFile(file: File): Promise { const data = await JSZip.loadAsync(file); if (Object.keys(data.files).length === 0) { throw new Error("ParserError: There were no files found inside the zip archive."); } return data; } async validate(data: JSZip) { const result: Json = {}; for (const [name, file] of Object.entries(data.files)) { for (const key of Object.keys(linkedInSchema.shape)) { if (name.includes(key)) { const content = await file.async("text"); const jsonArray = await parseCSV(content); result[key] = jsonArray; } } } return linkedInSchema.parse(result); } convert(data: LinkedIn) { const result = JSON.parse(JSON.stringify(defaultResumeData)) as ResumeData; // Profile if (data.Profile && data.Profile.length > 0) { const profile = data.Profile[0]; const twitterHandle = profile["Twitter Handles"]; result.basics.name = `${profile["First Name"]} ${profile["Last Name"]}`; result.basics.location = profile["Geo Location"]; result.basics.headline = profile.Headline; result.basics.url.href = extractUrl(profile.Websites) ?? ""; result.sections.summary.content = profile.Summary; result.sections.profiles.items.push({ ...defaultProfile, id: createId(), icon: "twitter", network: "Twitter", username: twitterHandle, url: { ...defaultProfile.url, href: `https://twitter.com/${twitterHandle}` }, }); } // Email Addresses if (data["Email Addresses"] && data["Email Addresses"].length > 0) { const email = data["Email Addresses"][0]; result.basics.email = email["Email Address"]; } // Positions if (data["Positions"] && data["Positions"].length > 0) { for (const position of data["Positions"]) { result.sections.experience.items.push({ ...defaultExperience, id: createId(), company: position["Company Name"], position: position.Title, location: position.Location, summary: position.Description ?? "", date: `${position["Started On"]} - ${position["Finished On"] ?? "Present"}`, }); } } // Education if (data["Education"] && data["Education"].length > 0) { for (const education of data["Education"]) { result.sections.education.items.push({ ...defaultEducation, id: createId(), institution: education["School Name"], studyType: education["Degree Name"], summary: education.Notes ?? "", date: `${education["Start Date"]} - ${education["End Date"] ?? "Present"}`, }); } } // Skills if (data["Skills"] && data["Skills"].length > 0) { for (const skill of data["Skills"]) { result.sections.skills.items.push({ ...defaultSkill, id: createId(), name: skill.Name, }); } } // Languages if (data["Languages"] && data["Languages"].length > 0) { for (const language of data["Languages"]) { result.sections.languages.items.push({ ...defaultLanguage, id: createId(), name: language.Name, description: language.Proficiency ?? "", }); } } // Certifications if (data["Certifications"] && data["Certifications"].length > 0) { for (const certification of data["Certifications"]) { result.sections.certifications.items.push({ ...defaultCertification, id: createId(), name: certification.Name, issuer: certification.Authority, url: { ...defaultCertification.url, href: certification.Url }, date: `${certification["Started On"]} - ${certification["Finished On"] ?? "Present"}`, }); } } // Projects if (data["Projects"] && data["Projects"].length > 0) { for (const project of data["Projects"]) { result.sections.projects.items.push({ ...defaultProject, id: createId(), name: project.Title, description: project.Description, url: { ...defaultProject.url, href: project.Url ?? "" }, date: `${project["Started On"]} - ${project["Finished On"] ?? "Present"}`, }); } } return resumeDataSchema.parse(result); } }