import type { DataDomain } from './DataDomain.js';
import { DomainModelKind } from '../models/kinds.js';
import { DomainElement, DomainElementSchema } from './DomainElement.js';
import { type IThing, Thing } from '../models/Thing.js';
import type { DomainNamespace } from './DomainNamespace.js';
import type { FileBreadcrumb } from '../models/store/File.js';
import { DomainEntity, type DomainEntitySchema } from './DomainEntity.js';
export interface ModelOrderedItem {
    /**
     * The type of the ordered item.
     */
    type: 'entity';
    /**
     * The key of the ordered item.
     */
    key: string;
}
export interface DomainModelSchema extends DomainElementSchema {
    kind: typeof DomainModelKind;
    /**
     * The data model description.
     */
    info: IThing;
    /**
     * The ordered list of entities in the schema.
     */
    fields?: ModelOrderedItem[];
    /**
     * Whether this model is deprecated.
     */
    deprecated?: boolean;
}
/**
 * Represents a data model within a data domain.
 *
 * A `DomainModel` groups related `DomainEntity` instances, providing a logical structure for organizing
 * data. It acts as a container for entities that share a common purpose or context.
 *
 * **Key Features:**
 *
 * - **Entity Container:** Holds a collection of `DomainEntity` instances.
 * - **Logical Grouping:** Organizes entities into meaningful groups.
 * - **Metadata:** Supports a description for the data model.
 * - **Namespace Integration:**  Belongs to a `DomainNamespace`, creating a hierarchical structure.
 *
 * **Usage:**
 *
 * The preferred way to create a `DomainModel` is through
 * the `DomainNamespace.addModel()` or
 * `DataDomain.addModel()` method.
 *
 * **Example:**
 *
 * ```typescript
 * const dataDomain = new DataDomain();
 * const ns = dataDomain.addNamespace({
 *   key: 'myNamespace',
 * });
 * const userModel = ns.addModel({
 *   key: 'userModel',
 *   info: { name: 'User Model' },
 * });
 * ```
 */
export declare class DomainModel extends DomainElement {
    kind: typeof DomainModelKind;
    /**
     * The description of the domain model.
     */
    accessor info: Thing;
    /**
     * The ordered list of entities in the schema.
     */
    accessor fields: ModelOrderedItem[];
    /**
     * Whether this model is deprecated.
     */
    accessor deprecated: boolean | undefined;
    /**
     * Creates a full data model schema with defaults.
     * @param input The partial data model schema.
     * @returns The data model schema.
     */
    static createSchema(input?: Partial<DomainModelSchema>): DomainModelSchema;
    /**
     * Creates a new model instance.
     *
     * You should use the `DomainNamespace.addModel()` or
     * `DataDomain.addModel()` method instead.
     *
     * @param root A reference to the root DataDomain instance.
     * @param input The partial model schema.
     */
    constructor(root: DataDomain, input?: Partial<DomainModelSchema>);
    /**
     * Generates a JSON representation of the data model.
     *
     * @returns A plain object representation of the
     *   `DomainModel`.
     * @example
     * ```typescript
     * const json = userModel.toJSON();
     * console.log(json);
     * ```
     */
    toJSON(): DomainModelSchema;
    /**
     * Returns the parent namespace where this data model
     * exists.
     *
     * @returns The parent `DomainNamespace`.
     * @throws Error When no parent is found.
     * @example
     * ```typescript
     * const parent = userModel.getParentInstance();
     * console.log(parent.key);
     * ```
     */
    getParentInstance(): DomainNamespace | DataDomain;
    /**
     * Adds a child entity to the current model.
     *
     * @param value The partial entity schema.
     * @returns The created entity instance.
     * @example
     * ```typescript
     * const entity = model.addEntity({
     *   key: 'address',
     *   info: { name: 'Address' },
     * })
     * ```
     */
    addEntity(input?: Partial<DomainEntitySchema>): DomainEntity;
    /**
     * Removes an entity from the current model.
     *
     * @param key The key of the model to remove.
     * @throws {RemoveEntityException} If the model does not exist.
     * @example
     * ```typescript
     * model.removeEntity('address')
     * ```
     */
    removeEntity(key: string): void;
    /**
     * Attaches an entity to the current model. It changes the parent of the entity
     * to the current model in the graph.
     *
     * The attached entity must be already a child of another model. It detaches the entity
     * from the previous model.
     *
     * @param key The key of the entity to attach.
     * @throws {AttachException} If the entity does not exist.
     * @throws {AttachException} If passed key doesn't belong to an entity.
     * @throws {AttachException} When the entity is already a child of the current model.
     * @throws {AttachException} If the entity is not in the same domain.
     * @example
     * ```typescript
     * model.attachEntity('address')
     * ```
     */
    attachEntity(key: string): this;
    /**
     * Detaches an entity from the current model. It changes the parent of the entity
     * to the root graph.
     * Unlike remove, it doesn't remove the entity from the graph nor notifies the change.
     * @param key The key of the entity to detach.
     * @throws {DetachException} If the entity does not exist.
     * @throws {DetachException} If passed key doesn't belong to an entity.
     * @throws {DetachException} When the entity is not a child of the current model.
     */
    detachEntity(key: string): this;
    /**
     * Lists all entities.
     *
     * Note, it accounts for the order of the entities as
     * defined in the `fields` array.
     *
     * @returns A generator that yields each `DomainEntity`.
     * @example
     * ```typescript
     * for (const entity of model.listEntities()) {
     *   console.log(entity.key);
     * }
     * ```
     */
    listEntities(): Generator<DomainEntity>;
    /**
     * Checks if this model has any entities.
     *
     * @returns True if the model has entities.
     * @example
     * ```typescript
     * if (model.hasEntities()) {
     *   // ...
     * }
     * ```
     */
    hasEntities(): boolean;
    /**
     * Creates breadcrumbs from this data model to the root namespace.
     */
    breadcrumbs(): FileBreadcrumb[];
    /**
     * Checks if this model has any fields (entities).
     *
     * @returns True if the model has fields.
     * @example
     * ```typescript
     * if (model.hasFields()) {
     *   // ...
     * }
     * ```
     */
    hasFields(): boolean;
    private removeField;
    /**
     * Checks whether the data model is a child of the given namespace.
     * The relationship doesn't have to be direct, as long as the data model is in the hierarchy it will return true.
     *
     * @param key The key of the parent namespace to check.
     * @returns True if this data model is a child of the given namespace.
     */
    isChildOf(key: string): boolean;
}
//# sourceMappingURL=DomainModel.d.ts.map