Skip to content

Commit

Permalink
feat(Instance)!: parser throw when default async is true and called w…
Browse files Browse the repository at this point in the history
…ith 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.
  • Loading branch information
Yimiprod committed Feb 12, 2024
1 parent b81660a commit 1e602f2
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/Instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/MarkedOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
16 changes: 14 additions & 2 deletions test/types/marked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,25 @@ marked.use(asyncExtension);
const md = '# foobar';
const asyncMarked: string = await marked(md, { async: true });
const promiseMarked: Promise<string> = 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<string> = 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
Expand Down
20 changes: 19 additions & 1 deletion test/unit/marked.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,25 @@ used extension2 walked</p>
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', () => {
Expand Down

0 comments on commit 1e602f2

Please sign in to comment.