solid-logic 1.3.17-8a332867 → 1.3.17-a849582e
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/jest.config.js +1 -1
- package/lib/acl/aclLogic.d.ts +12 -30
- package/lib/acl/aclLogic.d.ts.map +1 -1
- package/lib/acl/aclLogic.js +151 -116
- package/lib/acl/aclLogic.js.map +1 -1
- package/lib/authn/SolidAuthnLogic.d.ts.map +1 -1
- package/lib/authn/SolidAuthnLogic.js +2 -2
- package/lib/authn/SolidAuthnLogic.js.map +1 -1
- package/lib/chat/chatLogic.d.ts +16 -0
- package/lib/chat/chatLogic.d.ts.map +1 -0
- package/lib/chat/{ChatLogic.js → chatLogic.js} +82 -87
- package/lib/chat/chatLogic.js.map +1 -0
- package/lib/discovery/discoveryLogic.d.ts +6 -9
- package/lib/discovery/discoveryLogic.d.ts.map +1 -1
- package/lib/discovery/discoveryLogic.js +95 -89
- package/lib/discovery/discoveryLogic.js.map +1 -1
- package/lib/inbox/inboxLogic.d.ts +7 -0
- package/lib/inbox/inboxLogic.d.ts.map +1 -0
- package/lib/inbox/{InboxLogic.js → inboxLogic.js} +58 -64
- package/lib/inbox/inboxLogic.js.map +1 -0
- package/lib/index.d.ts +10 -13
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +76 -44
- package/lib/index.js.map +1 -1
- package/lib/logic/CustomError.d.ts +4 -0
- package/lib/logic/CustomError.d.ts.map +1 -1
- package/lib/logic/CustomError.js +17 -1
- package/lib/logic/CustomError.js.map +1 -1
- package/lib/logic/solidLogicSingleton.d.ts +35 -3
- package/lib/logic/solidLogicSingleton.d.ts.map +1 -1
- package/lib/logic/solidLogicSingleton.js +87 -8
- package/lib/logic/solidLogicSingleton.js.map +1 -1
- package/lib/profile/profileLogic.d.ts +13 -0
- package/lib/profile/profileLogic.d.ts.map +1 -0
- package/lib/profile/profileLogic.js +268 -0
- package/lib/profile/profileLogic.js.map +1 -0
- package/lib/typeIndex/typeIndexLogic.d.ts +31 -21
- package/lib/typeIndex/typeIndexLogic.d.ts.map +1 -1
- package/lib/typeIndex/typeIndexLogic.js +650 -295
- package/lib/typeIndex/typeIndexLogic.js.map +1 -1
- package/lib/types.d.ts +17 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/util/containerLogic.d.ts +11 -0
- package/lib/util/containerLogic.d.ts.map +1 -0
- package/lib/{profile/ProfileLogic.js → util/containerLogic.js} +53 -44
- package/lib/util/containerLogic.js.map +1 -0
- package/lib/util/utilityLogic.d.ts +15 -0
- package/lib/util/utilityLogic.d.ts.map +1 -0
- package/lib/util/utilityLogic.js +272 -0
- package/lib/util/utilityLogic.js.map +1 -0
- package/lib/util/utils.d.ts +8 -0
- package/lib/util/utils.d.ts.map +1 -0
- package/lib/util/utils.js +48 -0
- package/lib/util/utils.js.map +1 -0
- package/package.json +3 -1
- package/src/acl/aclLogic.ts +135 -119
- package/src/authn/SolidAuthnLogic.ts +3 -2
- package/src/chat/chatLogic.ts +225 -0
- package/src/discovery/discoveryLogic.ts +42 -85
- package/src/inbox/inboxLogic.ts +57 -0
- package/src/index.ts +71 -30
- package/src/logic/CustomError.ts +5 -1
- package/src/logic/solidLogicSingleton.ts +160 -7
- package/src/profile/profileLogic.ts +134 -0
- package/src/typeIndex/typeIndexLogic.ts +417 -153
- package/src/types.ts +7 -3
- package/src/util/containerLogic.ts +54 -0
- package/src/util/ns.js +5 -0
- package/src/util/utilityLogic.ts +155 -0
- package/src/util/utils.ts +52 -0
- package/test/aclLogic.test.ts +13 -4
- package/test/chatLogic.test.ts +70 -71
- package/test/container.test.ts +56 -0
- package/test/discoveryLogic.test.ts +503 -531
- package/test/helpers/dataSetup.ts +134 -0
- package/test/helpers/setup.ts +1 -0
- package/test/inboxLogic.test.ts +39 -38
- package/test/logic.test.ts +11 -9
- package/test/profileLogic.test.ts +246 -0
- package/test/typeIndexLogic.test.ts +49 -22
- package/test/typeIndexLogicPart2.test.ts +485 -0
- package/test/utilityLogic.test.ts +172 -126
- package/test/utils.test.ts +32 -0
- package/lib/chat/ChatLogic.d.ts +0 -26
- package/lib/chat/ChatLogic.d.ts.map +0 -1
- package/lib/chat/ChatLogic.js.map +0 -1
- package/lib/chat/determineChatContainer.d.ts +0 -3
- package/lib/chat/determineChatContainer.d.ts.map +0 -1
- package/lib/chat/determineChatContainer.js +0 -12
- package/lib/chat/determineChatContainer.js.map +0 -1
- package/lib/inbox/InboxLogic.d.ts +0 -18
- package/lib/inbox/InboxLogic.d.ts.map +0 -1
- package/lib/inbox/InboxLogic.js.map +0 -1
- package/lib/logic/SolidLogic.d.ts +0 -48
- package/lib/logic/SolidLogic.d.ts.map +0 -1
- package/lib/logic/SolidLogic.js +0 -321
- package/lib/logic/SolidLogic.js.map +0 -1
- package/lib/profile/ProfileLogic.d.ts +0 -13
- package/lib/profile/ProfileLogic.d.ts.map +0 -1
- package/lib/profile/ProfileLogic.js.map +0 -1
- package/lib/util/UtilityLogic.d.ts +0 -33
- package/lib/util/UtilityLogic.d.ts.map +0 -1
- package/lib/util/UtilityLogic.js +0 -240
- package/lib/util/UtilityLogic.js.map +0 -1
- package/lib/util/uri.d.ts +0 -3
- package/lib/util/uri.d.ts.map +0 -1
- package/lib/util/uri.js +0 -9
- package/lib/util/uri.js.map +0 -1
- package/src/chat/ChatLogic.ts +0 -244
- package/src/chat/determineChatContainer.ts +0 -14
- package/src/inbox/InboxLogic.ts +0 -66
- package/src/logic/SolidLogic.ts +0 -262
- package/src/profile/ProfileLogic.ts +0 -44
- package/src/util/UtilityLogic.ts +0 -161
- package/src/util/uri.ts +0 -5
|
@@ -1,58 +1,38 @@
|
|
|
1
|
-
import { NamedNode,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
const { authn } = solidLogicSingleton
|
|
7
|
-
const { currentUser } = authn
|
|
8
|
-
|
|
9
|
-
type TypeIndexScope = { label: string, index: NamedNode, agent: NamedNode } ;
|
|
10
|
-
type ScopedApp = { instance: NamedNode, scope: TypeIndexScope }
|
|
1
|
+
import { NamedNode, LiveStore, sym, st } from 'rdflib'
|
|
2
|
+
import * as $rdf from 'rdflib'
|
|
3
|
+
import { newThing } from "../util/utils"
|
|
4
|
+
import solidNamespace from 'solid-namespace'
|
|
5
|
+
import { authn } from '../logic/solidLogicSingleton'
|
|
11
6
|
|
|
12
|
-
const ns =
|
|
13
|
-
dct: Namespace('http://purl.org/dc/terms/'),
|
|
14
|
-
ldp: Namespace('http://www.w3.org/ns/ldp#'),
|
|
15
|
-
meeting: Namespace('http://www.w3.org/ns/pim/meeting#'),
|
|
16
|
-
rdf: Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#'),
|
|
17
|
-
schema: Namespace('http://schema.org/'),
|
|
18
|
-
solid: Namespace('http://www.w3.org/ns/solid/terms#'),
|
|
19
|
-
space: Namespace('http://www.w3.org/ns/pim/space#'),
|
|
20
|
-
stat: Namespace('http://www.w3.org/ns/posix/stat#'),
|
|
21
|
-
vcard: Namespace('http://www.w3.org/2006/vcard/ns#'),
|
|
22
|
-
wf: Namespace('http://www.w3.org/2005/01/wf/flow#'),
|
|
23
|
-
xsd: Namespace('http://www.w3.org/2001/XMLSchema#')
|
|
7
|
+
const ns = solidNamespace($rdf)
|
|
24
8
|
|
|
25
|
-
}
|
|
9
|
+
type TypeIndexScope = { label: string, index: NamedNode, agent: NamedNode }
|
|
10
|
+
type ScopedApp = { instance: NamedNode, scope: TypeIndexScope }
|
|
26
11
|
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
12
|
+
/**
|
|
13
|
+
* Create a resource if it really does not exist
|
|
14
|
+
* Be absolutely sure something does not exist before creating a new empty file
|
|
29
15
|
* as otherwise existing could be deleted.
|
|
30
16
|
* @param doc {NamedNode} - The resource
|
|
31
17
|
*/
|
|
32
18
|
export async function loadOrCreateIfNotExists (store: LiveStore, doc: NamedNode) {
|
|
33
19
|
let response
|
|
34
|
-
// console.log('@@ loadOrCreateIfNotExists doc ', doc)
|
|
35
20
|
try {
|
|
36
21
|
response = await store.fetcher.load(doc)
|
|
37
22
|
} catch (err) {
|
|
38
23
|
if (err.response.status === 404) {
|
|
39
|
-
// console.log('createIfNotExists doc does NOT exist, will create: ' + doc)
|
|
40
24
|
try {
|
|
41
25
|
store.fetcher.webOperation('PUT', doc, {data: '', contentType: 'text/turtle'})
|
|
42
26
|
} catch (err) {
|
|
43
27
|
const msg = 'createIfNotExists: PUT FAILED: ' + doc + ': ' + err
|
|
44
|
-
// console.log(msg)
|
|
45
28
|
throw new Error(msg)
|
|
46
29
|
}
|
|
47
30
|
delete store.fetcher.requested[doc.uri] // delete cached 404 error
|
|
48
|
-
// console.log('createIfNotExists doc created ok ' + doc)
|
|
49
31
|
} else {
|
|
50
32
|
const msg = 'createIfNotExists doc load error NOT 404: ' + doc + ': ' + err
|
|
51
|
-
// console.log(msg)
|
|
52
33
|
throw new Error(msg) // @@ add nested errors
|
|
53
34
|
}
|
|
54
35
|
}
|
|
55
|
-
// console.log('createIfNotExists doc exists, all good ' + doc)
|
|
56
36
|
return response
|
|
57
37
|
}
|
|
58
38
|
|
|
@@ -72,20 +52,18 @@ export function suggestPublicTypeIndex (me:NamedNode) {
|
|
|
72
52
|
export function suggestPrivateTypeIndex (preferencesFile:NamedNode) {
|
|
73
53
|
return sym(preferencesFile.doc().dir()?.uri + 'privateTypeIndex.ttl')
|
|
74
54
|
}
|
|
55
|
+
|
|
75
56
|
/* Follow link from this doc to another thing, or else make a new link
|
|
76
57
|
**
|
|
77
|
-
**
|
|
58
|
+
** return: null no ld one and failed to make a new one
|
|
78
59
|
*/
|
|
79
60
|
export async function followOrCreateLink (store: LiveStore, subject: NamedNode, predicate: NamedNode,
|
|
80
61
|
object: NamedNode, doc:NamedNode):Promise<NamedNode | null> {
|
|
81
62
|
await store.fetcher.load(doc)
|
|
82
63
|
const result = store.any(subject, predicate, null, doc)
|
|
83
|
-
// console.log('@@ followOrCreateLink result ', result)
|
|
84
64
|
|
|
85
65
|
if (result) return result as NamedNode
|
|
86
66
|
if (!store.updater.editable(doc)) {
|
|
87
|
-
// console.log(`followOrCreateLink: Can't modify ${doc} so can't make new link to ${object}.`)
|
|
88
|
-
// console.log('followOrCreateLink @@ connectedStatements', store.connectedStatements(subject))
|
|
89
67
|
return null
|
|
90
68
|
}
|
|
91
69
|
try {
|
|
@@ -95,58 +73,48 @@ export async function followOrCreateLink (store: LiveStore, subject: NamedNode,
|
|
|
95
73
|
return null
|
|
96
74
|
}
|
|
97
75
|
|
|
98
|
-
// console.log(`Success making link in ${doc} to ${object}` )
|
|
99
|
-
|
|
100
76
|
try {
|
|
101
77
|
await loadOrCreateIfNotExists(store, object)
|
|
102
78
|
// store.fetcher.webOperation('PUT', object, { data: '', contentType: 'text/turtle'})
|
|
103
79
|
} catch (err) {
|
|
104
80
|
console.warn(`followOrCreateLink: Error loading or saving new linked document: ${object}: ${err}`)
|
|
105
81
|
}
|
|
106
|
-
// console.log(`followOrCreateLink: Success loading or saving new linked document: ${object}.`)
|
|
107
82
|
return object
|
|
108
83
|
}
|
|
109
84
|
|
|
110
85
|
export async function loadProfile (store: LiveStore, user: NamedNode) {
|
|
111
|
-
// console.log(' @@ loadProfile: user', user)
|
|
112
86
|
if (!user) {
|
|
113
87
|
throw new Error(`loadProfile: no user given.`)
|
|
114
88
|
}
|
|
115
|
-
|
|
89
|
+
try {
|
|
116
90
|
await store.fetcher.load(user.doc())
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
91
|
+
} catch (err) {
|
|
92
|
+
throw new Error(`Unable to load profile of user ${user}: ${err}`)
|
|
93
|
+
}
|
|
120
94
|
return user.doc()
|
|
121
95
|
}
|
|
122
96
|
|
|
123
97
|
export async function loadPreferences (store: LiveStore, user: NamedNode): Promise <NamedNode | undefined > {
|
|
124
|
-
// console.log('loadPreferences @@ user', user)
|
|
125
98
|
await loadProfile(store as LiveStore, user)
|
|
126
99
|
|
|
127
100
|
const possiblePreferencesFile = suggestPreferencesFile(user)
|
|
128
101
|
|
|
129
102
|
const preferencesFile = await followOrCreateLink(store, user, ns.space('preferencesFile') as NamedNode, possiblePreferencesFile, user.doc())
|
|
130
|
-
// const preferencesFile = store.any(user, ns.space('preferencesFile'), undefined, profile)
|
|
131
103
|
|
|
132
|
-
// console.log('loadPreferences @@ pref file', preferencesFile)
|
|
133
104
|
if (!preferencesFile) {
|
|
134
105
|
const message = `User ${user} has no pointer in profile to preferences file.`
|
|
135
106
|
console.warn(message)
|
|
136
|
-
// throw new Error()
|
|
137
107
|
return undefined
|
|
138
108
|
}
|
|
139
109
|
try {
|
|
140
110
|
await store.fetcher.load(preferencesFile as NamedNode)
|
|
141
|
-
} catch (err) { //
|
|
111
|
+
} catch (err) { // Maybe a permission propblem or origin problem
|
|
142
112
|
return undefined
|
|
143
|
-
// throw new Error(`Unable to load preferences file ${preferencesFile} of user <${user}>: ${err}`)
|
|
144
113
|
}
|
|
145
114
|
return preferencesFile as NamedNode
|
|
146
115
|
}
|
|
147
116
|
|
|
148
117
|
export async function loadTypeIndexesFor (store: LiveStore, user:NamedNode): Promise<Array<TypeIndexScope>> {
|
|
149
|
-
// console.log('@@ loadTypeIndexesFor user', user)
|
|
150
118
|
if (!user) throw new Error(`loadTypeIndexesFor: No user given`)
|
|
151
119
|
const profile = await loadProfile(store, user)
|
|
152
120
|
|
|
@@ -154,9 +122,6 @@ export async function loadTypeIndexesFor (store: LiveStore, user:NamedNode): Pro
|
|
|
154
122
|
|
|
155
123
|
const publicTypeIndex = await followOrCreateLink(store, user, ns.solid('publicTypeIndex') as NamedNode, suggestion, profile)
|
|
156
124
|
|
|
157
|
-
// const publicTypeIndex = store.any(user, ns.solid('publicTypeIndex'), undefined, profile)
|
|
158
|
-
// console.log('@@ loadTypeIndexesFor publicTypeIndex', publicTypeIndex)
|
|
159
|
-
|
|
160
125
|
const publicScopes = publicTypeIndex ? [ { label: 'public', index: publicTypeIndex as NamedNode, agent: user } ] : []
|
|
161
126
|
|
|
162
127
|
let preferencesFile
|
|
@@ -174,7 +139,7 @@ export async function loadTypeIndexesFor (store: LiveStore, user:NamedNode): Pro
|
|
|
174
139
|
|
|
175
140
|
const privateTypeIndex = store.any(user, ns.solid('privateTypeIndex'), undefined, profile) ||
|
|
176
141
|
|
|
177
|
-
|
|
142
|
+
await followOrCreateLink(store, user, ns.solid('privateTypeIndex') as NamedNode, suggestedPrivateTypeIndex, preferencesFile);
|
|
178
143
|
|
|
179
144
|
privateScopes = privateTypeIndex ? [ { label: 'private', index: privateTypeIndex as NamedNode, agent: user } ] : []
|
|
180
145
|
} else {
|
|
@@ -183,7 +148,6 @@ export async function loadTypeIndexesFor (store: LiveStore, user:NamedNode): Pro
|
|
|
183
148
|
const scopes = publicScopes.concat(privateScopes)
|
|
184
149
|
if (scopes.length === 0) return scopes
|
|
185
150
|
const files = scopes.map(scope => scope.index)
|
|
186
|
-
// console.log('@@ loadTypeIndexesFor files ', files)
|
|
187
151
|
try {
|
|
188
152
|
await store.fetcher.load(files)
|
|
189
153
|
} catch (err) {
|
|
@@ -195,14 +159,13 @@ export async function loadTypeIndexesFor (store: LiveStore, user:NamedNode): Pro
|
|
|
195
159
|
export async function loadCommunityTypeIndexes (store:LiveStore, user:NamedNode): Promise<TypeIndexScope[][]> {
|
|
196
160
|
const preferencesFile = await loadPreferences(store, user)
|
|
197
161
|
if (preferencesFile) { // For now, pick up communities as simple links from the preferences file.
|
|
198
|
-
const communities = store.each(user, ns.solid('community'), undefined, preferencesFile as NamedNode)
|
|
199
|
-
|
|
162
|
+
const communities = store.each(user, ns.solid('community'), undefined, preferencesFile as NamedNode).concat(
|
|
163
|
+
store.each(user, ns.solid('community'), undefined, user.doc() as NamedNode)
|
|
164
|
+
)
|
|
200
165
|
let result = []
|
|
201
166
|
for (const org of communities) {
|
|
202
167
|
result = result.concat(await loadTypeIndexesFor(store, org as NamedNode) as any)
|
|
203
168
|
}
|
|
204
|
-
// const communityTypeIndexesPromises = communities.map(async community => await loadTypeIndexesFor(store, community as NamedNode))
|
|
205
|
-
// const result1 = Promise.all(communityTypeIndexesPromises)
|
|
206
169
|
return result
|
|
207
170
|
}
|
|
208
171
|
return [] // No communities
|
|
@@ -213,7 +176,6 @@ export async function loadAllTypeIndexes (store:LiveStore, user:NamedNode) {
|
|
|
213
176
|
}
|
|
214
177
|
|
|
215
178
|
// Utility: remove duplicates from Array of NamedNodes
|
|
216
|
-
|
|
217
179
|
export function uniqueNodes (arr: NamedNode[]): NamedNode[] {
|
|
218
180
|
const uris = arr.map(x => x.uri)
|
|
219
181
|
const set = new Set(uris)
|
|
@@ -222,45 +184,32 @@ export function uniqueNodes (arr: NamedNode[]): NamedNode[] {
|
|
|
222
184
|
return arr2 // Array.from(new Set(arr.map(x => x.uri))).map(u => sym(u))
|
|
223
185
|
}
|
|
224
186
|
|
|
225
|
-
export async function getScopedAppsFromIndex (store, scope, theClass: NamedNode) {
|
|
226
|
-
// console.log(`getScopedAppsFromIndex agent ${scope.agent} index: ${scope.index}` )
|
|
187
|
+
export async function getScopedAppsFromIndex (store, scope, theClass: NamedNode | null) {
|
|
227
188
|
const index = scope.index
|
|
228
|
-
const registrations = store.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const
|
|
232
|
-
|
|
189
|
+
const registrations = store.statementsMatching(null, ns.solid('instance'), null, index)
|
|
190
|
+
.concat(store.statementsMatching(null, ns.solid('instanceContainer'), null, index))
|
|
191
|
+
.map(st => st.subject)
|
|
192
|
+
const relevant = theClass ? registrations.filter(reg => store.any(reg, ns.solid('forClass'), null, index).sameTerm(theClass))
|
|
193
|
+
: registrations
|
|
194
|
+
const directInstances = relevant.map(reg => store.each(reg as NamedNode, ns.solid('instance'), null, index)).flat()
|
|
233
195
|
let instances = uniqueNodes(directInstances)
|
|
234
196
|
|
|
235
|
-
|
|
236
|
-
let instanceContainers = []
|
|
237
|
-
for (const reg of registrations) {
|
|
238
|
-
const cont = store.any(reg as NamedNode, ns.solid('instanceContainer'), null, index)
|
|
239
|
-
if (cont) {
|
|
240
|
-
// console.log(' @@ getScopedAppsFromIndex got one: ', cont)
|
|
241
|
-
instanceContainers.push(cont)
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
*/
|
|
245
|
-
const instanceContainers = registrations.map(
|
|
197
|
+
const instanceContainers = relevant.map(
|
|
246
198
|
reg => store.each(reg as NamedNode, ns.solid('instanceContainer'), null, index)).flat()
|
|
247
199
|
|
|
248
200
|
// instanceContainers may be deprocatable if no one has used them
|
|
249
|
-
|
|
250
201
|
const containers = uniqueNodes(instanceContainers)
|
|
202
|
+
if (containers.length > 0) { console.log('@@ getScopedAppsFromIndex containers ', containers)}
|
|
251
203
|
for (let i = 0; i < containers.length; i++) {
|
|
252
204
|
const cont = containers[i]
|
|
253
205
|
await store.fetcher.load(cont)
|
|
254
206
|
const contents = store.each(cont, ns.ldp('contains'), null, cont)
|
|
255
|
-
// if (contents.length) console.log('getScopedAppsFromIndex @@ instanceContainer contents:', contents)
|
|
256
207
|
instances = instances.concat(contents)
|
|
257
208
|
}
|
|
258
209
|
return instances.map(instance => { return {instance, scope}})
|
|
259
210
|
}
|
|
260
211
|
|
|
261
|
-
|
|
262
212
|
export async function getScopedAppInstances (store:LiveStore, klass: NamedNode, user: NamedNode):Promise<ScopedApp[]> {
|
|
263
|
-
// console.log('getScopedAppInstances @@ ' + user)
|
|
264
213
|
const scopes = await loadAllTypeIndexes(store, user)
|
|
265
214
|
let scopedApps = []
|
|
266
215
|
for (const scope of scopes) {
|
|
@@ -269,16 +218,18 @@ export async function getScopedAppInstances (store:LiveStore, klass: NamedNode,
|
|
|
269
218
|
}
|
|
270
219
|
return scopedApps
|
|
271
220
|
}
|
|
221
|
+
|
|
272
222
|
// This is the function signature which used to be in solid-ui/logic
|
|
273
223
|
// Recommended to use getScopedAppInstances instead as it provides more information.
|
|
274
224
|
//
|
|
275
225
|
export async function getAppInstances (store:LiveStore, klass: NamedNode): Promise<NamedNode[]> {
|
|
276
|
-
const user = currentUser()
|
|
226
|
+
const user = authn.currentUser()
|
|
277
227
|
if (!user) throw new Error('getAppInstances: Must be logged in to find apps.')
|
|
278
228
|
const scopedAppInstances = await getScopedAppInstances(store, klass, user)
|
|
279
229
|
return scopedAppInstances.map(scoped => scoped.instance)
|
|
280
230
|
}
|
|
281
|
-
|
|
231
|
+
|
|
232
|
+
/*
|
|
282
233
|
* Register a new app in a type index
|
|
283
234
|
* used in chat in bookmark.js (solid-ui)
|
|
284
235
|
* Returns the registration object if successful else null
|
|
@@ -298,7 +249,6 @@ export async function registerInstanceInTypeIndex (
|
|
|
298
249
|
st(registration, ns.solid('instance'), instance, index)
|
|
299
250
|
]
|
|
300
251
|
try {
|
|
301
|
-
console.log('patching index', ins)
|
|
302
252
|
await store.updater.update([], ins)
|
|
303
253
|
} catch (err) {
|
|
304
254
|
const msg = `Unable to register ${instance} in index ${index}: ${err}`
|
|
@@ -307,4 +257,11 @@ export async function registerInstanceInTypeIndex (
|
|
|
307
257
|
}
|
|
308
258
|
return registration
|
|
309
259
|
}
|
|
260
|
+
|
|
261
|
+
export async function deleteTypeIndexRegistration (store: LiveStore, item) {
|
|
262
|
+
const reg = store.the(null, ns.solid('instance'), item.instance, item.scope.index) as NamedNode
|
|
263
|
+
if (!reg) throw new Error(`deleteTypeIndexRegistration: No registration found for ${item.instance}`)
|
|
264
|
+
const statements = store.statementsMatching(reg, null, null, item.scope.index)
|
|
265
|
+
await store.updater.update(statements, [])
|
|
266
|
+
}
|
|
310
267
|
// ENDS
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { NamedNode } from "rdflib";
|
|
2
|
+
import { getArchiveUrl } from "../util/utils";
|
|
3
|
+
|
|
4
|
+
export function createInboxLogic(store, profileLogic, utilityLogic, containerLogic, aclLogic) {
|
|
5
|
+
|
|
6
|
+
async function createInboxFor(peerWebId: string, nick: string) {
|
|
7
|
+
const myWebId: NamedNode = await profileLogic.loadMe();
|
|
8
|
+
const podRoot: NamedNode = await profileLogic.getPodRoot(myWebId);
|
|
9
|
+
const ourInbox = `${podRoot.value}p2p-inboxes/${encodeURIComponent(nick)}/`;
|
|
10
|
+
await containerLogic.createContainer(ourInbox);
|
|
11
|
+
const aclDocUrl = await aclLogic.findAclDocUrl(ourInbox);
|
|
12
|
+
await utilityLogic.setSinglePeerAccess({
|
|
13
|
+
ownerWebId: myWebId.value,
|
|
14
|
+
peerWebId,
|
|
15
|
+
accessToModes: 'acl:Append',
|
|
16
|
+
target: ourInbox
|
|
17
|
+
});
|
|
18
|
+
return ourInbox;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function getNewMessages(
|
|
22
|
+
user?: NamedNode
|
|
23
|
+
): Promise<string[]> {
|
|
24
|
+
if (!user) {
|
|
25
|
+
user = await profileLogic.loadMe();
|
|
26
|
+
}
|
|
27
|
+
const inbox = await profileLogic.getMainInbox(user);
|
|
28
|
+
const urls = await containerLogic.getContainerMembers(inbox.value);
|
|
29
|
+
return urls.filter(url => !containerLogic.isContainer(url));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function markAsRead(url: string, date: Date) {
|
|
33
|
+
const downloaded = await store.fetcher._fetch(url);
|
|
34
|
+
if (downloaded.status !== 200) {
|
|
35
|
+
throw new Error(`Not OK! ${url}`);
|
|
36
|
+
}
|
|
37
|
+
const archiveUrl = getArchiveUrl(url, date);
|
|
38
|
+
const options = {
|
|
39
|
+
method: 'PUT',
|
|
40
|
+
body: await downloaded.text(),
|
|
41
|
+
headers: [
|
|
42
|
+
['Content-Type', downloaded.headers.get('Content-Type') || 'application/octet-stream']
|
|
43
|
+
]
|
|
44
|
+
};
|
|
45
|
+
const uploaded = await store.fetcher._fetch(archiveUrl, options);
|
|
46
|
+
if (uploaded.status.toString()[0] === '2') {
|
|
47
|
+
await store.fetcher._fetch(url, {
|
|
48
|
+
method: 'DELETE'
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
createInboxFor,
|
|
54
|
+
getNewMessages,
|
|
55
|
+
markAsRead
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,51 +1,92 @@
|
|
|
1
1
|
// Make these variables directly accessible as it is what you need most of the time
|
|
2
2
|
// This also makes these variable globaly accesible in mashlib
|
|
3
|
-
import { solidLogicSingleton } from './logic/solidLogicSingleton'
|
|
4
|
-
const authn = solidLogicSingleton.authn
|
|
5
|
-
const authSession = solidLogicSingleton.authn.authSession
|
|
6
|
-
const store = solidLogicSingleton.store
|
|
3
|
+
//import { solidLogicSingleton } from './logic/solidLogicSingleton'
|
|
4
|
+
//const authn = solidLogicSingleton.authn
|
|
5
|
+
//const authSession = solidLogicSingleton.authn.authSession
|
|
6
|
+
//const store = solidLogicSingleton.store
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
export {
|
|
9
|
+
ACL_LINK
|
|
10
|
+
} from './acl/aclLogic'
|
|
10
11
|
|
|
11
12
|
export {
|
|
13
|
+
findAclDocUrl,
|
|
12
14
|
setACLUserPublic,
|
|
13
|
-
genACLText
|
|
14
|
-
} from './
|
|
15
|
+
genACLText,
|
|
16
|
+
} from './logic/solidLogicSingleton'
|
|
15
17
|
|
|
16
18
|
export {
|
|
17
19
|
ensureTypeIndexes,
|
|
18
20
|
loadTypeIndexes,
|
|
19
21
|
registerInTypeIndex,
|
|
20
|
-
loadIndex
|
|
21
|
-
|
|
22
|
+
loadIndex,
|
|
23
|
+
ensureOneTypeIndex,
|
|
24
|
+
putIndex,
|
|
25
|
+
makeIndexIfNecessary,
|
|
26
|
+
loadIndexes,
|
|
27
|
+
getTypeIndex,
|
|
28
|
+
getRegistrations,
|
|
29
|
+
//NEW function for discovery
|
|
30
|
+
loadTypeIndexesFor,
|
|
31
|
+
loadCommunityTypeIndexes,
|
|
32
|
+
loadAllTypeIndexes,
|
|
33
|
+
getScopedAppInstances,
|
|
34
|
+
getAppInstances,
|
|
35
|
+
suggestPublicTypeIndex,
|
|
36
|
+
suggestPrivateTypeIndex,
|
|
37
|
+
registerInstanceInTypeIndex,
|
|
38
|
+
deleteTypeIndexRegistration,
|
|
39
|
+
getScopedAppsFromIndex
|
|
40
|
+
} from './logic/solidLogicSingleton'
|
|
22
41
|
|
|
23
|
-
// Generate by
|
|
24
|
-
// grep export src/discovery/discoveryLogic.ts | sed -e 's/export //g' | sed -e 's/async //g'| sed -e 's/function //g' | sed -e 's/ .*/,/g' | sort
|
|
25
42
|
export {
|
|
43
|
+
setAcl,
|
|
44
|
+
addToPrivateTypeIndex,
|
|
45
|
+
findChat,
|
|
46
|
+
createChatThing,
|
|
47
|
+
getChat,
|
|
48
|
+
sendInvite,
|
|
49
|
+
mintNew
|
|
50
|
+
} from './logic/solidLogicSingleton'
|
|
51
|
+
|
|
52
|
+
export { offlineTestID, appContext } from './authn/authUtil'
|
|
53
|
+
export { createInboxFor, getNewMessages, markAsRead } from './logic/solidLogicSingleton'
|
|
54
|
+
export {
|
|
55
|
+
recursiveDelete,
|
|
56
|
+
setSinglePeerAccess,
|
|
57
|
+
createEmptyRdfDoc,
|
|
58
|
+
//NEW function for discovery
|
|
26
59
|
followOrCreateLink,
|
|
27
|
-
getAppInstances,
|
|
28
|
-
getScopedAppInstances,
|
|
29
|
-
getScopedAppsFromIndex,
|
|
30
|
-
loadAllTypeIndexes,
|
|
31
|
-
loadCommunityTypeIndexes,
|
|
32
60
|
loadOrCreateIfNotExists,
|
|
61
|
+
} from './logic/solidLogicSingleton'
|
|
62
|
+
|
|
63
|
+
export {
|
|
64
|
+
ensureLoadedPreferences,
|
|
65
|
+
loadMe,
|
|
66
|
+
getPodRoot,
|
|
67
|
+
getMainInbox,
|
|
68
|
+
findStorage,
|
|
69
|
+
//NEW content from discovery
|
|
33
70
|
loadPreferences,
|
|
34
71
|
loadProfile,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
suggestPrivateTypeIndex,
|
|
39
|
-
suggestPublicTypeIndex,
|
|
40
|
-
uniqueNodes
|
|
41
|
-
} from './discovery/discoveryLogic'
|
|
72
|
+
//NEW function for discovery
|
|
73
|
+
silencedLoadPreferences
|
|
74
|
+
} from './logic/solidLogicSingleton'
|
|
42
75
|
|
|
43
|
-
export { SolidLogic } from './logic/SolidLogic'
|
|
44
|
-
export { offlineTestID, appContext } from './authn/authUtil'
|
|
45
|
-
export { ACL_LINK } from './util/UtilityLogic'
|
|
46
76
|
export { getSuggestedIssuers } from './issuer/issuerLogic'
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
isContainer,
|
|
80
|
+
createContainer,
|
|
81
|
+
getContainerElements,
|
|
82
|
+
getContainerMembers
|
|
83
|
+
} from './logic/solidLogicSingleton'
|
|
84
|
+
|
|
85
|
+
export { authn, authSession, store } from './logic/solidLogicSingleton'
|
|
86
|
+
|
|
87
|
+
//export { SolidLogic } from './logic/SolidLogic'
|
|
47
88
|
export { AppDetails, SolidNamespace, AuthenticationContext } from './types'
|
|
48
89
|
// solidLogicSingleton is exported entirely because it is used in solid-panes
|
|
49
|
-
export { solidLogicSingleton } from './logic/solidLogicSingleton'
|
|
50
|
-
export { UnauthorizedError, CrossOriginForbiddenError, SameOriginForbiddenError, NotFoundError, FetchError } from './logic/CustomError'
|
|
51
|
-
|
|
90
|
+
//export { solidLogicSingleton } from './logic/solidLogicSingleton'
|
|
91
|
+
export { UnauthorizedError, CrossOriginForbiddenError, SameOriginForbiddenError, NotFoundError, FetchError, NotEditableError, WebOperationError } from './logic/CustomError'
|
|
92
|
+
|
package/src/logic/CustomError.ts
CHANGED
|
@@ -6,7 +6,7 @@ class CustomError extends Error {
|
|
|
6
6
|
this.name = new.target.name; // stack traces display correctly now
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
export class UnauthorizedError extends CustomError {}
|
|
11
11
|
|
|
12
12
|
export class CrossOriginForbiddenError extends CustomError {}
|
|
@@ -15,6 +15,10 @@ export class SameOriginForbiddenError extends CustomError {}
|
|
|
15
15
|
|
|
16
16
|
export class NotFoundError extends CustomError {}
|
|
17
17
|
|
|
18
|
+
export class NotEditableError extends CustomError { }
|
|
19
|
+
|
|
20
|
+
export class WebOperationError extends CustomError {}
|
|
21
|
+
|
|
18
22
|
export class FetchError extends CustomError {
|
|
19
23
|
status: number;
|
|
20
24
|
|
|
@@ -1,20 +1,173 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as rdf from "rdflib"
|
|
2
|
+
import { SolidAuthnLogic } from "../authn/SolidAuthnLogic"
|
|
2
3
|
import { authSession } from "../authSession/authSession"
|
|
3
|
-
import {
|
|
4
|
+
import { createContainerLogic } from "../util/containerLogic"
|
|
5
|
+
import { createTypeIndexLogic } from "../typeIndex/typeIndexLogic"
|
|
6
|
+
import * as debug from "../util/debug"
|
|
7
|
+
import { createUtilityLogic } from "../util/utilityLogic"
|
|
8
|
+
import { createProfileLogic } from "../profile/profileLogic"
|
|
9
|
+
import { createInboxLogic } from "../inbox/inboxLogic"
|
|
10
|
+
import { createChatLogic } from "../chat/chatLogic"
|
|
11
|
+
import { createAclLogic } from "../acl/aclLogic"
|
|
4
12
|
|
|
5
13
|
const _fetch = async (url, requestInit) => {
|
|
6
14
|
const omitCreds = requestInit && requestInit.credentials && requestInit.credentials == 'omit'
|
|
7
15
|
if (authSession.info.webId && !omitCreds) { // see https://github.com/solidos/solidos/issues/114
|
|
8
|
-
// In fact
|
|
16
|
+
// In fact fetch should respect credentials omit itself
|
|
9
17
|
return authSession.fetch(url, requestInit)
|
|
10
18
|
} else {
|
|
11
19
|
return window.fetch(url, requestInit)
|
|
12
20
|
}
|
|
13
21
|
}
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
debug.log("SolidLogicSingleton: Unique instance created. There should only be one of these.")
|
|
24
|
+
|
|
25
|
+
const store = rdf.graph() as rdf.LiveStore; // Make a Quad store
|
|
26
|
+
rdf.fetcher(store, { fetch: _fetch}); // Attach a web I/O module, store.fetcher
|
|
27
|
+
store.updater = new rdf.UpdateManager(store); // Add real-time live updates store.updater
|
|
28
|
+
store.features = [] // disable automatic node merging on store load
|
|
29
|
+
|
|
30
|
+
debug.log('SolidAuthnLogic initialized')
|
|
31
|
+
const authn = new SolidAuthnLogic(authSession)
|
|
32
|
+
|
|
33
|
+
const aclLogic = createAclLogic(store)
|
|
34
|
+
const {
|
|
35
|
+
findAclDocUrl,
|
|
36
|
+
setACLUserPublic,
|
|
37
|
+
genACLText
|
|
38
|
+
} = aclLogic
|
|
39
|
+
|
|
40
|
+
const containerLogic = createContainerLogic(store)
|
|
41
|
+
const {
|
|
42
|
+
isContainer,
|
|
43
|
+
createContainer,
|
|
44
|
+
getContainerElements,
|
|
45
|
+
getContainerMembers
|
|
46
|
+
} = containerLogic
|
|
17
47
|
|
|
18
|
-
|
|
48
|
+
const utilityLogic = createUtilityLogic(store, aclLogic, containerLogic)
|
|
49
|
+
const {
|
|
50
|
+
recursiveDelete,
|
|
51
|
+
setSinglePeerAccess,
|
|
52
|
+
createEmptyRdfDoc,
|
|
53
|
+
followOrCreateLink,
|
|
54
|
+
loadOrCreateIfNotExists
|
|
55
|
+
} = utilityLogic
|
|
56
|
+
|
|
57
|
+
const profileLogic = createProfileLogic(store, authn, utilityLogic)
|
|
58
|
+
const {
|
|
59
|
+
ensureLoadedPreferences,
|
|
60
|
+
loadMe,
|
|
61
|
+
getPodRoot,
|
|
62
|
+
getMainInbox,
|
|
63
|
+
findStorage,
|
|
64
|
+
loadPreferences,
|
|
65
|
+
loadProfile,
|
|
66
|
+
silencedLoadPreferences
|
|
67
|
+
} = profileLogic
|
|
68
|
+
|
|
69
|
+
const chatLogic = createChatLogic(store, profileLogic)
|
|
70
|
+
const {
|
|
71
|
+
setAcl,
|
|
72
|
+
addToPrivateTypeIndex,
|
|
73
|
+
findChat,
|
|
74
|
+
createChatThing,
|
|
75
|
+
getChat,
|
|
76
|
+
sendInvite,
|
|
77
|
+
mintNew
|
|
78
|
+
} = chatLogic
|
|
79
|
+
|
|
80
|
+
const inboxLogic = createInboxLogic(store, profileLogic, utilityLogic, containerLogic, aclLogic)
|
|
81
|
+
const {
|
|
82
|
+
createInboxFor,
|
|
83
|
+
getNewMessages,
|
|
84
|
+
markAsRead
|
|
85
|
+
} = inboxLogic
|
|
86
|
+
|
|
87
|
+
const typeIndexLogic = createTypeIndexLogic(store, authn, profileLogic, utilityLogic)
|
|
88
|
+
const {
|
|
89
|
+
ensureTypeIndexes,
|
|
90
|
+
loadTypeIndexes,
|
|
91
|
+
registerInTypeIndex,
|
|
92
|
+
loadIndex,
|
|
93
|
+
ensureOneTypeIndex,
|
|
94
|
+
putIndex,
|
|
95
|
+
makeIndexIfNecessary,
|
|
96
|
+
loadIndexes,
|
|
97
|
+
getTypeIndex,
|
|
98
|
+
getRegistrations,
|
|
99
|
+
loadTypeIndexesFor,
|
|
100
|
+
loadCommunityTypeIndexes,
|
|
101
|
+
loadAllTypeIndexes,
|
|
102
|
+
getScopedAppInstances,
|
|
103
|
+
getAppInstances,
|
|
104
|
+
suggestPublicTypeIndex,
|
|
105
|
+
suggestPrivateTypeIndex,
|
|
106
|
+
registerInstanceInTypeIndex,
|
|
107
|
+
deleteTypeIndexRegistration,
|
|
108
|
+
getScopedAppsFromIndex
|
|
109
|
+
} = typeIndexLogic
|
|
110
|
+
|
|
111
|
+
export {
|
|
112
|
+
store,
|
|
113
|
+
authn,
|
|
114
|
+
authSession,
|
|
115
|
+
//unilityLogic
|
|
116
|
+
recursiveDelete,
|
|
117
|
+
setSinglePeerAccess,
|
|
118
|
+
createEmptyRdfDoc,
|
|
119
|
+
followOrCreateLink,
|
|
120
|
+
loadOrCreateIfNotExists,
|
|
121
|
+
//containerLogic
|
|
122
|
+
isContainer,
|
|
123
|
+
createContainer,
|
|
124
|
+
getContainerElements,
|
|
125
|
+
getContainerMembers,
|
|
126
|
+
//typeIndexLogic
|
|
127
|
+
ensureTypeIndexes,
|
|
128
|
+
loadTypeIndexes,
|
|
129
|
+
registerInTypeIndex,
|
|
130
|
+
loadIndex,
|
|
131
|
+
ensureOneTypeIndex,
|
|
132
|
+
putIndex,
|
|
133
|
+
makeIndexIfNecessary,
|
|
134
|
+
loadIndexes,
|
|
135
|
+
getTypeIndex,
|
|
136
|
+
getRegistrations,
|
|
137
|
+
loadTypeIndexesFor,
|
|
138
|
+
loadCommunityTypeIndexes,
|
|
139
|
+
loadAllTypeIndexes,
|
|
140
|
+
getScopedAppInstances,
|
|
141
|
+
getAppInstances,
|
|
142
|
+
suggestPublicTypeIndex,
|
|
143
|
+
suggestPrivateTypeIndex,
|
|
144
|
+
registerInstanceInTypeIndex,
|
|
145
|
+
deleteTypeIndexRegistration,
|
|
146
|
+
getScopedAppsFromIndex,
|
|
147
|
+
//profileLogic
|
|
148
|
+
ensureLoadedPreferences,
|
|
149
|
+
loadMe,
|
|
150
|
+
getPodRoot,
|
|
151
|
+
getMainInbox,
|
|
152
|
+
findStorage,
|
|
153
|
+
loadPreferences,
|
|
154
|
+
loadProfile,
|
|
155
|
+
silencedLoadPreferences,
|
|
156
|
+
//inboxLogic
|
|
157
|
+
createInboxFor,
|
|
158
|
+
getNewMessages,
|
|
159
|
+
markAsRead,
|
|
160
|
+
//chatLogic
|
|
161
|
+
setAcl,
|
|
162
|
+
addToPrivateTypeIndex,
|
|
163
|
+
findChat,
|
|
164
|
+
createChatThing,
|
|
165
|
+
getChat,
|
|
166
|
+
sendInvite,
|
|
167
|
+
mintNew,
|
|
168
|
+
//aclLogic
|
|
169
|
+
findAclDocUrl,
|
|
170
|
+
setACLUserPublic,
|
|
171
|
+
genACLText
|
|
172
|
+
}
|
|
19
173
|
|
|
20
|
-
export { solidLogicSingleton }
|