Skip to main content

Data Model

ChamevoJS uses a three-level hierarchy: Product -> Views -> Elements.

Hierarchy

CVProduct
├── id?: string
├── title?: string
├── thumbnail?: string
├── options?: Partial<ChamevoOptions>
├── namesNumbers?: NamesNumbersEntry[] ← shared roster across all views
└── views: CVView[]
├── id?: string
├── title: string
├── thumbnail?: string
├── options?: Partial<ChamevoViewOptions>
├── locked?: boolean
├── elements: CVElementData[]
│ ├── id?: string
│ ├── type: ElementType
│ ├── title: string
│ ├── source: string
│ └── parameters: ElementParameters
└── printAreas?: CVPrintAreaConfig[]
├── id?: string
├── printingBox: PrintingBox
├── output?: PrintAreaOutput
├── mask?: PrintAreaMask
└── printProfile?: Partial<ChamevoPrintAreaOptions>

Types

All types are defined in @chamevo/types and can be imported:

import type {
CVProduct,
CVView,
CVElementData,
CVPrintAreaConfig,
ElementParameters,
TextParameters,
ImageParameters,
ChamevoOptions,
ChamevoEvents,
} from '@chamevo/types';

Serialization

getProduct() returns the complete product data as a serializable CVProduct:

const product = chamevo.getProduct();
const json = JSON.stringify(product);

// Later: restore the product
await chamevo.loadProduct(JSON.parse(json));

ID Generation

When id is omitted, ChamevoJS auto-generates a URL-friendly slug:

"Front View" → "front-view"
"Custom T-Shirt" → "custom-t-shirt"

Legacy Format

loadProduct() accepts both formats:

// New format
await chamevo.loadProduct({
title: 'T-Shirt',
views: [{ title: 'Front', elements: [...] }],
});

// Legacy format (flat array)
await chamevo.loadProduct([
{ title: 'Front', productTitle: 'T-Shirt', elements: [...] },
]);

Legacy arrays are auto-normalized: productTitle and productThumbnail from the first view become the product's title and thumbnail.

Next Steps