Skip to content

Commit

Permalink
[XM Cloud Proxy] API /api/editing/render endpoint (#1908)
Browse files Browse the repository at this point in the history
  • Loading branch information
illiakovalenko authored Aug 28, 2024
1 parent b4f4b36 commit 60f3ec1
Show file tree
Hide file tree
Showing 16 changed files with 793 additions and 230 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ Our versioning strategy is as follows:
* `[create-sitecore-jss]` Rework Angular initializer to support XMCloud and SXP journeys ([#1845](https://github.com/Sitecore/jss/pull/1845))([#1858](https://github.com/Sitecore/jss/pull/1858))([#1868](https://github.com/Sitecore/jss/pull/1868))([#1881](https://github.com/Sitecore/jss/pull/1881))([#1882](https://github.com/Sitecore/jss/pull/1882))
* `[create-sitecore-jss]` Allow node-xmcloud-proxy app to be installed alongside Angular SPA application
* `proxyAppDestination` arg can be passed into `create-sitecore-jss` command to define path for proxy to be installed in
* `[create-sitecore-jss]` `[template/angular]` `[template/angular-xmcloud]` `[template/node-xmcloud-proxy]` Introduced /api/editing/config endpoint ([#1903](https://github.com/Sitecore/jss/pull/1903))
* `[templates/angular]` `[templates/angular-xmcloud]` `[template/node-xmcloud-proxy]` `[sitecore-jss-proxy]` Introduced /api/editing/config endpoint ([#1903](https://github.com/Sitecore/jss/pull/1903))
* `[templates/angular]` `[templates/angular-xmcloud]` `[template/node-xmcloud-proxy]` `[sitecore-jss-proxy]` Introduced /api/editing/render endpoint ([#1908](https://github.com/Sitecore/jss/pull/1908))
* `[create-sitecore-jss]``[sitecore-jss-angular]``[template/angular-xmcloud]` Angular SXA components
* Angular placeholder now supports SXA components ([#1870](https://github.com/Sitecore/jss/pull/1870))
* Title component ([#1904](https://github.com/Sitecore/jss/pull/1904))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@ import metadata from './src/environments/metadata.json';
* Define the required configuration values to be exported from the server.bundle.ts.
*/

const apiKey = environment.sitecoreApiKey;
const siteName = environment.sitecoreSiteName;
const defaultLanguage = environment.defaultLanguage;
const getClientFactoryConfig = getGraphQLClientFactoryConfig;

export {
apiKey,
siteName,
clientFactory,
getClientFactoryConfig,
dictionaryServiceFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const requiredProperties = [
'parseRouteUrl',
'clientFactory',
'getClientFactoryConfig',
'siteName',
'defaultLanguage',
'layoutServiceFactory',
'dictionaryServiceFactory',
Expand All @@ -41,12 +40,16 @@ if (missingProperties.length > 0) {
);
}

const layoutService = layoutServiceFactory.create();

const dictionaryService = dictionaryServiceFactory.create();

const clientFactoryConfig = config.serverBundle.getClientFactoryConfig();

/**
* GraphQL endpoint resolution to meet the requirements of the http-proxy-middleware
*/
const graphQLEndpoint = (() => {
const clientFactoryConfig = config.serverBundle.getClientFactoryConfig();

try {
const graphQLEndpoint = new URL(clientFactoryConfig.endpoint);
// Browser request path to the proxy. Includes only the pathname.
Expand All @@ -66,10 +69,6 @@ const graphQLEndpoint = (() => {
}
})();

const layoutService = layoutServiceFactory.create();

const dictionaryService = dictionaryServiceFactory.create();

/**
* Parse requested url in order to detect current route and language
* @param {string} reqRoute requested route
Expand Down Expand Up @@ -138,6 +137,10 @@ server.use(
components: config.serverBundle.components,
metadata: config.serverBundle.metadata,
},
render: {
clientFactory: config.serverBundle.clientFactory,
renderView,
},
})
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export interface ServerBundle {
parseRouteUrl: RouteUrlParser;
clientFactory: GraphQLRequestClientFactory;
getClientFactoryConfig: () => GraphQLRequestClientFactoryConfig;
siteName: string;
defaultLanguage: string;
layoutServiceFactory: { create: () => LayoutService };
dictionaryServiceFactory: { create: () => DictionaryService };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { EditingDataService, EditingPreviewData } from './editing-data-service';
import {
EDITING_ALLOWED_ORIGINS,
QUERY_PARAM_EDITING_SECRET,
RenderMetadataQueryParams,
} from '@sitecore-jss/sitecore-jss/editing';
import {
QUERY_PARAM_VERCEL_PROTECTION_BYPASS,
Expand All @@ -17,7 +18,6 @@ import { EE_PATH, EE_LANGUAGE, EE_LAYOUT, EE_DICTIONARY, EE_BODY } from '../test
import {
ChromesHandler,
EditingRenderMiddleware,
MetadataQueryParams,
isEditingMetadataPreviewData,
} from './editing-render-middleware';
import { spy, match } from 'sinon';
Expand All @@ -38,7 +38,7 @@ const allowedOrigin = 'https://allowed.com';

const mockRequest = (
body?: any,
query?: Query | MetadataQueryParams,
query?: Query | RenderMetadataQueryParams,
method?: string,
headers?: { [key: string]: string }
) => {
Expand Down Expand Up @@ -182,7 +182,7 @@ describe('EditingRenderMiddleware', () => {
sc_version: 'latest',
secret: secret,
sc_layoutKind: 'shared',
} as MetadataQueryParams;
} as RenderMetadataQueryParams;

it('should handle request', async () => {
const req = mockRequest(EE_BODY, query, 'GET');
Expand Down Expand Up @@ -221,7 +221,7 @@ describe('EditingRenderMiddleware', () => {
sc_site: 'website',
secret: secret,
sc_variant: 'id-1,id-2,id-3',
} as MetadataQueryParams;
} as RenderMetadataQueryParams;

const req = mockRequest(EE_BODY, query, 'GET');
const res = mockResponse();
Expand Down Expand Up @@ -251,7 +251,7 @@ describe('EditingRenderMiddleware', () => {
sc_lang: 'en',
sc_site: 'website',
secret: secret,
} as MetadataQueryParams;
} as RenderMetadataQueryParams;
const req = mockRequest(EE_BODY, queryWithoutOptionalParams, 'GET');
const res = mockResponse();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { NextApiRequest, NextApiResponse } from 'next';
import { STATIC_PROPS_ID, SERVER_PROPS_ID } from 'next/constants';
import { AxiosDataFetcher, debug } from '@sitecore-jss/sitecore-jss';
import { EditMode, LayoutServicePageState } from '@sitecore-jss/sitecore-jss/layout';
import { LayoutKind } from '@sitecore-jss/sitecore-jss/editing';
import {
QUERY_PARAM_EDITING_SECRET,
EDITING_ALLOWED_ORIGINS,
RenderMetadataQueryParams,
LayoutKind,
} from '@sitecore-jss/sitecore-jss/editing';
import { EditingData } from './editing-data';
import { EditingDataService, editingDataService } from './editing-data-service';
Expand Down Expand Up @@ -265,27 +266,11 @@ export type EditingRenderMiddlewareMetadataConfig = Pick<
'resolvePageUrl'
>;

/**
* Query parameters appended to the page route URL
* Appended when XMCloud Pages preview (editing) Metadata Edit Mode is used
*/
export type MetadataQueryParams = {
secret: string;
sc_lang: string;
sc_itemid: string;
sc_site: string;
route: string;
mode: Exclude<LayoutServicePageState, 'normal'>;
sc_variant?: string;
sc_version?: string;
sc_layoutKind?: LayoutKind;
};

/**
* Next.js API request with Metadata query parameters.
*/
type MetadataNextApiRequest = NextApiRequest & {
query: MetadataQueryParams;
query: RenderMetadataQueryParams;
};

/**
Expand Down Expand Up @@ -330,7 +315,7 @@ export class MetadataHandler {

const startTimestamp = Date.now();

const requiredQueryParams: (keyof MetadataQueryParams)[] = [
const requiredQueryParams: (keyof RenderMetadataQueryParams)[] = [
'sc_site',
'sc_itemid',
'sc_lang',
Expand Down
4 changes: 3 additions & 1 deletion packages/sitecore-jss-proxy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"build": "npm run clean && tsc -p tsconfig.json && tsc -p tsconfig-esm.json",
"clean": "del-cli dist types",
"lint": "eslint \"./src/**/*.ts\"",
"test": "mocha --require ts-node/register \"./src/**/*.test.ts\"",
"test": "mocha --require ts-node/register \"./src/**/*.test.ts\" --exit",
"prepublishOnly": "npm run build",
"coverage": "nyc npm test",
"generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --readme none --out ../../ref-docs/sitecore-jss-proxy src/index.ts --githubPages false"
Expand Down Expand Up @@ -38,13 +38,15 @@
"@types/mocha": "^10.0.1",
"@types/node": "^20.14.2",
"@types/set-cookie-parser": "^2.4.2",
"@types/sinon": "^17.0.3",
"@types/supertest": "^6.0.2",
"chai": "^4.3.7",
"del-cli": "^5.0.0",
"eslint": "^8.33.0",
"express": "^4.19.2",
"mocha": "^10.2.0",
"nyc": "^15.1.0",
"sinon": "^17.0.1",
"supertest": "^7.0.0",
"ts-node": "^10.9.1",
"typescript": "~4.9.5"
Expand Down
135 changes: 135 additions & 0 deletions packages/sitecore-jss-proxy/src/middleware/editing/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/* eslint-disable no-unused-expressions */
import sinon from 'sinon';
import express from 'express';
import request from 'supertest';
import { editingRouter, EditingRouterConfig } from './index';
import { GraphQLRequestClient } from '@sitecore-jss/sitecore-jss';
import { EditingRenderEndpointOptions } from './render';

describe('editingRouter - /editing/config', () => {
const clientFactory = GraphQLRequestClient.createClientFactory({
endpoint: 'http://site/?sitecoreContextId=context-id',
});

const renderView: sinon.SinonStub = sinon.stub();

const renderConfig: EditingRenderEndpointOptions = {
clientFactory,
renderView,
};

const defaultOptions: EditingRouterConfig = {
config: {
components: ['component1', 'component2'],
metadata: {
packages: {
foo: '1.0.0',
bar: '2.0.0',
},
},
},
render: renderConfig,
};

let app: express.Express;

beforeEach(() => {
app = express();

process.env.JSS_EDITING_SECRET = 'correct';
});

afterEach(() => {
delete process.env.JSS_EDITING_SECRET;
});

it('should response 200 status code and return editing config', (done) => {
app.use('/api/editing', editingRouter(defaultOptions));

request(app)
.get('/api/editing/config')
.query({ secret: 'correct' })
.expect(
200,
{
components: ['component1', 'component2'],
packages: {
foo: '1.0.0',
bar: '2.0.0',
},
editMode: 'metadata',
},
done
);
});

it('should response 200 status code and return editing config when components are a map', (done) => {
app.use(
'/api/editing',
editingRouter({
config: {
components: new Map([
['component1', true],
['component2', true],
]),
metadata: {
packages: {
foo: '1.0.0',
bar: '2.0.0',
},
},
},
render: renderConfig,
})
);

request(app)
.get('/api/editing/config')
.query({ secret: 'correct' })
.expect(
200,
{
components: ['component1', 'component2'],
packages: {
foo: '1.0.0',
bar: '2.0.0',
},
editMode: 'metadata',
},
done
);
});

it('should response 200 status code and return editing config when custom request path is set', (done) => {
app.use(
'/api/editing',
editingRouter({
config: {
components: ['component1'],
metadata: {
packages: {
foo: '1.0.0',
},
},
path: '/foo/config',
},
render: renderConfig,
})
);

request(app)
.get('/api/editing/foo/config')
.query({ secret: 'correct' })
.expect(
200,
{
components: ['component1'],
packages: {
foo: '1.0.0',
},
editMode: 'metadata',
},
done
);
});
});
4 changes: 2 additions & 2 deletions packages/sitecore-jss-proxy/src/middleware/editing/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Request, RequestHandler, Response } from 'express';
import { Request, Response } from 'express';
import { debug } from '@sitecore-jss/sitecore-jss';
import { EditMode } from '@sitecore-jss/sitecore-jss/layout';
import { Metadata } from '@sitecore-jss/sitecore-jss/utils';
Expand Down Expand Up @@ -28,7 +28,7 @@ export type EditingConfigEndpointOptions = {
* @param {EditingConfigEndpointOptions} config Configuration for the endpoint
* @returns {RequestHandler} Middleware function
*/
export const editingConfigMiddleware = (config: EditingConfigEndpointOptions): RequestHandler => (
export const editingConfigMiddleware = (config: EditingConfigEndpointOptions) => (
_req: Request,
res: Response
): void => {
Expand Down
Loading

0 comments on commit 60f3ec1

Please sign in to comment.