import type { DataDomain } from './DataDomain.js';
import { DomainNamespaceKind } from '../models/kinds.js';
import { DomainElement, DomainElementSchema } from './DomainElement.js';
import { IThing, Thing } from '../models/Thing.js';
import { DomainModel, DomainModelSchema } from './DomainModel.js';
export interface NamespaceOrderedItem {
    /**
     * The type of the ordered item.
     */
    type: 'namespace' | 'model';
    /**
     * The key of the ordered item.
     */
    key: string;
}
export interface DomainNamespaceSchema extends DomainElementSchema {
    kind: typeof DomainNamespaceKind;
    /**
     * The data namespace description.
     */
    info: IThing;
    /**
     * The ordered list of fields (namespace and models) in the schema.
     * These only keep references to define the order of these properties
     * in the schema as graph won't do it.
     */
    fields?: NamespaceOrderedItem[];
    /**
     * Whether this namespace is deprecated.
     */
    deprecated?: boolean;
}
/**
 * The domain namespace is a way to create a logical structure around data models.
 * It groups data models that represent a whole schema, like a Product data namespace
 * can have data models that describe: the product data model, price history data model,
 * product location, etc.
 *
 * It is optional to have a namespace, but it is recommended to have one for complex
 * data domains.
 *
 * A data domain can be a child of another data domain. It can also contain multiple
 * data domains and data models.
 */
export declare class DomainNamespace extends DomainElement {
    kind: typeof DomainNamespaceKind;
    /**
     * The description of the domain namespace.
     */
    accessor info: Thing;
    /**
     * The ordered list of fields (namespace and models) in the schema.
     * These only keep references to define the order of these properties
     * in the schema as graph won't do it.
     */
    accessor fields: NamespaceOrderedItem[];
    /**
     * Whether this namespace is deprecated.
     */
    accessor deprecated: boolean | undefined;
    /**
     * Creates a full namespace schema with defaults.
     * @param input The partial namespace schema.
     * @returns The namespace schema.
     */
    static createSchema(input?: Partial<DomainNamespaceSchema>): DomainNamespaceSchema;
    /**
     * Creates a new namespace instance.
     * It does not add it to the graph.
     * You need to call the `addNamespace` method of the graph to add it.
     *
     * @param root A reference to the root DataDomain instance.
     * @param input The partial namespace schema.
     * @returns Created namespace instance.
     */
    constructor(root: DataDomain, input?: Partial<DomainNamespaceSchema>);
    toJSON(): DomainNamespaceSchema;
    /**
     * Adds a child namespace to the current namespace.
     *
     * @param value The partial namespace schema.
     * @returns The created namespace instance.
     * @example
     * ```typescript
     * const property = namespace.addNamespace({
     *   key: 'e-commerce'
     * })
     * ```
     */
    addNamespace(value?: Partial<DomainNamespaceSchema>): DomainNamespace;
    /**
     * Removes a namespace from the current namespace.
     *
     * @param key The key of the namespace to remove.
     * @throws {RemoveNamespaceException} If the namespace does not exist.
     * @example
     * ```typescript
     * namespace.removeNamespace('e-commerce')
     * ```
     */
    removeNamespace(key: string): this;
    /**
     * Attaches a namespace to the current namespace. It changes the parent of the namespace
     * to the current namespace in the graph.
     *
     * The attached namespace must be already a child of another namespace.
     *
     * @param key The key of the namespace to attach.
     * @throws {Error} If the namespace does not exist.
     * @example
     * ```typescript
     * namespace.attachNamespace('e-commerce')
     * ```
     */
    attachNamespace(key: string): this;
    /**
     * Detaches a namespace from the current namespace. It changes the parent of the namespace
     * to the root graph.
     * Unlike remove, it doesn't remove the namespace from the graph nor notifies the change.
     * @param key The key of the namespace to detach.
     * @throws {RemoveNamespaceException} If the namespace does not exist.
     */
    detachNamespace(key: string): this;
    /**
     * Lists all namespaces of this namespaces.
     *
     * Note, it accounts for the order of the namespaces as
     * defined in the `fields` array.
     *
     * @returns A generator that yields each `DomainNamespace`.
     * @example
     * ```typescript
     * for (const ns of namespace.listNamespaces()) {
     *   console.log(ns.key);
     * }
     * ```
     */
    listNamespaces(): Generator<DomainNamespace>;
    /**
     * Checks if this namespace has any namespaces.
     *
     * @returns True if the namespace has namespaces.
     * @example
     * ```typescript
     * if (namespace.hasNamespaces()) {
     *   // ...
     * }
     * ```
     */
    hasNamespaces(): boolean;
    /**
     * Adds a data model to the current namespace.
     * @param value The partial data model schema.
     * @returns The created data model instance.
     * @example
     * ```typescript
     * const property = namespace.addModel({
     *   key: 'inventory'
     * })
     * ```
     */
    addModel(input?: Partial<DomainModelSchema>): DomainModel;
    /**
     * Removes a data model from the current namespace.
     *
     * @param key The key of the data model to remove.
     * @throws {RemoveModelException} If the data model does not exist.
     * @example
     * ```typescript
     * namespace.removeModel('inventory')
     * ```
     */
    removeModel(key: string): this;
    /**
     * Attaches a model to the current namespace and sets its parent to the current namespace.
     *
     * The attached model is already a child of another namespace.
     * This method only adds this model to its internal list of fields.
     *
     * Unlike `addModel`, it doesn't create a new model or add it to the graph.
     * It only adds the model to the list of fields.
     *
     * @param key The key of the model to attach.
     * @throws {AttachException} If the model does not exist.
     * @throws {AttachException} If the model is not a model.
     * @throws {AttachException} If the model is not in the same domain.
     * @throws {AttachException} If the model is already a child of this namespace.
     * @example
     * ```typescript
     * namespace.attachModel('inventory')
     * ```
     */
    attachModel(key: string): this;
    /**
     * Detaches a model from the current namespace and sets its parent to the root graph.
     * Unlike remove, it doesn't remove the model from the graph nor notifies the change.
     * @param key The key of the model to detach.
     * @throws {DetachException} If the model does not exist.
     * @throws {DetachException} If the model is not a model.
     * @throws {DetachException} If the model is not a child of this namespace.
     */
    detachModel(key: string): this;
    /**
     * Lists all models of this namespaces.
     *
     * Note, it accounts for the order of the models as
     * defined in the `fields` array.
     *
     * @returns A generator that yields each `DomainModel`.
     * @example
     * ```typescript
     * for (const ns of namespace.listModels()) {
     *   console.log(ns.key);
     * }
     * ```
     */
    listModels(): Generator<DomainModel>;
    /**
     * Checks if this namespace has any models.
     *
     * @returns True if the namespace has models.
     * @example
     * ```typescript
     * if (namespace.hasModels()) {
     *   // ...
     * }
     * ```
     */
    hasModels(): boolean;
    /**
     * Returns a parent data namespace or the data domain where this data namespace exist.
     */
    getParentInstance(): DomainNamespace | DataDomain;
    /**
     * Lists all fields (namespace and models) of this namespace.
     *
     * @returns A generator that yields each `DomainAssociation` or `DomainProperty`.
     * @example
     * ```typescript
     * for (const field of namespace.listFields()) {
     *   console.log(field.key);
     * }
     * ```
     */
    listFields(): Generator<DomainNamespace | DomainModel>;
    /**
     * Checks if this namespace has any fields (namespace and models).
     *
     * @returns True if the namespace has fields.
     * @example
     * ```typescript
     * if (namespace.hasFields()) {
     *   // ...
     * }
     * ```
     */
    hasFields(): boolean;
    private removeField;
    /**
     * Checks whether the namespace is a child of the given namespace.
     * The relationship doesn't have to be direct, as long as the namespace is in the hierarchy it will return true.
     *
     * @param key The key of the parent namespace to check.
     * @returns True if this namespace is a child of the given namespace.
     */
    isChildOf(key: string): boolean;
}
//# sourceMappingURL=DomainNamespace.d.ts.map