@ -0,0 +1 @@ |
||||
Subproject commit e0685ea2eac50051b41dd186b752905e85f4143d |
@ -0,0 +1,116 @@ |
||||
module.exports = { |
||||
angular: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2277.8, |
||||
}, |
||||
}, |
||||
'aspnet-core': { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2773.45, |
||||
}, |
||||
}, |
||||
backend: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2840.4, |
||||
}, |
||||
}, |
||||
blockchain: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2173.87, |
||||
}, |
||||
}, |
||||
'computer-science': { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 3009.05, |
||||
}, |
||||
}, |
||||
'design-system': { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2309.7, |
||||
}, |
||||
}, |
||||
devops: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2527.46, |
||||
}, |
||||
}, |
||||
flutter: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2042.2, |
||||
}, |
||||
}, |
||||
frontend: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2734.48, |
||||
}, |
||||
}, |
||||
golang: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 1495.21, |
||||
}, |
||||
}, |
||||
java: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 1167.29, |
||||
}, |
||||
}, |
||||
javascript: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2438.9, |
||||
}, |
||||
}, |
||||
nodejs: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2474.06, |
||||
}, |
||||
}, |
||||
python: { |
||||
dimensions: { |
||||
width: 992, |
||||
height: 1259.03, |
||||
}, |
||||
}, |
||||
qa: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2107.75, |
||||
}, |
||||
}, |
||||
react: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 2570.26, |
||||
}, |
||||
}, |
||||
'software-architect': { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 1882.18, |
||||
}, |
||||
}, |
||||
'software-design-architecture': { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 1764.66, |
||||
}, |
||||
}, |
||||
vue: { |
||||
dimensions: { |
||||
width: 968, |
||||
height: 1657.07, |
||||
}, |
||||
}, |
||||
}; |
@ -0,0 +1,132 @@ |
||||
const fs = require('fs'); |
||||
const path = require('path'); |
||||
const yaml = require('json-to-pretty-yaml'); |
||||
const roadmapMetas = require('./roadmap-metas.cjs'); |
||||
|
||||
const oldAssetsPath = path.join(__dirname, 'developer-roadmap/public'); |
||||
const newAssetsPath = path.join(__dirname, '../public/'); |
||||
|
||||
// Create JSONs dir |
||||
const newJsonsPath = path.join(newAssetsPath, 'jsons'); |
||||
if (fs.existsSync(newJsonsPath)) { |
||||
fs.rmSync(newJsonsPath, { recursive: true }); |
||||
} |
||||
|
||||
fs.mkdirSync(newJsonsPath); |
||||
|
||||
// Create PDFs dir |
||||
const newPdfsPath = path.join(newAssetsPath, 'pdfs'); |
||||
if (fs.existsSync(newPdfsPath)) { |
||||
fs.rmSync(newPdfsPath, { recursive: true }); |
||||
} |
||||
|
||||
fs.mkdirSync(newPdfsPath); |
||||
|
||||
const oldRoadmapsDirPath = path.join(__dirname, 'developer-roadmap/content/roadmaps'); |
||||
const newRoadmapsDirPath = path.join(__dirname, '../src/roadmaps'); |
||||
|
||||
if (fs.existsSync(newRoadmapsDirPath)) { |
||||
fs.rmSync(newRoadmapsDirPath, { recursive: true }); |
||||
} |
||||
|
||||
fs.mkdirSync(newRoadmapsDirPath); |
||||
|
||||
const oldRoadmaps = fs |
||||
.readdirSync(oldRoadmapsDirPath) |
||||
.map((roadmapDirName) => path.join(oldRoadmapsDirPath, roadmapDirName)); |
||||
|
||||
const orderInfo = {}; |
||||
const typeCounter = { |
||||
role: 1, |
||||
tool: 1, |
||||
}; |
||||
|
||||
// Calculate the sorting information for the roadmaps |
||||
oldRoadmaps.forEach((oldRoadmapPath) => { |
||||
const roadmapId = path.basename(oldRoadmapPath).replace(/\d+-/g, '').toLowerCase(); |
||||
const oldRoadmapMeta = require(path.join(oldRoadmapPath, 'meta.json')); |
||||
|
||||
orderInfo[roadmapId] = typeCounter[oldRoadmapMeta.type]; |
||||
typeCounter[oldRoadmapMeta.type] += 1; |
||||
}); |
||||
|
||||
// Iterate and create new roadmaps |
||||
oldRoadmaps.forEach((oldRoadmapPath) => { |
||||
const roadmapId = path.basename(oldRoadmapPath).replace(/\d+-/g, '').toLowerCase(); |
||||
|
||||
const metaToMerge = roadmapMetas[roadmapId] ?? {}; |
||||
const oldRoadmapMeta = require(path.join(oldRoadmapPath, 'meta.json')); |
||||
const isTextual = oldRoadmapMeta?.landingPath?.endsWith('.md'); |
||||
|
||||
const hasContentDir = fs.existsSync(path.join(oldRoadmapPath, 'content')); |
||||
|
||||
const roadmapFileContent = isTextual |
||||
? fs.readFileSync(path.join(oldRoadmapPath, oldRoadmapMeta.landingPath), 'utf8') |
||||
: ''; |
||||
|
||||
const roadmapFileContentWithUpdatedUrls = roadmapFileContent |
||||
.replace(/\[\!\[\]\((.+?\.png)\)\]\((.+?\.png)\)/g, '[![](/assets$1)](/assets$2)') |
||||
.replace(/\[\!\[\]\((.+?\.svg)\)\]\((.+?\.svg)\)/g, '[![](/assets$1)](/assets$2)') |
||||
.replace(/\[\!\[\]\((.+?\.svg)\)\]\((.+?\.png)\)/g, '[![](/assets$1)](/assets$2)') |
||||
.replace(/assetshttp\//g, 'http') |
||||
.replace(/assetshttps:\/\//g, 'https://') |
||||
.replace(/\/http/g, 'http') |
||||
.replace(/]\(\/roadmaps\/(.+?)\.png\)/g, '](/assets/roadmaps/$1.png)') |
||||
.replace(/]\(\/roadmaps\/(.+?)\.svg\)/g, '](/assets/roadmaps/$1.svg)') |
||||
.replace(/<iframe/g, '<iframe class="w-full aspect-video mb-5"') |
||||
.replace(/<iframe(.+?)\s?\/>/g, '<iframe$1></iframe>'); |
||||
|
||||
const hasJson = fs.existsSync(path.join(newAssetsPath, `/${roadmapId}.json`)); |
||||
|
||||
const newRoadmapMeta = { |
||||
...( hasJson ? { jsonUrl: `/jsons/${roadmapId}.json`} : {}), |
||||
pdfUrl: `/pdfs/${roadmapId}.pdf`, |
||||
order: orderInfo[roadmapId], |
||||
featuredTitle: |
||||
oldRoadmapMeta.featuredTitle === 'Software Design and Architecture' |
||||
? 'Software Design' |
||||
: oldRoadmapMeta.featuredTitle, |
||||
featuredDescription: oldRoadmapMeta.featuredDescription, |
||||
title: oldRoadmapMeta.title, |
||||
description: oldRoadmapMeta.description, |
||||
isNew: oldRoadmapMeta.isNew, |
||||
hasTopics: hasContentDir, |
||||
...metaToMerge, |
||||
seo: oldRoadmapMeta.seo, |
||||
relatedRoadmaps: oldRoadmapMeta.relatedRoadmaps, |
||||
sitemap: { |
||||
priority: 1, |
||||
changefreq: 'monthly', |
||||
}, |
||||
tags: ['roadmap', 'main-sitemap', `${oldRoadmapMeta.type === 'tool' ? 'skill' : oldRoadmapMeta.type}-roadmap`], |
||||
}; |
||||
|
||||
const frontmatter = yaml.stringify(newRoadmapMeta); |
||||
const newRoadmapDirPath = path.join(newRoadmapsDirPath, roadmapId); |
||||
const newRoadmapFilePath = path.join(newRoadmapDirPath, `/${roadmapId}.md`); |
||||
|
||||
fs.mkdirSync(newRoadmapDirPath); |
||||
fs.writeFileSync(newRoadmapFilePath, `---\n${frontmatter}---\n\n${roadmapFileContentWithUpdatedUrls}`); |
||||
|
||||
const jsonFile = path.join(oldAssetsPath, oldRoadmapMeta.jsonUrl || '/unknown'); |
||||
const pdfFile = path.join(oldAssetsPath, oldRoadmapMeta.pdfUrl || '/unknown'); |
||||
|
||||
if (fs.existsSync(jsonFile)) { |
||||
fs.copyFileSync(jsonFile, path.join(newJsonsPath, `${roadmapId}.json`)); |
||||
} |
||||
|
||||
if (fs.existsSync(pdfFile)) { |
||||
fs.copyFileSync(pdfFile, path.join(newPdfsPath, `${roadmapId}.pdf`)); |
||||
} |
||||
|
||||
// Copy the content directory |
||||
const oldRoadmapContentDir = path.join(oldRoadmapPath, 'content'); |
||||
if (fs.existsSync(oldRoadmapContentDir)) { |
||||
fs.cpSync(oldRoadmapContentDir, path.join(newRoadmapDirPath, 'content'), { recursive: true }); |
||||
} |
||||
}); |
||||
|
||||
const roadmapAssets = path.join(oldAssetsPath, 'roadmaps'); |
||||
if (fs.existsSync(roadmapAssets)) { |
||||
fs.cpSync(roadmapAssets, path.join(newAssetsPath, 'roadmaps'), { recursive: true }); |
||||
} |
@ -0,0 +1,30 @@ |
||||
#!/usr/bin/env bash |
||||
|
||||
set -e |
||||
|
||||
# Change working directory to the directory of this script |
||||
cd "$(dirname "$0")" |
||||
|
||||
if [ ! -d "./developer-roadmap" ]; then |
||||
git clone --depth 1 -b master git@github.com:kamranahmedse/developer-roadmap.git |
||||
fi |
||||
|
||||
echo "Removing old directories" |
||||
rm -rf ../src/videos |
||||
rm -rf ../src/guides |
||||
rm -rf ../src/roadmaps |
||||
|
||||
rm -rf ../public/jsons |
||||
rm -rf ../public/pdfs |
||||
|
||||
echo "=== Migrating Roadmaps ===" |
||||
node roadmap-migrator.cjs |
||||
|
||||
echo "=== Migrating Content ===" |
||||
# node content-migrator.cjs |
||||
|
||||
echo "=== Migrating Guides ===" |
||||
# node guide-migrator.cjs |
||||
|
||||
echo "=== Migrating Videos ===" |
||||
# node video-migrator.cjs |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 215 KiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 875 KiB |
After Width: | Height: | Size: 721 KiB |
After Width: | Height: | Size: 985 KiB |
After Width: | Height: | Size: 699 KiB |
After Width: | Height: | Size: 831 KiB |
After Width: | Height: | Size: 658 KiB |
After Width: | Height: | Size: 881 KiB |
After Width: | Height: | Size: 238 KiB |
After Width: | Height: | Size: 387 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 643 KiB |
After Width: | Height: | Size: 752 KiB |
After Width: | Height: | Size: 733 KiB |
After Width: | Height: | Size: 316 KiB |
After Width: | Height: | Size: 698 KiB |
After Width: | Height: | Size: 448 KiB |
After Width: | Height: | Size: 669 KiB |
After Width: | Height: | Size: 678 KiB |
After Width: | Height: | Size: 425 KiB |
@ -1,2 +0,0 @@ |
||||
#!/usr/bin/env bash |
||||
|
@ -1 +1,8 @@ |
||||
# Marble diagrams |
||||
# Marble Diagrams |
||||
|
||||
Marble testing allows you to test asynchronous RxJS code synchronously and step-by-step with the help of RxJS TestScheduler test utility and using virtual time steps. |
||||
|
||||
<ResourceGroupTitle>Free Content</ResourceGroupTitle> |
||||
<BadgeLink colorScheme='yellow' badgeText='Read' href='https://www.altamira.ai/blog/angular-marble-testing-a-brief-introduction/'>Angular Marble Testing: A Brief Introduction</BadgeLink> |
||||
<BadgeLink colorScheme='yellow' badgeText='Read' href='https://medium.com/@jshvarts/read-marble-diagrams-like-a-pro-3d72934d3ef5'>IUnderstanding Marble Diagrams for Reactive Streams</BadgeLink> |
||||
<BadgeLink colorScheme='yellow' badgeText='Read' href='https://rxmarbles.com/#from'>Interactive Diagrams</BadgeLink> |
||||
|
@ -1 +1,11 @@ |
||||
# Rxjs vs promises |
||||
# RxJS vs Promises |
||||
|
||||
In a nutshell, the main differences between the Promise and the Observable are as follows: |
||||
|
||||
- The Promise is eager, whereas the Observable is lazy, |
||||
- The Promise is always asynchronous, while the Observable can be either asynchronous or synchronous, |
||||
- The Promise can provide a single value, whereas the Observable is a stream of values (from 0 to multiple values), |
||||
you can apply RxJS operators to the Observable to get a new tailored stream. |
||||
|
||||
<ResourceGroupTitle>Free Content</ResourceGroupTitle> |
||||
<BadgeLink colorScheme='blue' badgeText='Official Website' href='https://javascript.plainenglish.io/why-rxjs-rxjs-vs-promises-b28962771d68'>Why RxJS? RxJS vs Promises</BadgeLink> |
||||
|
@ -1,10 +0,0 @@ |
||||
# Angular CLI |
||||
|
||||
The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications directly from a command shell. we can install angular latest CLI using the following command |
||||
|
||||
`npm install -g @angular/cli` |
||||
|
||||
{% resources %} |
||||
{% Official "https://angular.io/cli", "Angular CLI - Angular.io" %} |
||||
{% Blog "https://www.youtube.com/watch?v=mZnzX3J5XKI", "Angular CLI - setup" %} |
||||
{% endresources %} |
@ -0,0 +1,9 @@ |
||||
# Angular CLI |
||||
|
||||
The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications directly from a command shell. we can install angular latest CLI using the following command |
||||
|
||||
`npm install -g @angular/cli` |
||||
|
||||
<ResourceGroupTitle>Free Resources</ResourceGroupTitle> |
||||
<BadgeLink colorScheme='blue' badgeText='Official Website' href='https://angular.io/cli'>Angular CLI - Angular.io</BadgeLink> |
||||
<BadgeLink colorScheme='yellow' badgeText='watch' href='https://www.youtube.com/watch?v=mZnzX3J5XKI'>Angular CLI - setup</BadgeLink> |