@esri/hub-common 9.7.0 → 9.8.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 (76) hide show
  1. package/dist/es2017/content.js +17 -6
  2. package/dist/es2017/content.js.map +1 -1
  3. package/dist/es2017/search/_searchContent.js +66 -53
  4. package/dist/es2017/search/_searchContent.js.map +1 -1
  5. package/dist/es2017/search/_searchGroups.js +71 -36
  6. package/dist/es2017/search/_searchGroups.js.map +1 -1
  7. package/dist/es2017/search/_searchUsers.js +83 -0
  8. package/dist/es2017/search/_searchUsers.js.map +1 -0
  9. package/dist/es2017/search/index.js +2 -0
  10. package/dist/es2017/search/index.js.map +1 -1
  11. package/dist/es2017/search/user-utils.js +132 -0
  12. package/dist/es2017/search/user-utils.js.map +1 -0
  13. package/dist/es2017/search/utils.js +76 -37
  14. package/dist/es2017/search/utils.js.map +1 -1
  15. package/dist/es2017/sites/upgrade-site-schema.js +3 -0
  16. package/dist/es2017/sites/upgrade-site-schema.js.map +1 -1
  17. package/dist/es2017/urls/index.js +1 -0
  18. package/dist/es2017/urls/index.js.map +1 -1
  19. package/dist/es2017/urls/upgrade-protocol.js +14 -0
  20. package/dist/es2017/urls/upgrade-protocol.js.map +1 -0
  21. package/dist/esm/content.js +17 -6
  22. package/dist/esm/content.js.map +1 -1
  23. package/dist/esm/search/_searchContent.js +71 -62
  24. package/dist/esm/search/_searchContent.js.map +1 -1
  25. package/dist/esm/search/_searchGroups.js +75 -40
  26. package/dist/esm/search/_searchGroups.js.map +1 -1
  27. package/dist/esm/search/_searchUsers.js +88 -0
  28. package/dist/esm/search/_searchUsers.js.map +1 -0
  29. package/dist/esm/search/index.js +2 -0
  30. package/dist/esm/search/index.js.map +1 -1
  31. package/dist/esm/search/user-utils.js +136 -0
  32. package/dist/esm/search/user-utils.js.map +1 -0
  33. package/dist/esm/search/utils.js +76 -37
  34. package/dist/esm/search/utils.js.map +1 -1
  35. package/dist/esm/sites/upgrade-site-schema.js +3 -0
  36. package/dist/esm/sites/upgrade-site-schema.js.map +1 -1
  37. package/dist/esm/urls/index.js +1 -0
  38. package/dist/esm/urls/index.js.map +1 -1
  39. package/dist/esm/urls/upgrade-protocol.js +14 -0
  40. package/dist/esm/urls/upgrade-protocol.js.map +1 -0
  41. package/dist/node/content.js +18 -7
  42. package/dist/node/content.js.map +1 -1
  43. package/dist/node/search/_searchContent.js +65 -52
  44. package/dist/node/search/_searchContent.js.map +1 -1
  45. package/dist/node/search/_searchGroups.js +71 -36
  46. package/dist/node/search/_searchGroups.js.map +1 -1
  47. package/dist/node/search/_searchUsers.js +87 -0
  48. package/dist/node/search/_searchUsers.js.map +1 -0
  49. package/dist/node/search/index.js +2 -0
  50. package/dist/node/search/index.js.map +1 -1
  51. package/dist/node/search/user-utils.js +138 -0
  52. package/dist/node/search/user-utils.js.map +1 -0
  53. package/dist/node/search/utils.js +81 -39
  54. package/dist/node/search/utils.js.map +1 -1
  55. package/dist/node/sites/upgrade-site-schema.js +3 -0
  56. package/dist/node/sites/upgrade-site-schema.js.map +1 -1
  57. package/dist/node/urls/index.js +1 -0
  58. package/dist/node/urls/index.js.map +1 -1
  59. package/dist/node/urls/upgrade-protocol.js +18 -0
  60. package/dist/node/urls/upgrade-protocol.js.map +1 -0
  61. package/dist/types/content.d.ts +11 -0
  62. package/dist/types/search/_searchContent.d.ts +3 -2
  63. package/dist/types/search/_searchGroups.d.ts +3 -2
  64. package/dist/types/search/_searchUsers.d.ts +28 -0
  65. package/dist/types/search/index.d.ts +2 -0
  66. package/dist/types/search/types.d.ts +20 -2
  67. package/dist/types/search/user-utils.d.ts +35 -0
  68. package/dist/types/search/utils.d.ts +39 -8
  69. package/dist/types/types.d.ts +17 -0
  70. package/dist/types/urls/index.d.ts +1 -0
  71. package/dist/types/urls/upgrade-protocol.d.ts +5 -0
  72. package/dist/umd/common.umd.js +489 -142
  73. package/dist/umd/common.umd.js.map +1 -1
  74. package/dist/umd/common.umd.min.js +1 -1
  75. package/dist/umd/common.umd.min.js.map +1 -1
  76. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  /* @preserve
2
- * @esri/hub-common - v9.6.2 - Tue Nov 09 2021 17:13:51 GMT-0700 (Mountain Standard Time)
2
+ * @esri/hub-common - v9.7.2 - Wed Nov 24 2021 08:55:18 GMT-0800 (Pacific Standard Time)
3
3
  * Copyright (c) 2021 Environmental Systems Research Institute, Inc.
4
4
  * Apache-2.0
5
5
  */
@@ -3220,6 +3220,22 @@
3220
3220
  return request(url, options);
3221
3221
  }
3222
3222
 
3223
+ /**
3224
+ * ```js
3225
+ * import { searchItems } from "@esri/arcgis-rest-portal";
3226
+ * //
3227
+ * searchUsers({ q: 'tommy', authentication })
3228
+ * .then(response) // response.total => 355
3229
+ * ```
3230
+ * Search a portal for users.
3231
+ *
3232
+ * @param search - A RequestOptions object to pass through to the endpoint.
3233
+ * @returns A Promise that will resolve with the data from the response.
3234
+ */
3235
+ function searchUsers(search) {
3236
+ return genericSearch(search, "user");
3237
+ }
3238
+
3223
3239
  /**
3224
3240
  * ```js
3225
3241
  * import { isItemSharedWithGroup } from "@esri/arcgis-rest-portal";
@@ -3690,6 +3706,20 @@
3690
3706
  return getPortalUrl(urlOrObject) + "/sharing/rest";
3691
3707
  }
3692
3708
 
3709
+ /**
3710
+ * Add protocol or upgrade http to https
3711
+ * @param {string} url
3712
+ */
3713
+ function upgradeProtocol(url) {
3714
+ if (url.indexOf("http") === -1) {
3715
+ return "https://" + url;
3716
+ }
3717
+ else if (url.indexOf("http://") !== -1) {
3718
+ return url.replace(/^http:/i, "https:");
3719
+ }
3720
+ return url;
3721
+ }
3722
+
3693
3723
  /**
3694
3724
  * Remove protocol if present
3695
3725
  * @param {string} hostname Hostname
@@ -6184,19 +6214,30 @@
6184
6214
  });
6185
6215
  };
6186
6216
  /**
6187
- * append the absolute URL to the content on the site
6188
- * also updates the relative URL in case the
6217
+ * Calculates the relative and absolute urls for a given content on a specific site
6218
+ *
6189
6219
  * @param content
6190
6220
  * @param siteModel
6191
- * @returns
6221
+ * @returns relative and absolute urls
6192
6222
  */
6193
- var setContentSiteUrls = function (content, siteModel) {
6194
- // recompute relative URL using a site specific identifier
6223
+ var getContentSiteUrls = function (content, siteModel) {
6224
+ // compute relative URL using a site specific identifier
6195
6225
  var siteIdentifier = getContentIdentifier(content, siteModel);
6196
6226
  var relative = getContentRelativeUrl(content, siteIdentifier);
6197
6227
  // get the absolute URL to this content on the site
6198
6228
  var siteUrl = getProp(siteModel, "item.url").replace(/\/$/, "");
6199
- var site = "" + siteUrl + relative;
6229
+ var absolute = "" + siteUrl + relative;
6230
+ return { relative: relative, absolute: absolute };
6231
+ };
6232
+ /**
6233
+ * append the absolute URL to the content on the site
6234
+ * also updates the relative URL in case the
6235
+ * @param content
6236
+ * @param siteModel
6237
+ * @returns
6238
+ */
6239
+ var setContentSiteUrls = function (content, siteModel) {
6240
+ var _a = getContentSiteUrls(content, siteModel), relative = _a.relative, site = _a.absolute;
6200
6241
  // append the updated URLs to a new content
6201
6242
  return appendContentUrls(content, {
6202
6243
  relative: relative,
@@ -8144,52 +8185,27 @@
8144
8185
  };
8145
8186
  /**
8146
8187
  * @private
8147
- * Convert api "names" into full ApiDefinitions
8188
+ * Convert array of api "names" into full ApiDefinitions
8148
8189
  * @param apis
8149
8190
  * @returns
8150
8191
  */
8151
8192
  function expandApis(apis) {
8152
- return apis.map(function (api) {
8153
- if (typeof api === "string" && api in SEARCH_APIS) {
8154
- return SEARCH_APIS[api];
8155
- }
8156
- else {
8157
- // it's an object, so we trust that it's well formed
8158
- return api;
8159
- }
8160
- });
8193
+ return apis.map(expandApi);
8161
8194
  }
8162
8195
  /**
8163
8196
  * @private
8164
- * Merge multiple search responses
8165
- *
8166
- * Naieve implementation that just merges arrays
8167
- * @param responses
8197
+ * Convert an api "name" into a full ApiDefinition
8198
+ * @param api
8168
8199
  * @returns
8169
8200
  */
8170
- function mergeSearchResults(responses) {
8171
- // Merge content
8172
- var results = responses.reduce(function (acc, response) {
8173
- if (response.results) {
8174
- acc = acc.concat(response.results);
8175
- }
8176
- return acc;
8177
- }, []);
8178
- // Merge Facets
8179
- var facets = responses.reduce(function (acc, response) {
8180
- if (response.facets) {
8181
- acc = acc.concat(response.facets);
8182
- }
8183
- return acc;
8184
- }, []);
8185
- // Total
8186
- var total = responses.reduce(function (acc, entry) {
8187
- if (entry.total) {
8188
- acc = acc + entry.total;
8189
- }
8190
- return acc;
8191
- }, 0);
8192
- return { total: total, results: results, facets: facets };
8201
+ function expandApi(api) {
8202
+ if (typeof api === "string" && api in SEARCH_APIS) {
8203
+ return SEARCH_APIS[api];
8204
+ }
8205
+ else {
8206
+ // it's an object, so we trust that it's well formed
8207
+ return api;
8208
+ }
8193
8209
  }
8194
8210
  /**
8195
8211
  * @private
@@ -8449,6 +8465,69 @@
8449
8465
  }
8450
8466
  return q;
8451
8467
  }
8468
+ /**
8469
+ * Create a `.next()` function for a type
8470
+ * @param request
8471
+ * @param nextStart
8472
+ * @param total
8473
+ * @param fn
8474
+ * @returns
8475
+ */
8476
+ function getNextFunction(request, nextStart, total, fn) {
8477
+ var clonedRequest = cloneObject$1(request);
8478
+ // clone will not handle authentication so we do it manually
8479
+ if (request.authentication) {
8480
+ clonedRequest.authentication = UserSession.deserialize(request.authentication.serialize());
8481
+ }
8482
+ // figure out the start
8483
+ clonedRequest.start = nextStart > -1 ? nextStart : total + 1;
8484
+ return function (authentication) {
8485
+ if (authentication) {
8486
+ clonedRequest.authentication = authentication;
8487
+ }
8488
+ return fn(clonedRequest);
8489
+ };
8490
+ }
8491
+ /**
8492
+ * Construct a the full url to a group thumbnail
8493
+ *
8494
+ * - If the group has a thumbnail, construct the full url
8495
+ * - If the group is not public, append on the token
8496
+ * @param portalUrl
8497
+ * @param group
8498
+ * @param token
8499
+ * @returns
8500
+ */
8501
+ function getGroupThumbnailUrl(portalUrl, group, token) {
8502
+ var thumbnailUrl = null;
8503
+ if (group.thumbnail) {
8504
+ thumbnailUrl = portalUrl + "/community/groups/" + group.id + "/info/" + group.thumbnail;
8505
+ if (token && group.access !== "public") {
8506
+ thumbnailUrl = thumbnailUrl + "?token=" + token;
8507
+ }
8508
+ }
8509
+ return thumbnailUrl;
8510
+ }
8511
+ /**
8512
+ * Construct a the full url to a user thumbnail
8513
+ *
8514
+ * - If the user has a thumbnail, construct the full url
8515
+ * - If the user is not public, append on the token
8516
+ * @param portalUrl
8517
+ * @param user
8518
+ * @param token
8519
+ * @returns
8520
+ */
8521
+ function getUserThumbnailUrl(portalUrl, user, token) {
8522
+ var thumbnailUrl = null;
8523
+ if (user.thumbnail) {
8524
+ thumbnailUrl = portalUrl + "/community/users/" + user.username + "/info/" + user.thumbnail;
8525
+ if (token && user.access !== "public") {
8526
+ thumbnailUrl = thumbnailUrl + "?token=" + token;
8527
+ }
8528
+ }
8529
+ return thumbnailUrl;
8530
+ }
8452
8531
 
8453
8532
  // TODO: Implement $dataset
8454
8533
  var ContentFilterExpansions = {
@@ -8998,79 +9077,219 @@
8998
9077
  return result;
8999
9078
  }
9000
9079
 
9080
+ /**
9081
+ *
9082
+ * Merge `Filter<"user">` objects
9083
+ *
9084
+ * Useful in components which may get partial filters from a variety of
9085
+ * sub-components, which are then combined into a single filter prior
9086
+ * to executing the search.
9087
+ * @param filters
9088
+ * @returns
9089
+ */
9090
+ function mergeUserFilters(filters) {
9091
+ // expand all the filters so all prop types are consistent
9092
+ var expanded = filters.map(expandUserFilter);
9093
+ // now we can merge based on fields
9094
+ var dateFields = ["created", "modified", "lastlogin"];
9095
+ var specialFields = __spreadArrays(["disabled", "term", "filterType"], dateFields);
9096
+ // acc is initialized as Filter<group> but also needs it
9097
+ // in the function signature... for reasons?!
9098
+ var result = expanded.reduce(function (acc, entry) {
9099
+ // process fields
9100
+ Object.entries(entry).forEach(function (_a) {
9101
+ // Note: getProp/setProp are used to get around
9102
+ // typescript issues with string indexing
9103
+ var key = _a[0], value = _a[1];
9104
+ if (acc.hasOwnProperty(key)) {
9105
+ var existingValue = getProp(acc, key);
9106
+ // if the key is not to a special field
9107
+ if (!specialFields.includes(key)) {
9108
+ // treat as an IMatchOptions
9109
+ setProp(key, mergeMatchOptions(existingValue, value), acc);
9110
+ }
9111
+ else if (dateFields.includes(key)) {
9112
+ // treat as IDateRange
9113
+ setProp(key, mergeDateRange(existingValue, value), acc);
9114
+ }
9115
+ else if (key === "term") {
9116
+ // append terms
9117
+ acc[key] = acc[key] + " " + value;
9118
+ }
9119
+ }
9120
+ else {
9121
+ // Acc does not have an entry for this yet
9122
+ // so just clone it
9123
+ setProp(key, cloneObject$1(value), acc);
9124
+ }
9125
+ });
9126
+ return acc;
9127
+ }, {
9128
+ filterType: "user",
9129
+ });
9130
+ return result;
9131
+ }
9132
+ /**
9133
+ * Prior to serialization into the query syntax for the backing APIs, we first expand [Filters](../Filter)
9134
+ *
9135
+ * Filter's can express their intent in a very terse form, but to ensure consistent structures
9136
+ * we expand them into their more verbose form.
9137
+ *
9138
+ * i.e. `firstname: "John"` expands into `firstname: { any: ["John"]}`
9139
+ *
9140
+ * - Fields defined as `string | string[] | MatchOptions` will be converted to a `MatchOptions`
9141
+ * - RelativeDate fields are converted to DateRange<number>
9142
+ * @param filter
9143
+ * @returns
9144
+ */
9145
+ function expandUserFilter(filter) {
9146
+ var result = {};
9147
+ var dateProps = ["created", "modified", "lastlogin"];
9148
+ var specialProps = __spreadArrays(["disabled", "term"], dateProps);
9149
+ Object.entries(filter).forEach(function (_a) {
9150
+ var key = _a[0], value = _a[1];
9151
+ // handle Matchish fields
9152
+ if (!specialProps.includes(key)) {
9153
+ // setProp side-steps typescript complaining
9154
+ setProp(key, valueToMatchOptions(value), result);
9155
+ }
9156
+ // Handle date fields
9157
+ if (dateProps.includes(key)) {
9158
+ var dateFieldValue = cloneObject$1(getProp(filter, key));
9159
+ if (getProp(filter, key + ".type") === "relative-date") {
9160
+ setProp(key, relativeDateToDateRange(dateFieldValue), result);
9161
+ }
9162
+ else {
9163
+ setProp(key, dateFieldValue, result);
9164
+ }
9165
+ }
9166
+ });
9167
+ // disabled is boolean, so we check if the prop exists
9168
+ // vs checking if the value is truthy
9169
+ if (filter.hasOwnProperty("disabled")) {
9170
+ result.disabled = filter.disabled;
9171
+ }
9172
+ if (filter.term) {
9173
+ result.term = filter.term;
9174
+ }
9175
+ return result;
9176
+ }
9177
+ /**
9178
+ * @private
9179
+ * Serialize an `IUserFilterDefinition` into an `ISearchOptions` for use
9180
+ * with `searchUsers`
9181
+ * @param filter
9182
+ * @returns
9183
+ */
9184
+ function serializeUserFilterForPortal(filter) {
9185
+ var result = {
9186
+ q: "",
9187
+ filter: "",
9188
+ };
9189
+ var dateProps = ["created", "modified", "lastlogin"];
9190
+ var specialProps = __spreadArrays(["term", "filterType"], dateProps);
9191
+ Object.entries(filter).forEach(function (_a) {
9192
+ var key = _a[0], value = _a[1];
9193
+ // MatchOptions fields
9194
+ if (!specialProps.includes(key)) {
9195
+ result = mergeSearchOptions(result, serializeMatchOptions(key, value), "AND");
9196
+ }
9197
+ // Dates only go into q
9198
+ if (dateProps.includes(key)) {
9199
+ result = mergeSearchOptions(result, serializeDateRange(key, value), "AND");
9200
+ }
9201
+ });
9202
+ // disabled is also a top-level property
9203
+ if (filter.hasOwnProperty("disabled")) {
9204
+ result.disabled = filter.disabled;
9205
+ }
9206
+ // add the term
9207
+ if (filter.term) {
9208
+ // Note: this is slightly different from other types
9209
+ result.q = ("(" + filter.term + ") " + result.q).trim();
9210
+ }
9211
+ return result;
9212
+ }
9213
+
9001
9214
  /**
9002
9215
  * Search for content via the Portal or Hub API
9003
9216
  * @param filter
9004
9217
  * @param options
9005
9218
  */
9006
9219
  function _searchContent(filter, options) {
9220
+ var _a;
9007
9221
  return __awaiter(this, void 0, void 0, function () {
9008
- var expanded, apis, searchPromises, results;
9009
- return __generator(this, function (_a) {
9010
- switch (_a.label) {
9011
- case 0:
9012
- expanded = expandContentFilter(filter);
9013
- // APIs
9014
- if (!options.apis) {
9015
- // default to AGO PROD
9016
- options.apis = ["arcgis"];
9017
- }
9018
- apis = expandApis(options.apis);
9019
- searchPromises = apis.map(function (api) {
9020
- var _a;
9021
- // Portal Search
9022
- if (api.type === "arcgis") {
9023
- // serialize for portal
9024
- var so = serializeContentFilterForPortal(expanded);
9025
- // pass auth forward
9026
- if (options.authentication) {
9027
- so.authentication = options.authentication;
9028
- }
9029
- // Aggregations
9030
- if ((_a = options.aggregations) === null || _a === void 0 ? void 0 : _a.length) {
9031
- so.countFields = options.aggregations.join(",");
9032
- so.countSize = 200;
9033
- }
9034
- // copy over various options
9035
- // TODO: Dry this up
9036
- if (options.num) {
9037
- so.num = options.num;
9038
- }
9039
- if (options.sortField) {
9040
- so.sortField = options.sortField;
9041
- }
9042
- if (options.sortOrder) {
9043
- so.sortOrder = options.sortOrder;
9044
- }
9045
- // NOTE: I think we will end up setting
9046
- // the site URL in mergeSearchResults() instead
9047
- // since it applies to both items and datasets
9048
- return searchPortal(so, options.site);
9049
- }
9050
- else {
9051
- // Hub API Search
9052
- // TODO: Implement hub api content search
9053
- return Promise.resolve({
9054
- total: 0,
9055
- results: [],
9056
- facets: [],
9057
- });
9058
- }
9059
- });
9060
- return [4 /*yield*/, Promise.all(searchPromises)];
9061
- case 1:
9062
- results = _a.sent();
9063
- // merge and return
9064
- return [2 /*return*/, mergeSearchResults(results)];
9222
+ var expanded, api, searchPromise, so;
9223
+ return __generator(this, function (_b) {
9224
+ expanded = expandContentFilter(filter);
9225
+ api = expandApi(options.api || "arcgis");
9226
+ // map over the apis, depending on the type we issue the queries
9227
+ // const searchPromises = apis.map((api) => {
9228
+ // Portal Search
9229
+ if (api.type === "arcgis") {
9230
+ so = serializeContentFilterForPortal(expanded);
9231
+ // pass auth forward
9232
+ if (options.authentication) {
9233
+ so.authentication = options.authentication;
9234
+ }
9235
+ else {
9236
+ so.portal = api.url + "/sharing/rest";
9237
+ }
9238
+ // Aggregations
9239
+ if ((_a = options.aggregations) === null || _a === void 0 ? void 0 : _a.length) {
9240
+ so.countFields = options.aggregations.join(",");
9241
+ so.countSize = 200;
9242
+ }
9243
+ // copy over various options
9244
+ // TODO: Dry this up - typscript makes this... inconvenient
9245
+ if (options.num) {
9246
+ so.num = options.num;
9247
+ }
9248
+ if (options.sortField) {
9249
+ so.sortField = options.sortField;
9250
+ }
9251
+ if (options.sortOrder) {
9252
+ so.sortOrder = options.sortOrder;
9253
+ }
9254
+ if (options.site) {
9255
+ so.site = cloneObject$1(options.site);
9256
+ }
9257
+ searchPromise = searchPortal(so);
9065
9258
  }
9259
+ else {
9260
+ // Hub API Search
9261
+ // TODO: Implement hub api content search
9262
+ searchPromise = Promise.resolve({
9263
+ total: 0,
9264
+ results: [],
9265
+ facets: [],
9266
+ hasNext: false,
9267
+ next: function () {
9268
+ },
9269
+ });
9270
+ }
9271
+ // });
9272
+ // return for results
9273
+ return [2 /*return*/, searchPromise];
9066
9274
  });
9067
9275
  });
9068
9276
  }
9069
- function searchPortal(searchOptions, site) {
9277
+ /**
9278
+ * Internal portal search, which then converts items to Content, and
9279
+ * if a Site was passed, also sets urls
9280
+ *
9281
+ * @param searchOptions
9282
+ * @param site
9283
+ * @returns
9284
+ */
9285
+ function searchPortal(searchOptions) {
9070
9286
  return searchItems(searchOptions).then(function (resp) {
9287
+ var hasNext = resp.nextStart > -1;
9071
9288
  var content = resp.results.map(itemToContent);
9072
- if (site) {
9073
- content = content.map(function (entry) { return setContentSiteUrls(entry, site); });
9289
+ if (searchOptions.site) {
9290
+ content = content.map(function (entry) {
9291
+ return setContentSiteUrls(entry, searchOptions.site);
9292
+ });
9074
9293
  }
9075
9294
  // convert aggregations into facets
9076
9295
  var facets = convertPortalResponseToFacets(resp);
@@ -9078,6 +9297,8 @@
9078
9297
  total: resp.total,
9079
9298
  results: content,
9080
9299
  facets: facets,
9300
+ hasNext: hasNext,
9301
+ next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal),
9081
9302
  };
9082
9303
  });
9083
9304
  }
@@ -9093,54 +9314,168 @@
9093
9314
  function _searchGroups(filter, options) {
9094
9315
  var _a;
9095
9316
  return __awaiter(this, void 0, void 0, function () {
9096
- var expanded, apis, so, token, us, portalUrl, thumbnailify;
9317
+ var expanded, api, so;
9097
9318
  return __generator(this, function (_b) {
9098
9319
  expanded = expandGroupFilter(filter);
9099
- // APIs
9100
- if (!options.apis) {
9101
- // default to AGO PROD
9102
- options.apis = ["arcgis"];
9103
- }
9104
- apis = expandApis(options.apis);
9105
- so = serializeGroupFilterForPortal(expanded);
9106
- token = "";
9107
- // if we have auth, pass it forward
9108
- // otherwise set the portal property
9109
- if (options.authentication) {
9110
- so.authentication = options.authentication;
9111
- us = options.authentication;
9112
- token = us.token;
9320
+ api = expandApi(options.api || "arcgis");
9321
+ if (api.type === "arcgis") {
9322
+ so = serializeGroupFilterForPortal(expanded);
9323
+ // if we have auth, pass it forward
9324
+ // otherwise set the portal property
9325
+ if (options.authentication) {
9326
+ so.authentication = options.authentication;
9327
+ }
9328
+ else {
9329
+ so.portal = api.url + "/sharing/rest";
9330
+ }
9331
+ // TODO: Dry this up - typscript makes this... inconvenient
9332
+ if (options.num) {
9333
+ so.num = options.num;
9334
+ }
9335
+ if (options.sortField) {
9336
+ so.sortField = options.sortField;
9337
+ }
9338
+ if (options.sortOrder) {
9339
+ so.sortOrder = options.sortOrder;
9340
+ }
9341
+ api.url + "/sharing/rest";
9342
+ if ((_a = so.authentication) === null || _a === void 0 ? void 0 : _a.portal) {
9343
+ so.authentication.portal;
9344
+ }
9345
+ if (options.site) {
9346
+ so.site = cloneObject$1(options.site);
9347
+ }
9348
+ return [2 /*return*/, searchPortalGroups(so)];
9113
9349
  }
9114
9350
  else {
9115
- so.portal = apis[0].url + "/sharing/rest";
9351
+ throw new Error("_searchGroups is not implemented for non-arcgis apis");
9352
+ }
9353
+ });
9354
+ });
9355
+ }
9356
+ /**
9357
+ * Internal function that searches for groups using the ArcGIS Portal API
9358
+ * @param searchOptions
9359
+ * @returns
9360
+ */
9361
+ function searchPortalGroups(searchOptions) {
9362
+ var _a;
9363
+ var teamLinkify = function (group) {
9364
+ group.siteTeamUrl = searchOptions.site.item.url + "/teams/" + group.id + "/about";
9365
+ return group;
9366
+ };
9367
+ var portalUrl = ((_a = searchOptions.authentication) === null || _a === void 0 ? void 0 : _a.portal) ||
9368
+ "https://www.arcgis.com/sharing/rest";
9369
+ var token;
9370
+ if (searchOptions.authentication) {
9371
+ var us = searchOptions.authentication;
9372
+ token = us.token;
9373
+ }
9374
+ var thumbnailify = function (group) {
9375
+ group.thumbnailUrl = getGroupThumbnailUrl(portalUrl, group, token);
9376
+ return group;
9377
+ };
9378
+ // execute the search
9379
+ return searchGroups(searchOptions).then(function (response) {
9380
+ var _a, _b;
9381
+ var hasNext = response.nextStart > -1;
9382
+ // upgrade thumbnail url
9383
+ var results = response.results.map(thumbnailify);
9384
+ // generate the site team url if site url is provided
9385
+ if ((_b = (_a = searchOptions.site) === null || _a === void 0 ? void 0 : _a.item) === null || _b === void 0 ? void 0 : _b.url) {
9386
+ results = response.results.map(teamLinkify);
9387
+ }
9388
+ return {
9389
+ hasNext: hasNext,
9390
+ total: response.total,
9391
+ results: results,
9392
+ next: getNextFunction(searchOptions, response.nextStart, response.total, searchPortalGroups),
9393
+ };
9394
+ });
9395
+ }
9396
+
9397
+ /**
9398
+ * Search for Users via the Portal API.
9399
+ *
9400
+ * **Note** Authentication is required
9401
+ *
9402
+ * Note: in the future, there may be options to search via
9403
+ * a Hub specific API
9404
+ * @param filter
9405
+ * @param options
9406
+ * @returns
9407
+ */
9408
+ function _searchUsers(filter, options) {
9409
+ return __awaiter(this, void 0, void 0, function () {
9410
+ var expanded, api, searchOptions;
9411
+ return __generator(this, function (_a) {
9412
+ // JS Clients may not pass in authentication
9413
+ if (!options.authentication) {
9414
+ throw new Error("Authentication required to search for users.");
9116
9415
  }
9117
- if (options.num) {
9118
- so.num = options.num;
9416
+ expanded = expandUserFilter(filter);
9417
+ api = expandApi(options.api || "arcgis");
9418
+ if (api.type === "arcgis") {
9419
+ searchOptions = serializeUserFilterForPortal(expanded);
9420
+ // carry the auth forward
9421
+ searchOptions.authentication = options.authentication;
9422
+ // TODO: Dry this up - typscript makes this... inconvenient
9423
+ if (options.num) {
9424
+ searchOptions.num = options.num;
9425
+ }
9426
+ if (options.sortField) {
9427
+ searchOptions.sortField = options.sortField;
9428
+ }
9429
+ if (options.sortOrder) {
9430
+ searchOptions.sortOrder = options.sortOrder;
9431
+ }
9432
+ if (options.site) {
9433
+ searchOptions.site = cloneObject$1(options.site);
9434
+ }
9435
+ return [2 /*return*/, searchPortalUsers(searchOptions)];
9119
9436
  }
9120
- portalUrl = "https://www.arcgis.com/sharing/rest";
9121
- if ((_a = so.authentication) === null || _a === void 0 ? void 0 : _a.portal) {
9122
- portalUrl = so.authentication.portal;
9437
+ else {
9438
+ throw new Error("_searchUsers is not implemented for non-arcgis apis");
9123
9439
  }
9124
- thumbnailify = function (group) {
9125
- return addThumbnailUrl(portalUrl, group, token);
9126
- };
9127
- return [2 /*return*/, searchGroups(so).then(function (response) {
9128
- // upgrade thumbnail url
9129
- response.results = response.results.map(thumbnailify);
9130
- return response;
9131
- })];
9132
9440
  });
9133
9441
  });
9134
9442
  }
9135
- // Need to decide how to handle adding the token is group is not public
9136
- function addThumbnailUrl(portalUrl, group, token) {
9137
- if (group.thumbnail) {
9138
- group.thumnailUrl = portalUrl + "/community/groups/" + group.id + "/info/" + group.thumbnail;
9139
- if (token) {
9140
- group.thumbnailUrl = group.thumbnailUrl + "?token=" + token;
9443
+ /**
9444
+ * Internal function that executes the user search along with
9445
+ * some simple enrichments
9446
+ * @param searchOptions
9447
+ * @returns
9448
+ */
9449
+ function searchPortalUsers(searchOptions) {
9450
+ var portalUrl = searchOptions.authentication.portal;
9451
+ var token = searchOptions.authentication.token;
9452
+ // Partially applied functions for mapping over the results
9453
+ var userLinkify = function (user) {
9454
+ user.profileUrl = searchOptions.site.item.url + "/people/" + user.username + "/profile";
9455
+ return user;
9456
+ };
9457
+ var thumbnailify = function (user) {
9458
+ if (user.thumbnail) {
9459
+ user.thumbnailUrl = getUserThumbnailUrl(portalUrl, user, token);
9141
9460
  }
9142
- }
9143
- return group;
9461
+ return user;
9462
+ };
9463
+ return searchUsers(searchOptions).then(function (response) {
9464
+ var _a, _b;
9465
+ var hasNext = response.nextStart > -1;
9466
+ // upgrade thumbnail url
9467
+ var results = response.results.map(thumbnailify);
9468
+ // generate the site team url if site url is provided
9469
+ if ((_b = (_a = searchOptions.site) === null || _a === void 0 ? void 0 : _a.item) === null || _b === void 0 ? void 0 : _b.url) {
9470
+ results = response.results.map(userLinkify);
9471
+ }
9472
+ return {
9473
+ hasNext: hasNext,
9474
+ total: response.total,
9475
+ results: results,
9476
+ next: getNextFunction(searchOptions, response.nextStart, response.total, searchPortalUsers),
9477
+ };
9478
+ });
9144
9479
  }
9145
9480
 
9146
9481
  /**
@@ -9749,6 +10084,9 @@
9749
10084
  model = _purgeNonGuidsFromCatalog(model);
9750
10085
  model = _ensureTelemetry(model);
9751
10086
  model = _migrateFeedConfig(model);
10087
+ // WARNING - If you are writing a site schema migration,
10088
+ // you probably need to apply it to site drafts as well!
10089
+ // See https://github.com/Esri/hub.js/issues/498 for more details.
9752
10090
  return model;
9753
10091
  }
9754
10092
  }
@@ -10385,6 +10723,7 @@
10385
10723
  exports._processSecondaryEmail = _processSecondaryEmail;
10386
10724
  exports._searchContent = _searchContent;
10387
10725
  exports._searchGroups = _searchGroups;
10726
+ exports._searchUsers = _searchUsers;
10388
10727
  exports._unprotectAndRemoveGroup = _unprotectAndRemoveGroup;
10389
10728
  exports._unprotectAndRemoveItem = _unprotectAndRemoveItem;
10390
10729
  exports.addContextToSlug = addContextToSlug;
@@ -10434,10 +10773,12 @@
10434
10773
  exports.ensureProp = ensureProp;
10435
10774
  exports.ensureUniqueDomainName = ensureUniqueDomainName;
10436
10775
  exports.ensureUniqueString = ensureUniqueString;
10776
+ exports.expandApi = expandApi;
10437
10777
  exports.expandApis = expandApis;
10438
10778
  exports.expandContentFilter = expandContentFilter;
10439
10779
  exports.expandGroupFilter = expandGroupFilter;
10440
10780
  exports.expandTypeField = expandTypeField;
10781
+ exports.expandUserFilter = expandUserFilter;
10441
10782
  exports.extend = extend;
10442
10783
  exports.extentToBBox = extentToBBox;
10443
10784
  exports.failSafe = failSafe;
@@ -10455,12 +10796,14 @@
10455
10796
  exports.getCategory = getCategory;
10456
10797
  exports.getCollection = getCollection;
10457
10798
  exports.getContentIdentifier = getContentIdentifier;
10799
+ exports.getContentSiteUrls = getContentSiteUrls;
10458
10800
  exports.getCulture = getCulture;
10459
10801
  exports.getDomainsForSite = getDomainsForSite;
10460
10802
  exports.getExportItemTypeKeyword = getExportItemTypeKeyword;
10461
10803
  exports.getExportLayerTypeKeyword = getExportLayerTypeKeyword;
10462
10804
  exports.getFamily = getFamily;
10463
10805
  exports.getGeographicOrgExtent = getGeographicOrgExtent;
10806
+ exports.getGroupThumbnailUrl = getGroupThumbnailUrl;
10464
10807
  exports.getHubApiUrl = getHubApiUrl;
10465
10808
  exports.getHubApiUrlFromPortal = getHubApiUrlFromPortal;
10466
10809
  exports.getHubLocaleAssetUrl = getHubLocaleAssetUrl;
@@ -10478,6 +10821,7 @@
10478
10821
  exports.getLayerIdFromUrl = getLayerIdFromUrl;
10479
10822
  exports.getModel = getModel;
10480
10823
  exports.getModelFromOptions = getModelFromOptions;
10824
+ exports.getNextFunction = getNextFunction;
10481
10825
  exports.getOrgExtentAsBBox = getOrgExtentAsBBox;
10482
10826
  exports.getPortalApiUrl = getPortalApiUrl;
10483
10827
  exports.getPortalUrl = getPortalUrl;
@@ -10496,6 +10840,7 @@
10496
10840
  exports.getUniqueDomainName = getUniqueDomainName;
10497
10841
  exports.getUniqueDomainNamePortal = getUniqueDomainNamePortal;
10498
10842
  exports.getUniqueItemTitle = getUniqueItemTitle;
10843
+ exports.getUserThumbnailUrl = getUserThumbnailUrl;
10499
10844
  exports.getWithDefault = getWithDefault$1;
10500
10845
  exports.hasBasePriv = hasBasePriv;
10501
10846
  exports.hubApiRequest = hubApiRequest;
@@ -10531,7 +10876,7 @@
10531
10876
  exports.mergeMatchOptions = mergeMatchOptions;
10532
10877
  exports.mergeObjects = mergeObjects;
10533
10878
  exports.mergeSearchOptions = mergeSearchOptions;
10534
- exports.mergeSearchResults = mergeSearchResults;
10879
+ exports.mergeUserFilters = mergeUserFilters;
10535
10880
  exports.normalizeItemType = normalizeItemType;
10536
10881
  exports.normalizeSolutionTemplateItem = normalizeSolutionTemplateItem;
10537
10882
  exports.objectToArray = objectToArray;
@@ -10553,6 +10898,7 @@
10553
10898
  exports.serializeModel = serializeModel;
10554
10899
  exports.serializeSpatialReference = serializeSpatialReference;
10555
10900
  exports.serializeStringOrArray = serializeStringOrArray;
10901
+ exports.serializeUserFilterForPortal = serializeUserFilterForPortal;
10556
10902
  exports.setContentHubId = setContentHubId;
10557
10903
  exports.setContentSiteUrls = setContentSiteUrls;
10558
10904
  exports.setContentType = setContentType;
@@ -10566,6 +10912,7 @@
10566
10912
  exports.unprotectModel = unprotectModel;
10567
10913
  exports.unshareItemFromGroups = unshareItemFromGroups;
10568
10914
  exports.updateDomain = updateDomain;
10915
+ exports.upgradeProtocol = upgradeProtocol;
10569
10916
  exports.upgradeSiteSchema = upgradeSiteSchema;
10570
10917
  exports.uploadResourcesFromUrl = uploadResourcesFromUrl;
10571
10918
  exports.valueToMatchOptions = valueToMatchOptions;