@wallethero/sdk
Version:
TypeScript SDK for WalletHero API - manage pass templates and passes for Apple Wallet and Google Pay
1,605 lines (1,594 loc) • 54.2 kB
TypeScript
type PassType = "LOYALTY" | "GIFT_CARD" | "EVENT_TICKET" | "OFFER" | "GENERIC";
type BarcodeType = "none" | "qr" | "aztec" | "code128" | "pdf417";
interface PassField {
label: string;
value: string;
}
interface Location {
latitude: number;
longitude: number;
altitude?: number;
name?: string;
}
interface Workspace {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
name?: string;
slug: string;
}
interface Project {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
workspace_id: string;
name: string;
description?: string;
statistics?: ProjectStatistics;
}
interface PassTemplate {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
uuid: string;
name: string;
description?: string;
pass_type: PassType;
apple_pass_type_identifier: string;
workspace_id: string;
project_id: string;
tier_id?: string;
tier_label?: string;
icon?: string;
logo?: string;
cover_image?: string;
background_color?: string;
label_color?: string;
value_color?: string;
logo_text?: string;
barcode_id?: string;
barcode_type?: BarcodeType;
barcode_label?: string;
top_field_label?: string;
top_field_value?: string;
front_fields?: PassField[];
secondary_fields?: PassField[];
back_fields?: PassField[];
locations?: Location[];
location_message?: string;
ios_deeplink_id?: number;
ios_deeplink_url?: string;
statistics?: PassTemplateStatistics;
}
interface Pass {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
pass_template_id: string;
project_id: string;
workspace_id: string;
full_name?: string;
email?: string;
notification?: string;
marketing_consent?: boolean;
custom_fields?: Record<string, any>;
computed_metrics?: Record<string, number>;
apple_pass_url?: string;
apple_qrcode_url?: string;
google_pass_url?: string;
google_qrcode_url?: string;
}
type CreateProjectRequest = Omit<Project, "id" | "user_created" | "date_created" | "user_updated" | "date_updated" | "statistics">;
type UpdateProjectRequest = Partial<Omit<Project, "id" | "user_created" | "date_created" | "user_updated" | "date_updated" | "statistics">>;
type CreatePassTemplateRequest = Omit<PassTemplate, "id" | "user_created" | "date_created" | "user_updated" | "date_updated" | "statistics">;
type UpdatePassTemplateRequest = Partial<Omit<PassTemplate, "id" | "user_created" | "date_created" | "user_updated" | "date_updated" | "statistics">>;
type CreatePassRequest = {
pass_template_id: string;
project_id: string;
workspace_id: string;
full_name?: string;
email?: string;
notification?: string;
custom_fields?: Record<string, any>;
};
type UpdatePassRequest = Partial<Omit<Pass, "id" | "user_created" | "date_created" | "user_updated" | "date_updated">>;
type CreateWorkspaceRequest = Omit<Workspace, "id" | "user_created" | "date_created" | "user_updated" | "date_updated">;
type UpdateWorkspaceRequest = Partial<Omit<Workspace, "id" | "user_created" | "date_created" | "user_updated" | "date_updated">>;
interface ApiResponse<T> {
data: T;
}
interface ApiListResponse<T> {
data: T[];
meta?: {
total_count?: number;
filter_count?: number;
};
}
interface ApiError {
message: string;
extensions?: {
code?: string;
[key: string]: any;
};
}
interface QueryOptions {
fields?: string[];
filter?: Record<string, any>;
sort?: string[];
limit?: number;
offset?: number;
search?: string;
}
interface DirectusFile {
id: string;
storage: string;
filename_disk: string;
filename_download: string;
title?: string;
type: string;
folder?: string;
uploaded_by?: string;
uploaded_on: string;
modified_by?: string;
modified_on?: string;
charset?: string;
filesize: number;
width?: number;
height?: number;
duration?: number;
embed?: string;
description?: string;
location?: string;
tags?: string[];
metadata?: Record<string, any>;
}
interface FileUploadOptions {
title?: string;
description?: string;
folder?: string;
tags?: string[];
}
interface TemplateImageUpdate {
icon?: string | File | Blob;
logo?: string | File | Blob;
cover_image?: string | File | Blob;
}
interface IOSDeeplinkConfig {
ios_deeplink_id?: number;
ios_deeplink_url?: string;
}
interface WalletHeroConfig {
apiUrl?: string;
apiToken: string;
timeout?: number;
}
interface CompletePassData {
pass: Pass;
project: Project;
template: PassTemplate;
effectiveCustomFields: Record<string, any>;
}
interface PassTemplateStatistics {
apple_registrations_count: number;
google_registrations_count: number;
total_registrations_count: number;
passes_count: number;
}
interface ProjectStatistics {
templates_count: number;
apple_registrations_count: number;
google_registrations_count: number;
total_registrations_count: number;
passes_count: number;
}
type DistributionStatus = "published" | "draft";
type FormFieldType = "text" | "email" | "tel" | "checkbox";
interface FormFieldConfig {
enabled: boolean;
required: boolean;
label: string;
type: FormFieldType;
customFieldMapping?: string;
}
interface MarketingConsentConfig {
enabled: boolean;
required: boolean;
label: string;
}
interface FormFieldsConfig {
marketing_consent?: MarketingConsentConfig;
[key: string]: FormFieldConfig | MarketingConsentConfig | undefined;
}
interface Distribution {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
status: DistributionStatus;
workspace_id: string;
project_id: string;
pass_template_id: string;
page_address?: string;
landing_html?: string;
landing_html_success?: string;
email_html?: string;
email_reply_to?: string;
email_topic?: string;
css?: string;
setup_config?: Record<string, any>;
form_fields_config?: FormFieldsConfig;
}
type CreateDistributionRequest = Omit<Distribution, "id" | "user_created" | "date_created" | "user_updated" | "date_updated">;
type UpdateDistributionRequest = Partial<Omit<Distribution, "id" | "user_created" | "date_created" | "user_updated" | "date_updated">>;
interface FeatureFlag {
id: number;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
name: string;
enabled: boolean;
workspace_id: string;
}
type FeatureFlagName = string;
type FeatureFlagsMap = Record<string, boolean>;
type SegmentFilterType = "template" | "project" | "custom_field" | "event_count" | "event_sum" | "field_sum" | "event_recency";
type CustomFieldOperator = "_eq" | "_neq" | "_gt" | "_gte" | "_lt" | "_lte" | "_contains" | "_starts_with" | "_ends_with" | "_in" | "_nin" | "_null";
interface CustomFieldCondition {
operator: CustomFieldOperator;
value: string | number | boolean | string[] | null;
}
interface TemplateFilterConfig {
pass_template_ids: string[];
}
interface ProjectFilterConfig {
project_ids: string[];
}
interface CustomFieldFilterConfig {
custom_field_filters: Record<string, CustomFieldCondition>;
}
type EventCategory = "field_change" | "transaction" | "activity";
type TimeWindow = "day" | "week" | "month" | "quarter" | "year" | "all_time";
type ComparisonOperator = "_gt" | "_gte" | "_lt" | "_lte" | "_eq" | "_neq";
type RecencyOperator = "within_days" | "not_within_days" | "before_days";
interface EventCountFilterConfig {
event_category: EventCategory;
event_types?: string[];
operator: ComparisonOperator;
value: number;
time_window?: TimeWindow;
custom_days?: number;
from_date?: string;
to_date?: string;
}
interface EventSumFilterConfig {
event_category: "transaction";
event_types?: string[];
field: "amount";
operator: ComparisonOperator;
value: number;
time_window?: TimeWindow;
custom_days?: number;
from_date?: string;
to_date?: string;
}
interface FieldSumFilterConfig {
field_name: string;
event_types?: string[];
operator: ComparisonOperator;
value: number;
time_window?: TimeWindow;
custom_days?: number;
from_date?: string;
to_date?: string;
}
interface EventRecencyFilterConfig {
event_category: EventCategory;
event_types?: string[];
operator: RecencyOperator;
days: number;
}
type FilterConfig = TemplateFilterConfig | ProjectFilterConfig | CustomFieldFilterConfig | EventCountFilterConfig | EventSumFilterConfig | FieldSumFilterConfig | EventRecencyFilterConfig | Record<string, never>;
interface SegmentFilter {
id?: string;
filter_type: SegmentFilterType;
filter_config: FilterConfig;
}
interface Segment {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
workspace_id: string;
name: string;
description?: string;
filters: SegmentFilter[];
}
type CreateSegmentRequest = {
workspace_id: string;
name: string;
description?: string;
filters?: SegmentFilter[];
};
type UpdateSegmentRequest = {
name?: string;
description?: string;
filters?: SegmentFilter[];
};
interface SegmentSizeResult {
total: number;
}
interface TestFiltersResult {
total: number;
passes: Pass[];
computed_columns: string[];
}
interface CustomFieldValue {
value: string;
count: number;
isNumeric: boolean;
}
type CampaignStatus = "draft" | "scheduled" | "active" | "completed" | "cancelled";
type CampaignActionType = "push_notification" | "template_switch" | "custom_field_update";
type CampaignActionStatus = "pending" | "in_progress" | "completed" | "failed";
type CampaignPassStatus = "pending" | "processing" | "completed" | "failed";
interface Campaign {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
workspace_id: string;
name: string;
description?: string;
status: CampaignStatus;
scheduled_at?: string;
started_at?: string;
completed_at?: string;
segment_id?: string;
}
interface CampaignAction {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
campaign_id: string;
action_type: CampaignActionType;
status: CampaignActionStatus;
executed_at?: string;
action_config: Record<string, any>;
}
interface CampaignPass {
id: string;
campaign_id: string;
pass_id: string;
status: CampaignPassStatus;
error_message?: string;
processed_at?: string;
}
interface CampaignPassError {
id: string;
pass_id: string;
status: string;
error_message: string;
processed_at?: string;
full_name?: string;
email?: string;
}
interface CampaignEventsResult {
data: PassEvent[];
meta: {
total: number;
};
}
interface CampaignErrorsResult {
data: CampaignPassError[];
}
interface CampaignStatistics {
campaign_id: string;
status: CampaignStatus;
total_targeted: number;
passes_pending: number;
passes_processing: number;
passes_completed: number;
passes_failed: number;
actions_total: number;
actions_pending: number;
actions_completed: number;
actions_failed: number;
scheduled_at?: string;
started_at?: string;
completed_at?: string;
}
type CreateCampaignRequest = {
workspace_id: string;
name: string;
description?: string;
scheduled_at?: string;
segment_id?: string;
};
type UpdateCampaignRequest = Partial<Omit<Campaign, "id" | "user_created" | "date_created" | "user_updated" | "date_updated" | "workspace_id" | "status" | "started_at" | "completed_at">>;
interface PushNotificationConfig {
notification_message: string;
}
interface TemplateSwitchConfig {
target_template_id: string;
}
interface CustomFieldUpdateConfig {
custom_field_updates: Record<string, any>;
}
type ActionConfig = PushNotificationConfig | TemplateSwitchConfig | CustomFieldUpdateConfig;
interface CreateCampaignActionRequest {
action_type: CampaignActionType;
action_config: ActionConfig;
}
interface UpdateCampaignActionRequest {
action_config?: ActionConfig;
}
interface CampaignAudiencePreview {
passes: Pass[];
total: number;
}
interface CampaignCalendarOptions {
status?: CampaignStatus;
start?: string;
end?: string;
}
interface DuplicateCampaignOptions {
name?: string;
include_actions?: boolean;
}
type DataModelFieldType = "string" | "number" | "multiselect" | "date";
interface WorkspaceDataModelField {
id: string;
user_created?: string;
date_created?: string;
user_updated?: string;
date_updated?: string;
workspace_id: string;
field_name: string;
field_label: string;
field_type: DataModelFieldType;
default_value?: string | null;
allowed_values?: string[] | null;
is_required: boolean;
is_system: boolean;
sort_order: number;
}
interface WorkspaceDataModel {
workspace_id: string;
fields: WorkspaceDataModelField[];
}
type CreateDataModelFieldRequest = {
field_name: string;
field_label: string;
field_type: DataModelFieldType;
default_value?: string | null;
allowed_values?: string[] | null;
is_required?: boolean;
sort_order?: number;
};
type UpdateDataModelFieldRequest = Partial<CreateDataModelFieldRequest>;
interface DataModelValidationResult {
valid: boolean;
errors: string[];
}
type FieldChangeEventType = "field_updated" | "field_increment" | "field_decrement" | "template_changed";
type TransactionEventType = "purchase" | "refund" | "payment" | "charge" | "credit";
type ActivityEventType = "check_in" | "check_out" | "visit" | "scan" | "app_open" | "link_click" | "notification_received" | "notification_opened" | "pass_installed" | "pass_uninstalled" | "pass_registered" | "custom";
type EventType = FieldChangeEventType | TransactionEventType | ActivityEventType;
interface BaseEvent {
id: string;
user_created?: string;
date_created?: string;
workspace_id: string;
pass_id: string;
project_id?: string;
pass_template_id?: string;
event_category: EventCategory;
event_type: EventType;
event_timestamp: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}
interface FieldChangeEvent extends BaseEvent {
event_category: "field_change";
event_type: FieldChangeEventType;
field_name: string;
old_value?: string | null;
new_value?: string | null;
}
interface TransactionEvent extends BaseEvent {
event_category: "transaction";
event_type: TransactionEventType;
amount: number;
currency: string;
}
interface ActivityEvent extends BaseEvent {
event_category: "activity";
event_type: ActivityEventType;
}
type PassEvent = FieldChangeEvent | TransactionEvent | ActivityEvent;
interface CreateFieldChangeEventRequest {
pass_id: string;
event_type?: FieldChangeEventType;
field_name: string;
old_value?: string | null;
new_value?: string | null;
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}
interface CreateTransactionEventRequest {
pass_id: string;
event_type: TransactionEventType;
amount: number;
currency: string;
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}
interface CreateActivityEventRequest {
pass_id: string;
event_type: ActivityEventType;
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}
type CreateEventRequest = ({
event_category: "field_change";
} & CreateFieldChangeEventRequest) | ({
event_category: "transaction";
} & CreateTransactionEventRequest) | ({
event_category: "activity";
} & CreateActivityEventRequest);
type AggregationFunction = "count" | "sum" | "avg" | "min" | "max";
interface EventQuery {
workspace_id?: string;
pass_id?: string;
project_id?: string;
pass_template_id?: string;
event_category?: EventCategory;
event_types?: string[];
field_name?: string;
from_date?: string;
to_date?: string;
source?: string;
limit?: number;
offset?: number;
}
interface AggregationQuery {
workspace_id: string;
pass_ids?: string[];
function: AggregationFunction;
field?: "amount" | "points_delta";
event_category?: EventCategory;
event_types?: string[];
field_name?: string;
time_window?: TimeWindow;
custom_days?: number;
from_date?: string;
to_date?: string;
group_by_pass?: boolean;
}
interface AggregationResult {
value: number;
event_category?: EventCategory;
event_types?: string[];
time_window?: TimeWindow | string;
from_date?: string;
to_date?: string;
}
interface PassAggregationResult extends AggregationResult {
pass_id: string;
}
interface BatchCreateEventsResult {
created: number;
failed: number;
events: PassEvent[];
errors?: Array<{
index: number;
error: string;
}>;
}
interface EventListResult {
data: PassEvent[];
meta: {
total_count: number;
returned_count: number;
offset: number;
};
}
interface EventTypesByCategory {
category: EventCategory;
types: string[];
}
declare class WalletHeroError extends Error {
code?: string | undefined;
status?: number | undefined;
details?: any | undefined;
constructor(message: string, code?: string | undefined, status?: number | undefined, details?: any | undefined);
}
declare class HttpClient {
private baseUrl;
private token;
private timeout;
constructor(apiUrl: string, apiToken: string, timeout?: number);
get apiBaseUrl(): string;
get apiToken(): string;
private buildUrl;
private handleResponse;
get<T>(endpoint: string, options?: QueryOptions): Promise<T>;
post<T>(endpoint: string, data?: any): Promise<T>;
patch<T>(endpoint: string, data?: any): Promise<T>;
put<T>(endpoint: string, data?: any): Promise<T>;
delete<T>(endpoint: string, data?: any): Promise<T>;
}
declare class CampaignsService {
private http;
constructor(httpClient: HttpClient);
/**
* Get a list of campaigns
*/
list(options?: QueryOptions): Promise<ApiListResponse<Campaign>>;
/**
* Get a specific campaign by ID
*/
get(id: string, options?: QueryOptions): Promise<ApiResponse<Campaign>>;
/**
* Create a new campaign
*/
create(data: CreateCampaignRequest): Promise<ApiResponse<Campaign>>;
/**
* Update an existing campaign
*/
update(id: string, data: UpdateCampaignRequest): Promise<ApiResponse<Campaign>>;
/**
* Delete a campaign
*/
delete(id: string): Promise<void>;
/**
* Get campaigns by workspace
*/
getByWorkspace(workspaceId: string, options?: QueryOptions): Promise<ApiListResponse<Campaign>>;
/**
* Get campaigns by status
*/
getByStatus(status: CampaignStatus, options?: QueryOptions): Promise<ApiListResponse<Campaign>>;
/**
* Get campaigns for calendar view
*/
getCalendar(workspaceId: string, options?: CampaignCalendarOptions): Promise<Campaign[]>;
/**
* Schedule a campaign for future execution
*/
schedule(id: string, scheduledAt: string): Promise<Campaign>;
/**
* Start a campaign immediately (bypasses scheduling)
*/
startNow(id: string): Promise<Campaign>;
/**
* Complete a campaign
*/
complete(id: string): Promise<Campaign>;
/**
* Cancel a campaign
*/
cancel(id: string): Promise<Campaign>;
/**
* Preview campaign audience
*/
previewAudience(id: string, limit?: number): Promise<CampaignAudiencePreview>;
/**
* Count campaign audience
*/
countAudience(id: string): Promise<number>;
/**
* Get campaign statistics
*/
getStatistics(id: string): Promise<CampaignStatistics>;
/**
* Get campaign events (events logged during execution)
*/
getEvents(id: string, options?: {
limit?: number;
offset?: number;
}): Promise<CampaignEventsResult>;
/**
* Get campaign errors (failed passes with error details)
*/
getErrors(id: string): Promise<CampaignPassError[]>;
/**
* Get all campaign passes (affected users)
*/
getPasses(id: string, options?: {
limit?: number;
offset?: number;
}): Promise<{
data: CampaignPassError[];
meta: {
total: number;
};
}>;
/**
* Get all actions for a campaign
*/
getActions(campaignId: string): Promise<CampaignAction[]>;
/**
* Add an action to a campaign
*/
addAction(campaignId: string, action: CreateCampaignActionRequest): Promise<CampaignAction>;
/**
* Update a campaign action
*/
updateAction(actionId: string, data: UpdateCampaignActionRequest): Promise<CampaignAction>;
/**
* Delete a campaign action
*/
deleteAction(actionId: string): Promise<void>;
/**
* Execute a single action
*/
executeAction(actionId: string): Promise<CampaignAction>;
/**
* Execute all pending actions in a campaign
*/
executeAllActions(campaignId: string): Promise<CampaignAction[]>;
/**
* Add a push notification action
*/
addPushNotificationAction(campaignId: string, message: string): Promise<CampaignAction>;
/**
* Add a template switch action
*/
addTemplateSwitchAction(campaignId: string, targetTemplateId: string): Promise<CampaignAction>;
/**
* Add a custom field update action
*/
addCustomFieldUpdateAction(campaignId: string, fieldUpdates: Record<string, any>): Promise<CampaignAction>;
/**
* Duplicate a campaign
*/
duplicate(id: string, options?: DuplicateCampaignOptions): Promise<Campaign>;
/**
* Get draft campaigns
*/
getDrafts(options?: QueryOptions): Promise<ApiListResponse<Campaign>>;
/**
* Get scheduled campaigns
*/
getScheduled(options?: QueryOptions): Promise<ApiListResponse<Campaign>>;
/**
* Get active campaigns
*/
getActive(options?: QueryOptions): Promise<ApiListResponse<Campaign>>;
/**
* Get completed campaigns
*/
getCompleted(options?: QueryOptions): Promise<ApiListResponse<Campaign>>;
/**
* Assign a segment to a campaign
*/
assignSegment(campaignId: string, segmentId: string): Promise<Campaign>;
/**
* Remove segment from a campaign
*/
removeSegment(campaignId: string): Promise<Campaign>;
}
declare class DistributionsService {
private http;
constructor(httpClient: HttpClient);
/**
* Get a list of distributions
*/
list(options?: QueryOptions): Promise<ApiListResponse<Distribution>>;
/**
* Get a specific distribution by ID
*/
get(id: string, options?: QueryOptions): Promise<ApiResponse<Distribution>>;
/**
* Create a new distribution
*/
create(data: CreateDistributionRequest): Promise<ApiResponse<Distribution>>;
/**
* Update an existing distribution
*/
update(id: string, data: UpdateDistributionRequest): Promise<ApiResponse<Distribution>>;
/**
* Delete a distribution
*/
delete(id: string): Promise<void>;
/**
* Get distributions by workspace
*/
getByWorkspace(workspaceId: string, options?: QueryOptions): Promise<ApiListResponse<Distribution>>;
/**
* Get distributions by project
*/
getByProject(projectId: string, options?: QueryOptions): Promise<ApiListResponse<Distribution>>;
/**
* Get distributions by template
*/
getByTemplate(templateId: string, options?: QueryOptions): Promise<ApiListResponse<Distribution>>;
/**
* Get distributions by status
*/
getByStatus(status: "published" | "draft", options?: QueryOptions): Promise<ApiListResponse<Distribution>>;
/**
* Get a published distribution by page address
* Only returns published distributions (for public access)
* @param pageAddress - The page address to look up
* @param workspaceFilter - Optional workspace filter (slug or ID)
* @param options - Optional query options
*/
getByPageAddress(pageAddress: string, workspaceFilter?: {
workspaceSlug?: string;
workspaceId?: string;
}, options?: QueryOptions): Promise<ApiResponse<Distribution>>;
/**
* Search distributions by page address
*/
search(query: string, options?: QueryOptions): Promise<ApiListResponse<Distribution>>;
/**
* Publish a distribution (change status to published)
*/
publish(id: string): Promise<ApiResponse<Distribution>>;
/**
* Unpublish a distribution (change status to draft)
*/
unpublish(id: string): Promise<ApiResponse<Distribution>>;
/**
* Duplicate a distribution
* @param id - The ID of the distribution to duplicate
* @param options - Options for duplication
* @param options.newPageAddress - New page address (optional, defaults to same address for versioning)
* @param options.keepSameAddress - If true, keeps the same page_address (for versioning). Defaults to true.
*/
duplicate(id: string, options?: {
newPageAddress?: string;
keepSameAddress?: boolean;
}): Promise<ApiResponse<Distribution>>;
/**
* Get complete distribution data with related entities
*/
getComplete(id: string): Promise<ApiResponse<Distribution & {
project?: any;
pass_template?: any;
workspace?: any;
}>>;
/**
* Bulk update distributions
*/
bulkUpdate(updates: Array<{
id: string;
data: UpdateDistributionRequest;
}>): Promise<ApiListResponse<Distribution>>;
/**
* Bulk publish distributions
*/
bulkPublish(ids: string[]): Promise<ApiListResponse<Distribution>>;
/**
* Bulk unpublish distributions (set status to draft)
*/
bulkUnpublish(ids: string[]): Promise<ApiListResponse<Distribution>>;
}
declare class EventsService {
private http;
constructor(httpClient: HttpClient);
/**
* Create a single event
*/
create(data: CreateEventRequest): Promise<ApiResponse<PassEvent>>;
/**
* Create multiple events in batch (up to 1000)
*/
createBatch(events: CreateEventRequest[]): Promise<ApiResponse<BatchCreateEventsResult>>;
/**
* Get a single event by ID
*/
get(id: string): Promise<ApiResponse<PassEvent>>;
/**
* Delete multiple events by IDs
*/
deleteBatch(eventIds: string[], workspaceId: string): Promise<ApiResponse<{
deleted: number;
}>>;
/**
* List events with filters
*/
list(query: EventQuery): Promise<EventListResult>;
/**
* Get events for a specific pass
*/
getByPass(passId: string, options?: {
event_category?: EventCategory;
limit?: number;
offset?: number;
}): Promise<EventListResult>;
/**
* Aggregate events (count, sum, avg, min, max)
*/
aggregate(query: AggregationQuery): Promise<ApiResponse<AggregationResult>>;
/**
* Aggregate events grouped by pass
*/
aggregateByPass(query: Omit<AggregationQuery, "group_by_pass">): Promise<ApiResponse<PassAggregationResult[]>>;
/**
* Get distinct event types used in a workspace
*/
getEventTypes(workspaceId: string): Promise<ApiResponse<EventTypesByCategory[]>>;
/**
* Get distinct event sources in a workspace
*/
getSources(workspaceId: string): Promise<ApiResponse<string[]>>;
/**
* Record a purchase transaction
*/
recordPurchase(passId: string, amount: number, currency: string, options?: {
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Record a refund transaction
*/
recordRefund(passId: string, amount: number, currency: string, options?: {
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Record a custom transaction
*/
recordTransaction(passId: string, eventType: TransactionEventType, amount: number, currency: string, options?: {
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Record a check-in activity
*/
recordCheckIn(passId: string, options?: {
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Record a visit activity
*/
recordVisit(passId: string, options?: {
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Record a custom activity
*/
recordActivity(passId: string, eventType: ActivityEventType, options?: {
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Record a field change (e.g., points balance update)
*/
recordFieldChange(passId: string, fieldName: string, oldValue: string | null, newValue: string | null, options?: {
event_type?: FieldChangeEventType;
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Record points earned (increment)
*/
recordPointsEarned(passId: string, pointsFieldName: string, pointsEarned: number, currentBalance: number, options?: {
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Record points redeemed (decrement)
*/
recordPointsRedeemed(passId: string, pointsFieldName: string, pointsRedeemed: number, currentBalance: number, options?: {
event_timestamp?: string;
external_id?: string;
source?: string;
metadata?: Record<string, unknown>;
}): Promise<ApiResponse<PassEvent>>;
/**
* Get total transaction amount for a workspace
*/
getTotalTransactionAmount(workspaceId: string, options?: {
event_types?: TransactionEventType[];
time_window?: "day" | "week" | "month" | "quarter" | "year" | "all_time";
custom_days?: number;
}): Promise<number>;
/**
* Get event count for a workspace
*/
getEventCount(workspaceId: string, options?: {
event_category?: EventCategory;
event_types?: string[];
time_window?: "day" | "week" | "month" | "quarter" | "year" | "all_time";
custom_days?: number;
}): Promise<number>;
}
declare class FilesService {
private http;
constructor(httpClient: HttpClient);
/**
* Upload a file
*/
upload(file: File | Blob, options?: FileUploadOptions): Promise<ApiResponse<DirectusFile>>;
/**
* Get file information by ID
*/
get(id: string, options?: QueryOptions): Promise<ApiResponse<DirectusFile>>;
/**
* List files
*/
list(options?: QueryOptions): Promise<ApiListResponse<DirectusFile>>;
/**
* Delete a file
*/
delete(id: string): Promise<void>;
/**
* Update file metadata
*/
update(id: string, data: Partial<Pick<DirectusFile, "title" | "description" | "tags" | "folder">>): Promise<ApiResponse<DirectusFile>>;
/**
* Get file URL for download/display
*/
getFileUrl(id: string, options?: {
width?: number;
height?: number;
fit?: "cover" | "contain" | "inside" | "outside";
quality?: number;
format?: "jpg" | "png" | "webp" | "tiff";
}): string;
/**
* Upload image with automatic optimization for pass templates
*/
uploadPassImage(file: File | Blob, type: "icon" | "logo" | "cover_image", options?: Omit<FileUploadOptions, "folder">): Promise<ApiResponse<DirectusFile>>;
}
declare class PassTemplatesService {
private http;
private files;
constructor(httpClient: HttpClient);
/**
* Filter out fields that shouldn't be sent in update requests
*/
private filterUpdateData;
/**
* Get a list of pass templates
*/
list(options?: QueryOptions): Promise<ApiListResponse<PassTemplate>>;
/**
* Get a specific pass template by ID (UUID)
*/
get(id: string, options?: QueryOptions): Promise<ApiResponse<PassTemplate>>;
/**
* Create a new pass template
*/
create(data: CreatePassTemplateRequest): Promise<ApiResponse<PassTemplate>>;
/**
* Update an existing pass template
*/
update(id: string, data: UpdatePassTemplateRequest | Partial<PassTemplate>): Promise<ApiResponse<PassTemplate>>;
/**
* Delete a pass template
*/
delete(id: string): Promise<void>;
/**
* Get pass templates by workspace
*/
getByWorkspace(workspaceId: string, options?: QueryOptions): Promise<ApiListResponse<PassTemplate>>;
/**
* Get pass templates by project
*/
getByProject(projectId: string, options?: QueryOptions): Promise<ApiListResponse<PassTemplate>>;
/**
* Search pass templates by name
*/
search(query: string, options?: QueryOptions): Promise<ApiListResponse<PassTemplate>>;
/**
* Get pass templates by type
*/
getByType(passType: string, options?: QueryOptions): Promise<ApiListResponse<PassTemplate>>;
/**
* Duplicate a pass template
*/
duplicate(id: string): Promise<ApiResponse<PassTemplate>>;
/**
* Upload and set template images
*/
updateImages(id: string, images: TemplateImageUpdate): Promise<ApiResponse<PassTemplate>>;
/**
* Get image URLs for a template
*/
getImageUrls(template: PassTemplate): {
icon?: string;
logo?: string;
cover_image?: string;
};
/**
* Get optimized image URLs for different uses
*/
getOptimizedImageUrls(template: PassTemplate): {
icon?: {
small: string;
medium: string;
large: string;
};
logo?: {
small: string;
medium: string;
large: string;
};
cover_image?: {
small: string;
medium: string;
large: string;
};
};
/**
* Remove images from a template
*/
removeImages(id: string, imageTypes: Array<"icon" | "logo" | "cover_image">): Promise<ApiResponse<PassTemplate>>;
/**
* Upload icon image
*/
uploadIcon(id: string, file: File | Blob, _options?: {
title?: string;
description?: string;
}): Promise<ApiResponse<PassTemplate>>;
/**
* Upload logo image
*/
uploadLogo(id: string, file: File | Blob, _options?: {
title?: string;
description?: string;
}): Promise<ApiResponse<PassTemplate>>;
/**
* Upload cover image
*/
uploadCoverImage(id: string, file: File | Blob, _options?: {
title?: string;
description?: string;
}): Promise<ApiResponse<PassTemplate>>;
/**
* Set iOS deeplink configuration for a pass template
*/
setIOSDeeplink(id: string, deeplinkConfig: IOSDeeplinkConfig): Promise<ApiResponse<PassTemplate>>;
/**
* Remove iOS deeplink configuration from a pass template
*/
removeIOSDeeplink(id: string): Promise<ApiResponse<PassTemplate>>;
/**
* Get iOS deeplink configuration for a pass template
*/
getIOSDeeplink(id: string): Promise<IOSDeeplinkConfig>;
/**
* Get templates by tier
*/
getByTier(tierId: string, options?: QueryOptions): Promise<ApiListResponse<PassTemplate>>;
/**
* Set template tier
*/
setTier(id: string, tierId: string, tierLabel?: string): Promise<ApiResponse<PassTemplate>>;
/**
* Remove template tier
*/
removeTier(id: string): Promise<ApiResponse<PassTemplate>>;
}
declare class PassesService {
private http;
constructor(httpClient: HttpClient);
/**
* Get a list of passes
*/
list(options?: QueryOptions): Promise<ApiListResponse<Pass>>;
/**
* Get a specific pass by ID (UUID)
*/
get(id: string, options?: QueryOptions): Promise<ApiResponse<Pass>>;
/**
* Create a new pass
*/
create(data: CreatePassRequest): Promise<ApiResponse<Pass>>;
/**
* Update an existing pass
*/
update(id: string, data: UpdatePassRequest): Promise<ApiResponse<Pass>>;
/**
* Delete a pass
*/
delete(id: string): Promise<void>;
/**
* Get passes by workspace
*/
getByWorkspace(workspaceId: number, options?: QueryOptions): Promise<ApiListResponse<Pass>>;
/**
* Get passes by template
*/
getByTemplate(templateId: string, options?: QueryOptions): Promise<ApiListResponse<Pass>>;
/**
* Get passes by project
*/
getByProject(projectId: string, options?: QueryOptions): Promise<ApiListResponse<Pass>>;
/**
* Search passes by email or name
*/
search(query: string, options?: QueryOptions): Promise<ApiListResponse<Pass>>;
/**
* Send push notification to update a pass
*/
sendNotification(id: string, message?: string): Promise<void>;
/**
* Resend pass email to user
* @param passId - The pass ID (UUID string)
* @param emailTemplate - Optional custom email HTML template
* @param email - Optional email address override (if not provided, uses pass's email)
* @returns Object with pass URLs
*/
resendEmail(passId: string, emailTemplate?: string, email?: string): Promise<{
success: boolean;
message: string;
data: {
pass_id: string;
apple_pass_url: string;
google_pass_url: string;
};
}>;
/**
* Bulk create passes from template
*/
bulkCreateFromTemplate(templateId: string, passes: Array<Omit<CreatePassRequest, "pass_template_id">>): Promise<ApiListResponse<Pass>>;
/**
* Update pass custom fields (replaces the old updatePayload method)
*/
updateCustomFields(id: string, customFields: Record<string, any>): Promise<ApiResponse<Pass>>;
/**
* Get custom fields for a specific pass
*/
getCustomFields(id: string): Promise<Record<string, any>>;
/**
* Set a single custom field value
*/
setCustomField(id: string, fieldName: string, value: any): Promise<ApiResponse<Pass>>;
/**
* Get a single custom field value
*/
getCustomField(id: string, fieldName: string): Promise<any>;
/**
* Remove a custom field
*/
removeCustomField(id: string, fieldName: string): Promise<ApiResponse<Pass>>;
/**
* Merge custom fields (adds new fields without removing existing ones)
*/
mergeCustomFields(id: string, fieldsToMerge: Record<string, any>): Promise<ApiResponse<Pass>>;
/**
* Clear all custom fields
*/
clearCustomFields(id: string): Promise<ApiResponse<Pass>>;
/**
* Check if a custom field exists
*/
hasCustomField(id: string, fieldName: string): Promise<boolean>;
/**
* Get all custom field names for a pass
*/
getCustomFieldNames(id: string): Promise<string[]>;
/**
* Bulk update custom fields for multiple passes
*/
bulkUpdateCustomFields(updates: Array<{
passId: string;
customFields: Record<string, any>;
}>): Promise<ApiListResponse<Pass>>;
/**
* Search passes by custom field value
*/
searchByCustomField(fieldName: string, value: any, options?: QueryOptions): Promise<ApiListResponse<Pass>>;
/**
* Filter passes by multiple custom field criteria
*/
filterByCustomFields(criteria: Record<string, any>, options?: QueryOptions): Promise<ApiListResponse<Pass>>;
/**
* @deprecated Use updateCustomFields instead
* Update pass payload (custom data) - kept for backward compatibility
*/
updatePayload(id: string, payload: Record<string, any>): Promise<ApiResponse<Pass>>;
/**
* Switch pass to a different template within the same project
*/
switchTemplate(id: string, newTemplateId: string): Promise<ApiResponse<Pass>>;
/**
* Get complete pass data with template inheritance
*/
getCompleteData(id: string): Promise<any>;
/**
* Bulk switch passes to a different template within the same project
*/
bulkSwitchTemplate(passIds: string[], newTemplateId: string): Promise<ApiListResponse<Pass>>;
}
declare class ProjectsService {
private http;
constructor(httpClient: HttpClient);
/**
* Get a list of projects
*/
list(options?: QueryOptions): Promise<ApiListResponse<Project>>;
/**
* Get a specific project by ID (UUID)
*/
get(id: string, options?: QueryOptions): Promise<ApiResponse<Project>>;
/**
* Create a new project
*/
create(data: CreateProjectRequest): Promise<ApiResponse<Project>>;
/**
* Update an existing project
*/
update(id: string, data: UpdateProjectRequest): Promise<ApiResponse<Project>>;
/**
* Delete a project
*/
delete(id: string): Promise<void>;
/**
* Get projects by workspace
*/
getByWorkspace(workspaceId: string, options?: QueryOptions): Promise<ApiListResponse<Project>>;
/**
* Search projects by name
*/
search(query: string, options?: QueryOptions): Promise<ApiListResponse<Project>>;
/**
* Get all templates for a project
*/
getTemplates(projectId: string, options?: QueryOptions): Promise<ApiListResponse<PassTemplate>>;
/**
* Get all passes for a project
*/
getPasses(projectId: string, options?: QueryOptions): Promise<ApiListResponse<any>>;
/**
* Get complete pass data with template inheritance for a pass
*/
getCompletePassData(passId: string): Promise<ApiResponse<CompletePassData>>;
/**
* Get project statistics
*/
getStats(id: string): Promise<{
templateCount: number;
passCount: number;
}>;
/**
* Duplicate a project with all its templates
*/
duplicate(id: string, newName?: string): Promise<ApiResponse<Project>>;
}
interface QRCodeOptions {
width?: number;
margin?: number;
dark?: string;
light?: string;
format?: "png" | "json";
}
interface QRCodeResponse {
passId: string;
url: string;
qrCode: string;
format: string;
}
declare class QRCodeService {
private http;
constructor(httpClient: HttpClient);
/**
* Get pass data to retrieve QR code URLs
*/
private getPassData;
/**
* Private helper method to build QR code URL with query parameters
*/
private getQRCodeUrlForPassType;
/**
* Get QR code URL for Apple Pass
* Returns URL that can be used directly in img src or for JSON format
*/
getApplePassQRCode(passId: string, options?: QRCodeOptions): Promise<string | QRCodeResponse>;
/**
* Get QR code URL for Google Wallet Pass
* Returns URL that can be used directly in img src or for JSON format
*/
getGooglePassQRCode(passId: string, options?: QRCodeOptions): Promise<string | QRCodeResponse>;
/**
* Get Apple Pass URL for QR code generation from pass data
*/
getApplePassURL(passId: string): Promise<string>;
/**
* Get Google Wallet Pass URL for QR code generation from pass data
*/
getGooglePassURL(passId: string): Promise<string>;
}
declare class SegmentsService {
private http;
constructor(httpClient: HttpClient);
/**
* Get a list of segments
*/
list(options?: QueryOptions): Promise<ApiListResponse<Segment>>;
/**
* Get a specific segment by ID
*/
get(id: string, options?: QueryOptions): Promise<ApiResponse<Segment>>;
/**
* Create a new segment
*/
create(data: CreateSegmentRequest): Promise<ApiResponse<Segment>>;
/**
* Update an existing segment
*/
update(id: string, data: UpdateSegmentRequest): Promise<ApiResponse<Segment>>;
/**
* Delete a segment
*/
delete(id: string): Promise<void>;
/**
* Get segments by workspace
*/
getByWorkspace(workspaceId: string, options?: QueryOptions): Promise<ApiListResponse<Segment>>;
/**
* Calculate segment size (number of passes matching the segment criteria)
*/
calculateSize(id: string): Promise<SegmentSizeResult>;
/**
* Preview passes in a segment
*/
preview(id: string, limit?: number): Promise<Pass[]>;
/**
* Get all passes in a segment
*/
getPasses(id: string, limit?: number): Promise<Pass[]>;
/**
* Duplicate a segment
*/
duplicate(id: string, name?: string): Promise<Segment>;
/**
* Test filter configurations without creating a segment
*/
testFilters(workspaceId: string, filters: SegmentFilter[], limit?: number): Promise<TestFiltersResult>;
/**
* Get all unique custom field names used in passes for a workspace
* Useful for building dynamic filters based on actual data
*/
getCustomFieldNames(workspaceId: string): Promise<string[]>;
/**
* Get distinct values for a specific custom field in a workspace
* Returns values with counts and whether they appear to be numeric
*/
getCustomFieldValues(workspaceId: string, fieldName: string, limit?: number): Promise<CustomFieldValue[]>;
}
declare class WorkspacesService {
private http;
constructor(httpClient: HttpClient);
/**
* Get a list of workspaces
*/
list(options?: QueryOptions): Promise<ApiListResponse<Workspace>>;
/**
* Get a specific workspace by ID (UUID)
*/
get(id: string, options?: QueryOptions): Promise<ApiResponse<Workspace>>;
/**
* Create a new workspace
*/
create(data: CreateWorkspaceRequest): Promise<ApiResponse<Workspace>>;
/**
* Update an existing workspace
*/
update(id: string, data: UpdateWorkspaceRequest): Promise<ApiResponse<Workspace>>;
/**
* Delete a workspace (native Directus API)
* @deprecated Use deleteWorkspace() instead for proper permission checks
*/
delete(id: string): Promise<void>;
/**
* Delete a workspace with all related data (requires admin permission)
* Uses custom endpoint with proper permission validation
*/
deleteWorkspace(id: string): Promise<{
message: string;
workspace_id: string;
}>;
/**
* Clear all workspace data without deleting the workspace itself
* Useful for resetting a workspace before re-seeding
*/
clearWorkspace(id: string): Promise<{
message: string;
workspace_id: string;
}>;
/**
* Search workspaces by name
*/
search(query: string, options?: QueryOptions): Promise<ApiListResponse<Workspace>>;
/**
* Get workspaces by name (exact match)
*/
getByName(name: string, options?: QueryOptions): Promise<ApiListResponse<Workspace>>;
/**
* Get workspace with related data (passes, templates, etc.)
*/
getWithRelations(id: string, includeFields?: string[]): Promise<ApiResponse<Workspace>>;
/**
* Get workspace statistics
*/
getStats(id: string): Promise<{
passCount: number;
templateCount: number;
appleRegistrationCount: number;
googleRegistrationCount: number;
}>;
/**
* Get current user's workspaces
*/
getMy(options?: QueryOptions): Promise<ApiListResponse<Workspace>>;
/**
* Check if workspace name is available
*/
isNameAvailable(name: string): Promise<boolean>;
/**
* Get workspace members (requires junction table access)
*/
getMembers(id: string): Promise<ApiListResponse<any>>;
/**
* Add member to workspace
*/
addMember(workspaceId: string, userId: string): Promise<ApiResponse<any>>;
/**
* Remove member from workspace
*/
removeMember(workspaceId: string, userId: string): Promise<void>;
/**
* Get feature flags for a workspace
*/
getFeatureFlags(workspaceId: string): Promise<{
featureFlags: FeatureFlagsMap;
raw: FeatureFlag[];
}>;
/**
* Get workspace data model (custom fields schema)
*/
getDataModel(workspaceId: string): Promise<WorkspaceDataModel>;
/**
* Create a field in the workspace data model
*/
createDataModelField(workspaceId: string, field: CreateDataModelFieldRequest): Promise<WorkspaceDataModelField>;
/**
* Update a field in the workspace data model
*/
updateDataModelField(workspaceId: string, fieldId: string, field: UpdateDataModelFieldRequest): Promise<WorkspaceDataMode