@wuchale/astro 0.2.3 → 0.2.5

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.
@@ -6,15 +6,17 @@ import { Transformer } from 'wuchale/adapter-vanilla';
6
6
  export declare function parseExpr(content: string): [Estree.Expression, Estree.Comment[][]];
7
7
  type MixedAstroNodes = Node;
8
8
  export declare class AstroTransformer extends Transformer {
9
+ byteArray: Uint8Array;
9
10
  currentElement?: string;
10
11
  inCompoundText: boolean;
11
12
  frontMatterStart?: number;
12
13
  mixedVisitor: MixedVisitor<MixedAstroNodes>;
13
- correctedExprRanges: WeakMap<Node, {
14
+ correctedExprRanges: WeakMap<Node | AttributeNode, {
14
15
  start: number;
15
16
  end: number;
16
17
  }>;
17
18
  constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: CatalogExpr, rtConf: RuntimeConf, matchUrl: UrlMatcher);
19
+ _byteOffsetToIndex: (offset?: number) => number;
18
20
  _saveCorrectedExprRanges: (nodes: Node[], containerEnd: number) => void;
19
21
  getRange: (node: Node | AttributeNode) => {
20
22
  start: number;
@@ -12,7 +12,9 @@ export function parseExpr(content) {
12
12
  // Astro nodes that can have children
13
13
  const nodesWithChildren = ['element', 'component', 'custom-element', 'fragment'];
14
14
  const rtRenderFunc = '_w_Tx_';
15
+ const u8decoder = new TextDecoder();
15
16
  export class AstroTransformer extends Transformer {
17
+ byteArray;
16
18
  // state
17
19
  currentElement;
18
20
  inCompoundText = false;
@@ -23,38 +25,52 @@ export class AstroTransformer extends Transformer {
23
25
  constructor(content, filename, index, heuristic, patterns, catalogExpr, rtConf, matchUrl) {
24
26
  // trim() is VERY important, without it offset positions become wrong due to astro's parser
25
27
  super(content.trim(), filename, index, heuristic, patterns, catalogExpr, rtConf, matchUrl);
28
+ this.byteArray = new Uint8Array(Buffer.from(this.content));
26
29
  this.heuristciDetails.insideProgram = false;
27
30
  }
31
+ _byteOffsetToIndex = (offset) => {
32
+ // this is necessary because offsets come from astro's go parser, which works with bytes
33
+ // and that can cause misalignments when there are unicode characters
34
+ if (offset === undefined) {
35
+ return -1;
36
+ }
37
+ return u8decoder.decode(this.byteArray.slice(0, offset)).length;
38
+ };
28
39
  _saveCorrectedExprRanges = (nodes, containerEnd) => {
29
40
  for (const [i, child] of nodes.entries()) {
30
- if (child.type !== 'expression') {
41
+ const isExpr = child.type === 'expression';
42
+ const isMeta = child.type === 'element' && child.name === 'meta';
43
+ if (!(isExpr || isMeta)) {
31
44
  continue;
32
45
  }
46
+ let start = this._byteOffsetToIndex(child.position?.start?.offset);
47
+ if (isExpr) {
48
+ start = this.content.indexOf('{', start);
49
+ }
33
50
  const nextChild = nodes[i + 1];
34
- let actualEnd;
51
+ let end = this._byteOffsetToIndex(child.position?.end?.offset);
35
52
  if (nextChild != null) {
36
- actualEnd = nextChild.position?.start?.offset ?? 0;
53
+ end = this._byteOffsetToIndex(nextChild.position?.start?.offset);
37
54
  if (nextChild.type === 'expression') {
38
- actualEnd = this.content.indexOf('{', actualEnd);
55
+ end = this.content.indexOf('{', end);
39
56
  }
40
57
  }
41
58
  else {
42
- actualEnd = this.content.lastIndexOf('}', containerEnd) + 1;
59
+ const lookFor = isExpr ? '}' : '>';
60
+ end = this.content.lastIndexOf(lookFor, containerEnd) + lookFor.length;
43
61
  }
44
- this.correctedExprRanges.set(child, {
45
- start: this.content.indexOf('{', child.position?.start?.offset ?? 0),
46
- end: actualEnd,
47
- });
62
+ this.correctedExprRanges.set(child, { start, end });
48
63
  }
49
64
  };
50
65
  getRange = (node) => {
51
- if (node.type === 'expression') {
52
- return this.correctedExprRanges.get(node) ?? { start: -1, end: -1 };
66
+ const corrected = this.correctedExprRanges.get(node);
67
+ if (corrected) {
68
+ return corrected;
53
69
  }
54
70
  const { start, end } = node.position ?? {};
55
71
  return {
56
- start: start?.offset ?? -1,
57
- end: end?.offset ?? -1,
72
+ start: this._byteOffsetToIndex(start?.offset),
73
+ end: this._byteOffsetToIndex(end?.offset),
58
74
  };
59
75
  };
60
76
  initMixedVisitor = () => new MixedVisitor({
@@ -119,8 +135,14 @@ export class AstroTransformer extends Transformer {
119
135
  return msgs;
120
136
  };
121
137
  visitexpression = (node) => {
138
+ if (!node.children?.length) {
139
+ // can be undefined!
140
+ return [];
141
+ }
122
142
  let expr = '';
123
143
  const msgs = [];
144
+ const { start, end } = this.getRange(node);
145
+ this._saveCorrectedExprRanges(node.children, end);
124
146
  for (const part of node.children) {
125
147
  if (part.type === 'text') {
126
148
  expr += part.value;
@@ -130,7 +152,6 @@ export class AstroTransformer extends Transformer {
130
152
  const { start, end } = this.getRange(part);
131
153
  expr += `"${' '.repeat(end - start)}"`;
132
154
  }
133
- const { start } = this.getRange(node);
134
155
  msgs.push(...this._parseAndVisitExpr(expr, start + 1));
135
156
  return msgs;
136
157
  };
@@ -150,7 +171,8 @@ export class AstroTransformer extends Transformer {
150
171
  for (const attrib of node.attributes) {
151
172
  msgs.push(...this.visitAs(attrib));
152
173
  }
153
- this._saveCorrectedExprRanges(node.children, node.position?.end?.offset ?? 0);
174
+ const { end } = this.getRange(node);
175
+ this._saveCorrectedExprRanges(node.children, end);
154
176
  msgs.push(...this._visitChildren(node.children));
155
177
  this.currentElement = currentElement;
156
178
  return msgs;
@@ -208,7 +230,10 @@ export class AstroTransformer extends Transformer {
208
230
  this.frontMatterStart = this.content.indexOf('---', start) + 3;
209
231
  return this._parseAndVisitExpr(node.value, this.frontMatterStart, true);
210
232
  };
211
- visitroot = (node) => this._visitChildren(node.children ?? []); // can be undefined!
233
+ visitroot = (node) => {
234
+ this._saveCorrectedExprRanges(node.children, this.content.length);
235
+ return this._visitChildren(node.children ?? []); // can be undefined!
236
+ };
212
237
  visitAs = (node) => this.visit(node);
213
238
  transformAs = async () => {
214
239
  const { ast } = await parse(this.content);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wuchale/astro",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Wuchale i18n adapter for Astro files",
5
5
  "scripts": {
6
6
  "dev": "tsc --watch",
@@ -52,7 +52,7 @@
52
52
  "@sveltejs/acorn-typescript": "^1.0.8",
53
53
  "acorn": "^8.15.0",
54
54
  "magic-string": "^0.30.21",
55
- "wuchale": "^0.19.1"
55
+ "wuchale": "^0.19.2"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/estree-jsx": "^1.0.5",