@rspnseapp/dev-inspector 0.3.2 → 0.5.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/index.cjs +104 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +49 -0
- package/dist/index.inspector.js +2 -2
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/webpack.cjs +136 -0
- package/dist/webpack.cjs.map +1 -0
- package/dist/webpack.d.cts +59 -0
- package/dist/webpack.js +12 -3
- package/dist/webpack.js.map +1 -1
- package/package.json +27 -7
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
rspnseInspector: () => rspnseInspector
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/vite-plugin.ts
|
|
28
|
+
var import_fs = require("fs");
|
|
29
|
+
var import_path = require("path");
|
|
30
|
+
var import_url = require("url");
|
|
31
|
+
var import_meta = {};
|
|
32
|
+
function getDirname() {
|
|
33
|
+
if (typeof import_meta !== "undefined" && import_meta.url) {
|
|
34
|
+
return (0, import_path.dirname)((0, import_url.fileURLToPath)(import_meta.url));
|
|
35
|
+
}
|
|
36
|
+
if (typeof __dirname !== "undefined") {
|
|
37
|
+
return __dirname;
|
|
38
|
+
}
|
|
39
|
+
return process.cwd();
|
|
40
|
+
}
|
|
41
|
+
var moduleDir = getDirname();
|
|
42
|
+
function rspnseInspector(options = {}) {
|
|
43
|
+
const { enabled = true, trustedOrigins } = options;
|
|
44
|
+
let inspectorScript = null;
|
|
45
|
+
function getInspectorScript() {
|
|
46
|
+
if (inspectorScript) return inspectorScript;
|
|
47
|
+
try {
|
|
48
|
+
const scriptPath = (0, import_path.resolve)(moduleDir, "../dist/index.inspector.js");
|
|
49
|
+
inspectorScript = (0, import_fs.readFileSync)(scriptPath, "utf-8");
|
|
50
|
+
} catch {
|
|
51
|
+
try {
|
|
52
|
+
const scriptPath = (0, import_path.resolve)(moduleDir, "./index.inspector.js");
|
|
53
|
+
inspectorScript = (0, import_fs.readFileSync)(scriptPath, "utf-8");
|
|
54
|
+
} catch {
|
|
55
|
+
console.warn(
|
|
56
|
+
"[@rspnseapp/dev-inspector] Could not load inspector script. Run `npm run build` first."
|
|
57
|
+
);
|
|
58
|
+
inspectorScript = "// Inspector script not found";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return inspectorScript;
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
name: "rspnse-inspector",
|
|
65
|
+
// Only apply in dev mode
|
|
66
|
+
apply: "serve",
|
|
67
|
+
configureServer(server) {
|
|
68
|
+
if (!enabled) return;
|
|
69
|
+
server.middlewares.use((req, res, next) => {
|
|
70
|
+
if (req.url === "/@rspnse-inspector/inspector.js") {
|
|
71
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
72
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
73
|
+
let script = getInspectorScript();
|
|
74
|
+
if (trustedOrigins && trustedOrigins.length > 0) {
|
|
75
|
+
const originsArray = JSON.stringify(trustedOrigins);
|
|
76
|
+
script = `window.__RSPNSE_TRUSTED_ORIGINS__ = ${originsArray};
|
|
77
|
+
${script}`;
|
|
78
|
+
}
|
|
79
|
+
res.end(script);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
next();
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
transformIndexHtml(html) {
|
|
86
|
+
if (!enabled) return html;
|
|
87
|
+
const scriptTag = `<script src="/@rspnse-inspector/inspector.js" defer></script>`;
|
|
88
|
+
if (html.includes("</head>")) {
|
|
89
|
+
return html.replace("</head>", `${scriptTag}
|
|
90
|
+
</head>`);
|
|
91
|
+
}
|
|
92
|
+
if (html.includes("<body")) {
|
|
93
|
+
return html.replace(/<body([^>]*)>/, `<body$1>
|
|
94
|
+
${scriptTag}`);
|
|
95
|
+
}
|
|
96
|
+
return scriptTag + "\n" + html;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
101
|
+
0 && (module.exports = {
|
|
102
|
+
rspnseInspector
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/vite-plugin.ts"],"sourcesContent":["/**\n * @rspnseapp/dev-inspector\n *\n * A Vite plugin that enables Rspnse inspect functionality on localhost dev servers.\n * Works across all browsers without requiring a browser extension.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { rspnseInspector } from '@rspnseapp/dev-inspector';\n *\n * export default defineConfig({\n * plugins: [rspnseInspector()]\n * });\n * ```\n *\n * Then open your site in rspnse.net and use the inspect feature!\n */\n\nexport { rspnseInspector } from './vite-plugin';\nexport type {\n RspnseInspectorOptions,\n InspectedElement,\n BreadcrumbItem,\n StyleEntry,\n} from './types';\n","import type { Plugin } from 'vite';\nimport { readFileSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { RspnseInspectorOptions } from './types';\n\n// Get the directory of this module (works in both ESM and CJS)\nfunction getDirname(): string {\n // ESM: use import.meta.url\n if (typeof import.meta !== 'undefined' && import.meta.url) {\n return dirname(fileURLToPath(import.meta.url));\n }\n // CJS: __dirname is globally available (injected by bundler)\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof __dirname !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return __dirname;\n }\n // Fallback: use process.cwd()\n return process.cwd();\n}\n\nconst moduleDir = getDirname();\n\n/**\n * Vite plugin that injects the Rspnse inspector script into dev server pages.\n * This enables inspect functionality from rspnse.net without a browser extension.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { rspnseInspector } from '@rspnseapp/dev-inspector';\n *\n * export default {\n * plugins: [rspnseInspector()]\n * }\n * ```\n */\nexport function rspnseInspector(options: RspnseInspectorOptions = {}): Plugin {\n const { enabled = true, trustedOrigins } = options;\n\n // Cache the inspector script content\n let inspectorScript: string | null = null;\n\n function getInspectorScript(): string {\n if (inspectorScript) return inspectorScript;\n\n try {\n // Try to load the bundled inspector script\n const scriptPath = resolve(moduleDir, '../dist/index.inspector.js');\n inspectorScript = readFileSync(scriptPath, 'utf-8');\n } catch {\n // Fallback: load from same directory (during development)\n try {\n const scriptPath = resolve(moduleDir, './index.inspector.js');\n inspectorScript = readFileSync(scriptPath, 'utf-8');\n } catch {\n console.warn(\n '[@rspnseapp/dev-inspector] Could not load inspector script. Run `npm run build` first.'\n );\n inspectorScript = '// Inspector script not found';\n }\n }\n\n return inspectorScript;\n }\n\n return {\n name: 'rspnse-inspector',\n\n // Only apply in dev mode\n apply: 'serve',\n\n configureServer(server) {\n if (!enabled) return;\n\n // Serve the inspector script at a special path\n server.middlewares.use((req, res, next) => {\n if (req.url === '/@rspnse-inspector/inspector.js') {\n res.setHeader('Content-Type', 'application/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n\n let script = getInspectorScript();\n\n // If custom trusted origins are provided, inject them\n if (trustedOrigins && trustedOrigins.length > 0) {\n const originsArray = JSON.stringify(trustedOrigins);\n script = `window.__RSPNSE_TRUSTED_ORIGINS__ = ${originsArray};\\n${script}`;\n }\n\n res.end(script);\n return;\n }\n next();\n });\n },\n\n transformIndexHtml(html) {\n if (!enabled) return html;\n\n // Inject the inspector script before </head>\n const scriptTag = `<script src=\"/@rspnse-inspector/inspector.js\" defer></script>`;\n\n if (html.includes('</head>')) {\n return html.replace('</head>', `${scriptTag}\\n</head>`);\n }\n\n // Fallback: inject at start of body if no head tag\n if (html.includes('<body')) {\n return html.replace(/<body([^>]*)>/, `<body$1>\\n${scriptTag}`);\n }\n\n // Last resort: prepend to html\n return scriptTag + '\\n' + html;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,gBAA6B;AAC7B,kBAAiC;AACjC,iBAA8B;AAH9B;AAOA,SAAS,aAAqB;AAE5B,MAAI,OAAO,gBAAgB,eAAe,YAAY,KAAK;AACzD,eAAO,yBAAQ,0BAAc,YAAY,GAAG,CAAC;AAAA,EAC/C;AAIA,MAAI,OAAO,cAAc,aAAa;AAGpC,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,IAAI;AACrB;AAEA,IAAM,YAAY,WAAW;AAgBtB,SAAS,gBAAgB,UAAkC,CAAC,GAAW;AAC5E,QAAM,EAAE,UAAU,MAAM,eAAe,IAAI;AAG3C,MAAI,kBAAiC;AAErC,WAAS,qBAA6B;AACpC,QAAI,gBAAiB,QAAO;AAE5B,QAAI;AAEF,YAAM,iBAAa,qBAAQ,WAAW,4BAA4B;AAClE,4BAAkB,wBAAa,YAAY,OAAO;AAAA,IACpD,QAAQ;AAEN,UAAI;AACF,cAAM,iBAAa,qBAAQ,WAAW,sBAAsB;AAC5D,8BAAkB,wBAAa,YAAY,OAAO;AAAA,MACpD,QAAQ;AACN,gBAAQ;AAAA,UACN;AAAA,QACF;AACA,0BAAkB;AAAA,MACpB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM;AAAA;AAAA,IAGN,OAAO;AAAA,IAEP,gBAAgB,QAAQ;AACtB,UAAI,CAAC,QAAS;AAGd,aAAO,YAAY,IAAI,CAAC,KAAK,KAAK,SAAS;AACzC,YAAI,IAAI,QAAQ,mCAAmC;AACjD,cAAI,UAAU,gBAAgB,wBAAwB;AACtD,cAAI,UAAU,iBAAiB,UAAU;AAEzC,cAAI,SAAS,mBAAmB;AAGhC,cAAI,kBAAkB,eAAe,SAAS,GAAG;AAC/C,kBAAM,eAAe,KAAK,UAAU,cAAc;AAClD,qBAAS,uCAAuC,YAAY;AAAA,EAAM,MAAM;AAAA,UAC1E;AAEA,cAAI,IAAI,MAAM;AACd;AAAA,QACF;AACA,aAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,IAEA,mBAAmB,MAAM;AACvB,UAAI,CAAC,QAAS,QAAO;AAGrB,YAAM,YAAY;AAElB,UAAI,KAAK,SAAS,SAAS,GAAG;AAC5B,eAAO,KAAK,QAAQ,WAAW,GAAG,SAAS;AAAA,QAAW;AAAA,MACxD;AAGA,UAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,eAAO,KAAK,QAAQ,iBAAiB;AAAA,EAAa,SAAS,EAAE;AAAA,MAC/D;AAGA,aAAO,YAAY,OAAO;AAAA,IAC5B;AAAA,EACF;AACF;","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
interface BreadcrumbItem {
|
|
4
|
+
label: string;
|
|
5
|
+
index: number;
|
|
6
|
+
}
|
|
7
|
+
interface InspectedElement {
|
|
8
|
+
selector: string;
|
|
9
|
+
tagName: string;
|
|
10
|
+
classList: string[];
|
|
11
|
+
id: string | null;
|
|
12
|
+
computedStyles: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
interface StyleEntry {
|
|
15
|
+
type: 'inline' | 'external';
|
|
16
|
+
index?: number;
|
|
17
|
+
href?: string;
|
|
18
|
+
css: string | null;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
interface RspnseInspectorOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Enable/disable the inspector. Defaults to true in development.
|
|
24
|
+
*/
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Trusted origins that can communicate with the inspector.
|
|
28
|
+
* Defaults to ['https://rspnse.net', 'http://localhost']
|
|
29
|
+
*/
|
|
30
|
+
trustedOrigins?: string[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Vite plugin that injects the Rspnse inspector script into dev server pages.
|
|
35
|
+
* This enables inspect functionality from rspnse.net without a browser extension.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* // vite.config.ts
|
|
40
|
+
* import { rspnseInspector } from '@rspnseapp/dev-inspector';
|
|
41
|
+
*
|
|
42
|
+
* export default {
|
|
43
|
+
* plugins: [rspnseInspector()]
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
declare function rspnseInspector(options?: RspnseInspectorOptions): Plugin;
|
|
48
|
+
|
|
49
|
+
export { type BreadcrumbItem, type InspectedElement, type RspnseInspectorOptions, type StyleEntry, rspnseInspector };
|
package/dist/index.inspector.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var RspnseInspector=(()=>{var
|
|
1
|
+
"use strict";var RspnseInspector=(()=>{var fe="rspnse-layout-overlay-canvas",p=null,h=null,F=[],T=new Map,R=!1;function he(){return p||(p=document.createElement("canvas"),p.id=fe,p.style.cssText=`
|
|
2
2
|
position: fixed;
|
|
3
3
|
inset: 0;
|
|
4
4
|
width: 100%;
|
|
5
5
|
height: 100%;
|
|
6
6
|
pointer-events: none;
|
|
7
7
|
z-index: 2147483645;
|
|
8
|
-
`,document.body.appendChild(g),h=g.getContext("2d"),H(),we(),g)}function H(){if(!g||!h)return;let e=window.devicePixelRatio||1,t=window.innerWidth,n=window.innerHeight;g.width=t*e,g.height=n*e,g.style.width=t+"px",g.style.height=n+"px",h.scale(e,e)}function B(){g&&(g.remove(),g=null,h=null)}function G(){let e=[],t=document.querySelectorAll("*"),n=0,s=0;return t.forEach(o=>{if(o.id?.startsWith("rspnse-"))return;let r=window.getComputedStyle(o).display;r==="grid"||r==="inline-grid"?e.push(le(o,n++)):(r==="flex"||r==="inline-flex")&&e.push(de(o,s++))}),W=e,e}function le(e,t){let n=window.getComputedStyle(e),s=e.getBoundingClientRect(),o=parseFloat(n.columnGap)||0,i=parseFloat(n.rowGap)||0,r=P(n.gridTemplateColumns,o),a=P(n.gridTemplateRows,i),l=ce(n.gridTemplateAreas,r.length,a.length);return{id:`grid-${t}`,type:"grid",selector:F(e),label:U(e),rect:{x:s.x,y:s.y,width:s.width,height:s.height},columns:r,rows:a,areas:l,columnGap:o,rowGap:i}}function de(e,t){let n=window.getComputedStyle(e),s=e.getBoundingClientRect();return{id:`flex-${t}`,type:"flex",selector:F(e),label:U(e),rect:{x:s.x,y:s.y,width:s.width,height:s.height},direction:n.flexDirection,wrap:n.flexWrap,justifyContent:n.justifyContent,alignItems:n.alignItems,gap:parseFloat(n.gap)||0}}function P(e,t){if(!e||e==="none")return[];let n=e.split(" ").filter(i=>i.trim()),s=[],o=0;return n.forEach((i,r)=>{let a=parseFloat(i);isNaN(a)||(s.push({index:r,start:o,end:o+a,size:i,isImplicit:!1}),o+=a+(r<n.length-1?t:0))}),s}function ce(e,t,n){if(!e||e==="none")return[];let s=e.match(/"([^"]+)"/g);if(!s)return[];let o=new Map;return s.forEach((i,r)=>{i.replace(/"/g,"").split(/\s+/).filter(l=>l).forEach((l,c)=>{if(l!==".")if(!o.has(l))o.set(l,{name:l,rowStart:r,rowEnd:r+1,colStart:c,colEnd:c+1});else{let d=o.get(l);d.rowEnd=Math.max(d.rowEnd,r+1),d.colEnd=Math.max(d.colEnd,c+1)}})}),Array.from(o.values())}function F(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=Array.from(e.classList).filter(s=>!s.startsWith("__")&&!s.startsWith("rspnse-")&&!/[[\]():]/.test(s)).slice(0,2);if(t.length>0){let s=`.${t.map(o=>CSS.escape(o)).join(".")}`;try{if(document.querySelectorAll(s).length===1)return s}catch{}}let n=e.tagName.toLowerCase();return t.length>0?`${n}.${CSS.escape(t[0])}`:n}function U(e){if(e.id)return`#${e.id}`;if(e.classList.length>0){let t=Array.from(e.classList).find(n=>!n.startsWith("__"));if(t)return`.${t}`}return e.tagName.toLowerCase()}function Y(e,t,n){let s=W.find(o=>o.id===e);s&&(ae(),T.set(e,{containerId:e,container:s,settings:t,color:n}),V())}function j(e){T.delete(e),V(),T.size===0&&B()}function q(){T.clear(),B()}function V(){R||(R=!0,requestAnimationFrame(()=>{R=!1,M()}))}function M(){if(!h||!g)return;let e=window.devicePixelRatio||1;h.setTransform(1,0,0,1,0,0),h.clearRect(0,0,g.width,g.height),h.scale(e,e),T.forEach(t=>{t.container.type==="grid"?ue(t):pe(t)})}function ue(e){let{container:t,settings:n,color:s}=e,o=h,i=document.querySelector(t.selector);if(!i)return;let r=i.getBoundingClientRect();ye(o,r,s),o.strokeStyle=s,o.lineWidth=1,o.setLineDash([4,4]),o.strokeRect(r.x,r.y,r.width,r.height),t.columns&&t.columns.length>0&&k(o,r,t.columns,"column",s,n),t.rows&&t.rows.length>0&&k(o,r,t.rows,"row",s,n),n.showAreaNames&&t.areas&&t.areas.length>0&&ge(o,r,t,s)}function k(e,t,n,s,o,i){let r=s==="column";n.forEach((l,c)=>{let d=r?t.x+l.start:t.y+l.start;if(e.strokeStyle=l.isImplicit&&i.highlightImplicitTracks?y(o,.4):y(o,.7),e.lineWidth=1,e.setLineDash([4,4]),e.beginPath(),r?(e.moveTo(d,t.y),e.lineTo(d,t.y+t.height)):(e.moveTo(t.x,d),e.lineTo(t.x+t.width,d)),e.stroke(),i.showLineNumbers&&$(e,c+1,d,t,r,o),i.showTrackSizes){let f=r?t.x+l.end:t.y+l.end;fe(e,l.size,d,f,t,r,o)}});let a=n[n.length-1];if(a){let l=r?t.x+a.end:t.y+a.end;e.strokeStyle=y(o,.7),e.lineWidth=1,e.setLineDash([4,4]),e.beginPath(),r?(e.moveTo(l,t.y),e.lineTo(l,t.y+t.height)):(e.moveTo(t.x,l),e.lineTo(t.x+t.width,l)),e.stroke(),i.showLineNumbers&&$(e,n.length+1,l,t,r,o)}}function $(e,t,n,s,o,i){let r=String(t),a=10,l=2;e.font=`${a}px ui-monospace, monospace`;let c=e.measureText(r).width,d,f;o?(d=n-c/2,f=s.y-a/2):(d=s.x-c-l*3,f=n+a/3),e.fillStyle=i,e.fillRect(d-l,f-a,c+l*2,a+l),e.fillStyle="#ffffff",e.fillText(r,d,f)}function fe(e,t,n,s,o,i,r){let a=(n+s)/2,l=9,c=2;e.font=`${l}px ui-monospace, monospace`;let d=e.measureText(t).width,f,m;i?(f=a-d/2,m=o.y+o.height+l+c*2):(f=o.x+o.width+c*2,m=a+l/3),e.fillStyle=y(r,.8),e.fillRect(f-c,m-l,d+c*2,l+c),e.fillStyle="#ffffff",e.fillText(t,f,m)}function ge(e,t,n,s){!n.areas||!n.columns||!n.rows||n.areas.forEach(o=>{let i=n.columns[o.colStart]?.start||0,r=n.columns[o.colEnd-1]?.end||0,a=n.rows[o.rowStart]?.start||0,l=n.rows[o.rowEnd-1]?.end||0,c={x:t.x+i,y:t.y+a,width:r-i,height:l-a};e.fillStyle=y(s,.1),e.fillRect(c.x,c.y,c.width,c.height);let d=11;e.font=`bold ${d}px sans-serif`;let f=e.measureText(o.name).width,m=c.x+(c.width-f)/2,E=c.y+(c.height+d)/2;e.fillStyle=s,e.fillRect(m-4,E-d,f+8,d+4),e.fillStyle="#ffffff",e.fillText(o.name,m,E)})}function pe(e){let{container:t,color:n}=e,s=h,o=document.querySelector(t.selector);if(!o)return;let i=o.getBoundingClientRect();s.strokeStyle=n,s.lineWidth=1,s.setLineDash([4,4]),s.strokeRect(i.x,i.y,i.width,i.height),me(s,i,t.direction||"row",n),s.setLineDash([4,4]),s.strokeStyle=y(n,.6),s.lineWidth=1;let r=o.children;for(let a=0;a<r.length;a++){let l=r[a];if(l.id?.startsWith("rspnse-"))continue;let c=l.getBoundingClientRect();s.strokeRect(c.x,c.y,c.width,c.height)}he(s,i,"flex",n)}function me(e,t,n,s){e.fillStyle=s,e.beginPath();let r=t.x+t.width/2,a=t.y+t.height/2;switch(n){case"row":e.moveTo(t.x+8,a-16/2),e.lineTo(t.x+8+16,a),e.lineTo(t.x+8,a+16/2);break;case"row-reverse":e.moveTo(t.x+t.width-8,a-16/2),e.lineTo(t.x+t.width-8-16,a),e.lineTo(t.x+t.width-8,a+16/2);break;case"column":e.moveTo(r-16/2,t.y+8),e.lineTo(r,t.y+8+16),e.lineTo(r+16/2,t.y+8);break;case"column-reverse":e.moveTo(r-16/2,t.y+t.height-8),e.lineTo(r,t.y+t.height-8-16),e.lineTo(r+16/2,t.y+t.height-8);break}e.closePath(),e.fill()}function he(e,t,n,s){let i=n.toUpperCase();e.font="bold 10px sans-serif";let r=e.measureText(i).width,a=t.x+4,l=t.y+10+4;e.fillStyle=s,e.fillRect(a-2,l-10,r+4,12),e.fillStyle="#ffffff",e.fillText(i,a,l)}function y(e,t){let n=parseInt(e.slice(1,3),16),s=parseInt(e.slice(3,5),16),o=parseInt(e.slice(5,7),16);return`rgba(${n}, ${s}, ${o}, ${t})`}function ye(e,t,n){let o=y(n,.15);e.save(),e.strokeStyle=o,e.lineWidth=1,e.setLineDash([]),e.beginPath(),e.rect(t.x,t.y,t.width,t.height),e.clip();let i=Math.max(t.width,t.height)*2;for(let r=-i;r<i;r+=8)e.beginPath(),e.moveTo(t.x+r,t.y),e.lineTo(t.x+r+i,t.y+i),e.stroke();e.restore()}var z=!1;function we(){if(z)return;z=!0;let e=!1,t=()=>{e||(e=!0,requestAnimationFrame(()=>{M(),e=!1}))};window.addEventListener("scroll",t,{passive:!0}),window.addEventListener("resize",()=>{H(),M()})}var x="rspnse-injected-css",S="rspnse-inspect-highlight",L="rspnse-inspect-label",I="rspnse-inspect-margin",_="rspnse-inspect-padding",v="1.0.0",X=["https://rspnse.net","https://www.rspnse.net","http://localhost","http://127.0.0.1"];function Ee(){return window.__RSPNSE_TRUSTED_ORIGINS__&&Array.isArray(window.__RSPNSE_TRUSTED_ORIGINS__)?[...X,...window.__RSPNSE_TRUSTED_ORIGINS__]:X}var b=!1,w=null,p=null,K={layout:["display","position","top","right","bottom","left","z-index"],flexbox:["flex","flex-direction","flex-wrap","justify-content","align-items","align-content","gap","row-gap","column-gap"],grid:["grid-template-columns","grid-template-rows","grid-column","grid-row"],box:["width","height","min-width","max-width","min-height","max-height","margin","margin-top","margin-right","margin-bottom","margin-left","padding","padding-top","padding-right","padding-bottom","padding-left","border","border-radius","box-sizing"],typography:["font-family","font-size","font-weight","font-style","line-height","letter-spacing","text-align","text-decoration","text-transform","color","white-space"],background:["background","background-color","background-image","background-size","background-position"],visual:["opacity","visibility","overflow","overflow-x","overflow-y","box-shadow","transform","cursor"]};function Se(e){return Ee().some(n=>n.startsWith("http://localhost")||n.startsWith("http://127.0.0.1")?e.startsWith("http://localhost")||e.startsWith("http://127.0.0.1"):e===n||e.startsWith(n))}function be(e){let t=document.getElementById(x);return t||(t=document.createElement("style"),t.id=x,(document.head||document.documentElement).appendChild(t)),t.textContent=e,{success:!0}}function Te(){let e=document.getElementById(x);return e?(e.remove(),{success:!0}):{success:!1,error:"No styles to remove"}}function ve(){let e=document.getElementById(x);return e&&e.textContent||""}async function xe(){let e=[];document.querySelectorAll("style").forEach((s,o)=>{s.textContent&&s.id!==x&&e.push({type:"inline",index:o+1,css:s.textContent.trim()})});let n=document.querySelectorAll('link[rel="stylesheet"]');for(let s of Array.from(n)){let o=s.href;try{let i=await fetch(o);if(i.ok){let r=await i.text();e.push({type:"external",href:o,css:r.trim()})}}catch(i){e.push({type:"external",href:o,css:null,error:`Could not fetch: ${i.message}`})}}return e}function Ce(e){if(e.id)return"#"+CSS.escape(e.id);let t=[],n=e,s=0;for(;n&&n!==document.body&&n!==document.documentElement&&s<3;){let o=n.tagName.toLowerCase();if(n.className&&typeof n.className=="string"){let i=n.className.trim().split(/\s+/).filter(r=>r&&!r.startsWith("rspnse-")).slice(0,2);i.length>0&&(o+="."+i.map(r=>CSS.escape(r)).join("."))}if(n.parentElement){let i=Array.from(n.parentElement.children).filter(r=>r.tagName===n.tagName);if(i.length>1){let r=i.indexOf(n)+1;o+=`:nth-of-type(${r})`}}t.unshift(o),n=n.parentElement,s++}return t.join(" > ")}function J(e){let t=window.getComputedStyle(e),n={},s=document.createElement(e.tagName);s.style.cssText="position: absolute; visibility: hidden;",document.body.appendChild(s);let o=window.getComputedStyle(s);return Object.keys(K).forEach(i=>{K[i].forEach(r=>{let a=t.getPropertyValue(r),l=o.getPropertyValue(r);a&&a!==l&&a!=="none"&&a!=="auto"&&a!=="normal"&&a!=="0px"&&a!=="rgba(0, 0, 0, 0)"&&(n[r]=a)})}),s.remove(),{selector:Ce(e),tagName:e.tagName.toLowerCase(),classList:Array.from(e.classList),id:e.id||null,computedStyles:n}}function Q(e){let t=[],n=e;for(;n&&n!==document.documentElement;){if(n.nodeType!==1){n=n.parentElement;continue}let s=n.tagName.toLowerCase(),o=n.id?"#"+n.id:"",i=n.className&&typeof n.className=="string"?"."+n.className.trim().split(/\s+/).filter(r=>r&&!r.startsWith("rspnse-")).slice(0,1).join("."):"";t.unshift({label:s+o+i,index:t.length}),n=n.parentElement}t.unshift({label:"html",index:t.length});for(let s=0;s<t.length;s++)t[s].index=s;return t}function Le(e){if(!p)return null;let t=[],n=p;for(;n&&n!==document.documentElement;)n.nodeType===1&&t.unshift(n),n=n.parentElement;return t.unshift(document.documentElement),t[e]||null}function Ie(e){let t=e.tagName.toLowerCase(),n=e.id?"#"+e.id:"",s=e.className&&typeof e.className=="string"?"."+e.className.trim().split(/\s+/).filter(o=>o&&!o.startsWith("rspnse-")).slice(0,2).join("."):"";return t+n+s}function _e(){[S,L,I,_].forEach(o=>{let i=document.getElementById(o);i&&i.remove()});let e=document.createElement("div");e.id=S,e.style.cssText="position: fixed; pointer-events: none; z-index: 2147483646; border: 2px solid #3b82f6; background: rgba(59, 130, 246, 0.15); transition: all 0.05s ease-out; display: none;",document.body.appendChild(e);let t=document.createElement("div");t.id=I,t.style.cssText="position: fixed; pointer-events: none; z-index: 2147483645; background: rgba(249, 115, 22, 0.25); transition: all 0.05s ease-out; display: none;",document.body.appendChild(t);let n=document.createElement("div");n.id=_,n.style.cssText="position: fixed; pointer-events: none; z-index: 2147483644; background: rgba(34, 197, 94, 0.25); transition: all 0.05s ease-out; display: none;",document.body.appendChild(n);let s=document.createElement("div");return s.id=L,s.style.cssText="position: fixed; pointer-events: none; z-index: 2147483647; background: #1e293b; color: #f8fafc; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; padding: 4px 8px; border-radius: 4px; white-space: nowrap; display: none; box-shadow: 0 2px 8px rgba(0,0,0,0.3); max-width: calc(100vw - 16px); overflow: hidden; text-overflow: ellipsis;",document.body.appendChild(s),e}function Z(e){let t=document.getElementById(S),n=document.getElementById(L),s=document.getElementById(I),o=document.getElementById(_);if(!t||!n)return;if(!e){t.style.display="none",n.style.display="none",s&&(s.style.display="none"),o&&(o.style.display="none");return}let i=e.getBoundingClientRect(),r=window.getComputedStyle(e),a=parseFloat(r.marginTop)||0,l=parseFloat(r.marginRight)||0,c=parseFloat(r.marginBottom)||0,d=parseFloat(r.marginLeft)||0,f=parseFloat(r.paddingTop)||0,m=parseFloat(r.paddingRight)||0,E=parseFloat(r.paddingBottom)||0,C=parseFloat(r.paddingLeft)||0;t.style.display="block",t.style.top=i.top+"px",t.style.left=i.left+"px",t.style.width=i.width+"px",t.style.height=i.height+"px",s&&(a||l||c||d)?(s.style.display="block",s.style.top=i.top-a+"px",s.style.left=i.left-d+"px",s.style.width=i.width+d+l+"px",s.style.height=i.height+a+c+"px",s.style.clipPath=`polygon(0 0, 100% 0, 100% 100%, 0 100%, 0 0, ${d}px ${a}px, ${d}px ${a+i.height}px, ${d+i.width}px ${a+i.height}px, ${d+i.width}px ${a}px, ${d}px ${a}px)`):s&&(s.style.display="none"),o&&(f||m||E||C)?(o.style.display="block",o.style.top=i.top+"px",o.style.left=i.left+"px",o.style.width=i.width+"px",o.style.height=i.height+"px",o.style.clipPath=`polygon(0 0, 100% 0, 100% 100%, 0 100%, 0 0, ${C}px ${f}px, ${C}px ${i.height-E}px, ${i.width-m}px ${i.height-E}px, ${i.width-m}px ${f}px, ${C}px ${f}px)`):o&&(o.style.display="none");let oe=Ie(e),ie=`${Math.round(i.width)} x ${Math.round(i.height)}`;n.innerHTML=`<span style="color: #93c5fd;">${oe}</span> <span style="color: #94a3b8; margin-left: 6px;">${ie}</span>`,n.style.display="block",n.style.left="auto",n.style.right="auto";let A=window.innerWidth,N=i.top-24-6;N<4&&(N=i.bottom+6),n.style.top=N+"px",i.left+i.width/2>A/2?(n.style.right=Math.max(4,A-i.right)+"px",n.style.left="auto"):(n.style.left=Math.max(4,i.left)+"px",n.style.right="auto")}function O(e){if(!p)return-1;let t=[],n=p;for(;n&&n!==document.documentElement;)n.nodeType===1&&t.unshift(n),n=n.parentElement;t.unshift(document.documentElement);for(let s=0;s<t.length;s++)if(t[s]===e)return s;return-1}function D(e){if(!e||e.id&&e.id.startsWith("rspnse-"))return!1;w=e,Z(e);let t=J(e),n=Q(p),s=O(e);return window.parent!==window&&window.parent.postMessage({type:"RSPNSE_INSPECT_ELEMENT_RESULT",success:!0,element:t,breadcrumb:n,breadcrumbIndex:s},"*"),!0}function ee(e){if(!b)return;let t=document.elementFromPoint(e.clientX,e.clientY);t&&t.id!==S&&Z(t)}function te(e){if(!b)return;e.preventDefault(),e.stopPropagation();let t=document.elementFromPoint(e.clientX,e.clientY);if(t&&t.id!==S&&!t.id?.startsWith("rspnse-")){p=t,w=t;let n=J(t),s=Q(t);window.parent!==window&&window.parent.postMessage({type:"RSPNSE_INSPECT_ELEMENT_RESULT",success:!0,element:n,breadcrumb:s,breadcrumbIndex:s.length-1},"*")}}function ne(e){if(!b)return;if(e.key==="Escape"){se(),window.parent!==window&&window.parent.postMessage({type:"RSPNSE_INSPECT_CANCELLED",reason:"escape"},"*");return}if(!w||!p)return;let t=O(w),n=[],s=p;for(;s&&s!==document.documentElement;)s.nodeType===1&&n.unshift(s),s=s.parentElement;n.unshift(document.documentElement);let o=t;switch(e.key){case"ArrowUp":case"ArrowLeft":o=t-1;break;case"ArrowDown":case"ArrowRight":o=t+1;break;default:return}o>=0&&o<n.length&&(e.preventDefault(),D(n[o]))}function Ne(){b||(b=!0,document.body.style.cursor="crosshair",_e(),document.addEventListener("mousemove",ee,!0),document.addEventListener("click",te,!0),document.addEventListener("keydown",ne,!0))}function se(){b=!1,w=null,p=null,document.body.style.cursor="",[S,L,I,_].forEach(e=>{let t=document.getElementById(e);t&&t.remove()}),document.removeEventListener("mousemove",ee,!0),document.removeEventListener("click",te,!0),document.removeEventListener("keydown",ne,!0)}function u(e,t,n){if(e.source&&e.source!==window)try{e.source.postMessage({type:t.type+"_RESULT",requestId:t.requestId,frameId:t.frameId,...n},"*")}catch{}}function Re(e){if(!Se(e.origin))return;let t=e.data;if(!(!t||typeof t!="object")&&t.type&&t.type.startsWith("RSPNSE_"))switch(t.type){case"RSPNSE_INJECT_CSS":typeof t.css=="string"?u(e,t,be(t.css)):u(e,t,{success:!1,error:"CSS must be a string"});break;case"RSPNSE_REMOVE_CSS":u(e,t,Te());break;case"RSPNSE_GET_CSS":u(e,t,{success:!0,css:ve()});break;case"RSPNSE_CAPTURE_STYLES":xe().then(n=>{u(e,t,{success:!0,styles:n})}).catch(n=>{u(e,t,{success:!1,error:n.message})});break;case"RSPNSE_INSPECT_START":Ne(),u(e,t,{success:!0});break;case"RSPNSE_INSPECT_STOP":se(),u(e,t,{success:!0});break;case"RSPNSE_INSPECT_NAVIGATE_TO":if(p&&typeof t.breadcrumbIndex=="number"){let n=Le(t.breadcrumbIndex);n?(D(n),u(e,t,{success:!0})):u(e,t,{success:!1,error:"Element not found"})}else u(e,t,{success:!1,error:"No original element or invalid index"});break;case"RSPNSE_INSPECT_NAVIGATE":if(p&&w&&t.direction){let n=O(w),s=[],o=p;for(;o&&o!==document.documentElement;)o.nodeType===1&&s.unshift(o),o=o.parentElement;s.unshift(document.documentElement);let i=n;(t.direction==="left"||t.direction==="up")&&(i=n-1),(t.direction==="right"||t.direction==="down")&&(i=n+1),i>=0&&i<s.length?(D(s[i]),u(e,t,{success:!0})):u(e,t,{success:!1,error:"At end of breadcrumb"})}else u(e,t,{success:!1,error:"No selection"});break;case"RSPNSE_PING":u(e,t,{success:!0,pong:!0,version:v});break;case"RSPNSE_LAYOUT_DETECT":console.log("[dev-inspector] RSPNSE_LAYOUT_DETECT received, requestId:",t.requestId);try{let n=G();console.log("[dev-inspector] Detected",n.length,"containers"),u(e,t,{success:!0,containers:n}),console.log("[dev-inspector] Sent RSPNSE_LAYOUT_DETECT_RESULT")}catch(n){console.error("[dev-inspector] Detection error:",n),u(e,t,{success:!1,error:n.message})}break;case"RSPNSE_LAYOUT_HIGHLIGHT":t.containerId&&t.settings&&t.color?(t.visible!==!1?Y(t.containerId,t.settings,t.color):j(t.containerId),u(e,t,{success:!0})):u(e,t,{success:!1,error:"Missing containerId, settings, or color"});break;case"RSPNSE_LAYOUT_CLEAR":q(),u(e,t,{success:!0});break}}function Me(){if(document.documentElement.setAttribute("data-rspnse-inspector",v),window.addEventListener("message",Re),window.parent!==window)try{window.parent.postMessage({type:"RSPNSE_DEV_INSPECTOR_READY",version:v,url:window.location.href},"*"),window.parent.postMessage({type:"RSPNSE_EXTENSION_READY",version:v,url:window.location.href},"*")}catch{}window.dispatchEvent(new CustomEvent("rspnse-inspector-loaded",{detail:{version:v}}))}Me();})();
|
|
8
|
+
`,document.body.appendChild(p),h=p.getContext("2d"),U(),Me(),p)}function U(){if(!p||!h)return;let e=window.devicePixelRatio||1,t=window.innerWidth,n=window.innerHeight;p.width=t*e,p.height=n*e,p.style.width=t+"px",p.style.height=n+"px",h.scale(e,e)}function X(){p&&(p.remove(),p=null,h=null)}function K(){let e=[],t=document.querySelectorAll("*"),n=0,o=0;return t.forEach(s=>{if(s.id?.startsWith("rspnse-"))return;let r=window.getComputedStyle(s).display;r==="grid"||r==="inline-grid"?e.push(ye(s,n++)):(r==="flex"||r==="inline-flex")&&e.push(Ee(s,o++))}),F=e,e}function ye(e,t){let n=window.getComputedStyle(e),o=e.getBoundingClientRect(),s=parseFloat(n.columnGap)||0,i=parseFloat(n.rowGap)||0,r=z(n.gridTemplateColumns,s),l=z(n.gridTemplateRows,i),a=we(n.gridTemplateAreas,r.length,l.length);return{id:`grid-${t}`,type:"grid",selector:j(e),label:q(e),rect:{x:o.x,y:o.y,width:o.width,height:o.height},columns:r,rows:l,areas:a,columnGap:s,rowGap:i}}function Ee(e,t){let n=window.getComputedStyle(e),o=e.getBoundingClientRect();return{id:`flex-${t}`,type:"flex",selector:j(e),label:q(e),rect:{x:o.x,y:o.y,width:o.width,height:o.height},direction:n.flexDirection,wrap:n.flexWrap,justifyContent:n.justifyContent,alignItems:n.alignItems,gap:parseFloat(n.gap)||0}}function z(e,t){if(!e||e==="none")return[];let n=e.split(" ").filter(i=>i.trim()),o=[],s=0;return n.forEach((i,r)=>{let l=parseFloat(i);isNaN(l)||(o.push({index:r,start:s,end:s+l,size:i,isImplicit:!1}),s+=l+(r<n.length-1?t:0))}),o}function we(e,t,n){if(!e||e==="none")return[];let o=e.match(/"([^"]+)"/g);if(!o)return[];let s=new Map;return o.forEach((i,r)=>{i.replace(/"/g,"").split(/\s+/).filter(a=>a).forEach((a,d)=>{if(a!==".")if(!s.has(a))s.set(a,{name:a,rowStart:r,rowEnd:r+1,colStart:d,colEnd:d+1});else{let c=s.get(a);c.rowEnd=Math.max(c.rowEnd,r+1),c.colEnd=Math.max(c.colEnd,d+1)}})}),Array.from(s.values())}function j(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=Array.from(e.classList).filter(o=>!o.startsWith("__")&&!o.startsWith("rspnse-")&&!/[[\]():]/.test(o)).slice(0,2);if(t.length>0){let o=`.${t.map(s=>CSS.escape(s)).join(".")}`;try{if(document.querySelectorAll(o).length===1)return o}catch{}}let n=e.tagName.toLowerCase();return t.length>0?`${n}.${CSS.escape(t[0])}`:n}function q(e){if(e.id)return`#${e.id}`;if(e.classList.length>0){let t=Array.from(e.classList).find(n=>!n.startsWith("__"));if(t)return`.${t}`}return e.tagName.toLowerCase()}function V(e,t,n){let o=F.find(s=>s.id===e);o&&(he(),T.set(e,{containerId:e,container:o,settings:t,color:n}),Z())}function J(e){T.delete(e),Z(),T.size===0&&X()}function Q(){T.clear(),X()}function Z(){R||(R=!0,requestAnimationFrame(()=>{R=!1,D()}))}function D(){if(!h||!p)return;let e=window.devicePixelRatio||1;h.setTransform(1,0,0,1,0,0),h.clearRect(0,0,p.width,p.height),h.scale(e,e),T.forEach(t=>{t.container.type==="grid"?Se(t):Te(t)})}function Se(e){let{container:t,settings:n,color:o}=e,s=h,i=document.querySelector(t.selector);if(!i)return;let r=i.getBoundingClientRect();Le(s,r,o),s.strokeStyle=o,s.lineWidth=1,s.setLineDash([4,4]),s.strokeRect(r.x,r.y,r.width,r.height),t.columns&&t.columns.length>0&&B(s,r,t.columns,"column",o,n),t.rows&&t.rows.length>0&&B(s,r,t.rows,"row",o,n),n.showAreaNames&&t.areas&&t.areas.length>0&&be(s,r,t,o)}function B(e,t,n,o,s,i){let r=o==="column";n.forEach((a,d)=>{let c=r?t.x+a.start:t.y+a.start;if(e.strokeStyle=a.isImplicit&&i.highlightImplicitTracks?w(s,.4):w(s,.7),e.lineWidth=1,e.setLineDash([4,4]),e.beginPath(),r?(e.moveTo(c,t.y),e.lineTo(c,t.y+t.height)):(e.moveTo(t.x,c),e.lineTo(t.x+t.width,c)),e.stroke(),i.showLineNumbers&&Y(e,d+1,c,t,r,s),i.showTrackSizes){let m=r?t.x+a.end:t.y+a.end;ve(e,a.size,c,m,t,r,s)}});let l=n[n.length-1];if(l){let a=r?t.x+l.end:t.y+l.end;e.strokeStyle=w(s,.7),e.lineWidth=1,e.setLineDash([4,4]),e.beginPath(),r?(e.moveTo(a,t.y),e.lineTo(a,t.y+t.height)):(e.moveTo(t.x,a),e.lineTo(t.x+t.width,a)),e.stroke(),i.showLineNumbers&&Y(e,n.length+1,a,t,r,s)}}function Y(e,t,n,o,s,i){let r=String(t),l=10,a=2;e.font=`${l}px ui-monospace, monospace`;let d=e.measureText(r).width,c,m;s?(c=n-d/2,m=o.y-l/2):(c=o.x-d-a*3,m=n+l/3),e.fillStyle=i,e.fillRect(c-a,m-l,d+a*2,l+a),e.fillStyle="#ffffff",e.fillText(r,c,m)}function ve(e,t,n,o,s,i,r){let l=(n+o)/2,a=9,d=2;e.font=`${a}px ui-monospace, monospace`;let c=e.measureText(t).width,m,g;i?(m=l-c/2,g=s.y+s.height+a+d*2):(m=s.x+s.width+d*2,g=l+a/3),e.fillStyle=w(r,.8),e.fillRect(m-d,g-a,c+d*2,a+d),e.fillStyle="#ffffff",e.fillText(t,m,g)}function be(e,t,n,o){!n.areas||!n.columns||!n.rows||n.areas.forEach(s=>{let i=n.columns[s.colStart]?.start||0,r=n.columns[s.colEnd-1]?.end||0,l=n.rows[s.rowStart]?.start||0,a=n.rows[s.rowEnd-1]?.end||0,d={x:t.x+i,y:t.y+l,width:r-i,height:a-l};e.fillStyle=w(o,.1),e.fillRect(d.x,d.y,d.width,d.height);let c=11;e.font=`bold ${c}px sans-serif`;let m=e.measureText(s.name).width,g=d.x+(d.width-m)/2,y=d.y+(d.height+c)/2;e.fillStyle=o,e.fillRect(g-4,y-c,m+8,c+4),e.fillStyle="#ffffff",e.fillText(s.name,g,y)})}function Te(e){let{container:t,color:n}=e,o=h,s=document.querySelector(t.selector);if(!s)return;let i=s.getBoundingClientRect();o.strokeStyle=n,o.lineWidth=1,o.setLineDash([4,4]),o.strokeRect(i.x,i.y,i.width,i.height),xe(o,i,t.direction||"row",n),o.setLineDash([4,4]),o.strokeStyle=w(n,.6),o.lineWidth=1;let r=s.children;for(let l=0;l<r.length;l++){let a=r[l];if(a.id?.startsWith("rspnse-"))continue;let d=a.getBoundingClientRect();o.strokeRect(d.x,d.y,d.width,d.height)}Ce(o,i,"flex",n)}function xe(e,t,n,o){e.fillStyle=o,e.beginPath();let r=t.x+t.width/2,l=t.y+t.height/2;switch(n){case"row":e.moveTo(t.x+8,l-16/2),e.lineTo(t.x+8+16,l),e.lineTo(t.x+8,l+16/2);break;case"row-reverse":e.moveTo(t.x+t.width-8,l-16/2),e.lineTo(t.x+t.width-8-16,l),e.lineTo(t.x+t.width-8,l+16/2);break;case"column":e.moveTo(r-16/2,t.y+8),e.lineTo(r,t.y+8+16),e.lineTo(r+16/2,t.y+8);break;case"column-reverse":e.moveTo(r-16/2,t.y+t.height-8),e.lineTo(r,t.y+t.height-8-16),e.lineTo(r+16/2,t.y+t.height-8);break}e.closePath(),e.fill()}function Ce(e,t,n,o){let i=n.toUpperCase();e.font="bold 10px sans-serif";let r=e.measureText(i).width,l=t.x+4,a=t.y+10+4;e.fillStyle=o,e.fillRect(l-2,a-10,r+4,12),e.fillStyle="#ffffff",e.fillText(i,l,a)}function w(e,t){let n=parseInt(e.slice(1,3),16),o=parseInt(e.slice(3,5),16),s=parseInt(e.slice(5,7),16);return`rgba(${n}, ${o}, ${s}, ${t})`}function Le(e,t,n){let s=w(n,.15);e.save(),e.strokeStyle=s,e.lineWidth=1,e.setLineDash([]),e.beginPath(),e.rect(t.x,t.y,t.width,t.height),e.clip();let i=Math.max(t.width,t.height)*2;for(let r=-i;r<i;r+=8)e.beginPath(),e.moveTo(t.x+r,t.y),e.lineTo(t.x+r+i,t.y+i),e.stroke();e.restore()}var G=!1;function Me(){if(G)return;G=!0;let e=!1,t=()=>{e||(e=!0,requestAnimationFrame(()=>{D(),e=!1}))};window.addEventListener("scroll",t,{passive:!0}),window.addEventListener("resize",()=>{U(),D()})}var C="rspnse-injected-css",v="rspnse-inspect-highlight",_="rspnse-inspect-label",k="rspnse-inspect-margin",N="rspnse-inspect-padding",x="1.0.0",ee=["https://rspnse.net","https://www.rspnse.net","http://localhost","http://127.0.0.1"];function _e(){return window.__RSPNSE_TRUSTED_ORIGINS__&&Array.isArray(window.__RSPNSE_TRUSTED_ORIGINS__)?[...ee,...window.__RSPNSE_TRUSTED_ORIGINS__]:ee}var E=!1,S=null,f=null,b=!1,L="rspnse-mark-highlight",te={layout:["display","position","top","right","bottom","left","z-index"],flexbox:["flex","flex-direction","flex-wrap","justify-content","align-items","align-content","gap","row-gap","column-gap"],grid:["grid-template-columns","grid-template-rows","grid-column","grid-row"],box:["width","height","min-width","max-width","min-height","max-height","margin","margin-top","margin-right","margin-bottom","margin-left","padding","padding-top","padding-right","padding-bottom","padding-left","border","border-radius","box-sizing"],typography:["font-family","font-size","font-weight","font-style","line-height","letter-spacing","text-align","text-decoration","text-transform","color","white-space"],background:["background","background-color","background-image","background-size","background-position"],visual:["opacity","visibility","overflow","overflow-x","overflow-y","box-shadow","transform","cursor"]};function ke(e){return _e().some(n=>n.startsWith("http://localhost")||n.startsWith("http://127.0.0.1")?e.startsWith("http://localhost")||e.startsWith("http://127.0.0.1"):e===n||e.startsWith(n))}function Ne(e){let t=document.getElementById(C);return t||(t=document.createElement("style"),t.id=C,(document.head||document.documentElement).appendChild(t)),t.textContent=e,{success:!0}}function Ie(){let e=document.getElementById(C);return e?(e.remove(),{success:!0}):{success:!1,error:"No styles to remove"}}function Re(){let e=document.getElementById(C);return e&&e.textContent||""}async function De(){let e=[];document.querySelectorAll("style").forEach((o,s)=>{o.textContent&&o.id!==C&&e.push({type:"inline",index:s+1,css:o.textContent.trim()})});let n=document.querySelectorAll('link[rel="stylesheet"]');for(let o of Array.from(n)){let s=o.href;try{let i=await fetch(s);if(i.ok){let r=await i.text();e.push({type:"external",href:s,css:r.trim()})}}catch(i){e.push({type:"external",href:s,css:null,error:`Could not fetch: ${i.message}`})}}return e}function ne(e){if(e.id)return"#"+CSS.escape(e.id);let t=[],n=e,o=0;for(;n&&n!==document.body&&n!==document.documentElement&&o<3;){let s=n.tagName.toLowerCase();if(n.className&&typeof n.className=="string"){let i=n.className.trim().split(/\s+/).filter(r=>r&&!r.startsWith("rspnse-")).slice(0,2);i.length>0&&(s+="."+i.map(r=>CSS.escape(r)).join("."))}if(n.parentElement){let i=Array.from(n.parentElement.children).filter(r=>r.tagName===n.tagName);if(i.length>1){let r=i.indexOf(n)+1;s+=`:nth-of-type(${r})`}}t.unshift(s),n=n.parentElement,o++}return t.join(" > ")}function oe(e){let t=window.getComputedStyle(e),n={},o=document.createElement(e.tagName);o.style.cssText="position: absolute; visibility: hidden;",document.body.appendChild(o);let s=window.getComputedStyle(o);return Object.keys(te).forEach(i=>{te[i].forEach(r=>{let l=t.getPropertyValue(r),a=s.getPropertyValue(r);l&&l!==a&&l!=="none"&&l!=="auto"&&l!=="normal"&&l!=="0px"&&l!=="rgba(0, 0, 0, 0)"&&(n[r]=l)})}),o.remove(),{selector:ne(e),tagName:e.tagName.toLowerCase(),classList:Array.from(e.classList),id:e.id||null,computedStyles:n}}function se(e){let t=[],n=e;for(;n&&n!==document.documentElement;){if(n.nodeType!==1){n=n.parentElement;continue}let o=n.tagName.toLowerCase(),s=n.id?"#"+n.id:"",i=n.className&&typeof n.className=="string"?"."+n.className.trim().split(/\s+/).filter(r=>r&&!r.startsWith("rspnse-")).slice(0,1).join("."):"";t.unshift({label:o+s+i,index:t.length}),n=n.parentElement}t.unshift({label:"html",index:t.length});for(let o=0;o<t.length;o++)t[o].index=o;return t}function Oe(e){if(!f)return null;let t=[],n=f;for(;n&&n!==document.documentElement;)n.nodeType===1&&t.unshift(n),n=n.parentElement;return t.unshift(document.documentElement),t[e]||null}function Pe(e){let t=e.tagName.toLowerCase(),n=e.id?"#"+e.id:"",o=e.className&&typeof e.className=="string"?"."+e.className.trim().split(/\s+/).filter(s=>s&&!s.startsWith("rspnse-")).slice(0,2).join("."):"";return t+n+o}function Ae(){[v,_,k,N].forEach(s=>{let i=document.getElementById(s);i&&i.remove()});let e=document.createElement("div");e.id=v,e.style.cssText="position: fixed; pointer-events: none; z-index: 2147483646; border: 2px solid #3b82f6; background: rgba(59, 130, 246, 0.15); transition: all 0.05s ease-out; display: none;",document.body.appendChild(e);let t=document.createElement("div");t.id=k,t.style.cssText="position: fixed; pointer-events: none; z-index: 2147483645; background: rgba(249, 115, 22, 0.25); transition: all 0.05s ease-out; display: none;",document.body.appendChild(t);let n=document.createElement("div");n.id=N,n.style.cssText="position: fixed; pointer-events: none; z-index: 2147483644; background: rgba(34, 197, 94, 0.25); transition: all 0.05s ease-out; display: none;",document.body.appendChild(n);let o=document.createElement("div");return o.id=_,o.style.cssText="position: fixed; pointer-events: none; z-index: 2147483647; background: #1e293b; color: #f8fafc; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; padding: 4px 8px; border-radius: 4px; white-space: nowrap; display: none; box-shadow: 0 2px 8px rgba(0,0,0,0.3); max-width: calc(100vw - 16px); overflow: hidden; text-overflow: ellipsis;",document.body.appendChild(o),e}function ie(e){let t=document.getElementById(v),n=document.getElementById(_),o=document.getElementById(k),s=document.getElementById(N);if(!t||!n)return;if(!e){t.style.display="none",n.style.display="none",o&&(o.style.display="none"),s&&(s.style.display="none");return}let i=e.getBoundingClientRect(),r=window.getComputedStyle(e),l=parseFloat(r.marginTop)||0,a=parseFloat(r.marginRight)||0,d=parseFloat(r.marginBottom)||0,c=parseFloat(r.marginLeft)||0,m=parseFloat(r.paddingTop)||0,g=parseFloat(r.paddingRight)||0,y=parseFloat(r.paddingBottom)||0,M=parseFloat(r.paddingLeft)||0;t.style.display="block",t.style.top=i.top+"px",t.style.left=i.left+"px",t.style.width=i.width+"px",t.style.height=i.height+"px",o&&(l||a||d||c)?(o.style.display="block",o.style.top=i.top-l+"px",o.style.left=i.left-c+"px",o.style.width=i.width+c+a+"px",o.style.height=i.height+l+d+"px",o.style.clipPath=`polygon(0 0, 100% 0, 100% 100%, 0 100%, 0 0, ${c}px ${l}px, ${c}px ${l+i.height}px, ${c+i.width}px ${l+i.height}px, ${c+i.width}px ${l}px, ${c}px ${l}px)`):o&&(o.style.display="none"),s&&(m||g||y||M)?(s.style.display="block",s.style.top=i.top+"px",s.style.left=i.left+"px",s.style.width=i.width+"px",s.style.height=i.height+"px",s.style.clipPath=`polygon(0 0, 100% 0, 100% 100%, 0 100%, 0 0, ${M}px ${m}px, ${M}px ${i.height-y}px, ${i.width-g}px ${i.height-y}px, ${i.width-g}px ${m}px, ${M}px ${m}px)`):s&&(s.style.display="none");let pe=Pe(e),ge=`${Math.round(i.width)} x ${Math.round(i.height)}`;n.innerHTML=`<span style="color: #93c5fd;">${pe}</span> <span style="color: #94a3b8; margin-left: 6px;">${ge}</span>`,n.style.display="block",n.style.left="auto",n.style.right="auto";let $=window.innerWidth,I=i.top-24-6;I<4&&(I=i.bottom+6),n.style.top=I+"px",i.left+i.width/2>$/2?(n.style.right=Math.max(4,$-i.right)+"px",n.style.left="auto"):(n.style.left=Math.max(4,i.left)+"px",n.style.right="auto")}function A(e){if(!f)return-1;let t=[],n=f;for(;n&&n!==document.documentElement;)n.nodeType===1&&t.unshift(n),n=n.parentElement;t.unshift(document.documentElement);for(let o=0;o<t.length;o++)if(t[o]===e)return o;return-1}function P(e){if(!e||e.id&&e.id.startsWith("rspnse-"))return!1;S=e,ie(e);let t=oe(e),n=se(f),o=A(e);return window.parent!==window&&window.parent.postMessage({type:"RSPNSE_INSPECT_ELEMENT_RESULT",success:!0,element:t,breadcrumb:n,breadcrumbIndex:o},"*"),!0}function re(e){if(!E)return;let t=document.elementFromPoint(e.clientX,e.clientY);t&&t.id!==v&&ie(t)}function le(e){if(!E)return;if(e.preventDefault(),e.stopPropagation(),e.ctrlKey||e.metaKey){console.log("[dev-inspector] Ctrl+Click during inspect mode - triggering mark"),W(e);return}let t=document.elementFromPoint(e.clientX,e.clientY);if(t&&t.id!==v&&!t.id?.startsWith("rspnse-")){f=t,S=t;let n=oe(t),o=se(t);window.parent!==window&&window.parent.postMessage({type:"RSPNSE_INSPECT_ELEMENT_RESULT",success:!0,element:n,breadcrumb:o,breadcrumbIndex:o.length-1},"*")}}function ae(e){if(!E)return;if(e.key==="Escape"){H(),window.parent!==window&&window.parent.postMessage({type:"RSPNSE_INSPECT_CANCELLED",reason:"escape"},"*");return}if(!S||!f)return;let t=A(S),n=[],o=f;for(;o&&o!==document.documentElement;)o.nodeType===1&&n.unshift(o),o=o.parentElement;n.unshift(document.documentElement);let s=t;switch(e.key){case"ArrowUp":case"ArrowLeft":s=t-1;break;case"ArrowDown":case"ArrowRight":s=t+1;break;default:return}s>=0&&s<n.length&&(e.preventDefault(),P(n[s]))}function He(){E||(E=!0,document.body.style.cursor="crosshair",Ae(),document.addEventListener("mousemove",re,!0),document.addEventListener("click",le,!0),document.addEventListener("keydown",ae,!0))}function H(){E=!1,S=null,f=null,document.body.style.cursor="",[v,_,k,N].forEach(e=>{let t=document.getElementById(e);t&&t.remove()}),document.removeEventListener("mousemove",re,!0),document.removeEventListener("click",le,!0),document.removeEventListener("keydown",ae,!0)}function We(){let e=document.getElementById(L);e&&e.remove();let t=document.createElement("div");return t.id=L,t.style.cssText="position: fixed; pointer-events: none; z-index: 2147483646; border: 2px dashed #ef4444; background: rgba(239, 68, 68, 0.1); transition: all 0.05s ease-out; display: none;",document.body.appendChild(t),t}function $e(e){let t=document.getElementById(L);if(!t)return;if(!e){t.style.display="none";return}let n=e.getBoundingClientRect();t.style.display="block",t.style.top=n.top+"px",t.style.left=n.left+"px",t.style.width=n.width+"px",t.style.height=n.height+"px"}function ze(e){let t=[],n=e;for(;n&&n!==document.documentElement;){if(n.nodeType!==1){n=n.parentElement;continue}let o=n.tagName.toLowerCase(),s=n.id?"#"+n.id:"",i=n.className&&typeof n.className=="string"?"."+n.className.trim().split(/\s+/).filter(r=>r&&!r.startsWith("rspnse-")).slice(0,1).join("."):"";t.unshift(o+s+i),n=n.parentElement}return t.unshift("html"),t.join(" > ")}function Be(e){let t="rspnse-mark-feedback",n=document.getElementById(t);n||(n=document.createElement("div"),n.id=t,n.style.cssText="position: fixed; pointer-events: none; z-index: 2147483647; border: 3px solid #ef4444; background: rgba(239, 68, 68, 0.2); transition: opacity 0.3s ease-out;",document.body.appendChild(n));let o=e.getBoundingClientRect();n.style.top=o.top+"px",n.style.left=o.left+"px",n.style.width=o.width+"px",n.style.height=o.height+"px",n.style.opacity="1",setTimeout(()=>{n&&(n.style.opacity="0")},200),setTimeout(()=>{n?.remove()},500)}function W(e){let t=document.elementFromPoint(e.clientX,e.clientY),n=window.innerWidth,o=window.innerHeight,s=window.scrollX||window.pageXOffset||document.documentElement.scrollLeft,i=window.scrollY||window.pageYOffset||document.documentElement.scrollTop,r=Math.max(document.body.scrollWidth||0,document.documentElement.scrollWidth||0,document.body.offsetWidth||0,document.documentElement.offsetWidth||0),l=Math.max(document.body.scrollHeight||0,document.documentElement.scrollHeight||0,document.body.offsetHeight||0,document.documentElement.offsetHeight||0),a=e.clientX/n,d=e.clientY/o,c=e.clientX+s,m=e.clientY+i,g;if(t&&!t.id?.startsWith("rspnse-")){let y=t.getBoundingClientRect();g={selector:ne(t),tagName:t.tagName.toLowerCase(),breadcrumb:ze(t),relativeX:a,relativeY:d,captureWidth:n,captureHeight:o,documentX:c,documentY:m,documentWidth:r,documentHeight:l,scrollX:s,scrollY:i,elementWidth:Math.round(y.width),elementHeight:Math.round(y.height)},Be(t)}else g={selector:null,tagName:null,breadcrumb:null,relativeX:a,relativeY:d,captureWidth:n,captureHeight:o,documentX:c,documentY:m,documentWidth:r,documentHeight:l,scrollX:s,scrollY:i};window.parent!==window&&(console.log("[dev-inspector] Sending RSPNSE_MARK_ELEMENT message:",g),window.parent.postMessage({type:"RSPNSE_MARK_ELEMENT",success:!0,markElement:g},"*"))}function Ye(e){if(console.log("[dev-inspector] Click detected, ctrlKey:",e.ctrlKey,"metaKey:",e.metaKey,"inspectMode:",E),!(!e.ctrlKey&&!e.metaKey)){if(E){console.log("[dev-inspector] Ignoring Ctrl+Click - inspect mode is active");return}console.log("[dev-inspector] Ctrl+Click detected, capturing mark data..."),e.preventDefault(),e.stopPropagation(),W(e)}}function ce(e){if(!b)return;let t=document.elementFromPoint(e.clientX,e.clientY);t&&!t.id?.startsWith("rspnse-")&&$e(t)}function de(e){if(!b)return;e.preventDefault(),e.stopPropagation(),W(e);let t=document.elementFromPoint(e.clientX,e.clientY);if(t&&!t.id?.startsWith("rspnse-")){let n=document.getElementById(L);n&&(n.style.background="rgba(239, 68, 68, 0.3)",setTimeout(()=>{n.style.background="rgba(239, 68, 68, 0.1)"},150))}}function ue(e){b&&e.key==="Escape"&&(me(),window.parent!==window&&window.parent.postMessage({type:"RSPNSE_MARK_MODE_CANCELLED",reason:"escape"},"*"))}function Ge(){b||(E&&H(),b=!0,document.body.style.cursor="crosshair",We(),document.addEventListener("mousemove",ce,!0),document.addEventListener("click",de,!0),document.addEventListener("keydown",ue,!0))}function me(){b=!1,document.body.style.cursor="";let e=document.getElementById(L);e&&e.remove(),document.removeEventListener("mousemove",ce,!0),document.removeEventListener("click",de,!0),document.removeEventListener("keydown",ue,!0)}function u(e,t,n){if(e.source&&e.source!==window)try{e.source.postMessage({type:t.type+"_RESULT",requestId:t.requestId,frameId:t.frameId,...n},"*")}catch{}}function Fe(e){if(!ke(e.origin))return;let t=e.data;if(!(!t||typeof t!="object")&&t.type&&t.type.startsWith("RSPNSE_"))switch(t.type){case"RSPNSE_INJECT_CSS":typeof t.css=="string"?u(e,t,Ne(t.css)):u(e,t,{success:!1,error:"CSS must be a string"});break;case"RSPNSE_REMOVE_CSS":u(e,t,Ie());break;case"RSPNSE_GET_CSS":u(e,t,{success:!0,css:Re()});break;case"RSPNSE_CAPTURE_STYLES":De().then(n=>{u(e,t,{success:!0,styles:n})}).catch(n=>{u(e,t,{success:!1,error:n.message})});break;case"RSPNSE_INSPECT_START":He(),u(e,t,{success:!0});break;case"RSPNSE_INSPECT_STOP":H(),u(e,t,{success:!0});break;case"RSPNSE_INSPECT_NAVIGATE_TO":if(f&&typeof t.breadcrumbIndex=="number"){let n=Oe(t.breadcrumbIndex);n?(P(n),u(e,t,{success:!0})):u(e,t,{success:!1,error:"Element not found"})}else u(e,t,{success:!1,error:"No original element or invalid index"});break;case"RSPNSE_INSPECT_NAVIGATE":if(f&&S&&t.direction){let n=A(S),o=[],s=f;for(;s&&s!==document.documentElement;)s.nodeType===1&&o.unshift(s),s=s.parentElement;o.unshift(document.documentElement);let i=n;(t.direction==="left"||t.direction==="up")&&(i=n-1),(t.direction==="right"||t.direction==="down")&&(i=n+1),i>=0&&i<o.length?(P(o[i]),u(e,t,{success:!0})):u(e,t,{success:!1,error:"At end of breadcrumb"})}else u(e,t,{success:!1,error:"No selection"});break;case"RSPNSE_PING":u(e,t,{success:!0,pong:!0,version:x});break;case"RSPNSE_LAYOUT_DETECT":console.log("[dev-inspector] RSPNSE_LAYOUT_DETECT received, requestId:",t.requestId);try{let n=K();console.log("[dev-inspector] Detected",n.length,"containers"),u(e,t,{success:!0,containers:n}),console.log("[dev-inspector] Sent RSPNSE_LAYOUT_DETECT_RESULT")}catch(n){console.error("[dev-inspector] Detection error:",n),u(e,t,{success:!1,error:n.message})}break;case"RSPNSE_LAYOUT_HIGHLIGHT":t.containerId&&t.settings&&t.color?(t.visible!==!1?V(t.containerId,t.settings,t.color):J(t.containerId),u(e,t,{success:!0})):u(e,t,{success:!1,error:"Missing containerId, settings, or color"});break;case"RSPNSE_LAYOUT_CLEAR":Q(),u(e,t,{success:!0});break;case"RSPNSE_MARK_MODE_START":Ge(),u(e,t,{success:!0});break;case"RSPNSE_MARK_MODE_STOP":me(),u(e,t,{success:!0});break;case"RSPNSE_SCROLL_TO":typeof t.scrollToX=="number"&&typeof t.scrollToY=="number"?(window.scrollTo({left:t.scrollToX,top:t.scrollToY,behavior:"smooth"}),u(e,t,{success:!0})):u(e,t,{success:!1,error:"Missing scroll coordinates"});break}}var O=null;function Ue(){if(window.parent===window)return;let e=window.scrollX||window.pageXOffset||document.documentElement.scrollLeft,t=window.scrollY||window.pageYOffset||document.documentElement.scrollTop;window.parent.postMessage({type:"RSPNSE_SCROLL_UPDATE",scrollX:e,scrollY:t},"*")}function Xe(){O||(O=setTimeout(()=>{O=null,Ue()},16))}function Ke(){if(document.documentElement.setAttribute("data-rspnse-inspector",x),window.addEventListener("message",Fe),document.addEventListener("click",Ye,!0),window.addEventListener("scroll",Xe,{passive:!0}),window.parent!==window)try{window.parent.postMessage({type:"RSPNSE_DEV_INSPECTOR_READY",version:x,url:window.location.href},"*"),window.parent.postMessage({type:"RSPNSE_EXTENSION_READY",version:x,url:window.location.href},"*")}catch{}window.dispatchEvent(new CustomEvent("rspnse-inspector-loaded",{detail:{version:x}}))}Ke();})();
|
package/dist/index.js
CHANGED
|
@@ -2,18 +2,27 @@
|
|
|
2
2
|
import { readFileSync } from "fs";
|
|
3
3
|
import { resolve, dirname } from "path";
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
|
-
|
|
5
|
+
function getDirname() {
|
|
6
|
+
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
7
|
+
return dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
}
|
|
9
|
+
if (typeof __dirname !== "undefined") {
|
|
10
|
+
return __dirname;
|
|
11
|
+
}
|
|
12
|
+
return process.cwd();
|
|
13
|
+
}
|
|
14
|
+
var moduleDir = getDirname();
|
|
6
15
|
function rspnseInspector(options = {}) {
|
|
7
16
|
const { enabled = true, trustedOrigins } = options;
|
|
8
17
|
let inspectorScript = null;
|
|
9
18
|
function getInspectorScript() {
|
|
10
19
|
if (inspectorScript) return inspectorScript;
|
|
11
20
|
try {
|
|
12
|
-
const scriptPath = resolve(
|
|
21
|
+
const scriptPath = resolve(moduleDir, "../dist/index.inspector.js");
|
|
13
22
|
inspectorScript = readFileSync(scriptPath, "utf-8");
|
|
14
23
|
} catch {
|
|
15
24
|
try {
|
|
16
|
-
const scriptPath = resolve(
|
|
25
|
+
const scriptPath = resolve(moduleDir, "./index.inspector.js");
|
|
17
26
|
inspectorScript = readFileSync(scriptPath, "utf-8");
|
|
18
27
|
} catch {
|
|
19
28
|
console.warn(
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/vite-plugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport { readFileSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { RspnseInspectorOptions } from './types';\n\n// Get the directory of this module\
|
|
1
|
+
{"version":3,"sources":["../src/vite-plugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport { readFileSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { RspnseInspectorOptions } from './types';\n\n// Get the directory of this module (works in both ESM and CJS)\nfunction getDirname(): string {\n // ESM: use import.meta.url\n if (typeof import.meta !== 'undefined' && import.meta.url) {\n return dirname(fileURLToPath(import.meta.url));\n }\n // CJS: __dirname is globally available (injected by bundler)\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof __dirname !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return __dirname;\n }\n // Fallback: use process.cwd()\n return process.cwd();\n}\n\nconst moduleDir = getDirname();\n\n/**\n * Vite plugin that injects the Rspnse inspector script into dev server pages.\n * This enables inspect functionality from rspnse.net without a browser extension.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { rspnseInspector } from '@rspnseapp/dev-inspector';\n *\n * export default {\n * plugins: [rspnseInspector()]\n * }\n * ```\n */\nexport function rspnseInspector(options: RspnseInspectorOptions = {}): Plugin {\n const { enabled = true, trustedOrigins } = options;\n\n // Cache the inspector script content\n let inspectorScript: string | null = null;\n\n function getInspectorScript(): string {\n if (inspectorScript) return inspectorScript;\n\n try {\n // Try to load the bundled inspector script\n const scriptPath = resolve(moduleDir, '../dist/index.inspector.js');\n inspectorScript = readFileSync(scriptPath, 'utf-8');\n } catch {\n // Fallback: load from same directory (during development)\n try {\n const scriptPath = resolve(moduleDir, './index.inspector.js');\n inspectorScript = readFileSync(scriptPath, 'utf-8');\n } catch {\n console.warn(\n '[@rspnseapp/dev-inspector] Could not load inspector script. Run `npm run build` first.'\n );\n inspectorScript = '// Inspector script not found';\n }\n }\n\n return inspectorScript;\n }\n\n return {\n name: 'rspnse-inspector',\n\n // Only apply in dev mode\n apply: 'serve',\n\n configureServer(server) {\n if (!enabled) return;\n\n // Serve the inspector script at a special path\n server.middlewares.use((req, res, next) => {\n if (req.url === '/@rspnse-inspector/inspector.js') {\n res.setHeader('Content-Type', 'application/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n\n let script = getInspectorScript();\n\n // If custom trusted origins are provided, inject them\n if (trustedOrigins && trustedOrigins.length > 0) {\n const originsArray = JSON.stringify(trustedOrigins);\n script = `window.__RSPNSE_TRUSTED_ORIGINS__ = ${originsArray};\\n${script}`;\n }\n\n res.end(script);\n return;\n }\n next();\n });\n },\n\n transformIndexHtml(html) {\n if (!enabled) return html;\n\n // Inject the inspector script before </head>\n const scriptTag = `<script src=\"/@rspnse-inspector/inspector.js\" defer></script>`;\n\n if (html.includes('</head>')) {\n return html.replace('</head>', `${scriptTag}\\n</head>`);\n }\n\n // Fallback: inject at start of body if no head tag\n if (html.includes('<body')) {\n return html.replace(/<body([^>]*)>/, `<body$1>\\n${scriptTag}`);\n }\n\n // Last resort: prepend to html\n return scriptTag + '\\n' + html;\n },\n };\n}\n"],"mappings":";AACA,SAAS,oBAAoB;AAC7B,SAAS,SAAS,eAAe;AACjC,SAAS,qBAAqB;AAI9B,SAAS,aAAqB;AAE5B,MAAI,OAAO,gBAAgB,eAAe,YAAY,KAAK;AACzD,WAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AAAA,EAC/C;AAIA,MAAI,OAAO,cAAc,aAAa;AAGpC,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,IAAI;AACrB;AAEA,IAAM,YAAY,WAAW;AAgBtB,SAAS,gBAAgB,UAAkC,CAAC,GAAW;AAC5E,QAAM,EAAE,UAAU,MAAM,eAAe,IAAI;AAG3C,MAAI,kBAAiC;AAErC,WAAS,qBAA6B;AACpC,QAAI,gBAAiB,QAAO;AAE5B,QAAI;AAEF,YAAM,aAAa,QAAQ,WAAW,4BAA4B;AAClE,wBAAkB,aAAa,YAAY,OAAO;AAAA,IACpD,QAAQ;AAEN,UAAI;AACF,cAAM,aAAa,QAAQ,WAAW,sBAAsB;AAC5D,0BAAkB,aAAa,YAAY,OAAO;AAAA,MACpD,QAAQ;AACN,gBAAQ;AAAA,UACN;AAAA,QACF;AACA,0BAAkB;AAAA,MACpB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM;AAAA;AAAA,IAGN,OAAO;AAAA,IAEP,gBAAgB,QAAQ;AACtB,UAAI,CAAC,QAAS;AAGd,aAAO,YAAY,IAAI,CAAC,KAAK,KAAK,SAAS;AACzC,YAAI,IAAI,QAAQ,mCAAmC;AACjD,cAAI,UAAU,gBAAgB,wBAAwB;AACtD,cAAI,UAAU,iBAAiB,UAAU;AAEzC,cAAI,SAAS,mBAAmB;AAGhC,cAAI,kBAAkB,eAAe,SAAS,GAAG;AAC/C,kBAAM,eAAe,KAAK,UAAU,cAAc;AAClD,qBAAS,uCAAuC,YAAY;AAAA,EAAM,MAAM;AAAA,UAC1E;AAEA,cAAI,IAAI,MAAM;AACd;AAAA,QACF;AACA,aAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,IAEA,mBAAmB,MAAM;AACvB,UAAI,CAAC,QAAS,QAAO;AAGrB,YAAM,YAAY;AAElB,UAAI,KAAK,SAAS,SAAS,GAAG;AAC5B,eAAO,KAAK,QAAQ,WAAW,GAAG,SAAS;AAAA,QAAW;AAAA,MACxD;AAGA,UAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,eAAO,KAAK,QAAQ,iBAAiB;AAAA,EAAa,SAAS,EAAE;AAAA,MAC/D;AAGA,aAAO,YAAY,OAAO;AAAA,IAC5B;AAAA,EACF;AACF;","names":[]}
|
package/dist/webpack.cjs
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/webpack.ts
|
|
21
|
+
var webpack_exports = {};
|
|
22
|
+
__export(webpack_exports, {
|
|
23
|
+
RspnseInspectorPlugin: () => RspnseInspectorPlugin,
|
|
24
|
+
rspnseInspector: () => rspnseInspector
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(webpack_exports);
|
|
27
|
+
|
|
28
|
+
// src/webpack-plugin.ts
|
|
29
|
+
var import_fs = require("fs");
|
|
30
|
+
var import_path = require("path");
|
|
31
|
+
var import_url = require("url");
|
|
32
|
+
var import_meta = {};
|
|
33
|
+
var PLUGIN_NAME = "RspnseInspectorPlugin";
|
|
34
|
+
var INSPECTOR_PATH = "/__rspnse-inspector__/inspector.js";
|
|
35
|
+
function getDirname() {
|
|
36
|
+
if (typeof import_meta !== "undefined" && import_meta.url) {
|
|
37
|
+
return (0, import_path.dirname)((0, import_url.fileURLToPath)(import_meta.url));
|
|
38
|
+
}
|
|
39
|
+
if (typeof __dirname !== "undefined") {
|
|
40
|
+
return __dirname;
|
|
41
|
+
}
|
|
42
|
+
return process.cwd();
|
|
43
|
+
}
|
|
44
|
+
var moduleDir = getDirname();
|
|
45
|
+
var RspnseInspectorPlugin = class {
|
|
46
|
+
constructor(options = {}) {
|
|
47
|
+
this.inspectorScript = null;
|
|
48
|
+
this.options = {
|
|
49
|
+
enabled: true,
|
|
50
|
+
...options
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
getInspectorScript() {
|
|
54
|
+
if (this.inspectorScript) return this.inspectorScript;
|
|
55
|
+
try {
|
|
56
|
+
const scriptPath = (0, import_path.resolve)(moduleDir, "index.inspector.js");
|
|
57
|
+
this.inspectorScript = (0, import_fs.readFileSync)(scriptPath, "utf-8");
|
|
58
|
+
} catch {
|
|
59
|
+
console.warn(
|
|
60
|
+
`[${PLUGIN_NAME}] Could not load inspector script from ${moduleDir}.`
|
|
61
|
+
);
|
|
62
|
+
this.inspectorScript = "// Inspector script not found";
|
|
63
|
+
}
|
|
64
|
+
return this.inspectorScript;
|
|
65
|
+
}
|
|
66
|
+
apply(compiler) {
|
|
67
|
+
if (!this.options.enabled) return;
|
|
68
|
+
if (compiler.options.mode !== "development") return;
|
|
69
|
+
const { trustedOrigins } = this.options;
|
|
70
|
+
compiler.hooks.afterEnvironment.tap(PLUGIN_NAME, () => {
|
|
71
|
+
const devServer = compiler.options.devServer;
|
|
72
|
+
if (!devServer) return;
|
|
73
|
+
const originalSetupMiddlewares = devServer.setupMiddlewares;
|
|
74
|
+
devServer.setupMiddlewares = (middlewares, devServerInstance) => {
|
|
75
|
+
middlewares.unshift({
|
|
76
|
+
name: PLUGIN_NAME,
|
|
77
|
+
path: INSPECTOR_PATH,
|
|
78
|
+
middleware: (_req, res) => {
|
|
79
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
80
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
81
|
+
let script = this.getInspectorScript();
|
|
82
|
+
if (trustedOrigins && trustedOrigins.length > 0) {
|
|
83
|
+
const originsArray = JSON.stringify(trustedOrigins);
|
|
84
|
+
script = `window.__RSPNSE_TRUSTED_ORIGINS__ = ${originsArray};
|
|
85
|
+
${script}`;
|
|
86
|
+
}
|
|
87
|
+
res.end(script);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
if (originalSetupMiddlewares) {
|
|
91
|
+
return originalSetupMiddlewares(middlewares, devServerInstance);
|
|
92
|
+
}
|
|
93
|
+
return middlewares;
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
97
|
+
compilation.hooks.processAssets.tap(
|
|
98
|
+
{
|
|
99
|
+
name: PLUGIN_NAME,
|
|
100
|
+
// Run after HTML has been generated
|
|
101
|
+
stage: 1e3
|
|
102
|
+
},
|
|
103
|
+
(assets) => {
|
|
104
|
+
const scriptTag = `<script src="${INSPECTOR_PATH}" defer></script>`;
|
|
105
|
+
for (const name of Object.keys(assets)) {
|
|
106
|
+
if (name.endsWith(".html")) {
|
|
107
|
+
const asset = assets[name];
|
|
108
|
+
let html = asset.source().toString();
|
|
109
|
+
if (html.includes(INSPECTOR_PATH)) continue;
|
|
110
|
+
if (html.includes("</head>")) {
|
|
111
|
+
html = html.replace("</head>", `${scriptTag}
|
|
112
|
+
</head>`);
|
|
113
|
+
} else if (html.includes("<body")) {
|
|
114
|
+
html = html.replace(/<body([^>]*)>/, `<body$1>
|
|
115
|
+
${scriptTag}`);
|
|
116
|
+
} else {
|
|
117
|
+
html = scriptTag + "\n" + html;
|
|
118
|
+
}
|
|
119
|
+
const webpack = require("webpack");
|
|
120
|
+
compilation.updateAsset(name, new webpack.sources.RawSource(html));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
function rspnseInspector(options = {}) {
|
|
129
|
+
return new RspnseInspectorPlugin(options);
|
|
130
|
+
}
|
|
131
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
132
|
+
0 && (module.exports = {
|
|
133
|
+
RspnseInspectorPlugin,
|
|
134
|
+
rspnseInspector
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=webpack.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/webpack.ts","../src/webpack-plugin.ts"],"sourcesContent":["/**\n * @rspnseapp/dev-inspector/webpack\n *\n * A Webpack plugin that enables Rspnse inspect functionality on localhost dev servers.\n * Works across all browsers without requiring a browser extension.\n *\n * @example\n * ```ts\n * // webpack.config.js\n * const { RspnseInspectorPlugin } = require('@rspnseapp/dev-inspector/webpack');\n *\n * module.exports = {\n * plugins: [new RspnseInspectorPlugin()]\n * };\n * ```\n *\n * Or using the factory function:\n * ```ts\n * const { rspnseInspector } = require('@rspnseapp/dev-inspector/webpack');\n *\n * module.exports = {\n * plugins: [rspnseInspector()]\n * };\n * ```\n *\n * Then open your site in rspnse.net and use the inspect feature!\n */\n\nexport { RspnseInspectorPlugin, rspnseInspector } from './webpack-plugin';\nexport type {\n RspnseInspectorOptions,\n InspectedElement,\n BreadcrumbItem,\n StyleEntry,\n} from './types';\n","import type { Compiler } from 'webpack';\nimport { readFileSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { RspnseInspectorOptions } from './types';\n\nconst PLUGIN_NAME = 'RspnseInspectorPlugin';\nconst INSPECTOR_PATH = '/__rspnse-inspector__/inspector.js';\n\n// Get the directory of this module (works in both ESM and CJS)\nfunction getDirname(): string {\n // ESM: use import.meta.url\n if (typeof import.meta !== 'undefined' && import.meta.url) {\n return dirname(fileURLToPath(import.meta.url));\n }\n // CJS: __dirname is globally available (injected by bundler)\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof __dirname !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return __dirname;\n }\n // Fallback: use process.cwd()\n return process.cwd();\n}\n\nconst moduleDir = getDirname();\n\n/**\n * Webpack plugin that injects the Rspnse inspector script into dev server pages.\n * This enables inspect functionality from rspnse.net without a browser extension.\n *\n * @example\n * ```ts\n * // webpack.config.js (ESM)\n * import { RspnseInspectorPlugin } from '@rspnseapp/dev-inspector/webpack';\n *\n * export default {\n * plugins: [new RspnseInspectorPlugin()]\n * }\n * ```\n */\nexport class RspnseInspectorPlugin {\n private options: Required<Pick<RspnseInspectorOptions, 'enabled'>> &\n RspnseInspectorOptions;\n private inspectorScript: string | null = null;\n\n constructor(options: RspnseInspectorOptions = {}) {\n this.options = {\n enabled: true,\n ...options,\n };\n }\n\n private getInspectorScript(): string {\n if (this.inspectorScript) return this.inspectorScript;\n\n try {\n // Load the bundled inspector script from dist\n const scriptPath = resolve(moduleDir, 'index.inspector.js');\n this.inspectorScript = readFileSync(scriptPath, 'utf-8');\n } catch {\n console.warn(\n `[${PLUGIN_NAME}] Could not load inspector script from ${moduleDir}.`\n );\n this.inspectorScript = '// Inspector script not found';\n }\n\n return this.inspectorScript;\n }\n\n apply(compiler: Compiler): void {\n if (!this.options.enabled) return;\n\n // Only apply in development mode\n if (compiler.options.mode !== 'development') return;\n\n const { trustedOrigins } = this.options;\n\n // Add middleware to serve the inspector script via devServer\n compiler.hooks.afterEnvironment.tap(PLUGIN_NAME, () => {\n const devServer = compiler.options.devServer as\n | {\n setupMiddlewares?: (\n middlewares: Array<{\n name: string;\n path: string;\n middleware: (\n req: unknown,\n res: { setHeader: (k: string, v: string) => void; end: (s: string) => void }\n ) => void;\n }>,\n devServer: unknown\n ) => unknown[];\n }\n | undefined;\n\n if (!devServer) return;\n\n // Store original setupMiddlewares if it exists\n const originalSetupMiddlewares = devServer.setupMiddlewares;\n\n devServer.setupMiddlewares = (middlewares, devServerInstance) => {\n // Add our middleware first\n middlewares.unshift({\n name: PLUGIN_NAME,\n path: INSPECTOR_PATH,\n middleware: (_req, res) => {\n res.setHeader('Content-Type', 'application/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n\n let script = this.getInspectorScript();\n\n // If custom trusted origins are provided, inject them\n if (trustedOrigins && trustedOrigins.length > 0) {\n const originsArray = JSON.stringify(trustedOrigins);\n script = `window.__RSPNSE_TRUSTED_ORIGINS__ = ${originsArray};\\n${script}`;\n }\n\n res.end(script);\n },\n });\n\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n return originalSetupMiddlewares(middlewares, devServerInstance) as typeof middlewares;\n }\n\n return middlewares;\n };\n });\n\n // Inject script tag into HTML assets\n compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {\n compilation.hooks.processAssets.tap(\n {\n name: PLUGIN_NAME,\n // Run after HTML has been generated\n stage: 1000,\n },\n (assets) => {\n const scriptTag = `<script src=\"${INSPECTOR_PATH}\" defer></script>`;\n\n for (const name of Object.keys(assets)) {\n if (name.endsWith('.html')) {\n const asset = assets[name];\n let html = asset.source().toString();\n\n // Don't inject twice\n if (html.includes(INSPECTOR_PATH)) continue;\n\n if (html.includes('</head>')) {\n html = html.replace('</head>', `${scriptTag}\\n</head>`);\n } else if (html.includes('<body')) {\n html = html.replace(/<body([^>]*)>/, `<body$1>\\n${scriptTag}`);\n } else {\n html = scriptTag + '\\n' + html;\n }\n\n // Update the asset - use webpack's sources API\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const webpack = require('webpack') as typeof import('webpack');\n compilation.updateAsset(name, new webpack.sources.RawSource(html));\n }\n }\n }\n );\n });\n }\n}\n\n/**\n * Factory function for creating the plugin (alternative to class instantiation)\n */\nexport function rspnseInspector(\n options: RspnseInspectorOptions = {}\n): RspnseInspectorPlugin {\n return new RspnseInspectorPlugin(options);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Compiler } from 'webpack';
|
|
2
|
+
|
|
3
|
+
interface BreadcrumbItem {
|
|
4
|
+
label: string;
|
|
5
|
+
index: number;
|
|
6
|
+
}
|
|
7
|
+
interface InspectedElement {
|
|
8
|
+
selector: string;
|
|
9
|
+
tagName: string;
|
|
10
|
+
classList: string[];
|
|
11
|
+
id: string | null;
|
|
12
|
+
computedStyles: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
interface StyleEntry {
|
|
15
|
+
type: 'inline' | 'external';
|
|
16
|
+
index?: number;
|
|
17
|
+
href?: string;
|
|
18
|
+
css: string | null;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
interface RspnseInspectorOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Enable/disable the inspector. Defaults to true in development.
|
|
24
|
+
*/
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Trusted origins that can communicate with the inspector.
|
|
28
|
+
* Defaults to ['https://rspnse.net', 'http://localhost']
|
|
29
|
+
*/
|
|
30
|
+
trustedOrigins?: string[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Webpack plugin that injects the Rspnse inspector script into dev server pages.
|
|
35
|
+
* This enables inspect functionality from rspnse.net without a browser extension.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* // webpack.config.js (ESM)
|
|
40
|
+
* import { RspnseInspectorPlugin } from '@rspnseapp/dev-inspector/webpack';
|
|
41
|
+
*
|
|
42
|
+
* export default {
|
|
43
|
+
* plugins: [new RspnseInspectorPlugin()]
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
declare class RspnseInspectorPlugin {
|
|
48
|
+
private options;
|
|
49
|
+
private inspectorScript;
|
|
50
|
+
constructor(options?: RspnseInspectorOptions);
|
|
51
|
+
private getInspectorScript;
|
|
52
|
+
apply(compiler: Compiler): void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Factory function for creating the plugin (alternative to class instantiation)
|
|
56
|
+
*/
|
|
57
|
+
declare function rspnseInspector(options?: RspnseInspectorOptions): RspnseInspectorPlugin;
|
|
58
|
+
|
|
59
|
+
export { type BreadcrumbItem, type InspectedElement, type RspnseInspectorOptions, RspnseInspectorPlugin, type StyleEntry, rspnseInspector };
|
package/dist/webpack.js
CHANGED
|
@@ -11,7 +11,16 @@ import { resolve, dirname } from "path";
|
|
|
11
11
|
import { fileURLToPath } from "url";
|
|
12
12
|
var PLUGIN_NAME = "RspnseInspectorPlugin";
|
|
13
13
|
var INSPECTOR_PATH = "/__rspnse-inspector__/inspector.js";
|
|
14
|
-
|
|
14
|
+
function getDirname() {
|
|
15
|
+
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
16
|
+
return dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
}
|
|
18
|
+
if (typeof __dirname !== "undefined") {
|
|
19
|
+
return __dirname;
|
|
20
|
+
}
|
|
21
|
+
return process.cwd();
|
|
22
|
+
}
|
|
23
|
+
var moduleDir = getDirname();
|
|
15
24
|
var RspnseInspectorPlugin = class {
|
|
16
25
|
constructor(options = {}) {
|
|
17
26
|
this.inspectorScript = null;
|
|
@@ -23,11 +32,11 @@ var RspnseInspectorPlugin = class {
|
|
|
23
32
|
getInspectorScript() {
|
|
24
33
|
if (this.inspectorScript) return this.inspectorScript;
|
|
25
34
|
try {
|
|
26
|
-
const scriptPath = resolve(
|
|
35
|
+
const scriptPath = resolve(moduleDir, "index.inspector.js");
|
|
27
36
|
this.inspectorScript = readFileSync(scriptPath, "utf-8");
|
|
28
37
|
} catch {
|
|
29
38
|
console.warn(
|
|
30
|
-
`[${PLUGIN_NAME}] Could not load inspector script from ${
|
|
39
|
+
`[${PLUGIN_NAME}] Could not load inspector script from ${moduleDir}.`
|
|
31
40
|
);
|
|
32
41
|
this.inspectorScript = "// Inspector script not found";
|
|
33
42
|
}
|
package/dist/webpack.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/webpack-plugin.ts"],"sourcesContent":["import type { Compiler } from 'webpack';\nimport { readFileSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { RspnseInspectorOptions } from './types';\n\nconst PLUGIN_NAME = 'RspnseInspectorPlugin';\nconst INSPECTOR_PATH = '/__rspnse-inspector__/inspector.js';\n\n// Get the directory of this module (ESM)\
|
|
1
|
+
{"version":3,"sources":["../src/webpack-plugin.ts"],"sourcesContent":["import type { Compiler } from 'webpack';\nimport { readFileSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { RspnseInspectorOptions } from './types';\n\nconst PLUGIN_NAME = 'RspnseInspectorPlugin';\nconst INSPECTOR_PATH = '/__rspnse-inspector__/inspector.js';\n\n// Get the directory of this module (works in both ESM and CJS)\nfunction getDirname(): string {\n // ESM: use import.meta.url\n if (typeof import.meta !== 'undefined' && import.meta.url) {\n return dirname(fileURLToPath(import.meta.url));\n }\n // CJS: __dirname is globally available (injected by bundler)\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof __dirname !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return __dirname;\n }\n // Fallback: use process.cwd()\n return process.cwd();\n}\n\nconst moduleDir = getDirname();\n\n/**\n * Webpack plugin that injects the Rspnse inspector script into dev server pages.\n * This enables inspect functionality from rspnse.net without a browser extension.\n *\n * @example\n * ```ts\n * // webpack.config.js (ESM)\n * import { RspnseInspectorPlugin } from '@rspnseapp/dev-inspector/webpack';\n *\n * export default {\n * plugins: [new RspnseInspectorPlugin()]\n * }\n * ```\n */\nexport class RspnseInspectorPlugin {\n private options: Required<Pick<RspnseInspectorOptions, 'enabled'>> &\n RspnseInspectorOptions;\n private inspectorScript: string | null = null;\n\n constructor(options: RspnseInspectorOptions = {}) {\n this.options = {\n enabled: true,\n ...options,\n };\n }\n\n private getInspectorScript(): string {\n if (this.inspectorScript) return this.inspectorScript;\n\n try {\n // Load the bundled inspector script from dist\n const scriptPath = resolve(moduleDir, 'index.inspector.js');\n this.inspectorScript = readFileSync(scriptPath, 'utf-8');\n } catch {\n console.warn(\n `[${PLUGIN_NAME}] Could not load inspector script from ${moduleDir}.`\n );\n this.inspectorScript = '// Inspector script not found';\n }\n\n return this.inspectorScript;\n }\n\n apply(compiler: Compiler): void {\n if (!this.options.enabled) return;\n\n // Only apply in development mode\n if (compiler.options.mode !== 'development') return;\n\n const { trustedOrigins } = this.options;\n\n // Add middleware to serve the inspector script via devServer\n compiler.hooks.afterEnvironment.tap(PLUGIN_NAME, () => {\n const devServer = compiler.options.devServer as\n | {\n setupMiddlewares?: (\n middlewares: Array<{\n name: string;\n path: string;\n middleware: (\n req: unknown,\n res: { setHeader: (k: string, v: string) => void; end: (s: string) => void }\n ) => void;\n }>,\n devServer: unknown\n ) => unknown[];\n }\n | undefined;\n\n if (!devServer) return;\n\n // Store original setupMiddlewares if it exists\n const originalSetupMiddlewares = devServer.setupMiddlewares;\n\n devServer.setupMiddlewares = (middlewares, devServerInstance) => {\n // Add our middleware first\n middlewares.unshift({\n name: PLUGIN_NAME,\n path: INSPECTOR_PATH,\n middleware: (_req, res) => {\n res.setHeader('Content-Type', 'application/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n\n let script = this.getInspectorScript();\n\n // If custom trusted origins are provided, inject them\n if (trustedOrigins && trustedOrigins.length > 0) {\n const originsArray = JSON.stringify(trustedOrigins);\n script = `window.__RSPNSE_TRUSTED_ORIGINS__ = ${originsArray};\\n${script}`;\n }\n\n res.end(script);\n },\n });\n\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n return originalSetupMiddlewares(middlewares, devServerInstance) as typeof middlewares;\n }\n\n return middlewares;\n };\n });\n\n // Inject script tag into HTML assets\n compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {\n compilation.hooks.processAssets.tap(\n {\n name: PLUGIN_NAME,\n // Run after HTML has been generated\n stage: 1000,\n },\n (assets) => {\n const scriptTag = `<script src=\"${INSPECTOR_PATH}\" defer></script>`;\n\n for (const name of Object.keys(assets)) {\n if (name.endsWith('.html')) {\n const asset = assets[name];\n let html = asset.source().toString();\n\n // Don't inject twice\n if (html.includes(INSPECTOR_PATH)) continue;\n\n if (html.includes('</head>')) {\n html = html.replace('</head>', `${scriptTag}\\n</head>`);\n } else if (html.includes('<body')) {\n html = html.replace(/<body([^>]*)>/, `<body$1>\\n${scriptTag}`);\n } else {\n html = scriptTag + '\\n' + html;\n }\n\n // Update the asset - use webpack's sources API\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const webpack = require('webpack') as typeof import('webpack');\n compilation.updateAsset(name, new webpack.sources.RawSource(html));\n }\n }\n }\n );\n });\n }\n}\n\n/**\n * Factory function for creating the plugin (alternative to class instantiation)\n */\nexport function rspnseInspector(\n options: RspnseInspectorOptions = {}\n): RspnseInspectorPlugin {\n return new RspnseInspectorPlugin(options);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rspnseapp/dev-inspector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Dev server plugins for Rspnse inspect functionality (Vite & Webpack)",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/index.
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"
|
|
12
|
-
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
13
19
|
},
|
|
14
20
|
"./webpack": {
|
|
15
|
-
"
|
|
16
|
-
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/webpack.d.ts",
|
|
23
|
+
"default": "./dist/webpack.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/webpack.d.cts",
|
|
27
|
+
"default": "./dist/webpack.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"./inspector": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"default": "./dist/index.inspector.js"
|
|
17
33
|
}
|
|
18
34
|
},
|
|
19
35
|
"files": [
|
|
@@ -35,13 +51,17 @@
|
|
|
35
51
|
"css",
|
|
36
52
|
"devtools"
|
|
37
53
|
],
|
|
38
|
-
"author": "",
|
|
54
|
+
"author": "AlexBoghh",
|
|
39
55
|
"license": "MIT",
|
|
56
|
+
"homepage": "https://rspnse.net",
|
|
40
57
|
"repository": {
|
|
41
58
|
"type": "git",
|
|
42
59
|
"url": "git+https://github.com/AlexBoghh/Rspnse.git",
|
|
43
60
|
"directory": "packages/dev-inspector"
|
|
44
61
|
},
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/AlexBoghh/Rspnse/issues"
|
|
64
|
+
},
|
|
45
65
|
"peerDependencies": {
|
|
46
66
|
"vite": ">=4.0.0",
|
|
47
67
|
"webpack": ">=5.0.0"
|