@runner-ai/vite-uuid-tagger 0.0.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/dist/features/dev-middleware.d.ts +7 -0
- package/dist/features/dev-middleware.d.ts.map +1 -0
- package/dist/features/dev-middleware.js +16 -0
- package/dist/features/jsx-source-tagger.d.ts +9 -0
- package/dist/features/jsx-source-tagger.d.ts.map +1 -0
- package/dist/features/jsx-source-tagger.js +87 -0
- package/dist/features/tailwind-registry.d.ts +20 -0
- package/dist/features/tailwind-registry.d.ts.map +1 -0
- package/dist/features/tailwind-registry.js +185 -0
- package/dist/features/virtual-overrides.d.ts +8 -0
- package/dist/features/virtual-overrides.d.ts.map +1 -0
- package/dist/features/virtual-overrides.js +76 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +56 -0
- package/dist/runtime/content-extraction.d.ts +11 -0
- package/dist/runtime/content-extraction.d.ts.map +1 -0
- package/dist/runtime/content-extraction.js +35 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-middleware.d.ts","sourceRoot":"","sources":["../../src/features/dev-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAE1C,UAAU,kBAAkB;IAC1B,eAAe,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;CAClD;AAED,wBAAgB,mBAAmB,IAAI,kBAAkB,CAexD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function createDevMiddleware() {
|
|
2
|
+
return {
|
|
3
|
+
configureServer(server) {
|
|
4
|
+
// biome-ignore lint/suspicious/noExplicitAny: Vite Connect middleware types
|
|
5
|
+
server.middlewares.use((req, res, next) => {
|
|
6
|
+
if (req.url === '/uuid-mappings.json') {
|
|
7
|
+
res.statusCode = 200;
|
|
8
|
+
res.setHeader('content-type', 'application/json');
|
|
9
|
+
res.end(JSON.stringify({}));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
next();
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface JsxSourceTaggerHooks {
|
|
2
|
+
resolveId: (this: unknown, source: string, importer: string | undefined, options?: {
|
|
3
|
+
ssr?: boolean;
|
|
4
|
+
}) => string | null;
|
|
5
|
+
load: (id: string) => string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function createJsxSourceTagger(): JsxSourceTaggerHooks;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=jsx-source-tagger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-source-tagger.d.ts","sourceRoot":"","sources":["../../src/features/jsx-source-tagger.ts"],"names":[],"mappings":"AAgEA,UAAU,oBAAoB;IAC5B,SAAS,EAAE,CACT,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,KACxB,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,wBAAgB,qBAAqB,IAAI,oBAAoB,CA4B5D"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const CLIENT_RUNTIME_CODE = `
|
|
2
|
+
import { jsxDEV as _jsxDEV, Fragment } from 'react/jsx-dev-runtime';
|
|
3
|
+
|
|
4
|
+
if (typeof window !== 'undefined' && !window.sourceElementMap) {
|
|
5
|
+
window.sourceElementMap = new Map();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function getCleanFileName(fileName) {
|
|
9
|
+
if (!fileName) return '';
|
|
10
|
+
return fileName
|
|
11
|
+
.replace(/^.*?\\/src\\//, 'src/')
|
|
12
|
+
.replace(/^\\//, '');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function wrapRef(originalRef, sourceInfo) {
|
|
16
|
+
return function taggedRef(node) {
|
|
17
|
+
if (node && node instanceof Element) {
|
|
18
|
+
var loc = sourceInfo.fileName + ':' + sourceInfo.lineNumber + ':' + sourceInfo.columnNumber;
|
|
19
|
+
node.setAttribute('data-uuid-loc', loc);
|
|
20
|
+
|
|
21
|
+
var sym = Symbol.for('__jsxSource__');
|
|
22
|
+
node[sym] = sourceInfo;
|
|
23
|
+
|
|
24
|
+
if (typeof window !== 'undefined' && window.sourceElementMap) {
|
|
25
|
+
var key = loc;
|
|
26
|
+
if (!window.sourceElementMap.has(key)) {
|
|
27
|
+
window.sourceElementMap.set(key, new Set());
|
|
28
|
+
}
|
|
29
|
+
window.sourceElementMap.get(key).add(new WeakRef(node));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (typeof originalRef === 'function') {
|
|
34
|
+
originalRef(node);
|
|
35
|
+
} else if (originalRef && typeof originalRef === 'object') {
|
|
36
|
+
originalRef.current = node;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
|
42
|
+
if (source && source.fileName && typeof type === 'string') {
|
|
43
|
+
var cleanFileName = getCleanFileName(source.fileName);
|
|
44
|
+
var sourceInfo = {
|
|
45
|
+
fileName: cleanFileName,
|
|
46
|
+
lineNumber: source.lineNumber || 0,
|
|
47
|
+
columnNumber: source.columnNumber || 0,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
var newProps = Object.assign({}, props);
|
|
51
|
+
newProps.ref = wrapRef(props ? props.ref : undefined, sourceInfo);
|
|
52
|
+
|
|
53
|
+
return _jsxDEV(type, newProps, key, isStaticChildren, source, self);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return _jsxDEV(type, props, key, isStaticChildren, source, self);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { Fragment };
|
|
60
|
+
export { jsx, jsxs } from 'react/jsx-dev-runtime';
|
|
61
|
+
`;
|
|
62
|
+
const PASSTHROUGH_CODE = `export * from 'react/jsx-dev-runtime';\n`;
|
|
63
|
+
export function createJsxSourceTagger() {
|
|
64
|
+
return {
|
|
65
|
+
resolveId(source, importer, options) {
|
|
66
|
+
if (source !== 'react/jsx-dev-runtime') {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (importer?.includes('\0runner-jsx')) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const self = this;
|
|
73
|
+
const env = self?.environment;
|
|
74
|
+
const isSSR = env?.config?.consumer === 'server' || options?.ssr === true;
|
|
75
|
+
return isSSR ? '\0runner-jsx/passthrough' : '\0runner-jsx/client-runtime';
|
|
76
|
+
},
|
|
77
|
+
load(id) {
|
|
78
|
+
if (id === '\0runner-jsx/client-runtime') {
|
|
79
|
+
return CLIENT_RUNTIME_CODE;
|
|
80
|
+
}
|
|
81
|
+
if (id === '\0runner-jsx/passthrough') {
|
|
82
|
+
return PASSTHROUGH_CODE;
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface TailwindRegistryHooks {
|
|
2
|
+
buildStart: () => Promise<void>;
|
|
3
|
+
transformIndexHtml: (html: string) => string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Parse CSS content for @theme and :root color variables.
|
|
7
|
+
* @theme colors take precedence over :root.
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseThemeColors(cssContent: string): Record<string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Build runtime script that exposes window.__TAILWIND_REGISTRY__
|
|
12
|
+
* and posts TAILWIND_REGISTRY_UPDATE to parent frame.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildColorRegistry(tailwindColors?: Record<string, unknown>, tailwindSpacing?: Record<string, unknown>, themeColors?: Record<string, string>): string;
|
|
15
|
+
/**
|
|
16
|
+
* Create Tailwind registry feature hooks for the Vite plugin.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createTailwindRegistry(): TailwindRegistryHooks;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=tailwind-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tailwind-registry.d.ts","sourceRoot":"","sources":["../../src/features/tailwind-registry.ts"],"names":[],"mappings":"AAGA,UAAU,qBAAqB;IAC7B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0B3E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAC5C,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAC7C,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACvC,MAAM,CAoGR;AAuBD;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,qBAAqB,CAqC9D"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import glob from 'fast-glob';
|
|
3
|
+
/**
|
|
4
|
+
* Parse CSS content for @theme and :root color variables.
|
|
5
|
+
* @theme colors take precedence over :root.
|
|
6
|
+
*/
|
|
7
|
+
export function parseThemeColors(cssContent) {
|
|
8
|
+
const themeColors = {};
|
|
9
|
+
// Match @theme blocks
|
|
10
|
+
const themeRegex = /@theme\s*\{([^}]*)\}/gs;
|
|
11
|
+
for (const match of cssContent.matchAll(themeRegex)) {
|
|
12
|
+
const content = match[1];
|
|
13
|
+
const colorRegex = /--color-([\w-]+):\s*([^;]+);/g;
|
|
14
|
+
for (const colorMatch of content.matchAll(colorRegex)) {
|
|
15
|
+
themeColors[colorMatch[1]] = colorMatch[2].trim();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// Match :root blocks — only add if not already defined in @theme
|
|
19
|
+
const rootRegex = /:root\s*\{([^}]*)\}/gs;
|
|
20
|
+
for (const match of cssContent.matchAll(rootRegex)) {
|
|
21
|
+
const content = match[1];
|
|
22
|
+
const colorRegex = /--color-([\w-]+):\s*([^;]+);/g;
|
|
23
|
+
for (const colorMatch of content.matchAll(colorRegex)) {
|
|
24
|
+
if (!themeColors[colorMatch[1]]) {
|
|
25
|
+
themeColors[colorMatch[1]] = colorMatch[2].trim();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return themeColors;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build runtime script that exposes window.__TAILWIND_REGISTRY__
|
|
33
|
+
* and posts TAILWIND_REGISTRY_UPDATE to parent frame.
|
|
34
|
+
*/
|
|
35
|
+
export function buildColorRegistry(tailwindColors = {}, tailwindSpacing = {}, themeColors = {}) {
|
|
36
|
+
const serializedColors = JSON.stringify(tailwindColors, (_, value) => typeof value === 'function' ? undefined : value);
|
|
37
|
+
const serializedSpacing = JSON.stringify(tailwindSpacing, (_, value) => typeof value === 'function' ? undefined : value);
|
|
38
|
+
const serializedThemeColors = JSON.stringify(themeColors);
|
|
39
|
+
return `
|
|
40
|
+
(function() {
|
|
41
|
+
var registry = { default: {}, custom: {} };
|
|
42
|
+
|
|
43
|
+
var tailwindColors = ${serializedColors};
|
|
44
|
+
if (tailwindColors && Object.keys(tailwindColors).length > 0) {
|
|
45
|
+
Object.entries(tailwindColors).forEach(function(entry) {
|
|
46
|
+
var name = entry[0], shades = entry[1];
|
|
47
|
+
if (name === 'lightBlue' || name === 'warmGray' || name === 'trueGray' || name === 'coolGray' || name === 'blueGray' || typeof shades === 'function') return;
|
|
48
|
+
if (typeof shades === 'object' && shades !== null && !Array.isArray(shades)) {
|
|
49
|
+
registry.default[name] = {};
|
|
50
|
+
Object.entries(shades).forEach(function(se) {
|
|
51
|
+
var shade = se[0], value = se[1];
|
|
52
|
+
if (typeof value === 'string') {
|
|
53
|
+
registry.default[name][shade] = {
|
|
54
|
+
value: value,
|
|
55
|
+
classes: { bg: 'bg-' + name + '-' + shade, text: 'text-' + name + '-' + shade, border: 'border-' + name + '-' + shade, ring: 'ring-' + name + '-' + shade }
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
} else if (typeof shades === 'string') {
|
|
60
|
+
registry.default[name] = {
|
|
61
|
+
value: shades,
|
|
62
|
+
classes: { bg: 'bg-' + name, text: 'text-' + name, border: 'border-' + name }
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
var themeColors = ${serializedThemeColors};
|
|
69
|
+
Object.entries(themeColors).forEach(function(entry) {
|
|
70
|
+
var name = entry[0], value = entry[1];
|
|
71
|
+
registry.custom[name] = {
|
|
72
|
+
value: value,
|
|
73
|
+
variable: '--color-' + name,
|
|
74
|
+
classes: { bg: 'bg-' + name, text: 'text-' + name, border: 'border-' + name, ring: 'ring-' + name }
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
var computed = getComputedStyle(document.documentElement);
|
|
79
|
+
var cssVarArray = Array.from(computed).filter(function(p) { return p.startsWith('--'); });
|
|
80
|
+
cssVarArray.forEach(function(prop) {
|
|
81
|
+
if (prop.startsWith('--color-')) {
|
|
82
|
+
var value = computed.getPropertyValue(prop).trim();
|
|
83
|
+
var name = prop.replace('--color-', '').replace(/^-+|-+$/g, '');
|
|
84
|
+
if (!registry.custom[name]) {
|
|
85
|
+
registry.custom[name] = {
|
|
86
|
+
value: value, variable: prop,
|
|
87
|
+
classes: { bg: 'bg-' + name, text: 'text-' + name, border: 'border-' + name, ring: 'ring-' + name }
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
var tailwindSpacing = ${serializedSpacing};
|
|
94
|
+
var spacingRegistry = {};
|
|
95
|
+
if (tailwindSpacing && Object.keys(tailwindSpacing).length > 0) {
|
|
96
|
+
Object.entries(tailwindSpacing).forEach(function(entry) {
|
|
97
|
+
if (typeof entry[1] === 'string') spacingRegistry[entry[0]] = entry[1];
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
var baseSpacing = '0.25rem';
|
|
102
|
+
cssVarArray.forEach(function(prop) {
|
|
103
|
+
if (prop === '--spacing') baseSpacing = computed.getPropertyValue(prop).trim();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (Object.keys(spacingRegistry).length === 0) {
|
|
107
|
+
var scale = [0, 'px', 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96];
|
|
108
|
+
scale.forEach(function(step) {
|
|
109
|
+
if (step === 0) { spacingRegistry['0'] = '0'; }
|
|
110
|
+
else if (step === 'px') { spacingRegistry['px'] = '1px'; }
|
|
111
|
+
else {
|
|
112
|
+
var match = baseSpacing.match(/([0-9.]+)([a-z%]+)/);
|
|
113
|
+
if (match) spacingRegistry[String(step)] = (parseFloat(match[1]) * step) + match[2];
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
window.__TAILWIND_REGISTRY__ = {
|
|
119
|
+
colors: registry,
|
|
120
|
+
spacing: spacingRegistry,
|
|
121
|
+
baseSpacing: baseSpacing,
|
|
122
|
+
timestamp: Date.now()
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
if (window.parent !== window) {
|
|
126
|
+
window.parent.postMessage({ type: 'TAILWIND_REGISTRY_UPDATE', data: window.__TAILWIND_REGISTRY__ }, '*');
|
|
127
|
+
}
|
|
128
|
+
})();
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Attempt to load Tailwind default theme colors and spacing from the host project.
|
|
133
|
+
*/
|
|
134
|
+
async function loadTailwindDefaults() {
|
|
135
|
+
try {
|
|
136
|
+
const defaultTheme = await import('tailwindcss/defaultTheme.js');
|
|
137
|
+
const rawColors = defaultTheme?.default?.colors;
|
|
138
|
+
const rawSpacing = defaultTheme?.default?.spacing;
|
|
139
|
+
const colors = typeof rawColors === 'function' ? rawColors() : (rawColors ?? {});
|
|
140
|
+
const spacing = typeof rawSpacing === 'function' ? rawSpacing() : (rawSpacing ?? {});
|
|
141
|
+
return { colors, spacing };
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return { colors: {}, spacing: {} };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Create Tailwind registry feature hooks for the Vite plugin.
|
|
149
|
+
*/
|
|
150
|
+
export function createTailwindRegistry() {
|
|
151
|
+
let tailwindColors = {};
|
|
152
|
+
let tailwindSpacing = {};
|
|
153
|
+
let themeColors = {};
|
|
154
|
+
return {
|
|
155
|
+
async buildStart() {
|
|
156
|
+
const tw = await loadTailwindDefaults();
|
|
157
|
+
tailwindColors = tw.colors;
|
|
158
|
+
tailwindSpacing = tw.spacing;
|
|
159
|
+
try {
|
|
160
|
+
const cssFiles = await glob('**/*.css', {
|
|
161
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/.next/**', '**/.git/**', '**/build/**'],
|
|
162
|
+
cwd: process.cwd(),
|
|
163
|
+
absolute: true,
|
|
164
|
+
});
|
|
165
|
+
for (const file of cssFiles) {
|
|
166
|
+
try {
|
|
167
|
+
const content = await fs.readFile(file, 'utf-8');
|
|
168
|
+
const parsed = parseThemeColors(content);
|
|
169
|
+
themeColors = { ...themeColors, ...parsed };
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Skip unreadable files
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Glob failure is non-fatal
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
transformIndexHtml(html) {
|
|
181
|
+
const script = buildColorRegistry(tailwindColors, tailwindSpacing, themeColors);
|
|
182
|
+
return html.replace('</body>', `<script>${script}</script></body>`);
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ViteDevServer } from 'vite';
|
|
2
|
+
interface VirtualOverridesHooks {
|
|
3
|
+
configureServer: (server: ViteDevServer) => void;
|
|
4
|
+
load: (id: string) => string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function createVirtualOverrides(): VirtualOverridesHooks;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=virtual-overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-overrides.d.ts","sourceRoot":"","sources":["../../src/features/virtual-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAE1C,UAAU,qBAAqB;IAC7B,eAAe,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACrC;AAmBD,wBAAgB,sBAAsB,IAAI,qBAAqB,CAwE9D"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const LEADING_DOT_SLASH = /^\.\//;
|
|
2
|
+
const BACKSLASH = /\\/g;
|
|
3
|
+
function normalizePath(path) {
|
|
4
|
+
return path.replace(LEADING_DOT_SLASH, '').replace(BACKSLASH, '/');
|
|
5
|
+
}
|
|
6
|
+
function isPathSafe(path) {
|
|
7
|
+
if (path.includes('..')) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if (path.includes('node_modules')) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
export function createVirtualOverrides() {
|
|
16
|
+
const overrides = new Map();
|
|
17
|
+
let _server = null;
|
|
18
|
+
function invalidateAndUpdate(path) {
|
|
19
|
+
if (!_server) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const normalizedPath = normalizePath(path);
|
|
23
|
+
const mod = _server.moduleGraph.getModuleById(normalizedPath);
|
|
24
|
+
if (mod) {
|
|
25
|
+
_server.moduleGraph.invalidateModule(mod);
|
|
26
|
+
_server.ws.send({
|
|
27
|
+
type: 'update',
|
|
28
|
+
updates: [
|
|
29
|
+
{
|
|
30
|
+
type: 'js-update',
|
|
31
|
+
path: mod.url,
|
|
32
|
+
acceptedPath: mod.url,
|
|
33
|
+
timestamp: Date.now(),
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
configureServer(server) {
|
|
41
|
+
_server = server;
|
|
42
|
+
server.ws.on('runner:override', (data) => {
|
|
43
|
+
const normalizedPath = normalizePath(data.path);
|
|
44
|
+
if (!isPathSafe(normalizedPath)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
overrides.set(normalizedPath, data.content);
|
|
48
|
+
invalidateAndUpdate(normalizedPath);
|
|
49
|
+
});
|
|
50
|
+
server.ws.on('runner:clear-override', (data) => {
|
|
51
|
+
const normalizedPath = normalizePath(data.path);
|
|
52
|
+
overrides.delete(normalizedPath);
|
|
53
|
+
invalidateAndUpdate(normalizedPath);
|
|
54
|
+
});
|
|
55
|
+
server.ws.on('runner:clear-all-overrides', () => {
|
|
56
|
+
const paths = Array.from(overrides.keys());
|
|
57
|
+
overrides.clear();
|
|
58
|
+
for (const path of paths) {
|
|
59
|
+
invalidateAndUpdate(path);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
load(id) {
|
|
64
|
+
if (!id) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
// Strip query parameters
|
|
68
|
+
const cleanId = id.split('?')[0];
|
|
69
|
+
const normalizedId = normalizePath(cleanId);
|
|
70
|
+
if (!isPathSafe(normalizedId)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return overrides.get(normalizedId) ?? null;
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,YAAY,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './plugin';
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAKnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,CA6DlF"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createDevMiddleware } from './features/dev-middleware';
|
|
2
|
+
import { createJsxSourceTagger } from './features/jsx-source-tagger';
|
|
3
|
+
import { createTailwindRegistry } from './features/tailwind-registry';
|
|
4
|
+
import { createVirtualOverrides } from './features/virtual-overrides';
|
|
5
|
+
export default function viteUuidTagger(options = {}) {
|
|
6
|
+
const { enabled = true, extractColors = true } = options;
|
|
7
|
+
if (!enabled) {
|
|
8
|
+
return {
|
|
9
|
+
name: 'vite-uuid-tagger',
|
|
10
|
+
enforce: 'pre',
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const jsxTagger = createJsxSourceTagger();
|
|
14
|
+
const overrides = createVirtualOverrides();
|
|
15
|
+
const tailwindRegistry = extractColors ? createTailwindRegistry() : null;
|
|
16
|
+
const devMiddleware = createDevMiddleware();
|
|
17
|
+
return {
|
|
18
|
+
name: 'vite-uuid-tagger',
|
|
19
|
+
enforce: 'pre',
|
|
20
|
+
resolveId(source, importer, resolveOptions) {
|
|
21
|
+
return jsxTagger.resolveId.call(this, source, importer, resolveOptions);
|
|
22
|
+
},
|
|
23
|
+
load(id) {
|
|
24
|
+
// Check overrides first (higher priority)
|
|
25
|
+
const overrideResult = overrides.load(id);
|
|
26
|
+
if (overrideResult !== null) {
|
|
27
|
+
return overrideResult;
|
|
28
|
+
}
|
|
29
|
+
// Then check JSX tagger
|
|
30
|
+
return jsxTagger.load(id);
|
|
31
|
+
},
|
|
32
|
+
config() {
|
|
33
|
+
return {
|
|
34
|
+
optimizeDeps: {
|
|
35
|
+
exclude: ['react/jsx-dev-runtime'],
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
configureServer(server) {
|
|
40
|
+
// Configure all server-side features
|
|
41
|
+
overrides.configureServer(server);
|
|
42
|
+
devMiddleware.configureServer(server);
|
|
43
|
+
},
|
|
44
|
+
async buildStart() {
|
|
45
|
+
if (tailwindRegistry) {
|
|
46
|
+
await tailwindRegistry.buildStart();
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
transformIndexHtml(html) {
|
|
50
|
+
if (tailwindRegistry) {
|
|
51
|
+
return tailwindRegistry.transformIndexHtml(html);
|
|
52
|
+
}
|
|
53
|
+
return html;
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract content metadata from a DOM element.
|
|
3
|
+
* Used in the client runtime's ref callback to set data-content attribute.
|
|
4
|
+
*/
|
|
5
|
+
export declare function extractContent(node: Element): Record<string, string>;
|
|
6
|
+
/**
|
|
7
|
+
* Encode content object as URI-encoded JSON string.
|
|
8
|
+
* Used for the data-content attribute value.
|
|
9
|
+
*/
|
|
10
|
+
export declare function encodeContent(content: Record<string, string>): string;
|
|
11
|
+
//# sourceMappingURL=content-extraction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-extraction.d.ts","sourceRoot":"","sources":["../../src/runtime/content-extraction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA4BpE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAErE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract content metadata from a DOM element.
|
|
3
|
+
* Used in the client runtime's ref callback to set data-content attribute.
|
|
4
|
+
*/
|
|
5
|
+
export function extractContent(node) {
|
|
6
|
+
const content = {};
|
|
7
|
+
// Extract className
|
|
8
|
+
const className = node.className;
|
|
9
|
+
if (className && typeof className === 'string' && className.trim()) {
|
|
10
|
+
content.className = className;
|
|
11
|
+
}
|
|
12
|
+
// Extract src from img/video elements
|
|
13
|
+
const src = node.getAttribute('src');
|
|
14
|
+
if (src) {
|
|
15
|
+
content.src = src;
|
|
16
|
+
}
|
|
17
|
+
// Extract placeholder from input elements
|
|
18
|
+
const placeholder = node.getAttribute('placeholder');
|
|
19
|
+
if (placeholder) {
|
|
20
|
+
content.placeholder = placeholder;
|
|
21
|
+
}
|
|
22
|
+
// Extract text content (only if element has text)
|
|
23
|
+
const text = node.textContent?.trim();
|
|
24
|
+
if (text) {
|
|
25
|
+
content.text = text;
|
|
26
|
+
}
|
|
27
|
+
return content;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Encode content object as URI-encoded JSON string.
|
|
31
|
+
* Used for the data-content attribute value.
|
|
32
|
+
*/
|
|
33
|
+
export function encodeContent(content) {
|
|
34
|
+
return encodeURIComponent(JSON.stringify(content));
|
|
35
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gEAAgE;IAChE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@runner-ai/vite-uuid-tagger",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"files": ["dist"],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc -b",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"clean": "rm -rf .turbo node_modules dist",
|
|
18
|
+
"publish:dev": "npm run build && npm publish --tag dev --access public",
|
|
19
|
+
"publish:prod": "npm run build && npm publish --access public"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"fast-glob": "^3.3.2"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"vite": "^7.0.0",
|
|
26
|
+
"@types/react": "^19.0.0",
|
|
27
|
+
"typescript": "^5.8.0",
|
|
28
|
+
"vitest": "^3.0.0"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"vite": ">=6.0.0"
|
|
32
|
+
}
|
|
33
|
+
}
|