solid-logic 1.3.17-7b06fb45 → 1.3.17-7b8c254b

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.
Files changed (73) hide show
  1. package/README.md +2 -2
  2. package/lib/acl/aclLogic.d.ts +2 -11
  3. package/lib/acl/aclLogic.d.ts.map +1 -1
  4. package/lib/acl/aclLogic.js +8 -12
  5. package/lib/acl/aclLogic.js.map +1 -1
  6. package/lib/chat/chatLogic.d.ts +2 -15
  7. package/lib/chat/chatLogic.d.ts.map +1 -1
  8. package/lib/chat/chatLogic.js +8 -7
  9. package/lib/chat/chatLogic.js.map +1 -1
  10. package/lib/inbox/inboxLogic.d.ts +2 -6
  11. package/lib/inbox/inboxLogic.d.ts.map +1 -1
  12. package/lib/inbox/inboxLogic.js +3 -2
  13. package/lib/inbox/inboxLogic.js.map +1 -1
  14. package/lib/index.d.ts +4 -18
  15. package/lib/index.d.ts.map +1 -1
  16. package/lib/index.js +2 -86
  17. package/lib/index.js.map +1 -1
  18. package/lib/logic/solidLogic.d.ts +6 -0
  19. package/lib/logic/solidLogic.d.ts.map +1 -0
  20. package/lib/logic/{SolidLogic.js → solidLogic.js} +38 -33
  21. package/lib/logic/solidLogic.js.map +1 -0
  22. package/lib/logic/solidLogicSingleton.d.ts +1 -2
  23. package/lib/logic/solidLogicSingleton.d.ts.map +1 -1
  24. package/lib/logic/solidLogicSingleton.js +2 -2
  25. package/lib/logic/solidLogicSingleton.js.map +1 -1
  26. package/lib/profile/profileLogic.d.ts +2 -12
  27. package/lib/profile/profileLogic.d.ts.map +1 -1
  28. package/lib/profile/profileLogic.js +1 -23
  29. package/lib/profile/profileLogic.js.map +1 -1
  30. package/lib/typeIndex/typeIndexLogic.d.ts +2 -31
  31. package/lib/typeIndex/typeIndexLogic.d.ts.map +1 -1
  32. package/lib/typeIndex/typeIndexLogic.js +12 -359
  33. package/lib/typeIndex/typeIndexLogic.js.map +1 -1
  34. package/lib/types.d.ts +65 -1
  35. package/lib/types.d.ts.map +1 -1
  36. package/lib/util/containerLogic.d.ts +2 -2
  37. package/lib/util/containerLogic.d.ts.map +1 -1
  38. package/lib/util/containerLogic.js +8 -10
  39. package/lib/util/containerLogic.js.map +1 -1
  40. package/lib/util/ns.d.ts +2 -0
  41. package/lib/util/ns.d.ts.map +1 -0
  42. package/lib/util/ns.js +34 -0
  43. package/lib/util/ns.js.map +1 -0
  44. package/lib/util/utilityLogic.d.ts +1 -1
  45. package/lib/util/utilityLogic.d.ts.map +1 -1
  46. package/lib/util/utilityLogic.js +9 -7
  47. package/lib/util/utilityLogic.js.map +1 -1
  48. package/package.json +3 -1
  49. package/src/acl/aclLogic.ts +11 -9
  50. package/src/chat/chatLogic.ts +7 -7
  51. package/src/inbox/inboxLogic.ts +6 -5
  52. package/src/index.ts +5 -147
  53. package/src/logic/solidLogic.ts +75 -0
  54. package/src/logic/solidLogicSingleton.ts +2 -2
  55. package/src/profile/profileLogic.ts +4 -12
  56. package/src/typeIndex/typeIndexLogic.ts +6 -277
  57. package/src/types.ts +76 -1
  58. package/src/util/containerLogic.ts +30 -31
  59. package/src/util/{ns.js → ns.ts} +0 -0
  60. package/src/util/utilityLogic.ts +8 -7
  61. package/test/container.test.ts +7 -6
  62. package/test/inboxLogic.test.ts +2 -1
  63. package/test/typeIndexLogic.test.ts +484 -54
  64. package/lib/logic/SolidLogic.d.ts +0 -22
  65. package/lib/logic/SolidLogic.d.ts.map +0 -1
  66. package/lib/logic/SolidLogic.js.map +0 -1
  67. package/lib/logic/solidLogicSingletonNew.d.ts +0 -80
  68. package/lib/logic/solidLogicSingletonNew.d.ts.map +0 -1
  69. package/lib/logic/solidLogicSingletonNew.js +0 -238
  70. package/lib/logic/solidLogicSingletonNew.js.map +0 -1
  71. package/src/logic/SolidLogic.ts +0 -81
  72. package/src/logic/solidLogicSingletonNew.ts +0 -239
  73. package/test/typeIndexLogicPart2.test.ts +0 -485
@@ -0,0 +1,75 @@
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
+ /*
15
+ ** It is important to distinquish `fetch`, a function provided by the browser
16
+ ** and `Fetcher`, a helper object for the rdflib Store which turns it
17
+ ** into a `ConnectedStore` or a `LiveStore`. A Fetcher object is
18
+ ** available at store.fetcher, and `fetch` function at `store.fetcher._fetch`,
19
+ */
20
+ export function createSolidLogic(specialFetch: { fetch: (url: any, requestInit: any) => any }, session: Session): SolidLogic {
21
+
22
+ debug.log("SolidLogic: Unique instance created. There should only be one of these.")
23
+ const store: LiveStore = rdf.graph() as LiveStore
24
+ rdf.fetcher(store, {fetch: specialFetch.fetch}); // Attach a web I/O module, store.fetcher
25
+ store.updater = new rdf.UpdateManager(store); // Add real-time live updates store.updater
26
+ store.features = [] // disable automatic node merging on store load
27
+
28
+ const authn: AuthnLogic = new SolidAuthnLogic(session)
29
+
30
+ const acl = createAclLogic(store)
31
+ const containerLogic = createContainerLogic(store)
32
+ const utilityLogic = createUtilityLogic(store, acl, containerLogic)
33
+ const profile = createProfileLogic(store, authn, utilityLogic)
34
+ const chat = createChatLogic(store, profile)
35
+ const inbox = createInboxLogic(store, profile, utilityLogic, containerLogic, acl)
36
+ const typeIndex = createTypeIndexLogic(store, authn, profile, utilityLogic)
37
+ debug.log('SolidAuthnLogic initialized')
38
+
39
+ function load(doc: NamedNode | NamedNode[] | string) {
40
+ return store.fetcher.load(doc);
41
+ }
42
+
43
+ // @@@@ use the one in rdflib.js when it is available and delete this
44
+ function updatePromise(
45
+ del: Array<Statement>,
46
+ ins: Array<Statement> = []
47
+ ): Promise<void> {
48
+ return new Promise((resolve, reject) => {
49
+ store.updater.update(del, ins, function (_uri, ok, errorBody) {
50
+ if (!ok) {
51
+ reject(new Error(errorBody));
52
+ } else {
53
+ resolve();
54
+ }
55
+ }); // callback
56
+ }); // promise
57
+ }
58
+
59
+ function clearStore() {
60
+ store.statements.slice().forEach(store.remove.bind(store));
61
+ }
62
+
63
+ return {
64
+ store,
65
+ authn,
66
+ acl,
67
+ inbox,
68
+ chat,
69
+ profile,
70
+ typeIndex,
71
+ load,
72
+ updatePromise,
73
+ clearStore
74
+ }
75
+ }
@@ -1,6 +1,6 @@
1
1
  import * as debug from "../util/debug"
2
2
  import { authSession } from "../authSession/authSession"
3
- import { SolidLogic } from "./SolidLogic"
3
+ import { createSolidLogic } from "./solidLogic"
4
4
 
5
5
  const _fetch = async (url, requestInit) => {
6
6
  const omitCreds = requestInit && requestInit.credentials && requestInit.credentials == 'omit'
@@ -13,7 +13,7 @@ const _fetch = async (url, requestInit) => {
13
13
  }
14
14
 
15
15
  //this const makes solidLogicSingleton global accessible in mashlib
16
- const solidLogicSingleton = new SolidLogic({ fetch: _fetch }, authSession)
16
+ const solidLogicSingleton = createSolidLogic({ fetch: _fetch }, authSession)
17
17
 
18
18
  debug.log('Unique quadstore initialized.')
19
19
 
@@ -1,20 +1,13 @@
1
1
  import { NamedNode } from "rdflib";
2
2
  import { CrossOriginForbiddenError, FetchError, NotEditableError, SameOriginForbiddenError, UnauthorizedError, WebOperationError } from "../logic/CustomError";
3
- import { AuthenticationContext } from "../types";
4
3
  import * as debug from "../util/debug";
5
- import { differentOrigin, suggestPreferencesFile } from "../util/utils";
6
- import { ns as namespace } from '../util/ns'
4
+ import { ns as namespace } from '../util/ns';
5
+ import { differentOrigin, suggestPreferencesFile } from "../util/utils"
6
+ import { ProfileLogic } from "../types"
7
7
 
8
- export function createProfileLogic(store, authn, utilityLogic) {
8
+ export function createProfileLogic(store, authn, utilityLogic): ProfileLogic {
9
9
  const ns = namespace
10
10
 
11
- async function ensureLoadedPreferences (context: AuthenticationContext) {
12
- if (!context.me) throw new Error('@@ ensureLoadedPreferences: no user specified')
13
- context.publicProfile = await loadProfile(context.me)
14
- context.preferencesFile = await silencedLoadPreferences(context.me)
15
- return context
16
- }
17
-
18
11
  /**
19
12
  * loads the preference without throwing errors - if it can create it it does so.
20
13
  * remark: it still throws error if it cannot load profile.
@@ -121,7 +114,6 @@ export function createProfileLogic(store, authn, utilityLogic) {
121
114
  }
122
115
 
123
116
  return {
124
- ensureLoadedPreferences,
125
117
  loadMe,
126
118
  getPodRoot,
127
119
  getMainInbox,
@@ -1,273 +1,11 @@
1
- import * as rdf from "rdflib"
2
- import { NamedNode, st, Statement, sym } from 'rdflib'
3
- import { AuthenticationContext, ScopedApp, TypeIndexScope } from '../types'
1
+ import { NamedNode, st, sym } from 'rdflib'
2
+ import { ScopedApp, TypeIndexLogic, TypeIndexScope } from '../types'
4
3
  import * as debug from "../util/debug"
5
- import {ns as namespace } from '../util/ns'
4
+ import { ns as namespace } from '../util/ns'
6
5
  import { newThing, uniqueNodes } from "../util/utils"
7
6
 
8
- export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic) {
7
+ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic): TypeIndexLogic {
9
8
  const ns = namespace
10
-
11
- function updatePromise(
12
- del: Array<Statement>,
13
- ins: Array<Statement> = []
14
- ): Promise<void> {
15
- return new Promise((resolve, reject) => {
16
- store.updater.update(del, ins, function (_uri, ok, errorBody) {
17
- if (!ok) {
18
- reject(new Error(errorBody));
19
- } else {
20
- resolve();
21
- }
22
- }); // callback
23
- }); // promise
24
- }
25
- /**
26
- * Resolves with the same context, outputting
27
- * @see https://github.com/solidos/solid/blob/main/proposals/data-discovery.md#discoverability
28
- */
29
- async function ensureTypeIndexes(context: AuthenticationContext, agent?: NamedNode): Promise<AuthenticationContext> {
30
- if (!context.me) {
31
- throw new Error(`ensureTypeIndexes: @@ no user`)
32
- }
33
- await ensureOneTypeIndex(context, true, agent)
34
- await ensureOneTypeIndex(context, false, agent)
35
- return context
36
- }
37
-
38
- async function loadTypeIndexes(context: AuthenticationContext) {
39
- try {
40
- await profileLogic.silencedLoadPreferences(context.me as NamedNode)
41
- } catch (error) {
42
- debug.warn(error.message) as undefined
43
- }
44
- try {
45
- const indexes = await loadIndexes(
46
- context.me as NamedNode,
47
- context.publicProfile || null,
48
- context.preferencesFile || null,
49
- // async (err: Error) => widgets.complain(context, err.message)
50
- // async (err: Error) => debug.warn(err.message) as undefined
51
- )
52
- context.index = context.index || {}
53
- context.index.private = indexes.private || context.index.private
54
- context.index.public = indexes.public || context.index.public
55
- return context
56
- } catch (error) {
57
- async (error: Error) => debug.warn(error.message) as undefined
58
- }
59
- }
60
-
61
- /**
62
- * Register a new app in a type index
63
- * used in chat in bookmark.js (solid-ui)
64
- */
65
- async function registerInTypeIndex(
66
- context: AuthenticationContext,
67
- instance: NamedNode,
68
- theClass: NamedNode,
69
- isPublic: boolean,
70
- agent?: NamedNode // Defaults to current user
71
- ): Promise<AuthenticationContext> {
72
- await ensureOneTypeIndex(context, isPublic, agent)
73
- if (!context.index) {
74
- throw new Error('registerInTypeIndex: No type index found')
75
- }
76
- const indexes = isPublic ? context.index.public : context.index.private
77
- if (!indexes.length) {
78
- throw new Error('registerInTypeIndex: What no type index?')
79
- }
80
- const index = indexes[0]
81
- const registration = newThing(index)
82
- const ins = [
83
- // See https://github.com/solidos/solid/blob/main/proposals/data-discovery.md
84
- st(registration, ns.rdf('type'), ns.solid('TypeRegistration'), index),
85
- st(registration, ns.solid('forClass'), theClass, index),
86
- st(registration, ns.solid('instance'), instance, index)
87
- ]
88
- try {
89
- await updatePromise([], ins)
90
- } catch (e) {
91
- debug.log(e)
92
- alert(e)
93
- }
94
- return context
95
- }
96
-
97
- /**
98
- * Resolves with the same context, outputting
99
- * output: index.public, index.private
100
- * @@ This is a very bizare function
101
- * @see https://github.com/solidos/solid/blob/main/proposals/data-discovery.md#discoverability
102
- */
103
- async function loadIndex(
104
- context: AuthenticationContext,
105
- isPublic: boolean
106
- ): Promise<AuthenticationContext> {
107
- const indexes = await loadIndexes(
108
- context.me as NamedNode,
109
- (isPublic ? context.publicProfile || null : null),
110
- (isPublic ? null : context.preferencesFile || null),
111
- // async (err: Error) => widgets.complain(context, err.message)
112
- async (err: Error) => debug.error(err.message) as undefined
113
- )
114
- context.index = context.index || {}
115
- context.index.private = indexes.private.concat(context.index.private || []) // otherwise concat will wrongly add 'undefined' as a private index
116
- context.index.public = indexes.public.concat(context.index.public || []) // otherwise concat will wrongly add 'undefined' as a public index
117
- return context
118
- }
119
-
120
- /**
121
- * Load or create ONE type index
122
- * Find one or make one or fail
123
- * Many reasons for failing including script not having permission etc
124
- *
125
- * Adds its output to the context
126
- * @see https://github.com/solidos/solid/blob/main/proposals/data-discovery.md#discoverability
127
- */
128
- async function ensureOneTypeIndex(context: AuthenticationContext, isPublic: boolean, agent?: NamedNode): Promise<AuthenticationContext | void> {
129
-
130
- const context2 = await profileLogic.ensureLoadedPreferences(context)
131
- if (!context2.publicProfile) throw new Error(`@@ type index: no publicProfile`)
132
- if (!context2.preferencesFile) throw new Error(`@@ type index: no preferencesFile for profile ${context2.publicProfile}`)
133
- const relevant = isPublic ? context2.publicProfile : context2.preferencesFile
134
-
135
- try {
136
- await loadIndex(context2, isPublic)
137
- const pp = isPublic ? 'public' : 'private'
138
- if (context2.index && context2.index[pp] && context2.index[pp].length > 0) {
139
- debug.log(`ensureOneTypeIndex: Type index exists already ${context2.index[pp]}`)
140
- return context2
141
- }
142
- await makeIndexIfNecessary(context2, isPublic, store, ns)
143
- } catch (error) {
144
- await makeIndexIfNecessary(context2, isPublic, store, ns)
145
- // widgets.complain(context2, 'calling loadIndex:' + error)
146
- }
147
- }
148
-
149
- async function putIndex(newIndex, context) {
150
- try {
151
- await utilityLogic.createEmptyRdfDoc(newIndex, 'Blank initial Type index')
152
- return context
153
- } catch (e) {
154
- const msg = `Error creating new index ${e}`
155
- // widgets.complain(context, msg)
156
- debug.warn(msg)
157
- }
158
- } // putIndex
159
-
160
- async function makeIndexIfNecessary(context, isPublic, store, ns) {
161
- const relevant = isPublic ? context.publicProfile : context.preferencesFile
162
- if (!relevant) alert('@@@@ relevent null')
163
- const visibility = isPublic ? 'public' : 'private'
164
-
165
- context.index = context.index || {}
166
- context.index[visibility] = context.index[visibility] || []
167
- let newIndex
168
- if (context.index[visibility].length === 0) {
169
- if (!store.updater.editable(relevant)) {
170
- debug.log(`Not adding new type index as ${relevant} is not editable`)
171
- return
172
- }
173
- newIndex = rdf.sym(`${relevant.dir().uri + visibility}TypeIndex.ttl`)
174
- debug.log(`Linking to new fresh type index ${newIndex}`)
175
- if (!confirm(`OK to create a new empty index file at ${newIndex}, overwriting anything that is now there?`)) {
176
- throw new Error('cancelled by user')
177
- }
178
- debug.log(`Linking to new fresh type index ${newIndex}`)
179
- const addMe = [
180
- st(context.me, ns.solid(`${visibility}TypeIndex`), newIndex, relevant)
181
- ]
182
- try {
183
- await updatePromise([], addMe)
184
- } catch (err) {
185
- const msg = `Error saving type index link saving back ${newIndex}: ${err}`
186
- //widgets.complain(context, msg)
187
- debug.warn(msg)
188
- return context
189
- }
190
-
191
- debug.log(`Creating new fresh type index file${newIndex}`)
192
- await putIndex(newIndex, context)
193
- context.index[visibility].push(newIndex) // @@ wait
194
- } else {
195
- // officially exists
196
- const ixs = context.index[visibility]
197
- try {
198
- await store.fetcher.load(ixs)
199
- } catch (err) {
200
- const msg = `ensureOneTypeIndex: loading indexes ${err}`
201
- debug.warn(msg)
202
- // widgets.complain(context, `ensureOneTypeIndex: loading indexes ${err}`)
203
- }
204
- }
205
- } // makeIndexIfNecessary
206
-
207
- async function loadIndexes(
208
- me: NamedNode | string,
209
- publicProfile: NamedNode | string | null,
210
- preferencesFile: NamedNode | string | null,
211
- onWarning = async (_err: Error) => {
212
- return undefined;
213
- }
214
- ): Promise<{
215
- private: any;
216
- public: any;
217
- }> {
218
- let privateIndexes: any[] = [];
219
- let publicIndexes: any[] = [];
220
- if (publicProfile) {
221
- publicIndexes = getTypeIndex(me, publicProfile, true);
222
- try {
223
- await store.fetcher.load(publicIndexes as NamedNode[]);
224
- } catch (err) {
225
- onWarning(new Error(`loadIndex: loading public type index(es) ${err}`));
226
- }
227
- }
228
- if (preferencesFile) {
229
- privateIndexes = getTypeIndex(me, preferencesFile, false);
230
- // console.log({ privateIndexes })
231
- if (privateIndexes.length === 0) {
232
- await onWarning(
233
- new Error(
234
- `Your preference file ${preferencesFile} does not point to a private type index.`
235
- )
236
- );
237
- } else {
238
- try {
239
- await store.fetcher.load(privateIndexes);
240
- } catch (err) {
241
- onWarning(
242
- new Error(`loadIndex: loading private type index(es) ${err}`)
243
- );
244
- }
245
- }
246
- // } else {
247
- // debug.log(
248
- // 'We know your preference file is not available, so we are not bothering with private type indexes.'
249
- // )
250
- }
251
-
252
- return {
253
- private: privateIndexes,
254
- public: publicIndexes,
255
- };
256
- }
257
-
258
- function getTypeIndex(
259
- me: NamedNode | string,
260
- preferencesFile: NamedNode | string,
261
- isPublic: boolean
262
- ): NamedNode[] {
263
- // console.log('getTypeIndex', store.each(me, undefined, undefined, preferencesFile), isPublic, preferencesFile)
264
- return store.each(
265
- me as NamedNode,
266
- isPublic ? ns.solid("publicTypeIndex") : ns.solid("privateTypeIndex"),
267
- undefined,
268
- preferencesFile as NamedNode
269
- ) as NamedNode[];
270
- }
271
9
 
272
10
  function getRegistrations(instance, theClass) {
273
11
  return store
@@ -385,7 +123,7 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic) {
385
123
  * used in chat in bookmark.js (solid-ui)
386
124
  * Returns the registration object if successful else null
387
125
  */
388
- async function registerInstanceInTypeIndex(
126
+ async function registerInTypeIndex(
389
127
  instance: NamedNode,
390
128
  index: NamedNode,
391
129
  theClass: NamedNode,
@@ -415,7 +153,7 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic) {
415
153
  await store.updater.update(statements, [])
416
154
  }
417
155
 
418
- async function getScopedAppsFromIndex(scope, theClass: NamedNode | null) {
156
+ async function getScopedAppsFromIndex(scope: TypeIndexScope, theClass: NamedNode | null): Promise<ScopedApp[]> {
419
157
  const index = scope.index
420
158
  const registrations = store.statementsMatching(null, ns.solid('instance'), null, index)
421
159
  .concat(store.statementsMatching(null, ns.solid('instanceContainer'), null, index))
@@ -441,15 +179,7 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic) {
441
179
  }
442
180
 
443
181
  return {
444
- ensureTypeIndexes,
445
- loadTypeIndexes,
446
182
  registerInTypeIndex,
447
- loadIndex,
448
- ensureOneTypeIndex,
449
- putIndex,
450
- makeIndexIfNecessary,
451
- loadIndexes,
452
- getTypeIndex,
453
183
  getRegistrations,
454
184
  loadTypeIndexesFor,
455
185
  loadCommunityTypeIndexes,
@@ -458,7 +188,6 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic) {
458
188
  getAppInstances,
459
189
  suggestPublicTypeIndex,
460
190
  suggestPrivateTypeIndex,
461
- registerInstanceInTypeIndex,
462
191
  deleteTypeIndexRegistration,
463
192
  getScopedAppsFromIndex
464
193
  }
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Session } from "@inrupt/solid-client-authn-browser"
2
- import { NamedNode } from "rdflib"
2
+ import { LiveStore, NamedNode, Statement } from "rdflib"
3
3
 
4
4
  export type AppDetails = {
5
5
  noun: string
@@ -45,3 +45,78 @@ export interface CreatedPaneOptions {
45
45
  newInstance: NamedNode;
46
46
  }
47
47
 
48
+ export interface ChatLogic {
49
+ setAcl: (chatContainer: NamedNode, me: NamedNode, invitee: NamedNode) => Promise<void>,
50
+ addToPrivateTypeIndex: (chatThing, me) => void | Promise<void>,
51
+ findChat: (invitee: NamedNode) => Promise<Chat>,
52
+ createChatThing: (chatContainer: NamedNode, me: NamedNode) => Promise<NamedNode>,
53
+ mintNew: (newPaneOptions: NewPaneOptions) => Promise<CreatedPaneOptions>,
54
+ getChat: (invitee: NamedNode, boolean) => Promise<NamedNode | null>,
55
+ sendInvite: (invitee: NamedNode, chatThing: NamedNode) => void
56
+ }
57
+
58
+ export interface Chat {
59
+ me: NamedNode,
60
+ chatContainer: NamedNode,
61
+ exists: boolean
62
+ }
63
+
64
+ export interface ProfileLogic {
65
+ silencedLoadPreferences: (user: NamedNode) => Promise<NamedNode | undefined>,
66
+ loadPreferences: (user: NamedNode) => Promise<NamedNode>,
67
+ loadProfile: (user: NamedNode) => Promise<NamedNode>,
68
+ loadMe: () => Promise<NamedNode>,
69
+ getPodRoot: (user: NamedNode) => NamedNode,
70
+ getMainInbox: (user: NamedNode) => Promise<NamedNode>,
71
+ findStorage: (me: NamedNode) => Node | null
72
+ }
73
+
74
+ export interface AclLogic {
75
+ findAclDocUrl: (url: NamedNode) => Promise<any>,
76
+ setACLUserPublic: (docURI: string, me: NamedNode,
77
+ options: {
78
+ defaultForNew?: boolean,
79
+ public?: []
80
+ }
81
+ ) => Promise<NamedNode>,
82
+ genACLText: (docURI: string, me: NamedNode, aclURI: string,
83
+ options: {
84
+ defaultForNew?: boolean,
85
+ public?: []
86
+ }
87
+ ) => string | undefined
88
+ }
89
+
90
+ export interface InboxLogic {
91
+ createInboxFor: (peerWebId: string, nick: string) => Promise<string>,
92
+ getNewMessages: (user?: NamedNode) => Promise<NamedNode[]>,
93
+ markAsRead: (url: string, date: Date) => void
94
+ }
95
+
96
+ export interface TypeIndexLogic {
97
+ getRegistrations: (instance, theClass) => Node[],
98
+ loadTypeIndexesFor: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
99
+ loadCommunityTypeIndexes: (user: NamedNode) => Promise<TypeIndexScope[][]>,
100
+ loadAllTypeIndexes: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
101
+ getScopedAppInstances: (klass: NamedNode, user: NamedNode) => Promise<ScopedApp[]>,
102
+ getAppInstances: (klass: NamedNode) => Promise<NamedNode[]>,
103
+ suggestPublicTypeIndex: (me: NamedNode) => NamedNode,
104
+ suggestPrivateTypeIndex: (preferencesFile: NamedNode) => NamedNode,
105
+ registerInTypeIndex: (instance: NamedNode, index: NamedNode, theClass: NamedNode) => Promise<NamedNode | null>,
106
+ deleteTypeIndexRegistration: (item: any) => Promise<void>
107
+ getScopedAppsFromIndex: (scope: TypeIndexScope, theClass: NamedNode | null) => Promise<ScopedApp[]>
108
+ }
109
+
110
+ export interface SolidLogic {
111
+ store: LiveStore,
112
+ authn: AuthnLogic,
113
+ acl: AclLogic,
114
+ profile: ProfileLogic,
115
+ inbox: InboxLogic,
116
+ typeIndex: TypeIndexLogic,
117
+ chat: ChatLogic,
118
+ load: (doc: NamedNode | NamedNode[] | string) => void,
119
+ updatePromise: (del: Array<Statement>, ins: Array<Statement>) => Promise<void>,
120
+ clearStore: () => void
121
+ }
122
+
@@ -6,44 +6,43 @@ import { NamedNode, Statement, sym } from "rdflib";
6
6
  export function createContainerLogic(store) {
7
7
 
8
8
  function getContainerElements(containerNode: NamedNode): NamedNode[] {
9
- return store
10
- .statementsMatching(
11
- containerNode,
12
- sym("http://www.w3.org/ns/ldp#contains"),
13
- undefined,
14
- containerNode.doc()
15
- )
16
- .map((st: Statement) => st.object as NamedNode);
9
+ return store
10
+ .statementsMatching(
11
+ containerNode,
12
+ sym("http://www.w3.org/ns/ldp#contains"),
13
+ undefined
14
+ )
15
+ .map((st: Statement) => st.object as NamedNode);
17
16
  }
18
17
 
19
- function isContainer(url: string) {
20
- return url.charAt(url.length - 1) === "/";
18
+ function isContainer(url: NamedNode) {
19
+ const nodeToString = url.value;
20
+ return nodeToString.charAt(nodeToString.length - 1) === "/";
21
21
  }
22
22
 
23
23
  async function createContainer(url: string) {
24
- if (!isContainer(url)) {
25
- throw new Error(`Not a container URL ${url}`);
26
- }
27
- // Copied from https://github.com/solidos/solid-crud-tests/blob/v3.1.0/test/surface/create-container.test.ts#L56-L64
28
- const result = await store.fetcher._fetch(url, {
29
- method: "PUT",
30
- headers: {
31
- "Content-Type": "text/turtle",
32
- "If-None-Match": "*",
33
- Link: '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"', // See https://github.com/solidos/node-solid-server/issues/1465
34
- },
35
- body: " ", // work around https://github.com/michielbdejong/community-server/issues/4#issuecomment-776222863
36
- });
37
- if (result.status.toString()[0] !== '2') {
38
- throw new Error(`Not OK: got ${result.status} response while creating container at ${url}`);
39
- }
24
+ const stringToNode = sym(url);
25
+ if (!isContainer(stringToNode)) {
26
+ throw new Error(`Not a container URL ${url}`);
27
+ }
28
+ // Copied from https://github.com/solidos/solid-crud-tests/blob/v3.1.0/test/surface/create-container.test.ts#L56-L64
29
+ const result = await store.fetcher._fetch(url, {
30
+ method: "PUT",
31
+ headers: {
32
+ "Content-Type": "text/turtle",
33
+ "If-None-Match": "*",
34
+ Link: '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"', // See https://github.com/solidos/node-solid-server/issues/1465
35
+ },
36
+ body: " ", // work around https://github.com/michielbdejong/community-server/issues/4#issuecomment-776222863
37
+ });
38
+ if (result.status.toString()[0] !== '2') {
39
+ throw new Error(`Not OK: got ${result.status} response while creating container at ${url}`);
40
+ }
40
41
  }
41
42
 
42
- async function getContainerMembers(containerUrl: string): Promise<string[]> {
43
- const containerNode = store.sym(containerUrl);
44
- await store.fetcher.load(containerNode);
45
- const nodes = getContainerElements(containerNode);
46
- return nodes.map(node => node.value);
43
+ async function getContainerMembers(containerUrl: NamedNode): Promise<NamedNode[]> {
44
+ await store.fetcher.load(containerUrl);
45
+ return getContainerElements(containerUrl);
47
46
  }
48
47
  return {
49
48
  isContainer,
File without changes
@@ -1,21 +1,22 @@
1
- import { NamedNode, st } from "rdflib";
1
+ import { NamedNode, st, sym } from "rdflib";
2
2
  import { CrossOriginForbiddenError, FetchError, NotEditableError, SameOriginForbiddenError, UnauthorizedError, WebOperationError } from "../logic/CustomError";
3
3
  import * as debug from '../util/debug';
4
4
  import { differentOrigin } from "./utils";
5
5
 
6
6
  export function createUtilityLogic(store, aclLogic, containerLogic) {
7
7
 
8
- async function recursiveDelete(url: string) {
8
+ async function recursiveDelete(containerNode: NamedNode) {
9
9
  try {
10
- if (containerLogic.isContainer(url)) {
11
- const aclDocUrl = await aclLogic.findAclDocUrl(url);
10
+ if (containerLogic.isContainer(containerNode)) {
11
+ const aclDocUrl = await aclLogic.findAclDocUrl(containerNode)
12
12
  await store.fetcher._fetch(aclDocUrl, { method: "DELETE" });
13
- const containerMembers = await containerLogic.getContainerMembers(url);
13
+ const containerMembers = await containerLogic.getContainerMembers(containerNode);
14
14
  await Promise.all(
15
15
  containerMembers.map((url) => recursiveDelete(url))
16
16
  );
17
17
  }
18
- return store.fetcher._fetch(url, { method: "DELETE" });
18
+ const nodeToStringHere = containerNode.value;
19
+ return store.fetcher._fetch(nodeToStringHere, { method: "DELETE" });
19
20
  } catch (e) {
20
21
  // debug.log(`Please manually remove ${url} from your system under test.`, e);
21
22
  }
@@ -126,7 +127,7 @@ export function createUtilityLogic(store, aclLogic, containerLogic) {
126
127
  ''
127
128
  ].join('\n')
128
129
  }
129
- const aclDocUrl = await aclLogic.findAclDocUrl(options.target);
130
+ const aclDocUrl = await aclLogic.findAclDocUrl(sym(options.target))
130
131
  return store.fetcher._fetch(aclDocUrl, {
131
132
  method: 'PUT',
132
133
  body: str,