Compare commits

..

3 Commits

Author SHA1 Message Date
Kamran Ahmed
83504f495b Merge branch 'master' into content/spring-boot 2023-01-12 14:38:38 +04:00
Kamran Ahmed
fc6e8048a7 Update content files 2023-01-12 14:35:57 +04:00
mouaaz
fa9d8d6656 Initial commit 2023-01-11 21:49:06 +05:00
681 changed files with 1689 additions and 6483 deletions

View File

@@ -1,21 +0,0 @@
name: Sends Daily AWS Costs to Slack
on:
# Allow manual Run
workflow_dispatch:
# Run at 7:00 UTC every day
schedule:
- cron: "0 7 * * *"
jobs:
aws_costs:
runs-on: ubuntu-latest
steps:
- name: Get Costs
env:
AWS_KEY: ${{ secrets.COST_AWS_ACCESS_KEY }}
AWS_SECRET: ${{ secrets.COST_AWS_SECRET_KEY }}
AWS_REGION: ${{ secrets.COST_AWS_REGION }}
SLACK_CHANNEL: ${{ secrets.SLACK_COST_CHANNEL }}
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
run: |
npm install -g aws-cost-cli
aws-cost -k $AWS_KEY -s $AWS_SECRET -r $AWS_REGION -S $SLACK_TOKEN -C $SLACK_CHANNEL

4
.gitignore vendored
View File

@@ -20,7 +20,3 @@ pnpm-debug.log*
# macOS-specific files
.DS_Store
/test-results/
/playwright-report/
/playwright/.cache/
tests-examples

View File

@@ -9,9 +9,6 @@ import { serializeSitemap, shouldIndexPage } from './sitemap.mjs';
export default defineConfig({
site: 'https://roadmap.sh',
markdown: {
shikiConfig: {
theme: 'dracula',
},
rehypePlugins: [
[
rehypeExternalLinks,
@@ -21,9 +18,6 @@ export default defineConfig({
],
],
},
build: {
format: 'file',
},
integrations: [
tailwind({
config: {

View File

@@ -1,144 +0,0 @@
const fs = require('fs');
const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the best-practices
const BEST_PRACTICE_CONTENT_DIR = path.join(__dirname, '../src/best-practices');
const bestPracticeId = process.argv[2];
const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR);
if (!bestPracticeId) {
console.error('bestPractice is required');
process.exit(1);
}
if (!allowedBestPracticeId.includes(bestPracticeId)) {
console.error(`Invalid best practice key ${bestPracticeId}`);
console.error(`Allowed keys are ${allowedBestPracticeId.join(', ')}`);
process.exit(1);
}
// Directory holding the best parctice content files
const bestPracticeDirName = fs
.readdirSync(BEST_PRACTICE_CONTENT_DIR)
.find((dirName) => dirName.replace(/\d+-/, '') === bestPracticeId);
if (!bestPracticeDirName) {
console.error('Best practice directory not found');
process.exit(1);
}
const bestPracticeDirPath = path.join(BEST_PRACTICE_CONTENT_DIR, bestPracticeDirName);
const bestPracticeContentDirPath = path.join(
BEST_PRACTICE_CONTENT_DIR,
bestPracticeDirName,
'content'
);
// If best practice content already exists do not proceed as it would override the files
if (fs.existsSync(bestPracticeContentDirPath)) {
console.error(`Best Practice content already exists @ ${bestPracticeContentDirPath}`);
process.exit(1);
}
function prepareDirTree(control, dirTree) {
// Directories are only created for groups
if (control.typeID !== '__group__') {
return;
}
// e.g. 104-testing-your-apps:other-options
const controlName = control?.properties?.controlName || '';
// No directory for a group without control name
if (!controlName || controlName.startsWith('check:') || controlName.startsWith('ext_link:')) {
return;
}
// e.g. ['testing-your-apps', 'other-options']
const dirParts = controlName.split(':');
// Nest the dir path in the dirTree
let currDirTree = dirTree;
dirParts.forEach((dirPart) => {
currDirTree[dirPart] = currDirTree[dirPart] || {};
currDirTree = currDirTree[dirPart];
});
const childrenControls = control.children.controls.control;
// No more children
if (childrenControls.length) {
childrenControls.forEach((childControl) => {
prepareDirTree(childControl, dirTree);
});
}
return { dirTree };
}
const bestPractice = require(path.join(__dirname, `../public/jsons/best-practices/${bestPracticeId}`));
const controls = bestPractice.mockup.controls.control;
// Prepare the dir tree that we will be creating
const dirTree = {};
controls.forEach((control) => {
prepareDirTree(control, dirTree);
});
/**
* @param parentDir Parent directory in which directory is to be created
* @param dirTree Nested dir tree to be created
* @param filePaths The mapping from groupName to file path
*/
function createDirTree(parentDir, dirTree, filePaths = {}) {
const childrenDirNames = Object.keys(dirTree);
const hasChildren = childrenDirNames.length !== 0;
// @todo write test for this, yolo for now
const groupName = parentDir
.replace(bestPracticeContentDirPath, '') // Remove base dir path
.replace(/(^\/)|(\/$)/g, '') // Remove trailing slashes
.replaceAll('/', ':') // Replace slashes with `:`
.replace(/:\d+-/, ':');
const humanizedGroupName = groupName
.split(':')
.pop()
?.replaceAll('-', ' ')
.replace(/^\w/, ($0) => $0.toUpperCase());
// If no children, create a file for this under the parent directory
if (!hasChildren) {
let fileName = `${parentDir}.md`;
fs.writeFileSync(fileName, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = fileName.replace(CONTENT_DIR, '');
return filePaths;
}
// There *are* children, so create the parent as a directory
// and create `index.md` as the content file for this
fs.mkdirSync(parentDir);
let readmeFilePath = path.join(parentDir, 'index.md');
fs.writeFileSync(readmeFilePath, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = readmeFilePath.replace(CONTENT_DIR, '');
// For each of the directory names, create a
// directory inside the given directory
childrenDirNames.forEach((dirName) => {
createDirTree(
path.join(parentDir, dirName),
dirTree[dirName],
filePaths
);
});
return filePaths;
}
// Create directories and get back the paths for created directories
createDirTree(bestPracticeContentDirPath, dirTree);
console.log('Created best practice content directory structure');

View File

@@ -2,18 +2,13 @@ const fs = require('node:fs');
const path = require('node:path');
const jsonsDir = path.join(process.cwd(), 'public/jsons');
const childJsonDirs = fs.readdirSync(jsonsDir);
const jsonFiles = fs.readdirSync(jsonsDir);
childJsonDirs.forEach((childJsonDir) => {
const fullChildJsonDirPath = path.join(jsonsDir, childJsonDir);
const jsonFiles = fs.readdirSync(fullChildJsonDirPath);
jsonFiles.forEach((jsonFileName) => {
console.log(`Compressing ${jsonFileName}...`);
jsonFiles.forEach((jsonFileName) => {
console.log(`Compressing ${jsonFileName}...`);
const jsonFilePath = path.join(jsonsDir, jsonFileName);
const json = require(jsonFilePath);
const jsonFilePath = path.join(fullChildJsonDirPath, jsonFileName);
const json = require(jsonFilePath);
fs.writeFileSync(jsonFilePath, JSON.stringify(json));
});
fs.writeFileSync(jsonFilePath, JSON.stringify(json));
});

View File

@@ -1,28 +0,0 @@
## CLI Tools
> A bunch of CLI scripts to make the development easier
## `roadmap-links.cjs`
Generates a list of all the resources links in any roadmap file.
## `compress-jsons.cjs`
Compresses all the JSON files in the `public/jsons` folder
## `roadmap-content.cjs`
This command is used to create the content folders and files for the interactivity of the roadmap. You can use the below command to generate the roadmap skeletons inside a roadmap directory:
```bash
npm run roadmap-content [frontend|backend|devops|...]
```
For the content skeleton to be generated, we should have proper grouping, and the group names in the project files. You can follow the steps listed below in order to add the meta information to the roadmap.
- Remove all the groups from the roadmaps through the project editor. Select all and press `cmd+shift+g`
- Identify the boxes that should be clickable and group them together with `cmd+shift+g`
- Assign the name to the groups.
- Group names have the format of `[sort]-[slug]` e.g. `100-internet`. Each group name should start with a number starting from 100 which helps with sorting of the directories and the files. Groups at the same level have the sequential sorting information.
- Each groups children have a separate group and have the name similar to `[sort]-[parent-slug]:[child-slug]` where sort refers to the sorting of the `child-slug` and not the parent. Also parent-slug does not need to have the sorting information as a part of slug e.g. if parent was `100-internet` the children would be `100-internet:how-does-the-internet-work`, `101-internet:what-is-http`, `102-internet:browsers`.

View File

@@ -82,7 +82,7 @@ function prepareDirTree(control, dirTree, dirSortOrders) {
return { dirTree, dirSortOrders };
}
const roadmap = require(path.join(__dirname, `../public/jsons/roadmaps/${roadmapId}`));
const roadmap = require(path.join(__dirname, `../public/jsons/${roadmapId}`));
const controls = roadmap.mockup.controls.control;
// Prepare the dir tree that we will be creating and also calculate the sort orders

View File

@@ -3,10 +3,10 @@
First of all thank you for considering to contribute. Please look at the details below:
- [Contribution](#contribution)
- [New Roadmaps](#new-roadmaps)
- [Existing Roadmaps](#existing-roadmaps)
- [Adding Content](#adding-content)
- [Guidelines](#guidelines)
- [New Roadmaps](#new-roadmaps)
- [Existing Roadmaps](#existing-roadmaps)
- [Adding Content](#adding-content)
- [Guidelines](#guidelines)
## New Roadmaps
@@ -23,7 +23,7 @@ For the existing roadmaps, please follow the details listed for the nature of co
## Adding Content
Find [the content directory inside the relevant roadmap](https://github.com/kamranahmedse/developer-roadmap/tree/master/src/roadmaps). Please keep the following guidelines in mind when submitting content:
Find [the content directory inside the relevant roadmap](https://github.com/kamranahmedse/roadmap-astro/tree/master/src/roadmaps). Please keep the following guidelines in mind when submitting content:
- Content must be in English.
- Put a brief description about the topic on top of the file and the a list of links below with each link having title of the URL.

View File

@@ -13,28 +13,25 @@
"compress:jsons": "node bin/compress-jsons.cjs",
"upgrade": "ncu -u",
"roadmap-links": "node bin/roadmap-links.cjs",
"roadmap-content": "node bin/roadmap-content.cjs",
"best-practice-content": "node bin/best-practice-content.cjs",
"test:e2e": "playwright test"
"roadmap-content": "node bin/roadmap-content.cjs"
},
"dependencies": {
"@astrojs/sitemap": "^1.0.0",
"@astrojs/tailwind": "^2.1.3",
"astro": "^1.9.2",
"astro-compress": "^1.1.28",
"astro": "^1.8.0",
"astro-compress": "^1.1.24",
"astro-critters": "^1.1.24",
"node-html-parser": "^6.1.4",
"npm-check-updates": "^16.6.2",
"rehype-external-links": "^2.0.1",
"roadmap-renderer": "^1.0.4",
"roadmap-renderer": "^1.0.1",
"tailwindcss": "^3.2.4"
},
"devDependencies": {
"@playwright/test": "^1.29.2",
"@tailwindcss/typography": "^0.5.9",
"gh-pages": "^5.0.0",
"@tailwindcss/typography": "^0.5.8",
"gh-pages": "^4.0.0",
"json-to-pretty-yaml": "^1.2.2",
"markdown-it": "^13.0.1",
"prettier": "^2.8.3",
"prettier-plugin-astro": "^0.7.2"
"prettier": "^2.8.1",
"prettier-plugin-astro": "^0.7.0"
}
}

View File

@@ -1,108 +0,0 @@
import type { PlaywrightTestConfig } from '@playwright/test';
import { devices } from '@playwright/test';
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
const config: PlaywrightTestConfig = {
testDir: './tests',
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000,
},
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:3000',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},
/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
// {
// name: 'firefox',
// use: {
// ...devices['Desktop Firefox'],
// },
// },
// {
// name: 'webkit',
// use: {
// ...devices['Desktop Safari'],
// },
// },
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: {
// ...devices['Pixel 5'],
// },
// },
// {
// name: 'Mobile Safari',
// use: {
// ...devices['iPhone 12'],
// },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: {
// channel: 'msedge',
// },
// },
// {
// name: 'Google Chrome',
// use: {
// channel: 'chrome',
// },
// },
],
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/',
/* Run your local dev server before starting the tests */
webServer: {
command: 'npm run dev',
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
},
};
export default config;

220
pnpm-lock.yaml generated
View File

@@ -3,40 +3,38 @@ lockfileVersion: 5.4
specifiers:
'@astrojs/sitemap': ^1.0.0
'@astrojs/tailwind': ^2.1.3
'@playwright/test': ^1.29.2
'@tailwindcss/typography': ^0.5.9
astro: ^1.9.2
astro-compress: ^1.1.28
gh-pages: ^5.0.0
'@tailwindcss/typography': ^0.5.8
astro: ^1.8.0
astro-compress: ^1.1.24
astro-critters: ^1.1.24
gh-pages: ^4.0.0
json-to-pretty-yaml: ^1.2.2
markdown-it: ^13.0.1
node-html-parser: ^6.1.4
npm-check-updates: ^16.6.2
prettier: ^2.8.3
prettier-plugin-astro: ^0.7.2
prettier: ^2.8.1
prettier-plugin-astro: ^0.7.0
rehype-external-links: ^2.0.1
roadmap-renderer: ^1.0.4
roadmap-renderer: ^1.0.1
tailwindcss: ^3.2.4
dependencies:
'@astrojs/sitemap': 1.0.0
'@astrojs/tailwind': 2.1.3_tailwindcss@3.2.4
astro: 1.9.2
astro-compress: 1.1.28
astro: 1.8.0
astro-compress: 1.1.24
astro-critters: 1.1.24
node-html-parser: 6.1.4
npm-check-updates: 16.6.2
rehype-external-links: 2.0.1
roadmap-renderer: 1.0.4
roadmap-renderer: 1.0.1
tailwindcss: 3.2.4
devDependencies:
'@playwright/test': 1.29.2
'@tailwindcss/typography': 0.5.9_tailwindcss@3.2.4
gh-pages: 5.0.0
'@tailwindcss/typography': 0.5.8_tailwindcss@3.2.4
gh-pages: 4.0.0
json-to-pretty-yaml: 1.2.2
markdown-it: 13.0.1
prettier: 2.8.3
prettier-plugin-astro: 0.7.2
prettier: 2.8.1
prettier-plugin-astro: 0.7.0
packages:
@@ -48,8 +46,12 @@ packages:
'@jridgewell/trace-mapping': 0.3.17
dev: false
/@astrojs/compiler/0.29.19:
resolution: {integrity: sha512-lvPpoOA6Fc1NpJrPT65ZOhhFieYkiBds9wzOhWX55lXMUpNPu5CUxqzgDAkNSTIoXHZxkxHfi+6EpFNnRZBBYQ==}
/@astrojs/compiler/0.31.3:
resolution: {integrity: sha512-WbA05QH5xkdaJ3XtzDuYOjtqsip2InW5rk156sSdaHs5qN2NroUHbzWZthHJwmNAAjQSGXVIj+O6jQj81zzX/Q==}
dev: false
/@astrojs/language-server/0.28.3:
resolution: {integrity: sha512-fPovAX/X46eE2w03jNRMpQ7W9m2mAvNt4Ay65lD9wl1Z5vIQYxlg7Enp9qP225muTr4jSVB5QiLumFJmZMAaVA==}
@@ -57,8 +59,8 @@ packages:
dependencies:
'@vscode/emmet-helper': 2.8.6
events: 3.3.0
prettier: 2.8.3
prettier-plugin-astro: 0.7.2
prettier: 2.8.1
prettier-plugin-astro: 0.7.0
source-map: 0.7.4
vscode-css-languageservice: 6.2.1
vscode-html-languageservice: 5.0.3
@@ -584,15 +586,6 @@ packages:
tiny-glob: 0.2.9
tslib: 2.4.1
/@playwright/test/1.29.2:
resolution: {integrity: sha512-+3/GPwOgcoF0xLz/opTnahel1/y42PdcgZ4hs+BZGIUjtmEFSXGg+nFoaH3NSmuc7a6GSFwXDJ5L7VXpqzigNg==}
engines: {node: '>=14'}
hasBin: true
dependencies:
'@types/node': 17.0.45
playwright-core: 1.29.2
dev: true
/@pnpm/network.ca-file/1.0.2:
resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==}
engines: {node: '>=12.22.0'}
@@ -640,8 +633,8 @@ packages:
defer-to-connect: 2.0.1
dev: false
/@tailwindcss/typography/0.5.9_tailwindcss@3.2.4:
resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==}
/@tailwindcss/typography/0.5.8_tailwindcss@3.2.4:
resolution: {integrity: sha512-xGQEp8KXN8Sd8m6R4xYmwxghmswrd0cPnNI2Lc6fmrC3OojysTBJJGSIVwPV56q4t6THFUK3HJ0EaWwpglSxWw==}
peerDependencies:
tailwindcss: '>=3.0.0 || insiders'
dependencies:
@@ -769,6 +762,7 @@ packages:
/@types/node/17.0.45:
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
dev: false
/@types/parse5/6.0.3:
resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==}
@@ -784,8 +778,8 @@ packages:
'@types/node': 17.0.45
dev: false
/@types/sharp/0.31.1:
resolution: {integrity: sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==}
/@types/sharp/0.31.0:
resolution: {integrity: sha512-nwivOU101fYInCwdDcH/0/Ru6yIRXOpORx25ynEOc6/IakuCmjOAGpaO5VfUl4QkDtUC6hj+Z2eCQvgXOioknw==}
dependencies:
'@types/node': 17.0.45
dev: false
@@ -939,6 +933,7 @@ packages:
/argparse/2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: false
/array-iterate/2.0.1:
resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
@@ -968,22 +963,29 @@ packages:
tslib: 2.4.1
dev: false
/astro-compress/1.1.28:
resolution: {integrity: sha512-uk4lZHug/A276T/jdtEscCFbWVI78UqlvDg4ujRL5UUcIs+nd8gJOipSagkzdGswjNkd482zFysQ9YS5/u7xVw==}
/astro-compress/1.1.24:
resolution: {integrity: sha512-S7yzhmYdHxMPn8N3E7XJFKhTuHFrwLovPyhMJAuReVmhISvR0cxubGxaYnSJZrE67vFePj5Y8Gkd82GJIjFS2A==}
dependencies:
'@types/csso': 5.0.0
'@types/html-minifier-terser': 7.0.0
'@types/sharp': 0.31.1
'@types/sharp': 0.31.0
csso: 5.0.5
files-pipeline: 0.0.2
html-minifier-terser: 7.1.0
sharp: 0.31.3
sharp: 0.31.2
svgo: 3.0.2
terser: 5.16.1
dev: false
/astro/1.9.2:
resolution: {integrity: sha512-L+Ma0eR0Aa6QZg7RF0lEs+106Ye1/zukvtq3KtsYIogAojltlwllwU9X5CwMBzFwA55NxpNp4gSRh5US/xb+8Q==}
/astro-critters/1.1.24:
resolution: {integrity: sha512-yyvAka+LeWO0LToHSc53yTjI1eUQqBDBg6uDbjEJ4vvaKegF6z122VPCFQzLe2dPeJiyYLUMUs3W5CIErZEBqQ==}
dependencies:
critters: 0.0.16
files-pipeline: 0.0.2
dev: false
/astro/1.8.0:
resolution: {integrity: sha512-MZIJveOC1OCIA0w2XmxjDtKviAEuYdF142DVq0VApInE1lm+CvAoyMgJs0a1h4mydD2vgQZpTjPhYKJIdxDjOA==}
engines: {node: ^14.18.0 || >=16.12.0, npm: '>=6.14.0'}
hasBin: true
dependencies:
@@ -1016,7 +1018,7 @@ packages:
estree-walker: 3.0.1
execa: 6.1.0
fast-glob: 3.2.12
github-slugger: 2.0.0
github-slugger: 1.5.0
gray-matter: 4.0.3
html-entities: 2.3.3
html-escaper: 3.0.3
@@ -1061,8 +1063,10 @@ packages:
- ts-node
dev: false
/async/3.2.4:
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
/async/2.6.4:
resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==}
dependencies:
lodash: 4.17.21
dev: true
/autoprefixer/10.4.13_postcss@8.4.20:
@@ -1506,6 +1510,17 @@ packages:
engines: {node: '>= 0.6'}
dev: false
/critters/0.0.16:
resolution: {integrity: sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A==}
dependencies:
chalk: 4.1.2
css-select: 4.3.0
parse5: 6.0.1
parse5-htmlparser2-tree-adapter: 6.0.1
postcss: 8.4.20
pretty-bytes: 5.6.0
dev: false
/cross-spawn/7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@@ -1521,6 +1536,16 @@ packages:
type-fest: 1.4.0
dev: false
/css-select/4.3.0:
resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==}
dependencies:
boolbase: 1.0.0
css-what: 6.1.0
domhandler: 4.3.1
domutils: 2.8.0
nth-check: 2.1.1
dev: false
/css-select/5.1.0:
resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
dependencies:
@@ -1689,6 +1714,14 @@ packages:
/dlv/1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
/dom-serializer/1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
dependencies:
domelementtype: 2.3.0
domhandler: 4.3.1
entities: 2.2.0
dev: false
/dom-serializer/2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
dependencies:
@@ -1701,6 +1734,13 @@ packages:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
dev: false
/domhandler/4.3.1:
resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==}
engines: {node: '>= 4'}
dependencies:
domelementtype: 2.3.0
dev: false
/domhandler/5.0.3:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'}
@@ -1708,6 +1748,14 @@ packages:
domelementtype: 2.3.0
dev: false
/domutils/2.8.0:
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
dependencies:
dom-serializer: 1.4.1
domelementtype: 2.3.0
domhandler: 4.3.1
dev: false
/domutils/3.0.1:
resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==}
dependencies:
@@ -1743,8 +1791,8 @@ packages:
resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==}
dev: false
/email-addresses/5.0.0:
resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==}
/email-addresses/3.1.0:
resolution: {integrity: sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==}
dev: true
/emmet/2.3.6:
@@ -1776,10 +1824,9 @@ packages:
once: 1.4.0
dev: false
/entities/3.0.1:
resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==}
engines: {node: '>=0.12'}
dev: true
/entities/2.2.0:
resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
dev: false
/entities/4.4.0:
resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==}
@@ -2277,14 +2324,14 @@ packages:
engines: {node: '>=10'}
dev: false
/gh-pages/5.0.0:
resolution: {integrity: sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ==}
/gh-pages/4.0.0:
resolution: {integrity: sha512-p8S0T3aGJc68MtwOcZusul5qPSNZCalap3NWbhRUZYu1YOdp+EjZ+4kPmRM8h3NNRdqw00yuevRjlkuSzCn7iQ==}
engines: {node: '>=10'}
hasBin: true
dependencies:
async: 3.2.4
async: 2.6.4
commander: 2.20.3
email-addresses: 5.0.0
email-addresses: 3.1.0
filenamify: 4.3.0
find-cache-dir: 3.3.2
fs-extra: 8.1.0
@@ -2299,10 +2346,6 @@ packages:
resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==}
dev: false
/github-slugger/2.0.0:
resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
dev: false
/glob-parent/5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -2997,12 +3040,6 @@ packages:
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
engines: {node: '>=10'}
/linkify-it/4.0.1:
resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==}
dependencies:
uc.micro: 1.0.6
dev: true
/load-yaml-file/0.2.0:
resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==}
engines: {node: '>=6'}
@@ -3040,7 +3077,6 @@ packages:
/lodash/4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: false
/log-symbols/5.1.0:
resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==}
@@ -3147,17 +3183,6 @@ packages:
- supports-color
dev: false
/markdown-it/13.0.1:
resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==}
hasBin: true
dependencies:
argparse: 2.0.1
entities: 3.0.1
linkify-it: 4.0.1
mdurl: 1.0.1
uc.micro: 1.0.6
dev: true
/markdown-table/3.0.3:
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
dev: false
@@ -3323,10 +3348,6 @@ packages:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
dev: false
/mdurl/1.0.1:
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
dev: true
/merge-stream/2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
dev: false
@@ -4186,6 +4207,12 @@ packages:
unist-util-visit-children: 2.0.1
dev: false
/parse5-htmlparser2-tree-adapter/6.0.1:
resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==}
dependencies:
parse5: 6.0.1
dev: false
/parse5/6.0.1:
resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==}
dev: false
@@ -4264,12 +4291,6 @@ packages:
dependencies:
find-up: 4.1.0
/playwright-core/1.29.2:
resolution: {integrity: sha512-94QXm4PMgFoHAhlCuoWyaBYKb92yOcGVHdQLoxQ7Wjlc7Flg4aC/jbFW7xMR52OfXMVkWicue4WXE7QEegbIRA==}
engines: {node: '>=14'}
hasBin: true
dev: true
/postcss-import/14.1.0_postcss@8.4.20:
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
engines: {node: '>=10.0.0'}
@@ -4370,20 +4391,25 @@ packages:
which-pm: 2.0.0
dev: false
/prettier-plugin-astro/0.7.2:
resolution: {integrity: sha512-mmifnkG160BtC727gqoimoxnZT/dwr8ASxpoGGl6EHevhfblSOeu+pwH1LAm5Qu1MynizktztFujHHaijLCkww==}
engines: {node: ^14.15.0 || >=16.0.0, pnpm: '>=7.14.0'}
/prettier-plugin-astro/0.7.0:
resolution: {integrity: sha512-ehCUx7MqHWvkHwUmxxAWLsL35pFaCTM5YXQ8xjG/1W6dY2yBhvEks+2aCfjeI5zmMrZNCXkiMQtpznSlLSLrxw==}
engines: {node: ^14.15.0 || >=16.0.0, npm: '>=6.14.0'}
dependencies:
'@astrojs/compiler': 0.31.3
prettier: 2.8.3
'@astrojs/compiler': 0.29.19
prettier: 2.8.1
sass-formatter: 0.7.5
synckit: 0.8.4
/prettier/2.8.3:
resolution: {integrity: sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==}
/prettier/2.8.1:
resolution: {integrity: sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==}
engines: {node: '>=10.13.0'}
hasBin: true
/pretty-bytes/5.6.0:
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==}
engines: {node: '>=6'}
dev: false
/prismjs/1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
engines: {node: '>=6'}
@@ -4729,8 +4755,8 @@ packages:
glob: 7.2.3
dev: false
/roadmap-renderer/1.0.4:
resolution: {integrity: sha512-TS9jDZu/CzTqxv7QWnMZHgB89WzgLpaExXKcBIWQEKtXm9g9E45t7gijZst9qtRQ2E2+iplAxQz/eMuttq4wAQ==}
/roadmap-renderer/1.0.1:
resolution: {integrity: sha512-f71DLNMfBNtwNwa5ffkXVRBL24loYJ7YMcyyeAUhbJMzEQYp9vWaArVGualylBIw95APy/UIgBZ9KuqiW1Y4UA==}
dev: false
/roarr/2.15.4:
@@ -4832,8 +4858,8 @@ packages:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
dev: false
/sharp/0.31.3:
resolution: {integrity: sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==}
/sharp/0.31.2:
resolution: {integrity: sha512-DUdNVEXgS5A97cTagSLIIp8dUZ/lZtk78iNVZgHdHbx1qnQR7JAHY0BnXnwwH39Iw+VKhO08CTYhIg0p98vQ5Q==}
engines: {node: '>=14.15.0'}
requiresBuild: true
dependencies:
@@ -5319,10 +5345,6 @@ packages:
hasBin: true
dev: false
/uc.micro/1.0.6:
resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
dev: true
/unherit/3.0.1:
resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==}
dev: false

Binary file not shown.

Before

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -7,21 +7,21 @@ async function getRoadmapIds() {
export function shouldIndexPage(page) {
return ![
'https://roadmap.sh/404',
'https://roadmap.sh/terms',
'https://roadmap.sh/privacy',
'https://roadmap.sh/pdfs',
'https://roadmap.sh/404/',
'https://roadmap.sh/terms/',
'https://roadmap.sh/privacy/',
'https://roadmap.sh/pdfs/',
].includes(page);
}
export async function serializeSitemap(item) {
const highPriorityPages = [
'https://roadmap.sh',
'https://roadmap.sh/about',
'https://roadmap.sh/roadmaps',
'https://roadmap.sh/guides',
'https://roadmap.sh/videos',
...(await getRoadmapIds()).flatMap((id) => [`https://roadmap.sh/${id}`, `https://roadmap.sh/${id}/topics`]),
'https://roadmap.sh/',
'https://roadmap.sh/about/',
'https://roadmap.sh/roadmaps/',
'https://roadmap.sh/guides/',
'https://roadmap.sh/videos/',
...(await getRoadmapIds()).map((id) => `https://roadmap.sh/${id}/`),
];
// Roadmaps and other high priority pages
@@ -32,17 +32,22 @@ export async function serializeSitemap(item) {
// @ts-ignore
changefreq: 'monthly',
priority: 1,
lastmod: new Date().toISOString(),
};
}
}
// Guide and video pages
if (item.url.startsWith('https://roadmap.sh/guides') || item.url.startsWith('https://roadmap.sh/videos')) {
if (
item.url.startsWith('https://roadmap.sh/guides/') ||
item.url.startsWith('https://roadmap.sh/videos/')
) {
return {
...item,
// @ts-ignore
changefreq: 'monthly',
priority: 0.9,
lastmod: new Date().toISOString(),
};
}

View File

@@ -1 +0,0 @@
# Analyse stylesheets complexity

View File

@@ -1 +0,0 @@
# Analyze js for perf issues

View File

@@ -1 +0,0 @@
# Avoid 404 files

View File

@@ -1 +0,0 @@
# Avoid base64 images

View File

@@ -1 +0,0 @@
# Avoid inline css

View File

@@ -1 +0,0 @@
# Avoid multiple inline js snippets

View File

@@ -1 +0,0 @@
# Bundlephobia

View File

@@ -1 +0,0 @@
# Check dependency size

View File

@@ -1 +0,0 @@
# Choose image format approprietly

View File

@@ -1 +0,0 @@
# Chrome dev tools

View File

@@ -1 +0,0 @@
# Compress your images

View File

@@ -1 +0,0 @@
# Concatenate css single file

View File

@@ -1 +0,0 @@
# Cookie size less 4096 bytes

View File

@@ -1 +0,0 @@
# Enable compression

View File

@@ -1 +0,0 @@
# Framework guides

View File

@@ -1 +0,0 @@
# Inline critical css

View File

@@ -1 +0,0 @@
# Keep cookie count below 20

View File

@@ -1 +0,0 @@
# Keep dependencies up to date

View File

@@ -1 +0,0 @@
# Keep ttfb less 1 3s

View File

@@ -1 +0,0 @@
# Keep web font under 300k

View File

@@ -1 +0,0 @@
# Lighthouse

View File

@@ -1 +0,0 @@
# Load offscreen images lazily

View File

@@ -1 +0,0 @@
# Make css files non blocking

View File

@@ -1 +0,0 @@
# Minify css

View File

@@ -1 +0,0 @@
# Minify html

View File

@@ -1 +0,0 @@
# Minify your javascript

View File

@@ -1 +0,0 @@
# Minimize http requests

View File

@@ -1,3 +0,0 @@
# Avoid iframes
Use iframes only if you don't have any other technical possibility. Try to avoid iframes as much as you can. Iframes are not only bad for performance, but also for accessibility and usability. Iframes are also not indexed by search engines.

View File

@@ -1 +0,0 @@
# Page load time below 3s

View File

@@ -1 +0,0 @@
# Page speed insights

View File

@@ -1 +0,0 @@
# Page weight below 1500

View File

@@ -1 +0,0 @@
# Pre load urls where possible

View File

@@ -1 +0,0 @@
# Prefer vector images

View File

@@ -1 +0,0 @@
# Prevent flash text

View File

@@ -1 +0,0 @@
# Recommended guides

View File

@@ -1 +0,0 @@
# Remove unused css

Some files were not shown because too many files have changed in this diff Show More