import {z} from 'zod' export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsSearchLocation = {state?: ('ACT' | 'NSW' | 'QLD' | 'VIC' | 'SA' | 'WA' | 'NT' | 'TAS') | undefined, region?: string | undefined, area?: string | undefined, suburb?: string | undefined, postCode?: string | undefined, includeSurroundingSuburbs?: boolean | undefined, surroundingRadiusInMeters?: number | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsSchoolCatchment = {name?: string | undefined, state?: string | undefined, postcode?: string | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsCustomSortElement = {field?: ('AdId' | 'PromoLevelScore' | 'FreshnessLevel' | 'ProductBoost' | 'DateUpdated' | 'DateListed' | 'SuburbName' | 'PriceDisplayOption' | 'SoldDate' | 'Price' | 'EarliestInspectionOpenTime' | 'EarliestAuctionTime' | 'DateAvailable') | undefined, direction?: ('Ascending' | 'Descending') | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsCustomSort = {elements?: Array | undefined, boostPrimarySuburbs?: boolean | undefined}; export type DomainSearchServiceV2ModelSystemNullableDomainSearchWebApiV2ModelsSortBy = {sortKey?: ('Default' | 'Suburb' | 'Price' | 'DateUpdated' | 'InspectionTime' | 'AuctionTime' | 'SoldDate' | 'DefaultThenDateUpdated' | 'DateAvailable' | 'DateListed') | undefined, direction?: ('Ascending' | 'Descending') | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsGeoPoint = {lat?: number | undefined, lon?: number | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsBox = {topLeft?: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsGeoPoint | undefined, bottomRight?: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsGeoPoint | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsCircle = {center?: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsGeoPoint | undefined, radiusInMeters?: number | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsPolygon = {points?: Array | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsGeoWindow = {box?: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsBox | undefined, circle?: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsCircle | undefined, polygon?: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsPolygon | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsTagQuery = {criteria?: ('Include' | 'Exclude') | undefined, tag?: string | undefined}; export type DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsSearchParameters = {listingType?: ('Sale' | 'Rent' | 'Share' | 'Sold' | 'NewHomes') | undefined, propertyTypes?: (Array<'AcreageSemiRural' | 'ApartmentUnitFlat' | 'Aquaculture' | 'BlockOfUnits' | 'CarSpace' | 'DairyFarming' | 'DevelopmentSite' | 'Duplex' | 'Farm' | 'FishingForestry' | 'NewHomeDesigns' | 'House' | 'NewHouseLand' | 'IrrigationServices' | 'NewLand' | 'Livestock' | 'NewApartments' | 'Penthouse' | 'RetirementVillage' | 'Rural' | 'SemiDetached' | 'SpecialistFarm' | 'Studio' | 'Terrace' | 'Townhouse' | 'VacantLand' | 'Villa' | 'Cropping' | 'Viticulture' | 'MixedFarming' | 'Grazing' | 'Horticulture' | 'Equine' | 'Farmlet' | 'Orchard' | 'RuralLifestyle'>) | undefined, propertyFeatures?: (Array<'AirConditioning' | 'BuiltInWardrobes' | 'CableOrSatellite' | 'Ensuite' | 'Floorboards' | 'Gas' | 'InternalLaundry' | 'PetsAllowed' | 'SecureParking' | 'SwimmingPool' | 'Furnished' | 'GroundFloor' | 'WaterViews' | 'NorthFacing' | 'CityViews' | 'IndoorSpa' | 'Gym' | 'AlarmSystem' | 'Intercom' | 'BroadbandInternetAccess' | 'Bath' | 'Fireplace' | 'SeparateDiningRoom' | 'Heating' | 'Dishwasher' | 'Study' | 'TennisCourt' | 'Shed' | 'FullyFenced' | 'BalconyDeck' | 'GardenCourtyard' | 'OutdoorSpa' | 'DoubleGlazedWindows' | 'EnergyEfficientAppliances' | 'WaterEfficientAppliances' | 'WallCeilingInsulation' | 'RainwaterStorageTank' | 'GreywaterSystem' | 'WaterEfficientFixtures' | 'SolarHotWater' | 'SolarPanels'>) | undefined, listingAttributes?: (Array<'HasPhotos' | 'HasPrice' | 'NotUpForAuction' | 'NotUnderContract' | 'MarkedAsNew'>) | undefined, propertyEstablishedType?: ('Any' | 'New' | 'Established') | undefined, minBedrooms?: number | undefined, maxBedrooms?: number | undefined, minBathrooms?: number | undefined, maxBathrooms?: number | undefined, minCarspaces?: number | undefined, maxCarspaces?: number | undefined, minPrice?: number | undefined, maxPrice?: number | undefined, minLandArea?: number | undefined, maxLandArea?: number | undefined, advertiserIds?: Array | undefined, adIds?: Array | undefined, excludeAdIds?: Array | undefined, locations?: Array | undefined, schoolCatchments?: Array | undefined, locationTerms?: string | undefined, keywords?: Array | undefined, newDevOnly?: boolean | undefined, inspectionFrom?: string | undefined, inspectionTo?: string | undefined, auctionFrom?: string | undefined, auctionTo?: string | undefined, dateAvailableFrom?: string | undefined, dateAvailableTo?: string | undefined, ruralOnly?: boolean | undefined, excludePriceWithheld?: boolean | undefined, excludeDepositTaken?: boolean | undefined, topspotKeywords?: Array | undefined, customSort?: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsCustomSort | undefined, sort?: DomainSearchServiceV2ModelSystemNullableDomainSearchWebApiV2ModelsSortBy | undefined, pageSize?: number | undefined, geoWindow?: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsGeoWindow | undefined, updatedSince?: string | undefined, listedSince?: string | undefined, includeInspectionAggregations?: boolean | undefined, aggregations?: Array | undefined, tags?: Array | undefined, pageNumber?: number | undefined}; export type CreateApiV1ListingsResidentialSearchArgs = {body: DomainSearchServiceV2ModelDomainSearchWebApiV2ModelsSearchParameters}; export type CreateApiV1ListingsResidentialSearchOptions = {baseUrl?: string | undefined, apikey?: string | undefined, fetch?: typeof fetch | undefined}; export const domainSearchServiceV2ModelDomainSearchContractsV2Contact = z.object({name: z.string().optional(), photoUrl: z.string().optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2Advertiser = z.object({type: z.enum(["Agency", "Private"]).optional(), id: z.number().int().optional(), name: z.string().optional(), logoUrl: z.string().optional(), preferredColourHex: z.string().optional(), bannerUrl: z.string().optional(), contacts: z.array(domainSearchServiceV2ModelDomainSearchContractsV2Contact).optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2PriceDetails = z.object({price: z.number().int().optional(), priceFrom: z.number().int().optional(), priceTo: z.number().int().optional(), displayPrice: z.string().optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2Media = z.object({category: z.literal("Image").optional(), url: z.string().optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2PropertyDetails = z.object({state: z.enum(["ACT", "NSW", "QLD", "VIC", "SA", "WA", "NT", "TAS"]).optional(), features: z.array(z.enum(["Unrecognised", "AirConditioning", "BuiltInWardrobes", "CableOrSatellite", "Ensuite", "Floorboards", "Gas", "InternalLaundry", "PetsAllowed", "SecureParking", "SwimmingPool", "Furnished", "GroundFloor", "WaterViews", "NorthFacing", "CityViews", "IndoorSpa", "Gym", "AlarmSystem", "Intercom", "BroadbandInternetAccess", "Bath", "Fireplace", "SeparateDiningRoom", "Heating", "Dishwasher", "Study", "TennisCourt", "Shed", "FullyFenced", "BalconyDeck", "GardenCourtyard", "OutdoorSpa", "DoubleGlazedWindows", "EnergyEfficientAppliances", "WaterEfficientAppliances", "WallCeilingInsulation", "RainwaterStorageTank", "GreywaterSystem", "WaterEfficientFixtures", "SolarHotWater", "SolarPanels"])).optional(), propertyType: z.enum(["Unknown", "AcreageSemiRural", "ApartmentUnitFlat", "Aquaculture", "BlockOfUnits", "CarSpace", "DairyFarming", "DevelopmentSite", "Duplex", "Farm", "FishingForestry", "NewHomeDesigns", "House", "NewHouseLand", "IrrigationServices", "NewLand", "Livestock", "NewApartments", "Penthouse", "RetirementVillage", "Rural", "SemiDetached", "SpecialistFarm", "Studio", "Terrace", "Townhouse", "VacantLand", "Villa", "Cropping", "Viticulture", "MixedFarming", "Grazing", "Horticulture", "Equine", "Farmlet", "Orchard", "RuralLifestyle"]).optional(), allPropertyTypes: z.array(z.enum(["Unknown", "AcreageSemiRural", "ApartmentUnitFlat", "Aquaculture", "BlockOfUnits", "CarSpace", "DairyFarming", "DevelopmentSite", "Duplex", "Farm", "FishingForestry", "NewHomeDesigns", "House", "NewHouseLand", "IrrigationServices", "NewLand", "Livestock", "NewApartments", "Penthouse", "RetirementVillage", "Rural", "SemiDetached", "SpecialistFarm", "Studio", "Terrace", "Townhouse", "VacantLand", "Villa", "Cropping", "Viticulture", "MixedFarming", "Grazing", "Horticulture", "Equine", "Farmlet", "Orchard", "RuralLifestyle"])).optional(), bathrooms: z.number().optional(), bedrooms: z.number().optional(), carspaces: z.number().int().optional(), unitNumber: z.string().optional(), streetNumber: z.string().optional(), street: z.string().optional(), area: z.string().optional(), region: z.string().optional(), suburb: z.string().optional(), suburbId: z.number().int().optional(), postcode: z.string().optional(), displayableAddress: z.string().optional(), latitude: z.number().optional(), longitude: z.number().optional(), mapCertainty: z.number().int().optional(), landArea: z.number().optional(), buildingArea: z.number().optional(), onlyShowProperties: z.array(z.string()).optional(), displayAddressType: z.string().optional(), isRural: z.boolean().optional(), topSpotKeywords: z.array(z.string()).optional(), isNew: z.boolean().optional(), tags: z.array(z.string()).optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2AuctionSchedule = z.object({time: z.string().optional(), auctionLocation: z.string().optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2Inspection = z.object({openingTime: z.string().optional(), closingTime: z.string().optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2InspectionSchedule = z.object({byAppointment: z.boolean().optional(), recurring: z.boolean().optional(), times: z.array(domainSearchServiceV2ModelDomainSearchContractsV2Inspection).optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2SoldData = z.object({source: z.enum(["Agency", "Apm"]).optional(), saleMethod: z.enum(["NotStated", "SoldByAuction", "SoldByPrivateTreaty", "Withdrawn", "SoldPriorToAuction"]).optional(), soldDate: z.string().optional(), soldPrice: z.number().int().optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2PropertyListing = z.object({promoLevel: z.enum(["Standard", "StandardPP", "Elite", "ElitePP", "PremiumPlus"]).optional(), listingType: z.enum(["Sale", "Rent", "Share", "Sold", "NewHomes"]).optional(), id: z.number().int().optional(), projectId: z.number().int().optional(), advertiser: domainSearchServiceV2ModelDomainSearchContractsV2Advertiser.optional(), priceDetails: domainSearchServiceV2ModelDomainSearchContractsV2PriceDetails.optional(), media: z.array(domainSearchServiceV2ModelDomainSearchContractsV2Media).optional(), propertyDetails: domainSearchServiceV2ModelDomainSearchContractsV2PropertyDetails.optional(), headline: z.string().optional(), summaryDescription: z.string().optional(), hasFloorplan: z.boolean().optional(), hasVideo: z.boolean().optional(), labels: z.array(z.string()).optional(), auctionSchedule: domainSearchServiceV2ModelDomainSearchContractsV2AuctionSchedule.optional(), dateAvailable: z.string().optional(), dateListed: z.string().optional(), inspectionSchedule: domainSearchServiceV2ModelDomainSearchContractsV2InspectionSchedule.optional(), soldData: domainSearchServiceV2ModelDomainSearchContractsV2SoldData.optional(), listingSlug: z.string().optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2Project = z.object({promoLevel: z.enum(["Standard", "Premium"]).optional(), state: z.enum(["ACT", "NSW", "QLD", "VIC", "SA", "WA", "NT", "TAS"]).optional(), id: z.number().int().optional(), name: z.string().optional(), bannerUrl: z.string().optional(), preferredColorHex: z.string().optional(), logoUrl: z.string().optional(), labels: z.array(z.string()).optional(), displayableAddress: z.string().optional(), suburb: z.string().optional(), suburbId: z.number().int().optional(), features: z.array(z.string()).optional(), media: z.array(domainSearchServiceV2ModelDomainSearchContractsV2Media).optional(), projectSlug: z.string().optional()}); export const domainSearchServiceV2ModelDomainSearchContractsV2SearchResult = z.object({type: z.enum(["PropertyListing", "Project"]).optional(), listing: domainSearchServiceV2ModelDomainSearchContractsV2PropertyListing.optional(), listings: z.array(domainSearchServiceV2ModelDomainSearchContractsV2PropertyListing).optional(), project: domainSearchServiceV2ModelDomainSearchContractsV2Project.optional()}); export const createApiV1ListingsResidentialSearchResponse = z.array(domainSearchServiceV2ModelDomainSearchContractsV2SearchResult); 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 }; /** * Retrieves residential listings matching the specified criteria. * * POST /v1/listings/residential/_search * * Also accepts auth: oauth2 */ export const createApiV1ListingsResidentialSearch = async (args: CreateApiV1ListingsResidentialSearchArgs, options?: CreateApiV1ListingsResidentialSearchOptions) => { const {baseUrl = "https://api.domain.com.au", fetch: fetchFn = fetch, apikey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (apikey !== undefined) headers.set("x-api-key", apikey) const url = `${baseUrl.replace(/\/+$/, '')}/v1/listings/residential/_search${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(createApiV1ListingsResidentialSearchResponse, await res.json()) };