Skip to content

Commit b248326

Browse files
authored
feat: Export projects and notebooks. (#234)
* feat: Export projects and notebooks. * feedback
1 parent 7b7576e commit b248326

File tree

7 files changed

+1041
-75
lines changed

7 files changed

+1041
-75
lines changed

build/mocha-esm-loader.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ export async function resolve(specifier, context, nextResolve) {
6969
};
7070
}
7171

72-
// Intercept @deepnote/convert
72+
// Intercept @deepnote/convert - needed because the real package performs file I/O
73+
// that we need to control in tests
7374
if (specifier === '@deepnote/convert') {
7475
return {
7576
url: 'vscode-mock:///deepnote-convert',
@@ -306,14 +307,40 @@ export async function load(url, context, nextLoad) {
306307
};
307308
}
308309

309-
// Handle deepnote convert mock
310+
// Handle deepnote convert mock - needed because the real package performs file I/O
310311
if (moduleName === 'deepnote-convert') {
311312
return {
312313
format: 'module',
313314
source: `
314315
export const convertIpynbFilesToDeepnoteFile = async () => {
315316
// Mock implementation - does nothing in tests
316317
};
318+
319+
export const convertDeepnoteToJupyterNotebooks = (deepnoteFile) => {
320+
// Mock implementation that converts Deepnote notebooks to Jupyter format
321+
const notebooks = deepnoteFile?.project?.notebooks || [];
322+
return notebooks.map(nb => ({
323+
filename: nb.name.replace(/[<>:"/\\\\|?*]/g, '_').replace(/\\s+/g, '-') + '.ipynb',
324+
notebook: {
325+
cells: (nb.blocks || []).map(block => ({
326+
cell_type: block.type === 'markdown' ? 'markdown' : 'code',
327+
source: block.content || '',
328+
metadata: {
329+
deepnote_cell_type: block.type,
330+
cell_id: block.id
331+
},
332+
outputs: block.outputs || []
333+
})),
334+
metadata: {
335+
deepnote_notebook_id: nb.id,
336+
deepnote_notebook_name: nb.name,
337+
deepnote_execution_mode: nb.executionMode
338+
},
339+
nbformat: 4,
340+
nbformat_minor: 5
341+
}
342+
}));
343+
};
317344
`,
318345
shortCircuit: true
319346
};

package-lock.json

Lines changed: 35 additions & 67 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,18 @@
279279
"category": "Deepnote",
280280
"icon": "$(add)"
281281
},
282+
{
283+
"command": "deepnote.exportProject",
284+
"title": "%deepnote.commands.exportProject.title%",
285+
"category": "Deepnote",
286+
"icon": "$(export)"
287+
},
288+
{
289+
"command": "deepnote.exportNotebook",
290+
"title": "%deepnote.commands.exportNotebook.title%",
291+
"category": "Deepnote",
292+
"icon": "$(export)"
293+
},
282294
{
283295
"command": "dataScience.ClearCache",
284296
"title": "%deepnote.command.dataScience.clearCache.title%",
@@ -1569,12 +1581,17 @@
15691581
{
15701582
"command": "deepnote.addNotebookToProject",
15711583
"when": "view == deepnoteExplorer && viewItem == projectFile",
1572-
"group": "1_project@1"
1584+
"group": "1_add@1"
15731585
},
15741586
{
15751587
"command": "deepnote.renameProject",
15761588
"when": "view == deepnoteExplorer && viewItem == projectFile",
1577-
"group": "2_edit@1"
1589+
"group": "2_manage@1"
1590+
},
1591+
{
1592+
"command": "deepnote.exportProject",
1593+
"when": "view == deepnoteExplorer && viewItem == projectFile",
1594+
"group": "2_manage@2"
15781595
},
15791596
{
15801597
"command": "deepnote.deleteProject",
@@ -1584,12 +1601,17 @@
15841601
{
15851602
"command": "deepnote.renameNotebook",
15861603
"when": "view == deepnoteExplorer && viewItem == notebook",
1587-
"group": "2_edit@1"
1604+
"group": "1_edit@1"
15881605
},
15891606
{
15901607
"command": "deepnote.duplicateNotebook",
15911608
"when": "view == deepnoteExplorer && viewItem == notebook",
1592-
"group": "2_edit@2"
1609+
"group": "1_edit@2"
1610+
},
1611+
{
1612+
"command": "deepnote.exportNotebook",
1613+
"when": "view == deepnoteExplorer && viewItem == notebook",
1614+
"group": "2_export@1"
15931615
},
15941616
{
15951617
"command": "deepnote.deleteNotebook",
@@ -2480,7 +2502,7 @@
24802502
"dependencies": {
24812503
"@c4312/evt": "^0.1.1",
24822504
"@deepnote/blocks": "^1.3.5",
2483-
"@deepnote/convert": "^1.2.0",
2505+
"@deepnote/convert": "^1.3.0",
24842506
"@deepnote/database-integrations": "^1.3.0",
24852507
"@enonic/fnv-plus": "^1.3.0",
24862508
"@jupyter-widgets/base": "^6.0.8",

package.nls.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@
273273
"deepnote.commands.deleteNotebook.title": "Delete Notebook",
274274
"deepnote.commands.duplicateNotebook.title": "Duplicate Notebook",
275275
"deepnote.commands.addNotebookToProject.title": "Add Notebook",
276+
"deepnote.commands.exportProject.title": "Export Project...",
277+
"deepnote.commands.exportNotebook.title": "Export Notebook...",
276278
"deepnote.views.explorer.name": "Explorer",
277279
"deepnote.views.explorer.welcome": "No Deepnote notebooks found in this workspace.",
278280
"deepnote.views.environments.name": "Environments",

0 commit comments

Comments
 (0)