From ce268388b46cd7a2d18ee877d2d3d4cd531f5463 Mon Sep 17 00:00:00 2001 From: Moses Date: Wed, 1 Oct 2025 07:35:43 +0100 Subject: [PATCH 1/3] Revert "fix: Turn into payload plugin" This reverts commit 25f2aad4760445de50ff3be5ea6aa93cb8bfdacc. --- src/utils/payload-assist.ts | 49 +++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/utils/payload-assist.ts b/src/utils/payload-assist.ts index fde93e8..925fa49 100644 --- a/src/utils/payload-assist.ts +++ b/src/utils/payload-assist.ts @@ -1,6 +1,6 @@ import { PayloadAssistConfig, PayloadAssistOptions } from "../types/config"; import payloadAssistDefaultConfig from "../default.config"; -import { Config as PayloadConfig, Plugin } from "payload"; +import { buildConfig, Config as PayloadConfig } from "payload"; export { payloadAssistDefaultConfig as defaultConfig }; @@ -12,32 +12,33 @@ export let payloadAssistConfig: PayloadAssistConfig | undefined = undefined; * @param options - The options to cusotmize payloadAssist. * @returns Built and sanitized Payload Config */ -export const payloadAssist = - (options?: PayloadAssistOptions): Plugin => - (payloadConfig: PayloadConfig) => { - if (payloadAssistConfig) throw `PayloadAssist is already initialized`; +export const payloadAssist = ( + payloadConfig: PayloadConfig, + options?: PayloadAssistOptions +) => { + if (payloadAssistConfig) throw `PayloadAssist is already initialized`; - payloadAssistConfig = { - ...payloadAssistDefaultConfig, - ...(options ?? {}), - }; + payloadAssistConfig = { + ...payloadAssistDefaultConfig, + ...(options ?? {}), + }; - Object.entries(payloadAssistConfig.ruleSet).reduce( - (payloadConfig, [ruleName, rule]) => { - try { - if (rule === false) return payloadConfig; // rule is deactivated, so we skip it - if (!rule(payloadConfig)) - throw `The payload config does not satisfy "${ruleName}".`; - } catch (error) { - throw `[PayloadAssist Error]: ${ruleName}: ${error}`; - } - return payloadConfig; - }, - payloadConfig - ); + Object.entries(payloadAssistConfig.ruleSet).reduce( + (payloadConfig, [ruleName, rule]) => { + try { + if (rule === false) return payloadConfig; // rule is deactivated, so we skip it + if (!rule(payloadConfig)) + throw `The payload config does not satisfy "${ruleName}".`; + } catch (error) { + throw `[PayloadAssist Error]: ${ruleName}: ${error}`; + } + return payloadConfig; + }, + payloadConfig + ); - return payloadConfig; - }; + return buildConfig(payloadConfig); +}; /** * Resets internal module state for tests or reinitialization. From 98a3e5a672bfc8efcd106ddfb4c3133fa173acf9 Mon Sep 17 00:00:00 2001 From: Moses Date: Wed, 1 Oct 2025 07:45:51 +0100 Subject: [PATCH 2/3] Revert "feat: update README" This reverts commit 7d90b2b6028200ef77e7240f3d406803d689f703. --- README.md | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index be306cb..929af5a 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Utilities to add guardrails, DTO tooling, and ergonomic rules to Payload CMS pro - **DTOs**: First-class helpers to define, transform, validate, and enforce DTO-only responses. - **Ergonomics**: Thin wrappers to keep endpoints and collection reads consistent and secure. + ## Installation ```bash @@ -41,6 +42,7 @@ npm install @byte5digital/payload-assist Peer deps: Payload v3+, Next v15+. Dependencies `class-transformer` and `reflect-metadata` are included in the package. + ## API overview - `payloadAssist(payloadConfig, options?)`: Main function that initializes Assist for Payload, validates your payload config against defined rules, and returns the built config. @@ -76,14 +78,13 @@ export const MyCollection: CollectionConfig = { ### Initialize Assist for Payload -The main `payloadAssist` function initializes the library and validates your payload config against defined rules. You can customize the `ruleSet` and `transformAndValidate` function through options. +The main `payloadAssist` function initializes the library, validates your payload config against defined rules, and returns the built config. You can customize the `ruleSet` and `transformAndValidate` function through options. - **ruleSet**: An object map of named rules; merge defaults with your own, if required. Deactivate a default rule by setting the rule to `false`. - **rules**: `(config: payloadConfig) => boolean | void`; throw to fail with an actionable message and return true if the rule is satisfied. - **transformAndValidate**: `(dto: Dto, data: unknown) => Dto` Turn raw Payload data into typed DTOs. **Built-in rules:** - - `disableQraphQL`: Ensures GraphQL is disabled in your config - `collectionsEndpointsUseWithResponse`: Ensures all collection endpoints use `withResponse` - `collectionsUseWithDtoReadHook`: Ensures all collections use `withDtoReadHook` in their afterRead hooks @@ -92,19 +93,15 @@ The main `payloadAssist` function initializes the library and validates your pay import { buildConfig } from "payload"; import payloadAssist, { defaultConfig } from "@byte5digital/payload-assist"; -export default buildConfig({ +export default payloadAssist({ // your Payload config - plugins: [ - payloadAssist( - { - ruleSet: { - ...defaultConfig.ruleSet, - // add/override rules here - secretIsSet: (config) => config.secret?.length > 0 ? true : throw 'A secret needs to be set', - }, - } - ), - ] +}, { + ruleSet: { + ...defaultConfig.ruleSet, + + // add/override rules here + secretIsSet: (config) => config.secret?.length > 0 ? true : throw 'A secret needs to be set', + }, }); ``` @@ -142,7 +139,7 @@ Transform any raw Payload doc into a DTO. By default `transformAndValidate` uses ```ts import { transformAndValidate } from "@byte5digital/payload-assist"; -const payloadDoc = await getPayloadDoc(); +const payloadDoc = await getPayloadDoc() const dto = transformAndValidate(MyCollectionDto, payloadDoc); ``` From 2d5685e1cecadecab8873808f1667c2ee11e24e7 Mon Sep 17 00:00:00 2001 From: Moses Date: Wed, 1 Oct 2025 08:02:18 +0100 Subject: [PATCH 3/3] chore: add hint to readme that states why payload assist is not setup as a plugin --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 929af5a..e9298b1 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,6 @@ Utilities to add guardrails, DTO tooling, and ergonomic rules to Payload CMS pro - **DTOs**: First-class helpers to define, transform, validate, and enforce DTO-only responses. - **Ergonomics**: Thin wrappers to keep endpoints and collection reads consistent and secure. - ## Installation ```bash @@ -42,7 +41,6 @@ npm install @byte5digital/payload-assist Peer deps: Payload v3+, Next v15+. Dependencies `class-transformer` and `reflect-metadata` are included in the package. - ## API overview - `payloadAssist(payloadConfig, options?)`: Main function that initializes Assist for Payload, validates your payload config against defined rules, and returns the built config. @@ -79,12 +77,14 @@ export const MyCollection: CollectionConfig = { ### Initialize Assist for Payload The main `payloadAssist` function initializes the library, validates your payload config against defined rules, and returns the built config. You can customize the `ruleSet` and `transformAndValidate` function through options. +payloadAssist is implemenented as a wrapper function and not as a payload plugin, to ensure it validates the raw config that is set by the user, instead of the config that was previously processed by other plugins and enriched by payload. - **ruleSet**: An object map of named rules; merge defaults with your own, if required. Deactivate a default rule by setting the rule to `false`. - **rules**: `(config: payloadConfig) => boolean | void`; throw to fail with an actionable message and return true if the rule is satisfied. - **transformAndValidate**: `(dto: Dto, data: unknown) => Dto` Turn raw Payload data into typed DTOs. **Built-in rules:** + - `disableQraphQL`: Ensures GraphQL is disabled in your config - `collectionsEndpointsUseWithResponse`: Ensures all collection endpoints use `withResponse` - `collectionsUseWithDtoReadHook`: Ensures all collections use `withDtoReadHook` in their afterRead hooks @@ -139,7 +139,7 @@ Transform any raw Payload doc into a DTO. By default `transformAndValidate` uses ```ts import { transformAndValidate } from "@byte5digital/payload-assist"; -const payloadDoc = await getPayloadDoc() +const payloadDoc = await getPayloadDoc(); const dto = transformAndValidate(MyCollectionDto, payloadDoc); ``` @@ -151,7 +151,10 @@ Use `withResponse` to guarantee your endpoints return DTOs (and nothing else). I ```ts import payload from "payload"; -import { withResponse, transformAndValidate } from "@byte5digital/payload-assist"; +import { + withResponse, + transformAndValidate, +} from "@byte5digital/payload-assist"; import { MyDataDto } from "path/to/dtos"; export const MyCollection: CollectionConfig = {