/** * This Source Code is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright (c) Infonomic Company Limited */ /** * Framework-neutral function contracts that admin UI components in * `@byline/ui` need from the host application. The host wires concrete * implementations via `BylineAdminServicesProvider` — typically thin * adapters around TanStack Start server functions, Next.js server * actions, or any other RPC-style transport. * * The call shape `(args: { data: TInput }) => Promise` mirrors * TanStack Start's `createServerFn().handler()` calling convention so a * webapp host can pass its server fns through as-is. Other transports * just need a tiny adapter. * * Scope: Phase 2.1 covers the framework-neutral admin UI components * only — the 15 forms, modals, and inner widgets that don't touch * TanStack Router. Page containers (list/edit/delete pages) keep using * server fns directly today and move into `@byline/host-tanstack-start` * in Phase 3 along with the route factories. */ import type { AccountResponse, ChangeAccountPasswordRequest, UpdateAccountRequest } from '../modules/admin-account/index.js'; import type { SetRoleAbilitiesResponse, WhoHasAbilityResponse } from '../modules/admin-permissions/index.js'; import type { AdminRoleResponse, UserRolesResponse } from '../modules/admin-roles/index.js'; import type { AdminUserResponse } from '../modules/admin-users/index.js'; /** * The TanStack Start `createServerFn(...).handler(...)` calling shape: * `fn({ data: input }) → Promise`. Hosts using a different * transport supply small adapters that match this shape. */ export type AdminServiceCall = (args: { data: TInput; }) => Promise; export interface SignInInput { email: string; password: string; } /** * The admin UI's sign-in form does not consume the `SignInResult` * payload directly — on success it navigates via `window.location`. The * shape is left as `unknown` here so each host's session provider can * supply whatever envelope it produces without forcing a public type. */ export type SignInResult = unknown; /** Same shape as `UpdateAccountRequest` from `@byline/admin/admin-account`. */ export type UpdateAccountInput = UpdateAccountRequest; /** Same shape as `ChangeAccountPasswordRequest` from `@byline/admin/admin-account`. */ export type ChangeAccountPasswordInput = ChangeAccountPasswordRequest; export interface SetAdminLocaleInput { /** BCP 47 tag, or `null` to clear the preference and re-engage detection. */ locale: string | null; } /** * Return shape for the locale-switcher service. `account` is populated * when the request resolved an authenticated admin actor (the form on * the account page); `null` on pre-auth surfaces (the sign-in page * locale dropdown) where the cookie write is the only effect. */ export interface SetAdminLocaleResult { ok: true; locale: string | null; account: AccountResponse | null; } export interface CreateAdminUserInput { email: string; password: string; given_name?: string | null; family_name?: string | null; username?: string | null; is_super_admin: boolean; is_enabled: boolean; is_email_verified: boolean; } export interface UpdateAdminUserInput { id: string; vid: number; patch: { email?: string; given_name?: string | null; family_name?: string | null; username?: string | null; is_super_admin?: boolean; is_enabled?: boolean; is_email_verified?: boolean; }; } export interface SetAdminUserPasswordInput { id: string; vid: number; password: string; } export interface SetUserRolesInput { userId: string; roleIds: string[]; } export interface CreateAdminRoleInput { name: string; machine_name: string; description: string | null; } export interface UpdateAdminRoleInput { id: string; vid: number; patch: { name?: string; description?: string | null; }; } export interface SetRoleAbilitiesInput { id: string; abilities: string[]; } export interface WhoHasAbilityInput { ability: string; } export interface BylineAdminServices { adminSignIn: AdminServiceCall; updateAccount: AdminServiceCall; changeAccountPassword: AdminServiceCall; setAdminLocale: AdminServiceCall; createAdminUser: AdminServiceCall; updateAdminUser: AdminServiceCall; setAdminUserPassword: AdminServiceCall; setUserRoles: AdminServiceCall; createAdminRole: AdminServiceCall; updateAdminRole: AdminServiceCall; setRoleAbilities: AdminServiceCall; whoHasAbility: AdminServiceCall; /** * Diff helper. Loads a specific historical version of a document so * the diff modal can compare it against the current version. Returns * the same shape as the regular document loader — the diff modal * consumes only `doc.fields` (or strips known meta keys when an * older flat-shape doc is encountered). * * Positional-args shape rather than `{ data }` because this helper * predates the contract and is consumed only by `DiffModal`. Hosts * adapt their server fn into this call signature. */ getCollectionDocumentVersion: (collection: string, documentId: string, versionId: string, locale: string | undefined) => Promise>; }