1- import { createJavaScriptRegexEngine } from '@shikijs/engine-javascript' ;
2- import { createOnigurumaEngine } from '@shikijs/engine-oniguruma' ;
3- import { transformerTwoslash } from '@shikijs/twoslash' ;
1+ // Keep all imports at the top
42import cLanguage from 'shiki/langs/c.mjs' ;
53import coffeeScriptLanguage from 'shiki/langs/coffeescript.mjs' ;
64import cPlusPlusLanguage from 'shiki/langs/cpp.mjs' ;
@@ -16,57 +14,93 @@ import shellSessionLanguage from 'shiki/langs/shellsession.mjs';
1614import typeScriptLanguage from 'shiki/langs/typescript.mjs' ;
1715import yamlLanguage from 'shiki/langs/yaml.mjs' ;
1816
19- import { createHighlighter } from './highlighter.mjs' ;
17+ import createHighlighter , { getLanguageByName } from './highlighter.mjs' ;
2018
21- const { shiki, getLanguageDisplayName, highlightToHast, highlightToHtml } =
22- createHighlighter ( {
23- transformers : [
19+ /**
20+ * @typedef {Object } HighlighterOptions
21+ * @property {boolean|Object } [wasm=false] - WebAssembly options for the regex engine
22+ * @property {boolean|Object } [twoslash=false] - Twoslash configuration options
23+ * @param {import('@shikijs/core').HighlighterCoreOptions } [coreOptions] - Core options for the highlighter.
24+ * @param {import('@shikijs/core').CodeToHastOptions } [highlighterOptions] - Additional options for highlighting.
25+ */
26+
27+ /**
28+ * Creates the appropriate regex engine based on configuration
29+ * @param {HighlighterOptions } options - Configuration options
30+ */
31+ async function getEngine ( { wasm = false } ) {
32+ if ( wasm ) {
33+ const { createJavaScriptRegexEngine } = await import (
34+ '@shikijs/engine-javascript'
35+ ) ;
36+ return createJavaScriptRegexEngine ( ) ;
37+ }
38+
39+ const { createOnigurumaEngine } = await import ( '@shikijs/engine-oniguruma' ) ;
40+ return createOnigurumaEngine (
41+ typeof wasm === 'boolean' ? await import ( 'shiki/wasm' ) : wasm
42+ ) ;
43+ }
44+
45+ /**
46+ * Configures and returns transformers based on options
47+ * @param {HighlighterOptions } options - Configuration options
48+ */
49+ async function getTransformers ( { twoslash = false } ) {
50+ const transformers = [ ] ;
51+
52+ if ( twoslash ) {
53+ const { transformerTwoslash } = await import ( '@shikijs/twoslash' ) ;
54+
55+ transformers . push (
2456 transformerTwoslash ( {
2557 langs : [ 'ts' , 'js' , 'cjs' , 'mjs' ] ,
26- // Don't show JSDoc
27- rendererRich : {
28- jsdoc : false ,
29- } ,
30- // Don't throw on errors on untype-able code
58+ rendererRich : { jsdoc : false } ,
3159 throws : false ,
32- } ) ,
33- ] ,
34- // We use the faster WASM engine on the server instead of the web-optimized version.
35- //
36- // Currently we fall back to the JavaScript RegEx engine
37- // on Cloudflare workers because `shiki/wasm` requires loading via
38- // `WebAssembly.instantiate` with custom imports, which Cloudflare doesn't support
39- // for security reasons.
40- //
41- // TODO(@avivkeller): When available, use `OPEN_NEXT_CLOUDFLARE` environment
42- // variable for detection instead of current method, which will enable better
43- // tree-shaking.
44- // Reference: https://github.com/nodejs/nodejs.org/pull/7896#issuecomment-3009480615
45- engine :
46- 'Cloudflare' in globalThis
47- ? createJavaScriptRegexEngine ( )
48- : await createOnigurumaEngine ( import ( 'shiki/wasm' ) ) ,
49- langs : [
50- ...cLanguage ,
51- ...coffeeScriptLanguage ,
52- ...cPlusPlusLanguage ,
53- ...diffLanguage ,
54- ...dockerLanguage ,
55- ...httpLanguage ,
56- ...iniLanguage ,
57- {
58- ...javaScriptLanguage [ 0 ] ,
59- // We patch the JavaScript language to include the CommonJS and ES Module aliases
60- // that are commonly used (non-standard aliases) within our API docs and Blog posts
61- aliases : javaScriptLanguage [ 0 ] . aliases . concat ( 'cjs' , 'mjs' ) ,
62- } ,
63- ...jsonLanguage ,
64- ...powershellLanguage ,
65- ...shellScriptLanguage ,
66- ...shellSessionLanguage ,
67- ...typeScriptLanguage ,
68- ...yamlLanguage ,
69- ] ,
70- } ) ;
60+ ...( typeof twoslash === 'object' ? twoslash : { } ) ,
61+ } )
62+ ) ;
63+ }
64+
65+ return transformers ;
66+ }
67+
68+ export const LANGS = [
69+ ...cLanguage ,
70+ ...coffeeScriptLanguage ,
71+ ...cPlusPlusLanguage ,
72+ ...diffLanguage ,
73+ ...dockerLanguage ,
74+ ...httpLanguage ,
75+ ...iniLanguage ,
76+ {
77+ ...javaScriptLanguage [ 0 ] ,
78+ aliases : javaScriptLanguage [ 0 ] . aliases . concat ( 'cjs' , 'mjs' ) ,
79+ } ,
80+ ...jsonLanguage ,
81+ ...powershellLanguage ,
82+ ...shellScriptLanguage ,
83+ ...shellSessionLanguage ,
84+ ...typeScriptLanguage ,
85+ ...yamlLanguage ,
86+ ] ;
7187
72- export { shiki , getLanguageDisplayName , highlightToHast , highlightToHtml } ;
88+ export const getLanguageDisplayName = language =>
89+ getLanguageByName ( language , LANGS ) ?. displayName ?? language ;
90+
91+ /**
92+ * Creates and configures a syntax highlighter
93+ * @param {HighlighterOptions } options - Configuration options
94+ */
95+ export default async ( options = { } ) =>
96+ createHighlighter ( {
97+ coreOptions : {
98+ ...options . coreOptions ,
99+ langs : LANGS ,
100+ engine : await getEngine ( options ) ,
101+ } ,
102+ highlighterOptions : {
103+ ...options . highlighterOptions ,
104+ transformers : await getTransformers ( options ) ,
105+ } ,
106+ } ) ;
0 commit comments