@peektravel/app-utilities 0.5.2 → 0.5.3
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/README.md +69 -14
- package/dist/index.cjs +102 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -5
- package/dist/index.d.ts +76 -5
- package/dist/index.js +101 -40
- package/dist/index.js.map +1 -1
- package/dist/ui/index.cjs +35 -1
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +35 -1
- package/dist/ui/index.js.map +1 -1
- package/docs/ui.md +26 -2
- package/docs/webhooks.md +80 -9
- package/llms.txt +28 -9
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1797,6 +1797,36 @@ interface PeekAuthTokenClaims {
|
|
|
1797
1797
|
/** Authenticated user context. */
|
|
1798
1798
|
user: PeekAuthTokenUser;
|
|
1799
1799
|
}
|
|
1800
|
+
/** The Peek account an install belongs to, as reported on an install webhook. */
|
|
1801
|
+
interface InstallWebhookAccount {
|
|
1802
|
+
/** Peek account ID that owns the install. */
|
|
1803
|
+
id: string;
|
|
1804
|
+
}
|
|
1805
|
+
/**
|
|
1806
|
+
* Claims returned by `verifyInstallWebhook` — the decoded, signature-verified
|
|
1807
|
+
* install-status webhook token.
|
|
1808
|
+
*
|
|
1809
|
+
* Shares the `app_registry_v2` token family with {@link PeekAuthTokenClaims},
|
|
1810
|
+
* but is emitted by the app registry itself for install lifecycle events
|
|
1811
|
+
* (installed / uninstalled / status changed) rather than for a user session —
|
|
1812
|
+
* so {@link InstallWebhookClaims.user} is `null` for system-initiated events
|
|
1813
|
+
* that no user triggered.
|
|
1814
|
+
*/
|
|
1815
|
+
interface InstallWebhookClaims {
|
|
1816
|
+
/** Install ID — the JWT subject (`sub`). Peek-assigned UUID. */
|
|
1817
|
+
installId: string;
|
|
1818
|
+
/** The account the install belongs to. */
|
|
1819
|
+
account: InstallWebhookAccount;
|
|
1820
|
+
/** Install lifecycle status (e.g. `"installed"`, `"uninstalled"`). */
|
|
1821
|
+
status: string;
|
|
1822
|
+
/** App display version at time of issuance. Empty string when absent. */
|
|
1823
|
+
displayVersion: string;
|
|
1824
|
+
/**
|
|
1825
|
+
* The user that triggered the event, or `null` for system-initiated events
|
|
1826
|
+
* (the whole point of a distinct type from {@link PeekAuthTokenClaims}).
|
|
1827
|
+
*/
|
|
1828
|
+
user: PeekAuthTokenUser | null;
|
|
1829
|
+
}
|
|
1800
1830
|
|
|
1801
1831
|
/**
|
|
1802
1832
|
* Configuration for a {@link PeekAccessService} instance. Extends the shared
|
|
@@ -2054,8 +2084,6 @@ declare class RestClient$1 {
|
|
|
2054
2084
|
* @throws {CngApiError} on any other non-2xx response
|
|
2055
2085
|
*/
|
|
2056
2086
|
get<T>(path: string): Promise<T>;
|
|
2057
|
-
/** Reads the response body as JSON, falling back to raw text when unparseable. */
|
|
2058
|
-
private parseBody;
|
|
2059
2087
|
private endpoint;
|
|
2060
2088
|
private buildHeaders;
|
|
2061
2089
|
}
|
|
@@ -2183,8 +2211,6 @@ declare class RestClient {
|
|
|
2183
2211
|
* @throws {AcmeApiError} on any other non-2xx response
|
|
2184
2212
|
*/
|
|
2185
2213
|
get<T>(path: string): Promise<T>;
|
|
2186
|
-
/** Reads the response body as JSON, falling back to raw text when unparseable. */
|
|
2187
|
-
private parseBody;
|
|
2188
2214
|
private endpoint;
|
|
2189
2215
|
private buildHeaders;
|
|
2190
2216
|
}
|
|
@@ -2366,6 +2392,29 @@ interface Waiver {
|
|
|
2366
2392
|
*/
|
|
2367
2393
|
declare function parseWaiverWebhook(payload: unknown, options?: AccessOptions): Waiver;
|
|
2368
2394
|
|
|
2395
|
+
/**
|
|
2396
|
+
* Verifies an install-status webhook token and returns its clean claims.
|
|
2397
|
+
*
|
|
2398
|
+
* Validates the HMAC signature (with `secret`), the token expiry, the
|
|
2399
|
+
* `"app_registry_v2"` issuer, and the `"Joken"` audience — the same checks as
|
|
2400
|
+
* {@link PeekAccessService.verifyPeekAuthToken} — then maps the payload to
|
|
2401
|
+
* {@link InstallWebhookClaims}, tolerating a `null` `user` (system events).
|
|
2402
|
+
* Throws from the `jsonwebtoken` library on any verification failure, so callers
|
|
2403
|
+
* can branch on the error kind:
|
|
2404
|
+
*
|
|
2405
|
+
* - `JsonWebTokenError` — signature invalid, wrong issuer/audience, or malformed
|
|
2406
|
+
* - `TokenExpiredError` — past `exp`
|
|
2407
|
+
* - `NotBeforeError` — before `nbf`
|
|
2408
|
+
*
|
|
2409
|
+
* @param token the raw JWT delivered by the install webhook (no `Bearer` prefix)
|
|
2410
|
+
* @param secret the app's HMAC signing secret (the `jwtSecret` you construct
|
|
2411
|
+
* `PeekAccessService` with)
|
|
2412
|
+
* @throws {JsonWebTokenError} signature invalid or token malformed
|
|
2413
|
+
* @throws {TokenExpiredError} token has expired
|
|
2414
|
+
* @throws {NotBeforeError} token not yet valid
|
|
2415
|
+
*/
|
|
2416
|
+
declare function verifyInstallWebhook(token: string, secret: string): InstallWebhookClaims;
|
|
2417
|
+
|
|
2369
2418
|
/**
|
|
2370
2419
|
* Typed errors thrown by the package. Each mirrors a failure mode of the Peek
|
|
2371
2420
|
* GraphQL gateway (or the CNG REST gateway) so callers can branch on the error
|
|
@@ -2402,6 +2451,28 @@ declare class PeekGraphQLError extends Error {
|
|
|
2402
2451
|
readonly graphqlErrors: unknown[];
|
|
2403
2452
|
constructor(graphqlErrors: unknown[], message?: string);
|
|
2404
2453
|
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Thrown when the Peek GraphQL gateway returns a non-2xx HTTP response that is
|
|
2456
|
+
* not one of the specifically-handled statuses (418/429) and does not carry a
|
|
2457
|
+
* GraphQL `errors` array. This is the transport-level failure — a `401`
|
|
2458
|
+
* (auth/secret wrong), `404` (wrong app id / not provisioned), `5xx`, etc. —
|
|
2459
|
+
* as opposed to {@link PeekGraphQLError}, which is a resolver-level failure
|
|
2460
|
+
* reported inside an otherwise-successful HTTP response.
|
|
2461
|
+
*
|
|
2462
|
+
* The offending status is preserved on {@link PeekHttpError.statusCode}, the
|
|
2463
|
+
* request URL on {@link PeekHttpError.url}, and the raw response body (parsed
|
|
2464
|
+
* JSON when possible, otherwise the raw text) on {@link PeekHttpError.body} — so
|
|
2465
|
+
* callers can tell "which config is wrong" without disassembling the bundle.
|
|
2466
|
+
*/
|
|
2467
|
+
declare class PeekHttpError extends Error {
|
|
2468
|
+
/** The HTTP status that triggered this error. */
|
|
2469
|
+
readonly statusCode: number;
|
|
2470
|
+
/** The request URL that produced the failing response. */
|
|
2471
|
+
readonly url: string;
|
|
2472
|
+
/** The raw response body (parsed JSON when possible, otherwise text). */
|
|
2473
|
+
readonly body: unknown;
|
|
2474
|
+
constructor(statusCode: number, url: string, body: unknown, message?: string);
|
|
2475
|
+
}
|
|
2405
2476
|
/**
|
|
2406
2477
|
* Thrown when a payment or booking-modification operation is called on an
|
|
2407
2478
|
* access service that was constructed without `fullCustomerAccess` (PII access
|
|
@@ -2442,4 +2513,4 @@ declare class AcmeApiError extends Error {
|
|
|
2442
2513
|
constructor(statusCode: number, body: unknown, message?: string);
|
|
2443
2514
|
}
|
|
2444
2515
|
|
|
2445
|
-
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, 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, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, 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, noopLogger, parseBookingWebhook, parseWaiverWebhook };
|
|
2516
|
+
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, 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, 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, noopLogger, parseBookingWebhook, parseWaiverWebhook, verifyInstallWebhook };
|
package/dist/index.d.ts
CHANGED
|
@@ -1797,6 +1797,36 @@ interface PeekAuthTokenClaims {
|
|
|
1797
1797
|
/** Authenticated user context. */
|
|
1798
1798
|
user: PeekAuthTokenUser;
|
|
1799
1799
|
}
|
|
1800
|
+
/** The Peek account an install belongs to, as reported on an install webhook. */
|
|
1801
|
+
interface InstallWebhookAccount {
|
|
1802
|
+
/** Peek account ID that owns the install. */
|
|
1803
|
+
id: string;
|
|
1804
|
+
}
|
|
1805
|
+
/**
|
|
1806
|
+
* Claims returned by `verifyInstallWebhook` — the decoded, signature-verified
|
|
1807
|
+
* install-status webhook token.
|
|
1808
|
+
*
|
|
1809
|
+
* Shares the `app_registry_v2` token family with {@link PeekAuthTokenClaims},
|
|
1810
|
+
* but is emitted by the app registry itself for install lifecycle events
|
|
1811
|
+
* (installed / uninstalled / status changed) rather than for a user session —
|
|
1812
|
+
* so {@link InstallWebhookClaims.user} is `null` for system-initiated events
|
|
1813
|
+
* that no user triggered.
|
|
1814
|
+
*/
|
|
1815
|
+
interface InstallWebhookClaims {
|
|
1816
|
+
/** Install ID — the JWT subject (`sub`). Peek-assigned UUID. */
|
|
1817
|
+
installId: string;
|
|
1818
|
+
/** The account the install belongs to. */
|
|
1819
|
+
account: InstallWebhookAccount;
|
|
1820
|
+
/** Install lifecycle status (e.g. `"installed"`, `"uninstalled"`). */
|
|
1821
|
+
status: string;
|
|
1822
|
+
/** App display version at time of issuance. Empty string when absent. */
|
|
1823
|
+
displayVersion: string;
|
|
1824
|
+
/**
|
|
1825
|
+
* The user that triggered the event, or `null` for system-initiated events
|
|
1826
|
+
* (the whole point of a distinct type from {@link PeekAuthTokenClaims}).
|
|
1827
|
+
*/
|
|
1828
|
+
user: PeekAuthTokenUser | null;
|
|
1829
|
+
}
|
|
1800
1830
|
|
|
1801
1831
|
/**
|
|
1802
1832
|
* Configuration for a {@link PeekAccessService} instance. Extends the shared
|
|
@@ -2054,8 +2084,6 @@ declare class RestClient$1 {
|
|
|
2054
2084
|
* @throws {CngApiError} on any other non-2xx response
|
|
2055
2085
|
*/
|
|
2056
2086
|
get<T>(path: string): Promise<T>;
|
|
2057
|
-
/** Reads the response body as JSON, falling back to raw text when unparseable. */
|
|
2058
|
-
private parseBody;
|
|
2059
2087
|
private endpoint;
|
|
2060
2088
|
private buildHeaders;
|
|
2061
2089
|
}
|
|
@@ -2183,8 +2211,6 @@ declare class RestClient {
|
|
|
2183
2211
|
* @throws {AcmeApiError} on any other non-2xx response
|
|
2184
2212
|
*/
|
|
2185
2213
|
get<T>(path: string): Promise<T>;
|
|
2186
|
-
/** Reads the response body as JSON, falling back to raw text when unparseable. */
|
|
2187
|
-
private parseBody;
|
|
2188
2214
|
private endpoint;
|
|
2189
2215
|
private buildHeaders;
|
|
2190
2216
|
}
|
|
@@ -2366,6 +2392,29 @@ interface Waiver {
|
|
|
2366
2392
|
*/
|
|
2367
2393
|
declare function parseWaiverWebhook(payload: unknown, options?: AccessOptions): Waiver;
|
|
2368
2394
|
|
|
2395
|
+
/**
|
|
2396
|
+
* Verifies an install-status webhook token and returns its clean claims.
|
|
2397
|
+
*
|
|
2398
|
+
* Validates the HMAC signature (with `secret`), the token expiry, the
|
|
2399
|
+
* `"app_registry_v2"` issuer, and the `"Joken"` audience — the same checks as
|
|
2400
|
+
* {@link PeekAccessService.verifyPeekAuthToken} — then maps the payload to
|
|
2401
|
+
* {@link InstallWebhookClaims}, tolerating a `null` `user` (system events).
|
|
2402
|
+
* Throws from the `jsonwebtoken` library on any verification failure, so callers
|
|
2403
|
+
* can branch on the error kind:
|
|
2404
|
+
*
|
|
2405
|
+
* - `JsonWebTokenError` — signature invalid, wrong issuer/audience, or malformed
|
|
2406
|
+
* - `TokenExpiredError` — past `exp`
|
|
2407
|
+
* - `NotBeforeError` — before `nbf`
|
|
2408
|
+
*
|
|
2409
|
+
* @param token the raw JWT delivered by the install webhook (no `Bearer` prefix)
|
|
2410
|
+
* @param secret the app's HMAC signing secret (the `jwtSecret` you construct
|
|
2411
|
+
* `PeekAccessService` with)
|
|
2412
|
+
* @throws {JsonWebTokenError} signature invalid or token malformed
|
|
2413
|
+
* @throws {TokenExpiredError} token has expired
|
|
2414
|
+
* @throws {NotBeforeError} token not yet valid
|
|
2415
|
+
*/
|
|
2416
|
+
declare function verifyInstallWebhook(token: string, secret: string): InstallWebhookClaims;
|
|
2417
|
+
|
|
2369
2418
|
/**
|
|
2370
2419
|
* Typed errors thrown by the package. Each mirrors a failure mode of the Peek
|
|
2371
2420
|
* GraphQL gateway (or the CNG REST gateway) so callers can branch on the error
|
|
@@ -2402,6 +2451,28 @@ declare class PeekGraphQLError extends Error {
|
|
|
2402
2451
|
readonly graphqlErrors: unknown[];
|
|
2403
2452
|
constructor(graphqlErrors: unknown[], message?: string);
|
|
2404
2453
|
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Thrown when the Peek GraphQL gateway returns a non-2xx HTTP response that is
|
|
2456
|
+
* not one of the specifically-handled statuses (418/429) and does not carry a
|
|
2457
|
+
* GraphQL `errors` array. This is the transport-level failure — a `401`
|
|
2458
|
+
* (auth/secret wrong), `404` (wrong app id / not provisioned), `5xx`, etc. —
|
|
2459
|
+
* as opposed to {@link PeekGraphQLError}, which is a resolver-level failure
|
|
2460
|
+
* reported inside an otherwise-successful HTTP response.
|
|
2461
|
+
*
|
|
2462
|
+
* The offending status is preserved on {@link PeekHttpError.statusCode}, the
|
|
2463
|
+
* request URL on {@link PeekHttpError.url}, and the raw response body (parsed
|
|
2464
|
+
* JSON when possible, otherwise the raw text) on {@link PeekHttpError.body} — so
|
|
2465
|
+
* callers can tell "which config is wrong" without disassembling the bundle.
|
|
2466
|
+
*/
|
|
2467
|
+
declare class PeekHttpError extends Error {
|
|
2468
|
+
/** The HTTP status that triggered this error. */
|
|
2469
|
+
readonly statusCode: number;
|
|
2470
|
+
/** The request URL that produced the failing response. */
|
|
2471
|
+
readonly url: string;
|
|
2472
|
+
/** The raw response body (parsed JSON when possible, otherwise text). */
|
|
2473
|
+
readonly body: unknown;
|
|
2474
|
+
constructor(statusCode: number, url: string, body: unknown, message?: string);
|
|
2475
|
+
}
|
|
2405
2476
|
/**
|
|
2406
2477
|
* Thrown when a payment or booking-modification operation is called on an
|
|
2407
2478
|
* access service that was constructed without `fullCustomerAccess` (PII access
|
|
@@ -2442,4 +2513,4 @@ declare class AcmeApiError extends Error {
|
|
|
2442
2513
|
constructor(statusCode: number, body: unknown, message?: string);
|
|
2443
2514
|
}
|
|
2444
2515
|
|
|
2445
|
-
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, 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, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, 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, noopLogger, parseBookingWebhook, parseWaiverWebhook };
|
|
2516
|
+
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, 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, 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, noopLogger, parseBookingWebhook, parseWaiverWebhook, verifyInstallWebhook };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import * as jwt from 'jsonwebtoken';
|
|
2
1
|
import { randomUUID } from 'crypto';
|
|
3
|
-
|
|
4
|
-
// src/peek-access-service.ts
|
|
2
|
+
import * as jwt from 'jsonwebtoken';
|
|
5
3
|
|
|
6
4
|
// src/internal/peek/gateway-endpoints.ts
|
|
7
5
|
var SALES_ENDPOINT = "sales";
|
|
@@ -212,6 +210,21 @@ var PeekGraphQLError = class extends Error {
|
|
|
212
210
|
this.graphqlErrors = graphqlErrors;
|
|
213
211
|
}
|
|
214
212
|
};
|
|
213
|
+
var PeekHttpError = class extends Error {
|
|
214
|
+
/** The HTTP status that triggered this error. */
|
|
215
|
+
statusCode;
|
|
216
|
+
/** The request URL that produced the failing response. */
|
|
217
|
+
url;
|
|
218
|
+
/** The raw response body (parsed JSON when possible, otherwise text). */
|
|
219
|
+
body;
|
|
220
|
+
constructor(statusCode, url, body, message) {
|
|
221
|
+
super(message ?? `Peek request failed with HTTP ${statusCode}`);
|
|
222
|
+
this.name = "PeekHttpError";
|
|
223
|
+
this.statusCode = statusCode;
|
|
224
|
+
this.url = url;
|
|
225
|
+
this.body = body;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
215
228
|
var PiiAccessDisabledError = class extends Error {
|
|
216
229
|
/** The name of the operation that was blocked (e.g. `"makePayment"`). */
|
|
217
230
|
operation;
|
|
@@ -1922,6 +1935,14 @@ function createTokenManager(config) {
|
|
|
1922
1935
|
var RATE_LIMIT_STATUS = 429;
|
|
1923
1936
|
var ADMIN_ACCOUNT_REQUIRED_STATUS = 418;
|
|
1924
1937
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1938
|
+
async function parseBody(response) {
|
|
1939
|
+
const text = await response.text();
|
|
1940
|
+
try {
|
|
1941
|
+
return JSON.parse(text);
|
|
1942
|
+
} catch {
|
|
1943
|
+
return text;
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1925
1946
|
async function requestWithRetry(http, url, init, label, onResponse) {
|
|
1926
1947
|
const { retryDelaysMs, logger, fetchFn } = http;
|
|
1927
1948
|
for (let attempt = 0; attempt <= retryDelaysMs.length; attempt++) {
|
|
@@ -1948,6 +1969,7 @@ async function requestWithRetry(http, url, init, label, onResponse) {
|
|
|
1948
1969
|
}
|
|
1949
1970
|
|
|
1950
1971
|
// src/internal/peek/graphql-client.ts
|
|
1972
|
+
var isObject = (value) => typeof value === "object" && value !== null;
|
|
1951
1973
|
var GraphQLClient = class {
|
|
1952
1974
|
constructor(options) {
|
|
1953
1975
|
this.options = options;
|
|
@@ -1973,7 +1995,8 @@ var GraphQLClient = class {
|
|
|
1973
1995
|
},
|
|
1974
1996
|
endpointName,
|
|
1975
1997
|
async (response) => {
|
|
1976
|
-
const
|
|
1998
|
+
const raw = await parseBody(response);
|
|
1999
|
+
const body = isObject(raw) ? raw : {};
|
|
1977
2000
|
if (body.errors) {
|
|
1978
2001
|
logger.error(`GraphQL errors for ${endpointName}`, {
|
|
1979
2002
|
url,
|
|
@@ -1983,7 +2006,7 @@ var GraphQLClient = class {
|
|
|
1983
2006
|
}
|
|
1984
2007
|
if (!response.ok) {
|
|
1985
2008
|
logger.error(`GraphQL request failed with HTTP ${response.status}`, { url });
|
|
1986
|
-
throw new
|
|
2009
|
+
throw new PeekHttpError(response.status, url, raw);
|
|
1987
2010
|
}
|
|
1988
2011
|
return body;
|
|
1989
2012
|
}
|
|
@@ -2005,6 +2028,24 @@ var GraphQLClient = class {
|
|
|
2005
2028
|
return headers;
|
|
2006
2029
|
}
|
|
2007
2030
|
};
|
|
2031
|
+
var PEEK_TOKEN_ISSUER = "app_registry_v2";
|
|
2032
|
+
var PEEK_TOKEN_AUDIENCE = "Joken";
|
|
2033
|
+
function verifyPeekJwt(token, secret) {
|
|
2034
|
+
return jwt.verify(token, secret, {
|
|
2035
|
+
issuer: PEEK_TOKEN_ISSUER,
|
|
2036
|
+
audience: PEEK_TOKEN_AUDIENCE
|
|
2037
|
+
});
|
|
2038
|
+
}
|
|
2039
|
+
function mapPeekTokenUser(u) {
|
|
2040
|
+
return {
|
|
2041
|
+
email: u.email,
|
|
2042
|
+
id: u.id,
|
|
2043
|
+
isAdmin: u.is_admin,
|
|
2044
|
+
locale: u.locale,
|
|
2045
|
+
name: u.name,
|
|
2046
|
+
platform: u.platform
|
|
2047
|
+
};
|
|
2048
|
+
}
|
|
2008
2049
|
|
|
2009
2050
|
// src/internal/peek/memberships/membership-converter.ts
|
|
2010
2051
|
function fromMembershipsResponse(response) {
|
|
@@ -2473,10 +2514,17 @@ function fromTimeslotNode(node, productId) {
|
|
|
2473
2514
|
durationMin: node.minuteLength ?? 0,
|
|
2474
2515
|
date: node.date || "",
|
|
2475
2516
|
startTime: node.start ?? null,
|
|
2476
|
-
assignedResources: mapAssignedResources(node
|
|
2517
|
+
assignedResources: mapAssignedResources(selectResourceAllocations(node))
|
|
2477
2518
|
};
|
|
2478
2519
|
}
|
|
2479
2520
|
var ACTIVE_ALLOCATION_STATUS = "ACTIVE";
|
|
2521
|
+
function selectResourceAllocations(node) {
|
|
2522
|
+
const inherited = node.inheritedResourceAllocations;
|
|
2523
|
+
if (Array.isArray(inherited) && inherited.length > 0) {
|
|
2524
|
+
return inherited;
|
|
2525
|
+
}
|
|
2526
|
+
return node.resourceAllocations;
|
|
2527
|
+
}
|
|
2480
2528
|
function mapAssignedResources(allocations) {
|
|
2481
2529
|
if (!Array.isArray(allocations) || allocations.length === 0) {
|
|
2482
2530
|
return [];
|
|
@@ -2563,9 +2611,24 @@ var TIMESLOTS_QUERY = `
|
|
|
2563
2611
|
status
|
|
2564
2612
|
date
|
|
2565
2613
|
inheritedResourceAllocations {
|
|
2614
|
+
id
|
|
2615
|
+
status
|
|
2616
|
+
quantity
|
|
2617
|
+
resourcePool {
|
|
2618
|
+
id
|
|
2619
|
+
name
|
|
2620
|
+
category
|
|
2621
|
+
capacity
|
|
2622
|
+
accountUser {
|
|
2623
|
+
id
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
resourceAllocations {
|
|
2566
2628
|
quantity
|
|
2567
2629
|
status
|
|
2568
2630
|
resourcePool {
|
|
2631
|
+
id
|
|
2569
2632
|
name
|
|
2570
2633
|
category
|
|
2571
2634
|
capacity
|
|
@@ -2601,9 +2664,24 @@ var TIMESLOT_BY_ID_QUERY = `
|
|
|
2601
2664
|
status
|
|
2602
2665
|
date
|
|
2603
2666
|
inheritedResourceAllocations {
|
|
2667
|
+
id
|
|
2668
|
+
status
|
|
2669
|
+
quantity
|
|
2670
|
+
resourcePool {
|
|
2671
|
+
id
|
|
2672
|
+
name
|
|
2673
|
+
category
|
|
2674
|
+
capacity
|
|
2675
|
+
accountUser {
|
|
2676
|
+
id
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
resourceAllocations {
|
|
2604
2681
|
quantity
|
|
2605
2682
|
status
|
|
2606
2683
|
resourcePool {
|
|
2684
|
+
id
|
|
2607
2685
|
name
|
|
2608
2686
|
category
|
|
2609
2687
|
capacity
|
|
@@ -3408,7 +3486,6 @@ var noopLogger = {
|
|
|
3408
3486
|
// src/peek-access-service.ts
|
|
3409
3487
|
var DEFAULT_BASE_URL = "https://apps.peekapis.com/backoffice-gql";
|
|
3410
3488
|
var DEFAULT_V2_BASE_URL = "https://app-registry.peeklabs.com/installations-api";
|
|
3411
|
-
var PEEK_TOKEN_ISSUER = "app_registry_v2";
|
|
3412
3489
|
var PeekAccessService = class {
|
|
3413
3490
|
client;
|
|
3414
3491
|
productServiceOptions;
|
|
@@ -3471,21 +3548,11 @@ var PeekAccessService = class {
|
|
|
3471
3548
|
* @throws {NotBeforeError} token not yet valid
|
|
3472
3549
|
*/
|
|
3473
3550
|
verifyPeekAuthToken(token) {
|
|
3474
|
-
const payload =
|
|
3475
|
-
issuer: PEEK_TOKEN_ISSUER
|
|
3476
|
-
});
|
|
3477
|
-
const { user: u } = payload;
|
|
3551
|
+
const payload = verifyPeekJwt(token, this.jwtSecret);
|
|
3478
3552
|
return {
|
|
3479
3553
|
installId: payload.sub,
|
|
3480
3554
|
displayVersion: payload.display_version,
|
|
3481
|
-
user:
|
|
3482
|
-
email: u.email,
|
|
3483
|
-
id: u.id,
|
|
3484
|
-
isAdmin: u.is_admin,
|
|
3485
|
-
locale: u.locale,
|
|
3486
|
-
name: u.name,
|
|
3487
|
-
platform: u.platform
|
|
3488
|
-
}
|
|
3555
|
+
user: mapPeekTokenUser(payload.user)
|
|
3489
3556
|
};
|
|
3490
3557
|
}
|
|
3491
3558
|
/**
|
|
@@ -3869,7 +3936,7 @@ var RestClient = class {
|
|
|
3869
3936
|
{ method: "GET", headers: this.buildHeaders() },
|
|
3870
3937
|
path,
|
|
3871
3938
|
async (response) => {
|
|
3872
|
-
const body = await
|
|
3939
|
+
const body = await parseBody(response);
|
|
3873
3940
|
if (!response.ok) {
|
|
3874
3941
|
logger.error(`CNG request failed with HTTP ${response.status}`, { url });
|
|
3875
3942
|
throw new CngApiError(response.status, body);
|
|
@@ -3878,15 +3945,6 @@ var RestClient = class {
|
|
|
3878
3945
|
}
|
|
3879
3946
|
);
|
|
3880
3947
|
}
|
|
3881
|
-
/** Reads the response body as JSON, falling back to raw text when unparseable. */
|
|
3882
|
-
async parseBody(response) {
|
|
3883
|
-
const text = await response.text();
|
|
3884
|
-
try {
|
|
3885
|
-
return JSON.parse(text);
|
|
3886
|
-
} catch {
|
|
3887
|
-
return text;
|
|
3888
|
-
}
|
|
3889
|
-
}
|
|
3890
3948
|
endpoint(path) {
|
|
3891
3949
|
const { baseUrl, appId, extendableSlug } = this.options;
|
|
3892
3950
|
return `${baseUrl}/${appId}/${extendableSlug}/${path}`;
|
|
@@ -4009,7 +4067,7 @@ var RestClient2 = class {
|
|
|
4009
4067
|
{ method: "GET", headers: this.buildHeaders() },
|
|
4010
4068
|
path,
|
|
4011
4069
|
async (response) => {
|
|
4012
|
-
const body = await
|
|
4070
|
+
const body = await parseBody(response);
|
|
4013
4071
|
if (!response.ok) {
|
|
4014
4072
|
logger.error(`ACME request failed with HTTP ${response.status}`, { url });
|
|
4015
4073
|
throw new AcmeApiError(response.status, body);
|
|
@@ -4018,15 +4076,6 @@ var RestClient2 = class {
|
|
|
4018
4076
|
}
|
|
4019
4077
|
);
|
|
4020
4078
|
}
|
|
4021
|
-
/** Reads the response body as JSON, falling back to raw text when unparseable. */
|
|
4022
|
-
async parseBody(response) {
|
|
4023
|
-
const text = await response.text();
|
|
4024
|
-
try {
|
|
4025
|
-
return JSON.parse(text);
|
|
4026
|
-
} catch {
|
|
4027
|
-
return text;
|
|
4028
|
-
}
|
|
4029
|
-
}
|
|
4030
4079
|
endpoint(path) {
|
|
4031
4080
|
const { baseUrl, appId, extendableSlug } = this.options;
|
|
4032
4081
|
return `${baseUrl}/${appId}/${extendableSlug}/${path}`;
|
|
@@ -4167,6 +4216,18 @@ function extractWaiverNode(payload) {
|
|
|
4167
4216
|
return record;
|
|
4168
4217
|
}
|
|
4169
4218
|
|
|
4170
|
-
|
|
4219
|
+
// src/internal/peek/installs/install-webhook.ts
|
|
4220
|
+
function verifyInstallWebhook(token, secret) {
|
|
4221
|
+
const payload = verifyPeekJwt(token, secret);
|
|
4222
|
+
return {
|
|
4223
|
+
installId: payload.sub ?? "",
|
|
4224
|
+
account: { id: payload.account?.id ?? "" },
|
|
4225
|
+
status: payload.status ?? "",
|
|
4226
|
+
displayVersion: payload.display_version ?? "",
|
|
4227
|
+
user: payload.user ? mapPeekTokenUser(payload.user) : null
|
|
4228
|
+
};
|
|
4229
|
+
}
|
|
4230
|
+
|
|
4231
|
+
export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, AccountUserService, AcmeAccessService, AcmeApiError, AcmeProductService, AdminAccountRequiredError, AvailabilityService, BookingService, CngAccessService, CngApiError, CngProductService, DailyNoteService, MembershipService, PeekAccessService, PeekGraphQLError, PeekHttpError, PiiAccessDisabledError, PricingService, ProductService, PromoCodeService, RENTAL_PRODUCT_TYPE, RateLimitError, ResellerService, ResourcePoolService, ReviewService, TimeslotService, noopLogger, parseBookingWebhook, parseWaiverWebhook, verifyInstallWebhook };
|
|
4171
4232
|
//# sourceMappingURL=index.js.map
|
|
4172
4233
|
//# sourceMappingURL=index.js.map
|