|
| 1 | +{%- if flavor contains "vanilla-js" -%} |
1 | 2 | export function run(input) { |
2 | 3 | const { fetchResult } = input; |
3 | 4 | const status = fetchResult?.status; |
@@ -101,3 +102,118 @@ function formatTime(time) { |
101 | 102 |
|
102 | 103 | return `${hourIn24Format.toString().padStart(2, '0')}:${min}:00`; |
103 | 104 | } |
| 105 | +{%- elsif flavor contains "typescript" -%} |
| 106 | +import { |
| 107 | + BusinessHours, |
| 108 | + FunctionRunResult, |
| 109 | + Operation, |
| 110 | + PickupAddress, |
| 111 | + PickupPointDeliveryOption, |
| 112 | + Provider, |
| 113 | + RunInput |
| 114 | +} from "../generated/api"; |
| 115 | + |
| 116 | +export function run(input: RunInput): FunctionRunResult { |
| 117 | + const { fetchResult } = input; |
| 118 | + const status = fetchResult?.status; |
| 119 | + const body = fetchResult?.body; |
| 120 | + |
| 121 | + let operations: Operation[] = []; |
| 122 | + |
| 123 | + if (status === 200 && body) { |
| 124 | + const { deliveryPoints: externalApiDeliveryPoints } = JSON.parse(body); |
| 125 | + operations = buildPickupPointDeliveryOptionOperations(externalApiDeliveryPoints); |
| 126 | + } |
| 127 | + |
| 128 | + return { operations }; |
| 129 | + |
| 130 | +} |
| 131 | + |
| 132 | +function buildPickupPointDeliveryOptionOperations(externalApiDeliveryPoints: any[]): Operation[] { |
| 133 | + return externalApiDeliveryPoints |
| 134 | + .map(externalApiDeliveryPoint => ({ add: buildPickupPointDeliveryOption(externalApiDeliveryPoint) })); |
| 135 | +} |
| 136 | + |
| 137 | +function buildPickupPointDeliveryOption(externalApiDeliveryPoint: any): PickupPointDeliveryOption { |
| 138 | + return { |
| 139 | + cost: null, |
| 140 | + pickupPoint: { |
| 141 | + externalId: externalApiDeliveryPoint.pointId, |
| 142 | + name: externalApiDeliveryPoint.pointName, |
| 143 | + provider: buildProvider(), |
| 144 | + address: buildAddress(externalApiDeliveryPoint), |
| 145 | + businessHours: buildBusinessHours(externalApiDeliveryPoint), |
| 146 | + }, |
| 147 | + }; |
| 148 | +} |
| 149 | + |
| 150 | +function buildProvider(): Provider { |
| 151 | + return { |
| 152 | + name: "Shopify TypeScript Demo", |
| 153 | + logoUrl: "https://cdn.shopify.com/s/files/1/0628/3830/9033/files/shopify_icon_146101.png?v=1706120545", |
| 154 | + }; |
| 155 | +} |
| 156 | + |
| 157 | +function buildAddress(externalApiDeliveryPoint: any): PickupAddress { |
| 158 | + let location = externalApiDeliveryPoint.location; |
| 159 | + let addressComponents = location.addressComponents; |
| 160 | + let geometry = location.geometry.location; |
| 161 | + let administrativeArea = addressComponents.administrativeArea; |
| 162 | + |
| 163 | + return { |
| 164 | + address1: `${addressComponents.streetNumber} ${addressComponents.route}`, |
| 165 | + address2: null, |
| 166 | + city: addressComponents.locality, |
| 167 | + country: addressComponents.country, |
| 168 | + countryCode: addressComponents.countryCode, |
| 169 | + latitude: geometry.lat, |
| 170 | + longitude: geometry.lng, |
| 171 | + phone: null, |
| 172 | + province: administrativeArea.name, |
| 173 | + provinceCode: administrativeArea.code, |
| 174 | + zip: addressComponents.postalCode, |
| 175 | + }; |
| 176 | +} |
| 177 | + |
| 178 | +// Transforms the opening hours of a delivery point into a vector of `BusinessHours` objects. |
| 179 | +// Each day's opening hours are represented using a `BusinessHours` object as follows: |
| 180 | +// "Monday: 9:00 AM – 5:00 PM" is transformed to {day: "MONDAY", periods: [{opening_time: "09:00:00", closing_time: "17:00:00"}]} |
| 181 | +// "Tuesday: Closed" is transformed to {day: "TUESDAY", periods: []} |
| 182 | +function buildBusinessHours(externalApiDeliveryPoint: any): BusinessHours[] | null { |
| 183 | + if(!externalApiDeliveryPoint.openingHours){ |
| 184 | + return null; |
| 185 | + } |
| 186 | + |
| 187 | + return externalApiDeliveryPoint.openingHours.weekdayText |
| 188 | + .map((dayOpeningHours: string) => { |
| 189 | + let dayOpeningHoursParts = dayOpeningHours.split(": "); |
| 190 | + let dayName = dayOpeningHoursParts[0].toUpperCase(); |
| 191 | + if (dayOpeningHoursParts[1] === "Closed") { |
| 192 | + return { day: dayName, periods: [] }; |
| 193 | + } else { |
| 194 | + let openingClosingTimes = dayOpeningHoursParts[1].split(" – "); |
| 195 | + return { |
| 196 | + day: dayName, |
| 197 | + periods: [{ |
| 198 | + openingTime: formatTime(openingClosingTimes[0]), |
| 199 | + closingTime: formatTime(openingClosingTimes[1]), |
| 200 | + }], |
| 201 | + }; |
| 202 | + } |
| 203 | + }); |
| 204 | +} |
| 205 | + |
| 206 | +// Converts a time string from 12-hour to 24-hour format. |
| 207 | +// Example: "9:00 AM" => "09:00:00", "5:00 PM" => "17:00:00" |
| 208 | +function formatTime(time: string): string { |
| 209 | + let timeParts = time.split(' '); |
| 210 | + let hourMin = timeParts[0].split(':'); |
| 211 | + let hour = parseInt(hourMin[0]); |
| 212 | + let min = hourMin[1]; |
| 213 | + let period = timeParts[1]; |
| 214 | + |
| 215 | + let hourIn24Format = period === 'AM' ? (hour === 12 ? 0 : hour) : (hour === 12 ? hour : hour + 12); |
| 216 | + |
| 217 | + return `${hourIn24Format.toString().padStart(2, '0')}:${min}:00`; |
| 218 | +} |
| 219 | +{%- endif -%} |
0 commit comments