Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 6 additions & 31 deletions src/browserFS.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,28 +137,12 @@ async postContainer(pathname,options){
}

/*
deleteResource(pathname,options)
* deletes a resource with links
deleteFile(pathname,options)
* deletes a fle
* on success, returns [200,undefined,optionalHeader]
* on failure, returns [500,undefined,optionalHeader]
*/
async deleteResource(pathname,options){
const folderLinks = pathname.endsWith('/') ? pathname : _getParent(pathname)
let files = await this.getContainer(folderLinks,options)
let fileName = pathname.replace(folderLinks, '')
let links = files.filter(file => (file.endsWith(fileName + '.meta') || file.endsWith(fileName + '.acl')))
links = links.map(file => folderLinks + file)
if (links.length) links.map(async link => await this.deleteItem(link,options))
return await this.deleteItem(pathname,options)
}

/*
deleteItem(pathname,options)
* deletes a resource
* on success, returns [200,undefined,optionalHeader]
* on failure, returns [500,undefined,optionalHeader]
*/
async deleteItem(pathname,options){
async deleteFile(pathname,options){
try {
let res = await this.prom(this.fs.unlink,pathname)
if(res && res.code) {
Expand All @@ -168,22 +152,13 @@ async deleteItem(pathname,options){
}
catch(e){ console.warn(e); return Promise.resolve( [500] ) }
}

/*
deleteContainer(pathname,options)
* if container is not empty, returns [409,undefined,optionalHeader]
* else deletes container
deleteDir(pathname,options)
* deletes a folder
* on success, returns [200,undefined,optionalHeader]
* on failure, returns [500,undefined,optionalHeader]
*/
async deleteContainer(pathname){
let files = await this.getContainer(pathname)
let links = files.filter(file => (file.endsWith('.meta') || file.endsWith('.acl')))
links = links.map(file => pathname + file)
files = files.filter(file => (!file.endsWith('.meta') && !file.endsWith('.acl')))
if( files.length ){ return Promise.resolve( [409] ) }
if (links.length) links.map(async link => await this.deleteItem(link))
return this.deleteDir(pathname)
}
async deleteDir(pathname,options){
try {
let res = await this.prom(this.fs.rmdir,pathname)
Expand Down
20 changes: 1 addition & 19 deletions src/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,32 +118,14 @@ async putResource(pathname,options){
}
})
}
async deleteResource (pathname, options) {
const folderLinks = pathname.endsWith('/') ? pathname : getParent(pathname)
let files = await this.getContainer(folderLinks,options)
let fileName = pathname.replace(folderLinks, '')
let links = files.filter(file => (file.endsWith(fileName + '.meta') || file.endsWith(fileName + '.acl')))
links = links.map(file => folderLinks + file)
if (links.length) links.map(async link => await this.deleteItem(link,options))
return await this.deleteItem(pathname,options)
}
async deleteItem(fn){
async deleteFile(fn){
return new Promise(function(resolve) {
fs.unlink( fn, function(err) {
if(err) resolve( [409] );
else resolve( [200] );
});
});
}
async deleteContainer(pathname){
let files = await this.getContainer(pathname)
let links = files.filter(file => (file.endsWith('.meta') || file.endsWith('.acl')))
links = links.map(file => pathname + file)
files = files.filter(file => (!file.endsWith('.meta') && !file.endsWith('.acl')))
if( files.length ){ return Promise.resolve( [409] ) }
if (links.length) links.map(async link => await this.deleteItem(link))
return this.deleteDir(pathname)
}

deleteDir(fn) {
return new Promise(function(resolve) {
Expand Down
50 changes: 9 additions & 41 deletions src/localStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,9 @@ async getContainer(pathname,options) {
.filter(path => path.startsWith(pathname) && path != pathname) // Only children
.map(path => path.substr(pathname.length))
.filter(path => !path.slice(0, -1).includes("/")) // Only include direct children
//console.log(files)
return files
}

async getLinks(pathname, options) {
let folderLinks = pathname.endsWith('/') ? pathname : getParent(pathname)
let links = await this.getContainer(folderLinks, options)
links = links.filter(file => (file.endsWith('.meta') || file.endsWith('.acl')))
.map(file => folderLinks + file)
return links
}

dump(pathname,options) {
let keys = Object.keys(localStorage).filter(k=>{
if(!k.match(/(setItem|getItem|removeItem)/)) return k
Expand Down Expand Up @@ -109,49 +100,26 @@ async postContainer(pathname,options){
return this.putResource(pathname,options)
}

/*
deleteResource(pathname,options)
* deletes a resource with links
/**
* deleteFile(pathname, options)
* on success, returns [200,undefined,optionalHeader]
* on failure, returns [500,undefined,optionalHeader]
*/
async deleteResource(pathname,options){
const folderLinks = pathname.endsWith('/') ? pathname : getParent(pathname)
let files = await this.getContainer(folderLinks,options)
let fileName = pathname.replace(folderLinks, '')
let links = files.filter(file => (file.endsWith(fileName + '.meta') || file.endsWith(fileName + '.acl')))
links = links.map(file => folderLinks + file)
if (links.length) links.map(async link => await this.deleteItem(link,options))
return await this.deleteItem(pathname,options)
}

/**
* deleteItem(pathname, options)
* @param {*} pathname
* @param {*} options
*/
async deleteItem(pathname,options){
async deleteFile(pathname,options){
try {
localStorage.removeItem(pathname)
return Promise.resolve( [200] )
}
catch(e){ return Promise.resolve( [500] ) }
}
/*
deleteContainer(pathname,options)
* if container is not empty, returns [409,undefined,optionalHeader]
* else deletes container

/**
* deleteFile(pathname, options)
* on success, returns [200,undefined,optionalHeader]
* on failure, returns [500,undefined,optionalHeader]
*/
async deleteContainer(pathname,options){
let files = await this.getContainer(pathname,options)
let links = files.filter(file => (file.endsWith('.meta') || file.endsWith('.acl')))
links = links.map(file => pathname + file)
files = files.filter(file => (!file.endsWith('.meta') && !file.endsWith('.acl')))
if( files.length ){ return Promise.resolve( [409] ) }
if (links.length) links.map(async link => await this.deleteItem(link,options))
return await this.deleteItem(pathname,options)
*/
async deleteDir (pathname, options) {
return await this.deleteFile(pathname, options)
}

async makeContainers(pathname,options){
Expand Down
44 changes: 41 additions & 3 deletions src/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const libPath = require("path");

const { Response } = require('cross-fetch')
const contentTypeLookup = require('mime-types').contentType

const linkExt = ['.acl', '.meta']
const linksExt = linkExt.concat('.meta.acl')
class SolidRest {

constructor( handlers ) {
Expand Down Expand Up @@ -114,13 +115,13 @@ async fetch(uri, options = {}) {
if( options.method==="DELETE" ){
if(!objectExists) return _response(notFoundMessage, resOptions, 404)
if( objectType==="Container" ){
const [status, , headers] = await self.storage(options).deleteContainer(pathname,options)
const [status, , headers] = await _deleteContainer(pathname,options)
Object.assign(resOptions.headers, headers)

return _response(null, resOptions, status)
}
else if (objectType === 'Resource' ) {
const [status, , headers] = await self.storage(options).deleteResource(pathname,options)
const [status, , headers] = await _deleteResource(pathname,options)
Object.assign(resOptions.headers, headers)

return _response(null, resOptions, status)
Expand All @@ -145,6 +146,7 @@ async fetch(uri, options = {}) {
return _response(null, resOptions, status)
}
else if( link && link.match("Resource")){
if (isLink(pathname)) return _response(null, resOptions, 403)
const [status, , headers] = await self.storage(options).putResource( pathname, options)
Object.assign(resOptions.headers, headers)

Expand Down Expand Up @@ -235,6 +237,9 @@ async fetch(uri, options = {}) {
return contentTypeLookup(ext)
}
}
function isLink(pathname) {
return linkExt.find(ext => _getExtension(pathname) === ext)
}
/* DEFAULT HEADER
link created using .meta and .acl appended to uri
content-type assigned by mime-types.lookup
Expand Down Expand Up @@ -311,6 +316,39 @@ async fetch(uri, options = {}) {
*/

} // end of getHeaders()
/*
_deleteContainer(pathname,options)
* deletes a container with links
*/
async function _deleteContainer(pathname,options){
let files = await self.storage(options).getContainer(pathname, options)
files = files.filter(file => !isLink(file)) // linkExt.find(ext => _getExtension(file) === ext))
if (files.length) return [409]
const links = await getLinks(pathname, options)
if (links.length) links.map(async link => await self.storage(options).deleteFile(link,options))
return await self.storage(options).deleteDir(pathname,options)
}

/*
_deleteResource(pathname,options)
* deletes a resource with links
*/
async function _deleteResource(pathname,options){
const links = await getLinks(pathname, options)
if (links.length) links.map(async link => await self.storage(options).deleteFile(link,options))
return await self.storage(options).deleteFile(pathname,options)
}

/**
* getLinks for item
* @param {*} pathname
* @param {*} options
*/
async function getLinks (pathname, options) {
let linksExists = linksExt.filter(async ext => await self.storage(options).getObjectType(pathname + ext)[1])
const links = linksExists.map( ext => pathname + ext)
return links
}
} // end of fetch()
} // end of SolidRest()

Expand Down
12 changes: 9 additions & 3 deletions tests/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ async function getConfig(scheme){
let c2name = "deep-folder"
let r1name = "test1.ttl"
let r2name = "test2.ttl"
let meta = '.meta'
let folder1 = base +"/"+ c1name
let folder2 = folder1 + c2name + "/"
let folder2acl = folder2 + '.acl'
let folder2meta = folder2 + meta
let deepR = folder2 +"test-file2.ttl"
let deepRacl = folder2 + "test-file2.ttl.acl"
let file1 = folder1 + r1name
Expand All @@ -64,9 +65,10 @@ async function getConfig(scheme){
c2name : c2name,
r1name : r1name,
r2name : r2name,
meta : meta,
folder1 : folder1,
folder2 : folder2,
folder2acl : folder2acl,
folder2meta : folder2meta,
deepR : deepR,
deepRacl : deepRacl,
file1 : file1,
Expand Down Expand Up @@ -103,6 +105,9 @@ async function run(scheme){
res = await postFolder( cfg.missingFolder,cfg.c2name )
ok( "404 post container, parent not found", res.status==404,res)

res = await postFile( cfg.folder2meta,cfg.meta )
ok( "403 post link resource", res.status==404,res)

res = await postFile( cfg.folder1,cfg.r1name,cfg.text )
ok( "201 post resource", res.status==201,res)

Expand All @@ -124,7 +129,7 @@ async function run(scheme){
res = await PUT( cfg.deepR,cfg.text )
ok("201 put resource, parent not found (recursive creation)",res.status==201)

res = await PUT( cfg.folder2acl,cfg.text )
res = await PUT( cfg.folder2meta,cfg.text )
ok("201 put container acl",res.status==201)

res = await PUT( cfg.deepRacl,cfg.text )
Expand Down Expand Up @@ -153,6 +158,7 @@ async function run(scheme){
res = await DELETE( cfg.base+'dummy.txt' )
res = await DELETE( cfg.file1 )
res = await DELETE( cfg.deepR )
res = await DELETE( cfg.folder2meta)
ok("200 delete resource",res.status==200,res)

if(scheme != "https:"){
Expand Down