@barqel/barq 1.0.0 → 1.0.1

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.
Files changed (42) hide show
  1. package/README.md +3 -3
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +4304 -10
  5. package/dist/index.js.map +24 -1
  6. package/dist/internal/node-compat.d.ts +2 -0
  7. package/dist/internal/node-compat.d.ts.map +1 -0
  8. package/dist/node-patch.d.ts +3 -0
  9. package/dist/node-patch.d.ts.map +1 -0
  10. package/dist/node-patch.js +4304 -0
  11. package/dist/node-patch.js.map +24 -0
  12. package/package.json +12 -3
  13. package/dist/app.js +0 -1370
  14. package/dist/app.js.map +0 -1
  15. package/dist/context.js +0 -261
  16. package/dist/context.js.map +0 -1
  17. package/dist/cookies.js +0 -234
  18. package/dist/cookies.js.map +0 -1
  19. package/dist/cors.js +0 -82
  20. package/dist/cors.js.map +0 -1
  21. package/dist/errors.js +0 -81
  22. package/dist/errors.js.map +0 -1
  23. package/dist/http.js +0 -127
  24. package/dist/http.js.map +0 -1
  25. package/dist/internal/ip.js +0 -151
  26. package/dist/internal/ip.js.map +0 -1
  27. package/dist/internal/pathname.js +0 -158
  28. package/dist/internal/pathname.js.map +0 -1
  29. package/dist/internal/query.js +0 -126
  30. package/dist/internal/query.js.map +0 -1
  31. package/dist/internal/scan.js +0 -1069
  32. package/dist/internal/scan.js.map +0 -1
  33. package/dist/internal/shutdown.js +0 -30
  34. package/dist/internal/shutdown.js.map +0 -1
  35. package/dist/internal/trie.js +0 -560
  36. package/dist/internal/trie.js.map +0 -1
  37. package/dist/middleware.js +0 -269
  38. package/dist/middleware.js.map +0 -1
  39. package/dist/types.js +0 -2
  40. package/dist/types.js.map +0 -1
  41. package/dist/validation.js +0 -32
  42. package/dist/validation.js.map +0 -1
@@ -1,1069 +0,0 @@
1
- /**
2
- * Token-based lexical scanner + semantic analyzer for handler functions.
3
- * Runs ONCE per route at registration time. Zero dependencies.
4
- */
5
- // biome-ignore lint/suspicious/noControlCharactersInRegex: JSON control chars must be escaped
6
- export const ESCAPE_JSON_CHARS_RE = /[\u0000-\u001f"\\]/;
7
- export function escapeJsonString(value) {
8
- if (!ESCAPE_JSON_CHARS_RE.test(value))
9
- return value;
10
- return JSON.stringify(value).slice(1, -1);
11
- }
12
- function isIdentStart(c) {
13
- return ((c >= 97 && c <= 122) ||
14
- (c >= 65 && c <= 90) ||
15
- c === 95 ||
16
- c === 36 ||
17
- c > 127);
18
- }
19
- function isIdentPart(c) {
20
- return isIdentStart(c) || (c >= 48 && c <= 57);
21
- }
22
- function isSpace(c) {
23
- return c === 32 || c === 9 || c === 10 || c === 13 || c === 12 || c === 11;
24
- }
25
- const KEYWORDS_BEFORE_REGEX = new Set([
26
- "return",
27
- "typeof",
28
- "instanceof",
29
- "in",
30
- "of",
31
- "new",
32
- "delete",
33
- "void",
34
- "throw",
35
- "case",
36
- "do",
37
- "else",
38
- "yield",
39
- "await",
40
- ]);
41
- const PUNCT_BEFORE_REGEX = new Set([
42
- "(",
43
- "[",
44
- "{",
45
- ",",
46
- ";",
47
- ":",
48
- "?",
49
- "!",
50
- "=",
51
- "==",
52
- "===",
53
- "!=",
54
- "!==",
55
- "&&",
56
- "||",
57
- "??",
58
- "+",
59
- "-",
60
- "*",
61
- "/",
62
- "%",
63
- "&",
64
- "|",
65
- "^",
66
- "~",
67
- "<",
68
- ">",
69
- "<=",
70
- ">=",
71
- "=>",
72
- "+=",
73
- "-=",
74
- "*=",
75
- "/=",
76
- "%=",
77
- "&=",
78
- "|=",
79
- "^=",
80
- "&&=",
81
- "||=",
82
- "??=",
83
- "<<",
84
- ">>",
85
- ">>>",
86
- "<<=",
87
- ">>=",
88
- ">>>=",
89
- ]);
90
- function tokenize(src) {
91
- const tokens = [];
92
- const len = src.length;
93
- let i = 0;
94
- let last = "";
95
- while (i < len) {
96
- const c = src.charCodeAt(i);
97
- if (isSpace(c)) {
98
- i++;
99
- continue;
100
- }
101
- if (c === 47 && src.charCodeAt(i + 1) === 47) {
102
- i += 2;
103
- while (i < len && src.charCodeAt(i) !== 10)
104
- i++;
105
- continue;
106
- }
107
- if (c === 47 && src.charCodeAt(i + 1) === 42) {
108
- i += 2;
109
- while (i < len &&
110
- !(src.charCodeAt(i) === 42 && src.charCodeAt(i + 1) === 47))
111
- i++;
112
- i += 2;
113
- continue;
114
- }
115
- if (c === 34 || c === 39) {
116
- const q = c;
117
- const start = i;
118
- i++;
119
- while (i < len) {
120
- const cc = src.charCodeAt(i);
121
- if (cc === 92) {
122
- i += 2;
123
- continue;
124
- }
125
- if (cc === q) {
126
- i++;
127
- break;
128
- }
129
- if (cc === 10)
130
- break;
131
- i++;
132
- }
133
- tokens.push({
134
- type: "str",
135
- value: src.slice(start + 1, i - 1),
136
- start,
137
- end: i,
138
- });
139
- last = "str";
140
- continue;
141
- }
142
- if (c === 96) {
143
- i = tokenizeTemplate(src, i, tokens);
144
- last = "template";
145
- continue;
146
- }
147
- if (c === 47) {
148
- let isRegex;
149
- if (last === "" || last === "regex" || last === "num")
150
- isRegex = true;
151
- else if (last === "str" || last === "template")
152
- isRegex = false;
153
- else if (last === "ident")
154
- isRegex = KEYWORDS_BEFORE_REGEX.has(last);
155
- else
156
- isRegex = PUNCT_BEFORE_REGEX.has(last);
157
- if (isRegex) {
158
- const start = i;
159
- i++;
160
- let inClass = false;
161
- while (i < len) {
162
- const cc = src.charCodeAt(i);
163
- if (cc === 92) {
164
- i += 2;
165
- continue;
166
- }
167
- if (cc === 91) {
168
- inClass = true;
169
- i++;
170
- continue;
171
- }
172
- if (cc === 93) {
173
- inClass = false;
174
- i++;
175
- continue;
176
- }
177
- if (cc === 47 && !inClass) {
178
- i++;
179
- break;
180
- }
181
- if (cc === 10)
182
- break;
183
- i++;
184
- }
185
- while (i < len && isIdentPart(src.charCodeAt(i)))
186
- i++;
187
- tokens.push({ type: "regex", value: "", start, end: i });
188
- last = "regex";
189
- continue;
190
- }
191
- tokens.push({ type: "punct", value: "/", start: i, end: i + 1 });
192
- last = "/";
193
- i++;
194
- continue;
195
- }
196
- if (isIdentStart(c)) {
197
- const start = i;
198
- i++;
199
- while (i < len && isIdentPart(src.charCodeAt(i)))
200
- i++;
201
- const value = src.slice(start, i);
202
- tokens.push({ type: "ident", value, start, end: i });
203
- last = value;
204
- continue;
205
- }
206
- if (c >= 48 && c <= 57) {
207
- const start = i;
208
- i++;
209
- while (i < len) {
210
- const cc = src.charCodeAt(i);
211
- if ((cc >= 48 && cc <= 57) ||
212
- cc === 46 ||
213
- cc === 95 ||
214
- (cc >= 97 && cc <= 122) ||
215
- (cc >= 65 && cc <= 90))
216
- i++;
217
- else if ((cc === 43 || cc === 45) &&
218
- (src.charCodeAt(i - 1) === 101 || src.charCodeAt(i - 1) === 69))
219
- i++;
220
- else
221
- break;
222
- }
223
- tokens.push({ type: "num", value: src.slice(start, i), start, end: i });
224
- last = "num";
225
- continue;
226
- }
227
- const start = i;
228
- const cc2 = src.charCodeAt(i + 1);
229
- const cc3 = src.charCodeAt(i + 2);
230
- const cc4 = src.charCodeAt(i + 3);
231
- let op = src[i];
232
- if (c === 62 && cc2 === 62 && cc3 === 62 && cc4 === 61)
233
- op = ">>>=";
234
- else if (c === 61 && cc2 === 61 && cc3 === 61)
235
- op = "===";
236
- else if (c === 33 && cc2 === 61 && cc3 === 61)
237
- op = "!==";
238
- else if (c === 42 && cc2 === 42 && cc3 === 61)
239
- op = "**=";
240
- else if (c === 60 && cc2 === 60 && cc3 === 61)
241
- op = "<<=";
242
- else if (c === 62 && cc2 === 62 && cc3 === 61)
243
- op = ">>=";
244
- else if (c === 62 && cc2 === 62 && cc3 === 62)
245
- op = ">>>";
246
- else if (c === 46 && cc2 === 46 && cc3 === 46)
247
- op = "...";
248
- else if (c === 63 && cc2 === 63 && cc3 === 61)
249
- op = "??=";
250
- else if (c === 38 && cc2 === 38 && cc3 === 61)
251
- op = "&&=";
252
- else if (c === 124 && cc2 === 124 && cc3 === 61)
253
- op = "||=";
254
- else if (c === 61 && cc2 === 62)
255
- op = "=>";
256
- else if (c === 61 && cc2 === 61)
257
- op = "==";
258
- else if (c === 33 && cc2 === 61)
259
- op = "!=";
260
- else if (c === 60 && cc2 === 61)
261
- op = "<=";
262
- else if (c === 62 && cc2 === 61)
263
- op = ">=";
264
- else if (c === 38 && cc2 === 38)
265
- op = "&&";
266
- else if (c === 124 && cc2 === 124)
267
- op = "||";
268
- else if (c === 63 && cc2 === 46)
269
- op = "?.";
270
- else if (c === 63 && cc2 === 63)
271
- op = "??";
272
- else if (c === 43 && cc2 === 43)
273
- op = "++";
274
- else if (c === 45 && cc2 === 45)
275
- op = "--";
276
- else if (c === 42 && cc2 === 42)
277
- op = "**";
278
- else if (c === 60 && cc2 === 60)
279
- op = "<<";
280
- else if (c === 62 && cc2 === 62)
281
- op = ">>";
282
- else if (c === 43 && cc2 === 61)
283
- op = "+=";
284
- else if (c === 45 && cc2 === 61)
285
- op = "-=";
286
- else if (c === 42 && cc2 === 61)
287
- op = "*=";
288
- else if (c === 47 && cc2 === 61)
289
- op = "/=";
290
- else if (c === 37 && cc2 === 61)
291
- op = "%=";
292
- else if (c === 38 && cc2 === 61)
293
- op = "&=";
294
- else if (c === 124 && cc2 === 61)
295
- op = "|=";
296
- else if (c === 94 && cc2 === 61)
297
- op = "^=";
298
- i += op.length;
299
- tokens.push({ type: "punct", value: op, start, end: i });
300
- last = op;
301
- }
302
- tokens.push({ type: "eof", value: "", start: len, end: len });
303
- return tokens;
304
- }
305
- function tokenizeTemplate(src, start, out) {
306
- let i = start + 1;
307
- const len = src.length;
308
- let strStart = i;
309
- while (i < len) {
310
- const c = src.charCodeAt(i);
311
- if (c === 92) {
312
- i += 2;
313
- continue;
314
- }
315
- if (c === 96) {
316
- if (i > strStart) {
317
- out.push({
318
- type: "str",
319
- value: src.slice(strStart, i),
320
- start: strStart,
321
- end: i,
322
- });
323
- }
324
- return i + 1;
325
- }
326
- if (c === 36 && src.charCodeAt(i + 1) === 123) {
327
- if (i > strStart) {
328
- out.push({
329
- type: "str",
330
- value: src.slice(strStart, i),
331
- start: strStart,
332
- end: i,
333
- });
334
- }
335
- out.push({ type: "punct", value: "${", start: i, end: i + 2 });
336
- i += 2;
337
- const exprStart = i;
338
- let depth = 1;
339
- while (i < len && depth > 0) {
340
- const cc = src.charCodeAt(i);
341
- if (cc === 92) {
342
- i += 2;
343
- continue;
344
- }
345
- if (cc === 34 || cc === 39) {
346
- const q = cc;
347
- i++;
348
- while (i < len) {
349
- const c2 = src.charCodeAt(i);
350
- if (c2 === 92) {
351
- i += 2;
352
- continue;
353
- }
354
- if (c2 === q) {
355
- i++;
356
- break;
357
- }
358
- i++;
359
- }
360
- continue;
361
- }
362
- if (cc === 96) {
363
- i = tokenizeTemplate(src, i, out);
364
- continue;
365
- }
366
- if (cc === 123) {
367
- depth++;
368
- i++;
369
- continue;
370
- }
371
- if (cc === 125) {
372
- depth--;
373
- if (depth === 0)
374
- break;
375
- i++;
376
- continue;
377
- }
378
- i++;
379
- }
380
- const inner = src.slice(exprStart, i);
381
- const innerTokens = tokenize(inner);
382
- for (const t of innerTokens) {
383
- if (t.type === "eof")
384
- continue;
385
- out.push({ ...t, start: t.start + exprStart, end: t.end + exprStart });
386
- }
387
- out.push({ type: "punct", value: "}", start: i, end: i + 1 });
388
- i++;
389
- strStart = i;
390
- continue;
391
- }
392
- i++;
393
- }
394
- if (i > strStart) {
395
- out.push({
396
- type: "str",
397
- value: src.slice(strStart, i),
398
- start: strStart,
399
- end: i,
400
- });
401
- }
402
- return i;
403
- }
404
- export function analyzeHandler(fn) {
405
- let src;
406
- try {
407
- src = fn.toString();
408
- }
409
- catch {
410
- return makeUnknown();
411
- }
412
- const tokens = tokenize(src);
413
- let i = 0;
414
- if (tokens[i]?.type === "ident" && tokens[i].value === "async")
415
- i++;
416
- if (tokens[i]?.type === "ident" && tokens[i].value === "function") {
417
- i++;
418
- if (tokens[i]?.type === "ident")
419
- i++;
420
- }
421
- if (tokens[i]?.type === "punct" && tokens[i].value === "(") {
422
- i++;
423
- const first = tokens[i];
424
- if (first?.type === "punct" && first.value === ")") {
425
- i++;
426
- const body = walkBody(tokens, i, null);
427
- return {
428
- isNoArg: true,
429
- contextProps: new Set(),
430
- hasDynamicAccess: false,
431
- isDestructured: false,
432
- destructuredProps: new Set(),
433
- literal: body.literal,
434
- arglessJsonCall: false,
435
- paramSerializer: null,
436
- paramParts: null,
437
- };
438
- }
439
- if (first?.type === "punct" && first.value === "{") {
440
- const { names, next } = parseDestructure(tokens, i);
441
- const body = walkBody(tokens, next, null);
442
- return {
443
- isNoArg: false,
444
- contextProps: new Set(),
445
- hasDynamicAccess: false,
446
- isDestructured: true,
447
- destructuredProps: names,
448
- literal: body.literal,
449
- arglessJsonCall: false,
450
- paramSerializer: body.paramSerializer,
451
- paramParts: body.paramParts,
452
- };
453
- }
454
- if (first?.type === "ident") {
455
- const name = first.value;
456
- i++;
457
- const body = walkBody(tokens, i, name);
458
- return {
459
- isNoArg: false,
460
- contextProps: body.props,
461
- hasDynamicAccess: body.hasDynamic,
462
- isDestructured: false,
463
- destructuredProps: new Set(),
464
- literal: body.literal,
465
- arglessJsonCall: body.arglessJsonCall,
466
- paramSerializer: body.paramSerializer,
467
- paramParts: body.paramParts,
468
- };
469
- }
470
- return makeUnknown();
471
- }
472
- if (tokens[i]?.type === "ident") {
473
- const name = tokens[i].value;
474
- i++;
475
- const body = walkBody(tokens, i, name);
476
- return {
477
- isNoArg: false,
478
- contextProps: body.props,
479
- hasDynamicAccess: body.hasDynamic,
480
- isDestructured: false,
481
- destructuredProps: new Set(),
482
- literal: body.literal,
483
- arglessJsonCall: body.arglessJsonCall,
484
- paramSerializer: body.paramSerializer,
485
- paramParts: body.paramParts,
486
- };
487
- }
488
- return makeUnknown();
489
- }
490
- function parseDestructure(tokens, braceStart) {
491
- const names = new Set();
492
- let i = braceStart + 1;
493
- let depth = 1;
494
- while (i < tokens.length) {
495
- const t = tokens[i];
496
- if (t.type === "eof")
497
- break;
498
- if (t.type === "punct") {
499
- if (t.value === "{")
500
- depth++;
501
- else if (t.value === "}") {
502
- depth--;
503
- i++;
504
- if (depth === 0)
505
- break;
506
- continue;
507
- }
508
- else if (t.value === "[")
509
- depth += 100;
510
- else if (t.value === "]")
511
- depth -= 100;
512
- }
513
- if (t.type === "ident" && depth === 1) {
514
- const prev = tokens[i - 1];
515
- const next = tokens[i + 1];
516
- if (prev?.type === "punct" && prev.value === ":") {
517
- names.add(t.value);
518
- }
519
- else if (next?.type !== "punct" || next.value !== ":") {
520
- names.add(t.value);
521
- }
522
- }
523
- i++;
524
- }
525
- while (i < tokens.length) {
526
- const t = tokens[i];
527
- if (t.type === "eof")
528
- break;
529
- if (t.type === "punct" && t.value === ")") {
530
- i++;
531
- break;
532
- }
533
- i++;
534
- }
535
- return { names, next: i };
536
- }
537
- function walkBody(tokens, from, paramName) {
538
- const props = new Set();
539
- let hasDynamic = false;
540
- let arglessJsonCall = false;
541
- let bodyStart = -1;
542
- let i = from;
543
- let parenDepth = 0;
544
- if (tokens[from]?.type === "punct" && tokens[from].value === "{") {
545
- bodyStart = from + 1;
546
- }
547
- else {
548
- while (i < tokens.length) {
549
- const t = tokens[i];
550
- if (t.type === "eof")
551
- break;
552
- if (t.type === "punct") {
553
- if (t.value === "(" || t.value === "[" || t.value === "{") {
554
- parenDepth++;
555
- }
556
- else if (t.value === ")" || t.value === "]" || t.value === "}") {
557
- if (parenDepth > 0)
558
- parenDepth--;
559
- }
560
- else if (t.value === "=>" && parenDepth === 0) {
561
- const next = tokens[i + 1];
562
- if (next?.type === "punct" && next.value === "{") {
563
- bodyStart = i + 2;
564
- }
565
- else {
566
- bodyStart = i + 1;
567
- }
568
- break;
569
- }
570
- if (t.value === ")" && parenDepth === 0 && i + 1 < tokens.length) {
571
- const next = tokens[i + 1];
572
- if (next?.type === "punct" && next.value === "{") {
573
- bodyStart = i + 2;
574
- break;
575
- }
576
- }
577
- }
578
- i++;
579
- }
580
- }
581
- if (bodyStart < 0) {
582
- return {
583
- props,
584
- hasDynamic,
585
- literal: null,
586
- arglessJsonCall: false,
587
- paramSerializer: null,
588
- paramParts: null,
589
- };
590
- }
591
- if (paramName !== null) {
592
- for (let j = bodyStart; j < tokens.length; j++) {
593
- const t = tokens[j];
594
- if (t.type === "eof")
595
- break;
596
- if (t.type !== "ident" || t.value !== paramName)
597
- continue;
598
- const n = tokens[j + 1];
599
- if (!n)
600
- continue;
601
- if (n.type === "punct" && (n.value === "." || n.value === "?.")) {
602
- const key = tokens[j + 2];
603
- if (key?.type === "ident") {
604
- props.add(key.value);
605
- if (key.value === "json") {
606
- const pOpen = tokens[j + 3];
607
- const pClose = tokens[j + 4];
608
- if (pOpen?.type === "punct" &&
609
- pOpen.value === "(" &&
610
- pClose?.type === "punct" &&
611
- pClose.value === ")") {
612
- const prev1 = tokens[j - 1];
613
- const prev2 = tokens[j - 2];
614
- const isPrecededByReturn = (prev1?.type === "punct" && prev1.value === "=>") ||
615
- (prev1?.type === "ident" && prev1.value === "return") ||
616
- (prev1?.type === "ident" &&
617
- prev1.value === "await" &&
618
- ((prev2?.type === "punct" && prev2.value === "=>") ||
619
- (prev2?.type === "ident" && prev2.value === "return")));
620
- const next1 = tokens[j + 5];
621
- const next2 = tokens[j + 6];
622
- const isEndOfBody = isBodyEnd(next1) && (next1?.value !== ";" || isBodyEnd(next2));
623
- if (isPrecededByReturn && isEndOfBody) {
624
- arglessJsonCall = true;
625
- }
626
- }
627
- }
628
- j += 2;
629
- continue;
630
- }
631
- hasDynamic = true;
632
- continue;
633
- }
634
- if (n.type === "punct" && n.value === "[") {
635
- const key = tokens[j + 2];
636
- const close = tokens[j + 3];
637
- if (key?.type === "str" &&
638
- close?.type === "punct" &&
639
- close.value === "]") {
640
- props.add(key.value);
641
- j += 3;
642
- continue;
643
- }
644
- hasDynamic = true;
645
- continue;
646
- }
647
- const prev = tokens[j - 1];
648
- if (prev?.type === "punct" && prev.value === "...") {
649
- hasDynamic = true;
650
- }
651
- }
652
- }
653
- const literal = tryExtractLiteral(tokens, bodyStart);
654
- const paramExtraction = literal === null
655
- ? tryExtractParamSerializer(tokens, bodyStart, paramName)
656
- : null;
657
- const paramSerializer = paramExtraction?.serializer ?? null;
658
- const paramParts = paramExtraction?.parts ?? null;
659
- return {
660
- props,
661
- hasDynamic,
662
- literal,
663
- arglessJsonCall,
664
- paramSerializer,
665
- paramParts,
666
- };
667
- }
668
- function isBodyEnd(t) {
669
- if (!t)
670
- return true;
671
- if (t.type === "eof")
672
- return true;
673
- if (t.type === "punct" && (t.value === ";" || t.value === "}"))
674
- return true;
675
- return false;
676
- }
677
- function tryExtractLiteral(tokens, bodyStart) {
678
- const t = tokens[bodyStart];
679
- if (!t || t.type === "eof")
680
- return null;
681
- if (t.type === "ident" && t.value === "return") {
682
- return tryExtractLiteral(tokens, bodyStart + 1);
683
- }
684
- if (t.type === "str") {
685
- if (isBodyEnd(tokens[bodyStart + 1])) {
686
- return { kind: "string", value: t.value };
687
- }
688
- return null;
689
- }
690
- if (t.type === "punct" && t.value === "(") {
691
- const inner = tokens[bodyStart + 1];
692
- if (inner?.type === "punct" && inner.value === "{") {
693
- const obj = extractFlatObject(tokens, bodyStart + 1);
694
- if (!obj.ok)
695
- return null;
696
- const afterBrace = tokens[obj.end];
697
- if (afterBrace?.type !== "punct" || afterBrace.value !== ")")
698
- return null;
699
- if (!isBodyEnd(tokens[obj.end + 1]))
700
- return null;
701
- return { kind: "json", value: JSON.stringify(obj.value) };
702
- }
703
- return null;
704
- }
705
- if (t.type === "punct" && t.value === "{") {
706
- const next = tokens[bodyStart + 1];
707
- if (next &&
708
- (next.type === "ident" || next.type === "str" || next.type === "num") &&
709
- tokens[bodyStart + 2]?.type === "punct" &&
710
- tokens[bodyStart + 2].value === ":") {
711
- const obj = extractFlatObject(tokens, bodyStart);
712
- if (obj.ok) {
713
- if (isBodyEnd(tokens[obj.end])) {
714
- return { kind: "json", value: JSON.stringify(obj.value) };
715
- }
716
- return null;
717
- }
718
- return null;
719
- }
720
- let j = bodyStart + 1;
721
- while (j < tokens.length) {
722
- const tt = tokens[j];
723
- if (tt.type === "eof")
724
- return null;
725
- if (tt.type === "punct" && tt.value === "}")
726
- return null;
727
- if (tt.type === "ident" && tt.value === "return") {
728
- return tryExtractLiteral(tokens, j + 1);
729
- }
730
- if (tt.type === "punct" && tt.value === ";")
731
- return null;
732
- if (tt.type === "ident" && tt.value !== "return")
733
- return null;
734
- j++;
735
- }
736
- return null;
737
- }
738
- return null;
739
- }
740
- function extractFlatObject(tokens, braceStart) {
741
- let i = braceStart + 1;
742
- const obj = {};
743
- let expectKey = true;
744
- let key = null;
745
- while (i < tokens.length) {
746
- const t = tokens[i];
747
- if (t.type === "eof")
748
- return { ok: false };
749
- if (t.type === "punct" && t.value === "}") {
750
- if (!expectKey)
751
- return { ok: false };
752
- return { ok: true, end: i + 1, value: obj };
753
- }
754
- if (expectKey) {
755
- if (t.type === "ident" || t.type === "str" || t.type === "num")
756
- key = t.value;
757
- else
758
- return { ok: false };
759
- i++;
760
- const colon = tokens[i];
761
- if (colon?.type !== "punct" || colon.value !== ":")
762
- return { ok: false };
763
- i++;
764
- expectKey = false;
765
- continue;
766
- }
767
- if (t.type === "str") {
768
- obj[key] = t.value;
769
- i++;
770
- }
771
- else if (t.type === "num") {
772
- obj[key] = Number(t.value);
773
- i++;
774
- }
775
- else if (t.type === "ident") {
776
- if (t.value === "true")
777
- obj[key] = true;
778
- else if (t.value === "false")
779
- obj[key] = false;
780
- else if (t.value === "null")
781
- obj[key] = null;
782
- else
783
- return { ok: false };
784
- i++;
785
- }
786
- else if (t.type === "punct" &&
787
- t.value === "!" &&
788
- tokens[i + 1]?.type === "num") {
789
- const n = tokens[i + 1].value;
790
- obj[key] = n === "1";
791
- i += 2;
792
- }
793
- else if (t.type === "punct" &&
794
- t.value === "-" &&
795
- tokens[i + 1]?.type === "num") {
796
- obj[key] = -Number(tokens[i + 1].value);
797
- i += 2;
798
- }
799
- else {
800
- return { ok: false };
801
- }
802
- const sep = tokens[i];
803
- if (sep?.type === "punct" && sep.value === ",") {
804
- i++;
805
- expectKey = true;
806
- continue;
807
- }
808
- if (sep?.type === "punct" && sep.value === "}") {
809
- return { ok: true, end: i + 1, value: obj };
810
- }
811
- return { ok: false };
812
- }
813
- return { ok: false };
814
- }
815
- function extractParamObject(tokens, braceStart, paramName) {
816
- let i = braceStart + 1;
817
- const parts = [];
818
- let expectKey = true;
819
- let key = null;
820
- let hasParam = false;
821
- while (i < tokens.length) {
822
- const t = tokens[i];
823
- if (t.type === "eof")
824
- return { ok: false };
825
- if (t.type === "punct" && t.value === "}") {
826
- if (!expectKey)
827
- return { ok: false };
828
- return hasParam ? { ok: true, end: i + 1, parts } : { ok: false };
829
- }
830
- if (expectKey) {
831
- if (t.type === "ident" || t.type === "str" || t.type === "num") {
832
- key = t.value;
833
- }
834
- else {
835
- return { ok: false };
836
- }
837
- i++;
838
- const colon = tokens[i];
839
- if (colon?.type !== "punct" || colon.value !== ":")
840
- return { ok: false };
841
- i++;
842
- expectKey = false;
843
- continue;
844
- }
845
- if (paramName !== null && t.type === "ident" && t.value === paramName) {
846
- const dot1 = tokens[i + 1];
847
- const pIdent = tokens[i + 2];
848
- const dot2 = tokens[i + 3];
849
- const pKey = tokens[i + 4];
850
- if (dot1?.type === "punct" &&
851
- (dot1.value === "." || dot1.value === "?.") &&
852
- pIdent?.type === "ident" &&
853
- pIdent.value === "params" &&
854
- dot2?.type === "punct" &&
855
- (dot2.value === "." || dot2.value === "?.") &&
856
- pKey?.type === "ident") {
857
- hasParam = true;
858
- parts.push({ key: key, isParam: true, paramKey: pKey.value });
859
- i += 5;
860
- const sep = tokens[i];
861
- if (sep?.type === "punct" && sep.value === ",") {
862
- i++;
863
- expectKey = true;
864
- continue;
865
- }
866
- if (sep?.type === "punct" && sep.value === "}") {
867
- return { ok: true, end: i + 1, parts };
868
- }
869
- return { ok: false };
870
- }
871
- }
872
- if (t.type === "ident" && t.value === "params") {
873
- const dot = tokens[i + 1];
874
- const pKey = tokens[i + 2];
875
- if (dot?.type === "punct" &&
876
- (dot.value === "." || dot.value === "?.") &&
877
- pKey?.type === "ident") {
878
- hasParam = true;
879
- parts.push({ key: key, isParam: true, paramKey: pKey.value });
880
- i += 3;
881
- const sep = tokens[i];
882
- if (sep?.type === "punct" && sep.value === ",") {
883
- i++;
884
- expectKey = true;
885
- continue;
886
- }
887
- if (sep?.type === "punct" && sep.value === "}") {
888
- return { ok: true, end: i + 1, parts };
889
- }
890
- return { ok: false };
891
- }
892
- }
893
- if (t.type === "str") {
894
- parts.push({
895
- key: key,
896
- isParam: false,
897
- literalValue: JSON.stringify(t.value),
898
- });
899
- i++;
900
- }
901
- else if (t.type === "num") {
902
- parts.push({
903
- key: key,
904
- isParam: false,
905
- literalValue: t.value,
906
- });
907
- i++;
908
- }
909
- else if (t.type === "ident") {
910
- if (t.value === "true" || t.value === "false" || t.value === "null") {
911
- parts.push({
912
- key: key,
913
- isParam: false,
914
- literalValue: t.value,
915
- });
916
- i++;
917
- }
918
- else {
919
- return { ok: false };
920
- }
921
- }
922
- else if (t.type === "punct" &&
923
- t.value === "!" &&
924
- tokens[i + 1]?.type === "num") {
925
- parts.push({
926
- key: key,
927
- isParam: false,
928
- literalValue: tokens[i + 1].value === "1" ? "true" : "false",
929
- });
930
- i += 2;
931
- }
932
- else if (t.type === "punct" &&
933
- t.value === "-" &&
934
- tokens[i + 1]?.type === "num") {
935
- parts.push({
936
- key: key,
937
- isParam: false,
938
- literalValue: `-${tokens[i + 1].value}`,
939
- });
940
- i += 2;
941
- }
942
- else {
943
- return { ok: false };
944
- }
945
- const sep = tokens[i];
946
- if (sep?.type === "punct" && sep.value === ",") {
947
- i++;
948
- expectKey = true;
949
- continue;
950
- }
951
- if (sep?.type === "punct" && sep.value === "}") {
952
- return hasParam ? { ok: true, end: i + 1, parts } : { ok: false };
953
- }
954
- return { ok: false };
955
- }
956
- return { ok: false };
957
- }
958
- function buildParamSerializer(parts) {
959
- const chunks = [];
960
- const keys = [];
961
- let current = "{";
962
- for (let i = 0; i < parts.length; i++) {
963
- const part = parts[i];
964
- if (i > 0)
965
- current += ",";
966
- current += `${JSON.stringify(part.key)}:`;
967
- if (part.isParam) {
968
- current += '"';
969
- chunks.push(current);
970
- keys.push(part.paramKey);
971
- current = '"';
972
- }
973
- else {
974
- current += part.literalValue;
975
- }
976
- }
977
- current += "}";
978
- chunks.push(current);
979
- if (keys.length === 1) {
980
- const c0 = chunks[0];
981
- const c1 = chunks[1];
982
- const k0 = keys[0];
983
- return (p) => c0 + escapeJsonString(typeof p === "string" ? p : (p[k0] ?? "")) + c1;
984
- }
985
- if (keys.length === 2) {
986
- const c0 = chunks[0];
987
- const c1 = chunks[1];
988
- const c2 = chunks[2];
989
- const k0 = keys[0];
990
- const k1 = keys[1];
991
- return (p) => `${c0}${escapeJsonString(typeof p === "string" ? p : (p[k0] ?? ""))}${c1}${typeof p === "string" ? "" : escapeJsonString(p[k1] ?? "")}${c2}`;
992
- }
993
- return (p) => {
994
- let out = chunks[0];
995
- for (let j = 0; j < keys.length; j++) {
996
- out +=
997
- escapeJsonString(typeof p === "string" ? (j === 0 ? p : "") : (p[keys[j]] ?? "")) + chunks[j + 1];
998
- }
999
- return out;
1000
- };
1001
- }
1002
- function tryExtractParamSerializer(tokens, bodyStart, paramName) {
1003
- const t = tokens[bodyStart];
1004
- if (!t || t.type === "eof")
1005
- return null;
1006
- if (t.type === "punct" && t.value === "(") {
1007
- const inner = tokens[bodyStart + 1];
1008
- if (inner?.type === "punct" && inner.value === "{") {
1009
- const res = extractParamObject(tokens, bodyStart + 1, paramName);
1010
- if (!res.ok)
1011
- return null;
1012
- const afterBrace = tokens[res.end];
1013
- if (afterBrace?.type !== "punct" || afterBrace.value !== ")")
1014
- return null;
1015
- if (!isBodyEnd(tokens[res.end + 1]))
1016
- return null;
1017
- return { serializer: buildParamSerializer(res.parts), parts: res.parts };
1018
- }
1019
- return null;
1020
- }
1021
- if (t.type === "punct" && t.value === "{") {
1022
- const next = tokens[bodyStart + 1];
1023
- if (next &&
1024
- (next.type === "ident" || next.type === "str" || next.type === "num") &&
1025
- tokens[bodyStart + 2]?.type === "punct" &&
1026
- tokens[bodyStart + 2].value === ":") {
1027
- const res = extractParamObject(tokens, bodyStart, paramName);
1028
- if (res.ok && isBodyEnd(tokens[res.end])) {
1029
- return {
1030
- serializer: buildParamSerializer(res.parts),
1031
- parts: res.parts,
1032
- };
1033
- }
1034
- return null;
1035
- }
1036
- let j = bodyStart + 1;
1037
- while (j < tokens.length) {
1038
- const tt = tokens[j];
1039
- if (tt.type === "eof")
1040
- return null;
1041
- if (tt.type === "punct" && tt.value === "}")
1042
- return null;
1043
- if (tt.type === "ident" && tt.value === "return") {
1044
- return tryExtractParamSerializer(tokens, j + 1, paramName);
1045
- }
1046
- if (tt.type === "punct" && tt.value === ";")
1047
- return null;
1048
- if (tt.type === "ident" && tt.value !== "return")
1049
- return null;
1050
- j++;
1051
- }
1052
- return null;
1053
- }
1054
- return null;
1055
- }
1056
- function makeUnknown() {
1057
- return {
1058
- isNoArg: false,
1059
- contextProps: new Set(),
1060
- hasDynamicAccess: true,
1061
- isDestructured: false,
1062
- destructuredProps: new Set(),
1063
- literal: null,
1064
- arglessJsonCall: false,
1065
- paramSerializer: null,
1066
- paramParts: null,
1067
- };
1068
- }
1069
- //# sourceMappingURL=scan.js.map