mirror of
https://github.com/morluto/rea.git
synced 2026-10-12 02:19:24 +00:00
refactor(artifacts): move inventory and extraction into provider owners (#1032)
This commit is contained in:
@@ -30,7 +30,7 @@ graph TD
|
||||
GHIDRA["src/ghidra/<br/>Ghidra discovery, profile & function analysis<br/>snapshot, Unix/Windows transport, bounded lifecycle"]
|
||||
IDA["src/ida/<br/>Upstream MCP contract adaptation<br/>live GUI binding or owned headless database"]
|
||||
IDA_MCP["External ida-pro-mcp<br/>GUI proxy or database supervisor<br/>upstream installation and engine lifecycle"]
|
||||
AUX["src/artifacts/ + src/native/<br/>disjoint artifact and native capabilities"]
|
||||
AUX["src/artifacts/ + src/native/<br/>artifact inventory and extraction<br/>format readers and native capabilities"]
|
||||
BROWSER["src/browser/<br/>CDP / Playwright capture<br/>captured scripts and native module resolution<br/>execution/: coverage, listener and source attribution"]
|
||||
JS_CODEC["src/javascript/sourceMaps/<br/>pinned upstream map codec<br/>owned heap-limited Node process, complete point evidence"]
|
||||
INSPECTOR["src/inspector/<br/>passive V8 Inspector discovery and capture<br/>script and target locations"]
|
||||
|
||||
@@ -385,6 +385,30 @@ claims. Actual Swift/Xcode, assetutil, native NIB, bundle signing and DMG lifecy
|
||||
claims require the real Apple lane. Native binary API/value-flow semantics and
|
||||
shared cross-domain contract aggregates keep their separate owners.
|
||||
|
||||
## Artifact inventory and extraction ownership
|
||||
|
||||
`src/artifacts/inventory/` owns format classification, reader selection, inventory
|
||||
policy, canonical scanning and artifact graph construction. The shared artifact
|
||||
provider and JavaScript reconstruction workflow consume this owner. Snapshot
|
||||
semantics remain in `src/domain/artifactInventorySnapshot.ts`.
|
||||
|
||||
`src/artifacts/extraction/` owns member selection, integrity checks and transactional
|
||||
materialization through the existing readers and safe output tree. Reader cleanup,
|
||||
cancellation, rollback, archive containment and caller-visible results retain their
|
||||
existing behavior. Acquisition guards reject imports from these producer owners
|
||||
into application workflows, production composition or CLI/MCP adapters.
|
||||
|
||||
`src/application/artifacts/ArtifactExtractionDestination.ts` owns the caller's
|
||||
default temporary output-root choice for both CLI and MCP. The adapters pass this
|
||||
destination to the existing provider operation; format handling and member writes
|
||||
remain in the artifact owner.
|
||||
|
||||
Add format-specific acquisition behavior beside the inventory readers and exercise
|
||||
its actual producer representation in filesystem boundary tests. Add caller
|
||||
workflow behavior in the application owner and verify both adapters. The installed
|
||||
package lane checks inventory identity and extraction through CLI and MCP; the
|
||||
real Apple bundle lane separately establishes DMG mount and detach behavior.
|
||||
|
||||
## Binary production composition closure
|
||||
|
||||
`src/composition/binary.ts` is the shared production owner for deep candidate
|
||||
|
||||
@@ -78,6 +78,8 @@ const failedBoundary = (file, target) => {
|
||||
if (
|
||||
(file.startsWith("src/artifacts/javascript/") ||
|
||||
file.startsWith("src/artifacts/apple/") ||
|
||||
file.startsWith("src/artifacts/inventory/") ||
|
||||
file.startsWith("src/artifacts/extraction/") ||
|
||||
/^src\/artifacts\/ArtifactHash\.(?:js|ts)$/u.test(file)) &&
|
||||
(["application", "composition", "server", "cli", "main"].includes(
|
||||
targetLayer,
|
||||
|
||||
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
|
||||
import { join } from "node:path";
|
||||
import { execFile } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import { readFile, rm } from "node:fs/promises";
|
||||
|
||||
import { Client } from "@modelcontextprotocol/client";
|
||||
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
||||
@@ -167,6 +168,7 @@ const verifyMcpInlineArtifactEvidence = async (
|
||||
mcpOptions,
|
||||
);
|
||||
assert.notEqual(opened.isError, true, JSON.stringify(opened));
|
||||
let outputRoot;
|
||||
try {
|
||||
const inspected = await client.callTool(
|
||||
{ name: "inspect_artifact", arguments: {} },
|
||||
@@ -212,12 +214,35 @@ const verifyMcpInlineArtifactEvidence = async (
|
||||
evidence,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
const closed = await client.callTool(
|
||||
{ name: "close_binary", arguments: {} },
|
||||
const extracted = await client.callTool(
|
||||
{ name: "extract_artifact", arguments: {} },
|
||||
mcpOptions,
|
||||
);
|
||||
assert.notEqual(closed.isError, true, JSON.stringify(closed));
|
||||
assert.notEqual(extracted.isError, true, JSON.stringify(extracted));
|
||||
const extraction = parseEvidence(extracted.structuredContent?.evidence);
|
||||
assert.deepEqual(
|
||||
extraction.normalized_result,
|
||||
extracted.structuredContent?.result,
|
||||
);
|
||||
const materialized = extracted.structuredContent?.result;
|
||||
assert.equal(typeof materialized?.output_root, "string");
|
||||
outputRoot = materialized.output_root;
|
||||
assert.equal(materialized.containment_verified, true);
|
||||
assert.equal(
|
||||
await readFile(join(outputRoot, "app/main.js"), "utf8"),
|
||||
"main();",
|
||||
);
|
||||
} finally {
|
||||
try {
|
||||
const closed = await client.callTool(
|
||||
{ name: "close_binary", arguments: {} },
|
||||
mcpOptions,
|
||||
);
|
||||
assert.notEqual(closed.isError, true, JSON.stringify(closed));
|
||||
} finally {
|
||||
if (outputRoot !== undefined)
|
||||
await rm(outputRoot, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
|
||||
import type { ArtifactInventorySnapshot } from "../../artifacts/inventory/ArtifactInventory.js";
|
||||
import {
|
||||
createJavaScriptApplicationGraph,
|
||||
type JavaScriptApplicationGraph,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
|
||||
import type { ArtifactInventorySnapshot } from "../../artifacts/inventory/ArtifactInventory.js";
|
||||
import {
|
||||
completeApplicationCoverage,
|
||||
partialApplicationCoverage,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
|
||||
import type { ArtifactInventorySnapshot } from "../../artifacts/inventory/ArtifactInventory.js";
|
||||
import type { ApplicationNode } from "../../domain/javascript/javascriptApplicationGraph.js";
|
||||
import { completeApplicationCoverage } from "../../domain/javascript/javascriptApplicationEvidenceSchemas.js";
|
||||
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
javascriptArtifactReconstructionInputSchema,
|
||||
type JavaScriptArtifactReconstructionInput,
|
||||
} from "./JavaScriptArtifactReconstructionInput.js";
|
||||
import { scanCanonicalArtifactInventory } from "../ArtifactInventory.js";
|
||||
import { scanCanonicalArtifactInventory } from "../../artifacts/inventory/ArtifactInventory.js";
|
||||
import { summarizeElectronBoundaries } from "./ElectronBoundaryAnalysis.js";
|
||||
import { buildJavaScriptSemanticGraph } from "./JavaScriptSemanticGraphBuilder.js";
|
||||
import type { ProgressReporter } from "../ProgressReporter.js";
|
||||
|
||||
@@ -9,8 +9,8 @@ import {
|
||||
} from "../application/AnalysisProvider.js";
|
||||
import { inspectBundleKeyedArchive } from "./apple/KeyedArchiveReader.js";
|
||||
import { basename, dirname } from "node:path";
|
||||
import { inventoryArtifact } from "../application/ArtifactInventory.js";
|
||||
import { extractArtifact } from "../application/ArtifactExtraction.js";
|
||||
import { inventoryArtifact } from "./inventory/ArtifactInventory.js";
|
||||
import { extractArtifact } from "./extraction/ArtifactExtraction.js";
|
||||
import { analyzeInterfaceBuilderBundle } from "./apple/InterfaceBuilderAnalysis.js";
|
||||
import { analyzeAppleAssetCatalogs } from "./apple/AppleAssetCatalogAnalysis.js";
|
||||
import {
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
} from "./ArtifactProviderMetadata.js";
|
||||
import { createEvidence } from "../domain/evidence.js";
|
||||
import { createArtifactInspection } from "../domain/artifactInspection.js";
|
||||
import { resolveArtifactIntegrityPolicy } from "../application/ArtifactInventory/policy.js";
|
||||
import { resolveArtifactIntegrityPolicy } from "./inventory/policy.js";
|
||||
|
||||
/** Read-only inventory and exclusively owned extraction provider. */
|
||||
export class ArtifactProvider implements AnalysisProvider {
|
||||
|
||||
+11
-11
@@ -1,29 +1,29 @@
|
||||
import { lstat, realpath } from "node:fs/promises";
|
||||
|
||||
import { canonicalDigest } from "../domain/comparisonSemantics.js";
|
||||
import { AsarArtifactReader } from "../artifacts/AsarArtifactReader.js";
|
||||
import { canonicalDigest } from "../../domain/comparisonSemantics.js";
|
||||
import { AsarArtifactReader } from "../AsarArtifactReader.js";
|
||||
import {
|
||||
ArtifactPathRegistry,
|
||||
normalizeArtifactPath,
|
||||
} from "../artifacts/ArtifactPaths.js";
|
||||
} from "../ArtifactPaths.js";
|
||||
import {
|
||||
ArtifactReaderFailure,
|
||||
type ArtifactEntry,
|
||||
type ArtifactReader,
|
||||
} from "../artifacts/ArtifactReader.js";
|
||||
import { DirectoryArtifactReader } from "../artifacts/DirectoryArtifactReader.js";
|
||||
import { SafeOutputTree } from "../artifacts/SafeOutputTree.js";
|
||||
import { ZipArtifactReader } from "../artifacts/ZipArtifactReader.js";
|
||||
import { MachOSliceArtifactReader } from "../artifacts/MachOSliceArtifactReader.js";
|
||||
} from "../ArtifactReader.js";
|
||||
import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js";
|
||||
import { SafeOutputTree } from "../SafeOutputTree.js";
|
||||
import { ZipArtifactReader } from "../ZipArtifactReader.js";
|
||||
import { MachOSliceArtifactReader } from "../MachOSliceArtifactReader.js";
|
||||
import {
|
||||
artifactExtractionResultSchema,
|
||||
type ArtifactExtractionResult,
|
||||
type ArtifactGraphManifest,
|
||||
type ArtifactNode,
|
||||
type ArtifactOccurrence,
|
||||
} from "../domain/artifactGraph.js";
|
||||
import type { BinaryTarget } from "../domain/binaryTarget.js";
|
||||
import { scanArtifactInventory } from "./ArtifactInventory.js";
|
||||
} from "../../domain/artifactGraph.js";
|
||||
import type { BinaryTarget } from "../../domain/binaryTarget.js";
|
||||
import { scanArtifactInventory } from "../inventory/ArtifactInventory.js";
|
||||
|
||||
/** Local extraction input with the output root chosen by the adapter. */
|
||||
export interface ArtifactExtractionInput {
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
import { canonicalDigest } from "../domain/comparisonSemantics.js";
|
||||
import type { ArtifactEntry } from "../artifacts/ArtifactReader.js";
|
||||
import { canonicalDigest } from "../../domain/comparisonSemantics.js";
|
||||
import type { ArtifactEntry } from "../ArtifactReader.js";
|
||||
import type {
|
||||
ArtifactCommand,
|
||||
ArtifactEdge,
|
||||
ArtifactNode,
|
||||
ArtifactOccurrence,
|
||||
} from "../domain/artifactGraph.js";
|
||||
import { zipPackageFormatForPath } from "../domain/zipPackageFormat.js";
|
||||
import { mzWindowsHeaderOffset, parseDosMzHeader } from "../domain/dosMz.js";
|
||||
} from "../../domain/artifactGraph.js";
|
||||
import { zipPackageFormatForPath } from "../../domain/zipPackageFormat.js";
|
||||
import { mzWindowsHeaderOffset, parseDosMzHeader } from "../../domain/dosMz.js";
|
||||
|
||||
/** Mutable internal occurrence used until root-bound IDs are known. */
|
||||
export interface MutableOccurrence {
|
||||
@@ -3,22 +3,22 @@ import { realpath } from "node:fs/promises";
|
||||
import {
|
||||
artifactInventoryResultSchema,
|
||||
type ArtifactInventoryResult,
|
||||
} from "../domain/artifactGraph.js";
|
||||
import { abortIfNeeded } from "../artifacts/ArtifactHash.js";
|
||||
import { scanCanonicalArtifactInventory } from "./ArtifactInventory/scanCanonical.js";
|
||||
} from "../../domain/artifactGraph.js";
|
||||
import { abortIfNeeded } from "../ArtifactHash.js";
|
||||
import { scanCanonicalArtifactInventory } from "./scanCanonical.js";
|
||||
import type {
|
||||
ArtifactIntegrityPolicy,
|
||||
ArtifactInventoryOptions,
|
||||
ArtifactInventorySnapshot,
|
||||
} from "./ArtifactInventory/types.js";
|
||||
} from "./types.js";
|
||||
|
||||
export { scanCanonicalArtifactInventory } from "./ArtifactInventory/scanCanonical.js";
|
||||
export { scanCanonicalArtifactInventory } from "./scanCanonical.js";
|
||||
|
||||
export type {
|
||||
ArtifactIntegrityPolicy,
|
||||
ArtifactInventoryOptions,
|
||||
ArtifactInventorySnapshot,
|
||||
} from "./ArtifactInventory/types.js";
|
||||
} from "./types.js";
|
||||
|
||||
/** Inventory one local artifact and return every graph collection inline. */
|
||||
export const inventoryArtifact = async (
|
||||
@@ -1,7 +1,7 @@
|
||||
import { open } from "node:fs/promises";
|
||||
|
||||
import { classifyArtifactContent } from "../ArtifactGraphConstruction.js";
|
||||
import { ARTIFACT_CLASSIFICATION_PREFIX_BYTES } from "../../artifacts/ArtifactHash.js";
|
||||
import { classifyArtifactContent } from "./ArtifactGraphConstruction.js";
|
||||
import { ARTIFACT_CLASSIFICATION_PREFIX_BYTES } from "../ArtifactHash.js";
|
||||
import type { ArtifactNode } from "../../domain/artifactGraph.js";
|
||||
import {
|
||||
hasZipSignature,
|
||||
@@ -1,9 +1,9 @@
|
||||
import { AsarArtifactReader } from "../../artifacts/AsarArtifactReader.js";
|
||||
import type { ArtifactReader } from "../../artifacts/ArtifactReader.js";
|
||||
import { DirectoryArtifactReader } from "../../artifacts/DirectoryArtifactReader.js";
|
||||
import { MachOSliceArtifactReader } from "../../artifacts/MachOSliceArtifactReader.js";
|
||||
import { NativeDmgArtifactReader } from "../../artifacts/NativeDmgArtifactReader.js";
|
||||
import { ZipArtifactReader } from "../../artifacts/ZipArtifactReader.js";
|
||||
import { AsarArtifactReader } from "../AsarArtifactReader.js";
|
||||
import type { ArtifactReader } from "../ArtifactReader.js";
|
||||
import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js";
|
||||
import { MachOSliceArtifactReader } from "../MachOSliceArtifactReader.js";
|
||||
import { NativeDmgArtifactReader } from "../NativeDmgArtifactReader.js";
|
||||
import { ZipArtifactReader } from "../ZipArtifactReader.js";
|
||||
import type { ArtifactNode } from "../../domain/artifactGraph.js";
|
||||
|
||||
export const createReader = async (
|
||||
+3
-3
@@ -5,7 +5,7 @@ import type { Stats } from "node:fs";
|
||||
import {
|
||||
ArtifactReaderFailure,
|
||||
type ArtifactReader,
|
||||
} from "../../artifacts/ArtifactReader.js";
|
||||
} from "../ArtifactReader.js";
|
||||
import {
|
||||
artifactInventoryResultSchema,
|
||||
type ArtifactInventoryResult,
|
||||
@@ -20,10 +20,10 @@ import {
|
||||
rekeyOccurrences,
|
||||
rootOccurrenceFor,
|
||||
type MutableOccurrence,
|
||||
} from "../ArtifactGraphConstruction.js";
|
||||
} from "./ArtifactGraphConstruction.js";
|
||||
import { canonicalDigest } from "../../domain/comparisonSemantics.js";
|
||||
import { classifyRoot } from "./classify.js";
|
||||
import { hashReadable, type HashResult } from "../../artifacts/ArtifactHash.js";
|
||||
import { hashReadable, type HashResult } from "../ArtifactHash.js";
|
||||
import { createReader, inventoryLimitations } from "./reader.js";
|
||||
import {
|
||||
scanReader,
|
||||
+5
-5
@@ -3,13 +3,13 @@ import { isAbsolute } from "node:path";
|
||||
import {
|
||||
ArtifactPathRegistry,
|
||||
normalizeArtifactPath,
|
||||
} from "../../artifacts/ArtifactPaths.js";
|
||||
} from "../ArtifactPaths.js";
|
||||
import {
|
||||
ArtifactReaderFailure,
|
||||
type ArtifactEntry,
|
||||
type ArtifactReader,
|
||||
} from "../../artifacts/ArtifactReader.js";
|
||||
import { AsarArtifactReader } from "../../artifacts/AsarArtifactReader.js";
|
||||
} from "../ArtifactReader.js";
|
||||
import { AsarArtifactReader } from "../AsarArtifactReader.js";
|
||||
import type { ArtifactNode } from "../../domain/artifactGraph.js";
|
||||
import {
|
||||
classifyArtifactContent,
|
||||
@@ -17,12 +17,12 @@ import {
|
||||
createOccurrence,
|
||||
nearestParent,
|
||||
type MutableOccurrence,
|
||||
} from "../ArtifactGraphConstruction.js";
|
||||
} from "./ArtifactGraphConstruction.js";
|
||||
import {
|
||||
STRICT_INTEGRITY_POLICY,
|
||||
type ArtifactIntegrityPolicy,
|
||||
} from "./types.js";
|
||||
import { hashReadable } from "../../artifacts/ArtifactHash.js";
|
||||
import { hashReadable } from "../ArtifactHash.js";
|
||||
|
||||
export interface PendingIntegrityContradiction {
|
||||
readonly logicalPath: string;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from "incur";
|
||||
|
||||
import { runProviderAnalysis } from "../composition/directAnalysis.js";
|
||||
import { createArtifactExtractionDestination } from "../application/ArtifactExtractionDestination.js";
|
||||
import { createArtifactExtractionDestination } from "../application/artifacts/ArtifactExtractionDestination.js";
|
||||
import { logCliCommand } from "../cliLogging.js";
|
||||
import { CLI_COMMANDS } from "../cliCommandNames.js";
|
||||
import type { Logger } from "../logger.js";
|
||||
|
||||
@@ -14,7 +14,7 @@ import { mcpProgressReporter } from "./mcpProgress.js";
|
||||
import { logToolExecution } from "./toolLogging.js";
|
||||
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
|
||||
import { toCallToolResult } from "./toolResult.js";
|
||||
import { createArtifactExtractionDestination } from "../application/ArtifactExtractionDestination.js";
|
||||
import { createArtifactExtractionDestination } from "../application/artifacts/ArtifactExtractionDestination.js";
|
||||
|
||||
interface EvidenceToolRegistration {
|
||||
readonly logger: Logger;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { join } from "node:path";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
|
||||
import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import { compareArtifacts } from "../../../src/domain/artifactComparison.js";
|
||||
import { createEvidence } from "../../../src/domain/evidence.js";
|
||||
import { jsonValueSchema } from "../../../src/domain/jsonValue.js";
|
||||
|
||||
@@ -5,7 +5,7 @@ import { TextReader, Uint8ArrayWriter, ZipWriter } from "@zip.js/zip.js";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { canonicalDigest } from "../../../src/domain/comparisonSemantics.js";
|
||||
import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
|
||||
import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import { compareArtifacts } from "../../../src/domain/artifactComparison.js";
|
||||
import type { ArtifactInventoryResult } from "../../../src/domain/artifactGraph.js";
|
||||
import { createEvidence } from "../../../src/domain/evidence.js";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { join } from "node:path";
|
||||
import { createPackage } from "@electron/asar";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
|
||||
import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import {
|
||||
artifactOccurrenceAt,
|
||||
artifactParentPaths,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
|
||||
import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
|
||||
describe("artifact inventory snapshot", () => {
|
||||
it("retains the complete scan after the source directory changes", async () => {
|
||||
|
||||
@@ -3,10 +3,10 @@ import { join } from "node:path";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { classifyArtifactContent } from "../../../src/application/ArtifactGraphConstruction.js";
|
||||
import { classifyRoot } from "../../../src/application/ArtifactInventory/classify.js";
|
||||
import { classifyArtifactContent } from "../../../src/artifacts/inventory/ArtifactGraphConstruction.js";
|
||||
import { classifyRoot } from "../../../src/artifacts/inventory/classify.js";
|
||||
import { ARTIFACT_CLASSIFICATION_PREFIX_BYTES } from "../../../src/artifacts/ArtifactHash.js";
|
||||
import { scanCanonicalArtifactInventory } from "../../../src/application/ArtifactInventory/scanCanonical.js";
|
||||
import { scanCanonicalArtifactInventory } from "../../../src/artifacts/inventory/scanCanonical.js";
|
||||
import { targetFormatSchema } from "../../../src/contracts/toolOutputSchemaPrimitives.js";
|
||||
import { artifactInventoryResultSchema } from "../../../src/domain/artifactGraph.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from "@zip.js/zip.js";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
|
||||
import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import {
|
||||
artifactOccurrenceAt,
|
||||
artifactParentPaths,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { buffer } from "node:stream/consumers";
|
||||
import { createPackage, listPackage, uncache } from "@electron/asar";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
|
||||
import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import { AsarArtifactReader } from "../../../src/artifacts/AsarArtifactReader.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import { Readable } from "node:stream";
|
||||
import { buffer } from "node:stream/consumers";
|
||||
import { createPackageWithOptions } from "@electron/asar";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
|
||||
import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import { AsarArtifactReader } from "../../../src/artifacts/AsarArtifactReader.js";
|
||||
import {
|
||||
closeAsarHandle,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { join } from "node:path";
|
||||
import { createPackage } from "@electron/asar";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
|
||||
import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import { readJavaScriptArtifactFiles } from "../../../src/artifacts/javascript/JavaScriptArtifactFiles.js";
|
||||
import { AsarArtifactReader } from "../../../src/artifacts/AsarArtifactReader.js";
|
||||
import { DirectoryArtifactReader } from "../../../src/artifacts/DirectoryArtifactReader.js";
|
||||
|
||||
@@ -8,7 +8,7 @@ import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
import { readJavaScriptArtifactFiles } from "../../../src/artifacts/javascript/JavaScriptArtifactFiles.js";
|
||||
import { reconstructJavaScriptArtifact } from "../../../src/application/javascript/JavaScriptArtifactReconstruction.js";
|
||||
import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
|
||||
import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import {
|
||||
type ArtifactEntry,
|
||||
type ArtifactReader,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { join } from "node:path";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { classifyRoot } from "../../../src/application/ArtifactInventory/classify.js";
|
||||
import { classifyRoot } from "../../../src/artifacts/inventory/classify.js";
|
||||
import { parseBinaryTarget } from "../../../src/application/BinaryTargetResolver.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { describe, expect, it } from "vitest";
|
||||
import { fragmentInventoryEvidence } from "../../fixtures/artifactEvidence.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
|
||||
import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import { artifactInventoryResultSchema } from "../../../src/domain/artifactGraph.js";
|
||||
import {
|
||||
artifactComparisonResultSchema,
|
||||
|
||||
@@ -7,7 +7,7 @@ import { expect, it } from "vitest";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
import { reconstructJavaScriptArtifact } from "../../../src/application/javascript/JavaScriptArtifactReconstruction.js";
|
||||
import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
|
||||
import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
|
||||
import { parseJavaScriptApplicationGraph } from "../../../src/domain/javascript/javascriptApplicationGraph.js";
|
||||
import { javascriptApplicationAnalysisResultSchema } from "../../../src/domain/javascript/javascriptApplicationAnalysis.js";
|
||||
import { createJavaScriptSemanticGraph } from "../../../src/domain/javascript/javascriptSemanticGraph.js";
|
||||
|
||||
@@ -76,7 +76,7 @@ describe("incremental module import boundaries", () => {
|
||||
["src/contracts/probe.ts", "../composition/android.js", false],
|
||||
[
|
||||
"src/artifacts/javascript/probe.ts",
|
||||
"../../application/ArtifactInventory.js",
|
||||
"../../application/javascript/JavaScriptArtifactReconstruction.js",
|
||||
false,
|
||||
],
|
||||
[
|
||||
@@ -87,7 +87,7 @@ describe("incremental module import boundaries", () => {
|
||||
["src/artifacts/javascript/probe.ts", "../../cli.js", false],
|
||||
[
|
||||
"src/artifacts/ArtifactHash.ts",
|
||||
"../application/ArtifactInventory/hash.js",
|
||||
"../application/artifacts/ArtifactExtractionDestination.js",
|
||||
false,
|
||||
],
|
||||
[
|
||||
@@ -111,11 +111,7 @@ describe("incremental module import boundaries", () => {
|
||||
"../../artifacts/javascript/JavaScriptArtifactReader.js",
|
||||
true,
|
||||
],
|
||||
[
|
||||
"src/application/ArtifactInventory/probe.ts",
|
||||
"../../artifacts/AsarArtifactReader.js",
|
||||
true,
|
||||
],
|
||||
["src/artifacts/inventory/probe.ts", "../AsarArtifactReader.js", true],
|
||||
["src/domain/probe.test.ts", "../composition/firmware.js", false],
|
||||
["src/application/probe.ts", "../android/JadxProvider.js", false],
|
||||
["src/application/probe.ts", "../composition/android.js", false],
|
||||
@@ -329,21 +325,30 @@ describe("test lane import boundaries", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Apple artifact producer ownership", () => {
|
||||
it.each([
|
||||
["../../application/Workflow.js", false],
|
||||
["../../composition/android.js", false],
|
||||
["../../cli.js", false],
|
||||
["../../domain/apple/plistValue.js", true],
|
||||
["../DirectoryArtifactReader.js", true],
|
||||
])("checks the producer dependency %s", (dependency, allowed) => {
|
||||
const violations = inspectModuleBoundaries(
|
||||
"src/artifacts/apple/probe.ts",
|
||||
`import type { Value } from ${JSON.stringify(dependency)};`,
|
||||
process.cwd(),
|
||||
);
|
||||
describe.each(["apple", "inventory", "extraction"])(
|
||||
"%s artifact producer ownership",
|
||||
(owner) => {
|
||||
it.each([
|
||||
["../../application/Workflow.js", false],
|
||||
["../../composition/android.js", false],
|
||||
["../../cli.js", false],
|
||||
["../../server/registerEvidenceTools.js", false],
|
||||
["../../main.ts", false],
|
||||
["../../domain/apple/plistValue.js", true],
|
||||
["../../domain/artifactInventorySnapshot.js", true],
|
||||
["../../contracts/artifactGraph.js", true],
|
||||
["../DirectoryArtifactReader.js", true],
|
||||
["../ArtifactHash.js", true],
|
||||
])("checks the producer dependency %s", (dependency, allowed) => {
|
||||
const violations = inspectModuleBoundaries(
|
||||
`src/artifacts/${owner}/probe.ts`,
|
||||
`import type { Value } from ${JSON.stringify(dependency)};`,
|
||||
process.cwd(),
|
||||
);
|
||||
|
||||
expect(violations.length === 0).toBe(allowed);
|
||||
if (!allowed) expect(violations[0]?.boundary).toBe("artifact-acquisition");
|
||||
});
|
||||
});
|
||||
expect(violations.length === 0).toBe(allowed);
|
||||
if (!allowed)
|
||||
expect(violations[0]?.boundary).toBe("artifact-acquisition");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user