Merge branch 'master' into feat/dashboard

feat/dashboard
Arik Chakma 2 months ago
commit 7e0dd7dd51
  1. 2
      .astro/settings.json
  2. 1
      .astro/types.d.ts
  3. 16
      .github/workflows/cloudfront-api-cache.yml
  4. 2
      .github/workflows/cloudfront-fe-cache.yml
  5. 24
      contributing.md
  6. 377
      package-lock.json
  7. 6
      package.json
  8. 666
      pnpm-lock.yaml
  9. 55
      public/roadmap-content/android.json
  10. 75
      public/roadmap-content/angular.json
  11. 4
      public/roadmap-content/backend.json
  12. 111
      public/roadmap-content/cyber-security.json
  13. 5
      public/roadmap-content/devops.json
  14. 10
      public/roadmap-content/frontend.json
  15. 30
      public/roadmap-content/game-developer.json
  16. 104
      public/roadmap-content/javascript.json
  17. 10
      public/roadmap-content/nodejs.json
  18. 34
      public/roadmap-content/python.json
  19. 45
      public/roadmap-content/software-architect.json
  20. 22
      public/roadmap-content/sql.json
  21. 2
      public/roadmap-content/terraform.json
  22. 2
      readme.md
  23. 227
      src/components/AdvertiseForm.tsx
  24. 1
      src/components/CustomRoadmap/CustomRoadmap.tsx
  25. 15
      src/components/Footer.astro
  26. 6
      src/components/NavigationDropdown.tsx
  27. 74
      src/components/Projects/ProjectSolutionModal.tsx
  28. 6
      src/components/Projects/StatusStepper/ProjectStepper.tsx
  29. 23
      src/components/Projects/SubmitProjectModal.tsx
  30. 73
      src/components/Projects/SubmitSuccessModal.tsx
  31. 17
      src/components/ReactIcons/FacebookIcon.tsx
  32. 52
      src/components/ReactIcons/LinkedInIcon.tsx
  33. 4
      src/components/ReactIcons/ShareIcon.tsx
  34. 16
      src/components/ReactIcons/TwitterIcon.tsx
  35. 1
      src/components/TeamMarketing/TeamPricing.tsx
  36. 33
      src/components/TopicDetail/ResourceListSeparator.tsx
  37. 254
      src/components/TopicDetail/TopicDetail.tsx
  38. 57
      src/components/TopicDetail/TopicDetailLink.tsx
  39. 2
      src/components/UserPublicProfile/UserPublicProfileHeader.tsx
  40. 4
      src/data/guides/backend-project-ideas.md
  41. 452
      src/data/guides/backend-technologies.md
  42. 2
      src/data/guides/devops-career-path.md
  43. 53
      src/data/projects/basic-html-website.md
  44. 8
      src/data/roadmaps/android/content/animations@Xn1VQ-xOT67ZfJJTM4r1p.md
  45. 8
      src/data/roadmaps/android/content/constraint@3fFNMhQIuuh-NRzSXYpXO.md
  46. 8
      src/data/roadmaps/android/content/drawer@amTxz7mS98lkhOrNMJXG_.md
  47. 9
      src/data/roadmaps/android/content/listview@EzLjX4iRT7AxkAOsJYnSU.md
  48. 33
      src/data/roadmaps/angular/angular.json
  49. 9
      src/data/roadmaps/angular/content/build-environments@Ax-s_xw3FO3Ocv-AnLbQD.md
  50. 9
      src/data/roadmaps/angular/content/case@cHC2MH50CbUSMRZV4QGJI.md
  51. 10
      src/data/roadmaps/angular/content/cli-builders@TeWEy9I-hU6SH02Sy2S2S.md
  52. 10
      src/data/roadmaps/angular/content/creating-libraries@A1mYMg7cbcj6p_VkDf-Tz.md
  53. 11
      src/data/roadmaps/angular/content/cross-site-request-forgery@Z1DZBbFI4oU6-KQg3wqMm.md
  54. 10
      src/data/roadmaps/angular/content/cross-site-script-inclusion@zd7YJGlcMFNFbsKUiW_XC.md
  55. 11
      src/data/roadmaps/angular/content/debugging-tests@f5v74Uw54LsB4FgdN6eCd.md
  56. 9
      src/data/roadmaps/angular/content/default@h4MMn0_qUN3YXEdMUJOyd.md
  57. 15
      src/data/roadmaps/angular/content/deployment@1fVi9AK6aLjt5QgAFbnGX.md
  58. 12
      src/data/roadmaps/angular/content/dynamic-components@tC5ETtOuuUcybj1jI4CuG.md
  59. 9
      src/data/roadmaps/angular/content/else-if@ys5untkSppGMFK-VsfuRt.md
  60. 12
      src/data/roadmaps/angular/content/end-to-end-testing@yhNGhduk__ow8VTLc6inZ.md
  61. 9
      src/data/roadmaps/angular/content/http-vulnerabilities@xH3RHPhsaqD9zIMms5OmX.md
  62. 12
      src/data/roadmaps/angular/content/httpclient-csrf@m2aw8vb4rz4IjshpoMyNx.md
  63. 11
      src/data/roadmaps/angular/content/hydration@NY_MfBNgNmloiRGcIvfJ1.md
  64. 11
      src/data/roadmaps/angular/content/local-setup@FVH0lnbIZ2m5EfF2EJ2DW.md
  65. 13
      src/data/roadmaps/angular/content/multiple-locales@9ISvaaJ815_cr_KW9vQhT.md
  66. 3
      src/data/roadmaps/angular/content/router-events@YF_sG292HqawIX0siWhrv.md
  67. 7
      src/data/roadmaps/angular/content/rxjs-basics@lfp7PIjwITU5gBITQdirD.md
  68. 8
      src/data/roadmaps/angular/content/services-with-dependencies@TGRZBizDy83JKg_MhnRdX.md
  69. 9
      src/data/roadmaps/angular/content/slow-computations@yxUtSBzJPRcS-IuPsyp-W.md
  70. 8
      src/data/roadmaps/angular/content/ssg@b-0yQ74zHtAxI9aRLBohc.md
  71. 9
      src/data/roadmaps/angular/content/switch@nZuim4Fjq6jYOXcRTAEay.md
  72. 1
      src/data/roadmaps/angular/content/template-ref-vars@Wc2ybRw43uamEtno0FpDv.md
  73. 10
      src/data/roadmaps/angular/content/template-syntax@VsC7UmE_AumsBP8fC6to1.md
  74. 10
      src/data/roadmaps/angular/content/testing-requests@4xt0m5jkUqB4Z-krcFBuL.md
  75. 9
      src/data/roadmaps/angular/content/testing-services@HU1eTYB321C93qh_U7ioF.md
  76. 11
      src/data/roadmaps/angular/content/zone-pollution@pRSR5PEbkJXAJ1LPyK-EE.md
  77. 3
      src/data/roadmaps/angular/content/zones@m4WBnx_9h01Jl6Q1sxi4Y.md
  78. 2
      src/data/roadmaps/aws/content/101-ec2/102-storage-volume.md
  79. 19
      src/data/roadmaps/backend/faqs.astro
  80. 9
      src/data/roadmaps/cyber-security/content/buffer-overflow@n8ZOZxNhlnw7DpzoXe_f_.md
  81. 8
      src/data/roadmaps/cyber-security/content/deauth-attack@LfWJJaT3fv0p6fUeS8b84.md
  82. 13
      src/data/roadmaps/cyber-security/content/directory-traversal@L0ROYh2DNlkybNDO2ezJY.md
  83. 8
      src/data/roadmaps/cyber-security/content/replay-attack@mIX8PsIGuwgPCGQZ6ok2H.md
  84. 8
      src/data/roadmaps/cyber-security/content/rogue-access-point@Ee7LfbhwJbiWjJ3b_bbni.md
  85. 16
      src/data/roadmaps/cyber-security/content/virustotal@rxzcAzHjzIc9lkWSw0fef.md
  86. 1
      src/data/roadmaps/datastructures-and-algorithms/content/100-language/104-cpp.md
  87. 2
      src/data/roadmaps/datastructures-and-algorithms/content/105-sorting-algorithms/104-selection-sort.md
  88. 7
      src/data/roadmaps/datastructures-and-algorithms/content/107-tree-data-structure/100-binary-trees.md
  89. 7
      src/data/roadmaps/datastructures-and-algorithms/content/107-tree-data-structure/101-binary-search-trees.md
  90. 6
      src/data/roadmaps/datastructures-and-algorithms/content/107-tree-data-structure/104-tree-traversal/index.md
  91. 1
      src/data/roadmaps/devops/content/docker@P0acFNZ413MSKElHqCxr3.md
  92. 1
      src/data/roadmaps/frontend/content/making-layouts@dXeYVMXv-3MRQ1ovOUuJW.md
  93. 1
      src/data/roadmaps/frontend/content/typescript@0asdhvwBH3gn-ercktV7A.md
  94. 6
      src/data/roadmaps/game-developer/content/decision-tree-learning@sz1047M8_kScjth84yPwU.md
  95. 6
      src/data/roadmaps/game-developer/content/microsurface-scattering@YrQgfjsdLCIUxrwflpEHO.md
  96. 10
      src/data/roadmaps/git-github/git-github.md
  97. 4
      src/data/roadmaps/golang/content/100-go-basics/100-basic-syntax.md
  98. 2
      src/data/roadmaps/graphql/content/100-graphql-introduction/101-problems-graphql-solves.md
  99. 5
      src/data/roadmaps/javascript/content/@lJwcc6JoUIQoiQ6FkV2KW.md
  100. 8
      src/data/roadmaps/javascript/content/apply@-BtF34cEzI6J8sZCDRlRE.md
  101. Some files were not shown because too many files have changed in this diff Show More

@ -3,6 +3,6 @@
"enabled": false
},
"_variables": {
"lastUpdateCheck": 1724902244772
"lastUpdateCheck": 1724925726721
}
}

1
.astro/types.d.ts vendored

@ -0,0 +1 @@
/// <reference types="astro/client" />

@ -0,0 +1,16 @@
name: Clears API Cloudfront Cache
on:
workflow_dispatch:
jobs:
aws_costs:
runs-on: ubuntu-latest
steps:
- name: Clear Cloudfront Caching
run: |
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GH_PAT }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/roadmapsh/infra-ansible/actions/workflows/playbook.yml/dispatches \
-d '{ "ref":"master", "inputs": { "playbook": "roadmap_web.yml", "tags": "cloudfront-api", "is_verbose": false } }'

@ -1,4 +1,4 @@
name: Clears Cloudfront Cache
name: Clears Frontend Cloudfront Cache
on:
workflow_dispatch:
jobs:

@ -1,6 +1,6 @@
# Contribution
First of all thank you for considering to contribute. Please look at the details below:
First of all, thank you for considering to contribute. Please look at the details below:
- [New Roadmaps](#new-roadmaps)
- [Existing Roadmaps](#existing-roadmaps)
@ -25,22 +25,22 @@ For the existing roadmaps, please follow the details listed for the nature of co
## Adding Projects
If you have a project idea that you think we should add to the roadmap, feel free to open an issue with as much details about the project as possible and the roadmap you think it should be added to.
If you have a project idea that you think we should add to the roadmap, feel free to open an issue with as many details about the project as possible and the roadmap you think it should be added to.
The detailed format for issue should be as follows:
The detailed format for the issue should be as follows:
```
## What is this project about?
(Add introduction to the project)
(Add an introduction to the project.)
## Skills this Project Covers
(Comma separated list of skills e.g. Programming Knowledge, Database,)
(Comma separated list of skills, e.g. Programming Knowledge, Database, etc.)
## Requirements
( Detailed list of requirements, i.e. input, output, an hints to help build this etc)
( Detailed list of requirements, i.e. input, output, hints to help build this, etc.)
```
Have a look at this project to get an idea of [what we are looking for](https://roadmap.sh/projects/github-user-activity).
@ -67,7 +67,7 @@ Visit the following resources to learn more:
- [@type@Description of link](Link)
```
`@type@` must be one of the following and describes the type of content you are adding:
`@type@` must be one of the following and describe the type of content you are adding:
- `@official@`
- `@opensource@`
@ -82,11 +82,11 @@ It's important to add a valid type, this will help us categorize the content and
- <p><strong>Please don't use the project for self-promotion!</strong><br />
We believe this project is a valuable asset to the developer community and it includes numerous helpful resources. We kindly ask you to avoid submitting pull requests for the sole purpose of self-promotion. We appreciate contributions that genuinely add value, such as guides from maintainers of well-known frameworks, and will consider accepting these even if they're self authored. Thank you for your understanding and cooperation!
We believe this project is a valuable asset to the developer community, and it includes numerous helpful resources. We kindly ask you to avoid submitting pull requests for the sole purpose of self-promotion. We appreciate contributions that genuinely add value, such as guides from maintainers of well-known frameworks, and will consider accepting these even if they're self authored. Thank you for your understanding and cooperation!
- <p><strong>Adding everything available out there is not the goal!</strong><br />
The roadmaps represent the skillset most valuable today, i.e., if you were to enter any of the listed fields today, what would you learn? There might be things that are of-course being used today but prioritize the things that are most in demand today, e.g., agreed that lots of people are using angular.js today but you wouldn't want to learn that instead of React, Angular, or Vue. Use your critical thinking to filter out non-essential stuff. Give honest arguments for why the resource should be included.</p>
The roadmaps represent the skillset most valuable today, i.e., if you were to enter any of the listed fields today, what would you learn? There might be things that are of-course being used today, but prioritize the things that are most in demand today, e.g., agree that lots of people are using angular.js today, but you wouldn't want to learn that instead of React, Angular, or Vue. Use your critical thinking to filter out non-essential stuff. Give honest arguments for why the resource should be included.</p>
- <p><strong>Do not add things you have not evaluated personally!</strong><br />
@ -98,12 +98,12 @@ It's important to add a valid type, this will help us categorize the content and
- <p><strong>Write meaningful commit messages</strong><br >
Meaningful commit messages help speed up the review process as well as help other contributors in gaining a good overview of the repositories commit history without having to dive into every commit.
Meaningful commit messages help speed up the review process as well as help other contributors gain a good overview of the repositories commit history without having to dive into every commit.
</p>
- <p><strong>Look at the existing issues/pull requests before opening new ones</strong></p>
### Good vs Not So Good Contributions
### Good vs. Not So Good Contributions
<strong>Good</strong>
@ -117,5 +117,5 @@ It's important to add a valid type, this will help us categorize the content and
- Adding whitespace that doesn't add to the readability of the content.
- Rewriting content in a way that doesn't add any value.
- Non-English content.
- PR's that don't follow our style guide, have no description and a default title.
- PR's that don't follow our style guide, have no description, and a default title.
- Links to your own blog articles.

377
package-lock.json generated

@ -8,8 +8,8 @@
"name": "roadmap.sh",
"version": "1.0.0",
"dependencies": {
"@astrojs/node": "^8.3.2",
"@astrojs/react": "^3.6.1",
"@astrojs/node": "^8.3.3",
"@astrojs/react": "^3.6.2",
"@astrojs/sitemap": "^3.1.6",
"@astrojs/tailwind": "^5.1.0",
"@fingerprintjs/fingerprintjs": "^4.4.3",
@ -18,7 +18,7 @@
"@resvg/resvg-js": "^2.6.2",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"astro": "^4.13.0",
"astro": "^4.14.6",
"clsx": "^2.1.1",
"dayjs": "^1.11.12",
"dom-to-image": "^2.6.0",
@ -132,9 +132,9 @@
}
},
"node_modules/@astrojs/node": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/@astrojs/node/-/node-8.3.2.tgz",
"integrity": "sha512-Upv0D+9b3RXp7XViQTtrijaDqihHWbVHLdJQ2sxtPOEtw2GDrVxuC6LmXIUew5YvJ9Ylmpst6KizVwO8d/K9/Q==",
"version": "8.3.3",
"resolved": "https://registry.npmjs.org/@astrojs/node/-/node-8.3.3.tgz",
"integrity": "sha512-idrKhnnPSi0ABV+PCQsRQqVNwpOvVDF/+fkwcIiE8sr9J8EMvW9g/oyAt8T4X2OBJ8FUzYPL8klfCdG7r0eB5g==",
"dependencies": {
"send": "^0.18.0",
"server-destroy": "^1.0.1"
@ -263,11 +263,11 @@
}
},
"node_modules/@babel/generator": {
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz",
"integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==",
"version": "7.25.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.5.tgz",
"integrity": "sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==",
"dependencies": {
"@babel/types": "^7.25.0",
"@babel/types": "^7.25.4",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
@ -402,11 +402,11 @@
}
},
"node_modules/@babel/parser": {
"version": "7.25.3",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz",
"integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==",
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.4.tgz",
"integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==",
"dependencies": {
"@babel/types": "^7.25.2"
"@babel/types": "^7.25.4"
},
"bin": {
"parser": "bin/babel-parser.js"
@ -489,15 +489,15 @@
}
},
"node_modules/@babel/traverse": {
"version": "7.25.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz",
"integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==",
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.4.tgz",
"integrity": "sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==",
"dependencies": {
"@babel/code-frame": "^7.24.7",
"@babel/generator": "^7.25.0",
"@babel/parser": "^7.25.3",
"@babel/generator": "^7.25.4",
"@babel/parser": "^7.25.4",
"@babel/template": "^7.25.0",
"@babel/types": "^7.25.2",
"@babel/types": "^7.25.4",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@ -506,9 +506,9 @@
}
},
"node_modules/@babel/types": {
"version": "7.25.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz",
"integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==",
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.4.tgz",
"integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==",
"dependencies": {
"@babel/helper-string-parser": "^7.24.8",
"@babel/helper-validator-identifier": "^7.24.7",
@ -2047,10 +2047,36 @@
"node": ">= 10"
}
},
"node_modules/@rollup/pluginutils": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
"integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/pluginutils/node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz",
"integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.1.tgz",
"integrity": "sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==",
"cpu": [
"arm"
],
@ -2060,9 +2086,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz",
"integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.1.tgz",
"integrity": "sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==",
"cpu": [
"arm64"
],
@ -2072,9 +2098,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz",
"integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.1.tgz",
"integrity": "sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==",
"cpu": [
"arm64"
],
@ -2084,9 +2110,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz",
"integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.1.tgz",
"integrity": "sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==",
"cpu": [
"x64"
],
@ -2096,9 +2122,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz",
"integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.1.tgz",
"integrity": "sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==",
"cpu": [
"arm"
],
@ -2108,9 +2134,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz",
"integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.1.tgz",
"integrity": "sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==",
"cpu": [
"arm"
],
@ -2120,9 +2146,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz",
"integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz",
"integrity": "sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==",
"cpu": [
"arm64"
],
@ -2132,9 +2158,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz",
"integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.1.tgz",
"integrity": "sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==",
"cpu": [
"arm64"
],
@ -2144,9 +2170,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz",
"integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.1.tgz",
"integrity": "sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==",
"cpu": [
"ppc64"
],
@ -2156,9 +2182,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz",
"integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.1.tgz",
"integrity": "sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==",
"cpu": [
"riscv64"
],
@ -2168,9 +2194,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz",
"integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.1.tgz",
"integrity": "sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==",
"cpu": [
"s390x"
],
@ -2180,9 +2206,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz",
"integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.1.tgz",
"integrity": "sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==",
"cpu": [
"x64"
],
@ -2192,9 +2218,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz",
"integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.1.tgz",
"integrity": "sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==",
"cpu": [
"x64"
],
@ -2204,9 +2230,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz",
"integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.1.tgz",
"integrity": "sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==",
"cpu": [
"arm64"
],
@ -2216,9 +2242,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz",
"integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.1.tgz",
"integrity": "sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==",
"cpu": [
"ia32"
],
@ -2228,9 +2254,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz",
"integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz",
"integrity": "sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==",
"cpu": [
"x64"
],
@ -2240,9 +2266,9 @@
]
},
"node_modules/@shikijs/core": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.13.0.tgz",
"integrity": "sha512-Mj5NVfbAXcD1GnwOTSPl8hBn/T8UDpfFQTptp+p41n/CbUcJtOq98WaRD7Lz3hCglYotUTHUWtzu3JhK6XlkAA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.14.1.tgz",
"integrity": "sha512-KyHIIpKNaT20FtFPFjCQB5WVSTpLR/n+jQXhWHWVUMm9MaOaG9BGOG0MSyt7yA4+Lm+4c9rTc03tt3nYzeYSfw==",
"dependencies": {
"@types/hast": "^3.0.4"
}
@ -2874,21 +2900,22 @@
}
},
"node_modules/astro": {
"version": "4.13.4",
"resolved": "https://registry.npmjs.org/astro/-/astro-4.13.4.tgz",
"integrity": "sha512-uoW961qyU5xxCiUzITVX8wYmdWbSH1zeog9UomoWC5uNpnIbH6WxOPv/qYu2m7W4r2PCxdRqfVXoYjZhFyGfTA==",
"version": "4.14.6",
"resolved": "https://registry.npmjs.org/astro/-/astro-4.14.6.tgz",
"integrity": "sha512-MIDyNhtu3L4uakHvlTprh21eQPehYOtZSuSLtd+r6xZcl3lB+mlBz/hs1W3iHEQAORyJnKArWSY/aVOBKUyflA==",
"dependencies": {
"@astrojs/compiler": "^2.10.2",
"@astrojs/compiler": "^2.10.3",
"@astrojs/internal-helpers": "0.4.1",
"@astrojs/markdown-remark": "5.2.0",
"@astrojs/telemetry": "3.1.0",
"@babel/core": "^7.25.2",
"@babel/generator": "^7.25.0",
"@babel/parser": "^7.25.3",
"@babel/generator": "^7.25.5",
"@babel/parser": "^7.25.4",
"@babel/plugin-transform-react-jsx": "^7.25.2",
"@babel/traverse": "^7.25.3",
"@babel/types": "^7.25.2",
"@babel/traverse": "^7.25.4",
"@babel/types": "^7.25.4",
"@oslojs/encoding": "^0.4.1",
"@rollup/pluginutils": "^5.1.0",
"@types/babel__core": "^7.20.5",
"@types/cookie": "^0.6.0",
"acorn": "^8.12.1",
@ -2919,8 +2946,10 @@
"js-yaml": "^4.1.0",
"kleur": "^4.1.5",
"magic-string": "^0.30.11",
"micromatch": "^4.0.8",
"mrmime": "^2.0.0",
"ora": "^8.0.1",
"neotraverse": "^0.6.18",
"ora": "^8.1.0",
"p-limit": "^6.1.0",
"p-queue": "^8.0.1",
"path-to-regexp": "^6.2.2",
@ -2928,18 +2957,20 @@
"prompts": "^2.4.2",
"rehype": "^13.0.1",
"semver": "^7.6.3",
"shiki": "^1.12.1",
"shiki": "^1.14.1",
"string-width": "^7.2.0",
"strip-ansi": "^7.1.0",
"tsconfck": "^3.1.1",
"unist-util-visit": "^5.0.0",
"vfile": "^6.0.2",
"vite": "^5.4.0",
"vfile": "^6.0.3",
"vite": "^5.4.2",
"vitefu": "^0.2.5",
"which-pm": "^3.0.0",
"xxhash-wasm": "^1.0.2",
"yargs-parser": "^21.1.1",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.23.2"
"zod-to-json-schema": "^3.23.2",
"zod-to-ts": "^1.2.0"
},
"bin": {
"astro": "astro.js"
@ -3322,14 +3353,14 @@
}
},
"node_modules/cli-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
"integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
"integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
"dependencies": {
"restore-cursor": "^4.0.0"
"restore-cursor": "^5.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@ -6044,9 +6075,9 @@
]
},
"node_modules/micromatch": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
"integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dependencies": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
@ -6098,6 +6129,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/mimic-function": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@ -6181,6 +6223,14 @@
"node": "^18.0.0 || >=20.0.0"
}
},
"node_modules/neotraverse": {
"version": "0.6.18",
"resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz",
"integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==",
"engines": {
"node": ">= 10"
}
},
"node_modules/nlcst-to-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz",
@ -6388,18 +6438,18 @@
}
},
"node_modules/ora": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/ora/-/ora-8.0.1.tgz",
"integrity": "sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-8.1.0.tgz",
"integrity": "sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==",
"dependencies": {
"chalk": "^5.3.0",
"cli-cursor": "^4.0.0",
"cli-cursor": "^5.0.0",
"cli-spinners": "^2.9.2",
"is-interactive": "^2.0.0",
"is-unicode-supported": "^2.0.0",
"log-symbols": "^6.0.0",
"stdin-discarder": "^0.2.1",
"string-width": "^7.0.0",
"stdin-discarder": "^0.2.2",
"string-width": "^7.2.0",
"strip-ansi": "^7.1.0"
},
"engines": {
@ -7382,47 +7432,34 @@
}
},
"node_modules/restore-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
"integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
"integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
"onetime": "^7.0.0",
"signal-exit": "^4.1.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/restore-cursor/node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"engines": {
"node": ">=6"
}
},
"node_modules/restore-cursor/node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
"integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
"dependencies": {
"mimic-fn": "^2.1.0"
"mimic-function": "^5.0.0"
},
"engines": {
"node": ">=6"
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/restore-cursor/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
"node_modules/retext": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz",
@ -7495,9 +7532,9 @@
"integrity": "sha512-IQejjIfr9RIvesNwp3SyhEq1DMQ2RdJfJhgsb1AyPuKXsfJgOG8F++Cz1p3SIcY0bnB57Q16Ke2VJLjiUVwI3Q=="
},
"node_modules/rollup": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz",
"integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.1.tgz",
"integrity": "sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==",
"dependencies": {
"@types/estree": "1.0.5"
},
@ -7509,22 +7546,22 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.18.1",
"@rollup/rollup-android-arm64": "4.18.1",
"@rollup/rollup-darwin-arm64": "4.18.1",
"@rollup/rollup-darwin-x64": "4.18.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.18.1",
"@rollup/rollup-linux-arm-musleabihf": "4.18.1",
"@rollup/rollup-linux-arm64-gnu": "4.18.1",
"@rollup/rollup-linux-arm64-musl": "4.18.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.18.1",
"@rollup/rollup-linux-riscv64-gnu": "4.18.1",
"@rollup/rollup-linux-s390x-gnu": "4.18.1",
"@rollup/rollup-linux-x64-gnu": "4.18.1",
"@rollup/rollup-linux-x64-musl": "4.18.1",
"@rollup/rollup-win32-arm64-msvc": "4.18.1",
"@rollup/rollup-win32-ia32-msvc": "4.18.1",
"@rollup/rollup-win32-x64-msvc": "4.18.1",
"@rollup/rollup-android-arm-eabi": "4.21.1",
"@rollup/rollup-android-arm64": "4.21.1",
"@rollup/rollup-darwin-arm64": "4.21.1",
"@rollup/rollup-darwin-x64": "4.21.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.21.1",
"@rollup/rollup-linux-arm-musleabihf": "4.21.1",
"@rollup/rollup-linux-arm64-gnu": "4.21.1",
"@rollup/rollup-linux-arm64-musl": "4.21.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.1",
"@rollup/rollup-linux-riscv64-gnu": "4.21.1",
"@rollup/rollup-linux-s390x-gnu": "4.21.1",
"@rollup/rollup-linux-x64-gnu": "4.21.1",
"@rollup/rollup-linux-x64-musl": "4.21.1",
"@rollup/rollup-win32-arm64-msvc": "4.21.1",
"@rollup/rollup-win32-ia32-msvc": "4.21.1",
"@rollup/rollup-win32-x64-msvc": "4.21.1",
"fsevents": "~2.3.2"
}
},
@ -7755,11 +7792,11 @@
}
},
"node_modules/shiki": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-1.13.0.tgz",
"integrity": "sha512-e0dWfnONbEv6xl7FJy3XIhsVHQ/65XHDZl92+6H9+4xWjfdo7pmkqG7Kg47KWtDiEtzM5Z+oEfb4vtRvoZ/X9w==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-1.14.1.tgz",
"integrity": "sha512-FujAN40NEejeXdzPt+3sZ3F2dx1U24BY2XTY01+MG8mbxCiA2XukXdcbyMyLAHJ/1AUUnQd1tZlvIjefWWEJeA==",
"dependencies": {
"@shikijs/core": "1.13.0",
"@shikijs/core": "1.14.1",
"@types/hast": "^3.0.4"
}
},
@ -8755,6 +8792,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typescript": {
"version": "5.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
@ -8964,12 +9014,11 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/vfile": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.2.tgz",
"integrity": "sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==",
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
"integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
"dependencies": {
"@types/unist": "^3.0.0",
"unist-util-stringify-position": "^4.0.0",
"vfile-message": "^4.0.0"
},
"funding": {
@ -9004,13 +9053,13 @@
}
},
"node_modules/vite": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz",
"integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==",
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
"integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
"dependencies": {
"esbuild": "^0.21.3",
"postcss": "^8.4.40",
"rollup": "^4.13.0"
"postcss": "^8.4.41",
"rollup": "^4.20.0"
},
"bin": {
"vite": "bin/vite.js"
@ -9305,6 +9354,11 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
"node_modules/xxhash-wasm": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.0.2.tgz",
"integrity": "sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A=="
},
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@ -9361,6 +9415,15 @@
"zod": "^3.23.3"
}
},
"node_modules/zod-to-ts": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz",
"integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==",
"peerDependencies": {
"typescript": "^4.9.4 || ^5.0.2",
"zod": "^3"
}
},
"node_modules/zustand": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz",

@ -29,8 +29,8 @@
"test:e2e": "playwright test"
},
"dependencies": {
"@astrojs/node": "^8.3.2",
"@astrojs/react": "^3.6.1",
"@astrojs/node": "^8.3.3",
"@astrojs/react": "^3.6.2",
"@astrojs/sitemap": "^3.1.6",
"@astrojs/tailwind": "^5.1.0",
"@fingerprintjs/fingerprintjs": "^4.4.3",
@ -39,7 +39,7 @@
"@resvg/resvg-js": "^2.6.2",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"astro": "^4.13.0",
"astro": "^4.14.6",
"clsx": "^2.1.1",
"dayjs": "^1.11.12",
"dom-to-image": "^2.6.0",

File diff suppressed because it is too large Load Diff

@ -199,8 +199,19 @@
},
"3fFNMhQIuuh-NRzSXYpXO": {
"title": "Constraint",
"description": "",
"links": []
"description": "Lets you create large, complex layouts with a flat view hierarchy—no nested view groups. It's similar to `RelativeLayout` in that all views are laid out according to relationships between sibling views and the parent layout, but it's more flexible than RelativeLayout and easier to use. Its available on xml and jetpack compose.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Android developers: ConstraintLayout in xml",
"url": "https://developer.android.com/develop/ui/views/layout/constraint-layout",
"type": "article"
},
{
"title": "Android developers: ContraintLayout in compose",
"url": "https://developer.android.com/develop/ui/compose/layouts/constraintlayout",
"type": "article"
}
]
},
"xIvplWfe-uDr9iHjPT1Mx": {
"title": "RecycleView",
@ -303,13 +314,30 @@
},
"EzLjX4iRT7AxkAOsJYnSU": {
"title": "ListView",
"description": "",
"links": []
"description": "Displays a vertically-scrollable collection of views, where each view is positioned immediatelybelow the previous view in the list.\n\nFor a more modern, flexible, and performant approach to displaying lists, use `RecyclerView`.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Android developers: ListView",
"url": "https://developer.android.com/reference/android/widget/ListView",
"type": "article"
}
]
},
"amTxz7mS98lkhOrNMJXG_": {
"title": "Drawer",
"description": "",
"links": []
"description": "The **Navigation Drawer** in Android is a sliding menu from the left that simplifies navigation between important app links. It opens by sliding or via an icon in the `ActionBar`. It’s an overlay panel that replaces a screen dedicated to displaying options.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Android developers: DrawerLayout",
"url": "https://developer.android.com/reference/androidx/drawerlayout/widget/DrawerLayout",
"type": "article"
},
{
"title": "Navigate Drawer Tutorial",
"url": "https://www.digitalocean.com/community/tutorials/android-navigation-drawer-example-tutorial",
"type": "article"
}
]
},
"pEBpXv3Jf1AzBNHlvVrG8": {
"title": "Tabs",
@ -324,8 +352,19 @@
},
"Xn1VQ-xOT67ZfJJTM4r1p": {
"title": "Animations",
"description": "",
"links": []
"description": "`Animations` can add visual cues that notify users about what's going on in your app. They are especially useful when the UI changes state, such as when new content loads or new actions become available. Animations also add a polished look to your app, which gives it a higher quality look and feel.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Google developers: Animations",
"url": "https://developer.android.com/develop/ui/views/animations/overview",
"type": "article"
},
{
"title": "Google developers: Animations",
"url": "https://www.youtube.com/watch?v=N_x7SV3I3P0",
"type": "video"
}
]
},
"60Vm-77rseUqpMiFvp-dA": {
"title": "Jetpack Compose",

@ -677,8 +677,19 @@
},
"ys5untkSppGMFK-VsfuRt": {
"title": "@else if",
"description": "",
"links": []
"description": "With the new control flow syntax, you gain `@else if` conditional blocks, something that is not possible with `@ngIf`. This addition makes the control flow syntax close to what we would write with just plain JavaScript.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Angular Official Docs - @if",
"url": "https://angular.dev/api/core/@if",
"type": "article"
},
{
"title": "Angular @if: Complete Guide",
"url": "https://blog.angular-university.io/angular-if/",
"type": "article"
}
]
},
"2kYS9w1UzQFZ1zhf01m9L": {
"title": "@for",
@ -693,18 +704,51 @@
},
"nZuim4Fjq6jYOXcRTAEay": {
"title": "@switch",
"description": "",
"links": []
"description": "The `@switch` blocks displays content selected by one of the cases matching against the conditional expression. The value of the conditional expression is compared to the case expression using the `===` operator. `@switch` does not have fallthrough, so you do not need an equivalent to a break or return statement.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Angular Official Docs - @switch",
"url": "https://angular.dev/guide/templates/control-flow#switch-block---selection",
"type": "article"
},
{
"title": "Angular @switch: Complete Guide",
"url": "https://blog.angular-university.io/angular-switch/",
"type": "article"
}
]
},
"cHC2MH50CbUSMRZV4QGJI": {
"title": "@case",
"description": "",
"links": []
"description": "If no `@case` matches the `@switch` condition and there is no `@default` block, nothing is shown. Otherwise, the content inside the `@case` that matches the condition will be displayed.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Angular Official Docs - @switch",
"url": "https://angular.dev/guide/templates/control-flow#switch-block---selection",
"type": "article"
},
{
"title": "Angular @switch: Complete Guide",
"url": "https://blog.angular-university.io/angular-switch/",
"type": "article"
}
]
},
"h4MMn0_qUN3YXEdMUJOyd": {
"title": "@default",
"description": "",
"links": []
"description": "The `@default` clause is used to render a template when none of the `@case` blocks matches the value of the `@switch` conditional. `@default` is optional and can be omitted.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Angular Official Docs - @switch",
"url": "https://angular.dev/guide/templates/control-flow#switch-block---selection",
"type": "article"
},
{
"title": "Angular @switch: Complete Guide",
"url": "https://blog.angular-university.io/angular-switch/",
"type": "article"
}
]
},
"AwOM0ucg6W7TohdUd7KWT": {
"title": "@let",
@ -1738,8 +1782,19 @@
},
"Ax-s_xw3FO3Ocv-AnLbQD": {
"title": "Build Environments",
"description": "",
"links": []
"description": "You can define different named build configurations for your project, such as `development` and `production`, with different defaults. Each named configuration can have defaults for any of the options that apply to the various builder targets, such as `build`, `serve`, and `test`. The Angular CLI can replace files for each environment if you pass a `--configuration` flag with the named configuration when running a CLI command.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Angular Official Docs - Build environments",
"url": "https://angular.dev/tools/cli/environments#using-environment-specific-variables-in-your-app",
"type": "article"
},
{
"title": "Building an Angular application in various environments using Angular CLI and server",
"url": "https://medium.com/yavar/building-an-angular-application-in-various-environments-using-angular-cli-and-server-18f94067154b",
"type": "article"
}
]
},
"TeWEy9I-hU6SH02Sy2S2S": {
"title": "CLI Builders",

@ -224,7 +224,7 @@
"type": "article"
},
{
"title": "Official JavaScript Documentation",
"title": "JavaScript Beginner Resources",
"url": "https://www.javascript.com/",
"type": "article"
},
@ -3047,4 +3047,4 @@
}
]
}
}
}

@ -1503,7 +1503,7 @@
},
"c2kY3wZVFKZYxMARhLIwO": {
"title": "SIEM",
"description": "SIEM, short for Security Information and Event Manager, is a term used to describe tools that greatly increases visibility into a network or system. It does this by monitoring, filtering, collecting, normalizing, and correlating vast amounts of data such as logs, and neatly presents it via an interface/dashboard.\n\nOrganizations leverage SIEMs to monitor and thus identify, protect, and respond to potential threats in their environment.\n\nFor hands-on experience, you should consider setting up a SIEM in your own environment. A common stack widely used for various purposes across the industry is the ELK-stack.\n\nVisit the following resources to learn more:",
"description": "SIEM, short for Security Information and Event Manager, is a term used to describe tools that greatly increases visibility into a network or system. It does this by monitoring, filtering, collecting, normalizing, and correlating vast amounts of data such as logs, and neatly presents it via an interface/dashboard.\n\nOrganizations leverage SIEMs to monitor and thus identify, protect, and respond to potential threats in their environment.\n\nFor hands-on experience, you should consider setting up a SIEM in your own environment. There are some commercial tools that you can try out for free, and there are also open source alternatives, such as Wazuh or LevelBlue OSSIM (AlienVault).\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Security 101: What is a SIEM? - Microsoft",
@ -1511,12 +1511,22 @@
"type": "article"
},
{
"title": "Using the ELK stack for SIEM",
"url": "https://logz.io/blog/elk-siem/",
"type": "article"
"title": "SIEM Explained - Professor Messer",
"url": "https://www.youtube.com/watch?v=JEcETdy5WxU",
"type": "video"
},
{
"title": "Wazuh | Open source SIEM",
"url": "https://www.youtube.com/watch?v=3CaG2GI1kn0",
"type": "video"
},
{
"title": "Build a powerful home SIEM",
"title": "Splunk | The Complete Beginner Tutorial",
"url": "https://www.youtube.com/playlist?list=PLY2f3p7xyMiTUbUo0A_lBFEwj6KdH0nFy",
"type": "video"
},
{
"title": "Elastic Security | Build a powerful home SIEM",
"url": "https://www.youtube.com/watch?v=2XLzMb9oZBI",
"type": "video"
}
@ -1699,7 +1709,7 @@
},
"9rmDvycXFcsGOq3v-_ziD": {
"title": "S/MIME",
"description": "",
"description": "**S/MIME** stands for Secure/Multipurpose Internet Mail Extensions, and it is a cryptographic protocol that enhances the security of business emails through encryption and digital signatures. It allows users to encrypt emails and digitally sign them to verify the sender’s identity.\n\nAdvantages of S/MIME\n--------------------\n\n* **Verification**: Confirms the sender’s identity.\n \n* **Confidentiality**: Protects the content from unauthorized access.\n \n* **Integrity**: Ensures the message has not been altered.\n \n* **Secure Data Transfer**: Safely transmits files like images, audio, videos, and documents.\n \n* **Non-repudiation**: Prevents the sender from denying the origin of the message.\n \n\nHow S/MIME Works\n----------------\n\nS/MIME enables the transmission of non-ASCII data via the Secure Mail Transfer Protocol (SMTP). It securely sends various data files, including music, video, and images, using encryption. Data encrypted with a public key can only be decrypted by the recipient’s private key, ensuring secure end-to-end communication.",
"links": []
},
"3140n5prZYySsuBHjqGOJ": {
@ -1831,7 +1841,7 @@
},
"rxzcAzHjzIc9lkWSw0fef": {
"title": "VirusTotal",
"description": "",
"description": "VirusTotal's main feature is multi-scanning using over 70 antivirus scanners to generate a cumulative report on whether a file is malicious. It also stores file hashes, eliminating the need to rescan previously uploaded files. Researchers can comment in the community, sharing their analysis and insights into malware for others to benefit from.\n\nVirusTotal's aggregated data comes from various antivirus engines, website scanners, file and URL analysis tools, and user contributions. These tools serve diverse purposes, including heuristic engines, known-bad signatures, metadata extraction, and identification of malicious signals.\n\nAdditionally, VirusTotal offers services to search by file hash, IP address, and URL, which are also scanned. For more comprehensive features, VirusTotal provides Premium services such as Intelligence & Hunting.\n\nVisit the following resources to learn more:",
"links": []
},
"h__KxKa0Q74_egY7GOe-L": {
@ -2096,8 +2106,19 @@
},
"LfWJJaT3fv0p6fUeS8b84": {
"title": "Deauth Attack",
"description": "",
"links": []
"description": "A Deauthentication (Deauth) Attack is a type of denial-of-service (DoS) attack specific to wireless networks. It involves sending fake deauthentication frames to a Wi-Fi client or access point, forcing the client to disconnect from the network. The attacker uses this technique to disrupt the communication between the client and the access point, often with the intention of capturing data, launching further attacks, or simply causing disruption.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Wi-Fi Deauthentication Attack",
"url": "https://medium.com/@balaramapunna123/wi-fi-deauthentication-attack-76cdd91d5fc",
"type": "article"
},
{
"title": "Deauthentication Attacks",
"url": "https://www.baeldung.com/cs/deauthentication-attacks",
"type": "article"
}
]
},
"u4hySof6if5hiONSaW-Uf": {
"title": "VLAN Hopping",
@ -2106,12 +2127,18 @@
},
"Ee7LfbhwJbiWjJ3b_bbni": {
"title": "Rogue Access Point",
"description": "",
"links": []
"description": "A Rogue Access Point (Rogue AP) is an unauthorized wireless access point installed on a secure network without the network administrator's knowledge or consent. These devices can be set up by malicious actors to intercept, steal, or manipulate network traffic, or by employees who unintentionally compromise network security by setting up their own wireless access points.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Rogue access points",
"url": "https://www.khanacademy.org/computing/computers-and-internet/xcae6f4a7ff015e7d:online-data-security/xcae6f4a7ff015e7d:cyber-attacks/a/rogue-access-points-mitm-attacks",
"type": "article"
}
]
},
"n8ZOZxNhlnw7DpzoXe_f_": {
"title": "Buffer Overflow",
"description": "",
"description": "A Buffer Overflow is a type of vulnerability that occurs when a program or process attempts to write more data to a buffer—a temporary storage area in memory—than it can hold. This overflow can cause the extra data to overwrite adjacent memory locations, potentially leading to unintended behavior, crashes, or security breaches.\n\nVisit the following resources to learn more:",
"links": []
},
"nOND14t7ISgSH3zNpV3F8": {
@ -2158,8 +2185,14 @@
},
"mIX8PsIGuwgPCGQZ6ok2H": {
"title": "Replay Attack",
"description": "",
"links": []
"description": "A Replay Attack is a type of network attack where an attacker intercepts and retransmits legitimate communication data, often with the aim of gaining unauthorized access to a system or performing unauthorized actions. In this attack, the attacker captures a valid data transmission and then \"replays\" it later, without needing to decrypt or alter the data, to trick the recipient into thinking it's a legitimate request.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "What Is a Replay Attack?",
"url": "https://usa.kaspersky.com/resource-center/definitions/replay-attack",
"type": "article"
}
]
},
"sMuKqf27y4iG0GrCdF5DN": {
"title": "Pass the Hash",
@ -2168,13 +2201,55 @@
},
"L0ROYh2DNlkybNDO2ezJY": {
"title": "Directory Traversal",
"description": "",
"links": []
"description": "Directory Traversal, also known as Path Traversal, is a vulnerability that allows attackers to read files on a system without proper authorization. These attacks typically exploit unsecured paths using \"../\" (dot-dot-slash) sequences and their variations, or absolute file paths. The attack is also referred to as \"dot-dot-slash,\" \"directory climbing,\" or \"backtracking.\"\n\nWhile Directory Traversal is sometimes combined with other vulnerabilities like Local File Inclusion (LFI) or Remote File Inclusion (RFI), the key difference is that Directory Traversal doesn't execute code, whereas LFI and RFI usually do.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "TryHackMe's room on Path Traversal & File Inclusion",
"url": "https://tryhackme.com/r/room/filepathtraversal",
"type": "course"
},
{
"title": "HackTheBox Academy's module on File Inclusion & Path Traversal",
"url": "https://academy.hackthebox.com/course/preview/file-inclusion",
"type": "course"
},
{
"title": "Portswigger's guide on File Path Traversal",
"url": "https://portswigger.net/web-security/file-path-traversal",
"type": "article"
},
{
"title": "OWASP's article on Path Traversal",
"url": "https://owasp.org/www-community/attacks/Path_Traversal",
"type": "article"
},
{
"title": "Acunetix's article on directory traversal",
"url": "https://www.acunetix.com/websitesecurity/directory-traversal/",
"type": "article"
}
]
},
"lv6fI3WeJawuCbwKtMRIh": {
"title": "Stakeholders",
"description": "",
"links": []
"description": "Stakeholders are individuals or organizations with a right, share, claim, or interest in a system or its characteristics that meet their needs and expectations.\n\n### External Stakeholders:\n\n* Government agencies\n* Policy regulators\n* Partners\n* Suppliers\n\n### Internal Stakeholders:\n\n* Subject matter experts\n* Legal\n* Compliance\n* Senior management\n\nStakeholders vary based on the organization, making their identification essential. They must be notified according to the organization's playbook for escalating problems and providing updates. Not all stakeholders are equal, some may require a less technical report highlighting the main points, while others will need a full technical report.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "TryHackMe room on Cyber Governance and regulation",
"url": "https://tryhackme.com/r/room/cybergovernanceregulation",
"type": "course"
},
{
"title": "NIST Publication on Engineering Trustworthy Secure Systems",
"url": "https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-160v1r1.pdf",
"type": "article"
},
{
"title": "NIST Glossary",
"url": "https://csrc.nist.gov/glossary/term/stakeholder",
"type": "article"
}
]
},
"05tH6WhToC615JTFN-TPc": {
"title": "HR",

@ -1037,6 +1037,11 @@
"title": "Docker",
"description": "Docker is a platform for working with containerized applications. Among its features are a daemon and client for managing and interacting with containers, registries for storing images, and a desktop application to package all these features together.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Visit Dedicated Docker Roadmap",
"url": "https://roadmap.sh/docker",
"type": "article"
},
{
"title": "Docker Documentation",
"url": "https://docs.docker.com/",

@ -593,11 +593,6 @@
"title": "Making Layouts",
"description": "Float, grid, flexbox, positioning, display and box model are some of the key topics that are used for making layouts. Use the resources below to learn about these topics:\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Learn CSS Grid for free",
"url": "https://scrimba.com/learn/cssgrid?via=roadmap",
"type": "course"
},
{
"title": "Learn and Practice Flexbox",
"url": "https://flexboxfroggy.com/",
@ -2086,11 +2081,6 @@
"title": "TypeScript",
"description": "TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Scrimba — TypeScript Basics",
"url": "https://scrimba.com/learn/typescript?via=roadmap",
"type": "course"
},
{
"title": "Official Website",
"url": "https://www.typescriptlang.org/",

@ -772,13 +772,25 @@
},
"sz1047M8_kScjth84yPwU": {
"title": "Decision Tree Learning",
"description": "`Decision Tree Learning` is an important concept in game development, particularly in the development of artificial intelligence for game characters. It is a kind of machine learning method that is based on using decision tree models to predict or classify information. A decision tree is a flowchart-like model, where each internal node denotes a test on an attribute, each branch represents an outcome of that test, and each leaf node holds a class label (decision made after testing all attributes). By applying decision tree learning models, computer-controlled characters can make decisions based on different conditions or states. They play a key role in creating complex and interactive gameplay experiences, by enabling game characters to adapt to the player's actions and the ever-changing game environment.",
"links": []
"description": "`Decision Tree Learning` is an important concept in game development, particularly in the development of artificial intelligence for game characters. It is a kind of machine learning method that is based on using decision tree models to predict or classify information. A decision tree is a flowchart-like model, where each internal node denotes a test on an attribute, each branch represents an outcome of that test, and each leaf node holds a class label (decision made after testing all attributes). By applying decision tree learning models, computer-controlled characters can make decisions based on different conditions or states. They play a key role in creating complex and interactive gameplay experiences, by enabling game characters to adapt to the player's actions and the ever-changing game environment.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Decision trees - A friendly introduction",
"url": "https://www.youtube.com/watch?v=HkyWAhr9v8g",
"type": "video"
}
]
},
"ltkEyfuDxExs7knqs79ya": {
"title": "Deep Learning",
"description": "Deep Learning is a sub-field of machine learning, inspired by the structure and function of the human brain, specifically designed to process complex input/output transformations. It uses artificial neural networks with many layers (hence the term 'deep' learning) to model complex, non-linear hypotheses and discover hidden patterns within large datasets. Deep learning techniques are crucial in game development, primarily in creating intelligent behaviors and features in gaming agents, procedural content generation, and player profiling. You might have heard about the uses of deep learning technologies in popular, cutting-edge games like Google DeepMind's AlphaGo. Coding languages like Python, R, and frameworks like TensorFlow, Keras, and PyTorch are commonly used for deep learning tasks. Learning Deep Learning can be a prominent game-changer in your game development journey.",
"links": []
"description": "Deep Learning is a sub-field of machine learning, inspired by the structure and function of the human brain, specifically designed to process complex input/output transformations. It uses artificial neural networks with many layers (hence the term 'deep' learning) to model complex, non-linear hypotheses and discover hidden patterns within large datasets. Deep learning techniques are crucial in game development, primarily in creating intelligent behaviors and features in gaming agents, procedural content generation, and player profiling. You might have heard about the uses of deep learning technologies in popular, cutting-edge games like Google DeepMind's AlphaGo. Coding languages like Python, R, and frameworks like TensorFlow, Keras, and PyTorch are commonly used for deep learning tasks. Learning Deep Learning can be a prominent game-changer in your game development journey.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "But what is a neural network? | Chapter 1, Deep learning",
"url": "https://www.youtube.com/watch?v=aircAruvnKk",
"type": "video"
}
]
},
"AoH2r4EOHyZd8YaV24rBk": {
"title": "Artificial Neural Network",
@ -854,7 +866,13 @@
},
"YrQgfjsdLCIUxrwflpEHO": {
"title": "Microsurface Scattering",
"description": "Microsurface scattering, also known as sub-surface scattering, is an important phenomenon in Physically Based Rendering (PBR). This process involves the penetration of light into the surface of a material, where it is scattered by interacting with the material. In other words, when light strikes an object, rather than simply bouncing off the surface, some of it goes into the object and gets scattered around inside before getting re-emitted. It is key to achieving more realistic rendering of translucent materials like skin, marble, milk, and more. Consider it essential for replicating how light interacts with real-world materials in a convincing manner in your game.",
"links": []
"description": "Microsurface scattering, also known as sub-surface scattering, is an important phenomenon in Physically Based Rendering (PBR). This process involves the penetration of light into the surface of a material, where it is scattered by interacting with the material. In other words, when light strikes an object, rather than simply bouncing off the surface, some of it goes into the object and gets scattered around inside before getting re-emitted. It is key to achieving more realistic rendering of translucent materials like skin, marble, milk, and more. Consider it essential for replicating how light interacts with real-world materials in a convincing manner in your game.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "The 4 main types of subsurface scattering",
"url": "https://www.youtube.com/watch?v=GkjvYSbGHg4",
"type": "video"
}
]
}
}

@ -4,7 +4,7 @@
"description": "JavaScript, often abbreviated JS, is a programming language that is one of the core technologies of the World Wide Web, alongside HTML and CSS. It lets us add interactivity to pages e.g. you might have seen sliders, alerts, click interactions, popups, etc on different websites -- all of that is built using JavaScript. Apart from being used in the browser, it is also used in other non-browser environments as well such as Node.js for writing server-side code in JavaScript, Electron for writing desktop applications, React Native for mobile applications, and so on.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "You Dont Know JS Yet (book series)",
"title": "You Don't Know JS Yet (book series)",
"url": "https://github.com/getify/You-Dont-Know-JS",
"type": "opensource"
},
@ -200,7 +200,7 @@
"type": "article"
},
{
"title": "Understanding hoisting ",
"title": "Understanding Hoisting",
"url": "https://www.digitalocean.com/community/tutorials/understanding-hoisting-in-javascript",
"type": "article"
},
@ -307,7 +307,7 @@
},
"q85z6x1Lc-yLWepwtIT2_": {
"title": "const",
"description": "Constants are block-scoped, much like variables declared using the `let` keyword. The value of a constant can't be changed through reassignment (i.e. by using the assignment operator), and it can't be redeclared (i.e. through a variable declaration). However, if a constant is an object or array its properties or items can be updated or removed.\n\nVisit the following resources to learn more:",
"description": "Constants are block-scoped, much like variables declared using the `let` keyword. The value of a constant can't be changed through reassignment (i.e. by using the assignment operator), and it can't be re-declared (i.e. through a variable declaration). However, if a constant is an object or array its properties or items can be updated or removed.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "JavaScript Constants - CodeGuage",
@ -360,7 +360,7 @@
},
"oC4o6GLEES_nUgCJu9Q6I": {
"title": "Global",
"description": "Variables declared Globally (outside any function) have Global Scope. Global variables can be accessed from anywhere in a JavaScript program. Variables declared with `var`, `let` and `const` are quite similar when declared outside a block.\n\n### Note:\n\nIf you assign a value to a variable that has not been declared i.e `potato = true` it will automatically become a _GLOBAL_ variable.\n\nVisit the following resources to learn more:",
"description": "Variables declared Globally (outside any function) have Global Scope. Global variables can be accessed from anywhere in a JavaScript program. Variables declared with `var`, `let` and `const` are quite similar when declared outside a block.\n\nNote\n----\n\nIf you assign a value to a variable that has not been declared i.e `potato = true` it will automatically become a _GLOBAL_ variable.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "JavaScript Scope",
@ -445,7 +445,7 @@
},
"GZ_SXsWmP7AsXRTc4WUMw": {
"title": "number",
"description": "The `Number` data type in JavaScript represents floating-point numbers, such as 37 or -9.25. The `Number` constructor provides constants and methods to work with numbers, and values of other types can be converted to numbers using the `Number()` function.\n\n### Example\n\n let num1 = 255; // integer\n let num2 = 255.0; // floating-point number with no fractional part\n let num3 = 0xff; // hexadecimal notation\n let num4 = 0b11111111; // binary notation\n let num5 = 0.255e3; // exponential notation\n \n console.log(num1 === num2); // true\n console.log(num1 === num3); // true\n console.log(num1 === num4); // true\n console.log(num1 === num5); // true\n \n\nIn this example:\n\n* `255` and `255.0` are equivalent, as JavaScript treats both as the same number.\n* `0xff` represents `255` in hexadecimal notation.\n* `0b11111111` represents `255` in binary notation.\n* `0.255e3` is `255` in exponential notation.\n* All these different representations are equal to `255` in JavaScript.",
"description": "The `Number` data type in JavaScript represents floating-point numbers, such as 37 or -9.25. The `Number` constructor provides constants and methods to work with numbers, and values of other types can be converted to numbers using the `Number()` function.\n\nExample\n-------\n\n let num1 = 255; // integer\n let num2 = 255.0; // floating-point number with no fractional part\n let num3 = 0xff; // hexadecimal notation\n let num4 = 0b11111111; // binary notation\n let num5 = 0.255e3; // exponential notation\n \n console.log(num1 === num2); // true\n console.log(num1 === num3); // true\n console.log(num1 === num4); // true\n console.log(num1 === num5); // true\n \n\nIn this example:\n\n* `255` and `255.0` are equivalent, as JavaScript treats both as the same number.\n* `0xff` represents `255` in hexadecimal notation.\n* `0b11111111` represents `255` in binary notation.\n* `0.255e3` is `255` in exponential notation.\n* All these different representations are equal to `255` in JavaScript.",
"links": []
},
"6lUF0neW1piiP1RsaVxEX": {
@ -580,12 +580,12 @@
"description": "You can use the typeOf operator to find the data type of a JavaScript variable. It returns a string indicating the type of provided operand's value.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Typeof Reference",
"title": "typeof Reference",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof",
"type": "article"
},
{
"title": "Typeof Live Examples",
"title": "typeof Live Examples",
"url": "https://www.w3schools.com/js/tryit.asp?filename=tryjs_typeof_all",
"type": "article"
}
@ -695,7 +695,7 @@
"type": "article"
},
{
"title": "What you need to know about Javascripts Implicit Coercion",
"title": "What you need to know about JavaScript Implicit Coercion",
"url": "https://dev.to/promisetochi/what-you-need-to-know-about-javascripts-implicit-coercion-e23",
"type": "article"
}
@ -1245,7 +1245,7 @@
},
"-z-4VTaC3tOThqChgyoMs": {
"title": "Error Objects",
"description": "When a runtime error occurs, a new `Error` object is created and thrown. With this `Error` object, we can determine the type of the Error and handle it according to its type.\n\nTypes of Errors:\n----------------\n\nBesides error constructors, Javascript also has other core Error constructors.\n\n* [@article@AggregateError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError)\n* [@article@EvalError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError)\n* [@article@InternalError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError)\n* [@article@RangeError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError)\n* [@article@ReferenceError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError)\n* [@article@SyntaxError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError)\n\nExample\n-------\n\n try {\n willGiveErrorSometime();\n } catch (error) {\n if (error instanceof RangeError) {\n rangeErrorHandler(error);\n } else if (error instanceof ReferenceError) {\n referenceErrorHandle(error);\n } else {\n errorHandler(error);\n }\n }\n \n\nVisit the following resources to learn more:",
"description": "When a runtime error occurs, a new `Error` object is created and thrown. With this `Error` object, we can determine the type of the Error and handle it according to its type.\n\nTypes of Errors\n---------------\n\nBesides error constructors, Javascript also has other core Error constructors. Like\n\n* AggregateError - A collection of errors thrown simultaneously.\n* EvalError - An error occurred during the evaluation of a JavaScript expression.\n* InternalError - An internal JavaScript error, often indicating a bug in the engine.\n* RangeError - A value is outside the allowed range for a given operation.\n* ReferenceError - A variable or object is referenced before it's declared or doesn't exist.\n* SyntaxError - The code contains incorrect syntax, preventing it from being parsed.\n\nExample\n-------\n\n try {\n willGiveErrorSometime();\n } catch (error) {\n if (error instanceof RangeError) {\n rangeErrorHandler(error);\n } else if (error instanceof ReferenceError) {\n referenceErrorHandle(error);\n } else {\n errorHandler(error);\n }\n }\n \n\nVisit the following resources to learn more:",
"links": [
{
"title": "Error Object - MDN",
@ -1256,6 +1256,36 @@
"title": "Control flow & Error handling - MDN",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling",
"type": "article"
},
{
"title": "AggregateError",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError",
"type": "article"
},
{
"title": "EvalError",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError",
"type": "article"
},
{
"title": "InternalError",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError",
"type": "article"
},
{
"title": "RangeError",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError",
"type": "article"
},
{
"title": "ReferenceError",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError",
"type": "article"
},
{
"title": "SyntaxError",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError",
"type": "article"
}
]
},
@ -1415,7 +1445,7 @@
]
},
"k9rSR-YQ8B_iRcXNm2btP": {
"title": "Unary Opeartors",
"title": "Unary Operators",
"description": "JavaScript Unary Operators are the special operators that consider a single operand and perform all the types of operations on that single operand. These operators include unary plus, unary minus, prefix increments, postfix increments, prefix decrements, and postfix decrements.\n\nVisit the following resources to learn more:",
"links": [
{
@ -1480,7 +1510,7 @@
},
"fr0NChxMXLpJizyMhXcXS": {
"title": "Arrow Functions",
"description": "Arrow Function is a new way of creating functions with the '=>' operator with a shorter syntax.\n\nVisit the following resources to learn more:",
"description": "Arrow Function is a new way of creating functions with the '=>' operator with a shorter syntax.\n\nExample\n-------\n\n const sayHello = () => {\n console.log(`Hello from Arrow Function !`);\n }\n \n\nVisit the following resources to learn more:",
"links": [
{
"title": "MDN - Arrow Function Expressions",
@ -1496,7 +1526,7 @@
},
"YZlCoPvZuX5MmpLOTj5d4": {
"title": "IIFEs",
"description": "Immediately-Invoked Function Expression is a function that is executed immediately after it is created.\n\nVisit the following resources to learn more:",
"description": "Immediately-Invoked Function Expression is a function that is executed immediately after it is created.\n\nExample\n-------\n\n // An Async IIFE\n ( async() => {\n \n const x = 1;\n const y = 9;\n \n console.log(`Hello, The Answer is ${x+y}`);\n \n })();\n \n\nVisit the following resources to learn more:",
"links": [
{
"title": "IIFE — MDN Docs",
@ -1782,21 +1812,38 @@
"description": "The `call()` method allows you to invoke a function with a given `this` value, and arguments provided individually.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Understanding Explicit Binding in JavaScript: Call, Bind, and Apply Methods",
"url": "https://medium.com/@amitsharma_24072/understanding-explicit-binding-in-javascript-call-bind-and-apply-methods-7b6ed0107628",
"title": "Call Method - MDN Docs",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call",
"type": "article"
}
]
},
"-BtF34cEzI6J8sZCDRlRE": {
"title": "apply",
"description": "",
"links": []
"description": "The apply() method of Function instances calls this function with a given this value, and arguments provided as an array (or an array-like object).\n\nVisit the following resources to learn more:",
"links": [
{
"title": "apply() - MDN",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply",
"type": "article"
}
]
},
"dbercnxXVTJXMpYSDNGb2": {
"title": "bind",
"description": "",
"links": []
"description": "The `bind()` method creates a new function with a given `this` value and arguments provided as an array. The original function is not called immediately but can be called later with the `new` keyword or as a normal function call.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Understanding Explicit Binding in JavaScript: Call, Bind, and Apply Methods",
"url": "https://medium.com/@amitsharma_24072/understanding-explicit-binding-in-javascript-call-bind-and-apply-methods-7b6ed0107628",
"type": "article"
},
{
"title": "Javascript Function Bind()",
"url": "https://www.w3schools.com/js/js_function_bind.asp",
"type": "article"
}
]
},
"sFOqx6_7poVIVuXhJVY0E": {
"title": "Asynchronous JavaScript",
@ -1941,7 +1988,7 @@
},
"PJSdqvh5OBwPCNpn3q_S5": {
"title": "Callback Hell",
"description": "The callback hell is when we try to write asynchronous JavaScript in a way where execution happens visually from top to bottom, creating a code that has a pyramid shape with many }) at the end.\n\nVisit the following resources to learn more:",
"description": "The callback hell is when we try to write asynchronous JavaScript in a way where execution happens visually from top to bottom, creating a code that has a pyramid shape with many **})** at the end.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Callbacks in Callbacks - Pyramid of Doom",
@ -2004,7 +2051,7 @@
},
"kL5rfWxXe4J44ENru1uJS": {
"title": "Fetch",
"description": "The fetch() method in JavaScript is used to request to the server and load the information on the webpages. The request can be of any APIs that return the data of the format JSON or XML. This method returns a promise.\n\nVisit the following resources to learn more:",
"description": "The `fetch()` method in JavaScript is used to request to the server and load the information on the webpages. The request can be of any APIs that return the data of the format JSON or XML. This method returns a promise.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Fetch MDN Docs",
@ -2119,7 +2166,7 @@
},
"4EXeGkOpfAViB9Uo4zL6O": {
"title": "CommonJS",
"description": "CommonJS modules are the original way to package JavaScript code for Node.js. Node.js also supports the ESModules standard used by browsers and other JavaScript runtimes, but CJS is still widely used in backend Node.js applications. Sometimes these modules will be written with a .cjs extension.\n\nVisit the following resources to learn more:",
"description": "CommonJS modules are the original way to package JavaScript code for Node.js. Node.js also supports the ESModules standard used by browsers and other JavaScript run-times, but CJS is still widely used in backend Node.js applications. Sometimes these modules will be written with a .cjs extension.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "How the CJS Module System Works",
@ -2203,7 +2250,7 @@
},
"bhuGtcyqPFKu-900aESYz": {
"title": "DOM APIs",
"description": "With HTML DOM, JavaScript can access and change all the elements of an HTML document such as its attributes, CSS styles, remove elements, add and create new elements on the page. Web API means application programming inteface for the web. All browsers have a set og built-in Web APIs to support complex operations, and to help accessing data. Like Geolocation API, Web Storage, Web History and others.\n\nVisit the following resources to learn more:",
"description": "With HTML DOM, JavaScript can access and change all the elements of an HTML document such as its attributes, CSS styles, remove elements, add and create new elements on the page. Web API means application programming interface for the web. All browsers have a set of built-in Web APIs to support complex operations, and to help accessing data. Like Geo-location API, Web Storage, Web History and others.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "DOM- MDN Docs",
@ -2235,11 +2282,16 @@
},
"rc5WzBBOm2cus-rQl8EOE": {
"title": "Using Browser DevTools",
"description": "These are a set of tools built into the browser to aid frontend developers diagnose and solve various issues in their applications — such as JavaScript and logical bugs, CSS styling issues or even just making quick temporary alterations to the DOM.\n\nTo enter the dev tools, right click and click **Inspect** (or press `ctrl+shift+c`/`cmd+opt+c`) to enter the Elements panel. Here you can debug CSS and HTML issues. If you want to see logged messages or interact with javascript, enter the **Console** tab from the tabs above (or press `ctrl+shift+j` or `F12` /`cmd+opt+j` to enter it directly). Another very useful feature in the Chrome dev tools is the Lighthouse (for checking performance).\n\nNOTE: This isn't a chrome-specific feature, and most browsers (Chromium based or otherwise) will have their own, largely-similar set of devtools.\n\nVisit the following resources to learn more:",
"description": "These are a set of tools built into the browser to aid frontend developers diagnose and solve various issues in their applications — such as JavaScript and logical bugs, CSS styling issues or even just making quick temporary alterations to the DOM.\n\nTo enter the dev tools, right click and click **Inspect** (or press `ctrl+shift+c`/`cmd+opt+c`) to enter the Elements panel. Here you can debug CSS and HTML issues. If you want to see logged messages or interact with javascript, enter the **Console** tab from the tabs above (or press `ctrl+shift+j` or `F12` / `cmd+opt+j` to enter it directly). Another very useful feature in the Chrome dev tools is the Lighthouse (for checking performance).\n\nNOTE: This isn't a chrome-specific feature, and most browsers (Chromium based or otherwise) will have their own, largely-similar set of devtools.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Official Docs",
"url": "https://developer.chrome.com/docs/devtools/overview/",
"url": "https://developer.chrome.com/docs/devtools/",
"type": "article"
},
{
"title": "Debug JavaScript with Chrome Dev Tools",
"url": "https://developer.chrome.com/docs/devtools/javascript/",
"type": "article"
},
{
@ -2270,7 +2322,7 @@
"type": "article"
},
{
"title": "Effective Javascript Debugging ",
"title": "Effective Javascript Debugging",
"url": "https://medium.com/swlh/effective-javascript-debugging-memory-leaks-75059b2436f6",
"type": "article"
},
@ -2293,7 +2345,7 @@
},
"ECxISKUAU7js_JsfSHzud": {
"title": "Debugging Performance",
"description": "Enter the dev tools and check out the Lighthouse tab. This is essentially a series of tests which analyses the currently open website on a bunch of metrics related to performance, page speed, accessibility, etc. Feel free to run the tests by clicking the **Analyse Page Load** button (you might want to do this in an incognito tab to avoid errors arising from extensions you're using). Once you have the results, take your time and read through them (and do click through to the reference pages mentioned alongside each test result to know more about it!)\n\nVisit the following resources to learn more:",
"description": "Enter the dev tools and check out the Lighthouse tab. This is essentially a series of tests which analyses the currently open website on a bunch of metrics related to performance, page speed, accessibility, etc. Feel free to run the tests by clicking the **Analyze Page Load** button (you might want to do this in an incognito tab to avoid errors arising from extensions you're using). Once you have the results, take your time and read through them (and do click through to the reference pages mentioned alongside each test result to know more about it!)\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Analyze runtime performance",

@ -1616,6 +1616,11 @@
"title": "Drizzle",
"description": "Drizzle lets you build your project the way you want, without interfering with your project or structure. Using Drizzle you can define and manage database schemas in TypeScript, access your data in a SQL-like or relational way, and take advantage of opt-in tools to make your developer experience amazing.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "Drizzle Github",
"url": "https://github.com/drizzle-team/drizzle-orm",
"type": "opensource"
},
{
"title": "Drizzle Website",
"url": "https://orm.drizzle.team/",
@ -1626,11 +1631,6 @@
"url": "https://orm.drizzle.team/docs/overview",
"type": "article"
},
{
"title": "Drizzle Github",
"url": "https://github.com/drizzle-team/drizzle-orm",
"type": "article"
},
{
"title": "Getting Started with Drizzle",
"url": "https://dev.to/franciscomendes10866/getting-started-with-drizzle-orm-a-beginners-tutorial-4782",

@ -95,6 +95,17 @@
"title": "Type Conversion and Casting",
"url": "https://www.programiz.com/python-programming/type-conversion-and-casting",
"type": "article"
}
]
},
"fNTb9y3zs1HPYclAmu_Wv": {
"title": "Exceptions",
"description": "Python exceptions are events that occur during the execution of a program and disrupt the normal flow of the program's instructions. When an exception is raised, it indicates that an error has occurred. Python provides a way to handle these exceptions using try-except blocks, allowing developers to manage errors gracefully and ensure the program can continue or exit smoothly.",
"links": [
{
"title": "Exceptions Documentation",
"url": "https://docs.python.org/3/tutorial/errors.html#exceptions",
"type": "article"
},
{
"title": "Python Exceptions: An Introduction",
@ -115,17 +126,6 @@
"title": "Python Try Except",
"url": "https://www.w3schools.com/python/python_try_except.asp",
"type": "article"
}
]
},
"fNTb9y3zs1HPYclAmu_Wv": {
"title": "Exceptions",
"description": "Python exceptions are events that occur during the execution of a program and disrupt the normal flow of the program's instructions. When an exception is raised, it indicates that an error has occurred. Python provides a way to handle these exceptions using try-except blocks, allowing developers to manage errors gracefully and ensure the program can continue or exit smoothly.",
"links": [
{
"title": "Exceptions Documentation",
"url": "https://docs.python.org/3/tutorial/errors.html#exceptions",
"type": "article"
},
{
"title": "Exception Handling in Python",
@ -1207,10 +1207,16 @@
}
]
},
"black@DS6nuAUhUYcqiJDmQisKM.md": {
"DS6nuAUhUYcqiJDmQisKM": {
"title": "black",
"description": "",
"links": []
"description": "black is a code formatter for Python. It is a tool that automatically formats Python code to adhere to the PEP 8 style guide. It is a great tool to use in your Python projects to ensure that your code is formatted consistently and correctly.",
"links": [
{
"title": "black documentation",
"url": "https://black.readthedocs.io/en/stable/",
"type": "article"
}
]
},
"tsh_vbhzKz1-H9Vh69tsK": {
"title": "yapf",

@ -315,11 +315,6 @@
"url": "https://www.tutorialspoint.com/typescript/index.htm",
"type": "article"
},
{
"title": "Scrimba — TypeScript Basics",
"url": "https://scrimba.com/learn/typescript?via=roadmap",
"type": "article"
},
{
"title": "Explore top posts about JavaScript",
"url": "https://app.daily.dev/tags/javascript?ref=roadmapsh",
@ -1421,8 +1416,24 @@
},
"O7H6dt3Z7EKohxfJzwbPM": {
"title": "Kanban",
"description": "",
"links": []
"description": "`Kanban` is a popular agile methodology that focuses on visualizing workflow and continuously improving that flow. It's a more flexible approach than Scrum, without the rigid framework.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "What Is Kanban? A Simple Guide to Improve Efficiency.",
"url": "https://businessmap.io/kanban-resources/getting-started/what-is-kanban",
"type": "article"
},
{
"title": "Kanban Methodology: The Simplest Agile Framework ",
"url": "https://kissflow.com/project/agile/kanban-methodology/",
"type": "article"
},
{
"title": "What is Kanban Methodology? The Ultimate Guide",
"url": "https://www.wrike.com/kanban-guide/what-is-kanban/",
"type": "article"
}
]
},
"PKqwKvoffm0unwcFwpojk": {
"title": "Scrum",
@ -1431,8 +1442,24 @@
},
"7fL9lSu4BD1wRjnZy9tM9": {
"title": "XP",
"description": "",
"links": []
"description": "`Extreme Programming (XP)` is a popular agile software development framework that emphasizes speed, simplicity, and quality. It was developed by Kent Beck in the late 1990s and is based on five values:\n\n* **Communication**: Open and honest communication among team members and stakeholders is essential.\n* **Simplicity**: The simplest solution that works is always preferred.\n* **Feedback**: Continuous feedback from customers and team members is used to improve the product.\n* **Courage**: Team members must be willing to make changes and take risks.\n* **Respect**: Everyone on the team is treated with respect.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "What is Extreme Programming (XP)?",
"url": "https://www.agilealliance.org/glossary/xp/",
"type": "article"
},
{
"title": "It's Values, Principles, And Practices",
"url": "https://www.nimblework.com/agile/extreme-programming-xp/",
"type": "article"
},
{
"title": "Extreme Programming (XP)",
"url": "https://scrum-master.org/en/extreme-programming-xp-a-beginners-guide-to-the-agile-method/",
"type": "article"
}
]
},
"cBWJ6Duw99tSKr7U6OW3A": {
"title": "Networks",

@ -116,8 +116,14 @@
},
"rmqXH29n1oXtZ8tvmcRFn": {
"title": "SELECT",
"description": "",
"links": []
"description": "The SELECT statement in SQL is used to retrieve data from a database. It allows you to specify the columns you want to fetch from a particular table or a combination of tables. Here’s a basic syntax of a SELECT statement:\n\n'''sql SELECT \\* FROM employees; '''\n\nLearn more from the following resources:",
"links": [
{
"title": "SQL_Select",
"url": "https://www.w3schools.com/sql/sql_select.asp",
"type": "article"
}
]
},
"mPj6BiK5FKKkIQ9WsWEo6": {
"title": "INSERT",
@ -126,8 +132,14 @@
},
"eu9dJFi6gBPMBdy08Y5Bb": {
"title": "UPDATE",
"description": "",
"links": []
"description": "The `UPDATE` statement is used to modify existing data in a given table. \nIt can be done so with the query\n\n UPDATE table_name\n SET column1 = value1, column2 = value2, ...\n WHERE condition;\n \n\n* _Keep in mind that **SET** and **WHERE** are also commands to assign a new value(SET) only if the condition is met(WHERE)_\n\nOmitting the `WHERE` clause will update **all** rows in the table.\n\nVisit the following resources to learn more:",
"links": [
{
"title": "W3Schools SQL UPDATE Statement Doc",
"url": "https://www.w3schools.com/sql/sql_update.asp",
"type": "article"
}
]
},
"ddtVaA4Ls6qRj-7OtTSIH": {
"title": "DELETE",
@ -259,7 +271,7 @@
},
"4UQQYbjzwVxZOAxBuXKQS": {
"title": "JOINs",
"description": "SQL `JOINs` are clauses used to combine rows from two or more tables based on a related column between them. They allow retrieval of data from multiple tables in a single query, enabling complex data analysis and reporting. The main types of `JOINs` include `INNER JOIN` (returns matching rows from both tables), `LEFT JOIN` (returns all rows from the left table and matching rows from the right), `RIGHT JOIN` (opposite of `LEFT JOIN`), and `FULL JOIN` (returns all rows when there's a match in either table). `JOINs` are fundamental to relational database operations, facilitating data integration and exploration across related datasets.\n\nLearn more from the following resources:",
"description": "SQL `JOINs` are clauses used to combine rows from two or more tables based on a related column between them. They allow retrieval of data from multiple tables in a single query, enabling complex data analysis and reporting. The main types of `JOINs` include:\n\n* `INNER JOIN` (returns matching rows from both tables)\n* `LEFT JOIN` (returns all rows from the left table and matching rows from the right)\n* `RIGHT JOIN` (opposite of `LEFT JOIN`)\n* `FULL JOIN` (returns all rows when there's a match in either table)\n\n`JOINs` are fundamental to relational database operations, facilitating data integration and exploration across related datasets.\n\nLearn more from the following resources:",
"links": [
{
"title": "SQL JOINs Cheat Sheet",

@ -535,7 +535,7 @@
"type": "article"
},
{
"title": "Surpressing values in CLI output",
"title": "Suppressing values in CLI output",
"url": "https://developer.hashicorp.com/terraform/language/values/outputs#sensitive-suppressing-values-in-cli-output",
"type": "article"
}

@ -36,7 +36,7 @@ Here is the list of available roadmaps with more being actively worked upon.
- [Backend Roadmap](https://roadmap.sh/backend) / [Backend Beginner Roadmap](https://roadmap.sh/backend?r=backend-beginner)
- [DevOps Roadmap](https://roadmap.sh/devops) / [DevOps Beginner Roadmap](https://roadmap.sh/devops?r=devops-beginner)
- [Full Stack Roadmap](https://roadmap.sh/full-stack)
- [Git and GitHub Roadmap](https://roadmap.sh/git-github)
- [Git and GitHub](https://roadmap.sh/git-github)
- [API Design Roadmap](https://roadmap.sh/api-design)
- [Computer Science Roadmap](https://roadmap.sh/computer-science)
- [Data Structures and Algorithms Roadmap](https://roadmap.sh/datastructures-and-algorithms)

@ -0,0 +1,227 @@
import React, { useState } from 'react';
import { CheckIcon } from './ReactIcons/CheckIcon.tsx';
import { pageProgressMessage } from '../stores/page.ts';
import { httpPost } from '../lib/http.ts';
type InputProps = {
label: string;
name: string;
type: string;
value: string;
onChange: (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => void;
required?: boolean;
rows?: number;
};
function Input(props: InputProps) {
const { label, name, type, value, onChange, required, rows } = props;
return (
<div className="mb-4">
<label htmlFor={name} className="block text-sm font-medium text-gray-700">
{label} {required && <span className="text-red-500">*</span>}
</label>
{type === 'textarea' ? (
<textarea
placeholder={label}
id={name}
name={name}
value={value}
onChange={onChange}
rows={rows}
className="mt-1 block w-full rounded-md border border-gray-300 p-2 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
autoComplete="off"
data-1p-ignore=""
data-form-type="other"
data-lpignore="true"
></textarea>
) : (
<input
type={type}
id={name}
placeholder={label}
name={name}
value={value}
onChange={onChange}
required={required}
className="mt-1 block w-full rounded-md border border-gray-300 p-2 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
autoComplete="off"
data-1p-ignore=""
data-form-type="other"
data-lpignore="true"
/>
)}
</div>
);
}
export function AdvertiseForm() {
const [status, setStatus] = useState<'submitting' | 'submitted'>();
const [error, setError] = useState<string | null>(null);
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
title: '',
company: '',
email: '',
phone: '',
message: '',
updates: false,
});
const handleInputChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
const { name, value, type, checked } = e.target as any;
setFormData({
...formData,
[name]: type === 'checkbox' ? checked : value,
});
};
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
pageProgressMessage.set('Please wait');
// Placeholder function to send data
console.log('Form data:', formData);
const { response, error } = await httpPost(
`${import.meta.env.PUBLIC_API_URL}/v1-advertise`,
formData,
);
if (!response || error) {
pageProgressMessage.set('');
setError(error?.message || 'Something went wrong. Please try again.');
return;
}
setStatus('submitted');
pageProgressMessage.set('');
}
if (status === 'submitted') {
return (
<div className="flex flex-col items-center justify-center rounded-md border bg-gray-50 p-12 text-center">
<CheckIcon additionalClasses="h-12 w-12 text-green-500 mb-5" />
<h2 className="text-balance text-xl font-semibold text-gray-900">
Thank you for your interest in advertising with roadmap.sh
</h2>
<p className="mt-2 text-sm text-gray-500">
We will get back to you soon.
</p>
</div>
);
}
return (
<>
<h2 className="mb-5 text-balance text-2xl font-bold">
Ready to learn more? Fill out the form below to get started!
</h2>
{error && (
<div className="relative mb-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700">
{error}
</div>
)}
<form className="mb-5" onSubmit={handleSubmit}>
<div className="grid gap-0 sm:grid-cols-2 sm:gap-4">
<Input
label="First Name"
name="firstName"
type="text"
value={formData.firstName}
onChange={handleInputChange}
required
/>
<Input
label="Last Name"
name="lastName"
type="text"
value={formData.lastName}
onChange={handleInputChange}
required
/>
</div>
<div className="grid gap-0 sm:grid-cols-2 sm:gap-4">
<Input
label="Title"
name="title"
type="text"
value={formData.title}
onChange={handleInputChange}
required
/>
<Input
label="Company"
name="company"
type="text"
value={formData.company}
onChange={handleInputChange}
required
/>
</div>
<div className="grid gap-0 sm:grid-cols-2 sm:gap-4">
<Input
label="Email"
name="email"
type="email"
value={formData.email}
onChange={handleInputChange}
required
/>
<Input
label="Phone"
name="phone"
type="tel"
value={formData.phone}
onChange={handleInputChange}
/>
</div>
<Input
label="Message (Optional)"
name="message"
type="textarea"
value={formData.message}
onChange={handleInputChange}
rows={4}
/>
<div className="mb-4 flex items-start">
<div className="flex h-5 items-center">
<input
id="updates"
name="updates"
type="checkbox"
checked={formData.updates}
onChange={handleInputChange}
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/>
</div>
<div className="ml-3 text-sm">
<label htmlFor="updates" className="font-medium text-gray-700">
I want to receive occasional updates about new products or
advertising opportunities with roadmap.sh
</label>
</div>
</div>
<div>
<button
type="submit"
className="flex justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
>
Send
</button>
</div>
</form>
</>
);
}

@ -122,6 +122,7 @@ export function CustomRoadmap(props: CustomRoadmapProps) {
{!isEmbed && <RoadmapHeader />}
<FlowRoadmapRenderer isEmbed={isEmbed} roadmap={roadmap!} />
<TopicDetail
resourceId={roadmap!._id}
resourceTitle={roadmap!.title}
resourceType="roadmap"
isEmbed={isEmbed}

@ -35,8 +35,8 @@ import Icon from './AstroIcon.astro';
>
</p>
<div class='flex flex-col justify-between gap-12 sm:flex-row'>
<div class='max-w-[365px]'>
<div class='flex flex-col justify-between gap-8 lg:gap-2 lg:flex-row'>
<div class='max-w-[425px]'>
<p class='text-md flex items-center'>
<a
class='inline-flex items-center text-lg font-medium text-white transition-colors hover:text-gray-400'
@ -56,7 +56,7 @@ import Icon from './AstroIcon.astro';
</a>
</p>
<p class='my-4 text-slate-300/60'>
Community created roadmaps, articles, resources and journeys to help
Community created roadmaps, best practices, projects, articles, resources and journeys to help
you choose your path and grow in your career.
</p>
<div class='text-sm text-gray-400'>
@ -67,6 +67,8 @@ import Icon from './AstroIcon.astro';
<span class='mx-1.5'>&middot;</span>
<a href='/privacy' class='hover:text-white'>Privacy</a>
<span class='mx-1.5'>&middot;</span>
<a href='/advertise' class='hover:text-white'>Advertise</a>
<span class='mx-1.5'>&middot;</span>
<a
aria-label='Write us an email'
href='mailto:info@roadmap.sh'
@ -97,20 +99,19 @@ import Icon from './AstroIcon.astro';
</div>
</div>
<div class='max-w-[365px] text-left sm:text-right'>
<div class='max-w-[340px] text-left lg:text-right'>
<a href='https://thenewstack.io' target='_blank'>
<img
src='/images/tns-sm.png'
alt='ThewNewStack'
class='my-1.5 mr-auto sm:ml-auto sm:mr-0'
class='my-1.5 mr-auto lg:ml-auto lg:mr-0'
width='200'
height='24.8'
loading="lazy"
/>
</a>
<p class='my-4 text-slate-300/60'>
The leading DevOps resource for Kubernetes, cloud-native computing,
and the latest in at-scale development, deployment, and management.
The top DevOps resource for Kubernetes, cloud-native computing, and large-scale development and deployment.
</p>
<div class='text-sm text-gray-400'>
<p>

@ -62,6 +62,12 @@ const links = [
Icon: Shirt,
isExternal: true,
},
{
link: '/advertise',
label: 'Advertise',
description: 'Promote your product or service',
Icon: Menu,
},
];
export function NavigationDropdown() {

@ -8,7 +8,7 @@ import {
type AllowedVoteType,
} from './ListProjectSolutions';
import { getRelativeTimeString } from '../../lib/date';
import { ArrowUpRight, ThumbsDown, ThumbsUp } from 'lucide-react';
import { ArrowUpRight, ThumbsDown, ThumbsUp, Trophy } from 'lucide-react';
import { VoteButton } from './VoteButton';
import { GitHubIcon } from '../ReactIcons/GitHubIcon';
import { isLoggedIn } from '../../lib/jwt';
@ -131,64 +131,58 @@ export function ProjectSolutionModal(props: ProjectSolutionModalProps) {
deleteUrlParam('u');
window.location.reload();
}}
wrapperClassName={'max-w-lg'}
bodyClassName={'h-auto'}
>
<div className="relative p-4">
<h1 className="text-xl font-semibold">{projectTitle}</h1>
<p className="mt-1 max-w-xs text-sm text-gray-500">
{projectDescription}
</p>
<hr className="-mx-4 my-4 border-gray-300" />
<div className="flex items-center gap-1.5">
<img
src={
avatar
? `${import.meta.env.PUBLIC_AVATAR_BASE_URL}/${avatar}`
: '/images/default-avatar.png'
}
alt={solution?.user?.name}
className="mr-0.5 h-7 w-7 rounded-full"
/>
<span className="font-medium text-black">{solution?.user.name}</span>
<span className="hidden sm:inline">
{submittedAlternatives[
Math.floor(Math.random() * submittedAlternatives.length)
] || 'submitted their solution'}
</span>{' '}
<span className="flex-grow text-right text-gray-400 sm:flex-grow-0 sm:text-left sm:font-medium sm:text-black">
{getRelativeTimeString(solution?.submittedAt!)}
</span>
<div className="relative p-6">
<h1 className="text-2xl text-balance mb-1 font-bold text-gray-900">{projectTitle}</h1>
<p className="text-sm text-balance text-gray-600">{projectDescription}</p>
<div className="my-5 rounded-lg bg-gray-100 p-4">
<div className="flex items-center gap-3">
<img
src={
avatar
? `${import.meta.env.PUBLIC_AVATAR_BASE_URL}/${avatar}`
: '/images/default-avatar.png'
}
alt={solution?.user?.name}
className="h-12 w-12 rounded-full border-2 border-white shadow-md"
/>
<div>
<h2 className="text-lg font-semibold text-gray-900">{solution?.user.name}'s Solution</h2>
<p className="text-sm text-gray-600">
Submitted their solution{' '}
{getRelativeTimeString(solution?.submittedAt!)}
</p>
</div>
</div>
</div>
<div className="mt-4 flex items-center justify-between gap-2">
<div className="flex items-center justify-between">
<a
className="flex items-center gap-1 rounded-full border px-2 py-1 text-xs text-black transition-colors hover:border-black hover:bg-black hover:text-white"
className="flex items-center gap-2 rounded-full bg-black px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-gray-800"
href={solution?.repositoryUrl}
target="_blank"
>
<GitHubIcon className="h-4 w-4 text-current" />
View Solution
<GitHubIcon className="h-5 w-5 text-current" />
View Solution on GitHub
<ArrowUpRight className="h-4 w-4" />
</a>
<div className="flex shrink-0 overflow-hidden rounded-full border">
<div className="flex overflow-hidden rounded-full border">
<VoteButton
icon={ThumbsUp}
isActive={solution?.voteType === 'upvote'}
count={solution?.upvotes || 0}
onClick={() => {
handleSubmitVote(solution?.id!, 'upvote');
}}
onClick={() => handleSubmitVote(solution?.id!, 'upvote')}
/>
<VoteButton
icon={ThumbsDown}
isActive={solution?.voteType === 'downvote'}
count={solution?.downvotes || 0}
hideCount={true}
onClick={() => {
handleSubmitVote(solution?.id!, 'downvote');
}}
onClick={() => handleSubmitVote(solution?.id!, 'downvote')}
/>
</div>
</div>

@ -207,7 +207,7 @@ export function ProjectStepper(props: ProjectStepperProps) {
) : (
<>
<Share className="h-3 w-3 stroke-[2.5px]" />
<span className="hidden md:inline">Share Solution</span>
<span className="hidden md:inline">Share your Solution</span>
<span className="md:hidden">Share</span>
</>
)}
@ -262,12 +262,12 @@ export function ProjectStepper(props: ProjectStepperProps) {
{isCopied ? (
<>
<CheckIcon additionalClasses="h-3 w-3" />
Copied
URL Copied
</>
) : (
<>
<Share className="h-3 w-3 stroke-[2.5px]" />
Share Solution
Share your Solution
</>
)}
</button>

@ -1,5 +1,4 @@
import { CheckIcon, CopyIcon, X } from 'lucide-react';
import { CheckIcon as ReactCheckIcon } from '../ReactIcons/CheckIcon.tsx';
import { Modal } from '../Modal';
import { type FormEvent, useState } from 'react';
import { httpPost } from '../../lib/http';
@ -40,7 +39,7 @@ export function SubmitProjectModal(props: SubmitProjectModalProps) {
const { isCopied, copyText } = useCopyText();
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState('');
const [successMessage, setSuccessMessage] = useState('');
const [isSuccess, setIsSuccess] = useState(false);
const [repoUrl, setRepoUrl] = useState(defaultRepositoryUrl);
const [verificationChecks, setVerificationChecks] =
useState<VerificationChecksType>({
@ -62,7 +61,7 @@ export function SubmitProjectModal(props: SubmitProjectModalProps) {
setIsLoading(true);
setError('');
setSuccessMessage('');
setIsSuccess(false);
if (!repoUrl) {
setVerificationChecks({
@ -199,7 +198,7 @@ export function SubmitProjectModal(props: SubmitProjectModalProps) {
);
}
setSuccessMessage('Solution submitted successfully!');
setIsSuccess(true);
setIsLoading(false);
onSubmit(submitResponse);
@ -210,14 +209,8 @@ export function SubmitProjectModal(props: SubmitProjectModalProps) {
}
};
if (successMessage) {
return (
<SubmitSuccessModal
projectId={projectId}
onClose={onClose}
successMessage={successMessage}
/>
);
if (isSuccess) {
return <SubmitSuccessModal projectId={projectId} onClose={onClose} />;
}
return (
@ -296,12 +289,6 @@ export function SubmitProjectModal(props: SubmitProjectModalProps) {
{error && (
<p className="mt-2 text-sm font-medium text-red-500">{error}</p>
)}
{successMessage && (
<p className="mt-2 text-sm font-medium text-green-500">
{successMessage}
</p>
)}
</form>
<button

@ -1,10 +1,4 @@
import {
CheckCircle2,
Clipboard,
Facebook,
Linkedin,
Twitter,
} from 'lucide-react';
import { CheckCircle, CheckCircle2, Clipboard, Copy } from 'lucide-react';
import { getUser } from '../../lib/jwt.ts';
import { Modal } from '../Modal';
import { CheckIcon as ReactCheckIcon } from '../ReactIcons/CheckIcon.tsx';
@ -14,62 +8,43 @@ import { cn } from '../../lib/classname.ts';
type SubmitSuccessModalProps = {
projectId: string;
onClose: () => void;
successMessage: string;
};
export function SubmitSuccessModal(props: SubmitSuccessModalProps) {
const { onClose, successMessage, projectId } = props;
const { onClose, projectId } = props;
const user = getUser();
const description = 'Check out my solution to this project on Roadmap.sh';
const projectSolutionUrl = `${import.meta.env.DEV ? 'http://localhost:3000' : 'https://roadmap.sh'}/projects/${projectId}/solutions?u=${user?.id}`;
const { isCopied, copyText } = useCopyText();
const socialShareLinks = [
{
title: 'Twitter',
href: `https://x.com/intent/tweet?text=${description}&url=${projectSolutionUrl}`,
icon: <Twitter className="size-4 text-gray-700" />,
},
{
title: 'Facebook',
href: `https://www.facebook.com/sharer/sharer.php?quote=${description}&u=${projectSolutionUrl}`,
icon: <Facebook className="size-4 text-gray-700" />,
},
{
title: 'Linkedin',
href: `https://www.linkedin.com/sharing/share-offsite/?url=${projectSolutionUrl}`,
icon: <Linkedin className="size-4 text-gray-700" />,
},
];
return (
<Modal onClose={onClose} bodyClassName="h-auto p-4">
<div className="flex flex-col items-center justify-center pb-5 pt-12">
<div className="flex flex-col items-center justify-center pb-3 pt-12">
<ReactCheckIcon additionalClasses="h-12 text-green-500 w-12" />
<p className="mt-4 text-lg font-medium">{successMessage}</p>
<p className="mt-4 text-lg font-medium">Solution Submitted</p>
<p className="mt-0.5 text-center text-sm text-gray-500">
You can use the link to share your solution with others.
Congrats! Your solution has been submitted.
</p>
<div className="mt-4 flex w-full items-stretch rounded-md border bg-gray-50">
<div className="mt-4 w-full">
<input
type="text"
readOnly={true}
value={projectSolutionUrl}
className="w-full bg-transparent px-2.5 py-2 text-sm text-gray-700 focus:outline-none"
className="w-full rounded-md border bg-gray-50 px-2.5 py-2 text-sm text-gray-700 focus:outline-none"
onClick={(e) => {
e.currentTarget.select();
copyText(projectSolutionUrl);
}}
/>
<button
className={cn(
'm-1 ml-0 flex items-center gap-1 rounded-md bg-gray-200 px-2 py-1.5 text-xs font-medium text-black',
isCopied ? 'bg-green-200 text-green-900' : '',
'mt-2 flex w-full items-center justify-center gap-1 rounded-md px-2 py-2 text-sm font-medium transition-colors',
isCopied
? 'bg-green-600 text-white hover:bg-green-700'
: 'bg-black text-white hover:bg-gray-800'
)}
onClick={() => {
copyText(projectSolutionUrl);
@ -77,35 +52,17 @@ export function SubmitSuccessModal(props: SubmitSuccessModalProps) {
>
{isCopied ? (
<>
<CheckCircle2 className="size-3 stroke-[2.5px]" />
Copied
<CheckCircle className="size-4 stroke-[2.5px]" />
URL Copied
</>
) : (
<>
<Clipboard className="size-3 stroke-[2.5px]" />
Copy
<Copy className="size-4 stroke-[2.5px]" />
Copy Shareable Link
</>
)}
</button>
</div>
<div className="mt-8 flex justify-center gap-2">
{socialShareLinks.map((socialLink) => (
<a
key={socialLink.title}
href={socialLink.href}
target="_blank"
rel="noreferrer"
className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md border bg-gray-50 hover:bg-gray-100"
>
{socialLink.icon}
</a>
))}
</div>
<p className="mt-4 text-sm text-gray-500">
Share your solution with the others!
</p>
</div>
</Modal>
);

@ -0,0 +1,17 @@
interface FacebookIconProps {
className?: string;
}
export function FacebookIcon(props: FacebookIconProps) {
const { className } = props;
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
fill="currentColor"
className={className}
>
<path d="M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h137.25V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.27c-30.81 0-40.42 19.12-40.42 38.73V256h68.78l-11 71.69h-57.78V480H400a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48z" />
</svg>
);
}

@ -1,49 +1,29 @@
type LinkedInIconProps = {
interface LinkedInIconProps {
className?: string;
};
}
export function LinkedInIcon(props: LinkedInIconProps) {
const { className } = props;
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
x="0px"
y="0px"
width="100"
height="100"
viewBox="0,0,256,256"
>
<g transform="translate(-26.66667,-26.66667) scale(1.20833,1.20833)">
<g
fill="none"
fillRule="nonzero"
stroke="none"
strokeWidth="1"
strokeLinecap="butt"
strokeLinejoin="miter"
strokeMiterlimit="10"
strokeDasharray=""
strokeDashoffset="0"
fontFamily="none"
fontWeight="none"
fontSize="none"
textAnchor="none"
style={{ mixBlendMode: 'normal' }}
>
<g transform="scale(5.33333,5.33333)">
<path
d="M42,37c0,2.762 -2.238,5 -5,5h-26c-2.761,0 -5,-2.238 -5,-5v-26c0,-2.762 2.239,-5 5,-5h26c2.762,0 5,2.238 5,5z"
fill="#0288d1"
></path>
<path
d="M12,19h5v17h-5zM14.485,17h-0.028c-1.492,0 -2.457,-1.112 -2.457,-2.501c0,-1.419 0.995,-2.499 2.514,-2.499c1.521,0 2.458,1.08 2.486,2.499c0,1.388 -0.965,2.501 -2.515,2.501zM36,36h-5v-9.099c0,-2.198 -1.225,-3.698 -3.192,-3.698c-1.501,0 -2.313,1.012 -2.707,1.99c-0.144,0.35 -0.101,1.318 -0.101,1.807v9h-5v-17h5v2.616c0.721,-1.116 1.85,-2.616 4.738,-2.616c3.578,0 6.261,2.25 6.261,7.274l0.001,9.726z"
fill="#ffffff"
></path>
</g>
</g>
<g clipPath="url(#clip0_2344_20)">
<path
d="M0 0V24H24V0H0ZM8 19H5V8H8V19ZM6.5 6.732C5.534 6.732 4.75 5.942 4.75 4.968C4.75 3.994 5.534 3.204 6.5 3.204C7.466 3.204 8.25 3.994 8.25 4.968C8.25 5.942 7.467 6.732 6.5 6.732ZM20 19H17V13.396C17 10.028 13 10.283 13 13.396V19H10V8H13V9.765C14.397 7.179 20 6.988 20 12.241V19Z"
fill="currentColor"
/>
</g>
<defs>
<clipPath id="clip0_2344_20">
<rect width="24" height="24" rx="2" fill="white" />
</clipPath>
</defs>
</svg>
);
}

@ -1,6 +1,6 @@
import type { JSX } from "preact/jsx-runtime";
import type { SVGAttributes } from 'react';
type ShareIconProps = JSX.SVGAttributes<SVGSVGElement>
type ShareIconProps = SVGAttributes<SVGSVGElement>;
export function ShareIcon(props: ShareIconProps) {
return (

@ -1,22 +1,22 @@
type TwitterIconProps = {
interface TwitterIconProps {
className?: string;
};
}
export function TwitterIcon(props: TwitterIconProps) {
const { className } = props;
return (
<svg
width="15"
height="15"
viewBox="0 0 15 15"
width="23"
height="23"
viewBox="0 0 23 23"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<rect width="23" height="23" rx="3" fill="currentColor" />
<path
d="M8.9285 6.35221L14.5135 0H13.1905L8.339 5.5144L4.467 0H0L5.8565 8.33955L0 15H1.323L6.443 9.17535L10.533 15H15M1.8005 0.976187H3.833L13.1895 14.0718H11.1565"
fill="currentColor"
d="M12.9285 10.3522L18.5135 4H17.1905L12.339 9.5144L8.467 4H4L9.8565 12.3395L4 19H5.323L10.443 13.1754L14.533 19H19M5.8005 4.97619H7.833L17.1895 18.0718H15.1565"
fill="#E5E5E5"
/>
</svg>
);

@ -91,6 +91,7 @@ export function TeamPricing() {
{
'top-full': !isCopied,
'top-0': isCopied,
'opacity-0': !isCopied,
},
)}
>

@ -0,0 +1,33 @@
import { type LucideIcon, Star } from 'lucide-react';
import { cn } from '../../lib/classname.ts';
type ResourceSeparatorProps = {
text: string;
className?: string;
labelClassName?: string;
icon?: LucideIcon;
};
export function ResourceListSeparator(props: ResourceSeparatorProps) {
const { text, icon: Icon, className = '', labelClassName = '' } = props;
return (
<p
className={cn(
'relative mt-6 flex items-center justify-start text-purple-600',
className,
)}
>
<span
className={cn(
'relative left-3 z-50 inline-flex items-center gap-1 rounded-md border border-current bg-white px-2 py-0.5 text-xs font-medium',
labelClassName,
)}
>
{Icon && <Icon className="inline-block h-3 w-3 fill-current" />}
{text}
</span>
<hr className="absolute inset-x-0 flex-grow border-current" />
</p>
);
}

@ -22,8 +22,7 @@ import type {
RoadmapContentDocument,
} from '../CustomRoadmap/CustomRoadmap';
import { markdownToHtml, sanitizeMarkdown } from '../../lib/markdown';
import { cn } from '../../lib/classname';
import { Ban, FileText, HeartHandshake, X } from 'lucide-react';
import { Ban, FileText, HeartHandshake, Star, X } from 'lucide-react';
import { getUrlParams, parseUrl } from '../../lib/browser';
import { Spinner } from '../ReactIcons/Spinner';
import { GitHubIcon } from '../ReactIcons/GitHubIcon.tsx';
@ -31,8 +30,11 @@ import { GoogleIcon } from '../ReactIcons/GoogleIcon.tsx';
import { YouTubeIcon } from '../ReactIcons/YouTubeIcon.tsx';
import { resourceTitleFromId } from '../../lib/roadmap.ts';
import { lockBodyScroll } from '../../lib/dom.ts';
import { TopicDetailLink } from './TopicDetailLink.tsx';
import { ResourceListSeparator } from './ResourceListSeparator.tsx';
type TopicDetailProps = {
resourceId?: string;
resourceTitle?: string;
resourceType?: ResourceType;
@ -40,21 +42,42 @@ type TopicDetailProps = {
canSubmitContribution: boolean;
};
const linkTypes: Record<AllowedLinkTypes, string> = {
article: 'bg-yellow-300',
course: 'bg-green-400',
opensource: 'bg-black text-white',
'roadmap.sh': 'bg-black text-white',
roadmap: 'bg-black text-white',
podcast: 'bg-purple-300',
video: 'bg-purple-300',
website: 'bg-blue-300',
official: 'bg-blue-600 text-white',
feed: "bg-[#ce3df3] text-white"
type PaidResourceType = {
_id?: string;
title: string;
type: 'course' | 'book' | 'other';
url: string;
topicIds: string[];
};
const paidResourcesCache: Record<string, PaidResourceType[]> = {};
async function fetchRoadmapPaidResources(roadmapId: string) {
if (paidResourcesCache[roadmapId]) {
return paidResourcesCache[roadmapId];
}
const { response, error } = await httpGet<PaidResourceType[]>(
`${import.meta.env.PUBLIC_API_URL}/v1-list-roadmap-paid-resources/${roadmapId}`,
);
if (!response || error) {
console.error(error);
return [];
}
paidResourcesCache[roadmapId] = response;
return response;
}
export function TopicDetail(props: TopicDetailProps) {
const { canSubmitContribution, isEmbed = false, resourceTitle } = props;
const {
canSubmitContribution,
resourceId: defaultResourceId,
isEmbed = false,
resourceTitle,
} = props;
const [hasEnoughLinks, setHasEnoughLinks] = useState(false);
const [contributionUrl, setContributionUrl] = useState('');
@ -77,6 +100,7 @@ export function TopicDetail(props: TopicDetailProps) {
const [topicId, setTopicId] = useState('');
const [resourceId, setResourceId] = useState('');
const [resourceType, setResourceType] = useState<ResourceType>('roadmap');
const [paidResources, setPaidResources] = useState<PaidResourceType[]>([]);
// Close the topic detail when user clicks outside the topic detail
useOutsideClick(topicRef, () => {
@ -87,6 +111,16 @@ export function TopicDetail(props: TopicDetailProps) {
setIsActive(false);
});
useEffect(() => {
if (resourceType !== 'roadmap' || !defaultResourceId) {
return;
}
fetchRoadmapPaidResources(defaultResourceId).then((resources) => {
setPaidResources(resources);
});
}, [defaultResourceId]);
// Toggle topic is available even if the component UI is not active
// This is used on the best practice screen where we have the checkboxes
// to mark the topic as done/undone.
@ -225,7 +259,13 @@ export function TopicDetail(props: TopicDetailProps) {
// article at third
// videos at fourth
// rest at last
const order = ['official', 'opensource', 'article', 'video', 'feed'];
const order = [
'official',
'opensource',
'article',
'video',
'feed',
];
return order.indexOf(a.type) - order.indexOf(b.type);
});
@ -280,6 +320,12 @@ export function TopicDetail(props: TopicDetailProps) {
const tnsLink =
'https://thenewstack.io/devops/?utm_source=roadmap.sh&utm_medium=Referral&utm_campaign=Topic';
const paidResourcesForTopic = paidResources.filter((resource) => {
const normalizedTopicId =
topicId.indexOf('@') !== -1 ? topicId.split('@')[1] : topicId;
return resource.topicIds.includes(normalizedTopicId);
});
return (
<div className={'relative z-[90]'}>
<div
@ -377,94 +423,108 @@ export function TopicDetail(props: TopicDetailProps) {
)}
{links.length > 0 && (
<ul className="mt-6 space-y-1">
{links.map((link) => {
return (
<li key={link.id}>
<>
<ResourceListSeparator
text="Free Resources"
className="text-green-600"
icon={HeartHandshake}
/>
<ul className="ml-3 mt-4 space-y-1">
{links.map((link) => {
return (
<li key={link.id}>
<TopicDetailLink
url={link.url}
type={link.type}
title={link.title}
onClick={() => {
// if it is one of our roadmaps, we want to track the click
if (canSubmitContribution) {
const parsedUrl = parseUrl(link.url);
window.fireEvent({
category: 'TopicResourceClick',
action: `Click: ${parsedUrl.hostname}`,
label: `${resourceType} / ${resourceId} / ${topicId} / ${link.url}`,
});
}
}}
/>
</li>
);
})}
</ul>
</>
)}
{paidResourcesForTopic.length > 0 && (
<>
<ResourceListSeparator text="Premium Resources" icon={Star} />
<ul className="ml-3 mt-3 space-y-1">
{paidResourcesForTopic.map((resource) => {
return (
<li key={resource._id}>
<TopicDetailLink
url={resource.url}
type={resource.type as any}
title={resource.title}
isPaid={true}
/>
</li>
);
})}
</ul>
</>
)}
{/* Contribution */}
{canSubmitContribution &&
!hasEnoughLinks &&
contributionUrl &&
hasContent && (
<div className="mb-12 mt-3 border-t text-sm text-gray-400 sm:mt-12">
<div className="mb-4 mt-3">
<p className="">
Find more resources using these pre-filled search
queries:
</p>
<div className="mt-3 flex gap-2 text-gray-700">
<a
href={link.url}
href={googleSearchUrl}
target="_blank"
className="group font-medium text-gray-800 underline underline-offset-1 hover:text-black"
onClick={() => {
// if it is one of our roadmaps, we want to track the click
if (canSubmitContribution) {
const parsedUrl = parseUrl(link.url);
window.fireEvent({
category: 'TopicResourceClick',
action: `Click: ${parsedUrl.hostname}`,
label: `${resourceType} / ${resourceId} / ${topicId} / ${link.url}`,
});
}
}}
className="flex items-center gap-2 rounded-md border border-gray-300 px-3 py-1.5 pl-2 text-xs hover:border-gray-700 hover:bg-gray-100"
>
<span
className={cn(
'mr-2 inline-block rounded px-1.5 py-0.5 text-xs uppercase no-underline',
link.type in linkTypes
? linkTypes[link.type]
: 'bg-gray-200',
)}
>
{link.type === 'opensource' ? (
<>
{link.url.includes('github') && 'GitHub'}
{link.url.includes('gitlab') && 'GitLab'}
</>
) : (
link.type
)}
</span>
{link.title}
<GoogleIcon className={'h-4 w-4'} />
Google
</a>
</li>
);
})}
</ul>
)}
<a
href={youtubeSearchUrl}
target="_blank"
className="flex items-center gap-2 rounded-md border border-gray-300 px-3 py-1.5 pl-2 text-xs hover:border-gray-700 hover:bg-gray-100"
>
<YouTubeIcon className={'h-4 w-4 text-red-500'} />
YouTube
</a>
</div>
</div>
{/* Contribution */}
{canSubmitContribution && !hasEnoughLinks && contributionUrl && hasContent && (
<div className="mb-12 mt-3 border-t text-sm text-gray-400 sm:mt-12">
<div className="mb-4 mt-3">
<p className="">
Find more resources using these pre-filled search queries:
<p className="mb-2 mt-2 leading-relaxed">
This popup should be a brief introductory paragraph for
the topic and a few links to good articles, videos, or any
other self-vetted resources. Please consider submitting a
PR to improve this content.
</p>
<div className="mt-3 flex gap-2 text-gray-700">
<a
href={googleSearchUrl}
target="_blank"
className="flex items-center gap-2 rounded-md border border-gray-300 px-3 py-1.5 pl-2 text-xs hover:border-gray-700 hover:bg-gray-100"
>
<GoogleIcon className={'h-4 w-4'} />
Google
</a>
<a
href={youtubeSearchUrl}
target="_blank"
className="flex items-center gap-2 rounded-md border border-gray-300 px-3 py-1.5 pl-2 text-xs hover:border-gray-700 hover:bg-gray-100"
>
<YouTubeIcon className={'h-4 w-4 text-red-500'} />
YouTube
</a>
</div>
<a
href={contributionUrl}
target={'_blank'}
className="flex w-full items-center justify-center rounded-md bg-gray-800 p-2 text-sm text-white transition-colors hover:bg-black hover:text-white disabled:bg-green-200 disabled:text-black"
>
<GitHubIcon className="mr-2 inline-block h-4 w-4 text-white" />
Help us Improve this Content
</a>
</div>
<p className="mb-2 mt-2 leading-relaxed">
This popup should be a brief introductory paragraph for the topic and a few links
to good articles, videos, or any other self-vetted resources. Please consider
submitting a PR to improve this content.
</p>
<a
href={contributionUrl}
target={'_blank'}
className="flex w-full items-center justify-center rounded-md bg-gray-800 p-2 text-sm text-white transition-colors hover:bg-black hover:text-white disabled:bg-green-200 disabled:text-black"
>
<GitHubIcon className="mr-2 inline-block h-4 w-4 text-white" />
Help us Improve this Content
</a>
</div>
)}
)}
</div>
{resourceId === 'devops' && (
<div className="mt-4">
@ -528,4 +588,4 @@ export function TopicDetail(props: TopicDetailProps) {
<div className="fixed inset-0 z-30 bg-gray-900 bg-opacity-50 dark:bg-opacity-80"></div>
</div>
);
}
}

@ -0,0 +1,57 @@
import { cn } from '../../lib/classname.ts';
import type { AllowedLinkTypes } from '../CustomRoadmap/CustomRoadmap.tsx';
const linkTypes: Record<AllowedLinkTypes, string> = {
article: 'bg-yellow-300',
course: 'bg-green-400',
opensource: 'bg-black text-white',
'roadmap.sh': 'bg-black text-white',
roadmap: 'bg-black text-white',
podcast: 'bg-purple-300',
video: 'bg-purple-300',
website: 'bg-blue-300',
official: 'bg-blue-600 text-white',
feed: 'bg-[#ce3df3] text-white',
};
const paidLinkTypes: Record<string, string> = {
course: 'bg-yellow-300',
};
type TopicDetailLinkProps = {
url: string;
onClick?: () => void;
type: AllowedLinkTypes;
title: string;
isPaid?: boolean;
};
export function TopicDetailLink(props: TopicDetailLinkProps) {
const { url, onClick, type, title, isPaid = false } = props;
return (
<a
href={url}
target="_blank"
className="group font-medium text-gray-800 underline underline-offset-1 hover:text-black"
onClick={onClick}
>
<span
className={cn(
'mr-2 inline-block rounded px-1.5 py-0.5 text-xs uppercase no-underline',
(isPaid ? paidLinkTypes[type] : linkTypes[type]) || 'bg-gray-200',
)}
>
{type === 'opensource' ? (
<>
{url.includes('github') && 'GitHub'}
{url.includes('gitlab') && 'GitLab'}
</>
) : (
type
)}
</span>
{title}
</a>
);
}

@ -27,7 +27,7 @@ export function UserPublicProfileHeader(props: UserPublicProfileHeaderProps) {
: '/images/default-avatar.png'
}
alt={name}
className="h-32 w-32 rounded-full"
className="h-32 w-32 object-cover rounded-full"
/>
<div>

@ -385,7 +385,7 @@ As a recommendation for technology implementing this project, [Socket.io](http:/
![Content Delivery Network (CDN) Simulator](https://assets.roadmap.sh/guest/cdn-simulator-lv7kl.png)
For this particular backend project, we’re not going to focus on coding, but rather on backend tools and their configuration. A [CDN](https://aws.amazon.com/es/what-is/cdn/) (or Content Delivery Network) is a platform that allows you to serve static content (like text files, images, audio, etc) safely and reliably.
For this particular backend project, we’re not going to focus on coding, but rather on backend tools and their configuration. A [CDN](https://aws.amazon.com/what-is/cdn/) (or Content Delivery Network) is a platform that allows you to serve static content (like text files, images, audio, etc) safely and reliably.
Instead of having all files inside the same server, the content is replicated and distributed across a network of servers that can provide you with the files at any given point in time.
@ -459,4 +459,4 @@ Feel free to add extra commands to make the navigation even more interactive.
With the last of our backend project ideas, you’ve covered all the major areas involved in backend development and you’re more than ready to apply for a backend development job if you haven’t already.
If you find a piece of technology that wasn’t covered here, you’ll have the skills required to pick it up in no time.
If you find a piece of technology that wasn’t covered here, you’ll have the skills required to pick it up in no time.

@ -0,0 +1,452 @@
---
title: 'Top 10+ Backend Technologies to Use in @currentYear@: Expert Advice'
description: 'Looking for the best backend technologies in @currentYear@? Check out our expert list of top tools for developers.'
authorId: fernando
excludedBySlug: '/backend/technologies'
seo:
title: 'Top 10+ Backend Technologies to Use in @currentYear@: Expert Advice'
description: 'Looking for the best backend technologies in @currentYear@? Check out our expert list of top tools for developers.'
ogImageUrl: 'https://assets.roadmap.sh/guest/backend-technologies-pnof4.jpg'
isNew: true
type: 'textual'
date: 2024-08-27
sitemap:
priority: 0.7
changefreq: 'weekly'
tags:
- 'guide'
- 'textual-guide'
- 'guide-sitemap'
---
![Best backend development technologies.](https://assets.roadmap.sh/guest/backend-technologies-pnof4.jpg)
Backend technologies are the key to building robust and scalable applications. They power all platforms and products on the web without even being visible to the users.
While backend programming languages form the foundation of backend development, they aren't enough on their own. Understanding and leveraging the right backend technologies can significantly enhance your development workflow and application performance.
As a [backend developer](https://roadmap.sh/backend), you’ll be faced with too many options while trying to define your backend technology stack, and that can feel overwhelming.
So, in this article, we’re going to cover the best backend technologies in the following categories:
- Databases
- Version control systems
- Containerization and orchestration
- Cloud platforms
- APIs & Web Services
- Caching systems
- Message brokers
- Authentication and Authorization systems
- CI/CD
- Monitoring & Logging
These should help you stay up-to-date or reach the required level to succeed as a backend developer.
## Databases
![Databases](https://assets.roadmap.sh/guest/databases-4a1kz.png)
We can’t have a list of backend technologies to learn without covering databases. After all, databases are a core piece of the best backend technologies in use today and the backbone of any application, providing the necessary storage and retrieval of data. Choosing the right type of database depends on your application's requirements, such as data consistency, scalability, and complexity.
### SQL Databases
SQL databases (or relational databases as they’re also called) bring structure to your data and a standard querying language known as SQL.
#### PostgreSQL
PostgreSQL is an advanced open-source relational database known for its reliability and extensive feature set. It supports a wide range of data types and complex queries, making it ideal for applications that require ACID compliance and advanced data handling capabilities. PostgreSQL is commonly used in financial systems, data warehousing, and applications needing strong data integrity and complex reporting.
PostgreSQL also offers robust support for JSON and JSONB data types, enabling seamless integration of relational and NoSQL capabilities within a single database system. Its powerful indexing mechanisms ensure efficient query performance even with large datasets.
Additionally, PostgreSQL provides advanced security features like row-level security and multi-factor authentication, making it a secure choice for handling sensitive data.
#### MySQL
MySQL is a widely used open-source SQL database praised for its speed, reliability, and ease of use. It is particularly popular backend technology for web applications and online transaction processing (OLTP) due to its performance and robust community support. MySQL is often the database of choice for content management systems, e-commerce platforms, and logging applications.
MySQL also supports a variety of storage engines, including InnoDB, which provides ACID compliance, foreign key support, and transaction-safe operations, making it suitable for a wide range of applications.
Its replication capabilities, including master-slave and group replication, ensure high availability and scalability for large-scale deployments. Additionally, MySQL offers advanced security features such as data encryption, user authentication, and role-based access control, enhancing its suitability for handling sensitive data.
#### Microsoft SQL Server
SQL Server is a relational database management system from Microsoft that offers great performance, scalability, and deep integration with other Microsoft products. It provides comprehensive tools for database management, including advanced analytics and business intelligence features. SQL Server is ideal for enterprise-level applications, data warehousing, and environments where integration with Microsoft services, such as Azure, is beneficial.
MSSQL Server also includes robust security features, such as transparent data encryption, dynamic data masking, and advanced threat protection, making it a trusted choice for handling sensitive data. It supports a wide range of data types, including spatial and XML data, and offers powerful indexing and query optimization techniques to ensure efficient data retrieval and processing.
SQL Server's integration with Visual Studio and other Microsoft development tools helps to streamline the development process.
#### SQLite
SQLite is a self-contained, serverless, and zero-configuration database engine known for its simplicity and ease of use. It is lightweight and efficient, making it perfect for small to medium-sized applications, mobile apps, desktop applications, and prototyping. SQLite is embedded within the application, eliminating the need for a separate database server, which simplifies deployment and maintenance.
Its single-disk file format makes it highly portable across various operating systems and platforms.
SQLite's efficient memory and disk usage allow it to perform well even on devices with limited resources, such as IoT devices and embedded systems.
This makes SQLite an excellent choice for applications where simplicity, reliability, and low overhead are essential.
### NoSQL Databases
On the other hand, NoSQL databases allow for more flexibility by removing the need for a fixed schema and structure to your data. Each solution presented here covers a different type of unstructured database, and it’s up to you to decide if that focus actually makes sense for your business logic or not.
#### MongoDB
MongoDB is a document-oriented database that offers flexibility and scalability. It handles unstructured data with ease, making it ideal for applications with large-scale data and real-time analytics. MongoDB is commonly used in content management systems, e-commerce platforms, and applications that require a dynamic schema. Its ability to store data in JSON-like documents allows for easy data retrieval and manipulation.
#### DynamoDB
DynamoDB is a fully managed NoSQL database service provided by AWS. It is designed for high-performance applications requiring seamless scalability and high availability. DynamoDB is best suited for high-traffic web applications, gaming, and IoT applications. Its serverless nature means it can automatically scale up or down based on demand, ensuring consistent performance and cost-efficiency.
#### Cassandra
Cassandra is an open-source distributed NoSQL database known for its high availability and fault tolerance without compromising performance. It is ideal for large-scale applications and real-time big data analytics. Cassandra's distributed architecture makes it perfect for environments requiring continuous availability and the ability to handle large amounts of data across multiple nodes. It is commonly used in social media platforms, recommendation engines, and other data-intensive applications.
## Version Control Systems
![Version Control Systems](https://assets.roadmap.sh/guest/version-control-flow-bzojr.png)
Version control systems are essential for managing changes to source code over time, allowing multiple developers to collaborate effectively and maintain a history of changes.
### Git
When it comes to picking the right version control tool, Git is the most widely used one. It provides a powerful, flexible, and distributed model for tracking changes. Git’s architecture supports nonlinear development, allowing multiple branches to be created, merged, and managed independently. This makes Git essential for code collaboration and version tracking, making it a foundational tool for any developer.
Let’s go through some of the key benefits that make Git one of the leading backend technologies in web development.
#### Distributed Version Control
Unlike centralized version control systems (CVCS) where a single central repository holds the entire project history, Git allows each developer to have a complete copy of the repository, including its history. This decentralized approach enhances collaboration and ensures that work can continue even if the central server is down.
#### Branching and Merging
**Branching**: Git’s lightweight branching model allows developers to create, delete, and switch between branches effortlessly. This facilitates isolated development of features, bug fixes, or experiments without impacting the main codebase.
**Merging**: Git provides powerful merging capabilities to integrate changes from different branches. Tools like merge commits and rebasing help manage and resolve conflicts, ensuring a smooth integration process.
#### Performance
Git is designed to handle everything from small to very large projects with speed and efficiency. Its performance for both local operations (like committing and branching) and remote operations (like fetching and pushing changes) is optimized, making it suitable for high-performance needs.
#### Commit History and Tracking
Commit Granularity: Git encourages frequent commits, each with a descriptive message, making it easier to track changes, understand the project history, and identify when and why a change was made.
**History Viewing**: Commands like git log, git blame, and git bisect allow developers to explore the project’s history, pinpoint the introduction of bugs, and understand the evolution of the codebase.
#### Collaboration
While strictly not part of Git’s feature set, these functionalities enhance the basic set of features provided by the version control system.
**Pull Requests**: Platforms like GitHub, GitLab, and Bitbucket build on Git’s capabilities, offering features like pull requests to facilitate code reviews and discussions before integrating changes into the main branch.
**Code Reviews**: Integrating with continuous integration (CI) systems, Git platforms enable automated testing and code quality checks, ensuring that changes meet project standards before merging.
#### Staging Area
Git’s staging area (or index) provides an intermediate area where changes can be formatted and reviewed before committing. This allows for more granular control over what changes are included in a commit.
### GitHub
GitHub is a web-based platform that leverages Git for version control. It provides an extensive list of collaborative features, including (as already mentioned) pull requests, code reviews, and project management tools.
#### Key Features and Benefits
**Pull Requests and Code Reviews**: Facilitate discussions around proposed changes before integrating them into the main codebase. Developers can review code, leave comments, and suggest improvements. Built-in tools for reviewing code changes ensure collaborations are following coding standards and catch potential issues early.
**Project Management**: GitHub Issues allow tracking of bugs, enhancements, and tasks. Milestones help in organizing issues into targeted releases or sprints. Kanban-style boards provide a visual way to manage tasks, track progress, and organize workflows.
**Continuous Integration and Deployment**: Automate workflows for CI/CD, testing, deployment, and more. GitHub Actions supports custom scripts and pre-built actions to streamline DevOps processes.
**Community and Collaboration**: Developers can host static websites directly from a GitHub repository with Github Pages, they’re ideal for project documentation or personal websites. Integrated wikis can be used for detailed project documentation. And through forking, starring, and following repositories the platform encourages collaboration and knowledge sharing.
GitHub’s extensive features and strong community support make it the de facto choice for many companies and developers, both for open-source and private projects.
### GitLab
GitLab is a web-based platform for version control using Git, known for its robust CI/CD pipeline integration. It offers a comprehensive set of tools for the entire DevOps lifecycle, making it suitable for continuous integration, deployment, and monitoring.
#### Key Features and Benefits
**Integrated CI/CD**: Built-in continuous integration and continuous deployment pipelines allow backend developers to automate building, testing, and deploying code changes. With Gitlabs they can even automatically configure CI/CD pipelines, deploy applications, and monitor performance, all through the same platform.
**Security and Compliance**: Gitlabs provides key security capabilities for backend development: built-in static and dynamic application security testing (SAST/DAST).
**Collaboration and Communication**: Instead of Pull Requests like Github, Gitlabs provides the concept of “Merge Requests”: a simplified code review process with inline comments and suggestions.
GitLab’s all-in-one platform makes it an excellent choice for teams looking to streamline their DevOps processes and improve collaboration and productivity.
### Bitbucket
Bitbucket is a Git-based source code repository hosting service that provides both commercial plans and free accounts for small teams. It integrates seamlessly with Atlassian products like Jira and Trello, making it a great choice for teams already using these tools.
**Repository Hosting**: Bitbucket supports both Git and Mercurial version control systems. And it offers unlimited private repositories for teams.
**Integration with Atlassian Products**: Seamlessly integrates with Jira for issue tracking and project management. It can create branches from Jira issues and view development progress which is a fantastic integration for big teams using both tools. If, on the other hand, you’re using Trello, it can connect to Trello’s boards for visual task management and tracking.
**Continuous Integration and Deployment**: Integrated CI/CD service for automating builds, tests, and deployments. It can be configured with a YAML file for custom workflows.
**Security and Permissions**: Control who accesses specific branches to enforce workflows and protect critical branches. You can even enhance security with two-factor authentication.
Bitbucket’s integration with Atlassian’s suite of products, along with its robust CI/CD capabilities, make it an attractive option for teams seeking a tightly integrated development and project management environment.
## Containerization and Orchestration
![Containerization and Orchestration](https://assets.roadmap.sh/guest/containers-and-orchestrators-jb6xj.png)
While backend developers aren’t always directly involved in the deployment process, understanding the basics of containerization and orchestration can help them work and interact with the team in charge of devops (who usually set up these CI/CD pipelines).
While this is not an exhaustive list of backend technologies, the two main ones to learn about are:
### Docker
Docker is a platform for developing, shipping, and running applications in containers. Containers package software and its dependencies, ensuring it runs consistently across different environments. Docker simplifies application deployment and testing, making it ideal for microservices architectures and continuous integration/continuous deployment (CI/CD) pipelines.
### Kubernetes
Kubernetes is an open-source system for automating the deployment, scaling, and management of containerized applications. It orchestrates containers across clusters of machines, providing high availability, scalability, and efficient resource utilization. Kubernetes is perfect for complex, large-scale applications requiring robust infrastructure management and automated scaling.
## Cloud Platforms
![Cloud Platforms](https://assets.roadmap.sh/guest/cloud-providers-ownec.png)
Cloud platforms provide a range of services and infrastructure that allow developers to deploy, manage, and scale applications without maintaining physical servers. Mind you, the “cloud” is nothing else than someone else’s servers that you don’t have to manage.
These platforms all offer very similar types of managed services (each with its own flavor) that allow you to set up powerful and scalable infrastructures with a few clicks.
### Amazon Web Services (AWS)
Amazon Web Services (AWS) is a very complete cloud computing platform offered by Amazon. It provides a broad range of services, including computing power, storage solutions, and databases, catering to various needs and applications.
#### Key Characteristics of AWS
**Scalability**: AWS provides scalable solutions that allow businesses to easily adjust resources based on demand.
Global Reach: With data centers located worldwide, AWS offers high availability and low latency for global applications.
**Diverse Service Offerings**: AWS offers a wide range of services, including EC2 for computing, S3 for storage, and RDS for databases.
**Security and Compliance**: AWS provides robust security features and complies with numerous industry standards and regulations.
**Cost Management**: Flexible pricing models and cost management tools help businesses optimize their cloud spending.
### Google Cloud Platform (GCP)
Google Cloud Platform (GCP) is a suite of cloud computing services provided by Google. Like AWS and Microsoft Azure, GCP offers a variety of services, including computing power, storage, machine learning, and data analytics.
#### Key Characteristics of GCP
**AI and Machine Learning**: GCP excels in providing advanced AI and machine learning tools, leveraging Google's expertise.
**Big Data and Analytics**: GCP offers powerful analytics tools, including BigQuery, for handling large-scale data processing.
**Networking**: GCP provides a robust and secure global network infrastructure.
**Integration with Google Services**: Seamless integration with Google Workspace and other Google services enhances productivity and collaboration.
**Open Source Support**: GCP supports various open-source technologies, promoting flexibility and innovation.
### Microsoft Azure
Microsoft Azure is a cloud computing service created by Microsoft, offering a wide range of cloud services, including those for computing, analytics, storage, and networking.
#### Key Characteristics of Microsoft Azure
**Integration with Microsoft Products**: Azure offers seamless integration with popular Microsoft software and services.
**Hybrid Cloud Capabilities**: Azure supports hybrid cloud environments, enabling smooth integration between on-premises and cloud resources.
**Comprehensive Service Range**: Azure provides a broad spectrum of services, including Azure Virtual Machines, Azure SQL Database, and Azure DevOps.
**Enterprise-Grade Security**: Azure emphasizes security with advanced features and compliance with industry standards.
**Developer and IT Pro Tools**: Azure offers a wide range of tools for developers and IT professionals, including Visual Studio and Azure DevOps.
At a high level, all of these providers are very similar to each other, to the point where backend developers experienced in one of them, can extrapolate their understanding of the environment into others with minimum ramp-up time.
## APIs and Web Services
![APIs and Web Services](https://assets.roadmap.sh/guest/rest-vs-graphql-vs-grpc-tp40c.png)
APIs (or Application Programming Interfaces) and web services are another mandatory incorporation to the list of top backend technologies any developer should keep in mind. They enable communication between different software systems.
The three most common types of APIs right now, are REST, GraphQL and gPRC, let’s take a closer look at each one of them.
### REST
REST is a standard architecture for web services, known for its simplicity and scalability. It operates on stateless principles and uses standard HTTP methods (GET, POST, PUT, DELETE) to perform CRUD (Create, Read, Update, Delete) operations. RESTful APIs are typically used to access and manipulate web resources using URLs.
REST is ideal for web applications and services due to its ease of implementation and broad compatibility with various web technologies. It is commonly used for developing APIs for web and mobile applications, providing endpoints that clients can interact with to perform various operations. RESTful APIs are also ideal for integrating with third-party services, enabling data exchange and interaction between different systems.
#### Key Characteristics of REST
**Statelessness**: Each request from a client contains all the information needed to process the request, without relying on stored context on the server.
**Uniform Interface**: REST APIs follow standard conventions, making them easy to understand and use. This includes using standard HTTP methods and status codes.
**Client-Server Architecture**: Separates the client and server concerns, improving scalability and flexibility. Clients handle the user interface and user experience, while servers handle data storage and business logic.
**Cacheability**: Responses from REST APIs can be cached to improve performance, reducing the need for repeated requests.
**Layered System**: REST allows for a layered system architecture, enabling intermediaries like load balancers and proxy servers to enhance security, performance, and scalability.
If you’d like to know more about REST, you can read the full definition directly from [its source here](https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm).
### GraphQL
GraphQL is a query language for APIs and a runtime for executing those queries by using a type system you define for your data. Unlike REST, where multiple endpoints return fixed data structures, GraphQL allows clients to request exactly the data they need. This flexibility reduces the amount of data transferred over the network and can significantly improve performance.
GraphQL is ideal for applications with complex and dynamic data requirements.
#### Key Characteristics of GraphQL
**Declarative Data Fetching**: Clients specify the structure of the response, ensuring they receive only the data they need.
**Strongly Typed Schema**: The API schema is strongly typed, providing clear and detailed documentation of available data and operations.
**Single Endpoint**: Unlike REST, GraphQL uses a single endpoint to serve all requests, simplifying the API architecture.
**Real-time Data**: Supports real-time updates through subscriptions, enabling clients to receive live data changes.
### gRPC
gRPC is a high-performance, open-source RPC (Remote Procedure Call) framework developed by Google. gRPC is designed for low-latency, high-throughput communication, making it suitable for microservices architectures and real-time communication systems.
gRPC is ideal for applications that require efficient, reliable, and bi-directional communication.
#### Key Characteristics of gRPC
**Protocol Buffers**: Uses Protocol Buffers for compact, efficient, and platform-neutral serialization of structured data.
**HTTP/2**: Utilizes HTTP/2 for multiplexing, flow control, header compression, and efficient binary transport.
**Bi-directional Streaming**: Supports multiple types of streaming, including client-side, server-side, and bi-directional streaming.
**Cross-Language Compatibility**: Provides support for multiple backend programming languages, enabling interoperability between different systems.
## Caching Systems
![Caching Systems](https://assets.roadmap.sh/guest/working-cache-11kis.png)
Caching systems store copies of frequently accessed data to reduce latency and improve application performance. They are essential for speeding up data retrieval and reducing the load on primary data stores.
Implementing a successful caching strategy is not trivial, and one key aspect of it is the backend technology used for the implementation. While there might be multiple options out there, the industry currently recognizes only one de facto choice: Redis.
### Redis: a fast in-memory storage solution
Redis is an in-memory data structure store that can function as a database, cache, and message broker. It supports various data structures such as strings, hashes, lists, sets, sorted sets, bitmaps, hyperloglogs, and with the right add-ons, even vectors. Redis uses a key-value storage mechanism, which makes it simple yet powerful for a wide range of use cases.
Let’s quickly review some of the characteristics of Redis that make it such a fantastic option.
#### High Availability and Scalability
- **Redis Sentinel**: Provides high availability and monitoring, automatically promoting a slave to master in case of failure, ensuring minimal downtime.
- **Redis Cluster**: Supports automatic sharding, allowing Redis to scale horizontally. It partitions data across multiple nodes, ensuring that the system can handle large datasets and high throughput.
#### Performance and Use Cases
Redis's in-memory architecture gives it unmatched I/O speed, making it ideal for real-time applications such as:
- **Gaming**: Managing leaderboards, player sessions, and real-time statistics.
- **Chat Applications**: Storing messages, user presence information, and delivering real-time notifications.
- **Analytics**: Real-time data processing and analytics, where rapid data access and manipulation are crucial.
- **Caching**: Reducing database load by caching frequently accessed data, improving application response times.
#### Persistence and Durability
- **RDB (Redis Database)**: Creates snapshots of the dataset at specified intervals, allowing data to be restored from the last snapshot.
- **AOF (Append Only File)**: Logs every write operation received by the server, providing a more durable solution that can replay the log to reconstruct the dataset.
- **Hybrid Approach**: Combining RDB and AOF to leverage the benefits of both methods, balancing performance and data durability.
#### Advanced Features
On top of all of that, Redis even provides some very powerful out-of-the-box features:
- **Lua Scripting**: Supports server-side scripting with Lua, enabling complex operations to be executed atomically.
- **Pub/Sub Messaging**: Allows for message broadcasting to multiple clients, supporting real-time messaging and notifications. You can create whole event-based architectures around Redis.
- **Modules**: Extend Redis functionality with custom modules, such as RedisGraph for graph database capabilities and RedisJSON for JSON document storage.
Redis's robust feature set, combined with its high performance and flexibility, makes it a versatile tool for developers looking to build scalable and responsive applications.
## Message Brokers and Streaming Platforms
![Message Brokers and Streaming Platforms](https://assets.roadmap.sh/guest/message-queue-yoq3q.png)
Message brokers and streaming platforms facilitate communication between different parts of a system, enabling efficient data exchange and processing. They are crucial for building scalable and resilient applications and they are the core of reactive architectures (also known as event-based architectures).
### RabbitMQ
RabbitMQ is an open-source message broker that implements the Advanced Message Queuing Protocol (AMQP). It supports multiple messaging protocols and can be deployed in distributed and federated configurations. RabbitMQ is ideal for use cases that require reliable message delivery, complex routing, and interoperability with other messaging systems. It is commonly used in financial systems, order processing, and other applications that need robust messaging capabilities.
### Apache Kafka
Apache Kafka is a distributed streaming platform designed for high-throughput, low-latency data processing. It excels at handling real-time data feeds, making it suitable for applications that require continuous data integration and processing. Kafka’s publish-subscribe messaging system is fault-tolerant and scalable, making it ideal for big data applications, real-time analytics, event sourcing, and log aggregation. Its ability to store streams of records in a fault-tolerant manner also makes it useful for building event-driven architectures and microservices.
As backend developers, understanding how to take advantage of these message queues is critical to the development of scalable and resilient platforms. It is definitely a must-have skill and you need to master it.
## Authentication and Authorization
![Authentication and Authorization](https://assets.roadmap.sh/guest/authentication-vs-authorization-vl6lg.png)
Authentication and authorization technologies are essential for securing applications, ensuring that users are who they claim to be and have the appropriate permissions to access resources.
This space is filled with solutions and methodologies, so it’s not easy to pick one option here, however, these two are very common solutions used to implement both, authZ (authorization) and authN (authentication).
### OAuth
OAuth is an open standard for access delegation commonly used to grant websites or applications limited access to a user’s information without exposing their passwords. It is widely used in single sign-on (SSO) systems, enabling users to log in to multiple applications with a single set of credentials. OAuth is ideal for third-party applications that need access to user data, such as social media integrations and API access management.
### JWT (JSON Web Tokens)
JWT is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object, which is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure. JWTs are commonly used for authentication and authorization in web applications, providing a secure way to transmit information between parties. They are particularly useful in stateless authentication systems, where user state is not stored on the server (like when dealing with RESTful APIs).
## CI/CD Pipelines
![CI/CD Pipelines](https://assets.roadmap.sh/guest/continous-development-vs-continuous-integration-rg7t9.png)
CI/CD (Continuous Integration/Continuous Deployment) pipelines automate the process of code integration, testing, and deployment, enabling faster and more reliable software delivery. This is one of the key areas backend developers need to understand to avoid creating code that simply gets in the way of the deployment process.
### GitHub Actions
GitHub Actions is an integrated CI/CD service within GitHub repositories, allowing developers to automate build, test, and deployment workflows. It supports a wide range of actions and integrations, making it highly customizable and versatile for various development workflows.
### CircleCI
CircleCI is a continuous integration and delivery platform that automates the building, testing, and deployment of applications. It supports multiple backend languages and integrates with various version control systems, making it a popular choice for diverse development environments. CircleCI is known for its speed and ease of setup, providing robust tools for optimizing and monitoring CI/CD pipelines.
### GitLab CI/CD
GitLab CI/CD is an integrated part of the GitLab platform (similar to how GitHub actions are a part of GitHub), offering continuous integration, delivery, and deployment features within the GitLab ecosystem. It allows developers to manage their entire DevOps lifecycle in a single application, from planning and coding to monitoring and security. GitLab CI/CD is particularly useful for teams seeking a seamless and comprehensive CI/CD solution.
### Jenkins
If instead of a SaaS, you’re looking for a solution that you can potentially self-host, then you might want to look into Jenkins. Jenkins is an open-source automation server that provides hundreds of plugins to support building, deploying, and automating your software development process. It is highly extensible and can be integrated with a wide array of tools and technologies. Jenkins is ideal for complex, large-scale projects requiring a customizable and powerful CI/CD environment.
## Monitoring and Logging
![Monitoring and Logging](https://assets.roadmap.sh/guest/server-monitoring-vk5nb.png)
Understanding how the systems that you develop behave and perform on a daily basis is crucial to launching a successful product. Here’s where monitoring and logging come into play. Monitoring and logging are crucial pieces of backend technology used for maintaining the health, performance, and security of applications. These tools help detect issues, analyze performance, and ensure system reliability.
### ELK Stack (Elasticsearch, Logstash, Kibana)
The ELK Stack is a set of tools for searching, analyzing, and visualizing log data in real time. Elasticsearch is a search and analytics engine, Logstash is a server-side data processing pipeline, and Kibana is a visualization tool. Together, they provide a powerful platform for centralized logging and monitoring, making them ideal for applications requiring detailed log analysis and real-time insights.
### Grafana
Grafana is an open-source platform for monitoring and observability that integrates with various data sources. It provides powerful visualizations, dashboards, and alerting capabilities, making it a popular choice for monitoring infrastructure and application performance. Grafana is particularly useful for teams needing a flexible and customizable monitoring solution.
### Loki
Loki is a log aggregation system designed to work with Grafana. It is optimized for cost-effective and scalable logging, making it suitable for applications with high log volumes. Loki simplifies log management by allowing developers to query logs using the same language as Grafana, providing seamless integration for comprehensive observability.
### Prometheus
Prometheus is an open-source monitoring and alerting toolkit designed for reliability and scalability. It collects and stores metrics as time series data, providing powerful querying language and alerting capabilities. Prometheus is ideal for monitoring applications and infrastructure, particularly in cloud-native and microservices environments, where dynamic and ephemeral resources are common.
In the end, you might want to go with one or several of these options, the point is that you, as a developer, should be aware of them and what type of value they add to the project.
## Conclusion
As backend developers, focusing on a backend programming language and a backend framework is not going to be enough. The backend ecosystem is very rich, and there are many areas that are either directly or indirectly related to the daily tasks that a backend dev needs to work on.
This is why you need to stay up-to-date and look at the trends that develop within each area to make sure you’re still working with and focusing on the right solutions.
If you'd like more details on the type of backend development technologies you should be focusing on to excel at your role as a backend developer, check out our [Backend Developer roadmap](https://roadmap.sh/backend).

@ -132,7 +132,7 @@ As a DevOps professional, you can decide to go for any of these following DevOps
- Automation expert
- General DevOps engineer
- System engineer
- DevOps erchitect
- DevOps architect
- DevOps release manager
- DevSecOps engineer
- DevOps test engineer

@ -0,0 +1,53 @@
---
title: 'Basic HTML Website'
description: 'Create simple HTML only website with multiple pages.'
isNew: false
sort: 1
difficulty: 'beginner'
nature: 'HTML'
skills:
- 'HTML'
- 'Layouts'
- 'semantic HTML'
seo:
title: 'Basic HTML Website Project'
description: 'Create a simple HTML only website with multiple pages.'
keywords:
- 'basic html'
- 'html project idea'
roadmapIds:
- 'frontend'
---
> Goal of this project is to teach you how to structure a website using HTML i.e. different sections of a website like header, footer, navigation, main content, sidebars etc. Do not style the website, only focus on the structure. Styling will be done in separate projects.
In this project, you are required to create a simple HTML only website with multiple pages. The website should have following pages:
- Homepage
- Projects
- Articles
- Contact
The website should have a navigation bar that should be present on all pages and link to all the pages.
You are not required to style the website, you are only required to create the structure of the website using HTML. Goals of this project are:
- Learn how to create multiple pages in a website.
- Structure a website using HTML in a semantic way.
- Structure in a way that you can easily add styles later.
- Add SEO meta tags to the website.
You can use the following mockup example to create the structure of the website (remember, you are not required to style the website, only focus on the structure that you can style later):
![Basic HTML Website](https://assets.roadmap.sh/guest/portfolio-design-83lku.png)
Again, make sure that your submission includes the following:
- Semantically correct HTML structure.
- Multiple pages with a navigation bar.
- SEO meta tags in the head of each page.
- Contact page should have a form with fields like name, email, message etc.
<hr />
After completing this project, you will have a good understanding of how to structure a website using HTML, basic SEO meta tags, HTML tags, forms etc. You can now move on to the next project where you will learn how to style this website using CSS.

@ -0,0 +1,8 @@
# Animations
`Animations` can add visual cues that notify users about what's going on in your app. They are especially useful when the UI changes state, such as when new content loads or new actions become available. Animations also add a polished look to your app, which gives it a higher quality look and feel.
Visit the following resources to learn more:
- [@official@Google developers: Animations](https://developer.android.com/develop/ui/views/animations/overview)
- [@video@Google developers: Animations](https://www.youtube.com/watch?v=N_x7SV3I3P0)

@ -0,0 +1,8 @@
# ConstraintLayout
Lets you create large, complex layouts with a flat view hierarchy—no nested view groups. It's similar to `RelativeLayout` in that all views are laid out according to relationships between sibling views and the parent layout, but it's more flexible than RelativeLayout and easier to use. Its available on xml and jetpack compose.
Visit the following resources to learn more:
- [@official@Android developers: ConstraintLayout in xml](https://developer.android.com/develop/ui/views/layout/constraint-layout)
- [@official@Android developers: ContraintLayout in compose](https://developer.android.com/develop/ui/compose/layouts/constraintlayout)

@ -0,0 +1,8 @@
# Drawer
The **Navigation Drawer** in Android is a sliding menu from the left that simplifies navigation between important app links. It opens by sliding or via an icon in the `ActionBar`. It’s an overlay panel that replaces a screen dedicated to displaying options.
Visit the following resources to learn more:
- [@official@Android developers: DrawerLayout](https://developer.android.com/reference/androidx/drawerlayout/widget/DrawerLayout)
- [@article@Navigate Drawer Tutorial](https://www.digitalocean.com/community/tutorials/android-navigation-drawer-example-tutorial)

@ -0,0 +1,9 @@
# ListView
Displays a vertically-scrollable collection of views, where each view is positioned immediatelybelow the previous view in the list.
For a more modern, flexible, and performant approach to displaying lists, use `RecyclerView`.
Visit the following resources to learn more:
- [@official@Android developers: ListView](https://developer.android.com/reference/android/widget/ListView)

@ -2579,39 +2579,6 @@
"focusable": true,
"resizing": false
},
{
"id": "Wc2ybRw43uamEtno0FpDv",
"type": "subtopic",
"position": {
"x": -99.73327447982547,
"y": 957.2304293708296
},
"selected": false,
"data": {
"label": "Template Ref Vars",
"style": {
"fontSize": 17,
"justifyContent": "flex-start",
"textAlign": "center"
},
"oldId": "nyDry6ZWyEUuTq4pw-lU3"
},
"zIndex": 999,
"width": 225,
"height": 49,
"style": {
"width": 225,
"height": 49
},
"positionAbsolute": {
"x": -99.73327447982547,
"y": 957.2304293708296
},
"dragging": false,
"resizing": false,
"selectable": true,
"focusable": true
},
{
"id": "VsU6713jeIjAOEZnF6gWx",
"type": "subtopic",

@ -1 +1,8 @@
# Build Environments
# Build Environments
You can define different named build configurations for your project, such as `development` and `production`, with different defaults. Each named configuration can have defaults for any of the options that apply to the various builder targets, such as `build`, `serve`, and `test`. The Angular CLI can replace files for each environment if you pass a `--configuration` flag with the named configuration when running a CLI command.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Build environments](https://angular.dev/tools/cli/environments#using-environment-specific-variables-in-your-app)
- [@article@Building an Angular application in various environments using Angular CLI and server](https://medium.com/yavar/building-an-angular-application-in-various-environments-using-angular-cli-and-server-18f94067154b)

@ -1 +1,8 @@
# @case
# @case
If no `@case` matches the `@switch` condition and there is no `@default` block, nothing is shown. Otherwise, the content inside the `@case` that matches the condition will be displayed.
Visit the following resources to learn more:
- [@official@Angular Official Docs - @switch](https://angular.dev/guide/templates/control-flow#switch-block---selection)
- [@article@Angular @switch: Complete Guide](https://blog.angular-university.io/angular-switch/)

@ -1 +1,9 @@
# CLI Builders
# CLI Builders
A number of Angular CLI commands run a complex process on your code, such as building, testing, or serving your application. The commands use an internal tool called `Architect` to run CLI builders, which invoke another tool (bundler, test runner, server) to accomplish the desired task. Custom builders can perform an entirely new task or to change which third-party tool is used by an existing command.
Visit the following resources to learn more:
- [@official@Angular Official Docs - CLI Builders](https://angular.dev/tools/cli/cli-builder)
- [@video@Angular Builders – Creating Custom Builder from Scratch](https://www.youtube.com/watch?v=QbDkDLnXAZE)
- [@opensource@Angular Builders](https://github.com/just-jeb/angular-builders)

@ -1 +1,9 @@
# Creating Libraries
# Creating Libraries
If you have developed features that are suitable for reuse, you can create your own libraries. These libraries can be used locally in your workspace, or you can publish them as npm packages to share with other projects or other Angular developers. Putting code into a separate library is more complex than simply putting everything in one application. It requires more of an investment in time and thought for managing, maintaining, and updating the library. This complexity can pay off when the library is being used in multiple applications.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Creating Libraries](https://angular.dev/tools/libraries/creating-libraries)
- [@official@Angular Official Docs - File Structure: Library project files](https://angular.dev/reference/configs/file-structure#library-project-files)
- [@opensource@NG Packagr](https://github.com/ng-packagr/ng-packagr)

@ -1 +1,10 @@
# Cross-site Request Forgery
# Cross-site Request Forgery
Cross-site request forgery, also known as one-click attack or session riding and abbreviated as CSRF or XSRF, is a type of malicious exploit of a website or web application where unauthorized commands are submitted from a user that the web application trusts. There are many ways in which a malicious website can transmit such commands; specially-crafted image tags, hidden forms, and JavaScript fetch or XMLHttpRequests, for example, can all work without the user's interaction or knowledge. Unlike cross-site scripting (XSS), which exploits the trust a user has for a particular site, CSRF exploits the trust that a site has in a user's browser. In a CSRF attack, an innocent end user is tricked by an attacker into submitting a web request that they did not intend. This may cause actions to be performed on the website that can include inadvertent client or server data leakage, change of session state, or manipulation of an end user's account. Angular provides built-in protection against CSRF attacks through the `HttpClientXsrfModule` module. This module automatically adds a token to outgoing requests and validates it on the server side.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Cross Site Request Forgery](https://angular.dev/best-practices/security#cross-site-request-forgery)
- [@official@HttpClientXsrfModule](https://angular.dev/api/common/http/HttpClientXsrfModule)
- [@video@Configure the CSRF Protection With Spring Security 6 and Angular](https://www.youtube.com/watch?v=tgjLsEmxcuY)
- [@video@Angular security - CSRF prevention using Double Submit Cookie](https://www.youtube.com/watch?v=lZfF4MOTeNM)

@ -1 +1,9 @@
# Cross-site Script Inclusion
# Cross-site Script Inclusion
Cross-site script inclusion, also known as JSON vulnerability, can allow an attacker's website to read data from a JSON API. The attack works on older browsers by overriding built-in JavaScript object constructors, and then including an API URL using a `<script>` tag. Angular's HttpClient library recognizes this convention and automatically strips the string ")]}',\n" from all responses before further parsing.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Cross Site Script Inclusion](https://angular.dev/best-practices/security#cross-site-script-inclusion-xssi)
- [@article@XSSI Cross Site Script Inclusion](https://book.hacktricks.xyz/pentesting-web/xssi-cross-site-script-inclusion)
- [@article@Testing for Cross Site Script Inclusion](https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/11-Client_Side_Testing/13-Testing_for_Cross_Site_Script_Inclusion)

@ -1 +1,10 @@
# Debugging Tests
# Debugging Tests
If your tests aren't working as you expect them to, you can inspect and debug them in the browser. Be sure to set breakpoints to track your application's execution.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Debugging tests](https://angular.dev/guide/testing/debugging)
- [@official@Angular Official Docs - Devtools](https://angular.dev/tools/devtools)
- [@video@Debug Like a Pro: Essential Breakpoint Techniques in Angular](https://www.youtube.com/watch?v=Be9Q1cchurQ)
- [@video@Debug Angular 17 Code in VS Code with Break Points and Extensions](https://www.youtube.com/watch?v=r50UXhT9hc0)

@ -1 +1,8 @@
# @default
# @default
The `@default` clause is used to render a template when none of the `@case` blocks matches the value of the `@switch` conditional. `@default` is optional and can be omitted.
Visit the following resources to learn more:
- [@official@Angular Official Docs - @switch](https://angular.dev/guide/templates/control-flow#switch-block---selection)
- [@article@Angular @switch: Complete Guide](https://blog.angular-university.io/angular-switch/)

@ -1 +1,14 @@
# Deployment
# Deployment
The Angular CLI command `ng deploy` executes the deploy CLI builder associated with your project. A number of third-party builders implement deployment capabilities to different platforms. You can add any of them to your project with `ng add`.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Deployment](https://angular.dev/tools/cli/deployment)
- [@official@Firebase Hosting](https://firebase.google.com/docs/hosting)
- [@official@Vercel: Angular Solutions](https://vercel.com/solutions/angular)
- [@official@Netlify](https://docs.netlify.com/frameworks/angular/)
- [@official@Cloudflare Pages](https://developers.cloudflare.com/pages/framework-guides/deploy-an-angular-site/#create-a-new-project-using-the-create-cloudflare-cli-c3)
- [@official@AWS Amplify](https://docs.amplify.aws/angular/)
- [@opensource@NGX AWS Deploy](https://github.com/Jefiozie/ngx-aws-deploy)
- [@opensource@Angular CLI GitHub Pages](https://github.com/angular-schule/angular-cli-ghpages)

@ -1 +1,11 @@
# Dynamic Components
# Dynamic Components
In addition to using a component directly in a template, you can also dynamically render components. There are two main ways to dynamically render a component: in a template with `NgComponentOutlet`, or in your TypeScript code with `ViewContainerRef`.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Programmatically rendering components](https://angular.dev/guide/components/programmatic-rendering)
- [@video@Dynamic Component in Angular (2024)](https://www.youtube.com/watch?v=ncbftt3NWVo)
- [@article@New Input Binding for NgComponentOutlet](https://medium.com/ngconf/new-input-binding-for-ngcomponentoutlet-cb18a86a739d)
- [@article@Render dynamic components in Angular using ViewContainerRef](https://dev.to/railsstudent/render-dynamic-components-in-angular-using-viewcontainerref-160h)
- [@video@Mastering ViewContainerRef for dynamic component loading in Angular17](https://www.youtube.com/watch?v=Ra4PITCt8m0)

@ -1 +1,8 @@
# @else if
# @else if
With the new control flow syntax, you gain `@else if` conditional blocks, something that is not possible with `@ngIf`. This addition makes the control flow syntax close to what we would write with just plain JavaScript.
Visit the following resources to learn more:
- [@official@Angular Official Docs - @if](https://angular.dev/api/core/@if)
- [@article@Angular @if: Complete Guide](https://blog.angular-university.io/angular-if/)

@ -1 +1,11 @@
# End-to-End Testing
# End-to-End Testing
End-to-end or (E2E) testing is a form of testing used to assert your entire application works as expected from start to finish or "end-to-end". E2E testing differs from unit testing in that it is completely decoupled from the underlying implementation details of your code. It is typically used to validate an application in a way that mimics the way a user would interact with it. The `ng e2e` command will first check your project for the "e2e" target. If it can't locate it, the CLI will then prompt you which e2e package you would like to use and walk you through the setup.
Visit the following resources to learn more:
- [@official@Angular Official Docs - End to End Testing](https://angular.dev/tools/cli/end-to-end)
- [@official@Cypress Official Docs - Your First Test with Cypress](https://docs.cypress.io/guides/end-to-end-testing/writing-your-first-end-to-end-test)
- [@official@Nightwatch Official Docs - Writing Tests: Introduction](https://nightwatchjs.org/guide/writing-tests/introduction.html)
- [@official@Webdriver Official Docs - Getting Started](https://webdriver.io/docs/gettingstarted/)
- [@official@Puppeteer Angular Schematic](https://pptr.dev/guides/ng-schematics/#getting-started)

@ -1 +1,8 @@
# HTTP Vulnerabilities
# HTTP Vulnerabilities
Angular has built-in support to help prevent two common HTTP vulnerabilities, cross-site request forgery (CSRF or XSRF) and cross-site script inclusion (XSSI). Both of these must be mitigated primarily on the server side, but Angular provides helpers to make integration on the client side easier.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Security](https://angular.dev/best-practices/security)
- [@article@Angular | HackTricks](https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/angular)

@ -1 +1,11 @@
# HttpClient CSRF
# HttpClient CSRF
HttpClient includes a built-in mechanism to prevent XSRF attacks. When making HTTP requests, an interceptor reads a token from a cookie (default name: XSRF-TOKEN) and sets it as an HTTP header (X-XSRF-TOKEN). Since only code running on your domain can read this cookie, the backend can verify that the HTTP request originates from your client application and not from an attacker.
However, HttpClient only handles the client-side aspect of XSRF protection. Your backend service must be configured to set the cookie for your page and verify that the header is present on all relevant requests. Without this backend configuration, Angular’s default XSRF protection will not be effective.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Security](https://angular.dev/best-practices/security#httpclient-xsrf-csrf-security)
- [@article@How can you protect Angular Web app from cross site request forgery?](https://www.linkedin.com/advice/3/how-can-you-protect-angular-web-app-from-cross-site-pyqwc)
- [@article@Cross Site Request Forgery: XSRF protection in Angular](https://borstch.com/blog/development/cross-site-request-forgery-xsrf-protection-in-angular)

@ -1 +1,10 @@
# Hydration
# Hydration
Hydration is the process that restores the server-side rendered application on the client. This includes things like reusing the server rendered DOM structures, persisting the application state, transferring application data that was retrieved already by the server, and other processes. Hydration can be enabled for server-side rendered (SSR) applications only. You can enable hydration manually by visiting your main application component or module and importing `provideClientHydration` from `@angular/platform-browser`.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Hydration](https://angular.dev/guide/hydration)
- [@official@Angular Official Docs - provideClientHydration](https://angular.dev/api/platform-browser/provideClientHydration)
- [@article@Angular Hydration](https://www.bacancytechnology.com/blog/angular-hydration)
- [@video@Angular SSR Deep Dive (With Client HYDRATION)](https://www.youtube.com/watch?v=U1MP4uCuUVI)

@ -1 +1,10 @@
# Local Setup
# Local Setup
To install Angular CLI on your local system, you need to install `Node.js`. Angular requires an active LTS or maintenance LTS version of Node. Angular CLI uses Node and its associated package manager, npm, to install and run JavaScript tools outside the browser. Once you have Node installed, you can run `npm install -g @angular/cli` to install the Angular CLI.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Local set-up](https://angular.dev/tools/cli/setup-local)
- [@official@Angular Official Docs - Version compatibility guide](https://angular.dev/reference/versions)
- [@video@How To Install Angular CLI In Windows 10 | In Under 2 Minutes!](https://www.youtube.com/watch?v=vjgACKkPENg)
- [@video@How to Install Multiple Versions of Angular in Your Development Environment](https://www.youtube.com/watch?v=LYNG3kcKRQ8)

@ -1 +1,12 @@
# Multiple Locales
# Multiple Locales
To deploy an Angular application with multiple locales, follow these steps:
1. Place different versions of your app in locale-specific directories
2. Use the HTML `<base>` tag with the `href` attribute to set the base URL for relative links.
3. Deploy each language version in a different subdirectory. Redirect users to their preferred language based on the `Accept-Language` HTTP header.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Deploy Multiple Locales](https://angular.dev/guide/i18n/deploy)
- [@video@How Make Multi-Language Angular Websites - Full Guidance On Angular Localization](https://www.youtube.com/watch?v=vSwYuyH4kMA)

@ -2,5 +2,8 @@
The Angular Router raises events when it navigates from one route to another route. It raises several events such as `NavigationStart`, `NavigationEnd`, `NavigationCancel`, `NavigationError`, `ResolveStart`, etc. You can listen to these events and find out when the state of the route changes. Some of the useful events are route change start (NavigationStart) and route change end (NavigationEnd).
Visit the following resources to learn more:
- [@official@Router reference - Router events](https://angular.dev/guide/routing/router-reference#router-events)
- [@official@Router event - API](https://angular.dev/api/router/RouterEvent)
- [@article@Router events in Angular](https://medium.com/@gurunadhpukkalla/router-events-in-angular-3112a3968660)

@ -3,3 +3,10 @@
Reactive Extensions for JavaScript, or RxJS, is a reactive library used to implement reactive programming to deal with async implementation, callbacks, and event-based programs.
The reactive paradigm can be used in many different languages through the use of reactive libraries. These libraries are downloaded APIs that provide functionalities for reactive tools like observers and operators. It can be used in your browser or with Node.js.
Visit the following resources to learn more:
- [@official@RxJS Docs](https://rxjs.dev/guide/overview)
- [@article@Learn RxJS](https://www.learnrxjs.io/)
- [@article@RxJs and Observables for Beginners: A Beginner Friendly Introduction](https://blog.angular-university.io/functional-reactive-programming-for-angular-2-developers-rxjs-and-observables/)
- [@video@Beginner's RxJS Tutorial: Dive Deep with RxJS Crash Course!](https://www.youtube.com/watch?v=yJdh1_FbtjU)

@ -1,9 +1,11 @@
# Testing services
# Testing services with dependencies
In an Angular application, Services are responsible for fetching, storing and processing data. Services are singletons, meaning there is only one instance of a Service during runtime. They are fit for central data storage, HTTP and WebSocket communication as well as data validation.
When you add a dependency to your service, you must also include it in your tests. For isolated tests, pass an instance of the injectable dependency class into the service’s constructor. Using the `inject` function can add complexity. Injecting the real service is often impractical because dependent services can be difficult to create and control. Instead, mock the dependency, use a dummy value, or create a spy on the relevant service method. By using the TestBed testing utility, you can let Angular’s dependency injection handle service creation and manage constructor argument order.
Visit the following resources to learn more:
- [@official@Angular Website](https://angular.dev/guide/testing/services)
- [@article@Testing-Angular.com](https://testing-angular.com/testing-services/)
- [@feed@Explore top posts about Testing](https://app.daily.dev/tags/testing?ref=roadmapsh)
- [@video@Testing the Service which has another service injected through Dependency Injection](https://www.youtube.com/watch?v=ACb8wqwgOV4)
- [@video@Testing Services which has HttpClient as dependency by using Jasmine Spy](https://www.youtube.com/watch?v=15othucRXcI)
- [@video@Angular Unit Tests with the inject() function](https://www.youtube.com/watch?v=Tvsa4OMUGXs)

@ -1 +1,8 @@
# Slow Computations
# Slow Computations
On every change detection cycle, Angular synchronously evaluates all template expressions in components based on their detection strategy and executes the `ngDoCheck`, `ngAfterContentChecked`, `ngAfterViewChecked`, and `ngOnChanges` lifecycle hooks. To remove slow computations, you can optimize algorithms, cache data with pure pipes or memoization, and limit lifecycle hook usage.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Slow Computations](https://angular.dev/best-practices/slow-computations)
- [@article@Angular Performance Optimization](https://davembush.medium.com/angular-performance-optimization-5ec630d2b8f1)

@ -1,3 +1,9 @@
# Angular SSG
SSG (Static Site Generator), helps in building the HTML full website, during the process of building and serving that HTML Page. This method helps to generate the HTML website on the client side before its being served on the server side. Therefore, whenever a user requests a HTML Page, firstly HTML page will be rendered and secondly, the angular app will be rendered. The SSG can be used only if your website is static (or) it's content doesn't changes frequently.
SSG (Static Site Generator) helps in building the HTML full website during the process of building and serving that HTML page. This method helps to generate the HTML website on the client side before it's served on the server side. Therefore, whenever a user requests a HTML page, the HTML page will be rendered, and secondly, the Angular app will be rendered. The SSG can be used only if your website is static or its content doesn't change frequently.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Prerendering (SSG)](https://angular.dev/guide/prerendering)
- [@video@Angular 16 Pre Rendering Static Pages - Static Site Generation SSG](https://www.youtube.com/watch?v=vmOWJvm3apA)
- [@podcast@Angular Air with Alyssa Nicoll - SSR, SSG, ISR, & SOS](https://www.youtube.com/watch?v=b0pUU7RJbBQ)

@ -1 +1,8 @@
# @switch
# @switch
The `@switch` blocks displays content selected by one of the cases matching against the conditional expression. The value of the conditional expression is compared to the case expression using the `===` operator. `@switch` does not have fallthrough, so you do not need an equivalent to a break or return statement.
Visit the following resources to learn more:
- [@official@Angular Official Docs - @switch](https://angular.dev/guide/templates/control-flow#switch-block---selection)
- [@article@Angular @switch: Complete Guide](https://blog.angular-university.io/angular-switch/)

@ -1 +1,9 @@
# Template Syntax
# Template Syntax
In Angular, a *template* is a chunk of HTML. Use special syntax within a template to build on many of Angular's features. Extend the HTML vocabulary of your applications with special Angular syntax in your templates. For example, Angular helps you get and set DOM (Document Object Model) values dynamically with features such as built-in template functions, variables, event listening, and data binding.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Template Syntax](https://angular.dev/guide/templates)
- [@article@An Introduction to Angular Template Syntax](https://angularstart.com/modules/basic-angular-concepts/3/)
- [@video@Craft Dynamic Templates with Angular's Template Syntax](https://www.youtube.com/watch?v=uSnUTcf8adI)

@ -1 +1,9 @@
# Testing Requests
# Testing Requests
As for any external dependency, you must mock the HTTP backend so your tests can simulate interaction with a remote server. The `@angular/common/http/testing` library provides tools to capture requests made by the application, make assertions about them, and mock the responses to emulate your backend's behavior.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Testing Requests](https://angular.dev/guide/http/testing)
- [@video@Import Http Client Testing Module and make Test call with the HttpClient](https://www.youtube.com/watch?v=Sgy_RRXC9As)
- [@video@HTTP | Angular Unit Testing Made Easy: Comprehensive Guide to HTTP Testing](https://www.youtube.com/watch?v=7rlwryYhGzs)

@ -1 +1,8 @@
# Testing Services
# Testing Services
To ensure your services function as expected, you can write dedicated tests for them. Services are typically the easiest files to unit test. You can instantiate the service within a `beforeEach` block, invoke its methods, and assert the results.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Testing Services](https://angular.dev/guide/testing/services)
- [@video@Step by Step implementation of the Calculator Service with Jasmine Specification](https://www.youtube.com/watch?v=yoJDYEq8vSs)

@ -1 +1,10 @@
# Zone Pollution
# Zone Pollution
`Zone.js` is a signaling mechanism that Angular uses to detect when an application state might have changed. In some cases, scheduled tasks or microtasks don’t make any changes in the data model, which makes running change detection unnecessary. Common examples are `requestAnimationFrame`, `setTimeout` and `setInterval`. You can identify change detection with Angular DevTools, and you can run code outside the Angular zone to avoid unnecessary change detection calls.
Visit the following resources to learn more:
- [@official@Angular Official Docs - Zone Pollution](https://angular.dev/best-practices/zone-pollution)
- [@official@Angular Official Docs - DevTools](https://angular.dev/tools/devtools)
- [@video@NgZone in Angular - Improve Performance by Running Code Outside Angular](https://www.youtube.com/watch?v=7duYY9IFIuw)
- [@video@4 Runtime Performance Optimizations](https://www.youtube.com/watch?v=f8sA-i6gkGQ)

@ -4,6 +4,9 @@ Zone.js is a signaling mechanism that Angular uses to detect when an application
It captures asynchronous operations like setTimeout, network requests, and event listeners.
Angular schedules change detection based on signals from Zone.js.
Visit the following resources to learn more:
- [@official@Resolving zone pollution](https://angular.dev/best-practices/zone-pollution)
- [@official@Angular without ZoneJS (Zoneless)](https://angular.dev/guide/experimental/zoneless)
- [@official@NgZone - API](https://angular.dev/api/core/NgZone)
- [@video@WTF is "Zone.js" and is it making your app slow?](https://www.youtube.com/watch?v=lmrf_gPIOZU)

@ -4,4 +4,4 @@ In AWS, an `Amazon EBS` (Elastic Block Store) is the storage volume used by EC2
Visit the following resources to learn more:
- [@official@Elastic Block Store](https://docs.aws.amazon.com/pt_br/ebs/latest/userguide/what-is-ebs.html)
- [@official@Elastic Block Store](https://docs.aws.amazon.com/ebs/latest/userguide/what-is-ebs.html)

@ -32,12 +32,19 @@ export const faqs: FAQType[] = [
'If you are a beginner who is just getting started, don\'t feel overwhelmed by looking at this roadmap. Look at the answer to the FAQ "How to become a Backend Developer?"',
],
},
{
question: 'What tools does a backend developer use?',
answer: [
'Other than the language itself, some common [backend developer tools](https://roadmap.sh/backend/developer-tools) that you’ll use as a backend dev, are going to be: The IDE/Text editor; here you have tons of options from VSCode, to Zed or Sublime Text. Some database tools, such as DataGrid or Navicat interact with your databases from outside your code. API-related tools like Swagger or Postman will help you document their behavior and share the endpoints with your team. A hosting service for your code. And finally, some collaborative and productivity tools such as Jira, Wrike, Trello or Monday to help you organize your work with your colleagues. And others like Raycast or iTerm to boost your productivity. There are many alternatives in each category, it’s up to you to try them and pick the ones that work best for you.',
{
question: 'What tools does a backend developer use?',
answer: [
'Other than the language itself, some common [backend developer tools](https://roadmap.sh/backend/developer-tools) that you’ll use as a backend dev, are going to be: The IDE/Text editor; here you have tons of options from VSCode, to Zed or Sublime Text. Some database tools, such as DataGrid or Navicat interact with your databases from outside your code. API-related tools like Swagger or Postman will help you document their behavior and share the endpoints with your team. A hosting service for your code. And finally, some collaborative and productivity tools such as Jira, Wrike, Trello or Monday to help you organize your work with your colleagues. And others like Raycast or iTerm to boost your productivity. There are many alternatives in each category, it’s up to you to try them and pick the ones that work best for you.',
]
},
{
question: 'What are backend technologies?',
answer: [
'[Backend technologies](https://roadmap.sh/backend/technologies) are the technologies that power the server-side of web applications. They are responsible for managing data, processing requests, and generating responses to the client-side of the application. Some of the most popular backend technologies include programming languages like Python, Ruby, Java, and Go, as well as frameworks like Django, Ruby on Rails, Spring Boot, and Gin. Backend technologies also include databases like PostgreSQL, MySQL, and MongoDB, as well as tools like Docker, Kubernetes, and Jenkins. These technologies work together to create the server-side of web applications and provide the functionality that users interact with on the client-side.',
]
}
]
}
];
---

@ -0,0 +1,9 @@
# Buffer Overflow
A Buffer Overflow is a type of vulnerability that occurs when a program or process attempts to write more data to a buffer—a temporary storage area in memory—than it can hold. This overflow can cause the extra data to overwrite adjacent memory locations, potentially leading to unintended behavior, crashes, or security breaches.
Visit the following resources to learn more:
- [@article@What Is Buffer Overflow?](https://www.fortinet.com/resources/cyberglossary/buffer-overflow)
- [@article@Buffer Overflow Attack](https://www.imperva.com/learn/application-security/buffer-overflow/)

@ -0,0 +1,8 @@
# Deauth Attack
A Deauthentication (Deauth) Attack is a type of denial-of-service (DoS) attack specific to wireless networks. It involves sending fake deauthentication frames to a Wi-Fi client or access point, forcing the client to disconnect from the network. The attacker uses this technique to disrupt the communication between the client and the access point, often with the intention of capturing data, launching further attacks, or simply causing disruption.
Visit the following resources to learn more:
- [@article@Wi-Fi Deauthentication Attack](https://medium.com/@balaramapunna123/wi-fi-deauthentication-attack-76cdd91d5fc)
- [@article@Deauthentication Attacks](https://www.baeldung.com/cs/deauthentication-attacks)

@ -0,0 +1,13 @@
# Directory Traversal
Directory Traversal, also known as Path Traversal, is a vulnerability that allows attackers to read files on a system without proper authorization. These attacks typically exploit unsecured paths using "../" (dot-dot-slash) sequences and their variations, or absolute file paths. The attack is also referred to as "dot-dot-slash," "directory climbing," or "backtracking."
While Directory Traversal is sometimes combined with other vulnerabilities like Local File Inclusion (LFI) or Remote File Inclusion (RFI), the key difference is that Directory Traversal doesn't execute code, whereas LFI and RFI usually do.
Visit the following resources to learn more:
- [@article@Portswigger's guide on File Path Traversal](https://portswigger.net/web-security/file-path-traversal)
- [@official@OWASP's article on Path Traversal](https://owasp.org/www-community/attacks/Path_Traversal)
- [@course@TryHackMe's room on Path Traversal & File Inclusion](https://tryhackme.com/r/room/filepathtraversal)
- [@article@Acunetix's article on directory traversal](https://www.acunetix.com/websitesecurity/directory-traversal/)
- [@course@HackTheBox Academy's module on File Inclusion & Path Traversal](https://academy.hackthebox.com/course/preview/file-inclusion)

@ -0,0 +1,8 @@
# Replay Attack
A Replay Attack is a type of network attack where an attacker intercepts and retransmits legitimate communication data, often with the aim of gaining unauthorized access to a system or performing unauthorized actions. In this attack, the attacker captures a valid data transmission and then "replays" it later, without needing to decrypt or alter the data, to trick the recipient into thinking it's a legitimate request.
Visit the following resources to learn more:
- [@article@What Is a Replay Attack?](https://usa.kaspersky.com/resource-center/definitions/replay-attack)

@ -0,0 +1,8 @@
# Rogue Access Point
A Rogue Access Point (Rogue AP) is an unauthorized wireless access point installed on a secure network without the network administrator's knowledge or consent. These devices can be set up by malicious actors to intercept, steal, or manipulate network traffic, or by employees who unintentionally compromise network security by setting up their own wireless access points.
Visit the following resources to learn more:
- [@article@Rogue access points](https://www.khanacademy.org/computing/computers-and-internet/xcae6f4a7ff015e7d:online-data-security/xcae6f4a7ff015e7d:cyber-attacks/a/rogue-access-points-mitm-attacks)

@ -0,0 +1,16 @@
# VirusTotal
VirusTotal's main feature is multi-scanning using over 70 antivirus scanners to generate a cumulative report on whether a file is malicious. It also stores file hashes, eliminating the need to rescan previously uploaded files. Researchers can comment in the community, sharing their analysis and insights into malware for others to benefit from.
VirusTotal's aggregated data comes from various antivirus engines, website scanners, file and URL analysis tools, and user contributions. These tools serve diverse purposes, including heuristic engines, known-bad signatures, metadata extraction, and identification of malicious signals.
Additionally, VirusTotal offers services to search by file hash, IP address, and URL, which are also scanned. For more comprehensive features, VirusTotal provides Premium services such as Intelligence & Hunting.
Visit the following resources to learn more:
- [@article@VirusTotal Explained](https://isecjobs.com/insights/virustotal-explained/)
- [@official@VirusTotal's Docs on how VirusTotal Works](https://docs.virustotal.com/docs/how-it-works)
- [@official@VirusTotal's website](https://www.virustotal.com)
- [@article@Wikipedia Page on VirusTotal](https://en.wikipedia.org/wiki/VirusTotal)
- [@official@CISA's definition of VirusTotal](https://www.cisa.gov/resources-tools/services/virustotal)

@ -4,6 +4,7 @@ C++ is a powerful general-purpose programming language. It can be used to develo
Visit the following resources to learn more:
- [@official@Visit Dedicated C++ Roadmap](https://roadmap.sh/cpp)
- [@article@Learn Cpp](https://learncpp.com/)
- [@article@C++ Reference](https://en.cppreference.com/)
- [@feed@Explore top posts about C++](https://app.daily.dev/tags/c++?ref=roadmapsh)

@ -1,3 +1,3 @@
# Selection Sort
Selection Sort is a simple and intuitive sorting algorithm. It works by dividing the array into two parts - sorted and unsorted. Initially, the sorted part is empty and the unsorted part contains all the elements. The algorithm repeatedly selects the smallest (or largest, if sorting in descending order) element from the unsorted part and moves that to the end of the sorted part. The process continues until the unsorted part becomes empty and the sorted part contains all the elements. Selection sort is not efficient on large lists, as its time complexity is O(n²) where n is the number of items.
Selection Sort is a simple and intuitive sorting algorithm. It works by dividing the array into two parts - sorted and unsorted. Initially, the sorted part is empty and the unsorted part contains all the elements. The algorithm repeatedly selects the smallest (or largest, if sorting in descending order) element from the unsorted part and moves that to the end of the sorted part. The process continues until the unsorted part becomes empty and the sorted part contains all the elements. Selection sort is not efficient on large lists, as its time complexity is $O(n²)$ where $n$ is the number of items.

@ -1,3 +1,8 @@
# Binary Trees
A **Binary Tree** is a type of tree data structure in which each node has at most two children, referred to as the left child and the right child. This distinguishes it from trees in which nodes can have any number of children. A binary tree is further classified as a strictly binary tree if every non-leaf node in the tree has non-empty left and right child nodes. A binary tree is complete if all levels of the tree, except possibly the last, are fully filled, and all nodes are as left-justified as possible. Multiple algorithms and functions employ binary trees due to their suitable properties for mathematical operations and data organization.
A **Binary Tree** is a type of tree data structure in which each node has at most two children, referred to as the left child and the right child. This distinguishes it from trees in which nodes can have any number of children. A binary tree is further classified as a strictly binary tree if every non-leaf node in the tree has non-empty left and right child nodes. A binary tree is complete if all levels of the tree, except possibly the last, are fully filled, and all nodes are as left-justified as possible. Multiple algorithms and functions employ binary trees due to their suitable properties for mathematical operations and data organization.
Learn more from the following links:
- [@video@Binary Tree](https://youtu.be/4r_XR9fUPhQ?si=PBsRjix_Z9kVHgMM)
- [@article@Binary Tree](https://www.w3schools.com/dsa/dsa_data_binarytrees.php)

@ -1,3 +1,8 @@
# Binary Search Trees
A **Binary Search Tree** (BST) is a type of binary tree data structure where each node carries a unique key (a value), and each key/node has up to two referenced sub-trees, the left and right child. The key feature of a BST is that every node on the right subtree must have a value greater than its parent node, while every node on the left subtree must have a value less than its parent node. This property must be true for all the nodes, not just the root. Due to this property, searching, insertion, and removal of a node in a BST perform quite fast, and the operations can be done in O(log n) time complexity, making it suitable for data-intensive operations.
A **Binary Search Tree** (BST) is a type of binary tree data structure where each node carries a unique key (a value), and each key/node has up to two referenced sub-trees, the left and right child. The key feature of a BST is that every node on the right subtree must have a value greater than its parent node, while every node on the left subtree must have a value less than its parent node. This property must be true for all the nodes, not just the root. Due to this property, searching, insertion, and removal of a node in a BST perform quite fast, and the operations can be done in O(log n) time complexity, making it suitable for data-intensive operations.
Learn more from the following links:
- [@video@Binary Search Tree Part-1](https://youtu.be/lFq5mYUWEBk?si=GKRm1O278NCetnry)
- [@video@Binary Search Tree Part-2](https://youtu.be/JnrbMQyGLiU?si=1pfKn2akKXWLshY6)

@ -1,3 +1,7 @@
# Tree Traversal
Tree Traversal is a method of visiting all the nodes in a tree data structure. There are three main types of tree traversal, these include Preorder, Inorder, and Postorder. Preorder traversal visits the current node before its child nodes, Inorder traversal visits the left child, then the parent and right child, and Postorder traversal visits the children before their respective parents. There's also a level order traversal which visits nodes level by level. Depth First Search (DFS) and Breadth First Search (BFS) are two popular algorithms used for tree traversal. DFS involves exhaustive searches of nodes by going forward if possible and if it is not possible then by going back. BFS starts traversal from the root node and visits nodes in a level by level manner.
Tree Traversal is a method of visiting all the nodes in a tree data structure. There are three main types of tree traversal, these include Preorder, Inorder, and Postorder. Preorder traversal visits the current node before its child nodes, Inorder traversal visits the left child, then the parent and right child, and Postorder traversal visits the children before their respective parents. There's also a level order traversal which visits nodes level by level. Depth First Search (DFS) and Breadth First Search (BFS) are two popular algorithms used for tree traversal. DFS involves exhaustive searches of nodes by going forward if possible and if it is not possible then by going back. BFS starts traversal from the root node and visits nodes in a level by level manner.
Learn more from the following links:
- [@video@Tree Traversal pre-order, in-order, post-order](https://youtu.be/lFq5mYUWEBk?si=GKRm1O278NCetnry)

@ -4,6 +4,7 @@ Docker is a platform for working with containerized applications. Among its feat
Visit the following resources to learn more:
- [@official@Visit Dedicated Docker Roadmap](https://roadmap.sh/docker)
- [@article@Docker Documentation](https://docs.docker.com/)
- [@video@Docker Tutorial](https://www.youtube.com/watch?v=RqTEHSBrYFw)
- [@video@Docker simplified in 55 seconds](https://youtu.be/vP_4DlOH1G4)

@ -12,5 +12,4 @@ Visit the following resources to learn more:
- [@article@A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox)
- [@article@A Complete Guide to Grid](https://css-tricks.com/snippets/css/complete-guide-grid)
- [@article@Learn CSS Grid - Course](https://cssgrid.io/)
- [@course@Learn CSS Grid for free](https://scrimba.com/learn/cssgrid?via=roadmap)
- [@article@Get on the Grid at Last with the CSS Grid Layout Module](https://thenewstack.io/get-grid-last-css-grid-template-markup/)

@ -8,7 +8,6 @@ Visit the following resources to learn more:
- [@article@Official Docs for Deep Dives](https://www.typescriptlang.org/docs/)
- [@article@The TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
- [@article@TypeScript Tutorial](https://www.tutorialspoint.com/typescript/index.htm)
- [@course@Scrimba — TypeScript Basics](https://scrimba.com/learn/typescript?via=roadmap)
- [@video@TypeScript for Beginners](https://www.youtube.com/watch?v=BwuLxPH8IDs)
- [@article@What Is TypeScript?](https://thenewstack.io/what-is-typescript/)
- [@article@TypeScript Tutorial: Go beyond ‘Hello, World!’](https://thenewstack.io/typescript-tutorial-go-beyond-hello-world/)

@ -1,3 +1,7 @@
# Decision Tree Learning
`Decision Tree Learning` is an important concept in game development, particularly in the development of artificial intelligence for game characters. It is a kind of machine learning method that is based on using decision tree models to predict or classify information. A decision tree is a flowchart-like model, where each internal node denotes a test on an attribute, each branch represents an outcome of that test, and each leaf node holds a class label (decision made after testing all attributes). By applying decision tree learning models, computer-controlled characters can make decisions based on different conditions or states. They play a key role in creating complex and interactive gameplay experiences, by enabling game characters to adapt to the player's actions and the ever-changing game environment.
`Decision Tree Learning` is an important concept in game development, particularly in the development of artificial intelligence for game characters. It is a kind of machine learning method that is based on using decision tree models to predict or classify information. A decision tree is a flowchart-like model, where each internal node denotes a test on an attribute, each branch represents an outcome of that test, and each leaf node holds a class label (decision made after testing all attributes). By applying decision tree learning models, computer-controlled characters can make decisions based on different conditions or states. They play a key role in creating complex and interactive gameplay experiences, by enabling game characters to adapt to the player's actions and the ever-changing game environment.
Visit the following resources to learn more:
- [@video@Decision trees - A friendly introduction](https://www.youtube.com/watch?v=HkyWAhr9v8g)

@ -1,3 +1,7 @@
# Microsurface Scattering
Microsurface scattering, also known as sub-surface scattering, is an important phenomenon in Physically Based Rendering (PBR). This process involves the penetration of light into the surface of a material, where it is scattered by interacting with the material. In other words, when light strikes an object, rather than simply bouncing off the surface, some of it goes into the object and gets scattered around inside before getting re-emitted. It is key to achieving more realistic rendering of translucent materials like skin, marble, milk, and more. Consider it essential for replicating how light interacts with real-world materials in a convincing manner in your game.
Microsurface scattering, also known as sub-surface scattering, is an important phenomenon in Physically Based Rendering (PBR). This process involves the penetration of light into the surface of a material, where it is scattered by interacting with the material. In other words, when light strikes an object, rather than simply bouncing off the surface, some of it goes into the object and gets scattered around inside before getting re-emitted. It is key to achieving more realistic rendering of translucent materials like skin, marble, milk, and more. Consider it essential for replicating how light interacts with real-world materials in a convincing manner in your game.
Visit the following resources to learn more:
- [@video@The 4 main types of subsurface scattering](https://www.youtube.com/watch?v=GkjvYSbGHg4)

@ -5,7 +5,7 @@ renderer: 'editor'
order: 19
briefTitle: 'Git and GitHub'
briefDescription: 'Step by step guide to learn Git and GitHub in 2024'
title: 'Git and GitHub Roadmap'
title: 'Learn Git and GitHub'
description: 'Step by step guide to learn Git and GitHub in 2024'
hasTopics: true
isNew: true
@ -13,18 +13,18 @@ dimensions:
width: 968
height: 3330
schema:
headline: 'Git and GitHub Roadmap'
headline: 'Learn Git and GitHub'
description: 'Learn about Git and GitHub with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place.'
imageUrl: 'https://roadmap.sh/roadmaps/git-github.png'
datePublished: '2024-08-12'
dateModified: '2024-08-12'
seo:
title: 'Git and GitHub Roadmap'
title: 'Learn Git and GitHub'
description: 'Learn about Git and GitHub using this roadmap. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place.'
keywords:
- 'git and github roadmap 2024'
- 'learn git and github 2024'
- 'git roadmap'
- 'github roadmap'
- 'learn github'
relatedRoadmaps:
- 'computer-science'
- 'frontend'

@ -1,9 +1,9 @@
# Basic Syntax
Learn about the basic syntax of Go, such as how the go programs are executed, package imports, main function, and so on. Visit the resources listed below
Learn about the basic syntax of Go, such as how the Go programs are executed, package imports, main function, and so on.
Visit the following resources to learn more:
- [@official@Go Tutorial: Getting started](https://go.dev/doc/tutorial/getting-started)
- [@article@Go by Example: Hello World](https://gobyexample.com/hello-world)
- [@article@W3schools : Go Syntax](https://www.w3schools.com/go/go_syntax.php)
- [@article@W3schools: Go Syntax](https://www.w3schools.com/go/go_syntax.php)

@ -9,3 +9,5 @@ GraphQL solves several problems commonly faced when building APIs, including:
- **Inefficient versioning:** With REST, creating a new endpoint for each version of an API can quickly become cumbersome and hard to maintain. GraphQL allows for seamless versioning by adding new fields and types, rather than creating new endpoints.
- **Lack of flexibility:** REST APIs are typically fixed, meaning that the client has to work with the data structure provided by the API. GraphQL allows the client to request exactly the data it needs and receive it in a predictable format, increasing flexibility.
- **Microservice communicating** with Federation or Supergraph implementation you can easily query data from multiple microservice in one single query without code overhead or request overhead (if nothing requested from one microservice it wouldn't make a real network request for this data)

@ -1,12 +1,17 @@
# Strict Equality Operator (===)
In JavaScript, the strict equality operator `===` compares both the value and the type of two operands. This means that it will only return true if both the value and the type are identical.
```sh
"5" === "5" // true
```
In this case, both the value and the type are the same, so the result is true.
```sh
"5" === 5 // false
```
Here, although the values might appear similar, the types are different (string and number), so the result is false. The strict equality operator does not perform type coercion; both the value and the type must be identical.
Learn more from the following resources:

@ -1 +1,7 @@
# apply
# apply
The apply() method of Function instances calls this function with a given this value, and arguments provided as an array (or an array-like object).
Visit the following resources to learn more:
- [@official@apply() - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply)

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

Loading…
Cancel
Save