solid-logic 1.3.17-ec29db42 → 1.3.17-f7bdc345
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/lib/discovery/discoveryLogic.d.ts +8 -8
- package/lib/discovery/discoveryLogic.d.ts.map +1 -1
- package/lib/discovery/discoveryLogic.js +63 -68
- package/lib/discovery/discoveryLogic.js.map +1 -1
- package/lib/inbox/InboxLogic.js +2 -2
- package/lib/inbox/InboxLogic.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +17 -4
- package/lib/index.js.map +1 -1
- package/lib/logic/SolidLogic.d.ts +2 -5
- package/lib/logic/SolidLogic.d.ts.map +1 -1
- package/lib/logic/SolidLogic.js +2 -3
- package/lib/logic/SolidLogic.js.map +1 -1
- package/lib/util/UtilityLogic.d.ts +3 -9
- package/lib/util/UtilityLogic.d.ts.map +1 -1
- package/lib/util/UtilityLogic.js +6 -30
- package/lib/util/UtilityLogic.js.map +1 -1
- package/package.json +3 -1
- package/src/discovery/discoveryLogic.ts +65 -84
- package/src/inbox/InboxLogic.ts +2 -2
- package/src/index.ts +16 -3
- package/src/logic/SolidLogic.ts +2 -5
- package/src/util/UtilityLogic.ts +6 -23
- package/test/discoveryLogic.test.ts +14 -14
|
@@ -7,12 +7,7 @@ export declare const ACL_LINK: NamedNode;
|
|
|
7
7
|
export declare class UtilityLogic {
|
|
8
8
|
store: LiveStore;
|
|
9
9
|
ns: SolidNamespace;
|
|
10
|
-
|
|
11
|
-
fetch: (url: string, options?: any) => any;
|
|
12
|
-
};
|
|
13
|
-
constructor(store: LiveStore, ns: SolidNamespace, underlyingFetch: {
|
|
14
|
-
fetch: (url: string, options?: any) => any;
|
|
15
|
-
});
|
|
10
|
+
constructor(store: LiveStore, ns: SolidNamespace);
|
|
16
11
|
findAclDocUrl(url: string): Promise<string>;
|
|
17
12
|
setSinglePeerAccess(options: {
|
|
18
13
|
ownerWebId: string;
|
|
@@ -20,13 +15,12 @@ export declare class UtilityLogic {
|
|
|
20
15
|
accessToModes?: string;
|
|
21
16
|
defaultModes?: string;
|
|
22
17
|
target: string;
|
|
23
|
-
}): Promise<
|
|
24
|
-
loadDoc(doc: NamedNode): Promise<void>;
|
|
18
|
+
}): Promise<import("rdflib").ExtendedResponse>;
|
|
25
19
|
isContainer(url: string): boolean;
|
|
26
20
|
createContainer(url: string): Promise<void>;
|
|
27
21
|
getContainerElements(containerNode: NamedNode): NamedNode[];
|
|
28
22
|
getContainerMembers(containerUrl: string): Promise<string[]>;
|
|
29
|
-
recursiveDelete(url: string): Promise<
|
|
23
|
+
recursiveDelete(url: string): Promise<import("rdflib").ExtendedResponse | undefined>;
|
|
30
24
|
clearStore(): void;
|
|
31
25
|
getArchiveUrl(baseUrl: string, date: Date): string;
|
|
32
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UtilityLogic.d.ts","sourceRoot":"","sources":["../../src/util/UtilityLogic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,eAAO,MAAM,QAAQ,WAEpB,CAAC;AAEF;;GAEG;AACH,qBAAa,YAAY;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,EAAE,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"UtilityLogic.d.ts","sourceRoot":"","sources":["../../src/util/UtilityLogic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,eAAO,MAAM,QAAQ,WAEpB,CAAC;AAEF;;GAEG;AACH,qBAAa,YAAY;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,EAAE,EAAE,cAAc,CAAC;gBAEP,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,cAAc;IAK1C,aAAa,CAAC,GAAG,EAAE,MAAM;IAWzB,mBAAmB,CAAC,OAAO,EAAE;QACjC,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAA;KACf;IAsCD,WAAW,CAAC,GAAG,EAAE,MAAM;IAIjB,eAAe,CAAC,GAAG,EAAE,MAAM;IAmBjC,oBAAoB,CAAC,aAAa,EAAE,SAAS,GAAG,SAAS,EAAE;IAWrD,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAO5D,eAAe,CAAC,GAAG,EAAE,MAAM;IAgBjC,UAAU;IAIV,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI;CAQ1C"}
|
package/lib/util/UtilityLogic.js
CHANGED
|
@@ -43,10 +43,9 @@ exports.ACL_LINK = (0, rdflib_1.sym)("http://www.iana.org/assignments/link-relat
|
|
|
43
43
|
* Utility-related logic
|
|
44
44
|
*/
|
|
45
45
|
var UtilityLogic = /** @class */ (function () {
|
|
46
|
-
function UtilityLogic(store, ns
|
|
46
|
+
function UtilityLogic(store, ns) {
|
|
47
47
|
this.store = store;
|
|
48
48
|
this.ns = ns;
|
|
49
|
-
this.underlyingFetch = underlyingFetch;
|
|
50
49
|
}
|
|
51
50
|
UtilityLogic.prototype.findAclDocUrl = function (url) {
|
|
52
51
|
var _a;
|
|
@@ -105,7 +104,7 @@ var UtilityLogic = /** @class */ (function () {
|
|
|
105
104
|
return [4 /*yield*/, this.findAclDocUrl(options.target)];
|
|
106
105
|
case 1:
|
|
107
106
|
aclDocUrl = _a.sent();
|
|
108
|
-
return [2 /*return*/, this.
|
|
107
|
+
return [2 /*return*/, this.store.fetcher._fetch(aclDocUrl, {
|
|
109
108
|
method: 'PUT',
|
|
110
109
|
body: str,
|
|
111
110
|
headers: [
|
|
@@ -116,31 +115,8 @@ var UtilityLogic = /** @class */ (function () {
|
|
|
116
115
|
});
|
|
117
116
|
});
|
|
118
117
|
};
|
|
119
|
-
UtilityLogic.prototype.loadDoc = function (doc) {
|
|
120
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
121
|
-
return __generator(this, function (_a) {
|
|
122
|
-
switch (_a.label) {
|
|
123
|
-
case 0:
|
|
124
|
-
// Load a document into the knowledge base (fetcher.store)
|
|
125
|
-
// withCredentials: Web arch should let us just load by turning off creds helps CORS
|
|
126
|
-
// reload: Gets around a specific old Chrome bug caching/origin/cors
|
|
127
|
-
// console.log('loading', profileDocument)
|
|
128
|
-
if (!this.store.fetcher) {
|
|
129
|
-
throw new Error("Cannot load doc, have no fetcher");
|
|
130
|
-
}
|
|
131
|
-
return [4 /*yield*/, this.store.fetcher.load(doc, {
|
|
132
|
-
withCredentials: false,
|
|
133
|
-
cache: "reload",
|
|
134
|
-
})];
|
|
135
|
-
case 1:
|
|
136
|
-
_a.sent();
|
|
137
|
-
return [2 /*return*/];
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
};
|
|
142
118
|
UtilityLogic.prototype.isContainer = function (url) {
|
|
143
|
-
return url.
|
|
119
|
+
return url.charAt(url.length - 1) === "/";
|
|
144
120
|
};
|
|
145
121
|
UtilityLogic.prototype.createContainer = function (url) {
|
|
146
122
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -151,7 +127,7 @@ var UtilityLogic = /** @class */ (function () {
|
|
|
151
127
|
if (!this.isContainer(url)) {
|
|
152
128
|
throw new Error("Not a container URL ".concat(url));
|
|
153
129
|
}
|
|
154
|
-
return [4 /*yield*/, this.
|
|
130
|
+
return [4 /*yield*/, this.store.fetcher._fetch(url, {
|
|
155
131
|
method: "PUT",
|
|
156
132
|
headers: {
|
|
157
133
|
"Content-Type": "text/turtle",
|
|
@@ -204,7 +180,7 @@ var UtilityLogic = /** @class */ (function () {
|
|
|
204
180
|
return [4 /*yield*/, this.findAclDocUrl(url)];
|
|
205
181
|
case 1:
|
|
206
182
|
aclDocUrl = _a.sent();
|
|
207
|
-
return [4 /*yield*/, this.
|
|
183
|
+
return [4 /*yield*/, this.store.fetcher._fetch(aclDocUrl, { method: "DELETE" })];
|
|
208
184
|
case 2:
|
|
209
185
|
_a.sent();
|
|
210
186
|
return [4 /*yield*/, this.getContainerMembers(url)];
|
|
@@ -214,7 +190,7 @@ var UtilityLogic = /** @class */ (function () {
|
|
|
214
190
|
case 4:
|
|
215
191
|
_a.sent();
|
|
216
192
|
_a.label = 5;
|
|
217
|
-
case 5: return [2 /*return*/, this.
|
|
193
|
+
case 5: return [2 /*return*/, this.store.fetcher._fetch(url, { method: "DELETE" })];
|
|
218
194
|
case 6:
|
|
219
195
|
e_1 = _a.sent();
|
|
220
196
|
return [3 /*break*/, 7];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UtilityLogic.js","sourceRoot":"","sources":["../../src/util/UtilityLogic.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iCAA8D;AAGjD,QAAA,QAAQ,GAAG,IAAA,YAAG,EACzB,oDAAoD,CACrD,CAAC;AAEF;;GAEG;AACH;
|
|
1
|
+
{"version":3,"file":"UtilityLogic.js","sourceRoot":"","sources":["../../src/util/UtilityLogic.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solid-logic",
|
|
3
|
-
"version": "1.3.17-
|
|
3
|
+
"version": "1.3.17-f7bdc345",
|
|
4
4
|
"description": "Core business logic of Solid OS",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"clean": "rm -rf lib",
|
|
9
9
|
"lint": "eslint ./src",
|
|
10
10
|
"test": "jest",
|
|
11
|
+
"test-debug": "node --inspect-brk ./node_modules/.bin/jest -i --env jest-environment-node-debug",
|
|
11
12
|
"preversion": "npm test",
|
|
12
13
|
"postversion": "git push --follow-tags",
|
|
13
14
|
"ignore:prepublishOnly": "npm run build",
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
"@typescript-eslint/parser": "^5.19.0",
|
|
36
37
|
"eslint": "^8.13.0",
|
|
37
38
|
"jest": "^27.5.1",
|
|
39
|
+
"jest-environment-node-debug": "^2.0.0",
|
|
38
40
|
"jest-fetch-mock": "^3.0.3",
|
|
39
41
|
"typescript": "^4.6.3"
|
|
40
42
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { NamedNode, LiveStore, sym, st } from 'rdflib'
|
|
1
2
|
import * as $rdf from 'rdflib'
|
|
2
|
-
import {
|
|
3
|
+
import { solidLogicSingleton } from "../logic/solidLogicSingleton"
|
|
4
|
+
import { newThing } from "../util/uri"
|
|
3
5
|
import solidNamespace from 'solid-namespace'
|
|
4
|
-
import { solidLogicSingleton } from '../logic/solidLogicSingleton'
|
|
5
|
-
import { newThing } from '../util/uri'
|
|
6
6
|
|
|
7
7
|
const { authn } = solidLogicSingleton
|
|
8
8
|
const { currentUser } = authn
|
|
@@ -18,30 +18,24 @@ type ScopedApp = { instance: NamedNode, scope: TypeIndexScope }
|
|
|
18
18
|
* @param doc {NamedNode} - The resource
|
|
19
19
|
*/
|
|
20
20
|
export async function loadOrCreateIfNotExists (store: LiveStore, doc: NamedNode) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
21
|
+
let response
|
|
22
|
+
try {
|
|
23
|
+
response = await store.fetcher.load(doc)
|
|
24
|
+
} catch (err) {
|
|
25
|
+
if (err.response.status === 404) {
|
|
26
|
+
try {
|
|
27
|
+
store.fetcher.webOperation('PUT', doc, {data: '', contentType: 'text/turtle'})
|
|
28
|
+
} catch (err) {
|
|
29
|
+
const msg = 'createIfNotExists: PUT FAILED: ' + doc + ': ' + err
|
|
30
|
+
throw new Error(msg)
|
|
31
|
+
}
|
|
32
|
+
delete store.fetcher.requested[doc.uri] // delete cached 404 error
|
|
33
|
+
} else {
|
|
34
|
+
const msg = 'createIfNotExists doc load error NOT 404: ' + doc + ': ' + err
|
|
35
|
+
throw new Error(msg) // @@ add nested errors
|
|
34
36
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} else {
|
|
38
|
-
const msg = 'createIfNotExists doc load error NOT 404: ' + doc + ': ' + err
|
|
39
|
-
// console.log(msg)
|
|
40
|
-
throw new Error(msg) // @@ add nested errors
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// console.log('createIfNotExists doc exists, all good ' + doc)
|
|
44
|
-
return response
|
|
37
|
+
}
|
|
38
|
+
return response
|
|
45
39
|
}
|
|
46
40
|
|
|
47
41
|
export function suggestPreferencesFile (me:NamedNode) {
|
|
@@ -65,16 +59,13 @@ export function suggestPrivateTypeIndex (preferencesFile:NamedNode) {
|
|
|
65
59
|
**
|
|
66
60
|
** return: null no ld one and failed to make a new one
|
|
67
61
|
*/
|
|
68
|
-
export async function followOrCreateLink(store: LiveStore, subject: NamedNode, predicate: NamedNode,
|
|
69
|
-
|
|
62
|
+
export async function followOrCreateLink (store: LiveStore, subject: NamedNode, predicate: NamedNode,
|
|
63
|
+
object: NamedNode, doc:NamedNode):Promise<NamedNode | null> {
|
|
70
64
|
await store.fetcher.load(doc)
|
|
71
65
|
const result = store.any(subject, predicate, null, doc)
|
|
72
|
-
// console.log('@@ followOrCreateLink result ', result)
|
|
73
66
|
|
|
74
67
|
if (result) return result as NamedNode
|
|
75
68
|
if (!store.updater.editable(doc)) {
|
|
76
|
-
// console.log(`followOrCreateLink: Can't modify ${doc} so can't make new link to ${object}.`)
|
|
77
|
-
// console.log('followOrCreateLink @@ connectedStatements', store.connectedStatements(subject))
|
|
78
69
|
return null
|
|
79
70
|
}
|
|
80
71
|
try {
|
|
@@ -84,57 +75,48 @@ export async function followOrCreateLink(store: LiveStore, subject: NamedNode, p
|
|
|
84
75
|
return null
|
|
85
76
|
}
|
|
86
77
|
|
|
87
|
-
// console.log(`Success making link in ${doc} to ${object}` )
|
|
88
|
-
|
|
89
78
|
try {
|
|
90
79
|
await loadOrCreateIfNotExists(store, object)
|
|
91
80
|
// store.fetcher.webOperation('PUT', object, { data: '', contentType: 'text/turtle'})
|
|
92
81
|
} catch (err) {
|
|
93
82
|
console.warn(`followOrCreateLink: Error loading or saving new linked document: ${object}: ${err}`)
|
|
94
83
|
}
|
|
95
|
-
// console.log(`followOrCreateLink: Success loading or saving new linked document: ${object}.`)
|
|
96
84
|
return object
|
|
97
85
|
}
|
|
98
86
|
|
|
99
|
-
export async function loadProfile(store: LiveStore, user: NamedNode) {
|
|
100
|
-
// console.log(' @@ loadProfile: user', user)
|
|
87
|
+
export async function loadProfile (store: LiveStore, user: NamedNode) {
|
|
101
88
|
if (!user) {
|
|
102
89
|
throw new Error(`loadProfile: no user given.`)
|
|
103
90
|
}
|
|
104
|
-
|
|
91
|
+
try {
|
|
105
92
|
await store.fetcher.load(user.doc())
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
93
|
+
} catch (err) {
|
|
94
|
+
throw new Error(`Unable to load profile of user ${user}: ${err}`)
|
|
95
|
+
}
|
|
109
96
|
return user.doc()
|
|
110
97
|
}
|
|
111
98
|
|
|
112
|
-
export async function loadPreferences(store: LiveStore, user: NamedNode): Promise <NamedNode | undefined > {
|
|
113
|
-
// console.log('loadPreferences @@ user', user)
|
|
99
|
+
export async function loadPreferences (store: LiveStore, user: NamedNode): Promise <NamedNode | undefined > {
|
|
114
100
|
await loadProfile(store as LiveStore, user)
|
|
115
101
|
|
|
116
102
|
const possiblePreferencesFile = suggestPreferencesFile(user)
|
|
117
103
|
|
|
118
104
|
const preferencesFile = await followOrCreateLink(store, user, ns.space('preferencesFile') as NamedNode, possiblePreferencesFile, user.doc())
|
|
119
105
|
|
|
120
|
-
// console.log('loadPreferences @@ pref file', preferencesFile)
|
|
121
106
|
if (!preferencesFile) {
|
|
122
107
|
const message = `User ${user} has no pointer in profile to preferences file.`
|
|
123
108
|
console.warn(message)
|
|
124
|
-
// throw new Error()
|
|
125
109
|
return undefined
|
|
126
110
|
}
|
|
127
111
|
try {
|
|
128
112
|
await store.fetcher.load(preferencesFile as NamedNode)
|
|
129
113
|
} catch (err) { // Maybe a permission propblem or origin problem
|
|
130
114
|
return undefined
|
|
131
|
-
// throw new Error(`Unable to load preferences file ${preferencesFile} of user <${user}>: ${err}`)
|
|
132
115
|
}
|
|
133
116
|
return preferencesFile as NamedNode
|
|
134
117
|
}
|
|
135
118
|
|
|
136
|
-
export async function loadTypeIndexesFor(store: LiveStore, user:NamedNode): Promise<Array<TypeIndexScope>> {
|
|
137
|
-
// console.log('@@ loadTypeIndexesFor user', user)
|
|
119
|
+
export async function loadTypeIndexesFor (store: LiveStore, user:NamedNode): Promise<Array<TypeIndexScope>> {
|
|
138
120
|
if (!user) throw new Error(`loadTypeIndexesFor: No user given`)
|
|
139
121
|
const profile = await loadProfile(store, user)
|
|
140
122
|
|
|
@@ -142,9 +124,6 @@ export async function loadTypeIndexesFor(store: LiveStore, user:NamedNode): Prom
|
|
|
142
124
|
|
|
143
125
|
const publicTypeIndex = await followOrCreateLink(store, user, ns.solid('publicTypeIndex') as NamedNode, suggestion, profile)
|
|
144
126
|
|
|
145
|
-
// const publicTypeIndex = store.any(user, ns.solid('publicTypeIndex'), undefined, profile)
|
|
146
|
-
// console.log('@@ loadTypeIndexesFor publicTypeIndex', publicTypeIndex)
|
|
147
|
-
|
|
148
127
|
const publicScopes = publicTypeIndex ? [ { label: 'public', index: publicTypeIndex as NamedNode, agent: user } ] : []
|
|
149
128
|
|
|
150
129
|
let preferencesFile
|
|
@@ -171,7 +150,6 @@ export async function loadTypeIndexesFor(store: LiveStore, user:NamedNode): Prom
|
|
|
171
150
|
const scopes = publicScopes.concat(privateScopes)
|
|
172
151
|
if (scopes.length === 0) return scopes
|
|
173
152
|
const files = scopes.map(scope => scope.index)
|
|
174
|
-
// console.log('@@ loadTypeIndexesFor files ', files)
|
|
175
153
|
try {
|
|
176
154
|
await store.fetcher.load(files)
|
|
177
155
|
} catch (err) {
|
|
@@ -183,14 +161,13 @@ export async function loadTypeIndexesFor(store: LiveStore, user:NamedNode): Prom
|
|
|
183
161
|
export async function loadCommunityTypeIndexes (store:LiveStore, user:NamedNode): Promise<TypeIndexScope[][]> {
|
|
184
162
|
const preferencesFile = await loadPreferences(store, user)
|
|
185
163
|
if (preferencesFile) { // For now, pick up communities as simple links from the preferences file.
|
|
186
|
-
const communities = store.each(user, ns.solid('community'), undefined, preferencesFile as NamedNode)
|
|
187
|
-
|
|
164
|
+
const communities = store.each(user, ns.solid('community'), undefined, preferencesFile as NamedNode).concat(
|
|
165
|
+
store.each(user, ns.solid('community'), undefined, user.doc() as NamedNode)
|
|
166
|
+
)
|
|
188
167
|
let result = []
|
|
189
168
|
for (const org of communities) {
|
|
190
169
|
result = result.concat(await loadTypeIndexesFor(store, org as NamedNode) as any)
|
|
191
170
|
}
|
|
192
|
-
// const communityTypeIndexesPromises = communities.map(async community => await loadTypeIndexesFor(store, community as NamedNode))
|
|
193
|
-
// const result1 = Promise.all(communityTypeIndexesPromises)
|
|
194
171
|
return result
|
|
195
172
|
}
|
|
196
173
|
return [] // No communities
|
|
@@ -209,38 +186,36 @@ export function uniqueNodes (arr: NamedNode[]): NamedNode[] {
|
|
|
209
186
|
return arr2 // Array.from(new Set(arr.map(x => x.uri))).map(u => sym(u))
|
|
210
187
|
}
|
|
211
188
|
|
|
212
|
-
export async function
|
|
213
|
-
// console.log(`getScopedAppsfromIndex agent ${scope.agent} index: ${scope.index}` )
|
|
189
|
+
export async function getScopedAppsFromIndex (store, scope, theClass: NamedNode | null) {
|
|
214
190
|
const index = scope.index
|
|
215
|
-
const registrations = store.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
191
|
+
const registrations = store.statementsMatching(null, ns.solid('instance'), null, index)
|
|
192
|
+
.concat(store.statementsMatching(null, ns.solid('instanceContainer'), null, index))
|
|
193
|
+
.map(st => st.subject)
|
|
194
|
+
const relevant = theClass ? registrations.filter(reg => store.any(reg, ns.solid('forClass'), null, index).sameTerm(theClass))
|
|
195
|
+
: registrations
|
|
196
|
+
const directInstances = relevant.map(reg => store.each(reg as NamedNode, ns.solid('instance'), null, index)).flat()
|
|
220
197
|
let instances = uniqueNodes(directInstances)
|
|
221
198
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
).flat()
|
|
199
|
+
const instanceContainers = relevant.map(
|
|
200
|
+
reg => store.each(reg as NamedNode, ns.solid('instanceContainer'), null, index)).flat()
|
|
225
201
|
|
|
226
202
|
// instanceContainers may be deprocatable if no one has used them
|
|
227
203
|
const containers = uniqueNodes(instanceContainers)
|
|
204
|
+
if (containers.length > 0) { console.log('@@ getScopedAppsFromIndex containers ', containers)}
|
|
228
205
|
for (let i = 0; i < containers.length; i++) {
|
|
229
206
|
const cont = containers[i]
|
|
230
207
|
await store.fetcher.load(cont)
|
|
231
208
|
const contents = store.each(cont, ns.ldp('contains'), null, cont)
|
|
232
|
-
// if (contents.length) console.log('getScopedAppsfromIndex @@ instanceContainer contents:', contents)
|
|
233
209
|
instances = instances.concat(contents)
|
|
234
210
|
}
|
|
235
211
|
return instances.map(instance => { return {instance, scope}})
|
|
236
212
|
}
|
|
237
213
|
|
|
238
214
|
export async function getScopedAppInstances (store:LiveStore, klass: NamedNode, user: NamedNode):Promise<ScopedApp[]> {
|
|
239
|
-
// console.log('getScopedAppInstances @@ ' + user)
|
|
240
215
|
const scopes = await loadAllTypeIndexes(store, user)
|
|
241
216
|
let scopedApps = []
|
|
242
217
|
for (const scope of scopes) {
|
|
243
|
-
const scopedApps0 = await
|
|
218
|
+
const scopedApps0 = await getScopedAppsFromIndex(store, scope, klass) as any
|
|
244
219
|
scopedApps = scopedApps.concat(scopedApps0)
|
|
245
220
|
}
|
|
246
221
|
return scopedApps
|
|
@@ -268,21 +243,27 @@ export async function registerInstanceInTypeIndex (
|
|
|
268
243
|
theClass: NamedNode,
|
|
269
244
|
// agent: NamedNode
|
|
270
245
|
): Promise<NamedNode | null> {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
246
|
+
const registration = newThing(index)
|
|
247
|
+
const ins = [
|
|
248
|
+
// See https://github.com/solid/solid/blob/main/proposals/data-discovery.md
|
|
249
|
+
st(registration, ns.rdf('type'), ns.solid('TypeRegistration'), index),
|
|
250
|
+
st(registration, ns.solid('forClass'), theClass, index),
|
|
251
|
+
st(registration, ns.solid('instance'), instance, index)
|
|
252
|
+
]
|
|
253
|
+
try {
|
|
254
|
+
await store.updater.update([], ins)
|
|
255
|
+
} catch (err) {
|
|
256
|
+
const msg = `Unable to register ${instance} in index ${index}: ${err}`
|
|
257
|
+
console.warn(msg)
|
|
258
|
+
return null
|
|
259
|
+
}
|
|
260
|
+
return registration
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export async function deleteTypeIndexRegistration (store: LiveStore, item) {
|
|
264
|
+
const reg = store.the(null, ns.solid('instance'), item.instance, item.scope.index) as NamedNode
|
|
265
|
+
if (!reg) throw new Error(`deleteTypeIndexRegistration: No registration found for ${item.instance}`)
|
|
266
|
+
const statements = store.statementsMatching(reg, null, null, item.scope.index)
|
|
267
|
+
await store.updater.update(statements, [])
|
|
287
268
|
}
|
|
288
269
|
// ENDS
|
package/src/inbox/InboxLogic.ts
CHANGED
|
@@ -44,7 +44,7 @@ export class InboxLogic {
|
|
|
44
44
|
return ourInbox;
|
|
45
45
|
}
|
|
46
46
|
async markAsRead(url: string, date: Date) {
|
|
47
|
-
const downloaded = await this.
|
|
47
|
+
const downloaded = await this.store.fetcher._fetch(url);
|
|
48
48
|
if (downloaded.status !== 200) {
|
|
49
49
|
throw new Error(`Not OK! ${url}`);
|
|
50
50
|
}
|
|
@@ -56,7 +56,7 @@ export class InboxLogic {
|
|
|
56
56
|
[ 'Content-Type', downloaded.headers.get('Content-Type') || 'application/octet-stream' ]
|
|
57
57
|
]
|
|
58
58
|
};
|
|
59
|
-
const uploaded = await this.
|
|
59
|
+
const uploaded = await this.store.fetcher._fetch(archiveUrl, options);
|
|
60
60
|
if (uploaded.status.toString()[0] === '2') {
|
|
61
61
|
await this.store.fetcher?._fetch(url, {
|
|
62
62
|
method: 'DELETE'
|
package/src/index.ts
CHANGED
|
@@ -20,12 +20,25 @@ export {
|
|
|
20
20
|
loadIndex
|
|
21
21
|
} from './typeIndex/typeIndexLogic'
|
|
22
22
|
|
|
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
|
|
23
25
|
export {
|
|
24
|
-
|
|
26
|
+
deleteTypeIndexRegistration,
|
|
27
|
+
followOrCreateLink,
|
|
28
|
+
getAppInstances,
|
|
29
|
+
getScopedAppInstances,
|
|
30
|
+
getScopedAppsFromIndex,
|
|
31
|
+
loadAllTypeIndexes,
|
|
32
|
+
loadCommunityTypeIndexes,
|
|
33
|
+
loadOrCreateIfNotExists,
|
|
25
34
|
loadPreferences,
|
|
35
|
+
loadProfile,
|
|
26
36
|
loadTypeIndexesFor,
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
registerInstanceInTypeIndex,
|
|
38
|
+
suggestPreferencesFile,
|
|
39
|
+
suggestPrivateTypeIndex,
|
|
40
|
+
suggestPublicTypeIndex,
|
|
41
|
+
uniqueNodes
|
|
29
42
|
} from './discovery/discoveryLogic'
|
|
30
43
|
|
|
31
44
|
export { SolidLogic } from './logic/SolidLogic'
|
package/src/logic/SolidLogic.ts
CHANGED
|
@@ -30,8 +30,6 @@ export class SolidLogic {
|
|
|
30
30
|
|
|
31
31
|
store: LiveStore;
|
|
32
32
|
me: string | undefined;
|
|
33
|
-
underlyingFetch: { fetch: (url: string, options?: any) => any };
|
|
34
|
-
|
|
35
33
|
chat: ChatLogic;
|
|
36
34
|
profile: ProfileLogic;
|
|
37
35
|
authn: AuthnLogic;
|
|
@@ -51,12 +49,11 @@ export class SolidLogic {
|
|
|
51
49
|
profileDocument: {},
|
|
52
50
|
preferencesFile: {},
|
|
53
51
|
};
|
|
54
|
-
this.underlyingFetch = { fetch: fetch }; // Note global one not the one passed
|
|
55
52
|
this.authn = new SolidAuthnLogic(session);
|
|
56
53
|
debug.log('SolidAuthnLogic initialized')
|
|
57
54
|
this.profile = new ProfileLogic(this.store, ns, this.authn);
|
|
58
55
|
this.chat = new ChatLogic(this.store, ns, this.profile);
|
|
59
|
-
this.util = new UtilityLogic(this.store, ns
|
|
56
|
+
this.util = new UtilityLogic(this.store, ns);
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
findAclDocUrl(url: string) {
|
|
@@ -257,6 +254,6 @@ export class SolidLogic {
|
|
|
257
254
|
}
|
|
258
255
|
|
|
259
256
|
async fetch(url: string, options?: any) {
|
|
260
|
-
return this.
|
|
257
|
+
return this.store.fetcher._fetch(url, options);
|
|
261
258
|
}
|
|
262
259
|
}
|
package/src/util/UtilityLogic.ts
CHANGED
|
@@ -11,12 +11,10 @@ export const ACL_LINK = sym(
|
|
|
11
11
|
export class UtilityLogic {
|
|
12
12
|
store: LiveStore;
|
|
13
13
|
ns: SolidNamespace;
|
|
14
|
-
underlyingFetch: { fetch: (url: string, options?: any) => any };
|
|
15
14
|
|
|
16
|
-
constructor(store: LiveStore, ns: SolidNamespace
|
|
15
|
+
constructor(store: LiveStore, ns: SolidNamespace) {
|
|
17
16
|
this.store = store;
|
|
18
17
|
this.ns = ns;
|
|
19
|
-
this.underlyingFetch = underlyingFetch;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
async findAclDocUrl(url: string) {
|
|
@@ -65,7 +63,7 @@ export class UtilityLogic {
|
|
|
65
63
|
].join('\n')
|
|
66
64
|
}
|
|
67
65
|
const aclDocUrl = await this.findAclDocUrl(options.target);
|
|
68
|
-
return this.
|
|
66
|
+
return this.store.fetcher._fetch(aclDocUrl, {
|
|
69
67
|
method: 'PUT',
|
|
70
68
|
body: str,
|
|
71
69
|
headers: [
|
|
@@ -74,23 +72,8 @@ export class UtilityLogic {
|
|
|
74
72
|
});
|
|
75
73
|
}
|
|
76
74
|
|
|
77
|
-
async loadDoc(doc: NamedNode): Promise<void> {
|
|
78
|
-
// Load a document into the knowledge base (fetcher.store)
|
|
79
|
-
// withCredentials: Web arch should let us just load by turning off creds helps CORS
|
|
80
|
-
// reload: Gets around a specific old Chrome bug caching/origin/cors
|
|
81
|
-
// console.log('loading', profileDocument)
|
|
82
|
-
if (!this.store.fetcher) {
|
|
83
|
-
throw new Error("Cannot load doc, have no fetcher");
|
|
84
|
-
}
|
|
85
|
-
await this.store.fetcher.load(doc, {
|
|
86
|
-
withCredentials: false, // @@ BUT this won't work when logged in an accessing private stuff!
|
|
87
|
-
cache: "reload",
|
|
88
|
-
});
|
|
89
|
-
// console.log('loaded', profileDocument, this.store)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
75
|
isContainer(url: string) {
|
|
93
|
-
return url.
|
|
76
|
+
return url.charAt(url.length-1) === "/";
|
|
94
77
|
}
|
|
95
78
|
|
|
96
79
|
async createContainer(url: string) {
|
|
@@ -98,7 +81,7 @@ export class UtilityLogic {
|
|
|
98
81
|
throw new Error(`Not a container URL ${url}`);
|
|
99
82
|
}
|
|
100
83
|
// Copied from https://github.com/solidos/solid-crud-tests/blob/v3.1.0/test/surface/create-container.test.ts#L56-L64
|
|
101
|
-
const result = await this.
|
|
84
|
+
const result = await this.store.fetcher._fetch(url, {
|
|
102
85
|
method: "PUT",
|
|
103
86
|
headers: {
|
|
104
87
|
"Content-Type": "text/turtle",
|
|
@@ -134,13 +117,13 @@ export class UtilityLogic {
|
|
|
134
117
|
try {
|
|
135
118
|
if (this.isContainer(url)) {
|
|
136
119
|
const aclDocUrl = await this.findAclDocUrl(url);
|
|
137
|
-
await this.
|
|
120
|
+
await this.store.fetcher._fetch(aclDocUrl, { method: "DELETE" });
|
|
138
121
|
const containerMembers = await this.getContainerMembers(url);
|
|
139
122
|
await Promise.all(
|
|
140
123
|
containerMembers.map((url) => this.recursiveDelete(url))
|
|
141
124
|
);
|
|
142
125
|
}
|
|
143
|
-
return this.
|
|
126
|
+
return this.store.fetcher._fetch(url, { method: "DELETE" });
|
|
144
127
|
} catch (e) {
|
|
145
128
|
// console.log(`Please manually remove ${url} from your system under test.`, e);
|
|
146
129
|
}
|
|
@@ -363,29 +363,29 @@ const ClubScopes =
|
|
|
363
363
|
},
|
|
364
364
|
"label": "public",
|
|
365
365
|
},
|
|
366
|
-
|
|
367
|
-
"agent":
|
|
366
|
+
{
|
|
367
|
+
"agent": {
|
|
368
368
|
"classOrder": 5,
|
|
369
369
|
"termType": "NamedNode",
|
|
370
370
|
"value": "https://club.example.com/profile/card.ttl#it",
|
|
371
371
|
},
|
|
372
|
-
"index":
|
|
372
|
+
"index": {
|
|
373
373
|
"classOrder": 5,
|
|
374
374
|
"termType": "NamedNode",
|
|
375
375
|
"value": "https://club.example.com/settings/private-type-index.ttl",
|
|
376
376
|
},
|
|
377
377
|
"label": "private",
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
describe('loadCommunityTypeIndexes', () => {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
})
|
|
378
|
+
}
|
|
379
|
+
]
|
|
380
|
+
describe('loadCommunityTypeIndexes', () => {
|
|
381
|
+
it('exists', () => {
|
|
382
|
+
expect(loadCommunityTypeIndexes).toBeInstanceOf(Function)
|
|
383
|
+
})
|
|
384
|
+
it('loads data', async () => {
|
|
385
|
+
const result = await loadCommunityTypeIndexes(store, user)
|
|
386
|
+
expect(result).toEqual(ClubScopes)
|
|
387
|
+
})
|
|
388
|
+
})
|
|
389
389
|
|
|
390
390
|
const AliceAndClubScopes =
|
|
391
391
|
[
|