import {z} from 'zod' export type GetApiApiV4RailShipmentsIdStatusesArgs = {id: string, includeStatusHistory?: boolean | undefined}; export type GetApiApiV4RailShipmentsIdStatusesOptions = {baseUrl?: string | undefined, oAuth2?: string | undefined, fetch?: typeof fetch | undefined}; export const railEquipmentIdentifier = z.object({type: z.enum(["CONTAINER_ID", "TRAILER_ID", "RAIL_CAR_ID"]).optional(), value: z.string().optional()}); export const railEquipment = z.object({equipmentIdentifier: railEquipmentIdentifier.optional()}); export const weightUnit = z.enum(["LB", "KG"]); export const weightMeasurement = z.object({unit: weightUnit.optional(), value: z.number().optional()}); export const weightPerDistanceUnit = z.literal("KG_PER_KM"); export const weightPerDistanceMeasurement = z.object({unit: weightPerDistanceUnit.optional(), value: z.number().optional()}); export const distanceUnit = z.enum(["FT", "M", "MI", "KM"]); export const distanceMeasurement = z.object({unit: distanceUnit.optional(), value: z.number().optional()}); export const vehicleType = z.object({enumValue: z.enum(["UNKNOWN", "AIR_FREIGHTER", "AIR_BELLY_FREIGHT", "AIR_UNKNOWN", "INLAND_WATERWAY_MOTOR_VESSEL_LT_650T", "INLAND_WATERWAY_MOTOR_VESSEL_650T_TO_1000T", "INLAND_WATERWAY_MOTOR_VESSEL_1000T_TO_2000T", "INLAND_WATERWAY_MOTOR_VESSEL_2000T_TO_3000T", "INLAND_WATERWAY_COUPLED_CONVOY", "INLAND_WATERWAY_PUSHED_CONVOY_2_TO_3_BARGES", "INLAND_WATERWAY_PUSHED_CONVOY_4_TO_5_BARGES", "INLAND_WATERWAY_PUSHED_CONVOY_6_BARGES", "INLAND_WATERWAY_TANKER_VESSELS", "INLAND_WATERWAY_CONTAINER_VESSELS_110M", "INLAND_WATERWAY_CONTAINER_VESSELS_135M", "INLAND_WATERWAY_CONTAINER_VESSELS_COUPLED_CONVOY", "RAIL_AVERAGE_MIXED", "RAIL_CONTAINER", "RAIL_CARS", "RAIL_CHEMICALS", "RAIL_COAL_STEEL", "RAIL_BUILDING_MATERIALS", "RAIL_MANUFACTURED_PRODUCTS", "RAIL_CEREALS", "RAIL_TRUCK_AND_TRAILER", "RAIL_TRAILER_ONLY", "ROAD_NA_VAN", "ROAD_NA_GENERAL", "ROAD_NA_AUTO_CARRIER", "ROAD_NA_DRAY", "ROAD_NA_EXPEDITED", "ROAD_NA_FLATBED", "ROAD_NA_HEAVY_BULK", "ROAD_NA_LTL_DRY_VAN", "ROAD_NA_MIXED", "ROAD_NA_MOVING", "ROAD_NA_PACKAGE", "ROAD_NA_REFRIGERATED", "ROAD_NA_SPECIALIZED", "ROAD_NA_TANKER", "ROAD_NA_TL_DRY_VAN", "ROAD_GLOBAL_VAN_LT_3500KG", "ROAD_GLOBAL_RIGID_TRUCK_3500KG_TO_7500KG", "ROAD_GLOBAL_RIGID_TRUCK_7500KG_TO_12T_GVW", "ROAD_GLOBAL_RIGID_TRUCK_12T_20T_GVW", "ROAD_GLOBAL_RIGID_TRUCK_20T_TO_26T_GVW", "ROAD_GLOBAL_RIGID_TRUCK_26T_TO_32T_GVW", "ROAD_GLOBAL_ARTIC_TRUCK_UP_TO_34T_GVW", "ROAD_GLOBAL_ARTIC_TRUCK_UP_TO_40T_GVW", "ROAD_GLOBAL_ARTIC_TRUCK_UP_TO_40T_GVW_SI_ENGINE", "ROAD_GLOBAL_ARTIC_TRUCK_UP_TO_40T_GVW_HPDI", "ROAD_GLOBAL_ARTIC_TRUCK_40T_GVW_LIGHTWEIGHT_TRAILER", "ROAD_GLOBAL_ARTIC_TRUCK_UP_TO_44T_GVW", "ROAD_GLOBAL_ARTIC_TRUCK_UP_TO_60T_GVW", "ROAD_GLOBAL_ARTIC_TRUCK_UP_TO_72T_GVW", "OCEAN_BULK_CARRIER_0_TO_9999_DWT", "OCEAN_BULK_CARRIER_10000_TO_34999_DWT", "OCEAN_BULK_CARRIER_35000_TO_59999_DWT", "OCEAN_BULK_CARRIER_60000_TO_99999_DWT", "OCEAN_BULK_CARRIER_100000_TO_199999_DWT", "OCEAN_BULK_CARRIER_200000_AND_UP_DWT", "OCEAN_CHEMICAL_TANKER_0_TO_4999_DWT", "OCEAN_CHEMICAL_TANKER_5000_TO_9999_DWT", "OCEAN_CHEMICAL_TANKER_10000_TO_19999_DWT", "OCEAN_CHEMICAL_TANKER_20000_TO_39999_DWT", "OCEAN_CHEMICAL_TANKER_40000_AND_UP_DWT", "OCEAN_GENERAL_CARGO_0_TO_4999_DWT", "OCEAN_GENERAL_CARGO_5000_TO_9999_DWT", "OCEAN_GENERAL_CARGO_10000_TO_19999_DWT", "OCEAN_GENERAL_CARGO_20000_AND_UP_DWT", "OCEAN_LNG_TANKER_0_TO_49999_CBM", "OCEAN_LNG_TANKER_50000_TO_99999_CBM", "OCEAN_LNG_TANKER_100000_TO_199999_CBM", "OCEAN_LNG_TANKER_200000_AND_UP_CBM", "OCEAN_OIL_TANKER_0_TO_4999_DWT", "OCEAN_OIL_TANKER_5000_TO_9999_DWT", "OCEAN_OIL_TANKER_10000_TO_19999_DWT", "OCEAN_OIL_TANKER_20000_TO_59999_DWT", "OCEAN_OIL_TANKER_60000_TO_79999_DWT", "OCEAN_OIL_TANKER_80000_TO_119999_DWT", "OCEAN_OIL_TANKER_120000_TO_199999_DWT", "OCEAN_OIL_TANKER_200000_AND_UP_DWT", "OCEAN_OTHER_LIQUIDS_TANKER_0_TO_999_DWT", "OCEAN_OTHER_LIQUIDS_TANKER_1000_AND_UP_DWT", "OCEAN_FERRY_ROPAX_0_TO_1999_GT", "OCEAN_FERRY_ROPAX_2000_TO_4999_GT", "OCEAN_FERRY_ROPAX_5000_TO_9999_GT", "OCEAN_FERRY_ROPAX_10000_TO_19999_GT", "OCEAN_FERRY_ROPAX_20000_AND_UP_GT", "OCEAN_REFRIGERATED_BULK_0_TO_1999_DWT", "OCEAN_REFRIGERATED_BULK_2000_TO_5999_DWT", "OCEAN_REFRIGERATED_BULK_6000_TO_9999_DWT", "OCEAN_REFRIGERATED_BULK_10000_AND_UP_DWT", "OCEAN_CONTAINER_AVERAGE"]).optional()}); export const vehicleInfo = z.object({type: vehicleType.optional(), weight: weightMeasurement.optional()}); export const emissionData = z.object({cargoWeight: weightMeasurement.optional(), co2EmissionIntensity: weightPerDistanceMeasurement.optional(), distance: distanceMeasurement.optional(), loadFactor: z.number().optional(), totalCO2Emissions: weightMeasurement.optional(), vehicleInfo: vehicleInfo.optional()}); export const logisticsIdentifierTypeEnum = z.enum(["AIR_WAYBILL", "BILL_OF_LADING", "HOUSE_BILL_OF_LADING", "BOOKING_NUMBER", "CARRIER_IATA", "CARRIER_ICAO", "CARRIER_NAME", "CARRIER_SCAC", "FFW_SCAC", "NVOCC_SCAC", "NVOCC_NAME", "FFW_NAME", "FFW_MASTER_ID", "NVOCC_MASTER_ID", "CONTAINER_ID", "CUSTOMER_REFERENCE", "DELIVERY_NUMBER", "EXTERNAL", "FLIGHT_NUMBER", "ORDER", "PICKUP", "PRO", "PURCHASE_ORDER", "RAIL_CAR_ID", "RAIL_WAYBILL", "TRACKING_NUMBER", "TRAILER_ID", "UNKNOWN", "VESSEL_IMO", "VESSEL_NAME", "WAYBILL", "VESSEL_CALL_SIGN", "VESSEL_MMSI", "CARRIER_US_DOT_NUMBER", "CARRIER_MC_NUMBER", "SUBSCRIPTION_ID", "HOUSE_AIR_WAYBILL", "SALES_ORDER", "WAREHOUSE_MOVEMENT_ORDER", "ADVANCED_SHIPMENT_NOTICE", "DRIVER_MOBILE_PHONE_NUMBER", "VEHICLE_ID", "LICENSE_PLATE", "TRAILER_LICENSE_PLATE", "SENSITECH_DEVICE_ID", "EMERSON_DEVICE_ID", "TIVE_DEVICE_ID", "ZILLION_DEVICE_ID", "VOYAGE_NUMBER", "CARRIER_MASTER_ID", "CARRIER_NMC_ID", "CONTAINER_TYPE", "TRAIN_NUMBER", "WAGON_ID", "TRAIN_ID", "CAPACITY_PROVIDER_ACCOUNT_GROUP", "CAPACITY_PROVIDER_ACCOUNT_CODE", "SERIAL_NUMBER", "VEHICLE_IDENTIFICATION_NUMBER", "REFERENCE_NUMBER", "CONTAINER_PIN", "VESSEL_P44_ID", "EXPORT_CUSTOMS_BROKER", "IMPORT_CUSTOMS_BROKER", "POL_QUALITY_CONTROL_PROVIDER", "POD_QUALITY_CONTROL_PROVIDER", "AIRCRAFT_ICAO", "AIRLINE_NAME", "SEAL_NUMBER", "DRAYAGE_CARRIER_SCAC", "EXPORT_DRAYAGE_CARRIER_SCAC", "IMPORT_DRAYAGE_CARRIER_SCAC", "INBOUND_VOYAGE_NUMBER"]); export const logisticsIdentifier = z.object({type: logisticsIdentifierTypeEnum.optional(), value: z.string().min(1).optional()}); export const trackedShipmentRouteSegment = z.object({emissions: emissionData.optional(), fromStopId: z.string().optional(), id: z.string().optional(), identifiers: z.array(logisticsIdentifier).optional(), toStopId: z.string().optional(), transportationMode: z.enum(["AIR", "OCEAN", "RAIL", "UNKNOWN", "TRUCKLOAD", "PARCEL", "LTL", "BARGE"]).optional()}); export const railAddress = z.object({pointName: z.string().optional(), state: z.string().optional()}); export const geoCoordinates = z.object({latitude: z.number().optional(), longitude: z.number().optional()}); export const railStatusReason = z.object({code: z.enum(["UNKNOWN", "SCHEDULED", "ACQUIRING_LOCATION", "IN_MOTION", "IDLE", "ARRIVED", "IN_GATE", "RAMPED", "DERAMPED", "NOTIFIED", "OUT_GATE", "DEPARTED_STOP", "TIMED_OUT", "CANCELED", "DEPARTED_FINAL_STOP", "WAYBILL_CHANGED", "UNAUTHORIZED"]).optional(), description: z.string().optional()}); export const railEquipmentStatusUpdate = z.object({address: railAddress.optional(), clmEventCode: z.string().optional(), clmSightingCode: z.string().optional(), geoCoordinates: geoCoordinates.optional(), statusCode: z.enum(["DISPATCHED", "IN_TRANSIT", "AT_STOP", "COMPLETED", "UNAUTHORIZED"]).optional(), statusReason: railStatusReason.optional(), stopNumber: z.number().int().optional(), timestamp: z.string().optional(), trainIdentifier: z.string().optional()}); export const offsetDateTimeWindow = z.object({endDateTime: z.string().optional(), startDateTime: z.string().optional()}); export const railArrivalEstimate = z.object({estimatedArrivalCode: z.enum(["UNKNOWN", "EARLY", "ON_TIME", "LATE"]).optional(), estimatedArrivalWindow: offsetDateTimeWindow.optional(), lastCalculatedDateTime: z.string().optional()}); export const railEquipmentStopStatus = z.object({arrivalCode: z.enum(["UNKNOWN", "EARLY", "ON_TIME", "LATE"]).optional(), arrivalDateTime: z.string().optional(), arrivalEstimate: railArrivalEstimate.optional(), departureDateTime: z.string().optional(), stopNumber: z.number().int().optional(), stopStatusCode: z.enum(["UNKNOWN", "EN_ROUTE", "ARRIVED", "DEPARTED"]).optional()}); export const railEquipmentStatus = z.object({equipment: railEquipment.optional(), equipmentRouteSegments: z.array(trackedShipmentRouteSegment).optional(), latestStatusUpdate: railEquipmentStatusUpdate.optional(), latestStopStatuses: z.array(railEquipmentStopStatus).optional(), statusUpdates: z.array(railEquipmentStatusUpdate).optional()}); export const message = z.object({diagnostic: z.string().optional(), message: z.string().optional(), severity: z.enum(["ERROR", "WARNING", "INFO"]).optional(), source: z.enum(["SYSTEM", "CAPACITY_PROVIDER"]).optional()}); export const railShipmentIdentifier = z.object({type: z.enum(["BILL_OF_LADING", "WAYBILL"]).optional(), value: z.string().optional()}); export const zonedDateTimeWindow = z.object({endDateTime: z.string().optional(), localTimeZoneIdentifier: z.string().optional(), startDateTime: z.string().optional()}); export const railLocation = z.object({address: railAddress.optional(), id: z.string().optional()}); export const railShipmentStop = z.object({appointmentWindow: zonedDateTimeWindow.optional(), geoCoordinates: geoCoordinates.optional(), id: z.string().optional(), location: railLocation.optional(), stopName: z.string().optional(), stopNumber: z.number().int().optional(), type: z.enum(["UNKNOWN", "ORIGIN", "DESTINATION", "TRANSFER", "OTHER", "PORT_OF_LOADING", "TRANSSHIPMENT_PORT", "PORT_OF_DISCHARGE", "PICKUP", "DELIVERY", "RETURN", "WAREHOUSE", "HUB", "AIRPORT"]).optional()}); export const railShipment = z.object({equipmentIdentifiers: z.array(railEquipmentIdentifier).optional(), id: z.number().int().optional(), masterShipmentId: z.string().optional(), railLegId: z.string().optional(), shipmentIdentifiers: z.array(railShipmentIdentifier).optional(), shipmentStops: z.array(railShipmentStop).optional(), trackingStartDateTime: z.string().optional()}); export const railShipmentStatus = z.object({equipmentStatuses: z.array(railEquipmentStatus).optional(), infoMessages: z.array(message).optional(), shipment: railShipment.optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Get a shipment status by system id. * * GET /api/v4/rail/shipments/{id}/statuses */ export const getApiApiV4RailShipmentsIdStatuses = async (args: GetApiApiV4RailShipmentsIdStatusesArgs, options?: GetApiApiV4RailShipmentsIdStatusesOptions) => { const {baseUrl = "https://na12.api.project44.com", fetch: fetchFn = fetch, oAuth2} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.includeStatusHistory != null) query.append("includeStatusHistory", String(args.includeStatusHistory)) if (oAuth2 !== undefined) headers.set('authorization', `Bearer ${oAuth2}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/v4/rail/shipments/${encodeURIComponent(String(args.id))}/statuses${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(railShipmentStatus, await res.json()) };