@startinblox/core 2.0.5 → 2.0.6-beta.1

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/README.md CHANGED
@@ -21,6 +21,8 @@ npm run dev
21
21
 
22
22
  You can now see examples at [http://127.0.0.1:3000](http://127.0.0.1:3000/).
23
23
 
24
+
25
+
24
26
  ## Adding new features
25
27
  To develop new features for `sib-core`, you can add an HTML example file in `/examples` directory and link it in `/index.html`.
26
28
  Don't forget to import the framework:
@@ -30,6 +32,9 @@ Don't forget to import the framework:
30
32
  ```
31
33
  You can now write HTML using `sib-core` and test it in your browser.
32
34
 
35
+ ## Documentation
36
+
37
+ - **[Store API Documentation](./docs/store.md)** - Comprehensive guide to the StartinBlox Store API, including data retrieval, manipulation, and advanced querying capabilities.
33
38
 
34
39
  ## Testing
35
40
 
@@ -0,0 +1,440 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { q as mergeContexts, o as getRawContext, n as normalizeContext } from "./helpers-vZrb1UDN.js";
5
+ import { S as StoreService } from "./store-_JtvdYph.js";
6
+ const store = StoreService.getInstance();
7
+ class CustomGetter {
8
+ // search attributes to give to server
9
+ constructor(resourceId, resource, clientContext, serverContext, parentId = "", serverPagination = {}, serverSearch = {}) {
10
+ __publicField(this, "resource");
11
+ // content of the requested resource
12
+ __publicField(this, "resourceId");
13
+ __publicField(this, "clientContext");
14
+ // context given by the app
15
+ __publicField(this, "serverContext");
16
+ // context given by the server
17
+ __publicField(this, "parentId");
18
+ // id of the parent resource, used to get the absolute url of the current resource
19
+ __publicField(this, "listTypes");
20
+ // types of resources interpreted as containers
21
+ __publicField(this, "serverPagination");
22
+ // pagination attributes to give to server
23
+ __publicField(this, "serverSearch");
24
+ this.clientContext = clientContext;
25
+ this.serverContext = serverContext;
26
+ this.parentId = parentId;
27
+ this.resource = resource;
28
+ this.resourceId = resourceId;
29
+ this.serverPagination = serverPagination;
30
+ this.serverSearch = serverSearch;
31
+ this.listTypes = [
32
+ this.getExpandedPredicate("ldp:Container"),
33
+ this.getExpandedPredicate("dcat:Catalog"),
34
+ this.getExpandedPredicate("ldp:BasicContainer"),
35
+ this.getExpandedPredicate("ldp:DirectContainer"),
36
+ this.getExpandedPredicate("ldp:IndirectContainer"),
37
+ this.getExpandedPredicate("sib:federatedContainer")
38
+ ].filter(Boolean);
39
+ }
40
+ /**
41
+ * Get the property of a resource for a given path
42
+ * Which means that if the resource is not complete, it will fetch it
43
+ * And that we handle the `.` notation, traversing the path recursively
44
+ * @param path: string
45
+ */
46
+ async get(path) {
47
+ if (!path) return;
48
+ try {
49
+ const isUrl = new URL(path);
50
+ if (!isUrl.protocol.startsWith("http"))
51
+ throw new Error("Not a valid HTTP url");
52
+ if (isUrl) {
53
+ let resources = await this.getList(path);
54
+ if (!resources || Array.isArray(resources) && resources.length === 0)
55
+ return void 0;
56
+ if (!Array.isArray(resources)) resources = [resources];
57
+ const result = resources ? Promise.all(
58
+ resources.map(async (res) => {
59
+ let resource = await store.get(res["@id"]);
60
+ if (resource) return resource;
61
+ resource = new CustomGetter(
62
+ res["@id"],
63
+ { "@id": res["@id"] },
64
+ this.clientContext,
65
+ this.serverContext,
66
+ this.parentId
67
+ ).getProxy();
68
+ await store.cacheResource(res["@id"], resource);
69
+ return resource;
70
+ })
71
+ ) : [];
72
+ return result;
73
+ }
74
+ } catch {
75
+ if (!path.split) return void 0;
76
+ const path1 = path.split(".");
77
+ const path2 = [];
78
+ let value;
79
+ if (!this.isFullResource()) {
80
+ await this.getResource(
81
+ this.resourceId,
82
+ { ...this.clientContext, ...this.serverContext },
83
+ this.parentId
84
+ );
85
+ }
86
+ while (true) {
87
+ value = this.resource[path1[0]];
88
+ if (!value) {
89
+ const expandedPath = this.getExpandedPredicate(path1[0]);
90
+ if (expandedPath) {
91
+ value = this.resource[expandedPath];
92
+ }
93
+ }
94
+ if (!value) {
95
+ value = await this.getList(path1[0]);
96
+ if (Array.isArray(value) && value.length === 0) {
97
+ value = void 0;
98
+ }
99
+ }
100
+ if (path1.length <= 1) break;
101
+ const lastPath1El = path1.pop();
102
+ if (lastPath1El) path2.unshift(lastPath1El);
103
+ }
104
+ if (path2.length === 0) {
105
+ if (!value || !value["@id"]) return this.getLiteralValue(value);
106
+ const valueKeys = Object.keys(value).filter((k) => k !== "@type");
107
+ if (valueKeys.length === 1 && valueKeys[0] === "@id") {
108
+ const cachedResource = await store.get(value["@id"]);
109
+ if (cachedResource) {
110
+ return cachedResource;
111
+ }
112
+ try {
113
+ const mergedContext = mergeContexts(
114
+ this.clientContext,
115
+ this.serverContext
116
+ );
117
+ const rawContext = getRawContext(mergedContext);
118
+ const pathsToCheck = [path];
119
+ try {
120
+ const expandedPath = this.getExpandedPredicate(path);
121
+ if (expandedPath && expandedPath !== path) {
122
+ pathsToCheck.push(expandedPath);
123
+ }
124
+ } catch (_expandError) {
125
+ }
126
+ for (const pathToCheck of pathsToCheck) {
127
+ if ((rawContext == null ? void 0 : rawContext[pathToCheck]) && typeof rawContext[pathToCheck] === "object" && rawContext[pathToCheck]["@type"] === "@id") {
128
+ return value["@id"];
129
+ }
130
+ }
131
+ } catch (error) {
132
+ console.warn("Context parsing failed in CustomGetter:", error);
133
+ }
134
+ try {
135
+ const resource2 = await this.getResource(
136
+ value["@id"],
137
+ mergeContexts(this.clientContext, this.serverContext),
138
+ this.parentId || this.resourceId
139
+ );
140
+ if (resource2 !== null) {
141
+ return resource2;
142
+ }
143
+ } catch (fetchError) {
144
+ console.warn("Failed to fetch resource:", value["@id"], fetchError);
145
+ }
146
+ return value["@id"];
147
+ }
148
+ return await this.getResource(
149
+ value["@id"],
150
+ mergeContexts(this.clientContext, this.serverContext),
151
+ this.parentId || this.resourceId
152
+ );
153
+ }
154
+ if (!value || !value["@id"]) return void 0;
155
+ const resource = await this.getResource(
156
+ value["@id"],
157
+ mergeContexts(this.clientContext, this.serverContext),
158
+ this.parentId || this.resourceId
159
+ );
160
+ store.subscribeResourceTo(this.resourceId, value["@id"]);
161
+ return resource ? await resource[path2.join(".")] : void 0;
162
+ }
163
+ }
164
+ static getEmptyResource(id, clientContext, parentContext) {
165
+ return new CustomGetter(
166
+ id,
167
+ { "@id": id },
168
+ clientContext,
169
+ parentContext
170
+ ).getProxy();
171
+ }
172
+ /**
173
+ * Return value depending of the current language
174
+ * @param value
175
+ * @returns
176
+ */
177
+ getLiteralValue(value) {
178
+ if (typeof value !== "object" || value === null) return value;
179
+ if (value["@value"]) return value["@value"];
180
+ if (!Array.isArray(value)) return value;
181
+ if (value.length === 0) return null;
182
+ if (!Array.isArray(value[0])) return value;
183
+ const ln = store._getLanguage();
184
+ let translatedValue = value.find(
185
+ (v) => v["@language"] && v["@language"] === ln
186
+ );
187
+ if (!translatedValue)
188
+ translatedValue = value.find(
189
+ (v) => v["@language"] && v["@language"] === "en"
190
+ );
191
+ return (translatedValue == null ? void 0 : translatedValue["@value"]) ?? null;
192
+ }
193
+ /**
194
+ * Cache resource in the store, and return the created proxy
195
+ * @param id
196
+ * @param context
197
+ * @param iriParent
198
+ */
199
+ async getResource(id, context, iriParent, forceFetch = false) {
200
+ if (id.startsWith("_:b")) return await store.get(id + iriParent);
201
+ return await store.getData(
202
+ id,
203
+ context,
204
+ iriParent,
205
+ void 0,
206
+ forceFetch
207
+ );
208
+ }
209
+ /**
210
+ * Return true if the resource is a container
211
+ */
212
+ isContainer() {
213
+ if (this.resource["@type"]) {
214
+ if (Array.isArray(this.resource["@type"]))
215
+ return this.listTypes.some(
216
+ (type) => this.resource["@type"].includes(type)
217
+ );
218
+ return this.listTypes.includes(this.resource["@type"]);
219
+ }
220
+ if (!this.resource.type) return false;
221
+ if (Array.isArray(this.resource.type))
222
+ return this.listTypes.some((type) => this.resource.type.includes(type));
223
+ return this.listTypes.includes(this.resource.type);
224
+ }
225
+ /**
226
+ * Return true if the given key in the current resource in an array
227
+ */
228
+ isArray() {
229
+ if (Array.isArray(this.resource)) return true;
230
+ return false;
231
+ }
232
+ /**
233
+ * Get all properties of a resource
234
+ */
235
+ getProperties() {
236
+ return Object.keys(this.resource).map(
237
+ (prop) => this.getCompactedPredicate(prop)
238
+ );
239
+ }
240
+ /**
241
+ * Get children of container as objects
242
+ */
243
+ async getList(predicateName) {
244
+ let value = await this.resource[predicateName];
245
+ if (!value) {
246
+ const index = this.getExpandedPredicate(predicateName);
247
+ if (index) {
248
+ value = await this.resource[index];
249
+ }
250
+ }
251
+ if (value === void 0 || value === null) {
252
+ return [];
253
+ }
254
+ return value;
255
+ }
256
+ async getListAndCacheIt(predicate) {
257
+ let children = await this.getList(predicate);
258
+ if (!children) return null;
259
+ if (!Array.isArray(children)) children = [children];
260
+ const result = children ? await Promise.all(
261
+ children.map(async (res) => {
262
+ let resource = await store.get(res["@id"]);
263
+ if (resource) return resource;
264
+ resource = new CustomGetter(
265
+ res["@id"],
266
+ { "@id": res["@id"] },
267
+ this.clientContext,
268
+ this.serverContext,
269
+ this.parentId
270
+ ).getProxy();
271
+ await store.cacheResource(res["@id"], resource);
272
+ return resource;
273
+ })
274
+ ) : [];
275
+ return result;
276
+ }
277
+ async getDcatDataset() {
278
+ return await this.getListAndCacheIt("dcat:dataset");
279
+ }
280
+ /**
281
+ * Get children of container as Proxys
282
+ */
283
+ async getLdpContains() {
284
+ return await this.getListAndCacheIt("ldp:contains");
285
+ }
286
+ merge(resource) {
287
+ this.resource = {
288
+ ...this.getResourceData(),
289
+ ...resource.getResourceData()
290
+ };
291
+ }
292
+ getResourceData() {
293
+ return this.resource;
294
+ }
295
+ /**
296
+ * Get the list of resources associated with the list predicate of the resource
297
+ * If the resource is a container, it will return the ldp:contains list
298
+ * If the resource is a dcat:Catalog, it will return the dcat:dataset list
299
+ * If the resource is not a container or a catalog, it will return null
300
+ * @returns object[] | null
301
+ */
302
+ async getContainerList() {
303
+ if (this.hasType("ldp:Container")) {
304
+ return await this.getLdpContains();
305
+ }
306
+ if (this.getType() === "dcat:Catalog") {
307
+ return await this.getDcatDataset();
308
+ }
309
+ return null;
310
+ }
311
+ /**
312
+ * return true if resource seems complete
313
+ * A resource is considered complete if it has at least one property which is not a permission
314
+ */
315
+ isFullResource() {
316
+ const propertiesKeys = Object.keys(this.resource).filter(
317
+ (p) => !p.startsWith("@")
318
+ );
319
+ if (this.resource["@id"].startsWith("_:b")) return true;
320
+ if (propertiesKeys.length === 1 && propertiesKeys[0] === this.getExpandedPredicate("permissions"))
321
+ return false;
322
+ if (propertiesKeys.length > 0) return true;
323
+ return false;
324
+ }
325
+ /**
326
+ * Get permissions of a resource
327
+ * @param resourceId
328
+ * @returns
329
+ */
330
+ async getPermissions() {
331
+ const perms = this.getExpandedPredicate("permissions");
332
+ if (!perms) return [];
333
+ let permissions = this.resource[perms];
334
+ if (!permissions) {
335
+ await this.getResource(
336
+ this.resourceId,
337
+ { ...this.clientContext, ...this.serverContext },
338
+ this.parentId,
339
+ true
340
+ );
341
+ permissions = this.resource[perms];
342
+ }
343
+ if (!Array.isArray(permissions)) permissions = [permissions];
344
+ return permissions ? permissions : [];
345
+ }
346
+ /**
347
+ * returns compacted @type of resource
348
+ */
349
+ getType() {
350
+ if (Array.isArray(this.resource["@type"])) {
351
+ return this.resource["@type"].map((type) => this.getCompactedIri(type));
352
+ }
353
+ return this.resource["@type"] ? this.getCompactedIri(this.resource["@type"]) : "";
354
+ }
355
+ /**
356
+ * Check if the resource has a specific type
357
+ * @param type
358
+ */
359
+ hasType(type) {
360
+ const types = this.getType();
361
+ if (!types) return false;
362
+ if (Array.isArray(types)) {
363
+ return types.includes(this.getCompactedIri(type));
364
+ }
365
+ return types === this.getCompactedIri(type);
366
+ }
367
+ /**
368
+ * Remove the resource from the cache
369
+ */
370
+ async clearCache() {
371
+ await store.clearCache(this.resourceId);
372
+ }
373
+ getExpandedPredicate(property) {
374
+ const context = normalizeContext(
375
+ mergeContexts(this.clientContext, this.serverContext)
376
+ );
377
+ return context.expandTerm(property, true);
378
+ }
379
+ getCompactedPredicate(property) {
380
+ const context = normalizeContext(
381
+ mergeContexts(this.clientContext, this.serverContext)
382
+ );
383
+ return context.compactIri(property, true);
384
+ }
385
+ getCompactedIri(id) {
386
+ const context = normalizeContext(
387
+ mergeContexts(this.clientContext, this.serverContext)
388
+ );
389
+ return context.compactIri(id);
390
+ }
391
+ toString() {
392
+ return this.getCompactedIri(this.resource["@id"]);
393
+ }
394
+ [Symbol.toPrimitive]() {
395
+ return this.getCompactedIri(this.resource["@id"]);
396
+ }
397
+ /**
398
+ * Returns a Proxy which handles the different get requests
399
+ */
400
+ getProxy() {
401
+ return new Proxy(this, {
402
+ get: (resource, property) => {
403
+ if (!this.resource) return void 0;
404
+ if (typeof resource[property] === "function")
405
+ return resource[property].bind(resource);
406
+ switch (property) {
407
+ case "@id":
408
+ if (this.resource["@id"])
409
+ return this.getCompactedIri(this.resource["@id"]);
410
+ return;
411
+ case "@type":
412
+ return this.resource["@type"];
413
+ // return synchronously
414
+ case "properties":
415
+ return this.getProperties();
416
+ case "ldp:contains":
417
+ case "listPredicate":
418
+ return this.getContainerList();
419
+ // returns standard arrays synchronously
420
+ case "permissions":
421
+ return this.getPermissions();
422
+ // get expanded permissions
423
+ case "clientContext":
424
+ return getRawContext(this.clientContext);
425
+ // get saved client context to re-fetch easily a resource
426
+ case "serverContext":
427
+ return getRawContext(this.serverContext);
428
+ // get saved client context to re-fetch easily a resource
429
+ case "then":
430
+ return;
431
+ default:
432
+ return resource.get(property);
433
+ }
434
+ }
435
+ });
436
+ }
437
+ }
438
+ export {
439
+ CustomGetter
440
+ };
@@ -1,7 +1,7 @@
1
1
  const fr = {
2
- "autocompletion.placeholder": "Sélectionner une valeur",
2
+ "autocompletion.placeholder": "S\xE9lectionner une valeur",
3
3
  "autocompletion.searchPlaceholder": "Rechercher",
4
- "autocompletion.searchText": "Aucun résultat",
4
+ "autocompletion.searchText": "Aucun r\xE9sultat",
5
5
  "solid-delete.button": "Supprimer",
6
6
  "solid-form.submit-button": "Envoyer",
7
7
  "solid-form.validation-error": "Erreur de validation.",
@@ -1861,7 +1861,7 @@ function fuzzyCompare(subject, search) {
1861
1861
  return compareTransform(subject).includes(compareTransform(String(search)));
1862
1862
  }
1863
1863
  function compareTransform(str) {
1864
- return str.normalize("NFD").replaceAll(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase().replaceAll("œ", "oe").replaceAll("æ", "ae").replaceAll(/[ ,.!?;:-`"]+/g, " ").trim();
1864
+ return str.normalize("NFD").replaceAll(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase().replaceAll("\u0153", "oe").replaceAll("\xE6", "ae").replaceAll(/[ ,.!?;:-`"]+/g, " ").trim();
1865
1865
  }
1866
1866
  const compare = {
1867
1867
  string(subject, query) {
@@ -2078,29 +2078,32 @@ const helpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
2078
2078
  }, Symbol.toStringTag, { value: "Module" }));
2079
2079
  export {
2080
2080
  AsyncIterableBuilder as A,
2081
- doesResourceContainList as a,
2082
- fuzzyCompare as b,
2083
- compare as c,
2081
+ domIsReady as B,
2082
+ asyncQuerySelectorAll as C,
2083
+ asyncQuerySelector as a,
2084
+ importCSS as b,
2085
+ doesResourceContainList as c,
2084
2086
  defineComponent as d,
2085
- evalTemplateString as e,
2086
- findClosingBracketMatchIndex as f,
2087
- generalComparator as g,
2088
- asyncQuerySelector as h,
2087
+ findClosingBracketMatchIndex as e,
2088
+ fuzzyCompare as f,
2089
+ evalTemplateString as g,
2090
+ compare as h,
2089
2091
  importInlineCSS as i,
2090
- importCSS as j,
2092
+ generalComparator as j,
2091
2093
  helpers as k,
2092
- getRawContext as l,
2093
- mergeContexts as m,
2094
+ isUrlOrRelativePath as l,
2095
+ jsonldContextParserExports as m,
2094
2096
  normalizeContext as n,
2095
- isUrlOrRelativePath as o,
2097
+ getRawContext as o,
2096
2098
  parseFieldsString as p,
2097
- jsonldContextParserExports as q,
2098
- stringToDom as r,
2099
+ mergeContexts as q,
2100
+ requireJsonldContextParser as r,
2099
2101
  setDeepProperty as s,
2100
2102
  transformArrayToContainer as t,
2101
2103
  uniqID as u,
2102
- importJS as v,
2103
- loadScript as w,
2104
- domIsReady as x,
2105
- asyncQuerySelectorAll as y
2104
+ requireErrorCoded as v,
2105
+ requireLink as w,
2106
+ stringToDom as x,
2107
+ importJS as y,
2108
+ loadScript as z
2106
2109
  };
package/dist/helpers.js CHANGED
@@ -1,28 +1,28 @@
1
- import { A, h, y, c, A as A2, d, a, x, e, f, b, g, l, j, i, v, o, w, m, n, p, s, r, t, u } from "./helpers-4GFJ8HI8.js";
1
+ import { A, a, C, h, A as A2, d, c, B, g, e, f, j, o, b, i, y, l, z, q, n, p, s, x, t, u } from "./helpers-vZrb1UDN.js";
2
2
  export {
3
3
  A as AsyncIterableBuilder,
4
- h as asyncQuerySelector,
5
- y as asyncQuerySelectorAll,
6
- c as compare,
4
+ a as asyncQuerySelector,
5
+ C as asyncQuerySelectorAll,
6
+ h as compare,
7
7
  A2 as default,
8
8
  d as defineComponent,
9
- a as doesResourceContainList,
10
- x as domIsReady,
11
- e as evalTemplateString,
12
- f as findClosingBracketMatchIndex,
13
- b as fuzzyCompare,
14
- g as generalComparator,
15
- l as getRawContext,
16
- j as importCSS,
9
+ c as doesResourceContainList,
10
+ B as domIsReady,
11
+ g as evalTemplateString,
12
+ e as findClosingBracketMatchIndex,
13
+ f as fuzzyCompare,
14
+ j as generalComparator,
15
+ o as getRawContext,
16
+ b as importCSS,
17
17
  i as importInlineCSS,
18
- v as importJS,
19
- o as isUrlOrRelativePath,
20
- w as loadScript,
21
- m as mergeContexts,
18
+ y as importJS,
19
+ l as isUrlOrRelativePath,
20
+ z as loadScript,
21
+ q as mergeContexts,
22
22
  n as normalizeContext,
23
23
  p as parseFieldsString,
24
24
  s as setDeepProperty,
25
- r as stringToDom,
25
+ x as stringToDom,
26
26
  t as transformArrayToContainer,
27
27
  u as uniqID
28
28
  };