@esri/hub-common 9.1.3 → 9.4.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.
- package/dist/es2017/content.js +127 -19
- package/dist/es2017/content.js.map +1 -1
- package/dist/es2017/search/_searchContent.js +62 -0
- package/dist/es2017/search/_searchContent.js.map +1 -0
- package/dist/es2017/search/content-utils.js +422 -0
- package/dist/es2017/search/content-utils.js.map +1 -0
- package/dist/es2017/search/index.js +4 -0
- package/dist/es2017/search/index.js.map +1 -1
- package/dist/es2017/search/types.js +1 -0
- package/dist/es2017/search/types.js.map +1 -0
- package/dist/es2017/search/utils.js +344 -0
- package/dist/es2017/search/utils.js.map +1 -0
- package/dist/esm/content.js +129 -19
- package/dist/esm/content.js.map +1 -1
- package/dist/esm/search/_searchContent.js +70 -0
- package/dist/esm/search/_searchContent.js.map +1 -0
- package/dist/esm/search/content-utils.js +426 -0
- package/dist/esm/search/content-utils.js.map +1 -0
- package/dist/esm/search/index.js +4 -0
- package/dist/esm/search/index.js.map +1 -1
- package/dist/esm/search/types.js +1 -0
- package/dist/esm/search/types.js.map +1 -0
- package/dist/esm/search/utils.js +341 -0
- package/dist/esm/search/utils.js.map +1 -0
- package/dist/node/content.js +128 -20
- package/dist/node/content.js.map +1 -1
- package/dist/node/search/_searchContent.js +66 -0
- package/dist/node/search/_searchContent.js.map +1 -0
- package/dist/node/search/content-utils.js +432 -0
- package/dist/node/search/content-utils.js.map +1 -0
- package/dist/node/search/index.js +4 -0
- package/dist/node/search/index.js.map +1 -1
- package/dist/node/search/types.js +3 -0
- package/dist/node/search/types.js.map +1 -0
- package/dist/node/search/utils.js +357 -0
- package/dist/node/search/utils.js.map +1 -0
- package/dist/types/content.d.ts +23 -0
- package/dist/types/search/_searchContent.d.ts +7 -0
- package/dist/types/search/content-utils.d.ts +70 -0
- package/dist/types/search/index.d.ts +4 -0
- package/dist/types/search/types.d.ts +294 -0
- package/dist/types/search/utils.d.ts +92 -0
- package/dist/umd/common.umd.js +992 -25
- package/dist/umd/common.umd.js.map +1 -1
- package/dist/umd/common.umd.min.js +1 -1
- package/dist/umd/common.umd.min.js.map +1 -1
- package/package.json +3 -3
package/dist/umd/common.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* @preserve
|
|
2
|
-
* @esri/hub-common - v9.
|
|
2
|
+
* @esri/hub-common - v9.3.0 - Thu Oct 28 2021 14:17:26 GMT-0600 (Mountain Daylight Time)
|
|
3
3
|
* Copyright (c) 2021 Environmental Systems Research Institute, Inc.
|
|
4
4
|
* Apache-2.0
|
|
5
5
|
*/
|
|
@@ -2637,14 +2637,27 @@
|
|
|
2637
2637
|
options = {
|
|
2638
2638
|
httpMethod: "GET",
|
|
2639
2639
|
params: {
|
|
2640
|
-
q: search
|
|
2641
|
-
}
|
|
2640
|
+
q: search,
|
|
2641
|
+
},
|
|
2642
2642
|
};
|
|
2643
2643
|
}
|
|
2644
2644
|
else {
|
|
2645
2645
|
// searchUserAccess has one (knonw) valid value: "groupMember"
|
|
2646
|
-
options = appendCustomParams(search, [
|
|
2647
|
-
|
|
2646
|
+
options = appendCustomParams(search, [
|
|
2647
|
+
"q",
|
|
2648
|
+
"num",
|
|
2649
|
+
"start",
|
|
2650
|
+
"sortField",
|
|
2651
|
+
"sortOrder",
|
|
2652
|
+
"searchUserAccess",
|
|
2653
|
+
"searchUserName",
|
|
2654
|
+
"filter",
|
|
2655
|
+
"countFields",
|
|
2656
|
+
"countSize",
|
|
2657
|
+
"categories",
|
|
2658
|
+
"categoryFilters",
|
|
2659
|
+
], {
|
|
2660
|
+
httpMethod: "GET",
|
|
2648
2661
|
});
|
|
2649
2662
|
}
|
|
2650
2663
|
var path;
|
|
@@ -2682,7 +2695,7 @@
|
|
|
2682
2695
|
search instanceof SearchQueryBuilder) {
|
|
2683
2696
|
newOptions = {
|
|
2684
2697
|
q: search,
|
|
2685
|
-
start: r.nextStart
|
|
2698
|
+
start: r.nextStart,
|
|
2686
2699
|
};
|
|
2687
2700
|
}
|
|
2688
2701
|
else {
|
|
@@ -5611,14 +5624,11 @@
|
|
|
5611
5624
|
// site data instead. Because this one is the original one that was used
|
|
5612
5625
|
// to create the page url (not mutable once created) and the slug (below)
|
|
5613
5626
|
// generated by the hub-indexer could simply change with page name.
|
|
5614
|
-
|
|
5615
|
-
// In the future, the site object will have a site.isPortal() function that we can leverage
|
|
5616
|
-
// instead of hardcoding the types here.
|
|
5617
|
-
if (includes(["Hub Page", "Site Page"], content.type)) {
|
|
5627
|
+
if (isPageContent(content)) {
|
|
5618
5628
|
// check if the page is linked to the current site
|
|
5619
5629
|
var pages = getProp(site, "data.values.pages") || [];
|
|
5620
|
-
var page = pages.find(function (p) { return p.id === content.id; });
|
|
5621
5630
|
// if so, return the page slug otherwise the page id
|
|
5631
|
+
var page = pages.find(function (p) { return p.id === content.id; });
|
|
5622
5632
|
return page ? page.slug : content.id;
|
|
5623
5633
|
}
|
|
5624
5634
|
// If a slug is present, always return it
|
|
@@ -5781,8 +5791,8 @@
|
|
|
5781
5791
|
var createdDate = new Date(item.created);
|
|
5782
5792
|
var createdDateSource = "item.created";
|
|
5783
5793
|
var properties = item.properties;
|
|
5784
|
-
var normalizedType = normalizeItemType(item);
|
|
5785
5794
|
var content = Object.assign({}, item, {
|
|
5795
|
+
identifier: item.id,
|
|
5786
5796
|
// no server errors when fetching the item directly
|
|
5787
5797
|
errors: [],
|
|
5788
5798
|
// store a reference to the item
|
|
@@ -5792,10 +5802,8 @@
|
|
|
5792
5802
|
// presumably there to use as the default file name when downloading
|
|
5793
5803
|
// we don't store item.name in the Hub API and we use name for title
|
|
5794
5804
|
name: item.title,
|
|
5795
|
-
family: getFamily(normalizedType),
|
|
5796
5805
|
// TODO: hubType is no longer used, remove it at next breaking change
|
|
5797
5806
|
hubType: getItemHubType(item),
|
|
5798
|
-
normalizedType: normalizedType,
|
|
5799
5807
|
categories: parseItemCategories(item.categories),
|
|
5800
5808
|
itemCategories: item.categories,
|
|
5801
5809
|
// can we strip HTML from description, and do we need to trim it to a X chars?
|
|
@@ -5825,7 +5833,7 @@
|
|
|
5825
5833
|
updatedDateSource: "item.modified",
|
|
5826
5834
|
structuredLicense: getStructuredLicense(item.licenseInfo),
|
|
5827
5835
|
});
|
|
5828
|
-
return content;
|
|
5836
|
+
return setContentType(content, item.type);
|
|
5829
5837
|
}
|
|
5830
5838
|
/**
|
|
5831
5839
|
* Convert a Hub API dataset resource to Hub Content
|
|
@@ -5835,17 +5843,14 @@
|
|
|
5835
5843
|
* @export
|
|
5836
5844
|
*/
|
|
5837
5845
|
function datasetToContent(dataset) {
|
|
5838
|
-
// extract item from dataset, create content
|
|
5846
|
+
// extract item from dataset, create content from the item
|
|
5839
5847
|
var item = datasetToItem(dataset);
|
|
5840
5848
|
var content = itemToContent(item);
|
|
5841
|
-
content.item = item;
|
|
5842
5849
|
// We remove these because the indexer doesn't actually
|
|
5843
5850
|
// preserve the original item categories so this attribute is invalid
|
|
5844
5851
|
delete content.itemCategories;
|
|
5845
|
-
// overwrite hubId
|
|
5846
|
-
content.hubId = dataset.id;
|
|
5847
5852
|
// overwrite or add enrichments from Hub API
|
|
5848
|
-
var attributes = dataset.attributes;
|
|
5853
|
+
var hubId = dataset.id, attributes = dataset.attributes;
|
|
5849
5854
|
var
|
|
5850
5855
|
// common enrichments
|
|
5851
5856
|
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,
|
|
@@ -5866,10 +5871,6 @@
|
|
|
5866
5871
|
// NOTE: for layers and tables the Hub API returns the layer type
|
|
5867
5872
|
// ("Feature Layer", "Table", "Raster Layer") instead of the item type
|
|
5868
5873
|
type = attributes.type;
|
|
5869
|
-
// use the type returned by the API (i.e. possibly layer.type)
|
|
5870
|
-
content.type = type;
|
|
5871
|
-
content.normalizedType = normalizeItemType(__assign(__assign({}, content.item), { type: type }));
|
|
5872
|
-
content.family = getFamily(type);
|
|
5873
5874
|
// NOTE: we could throw or return if there are errors
|
|
5874
5875
|
// to prevent type errors trying to read properties below
|
|
5875
5876
|
content.errors = errors;
|
|
@@ -5913,7 +5914,9 @@
|
|
|
5913
5914
|
extent: orgExtent,
|
|
5914
5915
|
};
|
|
5915
5916
|
}
|
|
5916
|
-
return content
|
|
5917
|
+
// return a content with updated hubId and type
|
|
5918
|
+
// along w/ related properties like identifier, family, etc
|
|
5919
|
+
return setContentType(setContentHubId(content, hubId), type);
|
|
5917
5920
|
}
|
|
5918
5921
|
/**
|
|
5919
5922
|
* Convert a Hub API dataset resource to a portal item
|
|
@@ -6020,6 +6023,126 @@
|
|
|
6020
6023
|
scoreCompleteness: scoreCompleteness,
|
|
6021
6024
|
};
|
|
6022
6025
|
}
|
|
6026
|
+
/**
|
|
6027
|
+
* retunrs a new content that has the specified type and
|
|
6028
|
+
* and updated related properties like normalizedType, family, etc
|
|
6029
|
+
* @param content orignal content
|
|
6030
|
+
* @param type new type
|
|
6031
|
+
* @returns new content
|
|
6032
|
+
*/
|
|
6033
|
+
var setContentType = function (content, type) {
|
|
6034
|
+
// get family and normalized type based on new type
|
|
6035
|
+
var family = getFamily(type);
|
|
6036
|
+
var normalizedType = normalizeItemType(__assign(__assign({}, content.item), { type: type }));
|
|
6037
|
+
var updated = __assign(__assign({}, content), { type: type, family: family, normalizedType: normalizedType });
|
|
6038
|
+
// update the relative URL to the content
|
|
6039
|
+
// which is based on type and family
|
|
6040
|
+
return appendContentUrls(updated, {
|
|
6041
|
+
relative: getContentRelativeUrl(updated),
|
|
6042
|
+
});
|
|
6043
|
+
};
|
|
6044
|
+
/**
|
|
6045
|
+
* retunrs a new content that has the specified hubId and updated identifier
|
|
6046
|
+
* @param content orignal content
|
|
6047
|
+
* @param hubId new hubId
|
|
6048
|
+
* @returns new content
|
|
6049
|
+
*/
|
|
6050
|
+
var setContentHubId = function (content, hubId) {
|
|
6051
|
+
var id = content.id, slug = content.slug;
|
|
6052
|
+
// get the identifier which is based on hubId
|
|
6053
|
+
var identifier = slug || hubId || id;
|
|
6054
|
+
var updated = __assign(__assign({}, content), { hubId: hubId, identifier: identifier });
|
|
6055
|
+
// update the relative URL to the content
|
|
6056
|
+
// which is based on identifier
|
|
6057
|
+
return appendContentUrls(updated, {
|
|
6058
|
+
relative: getContentRelativeUrl(updated),
|
|
6059
|
+
});
|
|
6060
|
+
};
|
|
6061
|
+
/**
|
|
6062
|
+
* append the absolute URL to the content on the site
|
|
6063
|
+
* also updates the relative URL in case the
|
|
6064
|
+
* @param content
|
|
6065
|
+
* @param siteModel
|
|
6066
|
+
* @returns
|
|
6067
|
+
*/
|
|
6068
|
+
var setContentSiteUrls = function (content, siteModel) {
|
|
6069
|
+
// recompute relative URL using a site specific identifier
|
|
6070
|
+
var siteIdentifier = getContentIdentifier(content, siteModel);
|
|
6071
|
+
var relative = getContentRelativeUrl(content, siteIdentifier);
|
|
6072
|
+
// get the absolute URL to this content on the site
|
|
6073
|
+
var siteUrl = getProp(siteModel, "item.url").replace(/\/$/, "");
|
|
6074
|
+
var site = "" + siteUrl + relative;
|
|
6075
|
+
// append the updated URLs to a new content
|
|
6076
|
+
return appendContentUrls(content, {
|
|
6077
|
+
relative: relative,
|
|
6078
|
+
site: site,
|
|
6079
|
+
});
|
|
6080
|
+
};
|
|
6081
|
+
// URL helpers
|
|
6082
|
+
var appendContentUrls = function (content, newUrls) {
|
|
6083
|
+
// merge new urls into existing ones and return a new content
|
|
6084
|
+
var urls = __assign(__assign({}, content.urls), newUrls);
|
|
6085
|
+
return __assign(__assign({}, content), { urls: urls });
|
|
6086
|
+
};
|
|
6087
|
+
var getContentRelativeUrl = function (content, siteIdentifier) {
|
|
6088
|
+
var family = content.family;
|
|
6089
|
+
// prefer site specific identifier if passed in
|
|
6090
|
+
var identifier = siteIdentifier || content.identifier;
|
|
6091
|
+
// solution types have their own logic
|
|
6092
|
+
var contentUrl = getSolutionUrl(content);
|
|
6093
|
+
if (!contentUrl) {
|
|
6094
|
+
var pluralizedFamilies = [
|
|
6095
|
+
"app",
|
|
6096
|
+
"dataset",
|
|
6097
|
+
"document",
|
|
6098
|
+
"map",
|
|
6099
|
+
"template",
|
|
6100
|
+
];
|
|
6101
|
+
// default to the catchall content route
|
|
6102
|
+
var path = "/content";
|
|
6103
|
+
if (content.family === "feedback") {
|
|
6104
|
+
// exception
|
|
6105
|
+
path = "/feedback/surveys";
|
|
6106
|
+
}
|
|
6107
|
+
else if (isPageContent(content)) {
|
|
6108
|
+
// pages are in the document family,
|
|
6109
|
+
// but instead of showing the page's metadata on /documents/about
|
|
6110
|
+
// but we render the page on the pages route
|
|
6111
|
+
path = "/pages";
|
|
6112
|
+
}
|
|
6113
|
+
else if (pluralizedFamilies.indexOf(family) > -1) {
|
|
6114
|
+
// the rule
|
|
6115
|
+
path = "/" + family + "s";
|
|
6116
|
+
}
|
|
6117
|
+
contentUrl = path + "/" + identifier;
|
|
6118
|
+
}
|
|
6119
|
+
return contentUrl;
|
|
6120
|
+
};
|
|
6121
|
+
var getSolutionUrl = function (content) {
|
|
6122
|
+
var _a;
|
|
6123
|
+
var hubUrl;
|
|
6124
|
+
var normalizedType = content.normalizedType, identifier = content.identifier;
|
|
6125
|
+
if (normalizedType === "Solution") {
|
|
6126
|
+
// NOTE: as per the above spreadsheet,
|
|
6127
|
+
// solution types are now in the Template family
|
|
6128
|
+
// but we don't send them to the route for initiative templates
|
|
6129
|
+
if (((_a = content.typeKeywords) === null || _a === void 0 ? void 0 : _a.indexOf("Deployed")) > 0) {
|
|
6130
|
+
// deployed solutions go to the generic content route
|
|
6131
|
+
hubUrl = "/content/" + identifier;
|
|
6132
|
+
}
|
|
6133
|
+
// others go to the solution about route
|
|
6134
|
+
hubUrl = "/templates/" + identifier + "/about";
|
|
6135
|
+
}
|
|
6136
|
+
return hubUrl;
|
|
6137
|
+
};
|
|
6138
|
+
// page helpers
|
|
6139
|
+
// TODO: we check both "Hub Page" and "Site Page" because we don't know whether the site is a portal or not
|
|
6140
|
+
// In the future, the site object will have a site.isPortal() function that we can leverage
|
|
6141
|
+
// instead of hardcoding the types here.
|
|
6142
|
+
// TODO: should this be based on normalizedType instead?
|
|
6143
|
+
var isPageContent = function (content) {
|
|
6144
|
+
return includes(["Hub Page", "Site Page"], content.type);
|
|
6145
|
+
};
|
|
6023
6146
|
|
|
6024
6147
|
/**
|
|
6025
6148
|
* Implementation of atob() according to the HTML and Infra specs, except that
|
|
@@ -7856,6 +7979,828 @@
|
|
|
7856
7979
|
return hubApiRequest("/search", __assign(__assign({}, defaults), requestOptions));
|
|
7857
7980
|
}
|
|
7858
7981
|
|
|
7982
|
+
/* Copyright (c) 2018-2021 Environmental Systems Research Institute, Inc.
|
|
7983
|
+
* Apache-2.0 */
|
|
7984
|
+
/**
|
|
7985
|
+
* Well known APIs
|
|
7986
|
+
* Short-forms for specifying common APIs
|
|
7987
|
+
*/
|
|
7988
|
+
var SEARCH_APIS = {
|
|
7989
|
+
arcgis: {
|
|
7990
|
+
label: "ArcGIS Online",
|
|
7991
|
+
url: "https://www.arcgis.com",
|
|
7992
|
+
type: "arcgis",
|
|
7993
|
+
},
|
|
7994
|
+
arcgisQA: {
|
|
7995
|
+
label: "ArcGIS Online QAEXT",
|
|
7996
|
+
url: "https://qaext.arcgis.com",
|
|
7997
|
+
type: "arcgis",
|
|
7998
|
+
},
|
|
7999
|
+
arcgisDEV: {
|
|
8000
|
+
label: "ArcGIS Online DEVEXT",
|
|
8001
|
+
url: "https://devext.arcgis.com",
|
|
8002
|
+
type: "arcgis",
|
|
8003
|
+
},
|
|
8004
|
+
hub: {
|
|
8005
|
+
label: "ArcGIS Hub",
|
|
8006
|
+
url: "https://hub.arcgis.com/api",
|
|
8007
|
+
type: "arcgis-hub",
|
|
8008
|
+
},
|
|
8009
|
+
hubDEV: {
|
|
8010
|
+
label: "ArcGIS Hub DEV",
|
|
8011
|
+
url: "https://hubdev.arcgis.com/api",
|
|
8012
|
+
type: "arcgis-hub",
|
|
8013
|
+
},
|
|
8014
|
+
hubQA: {
|
|
8015
|
+
label: "ArcGIS Hub QA",
|
|
8016
|
+
url: "https://hubqa.arcgis.com/api",
|
|
8017
|
+
type: "arcgis-hub",
|
|
8018
|
+
},
|
|
8019
|
+
};
|
|
8020
|
+
/**
|
|
8021
|
+
* @private
|
|
8022
|
+
* Convert api "names" into full ApiDefinitions
|
|
8023
|
+
* @param apis
|
|
8024
|
+
* @returns
|
|
8025
|
+
*/
|
|
8026
|
+
function expandApis(apis) {
|
|
8027
|
+
return apis.map(function (api) {
|
|
8028
|
+
if (typeof api === "string" && api in SEARCH_APIS) {
|
|
8029
|
+
return SEARCH_APIS[api];
|
|
8030
|
+
}
|
|
8031
|
+
else {
|
|
8032
|
+
// it's an object, so we trust that it's well formed
|
|
8033
|
+
return api;
|
|
8034
|
+
}
|
|
8035
|
+
});
|
|
8036
|
+
}
|
|
8037
|
+
/**
|
|
8038
|
+
* @private
|
|
8039
|
+
* Merge multiple search responses
|
|
8040
|
+
*
|
|
8041
|
+
* Naieve implementation that just merges arrays
|
|
8042
|
+
* @param responses
|
|
8043
|
+
* @returns
|
|
8044
|
+
*/
|
|
8045
|
+
function mergeSearchResults(responses) {
|
|
8046
|
+
// Merge content
|
|
8047
|
+
var content = responses.reduce(function (acc, response) {
|
|
8048
|
+
if (response.content) {
|
|
8049
|
+
acc = acc.concat(response.content);
|
|
8050
|
+
}
|
|
8051
|
+
return acc;
|
|
8052
|
+
}, []);
|
|
8053
|
+
// Merge Facets
|
|
8054
|
+
var facets = responses.reduce(function (acc, response) {
|
|
8055
|
+
if (response.facets) {
|
|
8056
|
+
acc = acc.concat(response.facets);
|
|
8057
|
+
}
|
|
8058
|
+
return acc;
|
|
8059
|
+
}, []);
|
|
8060
|
+
return { content: content, facets: facets };
|
|
8061
|
+
}
|
|
8062
|
+
/**
|
|
8063
|
+
* @private
|
|
8064
|
+
* Merge two date ranges by taking the longest span
|
|
8065
|
+
* @param dr1
|
|
8066
|
+
* @param dr2
|
|
8067
|
+
* @returns
|
|
8068
|
+
*/
|
|
8069
|
+
function mergeDateRange(dr1, dr2) {
|
|
8070
|
+
var result = cloneObject$1(dr1);
|
|
8071
|
+
// feels like there is a more concise way to do this...
|
|
8072
|
+
if (dr2.from < dr1.from) {
|
|
8073
|
+
result.from = dr2.from;
|
|
8074
|
+
}
|
|
8075
|
+
if (dr2.to > dr1.to) {
|
|
8076
|
+
result.to = dr2.to;
|
|
8077
|
+
}
|
|
8078
|
+
return result;
|
|
8079
|
+
}
|
|
8080
|
+
/**
|
|
8081
|
+
* @private
|
|
8082
|
+
* Merge two [`MatchOptions`](../MatchOptions)
|
|
8083
|
+
*
|
|
8084
|
+
* Currently a naieve implementation where the arrays are simply merged
|
|
8085
|
+
*
|
|
8086
|
+
* @param mo1
|
|
8087
|
+
* @param mo2
|
|
8088
|
+
* @returns
|
|
8089
|
+
*/
|
|
8090
|
+
function mergeMatchOptions(mo1, mo2) {
|
|
8091
|
+
var result = {};
|
|
8092
|
+
// None of these props are required, so we can't just
|
|
8093
|
+
// use Object.keys/.entries
|
|
8094
|
+
var props = ["any", "all", "not", "exact"];
|
|
8095
|
+
props.forEach(function (prop) {
|
|
8096
|
+
var key = prop;
|
|
8097
|
+
var merged = __spreadArrays(getMatchValue(mo1, key), getMatchValue(mo2, key));
|
|
8098
|
+
if (merged.length) {
|
|
8099
|
+
// remove any dupes and set on the return
|
|
8100
|
+
result[key] = merged.filter(unique);
|
|
8101
|
+
}
|
|
8102
|
+
});
|
|
8103
|
+
return result;
|
|
8104
|
+
}
|
|
8105
|
+
/**
|
|
8106
|
+
* Get the value of a property on an IMatchOptions
|
|
8107
|
+
*
|
|
8108
|
+
* This is complex b/c all the props are optional, and
|
|
8109
|
+
* they could be a simple string, or an array of strings.
|
|
8110
|
+
*
|
|
8111
|
+
* This function normalizes all that and returns an array,
|
|
8112
|
+
* which may or may not be empty
|
|
8113
|
+
* @param option
|
|
8114
|
+
* @param key
|
|
8115
|
+
* @returns
|
|
8116
|
+
*/
|
|
8117
|
+
function getMatchValue(option, key) {
|
|
8118
|
+
var matchValue = [];
|
|
8119
|
+
if (option[key]) {
|
|
8120
|
+
var val = option[key];
|
|
8121
|
+
if (Array.isArray(val)) {
|
|
8122
|
+
matchValue = val;
|
|
8123
|
+
}
|
|
8124
|
+
else {
|
|
8125
|
+
matchValue = [val];
|
|
8126
|
+
}
|
|
8127
|
+
}
|
|
8128
|
+
return matchValue;
|
|
8129
|
+
}
|
|
8130
|
+
/**
|
|
8131
|
+
* @private
|
|
8132
|
+
* Convert a field value into a MatchOptions if it's not already one
|
|
8133
|
+
* @param value
|
|
8134
|
+
* @returns
|
|
8135
|
+
*/
|
|
8136
|
+
function valueToMatchOptions(value) {
|
|
8137
|
+
var result = {};
|
|
8138
|
+
if (Array.isArray(value)) {
|
|
8139
|
+
result = {
|
|
8140
|
+
any: value,
|
|
8141
|
+
};
|
|
8142
|
+
}
|
|
8143
|
+
else {
|
|
8144
|
+
if (typeof value === "string") {
|
|
8145
|
+
result = {
|
|
8146
|
+
any: [value],
|
|
8147
|
+
};
|
|
8148
|
+
}
|
|
8149
|
+
if (typeof value === "object") {
|
|
8150
|
+
result = value;
|
|
8151
|
+
}
|
|
8152
|
+
}
|
|
8153
|
+
return result;
|
|
8154
|
+
}
|
|
8155
|
+
/**
|
|
8156
|
+
* @private
|
|
8157
|
+
* Convert a RelativeDate to a DateRange<number>
|
|
8158
|
+
* @param relative
|
|
8159
|
+
* @returns
|
|
8160
|
+
*/
|
|
8161
|
+
function relativeDateToDateRange(relative) {
|
|
8162
|
+
// hash of offsets
|
|
8163
|
+
var offsetMs = {
|
|
8164
|
+
min: 1000 * 60,
|
|
8165
|
+
hours: 1000 * 60 * 60,
|
|
8166
|
+
days: 1000 * 60 * 60 * 24,
|
|
8167
|
+
weeks: 1000 * 60 * 60 * 24 * 7,
|
|
8168
|
+
};
|
|
8169
|
+
var now = new Date();
|
|
8170
|
+
// default
|
|
8171
|
+
var result = {
|
|
8172
|
+
type: "date-range",
|
|
8173
|
+
from: now.getTime(),
|
|
8174
|
+
to: now.getTime(),
|
|
8175
|
+
};
|
|
8176
|
+
//
|
|
8177
|
+
switch (relative.unit) {
|
|
8178
|
+
case "hours":
|
|
8179
|
+
case "days":
|
|
8180
|
+
case "weeks":
|
|
8181
|
+
result.from = result.to - offsetMs[relative.unit] * relative.num;
|
|
8182
|
+
break;
|
|
8183
|
+
case "months":
|
|
8184
|
+
// get the current month and subtract num
|
|
8185
|
+
now.setMonth(now.getMonth() - relative.num);
|
|
8186
|
+
result.from = now.getTime();
|
|
8187
|
+
break;
|
|
8188
|
+
case "years":
|
|
8189
|
+
now.setFullYear(now.getFullYear() - relative.num);
|
|
8190
|
+
result.from = now.getTime();
|
|
8191
|
+
break;
|
|
8192
|
+
}
|
|
8193
|
+
return result;
|
|
8194
|
+
}
|
|
8195
|
+
/**
|
|
8196
|
+
* @private
|
|
8197
|
+
* As a final `ISearchOptions` object gets created, many such objects are created, and
|
|
8198
|
+
* need to be systematically "merged" so as to return consistently structured `q` and `filter`
|
|
8199
|
+
* values.
|
|
8200
|
+
* @param so1
|
|
8201
|
+
* @param so2
|
|
8202
|
+
* @param join
|
|
8203
|
+
* @returns
|
|
8204
|
+
*/
|
|
8205
|
+
function mergeSearchOptions(so1, so2, join) {
|
|
8206
|
+
var result = cloneObject$1(so1);
|
|
8207
|
+
var q = so2.q, filter = so2.filter;
|
|
8208
|
+
if (q) {
|
|
8209
|
+
result.q = (result.q ? " (" + result.q + " " + join + " " + q + ")" : q).trim();
|
|
8210
|
+
}
|
|
8211
|
+
if (filter) {
|
|
8212
|
+
result.filter = (result.filter ? "(" + result.filter + " " + join + " " + filter + ")" : filter).trim();
|
|
8213
|
+
}
|
|
8214
|
+
return result;
|
|
8215
|
+
}
|
|
8216
|
+
/**
|
|
8217
|
+
* @private
|
|
8218
|
+
* Serialize a `MatchOptions` into `q` or `filter` on an `ISearchOptions`
|
|
8219
|
+
* @param key
|
|
8220
|
+
* @param opts
|
|
8221
|
+
* @returns
|
|
8222
|
+
*/
|
|
8223
|
+
function serializeMatchOptions(key, opts) {
|
|
8224
|
+
var result = {
|
|
8225
|
+
q: "",
|
|
8226
|
+
filter: "",
|
|
8227
|
+
};
|
|
8228
|
+
if (opts.exact) {
|
|
8229
|
+
// defined separately for refactoring later
|
|
8230
|
+
var userFilterableFields = [
|
|
8231
|
+
"username",
|
|
8232
|
+
"firstname",
|
|
8233
|
+
"lastname",
|
|
8234
|
+
"fullname",
|
|
8235
|
+
"email",
|
|
8236
|
+
];
|
|
8237
|
+
var itemFilterableFields = [
|
|
8238
|
+
"title",
|
|
8239
|
+
"tags",
|
|
8240
|
+
"typekeywords",
|
|
8241
|
+
"type",
|
|
8242
|
+
"name",
|
|
8243
|
+
"owner",
|
|
8244
|
+
];
|
|
8245
|
+
var groupFilterableFields = ["title", "typekeywords", "owner"];
|
|
8246
|
+
var filterableFields = __spreadArrays(userFilterableFields, itemFilterableFields, groupFilterableFields);
|
|
8247
|
+
if (filterableFields.includes(key)) {
|
|
8248
|
+
result.filter = serializeStringOrArray("AND", key, opts.exact);
|
|
8249
|
+
}
|
|
8250
|
+
else {
|
|
8251
|
+
// Treat it the same as .all
|
|
8252
|
+
if (typeof opts.exact === "string") {
|
|
8253
|
+
if (!opts.all) {
|
|
8254
|
+
opts.all = [];
|
|
8255
|
+
}
|
|
8256
|
+
if (typeof opts.all === "string") {
|
|
8257
|
+
opts.all = [opts.all];
|
|
8258
|
+
}
|
|
8259
|
+
opts.all.push(opts.exact);
|
|
8260
|
+
}
|
|
8261
|
+
if (Array.isArray(opts.exact)) {
|
|
8262
|
+
if (!opts.all) {
|
|
8263
|
+
opts.all = [];
|
|
8264
|
+
}
|
|
8265
|
+
if (typeof opts.all === "string") {
|
|
8266
|
+
opts.all = [opts.all];
|
|
8267
|
+
}
|
|
8268
|
+
opts.all = opts.all.concat(opts.exact);
|
|
8269
|
+
}
|
|
8270
|
+
}
|
|
8271
|
+
}
|
|
8272
|
+
// Handle the other props
|
|
8273
|
+
if (opts.any) {
|
|
8274
|
+
result.q = serializeStringOrArray("OR", key, opts.any);
|
|
8275
|
+
}
|
|
8276
|
+
if (opts.all) {
|
|
8277
|
+
result.q =
|
|
8278
|
+
(result.q ? result.q + " AND " : "") +
|
|
8279
|
+
serializeStringOrArray("AND", key, opts.all);
|
|
8280
|
+
}
|
|
8281
|
+
if (opts.not) {
|
|
8282
|
+
// negate the entries if they are not
|
|
8283
|
+
result.q =
|
|
8284
|
+
(result.q ? result.q + " AND " : "") +
|
|
8285
|
+
serializeStringOrArray("OR", "-" + key, opts.not);
|
|
8286
|
+
}
|
|
8287
|
+
return result;
|
|
8288
|
+
}
|
|
8289
|
+
/**
|
|
8290
|
+
* @private
|
|
8291
|
+
* Serialize a DateRange<number> into a Portal Query string
|
|
8292
|
+
* @param key
|
|
8293
|
+
* @param range
|
|
8294
|
+
* @returns
|
|
8295
|
+
*/
|
|
8296
|
+
function serializeDateRange(key, range) {
|
|
8297
|
+
return {
|
|
8298
|
+
q: key + ":[" + range.from + " TO " + range.to + "]",
|
|
8299
|
+
filter: "",
|
|
8300
|
+
};
|
|
8301
|
+
}
|
|
8302
|
+
/**
|
|
8303
|
+
* @private
|
|
8304
|
+
* Serialize a `string` or `string[]` into a string
|
|
8305
|
+
* @param join
|
|
8306
|
+
* @param key
|
|
8307
|
+
* @param value
|
|
8308
|
+
* @returns
|
|
8309
|
+
*/
|
|
8310
|
+
function serializeStringOrArray(join, key, value) {
|
|
8311
|
+
var q = "";
|
|
8312
|
+
if (Array.isArray(value)) {
|
|
8313
|
+
q = "(" + key + ":\"" + value.join("\" " + join + " " + key + ":\"") + "\")";
|
|
8314
|
+
}
|
|
8315
|
+
else {
|
|
8316
|
+
q = key + ":\"" + value + "\"";
|
|
8317
|
+
}
|
|
8318
|
+
return q;
|
|
8319
|
+
}
|
|
8320
|
+
|
|
8321
|
+
// TODO: Implement $dataset
|
|
8322
|
+
var ContentFilterExpansions = {
|
|
8323
|
+
$apps: [
|
|
8324
|
+
{
|
|
8325
|
+
type: {
|
|
8326
|
+
any: [
|
|
8327
|
+
"Code Sample",
|
|
8328
|
+
"Web Mapping Application",
|
|
8329
|
+
"Mobile Application",
|
|
8330
|
+
"Application",
|
|
8331
|
+
"Desktop Application Template",
|
|
8332
|
+
"Desktop Application",
|
|
8333
|
+
"Operation View",
|
|
8334
|
+
"Dashboard",
|
|
8335
|
+
"Operations Dashboard Extension",
|
|
8336
|
+
"Workforce Project",
|
|
8337
|
+
"Insights Workbook",
|
|
8338
|
+
"Insights Page",
|
|
8339
|
+
"Insights Model",
|
|
8340
|
+
"Hub Page",
|
|
8341
|
+
"Hub Initiative",
|
|
8342
|
+
"Hub Site Application",
|
|
8343
|
+
"StoryMap",
|
|
8344
|
+
"Web Experience",
|
|
8345
|
+
"Web Experience Template",
|
|
8346
|
+
"Form",
|
|
8347
|
+
],
|
|
8348
|
+
not: [
|
|
8349
|
+
"Code Attachment",
|
|
8350
|
+
"Featured Items",
|
|
8351
|
+
"Symbol Set",
|
|
8352
|
+
"Color Set",
|
|
8353
|
+
"Windows Viewer Add In",
|
|
8354
|
+
"Windows Viewer Configuration",
|
|
8355
|
+
"Map Area",
|
|
8356
|
+
"Indoors Map Configuration",
|
|
8357
|
+
],
|
|
8358
|
+
},
|
|
8359
|
+
typekeywords: {
|
|
8360
|
+
not: ["MapAreaPackage", "SMX"],
|
|
8361
|
+
},
|
|
8362
|
+
},
|
|
8363
|
+
],
|
|
8364
|
+
$storymap: [
|
|
8365
|
+
{
|
|
8366
|
+
type: "StoryMap",
|
|
8367
|
+
},
|
|
8368
|
+
{
|
|
8369
|
+
type: "Web Mapping Application",
|
|
8370
|
+
typekeywords: ["Story Map"],
|
|
8371
|
+
},
|
|
8372
|
+
],
|
|
8373
|
+
$dashboard: [
|
|
8374
|
+
{
|
|
8375
|
+
type: "Dashboard",
|
|
8376
|
+
typekeywords: {
|
|
8377
|
+
any: ["Dashboard"],
|
|
8378
|
+
not: ["ArcGIS Operation View", "Add In", "Extension"],
|
|
8379
|
+
},
|
|
8380
|
+
},
|
|
8381
|
+
],
|
|
8382
|
+
$dataset: [],
|
|
8383
|
+
$experience: [
|
|
8384
|
+
{
|
|
8385
|
+
type: {
|
|
8386
|
+
any: ["Web Experience"],
|
|
8387
|
+
not: ["Web Experience Template"],
|
|
8388
|
+
},
|
|
8389
|
+
},
|
|
8390
|
+
],
|
|
8391
|
+
$site: [
|
|
8392
|
+
{
|
|
8393
|
+
type: ["Hub Site Application", "Site Application"],
|
|
8394
|
+
},
|
|
8395
|
+
{
|
|
8396
|
+
type: ["Web Mapping Application"],
|
|
8397
|
+
typekeywords: ["hubSite"],
|
|
8398
|
+
},
|
|
8399
|
+
],
|
|
8400
|
+
$initiative: [
|
|
8401
|
+
{
|
|
8402
|
+
type: {
|
|
8403
|
+
any: "Hub Initiative",
|
|
8404
|
+
not: "Hub Initiative Template",
|
|
8405
|
+
},
|
|
8406
|
+
},
|
|
8407
|
+
],
|
|
8408
|
+
$document: [
|
|
8409
|
+
{
|
|
8410
|
+
typekeywords: {
|
|
8411
|
+
any: "Document",
|
|
8412
|
+
not: ["MapAreaPackage", "SMX"],
|
|
8413
|
+
},
|
|
8414
|
+
type: {
|
|
8415
|
+
any: [
|
|
8416
|
+
"Image",
|
|
8417
|
+
"Layout",
|
|
8418
|
+
"Desktop Style",
|
|
8419
|
+
"Project Template",
|
|
8420
|
+
"Report Template",
|
|
8421
|
+
"Pro Report",
|
|
8422
|
+
"Statistical Data Collection",
|
|
8423
|
+
"360 VR Experience",
|
|
8424
|
+
"netCDF",
|
|
8425
|
+
"PDF",
|
|
8426
|
+
"CSV",
|
|
8427
|
+
"Administrative Report",
|
|
8428
|
+
"Raster function template",
|
|
8429
|
+
],
|
|
8430
|
+
not: [
|
|
8431
|
+
"Image Service",
|
|
8432
|
+
"Explorer Document",
|
|
8433
|
+
"Explorer Map",
|
|
8434
|
+
"Globe Document",
|
|
8435
|
+
"Scene Document",
|
|
8436
|
+
"Code Attachment",
|
|
8437
|
+
"Featured Items",
|
|
8438
|
+
"Symbol Set",
|
|
8439
|
+
"ColorSet",
|
|
8440
|
+
"Windows Viewer Add In",
|
|
8441
|
+
"Windows Viewer Configuration",
|
|
8442
|
+
"Map Area",
|
|
8443
|
+
"Indoors Map Configuration",
|
|
8444
|
+
],
|
|
8445
|
+
},
|
|
8446
|
+
},
|
|
8447
|
+
],
|
|
8448
|
+
};
|
|
8449
|
+
/**
|
|
8450
|
+
* @private
|
|
8451
|
+
* Convert portal search response to items
|
|
8452
|
+
* @param response
|
|
8453
|
+
* @returns
|
|
8454
|
+
*/
|
|
8455
|
+
function convertPortalResponseToFacets(response) {
|
|
8456
|
+
var _a;
|
|
8457
|
+
var result = [];
|
|
8458
|
+
if ((_a = response.aggregations) === null || _a === void 0 ? void 0 : _a.counts) {
|
|
8459
|
+
response.aggregations.counts.forEach(function (entry) {
|
|
8460
|
+
var facet = {
|
|
8461
|
+
label: entry.fieldName,
|
|
8462
|
+
attribute: entry.fieldName,
|
|
8463
|
+
type: "multi-select",
|
|
8464
|
+
};
|
|
8465
|
+
var options = [];
|
|
8466
|
+
entry.fieldValues.forEach(function (fv) {
|
|
8467
|
+
var filter = {
|
|
8468
|
+
filterType: "content",
|
|
8469
|
+
};
|
|
8470
|
+
filter[entry.fieldName] = fv.value;
|
|
8471
|
+
var fo = {
|
|
8472
|
+
label: fv.value,
|
|
8473
|
+
value: fv.value,
|
|
8474
|
+
count: fv.count,
|
|
8475
|
+
selected: false,
|
|
8476
|
+
filter: filter,
|
|
8477
|
+
};
|
|
8478
|
+
options.push(fo);
|
|
8479
|
+
});
|
|
8480
|
+
facet.options = options;
|
|
8481
|
+
result.push(facet);
|
|
8482
|
+
});
|
|
8483
|
+
}
|
|
8484
|
+
return result;
|
|
8485
|
+
}
|
|
8486
|
+
/**
|
|
8487
|
+
* @private
|
|
8488
|
+
* Merge `Filter<"content">` objects
|
|
8489
|
+
* @param filters
|
|
8490
|
+
* @returns
|
|
8491
|
+
*/
|
|
8492
|
+
function mergeContentFilter(filters) {
|
|
8493
|
+
// expand all the filters so all prop types are consistent
|
|
8494
|
+
var expanded = filters.map(expandContentFilter);
|
|
8495
|
+
// now we can merge based on fields
|
|
8496
|
+
var dateFields = ["created", "modified"];
|
|
8497
|
+
var specialFields = __spreadArrays(["filterType", "subFilters"], dateFields);
|
|
8498
|
+
var result = expanded.reduce(function (acc, entry) {
|
|
8499
|
+
// process fields
|
|
8500
|
+
Object.entries(entry).forEach(function (_a) {
|
|
8501
|
+
var key = _a[0], value = _a[1];
|
|
8502
|
+
// MatchOption fields
|
|
8503
|
+
if (!specialFields.includes(key)) {
|
|
8504
|
+
if (acc[key]) {
|
|
8505
|
+
acc[key] = mergeMatchOptions(acc[key], value);
|
|
8506
|
+
}
|
|
8507
|
+
else {
|
|
8508
|
+
acc[key] = cloneObject$1(value);
|
|
8509
|
+
}
|
|
8510
|
+
}
|
|
8511
|
+
// Dates
|
|
8512
|
+
if (dateFields.includes(key)) {
|
|
8513
|
+
if (acc[key]) {
|
|
8514
|
+
acc[key] = mergeDateRange(acc[key], value);
|
|
8515
|
+
}
|
|
8516
|
+
else {
|
|
8517
|
+
acc[key] = cloneObject$1(value);
|
|
8518
|
+
}
|
|
8519
|
+
}
|
|
8520
|
+
// SubFilters
|
|
8521
|
+
if (key === "subFilters" && Array.isArray(value)) {
|
|
8522
|
+
if (acc.subFilters) {
|
|
8523
|
+
acc.subFilters = mergeSubFilters(acc.subFilters, value);
|
|
8524
|
+
}
|
|
8525
|
+
else {
|
|
8526
|
+
acc.subFilters = cloneObject$1(value);
|
|
8527
|
+
}
|
|
8528
|
+
}
|
|
8529
|
+
});
|
|
8530
|
+
return acc;
|
|
8531
|
+
}, {});
|
|
8532
|
+
result.filterType = "content";
|
|
8533
|
+
return result;
|
|
8534
|
+
}
|
|
8535
|
+
function mergeSubFilters(sf1, sf2) {
|
|
8536
|
+
// Simplistic implementation: we just merge the arrays
|
|
8537
|
+
// in the future we may try to de-dupe things as a safeguard
|
|
8538
|
+
return __spreadArrays(sf1, sf2);
|
|
8539
|
+
}
|
|
8540
|
+
/**
|
|
8541
|
+
* Prior to serialization into the query syntax for the backing APIs, we first expand [Filters](../Filter)
|
|
8542
|
+
*
|
|
8543
|
+
* Filter's can express their intent in a very terse form, but to ensure consistent
|
|
8544
|
+
* into their more verbose form.
|
|
8545
|
+
*
|
|
8546
|
+
* i.e. `title: "Water"` expands into `title: { any: ["Water"]}`
|
|
8547
|
+
*
|
|
8548
|
+
* - "well known" type values are expanded
|
|
8549
|
+
* - i.e. `type: "$storymap"` expands into two `subFilter` entries
|
|
8550
|
+
* - Fields defined as `string | string[] | MatchOptions` will be converted to a `MatchOptions`
|
|
8551
|
+
* - RelativeDate fields are converted to DateRange<number>
|
|
8552
|
+
*
|
|
8553
|
+
* @param filter
|
|
8554
|
+
* @returns
|
|
8555
|
+
*/
|
|
8556
|
+
function expandContentFilter(filter) {
|
|
8557
|
+
// Expand filter.type first
|
|
8558
|
+
var expandedTypeFilter = expandTypeField(filter);
|
|
8559
|
+
// Expand subfilters
|
|
8560
|
+
// Guard - JS Clients could send in anything...
|
|
8561
|
+
if (Array.isArray(filter.subFilters)) {
|
|
8562
|
+
// Convert any strings into the coresponding ContentFilterDefinition
|
|
8563
|
+
expandedTypeFilter.subFilters = expandedTypeFilter.subFilters.reduce(function (acc, entry) {
|
|
8564
|
+
if (typeof entry === "string") {
|
|
8565
|
+
// if the entry is not a key of ContentFilterExpansions
|
|
8566
|
+
// we just skip over it
|
|
8567
|
+
if (ContentFilterExpansions[entry]) {
|
|
8568
|
+
acc = acc.concat(ContentFilterExpansions[entry]);
|
|
8569
|
+
}
|
|
8570
|
+
}
|
|
8571
|
+
else {
|
|
8572
|
+
acc.push(entry); // should be a ContentFilterDefinition
|
|
8573
|
+
}
|
|
8574
|
+
return acc;
|
|
8575
|
+
}, []);
|
|
8576
|
+
}
|
|
8577
|
+
// Convert all props into MatchOptions/DateRanges
|
|
8578
|
+
return convertContentDefinitionToFilter(expandedTypeFilter);
|
|
8579
|
+
}
|
|
8580
|
+
/**
|
|
8581
|
+
* @private
|
|
8582
|
+
* Expand from a well-known "type" into it's longer form
|
|
8583
|
+
*
|
|
8584
|
+
* i.e. `type: "$storymap"` expands into two subFilters entries
|
|
8585
|
+
*
|
|
8586
|
+
* @param filter
|
|
8587
|
+
* @returns
|
|
8588
|
+
*/
|
|
8589
|
+
function expandTypeField(filter) {
|
|
8590
|
+
var clone = cloneObject$1(filter);
|
|
8591
|
+
// ensure subFilters is defined as an array
|
|
8592
|
+
clone.subFilters = clone.subFilters || [];
|
|
8593
|
+
if (clone.type) {
|
|
8594
|
+
// if .type is an Array...
|
|
8595
|
+
if (Array.isArray(clone.type)) {
|
|
8596
|
+
// remove any well-known-keys and move their expansions into subfilters
|
|
8597
|
+
clone.type = clone.type.reduce(function (acc, entry) {
|
|
8598
|
+
if (isWellKnownType(entry)) {
|
|
8599
|
+
// working with dynamic objects in typescript requires some assertions
|
|
8600
|
+
var key = entry;
|
|
8601
|
+
clone.subFilters = clone.subFilters.concat(lookupTypeFilters(key));
|
|
8602
|
+
}
|
|
8603
|
+
else {
|
|
8604
|
+
acc.push(entry);
|
|
8605
|
+
}
|
|
8606
|
+
return acc;
|
|
8607
|
+
}, []);
|
|
8608
|
+
}
|
|
8609
|
+
else if (isWellKnownType(clone.type)) {
|
|
8610
|
+
var key = clone.type;
|
|
8611
|
+
clone.subFilters = clone.subFilters.concat(lookupTypeFilters(key));
|
|
8612
|
+
delete clone.type;
|
|
8613
|
+
}
|
|
8614
|
+
else ;
|
|
8615
|
+
}
|
|
8616
|
+
return clone;
|
|
8617
|
+
}
|
|
8618
|
+
/**
|
|
8619
|
+
* Is the argument a well-known type "key"
|
|
8620
|
+
*
|
|
8621
|
+
* Accepts `string`, `string[]` or `IMatchOptions`
|
|
8622
|
+
* but only string values can possibly be properties
|
|
8623
|
+
* on `ContentFilterExpansions`
|
|
8624
|
+
* @param key
|
|
8625
|
+
* @returns
|
|
8626
|
+
*/
|
|
8627
|
+
function isWellKnownType(key) {
|
|
8628
|
+
var result = false;
|
|
8629
|
+
if (typeof key === "string") {
|
|
8630
|
+
result = key in ContentFilterExpansions;
|
|
8631
|
+
}
|
|
8632
|
+
return result;
|
|
8633
|
+
}
|
|
8634
|
+
function lookupTypeFilters(key) {
|
|
8635
|
+
return ContentFilterExpansions[key];
|
|
8636
|
+
}
|
|
8637
|
+
/**
|
|
8638
|
+
* @private
|
|
8639
|
+
* Convert a `ContentFilterDefinition` to a `ContentFilter`
|
|
8640
|
+
*
|
|
8641
|
+
* ContentFilter is a narrower version of ContentFilterDefinition, without
|
|
8642
|
+
* the union types. Using a ContentFilter makes working with the structure
|
|
8643
|
+
* in typescript much easier.
|
|
8644
|
+
*
|
|
8645
|
+
* @param filter
|
|
8646
|
+
* @returns
|
|
8647
|
+
*/
|
|
8648
|
+
function convertContentDefinitionToFilter(filter) {
|
|
8649
|
+
var result = {};
|
|
8650
|
+
if (filter.term) {
|
|
8651
|
+
result.term = filter.term;
|
|
8652
|
+
}
|
|
8653
|
+
var dateProps = ["created", "modified"];
|
|
8654
|
+
// Some properties should not get converted to MatchOptions
|
|
8655
|
+
var specialProps = __spreadArrays(["filterType", "subFilters", "term"], dateProps);
|
|
8656
|
+
// Do the conversion
|
|
8657
|
+
Object.entries(filter).forEach(function (_a) {
|
|
8658
|
+
var key = _a[0], value = _a[1];
|
|
8659
|
+
if (!specialProps.includes(key)) {
|
|
8660
|
+
result[key] = valueToMatchOptions(value);
|
|
8661
|
+
}
|
|
8662
|
+
});
|
|
8663
|
+
// Special Cases
|
|
8664
|
+
// subFilters; Array of ContentFilterDefinitions
|
|
8665
|
+
if (filter.subFilters && Array.isArray(filter.subFilters)) {
|
|
8666
|
+
// downcast - would be nice to skip this or use some other constuct
|
|
8667
|
+
var sf = filter.subFilters;
|
|
8668
|
+
result.subFilters = sf.map(convertContentDefinitionToFilter);
|
|
8669
|
+
}
|
|
8670
|
+
// Dates; Ensure they are all DateRange<number>
|
|
8671
|
+
dateProps.forEach(function (fld) {
|
|
8672
|
+
if (filter[fld]) {
|
|
8673
|
+
if (filter[fld].type === "relative-date") {
|
|
8674
|
+
result[fld] = relativeDateToDateRange(filter[fld]);
|
|
8675
|
+
}
|
|
8676
|
+
else {
|
|
8677
|
+
result[fld] = cloneObject$1(filter[fld]);
|
|
8678
|
+
}
|
|
8679
|
+
}
|
|
8680
|
+
});
|
|
8681
|
+
return result;
|
|
8682
|
+
}
|
|
8683
|
+
/**
|
|
8684
|
+
* @private
|
|
8685
|
+
* Serialize a `ContentFilter` into an `ISearchOptions` for use with `searchItems`
|
|
8686
|
+
* @param filter
|
|
8687
|
+
* @returns
|
|
8688
|
+
*/
|
|
8689
|
+
function serializeContentFilterForPortal(filter) {
|
|
8690
|
+
var searchOptions = convertContentFilterToSearchOptions(filter);
|
|
8691
|
+
if (filter.subFilters) {
|
|
8692
|
+
var subFilterOptions = filter.subFilters.reduce(function (acc, entry) {
|
|
8693
|
+
// Next guard is present b/c this can be used from javascript
|
|
8694
|
+
// but our tests are written in typescript which prevents us
|
|
8695
|
+
// from hitting the else
|
|
8696
|
+
/* istanbul ignore else */
|
|
8697
|
+
if (typeof entry === "object") {
|
|
8698
|
+
acc = mergeSearchOptions(acc, convertContentFilterToSearchOptions(entry), "OR");
|
|
8699
|
+
}
|
|
8700
|
+
return acc;
|
|
8701
|
+
}, { q: "", filter: "" });
|
|
8702
|
+
// merge with searchOptions using AND
|
|
8703
|
+
searchOptions = mergeSearchOptions(searchOptions, subFilterOptions, "AND");
|
|
8704
|
+
}
|
|
8705
|
+
// term is always last, and pre-pended on searchOptions.q
|
|
8706
|
+
if (filter.term) {
|
|
8707
|
+
searchOptions.q = (filter.term + " " + searchOptions.q).trim();
|
|
8708
|
+
}
|
|
8709
|
+
return searchOptions;
|
|
8710
|
+
}
|
|
8711
|
+
/**
|
|
8712
|
+
* @private
|
|
8713
|
+
* Convert a ContentFilter to a SearchOptions
|
|
8714
|
+
*
|
|
8715
|
+
* @param filter
|
|
8716
|
+
* @returns
|
|
8717
|
+
*/
|
|
8718
|
+
function convertContentFilterToSearchOptions(filter) {
|
|
8719
|
+
var result = {
|
|
8720
|
+
q: "",
|
|
8721
|
+
filter: "",
|
|
8722
|
+
};
|
|
8723
|
+
var dateProps = ["created", "modified"];
|
|
8724
|
+
var specialProps = __spreadArrays(["filterType", "subFilters", "term"], dateProps);
|
|
8725
|
+
Object.entries(filter).forEach(function (_a) {
|
|
8726
|
+
var key = _a[0], value = _a[1];
|
|
8727
|
+
// MatchOptions may go into either q or filter
|
|
8728
|
+
if (!specialProps.includes(key)) {
|
|
8729
|
+
result = mergeSearchOptions(result, serializeMatchOptions(key, value), "AND");
|
|
8730
|
+
}
|
|
8731
|
+
// Dates only go into q
|
|
8732
|
+
if (dateProps.includes(key)) {
|
|
8733
|
+
result = mergeSearchOptions(result, serializeDateRange(key, value), "AND");
|
|
8734
|
+
}
|
|
8735
|
+
});
|
|
8736
|
+
return result;
|
|
8737
|
+
}
|
|
8738
|
+
|
|
8739
|
+
/**
|
|
8740
|
+
* Search for content via the Portal or Hub API
|
|
8741
|
+
* @param filter
|
|
8742
|
+
* @param options
|
|
8743
|
+
*/
|
|
8744
|
+
function _searchContent(filter, options) {
|
|
8745
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
8746
|
+
var expanded, apis, searchPromises, results;
|
|
8747
|
+
return __generator(this, function (_a) {
|
|
8748
|
+
switch (_a.label) {
|
|
8749
|
+
case 0:
|
|
8750
|
+
expanded = expandContentFilter(filter);
|
|
8751
|
+
// APIs
|
|
8752
|
+
if (!options.apis) {
|
|
8753
|
+
// default to AGO PROD
|
|
8754
|
+
options.apis = ["arcgis"];
|
|
8755
|
+
}
|
|
8756
|
+
apis = expandApis(options.apis);
|
|
8757
|
+
searchPromises = apis.map(function (api) {
|
|
8758
|
+
var _a;
|
|
8759
|
+
// Portal Search
|
|
8760
|
+
if (api.type === "arcgis") {
|
|
8761
|
+
// serialize for portal
|
|
8762
|
+
var so = serializeContentFilterForPortal(expanded);
|
|
8763
|
+
// pass auth forward
|
|
8764
|
+
if (options.authentication) {
|
|
8765
|
+
so.authentication = options.authentication;
|
|
8766
|
+
}
|
|
8767
|
+
// Aggregations
|
|
8768
|
+
if ((_a = options.aggregations) === null || _a === void 0 ? void 0 : _a.length) {
|
|
8769
|
+
so.countFields = options.aggregations.join(",");
|
|
8770
|
+
so.countSize = 200;
|
|
8771
|
+
}
|
|
8772
|
+
if (options.num) {
|
|
8773
|
+
so.num = options.num;
|
|
8774
|
+
}
|
|
8775
|
+
return searchPortal(so);
|
|
8776
|
+
}
|
|
8777
|
+
else {
|
|
8778
|
+
// Hub API Search
|
|
8779
|
+
// TODO: Implement hub api content search
|
|
8780
|
+
return Promise.resolve({
|
|
8781
|
+
content: [],
|
|
8782
|
+
facets: [],
|
|
8783
|
+
});
|
|
8784
|
+
}
|
|
8785
|
+
});
|
|
8786
|
+
return [4 /*yield*/, Promise.all(searchPromises)];
|
|
8787
|
+
case 1:
|
|
8788
|
+
results = _a.sent();
|
|
8789
|
+
// merge and return
|
|
8790
|
+
return [2 /*return*/, mergeSearchResults(results)];
|
|
8791
|
+
}
|
|
8792
|
+
});
|
|
8793
|
+
});
|
|
8794
|
+
}
|
|
8795
|
+
function searchPortal(searchOptions) {
|
|
8796
|
+
return searchItems(searchOptions).then(function (resp) {
|
|
8797
|
+
var content = resp.results.map(itemToContent);
|
|
8798
|
+
// convert aggregations into facets
|
|
8799
|
+
var facets = convertPortalResponseToFacets(resp);
|
|
8800
|
+
return { content: content, facets: facets };
|
|
8801
|
+
});
|
|
8802
|
+
}
|
|
8803
|
+
|
|
7859
8804
|
/**
|
|
7860
8805
|
* Parse a response object, and throw if it contains an error.
|
|
7861
8806
|
* Just a wrapper to hide some platform idiosyncracies
|
|
@@ -9065,6 +10010,7 @@
|
|
|
9065
10010
|
exports.PORTAL_EXPORT_TYPES = PORTAL_EXPORT_TYPES;
|
|
9066
10011
|
exports.REQUIRED_PRIVS = REQUIRED_PRIVS;
|
|
9067
10012
|
exports.RemoteServerError = RemoteServerError;
|
|
10013
|
+
exports.SEARCH_APIS = SEARCH_APIS;
|
|
9068
10014
|
exports.SITE_SCHEMA_VERSION = SITE_SCHEMA_VERSION;
|
|
9069
10015
|
exports.STANDARD_LICENSES = STANDARD_LICENSES;
|
|
9070
10016
|
exports.WGS84_WKID = WGS84_WKID;
|
|
@@ -9095,6 +10041,7 @@
|
|
|
9095
10041
|
exports._processInvite = _processInvite;
|
|
9096
10042
|
exports._processPrimaryEmail = _processPrimaryEmail;
|
|
9097
10043
|
exports._processSecondaryEmail = _processSecondaryEmail;
|
|
10044
|
+
exports._searchContent = _searchContent;
|
|
9098
10045
|
exports._unprotectAndRemoveGroup = _unprotectAndRemoveGroup;
|
|
9099
10046
|
exports._unprotectAndRemoveItem = _unprotectAndRemoveItem;
|
|
9100
10047
|
exports.addContextToSlug = addContextToSlug;
|
|
@@ -9122,6 +10069,9 @@
|
|
|
9122
10069
|
exports.cloneObject = cloneObject$1;
|
|
9123
10070
|
exports.completeOAuth2 = completeOAuth2;
|
|
9124
10071
|
exports.compose = compose;
|
|
10072
|
+
exports.convertContentDefinitionToFilter = convertContentDefinitionToFilter;
|
|
10073
|
+
exports.convertContentFilterToSearchOptions = convertContentFilterToSearchOptions;
|
|
10074
|
+
exports.convertPortalResponseToFacets = convertPortalResponseToFacets;
|
|
9125
10075
|
exports.convertSolutionTemplateResourcesToAssets = convertSolutionTemplateResourcesToAssets;
|
|
9126
10076
|
exports.convertToWellKnownLocale = convertToWellKnownLocale;
|
|
9127
10077
|
exports.createExtent = createExtent;
|
|
@@ -9139,6 +10089,9 @@
|
|
|
9139
10089
|
exports.ensureProp = ensureProp;
|
|
9140
10090
|
exports.ensureUniqueDomainName = ensureUniqueDomainName;
|
|
9141
10091
|
exports.ensureUniqueString = ensureUniqueString;
|
|
10092
|
+
exports.expandApis = expandApis;
|
|
10093
|
+
exports.expandContentFilter = expandContentFilter;
|
|
10094
|
+
exports.expandTypeField = expandTypeField;
|
|
9142
10095
|
exports.extend = extend;
|
|
9143
10096
|
exports.extentToBBox = extentToBBox;
|
|
9144
10097
|
exports.failSafe = failSafe;
|
|
@@ -9226,7 +10179,12 @@
|
|
|
9226
10179
|
exports.mapBy = mapBy;
|
|
9227
10180
|
exports.maybeAdd = maybeAdd;
|
|
9228
10181
|
exports.maybePush = maybePush;
|
|
10182
|
+
exports.mergeContentFilter = mergeContentFilter;
|
|
10183
|
+
exports.mergeDateRange = mergeDateRange;
|
|
10184
|
+
exports.mergeMatchOptions = mergeMatchOptions;
|
|
9229
10185
|
exports.mergeObjects = mergeObjects;
|
|
10186
|
+
exports.mergeSearchOptions = mergeSearchOptions;
|
|
10187
|
+
exports.mergeSearchResults = mergeSearchResults;
|
|
9230
10188
|
exports.normalizeItemType = normalizeItemType;
|
|
9231
10189
|
exports.normalizeSolutionTemplateItem = normalizeSolutionTemplateItem;
|
|
9232
10190
|
exports.objectToArray = objectToArray;
|
|
@@ -9235,13 +10193,21 @@
|
|
|
9235
10193
|
exports.parseItemCategories = parseItemCategories;
|
|
9236
10194
|
exports.processRevertableTasks = processRevertableTasks;
|
|
9237
10195
|
exports.propifyString = propifyString;
|
|
10196
|
+
exports.relativeDateToDateRange = relativeDateToDateRange;
|
|
9238
10197
|
exports.removeContextFromSlug = removeContextFromSlug;
|
|
9239
10198
|
exports.removeDomain = removeDomain;
|
|
9240
10199
|
exports.removeEmptyProps = removeEmptyProps;
|
|
9241
10200
|
exports.replaceItemId = replaceItemId;
|
|
9242
10201
|
exports.runRevertableTask = runRevertableTask;
|
|
10202
|
+
exports.serializeContentFilterForPortal = serializeContentFilterForPortal;
|
|
10203
|
+
exports.serializeDateRange = serializeDateRange;
|
|
10204
|
+
exports.serializeMatchOptions = serializeMatchOptions;
|
|
9243
10205
|
exports.serializeModel = serializeModel;
|
|
9244
10206
|
exports.serializeSpatialReference = serializeSpatialReference;
|
|
10207
|
+
exports.serializeStringOrArray = serializeStringOrArray;
|
|
10208
|
+
exports.setContentHubId = setContentHubId;
|
|
10209
|
+
exports.setContentSiteUrls = setContentSiteUrls;
|
|
10210
|
+
exports.setContentType = setContentType;
|
|
9245
10211
|
exports.setProp = setProp;
|
|
9246
10212
|
exports.shareItemToGroups = shareItemToGroups;
|
|
9247
10213
|
exports.slugify = slugify;
|
|
@@ -9254,6 +10220,7 @@
|
|
|
9254
10220
|
exports.updateDomain = updateDomain;
|
|
9255
10221
|
exports.upgradeSiteSchema = upgradeSiteSchema;
|
|
9256
10222
|
exports.uploadResourcesFromUrl = uploadResourcesFromUrl;
|
|
10223
|
+
exports.valueToMatchOptions = valueToMatchOptions;
|
|
9257
10224
|
exports.without = without;
|
|
9258
10225
|
exports.withoutByProp = withoutByProp;
|
|
9259
10226
|
|