import type { DataDomain } from './DataDomain.js';
import { DomainEntityKind } from '../models/kinds.js';
import { DomainElement, type DomainElementSchema } from './DomainElement.js';
import { type IThing, Thing } from '../models/Thing.js';
import type { IShapeUnion } from '../amf/definitions/Shapes.js';
import { DomainProperty, type DomainPropertySchema } from './DomainProperty.js';
import { DomainAssociation, DomainAssociationSchema } from './DomainAssociation.js';
import type { AssociationAddOptions } from './types.js';
import type { FileBreadcrumb } from '../models/store/File.js';
import type { DomainModel } from './DomainModel.js';
import type { IShapeRenderOptions } from '../amf/shape/ShapeBase.js';
import { type SemanticType, type AppliedDataSemantic } from './Semantics.js';
export interface EntityOrderedItem {
    /**
     * The type of the ordered item.
     */
    type: 'property' | 'association';
    /**
     * The key of the ordered item.
     */
    key: string;
}
export interface DomainEntitySchema extends DomainElementSchema {
    kind: typeof DomainEntityKind;
    /**
     * The domain entity description.
     */
    info: IThing;
    /**
     * Optional general purpose tags for the UI.
     */
    tags?: string[];
    /**
     * The semantics applied to this entity.
     * This is a list of applied semantics that can be used to
     * describe the entity in more detail.
     */
    semantics?: AppliedDataSemantic[];
    /**
     * The ordered list of fields (properties and associations) in the schema.
     * These only keep references to the properties and associations.
     * The order of the fields is important as it defines the order of the
     * properties in the schema.
     */
    fields?: EntityOrderedItem[];
    /**
     * Whether this entity is deprecated.
     */
    deprecated?: boolean;
}
/**
 * Represents an entity within a data domain model.
 *
 * A `DomainEntity` defines a structured data type,
 * containing properties and associations. It's a
 * fundamental building block for modeling complex data
 * structures.
 *
 * **Key Features:**
 *
 * - **Properties:** Defines the data elements (fields) within the entity.
 * - **Associations:** Defines relationships to other entities.
 * - **Inheritance:** Supports inheriting properties and associations from parent entities.
 * - **Metadata:** Supports tags, semantics, and deprecation status.
 * - **AMF Shape Generation:** Can be serialized to an AMF (API Modeling Framework) shape.
 * - **Example Generation:** Can generate example databased on its schema.
 *
 * **Usage:**
 *
 * The preferred way to create a `DomainEntity` is through
 * the `DomainModel.addEntity()` method.
 *
 * **Example:**
 *
 * ```typescript
 * const dataDomain = new DataDomain();
 * const userModel = dataDomain.addModel({ key: 'userModel' });
 * const userEntity = userModel.addEntity({ key: 'user' });
 * ```
 *
 * Entity Validation Rules:
 *
 * - **Primary Key:** An entity must have a primary key selected. This can come from a parent
 *   entity or be defined in the current entity.
 * - **Parent Entity:** The parent entity must exist in the graph.
 * - **Circular Dependency:** Adding a parent entity that creates a circular dependency is not allowed.
 * - **Unique Parent:** An entity cannot have the same parent more than once.
 * - **Property Shadowing:** A property can shadow a parent property. This means that if a property
 *   with the same key exists in both the parent and child entity, the child property will take precedence.
 * - **Association Shadowing:** An association can shadow a parent association. This means that if an
 *   association with the same key exists in both the parent and child entity,
 *   the child association will take precedence.
 * - **Property Resolution:** When the same property exists more than one parent and the child entity,
 *   doesn't explicitly define the property, then:
 *   - The last parent entity (iterating from the first entity to the last) that has the property
 *     will be used as the source of the property.
 * - **Association Resolution:** When the same association exists more than one parent and the child entity,
 *   doesn't explicitly define the association, then:
 *   - The last parent entity (iterating from the first entity to the last) that has the association
 *     will be used as the source of the association.
 * - **Minimum Required Properties:** An entity must have at least one property defined. Entities without properties
 *   are ignored in the system.
 * - **Entity Name**:
 *   - An entity must have a name defined.
 *   - The name has to follow the same rules as the names in a SQL database. This means that the name must be unique
 *     within the data domain and cannot contain special characters.
 * - **Association Targets:** An association must have a target entity defined.
 *   This means that the association must point to at least one entity.
 */
export declare class DomainEntity extends DomainElement {
    /**
     * The kind of the domain element.
     */
    kind: typeof DomainEntityKind;
    /**
     * The description of the domain entity.
     */
    accessor info: Thing;
    /**
     * Optional general purpose tags for the UI.
     */
    accessor tags: string[];
    /**
     * Semantics applied to this property.
     */
    accessor semantics: AppliedDataSemantic[];
    /**
     * The ordered list of fields (properties and associations) in the schema.
     * These only keep references to the properties and associations.
     * The order of the fields is important as it defines the order of the
     * properties in the schema.
     */
    accessor fields: EntityOrderedItem[];
    /**
     * Whether this entity is deprecated.
     */
    accessor deprecated: boolean | undefined;
    /**
     * Creates a full data entity schema with defaults.
     *
     * @param input The partial data entity schema.
     * @returns The data entity schema.
     */
    static createSchema(input?: Partial<DomainEntitySchema>): DomainEntitySchema;
    /**
     * Creates a new domain entity instance.
     *
     * You probably want to use the `DomainModel.addEntity()`
     * method instead.
     *
     * @param root A reference to the root DataDomain instance.
     * @param input The partial domain entity schema.
     */
    constructor(root: DataDomain, input?: Partial<DomainEntitySchema>);
    /**
     * Generates a JSON representation of the entity.
     *
     * @returns A plain object representation of the `DomainEntity`.
     */
    toJSON(): DomainEntitySchema;
    /**
     * Returns a parent data entity where this data property
     * exist.
     *
     * @returns The parent `DomainModel` or undefined if not found.
     * @example
     * ```typescript
     * const parent = entity.getParentInstance();
     * if (parent) {
     *   console.log(parent.key);
     * }
     * ```
     */
    getParentInstance(): DomainModel | undefined;
    /**
     * Adds a property to this entity.
     *
     * @param property The partial property schema.
     * @returns The created `DomainProperty` instance.
     * @example
     * ```typescript
     * const property = entity.addProperty({
     *   key: 'name',
     *   type: 'string',
     *   required: true,
     * })
     * ```
     */
    addProperty(property?: Partial<DomainPropertySchema>): DomainProperty;
    /**
     * Removes a property from this entity.
     *
     * @param key The key of the property to remove.
     * @throws {RemovePropertyException} When the property does not exist.
     * @example
     * ```typescript
     * entity.removeProperty('name')
     * ```
     */
    removeProperty(key: string): void;
    /**
     * A shortcut to `listProperties()`.
     */
    get properties(): Generator<DomainProperty>;
    /**
     * Lists all properties of this entity.
     *
     * Note, it accounts for the order of the properties as
     * defined in the `fields` array.
     *
     * @returns A generator that yields each `DomainProperty`.
     * @example
     * ```typescript
     * for (const property of entity.listProperties()) {
     *   console.log(property.key);
     * }
     * ```
     */
    listProperties(): Generator<DomainProperty>;
    /**
     * Checks if this entity has any properties.
     *
     * @returns True if the entity has properties.
     * @example
     * ```typescript
     * if (entity.hasProperties()) {
     *   // ...
     * }
     * ```
     */
    hasProperties(): boolean;
    /**
     * A shortcut to `listParents()`.
     */
    get parents(): Generator<DomainEntity>;
    /**
     * Lists all parent entities of this entity.
     *
     * @returns A generator that yields each parent `DomainEntity`.
     * @example
     * ```typescript
     * for (const parent of entity.listParents()) {
     *   console.log(parent.key);
     * }
     * ```
     */
    listParents(): Generator<DomainEntity>;
    /**
     * Adds a parent to this entity.
     *
     * @param key The key of the parent entity.
     * @param domain The key of the foreign domain the parent belongs to.
     * @returns `this` for chaining.
     * @throws ValidationError When the parent does not exist or a circular dependency is detected.
     * @example
     * ```typescript
     * entity.addParent('baseEntity');
     * ```
     */
    addParent(key: string, domain?: string): this;
    /**
     * Removes a parent from this entity.
     *
     * @param key The key of the parent entity to remove.
     * @param domain Optional domain key if the parent belongs to a foreign domain.
     * @returns `this` for chaining.
     * @throws Error When the parent does not exist.
     * @example
     * ```typescript
     * // Remove local parent
     * entity.removeParent('baseEntity');
     *
     * // Remove foreign domain parent
     * entity.removeParent('baseEntity', 'externalDomain');
     * ```
     */
    removeParent(key: string, domain?: string): this;
    /**
     * Checks if this entity has any parents.
     *
     * @returns True if the entity has parents.
     * @example
     * ```typescript
     * if (entity.hasParents()) {
     *   // ...
     * }
     * ```
     */
    hasParents(): boolean;
    /**
     * Checks if the passed entity has a circular parent
     * relationship when attempting to add a new parent.
     *
     * @param key The key of the parent being added.
     * @returns True if adding this parent would create a
     *   circular relationship.
     */
    hasCircularParent(key: string): boolean;
    /**
     * Creates breadcrumbs from this entity to the root
     * namespace.
     *
     * @returns An array of `FileBreadcrumb` instances.
     * @example
     * ```typescript
     * const breadcrumbs = entity.breadcrumbs();
     * console.log(breadcrumbs);
     * ```
     */
    breadcrumbs(): FileBreadcrumb[];
    /**
     * Adds an association to this entity.
     *
     * @param init The association options.
     * @param input The partial association schema.
     * @returns The created `DomainAssociation` instance.
     * @throws Error When the target entity does not exist.
     * @example
     * ```typescript
     * const association = entity.addAssociation({
     *   key: 'address',
     * });
     * ```
     */
    addAssociation(init?: AssociationAddOptions, input?: Partial<DomainAssociationSchema>): DomainAssociation;
    /**
     * Removes an association from this entity.
     *
     * @param key The key of the association to remove.
     * @throws Error When the association does not exist.
     * @example
     * ```typescript
     * entity.removeAssociation('address');
     * ```
     */
    removeAssociation(key: string): void;
    /**
     * A shortcut to `listAssociations()`.
     */
    get associations(): Generator<DomainAssociation>;
    /**
     * Lists all associations of this entity.
     *
     * The order of the associations is defined in the `fields` array.
     *
     * @returns A generator that yields each
     *   `DomainAssociation`.
     * @example
     * ```typescript
     * for (const association of entity.listAssociations()) {
     *   console.log(association.key);
     * }
     * ```
     */
    listAssociations(): Generator<DomainAssociation>;
    /**
     * Checks if this entity has any associations.
     *
     * @returns True if the entity has associations.
     * @example
     * ```typescript
     * if (entity.hasAssociations()) {
     *   // ...
     * }
     * ```
     */
    hasAssociations(): boolean;
    /**
     * Lists all fields (properties and associations) of this entity.
     *
     * @returns A generator that yields each `DomainAssociation` or `DomainProperty`.
     * @example
     * ```typescript
     * for (const field of entity.listFields()) {
     *   console.log(field.key);
     * }
     * ```
     */
    listFields(): Generator<DomainAssociation | DomainProperty>;
    /**
     * Checks if this entity has any fields (properties or associations).
     *
     * @returns True if the entity has fields.
     * @example
     * ```typescript
     * if (entity.hasFields()) {
     *   // ...
     * }
     * ```
     */
    hasFields(): boolean;
    private removeField;
    /**
     * Creates an AMF's data Shape.
     *
     * The property itself is auto-generated. If the `schema` is defined then it is used
     * as the `range` of the property. Otherwise basic shape is generated for the range.
     *
     * This is a preferred way of reading the AMF shape as this synchronizes changed
     * data properties with the shape definition.
     *
     * @returns AMF property shape definition.
     */
    toApiShape(): IShapeUnion;
    /**
     * Reads the schema of the Entity and generates an example for it.
     *
     * @param mime The mime type of the example.
     * @param opts The example generation options.
     * @returns The generated example.
     * @example
     * ```typescript
     * const example = entity.toExample('application/json');
     * console.log(example);
     * ```
     */
    toExample(mime: string, opts?: IShapeRenderOptions): string | number | boolean | null | undefined;
    /**
     * Checks whether the entity is a child of the given namespace or data model.
     * The relationship doesn't have to be direct, as long as the entity
     * is in the hierarchy it will return true.
     *
     * @param key The key of the parent to check.
     * @returns True if this entity is a child of the given namespace or data model.
     */
    isChildOf(key: string): boolean;
    /**
     * Finds the primary key property of this entity.
     * @returns The primary key property of this entity or undefined if not found.
     */
    primaryKey(): DomainProperty | undefined;
    /**
     * Adds or updates a semantic to the entity.
     * @param semantic The semantic to add to the entity.
     * @throws Error if the semantic is not an entity semantic.
     */
    addSemantic(semantic: AppliedDataSemantic): void;
    /**
     * Removes a semantic from the entity.
     * @param semanticId The ID of the semantic to remove.
     */
    removeSemantic(semanticId: SemanticType): void;
    /**
     * Checks if the entity has a specific semantic.
     * @param semanticId The ID of the semantic to check.
     * @returns True if the semantic is present, false otherwise.
     */
    hasSemantic(semanticId: SemanticType): boolean;
    /**
     * Generates a unique name by appending a number to the base name.
     * @param baseName The base name to make unique.
     * @returns A unique name within the current entity.
     */
    generateUniqueName(baseName: string): string;
}
//# sourceMappingURL=DomainEntity.d.ts.map