contacts-pane 2.6.5 → 2.6.6

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 (51) hide show
  1. package/.eslintrc +0 -0
  2. package/.github/workflows/ci.yml +0 -0
  3. package/.nvmrc +0 -0
  4. package/LICENSE.md +0 -0
  5. package/Makefile +0 -0
  6. package/README.md +0 -0
  7. package/__tests__/unit/data-reformat-test.js +166 -0
  8. package/__tests__/unit/data-reformat-test.ts +185 -0
  9. package/__tests__/unit/setup.js +74 -0
  10. package/__tests__/unit/setup.ts +77 -0
  11. package/babel.config.js +13 -0
  12. package/card.ai +0 -0
  13. package/card.png +0 -0
  14. package/contactLogic.js +39 -3
  15. package/contactsPane.js +21 -34
  16. package/diff.txt +0 -0
  17. package/exampleOfOpenData/mit-wikidata-details.ttl +0 -0
  18. package/exampleOfOpenData/mit-wikidata-query.sparql +0 -0
  19. package/exampleOfOpenData/wikidata-get.json +0 -0
  20. package/groupMembershipControl.js +0 -0
  21. package/individual.js +0 -0
  22. package/individualForm.js +0 -0
  23. package/jest.config.js +11 -0
  24. package/jest.setup.ts +10 -0
  25. package/lib/autocompleteBar.js +65 -130
  26. package/lib/autocompleteBar.js.map +1 -0
  27. package/lib/autocompleteField.js +48 -88
  28. package/lib/autocompleteField.js.map +1 -0
  29. package/lib/autocompletePicker.js +143 -203
  30. package/lib/autocompletePicker.js.map +1 -0
  31. package/lib/forms.js +0 -0
  32. package/lib/instituteDetailsQuery.js +0 -0
  33. package/lib/publicData.js +217 -270
  34. package/lib/publicData.js.map +1 -0
  35. package/lib/vcard.js +0 -0
  36. package/mintNewAddressBook.js +0 -0
  37. package/mugshotGallery.js +0 -0
  38. package/organizationForm.js +0 -0
  39. package/organizationForm.ttl +0 -0
  40. package/package.json +12 -3
  41. package/shapes/contacts-shapes.ttl +0 -0
  42. package/src/autocompleteBar.ts +0 -0
  43. package/src/autocompleteField.ts +0 -0
  44. package/src/autocompletePicker.ts +0 -0
  45. package/src/forms.ttl +0 -0
  46. package/src/instituteDetailsQuery.sparql +0 -0
  47. package/src/publicData.ts +0 -0
  48. package/src/vcard.ttl +0 -0
  49. package/toolsPane.js +0 -0
  50. package/tsconfig.json +14 -0
  51. package/webidControl.js +1 -1
package/.eslintrc CHANGED
File without changes
File without changes
package/.nvmrc CHANGED
File without changes
package/LICENSE.md CHANGED
File without changes
package/Makefile CHANGED
File without changes
package/README.md CHANGED
File without changes
@@ -0,0 +1,166 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { getDataModelIssues } from '../../contactLogic';
11
+ import fetchMock from "jest-fetch-mock";
12
+ import pane from "../../contactsPane";
13
+ import { parse } from "rdflib";
14
+ import { context, doc, mockFetchFunction, mockUpdate, ns, store, prefixes, web } from "./setup";
15
+ // This was at testingsolidos.solidcommunity.net
16
+ const base = doc.dir().uri;
17
+ const webid1 = store.sym(base + 'People/localPerson/index.ttl#this');
18
+ const exampleData = prefixes + `
19
+
20
+ :homeGroup1 a vcard:Group;
21
+ vcard:fn "Happy Home";
22
+ vcard:hasMember ${webid1} .
23
+
24
+ :homeGroup2 a vcard:Group;
25
+ vcard:fn "Home";
26
+ vcard:hasMember :localPerson.
27
+
28
+ :homeGroup3 a vcard:Group;
29
+ vcard:fn "Home";
30
+ vcard:hasMember :localPerson.
31
+
32
+ `;
33
+ const book = store.sym(base + 'book.ttl#this');
34
+ const aliceLocal = store.sym(base + 'People/aaaaaaaaaa/index.ttl#this');
35
+ const aliceWebId = store.sym('https://alice.example/card#me');
36
+ web[aliceLocal.doc().uri] = `<#this> a vcard:Individual, schema:Person; vcard:fn "Alice".`;
37
+ const bobLocal = store.sym(base + 'People/bbbbbbbbbb/index.ttl#this');
38
+ const bobWebId = store.sym('https://bob.example.net/#me');
39
+ web[bobLocal.doc().uri] = `<#this> a vcard:Individual, schema:Person;
40
+ vcard:hasURL [ vcard:type vcard:WebId; vcard:value ${bobWebId} ];
41
+ vcard:fn "Bob".`;
42
+ web[base + 'book.ttl'] = `
43
+ <#this> a vcard:AddressBook;
44
+ vcard:fn """Contacts: Test address book""";
45
+ vcard:nameEmailIndex <people.ttl>;
46
+ vcard:groupIndex <groups.ttl>.
47
+ `;
48
+ web[base + 'groups.ttl'] = `
49
+ <Group/Test.ttl#this> a vcard:Group ;
50
+ vcard:fn "Test group".
51
+ <Group/Home.ttl#this> a vcard:Group ;
52
+ vcard:fn "Home group".
53
+ <Group/Work.ttl#this> a vcard:Group ;
54
+ vcard:fn "Work group".
55
+ `;
56
+ const testGroup = store.sym(base + 'Group/Test.ttl#this');
57
+ web[testGroup.doc().uri] = `
58
+ <#this> a vcard:Group;
59
+ vcard:fn "Test Group";
60
+ vcard:hasMember ${aliceLocal} .
61
+ # <https://alice.example/card#me>,
62
+ # <../People/aaaaaaaaaa/index.ttl#this>,
63
+ # <../People/bbbbbbbbbbb/index.ttl#this> .
64
+
65
+ ${aliceLocal} = ${aliceWebId} .
66
+ `;
67
+ const homeGroup = store.sym(base + 'Group/Home.ttl#this');
68
+ web[homeGroup.doc().uri] = `
69
+ <#this> a vcard:Group;
70
+ vcard:fn "Home Group";
71
+ vcard:hasMember
72
+ <../People/aaaaaaaaaa/index.ttl#this>,
73
+ <../People/bbbbbbbbbb/index.ttl#this> .
74
+ `;
75
+ const workGroup = store.sym(base + 'Group/Work.ttl#this');
76
+ web[workGroup.doc().uri] = `
77
+ <#this> a vcard:Group;
78
+ vcard:fn "Work Group";
79
+ vcard:hasMember
80
+ <https://alice.example/card#me>,
81
+ <https://bob.example/card#me>,
82
+ <https://charlie.example/card#me> .`;
83
+ web[base + 'People/aaaaaaaaaa/index.ttl'] = `
84
+ <#this> vcard:fn "Alice" .
85
+ `;
86
+ const groups = [testGroup, homeGroup, workGroup];
87
+ for (const uri in web) {
88
+ console.log(` parsing "${uri}" (${web[uri].length})`);
89
+ parse(prefixes + web[uri], store, uri);
90
+ }
91
+ describe("contacts-pane", () => {
92
+ describe("returns right label", () => {
93
+ beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
94
+ store.removeDocument(doc);
95
+ // parse(exampleData, store, doc.uri);
96
+ // const label = pane.label(subject, context);
97
+ }));
98
+ /*
99
+ if (t[ns.vcard('Individual').uri]) return 'Contact'
100
+ if (t[ns.vcard('Organization').uri]) return 'contact'
101
+ if (t[ns.foaf('Person').uri]) return 'Person'
102
+ if (t[ns.schema('Person').uri]) return 'Person'
103
+ if (t[ns.vcard('Group').uri]) return 'Group'
104
+ if (t[ns.vcard('AddressBook').uri]) return 'Address book'
105
+ */
106
+ it("returns a good label contact if Organization", () => {
107
+ let thing = store.sym(base + 'thing1');
108
+ store.add(thing, ns.rdf('type'), ns.vcard('Organization'), doc);
109
+ expect(pane.label(thing, context)).toEqual('contact');
110
+ });
111
+ it("returns a good label Contact for Individual", () => {
112
+ let thing = store.sym(base + 'thing2');
113
+ store.add(thing, ns.rdf('type'), ns.vcard('Individual'), doc);
114
+ expect(pane.label(thing, context)).toEqual('Contact');
115
+ });
116
+ it("returns a good label Person if Person", () => {
117
+ let thing = store.sym(base + 'thing3');
118
+ store.add(thing, ns.rdf('type'), ns.schema('Person'), doc);
119
+ expect(pane.label(thing, context)).toEqual('Person');
120
+ });
121
+ it("returns a good label Person if foaf:Person", () => {
122
+ let thing = store.sym(base + 'thing4');
123
+ store.add(thing, ns.rdf('type'), ns.foaf('Person'), doc);
124
+ expect(pane.label(thing, context)).toEqual('Person');
125
+ });
126
+ it("returns a good label Group if Group", () => {
127
+ let thing = store.sym(base + 'thing5');
128
+ store.add(thing, ns.rdf('type'), ns.vcard('Group'), doc);
129
+ expect(pane.label(thing, context)).toEqual('Group');
130
+ });
131
+ it("returns a good label AddressBook if AddressBook", () => {
132
+ let thing = store.sym(base + 'thing6');
133
+ store.add(thing, ns.rdf('type'), ns.vcard('AddressBook'), doc);
134
+ expect(pane.label(thing, context)).toEqual('Address book');
135
+ });
136
+ it("returns a null label if not a person", () => {
137
+ let thing = store.sym(base + 'thing7');
138
+ expect(pane.label(store.sym('https://random.example.com/'), context)).toEqual(null);
139
+ // done()
140
+ });
141
+ }); // label tests
142
+ describe("render tests", () => {
143
+ it("renders an empty UI of an address book", () => {
144
+ const div = pane.render(book, context);
145
+ expect(div.outerHTML).toMatch("<div class=\"contactPane\"></div>");
146
+ expect(div.innerHTML).toMatch("");
147
+ });
148
+ }); // render tests
149
+ describe("data format tests", () => {
150
+ beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
151
+ store.removeDocument(doc);
152
+ parse(exampleData, store, doc.uri);
153
+ fetchMock.mockIf(/^https?.*$/, mockFetchFunction);
154
+ }));
155
+ it("converts a bad format into a good one", () => __awaiter(void 0, void 0, void 0, function* () {
156
+ expect(store.the(testGroup, ns.vcard('hasMember'), null, testGroup.doc())).toEqual(aliceLocal);
157
+ const { del, ins } = yield getDataModelIssues(groups);
158
+ expect(del.length).toEqual(1);
159
+ expect(ins.length).toEqual(1);
160
+ expect(del.toString()).toEqual('<https://janedoe.example/profile/Group/Test.ttl#this> <http://www.w3.org/2006/vcard/ns#hasMember> <https://janedoe.example/profile/People/aaaaaaaaaa/index.ttl#this> .');
161
+ expect(ins.toString()).toEqual('<https://janedoe.example/profile/Group/Test.ttl#this> <http://www.w3.org/2006/vcard/ns#hasMember> <https://alice.example/card#me> .');
162
+ mockUpdate(store, del, ins);
163
+ expect(store.the(testGroup, ns.vcard('hasMember'), null, testGroup.doc())).toEqual(aliceWebId);
164
+ }));
165
+ }); // data format tests
166
+ }); // all tests
@@ -0,0 +1,185 @@
1
+ import { getDataModelIssues } from '../../contactLogic'
2
+ import fetchMock from "jest-fetch-mock";
3
+
4
+ import pane from "../../contactsPane";
5
+ import { parse, NamedNode } from "rdflib";
6
+ import { context, doc, subject, mockFetchFunction, mockUpdate, ns, store, prefixes, web } from "./setup";
7
+
8
+ // This was at testingsolidos.solidcommunity.net
9
+
10
+ const base = doc.dir().uri
11
+ const webid1 = store.sym(base + 'People/localPerson/index.ttl#this')
12
+
13
+ const exampleData = prefixes + `
14
+
15
+ :homeGroup1 a vcard:Group;
16
+ vcard:fn "Happy Home";
17
+ vcard:hasMember ${webid1} .
18
+
19
+ :homeGroup2 a vcard:Group;
20
+ vcard:fn "Home";
21
+ vcard:hasMember :localPerson.
22
+
23
+ :homeGroup3 a vcard:Group;
24
+ vcard:fn "Home";
25
+ vcard:hasMember :localPerson.
26
+
27
+ `
28
+
29
+ const book = store.sym(base + 'book.ttl#this')
30
+
31
+ const aliceLocal = store.sym(base + 'People/aaaaaaaaaa/index.ttl#this');
32
+ const aliceWebId = store.sym('https://alice.example/card#me')
33
+
34
+ web[aliceLocal.doc().uri] = `<#this> a vcard:Individual, schema:Person; vcard:fn "Alice".`;
35
+
36
+ const bobLocal = store.sym(base + 'People/bbbbbbbbbb/index.ttl#this')
37
+ const bobWebId = store.sym('https://bob.example.net/#me')
38
+ web[bobLocal.doc().uri] = `<#this> a vcard:Individual, schema:Person;
39
+ vcard:hasURL [ vcard:type vcard:WebId; vcard:value ${bobWebId} ];
40
+ vcard:fn "Bob".`;
41
+
42
+
43
+
44
+ web[base + 'book.ttl'] = `
45
+ <#this> a vcard:AddressBook;
46
+ vcard:fn """Contacts: Test address book""";
47
+ vcard:nameEmailIndex <people.ttl>;
48
+ vcard:groupIndex <groups.ttl>.
49
+ `;
50
+
51
+ web[base + 'groups.ttl'] = `
52
+ <Group/Test.ttl#this> a vcard:Group ;
53
+ vcard:fn "Test group".
54
+ <Group/Home.ttl#this> a vcard:Group ;
55
+ vcard:fn "Home group".
56
+ <Group/Work.ttl#this> a vcard:Group ;
57
+ vcard:fn "Work group".
58
+ `;
59
+
60
+ const testGroup = store.sym(base + 'Group/Test.ttl#this')
61
+ web[testGroup.doc().uri] = `
62
+ <#this> a vcard:Group;
63
+ vcard:fn "Test Group";
64
+ vcard:hasMember ${aliceLocal} .
65
+ # <https://alice.example/card#me>,
66
+ # <../People/aaaaaaaaaa/index.ttl#this>,
67
+ # <../People/bbbbbbbbbbb/index.ttl#this> .
68
+
69
+ ${aliceLocal} = ${aliceWebId} .
70
+ `;
71
+ const homeGroup = store.sym(base + 'Group/Home.ttl#this')
72
+ web[homeGroup.doc().uri] = `
73
+ <#this> a vcard:Group;
74
+ vcard:fn "Home Group";
75
+ vcard:hasMember
76
+ <../People/aaaaaaaaaa/index.ttl#this>,
77
+ <../People/bbbbbbbbbb/index.ttl#this> .
78
+ `;
79
+
80
+ const workGroup = store.sym(base + 'Group/Work.ttl#this')
81
+ web[workGroup.doc().uri] = `
82
+ <#this> a vcard:Group;
83
+ vcard:fn "Work Group";
84
+ vcard:hasMember
85
+ <https://alice.example/card#me>,
86
+ <https://bob.example/card#me>,
87
+ <https://charlie.example/card#me> .`;
88
+
89
+ web[base + 'People/aaaaaaaaaa/index.ttl'] = `
90
+ <#this> vcard:fn "Alice" .
91
+ `;
92
+
93
+ const groups = [ testGroup, homeGroup, workGroup ];
94
+
95
+ for (const uri in web) {
96
+ console.log(` parsing "${uri}" (${web[uri].length})`)
97
+ parse(prefixes + web[uri], store, uri);
98
+ }
99
+
100
+ describe("contacts-pane", () => {
101
+
102
+ describe("returns right label", () => {
103
+ beforeAll(async () => {
104
+ store.removeDocument(doc);
105
+ // parse(exampleData, store, doc.uri);
106
+ // const label = pane.label(subject, context);
107
+ });
108
+ /*
109
+ if (t[ns.vcard('Individual').uri]) return 'Contact'
110
+ if (t[ns.vcard('Organization').uri]) return 'contact'
111
+ if (t[ns.foaf('Person').uri]) return 'Person'
112
+ if (t[ns.schema('Person').uri]) return 'Person'
113
+ if (t[ns.vcard('Group').uri]) return 'Group'
114
+ if (t[ns.vcard('AddressBook').uri]) return 'Address book'
115
+ */
116
+ it("returns a good label contact if Organization", () => {
117
+ let thing = store.sym(base + 'thing1')
118
+ store.add(thing, ns.rdf('type'), ns.vcard('Organization'), doc)
119
+ expect(pane.label(thing, context)).toEqual('contact');
120
+ });
121
+
122
+ it("returns a good label Contact for Individual", () => {
123
+ let thing = store.sym(base + 'thing2')
124
+ store.add(thing, ns.rdf('type'), ns.vcard('Individual'), doc)
125
+ expect(pane.label(thing, context)).toEqual('Contact');
126
+ });
127
+ it("returns a good label Person if Person", () => {
128
+ let thing = store.sym(base + 'thing3')
129
+ store.add(thing, ns.rdf('type'), ns.schema('Person'), doc)
130
+ expect(pane.label(thing, context)).toEqual('Person');
131
+ });
132
+ it("returns a good label Person if foaf:Person", () => {
133
+ let thing = store.sym(base + 'thing4')
134
+ store.add(thing, ns.rdf('type'), ns.foaf('Person'), doc)
135
+ expect(pane.label(thing, context)).toEqual('Person');
136
+ });
137
+ it("returns a good label Group if Group", () => {
138
+ let thing = store.sym(base + 'thing5')
139
+
140
+ store.add(thing, ns.rdf('type'), ns.vcard('Group'), doc)
141
+ expect(pane.label(thing, context)).toEqual('Group');
142
+ });
143
+ it("returns a good label AddressBook if AddressBook", () => {
144
+ let thing = store.sym(base + 'thing6')
145
+ store.add(thing, ns.rdf('type'), ns.vcard('AddressBook'), doc)
146
+ expect(pane.label(thing, context)).toEqual('Address book');
147
+ });
148
+ it("returns a null label if not a person", () => {
149
+ let thing = store.sym(base + 'thing7')
150
+ expect(pane.label(store.sym('https://random.example.com/'), context)).toEqual(null);
151
+ // done()
152
+ });
153
+
154
+ }); // label tests
155
+
156
+ describe("render tests", () => { // How to get the UI which comes over time?
157
+ it("renders an empty UI of an address book", () => {
158
+ const div = pane.render(book, context)
159
+ expect(div.outerHTML).toMatch("<div class=\"contactPane\"></div>");
160
+ expect(div.innerHTML).toMatch("");
161
+ });
162
+ }); // render tests
163
+
164
+ describe("data format tests", () => {
165
+ beforeAll(async () => {
166
+ store.removeDocument(doc);
167
+ parse(exampleData, store, doc.uri);
168
+ fetchMock.mockIf(/^https?.*$/, mockFetchFunction)
169
+ });
170
+
171
+ it("converts a bad format into a good one", async () => {
172
+ expect(store.the(testGroup, ns.vcard('hasMember'), null, testGroup.doc())).toEqual(aliceLocal)
173
+ const { del, ins } = await getDataModelIssues(groups)
174
+ expect(del.length).toEqual(1)
175
+ expect(ins.length).toEqual(1)
176
+ expect(del.toString()).toEqual('<https://janedoe.example/profile/Group/Test.ttl#this> <http://www.w3.org/2006/vcard/ns#hasMember> <https://janedoe.example/profile/People/aaaaaaaaaa/index.ttl#this> .')
177
+ expect(ins.toString()).toEqual('<https://janedoe.example/profile/Group/Test.ttl#this> <http://www.w3.org/2006/vcard/ns#hasMember> <https://alice.example/card#me> .')
178
+ mockUpdate(store, del, ins)
179
+ expect(store.the(testGroup, ns.vcard('hasMember'), null, testGroup.doc())).toEqual(aliceWebId)
180
+
181
+ });
182
+
183
+ }); // data format tests
184
+
185
+ }); // all tests
@@ -0,0 +1,74 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { ns, store } from "solid-ui";
11
+ export { ns, store, rdf } from "solid-ui";
12
+ // console.log('@@ store', store)
13
+ // console.log('@@ store.sym', store.sym)
14
+ export const subject = store.sym("https://janedoe.example/profile/card#me");
15
+ export const doc = subject.doc();
16
+ export const context = {
17
+ dom: document,
18
+ getOutliner: () => null,
19
+ session: {
20
+ paneRegistry: {
21
+ byName: (name) => {
22
+ return {
23
+ render: () => {
24
+ return document.createElement('div')
25
+ .appendChild(document.createTextNode(`mock ${name} pane`));
26
+ }
27
+ };
28
+ }
29
+ },
30
+ store,
31
+ logic: {},
32
+ },
33
+ };
34
+ const prefs = Object.keys(ns).filter(x => x !== 'default'); // default is bogus value
35
+ export const prefixes = prefs.map(prefix => `@prefix ${prefix}: ${ns[prefix]('')}.\n`).join(''); // In turtle
36
+ export let web = {};
37
+ export let requests = [];
38
+ export function mockFetchFunction(req) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ if (req.method !== 'GET') {
41
+ requests.push(req);
42
+ if (req.method === 'PUT') {
43
+ const contents = yield req.text();
44
+ web[req.url] = contents; // Update our dummy web
45
+ console.log(`Tetst: Updated ${req.url} on PUT to <<<${web[req.url]}>>>`);
46
+ }
47
+ return { status: 200 };
48
+ }
49
+ const contents = web[req.url];
50
+ if (contents !== undefined) { //
51
+ return {
52
+ body: prefixes + contents,
53
+ status: 200,
54
+ headers: {
55
+ "Content-Type": "text/turtle",
56
+ "WAC-Allow": 'user="write", public="read"',
57
+ "Accept-Patch": "application/sparql-update"
58
+ }
59
+ };
60
+ } // if contents
61
+ return {
62
+ status: 404,
63
+ body: 'Not Found'
64
+ };
65
+ });
66
+ }
67
+ export function mockUpdate(store, del, ins) {
68
+ for (const st of del) {
69
+ store.remove(st);
70
+ }
71
+ for (const st of ins) {
72
+ store.addStatement(st);
73
+ }
74
+ }
@@ -0,0 +1,77 @@
1
+ import { DataBrowserContext, PaneRegistry } from "pane-registry";
2
+
3
+ import { Statement, LiveStore } from "rdflib";
4
+ import { ns, store, rdf } from "solid-ui"
5
+ export { ns, store, rdf } from "solid-ui"
6
+
7
+ import { SolidLogic } from "solid-logic";
8
+
9
+ // console.log('@@ store', store)
10
+ // console.log('@@ store.sym', store.sym)
11
+
12
+ export const subject = store.sym("https://janedoe.example/profile/card#me");
13
+ export const doc = subject.doc();
14
+
15
+ export const context = {
16
+ dom: document,
17
+ getOutliner: () => null,
18
+ session: {
19
+ paneRegistry: {
20
+ byName: (name: string) => {
21
+ return {
22
+ render: () => {
23
+ return document.createElement('div')
24
+ .appendChild(
25
+ document.createTextNode(`mock ${name} pane`)
26
+ );
27
+ }
28
+ }
29
+ }
30
+ } as PaneRegistry,
31
+ store,
32
+ logic: {} as SolidLogic,
33
+ },
34
+ } as unknown as DataBrowserContext;
35
+
36
+ const prefs = Object.keys(ns).filter(x => x !== 'default') // default is bogus value
37
+ export const prefixes = prefs.map(prefix => `@prefix ${prefix}: ${ns[prefix]('')}.\n`).join('') // In turtle
38
+
39
+ export let web = {}
40
+ export let requests = []
41
+
42
+ export async function mockFetchFunction (req) {
43
+ if (req.method !== 'GET') {
44
+ requests.push(req)
45
+ if (req.method === 'PUT') {
46
+ const contents = await req.text()
47
+ web[req.url] = contents // Update our dummy web
48
+ console.log(`Tetst: Updated ${req.url} on PUT to <<<${web[req.url]}>>>`)
49
+ }
50
+ return { status: 200 }
51
+ }
52
+ const contents = web[req.url]
53
+ if (contents !== undefined) { //
54
+ return {
55
+ body: prefixes + contents, // Add namespaces to anything
56
+ status: 200,
57
+ headers: {
58
+ "Content-Type": "text/turtle",
59
+ "WAC-Allow": 'user="write", public="read"',
60
+ "Accept-Patch": "application/sparql-update"
61
+ }
62
+ }
63
+ } // if contents
64
+ return {
65
+ status: 404,
66
+ body: 'Not Found'
67
+ }
68
+ }
69
+
70
+ export function mockUpdate (store: LiveStore, del: Statement[], ins: Statement[]) {
71
+ for (const st of del) {
72
+ store.remove(st)
73
+ }
74
+ for (const st of ins) {
75
+ store.addStatement(st)
76
+ }
77
+ }
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ presets: [
3
+ [
4
+ "@babel/preset-env",
5
+ {
6
+ targets: {
7
+ node: "current",
8
+ },
9
+ },
10
+ ],
11
+ "@babel/preset-typescript",
12
+ ],
13
+ };
package/card.ai CHANGED
File without changes
package/card.png CHANGED
File without changes
package/contactLogic.js CHANGED
@@ -64,7 +64,7 @@ export async function saveNewContact (book, name, selectedGroups, klass) {
64
64
  try {
65
65
  await updater.updateMany([], agenda) // @@ in future, updater.updateMany
66
66
  } catch (e) {
67
- console.log("Error: can't update " + person + ' as new contact:' + e)
67
+ console.error("Error: can't update " + person + ' as new contact:' + e)
68
68
  throw new Error('Updating new contact: ' + e)
69
69
  }
70
70
  return person
@@ -86,7 +86,7 @@ export async function saveNewGroup (book, name) {
86
86
  const gname = sanitizeToAlpha(name)
87
87
  const group = kb.sym(book.dir().uri + 'Group/' + gname + '.ttl#this')
88
88
  const doc = group.doc()
89
- console.log(' New group will be: ' + group + '\n')
89
+ // console.log(' New group will be: ' + group + '\n')
90
90
  try {
91
91
  await kb.fetcher.load(gix)
92
92
  } catch (err) {
@@ -129,7 +129,7 @@ export async function addPersonToGroup (thing, group) {
129
129
 
130
130
  const types = kb.findTypeURIs(thing)
131
131
  for (const ty in types) {
132
- console.log(' drop object type includes: ' + ty) // @@ Allow email addresses and phone numbers to be dropped?
132
+ // console.log(' drop object type includes: ' + ty) // @@ Allow email addresses and phone numbers to be dropped?
133
133
  }
134
134
  if (!(ns.vcard('Individual').uri in types ||
135
135
  ns.vcard('Organization').uri in types)) {
@@ -194,3 +194,39 @@ export function groupMembers (kb, group) {
194
194
  return b
195
195
  }
196
196
 
197
+ export function isLocal(group, item) {
198
+ const tree = group.dir().dir().dir()
199
+ const local = item.uri && item.uri.startsWith(tree.uri)
200
+ // console.log(` isLocal ${local} for ${item.uri} in group ${group} tree ${tree.uri}`)
201
+ return local
202
+ }
203
+
204
+ export function getSameAs(kb, item, doc) {
205
+ return kb.each(item, ns.owl('sameAs'), null, doc).concat(
206
+ kb.each(null, ns.owl('sameAs'), item, doc))
207
+ }
208
+
209
+ export async function getDataModelIssues(groups) {
210
+ let del = []
211
+ let ins = []
212
+ groups.forEach(group => {
213
+ const members = kb.each(group, ns.vcard('hasMember'), null, group.doc())
214
+ members.forEach((member) => {
215
+ const others = getSameAs(kb, member, group.doc())
216
+ if (others.length && isLocal(group, member)) { // Problem: local ID used instead of webID
217
+ for (const other of others) {
218
+ if (!isLocal(group, other)) { // Let's use this one as the immediate member for CSS ACLs'
219
+ // console.warn(`getDataModelIssues: Need to swap ${member} to ${other}`)
220
+ del.push($rdf.st(group, ns.vcard('hasMember'), member, group.doc()))
221
+ ins.push($rdf.st(group, ns.vcard('hasMember'), other, group.doc()))
222
+ break
223
+ }
224
+ // console.log('getDataModelIssues: ??? expected id not to be local ' + other)
225
+ } // other
226
+ } // if
227
+ }) // member
228
+ }) // next group
229
+ return {del, ins }
230
+ } // getDataModelIssues
231
+
232
+ // Ends