@esri/hub-common 9.20.0 → 9.21.2

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 (57) hide show
  1. package/dist/es2017/content/_internal.js +70 -0
  2. package/dist/es2017/content/_internal.js.map +1 -1
  3. package/dist/es2017/content/compose.js +6 -1
  4. package/dist/es2017/content/compose.js.map +1 -1
  5. package/dist/es2017/content/index.js +11 -1
  6. package/dist/es2017/content/index.js.map +1 -1
  7. package/dist/es2017/core/types/IHubAdditionalResource.js +1 -0
  8. package/dist/es2017/core/types/IHubAdditionalResource.js.map +1 -0
  9. package/dist/es2017/projects/HubProjects.js +17 -18
  10. package/dist/es2017/projects/HubProjects.js.map +1 -1
  11. package/dist/es2017/search/_searchContent.js +18 -20
  12. package/dist/es2017/search/_searchContent.js.map +1 -1
  13. package/dist/es2017/search/_searchGroups.js +18 -19
  14. package/dist/es2017/search/_searchGroups.js.map +1 -1
  15. package/dist/es2017/search/_searchUsers.js +16 -16
  16. package/dist/es2017/search/_searchUsers.js.map +1 -1
  17. package/dist/esm/content/_internal.js +70 -0
  18. package/dist/esm/content/_internal.js.map +1 -1
  19. package/dist/esm/content/compose.js +6 -1
  20. package/dist/esm/content/compose.js.map +1 -1
  21. package/dist/esm/content/index.js +11 -1
  22. package/dist/esm/content/index.js.map +1 -1
  23. package/dist/esm/core/types/IHubAdditionalResource.js +1 -0
  24. package/dist/esm/core/types/IHubAdditionalResource.js.map +1 -0
  25. package/dist/esm/projects/HubProjects.js +16 -19
  26. package/dist/esm/projects/HubProjects.js.map +1 -1
  27. package/dist/esm/search/_searchContent.js +22 -26
  28. package/dist/esm/search/_searchContent.js.map +1 -1
  29. package/dist/esm/search/_searchGroups.js +20 -23
  30. package/dist/esm/search/_searchGroups.js.map +1 -1
  31. package/dist/esm/search/_searchUsers.js +17 -19
  32. package/dist/esm/search/_searchUsers.js.map +1 -1
  33. package/dist/node/content/_internal.js +71 -1
  34. package/dist/node/content/_internal.js.map +1 -1
  35. package/dist/node/content/compose.js +5 -0
  36. package/dist/node/content/compose.js.map +1 -1
  37. package/dist/node/content/index.js +11 -1
  38. package/dist/node/content/index.js.map +1 -1
  39. package/dist/node/core/types/IHubAdditionalResource.js +3 -0
  40. package/dist/node/core/types/IHubAdditionalResource.js.map +1 -0
  41. package/dist/node/projects/HubProjects.js +17 -18
  42. package/dist/node/projects/HubProjects.js.map +1 -1
  43. package/dist/node/search/_searchContent.js +17 -19
  44. package/dist/node/search/_searchContent.js.map +1 -1
  45. package/dist/node/search/_searchGroups.js +17 -18
  46. package/dist/node/search/_searchGroups.js.map +1 -1
  47. package/dist/node/search/_searchUsers.js +15 -15
  48. package/dist/node/search/_searchUsers.js.map +1 -1
  49. package/dist/types/content/_internal.d.ts +44 -0
  50. package/dist/types/core/types/IHubAdditionalResource.d.ts +10 -0
  51. package/dist/types/core/types/IHubContent.d.ts +5 -1
  52. package/dist/types/projects/HubProjects.d.ts +1 -1
  53. package/dist/umd/common.umd.js +163 -102
  54. package/dist/umd/common.umd.js.map +1 -1
  55. package/dist/umd/common.umd.min.js +1 -1
  56. package/dist/umd/common.umd.min.js.map +1 -1
  57. package/package.json +1 -1
@@ -13,6 +13,7 @@ import { IItem } from "@esri/arcgis-rest-portal";
13
13
  import { ISpatialReference } from "@esri/arcgis-rest-types";
14
14
  import { IHubContent } from "../core";
15
15
  import { IHubGeography, GeographyProvenance, IHubRequestOptions } from "../types";
16
+ import { IHubAdditionalResource } from "../core/types/IHubAdditionalResource";
16
17
  /**
17
18
  * Create a new content with updated boundary properties
18
19
  * @param content original content
@@ -65,6 +66,7 @@ export declare const setContentBoundary: (content: IHubContent, boundary: Geogra
65
66
  hubActions?: object;
66
67
  layer?: Partial<ILayerDefinition>;
67
68
  isProxied?: boolean;
69
+ additionalResources?: IHubAdditionalResource[];
68
70
  itemCategories?: string[];
69
71
  normalizedType?: string;
70
72
  orgId?: string;
@@ -152,3 +154,45 @@ export declare function parseISODateString(isoString: string): {
152
154
  };
153
155
  export declare const getServerSpatialReference: (server: Partial<IFeatureServiceDefinition>, layer?: ILayerDefinition) => ISpatialReference;
154
156
  export declare const getItemSpatialReference: (item: IItem) => ISpatialReference;
157
+ /**
158
+ * Data model for additional resources that are extracted
159
+ * directly from formal item metadata (with no transformation)
160
+ */
161
+ interface IAGOAdditionalResource {
162
+ orName?: string;
163
+ linkage: string;
164
+ }
165
+ /**
166
+ * Extracts additional resources from the provided metadata
167
+ * and transforms them into a hub-friendly format.
168
+ *
169
+ * Returns null if no resources are available
170
+ *
171
+ * @param item
172
+ * @param metadata formal metadata
173
+ * @returns
174
+ */
175
+ export declare const getAdditionalResources: (item: IItem, metadata?: any, requestOptions?: IHubRequestOptions) => IHubAdditionalResource[];
176
+ /**
177
+ * Determines whether a raw additional resource (i.e. extracted out of formal
178
+ * metadata with no transformation) references the underlying service that backs
179
+ * the item.
180
+ *
181
+ * @param resource raw additional resource of an item
182
+ * @param item
183
+ * @returns
184
+ */
185
+ export declare const isDataSourceOfItem: (resource: IAGOAdditionalResource, item: IItem) => boolean;
186
+ /**
187
+ * Returns the url for an additional resource.
188
+ *
189
+ * Automatically appends auth token if token is available
190
+ * and resource points to the backing service of an item.
191
+ *
192
+ * @param resource raw additional resource of an item
193
+ * @param item
194
+ * @param requestOptions IHubRequestOptions, including authentication
195
+ * @returns
196
+ */
197
+ export declare const getAdditionalResourceUrl: (resource: IAGOAdditionalResource, item: IItem, requestOptions?: IHubRequestOptions) => string;
198
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Data model for additional resources that are pulled from formal item metadata
3
+ * and transformed into a hub-friendly interface
4
+ */
5
+ export interface IHubAdditionalResource {
6
+ name?: string;
7
+ url: string;
8
+ /** whether the url points to the service of the related item */
9
+ isDataSource: boolean;
10
+ }
@@ -1,8 +1,10 @@
1
1
  import { IItem, IGroup } from "@esri/arcgis-rest-portal";
2
2
  import { ILayerDefinition } from "@esri/arcgis-rest-feature-layer";
3
- import { Visibility, AccessControl, HubFamily, IActionLink, IStructuredLicense } from "../..";
3
+ import { AccessControl, HubFamily, IActionLink, Visibility } from "../../types";
4
+ import { IStructuredLicense } from "../../items/get-structured-license";
4
5
  import { IHubItemEntity } from ".";
5
6
  import { IHubContentEnrichments } from "./IHubContentEnrichments";
7
+ import { IHubAdditionalResource } from "./IHubAdditionalResource";
6
8
  /**
7
9
  * Data model for content
8
10
  */
@@ -73,6 +75,8 @@ export interface IHubContent extends IHubItemEntity, IHubContentEnrichments, IIt
73
75
  layer?: Partial<ILayerDefinition>;
74
76
  /** Whether or not the layer or table is actually a proxied CSV */
75
77
  isProxied?: boolean;
78
+ /** links to additional resources specified in the formal item metadata */
79
+ additionalResources?: IHubAdditionalResource[];
76
80
  itemCategories?: string[];
77
81
  normalizedType?: string;
78
82
  orgId?: string;
@@ -2,7 +2,7 @@ import { IUserRequestOptions } from "@esri/arcgis-rest-auth";
2
2
  import { Filter, IHubSearchOptions, ISearchResponse } from "..";
3
3
  import { IRequestOptions } from "@esri/arcgis-rest-request";
4
4
  import { IHubProject } from "../core/types";
5
- export declare const HUB_PROJECT_ITEM_TYPE = "Web Mapping Application";
5
+ export declare const HUB_PROJECT_ITEM_TYPE = "Hub Project";
6
6
  /**
7
7
  * Create a new Hub Project item
8
8
  *
@@ -1,5 +1,5 @@
1
1
  /* @preserve
2
- * @esri/hub-common - v9.19.0 - Fri Feb 25 2022 14:52:42 GMT+0000 (Coordinated Universal Time)
2
+ * @esri/hub-common - v9.21.1 - Mon Feb 28 2022 23:32:15 GMT+0000 (Coordinated Universal Time)
3
3
  * Copyright (c) 2022 Environmental Systems Research Institute, Inc.
4
4
  * Apache-2.0
5
5
  */
@@ -6105,6 +6105,26 @@
6105
6105
  };
6106
6106
  };
6107
6107
 
6108
+ /* Copyright (c) 2017-2019 Environmental Systems Research Institute, Inc.
6109
+ * Apache-2.0 */
6110
+ var serviceRegex = new RegExp(/.+(?:map|feature|image)server/i);
6111
+ /**
6112
+ * Return the service url. If not matched, returns what was passed in
6113
+ */
6114
+ function parseServiceUrl(url) {
6115
+ var match = url.match(serviceRegex);
6116
+ if (match) {
6117
+ return match[0];
6118
+ }
6119
+ else {
6120
+ return stripQueryString(url);
6121
+ }
6122
+ }
6123
+ function stripQueryString(url) {
6124
+ var stripped = url.split('?')[0];
6125
+ return cleanUrl(stripped);
6126
+ }
6127
+
6108
6128
  // private helper functions
6109
6129
  function collectionToFamily(collection) {
6110
6130
  var overrides = {
@@ -6330,26 +6350,65 @@
6330
6350
  : //
6331
6351
  { wkid: wkid };
6332
6352
  };
6333
-
6334
- /* Copyright (c) 2017-2019 Environmental Systems Research Institute, Inc.
6335
- * Apache-2.0 */
6336
- var serviceRegex = new RegExp(/.+(?:map|feature|image)server/i);
6337
6353
  /**
6338
- * Return the service url. If not matched, returns what was passed in
6354
+ * Extracts additional resources from the provided metadata
6355
+ * and transforms them into a hub-friendly format.
6356
+ *
6357
+ * Returns null if no resources are available
6358
+ *
6359
+ * @param item
6360
+ * @param metadata formal metadata
6361
+ * @returns
6339
6362
  */
6340
- function parseServiceUrl(url) {
6341
- var match = url.match(serviceRegex);
6342
- if (match) {
6343
- return match[0];
6363
+ var getAdditionalResources = function (item, metadata, requestOptions) {
6364
+ var rawResources = getProp(metadata, "metadata.distInfo.distTranOps.onLineSrc") || null;
6365
+ if (rawResources === null) {
6366
+ return null;
6344
6367
  }
6345
- else {
6346
- return stripQueryString(url);
6368
+ // Coerce to array since rawResources will be an object if only 1 resource is available
6369
+ rawResources = Array.isArray(rawResources) ? rawResources : [rawResources];
6370
+ return rawResources.map(function (resource) { return ({
6371
+ name: resource.orName,
6372
+ url: getAdditionalResourceUrl(resource, item, requestOptions),
6373
+ isDataSource: isDataSourceOfItem(resource, item),
6374
+ }); });
6375
+ };
6376
+ /**
6377
+ * Determines whether a raw additional resource (i.e. extracted out of formal
6378
+ * metadata with no transformation) references the underlying service that backs
6379
+ * the item.
6380
+ *
6381
+ * @param resource raw additional resource of an item
6382
+ * @param item
6383
+ * @returns
6384
+ */
6385
+ var isDataSourceOfItem = function (resource, item) {
6386
+ var serviceUrl = item.url && parseServiceUrl(item.url);
6387
+ return serviceUrl && resource.linkage.includes(serviceUrl);
6388
+ };
6389
+ /**
6390
+ * Returns the url for an additional resource.
6391
+ *
6392
+ * Automatically appends auth token if token is available
6393
+ * and resource points to the backing service of an item.
6394
+ *
6395
+ * @param resource raw additional resource of an item
6396
+ * @param item
6397
+ * @param requestOptions IHubRequestOptions, including authentication
6398
+ * @returns
6399
+ */
6400
+ var getAdditionalResourceUrl = function (resource, item, requestOptions) {
6401
+ var result = resource.linkage;
6402
+ var token = getProp(requestOptions, "authentication.token");
6403
+ if (token && isDataSourceOfItem(resource, item)) {
6404
+ var resUrl = new URL(resource.linkage);
6405
+ var params = new URLSearchParams(resUrl.search);
6406
+ params.set("token", token);
6407
+ resUrl.search = params.toString();
6408
+ result = resUrl.toString();
6347
6409
  }
6348
- }
6349
- function stripQueryString(url) {
6350
- var stripped = url.split('?')[0];
6351
- return cleanUrl(stripped);
6352
- }
6410
+ return result;
6411
+ };
6353
6412
 
6354
6413
  var STANDARD_LICENSES = [
6355
6414
  {
@@ -7152,6 +7211,8 @@
7152
7211
  control: item.itemControl || "view",
7153
7212
  };
7154
7213
  },
7214
+ // TODO: do we want to add dataset extent logic as a getter here?
7215
+ // would require us to do client-side projection of server/layer extent
7155
7216
  get boundary() {
7156
7217
  // TODO: need to be able to handle automatic w/ additional enrichment
7157
7218
  // that could for example fetch the concave hull from the Hub API or resources
@@ -7259,6 +7320,9 @@
7259
7320
  console.warn("DEPRECATED: use family instead");
7260
7321
  /* tslint:enable no-console */
7261
7322
  return getFamily(type);
7323
+ },
7324
+ get additionalResources() {
7325
+ return getAdditionalResources(item, metadata);
7262
7326
  } });
7263
7327
  };
7264
7328
 
@@ -7483,7 +7547,7 @@
7483
7547
  // map and feature server enrichments
7484
7548
  server = _a.server, layers = _a.layers, layer = _a.layer, recordCount = _a.recordCount, statistics = _a.statistics,
7485
7549
  // additional attributes needed
7486
- searchDescription = _a.searchDescription;
7550
+ extent = _a.extent; _a.itemExtent; var searchDescription = _a.searchDescription;
7487
7551
  // get the layerId from the layer
7488
7552
  var layerId = layer && layer.id;
7489
7553
  // re-assemble the org as an enrichment
@@ -7508,10 +7572,19 @@
7508
7572
  statistics: statistics,
7509
7573
  });
7510
7574
  // TODO: need to add searchDescription logic to composeContent()
7575
+ // or fetch it as a Hub enrichment like boundary
7511
7576
  if (searchDescription) {
7512
7577
  // overwrite default summary (from snippet) w/ search description
7513
7578
  content.summary = searchDescription;
7514
7579
  }
7580
+ // TODO: need to add extent logic to composeContent()
7581
+ // or fetch it as a Hub enrichment like boundary
7582
+ if (!isBBox(item.extent) && extent && isBBox(extent.coordinates)) {
7583
+ // we fall back to the extent derived by the API
7584
+ // which prefers layer or service extents and ultimately
7585
+ // falls back to the org's extent
7586
+ content.extent = extent.coordinates;
7587
+ }
7515
7588
  return content;
7516
7589
  }
7517
7590
  /**
@@ -9710,14 +9783,14 @@
9710
9783
  return clone;
9711
9784
  }
9712
9785
 
9713
- var HUB_PROJECT_ITEM_TYPE = "Web Mapping Application";
9786
+ var HUB_PROJECT_ITEM_TYPE = "Hub Project";
9714
9787
  /**
9715
9788
  * Default values of a IHubProject
9716
9789
  */
9717
9790
  var DEFAULT_PROJECT = {
9718
9791
  name: "No title provided",
9719
9792
  tags: [],
9720
- typeKeywords: ["IHubProject", "HubProject"],
9793
+ typeKeywords: ["Hub Project"],
9721
9794
  status: "inactive",
9722
9795
  };
9723
9796
  /**
@@ -9927,7 +10000,7 @@
9927
10000
  function searchProjects(filter, options) {
9928
10001
  var _a;
9929
10002
  return __awaiter(this, void 0, void 0, function () {
9930
- var scopingFilter, projectFilter, expanded, so;
10003
+ var scopingFilter, projectFilter, expanded, so, props;
9931
10004
  return __generator(this, function (_b) {
9932
10005
  scopingFilter = {
9933
10006
  filterType: "content",
@@ -9943,22 +10016,19 @@
9943
10016
  so.countFields = options.aggregations.join(",");
9944
10017
  so.countSize = 200;
9945
10018
  }
9946
- // copy over various options
9947
- if (options.num) {
9948
- so.num = options.num;
9949
- }
9950
- if (options.sortField) {
9951
- so.sortField = options.sortField;
9952
- }
9953
- if (options.sortOrder) {
9954
- so.sortOrder = options.sortOrder;
9955
- }
9956
- if (options.site) {
9957
- so.site = cloneObject$1(options.site);
9958
- }
9959
- if (options.authentication) {
9960
- so.authentication = options.authentication;
9961
- }
10019
+ props = [
10020
+ "authentication",
10021
+ "num",
10022
+ "sortField",
10023
+ "sortOrder",
10024
+ "site",
10025
+ ];
10026
+ // copy the props over
10027
+ props.forEach(function (prop) {
10028
+ if (options.hasOwnProperty(prop)) {
10029
+ so[prop] = options[prop];
10030
+ }
10031
+ });
9962
10032
  return [2 /*return*/, searchPortalProjects(so)];
9963
10033
  });
9964
10034
  });
@@ -11603,40 +11673,36 @@
11603
11673
  function _searchContent(filter, options) {
11604
11674
  var _a;
11605
11675
  return __awaiter(this, void 0, void 0, function () {
11606
- var expanded, api, searchPromise, so;
11676
+ var expanded, api, searchPromise, so_1, props;
11607
11677
  return __generator(this, function (_b) {
11608
11678
  expanded = expandContentFilter(filter);
11609
11679
  api = expandApi(options.api || "arcgis");
11610
11680
  // Portal Search
11611
11681
  if (api.type === "arcgis") {
11612
- so = serializeContentFilterForPortal(expanded);
11613
- // if we have auth, pass it forward
11614
- // otherwise set the portal property
11615
- if (options.authentication) {
11616
- so.authentication = options.authentication;
11617
- }
11618
- else {
11619
- so.portal = api.url + "/sharing/rest";
11682
+ so_1 = serializeContentFilterForPortal(expanded);
11683
+ props = [
11684
+ "authentication",
11685
+ "num",
11686
+ "sortField",
11687
+ "sortOrder",
11688
+ "site",
11689
+ ];
11690
+ // copy the props over
11691
+ props.forEach(function (prop) {
11692
+ if (options.hasOwnProperty(prop)) {
11693
+ so_1[prop] = options[prop];
11694
+ }
11695
+ });
11696
+ // If we don't have auth, ensure we have .portal
11697
+ if (!so_1.authentication) {
11698
+ so_1.portal = api.url + "/sharing/rest";
11620
11699
  }
11621
11700
  // Aggregations
11622
11701
  if ((_a = options.aggregations) === null || _a === void 0 ? void 0 : _a.length) {
11623
- so.countFields = options.aggregations.join(",");
11624
- so.countSize = 200;
11625
- }
11626
- // copy over various options
11627
- if (options.num) {
11628
- so.num = options.num;
11629
- }
11630
- if (options.sortField) {
11631
- so.sortField = options.sortField;
11632
- }
11633
- if (options.sortOrder) {
11634
- so.sortOrder = options.sortOrder;
11702
+ so_1.countFields = options.aggregations.join(",");
11703
+ so_1.countSize = 200;
11635
11704
  }
11636
- if (options.site) {
11637
- so.site = cloneObject$1(options.site);
11638
- }
11639
- searchPromise = searchPortal(so);
11705
+ searchPromise = searchPortal(so_1);
11640
11706
  }
11641
11707
  else {
11642
11708
  // Hub API Search
@@ -11708,33 +11774,30 @@
11708
11774
  */
11709
11775
  function _searchGroups(filter, options) {
11710
11776
  return __awaiter(this, void 0, void 0, function () {
11711
- var expanded, api, so;
11777
+ var expanded, api, so_1, props;
11712
11778
  return __generator(this, function (_a) {
11713
11779
  expanded = expandGroupFilter(filter);
11714
11780
  api = expandApi(options.api || "arcgis");
11715
11781
  if (api.type === "arcgis") {
11716
- so = serializeGroupFilterForPortal(expanded);
11717
- // if we have auth, pass it forward
11718
- // otherwise set the portal property
11719
- if (options.authentication) {
11720
- so.authentication = options.authentication;
11721
- }
11722
- else {
11723
- so.portal = api.url + "/sharing/rest";
11724
- }
11725
- if (options.num) {
11726
- so.num = options.num;
11727
- }
11728
- if (options.sortField) {
11729
- so.sortField = options.sortField;
11730
- }
11731
- if (options.sortOrder) {
11732
- so.sortOrder = options.sortOrder;
11733
- }
11734
- if (options.site) {
11735
- so.site = cloneObject$1(options.site);
11782
+ so_1 = serializeGroupFilterForPortal(expanded);
11783
+ props = [
11784
+ "authentication",
11785
+ "num",
11786
+ "sortField",
11787
+ "sortOrder",
11788
+ "site",
11789
+ ];
11790
+ // copy the props over
11791
+ props.forEach(function (prop) {
11792
+ if (options.hasOwnProperty(prop)) {
11793
+ so_1[prop] = options[prop];
11794
+ }
11795
+ });
11796
+ // If we don't have auth, ensure we have .portal
11797
+ if (!so_1.authentication) {
11798
+ so_1.portal = api.url + "/sharing/rest";
11736
11799
  }
11737
- return [2 /*return*/, searchPortalGroups(so)];
11800
+ return [2 /*return*/, searchPortalGroups(so_1)];
11738
11801
  }
11739
11802
  else {
11740
11803
  throw new Error("_searchGroups is not implemented for non-arcgis apis");
@@ -11795,7 +11858,7 @@
11795
11858
  */
11796
11859
  function _searchUsers(filter, options) {
11797
11860
  return __awaiter(this, void 0, void 0, function () {
11798
- var expanded, api, searchOptions;
11861
+ var expanded, api, searchOptions_1, props;
11799
11862
  return __generator(this, function (_a) {
11800
11863
  // JS Clients may not pass in authentication
11801
11864
  if (!options.authentication) {
@@ -11804,23 +11867,21 @@
11804
11867
  expanded = expandUserFilter(filter);
11805
11868
  api = expandApi(options.api || "arcgis");
11806
11869
  if (api.type === "arcgis") {
11807
- searchOptions = serializeUserFilterForPortal(expanded);
11808
- // carry the auth forward
11809
- searchOptions.authentication = options.authentication;
11810
- // TODO: Dry this up - typscript makes this... inconvenient
11811
- if (options.num) {
11812
- searchOptions.num = options.num;
11813
- }
11814
- if (options.sortField) {
11815
- searchOptions.sortField = options.sortField;
11816
- }
11817
- if (options.sortOrder) {
11818
- searchOptions.sortOrder = options.sortOrder;
11819
- }
11820
- if (options.site) {
11821
- searchOptions.site = cloneObject$1(options.site);
11822
- }
11823
- return [2 /*return*/, searchPortalUsers(searchOptions)];
11870
+ searchOptions_1 = serializeUserFilterForPortal(expanded);
11871
+ props = [
11872
+ "authentication",
11873
+ "num",
11874
+ "sortField",
11875
+ "sortOrder",
11876
+ "site",
11877
+ ];
11878
+ // copy the props over
11879
+ props.forEach(function (prop) {
11880
+ if (options.hasOwnProperty(prop)) {
11881
+ searchOptions_1[prop] = options[prop];
11882
+ }
11883
+ });
11884
+ return [2 /*return*/, searchPortalUsers(searchOptions_1)];
11824
11885
  }
11825
11886
  else {
11826
11887
  throw new Error("_searchUsers is not implemented for non-arcgis apis");