diff --git a/lib/handlers/get.js b/lib/handlers/get.js index f4aed8eeb..effe681d6 100644 --- a/lib/handlers/get.js +++ b/lib/handlers/get.js @@ -128,6 +128,9 @@ async function handler (req, res, next) { res.send(data) return next() } catch (err) { + if (err.message === '404') { + return next(error(404, 'HTML do not contain data island')) + } debug('error translating: ' + req.originalUrl + ' ' + contentType + ' -> ' + possibleRDFType + ' -- ' + 500 + ' ' + err.message) return next(error(500, 'Error translating between RDF formats')) } diff --git a/lib/handlers/patch.js b/lib/handlers/patch.js index bda388393..d2385e112 100644 --- a/lib/handlers/patch.js +++ b/lib/handlers/patch.js @@ -8,7 +8,7 @@ const debug = require('../debug').handlers const error = require('../http-error') const $rdf = require('rdflib') const crypto = require('crypto') -const { overQuota, getContentType } = require('../utils') +const { overQuota, getContentType, HTMLDataIsland } = require('../utils') const withLock = require('../lock') // Patch parsers by request body content type @@ -18,6 +18,8 @@ const PATCH_PARSERS = { 'text/n3': require('./patch/n3-patch-parser.js') } +const dataIsland = {} + // use media-type as contentType for new RDF resource const DEFAULT_FOR_NEW_CONTENT_TYPE = 'text/turtle' @@ -116,16 +118,33 @@ function readGraph (resource) { } } debug('PATCH -- Read target file (%d bytes)', fileContents.length) + + // HTML data Island + let dataScript = '' + if (resource.contentType.includes('html')) { + [dataScript, dataIsland.contentType] = HTMLDataIsland(fileContents) + // default HTML data island + if (!dataIsland.contentType) { + dataIsland.contentType = DEFAULT_FOR_NEW_CONTENT_TYPE + } + dataIsland.fileContents = fileContents.replace(dataScript, '') + // remove data island from HTML + fileContents = dataScript.replace(/^` + const regex = `//gms` + const script = dataIsland.fileContents.match(regex) + let data = '' + console.log('alain script' + script) + if (script) data = dataIsland.fileContents.replace(script, scriptResult) + else { + if (dataIsland.fileContents.includes('')) { + data = dataIsland.fileContents.split('').join(scriptResult + '\n') + } else { + data = dataIsland.fileContents.split('
').join('\n' + scriptResult + '\n\n') + } + } + console.log('alain ' + data) + return data + } + + const contentType = dataIsland.contentType || resource.contentType + if (contentType === 'application/ld+json') { + $rdf.serialize(resourceSym, graph, resource.url, contentType, function (err, result) { if (err) return reject(error(500, `Failed to serialize after patch: ${err}`)) + if (dataIsland && dataIsland.contentType) result = addDataIsland(result) doWrite(result) }) } else { - const serialized = $rdf.serialize(resourceSym, graph, resource.url, resource.contentType) + let serialized = $rdf.serialize(resourceSym, graph, resource.url, contentType) + if (dataIsland && dataIsland.contentType) serialized = addDataIsland(serialized) doWrite(serialized) } }) diff --git a/lib/utils.js b/lib/utils.js index 0e16193e1..1038b455d 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -13,6 +13,7 @@ module.exports.getQuota = getQuota module.exports.overQuota = overQuota module.exports.getContentType = getContentType module.exports.parse = parse +module.exports.HTMLDataIsland = HTMLDataIsland const fs = require('fs') const path = require('path') @@ -128,6 +129,25 @@ function serialize (graph, baseUri, contentType) { }) } +function HTMLDataIsland (data) { + let from = '' + let dataScript = '' + const scripts = data.split('' + const RDFType = ['text/turtle', 'text/n3', 'application/ld+json', 'application/rdf+xml'] + const contentType = RDFType.find(type => script.includes(`type="${type}"`)) + if (contentType) { + dataScript = script // .replace(/^ + +Hello, world!\r +\r +` + })) + + describe('with a matching WHERE clause', describePatch({ + path: '/data-island.html', + patch: `<> a solid:InsertDeletePatch; + solid:where { ?a