@amalaika/form-sdk-package
v1.0.1
Published
Framework-agnostic SDK for event form integration — fetch forms, handle visibility, upload files, and submit.
Maintainers
Readme
@amalaika/form-sdk-package
Framework-agnostic SDK for integrating the event registration form system. Handles data fetching, conditional visibility, file uploads, and form submission — no UI rendering included.
Works with React, Vue, Angular, Svelte, vanilla JS, or any environment with the Fetch API.
Installation
npm install @amalaika/form-sdk-packageFor local development (monorepo):
{
"dependencies": {
"@amalaika/form-sdk-package": "file:../form-sdk-package"
}
}Quick Start
import { EventFormClient, getAllFields, isFieldVisible } from "@amalaika/form-sdk-package";
const client = new EventFormClient({
apiKey: "Am_550e8400-e29b-41d4-a716-446655440000",
resourceType: "ticketing",
locale: "en", // default locale for all requests
});
// All calls automatically use "en" — no locale param needed
const tickets = await client.fetchTickets();
const form = await client.fetchForm(tickets[0].id);
const fields = getAllFields(form.schema);
// Switch language without reinstantiating
client.setLocale("fr");
const ticketsFr = await client.fetchTickets(); // now uses "fr"API Reference
Constructor
const client = new EventFormClient(config: EventFormConfig);| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| apiKey | string | Yes | Event API key (e.g. "Am_550e8400-...") |
| resourceType | "ticketing" \| "accommodation" \| "exhibition" | Yes | Resource type for submissions |
| apiBaseUrl | string | No | API base URL. Defaults to "https://api.eventsfactory.rw/api" |
| locale | string | No | Default locale for all requests. Can be changed later via setLocale() |
| errorMessages | Partial<ErrorMessages> | No | Custom error messages — override any or all defaults |
| origin | string | No | Origin header sent with every request. Defaults to "https://smartevent.rw" |
| timeout | number | No | Request timeout in milliseconds. Defaults to 30000 |
| retry | { maxRetries?: number; delay?: number } | No | Retry configuration. Defaults to 3 retries with 1s delay and exponential backoff. Only retries on 5xx and network errors |
| cache | { enabled?: boolean; ttl?: number } | No | Response caching for GET requests. Disabled by default. Use clearCache() to invalidate |
| noCache | boolean | No | Send Cache-Control: no-cache header with every request. Defaults to false |
| interceptors | { request?, response?, error? } | No | Request/response interceptors for modifying headers, transforming data, or handling errors |
Locale Management
Set a default locale on the constructor so you don't have to pass it on every method call:
const client = new EventFormClient({
apiKey: "Am_550e8400-...",
resourceType: "ticketing",
locale: "fr",
});
// All calls automatically use "fr" — no need to pass locale
const tickets = await client.fetchTickets();
const form = await client.fetchForm(tickets[0].id);Switch locale at any time without reinstantiating:
client.setLocale("en");
// All subsequent calls now use "en"Read the current locale:
client.getLocale(); // "en"Per-call locale still overrides the default when needed:
// Uses "de" for this call only, default remains "en"
const tickets = await client.fetchTickets({ locale: "de" });Methods
client.fetchTickets(options?)
Fetch all published tickets for the event.
const tickets = await client.fetchTickets({ locale: "fr", name: "VIP" });| Option | Type | Description |
|--------|------|-------------|
| locale | string | Locale code for translations (also sent as Accept-Language) |
| name | string | Filter tickets by name |
Returns Promise<Ticket[]>.
client.fetchTicketById(id, locale?)
Fetch a single ticket by ID.
const ticket = await client.fetchTicketById(42, "en");Returns Promise<Ticket>.
client.fetchLanguages()
Fetch available languages for the event. Returns codes sorted with the default language first.
const languages = await client.fetchLanguages();
// ["en", "fr", "ar"]Returns Promise<string[]>.
client.fetchForm(ticketId, locale?)
Fetch the form linked to a ticket.
const form = await client.fetchForm(1, "fr");Returns Promise<FormData>. The form.schema contains the field definitions used to render the form.
client.authorizeUpload(formId, fieldId, file, locale?)
Step 1 of file upload — request an upload token.
const token = await client.authorizeUpload(form.id, "resume", file);Returns Promise<string> (the upload token).
client.uploadFile(formId, token, file, locale?)
Step 2 of file upload — upload the file using the token.
const fileUrl = await client.uploadFile(form.id, token, file);Returns Promise<string> (the uploaded file URL to include in submission data).
client.submitForm(formId, data, context)
Submit form data.
await client.submitForm(form.id, submissionData, {
eventId: form.eventId,
ticketId: 1,
locale: "en",
});| Context Field | Type | Required | Description |
|---------------|------|----------|-------------|
| eventId | number | Yes | Event ID (from form.eventId) |
| ticketId | number | Yes | Ticket ID used to fetch the form |
| locale | string | No | Locale for Accept-Language header |
The resourceType is automatically sent from the constructor config.
Returns Promise<void>.
Utility Functions
Pure functions for working with form schemas and conditional visibility. Import directly:
import { getAllFields, isFieldVisible, getVisibleFieldIds } from "@amalaika/form-sdk-package";getAllFields(schema)
Extracts all fields from a FormSchema, whether flat or stepped.
const fields = getAllFields(form.schema);Returns FieldDefinition[].
isFieldVisible(field, formValues, allFields)
Checks whether a field should be visible based on the current form values. Supports cascading visibility (if a parent field is hidden, its dependents are too).
if (isFieldVisible(field, currentValues, allFields)) {
// render this field
}Returns boolean.
Supported operators:
| Operator | Visible when |
|----------|-------------|
| equals | formValues[dependsOn] === value |
| not_equals | formValues[dependsOn] !== value |
| in | Any overlap between selected values and target values |
getVisibleFieldIds(allFields, formValues)
Returns the set of field IDs that are currently visible. Use this to filter submission data — only submit visible fields.
const visibleIds = getVisibleFieldIds(allFields, formValues);
const submissionData = {};
for (const [key, val] of Object.entries(formValues)) {
if (visibleIds.has(key)) submissionData[key] = val;
}Returns Set<string>.
Full Example
import {
EventFormClient,
getAllFields,
getVisibleFieldIds,
} from "@amalaika/form-sdk-package";
const client = new EventFormClient({
apiKey: "Am_550e8400-e29b-41d4-a716-446655440000",
resourceType: "ticketing",
locale: "en",
});
// 1. Fetch tickets and pick one (uses default locale "en")
const tickets = await client.fetchTickets();
const ticket = tickets[0];
// 2. Fetch the form (uses default locale "en")
const form = await client.fetchForm(ticket.id);
const allFields = getAllFields(form.schema);
// 3. Collect user input into formValues (your UI handles this)
const formValues: Record<string, unknown> = {
first_name: "Jane",
last_name: "Doe",
email: "[email protected]",
role: "speaker",
talk_title: "Building Dynamic Forms",
};
// 4. Filter to visible fields only
const visibleIds = getVisibleFieldIds(allFields, formValues);
const submissionData: Record<string, unknown> = {};
for (const [key, val] of Object.entries(formValues)) {
if (visibleIds.has(key)) submissionData[key] = val;
}
// 5. Handle file uploads (if any)
const resumeFile = new File(["..."], "resume.pdf", { type: "application/pdf" });
const token = await client.authorizeUpload(form.id, "resume", resumeFile);
const fileUrl = await client.uploadFile(form.id, token, resumeFile);
submissionData["resume"] = fileUrl;
// 6. Submit (locale comes from constructor default)
await client.submitForm(form.id, submissionData, {
eventId: form.eventId!,
ticketId: ticket.id,
});Exported Types
import type {
ErrorMessages,
EventFormConfig,
FieldOption,
FieldDefinition,
StepDefinition,
FormSchema,
FormData,
ApiResponse,
TicketTranslation,
Ticket,
} from "@amalaika/form-sdk-package";Development
# Install dependencies
npm install
# Build (ESM + CJS)
npm run build
# Run tests
npm test
# Lint
npm run lintLicense
MIT
