solid-logic 3.0.8 → 3.0.9-15abc0b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/babel.config.js +6 -0
- package/eslint.config.js +28 -0
- package/jest.config.js +15 -8
- package/lib/acl/aclLogic.d.ts +2 -2
- package/lib/acl/aclLogic.d.ts.map +1 -1
- package/lib/authn/SolidAuthnLogic.d.ts +3 -3
- package/lib/authn/SolidAuthnLogic.d.ts.map +1 -1
- package/lib/authn/authUtil.d.ts +1 -1
- package/lib/authn/authUtil.d.ts.map +1 -1
- package/lib/chat/chatLogic.d.ts +1 -1
- package/lib/chat/chatLogic.d.ts.map +1 -1
- package/lib/inbox/inboxLogic.d.ts +1 -1
- package/lib/inbox/inboxLogic.d.ts.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/logic/CustomError.d.ts.map +1 -1
- package/lib/logic/solidLogic.d.ts +2 -2
- package/lib/logic/solidLogic.d.ts.map +1 -1
- package/lib/profile/profileLogic.d.ts +1 -1
- package/lib/profile/profileLogic.d.ts.map +1 -1
- package/lib/solid-logic.js +107 -0
- package/lib/solid-logic.js.map +1 -0
- package/lib/typeIndex/typeIndexLogic.d.ts.map +1 -1
- package/lib/types.d.ts +3 -3
- package/lib/types.d.ts.map +1 -1
- package/lib/util/containerLogic.d.ts +1 -1
- package/lib/util/containerLogic.d.ts.map +1 -1
- package/lib/util/debug.d.ts.map +1 -1
- package/lib/util/utilityLogic.d.ts +1 -1
- package/lib/util/utilityLogic.d.ts.map +1 -1
- package/lib/util/utils.d.ts +1 -1
- package/lib/util/utils.d.ts.map +1 -1
- package/package.json +46 -23
- package/rollup.config.js +29 -0
- package/src/acl/aclLogic.ts +10 -9
- package/src/authn/SolidAuthnLogic.ts +6 -6
- package/src/authn/authUtil.ts +4 -1
- package/src/chat/chatLogic.ts +76 -75
- package/src/inbox/inboxLogic.ts +20 -19
- package/src/index.ts +1 -1
- package/src/logic/CustomError.ts +6 -6
- package/src/logic/solidLogic.ts +23 -22
- package/src/logic/solidLogicSingleton.ts +3 -3
- package/src/profile/profileLogic.ts +23 -22
- package/src/typeIndex/typeIndexLogic.ts +14 -8
- package/src/types.ts +4 -3
- package/src/util/containerLogic.ts +15 -15
- package/src/util/debug.ts +4 -8
- package/src/util/utilityLogic.ts +18 -18
- package/src/util/utils.ts +12 -12
- package/src/versionInfo.ts +32 -0
- package/test/aclLogic.test.ts +5 -5
- package/test/authUtil.test.ts +1 -1
- package/test/chatLogic.test.ts +160 -154
- package/test/container.test.ts +23 -23
- package/test/helpers/dataSetup.ts +2 -1
- package/test/helpers/setup.ts +8 -3
- package/test/inboxLogic.test.ts +101 -110
- package/test/logic.test.ts +2 -2
- package/test/profileLogic.test.ts +35 -33
- package/test/solidAuthLogic.test.ts +1 -1
- package/test/typeIndexLogic.test.ts +71 -71
- package/test/utilityLogic.test.ts +46 -45
- package/test/utils.test.ts +11 -11
- package/timestamp.sh +13 -0
- package/tsconfig.json +5 -3
- package/tsconfig.test.json +8 -0
- package/lib/acl/aclLogic.js +0 -167
- package/lib/acl/aclLogic.js.map +0 -1
- package/lib/authSession/authSession.js +0 -8
- package/lib/authSession/authSession.js.map +0 -1
- package/lib/authn/SolidAuthnLogic.js +0 -191
- package/lib/authn/SolidAuthnLogic.js.map +0 -1
- package/lib/authn/authUtil.js +0 -102
- package/lib/authn/authUtil.js.map +0 -1
- package/lib/chat/chatLogic.js +0 -272
- package/lib/chat/chatLogic.js.map +0 -1
- package/lib/inbox/inboxLogic.js +0 -138
- package/lib/inbox/inboxLogic.js.map +0 -1
- package/lib/index.js +0 -29
- package/lib/index.js.map +0 -1
- package/lib/issuer/issuerLogic.js +0 -52
- package/lib/issuer/issuerLogic.js.map +0 -1
- package/lib/logic/CustomError.js +0 -89
- package/lib/logic/CustomError.js.map +0 -1
- package/lib/logic/solidLogic.js +0 -101
- package/lib/logic/solidLogic.js.map +0 -1
- package/lib/logic/solidLogicSingleton.js +0 -94
- package/lib/logic/solidLogicSingleton.js.map +0 -1
- package/lib/profile/profileLogic.js +0 -255
- package/lib/profile/profileLogic.js.map +0 -1
- package/lib/typeIndex/typeIndexLogic.js +0 -392
- package/lib/typeIndex/typeIndexLogic.js.map +0 -1
- package/lib/types.js +0 -3
- package/lib/types.js.map +0 -1
- package/lib/util/containerLogic.js +0 -102
- package/lib/util/containerLogic.js.map +0 -1
- package/lib/util/debug.js +0 -40
- package/lib/util/debug.js.map +0 -1
- package/lib/util/ns.js +0 -44
- package/lib/util/ns.js.map +0 -1
- package/lib/util/utilityLogic.js +0 -283
- package/lib/util/utilityLogic.js.map +0 -1
- package/lib/util/utils.js +0 -47
- package/lib/util/utils.js.map +0 -1
package/src/inbox/inboxLogic.ts
CHANGED
|
@@ -1,53 +1,54 @@
|
|
|
1
|
-
import { NamedNode
|
|
2
|
-
import { InboxLogic } from
|
|
3
|
-
import { getArchiveUrl } from
|
|
1
|
+
import { NamedNode } from 'rdflib'
|
|
2
|
+
import { InboxLogic } from '../types'
|
|
3
|
+
import { getArchiveUrl } from '../util/utils'
|
|
4
4
|
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
5
6
|
export function createInboxLogic(store, profileLogic, utilityLogic, containerLogic, aclLogic): InboxLogic {
|
|
6
7
|
|
|
7
8
|
async function createInboxFor(peerWebId: string, nick: string) {
|
|
8
|
-
const myWebId: NamedNode = await profileLogic.loadMe()
|
|
9
|
-
const podRoot: NamedNode = await profileLogic.getPodRoot(myWebId)
|
|
10
|
-
const ourInbox = `${podRoot.value}p2p-inboxes/${encodeURIComponent(nick)}
|
|
11
|
-
await containerLogic.createContainer(ourInbox)
|
|
9
|
+
const myWebId: NamedNode = await profileLogic.loadMe()
|
|
10
|
+
const podRoot: NamedNode = await profileLogic.getPodRoot(myWebId)
|
|
11
|
+
const ourInbox = `${podRoot.value}p2p-inboxes/${encodeURIComponent(nick)}/`
|
|
12
|
+
await containerLogic.createContainer(ourInbox)
|
|
12
13
|
// const aclDocUrl = await aclLogic.findAclDocUrl(ourInbox);
|
|
13
14
|
await utilityLogic.setSinglePeerAccess({
|
|
14
15
|
ownerWebId: myWebId.value,
|
|
15
16
|
peerWebId,
|
|
16
17
|
accessToModes: 'acl:Append',
|
|
17
18
|
target: ourInbox
|
|
18
|
-
})
|
|
19
|
-
return ourInbox
|
|
19
|
+
})
|
|
20
|
+
return ourInbox
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
async function getNewMessages(
|
|
23
24
|
user?: NamedNode
|
|
24
25
|
): Promise<NamedNode[]> {
|
|
25
26
|
if (!user) {
|
|
26
|
-
user = await profileLogic.loadMe()
|
|
27
|
+
user = await profileLogic.loadMe()
|
|
27
28
|
}
|
|
28
|
-
const inbox = await profileLogic.getMainInbox(user)
|
|
29
|
-
const urls = await containerLogic.getContainerMembers(inbox)
|
|
30
|
-
return urls.filter(url => !containerLogic.isContainer(url))
|
|
29
|
+
const inbox = await profileLogic.getMainInbox(user)
|
|
30
|
+
const urls = await containerLogic.getContainerMembers(inbox)
|
|
31
|
+
return urls.filter(url => !containerLogic.isContainer(url))
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
async function markAsRead(url: string, date: Date) {
|
|
34
|
-
const downloaded = await store.fetcher._fetch(url)
|
|
35
|
+
const downloaded = await store.fetcher._fetch(url)
|
|
35
36
|
if (downloaded.status !== 200) {
|
|
36
|
-
throw new Error(`Not OK! ${url}`)
|
|
37
|
+
throw new Error(`Not OK! ${url}`)
|
|
37
38
|
}
|
|
38
|
-
const archiveUrl = getArchiveUrl(url, date)
|
|
39
|
+
const archiveUrl = getArchiveUrl(url, date)
|
|
39
40
|
const options = {
|
|
40
41
|
method: 'PUT',
|
|
41
42
|
body: await downloaded.text(),
|
|
42
43
|
headers: [
|
|
43
44
|
['Content-Type', downloaded.headers.get('Content-Type') || 'application/octet-stream']
|
|
44
45
|
]
|
|
45
|
-
}
|
|
46
|
-
const uploaded = await store.fetcher._fetch(archiveUrl, options)
|
|
46
|
+
}
|
|
47
|
+
const uploaded = await store.fetcher._fetch(archiveUrl, options)
|
|
47
48
|
if (uploaded.status.toString()[0] === '2') {
|
|
48
49
|
await store.fetcher._fetch(url, {
|
|
49
50
|
method: 'DELETE'
|
|
50
|
-
})
|
|
51
|
+
})
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
return {
|
package/src/index.ts
CHANGED
|
@@ -9,7 +9,7 @@ const store = solidLogicSingleton.store
|
|
|
9
9
|
export { ACL_LINK } from './acl/aclLogic'
|
|
10
10
|
export { offlineTestID, appContext } from './authn/authUtil'
|
|
11
11
|
export { getSuggestedIssuers } from './issuer/issuerLogic'
|
|
12
|
-
export { AppDetails, SolidNamespace, AuthenticationContext, SolidLogic } from './types'
|
|
12
|
+
export type { AppDetails, SolidNamespace, AuthenticationContext, SolidLogic } from './types'
|
|
13
13
|
export { UnauthorizedError, CrossOriginForbiddenError, SameOriginForbiddenError, NotFoundError, FetchError, NotEditableError, WebOperationError } from './logic/CustomError'
|
|
14
14
|
|
|
15
15
|
export {
|
package/src/logic/CustomError.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
class CustomError extends Error {
|
|
2
2
|
constructor(message?: string) {
|
|
3
|
-
super(message)
|
|
3
|
+
super(message)
|
|
4
4
|
// see: typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html
|
|
5
|
-
Object.setPrototypeOf(this, new.target.prototype)
|
|
6
|
-
this.name = new.target.name
|
|
5
|
+
Object.setPrototypeOf(this, new.target.prototype) // restore prototype chain
|
|
6
|
+
this.name = new.target.name // stack traces display correctly now
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -20,10 +20,10 @@ export class NotEditableError extends CustomError { }
|
|
|
20
20
|
export class WebOperationError extends CustomError {}
|
|
21
21
|
|
|
22
22
|
export class FetchError extends CustomError {
|
|
23
|
-
status: number
|
|
23
|
+
status: number
|
|
24
24
|
|
|
25
25
|
constructor(status: number, message?: string) {
|
|
26
|
-
super(message)
|
|
27
|
-
this.status = status
|
|
26
|
+
super(message)
|
|
27
|
+
this.status = status
|
|
28
28
|
}
|
|
29
29
|
}
|
package/src/logic/solidLogic.ts
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import { Session } from
|
|
2
|
-
import * as rdf from
|
|
3
|
-
import { LiveStore, NamedNode, Statement } from
|
|
4
|
-
import { createAclLogic } from
|
|
5
|
-
import { SolidAuthnLogic } from
|
|
6
|
-
import { createChatLogic } from
|
|
7
|
-
import { createInboxLogic } from
|
|
8
|
-
import { createProfileLogic } from
|
|
9
|
-
import { createTypeIndexLogic } from
|
|
10
|
-
import { createContainerLogic } from
|
|
11
|
-
import { createUtilityLogic } from
|
|
12
|
-
import { AuthnLogic, SolidLogic } from
|
|
13
|
-
import * as debug from
|
|
1
|
+
import { Session } from '@inrupt/solid-client-authn-browser'
|
|
2
|
+
import * as rdf from 'rdflib'
|
|
3
|
+
import { LiveStore, NamedNode, Statement } from 'rdflib'
|
|
4
|
+
import { createAclLogic } from '../acl/aclLogic'
|
|
5
|
+
import { SolidAuthnLogic } from '../authn/SolidAuthnLogic'
|
|
6
|
+
import { createChatLogic } from '../chat/chatLogic'
|
|
7
|
+
import { createInboxLogic } from '../inbox/inboxLogic'
|
|
8
|
+
import { createProfileLogic } from '../profile/profileLogic'
|
|
9
|
+
import { createTypeIndexLogic } from '../typeIndex/typeIndexLogic'
|
|
10
|
+
import { createContainerLogic } from '../util/containerLogic'
|
|
11
|
+
import { createUtilityLogic } from '../util/utilityLogic'
|
|
12
|
+
import { AuthnLogic, SolidLogic } from '../types'
|
|
13
|
+
import * as debug from '../util/debug'
|
|
14
14
|
/*
|
|
15
15
|
** It is important to distinquish `fetch`, a function provided by the browser
|
|
16
16
|
** and `Fetcher`, a helper object for the rdflib Store which turns it
|
|
17
17
|
** into a `ConnectedStore` or a `LiveStore`. A Fetcher object is
|
|
18
18
|
** available at store.fetcher, and `fetch` function at `store.fetcher._fetch`,
|
|
19
19
|
*/
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
21
|
export function createSolidLogic(specialFetch: { fetch: (url: any, requestInit: any) => any }, session: Session): SolidLogic {
|
|
21
22
|
|
|
22
|
-
debug.log(
|
|
23
|
+
debug.log('SolidLogic: Unique instance created. There should only be one of these.')
|
|
23
24
|
const store: LiveStore = rdf.graph() as LiveStore
|
|
24
|
-
rdf.fetcher(store, {fetch: specialFetch.fetch})
|
|
25
|
-
store.updater = new rdf.UpdateManager(store)
|
|
25
|
+
rdf.fetcher(store, {fetch: specialFetch.fetch}) // Attach a web I/O module, store.fetcher
|
|
26
|
+
store.updater = new rdf.UpdateManager(store) // Add real-time live updates store.updater
|
|
26
27
|
store.features = [] // disable automatic node merging on store load
|
|
27
28
|
|
|
28
29
|
const authn: AuthnLogic = new SolidAuthnLogic(session)
|
|
@@ -37,7 +38,7 @@ export function createSolidLogic(specialFetch: { fetch: (url: any, requestInit:
|
|
|
37
38
|
debug.log('SolidAuthnLogic initialized')
|
|
38
39
|
|
|
39
40
|
function load(doc: NamedNode | NamedNode[] | string) {
|
|
40
|
-
return store.fetcher.load(doc)
|
|
41
|
+
return store.fetcher.load(doc)
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
// @@@@ use the one in rdflib.js when it is available and delete this
|
|
@@ -48,16 +49,16 @@ export function createSolidLogic(specialFetch: { fetch: (url: any, requestInit:
|
|
|
48
49
|
return new Promise((resolve, reject) => {
|
|
49
50
|
store.updater.update(del, ins, function (_uri, ok, errorBody) {
|
|
50
51
|
if (!ok) {
|
|
51
|
-
reject(new Error(errorBody))
|
|
52
|
+
reject(new Error(errorBody))
|
|
52
53
|
} else {
|
|
53
|
-
resolve()
|
|
54
|
+
resolve()
|
|
54
55
|
}
|
|
55
|
-
})
|
|
56
|
-
})
|
|
56
|
+
}) // callback
|
|
57
|
+
}) // promise
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
function clearStore() {
|
|
60
|
-
store.statements.slice().forEach(store.remove.bind(store))
|
|
61
|
+
store.statements.slice().forEach(store.remove.bind(store))
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as debug from
|
|
2
|
-
import { authSession } from
|
|
3
|
-
import { createSolidLogic } from
|
|
1
|
+
import * as debug from '../util/debug'
|
|
2
|
+
import { authSession } from '../authSession/authSession'
|
|
3
|
+
import { createSolidLogic } from './solidLogic'
|
|
4
4
|
|
|
5
5
|
const _fetch = async (url, requestInit) => {
|
|
6
6
|
const omitCreds = requestInit && requestInit.credentials && requestInit.credentials == 'omit'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { NamedNode } from
|
|
2
|
-
import { CrossOriginForbiddenError, FetchError, NotEditableError, SameOriginForbiddenError, UnauthorizedError, WebOperationError } from
|
|
3
|
-
import * as debug from
|
|
4
|
-
import { ns as namespace } from '../util/ns'
|
|
5
|
-
import { differentOrigin, suggestPreferencesFile } from
|
|
6
|
-
import { ProfileLogic } from
|
|
1
|
+
import { NamedNode } from 'rdflib'
|
|
2
|
+
import { CrossOriginForbiddenError, FetchError, NotEditableError, SameOriginForbiddenError, UnauthorizedError, WebOperationError } from '../logic/CustomError'
|
|
3
|
+
import * as debug from '../util/debug'
|
|
4
|
+
import { ns as namespace } from '../util/ns'
|
|
5
|
+
import { differentOrigin, suggestPreferencesFile } from '../util/utils'
|
|
6
|
+
import { ProfileLogic } from '../types'
|
|
7
7
|
|
|
8
8
|
export function createProfileLogic(store, authn, utilityLogic): ProfileLogic {
|
|
9
9
|
const ns = namespace
|
|
@@ -17,6 +17,7 @@ export function createProfileLogic(store, authn, utilityLogic): ProfileLogic {
|
|
|
17
17
|
async function silencedLoadPreferences(user: NamedNode): Promise <NamedNode | undefined> {
|
|
18
18
|
try {
|
|
19
19
|
return await loadPreferences(user)
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
21
|
} catch (err) {
|
|
21
22
|
return undefined
|
|
22
23
|
}
|
|
@@ -54,13 +55,13 @@ export function createProfileLogic(store, authn, utilityLogic): ProfileLogic {
|
|
|
54
55
|
const msg = `Unable to load preference of user ${user}: ${err}`
|
|
55
56
|
debug.warn(msg)
|
|
56
57
|
if (err.response.status === 401) {
|
|
57
|
-
throw new UnauthorizedError()
|
|
58
|
+
throw new UnauthorizedError()
|
|
58
59
|
}
|
|
59
60
|
if (err.response.status === 403) {
|
|
60
61
|
if (differentOrigin(preferencesFile)) {
|
|
61
|
-
throw new CrossOriginForbiddenError()
|
|
62
|
+
throw new CrossOriginForbiddenError()
|
|
62
63
|
}
|
|
63
|
-
throw new SameOriginForbiddenError()
|
|
64
|
+
throw new SameOriginForbiddenError()
|
|
64
65
|
}
|
|
65
66
|
/*if (err.response.status === 404) {
|
|
66
67
|
throw new NotFoundError();
|
|
@@ -72,7 +73,7 @@ export function createProfileLogic(store, authn, utilityLogic): ProfileLogic {
|
|
|
72
73
|
|
|
73
74
|
async function loadProfile (user: NamedNode):Promise <NamedNode> {
|
|
74
75
|
if (!user) {
|
|
75
|
-
throw new Error(
|
|
76
|
+
throw new Error('loadProfile: no user given.')
|
|
76
77
|
}
|
|
77
78
|
try {
|
|
78
79
|
await store.fetcher.load(user.doc())
|
|
@@ -83,33 +84,33 @@ export function createProfileLogic(store, authn, utilityLogic): ProfileLogic {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
async function loadMe(): Promise<NamedNode> {
|
|
86
|
-
const me = authn.currentUser()
|
|
87
|
+
const me = authn.currentUser()
|
|
87
88
|
if (me === null) {
|
|
88
|
-
throw new Error(
|
|
89
|
+
throw new Error('Current user not found! Not logged in?')
|
|
89
90
|
}
|
|
90
|
-
await store.fetcher.load(me.doc())
|
|
91
|
-
return me
|
|
91
|
+
await store.fetcher.load(me.doc())
|
|
92
|
+
return me
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
function getPodRoot(user: NamedNode): NamedNode {
|
|
95
|
-
const podRoot = findStorage(user)
|
|
96
|
+
const podRoot = findStorage(user)
|
|
96
97
|
if (!podRoot) {
|
|
97
|
-
throw new Error(
|
|
98
|
+
throw new Error('User pod root not found!')
|
|
98
99
|
}
|
|
99
|
-
return podRoot as NamedNode
|
|
100
|
+
return podRoot as NamedNode
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
async function getMainInbox(user: NamedNode): Promise<NamedNode> {
|
|
103
|
-
await store.fetcher.load(user)
|
|
104
|
-
const mainInbox = store.any(user, ns.ldp(
|
|
104
|
+
await store.fetcher.load(user)
|
|
105
|
+
const mainInbox = store.any(user, ns.ldp('inbox'), undefined, user.doc())
|
|
105
106
|
if (!mainInbox) {
|
|
106
|
-
throw new Error(
|
|
107
|
+
throw new Error('User main inbox not found!')
|
|
107
108
|
}
|
|
108
|
-
return mainInbox as NamedNode
|
|
109
|
+
return mainInbox as NamedNode
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
function findStorage(me: NamedNode) {
|
|
112
|
-
return store.any(me, ns.space(
|
|
113
|
+
return store.any(me, ns.space('storage'), undefined, me.doc())
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
return {
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
import { NamedNode, st, sym } from 'rdflib'
|
|
2
2
|
import { ScopedApp, TypeIndexLogic, TypeIndexScope } from '../types'
|
|
3
|
-
import * as debug from
|
|
3
|
+
import * as debug from '../util/debug'
|
|
4
4
|
import { ns as namespace } from '../util/ns'
|
|
5
|
-
import { newThing } from
|
|
5
|
+
import { newThing } from '../util/utils'
|
|
6
6
|
|
|
7
7
|
export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic): TypeIndexLogic {
|
|
8
8
|
const ns = namespace
|
|
9
9
|
|
|
10
10
|
function getRegistrations(instance, theClass) {
|
|
11
11
|
return store
|
|
12
|
-
.each(undefined, ns.solid(
|
|
12
|
+
.each(undefined, ns.solid('instance'), instance)
|
|
13
13
|
.filter((r) => {
|
|
14
|
-
return store.holds(r, ns.solid(
|
|
15
|
-
})
|
|
14
|
+
return store.holds(r, ns.solid('forClass'), theClass)
|
|
15
|
+
})
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
async function loadTypeIndexesFor(user: NamedNode): Promise<Array<TypeIndexScope>> {
|
|
19
|
-
if (!user) throw new Error(
|
|
19
|
+
if (!user) throw new Error('loadTypeIndexesFor: No user given')
|
|
20
20
|
const profile = await profileLogic.loadProfile(user)
|
|
21
21
|
|
|
22
22
|
const suggestion = suggestPublicTypeIndex(user)
|
|
23
23
|
let publicTypeIndex
|
|
24
24
|
try {
|
|
25
25
|
publicTypeIndex = await utilityLogic.followOrCreateLink(user, ns.solid('publicTypeIndex') as NamedNode, suggestion, profile)
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
26
27
|
} catch (err) {
|
|
27
28
|
const message = `User ${user} has no pointer in profile to publicTypeIndex file.`
|
|
28
29
|
debug.warn(message)
|
|
@@ -32,6 +33,7 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic):
|
|
|
32
33
|
let preferencesFile
|
|
33
34
|
try {
|
|
34
35
|
preferencesFile = await profileLogic.silencedLoadPreferences(user)
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
35
37
|
} catch (err) {
|
|
36
38
|
preferencesFile = null
|
|
37
39
|
}
|
|
@@ -44,8 +46,9 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic):
|
|
|
44
46
|
let privateTypeIndex
|
|
45
47
|
try {
|
|
46
48
|
privateTypeIndex = store.any(user, ns.solid('privateTypeIndex'), undefined, profile) ||
|
|
47
|
-
await utilityLogic.followOrCreateLink(user, ns.solid('privateTypeIndex') as NamedNode, suggestedPrivateTypeIndex, preferencesFile)
|
|
48
|
-
|
|
49
|
+
await utilityLogic.followOrCreateLink(user, ns.solid('privateTypeIndex') as NamedNode, suggestedPrivateTypeIndex, preferencesFile)
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
|
+
} catch (err) {
|
|
49
52
|
const message = `User ${user} has no pointer in preference file to privateTypeIndex file.`
|
|
50
53
|
debug.warn(message)
|
|
51
54
|
}
|
|
@@ -68,6 +71,7 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic):
|
|
|
68
71
|
let preferencesFile
|
|
69
72
|
try {
|
|
70
73
|
preferencesFile = await profileLogic.silencedLoadPreferences(user)
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
71
75
|
} catch (err) {
|
|
72
76
|
const message = `User ${user} has no pointer in profile to preferences file.`
|
|
73
77
|
debug.warn(message)
|
|
@@ -78,6 +82,7 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic):
|
|
|
78
82
|
)
|
|
79
83
|
let result = []
|
|
80
84
|
for (const org of communities) {
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
86
|
result = result.concat(await loadTypeIndexesFor(org as NamedNode) as any)
|
|
82
87
|
}
|
|
83
88
|
return result
|
|
@@ -93,6 +98,7 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic):
|
|
|
93
98
|
const scopes = await loadAllTypeIndexes(user)
|
|
94
99
|
let scopedApps = []
|
|
95
100
|
for (const scope of scopes) {
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
96
102
|
const scopedApps0 = await getScopedAppsFromIndex(scope, klass) as any
|
|
97
103
|
scopedApps = scopedApps.concat(scopedApps0)
|
|
98
104
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Session } from
|
|
2
|
-
import { LiveStore, NamedNode, Statement } from
|
|
1
|
+
import { Session } from '@inrupt/solid-client-authn-browser'
|
|
2
|
+
import { LiveStore, NamedNode, Statement } from 'rdflib'
|
|
3
3
|
|
|
4
4
|
export type AppDetails = {
|
|
5
5
|
noun: string
|
|
@@ -72,7 +72,7 @@ export interface ProfileLogic {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
export interface AclLogic {
|
|
75
|
-
findAclDocUrl: (url: NamedNode) => Promise<
|
|
75
|
+
findAclDocUrl: (url: NamedNode) => Promise<string | undefined>,
|
|
76
76
|
setACLUserPublic: (docURI: string, me: NamedNode,
|
|
77
77
|
options: {
|
|
78
78
|
defaultForNew?: boolean,
|
|
@@ -103,6 +103,7 @@ export interface TypeIndexLogic {
|
|
|
103
103
|
suggestPublicTypeIndex: (me: NamedNode) => NamedNode,
|
|
104
104
|
suggestPrivateTypeIndex: (preferencesFile: NamedNode) => NamedNode,
|
|
105
105
|
registerInTypeIndex: (instance: NamedNode, index: NamedNode, theClass: NamedNode) => Promise<NamedNode | null>,
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
106
107
|
deleteTypeIndexRegistration: (item: any) => Promise<void>
|
|
107
108
|
getScopedAppsFromIndex: (scope: TypeIndexScope, theClass: NamedNode | null) => Promise<ScopedApp[]>
|
|
108
109
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NamedNode, Statement, sym } from
|
|
1
|
+
import { NamedNode, Statement, sym } from 'rdflib'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Container-related class
|
|
@@ -9,40 +9,40 @@ export function createContainerLogic(store) {
|
|
|
9
9
|
return store
|
|
10
10
|
.statementsMatching(
|
|
11
11
|
containerNode,
|
|
12
|
-
sym(
|
|
12
|
+
sym('http://www.w3.org/ns/ldp#contains'),
|
|
13
13
|
undefined
|
|
14
14
|
)
|
|
15
|
-
.map((st: Statement) => st.object as NamedNode)
|
|
15
|
+
.map((st: Statement) => st.object as NamedNode)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function isContainer(url: NamedNode) {
|
|
19
|
-
const nodeToString = url.value
|
|
20
|
-
return nodeToString.charAt(nodeToString.length - 1) ===
|
|
19
|
+
const nodeToString = url.value
|
|
20
|
+
return nodeToString.charAt(nodeToString.length - 1) === '/'
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
async function createContainer(url: string) {
|
|
24
|
-
const stringToNode = sym(url)
|
|
24
|
+
const stringToNode = sym(url)
|
|
25
25
|
if (!isContainer(stringToNode)) {
|
|
26
|
-
throw new Error(`Not a container URL ${url}`)
|
|
26
|
+
throw new Error(`Not a container URL ${url}`)
|
|
27
27
|
}
|
|
28
28
|
// Copied from https://github.com/solidos/solid-crud-tests/blob/v3.1.0/test/surface/create-container.test.ts#L56-L64
|
|
29
29
|
const result = await store.fetcher._fetch(url, {
|
|
30
|
-
method:
|
|
30
|
+
method: 'PUT',
|
|
31
31
|
headers: {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
'Content-Type': 'text/turtle',
|
|
33
|
+
'If-None-Match': '*',
|
|
34
34
|
Link: '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"', // See https://github.com/solidos/node-solid-server/issues/1465
|
|
35
35
|
},
|
|
36
|
-
body:
|
|
37
|
-
})
|
|
36
|
+
body: ' ', // work around https://github.com/michielbdejong/community-server/issues/4#issuecomment-776222863
|
|
37
|
+
})
|
|
38
38
|
if (result.status.toString()[0] !== '2') {
|
|
39
|
-
throw new Error(`Not OK: got ${result.status} response while creating container at ${url}`)
|
|
39
|
+
throw new Error(`Not OK: got ${result.status} response while creating container at ${url}`)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
async function getContainerMembers(containerUrl: NamedNode): Promise<NamedNode[]> {
|
|
44
|
-
await store.fetcher.load(containerUrl)
|
|
45
|
-
return getContainerElements(containerUrl)
|
|
44
|
+
await store.fetcher.load(containerUrl)
|
|
45
|
+
return getContainerElements(containerUrl)
|
|
46
46
|
}
|
|
47
47
|
return {
|
|
48
48
|
isContainer,
|
package/src/util/debug.ts
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
export function log(...args: any[]): void {
|
|
3
|
-
|
|
4
|
-
console.log(...args);
|
|
3
|
+
console.log(...args)
|
|
5
4
|
}
|
|
6
5
|
|
|
7
6
|
export function warn(...args: any[]): void {
|
|
8
|
-
|
|
9
|
-
console.warn(...args);
|
|
7
|
+
console.warn(...args)
|
|
10
8
|
}
|
|
11
9
|
|
|
12
10
|
export function error(...args: any[]): void {
|
|
13
|
-
|
|
14
|
-
console.error(...args);
|
|
11
|
+
console.error(...args)
|
|
15
12
|
}
|
|
16
13
|
|
|
17
14
|
export function trace(...args: any[]): void {
|
|
18
|
-
|
|
19
|
-
console.trace(...args);
|
|
15
|
+
console.trace(...args)
|
|
20
16
|
}
|
package/src/util/utilityLogic.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { NamedNode, st, sym } from
|
|
2
|
-
import { CrossOriginForbiddenError, FetchError, NotEditableError, SameOriginForbiddenError, UnauthorizedError, WebOperationError } from
|
|
3
|
-
import * as debug from '../util/debug'
|
|
4
|
-
import { differentOrigin } from
|
|
1
|
+
import { NamedNode, st, sym } from 'rdflib'
|
|
2
|
+
import { CrossOriginForbiddenError, FetchError, NotEditableError, SameOriginForbiddenError, UnauthorizedError, WebOperationError } from '../logic/CustomError'
|
|
3
|
+
import * as debug from '../util/debug'
|
|
4
|
+
import { differentOrigin } from './utils'
|
|
5
5
|
|
|
6
6
|
export function createUtilityLogic(store, aclLogic, containerLogic) {
|
|
7
7
|
|
|
@@ -9,16 +9,16 @@ export function createUtilityLogic(store, aclLogic, containerLogic) {
|
|
|
9
9
|
try {
|
|
10
10
|
if (containerLogic.isContainer(containerNode)) {
|
|
11
11
|
const aclDocUrl = await aclLogic.findAclDocUrl(containerNode)
|
|
12
|
-
await store.fetcher._fetch(aclDocUrl, { method:
|
|
13
|
-
const containerMembers = await containerLogic.getContainerMembers(containerNode)
|
|
12
|
+
await store.fetcher._fetch(aclDocUrl, { method: 'DELETE' })
|
|
13
|
+
const containerMembers = await containerLogic.getContainerMembers(containerNode)
|
|
14
14
|
await Promise.all(
|
|
15
15
|
containerMembers.map((url) => recursiveDelete(url))
|
|
16
|
-
)
|
|
16
|
+
)
|
|
17
17
|
}
|
|
18
|
-
const nodeToStringHere = containerNode.value
|
|
19
|
-
return store.fetcher._fetch(nodeToStringHere, { method:
|
|
18
|
+
const nodeToStringHere = containerNode.value
|
|
19
|
+
return store.fetcher._fetch(nodeToStringHere, { method: 'DELETE' })
|
|
20
20
|
} catch (e) {
|
|
21
|
-
|
|
21
|
+
debug.log(`Please manually remove ${containerNode.value} from your system.`, e)
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -43,13 +43,13 @@ export function createUtilityLogic(store, aclLogic, containerLogic) {
|
|
|
43
43
|
await store.fetcher.load(doc)
|
|
44
44
|
} else {
|
|
45
45
|
if (err.response.status === 401) {
|
|
46
|
-
throw new UnauthorizedError()
|
|
46
|
+
throw new UnauthorizedError()
|
|
47
47
|
}
|
|
48
48
|
if (err.response.status === 403) {
|
|
49
49
|
if (differentOrigin(doc)) {
|
|
50
|
-
throw new CrossOriginForbiddenError()
|
|
50
|
+
throw new CrossOriginForbiddenError()
|
|
51
51
|
}
|
|
52
|
-
throw new SameOriginForbiddenError()
|
|
52
|
+
throw new SameOriginForbiddenError()
|
|
53
53
|
}
|
|
54
54
|
const msg = 'createIfNotExists doc load error NOT 404: ' + doc + ': ' + err
|
|
55
55
|
throw new FetchError(err.status, err.message + msg)
|
|
@@ -87,7 +87,7 @@ export function createUtilityLogic(store, aclLogic, containerLogic) {
|
|
|
87
87
|
// store.fetcher.webOperation('PUT', object, { data: '', contentType: 'text/turtle'})
|
|
88
88
|
} catch (err) {
|
|
89
89
|
debug.warn(`followOrCreateLink: Error loading or saving new linked document: ${object}: ${err}`)
|
|
90
|
-
throw err
|
|
90
|
+
throw err
|
|
91
91
|
}
|
|
92
92
|
return object
|
|
93
93
|
}
|
|
@@ -134,15 +134,15 @@ export function createUtilityLogic(store, aclLogic, containerLogic) {
|
|
|
134
134
|
headers: [
|
|
135
135
|
['Content-Type', 'text/turtle']
|
|
136
136
|
]
|
|
137
|
-
})
|
|
137
|
+
})
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
async function createEmptyRdfDoc(doc: NamedNode, comment: string) {
|
|
141
|
-
await store.fetcher.webOperation(
|
|
141
|
+
await store.fetcher.webOperation('PUT', doc.uri, {
|
|
142
142
|
data: `# ${new Date()} ${comment}
|
|
143
143
|
`,
|
|
144
|
-
contentType:
|
|
145
|
-
})
|
|
144
|
+
contentType: 'text/turtle',
|
|
145
|
+
})
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
return {
|
package/src/util/utils.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { NamedNode, sym } from
|
|
1
|
+
import { NamedNode, sym } from 'rdflib'
|
|
2
2
|
|
|
3
3
|
export function newThing(doc: NamedNode): NamedNode {
|
|
4
|
-
return sym(doc.uri +
|
|
4
|
+
return sym(doc.uri + '#' + 'id' + ('' + Date.now()))
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export function uniqueNodes (arr: NamedNode[]): NamedNode[] {
|
|
@@ -13,21 +13,21 @@ export function uniqueNodes (arr: NamedNode[]): NamedNode[] {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export function getArchiveUrl(baseUrl: string, date: Date) {
|
|
16
|
-
const year = date.getUTCFullYear()
|
|
17
|
-
const month = ('0' + (date.getUTCMonth()+1)).slice(-2)
|
|
18
|
-
const day = ('0' + (date.getUTCDate())).slice(-2)
|
|
19
|
-
const parts = baseUrl.split('/')
|
|
20
|
-
const filename = parts[parts.length -1 ]
|
|
21
|
-
return new URL(`./archive/${year}/${month}/${day}/${filename}`, baseUrl).toString()
|
|
16
|
+
const year = date.getUTCFullYear()
|
|
17
|
+
const month = ('0' + (date.getUTCMonth()+1)).slice(-2)
|
|
18
|
+
const day = ('0' + (date.getUTCDate())).slice(-2)
|
|
19
|
+
const parts = baseUrl.split('/')
|
|
20
|
+
const filename = parts[parts.length -1 ]
|
|
21
|
+
return new URL(`./archive/${year}/${month}/${day}/${filename}`, baseUrl).toString()
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function differentOrigin(doc): boolean {
|
|
25
25
|
if (!doc) {
|
|
26
|
-
return true
|
|
26
|
+
return true
|
|
27
27
|
}
|
|
28
28
|
return (
|
|
29
29
|
`${window.location.origin}/` !== new URL(doc.value).origin
|
|
30
|
-
)
|
|
30
|
+
)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export function suggestPreferencesFile (me:NamedNode) {
|
|
@@ -47,6 +47,6 @@ export function determineChatContainer(
|
|
|
47
47
|
const chatContainerStr = new URL(
|
|
48
48
|
`IndividualChats/${new URL(invitee.value).host}/`,
|
|
49
49
|
podRoot.value
|
|
50
|
-
).toString()
|
|
51
|
-
return new NamedNode(chatContainerStr)
|
|
50
|
+
).toString()
|
|
51
|
+
return new NamedNode(chatContainerStr)
|
|
52
52
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
buildTime: '2025-09-03T13:35:44Z',
|
|
3
|
+
commit: '15abc0b75e2146041079c8477db20f79efd31388',
|
|
4
|
+
npmInfo: {
|
|
5
|
+
'\'solid-logic\'': '\'3.0.9\',',
|
|
6
|
+
'npm': '\'10.8.2\',',
|
|
7
|
+
'node': '\'20.19.4\',',
|
|
8
|
+
'acorn': '\'8.14.0\',',
|
|
9
|
+
'ada': '\'2.9.2\',',
|
|
10
|
+
'ares': '\'1.34.5\',',
|
|
11
|
+
'brotli': '\'1.1.0\',',
|
|
12
|
+
'cjs_module_lexer': '\'1.4.1\',',
|
|
13
|
+
'cldr': '\'47.0\',',
|
|
14
|
+
'icu': '\'77.1\',',
|
|
15
|
+
'llhttp': '\'9.2.1\',',
|
|
16
|
+
'modules': '\'115\',',
|
|
17
|
+
'napi': '\'9\',',
|
|
18
|
+
'nghttp2': '\'1.61.0\',',
|
|
19
|
+
'nghttp3': '\'0.7.0\',',
|
|
20
|
+
'ngtcp2': '\'1.1.0\',',
|
|
21
|
+
'openssl': '\'3.0.15+quic\',',
|
|
22
|
+
'simdutf': '\'6.4.2\',',
|
|
23
|
+
'tz': '\'2025b\',',
|
|
24
|
+
'undici': '\'6.21.2\',',
|
|
25
|
+
'unicode': '\'16.0\',',
|
|
26
|
+
'uv': '\'1.46.0\',',
|
|
27
|
+
'uvwasi': '\'0.0.21\',',
|
|
28
|
+
'v8': '\'11.3.244.8-node.29\',',
|
|
29
|
+
'zlib': '\'1.3.0.1-motley-82a5fec\'',
|
|
30
|
+
'}': '}',
|
|
31
|
+
}
|
|
32
|
+
}
|