/** * Deep JSON value with no `undefined` — every key/slot is present as * {@link ApiJsonValue} (use `null` for missing nested values). * * Used for opaque API blobs (partner, accounts, …) until dedicated *Model * types exist. Prefer typed models when the wire schema is stable. */ /** JSON primitive including explicit `null`. */ type ApiJsonPrimitive = string | number | boolean | null; /** * Plain object whose values are recursively {@link ApiJsonValue} * (never `undefined`). */ interface ApiJsonObjectModel { readonly [key: string]: ApiJsonValue; } /** * Null-safe JSON tree for untyped API subtrees. */ type ApiJsonValue = ApiJsonPrimitive | readonly ApiJsonValue[] | ApiJsonObjectModel; /** * Field-level validation or business-rule error returned inside an API envelope. * * Laravel-style bags (`{ name: ["…"], value: ["…"] }` in `errors` or failure * `data`) are normalized by the SDK into this array. Prefer `errors` for forms * (`fieldErrorsMap`) and joined `message` / `formatApiErrorMessage` for toasts — * the wire top-level `message` alone is often only the first field. */ interface ApiErrorDetailModel { field: string | null; message: string; code: string | null; } /** * Pagination metadata accompanying list responses. * * Field names match the wire (snake_case). */ interface PaginationMetaModel { current_page: number; per_page: number; total_items: number; total_pages: number; has_next_page: boolean; has_previous_page: boolean; } /** * Canonical API response envelope normalized by the SDK HTTP client. * * Every field is explicitly `| null` (never optional/undefined) so consumers * can rely on null-checks regardless of which subset the backend included. * Field names match the wire where the backend embeds them (`status_code`). * * @typeParam T - Shape of the successful payload in `data`. */ interface ApiResponseModel { success: boolean; message: string | null; data: T | null; errors: ApiErrorDetailModel[] | null; pagination: PaginationMetaModel | null; /** Application-level status when the body includes `status_code`. */ status_code: number | null; } /** * Allowed page sizes for list pagination (`size` query param). */ declare const PAGINATION_PAGE_SIZES: readonly [5, 15, 30]; /** One of {@link PAGINATION_PAGE_SIZES}. */ type PaginationPageSize = (typeof PAGINATION_PAGE_SIZES)[number]; /** Default `size` on paginated resource GETs. */ declare const DEFAULT_PAGE_SIZE: PaginationPageSize; /** Inbox / notification list page size. */ declare const NOTIFICATION_PAGE_SIZE: PaginationPageSize; /** * Resource identifier convention for AFRICANIES list/detail GET endpoints * on paths shaped like `/{basePath}/{id?}`. * * Applies to **all** list-style GETs (built-in SDK services and custom * `ApiClient.getResource*` / `buildResourcePath` calls): * * | Value | Meaning | Path | Pagination | * |-------|---------|------|------------| * | `null` | Paginated page (SDK default {@link DEFAULT_PAGE_SIZE} `15` unless overridden) | `{basePath}` | `page` / `size` / `order` apply | * | `'all'` | Full dump, not paginated | `{basePath}/all` | ignored | * | `number` | Single matching record | `{basePath}/{id}` | ignored | * * Prefer typed helpers when calling custom endpoints: * `getResourcePage`, `getResourceAll`, `getResourceById`, or overloads on * `getResource(basePath, id, query?)`. * * @example * ```ts * const pageId: ResourceId = null; // GET /widgets?page=1 * const allId: ResourceId = 'all'; // GET /widgets/all * const oneId: ResourceId = 42; // GET /widgets/42 * ``` */ type ResourceId = number | 'all' | null; /** * Optional query parameters for paginated resource list requests. * * Fields are optional (not `| null`) because omitted query params mean * "use the backend default" — distinct from sending an explicit null body field. */ interface PaginationQueryParamsModel { /** * 1-based page index to request. * Omitted when the caller accepts the backend's default page. */ page?: number; /** * Page size override. SDK paginated calls default to * {@link DEFAULT_PAGE_SIZE} (`15`) when omitted. Allowed UI sizes: * {@link PAGINATION_PAGE_SIZES} (`5`, `15`, `30`). */ size?: number; /** * Sort / order expression understood by the target endpoint. * Omitted when default ordering is acceptable. */ order?: string; } /** * UI-facing async query snapshot for wrappers such as AsyncStateComponent. * * Mirrors the signals typically exposed by TanStack Query's `injectQuery()` * so apps can map query results into one object without coupling the UI * package to TanStack itself. * * @typeParam T - Successful data shape when a fetch has produced a value. * * @example * ```ts * // Map injectQuery() signals into AsyncQueryStateModel for * const state: AsyncQueryStateModel = { * data: query.data(), * isLoading: query.isLoading(), * isFetching: query.isFetching(), * isError: query.isError(), * error: query.error()?.message ?? null, * }; * ``` */ interface AsyncQueryStateModel { /** * Latest successful data, if any. * `undefined` before the first successful fetch (and often while `isLoading`). * Uses `undefined` (not `null`) to align with TanStack Query's empty-data sentinel. */ data: T | undefined; /** * `true` only on the initial fetch before any data exists. * Distinguishes blocking first-load from background refetch (`isFetching`). */ isLoading: boolean; /** * `true` whenever any fetch is in flight, including background refetches. * May be true while `data` is still present from a prior success. */ isFetching: boolean; /** * `true` if the most recent fetch attempt failed. * Can be true with stale `data` still available after a background error. */ isError: boolean; /** * Human-readable error message for the latest failure. * `null` when `isError` is false or no message is available. */ error: string | null; } /** * Auth request shapes (`POST /auth/…`). * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Request body for `POST /auth/forgot/password`. * * Email-only: the backend emails a reset link. This frontend does **not** * collect a new password for that link (no token in the route). * * Response `data` is typically an empty array — branch on `success` / * `message`. The same body is used from login *and* from admin user/partner * screens that send a reset for someone else's email. */ interface ForgotPasswordRequestModel { /** Registered account email that should receive the reset link. */ email: string; } /** * Country and subdivision shapes from public utility endpoints. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). Mapping in `@africanies/africanies-core` * preserves those keys. */ /** * State / province / region under a {@link CountryModel}. */ interface CountryStateModel { /** Display name (e.g. `"Lagos"`, `"California"`). */ name: string; /** Subdivision code (e.g. `"LA"`, `"CA"`). */ state_code: string; } /** * Country record from `GET /public/country/read/{id|all}`. */ interface CountryModel { /** Numeric country id from the API. */ id: number; /** Official / display country name. */ name: string; /** ISO 3166-1 alpha-3 code (e.g. `"NGA"`). */ iso3: string; /** ISO 3166-1 alpha-2 code (e.g. `"NG"`). */ iso2: string; /** Nested subdivisions; may be an empty array. */ states: CountryStateModel[]; } /** * Currency shapes from utility read endpoints. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). Mapping in `@africanies/africanies-core` * preserves those keys. */ /** * Pivot linking a currency to a payment method (either nested direction). */ interface CurrencyPaymentMethodPivotModel { /** Currency id on the join. */ currency_id: number; /** Payment method id on the join. */ payment_method_id: number; } /** * Payment processor attached to a {@link CurrencyModel}. */ interface CurrencyPaymentMethodModel { /** Numeric payment-method id. */ id: number; /** Display name (e.g. `"Paystack"`, `"Stripe"`). */ name: string; /** Backend model class path (e.g. `"App\\Models\\Stripe"`). */ model: string; /** Whether the method is available. */ active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; /** Join keys for this currency. */ pivot: CurrencyPaymentMethodPivotModel; } /** * Currency record from `GET /currency/read/{id|all}`. * * `division_rate` / `multiplication_rate` stay strings as on the wire * (e.g. `"1"`, `"1400"`). */ interface CurrencyModel { /** Numeric currency id from the API. */ id: number; /** Display name (e.g. `"Naira"`, `"US Dollars"`). */ name: string; /** ISO-style code (e.g. `"NGN"`, `"USD"`). */ short_code: string; /** Wire rate string used when converting from this currency. */ division_rate: string; /** Wire rate string used when converting to this currency. */ multiplication_rate: string; /** Whether the local currency is greater than this unit (GET alias). */ is_local_currency_greater: boolean; /** * Same flag as {@link CurrencyModel.is_local_currency_greater}. * App Settings create/update send this key (`"1"` / `"0"` on the wire). */ is_naira_greater: boolean; /** Whether the currency is available for checkout. */ active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; /** Processors that accept this currency. */ payment_methods: CurrencyPaymentMethodModel[]; } /** `"1"` / `"0"` flag as sent on currency create/update. */ type CurrencyFlag01 = '0' | '1'; /** * Request body for `POST /currency/create` (App Settings → Currencies). * * `name` / `short_code` come from the host’s local currency list, not GET. * The SDK serializes `active` / `is_naira_greater` to `"1"` / `"0"`. */ interface CurrencyCreateRequestModel { name: string; short_code: string; multiplication_rate: string; division_rate: string; /** Boolean or wire `"1"` / `"0"`. */ active: boolean | CurrencyFlag01; /** Boolean or wire `"1"` / `"0"`. */ is_naira_greater: boolean | CurrencyFlag01; payment_method_ids: number[]; } /** * Request body for `PUT /currency/update`. Name and short code are not sent. */ interface CurrencyUpdateRequestModel { id: number; multiplication_rate: string; division_rate: string; active: boolean | CurrencyFlag01; is_naira_greater: boolean | CurrencyFlag01; payment_method_ids: number[]; } /** * Identifier for `DELETE /currency/delete` (JSON body `{ id }`). */ interface CurrencyDeleteRequestModel { id: number; } /** * Hardcoded inbound delivery vendor slugs — same values as legacy portal forms (no API). */ declare const DELIVERY_VENDORS: readonly [{ readonly id: "amazon"; readonly name: "Amazon"; }, { readonly id: "dhl"; readonly name: "DHL"; }, { readonly id: "fedex"; readonly name: "FedEx"; }, { readonly id: "usps"; readonly name: "USPS"; }, { readonly id: "ups"; readonly name: "UPS"; }, { readonly id: "others"; readonly name: "Others"; }]; /** * */ type DeliveryVendorId = (typeof DELIVERY_VENDORS)[number]['id']; /** Export box editor only — not used on inbound receive/edit forms. */ declare const EXPORT_DELIVERY_VENDORS: readonly [{ readonly id: "amazon"; readonly name: "Amazon"; }, { readonly id: "dhl"; readonly name: "DHL"; }, { readonly id: "fedex"; readonly name: "FedEx"; }, { readonly id: "usps"; readonly name: "USPS"; }, { readonly id: "ups"; readonly name: "UPS"; }, { readonly id: "others"; readonly name: "Others"; }, { readonly id: "walk-in"; readonly name: "Walk-In"; }]; /** * */ type ExportDeliveryVendorId = (typeof EXPORT_DELIVERY_VENDORS)[number]['id']; /** @deprecated Prefer {@link DELIVERY_VENDORS}. */ declare const DELIVERY_VENDOR_OPTIONS: { value: "amazon" | "dhl" | "fedex" | "usps" | "ups" | "others"; label: "Amazon" | "DHL" | "FedEx" | "USPS" | "UPS" | "Others"; }[]; /** @deprecated Prefer {@link EXPORT_DELIVERY_VENDORS}. */ declare const BOX_DELIVERY_VENDORS: readonly [{ readonly id: "amazon"; readonly name: "Amazon"; }, { readonly id: "dhl"; readonly name: "DHL"; }, { readonly id: "fedex"; readonly name: "FedEx"; }, { readonly id: "usps"; readonly name: "USPS"; }, { readonly id: "ups"; readonly name: "UPS"; }, { readonly id: "others"; readonly name: "Others"; }, { readonly id: "walk-in"; readonly name: "Walk-In"; }]; /** @deprecated Prefer {@link ExportDeliveryVendorId}. */ type BoxDeliveryVendorId = ExportDeliveryVendorId; /** * * @param value */ declare function normalizeDeliveryVendor(value: string): string; /** * * @param value */ declare function isKnownDeliveryVendor(value: string | null | undefined): boolean; /** * Lowercase known ids; keep raw string for legacy/custom stored values. * @param value */ declare function normalizeDeliveryVendorForForm(value: string | null | undefined): string; /** * * @param value */ declare function deliveryVendorLabel(value: string): string; /** * File read / signed-upload shapes from `POST /file/read` and `POST /file/generate`. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Request body for {@link FileReadModel} fetches. */ interface FileReadRequestModel { /** Storage / document reference UUID. */ ref: string; } /** * One file payload from `POST /file/read`. * * Response `data` is this object (not a list). Prefer {@link FileReadModel.url} * for downloads when the signed URL is present; `base_64` is typically a data * URI (`data:{mime};base64,…`). */ interface FileReadModel { /** MIME type (e.g. `"application/pdf"`). */ mime_type: string; /** * Inline file bytes as a data URI or raw base64 string. * Can be large — avoid logging or binding the full value in UI lists. */ base_64: string; /** Time-limited signed URL for the object (when provided). */ url: string; } /** * Allowed extensions for {@link FileGenerateRequestModel}. * Hosts still filter with `accept` — this is the SDK generate allow-list. */ type FileGenerateExtension = 'jpeg' | 'jpg' | 'png' | 'webp' | 'gif' | 'heic' | 'heif' | 'pdf' | 'doc' | 'docx' | 'xls' | 'xlsx' | 'csv' | 'txt' | 'zip'; /** * Allowed MIME types for {@link FileGenerateRequestModel}. * Hosts still filter with `accept` — this is the SDK generate allow-list. */ type FileGenerateMimeType = 'image/jpeg' | 'image/jpg' | 'image/png' | 'image/webp' | 'image/gif' | 'image/heic' | 'image/heif' | 'application/pdf' | 'application/msword' | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' | 'application/vnd.ms-excel' | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' | 'text/csv' | 'text/plain' | 'application/zip' | 'application/x-zip-compressed'; /** * One entry in the `files` array for `POST /file/generate`. */ interface FileGenerateRequestModel { extension: FileGenerateExtension; mime_type: FileGenerateMimeType; /** Storage folder prefix (e.g. `"images/items"`). */ folder: string; } /** * One signed PUT instruction from `POST /file/generate` (`data[]`). */ interface SignedUploadInstructionModel { upload_url: string; s3_key: string; method: 'PUT'; headers: { 'Content-Type': string; 'x-amz-acl'?: string; }; mime: string; input_name: 'file'; } /** * Document catalog shapes from public utility reads. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Document record from `GET /public/document/read/{id|all}`. * * List rows are usually metadata only. `readById(id)` for App Settings / * Products / Plans preview populates {@link DocumentModel.file_ref} with * `mime_type` and `base_64` (bind `file_ref.base_64` in an `` or PDF viewer). * * For entities that store a raw `file_ref` string (shipments, KYC, waybills), * use {@link FileReadRequestModel} + `POST /file/read` instead. * Authenticated upload/delete use `api/document/*`. */ interface DocumentModel { id: number; name: string; description: string | null; /** Document type / category label when present on the wire. */ type: string | null; active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; /** * Nested preview payload on `readById` responses (`file_ref.base_64`). * Null on list rows and when the wire omits preview bytes. */ file_ref: FileReadModel | null; } /** * Schema-driven list filter contracts for AFRICANIES modules. * * Modules declare a {@link ModuleFilterConfigModel}; the UI drawer renders from * it and {@link toFilterParams} / {@link fromFilterParams} speak to the API. */ /** * Backend wire format for filter query serialization. * * Use {@link resolveFilterTransport} when reading `config.transport` — omit the * property on {@link ModuleFilterConfigModel} to default to legacy-parallel. */ declare const FilterTransport: { /** Laravel-style `filterColumn` + `filterValue` CSV pairs (default). */ readonly LegacyParallel: "legacy-parallel"; /** Each {@link FilterFieldModel.key} is its own query param. */ readonly Named: "named"; }; /** Union of {@link FilterTransport} literal values. */ type FilterTransport = (typeof FilterTransport)[keyof typeof FilterTransport]; /** Default when {@link ModuleFilterConfigModel.transport} is omitted. */ declare const DEFAULT_FILTER_TRANSPORT: "legacy-parallel"; /** How a filter field is rendered and validated in the drawer. */ type FilterFieldType = /** Chip / single-select group — exclusive within the field by default. */ 'enum' /** Free-text scalar (tracking number, etc.). */ | 'text' /** Static or host-resolved option list (warehouse, carrier, …). */ | 'select' /** Yes/no mapped to API scalars (often `'1'` / `'0'`). */ | 'boolean'; /** * Option row for enum / select / boolean fields. * * `color` is a UI hint only (chip styling) — never sent to the API. */ interface FilterOptionModel { /** Canonical value written into filter state / query params. */ value: string; /** Visible label. */ label: string; /** Optional leading text/emoji (e.g. country flag emoji) in select rows. */ prefixText?: string; /** Optional leading image URL (e.g. flag CDN from {@link countryFlagUrl}). */ prefixImageUrl?: string; /** Optional chip / badge color (hex or CSS). */ color?: string; } /** * Well-known async option catalogs resolved by the SDK or host app. * * Built-in wiring ({@link FilterOptionsResolver} in `@africanies/africanies-core`): * - `warehouses` → {@link WarehouseService.readAll} → field keys like `warehouse_id` * - `shipmentMethods` → {@link ShipmentMethodService.readAll} → e.g. `shipment_method_id` * * Pass host `optionLists` for sources without a built-in service (e.g. `shipmentManifests`). */ type FilterOptionsSource = 'shipmentMethods' | 'warehouses' | 'shipmentManifests' | 'static'; /** * One filterable API field inside a {@link ModuleFilterConfigModel}. */ interface FilterFieldModel { /** API `filterColumn` name (e.g. `payment_status`). */ key: string; /** Drawer section label. */ label: string; /** Control kind. */ type: FilterFieldType; /** Static options (enum / boolean / static select). */ options?: FilterOptionModel[]; /** * When true (default for `enum`), selecting a value replaces any prior value * for this key — chip groups are mutually exclusive per field. */ exclusive?: boolean; /** Host-resolved option catalog name for `select` fields. */ optionsSource?: FilterOptionsSource; /** Placeholder for text / select triggers. */ placeholder?: string; } /** * Module-level filter schema — the only per-module difference for list filters. * * @example * ```ts * const trackShipmentsFilterConfig: ModuleFilterConfigModel = { * id: 'track-shipments', * // transport omitted → FilterTransport.LegacyParallel * fields: [ * { key: 'payment_status', label: 'Payment Status', type: 'enum', options: […] }, * ], * }; * ``` */ interface ModuleFilterConfigModel { /** Stable module id (`track-shipments`, `users`, …). */ id: string; /** * Optional portal route segments for docs / deep links * (e.g. `['portal', 'shipment', 'track-shipments']`). */ route?: string[]; /** Free-text search box. */ search?: { param: 'search'; label: string; placeholder?: string; }; /** Date range + which date column the range applies to. */ date?: { rangeParams: { from: 'from'; to: 'to'; }; fieldParam: 'date'; fields: FilterOptionModel[]; }; /** Sort direction control. */ sort?: { param: 'order'; options: FilterOptionModel[]; }; /** Pagination query param names (defaults when omitted at serialize time). */ pagination?: { pageParam: 'page'; sizeParam: 'size'; }; /** Filterable fields rendered in the drawer. */ fields: FilterFieldModel[]; /** * Backend wire format — see {@link FilterTransport}. * Defaults to {@link DEFAULT_FILTER_TRANSPORT} when omitted. */ transport?: FilterTransport; } /** * Preferred UI / feature state for filters. * * Keep values as a map keyed by {@link FilterFieldModel.key}; only flatten to * parallel comma strings at the API / URL boundary. */ interface FilterStateModel { search?: string; /** Inclusive range start (`YYYY-MM-DD`). */ from?: string; /** Inclusive range end (`YYYY-MM-DD`). */ to?: string; /** Which date column `from`/`to` apply to (`created_at`, …). */ date?: string; order?: 'asc' | 'desc' | string; page?: number; size?: number; /** * Field values keyed by {@link FilterFieldModel.key}. * Omit or set `undefined` / `''` to exclude from serialization. */ values: Record; } /** * Flat query / API bag produced by {@link toFilterParams}. * Values are strings (or numbers for page/size) ready for HttpParams / router. */ type FilterParamsModel = Record; /** * Resolved transport for a module config (defaults to {@link DEFAULT_FILTER_TRANSPORT}). * @param config */ declare function resolveFilterTransport(config: Pick): FilterTransport; /** * Track shipments — payment / shipment status chips + tracking number. * Transport: legacy `filterColumn` / `filterValue`. */ declare const trackShipmentsFilterConfig: ModuleFilterConfigModel; /** * Update shipments — richest legacy filter set (enums + entity selects + booleans). */ declare const updateShipmentsFilterConfig: ModuleFilterConfigModel; /** * Users (customer list) — performed_action chips + user type select. */ declare const usersFilterConfig: ModuleFilterConfigModel; /** * Named-transport example — newer endpoints with direct query keys. */ declare const shipmentTrackingItemFilterConfig: ModuleFilterConfigModel; /** Seed registry — look up config by module id. */ declare const FILTER_CONFIGS: { readonly 'track-shipments': ModuleFilterConfigModel; readonly 'update-shipments': ModuleFilterConfigModel; readonly users: ModuleFilterConfigModel; readonly 'shipment-tracking-item-list': ModuleFilterConfigModel; }; /** Module ids present in {@link FILTER_CONFIGS}. */ type FilterConfigId = keyof typeof FILTER_CONFIGS; /** Router / HTTP query bag accepted by {@link fromFilterParams}. */ type FilterQueryBag = Record; /** * Empty filter state — safe default before hydrate / after reset. * * Sort defaults to descending (`desc`) so list screens match the usual * “newest first” API contract without an explicit Apply. * * @returns A state with an empty `values` map and `order: 'desc'`. */ declare function emptyFilterState(): FilterStateModel; /** * Clone state so drawer edits do not mutate the host until Apply. * * @param state - Current filter state (or undefined). * @returns A shallow copy safe to mutate in the drawer. */ declare function cloneFilterState(state?: FilterStateModel | null): FilterStateModel; /** * Serialize {@link FilterStateModel} for URL query strings and list API calls. * * - `legacy-parallel`: emits `filterColumn` / `filterValue` as aligned CSV. * - `named`: each selected field key is its own query param. * * Empty strings and undefined field values are omitted. * * @param state - Current filter map state. * @param config - Module schema (controls transport + shared params). * @returns Flat query / API bag ready for HttpParams or the router. */ declare function toFilterParams(state: FilterStateModel, config: ModuleFilterConfigModel): FilterParamsModel; /** * Hydrate {@link FilterStateModel} from a flat query / API bag. * * For `legacy-parallel`, zips `filterColumn` + `filterValue` CSV pairs. * Unknown column keys are still restored into `values` so round-trips survive * config drift. * * @param params - Router query params or API query object (stringish values). * @param config - Module schema. * @returns Hydrated {@link FilterStateModel}. */ declare function fromFilterParams(params: FilterQueryBag, config: ModuleFilterConfigModel): FilterStateModel; /** * Query keys this config reads and writes (`search`, `page`, `size`, field * keys or `filterColumn` / `filterValue`, etc.). * * @param config - Module schema. * @returns Deduped list of query param names. */ declare function filterQueryKeys(config: ModuleFilterConfigModel): string[]; /** * True when the bag contains any list-filter / pagination key this config * understands. Used to decide whether to hydrate from the URL. * * @param params - Router query params or API query object. * @param config - Module schema. * @returns Whether at least one relevant non-empty param is present. */ declare function hasFilterParams(params: FilterQueryBag, config: ModuleFilterConfigModel): boolean; /** * Drop one field value (column deselected / section clear). * * @param state - Mutable or immutable state to copy. * @param key - {@link FilterFieldModel.key} to clear. * @returns Cloned state without that field value. */ declare function clearFilterField(state: FilterStateModel, key: string): FilterStateModel; /** * Reset to empty values while optionally keeping pagination. * * @param keepPagination - When true, preserve `page` / `size`. * @param state - Optional prior state for pagination retention. * @returns Empty filter state, optionally retaining pagination. */ declare function resetFilterState(keepPagination?: boolean, state?: FilterStateModel | null): FilterStateModel; /** * Product surface / shipment mode for STN vs SFN experiences. * * Persisted per browser tab (`sessionStorage`) and attached to outbound * requests (e.g. `x-shipment-mode` header and `mode` query where required). * * - `'stn'` — Ship To Nigeria / international inbound flows * - `'sfn'` — Ship From Nigeria / outbound flows */ type ShippingMode = 'stn' | 'sfn'; /** * Linear dimension unit used when displaying or validating package sizes. */ type ModeDimensionUnit = 'cm' | 'inches'; /** * Mass unit used when displaying or validating package weight. */ type ModeMassUnit = 'KG' | 'LBS'; /** * Supported currency codes for mode/region pricing display. */ type ModeCurrencyCode = 'NGN' | 'USD'; /** * App-type selector when resolving region config. */ type ModeAppType = ShippingMode; /** * Region-specific display units and currency for a shipping mode. * * Field names match the wire (snake_case). */ interface ModeRegionConfigModel { dimension_unit: ModeDimensionUnit; mass_unit: ModeMassUnit; currency: ModeCurrencyCode; currency_symbol: string; } /** * Region map for Ship-From-Nigeria (`sfn`) mode. */ interface ModeSfnConfigModel { default: ModeRegionConfigModel; ng: ModeRegionConfigModel; } /** * Region map for Ship-To-Nigeria (`stn`) mode. */ interface ModeStnConfigModel { default: ModeRegionConfigModel; us: ModeRegionConfigModel; cn: ModeRegionConfigModel; gb: ModeRegionConfigModel; } /** * Full public mode-config payload from `/public/mode/config`. */ interface ModeConfigDataModel { sfn: ModeSfnConfigModel; stn: ModeStnConfigModel; } /** * User notification records from authenticated inbox reads. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Parsed payload inside {@link NotificationModel.data}. * * The API stores this object as a JSON string on the wire; the SDK mapper * parses it once into this shape. */ interface NotificationPayloadModel { /** Related user id when present on the payload. */ user_id?: number | null; /** Primary inbox title. */ title: string; /** Supporting copy. */ body?: string | null; /** In-app or external navigation target when the user opens the item. */ link?: string | null; /** Optional image URL. */ image?: string | null; /** When true, {@link link} should open in a new browsing context. */ external_link?: boolean | null; } /** * Database notification row from `GET /user/notifications/read/{id?}`. */ interface NotificationModel { /** UUID primary key. */ id: string; /** Laravel notification class name. */ type: string; /** Polymorphic notifiable type (e.g. `App\\Models\\User`). */ notifiable_type: string; /** Polymorphic notifiable id. */ notifiable_id: number; /** Parsed notification payload. */ data: NotificationPayloadModel; /** ISO timestamp when read; `null` when unread. */ read_at: string | null; created_at: string | null; updated_at: string | null; } /** * Compact inbox item derived from {@link NotificationModel} for UI headers. * * Maps cleanly onto {@link AfricaniesNotification} in `@africanies/africanies-ui`. */ interface NotificationInboxItemModel { id: string; title: string; body?: string; timestamp?: string; read?: boolean; link?: string; external_link?: boolean; image?: string | null; } /** Mark one notification read — `PUT /user/notifications/update`. */ interface NotificationMarkReadSingleRequestModel { id: string; } /** Mark every notification read — `PUT /user/notifications/update` with `{}`. */ type NotificationMarkAllReadRequestModel = Record; /** * Payment-method shapes from utility read endpoints. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). Mapping in `@africanies/africanies-core` * preserves those keys. */ /** * Currency nested on {@link PaymentMethodModel} — currency fields plus the * join pivot (no nested `payment_methods`). */ interface PaymentMethodCurrencyModel extends Omit { /** Join keys for this payment method. */ pivot: CurrencyPaymentMethodPivotModel; } /** * Payment processor record from `GET /payment_method/read/{id|all}`. */ interface PaymentMethodModel { /** Numeric payment-method id. */ id: number; /** Display name (e.g. `"Squad"`, `"Stripe"`). */ name: string; /** Backend model class path (e.g. `"App\\Models\\Stripe"`). */ model: string; /** Whether the method is available. */ active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; /** Currencies this processor accepts. */ currencies: PaymentMethodCurrencyModel[]; } /** `"1"` / `"0"` flag as sent on payment-method update. */ type PaymentMethodFlag01 = '0' | '1'; /** * Request body for `PUT /payment_method/update` (App Settings → Payment Methods). * * The status switch is the only write UI. `name` and `model` are resent from * the current row (not edited in a form). The SDK serializes `active` to * `"1"` / `"0"`. */ interface PaymentMethodUpdateRequestModel { id: number; name: string; model: string; /** Boolean or wire `"1"` / `"0"`. */ active: boolean | PaymentMethodFlag01; } /** * Subscription plan shapes from public utility reads. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Line item under a {@link PlanModel} (dimensions, discounts, pricing tiers). */ interface PlanPackageModel { id: number; plan_id: number | null; company_service_id: number | null; name: string; metrics: string | null; volume: number | null; discount: string | null; model: string | null; monthly: string | null; quarterly: string | null; biannually: string | null; annually: string | null; active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; } /** * Plan catalog record from `GET /public/plan/read/{id|all}`. * * Used in App Settings for Plans and Plan Packages. Authenticated writes use * `api/plan/*`. Nested {@link PlanPackageModel} rows appear when the wire * includes `packages`. */ interface PlanModel { id: number; name: string; active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; packages: PlanPackageModel[]; } /** * Product shapes from utility read endpoints. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Product record from `GET /product/read/{id|all}`. * * Includes HS codes, document/ETW id lists, and human-readable document * labels. `zone_product_required_documents` stays an opaque JSON list until * a dedicated nested model is needed. */ interface ProductModel { id: number; account_id: number | null; product_category_id: number | null; hs_code: string; hs_code_10: string | null; hs_code_8: string | null; hs_code_6: string | null; name: string; value: number; usage: number; document_ids: number[] | null; etw_ids: number[] | null; active: boolean; is_external: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; /** Display labels for required documents (e.g. `"Fumigation Certificate"`). */ document_details: string[]; /** Display labels for ETW documents (e.g. `"FDA Certificate"`). */ etw_document_details: string[]; /** * Zone-scoped required document payloads when present (null-safe JSON tree). */ zone_product_required_documents: ApiJsonValue[]; } /** * Subscription / add-on service shapes from public utility reads. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Service catalog record from `GET /public/service/read/{id|all}`. * * Used in App Settings for Services, Plans, and Plan Packages boards. * Authenticated create/update/delete use `api/service/*`. */ interface ServiceModel { id: number; name: string; /** Optional marketing / admin description when the wire includes it. */ description: string | null; /** Backend Eloquent class (e.g. `"App\\Models\\SomeService"`). */ model: string; active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; } /** * Shipment method (carrier) shapes from utility read endpoints. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case), including nested `zone_values`. */ /** * Geographic zone nested under a method↔zone link. */ interface ShipmentZoneModel { id: number; name: string; type: string; active: boolean; } /** * Link row tying a shipment method to a {@link ShipmentZoneModel}. */ interface ShipmentMethodZoneLinkModel { id: number; zone_id: number; shipment_method_id: number; active: boolean; mode: ShippingMode; zone: ShipmentZoneModel | null; } /** * One Laravel-style page of zone links embedded on a method payload * (`zone_values` on the wire). */ interface ShipmentMethodZonePageModel { /** Rows on this page (wire key `data`). */ data: ShipmentMethodZoneLinkModel[]; current_page: number; per_page: number; total: number; last_page: number; } /** * Carrier / shipment method from `GET /shipment_method/read/{id|all}`. */ interface ShipmentMethodModel { id: number; name: string; slug: string; model: string; min_delivery_business_day: number; max_delivery_business_day: number; notes: string; blacklisted_words: string | null; position: number; min_weight: number; max_weight: number; max_length: number; max_width: number; max_height: number; markup: number; surcharge: number; insurance_benchmark: number; insurance: number; clearing_handling: number; destination: string; /** Whether the method is sea-only (wire `"yes"` / `"no"`). */ sea_only: boolean; currency: string; type: string; active: boolean; multiple_rates: boolean; first_shipment_discount: number; discount_type: string; discount_active: boolean; mode: ShippingMode; deleted_at: string | null; created_at: string | null; updated_at: string | null; markdown: number; zone_values: ShipmentMethodZonePageModel; } /** * Authenticated user shapes from `GET /user`. * * Field names match the wire (snake_case). Most properties are optional / * nullable so Customer and Admin payloads can share one type safely. * * The wire body is a bare user object (no `{ success, data }` envelope). * {@link ApiClient} still wraps it in {@link ApiResponseModel}; mapping in * `@africanies/africanies-core` preserves snake_case and fills nested models. */ /** Backend Eloquent class for the authenticated principal. */ type UserModelType = 'App\\Models\\Customer' | 'App\\Models\\Admin'; /** Account classification on the user / business account. */ type AccountType = 'business' | 'individual'; /** Preferred shipping flow. */ type ShippingType = 'instant' | 'consolidation'; /** Billing cadence on plans / subscriptions. */ type PlanType = 'monthly' | 'quarterly' | 'biannually' | 'annually'; /** * Subdivision entry under {@link UserCountryModel.states}. */ interface UserStateModel { name?: string | null; state_code?: string | null; } /** * Country nested on the user profile (lighter than the public country utility). */ interface UserCountryModel { id?: number | null; name?: string | null; iso3?: string | null; iso2?: string | null; states?: UserStateModel[] | null; } /** * Line item under a subscription {@link UserPlanModel} (dimensions, discounts, * perks — values are often stringified numbers or descriptive text). */ interface UserPlanPackageModel { id?: number | null; plan_id?: number | null; company_service_id?: number | null; name?: string | null; metrics?: string | null; volume?: number | null; discount?: string | null; model?: string | null; monthly?: string | null; quarterly?: string | null; biannually?: string | null; annually?: string | null; active?: boolean | null; deleted_at?: string | null; created_at?: string | null; updated_at?: string | null; } /** * Subscription plan attached to a business account. */ interface UserPlanModel { id?: number | null; name?: string | null; active?: boolean | null; deleted_at?: string | null; created_at?: string | null; updated_at?: string | null; packages?: UserPlanPackageModel[] | null; } /** * Payment gateway redirect payload (often nested under payment_payload JSON). */ interface UserGatewayPayloadModel { authorization_url?: string | null; access_code?: string | null; reference?: string | null; redirect_url?: string | null; } /** * Parsed payment redirect / checkout payload. */ interface UserPaymentPayloadModel { url?: string | null; redirect_url?: string | null; gateway_payload?: UserGatewayPayloadModel | null; reference?: string | null; } /** * Subscription row on a business account. * * `payment_payload` is a raw JSON string on the wire — parse with * `JSON.parse` into {@link UserPaymentPayloadModel} when needed. */ interface UserSubscriptionModel { id?: number | null; user_id?: number | null; plan_id?: number | null; account_id?: number | null; reference?: string | null; process_url?: string | null; reference_salt?: string | null; amount?: string | null; /** e.g. `"NGN"`. */ currency?: string | null; payment_amount?: string | null; payment_currency?: string | null; coupon_id?: number | null; coupon_discount?: string | null; coupon_amount?: string | null; /** Raw JSON string — parse to {@link UserPaymentPayloadModel}. */ payment_payload?: string | null; plan_type?: PlanType | null; used?: boolean | null; deleted_at?: string | null; created_at?: string | null; updated_at?: string | null; } /** * Business account nested under the user when present. */ interface UserBusinessAccountModel { id?: number | null; user_id?: number | null; plan_id?: number | null; name?: string | null; account_email?: string | null; plan_type?: PlanType | null; first_payment?: boolean | null; is_whitelisted?: boolean | null; no_state_validation?: boolean | null; show_waybill?: boolean | null; notify_api_shipment?: boolean | null; active?: boolean | null; expires_at?: string | null; deleted_at?: string | null; created_at?: string | null; updated_at?: string | null; type?: AccountType | null; days_left?: number | null; plan?: UserPlanModel | null; subscription?: UserSubscriptionModel | null; } /** * Assigned account manager when present. */ interface UserAccountManagerModel { id?: number | null; user_id?: number | null; manager_id?: number | null; account_id?: number | null; name?: string | null; email?: string | null; phone?: string | null; created_at?: string | null; updated_at?: string | null; deleted_at?: string | null; } /** Nested warehouse under a default-warehouse mode slot. */ interface UserDefaultWarehouseRefModel { id?: number | null; name?: string | null; } /** * Per-mode default warehouse from `user.default_warehouses.sfn|stn`. * `country` is typically an ISO2 code (e.g. `"CN"`). */ interface UserDefaultWarehouseSlotModel { country?: string | null; warehouse?: UserDefaultWarehouseRefModel | null; } /** Default warehouses keyed by shipping mode (`sfn` / `stn`). */ interface UserDefaultWarehousesModel { sfn?: UserDefaultWarehouseSlotModel | null; stn?: UserDefaultWarehouseSlotModel | null; } /** * Current user from `GET /user` (auth required). * * Covers Customer and Admin wire variants; omit or null fields as the API * omits them. */ interface UserModel { id?: number | null; central_id?: string | null; name?: string | null; first_name?: string | null; middle_name?: string | null; last_name?: string | null; email?: string | null; phone?: string | null; unit_number?: string | null; referral_code?: string | null; old_unit_number?: string | null; account_email?: string | null; two_factor?: boolean | null; default_pin?: boolean | null; model?: UserModelType | null; country?: UserCountryModel | null; /** Selected state label when the API returns a string. */ state?: string | null; email_verified_at?: string | null; phone_verified_at?: string | null; kyc_verified_at?: string | null; passport_verified_at?: string | null; suspended_at?: string | null; deactivated_at?: string | null; active?: boolean | null; /** * When true after login, send the user to `/onboarding/reset-password` * (change current → new via `POST /user/change/password`). Not the * email-link forgot-password flow. */ default_password?: boolean | null; type?: AccountType | null; deleted_at?: string | null; created_at?: string | null; updated_at?: string | null; last_login_at?: string | null; socialite_signup?: 0 | 1 | null; form_signup?: 0 | 1 | null; /** e.g. `"ng"`. */ main_region?: string | null; shipping_type?: ShippingType | null; /** Shape TBD when the API populates this list. */ accounts?: unknown[] | null; business_account?: UserBusinessAccountModel | null; account_manager?: UserAccountManagerModel | null; /** Per-mode default warehouse assignment when the API sends it. */ default_warehouses?: UserDefaultWarehousesModel | null; } /** * Request body for `POST /user/change/password`. * * First login with a default password (`user.default_password`) — not the * email-link forgot-password flow. Host apps typically land on * `/onboarding/reset-password`, then the dashboard. */ interface ChangePasswordRequestModel { /** Password the user signed in with (the default / current password). */ current_password: string; /** Replacement password. */ password: string; /** Must match {@link ChangePasswordRequestModel.password}. */ password_confirmation: string; } /** * Warehouse shapes from utility read endpoints. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Subdivision attached to a warehouse (includes country name/code). */ interface WarehouseStateModel { /** State id from the API. */ id: number; /** Display name (e.g. `"Guangdong"`). */ name: string; /** Subdivision code. */ state_code: string; /** Country display name on the wire (e.g. `"China"`). */ country: string; /** ISO 3166-1 alpha-2. */ country_code: string; } /** * Warehouse record from `GET /warehouse/read/{id|all}`. */ interface WarehouseModel { id: number; partner_id: number | null; name: string; phone: string; email: string; country: CountryModel | null; /** Whether API integrations are enabled (wire `"0"` / `"1"`). */ api_enabled: boolean; state: WarehouseStateModel | null; city: string; address: string; longitude: number; latitude: number; zip_code: string; usage: number; active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; storage_charge: number; storage_period: number; delivery_charge: number; delivery_count: number; currency: string; etw_shipment_available: boolean; local: boolean; no_shippo: boolean; /** * Nested partner payload when present (null-safe JSON tree). */ partner: ApiJsonValue | null; } /** * Zone shapes from utility read endpoints. * * Domain interfaces in `@africanies/africanies-models` use a `*Model` suffix. * Field names match the wire (snake_case). */ /** * Zone record from `GET /zone/read/records/{id|all}`. */ interface ZoneModel { id: number; name: string; /** Zone type from the API (e.g. `"standard"`, `"default"`). */ type: string; active: boolean; deleted_at: string | null; created_at: string | null; updated_at: string | null; } export { BOX_DELIVERY_VENDORS, DEFAULT_FILTER_TRANSPORT, DEFAULT_PAGE_SIZE, DELIVERY_VENDORS, DELIVERY_VENDOR_OPTIONS, EXPORT_DELIVERY_VENDORS, FILTER_CONFIGS, FilterTransport, NOTIFICATION_PAGE_SIZE, PAGINATION_PAGE_SIZES, clearFilterField, cloneFilterState, deliveryVendorLabel, emptyFilterState, filterQueryKeys, fromFilterParams, hasFilterParams, isKnownDeliveryVendor, normalizeDeliveryVendor, normalizeDeliveryVendorForForm, resetFilterState, resolveFilterTransport, shipmentTrackingItemFilterConfig, toFilterParams, trackShipmentsFilterConfig, updateShipmentsFilterConfig, usersFilterConfig }; export type { AccountType, ApiErrorDetailModel, ApiJsonObjectModel, ApiJsonPrimitive, ApiJsonValue, ApiResponseModel, AsyncQueryStateModel, BoxDeliveryVendorId, ChangePasswordRequestModel, CountryModel, CountryStateModel, CurrencyCreateRequestModel, CurrencyDeleteRequestModel, CurrencyFlag01, CurrencyModel, CurrencyPaymentMethodModel, CurrencyPaymentMethodPivotModel, CurrencyUpdateRequestModel, DeliveryVendorId, DocumentModel, ExportDeliveryVendorId, FileGenerateExtension, FileGenerateMimeType, FileGenerateRequestModel, FileReadModel, FileReadRequestModel, FilterConfigId, FilterFieldModel, FilterFieldType, FilterOptionModel, FilterOptionsSource, FilterParamsModel, FilterQueryBag, FilterStateModel, ForgotPasswordRequestModel, ModeAppType, ModeConfigDataModel, ModeCurrencyCode, ModeDimensionUnit, ModeMassUnit, ModeRegionConfigModel, ModeSfnConfigModel, ModeStnConfigModel, ModuleFilterConfigModel, NotificationInboxItemModel, NotificationMarkAllReadRequestModel, NotificationMarkReadSingleRequestModel, NotificationModel, NotificationPayloadModel, PaginationMetaModel, PaginationPageSize, PaginationQueryParamsModel, PaymentMethodCurrencyModel, PaymentMethodFlag01, PaymentMethodModel, PaymentMethodUpdateRequestModel, PlanModel, PlanPackageModel, PlanType, ProductModel, ResourceId, ServiceModel, ShipmentMethodModel, ShipmentMethodZoneLinkModel, ShipmentMethodZonePageModel, ShipmentZoneModel, ShippingMode, ShippingType, SignedUploadInstructionModel, UserAccountManagerModel, UserBusinessAccountModel, UserCountryModel, UserDefaultWarehouseRefModel, UserDefaultWarehouseSlotModel, UserDefaultWarehousesModel, UserGatewayPayloadModel, UserModel, UserModelType, UserPaymentPayloadModel, UserPlanModel, UserPlanPackageModel, UserStateModel, UserSubscriptionModel, WarehouseModel, WarehouseStateModel, ZoneModel };