(args: Record<string, unknown>)
| 378 | } |
| 379 | |
| 380 | async function handleSnapshotSplit(args: Record<string, unknown>) { |
| 381 | if (args.path === undefined) { |
| 382 | return snapshotError('path is required') |
| 383 | } |
| 384 | const parsedArgs = snapshotSplitArgsSchema.safeParse(args) |
| 385 | if (!parsedArgs.success) { |
| 386 | return snapshotError(`Invalid arguments for deepnote_snapshot_split: ${formatFirstIssue(parsedArgs.error)}`) |
| 387 | } |
| 388 | const { path: filePath, snapshotDir } = parsedArgs.data |
| 389 | const keepLatest = parsedArgs.data.keepLatest ?? true |
| 390 | |
| 391 | try { |
| 392 | const absolutePath = path.resolve(filePath) |
| 393 | const content = await fs.readFile(absolutePath, 'utf-8') |
| 394 | const file = deserializeDeepnoteFile(content) |
| 395 | |
| 396 | // Split into source and snapshot |
| 397 | const { source, snapshot } = splitDeepnoteFile(file) |
| 398 | |
| 399 | const snapshotDirOptions = snapshotDir !== undefined ? { snapshotDir } : {} |
| 400 | const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19) |
| 401 | const snapshotPath = getSnapshotPath(absolutePath, file, { ...snapshotDirOptions, timestamp }) |
| 402 | await fs.mkdir(path.dirname(snapshotPath), { recursive: true }) |
| 403 | |
| 404 | // Count outputs being extracted |
| 405 | let outputCount = 0 |
| 406 | for (const notebook of snapshot.project.notebooks) { |
| 407 | for (const block of notebook.blocks) { |
| 408 | const execBlock = block as { outputs?: unknown[] } |
| 409 | if (execBlock.outputs && execBlock.outputs.length > 0) { |
| 410 | outputCount++ |
| 411 | } |
| 412 | } |
| 413 | } |
| 414 | |
| 415 | // Save snapshot |
| 416 | const snapshotContent = serializeDeepnoteSnapshot(snapshot) |
| 417 | await fs.writeFile(snapshotPath, snapshotContent, 'utf-8') |
| 418 | |
| 419 | // Update latest snapshot |
| 420 | let latestPath: string | undefined |
| 421 | if (keepLatest) { |
| 422 | latestPath = getSnapshotPath(absolutePath, file, snapshotDirOptions) |
| 423 | await fs.writeFile(latestPath, snapshotContent, 'utf-8') |
| 424 | } |
| 425 | |
| 426 | // Update source file (without outputs) |
| 427 | const sourceContent = serializeDeepnoteFile(source) |
| 428 | await fs.writeFile(absolutePath, sourceContent, 'utf-8') |
| 429 | |
| 430 | return { |
| 431 | content: [ |
| 432 | { |
| 433 | type: 'text', |
| 434 | text: JSON.stringify( |
| 435 | { |
| 436 | success: true, |
| 437 | sourcePath: absolutePath, |
no test coverage detected