@semapps/semantic-data-provider 1.1.3 → 1.1.5

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/dist/index.cjs.js CHANGED
@@ -4,8 +4,8 @@ var $bkNnK$rdfjsdatamodel = require("@rdfjs/data-model");
4
4
  var $bkNnK$sparqljs = require("sparqljs");
5
5
  var $bkNnK$cryptojsmd5 = require("crypto-js/md5");
6
6
  var $bkNnK$reactadmin = require("react-admin");
7
- var $bkNnK$urljoin = require("url-join");
8
7
  var $bkNnK$jwtdecode = require("jwt-decode");
8
+ var $bkNnK$urljoin = require("url-join");
9
9
  var $bkNnK$httplinkheader = require("http-link-header");
10
10
  var $bkNnK$changecase = require("change-case");
11
11
  var $bkNnK$react = require("react");
@@ -359,6 +359,19 @@ const $e6fbab1f303bdb93$var$arrayOf = (value)=>{
359
359
  var $e6fbab1f303bdb93$export$2e2bcd8739ae039 = $e6fbab1f303bdb93$var$arrayOf;
360
360
 
361
361
 
362
+
363
+ // Fetch the selected resources of the provided containers
364
+ // Filter out resources that are provided (can avoid loading a resource twice)
365
+ const $448b8598c73a447a$var$fetchSelectedResources = async (containers, excludedResourcesUris, config)=>{
366
+ let selectedResourcesUris = containers.filter((c)=>c.selectedResources).map((c)=>c.selectedResources).flat();
367
+ // Filter out resources which are already included in the SPARQL query results
368
+ selectedResourcesUris = selectedResourcesUris.filter((uri)=>!excludedResourcesUris.includes(uri));
369
+ const selectedResources = await Promise.all(selectedResourcesUris.map((resourceUri)=>(0, $3db7a4510a668a04$export$2e2bcd8739ae039)(resourceUri, config)));
370
+ return selectedResources;
371
+ };
372
+ var $448b8598c73a447a$export$2e2bcd8739ae039 = $448b8598c73a447a$var$fetchSelectedResources;
373
+
374
+
362
375
  const $8c999cc29c8d6a6c$var$isValidLDPContainer = (container)=>{
363
376
  const resourceType = container.type || container['@type'];
364
377
  return Array.isArray(resourceType) ? resourceType.includes('ldp:Container') : resourceType === 'ldp:Container';
@@ -366,23 +379,24 @@ const $8c999cc29c8d6a6c$var$isValidLDPContainer = (container)=>{
366
379
  const $8c999cc29c8d6a6c$var$isObject = (val)=>{
367
380
  return val != null && typeof val === 'object' && !Array.isArray(val);
368
381
  };
369
- const $8c999cc29c8d6a6c$var$fetchContainers = async (containers, params, { httpClient: httpClient, jsonContext: jsonContext })=>{
370
- const fetchPromises = containers.map((container)=>httpClient(container.uri).then(async ({ json: json })=>{
371
- const jsonResponse = json;
372
- // If container's context is different, compact it to have an uniform result
373
- // TODO deep compare if the context is an object
374
- if (jsonResponse['@context'] !== jsonContext) return (0, ($parcel$interopDefault($bkNnK$jsonld))).compact(jsonResponse, jsonContext);
375
- return jsonResponse;
376
- }).then((json)=>{
377
- if (!$8c999cc29c8d6a6c$var$isValidLDPContainer(json)) throw new Error(`${container.uri} is not a LDP container`);
378
- return (0, $e6fbab1f303bdb93$export$2e2bcd8739ae039)(json['ldp:contains']).map((resource)=>({
379
- '@context': json['@context'],
380
- ...resource
381
- }));
382
- }));
382
+ const $8c999cc29c8d6a6c$var$fetchContainers = async (containers, params, config)=>{
383
+ const { httpClient: httpClient, jsonContext: jsonContext } = config;
383
384
  // Fetch simultaneously all containers
384
- const results = await Promise.all(fetchPromises);
385
+ const results = await Promise.all(containers.filter((c)=>!c.selectedResources).map(async (container)=>{
386
+ let { json: json } = await httpClient(container.uri);
387
+ // If container's context is different, compact it to have an uniform result
388
+ // TODO deep compare if the context is an object
389
+ if (json['@context'] !== jsonContext) json = await (0, ($parcel$interopDefault($bkNnK$jsonld))).compact(json, jsonContext);
390
+ if (!$8c999cc29c8d6a6c$var$isValidLDPContainer(json)) throw new Error(`${container.uri} is not a LDP container`);
391
+ return (0, $e6fbab1f303bdb93$export$2e2bcd8739ae039)(json['ldp:contains']).map((resource)=>({
392
+ '@context': json['@context'],
393
+ ...resource
394
+ }));
395
+ }));
385
396
  let resources = results.flat();
397
+ // Append selected resources (if any)
398
+ const selectedResources = await (0, $448b8598c73a447a$export$2e2bcd8739ae039)(containers, resources.map((r)=>r.id), config);
399
+ resources = resources.concat(selectedResources);
386
400
  resources = resources.map((resource)=>{
387
401
  resource.id = resource.id || resource['@id'];
388
402
  return resource;
@@ -782,6 +796,7 @@ const $33c37185da3771a9$var$buildSparqlQuery = ({ containersUris: containersUris
782
796
  var $33c37185da3771a9$export$2e2bcd8739ae039 = $33c37185da3771a9$var$buildSparqlQuery;
783
797
 
784
798
 
799
+
785
800
  const $1e7a94d745f8597b$var$compare = (a, b)=>{
786
801
  switch(typeof a){
787
802
  case 'string':
@@ -793,16 +808,19 @@ const $1e7a94d745f8597b$var$compare = (a, b)=>{
793
808
  }
794
809
  };
795
810
  const $1e7a94d745f8597b$var$fetchSparqlEndpoints = async (containers, resourceId, params, config)=>{
796
- const { dataServers: dataServers, resources: resources, httpClient: httpClient, jsonContext: jsonContext, ontologies: ontologies } = config;
797
- const dataModel = resources[resourceId];
798
- const serversToQuery = containers.reduce((acc, cur)=>{
811
+ const { dataServers: dataServers, httpClient: httpClient, jsonContext: jsonContext, ontologies: ontologies } = config;
812
+ const dataModel = config.resources[resourceId];
813
+ // Find servers to query with SPARQL
814
+ // (Ignore containers with selected resources, they will be fetched below)
815
+ const serversToQuery = containers.filter((c)=>!c.selectedResources).reduce((acc, cur)=>{
799
816
  if (!acc.includes(cur.server)) acc.push(cur.server);
800
817
  return acc;
801
818
  }, []);
802
- const sparqlQueryPromises = serversToQuery.map((serverKey)=>new Promise((resolve, reject)=>{
819
+ // Run simultaneous SPARQL queries
820
+ const results = await Promise.all(serversToQuery.map((serverKey)=>new Promise((resolve, reject)=>{
803
821
  const blankNodes = params.filter?.blankNodes || dataModel.list?.blankNodes;
804
822
  const sparqlQuery = (0, $33c37185da3771a9$export$2e2bcd8739ae039)({
805
- containersUris: containers.filter((c)=>c.server === serverKey).map((c)=>c.uri),
823
+ containersUris: containers.filter((c)=>c.server === serverKey && !c.selectedResources).map((c)=>c.uri),
806
824
  params: params,
807
825
  dataModel: dataModel,
808
826
  ontologies: ontologies
@@ -842,17 +860,18 @@ const $1e7a94d745f8597b$var$fetchSparqlEndpoints = async (containers, resourceId
842
860
  ...resource
843
861
  })) || []);
844
862
  }).catch((e)=>reject(e));
845
- }));
846
- // Run simultaneous SPARQL queries
847
- let results = await Promise.all(sparqlQueryPromises);
848
- if (results.length === 0) return {
863
+ })));
864
+ // Merge results from all SPARQL servers
865
+ let resources = results.flat();
866
+ // Append selected resources to SPARQL query results
867
+ const selectedResources = await (0, $448b8598c73a447a$export$2e2bcd8739ae039)(containers, resources.map((r)=>r.id), config);
868
+ resources = resources.concat(selectedResources);
869
+ if (resources.length === 0) return {
849
870
  data: [],
850
871
  total: 0
851
872
  };
852
- // Merge all results in one array
853
- results = [].concat(...results);
854
873
  // Add id in addition to @id, as this is what React-Admin expects
855
- let returnData = results.map((item)=>{
874
+ let returnData = resources.map((item)=>{
856
875
  item.id = item.id || item['@id'];
857
876
  return item;
858
877
  });
@@ -1020,14 +1039,22 @@ var $ceaafb56f75454f0$export$2e2bcd8739ae039 = $ceaafb56f75454f0$var$updateMetho
1020
1039
 
1021
1040
 
1022
1041
 
1042
+
1023
1043
  /*
1024
1044
  * HTTP client used by all calls in data provider and auth provider
1025
1045
  * Do proxy calls if a proxy endpoint is available and the server is different from the auth server
1026
1046
  */ const $341dff85fe619d85$var$httpClient = (dataServers)=>(url, options = {})=>{
1027
1047
  if (!url) throw new Error(`No URL provided on httpClient call`);
1048
+ const token = localStorage.getItem('token');
1049
+ let webId = localStorage.getItem('webId');
1050
+ if (!webId) {
1051
+ const payload = (0, ($parcel$interopDefault($bkNnK$jwtdecode)))(token);
1052
+ webId = payload.webId || payload.webid; // Currently we must deal with both formats
1053
+ localStorage.setItem('webId', webId);
1054
+ }
1028
1055
  const authServerKey = (0, $8f44b7c15b8b8e1d$export$2e2bcd8739ae039)('authServer', dataServers);
1029
1056
  const serverKey = (0, $59a07b932dae8600$export$2e2bcd8739ae039)(url, dataServers);
1030
- const useProxy = serverKey !== authServerKey && dataServers[authServerKey]?.proxyUrl && dataServers[serverKey]?.noProxy !== true;
1057
+ const useProxy = serverKey !== authServerKey && dataServers[webId]?.proxyUrl && dataServers[serverKey]?.noProxy !== true;
1031
1058
  if (!options.headers) options.headers = new Headers();
1032
1059
  switch(options.method){
1033
1060
  case 'POST':
@@ -1053,19 +1080,16 @@ var $ceaafb56f75454f0$export$2e2bcd8739ae039 = $ceaafb56f75454f0$var$updateMetho
1053
1080
  else formData.append('body', options.body);
1054
1081
  }
1055
1082
  // Post to proxy endpoint with multipart/form-data format
1056
- return (0, $bkNnK$reactadmin.fetchUtils).fetchJson(dataServers[authServerKey].proxyUrl, {
1083
+ return (0, $bkNnK$reactadmin.fetchUtils).fetchJson(dataServers[webId].proxyUrl, {
1057
1084
  method: 'POST',
1058
1085
  headers: new Headers({
1059
- Authorization: `Bearer ${localStorage.getItem('token')}`
1086
+ Authorization: `Bearer ${token}`
1060
1087
  }),
1061
1088
  body: formData
1062
1089
  });
1063
1090
  }
1064
1091
  // Add token if the server is the same as the auth server
1065
- if (serverKey === authServerKey) {
1066
- const token = localStorage.getItem('token');
1067
- if (token) options.headers.set('Authorization', `Bearer ${token}`);
1068
- }
1092
+ if (token && serverKey === authServerKey) options.headers.set('Authorization', `Bearer ${token}`);
1069
1093
  return (0, $bkNnK$reactadmin.fetchUtils).fetchJson(url, options);
1070
1094
  };
1071
1095
  var $341dff85fe619d85$export$2e2bcd8739ae039 = $341dff85fe619d85$var$httpClient;
@@ -1272,7 +1296,7 @@ const $89358cee13a17a31$var$configureUserStorage = ()=>({
1272
1296
  const newConfig = {
1273
1297
  ...config
1274
1298
  };
1275
- newConfig.dataServers.user = {
1299
+ newConfig.dataServers[webId] = {
1276
1300
  pod: true,
1277
1301
  default: true,
1278
1302
  authServer: true,
@@ -1300,6 +1324,7 @@ var $89358cee13a17a31$export$2e2bcd8739ae039 = $89358cee13a17a31$var$configureUs
1300
1324
 
1301
1325
 
1302
1326
 
1327
+
1303
1328
  const $37dc42f6e1c3b4af$var$getContainerFromDataRegistration = async (dataRegistrationUri, config)=>{
1304
1329
  const { json: dataRegistration } = await config.httpClient(dataRegistrationUri, {
1305
1330
  headers: new Headers({
@@ -1333,7 +1358,8 @@ const $37dc42f6e1c3b4af$var$getContainerFromDataRegistration = async (dataRegist
1333
1358
  '@container': '@language'
1334
1359
  }
1335
1360
  });
1336
- const { baseUrl: baseUrl } = config.dataServers.user;
1361
+ const userStorage = (0, $8f44b7c15b8b8e1d$export$2e2bcd8739ae039)('default', config.dataServers);
1362
+ const { baseUrl: baseUrl } = config.dataServers[userStorage];
1337
1363
  const containerPath = dataRegistration.id.replace(baseUrl, '');
1338
1364
  const container = {
1339
1365
  path: containerPath,
@@ -1359,7 +1385,9 @@ var $37dc42f6e1c3b4af$export$2e2bcd8739ae039 = $37dc42f6e1c3b4af$var$getContaine
1359
1385
  * Return a function that look if an app (clientId) is registered with an user (webId)
1360
1386
  * If not, it redirects to the endpoint provided by the user's authorization agent
1361
1387
  * See https://solid.github.io/data-interoperability-panel/specification/#authorization-agent
1362
- */ const $c512de108ef5d674$var$fetchAppRegistration = ()=>({
1388
+ */ const $c512de108ef5d674$var$fetchAppRegistration = (pluginConfig = {})=>{
1389
+ const { includeSelectedResources: includeSelectedResources = true } = pluginConfig;
1390
+ return {
1363
1391
  transformConfig: async (config)=>{
1364
1392
  const token = localStorage.getItem('token');
1365
1393
  // If the user is logged in
@@ -1381,15 +1409,27 @@ var $37dc42f6e1c3b4af$export$2e2bcd8739ae039 = $37dc42f6e1c3b4af$var$getContaine
1381
1409
  const newConfig = {
1382
1410
  ...config
1383
1411
  };
1384
- // Load data grants concurrently to improve performances
1412
+ // Load access grants concurrently to improve performances
1385
1413
  const results = await Promise.all((0, $e6fbab1f303bdb93$export$2e2bcd8739ae039)(appRegistration['interop:hasAccessGrant']).map(async (accessGrantUri)=>{
1386
1414
  const { json: accessGrant } = await config.httpClient(accessGrantUri);
1387
- return Promise.all((0, $e6fbab1f303bdb93$export$2e2bcd8739ae039)(accessGrant['interop:hasDataGrant']).map(async (dataGrantUri)=>{
1388
- const { json: dataGrant } = await config.httpClient(dataGrantUri);
1389
- return (0, $37dc42f6e1c3b4af$export$2e2bcd8739ae039)(dataGrant['interop:hasDataRegistration'], config);
1390
- }));
1415
+ const container = await (0, $37dc42f6e1c3b4af$export$2e2bcd8739ae039)(accessGrant['interop:hasDataRegistration'], config);
1416
+ container.server = accessGrant['interop:dataOwner'];
1417
+ if (accessGrant['interop:scopeOfGrant'] === 'interop:AllFromRegistry') return container;
1418
+ else if (accessGrant['interop:scopeOfGrant'] === 'interop:SelectedFromRegistry') {
1419
+ if (!includeSelectedResources) return undefined;
1420
+ container.selectedResources = (0, $e6fbab1f303bdb93$export$2e2bcd8739ae039)(accessGrant['interop:hasDataInstance']);
1421
+ return container;
1422
+ }
1391
1423
  }));
1392
- newConfig.dataServers.user.containers = results.flat();
1424
+ // Put data shared by other users in other servers (storages)
1425
+ for (const container of results.flat().filter((i)=>i !== undefined))if (!newConfig.dataServers[container.server]) newConfig.dataServers[container.server] = {
1426
+ pod: true,
1427
+ baseUrl: `${container.server}/data`,
1428
+ containers: [
1429
+ container
1430
+ ]
1431
+ };
1432
+ else newConfig.dataServers[container.server].containers.push(container);
1393
1433
  return newConfig;
1394
1434
  }
1395
1435
  }
@@ -1397,7 +1437,8 @@ var $37dc42f6e1c3b4af$export$2e2bcd8739ae039 = $37dc42f6e1c3b4af$var$getContaine
1397
1437
  }
1398
1438
  return config;
1399
1439
  }
1400
- });
1440
+ };
1441
+ };
1401
1442
  var $c512de108ef5d674$export$2e2bcd8739ae039 = $c512de108ef5d674$var$fetchAppRegistration;
1402
1443
 
1403
1444
 
@@ -1408,9 +1449,9 @@ const $cd772adda3024172$var$fetchDataRegistry = ()=>({
1408
1449
  const token = localStorage.getItem('token');
1409
1450
  // If the user is logged in
1410
1451
  if (token) {
1411
- if (!config.dataServers.user) throw new Error(`You must configure the user storage first with the configureUserStorage plugin`);
1412
1452
  const payload = (0, ($parcel$interopDefault($bkNnK$jwtdecode)))(token);
1413
1453
  const webId = payload.webId || payload.webid; // Currently we must deal with both formats
1454
+ if (!config.dataServers[webId]) throw new Error(`You must configure the user storage first with the configureUserStorage plugin`);
1414
1455
  const { json: user } = await config.httpClient(webId);
1415
1456
  const { json: registrySet } = await config.httpClient(user['interop:hasRegistrySet']);
1416
1457
  const { json: dataRegistry } = await config.httpClient(registrySet['interop:hasDataRegistry']);
@@ -1421,7 +1462,7 @@ const $cd772adda3024172$var$fetchDataRegistry = ()=>({
1421
1462
  const newConfig = {
1422
1463
  ...config
1423
1464
  };
1424
- newConfig.dataServers.user.containers?.push(...results.flat());
1465
+ newConfig.dataServers[webId].containers?.push(...results.flat());
1425
1466
  return newConfig;
1426
1467
  }
1427
1468
  }
@@ -1441,9 +1482,9 @@ const $69d4da9beaa62ac6$var$fetchTypeIndexes = ()=>({
1441
1482
  const token = localStorage.getItem('token');
1442
1483
  // If the user is logged in
1443
1484
  if (token) {
1444
- if (!config.dataServers.user) throw new Error(`You must configure the user storage first with the configureUserStorage plugin`);
1445
1485
  const payload = (0, ($parcel$interopDefault($bkNnK$jwtdecode)))(token);
1446
1486
  const webId = payload.webId || payload.webid; // Currently we must deal with both formats
1487
+ if (!config.dataServers[webId]) throw new Error(`You must configure the user storage first with the configureUserStorage plugin`);
1447
1488
  const { json: user } = await config.httpClient(webId);
1448
1489
  const typeRegistrations = {
1449
1490
  public: [],
@@ -1472,17 +1513,17 @@ const $69d4da9beaa62ac6$var$fetchTypeIndexes = ()=>({
1472
1513
  separateNumbers: true
1473
1514
  })
1474
1515
  },
1475
- path: typeRegistration['solid:instanceContainer'].replace(newConfig.dataServers.user.baseUrl, ''),
1516
+ path: typeRegistration['solid:instanceContainer'].replace(newConfig.dataServers[webId].baseUrl, ''),
1476
1517
  types: await (0, $9ab033d1ec46b5da$export$2e2bcd8739ae039)(types, user['@context']),
1477
1518
  private: mode === 'private'
1478
1519
  };
1479
- const containerIndex = newConfig.dataServers.user.containers.findIndex((c)=>c.path === container.path);
1520
+ const containerIndex = newConfig.dataServers[webId].containers.findIndex((c)=>c.path === container.path);
1480
1521
  if (containerIndex !== -1) // If a container with this URI already exist, add type registration information if they are not set
1481
- newConfig.dataServers.user.containers[containerIndex] = {
1522
+ newConfig.dataServers[webId].containers[containerIndex] = {
1482
1523
  ...container,
1483
- ...newConfig.dataServers.user.containers[containerIndex]
1524
+ ...newConfig.dataServers[webId].containers[containerIndex]
1484
1525
  };
1485
- else newConfig.dataServers.user.containers.push(container);
1526
+ else newConfig.dataServers[webId].containers.push(container);
1486
1527
  }
1487
1528
  return newConfig;
1488
1529
  }