From 451dad4d411c85352fdb15bc02c18809a0128c8a Mon Sep 17 00:00:00 2001 From: Yimiprod Date: Mon, 12 Feb 2024 16:11:01 +0100 Subject: [PATCH] feat(Instance)!: parser throw when default async is true and called with async at false BREAKING CHANGE: parser now throw an error when `defaultConfig` is modified by an extension to make the returned value a Promise and the we call parser with `async` option at false. It can be skipped with `silent` to true, making it still working for library that use it to modify the config globally but still calling each instance with the option `async` at false. --- src/Instance.ts | 4 ++-- src/MarkedOptions.ts | 4 ++-- test/types/marked.ts | 16 ++++++++++++++-- test/unit/marked.test.js | 20 +++++++++++++++++++- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/Instance.ts b/src/Instance.ts index 9b99cd56871..58fd1fdc6f1 100644 --- a/src/Instance.ts +++ b/src/Instance.ts @@ -273,10 +273,10 @@ export class Marked { const origOpt: MarkedOptions = { ...options }; const opt: MarkedOptions = { ...this.defaults, ...origOpt }; - // Show warning if an extension set async to true but the parse was called with async: false if (isAsyncOptions(this.defaults) && isSyncOptions(origOpt)) { + // Throw an error if an extension set async to true but the parse was called with 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.'); + throw new Error('marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored.'); } opt.async = true; diff --git a/src/MarkedOptions.ts b/src/MarkedOptions.ts index d1b73c779b1..8ad955d71e1 100644 --- a/src/MarkedOptions.ts +++ b/src/MarkedOptions.ts @@ -162,9 +162,9 @@ export interface MarkedAsyncOptions extends _MarkedOptions { export type MarkedOptions = MarkedSyncOptions | MarkedAsyncOptions; export function isAsyncOptions(options: MarkedOptions): options is MarkedAsyncOptions { - return 'async' in options && options.async === true; + return options.async === true; } export function isSyncOptions(options: MarkedOptions): options is MarkedSyncOptions { - return !isAsyncOptions(options); + return options.async === false; } diff --git a/test/types/marked.ts b/test/types/marked.ts index de2bd4bdd28..414b82d4d77 100644 --- a/test/types/marked.ts +++ b/test/types/marked.ts @@ -261,13 +261,25 @@ marked.use(asyncExtension); const md = '# foobar'; const asyncMarked: string = await marked(md, { async: true }); const promiseMarked: Promise = marked(md, { async: true }); -const notAsyncMarked: string = marked(md, { async: false }); +const notAsyncMarked: string = marked(md, { async: false, silent: true }); const defaultMarked: string = marked(md); const asyncMarkedParse: string = await marked.parse(md, { async: true }); const promiseMarkedParse: Promise = marked.parse(md, { async: true }); -const notAsyncMarkedParse: string = marked.parse(md, { async: false }); +const notAsyncMarkedParse: string = marked.parse(md, { async: false, silent: true }); const defaultMarkedParse: string = marked.parse(md); + +try { + const notAsyncMarkedThrow: string = marked(md, { async: false, silent: false }); +} catch { + console.log('expected throw'); +} + +try { + const notAsyncMarkedParseThrow: string = marked.parse(md, { async: false, silent: false }); +} catch { + console.log('expected throw'); +} })(); // Tests for List and ListItem diff --git a/test/unit/marked.test.js b/test/unit/marked.test.js index c9c0925a128..9bc1faaccdd 100644 --- a/test/unit/marked.test.js +++ b/test/unit/marked.test.js @@ -632,7 +632,25 @@ used extension2 walked

it('should return Promise if async is set by extension', () => { marked.use({ async: true }); - assert.ok(marked.parse('test', { async: false }) instanceof Promise); + assert.ok(marked.parse('test') instanceof Promise); + }); + + it('should throw an if async is set by extension and a different async parameter is set', () => { + marked.use({ async: true }); + + assert.throws(() => marked.parse('test', { async: false }), /The async option was set to true by an extension/); + }); + + it('should not throw an if async is set by extension and a different async parameter is set and the silent parameter is set', () => { + marked.use({ async: true }); + + assert.doesNotThrow(() => marked.parse('test', { async: false, silent: true }), /The async option was set to true by an extension/); + }); + + it('should return a Promise if async is set by extension and a different async parameter is set and the silent parameter is set', () => { + marked.use({ async: true }); + + assert.ok(marked.parse('test', { async: false, silent: true }) instanceof Promise); }); it('should allow deleting/editing tokens', () => {