refactor(v4.0.0-alpha): beginning of a new era

This commit is contained in:
Amruth Pillai
2023-11-05 12:31:42 +01:00
parent 0ba6a444e2
commit 22933bd412
505 changed files with 81829 additions and 0 deletions
+168
View File
@@ -0,0 +1,168 @@
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<JSZip, LinkedIn> {
schema: Schema;
constructor() {
this.schema = linkedInSchema;
}
async readFile(file: File): Promise<JSZip> {
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,
fluency: 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);
}
}
@@ -0,0 +1,10 @@
import { z } from "zod";
export const certificationSchema = z.object({
Name: z.string(),
Url: z.string().url(),
Authority: z.string(),
"Started On": z.string(),
"Finished On": z.string().optional(),
"License Number": z.string(),
});
@@ -0,0 +1,10 @@
import { z } from "zod";
export const educationSchema = z.object({
"School Name": z.string(),
"Start Date": z.string(),
"End Date": z.string(),
Notes: z.string().optional(),
"Degree Name": z.string(),
Activities: z.string(),
});
+8
View File
@@ -0,0 +1,8 @@
import { z } from "zod";
export const emailSchema = z.object({
"Email Address": z.string().email(),
Confirmed: z.enum(["Yes", "No"]),
Primary: z.enum(["Yes", "No"]),
"Updated On": z.string(),
});
+23
View File
@@ -0,0 +1,23 @@
import { z } from "zod";
import { certificationSchema } from "./certification";
import { educationSchema } from "./education";
import { emailSchema } from "./email";
import { languageSchema } from "./language";
import { positionSchema } from "./position";
import { profileSchema } from "./profile";
import { projectSchema } from "./project";
import { skillSchema } from "./skill";
export const linkedInSchema = z.object({
Profile: z.array(profileSchema).optional(),
"Email Addresses": z.array(emailSchema).optional(),
Certifications: z.array(certificationSchema).optional(),
Education: z.array(educationSchema).optional(),
Languages: z.array(languageSchema).optional(),
Positions: z.array(positionSchema).optional(),
Projects: z.array(projectSchema).optional(),
Skills: z.array(skillSchema).optional(),
});
export type LinkedIn = z.infer<typeof linkedInSchema>;
@@ -0,0 +1,6 @@
import { z } from "zod";
export const languageSchema = z.object({
Name: z.string(),
Proficiency: z.string().optional(),
});
@@ -0,0 +1,10 @@
import { z } from "zod";
export const positionSchema = z.object({
"Company Name": z.string(),
Title: z.string(),
Description: z.string().optional(),
Location: z.string(),
"Started On": z.string(),
"Finished On": z.string().optional(),
});
@@ -0,0 +1,17 @@
import { z } from "zod";
export const profileSchema = z.object({
"First Name": z.string(),
"Last Name": z.string(),
"Maiden Name": z.string().optional(),
Address: z.string(),
"Birth Date": z.string(),
Headline: z.string(),
Summary: z.string(),
Industry: z.string(),
"Zip Code": z.string().optional(),
"Geo Location": z.string(),
"Twitter Handles": z.string(),
Websites: z.string(),
"Instant Messengers": z.string().optional(),
});
@@ -0,0 +1,9 @@
import { z } from "zod";
export const projectSchema = z.object({
Title: z.string(),
Description: z.string(),
Url: z.string().url(),
"Started On": z.string(),
"Finished On": z.string().optional(),
});
+5
View File
@@ -0,0 +1,5 @@
import { z } from "zod";
export const skillSchema = z.object({
Name: z.string(),
});