import {z} from 'zod' export type GetApiIntervalResultsArgs = {per_page?: number | undefined, sort?: ('asc' | 'desc') | undefined, cursor?: string | undefined, pipeline_id?: string | undefined, format?: ('legacy' | 'standard') | undefined}; export type GetApiIntervalResultsOptions = {baseUrl?: string | undefined, ApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const previewBboxGeojsonGeometry = z.object({type: z.literal("Polygon"), coordinates: z.array(z.array(z.array(z.unknown())))}); export const intervalResultResource = z.object({id: z.string().min(1), output_id: z.string().min(1), pipeline_id: z.string().min(1), status: z.enum(["pending", "requested", "scheduled", "committed", "cancelled", "future", "failed", "waiting", "processing", "complete", "searching", "retrieving"]), message: z.string().optional(), interval: z.object({start_date: z.string().min(1), end_date: z.string().min(1)}), total_interval_cost: z.number().gte(0).optional(), probability_of_collection: z.object({probability_percent: z.number().gte(0).lte(100), probability_reason: z.string().min(1).optional()}).optional(), overall_metadata: z.object({scene_height: z.number().gte(0), scene_width: z.number().gte(0), filled_area_km2: z.number().gte(0), filled_area_percentage_of_aoi: z.number().gte(0).lte(100), cloud_cover_percentage: z.number().gte(0).lte(100), cloud_cover_percentage_of_aoi: z.number().gte(0).lte(100), visible_area_km2: z.number().gte(0), visible_area_percentage: z.number().gte(0).lte(100), visible_area_percentage_of_aoi: z.number().gte(0).lte(100)}).optional(), results: z.array(z.object({preview_url: z.string().optional(), visual_url: z.string().optional(), analytics_url: z.string().optional(), metadata_url: z.string().optional(), capture_time: z.string().optional(), vector_files: z.array(z.object({name: z.string().min(1), description: z.string().min(1), uri: z.string().min(1)})).optional(), raster_files: z.array(z.object({name: z.string().min(1), description: z.string().min(1), uri: z.string().min(1)})).optional(), metadata: z.object({processing_applied: z.object({atmospheric_correction_toa: z.boolean().optional(), pan_sharpening: z.boolean().optional(), cloud_masking: z.boolean().optional(), haze_masking: z.boolean().optional()}).optional(), bands: z.array(z.object({name: z.string().optional(), no_data_value: z.number().optional(), data_type: z.string().optional(), unit: z.string().optional(), spectral_wavelength: z.number().optional(), raster_width: z.number().optional(), raster_height: z.number().optional()})).optional(), resolution_x: z.number().optional(), resolution_y: z.number().optional(), map_crs: z.string().optional(), sensor_mode: z.string().optional(), source: z.string().optional(), valid_pixel_percentage: z.number().gte(0).lte(100).optional(), cloud_cover_percentage: z.number().gte(0).lte(100).optional(), name: z.string().optional(), size_in_mb: z.number().gte(0).optional(), corner_coordinates: z.array(z.array(z.number())).optional()}).optional(), created_at: z.string().optional(), updated_at: z.string().optional(), product_id: z.string().optional()})).optional(), alternate_search_results: z.array(z.object({index: z.number().int().gte(0).optional(), search_result_id: z.string().min(36).max(36).optional(), preview_url: z.string().optional(), preview_bbox: previewBboxGeojsonGeometry.optional(), capture_date: z.string().min(10).max(10).optional(), resolution: z.number().gte(0).optional(), price_per_km2: z.number().gte(0).optional(), max_interval_cost: z.number().gte(0).optional(), aoi_coverage_percentage: z.number().gte(0).lte(100).optional(), filled_coverage_percentage: z.number().gte(0).lte(100).optional(), source: z.string().min(1).optional(), processing_status: z.string().min(1)})).optional(), created_at: z.string(), updated_at: z.string(), products: z.array(z.object({id: z.string().optional(), name: z.string().optional(), output_id: z.string().optional(), tiles: z.array(z.string()).optional()})).optional(), deprecation_notice: z.string().optional()}); export const paginationFragment = z.object({per_page: z.number().int(), cursor: z.object({next: z.string().optional(), self: z.string().optional()})}); export const schema200ListResponse2 = z.object({data: z.array(intervalResultResource), pagination: paginationFragment}); export const intervalResultStandardResource = z.object({id: z.string().min(1), pipeline_id: z.string().min(1), status: z.enum(["pending", "requested", "scheduled", "committed", "cancelled", "future", "failed", "waiting", "processing", "complete", "searching", "retrieving"]), message: z.string().optional(), interval: z.object({start_date: z.string().min(1), end_date: z.string().min(1)}), total_interval_cost: z.number().gte(0).optional(), probability_of_collection: z.object({probability_percent: z.number().gte(0).lte(100), probability_reason: z.string().min(1).optional()}).optional(), overall_metadata: z.object({scene_height: z.number().gte(0), scene_width: z.number().gte(0), filled_area_km2: z.number().gte(0), filled_area_percentage_of_aoi: z.number().gte(0).lte(100), cloud_cover_percentage: z.number().gte(0).lte(100), cloud_cover_percentage_of_aoi: z.number().gte(0).lte(100), visible_area_km2: z.number().gte(0), visible_area_percentage: z.number().gte(0).lte(100), visible_area_percentage_of_aoi: z.number().gte(0).lte(100)}).optional(), results: z.array(z.object({name: z.string().optional(), output_id: z.string().min(1).optional(), capture_time: z.string().optional(), resolution_x: z.number().optional(), resolution_y: z.number().optional(), source: z.string().optional(), sensor_mode: z.string().optional(), sensor_type: z.string().optional(), tiles: z.array(z.object({name: z.string().optional(), size_in_mb: z.number().gte(0).optional(), cloud_cover_percentage: z.number().gte(0).lte(100).optional(), valid_pixel_percentage: z.number().gte(0).lte(100).optional(), created_at: z.string().optional(), updated_at: z.string().optional(), preview_file: z.string().optional(), visual_file: z.string().optional(), analytics_file: z.string().optional(), metadata_file: z.string().optional(), vector_files: z.array(z.object({name: z.string().min(1), description: z.string().min(1), uri: z.string().min(1)})).optional(), raster_files: z.array(z.object({name: z.string().min(1), description: z.string().min(1), uri: z.string().min(1)})).optional(), metadata_files: z.array(z.object({name: z.string().min(1), description: z.string().min(1), uri: z.string().min(1)})).optional()})).optional()})).optional(), alternate_search_results: z.array(z.object({index: z.number().int().gte(0).optional(), search_result_id: z.string().min(36).max(36).optional(), preview_url: z.string().optional(), preview_bbox: previewBboxGeojsonGeometry.optional(), capture_date: z.string().min(10).max(10).optional(), resolution: z.number().gte(0).optional(), price_per_km2: z.number().gte(0).optional(), max_interval_cost: z.number().gte(0).optional(), aoi_coverage_percentage: z.number().gte(0).lte(100).optional(), filled_coverage_percentage: z.number().gte(0).lte(100).optional(), source: z.string().min(1).optional(), processing_status: z.string().min(1)})).optional(), created_at: z.string(), updated_at: z.string()}); export const schema200ListStandardResponse = z.object({data: z.array(intervalResultStandardResource), pagination: paginationFragment}); export const getApiIntervalResultsResponse = z.union([schema200ListResponse2, schema200ListStandardResponse]); 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 }; /** * List All Interval Results * * GET /interval_results */ export const getApiIntervalResults = async (args: GetApiIntervalResultsArgs, options?: GetApiIntervalResultsOptions) => { const {baseUrl = "https://api.skywatch.co/earthcache", fetch: fetchFn = fetch, ApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.per_page != null) query.append("per_page", String(args.per_page)) if (args.sort != null) query.append("sort", String(args.sort)) if (args.cursor != null) query.append("cursor", String(args.cursor)) if (args.pipeline_id != null) query.append("pipeline_id", String(args.pipeline_id)) if (args.format != null) query.append("format", String(args.format)) if (ApiKey !== undefined) headers.set("x-api-key", ApiKey) const url = `${baseUrl.replace(/\/+$/, '')}/interval_results${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(getApiIntervalResultsResponse, await res.json()) };