mirror of
https://github.com/morluto/rea.git
synced 2026-10-12 02:19:24 +00:00
* feat(web): export captured scripts for JavaScript application analysis Add capture adapters, conservative source path projection, verified exclusive publication and a shared CLI/MCP workflow. Retain source identities, missing content and competing URL versions in a complete manifest for existing static analysis. Refs: #774 Closes: #799 Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis) Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing) * test(web): include script export in independent effect audit Register the new contract family in the independent inventory audit and verify the filesystem, session, network and idempotence metadata of the named export contract. Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis) Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing) * fix(web): preserve capture limitation values in export manifests Align the export boundary with passive capture’s string contract instead of rejecting an admitted empty limitation. Cover the publisher boundary and regenerate canonical schemas and identities. Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis) Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
71 lines
2.6 KiB
JavaScript
71 lines
2.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { createHash } from "node:crypto";
|
|
import { readFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { webScriptExportResultSchema } from "../../dist/domain/webScriptExport.js";
|
|
import { javascriptApplicationAnalysisResultSchema } from "../../dist/domain/javascriptApplicationAnalysis.js";
|
|
|
|
/** Verify exact exported bytes and the independently authored source manifest. */
|
|
export const assertWebScriptExport = async (evidence, capture, assets) => {
|
|
const result = webScriptExportResultSchema.parse(evidence.normalized_result);
|
|
assert.equal(result.source_evidence_id, capture.evidence_id);
|
|
assert.deepEqual(evidence.evidence_links, [capture.evidence_id]);
|
|
const manifest = await readFile(result.manifest.path);
|
|
assert.equal(
|
|
createHash("sha256").update(manifest).digest("hex"),
|
|
result.manifest.sha256,
|
|
);
|
|
const { manifest: descriptor, ...inline } = result;
|
|
assert.equal(descriptor.bytes, manifest.length);
|
|
assert.deepEqual(JSON.parse(manifest.toString()), inline);
|
|
assert.ok(result.analysis_input);
|
|
assert.ok(result.scripts.length > 0);
|
|
for (const script of result.scripts) {
|
|
assert.equal(script.content.state, "exported");
|
|
const bytes = await readFile(
|
|
join(result.analysis_input.input_path, script.content.relative_path),
|
|
);
|
|
assert.equal(
|
|
createHash("sha256").update(bytes).digest("hex"),
|
|
script.content.sha256,
|
|
);
|
|
if (assets) {
|
|
const url = new URL(script.url);
|
|
assert.equal(
|
|
bytes.toString(),
|
|
assets.get(`${url.pathname}${url.search}`),
|
|
`Wrong bytes for ${script.url}`,
|
|
);
|
|
}
|
|
}
|
|
if (assets) {
|
|
assert.equal(result.scripts.length, assets.size);
|
|
const variants = result.scripts.filter(({ url }) =>
|
|
url.includes("/variant.js?"),
|
|
);
|
|
assert.equal(variants.length, 2);
|
|
assert.ok(variants.every(({ content }) => content.layout === "isolated"));
|
|
assert.equal(
|
|
new Set(variants.map(({ content }) => content.relative_path)).size,
|
|
2,
|
|
);
|
|
}
|
|
return result;
|
|
};
|
|
/** Verify existing application analysis and an observed relative module layout. */
|
|
export const assertExportedScriptAnalysis = (evidence, modules, imports) => {
|
|
const result = javascriptApplicationAnalysisResultSchema.parse(
|
|
evidence.normalized_result,
|
|
);
|
|
assert.equal(result.statistics.parsed_javascript_files, modules);
|
|
if (imports)
|
|
assert.ok(
|
|
result.graph.edges.some(
|
|
({ relation, properties }) =>
|
|
relation === "imports" &&
|
|
properties.specifier === "./lib/dep.js" &&
|
|
properties.resolution_status === "resolved",
|
|
),
|
|
);
|
|
};
|