Commit 0e69426d authored by Aurélien Vermylen's avatar Aurélien Vermylen

Merge branch 'nodejs' of https://lab.nexedi.com/aurel/jio into clearroad

Conflicts:
	Gruntfile.js
	src/jio.storage/erp5storage.js
	src/jio.storage/mappingstorage.js
	test/jio.storage/mappingstorage.tests.js
	test/tests.html
parents 63be634c bf8de85a
...@@ -30,6 +30,7 @@ module.exports = function (grunt) { ...@@ -30,6 +30,7 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-open'); grunt.loadNpmTasks('grunt-open');
grunt.loadNpmTasks('grunt-qunitnode');
// Project configuration. // Project configuration.
grunt.initConfig({ grunt.initConfig({
...@@ -68,6 +69,26 @@ module.exports = function (grunt) { ...@@ -68,6 +69,26 @@ module.exports = function (grunt) {
nomen: true nomen: true
} }
}, },
jio_nodejs: {
src: ['src/jio-nodejs.js'],
directives: {
maxlen: 80,
indent: 2,
maxerr: 3,
node: true,
nomen: true
}
},
jio_nodejs_include: {
src: ['src/nodejs/include.js'],
directives: {
maxlen: 80,
indent: 2,
maxerr: 3,
node: true,
nomen: true
}
},
jio_storages: { jio_storages: {
src: ['src/jio.storage/*.js'], src: ['src/jio.storage/*.js'],
directives: { directives: {
...@@ -93,7 +114,7 @@ module.exports = function (grunt) { ...@@ -93,7 +114,7 @@ module.exports = function (grunt) {
predef: [ predef: [
'jIO' 'jIO'
] ]
}, }
}, },
tests: { tests: {
src: ['test/**/*.js'], src: ['test/**/*.js'],
...@@ -106,7 +127,7 @@ module.exports = function (grunt) { ...@@ -106,7 +127,7 @@ module.exports = function (grunt) {
'QUnit', 'QUnit',
'jIO' 'jIO'
] ]
}, }
}, },
queries: { queries: {
src: ['src/queries/*.js'], src: ['src/queries/*.js'],
...@@ -136,8 +157,8 @@ module.exports = function (grunt) { ...@@ -136,8 +157,8 @@ module.exports = function (grunt) {
'QUnit', 'QUnit',
'jIO' 'jIO'
] ]
}, }
}, }
}, },
concat: { concat: {
options: { options: {
...@@ -187,6 +208,34 @@ module.exports = function (grunt) { ...@@ -187,6 +208,34 @@ module.exports = function (grunt) {
], ],
dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js' dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
// dest: 'jio.js' // dest: 'jio.js'
},
nodejs: {
// duplicate files are ignored
src: [
// all the require for nodejs
'src/nodejs/include.js',
'src/nodejs/html5.js',
// queries
'src/queries/parser-begin.js',
'src/queries/build/parser.js',
'src/queries/parser-end.js',
'src/queries/query.js',
'src/jio.date/*.js',
'src/jio-nodejs.js',
'src/jio.storage/replicatestorage.js',
'src/jio.storage/uuidstorage.js',
'src/jio.storage/memorystorage.js',
'src/jio.storage/erp5storage.js',
'src/jio.storage/documentstorage.js',
'src/jio.storage/querystorage.js',
'src/jio.storage/localstorage.js',
'src/jio.storage/mappingstorage.js'
],
dest: 'dist/nodejs/jio.js'
} }
}, },
uglify: { uglify: {
...@@ -231,6 +280,22 @@ module.exports = function (grunt) { ...@@ -231,6 +280,22 @@ module.exports = function (grunt) {
// grunt doesn't like requirejs // grunt doesn't like requirejs
files: ['test/tests.html'] files: ['test/tests.html']
}, },
// test jio with nodejs
qunitnode: {
all: [ "dist/nodejs/jio.js",
"test/jio.storage/memorystorage.tests.js",
"test/jio.storage/replicatestorage.tests.js",
"test/jio.storage/uuidstorage.tests.js",
"test/jio.storage/querystorage.tests.js",
"test/jio.storage/mappingstorage.tests.js",
"test/jio.storage/localstorage.tests.js",
"test/jio.storage/documentstorage.tests.js",
"test/jio.storage/erp5storage.tests.js"
],
options : {
force: true
}
},
watch: { watch: {
src: { src: {
...@@ -245,7 +310,9 @@ module.exports = function (grunt) { ...@@ -245,7 +310,9 @@ module.exports = function (grunt) {
'<%= concat.jio.src %>', '<%= concat.jio.src %>',
'<%= qunit.files %>', '<%= qunit.files %>',
'test/**/*.js', 'test/**/*.js',
'examples/*' 'examples/*',
'src/jio-nodejs.js',
'src/nodejs/*.js'
], ],
tasks: ['default'], tasks: ['default'],
options: { options: {
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
"Sven Franck <sven.franck@nexedi.com>" "Sven Franck <sven.franck@nexedi.com>"
], ],
"description": "Client-side JavaScript library to manage documents across multiple storages", "description": "Client-side JavaScript library to manage documents across multiple storages",
"main": "jio.js", "main": "dist/nodejs/jio.js",
"directories": { "directories": {
"example": "examples", "example": "examples",
"test": "test" "test": "test"
...@@ -32,7 +32,17 @@ ...@@ -32,7 +32,17 @@
"rsvp": "git+https://lab.nexedi.com/nexedi/rsvp.js.git", "rsvp": "git+https://lab.nexedi.com/nexedi/rsvp.js.git",
"uritemplate": "git+https://lab.nexedi.com/nexedi/uritemplate-js.git", "uritemplate": "git+https://lab.nexedi.com/nexedi/uritemplate-js.git",
"moment": "2.13.0", "moment": "2.13.0",
"rusha": "0.8.2" "rusha": "0.8.2",
"urijs": "^1.18.9",
"xhr2": "^0.1.4",
"navigator": "^1.0.1",
"form-data": "^2.1.2",
"atob": "^2.0.3",
"node-localstorage": "^1.3.0",
"btoa": "^1.1.2",
"stream-buffers": "^3.0.1",
"mockdoc": "^0.0.2",
"sinon": "~2.1.0"
}, },
"devDependencies": { "devDependencies": {
"renderjs": "git+https://lab.nexedi.com/nexedi/renderjs.git", "renderjs": "git+https://lab.nexedi.com/nexedi/renderjs.git",
...@@ -47,11 +57,12 @@ ...@@ -47,11 +57,12 @@
"grunt-contrib-watch": "~0.5.3", "grunt-contrib-watch": "~0.5.3",
"grunt-jslint": "~1.0.0", "grunt-jslint": "~1.0.0",
"lz-string": "^1.4.4", "lz-string": "^1.4.4",
"sinon": "~1.7.3", "sinon": "~2.1.0",
"jison": "~0.4.16", "jison": "~0.4.16",
"connect-livereload": "~0.3.0", "connect-livereload": "~0.3.0",
"grunt-open": "~0.2.2", "grunt-open": "~0.2.2",
"grunt-contrib-connect": "~0.5.0" "grunt-contrib-connect": "~0.5.0",
"grunt-qunitnode": "~1.0.0"
}, },
"engines": { "engines": {
"npm": ">=1.3" "npm": ">=1.3"
......
This diff is collapsed.
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
/*jslint nomen: true, unparam: true */ /*jslint nomen: true, unparam: true */
/*global jIO, UriTemplate, FormData, RSVP, URI, Blob, /*global jIO, UriTemplate, FormData, RSVP, URI, Blob,
SimpleQuery, ComplexQuery*/ SimpleQuery, ComplexQuery, btoa*/
(function (jIO, UriTemplate, FormData, RSVP, URI, Blob, (function (jIO, UriTemplate, FormData, RSVP, URI, Blob,
SimpleQuery, ComplexQuery) { SimpleQuery, ComplexQuery) {
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
"type": "GET", "type": "GET",
"url": storage._url, "url": storage._url,
"xhrFields": { "xhrFields": {
withCredentials: true withCredentials: storage._thisCredentials
} },
"headers": storage._headers
}); });
}) })
.push(function (event) { .push(function (event) {
...@@ -50,8 +51,9 @@ ...@@ -50,8 +51,9 @@
view: options._view view: options._view
}), }),
"xhrFields": { "xhrFields": {
withCredentials: true withCredentials: storage._thisCredentials
} },
"headers": storage._headers
}); });
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
...@@ -128,8 +130,8 @@ ...@@ -128,8 +130,8 @@
}); });
} }
function extractPropertyFromForm(context, id) { function extractPropertyFromForm(storage, id) {
return context.getAttachment(id, "view") return storage.getAttachment(id, "view")
.push(function (blob) { .push(function (blob) {
return jIO.util.readBlobAsText(blob); return jIO.util.readBlobAsText(blob);
}) })
...@@ -149,20 +151,17 @@ ...@@ -149,20 +151,17 @@
} }
this._url = spec.url; this._url = spec.url;
this._default_view_reference = spec.default_view_reference; this._default_view_reference = spec.default_view_reference;
this._headers = null;
this._thisCredentials = true;
if (spec.login !== undefined && spec.password !== undefined) {
this._headers = {"Authorization": "Basic "
+ btoa(spec.login + ":" + spec.password)};
this._thisCredentials = false;
}
} }
function convertJSONToGet(json) { function convertJSONToGet(json) {
var key, return json.data;
result = json.data;
// Remove all ERP5 hateoas links / convert them into jIO ID
for (key in result) {
if (result.hasOwnProperty(key)) {
if (!result[key]) {
delete result[key];
}
}
}
return result;
} }
ERP5Storage.prototype.get = function (id) { ERP5Storage.prototype.get = function (id) {
...@@ -173,7 +172,7 @@ ...@@ -173,7 +172,7 @@
}; };
ERP5Storage.prototype.post = function (data) { ERP5Storage.prototype.post = function (data) {
var context = this, var storage = this,
new_id; new_id;
return getSiteDocument(this) return getSiteDocument(this)
...@@ -186,15 +185,16 @@ ...@@ -186,15 +185,16 @@
url: site_hal._actions.add.href, url: site_hal._actions.add.href,
data: form_data, data: form_data,
xhrFields: { xhrFields: {
withCredentials: true withCredentials: storage._thisCredentials
} },
"headers": storage._headers
}); });
}) })
.push(function (evt) { .push(function (evt) {
var location = evt.target.getResponseHeader("X-Location"), var location = evt.target.getResponseHeader("X-Location"),
uri = new URI(location); uri = new URI(location);
new_id = uri.segment(2); new_id = uri.segment(2);
return context.put(new_id, data); return storage.put(new_id, data);
}) })
.push(function () { .push(function () {
return new_id; return new_id;
...@@ -202,9 +202,9 @@ ...@@ -202,9 +202,9 @@
}; };
ERP5Storage.prototype.put = function (id, data) { ERP5Storage.prototype.put = function (id, data) {
var context = this; var storage = this;
return extractPropertyFromForm(context, id) return extractPropertyFromForm(storage, id)
.push(function (result) { .push(function (result) {
var key, var key,
json = result.form_data, json = result.form_data,
...@@ -237,7 +237,7 @@ ...@@ -237,7 +237,7 @@
403 403
); );
} }
return context.putAttachment( return storage.putAttachment(
id, id,
result.action_href, result.action_href,
new Blob([JSON.stringify(form_data)], {type: "application/json"}) new Blob([JSON.stringify(form_data)], {type: "application/json"})
...@@ -246,10 +246,10 @@ ...@@ -246,10 +246,10 @@
}; };
ERP5Storage.prototype.allAttachments = function (id) { ERP5Storage.prototype.allAttachments = function (id) {
var context = this; var storage = this;
return getDocumentAndHateoas(this, id) return getDocumentAndHateoas(this, id)
.push(function () { .push(function () {
if (context._default_view_reference === undefined) { if (storage._default_view_reference === undefined) {
return { return {
links: {} links: {}
}; };
...@@ -262,6 +262,7 @@ ...@@ -262,6 +262,7 @@
}; };
ERP5Storage.prototype.getAttachment = function (id, action, options) { ERP5Storage.prototype.getAttachment = function (id, action, options) {
var storage = this;
if (options === undefined) { if (options === undefined) {
options = {}; options = {};
} }
...@@ -308,8 +309,9 @@ ...@@ -308,8 +309,9 @@
"dataType": "blob", "dataType": "blob",
"url": action, "url": action,
"xhrFields": { "xhrFields": {
withCredentials: true withCredentials: storage._thisCredentials
} },
"headers": storage._headers
}; };
if (options.start !== undefined || options.end !== undefined) { if (options.start !== undefined || options.end !== undefined) {
start = options.start || 0; start = options.start || 0;
...@@ -329,7 +331,11 @@ ...@@ -329,7 +331,11 @@
} }
range = "bytes=" + start + "-" + end; range = "bytes=" + start + "-" + end;
} }
request_options.headers = {Range: range}; if (storage._headers === undefined) {
request_options.headers = {Range: range};
} else {
request_options.headers.Range = range;
}
} }
return jIO.util.ajax(request_options); return jIO.util.ajax(request_options);
}) })
...@@ -348,6 +354,7 @@ ...@@ -348,6 +354,7 @@
}; };
ERP5Storage.prototype.putAttachment = function (id, name, blob) { ERP5Storage.prototype.putAttachment = function (id, name, blob) {
var storage = this;
// Assert we use a callable on a document from the ERP5 site // Assert we use a callable on a document from the ERP5 site
if (name.indexOf(this._url) !== 0) { if (name.indexOf(this._url) !== 0) {
throw new jIO.util.jIOError("Can not store outside ERP5: " + throw new jIO.util.jIOError("Can not store outside ERP5: " +
...@@ -389,8 +396,9 @@ ...@@ -389,8 +396,9 @@
"data": data, "data": data,
"dataType": "blob", "dataType": "blob",
"xhrFields": { "xhrFields": {
withCredentials: true withCredentials: storage._thisCredentials
} },
"headers": storage._headers
}); });
}); });
}; };
...@@ -439,6 +447,7 @@ ...@@ -439,6 +447,7 @@
// jIO.Query.objectToSearchText(options.query) : // jIO.Query.objectToSearchText(options.query) :
// undefined); // undefined);
// } // }
var storage = this;
return getSiteDocument(this) return getSiteDocument(this)
.push(function (site_hal) { .push(function (site_hal) {
var query = options.query, var query = options.query,
...@@ -507,8 +516,9 @@ ...@@ -507,8 +516,9 @@
local_roles: local_roles local_roles: local_roles
}), }),
"xhrFields": { "xhrFields": {
withCredentials: true withCredentials: storage._thisCredentials
} },
"headers": storage._headers
}); });
}) })
.push(function (response) { .push(function (response) {
......
(function (env) {
"use strict";
var process = require("process");
env._html5_weakmap = new WeakMap();
function EventTarget() { env._html5_weakmap.set(this, Object.create(null)); }
EventTarget.prototype.addEventListener = function (type, listener) {
if (typeof listener !== "function") return;
var em = env._html5_weakmap.get(this);
type = "" + type;
if (em[type]) em[type].push(listener);
else em[type] = [listener];
};
EventTarget.prototype.removeEventListener = function (type, listener) {
if (typeof listener !== "function") return;
var em = env._html5_weakmap.get(this);
var i = 0, listeners = em[type];
type = "" + type;
if (listeners) for (; i < listeners.length; ++i) if (listeners[i] === listener) {
if (listeners.length === 1) { delete em[type]; return; }
listeners.splice(i, 1);
return;
}
};
EventTarget.prototype.dispatchEvent = function (event) {
var type = "" + event.type,
em = env._html5_weakmap.get(this),
ontype = "on" + type;
var i = 0, listeners;
if (typeof this[ontype] === "function") {
try { this[ontype](event); } catch (ignore) {}
}
if (listeners = em[type]) for (; i < listeners.length; ++i) {
try { listeners[i](event); } catch (ignore) {}
}
};
env.EventTarget = EventTarget;
function Blob(blobParts, options) {
// https://developer.mozilla.org/en-US/docs/Web/API/Blob
var i = 0; var priv = {}, buffers = [];
env._html5_weakmap.set(this, priv);
for (; i < blobParts.length; ++i) {
if (Buffer.isBuffer(blobParts[i])) {
buffers.push(blobParts[i]);
} else if (blobParts[i] instanceof Blob) {
buffers.push(env._html5_weakmap.get(blobParts[i]).data);
} else if (blobParts[i] instanceof ArrayBuffer) {
buffers.push(new Buffer(new Uint8Array(blobParts[i])));
} else {
buffers.push(new Buffer("" + blobParts[i]));
}
}
priv.data = Buffer.concat(buffers);
Object.defineProperty(this, "size", {enumerable: true, value: priv.data.length});
Object.defineProperty(this, "type", {enumerable: true, value: options ? "" + (options.type || "") : ""});
}
Blob.prototype.size = 0;
Blob.prototype.type = "";
Blob.prototype.slice = function (start, end, contentType) {
return new Blob([env._html5_weakmap.get(this).data.slice(start, end)], {type: contentType});
};
env.Blob = Blob;
function FileReader() { EventTarget.call(this); }
FileReader.prototype = Object.create(EventTarget.prototype);
Object.defineProperty(FileReader, "constructor", {value: FileReader});
FileReader.prototype.readAsText = function (blob) {
var priv = env._html5_weakmap.get(blob);
var text = priv.data.toString();
var event = Object.freeze({type: "load", target: this});
process.nextTick(() => {
this.result = text;
this.dispatchEvent(event);
});
};
FileReader.prototype.readAsArrayBuffer = function (blob) {
var priv = env._html5_weakmap.get(blob);
var arrayBuffer = new Uint8Array(priv.data).buffer;
var event = Object.freeze({type: "load", target: this});
process.nextTick(() => {
this.result = arrayBuffer;
this.dispatchEvent(event);
});
};
FileReader.prototype.readAsDataURL = function (blob) {
var priv = env._html5_weakmap.get(blob);
var dataUrl = "data:" + blob.type + ";base64," + priv.data.toString("base64");
var event = Object.freeze({type: "load", target: this});
process.nextTick(() => {
this.result = dataUrl;
this.dispatchEvent(event);
});
};
env.FileReader = FileReader;
}(global));
/*global global, require */
global.URI = require("urijs");
global.RSVP = require('rsvp');
global.UriTemplate = require("uritemplate");
global.moment = require('moment');
global.navigator = require('navigator');
global.Rusha = require('rusha');
global.FormData = require('form-data');
global.atob = require('atob');
var LocalStorage = require('node-localstorage').LocalStorage;
global.localStorage = new LocalStorage("jio");
global.btoa = require('btoa');
global.XMLHttpRequest = require('xhr2');
var Mockdoc = require("mockdoc");
global.document = new Mockdoc();
global.sinon = require('sinon');
global.StreamBuffers = require('stream-buffers');
global.window = global;
global.sessionStorage = {};
global.HTMLCanvasElement = {};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment