Skip to content

Commit

Permalink
Strict eslint configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
ivancea committed Oct 26, 2023
1 parent bec5baa commit 1534675
Show file tree
Hide file tree
Showing 17 changed files with 116 additions and 64 deletions.
10 changes: 9 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
module.exports = {
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
extends: ["eslint:recommended", "plugin:@typescript-eslint/strict-type-checked"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
env: {
node: true,
},
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
"@typescript-eslint/switch-exhaustiveness-check": "error"
}
};
4 changes: 2 additions & 2 deletions CV/snapshot.html
Original file line number Diff line number Diff line change
Expand Up @@ -1297,7 +1297,7 @@
<img class="right-column__highlight-title-image" src="https://media-asgard.s3.eu-west-1.amazonaws.com/22/04/22/6c6fed10-9b03-4a5f-9d6d-101639c2b170_tuenti-300x300.png" alt="tuenti-300x300.png" />
<div class="right-column__highlight-title-name">
Tuenti Challenge 8: 2nd place

<span class="common__type-label">Achievement</span>
</div>
</div>

Expand Down Expand Up @@ -1338,7 +1338,7 @@
<img class="right-column__highlight-title-image" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE4LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIg0KCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCgl4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCAyMTcuOTI5IDIxNy45MjkiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDIxNy45MjkgMjE3LjkyOTsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KCTxnPg0KCQk8cGF0aCBmaWxsPSJjb3JhbCIgZD0iTTIxMi4zOSwxMDEuNzAzYzUuMDIzLTQuODk3LDYuNzk3LTEyLjA4Myw0LjYyOS0xOC43NTVzLTcuODI3LTExLjQ0My0xNC43NjktMTIuNDUybC01Mi45NjktNy42OTcNCgkJYy0wLjA5Ny0wLjAxNC0wLjE4LTAuMDc1LTAuMjIzLTAuMTYyTDEyNS4zNzEsMTQuNjRDMTIyLjI2Nyw4LjM0OSwxMTUuOTgsNC40NCwxMDguOTY0LDQuNDRTOTUuNjYyLDguMzQ5LDkyLjU1OCwxNC42NA0KCQlMNjguODcsNjIuNjM3Yy0wLjA0MywwLjA4Ny0wLjEyNiwwLjE0Ny0wLjIyMywwLjE2MmwtNTIuOTY4LDcuNjk3Yy02Ljk0MiwxLjAwOS0xMi42MDEsNS43OC0xNC43NjksMTIuNDUyDQoJCXMtMC4zOTQsMTMuODU4LDQuNjI5LDE4Ljc1NWwzOC4zMjgsMzcuMzYxYzAuMDcsMC4wNjgsMC4xMDIsMC4xNjYsMC4wODUsMC4yNjJsLTkuMDQ4LDUyLjc1NQ0KCQljLTEuMTg2LDYuOTE0LDEuNjA0LDEzLjc3MSw3LjI3OSwxNy44OTRjNS42NzYsNC4xMjUsMTMuMDU5LDQuNjU3LDE5LjI2OCwxLjM5M2w0Ny4zNzYtMjQuOTA3YzAuMDg2LTAuMDQ2LDAuMTktMC4wNDUsMC4yNzYsMA0KCQlsNDcuMzc2LDI0LjkwN2MyLjcwMSwxLjQyLDUuNjIzLDIuMTIxLDguNTMxLDIuMTIxYzMuNzc3LDAsNy41My0xLjE4NCwxMC43MzYtMy41MTRjNS42NzUtNC4xMjMsOC40NjQtMTAuOTgsNy4yNzktMTcuODk1DQoJCWwtOS4wNDgtNTIuNzU0Yy0wLjAxNy0wLjA5NiwwLjAxNi0wLjE5NCwwLjA4NS0wLjI2MkwyMTIuMzksMTAxLjcwM3ogTTE1Ni4yMzUsMTQyLjM2OGw5LjA0OCw1Mi43NTQNCgkJYzAuMDI0LDAuMTQsMC4wMzEsMC4xODItMC4xMTgsMC4yOWMtMC4xNDksMC4xMDgtMC4xODcsMC4wODgtMC4zMTIsMC4wMjJsLTQ3LjM3Ny0yNC45MDhjLTUuMzMtMi44MDEtMTEuNjk1LTIuODAxLTE3LjAyNywwDQoJCWwtNDcuMzc2LDI0LjkwN2MtMC4xMjUsMC4wNjUtMC4xNjMsMC4wODYtMC4zMTItMC4wMjJjLTAuMTQ5LTAuMTA4LTAuMTQyLTAuMTUtMC4xMTgtMC4yODlsOS4wNDgtNTIuNzU1DQoJCWMxLjAxOC01LjkzNi0wLjk0OS0xMS45ODktNS4yNjItMTYuMTk0TDE4LjEwMyw4OC44MTNjLTAuMTAxLTAuMDk5LTAuMTMyLTAuMTI4LTAuMDc1LTAuMzAzYzAuMDU3LTAuMTc1LDAuMDk5LTAuMTgxLDAuMjM5LTAuMjAyDQoJCWw1Mi45NjgtNy42OTdjNS45NjEtMC44NjYsMTEuMTExLTQuNjA3LDEzLjc3Ni0xMC4wMDhsMjMuNjg4LTQ3Ljk5OGMwLjA2My0wLjEyNiwwLjA4MS0wLjE2NSwwLjI2NS0wLjE2NXMwLjIwMywwLjAzOSwwLjI2NSwwLjE2NQ0KCQlsMjMuNjg4LDQ3Ljk5OGMyLjY2Niw1LjQwMSw3LjgxNSw5LjE0MywxMy43NzYsMTAuMDA4bDUyLjk2OCw3LjY5N2MwLjE0LDAuMDIxLDAuMTgyLDAuMDI3LDAuMjM5LDAuMjAyDQoJCWMwLjA1NywwLjE3NSwwLjAyNiwwLjIwNS0wLjA3NSwwLjMwM2wtMzguMzI4LDM3LjM2MUMxNTcuMTg1LDEzMC4zNzgsMTU1LjIxOCwxMzYuNDMyLDE1Ni4yMzUsMTQyLjM2OHoiLz4NCgk8L2c+DQo8L3N2Zz4NCg==" alt="Highlight" />
<div class="right-column__highlight-title-name">
Other highlight

<span class="common__type-label">Achievement</span>
</div>
</div>

Expand Down
11 changes: 7 additions & 4 deletions action/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ async function main() {
const outputPath = process.argv[3];

const rawCv = await fs.readFile(path.resolve(process.cwd(), macPath));
const cv: ManfredAwesomicCV = JSON.parse(rawCv.toString());
const cv: unknown = JSON.parse(rawCv.toString());

// Generate the HTML
const html = await generateHtml(cv);
const html = await generateHtml(cv as ManfredAwesomicCV);

// Generate a PDF with the HTML
const pdf = await (generatePdf(
{ content: html },
{ format: "A4", scale: 0.6, printBackground: true }
{ format: "A4", scale: 0.6, printBackground: true },
) as unknown as Promise<Buffer>);

await fs.mkdir(path.resolve(process.cwd(), outputPath), { recursive: true });
await fs.writeFile(path.resolve(process.cwd(), outputPath, "index.html"), html);
await fs.writeFile(path.resolve(process.cwd(), outputPath, "cv.pdf"), pdf);
}

main();
main().catch((err) => {
console.error(err);
process.exit(1);
});
29 changes: 15 additions & 14 deletions action/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@

import { Command } from "commander";
import fs from "fs";
import { Validator } from "jsonschema";
import { Schema, Validator } from "jsonschema";
import path from "path";
import { generateHtml } from ".";
import { ManfredAwesomicCV } from "./lib/mac";

const program = new Command();

program
.name("mac-renderer")
.description("Convert a MAC JSON to HTML (stdout)")
.argument("<mac-file>", "MAC JSON file")
.action(async (macFile) => {
const schema = JSON.parse(fs.readFileSync(path.resolve(__dirname, "mac-schema.json"), "utf8"));
.action(async (macFile: string) => {
const schema: unknown = JSON.parse(fs.readFileSync(path.resolve(__dirname, "mac-schema.json"), "utf8"));
const input = fs.readFileSync(path.resolve(process.cwd(), macFile), "utf8");

const mac = JSON.parse(input);
const mac: unknown = JSON.parse(input);

new Validator().validate(mac, schema, { throwError: true });
new Validator().validate(mac, schema as Schema, { throwError: true });

const html = await generateHtml(mac);
const html = await generateHtml(mac as ManfredAwesomicCV);

console.log(html);
});
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/common/skillsGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { generatorFrom } from "../../utils";

export const generateSkills = generatorFrom(async function* (skills: string[]) {
export const generateSkills = generatorFrom(function* (skills: string[]) {
yield `
<div class="common__skills">
`;
Expand Down
63 changes: 48 additions & 15 deletions lib/generators/common/typeLabelGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,52 @@
import { ProjectType, PublicArtifactType, StudyType } from "../../mac";
import { generatorFrom } from "../../utils";

export const generateTypeLabels = generatorFrom(async function* (type: string | undefined) {
if (type == "proBono") {
yield `<span class="common__type-label">Pro bono</span>`;
} else if (type == "openSource") {
yield `<span class="common__type-label">Open source</span>`;
} else if (type == "sideProject") {
yield `<span class="common__type-label">Side project</span>`;
} else if (type == "personalAchievement") {
yield `<span class="common__type-label">Achievement</span>`;
} else if (type == "officialDegree") {
yield `<span class="common__type-label">Official Degree</span>`;
} else if (type == "certification") {
yield `<span class="common__type-label">Certification</span>`;
} else if (type == "selfTraining") {
yield `<span class="common__type-label">Self Training</span>`;
export const generateTypeLabels = generatorFrom(function* (
type: StudyType | ProjectType | PublicArtifactType | undefined,
) {
switch (type) {
case "proBono":
yield `<span class="common__type-label">Pro bono</span>`;
break;
case "openSource":
yield `<span class="common__type-label">Open source</span>`;
break;
case "sideProject":
yield `<span class="common__type-label">Side project</span>`;
break;
case "personalAchievement":
yield `<span class="common__type-label">Achievement</span>`;
break;
case "officialDegree":
yield `<span class="common__type-label">Official Degree</span>`;
break;
case "certification":
yield `<span class="common__type-label">Certification</span>`;
break;
case "selfTraining":
yield `<span class="common__type-label">Self Training</span>`;
break;
case "unaccredited":
yield `<span class="common__type-label">Unaccredited</span>`;
break;
case "post":
yield `<span class="common__type-label">Post</span>`;
break;
case "talk":
yield `<span class="common__type-label">Talk</span>`;
break;
case "achievement":
yield `<span class="common__type-label">Achievement</span>`;
break;
case "launch":
yield `<span class="common__type-label">Launch</span>`;
break;
case "video":
yield `<span class="common__type-label">Video</span>`;
break;
case "other":
yield `<span class="common__type-label">Other</span>`;
break;
case undefined:
}
});
2 changes: 1 addition & 1 deletion lib/generators/leftColumn/languageGroupGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Language } from "../../mac";
import { generatorFrom } from "../../utils";

export const generateLanguageGroup = generatorFrom(async function* (
export const generateLanguageGroup = generatorFrom(function* (
level: string | undefined,
languages: Language[]
) {
Expand Down
8 changes: 4 additions & 4 deletions lib/generators/leftColumnGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ export const generateLeftColumn = generatorFrom(async function* (mac: ManfredAwe
// First, the public contact links
const contact = mac.careerPreferences?.contact;

const publicProfileLinks =
(contact && "publicProfiles" in contact && contact?.publicProfiles) || [];
const publicProfileLinks = contact && "publicProfiles" in contact ? contact.publicProfiles : [];

if (publicProfileLinks.length) {
for (const link of publicProfileLinks) {
Expand All @@ -56,8 +55,9 @@ export const generateLeftColumn = generatorFrom(async function* (mac: ManfredAwe
// Filter relevant links that aren't contact ones
const publicProfileUrls = publicProfileLinks.map((link) => link.URL);

const nonContactLinks =
mac.aboutMe.relevantLinks?.filter((link) => !publicProfileUrls.includes(link.URL)) ?? [];
const nonContactLinks = mac.aboutMe.relevantLinks.filter(
(link) => !publicProfileUrls.includes(link.URL),
);

// Second, the known links
const knownLinks = nonContactLinks.filter((link) => link.type !== "other");
Expand Down
16 changes: 8 additions & 8 deletions lib/generators/rightColumn/highlightsGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ export const generateHighlights = generatorFrom(async function* (highlights: Hig
let imageUrl = await assets.highlightDefaultIcon;
let imageAlt = "Highlight";

if (details?.image && "link" in details.image) {
if (details.image && "link" in details.image) {
imageUrl = details.image.link;
}

if (details?.image && "alt" in details.image) {
imageAlt = details.image.alt as string;
if (details.image && details.image.alt) {
imageAlt = details.image.alt;
}

let urlText = "";
if (details?.URL) {
if (details.URL) {
urlText = `${decodeURI(details.URL.replace(/https?:\/\//, ""))}`;
}

Expand All @@ -33,19 +33,19 @@ export const generateHighlights = generatorFrom(async function* (highlights: Hig
<div class="right-column__highlight-title">
<img class="right-column__highlight-title-image" src="${imageUrl}" alt="${imageAlt}" />
<div class="right-column__highlight-title-name">
${details?.name}
${details.name}
${await generateTypeLabels(highlight.type)}
</div>
</div>
${
urlText || details?.description
urlText || details.description
? `
<div class="right-column__highlight-details">
${
urlText
? `
<a class="right-column__highlight-details-url" href="${
details?.URL
details.URL
}" target="_blank">
<img class="right-column__highlight-details-url-icon" src="${await assets.linkIcon}" alt="Link" />
${urlText}
Expand All @@ -54,7 +54,7 @@ export const generateHighlights = generatorFrom(async function* (highlights: Hig
: ""
}
${
details?.description
details.description
? `
<div class="right-column__highlight-details-description">
${marked(details.description)}
Expand Down
8 changes: 5 additions & 3 deletions lib/generators/rightColumn/jobsGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ export const generateJobs = generatorFrom(async function* (jobs: Job[]) {
<div class="right-column__job-organization-title">
`;

if (organization.image && "link" in organization.image) {
const organizationImage = organization.image;

if (organizationImage && "link" in organizationImage) {
yield `<img class="right-column__job-organization-image" src="${
organization.image.link
}" alt="${("alt" in organization.image && organization.image.alt) || ""}"/>`;
organizationImage.link
}" alt="${organizationImage.alt || ""}"/>`;
} else {
yield `<img class="right-column__job-organization-image" src="${await assets.jobDefaultIcon}" alt="Job">`;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/rightColumn/sectionGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { generatorFrom } from "../../utils";

export const generateSection = generatorFrom(async function* (title: string, content: string) {
export const generateSection = generatorFrom(function* (title: string, content: string) {
yield `
<div class="right-column__section">
<div class="right-column__section-title">
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/rightColumnGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const generateRightColumn = generatorFrom(async function* (mac: ManfredAw
"About me",
`
<div class="right-column__about-me">
${await marked(mac.aboutMe.profile.description)}
${marked(mac.aboutMe.profile.description)}
</div>
`
);
Expand Down
3 changes: 3 additions & 0 deletions lib/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module "html-pdf-node" {
export function generatePdf(file: { content: string }, options?: Options): Promise<Buffer>;
}
2 changes: 1 addition & 1 deletion lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { isEqual, isNil } from "lodash";
import { Highlight, Job, Project, Study } from "./mac";

export function generatorFrom<T extends unknown[]>(
generator: (...args: T) => AsyncGenerator<string>
generator: (...args: T) => AsyncGenerator<string> | Generator<string>
): (...args: T) => Promise<string> {
return async (...args: T) => {
const parts = [];
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"build": "rimraf ./build && npm run generate && tsc -p tsconfig.build.json && npm run copy-files",
"copy-files": "copyfiles ./{generated,images}/** ./build && copyfiles ./mac-schema.json ./build",
"generate": "rimraf ./generated && npm run generate-schema && npm run generate-sass",
"generate-schema": "json2ts mac-schema.json generated/mac.d.ts --no-additionalProperties && replace-in-file \"/\\[k: string\\]: unknown;/g\" \"\" generated/mac.d.ts --isRegex",
"generate-schema": "json2ts mac-schema.json generated/mac.d.ts --no-additionalProperties && npm run generate-schema-fixes",
"generate-schema-fixes": "replace-in-file \"/\\[k: string\\]: unknown;/g\" \"\" generated/mac.d.ts --isRegex && replace-in-file \": Image1\" \": Image\" generated/mac.d.ts",
"generate-sass": "sass --style=compressed --no-source-map ./sass:./generated/styles && copyfiles --flat ./generated/styles/styles.css ./generated && rimraf ./generated/styles",
"format": "prettier ./**/* --write",
"lint": "eslint . --ext .ts,.js",
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
"skipLibCheck": true,
}
}

0 comments on commit 1534675

Please sign in to comment.