Skip to content

Commit 9fec1f3

Browse files
committed
fix(upgrade): drop bare as-casts from re-emit script
The structural detection rewrite introduced a bare `as` cast, tripping the no-bare-cast ratchet. Replace it (and the pre-existing JSON.parse cast) with an isJsonObject type guard so the standalone script stays cast-free without importing the @prisma-next casts helper. Signed-off-by: Will Madden <madden@prisma.io>
1 parent 1efe950 commit 9fec1f3

1 file changed

Lines changed: 15 additions & 8 deletions

File tree

skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ async function isMongoContract(contractPath: string): Promise<boolean> {
108108
* A substring scan is unsafe here: a single closed branch would mask a sibling
109109
* that still needs re-emitting.
110110
*/
111+
/** Narrows an arbitrary JSON-parsed value to a plain object (non-null, non-array). */
112+
function isJsonObject(value: unknown): value is Record<string, unknown> {
113+
return typeof value === 'object' && value !== null && !Array.isArray(value);
114+
}
115+
111116
function contractLooksClosed(raw: string): boolean {
112117
let parsed: unknown;
113118
try {
@@ -117,17 +122,16 @@ function contractLooksClosed(raw: string): boolean {
117122
}
118123

119124
function isClosed(node: unknown): boolean {
120-
if (node === null || typeof node !== 'object') return true;
121125
if (Array.isArray(node)) return node.every(isClosed);
126+
if (!isJsonObject(node)) return true;
122127

123-
const obj = node as Record<string, unknown>;
124-
const hasProperties = typeof obj['properties'] === 'object' && obj['properties'] !== null;
125-
const isPolymorphicTopLevel = Array.isArray(obj['oneOf']);
126-
if (hasProperties && !isPolymorphicTopLevel && obj['additionalProperties'] !== false) {
128+
const hasProperties = isJsonObject(node['properties']);
129+
const isPolymorphicTopLevel = Array.isArray(node['oneOf']);
130+
if (hasProperties && !isPolymorphicTopLevel && node['additionalProperties'] !== false) {
127131
return false;
128132
}
129133

130-
return Object.values(obj).every(isClosed);
134+
return Object.values(node).every(isClosed);
131135
}
132136

133137
return isClosed(parsed);
@@ -138,8 +142,11 @@ async function packageJsonHasEmitScript(configDir: string): Promise<boolean> {
138142
if (!(await pathExists(pkgPath))) return false;
139143
const raw = await readFile(pkgPath, 'utf-8');
140144
try {
141-
const parsed = JSON.parse(raw) as { scripts?: Record<string, string> };
142-
return typeof parsed.scripts?.emit === 'string' && parsed.scripts.emit.length > 0;
145+
const parsed: unknown = JSON.parse(raw);
146+
if (!isJsonObject(parsed)) return false;
147+
const scripts = parsed['scripts'];
148+
if (!isJsonObject(scripts)) return false;
149+
return typeof scripts['emit'] === 'string' && scripts['emit'].length > 0;
143150
} catch {
144151
return false;
145152
}

0 commit comments

Comments
 (0)