@valaxyjs/utils 0.19.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/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var i=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var h=(r,e)=>{for(var t in e)i(r,t,{get:e[t],enumerable:!0})},g=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of p(e))!b.call(r,o)&&o!==t&&i(r,o,{get:()=>e[o],enumerable:!(n=f(e,o))||n.enumerable});return r};var y=r=>g(i({},"__esModule",{value:!0}),r);var H={};h(H,{addToParent:()=>s,getHeaders:()=>x,groupHeaders:()=>m,resolveHeaders:()=>a,serializeHeader:()=>c});module.exports=y(H);function m(r,e){let t=[];return r=r.map(n=>({...n})),r.forEach((n,o)=>{n.level>=e[0]&&n.level<=e[1]&&s(o,r,e)&&t.push(n)}),t}function s(r,e,t){if(r===0)return!0;let n=e[r];for(let o=r-1;o>=0;o--){let l=e[o];if(l.level<n.level&&l.level>=t[0]&&l.level<=t[1])return l.children==null&&(l.children=[]),l.children.push(n),!1}return!0}function a(r,e=[2,4]){return m(r,typeof e=="number"?[e,e]:e==="deep"?[2,6]:e)}function c(r){let e="";for(let t of Array.from(r.childNodes))if(t.nodeType===1){if(t.classList.contains("VABadge")||t.classList.contains("header-anchor"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function x(r={range:[2,4],selector:".markdown-body"}){let e=r.selector||".markdown-body",t=document.querySelectorAll(e),n=t[t.length-1],o=Array.from(n.querySelectorAll(`${e} :where(h1,h2,h3,h4,h5,h6)`)).filter(l=>r.filter?r.filter(l):!0).map(l=>{let d=Number(l.tagName[1]);return{title:c(l),link:`#${l.id}`,level:d,lang:l.lang}});return a(o,r.range)}0&&(module.exports={addToParent,getHeaders,groupHeaders,resolveHeaders,serializeHeader});
@@ -0,0 +1,53 @@
1
+ interface Header {
2
+ /**
3
+ * The level of the header
4
+ *
5
+ * `1` to `6` for `<h1>` to `<h6>`
6
+ */
7
+ level: number;
8
+ /**
9
+ * The title of the header
10
+ */
11
+ title: string;
12
+ /**
13
+ * The slug of the header
14
+ *
15
+ * Typically the `id` attr of the header anchor
16
+ */
17
+ slug: string;
18
+ /**
19
+ * Link of the header
20
+ *
21
+ * Typically using `#${slug}` as the anchor hash
22
+ */
23
+ link: string;
24
+ /**
25
+ * i18n
26
+ */
27
+ lang?: string;
28
+ }
29
+ interface GetHeadersOptions {
30
+ range?: number | [number, number] | 'deep';
31
+ selector?: string;
32
+ filter?: (el: Element) => boolean;
33
+ }
34
+ /**
35
+ * @en
36
+ * Menu item, the title menu parsed from the article.
37
+ *
38
+ * @zh
39
+ * 菜单项,从文章中解析出的标题菜单。
40
+ */
41
+ type MenuItem = Omit<Header, 'slug' | 'children'> & {
42
+ children?: MenuItem[];
43
+ };
44
+ declare function groupHeaders(headers: MenuItem[], levelsRange: [number, number]): MenuItem[];
45
+ declare function addToParent(currIndex: number, headers: MenuItem[], levelsRange: [number, number]): boolean;
46
+ declare function resolveHeaders(headers: MenuItem[], levelsRange?: GetHeadersOptions['range']): MenuItem[];
47
+ declare function serializeHeader(h: Element): string;
48
+ /**
49
+ * get headers from document directly
50
+ */
51
+ declare function getHeaders(options?: GetHeadersOptions): MenuItem[];
52
+
53
+ export { type GetHeadersOptions, type Header, type MenuItem, addToParent, getHeaders, groupHeaders, resolveHeaders, serializeHeader };
@@ -0,0 +1,53 @@
1
+ interface Header {
2
+ /**
3
+ * The level of the header
4
+ *
5
+ * `1` to `6` for `<h1>` to `<h6>`
6
+ */
7
+ level: number;
8
+ /**
9
+ * The title of the header
10
+ */
11
+ title: string;
12
+ /**
13
+ * The slug of the header
14
+ *
15
+ * Typically the `id` attr of the header anchor
16
+ */
17
+ slug: string;
18
+ /**
19
+ * Link of the header
20
+ *
21
+ * Typically using `#${slug}` as the anchor hash
22
+ */
23
+ link: string;
24
+ /**
25
+ * i18n
26
+ */
27
+ lang?: string;
28
+ }
29
+ interface GetHeadersOptions {
30
+ range?: number | [number, number] | 'deep';
31
+ selector?: string;
32
+ filter?: (el: Element) => boolean;
33
+ }
34
+ /**
35
+ * @en
36
+ * Menu item, the title menu parsed from the article.
37
+ *
38
+ * @zh
39
+ * 菜单项,从文章中解析出的标题菜单。
40
+ */
41
+ type MenuItem = Omit<Header, 'slug' | 'children'> & {
42
+ children?: MenuItem[];
43
+ };
44
+ declare function groupHeaders(headers: MenuItem[], levelsRange: [number, number]): MenuItem[];
45
+ declare function addToParent(currIndex: number, headers: MenuItem[], levelsRange: [number, number]): boolean;
46
+ declare function resolveHeaders(headers: MenuItem[], levelsRange?: GetHeadersOptions['range']): MenuItem[];
47
+ declare function serializeHeader(h: Element): string;
48
+ /**
49
+ * get headers from document directly
50
+ */
51
+ declare function getHeaders(options?: GetHeadersOptions): MenuItem[];
52
+
53
+ export { type GetHeadersOptions, type Header, type MenuItem, addToParent, getHeaders, groupHeaders, resolveHeaders, serializeHeader };
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import {createRequire as __createRequire} from 'module';var require=__createRequire(import.meta.url);
2
+ function s(r,e){let t=[];return r=r.map(o=>({...o})),r.forEach((o,l)=>{o.level>=e[0]&&o.level<=e[1]&&a(l,r,e)&&t.push(o)}),t}function a(r,e,t){if(r===0)return!0;let o=e[r];for(let l=r-1;l>=0;l--){let n=e[l];if(n.level<o.level&&n.level>=t[0]&&n.level<=t[1])return n.children==null&&(n.children=[]),n.children.push(o),!1}return!0}function c(r,e=[2,4]){return s(r,typeof e=="number"?[e,e]:e==="deep"?[2,6]:e)}function d(r){let e="";for(let t of Array.from(r.childNodes))if(t.nodeType===1){if(t.classList.contains("VABadge")||t.classList.contains("header-anchor"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function f(r={range:[2,4],selector:".markdown-body"}){let e=r.selector||".markdown-body",t=document.querySelectorAll(e),o=t[t.length-1],l=Array.from(o.querySelectorAll(`${e} :where(h1,h2,h3,h4,h5,h6)`)).filter(n=>r.filter?r.filter(n):!0).map(n=>{let m=Number(n.tagName[1]);return{title:d(n),link:`#${n.id}`,level:m,lang:n.lang}});return c(l,r.range)}export{a as addToParent,f as getHeaders,s as groupHeaders,c as resolveHeaders,d as serializeHeader};
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@valaxyjs/utils",
3
+ "type": "module",
4
+ "version": "0.19.2",
5
+ "description": "A utility library for Valaxy",
6
+ "author": {
7
+ "name": "Valaxy",
8
+ "url": "https://valaxy.site"
9
+ },
10
+ "license": "MIT",
11
+ "homepage": "https://valaxy.site",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/YunYouJun/valaxy"
15
+ },
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.mjs",
20
+ "require": "./dist/index.cjs"
21
+ }
22
+ },
23
+ "main": "./dist/index.mjs",
24
+ "module": "./dist/index.mjs",
25
+ "types": "./dist/index.d.ts",
26
+ "scripts": {
27
+ "dev": "tsup --watch",
28
+ "build": "tsup",
29
+ "prepublishOnly": "npm run build"
30
+ }
31
+ }
@@ -0,0 +1,148 @@
1
+ export interface Header {
2
+ /**
3
+ * The level of the header
4
+ *
5
+ * `1` to `6` for `<h1>` to `<h6>`
6
+ */
7
+ level: number
8
+ /**
9
+ * The title of the header
10
+ */
11
+ title: string
12
+ /**
13
+ * The slug of the header
14
+ *
15
+ * Typically the `id` attr of the header anchor
16
+ */
17
+ slug: string
18
+ /**
19
+ * Link of the header
20
+ *
21
+ * Typically using `#${slug}` as the anchor hash
22
+ */
23
+ link: string
24
+ /**
25
+ * i18n
26
+ */
27
+ lang?: string
28
+ }
29
+
30
+ export interface GetHeadersOptions {
31
+ range?: number | [number, number] | 'deep'
32
+ selector?: string
33
+ filter?: (el: Element) => boolean
34
+ }
35
+
36
+ /**
37
+ * @en
38
+ * Menu item, the title menu parsed from the article.
39
+ *
40
+ * @zh
41
+ * 菜单项,从文章中解析出的标题菜单。
42
+ */
43
+ export type MenuItem = Omit<Header, 'slug' | 'children'> & {
44
+ children?: MenuItem[]
45
+ }
46
+
47
+ export function groupHeaders(headers: MenuItem[], levelsRange: [number, number]) {
48
+ const result: MenuItem[] = []
49
+
50
+ headers = headers.map(h => ({ ...h }))
51
+ headers.forEach((h, index) => {
52
+ if (h.level >= levelsRange[0] && h.level <= levelsRange[1]) {
53
+ if (addToParent(index, headers, levelsRange))
54
+ result.push(h)
55
+ }
56
+ })
57
+
58
+ return result
59
+ }
60
+
61
+ export function addToParent(
62
+ currIndex: number,
63
+ headers: MenuItem[],
64
+ levelsRange: [number, number],
65
+ ) {
66
+ if (currIndex === 0)
67
+ return true
68
+
69
+ const currentHeader = headers[currIndex]
70
+ for (let index = currIndex - 1; index >= 0; index--) {
71
+ const header = headers[index]
72
+
73
+ if (
74
+ header.level < currentHeader.level
75
+ && header.level >= levelsRange[0]
76
+ && header.level <= levelsRange[1]
77
+ ) {
78
+ if (header.children == null)
79
+ header.children = []
80
+ header.children.push(currentHeader)
81
+ return false
82
+ }
83
+ }
84
+
85
+ return true
86
+ }
87
+
88
+ export function resolveHeaders(
89
+ headers: MenuItem[],
90
+ levelsRange: GetHeadersOptions['range'] = [2, 4],
91
+ ) {
92
+ const levels: [number, number]
93
+ = typeof levelsRange === 'number'
94
+ ? [levelsRange, levelsRange]
95
+ : levelsRange === 'deep'
96
+ ? [2, 6]
97
+ : levelsRange
98
+
99
+ return groupHeaders(headers, levels)
100
+ }
101
+
102
+ export function serializeHeader(h: Element): string {
103
+ let ret = ''
104
+ for (const node of Array.from(h.childNodes)) {
105
+ if (node.nodeType === 1) {
106
+ if (
107
+ (node as Element).classList.contains('VABadge')
108
+ || (node as Element).classList.contains('header-anchor')
109
+ )
110
+ continue
111
+
112
+ ret += node.textContent
113
+ }
114
+ else if (node.nodeType === 3) {
115
+ ret += node.textContent
116
+ }
117
+ }
118
+ return ret.trim()
119
+ }
120
+
121
+ // el => el.id && el.hasChildNodes()
122
+ /**
123
+ * get headers from document directly
124
+ */
125
+ export function getHeaders(options: GetHeadersOptions = {
126
+ range: [2, 4],
127
+ selector: '.markdown-body',
128
+ }) {
129
+ const mdBodySelector = options.selector || '.markdown-body'
130
+ // when transition, the markdown-body will be two
131
+ // the first is the old one, the last is the new one
132
+ const markdownBodyElements = document.querySelectorAll(mdBodySelector) as NodeListOf<HTMLElement>
133
+ const markdownBody = markdownBodyElements[markdownBodyElements.length - 1]
134
+ const headers = Array.from(markdownBody.querySelectorAll(`${mdBodySelector} :where(h1,h2,h3,h4,h5,h6)`))
135
+ .filter(el => options.filter ? options.filter(el) : true)
136
+ .map((el) => {
137
+ const level = Number(el.tagName[1])
138
+ return {
139
+ title: serializeHeader(el),
140
+ link: `#${el.id}`,
141
+ level,
142
+ // @ts-expect-error lang
143
+ lang: el.lang,
144
+ }
145
+ })
146
+
147
+ return resolveHeaders(headers, options.range)
148
+ }
@@ -0,0 +1 @@
1
+ export * from './headers'
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './client'
package/tsup.config.ts ADDED
@@ -0,0 +1,38 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig((options) => {
4
+ return {
5
+ entry: [
6
+ 'src/index.ts',
7
+ ],
8
+ // https://tsup.egoist.dev/#code-splitting
9
+ // Code splitting currently only works with the esm output format, and it's enabled by default. If you want code splitting for cjs output format as well, try using --splitting flag which is an experimental feature to get rid of the limitation in esbuild.
10
+ // splitting: true,
11
+ clean: true,
12
+ dts: true,
13
+ format: ['cjs', 'esm'],
14
+ minify: !options.watch,
15
+
16
+ outExtension({ format }) {
17
+ return {
18
+ js: `.${format === 'esm' ? 'mjs' : 'cjs'}`,
19
+ }
20
+ },
21
+
22
+ /**
23
+ * @see https://tsup.egoist.dev/#inject-cjs-and-esm-shims
24
+ * shim for __filename
25
+ */
26
+ shims: true,
27
+ /**
28
+ * @see https://github.com/egoist/tsup/discussions/505
29
+ */
30
+ banner: ({ format }) => {
31
+ if (format === 'esm') {
32
+ return {
33
+ js: `import {createRequire as __createRequire} from 'module';var require=__createRequire(import\.meta.url);`,
34
+ }
35
+ }
36
+ },
37
+ }
38
+ })