@abbox/inspector 0.0.0-stage → 0.2.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/README.md +51 -2
- package/dist/browser.d.ts +9 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +8 -0
- package/dist/host/client-bridge.d.ts +13 -0
- package/dist/host/client-bridge.d.ts.map +1 -0
- package/dist/host/client-bridge.js +75 -0
- package/dist/host/host-bridge.d.ts +34 -0
- package/dist/host/host-bridge.d.ts.map +1 -0
- package/dist/host/host-bridge.js +59 -0
- package/dist/host/origin-aliases.d.ts +3 -0
- package/dist/host/origin-aliases.d.ts.map +1 -0
- package/dist/host/origin-aliases.js +13 -0
- package/dist/host/validate.d.ts +8 -0
- package/dist/host/validate.d.ts.map +1 -0
- package/dist/host/validate.js +13 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/instrument/babel-plugin.d.ts +8 -0
- package/dist/instrument/babel-plugin.d.ts.map +1 -0
- package/dist/instrument/babel-plugin.js +26 -0
- package/dist/instrument/constants.d.ts +10 -0
- package/dist/instrument/constants.d.ts.map +1 -0
- package/dist/instrument/constants.js +17 -0
- package/dist/ir-match.d.ts +34 -0
- package/dist/ir-match.d.ts.map +1 -0
- package/dist/ir-match.js +129 -0
- package/dist/next/babel-config.cjs +39 -0
- package/dist/next/index.d.ts +3 -0
- package/dist/next/index.d.ts.map +1 -0
- package/dist/next/index.js +2 -0
- package/dist/next/preview-env.d.ts +8 -0
- package/dist/next/preview-env.d.ts.map +1 -0
- package/dist/next/preview-env.js +22 -0
- package/dist/next/webpack-instrumentation.cjs +82 -0
- package/dist/next/with-abbox-inspector.d.ts +26 -0
- package/dist/next/with-abbox-inspector.d.ts.map +1 -0
- package/dist/next/with-abbox-inspector.js +80 -0
- package/dist/protocol.d.ts +92 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +12 -0
- package/dist/react/AbboxInspectorBoot.d.ts +3 -0
- package/dist/react/AbboxInspectorBoot.d.ts.map +1 -0
- package/dist/react/AbboxInspectorBoot.js +10 -0
- package/dist/runtime/bootstrap.d.ts +10 -0
- package/dist/runtime/bootstrap.d.ts.map +1 -0
- package/dist/runtime/bootstrap.js +49 -0
- package/dist/runtime/element-ref.d.ts +4 -0
- package/dist/runtime/element-ref.d.ts.map +1 -0
- package/dist/runtime/element-ref.js +14 -0
- package/dist/runtime/inspector.d.ts +18 -0
- package/dist/runtime/inspector.d.ts.map +1 -0
- package/dist/runtime/inspector.js +137 -0
- package/dist/runtime/metadata.d.ts +6 -0
- package/dist/runtime/metadata.d.ts.map +1 -0
- package/dist/runtime/metadata.js +81 -0
- package/dist/runtime/overlay.d.ts +12 -0
- package/dist/runtime/overlay.d.ts.map +1 -0
- package/dist/runtime/overlay.js +104 -0
- package/dist/vite-plugin.d.ts +8 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.js +29 -0
- package/docs/TRUST.md +18 -0
- package/docs/architecture.md +21 -0
- package/docs/implementation-report.md +23 -0
- package/docs/integration.md +21 -0
- package/docs/known-limitations.md +8 -0
- package/docs/nextjs-integration.md +35 -0
- package/package.json +90 -4
- package/src/next/babel-config.cjs +39 -0
- package/src/next/webpack-instrumentation.cjs +82 -0
package/README.md
CHANGED
|
@@ -1,3 +1,52 @@
|
|
|
1
|
-
#
|
|
1
|
+
# abbox-inspector
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Runtime visual inspection for instrumented React/Next.js previews. Used by **Abbox Viewer** (Live Preview workspace) and embeddable in authorized preview apps.
|
|
4
|
+
|
|
5
|
+
## Local development
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd abbox-inspector
|
|
9
|
+
npm install
|
|
10
|
+
npm run ci
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Example preview (port 5174)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm run example:dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### With Abbox Viewer
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# terminal 1
|
|
23
|
+
cd abbox-inspector && npm run example:dev
|
|
24
|
+
|
|
25
|
+
# terminal 2
|
|
26
|
+
cd abbox-viewer && npm install && npm run dev
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Load compiler + interpreter JSON in the viewer, open **Live Preview**, enable **Inspect**, click elements in the iframe.
|
|
30
|
+
|
|
31
|
+
Query parameters on the preview URL:
|
|
32
|
+
|
|
33
|
+
- `abboxSession` — must match the viewer session id (default `local-dev`)
|
|
34
|
+
- `abboxHostOrigin` — viewer origin allowed to control inspect mode
|
|
35
|
+
|
|
36
|
+
## Package exports
|
|
37
|
+
|
|
38
|
+
| Import | Purpose |
|
|
39
|
+
|--------|---------|
|
|
40
|
+
| `abbox-inspector` | Protocol, host/client bridges, IR match helpers, Babel plugin |
|
|
41
|
+
| `abbox-inspector/runtime` | `bootstrapInspectorPreview()` for preview apps |
|
|
42
|
+
| `abbox-inspector/vite` | Optional Vite transform plugin |
|
|
43
|
+
|
|
44
|
+
## Instrumentation
|
|
45
|
+
|
|
46
|
+
Build-time Babel plugin adds `data-abbox-src="relative/path.tsx:line:column"` to JSX opening tags. Paths are relative to the project root; no absolute filesystem paths are emitted.
|
|
47
|
+
|
|
48
|
+
## Onlook
|
|
49
|
+
|
|
50
|
+
[Onlook](https://github.com/onlook-dev/onlook) was reviewed for overlay and instrumentation patterns. This package is a small standalone implementation (Apache-2.0); no code was copied wholesale.
|
|
51
|
+
|
|
52
|
+
See `docs/architecture.md` and `docs/integration.md`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Browser / Viewer-safe entry (no Babel, Vite, or Next build tooling). */
|
|
2
|
+
export * from "./protocol.js";
|
|
3
|
+
export * from "./ir-match.js";
|
|
4
|
+
export * from "./instrument/constants.js";
|
|
5
|
+
export { createInspectorClient } from "./host/client-bridge.js";
|
|
6
|
+
export { createInspectorHost } from "./host/host-bridge.js";
|
|
7
|
+
export { validateIncomingMessage } from "./host/validate.js";
|
|
8
|
+
export { createInspectorRuntime } from "./runtime/inspector.js";
|
|
9
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Browser / Viewer-safe entry (no Babel, Vite, or Next build tooling). */
|
|
2
|
+
export * from "./protocol.js";
|
|
3
|
+
export * from "./ir-match.js";
|
|
4
|
+
export * from "./instrument/constants.js";
|
|
5
|
+
export { createInspectorClient } from "./host/client-bridge.js";
|
|
6
|
+
export { createInspectorHost } from "./host/host-bridge.js";
|
|
7
|
+
export { validateIncomingMessage } from "./host/validate.js";
|
|
8
|
+
export { createInspectorRuntime } from "./runtime/inspector.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type InspectorClientOptions = {
|
|
2
|
+
sessionId: string;
|
|
3
|
+
/** Origins allowed to control this preview (typically the Viewer origin). */
|
|
4
|
+
allowedHostOrigins: readonly string[];
|
|
5
|
+
window?: Window;
|
|
6
|
+
document?: Document;
|
|
7
|
+
};
|
|
8
|
+
export type InspectorClient = {
|
|
9
|
+
start: () => void;
|
|
10
|
+
stop: () => void;
|
|
11
|
+
};
|
|
12
|
+
export declare function createInspectorClient(options: InspectorClientOptions): InspectorClient;
|
|
13
|
+
//# sourceMappingURL=client-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-bridge.d.ts","sourceRoot":"","sources":["../../src/host/client-bridge.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAsEjB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ABBBOX_INSPECTOR_CHANNEL, PROTOCOL_VERSION, } from "../protocol.js";
|
|
2
|
+
import { withLocalhostAliases } from "./origin-aliases.js";
|
|
3
|
+
import { createInspectorRuntime } from "../runtime/inspector.js";
|
|
4
|
+
import { validateIncomingMessage } from "./validate.js";
|
|
5
|
+
export function createInspectorClient(options) {
|
|
6
|
+
const win = options.window ?? globalThis.window;
|
|
7
|
+
const doc = options.document ?? win.document;
|
|
8
|
+
const allowedOrigins = withLocalhostAliases(options.allowedHostOrigins);
|
|
9
|
+
const send = (message) => {
|
|
10
|
+
if (!win.parent || win.parent === win)
|
|
11
|
+
return;
|
|
12
|
+
for (const targetOrigin of allowedOrigins) {
|
|
13
|
+
win.parent.postMessage(message, targetOrigin);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const base = () => ({
|
|
17
|
+
channel: ABBBOX_INSPECTOR_CHANNEL,
|
|
18
|
+
version: PROTOCOL_VERSION,
|
|
19
|
+
sessionId: options.sessionId,
|
|
20
|
+
});
|
|
21
|
+
const sendReady = () => {
|
|
22
|
+
const ready = {
|
|
23
|
+
...base(),
|
|
24
|
+
type: "INSPECTOR_READY",
|
|
25
|
+
previewUrl: win.location.href,
|
|
26
|
+
};
|
|
27
|
+
send(ready);
|
|
28
|
+
};
|
|
29
|
+
const runtime = createInspectorRuntime({
|
|
30
|
+
document: doc,
|
|
31
|
+
window: win,
|
|
32
|
+
onHover: (payload) => {
|
|
33
|
+
send({ ...base(), type: "ELEMENT_HOVERED", payload });
|
|
34
|
+
},
|
|
35
|
+
onSelect: (payload) => {
|
|
36
|
+
send({ ...base(), type: "ELEMENT_SELECTED", payload });
|
|
37
|
+
},
|
|
38
|
+
onClear: () => {
|
|
39
|
+
send({ ...base(), type: "ELEMENT_CLEARED" });
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
const onMessage = (event) => {
|
|
43
|
+
const msg = validateIncomingMessage(event.data, event.origin, {
|
|
44
|
+
sessionId: options.sessionId,
|
|
45
|
+
allowedOrigins,
|
|
46
|
+
});
|
|
47
|
+
if (!msg)
|
|
48
|
+
return;
|
|
49
|
+
if (msg.type === "INSPECTOR_HOST_HELLO")
|
|
50
|
+
sendReady();
|
|
51
|
+
if (msg.type === "INSPECTOR_ENABLE")
|
|
52
|
+
runtime.enable();
|
|
53
|
+
if (msg.type === "INSPECTOR_DISABLE")
|
|
54
|
+
runtime.disable();
|
|
55
|
+
if (msg.type === "APPLY_CHANGE_MARKERS") {
|
|
56
|
+
runtime.setChangeMarkers(msg.markers);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
start: () => {
|
|
61
|
+
win.addEventListener("message", onMessage);
|
|
62
|
+
sendReady();
|
|
63
|
+
if (doc.readyState === "complete") {
|
|
64
|
+
sendReady();
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
win.addEventListener("load", sendReady, { once: true });
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
stop: () => {
|
|
71
|
+
win.removeEventListener("message", onMessage);
|
|
72
|
+
runtime.destroy();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ChangeMarker, type ClientToHostMessage } from "../protocol.js";
|
|
2
|
+
export type InspectorHostOptions = {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
/** Origin of the embedded preview (iframe src origin). */
|
|
5
|
+
previewOrigin: string;
|
|
6
|
+
/** Viewer origin (allowed to receive messages). */
|
|
7
|
+
hostOrigin: string;
|
|
8
|
+
getPreviewWindow: () => Window | null;
|
|
9
|
+
};
|
|
10
|
+
type HoverPayload = Extract<ClientToHostMessage, {
|
|
11
|
+
type: "ELEMENT_HOVERED";
|
|
12
|
+
}>["payload"];
|
|
13
|
+
type SelectPayload = Extract<ClientToHostMessage, {
|
|
14
|
+
type: "ELEMENT_SELECTED";
|
|
15
|
+
}>["payload"];
|
|
16
|
+
export type InspectorHostHandlers = {
|
|
17
|
+
onReady?: (previewUrl: string) => void;
|
|
18
|
+
onHover?: (payload: HoverPayload) => void;
|
|
19
|
+
onSelect?: (payload: SelectPayload) => void;
|
|
20
|
+
onCleared?: () => void;
|
|
21
|
+
onError?: (code: string, message: string) => void;
|
|
22
|
+
};
|
|
23
|
+
export type InspectorHost = {
|
|
24
|
+
connect: () => void;
|
|
25
|
+
disconnect: () => void;
|
|
26
|
+
enableInspect: () => void;
|
|
27
|
+
disableInspect: () => void;
|
|
28
|
+
applyChangeMarkers: (markers: ChangeMarker[]) => void;
|
|
29
|
+
/** Ask the preview to resend INSPECTOR_READY (call after iframe load). */
|
|
30
|
+
pingPreview: () => void;
|
|
31
|
+
};
|
|
32
|
+
export declare function createInspectorHost(options: InspectorHostOptions, handlers: InspectorHostHandlers): InspectorHost;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=host-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-bridge.d.ts","sourceRoot":"","sources":["../../src/host/host-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,mBAAmB,EAGzB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACvC,CAAC;AAEF,KAAK,YAAY,GAAG,OAAO,CACzB,mBAAmB,EACnB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,CAC5B,CAAC,SAAS,CAAC,CAAC;AACb,KAAK,aAAa,GAAG,OAAO,CAC1B,mBAAmB,EACnB;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAC7B,CAAC,SAAS,CAAC,CAAC;AAEb,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,kBAAkB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IACtD,0EAA0E;IAC1E,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,qBAAqB,GAC9B,aAAa,CAwDf"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ABBBOX_INSPECTOR_CHANNEL, PROTOCOL_VERSION, } from "../protocol.js";
|
|
2
|
+
import { withLocalhostAliases } from "./origin-aliases.js";
|
|
3
|
+
import { postToTarget, validateIncomingMessage } from "./validate.js";
|
|
4
|
+
export function createInspectorHost(options, handlers) {
|
|
5
|
+
const base = () => ({
|
|
6
|
+
channel: ABBBOX_INSPECTOR_CHANNEL,
|
|
7
|
+
version: PROTOCOL_VERSION,
|
|
8
|
+
sessionId: options.sessionId,
|
|
9
|
+
});
|
|
10
|
+
const send = (message) => {
|
|
11
|
+
const target = options.getPreviewWindow();
|
|
12
|
+
if (!target)
|
|
13
|
+
return;
|
|
14
|
+
postToTarget(target, message, options.previewOrigin);
|
|
15
|
+
};
|
|
16
|
+
const onMessage = (event) => {
|
|
17
|
+
const msg = validateIncomingMessage(event.data, event.origin, {
|
|
18
|
+
sessionId: options.sessionId,
|
|
19
|
+
allowedOrigins: withLocalhostAliases([options.previewOrigin]),
|
|
20
|
+
});
|
|
21
|
+
if (!msg)
|
|
22
|
+
return;
|
|
23
|
+
if (msg.type === "INSPECTOR_READY") {
|
|
24
|
+
handlers.onReady?.(msg.previewUrl);
|
|
25
|
+
}
|
|
26
|
+
if (msg.type === "ELEMENT_HOVERED") {
|
|
27
|
+
handlers.onHover?.(msg.payload);
|
|
28
|
+
}
|
|
29
|
+
if (msg.type === "ELEMENT_SELECTED") {
|
|
30
|
+
handlers.onSelect?.(msg.payload);
|
|
31
|
+
}
|
|
32
|
+
if (msg.type === "ELEMENT_CLEARED") {
|
|
33
|
+
handlers.onCleared?.();
|
|
34
|
+
}
|
|
35
|
+
if (msg.type === "INSPECTOR_ERROR") {
|
|
36
|
+
handlers.onError?.(msg.code, msg.message);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
connect: () => {
|
|
41
|
+
globalThis.window.addEventListener("message", onMessage);
|
|
42
|
+
},
|
|
43
|
+
disconnect: () => {
|
|
44
|
+
globalThis.window.removeEventListener("message", onMessage);
|
|
45
|
+
},
|
|
46
|
+
enableInspect: () => {
|
|
47
|
+
send({ ...base(), type: "INSPECTOR_ENABLE" });
|
|
48
|
+
},
|
|
49
|
+
disableInspect: () => {
|
|
50
|
+
send({ ...base(), type: "INSPECTOR_DISABLE" });
|
|
51
|
+
},
|
|
52
|
+
applyChangeMarkers: (markers) => {
|
|
53
|
+
send({ ...base(), type: "APPLY_CHANGE_MARKERS", markers });
|
|
54
|
+
},
|
|
55
|
+
pingPreview: () => {
|
|
56
|
+
send({ ...base(), type: "INSPECTOR_HOST_HELLO" });
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"origin-aliases.d.ts","sourceRoot":"","sources":["../../src/host/origin-aliases.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,MAAM,EAAE,CAWV"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Accept localhost vs 127.0.0.1 when the Viewer and preview disagree on hostname. */
|
|
2
|
+
export function withLocalhostAliases(origins) {
|
|
3
|
+
const set = new Set(origins);
|
|
4
|
+
for (const origin of origins) {
|
|
5
|
+
if (origin.includes("://localhost")) {
|
|
6
|
+
set.add(origin.replace("://localhost", "://127.0.0.1"));
|
|
7
|
+
}
|
|
8
|
+
if (origin.includes("://127.0.0.1")) {
|
|
9
|
+
set.add(origin.replace("://127.0.0.1", "://localhost"));
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return [...set];
|
|
13
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type InspectorMessage } from "../protocol.js";
|
|
2
|
+
export type ValidateOptions = {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
allowedOrigins: readonly string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function validateIncomingMessage(data: unknown, origin: string, options: ValidateOptions): InspectorMessage | null;
|
|
7
|
+
export declare function postToTarget(target: Window, message: InspectorMessage, targetOrigin: string): void;
|
|
8
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/host/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAsB,MAAM,gBAAgB,CAAC;AAE3E,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,gBAAgB,GAAG,IAAI,CAKzB;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,MAAM,GACnB,IAAI,CAEN"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isInspectorMessage } from "../protocol.js";
|
|
2
|
+
export function validateIncomingMessage(data, origin, options) {
|
|
3
|
+
if (!options.allowedOrigins.includes(origin))
|
|
4
|
+
return null;
|
|
5
|
+
if (!isInspectorMessage(data))
|
|
6
|
+
return null;
|
|
7
|
+
if (data.sessionId !== options.sessionId)
|
|
8
|
+
return null;
|
|
9
|
+
return data;
|
|
10
|
+
}
|
|
11
|
+
export function postToTarget(target, message, targetOrigin) {
|
|
12
|
+
target.postMessage(message, targetOrigin);
|
|
13
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { createInspectorClient } from "./host/client-bridge.js";
|
|
2
|
+
export { createInspectorHost } from "./host/host-bridge.js";
|
|
3
|
+
export { validateIncomingMessage } from "./host/validate.js";
|
|
4
|
+
export { abboxSourceBabelPlugin } from "./instrument/babel-plugin.js";
|
|
5
|
+
export * from "./instrument/constants.js";
|
|
6
|
+
export * from "./ir-match.js";
|
|
7
|
+
export { type WithAbboxInspectorOptions, withAbboxInspector, } from "./next/with-abbox-inspector.js";
|
|
8
|
+
export * from "./protocol.js";
|
|
9
|
+
export { createInspectorRuntime } from "./runtime/inspector.js";
|
|
10
|
+
export { abboxInspectorVitePlugin } from "./vite-plugin.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,KAAK,yBAAyB,EAC9B,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { createInspectorClient } from "./host/client-bridge.js";
|
|
2
|
+
export { createInspectorHost } from "./host/host-bridge.js";
|
|
3
|
+
export { validateIncomingMessage } from "./host/validate.js";
|
|
4
|
+
export { abboxSourceBabelPlugin } from "./instrument/babel-plugin.js";
|
|
5
|
+
export * from "./instrument/constants.js";
|
|
6
|
+
export * from "./ir-match.js";
|
|
7
|
+
export { withAbboxInspector, } from "./next/with-abbox-inspector.js";
|
|
8
|
+
export * from "./protocol.js";
|
|
9
|
+
export { createInspectorRuntime } from "./runtime/inspector.js";
|
|
10
|
+
export { abboxInspectorVitePlugin } from "./vite-plugin.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PluginObj } from "@babel/core";
|
|
2
|
+
export type AbboxSourcePluginOptions = {
|
|
3
|
+
/** Project root used to relativize filenames. */
|
|
4
|
+
rootDir?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function abboxSourceBabelPlugin(_api: unknown, opts?: AbboxSourcePluginOptions): PluginObj;
|
|
7
|
+
export default abboxSourceBabelPlugin;
|
|
8
|
+
//# sourceMappingURL=babel-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"babel-plugin.d.ts","sourceRoot":"","sources":["../../src/instrument/babel-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,MAAM,wBAAwB,GAAG;IACrC,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,IAAI,GAAE,wBAA6B,GAClC,SAAS,CA+BX;AAED,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import * as t from "@babel/types";
|
|
3
|
+
import { ABBBOX_SOURCE_ATTR, formatSourceAttribute } from "./constants.js";
|
|
4
|
+
export function abboxSourceBabelPlugin(_api, opts = {}) {
|
|
5
|
+
const rootDir = opts.rootDir ?? process.cwd();
|
|
6
|
+
return {
|
|
7
|
+
name: "abbox-source-instrumentation",
|
|
8
|
+
visitor: {
|
|
9
|
+
JSXOpeningElement(nodePath, state) {
|
|
10
|
+
const loc = nodePath.node.loc;
|
|
11
|
+
const filename = state.filename;
|
|
12
|
+
if (!loc || !filename)
|
|
13
|
+
return;
|
|
14
|
+
const rel = path.relative(rootDir, filename).replace(/\\/g, "/");
|
|
15
|
+
const value = formatSourceAttribute(rel, loc.start.line, loc.start.column);
|
|
16
|
+
const hasAttr = nodePath.node.attributes.some((attr) => t.isJSXAttribute(attr) &&
|
|
17
|
+
t.isJSXIdentifier(attr.name) &&
|
|
18
|
+
attr.name.name === ABBBOX_SOURCE_ATTR);
|
|
19
|
+
if (hasAttr)
|
|
20
|
+
return;
|
|
21
|
+
nodePath.node.attributes.push(t.jsxAttribute(t.jsxIdentifier(ABBBOX_SOURCE_ATTR), t.stringLiteral(value)));
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export default abboxSourceBabelPlugin;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** DOM attribute written by build-time JSX instrumentation. */
|
|
2
|
+
export declare const ABBBOX_SOURCE_ATTR = "data-abbox-src";
|
|
3
|
+
/** Format: `relative/path.tsx:line:column` */
|
|
4
|
+
export declare function formatSourceAttribute(relativeFile: string, line: number, column: number): string;
|
|
5
|
+
export declare function parseSourceAttribute(raw: string): {
|
|
6
|
+
file: string;
|
|
7
|
+
line: number;
|
|
8
|
+
column: number;
|
|
9
|
+
} | null;
|
|
10
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/instrument/constants.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AAEnD,8CAA8C;AAC9C,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,MAAM,CAGR;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAOP"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** DOM attribute written by build-time JSX instrumentation. */
|
|
2
|
+
export const ABBBOX_SOURCE_ATTR = "data-abbox-src";
|
|
3
|
+
/** Format: `relative/path.tsx:line:column` */
|
|
4
|
+
export function formatSourceAttribute(relativeFile, line, column) {
|
|
5
|
+
const normalized = relativeFile.replace(/\\/g, "/");
|
|
6
|
+
return `${normalized}:${line}:${column}`;
|
|
7
|
+
}
|
|
8
|
+
export function parseSourceAttribute(raw) {
|
|
9
|
+
const match = /^(.+):(\d+):(\d+)$/.exec(raw.trim());
|
|
10
|
+
if (!match)
|
|
11
|
+
return null;
|
|
12
|
+
const line = Number.parseInt(match[2], 10);
|
|
13
|
+
const column = Number.parseInt(match[3], 10);
|
|
14
|
+
if (!Number.isFinite(line) || !Number.isFinite(column))
|
|
15
|
+
return null;
|
|
16
|
+
return { file: match[1], line, column };
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Optional mapping from runtime source locations to Product IR records (viewer-side). */
|
|
2
|
+
export type SourceEvidenceLike = {
|
|
3
|
+
file?: string;
|
|
4
|
+
line?: number;
|
|
5
|
+
column?: number;
|
|
6
|
+
};
|
|
7
|
+
export type IrRecordRef = {
|
|
8
|
+
kind: "section" | "content" | "element" | "interaction" | "form" | "field" | "navigation";
|
|
9
|
+
id: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
route?: string;
|
|
12
|
+
};
|
|
13
|
+
export type IrMatchConfidence = "exact" | "ambiguous" | "fuzzy" | "none";
|
|
14
|
+
export type IrMatchResult = {
|
|
15
|
+
matches: IrRecordRef[];
|
|
16
|
+
confidence: IrMatchConfidence;
|
|
17
|
+
note?: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function normalizeSourcePath(file: string): string;
|
|
20
|
+
export declare function pathsLikelyEqual(a: string, b: string): boolean;
|
|
21
|
+
export declare function matchSourceToIr(source: {
|
|
22
|
+
file: string;
|
|
23
|
+
line: number;
|
|
24
|
+
column?: number;
|
|
25
|
+
} | null, index: {
|
|
26
|
+
byFileLine: Map<string, IrRecordRef[]>;
|
|
27
|
+
}, options?: {
|
|
28
|
+
allowFuzzy?: boolean;
|
|
29
|
+
}): IrMatchResult;
|
|
30
|
+
export declare function buildFileLineIndex(entries: Array<{
|
|
31
|
+
evidence: SourceEvidenceLike;
|
|
32
|
+
ref: IrRecordRef;
|
|
33
|
+
}>): Map<string, IrRecordRef[]>;
|
|
34
|
+
//# sourceMappingURL=ir-match.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir-match.d.ts","sourceRoot":"","sources":["../src/ir-match.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EACA,SAAS,GACT,SAAS,GACT,SAAS,GACT,aAAa,GACb,MAAM,GACN,OAAO,GACP,YAAY,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAEzE,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAU9D;AA8CD,wBAAgB,eAAe,CAC7B,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,EAC9D,KAAK,EAAE;IACL,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;CACxC,EACD,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,aAAa,CAmEf;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,kBAAkB,CAAC;IAAC,GAAG,EAAE,WAAW,CAAA;CAAE,CAAC,GACjE,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAU5B"}
|
package/dist/ir-match.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/** Optional mapping from runtime source locations to Product IR records (viewer-side). */
|
|
2
|
+
export function normalizeSourcePath(file) {
|
|
3
|
+
return file.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
4
|
+
}
|
|
5
|
+
export function pathsLikelyEqual(a, b) {
|
|
6
|
+
const na = normalizeSourcePath(a);
|
|
7
|
+
const nb = normalizeSourcePath(b);
|
|
8
|
+
if (na === nb)
|
|
9
|
+
return true;
|
|
10
|
+
return (na.endsWith(`/${nb}`) ||
|
|
11
|
+
nb.endsWith(`/${na}`) ||
|
|
12
|
+
na.endsWith(nb) ||
|
|
13
|
+
nb.endsWith(na));
|
|
14
|
+
}
|
|
15
|
+
function lineKey(file, line) {
|
|
16
|
+
return `${normalizeSourcePath(file)}:${line}`;
|
|
17
|
+
}
|
|
18
|
+
function collectForLine(source, index) {
|
|
19
|
+
const exact = index.get(lineKey(source.file, source.line)) ?? [];
|
|
20
|
+
if (exact.length > 0)
|
|
21
|
+
return exact;
|
|
22
|
+
const pathMatches = [];
|
|
23
|
+
for (const [key, refs] of index) {
|
|
24
|
+
const colon = key.lastIndexOf(":");
|
|
25
|
+
if (colon <= 0)
|
|
26
|
+
continue;
|
|
27
|
+
const filePart = key.slice(0, colon);
|
|
28
|
+
const linePart = key.slice(colon + 1);
|
|
29
|
+
const lineNum = Number.parseInt(linePart, 10);
|
|
30
|
+
if (!Number.isFinite(lineNum))
|
|
31
|
+
continue;
|
|
32
|
+
if (pathsLikelyEqual(filePart, source.file) && lineNum === source.line) {
|
|
33
|
+
pathMatches.push(...refs);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return pathMatches;
|
|
37
|
+
}
|
|
38
|
+
function uniqueRefs(refs) {
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
const out = [];
|
|
41
|
+
for (const ref of refs) {
|
|
42
|
+
const k = `${ref.kind}:${ref.id}`;
|
|
43
|
+
if (seen.has(k))
|
|
44
|
+
continue;
|
|
45
|
+
seen.add(k);
|
|
46
|
+
out.push(ref);
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
function isAmbiguous(refs) {
|
|
51
|
+
if (refs.length <= 1)
|
|
52
|
+
return false;
|
|
53
|
+
const kinds = new Set(refs.map((r) => r.kind));
|
|
54
|
+
return kinds.size > 1 || refs.length > 3;
|
|
55
|
+
}
|
|
56
|
+
export function matchSourceToIr(source, index, options) {
|
|
57
|
+
const allowFuzzy = options?.allowFuzzy ?? true;
|
|
58
|
+
if (!source) {
|
|
59
|
+
return {
|
|
60
|
+
matches: [],
|
|
61
|
+
confidence: "none",
|
|
62
|
+
note: "No source mapping on this element.",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const exact = uniqueRefs(collectForLine(source, index.byFileLine));
|
|
66
|
+
if (exact.length > 0) {
|
|
67
|
+
if (isAmbiguous(exact)) {
|
|
68
|
+
return {
|
|
69
|
+
matches: exact,
|
|
70
|
+
confidence: "ambiguous",
|
|
71
|
+
note: "Multiple Product IR records share this source location. Review each match.",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
matches: exact,
|
|
76
|
+
confidence: "exact",
|
|
77
|
+
note: "Exact file and line match to compiler evidence.",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (!allowFuzzy) {
|
|
81
|
+
return {
|
|
82
|
+
matches: [],
|
|
83
|
+
confidence: "none",
|
|
84
|
+
note: "No Product IR record at this source location.",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const fuzzy = [];
|
|
88
|
+
for (const [key, refs] of index.byFileLine) {
|
|
89
|
+
const colon = key.lastIndexOf(":");
|
|
90
|
+
if (colon <= 0)
|
|
91
|
+
continue;
|
|
92
|
+
const filePart = key.slice(0, colon);
|
|
93
|
+
const linePart = key.slice(colon + 1);
|
|
94
|
+
const lineNum = Number.parseInt(linePart, 10);
|
|
95
|
+
if (!Number.isFinite(lineNum))
|
|
96
|
+
continue;
|
|
97
|
+
if (pathsLikelyEqual(filePart, source.file) &&
|
|
98
|
+
Math.abs(lineNum - source.line) <= 2) {
|
|
99
|
+
fuzzy.push(...refs);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const fuzzyUnique = uniqueRefs(fuzzy);
|
|
103
|
+
if (fuzzyUnique.length > 0) {
|
|
104
|
+
return {
|
|
105
|
+
matches: fuzzyUnique.slice(0, 12),
|
|
106
|
+
confidence: fuzzyUnique.length > 1 || isAmbiguous(fuzzyUnique)
|
|
107
|
+
? "ambiguous"
|
|
108
|
+
: "fuzzy",
|
|
109
|
+
note: "Nearby line match (±2 lines). Treat as tentative — confirm against source.",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
matches: [],
|
|
114
|
+
confidence: "none",
|
|
115
|
+
note: "No Product IR record at this source location.",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function buildFileLineIndex(entries) {
|
|
119
|
+
const map = new Map();
|
|
120
|
+
for (const { evidence, ref } of entries) {
|
|
121
|
+
if (!evidence.file || evidence.line === undefined)
|
|
122
|
+
continue;
|
|
123
|
+
const key = lineKey(evidence.file, evidence.line);
|
|
124
|
+
const list = map.get(key) ?? [];
|
|
125
|
+
list.push(ref);
|
|
126
|
+
map.set(key, list);
|
|
127
|
+
}
|
|
128
|
+
return map;
|
|
129
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommonJS babel config fragment for Next.js apps.
|
|
3
|
+
* Copy or require from babel.config.cjs when ABBBOX_INSPECTOR=1.
|
|
4
|
+
*/
|
|
5
|
+
const { createRequire } = require("node:module");
|
|
6
|
+
const path = require("node:path");
|
|
7
|
+
|
|
8
|
+
function createNextBabelConfig(options = {}) {
|
|
9
|
+
const rootDir = options.rootDir ?? process.cwd();
|
|
10
|
+
const enabled =
|
|
11
|
+
options.enabled ??
|
|
12
|
+
(process.env.ABBBOX_INSPECTOR === "1" ||
|
|
13
|
+
process.env.NEXT_PUBLIC_ABBOX_INSPECTOR === "1" ||
|
|
14
|
+
process.env.VERCEL_ENV === "preview");
|
|
15
|
+
|
|
16
|
+
const req = createRequire(path.join(rootDir, "package.json"));
|
|
17
|
+
let pluginPath = "@abbox/inspector/babel";
|
|
18
|
+
try {
|
|
19
|
+
pluginPath = req.resolve("@abbox/inspector/babel");
|
|
20
|
+
} catch {
|
|
21
|
+
try {
|
|
22
|
+
pluginPath = req.resolve("abbox-inspector/babel");
|
|
23
|
+
} catch {
|
|
24
|
+
pluginPath = req.resolve(
|
|
25
|
+
path.join(
|
|
26
|
+
rootDir,
|
|
27
|
+
"node_modules/@abbox/inspector/dist/instrument/babel-plugin.js",
|
|
28
|
+
),
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
presets: ["next/babel"],
|
|
35
|
+
plugins: enabled ? [[pluginPath, { rootDir }]] : [],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = { createNextBabelConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,yBAAyB,EAC9B,kBAAkB,EAClB,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,kBAAkB,CAAC"}
|