Compare commits

...

35 Commits

Author SHA1 Message Date
Arik Chakma
b1fad87eb6 feat: implement checklist 2024-03-28 02:52:40 +06:00
Kamran Ahmed
1d9adf742b Add Node.js questions link 2024-03-27 20:45:02 +00:00
Kamran Ahmed
625d9a1f5b fix: invalid link in backend performance best practices 2024-03-27 20:28:16 +00:00
Kamran Ahmed
08bc4c38ae fix: invalid link in backend performance best practices 2024-03-27 20:27:34 +00:00
Kamran Ahmed
cabbf51150 Make topic detail visible for logged in users 2024-03-27 20:25:53 +00:00
Arik Chakma
730af9b973 feat: ability to update email (#5370)
* chore: update email

* wip: verify email endpoint

* wip: implement success screen

* wip: social warning

* Update form for email update

* Update email form UI

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2024-03-27 15:38:47 +00:00
Vaibhav Chauhan
4e96a58e54 Add complexity video resource (#5399)
* feat/ Added complexity video resource

Added video resource for time and space complexity in Data structures and Algorithms section.

* Replace link

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2024-03-26 22:43:13 +00:00
Kamran Ahmed
5230ae22be Mark required fields 2024-03-26 15:54:08 +00:00
Arik Chakma
18deef46db feat: add increase generation limit options (#5388)
* wip: limit increase options

* feat: add increase AI limit options

* fix: overflow issue

* UI Updates

* UI for bypassing limits

* Refactor bypass limit

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2024-03-26 15:40:26 +00:00
Corey Barr
e6bea59ab5 Fix typo in Java Developer roadmap. (#5406) 2024-03-26 03:04:36 +00:00
Kamran Ahmed
66e4f3c97c Update twitter link 2024-03-26 03:02:39 +00:00
Kamran Ahmed
9511de967c Change backend performance dimensions 2024-03-25 21:53:25 +00:00
Kamran Ahmed
038bdb0e7d Add backend performance best practices 2024-03-25 21:34:47 +00:00
Kamran Ahmed
8a1f5d1bb4 Add backend performance best practices 2024-03-25 21:32:20 +00:00
Kamran Ahmed
3e8af3bd0f Add text-balance to guide headers 2024-03-25 21:27:30 +00:00
Kamran Ahmed
08a3970d08 Add content for backend performance best practices 2024-03-25 21:25:23 +00:00
Kamran Ahmed
e4f9b9fe01 Best practice content dir generation 2024-03-25 20:08:38 +00:00
Kamran Ahmed
2ab7690271 Best practice content dir generation 2024-03-25 19:40:53 +00:00
Kamran Ahmed
cdb9a87c85 Add backend performance best practices 2024-03-25 15:15:30 +00:00
Kamran Ahmed
0d43103323 Add "new" to new roadmaps on homepage 2024-03-25 15:11:25 +00:00
Kamran Ahmed
77d67e29eb fix: progress overflows the roadmap with 2024-03-25 15:11:05 +00:00
Aldiyar Dabarov
4a00a7bc79 Fix typo in System Design Roadmap (#5380) 2024-03-22 14:47:48 +06:00
Kamran Ahmed
ff2c13947b Add AI viewer behind signup 2024-03-21 20:34:48 +00:00
Kamran Ahmed
d880f84e0a Format result count 2024-03-20 16:22:49 +00:00
Kamran Ahmed
7cffcccfe8 Add result count on search 2024-03-20 16:13:28 +00:00
Kamran Ahmed
88ddeeb5fb Fix typescript errors 2024-03-20 15:47:30 +00:00
Kamran Ahmed
812a39154c feat: add search on the AI explore page (#5383)
* fix: type errors

* chore: implement roadmap pagination

* wip

* wip: merge conflicts

* wip: add search

* Add pagination

* Refactor AI search roadmaps

---------

Co-authored-by: Arik Chakma <arikchangma@gmail.com>
2024-03-20 15:38:08 +00:00
Arik Chakma
6e6489bc4c feat: show pre-existing results on AI search input (#5349)
* feat: ai term suggestion input

* fix: add suggestion for roadmap

* Update spinner

* fix: hydration errors

* Refactor roadmap search and suggestions

* Remove limit from frontend

* Update roadmap title

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2024-03-19 20:42:29 +00:00
Kamran Ahmed
696e4f1890 Add missing og image 2024-03-19 12:27:29 +00:00
Kamran Ahmed
37c18ec3cc Update SEO text 2024-03-19 12:21:29 +00:00
Kamran Ahmed
9e3d50a84d Update FAQ text 2024-03-19 12:17:37 +00:00
Kamran Ahmed
01c65084b5 Add FAQ for backend roadmap 2024-03-19 12:16:49 +00:00
Kamran Ahmed
05fe51ca33 Add article backend developer tools 2024-03-19 12:08:18 +00:00
Kamran Ahmed
59c0a7d451 Add high res frontend og image 2024-03-19 03:44:49 +00:00
Arik Chakma
d0bd4d6faf feat: implement open graph (#5340)
* chore: add open graph images

* fix: open graph function

* fix: open graph query params

* fix: remove guide id

* fix: generate images on build time

* fix: external author image

* fix: special character issue

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2024-03-19 03:33:04 +00:00
208 changed files with 8059 additions and 552 deletions

5
.astro/settings.json Normal file
View File

@@ -0,0 +1,5 @@
{
"devToolbar": {
"enabled": false
}
}

View File

@@ -29,7 +29,7 @@ export default defineConfig({
'mailto:',
'https://github.com/kamranahmedse',
'https://thenewstack.io',
'https://cs.fyi',
'https://kamranahmed.info',
'https://roadmap.sh',
];
if (whiteListedStarts.some((start) => href.startsWith(start))) {

View File

@@ -19,6 +19,7 @@
"generate-renderer": "sh scripts/generate-renderer.sh",
"best-practice-dirs": "node scripts/best-practice-dirs.cjs",
"best-practice-content": "node scripts/best-practice-content.cjs",
"generate:og": "node ./scripts/generate-og-images.mjs",
"test:e2e": "playwright test"
},
"dependencies": {
@@ -27,6 +28,7 @@
"@astrojs/tailwind": "^5.1.0",
"@fingerprintjs/fingerprintjs": "^4.2.2",
"@nanostores/react": "^0.7.1",
"@resvg/resvg-js": "^2.6.0",
"@types/react": "^18.2.56",
"@types/react-dom": "^18.2.19",
"astro": "^4.4.0",
@@ -34,9 +36,12 @@
"clsx": "^2.1.0",
"dom-to-image": "^2.6.0",
"dracula-prism": "^2.1.16",
"gray-matter": "^4.0.3",
"htm": "^3.1.1",
"image-size": "^1.1.1",
"jose": "^5.2.2",
"js-cookie": "^3.0.5",
"lucide-react": "^0.334.0",
"lucide-react": "^0.358.0",
"nanoid": "^5.0.5",
"nanostores": "^0.9.5",
"node-html-parser": "^6.1.12",
@@ -49,6 +54,9 @@
"rehype-external-links": "^3.0.0",
"remark-parse": "^11.0.0",
"roadmap-renderer": "^1.0.6",
"satori": "^0.10.13",
"satori-html": "^0.3.2",
"sharp": "^0.33.2",
"slugify": "^1.6.6",
"tailwind-merge": "^2.2.1",
"tailwindcss": "^3.4.1",

287
pnpm-lock.yaml generated
View File

@@ -20,6 +20,9 @@ dependencies:
'@nanostores/react':
specifier: ^0.7.1
version: 0.7.1(nanostores@0.9.5)(react@18.2.0)
'@resvg/resvg-js':
specifier: ^2.6.0
version: 2.6.0
'@types/react':
specifier: ^18.2.56
version: 18.2.59
@@ -41,6 +44,15 @@ dependencies:
dracula-prism:
specifier: ^2.1.16
version: 2.1.16
gray-matter:
specifier: ^4.0.3
version: 4.0.3
htm:
specifier: ^3.1.1
version: 3.1.1
image-size:
specifier: ^1.1.1
version: 1.1.1
jose:
specifier: ^5.2.2
version: 5.2.2
@@ -48,8 +60,8 @@ dependencies:
specifier: ^3.0.5
version: 3.0.5
lucide-react:
specifier: ^0.334.0
version: 0.334.0(react@18.2.0)
specifier: ^0.358.0
version: 0.358.0(react@18.2.0)
nanoid:
specifier: ^5.0.5
version: 5.0.5
@@ -86,6 +98,15 @@ dependencies:
roadmap-renderer:
specifier: ^1.0.6
version: 1.0.6
satori:
specifier: ^0.10.13
version: 0.10.13
satori-html:
specifier: ^0.3.2
version: 0.3.2
sharp:
specifier: ^0.33.2
version: 0.33.2
slugify:
specifier: ^1.6.6
version: 1.6.6
@@ -1222,6 +1243,132 @@ packages:
- immer
dev: false
/@resvg/resvg-js-android-arm-eabi@2.6.0:
resolution: {integrity: sha512-lJnZ/2P5aMocrFMW7HWhVne5gH82I8xH6zsfH75MYr4+/JOaVcGCTEQ06XFohGMdYRP3v05SSPLPvTM/RHjxfA==}
engines: {node: '>= 10'}
cpu: [arm]
os: [android]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-android-arm64@2.6.0:
resolution: {integrity: sha512-N527f529bjMwYWShZYfBD60dXA4Fux+D695QsHQ93BDYZSHUoOh1CUGUyICevnTxs7VgEl98XpArmUWBZQVMfQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-darwin-arm64@2.6.0:
resolution: {integrity: sha512-MabUKLVayEwlPo0mIqAmMt+qESN8LltCvv5+GLgVga1avpUrkxj/fkU1TKm8kQegutUjbP/B0QuMuUr0uhF8ew==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-darwin-x64@2.6.0:
resolution: {integrity: sha512-zrFetdnSw/suXjmyxSjfDV7i61hahv6DDG6kM7BYN2yJ3Es5+BZtqYZTcIWogPJedYKmzN1YTMWGd/3f0ubFiA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-linux-arm-gnueabihf@2.6.0:
resolution: {integrity: sha512-sH4gxXt7v7dGwjGyzLwn7SFGvwZG6DQqLaZ11MmzbCwd9Zosy1TnmrMJfn6TJ7RHezmQMgBPi18bl55FZ1AT4A==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-linux-arm64-gnu@2.6.0:
resolution: {integrity: sha512-fCyMncqCJtrlANADIduYF4IfnWQ295UKib7DAxFXQhBsM9PLDTpizr0qemZcCNadcwSVHnAIzL4tliZhCM8P6A==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-linux-arm64-musl@2.6.0:
resolution: {integrity: sha512-ouLjTgBQHQyxLht4FdMPTvuY8xzJigM9EM2Tlu0llWkN1mKyTQrvYWi6TA6XnKdzDJHy7ZLpWpjZi7F5+Pg+Vg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-linux-x64-gnu@2.6.0:
resolution: {integrity: sha512-n3zC8DWsvxC1AwxpKFclIPapDFibs5XdIRoV/mcIlxlh0vseW1F49b97F33BtJQRmlntsqqN6GMMqx8byB7B+Q==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-linux-x64-musl@2.6.0:
resolution: {integrity: sha512-n4tasK1HOlAxdTEROgYA1aCfsEKk0UOFDNd/AQTTZlTmCbHKXPq+O8npaaKlwXquxlVK8vrkcWbksbiGqbCAcw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-win32-arm64-msvc@2.6.0:
resolution: {integrity: sha512-X2+EoBJFwDI5LDVb51Sk7ldnVLitMGr9WwU/i21i3fAeAXZb3hM16k67DeTy16OYkT2dk/RfU1tP1wG+rWbz2Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-win32-ia32-msvc@2.6.0:
resolution: {integrity: sha512-L7oevWjQoUgK5W1fCKn0euSVemhDXVhrjtwqpc7MwBKKimYeiOshO1Li1pa8bBt5PESahenhWgdB6lav9O0fEg==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js-win32-x64-msvc@2.6.0:
resolution: {integrity: sha512-8lJlghb+Unki5AyKgsnFbRJwkEj9r1NpwyuBG8yEJiG1W9eEGl03R3I7bsVa3haof/3J1NlWf0rzSa1G++A2iw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@resvg/resvg-js@2.6.0:
resolution: {integrity: sha512-Tf3YpbBKcQn991KKcw/vg7vZf98v01seSv6CVxZBbRkL/xyjnoYB6KgrFL6zskT1A4dWC/vg77KyNOW+ePaNlA==}
engines: {node: '>= 10'}
optionalDependencies:
'@resvg/resvg-js-android-arm-eabi': 2.6.0
'@resvg/resvg-js-android-arm64': 2.6.0
'@resvg/resvg-js-darwin-arm64': 2.6.0
'@resvg/resvg-js-darwin-x64': 2.6.0
'@resvg/resvg-js-linux-arm-gnueabihf': 2.6.0
'@resvg/resvg-js-linux-arm64-gnu': 2.6.0
'@resvg/resvg-js-linux-arm64-musl': 2.6.0
'@resvg/resvg-js-linux-x64-gnu': 2.6.0
'@resvg/resvg-js-linux-x64-musl': 2.6.0
'@resvg/resvg-js-win32-arm64-msvc': 2.6.0
'@resvg/resvg-js-win32-ia32-msvc': 2.6.0
'@resvg/resvg-js-win32-x64-msvc': 2.6.0
dev: false
/@rollup/rollup-android-arm-eabi@4.9.6:
resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==}
cpu: [arm]
@@ -1326,6 +1473,15 @@ packages:
dev: false
optional: true
/@shuding/opentype.js@1.4.0-beta.0:
resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==}
engines: {node: '>= 8.0.0'}
hasBin: true
dependencies:
fflate: 0.7.4
string.prototype.codepointat: 0.2.1
dev: false
/@sigstore/bundle@1.1.0:
resolution: {integrity: sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -2047,6 +2203,11 @@ packages:
resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==}
dev: false
/base64-js@0.0.8:
resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==}
engines: {node: '>= 0.4'}
dev: false
/base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
dev: false
@@ -2223,6 +2384,10 @@ packages:
engines: {node: '>=14.16'}
dev: false
/camelize@1.0.1:
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
dev: false
/caniuse-lite@1.0.30001579:
resolution: {integrity: sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==}
dev: false
@@ -2364,6 +2529,7 @@ packages:
/color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
requiresBuild: true
dependencies:
color-name: 1.1.4
simple-swizzle: 0.2.2
@@ -2477,6 +2643,19 @@ packages:
type-fest: 1.4.0
dev: false
/css-background-parser@0.1.0:
resolution: {integrity: sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==}
dev: false
/css-box-shadow@1.0.0-3:
resolution: {integrity: sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==}
dev: false
/css-color-keywords@1.0.0:
resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==}
engines: {node: '>=4'}
dev: false
/css-select@5.1.0:
resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
dependencies:
@@ -2487,6 +2666,14 @@ packages:
nth-check: 2.1.1
dev: false
/css-to-react-native@3.2.0:
resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
dependencies:
camelize: 1.0.1
css-color-keywords: 1.0.0
postcss-value-parser: 4.2.0
dev: false
/css-tree@2.2.1:
resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
@@ -2854,6 +3041,10 @@ packages:
engines: {node: '>=12'}
dev: false
/escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
dev: false
/escape-string-regexp@1.0.5:
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'}
@@ -2946,6 +3137,10 @@ packages:
dependencies:
reusify: 1.0.4
/fflate@0.7.4:
resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==}
dev: false
/filename-reserved-regex@2.0.0:
resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==}
engines: {node: '>=4'}
@@ -3402,6 +3597,11 @@ packages:
hasBin: true
dev: false
/hex-rgb@4.3.0:
resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==}
engines: {node: '>=6'}
dev: false
/hosted-git-info@5.2.1:
resolution: {integrity: sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
@@ -3416,6 +3616,10 @@ packages:
lru-cache: 7.18.3
dev: false
/htm@3.1.1:
resolution: {integrity: sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==}
dev: false
/html-escaper@3.0.3:
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
dev: false
@@ -3506,6 +3710,14 @@ packages:
engines: {node: '>= 4'}
dev: false
/image-size@1.1.1:
resolution: {integrity: sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==}
engines: {node: '>=16.x'}
hasBin: true
dependencies:
queue: 6.0.2
dev: false
/import-lazy@4.0.0:
resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
engines: {node: '>=8'}
@@ -3563,6 +3775,7 @@ packages:
/is-arrayish@0.3.2:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
requiresBuild: true
dev: false
/is-binary-path@2.1.0:
@@ -3916,6 +4129,13 @@ packages:
resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==}
engines: {node: '>=14'}
/linebreak@1.1.0:
resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==}
dependencies:
base64-js: 0.0.8
unicode-trie: 2.0.0
dev: false
/lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
@@ -4016,8 +4236,8 @@ packages:
engines: {node: '>=12'}
dev: false
/lucide-react@0.334.0(react@18.2.0):
resolution: {integrity: sha512-y0Rv/Xx6qAq4FutZ3L/efl3O9vl6NC/1p0YOg6mBfRbQ4k1JCE2rz0rnV7WC8Moxq1RY99vLATvjcqUegGJTvA==}
/lucide-react@0.358.0(react@18.2.0):
resolution: {integrity: sha512-rBSptRjZTMBm24zsFhR6pK/NgbT18JegZGKcH4+1H3+UigMSRpeoWLtR/fAwMYwYnlJOZB+y8WpeHne9D6X6Kg==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0
dependencies:
@@ -5116,6 +5336,10 @@ packages:
- supports-color
dev: false
/pako@0.2.9:
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
dev: false
/param-case@3.0.4:
resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
dependencies:
@@ -5123,6 +5347,13 @@ packages:
tslib: 2.6.2
dev: false
/parse-css-color@0.2.1:
resolution: {integrity: sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==}
dependencies:
color-name: 1.1.4
hex-rgb: 4.3.0
dev: false
/parse-github-url@1.0.2:
resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==}
engines: {node: '>=0.10.0'}
@@ -5505,6 +5736,12 @@ packages:
dev: false
optional: true
/queue@6.0.2:
resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==}
dependencies:
inherits: 2.0.4
dev: false
/quick-lru@5.1.1:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
engines: {node: '>=10'}
@@ -5886,6 +6123,28 @@ packages:
suf-log: 2.5.3
dev: true
/satori-html@0.3.2:
resolution: {integrity: sha512-wjTh14iqADFKDK80e51/98MplTGfxz2RmIzh0GqShlf4a67+BooLywF17TvJPD6phO0Hxm7Mf1N5LtRYvdkYRA==}
dependencies:
ultrahtml: 1.5.2
dev: false
/satori@0.10.13:
resolution: {integrity: sha512-klCwkVYMQ/ZN5inJLHzrUmGwoRfsdP7idB5hfpJ1jfiJk1ErDitK8Hkc6Kll1+Ox2WtqEuGecSZLnmup3CGzvQ==}
engines: {node: '>=16'}
dependencies:
'@shuding/opentype.js': 1.4.0-beta.0
css-background-parser: 0.1.0
css-box-shadow: 1.0.0-3
css-to-react-native: 3.2.0
emoji-regex: 10.3.0
escape-html: 1.0.3
linebreak: 1.1.0
parse-css-color: 0.2.1
postcss-value-parser: 4.2.0
yoga-wasm-web: 0.3.3
dev: false
/sax@1.3.0:
resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==}
dev: false
@@ -6041,6 +6300,7 @@ packages:
/simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
requiresBuild: true
dependencies:
is-arrayish: 0.3.2
dev: false
@@ -6211,6 +6471,10 @@ packages:
strip-ansi: 7.1.0
dev: false
/string.prototype.codepointat@0.2.1:
resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==}
dev: false
/string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
dependencies:
@@ -6427,6 +6691,10 @@ packages:
dependencies:
any-promise: 1.3.0
/tiny-inflate@1.0.3:
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
dev: false
/to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@@ -6529,6 +6797,13 @@ packages:
resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==}
dev: false
/unicode-trie@2.0.0:
resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==}
dependencies:
pako: 0.2.9
tiny-inflate: 1.0.3
dev: false
/unified@10.1.2:
resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==}
dependencies:
@@ -6945,6 +7220,10 @@ packages:
engines: {node: '>=12.20'}
dev: false
/yoga-wasm-web@0.3.3:
resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==}
dev: false
/zod@3.22.4:
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
dev: false

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

3
public/images/graph.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg width="46" height="27" viewBox="0 0 46 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M43.354 0.9C42.184 0.9 41.2371 1.84684 41.2371 3.01686C41.2371 3.30867 41.3062 3.57708 41.4117 3.82435L33.4085 15.0163C33.38 15.0161 33.3514 15.0167 33.3248 15.0172C33.3051 15.0176 33.2864 15.018 33.2697 15.018C32.8703 15.018 32.484 15.1223 32.161 15.3186L25.2976 11.9024C25.1995 10.8219 24.2903 9.97585 23.1854 9.97585C22.0154 9.97585 21.0686 10.9227 21.0686 12.0927C21.0686 12.1865 21.0799 12.2794 21.0925 12.3656L13.8077 18.1561C13.5852 18.0783 13.3472 18.0433 13.1011 18.0433C12.0622 18.0433 11.2066 18.7882 11.0265 19.7732L4.26122 22.5041C3.91213 22.2447 3.48642 22.077 3.01686 22.077C1.84684 22.077 0.9 23.0238 0.9 24.1938C0.9 25.3639 1.84684 26.3107 3.01686 26.3107C4.06426 26.3107 4.92372 25.5497 5.0923 24.5492L11.8566 21.8497C12.2057 22.1092 12.6315 22.277 13.1011 22.277C14.2711 22.277 15.218 21.3301 15.218 20.1601C15.218 20.0663 15.2067 19.9735 15.194 19.8873L22.4789 14.0968C22.7013 14.1746 22.9393 14.2096 23.1854 14.2096C23.5848 14.2096 23.9711 14.1053 24.2941 13.909L31.1575 17.3252C31.2556 18.4057 32.1649 19.2517 33.2697 19.2517C34.4397 19.2517 35.3866 18.3049 35.3866 17.1348C35.3866 16.843 35.3175 16.5746 35.2119 16.3273L43.2151 5.13536C43.2437 5.13561 43.2723 5.13503 43.2989 5.13449C43.3186 5.13409 43.3373 5.13371 43.354 5.13371C44.524 5.13371 45.4708 4.18687 45.4708 3.01686C45.4708 1.84684 44.524 0.9 43.354 0.9Z" fill="black" stroke="black" stroke-width="0.2" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 KiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -74,14 +74,16 @@ Here is the list of available roadmaps with more being actively worked upon.
There are also interactive best practices:
- [Code Review Best Practices](https://roadmap.sh/best-practices/code-review)
- [Backend Performance Best Practices](https://roadmap.sh/best-practices/backend-performance)
- [Frontend Performance Best Practices](https://roadmap.sh/best-practices/frontend-performance)
- [Code Review Best Practices](https://roadmap.sh/best-practices/code-review)
- [API Security Best Practices](https://roadmap.sh/best-practices/api-security)
- [AWS Best Practices](https://roadmap.sh/best-practices/aws)
..and questions to help you test, rate and improve your knowledge
- [JavaScript Questions](https://roadmap.sh/questions/javascript)
- [Node.js Questions](https://roadmap.sh/questions/nodejs)
- [React Questions](https://roadmap.sh/questions/react)
![](https://i.imgur.com/waxVImv.png)

View File

@@ -4,11 +4,7 @@ const path = require('path');
const OPEN_AI_API_KEY = process.env.OPEN_AI_API_KEY;
const ALL_BEST_PRACTICES_DIR = path.join(
__dirname,
'../src/data/best-practices'
);
const BEST_PRACTICE_JSON_DIR = path.join(
__dirname,
'../public/jsons/best-practices'
'../src/data/best-practices',
);
const bestPracticeId = process.argv[2];
@@ -29,15 +25,14 @@ if (!allowedBestPracticeIds.includes(bestPracticeId)) {
const BEST_PRACTICE_CONTENT_DIR = path.join(
ALL_BEST_PRACTICES_DIR,
bestPracticeId,
'content'
'content',
);
const { Configuration, OpenAIApi } = require('openai');
const configuration = new Configuration({
const OpenAI = require('openai');
const openai = new OpenAI({
apiKey: OPEN_AI_API_KEY,
});
const openai = new OpenAIApi(configuration);
function getFilesInFolder(folderPath, fileList = {}) {
const files = fs.readdirSync(folderPath);
@@ -62,13 +57,19 @@ function getFilesInFolder(folderPath, fileList = {}) {
}
function writeTopicContent(topicTitle) {
let prompt = `I am reading a guide that has best practices about "${bestPracticeTitle}". I want to know more about "${topicTitle}". Write me a brief introductory paragraph about this and some tips on how I make sure of this? Behave as if you are the author of the guide.`;
let prompt = `I will give you a topic and you need to write a brief paragraph with examples (if possible) about why it is important for the "${bestPracticeTitle}". Just reply to the question without adding any other information about the prompt and use simple language. Also do not start your sentences with "XYZ is important because..". Your format should be as follows:
# (Put a heading for the topic)
(Write a brief paragraph about why it is important for the "${bestPracticeTitle})
First topic is: ${topicTitle}`;
console.log(`Generating '${topicTitle}'...`);
return new Promise((resolve, reject) => {
openai
.createChatCompletion({
openai.chat.completions
.create({
model: 'gpt-4',
messages: [
{
@@ -78,7 +79,7 @@ function writeTopicContent(topicTitle) {
],
})
.then((response) => {
const article = response.data.choices[0].message.content;
const article = response.choices[0].message.content;
resolve(article);
})
@@ -90,9 +91,12 @@ function writeTopicContent(topicTitle) {
async function writeFileForGroup(group, topicUrlToPathMapping) {
const topicId = group?.properties?.controlName;
const topicTitle = group?.children?.controls?.control?.find(
(control) => control?.typeID === 'Label'
)?.properties?.text;
const topicTitle = group?.children?.controls?.control
?.filter((control) => control?.typeID === 'Label')
.map((control) => control?.properties?.text)
.join(' ')
.toLowerCase();
const currTopicUrl = `/${topicId}`;
if (currTopicUrl.startsWith('/check:')) {
return;
@@ -102,7 +106,6 @@ async function writeFileForGroup(group, topicUrlToPathMapping) {
if (!contentFilePath) {
console.log(`Missing file for: ${currTopicUrl}`);
process.exit(0);
return;
}
@@ -123,8 +126,13 @@ async function writeFileForGroup(group, topicUrlToPathMapping) {
return;
}
if (!topicTitle) {
console.log(`Skipping ${topicId}. No title.`);
return;
}
const topicContent = await writeTopicContent(topicTitle);
newFileContent += `\n\n${topicContent}`;
newFileContent = `${topicContent}`;
console.log(`Writing ${topicId}..`);
fs.writeFileSync(contentFilePath, newFileContent, 'utf8');
@@ -138,14 +146,14 @@ async function writeFileForGroup(group, topicUrlToPathMapping) {
async function run() {
const topicUrlToPathMapping = getFilesInFolder(BEST_PRACTICE_CONTENT_DIR);
const bestPracticeJson = require(path.join(
BEST_PRACTICE_JSON_DIR,
`${bestPracticeId}.json`
));
const bestPracticeJson = require(
path.join(ALL_BEST_PRACTICES_DIR, `${bestPracticeId}/${bestPracticeId}`),
);
const groups = bestPracticeJson?.mockup?.controls?.control?.filter(
(control) =>
control.typeID === '__group__' &&
!control.properties?.controlName?.startsWith('ext_link')
!control.properties?.controlName?.startsWith('ext_link'),
);
if (!OPEN_AI_API_KEY) {

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