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

@jmen/strapi-types-generate

v0.0.7

Published

Generate typescript interfaces using Strapi Schemas

Readme

Strapi types generate

This library provides a CLI for Strapi V5 that generates typescript interfaces based on your components, collections and single types. This library supports dynamic zones, components and relations.

Installation

pnpm add -D @jmen/strapi-types-generate

Configuration file

First, create a strapi-types-generate.json file in the root of your project.

You cal also run the CLI providing the path for the config file: pnpm stg --config=src/config.json.

Example strapi-types-generate.json:

{
  "strapiDir": "backend",
  "outputDir": "frontend/src/@types",
  "dateType": "string",
  "customFields": {
    "plugin::color-picker.color": "`#${string}`",
    "plugin::ckeditor5.CKEditor": "string",
    "plugin::strapi-plugin-iconhub.iconhub": {
      "name": "IconHubIcon",
      "attributes": {
        "iconName": "string",
        "iconData": "string",
        "width": "number",
        "height": "number",
        "isSvgEditable": "boolean",
        "isIconNameEditable": "boolean"
      }
    }
  }
}

You can also provide any of the configuration as argument to the CLI.

pnpm stg --strapiDir='backend' --outputDir='frontend/src/@types' --dateType='Date' --customFields='{"plugin::color-picker.color":"`#${string}`","plugin::ckeditor5.CKEditor":"string"}'

Configuration options

| Property | Type | Default value | Description | | -------------- | -------------------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------ | | strapiDir | string | "." | Strapi root directory | | outputDir | string | "./@types" | Interfaces output directory | | dateType | string | "string" | Dates may be returned in different formats depending on how you're fetching data. You may want to use Date here. | | customFields | Record<string, string \| { name: string; attributes: Record<string, unknown> } | {} | Provide type definition for custom fields. |

Outputs

Routes.ts

A typescript enum is generated so you can have a type safe fetch function

export enum StrapiRoute {
  Footer = "footers",
  FooterDocument = "footers/{documentId}",
  Page = "pages",
  PageDocument = "pages/{documentId}",
  Menu = "menus",
  MenuDocument = "menus/{documentId}",
}

// Example
export const get = async <T>(
  route: StrapiRoute,
  opts?: { documentId?: string }
) => {
  let endpoint = `http://localhost:1337/api/${route}`;

  if (opts?.documentId) {
    endpoint = endpoint.replace("{documentId}", opts?.documentId);
  }

  const res = await fetch(`...`);
  const data = (await res.json()) as Strapi.Payload<T>;
};

Api.d.ts

Api.d.ts contains your collections and single types

declare namespace Api {
  interface Menu {
    id?: number;
    documentId?: string;
    logo?: null | Strapi.Media;
  }

  interface Page {
    id?: number;
    documentId?: string;
    url?: null | string;
    sections?: null | (Components.Text | Components.Button)[]; // dynamic zone
    menu?: null | Api.Menu;
  }
}

Components.d.ts

declare namespace Components {
  interface Button {
    __component?: "category.button"; // __component is returned in dynamic zones
    id?: number;
    label?: null | string;
    size?: null | "small" | "medium" | "large"; // enum
    backgroundColor?: `#${string}`; // customFields["plugin::color-picker.color"]
    icon?: null | Strapi.IconHubIcon; // customFields["plugin::strapi-plugin-iconhub.iconhub"].name
  }

  interface Text {
    __component?: "category.button"; // __component is returned in dynamic zones
    id?: number;
    content?: null | string; // customFields["plugin::ckeditor5.CKEdito"]
  }
}

Strapi.d.ts

declare namespace Strapi {
  interface Payload<T> {
    data: T;
    error?: {
      status: number;
      name: "NotFoundError";
      message: "Not Found";
      details: unknown;
    };
    meta?: {
      pagination?: {
        page: number;
        pageSize: number;
        pageCount: number;
        total: number;
      };
    };
  }

  interface MediaFormat {
    //...
  }

  interface Media {
    id?: number;
    formats?: {
      thumbnail: MediaFormat;
      medium: MediaFormat;
      small: MediaFormat;
    };
    //...
  }

  // custom field defined in config
  interface IconHubIcon {
    iconName?: string;
    iconData?: string;
    width?: number;
    height?: number;
    isSvgEditable?: boolean;
    isIconNameEditable?: boolean;
  }

  // Role, Permissions and User is only generated if @strapi/plugin-users-permissions is in package.json
  interface Role {
    id?: number;
    permissions?: Strapi.Permission[];
    // ...
  }

  interface Permission {
    id?: number;
    role?: Strapi.Role;
    // ...
  }

  interface User {
    id?: number;
    documentId?: string;
    username?: null | string;
    email?: null | string;
    provider?: null | string;
    resetPasswordToken?: null | string;
    confirmationToken?: null | string;
    confirmed?: null | boolean;
    blocked?: null | boolean;
    role?: null | Strapi.Role;
  }
}