refactor(ownership)!: consolidate legacy aliases
Migrate schema, installer, ASN.1, and tooling consumers to their owning definitions. Remove the redundant CI task entry and the deprecated Cutter command-local JSON flag. BREAKING CHANGE: Replace Cutter --json=true or --json=false with --json-output=true or --json-output=false. Bare --json still controls CLI result formatting.
This commit is contained in:
1 parent
7c8eb63fcc
commit
567ea4b1e8
17 files changed
+73
-109
No files matched your search
+4
-4
@@ -985,10 +985,10 @@ Cutter when available. This is separate from `--format json`, which selects the
|
||||
CLI result representation; the global `--json` flag selects that same CLI
|
||||
representation.
|
||||
|
||||
Cutter still accepts deprecated `--json=true` and `--json=false` compatibility
|
||||
values. When both forms are present, `--json-output` takes precedence in either
|
||||
argument order. Bare `--json` retains its global meaning of selecting JSON CLI
|
||||
output formatting.
|
||||
Cutter no longer accepts command-local `--json=true` or `--json=false`.
|
||||
Replace these with `--json-output=true` or `--json-output=false`, respectively.
|
||||
Combine `--json-output` with bare `--json` when both Cutter command output and
|
||||
the CLI result should use JSON; either argument order is accepted.
|
||||
|
||||
| Status | Meaning |
|
||||
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|
||||
@@ -129,7 +129,6 @@
|
||||
"check:ci:fast:tasks": "node scripts/run-turbo.mjs run typecheck lint:built format:check",
|
||||
"check:ci:deep": "node scripts/run-exclusive.mjs artifacts npm run check:ci:deep:tasks && npm run verify:architecture-guards && npm run verify:test-discovery && npm run test:python && npm run knip:production && npm run lint:typed",
|
||||
"check:ci:deep:tasks": "node scripts/run-turbo.mjs run knip metadata:check jscpd scan:todos",
|
||||
"check:ci:tasks": "node scripts/run-turbo.mjs run typecheck lint:built format:check knip metadata:check jscpd scan:todos",
|
||||
"ci:static-context": "node scripts/ci/static-task-context.mjs",
|
||||
"build:cached": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run artifacts:skills",
|
||||
"build:termux": "node scripts/run-exclusive.mjs artifacts npm run build:termux:run",
|
||||
|
||||
@@ -13,12 +13,12 @@ import {
|
||||
LinuxHopperTemporaryCleanupOwner,
|
||||
systemLinuxHopperInstallHost,
|
||||
type LinuxDistribution,
|
||||
type LinuxHopperDownload,
|
||||
type LinuxHopperInstallHost,
|
||||
type LinuxHopperLauncherStatus,
|
||||
type LinuxPackageInstallFailure,
|
||||
type LinuxPackageInstallOutcome,
|
||||
} from "./LinuxHopper.js";
|
||||
import type { HopperDownload } from "./HopperDownload.js";
|
||||
import { err, ok } from "../domain/result.js";
|
||||
import {
|
||||
type LinuxPackageFamily,
|
||||
@@ -74,7 +74,7 @@ class RecordingLinuxHost implements LinuxHopperInstallHost {
|
||||
Promise.resolve(this.distributionValue);
|
||||
release = (family: LinuxPackageFamily) =>
|
||||
Promise.resolve(ok(releasesFor(new Uint8Array([1, 2, 3]))[family]));
|
||||
download = (url: string): Promise<LinuxHopperDownload> => {
|
||||
download = (url: string): Promise<HopperDownload> => {
|
||||
this.downloads.push(url);
|
||||
return Promise.resolve({ ok: this.archiveOk, bytes: this.archive });
|
||||
};
|
||||
|
||||
@@ -119,9 +119,6 @@ export const supportsReaHost = (
|
||||
distribution: LinuxDistribution | undefined,
|
||||
): boolean => distribution?.packageFamily !== undefined;
|
||||
|
||||
/** Download response kept independent of Node's global fetch implementation. */
|
||||
export type LinuxHopperDownload = HopperDownload;
|
||||
|
||||
/** One failed package-manager command, with the output that explains it. */
|
||||
export interface LinuxPackageInstallFailure {
|
||||
/** The executed executable and arguments, joined for display. */
|
||||
@@ -159,7 +156,7 @@ export interface LinuxHopperInstallHost {
|
||||
download(
|
||||
url: string,
|
||||
options: { readonly signal?: AbortSignal },
|
||||
): Promise<LinuxHopperDownload>;
|
||||
): Promise<HopperDownload>;
|
||||
createTemporaryDirectory(): Promise<string>;
|
||||
writeArchive(path: string, bytes: Uint8Array): Promise<void>;
|
||||
installPackage(
|
||||
|
||||
@@ -107,9 +107,6 @@ export interface EnvironmentBuildInput {
|
||||
readonly exclusiveDestination?: boolean | undefined;
|
||||
}
|
||||
|
||||
/** The report environment-build prints and export_environment_bundle returns. */
|
||||
export type { EnvironmentBuildReport };
|
||||
|
||||
const captureOperations = new Set([
|
||||
"inspect_web_network_capture",
|
||||
"capture_browser_scenario",
|
||||
|
||||
@@ -60,12 +60,6 @@ export const registerCutterCommands = (
|
||||
.describe(
|
||||
"Return command-specific JSON output when available (independent of CLI output formatting).",
|
||||
),
|
||||
json: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.describe(
|
||||
"Deprecated compatibility input: use --json-output; pass --json=true or --json=false (bare --json formats CLI output).",
|
||||
),
|
||||
}),
|
||||
run: ({ args, options }) =>
|
||||
withCommandCancellation((signal) =>
|
||||
@@ -78,7 +72,7 @@ export const registerCutterCommands = (
|
||||
session_id: args.sessionId,
|
||||
expected_generation: args.expectedGeneration,
|
||||
command: args.command,
|
||||
json: options.jsonOutput ?? options.json ?? false,
|
||||
json: options.jsonOutput ?? false,
|
||||
},
|
||||
{ signal },
|
||||
),
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
peLoadConfigSchema,
|
||||
} from "../../domain/native/peLoadConfig.js";
|
||||
import { inspectByteEntropyInputSchema } from "../../domain/native/byteEntropy.js";
|
||||
import { publicInputStrictObject } from "../../domain/publicInput.js";
|
||||
import { byteEntropyOutputSchema } from "../toolOutputSchemaGroups.js";
|
||||
import {
|
||||
inspectRecordedCrashInputSchema,
|
||||
@@ -65,13 +64,9 @@ export const inspectBinaryLayoutRequestSchema =
|
||||
export const inspectNativeExportsRequestSchema =
|
||||
inspectNativeExportsInputSchema.extend({ detail: analysisDetailSchema });
|
||||
|
||||
/**
|
||||
* Public `inspect_byte_entropy` input. The shared constructor runs before
|
||||
* `detail` is added so the advertised input stays closed.
|
||||
*/
|
||||
export const inspectByteEntropyRequestSchema = publicInputStrictObject(
|
||||
inspectByteEntropyInputSchema.shape,
|
||||
).extend({ detail: analysisDetailSchema });
|
||||
/** Public byte-entropy input retains the producer schema's closed-object policy. */
|
||||
export const inspectByteEntropyRequestSchema =
|
||||
inspectByteEntropyInputSchema.extend({ detail: analysisDetailSchema });
|
||||
|
||||
/** Offline binary diagnostics are independent of macOS process/UI providers. */
|
||||
export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import {
|
||||
javaScriptRouteInventorySourceSchema,
|
||||
javaScriptRouteInventorySchema,
|
||||
} from "../javascript/javascriptRouteInventory.js";
|
||||
import { nativeFunctionMatchingContextSchema } from "../native/functionMatching.js";
|
||||
import {
|
||||
nativeObservationViewRequestSchema,
|
||||
nativeContextViewRequestSchema,
|
||||
@@ -58,7 +63,6 @@ import {
|
||||
javaScriptRoutesViewRequestSchema,
|
||||
javaScriptRoutesViewItemsSchema,
|
||||
javaScriptRoutesViewSummarySchema,
|
||||
javaScriptRoutesSourceReferenceSchema,
|
||||
projectJavaScriptRoutesView,
|
||||
} from "./javascriptRoutesView.js";
|
||||
import {
|
||||
@@ -69,7 +73,6 @@ import {
|
||||
} from "./webBundleView.js";
|
||||
import { webBundleAnalysisSchema } from "../webBundleAnalysis.js";
|
||||
import { recordedBrowserOriginSchema } from "../browserObservation.js";
|
||||
import { javaScriptRouteInventorySchema } from "../javascript/javascriptRouteInventory.js";
|
||||
import {
|
||||
sourceToBundleViewRequestSchema,
|
||||
sourceToBundleViewItemsSchema,
|
||||
@@ -122,7 +125,6 @@ import {
|
||||
projectNativeFunctionMatchingView,
|
||||
nativeFunctionMatchingViewRequestSchema,
|
||||
nativeFunctionMatchingViewItemsSchema,
|
||||
nativeFunctionMatchingViewContextSchema,
|
||||
} from "./nativeFunctionMatchingView.js";
|
||||
import {
|
||||
protobufViewRequestSchema,
|
||||
@@ -885,7 +887,7 @@ export const javaScriptRoutesViewResultSchema = z.strictObject({
|
||||
inventory_capacity: javaScriptRouteInventorySchema.shape.capacity,
|
||||
capture_url: z.string().nullable(),
|
||||
items: javaScriptRoutesViewItemsSchema,
|
||||
sources: z.array(javaScriptRoutesSourceReferenceSchema),
|
||||
sources: z.array(javaScriptRouteInventorySourceSchema),
|
||||
summary: javaScriptRoutesViewSummarySchema.nullable(),
|
||||
byte_limited: z.boolean(),
|
||||
});
|
||||
@@ -990,7 +992,7 @@ export const nativeFunctionMatchingSummaryViewResultSchema = z.strictObject({
|
||||
...summaryViewResultBase,
|
||||
artifact: z.null(),
|
||||
parent_operation: z.literal("match_native_functions"),
|
||||
summary: nativeFunctionMatchingViewContextSchema,
|
||||
summary: nativeFunctionMatchingContextSchema,
|
||||
});
|
||||
|
||||
/** Rows observed for one facet, or null when the provider declared that facet unavailable. */
|
||||
@@ -1141,7 +1143,7 @@ export const analysisViewResultSchema = z.discriminatedUnion("kind", [
|
||||
sourceToBundlePageViewResultSchema,
|
||||
z.strictObject({
|
||||
...viewResultBase,
|
||||
...nativeFunctionMatchingViewContextSchema.shape,
|
||||
...nativeFunctionMatchingContextSchema.shape,
|
||||
kind: z.literal("function-matches"),
|
||||
artifact: z.null(),
|
||||
view: nativeFunctionMatchingViewRequestSchema,
|
||||
|
||||
@@ -191,8 +191,6 @@ export const javaScriptRoutesViewSummarySchema = z.strictObject({
|
||||
unknown: z.int().nonnegative(),
|
||||
}),
|
||||
});
|
||||
export const javaScriptRoutesSourceReferenceSchema =
|
||||
javaScriptRouteInventorySourceSchema;
|
||||
|
||||
type Request = z.output<typeof javaScriptRoutesViewRequestSchema>;
|
||||
type Gap = z.infer<typeof javaScriptRouteGapSchema>;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { z } from "zod";
|
||||
import {
|
||||
nativeFunctionMatchingSchema,
|
||||
nativeFunctionMatchingContextSchema,
|
||||
nativeFunctionMatchSchema,
|
||||
nativeFunctionMatchMemberSchema,
|
||||
nativeMatchStateSchema,
|
||||
@@ -80,8 +79,6 @@ export const nativeFunctionMatchingViewItemsSchema = z.union([
|
||||
}),
|
||||
),
|
||||
]);
|
||||
export const nativeFunctionMatchingViewContextSchema =
|
||||
nativeFunctionMatchingContextSchema;
|
||||
interface FunctionRow {
|
||||
readonly member: NativeFunctionMatching["matches"][number]["left"][number];
|
||||
readonly match_id: string;
|
||||
|
||||
@@ -2,7 +2,6 @@ import { z } from "zod";
|
||||
|
||||
import { digestSchema } from "../digests.js";
|
||||
import { absoluteLocalPathStringSchema } from "../localPath.js";
|
||||
import { publicInputStrictObject } from "../publicInput.js";
|
||||
|
||||
const uint = z.number().int().min(0).max(0xffffffff);
|
||||
const range = z.strictObject({ offset: uint, bytes: uint });
|
||||
@@ -17,7 +16,7 @@ export const MAX_INSPECT_ERLANG_BEAM_ATOMS = 65536;
|
||||
export const MAX_INSPECT_ERLANG_BEAM_TABLE_ROWS = 65536;
|
||||
|
||||
/** Complete bounded inspection of one Erlang BEAM IFF container. */
|
||||
export const inspectErlangBeamInputSchema = publicInputStrictObject({
|
||||
export const inspectErlangBeamInputSchema = z.strictObject({
|
||||
path: absoluteLocalPathStringSchema.describe(
|
||||
"Absolute filesystem path to a BEAM file",
|
||||
),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { z } from "zod";
|
||||
import { javascriptSourceRangeSchema } from "./javascriptSourceCoordinates.js";
|
||||
import { digestSchema } from "../digests.js";
|
||||
import { prefixedDigestSchema } from "../digests.js";
|
||||
import { digestSchema, prefixedDigestSchema } from "../digests.js";
|
||||
|
||||
const boundedTextSchema = z.string().min(1);
|
||||
const boundedKeySchema = z.string().min(1);
|
||||
@@ -139,14 +138,17 @@ const applicationLocationSchema = z.discriminatedUnion("kind", [
|
||||
}),
|
||||
]);
|
||||
|
||||
/** Explicit source-location availability for one graph fact. */
|
||||
const applicationLocationReferenceSchema = z.discriminatedUnion("available", [
|
||||
z.strictObject({
|
||||
available: z.literal(true),
|
||||
value: applicationLocationSchema,
|
||||
}),
|
||||
unavailableFactSchema,
|
||||
]);
|
||||
/** Source-location availability and coordinates retained on each graph fact. */
|
||||
export const applicationGraphEvidenceLocationSchema = z.discriminatedUnion(
|
||||
"available",
|
||||
[
|
||||
z.strictObject({
|
||||
available: z.literal(true),
|
||||
value: applicationLocationSchema,
|
||||
}),
|
||||
unavailableFactSchema,
|
||||
],
|
||||
);
|
||||
|
||||
/** Versioned extractor coordinates attached to every graph fact. */
|
||||
const applicationExtractorSchema = z.strictObject({
|
||||
@@ -242,7 +244,7 @@ const applicationGraphEvidenceBaseSchema = z.strictObject({
|
||||
state: applicationFactStateSchema,
|
||||
confidence: applicationConfidenceSchema,
|
||||
artifact: applicationArtifactReferenceSchema,
|
||||
location: applicationLocationReferenceSchema,
|
||||
location: applicationGraphEvidenceLocationSchema,
|
||||
extractor: applicationExtractorSchema,
|
||||
coverage: applicationCoverageSchema,
|
||||
limitations: z.array(boundedTextSchema),
|
||||
@@ -253,10 +255,6 @@ const applicationGraphEvidenceBaseSchema = z.strictObject({
|
||||
export const applicationGraphEvidenceContextSchema =
|
||||
applicationGraphEvidenceBaseSchema.omit({ location: true });
|
||||
|
||||
/** Exact coordinates retained on each graph fact. */
|
||||
export const applicationGraphEvidenceLocationSchema =
|
||||
applicationLocationReferenceSchema;
|
||||
|
||||
type EvidenceValue = z.infer<typeof applicationGraphEvidenceBaseSchema>;
|
||||
|
||||
const checkAuthorityState = (
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { z } from "zod";
|
||||
import { localPathStringSchema } from "../localPath.js";
|
||||
import { publicInputStrictObject } from "../publicInput.js";
|
||||
|
||||
const offsetSchema = z
|
||||
.number()
|
||||
@@ -10,7 +9,7 @@ const offsetSchema = z
|
||||
const entropySchema = z.number().min(0).max(8);
|
||||
|
||||
/** Select blocks relative to an explicit byte window; identity remains file-wide. */
|
||||
export const inspectByteEntropyInputSchema = publicInputStrictObject({
|
||||
export const inspectByteEntropyInputSchema = z.strictObject({
|
||||
path: localPathStringSchema,
|
||||
block_size: z
|
||||
.number()
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { expect, it } from "vitest";
|
||||
import { z } from "zod";
|
||||
|
||||
import { publicInputStrictObject } from "./publicInput.js";
|
||||
|
||||
it("rejects unknown keys on a public tool input", () => {
|
||||
const schema = publicInputStrictObject({
|
||||
path: z.string(),
|
||||
block_size: z.number().default(4096),
|
||||
});
|
||||
expect(schema.parse({ path: "/file" })).toEqual({
|
||||
path: "/file",
|
||||
block_size: 4096,
|
||||
});
|
||||
expect(schema.safeParse({ path: "/file", extra: true }).success).toBe(false);
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Closed object schema for a public CLI or MCP tool input.
|
||||
*
|
||||
* Unknown keys fail here so public input policy has one owner. Result and
|
||||
* internal objects stay on their own constructors.
|
||||
*/
|
||||
export const publicInputStrictObject = z.strictObject;
|
||||
@@ -25,8 +25,6 @@ const OID_NAMES: Readonly<Record<string, string>> = {
|
||||
"2.16.840.1.101.3.4.2.3": "sha512",
|
||||
};
|
||||
|
||||
export type Asn1Node = Asn1BerNode;
|
||||
|
||||
export class PeCertificateAsn1Failure extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
@@ -46,7 +44,7 @@ const required = <T>(value: T | undefined, message: string): T =>
|
||||
export const ASN1_NODE_BUDGET = 16_384;
|
||||
|
||||
/** Decode one bounded ASN.1 TLV, including indefinite constructed BER values. */
|
||||
export const readAsn1 = (bytes: Buffer): Asn1Node => {
|
||||
export const readAsn1 = (bytes: Buffer): Asn1BerNode => {
|
||||
try {
|
||||
return new Asn1BerReader(bytes, ASN1_NODE_BUDGET).read();
|
||||
} catch (cause: unknown) {
|
||||
@@ -55,7 +53,7 @@ export const readAsn1 = (bytes: Buffer): Asn1Node => {
|
||||
}
|
||||
};
|
||||
|
||||
const requireDefiniteEncoding = (node: Asn1Node, label: string): void => {
|
||||
const requireDefiniteEncoding = (node: Asn1BerNode, label: string): void => {
|
||||
if (node.lengthForm === "indefinite")
|
||||
fail(`${label} must use definite DER length encoding.`);
|
||||
for (const child of node.children) requireDefiniteEncoding(child, label);
|
||||
@@ -165,7 +163,7 @@ const decodeUtf8 = (bytes: Buffer, budget: DecodedNameBudget): string => {
|
||||
};
|
||||
|
||||
const decodeDirectoryString = (
|
||||
node: Asn1Node,
|
||||
node: Asn1BerNode,
|
||||
budget: DecodedNameBudget,
|
||||
): string => {
|
||||
switch (node.tag) {
|
||||
@@ -211,18 +209,21 @@ const requireBitStringContent = (content: Buffer, label: string): void => {
|
||||
return fail(`${label} BIT STRING is truncated or has invalid unused bits.`);
|
||||
};
|
||||
|
||||
const requireBitString = (node: Asn1Node | undefined, label: string): void => {
|
||||
const requireBitString = (
|
||||
node: Asn1BerNode | undefined,
|
||||
label: string,
|
||||
): void => {
|
||||
if (node === undefined || node.tag !== 0x03)
|
||||
return fail(`${label} is not a BIT STRING.`);
|
||||
requireBitStringContent(node.content, label);
|
||||
};
|
||||
|
||||
const sequence = (node: Asn1Node, label: string): readonly Asn1Node[] => {
|
||||
const sequence = (node: Asn1BerNode, label: string): readonly Asn1BerNode[] => {
|
||||
if (node.tag !== 0x30) return fail(`Expected SEQUENCE for ${label}.`);
|
||||
return node.children;
|
||||
};
|
||||
|
||||
const algorithmOid = (node: Asn1Node): string => {
|
||||
const algorithmOid = (node: Asn1BerNode): string => {
|
||||
const children = sequence(node, "AlgorithmIdentifier");
|
||||
const oid = children[0];
|
||||
if (oid === undefined || oid.tag !== 0x06)
|
||||
@@ -237,7 +238,7 @@ interface Attribute {
|
||||
}
|
||||
|
||||
const decodeName = (
|
||||
node: Asn1Node,
|
||||
node: Asn1BerNode,
|
||||
budget: DecodedNameBudget,
|
||||
): {
|
||||
readonly text: string;
|
||||
@@ -273,7 +274,7 @@ const decodeName = (
|
||||
return { text, attributes };
|
||||
};
|
||||
|
||||
const validityTime = (node: Asn1Node, budget: DecodedNameBudget): string => {
|
||||
const validityTime = (node: Asn1BerNode, budget: DecodedNameBudget): string => {
|
||||
if (node.tag !== 0x17 && node.tag !== 0x18)
|
||||
return fail("Validity instant is not UTCTime or GeneralizedTime.");
|
||||
// A zero byte becomes "\u0000" (six characters) in the hashed evidence JSON.
|
||||
@@ -292,7 +293,7 @@ export interface ParsedCertificate {
|
||||
readonly signature_algorithm_oid: string;
|
||||
}
|
||||
|
||||
const requireSubjectPublicKeyInfo = (node: Asn1Node): void => {
|
||||
const requireSubjectPublicKeyInfo = (node: Asn1BerNode): void => {
|
||||
const children = sequence(node, "SubjectPublicKeyInfo");
|
||||
const algorithm = children[0];
|
||||
const key = children[1];
|
||||
@@ -307,7 +308,7 @@ const requireSubjectPublicKeyInfo = (node: Asn1Node): void => {
|
||||
// issuerUniqueID [1], subjectUniqueID [2], and extensions [3] are optional
|
||||
// and ordered. Anything else is not a TBSCertificate field.
|
||||
const finishTbsCertificate = (
|
||||
children: readonly Asn1Node[],
|
||||
children: readonly Asn1BerNode[],
|
||||
start: number,
|
||||
): void => {
|
||||
let cursor = start;
|
||||
@@ -344,7 +345,7 @@ const finishTbsCertificate = (
|
||||
|
||||
/** Decode one X.509 Certificate SEQUENCE at a known file-relative DER node. */
|
||||
export const parseCertificate = (
|
||||
node: Asn1Node,
|
||||
node: Asn1BerNode,
|
||||
names: DecodedNameBudget = {
|
||||
remaining: MAX_DECODED_NAME_BYTES,
|
||||
teletexStringCompatibilityUsed: false,
|
||||
@@ -432,7 +433,7 @@ export interface ParsedSigner {
|
||||
}
|
||||
|
||||
const signerIdentifier = (
|
||||
sid: Asn1Node,
|
||||
sid: Asn1BerNode,
|
||||
names: DecodedNameBudget,
|
||||
): {
|
||||
readonly issuer: ReturnType<typeof decodeName> | null;
|
||||
@@ -471,7 +472,7 @@ const signerIdentifier = (
|
||||
};
|
||||
|
||||
const parseSigner = (
|
||||
node: Asn1Node,
|
||||
node: Asn1BerNode,
|
||||
names: DecodedNameBudget,
|
||||
): ParsedSigner => {
|
||||
const children = sequence(node, "SignerInfo");
|
||||
@@ -523,7 +524,7 @@ export interface ParsedSignedData {
|
||||
}
|
||||
|
||||
const parseSignedData = (
|
||||
node: Asn1Node,
|
||||
node: Asn1BerNode,
|
||||
names: DecodedNameBudget,
|
||||
): ParsedSignedData => {
|
||||
const children = sequence(node, "SignedData");
|
||||
@@ -569,7 +570,7 @@ const parseSignedData = (
|
||||
};
|
||||
|
||||
/** Decode ContentInfo wrapping SignedData; other content types remain unsupported. */
|
||||
export const parsePkcs7SignedData = (root: Asn1Node): ParsedSignedData => {
|
||||
export const parsePkcs7SignedData = (root: Asn1BerNode): ParsedSignedData => {
|
||||
const children = sequence(root, "ContentInfo");
|
||||
const type = children[0];
|
||||
const content = children[1];
|
||||
|
||||
@@ -315,21 +315,34 @@ describe("Cutter CLI command output flags", () => {
|
||||
expect(() => JSON.parse(formatted.stdout)).not.toThrow();
|
||||
|
||||
for (const [flags, expected] of [
|
||||
[["--json=true"], true],
|
||||
[["--json=false"], false],
|
||||
[["--json=true", "--json-output=false"], false],
|
||||
[["--json=false", "--json-output=true"], true],
|
||||
[["--json-output=false", "--json=true"], false],
|
||||
[["--json-output=true", "--json=false"], true],
|
||||
[["--json-output=true"], true],
|
||||
[["--json-output=false"], false],
|
||||
[["--json", "--json-output=false"], false],
|
||||
[["--json", "--json-output=true"], true],
|
||||
[["--json-output=false", "--json"], false],
|
||||
[["--json-output=true", "--json"], true],
|
||||
] as const) {
|
||||
const compatible = await serveCli(
|
||||
const selected = await serveCli(
|
||||
["cutter-command", SESSION_ID, "0", "pdi", ...flags],
|
||||
{ REA_CUTTER_BRIDGE_DIR: directory },
|
||||
);
|
||||
expect(compatible.exitCode).toBe(0);
|
||||
expect(selected.exitCode).toBe(0);
|
||||
expect(commandJsonModes.at(-1)).toBe(expected);
|
||||
if (flags.some((flag) => flag === "--json"))
|
||||
expect(() => JSON.parse(selected.stdout)).not.toThrow();
|
||||
}
|
||||
|
||||
const commandsBeforeRejectedFlags = commandJsonModes.length;
|
||||
for (const flag of ["--json=true", "--json=false"]) {
|
||||
const rejected = await serveCli(
|
||||
["cutter-command", SESSION_ID, "0", "pdi", flag],
|
||||
{ REA_CUTTER_BRIDGE_DIR: directory },
|
||||
);
|
||||
expect(rejected.exitCode).toBe(1);
|
||||
expect(rejected.stdout).toContain("Unknown flag: --json");
|
||||
}
|
||||
expect(commandJsonModes).toHaveLength(commandsBeforeRejectedFlags);
|
||||
|
||||
await assertRealVerifierJsonInspection(directory, commandJsonModes);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user