From 5d9a5bd05c411b76b380f972f268856855a0c42c Mon Sep 17 00:00:00 2001 From: Arik Chakma Date: Mon, 19 May 2025 21:31:03 +0600 Subject: [PATCH] chore: update official roadmap endpoint (#8628) * chore: update official roadmap endpoint * fix: variable typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pnpm-lock.yaml | 8 ---- scripts/editor-roadmap-content-json.ts | 24 ++++++----- scripts/editor-roadmap-content.ts | 20 +++++---- scripts/editor-roadmap-dirs.ts | 18 ++++---- .../EditorRoadmap/EditorRoadmap.tsx | 4 +- .../TeamProgress/MemberProgressModal.tsx | 42 +++++++++---------- .../UserProgress/UserProgressModal.tsx | 4 +- .../UserProfileRoadmapRenderer.tsx | 4 +- src/queries/official-roadmap.ts | 23 ++++++++++ 9 files changed, 87 insertions(+), 60 deletions(-) create mode 100644 src/queries/official-roadmap.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b117f313b..8ef01a5bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -261,9 +261,6 @@ importers: tailwind-merge: specifier: ^3.2.0 version: 3.2.0 - tinykeys: - specifier: ^3.0.0 - version: 3.0.0 unified: specifier: ^11.0.5 version: 11.0.5 @@ -3485,9 +3482,6 @@ packages: resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} engines: {node: '>=12.0.0'} - tinykeys@3.0.0: - resolution: {integrity: sha512-nazawuGv5zx6MuDfDY0rmfXjuOGhD5XU2z0GLURQ1nzl0RUe9OuCJq+0u8xxJZINHe+mr7nw8PWYYZ9WhMFujw==} - tiptap-markdown@0.8.10: resolution: {integrity: sha512-iDVkR2BjAqkTDtFX0h94yVvE2AihCXlF0Q7RIXSJPRSR5I0PA1TMuAg6FHFpmqTn4tPxJ0by0CK7PUMlnFLGEQ==} peerDependencies: @@ -7306,8 +7300,6 @@ snapshots: fdir: 6.4.4(picomatch@4.0.2) picomatch: 4.0.2 - tinykeys@3.0.0: {} - tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)): dependencies: '@tiptap/core': 2.12.0(@tiptap/pm@2.12.0) diff --git a/scripts/editor-roadmap-content-json.ts b/scripts/editor-roadmap-content-json.ts index 229337004..4790c970e 100644 --- a/scripts/editor-roadmap-content-json.ts +++ b/scripts/editor-roadmap-content-json.ts @@ -8,6 +8,7 @@ import { slugify } from '../src/lib/slugger'; import { markdownToHtml } from '../src/lib/markdown'; import { HTMLElement, parse } from 'node-html-parser'; import { htmlToMarkdown } from '../src/lib/html'; +import { httpGet } from '../src/lib/http'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -53,13 +54,16 @@ if (!stats || !stats.isDirectory()) { for (const roadmapId of editorRoadmapIds) { console.log(`🚀 Starting ${roadmapId}`); - const roadmapDir = path.join( - ROADMAP_CONTENT_DIR, - roadmapId, - `${roadmapId}.json`, + const { response: data, error } = await httpGet( + `${import.meta.env.PUBLIC_API_URL}/v1-official-roadmap/${roadmapId}`, ); - const roadmapContent = await fs.readFile(roadmapDir, 'utf-8'); - let { nodes } = JSON.parse(roadmapContent) as { + + if (error) { + console.error(error); + continue; + } + + let { nodes } = data as { nodes: Node[]; }; nodes = nodes.filter( @@ -97,11 +101,11 @@ for (const roadmapId of editorRoadmapIds) { > = {}; for (const node of nodes) { - const ndoeDirPatterWithoutExt = `${slugify(node.data.label)}@${node.id}`; - const nodeDirPattern = `${ndoeDirPatterWithoutExt}.md`; + const nodeDirPatternWithoutExt = `${slugify(node?.data?.label as string)}@${node.id}`; + const nodeDirPattern = `${nodeDirPatternWithoutExt}.md`; if (!roadmapContentFiles.includes(nodeDirPattern)) { contentMap[nodeDirPattern] = { - title: node.data.label, + title: node?.data?.label as string, description: '', links: [], }; @@ -169,7 +173,7 @@ for (const roadmapId of editorRoadmapIds) { const description = htmlToMarkdown(htmlStringWithoutLinks); contentMap[node.id] = { - title: node.data.label, + title: node.data.label as string, description, links: listLinks, }; diff --git a/scripts/editor-roadmap-content.ts b/scripts/editor-roadmap-content.ts index 6877179bc..4c16676fe 100644 --- a/scripts/editor-roadmap-content.ts +++ b/scripts/editor-roadmap-content.ts @@ -7,6 +7,7 @@ import type { RoadmapFrontmatter } from '../src/lib/roadmap'; import { slugify } from '../src/lib/slugger'; import OpenAI from 'openai'; import { runPromisesInBatchSequentially } from '../src/lib/promise'; +import { httpGet } from '../src/lib/http'; // ERROR: `__dirname` is not defined in ES module scope // https://iamwebwiz.medium.com/how-to-fix-dirname-is-not-defined-in-es-module-scope-34d94a86694d @@ -50,13 +51,16 @@ if (roadmapFrontmatter.renderer !== 'editor') { process.exit(1); } -const roadmapDir = path.join( - ROADMAP_CONTENT_DIR, - roadmapId, - `${roadmapId}.json`, +const { response: roadmapContent, error } = await httpGet( + `${import.meta.env.PUBLIC_API_URL}/v1-official-roadmap/${roadmapId}`, ); -const roadmapContent = await fs.readFile(roadmapDir, 'utf-8'); -let { nodes, edges } = JSON.parse(roadmapContent) as { + +if (error) { + console.error(error); + process.exit(1); +} + +let { nodes, edges } = roadmapContent as { nodes: Node[]; edges: Edge[]; }; @@ -138,7 +142,7 @@ function writeTopicContent( } async function writeNodeContent(node: Node & { parentTitle?: string }) { - const nodeDirPattern = `${slugify(node.data.label)}@${node.id}.md`; + const nodeDirPattern = `${slugify(node?.data?.label as string)}@${node.id}.md`; if (!roadmapContentFiles.includes(nodeDirPattern)) { console.log(`Missing file for: ${nodeDirPattern}`); return; @@ -152,7 +156,7 @@ async function writeNodeContent(node: Node & { parentTitle?: string }) { return; } - const topic = node.data.label; + const topic = node.data.label as string; const parentTopic = node.parentTitle; console.log(`⏳ Generating content for ${topic}...`); diff --git a/scripts/editor-roadmap-dirs.ts b/scripts/editor-roadmap-dirs.ts index b1f0ebc2c..2f02320e0 100644 --- a/scripts/editor-roadmap-dirs.ts +++ b/scripts/editor-roadmap-dirs.ts @@ -5,6 +5,7 @@ import type { Node } from '@roadmapsh/editor'; import matter from 'gray-matter'; import type { RoadmapFrontmatter } from '../src/lib/roadmap'; import { slugify } from '../src/lib/slugger'; +import { httpGet } from '../src/lib/http'; // ERROR: `__dirname` is not defined in ES module scope // https://iamwebwiz.medium.com/how-to-fix-dirname-is-not-defined-in-es-module-scope-34d94a86694d @@ -48,13 +49,16 @@ if (roadmapFrontmatter.renderer !== 'editor') { process.exit(1); } -const roadmapDir = path.join( - ROADMAP_CONTENT_DIR, - roadmapId, - `${roadmapId}.json`, +const { response: roadmapContent, error } = await httpGet( + `${import.meta.env.PUBLIC_API_URL}/v1-official-roadmap/${roadmapId}`, ); -const roadmapContent = await fs.readFile(roadmapDir, 'utf-8'); -let { nodes } = JSON.parse(roadmapContent) as { + +if (error) { + console.error(error); + process.exit(1); +} + +let { nodes } = roadmapContent as { nodes: Node[]; }; nodes = nodes.filter( @@ -73,7 +77,7 @@ const roadmapContentFiles = await fs.readdir(roadmapContentDir, { }); nodes.forEach(async (node, index) => { - const nodeDirPattern = `${slugify(node.data.label)}@${node.id}.md`; + const nodeDirPattern = `${slugify(node.data.label as string)}@${node.id}.md`; if (roadmapContentFiles.includes(nodeDirPattern)) { console.log(`Skipping ${nodeDirPattern}`); return; diff --git a/src/components/EditorRoadmap/EditorRoadmap.tsx b/src/components/EditorRoadmap/EditorRoadmap.tsx index f34599b86..1a0df65a9 100644 --- a/src/components/EditorRoadmap/EditorRoadmap.tsx +++ b/src/components/EditorRoadmap/EditorRoadmap.tsx @@ -36,7 +36,9 @@ export function EditorRoadmap(props: EditorRoadmapProps) { const { response, error } = await httpGet< Omit - >(`/${switchRoadmapId || resourceId}.json`); + >( + `${import.meta.env.PUBLIC_API_URL}/v1-official-roadmap/${switchRoadmapId || resourceId}`, + ); if (error) { console.error(error); diff --git a/src/components/TeamProgress/MemberProgressModal.tsx b/src/components/TeamProgress/MemberProgressModal.tsx index 64c15eeae..5f312e7c9 100644 --- a/src/components/TeamProgress/MemberProgressModal.tsx +++ b/src/components/TeamProgress/MemberProgressModal.tsx @@ -62,15 +62,6 @@ export function MemberProgressModal(props: ProgressMapProps) { const toast = useToast(); const [renderer, setRenderer] = useState('balsamiq'); - let resourceJsonUrl = import.meta.env.DEV - ? 'http://localhost:3000' - : 'https://roadmap.sh'; - if (resourceType === 'roadmap') { - resourceJsonUrl += `/${resourceId}.json`; - } else { - resourceJsonUrl += `/best-practices/${resourceId}.json`; - } - async function getMemberProgress( teamId: string, memberId: string, @@ -92,7 +83,7 @@ export function MemberProgressModal(props: ProgressMapProps) { return response; } - async function renderResource(jsonUrl: string) { + async function renderResource() { const page = await getResourceMeta(resourceType, resourceId); if (!page) { toast.error('Resource not found'); @@ -102,11 +93,22 @@ export function MemberProgressModal(props: ProgressMapProps) { const renderer = page.renderer || 'balsamiq'; setRenderer(renderer); - const res = await fetch(jsonUrl, {}); + let resourceJsonUrl = import.meta.env.DEV + ? 'http://localhost:3000' + : 'https://roadmap.sh'; + if (resourceType === 'roadmap' && renderer === 'balsamiq') { + resourceJsonUrl += `/${resourceId}.json`; + } else if (resourceType === 'roadmap' && renderer === 'editor') { + resourceJsonUrl = `${import.meta.env.PUBLIC_API_URL}/v1-official-roadmap/${resourceId}`; + } else { + resourceJsonUrl += `/best-practices/${resourceId}.json`; + } + + const res = await fetch(resourceJsonUrl, {}); const json = await res.json(); const svg = renderer === 'editor' - ? await renderFlowJSON(json as any) + ? await renderFlowJSON(json) : await wireframeJSONToSVG(json, { fontURL: '/fonts/balsamiq.woff2', }); @@ -129,19 +131,13 @@ export function MemberProgressModal(props: ProgressMapProps) { }); useEffect(() => { - if ( - !containerEl.current || - !resourceJsonUrl || - !resourceId || - !resourceType || - !teamId - ) { + if (!containerEl.current || !resourceId || !resourceType || !teamId) { return; } setIsLoading(true); Promise.all([ - renderResource(resourceJsonUrl), + renderResource(), getMemberProgress(teamId, member._id, resourceType, resourceId), ]) .then(([_, memberProgress = {}]) => { @@ -276,7 +272,7 @@ export function MemberProgressModal(props: ProgressMapProps) { }, [member]); return ( -
+
)}