tangled
alpha
login
or
join now
tombl.dev
/
dhtml
1
fork
atom
a post-component library for building user-interfaces on the web.
1
fork
atom
overview
issues
pulls
pipelines
switch to node:test (#48)
should massively reduce deps
tombl.dev
1 year ago
594a6820
cb6b34e1
verified
This commit was signed with the committer's
known signature
.
tombl.dev
SSH Key Fingerprint:
SHA256:d8AHgL5V+3WdvGdDb3SVBfb0RIRJfkKcqhQ5aG1mVNk=
+1107
-3853
19 changed files
expand all
collapse all
unified
split
.github
workflows
test.yml
.gitignore
build.js
examples
kanban
package-lock.json
package-lock.json
package.json
src
client
compiler.ts
tests
attributes.test.ts
basic.test.ts
custom-elements.test.ts
directives.test.ts
lists.test.ts
recursion.test.ts
renderable.test.ts
setup.ts
util.ts
shared.ts
tsconfig.json
vitest.config.js
+9
-11
.github/workflows/test.yml
reviewed
···
7
7
test:
8
8
runs-on: ubuntu-latest
9
9
10
10
-
permissions:
11
11
-
contents: read
12
12
-
pull-requests: write
13
13
-
14
14
-
container:
15
15
-
image: mcr.microsoft.com/playwright:v1.50.1-noble
16
16
-
options: --user 1001
17
17
-
18
10
steps:
19
11
- uses: actions/checkout@v4
12
12
+
- uses: actions/setup-node@v4
13
13
+
with:
14
14
+
node-version: 23.x
20
15
- run: npm install
21
21
-
- run: npm run test
22
22
-
- if: always() && github.event_name == 'pull_request'
23
23
-
uses: davelosert/vitest-coverage-report-action@v2
16
16
+
- run: npm run test:coverage
17
17
+
- if: always()
18
18
+
uses: coverallsapp/github-action@v2
19
19
+
with:
20
20
+
file: lcov.info
21
21
+
format: lcov
+1
-1
.gitignore
reviewed
···
1
1
node_modules
2
2
dist
3
3
-
coverage
3
3
+
lcov.info
+97
-91
build.js
reviewed
···
6
6
import { build } from 'rolldown'
7
7
import { walk } from 'zimmerframe'
8
8
9
9
-
try {
10
10
-
await rm('dist', { recursive: true })
11
11
-
} catch {}
9
9
+
await rm('dist', { recursive: true, force: true })
12
10
13
13
-
/** @type {import('rolldown').Plugin} */
14
14
-
const strip_asserts_plugin = {
15
15
-
name: 'strip-asserts',
16
16
-
transform(code, id, { moduleType }) {
17
17
-
if (id.includes('node_modules')) return
11
11
+
await Promise.all([bundle_code(), generate_declarations(), write_package_json()])
18
12
19
19
-
const ast = this.parse(code, { lang: moduleType })
20
20
-
const source = new MagicString(code, { filename: id })
13
13
+
async function bundle_code() {
14
14
+
/** @type {import('rolldown').Plugin} */
15
15
+
const strip_asserts_plugin = {
16
16
+
name: 'strip-asserts',
17
17
+
transform(code, id, { moduleType }) {
18
18
+
if (id.includes('node_modules')) return
21
19
22
22
-
walk(/** @type {import('@oxc-project/types').Node} */ (ast), null, {
23
23
-
CallExpression(node, { next }) {
24
24
-
if (node.callee.type === 'Identifier' && node.callee.name === 'assert') {
25
25
-
source.update(node.start, node.end, ';')
26
26
-
return
27
27
-
}
20
20
+
const ast = this.parse(code, { lang: moduleType })
21
21
+
const source = new MagicString(code, { filename: id })
28
22
29
29
-
next()
30
30
-
},
31
31
-
})
23
23
+
walk(/** @type {import('@oxc-project/types').Node} */ (ast), null, {
24
24
+
CallExpression(node, { next }) {
25
25
+
if (node.callee.type === 'Identifier' && node.callee.name === 'assert') {
26
26
+
source.update(node.start, node.end, ';')
27
27
+
return
28
28
+
}
32
29
33
33
-
return { code: source.toString(), map: source.generateMap() }
34
34
-
},
35
35
-
}
30
30
+
next()
31
31
+
},
32
32
+
})
36
33
37
37
-
/** @returns {import('rolldown').BuildOptions} */
38
38
-
function define_bundle(env) {
39
39
-
const is_dev = env === 'dev'
40
40
-
41
41
-
return {
42
42
-
input: {
43
43
-
client: './src/client.ts',
44
44
-
server: './src/server.ts',
45
45
-
index: './src/index.ts',
46
46
-
},
47
47
-
plugins: [!is_dev && strip_asserts_plugin],
48
48
-
output: {
49
49
-
dir: 'dist',
50
50
-
entryFileNames: is_dev ? '[name].js' : '[name].min.js',
51
51
-
chunkFileNames: is_dev ? '[name].js' : '[name].min.js',
52
52
-
banner: is_dev ? '// @ts-nocheck' : undefined,
53
53
-
minify: !is_dev,
54
54
-
plugins: [
55
55
-
!is_dev &&
56
56
-
terser({
57
57
-
mangle: { properties: { regex: /^_/ } },
58
58
-
}),
59
59
-
],
60
60
-
},
61
61
-
define: {
62
62
-
__DEV__: JSON.stringify(is_dev),
34
34
+
return { code: source.toString(), map: source.generateMap() }
63
35
},
64
36
}
65
65
-
}
66
37
67
67
-
const bundles = await build([define_bundle('dev'), define_bundle('prod')])
68
68
-
69
69
-
await createBundle({
70
70
-
project: 'tsconfig.json',
71
71
-
output: 'dist/types.d.ts',
72
72
-
modules: {
73
73
-
dhtml: './src/index.ts',
74
74
-
'dhtml/client': './src/client.ts',
75
75
-
'dhtml/server': './src/server.ts',
76
76
-
},
77
77
-
})
38
38
+
/** @returns {import('rolldown').BuildOptions} */
39
39
+
function define_bundle(env) {
40
40
+
const is_dev = env === 'dev'
78
41
79
79
-
const pkg = JSON.parse(await readFile('package.json', 'utf8'))
80
80
-
81
81
-
delete pkg.scripts
82
82
-
delete pkg.devDependencies
83
83
-
delete pkg.prettier
84
84
-
;(function walk(exports) {
85
85
-
if (typeof exports === 'string') {
86
86
-
if (exports.startsWith('./src/')) exports = exports.slice('./src/'.length)
87
87
-
exports = exports.replace(/\.ts$/, '')
88
42
return {
89
89
-
types: './types.d.ts',
90
90
-
production: `./${exports}.min.js`,
91
91
-
default: `./${exports}.js`,
43
43
+
input: {
44
44
+
client: './src/client.ts',
45
45
+
server: './src/server.ts',
46
46
+
index: './src/index.ts',
47
47
+
},
48
48
+
plugins: [!is_dev && strip_asserts_plugin],
49
49
+
output: {
50
50
+
dir: 'dist',
51
51
+
entryFileNames: is_dev ? '[name].js' : '[name].min.js',
52
52
+
chunkFileNames: is_dev ? '[name].js' : '[name].min.js',
53
53
+
banner: is_dev ? '// @ts-nocheck' : undefined,
54
54
+
minify: !is_dev,
55
55
+
plugins: [
56
56
+
!is_dev &&
57
57
+
terser({
58
58
+
mangle: { properties: { regex: /^_/ } },
59
59
+
}),
60
60
+
],
61
61
+
},
62
62
+
define: {
63
63
+
__DEV__: JSON.stringify(is_dev),
64
64
+
},
92
65
}
93
66
}
94
94
-
for (const key in exports) {
95
95
-
exports[key] = walk(exports[key])
96
96
-
}
97
97
-
return exports
98
98
-
})(pkg.exports)
99
67
100
100
-
await writeFile('dist/package.json', JSON.stringify(pkg, null, 2))
68
68
+
const bundles = await build([define_bundle('dev'), define_bundle('prod')])
101
69
102
102
-
console.table(
103
103
-
Object.fromEntries(
104
104
-
bundles.flatMap(bundle =>
105
105
-
bundle.output.map(file => [
106
106
-
file.fileName,
107
107
-
{
108
108
-
normal: file.code.length,
109
109
-
gzip: gzipSync(file.code).length,
110
110
-
brotli: brotliCompressSync(file.code).length,
111
111
-
},
112
112
-
]),
70
70
+
console.table(
71
71
+
Object.fromEntries(
72
72
+
bundles.flatMap(bundle =>
73
73
+
bundle.output.map(file => [
74
74
+
file.fileName,
75
75
+
{
76
76
+
normal: file.code.length,
77
77
+
gzip: gzipSync(file.code).length,
78
78
+
brotli: brotliCompressSync(file.code).length,
79
79
+
},
80
80
+
]),
81
81
+
),
113
82
),
114
114
-
),
115
115
-
)
83
83
+
)
84
84
+
}
85
85
+
86
86
+
async function generate_declarations() {
87
87
+
await createBundle({
88
88
+
project: 'tsconfig.json',
89
89
+
output: 'dist/types.d.ts',
90
90
+
modules: {
91
91
+
dhtml: './src/index.ts',
92
92
+
'dhtml/client': './src/client.ts',
93
93
+
'dhtml/server': './src/server.ts',
94
94
+
},
95
95
+
})
96
96
+
}
97
97
+
98
98
+
async function write_package_json() {
99
99
+
const pkg = JSON.parse(await readFile('package.json', 'utf8'))
100
100
+
101
101
+
delete pkg.scripts
102
102
+
delete pkg.devDependencies
103
103
+
delete pkg.prettier
104
104
+
;(function walk(exports) {
105
105
+
if (typeof exports === 'string') {
106
106
+
if (exports.startsWith('./src/')) exports = exports.slice('./src/'.length)
107
107
+
exports = exports.replace(/\.ts$/, '')
108
108
+
return {
109
109
+
types: './types.d.ts',
110
110
+
production: `./${exports}.min.js`,
111
111
+
default: `./${exports}.js`,
112
112
+
}
113
113
+
}
114
114
+
for (const key in exports) {
115
115
+
exports[key] = walk(exports[key])
116
116
+
}
117
117
+
return exports
118
118
+
})(pkg.exports)
119
119
+
120
120
+
await writeFile('dist/package.json', JSON.stringify(pkg, null, 2))
121
121
+
}
+1
-5
examples/kanban/package-lock.json
reviewed
···
19
19
"../..": {
20
20
"devDependencies": {
21
21
"@rollup/plugin-terser": "^0.4.4",
22
22
-
"@vitest/browser": "^3.0.6",
23
23
-
"@vitest/coverage-v8": "^3.0.6",
24
24
-
"@vitest/ui": "^3.0.5",
25
22
"dhtml": ".",
26
23
"dts-buddy": "^0.5.5",
24
24
+
"happy-dom": "^17.4.4",
27
25
"htmlparser2": "^10.0.0",
28
26
"magic-string": "^0.30.17",
29
29
-
"playwright": "^1.50.1",
30
27
"prettier": "^3.4.2",
31
28
"rolldown": "^1.0.0-beta.6",
32
29
"typescript": "^5.7.2",
33
33
-
"vitest": "^3.0.6",
34
30
"zimmerframe": "^1.1.2"
35
31
}
36
32
},
+68
-2682
package-lock.json
reviewed
···
7
7
"": {
8
8
"name": "dhtml",
9
9
"devDependencies": {
10
10
+
"@happy-dom/global-registrator": "^17.4.4",
10
11
"@rollup/plugin-terser": "^0.4.4",
11
11
-
"@vitest/browser": "^3.0.6",
12
12
-
"@vitest/coverage-v8": "^3.0.6",
13
13
-
"@vitest/ui": "^3.0.5",
12
12
+
"@types/node": "^22.13.11",
14
13
"dhtml": ".",
15
14
"dts-buddy": "^0.5.5",
16
15
"htmlparser2": "^10.0.0",
17
16
"magic-string": "^0.30.17",
18
18
-
"playwright": "^1.50.1",
19
17
"prettier": "^3.4.2",
20
18
"rolldown": "^1.0.0-beta.6",
21
19
"typescript": "^5.7.2",
22
22
-
"vitest": "^3.0.6",
23
20
"zimmerframe": "^1.1.2"
24
21
}
25
22
},
26
26
-
"node_modules/@ampproject/remapping": {
27
27
-
"version": "2.3.0",
28
28
-
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
29
29
-
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
30
30
-
"dev": true,
31
31
-
"license": "Apache-2.0",
32
32
-
"dependencies": {
33
33
-
"@jridgewell/gen-mapping": "^0.3.5",
34
34
-
"@jridgewell/trace-mapping": "^0.3.24"
35
35
-
},
36
36
-
"engines": {
37
37
-
"node": ">=6.0.0"
38
38
-
}
39
39
-
},
40
40
-
"node_modules/@babel/code-frame": {
41
41
-
"version": "7.26.2",
42
42
-
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
43
43
-
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
44
44
-
"dev": true,
45
45
-
"license": "MIT",
46
46
-
"dependencies": {
47
47
-
"@babel/helper-validator-identifier": "^7.25.9",
48
48
-
"js-tokens": "^4.0.0",
49
49
-
"picocolors": "^1.0.0"
50
50
-
},
51
51
-
"engines": {
52
52
-
"node": ">=6.9.0"
53
53
-
}
54
54
-
},
55
55
-
"node_modules/@babel/helper-string-parser": {
56
56
-
"version": "7.25.9",
57
57
-
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
58
58
-
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
59
59
-
"dev": true,
60
60
-
"license": "MIT",
61
61
-
"engines": {
62
62
-
"node": ">=6.9.0"
63
63
-
}
64
64
-
},
65
65
-
"node_modules/@babel/helper-validator-identifier": {
66
66
-
"version": "7.25.9",
67
67
-
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
68
68
-
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
69
69
-
"dev": true,
70
70
-
"license": "MIT",
71
71
-
"engines": {
72
72
-
"node": ">=6.9.0"
73
73
-
}
74
74
-
},
75
75
-
"node_modules/@babel/parser": {
76
76
-
"version": "7.26.9",
77
77
-
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz",
78
78
-
"integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
79
79
-
"dev": true,
80
80
-
"license": "MIT",
81
81
-
"dependencies": {
82
82
-
"@babel/types": "^7.26.9"
83
83
-
},
84
84
-
"bin": {
85
85
-
"parser": "bin/babel-parser.js"
86
86
-
},
87
87
-
"engines": {
88
88
-
"node": ">=6.0.0"
89
89
-
}
90
90
-
},
91
91
-
"node_modules/@babel/runtime": {
92
92
-
"version": "7.26.7",
93
93
-
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz",
94
94
-
"integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==",
95
95
-
"dev": true,
96
96
-
"license": "MIT",
97
97
-
"dependencies": {
98
98
-
"regenerator-runtime": "^0.14.0"
99
99
-
},
100
100
-
"engines": {
101
101
-
"node": ">=6.9.0"
102
102
-
}
103
103
-
},
104
104
-
"node_modules/@babel/types": {
105
105
-
"version": "7.26.9",
106
106
-
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
107
107
-
"integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
108
108
-
"dev": true,
109
109
-
"license": "MIT",
110
110
-
"dependencies": {
111
111
-
"@babel/helper-string-parser": "^7.25.9",
112
112
-
"@babel/helper-validator-identifier": "^7.25.9"
113
113
-
},
114
114
-
"engines": {
115
115
-
"node": ">=6.9.0"
116
116
-
}
117
117
-
},
118
118
-
"node_modules/@bcoe/v8-coverage": {
119
119
-
"version": "1.0.2",
120
120
-
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
121
121
-
"integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
122
122
-
"dev": true,
123
123
-
"license": "MIT",
124
124
-
"engines": {
125
125
-
"node": ">=18"
126
126
-
}
127
127
-
},
128
128
-
"node_modules/@bundled-es-modules/cookie": {
129
129
-
"version": "2.0.1",
130
130
-
"resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz",
131
131
-
"integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==",
132
132
-
"dev": true,
133
133
-
"license": "ISC",
134
134
-
"dependencies": {
135
135
-
"cookie": "^0.7.2"
136
136
-
}
137
137
-
},
138
138
-
"node_modules/@bundled-es-modules/statuses": {
139
139
-
"version": "1.0.1",
140
140
-
"resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz",
141
141
-
"integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==",
142
142
-
"dev": true,
143
143
-
"license": "ISC",
144
144
-
"dependencies": {
145
145
-
"statuses": "^2.0.1"
146
146
-
}
147
147
-
},
148
148
-
"node_modules/@bundled-es-modules/tough-cookie": {
149
149
-
"version": "0.1.6",
150
150
-
"resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz",
151
151
-
"integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==",
152
152
-
"dev": true,
153
153
-
"license": "ISC",
154
154
-
"dependencies": {
155
155
-
"@types/tough-cookie": "^4.0.5",
156
156
-
"tough-cookie": "^4.1.4"
157
157
-
}
158
158
-
},
159
23
"node_modules/@emnapi/core": {
160
24
"version": "1.3.1",
161
25
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.3.1.tgz",
···
190
54
"tslib": "^2.4.0"
191
55
}
192
56
},
193
193
-
"node_modules/@esbuild/aix-ppc64": {
194
194
-
"version": "0.24.2",
195
195
-
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
196
196
-
"integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
197
197
-
"cpu": [
198
198
-
"ppc64"
199
199
-
],
200
200
-
"dev": true,
201
201
-
"license": "MIT",
202
202
-
"optional": true,
203
203
-
"os": [
204
204
-
"aix"
205
205
-
],
206
206
-
"engines": {
207
207
-
"node": ">=18"
208
208
-
}
209
209
-
},
210
210
-
"node_modules/@esbuild/android-arm": {
211
211
-
"version": "0.24.2",
212
212
-
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
213
213
-
"integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
214
214
-
"cpu": [
215
215
-
"arm"
216
216
-
],
217
217
-
"dev": true,
218
218
-
"license": "MIT",
219
219
-
"optional": true,
220
220
-
"os": [
221
221
-
"android"
222
222
-
],
223
223
-
"engines": {
224
224
-
"node": ">=18"
225
225
-
}
226
226
-
},
227
227
-
"node_modules/@esbuild/android-arm64": {
228
228
-
"version": "0.24.2",
229
229
-
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
230
230
-
"integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
231
231
-
"cpu": [
232
232
-
"arm64"
233
233
-
],
234
234
-
"dev": true,
235
235
-
"license": "MIT",
236
236
-
"optional": true,
237
237
-
"os": [
238
238
-
"android"
239
239
-
],
240
240
-
"engines": {
241
241
-
"node": ">=18"
242
242
-
}
243
243
-
},
244
244
-
"node_modules/@esbuild/android-x64": {
245
245
-
"version": "0.24.2",
246
246
-
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
247
247
-
"integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
248
248
-
"cpu": [
249
249
-
"x64"
250
250
-
],
251
251
-
"dev": true,
252
252
-
"license": "MIT",
253
253
-
"optional": true,
254
254
-
"os": [
255
255
-
"android"
256
256
-
],
257
257
-
"engines": {
258
258
-
"node": ">=18"
259
259
-
}
260
260
-
},
261
261
-
"node_modules/@esbuild/darwin-arm64": {
262
262
-
"version": "0.24.2",
263
263
-
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
264
264
-
"integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
265
265
-
"cpu": [
266
266
-
"arm64"
267
267
-
],
268
268
-
"dev": true,
269
269
-
"license": "MIT",
270
270
-
"optional": true,
271
271
-
"os": [
272
272
-
"darwin"
273
273
-
],
274
274
-
"engines": {
275
275
-
"node": ">=18"
276
276
-
}
277
277
-
},
278
278
-
"node_modules/@esbuild/darwin-x64": {
279
279
-
"version": "0.24.2",
280
280
-
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
281
281
-
"integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
282
282
-
"cpu": [
283
283
-
"x64"
284
284
-
],
285
285
-
"dev": true,
286
286
-
"license": "MIT",
287
287
-
"optional": true,
288
288
-
"os": [
289
289
-
"darwin"
290
290
-
],
291
291
-
"engines": {
292
292
-
"node": ">=18"
293
293
-
}
294
294
-
},
295
295
-
"node_modules/@esbuild/freebsd-arm64": {
296
296
-
"version": "0.24.2",
297
297
-
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
298
298
-
"integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
299
299
-
"cpu": [
300
300
-
"arm64"
301
301
-
],
302
302
-
"dev": true,
303
303
-
"license": "MIT",
304
304
-
"optional": true,
305
305
-
"os": [
306
306
-
"freebsd"
307
307
-
],
308
308
-
"engines": {
309
309
-
"node": ">=18"
310
310
-
}
311
311
-
},
312
312
-
"node_modules/@esbuild/freebsd-x64": {
313
313
-
"version": "0.24.2",
314
314
-
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
315
315
-
"integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
316
316
-
"cpu": [
317
317
-
"x64"
318
318
-
],
319
319
-
"dev": true,
320
320
-
"license": "MIT",
321
321
-
"optional": true,
322
322
-
"os": [
323
323
-
"freebsd"
324
324
-
],
325
325
-
"engines": {
326
326
-
"node": ">=18"
327
327
-
}
328
328
-
},
329
329
-
"node_modules/@esbuild/linux-arm": {
330
330
-
"version": "0.24.2",
331
331
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
332
332
-
"integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
333
333
-
"cpu": [
334
334
-
"arm"
335
335
-
],
336
336
-
"dev": true,
337
337
-
"license": "MIT",
338
338
-
"optional": true,
339
339
-
"os": [
340
340
-
"linux"
341
341
-
],
342
342
-
"engines": {
343
343
-
"node": ">=18"
344
344
-
}
345
345
-
},
346
346
-
"node_modules/@esbuild/linux-arm64": {
347
347
-
"version": "0.24.2",
348
348
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
349
349
-
"integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
350
350
-
"cpu": [
351
351
-
"arm64"
352
352
-
],
353
353
-
"dev": true,
354
354
-
"license": "MIT",
355
355
-
"optional": true,
356
356
-
"os": [
357
357
-
"linux"
358
358
-
],
359
359
-
"engines": {
360
360
-
"node": ">=18"
361
361
-
}
362
362
-
},
363
363
-
"node_modules/@esbuild/linux-ia32": {
364
364
-
"version": "0.24.2",
365
365
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
366
366
-
"integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
367
367
-
"cpu": [
368
368
-
"ia32"
369
369
-
],
370
370
-
"dev": true,
371
371
-
"license": "MIT",
372
372
-
"optional": true,
373
373
-
"os": [
374
374
-
"linux"
375
375
-
],
376
376
-
"engines": {
377
377
-
"node": ">=18"
378
378
-
}
379
379
-
},
380
380
-
"node_modules/@esbuild/linux-loong64": {
381
381
-
"version": "0.24.2",
382
382
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
383
383
-
"integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
384
384
-
"cpu": [
385
385
-
"loong64"
386
386
-
],
387
387
-
"dev": true,
388
388
-
"license": "MIT",
389
389
-
"optional": true,
390
390
-
"os": [
391
391
-
"linux"
392
392
-
],
393
393
-
"engines": {
394
394
-
"node": ">=18"
395
395
-
}
396
396
-
},
397
397
-
"node_modules/@esbuild/linux-mips64el": {
398
398
-
"version": "0.24.2",
399
399
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
400
400
-
"integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
401
401
-
"cpu": [
402
402
-
"mips64el"
403
403
-
],
404
404
-
"dev": true,
405
405
-
"license": "MIT",
406
406
-
"optional": true,
407
407
-
"os": [
408
408
-
"linux"
409
409
-
],
410
410
-
"engines": {
411
411
-
"node": ">=18"
412
412
-
}
413
413
-
},
414
414
-
"node_modules/@esbuild/linux-ppc64": {
415
415
-
"version": "0.24.2",
416
416
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
417
417
-
"integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
418
418
-
"cpu": [
419
419
-
"ppc64"
420
420
-
],
421
421
-
"dev": true,
422
422
-
"license": "MIT",
423
423
-
"optional": true,
424
424
-
"os": [
425
425
-
"linux"
426
426
-
],
427
427
-
"engines": {
428
428
-
"node": ">=18"
429
429
-
}
430
430
-
},
431
431
-
"node_modules/@esbuild/linux-riscv64": {
432
432
-
"version": "0.24.2",
433
433
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
434
434
-
"integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
435
435
-
"cpu": [
436
436
-
"riscv64"
437
437
-
],
438
438
-
"dev": true,
439
439
-
"license": "MIT",
440
440
-
"optional": true,
441
441
-
"os": [
442
442
-
"linux"
443
443
-
],
444
444
-
"engines": {
445
445
-
"node": ">=18"
446
446
-
}
447
447
-
},
448
448
-
"node_modules/@esbuild/linux-s390x": {
449
449
-
"version": "0.24.2",
450
450
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
451
451
-
"integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
452
452
-
"cpu": [
453
453
-
"s390x"
454
454
-
],
455
455
-
"dev": true,
456
456
-
"license": "MIT",
457
457
-
"optional": true,
458
458
-
"os": [
459
459
-
"linux"
460
460
-
],
461
461
-
"engines": {
462
462
-
"node": ">=18"
463
463
-
}
464
464
-
},
465
465
-
"node_modules/@esbuild/linux-x64": {
466
466
-
"version": "0.24.2",
467
467
-
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
468
468
-
"integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
469
469
-
"cpu": [
470
470
-
"x64"
471
471
-
],
472
472
-
"dev": true,
473
473
-
"license": "MIT",
474
474
-
"optional": true,
475
475
-
"os": [
476
476
-
"linux"
477
477
-
],
478
478
-
"engines": {
479
479
-
"node": ">=18"
480
480
-
}
481
481
-
},
482
482
-
"node_modules/@esbuild/netbsd-arm64": {
483
483
-
"version": "0.24.2",
484
484
-
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
485
485
-
"integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
486
486
-
"cpu": [
487
487
-
"arm64"
488
488
-
],
489
489
-
"dev": true,
490
490
-
"license": "MIT",
491
491
-
"optional": true,
492
492
-
"os": [
493
493
-
"netbsd"
494
494
-
],
495
495
-
"engines": {
496
496
-
"node": ">=18"
497
497
-
}
498
498
-
},
499
499
-
"node_modules/@esbuild/netbsd-x64": {
500
500
-
"version": "0.24.2",
501
501
-
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
502
502
-
"integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
503
503
-
"cpu": [
504
504
-
"x64"
505
505
-
],
506
506
-
"dev": true,
507
507
-
"license": "MIT",
508
508
-
"optional": true,
509
509
-
"os": [
510
510
-
"netbsd"
511
511
-
],
512
512
-
"engines": {
513
513
-
"node": ">=18"
514
514
-
}
515
515
-
},
516
516
-
"node_modules/@esbuild/openbsd-arm64": {
517
517
-
"version": "0.24.2",
518
518
-
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
519
519
-
"integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
520
520
-
"cpu": [
521
521
-
"arm64"
522
522
-
],
523
523
-
"dev": true,
524
524
-
"license": "MIT",
525
525
-
"optional": true,
526
526
-
"os": [
527
527
-
"openbsd"
528
528
-
],
529
529
-
"engines": {
530
530
-
"node": ">=18"
531
531
-
}
532
532
-
},
533
533
-
"node_modules/@esbuild/openbsd-x64": {
534
534
-
"version": "0.24.2",
535
535
-
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
536
536
-
"integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
537
537
-
"cpu": [
538
538
-
"x64"
539
539
-
],
540
540
-
"dev": true,
541
541
-
"license": "MIT",
542
542
-
"optional": true,
543
543
-
"os": [
544
544
-
"openbsd"
545
545
-
],
546
546
-
"engines": {
547
547
-
"node": ">=18"
548
548
-
}
549
549
-
},
550
550
-
"node_modules/@esbuild/sunos-x64": {
551
551
-
"version": "0.24.2",
552
552
-
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
553
553
-
"integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
554
554
-
"cpu": [
555
555
-
"x64"
556
556
-
],
557
557
-
"dev": true,
558
558
-
"license": "MIT",
559
559
-
"optional": true,
560
560
-
"os": [
561
561
-
"sunos"
562
562
-
],
563
563
-
"engines": {
564
564
-
"node": ">=18"
565
565
-
}
566
566
-
},
567
567
-
"node_modules/@esbuild/win32-arm64": {
568
568
-
"version": "0.24.2",
569
569
-
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
570
570
-
"integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
571
571
-
"cpu": [
572
572
-
"arm64"
573
573
-
],
574
574
-
"dev": true,
575
575
-
"license": "MIT",
576
576
-
"optional": true,
577
577
-
"os": [
578
578
-
"win32"
579
579
-
],
580
580
-
"engines": {
581
581
-
"node": ">=18"
582
582
-
}
583
583
-
},
584
584
-
"node_modules/@esbuild/win32-ia32": {
585
585
-
"version": "0.24.2",
586
586
-
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
587
587
-
"integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
588
588
-
"cpu": [
589
589
-
"ia32"
590
590
-
],
591
591
-
"dev": true,
592
592
-
"license": "MIT",
593
593
-
"optional": true,
594
594
-
"os": [
595
595
-
"win32"
596
596
-
],
597
597
-
"engines": {
598
598
-
"node": ">=18"
599
599
-
}
600
600
-
},
601
601
-
"node_modules/@esbuild/win32-x64": {
602
602
-
"version": "0.24.2",
603
603
-
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
604
604
-
"integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
605
605
-
"cpu": [
606
606
-
"x64"
607
607
-
],
608
608
-
"dev": true,
609
609
-
"license": "MIT",
610
610
-
"optional": true,
611
611
-
"os": [
612
612
-
"win32"
613
613
-
],
614
614
-
"engines": {
615
615
-
"node": ">=18"
616
616
-
}
617
617
-
},
618
618
-
"node_modules/@inquirer/confirm": {
619
619
-
"version": "5.1.5",
620
620
-
"resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.5.tgz",
621
621
-
"integrity": "sha512-ZB2Cz8KeMINUvoeDi7IrvghaVkYT2RB0Zb31EaLWOE87u276w4wnApv0SH2qWaJ3r0VSUa3BIuz7qAV2ZvsZlg==",
622
622
-
"dev": true,
623
623
-
"license": "MIT",
624
624
-
"dependencies": {
625
625
-
"@inquirer/core": "^10.1.6",
626
626
-
"@inquirer/type": "^3.0.4"
627
627
-
},
628
628
-
"engines": {
629
629
-
"node": ">=18"
630
630
-
},
631
631
-
"peerDependencies": {
632
632
-
"@types/node": ">=18"
633
633
-
},
634
634
-
"peerDependenciesMeta": {
635
635
-
"@types/node": {
636
636
-
"optional": true
637
637
-
}
638
638
-
}
639
639
-
},
640
640
-
"node_modules/@inquirer/core": {
641
641
-
"version": "10.1.6",
642
642
-
"resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.6.tgz",
643
643
-
"integrity": "sha512-Bwh/Zk6URrHwZnSSzAZAKH7YgGYi0xICIBDFOqBQoXNNAzBHw/bgXgLmChfp+GyR3PnChcTbiCTZGC6YJNJkMA==",
644
644
-
"dev": true,
645
645
-
"license": "MIT",
646
646
-
"dependencies": {
647
647
-
"@inquirer/figures": "^1.0.10",
648
648
-
"@inquirer/type": "^3.0.4",
649
649
-
"ansi-escapes": "^4.3.2",
650
650
-
"cli-width": "^4.1.0",
651
651
-
"mute-stream": "^2.0.0",
652
652
-
"signal-exit": "^4.1.0",
653
653
-
"wrap-ansi": "^6.2.0",
654
654
-
"yoctocolors-cjs": "^2.1.2"
655
655
-
},
656
656
-
"engines": {
657
657
-
"node": ">=18"
658
658
-
},
659
659
-
"peerDependencies": {
660
660
-
"@types/node": ">=18"
661
661
-
},
662
662
-
"peerDependenciesMeta": {
663
663
-
"@types/node": {
664
664
-
"optional": true
665
665
-
}
666
666
-
}
667
667
-
},
668
668
-
"node_modules/@inquirer/figures": {
669
669
-
"version": "1.0.10",
670
670
-
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.10.tgz",
671
671
-
"integrity": "sha512-Ey6176gZmeqZuY/W/nZiUyvmb1/qInjcpiZjXWi6nON+nxJpD1bxtSoBxNliGISae32n6OwbY+TSXPZ1CfS4bw==",
57
57
+
"node_modules/@happy-dom/global-registrator": {
58
58
+
"version": "17.4.4",
59
59
+
"resolved": "https://registry.npmjs.org/@happy-dom/global-registrator/-/global-registrator-17.4.4.tgz",
60
60
+
"integrity": "sha512-njrU74GrYVHO43upIJr96f7pEmUG7YLZbHCGiHALBECeVnDKpepzL9kVc7KIl8S2nQOkPA0rAA1EyC3xASb54w==",
672
61
"dev": true,
673
62
"license": "MIT",
674
674
-
"engines": {
675
675
-
"node": ">=18"
676
676
-
}
677
677
-
},
678
678
-
"node_modules/@inquirer/type": {
679
679
-
"version": "3.0.4",
680
680
-
"resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.4.tgz",
681
681
-
"integrity": "sha512-2MNFrDY8jkFYc9Il9DgLsHhMzuHnOYM1+CUYVWbzu9oT0hC7V7EcYvdCKeoll/Fcci04A+ERZ9wcc7cQ8lTkIA==",
682
682
-
"dev": true,
683
683
-
"license": "MIT",
684
684
-
"engines": {
685
685
-
"node": ">=18"
686
686
-
},
687
687
-
"peerDependencies": {
688
688
-
"@types/node": ">=18"
689
689
-
},
690
690
-
"peerDependenciesMeta": {
691
691
-
"@types/node": {
692
692
-
"optional": true
693
693
-
}
694
694
-
}
695
695
-
},
696
696
-
"node_modules/@isaacs/cliui": {
697
697
-
"version": "8.0.2",
698
698
-
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
699
699
-
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
700
700
-
"dev": true,
701
701
-
"license": "ISC",
702
63
"dependencies": {
703
703
-
"string-width": "^5.1.2",
704
704
-
"string-width-cjs": "npm:string-width@^4.2.0",
705
705
-
"strip-ansi": "^7.0.1",
706
706
-
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
707
707
-
"wrap-ansi": "^8.1.0",
708
708
-
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
64
64
+
"happy-dom": "^17.4.4"
709
65
},
710
66
"engines": {
711
711
-
"node": ">=12"
712
712
-
}
713
713
-
},
714
714
-
"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
715
715
-
"version": "6.1.0",
716
716
-
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
717
717
-
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
718
718
-
"dev": true,
719
719
-
"license": "MIT",
720
720
-
"engines": {
721
721
-
"node": ">=12"
722
722
-
},
723
723
-
"funding": {
724
724
-
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
725
725
-
}
726
726
-
},
727
727
-
"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
728
728
-
"version": "6.2.1",
729
729
-
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
730
730
-
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
731
731
-
"dev": true,
732
732
-
"license": "MIT",
733
733
-
"engines": {
734
734
-
"node": ">=12"
735
735
-
},
736
736
-
"funding": {
737
737
-
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
738
738
-
}
739
739
-
},
740
740
-
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
741
741
-
"version": "9.2.2",
742
742
-
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
743
743
-
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
744
744
-
"dev": true,
745
745
-
"license": "MIT"
746
746
-
},
747
747
-
"node_modules/@isaacs/cliui/node_modules/string-width": {
748
748
-
"version": "5.1.2",
749
749
-
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
750
750
-
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
751
751
-
"dev": true,
752
752
-
"license": "MIT",
753
753
-
"dependencies": {
754
754
-
"eastasianwidth": "^0.2.0",
755
755
-
"emoji-regex": "^9.2.2",
756
756
-
"strip-ansi": "^7.0.1"
757
757
-
},
758
758
-
"engines": {
759
759
-
"node": ">=12"
760
760
-
},
761
761
-
"funding": {
762
762
-
"url": "https://github.com/sponsors/sindresorhus"
763
763
-
}
764
764
-
},
765
765
-
"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
766
766
-
"version": "7.1.0",
767
767
-
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
768
768
-
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
769
769
-
"dev": true,
770
770
-
"license": "MIT",
771
771
-
"dependencies": {
772
772
-
"ansi-regex": "^6.0.1"
773
773
-
},
774
774
-
"engines": {
775
775
-
"node": ">=12"
776
776
-
},
777
777
-
"funding": {
778
778
-
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
779
779
-
}
780
780
-
},
781
781
-
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
782
782
-
"version": "8.1.0",
783
783
-
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
784
784
-
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
785
785
-
"dev": true,
786
786
-
"license": "MIT",
787
787
-
"dependencies": {
788
788
-
"ansi-styles": "^6.1.0",
789
789
-
"string-width": "^5.0.1",
790
790
-
"strip-ansi": "^7.0.1"
791
791
-
},
792
792
-
"engines": {
793
793
-
"node": ">=12"
794
794
-
},
795
795
-
"funding": {
796
796
-
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
797
797
-
}
798
798
-
},
799
799
-
"node_modules/@istanbuljs/schema": {
800
800
-
"version": "0.1.3",
801
801
-
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
802
802
-
"integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
803
803
-
"dev": true,
804
804
-
"license": "MIT",
805
805
-
"engines": {
806
806
-
"node": ">=8"
67
67
+
"node": ">=18.0.0"
807
68
}
808
69
},
809
70
"node_modules/@jridgewell/gen-mapping": {
···
858
119
"@jridgewell/sourcemap-codec": "^1.4.14"
859
120
}
860
121
},
861
861
-
"node_modules/@mswjs/interceptors": {
862
862
-
"version": "0.37.6",
863
863
-
"resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.6.tgz",
864
864
-
"integrity": "sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==",
865
865
-
"dev": true,
866
866
-
"license": "MIT",
867
867
-
"dependencies": {
868
868
-
"@open-draft/deferred-promise": "^2.2.0",
869
869
-
"@open-draft/logger": "^0.3.0",
870
870
-
"@open-draft/until": "^2.0.0",
871
871
-
"is-node-process": "^1.2.0",
872
872
-
"outvariant": "^1.4.3",
873
873
-
"strict-event-emitter": "^0.5.1"
874
874
-
},
875
875
-
"engines": {
876
876
-
"node": ">=18"
877
877
-
}
878
878
-
},
879
122
"node_modules/@napi-rs/wasm-runtime": {
880
123
"version": "0.2.7",
881
124
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.7.tgz",
···
889
132
"@tybys/wasm-util": "^0.9.0"
890
133
}
891
134
},
892
892
-
"node_modules/@open-draft/deferred-promise": {
893
893
-
"version": "2.2.0",
894
894
-
"resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz",
895
895
-
"integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==",
896
896
-
"dev": true,
897
897
-
"license": "MIT"
898
898
-
},
899
899
-
"node_modules/@open-draft/logger": {
900
900
-
"version": "0.3.0",
901
901
-
"resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz",
902
902
-
"integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==",
903
903
-
"dev": true,
904
904
-
"license": "MIT",
905
905
-
"dependencies": {
906
906
-
"is-node-process": "^1.2.0",
907
907
-
"outvariant": "^1.4.0"
908
908
-
}
909
909
-
},
910
910
-
"node_modules/@open-draft/until": {
911
911
-
"version": "2.1.0",
912
912
-
"resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz",
913
913
-
"integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==",
914
914
-
"dev": true,
915
915
-
"license": "MIT"
916
916
-
},
917
135
"node_modules/@oxc-project/types": {
918
136
"version": "0.58.1",
919
137
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.58.1.tgz",
···
923
141
"funding": {
924
142
"url": "https://github.com/sponsors/Boshen"
925
143
}
926
926
-
},
927
927
-
"node_modules/@pkgjs/parseargs": {
928
928
-
"version": "0.11.0",
929
929
-
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
930
930
-
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
931
931
-
"dev": true,
932
932
-
"license": "MIT",
933
933
-
"optional": true,
934
934
-
"engines": {
935
935
-
"node": ">=14"
936
936
-
}
937
937
-
},
938
938
-
"node_modules/@polka/url": {
939
939
-
"version": "1.0.0-next.28",
940
940
-
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
941
941
-
"integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
942
942
-
"dev": true,
943
943
-
"license": "MIT"
944
144
},
945
145
"node_modules/@rolldown/binding-darwin-arm64": {
946
146
"version": "1.0.0-beta.6",
···
1148
348
"optional": true,
1149
349
"os": [
1150
350
"android"
1151
1151
-
]
351
351
+
],
352
352
+
"peer": true
1152
353
},
1153
354
"node_modules/@rollup/rollup-android-arm64": {
1154
355
"version": "4.34.8",
···
1162
363
"optional": true,
1163
364
"os": [
1164
365
"android"
1165
1165
-
]
366
366
+
],
367
367
+
"peer": true
1166
368
},
1167
369
"node_modules/@rollup/rollup-darwin-arm64": {
1168
370
"version": "4.34.8",
···
1176
378
"optional": true,
1177
379
"os": [
1178
380
"darwin"
1179
1179
-
]
381
381
+
],
382
382
+
"peer": true
1180
383
},
1181
384
"node_modules/@rollup/rollup-darwin-x64": {
1182
385
"version": "4.34.8",
···
1190
393
"optional": true,
1191
394
"os": [
1192
395
"darwin"
1193
1193
-
]
396
396
+
],
397
397
+
"peer": true
1194
398
},
1195
399
"node_modules/@rollup/rollup-freebsd-arm64": {
1196
400
"version": "4.34.8",
···
1204
408
"optional": true,
1205
409
"os": [
1206
410
"freebsd"
1207
1207
-
]
411
411
+
],
412
412
+
"peer": true
1208
413
},
1209
414
"node_modules/@rollup/rollup-freebsd-x64": {
1210
415
"version": "4.34.8",
···
1218
423
"optional": true,
1219
424
"os": [
1220
425
"freebsd"
1221
1221
-
]
426
426
+
],
427
427
+
"peer": true
1222
428
},
1223
429
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
1224
430
"version": "4.34.8",
···
1232
438
"optional": true,
1233
439
"os": [
1234
440
"linux"
1235
1235
-
]
441
441
+
],
442
442
+
"peer": true
1236
443
},
1237
444
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
1238
445
"version": "4.34.8",
···
1246
453
"optional": true,
1247
454
"os": [
1248
455
"linux"
1249
1249
-
]
456
456
+
],
457
457
+
"peer": true
1250
458
},
1251
459
"node_modules/@rollup/rollup-linux-arm64-gnu": {
1252
460
"version": "4.34.8",
···
1260
468
"optional": true,
1261
469
"os": [
1262
470
"linux"
1263
1263
-
]
471
471
+
],
472
472
+
"peer": true
1264
473
},
1265
474
"node_modules/@rollup/rollup-linux-arm64-musl": {
1266
475
"version": "4.34.8",
···
1274
483
"optional": true,
1275
484
"os": [
1276
485
"linux"
1277
1277
-
]
486
486
+
],
487
487
+
"peer": true
1278
488
},
1279
489
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
1280
490
"version": "4.34.8",
···
1288
498
"optional": true,
1289
499
"os": [
1290
500
"linux"
1291
1291
-
]
501
501
+
],
502
502
+
"peer": true
1292
503
},
1293
504
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
1294
505
"version": "4.34.8",
···
1302
513
"optional": true,
1303
514
"os": [
1304
515
"linux"
1305
1305
-
]
516
516
+
],
517
517
+
"peer": true
1306
518
},
1307
519
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
1308
520
"version": "4.34.8",
···
1316
528
"optional": true,
1317
529
"os": [
1318
530
"linux"
1319
1319
-
]
531
531
+
],
532
532
+
"peer": true
1320
533
},
1321
534
"node_modules/@rollup/rollup-linux-s390x-gnu": {
1322
535
"version": "4.34.8",
···
1330
543
"optional": true,
1331
544
"os": [
1332
545
"linux"
1333
1333
-
]
546
546
+
],
547
547
+
"peer": true
1334
548
},
1335
549
"node_modules/@rollup/rollup-linux-x64-gnu": {
1336
550
"version": "4.34.8",
···
1344
558
"optional": true,
1345
559
"os": [
1346
560
"linux"
1347
1347
-
]
561
561
+
],
562
562
+
"peer": true
1348
563
},
1349
564
"node_modules/@rollup/rollup-linux-x64-musl": {
1350
565
"version": "4.34.8",
···
1358
573
"optional": true,
1359
574
"os": [
1360
575
"linux"
1361
1361
-
]
576
576
+
],
577
577
+
"peer": true
1362
578
},
1363
579
"node_modules/@rollup/rollup-win32-arm64-msvc": {
1364
580
"version": "4.34.8",
···
1372
588
"optional": true,
1373
589
"os": [
1374
590
"win32"
1375
1375
-
]
591
591
+
],
592
592
+
"peer": true
1376
593
},
1377
594
"node_modules/@rollup/rollup-win32-ia32-msvc": {
1378
595
"version": "4.34.8",
···
1386
603
"optional": true,
1387
604
"os": [
1388
605
"win32"
1389
1389
-
]
606
606
+
],
607
607
+
"peer": true
1390
608
},
1391
609
"node_modules/@rollup/rollup-win32-x64-msvc": {
1392
610
"version": "4.34.8",
···
1400
618
"optional": true,
1401
619
"os": [
1402
620
"win32"
1403
1403
-
]
1404
1404
-
},
1405
1405
-
"node_modules/@testing-library/dom": {
1406
1406
-
"version": "10.4.0",
1407
1407
-
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
1408
1408
-
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
1409
1409
-
"dev": true,
1410
1410
-
"license": "MIT",
1411
1411
-
"dependencies": {
1412
1412
-
"@babel/code-frame": "^7.10.4",
1413
1413
-
"@babel/runtime": "^7.12.5",
1414
1414
-
"@types/aria-query": "^5.0.1",
1415
1415
-
"aria-query": "5.3.0",
1416
1416
-
"chalk": "^4.1.0",
1417
1417
-
"dom-accessibility-api": "^0.5.9",
1418
1418
-
"lz-string": "^1.5.0",
1419
1419
-
"pretty-format": "^27.0.2"
1420
1420
-
},
1421
1421
-
"engines": {
1422
1422
-
"node": ">=18"
1423
1423
-
}
1424
1424
-
},
1425
1425
-
"node_modules/@testing-library/user-event": {
1426
1426
-
"version": "14.6.1",
1427
1427
-
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
1428
1428
-
"integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
1429
1429
-
"dev": true,
1430
1430
-
"license": "MIT",
1431
1431
-
"engines": {
1432
1432
-
"node": ">=12",
1433
1433
-
"npm": ">=6"
1434
1434
-
},
1435
1435
-
"peerDependencies": {
1436
1436
-
"@testing-library/dom": ">=7.21.4"
1437
1437
-
}
621
621
+
],
622
622
+
"peer": true
1438
623
},
1439
624
"node_modules/@tybys/wasm-util": {
1440
625
"version": "0.9.0",
···
1447
632
"tslib": "^2.4.0"
1448
633
}
1449
634
},
1450
1450
-
"node_modules/@types/aria-query": {
1451
1451
-
"version": "5.0.4",
1452
1452
-
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
1453
1453
-
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
1454
1454
-
"dev": true,
1455
1455
-
"license": "MIT"
1456
1456
-
},
1457
1457
-
"node_modules/@types/cookie": {
1458
1458
-
"version": "0.6.0",
1459
1459
-
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
1460
1460
-
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
1461
1461
-
"dev": true,
1462
1462
-
"license": "MIT"
1463
1463
-
},
1464
635
"node_modules/@types/estree": {
1465
636
"version": "1.0.6",
1466
637
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
1467
638
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
1468
639
"dev": true,
1469
1469
-
"license": "MIT"
640
640
+
"license": "MIT",
641
641
+
"optional": true,
642
642
+
"peer": true
1470
643
},
1471
1471
-
"node_modules/@types/statuses": {
1472
1472
-
"version": "2.0.5",
1473
1473
-
"resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz",
1474
1474
-
"integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==",
644
644
+
"node_modules/@types/node": {
645
645
+
"version": "22.13.11",
646
646
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.11.tgz",
647
647
+
"integrity": "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==",
1475
648
"dev": true,
1476
1476
-
"license": "MIT"
1477
1477
-
},
1478
1478
-
"node_modules/@types/tough-cookie": {
1479
1479
-
"version": "4.0.5",
1480
1480
-
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
1481
1481
-
"integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
1482
1482
-
"dev": true,
1483
1483
-
"license": "MIT"
649
649
+
"license": "MIT",
650
650
+
"dependencies": {
651
651
+
"undici-types": "~6.20.0"
652
652
+
}
1484
653
},
1485
654
"node_modules/@valibot/to-json-schema": {
1486
655
"version": "1.0.0-rc.0",
···
1492
661
"valibot": "^1.0.0 || ^1.0.0-beta.5 || ^1.0.0-rc"
1493
662
}
1494
663
},
1495
1495
-
"node_modules/@vitest/browser": {
1496
1496
-
"version": "3.0.6",
1497
1497
-
"resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-3.0.6.tgz",
1498
1498
-
"integrity": "sha512-FqKwCAkALZfNzGNx4YvRJa6HCWM2USWTjOdNO2egI/s6+3WkIl4xAlYISOARLJLDAI3yCXcpTtuUUF39K8TQgw==",
1499
1499
-
"dev": true,
1500
1500
-
"license": "MIT",
1501
1501
-
"dependencies": {
1502
1502
-
"@testing-library/dom": "^10.4.0",
1503
1503
-
"@testing-library/user-event": "^14.6.1",
1504
1504
-
"@vitest/mocker": "3.0.6",
1505
1505
-
"@vitest/utils": "3.0.6",
1506
1506
-
"magic-string": "^0.30.17",
1507
1507
-
"msw": "^2.7.0",
1508
1508
-
"sirv": "^3.0.1",
1509
1509
-
"tinyrainbow": "^2.0.0",
1510
1510
-
"ws": "^8.18.0"
1511
1511
-
},
1512
1512
-
"funding": {
1513
1513
-
"url": "https://opencollective.com/vitest"
1514
1514
-
},
1515
1515
-
"peerDependencies": {
1516
1516
-
"playwright": "*",
1517
1517
-
"vitest": "3.0.6",
1518
1518
-
"webdriverio": "*"
1519
1519
-
},
1520
1520
-
"peerDependenciesMeta": {
1521
1521
-
"playwright": {
1522
1522
-
"optional": true
1523
1523
-
},
1524
1524
-
"safaridriver": {
1525
1525
-
"optional": true
1526
1526
-
},
1527
1527
-
"webdriverio": {
1528
1528
-
"optional": true
1529
1529
-
}
1530
1530
-
}
1531
1531
-
},
1532
1532
-
"node_modules/@vitest/coverage-v8": {
1533
1533
-
"version": "3.0.6",
1534
1534
-
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.6.tgz",
1535
1535
-
"integrity": "sha512-JRTlR8Bw+4BcmVTICa7tJsxqphAktakiLsAmibVLAWbu1lauFddY/tXeM6sAyl1cgkPuXtpnUgaCPhTdz1Qapg==",
1536
1536
-
"dev": true,
1537
1537
-
"license": "MIT",
1538
1538
-
"dependencies": {
1539
1539
-
"@ampproject/remapping": "^2.3.0",
1540
1540
-
"@bcoe/v8-coverage": "^1.0.2",
1541
1541
-
"debug": "^4.4.0",
1542
1542
-
"istanbul-lib-coverage": "^3.2.2",
1543
1543
-
"istanbul-lib-report": "^3.0.1",
1544
1544
-
"istanbul-lib-source-maps": "^5.0.6",
1545
1545
-
"istanbul-reports": "^3.1.7",
1546
1546
-
"magic-string": "^0.30.17",
1547
1547
-
"magicast": "^0.3.5",
1548
1548
-
"std-env": "^3.8.0",
1549
1549
-
"test-exclude": "^7.0.1",
1550
1550
-
"tinyrainbow": "^2.0.0"
1551
1551
-
},
1552
1552
-
"funding": {
1553
1553
-
"url": "https://opencollective.com/vitest"
1554
1554
-
},
1555
1555
-
"peerDependencies": {
1556
1556
-
"@vitest/browser": "3.0.6",
1557
1557
-
"vitest": "3.0.6"
1558
1558
-
},
1559
1559
-
"peerDependenciesMeta": {
1560
1560
-
"@vitest/browser": {
1561
1561
-
"optional": true
1562
1562
-
}
1563
1563
-
}
1564
1564
-
},
1565
1565
-
"node_modules/@vitest/expect": {
1566
1566
-
"version": "3.0.6",
1567
1567
-
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.6.tgz",
1568
1568
-
"integrity": "sha512-zBduHf/ja7/QRX4HdP1DSq5XrPgdN+jzLOwaTq/0qZjYfgETNFCKf9nOAp2j3hmom3oTbczuUzrzg9Hafh7hNg==",
1569
1569
-
"dev": true,
1570
1570
-
"license": "MIT",
1571
1571
-
"dependencies": {
1572
1572
-
"@vitest/spy": "3.0.6",
1573
1573
-
"@vitest/utils": "3.0.6",
1574
1574
-
"chai": "^5.2.0",
1575
1575
-
"tinyrainbow": "^2.0.0"
1576
1576
-
},
1577
1577
-
"funding": {
1578
1578
-
"url": "https://opencollective.com/vitest"
1579
1579
-
}
1580
1580
-
},
1581
1581
-
"node_modules/@vitest/mocker": {
1582
1582
-
"version": "3.0.6",
1583
1583
-
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.6.tgz",
1584
1584
-
"integrity": "sha512-KPztr4/tn7qDGZfqlSPQoF2VgJcKxnDNhmfR3VgZ6Fy1bO8T9Fc1stUiTXtqz0yG24VpD00pZP5f8EOFknjNuQ==",
1585
1585
-
"dev": true,
1586
1586
-
"license": "MIT",
1587
1587
-
"dependencies": {
1588
1588
-
"@vitest/spy": "3.0.6",
1589
1589
-
"estree-walker": "^3.0.3",
1590
1590
-
"magic-string": "^0.30.17"
1591
1591
-
},
1592
1592
-
"funding": {
1593
1593
-
"url": "https://opencollective.com/vitest"
1594
1594
-
},
1595
1595
-
"peerDependencies": {
1596
1596
-
"msw": "^2.4.9",
1597
1597
-
"vite": "^5.0.0 || ^6.0.0"
1598
1598
-
},
1599
1599
-
"peerDependenciesMeta": {
1600
1600
-
"msw": {
1601
1601
-
"optional": true
1602
1602
-
},
1603
1603
-
"vite": {
1604
1604
-
"optional": true
1605
1605
-
}
1606
1606
-
}
1607
1607
-
},
1608
1608
-
"node_modules/@vitest/pretty-format": {
1609
1609
-
"version": "3.0.6",
1610
1610
-
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.6.tgz",
1611
1611
-
"integrity": "sha512-Zyctv3dbNL+67qtHfRnUE/k8qxduOamRfAL1BurEIQSyOEFffoMvx2pnDSSbKAAVxY0Ej2J/GH2dQKI0W2JyVg==",
1612
1612
-
"dev": true,
1613
1613
-
"license": "MIT",
1614
1614
-
"dependencies": {
1615
1615
-
"tinyrainbow": "^2.0.0"
1616
1616
-
},
1617
1617
-
"funding": {
1618
1618
-
"url": "https://opencollective.com/vitest"
1619
1619
-
}
1620
1620
-
},
1621
1621
-
"node_modules/@vitest/runner": {
1622
1622
-
"version": "3.0.6",
1623
1623
-
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.6.tgz",
1624
1624
-
"integrity": "sha512-JopP4m/jGoaG1+CBqubV/5VMbi7L+NQCJTu1J1Pf6YaUbk7bZtaq5CX7p+8sY64Sjn1UQ1XJparHfcvTTdu9cA==",
1625
1625
-
"dev": true,
1626
1626
-
"license": "MIT",
1627
1627
-
"dependencies": {
1628
1628
-
"@vitest/utils": "3.0.6",
1629
1629
-
"pathe": "^2.0.3"
1630
1630
-
},
1631
1631
-
"funding": {
1632
1632
-
"url": "https://opencollective.com/vitest"
1633
1633
-
}
1634
1634
-
},
1635
1635
-
"node_modules/@vitest/snapshot": {
1636
1636
-
"version": "3.0.6",
1637
1637
-
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.6.tgz",
1638
1638
-
"integrity": "sha512-qKSmxNQwT60kNwwJHMVwavvZsMGXWmngD023OHSgn873pV0lylK7dwBTfYP7e4URy5NiBCHHiQGA9DHkYkqRqg==",
1639
1639
-
"dev": true,
1640
1640
-
"license": "MIT",
1641
1641
-
"dependencies": {
1642
1642
-
"@vitest/pretty-format": "3.0.6",
1643
1643
-
"magic-string": "^0.30.17",
1644
1644
-
"pathe": "^2.0.3"
1645
1645
-
},
1646
1646
-
"funding": {
1647
1647
-
"url": "https://opencollective.com/vitest"
1648
1648
-
}
1649
1649
-
},
1650
1650
-
"node_modules/@vitest/spy": {
1651
1651
-
"version": "3.0.6",
1652
1652
-
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.6.tgz",
1653
1653
-
"integrity": "sha512-HfOGx/bXtjy24fDlTOpgiAEJbRfFxoX3zIGagCqACkFKKZ/TTOE6gYMKXlqecvxEndKFuNHcHqP081ggZ2yM0Q==",
1654
1654
-
"dev": true,
1655
1655
-
"license": "MIT",
1656
1656
-
"dependencies": {
1657
1657
-
"tinyspy": "^3.0.2"
1658
1658
-
},
1659
1659
-
"funding": {
1660
1660
-
"url": "https://opencollective.com/vitest"
1661
1661
-
}
1662
1662
-
},
1663
1663
-
"node_modules/@vitest/ui": {
1664
1664
-
"version": "3.0.6",
1665
1665
-
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.0.6.tgz",
1666
1666
-
"integrity": "sha512-N4M2IUG2Q5LCeX4OWs48pQF4P3qsFejmDTc6QWGRFTLPrEe5EvM5HN0WSUnGAmuzQpSWv7ItfSsIJIWaEM2wpQ==",
1667
1667
-
"dev": true,
1668
1668
-
"license": "MIT",
1669
1669
-
"dependencies": {
1670
1670
-
"@vitest/utils": "3.0.6",
1671
1671
-
"fflate": "^0.8.2",
1672
1672
-
"flatted": "^3.3.2",
1673
1673
-
"pathe": "^2.0.3",
1674
1674
-
"sirv": "^3.0.1",
1675
1675
-
"tinyglobby": "^0.2.11",
1676
1676
-
"tinyrainbow": "^2.0.0"
1677
1677
-
},
1678
1678
-
"funding": {
1679
1679
-
"url": "https://opencollective.com/vitest"
1680
1680
-
},
1681
1681
-
"peerDependencies": {
1682
1682
-
"vitest": "3.0.6"
1683
1683
-
}
1684
1684
-
},
1685
1685
-
"node_modules/@vitest/utils": {
1686
1686
-
"version": "3.0.6",
1687
1687
-
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.6.tgz",
1688
1688
-
"integrity": "sha512-18ktZpf4GQFTbf9jK543uspU03Q2qya7ZGya5yiZ0Gx0nnnalBvd5ZBislbl2EhLjM8A8rt4OilqKG7QwcGkvQ==",
1689
1689
-
"dev": true,
1690
1690
-
"license": "MIT",
1691
1691
-
"dependencies": {
1692
1692
-
"@vitest/pretty-format": "3.0.6",
1693
1693
-
"loupe": "^3.1.3",
1694
1694
-
"tinyrainbow": "^2.0.0"
1695
1695
-
},
1696
1696
-
"funding": {
1697
1697
-
"url": "https://opencollective.com/vitest"
1698
1698
-
}
1699
1699
-
},
1700
664
"node_modules/acorn": {
1701
665
"version": "8.14.0",
1702
666
"dev": true,
···
1708
672
"node": ">=0.4.0"
1709
673
}
1710
674
},
1711
1711
-
"node_modules/ansi-escapes": {
1712
1712
-
"version": "4.3.2",
1713
1713
-
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
1714
1714
-
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
1715
1715
-
"dev": true,
1716
1716
-
"license": "MIT",
1717
1717
-
"dependencies": {
1718
1718
-
"type-fest": "^0.21.3"
1719
1719
-
},
1720
1720
-
"engines": {
1721
1721
-
"node": ">=8"
1722
1722
-
},
1723
1723
-
"funding": {
1724
1724
-
"url": "https://github.com/sponsors/sindresorhus"
1725
1725
-
}
1726
1726
-
},
1727
1727
-
"node_modules/ansi-escapes/node_modules/type-fest": {
1728
1728
-
"version": "0.21.3",
1729
1729
-
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
1730
1730
-
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
1731
1731
-
"dev": true,
1732
1732
-
"license": "(MIT OR CC0-1.0)",
1733
1733
-
"engines": {
1734
1734
-
"node": ">=10"
1735
1735
-
},
1736
1736
-
"funding": {
1737
1737
-
"url": "https://github.com/sponsors/sindresorhus"
1738
1738
-
}
1739
1739
-
},
1740
1740
-
"node_modules/ansi-regex": {
1741
1741
-
"version": "5.0.1",
1742
1742
-
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1743
1743
-
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1744
1744
-
"dev": true,
1745
1745
-
"license": "MIT",
1746
1746
-
"engines": {
1747
1747
-
"node": ">=8"
1748
1748
-
}
1749
1749
-
},
1750
1750
-
"node_modules/ansi-styles": {
1751
1751
-
"version": "4.3.0",
1752
1752
-
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1753
1753
-
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1754
1754
-
"dev": true,
1755
1755
-
"license": "MIT",
1756
1756
-
"dependencies": {
1757
1757
-
"color-convert": "^2.0.1"
1758
1758
-
},
1759
1759
-
"engines": {
1760
1760
-
"node": ">=8"
1761
1761
-
},
1762
1762
-
"funding": {
1763
1763
-
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
1764
1764
-
}
1765
1765
-
},
1766
1766
-
"node_modules/aria-query": {
1767
1767
-
"version": "5.3.0",
1768
1768
-
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
1769
1769
-
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
1770
1770
-
"dev": true,
1771
1771
-
"license": "Apache-2.0",
1772
1772
-
"dependencies": {
1773
1773
-
"dequal": "^2.0.3"
1774
1774
-
}
1775
1775
-
},
1776
1776
-
"node_modules/assertion-error": {
1777
1777
-
"version": "2.0.1",
1778
1778
-
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
1779
1779
-
"integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
1780
1780
-
"dev": true,
1781
1781
-
"license": "MIT",
1782
1782
-
"engines": {
1783
1783
-
"node": ">=12"
1784
1784
-
}
1785
1785
-
},
1786
1786
-
"node_modules/balanced-match": {
1787
1787
-
"version": "1.0.2",
1788
1788
-
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1789
1789
-
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1790
1790
-
"dev": true,
1791
1791
-
"license": "MIT"
1792
1792
-
},
1793
1793
-
"node_modules/brace-expansion": {
1794
1794
-
"version": "2.0.1",
1795
1795
-
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
1796
1796
-
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
1797
1797
-
"dev": true,
1798
1798
-
"license": "MIT",
1799
1799
-
"dependencies": {
1800
1800
-
"balanced-match": "^1.0.0"
1801
1801
-
}
1802
1802
-
},
1803
675
"node_modules/buffer-from": {
1804
676
"version": "1.1.2",
1805
677
"dev": true,
1806
678
"license": "MIT"
1807
679
},
1808
1808
-
"node_modules/cac": {
1809
1809
-
"version": "6.7.14",
1810
1810
-
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
1811
1811
-
"integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
1812
1812
-
"dev": true,
1813
1813
-
"license": "MIT",
1814
1814
-
"engines": {
1815
1815
-
"node": ">=8"
1816
1816
-
}
1817
1817
-
},
1818
1818
-
"node_modules/chai": {
1819
1819
-
"version": "5.2.0",
1820
1820
-
"resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz",
1821
1821
-
"integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==",
1822
1822
-
"dev": true,
1823
1823
-
"license": "MIT",
1824
1824
-
"dependencies": {
1825
1825
-
"assertion-error": "^2.0.1",
1826
1826
-
"check-error": "^2.1.1",
1827
1827
-
"deep-eql": "^5.0.1",
1828
1828
-
"loupe": "^3.1.0",
1829
1829
-
"pathval": "^2.0.0"
1830
1830
-
},
1831
1831
-
"engines": {
1832
1832
-
"node": ">=12"
1833
1833
-
}
1834
1834
-
},
1835
1835
-
"node_modules/chalk": {
1836
1836
-
"version": "4.1.2",
1837
1837
-
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
1838
1838
-
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
1839
1839
-
"dev": true,
1840
1840
-
"license": "MIT",
1841
1841
-
"dependencies": {
1842
1842
-
"ansi-styles": "^4.1.0",
1843
1843
-
"supports-color": "^7.1.0"
1844
1844
-
},
1845
1845
-
"engines": {
1846
1846
-
"node": ">=10"
1847
1847
-
},
1848
1848
-
"funding": {
1849
1849
-
"url": "https://github.com/chalk/chalk?sponsor=1"
1850
1850
-
}
1851
1851
-
},
1852
1852
-
"node_modules/check-error": {
1853
1853
-
"version": "2.1.1",
1854
1854
-
"resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
1855
1855
-
"integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
1856
1856
-
"dev": true,
1857
1857
-
"license": "MIT",
1858
1858
-
"engines": {
1859
1859
-
"node": ">= 16"
1860
1860
-
}
1861
1861
-
},
1862
1862
-
"node_modules/cli-width": {
1863
1863
-
"version": "4.1.0",
1864
1864
-
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
1865
1865
-
"integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
1866
1866
-
"dev": true,
1867
1867
-
"license": "ISC",
1868
1868
-
"engines": {
1869
1869
-
"node": ">= 12"
1870
1870
-
}
1871
1871
-
},
1872
1872
-
"node_modules/cliui": {
1873
1873
-
"version": "8.0.1",
1874
1874
-
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
1875
1875
-
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
1876
1876
-
"dev": true,
1877
1877
-
"license": "ISC",
1878
1878
-
"dependencies": {
1879
1879
-
"string-width": "^4.2.0",
1880
1880
-
"strip-ansi": "^6.0.1",
1881
1881
-
"wrap-ansi": "^7.0.0"
1882
1882
-
},
1883
1883
-
"engines": {
1884
1884
-
"node": ">=12"
1885
1885
-
}
1886
1886
-
},
1887
1887
-
"node_modules/cliui/node_modules/wrap-ansi": {
1888
1888
-
"version": "7.0.0",
1889
1889
-
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1890
1890
-
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1891
1891
-
"dev": true,
1892
1892
-
"license": "MIT",
1893
1893
-
"dependencies": {
1894
1894
-
"ansi-styles": "^4.0.0",
1895
1895
-
"string-width": "^4.1.0",
1896
1896
-
"strip-ansi": "^6.0.0"
1897
1897
-
},
1898
1898
-
"engines": {
1899
1899
-
"node": ">=10"
1900
1900
-
},
1901
1901
-
"funding": {
1902
1902
-
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1903
1903
-
}
1904
1904
-
},
1905
1905
-
"node_modules/color-convert": {
1906
1906
-
"version": "2.0.1",
1907
1907
-
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1908
1908
-
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1909
1909
-
"dev": true,
1910
1910
-
"license": "MIT",
1911
1911
-
"dependencies": {
1912
1912
-
"color-name": "~1.1.4"
1913
1913
-
},
1914
1914
-
"engines": {
1915
1915
-
"node": ">=7.0.0"
1916
1916
-
}
1917
1917
-
},
1918
1918
-
"node_modules/color-name": {
1919
1919
-
"version": "1.1.4",
1920
1920
-
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1921
1921
-
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1922
1922
-
"dev": true,
1923
1923
-
"license": "MIT"
1924
1924
-
},
1925
680
"node_modules/commander": {
1926
681
"version": "2.20.3",
1927
682
"dev": true,
1928
683
"license": "MIT"
1929
684
},
1930
1930
-
"node_modules/cookie": {
1931
1931
-
"version": "0.7.2",
1932
1932
-
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
1933
1933
-
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
1934
1934
-
"dev": true,
1935
1935
-
"license": "MIT",
1936
1936
-
"engines": {
1937
1937
-
"node": ">= 0.6"
1938
1938
-
}
1939
1939
-
},
1940
1940
-
"node_modules/cross-spawn": {
1941
1941
-
"version": "7.0.6",
1942
1942
-
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
1943
1943
-
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
1944
1944
-
"dev": true,
1945
1945
-
"license": "MIT",
1946
1946
-
"dependencies": {
1947
1947
-
"path-key": "^3.1.0",
1948
1948
-
"shebang-command": "^2.0.0",
1949
1949
-
"which": "^2.0.1"
1950
1950
-
},
1951
1951
-
"engines": {
1952
1952
-
"node": ">= 8"
1953
1953
-
}
1954
1954
-
},
1955
1955
-
"node_modules/debug": {
1956
1956
-
"version": "4.4.0",
1957
1957
-
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
1958
1958
-
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
1959
1959
-
"dev": true,
1960
1960
-
"license": "MIT",
1961
1961
-
"dependencies": {
1962
1962
-
"ms": "^2.1.3"
1963
1963
-
},
1964
1964
-
"engines": {
1965
1965
-
"node": ">=6.0"
1966
1966
-
},
1967
1967
-
"peerDependenciesMeta": {
1968
1968
-
"supports-color": {
1969
1969
-
"optional": true
1970
1970
-
}
1971
1971
-
}
1972
1972
-
},
1973
1973
-
"node_modules/deep-eql": {
1974
1974
-
"version": "5.0.2",
1975
1975
-
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
1976
1976
-
"integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
1977
1977
-
"dev": true,
1978
1978
-
"license": "MIT",
1979
1979
-
"engines": {
1980
1980
-
"node": ">=6"
1981
1981
-
}
1982
1982
-
},
1983
1983
-
"node_modules/dequal": {
1984
1984
-
"version": "2.0.3",
1985
1985
-
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
1986
1986
-
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
1987
1987
-
"dev": true,
1988
1988
-
"license": "MIT",
1989
1989
-
"engines": {
1990
1990
-
"node": ">=6"
1991
1991
-
}
1992
1992
-
},
1993
685
"node_modules/dhtml": {
1994
686
"resolved": "",
1995
687
"link": true
1996
1996
-
},
1997
1997
-
"node_modules/dom-accessibility-api": {
1998
1998
-
"version": "0.5.16",
1999
1999
-
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
2000
2000
-
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
2001
2001
-
"dev": true,
2002
2002
-
"license": "MIT"
2003
688
},
2004
689
"node_modules/dom-serializer": {
2005
690
"version": "2.0.0",
···
2096
781
"typescript": ">=5.0.4 <5.8"
2097
782
}
2098
783
},
2099
2099
-
"node_modules/eastasianwidth": {
2100
2100
-
"version": "0.2.0",
2101
2101
-
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
2102
2102
-
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
2103
2103
-
"dev": true,
2104
2104
-
"license": "MIT"
2105
2105
-
},
2106
2106
-
"node_modules/emoji-regex": {
2107
2107
-
"version": "8.0.0",
2108
2108
-
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2109
2109
-
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2110
2110
-
"dev": true,
2111
2111
-
"license": "MIT"
2112
2112
-
},
2113
784
"node_modules/entities": {
2114
785
"version": "6.0.0",
2115
786
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
···
2123
794
"url": "https://github.com/fb55/entities?sponsor=1"
2124
795
}
2125
796
},
2126
2126
-
"node_modules/es-module-lexer": {
2127
2127
-
"version": "1.6.0",
2128
2128
-
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
2129
2129
-
"integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
2130
2130
-
"dev": true,
2131
2131
-
"license": "MIT"
2132
2132
-
},
2133
2133
-
"node_modules/esbuild": {
2134
2134
-
"version": "0.24.2",
2135
2135
-
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
2136
2136
-
"integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
2137
2137
-
"dev": true,
2138
2138
-
"hasInstallScript": true,
2139
2139
-
"license": "MIT",
2140
2140
-
"bin": {
2141
2141
-
"esbuild": "bin/esbuild"
2142
2142
-
},
2143
2143
-
"engines": {
2144
2144
-
"node": ">=18"
2145
2145
-
},
2146
2146
-
"optionalDependencies": {
2147
2147
-
"@esbuild/aix-ppc64": "0.24.2",
2148
2148
-
"@esbuild/android-arm": "0.24.2",
2149
2149
-
"@esbuild/android-arm64": "0.24.2",
2150
2150
-
"@esbuild/android-x64": "0.24.2",
2151
2151
-
"@esbuild/darwin-arm64": "0.24.2",
2152
2152
-
"@esbuild/darwin-x64": "0.24.2",
2153
2153
-
"@esbuild/freebsd-arm64": "0.24.2",
2154
2154
-
"@esbuild/freebsd-x64": "0.24.2",
2155
2155
-
"@esbuild/linux-arm": "0.24.2",
2156
2156
-
"@esbuild/linux-arm64": "0.24.2",
2157
2157
-
"@esbuild/linux-ia32": "0.24.2",
2158
2158
-
"@esbuild/linux-loong64": "0.24.2",
2159
2159
-
"@esbuild/linux-mips64el": "0.24.2",
2160
2160
-
"@esbuild/linux-ppc64": "0.24.2",
2161
2161
-
"@esbuild/linux-riscv64": "0.24.2",
2162
2162
-
"@esbuild/linux-s390x": "0.24.2",
2163
2163
-
"@esbuild/linux-x64": "0.24.2",
2164
2164
-
"@esbuild/netbsd-arm64": "0.24.2",
2165
2165
-
"@esbuild/netbsd-x64": "0.24.2",
2166
2166
-
"@esbuild/openbsd-arm64": "0.24.2",
2167
2167
-
"@esbuild/openbsd-x64": "0.24.2",
2168
2168
-
"@esbuild/sunos-x64": "0.24.2",
2169
2169
-
"@esbuild/win32-arm64": "0.24.2",
2170
2170
-
"@esbuild/win32-ia32": "0.24.2",
2171
2171
-
"@esbuild/win32-x64": "0.24.2"
2172
2172
-
}
2173
2173
-
},
2174
2174
-
"node_modules/escalade": {
2175
2175
-
"version": "3.2.0",
2176
2176
-
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
2177
2177
-
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
2178
2178
-
"dev": true,
2179
2179
-
"license": "MIT",
2180
2180
-
"engines": {
2181
2181
-
"node": ">=6"
2182
2182
-
}
2183
2183
-
},
2184
2184
-
"node_modules/estree-walker": {
2185
2185
-
"version": "3.0.3",
2186
2186
-
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
2187
2187
-
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
2188
2188
-
"dev": true,
2189
2189
-
"license": "MIT",
2190
2190
-
"dependencies": {
2191
2191
-
"@types/estree": "^1.0.0"
2192
2192
-
}
2193
2193
-
},
2194
2194
-
"node_modules/expect-type": {
2195
2195
-
"version": "1.1.0",
2196
2196
-
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz",
2197
2197
-
"integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==",
2198
2198
-
"dev": true,
2199
2199
-
"license": "Apache-2.0",
2200
2200
-
"engines": {
2201
2201
-
"node": ">=12.0.0"
2202
2202
-
}
2203
2203
-
},
2204
797
"node_modules/fdir": {
2205
798
"version": "6.4.3",
2206
799
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
···
2216
809
}
2217
810
}
2218
811
},
2219
2219
-
"node_modules/fflate": {
2220
2220
-
"version": "0.8.2",
2221
2221
-
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
2222
2222
-
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
2223
2223
-
"dev": true,
2224
2224
-
"license": "MIT"
2225
2225
-
},
2226
2226
-
"node_modules/flatted": {
2227
2227
-
"version": "3.3.2",
2228
2228
-
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
2229
2229
-
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
2230
2230
-
"dev": true,
2231
2231
-
"license": "ISC"
2232
2232
-
},
2233
2233
-
"node_modules/foreground-child": {
2234
2234
-
"version": "3.3.0",
2235
2235
-
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
2236
2236
-
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
2237
2237
-
"dev": true,
2238
2238
-
"license": "ISC",
2239
2239
-
"dependencies": {
2240
2240
-
"cross-spawn": "^7.0.0",
2241
2241
-
"signal-exit": "^4.0.1"
2242
2242
-
},
2243
2243
-
"engines": {
2244
2244
-
"node": ">=14"
2245
2245
-
},
2246
2246
-
"funding": {
2247
2247
-
"url": "https://github.com/sponsors/isaacs"
2248
2248
-
}
2249
2249
-
},
2250
812
"node_modules/fsevents": {
2251
813
"version": "2.3.3",
2252
814
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
···
2258
820
"os": [
2259
821
"darwin"
2260
822
],
823
823
+
"peer": true,
2261
824
"engines": {
2262
825
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
2263
826
}
2264
827
},
2265
2265
-
"node_modules/get-caller-file": {
2266
2266
-
"version": "2.0.5",
2267
2267
-
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
2268
2268
-
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
2269
2269
-
"dev": true,
2270
2270
-
"license": "ISC",
2271
2271
-
"engines": {
2272
2272
-
"node": "6.* || 8.* || >= 10.*"
2273
2273
-
}
2274
2274
-
},
2275
2275
-
"node_modules/glob": {
2276
2276
-
"version": "10.4.5",
2277
2277
-
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
2278
2278
-
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
2279
2279
-
"dev": true,
2280
2280
-
"license": "ISC",
2281
2281
-
"dependencies": {
2282
2282
-
"foreground-child": "^3.1.0",
2283
2283
-
"jackspeak": "^3.1.2",
2284
2284
-
"minimatch": "^9.0.4",
2285
2285
-
"minipass": "^7.1.2",
2286
2286
-
"package-json-from-dist": "^1.0.0",
2287
2287
-
"path-scurry": "^1.11.1"
2288
2288
-
},
2289
2289
-
"bin": {
2290
2290
-
"glob": "dist/esm/bin.mjs"
2291
2291
-
},
2292
2292
-
"funding": {
2293
2293
-
"url": "https://github.com/sponsors/isaacs"
2294
2294
-
}
2295
2295
-
},
2296
2296
-
"node_modules/graphql": {
2297
2297
-
"version": "16.10.0",
2298
2298
-
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz",
2299
2299
-
"integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==",
2300
2300
-
"dev": true,
2301
2301
-
"license": "MIT",
2302
2302
-
"engines": {
2303
2303
-
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
2304
2304
-
}
2305
2305
-
},
2306
828
"node_modules/happy-dom": {
2307
2307
-
"version": "17.0.0",
2308
2308
-
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.0.0.tgz",
2309
2309
-
"integrity": "sha512-jGuUr3UrgMzt1Mopyof3RzD49/GudAp1suP5KFU+EvNXmqUAMXpxux2zEJbabE1YXs0APrY61iRZ0BKMMWCGTg==",
829
829
+
"version": "17.4.4",
830
830
+
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.4.4.tgz",
831
831
+
"integrity": "sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA==",
2310
832
"dev": true,
2311
833
"license": "MIT",
2312
2312
-
"optional": true,
2313
2313
-
"peer": true,
2314
834
"dependencies": {
2315
835
"webidl-conversions": "^7.0.0",
2316
836
"whatwg-mimetype": "^3.0.0"
···
2319
839
"node": ">=18.0.0"
2320
840
}
2321
841
},
2322
2322
-
"node_modules/has-flag": {
2323
2323
-
"version": "4.0.0",
2324
2324
-
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
2325
2325
-
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
2326
2326
-
"dev": true,
2327
2327
-
"license": "MIT",
2328
2328
-
"engines": {
2329
2329
-
"node": ">=8"
2330
2330
-
}
2331
2331
-
},
2332
2332
-
"node_modules/headers-polyfill": {
2333
2333
-
"version": "4.0.3",
2334
2334
-
"resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz",
2335
2335
-
"integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==",
2336
2336
-
"dev": true,
2337
2337
-
"license": "MIT"
2338
2338
-
},
2339
2339
-
"node_modules/html-escaper": {
2340
2340
-
"version": "2.0.2",
2341
2341
-
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
2342
2342
-
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
2343
2343
-
"dev": true,
2344
2344
-
"license": "MIT"
2345
2345
-
},
2346
842
"node_modules/htmlparser2": {
2347
843
"version": "10.0.0",
2348
844
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
···
2363
859
"entities": "^6.0.0"
2364
860
}
2365
861
},
2366
2366
-
"node_modules/is-fullwidth-code-point": {
2367
2367
-
"version": "3.0.0",
2368
2368
-
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
2369
2369
-
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
2370
2370
-
"dev": true,
2371
2371
-
"license": "MIT",
2372
2372
-
"engines": {
2373
2373
-
"node": ">=8"
2374
2374
-
}
2375
2375
-
},
2376
2376
-
"node_modules/is-node-process": {
2377
2377
-
"version": "1.2.0",
2378
2378
-
"resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
2379
2379
-
"integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==",
2380
2380
-
"dev": true,
2381
2381
-
"license": "MIT"
2382
2382
-
},
2383
2383
-
"node_modules/isexe": {
2384
2384
-
"version": "2.0.0",
2385
2385
-
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
2386
2386
-
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
2387
2387
-
"dev": true,
2388
2388
-
"license": "ISC"
2389
2389
-
},
2390
2390
-
"node_modules/istanbul-lib-coverage": {
2391
2391
-
"version": "3.2.2",
2392
2392
-
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
2393
2393
-
"integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
2394
2394
-
"dev": true,
2395
2395
-
"license": "BSD-3-Clause",
2396
2396
-
"engines": {
2397
2397
-
"node": ">=8"
2398
2398
-
}
2399
2399
-
},
2400
2400
-
"node_modules/istanbul-lib-report": {
2401
2401
-
"version": "3.0.1",
2402
2402
-
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
2403
2403
-
"integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
2404
2404
-
"dev": true,
2405
2405
-
"license": "BSD-3-Clause",
2406
2406
-
"dependencies": {
2407
2407
-
"istanbul-lib-coverage": "^3.0.0",
2408
2408
-
"make-dir": "^4.0.0",
2409
2409
-
"supports-color": "^7.1.0"
2410
2410
-
},
2411
2411
-
"engines": {
2412
2412
-
"node": ">=10"
2413
2413
-
}
2414
2414
-
},
2415
2415
-
"node_modules/istanbul-lib-source-maps": {
2416
2416
-
"version": "5.0.6",
2417
2417
-
"resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
2418
2418
-
"integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
2419
2419
-
"dev": true,
2420
2420
-
"license": "BSD-3-Clause",
2421
2421
-
"dependencies": {
2422
2422
-
"@jridgewell/trace-mapping": "^0.3.23",
2423
2423
-
"debug": "^4.1.1",
2424
2424
-
"istanbul-lib-coverage": "^3.0.0"
2425
2425
-
},
2426
2426
-
"engines": {
2427
2427
-
"node": ">=10"
2428
2428
-
}
2429
2429
-
},
2430
2430
-
"node_modules/istanbul-reports": {
2431
2431
-
"version": "3.1.7",
2432
2432
-
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
2433
2433
-
"integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
2434
2434
-
"dev": true,
2435
2435
-
"license": "BSD-3-Clause",
2436
2436
-
"dependencies": {
2437
2437
-
"html-escaper": "^2.0.0",
2438
2438
-
"istanbul-lib-report": "^3.0.0"
2439
2439
-
},
2440
2440
-
"engines": {
2441
2441
-
"node": ">=8"
2442
2442
-
}
2443
2443
-
},
2444
2444
-
"node_modules/jackspeak": {
2445
2445
-
"version": "3.4.3",
2446
2446
-
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
2447
2447
-
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
2448
2448
-
"dev": true,
2449
2449
-
"license": "BlueOak-1.0.0",
2450
2450
-
"dependencies": {
2451
2451
-
"@isaacs/cliui": "^8.0.2"
2452
2452
-
},
2453
2453
-
"funding": {
2454
2454
-
"url": "https://github.com/sponsors/isaacs"
2455
2455
-
},
2456
2456
-
"optionalDependencies": {
2457
2457
-
"@pkgjs/parseargs": "^0.11.0"
2458
2458
-
}
2459
2459
-
},
2460
2460
-
"node_modules/js-tokens": {
2461
2461
-
"version": "4.0.0",
2462
2462
-
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
2463
2463
-
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
2464
2464
-
"dev": true,
2465
2465
-
"license": "MIT"
2466
2466
-
},
2467
862
"node_modules/kleur": {
2468
863
"version": "4.1.5",
2469
864
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
···
2481
876
"dev": true,
2482
877
"license": "MIT"
2483
878
},
2484
2484
-
"node_modules/loupe": {
2485
2485
-
"version": "3.1.3",
2486
2486
-
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz",
2487
2487
-
"integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==",
2488
2488
-
"dev": true,
2489
2489
-
"license": "MIT"
2490
2490
-
},
2491
2491
-
"node_modules/lru-cache": {
2492
2492
-
"version": "10.4.3",
2493
2493
-
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
2494
2494
-
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
2495
2495
-
"dev": true,
2496
2496
-
"license": "ISC"
2497
2497
-
},
2498
2498
-
"node_modules/lz-string": {
2499
2499
-
"version": "1.5.0",
2500
2500
-
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
2501
2501
-
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
2502
2502
-
"dev": true,
2503
2503
-
"license": "MIT",
2504
2504
-
"bin": {
2505
2505
-
"lz-string": "bin/bin.js"
2506
2506
-
}
2507
2507
-
},
2508
879
"node_modules/magic-string": {
2509
880
"version": "0.30.17",
2510
881
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
···
2513
884
"license": "MIT",
2514
885
"dependencies": {
2515
886
"@jridgewell/sourcemap-codec": "^1.5.0"
2516
2516
-
}
2517
2517
-
},
2518
2518
-
"node_modules/magicast": {
2519
2519
-
"version": "0.3.5",
2520
2520
-
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
2521
2521
-
"integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
2522
2522
-
"dev": true,
2523
2523
-
"license": "MIT",
2524
2524
-
"dependencies": {
2525
2525
-
"@babel/parser": "^7.25.4",
2526
2526
-
"@babel/types": "^7.25.4",
2527
2527
-
"source-map-js": "^1.2.0"
2528
2528
-
}
2529
2529
-
},
2530
2530
-
"node_modules/make-dir": {
2531
2531
-
"version": "4.0.0",
2532
2532
-
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
2533
2533
-
"integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
2534
2534
-
"dev": true,
2535
2535
-
"license": "MIT",
2536
2536
-
"dependencies": {
2537
2537
-
"semver": "^7.5.3"
2538
2538
-
},
2539
2539
-
"engines": {
2540
2540
-
"node": ">=10"
2541
2541
-
},
2542
2542
-
"funding": {
2543
2543
-
"url": "https://github.com/sponsors/sindresorhus"
2544
2544
-
}
2545
2545
-
},
2546
2546
-
"node_modules/minimatch": {
2547
2547
-
"version": "9.0.5",
2548
2548
-
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
2549
2549
-
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
2550
2550
-
"dev": true,
2551
2551
-
"license": "ISC",
2552
2552
-
"dependencies": {
2553
2553
-
"brace-expansion": "^2.0.1"
2554
2554
-
},
2555
2555
-
"engines": {
2556
2556
-
"node": ">=16 || 14 >=14.17"
2557
2557
-
},
2558
2558
-
"funding": {
2559
2559
-
"url": "https://github.com/sponsors/isaacs"
2560
2560
-
}
2561
2561
-
},
2562
2562
-
"node_modules/minipass": {
2563
2563
-
"version": "7.1.2",
2564
2564
-
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
2565
2565
-
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
2566
2566
-
"dev": true,
2567
2567
-
"license": "ISC",
2568
2568
-
"engines": {
2569
2569
-
"node": ">=16 || 14 >=14.17"
2570
887
}
2571
888
},
2572
889
"node_modules/mri": {
···
2579
896
"node": ">=4"
2580
897
}
2581
898
},
2582
2582
-
"node_modules/mrmime": {
2583
2583
-
"version": "2.0.1",
2584
2584
-
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
2585
2585
-
"integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
2586
2586
-
"dev": true,
2587
2587
-
"license": "MIT",
2588
2588
-
"engines": {
2589
2589
-
"node": ">=10"
2590
2590
-
}
2591
2591
-
},
2592
2592
-
"node_modules/ms": {
2593
2593
-
"version": "2.1.3",
2594
2594
-
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
2595
2595
-
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
2596
2596
-
"dev": true,
2597
2597
-
"license": "MIT"
2598
2598
-
},
2599
2599
-
"node_modules/msw": {
2600
2600
-
"version": "2.7.0",
2601
2601
-
"resolved": "https://registry.npmjs.org/msw/-/msw-2.7.0.tgz",
2602
2602
-
"integrity": "sha512-BIodwZ19RWfCbYTxWTUfTXc+sg4OwjCAgxU1ZsgmggX/7S3LdUifsbUPJs61j0rWb19CZRGY5if77duhc0uXzw==",
2603
2603
-
"dev": true,
2604
2604
-
"hasInstallScript": true,
2605
2605
-
"license": "MIT",
2606
2606
-
"dependencies": {
2607
2607
-
"@bundled-es-modules/cookie": "^2.0.1",
2608
2608
-
"@bundled-es-modules/statuses": "^1.0.1",
2609
2609
-
"@bundled-es-modules/tough-cookie": "^0.1.6",
2610
2610
-
"@inquirer/confirm": "^5.0.0",
2611
2611
-
"@mswjs/interceptors": "^0.37.0",
2612
2612
-
"@open-draft/deferred-promise": "^2.2.0",
2613
2613
-
"@open-draft/until": "^2.1.0",
2614
2614
-
"@types/cookie": "^0.6.0",
2615
2615
-
"@types/statuses": "^2.0.4",
2616
2616
-
"graphql": "^16.8.1",
2617
2617
-
"headers-polyfill": "^4.0.2",
2618
2618
-
"is-node-process": "^1.2.0",
2619
2619
-
"outvariant": "^1.4.3",
2620
2620
-
"path-to-regexp": "^6.3.0",
2621
2621
-
"picocolors": "^1.1.1",
2622
2622
-
"strict-event-emitter": "^0.5.1",
2623
2623
-
"type-fest": "^4.26.1",
2624
2624
-
"yargs": "^17.7.2"
2625
2625
-
},
2626
2626
-
"bin": {
2627
2627
-
"msw": "cli/index.js"
2628
2628
-
},
2629
2629
-
"engines": {
2630
2630
-
"node": ">=18"
2631
2631
-
},
2632
2632
-
"funding": {
2633
2633
-
"url": "https://github.com/sponsors/mswjs"
2634
2634
-
},
2635
2635
-
"peerDependencies": {
2636
2636
-
"typescript": ">= 4.8.x"
2637
2637
-
},
2638
2638
-
"peerDependenciesMeta": {
2639
2639
-
"typescript": {
2640
2640
-
"optional": true
2641
2641
-
}
2642
2642
-
}
2643
2643
-
},
2644
2644
-
"node_modules/mute-stream": {
2645
2645
-
"version": "2.0.0",
2646
2646
-
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz",
2647
2647
-
"integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
2648
2648
-
"dev": true,
2649
2649
-
"license": "ISC",
2650
2650
-
"engines": {
2651
2651
-
"node": "^18.17.0 || >=20.5.0"
2652
2652
-
}
2653
2653
-
},
2654
2654
-
"node_modules/nanoid": {
2655
2655
-
"version": "3.3.8",
2656
2656
-
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
2657
2657
-
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
2658
2658
-
"dev": true,
2659
2659
-
"funding": [
2660
2660
-
{
2661
2661
-
"type": "github",
2662
2662
-
"url": "https://github.com/sponsors/ai"
2663
2663
-
}
2664
2664
-
],
2665
2665
-
"license": "MIT",
2666
2666
-
"bin": {
2667
2667
-
"nanoid": "bin/nanoid.cjs"
2668
2668
-
},
2669
2669
-
"engines": {
2670
2670
-
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
2671
2671
-
}
2672
2672
-
},
2673
2673
-
"node_modules/outvariant": {
2674
2674
-
"version": "1.4.3",
2675
2675
-
"resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz",
2676
2676
-
"integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==",
2677
2677
-
"dev": true,
2678
2678
-
"license": "MIT"
2679
2679
-
},
2680
2680
-
"node_modules/package-json-from-dist": {
2681
2681
-
"version": "1.0.1",
2682
2682
-
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
2683
2683
-
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
2684
2684
-
"dev": true,
2685
2685
-
"license": "BlueOak-1.0.0"
2686
2686
-
},
2687
2687
-
"node_modules/path-key": {
2688
2688
-
"version": "3.1.1",
2689
2689
-
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
2690
2690
-
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
2691
2691
-
"dev": true,
2692
2692
-
"license": "MIT",
2693
2693
-
"engines": {
2694
2694
-
"node": ">=8"
2695
2695
-
}
2696
2696
-
},
2697
2697
-
"node_modules/path-scurry": {
2698
2698
-
"version": "1.11.1",
2699
2699
-
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
2700
2700
-
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
2701
2701
-
"dev": true,
2702
2702
-
"license": "BlueOak-1.0.0",
2703
2703
-
"dependencies": {
2704
2704
-
"lru-cache": "^10.2.0",
2705
2705
-
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
2706
2706
-
},
2707
2707
-
"engines": {
2708
2708
-
"node": ">=16 || 14 >=14.18"
2709
2709
-
},
2710
2710
-
"funding": {
2711
2711
-
"url": "https://github.com/sponsors/isaacs"
2712
2712
-
}
2713
2713
-
},
2714
2714
-
"node_modules/path-to-regexp": {
2715
2715
-
"version": "6.3.0",
2716
2716
-
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
2717
2717
-
"integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
2718
2718
-
"dev": true,
2719
2719
-
"license": "MIT"
2720
2720
-
},
2721
2721
-
"node_modules/pathe": {
2722
2722
-
"version": "2.0.3",
2723
2723
-
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
2724
2724
-
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
2725
2725
-
"dev": true,
2726
2726
-
"license": "MIT"
2727
2727
-
},
2728
2728
-
"node_modules/pathval": {
2729
2729
-
"version": "2.0.0",
2730
2730
-
"resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
2731
2731
-
"integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
2732
2732
-
"dev": true,
2733
2733
-
"license": "MIT",
2734
2734
-
"engines": {
2735
2735
-
"node": ">= 14.16"
2736
2736
-
}
2737
2737
-
},
2738
2738
-
"node_modules/picocolors": {
2739
2739
-
"version": "1.1.1",
2740
2740
-
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
2741
2741
-
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
2742
2742
-
"dev": true,
2743
2743
-
"license": "ISC"
2744
2744
-
},
2745
899
"node_modules/picomatch": {
2746
900
"version": "4.0.2",
2747
901
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
···
2755
909
"url": "https://github.com/sponsors/jonschlinkert"
2756
910
}
2757
911
},
2758
2758
-
"node_modules/playwright": {
2759
2759
-
"version": "1.50.1",
2760
2760
-
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.1.tgz",
2761
2761
-
"integrity": "sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==",
2762
2762
-
"dev": true,
2763
2763
-
"license": "Apache-2.0",
2764
2764
-
"dependencies": {
2765
2765
-
"playwright-core": "1.50.1"
2766
2766
-
},
2767
2767
-
"bin": {
2768
2768
-
"playwright": "cli.js"
2769
2769
-
},
2770
2770
-
"engines": {
2771
2771
-
"node": ">=18"
2772
2772
-
},
2773
2773
-
"optionalDependencies": {
2774
2774
-
"fsevents": "2.3.2"
2775
2775
-
}
2776
2776
-
},
2777
2777
-
"node_modules/playwright-core": {
2778
2778
-
"version": "1.50.1",
2779
2779
-
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.1.tgz",
2780
2780
-
"integrity": "sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==",
2781
2781
-
"dev": true,
2782
2782
-
"license": "Apache-2.0",
2783
2783
-
"bin": {
2784
2784
-
"playwright-core": "cli.js"
2785
2785
-
},
2786
2786
-
"engines": {
2787
2787
-
"node": ">=18"
2788
2788
-
}
2789
2789
-
},
2790
2790
-
"node_modules/playwright/node_modules/fsevents": {
2791
2791
-
"version": "2.3.2",
2792
2792
-
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
2793
2793
-
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
2794
2794
-
"dev": true,
2795
2795
-
"hasInstallScript": true,
2796
2796
-
"license": "MIT",
2797
2797
-
"optional": true,
2798
2798
-
"os": [
2799
2799
-
"darwin"
2800
2800
-
],
2801
2801
-
"engines": {
2802
2802
-
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
2803
2803
-
}
2804
2804
-
},
2805
2805
-
"node_modules/postcss": {
2806
2806
-
"version": "8.5.3",
2807
2807
-
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
2808
2808
-
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
2809
2809
-
"dev": true,
2810
2810
-
"funding": [
2811
2811
-
{
2812
2812
-
"type": "opencollective",
2813
2813
-
"url": "https://opencollective.com/postcss/"
2814
2814
-
},
2815
2815
-
{
2816
2816
-
"type": "tidelift",
2817
2817
-
"url": "https://tidelift.com/funding/github/npm/postcss"
2818
2818
-
},
2819
2819
-
{
2820
2820
-
"type": "github",
2821
2821
-
"url": "https://github.com/sponsors/ai"
2822
2822
-
}
2823
2823
-
],
2824
2824
-
"license": "MIT",
2825
2825
-
"dependencies": {
2826
2826
-
"nanoid": "^3.3.8",
2827
2827
-
"picocolors": "^1.1.1",
2828
2828
-
"source-map-js": "^1.2.1"
2829
2829
-
},
2830
2830
-
"engines": {
2831
2831
-
"node": "^10 || ^12 || >=14"
2832
2832
-
}
2833
2833
-
},
2834
912
"node_modules/prettier": {
2835
913
"version": "3.4.2",
2836
914
"dev": true,
···
2845
923
"url": "https://github.com/prettier/prettier?sponsor=1"
2846
924
}
2847
925
},
2848
2848
-
"node_modules/pretty-format": {
2849
2849
-
"version": "27.5.1",
2850
2850
-
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
2851
2851
-
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
2852
2852
-
"dev": true,
2853
2853
-
"license": "MIT",
2854
2854
-
"dependencies": {
2855
2855
-
"ansi-regex": "^5.0.1",
2856
2856
-
"ansi-styles": "^5.0.0",
2857
2857
-
"react-is": "^17.0.1"
2858
2858
-
},
2859
2859
-
"engines": {
2860
2860
-
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
2861
2861
-
}
2862
2862
-
},
2863
2863
-
"node_modules/pretty-format/node_modules/ansi-styles": {
2864
2864
-
"version": "5.2.0",
2865
2865
-
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
2866
2866
-
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
2867
2867
-
"dev": true,
2868
2868
-
"license": "MIT",
2869
2869
-
"engines": {
2870
2870
-
"node": ">=10"
2871
2871
-
},
2872
2872
-
"funding": {
2873
2873
-
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
2874
2874
-
}
2875
2875
-
},
2876
2876
-
"node_modules/psl": {
2877
2877
-
"version": "1.15.0",
2878
2878
-
"resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
2879
2879
-
"integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
2880
2880
-
"dev": true,
2881
2881
-
"license": "MIT",
2882
2882
-
"dependencies": {
2883
2883
-
"punycode": "^2.3.1"
2884
2884
-
},
2885
2885
-
"funding": {
2886
2886
-
"url": "https://github.com/sponsors/lupomontero"
2887
2887
-
}
2888
2888
-
},
2889
2889
-
"node_modules/punycode": {
2890
2890
-
"version": "2.3.1",
2891
2891
-
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
2892
2892
-
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
2893
2893
-
"dev": true,
2894
2894
-
"license": "MIT",
2895
2895
-
"engines": {
2896
2896
-
"node": ">=6"
2897
2897
-
}
2898
2898
-
},
2899
2899
-
"node_modules/querystringify": {
2900
2900
-
"version": "2.2.0",
2901
2901
-
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
2902
2902
-
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
2903
2903
-
"dev": true,
2904
2904
-
"license": "MIT"
2905
2905
-
},
2906
926
"node_modules/randombytes": {
2907
927
"version": "2.1.0",
2908
928
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
···
2913
933
"safe-buffer": "^5.1.0"
2914
934
}
2915
935
},
2916
2916
-
"node_modules/react-is": {
2917
2917
-
"version": "17.0.2",
2918
2918
-
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
2919
2919
-
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
2920
2920
-
"dev": true,
2921
2921
-
"license": "MIT"
2922
2922
-
},
2923
2923
-
"node_modules/regenerator-runtime": {
2924
2924
-
"version": "0.14.1",
2925
2925
-
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
2926
2926
-
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
2927
2927
-
"dev": true,
2928
2928
-
"license": "MIT"
2929
2929
-
},
2930
2930
-
"node_modules/require-directory": {
2931
2931
-
"version": "2.1.1",
2932
2932
-
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
2933
2933
-
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
2934
2934
-
"dev": true,
2935
2935
-
"license": "MIT",
2936
2936
-
"engines": {
2937
2937
-
"node": ">=0.10.0"
2938
2938
-
}
2939
2939
-
},
2940
2940
-
"node_modules/requires-port": {
2941
2941
-
"version": "1.0.0",
2942
2942
-
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
2943
2943
-
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
2944
2944
-
"dev": true,
2945
2945
-
"license": "MIT"
2946
2946
-
},
2947
936
"node_modules/rolldown": {
2948
937
"version": "1.0.0-beta.6",
2949
938
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.6.tgz",
···
2987
976
"integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
2988
977
"dev": true,
2989
978
"license": "MIT",
979
979
+
"optional": true,
980
980
+
"peer": true,
2990
981
"dependencies": {
2991
982
"@types/estree": "1.0.6"
2992
983
},
···
3054
1045
],
3055
1046
"license": "MIT"
3056
1047
},
3057
3057
-
"node_modules/semver": {
3058
3058
-
"version": "7.7.1",
3059
3059
-
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
3060
3060
-
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
3061
3061
-
"dev": true,
3062
3062
-
"license": "ISC",
3063
3063
-
"bin": {
3064
3064
-
"semver": "bin/semver.js"
3065
3065
-
},
3066
3066
-
"engines": {
3067
3067
-
"node": ">=10"
3068
3068
-
}
3069
3069
-
},
3070
1048
"node_modules/serialize-javascript": {
3071
1049
"version": "6.0.2",
3072
1050
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
···
3077
1055
"randombytes": "^2.1.0"
3078
1056
}
3079
1057
},
3080
3080
-
"node_modules/shebang-command": {
3081
3081
-
"version": "2.0.0",
3082
3082
-
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
3083
3083
-
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
3084
3084
-
"dev": true,
3085
3085
-
"license": "MIT",
3086
3086
-
"dependencies": {
3087
3087
-
"shebang-regex": "^3.0.0"
3088
3088
-
},
3089
3089
-
"engines": {
3090
3090
-
"node": ">=8"
3091
3091
-
}
3092
3092
-
},
3093
3093
-
"node_modules/shebang-regex": {
3094
3094
-
"version": "3.0.0",
3095
3095
-
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
3096
3096
-
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
3097
3097
-
"dev": true,
3098
3098
-
"license": "MIT",
3099
3099
-
"engines": {
3100
3100
-
"node": ">=8"
3101
3101
-
}
3102
3102
-
},
3103
3103
-
"node_modules/siginfo": {
3104
3104
-
"version": "2.0.0",
3105
3105
-
"resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
3106
3106
-
"integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
3107
3107
-
"dev": true,
3108
3108
-
"license": "ISC"
3109
3109
-
},
3110
3110
-
"node_modules/signal-exit": {
3111
3111
-
"version": "4.1.0",
3112
3112
-
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
3113
3113
-
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
3114
3114
-
"dev": true,
3115
3115
-
"license": "ISC",
3116
3116
-
"engines": {
3117
3117
-
"node": ">=14"
3118
3118
-
},
3119
3119
-
"funding": {
3120
3120
-
"url": "https://github.com/sponsors/isaacs"
3121
3121
-
}
3122
3122
-
},
3123
3123
-
"node_modules/sirv": {
3124
3124
-
"version": "3.0.1",
3125
3125
-
"resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz",
3126
3126
-
"integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==",
3127
3127
-
"dev": true,
3128
3128
-
"license": "MIT",
3129
3129
-
"dependencies": {
3130
3130
-
"@polka/url": "^1.0.0-next.24",
3131
3131
-
"mrmime": "^2.0.0",
3132
3132
-
"totalist": "^3.0.0"
3133
3133
-
},
3134
3134
-
"engines": {
3135
3135
-
"node": ">=18"
3136
3136
-
}
3137
3137
-
},
3138
1058
"node_modules/smob": {
3139
1059
"version": "1.5.0",
3140
1060
"resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
···
3150
1070
"node": ">=0.10.0"
3151
1071
}
3152
1072
},
3153
3153
-
"node_modules/source-map-js": {
3154
3154
-
"version": "1.2.1",
3155
3155
-
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
3156
3156
-
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
3157
3157
-
"dev": true,
3158
3158
-
"license": "BSD-3-Clause",
3159
3159
-
"engines": {
3160
3160
-
"node": ">=0.10.0"
3161
3161
-
}
3162
3162
-
},
3163
1073
"node_modules/source-map-support": {
3164
1074
"version": "0.5.21",
3165
1075
"dev": true,
···
3169
1079
"source-map": "^0.6.0"
3170
1080
}
3171
1081
},
3172
3172
-
"node_modules/stackback": {
3173
3173
-
"version": "0.0.2",
3174
3174
-
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
3175
3175
-
"integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
3176
3176
-
"dev": true,
3177
3177
-
"license": "MIT"
3178
3178
-
},
3179
3179
-
"node_modules/statuses": {
3180
3180
-
"version": "2.0.1",
3181
3181
-
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
3182
3182
-
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
3183
3183
-
"dev": true,
3184
3184
-
"license": "MIT",
3185
3185
-
"engines": {
3186
3186
-
"node": ">= 0.8"
3187
3187
-
}
3188
3188
-
},
3189
3189
-
"node_modules/std-env": {
3190
3190
-
"version": "3.8.0",
3191
3191
-
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz",
3192
3192
-
"integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==",
3193
3193
-
"dev": true,
3194
3194
-
"license": "MIT"
3195
3195
-
},
3196
3196
-
"node_modules/strict-event-emitter": {
3197
3197
-
"version": "0.5.1",
3198
3198
-
"resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
3199
3199
-
"integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==",
3200
3200
-
"dev": true,
3201
3201
-
"license": "MIT"
3202
3202
-
},
3203
3203
-
"node_modules/string-width": {
3204
3204
-
"version": "4.2.3",
3205
3205
-
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
3206
3206
-
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
3207
3207
-
"dev": true,
3208
3208
-
"license": "MIT",
3209
3209
-
"dependencies": {
3210
3210
-
"emoji-regex": "^8.0.0",
3211
3211
-
"is-fullwidth-code-point": "^3.0.0",
3212
3212
-
"strip-ansi": "^6.0.1"
3213
3213
-
},
3214
3214
-
"engines": {
3215
3215
-
"node": ">=8"
3216
3216
-
}
3217
3217
-
},
3218
3218
-
"node_modules/string-width-cjs": {
3219
3219
-
"name": "string-width",
3220
3220
-
"version": "4.2.3",
3221
3221
-
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
3222
3222
-
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
3223
3223
-
"dev": true,
3224
3224
-
"license": "MIT",
3225
3225
-
"dependencies": {
3226
3226
-
"emoji-regex": "^8.0.0",
3227
3227
-
"is-fullwidth-code-point": "^3.0.0",
3228
3228
-
"strip-ansi": "^6.0.1"
3229
3229
-
},
3230
3230
-
"engines": {
3231
3231
-
"node": ">=8"
3232
3232
-
}
3233
3233
-
},
3234
3234
-
"node_modules/strip-ansi": {
3235
3235
-
"version": "6.0.1",
3236
3236
-
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
3237
3237
-
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
3238
3238
-
"dev": true,
3239
3239
-
"license": "MIT",
3240
3240
-
"dependencies": {
3241
3241
-
"ansi-regex": "^5.0.1"
3242
3242
-
},
3243
3243
-
"engines": {
3244
3244
-
"node": ">=8"
3245
3245
-
}
3246
3246
-
},
3247
3247
-
"node_modules/strip-ansi-cjs": {
3248
3248
-
"name": "strip-ansi",
3249
3249
-
"version": "6.0.1",
3250
3250
-
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
3251
3251
-
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
3252
3252
-
"dev": true,
3253
3253
-
"license": "MIT",
3254
3254
-
"dependencies": {
3255
3255
-
"ansi-regex": "^5.0.1"
3256
3256
-
},
3257
3257
-
"engines": {
3258
3258
-
"node": ">=8"
3259
3259
-
}
3260
3260
-
},
3261
3261
-
"node_modules/supports-color": {
3262
3262
-
"version": "7.2.0",
3263
3263
-
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
3264
3264
-
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
3265
3265
-
"dev": true,
3266
3266
-
"license": "MIT",
3267
3267
-
"dependencies": {
3268
3268
-
"has-flag": "^4.0.0"
3269
3269
-
},
3270
3270
-
"engines": {
3271
3271
-
"node": ">=8"
3272
3272
-
}
3273
3273
-
},
3274
1082
"node_modules/terser": {
3275
1083
"version": "5.37.0",
3276
1084
"dev": true,
···
3288
1096
"node": ">=10"
3289
1097
}
3290
1098
},
3291
3291
-
"node_modules/test-exclude": {
3292
3292
-
"version": "7.0.1",
3293
3293
-
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
3294
3294
-
"integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==",
3295
3295
-
"dev": true,
3296
3296
-
"license": "ISC",
3297
3297
-
"dependencies": {
3298
3298
-
"@istanbuljs/schema": "^0.1.2",
3299
3299
-
"glob": "^10.4.1",
3300
3300
-
"minimatch": "^9.0.4"
3301
3301
-
},
3302
3302
-
"engines": {
3303
3303
-
"node": ">=18"
3304
3304
-
}
3305
3305
-
},
3306
3306
-
"node_modules/tinybench": {
3307
3307
-
"version": "2.9.0",
3308
3308
-
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
3309
3309
-
"integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
3310
3310
-
"dev": true,
3311
3311
-
"license": "MIT"
3312
3312
-
},
3313
3313
-
"node_modules/tinyexec": {
3314
3314
-
"version": "0.3.2",
3315
3315
-
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
3316
3316
-
"integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
3317
3317
-
"dev": true,
3318
3318
-
"license": "MIT"
3319
3319
-
},
3320
1099
"node_modules/tinyglobby": {
3321
1100
"version": "0.2.12",
3322
1101
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz",
···
3334
1113
"url": "https://github.com/sponsors/SuperchupuDev"
3335
1114
}
3336
1115
},
3337
3337
-
"node_modules/tinypool": {
3338
3338
-
"version": "1.0.2",
3339
3339
-
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz",
3340
3340
-
"integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==",
3341
3341
-
"dev": true,
3342
3342
-
"license": "MIT",
3343
3343
-
"engines": {
3344
3344
-
"node": "^18.0.0 || >=20.0.0"
3345
3345
-
}
3346
3346
-
},
3347
3347
-
"node_modules/tinyrainbow": {
3348
3348
-
"version": "2.0.0",
3349
3349
-
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
3350
3350
-
"integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
3351
3351
-
"dev": true,
3352
3352
-
"license": "MIT",
3353
3353
-
"engines": {
3354
3354
-
"node": ">=14.0.0"
3355
3355
-
}
3356
3356
-
},
3357
3357
-
"node_modules/tinyspy": {
3358
3358
-
"version": "3.0.2",
3359
3359
-
"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
3360
3360
-
"integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
3361
3361
-
"dev": true,
3362
3362
-
"license": "MIT",
3363
3363
-
"engines": {
3364
3364
-
"node": ">=14.0.0"
3365
3365
-
}
3366
3366
-
},
3367
3367
-
"node_modules/totalist": {
3368
3368
-
"version": "3.0.1",
3369
3369
-
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
3370
3370
-
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
3371
3371
-
"dev": true,
3372
3372
-
"license": "MIT",
3373
3373
-
"engines": {
3374
3374
-
"node": ">=6"
3375
3375
-
}
3376
3376
-
},
3377
3377
-
"node_modules/tough-cookie": {
3378
3378
-
"version": "4.1.4",
3379
3379
-
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
3380
3380
-
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
3381
3381
-
"dev": true,
3382
3382
-
"license": "BSD-3-Clause",
3383
3383
-
"dependencies": {
3384
3384
-
"psl": "^1.1.33",
3385
3385
-
"punycode": "^2.1.1",
3386
3386
-
"universalify": "^0.2.0",
3387
3387
-
"url-parse": "^1.5.3"
3388
3388
-
},
3389
3389
-
"engines": {
3390
3390
-
"node": ">=6"
3391
3391
-
}
3392
3392
-
},
3393
1116
"node_modules/ts-api-utils": {
3394
1117
"version": "1.4.3",
3395
1118
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
···
3411
1134
"license": "0BSD",
3412
1135
"optional": true
3413
1136
},
3414
3414
-
"node_modules/type-fest": {
3415
3415
-
"version": "4.33.0",
3416
3416
-
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.33.0.tgz",
3417
3417
-
"integrity": "sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g==",
3418
3418
-
"dev": true,
3419
3419
-
"license": "(MIT OR CC0-1.0)",
3420
3420
-
"engines": {
3421
3421
-
"node": ">=16"
3422
3422
-
},
3423
3423
-
"funding": {
3424
3424
-
"url": "https://github.com/sponsors/sindresorhus"
3425
3425
-
}
3426
3426
-
},
3427
1137
"node_modules/typescript": {
3428
1138
"version": "5.7.2",
3429
1139
"dev": true,
···
3436
1146
"node": ">=14.17"
3437
1147
}
3438
1148
},
3439
3439
-
"node_modules/universalify": {
3440
3440
-
"version": "0.2.0",
3441
3441
-
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
3442
3442
-
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
1149
1149
+
"node_modules/undici-types": {
1150
1150
+
"version": "6.20.0",
1151
1151
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
1152
1152
+
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
3443
1153
"dev": true,
3444
3444
-
"license": "MIT",
3445
3445
-
"engines": {
3446
3446
-
"node": ">= 4.0.0"
3447
3447
-
}
3448
3448
-
},
3449
3449
-
"node_modules/url-parse": {
3450
3450
-
"version": "1.5.10",
3451
3451
-
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
3452
3452
-
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
3453
3453
-
"dev": true,
3454
3454
-
"license": "MIT",
3455
3455
-
"dependencies": {
3456
3456
-
"querystringify": "^2.1.1",
3457
3457
-
"requires-port": "^1.0.0"
3458
3458
-
}
1154
1154
+
"license": "MIT"
3459
1155
},
3460
1156
"node_modules/valibot": {
3461
1157
"version": "1.0.0-rc.4",
···
3472
1168
}
3473
1169
}
3474
1170
},
3475
3475
-
"node_modules/vite": {
3476
3476
-
"version": "6.1.1",
3477
3477
-
"resolved": "https://registry.npmjs.org/vite/-/vite-6.1.1.tgz",
3478
3478
-
"integrity": "sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==",
3479
3479
-
"dev": true,
3480
3480
-
"license": "MIT",
3481
3481
-
"dependencies": {
3482
3482
-
"esbuild": "^0.24.2",
3483
3483
-
"postcss": "^8.5.2",
3484
3484
-
"rollup": "^4.30.1"
3485
3485
-
},
3486
3486
-
"bin": {
3487
3487
-
"vite": "bin/vite.js"
3488
3488
-
},
3489
3489
-
"engines": {
3490
3490
-
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
3491
3491
-
},
3492
3492
-
"funding": {
3493
3493
-
"url": "https://github.com/vitejs/vite?sponsor=1"
3494
3494
-
},
3495
3495
-
"optionalDependencies": {
3496
3496
-
"fsevents": "~2.3.3"
3497
3497
-
},
3498
3498
-
"peerDependencies": {
3499
3499
-
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
3500
3500
-
"jiti": ">=1.21.0",
3501
3501
-
"less": "*",
3502
3502
-
"lightningcss": "^1.21.0",
3503
3503
-
"sass": "*",
3504
3504
-
"sass-embedded": "*",
3505
3505
-
"stylus": "*",
3506
3506
-
"sugarss": "*",
3507
3507
-
"terser": "^5.16.0",
3508
3508
-
"tsx": "^4.8.1",
3509
3509
-
"yaml": "^2.4.2"
3510
3510
-
},
3511
3511
-
"peerDependenciesMeta": {
3512
3512
-
"@types/node": {
3513
3513
-
"optional": true
3514
3514
-
},
3515
3515
-
"jiti": {
3516
3516
-
"optional": true
3517
3517
-
},
3518
3518
-
"less": {
3519
3519
-
"optional": true
3520
3520
-
},
3521
3521
-
"lightningcss": {
3522
3522
-
"optional": true
3523
3523
-
},
3524
3524
-
"sass": {
3525
3525
-
"optional": true
3526
3526
-
},
3527
3527
-
"sass-embedded": {
3528
3528
-
"optional": true
3529
3529
-
},
3530
3530
-
"stylus": {
3531
3531
-
"optional": true
3532
3532
-
},
3533
3533
-
"sugarss": {
3534
3534
-
"optional": true
3535
3535
-
},
3536
3536
-
"terser": {
3537
3537
-
"optional": true
3538
3538
-
},
3539
3539
-
"tsx": {
3540
3540
-
"optional": true
3541
3541
-
},
3542
3542
-
"yaml": {
3543
3543
-
"optional": true
3544
3544
-
}
3545
3545
-
}
3546
3546
-
},
3547
3547
-
"node_modules/vite-node": {
3548
3548
-
"version": "3.0.6",
3549
3549
-
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.6.tgz",
3550
3550
-
"integrity": "sha512-s51RzrTkXKJrhNbUzQRsarjmAae7VmMPAsRT7lppVpIg6mK3zGthP9Hgz0YQQKuNcF+Ii7DfYk3Fxz40jRmePw==",
3551
3551
-
"dev": true,
3552
3552
-
"license": "MIT",
3553
3553
-
"dependencies": {
3554
3554
-
"cac": "^6.7.14",
3555
3555
-
"debug": "^4.4.0",
3556
3556
-
"es-module-lexer": "^1.6.0",
3557
3557
-
"pathe": "^2.0.3",
3558
3558
-
"vite": "^5.0.0 || ^6.0.0"
3559
3559
-
},
3560
3560
-
"bin": {
3561
3561
-
"vite-node": "vite-node.mjs"
3562
3562
-
},
3563
3563
-
"engines": {
3564
3564
-
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
3565
3565
-
},
3566
3566
-
"funding": {
3567
3567
-
"url": "https://opencollective.com/vitest"
3568
3568
-
}
3569
3569
-
},
3570
3570
-
"node_modules/vitest": {
3571
3571
-
"version": "3.0.6",
3572
3572
-
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.6.tgz",
3573
3573
-
"integrity": "sha512-/iL1Sc5VeDZKPDe58oGK4HUFLhw6b5XdY1MYawjuSaDA4sEfYlY9HnS6aCEG26fX+MgUi7MwlduTBHHAI/OvMA==",
3574
3574
-
"dev": true,
3575
3575
-
"license": "MIT",
3576
3576
-
"dependencies": {
3577
3577
-
"@vitest/expect": "3.0.6",
3578
3578
-
"@vitest/mocker": "3.0.6",
3579
3579
-
"@vitest/pretty-format": "^3.0.6",
3580
3580
-
"@vitest/runner": "3.0.6",
3581
3581
-
"@vitest/snapshot": "3.0.6",
3582
3582
-
"@vitest/spy": "3.0.6",
3583
3583
-
"@vitest/utils": "3.0.6",
3584
3584
-
"chai": "^5.2.0",
3585
3585
-
"debug": "^4.4.0",
3586
3586
-
"expect-type": "^1.1.0",
3587
3587
-
"magic-string": "^0.30.17",
3588
3588
-
"pathe": "^2.0.3",
3589
3589
-
"std-env": "^3.8.0",
3590
3590
-
"tinybench": "^2.9.0",
3591
3591
-
"tinyexec": "^0.3.2",
3592
3592
-
"tinypool": "^1.0.2",
3593
3593
-
"tinyrainbow": "^2.0.0",
3594
3594
-
"vite": "^5.0.0 || ^6.0.0",
3595
3595
-
"vite-node": "3.0.6",
3596
3596
-
"why-is-node-running": "^2.3.0"
3597
3597
-
},
3598
3598
-
"bin": {
3599
3599
-
"vitest": "vitest.mjs"
3600
3600
-
},
3601
3601
-
"engines": {
3602
3602
-
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
3603
3603
-
},
3604
3604
-
"funding": {
3605
3605
-
"url": "https://opencollective.com/vitest"
3606
3606
-
},
3607
3607
-
"peerDependencies": {
3608
3608
-
"@edge-runtime/vm": "*",
3609
3609
-
"@types/debug": "^4.1.12",
3610
3610
-
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
3611
3611
-
"@vitest/browser": "3.0.6",
3612
3612
-
"@vitest/ui": "3.0.6",
3613
3613
-
"happy-dom": "*",
3614
3614
-
"jsdom": "*"
3615
3615
-
},
3616
3616
-
"peerDependenciesMeta": {
3617
3617
-
"@edge-runtime/vm": {
3618
3618
-
"optional": true
3619
3619
-
},
3620
3620
-
"@types/debug": {
3621
3621
-
"optional": true
3622
3622
-
},
3623
3623
-
"@types/node": {
3624
3624
-
"optional": true
3625
3625
-
},
3626
3626
-
"@vitest/browser": {
3627
3627
-
"optional": true
3628
3628
-
},
3629
3629
-
"@vitest/ui": {
3630
3630
-
"optional": true
3631
3631
-
},
3632
3632
-
"happy-dom": {
3633
3633
-
"optional": true
3634
3634
-
},
3635
3635
-
"jsdom": {
3636
3636
-
"optional": true
3637
3637
-
}
3638
3638
-
}
3639
3639
-
},
3640
1171
"node_modules/webidl-conversions": {
3641
1172
"version": "7.0.0",
3642
1173
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
3643
1174
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
3644
1175
"dev": true,
3645
1176
"license": "BSD-2-Clause",
3646
3646
-
"optional": true,
3647
3647
-
"peer": true,
3648
1177
"engines": {
3649
1178
"node": ">=12"
3650
1179
}
···
3655
1184
"integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
3656
1185
"dev": true,
3657
1186
"license": "MIT",
3658
3658
-
"optional": true,
3659
3659
-
"peer": true,
3660
1187
"engines": {
3661
1188
"node": ">=12"
3662
3662
-
}
3663
3663
-
},
3664
3664
-
"node_modules/which": {
3665
3665
-
"version": "2.0.2",
3666
3666
-
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
3667
3667
-
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
3668
3668
-
"dev": true,
3669
3669
-
"license": "ISC",
3670
3670
-
"dependencies": {
3671
3671
-
"isexe": "^2.0.0"
3672
3672
-
},
3673
3673
-
"bin": {
3674
3674
-
"node-which": "bin/node-which"
3675
3675
-
},
3676
3676
-
"engines": {
3677
3677
-
"node": ">= 8"
3678
3678
-
}
3679
3679
-
},
3680
3680
-
"node_modules/why-is-node-running": {
3681
3681
-
"version": "2.3.0",
3682
3682
-
"resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
3683
3683
-
"integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
3684
3684
-
"dev": true,
3685
3685
-
"license": "MIT",
3686
3686
-
"dependencies": {
3687
3687
-
"siginfo": "^2.0.0",
3688
3688
-
"stackback": "0.0.2"
3689
3689
-
},
3690
3690
-
"bin": {
3691
3691
-
"why-is-node-running": "cli.js"
3692
3692
-
},
3693
3693
-
"engines": {
3694
3694
-
"node": ">=8"
3695
3695
-
}
3696
3696
-
},
3697
3697
-
"node_modules/wrap-ansi": {
3698
3698
-
"version": "6.2.0",
3699
3699
-
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
3700
3700
-
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
3701
3701
-
"dev": true,
3702
3702
-
"license": "MIT",
3703
3703
-
"dependencies": {
3704
3704
-
"ansi-styles": "^4.0.0",
3705
3705
-
"string-width": "^4.1.0",
3706
3706
-
"strip-ansi": "^6.0.0"
3707
3707
-
},
3708
3708
-
"engines": {
3709
3709
-
"node": ">=8"
3710
3710
-
}
3711
3711
-
},
3712
3712
-
"node_modules/wrap-ansi-cjs": {
3713
3713
-
"name": "wrap-ansi",
3714
3714
-
"version": "7.0.0",
3715
3715
-
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
3716
3716
-
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
3717
3717
-
"dev": true,
3718
3718
-
"license": "MIT",
3719
3719
-
"dependencies": {
3720
3720
-
"ansi-styles": "^4.0.0",
3721
3721
-
"string-width": "^4.1.0",
3722
3722
-
"strip-ansi": "^6.0.0"
3723
3723
-
},
3724
3724
-
"engines": {
3725
3725
-
"node": ">=10"
3726
3726
-
},
3727
3727
-
"funding": {
3728
3728
-
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
3729
3729
-
}
3730
3730
-
},
3731
3731
-
"node_modules/ws": {
3732
3732
-
"version": "8.18.0",
3733
3733
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
3734
3734
-
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
3735
3735
-
"dev": true,
3736
3736
-
"license": "MIT",
3737
3737
-
"engines": {
3738
3738
-
"node": ">=10.0.0"
3739
3739
-
},
3740
3740
-
"peerDependencies": {
3741
3741
-
"bufferutil": "^4.0.1",
3742
3742
-
"utf-8-validate": ">=5.0.2"
3743
3743
-
},
3744
3744
-
"peerDependenciesMeta": {
3745
3745
-
"bufferutil": {
3746
3746
-
"optional": true
3747
3747
-
},
3748
3748
-
"utf-8-validate": {
3749
3749
-
"optional": true
3750
3750
-
}
3751
3751
-
}
3752
3752
-
},
3753
3753
-
"node_modules/y18n": {
3754
3754
-
"version": "5.0.8",
3755
3755
-
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
3756
3756
-
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
3757
3757
-
"dev": true,
3758
3758
-
"license": "ISC",
3759
3759
-
"engines": {
3760
3760
-
"node": ">=10"
3761
3761
-
}
3762
3762
-
},
3763
3763
-
"node_modules/yargs": {
3764
3764
-
"version": "17.7.2",
3765
3765
-
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
3766
3766
-
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
3767
3767
-
"dev": true,
3768
3768
-
"license": "MIT",
3769
3769
-
"dependencies": {
3770
3770
-
"cliui": "^8.0.1",
3771
3771
-
"escalade": "^3.1.1",
3772
3772
-
"get-caller-file": "^2.0.5",
3773
3773
-
"require-directory": "^2.1.1",
3774
3774
-
"string-width": "^4.2.3",
3775
3775
-
"y18n": "^5.0.5",
3776
3776
-
"yargs-parser": "^21.1.1"
3777
3777
-
},
3778
3778
-
"engines": {
3779
3779
-
"node": ">=12"
3780
3780
-
}
3781
3781
-
},
3782
3782
-
"node_modules/yargs-parser": {
3783
3783
-
"version": "21.1.1",
3784
3784
-
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
3785
3785
-
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
3786
3786
-
"dev": true,
3787
3787
-
"license": "ISC",
3788
3788
-
"engines": {
3789
3789
-
"node": ">=12"
3790
3790
-
}
3791
3791
-
},
3792
3792
-
"node_modules/yoctocolors-cjs": {
3793
3793
-
"version": "2.1.2",
3794
3794
-
"resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz",
3795
3795
-
"integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==",
3796
3796
-
"dev": true,
3797
3797
-
"license": "MIT",
3798
3798
-
"engines": {
3799
3799
-
"node": ">=18"
3800
3800
-
},
3801
3801
-
"funding": {
3802
3802
-
"url": "https://github.com/sponsors/sindresorhus"
3803
1189
}
3804
1190
},
3805
1191
"node_modules/zimmerframe": {
+6
-8
package.json
reviewed
···
10
10
"build": "node build.js",
11
11
"format": "prettier --write . --cache",
12
12
"check": "tsc",
13
13
-
"test": "vitest run",
14
14
-
"test:watch": "vitest dev",
15
15
-
"test:prod": "npm run build && NODE_ENV=production vitest run"
13
13
+
"test": "node --no-warnings --test --experimental-test-coverage src/*/tests/*",
14
14
+
"test:coverage": "node --no-warnings --test --experimental-test-coverage --test-reporter=spec --test-reporter-destination=stderr --test-reporter=lcov --test-reporter-destination=lcov.info src/*/tests/*",
15
15
+
"test:watch": "node --no-warnings --test --watch src/*/tests/*",
16
16
+
"test:prod": "npm run build && NODE_ENV=production npm test"
16
17
},
17
18
"devDependencies": {
19
19
+
"@happy-dom/global-registrator": "^17.4.4",
18
20
"@rollup/plugin-terser": "^0.4.4",
19
19
-
"@vitest/browser": "^3.0.6",
20
20
-
"@vitest/coverage-v8": "^3.0.6",
21
21
-
"@vitest/ui": "^3.0.5",
21
21
+
"@types/node": "^22.13.11",
22
22
"dhtml": ".",
23
23
"dts-buddy": "^0.5.5",
24
24
"htmlparser2": "^10.0.0",
25
25
"magic-string": "^0.30.17",
26
26
-
"playwright": "^1.50.1",
27
26
"prettier": "^3.4.2",
28
27
"rolldown": "^1.0.0-beta.6",
29
28
"typescript": "^5.7.2",
30
30
-
"vitest": "^3.0.6",
31
29
"zimmerframe": "^1.1.2"
32
30
},
33
31
"prettier": {
+16
-7
src/client/compiler.ts
reviewed
···
122
122
})
123
123
} else {
124
124
if (!(name in node)) {
125
125
-
for (const property in node) {
126
126
-
if (property.toLowerCase() === name) {
127
127
-
name = property
128
128
-
break
129
129
-
}
130
130
-
}
125
125
+
name = (correct_case_cache[node.tagName] ??= generate_case_map(node))[name]
131
126
}
132
127
patch(node, parseInt(match[1]), node => {
133
128
assert(node instanceof Node)
134
129
return createPropertyPart(node, name)
135
130
})
136
131
}
137
137
-
} else if (__DEV__) {
132
132
+
} else {
138
133
assert(!DYNAMIC_GLOBAL.test(value), `expected a whole dynamic value for ${name}, got a partial one`)
139
134
}
140
135
}
···
148
143
templates.set(statics, compiled)
149
144
return compiled
150
145
}
146
146
+
147
147
+
const correct_case_cache: Record<string, Record<string, string>> = {}
148
148
+
function generate_case_map(node: Node) {
149
149
+
const cache: Record<string, string> = {}
150
150
+
151
151
+
while (node !== null) {
152
152
+
for (const prop of Object.getOwnPropertyNames(node)) {
153
153
+
cache[prop.toLowerCase()] ??= prop
154
154
+
}
155
155
+
node = Object.getPrototypeOf(node)
156
156
+
}
157
157
+
158
158
+
return cache
159
159
+
}
+78
-79
src/client/tests/attributes.test.ts
reviewed
···
1
1
import { html } from 'dhtml'
2
2
-
import { describe, expect, it, vi } from 'vitest'
3
3
-
import { setup } from './setup'
2
2
+
import test, { type TestContext } from 'node:test'
3
3
+
import { setup } from './setup.ts'
4
4
5
5
-
describe('attributes', () => {
6
6
-
it('supports regular attributes', () => {
7
7
-
const { root, el } = setup()
5
5
+
test('regular attributes', (t: TestContext) => {
6
6
+
const { root, el } = setup()
8
7
9
9
-
root.render(html`<h1 style=${'color: red'}>Hello, world!</h1>`)
10
10
-
expect(el.querySelector('h1')).toHaveAttribute('style', 'color: red;')
11
11
-
})
8
8
+
root.render(html`<h1 style=${'color: red'}>Hello, world!</h1>`)
9
9
+
t.assert.strictEqual(el.querySelector('h1')!.getAttribute('style'), 'color: red;')
10
10
+
})
12
11
13
13
-
it('can toggle attributes', () => {
14
14
-
const { root, el } = setup()
12
12
+
test('can toggle attributes', (t: TestContext) => {
13
13
+
const { root, el } = setup()
15
14
16
16
-
let hidden: unknown = false
17
17
-
const template = () => html`<h1 hidden=${hidden}>Hello, world!</h1>`
15
15
+
let hidden: unknown = false
16
16
+
const template = () => html`<h1 hidden=${hidden}>Hello, world!</h1>`
18
17
19
19
-
root.render(template())
20
20
-
expect(el.querySelector('h1')).not.toHaveAttribute('hidden')
18
18
+
root.render(template())
19
19
+
t.assert.ok(!el.querySelector('h1')!.hasAttribute('hidden'))
21
20
22
22
-
hidden = true
23
23
-
root.render(template())
24
24
-
expect(el.querySelector('h1')).toHaveAttribute('hidden')
21
21
+
hidden = true
22
22
+
root.render(template())
23
23
+
t.assert.ok(el.querySelector('h1')!.hasAttribute('hidden'))
25
24
26
26
-
hidden = null
27
27
-
root.render(template())
28
28
-
expect(el.querySelector('h1')).not.toHaveAttribute('hidden')
29
29
-
})
25
25
+
hidden = null
26
26
+
root.render(template())
27
27
+
t.assert.ok(!el.querySelector('h1')!.hasAttribute('hidden'))
28
28
+
})
30
29
31
31
-
it('supports property attributes', () => {
32
32
-
const { root, el } = setup()
30
30
+
test('supports property attributes', (t: TestContext) => {
31
31
+
const { root, el } = setup()
33
32
34
34
-
root.render(html`<details open=${true}></details>`)
35
35
-
expect(el.querySelector('details')!.open).toBe(true)
33
33
+
root.render(html`<details open=${true}></details>`)
34
34
+
t.assert.ok(el.querySelector('details')!.open)
36
35
37
37
-
root.render(html`<details open=${false}></details>`)
38
38
-
expect(el.querySelector('details')!.open).toBe(false)
39
39
-
})
36
36
+
root.render(html`<details open=${false}></details>`)
37
37
+
t.assert.ok(!el.querySelector('details')!.open)
38
38
+
})
40
39
41
41
-
it('guesses the case of properties', () => {
42
42
-
const { root, el } = setup()
40
40
+
test('infers the case of properties', (t: TestContext) => {
41
41
+
const { root, el } = setup()
43
42
44
44
-
const innerHTML = '<h1>Hello, world!</h1>'
43
43
+
const innerHTML = '<h1>Hello, world!</h1>'
45
44
46
46
-
root.render(html`<div innerhtml=${innerHTML}></div>`)
47
47
-
expect(el.querySelector('div')!.innerHTML).toBe(innerHTML)
45
45
+
root.render(html`<div innerhtml=${innerHTML}></div>`)
46
46
+
t.assert.strictEqual(el.querySelector('div')!.innerHTML, innerHTML)
48
47
49
49
-
root.render(html`<span innerHTML=${innerHTML}></span>`)
50
50
-
expect(el.querySelector('span')!.innerHTML).toBe(innerHTML)
51
51
-
})
48
48
+
root.render(html`<span innerHTML=${innerHTML}></span>`)
49
49
+
t.assert.strictEqual(el.querySelector('span')!.innerHTML, innerHTML)
50
50
+
})
52
51
53
53
-
it('treats class/for specially', () => {
54
54
-
const { root, el } = setup()
52
52
+
test('treats class/for specially', (t: TestContext) => {
53
53
+
const { root, el } = setup()
55
54
56
56
-
root.render(html`<h1 class=${'foo'}>Hello, world!</h1>`)
57
57
-
expect(el.querySelector('h1')).toHaveClass('foo')
55
55
+
root.render(html`<h1 class=${'foo'}>Hello, world!</h1>`)
56
56
+
t.assert.strictEqual(el.querySelector('h1')!.className, 'foo')
58
57
59
59
-
root.render(html`<label for=${'foo'}>Hello, world!</label>`)
60
60
-
expect(el.querySelector('label')).toHaveAttribute('for', 'foo')
61
61
-
})
58
58
+
root.render(html`<label for=${'foo'}>Hello, world!</label>`)
59
59
+
t.assert.strictEqual(el.querySelector('label')!.htmlFor, 'foo')
60
60
+
})
62
61
63
63
-
it('handles data attributes', () => {
64
64
-
const { root, el } = setup()
62
62
+
test('handles data attributes', (t: TestContext) => {
63
63
+
const { root, el } = setup()
65
64
66
66
-
root.render(html`<h1 data-foo=${'bar'}>Hello, world!</h1>`)
67
67
-
expect(el.querySelector('h1')).toHaveAttribute('data-foo', 'bar')
68
68
-
})
65
65
+
root.render(html`<h1 data-foo=${'bar'}>Hello, world!</h1>`)
66
66
+
t.assert.strictEqual(el.querySelector('h1')!.dataset.foo, 'bar')
67
67
+
})
69
68
70
70
-
it('supports events', () => {
71
71
-
const { root, el } = setup()
69
69
+
test('supports events', (t: TestContext) => {
70
70
+
const { root, el } = setup()
72
71
73
73
-
let clicks = 0
74
74
-
root.render(html`
75
75
-
<button
76
76
-
onclick=${() => {
77
77
-
clicks++
78
78
-
}}
79
79
-
>
80
80
-
Click me
81
81
-
</button>
82
82
-
`)
72
72
+
let clicks = 0
73
73
+
root.render(html`
74
74
+
<button
75
75
+
onclick=${() => {
76
76
+
clicks++
77
77
+
}}
78
78
+
>
79
79
+
Click me
80
80
+
</button>
81
81
+
`)
83
82
84
84
-
expect(clicks).toBe(0)
85
85
-
el.querySelector('button')!.click()
86
86
-
expect(clicks).toBe(1)
87
87
-
el.querySelector('button')!.click()
88
88
-
expect(clicks).toBe(2)
89
89
-
})
83
83
+
t.assert.strictEqual(clicks, 0)
84
84
+
el.querySelector('button')!.click()
85
85
+
t.assert.strictEqual(clicks, 1)
86
86
+
el.querySelector('button')!.click()
87
87
+
t.assert.strictEqual(clicks, 2)
88
88
+
})
90
89
91
91
-
it('supports event handlers that change', () => {
92
92
-
const { root, el } = setup()
90
90
+
test('supports event handlers that change', (t: TestContext) => {
91
91
+
const { root, el } = setup()
93
92
94
94
-
const template = (handler: (() => void) | null) => html`<input onblur=${handler}>Click me</input>`
93
93
+
const template = (handler: (() => void) | null) => html`<input onblur=${handler}>Click me</input>`
95
94
96
96
-
const handler = vi.fn()
97
97
-
root.render(template(handler))
98
98
-
expect(handler).not.toBeCalled()
95
95
+
const handler = t.mock.fn()
96
96
+
root.render(template(handler))
97
97
+
t.assert.strictEqual(handler.mock.callCount(), 0)
99
98
100
100
-
const event = new Event('blur')
101
101
-
el.querySelector('input')!.dispatchEvent(event)
102
102
-
expect(handler).toHaveBeenCalledExactlyOnceWith(event)
99
99
+
const event = new Event('blur')
100
100
+
el.querySelector('input')!.dispatchEvent(event)
101
101
+
t.assert.strictEqual(handler.mock.callCount(), 1)
102
102
+
t.assert.strictEqual(handler.mock.calls[0].arguments[0], event)
103
103
104
104
-
root.render(template(null))
105
105
-
el.querySelector('input')!.dispatchEvent(new Event('blur'))
106
106
-
expect(handler).toHaveBeenCalledOnce()
107
107
-
})
104
104
+
root.render(template(null))
105
105
+
el.querySelector('input')!.dispatchEvent(new Event('blur'))
106
106
+
t.assert.strictEqual(handler.mock.callCount(), 1)
108
107
})
+131
-128
src/client/tests/basic.test.ts
reviewed
···
1
1
import { html, type Displayable } from 'dhtml'
2
2
-
import { describe, expect, it } from 'vitest'
3
3
-
import { setup } from './setup'
2
2
+
import test, { type TestContext } from 'node:test'
3
3
+
import { setup } from './setup.ts'
4
4
5
5
-
describe('basic', () => {
6
6
-
it('should render basic html', () => {
7
7
-
const { root, el } = setup()
5
5
+
test('basic html renders correctly', (t: TestContext) => {
6
6
+
const { root, el } = setup()
8
7
9
9
-
root.render(html`<h1>Hello, world!</h1>`)
10
10
-
expect(el.innerHTML).toBe('<h1>Hello, world!</h1>')
11
11
-
})
8
8
+
root.render(html`<h1>Hello, world!</h1>`)
9
9
+
t.assert.strictEqual(el.innerHTML, '<h1>Hello, world!</h1>')
10
10
+
})
12
11
13
13
-
it('should render inner content', () => {
14
14
-
const { root, el } = setup()
12
12
+
test('inner content renders correctly', (t: TestContext) => {
13
13
+
const { root, el } = setup()
15
14
16
16
-
root.render(html`<h1>${html`Inner content!`}</h1>`)
17
17
-
expect(el.innerHTML).toBe('<h1>Inner content!</h1>')
18
18
-
})
15
15
+
root.render(html`<h1>${html`Inner content!`}</h1>`)
16
16
+
t.assert.strictEqual(el.innerHTML, '<h1>Inner content!</h1>')
17
17
+
})
19
18
20
20
-
it('should render template with number', () => {
21
21
-
const { root, el } = setup()
19
19
+
test('template with number renders correctly', (t: TestContext) => {
20
20
+
const { root, el } = setup()
22
21
23
23
-
const template = (n: number) => html`<h1>Hello, ${n}!</h1>`
22
22
+
const template = (n: number) => html`<h1>Hello, ${n}!</h1>`
24
23
25
25
-
root.render(template(1))
26
26
-
expect(el.innerHTML).toBe('<h1>Hello, 1!</h1>')
24
24
+
root.render(template(1))
25
25
+
t.assert.strictEqual(el.innerHTML, '<h1>Hello, 1!</h1>')
27
26
28
28
-
root.render(template(2))
29
29
-
expect(el.innerHTML).toBe('<h1>Hello, 2!</h1>')
30
30
-
})
27
27
+
root.render(template(2))
28
28
+
t.assert.strictEqual(el.innerHTML, '<h1>Hello, 2!</h1>')
29
29
+
})
31
30
32
32
-
it('should not clobber external sibling nodes', () => {
33
33
-
const { root, el } = setup('<div>before</div>')
31
31
+
test('external sibling nodes are not clobbered', (t: TestContext) => {
32
32
+
const { root, el } = setup('<div>before</div>')
34
33
35
35
-
root.render(html`<h1>Hello, world!</h1>`)
36
36
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<div>before</div><h1>Hello, world!</h1>"`)
34
34
+
root.render(html`<h1>Hello, world!</h1>`)
35
35
+
t.assert.strictEqual(el.innerHTML, '<div>before</div><h1>Hello, world!</h1>')
37
36
38
38
-
el.appendChild(document.createElement('div')).textContent = 'after'
39
39
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<div>before</div><h1>Hello, world!</h1><div>after</div>"`)
37
37
+
el.appendChild(document.createElement('div')).textContent = 'after'
38
38
+
t.assert.strictEqual(el.innerHTML, '<div>before</div><h1>Hello, world!</h1><div>after</div>')
40
39
41
41
-
root.render(html`<h2>Goodbye, world!</h2>`)
42
42
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<div>before</div><h2>Goodbye, world!</h2><div>after</div>"`)
40
40
+
root.render(html`<h2>Goodbye, world!</h2>`)
41
41
+
t.assert.strictEqual(el.innerHTML, '<div>before</div><h2>Goodbye, world!</h2><div>after</div>')
43
42
44
44
-
root.render(html``)
45
45
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<div>before</div><div>after</div>"`)
43
43
+
root.render(html``)
44
44
+
t.assert.strictEqual(el.innerHTML, '<div>before</div><div>after</div>')
46
45
47
47
-
root.render(html`<h1>Hello, world!</h1>`)
48
48
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<div>before</div><h1>Hello, world!</h1><div>after</div>"`)
49
49
-
})
46
46
+
root.render(html`<h1>Hello, world!</h1>`)
47
47
+
t.assert.strictEqual(el.innerHTML, '<div>before</div><h1>Hello, world!</h1><div>after</div>')
48
48
+
})
50
49
51
51
-
it('update identity', () => {
52
52
-
const { root, el } = setup()
50
50
+
test('identity is updated correctly', (t: TestContext) => {
51
51
+
const { root, el } = setup()
53
52
54
54
-
const template = (n: Displayable) => html`<h1>Hello, ${n}!</h1>`
55
55
-
const template2 = (n: Displayable) => html`<h1>Hello, ${n}!</h1>`
53
53
+
const template = (n: Displayable) => html`<h1>Hello, ${n}!</h1>`
54
54
+
const template2 = (n: Displayable) => html`<h1>Hello, ${n}!</h1>`
56
55
57
57
-
root.render(template(1))
58
58
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<h1>Hello, 1!</h1>"`)
59
59
-
let h1 = el.children[0]
60
60
-
const text = h1.childNodes[1] as Text
61
61
-
expect(text).toBeInstanceOf(Text)
62
62
-
expect(text.data).toBe('1')
56
56
+
root.render(template(1))
57
57
+
t.assert.strictEqual(el.innerHTML, '<h1>Hello, 1!</h1>')
58
58
+
let h1 = el.children[0]
59
59
+
const text = h1.childNodes[1] as Text
60
60
+
t.assert.ok(text instanceof Text)
61
61
+
t.assert.strictEqual(text.data, '1')
63
62
64
64
-
root.render(template(2))
65
65
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<h1>Hello, 2!</h1>"`)
66
66
-
expect(el.children[0]).toBe(h1)
67
67
-
expect(text.data).toBe('2')
68
68
-
expect(h1.childNodes[1]).toBe(text)
63
63
+
root.render(template(2))
64
64
+
t.assert.strictEqual(el.innerHTML, '<h1>Hello, 2!</h1>')
65
65
+
t.assert.strictEqual(el.children[0], h1)
66
66
+
t.assert.strictEqual(text.data, '2')
67
67
+
t.assert.strictEqual(h1.childNodes[1], text)
69
68
70
70
-
root.render(template2(3))
71
71
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<h1>Hello, 3!</h1>"`)
72
72
-
expect(el.children[0]).not.toBe(h1)
73
73
-
h1 = el.children[0]
69
69
+
root.render(template2(3))
70
70
+
t.assert.strictEqual(el.innerHTML, '<h1>Hello, 3!</h1>')
71
71
+
t.assert.notStrictEqual(el.children[0], h1)
72
72
+
h1 = el.children[0]
74
73
75
75
-
root.render(template2(template(template('inner'))))
76
76
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<h1>Hello, <h1>Hello, <h1>Hello, inner!</h1>!</h1>!</h1>"`)
77
77
-
expect(el.children[0]).toBe(h1)
78
78
-
})
74
74
+
root.render(template2(template(template('inner'))))
75
75
+
t.assert.strictEqual(el.innerHTML, '<h1>Hello, <h1>Hello, <h1>Hello, inner!</h1>!</h1>!</h1>')
76
76
+
t.assert.strictEqual(el.children[0], h1)
77
77
+
})
79
78
80
80
-
it('basic children', () => {
81
81
-
const { root, el } = setup()
79
79
+
test('basic children render correctly', (t: TestContext) => {
80
80
+
const { root, el } = setup()
82
81
83
83
-
root.render(html`<span>${'This is a'}</span> ${html`test`} ${html`test`} ${html`test`}`)
82
82
+
root.render(html`<span>${'This is a'}</span> ${html`test`} ${html`test`} ${html`test`}`)
84
83
85
85
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<span>This is a</span> test test test"`)
86
86
-
})
84
84
+
t.assert.strictEqual(el.innerHTML, '<span>This is a</span> test test test')
85
85
+
})
87
86
88
88
-
it('can embed nodes', () => {
89
89
-
const { root, el } = setup()
87
87
+
test('nodes can be embedded', (t: TestContext) => {
88
88
+
const { root, el } = setup()
90
89
91
91
-
let node: ParentNode = document.createElement('span')
90
90
+
let node: ParentNode = document.createElement('span')
92
91
93
93
-
root.render(html`<div>${node}</div>`)
94
94
-
expect(el.innerHTML).toBe('<div><span></span></div>')
95
95
-
expect(el.children[0].children[0]).toBe(node)
92
92
+
root.render(html`<div>${node}</div>`)
93
93
+
t.assert.strictEqual(el.innerHTML, '<div><span></span></div>')
94
94
+
t.assert.strictEqual(el.children[0].children[0], node)
96
95
97
97
-
node = document.createDocumentFragment()
98
98
-
node.append(document.createElement('h1'), document.createElement('h2'), document.createElement('h3'))
96
96
+
node = document.createDocumentFragment()
97
97
+
node.append(document.createElement('h1'), document.createElement('h2'), document.createElement('h3'))
99
98
100
100
-
root.render(html`<div>${node}</div>`)
101
101
-
expect(el.innerHTML).toBe('<div><h1></h1><h2></h2><h3></h3></div>')
102
102
-
expect(node.children.length).toBe(0)
103
103
-
})
99
99
+
root.render(html`<div>${node}</div>`)
100
100
+
t.assert.strictEqual(el.innerHTML, '<div><h1></h1><h2></h2><h3></h3></div>')
101
101
+
t.assert.strictEqual(node.children.length, 0)
102
102
+
})
104
103
105
105
-
it.todo('does not add extra empty text nodes', () => {
106
106
-
const { root, el } = setup()
104
104
+
test.skip('extra empty text nodes are not added', (t: TestContext) => {
105
105
+
const { root, el } = setup()
107
106
108
108
-
root.render(html`${'abc'}`)
109
109
-
expect(el.childNodes.length).toBe(1)
110
110
-
expect(el.firstChild).toBeInstanceOf(Text)
111
111
-
expect((el.firstChild as Text).data).toBe('abc')
112
112
-
})
107
107
+
root.render(html`${'abc'}`)
108
108
+
t.assert.strictEqual(el.childNodes.length, 1)
109
109
+
t.assert.ok(el.firstChild instanceof Text)
110
110
+
t.assert.strictEqual((el.firstChild as Text).data, 'abc')
111
111
+
})
113
112
114
114
-
it('shifting ChildPart index', () => {
115
115
-
const { root, el } = setup()
113
113
+
test('ChildPart index shifts correctly', (t: TestContext) => {
114
114
+
const { root, el } = setup()
116
115
117
117
-
root.render(html`${html`A<!--x-->`}B${'C'}`)
116
116
+
root.render(html`${html`A<!--x-->`}B${'C'}`)
118
117
119
119
-
expect(el.innerHTML).toBe('A<!--x-->BC')
120
120
-
})
118
118
+
t.assert.strictEqual(el.innerHTML, 'A<!--x-->BC')
121
119
})
122
120
123
123
-
describe('errors', () => {
124
124
-
it('throws cleanly', () => {
125
125
-
const { root, el } = setup()
121
121
+
test('errors are thrown cleanly', (t: TestContext) => {
122
122
+
const { root, el } = setup()
126
123
127
127
-
const oops = new Error('oops')
128
128
-
let thrown
129
129
-
try {
130
130
-
root.render(
131
131
-
html`${{
132
132
-
render() {
133
133
-
throw oops
134
134
-
},
135
135
-
}}`,
136
136
-
)
137
137
-
} catch (error) {
138
138
-
thrown = error
139
139
-
}
140
140
-
expect(thrown).toBe(oops)
124
124
+
const oops = new Error('oops')
125
125
+
let thrown
126
126
+
try {
127
127
+
root.render(
128
128
+
html`${{
129
129
+
render() {
130
130
+
throw oops
131
131
+
},
132
132
+
}}`,
133
133
+
)
134
134
+
} catch (error) {
135
135
+
thrown = error
136
136
+
}
137
137
+
t.assert.strictEqual(thrown, oops)
141
138
142
142
-
// on an error, don't leave any visible artifacts
143
143
-
expect(el.innerHTML).toBe('<!---->')
144
144
-
})
139
139
+
// on an error, don't leave any visible artifacts
140
140
+
t.assert.strictEqual(el.innerHTML, '<!---->')
141
141
+
})
145
142
146
146
-
it('warns on invalid part placement', { skip: import.meta.env.PROD }, () => {
147
147
-
const { root, el } = setup()
143
143
+
test('invalid part placement produces warning', { skip: process.env.NODE_ENV === 'production' }, (t: TestContext) => {
144
144
+
const { root, el } = setup()
148
145
149
149
-
expect(() => root.render(html`<${'div'}>${'text'}</${'div'}>`)).toThrowErrorMatchingInlineSnapshot(
150
150
-
`[Error: expected the same number of dynamics as parts. do you have a \${...} in an unsupported place?]`,
151
151
-
)
152
152
-
expect(el.innerHTML).toBe('')
146
146
+
t.assert.throws(() => root.render(html`<${'div'}>${'text'}</${'div'}>`), {
147
147
+
message: 'expected the same number of dynamics as parts. do you have a ${...} in an unsupported place?',
153
148
})
149
149
+
t.assert.strictEqual(el.innerHTML, '')
150
150
+
})
154
151
155
155
-
it('does not throw on parts in comments', () => {
156
156
-
const { root, el } = setup()
152
152
+
test('parts in comments do not throw', (t: TestContext) => {
153
153
+
const { root, el } = setup()
157
154
158
158
-
root.render(html`<!-- ${'text'} -->`)
159
159
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<!-- dyn-$0$ -->"`)
160
160
-
})
155
155
+
root.render(html`<!-- ${'text'} -->`)
156
156
+
t.assert.strictEqual(el.innerHTML, '<!-- dyn-$0$ -->')
157
157
+
})
161
158
162
162
-
it('throws when manually specifying internal template syntax', { skip: import.meta.env.PROD }, () => {
159
159
+
test(
160
160
+
'manually specifying internal template syntax throws',
161
161
+
{ skip: process.env.NODE_ENV === 'production' },
162
162
+
(t: TestContext) => {
163
163
const { root, el } = setup()
164
164
165
165
-
expect(() => {
166
166
-
root.render(html`${1} dyn-$0$`)
167
167
-
}).toThrowErrorMatchingInlineSnapshot(`[Error: got more parts than expected]`)
165
165
+
t.assert.throws(
166
166
+
() => {
167
167
+
root.render(html`${1} dyn-$0$`)
168
168
+
},
169
169
+
{ message: 'got more parts than expected' },
170
170
+
)
168
171
169
169
-
expect(el.innerHTML).toMatchInlineSnapshot(`""`)
170
170
-
})
172
172
+
t.assert.strictEqual(el.innerHTML, '')
173
173
+
},
174
174
+
)
171
175
172
172
-
it('does not throw when syntax is close but not exact', () => {
173
173
-
const { root, el } = setup()
176
176
+
test('syntax close but not exact does not throw', (t: TestContext) => {
177
177
+
const { root, el } = setup()
174
178
175
175
-
root.render(html`dyn-$${0}1$`)
179
179
+
root.render(html`dyn-$${0}1$`)
176
180
177
177
-
expect(el.innerHTML).toMatchInlineSnapshot(`"dyn-$01$"`)
178
178
-
})
181
181
+
t.assert.strictEqual(el.innerHTML, 'dyn-$01$')
179
182
})
+17
-19
src/client/tests/custom-elements.test.ts
reviewed
···
1
1
import { html } from 'dhtml'
2
2
import { createRoot } from 'dhtml/client'
3
3
-
import { describe, expect, it } from 'vitest'
4
4
-
import { setup } from './setup'
3
3
+
import test, { type TestContext } from 'node:test'
4
4
+
import { setup } from './setup.ts'
5
5
6
6
class CustomElement extends HTMLElement {
7
7
#thing?: string
···
20
20
21
21
customElements.define('custom-element', CustomElement)
22
22
23
23
-
describe('custom elements', () => {
24
24
-
it('correctly instantiates custom elements', () => {
25
25
-
const { root, el } = setup()
23
23
+
test('custom elements instantiate correctly', (t: TestContext) => {
24
24
+
const { root, el } = setup()
26
25
27
27
-
root.render(html`<custom-element thing=${'hello'}></custom-element>`)
28
28
-
expect(el.innerHTML).toBe(`<custom-element>inside custom element</custom-element>`)
26
26
+
root.render(html`<custom-element thing=${'hello'}></custom-element>`)
27
27
+
t.assert.strictEqual(el.innerHTML, `<custom-element>inside custom element</custom-element>`)
29
28
30
30
-
const customElement = el.querySelector('custom-element') as CustomElement
31
31
-
expect(customElement).toBeInstanceOf(CustomElement)
32
32
-
expect(customElement.thing).toBe('HELLO')
33
33
-
})
29
29
+
const customElement = el.querySelector('custom-element') as CustomElement
30
30
+
t.assert.ok(customElement instanceof CustomElement)
31
31
+
t.assert.strictEqual(customElement.thing, 'HELLO')
32
32
+
})
34
33
35
35
-
it('renders into shadow dom', () => {
36
36
-
const { el } = setup()
37
37
-
const shadowRoot = el.attachShadow({ mode: 'open' })
34
34
+
test('content renders into shadow dom', (t: TestContext) => {
35
35
+
const { el } = setup()
36
36
+
const shadowRoot = el.attachShadow({ mode: 'open' })
38
37
39
39
-
const root = createRoot(shadowRoot)
40
40
-
root.render(html`<p>hello</p>`)
38
38
+
const root = createRoot(shadowRoot)
39
39
+
root.render(html`<p>hello</p>`)
41
40
42
42
-
expect(el.innerHTML).toBe(``)
43
43
-
expect(shadowRoot.innerHTML).toBe(`<p>hello</p>`)
44
44
-
})
41
41
+
t.assert.strictEqual(el.innerHTML, ``)
42
42
+
t.assert.strictEqual(shadowRoot.innerHTML, `<p>hello</p>`)
45
43
})
+65
-69
src/client/tests/directives.test.ts
reviewed
···
1
1
import { html } from 'dhtml'
2
2
import { attr, type Directive } from 'dhtml/client'
3
3
-
import { describe, expect, it } from 'vitest'
4
4
-
import { setup } from './setup'
3
3
+
import test, { type TestContext } from 'node:test'
4
4
+
import { setup } from './setup.ts'
5
5
6
6
-
describe('directives', () => {
7
7
-
it('functions', () => {
8
8
-
const { root, el } = setup()
6
6
+
test('directive functions work correctly', (t: TestContext) => {
7
7
+
const { root, el } = setup()
9
8
10
10
-
const redifier: Directive = node => {
11
11
-
if (!(node instanceof HTMLElement)) throw new Error('expected HTMLElement')
12
12
-
node.style.color = 'red'
13
13
-
return () => {
14
14
-
node.style.color = ''
15
15
-
}
9
9
+
const redifier: Directive = node => {
10
10
+
if (!(node instanceof HTMLElement)) throw new Error('expected HTMLElement')
11
11
+
node.style.color = 'red'
12
12
+
return () => {
13
13
+
node.style.color = ''
16
14
}
17
17
-
const flipper: Directive = node => {
18
18
-
if (!(node instanceof HTMLElement)) throw new Error('expected HTMLElement')
19
19
-
node.style.transform = 'scaleX(-1)'
20
20
-
return () => {
21
21
-
node.style.transform = ''
22
22
-
}
15
15
+
}
16
16
+
const flipper: Directive = node => {
17
17
+
if (!(node instanceof HTMLElement)) throw new Error('expected HTMLElement')
18
18
+
node.style.transform = 'scaleX(-1)'
19
19
+
return () => {
20
20
+
node.style.transform = ''
23
21
}
22
22
+
}
24
23
25
25
-
const template = (d: Directive | null) => html`<div ${d}>Hello, world!</div>`
24
24
+
const template = (d: Directive | null) => html`<div ${d}>Hello, world!</div>`
26
25
27
27
-
root.render(template(redifier))
28
28
-
const div = el.firstChild as HTMLElement
29
29
-
expect(div.tagName).toBe('DIV')
30
30
-
expect(div.style.cssText).toBe('color: red;')
26
26
+
root.render(template(redifier))
27
27
+
const div = el.firstChild as HTMLElement
28
28
+
t.assert.strictEqual(div.tagName, 'DIV')
29
29
+
t.assert.strictEqual(div.style.cssText, 'color: red;')
31
30
32
32
-
root.render(template(flipper))
33
33
-
expect(div.style.cssText).toBe('transform: scaleX(-1);')
31
31
+
root.render(template(flipper))
32
32
+
t.assert.strictEqual(div.style.cssText, 'transform: scaleX(-1);')
34
33
35
35
-
root.render(template(null))
36
36
-
expect(div.style.cssText).toBe('')
34
34
+
root.render(template(null))
35
35
+
t.assert.strictEqual(div.style.cssText, '')
37
36
38
38
-
root.render(null)
39
39
-
})
37
37
+
root.render(null)
38
38
+
})
40
39
41
41
-
it('functions with values', () => {
42
42
-
const { root, el } = setup()
40
40
+
test('directive functions with values work correctly', (t: TestContext) => {
41
41
+
const { root, el } = setup()
43
42
44
44
-
function classes(value: string[]): Directive {
45
45
-
const values = value.filter(Boolean)
46
46
-
return node => {
47
47
-
node.classList.add(...values)
48
48
-
return () => {
49
49
-
node.classList.remove(...values)
50
50
-
}
43
43
+
function classes(value: string[]): Directive {
44
44
+
const values = value.filter(Boolean)
45
45
+
return node => {
46
46
+
node.classList.add(...values)
47
47
+
return () => {
48
48
+
node.classList.remove(...values)
51
49
}
52
50
}
51
51
+
}
53
52
54
54
-
const template = (c: string[]) => html`<div class="foo" ${classes(c)}>Hello, world!</div>`
53
53
+
const template = (c: string[]) => html`<div class="foo" ${classes(c)}>Hello, world!</div>`
55
54
56
56
-
root.render(template(['a', 'b']))
57
57
-
const div = el.firstChild as HTMLElement
58
58
-
expect(div.tagName).toBe('DIV')
59
59
-
expect(div.className).toBe('foo a b')
55
55
+
root.render(template(['a', 'b']))
56
56
+
const div = el.firstChild as HTMLElement
57
57
+
t.assert.strictEqual(div.tagName, 'DIV')
58
58
+
t.assert.strictEqual(div.className, 'foo a b')
60
59
61
61
-
root.render(template(['c', 'd']))
62
62
-
expect(div.className).toBe('foo c d')
60
60
+
root.render(template(['c', 'd']))
61
61
+
t.assert.strictEqual(div.className, 'foo c d')
63
62
64
64
-
root.render(template([]))
65
65
-
expect(div.className).toBe('foo')
66
66
-
})
63
63
+
root.render(template([]))
64
64
+
t.assert.strictEqual(div.className, 'foo')
67
65
})
68
66
69
69
-
describe('attr', () => {
70
70
-
it('works', () => {
71
71
-
const { root, el } = setup()
67
67
+
test('attr directive works correctly', (t: TestContext) => {
68
68
+
const { root, el } = setup()
72
69
73
73
-
const template = (value: string | null) => html`
74
74
-
<input id="attr-works-input"></input>
75
75
-
<label ${attr('for', value)}>Hello, world!</label>
76
76
-
`
70
70
+
const template = (value: string | null) => html`
71
71
+
<input id="attr-works-input"></input>
72
72
+
<label ${attr('for', value)}>Hello, world!</label>
73
73
+
`
77
74
78
78
-
root.render(template('attr-works-input'))
79
79
-
expect(el.querySelector('label')).toHaveProperty('htmlFor', 'attr-works-input')
75
75
+
root.render(template('attr-works-input'))
76
76
+
t.assert.strictEqual(el.querySelector('label')!.htmlFor, 'attr-works-input')
80
77
81
81
-
root.render(template('updated'))
82
82
-
expect(el.querySelector('label')).toHaveProperty('htmlFor', 'updated')
78
78
+
root.render(template('updated'))
79
79
+
t.assert.strictEqual(el.querySelector('label')!.htmlFor, 'updated')
83
80
84
84
-
root.render(template(null))
85
85
-
expect(el.querySelector('label')).toHaveProperty('htmlFor', '')
86
86
-
})
81
81
+
root.render(template(null))
82
82
+
t.assert.strictEqual(el.querySelector('label')!.htmlFor, '')
83
83
+
})
87
84
88
88
-
it('supports booleans', () => {
89
89
-
const { root, el } = setup()
85
85
+
test('attr directive supports booleans', (t: TestContext) => {
86
86
+
const { root, el } = setup()
90
87
91
91
-
const template = (value: boolean) => html`<input ${attr('disabled', value)} />`
88
88
+
const template = (value: boolean) => html`<input ${attr('disabled', value)} />`
92
89
93
93
-
root.render(template(true))
94
94
-
expect(el.querySelector('input')).toHaveProperty('disabled', true)
90
90
+
root.render(template(true))
91
91
+
t.assert.strictEqual(el.querySelector('input')!.disabled, true)
95
92
96
96
-
root.render(template(false))
97
97
-
expect(el.querySelector('input')).toHaveProperty('disabled', false)
98
98
-
})
93
93
+
root.render(template(false))
94
94
+
t.assert.strictEqual(el.querySelector('input')!.disabled, false)
99
95
})
+252
-256
src/client/tests/lists.test.ts
reviewed
···
1
1
import { html, type Displayable } from 'dhtml'
2
2
import { keyed } from 'dhtml/client'
3
3
-
import { describe, expect, it } from 'vitest'
4
4
-
import { setup } from './setup'
3
3
+
import test, { type TestContext } from 'node:test'
4
4
+
import { setup } from './setup.ts'
5
5
6
6
function shuffle<T>(array: T[]) {
7
7
for (let i = 0; i < array.length; i++) {
···
10
10
}
11
11
}
12
12
13
13
-
describe('lists', () => {
14
14
-
it('basic', () => {
15
15
-
const { root, el } = setup()
13
13
+
test('basic list operations work correctly', (t: TestContext) => {
14
14
+
const { root, el } = setup()
16
15
17
17
-
let items: Displayable[] | null = null
18
18
-
const listOfItems = () => html`
19
19
-
<ul>
20
20
-
<li>Before</li>
21
21
-
${items}
22
22
-
<li>After</li>
23
23
-
</ul>
24
24
-
`
16
16
+
let items: Displayable[] | null = null
17
17
+
const listOfItems = () => html`
18
18
+
<ul>
19
19
+
<li>Before</li>
20
20
+
${items}
21
21
+
<li>After</li>
22
22
+
</ul>
23
23
+
`
25
24
26
26
-
root.render(listOfItems())
27
27
-
expect(el.innerHTML.replace(/\s+/g, ' ')).toBe(' <ul> <li>Before</li> <li>After</li> </ul> ')
25
25
+
root.render(listOfItems())
26
26
+
t.assert.strictEqual(el.innerHTML.replace(/\s+/g, ' '), ' <ul> <li>Before</li> <li>After</li> </ul> ')
28
27
29
29
-
items = [html`<li>Item 1</li>`, html`<li>Item 2</li>`, html`<li>Item 3</li>`]
28
28
+
items = [html`<li>Item 1</li>`, html`<li>Item 2</li>`, html`<li>Item 3</li>`]
30
29
31
31
-
root.render(listOfItems())
32
32
-
expect(el.innerHTML.replace(/\s+/g, ' ')).toBe(
33
33
-
' <ul> <li>Before</li> <li>Item 1</li><li>Item 2</li><li>Item 3</li> <li>After</li> </ul> ',
34
34
-
)
35
35
-
const [item1, item2, item3] = el.querySelectorAll('li')
30
30
+
root.render(listOfItems())
31
31
+
t.assert.strictEqual(
32
32
+
el.innerHTML.replace(/\s+/g, ' '),
33
33
+
' <ul> <li>Before</li> <li>Item 1</li><li>Item 2</li><li>Item 3</li> <li>After</li> </ul> ',
34
34
+
)
35
35
+
const [item1, item2, item3] = el.querySelectorAll('li')
36
36
37
37
-
items.push(html`<li>Item 4</li>`)
38
38
-
root.render(listOfItems())
39
39
-
expect(el.innerHTML.replace(/\s+/g, ' ')).toBe(
40
40
-
' <ul> <li>Before</li> <li>Item 1</li><li>Item 2</li><li>Item 3</li><li>Item 4</li> <li>After</li> </ul> ',
41
41
-
)
42
42
-
const [item1b, item2b, item3b] = el.querySelectorAll('li')
43
43
-
expect(item1).toBe(item1b)
44
44
-
expect(item2).toBe(item2b)
45
45
-
expect(item3).toBe(item3b)
37
37
+
items.push(html`<li>Item 4</li>`)
38
38
+
root.render(listOfItems())
39
39
+
t.assert.strictEqual(
40
40
+
el.innerHTML.replace(/\s+/g, ' '),
41
41
+
' <ul> <li>Before</li> <li>Item 1</li><li>Item 2</li><li>Item 3</li><li>Item 4</li> <li>After</li> </ul> ',
42
42
+
)
43
43
+
const [item1b, item2b, item3b] = el.querySelectorAll('li')
44
44
+
t.assert.strictEqual(item1, item1b)
45
45
+
t.assert.strictEqual(item2, item2b)
46
46
+
t.assert.strictEqual(item3, item3b)
46
47
47
47
-
items.pop()
48
48
-
items.pop()
49
49
-
root.render(listOfItems())
50
50
-
expect(el.innerHTML.replace(/\s+/g, ' ')).toBe(
51
51
-
' <ul> <li>Before</li> <li>Item 1</li><li>Item 2</li> <li>After</li> </ul> ',
52
52
-
)
53
53
-
const [item1c, item2c] = el.querySelectorAll('li')
54
54
-
expect(item1).toBe(item1c)
55
55
-
expect(item2).toBe(item2c)
56
56
-
})
48
48
+
items.pop()
49
49
+
items.pop()
50
50
+
root.render(listOfItems())
51
51
+
t.assert.strictEqual(
52
52
+
el.innerHTML.replace(/\s+/g, ' '),
53
53
+
' <ul> <li>Before</li> <li>Item 1</li><li>Item 2</li> <li>After</li> </ul> ',
54
54
+
)
55
55
+
const [item1c, item2c] = el.querySelectorAll('li')
56
56
+
t.assert.strictEqual(item1, item1c)
57
57
+
t.assert.strictEqual(item2, item2c)
58
58
+
})
57
59
58
58
-
it('pop', () => {
59
59
-
const { root, el } = setup()
60
60
+
test('pop operation works correctly on lists', (t: TestContext) => {
61
61
+
const { root, el } = setup()
60
62
61
61
-
const items = [html`<p>Item 1</p>`, html`<p>Item 2</p>`, html`<p>Item 3</p>`]
62
62
-
const wrapped = html`[${items}]`
63
63
+
const items = [html`<p>Item 1</p>`, html`<p>Item 2</p>`, html`<p>Item 3</p>`]
64
64
+
const wrapped = html`[${items}]`
63
65
64
64
-
root.render(wrapped)
65
65
-
expect(el.innerHTML).toBe('[<p>Item 1</p><p>Item 2</p><p>Item 3</p>]')
66
66
-
const [item1, item2] = el.children
66
66
+
root.render(wrapped)
67
67
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 1</p><p>Item 2</p><p>Item 3</p>]')
68
68
+
const [item1, item2] = el.children
67
69
68
68
-
items.pop()
69
69
-
root.render(wrapped)
70
70
-
expect(el.innerHTML).toBe('[<p>Item 1</p><p>Item 2</p>]')
71
71
-
expect(el.children[0]).toBe(item1)
72
72
-
expect(el.children[1]).toBe(item2)
70
70
+
items.pop()
71
71
+
root.render(wrapped)
72
72
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 1</p><p>Item 2</p>]')
73
73
+
t.assert.strictEqual(el.children[0], item1)
74
74
+
t.assert.strictEqual(el.children[1], item2)
73
75
74
74
-
items.pop()
75
75
-
root.render(wrapped)
76
76
-
expect(el.innerHTML).toBe('[<p>Item 1</p>]')
77
77
-
expect(el.children[0]).toBe(item1)
76
76
+
items.pop()
77
77
+
root.render(wrapped)
78
78
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 1</p>]')
79
79
+
t.assert.strictEqual(el.children[0], item1)
78
80
79
79
-
items.pop()
80
80
-
root.render(wrapped)
81
81
-
expect(el.innerHTML).toBe('[]')
82
82
-
})
81
81
+
items.pop()
82
82
+
root.render(wrapped)
83
83
+
t.assert.strictEqual(el.innerHTML, '[]')
84
84
+
})
83
85
84
84
-
it('swap', () => {
85
85
-
const { root, el } = setup()
86
86
+
test('swap operation works correctly on lists', (t: TestContext) => {
87
87
+
const { root, el } = setup()
86
88
87
87
-
const items = [html`<p>Item 1</p>`, html`<p>Item 2</p>`, html`<p>Item 3</p>`]
88
88
-
const wrapped = html`[${items}]`
89
89
+
const items = [html`<p>Item 1</p>`, html`<p>Item 2</p>`, html`<p>Item 3</p>`]
90
90
+
const wrapped = html`[${items}]`
89
91
90
90
-
root.render(wrapped)
91
91
-
expect(el.innerHTML).toBe('[<p>Item 1</p><p>Item 2</p><p>Item 3</p>]')
92
92
-
const [item1, item2, item3] = el.children
92
92
+
root.render(wrapped)
93
93
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 1</p><p>Item 2</p><p>Item 3</p>]')
94
94
+
const [item1, item2, item3] = el.children
93
95
94
94
-
// swap the first two items
95
95
-
;[items[0], items[1]] = [items[1], items[0]]
96
96
-
root.render(wrapped)
97
97
-
expect(el.innerHTML).toBe('[<p>Item 2</p><p>Item 1</p><p>Item 3</p>]')
98
98
-
expect(el.children[0]).toBe(item2)
99
99
-
expect(el.children[1]).toBe(item1)
100
100
-
expect(el.children[2]).toBe(item3)
96
96
+
// swap the first two items
97
97
+
;[items[0], items[1]] = [items[1], items[0]]
98
98
+
root.render(wrapped)
99
99
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 2</p><p>Item 1</p><p>Item 3</p>]')
100
100
+
t.assert.strictEqual(el.children[0], item2)
101
101
+
t.assert.strictEqual(el.children[1], item1)
102
102
+
t.assert.strictEqual(el.children[2], item3)
101
103
102
102
-
// swap the last two items
103
103
-
;[items[1], items[2]] = [items[2], items[1]]
104
104
-
root.render(wrapped)
105
105
-
expect(el.innerHTML).toBe('[<p>Item 2</p><p>Item 3</p><p>Item 1</p>]')
106
106
-
expect(el.children[0]).toBe(item2)
107
107
-
expect(el.children[1]).toBe(item3)
108
108
-
expect(el.children[2]).toBe(item1)
104
104
+
// swap the last two items
105
105
+
;[items[1], items[2]] = [items[2], items[1]]
106
106
+
root.render(wrapped)
107
107
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 2</p><p>Item 3</p><p>Item 1</p>]')
108
108
+
t.assert.strictEqual(el.children[0], item2)
109
109
+
t.assert.strictEqual(el.children[1], item3)
110
110
+
t.assert.strictEqual(el.children[2], item1)
109
111
110
110
-
// swap the first and last items
111
111
-
;[items[0], items[2]] = [items[2], items[0]]
112
112
-
root.render(wrapped)
113
113
-
expect(el.innerHTML).toBe('[<p>Item 1</p><p>Item 3</p><p>Item 2</p>]')
114
114
-
expect(el.children[0]).toBe(item1)
115
115
-
expect(el.children[1]).toBe(item3)
116
116
-
expect(el.children[2]).toBe(item2)
112
112
+
// swap the first and last items
113
113
+
;[items[0], items[2]] = [items[2], items[0]]
114
114
+
root.render(wrapped)
115
115
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 1</p><p>Item 3</p><p>Item 2</p>]')
116
116
+
t.assert.strictEqual(el.children[0], item1)
117
117
+
t.assert.strictEqual(el.children[1], item3)
118
118
+
t.assert.strictEqual(el.children[2], item2)
117
119
118
118
-
// put things back
119
119
-
;[items[1], items[2]] = [items[2], items[1]]
120
120
-
root.render(wrapped)
121
121
-
expect(el.innerHTML).toBe('[<p>Item 1</p><p>Item 2</p><p>Item 3</p>]')
122
122
-
expect(el.children[0]).toBe(item1)
123
123
-
expect(el.children[1]).toBe(item2)
124
124
-
expect(el.children[2]).toBe(item3)
125
125
-
})
120
120
+
// put things back
121
121
+
;[items[1], items[2]] = [items[2], items[1]]
122
122
+
root.render(wrapped)
123
123
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 1</p><p>Item 2</p><p>Item 3</p>]')
124
124
+
t.assert.strictEqual(el.children[0], item1)
125
125
+
t.assert.strictEqual(el.children[1], item2)
126
126
+
t.assert.strictEqual(el.children[2], item3)
127
127
+
})
126
128
127
127
-
it('shift', () => {
128
128
-
const { root, el } = setup()
129
129
+
test('shift operation works correctly on lists', (t: TestContext) => {
130
130
+
const { root, el } = setup()
129
131
130
130
-
const items = [html`<p>Item 1</p>`, html`<p>Item 2</p>`, html`<p>Item 3</p>`]
131
131
-
const wrapped = html`[${items}]`
132
132
+
const items = [html`<p>Item 1</p>`, html`<p>Item 2</p>`, html`<p>Item 3</p>`]
133
133
+
const wrapped = html`[${items}]`
132
134
133
133
-
root.render(wrapped)
134
134
-
expect(el.innerHTML).toBe('[<p>Item 1</p><p>Item 2</p><p>Item 3</p>]')
135
135
-
const [, item2, item3] = el.children
135
135
+
root.render(wrapped)
136
136
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 1</p><p>Item 2</p><p>Item 3</p>]')
137
137
+
const [, item2, item3] = el.children
136
138
137
137
-
items.shift()
138
138
-
root.render(wrapped)
139
139
-
expect(el.innerHTML).toBe('[<p>Item 2</p><p>Item 3</p>]')
140
140
-
expect(el.children[0]).toBe(item2)
141
141
-
expect(el.children[1]).toBe(item3)
139
139
+
items.shift()
140
140
+
root.render(wrapped)
141
141
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 2</p><p>Item 3</p>]')
142
142
+
t.assert.strictEqual(el.children[0], item2)
143
143
+
t.assert.strictEqual(el.children[1], item3)
142
144
143
143
-
items.shift()
144
144
-
root.render(wrapped)
145
145
-
expect(el.innerHTML).toBe('[<p>Item 3</p>]')
146
146
-
expect(el.children[0]).toBe(item3)
145
145
+
items.shift()
146
146
+
root.render(wrapped)
147
147
+
t.assert.strictEqual(el.innerHTML, '[<p>Item 3</p>]')
148
148
+
t.assert.strictEqual(el.children[0], item3)
147
149
148
148
-
items.shift()
149
149
-
root.render(wrapped)
150
150
-
expect(el.innerHTML).toBe('[]')
151
151
-
})
150
150
+
items.shift()
151
151
+
root.render(wrapped)
152
152
+
t.assert.strictEqual(el.innerHTML, '[]')
153
153
+
})
152
154
153
153
-
it('full then empty then full', () => {
154
154
-
const { root, el } = setup()
155
155
+
test('full then empty then full list renders correctly', (t: TestContext) => {
156
156
+
const { root, el } = setup()
155
157
156
156
-
root.render([1])
157
157
-
expect(el.innerHTML).toBe('1')
158
158
+
root.render([1])
159
159
+
t.assert.strictEqual(el.innerHTML, '1')
158
160
159
159
-
root.render([])
160
160
-
expect(el.innerHTML).toBe('')
161
161
+
root.render([])
162
162
+
t.assert.strictEqual(el.innerHTML, '')
161
163
162
162
-
root.render([2])
163
163
-
expect(el.innerHTML).toBe('2')
164
164
-
})
164
164
+
root.render([2])
165
165
+
t.assert.strictEqual(el.innerHTML, '2')
166
166
+
})
165
167
166
166
-
it('can disappear', () => {
167
167
-
const { root, el } = setup()
168
168
+
test('list can disappear when condition changes', (t: TestContext) => {
169
169
+
const { root, el } = setup()
168
170
169
169
-
const app = {
170
170
-
show: true,
171
171
-
render() {
172
172
-
if (!this.show) return null
173
173
-
return [1, 2, 3].map(i => html`<div>${i}</div>`)
174
174
-
},
175
175
-
}
171
171
+
const app = {
172
172
+
show: true,
173
173
+
render() {
174
174
+
if (!this.show) return null
175
175
+
return [1, 2, 3].map(i => html`<div>${i}</div>`)
176
176
+
},
177
177
+
}
176
178
177
177
-
root.render(app)
178
178
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<div>1</div><div>2</div><div>3</div>"`)
179
179
+
root.render(app)
180
180
+
t.assert.strictEqual(el.innerHTML, '<div>1</div><div>2</div><div>3</div>')
179
181
180
180
-
app.show = false
181
181
-
root.render(app)
182
182
-
expect(el.innerHTML).toMatchInlineSnapshot(`""`)
183
183
-
})
182
182
+
app.show = false
183
183
+
root.render(app)
184
184
+
t.assert.strictEqual(el.innerHTML, '')
184
185
})
185
186
186
186
-
describe('list reordering', () => {
187
187
-
it('unkeyed', () => {
188
188
-
const { root, el } = setup()
187
187
+
test('unkeyed lists recreate elements when reordered', (t: TestContext) => {
188
188
+
const { root, el } = setup()
189
189
190
190
-
const a = () => html`<h1>Item 1</h1>`
191
191
-
const b = () => html`<h2>Item 2</h2>`
190
190
+
const a = () => html`<h1>Item 1</h1>`
191
191
+
const b = () => html`<h2>Item 2</h2>`
192
192
193
193
-
root.render([a(), b()])
194
194
-
expect(el.innerHTML).toBe('<h1>Item 1</h1><h2>Item 2</h2>')
193
193
+
root.render([a(), b()])
194
194
+
t.assert.strictEqual(el.innerHTML, '<h1>Item 1</h1><h2>Item 2</h2>')
195
195
196
196
-
const [h1, h2] = el.children
197
197
-
expect(h1.tagName).toBe('H1')
198
198
-
expect(h2.tagName).toBe('H2')
196
196
+
const [h1, h2] = el.children
197
197
+
t.assert.strictEqual(h1.tagName, 'H1')
198
198
+
t.assert.strictEqual(h2.tagName, 'H2')
199
199
200
200
-
root.render([b(), a()])
201
201
-
expect(el.innerHTML).toBe('<h2>Item 2</h2><h1>Item 1</h1>')
200
200
+
root.render([b(), a()])
201
201
+
t.assert.strictEqual(el.innerHTML, '<h2>Item 2</h2><h1>Item 1</h1>')
202
202
203
203
-
// visually they should be swapped
204
204
-
expect(el.children[0]).toEqual(h2)
205
205
-
expect(el.children[1]).toEqual(h1)
203
203
+
// visually they should be swapped
204
204
+
t.assert.strictEqual(el.children[0].innerHTML, h2.innerHTML)
205
205
+
t.assert.strictEqual(el.children[1].innerHTML, h1.innerHTML)
206
206
207
207
-
// but there's no stable identity, so they're recreated
208
208
-
expect(el.children[0]).not.toBe(h2)
209
209
-
expect(el.children[1]).not.toBe(h1)
210
210
-
})
207
207
+
// but there's no stable identity, so they're recreated
208
208
+
t.assert.notStrictEqual(el.children[0], h2)
209
209
+
t.assert.notStrictEqual(el.children[1], h1)
210
210
+
})
211
211
212
212
-
it('explicit keyed', () => {
213
213
-
const { root, el } = setup()
212
212
+
test('explicit keyed lists preserve identity when reordered', (t: TestContext) => {
213
213
+
const { root, el } = setup()
214
214
215
215
-
const a = () => keyed(html`<h1>Item 1</h1>`, 1)
216
216
-
const b = () => keyed(html`<h2>Item 2</h2>`, 2)
215
215
+
const a = () => keyed(html`<h1>Item 1</h1>`, 1)
216
216
+
const b = () => keyed(html`<h2>Item 2</h2>`, 2)
217
217
218
218
-
root.render([a(), b()])
219
219
-
expect(el.innerHTML).toBe('<h1>Item 1</h1><h2>Item 2</h2>')
218
218
+
root.render([a(), b()])
219
219
+
t.assert.strictEqual(el.innerHTML, '<h1>Item 1</h1><h2>Item 2</h2>')
220
220
221
221
-
const [h1, h2] = el.children
222
222
-
expect(h1.tagName).toBe('H1')
223
223
-
expect(h2.tagName).toBe('H2')
221
221
+
const [h1, h2] = el.children
222
222
+
t.assert.strictEqual(h1.tagName, 'H1')
223
223
+
t.assert.strictEqual(h2.tagName, 'H2')
224
224
225
225
-
root.render([b(), a()])
226
226
-
expect(el.innerHTML).toBe('<h2>Item 2</h2><h1>Item 1</h1>')
225
225
+
root.render([b(), a()])
226
226
+
t.assert.strictEqual(el.innerHTML, '<h2>Item 2</h2><h1>Item 1</h1>')
227
227
228
228
-
expect(el.children[0]).toBe(h2)
229
229
-
expect(el.children[1]).toBe(h1)
230
230
-
})
228
228
+
t.assert.strictEqual(el.children[0], h2)
229
229
+
t.assert.strictEqual(el.children[1], h1)
230
230
+
})
231
231
232
232
-
it('implicit keyed', () => {
233
233
-
const { root, el } = setup()
232
232
+
test('implicit keyed lists preserve identity when reordered', (t: TestContext) => {
233
233
+
const { root, el } = setup()
234
234
235
235
-
const items = [html`<h1>Item 1</h1>`, html`<h2>Item 2</h2>`]
235
235
+
const items = [html`<h1>Item 1</h1>`, html`<h2>Item 2</h2>`]
236
236
237
237
-
root.render(items)
238
238
-
expect(el.innerHTML).toBe('<h1>Item 1</h1><h2>Item 2</h2>')
237
237
+
root.render(items)
238
238
+
t.assert.strictEqual(el.innerHTML, '<h1>Item 1</h1><h2>Item 2</h2>')
239
239
240
240
-
const [h1, h2] = el.children
241
241
-
expect(h1.tagName).toBe('H1')
242
242
-
expect(h2.tagName).toBe('H2')
243
243
-
;[items[0], items[1]] = [items[1], items[0]]
240
240
+
const [h1, h2] = el.children
241
241
+
t.assert.strictEqual(h1.tagName, 'H1')
242
242
+
t.assert.strictEqual(h2.tagName, 'H2')
243
243
+
;[items[0], items[1]] = [items[1], items[0]]
244
244
245
245
-
root.render(items)
246
246
-
expect(el.innerHTML).toBe('<h2>Item 2</h2><h1>Item 1</h1>')
247
247
-
expect(el.children[0].tagName).toBe('H2')
248
248
-
expect(el.children[1].tagName).toBe('H1')
245
245
+
root.render(items)
246
246
+
t.assert.strictEqual(el.innerHTML, '<h2>Item 2</h2><h1>Item 1</h1>')
247
247
+
t.assert.strictEqual(el.children[0].tagName, 'H2')
248
248
+
t.assert.strictEqual(el.children[1].tagName, 'H1')
249
249
250
250
-
expect(el.children[0]).toBe(h2)
251
251
-
expect(el.children[1]).toBe(h1)
252
252
-
})
250
250
+
t.assert.strictEqual(el.children[0], h2)
251
251
+
t.assert.strictEqual(el.children[1], h1)
252
252
+
})
253
253
254
254
-
it('implicit keyed resize', () => {
255
255
-
const { root, el } = setup()
254
254
+
test('implicit keyed lists with multiple elements preserve identity when resized', (t: TestContext) => {
255
255
+
const { root, el } = setup()
256
256
257
257
-
const items = [
258
258
-
html`<h1>Item 1</h1>`,
259
259
-
html`
260
260
-
<h2>Item 2</h2>
261
261
-
<p>Body content</p>
262
262
-
`,
263
263
-
]
257
257
+
const items = [
258
258
+
html`<h1>Item 1</h1>`,
259
259
+
html`
260
260
+
<h2>Item 2</h2>
261
261
+
<p>Body content</p>
262
262
+
`,
263
263
+
]
264
264
265
265
-
root.render(items)
266
266
-
expect(el.innerHTML.replace(/\s+/g, ' ')).toBe('<h1>Item 1</h1> <h2>Item 2</h2> <p>Body content</p> ')
265
265
+
root.render(items)
266
266
+
t.assert.strictEqual(el.innerHTML.replace(/\s+/g, ' '), '<h1>Item 1</h1> <h2>Item 2</h2> <p>Body content</p> ')
267
267
268
268
-
const [h1, h2, p] = el.children
269
269
-
expect(h1.tagName).toBe('H1')
270
270
-
expect(h2.tagName).toBe('H2')
271
271
-
expect(p.tagName).toBe('P')
268
268
+
const [h1, h2, p] = el.children
269
269
+
t.assert.strictEqual(h1.tagName, 'H1')
270
270
+
t.assert.strictEqual(h2.tagName, 'H2')
271
271
+
t.assert.strictEqual(p.tagName, 'P')
272
272
273
273
-
// Swap
274
274
-
;[items[0], items[1]] = [items[1], items[0]]
275
275
-
root.render(items)
276
276
-
expect(el.innerHTML.replace(/\s+/g, ' ')).toBe(' <h2>Item 2</h2> <p>Body content</p> <h1>Item 1</h1>')
277
277
-
expect(el.children[0].tagName).toBe('H2')
278
278
-
expect(el.children[1].tagName).toBe('P')
279
279
-
expect(el.children[2].tagName).toBe('H1')
273
273
+
// Swap
274
274
+
;[items[0], items[1]] = [items[1], items[0]]
275
275
+
root.render(items)
276
276
+
t.assert.strictEqual(el.innerHTML.replace(/\s+/g, ' '), ' <h2>Item 2</h2> <p>Body content</p> <h1>Item 1</h1>')
277
277
+
t.assert.strictEqual(el.children[0].tagName, 'H2')
278
278
+
t.assert.strictEqual(el.children[1].tagName, 'P')
279
279
+
t.assert.strictEqual(el.children[2].tagName, 'H1')
280
280
281
281
-
expect(el.children[0]).toBe(h2)
282
282
-
expect(el.children[1]).toBe(p)
283
283
-
expect(el.children[2]).toBe(h1)
281
281
+
t.assert.strictEqual(el.children[0], h2)
282
282
+
t.assert.strictEqual(el.children[1], p)
283
283
+
t.assert.strictEqual(el.children[2], h1)
284
284
285
285
-
// Swap back
286
286
-
;[items[0], items[1]] = [items[1], items[0]]
287
287
-
root.render(items)
288
288
-
expect(el.innerHTML.replace(/\s+/g, ' ')).toBe('<h1>Item 1</h1> <h2>Item 2</h2> <p>Body content</p> ')
289
289
-
expect(el.children[0].tagName).toBe('H1')
290
290
-
expect(el.children[1].tagName).toBe('H2')
291
291
-
expect(el.children[2].tagName).toBe('P')
292
292
-
expect(el.children[0]).toBe(h1)
293
293
-
expect(el.children[1]).toBe(h2)
294
294
-
expect(el.children[2]).toBe(p)
295
295
-
})
285
285
+
// Swap back
286
286
+
;[items[0], items[1]] = [items[1], items[0]]
287
287
+
root.render(items)
288
288
+
t.assert.strictEqual(el.innerHTML.replace(/\s+/g, ' '), '<h1>Item 1</h1> <h2>Item 2</h2> <p>Body content</p> ')
289
289
+
t.assert.strictEqual(el.children[0].tagName, 'H1')
290
290
+
t.assert.strictEqual(el.children[1].tagName, 'H2')
291
291
+
t.assert.strictEqual(el.children[2].tagName, 'P')
292
292
+
t.assert.strictEqual(el.children[0], h1)
293
293
+
t.assert.strictEqual(el.children[1], h2)
294
294
+
t.assert.strictEqual(el.children[2], p)
295
295
+
})
296
296
297
297
-
it('implicit keyed renderable', () => {
298
298
-
const { root, el } = setup()
297
297
+
test('implicit keyed renderable lists preserve identity when reordered', (t: TestContext) => {
298
298
+
const { root, el } = setup()
299
299
300
300
-
const items = [{ render: () => html`<h1>Item 1</h1>` }, { render: () => html`<h2>Item 2</h2>` }]
300
300
+
const items = [{ render: () => html`<h1>Item 1</h1>` }, { render: () => html`<h2>Item 2</h2>` }]
301
301
302
302
-
root.render(items)
303
303
-
expect(el.innerHTML).toBe('<h1>Item 1</h1><h2>Item 2</h2>')
302
302
+
root.render(items)
303
303
+
t.assert.strictEqual(el.innerHTML, '<h1>Item 1</h1><h2>Item 2</h2>')
304
304
305
305
-
const [h1, h2] = el.children
306
306
-
expect(h1.tagName).toBe('H1')
307
307
-
expect(h2.tagName).toBe('H2')
308
308
-
;[items[0], items[1]] = [items[1], items[0]]
305
305
+
const [h1, h2] = el.children
306
306
+
t.assert.strictEqual(h1.tagName, 'H1')
307
307
+
t.assert.strictEqual(h2.tagName, 'H2')
308
308
+
;[items[0], items[1]] = [items[1], items[0]]
309
309
310
310
-
root.render(items)
311
311
-
expect(el.innerHTML).toBe('<h2>Item 2</h2><h1>Item 1</h1>')
312
312
-
expect(el.children[0].tagName).toBe('H2')
313
313
-
expect(el.children[1].tagName).toBe('H1')
310
310
+
root.render(items)
311
311
+
t.assert.strictEqual(el.innerHTML, '<h2>Item 2</h2><h1>Item 1</h1>')
312
312
+
t.assert.strictEqual(el.children[0].tagName, 'H2')
313
313
+
t.assert.strictEqual(el.children[1].tagName, 'H1')
314
314
315
315
-
expect(el.children[0]).toBe(h2)
316
316
-
expect(el.children[1]).toBe(h1)
317
317
-
})
315
315
+
t.assert.strictEqual(el.children[0], h2)
316
316
+
t.assert.strictEqual(el.children[1], h1)
317
317
+
})
318
318
319
319
-
it('reorders many items', () => {
320
320
-
const { root, el } = setup()
319
319
+
test('many items can be reordered', (t: TestContext) => {
320
320
+
const { root, el } = setup()
321
321
322
322
-
const items = Array.from({ length: 10 }, (_, i) => [html`<p>Item ${i}</p>`, `<p>Item ${i}</p>`])
322
322
+
const items = Array.from({ length: 10 }, (_, i) => [html`<p>Item ${i}</p>`, `<p>Item ${i}</p>`])
323
323
324
324
-
root.render(items.map(([item]) => item))
325
325
-
expect(el.innerHTML).toBe(items.map(([, html]) => html).join(''))
324
324
+
root.render(items.map(([item]) => item))
325
325
+
t.assert.strictEqual(el.innerHTML, items.map(([, html]) => html).join(''))
326
326
327
327
-
shuffle(items)
328
328
-
// items.reverse()
327
327
+
shuffle(items)
329
328
330
330
-
root.render(items.map(([item]) => item))
331
331
-
expect(el.innerHTML).toBe(items.map(([, html]) => html).join(''))
332
332
-
})
329
329
+
root.render(items.map(([item]) => item))
330
330
+
t.assert.strictEqual(el.innerHTML, items.map(([, html]) => html).join(''))
333
331
})
334
332
335
335
-
describe('list with keys', { skip: import.meta.env.PROD }, () => {
336
336
-
it("can't key something twice", () => {
337
337
-
expect(() => keyed(html``, 1)).not.toThrow()
338
338
-
expect(() => keyed(keyed(html``, 1), 1)).toThrow()
339
339
-
})
333
333
+
test('keying something twice throws an error', { skip: process.env.NODE_ENV === 'production' }, (t: TestContext) => {
334
334
+
t.assert.doesNotThrow(() => keyed(html``, 1))
335
335
+
t.assert.throws(() => keyed(keyed(html``, 1), 1))
340
336
})
+25
-27
src/client/tests/recursion.test.ts
reviewed
···
1
1
import { html } from 'dhtml'
2
2
-
import { setup } from './setup'
3
3
-
import { describe, it } from 'vitest'
2
2
+
import test, { type TestContext } from 'node:test'
3
3
+
import { setup } from './setup.ts'
4
4
5
5
const DEPTH = 10
6
6
7
7
-
describe('recursion', () => {
8
8
-
it('handles basic recursion', ({ expect }) => {
9
9
-
const { root, el } = setup()
7
7
+
test('basic recursion is handled correctly', (t: TestContext) => {
8
8
+
const { root, el } = setup()
10
9
11
11
-
const app = {
12
12
-
renders: 0,
13
13
-
render() {
14
14
-
if (++this.renders > DEPTH) return 'hello!'
15
15
-
return this
16
16
-
},
17
17
-
}
18
18
-
root.render(app)
19
19
-
expect(el.innerHTML).toBe('hello!')
20
20
-
})
10
10
+
const app = {
11
11
+
renders: 0,
12
12
+
render() {
13
13
+
if (++this.renders > DEPTH) return 'hello!'
14
14
+
return this
15
15
+
},
16
16
+
}
17
17
+
root.render(app)
18
18
+
t.assert.strictEqual(el.innerHTML, 'hello!')
19
19
+
})
21
20
22
22
-
it('handles nested recursion', ({ expect }) => {
23
23
-
const { root, el } = setup()
21
21
+
test('nested recursion is handled correctly', (t: TestContext) => {
22
22
+
const { root, el } = setup()
24
23
25
25
-
const app = {
26
26
-
renders: 0,
27
27
-
render() {
28
28
-
if (++this.renders > DEPTH) return 'hello!'
29
29
-
return html`<span>${this}</span>`
30
30
-
},
31
31
-
}
32
32
-
root.render(app)
33
33
-
expect(el.innerHTML).toBe('<span>'.repeat(DEPTH) + 'hello!' + '</span>'.repeat(DEPTH))
34
34
-
})
24
24
+
const app = {
25
25
+
renders: 0,
26
26
+
render() {
27
27
+
if (++this.renders > DEPTH) return 'hello!'
28
28
+
return html`<span>${this}</span>`
29
29
+
},
30
30
+
}
31
31
+
root.render(app)
32
32
+
t.assert.strictEqual(el.innerHTML, '<span>'.repeat(DEPTH) + 'hello!' + '</span>'.repeat(DEPTH))
35
33
})
+332
-423
src/client/tests/renderable.test.ts
reviewed
···
1
1
import { html, type Renderable } from 'dhtml'
2
2
import { getParentNode, invalidate, onMount, onUnmount } from 'dhtml/client'
3
3
-
import { describe, expect, it, vi } from 'vitest'
4
4
-
import { setup } from './setup'
5
5
-
6
6
-
describe('renderables', () => {
7
7
-
it('works', async () => {
8
8
-
const { root, el } = setup()
3
3
+
import test, { type TestContext } from 'node:test'
4
4
+
import { setup } from './setup.ts'
9
5
10
10
-
root.render(
11
11
-
html`${{
12
12
-
render() {
13
13
-
return html`<h1>Hello, world!</h1>`
14
14
-
},
15
15
-
}}`,
16
16
-
)
17
17
-
expect(el.innerHTML).toBe('<h1>Hello, world!</h1>')
6
6
+
test('renderables work correctly', async (t: TestContext) => {
7
7
+
const { root, el } = setup()
18
8
19
19
-
const app = {
20
20
-
i: 0,
9
9
+
root.render(
10
10
+
html`${{
21
11
render() {
22
22
-
return html`Count: ${this.i++}`
12
12
+
return html`<h1>Hello, world!</h1>`
23
13
},
24
24
-
}
25
25
-
root.render(app)
26
26
-
expect(el.innerHTML).toBe('Count: 0')
27
27
-
root.render(app)
28
28
-
expect(el.innerHTML).toBe('Count: 1')
29
29
-
await invalidate(app)
30
30
-
expect(el.innerHTML).toBe('Count: 2')
31
31
-
await invalidate(app)
32
32
-
expect(el.innerHTML).toBe('Count: 3')
33
33
-
expect(app.i).toBe(4)
34
34
-
})
14
14
+
}}`,
15
15
+
)
16
16
+
t.assert.strictEqual(el.innerHTML, '<h1>Hello, world!</h1>')
35
17
36
36
-
it('handles undefined', () => {
37
37
-
const { root, el } = setup()
18
18
+
const app = {
19
19
+
i: 0,
20
20
+
render() {
21
21
+
return html`Count: ${this.i++}`
22
22
+
},
23
23
+
}
24
24
+
root.render(app)
25
25
+
t.assert.strictEqual(el.innerHTML, 'Count: 0')
26
26
+
root.render(app)
27
27
+
t.assert.strictEqual(el.innerHTML, 'Count: 1')
28
28
+
await invalidate(app)
29
29
+
t.assert.strictEqual(el.innerHTML, 'Count: 2')
30
30
+
await invalidate(app)
31
31
+
t.assert.strictEqual(el.innerHTML, 'Count: 3')
32
32
+
t.assert.strictEqual(app.i, 4)
33
33
+
})
38
34
39
39
-
root.render({
40
40
-
// @ts-expect-error
41
41
-
render() {},
42
42
-
})
35
35
+
test('renderables handle undefined correctly', (t: TestContext) => {
36
36
+
const { root, el } = setup()
43
37
44
44
-
expect(el.innerHTML).toBe('')
38
38
+
root.render({
39
39
+
// @ts-expect-error
40
40
+
render() {},
45
41
})
42
42
+
43
43
+
t.assert.strictEqual(el.innerHTML, '')
46
44
})
47
45
48
48
-
describe('onMount', () => {
49
49
-
it('calls in the right order', () => {
50
50
-
const { root, el } = setup()
46
46
+
test('onMount calls in the right order', (t: TestContext) => {
47
47
+
const { root, el } = setup()
51
48
52
52
-
const sequence: string[] = []
49
49
+
const sequence: string[] = []
53
50
54
54
-
const inner = {
55
55
-
attached: false,
56
56
-
render() {
57
57
-
sequence.push('inner render')
58
58
-
if (!this.attached) {
59
59
-
this.attached = true
60
60
-
onMount(this, () => {
61
61
-
sequence.push('inner mount')
62
62
-
return () => {
63
63
-
sequence.push('inner cleanup')
64
64
-
}
65
65
-
})
66
66
-
}
67
67
-
return 'inner'
68
68
-
},
69
69
-
}
51
51
+
const inner = {
52
52
+
attached: false,
53
53
+
render() {
54
54
+
sequence.push('inner render')
55
55
+
if (!this.attached) {
56
56
+
this.attached = true
57
57
+
onMount(this, () => {
58
58
+
sequence.push('inner mount')
59
59
+
return () => {
60
60
+
sequence.push('inner cleanup')
61
61
+
}
62
62
+
})
63
63
+
}
64
64
+
return 'inner'
65
65
+
},
66
66
+
}
70
67
71
71
-
const outer = {
72
72
-
attached: false,
73
73
-
show: true,
74
74
-
render() {
75
75
-
sequence.push('outer render')
76
76
-
if (!this.attached) {
77
77
-
this.attached = true
78
78
-
onMount(this, () => {
79
79
-
sequence.push('outer mount')
80
80
-
return () => {
81
81
-
sequence.push('outer cleanup')
82
82
-
}
83
83
-
})
84
84
-
}
85
85
-
if (!this.show) return null
86
86
-
return inner
87
87
-
},
88
88
-
}
68
68
+
const outer = {
69
69
+
attached: false,
70
70
+
show: true,
71
71
+
render() {
72
72
+
sequence.push('outer render')
73
73
+
if (!this.attached) {
74
74
+
this.attached = true
75
75
+
onMount(this, () => {
76
76
+
sequence.push('outer mount')
77
77
+
return () => {
78
78
+
sequence.push('outer cleanup')
79
79
+
}
80
80
+
})
81
81
+
}
82
82
+
if (!this.show) return null
83
83
+
return inner
84
84
+
},
85
85
+
}
89
86
90
90
-
outer.show = true
91
91
-
root.render(outer)
92
92
-
expect(el.innerHTML).toBe('inner')
93
93
-
expect(sequence).toMatchInlineSnapshot(`
94
94
-
[
95
95
-
"outer render",
96
96
-
"inner render",
97
97
-
"inner mount",
98
98
-
"outer mount",
99
99
-
]
100
100
-
`)
101
101
-
sequence.length = 0
87
87
+
outer.show = true
88
88
+
root.render(outer)
89
89
+
t.assert.strictEqual(el.innerHTML, 'inner')
90
90
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner render', 'inner mount', 'outer mount'])
91
91
+
sequence.length = 0
102
92
103
103
-
outer.show = false
104
104
-
root.render(outer)
105
105
-
expect(el.innerHTML).toBe('')
106
106
-
expect(sequence).toMatchInlineSnapshot(`
107
107
-
[
108
108
-
"outer render",
109
109
-
"inner cleanup",
110
110
-
]
111
111
-
`)
112
112
-
sequence.length = 0
93
93
+
outer.show = false
94
94
+
root.render(outer)
95
95
+
t.assert.strictEqual(el.innerHTML, '')
96
96
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner cleanup'])
97
97
+
sequence.length = 0
113
98
114
114
-
outer.show = true
115
115
-
root.render(outer)
116
116
-
expect(el.innerHTML).toBe('inner')
117
117
-
expect(sequence).toMatchInlineSnapshot(`
118
118
-
[
119
119
-
"outer render",
120
120
-
"inner render",
121
121
-
]
122
122
-
`)
123
123
-
sequence.length = 0
124
124
-
})
99
99
+
outer.show = true
100
100
+
root.render(outer)
101
101
+
t.assert.strictEqual(el.innerHTML, 'inner')
102
102
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner render'])
103
103
+
sequence.length = 0
104
104
+
})
125
105
126
126
-
it('registers multiple callbacks', () => {
127
127
-
const { root } = setup()
106
106
+
test('onMount registers multiple callbacks', (t: TestContext) => {
107
107
+
const { root } = setup()
128
108
129
129
-
const sequence: string[] = []
109
109
+
const sequence: string[] = []
130
110
131
131
-
const app = {
132
132
-
render() {
133
133
-
onMount(this, () => {
134
134
-
sequence.push('mount 1')
135
135
-
return () => sequence.push('cleanup 1')
136
136
-
})
111
111
+
const app = {
112
112
+
render() {
113
113
+
onMount(this, () => {
114
114
+
sequence.push('mount 1')
115
115
+
return () => sequence.push('cleanup 1')
116
116
+
})
137
117
138
138
-
onMount(this, () => {
139
139
-
sequence.push('mount 2')
140
140
-
return () => sequence.push('cleanup 2')
141
141
-
})
118
118
+
onMount(this, () => {
119
119
+
sequence.push('mount 2')
120
120
+
return () => sequence.push('cleanup 2')
121
121
+
})
142
122
143
143
-
return 'app'
144
144
-
},
145
145
-
}
123
123
+
return 'app'
124
124
+
},
125
125
+
}
146
126
147
147
-
root.render(app)
148
148
-
expect(sequence).toMatchInlineSnapshot(`
149
149
-
[
150
150
-
"mount 1",
151
151
-
"mount 2",
152
152
-
]
153
153
-
`)
154
154
-
sequence.length = 0
127
127
+
root.render(app)
128
128
+
t.assert.deepStrictEqual(sequence, ['mount 1', 'mount 2'])
129
129
+
sequence.length = 0
155
130
156
156
-
root.render(null)
157
157
-
expect(sequence).toMatchInlineSnapshot(`
158
158
-
[
159
159
-
"cleanup 1",
160
160
-
"cleanup 2",
161
161
-
]
162
162
-
`)
163
163
-
})
131
131
+
root.render(null)
132
132
+
t.assert.deepStrictEqual(sequence, ['cleanup 1', 'cleanup 2'])
133
133
+
})
164
134
165
165
-
it('registers a fixed callback once', () => {
166
166
-
const { root } = setup()
135
135
+
test('onMount registers a fixed callback once', (t: TestContext) => {
136
136
+
const { root } = setup()
167
137
168
168
-
const sequence: string[] = []
138
138
+
const sequence: string[] = []
169
139
170
170
-
function callback() {
171
171
-
sequence.push('mount')
172
172
-
return () => sequence.push('cleanup')
173
173
-
}
140
140
+
function callback() {
141
141
+
sequence.push('mount')
142
142
+
return () => sequence.push('cleanup')
143
143
+
}
174
144
175
175
-
const app = {
176
176
-
render() {
177
177
-
onMount(this, callback)
178
178
-
onMount(this, callback)
179
179
-
return 'app'
180
180
-
},
181
181
-
}
145
145
+
const app = {
146
146
+
render() {
147
147
+
onMount(this, callback)
148
148
+
onMount(this, callback)
149
149
+
return 'app'
150
150
+
},
151
151
+
}
182
152
183
183
-
root.render(app)
184
184
-
expect(sequence).toMatchInlineSnapshot(`
185
185
-
[
186
186
-
"mount",
187
187
-
]
188
188
-
`)
189
189
-
sequence.length = 0
153
153
+
root.render(app)
154
154
+
t.assert.deepStrictEqual(sequence, ['mount'])
155
155
+
sequence.length = 0
190
156
191
191
-
root.render(null)
192
192
-
expect(sequence).toMatchInlineSnapshot(`
193
193
-
[
194
194
-
"cleanup",
195
195
-
]
196
196
-
`)
197
197
-
})
157
157
+
root.render(null)
158
158
+
t.assert.deepStrictEqual(sequence, ['cleanup'])
159
159
+
})
198
160
199
199
-
it('registers callbacks outside of render', () => {
200
200
-
const { root } = setup()
161
161
+
test('onMount registers callbacks outside of render', (t: TestContext) => {
162
162
+
const { root } = setup()
201
163
202
202
-
const sequence: string[] = []
164
164
+
const sequence: string[] = []
203
165
204
204
-
const app = {
205
205
-
render() {
206
206
-
sequence.push('render')
207
207
-
return 'app'
208
208
-
},
209
209
-
}
166
166
+
const app = {
167
167
+
render() {
168
168
+
sequence.push('render')
169
169
+
return 'app'
170
170
+
},
171
171
+
}
210
172
211
211
-
onMount(app, () => {
212
212
-
sequence.push('mount')
213
213
-
return () => sequence.push('cleanup')
214
214
-
})
173
173
+
onMount(app, () => {
174
174
+
sequence.push('mount')
175
175
+
return () => sequence.push('cleanup')
176
176
+
})
215
177
216
216
-
expect(sequence).toMatchInlineSnapshot(`[]`)
178
178
+
t.assert.deepStrictEqual(sequence, [])
217
179
218
218
-
root.render(app)
219
219
-
expect(sequence).toMatchInlineSnapshot(`
220
220
-
[
221
221
-
"render",
222
222
-
"mount",
223
223
-
]
224
224
-
`)
225
225
-
sequence.length = 0
180
180
+
root.render(app)
181
181
+
t.assert.deepStrictEqual(sequence, ['render', 'mount'])
182
182
+
sequence.length = 0
226
183
227
227
-
root.render(null)
228
228
-
expect(sequence).toMatchInlineSnapshot(`
229
229
-
[
230
230
-
"cleanup",
231
231
-
]
232
232
-
`)
233
233
-
})
184
184
+
root.render(null)
185
185
+
t.assert.deepStrictEqual(sequence, ['cleanup'])
186
186
+
})
234
187
235
235
-
it('can access the dom in callback', () => {
236
236
-
const { root } = setup()
188
188
+
test('onMount can access the dom in callback', (t: TestContext) => {
189
189
+
const { root } = setup()
237
190
238
238
-
const app = {
239
239
-
render() {
240
240
-
onMount(this, () => {
241
241
-
const parent = getParentNode(this) as Element
242
242
-
expect(parent.firstElementChild).toBeInstanceOf(HTMLParagraphElement)
243
243
-
})
244
244
-
return html`<p>Hello, world!</p>`
245
245
-
},
246
246
-
}
191
191
+
const app = {
192
192
+
render() {
193
193
+
onMount(this, () => {
194
194
+
const parent = getParentNode(this) as Element
195
195
+
t.assert.ok(parent.firstElementChild instanceof HTMLParagraphElement)
196
196
+
})
197
197
+
return html`<p>Hello, world!</p>`
198
198
+
},
199
199
+
}
247
200
248
248
-
root.render(app)
249
249
-
})
201
201
+
root.render(app)
202
202
+
})
250
203
251
251
-
it('works after render', () => {
252
252
-
const { root } = setup()
204
204
+
test('onMount works after render', (t: TestContext) => {
205
205
+
const { root } = setup()
253
206
254
254
-
const app = {
255
255
-
render() {
256
256
-
return 'app'
257
257
-
},
258
258
-
}
207
207
+
const app = {
208
208
+
render() {
209
209
+
return 'app'
210
210
+
},
211
211
+
}
259
212
260
260
-
root.render(app)
213
213
+
root.render(app)
261
214
262
262
-
const mounted = vi.fn()
263
263
-
onMount(app, mounted)
264
264
-
expect(mounted).toHaveBeenCalledOnce()
265
265
-
})
215
215
+
const mounted = t.mock.fn()
216
216
+
onMount(app, mounted)
217
217
+
t.assert.strictEqual(mounted.mock.callCount(), 1)
266
218
})
267
219
268
268
-
describe('onUnmount', () => {
269
269
-
it('unmount deep', () => {
270
270
-
const { root, el } = setup()
220
220
+
test('onUnmount deep works correctly', (t: TestContext) => {
221
221
+
const { root, el } = setup()
271
222
272
272
-
const sequence: string[] = []
223
223
+
const sequence: string[] = []
273
224
274
274
-
const inner = {
275
275
-
attached: false,
276
276
-
render() {
277
277
-
sequence.push('inner render')
278
278
-
if (!this.attached) {
279
279
-
this.attached = true
280
280
-
onUnmount(this, () => {
281
281
-
this.attached = false
282
282
-
sequence.push('inner abort')
283
283
-
})
284
284
-
}
285
285
-
return 'inner'
286
286
-
},
287
287
-
}
225
225
+
const inner = {
226
226
+
attached: false,
227
227
+
render() {
228
228
+
sequence.push('inner render')
229
229
+
if (!this.attached) {
230
230
+
this.attached = true
231
231
+
onUnmount(this, () => {
232
232
+
this.attached = false
233
233
+
sequence.push('inner abort')
234
234
+
})
235
235
+
}
236
236
+
return 'inner'
237
237
+
},
238
238
+
}
288
239
289
289
-
const outer = {
290
290
-
attached: false,
291
291
-
show: true,
292
292
-
render() {
293
293
-
sequence.push('outer render')
294
294
-
if (!this.attached) {
295
295
-
this.attached = true
296
296
-
onUnmount(this, () => {
297
297
-
this.attached = false
298
298
-
sequence.push('outer abort')
299
299
-
})
300
300
-
}
301
301
-
if (!this.show) return null
302
302
-
return inner
303
303
-
},
304
304
-
}
240
240
+
const outer = {
241
241
+
attached: false,
242
242
+
show: true,
243
243
+
render() {
244
244
+
sequence.push('outer render')
245
245
+
if (!this.attached) {
246
246
+
this.attached = true
247
247
+
onUnmount(this, () => {
248
248
+
this.attached = false
249
249
+
sequence.push('outer abort')
250
250
+
})
251
251
+
}
252
252
+
if (!this.show) return null
253
253
+
return inner
254
254
+
},
255
255
+
}
305
256
306
306
-
outer.show = true
307
307
-
root.render(outer)
308
308
-
expect(el.innerHTML).toBe('inner')
309
309
-
expect(sequence).toMatchInlineSnapshot(`
310
310
-
[
311
311
-
"outer render",
312
312
-
"inner render",
313
313
-
]
314
314
-
`)
315
315
-
sequence.length = 0
257
257
+
outer.show = true
258
258
+
root.render(outer)
259
259
+
t.assert.strictEqual(el.innerHTML, 'inner')
260
260
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner render'])
261
261
+
sequence.length = 0
316
262
317
317
-
outer.show = false
318
318
-
root.render(outer)
319
319
-
expect(el.innerHTML).toBe('')
320
320
-
expect(sequence).toMatchInlineSnapshot(`
321
321
-
[
322
322
-
"outer render",
323
323
-
"inner abort",
324
324
-
]
325
325
-
`)
326
326
-
sequence.length = 0
263
263
+
outer.show = false
264
264
+
root.render(outer)
265
265
+
t.assert.strictEqual(el.innerHTML, '')
266
266
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner abort'])
267
267
+
sequence.length = 0
327
268
328
328
-
outer.show = true
329
329
-
root.render(outer)
330
330
-
expect(el.innerHTML).toBe('inner')
331
331
-
expect(sequence).toMatchInlineSnapshot(`
332
332
-
[
333
333
-
"outer render",
334
334
-
"inner render",
335
335
-
]
336
336
-
`)
337
337
-
sequence.length = 0
269
269
+
outer.show = true
270
270
+
root.render(outer)
271
271
+
t.assert.strictEqual(el.innerHTML, 'inner')
272
272
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner render'])
273
273
+
sequence.length = 0
338
274
339
339
-
outer.show = false
340
340
-
root.render(outer)
341
341
-
expect(el.innerHTML).toBe('')
342
342
-
expect(sequence).toMatchInlineSnapshot(`
343
343
-
[
344
344
-
"outer render",
345
345
-
"inner abort",
346
346
-
]
347
347
-
`)
348
348
-
sequence.length = 0
349
349
-
})
275
275
+
outer.show = false
276
276
+
root.render(outer)
277
277
+
t.assert.strictEqual(el.innerHTML, '')
278
278
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner abort'])
279
279
+
sequence.length = 0
280
280
+
})
350
281
351
351
-
it('unmount shallow', () => {
352
352
-
const { root, el } = setup()
282
282
+
test('onUnmount shallow works correctly', (t: TestContext) => {
283
283
+
const { root, el } = setup()
353
284
354
354
-
const sequence: string[] = []
285
285
+
const sequence: string[] = []
355
286
356
356
-
const inner = {
357
357
-
attached: false,
358
358
-
render() {
359
359
-
sequence.push('inner render')
360
360
-
if (!this.attached) {
361
361
-
this.attached = true
362
362
-
onUnmount(this, () => {
363
363
-
this.attached = false
364
364
-
sequence.push('inner abort')
365
365
-
})
366
366
-
}
367
367
-
return 'inner'
368
368
-
},
369
369
-
}
287
287
+
const inner = {
288
288
+
attached: false,
289
289
+
render() {
290
290
+
sequence.push('inner render')
291
291
+
if (!this.attached) {
292
292
+
this.attached = true
293
293
+
onUnmount(this, () => {
294
294
+
this.attached = false
295
295
+
sequence.push('inner abort')
296
296
+
})
297
297
+
}
298
298
+
return 'inner'
299
299
+
},
300
300
+
}
370
301
371
371
-
const outer = {
372
372
-
attached: false,
373
373
-
show: true,
374
374
-
render() {
375
375
-
sequence.push('outer render')
376
376
-
if (!this.attached) {
377
377
-
this.attached = true
378
378
-
onUnmount(this, () => {
379
379
-
this.attached = false
380
380
-
sequence.push('outer abort')
381
381
-
})
382
382
-
}
383
383
-
return html`${this.show ? inner : null}`
384
384
-
},
385
385
-
}
302
302
+
const outer = {
303
303
+
attached: false,
304
304
+
show: true,
305
305
+
render() {
306
306
+
sequence.push('outer render')
307
307
+
if (!this.attached) {
308
308
+
this.attached = true
309
309
+
onUnmount(this, () => {
310
310
+
this.attached = false
311
311
+
sequence.push('outer abort')
312
312
+
})
313
313
+
}
314
314
+
return html`${this.show ? inner : null}`
315
315
+
},
316
316
+
}
386
317
387
387
-
outer.show = true
388
388
-
root.render(outer)
389
389
-
expect(el.innerHTML).toBe('inner')
390
390
-
expect(sequence).toMatchInlineSnapshot(`
391
391
-
[
392
392
-
"outer render",
393
393
-
"inner render",
394
394
-
]
395
395
-
`)
396
396
-
sequence.length = 0
318
318
+
outer.show = true
319
319
+
root.render(outer)
320
320
+
t.assert.strictEqual(el.innerHTML, 'inner')
321
321
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner render'])
322
322
+
sequence.length = 0
397
323
398
398
-
outer.show = false
399
399
-
root.render(outer)
400
400
-
expect(el.innerHTML).toBe('')
401
401
-
expect(sequence).toMatchInlineSnapshot(`
402
402
-
[
403
403
-
"outer render",
404
404
-
"inner abort",
405
405
-
]
406
406
-
`)
407
407
-
sequence.length = 0
324
324
+
outer.show = false
325
325
+
root.render(outer)
326
326
+
t.assert.strictEqual(el.innerHTML, '')
327
327
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner abort'])
328
328
+
sequence.length = 0
408
329
409
409
-
outer.show = true
410
410
-
root.render(outer)
411
411
-
expect(el.innerHTML).toBe('inner')
412
412
-
expect(sequence).toMatchInlineSnapshot(`
413
413
-
[
414
414
-
"outer render",
415
415
-
"inner render",
416
416
-
]
417
417
-
`)
418
418
-
sequence.length = 0
330
330
+
outer.show = true
331
331
+
root.render(outer)
332
332
+
t.assert.strictEqual(el.innerHTML, 'inner')
333
333
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner render'])
334
334
+
sequence.length = 0
419
335
420
420
-
outer.show = false
421
421
-
root.render(outer)
422
422
-
expect(el.innerHTML).toBe('')
423
423
-
expect(sequence).toMatchInlineSnapshot(`
424
424
-
[
425
425
-
"outer render",
426
426
-
"inner abort",
427
427
-
]
428
428
-
`)
429
429
-
sequence.length = 0
430
430
-
})
336
336
+
outer.show = false
337
337
+
root.render(outer)
338
338
+
t.assert.strictEqual(el.innerHTML, '')
339
339
+
t.assert.deepStrictEqual(sequence, ['outer render', 'inner abort'])
340
340
+
sequence.length = 0
341
341
+
})
431
342
432
432
-
it('works externally', async () => {
433
433
-
const { root, el } = setup()
343
343
+
test('onUnmount works externally', async (t: TestContext) => {
344
344
+
const { root, el } = setup()
434
345
435
435
-
const app = {
436
436
-
render() {
437
437
-
return [1, 2, 3].map(i => html`<div>${i}</div>`)
438
438
-
},
439
439
-
}
346
346
+
const app = {
347
347
+
render() {
348
348
+
return [1, 2, 3].map(i => html`<div>${i}</div>`)
349
349
+
},
350
350
+
}
440
351
441
441
-
const unmounted = vi.fn()
442
442
-
onUnmount(app, unmounted)
352
352
+
const unmounted = t.mock.fn()
353
353
+
onUnmount(app, unmounted)
443
354
444
444
-
root.render(app)
445
445
-
expect(el.innerHTML).toMatchInlineSnapshot(`"<div>1</div><div>2</div><div>3</div>"`)
446
446
-
expect(unmounted).not.toHaveBeenCalled()
355
355
+
root.render(app)
356
356
+
t.assert.strictEqual(el.innerHTML, '<div>1</div><div>2</div><div>3</div>')
357
357
+
t.assert.strictEqual(unmounted.mock.callCount(), 0)
447
358
448
448
-
root.render(null)
449
449
-
expect(unmounted).toHaveBeenCalledOnce()
450
450
-
})
359
359
+
root.render(null)
360
360
+
t.assert.strictEqual(unmounted.mock.callCount(), 1)
451
361
})
452
362
453
453
-
describe('getParentNode', () => {
454
454
-
it('works externally', () => {
455
455
-
const { root, el } = setup()
363
363
+
test('getParentNode works externally', (t: TestContext) => {
364
364
+
const { root, el } = setup()
456
365
457
457
-
const app = {
458
458
-
render() {
459
459
-
return html`<div></div>`
460
460
-
},
461
461
-
}
366
366
+
const app = {
367
367
+
render() {
368
368
+
return html`<div></div>`
369
369
+
},
370
370
+
}
462
371
463
463
-
root.render(app)
464
464
-
expect(el.innerHTML).toBe('<div></div>')
465
465
-
expect(getParentNode(app)).toBe(el)
466
466
-
})
372
372
+
root.render(app)
373
373
+
t.assert.strictEqual(el.innerHTML, '<div></div>')
374
374
+
t.assert.strictEqual(getParentNode(app), el)
375
375
+
})
467
376
468
468
-
it('works internally', () => {
469
469
-
const { root, el } = setup()
470
470
-
471
471
-
root.render({
472
472
-
render() {
473
473
-
return html`<div>${getParentNode(this) === el}</div>`
474
474
-
},
475
475
-
} satisfies Renderable)
377
377
+
test('getParentNode works internally', (t: TestContext) => {
378
378
+
const { root, el } = setup()
476
379
477
477
-
expect(el.innerHTML).toBe('<div>true</div>')
478
478
-
})
380
380
+
root.render({
381
381
+
render() {
382
382
+
return html`<div>${getParentNode(this) === el}</div>`
383
383
+
},
384
384
+
} satisfies Renderable)
479
385
480
480
-
it('handles nesting', () => {
481
481
-
const { root, el } = setup()
386
386
+
t.assert.strictEqual(el.innerHTML, '<div>true</div>')
387
387
+
})
482
388
483
483
-
const inner = {
484
484
-
render() {
485
485
-
const parent = getParentNode(this)
389
389
+
test('getParentNode handles nesting', (t: TestContext) => {
390
390
+
const { root, el } = setup()
486
391
487
487
-
expect(parent).toBeInstanceOf(HTMLDivElement)
488
488
-
expect((parent as HTMLDivElement).outerHTML).toMatchInlineSnapshot(`"<div class="the-app"><!----></div>"`)
489
489
-
expect(parent.parentNode).toBe(el)
392
392
+
const inner = {
393
393
+
render() {
394
394
+
const parent = getParentNode(this)
490
395
491
491
-
return null
492
492
-
},
493
493
-
}
396
396
+
t.assert.ok(parent instanceof HTMLDivElement)
397
397
+
t.assert.strictEqual((parent as HTMLDivElement).outerHTML, '<div class="the-app"><!----></div>')
398
398
+
t.assert.strictEqual(parent.parentNode, el)
494
399
495
495
-
const spy = vi.spyOn(inner, 'render')
400
400
+
return null
401
401
+
},
402
402
+
}
496
403
497
497
-
root.render({
498
498
-
render() {
499
499
-
return html`<div class="the-app">${inner}</div>`
500
500
-
},
501
501
-
})
404
404
+
const spy = t.mock.fn(inner.render)
405
405
+
inner.render = spy
502
406
503
503
-
expect(spy).toHaveBeenCalledOnce()
407
407
+
root.render({
408
408
+
render() {
409
409
+
return html`<div class="the-app">${inner}</div>`
410
410
+
},
504
411
})
412
412
+
413
413
+
t.assert.strictEqual(spy.mock.callCount(), 1)
505
414
})
+6
-16
src/client/tests/setup.ts
reviewed
···
1
1
-
/// <reference types='vite/client' />
2
2
-
/// <reference types='@vitest/browser/providers/playwright' />
1
1
+
import { GlobalRegistrator } from '@happy-dom/global-registrator'
2
2
+
import { createRoot, type Root } from 'dhtml/client'
3
3
+
import { afterEach } from 'node:test'
3
4
4
4
-
import '../../../reset.css'
5
5
-
6
6
-
import { createRoot, type Root } from 'dhtml/client'
7
7
-
import { afterEach, expect } from 'vitest'
5
5
+
GlobalRegistrator.register()
6
6
+
globalThis.__DEV__ = process.env.NODE_ENV !== 'production'
8
7
9
8
const roots: Root[] = []
10
9
11
10
export function setup(initialHtml = ''): { root: Root; el: HTMLDivElement } {
12
12
-
const state = expect.getState()
13
13
-
const parentEl = document.createElement('div')
14
14
-
Object.assign(parentEl.style, {
15
15
-
border: '1px solid black',
16
16
-
padding: '0.5em',
17
17
-
margin: '0.5em',
18
18
-
})
19
19
-
parentEl.appendChild(document.createElement('small')).textContent = state.currentTestName ?? 'test'
20
20
-
21
11
const el = document.createElement('div')
22
12
el.innerHTML = initialHtml
23
23
-
document.body.appendChild(parentEl).appendChild(el)
13
13
+
document.body.appendChild(el)
24
14
25
15
const root = createRoot(el)
26
16
roots.push(root)
-2
src/client/util.ts
reviewed
···
1
1
-
import type { Renderable } from '../shared.ts'
2
2
-
3
1
export type Cleanup = (() => void) | void | undefined | null
4
2
5
3
export const is_element = (node: Node): node is Element => node.nodeType === (1 satisfies typeof Node.ELEMENT_NODE)
+1
-3
src/shared.ts
reviewed
···
14
14
typeof value === 'object' && value !== null && Symbol.iterator in value
15
15
16
16
declare global {
17
17
-
const __DEV__: boolean
17
17
+
var __DEV__: boolean
18
18
}
19
19
20
20
-
/* v8 ignore start */
21
20
export function assert(value: unknown, message?: string): asserts value {
22
21
if (!__DEV__) return
23
22
if (!value) throw new Error(message ?? 'assertion failed')
24
23
}
25
25
-
/* v8 ignore stop */
26
24
27
25
const tag: unique symbol = Symbol()
28
26
+2
-2
tsconfig.json
reviewed
···
4
4
"noImplicitAny": true,
5
5
"skipLibCheck": true,
6
6
"noEmit": true,
7
7
-
"module": "es2020",
7
7
+
"module": "nodenext",
8
8
"target": "es2020",
9
9
"verbatimModuleSyntax": true,
10
10
-
"moduleResolution": "bundler",
10
10
+
"moduleResolution": "nodenext",
11
11
"allowImportingTsExtensions": true,
12
12
"stripInternal": true,
13
13
"isolatedDeclarations": true,
-24
vitest.config.js
reviewed
···
1
1
-
import { defineConfig } from 'vitest/config'
2
2
-
3
3
-
export default defineConfig({
4
4
-
define: {
5
5
-
__DEV__: !process.env.PROD,
6
6
-
},
7
7
-
test: {
8
8
-
clearMocks: true,
9
9
-
coverage: {
10
10
-
enabled: true,
11
11
-
reporter: ['text', 'json-summary', 'json', 'html'],
12
12
-
reportOnFailure: true,
13
13
-
include: ['src/client/**', 'src/client.ts'],
14
14
-
exclude: ['**/tests'],
15
15
-
},
16
16
-
browser: {
17
17
-
enabled: true,
18
18
-
headless: true,
19
19
-
screenshotFailures: false,
20
20
-
provider: 'playwright',
21
21
-
instances: [{ browser: 'chromium' }],
22
22
-
},
23
23
-
},
24
24
-
})