import * as API from '@unito/integration-api';
import Logger from './logger.js';
import { Credentials } from '../middlewares/credentials.js';
import { Secrets } from '../middlewares/secrets.js';
import { Filter } from '../middlewares/filters.js';
type Maybe<T> = T | null;
type Empty = Record<string, never>;
type Params = Record<string, string>;
type Query = {
    [key: string]: undefined | string | string[] | Query | Query[];
};
type CreateItemBody = API.CreateItemRequestPayload;
type CreateBlobBody = API.CreateBlobRequestPayload;
type UpdateItemBody = API.UpdateItemRequestPayload;
/**
 * The base context object is passed to every handler function.
 *
 * It contains the parsed request params, query string, credentials, secrets, etc.
 */
export type Context<P extends Maybe<Params> = Maybe<Params>, Q extends Maybe<Query> = Maybe<Query>> = {
    /**
     * The parsed credentials associated with the request through the X-Unito-Credentials header.
     *
     * Will contain the keys for the variables defined in the corresponding configuration's authorization.
     */
    credentials: Credentials;
    /**
     * The parsed secrets associated with the request through the X-Unito-Secrets header.
     *
     * Will contain the keys for the secrets defined in the corresponding configuration's secrets.
     */
    secrets: Secrets;
    /**
     * The logger pre decorated with the correlation ID and the additionnal metadata provided through the request headers.
     */
    logger: Logger;
    /**
     * Each request is expected to complete within a certain time frame. This signal object has been instantiated with the
     * X-Unito-Operation-Deadline header. This header contains the timestamp after which Unito will consider the operation
     * to be timed out. You can use this signal to abort any operation that would exceed this time frame.
     */
    signal: AbortSignal | undefined;
    /**
     * The request params.
     *
     * A call to `/customers/:customerId/subscriptions/:subscriptionId` => `/customers/123/subscriptions/2` will yield:
     *
     * {
     *  customerId: '123',
     *  subscriptionId: '2'
     * }
     */
    params: P;
    /**
     * The raw query string parsed as an object.
     */
    query: Q;
};
/**
 * Context received by the `GetItemHandler`.
 *
 * @see {@link Context}
 */
export type GetItemContext<P extends Maybe<Params> = Empty, Q extends Query = Empty> = Context<P, Q>;
/**
 * Context received by the `GetBlobHandler`, same as `GetItemContext`.
 *
 * @see {@link Context}
 */
export type GetBlobContext<P extends Maybe<Params> = Empty, Q extends Query = Empty> = Context<P, Q>;
/**
 * Context received by the `GetCollectionHandler`.
 *
 * @filters Array of {@link Filter} representing the filterss parsed from the query params
 * @see {@link Context} for base params
 */
export type GetCollectionContext<P extends Maybe<Params> = Empty, Q extends Query = Empty> = Context<P, Q> & {
    /**
     * Parsed filter query param yielding a list of filters.
     *
     *  Given a filter query param:
     *  `filter=name=John,department.name=Engineering`
     *
     *  Context.filters will be:
     *  [
     *    { field: 'name', operator: 'EQUAL', values: ['John'] },
     *    { field: 'department.name', operator: 'EQUAL', values: ['Engineering'] }
     *  ]
     *
     * @see {@link Filter}
     */
    filters: Filter[];
    /**
     * Parsed search query param yielding a free-text search query.
     *
     *  Given a search query param:
     *  `search=John`
     *
     *  Context.search will be:
     *  'John'
     */
    search: string | null;
    /**
     * Parsed select query param yielding a list of fields to select.
     *
     *  Given a select query param:
     *  `select=name,department.name`
     *
     *  Context.selects will be:
     *  ['name', 'department.name']
     */
    selects: string[];
    /**
     * Parsed relations query param yielding a list of relation for which the path should be returned.
     *
     *  Given a relations query param:
     *  `relations=items,subitems`
     *
     *  Context.relations will be:
     *  ['items', 'subitems']
     */
    relations: string[];
};
export type CreateItemContext<P extends Maybe<Params> = Empty, Q extends Maybe<Query> = Empty, B extends CreateItemBody = API.CreateItemRequestPayload> = Context<P, Q> & {
    body: B;
};
export type CreateBlobContext<P extends Maybe<Params> = Empty, Q extends Maybe<Query> = Empty, B extends CreateBlobBody = API.CreateBlobRequestPayload> = Context<P, Q> & {
    body: B;
};
export type UpdateItemContext<P extends Maybe<Params> = Empty, Q extends Maybe<Query> = Empty, B extends UpdateItemBody = API.UpdateItemRequestPayload> = Context<P, Q> & {
    body: B;
};
export type DeleteItemContext<P extends Maybe<Params> = Empty, Q extends Query = Empty> = Context<P, Q>;
export type GetCredentialAccountContext<P extends Maybe<Params> = Empty, Q extends Query = Empty> = Context<P, Q>;
export type ParseWebhooksContext<P extends Maybe<Params> = Empty, Q extends Maybe<Query> = Empty, B extends API.WebhookParseRequestPayload = API.WebhookParseRequestPayload> = Omit<Context<P, Q>, 'credentials'> & {
    body: B;
};
export type UpdateWebhookSubscriptionsContext<P extends Maybe<Params> = Empty, Q extends Maybe<Query> = Empty, B extends API.WebhookSubscriptionRequestPayload = API.WebhookSubscriptionRequestPayload> = Context<P, Q> & {
    body: B;
};
export type AcknowledgeWebhooksContext<P extends Maybe<Params> = Empty, Q extends Maybe<Query> = Empty, B extends API.WebhookParseRequestPayload = API.WebhookParseRequestPayload> = Omit<Context<P, Q>, 'credentials'> & {
    body: B;
};
export {};
