Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-zucker committed Apr 20, 2020
2 parents 0eb29bd + 90abe67 commit 2858e6d
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 29 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@
"jsdoc-to-markdown": "^5.0.3",
"regenerator-runtime": "^0.13.3",
"solid-auth-cli": "^1.0.10",
"solid-namespace": "^0.2.0",
"solid-rest": "^1.1.2",
"standard": "^14.3.1",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
},
"dependencies": {
"n3": "^1.3.5"
"n3": "^1.3.5",
"solid-namespace": "^0.2.0"
}
}
21 changes: 12 additions & 9 deletions src/SolidApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ class SolidAPI {
const addItemLinks = async item => { item.links = await this.getItemLinks(item.url, options) }
await composedFetch([
addItemLinks(parsedFolder),
...parsedFolder.files.map(addItemLinks),
...parsedFolder.files.map(addItemLinks)
])
}
// DON'T LOOK FOR SUBFOLDER LINKS ...parsedFolder.folders.map(addItemLinks)
Expand Down Expand Up @@ -438,6 +438,9 @@ class SolidAPI {
...defaultWriteOptions,
...options
}
if (from.endsWith('/') || to.endsWith('/')) {
throw toFetchError(new Error(`Folders are not allowed with copyFile. Found: ${from} and ${to}`))
}
if (from.endsWith('.acl') || to.endsWith('.acl')) {
throw toFetchError(new Error(`Use copyAclFile for copying ACL files. Found: ${from} and ${to}`))
}
Expand All @@ -464,17 +467,14 @@ class SolidAPI {
* @throws {FetchError} throws when from is defined and exists, but to is undefined
* @private
*/
async _linkUrlsDefined(from, to) {
async _linkUrlsDefined (from, to) {
if (typeof from !== 'string') {
return false
}
else if ( typeof to !== 'string' && await this.itemExists(from)) {
} else if (typeof to !== 'string' && await this.itemExists(from)) {
throw toFetchError(new Error('Cannot copy link file because target location was not provided by the pod'))
}
else if ( typeof(to) !== 'string' ) {
} else if (typeof to !== 'string') {
return false
}
else {
} else {
return true
}
}
Expand Down Expand Up @@ -537,7 +537,7 @@ class SolidAPI {
if (options.agent === AGENT.TO_TARGET) {
content = content.replace(new RegExp('<' + getRootUrl(oldTargetFile) + 'profile/card#', 'g'), '</profile/card#')
content = content.replace(new RegExp('<' + getRootUrl(oldTargetFile) + 'profile/card#me>', 'g'), '</profile/card#me>')
}
}
if (options.agent === AGENT.TO_SOURCE) {
content = content.replace(new RegExp('</profile/card#', 'g'), '<' + getRootUrl(oldTargetFile) + 'profile/card#')
content = content.replace(new RegExp('</profile/card#me>', 'g'), '<' + getRootUrl(oldTargetFile) + 'profile/card#me>')
Expand Down Expand Up @@ -586,6 +586,9 @@ class SolidAPI {
if (typeof from !== 'string' || typeof to !== 'string') {
throw toFetchError(new Error(`The from and to parameters of copyFolder must be strings. Found: ${from} and ${to}`))
}
if (!from.endsWith('/') || !to.endsWith('/')) {
throw toFetchError(new Error(`Files are not allowed with copyFolder. Found: ${from} and ${to}`))
}

const { folders, files } = await this.readFolder(from)
const folderResponse = await this.createFolder(to, options)
Expand Down
8 changes: 4 additions & 4 deletions src/SolidFileClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ class SolidFileClient extends SolidApi {
return res
}

async readHead (url, options) {
let response = await super.head(url, options)
let headStr = ""
async readHead (url, options) {
const response = await super.head(url, options)
let headStr = ''
for (var pair of response.headers.entries()) {
headStr += pair[0]+ ': '+ pair[1] + "\n"
headStr += pair[0] + ': ' + pair[1] + '\n'
}
return headStr
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/errorUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class SingleResponseError extends Error {
this.ok = false
this.status = response.status
this.statusText = response.statusText
this.url=response.url
this.url = response.url
}
}

Expand Down
23 changes: 14 additions & 9 deletions src/utils/folderUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const parseFolderResponse = async (folderResponse, folderUrl = folderResponse.ur
const turtle = await folderResponse.text()

const rdf = new RdfQuery()
const quads = await rdf.queryTurtle(folderUrl, turtle, { thisDoc: '' }) // await rdf.query(folderUrl, '<' + folderUrl + '>') //
const folderRecord = _processStatements(folderUrl, quads) // '<' + folderUrl + '>'
const files = await rdf.queryTurtle(folderUrl, turtle, { thisDoc: '' }, { ldp: 'contains' })

const folderItems = []
Expand All @@ -29,7 +31,7 @@ const parseFolderResponse = async (folderResponse, folderUrl = folderResponse.ur
}
}))

return _packageFolder(folderUrl, folderItems, fileItems)
return _packageFolder(folderRecord, folderItems, fileItems)
}

/**
Expand All @@ -55,7 +57,7 @@ function _processStatements (url, stmts) {
const predicate = stm.predicate.value.replace(/.*\//, '').replace(/.*#/, '')
let object = stm.object.value.match(ianaMediaType) ? stm.object.value.replace(ianaMediaType, '') : stm.object.value.replace(/.*\//, '')
if (!predicate.match('type')) object = object.replace(/.*#/, '')
else if (object !== 'ldp#Resource' && object !== 'ldp#Container') {
if (object !== 'ldp#Resource' && object !== 'ldp#Container') {
processed[predicate] = [...(processed[predicate] || []), object.replace('#Resource', '')] // keep only contentType and ldp#BasicContainer
}
})
Expand All @@ -80,18 +82,21 @@ function _processStatements (url, stmts) {
*/
/**
* @private
* @param {string} folderUrl
* @param {string} folderRecord
* @param {Item[]} folderItems
* @param {Item[]} fileItems
* @returns {FolderData}
*/
function _packageFolder (folderUrl, folderItems, fileItems) {
function _packageFolder (folderRecord, folderItems, fileItems) {
const returnVal = {}
returnVal.type = 'folder' // for backwards compatability :-(
returnVal.itemType = 'Container'
returnVal.name = getItemName(folderUrl)
returnVal.parent = getParentUrl(folderUrl)
returnVal.url = folderUrl
returnVal.type = 'folder' // for backwards compatibility :-(
returnVal.modified = folderRecord.modified
returnVal.mtime = folderRecord.mtime
returnVal.size = folderRecord.size
returnVal.itemType = folderRecord.itemType
returnVal.name = folderRecord.name // getItemName(folderUrl.url)
returnVal.parent = folderRecord.parent // getParentUrl(folderUrl.url)
returnVal.url = folderRecord.url
returnVal.folders = folderItems
returnVal.files = fileItems

Expand Down
6 changes: 4 additions & 2 deletions src/utils/rdf-query.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
* by Jeff Zucker with contributions from Otto_A_A and Alain Bourgeois
* &copy; 2019, Jeff Zucker, may be freely distributed using an MIT license
*/
const N3 = require('n3')
const ns = require('solid-namespace')()
import * as N3 from 'n3';
import solidNS from 'solid-namespace';

const ns = solidNS();

const { DataFactory } = N3
const { namedNode, literal } = DataFactory
Expand Down
8 changes: 6 additions & 2 deletions tests/SolidApi.composed.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ describe('composed methods', () => {
test('rejects when copying to existent file with merge=KEEP_TARGET', () => {
return expect(api.copyFile(childFile.url, childFileTwo.url, { merge: MERGE.KEEP_TARGET })).rejects.toThrowError('already existed')
})
test.todo('throws some kind of error when called on folder')
test('rejects when copying from folder', () => {
return expect(api.copyFile(childOne.url, childFileTwo.url)).rejects.toBeDefined()
})
})

describe('copyFolder', () => {
Expand Down Expand Up @@ -260,7 +262,9 @@ describe('composed methods', () => {
await expect(api.itemExists(emptyFolder.url)).resolves.toBe(true)
await expect(api.get(childFile.url).then(res => res.text())).resolves.toBe(childFile.content)
})
test.todo('throws some kind of error when called on file')
test('throws some kind of error when called on file', async () => {
await expect(api.copyFolder(childFile.url, childTwo.url)).rejects.toBeDefined()
})
test.todo('throws flattened errors when it fails in multiple levels')
})
})
Expand Down
9 changes: 9 additions & 0 deletions tests/SolidApi.readFolder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,33 @@ const folderUrl = `${parentUrl}${folderName}/`
const sampleFolderWithoutLinks = {
type: 'folder',
itemType: 'Container',
modified: '2019-11-16T11:59:29Z',
mtime: '1573905569.399',
size: '4096',
name: folderName,
parent: parentUrl,
url: folderUrl,
folders: [
{
type: 'folder',
itemType: 'Container',
modified: '2019-11-16T12:06:34Z',
mtime: '1573905994.593',
name: 'js',
parent: folderUrl,
size: "4096",
url: `${folderUrl}js/`
}
],
files: [
{
type: 'text/turtle',
itemType: 'Resource',
modified: '2019-11-11T20:03:03Z',
mtime: '1573502583.164',
name: 'notes.ttl',
parent: folderUrl,
size: "16",
url: `${folderUrl}notes.ttl`
}
]
Expand Down

0 comments on commit 2858e6d

Please sign in to comment.