Compare commits

..

1 Commits

Author SHA1 Message Date
Arik Chakma
eb0ab87d34 fix: progress nudge count 2024-09-16 17:19:30 +06:00
8611 changed files with 225546 additions and 373946 deletions

View File

@@ -3,6 +3,6 @@
"enabled": false
},
"_variables": {
"lastUpdateCheck": 1756224238932
"lastUpdateCheck": 1725962974592
}
}

View File

@@ -1,155 +0,0 @@
---
description: When user requests migrating old roadmap content to new folder from content-old to content folder
globs:
alwaysApply: false
---
# Content Migration Rule
## Rule Name: content-migration
## Description
This rule provides a complete process for migrating roadmap content from old structure to new structure using migration mapping files.
## When to Use
Use this rule when you need to:
- Migrate content from content-old directories to content directories
- Use a migration-mapping.json file to map topic paths to content IDs
- Populate empty content files with existing content from legacy structure
## Process
### 1. Prerequisites Check
- Verify the roadmap directory has a `migration-mapping.json` file
- Confirm `content-old/` directory exists with source content
- Confirm `content/` directory exists with target files
### 2. Migration Script Creation
Create a Node.js script with the following functionality:
```javascript
const fs = require('fs');
const path = require('path');
// Load the migration mapping
const migrationMapping = JSON.parse(fs.readFileSync('migration-mapping.json', 'utf8'));
// Function to find old content file based on topic path
function findOldContentFile(topicPath) {
const parts = topicPath.split(':');
if (parts.length === 1) {
// Top level file like "introduction"
return path.join('content-old', parts[0], 'index.md');
} else if (parts.length === 2) {
// Like "introduction:what-is-rust"
const [folder, filename] = parts;
return path.join('content-old', folder, `${filename}.md`);
} else if (parts.length === 3) {
// Like "language-basics:syntax:variables"
const [folder, subfolder, filename] = parts;
return path.join('content-old', folder, subfolder, `${filename}.md`);
}
return null;
}
// Function to find new content file based on content ID
function findNewContentFile(contentId) {
const contentDir = 'content';
const files = fs.readdirSync(contentDir);
// Find file that ends with the content ID
const matchingFile = files.find(file => file.includes(`@${contentId}.md`));
if (matchingFile) {
return path.join(contentDir, matchingFile);
}
return null;
}
// Process each mapping
console.log('Starting content migration...\n');
let migratedCount = 0;
let skippedCount = 0;
for (const [topicPath, contentId] of Object.entries(migrationMapping)) {
const oldFilePath = findOldContentFile(topicPath);
const newFilePath = findNewContentFile(contentId);
if (!oldFilePath) {
console.log(`❌ Could not determine old file path for: ${topicPath}`);
skippedCount++;
continue;
}
if (!newFilePath) {
console.log(`❌ Could not find new file for content ID: ${contentId} (topic: ${topicPath})`);
skippedCount++;
continue;
}
if (!fs.existsSync(oldFilePath)) {
console.log(`❌ Old file does not exist: ${oldFilePath} (topic: ${topicPath})`);
skippedCount++;
continue;
}
try {
// Read old content
const oldContent = fs.readFileSync(oldFilePath, 'utf8');
// Write to new file
fs.writeFileSync(newFilePath, oldContent);
console.log(`✅ Migrated: ${topicPath} -> ${path.basename(newFilePath)}`);
migratedCount++;
} catch (error) {
console.log(`❌ Error migrating ${topicPath}: ${error.message}`);
skippedCount++;
}
}
console.log(`\n📊 Migration complete:`);
console.log(` Migrated: ${migratedCount} files`);
console.log(` Skipped: ${skippedCount} files`);
console.log(` Total: ${Object.keys(migrationMapping).length} mappings`);
```
### 3. Execution Steps
1. Navigate to the roadmap directory (e.g., `src/data/roadmaps/[roadmap-name]`)
2. Create the migration script as `migrate_content.cjs`
3. Run: `node migrate_content.cjs`
4. Review the migration results
5. Clean up the temporary script file
### 4. Validation
After migration:
- Verify a few migrated files have proper content (not just titles)
- Check that the content structure matches the old content
- Ensure proper markdown formatting is preserved
## File Structure Expected
```
roadmap-directory/
├── migration-mapping.json
├── content/
│ ├── file1@contentId1.md
│ ├── file2@contentId2.md
│ └── ...
└── content-old/
├── section1/
│ ├── index.md
│ ├── topic1.md
│ └── subsection1/
│ └── subtopic1.md
└── section2/
└── ...
```
## Notes
- The migration mapping uses colons (`:`) to separate nested paths
- Content files in the new structure use the pattern `filename@contentId.md`
- The script handles 1-3 levels of nesting in the old structure
- Always create the script with `.cjs` extension to avoid ES module issues

View File

@@ -1,389 +0,0 @@
---
description: GitHub pull requests
globs:
alwaysApply: false
---
# gh cli
Work seamlessly with GitHub from the command line.
USAGE
gh <command> <subcommand> [flags]
CORE COMMANDS
auth: Authenticate gh and git with GitHub
browse: Open repositories, issues, pull requests, and more in the browser
codespace: Connect to and manage codespaces
gist: Manage gists
issue: Manage issues
org: Manage organizations
pr: Manage pull requests
project: Work with GitHub Projects.
release: Manage releases
repo: Manage repositories
GITHUB ACTIONS COMMANDS
cache: Manage GitHub Actions caches
run: View details about workflow runs
workflow: View details about GitHub Actions workflows
ALIAS COMMANDS
co: Alias for "pr checkout"
ADDITIONAL COMMANDS
alias: Create command shortcuts
api: Make an authenticated GitHub API request
attestation: Work with artifact attestations
completion: Generate shell completion scripts
config: Manage configuration for gh
extension: Manage gh extensions
gpg-key: Manage GPG keys
label: Manage labels
preview: Execute previews for gh features
ruleset: View info about repo rulesets
search: Search for repositories, issues, and pull requests
secret: Manage GitHub secrets
ssh-key: Manage SSH keys
status: Print information about relevant issues, pull requests, and notifications across repositories
variable: Manage GitHub Actions variables
HELP TOPICS
accessibility: Learn about GitHub CLI's accessibility experiences
actions: Learn about working with GitHub Actions
environment: Environment variables that can be used with gh
exit-codes: Exit codes used by gh
formatting: Formatting options for JSON data exported from gh
mintty: Information about using gh with MinTTY
reference: A comprehensive reference of all gh commands
FLAGS
--help Show help for command
--version Show gh version
EXAMPLES
$ gh issue create
$ gh repo clone cli/cli
$ gh pr checkout 321
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`
## gh pr
Work with GitHub pull requests.
USAGE
gh pr <command> [flags]
GENERAL COMMANDS
create: Create a pull request
list: List pull requests in a repository
status: Show status of relevant pull requests
TARGETED COMMANDS
checkout: Check out a pull request in git
checks: Show CI status for a single pull request
close: Close a pull request
comment: Add a comment to a pull request
diff: View changes in a pull request
edit: Edit a pull request
lock: Lock pull request conversation
merge: Merge a pull request
ready: Mark a pull request as ready for review
reopen: Reopen a pull request
review: Add a review to a pull request
unlock: Unlock pull request conversation
update-branch: Update a pull request branch
view: View a pull request
FLAGS
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
INHERITED FLAGS
--help Show help for command
ARGUMENTS
A pull request can be supplied as argument in any of the following formats:
- by number, e.g. "123";
- by URL, e.g. "https://github.com/OWNER/REPO/pull/123"; or
- by the name of its head branch, e.g. "patch-1" or "OWNER:patch-1".
EXAMPLES
$ gh pr checkout 353
$ gh pr create --fill
$ gh pr view --web
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`
## gh pr list
List pull requests in a GitHub repository. By default, this only lists open PRs.
The search query syntax is documented here:
<https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests>
For more information about output formatting flags, see `gh help formatting`.
USAGE
gh pr list [flags]
ALIASES
gh pr ls
FLAGS
--app string Filter by GitHub App author
-a, --assignee string Filter by assignee
-A, --author string Filter by author
-B, --base string Filter by base branch
-d, --draft Filter by draft state
-H, --head string Filter by head branch ("<owner>:<branch>" syntax not supported)
-q, --jq expression Filter JSON output using a jq expression
--json fields Output JSON with the specified fields
-l, --label strings Filter by label
-L, --limit int Maximum number of items to fetch (default 30)
-S, --search query Search pull requests with query
-s, --state string Filter by state: {open|closed|merged|all} (default "open")
-t, --template string Format JSON output using a Go template; see "gh help formatting"
-w, --web List pull requests in the web browser
INHERITED FLAGS
--help Show help for command
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
JSON FIELDS
additions, assignees, author, autoMergeRequest, baseRefName, baseRefOid, body,
changedFiles, closed, closedAt, closingIssuesReferences, comments, commits,
createdAt, deletions, files, fullDatabaseId, headRefName, headRefOid,
headRepository, headRepositoryOwner, id, isCrossRepository, isDraft, labels,
latestReviews, maintainerCanModify, mergeCommit, mergeStateStatus, mergeable,
mergedAt, mergedBy, milestone, number, potentialMergeCommit, projectCards,
projectItems, reactionGroups, reviewDecision, reviewRequests, reviews, state,
statusCheckRollup, title, updatedAt, url
EXAMPLES
# List PRs authored by you
$ gh pr list --author "@me"
# List PRs with a specific head branch name
$ gh pr list --head "typo"
# List only PRs with all of the given labels
$ gh pr list --label bug --label "priority 1"
# Filter PRs using search syntax
$ gh pr list --search "status:success review:required"
# Find a PR that introduced a given commit
$ gh pr list --search "<SHA>" --state merged
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`
## gh pr diff
View changes in a pull request.
Without an argument, the pull request that belongs to the current branch
is selected.
With `--web` flag, open the pull request diff in a web browser instead.
USAGE
gh pr diff [<number> | <url> | <branch>] [flags]
FLAGS
--color string Use color in diff output: {always|never|auto} (default "auto")
--name-only Display only names of changed files
--patch Display diff in patch format
-w, --web Open the pull request diff in the browser
INHERITED FLAGS
--help Show help for command
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`
## gh pr merge
Merge a pull request on GitHub.
Without an argument, the pull request that belongs to the current branch
is selected.
When targeting a branch that requires a merge queue, no merge strategy is required.
If required checks have not yet passed, auto-merge will be enabled.
If required checks have passed, the pull request will be added to the merge queue.
To bypass a merge queue and merge directly, pass the `--admin` flag.
USAGE
gh pr merge [<number> | <url> | <branch>] [flags]
FLAGS
--admin Use administrator privileges to merge a pull request that does not meet requirements
-A, --author-email text Email text for merge commit author
--auto Automatically merge only after necessary requirements are met
-b, --body text Body text for the merge commit
-F, --body-file file Read body text from file (use "-" to read from standard input)
-d, --delete-branch Delete the local and remote branch after merge
--disable-auto Disable auto-merge for this pull request
--match-head-commit SHA Commit SHA that the pull request head must match to allow merge
-m, --merge Merge the commits with the base branch
-r, --rebase Rebase the commits onto the base branch
-s, --squash Squash the commits into one commit and merge it into the base branch
-t, --subject text Subject text for the merge commit
INHERITED FLAGS
--help Show help for command
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`
## gh pr review
Add a review to a pull request.
Without an argument, the pull request that belongs to the current branch is reviewed.
USAGE
gh pr review [<number> | <url> | <branch>] [flags]
FLAGS
-a, --approve Approve pull request
-b, --body string Specify the body of a review
-F, --body-file file Read body text from file (use "-" to read from standard input)
-c, --comment Comment on a pull request
-r, --request-changes Request changes on a pull request
INHERITED FLAGS
--help Show help for command
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
EXAMPLES
# Approve the pull request of the current branch
$ gh pr review --approve
# Leave a review comment for the current branch
$ gh pr review --comment -b "interesting"
# Add a review for a specific pull request
$ gh pr review 123
# Request changes on a specific pull request
$ gh pr review 123 -r -b "needs more ASCII art"
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`
## gh pr checkout
Check out a pull request in git
USAGE
gh pr checkout [<number> | <url> | <branch>] [flags]
FLAGS
-b, --branch string Local branch name to use (default [the name of the head branch])
--detach Checkout PR with a detached HEAD
-f, --force Reset the existing local branch to the latest state of the pull request
--recurse-submodules Update all submodules after checkout
INHERITED FLAGS
--help Show help for command
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
EXAMPLES
# Interactively select a PR from the 10 most recent to check out
$ gh pr checkout
# Checkout a specific PR
$ gh pr checkout 32
$ gh pr checkout https://github.com/OWNER/REPO/pull/32
$ gh pr checkout feature
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`
## gh pr close
Close a pull request
USAGE
gh pr close {<number> | <url> | <branch>} [flags]
FLAGS
-c, --comment string Leave a closing comment
-d, --delete-branch Delete the local and remote branch after close
INHERITED FLAGS
--help Show help for command
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`
## gh pr comment
Add a comment to a GitHub pull request.
Without the body text supplied through flags, the command will interactively
prompt for the comment text.
USAGE
gh pr comment [<number> | <url> | <branch>] [flags]
FLAGS
-b, --body text The comment body text
-F, --body-file file Read body text from file (use "-" to read from standard input)
--create-if-none Create a new comment if no comments are found. Can be used only with --edit-last
--delete-last Delete the last comment of the current user
--edit-last Edit the last comment of the current user
-e, --editor Skip prompts and open the text editor to write the body in
-w, --web Open the web browser to write the comment
--yes Skip the delete confirmation prompt when --delete-last is provided
INHERITED FLAGS
--help Show help for command
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
EXAMPLES
$ gh pr comment 13 --body "Hi from GitHub CLI"
LEARN MORE
Use `gh <command> <subcommand> --help` for more information about a command.
Read the manual at https://cli.github.com/manual
Learn about exit codes using `gh help exit-codes`
Learn about accessibility experiences using `gh help accessibility`

View File

@@ -1,12 +1,3 @@
PUBLIC_API_URL=https://api.roadmap.sh
PUBLIC_AVATAR_BASE_URL=https://dodrc8eu8m09s.cloudfront.net/avatars
PUBLIC_EDITOR_APP_URL=https://draw.roadmap.sh
PUBLIC_COURSE_APP_URL=http://localhost:5173
PUBLIC_STRIPE_INDIVIDUAL_MONTHLY_PRICE_ID=
PUBLIC_STRIPE_INDIVIDUAL_YEARLY_PRICE_ID=
PUBLIC_STRIPE_INDIVIDUAL_MONTHLY_PRICE_AMOUNT=10
PUBLIC_STRIPE_INDIVIDUAL_YEARLY_PRICE_AMOUNT=100
ROADMAP_API_KEY=
PUBLIC_EDITOR_APP_URL=https://draw.roadmap.sh

View File

@@ -2,7 +2,7 @@ name: Clears API Cloudfront Cache
on:
workflow_dispatch:
jobs:
cloudfront_api_cache:
aws_costs:
runs-on: ubuntu-latest
steps:
- name: Clear Cloudfront Caching

View File

@@ -2,7 +2,7 @@ name: Clears Frontend Cloudfront Cache
on:
workflow_dispatch:
jobs:
cloudfront_fe_cache:
aws_costs:
runs-on: ubuntu-latest
steps:
- name: Clear Cloudfront Caching
@@ -13,4 +13,4 @@ jobs:
-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,cloudfront-course", "is_verbose": false } }'
-d '{ "ref":"master", "inputs": { "playbook": "roadmap_web.yml", "tags": "cloudfront", "is_verbose": false } }'

View File

@@ -1,66 +0,0 @@
name: Sync Content to Repo
on:
workflow_dispatch:
inputs:
roadmap_slug:
description: "The ID of the roadmap to sync"
required: true
default: "__default__"
jobs:
sync-content:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup pnpm@v9
uses: pnpm/action-setup@v4
with:
version: 9
run_install: false
- name: Setup Node.js Version 20 (LTS)
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install Dependencies and Sync Content
run: |
echo "Installing Dependencies"
pnpm install
echo "Syncing Content to Repo"
npm run sync:content-to-repo -- --roadmap-slug=${{ inputs.roadmap_slug }} --secret=${{ secrets.GH_SYNC_SECRET }}
- name: Check for changes
id: verify-changed-files
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "changed=true" >> $GITHUB_OUTPUT
else
echo "changed=false" >> $GITHUB_OUTPUT
fi
- name: Create PR
if: steps.verify-changed-files.outputs.changed == 'true'
uses: peter-evans/create-pull-request@v7
with:
delete-branch: false
branch: "chore/sync-content-to-repo-${{ inputs.roadmap_slug }}"
base: "master"
labels: |
automated pr
reviewers: jcanalesluna,kamranahmedse
commit-message: "chore: sync content to repo"
title: "chore: sync content to repository - ${{ inputs.roadmap_slug }}"
body: |
## Sync Content to Repo
> [!IMPORTANT]
> This PR Syncs the Content to the Repo for the Roadmap: ${{ inputs.roadmap_slug }}
>
> Commit: ${{ github.sha }}
> Workflow Path: ${{ github.workflow_ref }}
**Please Review the Changes and Merge the PR if everything is fine.**

View File

@@ -1,67 +0,0 @@
name: Sync on Roadmap Changes
on:
push:
branches:
- master
paths:
- 'src/data/roadmaps/**'
jobs:
sync-on-changes:
runs-on: ubuntu-latest
if: github.actor != 'github-actions[bot]' && github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2 # Fetch previous commit to compare changes
- name: Setup pnpm@v9
uses: pnpm/action-setup@v4
with:
version: 9
run_install: false
- name: Setup Node.js Version 20 (LTS)
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Get changed files
id: changed-files
run: |
echo "Getting changed files in /src/data/roadmaps/"
# Get changed files between HEAD and previous commit
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD -- src/data/roadmaps/)
if [ -z "$CHANGED_FILES" ]; then
echo "No changes found in roadmaps directory"
echo "has_changes=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "Changed files:"
echo "$CHANGED_FILES"
# Convert to space-separated list for the script
CHANGED_FILES_LIST=$(echo "$CHANGED_FILES" | tr '\n' ',')
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "changed_files=$CHANGED_FILES_LIST" >> $GITHUB_OUTPUT
- name: Install Dependencies
if: steps.changed-files.outputs.has_changes == 'true'
run: |
echo "Installing Dependencies"
pnpm install
- name: Run sync script with changed files
if: steps.changed-files.outputs.has_changes == 'true'
run: |
echo "Running sync script for changed roadmap files"
echo "Changed files: ${{ steps.changed-files.outputs.changed_files }}"
# Run your script with the changed file paths
npm run sync:repo-to-database -- --files="${{ steps.changed-files.outputs.changed_files }}" --secret=${{ secrets.GH_SYNC_SECRET }}

View File

@@ -43,7 +43,7 @@ jobs:
## Updated all Dependencies to Latest Versions.
> [!IMPORTANT]
> This PR Upgrades the Dependencies to the their latest versions.
> This PR Upgrades the Dependencies to the Latest Their Versions.
>
> Commit: ${{ github.sha }}
> Workflow Path: ${{ github.workflow_ref }}

8
.gitignore vendored
View File

@@ -1,6 +1,5 @@
.idea
.temp
.astro
# build output
dist/
@@ -28,6 +27,9 @@ pnpm-debug.log*
/playwright-report/
/playwright/.cache/
tests-examples
*.csveditor/
*.csv
packages/editor
/editor/*
!/editor/readonly-editor.tsx
!/editor/renderer/renderer.ts
!/editor/renderer/index.tsx

10
.vscode/settings.json vendored
View File

@@ -2,13 +2,5 @@
"prettier.documentSelectors": ["**/*.astro"],
"[astro]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"tailwindCSS.experimental.classRegex": [
["\\b\\w+[cC]lassName\\s*=\\s*[\"']([^\"']*)[\"']"],
["\\b\\w+[cC]lassName\\s*=\\s*`([^`]*)`"],
["[\\w]+[cC]lassName[\"']?\\s*:\\s*[\"']([^\"']*)[\"']"],
["[\\w]+[cC]lassName[\"']?\\s*:\\s*`([^`]*)`"],
["cva\\(((?:[^()]|\\([^()]*\\))*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cx\\(((?:[^()]|\\([^()]*\\))*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
]
}
}

View File

@@ -1,31 +1,16 @@
// https://astro.build/config
import sitemap from '@astrojs/sitemap';
import tailwind from '@astrojs/tailwind';
import node from '@astrojs/node';
import { defineConfig } from 'astro/config';
import rehypeExternalLinks from 'rehype-external-links';
import { serializeSitemap, shouldIndexPage } from './sitemap.mjs';
import tailwindcss from '@tailwindcss/vite';
import react from '@astrojs/react';
// https://astro.build/config
export default defineConfig({
site: 'https://roadmap.sh/',
redirects: {
'/devops/devops-engineer': {
status: 301,
destination: '/devops',
},
'/ai-tutor': {
status: 301,
destination: '/ai',
},
},
vite: {
server: {
allowedHosts: ['roadmap.sh', 'port3k.kamranahmed.info'],
},
},
markdown: {
shikiConfig: {
theme: 'dracula',
@@ -55,22 +40,21 @@ export default defineConfig({
],
],
},
output: 'server',
output: 'hybrid',
adapter: node({
mode: 'standalone',
}),
trailingSlash: 'never',
integrations: [
tailwind({
config: {
applyBaseStyles: false,
},
}),
sitemap({
filter: shouldIndexPage,
serialize: serializeSitemap,
}),
react(),
],
vite: {
plugins: [tailwindcss()],
ssr: {
noExternal: [/^@roadmapsh\/editor.*$/],
},
},
});

View File

@@ -1,4 +1,4 @@
# Contribution Guidelines ✨
# Contribution
First of all, thank you for considering to contribute. Please look at the details below:
@@ -7,12 +7,10 @@ First of all, thank you for considering to contribute. Please look at the detail
- [Adding Projects](#adding-projects)
- [Adding Content](#adding-content)
- [Guidelines](#guidelines)
- [Good vs. Not So Good Contributions](#good-vs-not-so-good-contributions)
## New Roadmaps
For new roadmaps, you can either:
- Submit a roadmap by providing [a textual roadmap similar to this roadmap](https://gist.github.com/kamranahmedse/98758d2c73799b3a6ce17385e4c548a5) in an [issue](https://github.com/kamranahmedse/developer-roadmap/issues).
- Create an interactive roadmap yourself using [our roadmap editor](https://draw.roadmap.sh/) & submit the link to that roadmap in an [issue](https://github.com/kamranahmedse/developer-roadmap/issues).
@@ -20,10 +18,10 @@ For new roadmaps, you can either:
For the existing roadmaps, please follow the details listed for the nature of contribution:
- **Fixing Typos** — Make your changes in the [roadmap markdown file](https://github.com/kamranahmedse/developer-roadmap/tree/master/src/data/roadmaps) and submit a [PR](https://github.com/kamranahmedse/developer-roadmap/pulls).
- **Fixing Typos** — Make your changes in the [roadmap JSON file](https://github.com/kamranahmedse/developer-roadmap/tree/master/src/data/roadmaps) and submit a [PR](https://github.com/kamranahmedse/developer-roadmap/pulls).
- **Adding or Removing Nodes** — Please open an [issue](https://github.com/kamranahmedse/developer-roadmap/issues) with your suggestion.
**Note:** Please note that our goal is **not to have the biggest list of items**. Our goal is to list items or skills most relevant today.
**Note:** Please note that our goal is <strong>not to have the biggest list of items</strong>. Our goal is to list items or skills most relevant today.
## Adding Projects
@@ -31,7 +29,7 @@ If you have a project idea that you think we should add to the roadmap, feel fre
The detailed format for the issue should be as follows:
```md
```
## What is this project about?
(Add an introduction to the project.)
@@ -55,20 +53,18 @@ Find [the content directory inside the relevant roadmap](https://github.com/kamr
- Maximum of 8 links per topic.
- Follow the below style guide for content.
Please note that we are intentionally keeping the content under the topic popup concise. You MUST always aim to explain the topic simply in a **single paragraph** or so and provide external resources where users can learn more about the topic.
### How To Structure Content
Please adhere to the following style when adding content to a topic:
```md
```
# Topic Title
(Content)
Visit the following resources to learn more:
- [@type@Title/Description of Link](Link)
- [@type@Description of link](Link)
```
`@type@` must be one of the following and describe the type of content you are adding:
@@ -79,21 +75,20 @@ Visit the following resources to learn more:
- `@course@`
- `@podcast@`
- `@video@`
- `@book@`
It's important to add a valid type, this will help us categorize the content and display it properly on the roadmap. The order of the links based on type is same as above.
It's important to add a valid type, this will help us categorize the content and display it properly on the roadmap.
## Guidelines
- <p><strong>Please don't use the project for self-promotion!</strong><br/>
- <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!
- <p><strong>Adding everything available out there is not the goal!</strong><br/>
- <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., 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/>
- <p><strong>Do not add things you have not evaluated personally!</strong><br />
Use your critical thinking to filter out non-essential stuff. Give honest arguments for why the resource should be included. Have you read this book? Can you give a short article?</p>
@@ -101,47 +96,26 @@ It's important to add a valid type, this will help us categorize the content and
If you are planning to contribute by adding content to the roadmaps, I recommend you to clone the repository, add content to the [content directory of the roadmap](./src/data/roadmaps/) and create a single PR to make it easier for me to review and merge the PR.
- <p><strong>Write meaningful commit messages</strong><br/>
- <p><strong>Write meaningful commit messages</strong><br >
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>
- New Roadmaps.
- Engaging and fresh content links.
- Typos and grammatical fixes.
- Enhanced Existing Content.
- Content copy in topics that do not have any (or minimal copy exists).
- New Roadmaps.
- Engaging, fresh content links.
- Typos and grammatical fixes.
- Content copy in topics that do not have any (or minimal copy exists).
<strong>Not So Good</strong>
- 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.
- Links to your own blog articles.
## Local Development
For local development, you can use the following commands:
```bash
git clone git@github.com:kamranahmedse/developer-roadmap.git --depth 1
cd developer-roadmap
pnpm add @roadmapsh/editor@npm:@roadmapsh/dummy-editor -w
pnpm install
```
Run the development server with:
```bash
pnpm dev
```
***
Have a look at the [License](./license) file.
- 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.
- Links to your own blog articles.

View File

@@ -0,0 +1,14 @@
export function ReadonlyEditor(props: any) {
return (
<div className="fixed bottom-0 left-0 right-0 top-0 z-[9999] border bg-white p-5 text-black">
<h2 className="mb-2 text-xl font-semibold">Private Component</h2>
<p className="mb-4">
Renderer is a private component. If you are a collaborator and have
access to it. Run the following command:
</p>
<code className="mt-5 rounded-md bg-gray-800 p-2 text-white">
npm run generate-renderer
</code>
</div>
);
}

14
editor/renderer/index.tsx Normal file
View File

@@ -0,0 +1,14 @@
export function Renderer(props: any) {
return (
<div className="fixed bottom-0 left-0 right-0 top-0 z-[9999] border bg-white p-5 text-black">
<h2 className="mb-2 text-xl font-semibold">Private Component</h2>
<p className="mb-4">
Renderer is a private component. If you are a collaborator and have
access to it. Run the following command:
</p>
<code className="mt-5 rounded-md bg-gray-800 p-2 text-white">
npm run generate-renderer
</code>
</div>
);
}

View File

@@ -0,0 +1,5 @@
export function renderFlowJSON(data: any, options?: any) {
console.warn("renderFlowJSON is not implemented");
console.warn("run the following command to generate the renderer:");
console.warn("> npm run generate-renderer");
}

View File

@@ -1,7 +1,7 @@
Everything including text and images in this project are protected by the copyright laws.
You are allowed to use this material for personal use but are not allowed to use it for
any other purpose including publishing the images, the project files or the content in
the images in any form either digital, non-digital, textual, graphical or written formats.
any other purpose including publishing the images, the project files or the content in the
images in any form either digital, non-digital, textual, graphical or written formats.
You are allowed to share the links to the repository or the website roadmap.sh but not
the content for any sort of usage that involves the content of this repository taken out
of the repository and be shared from any other medium including but not limited to blog
@@ -9,7 +9,7 @@ posts, articles, newsletters, you must get prior consent from the understated. T
conditions do not apply to the readonly GitHub forks created using the Fork button on
GitHub with the whole purpose of contributing to the project.
Copyright © 2017 - Present. Kamran Ahmed <kamranahmed.se@gmail.com>
Copyright © 2023 Kamran Ahmed <kamranahmed.se@gmail.com>
Please note that I am really flexible with allowing the usage of the content in this
repository. If you reach out to me with a brief detail of why and how you would like

146
package-lock.json generated
View File

@@ -29,18 +29,16 @@
"jose": "^5.6.3",
"js-cookie": "^3.0.5",
"lucide-react": "^0.419.0",
"luxon": "^3.5.0",
"nanoid": "^5.0.7",
"nanostores": "^0.10.3",
"node-html-parser": "^6.1.13",
"npm-check-updates": "^17.0.0",
"playwright": "^1.47.1",
"playwright": "^1.45.3",
"prismjs": "^1.29.0",
"react": "^18.3.1",
"react-calendar-heatmap": "^1.9.0",
"react-confetti": "^6.1.0",
"react-dom": "^18.3.1",
"react-slick": "^0.30.2",
"react-tooltip": "^5.27.1",
"reactflow": "^11.11.4",
"rehype-external-links": "^3.0.0",
@@ -49,7 +47,6 @@
"satori": "^0.10.14",
"satori-html": "^0.3.2",
"sharp": "^0.33.4",
"slick-carousel": "^1.8.1",
"slugify": "^1.6.6",
"tailwind-merge": "^2.4.0",
"tailwindcss": "^3.4.7",
@@ -62,10 +59,8 @@
"@tailwindcss/typography": "^0.5.13",
"@types/dom-to-image": "^2.6.7",
"@types/js-cookie": "^3.0.6",
"@types/luxon": "^3.4.2",
"@types/prismjs": "^1.26.4",
"@types/react-calendar-heatmap": "^1.6.7",
"@types/react-slick": "^0.23.13",
"@types/turndown": "^5.0.5",
"csv-parser": "^3.0.0",
"gh-pages": "^6.1.1",
@@ -1754,50 +1749,6 @@
"node": ">=18"
}
},
"node_modules/@playwright/test/node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/@playwright/test/node_modules/playwright": {
"version": "1.46.0",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.0.tgz",
"integrity": "sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==",
"dev": true,
"dependencies": {
"playwright-core": "1.46.0"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/@playwright/test/node_modules/playwright-core": {
"version": "1.46.0",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.0.tgz",
"integrity": "sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@reactflow/background": {
"version": "11.3.14",
"resolved": "https://registry.npmjs.org/@reactflow/background/-/background-11.3.14.tgz",
@@ -2671,12 +2622,6 @@
"integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==",
"dev": true
},
"node_modules/@types/luxon": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.2.tgz",
"integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==",
"dev": true
},
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -2753,15 +2698,6 @@
"@types/react": "*"
}
},
"node_modules/@types/react-slick": {
"version": "0.23.13",
"resolved": "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.13.tgz",
"integrity": "sha512-bNZfDhe/L8t5OQzIyhrRhBr/61pfBcWaYJoq6UDqFtv5LMwfg4NsVDD2J8N01JqdAdxLjOt66OZEp6PX+dGs/A==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/sax": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz",
@@ -3995,11 +3931,6 @@
"iconv-lite": "^0.6.2"
}
},
"node_modules/enquire.js": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz",
"integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw=="
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -5022,12 +4953,6 @@
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
"peer": true
},
"node_modules/js-cookie": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
@@ -5063,14 +4988,6 @@
"node": ">=4"
}
},
"node_modules/json2mq": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
"integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
"dependencies": {
"string-convert": "^0.2.0"
}
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -5197,11 +5114,6 @@
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
"dev": true
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
@@ -5287,14 +5199,6 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/luxon": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz",
"integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==",
"engines": {
"node": ">=12"
}
},
"node_modules/magic-string": {
"version": "0.30.11",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz",
@@ -6752,11 +6656,11 @@
}
},
"node_modules/playwright": {
"version": "1.47.2",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz",
"integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==",
"version": "1.46.0",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.0.tgz",
"integrity": "sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==",
"dependencies": {
"playwright-core": "1.47.2"
"playwright-core": "1.46.0"
},
"bin": {
"playwright": "cli.js"
@@ -6769,9 +6673,9 @@
}
},
"node_modules/playwright-core": {
"version": "1.47.2",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz",
"integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==",
"version": "1.46.0",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.0.tgz",
"integrity": "sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==",
"bin": {
"playwright-core": "cli.js"
},
@@ -7221,22 +7125,6 @@
"node": ">=0.10.0"
}
},
"node_modules/react-slick": {
"version": "0.30.2",
"resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.30.2.tgz",
"integrity": "sha512-XvQJi7mRHuiU3b9irsqS9SGIgftIfdV5/tNcURTb5LdIokRA5kIIx3l4rlq2XYHfxcSntXapoRg/GxaVOM1yfg==",
"dependencies": {
"classnames": "^2.2.5",
"enquire.js": "^2.1.6",
"json2mq": "^0.2.0",
"lodash.debounce": "^4.0.8",
"resize-observer-polyfill": "^1.5.0"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-tooltip": {
"version": "5.27.1",
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.27.1.tgz",
@@ -7441,11 +7329,6 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"node_modules/resolve": {
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@@ -7888,14 +7771,6 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="
},
"node_modules/slick-carousel": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
"integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==",
"peerDependencies": {
"jquery": ">=1.8.0"
}
},
"node_modules/slugify": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
@@ -7945,11 +7820,6 @@
"resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz",
"integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w=="
},
"node_modules/string-convert": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
"integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A=="
},
"node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",

View File

@@ -16,124 +16,81 @@
"roadmap-links": "node scripts/roadmap-links.cjs",
"roadmap-dirs": "node scripts/roadmap-dirs.cjs",
"roadmap-assets": "tsx scripts/editor-roadmap-assets.ts",
"refresh-assets": "tsx scripts/refresh-assets.ts",
"editor-roadmap-dirs": "tsx scripts/editor-roadmap-dirs.ts",
"editor-roadmap-content": "tsx scripts/editor-roadmap-content.ts",
"roadmap-content": "node scripts/roadmap-content.cjs",
"generate-renderer": "sh scripts/generate-renderer.sh",
"generate-renderer-dummy": "sh scripts/generate-renderer-dummy.sh",
"best-practice-dirs": "node scripts/best-practice-dirs.cjs",
"best-practice-content": "node scripts/best-practice-content.cjs",
"generate:og": "node ./scripts/generate-og-images.mjs",
"warm:urls": "sh ./scripts/warm-urls.sh https://roadmap.sh/sitemap-0.xml",
"compress:images": "tsx ./scripts/compress-images.ts",
"generate:roadmap-content-json": "tsx ./scripts/editor-roadmap-content-json.ts",
"migrate:editor-roadmaps": "tsx ./scripts/migrate-editor-roadmap.ts",
"sync:content-to-repo": "tsx ./scripts/sync-content-to-repo.ts",
"sync:repo-to-database": "tsx ./scripts/sync-repo-to-database.ts",
"migrate:content-repo-to-database": "tsx ./scripts/migrate-content-repo-to-database.ts",
"test:e2e": "playwright test"
},
"dependencies": {
"@ai-sdk/react": "2.0.0-beta.34",
"@astrojs/node": "^9.2.1",
"@astrojs/react": "^4.2.7",
"@astrojs/sitemap": "^3.4.0",
"@fingerprintjs/fingerprintjs": "^4.6.2",
"@microsoft/clarity": "^1.0.0",
"@nanostores/react": "^1.0.0",
"@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",
"@nanostores/react": "^0.7.2",
"@napi-rs/image": "^1.9.2",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-popover": "^1.1.14",
"@resvg/resvg-js": "^2.6.2",
"@roadmapsh/editor": "workspace:*",
"@shikijs/transformers": "^3.9.2",
"@tailwindcss/vite": "^4.1.7",
"@tanstack/react-query": "^5.76.1",
"@tiptap/core": "^2.12.0",
"@tiptap/extension-document": "^2.12.0",
"@tiptap/extension-paragraph": "^2.12.0",
"@tiptap/extension-placeholder": "^2.12.0",
"@tiptap/extension-text": "^2.12.0",
"@tiptap/pm": "^2.12.0",
"@tiptap/react": "^2.12.0",
"@tiptap/suggestion": "^2.12.0",
"@types/react": "^19.1.4",
"@types/react-dom": "^19.1.5",
"astro": "^5.7.13",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"astro": "^4.15.4",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"dayjs": "^1.11.12",
"dom-to-image": "^2.6.0",
"dracula-prism": "^2.1.16",
"gray-matter": "^4.0.3",
"htm": "^3.1.1",
"image-size": "^2.0.2",
"jose": "^6.0.11",
"image-size": "^1.1.1",
"jose": "^5.6.3",
"js-cookie": "^3.0.5",
"katex": "^0.16.22",
"lucide-react": "^0.511.0",
"luxon": "^3.6.1",
"markdown-it-async": "^2.2.0",
"nanoid": "^5.1.5",
"nanostores": "^1.0.1",
"node-html-parser": "^7.0.1",
"npm-check-updates": "^18.0.1",
"playwright": "^1.52.0",
"prismjs": "^1.30.0",
"radix-ui": "^1.4.2",
"react": "^19.1.0",
"react-calendar-heatmap": "^1.10.0",
"react-confetti": "^6.4.0",
"react-dom": "^19.1.0",
"react-dropzone": "^14.3.8",
"react-markdown": "^10.1.0",
"react-resizable-panels": "^3.0.2",
"react-textarea-autosize": "^8.5.9",
"react-tooltip": "^5.28.1",
"lucide-react": "^0.419.0",
"nanoid": "^5.0.7",
"nanostores": "^0.10.3",
"node-html-parser": "^6.1.13",
"npm-check-updates": "^17.0.0",
"playwright": "^1.45.3",
"prismjs": "^1.29.0",
"react": "^18.3.1",
"react-calendar-heatmap": "^1.9.0",
"react-confetti": "^6.1.0",
"react-dom": "^18.3.1",
"react-tooltip": "^5.27.1",
"reactflow": "^11.11.4",
"rehype-external-links": "^3.0.0",
"rehype-katex": "^7.0.1",
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"remark-parse": "^11.0.0",
"roadmap-renderer": "^1.0.7",
"sanitize-html": "^2.17.0",
"satori": "^0.13.1",
"roadmap-renderer": "^1.0.6",
"satori": "^0.10.14",
"satori-html": "^0.3.2",
"sharp": "^0.34.1",
"shiki": "^3.4.2",
"sharp": "^0.33.4",
"slugify": "^1.6.6",
"tailwind-merge": "^3.3.0",
"tailwindcss": "^4.1.7",
"tippy.js": "^6.3.7",
"tiptap-markdown": "^0.8.10",
"tailwind-merge": "^2.4.0",
"tailwindcss": "^3.4.7",
"turndown": "^7.2.0",
"unified": "^11.0.5",
"zod": "^4.0.17",
"zustand": "^5.0.4"
"zustand": "^4.5.4"
},
"devDependencies": {
"@ai-sdk/google": "^1.2.18",
"@playwright/test": "^1.52.0",
"@tailwindcss/typography": "^0.5.16",
"@playwright/test": "^1.45.3",
"@tailwindcss/typography": "^0.5.13",
"@types/dom-to-image": "^2.6.7",
"@types/js-cookie": "^3.0.6",
"@types/luxon": "^3.6.2",
"@types/markdown-it": "^14.1.2",
"@types/prismjs": "^1.26.5",
"@types/react-calendar-heatmap": "^1.9.0",
"@types/react-slick": "^0.23.13",
"@types/sanitize-html": "^2.16.0",
"@types/prismjs": "^1.26.4",
"@types/react-calendar-heatmap": "^1.6.7",
"@types/turndown": "^5.0.5",
"ai": "5.0.0-beta.34",
"csv-parser": "^3.2.0",
"gh-pages": "^6.3.0",
"csv-parser": "^3.0.0",
"gh-pages": "^6.1.1",
"js-yaml": "^4.1.0",
"markdown-it": "^14.1.0",
"openai": "^4.100.0",
"prettier": "^3.5.3",
"openai": "^4.53.2",
"prettier": "^3.3.3",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.6.11",
"tailwind-scrollbar": "^4.0.2",
"tsx": "^4.19.4"
"prettier-plugin-tailwindcss": "^0.6.5",
"tsx": "^4.16.5"
}
}

View File

8445
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
packages:
- packages/*

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 KiB

BIN
public/guides/ci-cd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

BIN
public/guides/dhcp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 KiB

BIN
public/guides/llms.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

BIN
public/guides/oauth.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
public/guides/sso.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 203 B

View File

Before

Width:  |  Height:  |  Size: 1021 B

After

Width:  |  Height:  |  Size: 1021 B

View File

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 405 KiB

After

Width:  |  Height:  |  Size: 405 KiB

View File

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 149 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 398 KiB

After

Width:  |  Height:  |  Size: 398 KiB

View File

Before

Width:  |  Height:  |  Size: 286 KiB

After

Width:  |  Height:  |  Size: 286 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

View File

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 137 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 119 KiB

View File

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 129 KiB

View File

Before

Width:  |  Height:  |  Size: 312 KiB

After

Width:  |  Height:  |  Size: 312 KiB

View File

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 99 KiB

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