From 5cbfc4d954b080d1881a141577677b0ccbec1815 Mon Sep 17 00:00:00 2001 From: Ivan Kiral Date: Tue, 4 Jun 2024 08:35:13 +0200 Subject: [PATCH 1/8] remove env --- .env.production | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .env.production diff --git a/.env.production b/.env.production deleted file mode 100644 index add94d9..0000000 --- a/.env.production +++ /dev/null @@ -1,11 +0,0 @@ -REACT_APP_PROJECT_DOMAIN="https://kontent-ai.github.io" -REACT_APP_PROJECT_ROUTE="/sample-app-preview-react" - -REACT_APP_AUTH_REDIRECT_URL="https://kontent-ai.github.io/sample-app-preview-react/callback" -REACT_APP_AUTH_LOGOUT_RETURN_TO="https://kontent-ai.github.io/sample-app-preview-react/logout" - -REACT_APP_AUTH_DOMAIN="login.kontent.ai" -REACT_APP_AUTH_CLIENT_ID="kk5POR5ME2uYwFQWovQ32n61Z5MwDWAH" - -REACT_APP_KONTENT_URL="https://app.kontent.ai" -REACT_APP_DELIVER_URL="https://preview-deliver.kontent.ai" From ad4078332c3979eba88f398fb1b967863dd7ba15 Mon Sep 17 00:00:00 2001 From: Ivan Kiral Date: Tue, 4 Jun 2024 08:51:53 +0200 Subject: [PATCH 2/8] update projectId to environmentId --- src/App.tsx | 6 +-- src/components/ErrorPage.tsx | 14 +++---- src/components/NavigationBar.tsx | 6 +-- src/components/Product/ProductCard.tsx | 6 +-- src/components/Product/ProductsPage.tsx | 8 ++-- src/constants/routePaths.ts | 6 +-- src/context/AppContext.tsx | 46 +++++++++++----------- src/context/AppContextInitialization.tsx | 10 ++--- src/factories/createLoadApplicationData.ts | 20 +++++----- src/factories/createLoadPreviewApiKey.ts | 6 +-- src/repositories/contentItemRepository.ts | 16 ++++---- src/utils/environmentIdUtil.ts | 15 +++++++ src/utils/projectIdUtil.ts | 15 ------- 13 files changed, 87 insertions(+), 87 deletions(-) create mode 100644 src/utils/environmentIdUtil.ts delete mode 100644 src/utils/projectIdUtil.ts diff --git a/src/App.tsx b/src/App.tsx index d6e6237..ee8756a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,7 @@ import { Route, Switch } from 'react-router-dom'; import { NavigationBar } from './components/NavigationBar'; import { ProductDetailsPage } from './components/Product/ProductDetailsPage'; import { ProductsPage } from './components/Product/ProductsPage'; -import { ProductDetailsRoute, ProductsRoute, ProjectRoute } from './constants/routePaths'; +import { ProductDetailsRoute, ProductsRoute, EnvironmentRoute } from './constants/routePaths'; import { WelcomePage } from './components/WelcomePage'; import { ProgressBar } from './components/ProgressBar'; @@ -14,13 +14,13 @@ export class App extends React.PureComponent {
diff --git a/src/components/ErrorPage.tsx b/src/components/ErrorPage.tsx index 09e5c8c..3069a9d 100644 --- a/src/components/ErrorPage.tsx +++ b/src/components/ErrorPage.tsx @@ -1,7 +1,7 @@ import React from 'react'; export enum ErrorPageType { - MissingProjectId = 'missingProjectId', + MissingEnvironmentId = 'missingEnvironmentId', UnableToGetPreviewApiKey = 'unableToGetPreviewApiKey', } @@ -9,16 +9,16 @@ interface IErrorPageProps { readonly type: ErrorPageType; } -const projectIdUrlTemplate = "https://kontent-ai.github.io/sample-app-preview-react/"; +const EnvironmentIdUrlTemplate = "https://getting-started.sample.kontent.ai/"; -const MissingProjectIdErrorPageContent: React.FunctionComponent = () => ( -

Didn't you forget to provide Project Id in the url? E.g. {projectIdUrlTemplate}

+const MissingEnvironmentIdErrorPageContent: React.FunctionComponent = () => ( +

Didn't you forget to provide Environment Id in the url? E.g. {EnvironmentIdUrlTemplate}

); const UnableToGetPreviewApiKeyErrorPageContent: React.FunctionComponent = () => ( <>

There was problem retrieving Preview Api Key.

-

Did you provide correct Project Id? E.g. {projectIdUrlTemplate}

+

Did you provide correct Environment Id? E.g. {EnvironmentIdUrlTemplate}

); @@ -29,8 +29,8 @@ export const ErrorPage: React.FunctionComponent = ({ type }) =>

Ooops, there was some error!

- {type === ErrorPageType.MissingProjectId && ( - + {type === ErrorPageType.MissingEnvironmentId && ( + )} {type === ErrorPageType.UnableToGetPreviewApiKey && ( diff --git a/src/components/NavigationBar.tsx b/src/components/NavigationBar.tsx index d29ed77..59c754d 100644 --- a/src/components/NavigationBar.tsx +++ b/src/components/NavigationBar.tsx @@ -3,7 +3,7 @@ import { NavLink } from 'react-router-dom'; import './NavigationBar.css'; import { ProductsRoute, - ProjectRoute, + EnvironmentRoute, ProjectRouteParams, } from '../constants/routePaths'; import { buildPath } from "../utils/routeTransitionUtils"; @@ -20,7 +20,7 @@ export class NavigationBar extends React.PureComponent { activeClassName="navigation-bar__app-menu-button--active" className="navigation-bar__app-menu-button" exact={true} - to={buildPath(ProjectRoute, { projectId: appContext.projectId })} + to={buildPath(EnvironmentRoute, { environmentId: appContext.environmentId })} > Welcome @@ -28,7 +28,7 @@ export class NavigationBar extends React.PureComponent { (ProductsRoute, { projectId: appContext.projectId })} + to={buildPath(ProductsRoute, { environmentId: appContext.environmentId })} > Products diff --git a/src/components/Product/ProductCard.tsx b/src/components/Product/ProductCard.tsx index ba89d51..73a0ce3 100644 --- a/src/components/Product/ProductCard.tsx +++ b/src/components/Product/ProductCard.tsx @@ -24,19 +24,19 @@ const ProductCardPlaceholder: React.FunctionComponent = - ({ projectId, productId, pictureUrl, title }) => { + ({ environmentId, productId, pictureUrl, title }) => { const imageSource = pictureUrl ? pictureUrl : productImagePlaceholderUrl; return (
{productId ? ( - (ProductDetailsRoute, { projectId, productUrlSlug: productId })}> + (ProductDetailsRoute, { environmentId, productUrlSlug: productId })}> ) : ( diff --git a/src/components/Product/ProductsPage.tsx b/src/components/Product/ProductsPage.tsx index 314e373..583ef09 100644 --- a/src/components/Product/ProductsPage.tsx +++ b/src/components/Product/ProductsPage.tsx @@ -8,7 +8,7 @@ import classNames from "classnames"; interface IProductsPageProps { readonly init: () => void; - readonly projectId: string; + readonly environmentId: string; readonly products: Array; } @@ -18,7 +18,7 @@ class ProductsPage extends React.PureComponent { } render() { - const { projectId, products } = this.props; + const { environmentId, products } = this.props; const isSingleProduct = products.length === 1; return ( @@ -30,7 +30,7 @@ class ProductsPage extends React.PureComponent { title={product.elements.name.value} pictureUrl={product.elements.image.value[0] ? product.elements.image.value[0].url : ''} productId={product.elements.url.value} - projectId={projectId} + environmentId={environmentId} key={product.system.id} />) )} @@ -45,7 +45,7 @@ const ProductsPageConnected = () => ( {appContext => ( )} diff --git a/src/constants/routePaths.ts b/src/constants/routePaths.ts index c74b044..273aeeb 100644 --- a/src/constants/routePaths.ts +++ b/src/constants/routePaths.ts @@ -5,12 +5,12 @@ export const DeployedProjectRootRoute = `${process.env.REACT_APP_PROJECT_ROUTE}` export const RootRoute = '/'; export const CallbackRoute = `${RootRoute}callback`; -export const ProjectRoute = `${RootRoute}:projectId(${uuidPattern})`; -export const ProductsRoute = `${ProjectRoute}/products`; +export const EnvironmentRoute = `${RootRoute}:environmentId(${uuidPattern})`; +export const ProductsRoute = `${EnvironmentRoute}/products`; export const ProductDetailsRoute = `${ProductsRoute}/:productUrlSlug`; export type ProjectRouteParams = { - readonly projectId: string; + readonly environmentId: string; }; export type ProductDetailsRouteParams = ProjectRouteParams & { diff --git a/src/context/AppContext.tsx b/src/context/AppContext.tsx index 5516ba1..e4cb2d3 100644 --- a/src/context/AppContext.tsx +++ b/src/context/AppContext.tsx @@ -10,8 +10,8 @@ interface IAppContextState { readonly dataPollingStatus: PollingStatus; readonly previewApiKey: string; readonly previewApiKeyLoadingStatus: LoadingStatus; - readonly projectId: string; - readonly projectIdLoadingStatus: LoadingStatus; + readonly environmentId: string; + readonly environmentIdLoadingStatus: LoadingStatus; readonly articles: Array; readonly productsByUrlSlug: {[key: string]: ProductExampleContentType}; } @@ -21,9 +21,9 @@ interface IAppContextProps { readonly loadProduct: (productUrlSlug: string) => void; readonly loadProducts: () => void; readonly getProducts: () => Array; - readonly setProjectId: (projectId: string) => void; + readonly setEnvironmentId: (environmentId: string) => void; readonly setLoadingStatus: (loadingStatus: LoadingStatus) => void; - readonly setProjectIdLoadingStatus: (projectIdLoadingStatus: LoadingStatus) => void; + readonly setEnvironmentIdLoadingStatus: (environmentIdLoadingStatus: LoadingStatus) => void; readonly setPreviewApiKey: (previewApiKey: string) => void; readonly setPreviewApiKeyLoadingStatus: (previewApiKeyLoadingStatus: LoadingStatus) => void; } @@ -36,17 +36,17 @@ const defaultAppContext: IAppContext = { dataPollingStatus: PollingStatus.Stopped, previewApiKey: '', previewApiKeyLoadingStatus: LoadingStatus.NotLoaded, - projectId: '', - projectIdLoadingStatus: LoadingStatus.NotLoaded, + environmentId: '', + environmentIdLoadingStatus: LoadingStatus.NotLoaded, articles: new Array(), productsByUrlSlug: {}, loadWelcomePage: () => undefined, loadProduct: () => undefined, loadProducts: () => undefined, getProducts: () => [], - setProjectId: () => undefined, + setEnvironmentId: () => undefined, setLoadingStatus: () => undefined, - setProjectIdLoadingStatus: () => undefined, + setEnvironmentIdLoadingStatus: () => undefined, setPreviewApiKey: () => undefined, setPreviewApiKeyLoadingStatus: () => undefined, }; @@ -62,8 +62,8 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat dataPollingStatus: PollingStatus.Stopped, previewApiKey: '', previewApiKeyLoadingStatus: LoadingStatus.NotLoaded, - projectId: '', - projectIdLoadingStatus: LoadingStatus.NotLoaded, + environmentId: '', + environmentIdLoadingStatus: LoadingStatus.NotLoaded, articles: new Array(), productsByUrlSlug: {}, }; @@ -83,16 +83,16 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat this.setState({ dataPollingStatus: PollingStatus.Waiting }); }; - setProjectId = (projectId: string) => { - this.setState({ projectId }); + setEnvironmentId = (environmentId: string) => { + this.setState({ environmentId: environmentId }); }; setLoadingStatus = (loadingStatus: LoadingStatus) => { this.setState({ dataLoadingStatus: loadingStatus }); }; - setProjectIdLoadingStatus = (projectIdLoadingStatus: LoadingStatus) => { - this.setState({ projectIdLoadingStatus }); + setEnvironmentIdLoadingStatus = (environmentIdLoadingStatus: LoadingStatus) => { + this.setState({ environmentIdLoadingStatus: environmentIdLoadingStatus }); }; setPreviewApiKey = (previewApiKey: string) => { @@ -104,7 +104,7 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat }; private _loadWelcomePageData = async () => { - const articles = await getAllArticles(this.state.projectId, this.state.previewApiKey); + const articles = await getAllArticles(this.state.environmentId, this.state.previewApiKey); this.setState({ articles }); }; @@ -114,7 +114,7 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat }; private _loadProductsData = async () => { - const productsPage = await getProductsPage(this.state.projectId, this.state.previewApiKey); + const productsPage = await getProductsPage(this.state.environmentId, this.state.previewApiKey); if (productsPage && productsPage[0]) { const newProducts = productsPage[0].elements.productList.linkedItems as Array; this.setState((state) => ({ productsByUrlSlug: newProducts @@ -130,7 +130,7 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat }; private _loadProductData = async (productUrlSlug: string) => { - const product = await getProductDetailsByUrlSlug(this.state.projectId, this.state.previewApiKey, productUrlSlug); + const product = await getProductDetailsByUrlSlug(this.state.environmentId, this.state.previewApiKey, productUrlSlug); if (product) { this.setState((state) => ({ productsByUrlSlug: ({...Object.assign({}, state.productsByUrlSlug), [product.elements.url.value]: product})})); } @@ -147,10 +147,10 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat const { productsByUrlSlug, articles, - projectId, + environmentId, dataLoadingStatus, dataPollingStatus, - projectIdLoadingStatus, + environmentIdLoadingStatus, previewApiKey, previewApiKeyLoadingStatus, } = this.state; @@ -160,17 +160,17 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat dataPollingStatus, previewApiKey, previewApiKeyLoadingStatus, - projectId, - projectIdLoadingStatus, + environmentId: environmentId, + environmentIdLoadingStatus: environmentIdLoadingStatus, articles, productsByUrlSlug, loadWelcomePage: this.loadWelcomePage, loadProduct: this.loadProduct, loadProducts: this.loadProducts, getProducts: this.getProducts, - setProjectId: this.setProjectId, + setEnvironmentId: this.setEnvironmentId, setLoadingStatus: this.setLoadingStatus, - setProjectIdLoadingStatus: this.setProjectIdLoadingStatus, + setEnvironmentIdLoadingStatus: this.setEnvironmentIdLoadingStatus, setPreviewApiKey: this.setPreviewApiKey, setPreviewApiKeyLoadingStatus: this.setPreviewApiKeyLoadingStatus, }; diff --git a/src/context/AppContextInitialization.tsx b/src/context/AppContextInitialization.tsx index 8872a46..9d14452 100644 --- a/src/context/AppContextInitialization.tsx +++ b/src/context/AppContextInitialization.tsx @@ -7,7 +7,7 @@ import { ErrorPage, ErrorPageType } from "../components/ErrorPage"; import { LoadingStatus } from "../enums/LoadingStatus"; import { createLoadApplicationData } from "../factories/createLoadApplicationData"; import { createLoadPreviewApiKey } from "../factories/createLoadPreviewApiKey"; -import { getProjectIdFromUrl } from "../utils/projectIdUtil"; +import { getEnvironmentIdFromUrl } from "../utils/environmentIdUtil"; interface IAppContextInitializationProps extends RouteComponentProps { readonly authContext: IAuthContext; @@ -22,9 +22,9 @@ class AppContextInitialization extends React.PureComponent + const { environmentIdLoadingStatus, previewApiKeyLoadingStatus, dataLoadingStatus } = this.props.appContext; + if (environmentIdLoadingStatus === LoadingStatus.Failed) { + return } if (previewApiKeyLoadingStatus === LoadingStatus.Failed) { @@ -46,7 +46,7 @@ const AppContextInitializationConnected = (props: RouteComponentProps) => ( {authContext => { const loadApplicationData = createLoadApplicationData({ appContext, - getProjectIdFromUrl, + getEnvironmentIdFromUrl: getEnvironmentIdFromUrl, loadPreviewApikey: createLoadPreviewApiKey({ authContext, appContext, diff --git a/src/factories/createLoadApplicationData.ts b/src/factories/createLoadApplicationData.ts index 9c2e1ee..72217b5 100644 --- a/src/factories/createLoadApplicationData.ts +++ b/src/factories/createLoadApplicationData.ts @@ -4,27 +4,27 @@ import { LoadingStatus } from "../enums/LoadingStatus"; interface ILoadApplicationDataDeps { readonly appContext: IAppContext; readonly loadPreviewApikey: () => Promise; - readonly getProjectIdFromUrl: () => string | null; + readonly getEnvironmentIdFromUrl: () => string | null; } export const createLoadApplicationData = (deps: ILoadApplicationDataDeps) => async (): Promise => { - const { appContext, loadPreviewApikey, getProjectIdFromUrl } = deps; + const { appContext, loadPreviewApikey, getEnvironmentIdFromUrl } = deps; if (appContext.dataLoadingStatus === LoadingStatus.Finished) { return; } - if (appContext.projectIdLoadingStatus === LoadingStatus.NotLoaded) { - const projectIdFromUrl = getProjectIdFromUrl(); - if (projectIdFromUrl) { - appContext.setProjectId(projectIdFromUrl); - appContext.setProjectIdLoadingStatus(LoadingStatus.Finished); + if (appContext.environmentIdLoadingStatus === LoadingStatus.NotLoaded) { + const environmentIdFromUrl = getEnvironmentIdFromUrl(); + if (environmentIdFromUrl) { + appContext.setEnvironmentId(environmentIdFromUrl); + appContext.setEnvironmentIdLoadingStatus(LoadingStatus.Finished); } else { - appContext.setProjectIdLoadingStatus(LoadingStatus.Failed); + appContext.setEnvironmentIdLoadingStatus(LoadingStatus.Failed); } } - if (appContext.projectIdLoadingStatus === LoadingStatus.Finished && appContext.previewApiKeyLoadingStatus === LoadingStatus.NotLoaded) { + if (appContext.environmentIdLoadingStatus === LoadingStatus.Finished && appContext.previewApiKeyLoadingStatus === LoadingStatus.NotLoaded) { appContext.setPreviewApiKeyLoadingStatus(LoadingStatus.InProgress); const previewApiKey = await loadPreviewApikey(); if (previewApiKey) { @@ -38,7 +38,7 @@ export const createLoadApplicationData = (deps: ILoadApplicationDataDeps) => asy const requiredDataLoaded = [ appContext.previewApiKeyLoadingStatus, - appContext.projectIdLoadingStatus, + appContext.environmentIdLoadingStatus, ].every(status => status === LoadingStatus.Finished); if (requiredDataLoaded) { diff --git a/src/factories/createLoadPreviewApiKey.ts b/src/factories/createLoadPreviewApiKey.ts index cfa3f85..a0e55ad 100644 --- a/src/factories/createLoadPreviewApiKey.ts +++ b/src/factories/createLoadPreviewApiKey.ts @@ -10,10 +10,10 @@ interface ILoadPreviewApiKeyDeps { export const createLoadPreviewApiKey = (props: ILoadPreviewApiKeyDeps): () => Promise => { const { accessToken } = props.authContext; - const { projectId } = props.appContext; + const { environmentId } = props.appContext; return async () => { - const projectContainerId = await getProjectContainerForEnvironment(accessToken, projectId).then(res => res.projectContainerId); - const tokenSeed = await getPreviewApiTokenSeed(accessToken, projectContainerId, projectId).then(res => res[0]?.token_seed_id); + const projectContainerId = await getProjectContainerForEnvironment(accessToken, environmentId).then(res => res.projectContainerId); + const tokenSeed = await getPreviewApiTokenSeed(accessToken, projectContainerId, environmentId).then(res => res[0]?.token_seed_id); if (!tokenSeed) { return null; diff --git a/src/repositories/contentItemRepository.ts b/src/repositories/contentItemRepository.ts index f01a3c5..0a1b3d6 100644 --- a/src/repositories/contentItemRepository.ts +++ b/src/repositories/contentItemRepository.ts @@ -8,14 +8,14 @@ let deliveryClient: IDeliveryClient | null = null; const sourceTrackingHeaderName = "X-KC-SOURCE"; -const ensureDeliveryClient = (projectId: string, previewApiKey: string): void => { +const ensureDeliveryClient = (environmentId: string, previewApiKey: string): void => { if (deliveryClient) { return; } deliveryClient = createDeliveryClient({ previewApiKey, - projectId: projectId, + projectId: environmentId, proxy: { basePreviewUrl: process.env.REACT_APP_DELIVER_URL, }, @@ -33,8 +33,8 @@ const ensureDeliveryClient = (projectId: string, previewApiKey: string): void => }; -export const getAllArticles = (projectId: string, previewApiKey: string): Promise> => { - ensureDeliveryClient(projectId, previewApiKey); +export const getAllArticles = (environmentId: string, previewApiKey: string): Promise> => { + ensureDeliveryClient(environmentId, previewApiKey); if (!deliveryClient) { throw new Error('Delivery client is not initialized yet'); } @@ -51,8 +51,8 @@ export const getAllArticles = (projectId: string, previewApiKey: string): Promis }); }; -export const getProductsPage = (projectId: string, previewApiKey: string): Promise> => { - ensureDeliveryClient(projectId, previewApiKey); +export const getProductsPage = (environmentId: string, previewApiKey: string): Promise> => { + ensureDeliveryClient(environmentId, previewApiKey); if (!deliveryClient) { throw new Error('Delivery client is not initialized yet'); } @@ -69,8 +69,8 @@ export const getProductsPage = (projectId: string, previewApiKey: string): Promi }); }; -export const getProductDetailsByUrlSlug = (projectId: string, previewApiKey: string, urlPattern: string): Promise => { - ensureDeliveryClient(projectId, previewApiKey); +export const getProductDetailsByUrlSlug = (environmentId: string, previewApiKey: string, urlPattern: string): Promise => { + ensureDeliveryClient(environmentId, previewApiKey); if (!deliveryClient) { throw new Error('Delivery client is not initialized yet'); } diff --git a/src/utils/environmentIdUtil.ts b/src/utils/environmentIdUtil.ts new file mode 100644 index 0000000..81d9ad5 --- /dev/null +++ b/src/utils/environmentIdUtil.ts @@ -0,0 +1,15 @@ +import { matchPath } from "react-router"; +import { DeployedProjectRootRoute, EnvironmentRoute, ProjectRouteParams } from "../constants/routePaths"; + +export const getEnvironmentIdFromUrl = (): string | null => { + if (window.location) { + const routeToMatch = DeployedProjectRootRoute + EnvironmentRoute + "*"; + const match = matchPath(window.location.pathname, routeToMatch); + if (match) { + return match.params.environmentId; + } + } + + console.warn('no environmentId in url'); + return null; +}; diff --git a/src/utils/projectIdUtil.ts b/src/utils/projectIdUtil.ts deleted file mode 100644 index a531d85..0000000 --- a/src/utils/projectIdUtil.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { matchPath } from "react-router"; -import { DeployedProjectRootRoute, ProjectRoute, ProjectRouteParams } from "../constants/routePaths"; - -export const getProjectIdFromUrl = (): string | null => { - if (window.location) { - const routeToMatch = DeployedProjectRootRoute + ProjectRoute + "*"; - const match = matchPath(window.location.pathname, routeToMatch); - if (match) { - return match.params.projectId; - } - } - - console.warn('no projectId in url'); - return null; -}; From 7b1adedcc85b3664a86844eb72d55dd20bc6d100 Mon Sep 17 00:00:00 2001 From: Ivan Kiral Date: Tue, 4 Jun 2024 13:17:22 +0200 Subject: [PATCH 3/8] update from ajax to fetch --- src/factories/createLoadPreviewApiKey.ts | 10 +- src/repositories/previewApiKeyRepository.ts | 26 ++-- .../projectContainerRepository.ts | 26 ++-- src/utils/ajax.ts | 123 ------------------ src/utils/fetch.ts | 36 +++++ src/utils/restProvider.ts | 81 ------------ 6 files changed, 74 insertions(+), 228 deletions(-) delete mode 100644 src/utils/ajax.ts create mode 100644 src/utils/fetch.ts delete mode 100644 src/utils/restProvider.ts diff --git a/src/factories/createLoadPreviewApiKey.ts b/src/factories/createLoadPreviewApiKey.ts index a0e55ad..dd4d4c2 100644 --- a/src/factories/createLoadPreviewApiKey.ts +++ b/src/factories/createLoadPreviewApiKey.ts @@ -12,8 +12,14 @@ export const createLoadPreviewApiKey = (props: ILoadPreviewApiKeyDeps): () => Pr const { accessToken } = props.authContext; const { environmentId } = props.appContext; return async () => { - const projectContainerId = await getProjectContainerForEnvironment(accessToken, environmentId).then(res => res.projectContainerId); - const tokenSeed = await getPreviewApiTokenSeed(accessToken, projectContainerId, environmentId).then(res => res[0]?.token_seed_id); + const projectContainerId = await getProjectContainerForEnvironment(accessToken, environmentId) + .then(res => res?.projectContainerId); + + if(!projectContainerId){ + return null; + } + + const tokenSeed = await getPreviewApiTokenSeed(accessToken, projectContainerId, environmentId).then(res => res?.[0]?.token_seed_id); if (!tokenSeed) { return null; diff --git a/src/repositories/previewApiKeyRepository.ts b/src/repositories/previewApiKeyRepository.ts index df9c92e..58ce6a5 100644 --- a/src/repositories/previewApiKeyRepository.ts +++ b/src/repositories/previewApiKeyRepository.ts @@ -1,17 +1,11 @@ -import { createAjaxWithCredentials } from '../utils/ajax'; -import { - createRestProvider, - IRequestContext, -} from '../utils/restProvider'; - -const restProvider = createRestProvider(createAjaxWithCredentials()); +import { RequestContext, get, post } from '../utils/fetch'; export interface TokenSeedResponse { token_seed_id: string; } -export const getPreviewApiTokenSeed = (authToken: string, projectContainerId: string, environmentId: string): Promise> => { - const requestContext: IRequestContext = { +export const getPreviewApiTokenSeed = (authToken: string, projectContainerId: string, environmentId: string): Promise | null> => { + const requestContext: RequestContext = { authToken: authToken, }; const url = `${process.env.REACT_APP_KONTENT_URL}/api/project-container/${projectContainerId}/keys/listing`; @@ -21,7 +15,15 @@ export const getPreviewApiTokenSeed = (authToken: string, projectContainerId: st environments: [environmentId], }; - return restProvider.post(url, data, requestContext); + return post(url, data, requestContext) + .then(async res => { + if(res.ok) { + return await res.json() as TokenSeedResponse[] + } + + console.error((await res.json()).description); + return null +}); }; export interface KeyFromSeedResponse { @@ -29,10 +31,10 @@ export interface KeyFromSeedResponse { } export const getKeyForTokenSeed = (authToken: string, projectContainerId: string, tokenSeed: string): Promise => { - const requestContext: IRequestContext = { + const requestContext: RequestContext = { authToken: authToken, }; const url = `${process.env.REACT_APP_KONTENT_URL}/api/project-container/${projectContainerId}/keys/${tokenSeed}`; - return restProvider.get(url, requestContext); + return get(url, requestContext).then(res => res.json()); }; diff --git a/src/repositories/projectContainerRepository.ts b/src/repositories/projectContainerRepository.ts index ee981c1..1b13ba9 100644 --- a/src/repositories/projectContainerRepository.ts +++ b/src/repositories/projectContainerRepository.ts @@ -1,19 +1,25 @@ -import { createAjaxWithCredentials } from '../utils/ajax'; -import { - createRestProvider, - IRequestContext, -} from '../utils/restProvider'; - -const restProvider = createRestProvider(createAjaxWithCredentials()); +import { RequestContext, get } from '../utils/fetch'; export interface ProjectContainer { projectContainerId: string; } -export const getProjectContainerForEnvironment = (authToken: string, environmentId: string): Promise => { - const requestContext: IRequestContext = { +export const getProjectContainerForEnvironment = ( + authToken: string, + environmentId: string, +): Promise => { + const requestContext: RequestContext = { authToken: authToken, }; const url = `${process.env.REACT_APP_KONTENT_URL}/api/project-management/${environmentId}`; - return restProvider.get(url, requestContext); + + return get(url, requestContext) + .then(async (res) => { + if(res.ok) { + return await res.json() as ProjectContainer + } + + console.error((await res.json()).description); + return null; + }); }; diff --git a/src/utils/ajax.ts b/src/utils/ajax.ts deleted file mode 100644 index 02b67d2..0000000 --- a/src/utils/ajax.ts +++ /dev/null @@ -1,123 +0,0 @@ -export type CustomHeaders = { - [key: string]: string, -}; - -export type RequestType = - 'GET' - | 'POST' - | 'PUT' - | 'DELETE' - | 'PATCH'; - -export type ProgressCallback = (event: { - loaded: number; - total: number; -}) => void; - -export interface ICreateAjax { - request: (type: RequestType, url: string, data: any, customHeaders?: CustomHeaders) => Promise; - requestFile: (type: RequestType, url: string, data: any, customHeaders?: CustomHeaders) => Promise; - upload: (url: string, formData: FormData, uploadProgressCallback: ProgressCallback, customHeaders?: CustomHeaders) => Promise; -} - -function createAjax(withCredentials: any): ICreateAjax { - return { - /** - * Attempts to parse the response as JSON otherwise returns it untouched. - * - * @param {string} type The HTTP verb to be used. - * @param {string} url The url for the XHR request. - * @param {object} data Optional. The data to be passed with a POST or PUT request. - * @param {object} customHeaders Optional. Custom headers to be included in a request. - * - * @memberof ajax - */ - request(type: RequestType, url: string, data: any, customHeaders?: CustomHeaders): Promise { - return new Promise(resolve => { - const request = getNewEmptyRequest(); - - request.open(type, url, true); - request.withCredentials = withCredentials; - - addCustomHeaders(request, customHeaders); - - request.onreadystatechange = () => { - if (request.readyState === 4) { - resolve(request); - } - }; - - request.send(data); - }); - }, - - requestFile(type: RequestType, url: string, data: any, customHeaders?: CustomHeaders): Promise { - return new Promise(resolve => { - const request = getNewEmptyRequest(); - - request.open(type, url, true); - request.responseType = 'blob'; - request.withCredentials = withCredentials; - - addCustomHeaders(request, customHeaders); - - request.onreadystatechange = () => { - if (request.readyState === 4) { - resolve(request); - } - }; - - request.send(data); - }); - }, - - upload(url: string, formData: FormData, uploadProgressCallback: ProgressCallback, customHeaders?: CustomHeaders): Promise { - return new Promise(resolve => { - const request = getNewEmptyRequest(); - - request.open('POST', url, true); - - addCustomHeaders(request, customHeaders); - - request.onreadystatechange = () => { - if (request.readyState === 4) { - resolve(request); - } - }; - - request.upload.addEventListener('progress', uploadProgressCallback); - request.send(formData); - }); - }, - }; -} - -function addCustomHeaders(request: XMLHttpRequest, customHeaders?: CustomHeaders) { - if (customHeaders) { - Object.keys(customHeaders).forEach((header) => { - const value = customHeaders[header]; - if (header && value) { - request.setRequestHeader(header, value); - } - }); - } -} - -function getNewEmptyRequest(): XMLHttpRequest { - // if (XMLHttpRequest) { - return new XMLHttpRequest(); - // } - // else { - // // Set ajax to correct XHR type. Source: https://gist.github.com/jed/993585 - // return new XMLHttpRequest(); - // //return new ActiveXObject('MSXML2.XMLHTTP.3.0'); - // } -} - -export function createAjaxWithCredentials(): ICreateAjax { - return createAjax(true); -} - -// export function createAjaxWithoutCredentials(): ICreateAjax { -// return createAjax(false); -// } diff --git a/src/utils/fetch.ts b/src/utils/fetch.ts new file mode 100644 index 0000000..623778d --- /dev/null +++ b/src/utils/fetch.ts @@ -0,0 +1,36 @@ + + +export type RequestContext = Readonly<{ + readonly appInstanceId?: string; + readonly authToken?: string; +}> + +export type CustomHeaders = Record; + +const makeHeaders = (requestContext?: RequestContext): CustomHeaders => requestContext ? { + ...requestContext.authToken ? { Authorization: `Bearer ${requestContext.authToken}` } : {}, + ...requestContext.appInstanceId ? {'X-AppInstanceId': requestContext.appInstanceId} : {} +} : {} + +export const get = (url: string, requestContext: RequestContext) => { + return fetch(url, { + method: "get", + headers: { + "Content-Type": "application/json", + ...makeHeaders(requestContext) + }, + credentials: "same-origin" + }) +} + +export const post = (url: string, data: Object, requestContext: RequestContext) => { + return fetch(url, { + method: "post", + headers: { + "Content-Type": "application/json", + ...makeHeaders(requestContext), + }, + body: JSON.stringify(data), + credentials: "same-origin" + }) +} \ No newline at end of file diff --git a/src/utils/restProvider.ts b/src/utils/restProvider.ts deleted file mode 100644 index 70f1774..0000000 --- a/src/utils/restProvider.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { RequestType } from './ajax'; - -export interface IRequestContext { - readonly appInstanceId?: string; - readonly authToken?: string; -} - -export type CustomHeaders = { - [key: string]: string, -}; - - -function getAuthHeader(accessToken: string): CustomHeaders { - return { Authorization: `Bearer ${accessToken}` }; -} - -function getHeaders(defaultHeaders: CustomHeaders, requestContext?: IRequestContext): CustomHeaders { - if (!requestContext) { - return defaultHeaders; - } - - const newHeaders = requestContext.authToken ? getAuthHeader(requestContext.authToken) : {}; - - if (requestContext.appInstanceId) { - newHeaders['X-AppInstanceId'] = requestContext.appInstanceId; - } - - return { ...defaultHeaders, ...newHeaders }; -} - -export function createRestProvider(ajax: any) { - function makeRequest(httpVerb: RequestType, url: string, data: any, requestContext?: IRequestContext): Promise { - const headers = getHeaders( - { 'Content-type': 'application/json' }, - requestContext, - ); - - const requestBody = data ? prepareDataForSend(data) : null; - return ajax.request(httpVerb, url, requestBody, headers); - } - - return { - get(url: string, requestContext?: IRequestContext): Promise { - return makeRequest('GET', url, undefined, requestContext) - .then(verifyStatusCode([200])) - .then(parseResponse); - }, - post(url: string, data: any, requestContext?: IRequestContext): Promise { - return makeRequest('POST', url, data, requestContext) - .then(verifyStatusCode([200, 201])) - .then(parseResponse); - }, - }; -} - -function prepareDataForSend(data: any): any { - if ((data && typeof data === 'object') || typeof data === "string") { - return JSON.stringify(data); - } - - return data; -} - -function verifyStatusCode(validStatusCodes: number[]) { - return (response: XMLHttpRequest) => { - if (validStatusCodes.indexOf(response.status) >= 0) { - return response; - } - else { - throw response; - } - }; -} - -function parseResponse(response: XMLHttpRequest) { - // it might be empty string which can't be parsed by JSON.parse - if (!response.responseText) { - return null; - } - return JSON.parse(response.responseText); -} From ee6fb4fb442a398d1c6c7c30c9cb222068a6e0d2 Mon Sep 17 00:00:00 2001 From: Ivan Kiral Date: Tue, 4 Jun 2024 13:38:43 +0200 Subject: [PATCH 4/8] add message to console when no api key exists --- src/repositories/previewApiKeyRepository.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/repositories/previewApiKeyRepository.ts b/src/repositories/previewApiKeyRepository.ts index 58ce6a5..17065cf 100644 --- a/src/repositories/previewApiKeyRepository.ts +++ b/src/repositories/previewApiKeyRepository.ts @@ -17,12 +17,19 @@ export const getPreviewApiTokenSeed = (authToken: string, projectContainerId: st return post(url, data, requestContext) .then(async res => { - if(res.ok) { - return await res.json() as TokenSeedResponse[] + if(!res.ok) { + console.error((await res.json()).description); + return null; + } + + const tokens = await res.json() as TokenSeedResponse[] + + if (!tokens.length){ + console.error(`There is no Delivery API key for environment ${environmentId}`); + return null; } - console.error((await res.json()).description); - return null + return tokens; }); }; From bb790861ed386e1e36c1f11aafb061138f48bea8 Mon Sep 17 00:00:00 2001 From: Ivan Kiral Date: Tue, 4 Jun 2024 13:44:07 +0200 Subject: [PATCH 5/8] add formatting --- dprint.json | 6 + package-lock.json | 175 ++++++++++++++++++ package.json | 7 +- src/App.tsx | 24 ++- src/authentication/WebAuth.ts | 22 ++- src/authentication/authOptions.ts | 11 +- src/components/ErrorPage.tsx | 25 ++- src/components/Loading.tsx | 12 +- src/components/NavigationBar.tsx | 15 +- src/components/PageContent.tsx | 4 +- src/components/Product/ProductCard.tsx | 37 ++-- src/components/Product/ProductDetailsPage.tsx | 19 +- src/components/Product/ProductsPage.tsx | 22 ++- src/components/ProgressBar.tsx | 11 +- src/components/WelcomePage.tsx | 11 +- src/constants/localStorageKeys.ts | 2 +- src/constants/resources.ts | 3 +- src/constants/routePaths.ts | 6 +- src/context/AppContext.tsx | 42 +++-- src/context/AppContextInitialization.tsx | 12 +- src/context/AuthContext.tsx | 54 +++--- src/enums/LoadingStatus.ts | 8 +- src/enums/PollingStatus.ts | 6 +- src/factories/createLoadApplicationData.ts | 8 +- src/factories/createLoadPreviewApiKey.ts | 10 +- src/index.tsx | 25 +-- src/models/_project.ts | 76 ++++---- src/models/article_example_content_type.ts | 2 +- .../landing_page_example_content_type.ts | 2 +- src/models/product_example_content_type.ts | 2 +- src/repositories/contentItemRepository.ts | 39 ++-- src/repositories/previewApiKeyRepository.ts | 46 +++-- .../projectContainerRepository.ts | 8 +- src/utils/environmentIdUtil.ts | 2 +- src/utils/fetch.ts | 29 +-- 35 files changed, 499 insertions(+), 284 deletions(-) create mode 100644 dprint.json diff --git a/dprint.json b/dprint.json new file mode 100644 index 0000000..7551368 --- /dev/null +++ b/dprint.json @@ -0,0 +1,6 @@ +{ + "extends": "https://raw.githubusercontent.com/kontent-ai/dprint-config/main/dprint.json", + "includes": [ + "src/**/*.{ts,tsx,js,jsx,json}" + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 95dc723..828f8e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "typescript": "^3.4.5" }, "devDependencies": { + "dprint": "^0.46.2", "gh-pages": "^2.0.1" } }, @@ -1938,6 +1939,97 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@dprint/darwin-arm64": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.2.tgz", + "integrity": "sha512-IA/VIWwmIJ4a9rLB0paU0ryXFHRV+NHyWykDa4F+3WgbyXVlv1PVncW5wgfZJ38wQM8FDfPUO2Ar8+Nkx8Fkfg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@dprint/darwin-x64": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.2.tgz", + "integrity": "sha512-YMY40MsN1CL/8fGPcZaA/3KeE09GHt7y4ZRJGCw8Cx7AjZ3P+SlNxL6X9v72eXUfotzudcZc5yC72tdUFaN7oA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@dprint/linux-arm64-glibc": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.2.tgz", + "integrity": "sha512-brllu3G7nPV5GQTHnDF54ihGwgWHxRr03EQI0Mbbif94P/jl+Dqf9I6qWBSDVt/zQTThY1aYIZt+mpblD4oXZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-arm64-musl": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.2.tgz", + "integrity": "sha512-+9pF6qmSMobvtlTk/PnyqYE66nlwyrg7TeJb+RhqAT3y40v8TT4XafdK5p5GOrC1qf1QV4PCLAuOrHAKaYLNqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-x64-glibc": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.2.tgz", + "integrity": "sha512-iq0WfIyLrxaE0PVXw89FKwC2VIbo3Hb6PscEVtzWDOpm/bmURXs5JIjRFpAaGfwCZcwzds70bb7utT5ItgZtlA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-x64-musl": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.2.tgz", + "integrity": "sha512-Ins2SD0v5Q61b6WIcxnsoHT84E+kyiUjjespxcWzqLrXdPgy8ATLMfcx1vHS4ALD687+PkwCgPF8N2jK66Md6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/win32-x64": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.2.tgz", + "integrity": "sha512-4msLVoyMppU5yPlxnCU0ibk6ahSQs1vcc7ToJkOi3LiCqu/KU+hYk2+bwqiZaQ1usi24iA9AIB+aBVA6X3VDXg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@eslint/eslintrc": { "version": "1.3.3", "license": "MIT", @@ -6200,6 +6292,25 @@ "version": "5.1.0", "license": "BSD-2-Clause" }, + "node_modules/dprint": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.2.tgz", + "integrity": "sha512-wjbOghUDqy4gNgW2TNkGOBCAfxwkWBUAyCEkqFZbrBKTGZ1DVbHB1YZOTwVlQNIcDcLWTZQz2AnIK1HjQC/rIQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "dprint": "bin.js" + }, + "optionalDependencies": { + "@dprint/darwin-arm64": "0.46.2", + "@dprint/darwin-x64": "0.46.2", + "@dprint/linux-arm64-glibc": "0.46.2", + "@dprint/linux-arm64-musl": "0.46.2", + "@dprint/linux-x64-glibc": "0.46.2", + "@dprint/linux-x64-musl": "0.46.2", + "@dprint/win32-x64": "0.46.2" + } + }, "node_modules/duplexer": { "version": "0.1.2", "license": "MIT" @@ -18225,6 +18336,55 @@ "version": "2.0.2", "requires": {} }, + "@dprint/darwin-arm64": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.2.tgz", + "integrity": "sha512-IA/VIWwmIJ4a9rLB0paU0ryXFHRV+NHyWykDa4F+3WgbyXVlv1PVncW5wgfZJ38wQM8FDfPUO2Ar8+Nkx8Fkfg==", + "dev": true, + "optional": true + }, + "@dprint/darwin-x64": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.2.tgz", + "integrity": "sha512-YMY40MsN1CL/8fGPcZaA/3KeE09GHt7y4ZRJGCw8Cx7AjZ3P+SlNxL6X9v72eXUfotzudcZc5yC72tdUFaN7oA==", + "dev": true, + "optional": true + }, + "@dprint/linux-arm64-glibc": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.2.tgz", + "integrity": "sha512-brllu3G7nPV5GQTHnDF54ihGwgWHxRr03EQI0Mbbif94P/jl+Dqf9I6qWBSDVt/zQTThY1aYIZt+mpblD4oXZQ==", + "dev": true, + "optional": true + }, + "@dprint/linux-arm64-musl": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.2.tgz", + "integrity": "sha512-+9pF6qmSMobvtlTk/PnyqYE66nlwyrg7TeJb+RhqAT3y40v8TT4XafdK5p5GOrC1qf1QV4PCLAuOrHAKaYLNqg==", + "dev": true, + "optional": true + }, + "@dprint/linux-x64-glibc": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.2.tgz", + "integrity": "sha512-iq0WfIyLrxaE0PVXw89FKwC2VIbo3Hb6PscEVtzWDOpm/bmURXs5JIjRFpAaGfwCZcwzds70bb7utT5ItgZtlA==", + "dev": true, + "optional": true + }, + "@dprint/linux-x64-musl": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.2.tgz", + "integrity": "sha512-Ins2SD0v5Q61b6WIcxnsoHT84E+kyiUjjespxcWzqLrXdPgy8ATLMfcx1vHS4ALD687+PkwCgPF8N2jK66Md6A==", + "dev": true, + "optional": true + }, + "@dprint/win32-x64": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.2.tgz", + "integrity": "sha512-4msLVoyMppU5yPlxnCU0ibk6ahSQs1vcc7ToJkOi3LiCqu/KU+hYk2+bwqiZaQ1usi24iA9AIB+aBVA6X3VDXg==", + "dev": true, + "optional": true + }, "@eslint/eslintrc": { "version": "1.3.3", "requires": { @@ -20861,6 +21021,21 @@ "dotenv-expand": { "version": "5.1.0" }, + "dprint": { + "version": "0.46.2", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.2.tgz", + "integrity": "sha512-wjbOghUDqy4gNgW2TNkGOBCAfxwkWBUAyCEkqFZbrBKTGZ1DVbHB1YZOTwVlQNIcDcLWTZQz2AnIK1HjQC/rIQ==", + "dev": true, + "requires": { + "@dprint/darwin-arm64": "0.46.2", + "@dprint/darwin-x64": "0.46.2", + "@dprint/linux-arm64-glibc": "0.46.2", + "@dprint/linux-arm64-musl": "0.46.2", + "@dprint/linux-x64-glibc": "0.46.2", + "@dprint/linux-x64-musl": "0.46.2", + "@dprint/win32-x64": "0.46.2" + } + }, "duplexer": { "version": "0.1.2" }, diff --git a/package.json b/package.json index 8198d6c..39f9847 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,9 @@ "test": "react-scripts test", "eject": "react-scripts eject", "predeploy": "npm run build", - "deploy": "gh-pages -d build" + "deploy": "gh-pages -d build", + "fmt": "dprint fmt", + "fmt:check": "dprint check" }, "eslintConfig": { "extends": "react-app" @@ -44,6 +46,7 @@ ] }, "devDependencies": { + "dprint": "^0.46.2", "gh-pages": "^2.0.1" } -} +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index ee8756a..dd0718c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,18 +1,18 @@ -import React from 'react'; -import './App.css'; -import { Route, Switch } from 'react-router-dom'; -import { NavigationBar } from './components/NavigationBar'; -import { ProductDetailsPage } from './components/Product/ProductDetailsPage'; -import { ProductsPage } from './components/Product/ProductsPage'; -import { ProductDetailsRoute, ProductsRoute, EnvironmentRoute } from './constants/routePaths'; -import { WelcomePage } from './components/WelcomePage'; -import { ProgressBar } from './components/ProgressBar'; +import React from "react"; +import "./App.css"; +import { Route, Switch } from "react-router-dom"; +import { NavigationBar } from "./components/NavigationBar"; +import { ProductDetailsPage } from "./components/Product/ProductDetailsPage"; +import { ProductsPage } from "./components/Product/ProductsPage"; +import { ProductDetailsRoute, ProductsRoute, EnvironmentRoute } from "./constants/routePaths"; +import { WelcomePage } from "./components/WelcomePage"; +import { ProgressBar } from "./components/ProgressBar"; export class App extends React.PureComponent { render() { return (
- + ( -

Ooops, missing page!

- )} + render={() =>

Ooops, missing page!

} />
diff --git a/src/authentication/WebAuth.ts b/src/authentication/WebAuth.ts index dd71ad1..ac5a180 100644 --- a/src/authentication/WebAuth.ts +++ b/src/authentication/WebAuth.ts @@ -1,8 +1,5 @@ -import auth0 from 'auth0-js'; -import { - authOptions, - logoutOptions, -} from './authOptions'; +import auth0 from "auth0-js"; +import { authOptions, logoutOptions } from "./authOptions"; import { Auth0RedirectUriStorageKey } from "../constants/localStorageKeys"; import { RootRoute, DeployedProjectRootRoute } from "../constants/routePaths"; @@ -15,7 +12,10 @@ export interface IWebAuth { readonly login: () => void; readonly logout: () => void; readonly silentLogin: () => void; - readonly handleAuthentication: (onSuccessLogin: (accessToken: IAccessToken, redirectUri: string) => void, onFailedLogin: () => void) => void; + readonly handleAuthentication: ( + onSuccessLogin: (accessToken: IAccessToken, redirectUri: string) => void, + onFailedLogin: () => void, + ) => void; readonly isAuthenticated: (expiresIn: number) => boolean; } @@ -29,7 +29,7 @@ export class WebAuth implements IWebAuth { silentLogin = (): void => { localStorage.setItem(Auth0RedirectUriStorageKey, window.location.pathname); this.webAuth.authorize({ - prompt: 'none', + prompt: "none", }); }; @@ -50,7 +50,10 @@ export class WebAuth implements IWebAuth { return redirectUri; }; - handleAuthentication = (onSuccessLogin: (accessToken: IAccessToken, redirectUri: string) => void, onFailedLogin: () => void): void => { + handleAuthentication = ( + onSuccessLogin: (accessToken: IAccessToken, redirectUri: string) => void, + onFailedLogin: () => void, + ): void => { this.webAuth.parseHash((err, authResult) => { if (authResult && authResult.accessToken && authResult.idToken) { const accessToken: IAccessToken = { @@ -59,8 +62,7 @@ export class WebAuth implements IWebAuth { }; const redirectUri = this.getRedirectUri(); onSuccessLogin(accessToken, redirectUri); - } - else if (err) { + } else if (err) { onFailedLogin(); this.login(); } diff --git a/src/authentication/authOptions.ts b/src/authentication/authOptions.ts index 7aba811..051505a 100644 --- a/src/authentication/authOptions.ts +++ b/src/authentication/authOptions.ts @@ -1,15 +1,12 @@ -import { - AuthOptions, - LogoutOptions, -} from 'auth0-js'; +import { AuthOptions, LogoutOptions } from "auth0-js"; export const authOptions: AuthOptions = { - audience: 'https://app.kenticocloud.com/', + audience: "https://app.kenticocloud.com/", clientID: process.env.REACT_APP_AUTH_CLIENT_ID!, domain: process.env.REACT_APP_AUTH_DOMAIN!, redirectUri: process.env.REACT_APP_AUTH_REDIRECT_URL, - responseType: 'token id_token', - scope: 'openid', + responseType: "token id_token", + scope: "openid", }; export const logoutOptions: LogoutOptions = { diff --git a/src/components/ErrorPage.tsx b/src/components/ErrorPage.tsx index 3069a9d..e9539a0 100644 --- a/src/components/ErrorPage.tsx +++ b/src/components/ErrorPage.tsx @@ -1,8 +1,8 @@ -import React from 'react'; +import React from "react"; export enum ErrorPageType { - MissingEnvironmentId = 'missingEnvironmentId', - UnableToGetPreviewApiKey = 'unableToGetPreviewApiKey', + MissingEnvironmentId = "missingEnvironmentId", + UnableToGetPreviewApiKey = "unableToGetPreviewApiKey", } interface IErrorPageProps { @@ -12,30 +12,29 @@ interface IErrorPageProps { const EnvironmentIdUrlTemplate = "https://getting-started.sample.kontent.ai/"; const MissingEnvironmentIdErrorPageContent: React.FunctionComponent = () => ( -

Didn't you forget to provide Environment Id in the url? E.g. {EnvironmentIdUrlTemplate}

+

+ Didn't you forget to provide Environment Id in the url? E.g. {EnvironmentIdUrlTemplate} +

); const UnableToGetPreviewApiKeyErrorPageContent: React.FunctionComponent = () => ( <>

There was problem retrieving Preview Api Key.

-

Did you provide correct Environment Id? E.g. {EnvironmentIdUrlTemplate}

+

+ Did you provide correct Environment Id? E.g. {EnvironmentIdUrlTemplate} +

); export const ErrorPage: React.FunctionComponent = ({ type }) => ( <>
-

Ooops, there was some error!

- {type === ErrorPageType.MissingEnvironmentId && ( - - )} + {type === ErrorPageType.MissingEnvironmentId && } - {type === ErrorPageType.UnableToGetPreviewApiKey && ( - - )} + {type === ErrorPageType.UnableToGetPreviewApiKey && } ); - diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx index 030fab0..c8685ba 100644 --- a/src/components/Loading.tsx +++ b/src/components/Loading.tsx @@ -1,9 +1,9 @@ -import React from 'react'; +import React from "react"; export const Loading = (): JSX.Element => { - return ( -
-

Loading...

-
- ); + return ( +
+

Loading...

+
+ ); }; diff --git a/src/components/NavigationBar.tsx b/src/components/NavigationBar.tsx index 59c754d..3d0fb18 100644 --- a/src/components/NavigationBar.tsx +++ b/src/components/NavigationBar.tsx @@ -1,11 +1,7 @@ -import React from 'react'; -import { NavLink } from 'react-router-dom'; -import './NavigationBar.css'; -import { - ProductsRoute, - EnvironmentRoute, - ProjectRouteParams, -} from '../constants/routePaths'; +import React from "react"; +import { NavLink } from "react-router-dom"; +import "./NavigationBar.css"; +import { ProductsRoute, EnvironmentRoute, ProjectRouteParams } from "../constants/routePaths"; import { buildPath } from "../utils/routeTransitionUtils"; import { AppContextConsumer } from "../context/AppContext"; @@ -36,7 +32,6 @@ export class NavigationBar extends React.PureComponent {
)} - ) + ); } } - diff --git a/src/components/PageContent.tsx b/src/components/PageContent.tsx index fa1990f..96dc2a6 100644 --- a/src/components/PageContent.tsx +++ b/src/components/PageContent.tsx @@ -1,5 +1,5 @@ -import React from 'react'; -import './PageContent.css'; +import React from "react"; +import "./PageContent.css"; export interface IPageContentProps { readonly title: string; diff --git a/src/components/Product/ProductCard.tsx b/src/components/Product/ProductCard.tsx index 73a0ce3..ba7e7f5 100644 --- a/src/components/Product/ProductCard.tsx +++ b/src/components/Product/ProductCard.tsx @@ -2,7 +2,7 @@ import { Link } from "react-router-dom"; import { buildPath } from "../../utils/routeTransitionUtils"; import { ProductDetailsRoute, ProductDetailsRouteParams } from "../../constants/routePaths"; import React from "react"; -import './ProductCard.css'; +import "./ProductCard.css"; import { productImagePlaceholderUrl } from "../../constants/resources"; interface IProductCardPlaceholderProps { @@ -19,7 +19,7 @@ const ProductCardPlaceholder: React.FunctionComponent
- {title ? title : 'Untitled content item'} + {title ? title : "Untitled content item"} ); @@ -30,18 +30,21 @@ interface IProductCardProps { readonly pictureUrl: string; } -export const ProductCard: React.FunctionComponent = - ({ environmentId, productId, pictureUrl, title }) => { - const imageSource = pictureUrl ? pictureUrl : productImagePlaceholderUrl; - return ( -
- {productId ? ( - (ProductDetailsRoute, { environmentId, productUrlSlug: productId })}> - - - ) : ( - - )} -
- ); - }; +export const ProductCard: React.FunctionComponent = ( + { environmentId, productId, pictureUrl, title }, +) => { + const imageSource = pictureUrl ? pictureUrl : productImagePlaceholderUrl; + return ( +
+ {productId + ? ( + (ProductDetailsRoute, { environmentId, productUrlSlug: productId })} + > + + + ) + : } +
+ ); +}; diff --git a/src/components/Product/ProductDetailsPage.tsx b/src/components/Product/ProductDetailsPage.tsx index 31a2601..d0e8626 100644 --- a/src/components/Product/ProductDetailsPage.tsx +++ b/src/components/Product/ProductDetailsPage.tsx @@ -1,9 +1,7 @@ -import React from 'react'; -import { - AppContextConsumer, -} from '../../context/AppContext'; -import './ProductDetailsPage.css'; -import './Testimonial.css'; +import React from "react"; +import { AppContextConsumer } from "../../context/AppContext"; +import "./ProductDetailsPage.css"; +import "./Testimonial.css"; import { ProductDetailsRouteParams } from "../../constants/routePaths"; import { ProductExampleContentType } from "../../models/product_example_content_type"; import { PageContent } from "../PageContent"; @@ -21,14 +19,14 @@ class ProductDetailsPage extends React.PureComponent { render() { const { product } = this.props; if (product) { - const pictureUrl = product.elements.image.value[0] ? product.elements.image.value[0].url : ''; + const pictureUrl = product.elements.image.value[0] ? product.elements.image.value[0].url : ""; return ( {pictureUrl && ( {product.elements.name.value} )} @@ -36,7 +34,8 @@ class ProductDetailsPage extends React.PureComponent { className="product-details__description" dangerouslySetInnerHTML={{ __html: product.elements.description.value }} /> - ); + + ); } return

There's no such product

; @@ -60,4 +59,4 @@ const ProductDetailsPageConnected: React.FunctionComponent ); -export { ProductDetailsPageConnected as ProductDetailsPage } +export { ProductDetailsPageConnected as ProductDetailsPage }; diff --git a/src/components/Product/ProductsPage.tsx b/src/components/Product/ProductsPage.tsx index 583ef09..a46cff6 100644 --- a/src/components/Product/ProductsPage.tsx +++ b/src/components/Product/ProductsPage.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { AppContextConsumer } from '../../context/AppContext'; -import { PageContent } from '../PageContent'; -import './ProductsPage.css'; +import React from "react"; +import { AppContextConsumer } from "../../context/AppContext"; +import { PageContent } from "../PageContent"; +import "./ProductsPage.css"; import { ProductExampleContentType } from "../../models/product_example_content_type"; import { ProductCard } from "./ProductCard"; import classNames from "classnames"; @@ -22,18 +22,20 @@ class ProductsPage extends React.PureComponent { const isSingleProduct = products.length === 1; return ( -
+
{products && products.map((product: ProductExampleContentType) => ( ) - )} + /> + ))}
); diff --git a/src/components/ProgressBar.tsx b/src/components/ProgressBar.tsx index 71b4154..19627d1 100644 --- a/src/components/ProgressBar.tsx +++ b/src/components/ProgressBar.tsx @@ -1,7 +1,7 @@ -import React, { useContext, useEffect, useState } from 'react'; -import { AppContext } from '../context/AppContext'; -import { PollingStatus } from '../enums/PollingStatus'; -import './ProgressBar.css'; +import React, { useContext, useEffect, useState } from "react"; +import { AppContext } from "../context/AppContext"; +import { PollingStatus } from "../enums/PollingStatus"; +import "./ProgressBar.css"; export const ProgressBar: React.FC = () => { const context = useContext(AppContext); @@ -24,8 +24,7 @@ export const ProgressBar: React.FC = () => { }; }, [context.dataPollingStatus, visible]); - return visible - ?
+ ?
: null; }; diff --git a/src/components/WelcomePage.tsx b/src/components/WelcomePage.tsx index 8c140ae..b9b6e23 100644 --- a/src/components/WelcomePage.tsx +++ b/src/components/WelcomePage.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { AppContextConsumer } from '../context/AppContext'; -import { PageContent } from './PageContent'; +import React from "react"; +import { AppContextConsumer } from "../context/AppContext"; +import { PageContent } from "./PageContent"; import { ArticleExampleContentType } from "../models/article_example_content_type"; interface IWelcomePageProps { @@ -32,9 +32,10 @@ const WelcomePageConnected = () => ( {appContext => ( + init={appContext.loadWelcomePage} + /> )} ); -export { WelcomePageConnected as WelcomePage } +export { WelcomePageConnected as WelcomePage }; diff --git a/src/constants/localStorageKeys.ts b/src/constants/localStorageKeys.ts index 70e03af..8147a88 100644 --- a/src/constants/localStorageKeys.ts +++ b/src/constants/localStorageKeys.ts @@ -1 +1 @@ -export const Auth0RedirectUriStorageKey = 'redirectUri'; +export const Auth0RedirectUriStorageKey = "redirectUri"; diff --git a/src/constants/resources.ts b/src/constants/resources.ts index 2a84cd4..a64b950 100644 --- a/src/constants/resources.ts +++ b/src/constants/resources.ts @@ -1 +1,2 @@ -export const productImagePlaceholderUrl = `${process.env.REACT_APP_PROJECT_DOMAIN}${process.env.REACT_APP_PROJECT_ROUTE}/placeholder-images.png`; +export const productImagePlaceholderUrl = + `${process.env.REACT_APP_PROJECT_DOMAIN}${process.env.REACT_APP_PROJECT_ROUTE}/placeholder-images.png`; diff --git a/src/constants/routePaths.ts b/src/constants/routePaths.ts index 273aeeb..f10ce55 100644 --- a/src/constants/routePaths.ts +++ b/src/constants/routePaths.ts @@ -1,8 +1,8 @@ -const uuidPattern = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'; +const uuidPattern = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"; export const DeployedProjectRootRoute = `${process.env.REACT_APP_PROJECT_ROUTE}`; -export const RootRoute = '/'; +export const RootRoute = "/"; export const CallbackRoute = `${RootRoute}callback`; export const EnvironmentRoute = `${RootRoute}:environmentId(${uuidPattern})`; @@ -15,4 +15,4 @@ export type ProjectRouteParams = { export type ProductDetailsRouteParams = ProjectRouteParams & { readonly productUrlSlug: string; -} +}; diff --git a/src/context/AppContext.tsx b/src/context/AppContext.tsx index e4cb2d3..3a9368a 100644 --- a/src/context/AppContext.tsx +++ b/src/context/AppContext.tsx @@ -1,9 +1,9 @@ -import React from 'react'; -import { LoadingStatus } from '../enums/LoadingStatus'; -import { PollingStatus } from '../enums/PollingStatus'; -import { ArticleExampleContentType } from '../models/article_example_content_type'; -import { ProductExampleContentType } from '../models/product_example_content_type'; -import { getAllArticles, getProductsPage, getProductDetailsByUrlSlug } from '../repositories/contentItemRepository'; +import React from "react"; +import { LoadingStatus } from "../enums/LoadingStatus"; +import { PollingStatus } from "../enums/PollingStatus"; +import { ArticleExampleContentType } from "../models/article_example_content_type"; +import { ProductExampleContentType } from "../models/product_example_content_type"; +import { getAllArticles, getProductsPage, getProductDetailsByUrlSlug } from "../repositories/contentItemRepository"; interface IAppContextState { readonly dataLoadingStatus: LoadingStatus; @@ -13,7 +13,7 @@ interface IAppContextState { readonly environmentId: string; readonly environmentIdLoadingStatus: LoadingStatus; readonly articles: Array; - readonly productsByUrlSlug: {[key: string]: ProductExampleContentType}; + readonly productsByUrlSlug: { [key: string]: ProductExampleContentType }; } interface IAppContextProps { @@ -34,9 +34,9 @@ export interface IAppContext extends IAppContextState, IAppContextProps { const defaultAppContext: IAppContext = { dataLoadingStatus: LoadingStatus.NotLoaded, dataPollingStatus: PollingStatus.Stopped, - previewApiKey: '', + previewApiKey: "", previewApiKeyLoadingStatus: LoadingStatus.NotLoaded, - environmentId: '', + environmentId: "", environmentIdLoadingStatus: LoadingStatus.NotLoaded, articles: new Array(), productsByUrlSlug: {}, @@ -56,13 +56,12 @@ const AppContextProvider = AppContext.Provider; export const AppContextConsumer = AppContext.Consumer; export class AppContextComponent extends React.PureComponent<{}, IAppContextState> { - readonly state = { dataLoadingStatus: LoadingStatus.NotLoaded, dataPollingStatus: PollingStatus.Stopped, - previewApiKey: '', + previewApiKey: "", previewApiKeyLoadingStatus: LoadingStatus.NotLoaded, - environmentId: '', + environmentId: "", environmentIdLoadingStatus: LoadingStatus.NotLoaded, articles: new Array(), productsByUrlSlug: {}, @@ -117,9 +116,12 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat const productsPage = await getProductsPage(this.state.environmentId, this.state.previewApiKey); if (productsPage && productsPage[0]) { const newProducts = productsPage[0].elements.productList.linkedItems as Array; - this.setState((state) => ({ productsByUrlSlug: newProducts - .reduce((byId, product: ProductExampleContentType) => ({...byId, [product.elements.url.value]: product}), - Object.assign({}, state.productsByUrlSlug)) + this.setState((state) => ({ + productsByUrlSlug: newProducts + .reduce( + (byId, product: ProductExampleContentType) => ({ ...byId, [product.elements.url.value]: product }), + Object.assign({}, state.productsByUrlSlug), + ), })); } }; @@ -130,9 +132,15 @@ export class AppContextComponent extends React.PureComponent<{}, IAppContextStat }; private _loadProductData = async (productUrlSlug: string) => { - const product = await getProductDetailsByUrlSlug(this.state.environmentId, this.state.previewApiKey, productUrlSlug); + const product = await getProductDetailsByUrlSlug( + this.state.environmentId, + this.state.previewApiKey, + productUrlSlug, + ); if (product) { - this.setState((state) => ({ productsByUrlSlug: ({...Object.assign({}, state.productsByUrlSlug), [product.elements.url.value]: product})})); + this.setState((state) => ({ + productsByUrlSlug: ({ ...Object.assign({}, state.productsByUrlSlug), [product.elements.url.value]: product }), + })); } }; diff --git a/src/context/AppContextInitialization.tsx b/src/context/AppContextInitialization.tsx index 9d14452..68d7a88 100644 --- a/src/context/AppContextInitialization.tsx +++ b/src/context/AppContextInitialization.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React from "react"; import { RouteComponentProps, withRouter } from "react-router"; import { AuthContextConsumer, IAuthContext } from "./AuthContext"; import { AppContextConsumer, IAppContext } from "./AppContext"; @@ -16,7 +16,6 @@ interface IAppContextInitializationProps extends RouteComponentProps { } class AppContextInitialization extends React.PureComponent { - componentDidUpdate(): void { this.props.loadApplicationData(); } @@ -24,18 +23,18 @@ class AppContextInitialization extends React.PureComponent + return ; } if (previewApiKeyLoadingStatus === LoadingStatus.Failed) { - return + return ; } if (dataLoadingStatus === LoadingStatus.Finished) { return this.props.children; } - return + return ; } } @@ -59,7 +58,8 @@ const AppContextInitializationConnected = (props: RouteComponentProps) => ( authContext={authContext} appContext={appContext} {...props} - />); + /> + ); }} )} diff --git a/src/context/AuthContext.tsx b/src/context/AuthContext.tsx index cd913e8..04b7a03 100644 --- a/src/context/AuthContext.tsx +++ b/src/context/AuthContext.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React from "react"; import { IAccessToken, WebAuth } from "../authentication/WebAuth"; import { Redirect, Route, RouteComponentProps, Switch, withRouter } from "react-router"; import { Loading } from "../components/Loading"; @@ -15,7 +15,7 @@ export interface IAuthContext extends IAuthContextState { } const defaultAuthContext: IAuthContext = { - accessToken: '', + accessToken: "", expiresAt: 0, isLoggedIn: false, logout: () => undefined, @@ -26,14 +26,13 @@ const AuthContextProvider = context.Provider; export const AuthContextConsumer = context.Consumer; class AuthContext extends React.Component { - private webAuth = new WebAuth(); constructor(props: RouteComponentProps) { super(props); this.state = { - accessToken: '', + accessToken: "", isLoggedIn: false, expiresAt: 0, }; @@ -57,11 +56,11 @@ class AuthContext extends React.Component { - console.warn('on failed login'); + console.warn("on failed login"); }; componentDidMount() { - const {silentLogin} = this.webAuth; + const { silentLogin } = this.webAuth; if (!this.isAuthUrlHash(window.location.hash)) { silentLogin(); } @@ -77,29 +76,34 @@ class AuthContext extends React.Component - {isLoggedIn ? - : - { - this.handleAuthCallback(props); - return ; - }} - /> - } + {isLoggedIn + ? ( + + ) + : ( + { + this.handleAuthCallback(props); + return ; + }} + /> + )} {isLoggedIn && ( - ( - - {this.props.children} - - )}/> + ( + + {this.props.children} + + )} + /> )} - ) + ); } } diff --git a/src/enums/LoadingStatus.ts b/src/enums/LoadingStatus.ts index fb86774..3936f84 100644 --- a/src/enums/LoadingStatus.ts +++ b/src/enums/LoadingStatus.ts @@ -1,6 +1,6 @@ export enum LoadingStatus { - NotLoaded = 'notLoaded', - InProgress = 'inProgress', - Finished = 'finished', - Failed = 'failed', + NotLoaded = "notLoaded", + InProgress = "inProgress", + Finished = "finished", + Failed = "failed", } diff --git a/src/enums/PollingStatus.ts b/src/enums/PollingStatus.ts index 038e91d..e804ebf 100644 --- a/src/enums/PollingStatus.ts +++ b/src/enums/PollingStatus.ts @@ -1,5 +1,5 @@ export enum PollingStatus { - Stopped = 'Stopped', - Fetching = 'Fetching', - Waiting = 'Waiting', + Stopped = "Stopped", + Fetching = "Fetching", + Waiting = "Waiting", } diff --git a/src/factories/createLoadApplicationData.ts b/src/factories/createLoadApplicationData.ts index 72217b5..b020df8 100644 --- a/src/factories/createLoadApplicationData.ts +++ b/src/factories/createLoadApplicationData.ts @@ -24,14 +24,16 @@ export const createLoadApplicationData = (deps: ILoadApplicationDataDeps) => asy } } - if (appContext.environmentIdLoadingStatus === LoadingStatus.Finished && appContext.previewApiKeyLoadingStatus === LoadingStatus.NotLoaded) { + if ( + appContext.environmentIdLoadingStatus === LoadingStatus.Finished + && appContext.previewApiKeyLoadingStatus === LoadingStatus.NotLoaded + ) { appContext.setPreviewApiKeyLoadingStatus(LoadingStatus.InProgress); const previewApiKey = await loadPreviewApikey(); if (previewApiKey) { appContext.setPreviewApiKey(previewApiKey); appContext.setPreviewApiKeyLoadingStatus(LoadingStatus.Finished); - } - else { + } else { appContext.setPreviewApiKeyLoadingStatus(LoadingStatus.Failed); } } diff --git a/src/factories/createLoadPreviewApiKey.ts b/src/factories/createLoadPreviewApiKey.ts index dd4d4c2..19be002 100644 --- a/src/factories/createLoadPreviewApiKey.ts +++ b/src/factories/createLoadPreviewApiKey.ts @@ -15,11 +15,13 @@ export const createLoadPreviewApiKey = (props: ILoadPreviewApiKeyDeps): () => Pr const projectContainerId = await getProjectContainerForEnvironment(accessToken, environmentId) .then(res => res?.projectContainerId); - if(!projectContainerId){ + if (!projectContainerId) { return null; } - - const tokenSeed = await getPreviewApiTokenSeed(accessToken, projectContainerId, environmentId).then(res => res?.[0]?.token_seed_id); + + const tokenSeed = await getPreviewApiTokenSeed(accessToken, projectContainerId, environmentId).then(res => + res?.[0]?.token_seed_id + ); if (!tokenSeed) { return null; @@ -28,5 +30,5 @@ export const createLoadPreviewApiKey = (props: ILoadPreviewApiKeyDeps): () => Pr return getKeyForTokenSeed(accessToken, projectContainerId, tokenSeed) .then(response => response.api_key) .catch(() => null); - } + }; }; diff --git a/src/index.tsx b/src/index.tsx index dfe1d26..b4dcd10 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,21 +1,22 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import './index.css'; -import { App } from './App'; -import { BrowserRouter as Router } from 'react-router-dom'; -import { AppContextComponent } from './context/AppContext'; -import { AuthContext } from './context/AuthContext'; -import { AppContextInitialization } from './context/AppContextInitialization'; -import { DeployedProjectRootRoute } from './constants/routePaths'; +import React from "react"; +import ReactDOM from "react-dom"; +import "./index.css"; +import { App } from "./App"; +import { BrowserRouter as Router } from "react-router-dom"; +import { AppContextComponent } from "./context/AppContext"; +import { AuthContext } from "./context/AuthContext"; +import { AppContextInitialization } from "./context/AppContextInitialization"; +import { DeployedProjectRootRoute } from "./constants/routePaths"; ReactDOM.render( - + - - , document.getElementById('root')); + , + document.getElementById("root"), +); diff --git a/src/models/_project.ts b/src/models/_project.ts index b3d3739..babeeb7 100644 --- a/src/models/_project.ts +++ b/src/models/_project.ts @@ -4,91 +4,91 @@ export const projectModel = { languages: { default: { - codename: 'default', - name: 'Default project language', + codename: "default", + name: "Default project language", }, }, contentTypes: { article_example_content_type: { - codename: 'article_example_content_type', - name: 'Article—example content type', + codename: "article_example_content_type", + name: "Article—example content type", elements: { body: { - codename: 'body', - name: 'Body', + codename: "body", + name: "Body", }, title: { - codename: 'title', - name: 'Title', + codename: "title", + name: "Title", }, url: { - codename: 'url', - name: 'URL', + codename: "url", + name: "URL", }, }, }, landing_page_example_content_type: { - codename: 'landing_page_example_content_type', - name: 'Landing page—example content type', + codename: "landing_page_example_content_type", + name: "Landing page—example content type", elements: { body: { - codename: 'body', - name: 'Body', + codename: "body", + name: "Body", }, product_list: { - codename: 'product_list', - name: 'Product list', + codename: "product_list", + name: "Product list", }, title: { - codename: 'title', - name: 'Title', + codename: "title", + name: "Title", }, url: { - codename: 'url', - name: 'URL', + codename: "url", + name: "URL", }, }, }, product_example_content_type: { - codename: 'product_example_content_type', - name: 'Product—example content type', + codename: "product_example_content_type", + name: "Product—example content type", elements: { url: { - codename: 'url', - name: 'URL', + codename: "url", + name: "URL", }, description: { - codename: 'description', - name: 'Description', + codename: "description", + name: "Description", }, name: { - codename: 'name', - name: 'Name', + codename: "name", + name: "Name", }, image: { - codename: 'image', - name: 'Image', + codename: "image", + name: "Image", }, taxonomy___categorizing_target_audience: { - codename: 'taxonomy___categorizing_target_audience', - name: 'Taxonomy - categorizing target audience', + codename: "taxonomy___categorizing_target_audience", + name: "Taxonomy - categorizing target audience", }, }, }, }, taxonomies: { taxonomy_categorizing_target_audience: { - codename: 'taxonomy_categorizing_target_audience', - name: 'Taxonomy—categorizing target audience', + codename: "taxonomy_categorizing_target_audience", + name: "Taxonomy—categorizing target audience", terms: { for_other_businesses__b2b_: { - codename: 'for_other_businesses__b2b_', - name: 'For other businesses (B2B)', + codename: "for_other_businesses__b2b_", + name: "For other businesses (B2B)", terms: {}, }, for_consumers__b2c_: { - codename: 'for_consumers__b2c_', - name: 'For consumers (B2C)', + codename: "for_consumers__b2c_", + name: "For consumers (B2C)", terms: {}, }, }, diff --git a/src/models/article_example_content_type.ts b/src/models/article_example_content_type.ts index 1b96ff4..d1baf67 100644 --- a/src/models/article_example_content_type.ts +++ b/src/models/article_example_content_type.ts @@ -1,4 +1,4 @@ -import { IContentItem, Elements } from '@kontent-ai/delivery-sdk'; +import { IContentItem, Elements } from "@kontent-ai/delivery-sdk"; /** * Generated by '@kentico/kontent-model-generator@4.1.0' diff --git a/src/models/landing_page_example_content_type.ts b/src/models/landing_page_example_content_type.ts index 11b1880..e1d2969 100644 --- a/src/models/landing_page_example_content_type.ts +++ b/src/models/landing_page_example_content_type.ts @@ -1,4 +1,4 @@ -import { IContentItem, Elements } from '@kontent-ai/delivery-sdk'; +import { IContentItem, Elements } from "@kontent-ai/delivery-sdk"; /** * Generated by '@kentico/kontent-model-generator@4.1.0' diff --git a/src/models/product_example_content_type.ts b/src/models/product_example_content_type.ts index 1af75a3..ad936d7 100644 --- a/src/models/product_example_content_type.ts +++ b/src/models/product_example_content_type.ts @@ -1,4 +1,4 @@ -import { IContentItem, Elements } from '@kontent-ai/delivery-sdk'; +import { IContentItem, Elements } from "@kontent-ai/delivery-sdk"; /** * Generated by '@kentico/kontent-model-generator@4.1.0' diff --git a/src/repositories/contentItemRepository.ts b/src/repositories/contentItemRepository.ts index 0a1b3d6..d34c707 100644 --- a/src/repositories/contentItemRepository.ts +++ b/src/repositories/contentItemRepository.ts @@ -1,5 +1,5 @@ import { ArticleExampleContentType } from "../models/article_example_content_type"; -import { camelCasePropertyNameResolver, createDeliveryClient, IDeliveryClient} from "@kontent-ai/delivery-sdk"; +import { camelCasePropertyNameResolver, createDeliveryClient, IDeliveryClient } from "@kontent-ai/delivery-sdk"; import { LandingPageExampleContentType } from "../models/landing_page_example_content_type"; import { ProductExampleContentType } from "../models/product_example_content_type"; import packageInfo from "../../package.json"; @@ -20,7 +20,7 @@ const ensureDeliveryClient = (environmentId: string, previewApiKey: string): voi basePreviewUrl: process.env.REACT_APP_DELIVER_URL, }, defaultQueryConfig: { - usePreviewMode: true + usePreviewMode: true, }, globalHeaders: (_queryConfig) => [ { @@ -28,19 +28,21 @@ const ensureDeliveryClient = (environmentId: string, previewApiKey: string): voi value: `${packageInfo.name};${packageInfo.version}`, }, ], - propertyNameResolver: camelCasePropertyNameResolver + propertyNameResolver: camelCasePropertyNameResolver, }); }; - -export const getAllArticles = (environmentId: string, previewApiKey: string): Promise> => { +export const getAllArticles = ( + environmentId: string, + previewApiKey: string, +): Promise> => { ensureDeliveryClient(environmentId, previewApiKey); if (!deliveryClient) { - throw new Error('Delivery client is not initialized yet'); + throw new Error("Delivery client is not initialized yet"); } return deliveryClient.items() - .type('article_example_content_type') + .type("article_example_content_type") .toPromise() .then(response => { return response.data.items; @@ -51,14 +53,17 @@ export const getAllArticles = (environmentId: string, previewApiKey: string): Pr }); }; -export const getProductsPage = (environmentId: string, previewApiKey: string): Promise> => { +export const getProductsPage = ( + environmentId: string, + previewApiKey: string, +): Promise> => { ensureDeliveryClient(environmentId, previewApiKey); if (!deliveryClient) { - throw new Error('Delivery client is not initialized yet'); + throw new Error("Delivery client is not initialized yet"); } return deliveryClient.items() - .type('landing_page_example_content_type') + .type("landing_page_example_content_type") .toPromise() .then(response => { return response.data.items; @@ -69,20 +74,24 @@ export const getProductsPage = (environmentId: string, previewApiKey: string): P }); }; -export const getProductDetailsByUrlSlug = (environmentId: string, previewApiKey: string, urlPattern: string): Promise => { +export const getProductDetailsByUrlSlug = ( + environmentId: string, + previewApiKey: string, + urlPattern: string, +): Promise => { ensureDeliveryClient(environmentId, previewApiKey); if (!deliveryClient) { - throw new Error('Delivery client is not initialized yet'); + throw new Error("Delivery client is not initialized yet"); } return deliveryClient.items() - .type('product_example_content_type') - .equalsFilter('elements.url', urlPattern) + .type("product_example_content_type") + .equalsFilter("elements.url", urlPattern) .toPromise() .then(response => { return response.data.items[0]; }) .catch(reason => { console.log(reason); - }) + }); }; diff --git a/src/repositories/previewApiKeyRepository.ts b/src/repositories/previewApiKeyRepository.ts index 17065cf..fcc9250 100644 --- a/src/repositories/previewApiKeyRepository.ts +++ b/src/repositories/previewApiKeyRepository.ts @@ -1,43 +1,51 @@ -import { RequestContext, get, post } from '../utils/fetch'; +import { RequestContext, get, post } from "../utils/fetch"; export interface TokenSeedResponse { token_seed_id: string; } -export const getPreviewApiTokenSeed = (authToken: string, projectContainerId: string, environmentId: string): Promise | null> => { +export const getPreviewApiTokenSeed = ( + authToken: string, + projectContainerId: string, + environmentId: string, +): Promise | null> => { const requestContext: RequestContext = { authToken: authToken, }; const url = `${process.env.REACT_APP_KONTENT_URL}/api/project-container/${projectContainerId}/keys/listing`; const data = { - query: '', - 'api_key_types': ['delivery-api'], + query: "", + api_key_types: ["delivery-api"], environments: [environmentId], }; return post(url, data, requestContext) .then(async res => { - if(!res.ok) { - console.error((await res.json()).description); - return null; - } - - const tokens = await res.json() as TokenSeedResponse[] - - if (!tokens.length){ - console.error(`There is no Delivery API key for environment ${environmentId}`); - return null; - } - - return tokens; -}); + if (!res.ok) { + console.error((await res.json()).description); + return null; + } + + const tokens = await res.json() as TokenSeedResponse[]; + + if (!tokens.length) { + console.error(`There is no Delivery API key for environment ${environmentId}`); + return null; + } + + return tokens; + }); }; export interface KeyFromSeedResponse { api_key: string; } -export const getKeyForTokenSeed = (authToken: string, projectContainerId: string, tokenSeed: string): Promise => { +export const getKeyForTokenSeed = ( + authToken: string, + projectContainerId: string, + tokenSeed: string, +): Promise => { const requestContext: RequestContext = { authToken: authToken, }; diff --git a/src/repositories/projectContainerRepository.ts b/src/repositories/projectContainerRepository.ts index 1b13ba9..c5c94c5 100644 --- a/src/repositories/projectContainerRepository.ts +++ b/src/repositories/projectContainerRepository.ts @@ -1,4 +1,4 @@ -import { RequestContext, get } from '../utils/fetch'; +import { RequestContext, get } from "../utils/fetch"; export interface ProjectContainer { projectContainerId: string; @@ -15,10 +15,10 @@ export const getProjectContainerForEnvironment = ( return get(url, requestContext) .then(async (res) => { - if(res.ok) { - return await res.json() as ProjectContainer + if (res.ok) { + return await res.json() as ProjectContainer; } - + console.error((await res.json()).description); return null; }); diff --git a/src/utils/environmentIdUtil.ts b/src/utils/environmentIdUtil.ts index 81d9ad5..43a1eba 100644 --- a/src/utils/environmentIdUtil.ts +++ b/src/utils/environmentIdUtil.ts @@ -10,6 +10,6 @@ export const getEnvironmentIdFromUrl = (): string | null => { } } - console.warn('no environmentId in url'); + console.warn("no environmentId in url"); return null; }; diff --git a/src/utils/fetch.ts b/src/utils/fetch.ts index 623778d..e6f6204 100644 --- a/src/utils/fetch.ts +++ b/src/utils/fetch.ts @@ -1,27 +1,28 @@ - - export type RequestContext = Readonly<{ readonly appInstanceId?: string; readonly authToken?: string; -}> +}>; export type CustomHeaders = Record; -const makeHeaders = (requestContext?: RequestContext): CustomHeaders => requestContext ? { - ...requestContext.authToken ? { Authorization: `Bearer ${requestContext.authToken}` } : {}, - ...requestContext.appInstanceId ? {'X-AppInstanceId': requestContext.appInstanceId} : {} -} : {} +const makeHeaders = (requestContext?: RequestContext): CustomHeaders => + requestContext + ? { + ...requestContext.authToken ? { Authorization: `Bearer ${requestContext.authToken}` } : {}, + ...requestContext.appInstanceId ? { "X-AppInstanceId": requestContext.appInstanceId } : {}, + } + : {}; export const get = (url: string, requestContext: RequestContext) => { return fetch(url, { method: "get", headers: { "Content-Type": "application/json", - ...makeHeaders(requestContext) + ...makeHeaders(requestContext), }, - credentials: "same-origin" - }) -} + credentials: "same-origin", + }); +}; export const post = (url: string, data: Object, requestContext: RequestContext) => { return fetch(url, { @@ -31,6 +32,6 @@ export const post = (url: string, data: Object, requestContext: RequestContext) ...makeHeaders(requestContext), }, body: JSON.stringify(data), - credentials: "same-origin" - }) -} \ No newline at end of file + credentials: "same-origin", + }); +}; From a5dcb764452d869e0dbeb916cd12e70214201d0f Mon Sep 17 00:00:00 2001 From: Ivan Kiral Date: Tue, 4 Jun 2024 13:45:18 +0200 Subject: [PATCH 6/8] update workflows --- .github/workflows/build.yml | 19 +++++++++++++++++ .github/workflows/integrate.yml | 38 --------------------------------- package.json | 1 - 3 files changed, 19 insertions(+), 39 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/integrate.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..29ede7f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,19 @@ +name: Lint & Build + +on: + push: + branches: [main] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js from .nvmrc file + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + - run: npm ci + - run: npm run fmt:check + - run: npm run build \ No newline at end of file diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml deleted file mode 100644 index 307f9d5..0000000 --- a/.github/workflows/integrate.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Integrate - -on: - push: - branches: [ master ] - pull_request: - -env: - NODE_ENV: "production" - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - id: nvm - - name: Use Node.js - uses: actions/setup-node@v2 - with: - node-version-file: '.nvmrc' - - run: npm ci - - run: npm run test -- --watchAll=false --passWithNoTests - - run: npm run build - - name: "Artifact : site" - uses: actions/upload-artifact@v2 - with: - name: "Site" - path: ./build - - name: Deploy 🚀 - if: github.ref == 'refs/heads/master' - uses: JamesIves/github-pages-deploy-action@3.6.2 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BRANCH: gh-pages - FOLDER: build - CLEAN: true # Automatically remove deleted files from the deploy branch diff --git a/package.json b/package.json index 39f9847..f1f2aba 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "test": "react-scripts test", "eject": "react-scripts eject", "predeploy": "npm run build", - "deploy": "gh-pages -d build", "fmt": "dprint fmt", "fmt:check": "dprint check" }, From 316f1a73856019b502f2c382e9fb611f9a95f20e Mon Sep 17 00:00:00 2001 From: Ivan Kiral Date: Tue, 18 Jun 2024 07:59:19 +0200 Subject: [PATCH 7/8] remove gh-pages --- package-lock.json | 538 ++++++---------------------------------------- package.json | 5 +- 2 files changed, 65 insertions(+), 478 deletions(-) diff --git a/package-lock.json b/package-lock.json index 828f8e9..7ec8d9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,7 @@ "typescript": "^3.4.5" }, "devDependencies": { - "dprint": "^0.46.2", - "gh-pages": "^2.0.1" + "dprint": "^0.46.3" } }, "node_modules/@ampproject/remapping": { @@ -1940,9 +1939,9 @@ } }, "node_modules/@dprint/darwin-arm64": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.2.tgz", - "integrity": "sha512-IA/VIWwmIJ4a9rLB0paU0ryXFHRV+NHyWykDa4F+3WgbyXVlv1PVncW5wgfZJ38wQM8FDfPUO2Ar8+Nkx8Fkfg==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.3.tgz", + "integrity": "sha512-1ycDpGvclGHF3UG5V6peymPDg6ouNTqM6BjhVELQ6zwr+X98AMhq/1slgO8hwHtPcaS5qhTAS+PkzOmBJRegow==", "cpu": [ "arm64" ], @@ -1953,9 +1952,9 @@ ] }, "node_modules/@dprint/darwin-x64": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.2.tgz", - "integrity": "sha512-YMY40MsN1CL/8fGPcZaA/3KeE09GHt7y4ZRJGCw8Cx7AjZ3P+SlNxL6X9v72eXUfotzudcZc5yC72tdUFaN7oA==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.3.tgz", + "integrity": "sha512-v5IpLmrY836Q5hJAxZuX097ZNQvoZgO6JKO4bK4l6XDhhHAw2XTIUr41+FM5r36ENxyASMk0NpHjhcHtih3o0g==", "cpu": [ "x64" ], @@ -1966,9 +1965,9 @@ ] }, "node_modules/@dprint/linux-arm64-glibc": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.2.tgz", - "integrity": "sha512-brllu3G7nPV5GQTHnDF54ihGwgWHxRr03EQI0Mbbif94P/jl+Dqf9I6qWBSDVt/zQTThY1aYIZt+mpblD4oXZQ==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.3.tgz", + "integrity": "sha512-9P13g1vgV8RfQH2qBGa8YAfaOeWA42RIhj7lmWRpkDFtwau96reMKwnBBn8bHUnc5e6bSsbPUOMb/X1KMUKz/g==", "cpu": [ "arm64" ], @@ -1979,9 +1978,9 @@ ] }, "node_modules/@dprint/linux-arm64-musl": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.2.tgz", - "integrity": "sha512-+9pF6qmSMobvtlTk/PnyqYE66nlwyrg7TeJb+RhqAT3y40v8TT4XafdK5p5GOrC1qf1QV4PCLAuOrHAKaYLNqg==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.3.tgz", + "integrity": "sha512-AAcdcMSZ6DEIoY9E0xQHjkZP+THP7EWsQge4TWzglSIjzn31YltglHAGYFcLB4CTJYpF0NsFDNFktzgkO+s0og==", "cpu": [ "arm64" ], @@ -1992,9 +1991,9 @@ ] }, "node_modules/@dprint/linux-x64-glibc": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.2.tgz", - "integrity": "sha512-iq0WfIyLrxaE0PVXw89FKwC2VIbo3Hb6PscEVtzWDOpm/bmURXs5JIjRFpAaGfwCZcwzds70bb7utT5ItgZtlA==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.3.tgz", + "integrity": "sha512-c5cQ3G1rC64nBZ8Pd2LGWwzkEk4D7Ax9NrBbwYmNPvs6mFbGlJPC1+RD95x2WwIrIlMIciLG+Kxmt25PzBphmg==", "cpu": [ "x64" ], @@ -2005,9 +2004,9 @@ ] }, "node_modules/@dprint/linux-x64-musl": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.2.tgz", - "integrity": "sha512-Ins2SD0v5Q61b6WIcxnsoHT84E+kyiUjjespxcWzqLrXdPgy8ATLMfcx1vHS4ALD687+PkwCgPF8N2jK66Md6A==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.3.tgz", + "integrity": "sha512-ONtk2QtLcV0TqWOCOqzUFQixgk3JC+vnJLB5L6tQwT7BX5LzeircfE/1f4dg459iqejNC9MBXZkHnXqabvWSow==", "cpu": [ "x64" ], @@ -2018,9 +2017,9 @@ ] }, "node_modules/@dprint/win32-x64": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.2.tgz", - "integrity": "sha512-4msLVoyMppU5yPlxnCU0ibk6ahSQs1vcc7ToJkOi3LiCqu/KU+hYk2+bwqiZaQ1usi24iA9AIB+aBVA6X3VDXg==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.3.tgz", + "integrity": "sha512-xvj4DSEilf0gGdT7CqnwNEgfWNuWqT6eIBxHDEUbmcn1vZ7IwirtqRq/nm3lmYtQaJ4EbtMQZvACHZwxC7G96w==", "cpu": [ "x64" ], @@ -4578,25 +4577,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-union": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.flat": { "version": "1.3.1", "license": "MIT", @@ -4665,14 +4645,6 @@ "version": "0.0.7", "license": "ISC" }, - "node_modules/async": { - "version": "2.6.4", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.14" - } - }, "node_modules/asynckit": { "version": "0.4.0", "license": "MIT" @@ -6293,22 +6265,22 @@ "license": "BSD-2-Clause" }, "node_modules/dprint": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.2.tgz", - "integrity": "sha512-wjbOghUDqy4gNgW2TNkGOBCAfxwkWBUAyCEkqFZbrBKTGZ1DVbHB1YZOTwVlQNIcDcLWTZQz2AnIK1HjQC/rIQ==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.3.tgz", + "integrity": "sha512-ACEd7B7sO/uvPvV/nsHbtkIeMqeD2a8XGO1DokROtKDUmI5WbuflGZOwyjFCYwy4rkX6FXoYBzGdEQ6um7BjCA==", "dev": true, "hasInstallScript": true, "bin": { "dprint": "bin.js" }, "optionalDependencies": { - "@dprint/darwin-arm64": "0.46.2", - "@dprint/darwin-x64": "0.46.2", - "@dprint/linux-arm64-glibc": "0.46.2", - "@dprint/linux-arm64-musl": "0.46.2", - "@dprint/linux-x64-glibc": "0.46.2", - "@dprint/linux-x64-musl": "0.46.2", - "@dprint/win32-x64": "0.46.2" + "@dprint/darwin-arm64": "0.46.3", + "@dprint/darwin-x64": "0.46.3", + "@dprint/linux-arm64-glibc": "0.46.3", + "@dprint/linux-arm64-musl": "0.46.3", + "@dprint/linux-x64-glibc": "0.46.3", + "@dprint/linux-x64-musl": "0.46.3", + "@dprint/win32-x64": "0.46.3" } }, "node_modules/duplexer": { @@ -6336,11 +6308,6 @@ "version": "1.4.284", "license": "ISC" }, - "node_modules/email-addresses": { - "version": "3.1.0", - "dev": true, - "license": "MIT" - }, "node_modules/emittery": { "version": "0.8.1", "license": "MIT", @@ -7506,39 +7473,6 @@ "node": ">=10" } }, - "node_modules/filename-reserved-regex": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/filenamify": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "filename-reserved-regex": "^1.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/filenamify-url": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "filenamify": "^1.0.0", - "humanize-url": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/filesize": { "version": "8.0.7", "license": "BSD-3-Clause", @@ -7864,19 +7798,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/fs-monkey": { "version": "1.0.3", "license": "Unlicense" @@ -7973,26 +7894,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gh-pages": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^2.6.1", - "commander": "^2.18.0", - "email-addresses": "^3.0.1", - "filenamify-url": "^1.0.0", - "fs-extra": "^8.1.0", - "globby": "^6.1.0" - }, - "bin": { - "gh-pages": "bin/gh-pages.js", - "gh-pages-clean": "bin/gh-pages-clean.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/glob": { "version": "7.2.0", "license": "ISC", @@ -8064,21 +7965,6 @@ "node": ">=4" } }, - "node_modules/globby": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/graceful-fs": { "version": "4.2.9", "license": "ISC" @@ -8401,18 +8287,6 @@ "node": ">=10.17.0" } }, - "node_modules/humanize-url": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "normalize-url": "^1.0.0", - "strip-url-auth": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/iconv-lite": { "version": "0.6.3", "license": "MIT", @@ -8717,14 +8591,6 @@ "node": ">=8" } }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "license": "MIT" @@ -12053,14 +11919,6 @@ "node": ">=6" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jsonpointer": { "version": "5.0.1", "license": "MIT", @@ -12524,20 +12382,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "license": "MIT", @@ -12904,25 +12748,6 @@ "node": ">=0.10.0" } }, - "node_modules/pinkie": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pirates": { "version": "4.0.5", "license": "MIT", @@ -14156,14 +13981,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prepend-http": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pretty-bytes": { "version": "5.6.0", "license": "MIT", @@ -14276,18 +14093,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/query-string": { - "version": "4.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/querystringify": { "version": "2.2.0", "license": "MIT" @@ -15417,17 +15222,6 @@ "websocket-driver": "^0.7.4" } }, - "node_modules/sort-keys": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-list-map": { "version": "2.0.1", "license": "MIT" @@ -15539,14 +15333,6 @@ "node": ">= 0.8" } }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "license": "MIT", @@ -15704,25 +15490,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-outer": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-url-auth": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/style-loader": { "version": "3.3.1", "license": "MIT", @@ -16147,17 +15914,6 @@ "node": ">=8" } }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/tryer": { "version": "1.0.1", "license": "MIT" @@ -16325,14 +16081,6 @@ "node": ">=8" } }, - "node_modules/universalify": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "license": "MIT", @@ -18337,51 +18085,51 @@ "requires": {} }, "@dprint/darwin-arm64": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.2.tgz", - "integrity": "sha512-IA/VIWwmIJ4a9rLB0paU0ryXFHRV+NHyWykDa4F+3WgbyXVlv1PVncW5wgfZJ38wQM8FDfPUO2Ar8+Nkx8Fkfg==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.3.tgz", + "integrity": "sha512-1ycDpGvclGHF3UG5V6peymPDg6ouNTqM6BjhVELQ6zwr+X98AMhq/1slgO8hwHtPcaS5qhTAS+PkzOmBJRegow==", "dev": true, "optional": true }, "@dprint/darwin-x64": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.2.tgz", - "integrity": "sha512-YMY40MsN1CL/8fGPcZaA/3KeE09GHt7y4ZRJGCw8Cx7AjZ3P+SlNxL6X9v72eXUfotzudcZc5yC72tdUFaN7oA==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.3.tgz", + "integrity": "sha512-v5IpLmrY836Q5hJAxZuX097ZNQvoZgO6JKO4bK4l6XDhhHAw2XTIUr41+FM5r36ENxyASMk0NpHjhcHtih3o0g==", "dev": true, "optional": true }, "@dprint/linux-arm64-glibc": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.2.tgz", - "integrity": "sha512-brllu3G7nPV5GQTHnDF54ihGwgWHxRr03EQI0Mbbif94P/jl+Dqf9I6qWBSDVt/zQTThY1aYIZt+mpblD4oXZQ==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.3.tgz", + "integrity": "sha512-9P13g1vgV8RfQH2qBGa8YAfaOeWA42RIhj7lmWRpkDFtwau96reMKwnBBn8bHUnc5e6bSsbPUOMb/X1KMUKz/g==", "dev": true, "optional": true }, "@dprint/linux-arm64-musl": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.2.tgz", - "integrity": "sha512-+9pF6qmSMobvtlTk/PnyqYE66nlwyrg7TeJb+RhqAT3y40v8TT4XafdK5p5GOrC1qf1QV4PCLAuOrHAKaYLNqg==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.3.tgz", + "integrity": "sha512-AAcdcMSZ6DEIoY9E0xQHjkZP+THP7EWsQge4TWzglSIjzn31YltglHAGYFcLB4CTJYpF0NsFDNFktzgkO+s0og==", "dev": true, "optional": true }, "@dprint/linux-x64-glibc": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.2.tgz", - "integrity": "sha512-iq0WfIyLrxaE0PVXw89FKwC2VIbo3Hb6PscEVtzWDOpm/bmURXs5JIjRFpAaGfwCZcwzds70bb7utT5ItgZtlA==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.3.tgz", + "integrity": "sha512-c5cQ3G1rC64nBZ8Pd2LGWwzkEk4D7Ax9NrBbwYmNPvs6mFbGlJPC1+RD95x2WwIrIlMIciLG+Kxmt25PzBphmg==", "dev": true, "optional": true }, "@dprint/linux-x64-musl": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.2.tgz", - "integrity": "sha512-Ins2SD0v5Q61b6WIcxnsoHT84E+kyiUjjespxcWzqLrXdPgy8ATLMfcx1vHS4ALD687+PkwCgPF8N2jK66Md6A==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.3.tgz", + "integrity": "sha512-ONtk2QtLcV0TqWOCOqzUFQixgk3JC+vnJLB5L6tQwT7BX5LzeircfE/1f4dg459iqejNC9MBXZkHnXqabvWSow==", "dev": true, "optional": true }, "@dprint/win32-x64": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.2.tgz", - "integrity": "sha512-4msLVoyMppU5yPlxnCU0ibk6ahSQs1vcc7ToJkOi3LiCqu/KU+hYk2+bwqiZaQ1usi24iA9AIB+aBVA6X3VDXg==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.3.tgz", + "integrity": "sha512-xvj4DSEilf0gGdT7CqnwNEgfWNuWqT6eIBxHDEUbmcn1vZ7IwirtqRq/nm3lmYtQaJ4EbtMQZvACHZwxC7G96w==", "dev": true, "optional": true }, @@ -20001,17 +19749,6 @@ "is-string": "^1.0.7" } }, - "array-union": { - "version": "1.0.2", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "dev": true - }, "array.prototype.flat": { "version": "1.3.1", "requires": { @@ -20056,13 +19793,6 @@ "ast-types-flow": { "version": "0.0.7" }, - "async": { - "version": "2.6.4", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, "asynckit": { "version": "0.4.0" }, @@ -21022,18 +20752,18 @@ "version": "5.1.0" }, "dprint": { - "version": "0.46.2", - "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.2.tgz", - "integrity": "sha512-wjbOghUDqy4gNgW2TNkGOBCAfxwkWBUAyCEkqFZbrBKTGZ1DVbHB1YZOTwVlQNIcDcLWTZQz2AnIK1HjQC/rIQ==", + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.3.tgz", + "integrity": "sha512-ACEd7B7sO/uvPvV/nsHbtkIeMqeD2a8XGO1DokROtKDUmI5WbuflGZOwyjFCYwy4rkX6FXoYBzGdEQ6um7BjCA==", "dev": true, "requires": { - "@dprint/darwin-arm64": "0.46.2", - "@dprint/darwin-x64": "0.46.2", - "@dprint/linux-arm64-glibc": "0.46.2", - "@dprint/linux-arm64-musl": "0.46.2", - "@dprint/linux-x64-glibc": "0.46.2", - "@dprint/linux-x64-musl": "0.46.2", - "@dprint/win32-x64": "0.46.2" + "@dprint/darwin-arm64": "0.46.3", + "@dprint/darwin-x64": "0.46.3", + "@dprint/linux-arm64-glibc": "0.46.3", + "@dprint/linux-arm64-musl": "0.46.3", + "@dprint/linux-x64-glibc": "0.46.3", + "@dprint/linux-x64-musl": "0.46.3", + "@dprint/win32-x64": "0.46.3" } }, "duplexer": { @@ -21051,10 +20781,6 @@ "electron-to-chromium": { "version": "1.4.284" }, - "email-addresses": { - "version": "3.1.0", - "dev": true - }, "emittery": { "version": "0.8.1" }, @@ -21786,27 +21512,6 @@ } } }, - "filename-reserved-regex": { - "version": "1.0.0", - "dev": true - }, - "filenamify": { - "version": "1.2.1", - "dev": true, - "requires": { - "filename-reserved-regex": "^1.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, - "filenamify-url": { - "version": "1.0.0", - "dev": true, - "requires": { - "filenamify": "^1.0.0", - "humanize-url": "^1.0.0" - } - }, "filesize": { "version": "8.0.7" }, @@ -21984,15 +21689,6 @@ "fresh": { "version": "0.5.2" }, - "fs-extra": { - "version": "8.1.0", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, "fs-monkey": { "version": "1.0.3" }, @@ -22044,18 +21740,6 @@ "get-intrinsic": "^1.1.1" } }, - "gh-pages": { - "version": "2.2.0", - "dev": true, - "requires": { - "async": "^2.6.1", - "commander": "^2.18.0", - "email-addresses": "^3.0.1", - "filenamify-url": "^1.0.0", - "fs-extra": "^8.1.0", - "globby": "^6.1.0" - } - }, "glob": { "version": "7.2.0", "requires": { @@ -22101,17 +21785,6 @@ "globals": { "version": "11.12.0" }, - "globby": { - "version": "6.1.0", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, "graceful-fs": { "version": "4.2.9" }, @@ -22309,14 +21982,6 @@ "human-signals": { "version": "2.1.0" }, - "humanize-url": { - "version": "1.0.1", - "dev": true, - "requires": { - "normalize-url": "^1.0.0", - "strip-url-auth": "^1.0.0" - } - }, "iconv-lite": { "version": "0.6.3", "requires": { @@ -22475,10 +22140,6 @@ "is-path-inside": { "version": "3.0.3" }, - "is-plain-obj": { - "version": "1.1.0", - "dev": true - }, "is-potential-custom-element-name": { "version": "1.0.1" }, @@ -24582,13 +24243,6 @@ "json5": { "version": "2.2.1" }, - "jsonfile": { - "version": "4.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, "jsonpointer": { "version": "5.0.1" }, @@ -24857,16 +24511,6 @@ "normalize-range": { "version": "0.1.2" }, - "normalize-url": { - "version": "1.9.1", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, "npm-run-path": { "version": "4.0.1", "requires": { @@ -25073,17 +24717,6 @@ "pify": { "version": "2.3.0" }, - "pinkie": { - "version": "2.0.4", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, "pirates": { "version": "4.0.5" }, @@ -25670,10 +25303,6 @@ "prelude-ls": { "version": "1.2.1" }, - "prepend-http": { - "version": "1.0.4", - "dev": true - }, "pretty-bytes": { "version": "5.6.0" }, @@ -25744,14 +25373,6 @@ "side-channel": "^1.0.4" } }, - "query-string": { - "version": "4.3.4", - "dev": true, - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, "querystringify": { "version": "2.2.0" }, @@ -26460,13 +26081,6 @@ "websocket-driver": "^0.7.4" } }, - "sort-keys": { - "version": "1.1.2", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, "source-list-map": { "version": "2.0.1" }, @@ -26538,10 +26152,6 @@ "statuses": { "version": "2.0.1" }, - "strict-uri-encode": { - "version": "1.1.0", - "dev": true - }, "string_decoder": { "version": "1.3.0", "requires": { @@ -26636,17 +26246,6 @@ "strip-json-comments": { "version": "3.1.1" }, - "strip-outer": { - "version": "1.0.1", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "strip-url-auth": { - "version": "1.0.1", - "dev": true - }, "style-loader": { "version": "3.3.1", "requires": {} @@ -26909,13 +26508,6 @@ "punycode": "^2.1.1" } }, - "trim-repeated": { - "version": "1.0.0", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, "tryer": { "version": "1.0.1" }, @@ -27015,10 +26607,6 @@ "crypto-random-string": "^2.0.0" } }, - "universalify": { - "version": "0.1.2", - "dev": true - }, "unpipe": { "version": "1.0.0" }, diff --git a/package.json b/package.json index f1f2aba..622914c 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ ] }, "devDependencies": { - "dprint": "^0.46.2", - "gh-pages": "^2.0.1" + "dprint": "^0.46.3" } -} \ No newline at end of file +} From e6917f35fbf587aae9b01ce0783a15dfcec33246 Mon Sep 17 00:00:00 2001 From: Ivan Kiral Date: Tue, 18 Jun 2024 07:59:39 +0200 Subject: [PATCH 8/8] add devrel team into codeowners --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c193788..4b8a2e7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,4 +2,4 @@ # See https://help.github.com/articles/about-code-owners/ # Example: * @kontent-ai/developer-relations -* @IvanKiral @kontent-ai/experiment-team +* @IvanKiral @kontent-ai/experiment-team @kontent-ai/developer-relations