@esri/hub-common 9.18.0 → 9.21.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 (106) hide show
  1. package/dist/es2017/content/_internal.js +211 -20
  2. package/dist/es2017/content/_internal.js.map +1 -1
  3. package/dist/es2017/content/compose.js +610 -0
  4. package/dist/es2017/content/compose.js.map +1 -0
  5. package/dist/es2017/content/get-family.js +42 -0
  6. package/dist/es2017/content/get-family.js.map +1 -0
  7. package/dist/es2017/content/index.js +42 -468
  8. package/dist/es2017/content/index.js.map +1 -1
  9. package/dist/es2017/core/types/IHubAdditionalResource.js +1 -0
  10. package/dist/es2017/core/types/IHubAdditionalResource.js.map +1 -0
  11. package/dist/es2017/core/types/IHubContentEnrichments.js +1 -0
  12. package/dist/es2017/core/types/IHubContentEnrichments.js.map +1 -0
  13. package/dist/es2017/core/types/IServerEnrichments.js +1 -0
  14. package/dist/es2017/core/types/IServerEnrichments.js.map +1 -0
  15. package/dist/es2017/core/types/index.js +2 -1
  16. package/dist/es2017/core/types/index.js.map +1 -1
  17. package/dist/es2017/projects/HubProjects.js +15 -16
  18. package/dist/es2017/projects/HubProjects.js.map +1 -1
  19. package/dist/es2017/search/_searchContent.js +18 -20
  20. package/dist/es2017/search/_searchContent.js.map +1 -1
  21. package/dist/es2017/search/_searchGroups.js +18 -19
  22. package/dist/es2017/search/_searchGroups.js.map +1 -1
  23. package/dist/es2017/search/_searchUsers.js +16 -16
  24. package/dist/es2017/search/_searchUsers.js.map +1 -1
  25. package/dist/es2017/sites/domains/index.js +1 -0
  26. package/dist/es2017/sites/domains/index.js.map +1 -1
  27. package/dist/es2017/sites/domains/remove-domains-by-site-id.js +20 -0
  28. package/dist/es2017/sites/domains/remove-domains-by-site-id.js.map +1 -0
  29. package/dist/esm/content/_internal.js +214 -21
  30. package/dist/esm/content/_internal.js.map +1 -1
  31. package/dist/esm/content/compose.js +603 -0
  32. package/dist/esm/content/compose.js.map +1 -0
  33. package/dist/esm/content/get-family.js +42 -0
  34. package/dist/esm/content/get-family.js.map +1 -0
  35. package/dist/esm/content/index.js +44 -476
  36. package/dist/esm/content/index.js.map +1 -1
  37. package/dist/esm/core/types/IHubAdditionalResource.js +1 -0
  38. package/dist/esm/core/types/IHubAdditionalResource.js.map +1 -0
  39. package/dist/esm/core/types/IHubContentEnrichments.js +1 -0
  40. package/dist/esm/core/types/IHubContentEnrichments.js.map +1 -0
  41. package/dist/esm/core/types/IServerEnrichments.js +1 -0
  42. package/dist/esm/core/types/IServerEnrichments.js.map +1 -0
  43. package/dist/esm/core/types/index.js +2 -1
  44. package/dist/esm/core/types/index.js.map +1 -1
  45. package/dist/esm/projects/HubProjects.js +14 -17
  46. package/dist/esm/projects/HubProjects.js.map +1 -1
  47. package/dist/esm/search/_searchContent.js +22 -26
  48. package/dist/esm/search/_searchContent.js.map +1 -1
  49. package/dist/esm/search/_searchGroups.js +20 -23
  50. package/dist/esm/search/_searchGroups.js.map +1 -1
  51. package/dist/esm/search/_searchUsers.js +17 -19
  52. package/dist/esm/search/_searchUsers.js.map +1 -1
  53. package/dist/esm/sites/domains/index.js +1 -0
  54. package/dist/esm/sites/domains/index.js.map +1 -1
  55. package/dist/esm/sites/domains/remove-domains-by-site-id.js +20 -0
  56. package/dist/esm/sites/domains/remove-domains-by-site-id.js.map +1 -0
  57. package/dist/node/content/_internal.js +216 -22
  58. package/dist/node/content/_internal.js.map +1 -1
  59. package/dist/node/content/compose.js +615 -0
  60. package/dist/node/content/compose.js.map +1 -0
  61. package/dist/node/content/get-family.js +46 -0
  62. package/dist/node/content/get-family.js.map +1 -0
  63. package/dist/node/content/index.js +48 -477
  64. package/dist/node/content/index.js.map +1 -1
  65. package/dist/node/core/types/IHubAdditionalResource.js +3 -0
  66. package/dist/node/core/types/IHubAdditionalResource.js.map +1 -0
  67. package/dist/node/core/types/IHubContentEnrichments.js +3 -0
  68. package/dist/node/core/types/IHubContentEnrichments.js.map +1 -0
  69. package/dist/node/core/types/{IContentEnrichments.js → IServerEnrichments.js} +1 -1
  70. package/dist/node/core/types/IServerEnrichments.js.map +1 -0
  71. package/dist/node/core/types/index.js +2 -1
  72. package/dist/node/core/types/index.js.map +1 -1
  73. package/dist/node/projects/HubProjects.js +15 -16
  74. package/dist/node/projects/HubProjects.js.map +1 -1
  75. package/dist/node/search/_searchContent.js +17 -19
  76. package/dist/node/search/_searchContent.js.map +1 -1
  77. package/dist/node/search/_searchGroups.js +17 -18
  78. package/dist/node/search/_searchGroups.js.map +1 -1
  79. package/dist/node/search/_searchUsers.js +15 -15
  80. package/dist/node/search/_searchUsers.js.map +1 -1
  81. package/dist/node/sites/domains/index.js +1 -0
  82. package/dist/node/sites/domains/index.js.map +1 -1
  83. package/dist/node/sites/domains/remove-domains-by-site-id.js +24 -0
  84. package/dist/node/sites/domains/remove-domains-by-site-id.js.map +1 -0
  85. package/dist/types/content/_internal.d.ts +101 -22
  86. package/dist/types/content/compose.d.ts +115 -0
  87. package/dist/types/content/get-family.d.ts +7 -0
  88. package/dist/types/content/index.d.ts +4 -86
  89. package/dist/types/core/types/IHubAdditionalResource.d.ts +10 -0
  90. package/dist/types/core/types/IHubContent.d.ts +9 -3
  91. package/dist/types/core/types/IHubContentEnrichments.d.ts +15 -0
  92. package/dist/types/core/types/IHubItemEntity.d.ts +1 -1
  93. package/dist/types/core/types/{IContentEnrichments.d.ts → IServerEnrichments.d.ts} +3 -2
  94. package/dist/types/core/types/index.d.ts +2 -1
  95. package/dist/types/sites/domains/index.d.ts +1 -0
  96. package/dist/types/sites/domains/remove-domains-by-site-id.d.ts +8 -0
  97. package/dist/umd/common.umd.js +1071 -648
  98. package/dist/umd/common.umd.js.map +1 -1
  99. package/dist/umd/common.umd.min.js +1 -1
  100. package/dist/umd/common.umd.min.js.map +1 -1
  101. package/package.json +1 -1
  102. package/dist/es2017/core/types/IContentEnrichments.js +0 -1
  103. package/dist/es2017/core/types/IContentEnrichments.js.map +0 -1
  104. package/dist/esm/core/types/IContentEnrichments.js +0 -1
  105. package/dist/esm/core/types/IContentEnrichments.js.map +0 -1
  106. package/dist/node/core/types/IContentEnrichments.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /* @preserve
2
- * @esri/hub-common - v9.17.1 - Fri Feb 18 2022 21:45:18 GMT+0000 (Coordinated Universal Time)
2
+ * @esri/hub-common - v9.20.0 - Mon Feb 28 2022 15:56:25 GMT+0000 (Coordinated Universal Time)
3
3
  * Copyright (c) 2022 Environmental Systems Research Institute, Inc.
4
4
  * Apache-2.0
5
5
  */
@@ -5850,6 +5850,27 @@
5850
5850
  "Workflow Manager Package",
5851
5851
  ];
5852
5852
  var site$1 = ["Hub Site Application", "Site Application"];
5853
+ /**
5854
+ * ```js
5855
+ * import { getCollection } from "@esri/hub-common";
5856
+ * //
5857
+ * getCollection('Feature Layer')
5858
+ * > 'dataset'
5859
+ * ```
5860
+ * Get the Hub collection for a given item type
5861
+ * @param itemType The ArcGIS [item type](https://developers.arcgis.com/rest/users-groups-and-items/items-and-item-types.htm).
5862
+ * @returns the Hub collection of a given item type.
5863
+ */
5864
+ var getCollection = function (type) {
5865
+ if (!type) {
5866
+ return;
5867
+ }
5868
+ var lowerCaseType = type.toLocaleLowerCase();
5869
+ return Object.keys(collections).find(function (key) {
5870
+ var collectionTypes = collections[key];
5871
+ return collectionTypes.some(function (t) { return t.toLocaleLowerCase() === lowerCaseType; });
5872
+ });
5873
+ };
5853
5874
  // TODO: remove this at the next breaking change
5854
5875
  // it's only here to support deprecated categories
5855
5876
  var collections = {
@@ -5942,6 +5963,26 @@
5942
5963
  })));
5943
5964
  }
5944
5965
 
5966
+ /* Copyright (c) 2017-2019 Environmental Systems Research Institute, Inc.
5967
+ * Apache-2.0 */
5968
+ var serviceRegex = new RegExp(/.+(?:map|feature|image)server/i);
5969
+ /**
5970
+ * Return the service url. If not matched, returns what was passed in
5971
+ */
5972
+ function parseServiceUrl(url) {
5973
+ var match = url.match(serviceRegex);
5974
+ if (match) {
5975
+ return match[0];
5976
+ }
5977
+ else {
5978
+ return stripQueryString(url);
5979
+ }
5980
+ }
5981
+ function stripQueryString(url) {
5982
+ var stripped = url.split('?')[0];
5983
+ return cleanUrl(stripped);
5984
+ }
5985
+
5945
5986
  function createExtent(xmin, ymin, xmax, ymax, wkid) {
5946
5987
  if (wkid === void 0) { wkid = 4326; }
5947
5988
  return {
@@ -6084,6 +6125,291 @@
6084
6125
  };
6085
6126
  };
6086
6127
 
6128
+ // private helper functions
6129
+ function collectionToFamily(collection) {
6130
+ var overrides = {
6131
+ other: "content",
6132
+ solution: "template",
6133
+ };
6134
+ return overrides[collection] || collection;
6135
+ }
6136
+ /**
6137
+ * return the Hub family given an item's type
6138
+ * @param type item type
6139
+ * @returns Hub family
6140
+ */
6141
+ function getFamily(type) {
6142
+ var family;
6143
+ // override default behavior for the rows that are highlighted in yellow here:
6144
+ // https://esriis.sharepoint.com/:x:/r/sites/ArcGISHub/_layouts/15/Doc.aspx?sourcedoc=%7BADA1C9DC-4F6C-4DE4-92C6-693EF9571CFA%7D&file=Hub%20Routes.xlsx&nav=MTBfe0VENEREQzI4LUZFMDctNEI0Ri04NjcyLThCQUE2MTA0MEZGRn1fezIwMTIwMEJFLTA4MEQtNEExRC05QzA4LTE5MTAzOUQwMEE1RH0&action=default&mobileredirect=true&cid=df1c874b-c367-4cea-bc13-7bebfad3f2ac
6145
+ switch ((type || "").toLowerCase()) {
6146
+ case "image service":
6147
+ family = "dataset";
6148
+ break;
6149
+ case "feature service":
6150
+ case "raster layer":
6151
+ // TODO: check if feature service has > 1 layer first?
6152
+ family = "map";
6153
+ break;
6154
+ case "microsoft excel":
6155
+ family = "document";
6156
+ break;
6157
+ case "cad drawing":
6158
+ case "feature collection template":
6159
+ case "report template":
6160
+ family = "content";
6161
+ break;
6162
+ default:
6163
+ // by default derive from collection
6164
+ family = collectionToFamily(getCollection(type));
6165
+ }
6166
+ return family;
6167
+ }
6168
+
6169
+ // TODO: this needs to be able to handle "automatic"
6170
+ var getContentBoundary = function (item) {
6171
+ var _a;
6172
+ var extent = item.extent;
6173
+ var isValidItemExtent = isBBox(extent);
6174
+ // user specified provenance is stored in item.properties
6175
+ var provenance = ((_a = item.properties) === null || _a === void 0 ? void 0 : _a.boundary) ||
6176
+ // but we default to item if the item has an extent
6177
+ (isValidItemExtent ? "item" : undefined);
6178
+ var geometry;
6179
+ switch (provenance) {
6180
+ case "item":
6181
+ geometry = isValidItemExtent ? bBoxToPolygon(extent) : null;
6182
+ break;
6183
+ case "none":
6184
+ geometry = null;
6185
+ break;
6186
+ // TODO: handle other provenances
6187
+ }
6188
+ // TODO: derive and return center
6189
+ return {
6190
+ provenance: provenance,
6191
+ geometry: geometry,
6192
+ };
6193
+ };
6194
+ // when no request options are provided, the underlying
6195
+ // request functions assume that we are online in production
6196
+ // so we only want use enterprise logic if isPortal is explicitly defined
6197
+ var isPortal = function (requestOptions) {
6198
+ return requestOptions && requestOptions.isPortal;
6199
+ };
6200
+ /**
6201
+ * Returns whether or not an item is a proxied csv
6202
+ *
6203
+ * @param item
6204
+ * @param requestOptions Hub Request Options (including whether we're in portal)
6205
+ * @returns
6206
+ */
6207
+ var isProxiedCSV = function (item, requestOptions) {
6208
+ return !isPortal(requestOptions) &&
6209
+ item.access === "public" &&
6210
+ item.type === "CSV" &&
6211
+ item.size <= 5000000;
6212
+ };
6213
+ var getHubRelativeUrl = function (type, identifier, typeKeywords) {
6214
+ // solution types have their own logic
6215
+ var contentUrl = getSolutionUrl(type, identifier, typeKeywords);
6216
+ if (!contentUrl) {
6217
+ var family = getFamily(type);
6218
+ var familiesWithPluralizedRoute = [
6219
+ "app",
6220
+ "dataset",
6221
+ "document",
6222
+ "map",
6223
+ "template",
6224
+ ];
6225
+ // default to the catchall content route
6226
+ var path = "/content";
6227
+ if (family === "feedback") {
6228
+ // the exception
6229
+ path = "/feedback/surveys";
6230
+ }
6231
+ else if (isPageType(type)) {
6232
+ // pages are in the document family,
6233
+ // but instead of showing the page's metadata on /documents/about
6234
+ // but we render the page on the pages route
6235
+ path = "/pages";
6236
+ }
6237
+ else if (familiesWithPluralizedRoute.indexOf(family) > -1) {
6238
+ // the rule: route name is plural of family name
6239
+ path = "/" + family + "s";
6240
+ }
6241
+ contentUrl = path + "/" + identifier;
6242
+ }
6243
+ return contentUrl;
6244
+ };
6245
+ var isPageType = function (type) {
6246
+ return ["Hub Page", "Site Page"].includes(type);
6247
+ };
6248
+ var getSolutionUrl = function (type, identifier, typeKeywords) {
6249
+ var hubUrl;
6250
+ if (type === "Solution") {
6251
+ // NOTE: as per the above spreadsheet,
6252
+ // solution types are now in the Template family
6253
+ // but we don't send them to the route for initiative templates
6254
+ if ((typeKeywords === null || typeKeywords === void 0 ? void 0 : typeKeywords.indexOf("Deployed")) > 0) {
6255
+ // deployed solutions go to the generic content route
6256
+ hubUrl = "/content/" + identifier;
6257
+ }
6258
+ // others go to the solution about route
6259
+ hubUrl = "/templates/" + identifier + "/about";
6260
+ }
6261
+ return hubUrl;
6262
+ };
6263
+ function getMetadataPath(identifier) {
6264
+ // NOTE: i have verified that this will work regardless of the "Metadata Style" set on the org
6265
+ var metadataPaths = {
6266
+ updateFrequency: "metadata.dataIdInfo.resMaint.maintFreq.MaintFreqCd.@_value",
6267
+ reviseDate: "metadata.dataIdInfo.idCitation.date.reviseDate",
6268
+ pubDate: "metadata.dataIdInfo.idCitation.date.pubDate",
6269
+ createDate: "metadata.dataIdInfo.idCitation.date.createDate",
6270
+ metadataUpdateFrequency: "metadata.mdMaint.maintFreq.MaintFreqCd.@_value",
6271
+ metadataUpdatedDate: "metadata.mdDateSt",
6272
+ };
6273
+ return metadataPaths[identifier];
6274
+ }
6275
+ function getValueFromMetadata(metadata, identifier) {
6276
+ var path = getMetadataPath(identifier);
6277
+ return path && getProp(metadata, path);
6278
+ }
6279
+ var DatePrecision;
6280
+ (function (DatePrecision) {
6281
+ DatePrecision["Year"] = "year";
6282
+ DatePrecision["Month"] = "month";
6283
+ DatePrecision["Day"] = "day";
6284
+ DatePrecision["Time"] = "time";
6285
+ })(DatePrecision || (DatePrecision = {}));
6286
+ /**
6287
+ * Parses an ISO8601 date string into a date and a precision.
6288
+ * This is because a) if somone entered 2018, we want to respect that and not treat it as the same as 2018-01-01
6289
+ * and b) you cannot naively call new Date with an ISO 8601 string that does not include time information
6290
+ * For example, when I, here in mountain time, do new Date('2018').getFullYear() I get "2017".
6291
+ * This is because when you do not provide time or timezone info, UTC is assumed, so new Date('2018') is 2018-01-01T00:00:00 in UTC
6292
+ * which is actually 7 hours earlier here in mountain time.
6293
+ *
6294
+ * @param {string} isoString
6295
+ * @return { date: Date, precision: DatePrecision }
6296
+ */
6297
+ function parseISODateString(isoString) {
6298
+ isoString = "" + isoString;
6299
+ var date;
6300
+ var precision;
6301
+ if (/^\d{4}$/.test(isoString)) {
6302
+ // yyyy
6303
+ date = new Date(+isoString, 0, 1);
6304
+ precision = DatePrecision.Year;
6305
+ }
6306
+ else if (/^\d{4}-\d{1,2}$/.test(isoString)) {
6307
+ // yyyy-mm
6308
+ var parts = isoString.split("-");
6309
+ date = new Date(+parts[0], +parts[1] - 1, 1);
6310
+ precision = DatePrecision.Month;
6311
+ }
6312
+ else if (/^\d{4}-\d{1,2}-\d{1,2}$/.test(isoString)) {
6313
+ // yyyy-mm-dd
6314
+ var parts = isoString.split("-");
6315
+ date = new Date(+parts[0], +parts[1] - 1, +parts[2]);
6316
+ precision = DatePrecision.Day;
6317
+ }
6318
+ else if (!Number.isNaN(Date.parse(isoString))) {
6319
+ // any other string parsable to a valid date
6320
+ date = new Date(isoString);
6321
+ precision = isoString.includes("T")
6322
+ ? DatePrecision.Time
6323
+ : DatePrecision.Day;
6324
+ }
6325
+ return date && precision && { date: date, precision: precision };
6326
+ }
6327
+ var getServerSpatialReference = function (server, layer) {
6328
+ var _a;
6329
+ var layerSpatialReference = (_a = layer === null || layer === void 0 ? void 0 : layer.extent) === null || _a === void 0 ? void 0 : _a.spatialReference;
6330
+ return layerSpatialReference || (server === null || server === void 0 ? void 0 : server.spatialReference);
6331
+ };
6332
+ // NOTE: IItem has spatialRefernce: ISpatialReference, but
6333
+ // the portal REST API returns spatialReference as as string
6334
+ // that is always either WKID like "102100" or
6335
+ // WKT like "NAD_1983_HARN_StatePlane_Hawaii_3_FIPS_5103_Feet"
6336
+ // so we coerce those string into a ISpatialReference object
6337
+ var getItemSpatialReference = function (item) {
6338
+ var spatialReference = item.spatialReference;
6339
+ if (!spatialReference || typeof spatialReference === "object") {
6340
+ // no need to try and transform this into an ISpatialReference
6341
+ return spatialReference;
6342
+ }
6343
+ // otherwise it _should_ be a string (if coming form the REST API)
6344
+ // but we force it in case it was set to a number somewhere outside of TS
6345
+ var spatialReferenceString = spatialReference + "";
6346
+ var wkid = parseInt(spatialReferenceString, 10);
6347
+ return isNaN(wkid)
6348
+ ? // string is not a number, assume it is WKT
6349
+ { wkt: spatialReferenceString }
6350
+ : //
6351
+ { wkid: wkid };
6352
+ };
6353
+ /**
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
6362
+ */
6363
+ var getAdditionalResources = function (item, metadata, requestOptions) {
6364
+ var rawResources = getProp(metadata, "metadata.distInfo.distTranOps.onLineSrc") || null;
6365
+ if (rawResources === null) {
6366
+ return null;
6367
+ }
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();
6409
+ }
6410
+ return result;
6411
+ };
6412
+
6087
6413
  var STANDARD_LICENSES = [
6088
6414
  {
6089
6415
  type: "CC0-1.0",
@@ -6380,116 +6706,313 @@
6380
6706
  }
6381
6707
 
6382
6708
  /**
6383
- * Use this module for functions that do not need to be used by consumers (yet),
6384
- * but may be shared between hub.js modules, and/or need to be tested
6385
- * to get 100% coverage w/o writing cumbersome tests of higher level functions.
6386
- *
6387
- * Consuming will not be able to import these functions.
6388
- *
6389
- * It's probably a good pattern to add functions here first and then
6390
- * move them to index.ts only when they are needed by a consumer.
6709
+ * Get the fully qualified URL for an item's thumbnail
6710
+ * @param item w/ id, thumbnail, and access
6711
+ * @param portalUrlOrObject a portal base or API URL, a portal object, or request options containing either of those
6712
+ * @param optionsOrToken options including width and/or token for the current user's session; will only be appended as a query parameter if the item's access is **not** `public`
6713
+ * @returns URL to the item's thumbnail, defaults to `https://www.arcgis.com/sharing/rest/content/items/{item.id}/info/{item.thumbnail}`. Returns `null` if the item does not have a thumbnail assigned.
6391
6714
  */
6715
+ function getItemThumbnailUrl(item, portalUrlOrObject, optionsOrToken) {
6716
+ if (!item || !item.thumbnail) {
6717
+ // TODO: handle image types by returning the image (item data) itself?
6718
+ return null;
6719
+ }
6720
+ // tslint:disable-next-line prefer-const
6721
+ var _a = optionsOrToken || {}, token = _a.token, width = _a.width;
6722
+ // TODO: at the next breaking change drop support for passing token as string
6723
+ if (!token && typeof optionsOrToken === "string") {
6724
+ token = optionsOrToken;
6725
+ }
6726
+ var itemApiUrl = getItemApiUrl(item, portalUrlOrObject, token);
6727
+ var _b = itemApiUrl.split("?"), baseUrl = _b[0], search = _b[1];
6728
+ var searchParams = new URLSearchParams(search);
6729
+ searchParams.delete("f");
6730
+ if (width) {
6731
+ searchParams.append("w", width + "");
6732
+ }
6733
+ var newSearch = searchParams.toString();
6734
+ var url = baseUrl + "/info/" + item.thumbnail;
6735
+ return newSearch ? url + "?" + newSearch : url;
6736
+ }
6737
+
6738
+ // helper fns - move this to _internal if needed elsewhere
6739
+ var getOnlyQueryLayer = function (layers) {
6740
+ var layer = layers && layers.length === 1 && layers[0];
6741
+ return layer && layer.capabilities.includes("Query") && layer;
6742
+ };
6743
+ var shouldUseLayerInfo = function (layer, layers, url) {
6744
+ return (layer &&
6745
+ layers &&
6746
+ layers.length > 1 &&
6747
+ // we use item info instead of layer info for single layer items
6748
+ !getLayerIdFromUrl(url));
6749
+ };
6392
6750
  /**
6393
- * Create a new content with updated extent and derived properties like boundary
6394
- * @param content original content
6395
- * @param extent new extent
6396
- * @returns a new content with the updated extent and boundary
6397
- */
6398
- var setContentExtent = function (content, extent) {
6399
- // update content's item and extent
6400
- var item = __assign(__assign({}, content.item), { extent: extent });
6401
- var updated = __assign(__assign({}, content), { item: item, extent: extent });
6402
- // derive boundary from content properties
6403
- var boundary = getContentBoundary(updated);
6404
- return __assign(__assign({}, updated), { boundary: boundary });
6751
+ * The possible values for updateFrequency
6752
+ *
6753
+ * @enum {string}
6754
+ */
6755
+ exports.UpdateFrequency = void 0;
6756
+ (function (UpdateFrequency) {
6757
+ UpdateFrequency["Continual"] = "continual";
6758
+ UpdateFrequency["Daily"] = "daily";
6759
+ UpdateFrequency["Weekly"] = "weekly";
6760
+ UpdateFrequency["Fortnightly"] = "fortnightly";
6761
+ UpdateFrequency["Monthly"] = "monthly";
6762
+ UpdateFrequency["Quarterly"] = "quarterly";
6763
+ UpdateFrequency["Biannually"] = "biannually";
6764
+ UpdateFrequency["Annually"] = "annually";
6765
+ UpdateFrequency["AsNeeded"] = "as-needed";
6766
+ UpdateFrequency["Irregular"] = "irregular";
6767
+ UpdateFrequency["NotPlanned"] = "not-planned";
6768
+ UpdateFrequency["Unknown"] = "unknown";
6769
+ UpdateFrequency["Semimonthly"] = "semimonthly";
6770
+ })(exports.UpdateFrequency || (exports.UpdateFrequency = {}));
6771
+ var getUpdateFrequencyFromMetadata = function (metadata, identifier) {
6772
+ var updateFrequencyMap = {
6773
+ "001": exports.UpdateFrequency.Continual,
6774
+ "002": exports.UpdateFrequency.Daily,
6775
+ "003": exports.UpdateFrequency.Weekly,
6776
+ "004": exports.UpdateFrequency.Fortnightly,
6777
+ "005": exports.UpdateFrequency.Monthly,
6778
+ "006": exports.UpdateFrequency.Quarterly,
6779
+ "007": exports.UpdateFrequency.Biannually,
6780
+ "008": exports.UpdateFrequency.Annually,
6781
+ "009": exports.UpdateFrequency.AsNeeded,
6782
+ "010": exports.UpdateFrequency.Irregular,
6783
+ "011": exports.UpdateFrequency.NotPlanned,
6784
+ "012": exports.UpdateFrequency.Unknown,
6785
+ "013": exports.UpdateFrequency.Semimonthly,
6786
+ };
6787
+ return updateFrequencyMap[getValueFromMetadata(metadata, identifier || "updateFrequency")];
6405
6788
  };
6406
- var getContentBoundary = function (content) {
6407
- var _a;
6408
- var item = content.item;
6409
- var extent = item.extent;
6410
- var isValidItemExtent = isBBox(extent);
6411
- // user specified provenance is stored in item.properties
6412
- var provenance = ((_a = item.properties) === null || _a === void 0 ? void 0 : _a.boundary) ||
6413
- // but we default to item if the item has an extent
6414
- (isValidItemExtent ? "item" : undefined);
6415
- var geometry;
6416
- switch (provenance) {
6417
- case "item":
6418
- geometry = isValidItemExtent ? bBoxToPolygon(extent) : null;
6419
- break;
6420
- case "none":
6421
- geometry = null;
6422
- break;
6423
- // TODO: handle other provenances
6424
- }
6425
- // TODO: derive and return center
6789
+ var getDateInfoFromMetadata = function (metadata, identifier) {
6790
+ var metadataDateInfo = parseISODateString(getValueFromMetadata(metadata, identifier));
6791
+ return (metadataDateInfo && __assign(__assign({}, metadataDateInfo), { source: "metadata." + getMetadataPath(identifier) }));
6792
+ };
6793
+ var getLastEditDateInfo = function (content, layerOrServer) {
6794
+ var source = layerOrServer + ".editingInfo.lastEditDate";
6795
+ var lastEditDate = getProp(content, source);
6796
+ return (lastEditDate && {
6797
+ date: new Date(lastEditDate),
6798
+ source: source,
6799
+ // NOTE: this default was taken from _enrichDates
6800
+ precision: DatePrecision.Day,
6801
+ });
6802
+ };
6803
+ var getItemDateInfo = function (item, createdOrModified) {
6426
6804
  return {
6427
- provenance: provenance,
6428
- geometry: geometry,
6805
+ date: new Date(item[createdOrModified]),
6806
+ // NOTE: this was set to Day in _enrichDates()
6807
+ // but I wonder if it should be Time instead?
6808
+ precision: DatePrecision.Day,
6809
+ source: "item." + createdOrModified,
6429
6810
  };
6430
6811
  };
6431
- var MAX_SIZE = 5000000;
6432
- /**
6433
- * Returns whether or not an item is a proxied csv
6434
- *
6435
- * @param item
6436
- * @param requestOptions Hub Request Options (including whether we're in portal)
6437
- * @returns
6438
- */
6439
- var isProxiedCSV = function (item, requestOptions) {
6440
- return !requestOptions.isPortal &&
6441
- item.access === "public" &&
6442
- item.type === "CSV" &&
6443
- item.size <= MAX_SIZE;
6812
+ var getUpdatedDateInfo = function (item, options) {
6813
+ return (
6814
+ // prefer metadata revise date
6815
+ getDateInfoFromMetadata(options.metadata, "reviseDate") ||
6816
+ // then layer last edit date
6817
+ getLastEditDateInfo(options, "layer") ||
6818
+ // then server last edit date
6819
+ getLastEditDateInfo(options, "server") ||
6820
+ // fall back to item modified date
6821
+ getItemDateInfo(item, "modified"));
6444
6822
  };
6445
-
6446
- // private helper functions
6447
- function collectionToFamily(collection) {
6448
- var overrides = {
6449
- other: "content",
6450
- solution: "template",
6451
- };
6452
- return overrides[collection] || collection;
6453
- }
6454
- var cache = {};
6455
- // TODO: remove this at next breaking version
6823
+ var getPublishedDateInfo = function (item, metadata) {
6824
+ return (
6825
+ // prefer metadata publish date
6826
+ getDateInfoFromMetadata(metadata, "pubDate") ||
6827
+ // then metadata create date
6828
+ getDateInfoFromMetadata(metadata, "createDate") ||
6829
+ // fall back to item created date
6830
+ getItemDateInfo(item, "created"));
6831
+ };
6832
+ var getMetadataUpdatedDateInfo = function (item, metadata) {
6833
+ // prefer date from metadata
6834
+ return (getDateInfoFromMetadata(metadata, "metadataUpdatedDate") ||
6835
+ // default to when the item was last modified
6836
+ getItemDateInfo(item, "modified"));
6837
+ };
6838
+ // public API
6456
6839
  /**
6457
- * ```js
6458
- * import { getCategory } from "@esri/hub-common";
6459
- * //
6460
- * getCategory('Feature Layer')
6461
- * > 'dataset'
6462
- * ```
6463
- * **DEPRECATED: Use getCollection() instead**
6464
- * returns the Hub category for a given item type
6465
- * @param itemType The ArcGIS [item type](https://developers.arcgis.com/rest/users-groups-and-items/items-and-item-types.htm).
6466
- * @returns the category of a given item type.
6840
+ * DEPRECATED: Compute the content type icon based on the content type
6841
+ * @param content type
6842
+ * @returns content type icon
6467
6843
  */
6468
- function getCategory(itemType) {
6469
- if (itemType === void 0) { itemType = ""; }
6470
- /* tslint:disable no-console */
6471
- console.warn("DEPRECATED: Use getCollection() instead. getCategory will be removed at v10.0.0");
6472
- /* tslint:enable no-console */
6473
- var collection = getCollection(itemType);
6474
- // for backwards compatibility
6475
- return collection === "feedback" ? "app" : collection;
6476
- }
6844
+ var getContentTypeIcon = function (contentType) {
6845
+ var _a;
6846
+ var type = camelize(contentType || "");
6847
+ var iconMap = {
6848
+ appbuilderExtension: "file",
6849
+ appbuilderWidgetPackage: "widgets-source",
6850
+ application: "web",
6851
+ applicationConfiguration: "app-gear",
6852
+ arcgisProMap: "desktop",
6853
+ cadDrawing: "file-cad",
6854
+ cityEngineWebScene: "urban-model",
6855
+ codeAttachment: "file-code",
6856
+ codeSample: "file-code",
6857
+ colorSet: "palette",
6858
+ contentCategorySet: "label",
6859
+ csv: "file-csv",
6860
+ cSV: "file-csv",
6861
+ cSVCollection: "file-csv",
6862
+ dashboard: "dashboard",
6863
+ desktopApplication: "desktop",
6864
+ documentLink: "link",
6865
+ excaliburImageryProject: "file",
6866
+ explorerMap: "file",
6867
+ exportPackage: "file",
6868
+ featureCollection: "data",
6869
+ featureCollectionTemplate: "file",
6870
+ featureLayer: "data",
6871
+ featureService: "collection",
6872
+ fileGeodatabase: "data",
6873
+ form: "survey",
6874
+ geocodingService: "file",
6875
+ geodataService: "file",
6876
+ geometryService: "file",
6877
+ geopackage: "file",
6878
+ geoprocessingService: "file",
6879
+ globeLayer: "layers",
6880
+ globeService: "file",
6881
+ hubInitiative: "initiative",
6882
+ hubInitiativeTemplate: "initiative-template",
6883
+ hubPage: "browser",
6884
+ hubSiteApplication: "web",
6885
+ image: "file-image",
6886
+ imageService: "data",
6887
+ insightsModel: "file",
6888
+ insightsPage: "graph-moving-average",
6889
+ insightsTheme: "palette",
6890
+ insightsWorkbook: "graph-moving-average",
6891
+ iWorkPages: "file-text",
6892
+ iWorkKeynote: "presentation",
6893
+ iWorkNumbers: "file-report",
6894
+ kML: "data",
6895
+ kMLCollection: "data",
6896
+ layer: "layers",
6897
+ layerPackage: "layers",
6898
+ layerTemplate: "file",
6899
+ locatorPackage: "file",
6900
+ mapArea: "file",
6901
+ mapDocument: "map-contents",
6902
+ mapImageLayer: "collection",
6903
+ mapPackage: "file",
6904
+ mapService: "collection",
6905
+ microsoftExcel: "file-report",
6906
+ microsoftPowerpoint: "presentation",
6907
+ microsoftWord: "file-text",
6908
+ mission: "file",
6909
+ mobileMapPackage: "map-contents",
6910
+ nativeApplication: "mobile",
6911
+ nativeApplicationInstaller: "file",
6912
+ nativeApplicationTemplate: "file",
6913
+ mobileApplication: "mobile",
6914
+ networkAnalysisService: "file",
6915
+ notebook: "code",
6916
+ orientedImageryCatalog: "file",
6917
+ orthoMappingProject: "file",
6918
+ orthoMappingTemplate: "file",
6919
+ pDF: "file-pdf",
6920
+ quickCaptureProject: "mobile",
6921
+ rasterFunctionTemplate: "file",
6922
+ rasterLayer: "map",
6923
+ realTimeAnalytic: "file",
6924
+ relationalDatabaseConnection: "file",
6925
+ reportTemplate: "file",
6926
+ sceneLayer: "data",
6927
+ sceneService: "urban-model",
6928
+ serviceDefinition: "file",
6929
+ shapefile: "data",
6930
+ solution: "puzzle-piece",
6931
+ sqliteGeodatabase: "file",
6932
+ statisticalDataCollection: "file",
6933
+ storymap: "tour",
6934
+ storyMap: "tour",
6935
+ storymapTheme: "palette",
6936
+ symbolSet: "file",
6937
+ table: "table",
6938
+ urbanModel: "urban-model",
6939
+ vectorTilePackage: "file-shape",
6940
+ vectorTileService: "map",
6941
+ visioDocument: "conditional-rules",
6942
+ webExperience: "apps",
6943
+ webMap: "map",
6944
+ webMappingApplication: "apps",
6945
+ webScene: "urban-model",
6946
+ wfs: "map",
6947
+ wFS: "map",
6948
+ wMS: "map",
6949
+ wMTS: "map",
6950
+ workflowManagerService: "file",
6951
+ workforceProject: "list-check",
6952
+ };
6953
+ return (_a = iconMap[type]) !== null && _a !== void 0 ? _a : "file";
6954
+ };
6477
6955
  /**
6478
- * ```js
6479
- * import { getTypes } from "@esri/hub-common";
6480
- * //
6481
- * getTypes('site')
6482
- * > [ 'hub site application' ]
6483
- * ```
6484
- * To do.
6485
- * @param category The ArcGIS Hub category.
6486
- * @returns all the item types for the given category.
6956
+ * get portal URLs (home, API, data, and thumbnail) for an item
6487
6957
  *
6958
+ * @param item Item
6959
+ * @param requestOptions Request options
6960
+ * @returns a hash with the portal URLs
6961
+ * @export
6488
6962
  */
6489
- function getTypes(category) {
6490
- if (category === void 0) { category = ""; }
6491
- return categories[category.toLowerCase()];
6492
- }
6963
+ var getPortalUrls = function (item, requestOptions) {
6964
+ var authentication = requestOptions.authentication;
6965
+ var token = authentication && authentication.token;
6966
+ // add properties that depend on portal
6967
+ var portalHome = getItemHomeUrl(item.id, requestOptions);
6968
+ // the URL of the item's Portal API end point
6969
+ var portalApi = getItemApiUrl(item, requestOptions, token);
6970
+ // the URL of the item's data API end point
6971
+ var portalData = getItemDataUrl(item, requestOptions, token);
6972
+ // the full URL of the thumbnail
6973
+ var thumbnail = getItemThumbnailUrl(item, requestOptions, {
6974
+ token: token,
6975
+ });
6976
+ return {
6977
+ portalHome: portalHome,
6978
+ portalApi: portalApi,
6979
+ portalData: portalData,
6980
+ thumbnail: thumbnail,
6981
+ };
6982
+ };
6983
+ /**
6984
+ * If an item is a proxied csv, returns the url for the proxying feature layer.
6985
+ * If the item is not a proxied csv, returns undefined.
6986
+ *
6987
+ * @param item
6988
+ * @param requestOptions Hub Request Options (including whether we're in portal)
6989
+ * @returns
6990
+ */
6991
+ var getProxyUrl = function (item, requestOptions) {
6992
+ var result;
6993
+ if (isProxiedCSV(item, requestOptions)) {
6994
+ result = getHubApiUrl(requestOptions) + "/datasets/" + item.id + "_0/FeatureServer/0";
6995
+ }
6996
+ return result;
6997
+ };
6998
+ /**
6999
+ * parse layer id from a service URL
7000
+ * @param {string} url
7001
+ * @returns {string} layer id
7002
+ */
7003
+ var getLayerIdFromUrl = function (url) {
7004
+ var endsWithNumberSegmentRegEx = /\/\d+$/;
7005
+ var matched = url && url.match(endsWithNumberSegmentRegEx);
7006
+ return matched && matched[0].slice(1);
7007
+ };
7008
+ /**
7009
+ * Case-insensitive check if the type is "Feature Service"
7010
+ * @param {string} type - item's type
7011
+ * @returns {boolean}
7012
+ */
7013
+ var isFeatureService = function (type) {
7014
+ return type && type.toLowerCase() === "feature service";
7015
+ };
6493
7016
  /**
6494
7017
  * ```js
6495
7018
  * import { normalizeItemType } from "@esri/hub-common";
@@ -6525,76 +7048,6 @@
6525
7048
  }
6526
7049
  return ret;
6527
7050
  }
6528
- /**
6529
- * ```js
6530
- * import { getTypeCategories } from "@esri/hub-common";
6531
- * //
6532
- * getTypeCategories(item)
6533
- * > [ 'Hub Site Application' ]
6534
- * ```
6535
- * @param item Item object.
6536
- * @returns typeCategory of the input item.
6537
- *
6538
- */
6539
- function getTypeCategories(item) {
6540
- if (item === void 0) { item = {}; }
6541
- var type = normalizeItemType(item);
6542
- var category = getCategory(type);
6543
- if (category) {
6544
- // upper case first letter and return as element in array for backwards compatibility
6545
- var chars = Array.from(category);
6546
- chars[0] = chars[0].toUpperCase();
6547
- return [chars.join("")];
6548
- }
6549
- else {
6550
- return ["Other"];
6551
- }
6552
- }
6553
- /**
6554
- * ```js
6555
- * import { getCollection } from "@esri/hub-common";
6556
- * //
6557
- * getCollection('Feature Layer')
6558
- * > 'dataset'
6559
- * ```
6560
- * Get the Hub collection for a given item type
6561
- * @param itemType The ArcGIS [item type](https://developers.arcgis.com/rest/users-groups-and-items/items-and-item-types.htm).
6562
- * @returns the Hub collection of a given item type.
6563
- */
6564
- function getCollection(itemType) {
6565
- if (itemType === void 0) { itemType = ""; }
6566
- if (cache[itemType]) {
6567
- return cache[itemType];
6568
- }
6569
- for (var _i = 0, _a = Object.keys(collections); _i < _a.length; _i++) {
6570
- var collection = _a[_i];
6571
- for (var _b = 0, _c = collections[collection]; _b < _c.length; _b++) {
6572
- var type = _c[_b];
6573
- if (itemType.toLowerCase() === type.toLowerCase()) {
6574
- cache[itemType] = collection;
6575
- return collection;
6576
- }
6577
- }
6578
- }
6579
- }
6580
- /**
6581
- * Case-insensitive check if the type is "Feature Service"
6582
- * @param {string} type - item's type
6583
- * @returns {boolean}
6584
- */
6585
- var isFeatureService = function (type) {
6586
- return type && type.toLowerCase() === "feature service";
6587
- };
6588
- /**
6589
- * parse layer id from a service URL
6590
- * @param {string} url
6591
- * @returns {string} layer id
6592
- */
6593
- var getLayerIdFromUrl = function (url) {
6594
- var endsWithNumberSegmentRegEx = /\/\d+$/;
6595
- var matched = url && url.match(endsWithNumberSegmentRegEx);
6596
- return matched && matched[0].slice(1);
6597
- };
6598
7051
  /**
6599
7052
  * return the layerId if we can tell that item is a single layer service
6600
7053
  * @param {*} item from AGO
@@ -6606,6 +7059,7 @@
6606
7059
  // but have not verified that, nor that we should alway return '0' in that case
6607
7060
  return (getLayerIdFromUrl(item.url) ||
6608
7061
  (isFeatureService(item.type) &&
7062
+ item.typeKeywords &&
6609
7063
  includes(item.typeKeywords, "Singlelayer") &&
6610
7064
  "0"));
6611
7065
  };
@@ -6623,6 +7077,316 @@
6623
7077
  var layerId = getItemLayerId(item);
6624
7078
  return layerId ? id + "_" + layerId : id;
6625
7079
  };
7080
+ /**
7081
+ * Splits item category strings at slashes and discards the "Categories" keyword
7082
+ *
7083
+ * ```
7084
+ * ["/Categories/Boundaries", "/Categories/Planning and cadastre/Property records", "/Categories/Structure"]
7085
+ * ```
7086
+ * Should end up being
7087
+ * ```
7088
+ * ["Boundaries", "Planning and cadastre", "Property records", "Structure"]
7089
+ * ```
7090
+ *
7091
+ * @param categories - an array of strings
7092
+ * @private
7093
+ */
7094
+ function parseItemCategories(categories) {
7095
+ if (!categories)
7096
+ return categories;
7097
+ var exclude = ["categories", ""];
7098
+ var parsed = categories.map(function (cat) { return cat.split("/"); });
7099
+ var flattened = parsed.reduce(function (acc, arr, _) { return __spreadArrays(acc, arr); }, []);
7100
+ return flattened.filter(function (cat) { return !includes(exclude, cat.toLowerCase()); });
7101
+ }
7102
+ /**
7103
+ * Compose a new content object out of an item, enrichments, and context
7104
+ * @param item
7105
+ * @param options any enrichments, current state (selected layerId), or context (requestOptions)
7106
+ * @returns new content object
7107
+ */
7108
+ var composeContent = function (item, options) {
7109
+ // extract enrichments and context out of the options
7110
+ var _a = options || {}, slug = _a.slug, requestOptions = _a.requestOptions, data = _a.data, metadata = _a.metadata, groupIds = _a.groupIds, ownerUser = _a.ownerUser, org = _a.org, errors = _a.errors, server = _a.server, layers = _a.layers, recordCount = _a.recordCount, boundary = _a.boundary, statistics = _a.statistics;
7111
+ // set common variables that we will use in the derived properties below
7112
+ // if item refers to a layer we always want to use that layer id
7113
+ // otherwise use the layer id that was passed in (if any)
7114
+ var _layerIdFromUrl = getLayerIdFromUrl(item.url);
7115
+ var layerId = _layerIdFromUrl
7116
+ ? parseInt(_layerIdFromUrl, 10)
7117
+ : options === null || options === void 0 ? void 0 : options.layerId;
7118
+ var layer = layers &&
7119
+ (!isNil(layerId)
7120
+ ? // find the explicitly set layer id
7121
+ layers.find(function (_layer) { return _layer.id === layerId; })
7122
+ : // for feature servers with a single layer always show the layer
7123
+ isFeatureService(item.type) && getOnlyQueryLayer(layers));
7124
+ // NOTE: we only set hubId for public items in online
7125
+ var _canUseHubApi = !isPortal(requestOptions) && item.access === "public";
7126
+ var hubId = _canUseHubApi
7127
+ ? layer
7128
+ ? item.id + "_" + layer.id
7129
+ : getItemHubId(item)
7130
+ : undefined;
7131
+ var identifier = slug || hubId || item.id;
7132
+ // whether or not we should show layer info for name, description, etc
7133
+ var _shouldUseLayerInfo = shouldUseLayerInfo(layer, layers, item.url);
7134
+ var name = _shouldUseLayerInfo ? layer.name : item.title;
7135
+ var _layerDescription = _shouldUseLayerInfo && layer.description;
7136
+ // so much depends on type
7137
+ var type = layer
7138
+ ? // use layer type (Feature Layer, Table, etc) for layer content
7139
+ layer.type
7140
+ : // otherwise use the normalized item type
7141
+ normalizeItemType(item);
7142
+ // all the urls
7143
+ var urls = __assign({ relative: getHubRelativeUrl(type, identifier, item.typeKeywords) }, (requestOptions && getPortalUrls(item, requestOptions)));
7144
+ var _proxyUrl = getProxyUrl(item, requestOptions);
7145
+ // NOTE: I'd rather not compute these date values up front,
7146
+ // but they are used by several getters below, so we do it here only once
7147
+ var _updatedDateInfo = getUpdatedDateInfo(item, {
7148
+ metadata: metadata,
7149
+ layer: layer,
7150
+ server: server,
7151
+ });
7152
+ var _publishedDateInfo = getPublishedDateInfo(item, metadata);
7153
+ var _metadataUpdatedDateInfo = getMetadataUpdatedDateInfo(item, metadata);
7154
+ // return all of the above composed into a content object
7155
+ return __assign(__assign({
7156
+ // a reference to underlying item
7157
+ item: item }, item), {
7158
+ // item enrichments
7159
+ slug: slug,
7160
+ data: data,
7161
+ metadata: metadata,
7162
+ groupIds: groupIds,
7163
+ ownerUser: ownerUser,
7164
+ org: org, errors: errors || [],
7165
+ // server enrichments
7166
+ server: server,
7167
+ layers: layers,
7168
+ recordCount: recordCount,
7169
+ // enrichments from the Hub API (boundary is below)
7170
+ statistics: statistics,
7171
+ // derived properties
7172
+ // NOTE: in the getters below you can **not** use `this`
7173
+ // these are not meant to provide live updating computed props
7174
+ // their purpose is to avoid computing all these values above
7175
+ // especially where we want to defer computation of less used props
7176
+ hubId: hubId,
7177
+ identifier: identifier, get isProxied() {
7178
+ return !!_proxyUrl;
7179
+ }, layer: layer,
7180
+ name: name, get title() {
7181
+ return name;
7182
+ },
7183
+ get description() {
7184
+ return _layerDescription || item.description;
7185
+ }, type: type, get family() {
7186
+ return getFamily(type);
7187
+ }, get url() {
7188
+ return _proxyUrl
7189
+ ? _proxyUrl
7190
+ : _shouldUseLayerInfo
7191
+ ? parseServiceUrl(item.url) + "/" + layer.id
7192
+ : item.url;
7193
+ }, get categories() {
7194
+ return parseItemCategories(item.categories);
7195
+ },
7196
+ get actionLinks() {
7197
+ return item.properties && item.properties.links;
7198
+ },
7199
+ get hubActions() {
7200
+ return item.properties && item.properties.actions;
7201
+ },
7202
+ get isDownloadable() {
7203
+ return isDownloadable(item);
7204
+ },
7205
+ get structuredLicense() {
7206
+ return getStructuredLicense(item.licenseInfo);
7207
+ },
7208
+ get permissions() {
7209
+ return {
7210
+ visibility: item.access,
7211
+ control: item.itemControl || "view",
7212
+ };
7213
+ },
7214
+ get boundary() {
7215
+ // TODO: need to be able to handle automatic w/ additional enrichment
7216
+ // that could for example fetch the concave hull from the Hub API or resources
7217
+ return boundary || getContentBoundary(item);
7218
+ },
7219
+ get summary() {
7220
+ return _layerDescription
7221
+ ? _layerDescription
7222
+ : // TODO: this should use the logic for the Hub API's searchDescription
7223
+ // see: https://github.com/ArcGIS/hub-indexer/blob/b352cfded8221a967ac80447879d493db6476d7a/packages/duke/compose/dataset.js#L238-L250
7224
+ // TODO: can we strip HTML from description, and do we need to trim it to a X chars?
7225
+ item.snippet || item.description;
7226
+ }, urls: urls, get portalHomeUrl() {
7227
+ return urls.portalHome;
7228
+ },
7229
+ get portalDataUrl() {
7230
+ return urls.portalData;
7231
+ },
7232
+ get portalApiUrl() {
7233
+ return urls.portalApi;
7234
+ },
7235
+ get thumbnailUrl() {
7236
+ return urls.thumbnail;
7237
+ },
7238
+ /** The date the item was created */
7239
+ get createdDate() {
7240
+ return new Date(item.created);
7241
+ }, createdDateSource: "item.created", get updatedDate() {
7242
+ return _updatedDateInfo.date;
7243
+ },
7244
+ get updatedDateSource() {
7245
+ return _updatedDateInfo.source;
7246
+ },
7247
+ get updatedDatePrecision() {
7248
+ return _updatedDateInfo.precision;
7249
+ },
7250
+ get modified() {
7251
+ return _updatedDateInfo.date.getTime();
7252
+ },
7253
+ get publishedDate() {
7254
+ return _publishedDateInfo.date;
7255
+ },
7256
+ get publishedDateSource() {
7257
+ return _publishedDateInfo.source;
7258
+ },
7259
+ get publishedDatePrecision() {
7260
+ return _publishedDateInfo.precision;
7261
+ },
7262
+ get metadataUpdatedDate() {
7263
+ return _metadataUpdatedDateInfo.date;
7264
+ },
7265
+ get metadataUpdatedDateSource() {
7266
+ return _metadataUpdatedDateInfo.source;
7267
+ },
7268
+ get metadataUpdatedDatePrecision() {
7269
+ return _metadataUpdatedDateInfo.precision;
7270
+ },
7271
+ get updateFrequency() {
7272
+ return getUpdateFrequencyFromMetadata(metadata);
7273
+ },
7274
+ get metadataUpdateFrequency() {
7275
+ return getUpdateFrequencyFromMetadata(metadata, "metadataUpdateFrequency");
7276
+ },
7277
+ // TODO: add the publisher logic outlined here:
7278
+ // https://devtopia.esri.com/dc/hub/issues/2932#issuecomment-3276309
7279
+ get publisher() {
7280
+ return {
7281
+ name: item.owner,
7282
+ username: item.owner,
7283
+ };
7284
+ },
7285
+ // TODO: is metrics in use?
7286
+ get metrics() {
7287
+ return item.properties && item.properties.metrics;
7288
+ },
7289
+ get spatialReference() {
7290
+ // NOTE: I had to add || null just so packages/content/test/portal.test.ts would pass
7291
+ // we can remove that when that package is deprecated
7292
+ return (getItemSpatialReference(item) ||
7293
+ getServerSpatialReference(server, layer) ||
7294
+ null);
7295
+ },
7296
+ get orgId() {
7297
+ // NOTE: it's undocumented, but the portal API will return orgId for items... sometimes
7298
+ return org ? org.id : item.orgId;
7299
+ },
7300
+ // deprecated properties
7301
+ // TODO: should we add these in legacy wrappers
7302
+ // like itemToContent or datasetToContent instead?
7303
+ get contentTypeIcon() {
7304
+ /* tslint:disable no-console */
7305
+ console.warn(
7306
+ /* tslint:enable no-console */
7307
+ "DEPRECATED: it is now the responsibility of the consuming package to determine the icon");
7308
+ return getContentTypeIcon(type);
7309
+ },
7310
+ get license() {
7311
+ /* tslint:disable no-console */
7312
+ console.warn("DEPRECATED: use structuredLicense instead");
7313
+ /* tslint:enable no-console */
7314
+ return { name: "Custom License", description: item.accessInformation };
7315
+ },
7316
+ get hubType() {
7317
+ /* tslint:disable no-console */
7318
+ console.warn("DEPRECATED: use family instead");
7319
+ /* tslint:enable no-console */
7320
+ return getFamily(type);
7321
+ },
7322
+ get additionalResources() {
7323
+ return getAdditionalResources(item, metadata);
7324
+ } });
7325
+ };
7326
+
7327
+ // TODO: remove this at next breaking version
7328
+ /**
7329
+ * ```js
7330
+ * import { getCategory } from "@esri/hub-common";
7331
+ * //
7332
+ * getCategory('Feature Layer')
7333
+ * > 'dataset'
7334
+ * ```
7335
+ * **DEPRECATED: Use getCollection() instead**
7336
+ * returns the Hub category for a given item type
7337
+ * @param itemType The ArcGIS [item type](https://developers.arcgis.com/rest/users-groups-and-items/items-and-item-types.htm).
7338
+ * @returns the category of a given item type.
7339
+ */
7340
+ function getCategory(itemType) {
7341
+ if (itemType === void 0) { itemType = ""; }
7342
+ /* tslint:disable no-console */
7343
+ console.warn("DEPRECATED: Use getCollection() instead. getCategory will be removed at v10.0.0");
7344
+ /* tslint:enable no-console */
7345
+ var collection = getCollection(itemType);
7346
+ // for backwards compatibility
7347
+ return collection === "feedback" ? "app" : collection;
7348
+ }
7349
+ /**
7350
+ * ```js
7351
+ * import { getTypes } from "@esri/hub-common";
7352
+ * //
7353
+ * getTypes('site')
7354
+ * > [ 'hub site application' ]
7355
+ * ```
7356
+ * To do.
7357
+ * @param category The ArcGIS Hub category.
7358
+ * @returns all the item types for the given category.
7359
+ *
7360
+ */
7361
+ function getTypes(category) {
7362
+ if (category === void 0) { category = ""; }
7363
+ return categories[category.toLowerCase()];
7364
+ }
7365
+ /**
7366
+ * ```js
7367
+ * import { getTypeCategories } from "@esri/hub-common";
7368
+ * //
7369
+ * getTypeCategories(item)
7370
+ * > [ 'Hub Site Application' ]
7371
+ * ```
7372
+ * @param item Item object.
7373
+ * @returns typeCategory of the input item.
7374
+ *
7375
+ */
7376
+ function getTypeCategories(item) {
7377
+ if (item === void 0) { item = {}; }
7378
+ var type = normalizeItemType(item);
7379
+ var category = getCategory(type);
7380
+ if (category) {
7381
+ // upper case first letter and return as element in array for backwards compatibility
7382
+ var chars = Array.from(category);
7383
+ chars[0] = chars[0].toUpperCase();
7384
+ return [chars.join("")];
7385
+ }
7386
+ else {
7387
+ return ["Other"];
7388
+ }
7389
+ }
6626
7390
  /**
6627
7391
  * ```js
6628
7392
  * import { getContentIdentifier } from "@esri/hub-common";
@@ -6652,7 +7416,7 @@
6652
7416
  // site data instead. Because this one is the original one that was used
6653
7417
  // to create the page url (not mutable once created) and the slug (below)
6654
7418
  // generated by the hub-indexer could simply change with page name.
6655
- if (isPageContent(content)) {
7419
+ if (isPageType(content.type)) {
6656
7420
  // check if the page is linked to the current site
6657
7421
  var pages = getProp(site, "data.values.pages") || [];
6658
7422
  // if so, return the page slug otherwise the page id
@@ -6721,74 +7485,20 @@
6721
7485
  return context + "::" + slug;
6722
7486
  }
6723
7487
  }
6724
- /**
6725
- * Remove context (prefix) from a slug
6726
- *
6727
- * @param slug Hub API slug with context
6728
- * @param context usually a portal's orgKey
6729
- * @returns slug without context
6730
- */
6731
- function removeContextFromSlug(slug, context) {
6732
- if (context && slug.match(context + "::")) {
6733
- return slug.split(context + "::")[1];
6734
- }
6735
- else {
6736
- return slug;
6737
- }
6738
- }
6739
- /**
6740
- * Splits item category strings at slashes and discards the "Categories" keyword
6741
- *
6742
- * ```
6743
- * ["/Categories/Boundaries", "/Categories/Planning and cadastre/Property records", "/Categories/Structure"]
6744
- * ```
6745
- * Should end up being
6746
- * ```
6747
- * ["Boundaries", "Planning and cadastre", "Property records", "Structure"]
6748
- * ```
6749
- *
6750
- * @param categories - an array of strings
6751
- * @private
6752
- */
6753
- function parseItemCategories(categories) {
6754
- if (!categories)
6755
- return categories;
6756
- var exclude = ["categories", ""];
6757
- var parsed = categories.map(function (cat) { return cat.split("/"); });
6758
- var flattened = parsed.reduce(function (acc, arr, _) { return __spreadArrays(acc, arr); }, []);
6759
- return flattened.filter(function (cat) { return !includes(exclude, cat.toLowerCase()); });
6760
- }
6761
- /**
6762
- * return the Hub family given an item's type
6763
- * @param type item type
6764
- * @returns Hub family
6765
- */
6766
- function getFamily(type) {
6767
- var family;
6768
- // override default behavior for the rows that are highlighted in yellow here:
6769
- // https://esriis.sharepoint.com/:x:/r/sites/ArcGISHub/_layouts/15/Doc.aspx?sourcedoc=%7BADA1C9DC-4F6C-4DE4-92C6-693EF9571CFA%7D&file=Hub%20Routes.xlsx&nav=MTBfe0VENEREQzI4LUZFMDctNEI0Ri04NjcyLThCQUE2MTA0MEZGRn1fezIwMTIwMEJFLTA4MEQtNEExRC05QzA4LTE5MTAzOUQwMEE1RH0&action=default&mobileredirect=true&cid=df1c874b-c367-4cea-bc13-7bebfad3f2ac
6770
- switch ((type || "").toLowerCase()) {
6771
- case "image service":
6772
- family = "dataset";
6773
- break;
6774
- case "feature service":
6775
- case "raster layer":
6776
- // TODO: check if feature service has > 1 layer first?
6777
- family = "map";
6778
- break;
6779
- case "microsoft excel":
6780
- family = "document";
6781
- break;
6782
- case "cad drawing":
6783
- case "feature collection template":
6784
- case "report template":
6785
- family = "content";
6786
- break;
6787
- default:
6788
- // by default derive from collection
6789
- family = collectionToFamily(getCollection(type));
7488
+ /**
7489
+ * Remove context (prefix) from a slug
7490
+ *
7491
+ * @param slug Hub API slug with context
7492
+ * @param context usually a portal's orgKey
7493
+ * @returns slug without context
7494
+ */
7495
+ function removeContextFromSlug(slug, context) {
7496
+ if (context && slug.match(context + "::")) {
7497
+ return slug.split(context + "::")[1];
7498
+ }
7499
+ else {
7500
+ return slug;
6790
7501
  }
6791
- return family;
6792
7502
  }
6793
7503
  /**
6794
7504
  * DEPRECATED: Use getFamily() instead.
@@ -6816,51 +7526,7 @@
6816
7526
  * @export
6817
7527
  */
6818
7528
  function itemToContent(item) {
6819
- var createdDate = new Date(item.created);
6820
- var createdDateSource = "item.created";
6821
- var properties = item.properties;
6822
- var content = Object.assign({}, item, {
6823
- identifier: item.id,
6824
- // no server errors when fetching the item directly
6825
- errors: [],
6826
- // store a reference to the item
6827
- item: item,
6828
- // NOTE: this will overwrite any existing item.name, which is
6829
- // The file name of the item for file types. Read-only.
6830
- // presumably there to use as the default file name when downloading
6831
- // we don't store item.name in the Hub API and we use name for title
6832
- name: item.title,
6833
- // TODO: hubType is no longer used, remove it at next breaking change
6834
- hubType: getItemHubType(item),
6835
- categories: parseItemCategories(item.categories),
6836
- itemCategories: item.categories,
6837
- // can we strip HTML from description, and do we need to trim it to a X chars?
6838
- summary: item.snippet || item.description,
6839
- publisher: {
6840
- name: item.owner,
6841
- username: item.owner,
6842
- },
6843
- permissions: {
6844
- visibility: item.access,
6845
- control: item.itemControl || "view",
6846
- },
6847
- // Hub app configuration metadata from item properties
6848
- actionLinks: properties && properties.links,
6849
- hubActions: properties && properties.actions,
6850
- metrics: properties && properties.metrics,
6851
- isDownloadable: isDownloadable(item),
6852
- // default boundary from item.extent
6853
- license: { name: "Custom License", description: item.accessInformation },
6854
- // dates and sources we will enrich these later...
6855
- createdDate: createdDate,
6856
- createdDateSource: createdDateSource,
6857
- publishedDate: createdDate,
6858
- publishedDateSource: createdDateSource,
6859
- updatedDate: new Date(item.modified),
6860
- updatedDateSource: "item.modified",
6861
- structuredLicense: getStructuredLicense(item.licenseInfo),
6862
- });
6863
- return setContentExtent(setContentType(content, item.type), item.extent);
7529
+ return composeContent(item);
6864
7530
  }
6865
7531
  /**
6866
7532
  * Convert a Hub API dataset resource to Hub Content
@@ -6872,76 +7538,43 @@
6872
7538
  function datasetToContent(dataset) {
6873
7539
  // extract item from dataset, create content from the item
6874
7540
  var item = datasetToItem(dataset);
6875
- var content = itemToContent(item);
6876
- // We remove these because the indexer doesn't actually
6877
- // preserve the original item categories so this attribute is invalid
6878
- delete content.itemCategories;
6879
- // overwrite or add enrichments from Hub API
6880
- var hubId = dataset.id, attributes = dataset.attributes;
6881
- var
6882
- // common enrichments
6883
- errors = attributes.errors, boundary = attributes.boundary, extent = attributes.extent, metadata = attributes.metadata, modified = attributes.modified, modifiedProvenance = attributes.modifiedProvenance, slug = attributes.slug, searchDescription = attributes.searchDescription, groupIds = attributes.groupIds,
7541
+ // extract enrichments from attributes
7542
+ var _a = dataset.attributes,
7543
+ // item enrichments
7544
+ errors = _a.errors, boundary = _a.boundary, metadata = _a.metadata, slug = _a.slug, groupIds = _a.groupIds, orgId = _a.orgId, orgName = _a.orgName, organization = _a.organization, orgExtent = _a.orgExtent,
6884
7545
  // map and feature server enrichments
6885
- server = attributes.server, layers = attributes.layers,
6886
- // NOTE: the Hub API also returns the following server properties
6887
- // but we should be able to get them from the above server object
6888
- // currentVersion, capabilities, tileInfo, serviceSpatialReference
6889
- // maxRecordCount, supportedQueryFormats, etc
6890
- // feature and raster layer enrichments
6891
- layer = attributes.layer, recordCount = attributes.recordCount, statistics = attributes.statistics,
6892
- // NOTE: the Hub API also returns the following layer properties
6893
- // but we should be able to get them from the above layer object
6894
- // supportedQueryFormats, supportsAdvancedQueries, advancedQueryCapabilities, useStandardizedQueries
6895
- // geometryType, objectIdField, displayField, fields,
6896
- // org properties?
6897
- orgId = attributes.orgId, orgName = attributes.orgName, organization = attributes.organization, orgExtent = attributes.orgExtent,
6898
- // NOTE: for layers and tables the Hub API returns the layer type
6899
- // ("Feature Layer", "Table", "Raster Layer") instead of the item type
6900
- type = attributes.type;
6901
- // NOTE: we could throw or return if there are errors
6902
- // to prevent type errors trying to read properties below
6903
- content.errors = errors;
6904
- // common enrichments
6905
- content.boundary = boundary;
6906
- if (!isBBox(item.extent) && extent && isBBox(extent.coordinates)) {
6907
- // we fall back to the extent derived by the API
6908
- // which prefers layer or service extents and ultimately
6909
- // falls back to the org's extent
6910
- content.extent = extent.coordinates;
6911
- }
6912
- // setting this to null signals to enrichMetadata to skip this
6913
- content.metadata = metadata || null;
6914
- if (content.modified !== modified) {
6915
- // capture the enriched modified date
6916
- // NOTE: the item modified date is still available on content.item.modified
6917
- content.modified = modified;
6918
- content.updatedDate = new Date(modified);
6919
- content.updatedDateSource = modifiedProvenance;
6920
- }
6921
- content.slug = slug;
7546
+ server = _a.server, layers = _a.layers, layer = _a.layer, recordCount = _a.recordCount, statistics = _a.statistics,
7547
+ // additional attributes needed
7548
+ searchDescription = _a.searchDescription;
7549
+ // get the layerId from the layer
7550
+ var layerId = layer && layer.id;
7551
+ // re-assemble the org as an enrichment
7552
+ var org = orgId && {
7553
+ id: orgId,
7554
+ name: orgName || organization,
7555
+ extent: orgExtent,
7556
+ };
7557
+ // compose a content out of the above
7558
+ var content = composeContent(item, {
7559
+ layerId: layerId,
7560
+ slug: slug,
7561
+ errors: errors,
7562
+ // setting this to null signals to enrichMetadata to skip this
7563
+ metadata: metadata || null,
7564
+ groupIds: groupIds,
7565
+ org: org,
7566
+ server: server,
7567
+ layers: layers,
7568
+ recordCount: recordCount,
7569
+ boundary: boundary,
7570
+ statistics: statistics,
7571
+ });
7572
+ // TODO: need to add searchDescription logic to composeContent()
6922
7573
  if (searchDescription) {
6923
7574
  // overwrite default summary (from snippet) w/ search description
6924
7575
  content.summary = searchDescription;
6925
7576
  }
6926
- content.groupIds = groupIds;
6927
- // server enrichments
6928
- content.server = server;
6929
- content.layers = layers;
6930
- // layer enrichments
6931
- content.layer = layer;
6932
- content.recordCount = recordCount;
6933
- content.statistics = statistics;
6934
- // org enrichments
6935
- if (orgId) {
6936
- content.org = {
6937
- id: orgId,
6938
- name: orgName || organization,
6939
- extent: orgExtent,
6940
- };
6941
- }
6942
- // return a content with updated hubId and type
6943
- // along w/ related properties like identifier, family, etc
6944
- return setContentType(setContentHubId(content, hubId), type);
7577
+ return content;
6945
7578
  }
6946
7579
  /**
6947
7580
  * Convert a Hub API dataset resource to a portal item
@@ -7072,122 +7705,6 @@
7072
7705
  relative: getContentRelativeUrl(updated),
7073
7706
  });
7074
7707
  };
7075
- /**
7076
- * Compute the content type icon based on the content type
7077
- * @param content type
7078
- * @returns content type icon
7079
- */
7080
- var getContentTypeIcon = function (contentType) {
7081
- var _a;
7082
- var type = camelize(contentType || "");
7083
- var iconMap = {
7084
- appbuilderExtension: "file",
7085
- appbuilderWidgetPackage: "widgets-source",
7086
- application: "web",
7087
- applicationConfiguration: "app-gear",
7088
- arcgisProMap: "desktop",
7089
- cadDrawing: "file-cad",
7090
- cityEngineWebScene: "urban-model",
7091
- codeAttachment: "file-code",
7092
- codeSample: "file-code",
7093
- colorSet: "palette",
7094
- contentCategorySet: "label",
7095
- csv: "file-csv",
7096
- cSV: "file-csv",
7097
- cSVCollection: "file-csv",
7098
- dashboard: "dashboard",
7099
- desktopApplication: "desktop",
7100
- documentLink: "link",
7101
- excaliburImageryProject: "file",
7102
- explorerMap: "file",
7103
- exportPackage: "file",
7104
- featureCollection: "data",
7105
- featureCollectionTemplate: "file",
7106
- featureLayer: "data",
7107
- featureService: "collection",
7108
- fileGeodatabase: "data",
7109
- form: "survey",
7110
- geocodingService: "file",
7111
- geodataService: "file",
7112
- geometryService: "file",
7113
- geopackage: "file",
7114
- geoprocessingService: "file",
7115
- globeLayer: "layers",
7116
- globeService: "file",
7117
- hubInitiative: "initiative",
7118
- hubInitiativeTemplate: "initiative-template",
7119
- hubPage: "browser",
7120
- hubSiteApplication: "web",
7121
- image: "file-image",
7122
- imageService: "data",
7123
- insightsModel: "file",
7124
- insightsPage: "graph-moving-average",
7125
- insightsTheme: "palette",
7126
- insightsWorkbook: "graph-moving-average",
7127
- iWorkPages: "file-text",
7128
- iWorkKeynote: "presentation",
7129
- iWorkNumbers: "file-report",
7130
- kML: "data",
7131
- kMLCollection: "data",
7132
- layer: "layers",
7133
- layerPackage: "layers",
7134
- layerTemplate: "file",
7135
- locatorPackage: "file",
7136
- mapArea: "file",
7137
- mapDocument: "map-contents",
7138
- mapImageLayer: "collection",
7139
- mapPackage: "file",
7140
- mapService: "collection",
7141
- microsoftExcel: "file-report",
7142
- microsoftPowerpoint: "presentation",
7143
- microsoftWord: "file-text",
7144
- mission: "file",
7145
- mobileMapPackage: "map-contents",
7146
- nativeApplication: "mobile",
7147
- nativeApplicationInstaller: "file",
7148
- nativeApplicationTemplate: "file",
7149
- mobileApplication: "mobile",
7150
- networkAnalysisService: "file",
7151
- notebook: "code",
7152
- orientedImageryCatalog: "file",
7153
- orthoMappingProject: "file",
7154
- orthoMappingTemplate: "file",
7155
- pDF: "file-pdf",
7156
- quickCaptureProject: "mobile",
7157
- rasterFunctionTemplate: "file",
7158
- rasterLayer: "map",
7159
- realTimeAnalytic: "file",
7160
- relationalDatabaseConnection: "file",
7161
- reportTemplate: "file",
7162
- sceneLayer: "data",
7163
- sceneService: "urban-model",
7164
- serviceDefinition: "file",
7165
- shapefile: "data",
7166
- solution: "puzzle-piece",
7167
- sqliteGeodatabase: "file",
7168
- statisticalDataCollection: "file",
7169
- storymap: "tour",
7170
- storyMap: "tour",
7171
- storymapTheme: "palette",
7172
- symbolSet: "file",
7173
- table: "table",
7174
- urbanModel: "urban-model",
7175
- vectorTilePackage: "file-shape",
7176
- vectorTileService: "map",
7177
- visioDocument: "conditional-rules",
7178
- webExperience: "apps",
7179
- webMap: "map",
7180
- webMappingApplication: "apps",
7181
- webScene: "urban-model",
7182
- wfs: "map",
7183
- wFS: "map",
7184
- wMS: "map",
7185
- wMTS: "map",
7186
- workflowManagerService: "file",
7187
- workforceProject: "list-check",
7188
- };
7189
- return (_a = iconMap[type]) !== null && _a !== void 0 ? _a : "file";
7190
- };
7191
7708
  /**
7192
7709
  * Compute the content type label
7193
7710
  * @param contentType
@@ -7252,78 +7769,7 @@
7252
7769
  return __assign(__assign({}, content), { urls: urls });
7253
7770
  };
7254
7771
  var getContentRelativeUrl = function (content, siteIdentifier) {
7255
- var family = content.family;
7256
- // prefer site specific identifier if passed in
7257
- var identifier = siteIdentifier || content.identifier;
7258
- // solution types have their own logic
7259
- var contentUrl = getSolutionUrl(content);
7260
- if (!contentUrl) {
7261
- var pluralizedFamilies = [
7262
- "app",
7263
- "dataset",
7264
- "document",
7265
- "map",
7266
- "template",
7267
- ];
7268
- // default to the catchall content route
7269
- var path = "/content";
7270
- if (content.family === "feedback") {
7271
- // exception
7272
- path = "/feedback/surveys";
7273
- }
7274
- else if (isPageContent(content)) {
7275
- // pages are in the document family,
7276
- // but instead of showing the page's metadata on /documents/about
7277
- // but we render the page on the pages route
7278
- path = "/pages";
7279
- }
7280
- else if (pluralizedFamilies.indexOf(family) > -1) {
7281
- // the rule
7282
- path = "/" + family + "s";
7283
- }
7284
- contentUrl = path + "/" + identifier;
7285
- }
7286
- return contentUrl;
7287
- };
7288
- var getSolutionUrl = function (content) {
7289
- var _a;
7290
- var hubUrl;
7291
- var type = content.type, identifier = content.identifier;
7292
- if (type === "Solution") {
7293
- // NOTE: as per the above spreadsheet,
7294
- // solution types are now in the Template family
7295
- // but we don't send them to the route for initiative templates
7296
- if (((_a = content.typeKeywords) === null || _a === void 0 ? void 0 : _a.indexOf("Deployed")) > 0) {
7297
- // deployed solutions go to the generic content route
7298
- hubUrl = "/content/" + identifier;
7299
- }
7300
- // others go to the solution about route
7301
- hubUrl = "/templates/" + identifier + "/about";
7302
- }
7303
- return hubUrl;
7304
- };
7305
- // page helpers
7306
- // TODO: we check both "Hub Page" and "Site Page" because we don't know whether the site is a portal or not
7307
- // In the future, the site object will have a site.isPortal() function that we can leverage
7308
- // instead of hardcoding the types here.
7309
- var isPageContent = function (content) {
7310
- return includes(["Hub Page", "Site Page"], content.type);
7311
- };
7312
- // proxied csv helpers
7313
- /**
7314
- * If an item is a proxied csv, returns the url for the proxying feature layer.
7315
- * If the item is not a proxied csv, returns undefined.
7316
- *
7317
- * @param item
7318
- * @param requestOptions Hub Request Options (including whether we're in portal)
7319
- * @returns
7320
- */
7321
- var getProxyUrl = function (item, requestOptions) {
7322
- var result;
7323
- if (isProxiedCSV(item, requestOptions)) {
7324
- result = requestOptions.hubApiUrl + "/datasets/" + item.id + "_0/FeatureServer/0";
7325
- }
7326
- return result;
7772
+ return getHubRelativeUrl(content.type, siteIdentifier || content.identifier, content.typeKeywords);
7327
7773
  };
7328
7774
 
7329
7775
  /**
@@ -9543,7 +9989,7 @@
9543
9989
  function searchProjects(filter, options) {
9544
9990
  var _a;
9545
9991
  return __awaiter(this, void 0, void 0, function () {
9546
- var scopingFilter, projectFilter, expanded, so;
9992
+ var scopingFilter, projectFilter, expanded, so, props;
9547
9993
  return __generator(this, function (_b) {
9548
9994
  scopingFilter = {
9549
9995
  filterType: "content",
@@ -9559,22 +10005,19 @@
9559
10005
  so.countFields = options.aggregations.join(",");
9560
10006
  so.countSize = 200;
9561
10007
  }
9562
- // copy over various options
9563
- if (options.num) {
9564
- so.num = options.num;
9565
- }
9566
- if (options.sortField) {
9567
- so.sortField = options.sortField;
9568
- }
9569
- if (options.sortOrder) {
9570
- so.sortOrder = options.sortOrder;
9571
- }
9572
- if (options.site) {
9573
- so.site = cloneObject$1(options.site);
9574
- }
9575
- if (options.authentication) {
9576
- so.authentication = options.authentication;
9577
- }
10008
+ props = [
10009
+ "authentication",
10010
+ "num",
10011
+ "sortField",
10012
+ "sortOrder",
10013
+ "site",
10014
+ ];
10015
+ // copy the props over
10016
+ props.forEach(function (prop) {
10017
+ if (options.hasOwnProperty(prop)) {
10018
+ so[prop] = options[prop];
10019
+ }
10020
+ });
9578
10021
  return [2 /*return*/, searchPortalProjects(so)];
9579
10022
  });
9580
10023
  });
@@ -9991,36 +10434,6 @@
9991
10434
  });
9992
10435
  }
9993
10436
 
9994
- /**
9995
- * Get the fully qualified URL for an item's thumbnail
9996
- * @param item w/ id, thumbnail, and access
9997
- * @param portalUrlOrObject a portal base or API URL, a portal object, or request options containing either of those
9998
- * @param optionsOrToken options including width and/or token for the current user's session; will only be appended as a query parameter if the item's access is **not** `public`
9999
- * @returns URL to the item's thumbnail, defaults to `https://www.arcgis.com/sharing/rest/content/items/{item.id}/info/{item.thumbnail}`. Returns `null` if the item does not have a thumbnail assigned.
10000
- */
10001
- function getItemThumbnailUrl(item, portalUrlOrObject, optionsOrToken) {
10002
- if (!item || !item.thumbnail) {
10003
- // TODO: handle image types by returning the image (item data) itself?
10004
- return null;
10005
- }
10006
- // tslint:disable-next-line prefer-const
10007
- var _a = optionsOrToken || {}, token = _a.token, width = _a.width;
10008
- // TODO: at the next breaking change drop support for passing token as string
10009
- if (!token && typeof optionsOrToken === "string") {
10010
- token = optionsOrToken;
10011
- }
10012
- var itemApiUrl = getItemApiUrl(item, portalUrlOrObject, token);
10013
- var _b = itemApiUrl.split("?"), baseUrl = _b[0], search = _b[1];
10014
- var searchParams = new URLSearchParams(search);
10015
- searchParams.delete("f");
10016
- if (width) {
10017
- searchParams.append("w", width + "");
10018
- }
10019
- var newSearch = searchParams.toString();
10020
- var url = baseUrl + "/info/" + item.thumbnail;
10021
- return newSearch ? url + "?" + newSearch : url;
10022
- }
10023
-
10024
10437
  /**
10025
10438
  * Given an item, return an array of assets that includes
10026
10439
  * all the resources, as well as the thumbnail
@@ -11249,40 +11662,36 @@
11249
11662
  function _searchContent(filter, options) {
11250
11663
  var _a;
11251
11664
  return __awaiter(this, void 0, void 0, function () {
11252
- var expanded, api, searchPromise, so;
11665
+ var expanded, api, searchPromise, so_1, props;
11253
11666
  return __generator(this, function (_b) {
11254
11667
  expanded = expandContentFilter(filter);
11255
11668
  api = expandApi(options.api || "arcgis");
11256
11669
  // Portal Search
11257
11670
  if (api.type === "arcgis") {
11258
- so = serializeContentFilterForPortal(expanded);
11259
- // if we have auth, pass it forward
11260
- // otherwise set the portal property
11261
- if (options.authentication) {
11262
- so.authentication = options.authentication;
11263
- }
11264
- else {
11265
- so.portal = api.url + "/sharing/rest";
11671
+ so_1 = serializeContentFilterForPortal(expanded);
11672
+ props = [
11673
+ "authentication",
11674
+ "num",
11675
+ "sortField",
11676
+ "sortOrder",
11677
+ "site",
11678
+ ];
11679
+ // copy the props over
11680
+ props.forEach(function (prop) {
11681
+ if (options.hasOwnProperty(prop)) {
11682
+ so_1[prop] = options[prop];
11683
+ }
11684
+ });
11685
+ // If we don't have auth, ensure we have .portal
11686
+ if (!so_1.authentication) {
11687
+ so_1.portal = api.url + "/sharing/rest";
11266
11688
  }
11267
11689
  // Aggregations
11268
11690
  if ((_a = options.aggregations) === null || _a === void 0 ? void 0 : _a.length) {
11269
- so.countFields = options.aggregations.join(",");
11270
- so.countSize = 200;
11271
- }
11272
- // copy over various options
11273
- if (options.num) {
11274
- so.num = options.num;
11691
+ so_1.countFields = options.aggregations.join(",");
11692
+ so_1.countSize = 200;
11275
11693
  }
11276
- if (options.sortField) {
11277
- so.sortField = options.sortField;
11278
- }
11279
- if (options.sortOrder) {
11280
- so.sortOrder = options.sortOrder;
11281
- }
11282
- if (options.site) {
11283
- so.site = cloneObject$1(options.site);
11284
- }
11285
- searchPromise = searchPortal(so);
11694
+ searchPromise = searchPortal(so_1);
11286
11695
  }
11287
11696
  else {
11288
11697
  // Hub API Search
@@ -11354,33 +11763,30 @@
11354
11763
  */
11355
11764
  function _searchGroups(filter, options) {
11356
11765
  return __awaiter(this, void 0, void 0, function () {
11357
- var expanded, api, so;
11766
+ var expanded, api, so_1, props;
11358
11767
  return __generator(this, function (_a) {
11359
11768
  expanded = expandGroupFilter(filter);
11360
11769
  api = expandApi(options.api || "arcgis");
11361
11770
  if (api.type === "arcgis") {
11362
- so = serializeGroupFilterForPortal(expanded);
11363
- // if we have auth, pass it forward
11364
- // otherwise set the portal property
11365
- if (options.authentication) {
11366
- so.authentication = options.authentication;
11367
- }
11368
- else {
11369
- so.portal = api.url + "/sharing/rest";
11370
- }
11371
- if (options.num) {
11372
- so.num = options.num;
11373
- }
11374
- if (options.sortField) {
11375
- so.sortField = options.sortField;
11376
- }
11377
- if (options.sortOrder) {
11378
- so.sortOrder = options.sortOrder;
11379
- }
11380
- if (options.site) {
11381
- so.site = cloneObject$1(options.site);
11771
+ so_1 = serializeGroupFilterForPortal(expanded);
11772
+ props = [
11773
+ "authentication",
11774
+ "num",
11775
+ "sortField",
11776
+ "sortOrder",
11777
+ "site",
11778
+ ];
11779
+ // copy the props over
11780
+ props.forEach(function (prop) {
11781
+ if (options.hasOwnProperty(prop)) {
11782
+ so_1[prop] = options[prop];
11783
+ }
11784
+ });
11785
+ // If we don't have auth, ensure we have .portal
11786
+ if (!so_1.authentication) {
11787
+ so_1.portal = api.url + "/sharing/rest";
11382
11788
  }
11383
- return [2 /*return*/, searchPortalGroups(so)];
11789
+ return [2 /*return*/, searchPortalGroups(so_1)];
11384
11790
  }
11385
11791
  else {
11386
11792
  throw new Error("_searchGroups is not implemented for non-arcgis apis");
@@ -11441,7 +11847,7 @@
11441
11847
  */
11442
11848
  function _searchUsers(filter, options) {
11443
11849
  return __awaiter(this, void 0, void 0, function () {
11444
- var expanded, api, searchOptions;
11850
+ var expanded, api, searchOptions_1, props;
11445
11851
  return __generator(this, function (_a) {
11446
11852
  // JS Clients may not pass in authentication
11447
11853
  if (!options.authentication) {
@@ -11450,23 +11856,21 @@
11450
11856
  expanded = expandUserFilter(filter);
11451
11857
  api = expandApi(options.api || "arcgis");
11452
11858
  if (api.type === "arcgis") {
11453
- searchOptions = serializeUserFilterForPortal(expanded);
11454
- // carry the auth forward
11455
- searchOptions.authentication = options.authentication;
11456
- // TODO: Dry this up - typscript makes this... inconvenient
11457
- if (options.num) {
11458
- searchOptions.num = options.num;
11459
- }
11460
- if (options.sortField) {
11461
- searchOptions.sortField = options.sortField;
11462
- }
11463
- if (options.sortOrder) {
11464
- searchOptions.sortOrder = options.sortOrder;
11465
- }
11466
- if (options.site) {
11467
- searchOptions.site = cloneObject$1(options.site);
11468
- }
11469
- return [2 /*return*/, searchPortalUsers(searchOptions)];
11859
+ searchOptions_1 = serializeUserFilterForPortal(expanded);
11860
+ props = [
11861
+ "authentication",
11862
+ "num",
11863
+ "sortField",
11864
+ "sortOrder",
11865
+ "site",
11866
+ ];
11867
+ // copy the props over
11868
+ props.forEach(function (prop) {
11869
+ if (options.hasOwnProperty(prop)) {
11870
+ searchOptions_1[prop] = options[prop];
11871
+ }
11872
+ });
11873
+ return [2 /*return*/, searchPortalUsers(searchOptions_1)];
11470
11874
  }
11471
11875
  else {
11472
11876
  throw new Error("_searchUsers is not implemented for non-arcgis apis");
@@ -11822,6 +12226,23 @@
11822
12226
  return fetch(url, { method: "DELETE", headers: headers, mode: "cors" }).then(_checkStatusAndParseJson);
11823
12227
  }
11824
12228
 
12229
+ /**
12230
+ * Remove all domain entries by site id.
12231
+ * User must be a member of the org that owns the domain entry.
12232
+ * @param {int} domainSiteId of the domain entries to remove
12233
+ * @param {IHubRequestOptions} hubRequestOptions`dom
12234
+ */
12235
+ function removeDomainsBySiteId(domainSiteId, hubRequestOptions) {
12236
+ // TODO: Can remove this if no longer required
12237
+ if (hubRequestOptions.isPortal) {
12238
+ throw new Error("removeDomainsBySiteId is not available in ArcGIS Enterprise. Instead, edit the hubdomain typekeyword on the item");
12239
+ }
12240
+ var headers = _getAuthHeader(hubRequestOptions);
12241
+ headers["Content-Type"] = "application/json";
12242
+ var url = _getDomainServiceUrl(hubRequestOptions.hubApiUrl) + "/?siteId=" + domainSiteId;
12243
+ return fetch(url, { method: "DELETE", headers: headers, mode: "cors" }).then(_checkStatusAndParseJson);
12244
+ }
12245
+
11825
12246
  /**
11826
12247
  * Update an entry in the domain system
11827
12248
  * @param {IHubDomain} domainEntry Doman object to be updated
@@ -12739,6 +13160,7 @@
12739
13160
  exports.cloneObject = cloneObject$1;
12740
13161
  exports.completeOAuth2 = completeOAuth2;
12741
13162
  exports.compose = compose;
13163
+ exports.composeContent = composeContent;
12742
13164
  exports.constructSlug = constructSlug;
12743
13165
  exports.convertContentDefinitionToFilter = convertContentDefinitionToFilter;
12744
13166
  exports.convertContentFilterToSearchOptions = convertContentFilterToSearchOptions;
@@ -12791,7 +13213,6 @@
12791
13213
  exports.flattenArray = flattenArray;
12792
13214
  exports.generateRandomString = generateRandomString;
12793
13215
  exports.getCategory = getCategory;
12794
- exports.getCollection = getCollection;
12795
13216
  exports.getContentIdentifier = getContentIdentifier;
12796
13217
  exports.getContentSiteUrls = getContentSiteUrls;
12797
13218
  exports.getContentTypeIcon = getContentTypeIcon;
@@ -12828,6 +13249,7 @@
12828
13249
  exports.getPortalApiUrl = getPortalApiUrl;
12829
13250
  exports.getPortalBaseFromOrgUrl = getPortalBaseFromOrgUrl;
12830
13251
  exports.getPortalUrl = getPortalUrl;
13252
+ exports.getPortalUrls = getPortalUrls;
12831
13253
  exports.getProp = getProp;
12832
13254
  exports.getProps = getProps;
12833
13255
  exports.getProxyUrl = getProxyUrl;
@@ -12895,6 +13317,7 @@
12895
13317
  exports.relativeDateToDateRange = relativeDateToDateRange;
12896
13318
  exports.removeContextFromSlug = removeContextFromSlug;
12897
13319
  exports.removeDomain = removeDomain;
13320
+ exports.removeDomainsBySiteId = removeDomainsBySiteId;
12898
13321
  exports.removeEmptyProps = removeEmptyProps;
12899
13322
  exports.replaceItemId = replaceItemId;
12900
13323
  exports.runRevertableTask = runRevertableTask;