@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 +21 -0
- package/README.md +66 -0
- package/dist/chunk-HSBF3NH3.js +89 -0
- package/dist/chunk-HSBF3NH3.js.map +1 -0
- package/dist/esbuild.d.ts +8 -0
- package/dist/esbuild.js +11 -0
- package/dist/esbuild.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/rollup.d.ts +9 -0
- package/dist/rollup.js +11 -0
- package/dist/rollup.js.map +1 -0
- package/dist/rspack.d.ts +8 -0
- package/dist/rspack.js +11 -0
- package/dist/rspack.js.map +1 -0
- package/dist/vite.d.ts +8 -0
- package/dist/vite.js +11 -0
- package/dist/vite.js.map +1 -0
- package/dist/webpack.d.ts +8 -0
- package/dist/webpack.js +11 -0
- package/dist/webpack.js.map +1 -0
- package/package.json +57 -0
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, """);
|
|
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, '"');\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 };
|
package/dist/esbuild.js
ADDED
|
@@ -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":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/rollup.d.ts
ADDED
|
@@ -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":[]}
|
package/dist/rspack.d.ts
ADDED
|
@@ -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
|
package/dist/vite.js.map
ADDED
|
@@ -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 };
|
package/dist/webpack.js
ADDED
|
@@ -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
|
+
}
|