@peektravel/app-utilities 0.9.0 → 0.9.1
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 +6 -3
- package/dist/index.cjs +72 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -55
- package/dist/index.d.ts +58 -55
- package/dist/index.js +72 -31
- package/dist/index.js.map +1 -1
- package/docs/webhooks.md +11 -8
- package/llms.txt +15 -8
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A platform's tiny map of **API endpoint key → relative path** (the "slug"
|
|
3
|
+
* inserted between the install's base API URL and the endpoint's own path).
|
|
4
|
+
*
|
|
5
|
+
* The base API URL is the install's app endpoint with no routing segment — the
|
|
6
|
+
* install webhook's `apiUrl` (with any slug stripped back off), or
|
|
7
|
+
* `baseUrl/appId` when built from the deprecated defaults. Each service class
|
|
8
|
+
* resolves *its own* slug through this lookup, so two services on the same
|
|
9
|
+
* platform can route through different slugs. Adding a new API — even one on a
|
|
10
|
+
* different slug than its siblings — is a single entry here.
|
|
11
|
+
*
|
|
12
|
+
* An empty-string path means the endpoint sits directly on the base with no
|
|
13
|
+
* slug (e.g. the legacy Peek v1 GraphQL gateway, which has no extendable slug).
|
|
14
|
+
*/
|
|
15
|
+
declare class ApiEndpoints<Key extends string = string> {
|
|
16
|
+
private readonly paths;
|
|
17
|
+
constructor(paths: Readonly<Record<Key, string>>);
|
|
18
|
+
/** The relative path (slug) for `endpoint`, appended to the base API URL. */
|
|
19
|
+
pathFor(endpoint: Key): string;
|
|
20
|
+
}
|
|
21
|
+
|
|
1
22
|
/**
|
|
2
23
|
* Minimal structured logger interface the package can write diagnostics to.
|
|
3
24
|
*
|
|
@@ -20,19 +41,13 @@ interface GraphQLBody<T> {
|
|
|
20
41
|
}
|
|
21
42
|
interface GraphQLClientOptions {
|
|
22
43
|
/**
|
|
23
|
-
* The install's
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* construction. Takes precedence over `baseUrl`.
|
|
44
|
+
* The install's **base API URL** (no trailing slash, no routing slug). Every
|
|
45
|
+
* GraphQL call POSTs to `baseApiUrl/<slug>`, where the slug comes from
|
|
46
|
+
* {@link endpoints} for the request's endpoint name.
|
|
27
47
|
*/
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
* when `apiUrl` is not set; the URL is `baseUrl/appId/[prefix/]endpointName`.
|
|
32
|
-
*/
|
|
33
|
-
baseUrl?: string;
|
|
34
|
-
/** Peek app ID, used in the endpoint path (legacy `baseUrl` mode only). */
|
|
35
|
-
appId?: string;
|
|
48
|
+
baseApiUrl: string;
|
|
49
|
+
/** Maps an endpoint name to the relative slug appended to {@link baseApiUrl}. */
|
|
50
|
+
endpoints: ApiEndpoints;
|
|
36
51
|
/** API gateway key sent as the `pk-api-key` header. Omitted from headers when absent (v2 mode). */
|
|
37
52
|
gatewayKey?: string;
|
|
38
53
|
/** Supplies a valid bearer token for each request. */
|
|
@@ -43,11 +58,6 @@ interface GraphQLClientOptions {
|
|
|
43
58
|
logger: Logger;
|
|
44
59
|
/** `fetch` implementation to use. */
|
|
45
60
|
fetchFn: typeof fetch;
|
|
46
|
-
/**
|
|
47
|
-
* Optional fixed path segment inserted between `appId` and the endpoint name.
|
|
48
|
-
* Used in v2 mode: `baseUrl/appId/endpointPathPrefix/endpointName`.
|
|
49
|
-
*/
|
|
50
|
-
endpointPathPrefix?: string;
|
|
51
61
|
}
|
|
52
62
|
declare class GraphQLClient {
|
|
53
63
|
private readonly options;
|
|
@@ -1671,13 +1681,17 @@ interface BaseAccessServiceConfig {
|
|
|
1671
1681
|
/** JWT issuer — the app name / app ID. */
|
|
1672
1682
|
issuer: string;
|
|
1673
1683
|
/**
|
|
1674
|
-
* The install's **
|
|
1675
|
-
*
|
|
1676
|
-
*
|
|
1677
|
-
*
|
|
1678
|
-
*
|
|
1679
|
-
* it
|
|
1680
|
-
*
|
|
1684
|
+
* The install's **base API URL** — persist the install webhook's `apiUrl` and
|
|
1685
|
+
* pass it here. It is the app endpoint with no per-platform routing slug; each
|
|
1686
|
+
* service class appends its own slug (e.g. `peek_backoffice_api-v1`, via that
|
|
1687
|
+
* platform's endpoint lookup) when it makes a call, so different services can
|
|
1688
|
+
* route through different slugs. If the URL you pass still carries this
|
|
1689
|
+
* platform's slug it is stripped back off to recover the base; a URL carrying a
|
|
1690
|
+
* *different* platform's slug makes the constructor throw. No app-id/gateway
|
|
1691
|
+
* segment is inserted, so `appId` is not required. This is the forward-looking
|
|
1692
|
+
* way to target an install — prefer it over `baseUrl`/`appId`, which are
|
|
1693
|
+
* deprecated (the hardcoded base-URL fallbacks will be removed and a URL will
|
|
1694
|
+
* become required in a future release).
|
|
1681
1695
|
*/
|
|
1682
1696
|
apiUrl?: string;
|
|
1683
1697
|
/**
|
|
@@ -2266,21 +2280,13 @@ declare class PeekAccessService {
|
|
|
2266
2280
|
|
|
2267
2281
|
interface RestClientOptions$1 {
|
|
2268
2282
|
/**
|
|
2269
|
-
* The install's
|
|
2270
|
-
*
|
|
2271
|
-
*
|
|
2272
|
-
* `baseUrl`.
|
|
2283
|
+
* The install's **base API URL** (no trailing slash, no routing slug). Each
|
|
2284
|
+
* request builds `baseApiUrl/<slug>/<path>`, where the slug comes from
|
|
2285
|
+
* {@link endpoints} for the request's endpoint key.
|
|
2273
2286
|
*/
|
|
2274
|
-
|
|
2275
|
-
/**
|
|
2276
|
-
|
|
2277
|
-
* `apiUrl` is not set; the URL is `baseUrl/appId/extendableSlug/path`.
|
|
2278
|
-
*/
|
|
2279
|
-
baseUrl?: string;
|
|
2280
|
-
/** App ID, used in the endpoint path (legacy `baseUrl` mode only). */
|
|
2281
|
-
appId?: string;
|
|
2282
|
-
/** Fixed extendable slug inserted between `appId` and the REST path (legacy mode). */
|
|
2283
|
-
extendableSlug?: string;
|
|
2287
|
+
baseApiUrl: string;
|
|
2288
|
+
/** Maps an endpoint key to the relative slug appended to {@link baseApiUrl}. */
|
|
2289
|
+
endpoints: ApiEndpoints;
|
|
2284
2290
|
/** Supplies a valid bearer token for each request. */
|
|
2285
2291
|
getToken: () => string;
|
|
2286
2292
|
/** Backoff delays (ms) applied on successive HTTP 429 responses. */
|
|
@@ -2303,7 +2309,7 @@ declare class RestClient$1 {
|
|
|
2303
2309
|
* @throws {CngPermissionError} on HTTP 403 (app missing a permission)
|
|
2304
2310
|
* @throws {CngApiError} on any other non-2xx response
|
|
2305
2311
|
*/
|
|
2306
|
-
get<T>(path: string): Promise<T>;
|
|
2312
|
+
get<T>(endpoint: string, path: string): Promise<T>;
|
|
2307
2313
|
private endpoint;
|
|
2308
2314
|
private buildHeaders;
|
|
2309
2315
|
}
|
|
@@ -2411,21 +2417,13 @@ declare class CngAccessService {
|
|
|
2411
2417
|
|
|
2412
2418
|
interface RestClientOptions {
|
|
2413
2419
|
/**
|
|
2414
|
-
* The install's
|
|
2415
|
-
*
|
|
2416
|
-
*
|
|
2417
|
-
* `baseUrl`.
|
|
2418
|
-
*/
|
|
2419
|
-
apiUrl?: string;
|
|
2420
|
-
/**
|
|
2421
|
-
* Base URL of the backoffice gateway (no trailing slash). Used only when
|
|
2422
|
-
* `apiUrl` is not set; the URL is `baseUrl/appId/extendableSlug/path`.
|
|
2420
|
+
* The install's **base API URL** (no trailing slash, no routing slug). Each
|
|
2421
|
+
* request builds `baseApiUrl/<slug>/<path>`, where the slug comes from
|
|
2422
|
+
* {@link endpoints} for the request's endpoint key.
|
|
2423
2423
|
*/
|
|
2424
|
-
|
|
2425
|
-
/**
|
|
2426
|
-
|
|
2427
|
-
/** Fixed extendable slug inserted between `appId` and the REST path (legacy mode). */
|
|
2428
|
-
extendableSlug?: string;
|
|
2424
|
+
baseApiUrl: string;
|
|
2425
|
+
/** Maps an endpoint key to the relative slug appended to {@link baseApiUrl}. */
|
|
2426
|
+
endpoints: ApiEndpoints;
|
|
2429
2427
|
/** Supplies a valid bearer token for each request. */
|
|
2430
2428
|
getToken: () => string;
|
|
2431
2429
|
/** Backoff delays (ms) applied on successive HTTP 429 responses. */
|
|
@@ -2447,7 +2445,7 @@ declare class RestClient {
|
|
|
2447
2445
|
* @throws {RateLimitError} on HTTP 429 after retries are exhausted
|
|
2448
2446
|
* @throws {AcmeApiError} on any other non-2xx response
|
|
2449
2447
|
*/
|
|
2450
|
-
get<T>(path: string): Promise<T>;
|
|
2448
|
+
get<T>(endpoint: string, path: string): Promise<T>;
|
|
2451
2449
|
private endpoint;
|
|
2452
2450
|
private buildHeaders;
|
|
2453
2451
|
}
|
|
@@ -2565,7 +2563,12 @@ declare class AcmeAccessService {
|
|
|
2565
2563
|
interface InstallAccessTarget {
|
|
2566
2564
|
/** Which platform serves the install (the install webhook's `platform`). */
|
|
2567
2565
|
platform: PeekPlatform | null;
|
|
2568
|
-
/**
|
|
2566
|
+
/**
|
|
2567
|
+
* The install's base API URL (the install webhook's `apiUrl`). The chosen
|
|
2568
|
+
* access service's service classes append their own backoffice slug when they
|
|
2569
|
+
* call; a URL already carrying this platform's slug is stripped back to the
|
|
2570
|
+
* base, and one carrying a different platform's slug throws.
|
|
2571
|
+
*/
|
|
2569
2572
|
apiUrl: string;
|
|
2570
2573
|
/** The install id (the install webhook's `installId`) — becomes the JWT subject. */
|
|
2571
2574
|
installId: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A platform's tiny map of **API endpoint key → relative path** (the "slug"
|
|
3
|
+
* inserted between the install's base API URL and the endpoint's own path).
|
|
4
|
+
*
|
|
5
|
+
* The base API URL is the install's app endpoint with no routing segment — the
|
|
6
|
+
* install webhook's `apiUrl` (with any slug stripped back off), or
|
|
7
|
+
* `baseUrl/appId` when built from the deprecated defaults. Each service class
|
|
8
|
+
* resolves *its own* slug through this lookup, so two services on the same
|
|
9
|
+
* platform can route through different slugs. Adding a new API — even one on a
|
|
10
|
+
* different slug than its siblings — is a single entry here.
|
|
11
|
+
*
|
|
12
|
+
* An empty-string path means the endpoint sits directly on the base with no
|
|
13
|
+
* slug (e.g. the legacy Peek v1 GraphQL gateway, which has no extendable slug).
|
|
14
|
+
*/
|
|
15
|
+
declare class ApiEndpoints<Key extends string = string> {
|
|
16
|
+
private readonly paths;
|
|
17
|
+
constructor(paths: Readonly<Record<Key, string>>);
|
|
18
|
+
/** The relative path (slug) for `endpoint`, appended to the base API URL. */
|
|
19
|
+
pathFor(endpoint: Key): string;
|
|
20
|
+
}
|
|
21
|
+
|
|
1
22
|
/**
|
|
2
23
|
* Minimal structured logger interface the package can write diagnostics to.
|
|
3
24
|
*
|
|
@@ -20,19 +41,13 @@ interface GraphQLBody<T> {
|
|
|
20
41
|
}
|
|
21
42
|
interface GraphQLClientOptions {
|
|
22
43
|
/**
|
|
23
|
-
* The install's
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* construction. Takes precedence over `baseUrl`.
|
|
44
|
+
* The install's **base API URL** (no trailing slash, no routing slug). Every
|
|
45
|
+
* GraphQL call POSTs to `baseApiUrl/<slug>`, where the slug comes from
|
|
46
|
+
* {@link endpoints} for the request's endpoint name.
|
|
27
47
|
*/
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
* when `apiUrl` is not set; the URL is `baseUrl/appId/[prefix/]endpointName`.
|
|
32
|
-
*/
|
|
33
|
-
baseUrl?: string;
|
|
34
|
-
/** Peek app ID, used in the endpoint path (legacy `baseUrl` mode only). */
|
|
35
|
-
appId?: string;
|
|
48
|
+
baseApiUrl: string;
|
|
49
|
+
/** Maps an endpoint name to the relative slug appended to {@link baseApiUrl}. */
|
|
50
|
+
endpoints: ApiEndpoints;
|
|
36
51
|
/** API gateway key sent as the `pk-api-key` header. Omitted from headers when absent (v2 mode). */
|
|
37
52
|
gatewayKey?: string;
|
|
38
53
|
/** Supplies a valid bearer token for each request. */
|
|
@@ -43,11 +58,6 @@ interface GraphQLClientOptions {
|
|
|
43
58
|
logger: Logger;
|
|
44
59
|
/** `fetch` implementation to use. */
|
|
45
60
|
fetchFn: typeof fetch;
|
|
46
|
-
/**
|
|
47
|
-
* Optional fixed path segment inserted between `appId` and the endpoint name.
|
|
48
|
-
* Used in v2 mode: `baseUrl/appId/endpointPathPrefix/endpointName`.
|
|
49
|
-
*/
|
|
50
|
-
endpointPathPrefix?: string;
|
|
51
61
|
}
|
|
52
62
|
declare class GraphQLClient {
|
|
53
63
|
private readonly options;
|
|
@@ -1671,13 +1681,17 @@ interface BaseAccessServiceConfig {
|
|
|
1671
1681
|
/** JWT issuer — the app name / app ID. */
|
|
1672
1682
|
issuer: string;
|
|
1673
1683
|
/**
|
|
1674
|
-
* The install's **
|
|
1675
|
-
*
|
|
1676
|
-
*
|
|
1677
|
-
*
|
|
1678
|
-
*
|
|
1679
|
-
* it
|
|
1680
|
-
*
|
|
1684
|
+
* The install's **base API URL** — persist the install webhook's `apiUrl` and
|
|
1685
|
+
* pass it here. It is the app endpoint with no per-platform routing slug; each
|
|
1686
|
+
* service class appends its own slug (e.g. `peek_backoffice_api-v1`, via that
|
|
1687
|
+
* platform's endpoint lookup) when it makes a call, so different services can
|
|
1688
|
+
* route through different slugs. If the URL you pass still carries this
|
|
1689
|
+
* platform's slug it is stripped back off to recover the base; a URL carrying a
|
|
1690
|
+
* *different* platform's slug makes the constructor throw. No app-id/gateway
|
|
1691
|
+
* segment is inserted, so `appId` is not required. This is the forward-looking
|
|
1692
|
+
* way to target an install — prefer it over `baseUrl`/`appId`, which are
|
|
1693
|
+
* deprecated (the hardcoded base-URL fallbacks will be removed and a URL will
|
|
1694
|
+
* become required in a future release).
|
|
1681
1695
|
*/
|
|
1682
1696
|
apiUrl?: string;
|
|
1683
1697
|
/**
|
|
@@ -2266,21 +2280,13 @@ declare class PeekAccessService {
|
|
|
2266
2280
|
|
|
2267
2281
|
interface RestClientOptions$1 {
|
|
2268
2282
|
/**
|
|
2269
|
-
* The install's
|
|
2270
|
-
*
|
|
2271
|
-
*
|
|
2272
|
-
* `baseUrl`.
|
|
2283
|
+
* The install's **base API URL** (no trailing slash, no routing slug). Each
|
|
2284
|
+
* request builds `baseApiUrl/<slug>/<path>`, where the slug comes from
|
|
2285
|
+
* {@link endpoints} for the request's endpoint key.
|
|
2273
2286
|
*/
|
|
2274
|
-
|
|
2275
|
-
/**
|
|
2276
|
-
|
|
2277
|
-
* `apiUrl` is not set; the URL is `baseUrl/appId/extendableSlug/path`.
|
|
2278
|
-
*/
|
|
2279
|
-
baseUrl?: string;
|
|
2280
|
-
/** App ID, used in the endpoint path (legacy `baseUrl` mode only). */
|
|
2281
|
-
appId?: string;
|
|
2282
|
-
/** Fixed extendable slug inserted between `appId` and the REST path (legacy mode). */
|
|
2283
|
-
extendableSlug?: string;
|
|
2287
|
+
baseApiUrl: string;
|
|
2288
|
+
/** Maps an endpoint key to the relative slug appended to {@link baseApiUrl}. */
|
|
2289
|
+
endpoints: ApiEndpoints;
|
|
2284
2290
|
/** Supplies a valid bearer token for each request. */
|
|
2285
2291
|
getToken: () => string;
|
|
2286
2292
|
/** Backoff delays (ms) applied on successive HTTP 429 responses. */
|
|
@@ -2303,7 +2309,7 @@ declare class RestClient$1 {
|
|
|
2303
2309
|
* @throws {CngPermissionError} on HTTP 403 (app missing a permission)
|
|
2304
2310
|
* @throws {CngApiError} on any other non-2xx response
|
|
2305
2311
|
*/
|
|
2306
|
-
get<T>(path: string): Promise<T>;
|
|
2312
|
+
get<T>(endpoint: string, path: string): Promise<T>;
|
|
2307
2313
|
private endpoint;
|
|
2308
2314
|
private buildHeaders;
|
|
2309
2315
|
}
|
|
@@ -2411,21 +2417,13 @@ declare class CngAccessService {
|
|
|
2411
2417
|
|
|
2412
2418
|
interface RestClientOptions {
|
|
2413
2419
|
/**
|
|
2414
|
-
* The install's
|
|
2415
|
-
*
|
|
2416
|
-
*
|
|
2417
|
-
* `baseUrl`.
|
|
2418
|
-
*/
|
|
2419
|
-
apiUrl?: string;
|
|
2420
|
-
/**
|
|
2421
|
-
* Base URL of the backoffice gateway (no trailing slash). Used only when
|
|
2422
|
-
* `apiUrl` is not set; the URL is `baseUrl/appId/extendableSlug/path`.
|
|
2420
|
+
* The install's **base API URL** (no trailing slash, no routing slug). Each
|
|
2421
|
+
* request builds `baseApiUrl/<slug>/<path>`, where the slug comes from
|
|
2422
|
+
* {@link endpoints} for the request's endpoint key.
|
|
2423
2423
|
*/
|
|
2424
|
-
|
|
2425
|
-
/**
|
|
2426
|
-
|
|
2427
|
-
/** Fixed extendable slug inserted between `appId` and the REST path (legacy mode). */
|
|
2428
|
-
extendableSlug?: string;
|
|
2424
|
+
baseApiUrl: string;
|
|
2425
|
+
/** Maps an endpoint key to the relative slug appended to {@link baseApiUrl}. */
|
|
2426
|
+
endpoints: ApiEndpoints;
|
|
2429
2427
|
/** Supplies a valid bearer token for each request. */
|
|
2430
2428
|
getToken: () => string;
|
|
2431
2429
|
/** Backoff delays (ms) applied on successive HTTP 429 responses. */
|
|
@@ -2447,7 +2445,7 @@ declare class RestClient {
|
|
|
2447
2445
|
* @throws {RateLimitError} on HTTP 429 after retries are exhausted
|
|
2448
2446
|
* @throws {AcmeApiError} on any other non-2xx response
|
|
2449
2447
|
*/
|
|
2450
|
-
get<T>(path: string): Promise<T>;
|
|
2448
|
+
get<T>(endpoint: string, path: string): Promise<T>;
|
|
2451
2449
|
private endpoint;
|
|
2452
2450
|
private buildHeaders;
|
|
2453
2451
|
}
|
|
@@ -2565,7 +2563,12 @@ declare class AcmeAccessService {
|
|
|
2565
2563
|
interface InstallAccessTarget {
|
|
2566
2564
|
/** Which platform serves the install (the install webhook's `platform`). */
|
|
2567
2565
|
platform: PeekPlatform | null;
|
|
2568
|
-
/**
|
|
2566
|
+
/**
|
|
2567
|
+
* The install's base API URL (the install webhook's `apiUrl`). The chosen
|
|
2568
|
+
* access service's service classes append their own backoffice slug when they
|
|
2569
|
+
* call; a URL already carrying this platform's slug is stripped back to the
|
|
2570
|
+
* base, and one carrying a different platform's slug throws.
|
|
2571
|
+
*/
|
|
2569
2572
|
apiUrl: string;
|
|
2570
2573
|
/** The install id (the install webhook's `installId`) — becomes the JWT subject. */
|
|
2571
2574
|
installId: string;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
2
|
import * as jwt from 'jsonwebtoken';
|
|
3
3
|
|
|
4
|
+
// src/internal/api-endpoints.ts
|
|
5
|
+
var ApiEndpoints = class {
|
|
6
|
+
constructor(paths) {
|
|
7
|
+
this.paths = paths;
|
|
8
|
+
}
|
|
9
|
+
paths;
|
|
10
|
+
/** The relative path (slug) for `endpoint`, appended to the base API URL. */
|
|
11
|
+
pathFor(endpoint) {
|
|
12
|
+
return this.paths[endpoint];
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
function joinUrl(...parts) {
|
|
16
|
+
return parts.filter((part) => part.length > 0).join("/");
|
|
17
|
+
}
|
|
18
|
+
|
|
4
19
|
// src/internal/peek/gateway-endpoints.ts
|
|
5
20
|
var SALES_ENDPOINT = "sales";
|
|
6
21
|
var V2_EXTENDABLE_SLUG = "peek_backoffice_api-v1";
|
|
22
|
+
function peekApiEndpoints(useRegistrySlug) {
|
|
23
|
+
return new ApiEndpoints({
|
|
24
|
+
[SALES_ENDPOINT]: useRegistrySlug ? V2_EXTENDABLE_SLUG : SALES_ENDPOINT
|
|
25
|
+
});
|
|
26
|
+
}
|
|
7
27
|
|
|
8
28
|
// src/internal/peek/account-users/account-user-converter.ts
|
|
9
29
|
var ACTIVE_STATUS = "ACTIVE";
|
|
@@ -2077,6 +2097,21 @@ function requireNonEmpty(value, name, serviceName) {
|
|
|
2077
2097
|
throw new Error(`${serviceName}: "${name}" is required`);
|
|
2078
2098
|
}
|
|
2079
2099
|
}
|
|
2100
|
+
var EXTENDABLE_SLUG_RE = /^([a-z0-9]+)[-_]backoffice[-_]api[-_]v1$/i;
|
|
2101
|
+
function resolveBaseApiUrl(apiUrl, platformSlug, serviceName) {
|
|
2102
|
+
const trimmed = apiUrl.replace(/\/+$/, "");
|
|
2103
|
+
const lastSegment = trimmed.slice(trimmed.lastIndexOf("/") + 1);
|
|
2104
|
+
const found = EXTENDABLE_SLUG_RE.exec(lastSegment);
|
|
2105
|
+
if (!found) return trimmed;
|
|
2106
|
+
const foundPlatform = found[1].toLowerCase();
|
|
2107
|
+
const expectedPlatform = EXTENDABLE_SLUG_RE.exec(platformSlug)[1].toLowerCase();
|
|
2108
|
+
if (foundPlatform !== expectedPlatform) {
|
|
2109
|
+
throw new Error(
|
|
2110
|
+
`${serviceName}: "apiUrl" carries a "${foundPlatform}" backoffice slug but this service targets "${expectedPlatform}" \u2014 pass the install's ${expectedPlatform} app endpoint`
|
|
2111
|
+
);
|
|
2112
|
+
}
|
|
2113
|
+
return trimmed.slice(0, trimmed.lastIndexOf("/"));
|
|
2114
|
+
}
|
|
2080
2115
|
function createTokenManager(config) {
|
|
2081
2116
|
return new TokenManager({
|
|
2082
2117
|
secret: config.jwtSecret,
|
|
@@ -2127,7 +2162,7 @@ async function requestWithRetry(http, url, init, label, onResponse) {
|
|
|
2127
2162
|
// src/internal/sdk-headers.ts
|
|
2128
2163
|
var SDK_HEADER_NAME = "x-peek-sdk";
|
|
2129
2164
|
var SDK_PLATFORM = "js";
|
|
2130
|
-
var SDK_VERSION = "0.9.
|
|
2165
|
+
var SDK_VERSION = "0.9.1";
|
|
2131
2166
|
var SDK_HEADER_VALUE = `${SDK_PLATFORM}-${SDK_VERSION}`;
|
|
2132
2167
|
|
|
2133
2168
|
// src/internal/peek/graphql-client.ts
|
|
@@ -2175,10 +2210,8 @@ var GraphQLClient = class {
|
|
|
2175
2210
|
);
|
|
2176
2211
|
}
|
|
2177
2212
|
endpoint(endpointName) {
|
|
2178
|
-
const {
|
|
2179
|
-
|
|
2180
|
-
const prefix = endpointPathPrefix ? `${endpointPathPrefix}/` : "";
|
|
2181
|
-
return `${baseUrl}/${appId}/${prefix}${endpointName}`;
|
|
2213
|
+
const { baseApiUrl, endpoints } = this.options;
|
|
2214
|
+
return joinUrl(baseApiUrl, endpoints.pathFor(endpointName));
|
|
2182
2215
|
}
|
|
2183
2216
|
buildHeaders() {
|
|
2184
2217
|
const headers = {
|
|
@@ -3801,17 +3834,17 @@ var PeekAccessService = class {
|
|
|
3801
3834
|
this.jwtSecret = config.jwtSecret;
|
|
3802
3835
|
const logger = config.logger ?? noopLogger;
|
|
3803
3836
|
const tokens = createTokenManager(config);
|
|
3837
|
+
const useRegistrySlug = hasApiUrl || isV2;
|
|
3804
3838
|
const defaultBaseUrl = isV2 ? DEFAULT_V2_BASE_URL : DEFAULT_BASE_URL;
|
|
3839
|
+
const baseApiUrl = hasApiUrl ? resolveBaseApiUrl(config.apiUrl, V2_EXTENDABLE_SLUG, "PeekAccessService") : `${config.baseUrl ?? defaultBaseUrl}/${config.appId}`;
|
|
3805
3840
|
this.client = new GraphQLClient({
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
appId: hasApiUrl ? void 0 : config.appId,
|
|
3841
|
+
baseApiUrl,
|
|
3842
|
+
endpoints: peekApiEndpoints(useRegistrySlug),
|
|
3809
3843
|
gatewayKey: config.gatewayKey,
|
|
3810
3844
|
getToken: () => tokens.getToken(),
|
|
3811
3845
|
retryDelaysMs: config.retryDelaysMs ?? DEFAULT_RETRY_DELAYS_MS,
|
|
3812
3846
|
logger,
|
|
3813
|
-
fetchFn: config.fetch ?? globalThis.fetch
|
|
3814
|
-
endpointPathPrefix: !hasApiUrl && isV2 ? V2_EXTENDABLE_SLUG : void 0
|
|
3847
|
+
fetchFn: config.fetch ?? globalThis.fetch
|
|
3815
3848
|
});
|
|
3816
3849
|
this.productServiceOptions = {
|
|
3817
3850
|
itemOptionsPageSize: config.itemOptionsPageSize
|
|
@@ -4165,7 +4198,11 @@ var PeekAccessService = class {
|
|
|
4165
4198
|
|
|
4166
4199
|
// src/internal/cng/endpoints.ts
|
|
4167
4200
|
var CNG_EXTENDABLE_SLUG = "cng_backoffice_api-v1";
|
|
4201
|
+
var CNG_PRODUCTS_ENDPOINT = "products";
|
|
4168
4202
|
var PRODUCTS_PATH = "api/v2/app-registry/products?active=1";
|
|
4203
|
+
var CNG_API_ENDPOINTS = new ApiEndpoints({
|
|
4204
|
+
[CNG_PRODUCTS_ENDPOINT]: CNG_EXTENDABLE_SLUG
|
|
4205
|
+
});
|
|
4169
4206
|
|
|
4170
4207
|
// src/models/cng/product.ts
|
|
4171
4208
|
var ACTIVITY_PRODUCT_TYPE2 = "ACTIVITY";
|
|
@@ -4199,7 +4236,10 @@ var CngProductService = class {
|
|
|
4199
4236
|
* ```
|
|
4200
4237
|
*/
|
|
4201
4238
|
async getAllActivities() {
|
|
4202
|
-
const body = await this.client.get(
|
|
4239
|
+
const body = await this.client.get(
|
|
4240
|
+
CNG_PRODUCTS_ENDPOINT,
|
|
4241
|
+
PRODUCTS_PATH
|
|
4242
|
+
);
|
|
4203
4243
|
return fromProductNodes(body?.data ?? []);
|
|
4204
4244
|
}
|
|
4205
4245
|
};
|
|
@@ -4221,9 +4261,9 @@ var RestClient = class {
|
|
|
4221
4261
|
* @throws {CngPermissionError} on HTTP 403 (app missing a permission)
|
|
4222
4262
|
* @throws {CngApiError} on any other non-2xx response
|
|
4223
4263
|
*/
|
|
4224
|
-
async get(path) {
|
|
4264
|
+
async get(endpoint, path) {
|
|
4225
4265
|
const { logger } = this.options;
|
|
4226
|
-
const url = this.endpoint(path);
|
|
4266
|
+
const url = this.endpoint(endpoint, path);
|
|
4227
4267
|
logger.info("Making CNG request", { url, path });
|
|
4228
4268
|
return requestWithRetry(
|
|
4229
4269
|
this.options,
|
|
@@ -4245,10 +4285,9 @@ var RestClient = class {
|
|
|
4245
4285
|
}
|
|
4246
4286
|
);
|
|
4247
4287
|
}
|
|
4248
|
-
endpoint(path) {
|
|
4249
|
-
const {
|
|
4250
|
-
|
|
4251
|
-
return `${baseUrl}/${appId}/${extendableSlug}/${path}`;
|
|
4288
|
+
endpoint(endpoint, path) {
|
|
4289
|
+
const { baseApiUrl, endpoints } = this.options;
|
|
4290
|
+
return joinUrl(baseApiUrl, endpoints.pathFor(endpoint), path);
|
|
4252
4291
|
}
|
|
4253
4292
|
buildHeaders() {
|
|
4254
4293
|
return {
|
|
@@ -4278,11 +4317,10 @@ var CngAccessService = class {
|
|
|
4278
4317
|
if (!hasApiUrl) requireNonEmpty(config.appId ?? "", "appId", "CngAccessService");
|
|
4279
4318
|
const logger = config.logger ?? noopLogger;
|
|
4280
4319
|
const tokens = createTokenManager(config);
|
|
4320
|
+
const baseApiUrl = hasApiUrl ? resolveBaseApiUrl(config.apiUrl, CNG_EXTENDABLE_SLUG, "CngAccessService") : `${config.baseUrl ?? DEFAULT_BASE_URL2}/${config.appId}`;
|
|
4281
4321
|
this.client = new RestClient({
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
appId: hasApiUrl ? void 0 : config.appId,
|
|
4285
|
-
extendableSlug: CNG_EXTENDABLE_SLUG,
|
|
4322
|
+
baseApiUrl,
|
|
4323
|
+
endpoints: CNG_API_ENDPOINTS,
|
|
4286
4324
|
getToken: () => tokens.getToken(),
|
|
4287
4325
|
retryDelaysMs: config.retryDelaysMs ?? DEFAULT_RETRY_DELAYS_MS,
|
|
4288
4326
|
logger,
|
|
@@ -4307,7 +4345,11 @@ var CngAccessService = class {
|
|
|
4307
4345
|
|
|
4308
4346
|
// src/internal/acme/endpoints.ts
|
|
4309
4347
|
var ACME_EXTENDABLE_SLUG = "acme_backoffice_api-v1";
|
|
4348
|
+
var ACME_TEMPLATES_ENDPOINT = "templates";
|
|
4310
4349
|
var TEMPLATES_PATH = "v2/b2b/event/templates/names?pageSize=-1&page=1";
|
|
4350
|
+
var ACME_API_ENDPOINTS = new ApiEndpoints({
|
|
4351
|
+
[ACME_TEMPLATES_ENDPOINT]: ACME_EXTENDABLE_SLUG
|
|
4352
|
+
});
|
|
4311
4353
|
|
|
4312
4354
|
// src/models/acme/product.ts
|
|
4313
4355
|
var ACME_ACTIVITY_TYPE = "standard";
|
|
@@ -4345,6 +4387,7 @@ var AcmeProductService = class {
|
|
|
4345
4387
|
*/
|
|
4346
4388
|
async getAllActivities() {
|
|
4347
4389
|
const body = await this.client.get(
|
|
4390
|
+
ACME_TEMPLATES_ENDPOINT,
|
|
4348
4391
|
TEMPLATES_PATH
|
|
4349
4392
|
);
|
|
4350
4393
|
const nodes = Array.isArray(body) ? body : body?.list ?? [];
|
|
@@ -4367,9 +4410,9 @@ var RestClient2 = class {
|
|
|
4367
4410
|
* @throws {RateLimitError} on HTTP 429 after retries are exhausted
|
|
4368
4411
|
* @throws {AcmeApiError} on any other non-2xx response
|
|
4369
4412
|
*/
|
|
4370
|
-
async get(path) {
|
|
4413
|
+
async get(endpoint, path) {
|
|
4371
4414
|
const { logger } = this.options;
|
|
4372
|
-
const url = this.endpoint(path);
|
|
4415
|
+
const url = this.endpoint(endpoint, path);
|
|
4373
4416
|
logger.info("Making ACME request", { url, path });
|
|
4374
4417
|
return requestWithRetry(
|
|
4375
4418
|
this.options,
|
|
@@ -4386,10 +4429,9 @@ var RestClient2 = class {
|
|
|
4386
4429
|
}
|
|
4387
4430
|
);
|
|
4388
4431
|
}
|
|
4389
|
-
endpoint(path) {
|
|
4390
|
-
const {
|
|
4391
|
-
|
|
4392
|
-
return `${baseUrl}/${appId}/${extendableSlug}/${path}`;
|
|
4432
|
+
endpoint(endpoint, path) {
|
|
4433
|
+
const { baseApiUrl, endpoints } = this.options;
|
|
4434
|
+
return joinUrl(baseApiUrl, endpoints.pathFor(endpoint), path);
|
|
4393
4435
|
}
|
|
4394
4436
|
buildHeaders() {
|
|
4395
4437
|
return {
|
|
@@ -4413,11 +4455,10 @@ var AcmeAccessService = class {
|
|
|
4413
4455
|
if (!hasApiUrl) requireNonEmpty(config.appId ?? "", "appId", "AcmeAccessService");
|
|
4414
4456
|
const logger = config.logger ?? noopLogger;
|
|
4415
4457
|
const tokens = createTokenManager(config);
|
|
4458
|
+
const baseApiUrl = hasApiUrl ? resolveBaseApiUrl(config.apiUrl, ACME_EXTENDABLE_SLUG, "AcmeAccessService") : `${config.baseUrl ?? DEFAULT_BASE_URL3}/${config.appId}`;
|
|
4416
4459
|
this.client = new RestClient2({
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
appId: hasApiUrl ? void 0 : config.appId,
|
|
4420
|
-
extendableSlug: ACME_EXTENDABLE_SLUG,
|
|
4460
|
+
baseApiUrl,
|
|
4461
|
+
endpoints: ACME_API_ENDPOINTS,
|
|
4421
4462
|
getToken: () => tokens.getToken(),
|
|
4422
4463
|
retryDelaysMs: config.retryDelaysMs ?? DEFAULT_RETRY_DELAYS_MS,
|
|
4423
4464
|
logger,
|