// Code generated by protoc-gen-ts-server. DO NOT EDIT.
// source: worldmonitor/supply_chain/v1/service.proto

export interface GetShippingRatesRequest {
}

export interface GetShippingRatesResponse {
  indices: ShippingIndex[];
  fetchedAt: string;
  upstreamUnavailable: boolean;
}

export interface ShippingIndex {
  indexId: string;
  name: string;
  currentValue: number;
  previousValue: number;
  changePct: number;
  unit: string;
  history: ShippingRatePoint[];
  spikeAlert: boolean;
}

export interface ShippingRatePoint {
  date: string;
  value: number;
}

export interface GetChokepointStatusRequest {
}

export interface GetChokepointStatusResponse {
  chokepoints: ChokepointInfo[];
  fetchedAt: string;
  upstreamUnavailable: boolean;
}

export interface ChokepointInfo {
  id: string;
  name: string;
  lat: number;
  lon: number;
  disruptionScore: number;
  status: string;
  activeWarnings: number;
  congestionLevel: string;
  affectedRoutes: string[];
  description: string;
  aisDisruptions: number;
  directions: string[];
  directionalDwt: DirectionalDwt[];
  transitSummary?: TransitSummary;
  flowEstimate?: FlowEstimate;
  warRiskTier: WarRiskTier;
}

export interface DirectionalDwt {
  direction: string;
  dwtThousandTonnes: number;
  wowChangePct: number;
}

export interface TransitSummary {
  todayTotal: number;
  todayTanker: number;
  todayCargo: number;
  todayOther: number;
  wowChangePct: number;
  history: TransitDayCount[];
  riskLevel: string;
  incidentCount7d: number;
  disruptionPct: number;
  riskSummary: string;
  riskReportAction: string;
  dataAvailable: boolean;
}

export interface TransitDayCount {
  date: string;
  tanker: number;
  cargo: number;
  other: number;
  total: number;
  container: number;
  dryBulk: number;
  generalCargo: number;
  roro: number;
  capContainer: number;
  capDryBulk: number;
  capGeneralCargo: number;
  capRoro: number;
  capTanker: number;
}

export interface FlowEstimate {
  currentMbd: number;
  baselineMbd: number;
  flowRatio: number;
  disrupted: boolean;
  source: string;
  hazardAlertLevel: string;
  hazardAlertName: string;
}

export interface GetChokepointHistoryRequest {
  chokepointId: string;
}

export interface GetChokepointHistoryResponse {
  chokepointId: string;
  history: TransitDayCount[];
  fetchedAt: string;
}

export interface GetCriticalMineralsRequest {
}

export interface GetCriticalMineralsResponse {
  minerals: CriticalMineral[];
  fetchedAt: string;
  upstreamUnavailable: boolean;
}

export interface CriticalMineral {
  mineral: string;
  topProducers: MineralProducer[];
  hhi: number;
  riskRating: string;
  globalProduction: number;
  unit: string;
}

export interface MineralProducer {
  country: string;
  countryCode: string;
  productionTonnes: number;
  sharePct: number;
}

export interface GetShippingStressRequest {
}

export interface GetShippingStressResponse {
  carriers: ShippingStressCarrier[];
  stressScore: number;
  stressLevel: string;
  fetchedAt: number;
  upstreamUnavailable: boolean;
}

export interface ShippingStressCarrier {
  symbol: string;
  name: string;
  price: number;
  changePct: number;
  carrierType: string;
  sparkline: number[];
}

export interface GetCountryChokepointIndexRequest {
  iso2: string;
  hs2: string;
}

export interface GetCountryChokepointIndexResponse {
  iso2: string;
  hs2: string;
  exposures: ChokepointExposureEntry[];
  primaryChokepointId: string;
  vulnerabilityIndex: number;
  fetchedAt: string;
}

export interface ChokepointExposureEntry {
  chokepointId: string;
  chokepointName: string;
  exposureScore: number;
  coastSide: string;
  shockSupported: boolean;
}

export interface GetBypassOptionsRequest {
  chokepointId: string;
  cargoType: string;
  closurePct: number;
}

export interface GetBypassOptionsResponse {
  chokepointId: string;
  cargoType: string;
  closurePct: number;
  options: BypassOption[];
  fetchedAt: string;
  primaryChokepointWarRiskTier: WarRiskTier;
}

export interface BypassOption {
  id: string;
  name: string;
  type: string;
  addedTransitDays: number;
  addedCostMultiplier: number;
  capacityConstraintTonnage: string;
  suitableCargoTypes: string[];
  activationThreshold: string;
  waypointChokepointIds: string[];
  liveScore: number;
  bypassWarRiskTier: WarRiskTier;
  notes: string;
}

export interface GetCountryCostShockRequest {
  iso2: string;
  chokepointId: string;
  hs2: string;
}

export interface GetCountryCostShockResponse {
  iso2: string;
  chokepointId: string;
  hs2: string;
  supplyDeficitPct: number;
  coverageDays: number;
  warRiskPremiumBps: number;
  warRiskTier: WarRiskTier;
  hasEnergyModel: boolean;
  unavailableReason: string;
  fetchedAt: string;
}

export interface GetCountryProductsRequest {
  iso2: string;
}

export interface GetCountryProductsResponse {
  iso2: string;
  products: CountryProduct[];
  fetchedAt: string;
}

export interface CountryProduct {
  hs4: string;
  description: string;
  totalValue: number;
  topExporters: ProductExporter[];
  year: number;
}

export interface ProductExporter {
  partnerCode: number;
  partnerIso2: string;
  value: number;
  share: number;
}

export interface GetMultiSectorCostShockRequest {
  iso2: string;
  chokepointId: string;
  closureDays: number;
}

export interface GetMultiSectorCostShockResponse {
  iso2: string;
  chokepointId: string;
  closureDays: number;
  warRiskTier: WarRiskTier;
  sectors: MultiSectorCostShock[];
  totalAddedCost: number;
  fetchedAt: string;
  unavailableReason: string;
}

export interface MultiSectorCostShock {
  hs2: string;
  hs2Label: string;
  importValueAnnual: number;
  freightAddedPctPerTon: number;
  warRiskPremiumBps: number;
  addedTransitDays: number;
  totalCostShockPerDay: number;
  totalCostShock30Days: number;
  totalCostShock90Days: number;
  totalCostShock: number;
  closureDays: number;
}

export interface GetSectorDependencyRequest {
  iso2: string;
  hs2: string;
}

export interface GetSectorDependencyResponse {
  iso2: string;
  hs2: string;
  hs2Label: string;
  flags: DependencyFlag[];
  primaryExporterIso2: string;
  primaryExporterShare: number;
  primaryChokepointId: string;
  primaryChokepointExposure: number;
  hasViableBypass: boolean;
  fetchedAt: string;
}

export interface GetRouteExplorerLaneRequest {
  fromIso2: string;
  toIso2: string;
  hs2: string;
  cargoType: string;
}

export interface GetRouteExplorerLaneResponse {
  fromIso2: string;
  toIso2: string;
  hs2: string;
  cargoType: string;
  primaryRouteId: string;
  primaryRouteGeometry: GeoPoint[];
  chokepointExposures: ChokepointExposureSummary[];
  bypassOptions: BypassCorridorOption[];
  warRiskTier: string;
  disruptionScore: number;
  estTransitDaysRange?: NumberRange;
  estFreightUsdPerTeuRange?: NumberRange;
  noModeledLane: boolean;
  fetchedAt: string;
}

export interface GeoPoint {
  lon: number;
  lat: number;
}

export interface ChokepointExposureSummary {
  chokepointId: string;
  chokepointName: string;
  exposurePct: number;
}

export interface BypassCorridorOption {
  id: string;
  name: string;
  type: string;
  addedTransitDays: number;
  addedCostMultiplier: number;
  warRiskTier: string;
  status: CorridorStatus;
  fromPort?: GeoPoint;
  toPort?: GeoPoint;
}

export interface NumberRange {
  min: number;
  max: number;
}

export interface GetRouteImpactRequest {
  fromIso2: string;
  toIso2: string;
  hs2: string;
}

export interface GetRouteImpactResponse {
  laneValueUsd: number;
  primaryExporterIso2: string;
  primaryExporterShare: number;
  topStrategicProducts: StrategicProduct[];
  resilienceScore: number;
  dependencyFlags: DependencyFlag[];
  hs2InSeededUniverse: boolean;
  comtradeSource: string;
  fetchedAt: string;
}

export interface StrategicProduct {
  hs4: string;
  label: string;
  totalValueUsd: number;
  topExporterIso2: string;
  topExporterShare: number;
  primaryChokepointId: string;
}

export interface ListPipelinesRequest {
  commodityType: string;
}

export interface ListPipelinesResponse {
  pipelines: PipelineEntry[];
  fetchedAt: string;
  classifierVersion: string;
  upstreamUnavailable: boolean;
}

export interface PipelineEntry {
  id: string;
  name: string;
  operator: string;
  commodityType: string;
  fromCountry: string;
  toCountry: string;
  transitCountries: string[];
  capacityBcmYr: number;
  capacityMbd: number;
  lengthKm: number;
  inService: number;
  startPoint?: LatLon;
  endPoint?: LatLon;
  waypoints: LatLon[];
  evidence?: PipelineEvidence;
  publicBadge: string;
}

export interface LatLon {
  lat: number;
  lon: number;
}

export interface PipelineEvidence {
  physicalState: string;
  physicalStateSource: string;
  operatorStatement?: OperatorStatement;
  commercialState: string;
  sanctionRefs: SanctionRef[];
  lastEvidenceUpdate: string;
  classifierVersion: string;
  classifierConfidence: number;
}

export interface OperatorStatement {
  text: string;
  url: string;
  date: string;
}

export interface SanctionRef {
  authority: string;
  listId: string;
  date: string;
  url: string;
}

export interface GetPipelineDetailRequest {
  pipelineId: string;
}

export interface GetPipelineDetailResponse {
  pipeline?: PipelineEntry;
  revisions: PipelineRevisionEntry[];
  fetchedAt: string;
  unavailable: boolean;
}

export interface PipelineRevisionEntry {
  date: string;
  fieldChanged: string;
  previousValue: string;
  newValue: string;
  trigger: string;
  sourcesUsed: string[];
  classifierVersion: string;
}

export interface ListStorageFacilitiesRequest {
  facilityType: string;
}

export interface ListStorageFacilitiesResponse {
  facilities: StorageFacilityEntry[];
  fetchedAt: string;
  classifierVersion: string;
  upstreamUnavailable: boolean;
}

export interface StorageFacilityEntry {
  id: string;
  name: string;
  operator: string;
  facilityType: string;
  country: string;
  location?: StorageLatLon;
  capacityTwh: number;
  capacityMb: number;
  capacityMtpa: number;
  workingCapacityUnit: string;
  inService: number;
  evidence?: StorageEvidence;
  publicBadge: string;
}

export interface StorageLatLon {
  lat: number;
  lon: number;
}

export interface StorageEvidence {
  physicalState: string;
  physicalStateSource: string;
  operatorStatement?: StorageOperatorStatement;
  commercialState: string;
  sanctionRefs: StorageSanctionRef[];
  fillDisclosed: boolean;
  fillSource: string;
  lastEvidenceUpdate: string;
  classifierVersion: string;
  classifierConfidence: number;
}

export interface StorageOperatorStatement {
  text: string;
  url: string;
  date: string;
}

export interface StorageSanctionRef {
  authority: string;
  listId: string;
  date: string;
  url: string;
}

export interface GetStorageFacilityDetailRequest {
  facilityId: string;
}

export interface GetStorageFacilityDetailResponse {
  facility?: StorageFacilityEntry;
  revisions: StorageFacilityRevisionEntry[];
  fetchedAt: string;
  unavailable: boolean;
}

export interface StorageFacilityRevisionEntry {
  date: string;
  fieldChanged: string;
  previousValue: string;
  newValue: string;
  trigger: string;
  sourcesUsed: string[];
  classifierVersion: string;
}

export interface ListFuelShortagesRequest {
  country: string;
  product: string;
  severity: string;
}

export interface ListFuelShortagesResponse {
  shortages: FuelShortageEntry[];
  fetchedAt: string;
  classifierVersion: string;
  upstreamUnavailable: boolean;
}

export interface FuelShortageEntry {
  id: string;
  country: string;
  product: string;
  severity: string;
  firstSeen: string;
  lastConfirmed: string;
  resolvedAt: string;
  impactTypes: string[];
  causeChain: string[];
  shortDescription: string;
  evidence?: FuelShortageEvidence;
}

export interface FuelShortageEvidence {
  evidenceSources: FuelShortageEvidenceSource[];
  firstRegulatorConfirmation: string;
  classifierVersion: string;
  classifierConfidence: number;
  lastEvidenceUpdate: string;
}

export interface FuelShortageEvidenceSource {
  authority: string;
  title: string;
  url: string;
  date: string;
  sourceType: string;
}

export interface GetFuelShortageDetailRequest {
  shortageId: string;
}

export interface GetFuelShortageDetailResponse {
  shortage?: FuelShortageEntry;
  fetchedAt: string;
  unavailable: boolean;
}

export interface ListEnergyDisruptionsRequest {
  assetId: string;
  assetType: string;
  ongoingOnly: boolean;
}

export interface ListEnergyDisruptionsResponse {
  events: EnergyDisruptionEntry[];
  fetchedAt: string;
  classifierVersion: string;
  upstreamUnavailable: boolean;
}

export interface EnergyDisruptionEntry {
  id: string;
  assetId: string;
  assetType: string;
  eventType: string;
  startAt: string;
  endAt: string;
  capacityOfflineBcmYr: number;
  capacityOfflineMbd: number;
  causeChain: string[];
  shortDescription: string;
  sources: EnergyDisruptionSource[];
  classifierVersion: string;
  classifierConfidence: number;
  lastEvidenceUpdate: string;
}

export interface EnergyDisruptionSource {
  authority: string;
  title: string;
  url: string;
  date: string;
  sourceType: string;
}

export type CorridorStatus = "CORRIDOR_STATUS_UNSPECIFIED" | "CORRIDOR_STATUS_ACTIVE" | "CORRIDOR_STATUS_PROPOSED" | "CORRIDOR_STATUS_UNAVAILABLE";

export type DependencyFlag = "DEPENDENCY_FLAG_UNSPECIFIED" | "DEPENDENCY_FLAG_SINGLE_SOURCE_CRITICAL" | "DEPENDENCY_FLAG_SINGLE_CORRIDOR_CRITICAL" | "DEPENDENCY_FLAG_COMPOUND_RISK" | "DEPENDENCY_FLAG_DIVERSIFIABLE";

export type WarRiskTier = "WAR_RISK_TIER_UNSPECIFIED" | "WAR_RISK_TIER_NORMAL" | "WAR_RISK_TIER_ELEVATED" | "WAR_RISK_TIER_HIGH" | "WAR_RISK_TIER_CRITICAL" | "WAR_RISK_TIER_WAR_ZONE";

export interface FieldViolation {
  field: string;
  description: string;
}

export class ValidationError extends Error {
  violations: FieldViolation[];

  constructor(violations: FieldViolation[]) {
    super("Validation failed");
    this.name = "ValidationError";
    this.violations = violations;
  }
}

export class ApiError extends Error {
  statusCode: number;
  body: string;

  constructor(statusCode: number, message: string, body: string) {
    super(message);
    this.name = "ApiError";
    this.statusCode = statusCode;
    this.body = body;
  }
}

export interface ServerContext {
  request: Request;
  pathParams: Record<string, string>;
  headers: Record<string, string>;
}

export interface ServerOptions {
  onError?: (error: unknown, req: Request) => Response | Promise<Response>;
  validateRequest?: (methodName: string, body: unknown) => FieldViolation[] | undefined;
}

export interface RouteDescriptor {
  method: string;
  path: string;
  handler: (req: Request) => Promise<Response>;
}

export interface SupplyChainServiceHandler {
  getShippingRates(ctx: ServerContext, req: GetShippingRatesRequest): Promise<GetShippingRatesResponse>;
  getChokepointStatus(ctx: ServerContext, req: GetChokepointStatusRequest): Promise<GetChokepointStatusResponse>;
  getChokepointHistory(ctx: ServerContext, req: GetChokepointHistoryRequest): Promise<GetChokepointHistoryResponse>;
  getCriticalMinerals(ctx: ServerContext, req: GetCriticalMineralsRequest): Promise<GetCriticalMineralsResponse>;
  getShippingStress(ctx: ServerContext, req: GetShippingStressRequest): Promise<GetShippingStressResponse>;
  getCountryChokepointIndex(ctx: ServerContext, req: GetCountryChokepointIndexRequest): Promise<GetCountryChokepointIndexResponse>;
  getBypassOptions(ctx: ServerContext, req: GetBypassOptionsRequest): Promise<GetBypassOptionsResponse>;
  getCountryCostShock(ctx: ServerContext, req: GetCountryCostShockRequest): Promise<GetCountryCostShockResponse>;
  getCountryProducts(ctx: ServerContext, req: GetCountryProductsRequest): Promise<GetCountryProductsResponse>;
  getMultiSectorCostShock(ctx: ServerContext, req: GetMultiSectorCostShockRequest): Promise<GetMultiSectorCostShockResponse>;
  getSectorDependency(ctx: ServerContext, req: GetSectorDependencyRequest): Promise<GetSectorDependencyResponse>;
  getRouteExplorerLane(ctx: ServerContext, req: GetRouteExplorerLaneRequest): Promise<GetRouteExplorerLaneResponse>;
  getRouteImpact(ctx: ServerContext, req: GetRouteImpactRequest): Promise<GetRouteImpactResponse>;
  listPipelines(ctx: ServerContext, req: ListPipelinesRequest): Promise<ListPipelinesResponse>;
  getPipelineDetail(ctx: ServerContext, req: GetPipelineDetailRequest): Promise<GetPipelineDetailResponse>;
  listStorageFacilities(ctx: ServerContext, req: ListStorageFacilitiesRequest): Promise<ListStorageFacilitiesResponse>;
  getStorageFacilityDetail(ctx: ServerContext, req: GetStorageFacilityDetailRequest): Promise<GetStorageFacilityDetailResponse>;
  listFuelShortages(ctx: ServerContext, req: ListFuelShortagesRequest): Promise<ListFuelShortagesResponse>;
  getFuelShortageDetail(ctx: ServerContext, req: GetFuelShortageDetailRequest): Promise<GetFuelShortageDetailResponse>;
  listEnergyDisruptions(ctx: ServerContext, req: ListEnergyDisruptionsRequest): Promise<ListEnergyDisruptionsResponse>;
}

export function createSupplyChainServiceRoutes(
  handler: SupplyChainServiceHandler,
  options?: ServerOptions,
): RouteDescriptor[] {
  return [
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-shipping-rates",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetShippingRatesRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getShippingRates(ctx, body);
          return new Response(JSON.stringify(result as GetShippingRatesResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-chokepoint-status",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetChokepointStatusRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getChokepointStatus(ctx, body);
          return new Response(JSON.stringify(result as GetChokepointStatusResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-chokepoint-history",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetChokepointHistoryRequest = {
            chokepointId: params.get("chokepointId") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getChokepointHistory", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getChokepointHistory(ctx, body);
          return new Response(JSON.stringify(result as GetChokepointHistoryResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-critical-minerals",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetCriticalMineralsRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getCriticalMinerals(ctx, body);
          return new Response(JSON.stringify(result as GetCriticalMineralsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-shipping-stress",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetShippingStressRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getShippingStress(ctx, body);
          return new Response(JSON.stringify(result as GetShippingStressResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-country-chokepoint-index",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetCountryChokepointIndexRequest = {
            iso2: params.get("iso2") ?? "",
            hs2: params.get("hs2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getCountryChokepointIndex", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getCountryChokepointIndex(ctx, body);
          return new Response(JSON.stringify(result as GetCountryChokepointIndexResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-bypass-options",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetBypassOptionsRequest = {
            chokepointId: params.get("chokepointId") ?? "",
            cargoType: params.get("cargoType") ?? "",
            closurePct: Number(params.get("closurePct") ?? "0"),
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getBypassOptions", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getBypassOptions(ctx, body);
          return new Response(JSON.stringify(result as GetBypassOptionsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-country-cost-shock",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetCountryCostShockRequest = {
            iso2: params.get("iso2") ?? "",
            chokepointId: params.get("chokepointId") ?? "",
            hs2: params.get("hs2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getCountryCostShock", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getCountryCostShock(ctx, body);
          return new Response(JSON.stringify(result as GetCountryCostShockResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-country-products",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetCountryProductsRequest = {
            iso2: params.get("iso2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getCountryProducts", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getCountryProducts(ctx, body);
          return new Response(JSON.stringify(result as GetCountryProductsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-multi-sector-cost-shock",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetMultiSectorCostShockRequest = {
            iso2: params.get("iso2") ?? "",
            chokepointId: params.get("chokepointId") ?? "",
            closureDays: Number(params.get("closureDays") ?? "0"),
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getMultiSectorCostShock", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getMultiSectorCostShock(ctx, body);
          return new Response(JSON.stringify(result as GetMultiSectorCostShockResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-sector-dependency",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetSectorDependencyRequest = {
            iso2: params.get("iso2") ?? "",
            hs2: params.get("hs2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getSectorDependency", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getSectorDependency(ctx, body);
          return new Response(JSON.stringify(result as GetSectorDependencyResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-route-explorer-lane",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetRouteExplorerLaneRequest = {
            fromIso2: params.get("fromIso2") ?? "",
            toIso2: params.get("toIso2") ?? "",
            hs2: params.get("hs2") ?? "",
            cargoType: params.get("cargoType") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getRouteExplorerLane", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getRouteExplorerLane(ctx, body);
          return new Response(JSON.stringify(result as GetRouteExplorerLaneResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-route-impact",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetRouteImpactRequest = {
            fromIso2: params.get("fromIso2") ?? "",
            toIso2: params.get("toIso2") ?? "",
            hs2: params.get("hs2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getRouteImpact", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getRouteImpact(ctx, body);
          return new Response(JSON.stringify(result as GetRouteImpactResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/list-pipelines",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: ListPipelinesRequest = {
            commodityType: params.get("commodityType") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("listPipelines", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.listPipelines(ctx, body);
          return new Response(JSON.stringify(result as ListPipelinesResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-pipeline-detail",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetPipelineDetailRequest = {
            pipelineId: params.get("pipelineId") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getPipelineDetail", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getPipelineDetail(ctx, body);
          return new Response(JSON.stringify(result as GetPipelineDetailResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/list-storage-facilities",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: ListStorageFacilitiesRequest = {
            facilityType: params.get("facilityType") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("listStorageFacilities", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.listStorageFacilities(ctx, body);
          return new Response(JSON.stringify(result as ListStorageFacilitiesResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-storage-facility-detail",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetStorageFacilityDetailRequest = {
            facilityId: params.get("facilityId") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getStorageFacilityDetail", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getStorageFacilityDetail(ctx, body);
          return new Response(JSON.stringify(result as GetStorageFacilityDetailResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/list-fuel-shortages",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: ListFuelShortagesRequest = {
            country: params.get("country") ?? "",
            product: params.get("product") ?? "",
            severity: params.get("severity") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("listFuelShortages", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.listFuelShortages(ctx, body);
          return new Response(JSON.stringify(result as ListFuelShortagesResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-fuel-shortage-detail",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetFuelShortageDetailRequest = {
            shortageId: params.get("shortageId") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getFuelShortageDetail", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getFuelShortageDetail(ctx, body);
          return new Response(JSON.stringify(result as GetFuelShortageDetailResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/list-energy-disruptions",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: ListEnergyDisruptionsRequest = {
            assetId: params.get("assetId") ?? "",
            assetType: params.get("assetType") ?? "",
            ongoingOnly: params.get("ongoingOnly") === "true",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("listEnergyDisruptions", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.listEnergyDisruptions(ctx, body);
          return new Response(JSON.stringify(result as ListEnergyDisruptionsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
  ];
}

