Skip to content

Commit

Permalink
feat: table for mapping routes between ICM and PWA
Browse files Browse the repository at this point in the history
  • Loading branch information
dhhyi committed Jan 30, 2020
1 parent 1cdfb3d commit efb095e
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 2 deletions.
60 changes: 60 additions & 0 deletions server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModul
import { Environment } from 'src/environments/environment.model';
const environment: Environment = require('./dist/server/main').environment;

// tslint:disable-next-line: ban-specific-imports
import { HybridMappingEntry } from 'src/hybrid/default-url-mapping-table';
const HYBRID_MAPPING_TABLE: HybridMappingEntry[] = require('./dist/server/main').HYBRID_MAPPING_TABLE;

const logging = !!process.env.LOGGING;

// Express server
Expand Down Expand Up @@ -64,6 +68,62 @@ app.engine(
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));

app.use('*', (req, res, next) => {
const url = req.originalUrl;
let newUrl: string;

if (logging && !/.*\.([a-z]{2,3}|woff2?|json)(\?.*|)$/.test(url)) {
console.log('URL', url);
}

for (const entry of HYBRID_MAPPING_TABLE) {
const icmUrlRegex = new RegExp(entry.icm);
const pwaUrlRegex = new RegExp(entry.pwa);
if (icmUrlRegex.exec(url) && entry.handledBy === 'pwa') {
newUrl = url.replace(icmUrlRegex, '/' + entry.pwaBuild);
break;
} else if (pwaUrlRegex.exec(url) && entry.handledBy === 'icm') {
let locale;
if (/;lang=[\w_]+/.test(url)) {
const [, lang] = /;lang=([\w_]+)/.exec(url);
if (lang !== 'default') {
locale = environment.locales.find(loc => loc.lang === lang);
}
}
if (!locale) {
locale = environment.locales[0];
}

let channel;
if (/;channel=[^;]*/.test(url)) {
channel = /;channel=([^;]*)/.exec(url)[1];
} else {
channel = environment.icmChannel;
}

let application;
if (/;application=[^;]*/.test(url)) {
application = /;application=([^;]*)/.exec(url)[1];
} else {
application = environment.icmApplication || '-';
}

const parts = ['', environment.icmServerWeb, channel, locale.lang, application, locale.currency, entry.icmBuild];
newUrl = url.replace(pwaUrlRegex, parts.join('/')).replace(/;.*/g, '');
break;
}
}

if (newUrl) {
if (logging) {
console.log('RED', newUrl);
}
res.redirect(newUrl);
} else {
next();
}
});

// seo robots.txt
const pathToRobotsTxt = join(DIST_FOLDER, 'robots.txt');
if (fs.existsSync(pathToRobotsTxt)) {
Expand Down
5 changes: 3 additions & 2 deletions src/app/core/store/configuration/configuration.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export class ConfigurationEffects {
this.stateProperties.getStateOrEnvOrDefault<string>('ICM_BASE_URL', 'icmBaseURL'),
this.stateProperties.getStateOrEnvOrDefault<string>('ICM_SERVER', 'icmServer'),
this.stateProperties.getStateOrEnvOrDefault<string>('ICM_SERVER_STATIC', 'icmServerStatic'),
this.stateProperties.getStateOrEnvOrDefault<string>('ICM_SERVER_WEB', 'icmServerWeb'),
this.stateProperties.getStateOrEnvOrDefault<string>('ICM_CHANNEL', 'icmChannel'),
this.stateProperties.getStateOrEnvOrDefault<string>('ICM_APPLICATION', 'icmApplication'),
this.stateProperties
Expand All @@ -53,8 +54,8 @@ export class ConfigurationEffects {
this.stateProperties.getStateOrEnvOrDefault<string>('THEME', 'theme').pipe(map(x => x || 'default'))
),
map(
([, baseURL, server, serverStatic, channel, application, features, theme]) =>
new ApplyConfiguration({ baseURL, server, serverStatic, channel, application, features, theme })
([, baseURL, server, serverStatic, serverWeb, channel, application, features, theme]) =>
new ApplyConfiguration({ baseURL, server, serverStatic, serverWeb, channel, application, features, theme })
)
);

Expand Down
2 changes: 2 additions & 0 deletions src/app/core/store/configuration/configuration.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface ConfigurationState {
baseURL?: string;
server?: string;
serverStatic?: string;
serverWeb?: string;
channel?: string;
application?: string;
features?: string[];
Expand All @@ -15,6 +16,7 @@ const initialState: ConfigurationState = {
baseURL: undefined,
server: undefined,
serverStatic: undefined,
serverWeb: undefined,
channel: undefined,
application: undefined,
features: [],
Expand Down
10 changes: 10 additions & 0 deletions src/app/core/store/configuration/configuration.selectors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createSelector } from '@ngrx/store';

import { getCoreState } from 'ish-core/store/core-store';
import { getCurrentLocale } from 'ish-core/store/locale';

export const getConfigurationState = createSelector(
getCoreState,
Expand All @@ -27,6 +28,15 @@ export const getICMStaticURL = createSelector(
: undefined
);

export const getICMWebURL = createSelector(
getConfigurationState,
getCurrentLocale,
(state, locale) => {
const parts = [state.serverWeb, state.channel, locale.lang, state.application || '-', locale.currency];
return parts.every(x => !!x) ? `/${parts.join('/')}` : undefined;
}
);

export const getICMBaseURL = createSelector(
getConfigurationState,
state => state.baseURL
Expand Down
25 changes: 25 additions & 0 deletions src/app/core/store/restore/restore.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ import {

import { CookiesService } from 'ish-core/services/cookies/cookies.service';
import { LoadBasket, LoadBasketByAPIToken, ResetBasket, getCurrentBasket } from 'ish-core/store/checkout/basket';
import { getICMWebURL } from 'ish-core/store/configuration';
import { LoadOrderByAPIToken, getSelectedOrderId } from 'ish-core/store/orders';
import { LoadUserByAPIToken, LogoutUser, UserActionTypes, getAPIToken, getLoggedInUser } from 'ish-core/store/user';
import { whenTruthy } from 'ish-core/utils/operators';
import { SfeAdapterService } from 'ish-shared/cms/sfe-adapter/sfe-adapter.service';

import { HYBRID_MAPPING_TABLE } from '../../../../hybrid/default-url-mapping-table';

interface CookieType {
apiToken: string;
type: 'user' | 'basket' | 'order';
Expand Down Expand Up @@ -150,6 +153,28 @@ export class RestoreEffects {
)
);

@Effect({ dispatch: false })
hybridApproachRedirectToICM$ = this.router.events.pipe(
filter(() => isPlatformBrowser(this.platformId)),
filter(event => event instanceof NavigationStart),
map((event: NavigationStart) => event.url),
withLatestFrom(this.store$.pipe(select(getICMWebURL))),
tap(([url, icmWebUrl]) => {
for (const entry of HYBRID_MAPPING_TABLE) {
if (entry.handledBy === 'pwa') {
continue;
}
const regex = new RegExp(entry.pwa);
if (regex.exec(url)) {
this.router.dispose();
const newUrl = url.replace(regex, `${icmWebUrl}/${entry.icmBuild}`);
location.assign(newUrl);
break;
}
}
})
);

private makeCookie(cookie: CookieType): string {
return cookie && cookie.apiToken
? JSON.stringify({ apiToken: cookie.apiToken, type: cookie.type, orderId: cookie.orderId })
Expand Down
3 changes: 3 additions & 0 deletions src/environments/environment.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export interface Environment {
icmBaseURL: string;
icmServer: string;
icmServerStatic: string;
icmServerWeb: string;

// application specific
icmChannel: string;
icmApplication?: string;

Expand Down
1 change: 1 addition & 0 deletions src/environments/environment.prod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const environment: Environment = {
icmBaseURL: 'https://intershoppwa.azurewebsites.net',
icmServer: 'INTERSHOP/rest/WFS',
icmServerStatic: 'INTERSHOP/static/WFS',
icmServerWeb: 'INTERSHOP/web/WFS',
icmChannel: 'inSPIRED-inTRONICS-Site',

/* FEATURE TOOGLES */
Expand Down
1 change: 1 addition & 0 deletions src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const environment: Environment = {
icmBaseURL: 'http://localhost:4200',
icmServer: 'INTERSHOP/rest/WFS',
icmServerStatic: 'INTERSHOP/static/WFS',
icmServerWeb: 'INTERSHOP/web/WFS',
icmChannel: 'inSPIRED-inTRONICS-Site',

mockServerAPI: true,
Expand Down
41 changes: 41 additions & 0 deletions src/hybrid/default-url-mapping-table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { environment } from '../environments/environment';

const ICM_CONFIG_MATCH = `^/${environment.icmServerWeb}/(?<channel>[\\w-]+)/(?<lang>\\w+)/(?<application>[\\w-]+)/\\w+`;
const PWA_CONFIG_BUILD = ';channel=$<channel>;lang=$<lang>;application=$<application>;redirect=1';

export interface HybridMappingEntry {
/** ID for grouping */
id: string;
/** regex for detecting ICM URL */
icm: string;
/** regex for building ICM URL (w/o web url) */
icmBuild: string;
/** regex for detecting PWA URL */
pwa: string;
/** regex for building PWA URL */
pwaBuild: string;
/** handler */
handledBy: 'icm' | 'pwa';
}

/**
* Mapping table for running PWA and ICM in parallel
*/
export const HYBRID_MAPPING_TABLE: HybridMappingEntry[] = [
{
id: 'Home',
icm: `${ICM_CONFIG_MATCH}/(Default|ViewHomepage)-Start.*$`,
icmBuild: `ViewHomepage-Start`,
pwa: `^/home.*$`,
pwaBuild: `home${PWA_CONFIG_BUILD}`,
handledBy: 'pwa',
},
{
id: 'PDP',
icm: `${ICM_CONFIG_MATCH}/ViewProduct-Start.*(\\?|&)SKU=(?<sku>[\\w-]+).*$`,
icmBuild: `ViewProduct-Start?SKU=$<sku>`,
pwa: `^.*/product/(?<sku>[\\w-]+).*$`,
pwaBuild: `product/$<sku>${PWA_CONFIG_BUILD}`,
handledBy: 'pwa',
},
];
1 change: 1 addition & 0 deletions src/main.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export { AppServerModule } from './app/app.server.module';
export { ngExpressEngine } from '@nguniversal/express-engine';
export { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
export { environment } from './environments/environment';
export { HYBRID_MAPPING_TABLE } from './hybrid/default-url-mapping-table';
1 change: 1 addition & 0 deletions tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@
"^.*/cypress/.*$",
"^.*/src/environments/environment(\\.\\w+|)\\.ts$",
"^.*/src/ngrx-router/.*$",
"^.*/src/hybrid/default-url-mapping-table.ts$",
// core
"^.*/src/app/core/[a-z][a-z0-9-]+\\.module\\.ts",
"^.*/src/app/core/configurations/.*",
Expand Down

0 comments on commit efb095e

Please sign in to comment.