@prover-coder-ai/component-tagger 1.0.25 → 1.0.26

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.
@@ -1,3 +1,18 @@
1
+ /**
2
+ * Normalizes a module ID by stripping query parameters.
3
+ *
4
+ * Vite and other bundlers may append query parameters to module IDs
5
+ * (e.g., "src/App.tsx?import" or "src/App.tsx?v=123"). This function
6
+ * returns the clean file path without query string.
7
+ *
8
+ * @param id - Module ID (may include query parameters).
9
+ * @returns Clean path without query string.
10
+ *
11
+ * @pure true
12
+ * @invariant ∀ id: normalizeModuleId(id) does not contain '?'
13
+ * @complexity O(n) time / O(1) space where n = |id|
14
+ */
15
+ export declare const normalizeModuleId: (id: string) => string;
1
16
  export declare const componentPathAttributeName = "data-path";
2
17
  /**
3
18
  * Checks whether the Vite id represents a JSX or TSX module.
@@ -1,4 +1,32 @@
1
1
  const jsxFilePattern = /\.(tsx|jsx)(\?.*)?$/u;
2
+ /**
3
+ * Normalizes a module ID by stripping query parameters.
4
+ *
5
+ * Vite and other bundlers may append query parameters to module IDs
6
+ * (e.g., "src/App.tsx?import" or "src/App.tsx?v=123"). This function
7
+ * returns the clean file path without query string.
8
+ *
9
+ * @param id - Module ID (may include query parameters).
10
+ * @returns Clean path without query string.
11
+ *
12
+ * @pure true
13
+ * @invariant ∀ id: normalizeModuleId(id) does not contain '?'
14
+ * @complexity O(n) time / O(1) space where n = |id|
15
+ */
16
+ // CHANGE: centralize query stripping as a pure function in core.
17
+ // WHY: unify module ID normalization in one place as requested in issue #18.
18
+ // QUOTE(ТЗ): "Вынести stripQuery() (или normalizeModuleId()) в core, использовать в Vite и (при желании) в isJsxFile."
19
+ // REF: REQ-18 (issue #18)
20
+ // SOURCE: n/a
21
+ // FORMAT THEOREM: ∀ id: normalizeModuleId(id) = id.split('?')[0]
22
+ // PURITY: CORE
23
+ // EFFECT: n/a
24
+ // INVARIANT: result contains no query string
25
+ // COMPLEXITY: O(n)/O(1)
26
+ export const normalizeModuleId = (id) => {
27
+ const queryIndex = id.indexOf("?");
28
+ return queryIndex === -1 ? id : id.slice(0, queryIndex);
29
+ };
2
30
  // CHANGE: rename attribute from "path" to "data-path" for HTML5 compliance.
3
31
  // WHY: data-* attributes are standard HTML5 custom data attributes, improving compatibility.
4
32
  // QUOTE(issue-14): "Rename attribute path → data-path (breaking change)"
@@ -22,7 +50,7 @@ export const componentPathAttributeName = "data-path";
22
50
  */
23
51
  // CHANGE: centralize JSX file detection as a pure predicate.
24
52
  // WHY: keep file filtering in the functional core for testability.
25
- // QUOTE(TZ): "\u0421\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c app \u043d\u043e \u0432\u043e\u0442 \u0447\u0442\u043e \u0431\u044b \u0435\u0433\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0435\u043a\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0448 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0430\u043f\u043f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c"
53
+ // QUOTE(TZ): "Сам компонент должен быть в текущем app но вот что бы его протестировать надо создать ещё один проект который наш текущий апп будет подключать"
26
54
  // REF: user-2026-01-14-frontend-consumer
27
55
  // SOURCE: n/a
28
56
  // FORMAT THEOREM: forall id in ModuleId: isJsxFile(id) -> matches(id, jsxFilePattern)
@@ -45,7 +73,7 @@ export const isJsxFile = (id) => jsxFilePattern.test(id);
45
73
  */
46
74
  // CHANGE: provide a pure formatter for component location payloads.
47
75
  // WHY: reuse a single, deterministic encoding for UI metadata.
48
- // QUOTE(TZ): "\u0421\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c app \u043d\u043e \u0432\u043e\u0442 \u0447\u0442\u043e \u0431\u044b \u0435\u0433\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0435\u043a\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0448 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0430\u043f\u043f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c"
76
+ // QUOTE(TZ): "Сам компонент должен быть в текущем app но вот что бы его протестировать надо создать ещё один проект который наш текущий апп будет подключать"
49
77
  // REF: user-2026-01-14-frontend-consumer
50
78
  // SOURCE: n/a
51
79
  // FORMAT THEOREM: forall p,l,c: formatComponentPathValue(p,l,c) = concat(p, ":", l, ":", c)
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { componentPathAttributeName, formatComponentPathValue, isJsxFile } from "./core/component-path.js";
1
+ export { componentPathAttributeName, formatComponentPathValue, isJsxFile, normalizeModuleId } from "./core/component-path.js";
2
2
  export { attrExists, createJsxTaggerVisitor, createPathAttribute, type JsxTaggerContext, processJsxElement } from "./core/jsx-tagger.js";
3
3
  export { componentTaggerBabelPlugin, type ComponentTaggerBabelPluginOptions } from "./shell/babel-plugin.js";
4
4
  export { componentTagger, type ComponentTaggerOptions } from "./shell/component-tagger.js";
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  // EFFECT: n/a
9
9
  // INVARIANT: exports remain stable for consumers
10
10
  // COMPLEXITY: O(1)/O(1)
11
- export { componentPathAttributeName, formatComponentPathValue, isJsxFile } from "./core/component-path.js";
11
+ export { componentPathAttributeName, formatComponentPathValue, isJsxFile, normalizeModuleId } from "./core/component-path.js";
12
12
  export { attrExists, createJsxTaggerVisitor, createPathAttribute, processJsxElement } from "./core/jsx-tagger.js";
13
13
  export { componentTaggerBabelPlugin } from "./shell/babel-plugin.js";
14
14
  export { componentTagger } from "./shell/component-tagger.js";
@@ -1,6 +1,6 @@
1
1
  import { transformAsync, types as t } from "@babel/core";
2
2
  import { Effect, pipe } from "effect";
3
- import { componentPathAttributeName, isJsxFile } from "../core/component-path.js";
3
+ import { componentPathAttributeName, isJsxFile, normalizeModuleId } from "../core/component-path.js";
4
4
  import { createJsxTaggerVisitor } from "../core/jsx-tagger.js";
5
5
  import { NodePathLayer, relativeFromRoot } from "../core/path-service.js";
6
6
  class ComponentTaggerError extends Error {
@@ -11,10 +11,6 @@ class ComponentTaggerError extends Error {
11
11
  this.cause = cause;
12
12
  }
13
13
  }
14
- const stripQuery = (id) => {
15
- const queryIndex = id.indexOf("?");
16
- return queryIndex === -1 ? id : id.slice(0, queryIndex);
17
- };
18
14
  const toViteResult = (result) => {
19
15
  if (result === null || result.code === null || result.code === undefined) {
20
16
  return null;
@@ -55,7 +51,7 @@ const makeBabelTagger = (relativeFilename, attributeName) => {
55
51
  // INVARIANT: errors are surfaced as ComponentTaggerError only
56
52
  // COMPLEXITY: O(n)/O(1)
57
53
  const runTransform = (code, id, rootDir, attributeName) => {
58
- const cleanId = stripQuery(id);
54
+ const cleanId = normalizeModuleId(id);
59
55
  return pipe(relativeFromRoot(rootDir, cleanId), Effect.flatMap((relative) => Effect.tryPromise({
60
56
  try: () => transformAsync(code, {
61
57
  filename: cleanId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prover-coder-ai/component-tagger",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "Component tagger Vite plugin and Babel plugin for JSX metadata",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",