[GH-ISSUE #2662] fix(javascript): preserve asterisks in supported block source-map declarations #961

Closed
opened 2026-10-15 18:29:56 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 13, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2662

Summary

JavaScript application analysis recognizes block-form source-map annotations but cuts their declared URL at an internal asterisk. A comment declaring app*part.js.map produces app, and a declaration beginning with * disappears. The returned declaration and its source range no longer describe the original artifact. The local URL resolver can resolve the complete name to an inventoried map but cannot resolve the truncated value.

Steps to reproduce

Use a checkout at the source baseline under Runtime or environment with its pinned dependencies available. This reproduction exercises the source parser used by the public analyze-javascript-application workflow. It does not execute the analyzed JavaScript.

Create src/domain/javascript/blockSourceMapDeclaration.test.ts containing this diagnostic test:

import { expect, it } from "vitest";
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";

it("prints source-map declarations from owned comment fixtures", () => {
  for (const source of [
    "/*# sourceMappingURL=app*part.js.map */",
    "/*# sourceMappingURL=*part.js.map */",
    "//# sourceMappingURL=app*part.js.map",
    "/*# sourceMappingURL=app.js.map*/",
  ]) {
    const result = analyzeJavaScriptStaticSource(source);
    expect(result.parse_status).toBe("complete");
    console.log(JSON.stringify({ source, source_map_urls: result.source_map_urls }));
  }
});

Run the focused source test:

npm run test:focused -- src/domain/javascript/blockSourceMapDeclaration.test.ts

Inspect declared_url and location.end in the printed observations. The first comment loses everything after app; the second records no declaration. The line-comment and ordinary block-comment fixtures preserve their URLs. Remove the diagnostic test after inspection.

The verifier ran these inputs in a bounded focused source test, including legacy block annotations and a comment after a small export statement. It also directly ran local URL resolution against an owned in-memory map file. A full CLI invocation and final graph serialization were not run; their connection to these source results was checked by tracing the production call path.

Expected behavior

For the already-supported block annotation /*# sourceMappingURL=app*part.js.map */, retain app*part.js.map as the original declared URL. Its range starts at the comment marker and ends immediately after the URL at one-based line 1, zero-based column 36. An internal asterisk does not close a JavaScript block comment. A leading asterisk in *part.js.map should likewise remain part of the declaration. Preserve the complete declaration when deriving its digest and resolving the corresponding local map.

Actual behavior

Every executed fixture parsed completely. The focused source test produced these observations:

{"source":"/*# sourceMappingURL=app*part.js.map */","source_map_urls":[{"declared_url":"app","location":{"start":{"line":1,"column":0},"end":{"line":1,"column":24}}}]}
{"source":"/*# sourceMappingURL=*part.js.map */","source_map_urls":[]}
{"source":"//# sourceMappingURL=app*part.js.map","source_map_urls":[{"declared_url":"app*part.js.map","location":{"start":{"line":1,"column":0},"end":{"line":1,"column":36}}}]}
{"source":"/*# sourceMappingURL=app.js.map*/","source_map_urls":[{"declared_url":"app.js.map","location":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}}}]}

The legacy /*@ form and a block comment on the line after export const value = 1; also recorded app. Ordinary block URLs worked with and without whitespace before the closing delimiter.

With an in-memory inventory containing app*part.js.map, direct execution of resolveArtifactPathByContext in url-reference context returned resolved_path: "app*part.js.map" and resolution_status: "resolved" for the full declaration. The value extracted from the block comment returned resolved_path: null and resolution_status: "not-found". Production graph projection hashes and stores that extracted value and uses the same resolver. The resulting unavailable reference is a source-traced consequence rather than an observed full CLI result.

Runtime or environment

Source checkout at commit a2d8b94dd50dab8d966239dd63ab84718aa8b4b4, tested with Node.js 24.18.0 and npm 11.16.0. The published package was not tested.

Current upstream 3ae826ceba6f25b08bce50bcb51001209bc16b57 was rechecked from source: the directive parser, exact URL lookup, and declaration projection remain unchanged, so the verified block-comment failure is still present. No new runtime test or full CLI invocation was run for this recheck.

Evidence

  • Expected source: docs/javascript-application-graph.md:76-86 promises the exact declared URL and preservation of the original URL in reference observations. src/domain/javascript/javascriptStaticAnalysisSourceMaps.test.ts:10-23 confirms that block annotations are an existing supported form; src/domain/javascript/javascriptStaticAnalysisCalls.ts:420-421 explicitly includes current and legacy block annotations.
  • Failure source: Focused execution of analyzeJavaScriptStaticSource produced the observations above. src/domain/javascript/javascriptStaticAnalysisCalls.ts:451-457 ends a block URL at any asterisk; src/application/javascript/JavaScriptArtifactPathResolution.ts:149-167 performs exact URL resource lookup. src/application/javascript/JavaScriptArtifactGraphFindings.ts:303-369 hashes, resolves, and stores the extracted declaration without recovering omitted text.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

The existing Unicode whitespace test in src/domain/javascript/javascriptStaticAnalysisSourceMaps.test.ts:72-88 expects an asterisk to terminate a value even without the following slash. That expectation needs reconciliation with the original-declaration contract for supported block comments. This report relies on REA's supported block form, rather than asserting that JavaScript source-map standards require block annotations.

Related issue #1781 reports the line-comment variant and explicitly excludes block-comment behavior. Its closing source change preserves line-comment asterisks while retaining the block-comment branch reproduced here.

Restoration check

The first fixture must record app*part.js.map with an endpoint at line 1, column 36. The leading-asterisk fixture must record *part.js.map. Modern, legacy, and code-preceded block forms must retain the same complete declaration. In the public application result, an inventoried map with that exact name must receive the available reference and corresponding maps_to relationship. Check that the declaration digest matches the preserved URL. Keep the passing line-comment control and ordinary block URLs, including the form without whitespace before */.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: A bounded class of supported declarations loses URL text and source-range accuracy. Direct lookup confirms that the extracted value cannot identify the available map, affecting declaration evidence and source-map linkage. No application-wide failure was observed.
  • Workaround status: unverified
  • Workaround basis: The line-comment control works, but rewriting the input changes the original artifact. No workaround preserving both the original artifact and exact declaration evidence was verified.
Originally created by @coygeek on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2662 ## Summary JavaScript application analysis recognizes block-form source-map annotations but cuts their declared URL at an internal asterisk. A comment declaring `app*part.js.map` produces `app`, and a declaration beginning with `*` disappears. The returned declaration and its source range no longer describe the original artifact. The local URL resolver can resolve the complete name to an inventoried map but cannot resolve the truncated value. ## Steps to reproduce Use a checkout at the source baseline under Runtime or environment with its pinned dependencies available. This reproduction exercises the source parser used by the public `analyze-javascript-application` workflow. It does not execute the analyzed JavaScript. Create `src/domain/javascript/blockSourceMapDeclaration.test.ts` containing this diagnostic test: ```ts import { expect, it } from "vitest"; import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js"; it("prints source-map declarations from owned comment fixtures", () => { for (const source of [ "/*# sourceMappingURL=app*part.js.map */", "/*# sourceMappingURL=*part.js.map */", "//# sourceMappingURL=app*part.js.map", "/*# sourceMappingURL=app.js.map*/", ]) { const result = analyzeJavaScriptStaticSource(source); expect(result.parse_status).toBe("complete"); console.log(JSON.stringify({ source, source_map_urls: result.source_map_urls })); } }); ``` Run the focused source test: ```sh npm run test:focused -- src/domain/javascript/blockSourceMapDeclaration.test.ts ``` Inspect `declared_url` and `location.end` in the printed observations. The first comment loses everything after `app`; the second records no declaration. The line-comment and ordinary block-comment fixtures preserve their URLs. Remove the diagnostic test after inspection. The verifier ran these inputs in a bounded focused source test, including legacy block annotations and a comment after a small export statement. It also directly ran local URL resolution against an owned in-memory map file. A full CLI invocation and final graph serialization were not run; their connection to these source results was checked by tracing the production call path. ## Expected behavior For the already-supported block annotation `/*# sourceMappingURL=app*part.js.map */`, retain `app*part.js.map` as the original declared URL. Its range starts at the comment marker and ends immediately after the URL at one-based line 1, zero-based column 36. An internal asterisk does not close a JavaScript block comment. A leading asterisk in `*part.js.map` should likewise remain part of the declaration. Preserve the complete declaration when deriving its digest and resolving the corresponding local map. ## Actual behavior Every executed fixture parsed completely. The focused source test produced these observations: ```json {"source":"/*# sourceMappingURL=app*part.js.map */","source_map_urls":[{"declared_url":"app","location":{"start":{"line":1,"column":0},"end":{"line":1,"column":24}}}]} {"source":"/*# sourceMappingURL=*part.js.map */","source_map_urls":[]} {"source":"//# sourceMappingURL=app*part.js.map","source_map_urls":[{"declared_url":"app*part.js.map","location":{"start":{"line":1,"column":0},"end":{"line":1,"column":36}}}]} {"source":"/*# sourceMappingURL=app.js.map*/","source_map_urls":[{"declared_url":"app.js.map","location":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}}}]} ``` The legacy `/*@` form and a block comment on the line after `export const value = 1;` also recorded `app`. Ordinary block URLs worked with and without whitespace before the closing delimiter. With an in-memory inventory containing `app*part.js.map`, direct execution of `resolveArtifactPathByContext` in `url-reference` context returned `resolved_path: "app*part.js.map"` and `resolution_status: "resolved"` for the full declaration. The value extracted from the block comment returned `resolved_path: null` and `resolution_status: "not-found"`. Production graph projection hashes and stores that extracted value and uses the same resolver. The resulting unavailable reference is a source-traced consequence rather than an observed full CLI result. ## Runtime or environment Source checkout at commit `a2d8b94dd50dab8d966239dd63ab84718aa8b4b4`, tested with Node.js 24.18.0 and npm 11.16.0. The published package was not tested. Current upstream `3ae826ceba6f25b08bce50bcb51001209bc16b57` was rechecked from source: the directive parser, exact URL lookup, and declaration projection remain unchanged, so the verified block-comment failure is still present. No new runtime test or full CLI invocation was run for this recheck. ## Evidence - Expected source: `docs/javascript-application-graph.md:76-86` promises the exact declared URL and preservation of the original URL in reference observations. `src/domain/javascript/javascriptStaticAnalysisSourceMaps.test.ts:10-23` confirms that block annotations are an existing supported form; `src/domain/javascript/javascriptStaticAnalysisCalls.ts:420-421` explicitly includes current and legacy block annotations. - Failure source: Focused execution of `analyzeJavaScriptStaticSource` produced the observations above. `src/domain/javascript/javascriptStaticAnalysisCalls.ts:451-457` ends a block URL at any asterisk; `src/application/javascript/JavaScriptArtifactPathResolution.ts:149-167` performs exact URL resource lookup. `src/application/javascript/JavaScriptArtifactGraphFindings.ts:303-369` hashes, resolves, and stores the extracted declaration without recovering omitted text. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete The existing Unicode whitespace test in `src/domain/javascript/javascriptStaticAnalysisSourceMaps.test.ts:72-88` expects an asterisk to terminate a value even without the following slash. That expectation needs reconciliation with the original-declaration contract for supported block comments. This report relies on REA's supported block form, rather than asserting that JavaScript source-map standards require block annotations. Related [issue #1781](https://github.com/morluto/rea/issues/1781) reports the line-comment variant and explicitly excludes block-comment behavior. Its closing source change preserves line-comment asterisks while retaining the block-comment branch reproduced here. ## Restoration check The first fixture must record `app*part.js.map` with an endpoint at line 1, column 36. The leading-asterisk fixture must record `*part.js.map`. Modern, legacy, and code-preceded block forms must retain the same complete declaration. In the public application result, an inventoried map with that exact name must receive the available reference and corresponding `maps_to` relationship. Check that the declaration digest matches the preserved URL. Keep the passing line-comment control and ordinary block URLs, including the form without whitespace before `*/`. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: A bounded class of supported declarations loses URL text and source-range accuracy. Direct lookup confirms that the extracted value cannot identify the available map, affecting declaration evidence and source-map linkage. No application-wide failure was observed. - Workaround status: unverified - Workaround basis: The line-comment control works, but rewriting the input changes the original artifact. No workaround preserving both the original artifact and exact declaration evidence was verified.
bsakaguchi 2026-10-15 18:29:56 +00:00
  • closed this issue
  • added the
    bug
    label
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#961
No description provided.