|
| 1 | +import { realpathSync } from 'node:fs' |
1 | 2 | import { cp, mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises' |
2 | 3 | import { dirname, resolve, sep } from 'node:path' |
3 | 4 | import { fileURLToPath } from 'node:url' |
@@ -325,10 +326,34 @@ const patchInterpolatableRobot = (contents: string): string => { |
325 | 326 | return `${contents.slice(0, start)}${replacement}${contents.slice(end)}` |
326 | 327 | } |
327 | 328 |
|
328 | | -const patchAiChatSchema = (contents: string): string => |
329 | | - contents |
330 | | - .replace('const jsonValueSchema: z.ZodType =', 'const jsonValueSchema: z.ZodType<any> =') |
331 | | - .replace('result: z.unknown(),', 'result: z.unknown().optional(),') |
| 329 | +export const patchAiChatSchema = (contents: string): string => { |
| 330 | + const jsonValueToken = 'const jsonValueSchema: z.ZodType =' |
| 331 | + const jsonValuePatched = 'const jsonValueSchema: z.ZodType<any> =' |
| 332 | + const resultToken = 'result: z.unknown(),' |
| 333 | + const resultPatched = 'result: z.unknown().optional(),' |
| 334 | + |
| 335 | + let next = contents |
| 336 | + if (next.includes(jsonValueToken)) { |
| 337 | + next = next.replace(jsonValueToken, jsonValuePatched) |
| 338 | + } |
| 339 | + if (next.includes(resultToken)) { |
| 340 | + next = next.replace(resultToken, resultPatched) |
| 341 | + } |
| 342 | + |
| 343 | + const hasJsonValue = next.includes(jsonValuePatched) |
| 344 | + const hasResult = next.includes(resultPatched) |
| 345 | + if (!hasJsonValue || !hasResult) { |
| 346 | + const missing = [ |
| 347 | + !hasJsonValue ? 'jsonValueSchema' : null, |
| 348 | + !hasResult ? 'result optional' : null, |
| 349 | + ] |
| 350 | + .filter(Boolean) |
| 351 | + .join(', ') |
| 352 | + throw new Error(`ai-chat schema patch failed (${missing})`) |
| 353 | + } |
| 354 | + |
| 355 | + return next |
| 356 | +} |
332 | 357 |
|
333 | 358 | const patchFile = (filePath: string, contents: string): string => { |
334 | 359 | let next = contents |
@@ -360,4 +385,17 @@ const main = async () => { |
360 | 385 | } |
361 | 386 | } |
362 | 387 |
|
363 | | -await main() |
| 388 | +const shouldRun = (): boolean => { |
| 389 | + if (!process.argv[1]) return false |
| 390 | + try { |
| 391 | + const current = realpathSync(fileURLToPath(import.meta.url)) |
| 392 | + const invoked = realpathSync(process.argv[1]) |
| 393 | + return current === invoked |
| 394 | + } catch { |
| 395 | + return false |
| 396 | + } |
| 397 | +} |
| 398 | + |
| 399 | +if (shouldRun()) { |
| 400 | + await main() |
| 401 | +} |
0 commit comments