Skip to content

soranoo/payloadcms-typing-supercharge

Repository files navigation

PayloadCMS-Typing-Supercharge

Project starts on 18-05-2025

MIT License npm version npm downloads   Donation

This package provides strongly typed PayloadCMS types, enhancing the type safety and validation of your PayloadCMS queries and operations. It allows you to perform type-safe selections, where clauses, sort operations, and CRUD operations with strong type inference.

Give me a ⭐ if you like it.

🤔 Why this?

PayloadCMS is a great headless CMS, but its default types can be enhanced to provide better type safety and validation. This package supercharges PayloadCMS with:

  • Strong type inference for nested queries
  • Type-safe field selections
  • Enhanced type safety for CRUD operations

IMHO, Payload claims to be type-safe, but not strong as I expected (ton of any...) Give me a ⭐ if you agree :p

🗝️ Features

  • Type Safety Selection: Type-safe selecting up to any specified depth, not more string | {collection-object} at the same time.
  • 🎯 Where Clause Type Safety: Enhanced type checking for query filters
  • 📊 Sort Type Safety: Type-safe sorting operations with dot notation support
  • 🚀 CRUD Operation Type Safety: Support the following operations:
    • find
    • findByID
    • create
    • update (byID and Bulk)
    • delete (byID and Bulk)
  • 🔍 Type-Safe Types: Support the following type:
    • AccessResult
    • Access
    • FilterOptionsFunc
    • FilterOptions
    • Sort
    • Where

Caution

ALL operations under TypedPayload are rootless by default, meaning overrideAccess = false.

Note

If you want to use root access by default, you can set overrideAccess = true in the constructor of TypedPayload class. eg. const typedPayload = new TypedPayload(payload, { overrideAccess: true });

📦 Requirements

  • PayloadCMS >= 3.0.0
  • TypeScript >= 5.0.0

🚀 Getting Started

Installation

Install the package using npm:

npm install payloadcms-typing-supercharge

Then you can use the CLI to generate types.

Tip

Read CLI for more information on using the command line interface.

Usage 🎉

  1. First, import the TypedPayload class:

    import { TypedPayload } from 'payloadcms-typing-supercharge';
  2. Create a type-safe PayloadCMS instance:

    const typedPayload = TypedPayload.createTypedPayload(payload);
  3. Enjoy type-safe operations! Here are some examples:

Type Safe Selection

interface Profile { // Sample Collection Type
  id: string;
  name: string;
  subProfile: Profile;
}
interface User { // Sample Collection Type
  id: string;
  name: string;
  profile: Profile;
}

const result = await typedPayload.find({
  collection: 'users',
  depth: 2,
});

result.profile // ✅ Type: Profile, current depth 0
result.profile.subProfile // ✅ Type: Profile, current depth 1
result.profile.subProfile.subProfile // ✅ Type: string (ID),  current depth 2
result.profile.subProfile.subProfile.subProfile // ❌ Invalid, depth exceeded, current depth 3

Type-Safe Query Operation

interface Profile { // Sample Collection Type
  id: string;
  name: string;
  subProfile: Profile;
}
interface User { // Sample Collection Type
  id: string;
  name: string;
  profile: Profile;
}

await typedPayload.find({
  collection: 'users',
  where: {
    "profile.subProfile.name": { // ✅ Valid selection
      equals: 'John Doe'
    }
  },
});

await typedPayload.find({
  collection: 'users',
  where: {
    "profile.subProfile.firstName": { // ❌ Invalid selection, `firstName` does not exist
      equals: 'John Doe'
    }
  },
});

Type-Safe Sort Operation

interface Profile { // Sample Collection Type
  id: string;
  name: string;
  subProfile: Profile;
}
interface User { // Sample Collection Type
  id: string;
  name: string;
  profile: Profile;
}

await typedPayload.find({
  collection: 'users',
  sort: ['name', '-profile.subProfile.name'], // ✅ Valid sort
});

await typedPayload.find({
  collection: 'users',
  sort: [
    '+name', // ❌ Invalid sortting operator, `+` is not allowed
    '-profile.subProfile.firstName' // ❌ Invalid sort, `firstName` does not exist
    ], 
});

Type-Safe Collection Config (WIP)

import { createTypedCollectionConfig } from './__generated__/payloadcms-typing-supercharge';

export const Users = createTypedCollectionConfig({
  slug: 'users',
  fields: [
    {
      name: 'name',
      type: 'text',
    },
    {
      name: 'profile',
      type: 'relationship',
      relationTo: 'profiles',
    },
  ],
  access: { // ✅ Typed
    //...
  },
});

Note

Not all values in the createTypedCollectionConfig are type-safe right now.

⚡ CLI

  • --in <path>: The path of your payload-types.ts. Default: ./src/payload-types.ts.
  • --out <dir>: Output directory to write types. Default: ./src/__generated__/payloadcms-typing-supercharge.
  • --depth <n>: Max depth to emit (inclusive from 0..n). Default: 6.

Examples:

payloadcms-typing-supercharge --in ./src/payload-types.ts --out ./src/__generated__/payloadcms-typing-supercharge --depth 2

🐛 Troubleshooting

n/a

⭐ TODO

  • Optimise typed Where performance
  • Retype the WHOLE Payload CollectionConfig

🐛 Known Issues

  • n/a

🤝 Contributing

Contributions are welcome! If you find a bug or have a feature request, please open an issue. If you want to contribute code, please fork the repository and submit a pull request.

Note

Due to the typing loss in the TypedPayload class after build process, the package will serve as the orginal typescript source code.

Note

TypeScript aliases are not allowed in this project to prevent aliases mapping problem after file copy. So make sure to use the relative path for file imports.

📝 License

This project is licensed under the MIT License - see the LICENSE file for details

☕ Donation

Love it? Consider a donation to support my work.

"Donation" <- click me~

About

This package provides strongly typed PayloadCMS types, enhancing the type safety and validation of your PayloadCMS queries and operations. It allows you to perform type-safe selections, where clauses, sort operations, and CRUD operations with strong type inference.

Topics

Resources

License

Stars

Watchers

Forks

Contributors