astro-eslint-parser 0.5.1 → 0.6.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.
Files changed (58) hide show
  1. package/lib/index.d.ts +345 -9
  2. package/lib/index.js +1745 -42
  3. package/lib/index.mjs +1719 -0
  4. package/package.json +9 -7
  5. package/lib/ast/astro.d.ts +0 -49
  6. package/lib/ast/astro.js +0 -2
  7. package/lib/ast/base.d.ts +0 -6
  8. package/lib/ast/base.js +0 -2
  9. package/lib/ast/index.d.ts +0 -8
  10. package/lib/ast/index.js +0 -18
  11. package/lib/ast/jsx.d.ts +0 -91
  12. package/lib/ast/jsx.js +0 -2
  13. package/lib/astro/index.d.ts +0 -56
  14. package/lib/astro/index.js +0 -357
  15. package/lib/astro-tools/index.d.ts +0 -21
  16. package/lib/astro-tools/index.js +0 -26
  17. package/lib/context/index.d.ts +0 -55
  18. package/lib/context/index.js +0 -158
  19. package/lib/context/parser-options.d.ts +0 -8
  20. package/lib/context/parser-options.js +0 -77
  21. package/lib/context/resolve-parser/espree.d.ts +0 -6
  22. package/lib/context/resolve-parser/espree.js +0 -41
  23. package/lib/context/resolve-parser/index.d.ts +0 -7
  24. package/lib/context/resolve-parser/index.js +0 -34
  25. package/lib/context/resolve-parser/parser-object.d.ts +0 -33
  26. package/lib/context/resolve-parser/parser-object.js +0 -27
  27. package/lib/context/script.d.ts +0 -34
  28. package/lib/context/script.js +0 -178
  29. package/lib/debug.d.ts +0 -2
  30. package/lib/debug.js +0 -8
  31. package/lib/errors.d.ts +0 -14
  32. package/lib/errors.js +0 -20
  33. package/lib/parser/astro-parser/astrojs-compiler-service.d.ts +0 -5
  34. package/lib/parser/astro-parser/astrojs-compiler-service.js +0 -12
  35. package/lib/parser/astro-parser/astrojs-compiler-worker.d.ts +0 -1
  36. package/lib/parser/astro-parser/astrojs-compiler-worker.js +0 -11
  37. package/lib/parser/astro-parser/parse.d.ts +0 -6
  38. package/lib/parser/astro-parser/parse.js +0 -270
  39. package/lib/parser/index.d.ts +0 -21
  40. package/lib/parser/index.js +0 -72
  41. package/lib/parser/lru-cache.d.ts +0 -7
  42. package/lib/parser/lru-cache.js +0 -32
  43. package/lib/parser/process-template.d.ts +0 -7
  44. package/lib/parser/process-template.js +0 -390
  45. package/lib/parser/script.d.ts +0 -7
  46. package/lib/parser/script.js +0 -44
  47. package/lib/parser/sort.d.ts +0 -6
  48. package/lib/parser/sort.js +0 -15
  49. package/lib/parser/template.d.ts +0 -10
  50. package/lib/parser/template.js +0 -102
  51. package/lib/parser/ts-patch.d.ts +0 -8
  52. package/lib/parser/ts-patch.js +0 -65
  53. package/lib/traverse.d.ts +0 -27
  54. package/lib/traverse.js +0 -93
  55. package/lib/types.d.ts +0 -17
  56. package/lib/types.js +0 -2
  57. package/lib/visitor-keys.d.ts +0 -2
  58. package/lib/visitor-keys.js +0 -14
package/lib/index.mjs ADDED
@@ -0,0 +1,1719 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw new Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // src/visitor-keys.ts
10
+ import { unionWith } from "eslint-visitor-keys";
11
+ var astroKeys = {
12
+ Program: ["body"],
13
+ AstroFragment: ["children"],
14
+ AstroHTMLComment: [],
15
+ AstroDoctype: [],
16
+ AstroShorthandAttribute: ["name", "value"],
17
+ AstroTemplateLiteralAttribute: ["name", "value"],
18
+ AstroRawText: []
19
+ };
20
+ var KEYS = unionWith(
21
+ astroKeys
22
+ );
23
+
24
+ // src/parser/index.ts
25
+ import { AST_TOKEN_TYPES as AST_TOKEN_TYPES2 } from "@typescript-eslint/types";
26
+
27
+ // src/debug.ts
28
+ import debugFactory from "debug";
29
+ var debug = debugFactory("astro-eslint-parser");
30
+
31
+ // src/parser/ts-patch.ts
32
+ import { createRequire } from "module";
33
+ import path from "path";
34
+ import fs from "fs";
35
+ function tsPatch(scriptParserOptions) {
36
+ let targetExt = ".astro";
37
+ if (scriptParserOptions.filePath) {
38
+ const ext = path.extname(scriptParserOptions.filePath);
39
+ if (ext) {
40
+ targetExt = ext;
41
+ }
42
+ }
43
+ try {
44
+ const cwd = process.cwd();
45
+ const relativeTo = path.join(cwd, "__placeholder__.js");
46
+ const ts = createRequire(relativeTo)("typescript");
47
+ const { ensureScriptKind, getScriptKindFromFileName } = ts;
48
+ if (typeof ensureScriptKind === "function" && typeof getScriptKindFromFileName === "function") {
49
+ ts.ensureScriptKind = function(fileName, ...args) {
50
+ if (fileName.endsWith(targetExt)) {
51
+ return ts.ScriptKind.TSX;
52
+ }
53
+ return ensureScriptKind.call(this, fileName, ...args);
54
+ };
55
+ ts.getScriptKindFromFileName = function(fileName, ...args) {
56
+ if (fileName.endsWith(targetExt)) {
57
+ return ts.ScriptKind.TSX;
58
+ }
59
+ return getScriptKindFromFileName.call(this, fileName, ...args);
60
+ };
61
+ return {
62
+ terminate() {
63
+ ts.ensureScriptKind = ensureScriptKind;
64
+ ts.getScriptKindFromFileName = getScriptKindFromFileName;
65
+ }
66
+ };
67
+ }
68
+ } catch {
69
+ }
70
+ const tsxFilePath = `${scriptParserOptions.filePath}.tsx`;
71
+ scriptParserOptions.filePath = tsxFilePath;
72
+ if (!fs.existsSync(tsxFilePath)) {
73
+ fs.writeFileSync(tsxFilePath, "/* temp for astro-eslint-parser */");
74
+ return {
75
+ terminate() {
76
+ fs.unlinkSync(tsxFilePath);
77
+ }
78
+ };
79
+ }
80
+ return null;
81
+ }
82
+
83
+ // src/context/resolve-parser/parser-object.ts
84
+ function isParserObject(value) {
85
+ return isEnhancedParserObject(value) || isBasicParserObject(value);
86
+ }
87
+ function isEnhancedParserObject(value) {
88
+ return Boolean(value && typeof value.parseForESLint === "function");
89
+ }
90
+ function isBasicParserObject(value) {
91
+ return Boolean(value && typeof value.parse === "function");
92
+ }
93
+ function maybeTSESLintParserObject(value) {
94
+ return isEnhancedParserObject(value) && isBasicParserObject(value) && typeof value.createProgram === "function" && typeof value.clearCaches === "function" && typeof value.version === "string";
95
+ }
96
+
97
+ // src/parser/script.ts
98
+ function parseScript(code, _ctx, parserOptions) {
99
+ const parser = parserOptions.getParser();
100
+ let patchResult;
101
+ try {
102
+ const scriptParserOptions = {
103
+ ...parserOptions.parserOptions
104
+ };
105
+ scriptParserOptions.ecmaFeatures = {
106
+ ...scriptParserOptions.ecmaFeatures || {},
107
+ jsx: true
108
+ };
109
+ if (parserOptions.isTypeScript() && scriptParserOptions.filePath && scriptParserOptions.project) {
110
+ patchResult = tsPatch(scriptParserOptions);
111
+ }
112
+ const result = isEnhancedParserObject(parser) ? parser.parseForESLint(code, scriptParserOptions) : parser.parse(code, scriptParserOptions);
113
+ if ("ast" in result && result.ast != null) {
114
+ return result;
115
+ }
116
+ return { ast: result };
117
+ } catch (e) {
118
+ debug(
119
+ "[script] parsing error:",
120
+ e.message,
121
+ `@ ${JSON.stringify(code)}
122
+
123
+ ${code}`
124
+ );
125
+ throw e;
126
+ } finally {
127
+ patchResult == null ? void 0 : patchResult.terminate();
128
+ }
129
+ }
130
+
131
+ // src/parser/sort.ts
132
+ function sort(tokens) {
133
+ return tokens.sort((a, b) => {
134
+ if (a.range[0] !== b.range[0]) {
135
+ return a.range[0] - b.range[0];
136
+ }
137
+ return a.range[1] - b.range[1];
138
+ });
139
+ }
140
+
141
+ // src/parser/process-template.ts
142
+ import { AST_TOKEN_TYPES, AST_NODE_TYPES } from "@typescript-eslint/types";
143
+
144
+ // src/errors.ts
145
+ var ParseError = class extends SyntaxError {
146
+ constructor(message, offset, ctx) {
147
+ super(message);
148
+ this.index = offset;
149
+ const loc = ctx.getLocFromIndex(offset);
150
+ this.lineNumber = loc.line;
151
+ this.column = loc.column;
152
+ this.originalAST = ctx.originalAST;
153
+ }
154
+ };
155
+
156
+ // src/astro/index.ts
157
+ function isTag(node) {
158
+ return node.type === "element" || node.type === "custom-element" || node.type === "component" || node.type === "fragment";
159
+ }
160
+ function isParent(node) {
161
+ return Array.isArray(node.children);
162
+ }
163
+ function walkElements(parent, code, enter, leave, parents = []) {
164
+ const children = getSortedChildren(parent, code);
165
+ const currParents = [parent, ...parents];
166
+ for (const node of children) {
167
+ enter(node, currParents);
168
+ if (isParent(node)) {
169
+ walkElements(node, code, enter, leave, currParents);
170
+ }
171
+ leave(node, currParents);
172
+ }
173
+ }
174
+ function walk(parent, code, enter, leave) {
175
+ walkElements(
176
+ parent,
177
+ code,
178
+ (node, parents) => {
179
+ enter(node, parents);
180
+ if (isTag(node)) {
181
+ const attrParents = [node, ...parents];
182
+ for (const attr of node.attributes) {
183
+ enter(attr, attrParents);
184
+ leave(attr, attrParents);
185
+ }
186
+ }
187
+ },
188
+ leave
189
+ );
190
+ }
191
+ function calcStartTagEndOffset(node, ctx) {
192
+ const lastAttr = node.attributes[node.attributes.length - 1];
193
+ let beforeCloseIndex;
194
+ if (lastAttr) {
195
+ beforeCloseIndex = calcAttributeEndOffset(lastAttr, ctx);
196
+ } else {
197
+ const info2 = getTokenInfo(
198
+ ctx,
199
+ [`<${node.name}`],
200
+ node.position.start.offset
201
+ );
202
+ beforeCloseIndex = info2.index + info2.match.length;
203
+ }
204
+ const info = getTokenInfo(ctx, [[">", "/>"]], beforeCloseIndex);
205
+ return info.index + info.match.length;
206
+ }
207
+ function calcAttributeEndOffset(node, ctx) {
208
+ let info;
209
+ if (node.kind === "empty") {
210
+ info = getTokenInfo(ctx, [node.name], node.position.start.offset);
211
+ } else if (node.kind === "quoted") {
212
+ info = getTokenInfo(
213
+ ctx,
214
+ [[`"${node.value}"`, `'${node.value}'`, node.value]],
215
+ calcAttributeValueStartOffset(node, ctx)
216
+ );
217
+ } else if (node.kind === "expression") {
218
+ info = getTokenInfo(
219
+ ctx,
220
+ ["{", node.value, "}"],
221
+ calcAttributeValueStartOffset(node, ctx)
222
+ );
223
+ } else if (node.kind === "shorthand") {
224
+ info = getTokenInfo(
225
+ ctx,
226
+ ["{", node.name, "}"],
227
+ node.position.start.offset
228
+ );
229
+ } else if (node.kind === "spread") {
230
+ info = getTokenInfo(
231
+ ctx,
232
+ ["{", "...", node.name, "}"],
233
+ node.position.start.offset
234
+ );
235
+ } else if (node.kind === "template-literal") {
236
+ info = getTokenInfo(
237
+ ctx,
238
+ [`\`${node.value}\``],
239
+ calcAttributeValueStartOffset(node, ctx)
240
+ );
241
+ } else {
242
+ throw new ParseError(
243
+ `Unknown attr kind: ${node.kind}`,
244
+ node.position.start.offset,
245
+ ctx
246
+ );
247
+ }
248
+ return info.index + info.match.length;
249
+ }
250
+ function calcAttributeValueStartOffset(node, ctx) {
251
+ let info;
252
+ if (node.kind === "quoted") {
253
+ info = getTokenInfo(
254
+ ctx,
255
+ [node.name, "=", [`"`, `'`, node.value]],
256
+ node.position.start.offset
257
+ );
258
+ } else if (node.kind === "expression") {
259
+ info = getTokenInfo(
260
+ ctx,
261
+ [node.name, "=", "{"],
262
+ node.position.start.offset
263
+ );
264
+ } else if (node.kind === "template-literal") {
265
+ info = getTokenInfo(
266
+ ctx,
267
+ [node.name, "=", "`"],
268
+ node.position.start.offset
269
+ );
270
+ } else {
271
+ throw new ParseError(
272
+ `Unknown attr kind: ${node.kind}`,
273
+ node.position.start.offset,
274
+ ctx
275
+ );
276
+ }
277
+ return info.index;
278
+ }
279
+ function getEndOffset(node, ctx) {
280
+ var _a;
281
+ if (((_a = node.position.end) == null ? void 0 : _a.offset) != null) {
282
+ return node.position.end.offset;
283
+ }
284
+ if (isTag(node))
285
+ return calcTagEndOffset(node, ctx);
286
+ if (node.type === "expression")
287
+ return calcExpressionEndOffset(node, ctx);
288
+ if (node.type === "comment")
289
+ return calcCommentEndOffset(node, ctx);
290
+ if (node.type === "frontmatter") {
291
+ const start = node.position.start.offset;
292
+ return ctx.code.indexOf("---", start + 3) + 3;
293
+ }
294
+ if (node.type === "doctype") {
295
+ const start = node.position.start.offset;
296
+ return ctx.code.indexOf(">", start) + 1;
297
+ }
298
+ if (node.type === "text") {
299
+ const start = node.position.start.offset;
300
+ return start + node.value.length;
301
+ }
302
+ if (node.type === "root") {
303
+ return ctx.code.length;
304
+ }
305
+ throw new Error(`unknown type: ${node.type}`);
306
+ }
307
+ function calcContentEndOffset(parent, ctx) {
308
+ const code = ctx.code;
309
+ if (isTag(parent)) {
310
+ const end = getEndOffset(parent, ctx);
311
+ if (code[end - 1] !== ">") {
312
+ return end;
313
+ }
314
+ const index = code.lastIndexOf("</", end - 1);
315
+ if (index >= 0 && code.slice(index + 2, end - 1).trim() === parent.name) {
316
+ return index;
317
+ }
318
+ return end;
319
+ } else if (parent.type === "expression") {
320
+ const end = getEndOffset(parent, ctx);
321
+ return code.lastIndexOf("}", end);
322
+ } else if (parent.type === "root") {
323
+ return code.length;
324
+ }
325
+ throw new Error(`unknown type: ${parent.type}`);
326
+ }
327
+ function getSelfClosingTag(node, ctx) {
328
+ if (node.children.length > 0) {
329
+ return null;
330
+ }
331
+ const code = ctx.code;
332
+ const startTagEndOffset = calcStartTagEndOffset(node, ctx);
333
+ if (code.startsWith("/>", startTagEndOffset - 2)) {
334
+ return {
335
+ offset: startTagEndOffset,
336
+ end: "/>"
337
+ };
338
+ }
339
+ if (code.startsWith(`</${node.name}`, startTagEndOffset)) {
340
+ return null;
341
+ }
342
+ return {
343
+ offset: startTagEndOffset,
344
+ end: ">"
345
+ };
346
+ }
347
+ function getEndTag(node, ctx) {
348
+ let beforeIndex;
349
+ if (node.children.length) {
350
+ const lastChild = node.children[node.children.length - 1];
351
+ beforeIndex = getEndOffset(lastChild, ctx);
352
+ } else {
353
+ beforeIndex = calcStartTagEndOffset(node, ctx);
354
+ }
355
+ beforeIndex = skipSpaces(ctx.code, beforeIndex);
356
+ if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
357
+ const offset = beforeIndex;
358
+ beforeIndex = beforeIndex + 2 + node.name.length;
359
+ const info = getTokenInfo(ctx, [">"], beforeIndex);
360
+ const end = info.index + info.match.length;
361
+ return {
362
+ offset,
363
+ tag: ctx.code.slice(offset, end)
364
+ };
365
+ }
366
+ return null;
367
+ }
368
+ function calcCommentEndOffset(node, ctx) {
369
+ const info = getTokenInfo(
370
+ ctx,
371
+ ["<!--", node.value, "-->"],
372
+ node.position.start.offset
373
+ );
374
+ return info.index + info.match.length;
375
+ }
376
+ function calcTagEndOffset(node, ctx) {
377
+ let beforeIndex;
378
+ if (node.children.length) {
379
+ const lastChild = node.children[node.children.length - 1];
380
+ beforeIndex = getEndOffset(lastChild, ctx);
381
+ } else {
382
+ beforeIndex = calcStartTagEndOffset(node, ctx);
383
+ }
384
+ beforeIndex = skipSpaces(ctx.code, beforeIndex);
385
+ if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
386
+ beforeIndex = beforeIndex + 2 + node.name.length;
387
+ const info = getTokenInfo(ctx, [">"], beforeIndex);
388
+ return info.index + info.match.length;
389
+ }
390
+ return beforeIndex;
391
+ }
392
+ function calcExpressionEndOffset(node, ctx) {
393
+ if (node.children.length) {
394
+ const lastChild = node.children[node.children.length - 1];
395
+ const beforeIndex = getEndOffset(lastChild, ctx);
396
+ const info2 = getTokenInfo(ctx, ["}"], beforeIndex);
397
+ return info2.index + info2.match.length;
398
+ }
399
+ const info = getTokenInfo(ctx, ["{", "}"], node.position.start.offset);
400
+ return info.index + info.match.length;
401
+ }
402
+ function getTokenInfo(ctx, tokens, position) {
403
+ let lastMatch;
404
+ for (const t of tokens) {
405
+ const index = lastMatch ? lastMatch.index + lastMatch.match.length : position;
406
+ const m = typeof t === "string" ? matchOfStr(t, index) : matchOfForMulti(t, index);
407
+ if (m == null) {
408
+ throw new ParseError(
409
+ `Unknown token at ${index}, expected: ${JSON.stringify(
410
+ t
411
+ )}, actual: ${JSON.stringify(ctx.code.slice(index, index + 10))}`,
412
+ index,
413
+ ctx
414
+ );
415
+ }
416
+ lastMatch = m;
417
+ }
418
+ return lastMatch;
419
+ function matchOfStr(search, position2) {
420
+ const index = search.trim() === search ? skipSpaces(ctx.code, position2) : position2;
421
+ if (ctx.code.startsWith(search, index)) {
422
+ return {
423
+ match: search,
424
+ index
425
+ };
426
+ }
427
+ return null;
428
+ }
429
+ function matchOfForMulti(search, position2) {
430
+ for (const s of search) {
431
+ const m = matchOfStr(s, position2);
432
+ if (m) {
433
+ return m;
434
+ }
435
+ }
436
+ return null;
437
+ }
438
+ }
439
+ function skipSpaces(string, position) {
440
+ const re = /\s*/g;
441
+ re.lastIndex = position;
442
+ const match = re.exec(string);
443
+ if (match) {
444
+ return match.index + match[0].length;
445
+ }
446
+ return position;
447
+ }
448
+ function getSortedChildren(parent, code) {
449
+ var _a;
450
+ if (parent.type === "root" && ((_a = parent.children[0]) == null ? void 0 : _a.type) === "frontmatter") {
451
+ const children = [...parent.children];
452
+ if (children.every((n) => n.position)) {
453
+ return children.sort(
454
+ (a, b) => a.position.start.offset - b.position.start.offset
455
+ );
456
+ }
457
+ let start = skipSpaces(code, 0);
458
+ if (code.startsWith("<!", start)) {
459
+ const frontmatter = children.shift();
460
+ const before = [];
461
+ let first;
462
+ while (first = children.shift()) {
463
+ start = skipSpaces(code, start);
464
+ if (first.type === "comment" && code.startsWith("<!--", start)) {
465
+ start = code.indexOf("-->", start + 4) + 3;
466
+ before.push(first);
467
+ } else if (first.type === "doctype" && code.startsWith("<!", start)) {
468
+ start = code.indexOf(">", start + 2) + 1;
469
+ before.push(first);
470
+ } else {
471
+ children.unshift(first);
472
+ break;
473
+ }
474
+ }
475
+ return [...before, frontmatter, ...children];
476
+ }
477
+ }
478
+ return parent.children;
479
+ }
480
+
481
+ // src/traverse.ts
482
+ function fallbackKeysFilter(key) {
483
+ let value = null;
484
+ return key !== "comments" && key !== "leadingComments" && key !== "loc" && key !== "parent" && key !== "range" && key !== "tokens" && key !== "trailingComments" && (value = this[key]) !== null && typeof value === "object" && (typeof value.type === "string" || Array.isArray(value));
485
+ }
486
+ function getFallbackKeys(node) {
487
+ return Object.keys(node).filter(fallbackKeysFilter, node);
488
+ }
489
+ function getKeys(node, visitorKeys) {
490
+ const keys = (visitorKeys || KEYS)[node.type] || getFallbackKeys(node);
491
+ return keys.filter((key) => !getNodes(node, key).next().done);
492
+ }
493
+ function* getNodes(node, key) {
494
+ const child = node[key];
495
+ if (Array.isArray(child)) {
496
+ for (const c of child) {
497
+ if (isNode(c)) {
498
+ yield c;
499
+ }
500
+ }
501
+ } else if (isNode(child)) {
502
+ yield child;
503
+ }
504
+ }
505
+ function isNode(x) {
506
+ return x !== null && typeof x === "object" && typeof x.type === "string";
507
+ }
508
+ function traverse(node, parent, visitor) {
509
+ visitor.enterNode(node, parent);
510
+ const keys = getKeys(node, visitor.visitorKeys);
511
+ for (const key of keys) {
512
+ for (const child of getNodes(node, key)) {
513
+ traverse(child, node, visitor);
514
+ }
515
+ }
516
+ visitor.leaveNode(node, parent);
517
+ }
518
+ function traverseNodes(node, visitor) {
519
+ traverse(node, null, visitor);
520
+ }
521
+
522
+ // src/context/script.ts
523
+ var RestoreNodeProcessContext = class {
524
+ constructor(result, parentMap) {
525
+ this.removeTokens = /* @__PURE__ */ new Set();
526
+ this.result = result;
527
+ this.parentMap = parentMap;
528
+ }
529
+ addRemoveToken(test) {
530
+ this.removeTokens.add(test);
531
+ }
532
+ getParent(node) {
533
+ return this.parentMap.get(node) || null;
534
+ }
535
+ };
536
+ var ScriptContext = class {
537
+ constructor(ctx) {
538
+ this.script = "";
539
+ this.consumedIndex = 0;
540
+ this.offsets = [];
541
+ this.fragments = [];
542
+ this.tokens = [];
543
+ this.restoreNodeProcesses = [];
544
+ this.ctx = ctx;
545
+ }
546
+ get originalCode() {
547
+ return this.ctx.code;
548
+ }
549
+ skipOriginalOffset(offset) {
550
+ this.consumedIndex += offset;
551
+ }
552
+ appendOriginal(index) {
553
+ if (this.consumedIndex >= index) {
554
+ return;
555
+ }
556
+ this.offsets.push({
557
+ original: this.consumedIndex,
558
+ script: this.script.length
559
+ });
560
+ this.script += this.ctx.code.slice(this.consumedIndex, index);
561
+ this.consumedIndex = index;
562
+ }
563
+ appendScript(fragment) {
564
+ const start = this.script.length;
565
+ this.script += fragment;
566
+ this.fragments.push({ start, end: this.script.length });
567
+ }
568
+ addToken(type, range) {
569
+ if (range[0] >= range[1]) {
570
+ return;
571
+ }
572
+ this.tokens.push(this.ctx.buildToken(type, range));
573
+ }
574
+ addRestoreNodeProcess(process2) {
575
+ this.restoreNodeProcesses.push(process2);
576
+ }
577
+ restore(result) {
578
+ var _a, _b;
579
+ const traversed = /* @__PURE__ */ new Map();
580
+ traverseNodes(result.ast, {
581
+ visitorKeys: result.visitorKeys,
582
+ enterNode: (node, p) => {
583
+ if (!traversed.has(node)) {
584
+ traversed.set(node, p);
585
+ this.remapLocation(node);
586
+ }
587
+ },
588
+ leaveNode: (_node) => {
589
+ }
590
+ });
591
+ const tokens = [...this.tokens];
592
+ for (const token of result.ast.tokens || []) {
593
+ if (this.fragments.some(
594
+ (f) => f.start <= token.range[0] && token.range[1] <= f.end
595
+ )) {
596
+ continue;
597
+ }
598
+ this.remapLocation(token);
599
+ tokens.push(token);
600
+ }
601
+ result.ast.tokens = tokens;
602
+ for (const token of result.ast.comments || []) {
603
+ this.remapLocation(token);
604
+ }
605
+ const context = new RestoreNodeProcessContext(result, traversed);
606
+ let restoreNodeProcesses = this.restoreNodeProcesses;
607
+ for (const [node, parent] of traversed) {
608
+ if (!parent)
609
+ continue;
610
+ restoreNodeProcesses = restoreNodeProcesses.filter(
611
+ (proc) => !proc(node, context)
612
+ );
613
+ }
614
+ if (context.removeTokens.size) {
615
+ const tokens2 = result.ast.tokens || [];
616
+ for (let index = tokens2.length - 1; index >= 0; index--) {
617
+ const token = tokens2[index];
618
+ for (const rt of context.removeTokens) {
619
+ if (rt(token)) {
620
+ tokens2.splice(index, 1);
621
+ context.removeTokens.delete(rt);
622
+ if (!context.removeTokens.size) {
623
+ break;
624
+ }
625
+ }
626
+ }
627
+ }
628
+ }
629
+ const firstOffset = Math.min(
630
+ ...[result.ast.body[0], (_a = result.ast.tokens) == null ? void 0 : _a[0], (_b = result.ast.comments) == null ? void 0 : _b[0]].filter(Boolean).map((t) => t.range[0])
631
+ );
632
+ if (firstOffset < result.ast.range[0]) {
633
+ result.ast.range[0] = firstOffset;
634
+ result.ast.loc.start = this.ctx.getLocFromIndex(firstOffset);
635
+ }
636
+ }
637
+ remapLocation(node) {
638
+ let [start, end] = node.range;
639
+ const startFragment = this.fragments.find(
640
+ (f) => f.start <= start && start < f.end
641
+ );
642
+ if (startFragment) {
643
+ start = startFragment.end;
644
+ }
645
+ const endFragment = this.fragments.find(
646
+ (f) => f.start < end && end <= f.end
647
+ );
648
+ if (endFragment) {
649
+ end = endFragment.start;
650
+ }
651
+ if (end < start) {
652
+ const w = start;
653
+ start = end;
654
+ end = w;
655
+ }
656
+ const locs = this.ctx.getLocations(...this.getRemapRange(start, end));
657
+ node.loc = locs.loc;
658
+ node.range = locs.range;
659
+ if (node.start != null) {
660
+ delete node.start;
661
+ }
662
+ if (node.end != null) {
663
+ delete node.end;
664
+ }
665
+ }
666
+ getRemapRange(start, end) {
667
+ if (!this.offsets.length) {
668
+ return [start, end];
669
+ }
670
+ let lastStart = this.offsets[0];
671
+ let lastEnd = this.offsets[0];
672
+ for (const offset of this.offsets) {
673
+ if (offset.script <= start) {
674
+ lastStart = offset;
675
+ }
676
+ if (offset.script < end) {
677
+ lastEnd = offset;
678
+ } else {
679
+ if (offset.script === end) {
680
+ const remapStart2 = lastStart.original + (start - lastStart.script);
681
+ if (this.tokens.some(
682
+ (t) => t.range[0] <= remapStart2 && offset.original <= t.range[1]
683
+ )) {
684
+ lastEnd = offset;
685
+ }
686
+ }
687
+ break;
688
+ }
689
+ }
690
+ const remapStart = lastStart.original + (start - lastStart.script);
691
+ const remapEnd = lastEnd.original + (end - lastEnd.script);
692
+ return [remapStart, remapEnd];
693
+ }
694
+ };
695
+
696
+ // src/parser/process-template.ts
697
+ function processTemplate(ctx, resultTemplate) {
698
+ let uniqueIdSeq = 0;
699
+ const usedUniqueIds = /* @__PURE__ */ new Set();
700
+ const script = new ScriptContext(ctx);
701
+ let fragmentOpened = false;
702
+ function openRootFragment(startOffset) {
703
+ script.appendScript("<>");
704
+ fragmentOpened = true;
705
+ script.addRestoreNodeProcess((scriptNode, { result }) => {
706
+ if (scriptNode.type === AST_NODE_TYPES.ExpressionStatement && scriptNode.expression.type === AST_NODE_TYPES.JSXFragment && scriptNode.range[0] === startOffset && result.ast.body.includes(scriptNode)) {
707
+ const index = result.ast.body.indexOf(scriptNode);
708
+ const rootFragment = result.ast.body[index] = scriptNode.expression;
709
+ delete rootFragment.closingFragment;
710
+ delete rootFragment.openingFragment;
711
+ rootFragment.type = "AstroFragment";
712
+ return true;
713
+ }
714
+ return false;
715
+ });
716
+ }
717
+ walkElements(
718
+ resultTemplate.ast,
719
+ ctx.code,
720
+ (node, [parent]) => {
721
+ if (node.type === "frontmatter") {
722
+ const start = node.position.start.offset;
723
+ if (fragmentOpened) {
724
+ script.appendScript("</>;");
725
+ fragmentOpened = false;
726
+ }
727
+ script.appendOriginal(start);
728
+ script.skipOriginalOffset(3);
729
+ const end = getEndOffset(node, ctx);
730
+ const scriptStart = start + 3;
731
+ let scriptEnd = end - 3;
732
+ let endChar;
733
+ while (scriptStart < scriptEnd - 1 && (endChar = script.originalCode[scriptEnd - 1]) && !endChar.trim()) {
734
+ scriptEnd--;
735
+ }
736
+ script.appendOriginal(scriptEnd);
737
+ script.appendScript("\n;");
738
+ script.skipOriginalOffset(end - scriptEnd);
739
+ script.addRestoreNodeProcess((_scriptNode, { result }) => {
740
+ for (let index = 0; index < result.ast.body.length; index++) {
741
+ const st = result.ast.body[index];
742
+ if (st.type === AST_NODE_TYPES.EmptyStatement) {
743
+ if (st.range[0] === scriptEnd && st.range[1] <= end) {
744
+ result.ast.body.splice(index, 1);
745
+ break;
746
+ }
747
+ }
748
+ }
749
+ return true;
750
+ });
751
+ script.addToken(AST_TOKEN_TYPES.Punctuator, [
752
+ node.position.start.offset,
753
+ node.position.start.offset + 3
754
+ ]);
755
+ script.addToken(AST_TOKEN_TYPES.Punctuator, [end - 3, end]);
756
+ } else if (isTag(node)) {
757
+ if (parent.type === "expression") {
758
+ const index = parent.children.indexOf(node);
759
+ const before = parent.children[index - 1];
760
+ if (!before || !isTag(before)) {
761
+ const after = parent.children[index + 1];
762
+ if (after && (isTag(after) || after.type === "comment")) {
763
+ const start2 = node.position.start.offset;
764
+ script.appendOriginal(start2);
765
+ script.appendScript("<>");
766
+ script.addRestoreNodeProcess((scriptNode) => {
767
+ if (scriptNode.range[0] === start2 && scriptNode.type === AST_NODE_TYPES.JSXFragment) {
768
+ delete scriptNode.openingFragment;
769
+ delete scriptNode.closingFragment;
770
+ const fragmentNode = scriptNode;
771
+ fragmentNode.type = "AstroFragment";
772
+ const last = fragmentNode.children[fragmentNode.children.length - 1];
773
+ if (fragmentNode.range[1] < last.range[1]) {
774
+ fragmentNode.range[1] = last.range[1];
775
+ fragmentNode.loc.end = ctx.getLocFromIndex(
776
+ fragmentNode.range[1]
777
+ );
778
+ }
779
+ return true;
780
+ }
781
+ return false;
782
+ });
783
+ }
784
+ }
785
+ }
786
+ const start = node.position.start.offset;
787
+ script.appendOriginal(start);
788
+ if (!fragmentOpened) {
789
+ openRootFragment(start);
790
+ }
791
+ for (const attr of node.attributes) {
792
+ if ((node.type === "component" || node.type === "fragment") && (attr.kind === "quoted" || attr.kind === "empty" || attr.kind === "expression" || attr.kind === "template-literal")) {
793
+ const colonIndex = attr.name.indexOf(":");
794
+ if (colonIndex >= 0) {
795
+ const start2 = attr.position.start.offset;
796
+ script.appendOriginal(start2 + colonIndex);
797
+ script.skipOriginalOffset(1);
798
+ script.appendScript(`_`);
799
+ script.addToken(AST_TOKEN_TYPES.JSXIdentifier, [
800
+ start2,
801
+ start2 + colonIndex
802
+ ]);
803
+ script.addToken(AST_TOKEN_TYPES.Punctuator, [
804
+ start2 + colonIndex,
805
+ start2 + colonIndex + 1
806
+ ]);
807
+ script.addToken(AST_TOKEN_TYPES.JSXIdentifier, [
808
+ start2 + colonIndex + 1,
809
+ start2 + attr.name.length
810
+ ]);
811
+ script.addRestoreNodeProcess((scriptNode, context) => {
812
+ if (scriptNode.type === AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === start2) {
813
+ const baseNameNode = scriptNode.name;
814
+ const nsn = {
815
+ ...baseNameNode,
816
+ type: AST_NODE_TYPES.JSXNamespacedName,
817
+ namespace: {
818
+ type: AST_NODE_TYPES.JSXIdentifier,
819
+ name: attr.name.slice(0, colonIndex),
820
+ ...ctx.getLocations(
821
+ baseNameNode.range[0],
822
+ baseNameNode.range[0] + colonIndex
823
+ )
824
+ },
825
+ name: {
826
+ type: AST_NODE_TYPES.JSXIdentifier,
827
+ name: attr.name.slice(colonIndex + 1),
828
+ ...ctx.getLocations(
829
+ baseNameNode.range[0] + colonIndex + 1,
830
+ baseNameNode.range[1]
831
+ )
832
+ }
833
+ };
834
+ scriptNode.name = nsn;
835
+ nsn.namespace.parent = nsn;
836
+ nsn.name.parent = nsn;
837
+ context.addRemoveToken(
838
+ (token) => token.range[0] === baseNameNode.range[0] && token.range[1] === baseNameNode.range[1]
839
+ );
840
+ return true;
841
+ }
842
+ return false;
843
+ });
844
+ }
845
+ }
846
+ if (attr.kind === "shorthand") {
847
+ const start2 = attr.position.start.offset;
848
+ script.appendOriginal(start2);
849
+ const jsxName = /[\s"'[\]{}]/u.test(attr.name) ? generateUniqueId(attr.name) : attr.name;
850
+ script.appendScript(`${jsxName}=`);
851
+ script.addRestoreNodeProcess((scriptNode) => {
852
+ if (scriptNode.type === AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === start2) {
853
+ const attrNode = scriptNode;
854
+ attrNode.type = "AstroShorthandAttribute";
855
+ const locs = ctx.getLocations(
856
+ ...attrNode.value.expression.range
857
+ );
858
+ if (jsxName !== attr.name) {
859
+ attrNode.name.name = attr.name;
860
+ }
861
+ attrNode.name.range = locs.range;
862
+ attrNode.name.loc = locs.loc;
863
+ return true;
864
+ }
865
+ return false;
866
+ });
867
+ } else if (attr.kind === "template-literal") {
868
+ const attrStart = attr.position.start.offset;
869
+ const start2 = calcAttributeValueStartOffset(attr, ctx);
870
+ const end = calcAttributeEndOffset(attr, ctx);
871
+ script.appendOriginal(start2);
872
+ script.appendScript("{");
873
+ script.appendOriginal(end);
874
+ script.appendScript("}");
875
+ script.addRestoreNodeProcess((scriptNode) => {
876
+ if (scriptNode.type === AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === attrStart) {
877
+ const attrNode = scriptNode;
878
+ attrNode.type = "AstroTemplateLiteralAttribute";
879
+ return true;
880
+ }
881
+ return false;
882
+ });
883
+ }
884
+ }
885
+ const closing = getSelfClosingTag(node, ctx);
886
+ if (closing && closing.end === ">") {
887
+ script.appendOriginal(closing.offset - 1);
888
+ script.appendScript("/");
889
+ }
890
+ if (node.name === "script" || node.name === "style") {
891
+ const text = node.children[0];
892
+ if (text && text.type === "text") {
893
+ const styleNodeStart = node.position.start.offset;
894
+ const start2 = text.position.start.offset;
895
+ script.appendOriginal(start2);
896
+ script.skipOriginalOffset(text.value.length);
897
+ script.addRestoreNodeProcess((scriptNode) => {
898
+ if (scriptNode.type === AST_NODE_TYPES.JSXElement && scriptNode.range[0] === styleNodeStart) {
899
+ const textNode = {
900
+ type: "AstroRawText",
901
+ value: text.value,
902
+ raw: text.value,
903
+ parent: scriptNode,
904
+ ...ctx.getLocations(start2, start2 + text.value.length)
905
+ };
906
+ scriptNode.children = [textNode];
907
+ return true;
908
+ }
909
+ return false;
910
+ });
911
+ script.addToken(AST_TOKEN_TYPES.JSXText, [
912
+ start2,
913
+ start2 + text.value.length
914
+ ]);
915
+ }
916
+ }
917
+ } else if (node.type === "comment") {
918
+ const start = node.position.start.offset;
919
+ const end = getEndOffset(node, ctx);
920
+ const length = end - start;
921
+ script.appendOriginal(start);
922
+ if (!fragmentOpened) {
923
+ openRootFragment(start);
924
+ }
925
+ script.appendOriginal(start + 1);
926
+ script.appendScript(`></`);
927
+ script.skipOriginalOffset(length - 2);
928
+ script.appendOriginal(end);
929
+ script.addRestoreNodeProcess((scriptNode, context) => {
930
+ if (scriptNode.range[0] === start && scriptNode.type === AST_NODE_TYPES.JSXFragment) {
931
+ delete scriptNode.children;
932
+ delete scriptNode.openingFragment;
933
+ delete scriptNode.closingFragment;
934
+ delete scriptNode.expression;
935
+ const commentNode = scriptNode;
936
+ commentNode.type = "AstroHTMLComment";
937
+ commentNode.value = node.value;
938
+ context.addRemoveToken(
939
+ (token) => token.value === "<" && token.range[0] === scriptNode.range[0]
940
+ );
941
+ context.addRemoveToken(
942
+ (token) => token.value === ">" && token.range[1] === scriptNode.range[1]
943
+ );
944
+ return true;
945
+ }
946
+ return false;
947
+ });
948
+ script.addToken("HTMLComment", [
949
+ start,
950
+ start + length
951
+ ]);
952
+ } else if (node.type === "doctype") {
953
+ const start = node.position.start.offset;
954
+ const end = getEndOffset(node, ctx);
955
+ const length = end - start;
956
+ script.appendOriginal(start);
957
+ if (!fragmentOpened) {
958
+ openRootFragment(start);
959
+ }
960
+ script.appendOriginal(start + 1);
961
+ script.appendScript(`></`);
962
+ script.skipOriginalOffset(length - 2);
963
+ script.appendOriginal(end);
964
+ script.addRestoreNodeProcess((scriptNode, context) => {
965
+ if (scriptNode.range[0] === start && scriptNode.type === AST_NODE_TYPES.JSXFragment) {
966
+ delete scriptNode.children;
967
+ delete scriptNode.openingFragment;
968
+ delete scriptNode.closingFragment;
969
+ delete scriptNode.expression;
970
+ const doctypeNode = scriptNode;
971
+ doctypeNode.type = "AstroDoctype";
972
+ context.addRemoveToken(
973
+ (token) => token.value === "<" && token.range[0] === scriptNode.range[0]
974
+ );
975
+ context.addRemoveToken(
976
+ (token) => token.value === ">" && token.range[1] === scriptNode.range[1]
977
+ );
978
+ return true;
979
+ }
980
+ return false;
981
+ });
982
+ script.addToken("HTMLDocType", [start, end]);
983
+ } else {
984
+ const start = node.position.start.offset;
985
+ script.appendOriginal(start);
986
+ if (!fragmentOpened) {
987
+ openRootFragment(start);
988
+ }
989
+ }
990
+ },
991
+ (node, [parent]) => {
992
+ if (isTag(node)) {
993
+ const closing = getSelfClosingTag(node, ctx);
994
+ if (!closing) {
995
+ const end = getEndTag(node, ctx);
996
+ if (!end) {
997
+ const offset = calcContentEndOffset(node, ctx);
998
+ script.appendOriginal(offset);
999
+ script.appendScript(`</${node.name}>`);
1000
+ script.addRestoreNodeProcess((scriptNode, context) => {
1001
+ const parent2 = context.getParent(scriptNode);
1002
+ if (scriptNode.range[0] === offset && scriptNode.type === AST_NODE_TYPES.JSXClosingElement && parent2.type === AST_NODE_TYPES.JSXElement) {
1003
+ parent2.closingElement = null;
1004
+ return true;
1005
+ }
1006
+ return false;
1007
+ });
1008
+ }
1009
+ }
1010
+ }
1011
+ if ((isTag(node) || node.type === "comment") && parent.type === "expression") {
1012
+ const index = parent.children.indexOf(node);
1013
+ const after = parent.children[index + 1];
1014
+ if (!after || !isTag(after) && after.type !== "comment") {
1015
+ const before = parent.children[index - 1];
1016
+ if (before && (isTag(before) || before.type === "comment")) {
1017
+ const end = getEndOffset(node, ctx);
1018
+ script.appendOriginal(end);
1019
+ script.appendScript("</>");
1020
+ }
1021
+ }
1022
+ }
1023
+ }
1024
+ );
1025
+ if (fragmentOpened) {
1026
+ const last = resultTemplate.ast.children[resultTemplate.ast.children.length - 1];
1027
+ const end = getEndOffset(last, ctx);
1028
+ script.appendOriginal(end);
1029
+ script.appendScript("</>");
1030
+ }
1031
+ script.appendOriginal(ctx.code.length);
1032
+ return script;
1033
+ function generateUniqueId(base) {
1034
+ let candidate = `$_${base.replace(/\W/g, "_")}${uniqueIdSeq++}`;
1035
+ while (usedUniqueIds.has(candidate) || ctx.code.includes(candidate)) {
1036
+ candidate = `$_${base.replace(/\W/g, "_")}${uniqueIdSeq++}`;
1037
+ }
1038
+ usedUniqueIds.add(candidate);
1039
+ return candidate;
1040
+ }
1041
+ }
1042
+
1043
+ // src/context/index.ts
1044
+ var Context = class {
1045
+ constructor(code) {
1046
+ this.locsMap = /* @__PURE__ */ new Map();
1047
+ this.state = {};
1048
+ this.locs = new LinesAndColumns(code);
1049
+ this.code = code;
1050
+ }
1051
+ getLocFromIndex(index) {
1052
+ let loc = this.locsMap.get(index);
1053
+ if (!loc) {
1054
+ loc = this.locs.getLocFromIndex(index);
1055
+ this.locsMap.set(index, loc);
1056
+ }
1057
+ return {
1058
+ line: loc.line,
1059
+ column: loc.column
1060
+ };
1061
+ }
1062
+ getLocations(start, end) {
1063
+ return {
1064
+ range: [start, end],
1065
+ loc: {
1066
+ start: this.getLocFromIndex(start),
1067
+ end: this.getLocFromIndex(end)
1068
+ }
1069
+ };
1070
+ }
1071
+ buildToken(type, range) {
1072
+ return {
1073
+ type,
1074
+ value: this.getText(range),
1075
+ ...this.getLocations(...range)
1076
+ };
1077
+ }
1078
+ getText(range) {
1079
+ return this.code.slice(range[0], range[1]);
1080
+ }
1081
+ get originalAST() {
1082
+ return this.state.originalAST;
1083
+ }
1084
+ set originalAST(originalAST) {
1085
+ this.state.originalAST = originalAST;
1086
+ }
1087
+ };
1088
+ var LinesAndColumns = class {
1089
+ constructor(origCode) {
1090
+ const len = origCode.length;
1091
+ const lineStartIndices = [0];
1092
+ const crs = [];
1093
+ let normalizedCode = "";
1094
+ for (let index = 0; index < len; ) {
1095
+ const c = origCode[index++];
1096
+ if (c === "\r") {
1097
+ const next = origCode[index++] || "";
1098
+ if (next === "\n") {
1099
+ normalizedCode += next;
1100
+ crs.push(index - 2);
1101
+ lineStartIndices.push(index);
1102
+ } else {
1103
+ normalizedCode += `
1104
+ ${next}`;
1105
+ lineStartIndices.push(index - 1);
1106
+ }
1107
+ } else {
1108
+ normalizedCode += c;
1109
+ if (c === "\n") {
1110
+ lineStartIndices.push(index);
1111
+ }
1112
+ }
1113
+ }
1114
+ this.lineStartIndices = lineStartIndices;
1115
+ this.normalizedLineFeed = new NormalizedLineFeed(normalizedCode, crs);
1116
+ }
1117
+ getLocFromIndex(index) {
1118
+ const lineNumber = sortedLastIndex(this.lineStartIndices, index);
1119
+ return {
1120
+ line: lineNumber,
1121
+ column: index - this.lineStartIndices[lineNumber - 1]
1122
+ };
1123
+ }
1124
+ getIndexFromLoc(loc) {
1125
+ const lineStartIndex = this.lineStartIndices[loc.line - 1];
1126
+ const positionIndex = lineStartIndex + loc.column;
1127
+ return positionIndex;
1128
+ }
1129
+ getNormalizedLineFeed() {
1130
+ return this.normalizedLineFeed;
1131
+ }
1132
+ };
1133
+ var NormalizedLineFeed = class {
1134
+ get needRemap() {
1135
+ return this.offsets.length > 0;
1136
+ }
1137
+ constructor(code, offsets) {
1138
+ this.code = code;
1139
+ this.offsets = offsets;
1140
+ if (offsets.length) {
1141
+ const cache = {};
1142
+ this.remapIndex = (index) => {
1143
+ let result = cache[index];
1144
+ if (result != null) {
1145
+ return result;
1146
+ }
1147
+ result = index;
1148
+ for (const offset of offsets) {
1149
+ if (offset < result) {
1150
+ result++;
1151
+ } else {
1152
+ break;
1153
+ }
1154
+ }
1155
+ return cache[index] = result;
1156
+ };
1157
+ } else {
1158
+ this.remapIndex = (i) => i;
1159
+ }
1160
+ }
1161
+ };
1162
+ function sortedLastIndex(array, value) {
1163
+ let lower = 0;
1164
+ let upper = array.length;
1165
+ while (lower < upper) {
1166
+ const mid = Math.floor(lower + (upper - lower) / 2);
1167
+ const target = array[mid];
1168
+ if (target < value) {
1169
+ lower = mid + 1;
1170
+ } else if (target > value) {
1171
+ upper = mid;
1172
+ } else {
1173
+ return mid + 1;
1174
+ }
1175
+ }
1176
+ return upper;
1177
+ }
1178
+
1179
+ // src/parser/astro-parser/parse.ts
1180
+ import * as service from "astrojs-compiler-sync";
1181
+ function parse2(code, ctx) {
1182
+ const ast = service.parse(code, { position: true }).ast;
1183
+ if (!ast.children) {
1184
+ ast.children = [];
1185
+ }
1186
+ const htmlElement = ast.children.find(
1187
+ (n) => n.type === "element" && n.name === "html"
1188
+ );
1189
+ if (htmlElement) {
1190
+ adjustHTML(ast, htmlElement, ctx);
1191
+ }
1192
+ fixLocations(ast, ctx);
1193
+ return { ast };
1194
+ }
1195
+ function adjustHTML(ast, htmlElement, ctx) {
1196
+ var _a;
1197
+ const htmlEnd = ctx.code.indexOf("</html");
1198
+ if (htmlEnd == null) {
1199
+ return;
1200
+ }
1201
+ const hasTokenAfter = Boolean(ctx.code.slice(htmlEnd + 7).trim());
1202
+ const children = [...htmlElement.children];
1203
+ for (const child of children) {
1204
+ const offset = (_a = child.position) == null ? void 0 : _a.start.offset;
1205
+ if (hasTokenAfter && offset != null) {
1206
+ if (htmlEnd <= offset) {
1207
+ htmlElement.children.splice(htmlElement.children.indexOf(child), 1);
1208
+ ast.children.push(child);
1209
+ }
1210
+ }
1211
+ if (child.type === "element" && child.name === "body") {
1212
+ adjustHTMLBody(ast, htmlElement, htmlEnd, hasTokenAfter, child, ctx);
1213
+ }
1214
+ }
1215
+ }
1216
+ function adjustHTMLBody(ast, htmlElement, htmlEnd, hasTokenAfterHtmlEnd, bodyElement, ctx) {
1217
+ var _a;
1218
+ const bodyEnd = ctx.code.indexOf("</body");
1219
+ if (bodyEnd == null) {
1220
+ return;
1221
+ }
1222
+ const hasTokenAfter = Boolean(ctx.code.slice(bodyEnd + 7, htmlEnd).trim());
1223
+ if (!hasTokenAfter && !hasTokenAfterHtmlEnd) {
1224
+ return;
1225
+ }
1226
+ const children = [...bodyElement.children];
1227
+ for (const child of children) {
1228
+ const offset = (_a = child.position) == null ? void 0 : _a.start.offset;
1229
+ if (offset != null) {
1230
+ if (bodyEnd <= offset) {
1231
+ if (hasTokenAfterHtmlEnd && htmlEnd <= offset) {
1232
+ bodyElement.children.splice(bodyElement.children.indexOf(child), 1);
1233
+ ast.children.push(child);
1234
+ } else if (hasTokenAfter) {
1235
+ bodyElement.children.splice(bodyElement.children.indexOf(child), 1);
1236
+ htmlElement.children.push(child);
1237
+ }
1238
+ }
1239
+ }
1240
+ }
1241
+ }
1242
+ function fixLocations(node, ctx) {
1243
+ let start = 0;
1244
+ walk(
1245
+ node,
1246
+ ctx.code,
1247
+ (node2, [parent]) => {
1248
+ if (node2.type === "frontmatter") {
1249
+ start = node2.position.start.offset = tokenIndex(ctx, "---", start);
1250
+ if (!node2.position.end) {
1251
+ node2.position.end = {};
1252
+ }
1253
+ start = node2.position.end.offset = tokenIndex(ctx, "---", start + 3 + node2.value.length) + 3;
1254
+ } else if (node2.type === "fragment" || node2.type === "element" || node2.type === "component" || node2.type === "custom-element") {
1255
+ if (!node2.position) {
1256
+ node2.position = { start: {}, end: {} };
1257
+ }
1258
+ start = node2.position.start.offset = tokenIndex(ctx, "<", start);
1259
+ start += 1;
1260
+ start += node2.name.length;
1261
+ if (!node2.attributes.length) {
1262
+ start = calcStartTagEndOffset(node2, ctx);
1263
+ }
1264
+ } else if (node2.type === "attribute") {
1265
+ fixLocationForAttr(node2, ctx, start);
1266
+ start = calcAttributeEndOffset(node2, ctx);
1267
+ if (node2.position.end) {
1268
+ node2.position.end.offset = start;
1269
+ }
1270
+ } else if (node2.type === "comment") {
1271
+ node2.position.start.offset = tokenIndex(ctx, "<!--", start);
1272
+ start = calcCommentEndOffset(node2, ctx);
1273
+ if (node2.position.end) {
1274
+ node2.position.end.offset = start;
1275
+ }
1276
+ } else if (node2.type === "text") {
1277
+ if (parent.type === "element" && (parent.name === "script" || parent.name === "style")) {
1278
+ node2.position.start.offset = start;
1279
+ start = ctx.code.indexOf(`</${parent.name}`, start);
1280
+ if (start < 0) {
1281
+ start = ctx.code.length;
1282
+ }
1283
+ } else {
1284
+ const index = tokenIndexSafe(ctx.code, node2.value, start);
1285
+ if (index != null) {
1286
+ start = node2.position.start.offset = index;
1287
+ start += node2.value.length;
1288
+ } else {
1289
+ node2.position.start.offset = start;
1290
+ const value = node2.value.replace(/\s+/gu, "");
1291
+ for (const char of value) {
1292
+ const index2 = tokenIndex(ctx, char, start);
1293
+ start = index2 + 1;
1294
+ }
1295
+ start = skipSpaces(ctx.code, start);
1296
+ node2.value = ctx.code.slice(node2.position.start.offset, start);
1297
+ }
1298
+ }
1299
+ if (node2.position.end) {
1300
+ node2.position.end.offset = start;
1301
+ }
1302
+ } else if (node2.type === "expression") {
1303
+ start = node2.position.start.offset = tokenIndex(ctx, "{", start);
1304
+ start += 1;
1305
+ } else if (node2.type === "doctype") {
1306
+ if (!node2.position) {
1307
+ node2.position = { start: {}, end: {} };
1308
+ }
1309
+ if (!node2.position.end) {
1310
+ node2.position.end = {};
1311
+ }
1312
+ start = node2.position.start.offset = tokenIndex(ctx, "<!", start);
1313
+ start += 2;
1314
+ start = node2.position.end.offset = ctx.code.indexOf(">", start) + 1;
1315
+ } else if (node2.type === "root") {
1316
+ }
1317
+ },
1318
+ (node2, [parent]) => {
1319
+ if (node2.type === "attribute") {
1320
+ const attributes = parent.attributes;
1321
+ if (attributes[attributes.length - 1] === node2) {
1322
+ start = calcStartTagEndOffset(parent, ctx);
1323
+ }
1324
+ } else if (node2.type === "expression") {
1325
+ start = tokenIndex(ctx, "}", start) + 1;
1326
+ } else if (node2.type === "fragment" || node2.type === "element" || node2.type === "component" || node2.type === "custom-element") {
1327
+ if (!getSelfClosingTag(node2, ctx)) {
1328
+ const closeTagStart = tokenIndexSafe(
1329
+ ctx.code,
1330
+ `</${node2.name}`,
1331
+ start
1332
+ );
1333
+ if (closeTagStart != null) {
1334
+ start = closeTagStart + 2 + node2.name.length;
1335
+ start = tokenIndex(ctx, ">", start) + 1;
1336
+ }
1337
+ }
1338
+ } else {
1339
+ return;
1340
+ }
1341
+ if (node2.position.end) {
1342
+ node2.position.end.offset = start;
1343
+ }
1344
+ }
1345
+ );
1346
+ }
1347
+ function fixLocationForAttr(node, ctx, start) {
1348
+ if (node.kind === "empty") {
1349
+ node.position.start.offset = tokenIndex(ctx, node.name, start);
1350
+ } else if (node.kind === "quoted") {
1351
+ node.position.start.offset = tokenIndex(ctx, node.name, start);
1352
+ } else if (node.kind === "expression") {
1353
+ node.position.start.offset = tokenIndex(ctx, node.name, start);
1354
+ } else if (node.kind === "shorthand") {
1355
+ node.position.start.offset = tokenIndex(ctx, "{", start);
1356
+ } else if (node.kind === "spread") {
1357
+ node.position.start.offset = tokenIndex(ctx, "{", start);
1358
+ } else if (node.kind === "template-literal") {
1359
+ node.position.start.offset = tokenIndex(ctx, node.name, start);
1360
+ } else {
1361
+ throw new ParseError(
1362
+ `Unknown attr kind: ${node.kind}`,
1363
+ node.position.start.offset,
1364
+ ctx
1365
+ );
1366
+ }
1367
+ }
1368
+ function tokenIndex(ctx, token, position) {
1369
+ const index = tokenIndexSafe(ctx.code, token, position);
1370
+ if (index == null) {
1371
+ const start = token.trim() === token ? skipSpaces(ctx.code, position) : position;
1372
+ throw new ParseError(
1373
+ `Unknown token at ${start}, expected: ${JSON.stringify(
1374
+ token
1375
+ )}, actual: ${JSON.stringify(ctx.code.slice(start, start + 10))}`,
1376
+ start,
1377
+ ctx
1378
+ );
1379
+ }
1380
+ return index;
1381
+ }
1382
+ function tokenIndexSafe(string, token, position) {
1383
+ const index = token.trim() === token ? skipSpaces(string, position) : position;
1384
+ if (string.startsWith(token, index)) {
1385
+ return index;
1386
+ }
1387
+ return null;
1388
+ }
1389
+
1390
+ // src/parser/lru-cache.ts
1391
+ var LruCache = class extends Map {
1392
+ constructor(capacity) {
1393
+ super();
1394
+ this.capacity = capacity;
1395
+ }
1396
+ get(key) {
1397
+ if (!this.has(key)) {
1398
+ return void 0;
1399
+ }
1400
+ const value = super.get(key);
1401
+ this.set(key, value);
1402
+ return value;
1403
+ }
1404
+ set(key, value) {
1405
+ this.delete(key);
1406
+ super.set(key, value);
1407
+ if (this.size > this.capacity) {
1408
+ this.deleteOldestEntry();
1409
+ }
1410
+ return this;
1411
+ }
1412
+ deleteOldestEntry() {
1413
+ for (const entry of this) {
1414
+ this.delete(entry[0]);
1415
+ return;
1416
+ }
1417
+ }
1418
+ };
1419
+
1420
+ // src/parser/template.ts
1421
+ var lruCache = new LruCache(5);
1422
+ function parseTemplate(code) {
1423
+ const cache = lruCache.get(code);
1424
+ if (cache) {
1425
+ return cache;
1426
+ }
1427
+ const ctx = new Context(code);
1428
+ const normalized = ctx.locs.getNormalizedLineFeed();
1429
+ const ctxForAstro = normalized.needRemap ? new Context(normalized.code) : ctx;
1430
+ try {
1431
+ const result = parse2((normalized == null ? void 0 : normalized.code) ?? code, ctxForAstro);
1432
+ if (normalized.needRemap) {
1433
+ remap(result, normalized, code, ctxForAstro);
1434
+ ctx.originalAST = ctxForAstro.originalAST;
1435
+ }
1436
+ const templateResult = {
1437
+ result,
1438
+ context: ctx
1439
+ };
1440
+ lruCache.set(code, templateResult);
1441
+ return templateResult;
1442
+ } catch (e) {
1443
+ if (typeof e.pos === "number") {
1444
+ const err = new ParseError(e.message, normalized == null ? void 0 : normalized.remapIndex(e.pos), ctx);
1445
+ err.astroCompilerError = e;
1446
+ throw err;
1447
+ }
1448
+ throw e;
1449
+ }
1450
+ }
1451
+ function remap(result, normalized, originalCode, ctxForAstro) {
1452
+ const remapDataMap = /* @__PURE__ */ new Map();
1453
+ walk(
1454
+ result.ast,
1455
+ normalized.code,
1456
+ (node) => {
1457
+ const start = normalized.remapIndex(node.position.start.offset);
1458
+ let end, value;
1459
+ if (node.position.end) {
1460
+ end = normalized.remapIndex(node.position.end.offset);
1461
+ if (node.position.start.offset === start && node.position.end.offset === end) {
1462
+ return;
1463
+ }
1464
+ }
1465
+ if (node.type === "text") {
1466
+ value = originalCode.slice(
1467
+ start,
1468
+ normalized.remapIndex(getEndOffset(node, ctxForAstro))
1469
+ );
1470
+ } else if (node.type === "comment") {
1471
+ value = originalCode.slice(
1472
+ start + 4,
1473
+ normalized.remapIndex(getEndOffset(node, ctxForAstro)) - 3
1474
+ );
1475
+ } else if (node.type === "attribute") {
1476
+ if (node.kind !== "empty" && node.kind !== "shorthand" && node.kind !== "spread") {
1477
+ let valueStart = normalized.remapIndex(
1478
+ calcAttributeValueStartOffset(node, ctxForAstro)
1479
+ );
1480
+ let valueEnd = normalized.remapIndex(
1481
+ calcAttributeEndOffset(node, ctxForAstro)
1482
+ );
1483
+ if (node.kind !== "quoted" || originalCode[valueStart] === '"' || originalCode[valueStart] === "'") {
1484
+ valueStart++;
1485
+ valueEnd--;
1486
+ }
1487
+ value = originalCode.slice(valueStart, valueEnd);
1488
+ }
1489
+ }
1490
+ remapDataMap.set(node, {
1491
+ start,
1492
+ end,
1493
+ value
1494
+ });
1495
+ },
1496
+ (_node) => {
1497
+ }
1498
+ );
1499
+ for (const [node, remapData] of remapDataMap) {
1500
+ node.position.start.offset = remapData.start;
1501
+ if (node.position.end) {
1502
+ node.position.end.offset = remapData.end;
1503
+ }
1504
+ if (node.type === "text" || node.type === "comment" || node.type === "attribute" && node.kind !== "empty" && node.kind !== "shorthand" && node.kind !== "spread") {
1505
+ node.value = remapData.value;
1506
+ }
1507
+ }
1508
+ }
1509
+
1510
+ // src/context/parser-options.ts
1511
+ import path3 from "path";
1512
+ import fs2 from "fs";
1513
+
1514
+ // src/context/resolve-parser/espree.ts
1515
+ import { createRequire as createRequire2 } from "module";
1516
+ import path2 from "path";
1517
+ var espreeCache = null;
1518
+ function isLinterPath(p) {
1519
+ return p.includes(`eslint${path2.sep}lib${path2.sep}linter${path2.sep}linter.js`) || p.includes(`eslint${path2.sep}lib${path2.sep}linter.js`);
1520
+ }
1521
+ function getEspree() {
1522
+ if (!espreeCache) {
1523
+ const linterPath = Object.keys(__require.cache || {}).find(isLinterPath);
1524
+ if (linterPath) {
1525
+ try {
1526
+ espreeCache = createRequire2(linterPath)("espree");
1527
+ } catch {
1528
+ }
1529
+ }
1530
+ if (!espreeCache) {
1531
+ espreeCache = __require("espree");
1532
+ }
1533
+ }
1534
+ return espreeCache;
1535
+ }
1536
+
1537
+ // src/context/resolve-parser/index.ts
1538
+ function getParserForLang(attrs, parser) {
1539
+ if (parser) {
1540
+ if (typeof parser === "string" || isParserObject(parser)) {
1541
+ return parser;
1542
+ }
1543
+ if (typeof parser === "object") {
1544
+ const value = parser[attrs.lang || "js"];
1545
+ if (typeof value === "string" || isParserObject(value)) {
1546
+ return value;
1547
+ }
1548
+ }
1549
+ }
1550
+ return "espree";
1551
+ }
1552
+ function getParser(attrs, parser) {
1553
+ const parserValue = getParserForLang(attrs, parser);
1554
+ if (isParserObject(parserValue)) {
1555
+ return parserValue;
1556
+ }
1557
+ if (parserValue !== "espree") {
1558
+ return __require(parserValue);
1559
+ }
1560
+ return getEspree();
1561
+ }
1562
+
1563
+ // src/context/parser-options.ts
1564
+ var ParserOptionsContext = class {
1565
+ constructor(options) {
1566
+ this.state = {};
1567
+ const parserOptions = {
1568
+ ecmaVersion: 2020,
1569
+ sourceType: "module",
1570
+ loc: true,
1571
+ range: true,
1572
+ raw: true,
1573
+ tokens: true,
1574
+ comment: true,
1575
+ eslintVisitorKeys: true,
1576
+ eslintScopeManager: true,
1577
+ ...options || {}
1578
+ };
1579
+ parserOptions.ecmaFeatures = {
1580
+ ...parserOptions.ecmaFeatures || {},
1581
+ jsx: true
1582
+ };
1583
+ parserOptions.sourceType = "module";
1584
+ if (parserOptions.ecmaVersion <= 5 || parserOptions.ecmaVersion == null) {
1585
+ parserOptions.ecmaVersion = 2015;
1586
+ }
1587
+ this.parserOptions = parserOptions;
1588
+ }
1589
+ getParser() {
1590
+ return getParser({}, this.parserOptions.parser);
1591
+ }
1592
+ isTypeScript() {
1593
+ var _a, _b;
1594
+ if (this.state.isTypeScript != null) {
1595
+ return this.state.isTypeScript;
1596
+ }
1597
+ const parserValue = getParserForLang({}, (_a = this.parserOptions) == null ? void 0 : _a.parser);
1598
+ if (maybeTSESLintParserObject(parserValue) || parserValue === "@typescript-eslint/parser") {
1599
+ return this.state.isTypeScript = true;
1600
+ }
1601
+ if (typeof parserValue !== "string") {
1602
+ return this.state.isTypeScript = false;
1603
+ }
1604
+ const parserName = parserValue;
1605
+ if (parserName.includes("@typescript-eslint/parser")) {
1606
+ let targetPath = parserName;
1607
+ while (targetPath) {
1608
+ const pkgPath = path3.join(targetPath, "package.json");
1609
+ if (fs2.existsSync(pkgPath)) {
1610
+ try {
1611
+ return this.state.isTypeScript = ((_b = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"))) == null ? void 0 : _b.name) === "@typescript-eslint/parser";
1612
+ } catch {
1613
+ return this.state.isTypeScript = false;
1614
+ }
1615
+ }
1616
+ const parent = path3.dirname(targetPath);
1617
+ if (targetPath === parent) {
1618
+ break;
1619
+ }
1620
+ targetPath = parent;
1621
+ }
1622
+ }
1623
+ return this.state.isTypeScript = false;
1624
+ }
1625
+ };
1626
+
1627
+ // src/parser/index.ts
1628
+ function parseForESLint(code, options) {
1629
+ const { result: resultTemplate, context: ctx } = parseTemplate(code);
1630
+ const scriptContext = processTemplate(ctx, resultTemplate);
1631
+ const parserOptions = new ParserOptionsContext(options);
1632
+ const resultScript = parseScript(scriptContext.script, ctx, parserOptions);
1633
+ scriptContext.restore(resultScript);
1634
+ sort(resultScript.ast.comments);
1635
+ sort(resultScript.ast.tokens);
1636
+ extractTokens(resultScript, ctx);
1637
+ resultScript.services = Object.assign(resultScript.services || {}, {
1638
+ isAstro: true,
1639
+ getAstroAst() {
1640
+ return resultTemplate.ast;
1641
+ }
1642
+ });
1643
+ resultScript.visitorKeys = Object.assign({}, KEYS, resultScript.visitorKeys);
1644
+ return resultScript;
1645
+ }
1646
+ function extractTokens(ast, ctx) {
1647
+ if (!ast.ast.tokens) {
1648
+ return;
1649
+ }
1650
+ const useRanges = sort([...ast.ast.tokens, ...ast.ast.comments || []]).map(
1651
+ (t) => t.range
1652
+ );
1653
+ let range = useRanges.shift();
1654
+ for (let index = 0; index < ctx.code.length; index++) {
1655
+ while (range && range[1] <= index) {
1656
+ range = useRanges.shift();
1657
+ }
1658
+ if (range && range[0] <= index) {
1659
+ index = range[1] - 1;
1660
+ continue;
1661
+ }
1662
+ const c = ctx.code[index];
1663
+ if (!c.trim()) {
1664
+ continue;
1665
+ }
1666
+ if (isPunctuator(c)) {
1667
+ ast.ast.tokens.push(
1668
+ ctx.buildToken(AST_TOKEN_TYPES2.Punctuator, [index, index + 1])
1669
+ );
1670
+ } else {
1671
+ ast.ast.tokens.push(
1672
+ ctx.buildToken(AST_TOKEN_TYPES2.Identifier, [index, index + 1])
1673
+ );
1674
+ }
1675
+ }
1676
+ sort(ast.ast.tokens);
1677
+ function isPunctuator(c) {
1678
+ return /^[^\w$]$/iu.test(c);
1679
+ }
1680
+ }
1681
+
1682
+ // src/astro-tools/index.ts
1683
+ function parseTemplate2(code) {
1684
+ const parsed = parseTemplate(code);
1685
+ return {
1686
+ result: parsed.result,
1687
+ getEndOffset: (node) => getEndOffset(node, parsed.context),
1688
+ calcAttributeValueStartOffset: (node) => calcAttributeValueStartOffset(node, parsed.context),
1689
+ calcAttributeEndOffset: (node) => calcAttributeEndOffset(node, parsed.context),
1690
+ walk(parent, enter, leave) {
1691
+ walk(
1692
+ parent,
1693
+ code,
1694
+ enter,
1695
+ leave || (() => {
1696
+ })
1697
+ );
1698
+ },
1699
+ getLocFromIndex: (index) => parsed.context.getLocFromIndex(index),
1700
+ getIndexFromLoc: (loc) => parsed.context.locs.getIndexFromLoc(loc)
1701
+ };
1702
+ }
1703
+
1704
+ // src/ast/index.ts
1705
+ var ast_exports = {};
1706
+
1707
+ // src/index.ts
1708
+ function parseForESLint2(code, options) {
1709
+ return parseForESLint(code, options);
1710
+ }
1711
+ var VisitorKeys = KEYS;
1712
+ export {
1713
+ ast_exports as AST,
1714
+ ParseError,
1715
+ VisitorKeys,
1716
+ parseForESLint2 as parseForESLint,
1717
+ parseTemplate2 as parseTemplate,
1718
+ traverseNodes
1719
+ };