@zanreal/medusa-admin-kit

Dokumentacja API

Wszystkie eksporty @zanreal/medusa-admin-kit: rejestr kolumn, budowanie kontekstu, odczyt kwot, mapowanie zapytań i typy.

Wszystko poniżej jest eksportowane z korzenia pakietu, @zanreal/medusa-admin-kit. Pakiet ma jeszcze podścieżkę ./admin, czyli zbudowany bundle panelu, który wczytuje Medusa. Kod aplikacji nie importuje z niej nic wprost.

Rejestr kolumn

registerVariantColumn

function registerVariantColumn<TProduct extends CatalogProduct = CatalogProduct, TData = unknown>(
  def: VariantColumnDef<TProduct, TData>,
): void;

Dokłada kolumnę do tabeli Catalog. Wywołaj to na najwyższym poziomie modułu rozszerzenia panelu, co wyjaśnia Dokładanie kolumny. Ponowna rejestracja z tym samym id nadpisuje wcześniejszą definicję, dzięki czemu przeładowanie modułu w trakcie pracy niczego nie duplikuje.

Rzuca TypeError, gdy id nie jest niepustym napisem albo gdy cell nie jest funkcją.

getRegisteredVariantColumns

function getRegisteredVariantColumns(): VariantColumnDef[];

Wszystkie zarejestrowane kolumny, posortowane rosnąco po priority, remisy zachowują kolejność rejestracji. Zwracana tablica jest świeżą kopią, więc jej modyfikowanie nie rusza rejestru.

hasVariantColumn, getVariantColumn

function hasVariantColumn(id: string): boolean;
function getVariantColumn(id: string): VariantColumnDef | undefined;

unregisterVariantColumn, clearVariantColumns

function unregisterVariantColumn(id: string): boolean;
function clearVariantColumns(): void;

unregisterVariantColumn zwraca informację o tym, czy kolumna faktycznie została usunięta. clearVariantColumns służy do izolacji testów i resetów przy przeładowaniu modułów; kod produkcyjny nie powinien go potrzebować.

Aliasy oznaczone jako przestarzałe

registerProductColumn, getRegisteredProductColumns, hasProductColumn, getProductColumn, unregisterProductColumn i clearProductColumns są aliasami powyższych nazw z Variant. To te same funkcje piszące do tego samego magazynu, więc wtyczka zbudowana na starszym API działa bez zmian.

Kontekst komórki

buildVariantColumnContext

function buildVariantColumnContext<TProduct extends CatalogProduct>(
  row: CatalogVariantRow<TProduct>,
): VariantColumnCellContext<TProduct>;

Przekształca wiersz wariantu z GET /admin/product-variants w kontekst przekazywany każdej komórce. To jedyne miejsce, w którym dzieje się normalizacja, więc komórka może ufać ctx.variant, ctx.sku i ctx.product bez wyliczania ich u siebie. Funkcja jest czysta, nie potrzebuje środowiska panelu.

normalizeVariant

function normalizeVariant(variant?: Partial<CatalogVariant> | null): CatalogVariant;

Uzupełnia surowy wariant do { id, sku, title, thumbnail }. Brak id daje "", brak sku, title i thumbnail daje null.

extractSkus

function extractSkus(variants?: Partial<CatalogVariant>[] | null): string[];

Wszystkie niepuste SKU z listy wariantów, bez powtórzeń i w kolejności wystąpienia. Przydatne, gdy chcesz zebrać jedno zapytanie dla całej strony wyników.

Składanie listy kolumn

BASE_CATALOG_COLUMN_IDS

const BASE_CATALOG_COLUMN_IDS: readonly [
  "thumbnail", "product", "variant", "sku", "status", "price", "srp",
];

Kolumny wbudowane, w kolejności renderowania. BaseCatalogColumnId to unia tych literałów.

resolveCatalogColumns

function resolveCatalogColumns<TProduct extends CatalogProduct>(
  registered: VariantColumnDef<TProduct>[],
): ResolvedCatalogColumn<TProduct>[];

Scala kolumny wbudowane z zarejestrowanymi w finalną, uporządkowaną listę: najpierw wbudowane, potem zarejestrowane w kolejności, w jakiej zostały podane. Funkcja jest czysta, więc kontrakt kolejności da się sprawdzić testem bez panelu.

ResolvedCatalogColumn to unia rozłączna: albo { id: BaseCatalogColumnId; source: "base" }, albo { id: string; source: "registered"; def: VariantColumnDef<TProduct> }.

renderRegisteredCell

function renderRegisteredCell<TProduct extends CatalogProduct, TData = unknown>(
  def: VariantColumnDef<TProduct, TData>,
  row: CatalogVariantRow<TProduct>,
  async?: VariantColumnAsyncState<TData>,
): ReactNode;

Synchroniczna połowa tego, co trasa robi dla każdego wiersza: zbuduj kontekst, podaj go do cell z definicji kolumny. Podanie async wprost pozwala sprawdzić gałęzie ładowania, danych i błędu w zwykłym teście w Node.

Kwoty

readAmount

function readAmount(value?: unknown): number | null;

Odczytuje kwotę z dowolnej postaci, w jakiej trzyma ją źródło: liczby, napisu z liczbą, żywego BigNumber, gołego obiektu { value, precision } albo BigNumber spłaszczonego do zwykłego obiektu. Zwraca kwotę w jednostkach głównych albo null, gdy wartości nie ma lub nie da się jej odczytać. Nigdy 0 w zastępstwie któregokolwiek z tych przypadków.

selectVariantPrice

function selectVariantPrice(
  prices?: readonly CatalogPrice[] | null,
): VariantPriceSelection | null;

Wybiera tę jedną cenę, którą pokaże komórka. Pierwszeństwo mają ceny zwykłe, remis rozstrzyga najniższy kod waluty, a wariant mający wyłącznie ceny warunkowe lub progowe korzysta z nich, zamiast nie pokazać nic. Zwraca null tylko wtedy, gdy naprawdę nie ma czego odczytać.

VariantPriceSelection to { price: CatalogMoney; otherCount: number }, gdzie otherCount mówi, ile jeszcze odczytywalnych cen ma ten wariant.

readVariantSrp, readVariantSrpMoney

function readVariantSrp(row: SrpSource, key?: string): number | null;
function readVariantSrpMoney(row: SrpSource, key?: string): CatalogMoney | null;

Obie czytają metadata.srp z wariantu, a gdy go tam nie ma, sięgają do metadanych produktu. readVariantSrp zwraca gołą liczbę, czyli to, co porównują konsumenci tej wartości po stronie serwera. readVariantSrpMoney czyta dodatkowo walutę z klucza obok, w tym samym obiekcie metadanych, z którego przyszła kwota, i nigdy pomiędzy dwoma obiektami; przy braku klucza obok zwraca currency: null.

SrpSource to minimalny kształt, z którego czytają: { metadata?, product?: { metadata? } }.

SRP_METADATA_KEY, srpCurrencyKey

const SRP_METADATA_KEY = "srp";
function srpCurrencyKey(key?: string): string;

srpCurrencyKey("srp") daje "srp_currency". Wyprowadzanie tej nazwy z klucza kwoty sprawia, że sklep, który przemianował srp, dostaje pasujący klucz obok bez żadnej dodatkowej konfiguracji.

formatAmount

function formatAmount(amount: number): string;

toFixed(2), bez separatora tysięcy zależnego od locale, żeby przecinek dziesiętny stał w tym samym miejscu w każdej komórce i w każdej przeglądarce.

CatalogMoney, CatalogPrice

interface CatalogMoney {
  amount: number;
  currency: string | null;
}

interface CatalogPrice {
  amount?: unknown;
  currency_code?: string | null;
  min_quantity?: number | null;
  max_quantity?: number | null;
  rules?: Record<string, unknown> | null;
}

CatalogMoney.currency to kod ISO wielkimi literami albo null, gdy źródło trzyma gołą kwotę bez własnej waluty, czyli dokładnie tak, jak metadata.srp. CatalogPrice.amount jest celowo typu unknown, bo nie da się założyć, że przyjdzie liczba, nawet tam, gdzie opublikowany typ tak twierdzi. Typ HttpTypes.AdminPrice z Medusy jest strukturalnie zgodny z CatalogPrice.

Linki z wierszy

variantDetailHref

function variantDetailHref(row: CatalogVariantRow<CatalogProduct>): string | null;

/products/:product_id/variants/:variant_id, czyli wbudowana strona szczegółów wariantu. Ścieżka jest celowo względna wobec routera, bo router panelu jest zamontowany pod ścieżką bazową panelu. Zwraca null, gdy wiersz nie ma produktu nadrzędnego albo identyfikatora wariantu, więc wywołujący może zrezygnować z nawigacji, zamiast wypychać zepsuty adres.

unwrapClickedRow

function unwrapClickedRow<TRow>(clicked: TRow | { original: TRow }): TRow;

Rozpakowuje to, co DataTable z @medusajs/ui podaje do onRowClick. useDataTable typuje drugi argument jako TData, ale w wersji 4.2.0 tabela wywołuje go z opakowaniem Row<TData> z TanStacka. Czytanie row.original w ciemno psuje się, gdy typy zostaną kiedyś poprawione, a czytanie samego wiersza psuje się dzisiaj. Ta funkcja sprawdza obecność opakowania i przyjmuje obie postaci.

Mapowanie zapytań

VARIANT_LIST_FIELDS

Napis fields, o który prosi tabela; obejmuje wariant, jego metadane, jego zestaw cen oraz produkt nadrzędny.

buildVariantListQuery

function buildVariantListQuery(input: VariantListQueryInput): VariantListQuery;

Zamienia { pageIndex, pageSize, search } na { limit, offset, fields, q? }. offset wychodzi z pageIndex * pageSize, a fraza pusta lub złożona z samych spacji jest pomijana, a nie wysyłana jako puste q.

mapVariantListResponse

function mapVariantListResponse<TVariant>(
  response: VariantListResponse<TVariant> | null | undefined,
): { variants: TVariant[]; count: number };

Normalizuje odpowiedź i radzi sobie z brakiem listy albo licznika.

pageCount, DEFAULT_PAGE_SIZE, PAGE_SIZE_OPTIONS

function pageCount(count: number, pageSize: number): number;
const DEFAULT_PAGE_SIZE = 20;
const PAGE_SIZE_OPTIONS: readonly [10, 20, 50, 100];

pageCount nigdy nie zwraca mniej niż 1.

Typy

CatalogVariant, CatalogProduct i CatalogVariantRow opisują wiersz i są trzymane strukturalnie, bez wiązania z @medusajs/types, dzięki czemu rejestr wraz z funkcjami pomocniczymi da się zaimportować i przetestować bez środowiska panelu. Typy HttpTypes.AdminProduct i HttpTypes.AdminProductVariant z Medusy są z nimi strukturalnie zgodne.

VariantColumnDef, VariantColumnCellContext i VariantColumnAsyncState opisuje Dokładanie kolumny.

ProductColumnVariant, ProductColumnProduct, ProductColumnCellContext, ProductColumnAsyncState i ProductColumnDef to przestarzałe aliasy powyższych, zachowane po to, żeby niezmigrowana wtyczka nadal się kompilowała.

Spis treści