swc-plugin-component-annotate 1.1.0 → 1.2.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.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SWC Plugin: React Component Annotate
1
+ # SWC Plugin: Component Annotate
2
2
 
3
3
  A SWC plugin that automatically annotates React components with data attributes for component tracking and debugging.
4
4
 
@@ -23,9 +23,9 @@ This plugin transforms React components by adding data attributes that help with
23
23
  ## Installation
24
24
 
25
25
  ```bash
26
- npm install --save-dev swc-plugin-react-component-annotate
26
+ npm install --save-dev swc-plugin-component-annotate
27
27
  # or
28
- yarn add -D swc-plugin-react-component-annotate
28
+ yarn add -D swc-plugin-component-annotate
29
29
  ```
30
30
 
31
31
  ## Usage
@@ -39,7 +39,7 @@ Add the plugin to your `.swcrc` configuration:
39
39
  "jsc": {
40
40
  "experimental": {
41
41
  "plugins": [
42
- ["swc-plugin-react-component-annotate", {}]
42
+ ["swc-plugin-component-annotate", {}]
43
43
  ]
44
44
  }
45
45
  }
@@ -53,7 +53,7 @@ Add the plugin to your `.swcrc` configuration:
53
53
  "jsc": {
54
54
  "experimental": {
55
55
  "plugins": [
56
- ["swc-plugin-react-component-annotate", {
56
+ ["swc-plugin-component-annotate", {
57
57
  "native": false,
58
58
  "annotate-fragments": false,
59
59
  "ignored-components": ["MyIgnoredComponent"],
@@ -92,7 +92,7 @@ To use Sentry-specific attribute names for compatibility with Sentry's tracking:
92
92
  "jsc": {
93
93
  "experimental": {
94
94
  "plugins": [
95
- ["swc-plugin-react-component-annotate", {
95
+ ["swc-plugin-component-annotate", {
96
96
  "component-attr": "data-sentry-component",
97
97
  "element-attr": "data-sentry-element",
98
98
  "source-file-attr": "data-sentry-source-file"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swc-plugin-component-annotate",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Use SWC to automatically annotate React components with data attributes for component tracking",
5
5
  "author": "scttcper <scttcper@gmail.com>",
6
6
  "license": "MIT",
package/src/lib.rs CHANGED
@@ -1,9 +1,11 @@
1
1
  pub mod config;
2
2
  mod constants;
3
3
  mod jsx_utils;
4
+ pub mod path_utils;
4
5
 
5
6
  use config::PluginConfig;
6
7
  use jsx_utils::*;
8
+ use path_utils::extract_filename;
7
9
  use rustc_hash::FxHashSet;
8
10
  use swc_core::{
9
11
  common::FileName,
@@ -14,22 +16,6 @@ use swc_core::{
14
16
  plugin::{plugin_transform, proxies::TransformPluginProgramMetadata},
15
17
  };
16
18
 
17
- // Macro to efficiently determine path separator and extract components
18
- macro_rules! path_info {
19
- ($path:expr) => {{
20
- let has_forward_slash = $path.contains('/');
21
- let has_backslash = $path.contains('\\');
22
-
23
- if has_forward_slash {
24
- (true, false, '/', $path.split('/'))
25
- } else if has_backslash {
26
- (false, true, '\\', $path.split('\\'))
27
- } else {
28
- (false, false, '/', $path.split('/')) // Default to forward slash for single component
29
- }
30
- }};
31
- }
32
-
33
19
  pub struct ReactComponentAnnotateVisitor {
34
20
  config: PluginConfig,
35
21
  source_file_name: Option<String>,
@@ -308,61 +294,6 @@ impl VisitMut for ReactComponentAnnotateVisitor {
308
294
  }
309
295
  }
310
296
 
311
- fn extract_filename(filename: &FileName) -> Option<String> {
312
- match filename {
313
- FileName::Real(path) => {
314
- if let Some(file_name) = path.file_name().and_then(|name| name.to_str()) {
315
- // Check if it's an index file
316
- if file_name.starts_with("index.") {
317
- // Get parent directory name and combine with filename
318
- if let Some(parent) = path
319
- .parent()
320
- .and_then(|p| p.file_name())
321
- .and_then(|n| n.to_str())
322
- {
323
- Some(format!("{}/{}", parent, file_name))
324
- } else {
325
- Some(file_name.to_string())
326
- }
327
- } else {
328
- Some(file_name.to_string())
329
- }
330
- } else {
331
- None
332
- }
333
- }
334
- FileName::Custom(custom) => {
335
- let (has_forward_slash, has_backslash, _separator, parts) = path_info!(custom);
336
- let parts_vec: Vec<&str> = parts.collect();
337
-
338
- let file_part = if has_forward_slash || has_backslash {
339
- parts_vec.last().copied().unwrap_or(custom)
340
- } else {
341
- custom
342
- };
343
-
344
- // Check if it's an index file
345
- if file_part.starts_with("index.") {
346
- // Extract parent directory from the full path
347
- let parent = if (has_forward_slash || has_backslash) && parts_vec.len() >= 2 {
348
- Some(parts_vec[parts_vec.len() - 2])
349
- } else {
350
- None
351
- };
352
-
353
- if let Some(parent_name) = parent {
354
- Some(format!("{}/{}", parent_name, file_part))
355
- } else {
356
- Some(file_part.to_string())
357
- }
358
- } else {
359
- Some(file_part.to_string())
360
- }
361
- }
362
- _ => None,
363
- }
364
- }
365
-
366
297
  // Export for testing
367
298
  pub fn extract_filename_for_test(filename: &FileName) -> Option<String> {
368
299
  extract_filename(filename)
@@ -0,0 +1,75 @@
1
+ use swc_core::common::FileName;
2
+
3
+ // Platform-specific path parsing functions
4
+ fn parse_unix_path(path: &str) -> Vec<&str> {
5
+ path.split('/').collect()
6
+ }
7
+
8
+ fn parse_windows_path(path: &str) -> Vec<&str> {
9
+ path.split('\\').collect()
10
+ }
11
+
12
+ // Fallback for mixed or unknown paths - checks the string content
13
+ fn parse_path_with_detection(path: &str) -> Vec<&str> {
14
+ if path.contains('\\') {
15
+ parse_windows_path(path)
16
+ } else {
17
+ parse_unix_path(path)
18
+ }
19
+ }
20
+
21
+ pub fn extract_filename(filename: &FileName) -> Option<String> {
22
+ match filename {
23
+ FileName::Real(path) => {
24
+ if let Some(file_name) = path.file_name().and_then(|name| name.to_str()) {
25
+ // Check if it's an index file
26
+ if file_name.starts_with("index.") {
27
+ // Get parent directory name and combine with filename
28
+ if let Some(parent) = path
29
+ .parent()
30
+ .and_then(|p| p.file_name())
31
+ .and_then(|n| n.to_str())
32
+ {
33
+ Some(format!("{}/{}", parent, file_name))
34
+ } else {
35
+ Some(file_name.to_string())
36
+ }
37
+ } else {
38
+ Some(file_name.to_string())
39
+ }
40
+ } else {
41
+ None
42
+ }
43
+ }
44
+ FileName::Custom(custom) => {
45
+ // Always use detection for Custom filenames since they can come from any platform
46
+ let parts = parse_path_with_detection(custom);
47
+
48
+ let file_part = if parts.len() > 1 {
49
+ parts.last().copied().unwrap_or(custom)
50
+ } else {
51
+ custom
52
+ };
53
+
54
+ // Check if it's an index file
55
+ if file_part.starts_with("index.") {
56
+ // Extract parent directory from the full path
57
+ let parent = if parts.len() >= 2 {
58
+ Some(parts[parts.len() - 2])
59
+ } else {
60
+ None
61
+ };
62
+
63
+ if let Some(parent_name) = parent {
64
+ // Always use forward slash in output for consistency
65
+ Some(format!("{}/{}", parent_name, file_part))
66
+ } else {
67
+ Some(file_part.to_string())
68
+ }
69
+ } else {
70
+ Some(file_part.to_string())
71
+ }
72
+ }
73
+ _ => None,
74
+ }
75
+ }
Binary file