mirror of
https://github.com/xtr-dev/payload-mailing.git
synced 2025-12-10 00:03:23 +00:00
Add PayloadID type and relation helpers, fix filterOptions casting issue
- Add PayloadID type for string | number IDs - Add PayloadRelation<T> type for populated/unpopulated relations - Add isPopulated() type guard to check if relation is populated - Add resolveID() helper to extract ID from relation (object or ID) - Add resolveIDs() helper for arrays of relations - Fix filterOptions in Emails.ts to safely resolve ID before filtering - This prevents MongoDB ObjectId casting errors when id is an object - Bump version to 0.4.15 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@xtr-dev/payload-mailing",
|
"name": "@xtr-dev/payload-mailing",
|
||||||
"version": "0.4.14",
|
"version": "0.4.15",
|
||||||
"description": "Template-based email system with scheduling and job processing for PayloadCMS",
|
"description": "Template-based email system with scheduling and job processing for PayloadCMS",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { CollectionConfig } from 'payload'
|
import type { CollectionConfig } from 'payload'
|
||||||
import { findExistingJobs, ensureEmailJob, updateEmailJobRelationship } from '../utils/jobScheduler.js'
|
import { findExistingJobs, ensureEmailJob, updateEmailJobRelationship } from '../utils/jobScheduler.js'
|
||||||
import { createContextLogger } from '../utils/logger.js'
|
import { createContextLogger } from '../utils/logger.js'
|
||||||
|
import { resolveID } from '../utils/helpers.js'
|
||||||
|
|
||||||
const Emails: CollectionConfig = {
|
const Emails: CollectionConfig = {
|
||||||
slug: 'emails',
|
slug: 'emails',
|
||||||
@@ -197,9 +198,10 @@ const Emails: CollectionConfig = {
|
|||||||
readOnly: true,
|
readOnly: true,
|
||||||
},
|
},
|
||||||
filterOptions: ({ id }) => {
|
filterOptions: ({ id }) => {
|
||||||
|
const emailId = resolveID({ id })
|
||||||
return {
|
return {
|
||||||
'input.emailId': {
|
'input.emailId': {
|
||||||
equals: id,
|
equals: emailId ? String(emailId) : '',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import { Payload } from 'payload'
|
import { Payload } from 'payload'
|
||||||
import type { CollectionConfig, RichTextField } from 'payload'
|
import type { CollectionConfig, RichTextField } from 'payload'
|
||||||
|
|
||||||
|
// Payload ID type (string or number)
|
||||||
|
export type PayloadID = string | number
|
||||||
|
|
||||||
|
// Payload relation type - can be populated (object with id) or unpopulated (just the ID)
|
||||||
|
export type PayloadRelation<T extends { id: PayloadID }> = T | PayloadID
|
||||||
|
|
||||||
// JSON value type that matches Payload's JSON field type
|
// JSON value type that matches Payload's JSON field type
|
||||||
export type JSONValue = string | number | boolean | { [k: string]: unknown } | unknown[] | null | undefined
|
export type JSONValue = string | number | boolean | { [k: string]: unknown } | unknown[] | null | undefined
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Payload } from 'payload'
|
import { Payload } from 'payload'
|
||||||
import { TemplateVariables } from '../types/index.js'
|
import { TemplateVariables, PayloadID, PayloadRelation } from '../types/index.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse and validate email addresses
|
* Parse and validate email addresses
|
||||||
@@ -74,6 +74,49 @@ export const sanitizeFromName = (fromName: string | null | undefined): string |
|
|||||||
return sanitized.length > 0 ? sanitized : undefined
|
return sanitized.length > 0 ? sanitized : undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type guard to check if a Payload relation is populated (object) or unpopulated (ID)
|
||||||
|
*/
|
||||||
|
export const isPopulated = <T extends { id: PayloadID }>(
|
||||||
|
value: PayloadRelation<T> | null | undefined
|
||||||
|
): value is T => {
|
||||||
|
return value !== null && value !== undefined && typeof value === 'object' && 'id' in value
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves a Payload relation to just the ID
|
||||||
|
* Handles both populated (object with id) and unpopulated (string/number) values
|
||||||
|
*/
|
||||||
|
export const resolveID = <T extends { id: PayloadID }>(
|
||||||
|
value: PayloadRelation<T> | null | undefined
|
||||||
|
): PayloadID | undefined => {
|
||||||
|
if (value === null || value === undefined) return undefined
|
||||||
|
|
||||||
|
if (typeof value === 'string' || typeof value === 'number') {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'object' && 'id' in value) {
|
||||||
|
return value.id
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves an array of Payload relations to an array of IDs
|
||||||
|
* Handles mixed arrays of populated and unpopulated values
|
||||||
|
*/
|
||||||
|
export const resolveIDs = <T extends { id: PayloadID }>(
|
||||||
|
values: (PayloadRelation<T> | null | undefined)[] | null | undefined
|
||||||
|
): PayloadID[] => {
|
||||||
|
if (!values || !Array.isArray(values)) return []
|
||||||
|
|
||||||
|
return values
|
||||||
|
.map(value => resolveID(value))
|
||||||
|
.filter((id): id is PayloadID => id !== undefined)
|
||||||
|
}
|
||||||
|
|
||||||
export const getMailing = (payload: Payload) => {
|
export const getMailing = (payload: Payload) => {
|
||||||
const mailing = (payload as any).mailing
|
const mailing = (payload as any).mailing
|
||||||
if (!mailing) {
|
if (!mailing) {
|
||||||
|
|||||||
Reference in New Issue
Block a user