Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions package-lock.json

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

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"scripts": {
"dev": "vite --host",
"build": "vite build",
"preview": "vite preview --host"
"preview": "vite preview --host",
"mocker": "node ./src/api/mocker.mjs"
},
"author": "Evren Ceyhan",
"license": "MIT",
Expand All @@ -27,6 +28,7 @@
"@vitejs/plugin-vue": "^2.3.4",
"autoprefixer": "^10.4.14",
"daisyui": "^3.5.1",
"dotenv": "^16.3.1",
"postcss": "^8.4.27",
"tailwindcss": "^3.3.3",
"vite": "^2.9.16"
Expand Down
68 changes: 43 additions & 25 deletions src/api/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,68 @@ const API_URL = 'https://api.github.com';
const API_USER_ID = import.meta.env.VITE_USER_GITHUB;
const API_USER_URL = `${API_URL}/users/${API_USER_ID}`;

// helpers
const fetchFile = async (path) => fetchJson(new URL(path, import.meta.url));
// RESOURCES ///////////////////////////////////////////////////////////////////////////////////////

const normalizeRepoLanguages = (languages) => {
// summarize total lines of languages in single repo
const lineSum = Object.values(languages).reduce((sum, v) => sum + v, 0);
export async function getProfile() {
return IS_DEV
? await fetchFile('mocks/profile.json')
: await fetchJson(API_USER_URL);
}

return Object.entries(languages).map(([name, lines]) => ({
name,
lines,
color: LANGUAGES[name]?.color,
rate: (lines / lineSum) * 100,
}));
};

export const getProfile = () =>
IS_DEV ? fetchFile('profile.json') : fetchJson(API_USER_URL);

export const getRepositories = async (query = { sort: 'updated' }) => {
export async function getRepositories(query = { sort: 'updated' }) {
// purge cache if modified since last cached request
// purgeCacheIfModified(`${API_USER_URL}/repos`);

// fetch data or use mock in DEV
const repos = IS_DEV
? await fetchFile('repos.json')
? await fetchFile('mocks/repos.json')
: await fetchJson(`${API_USER_URL}/repos`, query);

// fetch languages per repository
const reposWithLanguages = repos.map(async (repo) => {
// define default language as fallback
let languages = { [repo.language]: 1 };
let languages;

try {
languages = IS_DEV
? repo.languages // use as-is in DEV
: await fetchJson(repo.languages_url);
} catch (e) {}
// try fetching languages per repository
languages = await getRepoLanguages(repo.name);
} catch (e) {
// use default language as fallback if failed
languages = normalizeRepoLanguages({ [repo.language]: 1 });
}

// normalize languages per repository
return { ...repo, languages: normalizeRepoLanguages(languages) };
return { ...repo, languages };
});

// return all promises as one
return Promise.all(reposWithLanguages);
}

export async function getRepoLanguages(repo) {
const languages = IS_DEV
? await fetchFile(`mocks/${repo}-languages.json`)
: await fetchJson(`${API_USER_URL}/${repo}/languages`);

return normalizeRepoLanguages(languages);
}

// HELPERS /////////////////////////////////////////////////////////////////////////////////////////

const fetchFile = async (path) => {
const url = new URL(path, import.meta.url);
return (await fetch(url)).json();
};

const normalizeRepoLanguages = (languages) => {
// summarize total lines of languages in single repo
const lineSum = Object.values(languages).reduce((sum, v) => sum + v, 0);

return Object.entries(languages).map(([name, lines]) => ({
name,
lines,
color: LANGUAGES[name]?.color,
rate: ((lines / lineSum) * 100).toFixed(1),
}));
};

// export const purgeCacheIfModified = async (url) => {
Expand Down
62 changes: 62 additions & 0 deletions src/api/mocker.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* This is a server side script to generate mock data, it's not part of the app,
* It's only used to generate mock data for the DEV environment!
*/

import fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import dotenv from 'dotenv';

// load env vars
dotenv.config();

// __dirname is not available in ES6 modules
// https://stackoverflow.com/questions/46745014/using-dirname-in-es6-modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const MOCKS_DIR = __dirname + '/mocks';

// define vars
const API_URL = 'https://api.github.com';
const API_USER_ID = process.env.VITE_USER_GITHUB;
const API_USER_URL = `${API_URL}/users/${API_USER_ID}`;

const readMockFile = (name) => {
const filename = `${MOCKS_DIR}/${name}.json`;
const jsonData = fs.readFileSync(filename);
return JSON.parse(jsonData);
};

const writeMockFile = (name, data) => {
const filename = `${MOCKS_DIR}/${name}.json`;
const jsonData = JSON.stringify(data, null, 2);
fs.writeFileSync(filename, jsonData);
};

const generateProfile = async () => {
const response = await fetch(API_USER_URL);
const data = await response.json();
writeMockFile('profile', data);
};

const generateRepos = async () => {
const response = await fetch(`${API_USER_URL}/repos?sort=updated`);
const data = await response.json();
writeMockFile('repos', data);
};

const generateLanguages = async () => {
const repos = readMockFile('repos');

repos.forEach(async ({ name, languages_url }) => {
const response = await fetch(languages_url);
const languages = await response.json();
writeMockFile(`${name}-languages`, languages);
});
};

// generate mock data
await generateProfile();
await generateRepos();
await generateLanguages();
3 changes: 3 additions & 0 deletions src/api/mocks/amazon-scraper-api-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"JavaScript": 3106
}
5 changes: 5 additions & 0 deletions src/api/mocks/blog-challenge-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"PHP": 19143,
"HTML": 12378,
"Hack": 321
}
7 changes: 7 additions & 0 deletions src/api/mocks/bootstrap-breeze-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"Vue": 47227,
"PHP": 4894,
"JavaScript": 855,
"Blade": 474,
"CSS": 118
}
4 changes: 4 additions & 0 deletions src/api/mocks/bs-bootcamp-web-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"HTML": 32616,
"CSS": 177
}
4 changes: 4 additions & 0 deletions src/api/mocks/bs-splendid-food-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"HTML": 29547,
"SCSS": 14096
}
4 changes: 4 additions & 0 deletions src/api/mocks/devbox-lemp-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"Shell": 10343,
"PHP": 16
}
8 changes: 8 additions & 0 deletions src/api/mocks/fixxo-app-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"PHP": 237946,
"Vue": 194674,
"JavaScript": 12024,
"Blade": 700,
"CSS": 388,
"Procfile": 42
}
4 changes: 4 additions & 0 deletions src/api/mocks/gym-crm-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"PHP": 79585,
"HTML": 2953
}
7 changes: 7 additions & 0 deletions src/api/mocks/laragym-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"JavaScript": 230840,
"PHP": 209779,
"HTML": 5629,
"Dockerfile": 848,
"Shell": 322
}
5 changes: 5 additions & 0 deletions src/api/mocks/multiplay-ball-game-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"TypeScript": 6559,
"HTML": 4580,
"JavaScript": 3134
}
5 changes: 5 additions & 0 deletions src/api/mocks/multiplay-snake-game-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"JavaScript": 10103,
"Vue": 2523,
"HTML": 371
}
4 changes: 4 additions & 0 deletions src/api/mocks/networking-models-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"JavaScript": 9357,
"Shell": 533
}
4 changes: 4 additions & 0 deletions src/api/mocks/next-cats-world-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"JavaScript": 15574,
"CSS": 346
}
5 changes: 5 additions & 0 deletions src/api/mocks/next-meetups-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"JavaScript": 19858,
"CSS": 390,
"Shell": 97
}
3 changes: 3 additions & 0 deletions src/api/mocks/next-real-estate-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"JavaScript": 29655
}
6 changes: 6 additions & 0 deletions src/api/mocks/ng-comic-book-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"TypeScript": 24408,
"HTML": 13172,
"JavaScript": 2238,
"CSS": 1330
}
6 changes: 6 additions & 0 deletions src/api/mocks/ng-heroes-app-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"TypeScript": 21436,
"HTML": 5580,
"JavaScript": 2232,
"CSS": 322
}
6 changes: 6 additions & 0 deletions src/api/mocks/ng-organic-shop-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"TypeScript": 50970,
"HTML": 22580,
"JavaScript": 1832,
"CSS": 760
}
6 changes: 6 additions & 0 deletions src/api/mocks/ng-weather-app-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"HTML": 29042,
"TypeScript": 18705,
"JavaScript": 3802,
"CSS": 1096
}
4 changes: 4 additions & 0 deletions src/api/mocks/nuxt-resto-advisor-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"Vue": 6028,
"TypeScript": 1412
}
34 changes: 34 additions & 0 deletions src/api/mocks/profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"login": "webceyhan",
"id": 3739981,
"node_id": "MDQ6VXNlcjM3Mzk5ODE=",
"avatar_url": "https://avatars.githubusercontent.com/u/3739981?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/webceyhan",
"html_url": "https://github.com/webceyhan",
"followers_url": "https://api.github.com/users/webceyhan/followers",
"following_url": "https://api.github.com/users/webceyhan/following{/other_user}",
"gists_url": "https://api.github.com/users/webceyhan/gists{/gist_id}",
"starred_url": "https://api.github.com/users/webceyhan/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/webceyhan/subscriptions",
"organizations_url": "https://api.github.com/users/webceyhan/orgs",
"repos_url": "https://api.github.com/users/webceyhan/repos",
"events_url": "https://api.github.com/users/webceyhan/events{/privacy}",
"received_events_url": "https://api.github.com/users/webceyhan/received_events",
"type": "User",
"site_admin": false,
"name": "Evren Ceyhan",
"company": "CEYHAN I/O",
"blog": "http://ceyhan.io",
"location": "Brussels",
"email": null,
"hireable": true,
"bio": "Full Stack Web Developer",
"twitter_username": "webceyhan",
"public_repos": 40,
"public_gists": 0,
"followers": 4,
"following": 5,
"created_at": "2013-03-01T16:12:23Z",
"updated_at": "2023-08-08T08:24:14Z"
}
5 changes: 5 additions & 0 deletions src/api/mocks/react-budget-tracker-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"JavaScript": 22777,
"HTML": 1835,
"CSS": 200
}
5 changes: 5 additions & 0 deletions src/api/mocks/react-goggle-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"JavaScript": 30002,
"HTML": 1718,
"CSS": 59
}
5 changes: 5 additions & 0 deletions src/api/mocks/react-meetups-languages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"JavaScript": 14466,
"HTML": 403,
"CSS": 374
}
Loading