import {z} from 'zod' export type SearchServiceV2DomainSearchWebApiV2ModelsSearchLocation = {state?: ('ACT' | 'NSW' | 'QLD' | 'VIC' | 'SA' | 'WA' | 'NT' | 'TAS') | undefined, region?: (string | null) | undefined, area?: (string | null) | undefined, suburb?: (string | null) | undefined, postCode?: (string | null) | undefined, includeSurroundingSuburbs?: (boolean | null) | undefined, surroundingRadiusInMeters?: (number | null) | undefined, definesPostcodeOnly?: (boolean | null) | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsSchoolCatchment = {name?: (string | null) | undefined, state?: (string | null) | undefined, postcode?: (string | null) | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsCustomSortElement = {field?: ('AdId' | 'PromoLevelScore' | 'FreshnessLevel' | 'ProductBoost' | 'DateUpdated' | 'DateListed' | 'SuburbName' | 'PriceDisplayOption' | 'SoldDate' | 'Price' | 'EarliestInspectionOpenTime' | 'EarliestAuctionTime' | 'DateAvailable') | undefined, direction?: ('Ascending' | 'Descending') | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsCustomSort = {elements?: (Array | null) | undefined, boostPrimarySuburbs?: (boolean | null) | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsSortBy = {sortKey?: ('Default' | 'Suburb' | 'Price' | 'DateUpdated' | 'InspectionTime' | 'AuctionTime' | 'SoldDate' | 'DefaultThenDateUpdated' | 'DateAvailable' | 'DateListed') | undefined, direction?: ('Ascending' | 'Descending') | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsGeoPoint = {lat?: (number | null) | undefined, lon?: (number | null) | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsBox = {topLeft?: SearchServiceV2DomainSearchWebApiV2ModelsGeoPoint | undefined, bottomRight?: SearchServiceV2DomainSearchWebApiV2ModelsGeoPoint | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsCircle = {center?: SearchServiceV2DomainSearchWebApiV2ModelsGeoPoint | undefined, radiusInMeters: number}; export type SearchServiceV2DomainSearchWebApiV2ModelsPolygon = {points?: (Array | null) | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsGeoWindow = {box?: SearchServiceV2DomainSearchWebApiV2ModelsBox | undefined, circle?: SearchServiceV2DomainSearchWebApiV2ModelsCircle | undefined, polygon?: SearchServiceV2DomainSearchWebApiV2ModelsPolygon | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsTagQuery = {tag?: (string | null) | undefined, criteria?: ('Include' | 'Exclude') | undefined}; export type SearchServiceV2DomainSearchWebApiV2ModelsSearchParameters = {listingType?: ('Sale' | 'Rent' | 'Share' | 'Sold' | 'NewHomes') | undefined, saleMethods?: (Array<'NotStated' | 'Auction' | 'PrivateTreaty' | 'Tender' | 'ExpressionOfInterest'> | null) | undefined, minBedrooms?: (number | null) | undefined, maxBedrooms?: (number | null) | undefined, minBathrooms?: (number | null) | undefined, maxBathrooms?: (number | null) | undefined, minCarspaces?: (number | null) | undefined, maxCarspaces?: (number | null) | undefined, minPrice?: (number | null) | undefined, maxPrice?: (number | null) | undefined, minLandArea?: (number | null) | undefined, maxLandArea?: (number | null) | undefined, advertiserIds?: (Array | null) | undefined, adIds?: (Array | null) | undefined, excludeAdIds?: (Array | null) | 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'> | null) | 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'> | null) | undefined, locations?: (Array | null) | undefined, schoolCatchments?: (Array | null) | undefined, locationTerms?: (string | null) | undefined, keywords?: (Array | null) | undefined, listingAttributes?: (Array<'HasPhotos' | 'HasPrice' | 'NotUpForAuction' | 'NotUnderContract' | 'MarkedAsNew' | 'HasMatterport'> | null) | undefined, newDevOnly?: (boolean | null) | undefined, inspectionFrom?: (string | null) | undefined, inspectionTo?: (string | null) | undefined, auctionFrom?: (string | null) | undefined, auctionTo?: (string | null) | undefined, dateAvailableFrom?: (string | null) | undefined, dateAvailableTo?: (string | null) | undefined, ruralOnly?: (boolean | null) | undefined, excludePriceWithheld?: (boolean | null) | undefined, excludeDepositTaken?: (boolean | null) | undefined, topspotKeywords?: (Array | null) | undefined, customSort?: SearchServiceV2DomainSearchWebApiV2ModelsCustomSort | undefined, sort?: SearchServiceV2DomainSearchWebApiV2ModelsSortBy | undefined, page?: (number | null) | undefined, pageSize?: (number | null) | undefined, geoWindow?: SearchServiceV2DomainSearchWebApiV2ModelsGeoWindow | undefined, updatedSince?: (string | null) | undefined, listedSince?: (string | null) | undefined, propertyEstablishedType?: ('Any' | 'New' | 'Established') | undefined, includeInspectionAggregations?: (boolean | null) | undefined, tags?: (Array | null) | undefined, aggregations?: (Array | null) | undefined}; export type CreateApiV1ListingSearchResidentialSearchArgs = {body: SearchServiceV2DomainSearchWebApiV2ModelsSearchParameters}; export type CreateApiV1ListingSearchResidentialSearchOptions = {baseUrl?: string | undefined, apikey?: string | undefined, fetch?: typeof fetch | undefined}; export const searchServiceV2DomainSearchContractsV2Contact = z.object({name: z.string().nullable().optional(), photoUrl: z.string().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2Advertiser = z.object({id: z.number().int().nullable().optional(), type: z.enum(["Agency", "Private"]).optional(), name: z.string().nullable().optional(), logoUrl: z.string().nullable().optional(), preferredColourHex: z.string().nullable().optional(), bannerUrl: z.string().nullable().optional(), contacts: z.array(searchServiceV2DomainSearchContractsV2Contact).nullable().optional()}); export const searchServiceV2DomainSearchContractsV2PriceDetails = z.object({price: z.number().int().nullable().optional(), priceFrom: z.number().int().nullable().optional(), priceTo: z.number().int().nullable().optional(), displayPrice: z.string().nullable().optional(), canDisplayPrice: z.boolean().nullable().optional(), depositTaken: z.boolean().nullable().optional(), saleMethod: z.enum(["NotStated", "Auction", "PrivateTreaty", "Tender", "ExpressionOfInterest"]).optional()}); export const searchServiceV2DomainSearchContractsV2Media = z.object({category: z.literal("Image").optional(), type: z.enum(["Photo", "Floorplan"]).optional(), url: z.string().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2PropertyDetails = z.object({bathrooms: z.number().nullable().optional(), bedrooms: z.number().nullable().optional(), carspaces: z.number().int().nullable().optional(), unitNumber: z.string().nullable().optional(), streetNumber: z.string().nullable().optional(), street: z.string().nullable().optional(), area: z.string().nullable().optional(), region: z.string().nullable().optional(), suburb: z.string().nullable().optional(), suburbId: z.number().int().nullable().optional(), postcode: z.string().nullable().optional(), state: z.enum(["ACT", "NSW", "QLD", "VIC", "SA", "WA", "NT", "TAS"]).optional(), displayableAddress: z.string().nullable().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"])).nullable().optional(), latitude: z.number().nullable().optional(), longitude: z.number().nullable().optional(), mapCertainty: z.number().int().nullable().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"])).nullable().optional(), landArea: z.number().nullable().optional(), buildingArea: z.number().nullable().optional(), onlyShowProperties: z.array(z.string()).nullable().optional(), displayAddressType: z.string().nullable().optional(), isRural: z.boolean().nullable().optional(), topSpotKeywords: z.array(z.string()).nullable().optional(), isNew: z.boolean().nullable().optional(), tags: z.array(z.string()).nullable().optional()}); export const searchServiceV2DomainSearchContractsV2MatterportInterior = z.object({matterportKey: z.string().nullable().optional(), matterportThumbnailUri: z.string().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2MatterportExterior = z.object({attachmentId: z.number().int().nullable().optional(), gaussianSplatKey: z.string().nullable().optional(), gaussianThumbnailUri: z.string().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2Matterport = z.object({interior: searchServiceV2DomainSearchContractsV2MatterportInterior.optional(), exterior: searchServiceV2DomainSearchContractsV2MatterportExterior.optional()}); export const searchServiceV2DomainSearchContractsV2AuctionSchedule = z.object({time: z.string().nullable().optional(), auctionLocation: z.string().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2Inspection = z.object({openingTime: z.string().nullable().optional(), closingTime: z.string().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2InspectionSchedule = z.object({byAppointment: z.boolean().nullable().optional(), recurring: z.boolean().nullable().optional(), times: z.array(searchServiceV2DomainSearchContractsV2Inspection).nullable().optional()}); export const searchServiceV2DomainSearchContractsV2SoldData = z.object({source: z.enum(["Agency", "Apm"]).optional(), soldDate: z.string().nullable().optional(), soldPrice: z.number().int().nullable().optional(), saleMethod: z.enum(["NotStated", "SoldByAuction", "SoldByPrivateTreaty", "Withdrawn", "SoldPriorToAuction"]).optional()}); export const searchServiceV2DomainSearchContractsV2PropertyListing = z.object({id: z.number().int().nullable().optional(), projectId: z.number().int().nullable().optional(), promoLevel: z.enum(["Standard", "StandardPP", "Elite", "ElitePP", "PremiumPlus"]).optional(), listingType: z.enum(["Sale", "Rent", "Share", "Sold", "NewHomes"]).optional(), advertiser: searchServiceV2DomainSearchContractsV2Advertiser.optional(), priceDetails: searchServiceV2DomainSearchContractsV2PriceDetails.optional(), media: z.array(searchServiceV2DomainSearchContractsV2Media).nullable().optional(), propertyDetails: searchServiceV2DomainSearchContractsV2PropertyDetails.optional(), headline: z.string().nullable().optional(), summaryDescription: z.string().nullable().optional(), hasFloorplan: z.boolean().nullable().optional(), hasVideo: z.boolean().nullable().optional(), matterport: searchServiceV2DomainSearchContractsV2Matterport.optional(), labels: z.array(z.string()).nullable().optional(), auctionSchedule: searchServiceV2DomainSearchContractsV2AuctionSchedule.optional(), dateAvailable: z.string().nullable().optional(), dateListed: z.string().nullable().optional(), inspectionSchedule: searchServiceV2DomainSearchContractsV2InspectionSchedule.optional(), soldData: searchServiceV2DomainSearchContractsV2SoldData.optional(), listingSlug: z.string().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2Project = z.object({id: z.number().int().nullable().optional(), name: z.string().nullable().optional(), promoLevel: z.enum(["Standard", "Premium"]).optional(), bannerUrl: z.string().nullable().optional(), preferredColorHex: z.string().nullable().optional(), logoUrl: z.string().nullable().optional(), labels: z.array(z.string()).nullable().optional(), displayableAddress: z.string().nullable().optional(), suburb: z.string().nullable().optional(), suburbId: z.number().int().nullable().optional(), state: z.enum(["ACT", "NSW", "QLD", "VIC", "SA", "WA", "NT", "TAS"]).optional(), features: z.array(z.string()).nullable().optional(), media: z.array(searchServiceV2DomainSearchContractsV2Media).nullable().optional(), projectSlug: z.string().nullable().optional(), priceFrom: z.number().int().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2SearchResult = z.object({type: z.enum(["PropertyListing", "Project"]).optional(), listing: searchServiceV2DomainSearchContractsV2PropertyListing.optional(), listings: z.array(searchServiceV2DomainSearchContractsV2PropertyListing).nullable().optional(), project: searchServiceV2DomainSearchContractsV2Project.optional()}); export const searchServiceV2DomainSearchContractsV2ResultMetadata = z.object({aggregations: z.record(z.string(), z.record(z.string(), z.number().int()).nullable()).nullable().optional(), surroundingSuburbsListingsCount: z.number().int().nullable().optional(), newHomesCount: z.number().int().nullable().optional(), ruralListingsCount: z.number().int().nullable().optional(), medianPrice: z.number().int().nullable().optional(), totalListingsExcludingChildren: z.number().int().nullable().optional(), surroundingSuburbsListingsExcludingChildren: z.number().int().nullable().optional()}); export const searchServiceV2DomainSearchContractsV2SearchResults = z.object({results: z.array(searchServiceV2DomainSearchContractsV2SearchResult).nullable().optional(), totalResults: z.number().int().nullable().optional(), totalPages: z.number().int().nullable().optional(), page: z.number().int().nullable().optional(), metadata: searchServiceV2DomainSearchContractsV2ResultMetadata.optional(), actualTotalResults: z.number().int().nullable().optional(), actualTotalResultsExceedsMaximum: z.boolean().nullable().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 }; /** * Retrieves residential listings matching the specified criteria. * * POST /v1/listingSearch/residential/search * * Also accepts auth: oauth2 */ export const createApiV1ListingSearchResidentialSearch = async (args: CreateApiV1ListingSearchResidentialSearchArgs, options?: CreateApiV1ListingSearchResidentialSearchOptions) => { 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/listingSearch/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(searchServiceV2DomainSearchContractsV2SearchResults, await res.json()) };