Skip to content

Commit

Permalink
Merge pull request #30 from devtobi/26-add-initial-vue-based-wrapper-…
Browse files Browse the repository at this point in the history
…application

26 add initial vue based wrapper application
  • Loading branch information
devtobi authored Jun 5, 2024
2 parents daf9b28 + 81af043 commit b7107ea
Show file tree
Hide file tree
Showing 43 changed files with 728 additions and 149 deletions.
8 changes: 8 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"tabWidth": 2,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none"
}
7 changes: 7 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"recommendations": [
"Vue.volar",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ You can use this repository as starting point and inspiration to write your own

### Built With

This project is built as a monorepo. Currently it only contains the package `cv-content`, which is responsible for the generation of the static files.
This project is built as a monorepo. Currently it only contains the following packages
- `cv-content`: Generation for multiple static html files using JSONSchema and resumed
- `cv-wrapper`: Vue based SPA used as entrypoint to dynamically serve `cv-content` and provide additional features

The following lists contains the important technologies used to implement this application.

#### `cv-content`:

Expand All @@ -49,6 +53,11 @@ This project is built as a monorepo. Currently it only contains the package `cv-
- [prettier](https://prettier.io) (to format `.json` files)
- [concurrently](https://github.com/open-cli-tools/concurrently) (to allow for parallel build execution and speed increase)

#### `cv-wrapper`:

- [Vue](https://vuejs.org) (JavaScript framework used to implement the application)


## Getting Started

To get a local copy up and running follow these simple steps.
Expand Down Expand Up @@ -98,8 +107,8 @@ Then set your theme by exporting a environment variable named `THEME` to the nam

**Info**: Keep in note the commands for exporting environment variables might differ depending on your operating system.

To build the static files use the command `bun run build`.
The command builds an `.html` version and a `.pdf` version and places those files into specific subdirectories for each language your CV was written in.
To build the whole monorepo use the command `bun run build`.
The command builds an `.html` version and a `.pdf` version and places those files into specific subdirectories for each language your CV was written in. On top of that it builds the Vue based wrapper application. In the end both build folders are combined into a single `dist` folder. This folder can be served as is.

### Usage with GitHub actions

Expand Down
Binary file modified bun.lockb
Binary file not shown.
18 changes: 2 additions & 16 deletions data/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,7 @@
{
"name": "Webentwicklung",
"level": "fortgeschritten",
"keywords": [
"LAMP",
"JavaScript",
"HTML 5",
"Angular.js",
"jQuery",
"Sass",
"LESS"
]
"keywords": ["LAMP", "JavaScript", "HTML 5", "Angular.js", "jQuery", "Sass", "LESS"]
},
{
"name": "Ninjitsu",
Expand Down Expand Up @@ -139,13 +131,7 @@
{
"name": "GitHub",
"summary": "Regelmäßiger GitHub-Nutzer und Bastler.",
"keywords": [
"GitHub",
"git",
"GitHub Desktop (OS X)",
"LFS",
"GitHub API"
]
"keywords": ["GitHub", "git", "GitHub Desktop (OS X)", "LFS", "GitHub API"]
},
{
"name": "Schach",
Expand Down
18 changes: 2 additions & 16 deletions data/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,7 @@
{
"name": "Web Development",
"level": "advanced",
"keywords": [
"LAMP",
"JavaScript",
"HTML 5",
"Angular.js",
"jQuery",
"Sass",
"LESS"
]
"keywords": ["LAMP", "JavaScript", "HTML 5", "Angular.js", "jQuery", "Sass", "LESS"]
},
{
"name": "Ninjitsu",
Expand Down Expand Up @@ -139,13 +131,7 @@
{
"name": "GitHub",
"summary": "Regular GitHub user and tinkerer.",
"keywords": [
"GitHub",
"git",
"GitHub Desktop (OS X)",
"LFS",
"GitHub API"
]
"keywords": ["GitHub", "git", "GitHub Desktop (OS X)", "LFS", "GitHub API"]
},
{
"name": "chess",
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"description": "My CV application as a monorepo built using Vue.js and resumed",
"scripts": {
"build": "bun --filter '*' build && bun post-build",
"post-build": "concurrently --kill-others-on-fail -n copy-content 'ncp packages/cv-content/dist dist'",
"post-build": "concurrently --kill-others-on-fail -n copy-content,copy-wrapper 'ncp packages/cv-content/dist dist' 'ncp packages/cv-wrapper/dist dist'",
"setup": "bun --filter cv-content setup",
"format": "bun --filter cv-content format",
"validate": "bun --filter cv-content validate",
Expand All @@ -15,8 +15,6 @@
},
"devDependencies": {
"concurrently": "8.2.2",
"eslint": "9.4.0",
"eslint-config-prettier": "9.1.0",
"globals": "15.3.0",
"ncp": "2.0.0",
"prettier": "3.3.1"
Expand Down
18 changes: 9 additions & 9 deletions packages/cv-content/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import eslintConfigPrettier from "eslint-config-prettier";
import js from "@eslint/js";
import globals from "globals";
import eslintConfigPrettier from 'eslint-config-prettier'
import js from '@eslint/js'
import globals from 'globals'

export default [
js.configs.recommended,
eslintConfigPrettier,
{
languageOptions: {
sourceType: "commonjs",
sourceType: 'commonjs',
globals: {
...globals.node,
},
...globals.node
}
},
ignores: ["node_modules", "eslint.config.mjs"],
},
];
ignores: ['node_modules', 'eslint.config.mjs']
}
]
2 changes: 2 additions & 0 deletions packages/cv-content/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"author": "Tobias Stadler",
"license": "MIT",
"devDependencies": {
"eslint": "9.4.0",
"eslint-config-prettier": "9.1.0",
"html-minifier-terser": "7.2.0",
"minimist": "1.2.8",
"puppeteer": "22.10.0",
Expand Down
16 changes: 8 additions & 8 deletions packages/cv-content/scripts/buildHtml.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const createDirectories = require("./helpers/createDirectories.js");
const execConcurrently = require("./helpers/execConcurrently.js");
const generateTasks = require("./helpers/generateTasks.js");
const { DATA_DIRECTORY, DIST_DIRECTORY } = require("./helpers/constants.js");
const createDirectories = require('./helpers/createDirectories.js')
const execConcurrently = require('./helpers/execConcurrently.js')
const generateTasks = require('./helpers/generateTasks.js')
const { DATA_DIRECTORY, DIST_DIRECTORY } = require('./helpers/constants.js')

const BUILD_CMD = `resumed render ${DATA_DIRECTORY}/%s.json -o ${DIST_DIRECTORY}/%s/index.html -t $THEME`;
const BUILD_CMD = `resumed render ${DATA_DIRECTORY}/%s.json -o ${DIST_DIRECTORY}/%s/index.html -t $THEME`

createDirectories();
const buildTasks = generateTasks("build-html", BUILD_CMD);
execConcurrently(buildTasks);
createDirectories()
const buildTasks = generateTasks('build-html', BUILD_CMD)
execConcurrently(buildTasks)
12 changes: 6 additions & 6 deletions packages/cv-content/scripts/generatePdfs.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const execConcurrently = require("./helpers/execConcurrently.js");
const generateTasks = require("./helpers/generateTasks.js");
const { DIST_DIRECTORY } = require("./helpers/constants.js");
const execConcurrently = require('./helpers/execConcurrently.js')
const generateTasks = require('./helpers/generateTasks.js')
const { DIST_DIRECTORY } = require('./helpers/constants.js')

const GENERATE_PDF_CMD = `node scripts/helpers/generatePdf.js --input ${DIST_DIRECTORY}/%s/index.html --output ${DIST_DIRECTORY}/%s/cv.pdf`;
const GENERATE_PDF_CMD = `node scripts/helpers/generatePdf.js --input ${DIST_DIRECTORY}/%s/index.html --output ${DIST_DIRECTORY}/%s/cv.pdf`

const generatePdfTasks = generateTasks("build-pdf", GENERATE_PDF_CMD);
execConcurrently(generatePdfTasks);
const generatePdfTasks = generateTasks('build-pdf', GENERATE_PDF_CMD)
execConcurrently(generatePdfTasks)
8 changes: 4 additions & 4 deletions packages/cv-content/scripts/helpers/constants.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const DATA_DIRECTORY = "../../data";
const DIST_DIRECTORY = "dist";
const DATA_DIRECTORY = '../../data'
const DIST_DIRECTORY = 'dist'

module.exports = {
DATA_DIRECTORY,
DIST_DIRECTORY,
};
DIST_DIRECTORY
}
22 changes: 11 additions & 11 deletions packages/cv-content/scripts/helpers/createDirectories.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
const path = require("path");
const fs = require("fs");
const getFiles = require("./getFiles.js");
const { DATA_DIRECTORY, DIST_DIRECTORY } = require("./constants.js");
const path = require('path')
const fs = require('fs')
const getFiles = require('./getFiles.js')
const { DATA_DIRECTORY, DIST_DIRECTORY } = require('./constants.js')

const createDirectories = () => {
const files = getFiles(DATA_DIRECTORY);
const files = getFiles(DATA_DIRECTORY)
files.forEach((file) => {
const dirname = `${DIST_DIRECTORY}/${path.parse(file).name}`;
const dirname = `${DIST_DIRECTORY}/${path.parse(file).name}`
try {
fs.mkdirSync(dirname, { recursive: true });
fs.mkdirSync(dirname, { recursive: true })
} catch (err) {
console.error("Error creating directory:", err);
console.error('Error creating directory:', err)
}
});
};
})
}

module.exports = createDirectories;
module.exports = createDirectories
22 changes: 11 additions & 11 deletions packages/cv-content/scripts/helpers/execConcurrently.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
const concurrently = require("concurrently");
const concurrently = require('concurrently')

const returnStatusCode = (result) => {
result.then(
() => {
process.exit(0);
process.exit(0)
},
() => {
process.exit(1);
},
);
};
process.exit(1)
}
)
}

const execConcurrently = (taskList) => {
const { result } = concurrently(taskList, {
killOthers: ["failure"],
});
returnStatusCode(result);
};
killOthers: ['failure']
})
returnStatusCode(result)
}

module.exports = execConcurrently;
module.exports = execConcurrently
52 changes: 25 additions & 27 deletions packages/cv-content/scripts/helpers/generatePdf.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
const puppeteer = require("puppeteer");
const path = require("path");
const args = require("minimist")(process.argv.slice(2));
const puppeteer = require('puppeteer')
const path = require('path')
const args = require('minimist')(process.argv.slice(2))

const INPUT_ARG = "input";
const OUTPUT_ARG = "output";
const INPUT_ARG = 'input'
const OUTPUT_ARG = 'output'

if (!args[INPUT_ARG] || !args[OUTPUT_ARG]) {
console.log(
"Either input or output is missing. Use --input and --output respectively.",
);
process.exit(0);
console.log('Either input or output is missing. Use --input and --output respectively.')
process.exit(0)
}

const filePath = path.join(__dirname, `../../${args[INPUT_ARG]}`);
const outputPath = path.join(__dirname, `../../${args[OUTPUT_ARG]}`);
const filePath = path.join(__dirname, `../../${args[INPUT_ARG]}`)
const outputPath = path.join(__dirname, `../../${args[OUTPUT_ARG]}`)

const generateWithBrowser = async (filePath, outputPath) => {
try {
console.log(`Generating PDF for ${filePath}...`);
console.log(`Generating PDF for ${filePath}...`)
const browser = await puppeteer.launch(),
page = await browser.newPage();
await page.goto(`file://${filePath}`);
page = await browser.newPage()
await page.goto(`file://${filePath}`)
await page.pdf({
path: outputPath,
format: "A4",
format: 'A4',
printBackground: true,
displayHeaderFooter: false,
margin: {
top: "0mm",
left: "0mm",
right: "0mm",
bottom: "0mm",
},
});
await browser.close();
top: '0mm',
left: '0mm',
right: '0mm',
bottom: '0mm'
}
})
await browser.close()
} catch (error) {
console.log(`Error generating PDF for ${filePath}: ${error}`);
throw error;
console.log(`Error generating PDF for ${filePath}: ${error}`)
throw error
}
console.log(`Successfully generated PDF for ${filePath}`);
};
console.log(`Successfully generated PDF for ${filePath}`)
}

generateWithBrowser(filePath, outputPath);
generateWithBrowser(filePath, outputPath)
22 changes: 11 additions & 11 deletions packages/cv-content/scripts/helpers/generateTasks.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
const path = require("path");
const util = require("util");
const path = require('path')
const util = require('util')

const getFiles = require("./getFiles.js");
const { DATA_DIRECTORY } = require("./constants.js");
const getFiles = require('./getFiles.js')
const { DATA_DIRECTORY } = require('./constants.js')

const generateTasks = (taskName, commandString) => {
const files = getFiles(`${DATA_DIRECTORY}`);
const files = getFiles(`${DATA_DIRECTORY}`)
return files.map((file) => {
const dirname = path.parse(file).name;
const dirname = path.parse(file).name
return {
command: util.format(commandString, dirname, dirname),
name: taskName,
};
});
};
name: taskName
}
})
}

module.exports = generateTasks;
module.exports = generateTasks
Loading

0 comments on commit b7107ea

Please sign in to comment.