@joai/sdk 4.6.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -220,6 +220,7 @@ type CheckoutSnapshot = {
220
220
  type GuestBuyer = {
221
221
  name: string;
222
222
  email: string;
223
+ phone?: string;
223
224
  };
224
225
  type CheckoutSnapshotRequest = {
225
226
  fulfillmentMethod: FulfillmentMethod;
@@ -290,6 +291,7 @@ type SubscriptionDelivery = {
290
291
  fulfillmentLocation?: {
291
292
  name: string;
292
293
  instructions: string | null;
294
+ address?: AddressSnapshot | null;
293
295
  } | null;
294
296
  }; //#endregion
295
297
  //#region src/wallet/types.d.ts
@@ -614,6 +616,7 @@ declare const NativeApps: {
614
616
  readonly Heartbeats: "heartbeats";
615
617
  readonly Wallets: "wallets";
616
618
  readonly Campaigns: "campaigns";
619
+ readonly Automations: "automations";
617
620
  readonly News: "news";
618
621
  readonly Sites: "sites";
619
622
  readonly Contracts: "contracts";
@@ -824,9 +827,10 @@ type AiCostsResponse = {
824
827
  }; //#endregion
825
828
  //#region src/billing/types.d.ts
826
829
  type TranslatableValue = Partial<Record<WarpLocale, string>>;
827
- type OrderStatus = 'pending' | 'completed' | 'delivered' | 'canceled';
830
+ type OrderStatus = 'pending' | 'confirmed' | 'processing' | 'shipped' | 'completed' | 'delivered' | 'canceled' | 'returned';
828
831
  type OrderSource = 'auto' | 'manual' | 'kiosk';
829
832
  type OrderType = 'order' | 'quote';
833
+ type OrderPriceMode = 'net' | 'gross';
830
834
  type SubscriptionStatus = 'active' | 'canceled' | 'past_due' | 'pending';
831
835
  type SubscriptionInterval = 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly';
832
836
  type PricingModel = 'free' | 'one-time' | 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | 'per-run';
@@ -1037,6 +1041,7 @@ type Order = {
1037
1041
  source: OrderSource | null;
1038
1042
  context: OrderContext | null;
1039
1043
  paymentMode: string | null;
1044
+ priceMode?: OrderPriceMode | null;
1040
1045
  linkVariationId: string | null;
1041
1046
  notes: string | null;
1042
1047
  fulfillmentMethod?: FulfillmentMethod | null;
@@ -1046,6 +1051,7 @@ type Order = {
1046
1051
  fulfillmentLocation?: {
1047
1052
  name: string;
1048
1053
  instructions?: string | null;
1054
+ address?: AddressSnapshot | null;
1049
1055
  } | null;
1050
1056
  shippingFee?: number;
1051
1057
  fulfillments?: Fulfillment[];
@@ -1898,6 +1904,120 @@ type AppointmentRequest = {
1898
1904
  configuration?: Configuration;
1899
1905
  createdAt: string;
1900
1906
  }; //#endregion
1907
+ //#region src/automation/types.d.ts
1908
+ type AutomationTriggerType = 'prop' | 'segment' | 'manual' | 'webhook';
1909
+ type AutomationActionType = 'wait' | 'halt' | 'warp' | 'branch';
1910
+ type AutomationEnrollmentStatus = 'active' | 'completed' | 'skipped';
1911
+ type AutomationSkipReason = 'pending_consent' | 'opted_out' | 'missing_channel' | 'automation_disabled' | 'already_completed';
1912
+ type AutomationTriggerConfig = {
1913
+ propKey?: string;
1914
+ propValue?: string | number | boolean;
1915
+ segmentId?: string;
1916
+ source?: string;
1917
+ trigger?: {
1918
+ event?: string;
1919
+ when?: Array<{
1920
+ path: string;
1921
+ operator: string;
1922
+ value?: unknown;
1923
+ }>;
1924
+ inputs?: Record<string, unknown>;
1925
+ };
1926
+ hookId?: string;
1927
+ };
1928
+ type AutomationActionConfig = {
1929
+ delayMinutes?: number;
1930
+ warpId?: string;
1931
+ inputs?: Record<string, unknown>;
1932
+ when?: Array<{
1933
+ path: string;
1934
+ operator: string;
1935
+ value?: unknown;
1936
+ }>;
1937
+ thenPosition?: number;
1938
+ elsePosition?: number;
1939
+ [key: string]: unknown;
1940
+ };
1941
+ type AutomationAction = {
1942
+ id: string;
1943
+ position: number;
1944
+ type: AutomationActionType;
1945
+ config: AutomationActionConfig;
1946
+ };
1947
+ type Automation = {
1948
+ id: string;
1949
+ name: string;
1950
+ triggerType: AutomationTriggerType;
1951
+ triggerConfig: AutomationTriggerConfig;
1952
+ enabled: boolean;
1953
+ agent: AgentSimple | null;
1954
+ actions?: AutomationAction[];
1955
+ activeEnrollmentsCount?: number;
1956
+ completedEnrollmentsCount?: number;
1957
+ skippedEnrollmentsCount?: number;
1958
+ erroredEnrollmentsCount?: number;
1959
+ createdAt: string;
1960
+ updatedAt: string;
1961
+ };
1962
+ type AutomationEnrollment = {
1963
+ id: string;
1964
+ automationId: string;
1965
+ contactId: string | null;
1966
+ contact?: {
1967
+ id: string;
1968
+ name: string | null;
1969
+ email: string | null;
1970
+ };
1971
+ status: AutomationEnrollmentStatus;
1972
+ currentPosition: number;
1973
+ enteredAt: string | null;
1974
+ eligibleAt: string | null;
1975
+ sentAt: string | null;
1976
+ completedAt: string | null;
1977
+ skippedAt: string | null;
1978
+ skipReason: AutomationSkipReason | null;
1979
+ error: string | null;
1980
+ createdAt: string;
1981
+ updatedAt: string;
1982
+ };
1983
+ type AutomationActionInput = {
1984
+ type: AutomationActionType;
1985
+ config?: AutomationActionConfig;
1986
+ };
1987
+ type AutomationCreatePayload = {
1988
+ name: string;
1989
+ triggerType: AutomationTriggerType;
1990
+ triggerConfig?: AutomationTriggerConfig;
1991
+ actions?: AutomationActionInput[];
1992
+ enabled?: boolean;
1993
+ agentId?: string;
1994
+ };
1995
+ type AutomationUpdatePayload = {
1996
+ name?: string;
1997
+ triggerType?: AutomationTriggerType;
1998
+ triggerConfig?: AutomationTriggerConfig;
1999
+ enabled?: boolean;
2000
+ agentId?: string | null;
2001
+ };
2002
+ type AutomationAudiencePreview = {
2003
+ count: number;
2004
+ total: number;
2005
+ sendable: number;
2006
+ willSkip: number;
2007
+ reasons: Record<'pending_consent' | 'opted_out' | 'missing_channel', number>;
2008
+ sampleContactIds: string[];
2009
+ channel: string | null;
2010
+ };
2011
+ type AutomationStats = {
2012
+ totalAutomations: number;
2013
+ enabledAutomations: number;
2014
+ activeEnrollments: number;
2015
+ emailsSent: number;
2016
+ completedEnrollments: number;
2017
+ erroredEnrollments: number;
2018
+ };
2019
+ type CampaignChannelId = 'email' | 'whatsapp' | 'sms' | 'push';
2020
+ //#endregion
1901
2021
  //#region src/content/types.d.ts
1902
2022
  type ContentStatus = 'draft' | 'published' | 'archived';
1903
2023
  type ContentFieldType = 'text' | 'richText' | 'number' | 'boolean' | 'url' | 'image' | 'media' | 'list' | 'object' | 'reference';
@@ -1957,7 +2077,7 @@ type PatchContentInput = {
1957
2077
  patches: ContentPatch[];
1958
2078
  origin?: 'api' | 'inlineEditor' | 'joai' | 'mcp';
1959
2079
  }; //#endregion
1960
- //#region src/commerce/helpers.d.ts
2080
+ //#region src/address/formatAddressSnapshot.d.ts
1961
2081
  //#endregion
1962
2082
  //#region src/card/types.d.ts
1963
2083
  type Card = {
@@ -2793,6 +2913,8 @@ type SiteAgent = {
2793
2913
  type Site = {
2794
2914
  id: number;
2795
2915
  slug: string;
2916
+ name: string | null;
2917
+ url: string | null;
2796
2918
  brandSlug: string | null;
2797
2919
  customDomain: string | null;
2798
2920
  enabled: boolean;
@@ -3019,7 +3141,7 @@ type SegmentCountResult = {
3019
3141
  reachable: number | null;
3020
3142
  }; //#endregion
3021
3143
  //#region src/campaign/types.d.ts
3022
- type CampaignChannel = 'email' | 'whatsapp' | 'sms' | 'push';
3144
+ type CampaignChannel = CampaignChannelId;
3023
3145
  type CampaignStatus = 'draft' | 'pending' | 'approved' | 'rejected' | 'scheduled' | 'sending' | 'completed' | 'failed';
3024
3146
  type CampaignCategory = 'MARKETING' | 'UTILITY' | 'AUTHENTICATION';
3025
3147
  type CampaignSkipReason = 'pending_consent' | 'opted_out' | 'missing_channel' | 'approval_skipped';
@@ -3240,10 +3362,10 @@ type HookTriggerCondition = {
3240
3362
  value?: unknown;
3241
3363
  };
3242
3364
  type HookTriggerInput = string | {
3243
- source: 'payload';
3365
+ source: 'payload' | 'contact' | 'enrollment';
3244
3366
  path: string;
3245
3367
  } | {
3246
- source: 'literal';
3368
+ source: 'literal' | 'static';
3247
3369
  value: unknown;
3248
3370
  };
3249
3371
  type HookTrigger = {
@@ -3525,6 +3647,103 @@ declare function createGuestCommerceStorage(options: GuestCommerceStorageOptions
3525
3647
  listOrderAccess(): GuestOrderAccess[];
3526
3648
  };
3527
3649
  //#endregion
3650
+ //#region src/commerce/guestCheckout.d.ts
3651
+ type GuestCheckoutCartItem = {
3652
+ id: string;
3653
+ type: 'product' | 'service' | 'coupon';
3654
+ quantity: number;
3655
+ };
3656
+ type GuestCheckoutState<TCart = GuestCheckoutCartItem[]> = GuestCheckoutDraft<TCart> & {
3657
+ identity: GuestBuyer;
3658
+ address: AddressInput;
3659
+ };
3660
+ type GuestCheckoutErrorCode = 'empty_cart' | 'missing_identity' | 'missing_pickup_phone' | 'incomplete_shipping_address' | 'pickup_unavailable' | 'missing_shipping_rate' | 'rates_failed' | 'snapshot_failed' | 'review_required' | 'terms_required' | 'review_expired' | 'order_failed' | 'payment_failed';
3661
+ declare class GuestCheckoutError extends Error {
3662
+ readonly code: GuestCheckoutErrorCode;
3663
+ constructor(code: GuestCheckoutErrorCode);
3664
+ }
3665
+ type GuestCheckoutClient = {
3666
+ commerce: {
3667
+ checkout: {
3668
+ shippingRates(team: string, data: {
3669
+ address: {
3670
+ country: string;
3671
+ zipCode?: string;
3672
+ };
3673
+ items: GuestCheckoutCartItem[];
3674
+ }): Promise<IAppResponse<ShippingRate[]>>;
3675
+ snapshot(team: string, data: CheckoutSnapshotRequest): Promise<IAppResponse<CheckoutSnapshot>>;
3676
+ };
3677
+ };
3678
+ orders: {
3679
+ create(data: {
3680
+ team: string;
3681
+ snapshotId?: string;
3682
+ snapshotAccessToken?: string;
3683
+ guest?: GuestBuyer;
3684
+ idempotencyKey?: string;
3685
+ notes?: string;
3686
+ sendConfirmation?: boolean;
3687
+ }): Promise<IAppResponse<Order>>;
3688
+ pay(id: string, provider?: PaymentProvider, accessToken?: string): Promise<IAppResponse<{
3689
+ url: string;
3690
+ }>>;
3691
+ };
3692
+ };
3693
+ type CreateEmptyGuestCheckoutOptions = {
3694
+ country?: string;
3695
+ fulfillmentMethod?: FulfillmentMethod;
3696
+ };
3697
+ declare const createEmptyGuestCheckoutState: <TCart = GuestCheckoutCartItem[]>(options?: CreateEmptyGuestCheckoutOptions) => GuestCheckoutState<TCart>;
3698
+ declare const toGuestCheckoutDraft: <TCart>(state: GuestCheckoutState<TCart>) => GuestCheckoutDraft<TCart>;
3699
+ declare const assertGuestCheckoutReady: (state: GuestCheckoutState, pickupLocationIds?: number[]) => void;
3700
+ declare const buildGuestCheckoutSnapshotRequest: (state: GuestCheckoutState, options?: {
3701
+ shippingRates?: ShippingRate[];
3702
+ pickupLocationIds?: number[];
3703
+ }) => CheckoutSnapshotRequest;
3704
+ type GuestCheckoutSnapshotResult = {
3705
+ snapshot: CheckoutSnapshot & {
3706
+ accessToken: string;
3707
+ };
3708
+ shippingRates: ShippingRate[];
3709
+ shippingRateId: number | null;
3710
+ };
3711
+ declare function createGuestCheckoutSnapshot(options: {
3712
+ client: GuestCheckoutClient;
3713
+ team: string;
3714
+ state: GuestCheckoutState;
3715
+ pickupLocationIds?: number[];
3716
+ shippingRates?: ShippingRate[];
3717
+ }): Promise<GuestCheckoutSnapshotResult>;
3718
+ type PlaceGuestCheckoutOrderResult = {
3719
+ order: Order;
3720
+ accessToken: string | null; /** Payment provider redirect URL from `orders.pay`. Never the JoAi thank-you page. */
3721
+ paymentUrl: string | null;
3722
+ };
3723
+ /**
3724
+ * Places a guest order from a checkout snapshot and optionally starts payment.
3725
+ *
3726
+ * The client must already carry team context (e.g. `createClient({ team })` → `X-Team`).
3727
+ * Body `team` alone is not enough for `orders.create`.
3728
+ *
3729
+ * When `pay` is enabled (default), `paymentUrl` is only set from a successful `orders.pay`
3730
+ * response. `order.paymentUrl` from create is the JoAi thank-you URL and must not be used
3731
+ * as a gateway redirect.
3732
+ */
3733
+ declare function placeGuestCheckoutOrder(options: {
3734
+ client: GuestCheckoutClient;
3735
+ team: string;
3736
+ snapshot: Pick<CheckoutSnapshot, 'id' | 'expiresAt'> & {
3737
+ accessToken: string;
3738
+ };
3739
+ guest: GuestBuyer;
3740
+ acceptedTerms?: boolean;
3741
+ notes?: string;
3742
+ idempotencyKey?: string;
3743
+ pay?: boolean;
3744
+ }): Promise<PlaceGuestCheckoutOrderResult>;
3745
+ declare const isGuestCheckoutError: (error: unknown) => error is GuestCheckoutError;
3746
+ //#endregion
3528
3747
  //#region src/commerce/index.d.ts
3529
3748
  declare class CommerceResource {
3530
3749
  readonly checkout: CheckoutResource;
@@ -4481,7 +4700,7 @@ declare class OrdersResource {
4481
4700
  source?: 'kiosk';
4482
4701
  context?: OrderContext;
4483
4702
  linkVariationId?: string;
4484
- priceMode?: string;
4703
+ priceMode?: OrderPriceMode;
4485
4704
  type?: OrderType;
4486
4705
  sendConfirmation?: boolean;
4487
4706
  invoiceDate?: string;
@@ -4507,6 +4726,7 @@ declare class OrdersResource {
4507
4726
  guest?: {
4508
4727
  name: string;
4509
4728
  email: string;
4729
+ phone?: string;
4510
4730
  };
4511
4731
  }): Promise<IAppResponse<Order>>;
4512
4732
  update(id: string, data: {
@@ -4515,6 +4735,7 @@ declare class OrdersResource {
4515
4735
  serviceDate?: string;
4516
4736
  type?: OrderType;
4517
4737
  invoiceContactId?: string | null;
4738
+ priceMode?: OrderPriceMode;
4518
4739
  }): Promise<IAppResponse<Order>>;
4519
4740
  convertToOrder(id: string): Promise<IAppResponse<Order>>;
4520
4741
  delete(id: string): Promise<IAppResponse<void>>;
@@ -4719,10 +4940,13 @@ declare class SitesResource {
4719
4940
  constructor(http: IHttpService);
4720
4941
  brands(): Promise<IAppResponse<SiteBrand[]>>;
4721
4942
  listMine(teamSlug: string): Promise<IAppResponse<Site[]>>;
4722
- create(teamSlug: string, slug: string, data?: {
4943
+ create(teamSlug: string, data: {
4944
+ name: string;
4945
+ url?: string | null;
4723
4946
  contactId?: string | null;
4724
4947
  metricsSource?: string | null;
4725
4948
  metricsResource?: string | null;
4949
+ monthlyReport?: boolean;
4726
4950
  }): Promise<IAppResponse<Site>>;
4727
4951
  provision(teamSlug: string, brandSlug: string, data?: {
4728
4952
  settings?: Record<string, unknown>;
@@ -4733,6 +4957,8 @@ declare class SitesResource {
4733
4957
  customDomain?: string | null;
4734
4958
  enabled?: boolean;
4735
4959
  modules?: string[];
4960
+ name?: string | null;
4961
+ url?: string | null;
4736
4962
  contactId?: string | null;
4737
4963
  metricsSource?: string | null;
4738
4964
  metricsResource?: string | null;
@@ -4990,6 +5216,28 @@ declare class CampaignsResource {
4990
5216
  delete(id: string): Promise<IAppResponse<void>>;
4991
5217
  }
4992
5218
  //#endregion
5219
+ //#region src/resources/automations.d.ts
5220
+ declare class AutomationsResource {
5221
+ private readonly http;
5222
+ constructor(http: IHttpService);
5223
+ list(): Promise<IAppResponse<Automation[]>>;
5224
+ stats(): Promise<IAppResponse<AutomationStats>>;
5225
+ get(id: string): Promise<IAppResponse<Automation>>;
5226
+ create(payload: AutomationCreatePayload): Promise<IAppResponse<Automation>>;
5227
+ update(id: string, payload: AutomationUpdatePayload): Promise<IAppResponse<Automation>>;
5228
+ setActions(id: string, actions: AutomationActionInput[]): Promise<IAppResponse<Automation>>;
5229
+ delete(id: string): Promise<IAppResponse<void>>;
5230
+ enrollments(id: string, params?: {
5231
+ page?: number;
5232
+ perPage?: number;
5233
+ }): Promise<IAppResponse<AutomationEnrollment[]>>;
5234
+ run(id: string, payload: {
5235
+ contactId: string;
5236
+ }): Promise<IAppResponse<AutomationEnrollment>>;
5237
+ retryEnrollment(id: string, enrollmentId: string): Promise<IAppResponse<AutomationEnrollment>>;
5238
+ previewAudience(id: string): Promise<IAppResponse<AutomationAudiencePreview>>;
5239
+ }
5240
+ //#endregion
4993
5241
  //#region src/resources/segments.d.ts
4994
5242
  declare class SegmentsResource {
4995
5243
  private readonly http;
@@ -5017,6 +5265,9 @@ declare class UpdatesResource {
5017
5265
  tags?: string;
5018
5266
  with?: UpdateRelation[];
5019
5267
  sort?: string;
5268
+ limit?: number;
5269
+ upcoming?: boolean;
5270
+ past?: boolean;
5020
5271
  }): Promise<IAppResponse<Update[]>>;
5021
5272
  create(payload: UpdateCreatePayload): Promise<IAppResponse<Update>>;
5022
5273
  update(id: string, payload: UpdateUpdatePayload): Promise<IAppResponse<Update>>;
@@ -5322,6 +5573,7 @@ declare class JoAiClient {
5322
5573
  readonly teams: TeamsResource;
5323
5574
  readonly artifacts: ArtifactsResource;
5324
5575
  readonly campaigns: CampaignsResource;
5576
+ readonly automations: AutomationsResource;
5325
5577
  readonly segments: SegmentsResource;
5326
5578
  readonly updates: UpdatesResource;
5327
5579
  readonly upgrades: UpgradesResource;
@@ -5401,4 +5653,4 @@ declare class DistributionResource {
5401
5653
  private fetchDistribution;
5402
5654
  }
5403
5655
  //#endregion
5404
- export { AddressesResource, AgentsResource, AlertsResource, ApiTokensResource, AppointmentsResource, type AttachedMedia, type AuthConfirmCodeRequest, type AuthConfirmCodeResponse, type AuthNativeSessionResponse, type AuthPortalSessionResponse, AuthResource, type AuthSendCodeRequest, type BackendWarp, type BackendWarpBrand, BillingResource, BlueprintsResource, type CacheConfig, CachedHttpService, CampaignsResource, CardsResource, CartsResource, ChangelogResource, CharactersResource, CheckoutResource, CommerceResource, ContactsResource, ContentResource, ContractsResource, type CreateHookPayload, type CreateInboundHookPayload, type CreateInternalHookPayload, type CreateWarpLinkedHookPayload, type CreateWebHookPayload, DeskResource, DistributionResource, DocumentsResource, ElementsResource, EntitiesResource, FlowsResource, type FulfillmentLocationInput, FulfillmentsResource, GoalsResource, type GuestBuyer, type GuestCheckoutDraft, type GuestCommerceStorageOptions, type GuestOrderAccess, type Hook, type HookSample, type HookTrigger, type HookTriggerCondition, type HookTriggerInput, HooksResource, IngestionsResource, InquiriesResource, IntegrationsResource, IntentsResource, ItemsResource, JoAiClient, type JoAiClientConfig, KvResource, LinksResource, LoyaltyResource, McpResource, type MediaUploadType, MeetingsResource, MemoriesResource, MessagesResource, MetricsResource, MissionsResource, NotificationsResource, OfficeResource, type OpenPortalSessionOptions, type OpeningHoursEntry, type OpeningHoursFormatOptions, OrdersResource, PersonaResource, type PlaceCheckoutOrderRequest, type Product, type ProductVariation, ProductsResource, ProjectsResource, RemindersResource, ReturnsResource, SegmentsResource, ServicesResource, type ShippingRateInput, ShippingResource, type ShippingZoneInput, ShortcutsResource, SitesResource, SkillsResource, StatsResource, StoreResource, SubscriptionsResource, SwarmsResource, TagsResource, TasksResource, type TeamInviteInfo, TeamsResource, UpdatesResource, UpgradesResource, UsersResource, VoiceResource, WalletsResource, WarpsResource, type WebHookTriggerEvent, WorkspaceResource, completePortalSession, createClient, createGuestCommerceStorage, formatOpeningHours, getAuthFragmentToken, isAllowedRedirectUrl, isPortalCallbackUrl, openPortalSession, sanitizePortalCallbackUrl };
5656
+ export { AddressesResource, AgentsResource, AlertsResource, ApiTokensResource, AppointmentsResource, type AttachedMedia, type AuthConfirmCodeRequest, type AuthConfirmCodeResponse, type AuthNativeSessionResponse, type AuthPortalSessionResponse, AuthResource, type AuthSendCodeRequest, AutomationsResource, type BackendWarp, type BackendWarpBrand, BillingResource, BlueprintsResource, type CacheConfig, CachedHttpService, CampaignsResource, CardsResource, CartsResource, ChangelogResource, CharactersResource, CheckoutResource, CommerceResource, ContactsResource, ContentResource, ContractsResource, type CreateEmptyGuestCheckoutOptions, type CreateHookPayload, type CreateInboundHookPayload, type CreateInternalHookPayload, type CreateWarpLinkedHookPayload, type CreateWebHookPayload, DeskResource, DistributionResource, DocumentsResource, ElementsResource, EntitiesResource, FlowsResource, type FulfillmentLocationInput, FulfillmentsResource, GoalsResource, type GuestBuyer, type GuestCheckoutCartItem, type GuestCheckoutClient, type GuestCheckoutDraft, GuestCheckoutError, type GuestCheckoutErrorCode, type GuestCheckoutSnapshotResult, type GuestCheckoutState, type GuestCommerceStorageOptions, type GuestOrderAccess, type Hook, type HookSample, type HookTrigger, type HookTriggerCondition, type HookTriggerInput, HooksResource, IngestionsResource, InquiriesResource, IntegrationsResource, IntentsResource, ItemsResource, JoAiClient, type JoAiClientConfig, KvResource, LinksResource, LoyaltyResource, McpResource, type MediaUploadType, MeetingsResource, MemoriesResource, MessagesResource, MetricsResource, MissionsResource, NotificationsResource, OfficeResource, type OpenPortalSessionOptions, type OpeningHoursEntry, type OpeningHoursFormatOptions, OrdersResource, PersonaResource, type PlaceCheckoutOrderRequest, type PlaceGuestCheckoutOrderResult, type Product, type ProductVariation, ProductsResource, ProjectsResource, RemindersResource, ReturnsResource, SegmentsResource, ServicesResource, type ShippingRateInput, ShippingResource, type ShippingZoneInput, ShortcutsResource, SitesResource, SkillsResource, StatsResource, StoreResource, SubscriptionsResource, SwarmsResource, TagsResource, TasksResource, type TeamInviteInfo, TeamsResource, UpdatesResource, UpgradesResource, UsersResource, VoiceResource, WalletsResource, WarpsResource, type WebHookTriggerEvent, WorkspaceResource, assertGuestCheckoutReady, buildGuestCheckoutSnapshotRequest, completePortalSession, createClient, createEmptyGuestCheckoutState, createGuestCheckoutSnapshot, createGuestCommerceStorage, formatOpeningHours, getAuthFragmentToken, isAllowedRedirectUrl, isGuestCheckoutError, isPortalCallbackUrl, openPortalSession, placeGuestCheckoutOrder, sanitizePortalCallbackUrl, toGuestCheckoutDraft };
package/dist/index.mjs CHANGED
@@ -110,6 +110,37 @@ var HttpService = class {
110
110
  };
111
111
  }
112
112
  };
113
+ const OUTBOUND_CHANNELS = [
114
+ {
115
+ id: "email",
116
+ supportsHtml: true,
117
+ requiresSubject: true,
118
+ settingsKey: "email_provider"
119
+ },
120
+ {
121
+ id: "whatsapp",
122
+ supportsHtml: false,
123
+ requiresSubject: false
124
+ },
125
+ {
126
+ id: "whatsapp-personal",
127
+ supportsHtml: false,
128
+ requiresSubject: false
129
+ },
130
+ {
131
+ id: "sms",
132
+ supportsHtml: false,
133
+ requiresSubject: false
134
+ },
135
+ {
136
+ id: "push",
137
+ supportsHtml: false,
138
+ requiresSubject: true
139
+ }
140
+ ];
141
+ const AUTOMATION_SEND_CHANNELS = OUTBOUND_CHANNELS.filter((channel) => channel.id === "email" || channel.id === "whatsapp-personal");
142
+ OUTBOUND_CHANNELS.map((channel) => channel.id).filter((id) => id !== "whatsapp-personal");
143
+ AUTOMATION_SEND_CHANNELS[0];
113
144
  Object.values({
114
145
  Billing: "billing",
115
146
  Shipping: "shipping"
@@ -138,6 +169,7 @@ Object.values({
138
169
  Received: "received",
139
170
  Closed: "closed"
140
171
  });
172
+ const isCompleteAddressInput = (address) => Boolean(address.name.trim() && address.addressOne.trim() && address.city.trim() && address.zipCode.trim() && address.country.trim());
141
173
  Object.values({
142
174
  Board: "board",
143
175
  Shop: "shop",
@@ -151,6 +183,7 @@ Object.values({
151
183
  Heartbeats: "heartbeats",
152
184
  Wallets: "wallets",
153
185
  Campaigns: "campaigns",
186
+ Automations: "automations",
154
187
  News: "news",
155
188
  Sites: "sites",
156
189
  Contracts: "contracts",
@@ -505,6 +538,171 @@ function createGuestCommerceStorage(options) {
505
538
  };
506
539
  }
507
540
  //#endregion
541
+ //#region src/commerce/guestCheckout.ts
542
+ var GuestCheckoutError = class extends Error {
543
+ constructor(code) {
544
+ super(code);
545
+ this.code = code;
546
+ this.name = "GuestCheckoutError";
547
+ }
548
+ };
549
+ const createEmptyGuestCheckoutState = (options = {}) => ({
550
+ cart: [],
551
+ identity: {
552
+ name: "",
553
+ email: "",
554
+ phone: ""
555
+ },
556
+ fulfillmentMethod: options.fulfillmentMethod ?? "shipping",
557
+ address: {
558
+ name: "",
559
+ addressOne: "",
560
+ city: "",
561
+ zipCode: "",
562
+ country: options.country ?? "AT",
563
+ phone: ""
564
+ },
565
+ shippingRateId: null,
566
+ fulfillmentLocationId: null
567
+ });
568
+ const toGuestCheckoutDraft = (state) => ({
569
+ cart: state.cart,
570
+ fulfillmentMethod: state.fulfillmentMethod,
571
+ shippingRateId: state.shippingRateId,
572
+ fulfillmentLocationId: state.fulfillmentLocationId
573
+ });
574
+ const assertGuestCheckoutReady = (state, pickupLocationIds = []) => {
575
+ if (!state.cart.length) throw new GuestCheckoutError("empty_cart");
576
+ if (!state.identity.name.trim() || !state.identity.email.trim()) throw new GuestCheckoutError("missing_identity");
577
+ if (state.fulfillmentMethod === "pickup" && !state.identity.phone?.trim()) throw new GuestCheckoutError("missing_pickup_phone");
578
+ const address = {
579
+ ...state.address,
580
+ name: state.identity.name
581
+ };
582
+ if (state.fulfillmentMethod === "shipping" && !isCompleteAddressInput(address)) throw new GuestCheckoutError("incomplete_shipping_address");
583
+ if (state.fulfillmentMethod === "pickup" && !state.fulfillmentLocationId && !pickupLocationIds[0]) throw new GuestCheckoutError("pickup_unavailable");
584
+ };
585
+ const buildGuestCheckoutSnapshotRequest = (state, options = {}) => {
586
+ assertGuestCheckoutReady(state, options.pickupLocationIds ?? []);
587
+ const items = state.cart.map(({ id, type, quantity }) => ({
588
+ id,
589
+ type,
590
+ quantity
591
+ }));
592
+ const address = {
593
+ ...state.address,
594
+ name: state.identity.name
595
+ };
596
+ if (state.fulfillmentMethod === "shipping") {
597
+ const rates = options.shippingRates ?? [];
598
+ const rate = state.shippingRateId == null ? rates[0] : rates.find((item) => item.id === state.shippingRateId);
599
+ if (!rate) throw new GuestCheckoutError("missing_shipping_rate");
600
+ return {
601
+ fulfillmentMethod: "shipping",
602
+ items,
603
+ billingAddress: {
604
+ ...address,
605
+ type: "billing"
606
+ },
607
+ shippingAddress: {
608
+ ...address,
609
+ type: "shipping"
610
+ },
611
+ shippingRateId: rate.id
612
+ };
613
+ }
614
+ return {
615
+ fulfillmentMethod: "pickup",
616
+ items,
617
+ fulfillmentLocationId: state.fulfillmentLocationId || options.pickupLocationIds?.[0] || null
618
+ };
619
+ };
620
+ async function createGuestCheckoutSnapshot(options) {
621
+ const { client, team, state } = options;
622
+ const items = state.cart.map(({ id, type, quantity }) => ({
623
+ id,
624
+ type,
625
+ quantity
626
+ }));
627
+ let shippingRates = options.shippingRates ?? [];
628
+ if (state.fulfillmentMethod === "shipping" && !options.shippingRates) {
629
+ const address = {
630
+ ...state.address,
631
+ name: state.identity.name
632
+ };
633
+ const ratesResponse = await client.commerce.checkout.shippingRates(team, {
634
+ address: {
635
+ country: address.country,
636
+ zipCode: address.zipCode
637
+ },
638
+ items
639
+ });
640
+ if (!ratesResponse.ok || !Array.isArray(ratesResponse.data)) throw new GuestCheckoutError("rates_failed");
641
+ shippingRates = ratesResponse.data;
642
+ }
643
+ const snapshotRequest = buildGuestCheckoutSnapshotRequest(state, {
644
+ shippingRates,
645
+ pickupLocationIds: options.pickupLocationIds
646
+ });
647
+ const snapshot = await client.commerce.checkout.snapshot(team, snapshotRequest);
648
+ if (!snapshot.ok || !snapshot.data?.id || !snapshot.data.accessToken) throw new GuestCheckoutError("snapshot_failed");
649
+ return {
650
+ snapshot: {
651
+ ...snapshot.data,
652
+ accessToken: snapshot.data.accessToken
653
+ },
654
+ shippingRates,
655
+ shippingRateId: typeof snapshotRequest.shippingRateId === "number" ? snapshotRequest.shippingRateId : null
656
+ };
657
+ }
658
+ /**
659
+ * Places a guest order from a checkout snapshot and optionally starts payment.
660
+ *
661
+ * The client must already carry team context (e.g. `createClient({ team })` → `X-Team`).
662
+ * Body `team` alone is not enough for `orders.create`.
663
+ *
664
+ * When `pay` is enabled (default), `paymentUrl` is only set from a successful `orders.pay`
665
+ * response. `order.paymentUrl` from create is the JoAi thank-you URL and must not be used
666
+ * as a gateway redirect.
667
+ */
668
+ async function placeGuestCheckoutOrder(options) {
669
+ if (!options.acceptedTerms) throw new GuestCheckoutError("terms_required");
670
+ const expiresAt = new Date(options.snapshot.expiresAt).getTime();
671
+ if (!Number.isFinite(expiresAt) || expiresAt <= Date.now()) throw new GuestCheckoutError("review_expired");
672
+ const order = await options.client.orders.create({
673
+ team: options.team,
674
+ snapshotId: options.snapshot.id,
675
+ snapshotAccessToken: options.snapshot.accessToken,
676
+ guest: options.guest,
677
+ idempotencyKey: options.idempotencyKey ?? crypto.randomUUID(),
678
+ notes: options.notes,
679
+ sendConfirmation: true
680
+ });
681
+ if (!order.ok || !order.data?.id) throw new GuestCheckoutError("order_failed");
682
+ const accessToken = typeof order.meta?.orderAccessToken === "string" ? order.meta.orderAccessToken : null;
683
+ if (options.pay === false) return {
684
+ order: order.data,
685
+ accessToken,
686
+ paymentUrl: null
687
+ };
688
+ if (!accessToken) throw new GuestCheckoutError("payment_failed");
689
+ const payment = await options.client.orders.pay(order.data.id, void 0, accessToken);
690
+ if (!payment.ok || !payment.data?.url) return {
691
+ order: order.data,
692
+ accessToken,
693
+ paymentUrl: null
694
+ };
695
+ return {
696
+ order: order.data,
697
+ accessToken,
698
+ paymentUrl: payment.data.url
699
+ };
700
+ }
701
+ const isGuestCheckoutError = (error) => {
702
+ if (error instanceof GuestCheckoutError) return true;
703
+ return typeof error === "object" && error !== null && error.name === "GuestCheckoutError" && typeof error.code === "string";
704
+ };
705
+ //#endregion
508
706
  //#region src/commerce/index.ts
509
707
  var CommerceResource = class {
510
708
  constructor(http) {
@@ -1921,7 +2119,7 @@ var OrdersResource = class {
1921
2119
  return this.http.get(`orders/${id}`, orderAccessHeaders(accessToken));
1922
2120
  }
1923
2121
  create(data) {
1924
- return this.http.post("orders", data);
2122
+ return this.http.post("orders", data, { headers: { "X-Team": data.team } });
1925
2123
  }
1926
2124
  update(id, data) {
1927
2125
  return this.http.put(`orders/${id}`, data);
@@ -2175,10 +2373,9 @@ var SitesResource = class {
2175
2373
  listMine(teamSlug) {
2176
2374
  return this.http.get(`sites/mine?team=${encodeURIComponent(teamSlug)}`);
2177
2375
  }
2178
- create(teamSlug, slug, data) {
2376
+ create(teamSlug, data) {
2179
2377
  return this.http.post("sites", {
2180
2378
  team: teamSlug,
2181
- slug,
2182
2379
  ...data
2183
2380
  });
2184
2381
  }
@@ -2603,6 +2800,50 @@ const audiencePreviewQuery = (payload) => {
2603
2800
  return query ? `?${query}` : "";
2604
2801
  };
2605
2802
  //#endregion
2803
+ //#region src/resources/automations.ts
2804
+ var AutomationsResource = class {
2805
+ constructor(http) {
2806
+ this.http = http;
2807
+ }
2808
+ list() {
2809
+ return this.http.get("automations");
2810
+ }
2811
+ stats() {
2812
+ return this.http.get("automations/stats");
2813
+ }
2814
+ get(id) {
2815
+ return this.http.get(`automations/${id}`);
2816
+ }
2817
+ create(payload) {
2818
+ return this.http.post("automations", payload);
2819
+ }
2820
+ update(id, payload) {
2821
+ return this.http.put(`automations/${id}`, payload);
2822
+ }
2823
+ setActions(id, actions) {
2824
+ return this.http.put(`automations/${id}/actions`, { actions });
2825
+ }
2826
+ delete(id) {
2827
+ return this.http.delete(`automations/${id}`);
2828
+ }
2829
+ enrollments(id, params) {
2830
+ const search = new URLSearchParams();
2831
+ if (params?.page) search.set("page", String(params.page));
2832
+ if (params?.perPage) search.set("perPage", String(params.perPage));
2833
+ const query = search.toString();
2834
+ return this.http.get(`automations/${id}/enrollments${query ? `?${query}` : ""}`);
2835
+ }
2836
+ run(id, payload) {
2837
+ return this.http.post(`automations/${id}/run`, payload);
2838
+ }
2839
+ retryEnrollment(id, enrollmentId) {
2840
+ return this.http.post(`automations/${id}/enrollments/${enrollmentId}/retry`);
2841
+ }
2842
+ previewAudience(id) {
2843
+ return this.http.get(`automations/${id}/audience-preview`);
2844
+ }
2845
+ };
2846
+ //#endregion
2606
2847
  //#region src/resources/segments.ts
2607
2848
  var SegmentsResource = class {
2608
2849
  constructor(http) {
@@ -2646,6 +2887,9 @@ var UpdatesResource = class {
2646
2887
  if (params?.tags) query.set("tags", params.tags);
2647
2888
  if (params?.with?.length) query.set("with", params.with.join(","));
2648
2889
  if (params?.sort) query.set("sort", params.sort);
2890
+ if (params?.limit != null) query.set("limit", String(params.limit));
2891
+ if (params?.upcoming) query.set("filter[upcoming]", "1");
2892
+ if (params?.past) query.set("filter[past]", "1");
2649
2893
  const qs = query.toString();
2650
2894
  return this.http.get(`updates${qs ? "?" + qs : ""}`);
2651
2895
  }
@@ -3195,6 +3439,7 @@ var JoAiClient = class {
3195
3439
  this.teams = new TeamsResource(this.http);
3196
3440
  this.artifacts = new ArtifactsResource(this.http);
3197
3441
  this.campaigns = new CampaignsResource(this.http);
3442
+ this.automations = new AutomationsResource(this.http);
3198
3443
  this.segments = new SegmentsResource(this.http);
3199
3444
  this.updates = new UpdatesResource(this.http);
3200
3445
  this.upgrades = new UpgradesResource(this.http);
@@ -3310,4 +3555,4 @@ var DistributionResource = class {
3310
3555
  }
3311
3556
  };
3312
3557
  //#endregion
3313
- export { AddressesResource, AgentsResource, AlertsResource, ApiTokensResource, AppointmentsResource, AuthResource, BillingResource, BlueprintsResource, CachedHttpService, CampaignsResource, CardsResource, CartsResource, ChangelogResource, CharactersResource, CheckoutResource, CommerceResource, ContactsResource, ContentResource, ContractsResource, DeskResource, DistributionResource, DocumentsResource, ElementsResource, EntitiesResource, FlowsResource, FulfillmentsResource, GoalsResource, HooksResource, IngestionsResource, InquiriesResource, IntegrationsResource, IntentsResource, ItemsResource, JoAiClient, KvResource, LinksResource, LoyaltyResource, McpResource, MeetingsResource, MemoriesResource, MessagesResource, MetricsResource, MissionsResource, NotificationsResource, OfficeResource, OrdersResource, PersonaResource, ProductsResource, ProjectsResource, RemindersResource, ReturnsResource, SegmentsResource, ServicesResource, ShippingResource, ShortcutsResource, SitesResource, SkillsResource, StatsResource, StoreResource, SubscriptionsResource, SwarmsResource, TagsResource, TasksResource, TeamsResource, UpdatesResource, UpgradesResource, UsersResource, VoiceResource, WalletsResource, WarpsResource, WorkspaceResource, completePortalSession, createClient, createGuestCommerceStorage, formatOpeningHours, getAuthFragmentToken, isAllowedRedirectUrl, isPortalCallbackUrl, openPortalSession, sanitizePortalCallbackUrl };
3558
+ export { AddressesResource, AgentsResource, AlertsResource, ApiTokensResource, AppointmentsResource, AuthResource, AutomationsResource, BillingResource, BlueprintsResource, CachedHttpService, CampaignsResource, CardsResource, CartsResource, ChangelogResource, CharactersResource, CheckoutResource, CommerceResource, ContactsResource, ContentResource, ContractsResource, DeskResource, DistributionResource, DocumentsResource, ElementsResource, EntitiesResource, FlowsResource, FulfillmentsResource, GoalsResource, GuestCheckoutError, HooksResource, IngestionsResource, InquiriesResource, IntegrationsResource, IntentsResource, ItemsResource, JoAiClient, KvResource, LinksResource, LoyaltyResource, McpResource, MeetingsResource, MemoriesResource, MessagesResource, MetricsResource, MissionsResource, NotificationsResource, OfficeResource, OrdersResource, PersonaResource, ProductsResource, ProjectsResource, RemindersResource, ReturnsResource, SegmentsResource, ServicesResource, ShippingResource, ShortcutsResource, SitesResource, SkillsResource, StatsResource, StoreResource, SubscriptionsResource, SwarmsResource, TagsResource, TasksResource, TeamsResource, UpdatesResource, UpgradesResource, UsersResource, VoiceResource, WalletsResource, WarpsResource, WorkspaceResource, assertGuestCheckoutReady, buildGuestCheckoutSnapshotRequest, completePortalSession, createClient, createEmptyGuestCheckoutState, createGuestCheckoutSnapshot, createGuestCommerceStorage, formatOpeningHours, getAuthFragmentToken, isAllowedRedirectUrl, isGuestCheckoutError, isPortalCallbackUrl, openPortalSession, placeGuestCheckoutOrder, sanitizePortalCallbackUrl, toGuestCheckoutDraft };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joai/sdk",
3
- "version": "4.6.0",
3
+ "version": "4.8.0",
4
4
  "description": "JoAi public API SDK — build with your AI agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -38,7 +38,7 @@
38
38
  "@joai/warps": "*"
39
39
  },
40
40
  "devDependencies": {
41
- "@joai/core": "^4.11.0",
41
+ "@joai/core": "^4.12.0",
42
42
  "tsdown": "^0.21.0",
43
43
  "typescript": "^5.9.3"
44
44
  }