Skip to content

Commit a8b681d

Browse files
committed
Updated dependencies, implemented #6, v0.3.3.
1 parent f04b981 commit a8b681d

File tree

4 files changed

+132
-78
lines changed

4 files changed

+132
-78
lines changed

openeo.js

+99-56
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class OpenEO {
1515
var connection = new Connection(url);
1616
return connection.capabilities().then(capabilities => {
1717
// Check whether back-end is accessible and supports a correct version.
18-
if (capabilities.version().startsWith("0.3")) {
18+
if (capabilities.version().startsWith("0.3.")) {
1919
if(authType !== null) {
2020
switch(authType) {
2121
case 'basic':
@@ -35,7 +35,7 @@ class OpenEO {
3535
}
3636

3737
version() {
38-
return "0.3.2";
38+
return "0.3.3";
3939
}
4040
}
4141

@@ -113,22 +113,12 @@ class Connection {
113113
return Promise.reject(new Error("Not implemented yet."));
114114
}
115115

116-
_base64encode(str) {
117-
var buffer;
118-
if (str instanceof Buffer) {
119-
buffer = str;
120-
} else {
121-
buffer = Buffer.from(str.toString(), 'binary');
122-
}
123-
return buffer.toString('base64');
124-
}
125-
126116
authenticateBasic(username, password) {
127117
return this._send({
128118
method: 'get',
129119
responseType: 'json',
130120
url: '/credentials/basic',
131-
headers: {'Authorization': 'Basic ' + this._base64encode(username + ':' + password)} // btoa is JS's ugly name for encodeBase64
121+
headers: {'Authorization': 'Basic ' + Util.base64encode(username + ':' + password)}
132122
}).then(response => {
133123
if (!response.data.user_id) {
134124
throw new Error("No user_id returned.");
@@ -403,41 +393,6 @@ class Connection {
403393
unsubscribe(topic, parameters, callback) {
404394
return this.subscriptionsObject.unsubscribe(topic, parameters, callback);
405395
}
406-
407-
_saveToFileNode(data, filename) {
408-
var fs = require('fs');
409-
return new Promise((resolve, reject) => {
410-
var writeStream = fs.createWriteStream(filename);
411-
writeStream.on('close', (err) => {
412-
if (err) {
413-
return reject(err);
414-
}
415-
resolve();
416-
});
417-
data.pipe(writeStream);
418-
});
419-
}
420-
421-
/* istanbul ignore next */
422-
_saveToFileBrowser(data, filename) {
423-
// based on: https://github.com/kennethjiang/js-file-download/blob/master/file-download.js
424-
var blob = new Blob([data], {type: 'application/octet-stream'});
425-
var blobURL = window.URL.createObjectURL(blob);
426-
var tempLink = document.createElement('a');
427-
tempLink.style.display = 'none';
428-
tempLink.href = blobURL;
429-
tempLink.setAttribute('download', filename);
430-
431-
if (typeof tempLink.download === 'undefined') {
432-
tempLink.setAttribute('target', '_blank');
433-
}
434-
435-
document.body.appendChild(tempLink);
436-
tempLink.click();
437-
document.body.removeChild(tempLink);
438-
window.URL.revokeObjectURL(blobURL);
439-
return Promise.resolve();
440-
}
441396
}
442397

443398

@@ -461,7 +416,7 @@ class Subscriptions {
461416
if(!this.listeners.has(topic)) {
462417
this.listeners.set(topic, new Map());
463418
}
464-
this.listeners.get(topic).set(JSON.stringify(parameters), callback);
419+
this.listeners.get(topic).set(Util.hash(parameters), callback);
465420
}
466421

467422
this._sendSubscription('subscribe', topic, parameters);
@@ -477,7 +432,7 @@ class Subscriptions {
477432

478433
// remove the applicable sub-callback
479434
if(topicListeners instanceof Map) {
480-
topicListeners.delete(JSON.stringify(parameters));
435+
topicListeners.delete(Util.hash(parameters));
481436
} else {
482437
return Promise.reject(new Error("this.listeners must be a Map of Maps"));
483438
}
@@ -539,8 +494,8 @@ class Subscriptions {
539494
var callback;
540495
// we should now have a Map in which to look for the correct listener
541496
if (topicListeners && topicListeners instanceof Map) {
542-
callback = topicListeners.get('{}') // default: without parameters
543-
|| topicListeners.get('{"job_id":"' + json.payload.job_id + '"}');
497+
callback = topicListeners.get(Util.hash({})) // default: without parameters
498+
|| topicListeners.get(Util.hash({job_id: json.payload.job_id}));
544499
// more parameter checks possible
545500
}
546501
// if we now have a function, we can call it with the information
@@ -765,11 +720,11 @@ class File extends BaseEntity {
765720

766721
_saveToFile(data, filename) {
767722
if (isNode) {
768-
return this.connection._saveToFileNode(data, filename);
723+
return Util.saveToFileNode(data, filename);
769724
}
770725
else {
771726
/* istanbul ignore next */
772-
return this.connection._saveToFileBrowser(data, filename);
727+
return Util.saveToFileBrowser(data, filename);
773728
}
774729
}
775730

@@ -901,7 +856,7 @@ class Job extends BaseEntity {
901856
let parsedUrl = url.parse(link);
902857
let targetPath = path.join(targetFolder, path.basename(parsedUrl.pathname));
903858
let p = this.connection.download(link, false)
904-
.then(response => this.connection._saveToFileNode(response.data, targetPath))
859+
.then(response => Util.saveToFileNode(response.data, targetPath))
905860
.then(() => files.push(targetPath));
906861
promises.push(p);
907862
}
@@ -976,9 +931,97 @@ class Service extends BaseEntity {
976931
}
977932
}
978933

934+
class Util {
935+
936+
static base64encode(str) {
937+
if (typeof btoa === 'function') {
938+
// btoa is JS's ugly name for encodeBase64
939+
return btoa(str);
940+
}
941+
else {
942+
var buffer;
943+
if (str instanceof Buffer) {
944+
buffer = str;
945+
} else {
946+
buffer = Buffer.from(str.toString(), 'binary');
947+
}
948+
return buffer.toString('base64');
949+
}
950+
}
951+
952+
// Non-crypthographic / unsafe hashing for objects
953+
static hash(o) {
954+
switch(typeof o) {
955+
case 'boolean':
956+
return Util.hashString("b:" + o.toString());
957+
case 'number':
958+
return Util.hashString("n:" + o.toString());
959+
case 'string':
960+
return Util.hashString("s:" + o);
961+
case 'object':
962+
if (o === null) {
963+
return Util.hashString("n:");
964+
}
965+
else {
966+
return Util.hashString(Object.keys(o).sort().map(k => "o:" + k + ":" + Util.hash(o[k])).join("::"));
967+
}
968+
default:
969+
return Util.hashString(typeof o);
970+
}
971+
}
972+
973+
// See: https://en.wikipedia.org/wiki/Jenkins_hash_function
974+
static hashString(b) {
975+
for(var a=0,c=b.length;c--;) {
976+
a+=b.charCodeAt(c);
977+
a+=a<<10;
978+
a^=a>>6;
979+
}
980+
a+=a<<3;
981+
a^=a>>11;
982+
a+=a<<15;
983+
return ((a&4294967295)>>>0).toString(16);
984+
}
985+
986+
static saveToFileNode(data, filename) {
987+
var fs = require('fs');
988+
return new Promise((resolve, reject) => {
989+
var writeStream = fs.createWriteStream(filename);
990+
writeStream.on('close', (err) => {
991+
if (err) {
992+
return reject(err);
993+
}
994+
resolve();
995+
});
996+
data.pipe(writeStream);
997+
});
998+
}
999+
1000+
/* istanbul ignore next */
1001+
static saveToFileBrowser(data, filename) {
1002+
// based on: https://github.com/kennethjiang/js-file-download/blob/master/file-download.js
1003+
var blob = new Blob([data], {type: 'application/octet-stream'});
1004+
var blobURL = window.URL.createObjectURL(blob);
1005+
var tempLink = document.createElement('a');
1006+
tempLink.style.display = 'none';
1007+
tempLink.href = blobURL;
1008+
tempLink.setAttribute('download', filename);
1009+
1010+
if (typeof tempLink.download === 'undefined') {
1011+
tempLink.setAttribute('target', '_blank');
1012+
}
1013+
1014+
document.body.appendChild(tempLink);
1015+
tempLink.click();
1016+
document.body.removeChild(tempLink);
1017+
window.URL.revokeObjectURL(blobURL);
1018+
return Promise.resolve();
1019+
}
1020+
}
9791021

9801022
let toExport = {
981-
OpenEO: OpenEO
1023+
OpenEO: OpenEO,
1024+
Util: Util
9821025
};
9831026

9841027
// explanation: https://www.matteoagosti.com/blog/2013/02/24/writing-javascript-modules-for-both-browser-and-node/

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openeo/js-client",
3-
"version": "0.3.2",
3+
"version": "0.3.3",
44
"author": "openEO Consortium",
55
"contributors": [
66
{
@@ -22,12 +22,12 @@
2222
},
2323
"main": "openeo.js",
2424
"devDependencies": {
25-
"jest": "^23.5.0",
25+
"jest": "^24.7.1",
2626
"jest-html-reporter": "^2.4.2"
2727
},
2828
"dependencies": {
2929
"axios": "^0.18.0",
30-
"ws": "^6.1.2"
30+
"ws": "^6.2.1"
3131
},
3232
"scripts": {
3333
"test": "jest basic.test.js --env=jsdom",

tests/basic.test.js

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
const { OpenEO } = require('../openeo.js');
1+
const { OpenEO, Util } = require('../openeo.js');
22
const packageInfo = require('../package.json');
33

4-
describe('Basic client tests', () => {
4+
describe('Client Basics', () => {
55
var obj = new OpenEO();
66
test('Check that import worked', () => {
77
expect(obj).not.toBeNull();
@@ -10,4 +10,24 @@ describe('Basic client tests', () => {
1010
test('Check version number', () => {
1111
expect(obj.version()).toBe(packageInfo.version);
1212
});
13+
});
14+
15+
describe('Utils', () => {
16+
test('Base64 encoder', () => {
17+
expect(Util.base64encode(Buffer.from("test"))).toBe("dGVzdA==");
18+
expect(Util.base64encode("test")).toBe("dGVzdA==");
19+
});
20+
test('Base64 encoder', () => {
21+
expect(Util.base64encode(Buffer.from("test"))).toBe("dGVzdA==");
22+
expect(Util.base64encode("test")).toBe("dGVzdA==");
23+
});
24+
test('String hashing', () => {
25+
expect(Util.hashString("a")).toBe("ca2e9442");
26+
});
27+
test('Object hashing', () => {
28+
expect(Util.hash(null)).toBe("40d6be39");
29+
expect(Util.hash(123)).toBe("fd895d50");
30+
expect(Util.hash({a:"b"})).toBe("2a0a2095");
31+
expect(Util.hash([true])).toBe("7f0d24dd");
32+
});
1333
});

tests/earthengine.test.js

+8-17
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ describe('With earth-engine-driver', () => {
165165
});
166166
});
167167

168-
describe('Getting user-specific data', async () => {
168+
describe('Getting user-specific data', () => {
169169
var con;
170170
beforeAll(async (done) => {
171171
con = await connectWithBasicAuth();
@@ -179,7 +179,7 @@ describe('With earth-engine-driver', () => {
179179
});
180180
});
181181

182-
describe('Process graph validation', async () => {
182+
describe('Process graph validation', () => {
183183
var con;
184184
beforeAll(async (done) => {
185185
con = await connectWithBasicAuth();
@@ -206,7 +206,7 @@ describe('With earth-engine-driver', () => {
206206
});
207207
});
208208

209-
describe('Stored process graphs management', async () => {
209+
describe('Stored process graphs management', () => {
210210
var con;
211211
beforeAll(async () => {
212212
con = await connectWithBasicAuth();
@@ -319,7 +319,7 @@ describe('With earth-engine-driver', () => {
319319
});
320320
});
321321

322-
describe('Previews', async () => {
322+
describe('Previews', () => {
323323
var con;
324324
beforeAll(async () => {
325325
con = await connectWithBasicAuth();
@@ -343,7 +343,7 @@ describe('With earth-engine-driver', () => {
343343
});
344344
});
345345

346-
describe('Job management', async () => {
346+
describe('Job management', () => {
347347
var con;
348348
beforeAll(async () => {
349349
con = await connectWithBasicAuth();
@@ -471,7 +471,7 @@ describe('With earth-engine-driver', () => {
471471
});
472472
});
473473

474-
describe('Secondary Services management', async () => {
474+
describe('Secondary Services management', () => {
475475
var con;
476476
beforeAll(async () => {
477477
con = await connectWithBasicAuth();
@@ -526,7 +526,7 @@ describe('With earth-engine-driver', () => {
526526
});
527527
});
528528

529-
describe('File management', async () => {
529+
describe('File management', () => {
530530
var con, f;
531531
var fileContent = "Lorem ipsum";
532532
var fileName = "lorem.txt";
@@ -632,7 +632,7 @@ describe('With earth-engine-driver', () => {
632632
});
633633
});
634634

635-
describe('Subscriptions', async () => {
635+
describe('Subscriptions', () => {
636636
var fileName = 'randomnumber.txt';
637637
var prepareFile = async (f) => {
638638
var content = Math.random().toString(36);
@@ -677,14 +677,5 @@ describe('With earth-engine-driver', () => {
677677
done();
678678
});
679679
});
680-
681-
describe('Other tests', () => {
682-
test('Base64 encoder', async () => {
683-
await connectWithoutAuth().then(con => {
684-
expect(con._base64encode(Buffer.from("test"))).toBe("dGVzdA==");
685-
expect(con._base64encode("test")).toBe("dGVzdA==");
686-
});
687-
});
688-
});
689680

690681
});

0 commit comments

Comments
 (0)