Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@solid-rest/core

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@solid-rest/core - npm Package Compare versions

Comparing version 2.1.18 to 2.1.19

10

dist/cjs/examineRequest.js

@@ -7,5 +7,3 @@ "use strict";

exports.getRequest = getRequest;
var _url = require("url");
function getRequest(uri, options) {

@@ -17,3 +15,2 @@ const request = normalizeRequestKeys(options);

request.body = request.body || "";
if (!validUrl(uri)) {

@@ -27,3 +24,2 @@ request.url = null;

}
if (request.url && request.url.endsWith('.dummy')) {

@@ -34,3 +30,2 @@ // rdflib does this !!!

}
return request;

@@ -42,6 +37,4 @@ }

function normalizeRequestKeys(opts) {
let newOpts = {};
for (var o in opts) {

@@ -52,6 +45,4 @@ if (o === 'host') {

}
return newOpts;
}
const validUrl = s => {

@@ -69,5 +60,4 @@ try {

function normalizeRequestMethod(method) {
return method ? method.toUpperCase() : 'GET';
}

15

dist/cjs/examineRequestedItem.js

@@ -7,14 +7,10 @@ "use strict";

exports.getItem = getItem;
var _url = _interopRequireDefault(require("url"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
//import libPath from "path";
//import libPath from "path";
var pathHandler;
async function getItem(uri, request) {
let url, pname;
pathHandler = await this.perform('GET_PATH_HANDLER', uri);
if (uri.startsWith('file')) {

@@ -27,3 +23,2 @@ url = _url.default.format(request.url);

}
const item = await this.perform('GET_ITEM_INFO', pname, request);

@@ -36,3 +31,2 @@ item.mode = item.mode ? item.mode : {

item.pathname = pname;
if (request.method === 'DELETE' && item.isContainer) {

@@ -46,3 +40,2 @@ let files = await this.perform('GET_FILES', item.pathname);

}
this.getExtension = path => {

@@ -53,6 +46,4 @@ path = path || this.item.pathname || "";

};
this.pathSep = pathHandler.sep;
this.basename = pathHandler.extname;
this.mungePath = (pathname, slug, options) => {

@@ -63,3 +54,2 @@ pathname = pathHandler.join(pathname, slug);

};
pname = request.method === "POST" ? this.mungePath(item.pathname, request.slug) : item.pathname;

@@ -70,5 +60,6 @@ item.extension = this.getExtension(pname);

item.isAcl = pname.match(/\.acl/); // TBD use LinkExt
//item.isAuxResource = item.isAcl || this.extension === '.meta';
item.isAuxResource = pname.match(/\.(acl|meta)$/) ? true : false;
item.isAuxResource = pname.match(/\.(acl|meta)$/) ? true : false;
/*

@@ -75,0 +66,0 @@ let conflict

17

dist/cjs/handleRequest.js

@@ -38,9 +38,6 @@ "use strict";

};
async function handleRequest(uri, originalRequest) {
const request = this.requestObj = await this.getRequest(uri, originalRequest); //
const item = this.item = await this.getItem(uri, request); //
// Errors we find in the request
if (!request.url || !request.method) return 400;

@@ -51,11 +48,9 @@ if (request.slug.endsWith('/')) return 400;

if (request.method === 'PATCH' && !this.patch) return 405;
if (request.method === 'POST' && !request.headers.link) return 400; // Errors we find by comparing the request & the itemRequested
if (request.method === 'POST' && !request.headers.link) return 400;
// Errors we find by comparing the request & the itemRequested
if (item.isContainer && !item.contentType) item.contentType = "text/turtle";
if (item.folderFileConfusion) return 400; // can't have both /foo and /foo/
if (item.patchOnNonRdf) return 400;
if (item.mode.write) item.mode.append = true;
const method = methods[request.method];
if (item.isAuxResource) {

@@ -65,3 +60,2 @@ if (item.isAcl) method.requiresControl = true;

}
if (!method) console.log(55, request.method);

@@ -71,3 +65,2 @@ if (!method) return 409;

if (method.requiresRead && !item.mode.read || method.requiresAppend && !item.mode.append || method.requiresWrite && !item.mode.write || method.requiresControl && !item.mode.control) return 401;
if (method.requiresContentType && !request.headers['content-type']) {

@@ -77,3 +70,2 @@ // console.log(request.method, "No Content Type");

}
if (request.method === 'POST') {

@@ -84,3 +76,2 @@ this.item.pathname = await this.generateRandomSlug(this.item.pathname, request.slug);

if (request.method === 'PUT' || request.method === 'POST' || request.method === 'PATCH') {

@@ -91,8 +82,5 @@ // if (item.isContainer) return 405;

}
let response = await this.perform(request.method);
if (!response && request.method === 'DELETE' && item.isContainer) {
let stillExists = await this.perform('ITEM_EXISTS', this.item.pathname);
if (stillExists) {

@@ -102,4 +90,3 @@ return 409;

}
return response;
} // ENDS

@@ -7,7 +7,4 @@ "use strict";

exports.handleResponse = handleResponse;
var _crossFetch = require("cross-fetch");
var _uuid = require("uuid");
/*

@@ -19,2 +16,3 @@ url : file:///foo/bar.txt

//import libPath from 'path';
const statusText = {

@@ -34,6 +32,4 @@ 200: "OK",

};
async function handleResponse(response, originalRequest) {
let wrapHeaders = true; // {headers} instead of headers for Response
let method = originalRequest.method || this.request.method || "GET";

@@ -51,3 +47,2 @@ let finalResponse = {

*/
if (typeof response === 'number') {

@@ -74,22 +69,23 @@ wrapHeaders = false;

if (method.match(/(PUT)/) && finalResponse.headers.status == 200) {
finalResponse.headers.status = 201;
}
if (method.match(/(DELETE|GET|HEAD)/) && finalResponse.headers.status == 201) {
finalResponse.headers.status = 200;
}
let headers = {};
const request = this.requestObj;
const item = this.item;
const pathname = item.pathname; // const fn = libPath.basename(pathname);
const pathname = item.pathname;
// const fn = libPath.basename(pathname);
const fn = pathname.replace(/.*\//, '');
headers['vary'] = 'accept,authorization,origin';
headers['access-control-expose-headers'] = 'accept-patch,accept-post,accept-put,allow,content-range,etag,last-modified,link,location,updates-via,wac-allow,www-authenticate';
headers['content-type'] = this.item.contentType; // CONTENT-TYPE
headers.link = headers.link || createLinkHeader(item); // LINK
const storageHeader = item.pathname === '/' ? ', <http://www.w3.org/ns/pim/space#Storage>; rel="type"' : '';
headers.link = headers.link || createLinkHeader(item) + storageHeader; // LINK
headers.allow = createAllowHeader(this.patch, this.item.mode); // ALLOW
headers.allow = createAllowHeader(item.pathname); // ALLOW

@@ -102,6 +98,6 @@ headers['wac-allow'] = createWacHeader(this.item.mode); // WAC-ALLOW

if (this.response && this.response.headers) headers.location = this.response.headers.location; // NO, DON'T USE LOCATION headers.url = headers.location || pathname ;
if (this.response && this.response.headers) headers.location = this.response.headers.location;
// NO, DON'T USE LOCATION headers.url = headers.location || pathname ;
headers.url = pathname;
if (method === "POST") {

@@ -119,15 +115,14 @@ headers.url = this.request.url;

}
/* if (this.patch) { // ACCEPT-PATCH & MS-AUTHOR-VIA
headers['accept-patch'] = ['text/n3', 'application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
} */
if (this.patch) {
// ACCEPT-PATCH & MS-AUTHOR-VIA
headers['accept-patch'] = ['application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
}
let body = finalResponse.body || this.response.body || ""; // Now we merge headers we created with response headers, prefering response
Object.assign(headers, finalResponse.headers); //alert(finalResponse.headers.status)
Object.assign(headers, finalResponse.headers);
//alert(finalResponse.headers.status)
headers.status = finalResponse.headers.status || this.response.headers.status || 500;
let $rdf = typeof window != "undefined" && window.$rdf ? window.$rdf : typeof global != "undefined" && global.$rdf ? global.$rdf : null;
/*

@@ -158,12 +153,18 @@ async function serialize(uri,body,informat,outformat){

*/
headers.statusText = headers.statusText || statusText[headers.status];
headers = createAcceptHeader(request, headers); // ACCEPT
headers.statusText = headers.statusText || statusText[headers.status];
headers.etag = `W/"${(0, _uuid.v4)()}"`;
headers['content-length'] = typeof Buffer != 'undefined' ? Buffer.byteLength(body, 'utf8') : typeof Blob != "undefined" ? new Blob([body]).size : 77; // Now we create & return the Response object
headers['content-length'] = typeof Buffer != 'undefined' ? Buffer.byteLength(body, 'utf8') : typeof Blob != "undefined" ? new Blob([body]).size : 77;
// TODO (?) last-modified
// Now we create & return the Response object
for (var h of Object.keys(headers)) {
if (!headers[h]) delete headers[h];
}
if (!headers.url.match(/:/)) headers.url = (this.prefix || "file:") + "//" + headers.url;
if (!headers.url.match(/:/)) headers.url = (this.prefix || "file:") + "//" + headers.url; // headers.location = headers.location || headers.url.replace(/^....?:\/\//,'');
// headers.location = headers.location || headers.url.replace(/^....?:\/\//,'');
// if(!headers.location.match(/^file:/)) headers.location = "file://"+headers.location;

@@ -173,3 +174,2 @@

body = "";
for (let k of Object.keys(headers)) {

@@ -179,3 +179,2 @@ body = body + `${k}:${headers[k]}\n`;

}
if (originalRequest.plainResponse) {

@@ -192,3 +191,2 @@ // from a server that wants to munge

}
wrapHeaders = true;

@@ -203,3 +201,2 @@ headers = wrapHeaders ? {

let responseObject;
try {

@@ -212,3 +209,2 @@ responseObject = new _crossFetch.Response(body, headers, {

}
return responseObject;

@@ -218,3 +214,2 @@ } // end of handleResponse method

function createWacHeader(mode) {

@@ -226,7 +221,26 @@ if (!mode.read && !mode.write) return null;

}
function createAllowHeader(patch, mode) {
return 'OPTIONS,HEAD' + (mode.read ? ',GET' : '') + (mode.write ? ',POST,PUT,DELETE' : '') + (mode.write && patch ? ',PATCH' : '');
function createAllowHeader(requestPath) {
// root/ root/.acl can't be deleted
let del = requestPath === '/' || requestPath === '/.acl' ? '' : ',DELETE';
// no PATCH on Container
if (requestPath.endsWith('/')) return 'OPTIONS,HEAD,GET,POST,PUT' + del;
// no POST on Document
else return 'OPTIONS,HEAD,GET,PATCH,PUT' + del;
}
function createAcceptHeader(request, headers) {
const status = headers.status;
// no Accept header
if (request.method.match(/DELETE/) || status >= 500 || status.toString().match(/401|403/)) return headers;
// Accept headers on container
if (request.url.endsWith('/')) {
if (status === 404) headers['accept-put'] = ['*/*'];
headers['accept-post'] = ['*/*'];
} else {
// Accept headers on document
headers['accept-put'] = ['*/*'];
headers['accept-patch'] = ['text/n3', 'application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
}
return headers;
}
function createLinkHeader(item) {

@@ -237,12 +251,13 @@ let isContainer = item.isContainer;

let ext = item.extension;
if (ext === '.acl') // .acl not controlledBy or describedBy anything
if (ext === '.acl')
// .acl not controlledBy or describedBy anything
return `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;else if (ext === '.meta') {
return `<${fn}.acl>; rel="acl",` // .meta controlledBy .meta.acl
+ `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return `<${fn}.acl>; rel="acl"` // .meta controlledBy .meta.acl
+ `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
} else if (isContainer) {
return `<.meta>; rel="describedBy", <.acl>; rel="acl",` + `<http://www.w3.org/ns/ldp#Container>; rel="type",` + `<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"` + `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return `<.meta>; rel="describedBy", <.acl>; rel="acl"` + `, <http://www.w3.org/ns/ldp#Container>; rel="type"` + `, <http://www.w3.org/ns/ldp#BasicContainer>; rel="type"` + `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
} else {
let link = `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl",` + `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
let link = `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl"` + `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return link;
}
} // THE END!

@@ -7,25 +7,14 @@ "use strict";

exports.default = void 0;
var _examineRequest = require("./examineRequest.js");
var _examineRequestedItem = require("./examineRequestedItem.js");
var _handleRequest = require("./handleRequest.js");
var _performRequestedMethod = _interopRequireDefault(require("./performRequestedMethod.js"));
var _handleResponse = require("./handleResponse.js");
var _utils = require("./utils/utils.js");
var _container = _interopRequireDefault(require("./utils/container.js"));
var _restPatch = _interopRequireDefault(require("./utils/rest-patch.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class SolidRest {
constructor(options) {
options = options || {};
if (!options.plugin) {

@@ -35,3 +24,2 @@ console.log(`You must specify a plugin storage handler!`);

}
this.storage = options.plugin;

@@ -54,3 +42,2 @@ this.handleRequest = _handleRequest.handleRequest.bind(this);

}
async fetch(uri, options = {}) {

@@ -60,3 +47,2 @@ let response = await this.handleRequest(uri, options);

}
async login(options) {

@@ -70,21 +56,15 @@ options = {

}
async itemExists(pathname) {
return await this.perform('ITEM_EXISTS', pathname);
}
isPatchConflictError(response) {
if (response === 400) return true;
}
isAccessError(response) {
if (response === 401) return true;
}
/* =========================================================== */
/* REST METHODS */
/* =========================================================== */
async GET(url) {

@@ -95,3 +75,2 @@ return await this.fetch(url, {

}
async HEAD(url) {

@@ -102,3 +81,2 @@ return await this.fetch(url, {

}
async EXISTS(url) {

@@ -114,3 +92,2 @@ try {

}
async PUT(url, text, ctype) {

@@ -126,3 +103,2 @@ ctype = ctype || 'text/turtle';

}
async PATCH(url, patchContent, patchContentType) {

@@ -140,3 +116,2 @@ patchContentType = patchContent || "text/n3";

}
async DELETE(url) {

@@ -147,3 +122,2 @@ return await this.fetch(url, {

}
async POST(parent, item, content, link) {

@@ -160,3 +134,2 @@ return await this.fetch(parent, {

}
async postFile(parent, file, content) {

@@ -166,3 +139,2 @@ let link = '<http://www.w3.org/ns/ldp#Resource>; rel="type"';

}
async postFolder(parent, folder) {

@@ -172,6 +144,3 @@ let link = '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"';

}
} // THE END
exports.default = SolidRest;

@@ -7,3 +7,2 @@ "use strict";

exports.default = perform;
async function perform(method, pathname, content, ctype) {

@@ -20,3 +19,2 @@ this.request = this.requestObj;

};
switch (method) {

@@ -26,3 +24,2 @@ case 'STORAGE_NAME':

break;
case 'ITEM_EXISTS':

@@ -32,7 +29,5 @@ pathname = pathname.replace('file://', '');

break;
case 'LOGIN':
return await this.storage.login(this.request.loginoptions);
break;
case 'ITEM_TYPE':

@@ -42,20 +37,15 @@ // Container/Resource

break;
case 'GET_CONTENT_TYPE':
return await this.storage.getContentType(pathname); // return await this.storage.getContentType(pathname).bind(this.storage);
return await this.storage.getContentType(pathname);
// return await this.storage.getContentType(pathname).bind(this.storage);
break;
case 'GET_PATH_HANDLER':
return await this.storage.getPathHandler(pathname);
break;
case 'GET_ITEM_INFO':
return await this.storage.getItemInfo(pathname, this.request);
break;
case 'GET_FILES':
return await this.storage.getContainer(pathname);
break;
case 'DELETE':

@@ -69,8 +59,5 @@ if (this.item.isContainer) {

}
break;
case 'DELETE_AUX_RESOURCES':
const links = (await this.getAuxResources(pathname)) || [];
try {

@@ -85,18 +72,13 @@ links.map(async link => {

}
return 200;
break;
case 'CREATE_INTERMEDIATE_CONTAINERS':
return (await this.storage.makeContainers(pathname)) || 1;
break;
case 'GET':
if (this.item.isContainer) {
let files = await this.storage.getContainer(pathname);
if (files.headers) {
return files;
}
return await this.containerAsTurtle(pathname, files, this.request.typewanted, this);

@@ -106,7 +88,5 @@ } else {

if (!thing) return false;
if (thing.headers) {
return thing;
}
this.response.body = thing;

@@ -116,5 +96,3 @@ this.response.headers.status = 200;

}
break;
case 'OPTIONS':

@@ -124,7 +102,5 @@ case 'HEAD':

break;
case 'PUT':
content = content || this.request.body;
ctype = ctype || this.item.contentType || ""; // console.log('content for put',content);
let x = await this.storage.putResource(pathname, content, ctype); // console.log('response from put',x);

@@ -135,3 +111,2 @@

break;
case 'FULL_PUT':

@@ -144,3 +119,2 @@ let success = await this.storage.makeContainers(pathname);

break;
case 'POST':

@@ -156,5 +130,3 @@ if (this.request.headers.link.match("Container")) {

}
break;
case 'PATCH':

@@ -172,13 +144,11 @@ const contentType = this.item.contentType;

if (!exists) await this.perform('FULL_PUT', pathname, "", ctype);
; // 415 patchOnNonTurtle is handled already in handleRequest.js
;
// 415 patchOnNonTurtle is handled already in handleRequest.js
let oldContent = await this.storage.getResource(pathname);
oldContent = oldContent && oldContent.body ? oldContent.body : oldContent; // if (!oldContent) return false;
oldContent = oldContent && oldContent.body ? oldContent.body : oldContent;
// if (!oldContent) return false;
oldContent = typeof oldContent === 'string' ? oldContent : oldContent.toString();
let newContent, patchStatus;
try {
[patchStatus, newContent] = await this.patch.patchContent(oldContent, contentType, this.request);
if (patchStatus !== 200) {

@@ -196,7 +166,7 @@ return {

};
} // const status = await this.storage.makeContainers(pathname);
}
// const status = await this.storage.makeContainers(pathname);
// if (!status) return false;
// let putStatus = await this.storage.putResource(pathname, this.request.bod);
let putStatus = await this.storage.putResource(pathname, newContent);

@@ -203,0 +173,0 @@ putStatus = putStatus && putStatus.body ? putStatus.body : putStatus;

@@ -7,11 +7,9 @@ "use strict";

exports.default = containerAsTurtle;
// import libPath from 'path';
// import libPath from 'path';
async function containerAsTurtle(pathname, contentsArray, typeWanted, self) {
const pathSep = self.pathSep;
function basename(path) {
return path.substr(path.lastIndexOf(self.pathSep) + 1);
}
let filenames = contentsArray.filter(item => {

@@ -30,7 +28,6 @@ if (item.path && !item.path.endsWith('.acl') && !item.path.endsWith('.meta')) {

@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
<> a ldp:BasicContainer, ldp:Container
`;
<> a ldp:BasicContainer, ldp:Container`;
if (filenames.length) {
str = str + "; ldp:contains\n";
str = str + ";\n ldp:contains\n"; // alain

@@ -42,3 +39,2 @@ for (var i = 0; i < filenames.length; i++) {

fn = basename(fn); // contained resources are relative to folder
if (filenames[i].isContainer && !fn.endsWith("/")) fn = fn + "/";

@@ -48,3 +44,2 @@ str = str + ` <${fn}>,\n`;

let ctype, size, mtime, modified;
if (self && self.storage.getMetadata) {

@@ -60,19 +55,21 @@ try {

}
} else if (filenames[i].metadata) {
size = filenames[i].metadata.size;
mtime = filenames[i].metadata.mtimeMs;
modified = new Date(mtime).toISOString();
}
ctype = ctype || (await self.getContentType(fn, ftype)) || ""; // REMOVE CHARSET FROM CONTENT-TYPE
ctype = ctype || (await self.getContentType(fn, ftype)) || "";
// REMOVE CHARSET FROM CONTENT-TYPE
ctype = ctype.replace(/;.*/, '');
ftype = filenames[i].isContainer ? "ldp:Container; a ldp:BasicContainer; a ldp:Resource" : "ldp:Resource";
str2 = str2 + `<${fn}> a ${ftype}.\n`;
if (ctype) str2 = str2 + `<${fn}> a <http://www.w3.org/ns/iana/media-types/${ctype}#Resource>.\n`; // str2 = str2 + `<${fn}> :type "${ctype}".\n`
str2 = str2 + `<${fn}> a ${ftype}`;
if (ctype && !filenames[i].isContainer)
// no media-type for Container
str2 = str2 + `, <http://www.w3.org/ns/iana/media-types/${ctype}#Resource>`; // str2 = str2 + `<${fn}> :type "${ctype}".\n`
if (size) {
str2 = str2 + `<${fn}> stat:size ${size}; stat:mtime ${mtime}; dct:"${modified}"^^xsd:dateTime.\n`;
str2 = str2 + `;\n stat:size ${size};\n stat:mtime ${mtime};\n dct:modified "${modified}"^^xsd:dateTime.\n`;
}
}
str = str.replace(/,\n$/, "");
}
str = str + `.\n` + str2; // str = _makeStream(str);

@@ -79,0 +76,0 @@

@@ -6,4 +6,4 @@ "use strict";

});
exports.acl_content = exports.private_content = exports.public_content = exports.prefs_content = exports.profile_content = void 0;
const profile_content = `@prefix : <#>.
exports.public_content = exports.profile_content = exports.private_content = exports.prefs_content = exports.acl_content = void 0;
const profile_content = exports.profile_content = `@prefix : <#>.
@prefix jef: <../>.

@@ -41,4 +41,3 @@ @prefix ldp: <http://www.w3.org/ns/ldp#>.

`;
exports.profile_content = profile_content;
const prefs_content = `@prefix : <#>.
const prefs_content = exports.prefs_content = `@prefix : <#>.
@prefix solid: <http://www.w3.org/ns/solid/terms#>.

@@ -57,4 +56,3 @@ @prefix sp: <http://www.w3.org/ns/pim/space#>.

`;
exports.prefs_content = prefs_content;
const public_content = `@prefix : <#>.
const public_content = exports.public_content = `@prefix : <#>.
@prefix solid: <https://www.w3.org/ns/solid/terms#>.

@@ -72,4 +70,3 @@ @prefix terms: <http://purl.org/dc/terms/>.

`;
exports.public_content = public_content;
const private_content = `
const private_content = exports.private_content = `
@prefix solid: <https://www.w3.org/ns/solid/terms#>.

@@ -80,4 +77,3 @@ <>

`;
exports.private_content = private_content;
const acl_content = `@prefix acl: <http://www.w3.org/ns/auth/acl#>.
const acl_content = exports.acl_content = `@prefix acl: <http://www.w3.org/ns/auth/acl#>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.

@@ -106,4 +102,2 @@

`;
/* ENDS */
exports.acl_content = acl_content;
/* ENDS */

@@ -15,3 +15,2 @@ "use strict";

};
class RestPatch {

@@ -21,3 +20,2 @@ constructor(passedRDF) {

}
async patchContent(content, contentType, request) {

@@ -34,10 +32,7 @@ const url = request.url;

const parsePatch = PATCH_PARSERS[patch.contentType];
if (!parsePatch) {
return [415, `415 Unsupported patch content type: ${patch.contentType}`];
} // Parse the patch document and verify permissions
}
// Parse the patch document and verify permissions
const patchUri = `${url}#patch`;
try {

@@ -50,3 +45,2 @@ const patchObject = await parsePatch(url, patchUri, patch.text);

*/
let insertStmts = patch.text.match(/INSERT/g);

@@ -60,10 +54,9 @@ if (insertStmts && insertStmts.length > 1) return [400, "can not have multiple INSERT statements in a patch"];

}
} // PARSE ORIGINAL DOCUMENT
}
// PARSE ORIGINAL DOCUMENT
//
async readGraph(fileContents, resource) {
const graph = $rdf.graph();
if (!fileContents.length) return graph;
try {

@@ -74,8 +67,7 @@ $rdf.parse(fileContents, graph, resource.url, resource.contentType);

}
return graph;
}
return graph;
} // APPLY PATCH
// APPLY PATCH
//
async applyPatch(patchObject, graph, url) {

@@ -85,14 +77,11 @@ return new Promise((resolve, reject) => graph.applyPatch(patchObject, graph.sym(url), err => {

const message = err.message || err; // returns string at the moment
return reject(new Error(`409 : The patch could not be applied. ${message}`)); // is this correct : not tested
}
resolve(graph);
}));
} // serialize graph to turtle
}
// serialize graph to turtle
async writeGraph(graph, resource) {
const resourceSym = graph.sym(resource.url);
try {

@@ -104,19 +93,14 @@ const serialized = $rdf.serialize(resourceSym, graph, resource.url, resource.contentType);

}
} // Creates a hash of the given text
}
// Creates a hash of the given text
hash(text) {
return crypto.createHash('md5').update(text).digest('hex');
}
} // END OF CLASS RestPatch
} // END OF CLASS RestPatch
// PARSE SPARQL
//
exports.default = RestPatch;
async function parsePatchSparql(targetURI, patchURI, patchText) {
const baseURI = patchURI.replace(/#.*/, '');
try {

@@ -127,9 +111,8 @@ return $rdf.sparqlUpdateParser(patchText, $rdf.graph(), baseURI);

}
} // PARSE N3
}
// PARSE N3
//
async function parsePatchN3(targetURI, patchURI, patchText) {
const patchGraph = $rdf.graph();
try {

@@ -140,5 +123,3 @@ $rdf.parse(patchText, patchGraph, patchURI, 'text/n3');

}
let firstResult;
try {

@@ -165,3 +146,2 @@ firstResult = await queryForFirstResult(patchGraph, `${PREFIXES}

}
const {

@@ -172,7 +152,6 @@ '?insert': insert,

} = firstResult;
if (!insert && !deleted) {
return [400, 'Patch should at least contain inserts or deletes.']; // throw error(400, 'Patch should at least contain inserts or deletes.')
return [400, 'Patch should at least contain inserts or deletes.'];
// throw error(400, 'Patch should at least contain inserts or deletes.')
}
return {

@@ -183,6 +162,6 @@ insert,

};
} // EXECUTE FIRST SPARQL QUERY IN STORE & RETURN RESULTS
}
// EXECUTE FIRST SPARQL QUERY IN STORE & RETURN RESULTS
//
function queryForFirstResult(store, sparql) {

@@ -193,4 +172,5 @@ return new Promise((resolve, reject) => {

return ['409 : No results.'];
}); // TODO check status
});
// TODO check status
});
}

@@ -7,22 +7,15 @@ "use strict";

exports.createServerlessPod = createServerlessPod;
exports.generateRandomSlug = generateRandomSlug;
exports.getAuxResources = getAuxResources;
exports.getContentType = getContentType;
exports.isAuxResource = isAuxResource;
exports.getAuxResources = getAuxResources;
exports.generateRandomSlug = generateRandomSlug;
exports.linksExt = exports.linkExt = void 0;
var _uuid = require("uuid");
var pod = _interopRequireWildcard(require("./createServerlessPod.js"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
// import { contentType as contentTypeLookup } from 'mime-types';
const linkExt = ['.acl', '.meta'];
exports.linkExt = linkExt;
const linksExt = linkExt.concat('.meta.acl');
exports.linksExt = linksExt;
const linkExt = exports.linkExt = ['.acl', '.meta'];
const linksExt = exports.linksExt = linkExt.concat('.meta.acl');
async function createServerlessPod(base) {

@@ -42,6 +35,4 @@ console.log(`Creating pod at <${base}>`);

}
async function getContentType(path, type) {
let ext = this.getExtension(path);
if (!ext || ext === '.ttl' || ext === '.acl' || ext === '.meta' || type === "Container") {

@@ -55,7 +46,6 @@ return 'text/turtle';

}
function isAuxResource(o) {
return linkExt.find(ext => this.getExtension(o) === ext); // return linkExt.find(ext => o.extension === ext);
return linkExt.find(ext => this.getExtension(o) === ext);
// return linkExt.find(ext => o.extension === ext);
}
async function getAuxResources(pathname) {

@@ -68,12 +58,9 @@ if (pathname.endsWith('.acl')) return [];

}
async function generateRandomSlug(pathname, slug = (0, _uuid.v1)()) {
let requestUrl = this.mungePath(pathname, slug);
if (this.item.isContainer && !this.request.url.endsWith(this.pathSep)) requestUrl = requestUrl + this.pathSep;
if (await this.perform('ITEM_EXISTS', requestUrl)) {
slug = `${(0, _uuid.v1)()}-${slug}`;
}
return this.mungePath(pathname, slug);
}

@@ -8,3 +8,2 @@ import { Url as URL } from "url";

request.body = request.body || "";
if (!validUrl(uri)) {

@@ -18,3 +17,2 @@ request.url = null;

}
if (request.url && request.url.endsWith('.dummy')) {

@@ -25,3 +23,2 @@ // rdflib does this !!!

}
return request;

@@ -35,3 +32,2 @@ }

let newOpts = {};
for (var o in opts) {

@@ -42,6 +38,4 @@ if (o === 'host') {

}
return newOpts;
}
const validUrl = s => {

@@ -59,5 +53,4 @@ try {

function normalizeRequestMethod(method) {
return method ? method.toUpperCase() : 'GET';
}

@@ -7,3 +7,2 @@ //import libPath from "path";

pathHandler = await this.perform('GET_PATH_HANDLER', uri);
if (uri.startsWith('file')) {

@@ -16,3 +15,2 @@ url = Url.format(request.url);

}
const item = await this.perform('GET_ITEM_INFO', pname, request);

@@ -25,3 +23,2 @@ item.mode = item.mode ? item.mode : {

item.pathname = pname;
if (request.method === 'DELETE' && item.isContainer) {

@@ -35,3 +32,2 @@ let files = await this.perform('GET_FILES', item.pathname);

}
this.getExtension = path => {

@@ -42,6 +38,4 @@ path = path || this.item.pathname || "";

};
this.pathSep = pathHandler.sep;
this.basename = pathHandler.extname;
this.mungePath = (pathname, slug, options) => {

@@ -52,3 +46,2 @@ pathname = pathHandler.join(pathname, slug);

};
pname = request.method === "POST" ? this.mungePath(item.pathname, request.slug) : item.pathname;

@@ -59,5 +52,6 @@ item.extension = this.getExtension(pname);

item.isAcl = pname.match(/\.acl/); // TBD use LinkExt
//item.isAuxResource = item.isAcl || this.extension === '.meta';
item.isAuxResource = pname.match(/\.(acl|meta)$/) ? true : false;
item.isAuxResource = pname.match(/\.(acl|meta)$/) ? true : false;
/*

@@ -64,0 +58,0 @@ let conflict

@@ -34,6 +34,4 @@ const methods = {

const request = this.requestObj = await this.getRequest(uri, originalRequest); //
const item = this.item = await this.getItem(uri, request); //
// Errors we find in the request
if (!request.url || !request.method) return 400;

@@ -44,11 +42,9 @@ if (request.slug.endsWith('/')) return 400;

if (request.method === 'PATCH' && !this.patch) return 405;
if (request.method === 'POST' && !request.headers.link) return 400; // Errors we find by comparing the request & the itemRequested
if (request.method === 'POST' && !request.headers.link) return 400;
// Errors we find by comparing the request & the itemRequested
if (item.isContainer && !item.contentType) item.contentType = "text/turtle";
if (item.folderFileConfusion) return 400; // can't have both /foo and /foo/
if (item.patchOnNonRdf) return 400;
if (item.mode.write) item.mode.append = true;
const method = methods[request.method];
if (item.isAuxResource) {

@@ -58,3 +54,2 @@ if (item.isAcl) method.requiresControl = true;

}
if (!method) console.log(55, request.method);

@@ -64,3 +59,2 @@ if (!method) return 409;

if (method.requiresRead && !item.mode.read || method.requiresAppend && !item.mode.append || method.requiresWrite && !item.mode.write || method.requiresControl && !item.mode.control) return 401;
if (method.requiresContentType && !request.headers['content-type']) {

@@ -70,3 +64,2 @@ // console.log(request.method, "No Content Type");

}
if (request.method === 'POST') {

@@ -77,3 +70,2 @@ this.item.pathname = await this.generateRandomSlug(this.item.pathname, request.slug);

if (request.method === 'PUT' || request.method === 'POST' || request.method === 'PATCH') {

@@ -84,8 +76,5 @@ // if (item.isContainer) return 405;

}
let response = await this.perform(request.method);
if (!response && request.method === 'DELETE' && item.isContainer) {
let stillExists = await this.perform('ITEM_EXISTS', this.item.pathname);
if (stillExists) {

@@ -95,4 +84,3 @@ return 409;

}
return response;
} // ENDS

@@ -25,3 +25,2 @@ /*

let wrapHeaders = true; // {headers} instead of headers for Response
let method = originalRequest.method || this.request.method || "GET";

@@ -39,3 +38,2 @@ let finalResponse = {

*/
if (typeof response === 'number') {

@@ -62,22 +60,23 @@ wrapHeaders = false;

if (method.match(/(PUT)/) && finalResponse.headers.status == 200) {
finalResponse.headers.status = 201;
}
if (method.match(/(DELETE|GET|HEAD)/) && finalResponse.headers.status == 201) {
finalResponse.headers.status = 200;
}
let headers = {};
const request = this.requestObj;
const item = this.item;
const pathname = item.pathname; // const fn = libPath.basename(pathname);
const pathname = item.pathname;
// const fn = libPath.basename(pathname);
const fn = pathname.replace(/.*\//, '');
headers['vary'] = 'accept,authorization,origin';
headers['access-control-expose-headers'] = 'accept-patch,accept-post,accept-put,allow,content-range,etag,last-modified,link,location,updates-via,wac-allow,www-authenticate';
headers['content-type'] = this.item.contentType; // CONTENT-TYPE
headers.link = headers.link || createLinkHeader(item); // LINK
const storageHeader = item.pathname === '/' ? ', <http://www.w3.org/ns/pim/space#Storage>; rel="type"' : '';
headers.link = headers.link || createLinkHeader(item) + storageHeader; // LINK
headers.allow = createAllowHeader(this.patch, this.item.mode); // ALLOW
headers.allow = createAllowHeader(item.pathname); // ALLOW

@@ -90,6 +89,6 @@ headers['wac-allow'] = createWacHeader(this.item.mode); // WAC-ALLOW

if (this.response && this.response.headers) headers.location = this.response.headers.location; // NO, DON'T USE LOCATION headers.url = headers.location || pathname ;
if (this.response && this.response.headers) headers.location = this.response.headers.location;
// NO, DON'T USE LOCATION headers.url = headers.location || pathname ;
headers.url = pathname;
if (method === "POST") {

@@ -107,15 +106,14 @@ headers.url = this.request.url;

}
/* if (this.patch) { // ACCEPT-PATCH & MS-AUTHOR-VIA
headers['accept-patch'] = ['text/n3', 'application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
} */
if (this.patch) {
// ACCEPT-PATCH & MS-AUTHOR-VIA
headers['accept-patch'] = ['application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
}
let body = finalResponse.body || this.response.body || ""; // Now we merge headers we created with response headers, prefering response
Object.assign(headers, finalResponse.headers); //alert(finalResponse.headers.status)
Object.assign(headers, finalResponse.headers);
//alert(finalResponse.headers.status)
headers.status = finalResponse.headers.status || this.response.headers.status || 500;
let $rdf = typeof window != "undefined" && window.$rdf ? window.$rdf : typeof global != "undefined" && global.$rdf ? global.$rdf : null;
/*

@@ -146,12 +144,18 @@ async function serialize(uri,body,informat,outformat){

*/
headers.statusText = headers.statusText || statusText[headers.status];
headers = createAcceptHeader(request, headers); // ACCEPT
headers.statusText = headers.statusText || statusText[headers.status];
headers.etag = `W/"${uuid()}"`;
headers['content-length'] = typeof Buffer != 'undefined' ? Buffer.byteLength(body, 'utf8') : typeof Blob != "undefined" ? new Blob([body]).size : 77; // Now we create & return the Response object
headers['content-length'] = typeof Buffer != 'undefined' ? Buffer.byteLength(body, 'utf8') : typeof Blob != "undefined" ? new Blob([body]).size : 77;
// TODO (?) last-modified
// Now we create & return the Response object
for (var h of Object.keys(headers)) {
if (!headers[h]) delete headers[h];
}
if (!headers.url.match(/:/)) headers.url = (this.prefix || "file:") + "//" + headers.url;
if (!headers.url.match(/:/)) headers.url = (this.prefix || "file:") + "//" + headers.url; // headers.location = headers.location || headers.url.replace(/^....?:\/\//,'');
// headers.location = headers.location || headers.url.replace(/^....?:\/\//,'');
// if(!headers.location.match(/^file:/)) headers.location = "file://"+headers.location;

@@ -161,3 +165,2 @@

body = "";
for (let k of Object.keys(headers)) {

@@ -167,3 +170,2 @@ body = body + `${k}:${headers[k]}\n`;

}
if (originalRequest.plainResponse) {

@@ -180,3 +182,2 @@ // from a server that wants to munge

}
wrapHeaders = true;

@@ -191,3 +192,2 @@ headers = wrapHeaders ? {

let responseObject;
try {

@@ -200,3 +200,2 @@ responseObject = new Response(body, headers, {

}
return responseObject;

@@ -212,7 +211,26 @@ } // end of handleResponse method

}
function createAllowHeader(patch, mode) {
return 'OPTIONS,HEAD' + (mode.read ? ',GET' : '') + (mode.write ? ',POST,PUT,DELETE' : '') + (mode.write && patch ? ',PATCH' : '');
function createAllowHeader(requestPath) {
// root/ root/.acl can't be deleted
let del = requestPath === '/' || requestPath === '/.acl' ? '' : ',DELETE';
// no PATCH on Container
if (requestPath.endsWith('/')) return 'OPTIONS,HEAD,GET,POST,PUT' + del;
// no POST on Document
else return 'OPTIONS,HEAD,GET,PATCH,PUT' + del;
}
function createAcceptHeader(request, headers) {
const status = headers.status;
// no Accept header
if (request.method.match(/DELETE/) || status >= 500 || status.toString().match(/401|403/)) return headers;
// Accept headers on container
if (request.url.endsWith('/')) {
if (status === 404) headers['accept-put'] = ['*/*'];
headers['accept-post'] = ['*/*'];
} else {
// Accept headers on document
headers['accept-put'] = ['*/*'];
headers['accept-patch'] = ['text/n3', 'application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
}
return headers;
}
function createLinkHeader(item) {

@@ -223,12 +241,13 @@ let isContainer = item.isContainer;

let ext = item.extension;
if (ext === '.acl') // .acl not controlledBy or describedBy anything
if (ext === '.acl')
// .acl not controlledBy or describedBy anything
return `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;else if (ext === '.meta') {
return `<${fn}.acl>; rel="acl",` // .meta controlledBy .meta.acl
+ `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return `<${fn}.acl>; rel="acl"` // .meta controlledBy .meta.acl
+ `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
} else if (isContainer) {
return `<.meta>; rel="describedBy", <.acl>; rel="acl",` + `<http://www.w3.org/ns/ldp#Container>; rel="type",` + `<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"` + `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return `<.meta>; rel="describedBy", <.acl>; rel="acl"` + `, <http://www.w3.org/ns/ldp#Container>; rel="type"` + `, <http://www.w3.org/ns/ldp#BasicContainer>; rel="type"` + `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
} else {
let link = `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl",` + `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
let link = `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl"` + `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return link;
}
} // THE END!

@@ -12,3 +12,2 @@ import { getRequest } from './examineRequest.js';

options = options || {};
if (!options.plugin) {

@@ -18,3 +17,2 @@ console.log(`You must specify a plugin storage handler!`);

}
this.storage = options.plugin;

@@ -37,3 +35,2 @@ this.handleRequest = handleRequest.bind(this);

}
async fetch(uri, options = {}) {

@@ -43,3 +40,2 @@ let response = await this.handleRequest(uri, options);

}
async login(options) {

@@ -53,21 +49,15 @@ options = {

}
async itemExists(pathname) {
return await this.perform('ITEM_EXISTS', pathname);
}
isPatchConflictError(response) {
if (response === 400) return true;
}
isAccessError(response) {
if (response === 401) return true;
}
/* =========================================================== */
/* REST METHODS */
/* =========================================================== */
async GET(url) {

@@ -78,3 +68,2 @@ return await this.fetch(url, {

}
async HEAD(url) {

@@ -85,3 +74,2 @@ return await this.fetch(url, {

}
async EXISTS(url) {

@@ -97,3 +85,2 @@ try {

}
async PUT(url, text, ctype) {

@@ -109,3 +96,2 @@ ctype = ctype || 'text/turtle';

}
async PATCH(url, patchContent, patchContentType) {

@@ -123,3 +109,2 @@ patchContentType = patchContent || "text/n3";

}
async DELETE(url) {

@@ -130,3 +115,2 @@ return await this.fetch(url, {

}
async POST(parent, item, content, link) {

@@ -143,3 +127,2 @@ return await this.fetch(parent, {

}
async postFile(parent, file, content) {

@@ -149,3 +132,2 @@ let link = '<http://www.w3.org/ns/ldp#Resource>; rel="type"';

}
async postFolder(parent, folder) {

@@ -155,3 +137,2 @@ let link = '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"';

}
} // THE END

@@ -12,3 +12,2 @@ export default async function perform(method, pathname, content, ctype) {

};
switch (method) {

@@ -18,3 +17,2 @@ case 'STORAGE_NAME':

break;
case 'ITEM_EXISTS':

@@ -24,7 +22,5 @@ pathname = pathname.replace('file://', '');

break;
case 'LOGIN':
return await this.storage.login(this.request.loginoptions);
break;
case 'ITEM_TYPE':

@@ -34,20 +30,15 @@ // Container/Resource

break;
case 'GET_CONTENT_TYPE':
return await this.storage.getContentType(pathname); // return await this.storage.getContentType(pathname).bind(this.storage);
return await this.storage.getContentType(pathname);
// return await this.storage.getContentType(pathname).bind(this.storage);
break;
case 'GET_PATH_HANDLER':
return await this.storage.getPathHandler(pathname);
break;
case 'GET_ITEM_INFO':
return await this.storage.getItemInfo(pathname, this.request);
break;
case 'GET_FILES':
return await this.storage.getContainer(pathname);
break;
case 'DELETE':

@@ -61,8 +52,5 @@ if (this.item.isContainer) {

}
break;
case 'DELETE_AUX_RESOURCES':
const links = (await this.getAuxResources(pathname)) || [];
try {

@@ -77,18 +65,13 @@ links.map(async link => {

}
return 200;
break;
case 'CREATE_INTERMEDIATE_CONTAINERS':
return (await this.storage.makeContainers(pathname)) || 1;
break;
case 'GET':
if (this.item.isContainer) {
let files = await this.storage.getContainer(pathname);
if (files.headers) {
return files;
}
return await this.containerAsTurtle(pathname, files, this.request.typewanted, this);

@@ -98,7 +81,5 @@ } else {

if (!thing) return false;
if (thing.headers) {
return thing;
}
this.response.body = thing;

@@ -108,5 +89,3 @@ this.response.headers.status = 200;

}
break;
case 'OPTIONS':

@@ -116,7 +95,5 @@ case 'HEAD':

break;
case 'PUT':
content = content || this.request.body;
ctype = ctype || this.item.contentType || ""; // console.log('content for put',content);
let x = await this.storage.putResource(pathname, content, ctype); // console.log('response from put',x);

@@ -127,3 +104,2 @@

break;
case 'FULL_PUT':

@@ -136,3 +112,2 @@ let success = await this.storage.makeContainers(pathname);

break;
case 'POST':

@@ -148,5 +123,3 @@ if (this.request.headers.link.match("Container")) {

}
break;
case 'PATCH':

@@ -164,13 +137,11 @@ const contentType = this.item.contentType;

if (!exists) await this.perform('FULL_PUT', pathname, "", ctype);
; // 415 patchOnNonTurtle is handled already in handleRequest.js
;
// 415 patchOnNonTurtle is handled already in handleRequest.js
let oldContent = await this.storage.getResource(pathname);
oldContent = oldContent && oldContent.body ? oldContent.body : oldContent; // if (!oldContent) return false;
oldContent = oldContent && oldContent.body ? oldContent.body : oldContent;
// if (!oldContent) return false;
oldContent = typeof oldContent === 'string' ? oldContent : oldContent.toString();
let newContent, patchStatus;
try {
[patchStatus, newContent] = await this.patch.patchContent(oldContent, contentType, this.request);
if (patchStatus !== 200) {

@@ -188,7 +159,7 @@ return {

};
} // const status = await this.storage.makeContainers(pathname);
}
// const status = await this.storage.makeContainers(pathname);
// if (!status) return false;
// let putStatus = await this.storage.putResource(pathname, this.request.bod);
let putStatus = await this.storage.putResource(pathname, newContent);

@@ -195,0 +166,0 @@ putStatus = putStatus && putStatus.body ? putStatus.body : putStatus;

// import libPath from 'path';
export default async function containerAsTurtle(pathname, contentsArray, typeWanted, self) {
const pathSep = self.pathSep;
function basename(path) {
return path.substr(path.lastIndexOf(self.pathSep) + 1);
}
let filenames = contentsArray.filter(item => {

@@ -22,7 +21,6 @@ if (item.path && !item.path.endsWith('.acl') && !item.path.endsWith('.meta')) {

@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
<> a ldp:BasicContainer, ldp:Container
`;
<> a ldp:BasicContainer, ldp:Container`;
if (filenames.length) {
str = str + "; ldp:contains\n";
str = str + ";\n ldp:contains\n"; // alain

@@ -34,3 +32,2 @@ for (var i = 0; i < filenames.length; i++) {

fn = basename(fn); // contained resources are relative to folder
if (filenames[i].isContainer && !fn.endsWith("/")) fn = fn + "/";

@@ -40,3 +37,2 @@ str = str + ` <${fn}>,\n`;

let ctype, size, mtime, modified;
if (self && self.storage.getMetadata) {

@@ -52,19 +48,21 @@ try {

}
} else if (filenames[i].metadata) {
size = filenames[i].metadata.size;
mtime = filenames[i].metadata.mtimeMs;
modified = new Date(mtime).toISOString();
}
ctype = ctype || (await self.getContentType(fn, ftype)) || ""; // REMOVE CHARSET FROM CONTENT-TYPE
ctype = ctype || (await self.getContentType(fn, ftype)) || "";
// REMOVE CHARSET FROM CONTENT-TYPE
ctype = ctype.replace(/;.*/, '');
ftype = filenames[i].isContainer ? "ldp:Container; a ldp:BasicContainer; a ldp:Resource" : "ldp:Resource";
str2 = str2 + `<${fn}> a ${ftype}.\n`;
if (ctype) str2 = str2 + `<${fn}> a <http://www.w3.org/ns/iana/media-types/${ctype}#Resource>.\n`; // str2 = str2 + `<${fn}> :type "${ctype}".\n`
str2 = str2 + `<${fn}> a ${ftype}`;
if (ctype && !filenames[i].isContainer)
// no media-type for Container
str2 = str2 + `, <http://www.w3.org/ns/iana/media-types/${ctype}#Resource>`; // str2 = str2 + `<${fn}> :type "${ctype}".\n`
if (size) {
str2 = str2 + `<${fn}> stat:size ${size}; stat:mtime ${mtime}; dct:"${modified}"^^xsd:dateTime.\n`;
str2 = str2 + `;\n stat:size ${size};\n stat:mtime ${mtime};\n dct:modified "${modified}"^^xsd:dateTime.\n`;
}
}
str = str.replace(/,\n$/, "");
}
str = str + `.\n` + str2; // str = _makeStream(str);

@@ -71,0 +69,0 @@

@@ -13,3 +13,2 @@ let $rdf; //import crypto from 'crypto' TODO may be

}
async patchContent(content, contentType, request) {

@@ -26,10 +25,7 @@ const url = request.url;

const parsePatch = PATCH_PARSERS[patch.contentType];
if (!parsePatch) {
return [415, `415 Unsupported patch content type: ${patch.contentType}`];
} // Parse the patch document and verify permissions
}
// Parse the patch document and verify permissions
const patchUri = `${url}#patch`;
try {

@@ -42,3 +38,2 @@ const patchObject = await parsePatch(url, patchUri, patch.text);

*/
let insertStmts = patch.text.match(/INSERT/g);

@@ -52,10 +47,9 @@ if (insertStmts && insertStmts.length > 1) return [400, "can not have multiple INSERT statements in a patch"];

}
} // PARSE ORIGINAL DOCUMENT
}
// PARSE ORIGINAL DOCUMENT
//
async readGraph(fileContents, resource) {
const graph = $rdf.graph();
if (!fileContents.length) return graph;
try {

@@ -66,8 +60,7 @@ $rdf.parse(fileContents, graph, resource.url, resource.contentType);

}
return graph;
}
return graph;
} // APPLY PATCH
// APPLY PATCH
//
async applyPatch(patchObject, graph, url) {

@@ -77,14 +70,11 @@ return new Promise((resolve, reject) => graph.applyPatch(patchObject, graph.sym(url), err => {

const message = err.message || err; // returns string at the moment
return reject(new Error(`409 : The patch could not be applied. ${message}`)); // is this correct : not tested
}
resolve(graph);
}));
} // serialize graph to turtle
}
// serialize graph to turtle
async writeGraph(graph, resource) {
const resourceSym = graph.sym(resource.url);
try {

@@ -96,16 +86,13 @@ const serialized = $rdf.serialize(resourceSym, graph, resource.url, resource.contentType);

}
} // Creates a hash of the given text
}
// Creates a hash of the given text
hash(text) {
return crypto.createHash('md5').update(text).digest('hex');
}
} // END OF CLASS RestPatch
} // END OF CLASS RestPatch
// PARSE SPARQL
//
async function parsePatchSparql(targetURI, patchURI, patchText) {
const baseURI = patchURI.replace(/#.*/, '');
try {

@@ -116,9 +103,8 @@ return $rdf.sparqlUpdateParser(patchText, $rdf.graph(), baseURI);

}
} // PARSE N3
}
// PARSE N3
//
async function parsePatchN3(targetURI, patchURI, patchText) {
const patchGraph = $rdf.graph();
try {

@@ -129,5 +115,3 @@ $rdf.parse(patchText, patchGraph, patchURI, 'text/n3');

}
let firstResult;
try {

@@ -154,3 +138,2 @@ firstResult = await queryForFirstResult(patchGraph, `${PREFIXES}

}
const {

@@ -161,7 +144,6 @@ '?insert': insert,

} = firstResult;
if (!insert && !deleted) {
return [400, 'Patch should at least contain inserts or deletes.']; // throw error(400, 'Patch should at least contain inserts or deletes.')
return [400, 'Patch should at least contain inserts or deletes.'];
// throw error(400, 'Patch should at least contain inserts or deletes.')
}
return {

@@ -172,6 +154,6 @@ insert,

};
} // EXECUTE FIRST SPARQL QUERY IN STORE & RETURN RESULTS
}
// EXECUTE FIRST SPARQL QUERY IN STORE & RETURN RESULTS
//
function queryForFirstResult(store, sparql) {

@@ -182,4 +164,5 @@ return new Promise((resolve, reject) => {

return ['409 : No results.'];
}); // TODO check status
});
// TODO check status
});
}

@@ -6,3 +6,2 @@ // import { contentType as contentTypeLookup } from 'mime-types';

const linksExt = linkExt.concat('.meta.acl');
async function createServerlessPod(base) {

@@ -22,6 +21,4 @@ console.log(`Creating pod at <${base}>`);

}
async function getContentType(path, type) {
let ext = this.getExtension(path);
if (!ext || ext === '.ttl' || ext === '.acl' || ext === '.meta' || type === "Container") {

@@ -35,7 +32,6 @@ return 'text/turtle';

}
function isAuxResource(o) {
return linkExt.find(ext => this.getExtension(o) === ext); // return linkExt.find(ext => o.extension === ext);
return linkExt.find(ext => this.getExtension(o) === ext);
// return linkExt.find(ext => o.extension === ext);
}
async function getAuxResources(pathname) {

@@ -48,14 +44,10 @@ if (pathname.endsWith('.acl')) return [];

}
async function generateRandomSlug(pathname, slug = uuidv1()) {
let requestUrl = this.mungePath(pathname, slug);
if (this.item.isContainer && !this.request.url.endsWith(this.pathSep)) requestUrl = requestUrl + this.pathSep;
if (await this.perform('ITEM_EXISTS', requestUrl)) {
slug = `${uuidv1()}-${slug}`;
}
return this.mungePath(pathname, slug);
}
export { createServerlessPod, getContentType, isAuxResource, getAuxResources, generateRandomSlug, linkExt, linksExt };

@@ -20,3 +20,2 @@ (function (global, factory) {

_exports.getRequest = getRequest;
function getRequest(uri, options) {

@@ -28,3 +27,2 @@ const request = normalizeRequestKeys(options);

request.body = request.body || "";
if (!validUrl(uri)) {

@@ -38,3 +36,2 @@ request.url = null;

}
if (request.url && request.url.endsWith('.dummy')) {

@@ -45,3 +42,2 @@ // rdflib does this !!!

}
return request;

@@ -53,6 +49,4 @@ }

function normalizeRequestKeys(opts) {
let newOpts = {};
for (var o in opts) {

@@ -63,6 +57,4 @@ if (o === 'host') {

}
return newOpts;
}
const validUrl = s => {

@@ -80,3 +72,2 @@ try {

function normalizeRequestMethod(method) {

@@ -83,0 +74,0 @@ return method ? method.toUpperCase() : 'GET';

@@ -21,12 +21,9 @@ (function (global, factory) {

_url = _interopRequireDefault(_url);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
//import libPath from "path";
//import libPath from "path";
var pathHandler;
async function getItem(uri, request) {
let url, pname;
pathHandler = await this.perform('GET_PATH_HANDLER', uri);
if (uri.startsWith('file')) {

@@ -39,3 +36,2 @@ url = _url.default.format(request.url);

}
const item = await this.perform('GET_ITEM_INFO', pname, request);

@@ -48,3 +44,2 @@ item.mode = item.mode ? item.mode : {

item.pathname = pname;
if (request.method === 'DELETE' && item.isContainer) {

@@ -58,3 +53,2 @@ let files = await this.perform('GET_FILES', item.pathname);

}
this.getExtension = path => {

@@ -65,6 +59,4 @@ path = path || this.item.pathname || "";

};
this.pathSep = pathHandler.sep;
this.basename = pathHandler.extname;
this.mungePath = (pathname, slug, options) => {

@@ -75,3 +67,2 @@ pathname = pathHandler.join(pathname, slug);

};
pname = request.method === "POST" ? this.mungePath(item.pathname, request.slug) : item.pathname;

@@ -82,5 +73,6 @@ item.extension = this.getExtension(pname);

item.isAcl = pname.match(/\.acl/); // TBD use LinkExt
//item.isAuxResource = item.isAcl || this.extension === '.meta';
item.isAuxResource = pname.match(/\.(acl|meta)$/) ? true : false;
item.isAuxResource = pname.match(/\.(acl|meta)$/) ? true : false;
/*

@@ -130,3 +122,2 @@ let conflict

*/
});

@@ -51,9 +51,6 @@ (function (global, factory) {

};
async function handleRequest(uri, originalRequest) {
const request = this.requestObj = await this.getRequest(uri, originalRequest); //
const item = this.item = await this.getItem(uri, request); //
// Errors we find in the request
if (!request.url || !request.method) return 400;

@@ -64,11 +61,9 @@ if (request.slug.endsWith('/')) return 400;

if (request.method === 'PATCH' && !this.patch) return 405;
if (request.method === 'POST' && !request.headers.link) return 400; // Errors we find by comparing the request & the itemRequested
if (request.method === 'POST' && !request.headers.link) return 400;
// Errors we find by comparing the request & the itemRequested
if (item.isContainer && !item.contentType) item.contentType = "text/turtle";
if (item.folderFileConfusion) return 400; // can't have both /foo and /foo/
if (item.patchOnNonRdf) return 400;
if (item.mode.write) item.mode.append = true;
const method = methods[request.method];
if (item.isAuxResource) {

@@ -78,3 +73,2 @@ if (item.isAcl) method.requiresControl = true;

}
if (!method) console.log(55, request.method);

@@ -84,3 +78,2 @@ if (!method) return 409;

if (method.requiresRead && !item.mode.read || method.requiresAppend && !item.mode.append || method.requiresWrite && !item.mode.write || method.requiresControl && !item.mode.control) return 401;
if (method.requiresContentType && !request.headers['content-type']) {

@@ -90,3 +83,2 @@ // console.log(request.method, "No Content Type");

}
if (request.method === 'POST') {

@@ -97,3 +89,2 @@ this.item.pathname = await this.generateRandomSlug(this.item.pathname, request.slug);

if (request.method === 'PUT' || request.method === 'POST' || request.method === 'PATCH') {

@@ -104,8 +95,5 @@ // if (item.isContainer) return 405;

}
let response = await this.perform(request.method);
if (!response && request.method === 'DELETE' && item.isContainer) {
let stillExists = await this.perform('ITEM_EXISTS', this.item.pathname);
if (stillExists) {

@@ -115,6 +103,4 @@ return 409;

}
return response;
} // ENDS
});

@@ -20,3 +20,2 @@ (function (global, factory) {

_exports.handleResponse = handleResponse;
/*

@@ -28,2 +27,3 @@ url : file:///foo/bar.txt

//import libPath from 'path';
const statusText = {

@@ -43,6 +43,4 @@ 200: "OK",

};
async function handleResponse(response, originalRequest) {
let wrapHeaders = true; // {headers} instead of headers for Response
let method = originalRequest.method || this.request.method || "GET";

@@ -60,3 +58,2 @@ let finalResponse = {

*/
if (typeof response === 'number') {

@@ -83,22 +80,23 @@ wrapHeaders = false;

if (method.match(/(PUT)/) && finalResponse.headers.status == 200) {
finalResponse.headers.status = 201;
}
if (method.match(/(DELETE|GET|HEAD)/) && finalResponse.headers.status == 201) {
finalResponse.headers.status = 200;
}
let headers = {};
const request = this.requestObj;
const item = this.item;
const pathname = item.pathname; // const fn = libPath.basename(pathname);
const pathname = item.pathname;
// const fn = libPath.basename(pathname);
const fn = pathname.replace(/.*\//, '');
headers['vary'] = 'accept,authorization,origin';
headers['access-control-expose-headers'] = 'accept-patch,accept-post,accept-put,allow,content-range,etag,last-modified,link,location,updates-via,wac-allow,www-authenticate';
headers['content-type'] = this.item.contentType; // CONTENT-TYPE
headers.link = headers.link || createLinkHeader(item); // LINK
const storageHeader = item.pathname === '/' ? ', <http://www.w3.org/ns/pim/space#Storage>; rel="type"' : '';
headers.link = headers.link || createLinkHeader(item) + storageHeader; // LINK
headers.allow = createAllowHeader(this.patch, this.item.mode); // ALLOW
headers.allow = createAllowHeader(item.pathname); // ALLOW

@@ -111,6 +109,6 @@ headers['wac-allow'] = createWacHeader(this.item.mode); // WAC-ALLOW

if (this.response && this.response.headers) headers.location = this.response.headers.location; // NO, DON'T USE LOCATION headers.url = headers.location || pathname ;
if (this.response && this.response.headers) headers.location = this.response.headers.location;
// NO, DON'T USE LOCATION headers.url = headers.location || pathname ;
headers.url = pathname;
if (method === "POST") {

@@ -128,15 +126,14 @@ headers.url = this.request.url;

}
/* if (this.patch) { // ACCEPT-PATCH & MS-AUTHOR-VIA
headers['accept-patch'] = ['text/n3', 'application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
} */
if (this.patch) {
// ACCEPT-PATCH & MS-AUTHOR-VIA
headers['accept-patch'] = ['application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
}
let body = finalResponse.body || this.response.body || ""; // Now we merge headers we created with response headers, prefering response
Object.assign(headers, finalResponse.headers); //alert(finalResponse.headers.status)
Object.assign(headers, finalResponse.headers);
//alert(finalResponse.headers.status)
headers.status = finalResponse.headers.status || this.response.headers.status || 500;
let $rdf = typeof window != "undefined" && window.$rdf ? window.$rdf : typeof global != "undefined" && global.$rdf ? global.$rdf : null;
/*

@@ -167,12 +164,18 @@ async function serialize(uri,body,informat,outformat){

*/
headers.statusText = headers.statusText || statusText[headers.status];
headers = createAcceptHeader(request, headers); // ACCEPT
headers.statusText = headers.statusText || statusText[headers.status];
headers.etag = `W/"${(0, _uuid.v4)()}"`;
headers['content-length'] = typeof Buffer != 'undefined' ? Buffer.byteLength(body, 'utf8') : typeof Blob != "undefined" ? new Blob([body]).size : 77; // Now we create & return the Response object
headers['content-length'] = typeof Buffer != 'undefined' ? Buffer.byteLength(body, 'utf8') : typeof Blob != "undefined" ? new Blob([body]).size : 77;
// TODO (?) last-modified
// Now we create & return the Response object
for (var h of Object.keys(headers)) {
if (!headers[h]) delete headers[h];
}
if (!headers.url.match(/:/)) headers.url = (this.prefix || "file:") + "//" + headers.url;
if (!headers.url.match(/:/)) headers.url = (this.prefix || "file:") + "//" + headers.url; // headers.location = headers.location || headers.url.replace(/^....?:\/\//,'');
// headers.location = headers.location || headers.url.replace(/^....?:\/\//,'');
// if(!headers.location.match(/^file:/)) headers.location = "file://"+headers.location;

@@ -182,3 +185,2 @@

body = "";
for (let k of Object.keys(headers)) {

@@ -188,3 +190,2 @@ body = body + `${k}:${headers[k]}\n`;

}
if (originalRequest.plainResponse) {

@@ -201,3 +202,2 @@ // from a server that wants to munge

}
wrapHeaders = true;

@@ -212,3 +212,2 @@ headers = wrapHeaders ? {

let responseObject;
try {

@@ -221,3 +220,2 @@ responseObject = new _crossFetch.Response(body, headers, {

}
return responseObject;

@@ -227,3 +225,2 @@ } // end of handleResponse method

function createWacHeader(mode) {

@@ -235,7 +232,26 @@ if (!mode.read && !mode.write) return null;

}
function createAllowHeader(patch, mode) {
return 'OPTIONS,HEAD' + (mode.read ? ',GET' : '') + (mode.write ? ',POST,PUT,DELETE' : '') + (mode.write && patch ? ',PATCH' : '');
function createAllowHeader(requestPath) {
// root/ root/.acl can't be deleted
let del = requestPath === '/' || requestPath === '/.acl' ? '' : ',DELETE';
// no PATCH on Container
if (requestPath.endsWith('/')) return 'OPTIONS,HEAD,GET,POST,PUT' + del;
// no POST on Document
else return 'OPTIONS,HEAD,GET,PATCH,PUT' + del;
}
function createAcceptHeader(request, headers) {
const status = headers.status;
// no Accept header
if (request.method.match(/DELETE/) || status >= 500 || status.toString().match(/401|403/)) return headers;
// Accept headers on container
if (request.url.endsWith('/')) {
if (status === 404) headers['accept-put'] = ['*/*'];
headers['accept-post'] = ['*/*'];
} else {
// Accept headers on document
headers['accept-put'] = ['*/*'];
headers['accept-patch'] = ['text/n3', 'application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
}
return headers;
}
function createLinkHeader(item) {

@@ -246,14 +262,14 @@ let isContainer = item.isContainer;

let ext = item.extension;
if (ext === '.acl') // .acl not controlledBy or describedBy anything
if (ext === '.acl')
// .acl not controlledBy or describedBy anything
return `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;else if (ext === '.meta') {
return `<${fn}.acl>; rel="acl",` // .meta controlledBy .meta.acl
+ `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return `<${fn}.acl>; rel="acl"` // .meta controlledBy .meta.acl
+ `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
} else if (isContainer) {
return `<.meta>; rel="describedBy", <.acl>; rel="acl",` + `<http://www.w3.org/ns/ldp#Container>; rel="type",` + `<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"` + `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return `<.meta>; rel="describedBy", <.acl>; rel="acl"` + `, <http://www.w3.org/ns/ldp#Container>; rel="type"` + `, <http://www.w3.org/ns/ldp#BasicContainer>; rel="type"` + `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
} else {
let link = `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl",` + `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
let link = `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl"` + `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return link;
}
} // THE END!
});

@@ -23,9 +23,6 @@ (function (global, factory) {

_restPatch = _interopRequireDefault(_restPatch);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class SolidRest {
constructor(options) {
options = options || {};
if (!options.plugin) {

@@ -35,3 +32,2 @@ console.log(`You must specify a plugin storage handler!`);

}
this.storage = options.plugin;

@@ -54,3 +50,2 @@ this.handleRequest = _handleRequest.handleRequest.bind(this);

}
async fetch(uri, options = {}) {

@@ -60,3 +55,2 @@ let response = await this.handleRequest(uri, options);

}
async login(options) {

@@ -70,21 +64,15 @@ options = {

}
async itemExists(pathname) {
return await this.perform('ITEM_EXISTS', pathname);
}
isPatchConflictError(response) {
if (response === 400) return true;
}
isAccessError(response) {
if (response === 401) return true;
}
/* =========================================================== */
/* REST METHODS */
/* =========================================================== */
async GET(url) {

@@ -95,3 +83,2 @@ return await this.fetch(url, {

}
async HEAD(url) {

@@ -102,3 +89,2 @@ return await this.fetch(url, {

}
async EXISTS(url) {

@@ -114,3 +100,2 @@ try {

}
async PUT(url, text, ctype) {

@@ -126,3 +111,2 @@ ctype = ctype || 'text/turtle';

}
async PATCH(url, patchContent, patchContentType) {

@@ -140,3 +124,2 @@ patchContentType = patchContent || "text/n3";

}
async DELETE(url) {

@@ -147,3 +130,2 @@ return await this.fetch(url, {

}
async POST(parent, item, content, link) {

@@ -160,3 +142,2 @@ return await this.fetch(parent, {

}
async postFile(parent, file, content) {

@@ -166,3 +147,2 @@ let link = '<http://www.w3.org/ns/ldp#Resource>; rel="type"';

}
async postFolder(parent, folder) {

@@ -172,7 +152,4 @@ let link = '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"';

}
} // THE END
_exports.default = SolidRest;
});

@@ -20,3 +20,2 @@ (function (global, factory) {

_exports.default = perform;
async function perform(method, pathname, content, ctype) {

@@ -33,3 +32,2 @@ this.request = this.requestObj;

};
switch (method) {

@@ -39,3 +37,2 @@ case 'STORAGE_NAME':

break;
case 'ITEM_EXISTS':

@@ -45,7 +42,5 @@ pathname = pathname.replace('file://', '');

break;
case 'LOGIN':
return await this.storage.login(this.request.loginoptions);
break;
case 'ITEM_TYPE':

@@ -55,20 +50,15 @@ // Container/Resource

break;
case 'GET_CONTENT_TYPE':
return await this.storage.getContentType(pathname); // return await this.storage.getContentType(pathname).bind(this.storage);
return await this.storage.getContentType(pathname);
// return await this.storage.getContentType(pathname).bind(this.storage);
break;
case 'GET_PATH_HANDLER':
return await this.storage.getPathHandler(pathname);
break;
case 'GET_ITEM_INFO':
return await this.storage.getItemInfo(pathname, this.request);
break;
case 'GET_FILES':
return await this.storage.getContainer(pathname);
break;
case 'DELETE':

@@ -82,8 +72,5 @@ if (this.item.isContainer) {

}
break;
case 'DELETE_AUX_RESOURCES':
const links = (await this.getAuxResources(pathname)) || [];
try {

@@ -98,18 +85,13 @@ links.map(async link => {

}
return 200;
break;
case 'CREATE_INTERMEDIATE_CONTAINERS':
return (await this.storage.makeContainers(pathname)) || 1;
break;
case 'GET':
if (this.item.isContainer) {
let files = await this.storage.getContainer(pathname);
if (files.headers) {
return files;
}
return await this.containerAsTurtle(pathname, files, this.request.typewanted, this);

@@ -119,7 +101,5 @@ } else {

if (!thing) return false;
if (thing.headers) {
return thing;
}
this.response.body = thing;

@@ -129,5 +109,3 @@ this.response.headers.status = 200;

}
break;
case 'OPTIONS':

@@ -137,7 +115,5 @@ case 'HEAD':

break;
case 'PUT':
content = content || this.request.body;
ctype = ctype || this.item.contentType || ""; // console.log('content for put',content);
let x = await this.storage.putResource(pathname, content, ctype); // console.log('response from put',x);

@@ -148,3 +124,2 @@

break;
case 'FULL_PUT':

@@ -157,3 +132,2 @@ let success = await this.storage.makeContainers(pathname);

break;
case 'POST':

@@ -169,5 +143,3 @@ if (this.request.headers.link.match("Container")) {

}
break;
case 'PATCH':

@@ -185,13 +157,11 @@ const contentType = this.item.contentType;

if (!exists) await this.perform('FULL_PUT', pathname, "", ctype);
; // 415 patchOnNonTurtle is handled already in handleRequest.js
;
// 415 patchOnNonTurtle is handled already in handleRequest.js
let oldContent = await this.storage.getResource(pathname);
oldContent = oldContent && oldContent.body ? oldContent.body : oldContent; // if (!oldContent) return false;
oldContent = oldContent && oldContent.body ? oldContent.body : oldContent;
// if (!oldContent) return false;
oldContent = typeof oldContent === 'string' ? oldContent : oldContent.toString();
let newContent, patchStatus;
try {
[patchStatus, newContent] = await this.patch.patchContent(oldContent, contentType, this.request);
if (patchStatus !== 200) {

@@ -209,7 +179,7 @@ return {

};
} // const status = await this.storage.makeContainers(pathname);
}
// const status = await this.storage.makeContainers(pathname);
// if (!status) return false;
// let putStatus = await this.storage.putResource(pathname, this.request.bod);
let putStatus = await this.storage.putResource(pathname, newContent);

@@ -221,3 +191,2 @@ putStatus = putStatus && putStatus.body ? putStatus.body : putStatus;

} // ENDS
});

@@ -20,11 +20,9 @@ (function (global, factory) {

_exports.default = containerAsTurtle;
// import libPath from 'path';
// import libPath from 'path';
async function containerAsTurtle(pathname, contentsArray, typeWanted, self) {
const pathSep = self.pathSep;
function basename(path) {
return path.substr(path.lastIndexOf(self.pathSep) + 1);
}
let filenames = contentsArray.filter(item => {

@@ -43,7 +41,6 @@ if (item.path && !item.path.endsWith('.acl') && !item.path.endsWith('.meta')) {

@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
<> a ldp:BasicContainer, ldp:Container
`;
<> a ldp:BasicContainer, ldp:Container`;
if (filenames.length) {
str = str + "; ldp:contains\n";
str = str + ";\n ldp:contains\n"; // alain

@@ -55,3 +52,2 @@ for (var i = 0; i < filenames.length; i++) {

fn = basename(fn); // contained resources are relative to folder
if (filenames[i].isContainer && !fn.endsWith("/")) fn = fn + "/";

@@ -61,3 +57,2 @@ str = str + ` <${fn}>,\n`;

let ctype, size, mtime, modified;
if (self && self.storage.getMetadata) {

@@ -73,19 +68,21 @@ try {

}
} else if (filenames[i].metadata) {
size = filenames[i].metadata.size;
mtime = filenames[i].metadata.mtimeMs;
modified = new Date(mtime).toISOString();
}
ctype = ctype || (await self.getContentType(fn, ftype)) || ""; // REMOVE CHARSET FROM CONTENT-TYPE
ctype = ctype || (await self.getContentType(fn, ftype)) || "";
// REMOVE CHARSET FROM CONTENT-TYPE
ctype = ctype.replace(/;.*/, '');
ftype = filenames[i].isContainer ? "ldp:Container; a ldp:BasicContainer; a ldp:Resource" : "ldp:Resource";
str2 = str2 + `<${fn}> a ${ftype}.\n`;
if (ctype) str2 = str2 + `<${fn}> a <http://www.w3.org/ns/iana/media-types/${ctype}#Resource>.\n`; // str2 = str2 + `<${fn}> :type "${ctype}".\n`
str2 = str2 + `<${fn}> a ${ftype}`;
if (ctype && !filenames[i].isContainer)
// no media-type for Container
str2 = str2 + `, <http://www.w3.org/ns/iana/media-types/${ctype}#Resource>`; // str2 = str2 + `<${fn}> :type "${ctype}".\n`
if (size) {
str2 = str2 + `<${fn}> stat:size ${size}; stat:mtime ${mtime}; dct:"${modified}"^^xsd:dateTime.\n`;
str2 = str2 + `;\n stat:size ${size};\n stat:mtime ${mtime};\n dct:modified "${modified}"^^xsd:dateTime.\n`;
}
}
str = str.replace(/,\n$/, "");
}
str = str + `.\n` + str2; // str = _makeStream(str);

@@ -92,0 +89,0 @@

@@ -20,3 +20,3 @@ (function (global, factory) {

_exports.public_content = _exports.profile_content = _exports.private_content = _exports.prefs_content = _exports.acl_content = void 0;
const profile_content = `@prefix : <#>.
const profile_content = _exports.profile_content = `@prefix : <#>.
@prefix jef: <../>.

@@ -54,4 +54,3 @@ @prefix ldp: <http://www.w3.org/ns/ldp#>.

`;
_exports.profile_content = profile_content;
const prefs_content = `@prefix : <#>.
const prefs_content = _exports.prefs_content = `@prefix : <#>.
@prefix solid: <http://www.w3.org/ns/solid/terms#>.

@@ -70,4 +69,3 @@ @prefix sp: <http://www.w3.org/ns/pim/space#>.

`;
_exports.prefs_content = prefs_content;
const public_content = `@prefix : <#>.
const public_content = _exports.public_content = `@prefix : <#>.
@prefix solid: <https://www.w3.org/ns/solid/terms#>.

@@ -85,4 +83,3 @@ @prefix terms: <http://purl.org/dc/terms/>.

`;
_exports.public_content = public_content;
const private_content = `
const private_content = _exports.private_content = `
@prefix solid: <https://www.w3.org/ns/solid/terms#>.

@@ -93,4 +90,3 @@ <>

`;
_exports.private_content = private_content;
const acl_content = `@prefix acl: <http://www.w3.org/ns/auth/acl#>.
const acl_content = _exports.acl_content = `@prefix acl: <http://www.w3.org/ns/auth/acl#>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.

@@ -120,4 +116,2 @@

/* ENDS */
_exports.acl_content = acl_content;
});

@@ -28,3 +28,2 @@ (function (global, factory) {

};
class RestPatch {

@@ -34,3 +33,2 @@ constructor(passedRDF) {

}
async patchContent(content, contentType, request) {

@@ -47,10 +45,7 @@ const url = request.url;

const parsePatch = PATCH_PARSERS[patch.contentType];
if (!parsePatch) {
return [415, `415 Unsupported patch content type: ${patch.contentType}`];
} // Parse the patch document and verify permissions
}
// Parse the patch document and verify permissions
const patchUri = `${url}#patch`;
try {

@@ -63,3 +58,2 @@ const patchObject = await parsePatch(url, patchUri, patch.text);

*/
let insertStmts = patch.text.match(/INSERT/g);

@@ -73,10 +67,9 @@ if (insertStmts && insertStmts.length > 1) return [400, "can not have multiple INSERT statements in a patch"];

}
} // PARSE ORIGINAL DOCUMENT
}
// PARSE ORIGINAL DOCUMENT
//
async readGraph(fileContents, resource) {
const graph = $rdf.graph();
if (!fileContents.length) return graph;
try {

@@ -87,8 +80,7 @@ $rdf.parse(fileContents, graph, resource.url, resource.contentType);

}
return graph;
}
return graph;
} // APPLY PATCH
// APPLY PATCH
//
async applyPatch(patchObject, graph, url) {

@@ -98,14 +90,11 @@ return new Promise((resolve, reject) => graph.applyPatch(patchObject, graph.sym(url), err => {

const message = err.message || err; // returns string at the moment
return reject(new Error(`409 : The patch could not be applied. ${message}`)); // is this correct : not tested
}
resolve(graph);
}));
} // serialize graph to turtle
}
// serialize graph to turtle
async writeGraph(graph, resource) {
const resourceSym = graph.sym(resource.url);
try {

@@ -117,19 +106,14 @@ const serialized = $rdf.serialize(resourceSym, graph, resource.url, resource.contentType);

}
} // Creates a hash of the given text
}
// Creates a hash of the given text
hash(text) {
return crypto.createHash('md5').update(text).digest('hex');
}
} // END OF CLASS RestPatch
} // END OF CLASS RestPatch
// PARSE SPARQL
//
_exports.default = RestPatch;
async function parsePatchSparql(targetURI, patchURI, patchText) {
const baseURI = patchURI.replace(/#.*/, '');
try {

@@ -140,9 +124,8 @@ return $rdf.sparqlUpdateParser(patchText, $rdf.graph(), baseURI);

}
} // PARSE N3
}
// PARSE N3
//
async function parsePatchN3(targetURI, patchURI, patchText) {
const patchGraph = $rdf.graph();
try {

@@ -153,5 +136,3 @@ $rdf.parse(patchText, patchGraph, patchURI, 'text/n3');

}
let firstResult;
try {

@@ -178,3 +159,2 @@ firstResult = await queryForFirstResult(patchGraph, `${PREFIXES}

}
const {

@@ -185,7 +165,6 @@ '?insert': insert,

} = firstResult;
if (!insert && !deleted) {
return [400, 'Patch should at least contain inserts or deletes.']; // throw error(400, 'Patch should at least contain inserts or deletes.')
return [400, 'Patch should at least contain inserts or deletes.'];
// throw error(400, 'Patch should at least contain inserts or deletes.')
}
return {

@@ -196,6 +175,6 @@ insert,

};
} // EXECUTE FIRST SPARQL QUERY IN STORE & RETURN RESULTS
}
// EXECUTE FIRST SPARQL QUERY IN STORE & RETURN RESULTS
//
function queryForFirstResult(store, sparql) {

@@ -206,5 +185,6 @@ return new Promise((resolve, reject) => {

return ['409 : No results.'];
}); // TODO check status
});
// TODO check status
});
}
});

@@ -26,13 +26,8 @@ (function (global, factory) {

pod = _interopRequireWildcard(pod);
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
// import { contentType as contentTypeLookup } from 'mime-types';
const linkExt = ['.acl', '.meta'];
_exports.linkExt = linkExt;
const linksExt = linkExt.concat('.meta.acl');
_exports.linksExt = linksExt;
const linkExt = _exports.linkExt = ['.acl', '.meta'];
const linksExt = _exports.linksExt = linkExt.concat('.meta.acl');
async function createServerlessPod(base) {

@@ -52,6 +47,4 @@ console.log(`Creating pod at <${base}>`);

}
async function getContentType(path, type) {
let ext = this.getExtension(path);
if (!ext || ext === '.ttl' || ext === '.acl' || ext === '.meta' || type === "Container") {

@@ -65,7 +58,6 @@ return 'text/turtle';

}
function isAuxResource(o) {
return linkExt.find(ext => this.getExtension(o) === ext); // return linkExt.find(ext => o.extension === ext);
return linkExt.find(ext => this.getExtension(o) === ext);
// return linkExt.find(ext => o.extension === ext);
}
async function getAuxResources(pathname) {

@@ -78,13 +70,10 @@ if (pathname.endsWith('.acl')) return [];

}
async function generateRandomSlug(pathname, slug = (0, _uuid.v1)()) {
let requestUrl = this.mungePath(pathname, slug);
if (this.item.isContainer && !this.request.url.endsWith(this.pathSep)) requestUrl = requestUrl + this.pathSep;
if (await this.perform('ITEM_EXISTS', requestUrl)) {
slug = `${(0, _uuid.v1)()}-${slug}`;
}
return this.mungePath(pathname, slug);
}
});
{
"name": "@solid-rest/core",
"version": "2.1.18",
"version": "2.1.19",
"author": "Jeff Zucker",
"contributors": [
"Alain Bourgeois",
"Rahul Gupta"
],
"license": "MIT",

@@ -32,10 +36,10 @@ "description": "treat any storage as a mini Solid server",

"dependencies": {
"cross-fetch": "^3.1.5",
"uuid": "8.3.1"
"cross-fetch": "^4.0.0",
"uuid": "9.0.1"
},
"devDependencies": {
"@babel/cli": "^7.12.10",
"@babel/core": "^7.14.6",
"@babel/plugin-transform-modules-commonjs": "^7.12.1",
"@babel/plugin-transform-modules-umd": "^7.16.0",
"@babel/cli": "^7.23.9",
"@babel/core": "^7.23.9",
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
"@babel/plugin-transform-modules-umd": "^7.23.3",
"babel-preset-es2015": "6.24.1",

@@ -42,0 +46,0 @@ "babel-preset-stage-0": "6.24.1"

@@ -59,3 +59,3 @@ /*

if(method.match(/(PUT)/) && finalResponse.headers.status == 200){
finalResponse.headers.status = 201
finalResponse.headers.status = 201
}

@@ -73,9 +73,14 @@ if(method.match(/(DELETE|GET|HEAD)/) && finalResponse.headers.status == 201){

// const fn = libPath.basename(pathname);
const fn = pathname.replace(/.*\//,'');
const fn = pathname.replace(/.*\//,'');
headers['vary'] = 'accept,authorization,origin'
headers['access-control-expose-headers'] = 'accept-patch,accept-post,accept-put,allow,content-range,etag,last-modified,link,location,updates-via,wac-allow,www-authenticate'
headers['content-type'] = this.item.contentType; // CONTENT-TYPE
headers.link = headers.link || createLinkHeader(item); // LINK
const storageHeader = item.pathname === '/' ? ', <http://www.w3.org/ns/pim/space#Storage>; rel="type"' : ''
headers.link = headers.link || (createLinkHeader(item) + storageHeader); // LINK
headers.allow = createAllowHeader(this.patch, this.item.mode); // ALLOW
headers.allow = createAllowHeader(item.pathname) // ALLOW

@@ -104,6 +109,6 @@ headers['wac-allow'] = createWacHeader(this.item.mode); // WAC-ALLOW

}
if (this.patch) { // ACCEPT-PATCH & MS-AUTHOR-VIA
headers['accept-patch'] = ['application/sparql-update'];
/* if (this.patch) { // ACCEPT-PATCH & MS-AUTHOR-VIA
headers['accept-patch'] = ['text/n3', 'application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
}
} */

@@ -146,5 +151,9 @@

headers = createAcceptHeader(request, headers) // ACCEPT
headers.etag = `W/"${uuid()}"`;
headers['content-length'] = (typeof Buffer !='undefined') ?Buffer.byteLength(body,'utf8') :(typeof Blob!="undefined") ?(new Blob([body])).size :77;
// TODO (?) last-modified
// Now we create & return the Response object

@@ -209,6 +218,28 @@ for(var h of Object.keys(headers)){

function createAllowHeader(patch, mode) {
return 'OPTIONS,HEAD' + (mode.read ? ',GET' : '') + (mode.write ? ',POST,PUT,DELETE' : '') + (mode.write && patch ? ',PATCH' : '');
function createAllowHeader(requestPath) {
// root/ root/.acl can't be deleted
let del = (requestPath === '/' || requestPath === '/.acl') ? '' : ',DELETE'
// no PATCH on Container
if (requestPath.endsWith('/')) return 'OPTIONS,HEAD,GET,POST,PUT' + del
// no POST on Document
else return 'OPTIONS,HEAD,GET,PATCH,PUT' + del
}
function createAcceptHeader(request, headers) {
const status = headers.status
// no Accept header
if (request.method.match(/DELETE/) || status >= 500 || status.toString().match(/401|403/)) return headers
// Accept headers on container
if (request.url.endsWith('/')) {
if (status === 404) headers['accept-put'] = ['*/*'];
headers['accept-post'] = ['*/*'];
} else {
// Accept headers on document
headers['accept-put'] = ['*/*'];
headers['accept-patch'] = ['text/n3', 'application/sparql-update'];
headers['ms-author-via'] = ["SPARQL"];
}
return headers
}
function createLinkHeader(item) {

@@ -222,12 +253,12 @@ let isContainer = item.isContainer;

else if (ext === '.meta') {
return `<${fn}.acl>; rel="acl",` // .meta controlledBy .meta.acl
+ `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return `<${fn}.acl>; rel="acl"` // .meta controlledBy .meta.acl
+ `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
}
else if (isContainer) {
return `<.meta>; rel="describedBy", <.acl>; rel="acl",` + `<http://www.w3.org/ns/ldp#Container>; rel="type",` + `<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"` + `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return `<.meta>; rel="describedBy", <.acl>; rel="acl"` + `, <http://www.w3.org/ns/ldp#Container>; rel="type"` + `, <http://www.w3.org/ns/ldp#BasicContainer>; rel="type"` + `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
}
else {
let link = `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl",` + `<http://www.w3.org/ns/ldp#Resource>; rel="type"`;
let link = `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl"` + `, <http://www.w3.org/ns/ldp#Resource>; rel="type"`;
return link;
}
} // THE END!

@@ -22,7 +22,7 @@ // import libPath from 'path';

@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
<> a ldp:BasicContainer, ldp:Container
`;
<> a ldp:BasicContainer, ldp:Container`;
if (filenames.length) {
str = str + "; ldp:contains\n";
str = str + ";\n ldp:contains\n"; // alain

@@ -47,2 +47,6 @@ for (var i = 0; i < filenames.length; i++) {

catch(e){console.log(e)}
} else if (filenames[i].metadata) {
size = filenames[i].metadata.size
mtime = filenames[i].metadata.mtimeMs
modified = new Date(mtime).toISOString()
}

@@ -53,7 +57,7 @@ ctype = ctype || await self.getContentType(fn, ftype) || "";

ftype = filenames[i].isContainer ? "ldp:Container; a ldp:BasicContainer; a ldp:Resource" : "ldp:Resource";
str2 = str2 + `<${fn}> a ${ftype}.\n`;
if(ctype)
str2 = str2 + `<${fn}> a <http://www.w3.org/ns/iana/media-types/${ctype}#Resource>.\n`; // str2 = str2 + `<${fn}> :type "${ctype}".\n`
str2 = str2 + `<${fn}> a ${ftype}`;
if(ctype && !filenames[i].isContainer) // no media-type for Container
str2 = str2 + `, <http://www.w3.org/ns/iana/media-types/${ctype}#Resource>`; // str2 = str2 + `<${fn}> :type "${ctype}".\n`
if(size){
str2 = str2 + `<${fn}> stat:size ${size}; stat:mtime ${mtime}; dct:"${modified}"^^xsd:dateTime.\n`
str2 = str2 + `;\n stat:size ${size};\n stat:mtime ${mtime};\n dct:modified "${modified}"^^xsd:dateTime.\n`
}

@@ -60,0 +64,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc