- Updated typography for headings and paragraphs in AboutUsView. - Added animation effects for header and sections to improve user experience. - Refactored section headers to use new display styles. feat: Implement bilingual address handling in AddressConfirmation - Integrated JapanAddressForm for ZIP code lookup and bilingual address input. - Updated state management to handle bilingual addresses and validation. - Enhanced save functionality to support dual-write to WHMCS and Salesforce. fix: Adjust Japan Post address mapping to handle nullish values - Updated address mapping to use nullish coalescing for optional fields. - Ensured compatibility with API responses that may return null for certain fields. feat: Add ServiceCard component for displaying services - Created a flexible ServiceCard component with multiple variants (default, featured, minimal, bento). - Implemented accent color options and responsive design for better UI. - Added detailed props documentation and usage examples. chore: Clean up development scripts - Removed unnecessary build steps for validation package in manage.sh.
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
/**
|
|
* Japan Post API - Mapper
|
|
*
|
|
* Transforms Japan Post API responses to domain types.
|
|
* Single transformation point: Raw API -> Domain type
|
|
*/
|
|
|
|
import type { JapanPostAddressRecord, JapanPostSearchResponse } from "./raw.types.js";
|
|
import { japanPostSearchResponseSchema } from "./raw.types.js";
|
|
import type { JapanPostAddress, AddressLookupResult } from "../../schema.js";
|
|
|
|
/**
|
|
* Transform a single Japan Post address record to domain type
|
|
*/
|
|
export function transformJapanPostAddress(raw: JapanPostAddressRecord): JapanPostAddress {
|
|
// Get ZIP code from either field name
|
|
const zipCode = raw.zipcode || raw.zip_code || "";
|
|
|
|
return {
|
|
zipCode,
|
|
// Japanese
|
|
prefecture: raw.pref_name || "",
|
|
prefectureKana: raw.pref_kana ?? undefined,
|
|
city: raw.city_name || "",
|
|
cityKana: raw.city_kana ?? undefined,
|
|
town: raw.town_name || "",
|
|
townKana: raw.town_kana ?? undefined,
|
|
// Romanized
|
|
prefectureRoma: raw.pref_roma || "",
|
|
cityRoma: raw.city_roma || "",
|
|
townRoma: raw.town_roma || "",
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Transform Japan Post search response to domain AddressLookupResult
|
|
*/
|
|
export function transformJapanPostSearchResponse(raw: unknown): AddressLookupResult {
|
|
const parsed = japanPostSearchResponseSchema.parse(raw);
|
|
|
|
// Get ZIP code from first address or empty string
|
|
const firstAddress = parsed.addresses[0];
|
|
const zipCode = firstAddress?.zipcode || firstAddress?.zip_code || "";
|
|
|
|
return {
|
|
zipCode,
|
|
addresses: parsed.addresses.map(transformJapanPostAddress),
|
|
count: parsed.count,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Parse and validate raw Japan Post API response
|
|
*/
|
|
export function parseJapanPostSearchResponse(raw: unknown): JapanPostSearchResponse {
|
|
return japanPostSearchResponseSchema.parse(raw);
|
|
}
|