@amalaika/form-sdk-package
v1.2.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 event form integration — fetch forms, handle visibility, upload files, submit, and process payments.
Zero runtime dependencies. Works with any JavaScript framework or vanilla JS.
Installation
npm install @amalaika/form-sdk-packageQuick Start
import { EventFormClient, FormStateManager, validateForm, getAllFields } from "@amalaika/form-sdk-package";
// 1. Create a client
const client = new EventFormClient({
apiKey: "Am_550e8400-...",
resourceType: "ticketing",
});
// 2. Fetch tickets and forms
const tickets = await client.fetchTickets();
const form = await client.fetchForm(tickets[0].id);
// 3. Manage form state
const fields = getAllFields(form.schema);
const state = new FormStateManager(fields);
state.setValue("email", "[email protected]");
// 4. Validate and submit
const errors = validateForm(fields, state.getValues());
const allValid = Object.values(errors).every((r) => r.valid);
if (allValid) {
const { submission, integrations } = await client.submitForm(form, state.getSubmissionData(), {
resourceId: tickets[0].id,
attendanceType: "IN_PERSON",
});
}Configuration
const client = new EventFormClient({
// Required
apiKey: "Am_550e8400-...",
resourceType: "ticketing", // "ticketing" | "accommodation" | "exhibition"
// Optional
apiBaseUrl: "https://api.example.com", // defaults to production
locale: "en", // default locale for requests
origin: "https://myapp.com", // Origin header
timeout: 30000, // request timeout (ms)
noCache: false, // send Cache-Control: no-cache
mastercardCheckoutUrl: "https://...", // checkout script URL override
merchantName: "My Event", // shown in payment UI
// Retry failed requests
retry: { maxRetries: 3, delay: 1000 },
// Cache GET responses
cache: { enabled: true, ttl: 60000 },
// Custom error messages
errorMessages: {
fetchTickets: "Could not load tickets",
submitForm: "Submission failed",
},
// Interceptors
interceptors: {
request: (config) => { /* modify request */ return config; },
response: (data) => { /* transform response */ return data; },
error: (err) => { /* handle error */ return err; },
},
});Client Methods
Tickets
// Fetch all tickets (with optional locale/name filter)
const tickets = await client.fetchTickets({ locale: "fr", name: "VIP" });
// Fetch a single ticket by ID
const ticket = await client.fetchTicketById(42);
// Fetch a public ticket (no auth required)
const publicTicket = await client.fetchPublicTicket(42, "en");Languages & Forms
// Fetch available languages
const languages = await client.fetchLanguages(); // ["en", "fr", "rw"]
// Fetch form schema for a ticket
const form = await client.fetchForm(ticketId, "en");File Uploads
// Two-step upload: authorize, then upload
const token = await client.authorizeUpload(formId, fieldId, file);
const fileUrl = await client.uploadFile(formId, token, file);Form Submission
const { submission, integrations } = await client.submitForm(
form,
formValues,
{
resourceId: ticketId,
attendanceType: "IN_PERSON", // "VIRTUAL" | "IN_PERSON" | "HYBRID"
containerId: "#payment-container", // CSS selector for payment UI
},
);
// submission: SubmissionResponse with id, formId, payment info, etc.
// integrations: IntegrationResult[] from any payment handlersLocale & Cache
client.setLocale("fr");
client.getLocale(); // "fr"
client.clearCache();Payment
// Preload the Mastercard checkout script before it's needed
await client.preloadCheckoutScript();FormStateManager
Manages form field values, dirty/touched tracking, visibility, and change subscriptions.
import { FormStateManager, getAllFields } from "@amalaika/form-sdk-package";
const fields = getAllFields(form.schema);
const state = new FormStateManager(fields);
// Get/set values
state.setValue("name", "Alice");
state.getValue("name"); // "Alice"
state.setValues({ name: "Alice", email: "[email protected]" });
state.getValues(); // { name: "Alice", email: "[email protected]" }
// Track user interaction
state.touchField("email");
state.isTouched("email"); // true
state.isDirty(); // true
state.getDirtyFields(); // Set(["name", "email"])
// Visibility-aware submission data (excludes hidden fields)
const data = state.getSubmissionData();
// Get visible field IDs based on conditional logic
const visible = state.getVisibleFieldIds();
// Resolve active payment integrations
const integrations = state.getActiveIntegrations();
// Subscribe to changes
const unsubscribe = state.onChange(({ fieldId, value, values }) => {
console.log(`${fieldId} changed to`, value);
});
// Reset to initial state
state.reset();Validation
import { validateField, validateForm, getAllFields } from "@amalaika/form-sdk-package";
// Validate a single field
const result = validateField(field, value);
// { valid: true } or { valid: false, error: "This field is required" }
// Validate all visible fields at once
const results = validateForm(fields, values);
// { fieldId: { valid: boolean, error?: string }, ... }Supports: required, minLength, maxLength, min, max, pattern, accept (file types), maxSize (file size).
Utility Functions
import {
getAllFields,
isFieldVisible,
getVisibleFieldIds,
hasIntegration,
getIntegrationMethod,
resolveIntegrations,
} from "@amalaika/form-sdk-package";
// Flatten fields from schema (handles flat and step-based layouts)
const fields = getAllFields(form.schema);
// Conditional visibility
const visible = isFieldVisible(field, formValues, allFields);
const visibleIds = getVisibleFieldIds(fields, formValues);
// Payment integrations
const hasPay = hasIntegration(field);
const method = getIntegrationMethod(field, "CARD"); // "mastercard_payment_gateway"
const active = resolveIntegrations(fields, formValues);Mastercard Payment Integration
The SDK handles Mastercard Hosted Checkout via an embedded page flow:
- Submit the form — the API returns a
paymentobject withsession_idandorder_id - The SDK loads the Mastercard checkout script and renders the embedded payment UI in a container element
- On successful payment, the SDK confirms the payment with the backend
- The result is returned as part of the
integrationsarray
// Provide a container element for the payment UI
const { submission, integrations } = await client.submitForm(form, values, {
resourceId: ticketId,
attendanceType: "IN_PERSON",
containerId: "#payment-container", // must exist in the DOM
});
// Check payment result
for (const result of integrations) {
if (result.success) {
// Payment completed
} else {
// result.error contains the error message
// result.data may contain additional details
}
}TypeScript
All types are exported:
import type {
EventFormConfig,
FormData,
FormSchema,
FieldDefinition,
FieldOption,
StepDefinition,
Ticket,
TicketTranslation,
ValidationResult,
SubmissionResponse,
PaymentInfo,
IntegrationResult,
ResolvedIntegration,
ApiResponse,
ErrorMessages,
} from "@amalaika/form-sdk-package";i18n
The SDK supports en, fr, and rw locales for error messages. Pass a locale to the client constructor or to individual methods:
const client = new EventFormClient({ apiKey: "...", resourceType: "ticketing", locale: "fr" });
// or per-request:
const tickets = await client.fetchTickets({ locale: "rw" });Build
The package ships ESM and CJS builds with TypeScript declarations:
npm run build # Build both ESM and CJS
npm test # Run tests (212 tests, 100% coverage)License
ISC
