@clicksmith/unplugin 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ClickSmith contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @clicksmith/unplugin
2
+
3
+ Dev-only `data-loc` injection so ClickSmith can resolve a clicked element back to
4
+ its **exact source file and line** — the strongest locator in the
5
+ `source → attr → behavioral → dom` ranking.
6
+
7
+ Built on [unplugin](https://github.com/unjs/unplugin), so it works across Vite,
8
+ Rollup, Webpack, Rspack, and esbuild from one implementation.
9
+
10
+ > **Production is a hard no-op.** The plugin only injects when
11
+ > `NODE_ENV !== 'production'` (and, under Vite, only during `vite` dev — never
12
+ > `vite build`). Your shipped bundles never contain `data-loc`.
13
+
14
+ ## Usage
15
+
16
+ ```ts
17
+ // vite.config.ts
18
+ import { defineConfig } from 'vite';
19
+ import react from '@vitejs/plugin-react';
20
+ import clicksmith from '@clicksmith/unplugin/vite';
21
+
22
+ export default defineConfig({
23
+ plugins: [clicksmith(), react()],
24
+ });
25
+ ```
26
+
27
+ Other bundlers:
28
+
29
+ ```ts
30
+ import clicksmith from '@clicksmith/unplugin/webpack'; // or /rollup, /rspack, /esbuild
31
+ ```
32
+
33
+ ## What it does
34
+
35
+ For each JSX/TSX opening element it injects `data-loc="relative/path:line:column"`:
36
+
37
+ ```jsx
38
+ // before
39
+ <button onClick={onClick}>Buy</button>
40
+ // after (dev only)
41
+ <button data-loc="src/Card.tsx:4:6" onClick={onClick}>Buy</button>
42
+ ```
43
+
44
+ - **Idempotent** — never adds a duplicate `data-loc`.
45
+ - **Sourceless fallback** — files that can't be parsed are left untouched; the
46
+ runtime locator pipeline (attr → behavioral → dom) still works without it.
47
+ - **Source maps** preserved.
48
+
49
+ ## Options
50
+
51
+ ```ts
52
+ clicksmith({
53
+ root: process.cwd(), // base for the relative paths
54
+ attribute: 'data-loc', // attribute name
55
+ include: /\.[jt]sx$/, // which files to transform
56
+ exclude: /node_modules/,
57
+ enabled: undefined, // default: NODE_ENV !== 'production'
58
+ });
59
+ ```
60
+
61
+ ## Framework support
62
+
63
+ First-class support targets **JSX/TSX** (React and friends). Vue, Svelte, and
64
+ Angular rely on compiler-specific hooks; where those aren't wired up the build is
65
+ a no-op and ClickSmith automatically falls back to attribute/behavioral/DOM
66
+ locators — capture still works, you just don't get exact `file:line`.
@@ -0,0 +1,89 @@
1
+ // src/index.ts
2
+ import { createUnplugin } from "unplugin";
3
+ import { relative, isAbsolute } from "path";
4
+
5
+ // src/transform.ts
6
+ import { parse } from "@babel/parser";
7
+ import _traverse from "@babel/traverse";
8
+ import MagicString from "magic-string";
9
+ var traverse = typeof _traverse === "function" ? _traverse : _traverse.default;
10
+ function injectDataLoc(code, options) {
11
+ const attribute = options.attribute ?? "data-loc";
12
+ let ast;
13
+ try {
14
+ ast = parse(code, {
15
+ sourceType: "module",
16
+ plugins: ["jsx", "typescript"],
17
+ errorRecovery: false
18
+ });
19
+ } catch {
20
+ return null;
21
+ }
22
+ const s = new MagicString(code);
23
+ let injected = 0;
24
+ traverse(ast, {
25
+ JSXOpeningElement(path) {
26
+ const node = path.node;
27
+ if (isFragment(node) || hasAttribute(node, attribute)) return;
28
+ const loc = node.loc?.start;
29
+ const insertAt = node.name.end;
30
+ if (loc == null || insertAt == null) return;
31
+ const value = `${options.file}:${loc.line}:${loc.column}`;
32
+ s.appendLeft(insertAt, ` ${attribute}="${escapeAttr(value)}"`);
33
+ injected++;
34
+ }
35
+ });
36
+ if (injected === 0) return null;
37
+ return { code: s.toString(), map: s.generateMap({ hires: true }), injected };
38
+ }
39
+ function isFragment(node) {
40
+ return node.name.type === "JSXIdentifier" && node.name.name === "Fragment";
41
+ }
42
+ function hasAttribute(node, attribute) {
43
+ return node.attributes.some(
44
+ (attr) => attr.type === "JSXAttribute" && attr.name.type === "JSXIdentifier" && attr.name.name === attribute
45
+ );
46
+ }
47
+ function escapeAttr(value) {
48
+ return value.replace(/"/g, "&quot;");
49
+ }
50
+
51
+ // src/index.ts
52
+ var unpluginFactory = (rawOptions = {}) => {
53
+ const root = rawOptions.root ?? process.cwd();
54
+ const attribute = rawOptions.attribute ?? "data-loc";
55
+ const include = rawOptions.include ?? /\.[jt]sx$/;
56
+ const exclude = rawOptions.exclude ?? /node_modules/;
57
+ const enabled = rawOptions.enabled ?? process.env.NODE_ENV !== "production";
58
+ return {
59
+ name: "@clicksmith/unplugin",
60
+ enforce: "pre",
61
+ transformInclude(id) {
62
+ if (!enabled) return false;
63
+ const clean = id.split("?")[0];
64
+ return include.test(clean) && !exclude.test(clean);
65
+ },
66
+ transform(code, id) {
67
+ if (!enabled) return null;
68
+ const clean = id.split("?")[0];
69
+ const file = isAbsolute(clean) ? relative(root, clean) : clean;
70
+ const result = injectDataLoc(code, { file, attribute });
71
+ if (!result) return null;
72
+ return { code: result.code, map: result.map };
73
+ },
74
+ // Vite: hard no-op for `vite build` — only run in the dev server.
75
+ vite: {
76
+ apply: "serve"
77
+ }
78
+ };
79
+ };
80
+ var unplugin = /* @__PURE__ */ createUnplugin(unpluginFactory);
81
+ var index_default = unplugin;
82
+
83
+ export {
84
+ injectDataLoc,
85
+ unpluginFactory,
86
+ unplugin,
87
+ index_default
88
+ };
89
+ //# sourceMappingURL=chunk-HSBF3NH3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/transform.ts"],"sourcesContent":["import { createUnplugin, type UnpluginFactory } from 'unplugin';\nimport { relative, isAbsolute } from 'node:path';\nimport { injectDataLoc } from './transform.js';\n\nexport interface ClickSmithUnpluginOptions {\n /** Base directory for the relative paths encoded into `data-loc`. Default `process.cwd()`. */\n root?: string;\n /** Attribute name to inject. Default `data-loc`. */\n attribute?: string;\n /** Which files to transform. Default `/\\.[jt]sx$/`. */\n include?: RegExp;\n /** Files to skip. Default `/node_modules/`. */\n exclude?: RegExp;\n /**\n * Master switch. When `false`, the plugin is a complete no-op. Defaults to\n * `process.env.NODE_ENV !== 'production'` — production builds never inject.\n */\n enabled?: boolean;\n}\n\nexport const unpluginFactory: UnpluginFactory<ClickSmithUnpluginOptions | undefined> = (\n rawOptions = {},\n) => {\n const root = rawOptions.root ?? process.cwd();\n const attribute = rawOptions.attribute ?? 'data-loc';\n const include = rawOptions.include ?? /\\.[jt]sx$/;\n const exclude = rawOptions.exclude ?? /node_modules/;\n const enabled = rawOptions.enabled ?? process.env.NODE_ENV !== 'production';\n\n return {\n name: '@clicksmith/unplugin',\n enforce: 'pre',\n\n transformInclude(id) {\n if (!enabled) return false;\n const clean = id.split('?')[0]!;\n return include.test(clean) && !exclude.test(clean);\n },\n\n transform(code, id) {\n if (!enabled) return null;\n const clean = id.split('?')[0]!;\n const file = isAbsolute(clean) ? relative(root, clean) : clean;\n const result = injectDataLoc(code, { file, attribute });\n if (!result) return null;\n return { code: result.code, map: result.map };\n },\n\n // Vite: hard no-op for `vite build` — only run in the dev server.\n vite: {\n apply: 'serve',\n },\n };\n};\n\n/** The framework-agnostic unplugin instance. */\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory);\n\nexport default unplugin;\nexport { injectDataLoc } from './transform.js';\nexport type { InjectOptions, InjectResult } from './transform.js';\n","import { parse } from '@babel/parser';\nimport _traverse from '@babel/traverse';\nimport MagicString from 'magic-string';\nimport type { JSXOpeningElement } from '@babel/types';\n\n// @babel/traverse ships a CJS default export; normalize for ESM consumers.\nconst traverse = (\n typeof _traverse === 'function' ? _traverse : (_traverse as { default: typeof _traverse }).default\n) as typeof _traverse;\n\nexport interface InjectOptions {\n /** The (preferably project-relative) file path encoded into `data-loc`. */\n file: string;\n /** The attribute name to inject. Default `data-loc`. */\n attribute?: string;\n}\n\nexport interface InjectResult {\n code: string;\n map: ReturnType<MagicString['generateMap']>;\n /** How many opening elements received the attribute. */\n injected: number;\n}\n\n/**\n * Inject a `data-loc=\"file:line:column\"` attribute onto every JSX opening\n * element that does not already have one. Returns `null` when the source can't\n * be parsed or there is nothing to inject (so the caller falls back to leaving\n * the file untouched). Pure and idempotent: running it twice never adds a\n * duplicate attribute.\n */\nexport function injectDataLoc(code: string, options: InjectOptions): InjectResult | null {\n const attribute = options.attribute ?? 'data-loc';\n\n let ast;\n try {\n ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n errorRecovery: false,\n });\n } catch {\n // Sourceless fallback: unparseable input is left untouched. The runtime\n // locator pipeline (attr → behavioral → dom) still works without data-loc.\n return null;\n }\n\n const s = new MagicString(code);\n let injected = 0;\n\n traverse(ast, {\n JSXOpeningElement(path) {\n const node = path.node as JSXOpeningElement;\n if (isFragment(node) || hasAttribute(node, attribute)) return;\n const loc = node.loc?.start;\n const insertAt = node.name.end;\n if (loc == null || insertAt == null) return;\n const value = `${options.file}:${loc.line}:${loc.column}`;\n s.appendLeft(insertAt, ` ${attribute}=\"${escapeAttr(value)}\"`);\n injected++;\n },\n });\n\n if (injected === 0) return null;\n return { code: s.toString(), map: s.generateMap({ hires: true }), injected };\n}\n\nfunction isFragment(node: JSXOpeningElement): boolean {\n return node.name.type === 'JSXIdentifier' && node.name.name === 'Fragment';\n}\n\nfunction hasAttribute(node: JSXOpeningElement, attribute: string): boolean {\n return node.attributes.some(\n (attr) => attr.type === 'JSXAttribute' && attr.name.type === 'JSXIdentifier' && attr.name.name === attribute,\n );\n}\n\nfunction escapeAttr(value: string): string {\n return value.replace(/\"/g, '&quot;');\n}\n"],"mappings":";AAAA,SAAS,sBAA4C;AACrD,SAAS,UAAU,kBAAkB;;;ACDrC,SAAS,aAAa;AACtB,OAAO,eAAe;AACtB,OAAO,iBAAiB;AAIxB,IAAM,WACJ,OAAO,cAAc,aAAa,YAAa,UAA4C;AAwBtF,SAAS,cAAc,MAAc,SAA6C;AACvF,QAAM,YAAY,QAAQ,aAAa;AAEvC,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,YAAY;AAAA,MACZ,SAAS,CAAC,OAAO,YAAY;AAAA,MAC7B,eAAe;AAAA,IACjB,CAAC;AAAA,EACH,QAAQ;AAGN,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,IAAI,YAAY,IAAI;AAC9B,MAAI,WAAW;AAEf,WAAS,KAAK;AAAA,IACZ,kBAAkB,MAAM;AACtB,YAAM,OAAO,KAAK;AAClB,UAAI,WAAW,IAAI,KAAK,aAAa,MAAM,SAAS,EAAG;AACvD,YAAM,MAAM,KAAK,KAAK;AACtB,YAAM,WAAW,KAAK,KAAK;AAC3B,UAAI,OAAO,QAAQ,YAAY,KAAM;AACrC,YAAM,QAAQ,GAAG,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,MAAM;AACvD,QAAE,WAAW,UAAU,IAAI,SAAS,KAAK,WAAW,KAAK,CAAC,GAAG;AAC7D;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI,aAAa,EAAG,QAAO;AAC3B,SAAO,EAAE,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,YAAY,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS;AAC7E;AAEA,SAAS,WAAW,MAAkC;AACpD,SAAO,KAAK,KAAK,SAAS,mBAAmB,KAAK,KAAK,SAAS;AAClE;AAEA,SAAS,aAAa,MAAyB,WAA4B;AACzE,SAAO,KAAK,WAAW;AAAA,IACrB,CAAC,SAAS,KAAK,SAAS,kBAAkB,KAAK,KAAK,SAAS,mBAAmB,KAAK,KAAK,SAAS;AAAA,EACrG;AACF;AAEA,SAAS,WAAW,OAAuB;AACzC,SAAO,MAAM,QAAQ,MAAM,QAAQ;AACrC;;;AD3DO,IAAM,kBAA0E,CACrF,aAAa,CAAC,MACX;AACH,QAAM,OAAO,WAAW,QAAQ,QAAQ,IAAI;AAC5C,QAAM,YAAY,WAAW,aAAa;AAC1C,QAAM,UAAU,WAAW,WAAW;AACtC,QAAM,UAAU,WAAW,WAAW;AACtC,QAAM,UAAU,WAAW,WAAW,QAAQ,IAAI,aAAa;AAE/D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,iBAAiB,IAAI;AACnB,UAAI,CAAC,QAAS,QAAO;AACrB,YAAM,QAAQ,GAAG,MAAM,GAAG,EAAE,CAAC;AAC7B,aAAO,QAAQ,KAAK,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK;AAAA,IACnD;AAAA,IAEA,UAAU,MAAM,IAAI;AAClB,UAAI,CAAC,QAAS,QAAO;AACrB,YAAM,QAAQ,GAAG,MAAM,GAAG,EAAE,CAAC;AAC7B,YAAM,OAAO,WAAW,KAAK,IAAI,SAAS,MAAM,KAAK,IAAI;AACzD,YAAM,SAAS,cAAc,MAAM,EAAE,MAAM,UAAU,CAAC;AACtD,UAAI,CAAC,OAAQ,QAAO;AACpB,aAAO,EAAE,MAAM,OAAO,MAAM,KAAK,OAAO,IAAI;AAAA,IAC9C;AAAA;AAAA,IAGA,MAAM;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAGO,IAAM,WAA2B,+BAAe,eAAe;AAEtE,IAAO,gBAAQ;","names":[]}
@@ -0,0 +1,8 @@
1
+ import * as unplugin from 'unplugin';
2
+ import { ClickSmithUnpluginOptions } from './index.js';
3
+ import 'magic-string';
4
+
5
+ /** ClickSmith data-loc injection as an esbuild plugin (dev-only). */
6
+ declare const _default: (options?: ClickSmithUnpluginOptions | undefined) => unplugin.EsbuildPlugin;
7
+
8
+ export { ClickSmithUnpluginOptions, _default as default };
@@ -0,0 +1,11 @@
1
+ import {
2
+ unpluginFactory
3
+ } from "./chunk-HSBF3NH3.js";
4
+
5
+ // src/esbuild.ts
6
+ import { createEsbuildPlugin } from "unplugin";
7
+ var esbuild_default = createEsbuildPlugin(unpluginFactory);
8
+ export {
9
+ esbuild_default as default
10
+ };
11
+ //# sourceMappingURL=esbuild.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/esbuild.ts"],"sourcesContent":["import { unpluginFactory } from './index.js';\nimport { createEsbuildPlugin } from 'unplugin';\n\n/** ClickSmith data-loc injection as an esbuild plugin (dev-only). */\nexport default createEsbuildPlugin(unpluginFactory);\nexport type { ClickSmithUnpluginOptions } from './index.js';\n"],"mappings":";;;;;AACA,SAAS,2BAA2B;AAGpC,IAAO,kBAAQ,oBAAoB,eAAe;","names":[]}
@@ -0,0 +1,45 @@
1
+ import * as unplugin$1 from 'unplugin';
2
+ import { UnpluginFactory } from 'unplugin';
3
+ import MagicString from 'magic-string';
4
+
5
+ interface InjectOptions {
6
+ /** The (preferably project-relative) file path encoded into `data-loc`. */
7
+ file: string;
8
+ /** The attribute name to inject. Default `data-loc`. */
9
+ attribute?: string;
10
+ }
11
+ interface InjectResult {
12
+ code: string;
13
+ map: ReturnType<MagicString['generateMap']>;
14
+ /** How many opening elements received the attribute. */
15
+ injected: number;
16
+ }
17
+ /**
18
+ * Inject a `data-loc="file:line:column"` attribute onto every JSX opening
19
+ * element that does not already have one. Returns `null` when the source can't
20
+ * be parsed or there is nothing to inject (so the caller falls back to leaving
21
+ * the file untouched). Pure and idempotent: running it twice never adds a
22
+ * duplicate attribute.
23
+ */
24
+ declare function injectDataLoc(code: string, options: InjectOptions): InjectResult | null;
25
+
26
+ interface ClickSmithUnpluginOptions {
27
+ /** Base directory for the relative paths encoded into `data-loc`. Default `process.cwd()`. */
28
+ root?: string;
29
+ /** Attribute name to inject. Default `data-loc`. */
30
+ attribute?: string;
31
+ /** Which files to transform. Default `/\.[jt]sx$/`. */
32
+ include?: RegExp;
33
+ /** Files to skip. Default `/node_modules/`. */
34
+ exclude?: RegExp;
35
+ /**
36
+ * Master switch. When `false`, the plugin is a complete no-op. Defaults to
37
+ * `process.env.NODE_ENV !== 'production'` — production builds never inject.
38
+ */
39
+ enabled?: boolean;
40
+ }
41
+ declare const unpluginFactory: UnpluginFactory<ClickSmithUnpluginOptions | undefined>;
42
+ /** The framework-agnostic unplugin instance. */
43
+ declare const unplugin: unplugin$1.UnpluginInstance<ClickSmithUnpluginOptions | undefined, boolean>;
44
+
45
+ export { type ClickSmithUnpluginOptions, type InjectOptions, type InjectResult, unplugin as default, injectDataLoc, unplugin, unpluginFactory };
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ import {
2
+ index_default,
3
+ injectDataLoc,
4
+ unplugin,
5
+ unpluginFactory
6
+ } from "./chunk-HSBF3NH3.js";
7
+ export {
8
+ index_default as default,
9
+ injectDataLoc,
10
+ unplugin,
11
+ unpluginFactory
12
+ };
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,9 @@
1
+ import * as rollup from 'rollup';
2
+ import { ClickSmithUnpluginOptions } from './index.js';
3
+ import 'unplugin';
4
+ import 'magic-string';
5
+
6
+ /** ClickSmith data-loc injection as a Rollup plugin (dev-only). */
7
+ declare const _default: (options?: ClickSmithUnpluginOptions | undefined) => rollup.Plugin<any> | rollup.Plugin<any>[];
8
+
9
+ export { ClickSmithUnpluginOptions, _default as default };
package/dist/rollup.js ADDED
@@ -0,0 +1,11 @@
1
+ import {
2
+ unpluginFactory
3
+ } from "./chunk-HSBF3NH3.js";
4
+
5
+ // src/rollup.ts
6
+ import { createRollupPlugin } from "unplugin";
7
+ var rollup_default = createRollupPlugin(unpluginFactory);
8
+ export {
9
+ rollup_default as default
10
+ };
11
+ //# sourceMappingURL=rollup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rollup.ts"],"sourcesContent":["import { unpluginFactory } from './index.js';\nimport { createRollupPlugin } from 'unplugin';\n\n/** ClickSmith data-loc injection as a Rollup plugin (dev-only). */\nexport default createRollupPlugin(unpluginFactory);\nexport type { ClickSmithUnpluginOptions } from './index.js';\n"],"mappings":";;;;;AACA,SAAS,0BAA0B;AAGnC,IAAO,iBAAQ,mBAAmB,eAAe;","names":[]}
@@ -0,0 +1,8 @@
1
+ import { ClickSmithUnpluginOptions } from './index.js';
2
+ import 'unplugin';
3
+ import 'magic-string';
4
+
5
+ /** ClickSmith data-loc injection as an Rspack plugin (dev-only). */
6
+ declare const _default: (options?: ClickSmithUnpluginOptions | undefined) => _rspack_core_dist_config_types.RspackPluginInstance;
7
+
8
+ export { ClickSmithUnpluginOptions, _default as default };
package/dist/rspack.js ADDED
@@ -0,0 +1,11 @@
1
+ import {
2
+ unpluginFactory
3
+ } from "./chunk-HSBF3NH3.js";
4
+
5
+ // src/rspack.ts
6
+ import { createRspackPlugin } from "unplugin";
7
+ var rspack_default = createRspackPlugin(unpluginFactory);
8
+ export {
9
+ rspack_default as default
10
+ };
11
+ //# sourceMappingURL=rspack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rspack.ts"],"sourcesContent":["import { unpluginFactory } from './index.js';\nimport { createRspackPlugin } from 'unplugin';\n\n/** ClickSmith data-loc injection as an Rspack plugin (dev-only). */\nexport default createRspackPlugin(unpluginFactory);\nexport type { ClickSmithUnpluginOptions } from './index.js';\n"],"mappings":";;;;;AACA,SAAS,0BAA0B;AAGnC,IAAO,iBAAQ,mBAAmB,eAAe;","names":[]}
package/dist/vite.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import * as unplugin from 'unplugin';
2
+ import { ClickSmithUnpluginOptions } from './index.js';
3
+ import 'magic-string';
4
+
5
+ /** ClickSmith data-loc injection as a Vite plugin (dev-only). */
6
+ declare const _default: (options?: ClickSmithUnpluginOptions | undefined) => unplugin.VitePlugin<any> | unplugin.VitePlugin<any>[];
7
+
8
+ export { ClickSmithUnpluginOptions, _default as default };
package/dist/vite.js ADDED
@@ -0,0 +1,11 @@
1
+ import {
2
+ unpluginFactory
3
+ } from "./chunk-HSBF3NH3.js";
4
+
5
+ // src/vite.ts
6
+ import { createVitePlugin } from "unplugin";
7
+ var vite_default = createVitePlugin(unpluginFactory);
8
+ export {
9
+ vite_default as default
10
+ };
11
+ //# sourceMappingURL=vite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vite.ts"],"sourcesContent":["import { unpluginFactory } from './index.js';\nimport { createVitePlugin } from 'unplugin';\n\n/** ClickSmith data-loc injection as a Vite plugin (dev-only). */\nexport default createVitePlugin(unpluginFactory);\nexport type { ClickSmithUnpluginOptions } from './index.js';\n"],"mappings":";;;;;AACA,SAAS,wBAAwB;AAGjC,IAAO,eAAQ,iBAAiB,eAAe;","names":[]}
@@ -0,0 +1,8 @@
1
+ import { ClickSmithUnpluginOptions } from './index.js';
2
+ import 'unplugin';
3
+ import 'magic-string';
4
+
5
+ /** ClickSmith data-loc injection as a Webpack plugin (dev-only). */
6
+ declare const _default: (options?: ClickSmithUnpluginOptions | undefined) => webpack.WebpackPluginInstance;
7
+
8
+ export { ClickSmithUnpluginOptions, _default as default };
@@ -0,0 +1,11 @@
1
+ import {
2
+ unpluginFactory
3
+ } from "./chunk-HSBF3NH3.js";
4
+
5
+ // src/webpack.ts
6
+ import { createWebpackPlugin } from "unplugin";
7
+ var webpack_default = createWebpackPlugin(unpluginFactory);
8
+ export {
9
+ webpack_default as default
10
+ };
11
+ //# sourceMappingURL=webpack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/webpack.ts"],"sourcesContent":["import { unpluginFactory } from './index.js';\nimport { createWebpackPlugin } from 'unplugin';\n\n/** ClickSmith data-loc injection as a Webpack plugin (dev-only). */\nexport default createWebpackPlugin(unpluginFactory);\nexport type { ClickSmithUnpluginOptions } from './index.js';\n"],"mappings":";;;;;AACA,SAAS,2BAA2B;AAGpC,IAAO,kBAAQ,oBAAoB,eAAe;","names":[]}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@clicksmith/unplugin",
3
+ "version": "0.1.0",
4
+ "description": "Dev-only data-loc injection for ClickSmith across Vite/Rollup/Webpack/esbuild/Rspack. A hard no-op in production builds.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./vite": {
13
+ "types": "./dist/vite.d.ts",
14
+ "import": "./dist/vite.js"
15
+ },
16
+ "./rollup": {
17
+ "types": "./dist/rollup.d.ts",
18
+ "import": "./dist/rollup.js"
19
+ },
20
+ "./webpack": {
21
+ "types": "./dist/webpack.d.ts",
22
+ "import": "./dist/webpack.js"
23
+ },
24
+ "./rspack": {
25
+ "types": "./dist/rspack.d.ts",
26
+ "import": "./dist/rspack.js"
27
+ },
28
+ "./esbuild": {
29
+ "types": "./dist/esbuild.d.ts",
30
+ "import": "./dist/esbuild.js"
31
+ }
32
+ },
33
+ "main": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "dependencies": {
39
+ "@babel/parser": "^7.25.9",
40
+ "@babel/traverse": "^7.25.9",
41
+ "@babel/types": "^7.26.0",
42
+ "magic-string": "^0.30.12",
43
+ "unplugin": "^1.16.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/babel__traverse": "^7.20.6"
47
+ },
48
+ "scripts": {
49
+ "build": "tsup",
50
+ "dev": "tsup --watch",
51
+ "test": "vitest run",
52
+ "test:watch": "vitest",
53
+ "typecheck": "tsc --noEmit",
54
+ "lint": "eslint src",
55
+ "clean": "rimraf dist .turbo"
56
+ }
57
+ }