@wsxjs/wsx-vite-plugin 0.0.14 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -115,8 +115,12 @@ function babelPluginWSXState() {
115
115
  if (isUndefined) {
116
116
  const originalSource2 = path.state?.originalSource;
117
117
  if (originalSource2) {
118
+ const escapedPropertyName = propertyName.replace(
119
+ /[.*+?^${}()|[\]\\]/g,
120
+ "\\$&"
121
+ );
118
122
  const propertyPattern = new RegExp(
119
- `@state\\s+(?:private|protected|public)?\\s+${propertyName}\\s*[?;]`,
123
+ `@state\\s+(?:private|protected|public)?\\s+${escapedPropertyName}\\s*[?;]`,
120
124
  "m"
121
125
  );
122
126
  if (propertyPattern.test(originalSource2)) {
@@ -156,8 +160,12 @@ Fix: Change to '@state private ${propertyName} = undefined;' or provide a real i
156
160
  }
157
161
  const originalSource = path.state?.originalSource;
158
162
  if (originalSource) {
163
+ const escapedPropertyName = propertyName.replace(
164
+ /[.*+?^${}()|[\]\\]/g,
165
+ "\\$&"
166
+ );
159
167
  const propertyPattern = new RegExp(
160
- `@state\\s+(?:private|protected|public)?\\s+${propertyName}\\s*[?;]`,
168
+ `@state\\s+(?:private|protected|public)?\\s+${escapedPropertyName}\\s*[?;]`,
161
169
  "m"
162
170
  );
163
171
  const hasStateInSource = propertyPattern.test(originalSource);
@@ -166,7 +174,7 @@ Fix: Change to '@state private ${propertyName} = undefined;' or provide a real i
166
174
  `[Babel Plugin WSX State] Found @state in source for property '${propertyName}' (decorators array was empty: ${decoratorCount})`
167
175
  );
168
176
  const hasInitialValueInSource = new RegExp(
169
- `@state\\s+(?:private|protected|public)?\\s+${propertyName}\\s*=\\s*[^;]+`,
177
+ `@state\\s+(?:private|protected|public)?\\s+${escapedPropertyName}\\s*=\\s*[^;]+`,
170
178
  "m"
171
179
  ).test(originalSource);
172
180
  if (!hasInitialValueInSource) {
@@ -218,17 +226,15 @@ Fix: Change to '@state private ${propertyName} = undefined;' or provide a real i
218
226
  }
219
227
  let hasStateDecorator = false;
220
228
  try {
221
- hasStateDecorator = member.decorators?.some(
222
- (decorator) => {
223
- if (decorator.expression.type === "Identifier" && decorator.expression.name === "state") {
224
- return true;
225
- }
226
- if (decorator.expression.type === "CallExpression" && decorator.expression.callee.type === "Identifier" && decorator.expression.callee.name === "state") {
227
- return true;
228
- }
229
- return false;
229
+ hasStateDecorator = member.decorators?.some((decorator) => {
230
+ if (decorator.expression.type === "Identifier" && decorator.expression.name === "state") {
231
+ return true;
232
+ }
233
+ if (decorator.expression.type === "CallExpression" && decorator.expression.callee.type === "Identifier" && decorator.expression.callee.name === "state") {
234
+ return true;
230
235
  }
231
- ) || false;
236
+ return false;
237
+ }) || false;
232
238
  } catch (error) {
233
239
  console.error(
234
240
  `[Babel Plugin WSX State] ERROR in hasStateDecorator check for ${propertyName}: ${error}`
@@ -261,7 +267,9 @@ Current code: @state private ${key};
261
267
 
262
268
  This error should be caught during build time. If you see this at runtime, it means the Babel plugin did not process this file.`
263
269
  );
264
- console.error(`[Babel Plugin WSX State] ERROR: ${error.message}`);
270
+ console.error(
271
+ `[Babel Plugin WSX State] ERROR: ${error.message}`
272
+ );
265
273
  throw error;
266
274
  }
267
275
  const initialValue = member.value;
@@ -668,8 +676,9 @@ function findComponentName(path) {
668
676
  let classPath = path;
669
677
  while (classPath) {
670
678
  if (classPath.isClassDeclaration()) {
671
- if (classPath.node.id && tModule3.isIdentifier(classPath.node.id)) {
672
- return classPath.node.id.name;
679
+ const classNode = classPath.node;
680
+ if (classNode.id && tModule3.isIdentifier(classNode.id)) {
681
+ return classNode.id.name;
673
682
  }
674
683
  break;
675
684
  }
@@ -755,99 +764,95 @@ function vitePluginWSXWithBabel(options = {}) {
755
764
  `;
756
765
  transformedCode = importStatement + transformedCode;
757
766
  }
758
- try {
759
- const babelResult = (0, import_core.transformSync)(transformedCode, {
760
- filename: id,
761
- // Pass the actual filename so Babel knows it's .wsx
762
- // CRITICAL: Configure parser to preserve decorators
763
- // @babel/preset-typescript should preserve decorators by default,
764
- // but we explicitly enable decorator parsing to be sure
765
- parserOpts: {
766
- plugins: [
767
- ["decorators", { decoratorsBeforeExport: true }],
768
- // Stage 3 decorators
769
- "typescript",
770
- "jsx"
771
- ]
772
- },
773
- presets: [
767
+ const babelResult = (0, import_core.transformSync)(transformedCode, {
768
+ filename: id,
769
+ // Pass the actual filename so Babel knows it's .wsx
770
+ // CRITICAL: Configure parser to preserve decorators
771
+ // @babel/preset-typescript should preserve decorators by default,
772
+ // but we explicitly enable decorator parsing to be sure
773
+ parserOpts: {
774
+ plugins: [
775
+ ["decorators", { decoratorsBeforeExport: true }],
776
+ // Stage 3 decorators
777
+ "typescript",
778
+ "jsx"
779
+ ]
780
+ },
781
+ presets: [
782
+ [
783
+ "@babel/preset-typescript",
784
+ {
785
+ isTSX: true,
786
+ // Enable JSX syntax
787
+ allExtensions: true,
788
+ // Process all extensions, including .wsx
789
+ // CRITICAL: onlyRemoveTypeImports only affects import statements
790
+ // Decorators are preserved by default in @babel/preset-typescript
791
+ // They are only removed if we explicitly configure it
792
+ onlyRemoveTypeImports: false
793
+ // Remove all type-only imports
794
+ }
795
+ ]
796
+ ],
797
+ plugins: [
798
+ // CRITICAL: Decorator plugin must run FIRST to parse decorators correctly
799
+ // This ensures decorators are properly parsed before our custom plugins try to process them
800
+ // However, we need to use a custom visitor that doesn't transform decorators yet
801
+ // Actually, we should NOT run decorator plugin first because it transforms decorators
802
+ // Instead, we rely on TypeScript preset to parse but not transform decorators
803
+ // CRITICAL: Style injection plugin must run FIRST
804
+ // This ensures _autoStyles property exists before state transformations
805
+ ...autoStyleInjection && cssFileExists ? [
774
806
  [
775
- "@babel/preset-typescript",
807
+ babelPluginWSXStyle,
776
808
  {
777
- isTSX: true,
778
- // Enable JSX syntax
779
- allExtensions: true,
780
- // Process all extensions, including .wsx
781
- // CRITICAL: onlyRemoveTypeImports only affects import statements
782
- // Decorators are preserved by default in @babel/preset-typescript
783
- // They are only removed if we explicitly configure it
784
- onlyRemoveTypeImports: false
785
- // Remove all type-only imports
809
+ cssFileExists,
810
+ cssFilePath,
811
+ componentName
786
812
  }
787
813
  ]
814
+ ] : [],
815
+ // Focus key generation plugin runs early to add data-wsx-key attributes
816
+ // This must run before JSX is transformed to h() calls
817
+ babelPluginWSXFocus,
818
+ // CRITICAL: State decorator transformation must run BEFORE @babel/plugin-proposal-decorators
819
+ // This allows the plugin to detect @state decorators in their original form and throw errors if needed
820
+ // The plugin removes @state decorators after processing, so the decorator plugin won't see them
821
+ [
822
+ babelPluginWSXState,
823
+ {
824
+ // Pass ORIGINAL source code (before JSX import injection) to plugin
825
+ // This ensures we can detect @state decorators even if they're removed by TypeScript preset
826
+ originalSource: code
827
+ // Use original code, not transformedCode
828
+ }
788
829
  ],
789
- plugins: [
790
- // CRITICAL: Decorator plugin must run FIRST to parse decorators correctly
791
- // This ensures decorators are properly parsed before our custom plugins try to process them
792
- // However, we need to use a custom visitor that doesn't transform decorators yet
793
- // Actually, we should NOT run decorator plugin first because it transforms decorators
794
- // Instead, we rely on TypeScript preset to parse but not transform decorators
795
- // CRITICAL: Style injection plugin must run FIRST
796
- // This ensures _autoStyles property exists before state transformations
797
- ...autoStyleInjection && cssFileExists ? [
798
- [
799
- babelPluginWSXStyle,
800
- {
801
- cssFileExists,
802
- cssFilePath,
803
- componentName
804
- }
805
- ]
806
- ] : [],
807
- // Focus key generation plugin runs early to add data-wsx-key attributes
808
- // This must run before JSX is transformed to h() calls
809
- babelPluginWSXFocus,
810
- // CRITICAL: State decorator transformation must run BEFORE @babel/plugin-proposal-decorators
811
- // This allows the plugin to detect @state decorators in their original form and throw errors if needed
812
- // The plugin removes @state decorators after processing, so the decorator plugin won't see them
813
- [
814
- babelPluginWSXState,
815
- {
816
- // Pass ORIGINAL source code (before JSX import injection) to plugin
817
- // This ensures we can detect @state decorators even if they're removed by TypeScript preset
818
- originalSource: code
819
- // Use original code, not transformedCode
820
- }
821
- ],
822
- // Decorator plugin runs after our custom plugins
823
- // This transforms remaining decorators (like @autoRegister) to runtime calls
824
- [
825
- "@babel/plugin-proposal-decorators",
826
- {
827
- version: "2023-05",
828
- decoratorsBeforeExport: true
829
- }
830
- ],
831
- [
832
- "@babel/plugin-proposal-class-properties",
833
- {
834
- loose: false
835
- }
836
- ],
837
- "@babel/plugin-transform-class-static-block"
838
- // Support static class blocks
839
- ]
840
- // parserOpts not needed - @babel/preset-typescript and plugins handle it
841
- });
842
- if (babelResult && babelResult.code) {
843
- transformedCode = babelResult.code;
844
- } else {
845
- throw new Error(
846
- `[WSX Plugin] Babel transform returned no code for ${id}. @state decorators will NOT be processed and will cause runtime errors. Please check Babel configuration and plugin setup.`
847
- );
848
- }
849
- } catch (error) {
850
- throw error;
830
+ // Decorator plugin runs after our custom plugins
831
+ // This transforms remaining decorators (like @autoRegister) to runtime calls
832
+ [
833
+ "@babel/plugin-proposal-decorators",
834
+ {
835
+ version: "2023-05",
836
+ decoratorsBeforeExport: true
837
+ }
838
+ ],
839
+ [
840
+ "@babel/plugin-proposal-class-properties",
841
+ {
842
+ loose: false
843
+ }
844
+ ],
845
+ "@babel/plugin-transform-class-static-block"
846
+ // Support static class blocks
847
+ ]
848
+ // parserOpts not needed - @babel/preset-typescript and plugins handle it
849
+ });
850
+ if (babelResult && babelResult.code) {
851
+ transformedCode = babelResult.code;
852
+ } else {
853
+ throw new Error(
854
+ `[WSX Plugin] Babel transform returned no code for ${id}. @state decorators will NOT be processed and will cause runtime errors. Please check Babel configuration and plugin setup.`
855
+ );
851
856
  }
852
857
  const hasJSXAfterBabel = transformedCode.includes('from "@wsxjs/wsx-core"') && (new RegExp(`[{,]\\s*${jsxFactory}\\s*[},]`).test(transformedCode) || new RegExp(`[{,]\\s*${jsxFragment}\\s*[},]`).test(transformedCode));
853
858
  if ((transformedCode.includes("<") || transformedCode.includes("Fragment")) && !hasJSXAfterBabel) {
package/dist/index.mjs CHANGED
@@ -79,8 +79,12 @@ function babelPluginWSXState() {
79
79
  if (isUndefined) {
80
80
  const originalSource2 = path.state?.originalSource;
81
81
  if (originalSource2) {
82
+ const escapedPropertyName = propertyName.replace(
83
+ /[.*+?^${}()|[\]\\]/g,
84
+ "\\$&"
85
+ );
82
86
  const propertyPattern = new RegExp(
83
- `@state\\s+(?:private|protected|public)?\\s+${propertyName}\\s*[?;]`,
87
+ `@state\\s+(?:private|protected|public)?\\s+${escapedPropertyName}\\s*[?;]`,
84
88
  "m"
85
89
  );
86
90
  if (propertyPattern.test(originalSource2)) {
@@ -120,8 +124,12 @@ Fix: Change to '@state private ${propertyName} = undefined;' or provide a real i
120
124
  }
121
125
  const originalSource = path.state?.originalSource;
122
126
  if (originalSource) {
127
+ const escapedPropertyName = propertyName.replace(
128
+ /[.*+?^${}()|[\]\\]/g,
129
+ "\\$&"
130
+ );
123
131
  const propertyPattern = new RegExp(
124
- `@state\\s+(?:private|protected|public)?\\s+${propertyName}\\s*[?;]`,
132
+ `@state\\s+(?:private|protected|public)?\\s+${escapedPropertyName}\\s*[?;]`,
125
133
  "m"
126
134
  );
127
135
  const hasStateInSource = propertyPattern.test(originalSource);
@@ -130,7 +138,7 @@ Fix: Change to '@state private ${propertyName} = undefined;' or provide a real i
130
138
  `[Babel Plugin WSX State] Found @state in source for property '${propertyName}' (decorators array was empty: ${decoratorCount})`
131
139
  );
132
140
  const hasInitialValueInSource = new RegExp(
133
- `@state\\s+(?:private|protected|public)?\\s+${propertyName}\\s*=\\s*[^;]+`,
141
+ `@state\\s+(?:private|protected|public)?\\s+${escapedPropertyName}\\s*=\\s*[^;]+`,
134
142
  "m"
135
143
  ).test(originalSource);
136
144
  if (!hasInitialValueInSource) {
@@ -182,17 +190,15 @@ Fix: Change to '@state private ${propertyName} = undefined;' or provide a real i
182
190
  }
183
191
  let hasStateDecorator = false;
184
192
  try {
185
- hasStateDecorator = member.decorators?.some(
186
- (decorator) => {
187
- if (decorator.expression.type === "Identifier" && decorator.expression.name === "state") {
188
- return true;
189
- }
190
- if (decorator.expression.type === "CallExpression" && decorator.expression.callee.type === "Identifier" && decorator.expression.callee.name === "state") {
191
- return true;
192
- }
193
- return false;
193
+ hasStateDecorator = member.decorators?.some((decorator) => {
194
+ if (decorator.expression.type === "Identifier" && decorator.expression.name === "state") {
195
+ return true;
196
+ }
197
+ if (decorator.expression.type === "CallExpression" && decorator.expression.callee.type === "Identifier" && decorator.expression.callee.name === "state") {
198
+ return true;
194
199
  }
195
- ) || false;
200
+ return false;
201
+ }) || false;
196
202
  } catch (error) {
197
203
  console.error(
198
204
  `[Babel Plugin WSX State] ERROR in hasStateDecorator check for ${propertyName}: ${error}`
@@ -225,7 +231,9 @@ Current code: @state private ${key};
225
231
 
226
232
  This error should be caught during build time. If you see this at runtime, it means the Babel plugin did not process this file.`
227
233
  );
228
- console.error(`[Babel Plugin WSX State] ERROR: ${error.message}`);
234
+ console.error(
235
+ `[Babel Plugin WSX State] ERROR: ${error.message}`
236
+ );
229
237
  throw error;
230
238
  }
231
239
  const initialValue = member.value;
@@ -632,8 +640,9 @@ function findComponentName(path) {
632
640
  let classPath = path;
633
641
  while (classPath) {
634
642
  if (classPath.isClassDeclaration()) {
635
- if (classPath.node.id && tModule3.isIdentifier(classPath.node.id)) {
636
- return classPath.node.id.name;
643
+ const classNode = classPath.node;
644
+ if (classNode.id && tModule3.isIdentifier(classNode.id)) {
645
+ return classNode.id.name;
637
646
  }
638
647
  break;
639
648
  }
@@ -719,99 +728,95 @@ function vitePluginWSXWithBabel(options = {}) {
719
728
  `;
720
729
  transformedCode = importStatement + transformedCode;
721
730
  }
722
- try {
723
- const babelResult = transformSync(transformedCode, {
724
- filename: id,
725
- // Pass the actual filename so Babel knows it's .wsx
726
- // CRITICAL: Configure parser to preserve decorators
727
- // @babel/preset-typescript should preserve decorators by default,
728
- // but we explicitly enable decorator parsing to be sure
729
- parserOpts: {
730
- plugins: [
731
- ["decorators", { decoratorsBeforeExport: true }],
732
- // Stage 3 decorators
733
- "typescript",
734
- "jsx"
735
- ]
736
- },
737
- presets: [
731
+ const babelResult = transformSync(transformedCode, {
732
+ filename: id,
733
+ // Pass the actual filename so Babel knows it's .wsx
734
+ // CRITICAL: Configure parser to preserve decorators
735
+ // @babel/preset-typescript should preserve decorators by default,
736
+ // but we explicitly enable decorator parsing to be sure
737
+ parserOpts: {
738
+ plugins: [
739
+ ["decorators", { decoratorsBeforeExport: true }],
740
+ // Stage 3 decorators
741
+ "typescript",
742
+ "jsx"
743
+ ]
744
+ },
745
+ presets: [
746
+ [
747
+ "@babel/preset-typescript",
748
+ {
749
+ isTSX: true,
750
+ // Enable JSX syntax
751
+ allExtensions: true,
752
+ // Process all extensions, including .wsx
753
+ // CRITICAL: onlyRemoveTypeImports only affects import statements
754
+ // Decorators are preserved by default in @babel/preset-typescript
755
+ // They are only removed if we explicitly configure it
756
+ onlyRemoveTypeImports: false
757
+ // Remove all type-only imports
758
+ }
759
+ ]
760
+ ],
761
+ plugins: [
762
+ // CRITICAL: Decorator plugin must run FIRST to parse decorators correctly
763
+ // This ensures decorators are properly parsed before our custom plugins try to process them
764
+ // However, we need to use a custom visitor that doesn't transform decorators yet
765
+ // Actually, we should NOT run decorator plugin first because it transforms decorators
766
+ // Instead, we rely on TypeScript preset to parse but not transform decorators
767
+ // CRITICAL: Style injection plugin must run FIRST
768
+ // This ensures _autoStyles property exists before state transformations
769
+ ...autoStyleInjection && cssFileExists ? [
738
770
  [
739
- "@babel/preset-typescript",
771
+ babelPluginWSXStyle,
740
772
  {
741
- isTSX: true,
742
- // Enable JSX syntax
743
- allExtensions: true,
744
- // Process all extensions, including .wsx
745
- // CRITICAL: onlyRemoveTypeImports only affects import statements
746
- // Decorators are preserved by default in @babel/preset-typescript
747
- // They are only removed if we explicitly configure it
748
- onlyRemoveTypeImports: false
749
- // Remove all type-only imports
773
+ cssFileExists,
774
+ cssFilePath,
775
+ componentName
750
776
  }
751
777
  ]
778
+ ] : [],
779
+ // Focus key generation plugin runs early to add data-wsx-key attributes
780
+ // This must run before JSX is transformed to h() calls
781
+ babelPluginWSXFocus,
782
+ // CRITICAL: State decorator transformation must run BEFORE @babel/plugin-proposal-decorators
783
+ // This allows the plugin to detect @state decorators in their original form and throw errors if needed
784
+ // The plugin removes @state decorators after processing, so the decorator plugin won't see them
785
+ [
786
+ babelPluginWSXState,
787
+ {
788
+ // Pass ORIGINAL source code (before JSX import injection) to plugin
789
+ // This ensures we can detect @state decorators even if they're removed by TypeScript preset
790
+ originalSource: code
791
+ // Use original code, not transformedCode
792
+ }
752
793
  ],
753
- plugins: [
754
- // CRITICAL: Decorator plugin must run FIRST to parse decorators correctly
755
- // This ensures decorators are properly parsed before our custom plugins try to process them
756
- // However, we need to use a custom visitor that doesn't transform decorators yet
757
- // Actually, we should NOT run decorator plugin first because it transforms decorators
758
- // Instead, we rely on TypeScript preset to parse but not transform decorators
759
- // CRITICAL: Style injection plugin must run FIRST
760
- // This ensures _autoStyles property exists before state transformations
761
- ...autoStyleInjection && cssFileExists ? [
762
- [
763
- babelPluginWSXStyle,
764
- {
765
- cssFileExists,
766
- cssFilePath,
767
- componentName
768
- }
769
- ]
770
- ] : [],
771
- // Focus key generation plugin runs early to add data-wsx-key attributes
772
- // This must run before JSX is transformed to h() calls
773
- babelPluginWSXFocus,
774
- // CRITICAL: State decorator transformation must run BEFORE @babel/plugin-proposal-decorators
775
- // This allows the plugin to detect @state decorators in their original form and throw errors if needed
776
- // The plugin removes @state decorators after processing, so the decorator plugin won't see them
777
- [
778
- babelPluginWSXState,
779
- {
780
- // Pass ORIGINAL source code (before JSX import injection) to plugin
781
- // This ensures we can detect @state decorators even if they're removed by TypeScript preset
782
- originalSource: code
783
- // Use original code, not transformedCode
784
- }
785
- ],
786
- // Decorator plugin runs after our custom plugins
787
- // This transforms remaining decorators (like @autoRegister) to runtime calls
788
- [
789
- "@babel/plugin-proposal-decorators",
790
- {
791
- version: "2023-05",
792
- decoratorsBeforeExport: true
793
- }
794
- ],
795
- [
796
- "@babel/plugin-proposal-class-properties",
797
- {
798
- loose: false
799
- }
800
- ],
801
- "@babel/plugin-transform-class-static-block"
802
- // Support static class blocks
803
- ]
804
- // parserOpts not needed - @babel/preset-typescript and plugins handle it
805
- });
806
- if (babelResult && babelResult.code) {
807
- transformedCode = babelResult.code;
808
- } else {
809
- throw new Error(
810
- `[WSX Plugin] Babel transform returned no code for ${id}. @state decorators will NOT be processed and will cause runtime errors. Please check Babel configuration and plugin setup.`
811
- );
812
- }
813
- } catch (error) {
814
- throw error;
794
+ // Decorator plugin runs after our custom plugins
795
+ // This transforms remaining decorators (like @autoRegister) to runtime calls
796
+ [
797
+ "@babel/plugin-proposal-decorators",
798
+ {
799
+ version: "2023-05",
800
+ decoratorsBeforeExport: true
801
+ }
802
+ ],
803
+ [
804
+ "@babel/plugin-proposal-class-properties",
805
+ {
806
+ loose: false
807
+ }
808
+ ],
809
+ "@babel/plugin-transform-class-static-block"
810
+ // Support static class blocks
811
+ ]
812
+ // parserOpts not needed - @babel/preset-typescript and plugins handle it
813
+ });
814
+ if (babelResult && babelResult.code) {
815
+ transformedCode = babelResult.code;
816
+ } else {
817
+ throw new Error(
818
+ `[WSX Plugin] Babel transform returned no code for ${id}. @state decorators will NOT be processed and will cause runtime errors. Please check Babel configuration and plugin setup.`
819
+ );
815
820
  }
816
821
  const hasJSXAfterBabel = transformedCode.includes('from "@wsxjs/wsx-core"') && (new RegExp(`[{,]\\s*${jsxFactory}\\s*[},]`).test(transformedCode) || new RegExp(`[{,]\\s*${jsxFragment}\\s*[},]`).test(transformedCode));
817
822
  if ((transformedCode.includes("<") || transformedCode.includes("Fragment")) && !hasJSXAfterBabel) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wsxjs/wsx-vite-plugin",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Vite plugin for WSX Framework",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -31,7 +31,7 @@
31
31
  "@babel/plugin-transform-class-static-block": "^7.28.0",
32
32
  "@babel/preset-typescript": "^7.28.5",
33
33
  "@babel/types": "^7.28.1",
34
- "@wsxjs/wsx-core": "0.0.14"
34
+ "@wsxjs/wsx-core": "0.0.16"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@babel/traverse": "^7.28.5",
@@ -138,13 +138,14 @@ function calculateJSXPath(path: NodePath<t.JSXOpeningElement>): number[] {
138
138
  * Find component name from class declaration
139
139
  */
140
140
  function findComponentName(path: NodePath<t.JSXOpeningElement>): string {
141
- let classPath = path;
141
+ let classPath: NodePath<t.Node> | null = path;
142
142
 
143
143
  // Find parent class declaration
144
144
  while (classPath) {
145
145
  if (classPath.isClassDeclaration()) {
146
- if (classPath.node.id && tModule.isIdentifier(classPath.node.id)) {
147
- return classPath.node.id.name;
146
+ const classNode = classPath.node;
147
+ if (classNode.id && tModule.isIdentifier(classNode.id)) {
148
+ return classNode.id.name;
148
149
  }
149
150
  break;
150
151
  }