From cd81e8fd68f84644e4c5bc93efdfb32d377b0af4 Mon Sep 17 00:00:00 2001 From: Tom Wayson Date: Sun, 13 Jun 2021 21:00:35 -0700 Subject: [PATCH] feat(common): add isFeatureService, getLayerIdFromUrl, getItemLayerId, & getItemHubId affects: @esri/hub-common --- packages/common/src/content.ts | 54 ++++++++++++++++++- packages/common/test/content.test.ts | 81 +++++++++++++++++++++++++++- 2 files changed, 133 insertions(+), 2 deletions(-) diff --git a/packages/common/src/content.ts b/packages/common/src/content.ts index 91f510d17cc..f0af6ffba60 100644 --- a/packages/common/src/content.ts +++ b/packages/common/src/content.ts @@ -1,6 +1,6 @@ /* Copyright (c) 2019 Environmental Systems Research Institute, Inc. * Apache-2.0 */ - +import { IItem } from "@esri/arcgis-rest-portal"; import { collections } from "./collections"; import { categories } from "./categories"; import { includes } from "./utils"; @@ -138,3 +138,55 @@ export function getCollection(itemType: string = ""): string { } } } + +/** + * Case-insensitive check if the type is "Feature Service" + * @param {string} type - item's type + * @returns {boolean} + */ +export const isFeatureService = (type: string) => { + return type && type.toLowerCase() === "feature service"; +}; + +/** + * parse layer id from a service URL + * @param {string} url + * @returns {string} layer id + */ +export const getLayerIdFromUrl = (url: string) => { + const endsWithNumberSegmentRegEx = /\/\d+$/; + const matched = url && url.match(endsWithNumberSegmentRegEx); + return matched && matched[0].slice(1); +}; + +/** + * return the layerId if we can tell that item is a single layer service + * @param {*} item from AGO + * @returns {string} layer id + */ +export const getItemLayerId = (item: IItem) => { + // try to parse it from the URL, but failing that we check for + // the Singlelayer typeKeyword, which I think is set when you create the item in AGO + // but have not verified that, nor that we should alway return '0' in that case + return ( + getLayerIdFromUrl(item.url) || + (isFeatureService(item.type) && + includes(item.typeKeywords, "Singlelayer") && + "0") + ); +}; + +/** + * given an item, get the id to use w/ the Hub API + * @param item + * @returns Hub API id (hubId) + */ +export const getItemHubId = (item: IItem) => { + if (item.access !== "public") { + // the hub only indexes public items + return; + } + const id = item.id; + const layerId = getItemLayerId(item); + return layerId ? `${id}_${layerId}` : id; +}; diff --git a/packages/common/test/content.test.ts b/packages/common/test/content.test.ts index 1b8805001c2..0741f715bb1 100644 --- a/packages/common/test/content.test.ts +++ b/packages/common/test/content.test.ts @@ -3,7 +3,11 @@ import { getCollection, getTypes, getTypeCategories, - normalizeItemType + normalizeItemType, + isFeatureService, + getLayerIdFromUrl, + getItemLayerId, + getItemHubId } from "../src/content"; describe("getCollection", () => { @@ -108,3 +112,78 @@ describe("getTypeCategories", () => { expect(getTypeCategories()).toEqual(["Other"]); }); }); + +describe("isFeatureService", () => { + it("returns true when the type is Feature Service", () => { + expect(isFeatureService("Feature Service")).toBe(true); + expect(isFeatureService("feature service")).toBe(true); + }); + it("returns false when the type is not Feature Service", () => { + expect(isFeatureService("Map Service")).toBe(false); + }); +}); + +describe("getLayerIdFromUrl", () => { + it("returns layerId when present", () => { + expect( + getLayerIdFromUrl( + "https://services9.arcgis.com/BH6j7VrWdIXhhNYw/arcgis/rest/services/Befolkning_efter_k%C3%B6n/FeatureServer/0" + ) + ).toBe("0"); + }); + it("returns undefined when not present", () => { + expect( + getLayerIdFromUrl( + "https://services9.arcgis.com/BH6j7VrWdIXhhNYw/arcgis/rest/services/Befolkning_efter_k%C3%B6n/FeatureServer" + ) + ).toBe(null); + }); +}); + +describe("getLayerIdFromItem", () => { + it("returns '0' when typeKeywords includes 'Singlelayer'", () => { + const item: any = { + type: "Feature Service", + url: + "https://services9.arcgis.com/BH6j7VrWdIXhhNYw/arcgis/rest/services/Befolkning_efter_k%C3%B6n/FeatureServer", + typeKeywords: [ + "ArcGIS Server", + "Data", + "Feature Access", + "Feature Service", + "Metadata", + "Service", + "Singlelayer", + "Hosted Service" + ] + }; + expect(getItemLayerId(item)).toBe("0"); + }); +}); + +describe("getItemHubId", () => { + let layerItem: any; + beforeEach(() => { + layerItem = { + id: "4ef", + access: "shared", + type: "Feature Service", + url: + "https://services9.arcgis.com/BH6j7VrWdIXhhNYw/arcgis/rest/services/Befolkning_efter_k%C3%B6n/FeatureServer/42" + }; + }); + it("returns undefined when not public", () => { + expect(getItemHubId(layerItem)).toBeFalsy(); + }); + it("returns itemId_layerId when public layer", () => { + layerItem.access = "public"; + expect(getItemHubId(layerItem)).toBe("4ef_42"); + }); + it("returns item id when public non-layer", () => { + const item: any = { + id: "3ec", + access: "public" + }; + expect(getItemHubId(item)).toBe("3ec"); + }); +});