153 lines
4.6 KiB
TypeScript
153 lines
4.6 KiB
TypeScript
import { getApiUrl } from "@dashboard/config";
|
|
import { FlagWithName } from "@dashboard/hooks/useFlags/types";
|
|
import { stringifyQs } from "@dashboard/utils/urls";
|
|
import { ThemeType } from "@saleor/app-sdk/app-bridge";
|
|
import urlJoin from "url-join";
|
|
|
|
import { Dialog, SingleAction } from "../types";
|
|
|
|
export const MANIFEST_ATTR = "manifestUrl";
|
|
|
|
export type AppListUrlDialog = "app-installation-remove";
|
|
export type AppListUrlQueryParams = Dialog<AppListUrlDialog> & SingleAction;
|
|
|
|
export type AppDetailsUrlDialog =
|
|
| "app-activate"
|
|
| "app-deactivate"
|
|
| "app-delete";
|
|
export interface AppDetailsUrlMountQueryParams {
|
|
productId?: string;
|
|
productIds?: string[];
|
|
orderId?: string;
|
|
customerId?: string;
|
|
customerIds?: string[];
|
|
}
|
|
|
|
interface FeatureFlagsQueryParams {
|
|
featureFlags?: Record<string, string>;
|
|
}
|
|
export interface AppDetailsCommonParams {
|
|
theme: ThemeType;
|
|
}
|
|
export type AppDetailsUrlQueryParams = Dialog<AppDetailsUrlDialog> &
|
|
SingleAction &
|
|
AppDetailsUrlMountQueryParams &
|
|
FeatureFlagsQueryParams;
|
|
|
|
export type AppInstallUrlQueryParams = Partial<{ [MANIFEST_ATTR]: string }>;
|
|
|
|
export const prepareFeatureFlagsList = (
|
|
flags: FlagWithName[],
|
|
): Record<string, string> =>
|
|
flags.reduce<Record<string, string>>((acc, flag) => {
|
|
if (flag.enabled) {
|
|
acc[flag.name] = `${flag.value || true}`;
|
|
}
|
|
return acc;
|
|
}, {});
|
|
|
|
export const AppSections = {
|
|
appsSection: "/apps/",
|
|
};
|
|
|
|
export const AppPaths = {
|
|
appListPath: AppSections.appsSection,
|
|
resolveAppPath: (id: string) => urlJoin(AppSections.appsSection, id, "app"),
|
|
resolveAppDetailsPath: (id: string) => urlJoin(AppSections.appsSection, id),
|
|
resolveAppDeepPath: (id: string, subPath: string) =>
|
|
urlJoin(AppPaths.resolveAppPath(id), subPath),
|
|
appInstallPath: urlJoin(AppSections.appsSection, "install"),
|
|
};
|
|
|
|
export const AppUrls = {
|
|
resolveAppListUrl: (params?: AppListUrlQueryParams) =>
|
|
AppPaths.appListPath + "?" + stringifyQs(params),
|
|
resolveAppUrl: (id: string, params?: AppDetailsUrlQueryParams) =>
|
|
AppPaths.resolveAppPath(encodeURIComponent(id)) + "?" + stringifyQs(params),
|
|
resolveAppDetailsUrl: (id: string, params?: AppDetailsUrlQueryParams) =>
|
|
AppPaths.resolveAppDetailsPath(encodeURIComponent(id)) +
|
|
"?" +
|
|
stringifyQs(params),
|
|
resolveAppInstallUrl: (manifestUrl: string) =>
|
|
`${AppPaths.appInstallPath}?manifestUrl=${manifestUrl}`,
|
|
resolveAppDeepUrl: (
|
|
id: string,
|
|
subPath: string,
|
|
params?: AppDetailsUrlQueryParams,
|
|
) =>
|
|
AppPaths.resolveAppDeepPath(encodeURIComponent(id), subPath) +
|
|
"?" +
|
|
stringifyQs(params),
|
|
isAppDeepUrlChange: (appId: string, from: string, to: string) => {
|
|
const appCompletePath = AppPaths.resolveAppPath(encodeURIComponent(appId));
|
|
|
|
return to.startsWith(appCompletePath) && from.startsWith(appCompletePath);
|
|
},
|
|
resolveAppDeepPathFromDashboardUrl: (dashboardUrl: string, appId: string) => {
|
|
const deepSubPath = dashboardUrl.replace(
|
|
AppPaths.resolveAppPath(encodeURIComponent(appId)),
|
|
"",
|
|
);
|
|
return deepSubPath || "/";
|
|
},
|
|
resolveAppCompleteUrlFromDashboardUrl: (
|
|
dashboardUrl: string,
|
|
appUrl?: string,
|
|
appId?: string,
|
|
) => {
|
|
if (!appUrl || !appId) {
|
|
return appUrl;
|
|
}
|
|
const deepSubPath = dashboardUrl.replace(
|
|
AppPaths.resolveAppPath(encodeURIComponent(appId)),
|
|
"",
|
|
);
|
|
const appCompleteUrl = urlJoin(appUrl, deepSubPath);
|
|
return appCompleteUrl;
|
|
},
|
|
resolveDashboardUrlFromAppCompleteUrl: (
|
|
appCompleteUrl: string,
|
|
appUrl?: string,
|
|
appId?: string,
|
|
) => {
|
|
if (!appUrl || !appId) {
|
|
return appUrl;
|
|
}
|
|
const deepSubPath = appCompleteUrl.replace(appUrl, "");
|
|
const dashboardUrl = urlJoin(
|
|
AppPaths.resolveAppPath(encodeURIComponent(appId)),
|
|
deepSubPath,
|
|
);
|
|
return dashboardUrl;
|
|
},
|
|
resolveAppIframeUrl: (
|
|
appId: string,
|
|
appUrl: string,
|
|
params: AppDetailsUrlQueryParams & AppDetailsCommonParams,
|
|
) => {
|
|
const apiUrl = new URL(getApiUrl(), window.location.origin).href;
|
|
/**
|
|
* Use host to preserve port, in case of multiple Saleors running on localhost
|
|
*/
|
|
const apiUrlHost = new URL(apiUrl).host;
|
|
|
|
const iframeContextQueryString = `?${stringifyQs(
|
|
{
|
|
/**
|
|
* @deprecated - domain will be removed in favor of saleorApiUrl.
|
|
* Current hostname (used as domain) can be extracted from full URL
|
|
*
|
|
* Difference will be:
|
|
* shop.saleor.cloud -> https://shop.saleor.cloud/graphql/
|
|
*/
|
|
domain: apiUrlHost,
|
|
saleorApiUrl: apiUrl,
|
|
id: appId,
|
|
...params,
|
|
},
|
|
"comma",
|
|
)}`;
|
|
|
|
return urlJoin(appUrl, window.location.search, iframeContextQueryString);
|
|
},
|
|
};
|