@deepnote/blocks 1.3.6 → 2.0.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/dist/index.cjs CHANGED
@@ -30,9 +30,12 @@ ts_dedent = __toESM(ts_dedent);
30
30
 
31
31
  //#region src/deserialize-file/deepnote-file-schema.ts
32
32
  const deepnoteBlockSchema = zod.z.object({
33
- blockGroup: zod.z.string().optional(),
33
+ blockGroup: zod.z.string(),
34
34
  content: zod.z.string().optional(),
35
+ contentHash: zod.z.string().regex(/^(md5|sha256):[a-f0-9]+$/i).optional(),
35
36
  executionCount: zod.z.number().optional(),
37
+ executionFinishedAt: zod.z.string().datetime().optional(),
38
+ executionStartedAt: zod.z.string().datetime().optional(),
36
39
  id: zod.z.string(),
37
40
  metadata: zod.z.record(zod.z.any()).optional(),
38
41
  outputs: zod.z.array(zod.z.any()).optional(),
@@ -40,7 +43,49 @@ const deepnoteBlockSchema = zod.z.object({
40
43
  type: zod.z.string(),
41
44
  version: zod.z.number().optional()
42
45
  });
46
+ const environmentSchema = zod.z.object({
47
+ customImage: zod.z.string().optional(),
48
+ hash: zod.z.string().optional(),
49
+ packages: zod.z.record(zod.z.string()).optional(),
50
+ platform: zod.z.string().optional(),
51
+ python: zod.z.object({
52
+ environment: zod.z.enum([
53
+ "uv",
54
+ "conda",
55
+ "venv",
56
+ "poetry",
57
+ "system"
58
+ ]).optional(),
59
+ version: zod.z.string().optional()
60
+ }).optional()
61
+ }).optional();
62
+ const executionSummarySchema = zod.z.object({
63
+ blocksExecuted: zod.z.number().int().nonnegative().optional(),
64
+ blocksFailed: zod.z.number().int().nonnegative().optional(),
65
+ blocksSucceeded: zod.z.number().int().nonnegative().optional(),
66
+ totalDurationMs: zod.z.number().nonnegative().optional()
67
+ }).optional();
68
+ const executionErrorSchema = zod.z.object({
69
+ message: zod.z.string().optional(),
70
+ name: zod.z.string().optional(),
71
+ traceback: zod.z.array(zod.z.string()).optional()
72
+ }).optional();
73
+ const executionSchema = zod.z.object({
74
+ error: executionErrorSchema,
75
+ finishedAt: zod.z.string().datetime().optional(),
76
+ inputs: zod.z.record(zod.z.unknown()).optional(),
77
+ startedAt: zod.z.string().datetime().optional(),
78
+ summary: executionSummarySchema,
79
+ triggeredBy: zod.z.enum([
80
+ "user",
81
+ "schedule",
82
+ "api",
83
+ "ci"
84
+ ]).optional()
85
+ }).optional();
43
86
  const deepnoteFileSchema = zod.z.object({
87
+ environment: environmentSchema,
88
+ execution: executionSchema,
44
89
  metadata: zod.z.object({
45
90
  checksum: zod.z.string().optional(),
46
91
  createdAt: zod.z.string(),
@@ -78,9 +123,88 @@ const deepnoteFileSchema = zod.z.object({
78
123
 
79
124
  //#endregion
80
125
  //#region src/deserialize-file/parse-yaml.ts
126
+ /**
127
+ * Validates UTF-8 encoding from raw bytes before decoding to string.
128
+ * This is the proper way to validate UTF-8 - check BEFORE decoding.
129
+ *
130
+ * @param bytes - Raw file bytes as Uint8Array
131
+ * @returns Decoded UTF-8 string without BOM
132
+ * @throws Error if BOM detected or invalid UTF-8 encoding
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const bytes = await fs.readFile('file.deepnote') // Returns Buffer/Uint8Array
137
+ * const yamlContent = decodeUtf8NoBom(bytes)
138
+ * const parsed = parseYaml(yamlContent)
139
+ * ```
140
+ */
141
+ function decodeUtf8NoBom(bytes) {
142
+ if (bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) throw new Error("UTF-8 BOM detected in Deepnote file - files must be UTF-8 without BOM");
143
+ try {
144
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
145
+ } catch {
146
+ throw new Error("Invalid UTF-8 encoding detected in Deepnote file");
147
+ }
148
+ }
149
+ /**
150
+ * Validates that a string doesn't start with BOM.
151
+ * Note: This is a fallback when only a string is available.
152
+ * By the time we have a JS string, invalid UTF-8 has already been handled during decoding.
153
+ * For proper UTF-8 validation, use decodeUtf8NoBom() on raw bytes before decoding.
154
+ *
155
+ * @param yamlContent - Already-decoded YAML string
156
+ * @throws Error if BOM prefix detected
157
+ */
158
+ function validateNoBomPrefix(yamlContent) {
159
+ if (yamlContent.charCodeAt(0) === 65279) throw new Error("UTF-8 BOM detected in Deepnote file - files must be UTF-8 without BOM");
160
+ }
161
+ /**
162
+ * Validates that the YAML document doesn't contain prohibited features:
163
+ * - No anchors/aliases (&anchor, *alias)
164
+ * - No merge keys (<<)
165
+ * - No custom tags (!tag)
166
+ */
167
+ function validateYamlStructure(yamlContent) {
168
+ if (/(?:^|\n)\s*(?:-\s+|[\w-]+:\s*)&\w+/.test(yamlContent)) throw new Error("YAML anchors (&) are not allowed in Deepnote files");
169
+ if (/(?:^|\n)\s*(?:-\s+|[\w-]+:\s*)\*\w+/.test(yamlContent)) throw new Error("YAML aliases (*) are not allowed in Deepnote files");
170
+ if (/<<:/.test(yamlContent)) throw new Error("YAML merge keys (<<) are not allowed in Deepnote files");
171
+ const matches = yamlContent.match(/(?:^|\n)\s*(?:-\s+|[\w-]+:\s*)(![\w/-]+)/gm);
172
+ if (matches) {
173
+ const tags = matches.map((m) => m.match(/(![\w/-]+)/)?.[1]).filter(Boolean);
174
+ if (tags.length > 0) throw new Error(`YAML tags are not allowed in Deepnote files: ${tags.join(", ")}`);
175
+ }
176
+ }
177
+ /**
178
+ * Parse and validate YAML document in a single pass.
179
+ * Checks for duplicate keys and other parsing errors, then converts to JavaScript object.
180
+ */
181
+ function parseAndValidate(yamlContent) {
182
+ const doc = (0, yaml.parseDocument)(yamlContent, {
183
+ strict: true,
184
+ uniqueKeys: true,
185
+ version: "1.2"
186
+ });
187
+ if (doc.errors.length > 0) {
188
+ const duplicateKeyError = doc.errors.find((err) => err.message.includes("duplicate") || err.message.includes("key"));
189
+ if (duplicateKeyError) throw new Error(`Duplicate keys detected in Deepnote file: ${duplicateKeyError.message}`);
190
+ throw new Error(`YAML parsing error: ${doc.errors[0].message}`);
191
+ }
192
+ return doc.toJS();
193
+ }
194
+ /**
195
+ * Parse YAML content with strict validation rules:
196
+ * - YAML 1.2 only
197
+ * - UTF-8 only
198
+ * - No duplicate keys
199
+ * - No anchors/aliases/merge keys
200
+ * - No custom tags
201
+ * - Explicit typing enforced by schema
202
+ */
81
203
  function parseYaml(yamlContent) {
82
204
  try {
83
- return (0, yaml.parse)(yamlContent);
205
+ validateNoBomPrefix(yamlContent);
206
+ validateYamlStructure(yamlContent);
207
+ return parseAndValidate(yamlContent);
84
208
  } catch (error) {
85
209
  const message = error instanceof Error ? error.message : String(error);
86
210
  throw new Error(`Failed to parse Deepnote file: ${message}`);
@@ -593,7 +717,12 @@ function createPythonCode(block, executionContext) {
593
717
  //#endregion
594
718
  exports.createMarkdown = createMarkdown;
595
719
  exports.createPythonCode = createPythonCode;
720
+ exports.decodeUtf8NoBom = decodeUtf8NoBom;
596
721
  exports.deepnoteBlockSchema = deepnoteBlockSchema;
597
722
  exports.deepnoteFileSchema = deepnoteFileSchema;
598
723
  exports.deserializeDeepnoteFile = deserializeDeepnoteFile;
724
+ exports.environmentSchema = environmentSchema;
725
+ exports.executionErrorSchema = executionErrorSchema;
726
+ exports.executionSchema = executionSchema;
727
+ exports.executionSummarySchema = executionSummarySchema;
599
728
  exports.stripMarkdown = stripMarkdown;
package/dist/index.d.cts CHANGED
@@ -28,9 +28,12 @@ interface TableState {
28
28
  //#endregion
29
29
  //#region src/deserialize-file/deepnote-file-schema.d.ts
30
30
  declare const deepnoteBlockSchema: z.ZodObject<{
31
- blockGroup: z.ZodOptional<z.ZodString>;
31
+ blockGroup: z.ZodString;
32
32
  content: z.ZodOptional<z.ZodString>;
33
+ contentHash: z.ZodOptional<z.ZodString>;
33
34
  executionCount: z.ZodOptional<z.ZodNumber>;
35
+ executionFinishedAt: z.ZodOptional<z.ZodString>;
36
+ executionStartedAt: z.ZodOptional<z.ZodString>;
34
37
  id: z.ZodString;
35
38
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
36
39
  outputs: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
@@ -38,28 +41,269 @@ declare const deepnoteBlockSchema: z.ZodObject<{
38
41
  type: z.ZodString;
39
42
  version: z.ZodOptional<z.ZodNumber>;
40
43
  }, "strip", z.ZodTypeAny, {
44
+ blockGroup: string;
41
45
  id: string;
42
46
  type: string;
43
47
  sortingKey: string;
44
- blockGroup?: string | undefined;
45
48
  content?: string | undefined;
49
+ contentHash?: string | undefined;
46
50
  executionCount?: number | undefined;
51
+ executionFinishedAt?: string | undefined;
52
+ executionStartedAt?: string | undefined;
47
53
  metadata?: Record<string, any> | undefined;
48
54
  outputs?: any[] | undefined;
49
55
  version?: number | undefined;
50
56
  }, {
57
+ blockGroup: string;
51
58
  id: string;
52
59
  type: string;
53
60
  sortingKey: string;
54
- blockGroup?: string | undefined;
55
61
  content?: string | undefined;
62
+ contentHash?: string | undefined;
56
63
  executionCount?: number | undefined;
64
+ executionFinishedAt?: string | undefined;
65
+ executionStartedAt?: string | undefined;
57
66
  metadata?: Record<string, any> | undefined;
58
67
  outputs?: any[] | undefined;
59
68
  version?: number | undefined;
60
69
  }>;
61
70
  type DeepnoteBlock = z.infer<typeof deepnoteBlockSchema>;
71
+ declare const environmentSchema: z.ZodOptional<z.ZodObject<{
72
+ customImage: z.ZodOptional<z.ZodString>;
73
+ hash: z.ZodOptional<z.ZodString>;
74
+ packages: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
75
+ platform: z.ZodOptional<z.ZodString>;
76
+ python: z.ZodOptional<z.ZodObject<{
77
+ environment: z.ZodOptional<z.ZodEnum<["uv", "conda", "venv", "poetry", "system"]>>;
78
+ version: z.ZodOptional<z.ZodString>;
79
+ }, "strip", z.ZodTypeAny, {
80
+ version?: string | undefined;
81
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
82
+ }, {
83
+ version?: string | undefined;
84
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
85
+ }>>;
86
+ }, "strip", z.ZodTypeAny, {
87
+ customImage?: string | undefined;
88
+ hash?: string | undefined;
89
+ packages?: Record<string, string> | undefined;
90
+ platform?: string | undefined;
91
+ python?: {
92
+ version?: string | undefined;
93
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
94
+ } | undefined;
95
+ }, {
96
+ customImage?: string | undefined;
97
+ hash?: string | undefined;
98
+ packages?: Record<string, string> | undefined;
99
+ platform?: string | undefined;
100
+ python?: {
101
+ version?: string | undefined;
102
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
103
+ } | undefined;
104
+ }>>;
105
+ type Environment = z.infer<typeof environmentSchema>;
106
+ declare const executionSummarySchema: z.ZodOptional<z.ZodObject<{
107
+ blocksExecuted: z.ZodOptional<z.ZodNumber>;
108
+ blocksFailed: z.ZodOptional<z.ZodNumber>;
109
+ blocksSucceeded: z.ZodOptional<z.ZodNumber>;
110
+ totalDurationMs: z.ZodOptional<z.ZodNumber>;
111
+ }, "strip", z.ZodTypeAny, {
112
+ blocksExecuted?: number | undefined;
113
+ blocksFailed?: number | undefined;
114
+ blocksSucceeded?: number | undefined;
115
+ totalDurationMs?: number | undefined;
116
+ }, {
117
+ blocksExecuted?: number | undefined;
118
+ blocksFailed?: number | undefined;
119
+ blocksSucceeded?: number | undefined;
120
+ totalDurationMs?: number | undefined;
121
+ }>>;
122
+ type ExecutionSummary = z.infer<typeof executionSummarySchema>;
123
+ declare const executionErrorSchema: z.ZodOptional<z.ZodObject<{
124
+ message: z.ZodOptional<z.ZodString>;
125
+ name: z.ZodOptional<z.ZodString>;
126
+ traceback: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
127
+ }, "strip", z.ZodTypeAny, {
128
+ message?: string | undefined;
129
+ name?: string | undefined;
130
+ traceback?: string[] | undefined;
131
+ }, {
132
+ message?: string | undefined;
133
+ name?: string | undefined;
134
+ traceback?: string[] | undefined;
135
+ }>>;
136
+ type ExecutionError = z.infer<typeof executionErrorSchema>;
137
+ declare const executionSchema: z.ZodOptional<z.ZodObject<{
138
+ error: z.ZodOptional<z.ZodObject<{
139
+ message: z.ZodOptional<z.ZodString>;
140
+ name: z.ZodOptional<z.ZodString>;
141
+ traceback: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
142
+ }, "strip", z.ZodTypeAny, {
143
+ message?: string | undefined;
144
+ name?: string | undefined;
145
+ traceback?: string[] | undefined;
146
+ }, {
147
+ message?: string | undefined;
148
+ name?: string | undefined;
149
+ traceback?: string[] | undefined;
150
+ }>>;
151
+ finishedAt: z.ZodOptional<z.ZodString>;
152
+ inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
153
+ startedAt: z.ZodOptional<z.ZodString>;
154
+ summary: z.ZodOptional<z.ZodObject<{
155
+ blocksExecuted: z.ZodOptional<z.ZodNumber>;
156
+ blocksFailed: z.ZodOptional<z.ZodNumber>;
157
+ blocksSucceeded: z.ZodOptional<z.ZodNumber>;
158
+ totalDurationMs: z.ZodOptional<z.ZodNumber>;
159
+ }, "strip", z.ZodTypeAny, {
160
+ blocksExecuted?: number | undefined;
161
+ blocksFailed?: number | undefined;
162
+ blocksSucceeded?: number | undefined;
163
+ totalDurationMs?: number | undefined;
164
+ }, {
165
+ blocksExecuted?: number | undefined;
166
+ blocksFailed?: number | undefined;
167
+ blocksSucceeded?: number | undefined;
168
+ totalDurationMs?: number | undefined;
169
+ }>>;
170
+ triggeredBy: z.ZodOptional<z.ZodEnum<["user", "schedule", "api", "ci"]>>;
171
+ }, "strip", z.ZodTypeAny, {
172
+ error?: {
173
+ message?: string | undefined;
174
+ name?: string | undefined;
175
+ traceback?: string[] | undefined;
176
+ } | undefined;
177
+ finishedAt?: string | undefined;
178
+ inputs?: Record<string, unknown> | undefined;
179
+ startedAt?: string | undefined;
180
+ summary?: {
181
+ blocksExecuted?: number | undefined;
182
+ blocksFailed?: number | undefined;
183
+ blocksSucceeded?: number | undefined;
184
+ totalDurationMs?: number | undefined;
185
+ } | undefined;
186
+ triggeredBy?: "user" | "schedule" | "api" | "ci" | undefined;
187
+ }, {
188
+ error?: {
189
+ message?: string | undefined;
190
+ name?: string | undefined;
191
+ traceback?: string[] | undefined;
192
+ } | undefined;
193
+ finishedAt?: string | undefined;
194
+ inputs?: Record<string, unknown> | undefined;
195
+ startedAt?: string | undefined;
196
+ summary?: {
197
+ blocksExecuted?: number | undefined;
198
+ blocksFailed?: number | undefined;
199
+ blocksSucceeded?: number | undefined;
200
+ totalDurationMs?: number | undefined;
201
+ } | undefined;
202
+ triggeredBy?: "user" | "schedule" | "api" | "ci" | undefined;
203
+ }>>;
204
+ type Execution = z.infer<typeof executionSchema>;
62
205
  declare const deepnoteFileSchema: z.ZodObject<{
206
+ environment: z.ZodOptional<z.ZodObject<{
207
+ customImage: z.ZodOptional<z.ZodString>;
208
+ hash: z.ZodOptional<z.ZodString>;
209
+ packages: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
210
+ platform: z.ZodOptional<z.ZodString>;
211
+ python: z.ZodOptional<z.ZodObject<{
212
+ environment: z.ZodOptional<z.ZodEnum<["uv", "conda", "venv", "poetry", "system"]>>;
213
+ version: z.ZodOptional<z.ZodString>;
214
+ }, "strip", z.ZodTypeAny, {
215
+ version?: string | undefined;
216
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
217
+ }, {
218
+ version?: string | undefined;
219
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
220
+ }>>;
221
+ }, "strip", z.ZodTypeAny, {
222
+ customImage?: string | undefined;
223
+ hash?: string | undefined;
224
+ packages?: Record<string, string> | undefined;
225
+ platform?: string | undefined;
226
+ python?: {
227
+ version?: string | undefined;
228
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
229
+ } | undefined;
230
+ }, {
231
+ customImage?: string | undefined;
232
+ hash?: string | undefined;
233
+ packages?: Record<string, string> | undefined;
234
+ platform?: string | undefined;
235
+ python?: {
236
+ version?: string | undefined;
237
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
238
+ } | undefined;
239
+ }>>;
240
+ execution: z.ZodOptional<z.ZodObject<{
241
+ error: z.ZodOptional<z.ZodObject<{
242
+ message: z.ZodOptional<z.ZodString>;
243
+ name: z.ZodOptional<z.ZodString>;
244
+ traceback: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
245
+ }, "strip", z.ZodTypeAny, {
246
+ message?: string | undefined;
247
+ name?: string | undefined;
248
+ traceback?: string[] | undefined;
249
+ }, {
250
+ message?: string | undefined;
251
+ name?: string | undefined;
252
+ traceback?: string[] | undefined;
253
+ }>>;
254
+ finishedAt: z.ZodOptional<z.ZodString>;
255
+ inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
256
+ startedAt: z.ZodOptional<z.ZodString>;
257
+ summary: z.ZodOptional<z.ZodObject<{
258
+ blocksExecuted: z.ZodOptional<z.ZodNumber>;
259
+ blocksFailed: z.ZodOptional<z.ZodNumber>;
260
+ blocksSucceeded: z.ZodOptional<z.ZodNumber>;
261
+ totalDurationMs: z.ZodOptional<z.ZodNumber>;
262
+ }, "strip", z.ZodTypeAny, {
263
+ blocksExecuted?: number | undefined;
264
+ blocksFailed?: number | undefined;
265
+ blocksSucceeded?: number | undefined;
266
+ totalDurationMs?: number | undefined;
267
+ }, {
268
+ blocksExecuted?: number | undefined;
269
+ blocksFailed?: number | undefined;
270
+ blocksSucceeded?: number | undefined;
271
+ totalDurationMs?: number | undefined;
272
+ }>>;
273
+ triggeredBy: z.ZodOptional<z.ZodEnum<["user", "schedule", "api", "ci"]>>;
274
+ }, "strip", z.ZodTypeAny, {
275
+ error?: {
276
+ message?: string | undefined;
277
+ name?: string | undefined;
278
+ traceback?: string[] | undefined;
279
+ } | undefined;
280
+ finishedAt?: string | undefined;
281
+ inputs?: Record<string, unknown> | undefined;
282
+ startedAt?: string | undefined;
283
+ summary?: {
284
+ blocksExecuted?: number | undefined;
285
+ blocksFailed?: number | undefined;
286
+ blocksSucceeded?: number | undefined;
287
+ totalDurationMs?: number | undefined;
288
+ } | undefined;
289
+ triggeredBy?: "user" | "schedule" | "api" | "ci" | undefined;
290
+ }, {
291
+ error?: {
292
+ message?: string | undefined;
293
+ name?: string | undefined;
294
+ traceback?: string[] | undefined;
295
+ } | undefined;
296
+ finishedAt?: string | undefined;
297
+ inputs?: Record<string, unknown> | undefined;
298
+ startedAt?: string | undefined;
299
+ summary?: {
300
+ blocksExecuted?: number | undefined;
301
+ blocksFailed?: number | undefined;
302
+ blocksSucceeded?: number | undefined;
303
+ totalDurationMs?: number | undefined;
304
+ } | undefined;
305
+ triggeredBy?: "user" | "schedule" | "api" | "ci" | undefined;
306
+ }>>;
63
307
  metadata: z.ZodObject<{
64
308
  checksum: z.ZodOptional<z.ZodString>;
65
309
  createdAt: z.ZodString;
@@ -95,9 +339,12 @@ declare const deepnoteFileSchema: z.ZodObject<{
95
339
  name: z.ZodString;
96
340
  notebooks: z.ZodArray<z.ZodObject<{
97
341
  blocks: z.ZodArray<z.ZodObject<{
98
- blockGroup: z.ZodOptional<z.ZodString>;
342
+ blockGroup: z.ZodString;
99
343
  content: z.ZodOptional<z.ZodString>;
344
+ contentHash: z.ZodOptional<z.ZodString>;
100
345
  executionCount: z.ZodOptional<z.ZodNumber>;
346
+ executionFinishedAt: z.ZodOptional<z.ZodString>;
347
+ executionStartedAt: z.ZodOptional<z.ZodString>;
101
348
  id: z.ZodString;
102
349
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
103
350
  outputs: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
@@ -105,22 +352,28 @@ declare const deepnoteFileSchema: z.ZodObject<{
105
352
  type: z.ZodString;
106
353
  version: z.ZodOptional<z.ZodNumber>;
107
354
  }, "strip", z.ZodTypeAny, {
355
+ blockGroup: string;
108
356
  id: string;
109
357
  type: string;
110
358
  sortingKey: string;
111
- blockGroup?: string | undefined;
112
359
  content?: string | undefined;
360
+ contentHash?: string | undefined;
113
361
  executionCount?: number | undefined;
362
+ executionFinishedAt?: string | undefined;
363
+ executionStartedAt?: string | undefined;
114
364
  metadata?: Record<string, any> | undefined;
115
365
  outputs?: any[] | undefined;
116
366
  version?: number | undefined;
117
367
  }, {
368
+ blockGroup: string;
118
369
  id: string;
119
370
  type: string;
120
371
  sortingKey: string;
121
- blockGroup?: string | undefined;
122
372
  content?: string | undefined;
373
+ contentHash?: string | undefined;
123
374
  executionCount?: number | undefined;
375
+ executionFinishedAt?: string | undefined;
376
+ executionStartedAt?: string | undefined;
124
377
  metadata?: Record<string, any> | undefined;
125
378
  outputs?: any[] | undefined;
126
379
  version?: number | undefined;
@@ -134,12 +387,15 @@ declare const deepnoteFileSchema: z.ZodObject<{
134
387
  id: string;
135
388
  name: string;
136
389
  blocks: {
390
+ blockGroup: string;
137
391
  id: string;
138
392
  type: string;
139
393
  sortingKey: string;
140
- blockGroup?: string | undefined;
141
394
  content?: string | undefined;
395
+ contentHash?: string | undefined;
142
396
  executionCount?: number | undefined;
397
+ executionFinishedAt?: string | undefined;
398
+ executionStartedAt?: string | undefined;
143
399
  metadata?: Record<string, any> | undefined;
144
400
  outputs?: any[] | undefined;
145
401
  version?: number | undefined;
@@ -151,12 +407,15 @@ declare const deepnoteFileSchema: z.ZodObject<{
151
407
  id: string;
152
408
  name: string;
153
409
  blocks: {
410
+ blockGroup: string;
154
411
  id: string;
155
412
  type: string;
156
413
  sortingKey: string;
157
- blockGroup?: string | undefined;
158
414
  content?: string | undefined;
415
+ contentHash?: string | undefined;
159
416
  executionCount?: number | undefined;
417
+ executionFinishedAt?: string | undefined;
418
+ executionStartedAt?: string | undefined;
160
419
  metadata?: Record<string, any> | undefined;
161
420
  outputs?: any[] | undefined;
162
421
  version?: number | undefined;
@@ -166,6 +425,10 @@ declare const deepnoteFileSchema: z.ZodObject<{
166
425
  workingDirectory?: string | undefined;
167
426
  }>, "many">;
168
427
  settings: z.ZodOptional<z.ZodObject<{
428
+ /**
429
+ * @deprecated Use top-level `environment` instead.
430
+ * This field is kept for backward compatibility.
431
+ */
169
432
  environment: z.ZodOptional<z.ZodObject<{
170
433
  customImage: z.ZodOptional<z.ZodString>;
171
434
  pythonVersion: z.ZodOptional<z.ZodString>;
@@ -200,12 +463,15 @@ declare const deepnoteFileSchema: z.ZodObject<{
200
463
  id: string;
201
464
  name: string;
202
465
  blocks: {
466
+ blockGroup: string;
203
467
  id: string;
204
468
  type: string;
205
469
  sortingKey: string;
206
- blockGroup?: string | undefined;
207
470
  content?: string | undefined;
471
+ contentHash?: string | undefined;
208
472
  executionCount?: number | undefined;
473
+ executionFinishedAt?: string | undefined;
474
+ executionStartedAt?: string | undefined;
209
475
  metadata?: Record<string, any> | undefined;
210
476
  outputs?: any[] | undefined;
211
477
  version?: number | undefined;
@@ -235,12 +501,15 @@ declare const deepnoteFileSchema: z.ZodObject<{
235
501
  id: string;
236
502
  name: string;
237
503
  blocks: {
504
+ blockGroup: string;
238
505
  id: string;
239
506
  type: string;
240
507
  sortingKey: string;
241
- blockGroup?: string | undefined;
242
508
  content?: string | undefined;
509
+ contentHash?: string | undefined;
243
510
  executionCount?: number | undefined;
511
+ executionFinishedAt?: string | undefined;
512
+ executionStartedAt?: string | undefined;
244
513
  metadata?: Record<string, any> | undefined;
245
514
  outputs?: any[] | undefined;
246
515
  version?: number | undefined;
@@ -280,12 +549,15 @@ declare const deepnoteFileSchema: z.ZodObject<{
280
549
  id: string;
281
550
  name: string;
282
551
  blocks: {
552
+ blockGroup: string;
283
553
  id: string;
284
554
  type: string;
285
555
  sortingKey: string;
286
- blockGroup?: string | undefined;
287
556
  content?: string | undefined;
557
+ contentHash?: string | undefined;
288
558
  executionCount?: number | undefined;
559
+ executionFinishedAt?: string | undefined;
560
+ executionStartedAt?: string | undefined;
289
561
  metadata?: Record<string, any> | undefined;
290
562
  outputs?: any[] | undefined;
291
563
  version?: number | undefined;
@@ -309,6 +581,33 @@ declare const deepnoteFileSchema: z.ZodObject<{
309
581
  sqlCacheMaxAge?: number | undefined;
310
582
  } | undefined;
311
583
  };
584
+ environment?: {
585
+ customImage?: string | undefined;
586
+ hash?: string | undefined;
587
+ packages?: Record<string, string> | undefined;
588
+ platform?: string | undefined;
589
+ python?: {
590
+ version?: string | undefined;
591
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
592
+ } | undefined;
593
+ } | undefined;
594
+ execution?: {
595
+ error?: {
596
+ message?: string | undefined;
597
+ name?: string | undefined;
598
+ traceback?: string[] | undefined;
599
+ } | undefined;
600
+ finishedAt?: string | undefined;
601
+ inputs?: Record<string, unknown> | undefined;
602
+ startedAt?: string | undefined;
603
+ summary?: {
604
+ blocksExecuted?: number | undefined;
605
+ blocksFailed?: number | undefined;
606
+ blocksSucceeded?: number | undefined;
607
+ totalDurationMs?: number | undefined;
608
+ } | undefined;
609
+ triggeredBy?: "user" | "schedule" | "api" | "ci" | undefined;
610
+ } | undefined;
312
611
  }, {
313
612
  metadata: {
314
613
  createdAt: string;
@@ -324,12 +623,15 @@ declare const deepnoteFileSchema: z.ZodObject<{
324
623
  id: string;
325
624
  name: string;
326
625
  blocks: {
626
+ blockGroup: string;
327
627
  id: string;
328
628
  type: string;
329
629
  sortingKey: string;
330
- blockGroup?: string | undefined;
331
630
  content?: string | undefined;
631
+ contentHash?: string | undefined;
332
632
  executionCount?: number | undefined;
633
+ executionFinishedAt?: string | undefined;
634
+ executionStartedAt?: string | undefined;
333
635
  metadata?: Record<string, any> | undefined;
334
636
  outputs?: any[] | undefined;
335
637
  version?: number | undefined;
@@ -353,6 +655,33 @@ declare const deepnoteFileSchema: z.ZodObject<{
353
655
  sqlCacheMaxAge?: number | undefined;
354
656
  } | undefined;
355
657
  };
658
+ environment?: {
659
+ customImage?: string | undefined;
660
+ hash?: string | undefined;
661
+ packages?: Record<string, string> | undefined;
662
+ platform?: string | undefined;
663
+ python?: {
664
+ version?: string | undefined;
665
+ environment?: "uv" | "conda" | "venv" | "poetry" | "system" | undefined;
666
+ } | undefined;
667
+ } | undefined;
668
+ execution?: {
669
+ error?: {
670
+ message?: string | undefined;
671
+ name?: string | undefined;
672
+ traceback?: string[] | undefined;
673
+ } | undefined;
674
+ finishedAt?: string | undefined;
675
+ inputs?: Record<string, unknown> | undefined;
676
+ startedAt?: string | undefined;
677
+ summary?: {
678
+ blocksExecuted?: number | undefined;
679
+ blocksFailed?: number | undefined;
680
+ blocksSucceeded?: number | undefined;
681
+ totalDurationMs?: number | undefined;
682
+ } | undefined;
683
+ triggeredBy?: "user" | "schedule" | "api" | "ci" | undefined;
684
+ } | undefined;
356
685
  }>;
357
686
  type DeepnoteFile = z.infer<typeof deepnoteFileSchema>;
358
687
  //#endregion
@@ -362,6 +691,24 @@ type DeepnoteFile = z.infer<typeof deepnoteFileSchema>;
362
691
  */
363
692
  declare function deserializeDeepnoteFile(yamlContent: string): DeepnoteFile;
364
693
  //#endregion
694
+ //#region src/deserialize-file/parse-yaml.d.ts
695
+ /**
696
+ * Validates UTF-8 encoding from raw bytes before decoding to string.
697
+ * This is the proper way to validate UTF-8 - check BEFORE decoding.
698
+ *
699
+ * @param bytes - Raw file bytes as Uint8Array
700
+ * @returns Decoded UTF-8 string without BOM
701
+ * @throws Error if BOM detected or invalid UTF-8 encoding
702
+ *
703
+ * @example
704
+ * ```typescript
705
+ * const bytes = await fs.readFile('file.deepnote') // Returns Buffer/Uint8Array
706
+ * const yamlContent = decodeUtf8NoBom(bytes)
707
+ * const parsed = parseYaml(yamlContent)
708
+ * ```
709
+ */
710
+ declare function decodeUtf8NoBom(bytes: Uint8Array): string;
711
+ //#endregion
365
712
  //#region src/markdown.d.ts
366
713
  declare function createMarkdown(block: DeepnoteBlock): string;
367
714
  declare function stripMarkdown(block: DeepnoteBlock): string;
@@ -378,4 +725,4 @@ interface ButtonExecutionContext {
378
725
  //#region src/python-code.d.ts
379
726
  declare function createPythonCode(block: DeepnoteBlock, executionContext?: ButtonExecutionContext): string;
380
727
  //#endregion
381
- export { type DeepnoteBlock, type DeepnoteFile, type TableState, createMarkdown, createPythonCode, deepnoteBlockSchema, deepnoteFileSchema, deserializeDeepnoteFile, stripMarkdown };
728
+ export { type DeepnoteBlock, type DeepnoteFile, type Environment, type Execution, type ExecutionError, type ExecutionSummary, type TableState, createMarkdown, createPythonCode, decodeUtf8NoBom, deepnoteBlockSchema, deepnoteFileSchema, deserializeDeepnoteFile, environmentSchema, executionErrorSchema, executionSchema, executionSummarySchema, stripMarkdown };