MCPcopy Create free account
hub / github.com/TestSprite/testsprite-cli / readPlanFromGuarded

Function readPlanFromGuarded

src/commands/test.ts:1974–2024  ·  view source on GitHub ↗

* Read + validate a plan JSON file. Returns the parsed `CliPlanInput` * on success, throws a typed `VALIDATION_ERROR` envelope on any * schema problem (missing fields, wrong types, oversize body, etc.). * * Stat-first guard mirrors piece-2's `readCodeFileGuarded` — reject * obvious oversize fil

(path: string)

Source from the content-addressed store, hash-verified

1972 * plans the cap is 256 KB (vs. 350 KB for code).
1973 */
1974function readPlanFromGuarded(path: string): CliPlanInput {
1975 const absolute = resolveAbsolute(path);
1976
1977 let stat;
1978 try {
1979 stat = statSync(absolute);
1980 } catch (err) {
1981 const code = (err as NodeJS.ErrnoException).code;
1982 if (code === 'ENOENT') {
1983 throw localValidationError('plan-from', `file does not exist: ${path}`);
1984 }
1985 if (code === 'EACCES') {
1986 throw localValidationError('plan-from', `permission denied reading ${path}`);
1987 }
1988 const reason = err instanceof Error ? err.message : 'unknown error';
1989 throw localValidationError('plan-from', `cannot stat ${path}: ${reason}`);
1990 }
1991 if (stat.size > MAX_PLAN_BODY_BYTES) {
1992 throw ApiError.fromEnvelope({
1993 error: {
1994 code: 'PAYLOAD_TOO_LARGE',
1995 message: `Plan body exceeds the 256 KB CLI cap (${stat.size} bytes).`,
1996 nextAction: 'Split into multiple smaller tests or trim step descriptions.',
1997 requestId: 'local',
1998 details: {
1999 field: 'plan-from',
2000 sizeBytes: stat.size,
2001 maxBytes: MAX_PLAN_BODY_BYTES,
2002 },
2003 },
2004 });
2005 }
2006
2007 let raw;
2008 try {
2009 raw = stripBom(readFileSync(absolute, 'utf8'));
2010 } catch (err) {
2011 const reason = err instanceof Error ? err.message : 'unknown error';
2012 throw localValidationError('plan-from', `cannot read ${path}: ${reason}`);
2013 }
2014
2015 let parsed: unknown;
2016 try {
2017 parsed = JSON.parse(raw);
2018 } catch (err) {
2019 const reason = err instanceof Error ? err.message : 'unknown error';
2020 throw localValidationError('plan-from', `not valid JSON: ${reason}`);
2021 }
2022
2023 return assertPlanShape(parsed);
2024}
2025
2026/**
2027 * Type-narrow + validate a parsed plan input. Pulled out so the same

Callers 1

runCreateFromPlanFunction · 0.85

Calls 6

resolveAbsoluteFunction · 0.85
stripBomFunction · 0.85
readFileSyncFunction · 0.85
assertPlanShapeFunction · 0.85
fromEnvelopeMethod · 0.80
localValidationErrorFunction · 0.70

Tested by

no test coverage detected