@cluesurf/kink 1.0.8 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/code/base/index.ts +223 -0
- package/code/index.ts +7 -0
- package/code/site/index.ts +92 -0
- package/code/site/kink.ts +97 -0
- package/code/site/make.ts +17 -0
- package/code/site/test.ts +35 -0
- package/code/tree/browser.ts +20 -0
- package/code/tree/index.ts +1 -0
- package/code/tree/make.ts +347 -0
- package/code/tree/node.ts +99 -0
- package/code/tree/test.ts +51 -0
- package/eslint.config.ts +3 -0
- package/host/code/base/index.js +138 -0
- package/host/code/base/index.js.map +1 -0
- package/host/code/index.d.ts +5 -0
- package/host/code/index.js +6 -0
- package/host/code/index.js.map +1 -0
- package/host/code/site/index.d.ts +7 -0
- package/host/code/site/index.js +75 -0
- package/host/code/site/index.js.map +1 -0
- package/host/code/site/kink.d.ts +31 -0
- package/host/code/site/kink.js +41 -0
- package/host/code/site/kink.js.map +1 -0
- package/host/code/site/make.d.ts +1 -0
- package/host/code/site/make.js +18 -0
- package/host/code/site/make.js.map +1 -0
- package/host/code/site/test.d.ts +7 -0
- package/host/code/site/test.js +23 -0
- package/host/code/site/test.js.map +1 -0
- package/host/code/tree/browser.d.ts +6 -0
- package/host/code/tree/browser.js +17 -0
- package/host/code/tree/browser.js.map +1 -0
- package/host/code/tree/index.d.ts +1 -0
- package/host/code/tree/index.js +2 -0
- package/host/code/tree/index.js.map +1 -0
- package/host/code/tree/make.d.ts +30 -0
- package/host/code/tree/make.js +271 -0
- package/host/code/tree/make.js.map +1 -0
- package/host/code/tree/node.d.ts +6 -0
- package/host/code/tree/node.js +81 -0
- package/host/code/tree/node.js.map +1 -0
- package/host/code/tree/test.d.ts +7 -0
- package/host/code/tree/test.js +37 -0
- package/host/code/tree/test.js.map +1 -0
- package/host/test/index.d.ts +2 -0
- package/host/test/index.js +11 -0
- package/host/test/index.js.map +1 -0
- package/host/test/kink.d.ts +11 -0
- package/host/test/kink.js +12 -0
- package/host/test/kink.js.map +1 -0
- package/package.json +22 -11
- package/readme.md +6 -0
- package/host/index.js +0 -170
- package/host/index.js.map +0 -1
- /package/host/{index.d.ts → code/base/index.d.ts} +0 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { CustomError } from 'ts-custom-error'
|
|
3
|
+
|
|
4
|
+
export type BaseHook<T extends any = any> = (
|
|
5
|
+
take?: T,
|
|
6
|
+
) => KinkMeshBase & Link
|
|
7
|
+
|
|
8
|
+
export type FillHook<T extends any = any, U extends any = any> = (
|
|
9
|
+
take?: T,
|
|
10
|
+
load?: U,
|
|
11
|
+
) => Link
|
|
12
|
+
|
|
13
|
+
export type KinkMesh = {
|
|
14
|
+
code: string
|
|
15
|
+
form: string
|
|
16
|
+
host: string
|
|
17
|
+
link?: Link
|
|
18
|
+
note: string
|
|
19
|
+
// HTTP code
|
|
20
|
+
siteCode?: number
|
|
21
|
+
take?: Link
|
|
22
|
+
time: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type KinkMeshBase = {
|
|
26
|
+
code: number
|
|
27
|
+
note: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type Link = Record<string, unknown>
|
|
31
|
+
|
|
32
|
+
const base: Record<string, BaseHook> = {}
|
|
33
|
+
const load: Record<string, LoadHook> = {}
|
|
34
|
+
const fill: Record<string, FillHook> = {}
|
|
35
|
+
const code: Record<string, (code: number) => string> = {}
|
|
36
|
+
|
|
37
|
+
let timeHook: TimeHook = (time: number) => String(time)
|
|
38
|
+
|
|
39
|
+
export type LoadHook<T extends any = any> = (take?: T) => Link
|
|
40
|
+
|
|
41
|
+
export default class Kink extends CustomError {
|
|
42
|
+
form: string
|
|
43
|
+
|
|
44
|
+
host: string
|
|
45
|
+
|
|
46
|
+
code: string
|
|
47
|
+
|
|
48
|
+
note: string
|
|
49
|
+
|
|
50
|
+
link: Link
|
|
51
|
+
|
|
52
|
+
siteCode?: number
|
|
53
|
+
|
|
54
|
+
take?: Link
|
|
55
|
+
|
|
56
|
+
time: string
|
|
57
|
+
|
|
58
|
+
static base = (host: string, form: string, hook: BaseHook) => {
|
|
59
|
+
base[`${host}:${form}`] = hook
|
|
60
|
+
return Kink
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static code = (host: string, hook: (code: number) => string) => {
|
|
64
|
+
code[host] = hook
|
|
65
|
+
return Kink
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static load = (host: string, form: string, hook: LoadHook) => {
|
|
69
|
+
load[`${host}:${form}`] = hook
|
|
70
|
+
return Kink
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static fill = (host: string, form: string, hook: FillHook) => {
|
|
74
|
+
fill[`${host}:${form}`] = hook
|
|
75
|
+
return Kink
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static time = (hook: TimeHook) => {
|
|
79
|
+
timeHook = hook
|
|
80
|
+
return Kink
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static makeTime = (time: number) => {
|
|
84
|
+
return timeHook(time)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static make = (host: string, form: string, take?: any) => {
|
|
88
|
+
const time = Kink.makeTime(Date.now())
|
|
89
|
+
const hook = base[`${host}:${form}`]
|
|
90
|
+
if (!hook) {
|
|
91
|
+
throw new Error(`Missing ${host}:${form} in Kink.base`)
|
|
92
|
+
}
|
|
93
|
+
const hookLink = hook(take) as KinkMeshBase & Link
|
|
94
|
+
const kink = new Kink({
|
|
95
|
+
...hookLink,
|
|
96
|
+
code: Kink.makeCode(host, hookLink.code),
|
|
97
|
+
form,
|
|
98
|
+
host,
|
|
99
|
+
take: take as Link,
|
|
100
|
+
time,
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
Kink.saveLoad(kink, take)
|
|
104
|
+
|
|
105
|
+
return kink
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static saveLoad = (kink: Kink, take?: any) => {
|
|
109
|
+
const hook = load[`${kink.host}:${kink.form}`]
|
|
110
|
+
if (!hook) {
|
|
111
|
+
// throw new Error(`Missing ${kink.host}:${kink.form} in Kink.load`)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
kink.link = hook(take)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static saveFill = (kink: Kink) => {
|
|
118
|
+
const hook = fill[`${kink.host}:${kink.form}`]
|
|
119
|
+
if (!hook) {
|
|
120
|
+
// throw new Error(`Missing ${kink.host}:${kink.form} in Kink.fill`)
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
kink.link = hook(kink.take, kink.link)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static makeCode = (host: string, codeLink: number) => {
|
|
127
|
+
const hook = code[host]
|
|
128
|
+
if (!hook) {
|
|
129
|
+
return codeLink.toString()
|
|
130
|
+
}
|
|
131
|
+
return hook(codeLink)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
static makeBase = (
|
|
135
|
+
kink: Error,
|
|
136
|
+
{
|
|
137
|
+
siteCode,
|
|
138
|
+
list = false,
|
|
139
|
+
}: { list?: boolean; siteCode?: number } = {},
|
|
140
|
+
) => {
|
|
141
|
+
const time = Kink.makeTime(Date.now())
|
|
142
|
+
return new Kink({
|
|
143
|
+
code:
|
|
144
|
+
'code' in kink
|
|
145
|
+
? typeof kink.code === 'string'
|
|
146
|
+
? kink.code
|
|
147
|
+
: typeof kink.code === 'number'
|
|
148
|
+
? Kink.makeCode('system', kink.code)
|
|
149
|
+
: '0000'
|
|
150
|
+
: '0000',
|
|
151
|
+
form: 'system_error',
|
|
152
|
+
host: 'system',
|
|
153
|
+
// list: stack ? kink.stack?.split('\n') ?? [] : [],
|
|
154
|
+
note: kink.message,
|
|
155
|
+
siteCode,
|
|
156
|
+
time,
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
constructor({
|
|
161
|
+
siteCode,
|
|
162
|
+
host,
|
|
163
|
+
note,
|
|
164
|
+
form,
|
|
165
|
+
take,
|
|
166
|
+
link = {},
|
|
167
|
+
code,
|
|
168
|
+
time,
|
|
169
|
+
}: KinkMesh) {
|
|
170
|
+
super(note)
|
|
171
|
+
|
|
172
|
+
Object.defineProperty(this, 'name', {
|
|
173
|
+
enumerable: false,
|
|
174
|
+
value: '',
|
|
175
|
+
writable: true,
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
Object.defineProperty(this, 'take', {
|
|
179
|
+
enumerable: false,
|
|
180
|
+
value: take,
|
|
181
|
+
writable: true,
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
this.time = time
|
|
185
|
+
this.host = host
|
|
186
|
+
this.form = form
|
|
187
|
+
this.code = code
|
|
188
|
+
this.note = note
|
|
189
|
+
this.link = link
|
|
190
|
+
this.take = take
|
|
191
|
+
this.siteCode = siteCode
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
toJSON(): KinkMesh {
|
|
195
|
+
return {
|
|
196
|
+
code: this.code,
|
|
197
|
+
form: this.form,
|
|
198
|
+
host: this.host,
|
|
199
|
+
link: this.link,
|
|
200
|
+
note: this.note,
|
|
201
|
+
time: this.time,
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export type TimeHook = (time: number) => string
|
|
207
|
+
|
|
208
|
+
// eslint-disable-next-line sort-exports/sort-exports
|
|
209
|
+
export class KinkList extends Kink {
|
|
210
|
+
list: Array<Kink>
|
|
211
|
+
|
|
212
|
+
constructor(list: Array<Kink>) {
|
|
213
|
+
const time = Kink.makeTime(Date.now())
|
|
214
|
+
super({
|
|
215
|
+
code: Kink.makeCode('@cluesurf/kink', 0),
|
|
216
|
+
form: 'list',
|
|
217
|
+
host: '@cluesurf/kink',
|
|
218
|
+
note: 'A set of errors occurred.',
|
|
219
|
+
time,
|
|
220
|
+
})
|
|
221
|
+
this.list = list
|
|
222
|
+
}
|
|
223
|
+
}
|
package/code/index.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import Kink, { KinkList } from '../base'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
import _ from 'lodash'
|
|
4
|
+
import kink, { host } from './kink'
|
|
5
|
+
import { makeKinkText } from '../tree'
|
|
6
|
+
|
|
7
|
+
export function isZodError<I>(
|
|
8
|
+
input: any,
|
|
9
|
+
): input is z.SafeParseError<I> {
|
|
10
|
+
return Boolean(
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
12
|
+
input && !input.success && 'error' in input,
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function loadKink(error: any) {
|
|
17
|
+
const kink = loadKinkList(error)
|
|
18
|
+
|
|
19
|
+
if (kink instanceof KinkList) {
|
|
20
|
+
if (kink?.list.length === 1) {
|
|
21
|
+
return kink.list[0]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return kink
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function loadKinkList(error: any) {
|
|
29
|
+
if (error instanceof z.ZodError) {
|
|
30
|
+
return loadZodErrorJSON(error)
|
|
31
|
+
} else {
|
|
32
|
+
if (error instanceof KinkList) {
|
|
33
|
+
error.list.forEach(error => {
|
|
34
|
+
Kink.saveFill(error)
|
|
35
|
+
})
|
|
36
|
+
return error
|
|
37
|
+
} else if (error instanceof Kink) {
|
|
38
|
+
Kink.saveFill(error)
|
|
39
|
+
return error
|
|
40
|
+
} else if (error instanceof Error) {
|
|
41
|
+
return Kink.makeBase(error, { siteCode: 500 })
|
|
42
|
+
} else {
|
|
43
|
+
return Kink.makeBase(new Error(error as string), {
|
|
44
|
+
siteCode: 500,
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function loadZodErrorJSON(error: z.ZodError) {
|
|
51
|
+
return new KinkList(
|
|
52
|
+
error.issues.map(error => {
|
|
53
|
+
// ZodInvalidTypeIssue | ZodInvalidLiteralIssue | ZodUnrecognizedKeysIssue | ZodInvalidUnionIssue | ZodInvalidUnionDiscriminatorIssue | ZodInvalidEnumValueIssue | ZodInvalidArgumentsIssue | ZodInvalidReturnTypeIssue | ZodInvalidDateIssue | ZodInvalidStringIssue | ZodTooSmallIssue | ZodTooBigIssue | ZodInvalidIntersectionTypesIssue | ZodNotMultipleOfIssue | ZodNotFiniteIssue | ZodCustomIssue;
|
|
54
|
+
switch (error.code) {
|
|
55
|
+
case z.ZodIssueCode.invalid_type:
|
|
56
|
+
return kink(
|
|
57
|
+
'form_fail',
|
|
58
|
+
{
|
|
59
|
+
have: error.received,
|
|
60
|
+
link: error.path.map(String),
|
|
61
|
+
message: error.message,
|
|
62
|
+
need: error.expected,
|
|
63
|
+
},
|
|
64
|
+
406,
|
|
65
|
+
)
|
|
66
|
+
case z.ZodIssueCode.unrecognized_keys:
|
|
67
|
+
return kink(
|
|
68
|
+
'form_link_fail',
|
|
69
|
+
{
|
|
70
|
+
link: error.path,
|
|
71
|
+
list: error.keys,
|
|
72
|
+
message: error.message,
|
|
73
|
+
},
|
|
74
|
+
406,
|
|
75
|
+
)
|
|
76
|
+
default: {
|
|
77
|
+
const kink = new Kink({
|
|
78
|
+
code: Kink.makeCode(host, 0),
|
|
79
|
+
form: 'z.ZodError',
|
|
80
|
+
host: host,
|
|
81
|
+
note: error.message,
|
|
82
|
+
time: Kink.makeTime(Date.now()),
|
|
83
|
+
})
|
|
84
|
+
kink.siteCode = 406
|
|
85
|
+
return kink
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}),
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export { default } from './make'
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import Kink from '~/code/base'
|
|
2
|
+
|
|
3
|
+
export const host = '@cluesurf/kink'
|
|
4
|
+
|
|
5
|
+
type BaseZodError = {
|
|
6
|
+
link: Array<string | number>
|
|
7
|
+
message: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type Base = {
|
|
11
|
+
call_fail: {
|
|
12
|
+
take: {}
|
|
13
|
+
}
|
|
14
|
+
call_time_meet: {
|
|
15
|
+
take: {
|
|
16
|
+
link: string
|
|
17
|
+
}
|
|
18
|
+
// base: {
|
|
19
|
+
// url: string
|
|
20
|
+
// }
|
|
21
|
+
// fill: {
|
|
22
|
+
// url: string
|
|
23
|
+
// }
|
|
24
|
+
}
|
|
25
|
+
form_fail: {
|
|
26
|
+
take: BaseZodError & {
|
|
27
|
+
have: string
|
|
28
|
+
link: Array<string>
|
|
29
|
+
need: string
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
form_link_fail: {
|
|
33
|
+
take: BaseZodError & {
|
|
34
|
+
list: Array<string>
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type Name = keyof Base
|
|
40
|
+
|
|
41
|
+
let CODE_INDEX = 1
|
|
42
|
+
|
|
43
|
+
const CODE = {
|
|
44
|
+
call_fail: CODE_INDEX++,
|
|
45
|
+
call_time_meet: CODE_INDEX++,
|
|
46
|
+
form_fail: CODE_INDEX++,
|
|
47
|
+
form_link_fail: CODE_INDEX++,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
Kink.code(host, (code: number) => code.toString(16).padStart(4, '0'))
|
|
51
|
+
|
|
52
|
+
Kink.base(
|
|
53
|
+
host,
|
|
54
|
+
'call_time_meet',
|
|
55
|
+
(take: Base['call_time_meet']['take']) => ({
|
|
56
|
+
code: CODE.call_time_meet,
|
|
57
|
+
link: take.link,
|
|
58
|
+
note: 'Request timeout.',
|
|
59
|
+
}),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
Kink.base(host, 'call_fail', () => ({
|
|
63
|
+
code: CODE.call_fail,
|
|
64
|
+
note: 'System unable to make request currently.',
|
|
65
|
+
}))
|
|
66
|
+
|
|
67
|
+
Kink.base(host, 'form_fail', (take: Base['form_fail']['take']) => ({
|
|
68
|
+
code: CODE.form_fail,
|
|
69
|
+
have: take.have,
|
|
70
|
+
hint: take.message,
|
|
71
|
+
link: take.link,
|
|
72
|
+
need: take.need,
|
|
73
|
+
note: 'Invalid link type.',
|
|
74
|
+
}))
|
|
75
|
+
|
|
76
|
+
// https://github.com/colinhacks/zod/blob/master/ERROR_HANDLING.md
|
|
77
|
+
Kink.base(
|
|
78
|
+
host,
|
|
79
|
+
'form_link_fail',
|
|
80
|
+
(take: Base['form_link_fail']['take']) => ({
|
|
81
|
+
code: CODE.form_link_fail,
|
|
82
|
+
hint: take.message,
|
|
83
|
+
link: take.link,
|
|
84
|
+
list: take.list,
|
|
85
|
+
note: 'Unrecognized keys in object.',
|
|
86
|
+
}),
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
export default function makeBase<N extends Name>(
|
|
90
|
+
form: N,
|
|
91
|
+
link?: Base[N]['take'],
|
|
92
|
+
siteCode?: number,
|
|
93
|
+
) {
|
|
94
|
+
const kink = Kink.make(host, form, link)
|
|
95
|
+
kink.siteCode = siteCode
|
|
96
|
+
return kink
|
|
97
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { KinkList } from '../base'
|
|
2
|
+
import { loadKink } from '.'
|
|
3
|
+
import { makeKinkText } from '../tree'
|
|
4
|
+
|
|
5
|
+
export default function makeSiteKinkText(error: any) {
|
|
6
|
+
const kink = loadKink(error)
|
|
7
|
+
const text: Array<string> = []
|
|
8
|
+
if (kink instanceof KinkList) {
|
|
9
|
+
text.push(makeKinkText(kink))
|
|
10
|
+
kink.list.forEach(kink => {
|
|
11
|
+
text.push(makeKinkText(kink))
|
|
12
|
+
})
|
|
13
|
+
} else if (kink) {
|
|
14
|
+
text.push(makeKinkText(kink))
|
|
15
|
+
}
|
|
16
|
+
return text.join('\n')
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import Kink from '~/code/base'
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import makeSiteKinkText from '.'
|
|
4
|
+
|
|
5
|
+
const host = '@cluesurf/kink'
|
|
6
|
+
|
|
7
|
+
type Base = {
|
|
8
|
+
syntax_error: {}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Name = keyof Base
|
|
12
|
+
|
|
13
|
+
Kink.base(host, 'syntax_error', () => ({
|
|
14
|
+
code: 1,
|
|
15
|
+
note: 'Syntax error',
|
|
16
|
+
}))
|
|
17
|
+
|
|
18
|
+
Kink.code(host, (code: number) => code.toString(16).padStart(4, '0'))
|
|
19
|
+
|
|
20
|
+
export default function kink<N extends Name>(form: N, link?: Base[N]) {
|
|
21
|
+
return Kink.make(host, form, link)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// https://nodejs.org/api/errors.html
|
|
25
|
+
process.on('uncaughtException', err => {
|
|
26
|
+
console.log(makeSiteKinkText(err))
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
throw kink('syntax_error')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
setTimeout(() => {
|
|
34
|
+
fs.readFileSync('.')
|
|
35
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Kink from '~/code/base'
|
|
2
|
+
import makeText from './make'
|
|
3
|
+
|
|
4
|
+
export * from './make'
|
|
5
|
+
|
|
6
|
+
export function makeBaseKinkText(kink: Error): string {
|
|
7
|
+
return makeText({ ...Kink.makeBase(kink), list: [] })
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function makeKinkText(kink: Kink): string {
|
|
11
|
+
return makeText({
|
|
12
|
+
code: kink.code,
|
|
13
|
+
host: kink.host,
|
|
14
|
+
list: kink.stack?.split('\n') ?? [],
|
|
15
|
+
note: kink.note,
|
|
16
|
+
time: kink.time,
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { makeText }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './node'
|