@deepnote/convert 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/bin.cjs +128 -56
- package/dist/bin.js +127 -57
- package/dist/index.cjs +24 -3
- package/dist/index.d.cts +313 -3
- package/dist/index.d.ts +313 -3
- package/dist/index.js +2 -2
- package/dist/{src-CWHTtGro.js → src-C0XPNDnj.js} +651 -41
- package/dist/{src-DHLflV_K.cjs → src-CrnuwKOU.cjs} +775 -39
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -192,14 +192,14 @@ await convertMarimoFilesToDeepnoteFile(["notebook.py"], {
|
|
|
192
192
|
|
|
193
193
|
```typescript
|
|
194
194
|
import {
|
|
195
|
-
|
|
195
|
+
convertDeepnoteFileToJupyterFiles,
|
|
196
196
|
convertDeepnoteFileToQuartoFiles,
|
|
197
197
|
convertDeepnoteFileToPercentFiles,
|
|
198
198
|
convertDeepnoteFileToMarimoFiles,
|
|
199
199
|
} from "@deepnote/convert";
|
|
200
200
|
|
|
201
201
|
// To Jupyter
|
|
202
|
-
await
|
|
202
|
+
await convertDeepnoteFileToJupyterFiles("project.deepnote", {
|
|
203
203
|
outputDir: "./jupyter-notebooks",
|
|
204
204
|
});
|
|
205
205
|
|
package/dist/bin.cjs
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_src = require('./src-
|
|
2
|
+
const require_src = require('./src-CrnuwKOU.cjs');
|
|
3
3
|
let cleye = require("cleye");
|
|
4
4
|
cleye = require_src.__toESM(cleye);
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
6
|
node_fs_promises = require_src.__toESM(node_fs_promises);
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
node_path = require_src.__toESM(node_path);
|
|
9
|
+
let __deepnote_blocks = require("@deepnote/blocks");
|
|
10
|
+
__deepnote_blocks = require_src.__toESM(__deepnote_blocks);
|
|
9
11
|
let chalk = require("chalk");
|
|
10
12
|
chalk = require_src.__toESM(chalk);
|
|
11
13
|
let ora = require("ora");
|
|
12
14
|
ora = require_src.__toESM(ora);
|
|
15
|
+
let yaml = require("yaml");
|
|
16
|
+
yaml = require_src.__toESM(yaml);
|
|
13
17
|
|
|
14
18
|
//#region src/cli.ts
|
|
15
19
|
async function convert(options) {
|
|
16
|
-
const { inputPath, projectName: customProjectName, outputPath: customOutputPath, cwd = process.cwd(), outputFormat = "jupyter" } = options;
|
|
20
|
+
const { inputPath, projectName: customProjectName, outputPath: customOutputPath, cwd = process.cwd(), outputFormat = "jupyter", singleFile = false } = options;
|
|
17
21
|
const resolveProjectName = (possibleName) => {
|
|
18
22
|
if (customProjectName) return customProjectName;
|
|
19
23
|
if (possibleName) return possibleName;
|
|
@@ -57,25 +61,57 @@ async function convert(options) {
|
|
|
57
61
|
}
|
|
58
62
|
const marimoFiles = results.filter((r) => r.type === "marimo").map((r) => r.file);
|
|
59
63
|
const percentFiles = results.filter((r) => r.type === "percent").map((r) => r.file);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
const directoryOptions = {
|
|
65
|
+
resolveProjectName,
|
|
66
|
+
resolveOutputPath,
|
|
67
|
+
singleFile
|
|
68
|
+
};
|
|
69
|
+
if (ipynbFiles.length > 0) return convertDirectory({
|
|
70
|
+
dirPath: absolutePath,
|
|
71
|
+
files: ipynbFiles,
|
|
72
|
+
format: "jupyter",
|
|
73
|
+
...directoryOptions
|
|
74
|
+
});
|
|
75
|
+
if (quartoFiles.length > 0) return convertDirectory({
|
|
76
|
+
dirPath: absolutePath,
|
|
77
|
+
files: quartoFiles,
|
|
78
|
+
format: "quarto",
|
|
79
|
+
...directoryOptions
|
|
80
|
+
});
|
|
81
|
+
if (marimoFiles.length > 0) return convertDirectory({
|
|
82
|
+
dirPath: absolutePath,
|
|
83
|
+
files: marimoFiles,
|
|
84
|
+
format: "marimo",
|
|
85
|
+
...directoryOptions
|
|
86
|
+
});
|
|
87
|
+
if (percentFiles.length > 0) return convertDirectory({
|
|
88
|
+
dirPath: absolutePath,
|
|
89
|
+
files: percentFiles,
|
|
90
|
+
format: "percent",
|
|
91
|
+
...directoryOptions
|
|
92
|
+
});
|
|
64
93
|
throw new Error("No supported notebook files found in the specified directory (.ipynb, .qmd, .py)");
|
|
65
94
|
}
|
|
66
95
|
const ext = (0, node_path.extname)(absolutePath).toLowerCase();
|
|
67
|
-
|
|
68
|
-
|
|
96
|
+
const fileOptions = {
|
|
97
|
+
absolutePath,
|
|
98
|
+
resolveProjectName,
|
|
99
|
+
resolveOutputPath,
|
|
100
|
+
singleFile
|
|
101
|
+
};
|
|
102
|
+
if (ext === ".ipynb") return convertJupyterToDeepnote(fileOptions);
|
|
103
|
+
if (ext === ".qmd") return convertQuartoToDeepnote(fileOptions);
|
|
69
104
|
if (ext === ".py") {
|
|
70
105
|
const content = await node_fs_promises.default.readFile(absolutePath, "utf-8");
|
|
71
|
-
if (require_src.isMarimoContent(content)) return convertMarimoToDeepnote(
|
|
72
|
-
if (require_src.isPercentContent(content)) return convertPercentToDeepnote(
|
|
106
|
+
if (require_src.isMarimoContent(content)) return convertMarimoToDeepnote(fileOptions);
|
|
107
|
+
if (require_src.isPercentContent(content)) return convertPercentToDeepnote(fileOptions);
|
|
73
108
|
throw new Error("Unsupported Python file format. File must be a percent format (# %% markers) or Marimo notebook (@app.cell decorators).");
|
|
74
109
|
}
|
|
75
110
|
if (ext === ".deepnote") return convertDeepnoteToFormat(absolutePath, outputFormat, customOutputPath, cwd);
|
|
76
111
|
throw new Error("Unsupported file type. Please provide a .ipynb, .qmd, .py (percent/marimo), or .deepnote file.");
|
|
77
112
|
}
|
|
78
|
-
async function convertDirectory(
|
|
113
|
+
async function convertDirectory(options) {
|
|
114
|
+
const { dirPath, files, format, resolveProjectName, resolveOutputPath, singleFile } = options;
|
|
79
115
|
const spinner = (0, ora.default)(`Converting ${{
|
|
80
116
|
jupyter: "Jupyter Notebooks",
|
|
81
117
|
quarto: "Quarto documents",
|
|
@@ -87,67 +123,83 @@ async function convertDirectory(dirPath, files, format, resolveProjectName, reso
|
|
|
87
123
|
const projectName = resolveProjectName(filenameWithoutExtension);
|
|
88
124
|
const outputPath = await resolveOutputPath(`${filenameWithoutExtension}.deepnote`);
|
|
89
125
|
const inputFilePaths = files.map((file) => (0, node_path.resolve)(dirPath, file));
|
|
126
|
+
let deepnoteFile;
|
|
90
127
|
switch (format) {
|
|
91
128
|
case "jupyter":
|
|
92
|
-
await require_src.
|
|
93
|
-
projectName,
|
|
94
|
-
outputPath
|
|
95
|
-
});
|
|
129
|
+
deepnoteFile = await require_src.readAndConvertIpynbFiles(inputFilePaths, { projectName });
|
|
96
130
|
break;
|
|
97
131
|
case "quarto":
|
|
98
|
-
await require_src.
|
|
99
|
-
projectName,
|
|
100
|
-
outputPath
|
|
101
|
-
});
|
|
132
|
+
deepnoteFile = await require_src.readAndConvertQuartoFiles(inputFilePaths, { projectName });
|
|
102
133
|
break;
|
|
103
134
|
case "percent":
|
|
104
|
-
await require_src.
|
|
105
|
-
projectName,
|
|
106
|
-
outputPath
|
|
107
|
-
});
|
|
135
|
+
deepnoteFile = await require_src.readAndConvertPercentFiles(inputFilePaths, { projectName });
|
|
108
136
|
break;
|
|
109
137
|
case "marimo":
|
|
110
|
-
await require_src.
|
|
111
|
-
projectName,
|
|
112
|
-
outputPath
|
|
113
|
-
});
|
|
138
|
+
deepnoteFile = await require_src.readAndConvertMarimoFiles(inputFilePaths, { projectName });
|
|
114
139
|
break;
|
|
115
140
|
}
|
|
116
|
-
|
|
141
|
+
const { snapshotPath } = await require_src.writeDeepnoteFile({
|
|
142
|
+
file: deepnoteFile,
|
|
143
|
+
outputPath,
|
|
144
|
+
projectName,
|
|
145
|
+
singleFile
|
|
146
|
+
});
|
|
147
|
+
if (snapshotPath) spinner.succeed(`The Deepnote project has been saved to ${chalk.default.bold(outputPath)}\nSnapshot saved to ${chalk.default.bold(snapshotPath)}`);
|
|
148
|
+
else spinner.succeed(`The Deepnote project has been saved to ${chalk.default.bold(outputPath)}`);
|
|
117
149
|
return outputPath;
|
|
118
150
|
} catch (error) {
|
|
119
151
|
spinner.fail("Conversion failed");
|
|
120
152
|
throw error;
|
|
121
153
|
}
|
|
122
154
|
}
|
|
123
|
-
async function convertSingleFileToDeepnote(
|
|
155
|
+
async function convertSingleFileToDeepnote(options) {
|
|
156
|
+
const { absolutePath, formatName, converter, resolveProjectName, resolveOutputPath, singleFile } = options;
|
|
124
157
|
const spinner = (0, ora.default)(`Converting the ${formatName} to a Deepnote project...`).start();
|
|
125
158
|
try {
|
|
126
159
|
const filenameWithoutExtension = (0, node_path.basename)(absolutePath, (0, node_path.extname)(absolutePath));
|
|
127
160
|
const projectName = resolveProjectName(filenameWithoutExtension);
|
|
128
161
|
const outputPath = await resolveOutputPath(`${filenameWithoutExtension}.deepnote`);
|
|
129
|
-
await
|
|
162
|
+
const { snapshotPath } = await require_src.writeDeepnoteFile({
|
|
163
|
+
file: await converter([absolutePath], { projectName }),
|
|
164
|
+
outputPath,
|
|
130
165
|
projectName,
|
|
131
|
-
|
|
166
|
+
singleFile
|
|
132
167
|
});
|
|
133
|
-
spinner.succeed(`The Deepnote project has been saved to ${chalk.default.bold(outputPath)}`);
|
|
168
|
+
if (snapshotPath) spinner.succeed(`The Deepnote project has been saved to ${chalk.default.bold(outputPath)}\nSnapshot saved to ${chalk.default.bold(snapshotPath)}`);
|
|
169
|
+
else spinner.succeed(`The Deepnote project has been saved to ${chalk.default.bold(outputPath)}`);
|
|
134
170
|
return outputPath;
|
|
135
171
|
} catch (error) {
|
|
136
172
|
spinner.fail("Conversion failed");
|
|
137
173
|
throw error;
|
|
138
174
|
}
|
|
139
175
|
}
|
|
140
|
-
function convertJupyterToDeepnote(
|
|
141
|
-
return convertSingleFileToDeepnote(
|
|
176
|
+
function convertJupyterToDeepnote(options) {
|
|
177
|
+
return convertSingleFileToDeepnote({
|
|
178
|
+
...options,
|
|
179
|
+
formatName: "Jupyter Notebook",
|
|
180
|
+
converter: require_src.readAndConvertIpynbFiles
|
|
181
|
+
});
|
|
142
182
|
}
|
|
143
|
-
function convertQuartoToDeepnote(
|
|
144
|
-
return convertSingleFileToDeepnote(
|
|
183
|
+
function convertQuartoToDeepnote(options) {
|
|
184
|
+
return convertSingleFileToDeepnote({
|
|
185
|
+
...options,
|
|
186
|
+
formatName: "Quarto document",
|
|
187
|
+
converter: require_src.readAndConvertQuartoFiles
|
|
188
|
+
});
|
|
145
189
|
}
|
|
146
|
-
function convertPercentToDeepnote(
|
|
147
|
-
return convertSingleFileToDeepnote(
|
|
190
|
+
function convertPercentToDeepnote(options) {
|
|
191
|
+
return convertSingleFileToDeepnote({
|
|
192
|
+
...options,
|
|
193
|
+
formatName: "percent format notebook",
|
|
194
|
+
converter: require_src.readAndConvertPercentFiles
|
|
195
|
+
});
|
|
148
196
|
}
|
|
149
|
-
function convertMarimoToDeepnote(
|
|
150
|
-
return convertSingleFileToDeepnote(
|
|
197
|
+
function convertMarimoToDeepnote(options) {
|
|
198
|
+
return convertSingleFileToDeepnote({
|
|
199
|
+
...options,
|
|
200
|
+
formatName: "Marimo notebook",
|
|
201
|
+
converter: require_src.readAndConvertMarimoFiles
|
|
202
|
+
});
|
|
151
203
|
}
|
|
152
204
|
async function convertDeepnoteToFormat(absolutePath, outputFormat, customOutputPath, cwd) {
|
|
153
205
|
const formatNames = {
|
|
@@ -158,21 +210,35 @@ async function convertDeepnoteToFormat(absolutePath, outputFormat, customOutputP
|
|
|
158
210
|
};
|
|
159
211
|
const spinner = (0, ora.default)(`Converting Deepnote project to ${formatNames[outputFormat]}...`).start();
|
|
160
212
|
try {
|
|
161
|
-
const
|
|
162
|
-
const outputDir = customOutputPath ? (0, node_path.resolve)(cwd, customOutputPath) : (0, node_path.resolve)(cwd,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
213
|
+
const filenameWithoutExtension = (0, node_path.basename)(absolutePath, (0, node_path.extname)(absolutePath));
|
|
214
|
+
const outputDir = customOutputPath ? (0, node_path.resolve)(cwd, customOutputPath) : (0, node_path.resolve)(cwd, filenameWithoutExtension);
|
|
215
|
+
let deepnoteFile = (0, __deepnote_blocks.deserializeDeepnoteFile)(await node_fs_promises.default.readFile(absolutePath, "utf-8"));
|
|
216
|
+
const snapshot = await require_src.loadLatestSnapshot(absolutePath, deepnoteFile.project.id);
|
|
217
|
+
if (snapshot) deepnoteFile = require_src.mergeSnapshotIntoSource(deepnoteFile, snapshot, { skipMismatched: true });
|
|
218
|
+
const tempDir = await node_fs_promises.default.mkdtemp((0, node_path.resolve)((0, node_path.dirname)(absolutePath), ".deepnote-merge-"));
|
|
219
|
+
const tempPath = (0, node_path.resolve)(tempDir, `${filenameWithoutExtension}.merged.deepnote`);
|
|
220
|
+
try {
|
|
221
|
+
const mergedYaml = (0, yaml.stringify)(deepnoteFile);
|
|
222
|
+
await node_fs_promises.default.writeFile(tempPath, mergedYaml, "utf-8");
|
|
223
|
+
switch (outputFormat) {
|
|
224
|
+
case "jupyter":
|
|
225
|
+
await require_src.convertDeepnoteFileToJupyterFiles(tempPath, { outputDir });
|
|
226
|
+
break;
|
|
227
|
+
case "percent":
|
|
228
|
+
await require_src.convertDeepnoteFileToPercentFiles(tempPath, { outputDir });
|
|
229
|
+
break;
|
|
230
|
+
case "quarto":
|
|
231
|
+
await require_src.convertDeepnoteFileToQuartoFiles(tempPath, { outputDir });
|
|
232
|
+
break;
|
|
233
|
+
case "marimo":
|
|
234
|
+
await require_src.convertDeepnoteFileToMarimoFiles(tempPath, { outputDir });
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
} finally {
|
|
238
|
+
await node_fs_promises.default.rm(tempDir, {
|
|
239
|
+
recursive: true,
|
|
240
|
+
force: true
|
|
241
|
+
}).catch(() => {});
|
|
176
242
|
}
|
|
177
243
|
spinner.succeed(`${formatNames[outputFormat]} have been saved to ${chalk.default.bold(outputDir)}`);
|
|
178
244
|
return outputDir;
|
|
@@ -201,6 +267,11 @@ async function main() {
|
|
|
201
267
|
cwd: {
|
|
202
268
|
description: "The working directory to resolve paths relative to.",
|
|
203
269
|
type: String
|
|
270
|
+
},
|
|
271
|
+
singleFile: {
|
|
272
|
+
description: "Output a single file with outputs included (disables snapshot mode).",
|
|
273
|
+
type: Boolean,
|
|
274
|
+
default: false
|
|
204
275
|
}
|
|
205
276
|
}
|
|
206
277
|
});
|
|
@@ -208,7 +279,8 @@ async function main() {
|
|
|
208
279
|
inputPath: argv._.path,
|
|
209
280
|
projectName: argv.flags.projectName,
|
|
210
281
|
outputPath: argv.flags.outputPath,
|
|
211
|
-
cwd: argv.flags.cwd ?? process.cwd()
|
|
282
|
+
cwd: argv.flags.cwd ?? process.cwd(),
|
|
283
|
+
singleFile: argv.flags.singleFile
|
|
212
284
|
});
|
|
213
285
|
}
|
|
214
286
|
if (process.env.NODE_ENV !== "test" && process.env.VITEST !== "true") main().catch((error) => {
|
package/dist/bin.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { G as convertDeepnoteFileToPercentFiles, I as readAndConvertIpynbFiles, R as isMarimoContent, S as mergeSnapshotIntoSource, T as loadLatestSnapshot, V as convertDeepnoteFileToQuartoFiles, Y as convertDeepnoteFileToMarimoFiles, d as readAndConvertPercentFiles, et as convertDeepnoteFileToJupyterFiles, g as readAndConvertMarimoFiles, o as readAndConvertQuartoFiles, t as writeDeepnoteFile, z as isPercentContent } from "./src-C0XPNDnj.js";
|
|
3
3
|
import { cli } from "cleye";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
|
-
import { basename, extname, resolve } from "node:path";
|
|
5
|
+
import { basename, dirname, extname, resolve } from "node:path";
|
|
6
|
+
import { deserializeDeepnoteFile } from "@deepnote/blocks";
|
|
6
7
|
import chalk from "chalk";
|
|
7
8
|
import ora from "ora";
|
|
9
|
+
import { stringify } from "yaml";
|
|
8
10
|
|
|
9
11
|
//#region src/cli.ts
|
|
10
12
|
async function convert(options) {
|
|
11
|
-
const { inputPath, projectName: customProjectName, outputPath: customOutputPath, cwd = process.cwd(), outputFormat = "jupyter" } = options;
|
|
13
|
+
const { inputPath, projectName: customProjectName, outputPath: customOutputPath, cwd = process.cwd(), outputFormat = "jupyter", singleFile = false } = options;
|
|
12
14
|
const resolveProjectName = (possibleName) => {
|
|
13
15
|
if (customProjectName) return customProjectName;
|
|
14
16
|
if (possibleName) return possibleName;
|
|
@@ -52,25 +54,57 @@ async function convert(options) {
|
|
|
52
54
|
}
|
|
53
55
|
const marimoFiles = results.filter((r) => r.type === "marimo").map((r) => r.file);
|
|
54
56
|
const percentFiles = results.filter((r) => r.type === "percent").map((r) => r.file);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
const directoryOptions = {
|
|
58
|
+
resolveProjectName,
|
|
59
|
+
resolveOutputPath,
|
|
60
|
+
singleFile
|
|
61
|
+
};
|
|
62
|
+
if (ipynbFiles.length > 0) return convertDirectory({
|
|
63
|
+
dirPath: absolutePath,
|
|
64
|
+
files: ipynbFiles,
|
|
65
|
+
format: "jupyter",
|
|
66
|
+
...directoryOptions
|
|
67
|
+
});
|
|
68
|
+
if (quartoFiles.length > 0) return convertDirectory({
|
|
69
|
+
dirPath: absolutePath,
|
|
70
|
+
files: quartoFiles,
|
|
71
|
+
format: "quarto",
|
|
72
|
+
...directoryOptions
|
|
73
|
+
});
|
|
74
|
+
if (marimoFiles.length > 0) return convertDirectory({
|
|
75
|
+
dirPath: absolutePath,
|
|
76
|
+
files: marimoFiles,
|
|
77
|
+
format: "marimo",
|
|
78
|
+
...directoryOptions
|
|
79
|
+
});
|
|
80
|
+
if (percentFiles.length > 0) return convertDirectory({
|
|
81
|
+
dirPath: absolutePath,
|
|
82
|
+
files: percentFiles,
|
|
83
|
+
format: "percent",
|
|
84
|
+
...directoryOptions
|
|
85
|
+
});
|
|
59
86
|
throw new Error("No supported notebook files found in the specified directory (.ipynb, .qmd, .py)");
|
|
60
87
|
}
|
|
61
88
|
const ext = extname(absolutePath).toLowerCase();
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
const fileOptions = {
|
|
90
|
+
absolutePath,
|
|
91
|
+
resolveProjectName,
|
|
92
|
+
resolveOutputPath,
|
|
93
|
+
singleFile
|
|
94
|
+
};
|
|
95
|
+
if (ext === ".ipynb") return convertJupyterToDeepnote(fileOptions);
|
|
96
|
+
if (ext === ".qmd") return convertQuartoToDeepnote(fileOptions);
|
|
64
97
|
if (ext === ".py") {
|
|
65
98
|
const content = await fs.readFile(absolutePath, "utf-8");
|
|
66
|
-
if (isMarimoContent(content)) return convertMarimoToDeepnote(
|
|
67
|
-
if (isPercentContent(content)) return convertPercentToDeepnote(
|
|
99
|
+
if (isMarimoContent(content)) return convertMarimoToDeepnote(fileOptions);
|
|
100
|
+
if (isPercentContent(content)) return convertPercentToDeepnote(fileOptions);
|
|
68
101
|
throw new Error("Unsupported Python file format. File must be a percent format (# %% markers) or Marimo notebook (@app.cell decorators).");
|
|
69
102
|
}
|
|
70
103
|
if (ext === ".deepnote") return convertDeepnoteToFormat(absolutePath, outputFormat, customOutputPath, cwd);
|
|
71
104
|
throw new Error("Unsupported file type. Please provide a .ipynb, .qmd, .py (percent/marimo), or .deepnote file.");
|
|
72
105
|
}
|
|
73
|
-
async function convertDirectory(
|
|
106
|
+
async function convertDirectory(options) {
|
|
107
|
+
const { dirPath, files, format, resolveProjectName, resolveOutputPath, singleFile } = options;
|
|
74
108
|
const spinner = ora(`Converting ${{
|
|
75
109
|
jupyter: "Jupyter Notebooks",
|
|
76
110
|
quarto: "Quarto documents",
|
|
@@ -82,67 +116,83 @@ async function convertDirectory(dirPath, files, format, resolveProjectName, reso
|
|
|
82
116
|
const projectName = resolveProjectName(filenameWithoutExtension);
|
|
83
117
|
const outputPath = await resolveOutputPath(`${filenameWithoutExtension}.deepnote`);
|
|
84
118
|
const inputFilePaths = files.map((file) => resolve(dirPath, file));
|
|
119
|
+
let deepnoteFile;
|
|
85
120
|
switch (format) {
|
|
86
121
|
case "jupyter":
|
|
87
|
-
await
|
|
88
|
-
projectName,
|
|
89
|
-
outputPath
|
|
90
|
-
});
|
|
122
|
+
deepnoteFile = await readAndConvertIpynbFiles(inputFilePaths, { projectName });
|
|
91
123
|
break;
|
|
92
124
|
case "quarto":
|
|
93
|
-
await
|
|
94
|
-
projectName,
|
|
95
|
-
outputPath
|
|
96
|
-
});
|
|
125
|
+
deepnoteFile = await readAndConvertQuartoFiles(inputFilePaths, { projectName });
|
|
97
126
|
break;
|
|
98
127
|
case "percent":
|
|
99
|
-
await
|
|
100
|
-
projectName,
|
|
101
|
-
outputPath
|
|
102
|
-
});
|
|
128
|
+
deepnoteFile = await readAndConvertPercentFiles(inputFilePaths, { projectName });
|
|
103
129
|
break;
|
|
104
130
|
case "marimo":
|
|
105
|
-
await
|
|
106
|
-
projectName,
|
|
107
|
-
outputPath
|
|
108
|
-
});
|
|
131
|
+
deepnoteFile = await readAndConvertMarimoFiles(inputFilePaths, { projectName });
|
|
109
132
|
break;
|
|
110
133
|
}
|
|
111
|
-
|
|
134
|
+
const { snapshotPath } = await writeDeepnoteFile({
|
|
135
|
+
file: deepnoteFile,
|
|
136
|
+
outputPath,
|
|
137
|
+
projectName,
|
|
138
|
+
singleFile
|
|
139
|
+
});
|
|
140
|
+
if (snapshotPath) spinner.succeed(`The Deepnote project has been saved to ${chalk.bold(outputPath)}\nSnapshot saved to ${chalk.bold(snapshotPath)}`);
|
|
141
|
+
else spinner.succeed(`The Deepnote project has been saved to ${chalk.bold(outputPath)}`);
|
|
112
142
|
return outputPath;
|
|
113
143
|
} catch (error) {
|
|
114
144
|
spinner.fail("Conversion failed");
|
|
115
145
|
throw error;
|
|
116
146
|
}
|
|
117
147
|
}
|
|
118
|
-
async function convertSingleFileToDeepnote(
|
|
148
|
+
async function convertSingleFileToDeepnote(options) {
|
|
149
|
+
const { absolutePath, formatName, converter, resolveProjectName, resolveOutputPath, singleFile } = options;
|
|
119
150
|
const spinner = ora(`Converting the ${formatName} to a Deepnote project...`).start();
|
|
120
151
|
try {
|
|
121
152
|
const filenameWithoutExtension = basename(absolutePath, extname(absolutePath));
|
|
122
153
|
const projectName = resolveProjectName(filenameWithoutExtension);
|
|
123
154
|
const outputPath = await resolveOutputPath(`${filenameWithoutExtension}.deepnote`);
|
|
124
|
-
await
|
|
155
|
+
const { snapshotPath } = await writeDeepnoteFile({
|
|
156
|
+
file: await converter([absolutePath], { projectName }),
|
|
157
|
+
outputPath,
|
|
125
158
|
projectName,
|
|
126
|
-
|
|
159
|
+
singleFile
|
|
127
160
|
});
|
|
128
|
-
spinner.succeed(`The Deepnote project has been saved to ${chalk.bold(outputPath)}`);
|
|
161
|
+
if (snapshotPath) spinner.succeed(`The Deepnote project has been saved to ${chalk.bold(outputPath)}\nSnapshot saved to ${chalk.bold(snapshotPath)}`);
|
|
162
|
+
else spinner.succeed(`The Deepnote project has been saved to ${chalk.bold(outputPath)}`);
|
|
129
163
|
return outputPath;
|
|
130
164
|
} catch (error) {
|
|
131
165
|
spinner.fail("Conversion failed");
|
|
132
166
|
throw error;
|
|
133
167
|
}
|
|
134
168
|
}
|
|
135
|
-
function convertJupyterToDeepnote(
|
|
136
|
-
return convertSingleFileToDeepnote(
|
|
169
|
+
function convertJupyterToDeepnote(options) {
|
|
170
|
+
return convertSingleFileToDeepnote({
|
|
171
|
+
...options,
|
|
172
|
+
formatName: "Jupyter Notebook",
|
|
173
|
+
converter: readAndConvertIpynbFiles
|
|
174
|
+
});
|
|
137
175
|
}
|
|
138
|
-
function convertQuartoToDeepnote(
|
|
139
|
-
return convertSingleFileToDeepnote(
|
|
176
|
+
function convertQuartoToDeepnote(options) {
|
|
177
|
+
return convertSingleFileToDeepnote({
|
|
178
|
+
...options,
|
|
179
|
+
formatName: "Quarto document",
|
|
180
|
+
converter: readAndConvertQuartoFiles
|
|
181
|
+
});
|
|
140
182
|
}
|
|
141
|
-
function convertPercentToDeepnote(
|
|
142
|
-
return convertSingleFileToDeepnote(
|
|
183
|
+
function convertPercentToDeepnote(options) {
|
|
184
|
+
return convertSingleFileToDeepnote({
|
|
185
|
+
...options,
|
|
186
|
+
formatName: "percent format notebook",
|
|
187
|
+
converter: readAndConvertPercentFiles
|
|
188
|
+
});
|
|
143
189
|
}
|
|
144
|
-
function convertMarimoToDeepnote(
|
|
145
|
-
return convertSingleFileToDeepnote(
|
|
190
|
+
function convertMarimoToDeepnote(options) {
|
|
191
|
+
return convertSingleFileToDeepnote({
|
|
192
|
+
...options,
|
|
193
|
+
formatName: "Marimo notebook",
|
|
194
|
+
converter: readAndConvertMarimoFiles
|
|
195
|
+
});
|
|
146
196
|
}
|
|
147
197
|
async function convertDeepnoteToFormat(absolutePath, outputFormat, customOutputPath, cwd) {
|
|
148
198
|
const formatNames = {
|
|
@@ -153,21 +203,35 @@ async function convertDeepnoteToFormat(absolutePath, outputFormat, customOutputP
|
|
|
153
203
|
};
|
|
154
204
|
const spinner = ora(`Converting Deepnote project to ${formatNames[outputFormat]}...`).start();
|
|
155
205
|
try {
|
|
156
|
-
const
|
|
157
|
-
const outputDir = customOutputPath ? resolve(cwd, customOutputPath) : resolve(cwd,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
206
|
+
const filenameWithoutExtension = basename(absolutePath, extname(absolutePath));
|
|
207
|
+
const outputDir = customOutputPath ? resolve(cwd, customOutputPath) : resolve(cwd, filenameWithoutExtension);
|
|
208
|
+
let deepnoteFile = deserializeDeepnoteFile(await fs.readFile(absolutePath, "utf-8"));
|
|
209
|
+
const snapshot = await loadLatestSnapshot(absolutePath, deepnoteFile.project.id);
|
|
210
|
+
if (snapshot) deepnoteFile = mergeSnapshotIntoSource(deepnoteFile, snapshot, { skipMismatched: true });
|
|
211
|
+
const tempDir = await fs.mkdtemp(resolve(dirname(absolutePath), ".deepnote-merge-"));
|
|
212
|
+
const tempPath = resolve(tempDir, `${filenameWithoutExtension}.merged.deepnote`);
|
|
213
|
+
try {
|
|
214
|
+
const mergedYaml = stringify(deepnoteFile);
|
|
215
|
+
await fs.writeFile(tempPath, mergedYaml, "utf-8");
|
|
216
|
+
switch (outputFormat) {
|
|
217
|
+
case "jupyter":
|
|
218
|
+
await convertDeepnoteFileToJupyterFiles(tempPath, { outputDir });
|
|
219
|
+
break;
|
|
220
|
+
case "percent":
|
|
221
|
+
await convertDeepnoteFileToPercentFiles(tempPath, { outputDir });
|
|
222
|
+
break;
|
|
223
|
+
case "quarto":
|
|
224
|
+
await convertDeepnoteFileToQuartoFiles(tempPath, { outputDir });
|
|
225
|
+
break;
|
|
226
|
+
case "marimo":
|
|
227
|
+
await convertDeepnoteFileToMarimoFiles(tempPath, { outputDir });
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
} finally {
|
|
231
|
+
await fs.rm(tempDir, {
|
|
232
|
+
recursive: true,
|
|
233
|
+
force: true
|
|
234
|
+
}).catch(() => {});
|
|
171
235
|
}
|
|
172
236
|
spinner.succeed(`${formatNames[outputFormat]} have been saved to ${chalk.bold(outputDir)}`);
|
|
173
237
|
return outputDir;
|
|
@@ -196,6 +260,11 @@ async function main() {
|
|
|
196
260
|
cwd: {
|
|
197
261
|
description: "The working directory to resolve paths relative to.",
|
|
198
262
|
type: String
|
|
263
|
+
},
|
|
264
|
+
singleFile: {
|
|
265
|
+
description: "Output a single file with outputs included (disables snapshot mode).",
|
|
266
|
+
type: Boolean,
|
|
267
|
+
default: false
|
|
199
268
|
}
|
|
200
269
|
}
|
|
201
270
|
});
|
|
@@ -203,7 +272,8 @@ async function main() {
|
|
|
203
272
|
inputPath: argv._.path,
|
|
204
273
|
projectName: argv.flags.projectName,
|
|
205
274
|
outputPath: argv.flags.outputPath,
|
|
206
|
-
cwd: argv.flags.cwd ?? process.cwd()
|
|
275
|
+
cwd: argv.flags.cwd ?? process.cwd(),
|
|
276
|
+
singleFile: argv.flags.singleFile
|
|
207
277
|
});
|
|
208
278
|
}
|
|
209
279
|
if (process.env.NODE_ENV !== "test" && process.env.VITEST !== "true") main().catch((error) => {
|
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
const require_src = require('./src-
|
|
1
|
+
const require_src = require('./src-CrnuwKOU.cjs');
|
|
2
2
|
|
|
3
|
+
exports.addContentHashes = require_src.addContentHashes;
|
|
4
|
+
exports.computeContentHash = require_src.computeContentHash;
|
|
5
|
+
exports.computeSnapshotHash = require_src.computeSnapshotHash;
|
|
3
6
|
exports.convertBlockToJupyterCell = require_src.convertBlockToJupyterCell;
|
|
4
7
|
exports.convertBlocksToJupyterNotebook = require_src.convertBlocksToJupyterNotebook;
|
|
5
8
|
exports.convertBlocksToMarimoApp = require_src.convertBlocksToMarimoApp;
|
|
6
9
|
exports.convertBlocksToPercentNotebook = require_src.convertBlocksToPercentNotebook;
|
|
7
10
|
exports.convertBlocksToQuartoDocument = require_src.convertBlocksToQuartoDocument;
|
|
8
|
-
exports.
|
|
11
|
+
exports.convertDeepnoteFileToJupyterFiles = require_src.convertDeepnoteFileToJupyterFiles;
|
|
9
12
|
exports.convertDeepnoteFileToMarimoFiles = require_src.convertDeepnoteFileToMarimoFiles;
|
|
10
13
|
exports.convertDeepnoteFileToPercentFiles = require_src.convertDeepnoteFileToPercentFiles;
|
|
11
14
|
exports.convertDeepnoteFileToQuartoFiles = require_src.convertDeepnoteFileToQuartoFiles;
|
|
@@ -25,10 +28,28 @@ exports.convertPercentNotebooksToDeepnote = require_src.convertPercentNotebooksT
|
|
|
25
28
|
exports.convertQuartoDocumentToBlocks = require_src.convertQuartoDocumentToBlocks;
|
|
26
29
|
exports.convertQuartoDocumentsToDeepnote = require_src.convertQuartoDocumentsToDeepnote;
|
|
27
30
|
exports.convertQuartoFilesToDeepnoteFile = require_src.convertQuartoFilesToDeepnoteFile;
|
|
31
|
+
exports.countBlocksWithOutputs = require_src.countBlocksWithOutputs;
|
|
28
32
|
exports.detectFormat = require_src.detectFormat;
|
|
33
|
+
exports.findSnapshotsForProject = require_src.findSnapshotsForProject;
|
|
34
|
+
exports.generateSnapshotFilename = require_src.generateSnapshotFilename;
|
|
35
|
+
exports.getSnapshotDir = require_src.getSnapshotDir;
|
|
36
|
+
exports.hasOutputs = require_src.hasOutputs;
|
|
37
|
+
exports.loadLatestSnapshot = require_src.loadLatestSnapshot;
|
|
38
|
+
exports.loadSnapshotFile = require_src.loadSnapshotFile;
|
|
39
|
+
exports.mergeSnapshotIntoSource = require_src.mergeSnapshotIntoSource;
|
|
29
40
|
exports.parseMarimoFormat = require_src.parseMarimoFormat;
|
|
30
41
|
exports.parsePercentFormat = require_src.parsePercentFormat;
|
|
31
42
|
exports.parseQuartoFormat = require_src.parseQuartoFormat;
|
|
43
|
+
exports.parseSnapshotFilename = require_src.parseSnapshotFilename;
|
|
44
|
+
exports.parseSourceFilePath = require_src.parseSourceFilePath;
|
|
45
|
+
exports.readAndConvertIpynbFiles = require_src.readAndConvertIpynbFiles;
|
|
46
|
+
exports.readAndConvertMarimoFiles = require_src.readAndConvertMarimoFiles;
|
|
47
|
+
exports.readAndConvertPercentFiles = require_src.readAndConvertPercentFiles;
|
|
48
|
+
exports.readAndConvertQuartoFiles = require_src.readAndConvertQuartoFiles;
|
|
32
49
|
exports.serializeMarimoFormat = require_src.serializeMarimoFormat;
|
|
33
50
|
exports.serializePercentFormat = require_src.serializePercentFormat;
|
|
34
|
-
exports.serializeQuartoFormat = require_src.serializeQuartoFormat;
|
|
51
|
+
exports.serializeQuartoFormat = require_src.serializeQuartoFormat;
|
|
52
|
+
exports.slugifyProjectName = require_src.slugifyProjectName;
|
|
53
|
+
exports.snapshotExists = require_src.snapshotExists;
|
|
54
|
+
exports.splitDeepnoteFile = require_src.splitDeepnoteFile;
|
|
55
|
+
exports.writeDeepnoteFile = require_src.writeDeepnoteFile;
|