UNPKG

@datalayer/core

Version:

[![Datalayer](https://assets.datalayer.tech/datalayer-25.svg)](https://datalayer.io)

154 lines (153 loc) 4.92 kB
/* * Copyright (c) 2023-2025 Datalayer, Inc. * Distributed under the terms of the Modified BSD License. */ import * as notebooks from '../api/spacer/notebooks'; import { ItemDTO } from './ItemDTO'; import { ItemTypes } from '../client/constants'; import { validateJSON } from '../api/utils/validation'; /** * Notebook domain model that extends the base Item class. * Provides notebook-specific functionality for managing Jupyter notebooks. * * @example * ```typescript * const notebook = await sdk.createNotebook(formData); * const kernelSpec = await notebook.getKernelSpec(); * ``` */ export class NotebookDTO extends ItemDTO { /** * Create a Notebook instance. * * @param data - Notebook data from API * @param sdk - SDK instance */ constructor(data, sdk) { super(data, sdk); } // ======================================================================== // Abstract Method Implementations // ======================================================================== /** Document type identifier. */ get type() { this._checkDeleted(); return ItemTypes.NOTEBOOK; } /** The cached name of the notebook. */ get name() { this._checkDeleted(); return (this._data.name_t || this._data.notebook_name_s || this._data.name || ''); } /** The cached content. */ get content() { this._checkDeleted(); if (!this._data.content && this._data.model_s) { try { return JSON.parse(this._data.model_s); } catch { return this._data.model_s; } } return this._data.content; } /** Get the current name from API. */ async getName() { this._checkDeleted(); // For now, return cached value - implement API call if needed return this.name; } /** Get when the notebook was last updated from API. */ async getUpdatedAt() { this._checkDeleted(); const dateStr = this._data.updated_at || this._data.update_ts_dt; if (!dateStr) { throw new Error('No update timestamp available for notebook'); } return new Date(dateStr); } /** Update the notebook. */ async update(name, description) { // FIXME: check if both are needed, and use the existing values if only one provided this._checkDeleted(); const token = this._sdk.getToken(); const spacerRunUrl = this._sdk.getSpacerRunUrl(); const updateData = {}; if (name !== undefined) updateData.name = name; if (description !== undefined) updateData.description = description; await notebooks.updateNotebook(token, this.uid, updateData, spacerRunUrl); // FIXME: handle partial updates return this; } // ======================================================================== // Notebook-specific Properties // ======================================================================== /** File path within the space. */ get path() { this._checkDeleted(); return this._data.path || ''; } /** Version number. */ get version() { this._checkDeleted(); return this._data.version || 0; } /** Notebook metadata. */ get metadata() { this._checkDeleted(); return this._data.metadata || {}; } /** Kernel specification (cached). */ get kernelSpec() { this._checkDeleted(); return this._data.kernel_spec; } /** Description of the notebook. */ get description() { this._checkDeleted(); return this._data.description_t || ''; } /** Get the notebook extension. */ get extension() { this._checkDeleted(); const ext = this._data.notebook_extension_s; return ext ? (ext.startsWith('.') ? ext : `.${ext}`) : '.ipynb'; } /** * Get notebook data in camelCase format. * Returns only the core fields that consumers need. * This provides a stable interface regardless of API changes. * * @returns Core notebook data with camelCase properties */ toJSON() { this._checkDeleted(); const obj = { id: this.id, uid: this.uid, name: this.name, description: this.description, type: this.type, extension: this.extension, cdnUrl: this._data.cdn_url_s, }; validateJSON(obj, 'Notebook'); return obj; } /** * Get the raw notebook data exactly as received from the API. * This preserves the original snake_case naming from the API response. * * @returns Raw notebook data from API */ rawData() { this._checkDeleted(); return this._data; } }