@surfiran/public-api-client 0.14.0 → 0.20.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/README.md +45 -164
- package/dist/client.d.ts +7 -2
- package/dist/client.js +48 -3
- package/dist/generated/public-api-v1.d.ts +6 -6
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +298 -3
- package/dist/types.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,195 +1,76 @@
|
|
|
1
1
|
# Public API Client
|
|
2
2
|
|
|
3
|
-
TypeScript types and
|
|
3
|
+
Zero-runtime-dependency TypeScript types and fetch client for SURFIRAN Public API V1. The package-local contract snapshot is OpenAPI `v0.14.0`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Project authority lives in:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
The backend API remains the canonical contract owner at
|
|
12
|
-
`server/openapi/public-api-v1.yaml`. This package contains an explicit,
|
|
13
|
-
checked-in snapshot with provenance linking it to the canonical source commit
|
|
14
|
-
and checksum. The package never reads backend source during generation.
|
|
15
|
-
|
|
16
|
-
## Current Runtime Scope
|
|
17
|
-
|
|
18
|
-
Active read endpoints:
|
|
19
|
-
|
|
20
|
-
```http
|
|
21
|
-
GET /api/v1/homepage
|
|
22
|
-
GET /api/v1/site-navigation
|
|
23
|
-
GET /api/v1/sitemap
|
|
24
|
-
GET /api/v1/search-suggestions
|
|
25
|
-
GET /api/v1/tour-categories
|
|
26
|
-
GET /api/v1/tours
|
|
27
|
-
GET /api/v1/tours/:slug
|
|
28
|
-
GET /api/v1/tours/:slug/departures
|
|
29
|
-
GET /api/v1/tours/:slug/availability
|
|
30
|
-
GET /api/v1/destinations
|
|
31
|
-
GET /api/v1/destinations/:slug
|
|
32
|
-
GET /api/v1/travel-knowledge
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Active narrow public write endpoints:
|
|
36
|
-
|
|
37
|
-
```http
|
|
38
|
-
POST /api/v1/inquiries
|
|
39
|
-
POST /api/v1/booking-intents
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Blocked endpoint:
|
|
43
|
-
|
|
44
|
-
```http
|
|
45
|
-
GET /api/v1/booking-intents/:id
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
`POST /api/v1/booking-intents` creates a public booking-intent record only. It does not create bookings, traveler records, payments, uploads, inventory holds, supplier-private records, BFF behavior, or Next.js behavior.
|
|
49
|
-
|
|
50
|
-
`GET /api/v1/booking-intents/:id` remains blocked at `501 PUBLIC_API_ROUTE_NOT_IMPLEMENTED` and is intentionally not exposed by this client.
|
|
51
|
-
|
|
52
|
-
## Exported Types
|
|
53
|
-
|
|
54
|
-
All types are aligned with the OpenAPI specification. Key exports:
|
|
55
|
-
|
|
56
|
-
- `PublicApiErrorCode` - union of current public error code strings
|
|
57
|
-
- `PublicApiV1Path` - union of active client paths
|
|
58
|
-
- `PublicApiV1RouteMap` - maps supported `GET` and `POST` client operations to response types
|
|
59
|
-
- `PublicTourListItem`, `PublicTourDetail`
|
|
60
|
-
- `PublicDepartureListItem`
|
|
61
|
-
- `PublicAvailabilityListItem`, `PublicAvailabilityListResponse`
|
|
62
|
-
- `PublicDestinationListItem`, `PublicDestinationDetail`
|
|
63
|
-
- `PublicTourListResponse`, `PublicTourDetailResponse`
|
|
64
|
-
- `PublicDepartureListResponse`
|
|
65
|
-
- `PublicDestinationListResponse`, `PublicDestinationDetailResponse`
|
|
66
|
-
- `PublicInquiryRequest`, `PublicInquiryResponse`
|
|
67
|
-
- `PublicBookingIntentRequest`, `PublicBookingIntentResponse`
|
|
68
|
-
- `PublicTravelKnowledgeItem`, `PublicTravelKnowledgeResponse`
|
|
69
|
-
- `PublicError`, `PublicErrorEnvelope`
|
|
70
|
-
- `PublicApiNotImplementedError`, `PublicApiValidationError`
|
|
71
|
-
- `PublicApiRateLimitError`, `PublicApiAbuseBlockedError`
|
|
72
|
-
- `PublicApiIdempotencyConflictError`
|
|
73
|
-
|
|
74
|
-
## Client Functions
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
import { createPublicApiClient } from '@surfiran/public-api-client';
|
|
78
|
-
|
|
79
|
-
const client = createPublicApiClient({ baseUrl: 'https://crm.example.com' });
|
|
80
|
-
|
|
81
|
-
const homepage = await client.getPublicHomepage();
|
|
82
|
-
const siteNavigation = await client.getPublicSiteNavigation();
|
|
83
|
-
const sitemap = await client.getPublicSitemap({ type: 'tour' });
|
|
84
|
-
const suggestions = await client.getPublicSearchSuggestions({ q: 'iran' });
|
|
85
|
-
const categories = await client.listPublicTourCategories({ limit: 20 });
|
|
86
|
-
const tours = await client.listPublicTours({ limit: 20 });
|
|
87
|
-
const tour = await client.getPublicTourBySlug('iran-hiking-tour');
|
|
88
|
-
const departures = await client.listPublicTourDepartures('iran-hiking-tour', { limit: 20 });
|
|
89
|
-
const availability = await client.listPublicTourAvailability('iran-hiking-tour', { limit: 20 });
|
|
90
|
-
const destinations = await client.listPublicDestinations({ limit: 20 });
|
|
91
|
-
const destination = await client.getPublicDestinationBySlug('tehran');
|
|
92
|
-
const travelKnowledge = await client.getPublicTravelKnowledge({ type: 'city', q: 'shiraz' });
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Public write calls require caller-provided idempotency keys where the Public API contract requires them:
|
|
96
|
-
|
|
97
|
-
```ts
|
|
98
|
-
const inquiry = await client.createPublicInquiry(
|
|
99
|
-
{ name: 'Traveler', email: 'traveler@example.com', message: 'I am interested in Iran tours.' },
|
|
100
|
-
'client-generated-idempotency-key',
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
const bookingIntent = await client.createPublicBookingIntent(
|
|
104
|
-
{ tourSlug: 'iran-hiking-tour', travelerCount: 2 },
|
|
105
|
-
'client-generated-idempotency-key',
|
|
106
|
-
);
|
|
107
|
-
```
|
|
7
|
+
- [Cross-Repository Contracts](../../docs/architecture/CROSS_REPOSITORY_CONTRACTS.md)
|
|
8
|
+
- [System Architecture](../../docs/architecture/SYSTEM_ARCHITECTURE.md)
|
|
9
|
+
- [Public Web Product Model](../../docs/domains/public-web/PUBLIC_WEB_PRODUCT_MODEL.md)
|
|
108
10
|
|
|
109
|
-
|
|
11
|
+
This README contains package-local generation, verification, and consumption guidance.
|
|
110
12
|
|
|
111
|
-
|
|
13
|
+
## Contract ownership
|
|
112
14
|
|
|
113
|
-
-
|
|
114
|
-
- Call internal CRM routes
|
|
115
|
-
- Export raw CRM row types or sensitive fields
|
|
116
|
-
- Expose `storage_path`, upload-private fields, passenger data, supplier-private data, payment data, audit data, tokens, cookies, or internal notes
|
|
117
|
-
- Add a client method for `GET /api/v1/booking-intents/:id` until that route is separately approved and implemented
|
|
15
|
+
`contract/public-api-v1.yaml` is the package-local immutable snapshot. The canonical source is owned by the API component at `server/openapi/public-api-v1.yaml`; `contract/provenance.json` pins its source commit and checksums. Package generation reads package-local files only, generated source is never hand-edited, and committed dist output is rebuilt and verified from that snapshot.
|
|
118
16
|
|
|
119
|
-
##
|
|
17
|
+
## Boundary
|
|
120
18
|
|
|
121
|
-
|
|
19
|
+
The client exposes only operations present and implemented in the pinned Public API contract. It must never:
|
|
122
20
|
|
|
123
|
-
|
|
21
|
+
- import server modules or connect to MariaDB;
|
|
22
|
+
- call internal CRM or generic-table routes;
|
|
23
|
+
- export raw CRM rows or passenger, supplier-private, payment, audit, internal-note, credential, cookie, token, or storage-path fields;
|
|
24
|
+
- manufacture public media URLs from private upload fields; public media remains outside typed-client methods and is governed by the signed-only proxy contract;
|
|
25
|
+
- add `GET /api/v1/booking-intents/:id` until separately approved and implemented.
|
|
124
26
|
|
|
125
|
-
|
|
27
|
+
Booking-intent creation remains intent-only. It does not create a Booking/Passenger, payment, inventory hold, supplier confirmation, checkout, or Public Web behavior.
|
|
126
28
|
|
|
127
|
-
##
|
|
29
|
+
## Install and verify
|
|
128
30
|
|
|
129
|
-
From this
|
|
130
|
-
artifact from the checked-in contract snapshot:
|
|
31
|
+
From this directory:
|
|
131
32
|
|
|
132
|
-
```
|
|
33
|
+
```bash
|
|
133
34
|
npm ci --include=dev
|
|
134
35
|
npm run generate
|
|
135
36
|
npm run verify:contract
|
|
136
37
|
npm run verify:generated
|
|
38
|
+
npm test
|
|
39
|
+
npm run typecheck
|
|
40
|
+
npm run build
|
|
137
41
|
```
|
|
138
42
|
|
|
139
|
-
Generation
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
explicit root command with a recorded source commit:
|
|
43
|
+
Generation is deterministic: stable ordering/formatting, LF newlines, no machine paths, random IDs, or uncontrolled timestamps.
|
|
44
|
+
|
|
45
|
+
## Monorepo synchronization
|
|
143
46
|
|
|
144
|
-
|
|
47
|
+
During co-location only, synchronize from the canonical OpenAPI source with the root command and an explicit full source commit:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
145
50
|
npm run sync:public-api-client-contract -- --source-commit <canonical-source-commit>
|
|
146
51
|
```
|
|
147
52
|
|
|
148
|
-
|
|
149
|
-
not be used to create a competing contract.
|
|
53
|
+
After a future repository split, the client repository consumes an immutable versioned contract artifact published by the API repository. No build reads another repository's source tree.
|
|
150
54
|
|
|
151
|
-
##
|
|
55
|
+
## Consumer usage
|
|
152
56
|
|
|
153
|
-
|
|
57
|
+
`listPublicTours` accepts full-catalog country, style, travel-format, activity,
|
|
58
|
+
duration-bucket, journey-type and departure-month selections. Values within a
|
|
59
|
+
group are ORed; groups are ANDed. `includeFacets: true` adds disjunctive facet
|
|
60
|
+
counts and the unfiltered catalog total. `destination` retains its legacy city
|
|
61
|
+
meaning; countries use `countries`. Dates mean published departures, not available
|
|
62
|
+
capacity. Price filtering and price sorting are not supported.
|
|
154
63
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
npm run verify:generated
|
|
159
|
-
npm run verify:package
|
|
160
|
-
npm run typecheck
|
|
161
|
-
npm test
|
|
162
|
-
npm run build
|
|
163
|
-
npm pack --dry-run --json
|
|
164
|
-
npm run verify:pack
|
|
165
|
-
npm run verify:publication-preflight -- <previous-exact-version>
|
|
166
|
-
```
|
|
64
|
+
Treat the catalog cursor as opaque. Clear it after changing filters or sorting;
|
|
65
|
+
it is bound to the normalized selection, locale and UTC reference day. Calls
|
|
66
|
+
without catalog parameters keep their existing pagination and response shape.
|
|
167
67
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
```text
|
|
172
|
-
npm pack --pack-destination <evidence-directory>
|
|
173
|
-
npm run create:provenance -- \
|
|
174
|
-
--source-commit <full-source-commit> \
|
|
175
|
-
--generated-at <UTC-ISO-8601-timestamp> \
|
|
176
|
-
--tarball <packed-tarball> \
|
|
177
|
-
--rollback-version <previous-exact-version> \
|
|
178
|
-
--output <evidence-directory>/public-api-client-provenance.json
|
|
179
|
-
npm run verify:provenance -- \
|
|
180
|
-
--file <evidence-directory>/public-api-client-provenance.json \
|
|
181
|
-
--tarball <packed-tarball>
|
|
182
|
-
```
|
|
68
|
+
Consumers install an exact immutable `@surfiran/public-api-client` version and create a client with their supported Public API base URL. They check the typed success/error result for every operation and keep credentials/environment values outside code and logs.
|
|
69
|
+
|
|
70
|
+
Do not duplicate the endpoint list in this README; the pinned OpenAPI and generated route/types are the executable inventory.
|
|
183
71
|
|
|
184
|
-
|
|
185
|
-
package name and version, canonical source commit, canonical and snapshot
|
|
186
|
-
checksums, generated artifact checksum, allowlist checksum, generation tool,
|
|
187
|
-
explicit generation timestamp policy, rollback version, and tarball checksum.
|
|
188
|
-
The package is immutable on npm. Consumers roll back by pinning the previous
|
|
189
|
-
verified exact version; an existing version is never overwritten.
|
|
72
|
+
## Publication and rollback
|
|
190
73
|
|
|
191
|
-
|
|
74
|
+
Run package verification, `npm pack --dry-run --json`, pack verification, and publication preflight against the previous exact version. Publish a new immutable version with provenance; never rewrite an existing version. Rollback means reinstalling the prior verified package version and independently rolling back any consumer deployment.
|
|
192
75
|
|
|
193
|
-
|
|
194
|
-
- Synchronize the explicit snapshot only from the API-owned canonical source
|
|
195
|
-
- Run package-local generation, validation, provenance, and clean-clone checks
|
|
76
|
+
No package command deploys a consumer, changes API runtime behavior, applies a migration, or accesses production data/configuration.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GetPublicSearchSuggestionsParams, GetPublicSitemapParams, GetPublicTourPreviewParams, GetPublicTravelKnowledgeParams, ListPublicDeparturesParams, ListPublicDestinationsParams, ListPublicTourAccommodationsParams, ListPublicTourAvailabilityParams, ListPublicTourCategoriesParams, ListPublicTourExperiencesParams, ListPublicTravellerStoriesParams, ListPublicTourQuestionsParams, ListPublicTourReviewsParams, ListPublicTourItineraryParams, ListPublicTourRouteParams, ListPublicToursParams, PublicApiResult, PublicAvailabilityListResponse, PublicBookingIntentRequest, PublicBookingIntentResponse, PublicBrochureLeadRequest, PublicBrochureLeadResponse, PublicDepartureListResponse, PublicDestinationDetailResponse, PublicDestinationListResponse, PublicHomepageResponse, PublicInquiryRequest, PublicInquiryResponse, PublicSearchSuggestionsResponse, PublicSitemapResponse, PublicSiteChromeContentResponse, PublicSiteFeaturesResponse, PublicSiteHomeContentResponse, PublicSiteNavigationResponse, PublicSiteTrustPageContentResponse, PublicTourAccommodationListResponse, PublicTourCategoryListResponse, PublicTourDetailResponse, PublicTourExperienceListResponse, PublicTravellerStoryListResponse, PublicTourListResponse, PublicTourQuestionListResponse, PublicTourReviewsSummaryResponse, PublicTourReviewListResponse, PublicTourItineraryResponse, PublicTourRouteResponse, PublicTravelKnowledgeResponse, PublicTravelStatusResponse } from './types.js';
|
|
1
|
+
import type { GetPublicSearchResultsParams, GetPublicSearchSuggestionsParams, GetPublicSitemapParams, GetPublicTourPreviewParams, GetPublicTravelKnowledgeParams, ListPublicDeparturesParams, ListPublicDestinationsParams, ListPublicTourAccommodationsParams, ListPublicTourAvailabilityParams, ListPublicTourCategoriesParams, ListPublicTourExperiencesParams, ListPublicTravellerStoriesParams, ListPublicTourQuestionsParams, ListPublicTourReviewsParams, ListPublicTourItineraryParams, ListPublicTourRouteParams, ListPublicToursParams, GetPublicTourParams, PublicApiResult, PublicAvailabilityListResponse, PublicBookingIntentRequest, PublicBookingIntentResponse, PublicBrochureLeadRequest, PublicBrochureLeadResponse, PublicDepartureListResponse, PublicDestinationDetailResponse, PublicDestinationListResponse, PublicHomepageResponse, PublicInquiryRequest, PublicInquiryResponse, PublicSearchResultsResponse, PublicSearchSuggestionsResponse, PublicSitemapResponse, PublicSiteChromeContentResponse, PublicSiteFeaturesResponse, PublicLocaleRegistryResponse, PublicLocalizationCandidatePreviewResponse, PublicLocalizationReleaseResponse, PublicUiCatalogResponse, LocalizationReleaseId, LocalizationPreviewCapability, UiCatalogSnapshotId, PublicSiteHomeContentResponse, PublicSiteNavigationResponse, PublicSiteTrustPageContentResponse, PublicTourAccommodationListResponse, PublicTourCategoryListResponse, PublicTourDetailResponse, PublicTourExperienceListResponse, PublicTravellerStoryListResponse, PublicTourListResponse, PublicTourQuestionListResponse, PublicTourReviewsSummaryResponse, PublicTourReviewListResponse, PublicTourItineraryResponse, PublicTourRouteResponse, PublicTravelKnowledgeResponse, PublicTravelStatusResponse } from './types.js';
|
|
2
2
|
export type PublicApiClientOptions = {
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
fetchImpl?: typeof fetch;
|
|
@@ -12,7 +12,7 @@ export type PublicApiClientOptions = {
|
|
|
12
12
|
};
|
|
13
13
|
export declare const createPublicApiClient: (options: PublicApiClientOptions) => {
|
|
14
14
|
listPublicTours(params?: ListPublicToursParams): Promise<PublicApiResult<PublicTourListResponse>>;
|
|
15
|
-
getPublicTourBySlug(slug: string): Promise<PublicApiResult<PublicTourDetailResponse>>;
|
|
15
|
+
getPublicTourBySlug(slug: string, params?: GetPublicTourParams): Promise<PublicApiResult<PublicTourDetailResponse>>;
|
|
16
16
|
/**
|
|
17
17
|
* ADR-0022 Tour Product/Edition MVP candidate preview: renders the same
|
|
18
18
|
* public-safe DTO as getPublicTourBySlug, with the Edition-sourced
|
|
@@ -41,8 +41,13 @@ export declare const createPublicApiClient: (options: PublicApiClientOptions) =>
|
|
|
41
41
|
getPublicHomepage(): Promise<PublicApiResult<PublicHomepageResponse>>;
|
|
42
42
|
getPublicSiteNavigation(): Promise<PublicApiResult<PublicSiteNavigationResponse>>;
|
|
43
43
|
getPublicSiteFeatures(): Promise<PublicApiResult<PublicSiteFeaturesResponse>>;
|
|
44
|
+
listPublicLocales(): Promise<PublicApiResult<PublicLocaleRegistryResponse>>;
|
|
45
|
+
getPublicLocalizationRelease(releaseId: LocalizationReleaseId): Promise<PublicApiResult<PublicLocalizationReleaseResponse>>;
|
|
46
|
+
getPublicLocalizationCandidatePreview(candidateId: LocalizationReleaseId, capability: LocalizationPreviewCapability): Promise<PublicApiResult<PublicLocalizationCandidatePreviewResponse>>;
|
|
47
|
+
getPublicUiCatalog(snapshotId: UiCatalogSnapshotId): Promise<PublicApiResult<PublicUiCatalogResponse>>;
|
|
44
48
|
getPublicSitemap(params?: GetPublicSitemapParams): Promise<PublicApiResult<PublicSitemapResponse>>;
|
|
45
49
|
getPublicSearchSuggestions(params: GetPublicSearchSuggestionsParams): Promise<PublicApiResult<PublicSearchSuggestionsResponse>>;
|
|
50
|
+
getPublicSearchResults(params: GetPublicSearchResultsParams): Promise<PublicApiResult<PublicSearchResultsResponse>>;
|
|
46
51
|
listPublicTourCategories(params?: ListPublicTourCategoriesParams): Promise<PublicApiResult<PublicTourCategoryListResponse>>;
|
|
47
52
|
getPublicTravelStatus(): Promise<PublicApiResult<PublicTravelStatusResponse>>;
|
|
48
53
|
getPublicSiteContentHome(): Promise<PublicApiResult<PublicSiteHomeContentResponse>>;
|
package/dist/client.js
CHANGED
|
@@ -30,11 +30,13 @@ const toPublicError = async (response) => {
|
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
32
|
};
|
|
33
|
-
const requestJson = async (url, options) => {
|
|
33
|
+
const requestJson = async (url, options, authorization) => {
|
|
34
34
|
const fetcher = options.fetchImpl || fetch;
|
|
35
35
|
const headers = new Headers();
|
|
36
36
|
if (options.requestId)
|
|
37
37
|
headers.set('x-request-id', options.requestId);
|
|
38
|
+
if (authorization)
|
|
39
|
+
headers.set('Authorization', authorization);
|
|
38
40
|
const controller = new AbortController();
|
|
39
41
|
const timeoutId = setTimeout(() => controller.abort(), options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
40
42
|
let response;
|
|
@@ -83,9 +85,22 @@ const toQueryString = (params) => {
|
|
|
83
85
|
search.set('minDuration', String(params.minDuration));
|
|
84
86
|
if (params?.maxDuration !== undefined)
|
|
85
87
|
search.set('maxDuration', String(params.maxDuration));
|
|
88
|
+
if (params?.locale)
|
|
89
|
+
search.set('locale', params.locale);
|
|
90
|
+
for (const key of ['countries', 'styles', 'travelFormats', 'activityLevels', 'durationBuckets', 'journeyTypes', 'months']) {
|
|
91
|
+
if (params?.[key]?.length)
|
|
92
|
+
search.set(key, params[key].join(','));
|
|
93
|
+
}
|
|
94
|
+
for (const key of ['includeFacets', 'hasUpcomingDepartures']) {
|
|
95
|
+
if (params?.[key] !== undefined)
|
|
96
|
+
search.set(key, String(params[key]));
|
|
97
|
+
}
|
|
98
|
+
if (params?.sort)
|
|
99
|
+
search.set('sort', params.sort);
|
|
86
100
|
const value = search.toString();
|
|
87
101
|
return value ? `?${value}` : '';
|
|
88
102
|
};
|
|
103
|
+
const toContentLocaleQueryString = (params) => params?.locale ? `?locale=${encodeURIComponent(params.locale)}` : '';
|
|
89
104
|
const toSitemapQueryString = (params) => {
|
|
90
105
|
const search = new URLSearchParams();
|
|
91
106
|
if (params?.type)
|
|
@@ -102,6 +117,21 @@ const toSearchSuggestionsQueryString = (params) => {
|
|
|
102
117
|
search.set('type', params.type);
|
|
103
118
|
return `?${search.toString()}`;
|
|
104
119
|
};
|
|
120
|
+
/*
|
|
121
|
+
* Same shape as the suggestion query, kept as its own builder rather than
|
|
122
|
+
* shared: the two endpoints have separate limit ranges and are free to diverge,
|
|
123
|
+
* and the server rejects any parameter it does not name, so a builder that
|
|
124
|
+
* quietly served both would be the thing that broke on the first divergence.
|
|
125
|
+
*/
|
|
126
|
+
const toSearchResultsQueryString = (params) => {
|
|
127
|
+
const search = new URLSearchParams();
|
|
128
|
+
search.set('q', params.q);
|
|
129
|
+
if (params.limit !== undefined)
|
|
130
|
+
search.set('limit', String(params.limit));
|
|
131
|
+
if (params.type)
|
|
132
|
+
search.set('type', params.type);
|
|
133
|
+
return `?${search.toString()}`;
|
|
134
|
+
};
|
|
105
135
|
const toTravelKnowledgeQueryString = (params) => {
|
|
106
136
|
const search = new URLSearchParams();
|
|
107
137
|
search.set('type', params.type);
|
|
@@ -158,8 +188,8 @@ export const createPublicApiClient = (options) => {
|
|
|
158
188
|
listPublicTours(params) {
|
|
159
189
|
return requestJson(`${baseUrl}/api/v1/tours${toQueryString(params)}`, options);
|
|
160
190
|
},
|
|
161
|
-
getPublicTourBySlug(slug) {
|
|
162
|
-
return requestJson(`${baseUrl}/api/v1/tours/${encodeURIComponent(slug)}`, options);
|
|
191
|
+
getPublicTourBySlug(slug, params) {
|
|
192
|
+
return requestJson(`${baseUrl}/api/v1/tours/${encodeURIComponent(slug)}${toContentLocaleQueryString(params)}`, options);
|
|
163
193
|
},
|
|
164
194
|
/**
|
|
165
195
|
* ADR-0022 Tour Product/Edition MVP candidate preview: renders the same
|
|
@@ -232,12 +262,27 @@ export const createPublicApiClient = (options) => {
|
|
|
232
262
|
getPublicSiteFeatures() {
|
|
233
263
|
return requestJson(`${baseUrl}/api/v1/site-features`, options);
|
|
234
264
|
},
|
|
265
|
+
listPublicLocales() {
|
|
266
|
+
return requestJson(`${baseUrl}/api/v1/locales`, options);
|
|
267
|
+
},
|
|
268
|
+
getPublicLocalizationRelease(releaseId) {
|
|
269
|
+
return requestJson(`${baseUrl}/api/v1/localization/releases/${encodeURIComponent(releaseId)}`, options);
|
|
270
|
+
},
|
|
271
|
+
getPublicLocalizationCandidatePreview(candidateId, capability) {
|
|
272
|
+
return requestJson(`${baseUrl}/api/v1/localization/previews/${encodeURIComponent(candidateId)}`, options, `Bearer ${capability}`);
|
|
273
|
+
},
|
|
274
|
+
getPublicUiCatalog(snapshotId) {
|
|
275
|
+
return requestJson(`${baseUrl}/api/v1/localization/ui-catalogs/${encodeURIComponent(snapshotId)}`, options);
|
|
276
|
+
},
|
|
235
277
|
getPublicSitemap(params) {
|
|
236
278
|
return requestJson(`${baseUrl}/api/v1/sitemap${toSitemapQueryString(params)}`, options);
|
|
237
279
|
},
|
|
238
280
|
getPublicSearchSuggestions(params) {
|
|
239
281
|
return requestJson(`${baseUrl}/api/v1/search-suggestions${toSearchSuggestionsQueryString(params)}`, options);
|
|
240
282
|
},
|
|
283
|
+
getPublicSearchResults(params) {
|
|
284
|
+
return requestJson(`${baseUrl}/api/v1/search${toSearchResultsQueryString(params)}`, options);
|
|
285
|
+
},
|
|
241
286
|
listPublicTourCategories(params) {
|
|
242
287
|
return requestJson(`${baseUrl}/api/v1/tour-categories${toPaginationQueryString(params)}`, options);
|
|
243
288
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type GeneratedPublicApiVersion = '0.
|
|
2
|
-
export type GeneratedPublicApiPath = '/booking-intents' | '/booking-intents/{id}' | '/brochure-leads' | '/destinations' | '/destinations/{slug}' | '/homepage' | '/inquiries' | '/search-suggestions' | '/site-content/about' | '/site-content/accessibility-statement' | '/site-content/booking-cancellation-policy' | '/site-content/contact' | '/site-content/cookie-policy' | '/site-content/faqs' | '/site-content/footer' | '/site-content/header' | '/site-content/health-safety-support' | '/site-content/home' | '/site-content/iran-travel-status' | '/site-content/iran-visa-information' | '/site-content/money-in-iran' | '/site-content/privacy' | '/site-content/responsible-travel' | '/site-content/tailor-made' | '/site-content/terms' | '/site-content/travel-insurance' | '/site-features' | '/site-navigation' | '/sitemap' | '/tour-categories' | '/tours' | '/tours/{slug}' | '/tours/{slug}/accommodations' | '/tours/{slug}/availability' | '/tours/{slug}/departures' | '/tours/{slug}/experiences' | '/tours/{slug}/itinerary' | '/tours/{slug}/preview' | '/tours/{slug}/questions' | '/tours/{slug}/reviews' | '/tours/{slug}/reviews-summary' | '/tours/{slug}/route' | '/travel-knowledge' | '/travel-status' | '/traveller-stories';
|
|
3
|
-
export type GeneratedPublicApiOperation = 'GET /booking-intents/{id}' | 'GET /destinations' | 'GET /destinations/{slug}' | 'GET /homepage' | 'GET /search-suggestions' | 'GET /site-content/about' | 'GET /site-content/accessibility-statement' | 'GET /site-content/booking-cancellation-policy' | 'GET /site-content/contact' | 'GET /site-content/cookie-policy' | 'GET /site-content/faqs' | 'GET /site-content/footer' | 'GET /site-content/header' | 'GET /site-content/health-safety-support' | 'GET /site-content/home' | 'GET /site-content/iran-travel-status' | 'GET /site-content/iran-visa-information' | 'GET /site-content/money-in-iran' | 'GET /site-content/privacy' | 'GET /site-content/responsible-travel' | 'GET /site-content/tailor-made' | 'GET /site-content/terms' | 'GET /site-content/travel-insurance' | 'GET /site-features' | 'GET /site-navigation' | 'GET /sitemap' | 'GET /tour-categories' | 'GET /tours' | 'GET /tours/{slug}' | 'GET /tours/{slug}/accommodations' | 'GET /tours/{slug}/availability' | 'GET /tours/{slug}/departures' | 'GET /tours/{slug}/experiences' | 'GET /tours/{slug}/itinerary' | 'GET /tours/{slug}/preview' | 'GET /tours/{slug}/questions' | 'GET /tours/{slug}/reviews' | 'GET /tours/{slug}/reviews-summary' | 'GET /tours/{slug}/route' | 'GET /travel-knowledge' | 'GET /travel-status' | 'GET /traveller-stories' | 'POST /booking-intents' | 'POST /brochure-leads' | 'POST /inquiries';
|
|
4
|
-
export type GeneratedPublicApiActiveOperation = 'GET /destinations' | 'GET /destinations/{slug}' | 'GET /homepage' | 'GET /search-suggestions' | 'GET /site-content/about' | 'GET /site-content/accessibility-statement' | 'GET /site-content/booking-cancellation-policy' | 'GET /site-content/contact' | 'GET /site-content/cookie-policy' | 'GET /site-content/faqs' | 'GET /site-content/footer' | 'GET /site-content/header' | 'GET /site-content/health-safety-support' | 'GET /site-content/home' | 'GET /site-content/iran-travel-status' | 'GET /site-content/iran-visa-information' | 'GET /site-content/money-in-iran' | 'GET /site-content/privacy' | 'GET /site-content/responsible-travel' | 'GET /site-content/tailor-made' | 'GET /site-content/terms' | 'GET /site-content/travel-insurance' | 'GET /site-features' | 'GET /site-navigation' | 'GET /sitemap' | 'GET /tour-categories' | 'GET /tours' | 'GET /tours/{slug}' | 'GET /tours/{slug}/accommodations' | 'GET /tours/{slug}/availability' | 'GET /tours/{slug}/departures' | 'GET /tours/{slug}/experiences' | 'GET /tours/{slug}/itinerary' | 'GET /tours/{slug}/preview' | 'GET /tours/{slug}/questions' | 'GET /tours/{slug}/reviews' | 'GET /tours/{slug}/reviews-summary' | 'GET /tours/{slug}/route' | 'GET /travel-knowledge' | 'GET /travel-status' | 'GET /traveller-stories' | 'POST /booking-intents' | 'POST /brochure-leads' | 'POST /inquiries';
|
|
1
|
+
export type GeneratedPublicApiVersion = '0.14.0';
|
|
2
|
+
export type GeneratedPublicApiPath = '/booking-intents' | '/booking-intents/{id}' | '/brochure-leads' | '/destinations' | '/destinations/{slug}' | '/homepage' | '/inquiries' | '/locales' | '/localization/previews/{candidateId}' | '/localization/releases/{releaseId}' | '/localization/ui-catalogs/{snapshotId}' | '/search' | '/search-suggestions' | '/site-content/about' | '/site-content/accessibility-statement' | '/site-content/booking-cancellation-policy' | '/site-content/contact' | '/site-content/cookie-policy' | '/site-content/faqs' | '/site-content/footer' | '/site-content/header' | '/site-content/health-safety-support' | '/site-content/home' | '/site-content/iran-travel-status' | '/site-content/iran-visa-information' | '/site-content/money-in-iran' | '/site-content/privacy' | '/site-content/responsible-travel' | '/site-content/tailor-made' | '/site-content/terms' | '/site-content/travel-insurance' | '/site-features' | '/site-navigation' | '/sitemap' | '/tour-categories' | '/tours' | '/tours/{slug}' | '/tours/{slug}/accommodations' | '/tours/{slug}/availability' | '/tours/{slug}/departures' | '/tours/{slug}/experiences' | '/tours/{slug}/itinerary' | '/tours/{slug}/preview' | '/tours/{slug}/questions' | '/tours/{slug}/reviews' | '/tours/{slug}/reviews-summary' | '/tours/{slug}/route' | '/travel-knowledge' | '/travel-status' | '/traveller-stories';
|
|
3
|
+
export type GeneratedPublicApiOperation = 'GET /booking-intents/{id}' | 'GET /destinations' | 'GET /destinations/{slug}' | 'GET /homepage' | 'GET /locales' | 'GET /localization/previews/{candidateId}' | 'GET /localization/releases/{releaseId}' | 'GET /localization/ui-catalogs/{snapshotId}' | 'GET /search' | 'GET /search-suggestions' | 'GET /site-content/about' | 'GET /site-content/accessibility-statement' | 'GET /site-content/booking-cancellation-policy' | 'GET /site-content/contact' | 'GET /site-content/cookie-policy' | 'GET /site-content/faqs' | 'GET /site-content/footer' | 'GET /site-content/header' | 'GET /site-content/health-safety-support' | 'GET /site-content/home' | 'GET /site-content/iran-travel-status' | 'GET /site-content/iran-visa-information' | 'GET /site-content/money-in-iran' | 'GET /site-content/privacy' | 'GET /site-content/responsible-travel' | 'GET /site-content/tailor-made' | 'GET /site-content/terms' | 'GET /site-content/travel-insurance' | 'GET /site-features' | 'GET /site-navigation' | 'GET /sitemap' | 'GET /tour-categories' | 'GET /tours' | 'GET /tours/{slug}' | 'GET /tours/{slug}/accommodations' | 'GET /tours/{slug}/availability' | 'GET /tours/{slug}/departures' | 'GET /tours/{slug}/experiences' | 'GET /tours/{slug}/itinerary' | 'GET /tours/{slug}/preview' | 'GET /tours/{slug}/questions' | 'GET /tours/{slug}/reviews' | 'GET /tours/{slug}/reviews-summary' | 'GET /tours/{slug}/route' | 'GET /travel-knowledge' | 'GET /travel-status' | 'GET /traveller-stories' | 'POST /booking-intents' | 'POST /brochure-leads' | 'POST /inquiries';
|
|
4
|
+
export type GeneratedPublicApiActiveOperation = 'GET /destinations' | 'GET /destinations/{slug}' | 'GET /homepage' | 'GET /locales' | 'GET /localization/previews/{candidateId}' | 'GET /localization/releases/{releaseId}' | 'GET /localization/ui-catalogs/{snapshotId}' | 'GET /search' | 'GET /search-suggestions' | 'GET /site-content/about' | 'GET /site-content/accessibility-statement' | 'GET /site-content/booking-cancellation-policy' | 'GET /site-content/contact' | 'GET /site-content/cookie-policy' | 'GET /site-content/faqs' | 'GET /site-content/footer' | 'GET /site-content/header' | 'GET /site-content/health-safety-support' | 'GET /site-content/home' | 'GET /site-content/iran-travel-status' | 'GET /site-content/iran-visa-information' | 'GET /site-content/money-in-iran' | 'GET /site-content/privacy' | 'GET /site-content/responsible-travel' | 'GET /site-content/tailor-made' | 'GET /site-content/terms' | 'GET /site-content/travel-insurance' | 'GET /site-features' | 'GET /site-navigation' | 'GET /sitemap' | 'GET /tour-categories' | 'GET /tours' | 'GET /tours/{slug}' | 'GET /tours/{slug}/accommodations' | 'GET /tours/{slug}/availability' | 'GET /tours/{slug}/departures' | 'GET /tours/{slug}/experiences' | 'GET /tours/{slug}/itinerary' | 'GET /tours/{slug}/preview' | 'GET /tours/{slug}/questions' | 'GET /tours/{slug}/reviews' | 'GET /tours/{slug}/reviews-summary' | 'GET /tours/{slug}/route' | 'GET /travel-knowledge' | 'GET /travel-status' | 'GET /traveller-stories' | 'POST /booking-intents' | 'POST /brochure-leads' | 'POST /inquiries';
|
|
5
5
|
export type GeneratedPublicApiBlockedOperation = 'GET /booking-intents/{id}';
|
|
6
|
-
export type GeneratedPublicApiOperationId = 'getBookingIntent' | 'listPublicDestinations' | 'getPublicDestinationBySlug' | 'getPublicHomepage' | 'getPublicSearchSuggestions' | 'getPublicSiteContentAbout' | 'getPublicSiteContentAccessibilityStatement' | 'getPublicSiteContentBookingCancellationPolicy' | 'getPublicSiteContentContact' | 'getPublicSiteContentCookiePolicy' | 'getPublicSiteContentFaqs' | 'getPublicSiteContentFooter' | 'getPublicSiteContentHeader' | 'getPublicSiteContentHealthSafetySupport' | 'getPublicSiteContentHome' | 'getPublicSiteContentIranTravelStatus' | 'getPublicSiteContentIranVisaInformation' | 'getPublicSiteContentMoneyInIran' | 'getPublicSiteContentPrivacy' | 'getPublicSiteContentResponsibleTravel' | 'getPublicSiteContentTailorMade' | 'getPublicSiteContentTerms' | 'getPublicSiteContentTravelInsurance' | 'getPublicSiteFeatures' | 'getPublicSiteNavigation' | 'getPublicSitemap' | 'listPublicTourCategories' | 'listPublicTours' | 'getPublicTourBySlug' | 'listPublicTourAccommodations' | 'listPublicTourAvailability' | 'listPublicTourDepartures' | 'listPublicTourExperiences' | 'listPublicTourItinerary' | 'getPublicTourPreviewBySlug' | 'listPublicTourQuestions' | 'listPublicTourReviews' | 'getPublicTourReviewsSummary' | 'listPublicTourRoute' | 'listPublicTravelKnowledge' | 'getPublicTravelStatus' | 'listPublicTravellerStories' | 'createPublicBookingIntent' | 'createPublicBrochureLead' | 'createPublicInquiry';
|
|
7
|
-
export type GeneratedPublicApiSchemaName = 'BookingIntentConflictErrorResponse' | 'BookingIntentResponse' | 'CanonicalIntakeAttribution' | 'CanonicalIntakeConsent' | 'CreateBookingIntentRequest' | 'CreateBookingIntentSuccessResponse' | 'CreateBrochureLeadRequest' | 'CreateBrochureLeadResponse' | 'CreateInquiryRequest' | 'CreateInquiryResponse' | 'GetBookingIntentStatusResponse' | 'PaginationMeta' | 'PublicApiAbuseBlockedError' | 'PublicApiError' | 'PublicApiInternalError' | 'PublicApiNotFoundError' | 'PublicApiNotImplementedError' | 'PublicApiRateLimitError' | 'PublicApiTravelStatusUnavailableError' | 'PublicApiValidationError' | 'PublicAvailabilityListItem' | 'PublicAvailabilityListResponse' | 'PublicBookingIntentLinks' | 'PublicBookingIntentPublicStatus' | 'PublicBookingIntentStatus' | 'PublicCityDestinationContent' | 'PublicCityExperience' | 'PublicCityImage' | 'PublicCityLabelledValue' | 'PublicCityLink' | 'PublicCityNextPlace' | 'PublicCityReason' | 'PublicCityResource' | 'PublicCityRoutePattern' | 'PublicCityStayLink' | 'PublicDepartureListItem' | 'PublicDepartureListResponse' | 'PublicDestinationDetail' | 'PublicDestinationDetailResponse' | 'PublicDestinationListItem' | 'PublicDestinationListResponse' | 'PublicError' | 'PublicErrorEnvelope' | 'PublicHomepageResponse' | 'PublicHomepageSeo' | 'PublicHomepageStats' | 'PublicNavLink' | 'PublicOfficialSourceCard' | 'PublicSearchSuggestion' | 'PublicSearchSuggestionsResponse' | 'PublicSeo' | 'PublicSiteChromeContent' | 'PublicSiteChromeContentResponse' | 'PublicSiteCta' | 'PublicSiteFeaturesResponse' | 'PublicSiteFeatureStates' | 'PublicSiteHomeContent' | 'PublicSiteHomeContentResponse' | 'PublicSiteHomeSection' | 'PublicSitemapEntry' | 'PublicSitemapResponse' | 'PublicSiteNavigationResponse' | 'PublicSiteNavItem' | 'PublicSiteRouteKey' | 'PublicSiteSocialLink' | 'PublicSiteTrustPageContent' | 'PublicSiteTrustPageContentResponse' | 'PublicSiteTrustPageSeo' | 'PublicSiteTrustSection' | 'PublicSiteTrustTitledItem' | 'PublicStaticLink' | 'PublicSurfiranOperationalUpdate' | 'PublicTourAccommodationListItem' | 'PublicTourAccommodationListResponse' | 'PublicTourCategoryListItem' | 'PublicTourCategoryListResponse' | 'PublicTourDetail' | 'PublicTourDetailEditorial' | 'PublicTourDetailResponse' | 'PublicTourExperienceFrame' | 'PublicTourExperienceListItem' | 'PublicTourExperienceListResponse' | 'PublicTourItineraryDay' | 'PublicTourItineraryResponse' | 'PublicTourListItem' | 'PublicTourListResponse' | 'PublicTourQuestionListItem' | 'PublicTourQuestionListResponse' | 'PublicTourRatingBreakdownItem' | 'PublicTourReviewListItem' | 'PublicTourReviewListResponse' | 'PublicTourReviewsAggregate' | 'PublicTourReviewsSummary' | 'PublicTourReviewsSummaryResponse' | 'PublicTourRouteResponse' | 'PublicTourRouteStop' | 'PublicTourTailorJourney' | 'PublicTravelKnowledgeItem' | 'PublicTravelKnowledgeResponse' | 'PublicTravellerStoryListItem' | 'PublicTravellerStoryListResponse' | 'PublicTravelStatusCorrectionNotice' | 'PublicTravelStatusFreshness' | 'PublicTravelStatusHandoff' | 'PublicTravelStatusResponse' | 'PublicTravelStatusReviewerLabel' | 'PublicTravelStatusSection' | 'PublicTravelStatusState' | 'PublicTripBrief';
|
|
6
|
+
export type GeneratedPublicApiOperationId = 'getBookingIntent' | 'listPublicDestinations' | 'getPublicDestinationBySlug' | 'getPublicHomepage' | 'listPublicLocales' | 'getPublicLocalizationCandidatePreview' | 'getPublicLocalizationRelease' | 'getPublicUiCatalog' | 'getPublicSearchResults' | 'getPublicSearchSuggestions' | 'getPublicSiteContentAbout' | 'getPublicSiteContentAccessibilityStatement' | 'getPublicSiteContentBookingCancellationPolicy' | 'getPublicSiteContentContact' | 'getPublicSiteContentCookiePolicy' | 'getPublicSiteContentFaqs' | 'getPublicSiteContentFooter' | 'getPublicSiteContentHeader' | 'getPublicSiteContentHealthSafetySupport' | 'getPublicSiteContentHome' | 'getPublicSiteContentIranTravelStatus' | 'getPublicSiteContentIranVisaInformation' | 'getPublicSiteContentMoneyInIran' | 'getPublicSiteContentPrivacy' | 'getPublicSiteContentResponsibleTravel' | 'getPublicSiteContentTailorMade' | 'getPublicSiteContentTerms' | 'getPublicSiteContentTravelInsurance' | 'getPublicSiteFeatures' | 'getPublicSiteNavigation' | 'getPublicSitemap' | 'listPublicTourCategories' | 'listPublicTours' | 'getPublicTourBySlug' | 'listPublicTourAccommodations' | 'listPublicTourAvailability' | 'listPublicTourDepartures' | 'listPublicTourExperiences' | 'listPublicTourItinerary' | 'getPublicTourPreviewBySlug' | 'listPublicTourQuestions' | 'listPublicTourReviews' | 'getPublicTourReviewsSummary' | 'listPublicTourRoute' | 'listPublicTravelKnowledge' | 'getPublicTravelStatus' | 'listPublicTravellerStories' | 'createPublicBookingIntent' | 'createPublicBrochureLead' | 'createPublicInquiry';
|
|
7
|
+
export type GeneratedPublicApiSchemaName = 'BookingIntentConflictErrorResponse' | 'BookingIntentResponse' | 'CanonicalIntakeAttribution' | 'CanonicalIntakeConsent' | 'CreateBookingIntentRequest' | 'CreateBookingIntentSuccessResponse' | 'CreateBrochureLeadRequest' | 'CreateBrochureLeadResponse' | 'CreateInquiryRequest' | 'CreateInquiryResponse' | 'GetBookingIntentStatusResponse' | 'PaginationMeta' | 'PublicApiAbuseBlockedError' | 'PublicApiError' | 'PublicApiInternalError' | 'PublicApiNotFoundError' | 'PublicApiNotImplementedError' | 'PublicApiRateLimitError' | 'PublicApiTravelStatusUnavailableError' | 'PublicApiValidationError' | 'PublicAvailabilityListItem' | 'PublicAvailabilityListResponse' | 'PublicBookingIntentLinks' | 'PublicBookingIntentPublicStatus' | 'PublicBookingIntentStatus' | 'PublicCityDestinationContent' | 'PublicCityExperience' | 'PublicCityImage' | 'PublicCityLabelledValue' | 'PublicCityLink' | 'PublicCityNextPlace' | 'PublicCityReason' | 'PublicCityResource' | 'PublicCityRoutePattern' | 'PublicCityStayLink' | 'PublicCmsContentSnapshotId' | 'PublicDepartureListItem' | 'PublicDepartureListResponse' | 'PublicDestinationDetail' | 'PublicDestinationDetailResponse' | 'PublicDestinationListItem' | 'PublicDestinationListResponse' | 'PublicError' | 'PublicErrorEnvelope' | 'PublicHomepageResponse' | 'PublicHomepageSeo' | 'PublicHomepageStats' | 'PublicLocaleRegistryData' | 'PublicLocaleRegistryItem' | 'PublicLocaleRegistryResponse' | 'PublicLocaleTag' | 'PublicLocalizationCandidatePreview' | 'PublicLocalizationCandidatePreviewResponse' | 'PublicLocalizationRelease' | 'PublicLocalizationReleaseId' | 'PublicLocalizationReleaseResponse' | 'PublicLocalizationSnapshotReferences' | 'PublicNavLink' | 'PublicOfficialSourceCard' | 'PublicPriceDisplayByCurrency' | 'PublicSearchResultGroup' | 'PublicSearchResultItem' | 'PublicSearchResultsResponse' | 'PublicSearchSuggestion' | 'PublicSearchSuggestionsResponse' | 'PublicSeo' | 'PublicSiteChromeContent' | 'PublicSiteChromeContentResponse' | 'PublicSiteCta' | 'PublicSiteFeaturesResponse' | 'PublicSiteFeatureStates' | 'PublicSiteFooterNavGroup' | 'PublicSiteFooterNavGroupLink' | 'PublicSiteFooterPaymentNote' | 'PublicSiteFooterSupportBand' | 'PublicSiteHeaderMenuCategory' | 'PublicSiteHeaderMenuEditorial' | 'PublicSiteHeaderOffice' | 'PublicSiteHeaderQuickLink' | 'PublicSiteHeaderSearchShortcuts' | 'PublicSiteHomeContent' | 'PublicSiteHomeContentResponse' | 'PublicSiteHomeSection' | 'PublicSitemapEntry' | 'PublicSitemapResponse' | 'PublicSiteNavigationResponse' | 'PublicSiteNavItem' | 'PublicSiteRouteKey' | 'PublicSiteSocialLink' | 'PublicSiteTrustPageContent' | 'PublicSiteTrustPageContentResponse' | 'PublicSiteTrustPageSeo' | 'PublicSiteTrustSection' | 'PublicSiteTrustTitledItem' | 'PublicStaticLink' | 'PublicSurfiranOperationalUpdate' | 'PublicTourAccommodationListItem' | 'PublicTourAccommodationListResponse' | 'PublicTourCatalogDepartureSummary' | 'PublicTourCatalogFacetOption' | 'PublicTourCatalogMetadata' | 'PublicTourCategoryListItem' | 'PublicTourCategoryListResponse' | 'PublicTourDetail' | 'PublicTourDetailEditorial' | 'PublicTourDetailResponse' | 'PublicTourExperienceFrame' | 'PublicTourExperienceListItem' | 'PublicTourExperienceListResponse' | 'PublicTourItineraryDay' | 'PublicTourItineraryResponse' | 'PublicTourListItem' | 'PublicTourListResponse' | 'PublicTourMediaItem' | 'PublicTourQuestionListItem' | 'PublicTourQuestionListResponse' | 'PublicTourRatingBreakdownItem' | 'PublicTourReviewListItem' | 'PublicTourReviewListResponse' | 'PublicTourReviewsAggregate' | 'PublicTourReviewsSummary' | 'PublicTourReviewsSummaryResponse' | 'PublicTourRouteResponse' | 'PublicTourRouteStop' | 'PublicTourTailorJourney' | 'PublicTravelKnowledgeItem' | 'PublicTravelKnowledgeResponse' | 'PublicTravellerStoryListItem' | 'PublicTravellerStoryListResponse' | 'PublicTravelStatusCorrectionNotice' | 'PublicTravelStatusFreshness' | 'PublicTravelStatusHandoff' | 'PublicTravelStatusResponse' | 'PublicTravelStatusReviewerLabel' | 'PublicTravelStatusSection' | 'PublicTravelStatusState' | 'PublicTripBrief' | 'PublicUiCatalog' | 'PublicUiCatalogFallbackSummary' | 'PublicUiCatalogMessage' | 'PublicUiCatalogResponse' | 'PublicUiCatalogSnapshotId';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { createPublicApiClient } from './client.js';
|
|
2
|
-
export type { PublicApiErrorCode, PublicApiV1Path, PublicApiV1RouteMap, PublicError, PublicErrorEnvelope, PublicApiError, PublicApiNotImplementedError, PublicApiValidationError, PublicApiRateLimitError, PublicApiAbuseBlockedError, PublicTourListItem, PublicTourDetail, PublicTourDetailEditorial, PublicDepartureListItem, PublicAvailabilityStatus, PublicAvailabilityListItem, PublicAvailabilityListResponse, PublicDestinationListItem, PublicCityDestinationContent, PublicCityExperience, PublicCityImage, PublicCityLabelledValue, PublicCityLink, PublicCityNextPlace, PublicCityReason, PublicCityResource, PublicCityStayLink, PublicDestinationDetail, PublicTourListResponse, PublicTourDetailResponse, PublicDepartureListResponse, PublicDestinationListResponse, PublicDestinationDetailResponse, PublicApiResult, ListPublicToursParams, GetPublicTourPreviewParams, ListPublicDeparturesParams, ListPublicTourAvailabilityParams, ListPublicDestinationsParams, PublicInquiryRequest, PublicTourTailorJourney, PublicInquiryResponse, PublicBookingIntentRequest, PublicBookingIntentData, PublicBookingIntentResponse, PublicHomepageStats, PublicHomepageSeo, PublicHomepageResponse, PublicSitemapEntry, PublicSitemapResponse, PublicNavLink, PublicStaticLink, PublicSiteNavigationResponse, PublicTourCategoryListItem, PublicTourCategoryListResponse, PublicSearchSuggestion, PublicSearchSuggestionsResponse, PublicSiteRouteKey, PublicSiteCta, PublicSiteHomeSectionType, PublicSiteHomeSection, PublicSiteHomeContent, PublicSiteHomeContentResponse, PublicSiteNavItem, PublicSiteSocialPlatform, PublicSiteSocialLink, PublicSiteChromeContent, PublicSiteChromeContentResponse, PublicSiteFeatureStates, PublicSiteFeaturesResponse, PublicSiteTrustSectionType, PublicSiteTrustTitledItem, PublicSiteTrustParagraphGroup, PublicSiteTrustTitledItemList, PublicSiteTrustBulletList, PublicSiteTrustSection, PublicSiteTrustPageSeo, PublicSiteTrustPageContent, PublicSiteTrustPageContentResponse, PublicTravelStatusState, PublicTravelStatusFreshness, PublicSurfiranOperationalUpdate, PublicTravelStatusResponse, PublicTravelKnowledgeType, PublicTravelKnowledgeItem, PublicTravelKnowledgeResponse, GetPublicSitemapParams, GetPublicSearchSuggestionsParams, GetPublicTravelKnowledgeParams, ListPublicTourCategoriesParams, PublicTravellerStoryListItem, PublicTravellerStoryListResponse, ListPublicTravellerStoriesParams, PublicTourQuestionListItem, PublicTourQuestionListResponse, ListPublicTourQuestionsParams, PublicTourExperienceFrame, PublicTourExperienceListItem, PublicTourExperienceListResponse, ListPublicTourExperiencesParams, PublicTourAccommodationListItem, PublicTourAccommodationListResponse, ListPublicTourAccommodationsParams, PublicTourReviewsAggregate, PublicTourRatingBreakdownItem, PublicTourReviewsSummary, PublicTourReviewsSummaryResponse, PublicTourReviewListItem, PublicTourReviewListResponse, PublicTourReviewsLimit, ListPublicTourReviewsParams, PublicTourRouteStop, PublicTourRouteResponse, ListPublicTourRouteParams, PublicItineraryMealCode, PublicTourItineraryDay, PublicTourItineraryResponse, ListPublicTourItineraryParams, PublicBrochureLeadRequest, PublicBrochureLeadResponse, } from './types.js';
|
|
2
|
+
export type { PublicApiErrorCode, PublicApiV1Path, PublicApiV1RouteMap, PublicError, PublicErrorEnvelope, PublicApiError, PublicApiNotImplementedError, PublicApiValidationError, PublicApiRateLimitError, PublicApiAbuseBlockedError, PublicTourListItem, PublicTourDetail, PublicTourDetailEditorial, PublicDepartureListItem, PublicAvailabilityStatus, PublicAvailabilityListItem, PublicAvailabilityListResponse, PublicDestinationListItem, PublicCityDestinationContent, PublicCityExperience, PublicCityImage, PublicCityLabelledValue, PublicCityLink, PublicCityNextPlace, PublicCityReason, PublicCityResource, PublicCityStayLink, PublicDestinationDetail, PublicTourListResponse, PublicTourCatalogMetadata, PublicTourCatalogFacetKey, PublicTourCatalogFacetOption, PublicTourCatalogSort, PublicTourCatalogDepartureSummary, PublicTourDetailResponse, PublicDepartureListResponse, PublicDestinationListResponse, PublicDestinationDetailResponse, PublicApiResult, ListPublicToursParams, GetPublicTourParams, PublicContentLocale, GetPublicTourPreviewParams, ListPublicDeparturesParams, ListPublicTourAvailabilityParams, ListPublicDestinationsParams, PublicInquiryRequest, PublicTourTailorJourney, PublicInquiryResponse, PublicBookingIntentRequest, PublicBookingIntentData, PublicBookingIntentResponse, PublicHomepageStats, PublicHomepageSeo, PublicHomepageResponse, PublicSitemapEntry, PublicSitemapResponse, PublicNavLink, PublicStaticLink, PublicSiteNavigationResponse, PublicTourCategoryListItem, PublicTourCategoryListResponse, PublicPriceDisplayByCurrency, PublicSearchResultItem, PublicSearchResultGroup, PublicSearchResultsResponse, PublicSearchSuggestion, PublicSearchSuggestionsResponse, PublicSiteRouteKey, PublicSiteCta, PublicSiteHomeSectionType, PublicSiteHomeSection, PublicSiteHomeContent, PublicSiteHomeContentResponse, PublicSiteNavItem, PublicSiteSocialPlatform, PublicSiteSocialLink, PublicSiteHeaderOffice, PublicSiteHeaderMenuCategory, PublicSiteHeaderMenuEditorial, PublicSiteHeaderQuickLink, PublicSiteHeaderSearchShortcuts, PublicSiteFooterNavGroupLink, PublicSiteFooterNavGroup, PublicSiteFooterSupportBand, PublicSiteFooterPaymentNote, PublicSiteChromeContent, PublicSiteChromeContentResponse, PublicSiteFeatureStates, PublicSiteFeaturesResponse, LocaleTag, LocalizationReleaseId, UiCatalogSnapshotId, CmsContentSnapshotId, PublicLocaleRegistryItem, PublicLocaleRegistryResponse, PublicLocalizationRelease, PublicLocalizationReleaseResponse, PublicUiCatalogMessage, PublicUiCatalog, PublicUiCatalogResponse, PublicSiteTrustSectionType, PublicSiteTrustTitledItem, PublicSiteTrustParagraphGroup, PublicSiteTrustTitledItemList, PublicSiteTrustBulletList, PublicSiteTrustSection, PublicSiteTrustPageSeo, PublicSiteTrustPageContent, PublicSiteTrustPageContentResponse, PublicTravelStatusState, PublicTravelStatusFreshness, PublicSurfiranOperationalUpdate, PublicTravelStatusResponse, PublicTravelKnowledgeType, PublicTravelKnowledgeItem, PublicTravelKnowledgeResponse, GetPublicSitemapParams, GetPublicSearchResultsParams, GetPublicSearchSuggestionsParams, GetPublicTravelKnowledgeParams, ListPublicTourCategoriesParams, PublicTravellerStoryListItem, PublicTravellerStoryListResponse, ListPublicTravellerStoriesParams, PublicTourQuestionListItem, PublicTourQuestionListResponse, ListPublicTourQuestionsParams, PublicTourExperienceFrame, PublicTourExperienceListItem, PublicTourExperienceListResponse, ListPublicTourExperiencesParams, PublicTourAccommodationListItem, PublicTourAccommodationListResponse, ListPublicTourAccommodationsParams, PublicTourReviewsAggregate, PublicTourRatingBreakdownItem, PublicTourReviewsSummary, PublicTourReviewsSummaryResponse, PublicTourReviewListItem, PublicTourReviewListResponse, PublicTourReviewsLimit, ListPublicTourReviewsParams, PublicTourRouteStop, PublicTourRouteResponse, ListPublicTourRouteParams, PublicItineraryMealCode, PublicTourItineraryDay, PublicTourItineraryResponse, ListPublicTourItineraryParams, PublicBrochureLeadRequest, PublicBrochureLeadResponse, } from './types.js';
|
|
3
3
|
export type { PublicApiClientOptions } from './client.js';
|
|
4
4
|
export type { GeneratedPublicApiVersion, GeneratedPublicApiPath, GeneratedPublicApiOperation, GeneratedPublicApiActiveOperation, GeneratedPublicApiBlockedOperation, GeneratedPublicApiOperationId, GeneratedPublicApiSchemaName, } from './generated/public-api-v1.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type PublicApiErrorCode = 'PUBLIC_API_ROUTE_NOT_IMPLEMENTED' | 'PUBLIC_API_INTERNAL_ERROR' | 'PUBLIC_API_TOUR_NOT_FOUND' | 'PUBLIC_API_DESTINATION_NOT_FOUND' | 'PUBLIC_API_INVALID_QUERY' | 'PUBLIC_API_BOOKING_INTENT_VALIDATION_ERROR' | 'PUBLIC_API_IDEMPOTENCY_CONFLICT' | 'PUBLIC_API_RATE_LIMITED' | 'PUBLIC_API_ABUSE_BLOCKED' | 'PUBLIC_API_TRAVEL_STATUS_UNAVAILABLE' | 'PUBLIC_API_SITE_CONTENT_UNAVAILABLE' | 'PUBLIC_API_CLIENT_TIMEOUT';
|
|
2
|
-
export type PublicApiV1Path = '/homepage' | '/site-navigation' | '/site-features' | '/sitemap' | '/search-suggestions' | '/tour-categories' | '/tours' | '/tours/{slug}' | '/tours/{slug}/preview' | '/tours/{slug}/departures' | '/tours/{slug}/availability' | '/tours/{slug}/reviews' | '/destinations' | '/destinations/{slug}' | '/inquiries' | '/booking-intents' | '/travel-status' | '/travel-knowledge' | '/site-content/home' | '/site-content/header' | '/site-content/footer' | '/site-content/about' | '/site-content/contact' | '/site-content/tailor-made' | '/site-content/faqs' | '/site-content/privacy' | '/site-content/terms' | '/site-content/responsible-travel' | '/site-content/iran-travel-status' | '/site-content/iran-visa-information' | '/site-content/money-in-iran' | '/site-content/travel-insurance' | '/site-content/health-safety-support' | '/site-content/booking-cancellation-policy' | '/site-content/cookie-policy' | '/site-content/accessibility-statement';
|
|
1
|
+
export type PublicApiErrorCode = 'PUBLIC_API_ROUTE_NOT_IMPLEMENTED' | 'PUBLIC_API_INTERNAL_ERROR' | 'PUBLIC_API_TOUR_NOT_FOUND' | 'PUBLIC_API_DESTINATION_NOT_FOUND' | 'PUBLIC_API_INVALID_QUERY' | 'PUBLIC_API_BOOKING_INTENT_VALIDATION_ERROR' | 'PUBLIC_API_IDEMPOTENCY_CONFLICT' | 'PUBLIC_API_RATE_LIMITED' | 'PUBLIC_API_ABUSE_BLOCKED' | 'PUBLIC_API_TRAVEL_STATUS_UNAVAILABLE' | 'PUBLIC_API_SITE_CONTENT_UNAVAILABLE' | 'PUBLIC_API_LOCALIZATION_NOT_FOUND' | 'PUBLIC_API_LOCALIZATION_UNAVAILABLE' | 'PUBLIC_API_CLIENT_TIMEOUT';
|
|
2
|
+
export type PublicApiV1Path = '/homepage' | '/site-navigation' | '/site-features' | '/locales' | '/localization/previews/{candidateId}' | '/localization/releases/{releaseId}' | '/localization/ui-catalogs/{snapshotId}' | '/sitemap' | '/search-suggestions' | '/tour-categories' | '/tours' | '/tours/{slug}' | '/tours/{slug}/preview' | '/tours/{slug}/departures' | '/tours/{slug}/availability' | '/tours/{slug}/reviews' | '/destinations' | '/destinations/{slug}' | '/inquiries' | '/booking-intents' | '/travel-status' | '/travel-knowledge' | '/site-content/home' | '/site-content/header' | '/site-content/footer' | '/site-content/about' | '/site-content/contact' | '/site-content/tailor-made' | '/site-content/faqs' | '/site-content/privacy' | '/site-content/terms' | '/site-content/responsible-travel' | '/site-content/iran-travel-status' | '/site-content/iran-visa-information' | '/site-content/money-in-iran' | '/site-content/travel-insurance' | '/site-content/health-safety-support' | '/site-content/booking-cancellation-policy' | '/site-content/cookie-policy' | '/site-content/accessibility-statement';
|
|
3
3
|
export type PublicError = {
|
|
4
4
|
code: string;
|
|
5
5
|
message: string;
|
|
@@ -51,7 +51,23 @@ export type PublicApiIdempotencyConflictError = {
|
|
|
51
51
|
status: 409;
|
|
52
52
|
};
|
|
53
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* One finished display string per public display currency.
|
|
56
|
+
*
|
|
57
|
+
* Deliberately a per-payload map rather than a `?currency=` query parameter: a
|
|
58
|
+
* parameter would multiply every cached page by the number of currencies, while
|
|
59
|
+
* a map is one cache entry serving all of them and lets a consumer switch
|
|
60
|
+
* currency with no refetch. Every entry is `null` when the price, or the amount
|
|
61
|
+
* behind it, is not publishable.
|
|
62
|
+
*/
|
|
63
|
+
export type PublicPriceDisplayByCurrency = {
|
|
64
|
+
USD: string | null;
|
|
65
|
+
EUR: string | null;
|
|
66
|
+
GBP: string | null;
|
|
67
|
+
};
|
|
54
68
|
export type PublicTourListItem = {
|
|
69
|
+
/** Published dates, independent of capacity; present in catalog mode. */
|
|
70
|
+
departureSummary?: PublicTourCatalogDepartureSummary;
|
|
55
71
|
id: number;
|
|
56
72
|
slug: string;
|
|
57
73
|
title: string;
|
|
@@ -60,6 +76,16 @@ export type PublicTourListItem = {
|
|
|
60
76
|
durationNights: number | null;
|
|
61
77
|
startingPriceDisplay: string | null;
|
|
62
78
|
currency: string | null;
|
|
79
|
+
/**
|
|
80
|
+
* The same published starting price rendered in each display currency the
|
|
81
|
+
* public site offers. Finished display strings, never rates or raw amounts:
|
|
82
|
+
* the CRM converts from its own operational `fx_rates`, so a consumer picks a
|
|
83
|
+
* string and can neither round nor format differently.
|
|
84
|
+
*
|
|
85
|
+
* A currency with no active rate for this price's own currency is `null`, and
|
|
86
|
+
* the consumer falls back to `startingPriceDisplay` as published.
|
|
87
|
+
*/
|
|
88
|
+
priceDisplayByCurrency: PublicPriceDisplayByCurrency;
|
|
63
89
|
heroImage: string | null;
|
|
64
90
|
primaryDestinations: string[];
|
|
65
91
|
/**
|
|
@@ -383,6 +409,7 @@ export type PublicAvailabilityListItem = {
|
|
|
383
409
|
bookingStatus: 'open' | 'closed' | null;
|
|
384
410
|
currency: string | null;
|
|
385
411
|
priceDisplay: string | null;
|
|
412
|
+
priceDisplayByCurrency: PublicPriceDisplayByCurrency;
|
|
386
413
|
promoLabel?: string | null;
|
|
387
414
|
publicNote?: string | null;
|
|
388
415
|
roomBasis?: 'twin_share' | 'double_share' | 'single_room' | 'triple_share' | 'family_room' | null;
|
|
@@ -390,6 +417,7 @@ export type PublicAvailabilityListItem = {
|
|
|
390
417
|
basis: 'twin_share' | 'double_share' | 'single_room' | 'private_departure';
|
|
391
418
|
label: string;
|
|
392
419
|
priceDisplay: string;
|
|
420
|
+
priceDisplayByCurrency: PublicPriceDisplayByCurrency;
|
|
393
421
|
minimumTravelers?: number;
|
|
394
422
|
}>;
|
|
395
423
|
remainingCapacityBucket: 'available' | 'limited' | 'full' | 'unconstrained' | 'unknown';
|
|
@@ -550,7 +578,25 @@ export type PublicTourListResponse = {
|
|
|
550
578
|
data: PublicTourListItem[];
|
|
551
579
|
nextCursor: string | null;
|
|
552
580
|
total: number;
|
|
581
|
+
catalog?: PublicTourCatalogMetadata;
|
|
582
|
+
};
|
|
583
|
+
export type PublicTourCatalogDepartureSummary = {
|
|
584
|
+
nextDepartureDate: string | null;
|
|
585
|
+
upcomingCount: number;
|
|
586
|
+
upcomingMonths: string[];
|
|
587
|
+
};
|
|
588
|
+
export type PublicTourCatalogFacetKey = 'countries' | 'styles' | 'travelFormats' | 'activityLevels' | 'durationBuckets' | 'journeyTypes' | 'months';
|
|
589
|
+
export type PublicTourCatalogFacetOption = {
|
|
590
|
+
value: string;
|
|
591
|
+
label: string;
|
|
592
|
+
count: number;
|
|
593
|
+
};
|
|
594
|
+
export type PublicTourCatalogMetadata = {
|
|
595
|
+
asOf: string;
|
|
596
|
+
unfilteredTotal: number;
|
|
597
|
+
facets: Record<PublicTourCatalogFacetKey, PublicTourCatalogFacetOption[]>;
|
|
553
598
|
};
|
|
599
|
+
export type PublicTourCatalogSort = 'departure-soonest' | 'duration-asc' | 'duration-desc' | 'default';
|
|
554
600
|
export type PublicTourDetailResponse = {
|
|
555
601
|
data: PublicTourDetail;
|
|
556
602
|
};
|
|
@@ -808,6 +854,17 @@ export type PublicTourCategoryListItem = {
|
|
|
808
854
|
slug: string;
|
|
809
855
|
name: string;
|
|
810
856
|
tourCount: number;
|
|
857
|
+
/**
|
|
858
|
+
* Shortest published duration among this category's active tours, in days.
|
|
859
|
+
* Derived from active tour data, never authored, so a rendered range cannot
|
|
860
|
+
* disagree with the catalogue. `null` when no tour in the category publishes
|
|
861
|
+
* a usable duration -- never a guessed value.
|
|
862
|
+
*
|
|
863
|
+
* Optional so a response projected before these fields existed typechecks.
|
|
864
|
+
*/
|
|
865
|
+
durationMinDays?: number | null;
|
|
866
|
+
/** Longest published duration. Same derivation and same null rule. */
|
|
867
|
+
durationMaxDays?: number | null;
|
|
811
868
|
};
|
|
812
869
|
export type PublicTourCategoryListResponse = {
|
|
813
870
|
data: PublicTourCategoryListItem[];
|
|
@@ -825,6 +882,37 @@ export type PublicSearchSuggestionsResponse = {
|
|
|
825
882
|
total: number;
|
|
826
883
|
query: string;
|
|
827
884
|
};
|
|
885
|
+
/**
|
|
886
|
+
* One search hit. Already-public identity and published summary text only.
|
|
887
|
+
*
|
|
888
|
+
* Guides are deliberately absent from the union: guide records are staff and
|
|
889
|
+
* supplier data and no public-safe guide projection exists, so a guide group
|
|
890
|
+
* would be a promise the contract cannot keep.
|
|
891
|
+
*/
|
|
892
|
+
export type PublicSearchResultItem = {
|
|
893
|
+
type: 'tour' | 'destination';
|
|
894
|
+
label: string;
|
|
895
|
+
slug: string;
|
|
896
|
+
path: string;
|
|
897
|
+
summary: string | null;
|
|
898
|
+
};
|
|
899
|
+
export type PublicSearchResultGroup = {
|
|
900
|
+
type: 'tour' | 'destination';
|
|
901
|
+
/** Every match found in the scanned set, which may exceed `items.length`. */
|
|
902
|
+
total: number;
|
|
903
|
+
items: PublicSearchResultItem[];
|
|
904
|
+
};
|
|
905
|
+
export type PublicSearchResultsResponse = {
|
|
906
|
+
query: string;
|
|
907
|
+
groups: PublicSearchResultGroup[];
|
|
908
|
+
/** Sum of every group total. */
|
|
909
|
+
total: number;
|
|
910
|
+
/**
|
|
911
|
+
* False when the published set outgrew the server's scan bound, so a caller
|
|
912
|
+
* can tell "no more matches" from "we stopped looking". Never silently true.
|
|
913
|
+
*/
|
|
914
|
+
complete: boolean;
|
|
915
|
+
};
|
|
828
916
|
export type PublicTravelKnowledgeType = 'city' | 'landmark' | 'activity' | 'accommodation_label' | 'theme';
|
|
829
917
|
export type PublicTravelKnowledgeItem = {
|
|
830
918
|
type: PublicTravelKnowledgeType;
|
|
@@ -892,7 +980,7 @@ export type PublicTravelStatusResponse = {
|
|
|
892
980
|
};
|
|
893
981
|
};
|
|
894
982
|
/** Closed public route vocabulary. Routing is resolved by the rendering layer. */
|
|
895
|
-
export type PublicSiteRouteKey = 'home' | 'tours' | 'tour-categories' | 'destinations' | 'about' | 'contact' | 'inquire' | 'faqs' | 'privacy' | 'terms' | 'responsible-travel' | 'iran-travel-status' | 'iran-visa-information' | 'money-in-iran' | 'travel-insurance' | 'health-safety-support' | 'booking-cancellation-policy' | 'cookie-policy' | 'accessibility-statement' | 'reviews' | 'travel-trade' | 'tailor-made';
|
|
983
|
+
export type PublicSiteRouteKey = 'home' | 'tours' | 'tour-categories' | 'destinations' | 'about' | 'contact' | 'inquire' | 'faqs' | 'privacy' | 'terms' | 'responsible-travel' | 'iran-travel-status' | 'iran-visa-information' | 'money-in-iran' | 'travel-insurance' | 'health-safety-support' | 'booking-cancellation-policy' | 'cookie-policy' | 'accessibility-statement' | 'reviews' | 'travel-trade' | 'tailor-made' | 'ask-a-specialist' | 'journal' | 'travel-guide' | 'airport-transfers';
|
|
896
984
|
export type PublicSiteCta = {
|
|
897
985
|
label: string;
|
|
898
986
|
routeKey: PublicSiteRouteKey;
|
|
@@ -922,12 +1010,99 @@ export type PublicSiteSocialLink = {
|
|
|
922
1010
|
platform: PublicSiteSocialPlatform;
|
|
923
1011
|
url: string;
|
|
924
1012
|
};
|
|
1013
|
+
/**
|
|
1014
|
+
* Published office line for the site chrome.
|
|
1015
|
+
*
|
|
1016
|
+
* `timeZone` is an IANA zone name, so a consumer formats a real local time from
|
|
1017
|
+
* it. A numeric UTC offset is deliberately not representable -- it would be
|
|
1018
|
+
* wrong for half the year in any zone that observes a transition -- and a zone
|
|
1019
|
+
* the serving runtime cannot format is emitted as `null` rather than passed on.
|
|
1020
|
+
*/
|
|
1021
|
+
export type PublicSiteHeaderOffice = {
|
|
1022
|
+
label: string | null;
|
|
1023
|
+
hoursText: string | null;
|
|
1024
|
+
/** IANA time zone name, for example `Asia/Tehran`. */
|
|
1025
|
+
timeZone: string | null;
|
|
1026
|
+
};
|
|
1027
|
+
/**
|
|
1028
|
+
* Operator-authored editorial for one tour category, keyed on the slug
|
|
1029
|
+
* `GET /tour-categories` publishes.
|
|
1030
|
+
*
|
|
1031
|
+
* Editorial text only. Tour counts and duration ranges are derived from active
|
|
1032
|
+
* tour data and are deliberately not representable here, so a published value
|
|
1033
|
+
* can never disagree with the catalogue.
|
|
1034
|
+
*/
|
|
1035
|
+
export type PublicSiteHeaderMenuCategory = {
|
|
1036
|
+
categorySlug: string;
|
|
1037
|
+
blurb: string | null;
|
|
1038
|
+
ctaLabel: string | null;
|
|
1039
|
+
tags: string[];
|
|
1040
|
+
};
|
|
1041
|
+
export type PublicSiteHeaderMenuEditorial = {
|
|
1042
|
+
iranTagline: string | null;
|
|
1043
|
+
categories: PublicSiteHeaderMenuCategory[];
|
|
1044
|
+
};
|
|
1045
|
+
/**
|
|
1046
|
+
* A search-dialog shortcut. Carries a closed route key, never a path or URL, so
|
|
1047
|
+
* a shortcut can never point off-site or at an internal CRM route.
|
|
1048
|
+
*/
|
|
1049
|
+
export type PublicSiteHeaderQuickLink = {
|
|
1050
|
+
label: string;
|
|
1051
|
+
routeKey: PublicSiteRouteKey;
|
|
1052
|
+
};
|
|
1053
|
+
export type PublicSiteHeaderSearchShortcuts = {
|
|
1054
|
+
popularSearches: string[];
|
|
1055
|
+
quickLinks: PublicSiteHeaderQuickLink[];
|
|
1056
|
+
};
|
|
1057
|
+
/** One link inside a footer navigation group. Carries a closed route key, never a path. */
|
|
1058
|
+
export type PublicSiteFooterNavGroupLink = {
|
|
1059
|
+
label: string;
|
|
1060
|
+
routeKey: PublicSiteRouteKey;
|
|
1061
|
+
};
|
|
1062
|
+
/** One of the footer's grouped navigation columns (for example "Explore"). */
|
|
1063
|
+
export type PublicSiteFooterNavGroup = {
|
|
1064
|
+
title: string;
|
|
1065
|
+
links: PublicSiteFooterNavGroupLink[];
|
|
1066
|
+
};
|
|
1067
|
+
/** The footer's "Planning a trip to Iran?" support band. `null` when nothing is published. */
|
|
1068
|
+
export type PublicSiteFooterSupportBand = {
|
|
1069
|
+
heading: string | null;
|
|
1070
|
+
body: string | null;
|
|
1071
|
+
primary: PublicSiteCta | null;
|
|
1072
|
+
secondary: PublicSiteCta | null;
|
|
1073
|
+
};
|
|
1074
|
+
/** The footer's "Payment" row body copy and its one CTA. `null` when nothing is published. */
|
|
1075
|
+
export type PublicSiteFooterPaymentNote = {
|
|
1076
|
+
body: string | null;
|
|
1077
|
+
cta: PublicSiteCta | null;
|
|
1078
|
+
};
|
|
925
1079
|
export type PublicSiteChromeContent = {
|
|
926
1080
|
navItems: PublicSiteNavItem[];
|
|
927
1081
|
cta: PublicSiteCta | null;
|
|
928
1082
|
contactEmail: string | null;
|
|
929
1083
|
contactPhone: string | null;
|
|
930
1084
|
socialLinks: PublicSiteSocialLink[];
|
|
1085
|
+
/**
|
|
1086
|
+
* Header editorial. These three exist on both shared surfaces so the shape is
|
|
1087
|
+
* stable, but they are Header concepts: the Footer publishes `null` for each.
|
|
1088
|
+
* An unpublished or unusable value is `null` rather than an empty object, so a
|
|
1089
|
+
* consumer has one absent case to handle rather than two.
|
|
1090
|
+
*
|
|
1091
|
+
* Optional so a response projected before these fields existed typechecks.
|
|
1092
|
+
*/
|
|
1093
|
+
office?: PublicSiteHeaderOffice | null;
|
|
1094
|
+
menuEditorial?: PublicSiteHeaderMenuEditorial | null;
|
|
1095
|
+
searchShortcuts?: PublicSiteHeaderSearchShortcuts | null;
|
|
1096
|
+
/**
|
|
1097
|
+
* Footer editorial. These exist on both shared surfaces so the shape is
|
|
1098
|
+
* stable, but they are Footer concepts: the Header publishes an empty array
|
|
1099
|
+
* / `null` for each.
|
|
1100
|
+
*
|
|
1101
|
+
* Optional so a response projected before these fields existed typechecks.
|
|
1102
|
+
*/
|
|
1103
|
+
navGroups?: PublicSiteFooterNavGroup[];
|
|
1104
|
+
supportBand?: PublicSiteFooterSupportBand | null;
|
|
1105
|
+
paymentNote?: PublicSiteFooterPaymentNote | null;
|
|
931
1106
|
};
|
|
932
1107
|
export type PublicSiteChromeContentResponse = {
|
|
933
1108
|
data: PublicSiteChromeContent | null;
|
|
@@ -1050,11 +1225,99 @@ export type PublicSiteFeaturesResponse = {
|
|
|
1050
1225
|
features: PublicSiteFeatureStates;
|
|
1051
1226
|
};
|
|
1052
1227
|
};
|
|
1228
|
+
export type LocaleTag = string;
|
|
1229
|
+
export type LocalizationReleaseId = `lr1_${string}`;
|
|
1230
|
+
export type LocalizationPreviewCapability = string;
|
|
1231
|
+
export type UiCatalogSnapshotId = `ui1_${string}`;
|
|
1232
|
+
export type CmsContentSnapshotId = `cms1_${string}`;
|
|
1233
|
+
export type PublicLocaleRegistryItem = {
|
|
1234
|
+
localeTag: LocaleTag;
|
|
1235
|
+
language: string;
|
|
1236
|
+
script: string | null;
|
|
1237
|
+
region: string | null;
|
|
1238
|
+
direction: 'ltr' | 'rtl';
|
|
1239
|
+
routePrefix: string;
|
|
1240
|
+
hreflangTag: LocaleTag;
|
|
1241
|
+
fallbackLocaleTag: LocaleTag | null;
|
|
1242
|
+
isDefault: boolean;
|
|
1243
|
+
defaultCalendar: string;
|
|
1244
|
+
defaultNumberingSystem: string;
|
|
1245
|
+
defaultTimeZone: string;
|
|
1246
|
+
activeReleaseId: LocalizationReleaseId;
|
|
1247
|
+
};
|
|
1248
|
+
export type PublicLocaleRegistryResponse = {
|
|
1249
|
+
data: {
|
|
1250
|
+
schemaVersion: 1;
|
|
1251
|
+
marketScope: 'global';
|
|
1252
|
+
locales: PublicLocaleRegistryItem[];
|
|
1253
|
+
};
|
|
1254
|
+
};
|
|
1255
|
+
export type PublicLocalizationRelease = {
|
|
1256
|
+
schemaVersion: 1;
|
|
1257
|
+
releaseId: LocalizationReleaseId;
|
|
1258
|
+
localeTag: LocaleTag;
|
|
1259
|
+
contentLanguage: LocaleTag;
|
|
1260
|
+
channel: 'public_web';
|
|
1261
|
+
marketScope: string;
|
|
1262
|
+
manifestVersion: string;
|
|
1263
|
+
compatibilityVersion: string;
|
|
1264
|
+
checksum: string;
|
|
1265
|
+
snapshots: {
|
|
1266
|
+
uiCatalog: UiCatalogSnapshotId;
|
|
1267
|
+
cmsContent: CmsContentSnapshotId;
|
|
1268
|
+
};
|
|
1269
|
+
};
|
|
1270
|
+
export type PublicLocalizationReleaseResponse = {
|
|
1271
|
+
data: PublicLocalizationRelease;
|
|
1272
|
+
};
|
|
1273
|
+
export type PublicUiCatalogMessage = {
|
|
1274
|
+
messageId: string;
|
|
1275
|
+
resolvedLocale: LocaleTag;
|
|
1276
|
+
fallbackStatus: 'none' | 'safe_fallback';
|
|
1277
|
+
syntaxVersion: string;
|
|
1278
|
+
variableSchema: Record<string, unknown>;
|
|
1279
|
+
value: unknown;
|
|
1280
|
+
contentChecksum: string;
|
|
1281
|
+
};
|
|
1282
|
+
export type PublicUiCatalog = {
|
|
1283
|
+
schemaVersion: 1;
|
|
1284
|
+
snapshotId: UiCatalogSnapshotId;
|
|
1285
|
+
requestedLocale: LocaleTag;
|
|
1286
|
+
sourceLocale: LocaleTag;
|
|
1287
|
+
contentLanguage: LocaleTag;
|
|
1288
|
+
manifestVersion: string;
|
|
1289
|
+
compatibilityVersion: string;
|
|
1290
|
+
checksum: string;
|
|
1291
|
+
fallbackSummary: {
|
|
1292
|
+
itemCount: number;
|
|
1293
|
+
fallbackCount: number;
|
|
1294
|
+
};
|
|
1295
|
+
messages: PublicUiCatalogMessage[];
|
|
1296
|
+
};
|
|
1297
|
+
export type PublicUiCatalogResponse = {
|
|
1298
|
+
data: PublicUiCatalog;
|
|
1299
|
+
};
|
|
1300
|
+
export type PublicLocalizationCandidatePreview = {
|
|
1301
|
+
schemaVersion: 1;
|
|
1302
|
+
candidateId: LocalizationReleaseId;
|
|
1303
|
+
requestedLocale: LocaleTag;
|
|
1304
|
+
contentLanguage: LocaleTag;
|
|
1305
|
+
release: PublicLocalizationRelease;
|
|
1306
|
+
uiCatalog: PublicUiCatalog;
|
|
1307
|
+
};
|
|
1308
|
+
export type PublicLocalizationCandidatePreviewResponse = {
|
|
1309
|
+
data: PublicLocalizationCandidatePreview;
|
|
1310
|
+
};
|
|
1053
1311
|
export type PublicApiV1RouteMap = {
|
|
1054
1312
|
'GET /homepage': PublicHomepageResponse;
|
|
1055
1313
|
'GET /site-navigation': PublicSiteNavigationResponse;
|
|
1056
1314
|
'GET /site-features': PublicSiteFeaturesResponse;
|
|
1315
|
+
'GET /locales': PublicLocaleRegistryResponse;
|
|
1316
|
+
'GET /localization/previews/{candidateId}': PublicLocalizationCandidatePreviewResponse;
|
|
1317
|
+
'GET /localization/releases/{releaseId}': PublicLocalizationReleaseResponse;
|
|
1318
|
+
'GET /localization/ui-catalogs/{snapshotId}': PublicUiCatalogResponse;
|
|
1057
1319
|
'GET /sitemap': PublicSitemapResponse;
|
|
1320
|
+
'GET /search': PublicSearchResultsResponse;
|
|
1058
1321
|
'GET /search-suggestions': PublicSearchSuggestionsResponse;
|
|
1059
1322
|
'GET /tour-categories': PublicTourCategoryListResponse;
|
|
1060
1323
|
'GET /tours': PublicTourListResponse;
|
|
@@ -1101,6 +1364,17 @@ export type PublicApiResult<T> = {
|
|
|
1101
1364
|
requestId: string | null;
|
|
1102
1365
|
};
|
|
1103
1366
|
export type ListPublicToursParams = {
|
|
1367
|
+
/** OR within each group, AND between groups. Values are supplied by catalog facets. */
|
|
1368
|
+
countries?: string[];
|
|
1369
|
+
styles?: string[];
|
|
1370
|
+
travelFormats?: string[];
|
|
1371
|
+
activityLevels?: string[];
|
|
1372
|
+
durationBuckets?: string[];
|
|
1373
|
+
journeyTypes?: string[];
|
|
1374
|
+
months?: string[];
|
|
1375
|
+
hasUpcomingDepartures?: boolean;
|
|
1376
|
+
sort?: PublicTourCatalogSort;
|
|
1377
|
+
includeFacets?: boolean;
|
|
1104
1378
|
limit?: number;
|
|
1105
1379
|
cursor?: string;
|
|
1106
1380
|
/** Itinerary-derived destination slug, matched server-side. */
|
|
@@ -1109,6 +1383,21 @@ export type ListPublicToursParams = {
|
|
|
1109
1383
|
minDuration?: number;
|
|
1110
1384
|
/** Inclusive upper bound on `durationDays`. */
|
|
1111
1385
|
maxDuration?: number;
|
|
1386
|
+
/**
|
|
1387
|
+
* Content locale for CRM-authored tour copy (ADR-0023). Every approved and
|
|
1388
|
+
* published translation replaces its English source; anything not translated,
|
|
1389
|
+
* or translated from text that has since changed, stays as published in
|
|
1390
|
+
* English. Omitted, or 'en', requests the English source. Typed facts —
|
|
1391
|
+
* prices, durations, currencies, availability — are formatted per locale by
|
|
1392
|
+
* the consumer and are never affected by this parameter.
|
|
1393
|
+
*/
|
|
1394
|
+
locale?: PublicContentLocale;
|
|
1395
|
+
};
|
|
1396
|
+
/** Locales the public content contract will resolve translations for. */
|
|
1397
|
+
export type PublicContentLocale = 'en' | 'de' | 'fr' | 'es' | 'it' | 'fa' | 'ar';
|
|
1398
|
+
export type GetPublicTourParams = {
|
|
1399
|
+
/** See ListPublicToursParams['locale']. */
|
|
1400
|
+
locale?: PublicContentLocale;
|
|
1112
1401
|
};
|
|
1113
1402
|
export type ListPublicDeparturesParams = {
|
|
1114
1403
|
limit?: number;
|
|
@@ -1153,6 +1442,12 @@ export type GetPublicSearchSuggestionsParams = {
|
|
|
1153
1442
|
limit?: number;
|
|
1154
1443
|
type?: 'tour' | 'destination';
|
|
1155
1444
|
};
|
|
1445
|
+
export type GetPublicSearchResultsParams = {
|
|
1446
|
+
q: string;
|
|
1447
|
+
/** Maximum items per group. 1 through 25; defaults to 10 server-side. Group totals still report every match. */
|
|
1448
|
+
limit?: number;
|
|
1449
|
+
type?: 'tour' | 'destination';
|
|
1450
|
+
};
|
|
1156
1451
|
export type ListPublicTourCategoriesParams = {
|
|
1157
1452
|
limit?: number;
|
|
1158
1453
|
cursor?: string;
|
package/dist/types.js
CHANGED