@peektravel/app-utilities 0.7.4 → 0.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.cjs +199 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +118 -1
- package/dist/index.d.ts +118 -1
- package/dist/index.js +199 -0
- package/dist/index.js.map +1 -1
- package/llms.txt +15 -2
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -421,6 +421,64 @@ declare const RENTAL_PRODUCT_TYPE = "RENTAL";
|
|
|
421
421
|
*/
|
|
422
422
|
declare const ADD_ON_PRODUCT_TYPE = "ADD-ON";
|
|
423
423
|
|
|
424
|
+
/**
|
|
425
|
+
* The clean, transport-agnostic data model for an activity's custom questions.
|
|
426
|
+
*
|
|
427
|
+
* Custom questions are the operator-configured questions attached to a bookable
|
|
428
|
+
* activity (per-guest waiver-style prompts, free-text inputs, multiple-choice
|
|
429
|
+
* pickers, etc.). This is the shape consumers work with — it is decoupled from
|
|
430
|
+
* the underlying Peek GraphQL `Question`/`ChoiceQuestion` schema, which stays
|
|
431
|
+
* internal.
|
|
432
|
+
*
|
|
433
|
+
* Note: this describes the **question definitions** on an activity, not any
|
|
434
|
+
* customer's answers — so there is no PII here and nothing gated behind
|
|
435
|
+
* `fullCustomerAccess`.
|
|
436
|
+
*/
|
|
437
|
+
/**
|
|
438
|
+
* A single custom question configured on an activity.
|
|
439
|
+
*
|
|
440
|
+
* The ordering and requiredness come from the activity's question
|
|
441
|
+
* configuration; the remaining fields describe the reusable question itself.
|
|
442
|
+
*/
|
|
443
|
+
interface CustomQuestion {
|
|
444
|
+
/** Unique identifier of the question (e.g. `"cq_anq67"`). */
|
|
445
|
+
id: string;
|
|
446
|
+
/** 1-based position of the question within the activity's question list. */
|
|
447
|
+
order: number;
|
|
448
|
+
/** Whether the activity requires an answer to this question. */
|
|
449
|
+
isRequired: boolean;
|
|
450
|
+
/** The question prompt shown to the guest (Peek's `text`). */
|
|
451
|
+
questionText: string;
|
|
452
|
+
/** Helper/hint text shown alongside the prompt, or `null` when none. */
|
|
453
|
+
hintText: string | null;
|
|
454
|
+
/**
|
|
455
|
+
* The question's input type as reported by Peek — e.g. `"CHECK_BOX"`,
|
|
456
|
+
* `"TEXT"`, `"LOCATION"`, `"SELECT_ONE"`. Left as a string so new Peek
|
|
457
|
+
* question types flow through without a package change.
|
|
458
|
+
*/
|
|
459
|
+
questionType: string;
|
|
460
|
+
/** Operator-only label for the question, or `null` when none. */
|
|
461
|
+
internalLabel: string | null;
|
|
462
|
+
/** `true` when the question is answered once per guest rather than per booking. */
|
|
463
|
+
perGuest: boolean;
|
|
464
|
+
/** Pre-filled default answer, or `null` when none. */
|
|
465
|
+
defaultValue: string | null;
|
|
466
|
+
/**
|
|
467
|
+
* Selectable options for choice-style questions (`SELECT_ONE`, `LOCATION`,
|
|
468
|
+
* …). Empty for free-text/checkbox questions that carry no options.
|
|
469
|
+
*/
|
|
470
|
+
options: CustomQuestionOption[];
|
|
471
|
+
}
|
|
472
|
+
/** A single selectable option on a choice-style {@link CustomQuestion}. */
|
|
473
|
+
interface CustomQuestionOption {
|
|
474
|
+
/** Unique identifier of the option (e.g. `"cqao_mwdgvw"`). */
|
|
475
|
+
id: string;
|
|
476
|
+
/** 1-based position of the option within the question's option list. */
|
|
477
|
+
order: number;
|
|
478
|
+
/** The option's display label (Peek's `text`). */
|
|
479
|
+
value: string;
|
|
480
|
+
}
|
|
481
|
+
|
|
424
482
|
/** Tuning options for a {@link ProductService}. */
|
|
425
483
|
interface ProductServiceOptions {
|
|
426
484
|
/** Page size for cursor-paginated item options. Default: 50. */
|
|
@@ -451,6 +509,21 @@ declare class ProductService {
|
|
|
451
509
|
getAllRentals(): Promise<Product[]>;
|
|
452
510
|
/** Returns only add-on products. */
|
|
453
511
|
getAllAddons(): Promise<Product[]>;
|
|
512
|
+
/**
|
|
513
|
+
* Returns every custom question configured on a single activity, in the order
|
|
514
|
+
* Peek reports them. Choice-style questions (`SELECT_ONE`, `LOCATION`, …)
|
|
515
|
+
* carry their selectable {@link CustomQuestion.options}; free-text/checkbox
|
|
516
|
+
* questions return an empty option list.
|
|
517
|
+
*
|
|
518
|
+
* These are question **definitions**, not customer answers — no PII is
|
|
519
|
+
* involved, so the result is unaffected by `fullCustomerAccess`.
|
|
520
|
+
*
|
|
521
|
+
* @param productId The activity's id.
|
|
522
|
+
* @returns The activity's custom questions, or an empty list when the activity
|
|
523
|
+
* has none or is not found.
|
|
524
|
+
* @throws Error when `productId` is missing or blank.
|
|
525
|
+
*/
|
|
526
|
+
getCustomQuestions(productId: string): Promise<CustomQuestion[]>;
|
|
454
527
|
private fetchActivities;
|
|
455
528
|
private fetchAllItemOptionNodes;
|
|
456
529
|
}
|
|
@@ -773,6 +846,34 @@ interface CreateBookingGuest {
|
|
|
773
846
|
optinMarketing?: boolean;
|
|
774
847
|
optinSms?: boolean;
|
|
775
848
|
}
|
|
849
|
+
/**
|
|
850
|
+
* An answer to one of an activity's custom questions, supplied when creating a
|
|
851
|
+
* booking. The question is identified by id **or** text, and the value is
|
|
852
|
+
* resolved against the question's type at create time (see
|
|
853
|
+
* {@link CreateBookingInput.customQuestionAnswers}).
|
|
854
|
+
*/
|
|
855
|
+
interface CustomQuestionAnswerInput {
|
|
856
|
+
/**
|
|
857
|
+
* The question to answer — either its id (`cq_…`) or its question text. Text
|
|
858
|
+
* is matched leniently (lowercased, non-alphanumerics stripped); it must match
|
|
859
|
+
* exactly one question or creation fails.
|
|
860
|
+
*/
|
|
861
|
+
questionIdOrText: string;
|
|
862
|
+
/**
|
|
863
|
+
* The answer. How it is interpreted depends on the question's type:
|
|
864
|
+
* - **checkbox** — `yes`/`no`/`true`/`false` (case-insensitive).
|
|
865
|
+
* - **text** — used verbatim.
|
|
866
|
+
* - **select-one / location** — an option id (`cqao_…`) or the option's label,
|
|
867
|
+
* matched leniently the same way as `questionIdOrText`.
|
|
868
|
+
*
|
|
869
|
+
* For **location** questions you only select the option — Peek holds each
|
|
870
|
+
* option's configured lat/long and applies it, so no coordinates are (or can
|
|
871
|
+
* be) supplied here.
|
|
872
|
+
*
|
|
873
|
+
* Per-guest questions are **not yet supported**: answering one fails creation.
|
|
874
|
+
*/
|
|
875
|
+
value: string;
|
|
876
|
+
}
|
|
776
877
|
/**
|
|
777
878
|
* Input for creating a booking. IDs must already be resolved — the package does
|
|
778
879
|
* not do free-text product/ticket/time matching (that stays in the caller).
|
|
@@ -788,6 +889,13 @@ interface CreateBookingInput {
|
|
|
788
889
|
guest: CreateBookingGuest;
|
|
789
890
|
/** Operator notes to attach. */
|
|
790
891
|
operatorNotes?: string;
|
|
892
|
+
/**
|
|
893
|
+
* Answers to the activity's custom questions. When non-empty, the activity's
|
|
894
|
+
* custom questions are fetched and each answer is validated/resolved before
|
|
895
|
+
* the booking is created — an unmatched question, ambiguous text/option, or
|
|
896
|
+
* invalid checkbox value fails creation before any quote is made.
|
|
897
|
+
*/
|
|
898
|
+
customQuestionAnswers?: CustomQuestionAnswerInput[];
|
|
791
899
|
/** Suppress the customer confirmation email. Default: false. */
|
|
792
900
|
skipCustomerEmail?: boolean;
|
|
793
901
|
/** Clone the quote from an existing order. */
|
|
@@ -1164,6 +1272,13 @@ declare class BookingService {
|
|
|
1164
1272
|
* mutations fail.
|
|
1165
1273
|
*/
|
|
1166
1274
|
create(input: CreateBookingInput): Promise<CreatedBooking>;
|
|
1275
|
+
/**
|
|
1276
|
+
* Resolves the input's custom-question answers into the quote's
|
|
1277
|
+
* `questionAnswers` payload (each tagged with a fresh `refid`), or `null` when
|
|
1278
|
+
* none were supplied. Fetches the activity's custom questions to validate
|
|
1279
|
+
* against; throws on the first unmatched/ambiguous/invalid answer.
|
|
1280
|
+
*/
|
|
1281
|
+
private buildQuestionAnswers;
|
|
1167
1282
|
private markCreatedBookingPaid;
|
|
1168
1283
|
/** Finds the parent item id of an add-on by matching its option id. */
|
|
1169
1284
|
private resolveParentItemId;
|
|
@@ -2062,6 +2177,8 @@ declare class PeekAccessService {
|
|
|
2062
2177
|
getAllRentals(): Promise<Product[]>;
|
|
2063
2178
|
/** All add-on products. Delegates to {@link ProductService.getAllAddons}. */
|
|
2064
2179
|
getAllAddons(): Promise<Product[]>;
|
|
2180
|
+
/** An activity's custom questions. Delegates to {@link ProductService.getCustomQuestions}. */
|
|
2181
|
+
getCustomQuestions(productId: string): Promise<CustomQuestion[]>;
|
|
2065
2182
|
/** All active account users. Delegates to {@link AccountUserService.getAll}. */
|
|
2066
2183
|
getAllAccountUsers(): Promise<AccountUser[]>;
|
|
2067
2184
|
/** Account user by id, or null. Delegates to {@link AccountUserService.getById}. */
|
|
@@ -2836,4 +2953,4 @@ declare class AcmeApiError extends Error {
|
|
|
2836
2953
|
constructor(statusCode: number, body: unknown, message?: string);
|
|
2837
2954
|
}
|
|
2838
2955
|
|
|
2839
|
-
export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccessOptions, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, type Activity, type ActivityOverrides, type ActivityTicket, type AddAddonInput, AdminAccountRequiredError, type Agent, type AssignGuideResult, type AssignedActivity, type AssignedResource, type Availability, AvailabilityService, type AvailabilityTime, type AvailabilityTimesQuery, type Booking, type BookingAddon, type BookingAddonMoney, type BookingAddonOption, type BookingAddons, type BookingAddonsMutationResult, type BookingPaymentsOnFile, type BookingReadOptions, type BookingSearchBy, BookingService, type BookingServiceOptions, type BookingTimeRangeSearch, type CancelBookingResult, type Channel, type ClearOverridesInput, CngAccessService, type CngAccessServiceConfig, CngApiError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, type CreatedPromoCode, type CustomQuestionAnswer, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, INSTALL_STATUSES, type InstallAccessConfig, type InstallAccessService, type InstallAccessTarget, type InstallStatus, type InstallWebhook, type InstallWebhookAccount, type InstallWebhookClaims, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, PeekHttpError, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, type ProductMeetingLocation, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
|
|
2956
|
+
export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccessOptions, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, type Activity, type ActivityOverrides, type ActivityTicket, type AddAddonInput, AdminAccountRequiredError, type Agent, type AssignGuideResult, type AssignedActivity, type AssignedResource, type Availability, AvailabilityService, type AvailabilityTime, type AvailabilityTimesQuery, type Booking, type BookingAddon, type BookingAddonMoney, type BookingAddonOption, type BookingAddons, type BookingAddonsMutationResult, type BookingPaymentsOnFile, type BookingReadOptions, type BookingSearchBy, BookingService, type BookingServiceOptions, type BookingTimeRangeSearch, type CancelBookingResult, type Channel, type ClearOverridesInput, CngAccessService, type CngAccessServiceConfig, CngApiError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, type CreatedPromoCode, type CustomQuestion, type CustomQuestionAnswer, type CustomQuestionAnswerInput, type CustomQuestionOption, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, INSTALL_STATUSES, type InstallAccessConfig, type InstallAccessService, type InstallAccessTarget, type InstallStatus, type InstallWebhook, type InstallWebhookAccount, type InstallWebhookClaims, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, PeekHttpError, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, type ProductMeetingLocation, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
|
package/dist/index.d.ts
CHANGED
|
@@ -421,6 +421,64 @@ declare const RENTAL_PRODUCT_TYPE = "RENTAL";
|
|
|
421
421
|
*/
|
|
422
422
|
declare const ADD_ON_PRODUCT_TYPE = "ADD-ON";
|
|
423
423
|
|
|
424
|
+
/**
|
|
425
|
+
* The clean, transport-agnostic data model for an activity's custom questions.
|
|
426
|
+
*
|
|
427
|
+
* Custom questions are the operator-configured questions attached to a bookable
|
|
428
|
+
* activity (per-guest waiver-style prompts, free-text inputs, multiple-choice
|
|
429
|
+
* pickers, etc.). This is the shape consumers work with — it is decoupled from
|
|
430
|
+
* the underlying Peek GraphQL `Question`/`ChoiceQuestion` schema, which stays
|
|
431
|
+
* internal.
|
|
432
|
+
*
|
|
433
|
+
* Note: this describes the **question definitions** on an activity, not any
|
|
434
|
+
* customer's answers — so there is no PII here and nothing gated behind
|
|
435
|
+
* `fullCustomerAccess`.
|
|
436
|
+
*/
|
|
437
|
+
/**
|
|
438
|
+
* A single custom question configured on an activity.
|
|
439
|
+
*
|
|
440
|
+
* The ordering and requiredness come from the activity's question
|
|
441
|
+
* configuration; the remaining fields describe the reusable question itself.
|
|
442
|
+
*/
|
|
443
|
+
interface CustomQuestion {
|
|
444
|
+
/** Unique identifier of the question (e.g. `"cq_anq67"`). */
|
|
445
|
+
id: string;
|
|
446
|
+
/** 1-based position of the question within the activity's question list. */
|
|
447
|
+
order: number;
|
|
448
|
+
/** Whether the activity requires an answer to this question. */
|
|
449
|
+
isRequired: boolean;
|
|
450
|
+
/** The question prompt shown to the guest (Peek's `text`). */
|
|
451
|
+
questionText: string;
|
|
452
|
+
/** Helper/hint text shown alongside the prompt, or `null` when none. */
|
|
453
|
+
hintText: string | null;
|
|
454
|
+
/**
|
|
455
|
+
* The question's input type as reported by Peek — e.g. `"CHECK_BOX"`,
|
|
456
|
+
* `"TEXT"`, `"LOCATION"`, `"SELECT_ONE"`. Left as a string so new Peek
|
|
457
|
+
* question types flow through without a package change.
|
|
458
|
+
*/
|
|
459
|
+
questionType: string;
|
|
460
|
+
/** Operator-only label for the question, or `null` when none. */
|
|
461
|
+
internalLabel: string | null;
|
|
462
|
+
/** `true` when the question is answered once per guest rather than per booking. */
|
|
463
|
+
perGuest: boolean;
|
|
464
|
+
/** Pre-filled default answer, or `null` when none. */
|
|
465
|
+
defaultValue: string | null;
|
|
466
|
+
/**
|
|
467
|
+
* Selectable options for choice-style questions (`SELECT_ONE`, `LOCATION`,
|
|
468
|
+
* …). Empty for free-text/checkbox questions that carry no options.
|
|
469
|
+
*/
|
|
470
|
+
options: CustomQuestionOption[];
|
|
471
|
+
}
|
|
472
|
+
/** A single selectable option on a choice-style {@link CustomQuestion}. */
|
|
473
|
+
interface CustomQuestionOption {
|
|
474
|
+
/** Unique identifier of the option (e.g. `"cqao_mwdgvw"`). */
|
|
475
|
+
id: string;
|
|
476
|
+
/** 1-based position of the option within the question's option list. */
|
|
477
|
+
order: number;
|
|
478
|
+
/** The option's display label (Peek's `text`). */
|
|
479
|
+
value: string;
|
|
480
|
+
}
|
|
481
|
+
|
|
424
482
|
/** Tuning options for a {@link ProductService}. */
|
|
425
483
|
interface ProductServiceOptions {
|
|
426
484
|
/** Page size for cursor-paginated item options. Default: 50. */
|
|
@@ -451,6 +509,21 @@ declare class ProductService {
|
|
|
451
509
|
getAllRentals(): Promise<Product[]>;
|
|
452
510
|
/** Returns only add-on products. */
|
|
453
511
|
getAllAddons(): Promise<Product[]>;
|
|
512
|
+
/**
|
|
513
|
+
* Returns every custom question configured on a single activity, in the order
|
|
514
|
+
* Peek reports them. Choice-style questions (`SELECT_ONE`, `LOCATION`, …)
|
|
515
|
+
* carry their selectable {@link CustomQuestion.options}; free-text/checkbox
|
|
516
|
+
* questions return an empty option list.
|
|
517
|
+
*
|
|
518
|
+
* These are question **definitions**, not customer answers — no PII is
|
|
519
|
+
* involved, so the result is unaffected by `fullCustomerAccess`.
|
|
520
|
+
*
|
|
521
|
+
* @param productId The activity's id.
|
|
522
|
+
* @returns The activity's custom questions, or an empty list when the activity
|
|
523
|
+
* has none or is not found.
|
|
524
|
+
* @throws Error when `productId` is missing or blank.
|
|
525
|
+
*/
|
|
526
|
+
getCustomQuestions(productId: string): Promise<CustomQuestion[]>;
|
|
454
527
|
private fetchActivities;
|
|
455
528
|
private fetchAllItemOptionNodes;
|
|
456
529
|
}
|
|
@@ -773,6 +846,34 @@ interface CreateBookingGuest {
|
|
|
773
846
|
optinMarketing?: boolean;
|
|
774
847
|
optinSms?: boolean;
|
|
775
848
|
}
|
|
849
|
+
/**
|
|
850
|
+
* An answer to one of an activity's custom questions, supplied when creating a
|
|
851
|
+
* booking. The question is identified by id **or** text, and the value is
|
|
852
|
+
* resolved against the question's type at create time (see
|
|
853
|
+
* {@link CreateBookingInput.customQuestionAnswers}).
|
|
854
|
+
*/
|
|
855
|
+
interface CustomQuestionAnswerInput {
|
|
856
|
+
/**
|
|
857
|
+
* The question to answer — either its id (`cq_…`) or its question text. Text
|
|
858
|
+
* is matched leniently (lowercased, non-alphanumerics stripped); it must match
|
|
859
|
+
* exactly one question or creation fails.
|
|
860
|
+
*/
|
|
861
|
+
questionIdOrText: string;
|
|
862
|
+
/**
|
|
863
|
+
* The answer. How it is interpreted depends on the question's type:
|
|
864
|
+
* - **checkbox** — `yes`/`no`/`true`/`false` (case-insensitive).
|
|
865
|
+
* - **text** — used verbatim.
|
|
866
|
+
* - **select-one / location** — an option id (`cqao_…`) or the option's label,
|
|
867
|
+
* matched leniently the same way as `questionIdOrText`.
|
|
868
|
+
*
|
|
869
|
+
* For **location** questions you only select the option — Peek holds each
|
|
870
|
+
* option's configured lat/long and applies it, so no coordinates are (or can
|
|
871
|
+
* be) supplied here.
|
|
872
|
+
*
|
|
873
|
+
* Per-guest questions are **not yet supported**: answering one fails creation.
|
|
874
|
+
*/
|
|
875
|
+
value: string;
|
|
876
|
+
}
|
|
776
877
|
/**
|
|
777
878
|
* Input for creating a booking. IDs must already be resolved — the package does
|
|
778
879
|
* not do free-text product/ticket/time matching (that stays in the caller).
|
|
@@ -788,6 +889,13 @@ interface CreateBookingInput {
|
|
|
788
889
|
guest: CreateBookingGuest;
|
|
789
890
|
/** Operator notes to attach. */
|
|
790
891
|
operatorNotes?: string;
|
|
892
|
+
/**
|
|
893
|
+
* Answers to the activity's custom questions. When non-empty, the activity's
|
|
894
|
+
* custom questions are fetched and each answer is validated/resolved before
|
|
895
|
+
* the booking is created — an unmatched question, ambiguous text/option, or
|
|
896
|
+
* invalid checkbox value fails creation before any quote is made.
|
|
897
|
+
*/
|
|
898
|
+
customQuestionAnswers?: CustomQuestionAnswerInput[];
|
|
791
899
|
/** Suppress the customer confirmation email. Default: false. */
|
|
792
900
|
skipCustomerEmail?: boolean;
|
|
793
901
|
/** Clone the quote from an existing order. */
|
|
@@ -1164,6 +1272,13 @@ declare class BookingService {
|
|
|
1164
1272
|
* mutations fail.
|
|
1165
1273
|
*/
|
|
1166
1274
|
create(input: CreateBookingInput): Promise<CreatedBooking>;
|
|
1275
|
+
/**
|
|
1276
|
+
* Resolves the input's custom-question answers into the quote's
|
|
1277
|
+
* `questionAnswers` payload (each tagged with a fresh `refid`), or `null` when
|
|
1278
|
+
* none were supplied. Fetches the activity's custom questions to validate
|
|
1279
|
+
* against; throws on the first unmatched/ambiguous/invalid answer.
|
|
1280
|
+
*/
|
|
1281
|
+
private buildQuestionAnswers;
|
|
1167
1282
|
private markCreatedBookingPaid;
|
|
1168
1283
|
/** Finds the parent item id of an add-on by matching its option id. */
|
|
1169
1284
|
private resolveParentItemId;
|
|
@@ -2062,6 +2177,8 @@ declare class PeekAccessService {
|
|
|
2062
2177
|
getAllRentals(): Promise<Product[]>;
|
|
2063
2178
|
/** All add-on products. Delegates to {@link ProductService.getAllAddons}. */
|
|
2064
2179
|
getAllAddons(): Promise<Product[]>;
|
|
2180
|
+
/** An activity's custom questions. Delegates to {@link ProductService.getCustomQuestions}. */
|
|
2181
|
+
getCustomQuestions(productId: string): Promise<CustomQuestion[]>;
|
|
2065
2182
|
/** All active account users. Delegates to {@link AccountUserService.getAll}. */
|
|
2066
2183
|
getAllAccountUsers(): Promise<AccountUser[]>;
|
|
2067
2184
|
/** Account user by id, or null. Delegates to {@link AccountUserService.getById}. */
|
|
@@ -2836,4 +2953,4 @@ declare class AcmeApiError extends Error {
|
|
|
2836
2953
|
constructor(statusCode: number, body: unknown, message?: string);
|
|
2837
2954
|
}
|
|
2838
2955
|
|
|
2839
|
-
export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccessOptions, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, type Activity, type ActivityOverrides, type ActivityTicket, type AddAddonInput, AdminAccountRequiredError, type Agent, type AssignGuideResult, type AssignedActivity, type AssignedResource, type Availability, AvailabilityService, type AvailabilityTime, type AvailabilityTimesQuery, type Booking, type BookingAddon, type BookingAddonMoney, type BookingAddonOption, type BookingAddons, type BookingAddonsMutationResult, type BookingPaymentsOnFile, type BookingReadOptions, type BookingSearchBy, BookingService, type BookingServiceOptions, type BookingTimeRangeSearch, type CancelBookingResult, type Channel, type ClearOverridesInput, CngAccessService, type CngAccessServiceConfig, CngApiError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, type CreatedPromoCode, type CustomQuestionAnswer, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, INSTALL_STATUSES, type InstallAccessConfig, type InstallAccessService, type InstallAccessTarget, type InstallStatus, type InstallWebhook, type InstallWebhookAccount, type InstallWebhookClaims, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, PeekHttpError, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, type ProductMeetingLocation, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
|
|
2956
|
+
export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccessOptions, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, type Activity, type ActivityOverrides, type ActivityTicket, type AddAddonInput, AdminAccountRequiredError, type Agent, type AssignGuideResult, type AssignedActivity, type AssignedResource, type Availability, AvailabilityService, type AvailabilityTime, type AvailabilityTimesQuery, type Booking, type BookingAddon, type BookingAddonMoney, type BookingAddonOption, type BookingAddons, type BookingAddonsMutationResult, type BookingPaymentsOnFile, type BookingReadOptions, type BookingSearchBy, BookingService, type BookingServiceOptions, type BookingTimeRangeSearch, type CancelBookingResult, type Channel, type ClearOverridesInput, CngAccessService, type CngAccessServiceConfig, CngApiError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, type CreatedPromoCode, type CustomQuestion, type CustomQuestionAnswer, type CustomQuestionAnswerInput, type CustomQuestionOption, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, INSTALL_STATUSES, type InstallAccessConfig, type InstallAccessService, type InstallAccessTarget, type InstallStatus, type InstallWebhook, type InstallWebhookAccount, type InstallWebhookClaims, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, PeekHttpError, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, type ProductMeetingLocation, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
|
package/dist/index.js
CHANGED
|
@@ -1039,6 +1039,94 @@ function toBookingAddon(item) {
|
|
|
1039
1039
|
return { addonId, addonName, total: item.total, addonOptions };
|
|
1040
1040
|
}
|
|
1041
1041
|
|
|
1042
|
+
// src/internal/peek/bookings/custom-question-answer.ts
|
|
1043
|
+
var QUESTION_TYPE_CHECK_BOX = "CHECK_BOX";
|
|
1044
|
+
var QUESTION_TYPE_TEXT = "TEXT";
|
|
1045
|
+
var QUESTION_TYPE_SELECT_ONE = "SELECT_ONE";
|
|
1046
|
+
var QUESTION_TYPE_LOCATION = "LOCATION";
|
|
1047
|
+
var QUESTION_ID_REGEX = /^cq_[a-z0-9]+$/;
|
|
1048
|
+
var OPTION_ID_REGEX = /^cqao_[a-z0-9]+$/;
|
|
1049
|
+
var CHECKBOX_TRUE = /* @__PURE__ */ new Set(["yes", "true"]);
|
|
1050
|
+
var CHECKBOX_VALID = /* @__PURE__ */ new Set(["yes", "no", "true", "false"]);
|
|
1051
|
+
var CHECKBOX_TEXT_TRUE = "Yes";
|
|
1052
|
+
var CHECKBOX_TEXT_FALSE = "No";
|
|
1053
|
+
var errUnknownQuestionId = (v) => `No custom question matches id "${v}" for this activity`;
|
|
1054
|
+
var errNoTextMatch = (v) => `No custom question matches text "${v}" for this activity`;
|
|
1055
|
+
var errAmbiguousText = (v) => `Custom question text "${v}" matches more than one question`;
|
|
1056
|
+
var errPerGuestUnsupported = (id) => `Per-guest custom question "${id}" is not yet supported`;
|
|
1057
|
+
var errUnsupportedType = (type, id) => `Custom question "${id}" has unsupported type "${type}"`;
|
|
1058
|
+
var errInvalidCheckbox = (v, id) => `Checkbox answer for question "${id}" must be yes/no/true/false, got "${v}"`;
|
|
1059
|
+
var errUnknownOptionId = (v, id) => `No option matches id "${v}" for question "${id}"`;
|
|
1060
|
+
var errNoOptionMatch = (v, id) => `No option matches "${v}" for question "${id}"`;
|
|
1061
|
+
var errAmbiguousOption = (v, id) => `Option "${v}" matches more than one option for question "${id}"`;
|
|
1062
|
+
function normalize(value) {
|
|
1063
|
+
return value.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
1064
|
+
}
|
|
1065
|
+
function resolveQuestion(idOrText, questions) {
|
|
1066
|
+
if (QUESTION_ID_REGEX.test(idOrText)) {
|
|
1067
|
+
const byId = questions.find((question) => question.id === idOrText);
|
|
1068
|
+
if (!byId) throw new Error(errUnknownQuestionId(idOrText));
|
|
1069
|
+
return byId;
|
|
1070
|
+
}
|
|
1071
|
+
const target = normalize(idOrText);
|
|
1072
|
+
const matches = questions.filter(
|
|
1073
|
+
(question) => normalize(question.questionText) === target
|
|
1074
|
+
);
|
|
1075
|
+
if (matches.length === 0) throw new Error(errNoTextMatch(idOrText));
|
|
1076
|
+
if (matches.length > 1) throw new Error(errAmbiguousText(idOrText));
|
|
1077
|
+
return matches[0];
|
|
1078
|
+
}
|
|
1079
|
+
function resolveOption(value, question) {
|
|
1080
|
+
if (OPTION_ID_REGEX.test(value)) {
|
|
1081
|
+
const byId = question.options.find((option) => option.id === value);
|
|
1082
|
+
if (!byId) throw new Error(errUnknownOptionId(value, question.id));
|
|
1083
|
+
return byId;
|
|
1084
|
+
}
|
|
1085
|
+
const target = normalize(value);
|
|
1086
|
+
const matches = question.options.filter(
|
|
1087
|
+
(option) => normalize(option.value) === target
|
|
1088
|
+
);
|
|
1089
|
+
if (matches.length === 0) throw new Error(errNoOptionMatch(value, question.id));
|
|
1090
|
+
if (matches.length > 1) throw new Error(errAmbiguousOption(value, question.id));
|
|
1091
|
+
return matches[0];
|
|
1092
|
+
}
|
|
1093
|
+
function resolveOne(answer, questions) {
|
|
1094
|
+
const question = resolveQuestion(answer.questionIdOrText, questions);
|
|
1095
|
+
if (question.perGuest) {
|
|
1096
|
+
throw new Error(errPerGuestUnsupported(question.id));
|
|
1097
|
+
}
|
|
1098
|
+
switch (question.questionType) {
|
|
1099
|
+
case QUESTION_TYPE_CHECK_BOX: {
|
|
1100
|
+
const normalized = answer.value.trim().toLowerCase();
|
|
1101
|
+
if (!CHECKBOX_VALID.has(normalized)) {
|
|
1102
|
+
throw new Error(errInvalidCheckbox(answer.value, question.id));
|
|
1103
|
+
}
|
|
1104
|
+
const isChecked = CHECKBOX_TRUE.has(normalized);
|
|
1105
|
+
return {
|
|
1106
|
+
questionId: question.id,
|
|
1107
|
+
isChecked,
|
|
1108
|
+
questionAnswerText: isChecked ? CHECKBOX_TEXT_TRUE : CHECKBOX_TEXT_FALSE
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
case QUESTION_TYPE_TEXT:
|
|
1112
|
+
return { questionId: question.id, questionAnswerText: answer.value };
|
|
1113
|
+
case QUESTION_TYPE_SELECT_ONE:
|
|
1114
|
+
case QUESTION_TYPE_LOCATION: {
|
|
1115
|
+
const option = resolveOption(answer.value, question);
|
|
1116
|
+
return {
|
|
1117
|
+
questionId: question.id,
|
|
1118
|
+
questionAnswerOptionId: option.id,
|
|
1119
|
+
questionAnswerText: option.value
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
default:
|
|
1123
|
+
throw new Error(errUnsupportedType(question.questionType, question.id));
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
function resolveCustomQuestionAnswers(answers, questions) {
|
|
1127
|
+
return answers.map((answer) => resolveOne(answer, questions));
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1042
1130
|
// src/internal/peek/bookings/booking-service.ts
|
|
1043
1131
|
var DEFAULT_PAGE_SIZE2 = 50;
|
|
1044
1132
|
var DEFAULT_CANCEL_NOTE = "Canceled";
|
|
@@ -1558,6 +1646,7 @@ ${note}`;
|
|
|
1558
1646
|
*/
|
|
1559
1647
|
async create(input) {
|
|
1560
1648
|
validateCreateInput(input);
|
|
1649
|
+
const questionAnswers = await this.buildQuestionAnswers(input);
|
|
1561
1650
|
const tickets = input.tickets.flatMap(
|
|
1562
1651
|
(ticket) => Array.from({ length: ticket.quantity }, () => ({
|
|
1563
1652
|
resourceOptionId: ticket.resourceOptionId,
|
|
@@ -1584,6 +1673,9 @@ ${note}`;
|
|
|
1584
1673
|
if (input.operatorNotes) {
|
|
1585
1674
|
bookingQuote.operatorNotes = input.operatorNotes;
|
|
1586
1675
|
}
|
|
1676
|
+
if (questionAnswers) {
|
|
1677
|
+
bookingQuote.questionAnswers = questionAnswers;
|
|
1678
|
+
}
|
|
1587
1679
|
const quoteInput = { bookingQuotes: [bookingQuote] };
|
|
1588
1680
|
if (input.parentOrderId) {
|
|
1589
1681
|
quoteInput.source = { clonedFromId: input.parentOrderId };
|
|
@@ -1623,6 +1715,25 @@ ${note}`;
|
|
|
1623
1715
|
}
|
|
1624
1716
|
return created;
|
|
1625
1717
|
}
|
|
1718
|
+
/**
|
|
1719
|
+
* Resolves the input's custom-question answers into the quote's
|
|
1720
|
+
* `questionAnswers` payload (each tagged with a fresh `refid`), or `null` when
|
|
1721
|
+
* none were supplied. Fetches the activity's custom questions to validate
|
|
1722
|
+
* against; throws on the first unmatched/ambiguous/invalid answer.
|
|
1723
|
+
*/
|
|
1724
|
+
async buildQuestionAnswers(input) {
|
|
1725
|
+
const answers = input.customQuestionAnswers;
|
|
1726
|
+
if (!answers || answers.length === 0) {
|
|
1727
|
+
return null;
|
|
1728
|
+
}
|
|
1729
|
+
const questions = await this.deps.productService.getCustomQuestions(
|
|
1730
|
+
input.activityId
|
|
1731
|
+
);
|
|
1732
|
+
return resolveCustomQuestionAnswers(answers, questions).map((resolved) => ({
|
|
1733
|
+
...resolved,
|
|
1734
|
+
refid: randomUUID()
|
|
1735
|
+
}));
|
|
1736
|
+
}
|
|
1626
1737
|
async markCreatedBookingPaid(booking, input) {
|
|
1627
1738
|
const parsedPartial = input.markAsPaidAmount ? parseFloat(input.markAsPaidAmount) : NaN;
|
|
1628
1739
|
const amount = !Number.isNaN(parsedPartial) && parsedPartial > 0 ? parsedPartial.toFixed(2) : booking.balanceAmount;
|
|
@@ -2935,6 +3046,33 @@ function fromItemOptionNodes(nodes) {
|
|
|
2935
3046
|
return Array.from(grouped.values());
|
|
2936
3047
|
}
|
|
2937
3048
|
|
|
3049
|
+
// src/internal/peek/products/custom-question-converter.ts
|
|
3050
|
+
function fromQuestionConfigurations(configs) {
|
|
3051
|
+
return configs.map(fromQuestionConfiguration);
|
|
3052
|
+
}
|
|
3053
|
+
function fromQuestionConfiguration(config) {
|
|
3054
|
+
const question = config.question;
|
|
3055
|
+
return {
|
|
3056
|
+
id: question.id,
|
|
3057
|
+
order: config.order ?? 0,
|
|
3058
|
+
isRequired: config.isRequired ?? false,
|
|
3059
|
+
questionText: question.text,
|
|
3060
|
+
hintText: question.hint ?? null,
|
|
3061
|
+
questionType: question.questionType,
|
|
3062
|
+
internalLabel: question.internalLabel ?? null,
|
|
3063
|
+
perGuest: question.perGuest ?? false,
|
|
3064
|
+
defaultValue: question.answerDefaultValue ?? null,
|
|
3065
|
+
options: (question.options ?? []).map(fromQuestionOption)
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
function fromQuestionOption(option) {
|
|
3069
|
+
return {
|
|
3070
|
+
id: option.id,
|
|
3071
|
+
order: option.order,
|
|
3072
|
+
value: option.text
|
|
3073
|
+
};
|
|
3074
|
+
}
|
|
3075
|
+
|
|
2938
3076
|
// src/internal/peek/products/product-queries.ts
|
|
2939
3077
|
var PRODUCTS_QUERY = `
|
|
2940
3078
|
query Sales {
|
|
@@ -2993,7 +3131,38 @@ var ITEM_OPTIONS_QUERY = `
|
|
|
2993
3131
|
}
|
|
2994
3132
|
`;
|
|
2995
3133
|
|
|
3134
|
+
// src/internal/peek/products/custom-question-queries.ts
|
|
3135
|
+
var CUSTOM_QUESTIONS_QUERY = `
|
|
3136
|
+
query Sales($id: ID!) {
|
|
3137
|
+
activity(id: $id) {
|
|
3138
|
+
id
|
|
3139
|
+
name
|
|
3140
|
+
questionActivityConfigurations {
|
|
3141
|
+
isRequired
|
|
3142
|
+
order
|
|
3143
|
+
question {
|
|
3144
|
+
id
|
|
3145
|
+
questionType
|
|
3146
|
+
text
|
|
3147
|
+
answerDefaultValue
|
|
3148
|
+
hint
|
|
3149
|
+
internalLabel
|
|
3150
|
+
perGuest
|
|
3151
|
+
... on ChoiceQuestion {
|
|
3152
|
+
options {
|
|
3153
|
+
id
|
|
3154
|
+
text
|
|
3155
|
+
order
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
`;
|
|
3163
|
+
|
|
2996
3164
|
// src/internal/peek/products/product-service.ts
|
|
3165
|
+
var ERROR_PRODUCT_ID_REQUIRED2 = "A non-empty product id is required.";
|
|
2997
3166
|
var DEFAULT_ITEM_OPTIONS_PAGE_SIZE = 50;
|
|
2998
3167
|
var ProductService = class {
|
|
2999
3168
|
constructor(client, options = {}) {
|
|
@@ -3038,6 +3207,32 @@ var ProductService = class {
|
|
|
3038
3207
|
const nodes = await this.fetchAllItemOptionNodes();
|
|
3039
3208
|
return fromItemOptionNodes(nodes);
|
|
3040
3209
|
}
|
|
3210
|
+
/**
|
|
3211
|
+
* Returns every custom question configured on a single activity, in the order
|
|
3212
|
+
* Peek reports them. Choice-style questions (`SELECT_ONE`, `LOCATION`, …)
|
|
3213
|
+
* carry their selectable {@link CustomQuestion.options}; free-text/checkbox
|
|
3214
|
+
* questions return an empty option list.
|
|
3215
|
+
*
|
|
3216
|
+
* These are question **definitions**, not customer answers — no PII is
|
|
3217
|
+
* involved, so the result is unaffected by `fullCustomerAccess`.
|
|
3218
|
+
*
|
|
3219
|
+
* @param productId The activity's id.
|
|
3220
|
+
* @returns The activity's custom questions, or an empty list when the activity
|
|
3221
|
+
* has none or is not found.
|
|
3222
|
+
* @throws Error when `productId` is missing or blank.
|
|
3223
|
+
*/
|
|
3224
|
+
async getCustomQuestions(productId) {
|
|
3225
|
+
if (!productId?.trim()) {
|
|
3226
|
+
throw new Error(ERROR_PRODUCT_ID_REQUIRED2);
|
|
3227
|
+
}
|
|
3228
|
+
const body = await this.client.request(
|
|
3229
|
+
SALES_ENDPOINT,
|
|
3230
|
+
CUSTOM_QUESTIONS_QUERY,
|
|
3231
|
+
{ id: productId }
|
|
3232
|
+
);
|
|
3233
|
+
const configs = body.data?.activity?.questionActivityConfigurations ?? [];
|
|
3234
|
+
return fromQuestionConfigurations(configs);
|
|
3235
|
+
}
|
|
3041
3236
|
async fetchActivities() {
|
|
3042
3237
|
const body = await this.client.request(
|
|
3043
3238
|
SALES_ENDPOINT,
|
|
@@ -3751,6 +3946,10 @@ var PeekAccessService = class {
|
|
|
3751
3946
|
getAllAddons() {
|
|
3752
3947
|
return this.getProductService().getAllAddons();
|
|
3753
3948
|
}
|
|
3949
|
+
/** An activity's custom questions. Delegates to {@link ProductService.getCustomQuestions}. */
|
|
3950
|
+
getCustomQuestions(productId) {
|
|
3951
|
+
return this.getProductService().getCustomQuestions(productId);
|
|
3952
|
+
}
|
|
3754
3953
|
// ─── Account-user short-forms ─────────────────────────────────────────────
|
|
3755
3954
|
/** All active account users. Delegates to {@link AccountUserService.getAll}. */
|
|
3756
3955
|
getAllAccountUsers() {
|