rets-client
Advanced tools
Comparing version
36
index.js
@@ -1,33 +0,9 @@ | ||
var Promise = require('bluebird'); | ||
/* jshint node:true */ | ||
/* jshint -W097 */ | ||
'use strict'; | ||
var coffee = require('coffee-script'); | ||
coffee.register(); | ||
var replycodes = require('./lib/replycodes'); | ||
var Client = require('./lib/client'); | ||
var utils = require('./lib/utils'); | ||
/* Available settings: | ||
* loginUrl: RETS login URL (i.e http://<MLS_DOMAIN>/rets/login.ashx) | ||
* username: username credential | ||
* password: password credential | ||
* version: rets version | ||
* | ||
* //RETS-UA-Authorization | ||
* userAgent | ||
* userAgentPassword | ||
* sessionId | ||
*/ | ||
module.exports = { | ||
replycode: replycodes.codeMap, | ||
RetsReplyError: utils.RetsReplyError, | ||
RetsServerError: utils.RetsServerError, | ||
Client: Client, | ||
getAutoLogoutClient: function(settings, handler) { | ||
var client = new Client(settings); | ||
return client.login() | ||
.then(handler) | ||
.finally(function() { | ||
return client.logout(); | ||
}); | ||
} | ||
}; | ||
module.exports = require('./lib/api'); |
{ | ||
"name": "rets-client", | ||
"version": "2.0.7", | ||
"version": "3.0.0", | ||
"description": "A RETS client (Real Estate Transaction Standard).", | ||
@@ -11,7 +11,8 @@ "main": "index.js", | ||
"formidable": "~1.0.15", | ||
"node-expat": "^2.3.10", | ||
"request": "^2.55.0", | ||
"stream-buffers": "~0.2.5", | ||
"through2": "^2.0.0", | ||
"tough-cookie": "^0.13.0", | ||
"winston": "~0.7.3", | ||
"xml2js": "~0.4.4" | ||
"winston": "~0.7.3" | ||
}, | ||
@@ -34,3 +35,6 @@ "directories": { | ||
"promise", | ||
"mls" | ||
"mls", | ||
"stream", | ||
"streams", | ||
"streaming" | ||
], | ||
@@ -42,3 +46,3 @@ "author": "Steve Bruno <stevenrbruno@icloud.com>", | ||
], | ||
"license": "The MIT License (MIT)", | ||
"license": "MIT", | ||
"bugs": { | ||
@@ -45,0 +49,0 @@ "url": "https://github.com/sbruno81/rets-client/issues" |
@@ -5,9 +5,27 @@ rets-client | ||
Version 2.x of rets-client has a completely different interface from the 1.x version -- code written for 1.x will not | ||
work with 2.x. If you wish to continue to use the 1.x version, you can use the | ||
[v1 branch](https://github.com/sbruno81/rets-client/tree/v1). | ||
## Changes | ||
This interface uses promises, and future development plans include an optional stream-based interface | ||
for better performance with large datasets and/or large objects. | ||
Version 3.x is out! This represents a substantial rewrite of the underlying code, which should improve performance | ||
(both CPU and memory use) for almost all RETS calls by using node-expat instead of xml2js for xml parsing. The changes | ||
are mostly internal, however there is 1 small backward-incompatible change needed for correctness, described below. | ||
The large internal refactor plus even a small breaking change warrants a major version bump. | ||
Many of the metadata methods are capable of returning multiple sets of data, including (but not limited to) the | ||
getAll* methods. Versions 1.x and 2.x did not handle this properly; version 1.x returned the values from the last set | ||
encountered, and version 2.x returned the values from the first set encountered. Version 3.x always returns all values | ||
encountered, by returning an array of data sets rather than a single one. | ||
In addition to the methods available in 2.x, version 3.0 adds `client.search.stream.searchRets()`, which returns a | ||
text stream of the raw XML result, and `client.search.stream.query()`, which returns a stream of low-level objects | ||
parsed from the XML. (See the [streaming example](#simple-streaming-example) below.) These streams, if used properly, | ||
should result in a much lower memory footprint than their corresponding non-streaming counterparts. | ||
Version 3.x has almost the same interface as 2.x, which is completely different from 1.x. If you wish to continue to | ||
use the 1.x version, you can use the [v1 branch](https://github.com/sbruno81/rets-client/tree/v1). | ||
## Implementation Notes | ||
This interface uses promises, and an optional stream-based interface for better performance with large search results. | ||
Future development will include an optional stream-based interface for large objects. | ||
This library is written primarily in CoffeeScript, but may be used just as easily in a Node app using Javascript or | ||
@@ -28,3 +46,3 @@ CoffeeScript. Promises in this module are provided by [Bluebird](https://github.com/petkaantonov/bluebird). | ||
#### TODO | ||
- create optional streaming interface | ||
- create optional streaming interface for object downloads; when implemented, this will make version 3.1 | ||
- create unit tests -- specifically ones that run off example RETS data rather than requiring access to a real RETS server | ||
@@ -79,5 +97,5 @@ | ||
outputFields(data, ['Version', 'Date']); | ||
for (var dataItem = 0; dataItem < data.results.length; dataItem++) { | ||
for (var dataItem = 0; dataItem < data.results[0].metadata.length; dataItem++) { | ||
console.log("-------- Resource " + dataItem + " --------"); | ||
outputFields(data.results[dataItem], ['ResourceID', 'StandardName', 'VisibleName', 'ObjectVersion']); | ||
outputFields(data.results[0].metadata[dataItem], ['ResourceID', 'StandardName', 'VisibleName', 'ObjectVersion']); | ||
} | ||
@@ -92,5 +110,5 @@ }).then(function () { | ||
outputFields(data, ['Version', 'Date', 'Resource']); | ||
for (var classItem = 0; classItem < data.results.length; classItem++) { | ||
for (var classItem = 0; classItem < data.results[0].metadata.length; classItem++) { | ||
console.log("-------- Table " + classItem + " --------"); | ||
outputFields(data.results[classItem], ['ClassName', 'StandardName', 'VisibleName', 'TableVersion']); | ||
outputFields(data.results[0].metadata[classItem], ['ClassName', 'StandardName', 'VisibleName', 'TableVersion']); | ||
} | ||
@@ -105,7 +123,7 @@ }).then(function () { | ||
outputFields(data, ['Version', 'Date', 'Resource', 'Class']); | ||
for (var tableItem = 0; tableItem < data.results.length; tableItem++) { | ||
for (var tableItem = 0; tableItem < data.results[0].metadata.length; tableItem++) { | ||
console.log("-------- Field " + tableItem + " --------"); | ||
outputFields(data.results[tableItem], ['MetadataEntryID', 'SystemName', 'ShortName', 'LongName', 'DataType']); | ||
outputFields(data.results[0].metadata[tableItem], ['MetadataEntryID', 'SystemName', 'ShortName', 'LongName', 'DataType']); | ||
} | ||
return data.results | ||
return data.results[0].metadata | ||
}).then(function (fieldsData) { | ||
@@ -119,3 +137,3 @@ var plucked = []; | ||
//perform a query using DQML2 -- pass resource, class, and query, and options | ||
return client.search.query("OpenHouse", "OPENHOUSE", "(OpenHouseType=PUBLIC),(ActiveYN=1)", {limit:100, offset:1}) | ||
return client.search.query("OpenHouse", "OPENHOUSE", "(OpenHouseType=PUBLIC),(ActiveYN=1)", {limit:100, offset:10}) | ||
.then(function (searchData) { | ||
@@ -153,2 +171,45 @@ console.log("==========================================="); | ||
}); | ||
``` | ||
``` | ||
#### Simple streaming example | ||
```javascript | ||
var rets = require('rets-client'); | ||
var through2 = require('through2'); | ||
var Promise = require('bluebird'); | ||
// establish connection to RETS server which auto-logs out when we're done | ||
rets.getAutoLogoutClient(clientSettings, function (client) { | ||
// in order to have the auto-logout function work properly, we need to make a promise that either rejects or | ||
// resolves only once we're done processing the stream | ||
return new Promise(function (reject, resolve) { | ||
var retsStream = client.search.stream.query("OpenHouse", "OPENHOUSE", "(OpenHouseType=PUBLIC),(ActiveYN=1)", {limit:100, offset:10}); | ||
var processorStream = through2.obj(function (event, encoding, callback) { | ||
switch (event.type) { | ||
case 'data': | ||
// event.payload is an object representing a single row of results | ||
// make sure callback is called only when all processing is complete | ||
doAsyncProcessing(event.payload, callback); | ||
break; | ||
case 'done': | ||
// event.payload is an object containing a count of rows actually received, plus some other things | ||
// now we can resolve the auto-logout promise | ||
resolve(event.payload.rowsReceived); | ||
callback(); | ||
break; | ||
case 'error': | ||
// event.payload is an Error object | ||
console.log('Error streaming RETS results: '+event.payload); | ||
retsStream.unpipe(processorStream); | ||
processorStream.end(); | ||
// we need to reject the auto-logout promise | ||
reject(event.payload); | ||
callback(); | ||
break; | ||
default: | ||
// ignore other events | ||
callback(); | ||
} | ||
}); | ||
retsStream.pipe(processorStream); | ||
}); | ||
}); | ||
``` |
Sorry, the diff of this file is not supported yet
Trivial Package
Supply chain riskPackages less than 10 lines of code are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.
Found 1 instance in 1 package
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
48451
39.18%21
61.54%0
-100%0
-100%209
42.18%10
11.11%6
-80.65%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed