CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-strapi--helper-plugin

Helper library for Strapi plugins development providing React components, hooks, utilities, and TypeScript types for building plugin interfaces

Pending
Overview
Eval results
Files

types.mddocs/

Types

The @strapi/helper-plugin package provides comprehensive TypeScript interfaces and types for Strapi-specific data structures, API responses, component props, and system functionality. These types ensure type safety and developer experience across plugin development.

Core Message & Translation Types

Types for internationalization and message handling throughout the Strapi admin interface.

// Translation message interface extending react-intl
interface TranslationMessage extends MessageDescriptor {
  values?: Record<string, PrimitiveType>;
}

// Base message descriptor from react-intl
interface MessageDescriptor {
  id: string;
  defaultMessage?: string;
  description?: string;
}

// Primitive types for translation values
type PrimitiveType = string | number | boolean | null | undefined | Date;

Usage Examples:

// Define translatable messages
const messages: TranslationMessage = {
  id: 'plugin.my-plugin.button.save',
  defaultMessage: 'Save Changes',
  values: {
    count: 5,
    name: 'Article'
  }
};

// Use with react-intl
const { formatMessage } = useIntl();
const text = formatMessage(messages);

API Error Types

Union types for various API error responses that can occur in Strapi applications.

// Union type covering all possible API errors
type ApiError =
  | errors.ApplicationError
  | errors.ForbiddenError
  | errors.NotFoundError
  | errors.NotImplementedError
  | errors.PaginationError
  | errors.PayloadTooLargeError
  | errors.PolicyError
  | errors.RateLimitError
  | errors.UnauthorizedError
  | errors.ValidationError
  | errors.YupValidationError;

// Individual error type examples
interface ApplicationError {
  name: 'ApplicationError';
  message: string;
  details?: Record<string, any>;
}

interface ValidationError {
  name: 'ValidationError';
  message: string;
  details: {
    errors: Array<{
      path: string[];
      message: string;
      name: string;
    }>;
  };
}

interface ForbiddenError {
  name: 'ForbiddenError';
  message: string;
  details?: Record<string, any>;
}

Usage Examples:

// Handle different error types
const handleApiError = (error: ApiError) => {
  switch (error.name) {
    case 'ValidationError':
      // Handle validation errors
      error.details.errors.forEach(validationError => {
        console.error(`Field ${validationError.path.join('.')}: ${validationError.message}`);
      });
      break;
    case 'ForbiddenError':
      // Handle permission errors
      console.error('Access denied:', error.message);
      break;
    case 'ApplicationError':
      // Handle general application errors
      console.error('Application error:', error.message);
      break;
    default:
      console.error('Unknown error:', error.message);
  }
};

Filter & Query Types

Types for data filtering, querying, and search operations.

// Attribute-based filters
type AttributeFilter = Record<
  string,
  Record<EntityService.Params.Filters.Operator.Where, string | null>
>;

// Relation-based filters
type RelationFilter = Record<string, AttributeFilter>;

// Generic filter type
type Filter = AttributeFilter | RelationFilter;

// Filter operator interface
interface Operator {
  value: EntityService.Params.Filters.Operator.Where;
  intlLabel: MessageDescriptor;
}

// Comprehensive filter data configuration
interface FilterData {
  name: string;
  metadatas: {
    label: string;
    customOperators?: Array<{
      intlLabel: { id: string; defaultMessage: string };
      value: string;
    }>;
    customInput?: React.ComponentType;
    options?: Array<{ label?: string; customValue: string }>;
    uid?: string;
  };
  fieldSchema: {
    type: Attribute.Any['type'];
    options?: string[];
    mainField?: {
      name: string;
      type?: Attribute.Any['type'];
    };
  };
  trackedEvent?: TrackingEvent;
}

// Default filter input props
interface DefaultFilterInputsProps {
  label?: string;
  onChange: (value: string | null) => void;
  options?: FilterData['fieldSchema']['options'] | FilterData['metadatas']['options'];
  type: FilterData['fieldSchema']['type'];
  value?: string | null;
}

Usage Examples:

// Define filter configuration
const articleFilters: FilterData[] = [
  {
    name: 'title',
    metadatas: {
      label: 'Title',
      customOperators: [
        {
          intlLabel: { id: 'filter.contains', defaultMessage: 'Contains' },
          value: '$containsi'
        }
      ]
    },
    fieldSchema: {
      type: 'string'
    }
  },
  {
    name: 'category',
    metadatas: {
      label: 'Category',
      uid: 'api::category.category'
    },
    fieldSchema: {
      type: 'relation',
      mainField: { name: 'name', type: 'string' }
    }
  }
];

// Create filter objects
const titleFilter: AttributeFilter = {
  title: {
    $containsi: 'react'
  }
};

const categoryFilter: RelationFilter = {
  category: {
    name: {
      $eq: 'Technology'
    }
  }
};

Content Manager Types

Types specific to content management functionality (also covered in Content Manager documentation).

// Base entity interface
interface Entity {
  id: StrapiEntity.ID;
  createdAt: string | null;
  createdBy: User | null;
  updatedAt: string | null;
  updatedBy: User | null;
}

// Content type with optional entity fields and dynamic attributes
interface ContentType extends Partial<Entity> {
  publishedAt?: string | null;
  publishedBy?: User | null;
  [key: string]: Attribute.GetValue<Attribute.Any> | null;
}

// User interface for content relations
interface User extends NonNullableObject<Entity> {
  firstname?: string;
  lastname?: string;
  username?: string;
  email?: string;
  isActive: boolean;
  blocked: boolean;
  roles: [];
}

// Helper type for non-nullable object properties
type NonNullableObject<T> = {
  [key in keyof T]: NonNullable<T[key]>;
};

Usage Examples:

// Work with content types
const article: ContentType = {
  id: 1,
  title: 'My Article',
  content: 'Article content...',
  publishedAt: '2023-01-01T00:00:00.000Z',
  createdAt: '2023-01-01T00:00:00.000Z',
  updatedAt: '2023-01-01T00:00:00.000Z'
};

// Type-safe property access
const title: string = article.title as string;
const isPublished: boolean = !!article.publishedAt;

Component Prop Types

Common prop interfaces used across UI components.

// Permission-based component props
interface CheckPermissionsProps {
  children: React.ReactNode;
  permissions?: Array<{ action: string; subject: string }>;
}

// Form component props
interface FormProps extends Omit<FormikFormProps, 'noValidate'> {
  children: React.ReactNode;
}

// Generic input props
interface GenericInputProps {
  type: string;
  name: string;
  value?: any;
  onChange?: (event: { target: { name: string; value: any; type: string } }) => void;
  error?: string | TranslationMessage;
  description?: string | TranslationMessage;
  disabled?: boolean;
  intlLabel?: TranslationMessage;
  placeholder?: string | TranslationMessage;
  required?: boolean;
  step?: number;
  max?: number;
  min?: number;
  attribute?: any;
}

// Table component props
interface TableProps<TRows extends { id: Entity.ID } = { id: Entity.ID }> {
  children?: React.ReactNode;
  contentType: string;
  headers?: Array<TableHeader>;
  rows?: Array<TRows>;
  isLoading?: boolean;
  withBulkActions?: boolean;
  withMainAction?: boolean;
  onConfirmDeleteAll?: (ids: Array<TRows['id']>) => Promise<void>;
  onConfirmDelete?: (id: TRows['id']) => Promise<void>;
  footer?: React.ReactNode;
  action?: React.ReactNode;
}

// Table header definition
interface TableHeader {
  name: string;
  metadatas: {
    sortable: boolean;
    label: string;
    mainField?: { name: string };
  };
  fieldSchema?: { type: string };
}

Usage Examples:

// Type-safe component props
const MyFormComponent: React.FC<FormProps> = ({ children, ...props }) => {
  return <Form {...props}>{children}</Form>;
};

// Table with typed rows
interface Article {
  id: number;
  title: string;
  status: 'draft' | 'published';
}

const ArticleTable: React.FC = () => {
  const tableProps: TableProps<Article> = {
    contentType: 'articles',
    headers: [
      { name: 'title', metadatas: { label: 'Title', sortable: true } },
      { name: 'status', metadatas: { label: 'Status', sortable: false } }
    ],
    rows: articles,
    withBulkActions: true,
    onConfirmDelete: handleDelete
  };

  return <DynamicTable {...tableProps} />;
};

Hook Return Types

Types for values returned by custom hooks.

// Fetch client hook return
interface FetchClientReturn {
  get: <TData = any>(url: string, config?: any) => Promise<TData>;
  post: <TData = any, TResponse = any>(url: string, data?: any, config?: any) => Promise<TResponse>;
  put: <TData = any>(url: string, data?: any, config?: any) => Promise<TData>;
  del: <TData = any>(url: string, config?: any) => Promise<TData>;
}

// RBAC hook return
interface AllowedActions {
  [key: string]: boolean;
}

interface RBACReturn {
  allowedActions: AllowedActions;
  isLoading: boolean;
  setIsLoading: () => void;
}

// Selection state hook return
interface SelectionActions<TValues> {
  selectOne: (selection: TValues) => void;
  selectAll: (nextSelections: TValues[]) => void;
  selectOnly: (nextSelection: TValues) => void;
  selectMultiple: (nextSelections: TValues[]) => void;
  deselectMultiple: (nextSelections: TValues[]) => void;
  setSelections: (selections: TValues[]) => void;
}

type UseSelectionStateReturn<TValues> = readonly [TValues[], SelectionActions<TValues>];

// Clipboard hook return
interface ClipboardReturn {
  copy: (value: string | number) => Promise<boolean>;
}

// Query params hook return
interface QueryResult<TQuery> {
  query: TQuery;
  rawQuery: string;
}

type UseQueryParamsReturn<TQuery> = readonly [
  QueryResult<TQuery>,
  (nextParams: TQuery, method?: 'push' | 'remove') => void
];

Usage Examples:

// Use typed hook returns
const { allowedActions, isLoading }: RBACReturn = useRBAC({
  create: [{ action: 'create', subject: 'api::article.article' }]
});

// Selection state with typed values
interface SelectableItem {
  id: number;
  name: string;
}

const [selections, actions]: UseSelectionStateReturn<SelectableItem> = useSelectionState(
  ['id'],
  []
);

// Type-safe query parameters
interface QueryParams {
  search?: string;
  page?: number;
  sort?: string;
}

const [{ query }, setQuery]: UseQueryParamsReturn<QueryParams> = useQueryParams({
  page: 1,
  sort: 'name:asc'
});

Context Value Types

Types for React context values used throughout the plugin system.

// App information context
interface AppInfoContextValue {
  autoReload?: boolean;
  communityEdition?: boolean;
  currentEnvironment?: string;
  dependencies?: Record<string, string>;
  latestStrapiReleaseTag?: string;
  nodeVersion?: string;
  projectId?: string | null;
  setUserDisplayName: (name: string) => void;
  shouldUpdateStrapi: boolean;
  strapiVersion?: string | null;
  useYarn?: boolean;
  userDisplayName: string;
  userId?: string;
}

// Notification context
interface NotificationConfig {
  blockTransition?: boolean;
  link?: NotificationLink;
  message?: string | TranslationMessage;
  onClose?: () => void;
  timeout?: number;
  title?: string | TranslationMessage;
  type?: 'info' | 'warning' | 'softWarning' | 'success';
}

interface NotificationsContextValue {
  toggleNotification: (config: NotificationConfig) => void;
}

// RBAC context
interface Permission {
  id?: Entity.ID;
  action: string;
  actionParameters?: object;
  subject?: string | null;
  properties?: {
    fields?: string[];
    locales?: string[];
    [key: string]: any;
  };
  conditions?: string[];
}

interface RBACContextValue {
  allPermissions: Permission[];
  refetchPermissions: () => void;
}

// Tracking context
interface TrackingContextValue {
  uuid?: string | boolean;
  deviceId?: string;
  telemetryProperties?: TelemetryProperties;
}

interface TelemetryProperties {
  useTypescriptOnServer?: boolean;
  useTypescriptOnAdmin?: boolean;
  isHostedOnStrapiCloud?: boolean;
  numberOfAllContentTypes?: number;
  numberOfComponents?: number;
  numberOfDynamicZones?: number;
}

Usage Examples:

// Create typed context providers
const MyCustomProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const appInfo: AppInfoContextValue = useAppInfo();
  const { toggleNotification }: NotificationsContextValue = useNotification();
  
  const handleAction = () => {
    if (appInfo.shouldUpdateStrapi) {
      toggleNotification({
        type: 'info',
        message: 'Update available!'
      });
    }
  };

  return (
    <div>
      {children}
      <button onClick={handleAction}>Check Updates</button>
    </div>
  );
};

Utility Function Types

Types for parameters and return values of utility functions.

// HTTP client configuration
interface FetchClientOptions extends AxiosRequestConfig {
  signal?: AbortSignal;
}

// Error normalization options
interface NormalizeErrorOptions {
  name?: string;
  intlMessagePrefixCallback?: (id: string) => string;
}

// Permission checking types
type PermissionToCheckAgainst = Pick<Permission, 'action' | 'subject'> &
  Partial<Pick<Permission, 'actionParameters' | 'conditions' | 'properties'>>;

// Storage types
interface StorageItems {
  userInfo: UserInfo;
  jwtToken: string;
  STRAPI_THEME: 'light' | 'dark';
  GUIDED_TOUR_CURRENT_STEP: string | null;
  GUIDED_TOUR_COMPLETED_STEPS: string[] | null;
  GUIDED_TOUR_SKIPPED: boolean | null;
  STRAPI_UPDATE_NOTIF: boolean | null;
  STRAPI_UPLOAD_MODAL_VIEW: 0 | 1 | null;
  STRAPI_UPLOAD_LIBRARY_VIEW: 0 | 1 | null;
  videos: unknown;
  onboarding: unknown;
}

type StorageItemValues = StorageItems[keyof StorageItems];

Event & Tracking Types

Comprehensive type system for analytics and event tracking.

// Base event without properties
interface EventWithoutProperties {
  name: 'didCreateEntry' | 'didDeleteEntry' | 'didEditEntry' | /* ... many more */;
  properties?: never;
}

// Events with specific properties
interface CreateEntryEvents {
  name: 'willCreateEntry' | 'didCreateEntry' | 'didNotCreateEntry';
  properties: {
    status?: string;
    error?: unknown;
  };
}

interface NavigationEvent {
  name: 'willNavigate';
  properties: {
    from: string;
    to: string;
  };
}

// Union of all tracking events
type TrackingEvent = EventWithoutProperties | CreateEntryEvents | NavigationEvent | /* ... others */;

// Tracking hook interface
interface UseTrackingReturn {
  trackUsage<TEvent extends TrackingEvent>(
    event: TEvent['name'],
    properties?: TEvent['properties']
  ): Promise<null | AxiosResponse<string>>;
}

Usage Examples:

// Type-safe event tracking
const { trackUsage }: UseTrackingReturn = useTracking();

// Events without properties
trackUsage('didCreateEntry');

// Events with properties
trackUsage('willNavigate', {
  from: '/admin/plugins',
  to: '/admin/content-manager'
});

trackUsage('didCreateEntry', {
  status: 'success'
});

Generic & Utility Types

Helper types for generic operations and type transformations.

// Make all properties of an object non-nullable
type NonNullableObject<T> = {
  [K in keyof T]: NonNullable<T[K]>;
};

// Empty object type
type EmptyObject = Record<string, never>;

// Callback ref type
type CallbackRef<T> = (instance: T | null) => void;

// Axios response wrapper
interface AxiosResponseWrapper<T> extends AxiosResponse<T> {
  data: T;
}

// Generic ID types
type EntityID = string | number;

// Generic entity with ID
interface WithId {
  id: EntityID;
}

// Partial with required ID
type PartialWithId<T> = Partial<T> & WithId;

Usage Examples:

// Use generic types for type safety
interface MyEntity {
  id: number;
  name: string;
  description?: string;
}

// Ensure all properties are non-null
type RequiredEntity = NonNullableObject<MyEntity>;

// Create partial updates with required ID
type EntityUpdate = PartialWithId<MyEntity>;

const updateEntity = (update: EntityUpdate) => {
  // update.id is guaranteed to exist
  // other properties are optional
  console.log(`Updating entity ${update.id}`);
};

Type Integration Best Practices

Component Type Safety

// Extend base props with additional types
interface MyComponentProps extends GenericInputProps {
  customOption?: boolean;
  onCustomEvent?: () => void;
}

const MyComponent: React.FC<MyComponentProps> = (props) => {
  return <GenericInput {...props} />;
};

API Response Typing

// Define API response shapes
interface ArticleListResponse {
  data: ContentType[];
  meta: {
    pagination: {
      page: number;
      pageSize: number;
      pageCount: number;
      total: number;
    };
  };
}

// Use with fetch client
const { get }: FetchClientReturn = useFetchClient();
const response = await get<ArticleListResponse>('/api/articles');

Error Handling with Types

// Create typed error handlers
const handleTypedError = (error: unknown) => {
  if (error && typeof error === 'object' && 'response' in error) {
    const axiosError = error as AxiosError<{ error: ApiError }>;
    const normalized = normalizeAPIError(axiosError);
    
    if (normalized) {
      console.error(normalized.defaultMessage);
    }
  }
};

The comprehensive type system in @strapi/helper-plugin ensures type safety across all plugin development scenarios, from UI components to API interactions to data management operations.

Install with Tessl CLI

npx tessl i tessl/npm-strapi--helper-plugin

docs

content-manager.md

features.md

hooks.md

index.md

types.md

ui-components.md

utilities.md

tile.json