SimpleNS LogoDocs

Schemas

Reusable Zod schemas for validating notification payloads in SimpleNS providers.


Overview

The SDK provides pre-built Zod schemas that you can use directly or extend for your custom provider. Zod is re-exported from the SDK, so you don't need to install it separately.

import { z, emailRecipientSchema, createNotificationSchema } from '@simplens/sdk';

Base Schemas

baseRecipientSchema

The foundation for all recipient schemas. Contains the user_id field required for tracking.

const baseRecipientSchema = z.object({
  user_id: z.string(),
});

Fields:

FieldTypeDescription
user_idstringUnique identifier for the user

baseNotificationSchema

Common fields present in all notification payloads.

const baseNotificationSchema = z.object({
  notification_id: z.string(),
  request_id: z.string().uuid(),
  client_id: z.string().uuid(),
  channel: z.string(),
  provider: z.string().optional(),
  variables: z.record(z.string(), z.string()).optional(),
  webhook_url: z.string().url(),
  retry_count: z.number().int().min(0),
  created_at: z.coerce.date(),
});

Fields:

FieldTypeDescription
notification_idstringMongoDB ObjectId as string
request_idstring (UUID)Unique request identifier
client_idstring (UUID)Client application identifier
channelstringChannel name (email, sms, etc.)
providerstring?Optional provider override
variablesRecord<string, string>?Template variables for substitution
webhook_urlstring (URL)URL for status callbacks
retry_countnumber (int >= 0)Current retry attempt number
created_atDateNotification creation timestamp

Recipient Schemas

These schemas extend baseRecipientSchema with channel-specific fields.

emailRecipientSchema

const emailRecipientSchema = baseRecipientSchema.extend({
  email: z.string().email(),
});
FieldTypeDescription
user_idstringUser identifier
emailstring (email)Valid email address

Example:

{
  "user_id": "usr_12345",
  "email": "user@example.com"
}

smsRecipientSchema

const smsRecipientSchema = baseRecipientSchema.extend({
  phone: z.string(),
});
FieldTypeDescription
user_idstringUser identifier
phonestringPhone number (E.164)

Example:

{
  "user_id": "usr_12345",
  "phone": "+14155551234"
}

whatsappRecipientSchema

const whatsappRecipientSchema = baseRecipientSchema.extend({
  phone: z.string(),
});
FieldTypeDescription
user_idstringUser identifier
phonestringWhatsApp phone number

Example:

{
  "user_id": "usr_12345",
  "phone": "+14155551234"
}

pushRecipientSchema

const pushRecipientSchema = baseRecipientSchema.extend({
  device_token: z.string(),
});
FieldTypeDescription
user_idstringUser identifier
device_tokenstringFCM/APNs device token

Example:

{
  "user_id": "usr_12345",
  "device_token": "fcm_token_abc123..."
}

Content Schemas

emailContentSchema

Email message content with HTML/text body options.

const emailContentSchema = z.object({
  subject: z.string().optional(),
  html: z.string().optional(),
  text: z.string().optional(),
}).refine(
  data => data.html || data.text,
  { message: 'Either html or text content is required' }
);

At least one of html or text must be provided. The schema uses a Zod refinement to enforce this.

FieldTypeDescription
subjectstring?Email subject line
htmlstring?HTML body content
textstring?Plain text body content

Example:

{
  "subject": "Welcome to SimpleNS",
  "html": "<h1>Hello!</h1><p>Welcome to our platform.</p>"
}

smsContentSchema

SMS message content with character limit.

const smsContentSchema = z.object({
  message: z.string().max(1600),
});
FieldTypeDescription
messagestring (max 1600)SMS message body

The 1600 character limit supports concatenated SMS messages. Most providers segment messages at 160 characters.


whatsappContentSchema

WhatsApp message content.

const whatsappContentSchema = z.object({
  message: z.string(),
});
FieldTypeDescription
messagestringWhatsApp message body

Creating Complete Schemas

createNotificationSchema()

Combines base schemas with channel-specific recipient and content schemas.

function createNotificationSchema<
  R extends z.ZodObject<Record<string, z.ZodTypeAny>>,
  C extends z.ZodObject<Record<string, z.ZodTypeAny>>
>(
  channelName: string,
  recipientSchema: R,
  contentSchema: C
)

Parameters:

ParameterTypeDescription
channelNamestringChannel identifier (e.g., 'email')
recipientSchemaZodObjectRecipient fields schema
contentSchemaZodObjectContent fields schema

Example:

import { 
  createNotificationSchema, 
  emailRecipientSchema, 
  emailContentSchema,
  z 
} from '@simplens/sdk';

// Create the complete schema
const emailNotificationSchema = createNotificationSchema(
  'email',
  emailRecipientSchema,
  emailContentSchema
);

// Infer the TypeScript type
type EmailNotification = z.infer<typeof emailNotificationSchema>;

Extending Schemas

You can extend the built-in schemas to add custom fields.


Type Inference

Use Zod's z.infer<> to get TypeScript types from your schemas:

import { emailNotificationSchema } from './my-schemas';
import { z } from '@simplens/sdk';

// Get the type
type EmailNotification = z.infer<typeof emailNotificationSchema>;

// Now you have full type safety
function processNotification(notification: EmailNotification) {
  console.log(notification.recipient.email);  // ✓ Type-safe
  console.log(notification.content.html);     // ✓ Type-safe
}

On this page