@esri/hub-common 9.40.0 → 9.42.0

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 (82) hide show
  1. package/dist/es2017/content/_internal.js +14 -1
  2. package/dist/es2017/content/_internal.js.map +1 -1
  3. package/dist/es2017/core/types/IHubContent.js +1 -0
  4. package/dist/es2017/core/types/IHubContent.js.map +1 -1
  5. package/dist/es2017/index.js +1 -0
  6. package/dist/es2017/index.js.map +1 -1
  7. package/dist/es2017/search/_internal/portalSearchGroups.js.map +1 -1
  8. package/dist/es2017/search/_internal/portalSearchUsers.js +89 -0
  9. package/dist/es2017/search/_internal/portalSearchUsers.js.map +1 -0
  10. package/dist/es2017/search/filter-utils.js +59 -26
  11. package/dist/es2017/search/filter-utils.js.map +1 -1
  12. package/dist/es2017/search/hubSearch.js +4 -1
  13. package/dist/es2017/search/hubSearch.js.map +1 -1
  14. package/dist/es2017/urls/getUserHomeUrl.js +12 -0
  15. package/dist/es2017/urls/getUserHomeUrl.js.map +1 -0
  16. package/dist/es2017/urls/index.js +1 -0
  17. package/dist/es2017/urls/index.js.map +1 -1
  18. package/dist/es2017/users/HubUsers.js +64 -0
  19. package/dist/es2017/users/HubUsers.js.map +1 -0
  20. package/dist/es2017/users/_internal/enrichments.js +85 -0
  21. package/dist/es2017/users/_internal/enrichments.js.map +1 -0
  22. package/dist/es2017/users/index.js +2 -0
  23. package/dist/es2017/users/index.js.map +1 -0
  24. package/dist/esm/content/_internal.js +14 -1
  25. package/dist/esm/content/_internal.js.map +1 -1
  26. package/dist/esm/core/types/IHubContent.js +1 -0
  27. package/dist/esm/core/types/IHubContent.js.map +1 -1
  28. package/dist/esm/index.js +1 -0
  29. package/dist/esm/index.js.map +1 -1
  30. package/dist/esm/search/_internal/portalSearchGroups.js.map +1 -1
  31. package/dist/esm/search/_internal/portalSearchUsers.js +104 -0
  32. package/dist/esm/search/_internal/portalSearchUsers.js.map +1 -0
  33. package/dist/esm/search/filter-utils.js +60 -27
  34. package/dist/esm/search/filter-utils.js.map +1 -1
  35. package/dist/esm/search/hubSearch.js +4 -1
  36. package/dist/esm/search/hubSearch.js.map +1 -1
  37. package/dist/esm/urls/getUserHomeUrl.js +12 -0
  38. package/dist/esm/urls/getUserHomeUrl.js.map +1 -0
  39. package/dist/esm/urls/index.js +1 -0
  40. package/dist/esm/urls/index.js.map +1 -1
  41. package/dist/esm/users/HubUsers.js +66 -0
  42. package/dist/esm/users/HubUsers.js.map +1 -0
  43. package/dist/esm/users/_internal/enrichments.js +86 -0
  44. package/dist/esm/users/_internal/enrichments.js.map +1 -0
  45. package/dist/esm/users/index.js +2 -0
  46. package/dist/esm/users/index.js.map +1 -0
  47. package/dist/node/content/_internal.js +14 -1
  48. package/dist/node/content/_internal.js.map +1 -1
  49. package/dist/node/core/types/IHubContent.js +1 -0
  50. package/dist/node/core/types/IHubContent.js.map +1 -1
  51. package/dist/node/index.js +1 -0
  52. package/dist/node/index.js.map +1 -1
  53. package/dist/node/search/_internal/portalSearchGroups.js.map +1 -1
  54. package/dist/node/search/_internal/portalSearchUsers.js +93 -0
  55. package/dist/node/search/_internal/portalSearchUsers.js.map +1 -0
  56. package/dist/node/search/filter-utils.js +59 -26
  57. package/dist/node/search/filter-utils.js.map +1 -1
  58. package/dist/node/search/hubSearch.js +4 -1
  59. package/dist/node/search/hubSearch.js.map +1 -1
  60. package/dist/node/urls/getUserHomeUrl.js +16 -0
  61. package/dist/node/urls/getUserHomeUrl.js.map +1 -0
  62. package/dist/node/urls/index.js +1 -0
  63. package/dist/node/urls/index.js.map +1 -1
  64. package/dist/node/users/HubUsers.js +68 -0
  65. package/dist/node/users/HubUsers.js.map +1 -0
  66. package/dist/node/users/_internal/enrichments.js +89 -0
  67. package/dist/node/users/_internal/enrichments.js.map +1 -0
  68. package/dist/node/users/index.js +5 -0
  69. package/dist/node/users/index.js.map +1 -0
  70. package/dist/types/content/_internal.d.ts +1 -0
  71. package/dist/types/core/types/IHubContent.d.ts +5 -2
  72. package/dist/types/index.d.ts +1 -0
  73. package/dist/types/search/_internal/portalSearchUsers.d.ts +8 -0
  74. package/dist/types/search/types/types.d.ts +18 -1
  75. package/dist/types/urls/getUserHomeUrl.d.ts +10 -0
  76. package/dist/types/urls/index.d.ts +1 -0
  77. package/dist/types/users/HubUsers.d.ts +11 -0
  78. package/dist/types/users/_internal/enrichments.d.ts +28 -0
  79. package/dist/types/users/index.d.ts +1 -0
  80. package/dist/umd/common.umd.js +359 -61
  81. package/dist/umd/common.umd.js.map +1 -1
  82. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /* @preserve
2
- * @esri/hub-common - v9.39.0 - Fri Jun 10 2022 17:25:47 GMT+0000 (Coordinated Universal Time)
2
+ * @esri/hub-common - v9.41.1 - Tue Jun 14 2022 18:27:39 GMT+0000 (Coordinated Universal Time)
3
3
  * Copyright (c) 2022 Environmental Systems Research Institute, Inc.
4
4
  * Apache-2.0
5
5
  */
@@ -5444,6 +5444,17 @@
5444
5444
  return portalUrl + "/home/group.html?id=" + groupId;
5445
5445
  }
5446
5446
 
5447
+ /**
5448
+ * Return the URL of the user's page in the Portal Home application
5449
+ * @param username The username
5450
+ * @param portalUrlOrObject a portal base or API URL, a portal object, or request options containing either of those
5451
+ * @returns URL to the user's profile, defaults to `https://www.arcgis.com/home/user.html?user={username}`
5452
+ */
5453
+ function getUserHomeUrl(username, portalUrlOrObject) {
5454
+ var portalUrl = getPortalUrl(portalUrlOrObject);
5455
+ return portalUrl + "/home/user.html?user=" + username;
5456
+ }
5457
+
5447
5458
  var MAP_OR_FEATURE_SERVER_URL_REGEX = /\/(map|feature)server/i;
5448
5459
  /**
5449
5460
  *
@@ -6438,6 +6449,7 @@
6438
6449
  (function (PublisherSource) {
6439
6450
  PublisherSource["CitationContact"] = "metadata.resource.citation.contact";
6440
6451
  PublisherSource["ResourceContact"] = "metadata.resource.contact";
6452
+ PublisherSource["MetadataContact"] = "metadata.contact";
6441
6453
  PublisherSource["ItemOwner"] = "item.owner";
6442
6454
  PublisherSource["None"] = "none";
6443
6455
  })(exports.PublisherSource || (exports.PublisherSource = {}));
@@ -7071,7 +7083,8 @@
7071
7083
  organizationSource: exports.PublisherSource.None,
7072
7084
  };
7073
7085
  var citationContact = extractFirstContact(metadata, "metadata.dataIdInfo.idCitation.citRespParty");
7074
- var resourceContact = extractFirstContact(metadata, "metadata.mdContact");
7086
+ var resourceContact = extractFirstContact(metadata, "metadata.dataIdInfo.idPoC");
7087
+ var metadataContact = extractFirstContact(metadata, "metadata.mdContact");
7075
7088
  // Determine publisher name properties
7076
7089
  var ownerFullName = getProp(ownerUser, "fullName");
7077
7090
  if (citationContact.individualName) {
@@ -7082,6 +7095,10 @@
7082
7095
  result.name = resourceContact.individualName;
7083
7096
  result.nameSource = exports.PublisherSource.ResourceContact;
7084
7097
  }
7098
+ else if (metadataContact.individualName) {
7099
+ result.name = metadataContact.individualName;
7100
+ result.nameSource = exports.PublisherSource.MetadataContact;
7101
+ }
7085
7102
  else if (ownerFullName) {
7086
7103
  result.name = ownerFullName;
7087
7104
  result.username = ownerUser.username;
@@ -7097,11 +7114,19 @@
7097
7114
  result.organization = resourceContact.organizationName;
7098
7115
  result.organizationSource = exports.PublisherSource.ResourceContact;
7099
7116
  }
7117
+ else if (metadataContact.organizationName) {
7118
+ result.organization = metadataContact.organizationName;
7119
+ result.organizationSource = exports.PublisherSource.MetadataContact;
7120
+ }
7100
7121
  else if (orgName) {
7101
7122
  result.organization = orgName;
7102
7123
  result.orgId = getItemOrgId(item, ownerUser);
7103
7124
  result.organizationSource = exports.PublisherSource.ItemOwner;
7104
7125
  }
7126
+ // We assume the item belongs to external org if no org info is available and the item is private
7127
+ result.isExternal =
7128
+ result.organizationSource === exports.PublisherSource.None &&
7129
+ item.access !== "public";
7105
7130
  return result;
7106
7131
  };
7107
7132
 
@@ -10032,7 +10057,7 @@
10032
10057
  requestOptions: requestOptions,
10033
10058
  };
10034
10059
  })
10035
- .catch(function (error) { return handleEnrichmentError$1(error, input, opId); });
10060
+ .catch(function (error) { return handleEnrichmentError$2(error, input, opId); });
10036
10061
  };
10037
10062
  var enrichMetadata = function (input) {
10038
10063
  var data = input.data, stack = input.stack, requestOptions = input.requestOptions;
@@ -10064,7 +10089,7 @@
10064
10089
  requestOptions: requestOptions,
10065
10090
  };
10066
10091
  })
10067
- .catch(function (error) { return handleEnrichmentError$1(error, input, opId); });
10092
+ .catch(function (error) { return handleEnrichmentError$2(error, input, opId); });
10068
10093
  };
10069
10094
  // Note, this MUST be run after `enrichOwnerUser` to access the correct orgId during
10070
10095
  // processing. `item.orgId` is only SOMETIMES returned by Portal, so we need to have
@@ -10082,7 +10107,7 @@
10082
10107
  requestOptions: requestOptions,
10083
10108
  };
10084
10109
  })
10085
- .catch(function (error) { return handleEnrichmentError$1(error, input, opId); });
10110
+ .catch(function (error) { return handleEnrichmentError$2(error, input, opId); });
10086
10111
  };
10087
10112
  var enrichData = function (input) {
10088
10113
  var data = input.data, stack = input.stack, requestOptions = input.requestOptions;
@@ -10092,7 +10117,7 @@
10092
10117
  stack.finish(opId);
10093
10118
  return { data: __assign(__assign({}, data), { data: itemData }), stack: stack, requestOptions: requestOptions };
10094
10119
  })
10095
- .catch(function (error) { return handleEnrichmentError$1(error, input, opId); });
10120
+ .catch(function (error) { return handleEnrichmentError$2(error, input, opId); });
10096
10121
  };
10097
10122
  var enrichServer = function (input) {
10098
10123
  var data = input.data, stack = input.stack, requestOptions = input.requestOptions;
@@ -10104,7 +10129,7 @@
10104
10129
  stack.finish(opId);
10105
10130
  return { data: __assign(__assign({}, data), { server: server }), stack: stack, requestOptions: requestOptions };
10106
10131
  })
10107
- .catch(function (error) { return handleEnrichmentError$1(error, input, opId); });
10132
+ .catch(function (error) { return handleEnrichmentError$2(error, input, opId); });
10108
10133
  };
10109
10134
  var enrichLayers = function (input) {
10110
10135
  var data = input.data, stack = input.stack, requestOptions = input.requestOptions;
@@ -10122,12 +10147,12 @@
10122
10147
  stack.finish(opId);
10123
10148
  return { data: __assign(__assign({}, data), { layers: layers }), stack: stack, requestOptions: requestOptions };
10124
10149
  })
10125
- .catch(function (error) { return handleEnrichmentError$1(error, input, opId); }));
10150
+ .catch(function (error) { return handleEnrichmentError$2(error, input, opId); }));
10126
10151
  };
10127
10152
  // add the error to the content.errors,
10128
10153
  // log current stack operation as finished with an error
10129
10154
  // and return output that can be piped into the next operation
10130
- var handleEnrichmentError$1 = function (error, input, opId) {
10155
+ var handleEnrichmentError$2 = function (error, input, opId) {
10131
10156
  var data = input.data, stack = input.stack, requestOptions = input.requestOptions;
10132
10157
  stack.finish(opId, { error: error });
10133
10158
  return {
@@ -13222,7 +13247,7 @@
13222
13247
  requestOptions: requestOptions,
13223
13248
  };
13224
13249
  })
13225
- .catch(function (error) { return handleEnrichmentError(error, input, opId); });
13250
+ .catch(function (error) { return handleEnrichmentError$1(error, input, opId); });
13226
13251
  };
13227
13252
  /**
13228
13253
  * Create a summary of the Group membership by searching for members,
@@ -13247,12 +13272,12 @@
13247
13272
  requestOptions: requestOptions,
13248
13273
  };
13249
13274
  })
13250
- .catch(function (error) { return handleEnrichmentError(error, input, opId); });
13275
+ .catch(function (error) { return handleEnrichmentError$1(error, input, opId); });
13251
13276
  };
13252
13277
  // add the error to the content.errors,
13253
13278
  // log current stack operation as finished with an error
13254
13279
  // and return output that can be piped into the next operation
13255
- var handleEnrichmentError = function (error, input, opId) {
13280
+ var handleEnrichmentError$1 = function (error, input, opId) {
13256
13281
  var data = input.data, stack = input.stack, requestOptions = input.requestOptions;
13257
13282
  stack.finish(opId, { error: error });
13258
13283
  return {
@@ -13264,7 +13289,7 @@
13264
13289
  /**
13265
13290
  * Available enrichments for Groups
13266
13291
  */
13267
- var groupEnrichementOperations = {
13292
+ var groupEnrichementOperations$1 = {
13268
13293
  membershipSummary: enrichGroupMembershipSummary,
13269
13294
  contentCount: enrichGroupContentCount,
13270
13295
  };
@@ -13278,7 +13303,7 @@
13278
13303
  function fetchGroupEnrichments(group, enrichments, requestOptions) {
13279
13304
  // create a pipeline of enrichment operations
13280
13305
  var operations = enrichments.reduce(function (ops, enrichment) {
13281
- var operation = groupEnrichementOperations[enrichment];
13306
+ var operation = groupEnrichementOperations$1[enrichment];
13282
13307
  // only include the enrichments that we know how to fetch
13283
13308
  operation && ops.push(operation);
13284
13309
  return ops;
@@ -13524,7 +13549,7 @@
13524
13549
  * @param join
13525
13550
  * @returns
13526
13551
  */
13527
- function mergeSearchOptions(so1, so2, join) {
13552
+ function mergeSearchOptions$1(so1, so2, join) {
13528
13553
  // TODO: Remove with _searchContent
13529
13554
  Logger.warn("DEPRECATION: mergeSearchOptions will be removed. Work with IFilterGroups<\"group\"> and hubSearch() instead");
13530
13555
  var result = cloneObject$1(so1);
@@ -14120,12 +14145,12 @@
14120
14145
  // from hitting the else
14121
14146
  /* istanbul ignore else */
14122
14147
  if (typeof entry === "object") {
14123
- acc = mergeSearchOptions(acc, convertContentFilterToSearchOptions(entry), "OR");
14148
+ acc = mergeSearchOptions$1(acc, convertContentFilterToSearchOptions(entry), "OR");
14124
14149
  }
14125
14150
  return acc;
14126
14151
  }, { q: "", filter: "" });
14127
14152
  // merge with searchOptions using AND
14128
- searchOptions = mergeSearchOptions(searchOptions, subFilterOptions, "AND");
14153
+ searchOptions = mergeSearchOptions$1(searchOptions, subFilterOptions, "AND");
14129
14154
  }
14130
14155
  // term is always last, and pre-pended on searchOptions.q
14131
14156
  if (filter.term) {
@@ -14153,11 +14178,11 @@
14153
14178
  var key = _a[0], value = _a[1];
14154
14179
  // MatchOptions may go into either q or filter
14155
14180
  if (!specialProps.includes(key)) {
14156
- result = mergeSearchOptions(result, serializeMatchOptions$1(key, value), "AND");
14181
+ result = mergeSearchOptions$1(result, serializeMatchOptions$1(key, value), "AND");
14157
14182
  }
14158
14183
  // Dates only go into q
14159
14184
  if (dateProps.includes(key)) {
14160
- result = mergeSearchOptions(result, serializeDateRange$1(key, value), "AND");
14185
+ result = mergeSearchOptions$1(result, serializeDateRange$1(key, value), "AND");
14161
14186
  }
14162
14187
  });
14163
14188
  return result;
@@ -14288,11 +14313,11 @@
14288
14313
  var key = _a[0], value = _a[1];
14289
14314
  // MatchOptions fields
14290
14315
  if (!specialProps.includes(key)) {
14291
- result = mergeSearchOptions(result, serializeMatchOptions$1(key, value), "AND");
14316
+ result = mergeSearchOptions$1(result, serializeMatchOptions$1(key, value), "AND");
14292
14317
  }
14293
14318
  // Dates only go into q
14294
14319
  if (dateProps.includes(key)) {
14295
- result = mergeSearchOptions(result, serializeDateRange$1(key, value), "AND");
14320
+ result = mergeSearchOptions$1(result, serializeDateRange$1(key, value), "AND");
14296
14321
  }
14297
14322
  });
14298
14323
  // searchUserAccess is also a top-level property
@@ -14428,11 +14453,11 @@
14428
14453
  var key = _a[0], value = _a[1];
14429
14454
  // MatchOptions fields
14430
14455
  if (!specialProps.includes(key)) {
14431
- result = mergeSearchOptions(result, serializeMatchOptions$1(key, value), "AND");
14456
+ result = mergeSearchOptions$1(result, serializeMatchOptions$1(key, value), "AND");
14432
14457
  }
14433
14458
  // Dates only go into q
14434
14459
  if (dateProps.includes(key)) {
14435
- result = mergeSearchOptions(result, serializeDateRange$1(key, value), "AND");
14460
+ result = mergeSearchOptions$1(result, serializeDateRange$1(key, value), "AND");
14436
14461
  }
14437
14462
  });
14438
14463
  // disabled is also a top-level property
@@ -14494,7 +14519,7 @@
14494
14519
  so_1.countFields = options.aggFields.join(",");
14495
14520
  so_1.countSize = options.aggLimit || 10;
14496
14521
  }
14497
- searchPromise = searchPortal$2(so_1);
14522
+ searchPromise = searchPortal$3(so_1);
14498
14523
  }
14499
14524
  else {
14500
14525
  // Hub API Search
@@ -14522,7 +14547,7 @@
14522
14547
  * @param site
14523
14548
  * @returns
14524
14549
  */
14525
- function searchPortal$2(searchOptions) {
14550
+ function searchPortal$3(searchOptions) {
14526
14551
  var _a;
14527
14552
  var portalUrl = ((_a = searchOptions.authentication) === null || _a === void 0 ? void 0 : _a.portal) || searchOptions.portal;
14528
14553
  var token;
@@ -14553,7 +14578,7 @@
14553
14578
  results: content,
14554
14579
  facets: facets,
14555
14580
  hasNext: hasNext,
14556
- next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal$2),
14581
+ next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal$3),
14557
14582
  };
14558
14583
  });
14559
14584
  }
@@ -14960,7 +14985,13 @@
14960
14985
  function expandFilter(filter) {
14961
14986
  var result = {};
14962
14987
  var dateProps = ["created", "modified", "lastlogin"];
14963
- var copyProps = ["filterType", "term", "searchUserAccess", "isopendata"];
14988
+ var copyProps = [
14989
+ "filterType",
14990
+ "term",
14991
+ "searchUserAccess",
14992
+ "isopendata",
14993
+ "searchUserName",
14994
+ ];
14964
14995
  var nonMatchOptionsFields = __spreadArrays(dateProps, copyProps);
14965
14996
  // Do the conversion
14966
14997
  Object.entries(filter).forEach(function (_a) {
@@ -14993,27 +15024,26 @@
14993
15024
  * @returns
14994
15025
  */
14995
15026
  function serializeFilterGroupsForPortal(filterGroups) {
14996
- var result = {
14997
- q: "",
14998
- filter: "",
14999
- };
15000
- result.q = filterGroups.map(serializeGroup).join(" AND ");
15027
+ var groupSearchOptions = filterGroups.map(serializeGroup);
15028
+ var result = mergeSearchOptions(groupSearchOptions, "AND");
15001
15029
  return result;
15002
15030
  }
15003
15031
  /**
15004
15032
  * Serialize the filters in a FitlerGroup into a Portal Query
15005
- * @param group
15033
+ * @param filterGroup
15006
15034
  * @returns
15007
15035
  */
15008
- function serializeGroup(group) {
15009
- var operation = group.operation || "AND";
15010
- var filters = group.filters.map(expandFilter);
15011
- var q = filters.map(serializeFilter).join(" " + operation + " ");
15012
- // Wrap in parens if there is more than one filter
15036
+ function serializeGroup(filterGroup) {
15037
+ var operation = filterGroup.operation || "AND";
15038
+ var filters = filterGroup.filters.map(expandFilter);
15039
+ var filterSearchOptions = filters.map(serializeFilter);
15040
+ // combine these searchOptions
15041
+ var groupSearchOptions = mergeSearchOptions(filterSearchOptions, operation);
15042
+ //
15013
15043
  if (filters.length > 1) {
15014
- q = "(" + q + ")";
15044
+ groupSearchOptions.q = "(" + groupSearchOptions.q + ")";
15015
15045
  }
15016
- return q;
15046
+ return groupSearchOptions;
15017
15047
  }
15018
15048
  /**
15019
15049
  * Serialize a Filter into a Portal Query
@@ -15023,36 +15053,64 @@
15023
15053
  function serializeFilter(filter) {
15024
15054
  var dateProps = ["created", "modified"];
15025
15055
  var boolProps = ["isopendata"];
15056
+ var passThroughProps = ["searchUserAccess", "searchUserName"];
15026
15057
  var specialProps = __spreadArrays([
15027
15058
  "filterType",
15028
- "searchUserAccess",
15029
15059
  "term"
15030
- ], dateProps, boolProps);
15060
+ ], dateProps, boolProps, passThroughProps);
15061
+ var qCount = 0;
15031
15062
  // TODO: Look at using reduce vs .map and remove the `.filter`
15032
- var stringFilters = Object.entries(filter)
15063
+ var opts = Object.entries(filter)
15033
15064
  .map(function (_a) {
15034
15065
  var key = _a[0], value = _a[1];
15066
+ var so = { q: "" };
15035
15067
  if (!specialProps.includes(key)) {
15036
- return serializeMatchOptions(key, value);
15068
+ qCount++;
15069
+ so.q = serializeMatchOptions(key, value);
15037
15070
  }
15038
15071
  if (dateProps.includes(key)) {
15039
- return serializeDateRange(key, value);
15072
+ qCount++;
15073
+ so.q = serializeDateRange(key, value);
15040
15074
  }
15041
15075
  if (boolProps.includes(key)) {
15042
- return key + ":" + value;
15076
+ qCount++;
15077
+ so.q = key + ":" + value;
15078
+ }
15079
+ if (passThroughProps.includes(key)) {
15080
+ so[key] = value;
15043
15081
  }
15044
15082
  if (key === "term") {
15045
- return value;
15083
+ qCount++;
15084
+ so.q = value;
15046
15085
  }
15086
+ return so;
15047
15087
  })
15048
15088
  .filter(function (e) { return e !== undefined; });
15049
- // eslint-disable-next-line unicorn/prefer-ternary
15050
- if (stringFilters.length > 1) {
15051
- return "(" + stringFilters.join(" AND ") + ")";
15052
- }
15053
- else {
15054
- return stringFilters[0];
15089
+ // merge up all the searchOptions
15090
+ var searchOptions = mergeSearchOptions(opts, "AND");
15091
+ if (qCount > 1) {
15092
+ searchOptions.q = "(" + searchOptions.q + ")";
15055
15093
  }
15094
+ return searchOptions;
15095
+ }
15096
+ function mergeSearchOptions(options, operation) {
15097
+ var result = options.reduce(function (acc, entry) {
15098
+ // walk the props
15099
+ Object.entries(entry).forEach(function (_a) {
15100
+ var key = _a[0], value = _a[1];
15101
+ // if prop exists
15102
+ if (acc[key]) {
15103
+ // combine via operation
15104
+ acc[key] = acc[key] + " " + operation + " " + value;
15105
+ }
15106
+ else {
15107
+ // just copy the value
15108
+ acc[key] = value;
15109
+ }
15110
+ });
15111
+ return acc;
15112
+ }, { q: "" });
15113
+ return result;
15056
15114
  }
15057
15115
  /**
15058
15116
  * Serialize MatchOptions into portal syntax
@@ -17803,7 +17861,7 @@
17803
17861
  so.countFields = options.aggFields.join(",");
17804
17862
  so.countSize = options.aggLimit || 10;
17805
17863
  }
17806
- return [2 /*return*/, searchPortal$1(so)];
17864
+ return [2 /*return*/, searchPortal$2(so)];
17807
17865
  });
17808
17866
  });
17809
17867
  }
@@ -17814,7 +17872,7 @@
17814
17872
  * @param searchOptions
17815
17873
  * @returns
17816
17874
  */
17817
- function searchPortal$1(searchOptions) {
17875
+ function searchPortal$2(searchOptions) {
17818
17876
  return __awaiter(this, void 0, void 0, function () {
17819
17877
  var resp, fn, results, facets;
17820
17878
  return __generator(this, function (_a) {
@@ -17835,7 +17893,7 @@
17835
17893
  results: results,
17836
17894
  facets: facets,
17837
17895
  hasNext: resp.nextStart > -1,
17838
- next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal$1),
17896
+ next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal$2),
17839
17897
  }];
17840
17898
  }
17841
17899
  });
@@ -18123,7 +18181,7 @@
18123
18181
  if (!so.authentication) {
18124
18182
  so.portal = so.requestOptions.portal || api.url + "/sharing/rest";
18125
18183
  }
18126
- return [2 /*return*/, searchPortal(so)];
18184
+ return [2 /*return*/, searchPortal$1(so)];
18127
18185
  });
18128
18186
  });
18129
18187
  }
@@ -18134,7 +18192,7 @@
18134
18192
  * @param searchOptions
18135
18193
  * @returns
18136
18194
  */
18137
- function searchPortal(searchOptions) {
18195
+ function searchPortal$1(searchOptions) {
18138
18196
  return __awaiter(this, void 0, void 0, function () {
18139
18197
  var resp, fn, results;
18140
18198
  return __generator(this, function (_a) {
@@ -18155,7 +18213,7 @@
18155
18213
  results: results,
18156
18214
  facets: [],
18157
18215
  hasNext: resp.nextStart > -1,
18158
- next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal),
18216
+ next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal$1),
18159
18217
  }];
18160
18218
  }
18161
18219
  });
@@ -18182,6 +18240,104 @@
18182
18240
  });
18183
18241
  }
18184
18242
 
18243
+ /**
18244
+ * @private
18245
+ * Portal Search implementation for Users
18246
+ * @param filterGroups
18247
+ * @param options
18248
+ */
18249
+ function portalSearchUsers(filterGroups, options) {
18250
+ return __awaiter(this, void 0, void 0, function () {
18251
+ var expandedGroups, so, props;
18252
+ return __generator(this, function (_a) {
18253
+ // requestOptions is always required and user must be authd
18254
+ if (!options.requestOptions) {
18255
+ throw new HubError$1("portalSearchUsers", "requestOptions: IHubRequestOptions is required.");
18256
+ }
18257
+ if (!options.requestOptions.authentication) {
18258
+ throw new HubError$1("portalSearchUsers", "requestOptions must pass authentication.");
18259
+ }
18260
+ expandedGroups = filterGroups.map(function (fg) {
18261
+ fg.filters = fg.filters.map(expandFilter);
18262
+ return fg;
18263
+ });
18264
+ so = serializeFilterGroupsForPortal(expandedGroups);
18265
+ props = [
18266
+ "num",
18267
+ "sortField",
18268
+ "sortOrder",
18269
+ "include",
18270
+ "start",
18271
+ "requestOptions",
18272
+ ];
18273
+ // copy the props over
18274
+ props.forEach(function (prop) {
18275
+ if (options.hasOwnProperty(prop)) {
18276
+ so[prop] = options[prop];
18277
+ }
18278
+ });
18279
+ // Ensure authentication gets sent
18280
+ so.authentication = options.requestOptions.authentication;
18281
+ // Execute search
18282
+ return [2 /*return*/, searchPortal(so)];
18283
+ });
18284
+ });
18285
+ }
18286
+ /**
18287
+ * Internal portal search, which then converts `IGroup`s to `IHubSearchResult`s
18288
+ * handling enrichments & includes along the way
18289
+ *
18290
+ * @param searchOptions
18291
+ * @returns
18292
+ */
18293
+ function searchPortal(searchOptions) {
18294
+ return __awaiter(this, void 0, void 0, function () {
18295
+ var resp, fn, results;
18296
+ return __generator(this, function (_a) {
18297
+ switch (_a.label) {
18298
+ case 0: return [4 /*yield*/, searchUsers(searchOptions)];
18299
+ case 1:
18300
+ resp = _a.sent();
18301
+ fn = function (user) {
18302
+ return userToSearchResult(user, searchOptions.include, searchOptions.requestOptions);
18303
+ };
18304
+ return [4 /*yield*/, Promise.all(resp.results.map(fn))];
18305
+ case 2:
18306
+ results = _a.sent();
18307
+ // Group Search does not support aggregations
18308
+ // Construct the return
18309
+ return [2 /*return*/, {
18310
+ total: resp.total,
18311
+ results: results,
18312
+ facets: [],
18313
+ hasNext: resp.nextStart > -1,
18314
+ next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal),
18315
+ }];
18316
+ }
18317
+ });
18318
+ });
18319
+ }
18320
+ /**
18321
+ * Convert an Item to a IHubSearchResult
18322
+ * Fetches the includes and attaches them to the item
18323
+ * @param item
18324
+ * @param includes
18325
+ * @param requestOptions
18326
+ * @returns
18327
+ */
18328
+ function userToSearchResult(user, includes, requestOptions) {
18329
+ if (includes === void 0) { includes = []; }
18330
+ return __awaiter(this, void 0, void 0, function () {
18331
+ return __generator(this, function (_a) {
18332
+ // Delegate to HubGroups module
18333
+ // This layer of indirection is not necessary but
18334
+ // aligns with how the items search works and
18335
+ // allows for future specialization
18336
+ return [2 /*return*/, enrichUserSearchResult(user, includes, requestOptions)];
18337
+ });
18338
+ });
18339
+ }
18340
+
18185
18341
  /**
18186
18342
  * Main Search function for ArcGIS Hub
18187
18343
  *
@@ -18215,6 +18371,7 @@
18215
18371
  arcgis: {
18216
18372
  item: portalSearchItems,
18217
18373
  group: portalSearchGroups,
18374
+ user: portalSearchUsers,
18218
18375
  },
18219
18376
  "arcgis-hub": {
18220
18377
  item: hubSearchItems,
@@ -18224,7 +18381,7 @@
18224
18381
  if (!fn) {
18225
18382
  throw new HubError$1("hubSearch", "Search via \"" + filterType + "\" filter against \"" + apiType + "\" api is not implemented");
18226
18383
  }
18227
- return [2 /*return*/, fn(filterGroups, options)];
18384
+ return [2 /*return*/, fn(cloneObject$1(filterGroups), options)];
18228
18385
  });
18229
18386
  });
18230
18387
  }
@@ -19698,6 +19855,145 @@
19698
19855
  return Hub;
19699
19856
  }());
19700
19857
 
19858
+ var enrichUserOrg = function (input) {
19859
+ var data = input.data, stack = input.stack, requestOptions = input.requestOptions;
19860
+ var opId = stack.start("enrichUserOrg");
19861
+ var options = __assign(__assign({}, requestOptions), {
19862
+ // In order to get the correct response, we must pass options.portal
19863
+ // as a base portal url (e.g., www.arcgis.com, qaext.arcgis.com, etc)
19864
+ // **not** an org portal (i.e. org.maps.arcgis.com).
19865
+ portal: getPortalBaseFromOrgUrl(requestOptions.portal) + "/sharing/rest" });
19866
+ // TODO: Add Caching
19867
+ // Had implemented a simple caching system, but it leads to unstable
19868
+ // tests because we can't deterministically clear it
19869
+ // if (!orgCache[data.user.orgId]) {
19870
+ // orgCache[data.user.orgId] = fetchOrg(data.user.orgId, options);
19871
+ // }
19872
+ // return (orgCache[data.user.orgId] as Promise<IPortal>)
19873
+ return fetchOrg(data.user.orgId, options)
19874
+ .then(function (results) {
19875
+ stack.finish(opId);
19876
+ return {
19877
+ data: __assign(__assign({}, data), {
19878
+ org: results,
19879
+ }),
19880
+ stack: stack,
19881
+ requestOptions: requestOptions,
19882
+ };
19883
+ })
19884
+ .catch(function (error) { return handleEnrichmentError(error, input, opId); });
19885
+ };
19886
+ /**
19887
+ * Simple cache for user org's. This does not expire
19888
+ * but that seems reasonable as Org props rarely change
19889
+ */
19890
+ // This works find at run-time, but it's a problem in tests
19891
+ // where we are validating calls. Will work with Randy to
19892
+ // create something that's more robust
19893
+ // const orgCache: Record<string, any> = {};
19894
+ // add the error to the content.errors,
19895
+ // log current stack operation as finished with an error
19896
+ // and return output that can be piped into the next operation
19897
+ var handleEnrichmentError = function (error, input, opId) {
19898
+ var data = input.data, stack = input.stack, requestOptions = input.requestOptions;
19899
+ stack.finish(opId, { error: error });
19900
+ return {
19901
+ data: __assign(__assign({}, data), { errors: getEnrichmentErrors(error, data.errors) }),
19902
+ stack: stack,
19903
+ requestOptions: requestOptions,
19904
+ };
19905
+ };
19906
+ /**
19907
+ * Available enrichments for Groups
19908
+ */
19909
+ var groupEnrichementOperations = {
19910
+ org: enrichUserOrg,
19911
+ };
19912
+ /**
19913
+ * Fetch enrichments for Users
19914
+ * @param group
19915
+ * @param enrichments
19916
+ * @param requestOptions
19917
+ * @returns
19918
+ */
19919
+ function fetchUserEnrichments(user, enrichments, requestOptions) {
19920
+ // create a pipeline of enrichment operations
19921
+ var operations = enrichments.reduce(function (ops, enrichment) {
19922
+ var operation = groupEnrichementOperations[enrichment];
19923
+ // only include the enrichments that we know how to fetch
19924
+ operation && ops.push(operation);
19925
+ return ops;
19926
+ }, []);
19927
+ var pipeline = createOperationPipeline(operations);
19928
+ // execute pipeline and return the item and enrichments
19929
+ return pipeline({
19930
+ data: { user: user },
19931
+ stack: new OperationStack$1(),
19932
+ requestOptions: requestOptions,
19933
+ }).then(function (output) {
19934
+ // TODO: send telemetry so we have info on what enrichments are requested and possible errors
19935
+ return output.data;
19936
+ });
19937
+ }
19938
+
19939
+ /**
19940
+ * Enrich a User object
19941
+ * @param user
19942
+ * @param includes
19943
+ * @param requestOptions
19944
+ * @returns
19945
+ */
19946
+ function enrichUserSearchResult(user, include, requestOptions) {
19947
+ return __awaiter(this, void 0, void 0, function () {
19948
+ var result, DEFAULTS, specs, enrichments, enriched, token;
19949
+ return __generator(this, function (_a) {
19950
+ switch (_a.label) {
19951
+ case 0:
19952
+ result = {
19953
+ access: user.access,
19954
+ id: user.username,
19955
+ type: "User",
19956
+ name: user.fullName,
19957
+ owner: user.username,
19958
+ summary: user.description,
19959
+ createdDate: new Date(user.created),
19960
+ createdDateSource: "user.created",
19961
+ updatedDate: new Date(user.modified),
19962
+ updatedDateSource: "user.modified",
19963
+ family: "people",
19964
+ links: {
19965
+ self: "not-implemented",
19966
+ siteRelative: "not-implemented",
19967
+ thumbnail: "not-implemented",
19968
+ },
19969
+ };
19970
+ DEFAULTS = ["org.name AS orgName"];
19971
+ // merge includes
19972
+ include = __spreadArrays(DEFAULTS, include).filter(unique);
19973
+ specs = include.map(parseInclude);
19974
+ enrichments = mapBy("enrichment", specs).filter(unique);
19975
+ enriched = {};
19976
+ if (!enrichments.length) return [3 /*break*/, 2];
19977
+ return [4 /*yield*/, fetchUserEnrichments(user, enrichments, requestOptions)];
19978
+ case 1:
19979
+ enriched = _a.sent();
19980
+ _a.label = 2;
19981
+ case 2:
19982
+ // map the enriched props onto the result
19983
+ specs.forEach(function (spec) {
19984
+ result[spec.prop] = getProp(enriched, spec.path);
19985
+ });
19986
+ token = requestOptions.authentication.token;
19987
+ // Handle links
19988
+ result.links.thumbnail = getUserThumbnailUrl(requestOptions.portal, user, token);
19989
+ result.links.self = getUserHomeUrl(result.id, requestOptions);
19990
+ result.links.siteRelative = "/people/" + result.id;
19991
+ return [2 /*return*/, result];
19992
+ }
19993
+ });
19994
+ });
19995
+ }
19996
+
19701
19997
  exports.ArcGISContext = ArcGISContext;
19702
19998
  exports.ArcGISContextManager = ArcGISContextManager;
19703
19999
  exports.DEFAULT_THEME = DEFAULT_THEME;
@@ -19825,6 +20121,7 @@
19825
20121
  exports.enrichPageSearchResult = enrichPageSearchResult;
19826
20122
  exports.enrichProjectSearchResult = enrichProjectSearchResult;
19827
20123
  exports.enrichSiteSearchResult = enrichSiteSearchResult;
20124
+ exports.enrichUserSearchResult = enrichUserSearchResult;
19828
20125
  exports.ensureProp = ensureProp;
19829
20126
  exports.ensureUniqueDomainName = ensureUniqueDomainName;
19830
20127
  exports.ensureUniqueString = ensureUniqueString;
@@ -19916,6 +20213,7 @@
19916
20213
  exports.getUniqueDomainNamePortal = getUniqueDomainNamePortal;
19917
20214
  exports.getUniqueItemTitle = getUniqueItemTitle;
19918
20215
  exports.getUniqueSlug = getUniqueSlug;
20216
+ exports.getUserHomeUrl = getUserHomeUrl;
19919
20217
  exports.getUserThumbnailUrl = getUserThumbnailUrl;
19920
20218
  exports.getWithDefault = getWithDefault$1;
19921
20219
  exports.hasBasePriv = hasBasePriv;
@@ -19954,7 +20252,7 @@
19954
20252
  exports.mergeGroupFilters = mergeGroupFilters;
19955
20253
  exports.mergeMatchOptions = mergeMatchOptions;
19956
20254
  exports.mergeObjects = mergeObjects;
19957
- exports.mergeSearchOptions = mergeSearchOptions;
20255
+ exports.mergeSearchOptions = mergeSearchOptions$1;
19958
20256
  exports.mergeUserFilters = mergeUserFilters;
19959
20257
  exports.normalizeItemType = normalizeItemType;
19960
20258
  exports.normalizeSolutionTemplateItem = normalizeSolutionTemplateItem;