diff --git a/.npmignore b/.npmignore index 75f0756b..a6ba8a7e 100644 --- a/.npmignore +++ b/.npmignore @@ -4,3 +4,4 @@ test .* tslint.json *.log +examples diff --git a/examples/customWebResource/README.md b/examples/customWebResource/README.md new file mode 100644 index 00000000..7cdb6d84 --- /dev/null +++ b/examples/customWebResource/README.md @@ -0,0 +1,21 @@ +# Custom Web Resource + +This is an example to show how to make a simple custom resource base on the web. It gets a web content as its own content. + +The folder `ts` and the folder `js` are the same thing. The `js` folder display the example in JavaScript while the `ts` display the example in TypeScript. + +## Usage + +### Execute + +```bash +node index.js +``` + +### Tests + +```bash +npm tst +``` + + diff --git a/examples/customWebResource/index.js b/examples/customWebResource/index.js new file mode 100644 index 00000000..349dc2c5 --- /dev/null +++ b/examples/customWebResource/index.js @@ -0,0 +1,18 @@ +const webFile = require('./js/resource.js'), + webdav = require('webdav-server'); + +const server = new webdav.WebDAVServer({ + port: 1900 +}); + +server.addResourceTree([ + new webFile.WebFile('http://unlicense.org/UNLICENSE', 'license.txt'), + new webFile.WebFile('https://github.com/OpenMarshal/npm-WebDAV-Server', 'webdav-server-github.html'), + new webFile.WebFile('http://www.stuffedcupcakes.com/wp-content/uploads/2013/05/Chocolate-Overload.jpg', 'chocolate.jpg') +], (e) => { + if(e) throw e; + + server.start((s) => { + console.log('Server started on port ' + s.address().port + '.'); + }); +}); diff --git a/examples/customWebResource/js/fsManager.js b/examples/customWebResource/js/fsManager.js new file mode 100644 index 00000000..c68e5eb3 --- /dev/null +++ b/examples/customWebResource/js/fsManager.js @@ -0,0 +1,34 @@ +const webdav = require('webdav-server'), + webFile = require('./resource.js'); + +module.exports.WebFSManager = function() +{ + const fsManager = { }; + fsManager.uid = 'WebFSManager_1.0.0'; + + fsManager.serialize = function(resource, obj) + { + return { + dateCreation: resource.dateCreation, + dateLastModified: resource.dateLastModified, + properties: resource.properties, + webUrl: resource.webUrl, + fileName: resource.fileName, + refreshTimeoutMS: resource.refreshTimeoutMS + }; + } + + fsManager.unserialize = function(data, obj) + { + const rs = new webFile.WebFile(data.webUrl, data.fileName, data.refreshTimeoutMS); + rs.dateCreation = data.dateCreation; + rs.dateLastModified = data.dateLastModified; + rs.properties = data.properties; + return rs; + } + + fsManager.newResource = function(fullPath, name, type, parent) + { + throw webdav.Errors.InvalidOperation; + } +} diff --git a/examples/customWebResource/js/resource.js b/examples/customWebResource/js/resource.js new file mode 100644 index 00000000..231d442d --- /dev/null +++ b/examples/customWebResource/js/resource.js @@ -0,0 +1,105 @@ +"use strict"; +const webdav = require('webdav-server'), + request = require('request'), + webFSManager = require('./fsManager.js'); + +module.exports.WebFile = function(webUrl, fileName, refreshTimeoutMs = 10000) +{ + const stdRes = new webdav.StandardResource(null, new webFSManager.WebFSManager()); + + stdRes.refreshTimeoutMs = refreshTimeoutMs; + stdRes.lenUpdateTime = 0; + stdRes.fileName = fileName; + stdRes.webUrl = webUrl; + stdRes.len = -1; + + stdRes.openReadStream = function() + { + let size = 0; + const stream = request.get(this.webUrl); + stream.on('data', (chunk) => { + size = chunk.length; + }) + stream.on('end', () => { + this.len = size; + this.lenUpdateTime = Date.now(); + }) + stream.end(); + return stream; + }; + + stdRes.create = function(callback) + { + callback(); + }; + + stdRes.delete = function(callback) + { + webdav.StandardResource.standardRemoveFromParent(this, callback); + } + + stdRes.moveTo = function(parent, newName, overwrite, callback) + { + webdav.StandardResource.standardMoveTo(this, parent, newName, overwrite, callback); + } + + stdRes.rename = function(newName, callback) + { + const oldname = this.fileName; + this.fileName = newName; + callback(null, oldname, newName); + } + + stdRes.write = function(targetSource, callback) + { + callback(webdav.Errors.InvalidOperation); + } + + stdRes.read = function(targetSource, callback) + { + callback(null, this.openReadStream()); + } + + stdRes.mimeType = function(targetSource, callback) + { + webdav.StandardResource.standardMimeType(this, targetSource, callback); + } + + stdRes.size = function(targetSource, callback) + { + if(this.len >= 0 && Date.now() - this.lenUpdateTime < this.refreshTimeoutMs) + { + callback(null, this.len); + return; + } + + const stream = this.openReadStream(); + stream.on('end', () => callback(null, this.len)); + } + + stdRes.webName = function(callback) + { + callback(null, this.fileName); + } + + stdRes.type = function(callback) + { + callback(null, webdav.ResourceType.File); + } + + stdRes.addChild = function(resource, callback) + { + callback(webdav.Errors.InvalidOperation); + } + stdRes.removeChild = function(resource, callback) + { + callback(webdav.Errors.InvalidOperation); + } + stdRes.getChildren = function(callback) + { + callback(webdav.Errors.InvalidOperation); + } + + + return stdRes; +} diff --git a/examples/customWebResource/package.json b/examples/customWebResource/package.json new file mode 100644 index 00000000..b6ae3b78 --- /dev/null +++ b/examples/customWebResource/package.json @@ -0,0 +1,14 @@ +{ + "name": "customwebresource", + "version": "1.0.0", + "description": "Example to show how to make a simple custom resource base on the web. It gets a web content as its own content.", + "main": "index.js", + "scripts": { + "test": "node test.js" + }, + "author": "Adrien Castex ", + "license": "Unlicense", + "dependencies": { + "webdav-server": "^1.8.0" + } +} diff --git a/examples/customWebResource/test.js b/examples/customWebResource/test.js new file mode 100644 index 00000000..f2c4d63b --- /dev/null +++ b/examples/customWebResource/test.js @@ -0,0 +1,32 @@ +const webFile = require('./js/resource.js'), + webdav = require('webdav-server'); + +new webdav.ResourceTester({ + canHaveVirtualFolderChildren: false, + canHaveVirtualFileChildren: false, + canGetLastModifiedDate: true, + canGetCreationDate: true, + canRemoveChildren: false, + canHaveChildren: false, + canGetChildren: false, + canGetMimeType: true, + canBeCreated: true, + canBeDeleted: true, + canBeRenamed: true, + canGetSize: true, + canBeMoved: true, + canWrite: false, + canRead: true, + canLock: true +}, + // For each battery of tests, create the resource to test + // willCreate : A value of true means you must not call the '.create(...)' method because it will be tested + (willCreate, cb) => cb(new webFile.WebFile('http://unlicense.org/UNLICENSE', 'test.txt')) +).run((results) => { + + // Display the results of the tests + console.log(results.all.isValid ? 'Tests passed!' : 'Tests failed!'); + if(results.all.errors) + for(const value of results.all.errors) + console.log(value.toString()); +}); diff --git a/examples/customWebResource/ts/FSManager.ts b/examples/customWebResource/ts/FSManager.ts new file mode 100644 index 00000000..719c4fe5 --- /dev/null +++ b/examples/customWebResource/ts/FSManager.ts @@ -0,0 +1,33 @@ +import { SerializedObject, FSManager, Errors, IResource, ResourceType } from 'webdav-server' +import { WebFile } from './Resource' + +export class WebFSManager implements FSManager +{ + uid : string = 'WebFSManager_1.0.0'; + + serialize(resource : any, obj : SerializedObject) : object + { + return { + dateCreation: resource.dateCreation, + dateLastModified: resource.dateLastModified, + properties: resource.properties, + webUrl: resource.webUrl, + fileName: resource.fileName, + refreshTimeoutMS: resource.refreshTimeoutMS + }; + } + + unserialize(data : any, obj : SerializedObject) : IResource + { + const rs = new WebFile(data.webUrl, data.fileName, data.refreshTimeoutMS); + rs.dateCreation = data.dateCreation; + rs.dateLastModified = data.dateLastModified; + rs.properties = data.properties; + return rs; + } + + newResource(fullPath : string, name : string, type : ResourceType, parent : IResource) : IResource + { + throw Errors.InvalidOperation; + } +} diff --git a/examples/customWebResource/ts/Resource.ts b/examples/customWebResource/ts/Resource.ts new file mode 100644 index 00000000..7d6fd313 --- /dev/null +++ b/examples/customWebResource/ts/Resource.ts @@ -0,0 +1,109 @@ +import * as webdav from 'webdav-server' +import * as request from 'request' + +export class WebFile extends webdav.StandardResource +{ + fileName : string + webUrl : string + len : number + lenUpdateTime : number + refreshTimeoutMs : number + + constructor(webUrl : string, fileName : string, refreshTimeoutMs : number = 10000) + { + super(null, null); + + this.refreshTimeoutMs = refreshTimeoutMs; + this.lenUpdateTime = 0; + this.fileName = fileName; + this.webUrl = webUrl; + this.len = -1; + } + + openReadStream() + { + let size = 0; + const stream = request.get(this.webUrl); + stream.on('data', (chunk) => { + size = chunk.length; + }) + stream.on('end', () => { + this.len = size; + this.lenUpdateTime = Date.now(); + }) + stream.end(); + return stream; + } + + create(callback) + { + callback(); + } + + delete(callback) + { + webdav.StandardResource.standardRemoveFromParent(this, callback); + } + + moveTo(parent, newName, overwrite, callback) + { + webdav.StandardResource.standardMoveTo(this, parent, newName, overwrite, callback); + } + + rename(newName, callback) + { + const oldname = this.fileName; + this.fileName = newName; + callback(null, oldname, newName); + } + + write(targetSource, callback) + { + callback(webdav.Errors.InvalidOperation); + } + + read(targetSource, callback) + { + callback(null, this.openReadStream()); + } + + mimeType(targetSource, callback) + { + webdav.StandardResource.standardMimeType(this, targetSource, callback); + } + + size(targetSource, callback) + { + if(this.len >= 0 && Date.now() - this.lenUpdateTime < this.refreshTimeoutMs) + { + callback(null, this.len); + return; + } + + const stream = this.openReadStream(); + stream.on('end', () => callback(null, this.len)); + } + + webName(callback) + { + callback(null, this.fileName); + } + + type(callback) + { + callback(null, webdav.ResourceType.File); + } + + addChild(resource, callback) + { + callback(webdav.Errors.InvalidOperation); + } + removeChild(resource, callback) + { + callback(webdav.Errors.InvalidOperation); + } + getChildren(callback) + { + callback(webdav.Errors.InvalidOperation); + } +}