@datalayer/core
Version:
[](https://datalayer.io)
158 lines (157 loc) • 5.37 kB
JavaScript
/*
* Copyright (c) 2023-2025 Datalayer, Inc.
* Distributed under the terms of the Modified BSD License.
*/
/**
* Lexical domain model for the Datalayer SDK.
*
* @module models/LexicalDTO
*/
import * as lexicals from '../api/spacer/lexicals';
import { ItemTypes } from '../client';
import { ItemDTO } from './ItemDTO';
import { validateJSON } from '../api/utils/validation';
/**
* Lexical domain model that extends the base Item class.
* Provides lexical document functionality for managing rich text documents.
*
* @example
* ```typescript
* const lexical = await sdk.createLexical(formData);
* await lexical.update({ name: 'Updated Documentation' });
* ```
*/
export class LexicalDTO extends ItemDTO {
/**
* Create a Lexical instance.
*
* @param data - Lexical 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.LEXICAL;
}
/** The cached name of the document. */
get name() {
this._checkDeleted();
return this._data.name_t || this._data.name || '';
}
/** Get the current name of the document from API. */
async getName() {
this._checkDeleted();
const token = this._getToken();
const spacerRunUrl = this._getSpacerRunUrl();
const response = await lexicals.getLexical(token, this.uid, spacerRunUrl);
if (response.document) {
this._updateData(response.document);
return response.document.name_t || response.document.name || '';
}
return this.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;
}
/** Description of the lexical document. */
get description() {
this._checkDeleted();
return this._data.description_t || '';
}
/** Get the document extension. */
get extension() {
this._checkDeleted();
const ext = this._data.document_extension_s;
return ext ? (ext.startsWith('.') ? ext : `.${ext}`) : '.lexical';
}
/** Get when the document was last updated from API. */
async getUpdatedAt() {
this._checkDeleted();
const token = this._getToken();
const spacerRunUrl = this._getSpacerRunUrl();
const response = await lexicals.getLexical(token, this.uid, spacerRunUrl);
if (response.document) {
this._updateData(response.document);
const dateStr = response.document.last_update_ts_dt ||
response.document.updated_at ||
response.document.creation_ts_dt ||
response.document.created_at;
if (!dateStr) {
throw new Error('No timestamp available for lexical document');
}
return new Date(dateStr);
}
const dateStr = this._data.last_update_ts_dt ||
this._data.updated_at ||
this._data.creation_ts_dt ||
this._data.created_at;
if (!dateStr) {
throw new Error('No timestamp available for lexical document');
}
return new Date(dateStr);
}
/** Update the document. */
async update(name, description) {
// FIXME: check if both are needed, and use the existing values if only one provided
this._checkDeleted();
const token = this._getToken();
const spacerRunUrl = this._getSpacerRunUrl();
const updateData = {};
if (name !== undefined)
updateData.name = name;
if (description !== undefined)
updateData.description = description;
const response = await lexicals.updateLexical(token, this.uid, updateData, spacerRunUrl);
this._updateData(response.document);
return this;
}
/**
* Get lexical document data in camelCase format.
* Returns only the core fields that consumers need.
* This provides a stable interface regardless of API changes.
*
* @returns Core lexical data with camelCase properties
*/
toJSON() {
this._checkDeleted();
const obj = {
uid: this.uid,
id: this.id,
name: this.name,
description: this.description,
type: this.type,
extension: this.extension,
createdAt: this.createdAt.toDateString(),
updatedAt: this.updatedAt.toDateString(),
cdnUrl: this._data.cdn_url_s,
};
validateJSON(obj, 'Lexical');
return obj;
}
/**
* Get the raw lexical data exactly as received from the API.
* This preserves the original snake_case naming from the API response.
*
* @returns Raw lexical data from API
*/
rawData() {
this._checkDeleted();
return this._data;
}
}