@trackunit/iris-app-api 2.3.10 → 2.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/CHANGELOG.md +10 -0
- package/migrations/entry.js.map +1 -0
- package/migrations/v2-4-0/add-ai-navigation.js +197 -0
- package/migrations/v2-4-0/add-ai-navigation.js.map +1 -0
- package/migrations.json +7 -1
- package/package.json +1 -1
- package/src/index.d.ts +4 -0
- package/src/index.js +4 -0
- package/src/index.js.map +1 -0
- package/src/types/aiNavigableExtension.d.ts +35 -0
- package/src/types/aiNavigableExtension.js +50 -0
- package/src/types/aiNavigableExtension.js.map +1 -0
- package/src/types/cspDirectives.js.map +1 -0
- package/src/types/defaultValidHosts.js.map +1 -0
- package/src/types/extensions/adminExtensionManifest.d.ts +2 -1
- package/src/types/extensions/adminExtensionManifest.js.map +1 -0
- package/src/types/extensions/assetEventsActionsExtensionManifest.d.ts +2 -1
- package/src/types/extensions/assetEventsActionsExtensionManifest.js.map +1 -0
- package/src/types/extensions/assetHomeExtensionManifest.d.ts +2 -1
- package/src/types/extensions/assetHomeExtensionManifest.js.map +1 -0
- package/src/types/extensions/customerHomeExtensionManifest.d.ts +2 -1
- package/src/types/extensions/customerHomeExtensionManifest.js.map +1 -0
- package/src/types/extensions/fleetExtensionManifest.d.ts +2 -1
- package/src/types/extensions/fleetExtensionManifest.js.map +1 -0
- package/src/types/extensions/irisAppSettingsExtensionManifest.d.ts +2 -1
- package/src/types/extensions/irisAppSettingsExtensionManifest.js.map +1 -0
- package/src/types/extensions/lifecycleExtensionManifest.js.map +1 -0
- package/src/types/extensions/reportExtensionManifest.js.map +1 -0
- package/src/types/extensions/serversideApiExtensionManifest.js.map +1 -0
- package/src/types/extensions/siteHomeExtensionManifest.d.ts +2 -1
- package/src/types/extensions/siteHomeExtensionManifest.js.map +1 -0
- package/src/types/extensions/widgetExtensionManifest.js.map +1 -0
- package/src/types/extractAiNavigationFromTanstackRouter.d.ts +33 -0
- package/src/types/extractAiNavigationFromTanstackRouter.js +60 -0
- package/src/types/extractAiNavigationFromTanstackRouter.js.map +1 -0
- package/src/types/iconImage.js.map +1 -0
- package/src/types/icons.generated.js.map +1 -0
- package/src/types/irisAiNavigation.d.ts +41 -0
- package/src/types/irisAiNavigation.js +3 -0
- package/src/types/irisAiNavigation.js.map +1 -0
- package/src/types/irisAiNavigationValidation.d.ts +17 -0
- package/src/types/irisAiNavigationValidation.js +207 -0
- package/src/types/irisAiNavigationValidation.js.map +1 -0
- package/src/types/irisAppCspInput.js.map +1 -0
- package/src/types/irisAppCustomFields.js.map +1 -0
- package/src/types/irisAppExtensionManifest.js.map +1 -0
- package/src/types/irisAppInstallationConfig.js.map +1 -0
- package/src/types/irisAppManifest.js.map +1 -0
- package/src/types/irisAppMarketplace.js.map +1 -0
- package/src/types/loadNxRootPackageJson.js.map +1 -0
- package/src/types/modulefederation.js.map +1 -0
- package/src/types/permissionsPolicy.js.map +1 -0
- package/src/types/scopes.js.map +1 -0
- package/src/types/serversideInterfaces.js.map +1 -0
- package/src/types/subscriptionPackages.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widgetExtensionManifest.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app-api/src/types/extensions/widgetExtensionManifest.ts"],"names":[],"mappings":";;;AAGA;;;;;GAKG;AACI,MAAM,gBAAgB,GAAG,CAAC,MAA0C,EAA4B,EAAE;IACvG,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC;AACrF,CAAC,CAAC;AAFW,QAAA,gBAAgB,oBAE3B;AAEF;;;;;GAKG;AACI,MAAM,mBAAmB,GAAG,CAAC,MAA0C,EAA+B,EAAE;IAC7G,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,KAAK,KAAK,CAAC;AAClE,CAAC,CAAC;AAFW,QAAA,mBAAmB,uBAE9B;AAQW,QAAA,WAAW,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAU,CAAC;AAIhE,QAAA,kBAAkB,GAAG;IAChC,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,OAAO;IACP,WAAW;IACX,QAAQ;IACR,WAAW;IACX,QAAQ;IACR,WAAW;IACX,aAAa;IACb,UAAU;IACV,sBAAsB;IACtB,4BAA4B;IAC5B,sBAAsB;IACtB,yBAAyB;IACzB,UAAU;IACV,UAAU;IACV,UAAU;IACV,iBAAiB;IACjB,MAAM;IACN,SAAS;IACT,iBAAiB;IACjB,eAAe;IACf,0BAA0B;IAC1B,qBAAqB;IACrB,cAAc;IACd,uBAAuB;IACvB,mBAAmB;IACnB,uBAAuB;IACvB,kBAAkB;IAClB,aAAa;IACb,iBAAiB;CACT,CAAC;AAEE,QAAA,8BAA8B,GAAG;IAC5C,GAAG,0BAAkB;IACrB,aAAa;IACb,gBAAgB;IAChB,2BAA2B;IAC3B,6BAA6B;IAC7B,6CAA6C;CACrC,CAAC;AACE,QAAA,oBAAoB,GAAG,cAAuB,CAAC;AAK/C,QAAA,kCAAkC,GAAG,CAAC,GAAG,sCAA8B,EAAE,4BAAoB,CAAU,CAAC;AAGxG,QAAA,iBAAiB,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAU,CAAC;AAElE,QAAA,iCAAiC,GAAG,CAAC,GAAG,yBAAiB,EAAE,4BAAoB,CAAU,CAAC;AAG1F,QAAA,qBAAqB,GAAG;IACnC,QAAQ;IACR,cAAc;IACd,aAAa;IACb,aAAa;IACb,wBAAwB;IACxB,gBAAgB;CACR,CAAC;AAEE,QAAA,qCAAqC,GAAG,CAAC,GAAG,6BAAqB,EAAE,4BAAoB,CAAU,CAAC;AAGlG,QAAA,sBAAsB,GAAG,CAAC,KAAK,CAAU,CAAC","sourcesContent":["import { IconByName, IconByPath, ImageByPath } from \"../iconImage\";\nimport { AbstractExtensionManifest, TranslationKey, Translations } from \"../irisAppExtensionManifest\";\n\n/**\n * Check if the object is a footer with a link\n *\n * @param object - The object to check\n * @returns {boolean} if the object is a footer with a link, false otherwise\n */\nexport const isFooterWithLink = (object: FooterWithLink | FooterWithoutLink): object is FooterWithLink => {\n return typeof object === \"object\" && \"link\" in object && object.link !== undefined;\n};\n\n/**\n * Check if the object is a footer without a link\n *\n * @param object - The object to check\n * @returns {boolean} if the object is a footer without a link, false otherwise\n */\nexport const isFooterWithoutLink = (object: FooterWithLink | FooterWithoutLink): object is FooterWithoutLink => {\n return typeof object === \"object\" && \"link\" in object === false;\n};\n\nexport type WidgetSupportedLocations = \"MY_HOME\" | \"SITE_HOME\" | \"PLAYGROUND\";\n\nexport type WidgetSupportedFilterBars = \"CUSTOMERS\" | \"ASSETS\" | \"SITES\";\n\nexport type WidgetSupportedFilters = WidgetSupportedFilterBars | \"TIME_RANGE\";\n\nexport const widgetTypes = [\"KPI\", \"CHART\", \"LIST\", \"MAP\", \"OTHER\"] as const;\n\nexport type WidgetType = (typeof widgetTypes)[number];\n\nexport const allAssetFilterKeys = [\n \"search\",\n \"siteIds\",\n \"groups\",\n \"types\",\n \"assetType\",\n \"brands\",\n \"countries\",\n \"models\",\n \"nameQuery\",\n \"criticality\",\n \"activity\",\n \"metadataCompleteness\",\n \"inspectionTemplateAssigned\",\n \"lastInspectionResult\",\n \"lastPerformedInspection\",\n \"lastSeen\",\n \"followed\",\n \"siteType\",\n \"ownerAccountIds\",\n \"area\",\n \"partner\",\n \"productionYears\",\n \"serviceStatus\",\n \"pendingTelematicsDevices\",\n \"telematicsConnected\",\n \"activeFilter\",\n \"siteDepotOwnershipIds\",\n \"fleetHealthStatus\",\n \"fleetHealthCategories\",\n \"fleetHealthTypes\",\n \"deviceTypes\",\n \"firmwareVersion\",\n] as const;\n\nexport const allAssetFilterKeysWithCustomer = [\n ...allAssetFilterKeys,\n \"customerIds\",\n \"rentalStatuses\",\n \"rentalContractOrderNumber\",\n \"rentalContractReferenceCode\",\n \"rentalContractReferenceCodeDescriptionQuery\",\n] as const;\nexport const customFieldFilterKey = \"customFields\" as const;\nexport type AssetFilterKeys = typeof allAssetFilterKeys;\n\nexport type AssetFilterKeysWithCustomer = typeof allAssetFilterKeysWithCustomer;\n\nexport const allAssetFilterKeysWithCustomFields = [...allAssetFilterKeysWithCustomer, customFieldFilterKey] as const;\nexport type AssetFilterKeysWithCustomFields = typeof allAssetFilterKeysWithCustomFields;\n\nexport const allSiteFilterKeys = [\"search\", \"siteStatus\", \"siteType\"] as const;\nexport type SiteFilterKeys = typeof allSiteFilterKeys;\nexport const allSiteFilterKeysWithCustomFields = [...allSiteFilterKeys, customFieldFilterKey] as const;\nexport type SiteFilterKeysWithCustomFields = typeof allSiteFilterKeysWithCustomFields;\n\nexport const allCustomerFilterKeys = [\n \"search\",\n \"customerType\",\n \"criticality\",\n \"servicePlan\",\n \"portalInvitationStatus\",\n \"portalTemplate\",\n] as const;\nexport type CustomerFilterKeys = typeof allCustomerFilterKeys;\nexport const allCustomerFilterKeysWithCustomFields = [...allCustomerFilterKeys, customFieldFilterKey] as const;\nexport type CustomerFilterKeysWithCustomFields = typeof allCustomerFilterKeysWithCustomFields;\n\nexport const allTimeRangeFilterKeys = [\"ALL\"] as const;\nexport type TimeRangeFilterKeys = typeof allTimeRangeFilterKeys;\n\ntype FilterConfig<TFilterKeys extends ReadonlyArray<string>> = {\n include: Array<TFilterKeys[number]>;\n};\n\nexport type SupportedFiltersConfig = {\n ASSETS?: FilterConfig<AssetFilterKeysWithCustomFields>;\n SITES?: FilterConfig<SiteFilterKeysWithCustomFields>;\n CUSTOMERS?: FilterConfig<CustomerFilterKeysWithCustomFields>;\n TIME_RANGE?: FilterConfig<TimeRangeFilterKeys>;\n};\n\nexport type FilterBarToLinkConfig = {\n /**\n * The name of the search property to append the filter bar to the link.\n * Example: \"assetFilter\"\n * Will append to the link as \"?assetFilter=<encoded value>\"\n */\n searchPropertyName?: string;\n\n /**\n * The filter bar to append to the search property.\n * Example:\n * {\n * ASSETS: { include: [\"assetType\"] },\n * }\n * Then use filterBar: \"ASSETS\"\n *\n * Will append to the link as \"?<searchPropertyName>=<encoded value>\"\n *\n * Encoded using useCustomEncoding from @trackunit/react-core-hooks it has a decode hook as well. Its optimized to create a small url string.\n * Will encode to something like \"H4sIAJblCWkAA6tWSipKzEspVrKKVgpJzE4tTc7IVNJRck_Ny0wF0o6lxYlKsbUAbPtHWiYAAAA\"\n */\n filterBar: keyof SupportedFiltersConfig;\n};\n\nexport type FooterWithLink = {\n /**\n * The link to display in the footer. The link is fixed and will always point to the same route.\n */\n link: string;\n\n /**\n * The link description to display in the footer, if not it will default to localized version of 'See full details'. Only relevant if link is provided.\n */\n linkDescription?: string | Translations | TranslationKey;\n\n /**\n * The filter bar to append to the link.\n */\n appendFilterBar?: FilterBarToLinkConfig | Array<FilterBarToLinkConfig>;\n\n /**\n * A logo can be displayed in the footer to show that the widget is powered by an entity. You can use an SVG logo, and provide background and foreground colors.\n * You can also use a SVG, PNG, JPEG or JPG logo directly max size 150x16px.\n */\n poweredByImage?: ImageByPath;\n};\n\nexport type FooterWithoutLink = {\n link?: never;\n linkDescription?: never;\n\n /**\n * A logo can be displayed in the footer to show that the widget is powered by an entity. You can use an SVG logo, and provide background and foreground colors.\n * You can also use a SVG, PNG, JPEG or JPG logo directly max size 150x16px.\n */\n poweredByImage?: ImageByPath;\n};\n\n/**\n * BETA! DO NOT USE THIS YET - its under development\n */\nexport interface WidgetExtensionManifest extends AbstractExtensionManifest {\n type: \"WIDGET_EXTENSION\";\n\n preview?: {\n /**\n * The description of the widget will be displayed in the drawer for adding widgets.\n */\n description?: string | Translations | TranslationKey;\n };\n\n /**\n * The widget type is used for filtering the widgets in the drawer.\n */\n widgetType: WidgetType;\n\n /**\n * Each widget must have one fixed size.\n * Standard widgets are 2x2.\n * Smaller widgets can be either 1x1 or 2x1.\n * It is not recommended to create widgets that are larger than 2x2 by default.\n * If a widget needs to support multiple sizes, create a separate widget for each size.\n * Use `allowFullWidth: true` to let users expand the widget across the full width of the screen.\n * This is generally recommended only for charts and maps where a larger display improves usability.\n */\n size: {\n default: {\n width: 1 | 2 | 3 | 4 | 5 | 6;\n height: 1 | 2 | 3 | 4 | 5 | 6;\n };\n allowFullWidth?: boolean;\n };\n\n header: {\n /**\n * The name of the widget to display in the header. Do not place date ranges or fixed filters in the name. It is used for finding the widget in the drawer.\n * Widgets sized 1x1 do not show the name in the header, but it is still visible in the drawer.\n */\n name: string | Translations | TranslationKey;\n\n /**\n * The image of the widget to display in the header, if not it will default to the icon of the manifest.\n * Most standard widgets use icons, but you can use an SVG logo instead.\n */\n image?: IconByName | IconByPath;\n\n /**\n * If true, a button will be on the header and an editDialog from the src folder of this extension will be loaded to allow users to configure the widget.\n */\n hasEditDialog?: boolean;\n };\n\n footer?: FooterWithLink | FooterWithoutLink;\n\n /**\n * The locations where the widget can be placed. Choose between My Home, Site Home and Playground.\n */\n supportedLocations: Array<WidgetSupportedLocations>;\n\n /**\n * The filters that the widget can be filtered by. To support a date range filter, add \"TIME_RANGE\" to the list. The date range will be displayed separately in the menu.\n * If you would like to lock the filters to a specific value, you can do so by adding the filter to the list and setting the value to the filter.\n */\n supportedFilters?: SupportedFiltersConfig;\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IrisAiNavigationRouteMetadata, IrisExtensionAiNavigation } from "./irisAiNavigation";
|
|
2
|
+
/**
|
|
3
|
+
* Structural view of a Tanstack route. `children` is `unknown` because Tanstack
|
|
4
|
+
* types it as the route's child tuple, or as `unknown` on a leaf route, and
|
|
5
|
+
* file-based route trees pass children as an object rather than an array.
|
|
6
|
+
*
|
|
7
|
+
* Read structurally so this package never depends on `@tanstack/react-router`.
|
|
8
|
+
*/
|
|
9
|
+
type TanstackRouteLike = {
|
|
10
|
+
readonly options?: {
|
|
11
|
+
readonly path?: string;
|
|
12
|
+
readonly staticData?: {
|
|
13
|
+
readonly aiNavigation?: IrisAiNavigationRouteMetadata;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
readonly children?: unknown;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Harvests `staticData.aiNavigation` from a Tanstack `routeTree` into the plain
|
|
20
|
+
* JSON an extension manifest carries. Routes without the annotation are
|
|
21
|
+
* skipped, and paths come from each route's resolved full path.
|
|
22
|
+
*
|
|
23
|
+
* Pass the `routeTree` itself rather than a router: the tree is inert, so no
|
|
24
|
+
* router (and no browser environment) has to exist for this to run.
|
|
25
|
+
*
|
|
26
|
+
* The manifest field is router-agnostic, so a `...FromReactRouter` counterpart
|
|
27
|
+
* can be added alongside this without touching the manifest types.
|
|
28
|
+
*
|
|
29
|
+
* @param routeTree - The app's Tanstack route tree.
|
|
30
|
+
* @returns {IrisExtensionAiNavigation} The AI navigation catalog for an extension manifest.
|
|
31
|
+
*/
|
|
32
|
+
export declare const extractAiNavigationFromTanstackRouter: (routeTree: TanstackRouteLike) => IrisExtensionAiNavigation;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractAiNavigationFromTanstackRouter = void 0;
|
|
4
|
+
const cleanPath = (path) => path.replace(/\/{2,}/g, "/");
|
|
5
|
+
const trimPathLeft = (path) => (path === "/" ? path : path.replace(/^\/+/, ""));
|
|
6
|
+
const joinPaths = (paths) => cleanPath(paths.filter((path) => path !== undefined).join("/"));
|
|
7
|
+
const withoutTrailingSlash = (path) => (path !== "/" && path.endsWith("/") ? path.slice(0, -1) : path);
|
|
8
|
+
const isRouteList = (children) => Array.isArray(children);
|
|
9
|
+
const isRouteRecord = (children) => children !== null && typeof children === "object";
|
|
10
|
+
const toChildRoutes = (children) => {
|
|
11
|
+
if (isRouteList(children)) {
|
|
12
|
+
return children;
|
|
13
|
+
}
|
|
14
|
+
return isRouteRecord(children) ? Object.values(children) : [];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Mirrors how Tanstack Router derives `fullPath` in `BaseRoute.init`, so paths
|
|
18
|
+
* match the running router without constructing one: a pathless layout route
|
|
19
|
+
* (declared with `id` instead of `path`) contributes nothing to the path, and a
|
|
20
|
+
* child `path` is joined onto the parent with duplicate slashes collapsed.
|
|
21
|
+
*/
|
|
22
|
+
const routeFullPath = ({ route, parentFullPath, }) => {
|
|
23
|
+
const declaredPath = route.options?.path;
|
|
24
|
+
const path = declaredPath !== undefined && declaredPath !== "/" ? trimPathLeft(declaredPath) : declaredPath;
|
|
25
|
+
return joinPaths([parentFullPath, path]);
|
|
26
|
+
};
|
|
27
|
+
const collectRoutes = ({ route, fullPath, collected, }) => {
|
|
28
|
+
const aiNavigation = route.options?.staticData?.aiNavigation;
|
|
29
|
+
if (aiNavigation !== undefined) {
|
|
30
|
+
collected.push({
|
|
31
|
+
path: withoutTrailingSlash(fullPath),
|
|
32
|
+
title: aiNavigation.title,
|
|
33
|
+
description: aiNavigation.description,
|
|
34
|
+
...(aiNavigation.params ? { params: aiNavigation.params } : {}),
|
|
35
|
+
...(aiNavigation.search ? { search: aiNavigation.search } : {}),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
toChildRoutes(route.children).forEach(child => collectRoutes({ route: child, fullPath: routeFullPath({ route: child, parentFullPath: fullPath }), collected }));
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Harvests `staticData.aiNavigation` from a Tanstack `routeTree` into the plain
|
|
42
|
+
* JSON an extension manifest carries. Routes without the annotation are
|
|
43
|
+
* skipped, and paths come from each route's resolved full path.
|
|
44
|
+
*
|
|
45
|
+
* Pass the `routeTree` itself rather than a router: the tree is inert, so no
|
|
46
|
+
* router (and no browser environment) has to exist for this to run.
|
|
47
|
+
*
|
|
48
|
+
* The manifest field is router-agnostic, so a `...FromReactRouter` counterpart
|
|
49
|
+
* can be added alongside this without touching the manifest types.
|
|
50
|
+
*
|
|
51
|
+
* @param routeTree - The app's Tanstack route tree.
|
|
52
|
+
* @returns {IrisExtensionAiNavigation} The AI navigation catalog for an extension manifest.
|
|
53
|
+
*/
|
|
54
|
+
const extractAiNavigationFromTanstackRouter = (routeTree) => {
|
|
55
|
+
const collected = [];
|
|
56
|
+
collectRoutes({ route: routeTree, fullPath: "/", collected });
|
|
57
|
+
return { routes: collected };
|
|
58
|
+
};
|
|
59
|
+
exports.extractAiNavigationFromTanstackRouter = extractAiNavigationFromTanstackRouter;
|
|
60
|
+
//# sourceMappingURL=extractAiNavigationFromTanstackRouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractAiNavigationFromTanstackRouter.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/extractAiNavigationFromTanstackRouter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IrisAiNavigationRoute, IrisAiNavigationRouteMetadata, IrisExtensionAiNavigation } from \"./irisAiNavigation\";\n\n/**\n * Structural view of a Tanstack route. `children` is `unknown` because Tanstack\n * types it as the route's child tuple, or as `unknown` on a leaf route, and\n * file-based route trees pass children as an object rather than an array.\n *\n * Read structurally so this package never depends on `@tanstack/react-router`.\n */\ntype TanstackRouteLike = {\n readonly options?: {\n readonly path?: string;\n readonly staticData?: {\n readonly aiNavigation?: IrisAiNavigationRouteMetadata;\n };\n };\n readonly children?: unknown;\n};\n\nconst cleanPath = (path: string): string => path.replace(/\\/{2,}/g, \"/\");\n\nconst trimPathLeft = (path: string): string => (path === \"/\" ? path : path.replace(/^\\/+/, \"\"));\n\nconst joinPaths = (paths: ReadonlyArray<string | undefined>): string =>\n cleanPath(paths.filter((path): path is string => path !== undefined).join(\"/\"));\n\nconst withoutTrailingSlash = (path: string): string => (path !== \"/\" && path.endsWith(\"/\") ? path.slice(0, -1) : path);\n\nconst isRouteList = (children: unknown): children is ReadonlyArray<TanstackRouteLike> => Array.isArray(children);\n\nconst isRouteRecord = (children: unknown): children is Readonly<Record<string, TanstackRouteLike>> =>\n children !== null && typeof children === \"object\";\n\nconst toChildRoutes = (children: unknown): ReadonlyArray<TanstackRouteLike> => {\n if (isRouteList(children)) {\n return children;\n }\n return isRouteRecord(children) ? Object.values(children) : [];\n};\n\n/**\n * Mirrors how Tanstack Router derives `fullPath` in `BaseRoute.init`, so paths\n * match the running router without constructing one: a pathless layout route\n * (declared with `id` instead of `path`) contributes nothing to the path, and a\n * child `path` is joined onto the parent with duplicate slashes collapsed.\n */\nconst routeFullPath = ({\n route,\n parentFullPath,\n}: {\n readonly route: TanstackRouteLike;\n readonly parentFullPath: string;\n}): string => {\n const declaredPath = route.options?.path;\n const path = declaredPath !== undefined && declaredPath !== \"/\" ? trimPathLeft(declaredPath) : declaredPath;\n\n return joinPaths([parentFullPath, path]);\n};\n\nconst collectRoutes = ({\n route,\n fullPath,\n collected,\n}: {\n readonly route: TanstackRouteLike;\n readonly fullPath: string;\n readonly collected: Array<IrisAiNavigationRoute>;\n}): void => {\n const aiNavigation = route.options?.staticData?.aiNavigation;\n\n if (aiNavigation !== undefined) {\n collected.push({\n path: withoutTrailingSlash(fullPath),\n title: aiNavigation.title,\n description: aiNavigation.description,\n ...(aiNavigation.params ? { params: aiNavigation.params } : {}),\n ...(aiNavigation.search ? { search: aiNavigation.search } : {}),\n });\n }\n\n toChildRoutes(route.children).forEach(child =>\n collectRoutes({ route: child, fullPath: routeFullPath({ route: child, parentFullPath: fullPath }), collected })\n );\n};\n\n/**\n * Harvests `staticData.aiNavigation` from a Tanstack `routeTree` into the plain\n * JSON an extension manifest carries. Routes without the annotation are\n * skipped, and paths come from each route's resolved full path.\n *\n * Pass the `routeTree` itself rather than a router: the tree is inert, so no\n * router (and no browser environment) has to exist for this to run.\n *\n * The manifest field is router-agnostic, so a `...FromReactRouter` counterpart\n * can be added alongside this without touching the manifest types.\n *\n * @param routeTree - The app's Tanstack route tree.\n * @returns {IrisExtensionAiNavigation} The AI navigation catalog for an extension manifest.\n */\nexport const extractAiNavigationFromTanstackRouter = (routeTree: TanstackRouteLike): IrisExtensionAiNavigation => {\n const collected: Array<IrisAiNavigationRoute> = [];\n\n collectRoutes({ route: routeTree, fullPath: \"/\", collected });\n\n return { routes: collected };\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iconImage.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/iconImage.ts"],"names":[],"mappings":";;;AASA;;GAEG;AACH,8DAA8D;AACvD,MAAM,UAAU,GAAG,CAAC,KAAU,EAAqB,EAAE;IAC1D,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACxE,CAAC,CAAC;AAFW,QAAA,UAAU,cAErB;AAEF;;GAEG;AACH,8DAA8D;AACvD,MAAM,UAAU,GAAG,CAAC,KAAU,EAAqB,EAAE;IAC1D,OAAO,mCAAmC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC,CAAC;AAFW,QAAA,UAAU,cAErB;AAmDF;;;;;GAKG;AACI,MAAM,YAAY,GAAG,CAAC,KAAc,EAAuB,EAAE;IAClE,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC5B,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,YAAY,gBAQvB;AAEF;;;;;GAKG;AACI,MAAM,aAAa,GAAG,CAAC,KAAc,EAAwB,EAAE;IACpE,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,CAAC,IAAA,iBAAS,EAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAA,uBAAe,EAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAA,iBAAS,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAChF,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,aAAa,iBAQxB;AAEF;;;;;GAKG;AACI,MAAM,SAAS,GAAG,CAAC,IAA+B,EAAwB,EAAE;IACjF,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC,CAAC;AALW,QAAA,SAAS,aAKpB;AAEF;;;;;GAKG;AACI,MAAM,SAAS,GAAG,CAAC,IAA+B,EAAwB,EAAE;IACjF,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC,CAAC;AALW,QAAA,SAAS,aAKpB;AAEF;;;;;GAKG;AACI,MAAM,eAAe,GAAG,CAAC,IAA+B,EAAyB,EAAE;IACxF,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACzD,CAAC,CAAC;AALW,QAAA,eAAe,mBAK1B;AAEF;;;;;GAKG;AACI,MAAM,YAAY,GAAG,CAAC,KAAc,EAAuB,EAAE;IAClE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;AACxE,CAAC,CAAC;AAFW,QAAA,YAAY,gBAEvB","sourcesContent":["import { IconName } from \"./icons.generated\";\n\ntype HexColor = `#${string}`;\ntype RgbColor = `rgb(${number},${number},${number})`;\n\nexport type SvgImagePath = `${string}.svg`;\nexport type PngImagePath = `${string}.png`;\nexport type JpegImagePath = `${string}.jpeg` | `${string}.jpg`;\n\n/**\n * Checks if the value is a valid hex color\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isHexColor = (color: any): color is HexColor => {\n return /^#[0-9A-F]{6}$/i.test(color) || /^#[0-9A-F]{3}$/i.test(color);\n};\n\n/**\n * Checks if the value is a valid rgb color\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isRgbColor = (color: any): color is RgbColor => {\n return /^rgb\\(\\d{1,3},\\d{1,3},\\d{1,3}\\)$/i.test(color);\n};\n\nexport type Color = HexColor | RgbColor;\n\nexport type Colorable = {\n /**\n * Color of the background for the icon\n * Supports hex or rgb\n *\n * @example \"#ff0000\" or \"rgb(255,0,0)\"\n */\n background?: Color;\n\n /**\n * Color of the foreground for the icon\n * Supports hex or rgb\n *\n * @example \"#ff0000\" or \"rgb(255,0,0)\"\n */\n foreground?: Color;\n};\n\nexport type IconByPath = {\n /**\n * Path relative to the projects src folder defined in the extensions sourceRoot\n * ONLY supports svg files since we replace the color in the svg file at runtime.\n *\n * @example \"assets/icon.svg\"\n */\n path: SvgImagePath;\n} & Colorable;\n\nexport type ImageByPath = {\n /**\n * Path relative to the projects src folder defined in the extensions sourceRoot\n * Supports png, jpeg, jpg and svg files.\n *\n * @example \"assets/icon1.png\" or \"assets/icon2.jpeg\" or \"assets/icon3.jpg\" or \"assets/icon4.svg\"\n */\n path: PngImagePath | JpegImagePath | SvgImagePath;\n};\n\nexport type IconByName = {\n /**\n * Name of the icon from the Iris Icons package\n *\n * @example \"MapMarkerPointSquare\"\n */\n name: IconName;\n} & Colorable;\n\n/**\n * Checks if value is an IconImage\n *\n * @param value - The value to check\n * @returns {boolean} True if value is an IconImage\n */\nexport const isIconByPath = (value: unknown): value is IconByPath => {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"path\" in value &&\n typeof value.path === \"string\" &&\n value.path.endsWith(\".svg\")\n );\n};\n\n/**\n * Checks if value is a ImageByPath\n *\n * @param value - The value to check\n * @returns {boolean} True if value is a ImageByPath\n */\nexport const isImageByPath = (value: unknown): value is ImageByPath => {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"path\" in value &&\n typeof value.path === \"string\" &&\n (isPngPath(value.path) || isJpgOrJpegPath(value.path) || isSvgPath(value.path))\n );\n};\n\n/**\n * Checks if the path is a svg path\n *\n * @param path - The path to check\n * @returns {boolean} True if the path is a svg path\n */\nexport const isSvgPath = (path: string | undefined | null): path is SvgImagePath => {\n if (path === undefined || path === null) {\n return false;\n }\n return path.endsWith(\".svg\");\n};\n\n/**\n * Checks if the path is a png path\n *\n * @param path - The path to check\n * @returns {boolean} True if the path is a png path\n */\nexport const isPngPath = (path: string | undefined | null): path is PngImagePath => {\n if (path === undefined || path === null) {\n return false;\n }\n return path.endsWith(\".png\");\n};\n\n/**\n * Checks if the path is a jpeg or jpg path\n *\n * @param path - The path to check\n * @returns {boolean} True if the path is a jpeg or jpg path\n */\nexport const isJpgOrJpegPath = (path: string | undefined | null): path is JpegImagePath => {\n if (path === undefined || path === null) {\n return false;\n }\n return path.endsWith(\".jpeg\") || path.endsWith(\".jpg\");\n};\n\n/**\n * Checks if value is an IconByName\n *\n * @param value - The value to check\n * @returns {boolean}- True if value is an IconByName\n */\nexport const isIconByName = (value: unknown): value is IconByName => {\n return typeof value === \"object\" && value !== null && \"name\" in value;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.generated.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/icons.generated.ts"],"names":[],"mappings":"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","sourcesContent":["export const iconNames = {\n Zone: \"Zone\",\n WackerNeusonZeroEmission: \"WackerNeusonZeroEmission\",\n Unpin: \"Unpin\",\n Transmission: \"Transmission\",\n Timeline: \"Timeline\",\n Timeline1: \"Timeline1\",\n Slash: \"Slash\",\n SidebarOpen: \"SidebarOpen\",\n SidebarClose: \"SidebarClose\",\n RawDevice: \"RawDevice\",\n Points: \"Points\",\n Plug: \"Plug\",\n Pin: \"Pin\",\n MapSearch: \"MapSearch\",\n MapPinStop: \"MapPinStop\",\n MapPinQuestionMark: \"MapPinQuestionMark\",\n MapPinPlay: \"MapPinPlay\",\n MapPinPause: \"MapPinPause\",\n MapPinExclamation: \"MapPinExclamation\",\n MapPinCheck: \"MapPinCheck\",\n MapMarkerPointSquare: \"MapMarkerPointSquare\",\n MapMarkerPointRound: \"MapMarkerPointRound\",\n MapMarkerLabelSquare: \"MapMarkerLabelSquare\",\n MapMarkerLabelRound: \"MapMarkerLabelRound\",\n Leaf: \"Leaf\",\n IrisX: \"IrisX\",\n Hierarchy: \"Hierarchy\",\n Heatmap: \"Heatmap\",\n Gps: \"Gps\",\n GpsArrow: \"GpsArrow\",\n GpsArrowNorth: \"GpsArrowNorth\",\n Fuel: \"Fuel\",\n FitToWidth: \"FitToWidth\",\n FitToHeight: \"FitToHeight\",\n Filter: \"Filter\",\n Excavator: \"Excavator\",\n Engine: \"Engine\",\n EllipsisDrag: \"EllipsisDrag\",\n Directions: \"Directions\",\n DemolitionHammer: \"DemolitionHammer\",\n ConstructionCone: \"ConstructionCone\",\n ConcreteMixer: \"ConcreteMixer\",\n Co2: \"Co2\",\n CloudX: \"CloudX\",\n Bucket: \"Bucket\",\n Brakes: \"Brakes\",\n Bluetooth: \"Bluetooth\",\n BatteryBig: \"BatteryBig\",\n Asset: \"Asset\",\n Spot: \"Spot\",\n XMark: \"XMark\",\n XCircle: \"XCircle\",\n Wrench: \"Wrench\",\n WrenchScrewdriver: \"WrenchScrewdriver\",\n Window: \"Window\",\n Wifi: \"Wifi\",\n Wallet: \"Wallet\",\n ViewfinderCircle: \"ViewfinderCircle\",\n ViewColumns: \"ViewColumns\",\n VideoCamera: \"VideoCamera\",\n VideoCameraSlash: \"VideoCameraSlash\",\n Variable: \"Variable\",\n Users: \"Users\",\n User: \"User\",\n UserPlus: \"UserPlus\",\n UserMinus: \"UserMinus\",\n UserGroup: \"UserGroup\",\n UserCircle: \"UserCircle\",\n Underline: \"Underline\",\n Tv: \"Tv\",\n Truck: \"Truck\",\n Trophy: \"Trophy\",\n Trash: \"Trash\",\n Ticket: \"Ticket\",\n Tag: \"Tag\",\n TableCells: \"TableCells\",\n Swatch: \"Swatch\",\n Sun: \"Sun\",\n Strikethrough: \"Strikethrough\",\n Stop: \"Stop\",\n StopCircle: \"StopCircle\",\n Star: \"Star\",\n SquaresPlus: \"SquaresPlus\",\n Squares2X2: \"Squares2X2\",\n Square3Stack3D: \"Square3Stack3D\",\n Square2Stack: \"Square2Stack\",\n SpeakerXMark: \"SpeakerXMark\",\n SpeakerWave: \"SpeakerWave\",\n Sparkles: \"Sparkles\",\n Signal: \"Signal\",\n SignalSlash: \"SignalSlash\",\n ShoppingCart: \"ShoppingCart\",\n ShoppingBag: \"ShoppingBag\",\n ShieldExclamation: \"ShieldExclamation\",\n ShieldCheck: \"ShieldCheck\",\n Share: \"Share\",\n Server: \"Server\",\n ServerStack: \"ServerStack\",\n Scissors: \"Scissors\",\n Scale: \"Scale\",\n Rss: \"Rss\",\n RocketLaunch: \"RocketLaunch\",\n RectangleStack: \"RectangleStack\",\n RectangleGroup: \"RectangleGroup\",\n ReceiptRefund: \"ReceiptRefund\",\n ReceiptPercent: \"ReceiptPercent\",\n Radio: \"Radio\",\n QueueList: \"QueueList\",\n QuestionMarkCircle: \"QuestionMarkCircle\",\n QrCode: \"QrCode\",\n PuzzlePiece: \"PuzzlePiece\",\n Printer: \"Printer\",\n PresentationChartLine: \"PresentationChartLine\",\n PresentationChartBar: \"PresentationChartBar\",\n Power: \"Power\",\n Plus: \"Plus\",\n PlusCircle: \"PlusCircle\",\n Play: \"Play\",\n PlayPause: \"PlayPause\",\n PlayCircle: \"PlayCircle\",\n Photo: \"Photo\",\n Phone: \"Phone\",\n PhoneXMark: \"PhoneXMark\",\n PhoneArrowUpRight: \"PhoneArrowUpRight\",\n PhoneArrowDownLeft: \"PhoneArrowDownLeft\",\n PercentBadge: \"PercentBadge\",\n Pencil: \"Pencil\",\n PencilSquare: \"PencilSquare\",\n Pause: \"Pause\",\n PauseCircle: \"PauseCircle\",\n PaperClip: \"PaperClip\",\n PaperAirplane: \"PaperAirplane\",\n PaintBrush: \"PaintBrush\",\n NumberedList: \"NumberedList\",\n NoSymbol: \"NoSymbol\",\n Newspaper: \"Newspaper\",\n MusicalNote: \"MusicalNote\",\n Moon: \"Moon\",\n Minus: \"Minus\",\n MinusCircle: \"MinusCircle\",\n Microphone: \"Microphone\",\n Megaphone: \"Megaphone\",\n Map: \"Map\",\n MapPin: \"MapPin\",\n MagnifyingGlass: \"MagnifyingGlass\",\n MagnifyingGlassPlus: \"MagnifyingGlassPlus\",\n MagnifyingGlassMinus: \"MagnifyingGlassMinus\",\n MagnifyingGlassCircle: \"MagnifyingGlassCircle\",\n LockOpen: \"LockOpen\",\n LockClosed: \"LockClosed\",\n ListBullet: \"ListBullet\",\n Link: \"Link\",\n LinkSlash: \"LinkSlash\",\n LightBulb: \"LightBulb\",\n Lifebuoy: \"Lifebuoy\",\n Language: \"Language\",\n Key: \"Key\",\n Italic: \"Italic\",\n InformationCircle: \"InformationCircle\",\n Inbox: \"Inbox\",\n InboxStack: \"InboxStack\",\n InboxArrowDown: \"InboxArrowDown\",\n Identification: \"Identification\",\n Home: \"Home\",\n HomeModern: \"HomeModern\",\n Heart: \"Heart\",\n Hashtag: \"Hashtag\",\n HandThumbUp: \"HandThumbUp\",\n HandThumbDown: \"HandThumbDown\",\n HandRaised: \"HandRaised\",\n H3: \"H3\",\n H2: \"H2\",\n H1: \"H1\",\n GlobeEuropeAfrica: \"GlobeEuropeAfrica\",\n GlobeAsiaAustralia: \"GlobeAsiaAustralia\",\n GlobeAmericas: \"GlobeAmericas\",\n GlobeAlt: \"GlobeAlt\",\n Gift: \"Gift\",\n GiftTop: \"GiftTop\",\n Gif: \"Gif\",\n Funnel: \"Funnel\",\n Forward: \"Forward\",\n Folder: \"Folder\",\n FolderPlus: \"FolderPlus\",\n FolderOpen: \"FolderOpen\",\n FolderMinus: \"FolderMinus\",\n FolderArrowDown: \"FolderArrowDown\",\n Flag: \"Flag\",\n Fire: \"Fire\",\n FingerPrint: \"FingerPrint\",\n Film: \"Film\",\n FaceSmile: \"FaceSmile\",\n FaceFrown: \"FaceFrown\",\n Eye: \"Eye\",\n EyeSlash: \"EyeSlash\",\n EyeDropper: \"EyeDropper\",\n ExclamationTriangle: \"ExclamationTriangle\",\n ExclamationCircle: \"ExclamationCircle\",\n Equals: \"Equals\",\n Envelope: \"Envelope\",\n EnvelopeOpen: \"EnvelopeOpen\",\n EllipsisVertical: \"EllipsisVertical\",\n EllipsisHorizontal: \"EllipsisHorizontal\",\n EllipsisHorizontalCircle: \"EllipsisHorizontalCircle\",\n Document: \"Document\",\n DocumentText: \"DocumentText\",\n DocumentPlus: \"DocumentPlus\",\n DocumentMinus: \"DocumentMinus\",\n DocumentMagnifyingGlass: \"DocumentMagnifyingGlass\",\n DocumentDuplicate: \"DocumentDuplicate\",\n DocumentCurrencyYen: \"DocumentCurrencyYen\",\n DocumentCurrencyRupee: \"DocumentCurrencyRupee\",\n DocumentCurrencyPound: \"DocumentCurrencyPound\",\n DocumentCurrencyEuro: \"DocumentCurrencyEuro\",\n DocumentCurrencyDollar: \"DocumentCurrencyDollar\",\n DocumentCurrencyBangladeshi: \"DocumentCurrencyBangladeshi\",\n DocumentCheck: \"DocumentCheck\",\n DocumentChartBar: \"DocumentChartBar\",\n DocumentArrowUp: \"DocumentArrowUp\",\n DocumentArrowDown: \"DocumentArrowDown\",\n Divide: \"Divide\",\n DeviceTablet: \"DeviceTablet\",\n DevicePhoneMobile: \"DevicePhoneMobile\",\n CursorArrowRipple: \"CursorArrowRipple\",\n CursorArrowRays: \"CursorArrowRays\",\n CurrencyYen: \"CurrencyYen\",\n CurrencyRupee: \"CurrencyRupee\",\n CurrencyPound: \"CurrencyPound\",\n CurrencyEuro: \"CurrencyEuro\",\n CurrencyDollar: \"CurrencyDollar\",\n CurrencyBangladeshi: \"CurrencyBangladeshi\",\n Cube: \"Cube\",\n CubeTransparent: \"CubeTransparent\",\n CreditCard: \"CreditCard\",\n CpuChip: \"CpuChip\",\n ComputerDesktop: \"ComputerDesktop\",\n CommandLine: \"CommandLine\",\n Cog: \"Cog\",\n Cog8Tooth: \"Cog8Tooth\",\n Cog6Tooth: \"Cog6Tooth\",\n CodeBracket: \"CodeBracket\",\n CodeBracketSquare: \"CodeBracketSquare\",\n Cloud: \"Cloud\",\n CloudArrowUp: \"CloudArrowUp\",\n CloudArrowDown: \"CloudArrowDown\",\n Clock: \"Clock\",\n Clipboard: \"Clipboard\",\n ClipboardDocument: \"ClipboardDocument\",\n ClipboardDocumentList: \"ClipboardDocumentList\",\n ClipboardDocumentCheck: \"ClipboardDocumentCheck\",\n CircleStack: \"CircleStack\",\n ChevronUp: \"ChevronUp\",\n ChevronUpDown: \"ChevronUpDown\",\n ChevronRight: \"ChevronRight\",\n ChevronLeft: \"ChevronLeft\",\n ChevronDown: \"ChevronDown\",\n ChevronDoubleUp: \"ChevronDoubleUp\",\n ChevronDoubleRight: \"ChevronDoubleRight\",\n ChevronDoubleLeft: \"ChevronDoubleLeft\",\n ChevronDoubleDown: \"ChevronDoubleDown\",\n Check: \"Check\",\n CheckCircle: \"CheckCircle\",\n CheckBadge: \"CheckBadge\",\n ChatBubbleOvalLeft: \"ChatBubbleOvalLeft\",\n ChatBubbleOvalLeftEllipsis: \"ChatBubbleOvalLeftEllipsis\",\n ChatBubbleLeft: \"ChatBubbleLeft\",\n ChatBubbleLeftRight: \"ChatBubbleLeftRight\",\n ChatBubbleLeftEllipsis: \"ChatBubbleLeftEllipsis\",\n ChatBubbleBottomCenter: \"ChatBubbleBottomCenter\",\n ChatBubbleBottomCenterText: \"ChatBubbleBottomCenterText\",\n ChartPie: \"ChartPie\",\n ChartBar: \"ChartBar\",\n ChartBarSquare: \"ChartBarSquare\",\n Camera: \"Camera\",\n Calendar: \"Calendar\",\n CalendarDays: \"CalendarDays\",\n CalendarDateRange: \"CalendarDateRange\",\n Calculator: \"Calculator\",\n Cake: \"Cake\",\n BuildingStorefront: \"BuildingStorefront\",\n BuildingOffice: \"BuildingOffice\",\n BuildingOffice2: \"BuildingOffice2\",\n BuildingLibrary: \"BuildingLibrary\",\n BugAnt: \"BugAnt\",\n Briefcase: \"Briefcase\",\n Bookmark: \"Bookmark\",\n BookmarkSquare: \"BookmarkSquare\",\n BookmarkSlash: \"BookmarkSlash\",\n BookOpen: \"BookOpen\",\n Bolt: \"Bolt\",\n BoltSlash: \"BoltSlash\",\n Bold: \"Bold\",\n Bell: \"Bell\",\n BellSnooze: \"BellSnooze\",\n BellSlash: \"BellSlash\",\n BellAlert: \"BellAlert\",\n Beaker: \"Beaker\",\n Battery50: \"Battery50\",\n Battery100: \"Battery100\",\n Battery0: \"Battery0\",\n BarsArrowUp: \"BarsArrowUp\",\n BarsArrowDown: \"BarsArrowDown\",\n Bars4: \"Bars4\",\n Bars3: \"Bars3\",\n Bars3CenterLeft: \"Bars3CenterLeft\",\n Bars3BottomRight: \"Bars3BottomRight\",\n Bars3BottomLeft: \"Bars3BottomLeft\",\n Bars2: \"Bars2\",\n Banknotes: \"Banknotes\",\n Backward: \"Backward\",\n Backspace: \"Backspace\",\n AtSymbol: \"AtSymbol\",\n ArrowsUpDown: \"ArrowsUpDown\",\n ArrowsRightLeft: \"ArrowsRightLeft\",\n ArrowsPointingOut: \"ArrowsPointingOut\",\n ArrowsPointingIn: \"ArrowsPointingIn\",\n ArrowUturnUp: \"ArrowUturnUp\",\n ArrowUturnRight: \"ArrowUturnRight\",\n ArrowUturnLeft: \"ArrowUturnLeft\",\n ArrowUturnDown: \"ArrowUturnDown\",\n ArrowUp: \"ArrowUp\",\n ArrowUpTray: \"ArrowUpTray\",\n ArrowUpRight: \"ArrowUpRight\",\n ArrowUpOnSquare: \"ArrowUpOnSquare\",\n ArrowUpOnSquareStack: \"ArrowUpOnSquareStack\",\n ArrowUpLeft: \"ArrowUpLeft\",\n ArrowUpCircle: \"ArrowUpCircle\",\n ArrowTurnUpRight: \"ArrowTurnUpRight\",\n ArrowTurnUpLeft: \"ArrowTurnUpLeft\",\n ArrowTurnRightUp: \"ArrowTurnRightUp\",\n ArrowTurnRightDown: \"ArrowTurnRightDown\",\n ArrowTurnLeftUp: \"ArrowTurnLeftUp\",\n ArrowTurnLeftDown: \"ArrowTurnLeftDown\",\n ArrowTurnDownRight: \"ArrowTurnDownRight\",\n ArrowTurnDownLeft: \"ArrowTurnDownLeft\",\n ArrowTrendingUp: \"ArrowTrendingUp\",\n ArrowTrendingDown: \"ArrowTrendingDown\",\n ArrowTopRightOnSquare: \"ArrowTopRightOnSquare\",\n ArrowRight: \"ArrowRight\",\n ArrowRightStartOnRectangle: \"ArrowRightStartOnRectangle\",\n ArrowRightEndOnRectangle: \"ArrowRightEndOnRectangle\",\n ArrowRightCircle: \"ArrowRightCircle\",\n ArrowPath: \"ArrowPath\",\n ArrowPathRoundedSquare: \"ArrowPathRoundedSquare\",\n ArrowLongUp: \"ArrowLongUp\",\n ArrowLongRight: \"ArrowLongRight\",\n ArrowLongLeft: \"ArrowLongLeft\",\n ArrowLongDown: \"ArrowLongDown\",\n ArrowLeft: \"ArrowLeft\",\n ArrowLeftStartOnRectangle: \"ArrowLeftStartOnRectangle\",\n ArrowLeftEndOnRectangle: \"ArrowLeftEndOnRectangle\",\n ArrowLeftCircle: \"ArrowLeftCircle\",\n ArrowDown: \"ArrowDown\",\n ArrowDownTray: \"ArrowDownTray\",\n ArrowDownRight: \"ArrowDownRight\",\n ArrowDownOnSquare: \"ArrowDownOnSquare\",\n ArrowDownOnSquareStack: \"ArrowDownOnSquareStack\",\n ArrowDownLeft: \"ArrowDownLeft\",\n ArrowDownCircle: \"ArrowDownCircle\",\n ArchiveBox: \"ArchiveBox\",\n ArchiveBoxXMark: \"ArchiveBoxXMark\",\n ArchiveBoxArrowDown: \"ArchiveBoxArrowDown\",\n AdjustmentsVertical: \"AdjustmentsVertical\",\n AdjustmentsHorizontal: \"AdjustmentsHorizontal\",\n AcademicCap: \"AcademicCap\",\n} as const;\nexport type IconName = keyof typeof iconNames;\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type IrisAiNavigationParam = {
|
|
2
|
+
readonly description: string;
|
|
3
|
+
};
|
|
4
|
+
export type IrisAiNavigationSearchParam = {
|
|
5
|
+
readonly description: string;
|
|
6
|
+
readonly required?: boolean;
|
|
7
|
+
readonly type?: "string" | "number" | "boolean";
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* AI navigation metadata for a single destination, without the path. Used both
|
|
11
|
+
* as the per-route half of {@link IrisAiNavigationRoute} and as the payload a
|
|
12
|
+
* router can carry per route (for example Tanstack Router's
|
|
13
|
+
* `staticData.aiNavigation`).
|
|
14
|
+
*/
|
|
15
|
+
export type IrisAiNavigationRouteMetadata = {
|
|
16
|
+
readonly title: string;
|
|
17
|
+
readonly description: string;
|
|
18
|
+
readonly params?: Readonly<Record<string, IrisAiNavigationParam>>;
|
|
19
|
+
readonly search?: Readonly<Record<string, IrisAiNavigationSearchParam>>;
|
|
20
|
+
};
|
|
21
|
+
export type IrisAiNavigationRoute = IrisAiNavigationRouteMetadata & {
|
|
22
|
+
readonly path: string;
|
|
23
|
+
};
|
|
24
|
+
export type IrisExtensionAiNavigation = {
|
|
25
|
+
readonly routes: ReadonlyArray<IrisAiNavigationRoute>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Opt-in for extension types whose host URL can express an in-app path, so the
|
|
29
|
+
* Manager AI assistant can offer their pages as navigation destinations. The
|
|
30
|
+
* manifests that implement it define which types those are; see
|
|
31
|
+
* `isAiNavigableExtensionType` for the matching runtime check.
|
|
32
|
+
*/
|
|
33
|
+
export interface AiNavigableExtensionManifest {
|
|
34
|
+
/**
|
|
35
|
+
* Pages of this extension the AI assistant may navigate to, as plain JSON.
|
|
36
|
+
* Router-agnostic: author it by hand, or derive it from whatever router the
|
|
37
|
+
* app uses — see `extractAiNavigationFromTanstackRouter` for Tanstack Router.
|
|
38
|
+
* Derived values are resolved when the manifest is built.
|
|
39
|
+
*/
|
|
40
|
+
aiNavigation?: IrisExtensionAiNavigation;
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irisAiNavigation.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/irisAiNavigation.ts"],"names":[],"mappings":"","sourcesContent":["export type IrisAiNavigationParam = {\n readonly description: string;\n};\n\nexport type IrisAiNavigationSearchParam = {\n readonly description: string;\n readonly required?: boolean;\n readonly type?: \"string\" | \"number\" | \"boolean\";\n};\n\n/**\n * AI navigation metadata for a single destination, without the path. Used both\n * as the per-route half of {@link IrisAiNavigationRoute} and as the payload a\n * router can carry per route (for example Tanstack Router's\n * `staticData.aiNavigation`).\n */\nexport type IrisAiNavigationRouteMetadata = {\n readonly title: string;\n readonly description: string;\n readonly params?: Readonly<Record<string, IrisAiNavigationParam>>;\n readonly search?: Readonly<Record<string, IrisAiNavigationSearchParam>>;\n};\n\nexport type IrisAiNavigationRoute = IrisAiNavigationRouteMetadata & {\n readonly path: string;\n};\n\nexport type IrisExtensionAiNavigation = {\n readonly routes: ReadonlyArray<IrisAiNavigationRoute>;\n};\n\n/**\n * Opt-in for extension types whose host URL can express an in-app path, so the\n * Manager AI assistant can offer their pages as navigation destinations. The\n * manifests that implement it define which types those are; see\n * `isAiNavigableExtensionType` for the matching runtime check.\n */\nexport interface AiNavigableExtensionManifest {\n /**\n * Pages of this extension the AI assistant may navigate to, as plain JSON.\n * Router-agnostic: author it by hand, or derive it from whatever router the\n * app uses — see `extractAiNavigationFromTanstackRouter` for Tanstack Router.\n * Derived values are resolved when the manifest is built.\n */\n aiNavigation?: IrisExtensionAiNavigation;\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IrisAppExtensionType } from "./irisAppExtensionManifest";
|
|
2
|
+
export declare const AI_NAVIGATION_MAX_ROUTES = 50;
|
|
3
|
+
export declare const AI_NAVIGATION_TITLE_MAX_LENGTH = 80;
|
|
4
|
+
export declare const AI_NAVIGATION_DESCRIPTION_MAX_LENGTH = 300;
|
|
5
|
+
export type AiNavigationValidationInput = {
|
|
6
|
+
readonly extensionId: string;
|
|
7
|
+
readonly extensionType: IrisAppExtensionType;
|
|
8
|
+
/** Untrusted at the server choke point: comes from a published manifest. */
|
|
9
|
+
readonly aiNavigation: unknown;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Structural validation for an extension's `aiNavigation` catalog. Returns an
|
|
13
|
+
* array of human-readable error messages; an empty array means the metadata is
|
|
14
|
+
* valid. Shared by the build (`updateExtensions`) and the server
|
|
15
|
+
* (`manifest-validator.ts`) so both choke points enforce identical rules.
|
|
16
|
+
*/
|
|
17
|
+
export declare const validateIrisAiNavigation: ({ extensionId, extensionType, aiNavigation, }: AiNavigationValidationInput) => ReadonlyArray<string>;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateIrisAiNavigation = exports.AI_NAVIGATION_DESCRIPTION_MAX_LENGTH = exports.AI_NAVIGATION_TITLE_MAX_LENGTH = exports.AI_NAVIGATION_MAX_ROUTES = void 0;
|
|
4
|
+
const aiNavigableExtension_1 = require("./aiNavigableExtension");
|
|
5
|
+
exports.AI_NAVIGATION_MAX_ROUTES = 50;
|
|
6
|
+
exports.AI_NAVIGATION_TITLE_MAX_LENGTH = 80;
|
|
7
|
+
exports.AI_NAVIGATION_DESCRIPTION_MAX_LENGTH = 300;
|
|
8
|
+
const AI_NAVIGATION_SEARCH_PARAM_TYPES = [
|
|
9
|
+
"string",
|
|
10
|
+
"number",
|
|
11
|
+
"boolean",
|
|
12
|
+
];
|
|
13
|
+
const PATH_PARAM_SEGMENT = /\$([a-zA-Z][a-zA-Z0-9_]*)/g;
|
|
14
|
+
const HTML_PATTERN = /[<>]/;
|
|
15
|
+
const URL_PATTERN = /(https?:\/\/|www\.)/i;
|
|
16
|
+
/**
|
|
17
|
+
* Markup constructs rather than bare characters, so ordinary prose such as
|
|
18
|
+
* "Key #1" or "asset_id" stays valid: links/images, fenced or inline code,
|
|
19
|
+
* paired emphasis, strikethrough, and heading or blockquote line prefixes.
|
|
20
|
+
*/
|
|
21
|
+
const MARKDOWN_PATTERNS = [
|
|
22
|
+
/!?\[[^\]]*\]\([^)]*\)/,
|
|
23
|
+
/`/,
|
|
24
|
+
/\*\*[\s\S]+?\*\*/,
|
|
25
|
+
/__[\s\S]+?__/,
|
|
26
|
+
/\*[^*\s][\s\S]*?\*/,
|
|
27
|
+
/~~[\s\S]+?~~/,
|
|
28
|
+
/(^|\n)\s*(#{1,6}\s|>\s|[-*+]\s|\d+\.\s)/,
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Extension types whose host URL cannot express an in-app path, so every
|
|
32
|
+
* annotated route would collapse onto the same destination. They may advertise
|
|
33
|
+
* the extension root only.
|
|
34
|
+
*/
|
|
35
|
+
const AI_NAVIGATION_ROOT_ONLY_EXTENSION_TYPES = ["IRIS_APP_SETTINGS_EXTENSION"];
|
|
36
|
+
const extractPathParamNames = (path) => Array.from(path.matchAll(PATH_PARAM_SEGMENT), match => match[1]).filter((name) => name !== undefined);
|
|
37
|
+
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
38
|
+
/** Returns the offending substring when `value` is not plain text, else `undefined`. */
|
|
39
|
+
const findNonPlainText = (value) => {
|
|
40
|
+
const match = [HTML_PATTERN, URL_PATTERN, ...MARKDOWN_PATTERNS].reduce((found, pattern) => found ?? value.match(pattern)?.[0], undefined);
|
|
41
|
+
return match === undefined ? undefined : match.trim();
|
|
42
|
+
};
|
|
43
|
+
const validateText = ({ value, field, maxLength, routeLabel, errors, }) => {
|
|
44
|
+
if (typeof value !== "string") {
|
|
45
|
+
errors.push(`${routeLabel}: '${field}' is required and must be a string.`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const trimmed = value.trim();
|
|
49
|
+
if (trimmed.length === 0) {
|
|
50
|
+
errors.push(`${routeLabel}: '${field}' must not be empty or whitespace.`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (value.length > maxLength) {
|
|
54
|
+
errors.push(`${routeLabel}: '${field}' must be at most ${maxLength} characters.`);
|
|
55
|
+
}
|
|
56
|
+
const nonPlainText = findNonPlainText(value);
|
|
57
|
+
if (nonPlainText !== undefined) {
|
|
58
|
+
errors.push(`${routeLabel}: '${field}' must be plain text (no HTML, URLs, or markdown), found '${nonPlainText}'.`);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const validatePath = ({ path, params, routeLabel, errors, }) => {
|
|
62
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
63
|
+
errors.push(`${routeLabel}: 'path' is required and must be a string.`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (!path.startsWith("/")) {
|
|
67
|
+
errors.push(`${routeLabel}: 'path' must start with '/'.`);
|
|
68
|
+
}
|
|
69
|
+
if (/:\/\//.test(path) || URL_PATTERN.test(path)) {
|
|
70
|
+
errors.push(`${routeLabel}: 'path' must not contain a protocol or host.`);
|
|
71
|
+
}
|
|
72
|
+
if (path.split("/").some(segment => segment === "..")) {
|
|
73
|
+
errors.push(`${routeLabel}: 'path' must not escape the extension root.`);
|
|
74
|
+
}
|
|
75
|
+
if (/\s/.test(path)) {
|
|
76
|
+
errors.push(`${routeLabel}: 'path' must not contain whitespace.`);
|
|
77
|
+
}
|
|
78
|
+
const pathParams = extractPathParamNames(path);
|
|
79
|
+
const declaredParams = isRecord(params) ? Object.keys(params) : [];
|
|
80
|
+
pathParams.forEach(name => {
|
|
81
|
+
if (!declaredParams.includes(name)) {
|
|
82
|
+
errors.push(`${routeLabel}: path param '$${name}' is not declared in 'params'.`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
declaredParams.forEach(name => {
|
|
86
|
+
if (!pathParams.includes(name)) {
|
|
87
|
+
errors.push(`${routeLabel}: declared param '${name}' is not used in 'path'.`);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
const validateParams = ({ params, routeLabel, errors, }) => {
|
|
92
|
+
if (params === undefined) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!isRecord(params)) {
|
|
96
|
+
errors.push(`${routeLabel}: 'params' must be an object.`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
Object.entries(params).forEach(([name, param]) => {
|
|
100
|
+
if (!isRecord(param) || typeof param.description !== "string") {
|
|
101
|
+
errors.push(`${routeLabel}: param '${name}' must declare a string 'description'.`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (param.description.trim().length === 0) {
|
|
105
|
+
errors.push(`${routeLabel}: param '${name}' description must not be empty.`);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
const validateSearch = ({ search, routeLabel, errors, }) => {
|
|
110
|
+
if (search === undefined) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (!isRecord(search)) {
|
|
114
|
+
errors.push(`${routeLabel}: 'search' must be an object.`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
Object.entries(search).forEach(([name, param]) => {
|
|
118
|
+
if (!isRecord(param) || typeof param.description !== "string") {
|
|
119
|
+
errors.push(`${routeLabel}: search param '${name}' must declare a string 'description'.`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (param.description.trim().length === 0) {
|
|
123
|
+
errors.push(`${routeLabel}: search param '${name}' description must not be empty.`);
|
|
124
|
+
}
|
|
125
|
+
if (param.required !== undefined && typeof param.required !== "boolean") {
|
|
126
|
+
errors.push(`${routeLabel}: search param '${name}' 'required' must be a boolean.`);
|
|
127
|
+
}
|
|
128
|
+
if (param.type !== undefined &&
|
|
129
|
+
(typeof param.type !== "string" || !AI_NAVIGATION_SEARCH_PARAM_TYPES.some(allowed => allowed === param.type))) {
|
|
130
|
+
errors.push(`${routeLabel}: search param '${name}' 'type' must be one of ${AI_NAVIGATION_SEARCH_PARAM_TYPES.join(", ")}.`);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
const isSerializable = (value) => {
|
|
135
|
+
try {
|
|
136
|
+
JSON.stringify(value);
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Structural validation for an extension's `aiNavigation` catalog. Returns an
|
|
145
|
+
* array of human-readable error messages; an empty array means the metadata is
|
|
146
|
+
* valid. Shared by the build (`updateExtensions`) and the server
|
|
147
|
+
* (`manifest-validator.ts`) so both choke points enforce identical rules.
|
|
148
|
+
*/
|
|
149
|
+
const validateIrisAiNavigation = ({ extensionId, extensionType, aiNavigation, }) => {
|
|
150
|
+
if (aiNavigation === undefined) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
const errors = [];
|
|
154
|
+
const prefix = `aiNavigation (extension '${extensionId}')`;
|
|
155
|
+
if (!(0, aiNavigableExtension_1.isAiNavigableExtensionType)(extensionType)) {
|
|
156
|
+
errors.push(`${prefix}: extension type '${extensionType}' does not support aiNavigation (allowed: ${(0, aiNavigableExtension_1.aiNavigableExtensionTypeNames)().join(", ")}).`);
|
|
157
|
+
}
|
|
158
|
+
if (!isRecord(aiNavigation)) {
|
|
159
|
+
errors.push(`${prefix}: must be an object.`);
|
|
160
|
+
return errors;
|
|
161
|
+
}
|
|
162
|
+
const { routes } = aiNavigation;
|
|
163
|
+
if (!Array.isArray(routes)) {
|
|
164
|
+
errors.push(`${prefix}: 'routes' must be an array.`);
|
|
165
|
+
return errors;
|
|
166
|
+
}
|
|
167
|
+
if (routes.length > exports.AI_NAVIGATION_MAX_ROUTES) {
|
|
168
|
+
errors.push(`${prefix}: at most ${exports.AI_NAVIGATION_MAX_ROUTES} routes are allowed.`);
|
|
169
|
+
}
|
|
170
|
+
if (!isSerializable(aiNavigation)) {
|
|
171
|
+
errors.push(`${prefix}: metadata must be serializable.`);
|
|
172
|
+
}
|
|
173
|
+
const rootOnly = AI_NAVIGATION_ROOT_ONLY_EXTENSION_TYPES.includes(extensionType);
|
|
174
|
+
if (rootOnly && routes.length > 1) {
|
|
175
|
+
errors.push(`${prefix}: extension type '${extensionType}' has no deep-linkable host URL, so at most one route ('/') is allowed.`);
|
|
176
|
+
}
|
|
177
|
+
routes.forEach((route, index) => {
|
|
178
|
+
if (!isRecord(route)) {
|
|
179
|
+
errors.push(`${prefix} route #${index}: must be an object.`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const routeLabel = `${prefix} route #${index} (${typeof route.path === "string" ? route.path : "unknown path"})`;
|
|
183
|
+
validateText({
|
|
184
|
+
value: route.title,
|
|
185
|
+
field: "title",
|
|
186
|
+
maxLength: exports.AI_NAVIGATION_TITLE_MAX_LENGTH,
|
|
187
|
+
routeLabel,
|
|
188
|
+
errors,
|
|
189
|
+
});
|
|
190
|
+
validateText({
|
|
191
|
+
value: route.description,
|
|
192
|
+
field: "description",
|
|
193
|
+
maxLength: exports.AI_NAVIGATION_DESCRIPTION_MAX_LENGTH,
|
|
194
|
+
routeLabel,
|
|
195
|
+
errors,
|
|
196
|
+
});
|
|
197
|
+
validatePath({ path: route.path, params: route.params, routeLabel, errors });
|
|
198
|
+
validateParams({ params: route.params, routeLabel, errors });
|
|
199
|
+
validateSearch({ search: route.search, routeLabel, errors });
|
|
200
|
+
if (rootOnly && route.path !== "/") {
|
|
201
|
+
errors.push(`${routeLabel}: extension type '${extensionType}' has no deep-linkable host URL, so 'path' must be '/'.`);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
return errors;
|
|
205
|
+
};
|
|
206
|
+
exports.validateIrisAiNavigation = validateIrisAiNavigation;
|
|
207
|
+
//# sourceMappingURL=irisAiNavigationValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irisAiNavigationValidation.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/irisAiNavigationValidation.ts"],"names":[],"mappings":"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","sourcesContent":["import { aiNavigableExtensionTypeNames, isAiNavigableExtensionType } from \"./aiNavigableExtension\";\nimport { IrisAiNavigationSearchParam } from \"./irisAiNavigation\";\nimport { IrisAppExtensionType } from \"./irisAppExtensionManifest\";\n\nexport const AI_NAVIGATION_MAX_ROUTES = 50;\nexport const AI_NAVIGATION_TITLE_MAX_LENGTH = 80;\nexport const AI_NAVIGATION_DESCRIPTION_MAX_LENGTH = 300;\n\nconst AI_NAVIGATION_SEARCH_PARAM_TYPES: ReadonlyArray<NonNullable<IrisAiNavigationSearchParam[\"type\"]>> = [\n \"string\",\n \"number\",\n \"boolean\",\n];\n\nconst PATH_PARAM_SEGMENT = /\\$([a-zA-Z][a-zA-Z0-9_]*)/g;\n\nconst HTML_PATTERN = /[<>]/;\nconst URL_PATTERN = /(https?:\\/\\/|www\\.)/i;\n\n/**\n * Markup constructs rather than bare characters, so ordinary prose such as\n * \"Key #1\" or \"asset_id\" stays valid: links/images, fenced or inline code,\n * paired emphasis, strikethrough, and heading or blockquote line prefixes.\n */\nconst MARKDOWN_PATTERNS: ReadonlyArray<RegExp> = [\n /!?\\[[^\\]]*\\]\\([^)]*\\)/,\n /`/,\n /\\*\\*[\\s\\S]+?\\*\\*/,\n /__[\\s\\S]+?__/,\n /\\*[^*\\s][\\s\\S]*?\\*/,\n /~~[\\s\\S]+?~~/,\n /(^|\\n)\\s*(#{1,6}\\s|>\\s|[-*+]\\s|\\d+\\.\\s)/,\n];\n\n/**\n * Extension types whose host URL cannot express an in-app path, so every\n * annotated route would collapse onto the same destination. They may advertise\n * the extension root only.\n */\nconst AI_NAVIGATION_ROOT_ONLY_EXTENSION_TYPES: ReadonlyArray<IrisAppExtensionType> = [\"IRIS_APP_SETTINGS_EXTENSION\"];\n\nexport type AiNavigationValidationInput = {\n readonly extensionId: string;\n readonly extensionType: IrisAppExtensionType;\n /** Untrusted at the server choke point: comes from a published manifest. */\n readonly aiNavigation: unknown;\n};\n\nconst extractPathParamNames = (path: string): ReadonlyArray<string> =>\n Array.from(path.matchAll(PATH_PARAM_SEGMENT), match => match[1]).filter((name): name is string => name !== undefined);\n\nconst isRecord = (value: unknown): value is Readonly<Record<string, unknown>> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\n/** Returns the offending substring when `value` is not plain text, else `undefined`. */\nconst findNonPlainText = (value: string): string | undefined => {\n const match = [HTML_PATTERN, URL_PATTERN, ...MARKDOWN_PATTERNS].reduce<string | undefined>(\n (found, pattern) => found ?? value.match(pattern)?.[0],\n undefined\n );\n\n return match === undefined ? undefined : match.trim();\n};\n\nconst validateText = ({\n value,\n field,\n maxLength,\n routeLabel,\n errors,\n}: {\n readonly value: unknown;\n readonly field: \"title\" | \"description\";\n readonly maxLength: number;\n readonly routeLabel: string;\n readonly errors: Array<string>;\n}): void => {\n if (typeof value !== \"string\") {\n errors.push(`${routeLabel}: '${field}' is required and must be a string.`);\n return;\n }\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n errors.push(`${routeLabel}: '${field}' must not be empty or whitespace.`);\n return;\n }\n if (value.length > maxLength) {\n errors.push(`${routeLabel}: '${field}' must be at most ${maxLength} characters.`);\n }\n const nonPlainText = findNonPlainText(value);\n if (nonPlainText !== undefined) {\n errors.push(`${routeLabel}: '${field}' must be plain text (no HTML, URLs, or markdown), found '${nonPlainText}'.`);\n }\n};\n\nconst validatePath = ({\n path,\n params,\n routeLabel,\n errors,\n}: {\n readonly path: unknown;\n readonly params: unknown;\n readonly routeLabel: string;\n readonly errors: Array<string>;\n}): void => {\n if (typeof path !== \"string\" || path.length === 0) {\n errors.push(`${routeLabel}: 'path' is required and must be a string.`);\n return;\n }\n if (!path.startsWith(\"/\")) {\n errors.push(`${routeLabel}: 'path' must start with '/'.`);\n }\n if (/:\\/\\//.test(path) || URL_PATTERN.test(path)) {\n errors.push(`${routeLabel}: 'path' must not contain a protocol or host.`);\n }\n if (path.split(\"/\").some(segment => segment === \"..\")) {\n errors.push(`${routeLabel}: 'path' must not escape the extension root.`);\n }\n if (/\\s/.test(path)) {\n errors.push(`${routeLabel}: 'path' must not contain whitespace.`);\n }\n\n const pathParams = extractPathParamNames(path);\n const declaredParams = isRecord(params) ? Object.keys(params) : [];\n\n pathParams.forEach(name => {\n if (!declaredParams.includes(name)) {\n errors.push(`${routeLabel}: path param '$${name}' is not declared in 'params'.`);\n }\n });\n declaredParams.forEach(name => {\n if (!pathParams.includes(name)) {\n errors.push(`${routeLabel}: declared param '${name}' is not used in 'path'.`);\n }\n });\n};\n\nconst validateParams = ({\n params,\n routeLabel,\n errors,\n}: {\n readonly params: unknown;\n readonly routeLabel: string;\n readonly errors: Array<string>;\n}): void => {\n if (params === undefined) {\n return;\n }\n if (!isRecord(params)) {\n errors.push(`${routeLabel}: 'params' must be an object.`);\n return;\n }\n Object.entries(params).forEach(([name, param]) => {\n if (!isRecord(param) || typeof param.description !== \"string\") {\n errors.push(`${routeLabel}: param '${name}' must declare a string 'description'.`);\n return;\n }\n if (param.description.trim().length === 0) {\n errors.push(`${routeLabel}: param '${name}' description must not be empty.`);\n }\n });\n};\n\nconst validateSearch = ({\n search,\n routeLabel,\n errors,\n}: {\n readonly search: unknown;\n readonly routeLabel: string;\n readonly errors: Array<string>;\n}): void => {\n if (search === undefined) {\n return;\n }\n if (!isRecord(search)) {\n errors.push(`${routeLabel}: 'search' must be an object.`);\n return;\n }\n Object.entries(search).forEach(([name, param]) => {\n if (!isRecord(param) || typeof param.description !== \"string\") {\n errors.push(`${routeLabel}: search param '${name}' must declare a string 'description'.`);\n return;\n }\n if (param.description.trim().length === 0) {\n errors.push(`${routeLabel}: search param '${name}' description must not be empty.`);\n }\n if (param.required !== undefined && typeof param.required !== \"boolean\") {\n errors.push(`${routeLabel}: search param '${name}' 'required' must be a boolean.`);\n }\n if (\n param.type !== undefined &&\n (typeof param.type !== \"string\" || !AI_NAVIGATION_SEARCH_PARAM_TYPES.some(allowed => allowed === param.type))\n ) {\n errors.push(\n `${routeLabel}: search param '${name}' 'type' must be one of ${AI_NAVIGATION_SEARCH_PARAM_TYPES.join(\", \")}.`\n );\n }\n });\n};\n\nconst isSerializable = (value: unknown): boolean => {\n try {\n JSON.stringify(value);\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Structural validation for an extension's `aiNavigation` catalog. Returns an\n * array of human-readable error messages; an empty array means the metadata is\n * valid. Shared by the build (`updateExtensions`) and the server\n * (`manifest-validator.ts`) so both choke points enforce identical rules.\n */\nexport const validateIrisAiNavigation = ({\n extensionId,\n extensionType,\n aiNavigation,\n}: AiNavigationValidationInput): ReadonlyArray<string> => {\n if (aiNavigation === undefined) {\n return [];\n }\n\n const errors: Array<string> = [];\n const prefix = `aiNavigation (extension '${extensionId}')`;\n\n if (!isAiNavigableExtensionType(extensionType)) {\n errors.push(\n `${prefix}: extension type '${extensionType}' does not support aiNavigation (allowed: ${aiNavigableExtensionTypeNames().join(\n \", \"\n )}).`\n );\n }\n\n if (!isRecord(aiNavigation)) {\n errors.push(`${prefix}: must be an object.`);\n return errors;\n }\n\n const { routes } = aiNavigation;\n\n if (!Array.isArray(routes)) {\n errors.push(`${prefix}: 'routes' must be an array.`);\n return errors;\n }\n\n if (routes.length > AI_NAVIGATION_MAX_ROUTES) {\n errors.push(`${prefix}: at most ${AI_NAVIGATION_MAX_ROUTES} routes are allowed.`);\n }\n\n if (!isSerializable(aiNavigation)) {\n errors.push(`${prefix}: metadata must be serializable.`);\n }\n\n const rootOnly = AI_NAVIGATION_ROOT_ONLY_EXTENSION_TYPES.includes(extensionType);\n\n if (rootOnly && routes.length > 1) {\n errors.push(\n `${prefix}: extension type '${extensionType}' has no deep-linkable host URL, so at most one route ('/') is allowed.`\n );\n }\n\n routes.forEach((route: unknown, index) => {\n if (!isRecord(route)) {\n errors.push(`${prefix} route #${index}: must be an object.`);\n return;\n }\n\n const routeLabel = `${prefix} route #${index} (${typeof route.path === \"string\" ? route.path : \"unknown path\"})`;\n\n validateText({\n value: route.title,\n field: \"title\",\n maxLength: AI_NAVIGATION_TITLE_MAX_LENGTH,\n routeLabel,\n errors,\n });\n validateText({\n value: route.description,\n field: \"description\",\n maxLength: AI_NAVIGATION_DESCRIPTION_MAX_LENGTH,\n routeLabel,\n errors,\n });\n validatePath({ path: route.path, params: route.params, routeLabel, errors });\n validateParams({ params: route.params, routeLabel, errors });\n validateSearch({ search: route.search, routeLabel, errors });\n\n if (rootOnly && route.path !== \"/\") {\n errors.push(\n `${routeLabel}: extension type '${extensionType}' has no deep-linkable host URL, so 'path' must be '/'.`\n );\n }\n });\n\n return errors;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irisAppCspInput.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/irisAppCspInput.ts"],"names":[],"mappings":";;;AAAA,mDAUyB;AAEzB,MAAM,WAAW,GAAG;IAClB,yBAAyB;IACzB,4BAA4B;IAC5B,uBAAuB;IACvB,gCAAgC;IAChC,uBAAuB;IACvB,2BAA2B;IAC3B,uBAAuB;IACvB,uBAAuB;IACvB,yBAAyB;IACzB,sBAAsB;CACvB,CAAC;AAIF;;GAEG;AACU,QAAA,qBAAqB,GAAG;IACnC,6BAAa;IACb,+BAAe;IACf,iCAAiB;IACjB,2BAAW;IACX,4BAAY;CACJ,CAAC;AAEX;;;;;GAKG;AACI,MAAM,4BAA4B,GAAG,CAAC,SAAiC,EAA0B,EAAE;IACxG,MAAM,aAAa,GAAG,6BAAqB,CAAC;IAC5C,MAAM,gBAAgB,GAAG,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC;IACjD,OAAO;QACL,GAAG,SAAS;QACZ,OAAO,EAAE,CAAC,GAAG,gBAAgB,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;KAC5F,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,4BAA4B,gCAOvC;AAEF;;;;;;;GAOG;AACI,MAAM,eAAe,GAAG,CAC7B,YAA4B,EAC5B,SAAkC,EACV,EAAE;IAC1B,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,IAAA,oCAA4B,EAAC,SAAS,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACxB,OAAO;YACL,YAAY,EAAE,YAAY;YAC1B,SAAS,EAAE,YAAY;YACvB,YAAY,EAAE,YAAY;YAC1B,aAAa,EAAE,YAAY;SAC5B,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,IAAA,oCAA4B,EAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC,CAAC;AAhBW,QAAA,eAAe,mBAgB1B;AAEW,QAAA,iBAAiB,GAAG;IAC/B,aAAa,EAAE,CAAC,oBAAI,CAAC;IACrB,YAAY,EAAE,CAAC,oBAAI,CAAC;IACpB,SAAS,EAAE,CAAC,oBAAI,EAAE,mCAAmC,EAAE,iCAAiC,CAAC;IACzF,YAAY,EAAE,CAAC,oBAAI,CAAC;IACpB,WAAW,EAAE,CAAC,6BAAa,EAAE,8BAA8B,CAAC;IAC5D,aAAa,EAAE,CAAC,oBAAI,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,GAAG,WAAW,CAAC;IACjF,cAAc,EAAE,CAAC,oBAAI,CAAC;IACtB,YAAY,EAAE,CAAC,oBAAI,CAAC;IACpB,UAAU,EAAE,CAAC,oBAAI,EAAE,2BAA2B,CAAC;IAC/C,2BAA2B,EAAE,IAAI;IACjC,OAAO,EAAE,CAAC,GAAG,6BAAqB,CAAC;CACpC,CAAC","sourcesContent":["import {\n ALLOW_DOWNLOADS,\n ALLOW_FORMS,\n ALLOW_POPUPS,\n ALLOW_SAME_ORIGIN,\n ALLOW_SCRIPTS,\n CSPDirectives,\n NONE,\n SELF,\n UNSAFE_INLINE,\n} from \"./cspDirectives\";\n\nconst BrandedUrls = [\n \"https://*.trackunit.com\",\n \"https://*.wackerneuson.com\",\n \"https://*.manitou.com\",\n \"https://*.niftylinkmanager.com\",\n \"https://*.skyjack.com\",\n \"https://*.ahernaccess.com\",\n \"https://*.magnith.com\",\n \"https://*.terberg.com\",\n \"https://*.mymecalac.com\",\n \"https://*.delille.be\",\n];\n\nexport type { CSPDirectives } from \"./cspDirectives\";\n\n/**\n * Default sandbox directives for the Iris Apps, these are the default directives that are allowed for all Iris Apps.\n */\nexport const irisAppDefaultSandbox = [\n ALLOW_SCRIPTS,\n ALLOW_DOWNLOADS,\n ALLOW_SAME_ORIGIN,\n ALLOW_FORMS,\n ALLOW_POPUPS,\n] as const;\n\n/**\n * Adds the default sandbox directives to the CSP header\n *\n * @param cspHeader - The CSP header to add the default sandbox directives to\n * @returns {Partial<CSPDirectives>} - The CSP header with the default sandbox directives added\n */\nexport const addDefaultSandboxToCspHeader = (cspHeader: Partial<CSPDirectives>): Partial<CSPDirectives> => {\n const sandboxResult = irisAppDefaultSandbox;\n const cspHeaderSandbox = cspHeader.sandbox ?? [];\n return {\n ...cspHeader,\n sandbox: [...cspHeaderSandbox, ...sandboxResult.filter(v => !cspHeaderSandbox.includes(v))],\n };\n};\n\n/**\n * This function is used to generate the CSP input for the Iris Apps Csp Header\n * automatically adds the default sandbox directives to the CSP input\n *\n * @param validDomains input legacy validDomains from manifest\n * @param cspHeader input cspHeader from manifest\n * @returns {Partial<CSPDirectives>} the CSP input for the Iris Apps Csp Header\n */\nexport const irisAppCspInput = (\n validDomains?: Array<string>,\n cspHeader?: Partial<CSPDirectives>\n): Partial<CSPDirectives> => {\n if (cspHeader) {\n return addDefaultSandboxToCspHeader(cspHeader);\n } else if (validDomains) {\n return {\n \"script-src\": validDomains,\n \"img-src\": validDomains,\n \"worker-src\": validDomains,\n \"connect-src\": validDomains,\n };\n } else {\n return addDefaultSandboxToCspHeader({});\n }\n};\n\nexport const irisAppDefaultCsp = {\n \"default-src\": [SELF],\n \"script-src\": [SELF],\n \"img-src\": [SELF, \"https://images.iris.trackunit.com\", \"https://*.awsapi.trackunit.com/\"],\n \"worker-src\": [SELF],\n \"style-src\": [UNSAFE_INLINE, \"https://fonts.googleapis.com\"],\n \"connect-src\": [SELF, \"https://*.sentry.io\", \"https://sentry.io\", ...BrandedUrls],\n \"manifest-src\": [NONE],\n \"object-src\": [NONE],\n \"font-src\": [SELF, \"https://fonts.gstatic.com\"],\n \"upgrade-insecure-requests\": true,\n sandbox: [...irisAppDefaultSandbox],\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irisAppCustomFields.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/irisAppCustomFields.ts"],"names":[],"mappings":";;;AAkBa,QAAA,SAAS,GAAG;IACvB;;OAEG;IACH,OAAO,EAAE,SAAS;IAClB;;OAEG;IACH,yBAAyB,EAAE,2BAA2B;IACtD;;OAEG;IACH,MAAM,EAAE,QAAQ;CACR,CAAC;AAGX;;GAEG;AACI,MAAM,6BAA6B,GAAG,CAC3C,MAA6F,EACtD,EAAE;IACzC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC,CAAC;AAJW,QAAA,6BAA6B,iCAIxC;AAwGW,QAAA,iBAAiB,GAAG;IAC/B,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;IACpB,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;IACtC,mBAAmB,EAAE,qBAAqB;IAC1C,gBAAgB,EAAE,kBAAkB;IACpC,kBAAkB,EAAE,oBAAoB;IACxC,KAAK,EAAE,OAAO;IACd,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,gBAAgB,EAAE,kBAAkB;IACpC,wBAAwB,EAAE,0BAA0B;IACpD,UAAU,EAAE,YAAY;IACxB,GAAG,EAAE,KAAK;IACV,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,eAAe,EAAE,iBAAiB;IAClC,sBAAsB,EAAE,wBAAwB;IAChD,WAAW,EAAE,aAAa;IAC1B,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IACxB,aAAa,EAAE,eAAe;IAC9B,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,cAAc,EAAE,gBAAgB;IAChC,gBAAgB,EAAE,kBAAkB;IACpC,IAAI,EAAE,MAAM;IACZ,aAAa,EAAE,eAAe;IAC9B,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,qBAAqB,EAAE,uBAAuB;IAC9C,eAAe,EAAE,iBAAiB;IAClC,gBAAgB,EAAE,kBAAkB;IACpC,UAAU,EAAE,YAAY;CAChB,CAAC;AAGX;;GAEG;AACU,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IACxB,aAAa,EAAE,eAAe;IAC9B,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,cAAc,EAAE,gBAAgB;IAChC,gBAAgB,EAAE,kBAAkB;IACpC,IAAI,EAAE,MAAM;IACZ,aAAa,EAAE,eAAe;IAC9B,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,qBAAqB,EAAE,uBAAuB;CACtC,CAAC;AAMX;;GAEG;AACU,QAAA,MAAM,GAAG;IACpB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,aAAa;IACzB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,eAAe;IAC7B,iBAAiB,EAAE,mBAAmB;IACtC,mBAAmB,EAAE,qBAAqB;IAC1C,gBAAgB,EAAE,kBAAkB;IACpC,kBAAkB,EAAE,oBAAoB;IACxC,KAAK,EAAE,OAAO;IACd,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,gBAAgB,EAAE,kBAAkB;IACpC,wBAAwB,EAAE,0BAA0B;IACpD,GAAG,EAAE,KAAK;IACV,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;CACJ,CAAC","sourcesContent":["import { TranslationKey, TranslationLanguageKeys } from \"./irisAppExtensionManifest\";\n\nexport declare type CustomFieldDefinitionType =\n | \"STRING\"\n | \"STRING_LIST\"\n | \"NUMBER\"\n | \"DATE\"\n | \"BOOLEAN\"\n | \"DROPDOWN\"\n | \"EMAIL\"\n | \"PHONE_NUMBER\"\n | \"WEB_ADDRESS\"\n | \"JSON\"\n | \"MONETARY\"\n | \"FILE\";\n\nexport declare type EntityType = \"ASSET\" | \"ACCOUNT\" | \"SITE\" | \"GROUP\" | \"CUSTOMER\";\n\nexport const ScopeType = {\n /**\n * Values with account scope will be shared within a single account\n */\n ACCOUNT: \"ACCOUNT\",\n /**\n * Values will be shared within a single account (write) and visible to all accounts (read)\n */\n ACCOUNT_WRITE_GLOBAL_READ: \"ACCOUNT_WRITE_GLOBAL_READ\",\n /**\n * Values with global scope will be shared between all accounts with access to the entity.\n */\n GLOBAL: \"GLOBAL\",\n} as const;\nexport type ScopeTypeType = (typeof ScopeType)[keyof typeof ScopeType];\n\n/**\n * Test if the object is a CustomFieldTranslation array.\n */\nexport const isCustomFieldTranslationArray = (\n object: CustomFieldTranslationArray | { title: TranslationKey; description?: TranslationKey }\n): object is CustomFieldTranslationArray => {\n return Array.isArray(object);\n};\n\nexport interface CustomFieldTranslation {\n language: TranslationLanguageKeys;\n title: string;\n description?: string;\n}\n\nexport interface CustomFieldTranslationWithoutEnglish {\n language: Exclude<TranslationLanguageKeys, \"en\">;\n title: string;\n description?: string;\n}\n\nexport type CustomFieldTranslationArray = [\n { language: \"en\"; title: string; description?: string },\n ...Array<CustomFieldTranslationWithoutEnglish>,\n];\n\nexport interface AbstractCustomFieldDefinition {\n /**\n * The key is the name you use to get the custom field.\n */\n key: string;\n\n /**\n * The type of the entity to attach this custom field on.\n */\n entityType: EntityType;\n\n /**\n * Who can access the field value. Default is only within the users account.\n */\n scopeType?: ScopeTypeType;\n\n /**\n * The translations for the custom field definition.\n * For Arrays of translations, the list must contain the language \"en\" as the default.\n * Either a list of translations or a single translation object with\n * translation keys it will look for all available languages in src/locales/<languagecode>/translation.json\n */\n translations: CustomFieldTranslationArray | { title: TranslationKey; description?: TranslationKey };\n\n /**\n * Should this be visible in the generic UI in Manager.\n */\n uiVisible?: boolean;\n\n /**\n * Should this be editable in the generic UI in Manager. This does not mean you cannot change it inside a app.\n */\n uiEditable?: boolean;\n\n /**\n * The type of this custom field definition\n */\n type: CustomFieldDefinitionType;\n}\n\nexport interface StringFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"STRING\";\n minimumLength?: number;\n maximumLength?: number;\n pattern?: string;\n}\n\nexport interface StringListFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"STRING_LIST\";\n itemMinimumLength?: number;\n itemMaximumLength?: number;\n pattern?: string;\n maximumItems?: number;\n}\n\nexport interface EmailFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"EMAIL\";\n}\n\nexport interface WebAddressFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"WEB_ADDRESS\";\n}\n\nexport interface PhoneNumberFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"PHONE_NUMBER\";\n}\nexport interface BooleanFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"BOOLEAN\";\n}\n\nexport interface DateFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"DATE\";\n}\n\nexport interface DropDownFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"DROPDOWN\";\n multiSelect?: boolean;\n allValues?: Array<string>;\n /**\n * Map from old values not in the allValues to new values. Used for updating existing data when changing\n * the drop down options.\n */\n valueReplacements?: Record<string, string>;\n}\n\nexport const UnitOfMeasurement = {\n NEWTON: \"NEWTON\",\n PASCAL: \"PASCAL\",\n KILOPASCAL: \"KILOPASCAL\",\n WATT: \"WATT\",\n BAR: \"BAR\",\n CENTIMETRE: \"CENTIMETRE\",\n MILLIMETRE: \"MILLIMETRE\",\n METRE: \"METRE\",\n KILOMETRE: \"KILOMETRE\",\n GRAM: \"GRAM\",\n KILOGRAM: \"KILOGRAM\",\n VOLT: \"VOLT\",\n AMPERE_HOUR: \"AMPERE_HOUR\",\n KILOWATT: \"KILOWATT\",\n KILOWATT_HOUR: \"KILOWATT_HOUR\",\n KILOGRAM_PER_HOUR: \"KILOGRAM_PER_HOUR\",\n KILOGRAM_PER_SECOND: \"KILOGRAM_PER_SECOND\",\n SQUARE_KILOMETRE: \"SQUARE_KILOMETRE\",\n KILOMETRE_PER_HOUR: \"KILOMETRE_PER_HOUR\",\n LITRE: \"LITRE\",\n SQUARE_METRE: \"SQUARE_METRE\",\n CUBIC_METRE: \"CUBIC_METRE\",\n METRE_PER_SECOND: \"METRE_PER_SECOND\",\n METRE_PER_SECOND_SQUARED: \"METRE_PER_SECOND_SQUARED\",\n METRIC_TON: \"METRIC_TON\",\n ARE: \"ARE\",\n HECTARE: \"HECTARE\",\n YEAR: \"YEAR\",\n MONTH: \"MONTH\",\n DAY: \"DAY\",\n HOUR: \"HOUR\",\n LITRES_PER_HOUR: \"LITRES_PER_HOUR\",\n REVOLUTIONS_PER_MINUTE: \"REVOLUTIONS_PER_MINUTE\",\n VOLT_AMPERE: \"VOLT_AMPERE\",\n G_FORCE: \"G_FORCE\",\n CELSIUS: \"CELSIUS\",\n PERCENT: \"PERCENT\",\n DEGREE_ANGLE: \"DEGREE_ANGLE\",\n MILLISECOND: \"MILLISECOND\",\n SECOND: \"SECOND\",\n MINUTE: \"MINUTE\",\n WEEK: \"WEEK\",\n AMPERE: \"AMPERE\",\n HERTZ: \"HERTZ\",\n ACRE: \"ACRE\",\n FOOT: \"FOOT\",\n SQUARE_FOOT: \"SQUARE_FOOT\",\n CUBIC_FOOT: \"CUBIC_FOOT\",\n GALLON_LIQUID: \"GALLON_LIQUID\",\n INCH: \"INCH\",\n POUND: \"POUND\",\n POUND_PER_HOUR: \"POUND_PER_HOUR\",\n POUND_PER_SECOND: \"POUND_PER_SECOND\",\n MILE: \"MILE\",\n MILE_PER_HOUR: \"MILE_PER_HOUR\",\n OUNCE: \"OUNCE\",\n US_TON: \"US_TON\",\n YARD: \"YARD\",\n POUND_PER_SQUARE_INCH: \"POUND_PER_SQUARE_INCH\",\n INCHES_OF_WATER: \"INCHES_OF_WATER\",\n GALLONS_PER_HOUR: \"GALLONS_PER_HOUR\",\n FAHRENHEIT: \"FAHRENHEIT\",\n} as const;\nexport type UnitOfMeasurementType = (typeof UnitOfMeasurement)[keyof typeof UnitOfMeasurement];\n\n/**\n * @deprecated Use UnitOfMeasurement instead\n */\nexport const UnitUs = {\n acre: \"ACRE\",\n foot: \"FOOT\",\n square_foot: \"SQUARE_FOOT\",\n cubic_foot: \"CUBIC_FOOT\",\n gallon_liquid: \"GALLON_LIQUID\",\n inch: \"INCH\",\n pound: \"POUND\",\n pound_per_hour: \"POUND_PER_HOUR\",\n pound_per_second: \"POUND_PER_SECOND\",\n mile: \"MILE\",\n mile_per_hour: \"MILE_PER_HOUR\",\n ounce: \"OUNCE\",\n ton_us: \"US_TON\",\n yard: \"YARD\",\n pound_per_square_inch: \"POUND_PER_SQUARE_INCH\",\n} as const;\n/**\n * @deprecated Use UnitOfMeasurementType instead\n */\nexport type UnitUsType = (typeof UnitUs)[keyof typeof UnitUs];\n\n/**\n * @deprecated Use UnitOfMeasurement instead\n */\nexport const UnitSi = {\n newton: \"NEWTON\",\n pascal: \"PASCAL\",\n kilopascal: \"KILOPASCAL\",\n amperehour: \"AMPERE_HOUR\",\n volt: \"VOLT\",\n watt: \"WATT\",\n bar: \"BAR\",\n centimetre: \"CENTIMETRE\",\n millimetre: \"MILLIMETRE\",\n metre: \"METRE\",\n kilometre: \"KILOMETRE\",\n gram: \"GRAM\",\n kilogram: \"KILOGRAM\",\n kilowatt: \"KILOWATT\",\n kilowatthour: \"KILOWATT_HOUR\",\n kilogram_per_hour: \"KILOGRAM_PER_HOUR\",\n kilogram_per_second: \"KILOGRAM_PER_SECOND\",\n square_kilometre: \"SQUARE_KILOMETRE\",\n kilometre_per_hour: \"KILOMETRE_PER_HOUR\",\n litre: \"LITRE\",\n square_metre: \"SQUARE_METRE\",\n cubic_metre: \"CUBIC_METRE\",\n metre_per_second: \"METRE_PER_SECOND\",\n metre_per_second_squared: \"METRE_PER_SECOND_SQUARED\",\n ton: \"TON\",\n hectare: \"HECTARE\",\n hour: \"HOUR\",\n} as const;\n/**\n * @deprecated Use UnitOfMeasurementType instead\n */\nexport type UnitSiType = (typeof UnitSi)[keyof typeof UnitSi];\n\nexport interface DecimalNumberFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"NUMBER\";\n\n minimum?: number;\n maximum?: number;\n\n unitSi?: UnitOfMeasurementType;\n unitUs?: UnitOfMeasurementType;\n\n isInteger: false;\n}\n\nexport interface IntegerNumberFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"NUMBER\";\n\n minimum?: number;\n maximum?: number;\n\n isInteger: true;\n}\n\nexport type JSONValue = string | number | boolean | null | { [x: string]: JSONValue } | Array<JSONValue>;\n\nexport interface JsonFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"JSON\";\n}\n\nexport interface MonetaryFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"MONETARY\";\n /**\n * The currency of the monetary field definition - ISO 4217 compliant.\n */\n currency: string;\n}\n\nexport interface FileFieldDefinition extends AbstractCustomFieldDefinition {\n type: \"FILE\";\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irisAppExtensionManifest.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/irisAppExtensionManifest.ts"],"names":[],"mappings":";;;AAAa,QAAA,qBAAqB,GAAG;IACnC,kBAAkB;IAClB,6BAA6B;IAC7B,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;IAClB,sBAAsB;IACtB,gCAAgC;IAChC,yBAAyB;IACzB,qBAAqB;IACrB,qBAAqB;IACrB,0BAA0B;CAClB,CAAC;AAIE,QAAA,mBAAmB,GAAgC;IAC9D,kBAAkB;IAClB,qBAAqB;IACrB,0BAA0B;CAC3B,CAAC;AAEW,QAAA,wBAAwB,GAAgC;IACnE,qBAAqB;IACrB,0BAA0B;CAC3B,CAAC;AA8DW,QAAA,YAAY,GAAG;IAC1B,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;CACI,CAAC","sourcesContent":["export const irisAppExtensionTypes = [\n \"REPORT_EXTENSION\",\n \"IRIS_APP_SETTINGS_EXTENSION\",\n \"ADMIN_EXTENSION\",\n \"FLEET_EXTENSION\",\n \"WIDGET_EXTENSION\",\n \"ASSET_HOME_EXTENSION\",\n \"ASSET_EVENTS_ACTIONS_EXTENSION\",\n \"CUSTOMER_HOME_EXTENSION\",\n \"SITE_HOME_EXTENSION\",\n \"LIFECYCLE_EXTENSION\",\n \"SERVERSIDE_API_EXTENSION\",\n] as const;\n\nexport type IrisAppExtensionType = (typeof irisAppExtensionTypes)[number];\n\nexport const nonUiExtensionTypes: Array<IrisAppExtensionType> = [\n \"REPORT_EXTENSION\",\n \"LIFECYCLE_EXTENSION\",\n \"SERVERSIDE_API_EXTENSION\",\n];\n\nexport const serverSideExtensionTypes: Array<IrisAppExtensionType> = [\n \"LIFECYCLE_EXTENSION\",\n \"SERVERSIDE_API_EXTENSION\",\n];\n\nexport type RegExpType = {\n pattern: string | RegExp;\n};\n\n/**\n * Used to limit access to iris apps based on custom field value.\n */\nexport interface RequiredCustomField {\n /**\n * The custom field key to check for, only dropdown, string or boolean is supported.\n */\n customFieldKey: string;\n\n /**\n * The requiredValue that is required for the app extension to be visible.\n */\n requiredValue: string | Array<string> | boolean;\n}\n\nexport interface AbstractExtensionManifest {\n /** The id of the app extension, will be part of the URL in the manager */\n id: string;\n\n /**\n * The path to the main entry point for the extension.\n *\n * @default \"index.tsx\"\n */\n main?: string;\n\n /**\n * The relative path from the NX workspace to this projects source Root.\n */\n sourceRoot: string;\n\n /** The type of the app extension */\n type: IrisAppExtensionType;\n}\n\nexport interface Translations {\n en: string;\n da?: string;\n de?: string;\n cs?: string;\n nl?: string;\n fr?: string;\n fi?: string;\n hu?: string;\n it?: string;\n nb?: string;\n pl?: string;\n pt?: string;\n ru?: string;\n ro?: string;\n es?: string;\n sv?: string;\n ja?: string;\n th?: string;\n}\n\nexport const languageKeys = [\n \"en\",\n \"da\",\n \"de\",\n \"cs\",\n \"nl\",\n \"fr\",\n \"fi\",\n \"hu\",\n \"it\",\n \"nb\",\n \"pl\",\n \"pt\",\n \"ru\",\n \"ro\",\n \"es\",\n \"sv\",\n \"ja\",\n \"th\",\n] as const;\n\nexport type TranslationLanguageKeys = (typeof languageKeys)[number];\n\nexport interface TranslationKey {\n key: string;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irisAppInstallationConfig.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-api/src/types/irisAppInstallationConfig.ts"],"names":[],"mappings":";;;AAEa,QAAA,kBAAkB,GAAG;IAChC,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,cAAc;IAC5B,SAAS,EAAE,WAAW;IACtB,2BAA2B,EAAE,6BAA6B;IAC1D,8BAA8B,EAAE,gCAAgC;CACxD,CAAC","sourcesContent":["import { SubscriptionPackage } from \"./subscriptionPackages\";\n\nexport const installationPolicy = {\n PERMANENT: \"PERMANENT\",\n PREINSTALLED: \"PREINSTALLED\",\n ON_DEMAND: \"ON_DEMAND\",\n ON_DEMAND_REQUIRES_APPROVAL: \"ON_DEMAND_REQUIRES_APPROVAL\",\n PREINSTALLED_REQUIRES_APPROVAL: \"PREINSTALLED_REQUIRES_APPROVAL\",\n} as const;\nexport type InstallationPolicy = (typeof installationPolicy)[keyof typeof installationPolicy];\n\n/**\n * @deprecated Use `InstallationConfig` instead.\n */\nexport interface InstallationConfigLegacy {\n /**\n * Installation policy for the app.\n *\n * - `PERMANENT`: Always installed and cannot be removed by the end customer.\n * - `PREINSTALLED`: Initially installed and can be removed by the end customer.\n * - `ON_DEMAND`: Available to be installed and removed by the end customer.\n * - `ON_DEMAND_REQUIRES_APPROVAL`: Requires approval by the Trackunit billing team before the end customer can install it. Behaves like 'ON_DEMAND' after receiving approval.\n * - `PREINSTALLED_REQUIRES_APPROVAL`: Requires approval by the Trackunit billing team and installs automatically once approved. Behaves like 'PREINSTALLED' after receiving approval.\n *\n * All policies will take into consideration both `accountIds` and `pricingPlans`.\n *\n * @deprecated Use `pricingPlanPolicy` instead.\n */\n policy: InstallationPolicy;\n /**\n * List of account IDs that can install this Iris App or `\"ALL_ACCOUNTS\"` if available for all customers.\n */\n accountIds: \"ALL_ACCOUNTS\" | Array<string>;\n /**\n * List of pricing plans the Iris App is available at or `\"ALL_PLANS\"` if available in all plans.\n *\n * @deprecated Use `pricingPlanPolicy` instead.\n */\n pricingPlans: \"ALL_PLANS\" | Array<SubscriptionPackage>;\n /**\n * Ensure that both cannot be set at the same time.\n */\n pricingPlanPolicy?: never;\n}\n\ninterface InstallationConfigBase {\n /**\n * Installation policy for the app per pricing plan.\n *\n * - `PERMANENT`: Always installed and cannot be removed by the end customer.\n * - `PREINSTALLED`: Initially installed and can be removed by the end customer.\n * - `ON_DEMAND`: Available to be installed and removed by the end customer.\n * - `ON_DEMAND_REQUIRES_APPROVAL`: Requires approval by the Trackunit billing team before the end customer can install it. Behaves like 'ON_DEMAND' after receiving approval.\n * - `PREINSTALLED_REQUIRES_APPROVAL`: Requires approval by the Trackunit billing team and installs automatically once approved. Behaves like 'PREINSTALLED' after receiving approval.\n *\n * All policies will also filter by `accountIds` if specified.\n *\n * If a pricing plan is not specified it means it will not be available for that plan.\n *\n */\n pricingPlanPolicy:\n | ({ [KeySubscriptionPackage in SubscriptionPackage]?: InstallationPolicy } & { ALL_PLANS?: never })\n | { ALL_PLANS: InstallationPolicy };\n\n /**\n * This field is optional and can be used to specify the identifiers of other Iris apps that are included within this bundle.\n * It helps in managing and organizing multiple apps that are packaged together.\n */\n irisAppsInsideBundle?: Array<string>;\n}\n\nexport interface InstallationConfig extends InstallationConfigBase {\n /**\n * List of account IDs that can install this Iris App or `\"ALL_ACCOUNTS\"` if available for all customers.\n */\n accountIds: \"ALL_ACCOUNTS\" | [string, ...Array<string>];\n}\n\nexport interface InstallationConfigExcludeAccountIds extends InstallationConfigBase {\n /**\n * List of account IDs that can install this Iris App or `\"ALL_ACCOUNTS\"` if available for all customers.\n */\n accountIds: \"ALL_ACCOUNTS\";\n /**\n * List of account IDs that can't install this Iris App. Available if accountIds is set to `\"ALL_ACCOUNTS\"`.\n */\n excludeAccountIds?: Array<string>;\n}\n\nexport interface InstallationConfigAllowOrganizationIds extends InstallationConfigBase {\n /**\n * List of organization IDs that are allowed to install this Iris App.\n */\n allowOrganizationIds: Array<string>;\n}"]}
|