Skip to content

Commit d72e274

Browse files
committed
Merge branch 'v0'
2 parents edaa58a + 4726b56 commit d72e274

File tree

5 files changed

+84
-49
lines changed

5 files changed

+84
-49
lines changed

packages/markdown-exit/src/common/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import { decodeHTML } from 'entities'
55
import * as mdurl from 'mdurl'
66
import * as ucmicro from 'uc.micro'
77

8+
export function isString(obj: unknown): obj is string {
9+
return typeof obj === 'string'
10+
}
11+
812
const _hasOwnProperty = Object.prototype.hasOwnProperty
913

1014
export function has(object: object, key: string | number | symbol): boolean {

packages/markdown-exit/src/index.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ export class MarkdownExit {
394394
*/
395395
use(plugin: PluginSimple): this
396396
use<T = any>(plugin: PluginWithOptions<T>, options?: T): this
397+
use(plugin: PluginWithParams, ...params: any[]): this
397398
use(plugin: PluginWithParams, ...params: any[]): this {
398399
plugin.apply(plugin, [this, ...params])
399400
return this
@@ -495,21 +496,30 @@ export function createMarkdownExit(presetNameOrOptions?: any, options?: any): Ma
495496
}
496497

497498
// hybrid types callable construct signatures hack
498-
type MarkdownExitConstructor = {
499-
new(options?: MarkdownExitOptions): MarkdownExit
500-
new(presetName: PresetName, options?: MarkdownExitOptions): MarkdownExit
501-
(options?: MarkdownExitOptions): MarkdownExit
502-
(presetName: PresetName, options?: MarkdownExitOptions): MarkdownExit
503-
} & typeof MarkdownExit
504-
505-
function _MarkdownExit(presetName?: PresetName | MarkdownExitOptions, options?: MarkdownExitOptions): MarkdownExit {
506-
return new MarkdownExit(presetName as any, options)
499+
500+
/**
501+
* Make class callable without `new` operator.
502+
*/
503+
function createCallableClass<T extends new (...args: any) => any>(Class: T) {
504+
function callable(...args: ConstructorParameters<T>): InstanceType<T> {
505+
return new Class(...args)
506+
}
507+
508+
// bridge statics
509+
Object.setPrototypeOf(callable, MarkdownExit)
510+
511+
// share the same instance prototype
512+
;(callable as any).prototype = MarkdownExit.prototype
513+
;(callable as any).prototype.constructor = callable
514+
515+
return callable as unknown as T
507516
}
508517

509-
// bridge statics
510-
Object.setPrototypeOf(_MarkdownExit, MarkdownExit)
511-
// share the same instance prototype
512-
;(_MarkdownExit as any).prototype = MarkdownExit.prototype
513-
;(_MarkdownExit as any).prototype.constructor = _MarkdownExit
518+
// type and default const variable name must be the same
519+
// for correct d.ts generation
520+
type MarkdownExitConstructor = InstanceType<typeof MarkdownExit>
521+
522+
// eslint-disable-next-line ts/no-redeclare
523+
const MarkdownExitConstructor = createCallableClass(MarkdownExit) as unknown as (typeof createMarkdownExit & typeof MarkdownExit)
514524

515-
export default _MarkdownExit as MarkdownExitConstructor
525+
export default MarkdownExitConstructor

packages/markdown-exit/src/ruler.ts

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,37 @@ export interface RuleOptions {
2121
* {@link MarkdownExit.use}.
2222
*/
2323
export default class Ruler<T extends (...args: any[]) => any> {
24+
/**
25+
* List of added rules. Each element is:
26+
*
27+
* ```js
28+
* {
29+
* name: XXX,
30+
* enabled: Boolean,
31+
* fn: Function(),
32+
* alt: [ name2, name3 ]
33+
* }
34+
* ```
35+
*/
2436
private __rules__: Array<{
2537
name: string
2638
enabled: boolean
2739
fn: T
2840
alt: string[]
29-
}>
30-
31-
private __cache__: Record<string, T[]> | null
32-
33-
constructor() {
34-
// List of added rules. Each element is:
35-
//
36-
// {
37-
// name: XXX,
38-
// enabled: Boolean,
39-
// fn: Function(),
40-
// alt: [ name2, name3 ]
41-
// }
42-
//
43-
this.__rules__ = []
44-
45-
// Cached rule chains.
46-
//
47-
// First level - chain name, '' for default.
48-
// Second level - diginal anchor for fast filtering by charcodes.
49-
//
50-
this.__cache__ = null
51-
}
41+
}> = []
5242

53-
// Helper methods, should not be used directly
43+
/**
44+
* Cached rule chains.
45+
*
46+
* First level - chain name, '' for default.
47+
* Second level - diginal anchor for fast filtering by charcodes.
48+
*/
49+
private __cache__: Record<string, T[]> | null = null
5450

55-
// Find rule index by name
56-
//
51+
/**
52+
* Helper methods, should not be used directly
53+
* Find rule index by name
54+
*/
5755
private __find__(name: string): number {
5856
for (let i = 0; i < this.__rules__.length; i++) {
5957
if (this.__rules__[i].name === name) {
@@ -63,8 +61,9 @@ export default class Ruler<T extends (...args: any[]) => any> {
6361
return -1
6462
}
6563

66-
// Build rules lookup cache
67-
//
64+
/**
65+
* Build rules lookup cache
66+
*/
6867
private __compile__(): void {
6968
const chains = ['']
7069

packages/markdown-exit/src/rules_block/state_block.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ export default class StateBlock {
9595

9696
level: number = 0
9797

98-
static Token: typeof Token = Token
98+
/**
99+
* re-export Token class to use in block rules
100+
*/
101+
Token = Token
99102

100103
constructor(src: string, md: MarkdownExit, env: MarkdownExitEnv, tokens: Token[]) {
101104
this.src = src
@@ -285,7 +288,4 @@ export default class StateBlock {
285288

286289
return queue.join('')
287290
}
288-
289-
// re-export Token class to use in block rules
290-
Token = Token
291291
}

packages/markdown-exit/tests/index.test.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { describe, expect, it } from 'vitest'
2-
import MarkdownExit from '../src'
1+
import { describe, expect, expectTypeOf, it } from 'vitest'
2+
import MarkdownExit, { createMarkdownExit } from '../src'
33

44
describe('callable and constructable', () => {
55
it('is constructable', () => {
@@ -54,4 +54,26 @@ describe('callable and constructable', () => {
5454
const inst = MarkdownExit()
5555
expect(inst.constructor).toBe(MarkdownExit)
5656
})
57+
58+
it('createMarkdownExit is not equal to MarkdownExit', () => {
59+
expect(createMarkdownExit).not.toEqual(MarkdownExit)
60+
})
61+
62+
it('types are correct', () => {
63+
// newable
64+
expectTypeOf(MarkdownExit).toBeConstructibleWith('commonmark')
65+
66+
// callable
67+
expectTypeOf(MarkdownExit).toBeCallableWith('commonmark')
68+
69+
const a = new MarkdownExit()
70+
const b = MarkdownExit()
71+
expectTypeOf(a).toEqualTypeOf(b)
72+
73+
// direct use as type
74+
expectTypeOf(a).toEqualTypeOf<MarkdownExit>()
75+
76+
expectTypeOf(a).toHaveProperty('use')
77+
expectTypeOf(a.use).parameter(0).toBeFunction()
78+
})
5779
})

0 commit comments

Comments
 (0)