From 6899df23ea1ca4c117e3719fd3a47dffd96057bd Mon Sep 17 00:00:00 2001 From: Puru Vijay Date: Fri, 14 Apr 2023 22:26:06 +0530 Subject: [PATCH] Get type links working --- sites/svelte.dev/.gitignore | 1 - sites/svelte.dev/scripts/type-gen/index.js | 23 ----- sites/svelte.dev/src/lib/server/docs/index.js | 95 +++++++++++++------ .../svelte.dev/src/lib/server/docs/render.js | 7 +- 4 files changed, 66 insertions(+), 60 deletions(-) diff --git a/sites/svelte.dev/.gitignore b/sites/svelte.dev/.gitignore index 557b7ffc1c..dcbe6ef26f 100644 --- a/sites/svelte.dev/.gitignore +++ b/sites/svelte.dev/.gitignore @@ -12,4 +12,3 @@ .vercel examples-data.js type-info.js -.snippets \ No newline at end of file diff --git a/sites/svelte.dev/scripts/type-gen/index.js b/sites/svelte.dev/scripts/type-gen/index.js index 37a95f9c97..c9b700b7c9 100644 --- a/sites/svelte.dev/scripts/type-gen/index.js +++ b/sites/svelte.dev/scripts/type-gen/index.js @@ -206,17 +206,6 @@ const bundled_types = await get_bundled_types(); }); } -{ - const module = bundled_types.get('svelte/runtime'); - - if (!module) throw new Error('Could not find svelte/runtime'); - - modules.push({ - name: 'svelte/runtime', - comment: '', - ...get_types(module.code, module.ts_source_file.statements) - }); -} { const module = bundled_types.get('svelte/action'); @@ -289,18 +278,6 @@ const bundled_types = await get_bundled_types(); }); } -{ - const module = bundled_types.get('svelte/internal'); - - if (!module) throw new Error('Could not find svelte/internal'); - - modules.push({ - name: 'svelte/internal', - comment: '', - ...get_types(module.code, module.ts_source_file.statements) - }); -} - // const dir = fileURLToPath( // new URL('../../../../packages/kit/types/synthetic', import.meta.url).href // ); diff --git a/sites/svelte.dev/src/lib/server/docs/index.js b/sites/svelte.dev/src/lib/server/docs/index.js index 29c3d1630c..62633d813e 100644 --- a/sites/svelte.dev/src/lib/server/docs/index.js +++ b/sites/svelte.dev/src/lib/server/docs/index.js @@ -1,19 +1,44 @@ -import { createShikiHighlighter, renderCodeToHTML, runTwoSlash } from 'shiki-twoslash'; -import { SHIKI_LANGUAGE_MAP, escape, normalizeSlugify, transform } from '../markdown'; -import { replace_placeholders } from './render.js'; -// import { parse_route_id } from '../../../../../../packages/kit/src/utils/routing.js'; +import { modules } from '$lib/generated/type-info'; import { createHash } from 'crypto'; import fs from 'fs'; import MagicString from 'magic-string'; +import { createShikiHighlighter, renderCodeToHTML, runTwoSlash } from 'shiki-twoslash'; import ts from 'typescript'; +import { SHIKI_LANGUAGE_MAP, escape, normalizeSlugify, slugify, transform } from '../markdown'; +import { replace_placeholders } from './render.js'; -const FILE_METADATA_REGEX = /(?:)|\/\/\/\s*file:\s*(.*?)(?:$))/i; +const METADATA_REGEX = /(?:|\/\/\/\s*([\w-]+):\s*(.*))\n/gm; -const snippet_cache = new URL('../../../../.snippets', import.meta.url).pathname; +const snippet_cache = new URL('../../../../node_modules/.snippets', import.meta.url).pathname; if (!fs.existsSync(snippet_cache)) { fs.mkdirSync(snippet_cache, { recursive: true }); } +const type_regex = new RegExp( + `(import\\('svelte'\\)\\.)?\\b(${modules + .flatMap((module) => module.types) + .map((type) => type.name) + .join('|')})\\b`, + 'g' +); + +const type_links = new Map(); + +// const slugs = { +// '@sveltejs/kit': 'public-types' +// }; + +modules.forEach((module) => { + const slug = slugify(module.name); + + module.types.forEach((type) => { + const link = `/docs/${slug}#type-${slugify(type.name)}`; + type_links.set(type.name, link); + }); +}); + +console.log(type_links); + /** * @param {import('./types').DocsData} docs_data * @param {string} slug @@ -39,9 +64,11 @@ export async function get_parsed_docs(docs_data, slug) { hash.update(source + language + current); const digest = hash.digest().toString('base64').replace(/\//g, '-'); - if (fs.existsSync(`${snippet_cache}/${digest}.html`)) { - return fs.readFileSync(`${snippet_cache}/${digest}.html`, 'utf-8'); - } + try { + if (fs.existsSync(`${snippet_cache}/${digest}.html`)) { + return fs.readFileSync(`${snippet_cache}/${digest}.html`, 'utf-8'); + } + } catch {} /** @type {Record} */ const options = {}; @@ -89,9 +116,6 @@ export async function get_parsed_docs(docs_data, slug) { try { const injected = []; - // For the snippets that are not proper JS or TS - // if (!source.includes('import')) injected.push('// @errors: 2552 1005 1109 2304'); - if (source.includes('svelte')) { injected.push( `// @filename: ambient.d.ts`, @@ -192,18 +216,21 @@ export async function get_parsed_docs(docs_data, slug) { html = html.replace(/class=('|")/, `class=$1${version_class} `); } - // type_regex.lastIndex = 0; + type_regex.lastIndex = 0; + + console.log(html); html = html - // .replace(type_regex, (match, prefix, name) => { - // if (options.link === 'false' || name === current) { - // // we don't want e.g. RequestHandler to link to RequestHandler - // return match; - // } - - // const link = `${name}`; - // return `${prefix || ''}${link}`; - // }) + .replace(type_regex, (match, prefix, name) => { + console.log(2); + if (options.link === 'false' || name === current) { + // we don't want e.g. RequestHandler to link to RequestHandler + return match; + } + + const link = `${name}`; + return `${prefix || ''}${link}`; + }) .replace( /^(\s+)([\s\S]+?)<\/span>\n/gm, (match, intro_whitespace, content) => { @@ -229,11 +256,12 @@ export async function get_parsed_docs(docs_data, slug) { codespan: (text) => { return ( '' + - text + - // text.replace(type_regex, (match, prefix, name) => { - // const link = `${name}`; - // return `${prefix || ''}${link}`; - // }) + + text.replace(type_regex, (match, prefix, name) => { + console.log(prefix); + console.log(1); + const link = `${name}`; + return `${prefix || ''}${link}`; + }) + '' ); } @@ -276,9 +304,16 @@ function parse({ body, code, codespan }) { headings[level] = normalized; headings.length = level; - const slug = normalizeSlugify(raw); + const type_heading_match = /^\[TYPE\]:\s+(.+)/.exec(raw); - return `${html}`; + const slug = normalizeSlugify(type_heading_match ? `type-${type_heading_match[1]}` : raw); + + return `${html + .replace(/<\/?code>/g, '') + .replace( + /^\[TYPE\]:\s+(.+)/, + '$1' + )}`; }, code: (source, language) => code(source, language, current), codespan @@ -310,7 +345,7 @@ export function generate_ts_from_js(markdown) { return match.replace('js', 'original-js') + '\n```generated-ts\n' + ts + '\n```'; }) .replaceAll(/```svelte\n([\s\S]+?)\n```/g, (match, code) => { - if (!FILE_METADATA_REGEX.test(code)) { + if (!METADATA_REGEX.test(code)) { // No named file -> assume that the code is not meant to be shown in two versions return match; } diff --git a/sites/svelte.dev/src/lib/server/docs/render.js b/sites/svelte.dev/src/lib/server/docs/render.js index b219937052..c61eb940d5 100644 --- a/sites/svelte.dev/src/lib/server/docs/render.js +++ b/sites/svelte.dev/src/lib/server/docs/render.js @@ -51,14 +51,9 @@ export function replace_placeholders(content) { return `${module.comment}\n\n${module.types .map((t) => { let children = t.children.map(stringify).join('\n\n'); - if (t.name === 'Config' || t.name === 'KitConfig') { - // special case — we want these to be on a separate page - children = - '
\n\nSee the [configuration reference](/docs/configuration) for details.
'; - } const markdown = `
${fence(t.snippet)}` + children + `
`; - return `### ${t.name}\n\n${t.comment}\n\n${markdown}\n\n`; + return `### [TYPE]: ${t.name}\n\n${t.comment}\n\n${markdown}\n\n`; }) .join('')}`; })