weevar 1.0.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/dist/chunk-IXK7HELP.mjs +28 -0
- package/dist/chunk-IXK7HELP.mjs.map +1 -0
- package/dist/chunk-LFEEXHSC.mjs +55 -0
- package/dist/chunk-LFEEXHSC.mjs.map +1 -0
- package/dist/react.dev.d.mts +6 -0
- package/dist/react.dev.d.ts +6 -0
- package/dist/react.dev.js +5044 -0
- package/dist/react.dev.js.map +1 -0
- package/dist/react.dev.mjs +5024 -0
- package/dist/react.dev.mjs.map +1 -0
- package/dist/react.prod.d.mts +6 -0
- package/dist/react.prod.d.ts +6 -0
- package/dist/react.prod.js +10 -0
- package/dist/react.prod.js.map +1 -0
- package/dist/react.prod.mjs +8 -0
- package/dist/react.prod.mjs.map +1 -0
- package/dist/swc.d.mts +9 -0
- package/dist/swc.d.ts +9 -0
- package/dist/swc.js +111 -0
- package/dist/swc.js.map +1 -0
- package/dist/swc.mjs +93 -0
- package/dist/swc.mjs.map +1 -0
- package/dist/types-DXyR9jUf.d.mts +31 -0
- package/dist/types-DXyR9jUf.d.ts +31 -0
- package/dist/vite.d.mts +12 -0
- package/dist/vite.d.ts +12 -0
- package/dist/vite.js +259 -0
- package/dist/vite.js.map +1 -0
- package/dist/vite.mjs +172 -0
- package/dist/vite.mjs.map +1 -0
- package/dist/webpack-loader.d.mts +27 -0
- package/dist/webpack-loader.d.ts +27 -0
- package/dist/webpack-loader.js +110 -0
- package/dist/webpack-loader.js.map +1 -0
- package/dist/webpack-loader.mjs +23 -0
- package/dist/webpack-loader.mjs.map +1 -0
- package/package.json +102 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/WeevarProd.tsx"],"names":[],"mappings":";;;AAEO,SAAS,OAAO,MAAA,EAA2B;AAChD,EAAA,OAAO,IAAA;AACT","file":"react.prod.js","sourcesContent":["import type { WeevarProps } from \"../types\";\n\nexport function Weevar(_props: WeevarProps): null {\n return null;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/WeevarProd.tsx"],"names":[],"mappings":";AAEO,SAAS,OAAO,MAAA,EAA2B;AAChD,EAAA,OAAO,IAAA;AACT","file":"react.prod.mjs","sourcesContent":["import type { WeevarProps } from \"../types\";\n\nexport function Weevar(_props: WeevarProps): null {\n return null;\n}\n"]}
|
package/dist/swc.d.mts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SWC-based JSX `data-wv-source` injection (for Next.js / @swc/core pipelines).
|
|
3
|
+
* Peer: `@swc/core`. Falls back to returning null on parse/print failure.
|
|
4
|
+
*/
|
|
5
|
+
declare function transformJsxWithWeevarSourceSwc(code: string, absFile: string, cwd: string): {
|
|
6
|
+
code: string;
|
|
7
|
+
} | null;
|
|
8
|
+
|
|
9
|
+
export { transformJsxWithWeevarSourceSwc };
|
package/dist/swc.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SWC-based JSX `data-wv-source` injection (for Next.js / @swc/core pipelines).
|
|
3
|
+
* Peer: `@swc/core`. Falls back to returning null on parse/print failure.
|
|
4
|
+
*/
|
|
5
|
+
declare function transformJsxWithWeevarSourceSwc(code: string, absFile: string, cwd: string): {
|
|
6
|
+
code: string;
|
|
7
|
+
} | null;
|
|
8
|
+
|
|
9
|
+
export { transformJsxWithWeevarSourceSwc };
|
package/dist/swc.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('path');
|
|
4
|
+
var core = require('@swc/core');
|
|
5
|
+
var Visitor = require('@swc/core/Visitor');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
10
|
+
|
|
11
|
+
// src/swc/transformJsxSource.ts
|
|
12
|
+
|
|
13
|
+
// src/engine/parseDataWvSource.ts
|
|
14
|
+
function encodeDataWvSource(loc) {
|
|
15
|
+
const json = JSON.stringify({
|
|
16
|
+
file: loc.file,
|
|
17
|
+
line: loc.line,
|
|
18
|
+
col: loc.col
|
|
19
|
+
});
|
|
20
|
+
return btoa(unescape(encodeURIComponent(json)));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/swc/transformJsxSource.ts
|
|
24
|
+
function noopSpan() {
|
|
25
|
+
return { start: 0, end: 0, ctxt: 0 };
|
|
26
|
+
}
|
|
27
|
+
function byteOffsetToLineCol(src, pos) {
|
|
28
|
+
let line = 1;
|
|
29
|
+
let col = 0;
|
|
30
|
+
const end = Math.min(pos, src.length);
|
|
31
|
+
for (let i = 0; i < end; i++) {
|
|
32
|
+
const c = src[i];
|
|
33
|
+
if (c === "\n") {
|
|
34
|
+
line++;
|
|
35
|
+
col = 0;
|
|
36
|
+
} else {
|
|
37
|
+
col++;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return { line, col };
|
|
41
|
+
}
|
|
42
|
+
var WeevarJsxVisitor = class extends Visitor.Visitor {
|
|
43
|
+
constructor(src, relFile) {
|
|
44
|
+
super();
|
|
45
|
+
this.src = src;
|
|
46
|
+
this.relFile = relFile;
|
|
47
|
+
}
|
|
48
|
+
visitJSXOpeningElement(n) {
|
|
49
|
+
const hasDataWv = n.attributes.some(
|
|
50
|
+
(a) => a.type === "JSXAttribute" && a.name.type === "Identifier" && a.name.value === "data-wv-source"
|
|
51
|
+
);
|
|
52
|
+
if (hasDataWv) return super.visitJSXOpeningElement(n);
|
|
53
|
+
const { line, col } = byteOffsetToLineCol(this.src, n.span.start);
|
|
54
|
+
const payload = encodeDataWvSource({
|
|
55
|
+
file: this.relFile,
|
|
56
|
+
line,
|
|
57
|
+
col
|
|
58
|
+
});
|
|
59
|
+
const name = {
|
|
60
|
+
type: "Identifier",
|
|
61
|
+
span: noopSpan(),
|
|
62
|
+
value: "data-wv-source",
|
|
63
|
+
optional: false
|
|
64
|
+
};
|
|
65
|
+
const value = {
|
|
66
|
+
type: "StringLiteral",
|
|
67
|
+
span: noopSpan(),
|
|
68
|
+
value: payload,
|
|
69
|
+
raw: JSON.stringify(payload)
|
|
70
|
+
};
|
|
71
|
+
const attr = {
|
|
72
|
+
type: "JSXAttribute",
|
|
73
|
+
span: noopSpan(),
|
|
74
|
+
name,
|
|
75
|
+
value
|
|
76
|
+
};
|
|
77
|
+
const next = {
|
|
78
|
+
...n,
|
|
79
|
+
attributes: [...n.attributes, attr]
|
|
80
|
+
};
|
|
81
|
+
return super.visitJSXOpeningElement(next);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
function transformJsxWithWeevarSourceSwc(code, absFile, cwd) {
|
|
85
|
+
const rel = path__default.default.relative(cwd, absFile).split(path__default.default.sep).join("/") || absFile;
|
|
86
|
+
try {
|
|
87
|
+
const ast = core.parseSync(code, {
|
|
88
|
+
syntax: "typescript",
|
|
89
|
+
tsx: true,
|
|
90
|
+
decorators: false
|
|
91
|
+
});
|
|
92
|
+
const visitor = new WeevarJsxVisitor(code, rel);
|
|
93
|
+
const out = visitor.visitProgram(ast);
|
|
94
|
+
const printed = core.printSync(out, {
|
|
95
|
+
jsc: {
|
|
96
|
+
parser: { syntax: "typescript", tsx: true },
|
|
97
|
+
target: "es2022",
|
|
98
|
+
transform: {
|
|
99
|
+
react: { runtime: "automatic", development: false }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
return { code: printed.code };
|
|
104
|
+
} catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
exports.transformJsxWithWeevarSourceSwc = transformJsxWithWeevarSourceSwc;
|
|
110
|
+
//# sourceMappingURL=swc.js.map
|
|
111
|
+
//# sourceMappingURL=swc.js.map
|
package/dist/swc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engine/parseDataWvSource.ts","../src/swc/transformJsxSource.ts"],"names":["Visitor","path","parseSync","printSync"],"mappings":"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","file":"swc.js","sourcesContent":["import type { SourceLocation } from \"./layoutTypes\";\n\nfunction decodeBase64Json(raw: string): SourceLocation | undefined {\n try {\n const bin = atob(raw.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n const j = JSON.parse(bin) as { file?: string; line?: number; col?: number };\n if (!j?.file || !Number.isFinite(j.line)) return undefined;\n return { file: String(j.file), line: Number(j.line), col: Number(j.col ?? 0) };\n } catch {\n return undefined;\n }\n}\n\n/** `data-wv-source` = base64(JSON.stringify({file,line,col})) from optional tooling. */\nexport function parseDataWvSource(el: Element): SourceLocation | undefined {\n const raw = el.getAttribute(\"data-wv-source\");\n if (!raw) return undefined;\n return decodeBase64Json(raw);\n}\n\nexport function encodeDataWvSource(loc: SourceLocation): string {\n const json = JSON.stringify({\n file: loc.file,\n line: loc.line,\n col: loc.col,\n });\n return btoa(unescape(encodeURIComponent(json)));\n}\n","import path from \"node:path\";\nimport { parseSync, printSync } from \"@swc/core\";\nimport { Visitor } from \"@swc/core/Visitor\";\nimport type { Identifier, JSXAttribute, JSXOpeningElement, Program, Span, StringLiteral } from \"@swc/types\";\nimport { encodeDataWvSource } from \"../engine/parseDataWvSource\";\n\nfunction noopSpan(): Span {\n return { start: 0, end: 0, ctxt: 0 };\n}\n\nfunction byteOffsetToLineCol(src: string, pos: number): { line: number; col: number } {\n let line = 1;\n let col = 0;\n const end = Math.min(pos, src.length);\n for (let i = 0; i < end; i++) {\n const c = src[i];\n if (c === \"\\n\") {\n line++;\n col = 0;\n } else {\n col++;\n }\n }\n return { line, col };\n}\n\nclass WeevarJsxVisitor extends Visitor {\n constructor(\n private readonly src: string,\n private readonly relFile: string,\n ) {\n super();\n }\n\n visitJSXOpeningElement(n: JSXOpeningElement): JSXOpeningElement {\n const hasDataWv = n.attributes.some(\n (a) =>\n a.type === \"JSXAttribute\" &&\n a.name.type === \"Identifier\" &&\n a.name.value === \"data-wv-source\",\n );\n if (hasDataWv) return super.visitJSXOpeningElement(n);\n\n const { line, col } = byteOffsetToLineCol(this.src, n.span.start);\n const payload = encodeDataWvSource({\n file: this.relFile,\n line,\n col,\n });\n\n const name: Identifier = {\n type: \"Identifier\",\n span: noopSpan(),\n value: \"data-wv-source\",\n optional: false,\n };\n const value: StringLiteral = {\n type: \"StringLiteral\",\n span: noopSpan(),\n value: payload,\n raw: JSON.stringify(payload),\n };\n const attr: JSXAttribute = {\n type: \"JSXAttribute\",\n span: noopSpan(),\n name,\n value,\n };\n\n const next: JSXOpeningElement = {\n ...n,\n attributes: [...n.attributes, attr],\n };\n return super.visitJSXOpeningElement(next);\n }\n}\n\n/**\n * SWC-based JSX `data-wv-source` injection (for Next.js / @swc/core pipelines).\n * Peer: `@swc/core`. Falls back to returning null on parse/print failure.\n */\nexport function transformJsxWithWeevarSourceSwc(\n code: string,\n absFile: string,\n cwd: string,\n): { code: string } | null {\n const rel = path.relative(cwd, absFile).split(path.sep).join(\"/\") || absFile;\n try {\n const ast = parseSync(code, {\n syntax: \"typescript\",\n tsx: true,\n decorators: false,\n }) as Program;\n\n const visitor = new WeevarJsxVisitor(code, rel);\n const out = visitor.visitProgram(ast);\n const printed = printSync(out, {\n jsc: {\n parser: { syntax: \"typescript\", tsx: true },\n target: \"es2022\",\n transform: {\n react: { runtime: \"automatic\", development: false },\n },\n },\n });\n return { code: printed.code };\n } catch {\n return null;\n }\n}\n"]}
|
package/dist/swc.mjs
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { encodeDataWvSource } from './chunk-IXK7HELP.mjs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { parseSync, printSync } from '@swc/core';
|
|
4
|
+
import { Visitor } from '@swc/core/Visitor';
|
|
5
|
+
|
|
6
|
+
function noopSpan() {
|
|
7
|
+
return { start: 0, end: 0, ctxt: 0 };
|
|
8
|
+
}
|
|
9
|
+
function byteOffsetToLineCol(src, pos) {
|
|
10
|
+
let line = 1;
|
|
11
|
+
let col = 0;
|
|
12
|
+
const end = Math.min(pos, src.length);
|
|
13
|
+
for (let i = 0; i < end; i++) {
|
|
14
|
+
const c = src[i];
|
|
15
|
+
if (c === "\n") {
|
|
16
|
+
line++;
|
|
17
|
+
col = 0;
|
|
18
|
+
} else {
|
|
19
|
+
col++;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return { line, col };
|
|
23
|
+
}
|
|
24
|
+
var WeevarJsxVisitor = class extends Visitor {
|
|
25
|
+
constructor(src, relFile) {
|
|
26
|
+
super();
|
|
27
|
+
this.src = src;
|
|
28
|
+
this.relFile = relFile;
|
|
29
|
+
}
|
|
30
|
+
visitJSXOpeningElement(n) {
|
|
31
|
+
const hasDataWv = n.attributes.some(
|
|
32
|
+
(a) => a.type === "JSXAttribute" && a.name.type === "Identifier" && a.name.value === "data-wv-source"
|
|
33
|
+
);
|
|
34
|
+
if (hasDataWv) return super.visitJSXOpeningElement(n);
|
|
35
|
+
const { line, col } = byteOffsetToLineCol(this.src, n.span.start);
|
|
36
|
+
const payload = encodeDataWvSource({
|
|
37
|
+
file: this.relFile,
|
|
38
|
+
line,
|
|
39
|
+
col
|
|
40
|
+
});
|
|
41
|
+
const name = {
|
|
42
|
+
type: "Identifier",
|
|
43
|
+
span: noopSpan(),
|
|
44
|
+
value: "data-wv-source",
|
|
45
|
+
optional: false
|
|
46
|
+
};
|
|
47
|
+
const value = {
|
|
48
|
+
type: "StringLiteral",
|
|
49
|
+
span: noopSpan(),
|
|
50
|
+
value: payload,
|
|
51
|
+
raw: JSON.stringify(payload)
|
|
52
|
+
};
|
|
53
|
+
const attr = {
|
|
54
|
+
type: "JSXAttribute",
|
|
55
|
+
span: noopSpan(),
|
|
56
|
+
name,
|
|
57
|
+
value
|
|
58
|
+
};
|
|
59
|
+
const next = {
|
|
60
|
+
...n,
|
|
61
|
+
attributes: [...n.attributes, attr]
|
|
62
|
+
};
|
|
63
|
+
return super.visitJSXOpeningElement(next);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
function transformJsxWithWeevarSourceSwc(code, absFile, cwd) {
|
|
67
|
+
const rel = path.relative(cwd, absFile).split(path.sep).join("/") || absFile;
|
|
68
|
+
try {
|
|
69
|
+
const ast = parseSync(code, {
|
|
70
|
+
syntax: "typescript",
|
|
71
|
+
tsx: true,
|
|
72
|
+
decorators: false
|
|
73
|
+
});
|
|
74
|
+
const visitor = new WeevarJsxVisitor(code, rel);
|
|
75
|
+
const out = visitor.visitProgram(ast);
|
|
76
|
+
const printed = printSync(out, {
|
|
77
|
+
jsc: {
|
|
78
|
+
parser: { syntax: "typescript", tsx: true },
|
|
79
|
+
target: "es2022",
|
|
80
|
+
transform: {
|
|
81
|
+
react: { runtime: "automatic", development: false }
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return { code: printed.code };
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { transformJsxWithWeevarSourceSwc };
|
|
92
|
+
//# sourceMappingURL=swc.mjs.map
|
|
93
|
+
//# sourceMappingURL=swc.mjs.map
|
package/dist/swc.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/swc/transformJsxSource.ts"],"names":[],"mappings":"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","file":"swc.mjs","sourcesContent":["import path from \"node:path\";\nimport { parseSync, printSync } from \"@swc/core\";\nimport { Visitor } from \"@swc/core/Visitor\";\nimport type { Identifier, JSXAttribute, JSXOpeningElement, Program, Span, StringLiteral } from \"@swc/types\";\nimport { encodeDataWvSource } from \"../engine/parseDataWvSource\";\n\nfunction noopSpan(): Span {\n return { start: 0, end: 0, ctxt: 0 };\n}\n\nfunction byteOffsetToLineCol(src: string, pos: number): { line: number; col: number } {\n let line = 1;\n let col = 0;\n const end = Math.min(pos, src.length);\n for (let i = 0; i < end; i++) {\n const c = src[i];\n if (c === \"\\n\") {\n line++;\n col = 0;\n } else {\n col++;\n }\n }\n return { line, col };\n}\n\nclass WeevarJsxVisitor extends Visitor {\n constructor(\n private readonly src: string,\n private readonly relFile: string,\n ) {\n super();\n }\n\n visitJSXOpeningElement(n: JSXOpeningElement): JSXOpeningElement {\n const hasDataWv = n.attributes.some(\n (a) =>\n a.type === \"JSXAttribute\" &&\n a.name.type === \"Identifier\" &&\n a.name.value === \"data-wv-source\",\n );\n if (hasDataWv) return super.visitJSXOpeningElement(n);\n\n const { line, col } = byteOffsetToLineCol(this.src, n.span.start);\n const payload = encodeDataWvSource({\n file: this.relFile,\n line,\n col,\n });\n\n const name: Identifier = {\n type: \"Identifier\",\n span: noopSpan(),\n value: \"data-wv-source\",\n optional: false,\n };\n const value: StringLiteral = {\n type: \"StringLiteral\",\n span: noopSpan(),\n value: payload,\n raw: JSON.stringify(payload),\n };\n const attr: JSXAttribute = {\n type: \"JSXAttribute\",\n span: noopSpan(),\n name,\n value,\n };\n\n const next: JSXOpeningElement = {\n ...n,\n attributes: [...n.attributes, attr],\n };\n return super.visitJSXOpeningElement(next);\n }\n}\n\n/**\n * SWC-based JSX `data-wv-source` injection (for Next.js / @swc/core pipelines).\n * Peer: `@swc/core`. Falls back to returning null on parse/print failure.\n */\nexport function transformJsxWithWeevarSourceSwc(\n code: string,\n absFile: string,\n cwd: string,\n): { code: string } | null {\n const rel = path.relative(cwd, absFile).split(path.sep).join(\"/\") || absFile;\n try {\n const ast = parseSync(code, {\n syntax: \"typescript\",\n tsx: true,\n decorators: false,\n }) as Program;\n\n const visitor = new WeevarJsxVisitor(code, rel);\n const out = visitor.visitProgram(ast);\n const printed = printSync(out, {\n jsc: {\n parser: { syntax: \"typescript\", tsx: true },\n target: \"es2022\",\n transform: {\n react: { runtime: \"automatic\", development: false },\n },\n },\n });\n return { code: printed.code };\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Optional overrides (serializable). Functions can be added later via vite virtual module. */
|
|
2
|
+
type WeevarPromptConfig = {
|
|
3
|
+
/** When true, prompts include parent class strings verbatim (Tailwind-friendly). */
|
|
4
|
+
tailwindVerbatimClasses?: boolean;
|
|
5
|
+
/** From `tailwind.config` `content` when the Vite plugin can resolve it. */
|
|
6
|
+
tailwindContentGlobs?: string[];
|
|
7
|
+
/** e.g. `tailwind.config.ts` for prompt context. */
|
|
8
|
+
tailwindConfigPath?: string;
|
|
9
|
+
};
|
|
10
|
+
type WeevarRuntimeConfig = {
|
|
11
|
+
prompts?: WeevarPromptConfig;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type WeevarKeybind = {
|
|
15
|
+
/** e.g. 'e' with meta+shift */
|
|
16
|
+
key: string;
|
|
17
|
+
meta?: boolean;
|
|
18
|
+
ctrl?: boolean;
|
|
19
|
+
shift?: boolean;
|
|
20
|
+
alt?: boolean;
|
|
21
|
+
};
|
|
22
|
+
type WeevarProps = {
|
|
23
|
+
/** Override default ⌘⇧E / Ctrl+Shift+E */
|
|
24
|
+
keybind?: WeevarKeybind;
|
|
25
|
+
/** Disable all interaction */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** Runtime prompt / inspector options (merge with `virtual:weevar-config` if used). */
|
|
28
|
+
config?: WeevarRuntimeConfig;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type { WeevarProps as W, WeevarKeybind as a, WeevarRuntimeConfig as b };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Optional overrides (serializable). Functions can be added later via vite virtual module. */
|
|
2
|
+
type WeevarPromptConfig = {
|
|
3
|
+
/** When true, prompts include parent class strings verbatim (Tailwind-friendly). */
|
|
4
|
+
tailwindVerbatimClasses?: boolean;
|
|
5
|
+
/** From `tailwind.config` `content` when the Vite plugin can resolve it. */
|
|
6
|
+
tailwindContentGlobs?: string[];
|
|
7
|
+
/** e.g. `tailwind.config.ts` for prompt context. */
|
|
8
|
+
tailwindConfigPath?: string;
|
|
9
|
+
};
|
|
10
|
+
type WeevarRuntimeConfig = {
|
|
11
|
+
prompts?: WeevarPromptConfig;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type WeevarKeybind = {
|
|
15
|
+
/** e.g. 'e' with meta+shift */
|
|
16
|
+
key: string;
|
|
17
|
+
meta?: boolean;
|
|
18
|
+
ctrl?: boolean;
|
|
19
|
+
shift?: boolean;
|
|
20
|
+
alt?: boolean;
|
|
21
|
+
};
|
|
22
|
+
type WeevarProps = {
|
|
23
|
+
/** Override default ⌘⇧E / Ctrl+Shift+E */
|
|
24
|
+
keybind?: WeevarKeybind;
|
|
25
|
+
/** Disable all interaction */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** Runtime prompt / inspector options (merge with `virtual:weevar-config` if used). */
|
|
28
|
+
config?: WeevarRuntimeConfig;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type { WeevarProps as W, WeevarKeybind as a, WeevarRuntimeConfig as b };
|
package/dist/vite.d.mts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/** Merges `weevar.config.json` with optional `weevar.config.mjs` / `weevar.config.js` (JS wins on overlap). */
|
|
4
|
+
declare function loadMergedWeevarConfig(cwd: string): Promise<Record<string, unknown>>;
|
|
5
|
+
/**
|
|
6
|
+
* Vite integration:
|
|
7
|
+
* - `virtual:weevar-config` — merged JSON + optional JS config, Tailwind file hint.
|
|
8
|
+
* - JSX/TSX transform — injects `data-wv-source` when missing (build-time source map).
|
|
9
|
+
*/
|
|
10
|
+
declare function weevar(): Plugin;
|
|
11
|
+
|
|
12
|
+
export { loadMergedWeevarConfig, weevar };
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/** Merges `weevar.config.json` with optional `weevar.config.mjs` / `weevar.config.js` (JS wins on overlap). */
|
|
4
|
+
declare function loadMergedWeevarConfig(cwd: string): Promise<Record<string, unknown>>;
|
|
5
|
+
/**
|
|
6
|
+
* Vite integration:
|
|
7
|
+
* - `virtual:weevar-config` — merged JSON + optional JS config, Tailwind file hint.
|
|
8
|
+
* - JSX/TSX transform — injects `data-wv-source` when missing (build-time source map).
|
|
9
|
+
*/
|
|
10
|
+
declare function weevar(): Plugin;
|
|
11
|
+
|
|
12
|
+
export { loadMergedWeevarConfig, weevar };
|
package/dist/vite.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var path2 = require('path');
|
|
5
|
+
var url = require('url');
|
|
6
|
+
var babel = require('@babel/core');
|
|
7
|
+
var t = require('@babel/types');
|
|
8
|
+
|
|
9
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
function _interopNamespace(e) {
|
|
12
|
+
if (e && e.__esModule) return e;
|
|
13
|
+
var n = Object.create(null);
|
|
14
|
+
if (e) {
|
|
15
|
+
Object.keys(e).forEach(function (k) {
|
|
16
|
+
if (k !== 'default') {
|
|
17
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
18
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return e[k]; }
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
n.default = e;
|
|
26
|
+
return Object.freeze(n);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
30
|
+
var path2__default = /*#__PURE__*/_interopDefault(path2);
|
|
31
|
+
var babel__namespace = /*#__PURE__*/_interopNamespace(babel);
|
|
32
|
+
var t__namespace = /*#__PURE__*/_interopNamespace(t);
|
|
33
|
+
|
|
34
|
+
// src/vite/plugin.ts
|
|
35
|
+
|
|
36
|
+
// src/engine/parseDataWvSource.ts
|
|
37
|
+
function encodeDataWvSource(loc) {
|
|
38
|
+
const json = JSON.stringify({
|
|
39
|
+
file: loc.file,
|
|
40
|
+
line: loc.line,
|
|
41
|
+
col: loc.col
|
|
42
|
+
});
|
|
43
|
+
return btoa(unescape(encodeURIComponent(json)));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/vite/babelAddSource.ts
|
|
47
|
+
function weevarJsxSourcePlugin(absFile, cwd) {
|
|
48
|
+
const rel = path2__default.default.relative(cwd, absFile).split(path2__default.default.sep).join("/") || absFile;
|
|
49
|
+
return {
|
|
50
|
+
name: "weevar-jsx-source-attr",
|
|
51
|
+
visitor: {
|
|
52
|
+
JSXOpeningElement(p) {
|
|
53
|
+
const loc = p.node.loc;
|
|
54
|
+
if (!loc) return;
|
|
55
|
+
const attrs = p.node.attributes;
|
|
56
|
+
if (attrs.some(
|
|
57
|
+
(a) => a.type === "JSXAttribute" && "name" in a && a.name.type === "JSXIdentifier" && a.name.name === "data-wv-source"
|
|
58
|
+
))
|
|
59
|
+
return;
|
|
60
|
+
const payload = encodeDataWvSource({
|
|
61
|
+
file: rel,
|
|
62
|
+
line: loc.start.line,
|
|
63
|
+
col: loc.start.column
|
|
64
|
+
});
|
|
65
|
+
attrs.push(
|
|
66
|
+
t__namespace.jsxAttribute(t__namespace.jsxIdentifier("data-wv-source"), t__namespace.stringLiteral(payload))
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function transformJsxWithWeevarSource(code, absFile, cwd) {
|
|
73
|
+
try {
|
|
74
|
+
const result = babel__namespace.transformSync(code, {
|
|
75
|
+
filename: absFile,
|
|
76
|
+
cwd,
|
|
77
|
+
ast: false,
|
|
78
|
+
babelrc: false,
|
|
79
|
+
configFile: false,
|
|
80
|
+
sourceMaps: true,
|
|
81
|
+
presets: [
|
|
82
|
+
["@babel/preset-typescript", { isTSX: true, allExtensions: true }],
|
|
83
|
+
["@babel/preset-react", { runtime: "automatic" }]
|
|
84
|
+
],
|
|
85
|
+
plugins: [weevarJsxSourcePlugin(absFile, cwd)]
|
|
86
|
+
});
|
|
87
|
+
if (!result?.code) return null;
|
|
88
|
+
return { code: result.code, map: result.map ?? null };
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
var TAILWIND_CONFIG_NAMES = [
|
|
94
|
+
"tailwind.config.js",
|
|
95
|
+
"tailwind.config.cjs",
|
|
96
|
+
"tailwind.config.mjs",
|
|
97
|
+
"tailwind.config.ts"
|
|
98
|
+
];
|
|
99
|
+
function findTailwindConfigPath(cwd) {
|
|
100
|
+
for (const n of TAILWIND_CONFIG_NAMES) {
|
|
101
|
+
const p = path2__default.default.join(cwd, n);
|
|
102
|
+
if (fs__default.default.existsSync(p)) return n;
|
|
103
|
+
}
|
|
104
|
+
return void 0;
|
|
105
|
+
}
|
|
106
|
+
function readTailwindPackageFlag(cwd) {
|
|
107
|
+
try {
|
|
108
|
+
const pkgPath = path2__default.default.join(cwd, "package.json");
|
|
109
|
+
if (!fs__default.default.existsSync(pkgPath)) return false;
|
|
110
|
+
const pkg = JSON.parse(fs__default.default.readFileSync(pkgPath, "utf8"));
|
|
111
|
+
return Boolean(
|
|
112
|
+
pkg.dependencies?.tailwindcss ?? pkg.devDependencies?.tailwindcss
|
|
113
|
+
);
|
|
114
|
+
} catch {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function extractContentGlobsFromTailwindSource(src) {
|
|
119
|
+
const m = src.match(/content\s*:\s*\[([\s\S]*?)\]/);
|
|
120
|
+
if (!m) return void 0;
|
|
121
|
+
const inner = m[1];
|
|
122
|
+
const globs = [];
|
|
123
|
+
const strRe = /['"]([^'"]+)['"]/g;
|
|
124
|
+
let sm;
|
|
125
|
+
while (sm = strRe.exec(inner)) globs.push(sm[1]);
|
|
126
|
+
return globs.length ? globs : void 0;
|
|
127
|
+
}
|
|
128
|
+
async function tryImportTailwindConfig(cwd) {
|
|
129
|
+
const rel = findTailwindConfigPath(cwd);
|
|
130
|
+
if (!rel) return {};
|
|
131
|
+
const abs = path2__default.default.join(cwd, rel);
|
|
132
|
+
const base = {
|
|
133
|
+
configPath: rel,
|
|
134
|
+
tailwindPackagePresent: readTailwindPackageFlag(cwd)
|
|
135
|
+
};
|
|
136
|
+
if (rel.endsWith(".ts")) {
|
|
137
|
+
try {
|
|
138
|
+
const src = fs__default.default.readFileSync(abs, "utf8");
|
|
139
|
+
const globs = extractContentGlobsFromTailwindSource(src);
|
|
140
|
+
return globs?.length ? { ...base, contentGlobs: globs } : base;
|
|
141
|
+
} catch {
|
|
142
|
+
return base;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
const href = url.pathToFileURL(abs).href + `?t=${Date.now()}`;
|
|
147
|
+
const mod = await import(href);
|
|
148
|
+
const content = mod.default?.content;
|
|
149
|
+
if (Array.isArray(content)) {
|
|
150
|
+
const globs = content.filter((x) => typeof x === "string");
|
|
151
|
+
if (globs.length) return { ...base, contentGlobs: globs };
|
|
152
|
+
}
|
|
153
|
+
} catch {
|
|
154
|
+
try {
|
|
155
|
+
const src = fs__default.default.readFileSync(abs, "utf8");
|
|
156
|
+
const globs = extractContentGlobsFromTailwindSource(src);
|
|
157
|
+
return globs?.length ? { ...base, contentGlobs: globs } : base;
|
|
158
|
+
} catch {
|
|
159
|
+
return base;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return base;
|
|
163
|
+
}
|
|
164
|
+
async function probeTailwindHints(cwd) {
|
|
165
|
+
const pkg = readTailwindPackageFlag(cwd);
|
|
166
|
+
const cfgPath = findTailwindConfigPath(cwd);
|
|
167
|
+
if (!cfgPath && !pkg) return {};
|
|
168
|
+
const imported = await tryImportTailwindConfig(cwd);
|
|
169
|
+
return {
|
|
170
|
+
...imported,
|
|
171
|
+
tailwindPackagePresent: pkg || imported.tailwindPackagePresent,
|
|
172
|
+
configPath: imported.configPath ?? cfgPath
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/vite/plugin.ts
|
|
177
|
+
var VIRTUAL = "\0virtual:weevar-config";
|
|
178
|
+
function isPlainObject(v) {
|
|
179
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
180
|
+
}
|
|
181
|
+
function deepMerge(base, over) {
|
|
182
|
+
const out = { ...base };
|
|
183
|
+
for (const key of Object.keys(over)) {
|
|
184
|
+
const bv = over[key];
|
|
185
|
+
const av = base[key];
|
|
186
|
+
if (isPlainObject(bv) && isPlainObject(av)) {
|
|
187
|
+
out[key] = deepMerge(av, bv);
|
|
188
|
+
} else {
|
|
189
|
+
out[key] = bv;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
194
|
+
async function loadOptionalJsConfig(cwd) {
|
|
195
|
+
const mjsPath = path2__default.default.join(cwd, "weevar.config.mjs");
|
|
196
|
+
const jsPath = path2__default.default.join(cwd, "weevar.config.js");
|
|
197
|
+
const pick = fs__default.default.existsSync(mjsPath) ? mjsPath : fs__default.default.existsSync(jsPath) ? jsPath : null;
|
|
198
|
+
if (!pick) return {};
|
|
199
|
+
try {
|
|
200
|
+
const href = url.pathToFileURL(pick).href + `?t=${Date.now()}`;
|
|
201
|
+
const mod = await import(href);
|
|
202
|
+
const def = mod.default;
|
|
203
|
+
return isPlainObject(def) ? def : {};
|
|
204
|
+
} catch {
|
|
205
|
+
return {};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async function loadMergedWeevarConfig(cwd) {
|
|
209
|
+
const jsonPath = path2__default.default.join(cwd, "weevar.config.json");
|
|
210
|
+
let jsonObj = {};
|
|
211
|
+
try {
|
|
212
|
+
if (fs__default.default.existsSync(jsonPath)) {
|
|
213
|
+
const parsed = JSON.parse(fs__default.default.readFileSync(jsonPath, "utf8"));
|
|
214
|
+
jsonObj = isPlainObject(parsed) ? parsed : {};
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
jsonObj = {};
|
|
218
|
+
}
|
|
219
|
+
const jsOverlay = await loadOptionalJsConfig(cwd);
|
|
220
|
+
const merged = deepMerge(jsonObj, jsOverlay);
|
|
221
|
+
const tw = await probeTailwindHints(cwd);
|
|
222
|
+
if (tw.configPath || tw.tailwindPackagePresent || tw.contentGlobs?.length) {
|
|
223
|
+
const prompts = isPlainObject(merged.prompts) ? { ...merged.prompts } : {};
|
|
224
|
+
if (prompts.tailwindVerbatimClasses === void 0 && (tw.configPath || tw.tailwindPackagePresent))
|
|
225
|
+
prompts.tailwindVerbatimClasses = true;
|
|
226
|
+
if (tw.contentGlobs?.length && prompts.tailwindContentGlobs === void 0)
|
|
227
|
+
prompts.tailwindContentGlobs = tw.contentGlobs;
|
|
228
|
+
if (tw.configPath && prompts.tailwindConfigPath === void 0)
|
|
229
|
+
prompts.tailwindConfigPath = tw.configPath;
|
|
230
|
+
merged.prompts = prompts;
|
|
231
|
+
}
|
|
232
|
+
return merged;
|
|
233
|
+
}
|
|
234
|
+
function weevar() {
|
|
235
|
+
return {
|
|
236
|
+
name: "weevar",
|
|
237
|
+
enforce: "pre",
|
|
238
|
+
resolveId(id) {
|
|
239
|
+
if (id === "virtual:weevar-config") return VIRTUAL;
|
|
240
|
+
},
|
|
241
|
+
async load(id) {
|
|
242
|
+
if (id !== VIRTUAL) return null;
|
|
243
|
+
const data = await loadMergedWeevarConfig(process.cwd());
|
|
244
|
+
return `export default ${JSON.stringify(data)};`;
|
|
245
|
+
},
|
|
246
|
+
transform(code, id) {
|
|
247
|
+
if (!/\.(tsx|jsx)$/.test(id)) return null;
|
|
248
|
+
if (id.includes("node_modules")) return null;
|
|
249
|
+
const out = transformJsxWithWeevarSource(code, id, process.cwd());
|
|
250
|
+
if (!out) return null;
|
|
251
|
+
return { code: out.code, map: out.map ?? void 0 };
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
exports.loadMergedWeevarConfig = loadMergedWeevarConfig;
|
|
257
|
+
exports.weevar = weevar;
|
|
258
|
+
//# sourceMappingURL=vite.js.map
|
|
259
|
+
//# sourceMappingURL=vite.js.map
|