@wuemv/content-sdk
v0.2.0
Published
SDK for Wue Content Management System — type generation, API client, schema validation, and helpers.
Maintainers
Readme
@wuemv/content-sdk
TypeScript SDK for Wue CMS — API client, schema-driven validation, type generation, and helpers for building storefronts.
Install
npm install @wuemv/content-sdkQuick Start
import { WueClient } from '@wuemv/content-sdk'
const client = new WueClient({
url: 'https://your-cms.com/api/v1',
token: 'your-tenant-api-token',
})
// Fetch contacts + form config
const { contacts, form } = await client.getContacts()
// Fetch booking packages + pricing
const { packages, form: bookingForm } = await client.getBookingConfig()
// Submit a contact form
const result = await client.submitContactForm({
full_name: 'John Doe',
email: '[email protected]',
message: 'Hello!',
})
console.log(result.reference) // "CF-2026-0001"API Client
Setup
import { WueClient } from '@wuemv/content-sdk'
const client = new WueClient({
url: process.env.CMS_API_URL, // e.g. https://cms.example.com/api/v1
token: process.env.CMS_API_TOKEN,
})Methods
| Method | Returns | Description |
|--------|---------|-------------|
| getContacts() | { contacts, form } | Display contacts + contact form schema |
| submitContactForm(data) | { reference, message } | Submit a contact form entry |
| getBookingConfig() | { content_type, packages, guest_fields, form } | Booking packages with pricing + guest form schema |
| submitBooking(payload) | { reference, status, message } | Submit a booking request |
| getEntries(typeSlug) | T[] | Published entries for a content type |
| getEntry(typeSlug, entrySlug) | T | Single entry by slug |
| getSchema() | ContentTypeSchema[] | All content type schemas |
| getContentTypeSchema(slug) | ContentTypeSchema | Schema for one content type |
| getSettings() | Record<string, any> | Tenant settings |
| getGalleries() | any[] | Photo galleries |
Error Handling
The client throws WueApiError on non-2xx responses, preserving the HTTP status and response body:
import { WueApiError } from '@wuemv/content-sdk'
try {
await client.submitContactForm(data)
} catch (err) {
if (err instanceof WueApiError) {
console.log(err.status) // 422
console.log(err.data) // { message: "...", errors: { email: ["..."] } }
}
}Schema Validation
Validate form data against field definitions from the CMS — client-side, before submitting. Rules mirror the CMS backend exactly.
import { validateForm, validateField } from '@wuemv/content-sdk'
// Validate entire form — returns { fieldKey: errorMessage } (empty = valid)
const errors = validateForm(schema.fields, formData)
if (Object.keys(errors).length === 0) {
// valid — submit
}
// Validate a single field (e.g. on blur)
const error = validateField(field, value, formData)
// null = valid, string = error messageSupported Rules
| Field Type | Validations |
|------------|-------------|
| text | required, max length (default 255), min length, pattern regex |
| email | required, email format, max 255 |
| url | required, URL format, max 255 |
| number | required, numeric, min/max value |
| textarea / richtext | required, min/max length |
| date | required, YYYY-MM-DD format |
| select | required, value must be in choices |
| boolean | required, must be true/false |
| tags | must be array |
| image | must be string |
Hidden fields (via conditions) are automatically skipped.
Helpers
import { flattenFields, isFieldVisible } from '@wuemv/content-sdk'
// Unwrap sections into a flat list of data fields
const flat = flattenFields(schema.fields)
// Check if a field is visible given current form state
const visible = isFieldVisible(field, formData)Type Generation (CLI)
Generate TypeScript interfaces from your CMS content type schemas:
npx wue-content generate-types --url=https://cms.example.com/api/v1 --token=abc123Or via environment variables:
export WUE_CONTENT_API_URL=https://cms.example.com/api/v1
export WUE_CONTENT_API_TOKEN=abc123
npx wue-content generate-typesOutput (default ./types/content.ts):
// Auto-generated — do not edit
export interface DivePackagesEntry {
id: number
slug: string
title: string
content: string
nights: number
// ...
}CLI Options
| Flag | Default | Description |
|------|---------|-------------|
| --url | WUE_CONTENT_API_URL | CMS API base URL |
| --token | WUE_CONTENT_API_TOKEN | Tenant API token |
| --output | ./types/content.ts | Output file path |
TypeScript Types
All types are exported for use in your frontend:
import type {
// Field system
FieldType,
FieldWidth,
FieldDefinition,
FieldOptions,
FieldCondition,
// Contacts
Contact,
ContactType,
ContactsResponse,
ContactFormSchema,
ContactSubmitResponse,
// Bookings
BookingPackage,
BookingPricingOption,
BookingConfigResponse,
BookingFormSchema,
BookingSubmitPayload,
BookingSubmitResponse,
BookingContentType,
// Content
ContentTypeSchema,
FieldSchema,
// Config
WueConfig,
} from '@wuemv/content-sdk'Field Types (Fixed Vocabulary)
type FieldType =
| 'text' | 'textarea' | 'richtext' | 'email'
| 'number' | 'date' | 'select' | 'boolean'
| 'url' | 'tags' | 'image' | 'section'
type FieldWidth = 3 | 4 | 6 | 12 // 12-column grid fractionsUsage with Nuxt
The SDK is designed for server-side usage in Nuxt — keep the tenant token out of the browser:
// server/utils/cms.ts
import { WueClient } from '@wuemv/content-sdk'
export function useCmsClient(): WueClient {
const config = useRuntimeConfig()
return new WueClient({
url: config.cmsApiUrl,
token: config.cmsApiToken,
})
}
// server/api/cms/contacts.get.ts
export default defineEventHandler(async () => {
const client = useCmsClient()
const data = await client.getContacts()
return { data }
})Browser-side code calls local Nuxt server routes — never touches the CMS directly.
License
MIT
