@surfiran/public-api-client 0.1.0 → 0.5.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 +74 -4
- package/dist/client.d.ts +2 -1
- package/dist/client.js +5 -0
- package/dist/generated/public-api-v1.d.ts +6 -6
- package/dist/generated/public-api-v1.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +140 -2
- package/dist/types.js +1 -1
- package/package.json +36 -6
package/README.md
CHANGED
|
@@ -5,9 +5,14 @@ TypeScript types and a fetch-based client for SURFIRAN CRM Public API V1 (`/api/
|
|
|
5
5
|
## Contract Source
|
|
6
6
|
|
|
7
7
|
```text
|
|
8
|
-
|
|
8
|
+
contract/public-api-v1.yaml (v0.9.0 package snapshot)
|
|
9
9
|
```
|
|
10
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
|
+
|
|
11
16
|
## Current Runtime Scope
|
|
12
17
|
|
|
13
18
|
Active read endpoints:
|
|
@@ -117,9 +122,74 @@ This package must never:
|
|
|
117
122
|
|
|
118
123
|
## Next.js Usage
|
|
119
124
|
|
|
120
|
-
|
|
125
|
+
The public Next.js website consumes this client as the exact published dependency `@surfiran/public-api-client@0.1.0`. Its TypeScript, Vitest, and build configuration must resolve the package from `node_modules`, never from the monorepo `packages/` source tree.
|
|
126
|
+
|
|
127
|
+
## Code Generation
|
|
128
|
+
|
|
129
|
+
From this package directory, install dependencies and generate the committed
|
|
130
|
+
artifact from the checked-in contract snapshot:
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
npm ci --include=dev
|
|
134
|
+
npm run generate
|
|
135
|
+
npm run verify:contract
|
|
136
|
+
npm run verify:generated
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Generation has stable ordering, formatting, LF newlines, no random identifiers,
|
|
140
|
+
no machine-specific paths, and no uncontrolled timestamps. To synchronize the
|
|
141
|
+
snapshot from the canonical backend source during monorepo development, use the
|
|
142
|
+
explicit root command with a recorded source commit:
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
npm run sync:public-api-client-contract -- --source-commit <canonical-source-commit>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The synchronization command is not required by a package-only clone and must
|
|
149
|
+
not be used to create a competing contract.
|
|
150
|
+
|
|
151
|
+
## Publication and Rollback
|
|
152
|
+
|
|
153
|
+
Publication preflight is validation-only and must run from the package root:
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
npm run verify:contract
|
|
157
|
+
npm run generate
|
|
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
|
+
```
|
|
167
|
+
|
|
168
|
+
Create and verify release provenance with an explicit UTC timestamp, source
|
|
169
|
+
commit, rollback version, and packed tarball:
|
|
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
|
+
```
|
|
183
|
+
|
|
184
|
+
The exact package allowlist is enforced before packing. Provenance links the
|
|
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.
|
|
121
190
|
|
|
122
191
|
## Next Steps
|
|
123
192
|
|
|
124
|
-
- Keep
|
|
125
|
-
-
|
|
193
|
+
- Keep `server/openapi/public-api-v1.yaml` as the API-owned contract source
|
|
194
|
+
- Synchronize the explicit snapshot only from the API-owned canonical source
|
|
195
|
+
- Run package-local generation, validation, provenance, and clean-clone checks
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GetPublicSearchSuggestionsParams, GetPublicSitemapParams, 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, PublicSiteHomeContentResponse, PublicSiteNavigationResponse, PublicSiteTrustPageContentResponse, PublicTourAccommodationListResponse, PublicTourCategoryListResponse, PublicTourDetailResponse, PublicTourExperienceListResponse, PublicTravellerStoryListResponse, PublicTourListResponse, PublicTourQuestionListResponse, PublicTourReviewsSummaryResponse, PublicTourReviewListResponse, PublicTourItineraryResponse, PublicTourRouteResponse, PublicTravelKnowledgeResponse, PublicTravelStatusResponse } from './types.js';
|
|
1
|
+
import type { GetPublicSearchSuggestionsParams, GetPublicSitemapParams, 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';
|
|
2
2
|
export type PublicApiClientOptions = {
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
fetchImpl?: typeof fetch;
|
|
@@ -31,6 +31,7 @@ export declare const createPublicApiClient: (options: PublicApiClientOptions) =>
|
|
|
31
31
|
createPublicBrochureLead(body: PublicBrochureLeadRequest, idempotencyKey?: string): Promise<PublicApiResult<PublicBrochureLeadResponse>>;
|
|
32
32
|
getPublicHomepage(): Promise<PublicApiResult<PublicHomepageResponse>>;
|
|
33
33
|
getPublicSiteNavigation(): Promise<PublicApiResult<PublicSiteNavigationResponse>>;
|
|
34
|
+
getPublicSiteFeatures(): Promise<PublicApiResult<PublicSiteFeaturesResponse>>;
|
|
34
35
|
getPublicSitemap(params?: GetPublicSitemapParams): Promise<PublicApiResult<PublicSitemapResponse>>;
|
|
35
36
|
getPublicSearchSuggestions(params: GetPublicSearchSuggestionsParams): Promise<PublicApiResult<PublicSearchSuggestionsResponse>>;
|
|
36
37
|
listPublicTourCategories(params?: ListPublicTourCategoriesParams): Promise<PublicApiResult<PublicTourCategoryListResponse>>;
|
package/dist/client.js
CHANGED
|
@@ -216,6 +216,11 @@ export const createPublicApiClient = (options) => {
|
|
|
216
216
|
getPublicSiteNavigation() {
|
|
217
217
|
return requestJson(`${baseUrl}/api/v1/site-navigation`, options);
|
|
218
218
|
},
|
|
219
|
+
// Effective public website feature state. One call returns every known
|
|
220
|
+
// feature, so a consumer never needs a per-feature request.
|
|
221
|
+
getPublicSiteFeatures() {
|
|
222
|
+
return requestJson(`${baseUrl}/api/v1/site-features`, options);
|
|
223
|
+
},
|
|
219
224
|
getPublicSitemap(params) {
|
|
220
225
|
return requestJson(`${baseUrl}/api/v1/sitemap${toSitemapQueryString(params)}`, options);
|
|
221
226
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type GeneratedPublicApiVersion = '0.
|
|
2
|
-
export type GeneratedPublicApiPath = '/
|
|
3
|
-
export type GeneratedPublicApiOperation = 'GET /
|
|
4
|
-
export type GeneratedPublicApiActiveOperation = 'GET /
|
|
1
|
+
export type GeneratedPublicApiVersion = '0.9.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/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}/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/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}/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/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}/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 = '
|
|
7
|
-
export type GeneratedPublicApiSchemaName = '
|
|
6
|
+
export type GeneratedPublicApiOperationId = 'getBookingIntent' | 'listPublicDestinations' | 'getPublicDestinationBySlug' | 'getPublicHomepage' | 'getPublicSearchSuggestions' | 'getPublicSiteContentAbout' | 'getPublicSiteContentAccessibilityStatement' | 'getPublicSiteContentBookingCancellationPolicy' | 'getPublicSiteContentContact' | 'getPublicSiteContentCookiePolicy' | 'getPublicSiteContentFaqs' | 'getPublicSiteContentFooter' | 'getPublicSiteContentHeader' | 'getPublicSiteContentHealthSafetySupport' | 'getPublicSiteContentHome' | 'getPublicSiteContentIranTravelStatus' | 'getPublicSiteContentIranVisaInformation' | 'getPublicSiteContentMoneyInIran' | 'getPublicSiteContentPrivacy' | 'getPublicSiteContentResponsibleTravel' | 'getPublicSiteContentTerms' | 'getPublicSiteContentTravelInsurance' | 'getPublicSiteFeatures' | 'getPublicSiteNavigation' | 'getPublicSitemap' | 'listPublicTourCategories' | 'listPublicTours' | 'getPublicTourBySlug' | 'listPublicTourAccommodations' | 'listPublicTourAvailability' | 'listPublicTourDepartures' | 'listPublicTourExperiences' | 'listPublicTourItinerary' | 'listPublicTourQuestions' | 'listPublicTourReviews' | 'getPublicTourReviewsSummary' | 'listPublicTourRoute' | 'listPublicTravelKnowledge' | 'getPublicTravelStatus' | 'listPublicTravellerStories' | 'createPublicBookingIntent' | 'createPublicBrochureLead' | 'createPublicInquiry';
|
|
7
|
+
export type GeneratedPublicApiSchemaName = 'BookingIntentConflictErrorResponse' | 'BookingIntentResponse' | 'CreateBookingIntentRequest' | 'CreateBookingIntentSuccessResponse' | 'CreateBrochureLeadRequest' | 'CreateBrochureLeadResponse' | 'CreateInquiryRequest' | 'CreateInquiryResponse' | 'GetBookingIntentStatusResponse' | 'PaginationMeta' | 'PublicApiAbuseBlockedError' | 'PublicApiError' | 'PublicApiInternalError' | 'PublicApiNotFoundError' | 'PublicApiNotImplementedError' | 'PublicApiRateLimitError' | 'PublicApiTravelStatusUnavailableError' | 'PublicApiValidationError' | 'PublicAvailabilityListItem' | 'PublicAvailabilityListResponse' | 'PublicBookingIntentLinks' | 'PublicBookingIntentPublicStatus' | 'PublicBookingIntentStatus' | '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' | 'PublicTravelKnowledgeItem' | 'PublicTravelKnowledgeResponse' | 'PublicTravellerStoryListItem' | 'PublicTravellerStoryListResponse' | 'PublicTravelStatusCorrectionNotice' | 'PublicTravelStatusFreshness' | 'PublicTravelStatusHandoff' | 'PublicTravelStatusResponse' | 'PublicTravelStatusReviewerLabel' | 'PublicTravelStatusSection' | 'PublicTravelStatusState';
|
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, PublicDepartureListItem, PublicAvailabilityStatus, PublicAvailabilityListItem, PublicAvailabilityListResponse, PublicDestinationListItem, PublicDestinationDetail, PublicTourListResponse, PublicTourDetailResponse, PublicDepartureListResponse, PublicDestinationListResponse, PublicDestinationDetailResponse, PublicApiResult, ListPublicToursParams, ListPublicDeparturesParams, ListPublicTourAvailabilityParams, ListPublicDestinationsParams, PublicInquiryRequest, 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, 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, PublicDestinationDetail, PublicTourListResponse, PublicTourDetailResponse, PublicDepartureListResponse, PublicDestinationListResponse, PublicDestinationDetailResponse, PublicApiResult, ListPublicToursParams, ListPublicDeparturesParams, ListPublicTourAvailabilityParams, ListPublicDestinationsParams, PublicInquiryRequest, 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';
|
|
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,10 +1,17 @@
|
|
|
1
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' | '/sitemap' | '/search-suggestions' | '/tour-categories' | '/tours' | '/tours/{slug}' | '/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/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';
|
|
2
|
+
export type PublicApiV1Path = '/homepage' | '/site-navigation' | '/site-features' | '/sitemap' | '/search-suggestions' | '/tour-categories' | '/tours' | '/tours/{slug}' | '/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/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;
|
|
6
6
|
status: number;
|
|
7
7
|
requestId: string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Optional public-safe diagnostic object (contract schema PublicError.details).
|
|
10
|
+
* Shape varies by error code — e.g. the destination-not-found error may
|
|
11
|
+
* carry `{ redirectSlug: string }` when the requested slug was renamed or
|
|
12
|
+
* merged into another place. Absent when there is nothing safe to expose.
|
|
13
|
+
*/
|
|
14
|
+
details?: Record<string, unknown>;
|
|
8
15
|
};
|
|
9
16
|
export type PublicErrorEnvelope = {
|
|
10
17
|
error: PublicError;
|
|
@@ -133,6 +140,63 @@ export type PublicTourDetail = PublicTourListItem & {
|
|
|
133
140
|
gallery: string[];
|
|
134
141
|
seoTitle: string | null;
|
|
135
142
|
seoDescription: string | null;
|
|
143
|
+
editorial?: PublicTourDetailEditorial | null;
|
|
144
|
+
};
|
|
145
|
+
export type PublicTourDetailEditorial = {
|
|
146
|
+
tourType: string | null;
|
|
147
|
+
tourCode: string | null;
|
|
148
|
+
authorName: string | null;
|
|
149
|
+
authorUrl: string | null;
|
|
150
|
+
authorRole: string | null;
|
|
151
|
+
lastReviewedAt: string | null;
|
|
152
|
+
guideLabel: string | null;
|
|
153
|
+
groupSizeNote: string | null;
|
|
154
|
+
paceLabel: string | null;
|
|
155
|
+
paceNote: string | null;
|
|
156
|
+
comfortLabel: string | null;
|
|
157
|
+
comfortNote: string | null;
|
|
158
|
+
guideNote: string | null;
|
|
159
|
+
startLabel: string | null;
|
|
160
|
+
endLabel: string | null;
|
|
161
|
+
startEndNote: string | null;
|
|
162
|
+
overviewParagraphs: string[];
|
|
163
|
+
heroAltText: string | null;
|
|
164
|
+
heroObjectPosition: string | null;
|
|
165
|
+
galleryAltTexts: string[];
|
|
166
|
+
galleryObjectPositions: string[];
|
|
167
|
+
heroVideo: {
|
|
168
|
+
url: string;
|
|
169
|
+
posterUrl: string | null;
|
|
170
|
+
durationLabel: string | null;
|
|
171
|
+
} | null;
|
|
172
|
+
heroQuote: {
|
|
173
|
+
text: string;
|
|
174
|
+
authorName: string | null;
|
|
175
|
+
sourceUrl: string | null;
|
|
176
|
+
} | null;
|
|
177
|
+
payment?: {
|
|
178
|
+
depositSummary: string | null;
|
|
179
|
+
balanceSummary: string | null;
|
|
180
|
+
cancellationSummary: string | null;
|
|
181
|
+
paymentSummary: string | null;
|
|
182
|
+
};
|
|
183
|
+
operator?: {
|
|
184
|
+
body: string | null;
|
|
185
|
+
imageUrl: string | null;
|
|
186
|
+
aboutUrl: string | null;
|
|
187
|
+
licenceLabel: string | null;
|
|
188
|
+
officeLabel: string | null;
|
|
189
|
+
metrics: Array<{
|
|
190
|
+
value: string;
|
|
191
|
+
label: string;
|
|
192
|
+
}>;
|
|
193
|
+
};
|
|
194
|
+
goodToKnow: Array<{
|
|
195
|
+
title: string;
|
|
196
|
+
body: string;
|
|
197
|
+
ctaLabel: string | null;
|
|
198
|
+
href: string | null;
|
|
199
|
+
}>;
|
|
136
200
|
};
|
|
137
201
|
export type PublicDepartureListItem = {
|
|
138
202
|
id: number;
|
|
@@ -190,6 +254,10 @@ export type PublicTourReviewsAggregate = {
|
|
|
190
254
|
averageRating: number | null;
|
|
191
255
|
reviewCount: number;
|
|
192
256
|
source: string | null;
|
|
257
|
+
/** Public URL for the source aggregate, when the CRM has verified one. */
|
|
258
|
+
sourceUrl?: string | null;
|
|
259
|
+
/** Source platform's operator-wide review count, when published. */
|
|
260
|
+
operatorReviewCount?: number | null;
|
|
193
261
|
/** Most recent staff entry among included reviews — the "as of" honesty marker. */
|
|
194
262
|
lastVerifiedAt: string | null;
|
|
195
263
|
};
|
|
@@ -207,9 +275,13 @@ export type PublicTourReviewListItem = {
|
|
|
207
275
|
authorName: string | null;
|
|
208
276
|
partyType: string | null;
|
|
209
277
|
reviewDate: string | null;
|
|
278
|
+
/** Source-backed month/year label when the original review has no known day. */
|
|
279
|
+
reviewDateLabel?: string | null;
|
|
210
280
|
rating: number;
|
|
211
281
|
title: string;
|
|
212
282
|
body: string;
|
|
283
|
+
/** Public attribution for the operator reply, without the reply body. */
|
|
284
|
+
replyAuthor?: string | null;
|
|
213
285
|
deepLink: string | null;
|
|
214
286
|
};
|
|
215
287
|
/** Meal codes a day can include. Always returned in B,L,D order. */
|
|
@@ -239,6 +311,13 @@ export type PublicTourItineraryDay = {
|
|
|
239
311
|
includedActivities: string[];
|
|
240
312
|
optionalActivities: string[];
|
|
241
313
|
landmarks: string[];
|
|
314
|
+
transportNote: string | null;
|
|
315
|
+
extraNightsNote?: string | null;
|
|
316
|
+
/** Alt text aligned by index with mediaUrls. Older runtime responses may omit it. */
|
|
317
|
+
mediaAltTexts?: string[];
|
|
318
|
+
/** @deprecated Use mediaAltTexts. Retained for older consumers. */
|
|
319
|
+
mediaAltText?: string | null;
|
|
320
|
+
mediaUrls: string[];
|
|
242
321
|
};
|
|
243
322
|
export type PublicTourRouteStop = {
|
|
244
323
|
id: number;
|
|
@@ -265,7 +344,14 @@ export type PublicAvailabilityListItem = {
|
|
|
265
344
|
currency: string | null;
|
|
266
345
|
priceDisplay: string | null;
|
|
267
346
|
promoLabel?: string | null;
|
|
347
|
+
publicNote?: string | null;
|
|
268
348
|
roomBasis?: 'twin_share' | 'double_share' | 'single_room' | 'triple_share' | 'family_room' | null;
|
|
349
|
+
roomOptions?: Array<{
|
|
350
|
+
basis: 'twin_share' | 'double_share' | 'single_room' | 'private_departure';
|
|
351
|
+
label: string;
|
|
352
|
+
priceDisplay: string;
|
|
353
|
+
minimumTravelers?: number;
|
|
354
|
+
}>;
|
|
269
355
|
remainingCapacityBucket: 'available' | 'limited' | 'full' | 'unconstrained' | 'unknown';
|
|
270
356
|
/**
|
|
271
357
|
* Owner directive 2026-08-07: full Home design application — limited-state
|
|
@@ -278,6 +364,26 @@ export type PublicAvailabilityListItem = {
|
|
|
278
364
|
ctaUrl?: string;
|
|
279
365
|
updatedAt: string | null;
|
|
280
366
|
};
|
|
367
|
+
export type PublicSeoRobots = {
|
|
368
|
+
index: boolean;
|
|
369
|
+
follow: boolean;
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Public-safe SEO projection (contract schema PublicSeo). The og fields
|
|
373
|
+
* default to mirroring title/description; destinations with a published place
|
|
374
|
+
* profile may carry operator-authored og overrides, a canonical override, and
|
|
375
|
+
* a robots directive. robots is null when no published source declares one.
|
|
376
|
+
*/
|
|
377
|
+
export type PublicSeo = {
|
|
378
|
+
title: string | null;
|
|
379
|
+
description: string | null;
|
|
380
|
+
canonicalPath: string;
|
|
381
|
+
ogTitle: string | null;
|
|
382
|
+
ogDescription: string | null;
|
|
383
|
+
ogImage: string | null;
|
|
384
|
+
schemaType: string | null;
|
|
385
|
+
robots?: PublicSeoRobots | null;
|
|
386
|
+
};
|
|
281
387
|
export type PublicDestinationListItem = {
|
|
282
388
|
id: number;
|
|
283
389
|
slug: string;
|
|
@@ -285,11 +391,15 @@ export type PublicDestinationListItem = {
|
|
|
285
391
|
summary: string | null;
|
|
286
392
|
heroImage: string | null;
|
|
287
393
|
updatedAt: string | null;
|
|
394
|
+
/** Optional so consumers stay compatible with servers predating the seo projection. */
|
|
395
|
+
seo?: PublicSeo;
|
|
288
396
|
};
|
|
289
397
|
export type PublicDestinationDetail = PublicDestinationListItem & {
|
|
290
398
|
description: string | null;
|
|
291
399
|
seoTitle: string | null;
|
|
292
400
|
seoDescription: string | null;
|
|
401
|
+
/** Operator-authored JSON-LD overrides from the published place profile. */
|
|
402
|
+
structuredDataOverrides?: Record<string, unknown> | null;
|
|
293
403
|
};
|
|
294
404
|
export type PublicTourListResponse = {
|
|
295
405
|
data: PublicTourListItem[];
|
|
@@ -362,6 +472,8 @@ export type PublicInquiryRequest = {
|
|
|
362
472
|
email: string;
|
|
363
473
|
message: string;
|
|
364
474
|
tourSlug?: string | null;
|
|
475
|
+
/** Closed public intent used by the CRM sales queue for inquiry routing. */
|
|
476
|
+
requestType?: 'tour_inquiry' | 'waiting_list' | 'specialist_question' | null;
|
|
365
477
|
/**
|
|
366
478
|
* Optional requested departure date (YYYY-MM-DD) when the inquiry was
|
|
367
479
|
* submitted from a specific public departure card. No departure identifier or
|
|
@@ -550,7 +662,7 @@ export type PublicTravelStatusResponse = {
|
|
|
550
662
|
};
|
|
551
663
|
};
|
|
552
664
|
/** Closed public route vocabulary. Routing is resolved by the rendering layer. */
|
|
553
|
-
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';
|
|
665
|
+
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';
|
|
554
666
|
export type PublicSiteCta = {
|
|
555
667
|
label: string;
|
|
556
668
|
routeKey: PublicSiteRouteKey;
|
|
@@ -637,9 +749,35 @@ export type PublicSiteTrustPageContent = {
|
|
|
637
749
|
export type PublicSiteTrustPageContentResponse = {
|
|
638
750
|
data: PublicSiteTrustPageContent | null;
|
|
639
751
|
};
|
|
752
|
+
/**
|
|
753
|
+
* Effective on/off state for every known public website feature.
|
|
754
|
+
*
|
|
755
|
+
* Closed by construction: the key set is owned by the API's feature registry,
|
|
756
|
+
* so a consumer can only branch on a feature the contract actually declares.
|
|
757
|
+
* The payload is booleans only — it never carries who changed a setting, when,
|
|
758
|
+
* or whether a master control is involved.
|
|
759
|
+
*
|
|
760
|
+
* These configure presentation. Booking, payment, inventory, guaranteed
|
|
761
|
+
* departure, availability, price validity, cancellation, and visa state are
|
|
762
|
+
* authoritative operational facts and never appear here.
|
|
763
|
+
*/
|
|
764
|
+
export type PublicSiteFeatureStates = {
|
|
765
|
+
/**
|
|
766
|
+
* True when the website may offer tour comparison. When false, every Compare
|
|
767
|
+
* control is removed and the comparison page is unavailable. Comparison
|
|
768
|
+
* selections already stored in a visitor's browser are not affected.
|
|
769
|
+
*/
|
|
770
|
+
compareTours: boolean;
|
|
771
|
+
};
|
|
772
|
+
export type PublicSiteFeaturesResponse = {
|
|
773
|
+
data: {
|
|
774
|
+
features: PublicSiteFeatureStates;
|
|
775
|
+
};
|
|
776
|
+
};
|
|
640
777
|
export type PublicApiV1RouteMap = {
|
|
641
778
|
'GET /homepage': PublicHomepageResponse;
|
|
642
779
|
'GET /site-navigation': PublicSiteNavigationResponse;
|
|
780
|
+
'GET /site-features': PublicSiteFeaturesResponse;
|
|
643
781
|
'GET /sitemap': PublicSitemapResponse;
|
|
644
782
|
'GET /search-suggestions': PublicSearchSuggestionsResponse;
|
|
645
783
|
'GET /tour-categories': PublicTourCategoryListResponse;
|
package/dist/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@surfiran/public-api-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "TypeScript types and client for SURFIRAN CRM Public API V1",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/mehdi360/surfiran-public-api-client.git",
|
|
12
|
+
"directory": "."
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/mehdi360/surfiran-public-api-client/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/mehdi360/surfiran-public-api-client",
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public",
|
|
20
|
+
"registry": "https://registry.npmjs.org"
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": false,
|
|
6
23
|
"main": "dist/index.js",
|
|
7
24
|
"types": "dist/index.d.ts",
|
|
8
25
|
"exports": {
|
|
@@ -16,16 +33,29 @@
|
|
|
16
33
|
}
|
|
17
34
|
},
|
|
18
35
|
"files": [
|
|
19
|
-
"
|
|
20
|
-
"
|
|
36
|
+
"README.md",
|
|
37
|
+
"dist/client.d.ts",
|
|
38
|
+
"dist/client.js",
|
|
39
|
+
"dist/generated/public-api-v1.d.ts",
|
|
40
|
+
"dist/generated/public-api-v1.js",
|
|
41
|
+
"dist/index.d.ts",
|
|
42
|
+
"dist/index.js",
|
|
43
|
+
"dist/types.d.ts",
|
|
44
|
+
"dist/types.js"
|
|
21
45
|
],
|
|
22
46
|
"scripts": {
|
|
23
|
-
"generate": "node ../../scripts/generate-public-api-v1-types.cjs",
|
|
24
47
|
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
25
|
-
"
|
|
48
|
+
"generate": "node scripts/generate-public-api-v1.cjs",
|
|
49
|
+
"prepack": "npm run verify:contract && npm run verify:package && npm run verify:generated && npm run typecheck && npm test && npm run build",
|
|
26
50
|
"typecheck": "tsc --noEmit",
|
|
27
51
|
"test": "vitest run",
|
|
28
|
-
"verify:
|
|
52
|
+
"verify:contract": "node scripts/verify-contract.cjs",
|
|
53
|
+
"verify:generated": "node scripts/verify-generated.cjs",
|
|
54
|
+
"verify:package": "node scripts/verify-package.cjs",
|
|
55
|
+
"verify:pack": "node scripts/verify-pack.cjs",
|
|
56
|
+
"verify:publication-preflight": "node scripts/verify-publication-preflight.cjs",
|
|
57
|
+
"create:provenance": "node scripts/create-provenance.cjs",
|
|
58
|
+
"verify:provenance": "node scripts/verify-provenance.cjs"
|
|
29
59
|
},
|
|
30
60
|
"dependencies": {},
|
|
31
61
|
"devDependencies": {
|