/**
 * FrontendModelResourceControllerArgs type.
 * @typedef {object} FrontendModelResourceControllerArgs
 * @property {import("../controller.js").default} controller - Frontend-model controller instance.
 * @property {typeof import("../database/record/index.js").default} modelClass - Backing model class.
 * @property {string} modelName - Model name.
 * @property {import("../configuration-types.js").VelociousLooseObject} params - Request params.
 * @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration} resourceConfiguration - Normalized resource configuration (or raw input shape during early bootstrap).
 */
/**
 * FrontendModelResourceAbilityArgs type.
 * @typedef {object} FrontendModelResourceAbilityArgs
 * @property {import("../authorization/ability.js").default} [ability] - Ability instance when the resource is used directly for authorization.
 * @property {import("../configuration-types.js").VelociousLooseObject} [context] - Ability context.
 * @property {import("../configuration-types.js").VelociousLooseObject} [locals] - Ability locals.
 * @property {typeof import("../database/record/index.js").default} [modelClass] - Optional backing model class override.
 * @property {string} [modelName] - Optional model name override.
 * @property {import("../configuration-types.js").VelociousLooseObject} [params] - Optional params override.
 * @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration} [resourceConfiguration] - Optional normalized resource configuration.
 */
/**
 * Base class for backend frontend-model resources.
 * @template {typeof import("../database/record/index.js").default} [out TModelClass=typeof import("../database/record/index.js").default]
 */
export default class FrontendModelBaseResource<out TModelClass extends typeof import("../database/record/index.js").default = typeof import("../database/record/index.js").default> extends AuthorizationBaseResource {
    /**
     * Attributes.
      @type {Record<string, ?> | string[] | undefined} */
    static attributes: Record<string, unknown> | string[] | undefined;
    /**
     * Abilities.
      @type {string[] | undefined} */
    static abilities: string[] | undefined;
    /**
     * Attachments.
      @type {Record<string, ?> | undefined} */
    static attachments: Record<string, unknown> | undefined;
    /**
     * Collection commands.
      @type {string[] | undefined} */
    static collectionCommands: string[] | undefined;
    /**
     * Built in collection commands.
      @type {string[] | undefined} */
    static builtInCollectionCommands: string[] | undefined;
    /**
     * Member commands.
      @type {string[] | undefined} */
    static memberCommands: string[] | undefined;
    /**
     * Built in member commands.
      @type {string[] | undefined} */
    static builtInMemberCommands: string[] | undefined;
    /**
     * Relationships.
      @type {string[] | undefined} */
    static relationships: string[] | undefined;
    /**
     * Translated attributes.
      @type {string[] | undefined} */
    static translatedAttributes: string[] | undefined;
    /**
     * Runs resource config.
     * @returns {import("../configuration-types.js").FrontendModelResourceConfiguration} - Static resource config (raw user input shape; consumers normalize).
     */
    static resourceConfig(): import("../configuration-types.js").FrontendModelResourceConfiguration;
    /**
     * Runs constructor.
     * @param {FrontendModelResourceAbilityArgs | FrontendModelResourceControllerArgs} args - Resource args.
     */
    constructor(args: FrontendModelResourceAbilityArgs | FrontendModelResourceControllerArgs);
    controller: import("../controller.js").default | undefined;
    modelClassValue: typeof import("../database/record/index.js").default | undefined;
    modelNameValue: string | undefined;
    paramsValue: import("../configuration-types.js").VelociousLooseObject | undefined;
    resourceConfigurationValue: import("../configuration-types.js").FrontendModelResourceConfiguration | import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | undefined;
    /**
     * Runs typed controller instance.
     * @returns {import("../controller.js").default & {
     *   frontendModelAuthorizedQuery: (action: "index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url") => import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>,
     *   frontendModelAbilityAction: (action: string) => string,
     *   currentAbility: () => import("../authorization/ability.js").default | undefined,
     *   frontendModelIndexQuery: () => import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>,
     *   frontendModelPreload: () => import("../database/query/index.js").NestedPreloadRecord | null,
     *   serializeFrontendModel: (model: import("../database/record/index.js").default) => Promise<Record<string, unknown>>
     * }} - Controller instance with frontend-model helpers.
     */
    typedControllerInstance(): import("../controller.js").default & {
        frontendModelAuthorizedQuery: (action: "index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url") => import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>;
        frontendModelAbilityAction: (action: string) => string;
        currentAbility: () => import("../authorization/ability.js").default | undefined;
        frontendModelIndexQuery: () => import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>;
        frontendModelPreload: () => import("../database/query/index.js").NestedPreloadRecord | null;
        serializeFrontendModel: (model: import("../database/record/index.js").default) => Promise<Record<string, unknown>>;
    };
    /**
     * Runs controller instance.
     * @returns {import("../controller.js").default} - Controller instance.
     */
    controllerInstance(): import("../controller.js").default;
    /**
     * Runs model class.
     * @returns {TModelClass} - Model class.
     */
    modelClass(): TModelClass;
    /**
     * Runs model name.
     * @returns {string} - Model name.
     */
    modelName(): string;
    /**
     * Runs params.
     * @returns {import("../configuration-types.js").VelociousLooseObject} - Params.
     */
    params(): import("../configuration-types.js").VelociousLooseObject;
    /**
     * Runs resource configuration.
     * @returns {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration} - Resource config (normalized at runtime; raw during early bootstrap).
     */
    resourceConfiguration(): import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration;
    /**
     * Returns a Rails-strong-params / api_maker-style permit spec declaring
     * which attributes and nested attributes are writable for the current
     * request. Submitting an attribute or nested-relationship key that is
     * not permitted raises an error and fails the write.
     *
     * The returned value is a flat array that mixes:
     *   - `"attributeName"` strings for plain attribute writes
     *   - `{<relationshipName>Attributes: [...]}` objects where the value
     *     is itself a permit spec for the nested relationship
     *
     * This matches Rails strong_params (`permit(:first_name, :last_name,
     * contact_attributes: [:email, details_attributes: [:detail]])`) and
     * the api_maker sister project. Include `"_destroy"` inside a nested
     * permit to allow `_destroy: true` entries for that relationship —
     * the model must also declare `acceptsNestedAttributesFor(name,
     * {allowDestroy: true})` for the destroy to be applied.
     *
     * Example:
     *
     *   class ProjectResource extends FrontendModelBaseResource {
     *     permittedParams(arg) {
     *       return [
     *         "name",
     *         "description",
     *         {tasksAttributes: ["id", "_destroy", "name",
     *           {subtasksAttributes: ["id", "_destroy", "name"]}
     *         ]}
     *       ]
     *     }
     *   }
     *
     * Default implementation returns `[]` — nothing permitted. Subclasses
     * must override to enable writes. A resource that does not declare
     * `permittedParams` cannot accept any write.
     * @param {{action?: "create" | "update", params?: Record<string, ?>, ability?: import("../authorization/ability.js").default, locals?: Record<string, ?>}} [arg] - Request context.
     * @returns {Array<string | Record<string, ?>>} - Permit spec.
     */
    permittedParams(arg?: {
        action?: "create" | "update";
        params?: Record<string, unknown>;
        ability?: import("../authorization/ability.js").default;
        locals?: Record<string, unknown>;
    }): Array<string | Record<string, unknown>>;
    /**
     * Runs primary key.
     * @returns {string} - Primary key.
     */
    primaryKey(): string;
    /**
     * Runs authorized query.
     * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Ability action.
     * @template {typeof import("../database/record/index.js").default} [MC=typeof import("../database/record/index.js").default]
     * @returns {import("../database/query/model-class-query.js").default<MC>} - Authorized query.
     */
    authorizedQuery<MC extends typeof import("../database/record/index.js").default = typeof import("../database/record/index.js").default>(action: "index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"): import("../database/query/model-class-query.js").default<MC>;
    /**
     * Runs supports pluck.
     * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Action.
     * @returns {boolean | Promise<boolean>} - Whether pluck is supported.
     */
    supportsPluck(action: "index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"): boolean | Promise<boolean>;
    /**
     * Runs supports count.
     * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Action.
     * @returns {boolean | Promise<boolean>} - Whether count is supported.
     */
    supportsCount(action: "index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"): boolean | Promise<boolean>;
    /**
     * Runs before action.
     * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Action.
     * @returns {boolean | void | Promise<boolean | void>} - Continue processing unless false.
     */
    beforeAction(action: "index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"): boolean | void | Promise<boolean | void>;
    /**
     * Runs records.
     * @returns {Promise<import("../database/record/index.js").default[]>} - Records for index action.
     */
    records(): Promise<import("../database/record/index.js").default[]>;
    /**
     * Runs count.
     * @returns {Promise<number>} - Records count for index action.
     */
    count(): Promise<number>;
    /**
     * Runs find.
     * @param {"find" | "update" | "destroy" | "attach" | "download" | "url"} action - Action.
     * @param {string | number} id - Record id.
     * @returns {Promise<import("../database/record/index.js").default | null>} - Located model.
     */
    find(action: "find" | "update" | "destroy" | "attach" | "download" | "url", id: string | number): Promise<import("../database/record/index.js").default | null>;
    /**
     * Runs create.
     * @param {Record<string, ?>} attributes - Create attributes.
     * @param {{controller?: ?, nestedAttributes?: Record<string, ?> | null}} [options] - Save options.
     * @returns {Promise<import("../database/record/index.js").default>} - Created model.
     */
    create(attributes: Record<string, unknown>, options?: {
        controller?: unknown;
        nestedAttributes?: Record<string, unknown> | null;
    }): Promise<import("../database/record/index.js").default>;
    /**
     * Runs handle unauthorized created model.
     * @param {import("../database/record/index.js").default} model - Created model.
     * @returns {Promise<void>} - Cleanup after failed authorization.
     */
    handleUnauthorizedCreatedModel(model: import("../database/record/index.js").default): Promise<void>;
    /**
     * Runs update.
     * @param {import("../database/record/index.js").default} model - Existing model.
     * @param {Record<string, ?>} attributes - Update attributes.
     * @param {{controller?: ?, nestedAttributes?: Record<string, ?> | null}} [options] - Save options.
     * @returns {Promise<import("../database/record/index.js").default>} - Updated model.
     */
    update(model: import("../database/record/index.js").default, attributes: Record<string, unknown>, options?: {
        controller?: unknown;
        nestedAttributes?: Record<string, unknown> | null;
    }): Promise<import("../database/record/index.js").default>;
    /**
     * Saves a model and applies nested attributes in one transaction.
     * @param {{filtered: Record<string, ?>, model: import("../database/record/index.js").default, options: {controller?: ?, nestedAttributes?: Record<string, ?> | null}, permit: {attributes: string[], nested: Record<string, ?>}}} args - Save arguments.
     * @returns {Promise<import("../database/record/index.js").default>} - Saved model.
     */
    _saveWithNestedAttributes({ filtered, model, options, permit }: {
        filtered: Record<string, unknown>;
        model: import("../database/record/index.js").default;
        options: {
            controller?: unknown;
            nestedAttributes?: Record<string, unknown> | null;
        };
        permit: {
            attributes: string[];
            nested: Record<string, unknown>;
        };
    }): Promise<import("../database/record/index.js").default>;
    /**
     * Assigns attributes to a model, using virtual setters on the resource when available.
     * @param {import("../database/record/index.js").default} model - Model instance.
     * @param {Record<string, ?>} attributes - Attributes to assign.
     * @returns {Promise<void>}
     */
    _assignWithVirtualSetters(model: import("../database/record/index.js").default, attributes: Record<string, unknown>): Promise<void>;
    /**
     * Sets a translated attribute on a model via the translations relationship.
     * @param {import("../database/record/index.js").default} model - Model instance.
     * @param {string} name - Attribute name.
     * @param {?} value - Attribute value.
     * @returns {Promise<void>}
     */
    _setTranslatedAttributeOnModel(model: import("../database/record/index.js").default, name: string, value: unknown): Promise<void>;
    /**
     * Runs destroy.
     * @param {import("../database/record/index.js").default} model - Existing model.
     * @returns {Promise<void>} - No return value.
     */
    destroy(model: import("../database/record/index.js").default): Promise<void>;
    /**
     * Runs serialize.
     * @param {import("../database/record/index.js").default} model - Model to serialize.
     * @param {"index" | "find" | "create" | "update"} [action] - Action.
     * @returns {Promise<Record<string, ?>>} - Serialized model payload.
     */
    serialize(model: import("../database/record/index.js").default, action?: "index" | "find" | "create" | "update"): Promise<Record<string, unknown>>;
    /**
     * Applies a `nestedAttributes` payload to a freshly-saved parent model,
     * cascading create/update/destroy writes across the declared relationships.
     *
     * Each child is authorized against its own resource's abilities (never the
     * parent's). Destroys run before updates, updates before creates, to avoid
     * unique-constraint conflicts when replacing a child at the same natural key.
     *
     * Attribute filtering for nested children uses the parent resource's
     * permit spec for that relationship — api_maker-style. Policy options
     * (allowDestroy, limit, rejectIf) come from the MODEL's
     * `acceptedNestedAttributesFor(name)` declaration.
     * @param {import("../database/record/index.js").default} parent - Parent model instance.
     * @param {Record<string, ?>} nestedAttributes - Nested-attribute payload keyed by relationship name.
     * @param {?} controller - Controller instance for resource resolution and authorization.
     * @param {{attributes: string[], nested: Record<string, ?>} | null} [parentPermit] - Parsed parent permit spec.
     * @returns {Promise<void>}
     */
    _applyNestedAttributes(parent: import("../database/record/index.js").default, nestedAttributes: Record<string, unknown>, controller: unknown, parentPermit?: {
        attributes: string[];
        nested: Record<string, unknown>;
    } | null): Promise<void>;
    /**
     * Resolves the ability action for a child resource using the child's own
     * `abilities` mapping — never the parent controller's. This preserves
     * custom mappings like `{update: "manage"}` and catches unmapped actions
     * instead of silently defaulting to the raw action name.
     * @param {import("../configuration-types.js").FrontendModelResourceConfiguration} childResourceConfiguration - Child resource configuration.
     * @param {"create" | "update" | "destroy"} action - Frontend action.
     * @returns {string} - Ability action for the child resource.
     */
    _resolveChildAbilityAction(childResourceConfiguration: import("../configuration-types.js").FrontendModelResourceConfiguration, action: "create" | "update" | "destroy"): string;
    /**
     * Finds an existing child for a nested update/destroy, scoped to the
     * child's own model class, the parent's foreign key, AND the child
     * resource's ability mapping for the requested action. Throws when the
     * child does not exist, does not belong to the current parent, or is
     * not authorized — all of which must roll the transaction back.
     * @param {object} args - Arguments.
     * @param {import("../authorization/ability.js").default | undefined} args.ability - Current ability.
     * @param {"update" | "destroy"} args.action - Frontend action.
     * @param {import("../configuration-types.js").FrontendModelResourceConfiguration} args.childResourceConfiguration - Child resource configuration.
     * @param {string} args.foreignKey - Foreign-key attribute on the child pointing to the parent.
     * @param {string | number} args.id - Child id from the payload.
     * @param {import("../database/record/index.js").default} args.parent - Parent model instance.
     * @param {string} args.relationshipName - Parent's relationship name (for error messages).
     * @param {typeof import("../database/record/index.js").default} args.targetModelClass - Child model class.
     * @returns {Promise<import("../database/record/index.js").default>} - Authorized, parent-linked child model.
     */
    _findScopedChild({ ability, action, childResourceConfiguration, foreignKey, id, parent, relationshipName, targetModelClass }: {
        ability: import("../authorization/ability.js").default | undefined;
        action: "update" | "destroy";
        childResourceConfiguration: import("../configuration-types.js").FrontendModelResourceConfiguration;
        foreignKey: string;
        id: string | number;
        parent: import("../database/record/index.js").default;
        relationshipName: string;
        targetModelClass: typeof import("../database/record/index.js").default;
    }): Promise<import("../database/record/index.js").default>;
    /**
     * Verifies an already-saved nested child is authorized under the child
     * resource's own `create` ability. Rolls back via thrown error when not
     * authorized so the outer transaction destroys the insert.
     * @param {object} args - Arguments.
     * @param {import("../authorization/ability.js").default | undefined} args.ability - Current ability.
     * @param {import("../database/record/index.js").default} args.child - Child model instance just created.
     * @param {import("../configuration-types.js").FrontendModelResourceConfiguration} args.childResourceConfiguration - Child resource configuration.
     * @param {string} args.relationshipName - Parent's relationship name (for error messages).
     * @param {typeof import("../database/record/index.js").default} args.targetModelClass - Child model class.
     * @returns {Promise<void>}
     */
    _authorizeCreatedChild({ ability, child, childResourceConfiguration, relationshipName, targetModelClass }: {
        ability: import("../authorization/ability.js").default | undefined;
        child: import("../database/record/index.js").default;
        childResourceConfiguration: import("../configuration-types.js").FrontendModelResourceConfiguration;
        relationshipName: string;
        targetModelClass: typeof import("../database/record/index.js").default;
    }): Promise<void>;
    /**
     * Best-effort foreign-key inference for relationships that don't declare it.
     * @param {import("../database/record/index.js").default} parent - Parent model.
     * @param {{foreignKey?: string}} definition - Relationship definition.
     * @returns {string} - Foreign-key attribute name.
     */
    _inferForeignKey(parent: import("../database/record/index.js").default, definition: {
        foreignKey?: string;
    }): string;
    /**
     * After nested writes, preload every relationship declared in the
     * parent's permit so the post-save serialize step emits them and the
     * client can reconcile ids.
     * @param {import("../database/record/index.js").default} model - Saved parent model.
     * @param {{attributes: string[], nested: Record<string, ?>}} permit - Parsed parent permit.
     * @returns {Promise<void>}
     */
    _preloadNestedWritableRelationships(model: import("../database/record/index.js").default, permit: {
        attributes: string[];
        nested: Record<string, unknown>;
    }): Promise<void>;
}
/**
 * FrontendModelResourceControllerArgs type.
 */
export type FrontendModelResourceControllerArgs = {
    /**
     * - Frontend-model controller instance.
     */
    controller: import("../controller.js").default;
    /**
     * - Backing model class.
     */
    modelClass: typeof import("../database/record/index.js").default;
    /**
     * - Model name.
     */
    modelName: string;
    /**
     * - Request params.
     */
    params: import("../configuration-types.js").VelociousLooseObject;
    /**
     * - Normalized resource configuration (or raw input shape during early bootstrap).
     */
    resourceConfiguration: import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration;
};
/**
 * FrontendModelResourceAbilityArgs type.
 */
export type FrontendModelResourceAbilityArgs = {
    /**
     * - Ability instance when the resource is used directly for authorization.
     */
    ability?: import("../authorization/ability.js").default | undefined;
    /**
     * - Ability context.
     */
    context?: import("../configuration-types.js").VelociousLooseObject | undefined;
    /**
     * - Ability locals.
     */
    locals?: import("../configuration-types.js").VelociousLooseObject | undefined;
    /**
     * - Optional backing model class override.
     */
    modelClass?: typeof import("../database/record/index.js").default | undefined;
    /**
     * - Optional model name override.
     */
    modelName?: string | undefined;
    /**
     * - Optional params override.
     */
    params?: import("../configuration-types.js").VelociousLooseObject | undefined;
    /**
     * - Optional normalized resource configuration.
     */
    resourceConfiguration?: import("../configuration-types.js").FrontendModelResourceConfiguration | import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | undefined;
};
import AuthorizationBaseResource from "../authorization/base-resource.js";
//# sourceMappingURL=base-resource.d.ts.map