zero-query 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +2 -0
- package/cli/args.js +33 -33
- package/cli/commands/build-api.js +443 -442
- package/cli/commands/build.js +254 -247
- package/cli/commands/bundle.js +1228 -1224
- package/cli/commands/create.js +137 -121
- package/cli/commands/dev/devtools/index.js +56 -56
- package/cli/commands/dev/devtools/js/components.js +49 -49
- package/cli/commands/dev/devtools/js/core.js +423 -423
- package/cli/commands/dev/devtools/js/elements.js +421 -421
- package/cli/commands/dev/devtools/js/network.js +166 -166
- package/cli/commands/dev/devtools/js/performance.js +73 -73
- package/cli/commands/dev/devtools/js/router.js +105 -105
- package/cli/commands/dev/devtools/js/source.js +132 -132
- package/cli/commands/dev/devtools/js/stats.js +35 -35
- package/cli/commands/dev/devtools/js/tabs.js +79 -79
- package/cli/commands/dev/devtools/panel.html +95 -95
- package/cli/commands/dev/devtools/styles.css +244 -244
- package/cli/commands/dev/index.js +107 -107
- package/cli/commands/dev/logger.js +75 -75
- package/cli/commands/dev/overlay.js +858 -858
- package/cli/commands/dev/server.js +220 -220
- package/cli/commands/dev/validator.js +94 -94
- package/cli/commands/dev/watcher.js +172 -172
- package/cli/help.js +114 -112
- package/cli/index.js +52 -52
- package/cli/scaffold/default/LICENSE +21 -21
- package/cli/scaffold/default/app/app.js +207 -207
- package/cli/scaffold/default/app/components/about.js +201 -201
- package/cli/scaffold/default/app/components/api-demo.js +143 -143
- package/cli/scaffold/default/app/components/contact-card.js +231 -231
- package/cli/scaffold/default/app/components/contacts/contacts.css +706 -706
- package/cli/scaffold/default/app/components/contacts/contacts.html +200 -200
- package/cli/scaffold/default/app/components/contacts/contacts.js +196 -196
- package/cli/scaffold/default/app/components/counter.js +127 -127
- package/cli/scaffold/default/app/components/home.js +249 -249
- package/cli/scaffold/default/app/components/not-found.js +16 -16
- package/cli/scaffold/default/app/components/playground/playground.css +115 -115
- package/cli/scaffold/default/app/components/playground/playground.html +161 -161
- package/cli/scaffold/default/app/components/playground/playground.js +116 -116
- package/cli/scaffold/default/app/components/todos.js +225 -225
- package/cli/scaffold/default/app/components/toolkit/toolkit.css +97 -97
- package/cli/scaffold/default/app/components/toolkit/toolkit.html +146 -146
- package/cli/scaffold/default/app/components/toolkit/toolkit.js +280 -280
- package/cli/scaffold/default/app/routes.js +15 -15
- package/cli/scaffold/default/app/store.js +101 -101
- package/cli/scaffold/default/global.css +552 -552
- package/cli/scaffold/default/index.html +99 -99
- package/cli/scaffold/minimal/app/app.js +85 -85
- package/cli/scaffold/minimal/app/components/about.js +68 -68
- package/cli/scaffold/minimal/app/components/counter.js +122 -122
- package/cli/scaffold/minimal/app/components/home.js +68 -68
- package/cli/scaffold/minimal/app/components/not-found.js +16 -16
- package/cli/scaffold/minimal/app/routes.js +9 -9
- package/cli/scaffold/minimal/app/store.js +36 -36
- package/cli/scaffold/minimal/global.css +300 -300
- package/cli/scaffold/minimal/index.html +44 -44
- package/cli/scaffold/ssr/app/app.js +41 -41
- package/cli/scaffold/ssr/app/components/about.js +55 -55
- package/cli/scaffold/ssr/app/components/blog/index.js +65 -65
- package/cli/scaffold/ssr/app/components/blog/post.js +86 -86
- package/cli/scaffold/ssr/app/components/home.js +37 -37
- package/cli/scaffold/ssr/app/components/not-found.js +15 -15
- package/cli/scaffold/ssr/app/routes.js +8 -8
- package/cli/scaffold/ssr/global.css +228 -228
- package/cli/scaffold/ssr/index.html +37 -37
- package/cli/scaffold/ssr/package.json +8 -8
- package/cli/scaffold/ssr/server/data/posts.js +144 -144
- package/cli/scaffold/ssr/server/index.js +213 -213
- package/cli/scaffold/webrtc/app/app.js +11 -0
- package/cli/scaffold/webrtc/app/components/video-room.js +295 -0
- package/cli/scaffold/webrtc/app/lib/room.js +252 -0
- package/cli/scaffold/webrtc/assets/.gitkeep +0 -0
- package/cli/scaffold/webrtc/global.css +250 -0
- package/cli/scaffold/webrtc/index.html +21 -0
- package/cli/utils.js +305 -287
- package/dist/API.md +661 -0
- package/dist/zquery.dist.zip +0 -0
- package/dist/zquery.js +10313 -6614
- package/dist/zquery.min.js +8 -631
- package/index.d.ts +570 -371
- package/index.js +311 -240
- package/package.json +76 -70
- package/src/component.js +1709 -1691
- package/src/core.js +921 -921
- package/src/diff.js +497 -497
- package/src/errors.js +209 -209
- package/src/expression.js +922 -922
- package/src/http.js +242 -242
- package/src/package.json +1 -1
- package/src/reactive.js +255 -255
- package/src/router.js +843 -843
- package/src/ssr.js +418 -418
- package/src/store.js +318 -318
- package/src/utils.js +515 -515
- package/src/webrtc/e2ee.js +351 -0
- package/src/webrtc/errors.js +116 -0
- package/src/webrtc/ice.js +301 -0
- package/src/webrtc/index.js +131 -0
- package/src/webrtc/joinToken.js +119 -0
- package/src/webrtc/observe.js +172 -0
- package/src/webrtc/peer.js +351 -0
- package/src/webrtc/reactive.js +268 -0
- package/src/webrtc/room.js +625 -0
- package/src/webrtc/sdp.js +302 -0
- package/src/webrtc/sfu/index.js +43 -0
- package/src/webrtc/sfu/livekit.js +131 -0
- package/src/webrtc/sfu/mediasoup.js +150 -0
- package/src/webrtc/signaling.js +373 -0
- package/src/webrtc/turn.js +237 -0
- package/tests/_helpers/webrtcFakes.js +289 -0
- package/tests/audit.test.js +4158 -4158
- package/tests/cli.test.js +1136 -1103
- package/tests/compare.test.js +497 -486
- package/tests/component.test.js +3969 -3938
- package/tests/core.test.js +1910 -1910
- package/tests/dev-server.test.js +489 -489
- package/tests/diff.test.js +1416 -1416
- package/tests/docs.test.js +1664 -1650
- package/tests/electron-features.test.js +864 -864
- package/tests/errors.test.js +619 -619
- package/tests/expression.test.js +1056 -1056
- package/tests/http.test.js +648 -648
- package/tests/reactive.test.js +819 -819
- package/tests/router.test.js +2327 -2327
- package/tests/ssr.test.js +870 -870
- package/tests/store.test.js +830 -830
- package/tests/test-minifier.js +153 -153
- package/tests/test-ssr.js +27 -27
- package/tests/utils.test.js +1377 -1377
- package/tests/webrtc/e2ee.test.js +283 -0
- package/tests/webrtc/ice.test.js +202 -0
- package/tests/webrtc/joinToken.test.js +89 -0
- package/tests/webrtc/observe.test.js +111 -0
- package/tests/webrtc/peer.test.js +373 -0
- package/tests/webrtc/reactive.test.js +235 -0
- package/tests/webrtc/room.test.js +406 -0
- package/tests/webrtc/sdp.test.js +151 -0
- package/tests/webrtc/sfu-livekit.test.js +119 -0
- package/tests/webrtc/sfu.test.js +160 -0
- package/tests/webrtc/signaling.test.js +251 -0
- package/tests/webrtc/turn.test.js +256 -0
- package/types/collection.d.ts +383 -383
- package/types/component.d.ts +186 -186
- package/types/errors.d.ts +135 -135
- package/types/http.d.ts +92 -92
- package/types/misc.d.ts +201 -201
- package/types/reactive.d.ts +98 -98
- package/types/router.d.ts +190 -190
- package/types/ssr.d.ts +102 -102
- package/types/store.d.ts +146 -146
- package/types/utils.d.ts +245 -245
- package/types/webrtc.d.ts +653 -0
|
@@ -1,442 +1,443 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* cli/commands/build-api.js - auto-generate API.md from docs section data
|
|
3
|
-
*
|
|
4
|
-
* Reads the structured docs sections (zquery-website/app/components/docs/sections),
|
|
5
|
-
* converts their HTML content to clean Markdown, and writes API.md.
|
|
6
|
-
*
|
|
7
|
-
* Usage: node cli/commands/build-api.js
|
|
8
|
-
* npm run build:api
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
'use strict';
|
|
12
|
-
|
|
13
|
-
const fs = require('fs');
|
|
14
|
-
const path = require('path');
|
|
15
|
-
const { pathToFileURL } = require('url');
|
|
16
|
-
|
|
17
|
-
// Sections to include in API.md and their order.
|
|
18
|
-
// Maps section ID → { file, export } for direct import (avoids pulling in
|
|
19
|
-
// getting-started.js which depends on the website store / globalThis.$).
|
|
20
|
-
const API_SECTIONS = [
|
|
21
|
-
{ id: 'router', file: 'router.js', exportName: 'routerSec' },
|
|
22
|
-
{ id: 'components', file: 'components.js', exportName: 'components' },
|
|
23
|
-
{ id: 'directives', file: 'directives.js', exportName: 'directives' },
|
|
24
|
-
{ id: 'store', file: 'store.js', exportName: 'storeSec' },
|
|
25
|
-
{ id: 'http', file: 'http.js', exportName: 'http' },
|
|
26
|
-
{ id: 'reactive', file: 'reactive.js', exportName: 'reactive' },
|
|
27
|
-
{ id: 'selectors', file: 'selectors.js', exportName: 'selectors' },
|
|
28
|
-
{ id: 'utils', file: 'utils.js', exportName: 'utils' },
|
|
29
|
-
{ id: 'error-handling', file: 'error-handling.js', exportName: 'errorHandling'},
|
|
30
|
-
{ id: 'ssr', file: 'ssr.js', exportName: 'ssr' },
|
|
31
|
-
{ id: 'security', file: 'security.js', exportName: 'security' },
|
|
32
|
-
{ id: 'environment', file: 'environment.js', exportName: 'environment' },
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
.replace(/&
|
|
44
|
-
.replace(/&
|
|
45
|
-
.replace(/&
|
|
46
|
-
.replace(
|
|
47
|
-
.replace(
|
|
48
|
-
.replace(/&
|
|
49
|
-
.replace(/&
|
|
50
|
-
.replace(/&
|
|
51
|
-
.replace(/&
|
|
52
|
-
.replace(/&
|
|
53
|
-
.replace(/&
|
|
54
|
-
.replace(/&
|
|
55
|
-
.replace(/&
|
|
56
|
-
.replace(/&
|
|
57
|
-
.replace(/&
|
|
58
|
-
.replace(/&
|
|
59
|
-
.replace(/&
|
|
60
|
-
.replace(/&
|
|
61
|
-
.replace(/&
|
|
62
|
-
.replace(/&
|
|
63
|
-
.replace(/&
|
|
64
|
-
.replace(/&
|
|
65
|
-
.replace(/&
|
|
66
|
-
.replace(/&
|
|
67
|
-
.replace(/&
|
|
68
|
-
.replace(/&
|
|
69
|
-
.replace(/&
|
|
70
|
-
.replace(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
*
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
md = md.replace(/<span class="docs-
|
|
89
|
-
md = md.replace(/<span class="docs-legend-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
cell =
|
|
154
|
-
cell = cell.replace(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
lines
|
|
171
|
-
lines.push('| ' + headers.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
md = md.replace(/<
|
|
224
|
-
md = md.replace(/<
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
let
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
md = md.
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
//
|
|
283
|
-
//
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
.
|
|
289
|
-
.replace(
|
|
290
|
-
.replace(
|
|
291
|
-
.replace(
|
|
292
|
-
.replace(
|
|
293
|
-
.replace(
|
|
294
|
-
.replace(
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
.
|
|
328
|
-
.
|
|
329
|
-
.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
'',
|
|
343
|
-
'
|
|
344
|
-
'',
|
|
345
|
-
'
|
|
346
|
-
'
|
|
347
|
-
'
|
|
348
|
-
|
|
349
|
-
'
|
|
350
|
-
'',
|
|
351
|
-
'
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
//
|
|
358
|
-
//
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
//
|
|
368
|
-
//
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
const
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
'',
|
|
389
|
-
'
|
|
390
|
-
'',
|
|
391
|
-
'
|
|
392
|
-
'',
|
|
393
|
-
'
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
parts.push(
|
|
411
|
-
parts.push(
|
|
412
|
-
parts.push('
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
parts.push(
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
output =
|
|
420
|
-
output = output.replace(/\n
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
console.log();
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
console.error(err.
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
|
|
1
|
+
/**
|
|
2
|
+
* cli/commands/build-api.js - auto-generate API.md from docs section data
|
|
3
|
+
*
|
|
4
|
+
* Reads the structured docs sections (zquery-website/app/components/docs/sections),
|
|
5
|
+
* converts their HTML content to clean Markdown, and writes API.md.
|
|
6
|
+
*
|
|
7
|
+
* Usage: node cli/commands/build-api.js
|
|
8
|
+
* npm run build:api
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { pathToFileURL } = require('url');
|
|
16
|
+
|
|
17
|
+
// Sections to include in API.md and their order.
|
|
18
|
+
// Maps section ID → { file, export } for direct import (avoids pulling in
|
|
19
|
+
// getting-started.js which depends on the website store / globalThis.$).
|
|
20
|
+
const API_SECTIONS = [
|
|
21
|
+
{ id: 'router', file: 'router.js', exportName: 'routerSec' },
|
|
22
|
+
{ id: 'components', file: 'components.js', exportName: 'components' },
|
|
23
|
+
{ id: 'directives', file: 'directives.js', exportName: 'directives' },
|
|
24
|
+
{ id: 'store', file: 'store.js', exportName: 'storeSec' },
|
|
25
|
+
{ id: 'http', file: 'http.js', exportName: 'http' },
|
|
26
|
+
{ id: 'reactive', file: 'reactive.js', exportName: 'reactive' },
|
|
27
|
+
{ id: 'selectors', file: 'selectors.js', exportName: 'selectors' },
|
|
28
|
+
{ id: 'utils', file: 'utils.js', exportName: 'utils' },
|
|
29
|
+
{ id: 'error-handling', file: 'error-handling.js', exportName: 'errorHandling'},
|
|
30
|
+
{ id: 'ssr', file: 'ssr.js', exportName: 'ssr' },
|
|
31
|
+
{ id: 'security', file: 'security.js', exportName: 'security' },
|
|
32
|
+
{ id: 'environment', file: 'environment.js', exportName: 'environment' },
|
|
33
|
+
{ id: 'webrtc', file: 'webrtc.js', exportName: 'webrtc' },
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// HTML entity decoding
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
function unesc(str) {
|
|
42
|
+
return str
|
|
43
|
+
.replace(/&/g, '&')
|
|
44
|
+
.replace(/</g, '<')
|
|
45
|
+
.replace(/>/g, '>')
|
|
46
|
+
.replace(/"/g, '"')
|
|
47
|
+
.replace(/'/g, "'")
|
|
48
|
+
.replace(/—/g, '\u2014')
|
|
49
|
+
.replace(/–/g, '\u2013')
|
|
50
|
+
.replace(/→/g, '\u2192')
|
|
51
|
+
.replace(/←/g, '\u2190')
|
|
52
|
+
.replace(/ /g, ' ')
|
|
53
|
+
.replace(/ /g, ' ')
|
|
54
|
+
.replace(/ /g, ' ')
|
|
55
|
+
.replace(/…/g, '\u2026')
|
|
56
|
+
.replace(/×/g, '\u00D7')
|
|
57
|
+
.replace(/©/g, '\u00A9')
|
|
58
|
+
.replace(/’/g, '\u2019')
|
|
59
|
+
.replace(/‘/g, '\u2018')
|
|
60
|
+
.replace(/”/g, '\u201D')
|
|
61
|
+
.replace(/“/g, '\u201C')
|
|
62
|
+
.replace(/•/g, '\u2022')
|
|
63
|
+
.replace(/·/g, '\u00B7')
|
|
64
|
+
.replace(/™/g, '\u2122')
|
|
65
|
+
.replace(/›/g, '\u203A')
|
|
66
|
+
.replace(/‹/g, '\u2039')
|
|
67
|
+
.replace(/↔/g, '\u2194')
|
|
68
|
+
.replace(/'/g, "'")
|
|
69
|
+
.replace(/ /g, '\u200A')
|
|
70
|
+
.replace(/ /g, '\u2009')
|
|
71
|
+
.replace(/&#(\d+);/g, (_, n) => String.fromCharCode(parseInt(n, 10)));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Inline HTML → Markdown
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Convert inline HTML elements to their Markdown equivalents.
|
|
81
|
+
* Handles: code, strong/b, em/i, a, br, spans (dots, badges, etc.)
|
|
82
|
+
*/
|
|
83
|
+
function inlineMd(html) {
|
|
84
|
+
if (!html) return '';
|
|
85
|
+
let md = html;
|
|
86
|
+
|
|
87
|
+
// Strip decorative dots (colored circles in table cells)
|
|
88
|
+
md = md.replace(/<span class="docs-dot"[^>]*><\/span>\s*/g, '');
|
|
89
|
+
md = md.replace(/<span class="docs-legend-dot"[^>]*><\/span>\s*/g, '');
|
|
90
|
+
md = md.replace(/<span class="docs-legend-item">[\s\S]*?<\/span>/g, '');
|
|
91
|
+
|
|
92
|
+
// ZQueryCollection SVG badge → backtick text
|
|
93
|
+
md = md.replace(/<span class="zq-badge">[\s\S]*?<\/span>/g, '`ZQueryCollection`');
|
|
94
|
+
|
|
95
|
+
// Status badges (colored pills) → plain text
|
|
96
|
+
md = md.replace(/<span\s+style="[^"]*background:[^"]*"[^>]*>([\s\S]*?)<\/span>/g, '$1');
|
|
97
|
+
|
|
98
|
+
// Convert <a> links (before code, since links can wrap code elements)
|
|
99
|
+
md = md.replace(/<a[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/g, '[$2]($1)');
|
|
100
|
+
|
|
101
|
+
// Convert <code> (both inline and zq-inline variants)
|
|
102
|
+
md = md.replace(/<code[^>]*>([\s\S]*?)<\/code>/g, (_, c) => '`' + unesc(c) + '`');
|
|
103
|
+
|
|
104
|
+
// Convert <strong>/<b>
|
|
105
|
+
md = md.replace(/<(?:strong|b)>([\s\S]*?)<\/(?:strong|b)>/g, '**$1**');
|
|
106
|
+
|
|
107
|
+
// Convert <em>/<i>
|
|
108
|
+
md = md.replace(/<(?:em|i)>([\s\S]*?)<\/(?:em|i)>/g, '*$1*');
|
|
109
|
+
|
|
110
|
+
// Convert <br>
|
|
111
|
+
md = md.replace(/<br\s*\/?>/g, '\n');
|
|
112
|
+
|
|
113
|
+
// Strip remaining <span> (keep content)
|
|
114
|
+
md = md.replace(/<span[^>]*>([\s\S]*?)<\/span>/g, '$1');
|
|
115
|
+
|
|
116
|
+
return md;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// HTML table → Markdown table
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
|
|
124
|
+
function convertTable(tableHtml) {
|
|
125
|
+
let html = tableHtml;
|
|
126
|
+
|
|
127
|
+
// Strip legend rows (decorative colored-dot rows)
|
|
128
|
+
html = html.replace(/<tr class="docs-table-legend-row">[\s\S]*?<\/tr>/g, '');
|
|
129
|
+
|
|
130
|
+
const headers = [];
|
|
131
|
+
const rows = [];
|
|
132
|
+
|
|
133
|
+
// --- Extract header cells from <thead> ---
|
|
134
|
+
const theadMatch = html.match(/<thead>([\s\S]*?)<\/thead>/);
|
|
135
|
+
if (theadMatch) {
|
|
136
|
+
const thRe = /<th[^>]*>([\s\S]*?)<\/th>/g;
|
|
137
|
+
let m;
|
|
138
|
+
while ((m = thRe.exec(theadMatch[1])) !== null) {
|
|
139
|
+
headers.push(unesc(inlineMd(m[1])).trim());
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// --- Extract body rows from <tbody> ---
|
|
144
|
+
const tbodyMatch = html.match(/<tbody>([\s\S]*?)<\/tbody>/);
|
|
145
|
+
if (tbodyMatch) {
|
|
146
|
+
const trRe = /<tr>([\s\S]*?)<\/tr>/g;
|
|
147
|
+
let m;
|
|
148
|
+
while ((m = trRe.exec(tbodyMatch[1])) !== null) {
|
|
149
|
+
const cells = [];
|
|
150
|
+
const tdRe = /<td>([\s\S]*?)<\/td>/g;
|
|
151
|
+
let td;
|
|
152
|
+
while ((td = tdRe.exec(m[1])) !== null) {
|
|
153
|
+
let cell = unesc(inlineMd(td[1])).trim();
|
|
154
|
+
cell = cell.replace(/\n+/g, ' '); // flatten to single line
|
|
155
|
+
cell = cell.replace(/\|/g, '\\|'); // escape pipe chars
|
|
156
|
+
cells.push(cell);
|
|
157
|
+
}
|
|
158
|
+
rows.push(cells);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!headers.length && !rows.length) return '';
|
|
163
|
+
|
|
164
|
+
const colCount = Math.max(headers.length, rows[0]?.length || 0);
|
|
165
|
+
|
|
166
|
+
// Pad short rows
|
|
167
|
+
while (headers.length < colCount) headers.push('');
|
|
168
|
+
rows.forEach(r => { while (r.length < colCount) r.push(''); });
|
|
169
|
+
|
|
170
|
+
const lines = [];
|
|
171
|
+
lines.push('| ' + headers.join(' | ') + ' |');
|
|
172
|
+
lines.push('| ' + headers.map(() => '---').join(' | ') + ' |');
|
|
173
|
+
rows.forEach(r => lines.push('| ' + r.join(' | ') + ' |'));
|
|
174
|
+
|
|
175
|
+
return '\n' + lines.join('\n') + '\n';
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Full section HTML → Markdown
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
function htmlToMarkdown(html) {
|
|
184
|
+
let md = html;
|
|
185
|
+
|
|
186
|
+
// ---- Pass 1: Extract code blocks → placeholders ----
|
|
187
|
+
// Matches: optional code-header div, then <pre z-skip><code class="language-xxx">...</code></pre>
|
|
188
|
+
const codeBlocks = [];
|
|
189
|
+
md = md.replace(
|
|
190
|
+
/(?:<div class="code-header">[\s\S]*?<\/div>\s*)?<pre[^>]*>\s*<code class="language-(\w+)">([\s\S]*?)<\/code>\s*<\/pre>/g,
|
|
191
|
+
(_, lang, src) => {
|
|
192
|
+
const idx = codeBlocks.length;
|
|
193
|
+
codeBlocks.push({ lang, src: unesc(src).trim() });
|
|
194
|
+
return `\n__CODEBLOCK_${idx}__\n`;
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
// ---- Pass 2: Convert tables ----
|
|
199
|
+
md = md.replace(
|
|
200
|
+
/<div class="docs-table-wrap">\s*<table[^>]*>([\s\S]*?)<\/table>\s*<\/div>/g,
|
|
201
|
+
(_, content) => convertTable(content)
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
// ---- Pass 3: Convert callouts, tips, warnings ----
|
|
205
|
+
md = md.replace(/<div class="docs-callout"[^>]*>([\s\S]*?)<\/div>/g, (_, c) => {
|
|
206
|
+
const text = unesc(inlineMd(c)).trim();
|
|
207
|
+
const lines = text.split('\n').map(l => '> ' + l);
|
|
208
|
+
return '\n' + lines.join('\n') + '\n';
|
|
209
|
+
});
|
|
210
|
+
md = md.replace(/<div class="docs-tip">([\s\S]*?)<\/div>/g, (_, c) => {
|
|
211
|
+
return '\n> **Tip:** ' + unesc(inlineMd(c)).trim() + '\n';
|
|
212
|
+
});
|
|
213
|
+
md = md.replace(/<div class="docs-warning">([\s\S]*?)<\/div>/g, (_, c) => {
|
|
214
|
+
return '\n> **Warning:** ' + unesc(inlineMd(c)).trim() + '\n';
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// ---- Pass 4: Strip legend bars & file trees ----
|
|
218
|
+
md = md.replace(/<div class="docs-legend-bar">[\s\S]*?<\/div>/g, '');
|
|
219
|
+
// File trees (only in non-API sections, but strip just in case)
|
|
220
|
+
md = md.replace(/<div class="file-tree">[\s\S]*?<\/div>(?:\s*<\/div>)*/g, '');
|
|
221
|
+
|
|
222
|
+
// ---- Pass 5: Convert headings ----
|
|
223
|
+
md = md.replace(/<h2[^>]*>([\s\S]*?)<\/h2>/g, (_, c) => '\n## ' + unesc(inlineMd(c)).trim() + '\n');
|
|
224
|
+
md = md.replace(/<h3[^>]*>([\s\S]*?)<\/h3>/g, (_, c) => '\n### ' + unesc(inlineMd(c)).trim() + '\n');
|
|
225
|
+
md = md.replace(/<h4[^>]*>([\s\S]*?)<\/h4>/g, (_, c) => '\n#### ' + unesc(inlineMd(c)).trim() + '\n');
|
|
226
|
+
|
|
227
|
+
// ---- Pass 6: Convert lists ----
|
|
228
|
+
md = md.replace(/<ul>([\s\S]*?)<\/ul>/g, (_, content) => {
|
|
229
|
+
let result = '\n';
|
|
230
|
+
const liRe = /<li>([\s\S]*?)<\/li>/g;
|
|
231
|
+
let li;
|
|
232
|
+
while ((li = liRe.exec(content)) !== null) {
|
|
233
|
+
result += '- ' + unesc(inlineMd(li[1])).trim() + '\n';
|
|
234
|
+
}
|
|
235
|
+
return result;
|
|
236
|
+
});
|
|
237
|
+
md = md.replace(/<ol>([\s\S]*?)<\/ol>/g, (_, content) => {
|
|
238
|
+
let result = '\n';
|
|
239
|
+
let i = 1;
|
|
240
|
+
const liRe = /<li>([\s\S]*?)<\/li>/g;
|
|
241
|
+
let li;
|
|
242
|
+
while ((li = liRe.exec(content)) !== null) {
|
|
243
|
+
result += `${i++}. ` + unesc(inlineMd(li[1])).trim() + '\n';
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// ---- Pass 7: Convert paragraphs ----
|
|
249
|
+
md = md.replace(/<p>([\s\S]*?)<\/p>/g, (_, c) => '\n' + unesc(inlineMd(c)).trim() + '\n');
|
|
250
|
+
|
|
251
|
+
// ---- Pass 8: Convert <hr> ----
|
|
252
|
+
md = md.replace(/<hr\s*\/?>/g, '\n---\n');
|
|
253
|
+
|
|
254
|
+
// ---- Pass 9: Remaining inline conversion ----
|
|
255
|
+
md = inlineMd(md);
|
|
256
|
+
|
|
257
|
+
// ---- Pass 10: Strip remaining HTML tags ----
|
|
258
|
+
md = md.replace(/<[^>]+>/g, '');
|
|
259
|
+
|
|
260
|
+
// ---- Pass 11: Decode remaining entities ----
|
|
261
|
+
md = unesc(md);
|
|
262
|
+
|
|
263
|
+
// ---- Pass 12: Clean up whitespace ----
|
|
264
|
+
md = md.replace(/\n{3,}/g, '\n\n');
|
|
265
|
+
md = md.trim();
|
|
266
|
+
|
|
267
|
+
// ---- Pass 13: Restore code blocks ----
|
|
268
|
+
codeBlocks.forEach((block, i) => {
|
|
269
|
+
md = md.replace(
|
|
270
|
+
`__CODEBLOCK_${i}__`,
|
|
271
|
+
'\n```' + block.lang + '\n' + block.src + '\n```\n'
|
|
272
|
+
);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Final whitespace cleanup
|
|
276
|
+
md = md.replace(/\n{3,}/g, '\n\n');
|
|
277
|
+
|
|
278
|
+
return md;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
// ---------------------------------------------------------------------------
|
|
283
|
+
// TOC builder
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
|
|
286
|
+
function slugify(text) {
|
|
287
|
+
return text
|
|
288
|
+
.toLowerCase()
|
|
289
|
+
.replace(/`/g, '')
|
|
290
|
+
.replace(/\$/g, '')
|
|
291
|
+
.replace(/\(\)/g, '')
|
|
292
|
+
.replace(/[^a-z0-9\s-]/g, '')
|
|
293
|
+
.replace(/\s+/g, '-')
|
|
294
|
+
.replace(/-+/g, '-')
|
|
295
|
+
.replace(/^-|-$/g, '');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function buildToc(sections) {
|
|
299
|
+
const lines = [];
|
|
300
|
+
for (const section of sections) {
|
|
301
|
+
// Get the section title from the first <h2> in content
|
|
302
|
+
const html = section.content();
|
|
303
|
+
const h2Match = html.match(/<h2[^>]*>([\s\S]*?)<\/h2>/);
|
|
304
|
+
const title = h2Match ? unesc(inlineMd(h2Match[1])).trim() : section.label;
|
|
305
|
+
lines.push(`- [${title}](#${slugify(title)})`);
|
|
306
|
+
for (const h of section.headings) {
|
|
307
|
+
const hText = unesc(h.text);
|
|
308
|
+
lines.push(` - [${hText}](#${slugify(hText)})`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return lines.join('\n');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
// ---------------------------------------------------------------------------
|
|
316
|
+
// ES Module Exports section (generated from index.js)
|
|
317
|
+
// ---------------------------------------------------------------------------
|
|
318
|
+
|
|
319
|
+
function buildEsmSection(root) {
|
|
320
|
+
const indexSrc = fs.readFileSync(path.join(root, 'index.js'), 'utf-8');
|
|
321
|
+
|
|
322
|
+
// Extract the export block
|
|
323
|
+
const exportMatch = indexSrc.match(/export\s*\{([\s\S]*?)\}/);
|
|
324
|
+
if (!exportMatch) return '';
|
|
325
|
+
|
|
326
|
+
const exports = exportMatch[1]
|
|
327
|
+
.split(',')
|
|
328
|
+
.map(e => e.trim())
|
|
329
|
+
.filter(Boolean)
|
|
330
|
+
.map(e => {
|
|
331
|
+
const parts = e.split(/\s+as\s+/);
|
|
332
|
+
return parts.length > 1
|
|
333
|
+
? { name: parts[1].trim(), alias: parts[0].trim() }
|
|
334
|
+
: { name: parts[0].trim() };
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
const importNames = exports.map(e => {
|
|
338
|
+
return e.alias ? `${e.alias} as ${e.name}` : e.name;
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
return [
|
|
342
|
+
'## ES Module Exports (for npm/bundler usage)',
|
|
343
|
+
'',
|
|
344
|
+
'When used as an ES module (not the built bundle), the library provides named exports for every public API:',
|
|
345
|
+
'',
|
|
346
|
+
'```js',
|
|
347
|
+
'import {',
|
|
348
|
+
' ' + importNames.join(',\n '),
|
|
349
|
+
"} from 'zero-query';",
|
|
350
|
+
'```',
|
|
351
|
+
'',
|
|
352
|
+
'> The SSR module has its own entry point: `import { createSSRApp, renderToString } from \'zero-query/ssr\';`',
|
|
353
|
+
].join('\n');
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
// ---------------------------------------------------------------------------
|
|
358
|
+
// Main
|
|
359
|
+
// ---------------------------------------------------------------------------
|
|
360
|
+
|
|
361
|
+
async function buildApi() {
|
|
362
|
+
const root = process.cwd();
|
|
363
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8'));
|
|
364
|
+
|
|
365
|
+
console.log('\n zQuery API.md Generator\n');
|
|
366
|
+
|
|
367
|
+
// Import sections individually (ESM dynamic import)
|
|
368
|
+
// We avoid importing sections/index.js because it pulls in getting-started.js
|
|
369
|
+
// which depends on the website store ($.libSize).
|
|
370
|
+
const sectionsDir = path.join(root, 'zquery-website', 'app', 'components', 'docs', 'sections');
|
|
371
|
+
|
|
372
|
+
const apiSections = [];
|
|
373
|
+
for (const entry of API_SECTIONS) {
|
|
374
|
+
const fileUrl = pathToFileURL(path.join(sectionsDir, entry.file)).href;
|
|
375
|
+
const mod = await import(fileUrl);
|
|
376
|
+
const section = mod[entry.exportName];
|
|
377
|
+
if (section) {
|
|
378
|
+
apiSections.push(section);
|
|
379
|
+
} else {
|
|
380
|
+
console.warn(` ⚠ Section "${entry.id}" not found in ${entry.file} (export: ${entry.exportName})`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
console.log(` Processing ${apiSections.length} sections...`);
|
|
385
|
+
|
|
386
|
+
// --- Header ---
|
|
387
|
+
const header = [
|
|
388
|
+
'# zQuery (zeroQuery) - Full API Reference',
|
|
389
|
+
'',
|
|
390
|
+
'Complete API documentation for every module, method, option, and type in zQuery. All examples assume the global `$` is available via the built `zquery.min.js` bundle. For getting started, project setup, the dev server, and the CLI bundler, see [README.md](README.md).',
|
|
391
|
+
'',
|
|
392
|
+
'> **Editor Support:** Install the [zQuery for VS Code](https://marketplace.visualstudio.com/items?itemName=zQuery.zquery-vs-code) extension for autocomplete, hover docs, directive support, and 185+ code snippets.',
|
|
393
|
+
'',
|
|
394
|
+
'---',
|
|
395
|
+
].join('\n');
|
|
396
|
+
|
|
397
|
+
// --- Table of Contents ---
|
|
398
|
+
const toc = buildToc(apiSections);
|
|
399
|
+
|
|
400
|
+
// --- Convert each section ---
|
|
401
|
+
const sectionMds = apiSections.map(s => htmlToMarkdown(s.content()));
|
|
402
|
+
|
|
403
|
+
// --- ES Module Exports ---
|
|
404
|
+
const esm = buildEsmSection(root);
|
|
405
|
+
|
|
406
|
+
// --- Assemble ---
|
|
407
|
+
const parts = [header, '', '## Table of Contents', '', toc, '', '---'];
|
|
408
|
+
|
|
409
|
+
for (const md of sectionMds) {
|
|
410
|
+
parts.push('');
|
|
411
|
+
parts.push(md);
|
|
412
|
+
parts.push('');
|
|
413
|
+
parts.push('---');
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
parts.push('');
|
|
417
|
+
parts.push(esm);
|
|
418
|
+
|
|
419
|
+
let output = parts.join('\n');
|
|
420
|
+
output = output.replace(/\n{4,}/g, '\n\n\n');
|
|
421
|
+
output = output.replace(/\n+$/, '\n');
|
|
422
|
+
|
|
423
|
+
// --- Write ---
|
|
424
|
+
const outPath = path.join(root, 'API.md');
|
|
425
|
+
fs.writeFileSync(outPath, output, 'utf-8');
|
|
426
|
+
|
|
427
|
+
const lines = output.split('\n').length;
|
|
428
|
+
const kb = Math.round(Buffer.from(output).byteLength / 1024);
|
|
429
|
+
console.log(` \u2713 API.md generated (${lines} lines, ${kb} KB)`);
|
|
430
|
+
console.log();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
// Allow both require() (from CLI) and direct execution
|
|
435
|
+
if (require.main === module) {
|
|
436
|
+
buildApi().catch(err => {
|
|
437
|
+
console.error(' \u2717 Failed to generate API.md:', err.message);
|
|
438
|
+
console.error(err.stack);
|
|
439
|
+
process.exit(1);
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
module.exports = buildApi;
|