@esri/hub-common 9.7.1 → 9.8.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.
Files changed (62) hide show
  1. package/dist/es2017/content.js +20 -9
  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 +67 -41
  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/esm/content.js +20 -9
  18. package/dist/esm/content.js.map +1 -1
  19. package/dist/esm/search/_searchContent.js +71 -62
  20. package/dist/esm/search/_searchContent.js.map +1 -1
  21. package/dist/esm/search/_searchGroups.js +75 -49
  22. package/dist/esm/search/_searchGroups.js.map +1 -1
  23. package/dist/esm/search/_searchUsers.js +88 -0
  24. package/dist/esm/search/_searchUsers.js.map +1 -0
  25. package/dist/esm/search/index.js +2 -0
  26. package/dist/esm/search/index.js.map +1 -1
  27. package/dist/esm/search/user-utils.js +136 -0
  28. package/dist/esm/search/user-utils.js.map +1 -0
  29. package/dist/esm/search/utils.js +76 -37
  30. package/dist/esm/search/utils.js.map +1 -1
  31. package/dist/esm/sites/upgrade-site-schema.js +3 -0
  32. package/dist/esm/sites/upgrade-site-schema.js.map +1 -1
  33. package/dist/node/content.js +21 -10
  34. package/dist/node/content.js.map +1 -1
  35. package/dist/node/search/_searchContent.js +65 -52
  36. package/dist/node/search/_searchContent.js.map +1 -1
  37. package/dist/node/search/_searchGroups.js +67 -41
  38. package/dist/node/search/_searchGroups.js.map +1 -1
  39. package/dist/node/search/_searchUsers.js +87 -0
  40. package/dist/node/search/_searchUsers.js.map +1 -0
  41. package/dist/node/search/index.js +2 -0
  42. package/dist/node/search/index.js.map +1 -1
  43. package/dist/node/search/user-utils.js +138 -0
  44. package/dist/node/search/user-utils.js.map +1 -0
  45. package/dist/node/search/utils.js +81 -39
  46. package/dist/node/search/utils.js.map +1 -1
  47. package/dist/node/sites/upgrade-site-schema.js +3 -0
  48. package/dist/node/sites/upgrade-site-schema.js.map +1 -1
  49. package/dist/types/content.d.ts +13 -2
  50. package/dist/types/search/_searchContent.d.ts +3 -2
  51. package/dist/types/search/_searchGroups.d.ts +3 -2
  52. package/dist/types/search/_searchUsers.d.ts +28 -0
  53. package/dist/types/search/index.d.ts +2 -0
  54. package/dist/types/search/types.d.ts +20 -2
  55. package/dist/types/search/user-utils.d.ts +35 -0
  56. package/dist/types/search/utils.d.ts +39 -8
  57. package/dist/types/types.d.ts +17 -0
  58. package/dist/umd/common.umd.js +477 -154
  59. package/dist/umd/common.umd.js.map +1 -1
  60. package/dist/umd/common.umd.min.js +1 -1
  61. package/dist/umd/common.umd.min.js.map +1 -1
  62. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  /* @preserve
2
- * @esri/hub-common - v9.7.0 - Mon Nov 15 2021 14:36:45 GMT-0700 (Mountain Standard Time)
2
+ * @esri/hub-common - v9.8.0 - Mon Dec 06 2021 08:31:21 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";
@@ -6163,7 +6179,7 @@
6163
6179
  };
6164
6180
  }
6165
6181
  /**
6166
- * retunrs a new content that has the specified type and
6182
+ * returns a new content that has the specified type and
6167
6183
  * and updated related properties like normalizedType, family, etc
6168
6184
  * @param content orignal content
6169
6185
  * @param type new type
@@ -6171,8 +6187,8 @@
6171
6187
  */
6172
6188
  var setContentType = function (content, type) {
6173
6189
  // get family and normalized type based on new type
6174
- var family = getFamily(type);
6175
6190
  var normalizedType = normalizeItemType(__assign(__assign({}, content.item), { type: type }));
6191
+ var family = getFamily(normalizedType);
6176
6192
  var updated = __assign(__assign({}, content), { type: type, family: family, normalizedType: normalizedType });
6177
6193
  // update the relative URL to the content
6178
6194
  // which is based on type and family
@@ -6181,7 +6197,7 @@
6181
6197
  });
6182
6198
  };
6183
6199
  /**
6184
- * retunrs a new content that has the specified hubId and updated identifier
6200
+ * returns a new content that has the specified hubId and updated identifier
6185
6201
  * @param content orignal content
6186
6202
  * @param hubId new hubId
6187
6203
  * @returns new content
@@ -6198,19 +6214,30 @@
6198
6214
  });
6199
6215
  };
6200
6216
  /**
6201
- * append the absolute URL to the content on the site
6202
- * also updates the relative URL in case the
6217
+ * Calculates the relative and absolute urls for a given content on a specific site
6218
+ *
6203
6219
  * @param content
6204
6220
  * @param siteModel
6205
- * @returns
6221
+ * @returns relative and absolute urls
6206
6222
  */
6207
- var setContentSiteUrls = function (content, siteModel) {
6208
- // recompute relative URL using a site specific identifier
6223
+ var getContentSiteUrls = function (content, siteModel) {
6224
+ // compute relative URL using a site specific identifier
6209
6225
  var siteIdentifier = getContentIdentifier(content, siteModel);
6210
6226
  var relative = getContentRelativeUrl(content, siteIdentifier);
6211
6227
  // get the absolute URL to this content on the site
6212
6228
  var siteUrl = getProp(siteModel, "item.url").replace(/\/$/, "");
6213
- 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;
6214
6241
  // append the updated URLs to a new content
6215
6242
  return appendContentUrls(content, {
6216
6243
  relative: relative,
@@ -8158,52 +8185,27 @@
8158
8185
  };
8159
8186
  /**
8160
8187
  * @private
8161
- * Convert api "names" into full ApiDefinitions
8188
+ * Convert array of api "names" into full ApiDefinitions
8162
8189
  * @param apis
8163
8190
  * @returns
8164
8191
  */
8165
8192
  function expandApis(apis) {
8166
- return apis.map(function (api) {
8167
- if (typeof api === "string" && api in SEARCH_APIS) {
8168
- return SEARCH_APIS[api];
8169
- }
8170
- else {
8171
- // it's an object, so we trust that it's well formed
8172
- return api;
8173
- }
8174
- });
8193
+ return apis.map(expandApi);
8175
8194
  }
8176
8195
  /**
8177
8196
  * @private
8178
- * Merge multiple search responses
8179
- *
8180
- * Naieve implementation that just merges arrays
8181
- * @param responses
8197
+ * Convert an api "name" into a full ApiDefinition
8198
+ * @param api
8182
8199
  * @returns
8183
8200
  */
8184
- function mergeSearchResults(responses) {
8185
- // Merge content
8186
- var results = responses.reduce(function (acc, response) {
8187
- if (response.results) {
8188
- acc = acc.concat(response.results);
8189
- }
8190
- return acc;
8191
- }, []);
8192
- // Merge Facets
8193
- var facets = responses.reduce(function (acc, response) {
8194
- if (response.facets) {
8195
- acc = acc.concat(response.facets);
8196
- }
8197
- return acc;
8198
- }, []);
8199
- // Total
8200
- var total = responses.reduce(function (acc, entry) {
8201
- if (entry.total) {
8202
- acc = acc + entry.total;
8203
- }
8204
- return acc;
8205
- }, 0);
8206
- 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
+ }
8207
8209
  }
8208
8210
  /**
8209
8211
  * @private
@@ -8463,6 +8465,69 @@
8463
8465
  }
8464
8466
  return q;
8465
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
+ }
8466
8531
 
8467
8532
  // TODO: Implement $dataset
8468
8533
  var ContentFilterExpansions = {
@@ -9012,79 +9077,219 @@
9012
9077
  return result;
9013
9078
  }
9014
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
+
9015
9214
  /**
9016
9215
  * Search for content via the Portal or Hub API
9017
9216
  * @param filter
9018
9217
  * @param options
9019
9218
  */
9020
9219
  function _searchContent(filter, options) {
9220
+ var _a;
9021
9221
  return __awaiter(this, void 0, void 0, function () {
9022
- var expanded, apis, searchPromises, results;
9023
- return __generator(this, function (_a) {
9024
- switch (_a.label) {
9025
- case 0:
9026
- expanded = expandContentFilter(filter);
9027
- // APIs
9028
- if (!options.apis) {
9029
- // default to AGO PROD
9030
- options.apis = ["arcgis"];
9031
- }
9032
- apis = expandApis(options.apis);
9033
- searchPromises = apis.map(function (api) {
9034
- var _a;
9035
- // Portal Search
9036
- if (api.type === "arcgis") {
9037
- // serialize for portal
9038
- var so = serializeContentFilterForPortal(expanded);
9039
- // pass auth forward
9040
- if (options.authentication) {
9041
- so.authentication = options.authentication;
9042
- }
9043
- // Aggregations
9044
- if ((_a = options.aggregations) === null || _a === void 0 ? void 0 : _a.length) {
9045
- so.countFields = options.aggregations.join(",");
9046
- so.countSize = 200;
9047
- }
9048
- // copy over various options
9049
- // TODO: Dry this up
9050
- if (options.num) {
9051
- so.num = options.num;
9052
- }
9053
- if (options.sortField) {
9054
- so.sortField = options.sortField;
9055
- }
9056
- if (options.sortOrder) {
9057
- so.sortOrder = options.sortOrder;
9058
- }
9059
- // NOTE: I think we will end up setting
9060
- // the site URL in mergeSearchResults() instead
9061
- // since it applies to both items and datasets
9062
- return searchPortal(so, options.site);
9063
- }
9064
- else {
9065
- // Hub API Search
9066
- // TODO: Implement hub api content search
9067
- return Promise.resolve({
9068
- total: 0,
9069
- results: [],
9070
- facets: [],
9071
- });
9072
- }
9073
- });
9074
- return [4 /*yield*/, Promise.all(searchPromises)];
9075
- case 1:
9076
- results = _a.sent();
9077
- // merge and return
9078
- 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);
9079
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];
9080
9274
  });
9081
9275
  });
9082
9276
  }
9083
- 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) {
9084
9286
  return searchItems(searchOptions).then(function (resp) {
9287
+ var hasNext = resp.nextStart > -1;
9085
9288
  var content = resp.results.map(itemToContent);
9086
- if (site) {
9087
- 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
+ });
9088
9293
  }
9089
9294
  // convert aggregations into facets
9090
9295
  var facets = convertPortalResponseToFacets(resp);
@@ -9092,6 +9297,8 @@
9092
9297
  total: resp.total,
9093
9298
  results: content,
9094
9299
  facets: facets,
9300
+ hasNext: hasNext,
9301
+ next: getNextFunction(searchOptions, resp.nextStart, resp.total, searchPortal),
9095
9302
  };
9096
9303
  });
9097
9304
  }
@@ -9107,63 +9314,168 @@
9107
9314
  function _searchGroups(filter, options) {
9108
9315
  var _a;
9109
9316
  return __awaiter(this, void 0, void 0, function () {
9110
- var expanded, apis, so, token, us, portalUrl, thumbnailify, teamLinkify;
9317
+ var expanded, api, so;
9111
9318
  return __generator(this, function (_b) {
9112
9319
  expanded = expandGroupFilter(filter);
9113
- // APIs
9114
- if (!options.apis) {
9115
- // default to AGO PROD
9116
- options.apis = ["arcgis"];
9117
- }
9118
- apis = expandApis(options.apis);
9119
- so = serializeGroupFilterForPortal(expanded);
9120
- token = "";
9121
- // if we have auth, pass it forward
9122
- // otherwise set the portal property
9123
- if (options.authentication) {
9124
- so.authentication = options.authentication;
9125
- us = options.authentication;
9126
- 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)];
9127
9349
  }
9128
9350
  else {
9129
- 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.");
9130
9415
  }
9131
- if (options.num) {
9132
- 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)];
9133
9436
  }
9134
- portalUrl = "https://www.arcgis.com/sharing/rest";
9135
- if ((_a = so.authentication) === null || _a === void 0 ? void 0 : _a.portal) {
9136
- portalUrl = so.authentication.portal;
9437
+ else {
9438
+ throw new Error("_searchUsers is not implemented for non-arcgis apis");
9137
9439
  }
9138
- thumbnailify = function (group) {
9139
- return addThumbnailUrl(portalUrl, group, token);
9140
- };
9141
- teamLinkify = function (group) {
9142
- group.siteTeamUrl = options.site.item.url + "/teams/" + group.id + "/about";
9143
- return group;
9144
- };
9145
- return [2 /*return*/, searchGroups(so).then(function (response) {
9146
- var _a, _b;
9147
- // upgrade thumbnail url
9148
- response.results = response.results.map(thumbnailify);
9149
- // generate the site team url if site url is provided
9150
- if ((_b = (_a = options.site) === null || _a === void 0 ? void 0 : _a.item) === null || _b === void 0 ? void 0 : _b.url) {
9151
- response.results = response.results.map(teamLinkify);
9152
- }
9153
- return response;
9154
- })];
9155
9440
  });
9156
9441
  });
9157
9442
  }
9158
- // Need to decide how to handle adding the token is group is not public
9159
- function addThumbnailUrl(portalUrl, group, token) {
9160
- if (group.thumbnail) {
9161
- group.thumbnailUrl = portalUrl + "/community/groups/" + group.id + "/info/" + group.thumbnail;
9162
- if (token) {
9163
- 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);
9164
9460
  }
9165
- }
9166
- 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
+ });
9167
9479
  }
9168
9480
 
9169
9481
  /**
@@ -9772,6 +10084,9 @@
9772
10084
  model = _purgeNonGuidsFromCatalog(model);
9773
10085
  model = _ensureTelemetry(model);
9774
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.
9775
10090
  return model;
9776
10091
  }
9777
10092
  }
@@ -10408,6 +10723,7 @@
10408
10723
  exports._processSecondaryEmail = _processSecondaryEmail;
10409
10724
  exports._searchContent = _searchContent;
10410
10725
  exports._searchGroups = _searchGroups;
10726
+ exports._searchUsers = _searchUsers;
10411
10727
  exports._unprotectAndRemoveGroup = _unprotectAndRemoveGroup;
10412
10728
  exports._unprotectAndRemoveItem = _unprotectAndRemoveItem;
10413
10729
  exports.addContextToSlug = addContextToSlug;
@@ -10457,10 +10773,12 @@
10457
10773
  exports.ensureProp = ensureProp;
10458
10774
  exports.ensureUniqueDomainName = ensureUniqueDomainName;
10459
10775
  exports.ensureUniqueString = ensureUniqueString;
10776
+ exports.expandApi = expandApi;
10460
10777
  exports.expandApis = expandApis;
10461
10778
  exports.expandContentFilter = expandContentFilter;
10462
10779
  exports.expandGroupFilter = expandGroupFilter;
10463
10780
  exports.expandTypeField = expandTypeField;
10781
+ exports.expandUserFilter = expandUserFilter;
10464
10782
  exports.extend = extend;
10465
10783
  exports.extentToBBox = extentToBBox;
10466
10784
  exports.failSafe = failSafe;
@@ -10478,12 +10796,14 @@
10478
10796
  exports.getCategory = getCategory;
10479
10797
  exports.getCollection = getCollection;
10480
10798
  exports.getContentIdentifier = getContentIdentifier;
10799
+ exports.getContentSiteUrls = getContentSiteUrls;
10481
10800
  exports.getCulture = getCulture;
10482
10801
  exports.getDomainsForSite = getDomainsForSite;
10483
10802
  exports.getExportItemTypeKeyword = getExportItemTypeKeyword;
10484
10803
  exports.getExportLayerTypeKeyword = getExportLayerTypeKeyword;
10485
10804
  exports.getFamily = getFamily;
10486
10805
  exports.getGeographicOrgExtent = getGeographicOrgExtent;
10806
+ exports.getGroupThumbnailUrl = getGroupThumbnailUrl;
10487
10807
  exports.getHubApiUrl = getHubApiUrl;
10488
10808
  exports.getHubApiUrlFromPortal = getHubApiUrlFromPortal;
10489
10809
  exports.getHubLocaleAssetUrl = getHubLocaleAssetUrl;
@@ -10501,6 +10821,7 @@
10501
10821
  exports.getLayerIdFromUrl = getLayerIdFromUrl;
10502
10822
  exports.getModel = getModel;
10503
10823
  exports.getModelFromOptions = getModelFromOptions;
10824
+ exports.getNextFunction = getNextFunction;
10504
10825
  exports.getOrgExtentAsBBox = getOrgExtentAsBBox;
10505
10826
  exports.getPortalApiUrl = getPortalApiUrl;
10506
10827
  exports.getPortalUrl = getPortalUrl;
@@ -10519,6 +10840,7 @@
10519
10840
  exports.getUniqueDomainName = getUniqueDomainName;
10520
10841
  exports.getUniqueDomainNamePortal = getUniqueDomainNamePortal;
10521
10842
  exports.getUniqueItemTitle = getUniqueItemTitle;
10843
+ exports.getUserThumbnailUrl = getUserThumbnailUrl;
10522
10844
  exports.getWithDefault = getWithDefault$1;
10523
10845
  exports.hasBasePriv = hasBasePriv;
10524
10846
  exports.hubApiRequest = hubApiRequest;
@@ -10554,7 +10876,7 @@
10554
10876
  exports.mergeMatchOptions = mergeMatchOptions;
10555
10877
  exports.mergeObjects = mergeObjects;
10556
10878
  exports.mergeSearchOptions = mergeSearchOptions;
10557
- exports.mergeSearchResults = mergeSearchResults;
10879
+ exports.mergeUserFilters = mergeUserFilters;
10558
10880
  exports.normalizeItemType = normalizeItemType;
10559
10881
  exports.normalizeSolutionTemplateItem = normalizeSolutionTemplateItem;
10560
10882
  exports.objectToArray = objectToArray;
@@ -10576,6 +10898,7 @@
10576
10898
  exports.serializeModel = serializeModel;
10577
10899
  exports.serializeSpatialReference = serializeSpatialReference;
10578
10900
  exports.serializeStringOrArray = serializeStringOrArray;
10901
+ exports.serializeUserFilterForPortal = serializeUserFilterForPortal;
10579
10902
  exports.setContentHubId = setContentHubId;
10580
10903
  exports.setContentSiteUrls = setContentSiteUrls;
10581
10904
  exports.setContentType = setContentType;