@noeldemartin/solid-utils 0.4.0-next.30aceafb9d58f505d02a146d8e81f2e3a041b92f → 0.4.0-next.a79c7155bfd5797638ebe4fcd41739c2831c89fc

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noeldemartin/solid-utils",
3
- "version": "0.4.0-next.30aceafb9d58f505d02a146d8e81f2e3a041b92f",
3
+ "version": "0.4.0-next.a79c7155bfd5797638ebe4fcd41739c2831c89fc",
4
4
  "description": "My JavaScript utilities for Solid",
5
5
  "main": "dist/noeldemartin-solid-utils.cjs.js",
6
6
  "module": "dist/noeldemartin-solid-utils.esm.js",
@@ -38,10 +38,8 @@ async function createTypeIndex(user: SolidUserProfile, type: TypeIndexType, fetc
38
38
  }
39
39
  `;
40
40
 
41
- await Promise.all([
42
- createSolidDocument(typeIndexUrl, typeIndexBody, fetch),
43
- updateSolidDocument(user.writableProfileUrl, profileUpdateBody, fetch),
44
- ]);
41
+ await createSolidDocument(typeIndexUrl, typeIndexBody, fetch);
42
+ await updateSolidDocument(user.writableProfileUrl, profileUpdateBody, fetch);
45
43
 
46
44
  if (type === 'public') {
47
45
  // TODO This is currently implemented in soukai-solid.
package/src/helpers/io.ts CHANGED
@@ -25,6 +25,9 @@ export declare type AnyFetch = (input: any, options?: any) => Promise<Response>;
25
25
  export declare type TypedFetch = (input: RequestInfo, options?: RequestInit) => Promise<Response>;
26
26
  export declare type Fetch = TypedFetch | AnyFetch;
27
27
 
28
+ const ANONYMOUS_PREFIX = 'anonymous://';
29
+ const ANONYMOUS_PREFIX_LENGTH = ANONYMOUS_PREFIX.length;
30
+
28
31
  async function fetchRawSolidDocument(url: string, fetch: Fetch): Promise<{ body: string; headers: Headers }> {
29
32
  const options = {
30
33
  headers: { Accept: 'text/turtle' },
@@ -116,6 +119,28 @@ function normalizeBlankNodes(quads: Quad[]): Quad[] {
116
119
  return normalizedQuads;
117
120
  }
118
121
 
122
+ function normalizeQuads(quads: Quad[]): string {
123
+ return quads.map(quad => ' ' + quadToTurtle(quad)).sort().join('\n');
124
+ }
125
+
126
+ function preprocessSubjects(jsonld: JsonLD): void {
127
+ if (!jsonld['@id']?.startsWith('#')) {
128
+ return;
129
+ }
130
+
131
+ jsonld['@id'] = ANONYMOUS_PREFIX + jsonld['@id'];
132
+ }
133
+
134
+ function postprocessSubjects(quads: Quad[]): void {
135
+ for (const quad of quads) {
136
+ if (!quad.subject.value.startsWith(ANONYMOUS_PREFIX)) {
137
+ continue;
138
+ }
139
+
140
+ quad.subject.value = quad.subject.value.slice(ANONYMOUS_PREFIX_LENGTH);
141
+ }
142
+ }
143
+
119
144
  export interface ParsingOptions {
120
145
  baseIRI: string;
121
146
  normalizeBlankNodes: boolean;
@@ -126,6 +151,7 @@ export interface RDFGraphData {
126
151
  containsRelativeIRIs: boolean;
127
152
  }
128
153
 
154
+
129
155
  export async function createSolidDocument(url: string, body: string, fetch?: Fetch): Promise<SolidDocument> {
130
156
  fetch = fetch ?? window.fetch.bind(window);
131
157
 
@@ -167,7 +193,13 @@ export async function jsonldToQuads(jsonld: JsonLD, baseIRI?: string): Promise<Q
167
193
  return graphQuads.flat();
168
194
  }
169
195
 
170
- return jsonLDToRDF(jsonld as JsonLdDocument, { base: baseIRI }) as Promise<Quad[]>;
196
+ preprocessSubjects(jsonld);
197
+
198
+ const quads = await (jsonLDToRDF(jsonld as JsonLdDocument, { base: baseIRI }) as Promise<Quad[]>);
199
+
200
+ postprocessSubjects(quads);
201
+
202
+ return quads;
171
203
  }
172
204
 
173
205
  export function normalizeSparql(sparql: string): string {
@@ -176,13 +208,19 @@ export function normalizeSparql(sparql: string): string {
176
208
  return Object
177
209
  .entries(quads)
178
210
  .reduce((normalizedOperations, [operation, quads]) => {
179
- const normalizedQuads = quads.map(quad => ' ' + quadToTurtle(quad)).sort().join('\n');
211
+ const normalizedQuads = normalizeQuads(quads);
180
212
 
181
213
  return normalizedOperations.concat(`${operation.toUpperCase()} DATA {\n${normalizedQuads}\n}`);
182
214
  }, [] as string[])
183
215
  .join(' ;\n');
184
216
  }
185
217
 
218
+ export function normalizeTurtle(sparql: string): string {
219
+ const quads = turtleToQuadsSync(sparql);
220
+
221
+ return normalizeQuads(quads);
222
+ }
223
+
186
224
  export function parseTurtle(turtle: string, options: Partial<ParsingOptions> = {}): Promise<RDFGraphData> {
187
225
  const parserOptions = objectWithoutEmpty({ baseIRI: options.baseIRI });
188
226
  const parser = new TurtleParser(parserOptions);
@@ -1,5 +1,5 @@
1
- import { normalizeSparql } from '@/helpers/io';
2
- import { jsonldEquals, sparqlEquals } from '@/helpers/testing';
1
+ import { normalizeSparql, normalizeTurtle } from '@/helpers/io';
2
+ import { jsonldEquals, sparqlEquals, turtleEquals } from '@/helpers/testing';
3
3
  import type { EqualityResult } from '@/helpers/testing';
4
4
 
5
5
  interface FormatResultOptions {
@@ -50,6 +50,16 @@ const matchers: jest.ExpectExtendMap = {
50
50
  received: normalizeSparql(received),
51
51
  });
52
52
  },
53
+ toEqualTurtle(received, expected) {
54
+ const result = turtleEquals(expected, received);
55
+
56
+ return formatResult(result, {
57
+ context: this,
58
+ hint: 'toEqualTurtle',
59
+ expected: normalizeTurtle(expected),
60
+ received: normalizeTurtle(received),
61
+ });
62
+ },
53
63
  };
54
64
 
55
65
  export default matchers;
@@ -5,6 +5,7 @@ declare global {
5
5
  // TODO generate automatically
6
6
  interface Matchers<R> {
7
7
  toEqualSparql(sparql: string): R;
8
+ toEqualTurtle(turtle: string): R;
8
9
  toEqualJsonLD(jsonld: JsonLD): Promise<R>;
9
10
  }
10
11