mirror of
https://github.com/markedjs/marked
synced 2024-11-22 00:05:53 +00:00
fix: allow async option to dictate type returned (#3341)
BREAKING CHANGE: throw an error if `async: false` is set when an extension sets `async: true`
This commit is contained in:
parent
ead7af34a5
commit
b5a50041ae
@ -21,8 +21,8 @@ export class Marked {
|
||||
defaults = _getDefaults();
|
||||
options = this.setOptions;
|
||||
|
||||
parse = this.#parseMarkdown(_Lexer.lex, _Parser.parse);
|
||||
parseInline = this.#parseMarkdown(_Lexer.lexInline, _Parser.parseInline);
|
||||
parse = this.parseMarkdown(_Lexer.lex, _Parser.parse);
|
||||
parseInline = this.parseMarkdown(_Lexer.lexInline, _Parser.parseInline);
|
||||
|
||||
Parser = _Parser;
|
||||
Renderer = _Renderer;
|
||||
@ -514,22 +514,25 @@ export class Marked {
|
||||
return _Parser.parse(tokens, options ?? this.defaults);
|
||||
}
|
||||
|
||||
#parseMarkdown(lexer: (src: string, options?: MarkedOptions) => TokensList | Token[], parser: (tokens: Token[], options?: MarkedOptions) => string) {
|
||||
return (src: string, options?: MarkedOptions | undefined | null): string | Promise<string> => {
|
||||
private parseMarkdown(lexer: (src: string, options?: MarkedOptions) => TokensList | Token[], parser: (tokens: Token[], options?: MarkedOptions) => string) {
|
||||
type overloadedParse = {
|
||||
(src: string, options: MarkedOptions & { async: true }): Promise<string>;
|
||||
(src: string, options: MarkedOptions & { async: false }): string;
|
||||
(src: string, options?: MarkedOptions | undefined | null): string | Promise<string>;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const parse: overloadedParse = (src: string, options?: MarkedOptions | undefined | null): any => {
|
||||
const origOpt = { ...options };
|
||||
const opt = { ...this.defaults, ...origOpt };
|
||||
|
||||
// Show warning if an extension set async to true but the parse was called with async: false
|
||||
const throwError = this.onError(!!opt.silent, !!opt.async);
|
||||
|
||||
// throw error if an extension set async to true but parse was called with async: false
|
||||
if (this.defaults.async === true && origOpt.async === false) {
|
||||
if (!opt.silent) {
|
||||
console.warn('marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored.');
|
||||
}
|
||||
|
||||
opt.async = true;
|
||||
return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));
|
||||
}
|
||||
|
||||
const throwError = this.#onError(!!opt.silent, !!opt.async);
|
||||
|
||||
// throw error in case of non string input
|
||||
if (typeof src === 'undefined' || src === null) {
|
||||
return throwError(new Error('marked(): input parameter is undefined or null'));
|
||||
@ -573,9 +576,11 @@ export class Marked {
|
||||
return throwError(e as Error);
|
||||
}
|
||||
};
|
||||
|
||||
return parse;
|
||||
}
|
||||
|
||||
#onError(silent: boolean, async: boolean) {
|
||||
private onError(silent: boolean, async: boolean) {
|
||||
return (e: Error): string | Promise<string> => {
|
||||
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
||||
|
||||
|
@ -32,8 +32,10 @@ export function marked(src: string, options: MarkedOptions & { async: true }): P
|
||||
* @param options Optional hash of options
|
||||
* @return String of compiled HTML. Will be a Promise of string if async is set to true by any extensions.
|
||||
*/
|
||||
export function marked(src: string, options?: MarkedOptions): string | Promise<string>;
|
||||
export function marked(src: string, opt?: MarkedOptions): string | Promise<string> {
|
||||
export function marked(src: string, options: MarkedOptions & { async: false }): string;
|
||||
export function marked(src: string, options: MarkedOptions & { async: true }): Promise<string>;
|
||||
export function marked(src: string, options?: MarkedOptions | undefined | null): string | Promise<string>;
|
||||
export function marked(src: string, opt?: MarkedOptions | undefined | null): string | Promise<string> {
|
||||
return markedInstance.parse(src, opt);
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,6 @@ marked.use(asyncExtension);
|
||||
const md = '# foobar';
|
||||
const asyncMarked: string = await marked(md, { async: true });
|
||||
const promiseMarked: Promise<string> = marked(md, { async: true });
|
||||
// @ts-expect-error marked can still be async if an extension sets `async: true`
|
||||
const notAsyncMarked: string = marked(md, { async: false });
|
||||
// @ts-expect-error marked can still be async if an extension sets `async: true`
|
||||
const defaultMarked: string = marked(md);
|
||||
@ -270,7 +269,6 @@ const stringMarked: string = marked(md) as string;
|
||||
|
||||
const asyncMarkedParse: string = await marked.parse(md, { async: true });
|
||||
const promiseMarkedParse: Promise<string> = marked.parse(md, { async: true });
|
||||
// @ts-expect-error marked can still be async if an extension sets `async: true`
|
||||
const notAsyncMarkedParse: string = marked.parse(md, { async: false });
|
||||
// @ts-expect-error marked can still be async if an extension sets `async: true`
|
||||
const defaultMarkedParse: string = marked.parse(md);
|
||||
|
@ -630,10 +630,10 @@ used extension2 walked</p>
|
||||
assert.strictEqual(typeof marked.parse('test', { async: false }), 'string');
|
||||
});
|
||||
|
||||
it('should return Promise if async is set by extension', () => {
|
||||
it('should throw an error if async is set by extension', () => {
|
||||
marked.use({ async: true });
|
||||
|
||||
assert.ok(marked.parse('test', { async: false }) instanceof Promise);
|
||||
assert.throws(() => marked.parse('test', { async: false }));
|
||||
});
|
||||
|
||||
it('should allow deleting/editing tokens', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user