Skip to content

feat: Add Phone Number Plugin field support.#74

Open
quangbahoa wants to merge 1 commit into
janbuchar:masterfrom
quangbahoa:feat/add-phonenumber-field-support
Open

feat: Add Phone Number Plugin field support.#74
quangbahoa wants to merge 1 commit into
janbuchar:masterfrom
quangbahoa:feat/add-phonenumber-field-support

Conversation

@quangbahoa
Copy link
Copy Markdown

Add PhoneNumber Field Type Support for payload-phone-number-plugin

Problem

When using payload-phone-number-plugin with payload-oapi, the OpenAPI spec generation fails with the error:

Unknown reference: PhoneNumber

This occurs because payload-phone-number-plugin creates a custom field type PhoneNumber that payload-oapi doesn't recognize when processing JSON schema references.

Solution

Add support for the PhoneNumber custom field type by:

  1. Adding PhoneNumber schema definition in generateComponents() function
  2. Handling PhoneNumber reference in adjustRefTargets() function

Changes Required

1. File: src/openapi/generators.ts (or equivalent TypeScript source)

Add helper function to check for PhoneNumber references:

// Helper function to check if PhoneNumber reference exists in generated schemas
// This is more reliable than checking field types since phoneNumberField from plugin
// may not expose its type directly
const hasPhoneNumberReference = (payload: PayloadRequest['payload']): boolean => {
  // Check all collections by generating schema and looking for PhoneNumber reference
  for (const collection of Object.values(payload.collections)) {
    try {
      const schema = entityToJSONSchema(
        payload.config,
        removeInterfaceNames(collection.config),
        new Map(),
        'text',
        undefined,
      )
      // Check if schema contains PhoneNumber reference
      const schemaStr = JSON.stringify(schema)
      if (schemaStr.includes('"#/definitions/PhoneNumber"') || schemaStr.includes('PhoneNumber')) {
        return true
      }
    } catch (e) {
      // If schema generation fails, continue checking other collections
      continue
    }
  }
  // Check all globals
  for (const global of payload.globals.config) {
    try {
      const schema = entityToJSONSchema(
        payload.config,
        removeInterfaceNames(global),
        new Map(),
        'text',
        undefined,
      )
      const schemaStr = JSON.stringify(schema)
      if (schemaStr.includes('"#/definitions/PhoneNumber"') || schemaStr.includes('PhoneNumber')) {
        return true
      }
    } catch (e) {
      continue
    }
  }
  return false
}

In generateComponents() function:

Conditionally add PhoneNumber schema only if it's actually used:

const generateComponents = (req: Pick<PayloadRequest, 'payload'>) => {
  const schemas: Record<string, JSONSchema4> = {
    supportedTimezones: {
      type: 'string',
      example: 'Europe/Prague',
    },
  }

  // Only add PhoneNumber schema if it's actually used (has PhoneNumber reference in any schema)
  if (hasPhoneNumberReference(req.payload)) {
    schemas.PhoneNumber = {
      type: 'string',
      format: 'tel',
      description: 'Phone number in E.164 format (e.g., +84901230000)',
      example: '+84901230000',
    }
  }
  // ... rest of function
}

In adjustRefTargets() function:

Add handling for PhoneNumber reference before checking collections:

const adjustRefTargets = (
  payload: PayloadRequest['payload'],
  spec: Record<string, unknown>,
): void => {
  const search = /^#\/definitions\/(.*)/

  visitObjectNodes(spec, (subject, key, value) => {
    const isRef = key === '$ref' && typeof value === 'string'

    if (!isRef) {
      return
    }

    subject[key] = value.replace(search, (_match, name: string) => {
      if (name === 'supportedTimezones') {
        return '#/components/schemas/supportedTimezones'
      }

      // Handle PhoneNumber custom field type from payload-phone-number-plugin
      if (name === 'PhoneNumber') {
        return '#/components/schemas/PhoneNumber'
      }

      const collection = payload.collections[name]
      // ... rest of function
    })
  })
}

Testing

  1. Install payload-phone-number-plugin in a Payload CMS project
  2. Add a phoneNumberField to a collection
  3. Generate OpenAPI spec - should no longer throw "Unknown reference: PhoneNumber" error
  4. Verify that phoneNumber field appears in OpenAPI spec as a string with format: 'tel'

Benefits

  • Enables OpenAPI spec generation for collections using phoneNumberField from payload-phone-number-plugin
  • Provides proper schema definition for phone numbers in OpenAPI documentation
  • Follows the same pattern as supportedTimezones handling
  • Conditional generation: Only adds PhoneNumber schema when actually used, keeping OpenAPI spec clean for projects that don't use the plugin

Related

Notes

This fix can be extended to support other custom field types from plugins by following the same pattern:

  1. Add schema definition in generateComponents()
  2. Add reference handling in adjustRefTargets()

Support for phoneNumber field.
@quangbahoa quangbahoa changed the title Add Phone Number Plugin field support. feat: Add Phone Number Plugin field support. Jan 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant