fix(javascript): attribute service workers to intact platform paths

Check the complete navigator.serviceWorker.register identity through the shared
ambient-write owner, including replaced methods and aliased receiver mutations.
Reuse the module URL reader for intact registrations while preserving unknown
document-relative strings. Cover the unresolved review case and the CLI graph.

Refs #3841

Co-authored-by: Chandan Chaudhary <chandankkumar156@gmail.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
This commit is contained in:
committed 2026-10-16 06:06:06 +08:00
1 parent 880b3a510b
commit 396b89c5e2
4 files changed
+157 -19

No files matched your search

@@ -102,17 +102,22 @@ export const inspectCall = (
specifier:
workerConstructor === undefined || worker === undefined
? undefined
: workerUrlSpecifier(worker, bindings),
: moduleUrlSpecifier(worker, bindings),
});
// Service worker script URLs are also relative to the document base URL.
// Service worker strings also use the document base URL. The complete called
// path must retain its platform identity, including the register method.
if (
name === "serviceWorker.register" ||
name.endsWith(".serviceWorker.register")
!t.isNewExpression(node) &&
isUnmodifiedGlobalReference(node.callee, bindings, [
"navigator",
"serviceWorker",
"register",
])
)
addReference(context, {
node,
kind: "service-worker",
specifier: undefined,
specifier: moduleUrlSpecifier(node, bindings),
});
inspectEndpointCall(node, name, first, context);
inspectStorageCall(node, name, first, context);
@@ -151,11 +156,11 @@ export const inspectCall = (
});
};
const workerUrlSpecifier = (
worker: t.NewExpression,
const moduleUrlSpecifier = (
call: JavaScriptCallLike,
bindings: JavaScriptSemanticAnalysisState,
): string | undefined => {
const argumentExpression = argumentNode(worker.arguments[0]);
const argumentExpression = argumentNode(call.arguments[0]);
if (argumentExpression === undefined) return undefined;
const node = unwrapJavaScriptExpression(argumentExpression).node;
if (!t.isNewExpression(node)) return undefined;