UNPKG

@jingbof/rets-client

Version:

RETS (Real Estate Transaction Standards) Client in Typescript

235 lines (212 loc) 6.24 kB
import dotenv from 'dotenv' import { promises as fs, createWriteStream } from 'fs' import { createHash } from 'crypto' import { Transform, Writable, Readable, PassThrough } from 'stream' import { unescape } from 'querystring' import { IRetsClientOptions, RetsMetadataType, ReturnType, IRetsRequestConfig, RetsObject, } from './types' import { DdfCulture, getClient, IRetsMetadataOptions } from '.' // const { RetsClient, RetsVersion, RetsFormat, DdfCulture, RetsRequestMethod } = require('./src') dotenv.config() const dateToString = (date: Date) => `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date .getDate() .toString() .padStart(2, '0')}` const config = { url: process.env.RETS_TEST_URL || '', username: process.env.RETS_TEST_USERNAME || '', password: process.env.RETS_TEST_PASSWORD || '', // debugResponseFilename: ({ method, url }: IRetsRequestConfig) => { // const now = new Date() // const hash = createHash('md5') // // build hash name // hash.update(url.toString()) // return `tests/${now.toISOString()}-${hash.digest('hex').toString()}.raw` // }, } /// /// TREB Specifics ////// enum REBGVClass { CondoProperty = 'CondoProperty', DeletedProperty = 'DeletedProperty', ResidentialProperty = 'ResidentialProperty', CommercialProperty = 'CommercialProperty', } enum REBGVResources { Property = 'Property', } enum REBGVObjects { Photo = 'Photo', Thumbnail = 'Thumbnail', } /// //// Testers ///// const testLogin = async () => { console.log('>> testLogin') await getClient(config, async () => { console.log('Logged In!') }) } const testSearch = async () => { console.log('>> testSearch') await getClient(config, async ({ search }) => { const listings = (await search({ // query: '(Status=A)', query: '(timestamp_sql=2021-06-01T00:00:00+)', limit: 4, searchType: REBGVResources.Property, className: REBGVClass.ResidentialProperty, })) as Record<string, string>[] console.log( 'listings', listings.map((item) => item.Ml_num), ) }) } const testStreamSearch = async () => { console.log('>> testStreamSearch') await getClient(config, async ({ search }) => { const avgPrice = 0 let count = 0 const saveToFile = new PassThrough({ objectMode: true, }) const searchStream = ( (await search({ // query: '(Status=A)', query: '(timestamp_sql=2021-07-15T00:00:00+)', // query: '(ml_num=E5230190)', limit: 3, searchType: REBGVResources.Property, className: REBGVClass.ResidentialProperty, returnType: ReturnType.Stream, processText: (text: string) => unescape(text), })) as Readable ) // .pipe( // new Transform({ // objectMode: true, // transform: (data, _, done) => { // const orig = parseFloat(data.Orig_dol) // avgPrice = (avgPrice * count + (Number.isNaN(orig) ? 0 : orig)) / (count + 1) // count += Number.isNaN(orig) ? 0 : 1 // done(null, data) // }, // }), // ) .pipe(saveToFile) .pipe( new Writable({ objectMode: true, write: (data, _, done) => { count += 1 if (!data.Ml_num.match(/^[A-Z]\d{7}$/)) { console.log('Invalid!!!!', count, data.Ml_num) } done() }, }), ) saveToFile.pipe( new Writable({ objectMode: true, write: (data, _, done) => { const saveData = async (save: Buffer) => { await fs.appendFile('test.json', JSON.stringify(save)) done() } saveData(data) }, }), ) // wait for the stream to finish await new Promise((fulfill) => searchStream.on('close', fulfill)) console.log('avgPrice', avgPrice, ' out of ', count) }) } const testObjects = async () => { console.log('>> testObjects') await getClient(config, async ({ getObject }) => { const objects = await getObject({ resource: REBGVResources.Property, // type: REBGVObjects.Photo, type: REBGVObjects.Thumbnail, // contentId: '262937674', contentId: ['262937674', '262937815'], // id: '1', // withLocation: true, }) console.log('objects', objects) const dir = 'tests' fs.mkdir(dir, { recursive: true }) console.log(`saveToFiles in directory [${dir}]`) objects.forEach((obj) => { if (obj.contentType === 'image/jpeg') { fs.writeFile(`${dir}/${obj.contentId}-${obj.objectId}-Thumbnail.jpg`, obj.data) } else { console.log('obj', obj.location) } }) }) } const testMetadata = async () => { console.log('>> testMetada') await getClient(config, async ({ getMetadata }) => { const resources = await getMetadata({ type: RetsMetadataType.Resource, }) console.log('getMetadata.Resource', resources) const classes = await getMetadata({ type: RetsMetadataType.Class, }) console.log('getMetadata.Class', classes) // const tables = await getMetadata({ // type: RetsMetadataType.Table, // classType: 'CommercialProperty', // id: 'Property', // }) // await fs.writeFile( // 'tables.json', // JSON.stringify( // { // tables, // }, // undefined, // 2, // ), // ) // console.log('getMetadata.Table', tables) const objects = await getMetadata({ type: RetsMetadataType.Objects, }) console.log('getMetadata.Class', objects) }) } const testDataMap = async () => { console.log('>> testDataMap') await getClient(config, async ({ getDataMap }) => { const dataMap = await getDataMap() console.log('getDataMap', dataMap) }) } const main = async () => { console.log('Start!') // await testLogin() // await testMetadata() // await testDataMap() // await testSearch() await testObjects() // await testStreamSearch() console.log('Finish!') } try { console.log('Begin!') main() } catch (e) { console.log('ERROR:: ', e) } // main().catch(console.error)