npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@igorchugurov/public-api-sdk

v1.4.0

Published

Public API SDK for Axon Dashboard - reusable SDK for working with universal entities

Downloads

489

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 - файлы и изображения загружаются как полные объекты EntityFilefileUrl, 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