import type { Schema } from '../schema';
import { utils } from '../utils';
type Field = Record<string, unknown>;
* Provides methods to access the components schema.
*/
class ComponentSchema {
private _schemaApi: Schema;
private _schema: Field;
* Creates new instance of API.
*
* @category Internal
* @param schema - The schema API
*/
constructor(schema: Schema) {
this._schemaApi = schema;
this._schema = schema.getComponents();
}
_resolveLazyDefaults(defaults: Record<string, unknown>) {
for (const [key, value] of Object.entries(defaults)) {
if (typeof value === 'function') defaults[key] = value();
}
}
* Gets default data for a component.
*
* @param component - The component name
* @returns The default data
* @example
* ```javascript
* const modelData = editor.schema.components.getDefaultData('model');
* ```
*/
getDefaultData(component: string) {
const result: Record<string, unknown> = {};
const schema = this._schemaApi.getFields(this._schema)[component];
for (const [name, field] of Object.entries(this._schemaApi.getFields(schema))) {
const value = this._schemaApi.getDefault(field);
if (value.hasDefault) result[name] = utils.deepCopy(value.value);
}
this._resolveLazyDefaults(result);
return result;
}
resolvePath(component: string, path: string) {
const schema = this._schemaApi.getFields(this._schema)[component];
const result = schema ? this._schemaApi.resolvePath(schema, path) : null;
if (result?.hasDefault) {
result.default = typeof result.default === 'function' ? result.default() : utils.deepCopy(result.default);
}
return result;
}
* Gets a list of fields of a particular type for a component.
*
* @param component - The component name
* @param type - The desired type
* @returns A list of fields
* @example
* ```javascript
* const buttonEntityFields = editor.schema.components.getFieldsOfType('button', 'entity');
* ```
*/
getFieldsOfType(component: string, type: string) {
const result: string[] = [];
const recurse = (schema: Field, path: string) => {
for (const [name, field] of Object.entries(this._schemaApi.getFields(schema))) {
const current = (path ? `${path}.` : '') + name;
const fieldType = this._schemaApi.getType(field);
if (fieldType === type || fieldType === `array:${type}`) {
result.push(current);
continue;
}
const map = this._schemaApi.getMapValue(field);
if (fieldType === 'object' && map) {
const mapType = this._schemaApi.getType(map);
if (mapType === type || mapType === `array:${type}`) {
result.push(`${current}.*`);
} else {
recurse(map as Field, `${current}.*`);
}
}
}
};
const schema = this._schemaApi.getFields(this._schema)[component];
if (schema) recurse(schema as Field, '');
return result;
}
* Gets a list of all the available components.
*
* @returns The components
*/
list() {
const result = Object.keys(this._schemaApi.getFields(this._schema)).sort();
const index = result.indexOf('zone');
if (index !== -1) result.splice(index, 1);
return result;
}
}
export { ComponentSchema };