Skip to content

Commit 3dca076

Browse files
authored
Merge pull request #69 from retejs/fix/node-compatibility
fix(ai): improve markdown-to-ansi dynamic import handling
2 parents 0bdf4ee + 31ba7f9 commit 3dca076

2 files changed

Lines changed: 32 additions & 5 deletions

File tree

src/ai/guidance.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@ import { join } from 'path'
44
import { assetsAI } from '../consts'
55
import { logger } from './logger'
66

7+
/**
8+
* Type definition for markdown-to-ansi converter function.
9+
* Takes markdown text and returns ANSI-formatted string.
10+
*/
11+
type MarkdownConverter = (text: string) => string
12+
13+
/**
14+
* Type definition for markdown-to-ansi factory function.
15+
* Returns a converter function when called.
16+
*/
17+
type MarkdownToAnsiFactory = () => MarkdownConverter
18+
19+
/**
20+
* Type definition for the markdown-to-ansi module.
21+
* Can export the factory as default or as the module itself.
22+
*/
23+
type MarkdownToAnsiModule = {
24+
default?: MarkdownToAnsiFactory
25+
} & MarkdownToAnsiFactory
26+
727
/**
828
* Loads and formats the guidance message from markdown file for terminal display.
929
* Converts markdown formatting (bold, italic, code, etc.) to ANSI escape codes.
@@ -18,12 +38,18 @@ async function getGuidance(): Promise<string> {
1838

1939
/*
2040
* Dynamic import is used because markdown-to-ansi is an ES module.
21-
* When compiled to CommonJS, static imports would be transformed to require(),
22-
* which doesn't work for ES modules in Node.js 18 and below.
41+
* When compiled to CommonJS, TypeScript transforms import() to require(),
42+
* which doesn't work for ES modules in Node.js 16 and 18.
43+
* Using Function constructor prevents TypeScript from transforming the import.
2344
*/
24-
const markdownToAnsiModule = await import('markdown-to-ansi')
25-
const markdownToAnsiFactory = markdownToAnsiModule.default ?? markdownToAnsiModule
26-
const converter = markdownToAnsiFactory()
45+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
46+
const dynamicImport = new Function('specifier', 'return import(specifier)') as (
47+
specifier: string
48+
) => Promise<MarkdownToAnsiModule>
49+
const markdownToAnsiModule = await dynamicImport('markdown-to-ansi')
50+
const markdownToAnsiFactory: MarkdownToAnsiFactory = markdownToAnsiModule.default ?? markdownToAnsiModule
51+
// markdown-to-ansi exports a factory function that returns a converter function
52+
const converter: MarkdownConverter = markdownToAnsiFactory()
2753
// Convert markdown to ANSI-formatted terminal text (supports bold, italic, code, etc.)
2854

2955
return converter(guidanceTemplate).trim()

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ program
107107
} catch (error) {
108108
if (error instanceof GuidanceError) {
109109
const guidance = await error.guidance
110+
110111
if (guidance) {
111112
console.log() // Add spacing before guidance
112113
logger.info(guidance)

0 commit comments

Comments
 (0)