@igorchugurov/public-api-sdk
v1.4.0
Published
Public API SDK for Axon Dashboard - reusable SDK for working with universal entities
Downloads
489
Maintainers
Readme
@igorchugurov/public-api-sdk
Переиспользуемый SDK для работы с универсальными сущностями (Entity Instances) в Axon Dashboard и других клиентских приложениях.
📦 Установка
# В монорепо (локально)
pnpm add @igorchugurov/public-api-sdk@workspace:*
# Или после публикации в npm
pnpm add @igorchugurov/public-api-sdk✨ Возможности
SDK предоставляет полный набор инструментов для работы с универсальными сущностями:
🔄 CRUD операции
- Получение списка с расширенной фильтрацией, поиском и пагинацией
- Получение одного экземпляра с автоматической загрузкой связей и файлов
- Создание экземпляров с поддержкой relations и автоматической установкой
created_by - Обновление экземпляров с поддержкой частичных обновлений и relations
- Удаление экземпляров с автоматической очисткой связей
🔗 Работа со связями (Relations)
- Автоматическое определение relation-полей из конфигурации
- Поддержка всех типов связей:
manyToMany,manyToOne,oneToMany,oneToOne - Batch-загрузка связанных объектов для оптимизации производительности
- Фильтрация по relations с режимами
any(OR) иall(AND) - Опция получения relations как ID или полных объектов
🔍 Поиск и фильтрация
- Умный поиск по полям с флагом
searchable: true - JSONB фильтрация для обычных полей
- Relation фильтрация с автоматическим определением relation-полей
- Гибкая сортировка по любому полю с поддержкой
asc/desc
📁 Работа с файлами
- Автоматическая загрузка файлов и изображений для полей типа
filesиimages - Batch-загрузка файлов для оптимизации запросов
- Поддержка множественных файлов на поле
⚡ Производительность
- Кэширование конфигурации EntityDefinition и Fields (TTL: 5 минут по умолчанию)
- Batch-запросы для relations и файлов
- Оптимизированные RPC функции для поиска и загрузки связей
- Поддержка ESM и CJS форматов
🎯 Типобезопасность
- Полная типизация всех методов и параметров
- Экспорт всех типов для использования в вашем коде
- Типизированные ошибки для удобной обработки
🔐 Безопасность
- Интеграция с Supabase RLS (Row Level Security)
- Автоматическая проверка прав доступа
- Типизированные ошибки для различных сценариев доступа
🎨 UI конфигурация
- Автоматическая генерация UI конфигурации из EntityDefinition и Fields
- Поддержка кастомных UI настроек
- Генерация конфигурации колонок таблицы из полей
🚀 Быстрый старт
1. Server Component (SSR)
import { createServerSDK } from "@igorchugurov/public-api-sdk/server";
import { cookies } from "next/headers";
export default async function MyPage({ params }) {
const { projectId } = await params;
const cookieStore = await cookies();
const sdk = await createServerSDK(
projectId,
{
supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL!,
supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
cookies: {
getAll: () => cookieStore.getAll(),
setAll: (cookiesToSet) => {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
);
},
},
},
{
enableCache: true, // Кэшировать конфигурацию
}
);
// Получаем список экземпляров
const { data, pagination } = await sdk.getInstances(entityDefinitionId, {
page: 1,
limit: 20,
search: "test",
});
return <div>{/* ... */}</div>;
}2. Client Component
"use client";
import { createClientSDK } from "@igorchugurov/public-api-sdk";
const sdk = createClientSDK(
projectId,
{
supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL!,
supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
},
{
enableCache: true,
}
);
// Используем SDK
const { data, pagination } = await sdk.getInstances(entityDefinitionId, {
page: 1,
limit: 20,
});📚 API Reference
CRUD операции
getInstances(entityDefinitionId, params?)
Получить список экземпляров с фильтрацией, поиском и пагинацией.
const { data, pagination } = await sdk.getInstances(entityDefinitionId, {
page?: number; // default: 1
limit?: number; // default: 20
search?: string;
filters?: Record<string, string[]>;
relationFilterModes?: Record<string, 'any' | 'all'>;
sortBy?: string; // default: 'created_at'
sortOrder?: 'asc' | 'desc'; // default: 'desc'
relationsAsIds?: boolean; // default: false
});getInstance(entityDefinitionId, id, params?)
Получить один экземпляр по ID.
const instance = await sdk.getInstance(entityDefinitionId, id, {
relationsAsIds?: boolean; // default: false
loadFiles?: boolean; // default: false
});Пример:
// Базовое использование - без файлов
const instance = await sdk.getInstance("entity-def-id", "instance-id");
// Для редактирования - нужны только ID связей
const instance = await sdk.getInstance("entity-def-id", "instance-id", {
relationsAsIds: true,
});
// Для отображения с файлами - полные объекты
const instance = await sdk.getInstance("entity-def-id", "instance-id", {
relationsAsIds: false,
loadFiles: true, // файлы и изображения будут загружены как полные объекты EntityFile
});getInstanceBySlug(entityDefinitionId, slug, params?)
Получить один экземпляр по slug.
const instance = await sdk.getInstanceBySlug(entityDefinitionId, slug, {
relationsAsIds?: boolean; // default: false
loadFiles?: boolean; // default: false
});Пример:
// Базовое использование - без файлов
const instance = await sdk.getInstanceBySlug(
"entity-def-id",
"my-article-slug"
);
// Для отображения с файлами - полные объекты
const instance = await sdk.getInstanceBySlug(
"entity-def-id",
"my-article-slug",
{
relationsAsIds: false,
loadFiles: true, // файлы и изображения будут загружены как полные объекты EntityFile
}
);Особенности:
- Валидирует формат slug перед запросом (только строчные латинские буквы, цифры и дефисы)
- Работает аналогично
getInstance, но ищет по slug вместо id - Поддерживает те же параметры, что и
getInstance - Параметр
relationsAsIds:false(по умолчанию) - возвращает полные объекты связанных сущностейtrue- возвращает только массивы ID связанных сущностей
- Параметр
loadFiles:false(по умолчанию) - файлы и изображения не загружаютсяtrue- файлы и изображения загружаются как полные объектыEntityFile(сfileUrl,fileName,fileSizeи т.д.)
createInstance(entityDefinitionId, data)
Создать новый экземпляр. Автоматически генерирует уникальный slug из поля name.
const instance = await sdk.createInstance(entityDefinitionId, {
data: Record<string, unknown>; // Обязательно должно содержать поле 'name' (string)
relations?: Record<string, string[]>;
});Особенности:
- Автоматически генерирует уникальный
slugиз поляname - Если slug уже существует, добавляет случайный суффикс
- Автоматически устанавливает
created_byиз текущего пользователя - Поддерживает создание relations в одном запросе
updateInstance(entityDefinitionId, id, data)
Обновить экземпляр.
const instance = await sdk.updateInstance(entityDefinitionId, id, {
data: Record<string, unknown>;
relations?: Record<string, string[]>;
});deleteInstance(entityDefinitionId, id)
Удалить экземпляр.
await sdk.deleteInstance(entityDefinitionId, id);Конфигурация
getEntityDefinitionConfig(entityDefinitionId)
Получить конфигурацию EntityDefinition с полями.
const config = await sdk.getEntityDefinitionConfig(entityDefinitionId);getEntityDefinitionWithUIConfig(entityDefinitionId)
Получить EntityDefinition с полями и сгенерированной UI конфигурацией.
const config = await sdk.getEntityDefinitionWithUIConfig(entityDefinitionId);
// config: { entityDefinition, fields, uiConfig }getAllEntityDefinitions()
Получить все EntityDefinitions проекта с полями одним запросом (JOIN). Используется для загрузки всех сущностей в layout.
const entityDefinitions = await sdk.getAllEntityDefinitions();
// Возвращает массив EntityDefinitionConfig с полями
// Каждый элемент содержит: { id, name, slug, fields, ... }🔧 Типы
import type {
EntityDefinition,
Field,
EntityInstanceWithFields,
QueryParams,
CreateInstanceData,
UpdateInstanceData,
PaginationResult,
} from "@igorchugurov/public-api-sdk";Slug поддержка
Все экземпляры и определения сущностей теперь содержат поле slug:
// EntityInstance содержит slug
const instance: EntityInstanceWithFields = {
id: string;
slug: string; // URL-friendly идентификатор
entityDefinitionId: string;
// ...
};
// EntityDefinition также содержит slug
const entityDef: EntityDefinition = {
id: string;
name: string;
slug: string; // URL-friendly идентификатор
// ...
};Slug автоматически генерируется при создании экземпляра из поля name и гарантирует уникальность в рамках одной EntityDefinition.
🛠️ Обработка ошибок
SDK использует типизированные ошибки:
import {
NotFoundError,
PermissionDeniedError,
ValidationError,
AuthenticationError,
SDKError,
} from "@igorchugurov/public-api-sdk";
try {
const instance = await sdk.getInstance(entityDefinitionId, id);
} catch (error) {
if (error instanceof NotFoundError) {
// 404 - экземпляр не найден
} else if (error instanceof PermissionDeniedError) {
// 403 - нет прав доступа
} else if (error instanceof ValidationError) {
// 400 - ошибка валидации
} else if (error instanceof AuthenticationError) {
// 401 - ошибка авторизации
}
}⚙️ Кэширование
SDK поддерживает кэширование конфигурации для оптимизации:
const sdk = await createServerSDK(projectId, config, {
enableCache: true, // default: true
cacheTTL: 5 * 60 * 1000, // default: 5 минут
});🚧 Разработка
# Установка зависимостей
pnpm install
# Сборка
pnpm build
# Проверка типов
pnpm type-check
# Режим разработки (watch mode)
pnpm dev📄 Лицензия
MIT
