File

libs/sdk/src/cli/split-journey/split-journey.ts

Extends

Omit<PagesJsonSchema, 'pages'>

Index

Properties

Properties

pages (Optional)
Type PageConfiguration[]
$schema (Optional)
Type string
Description

The JSON Schema for this file

description (Optional)
Type string
Description

Application Description. Will be used for the meta description tag.

frame (Optional)
Type Frame
Description

Configuration for Frame Parts (Navigation, Footer etc)

libraries
Type LibraryConfiguration[]
Default value []
Description

Provide a list of all used Building Block Libraries with the package name & version. Unused packages (i.e. not referred to in any 'Building Block Configuration') will be ignored. []

plugins (Optional)
Type PluginConfiguration[]
Default value []
Description

Configuration for plugins []

title (Optional)
Type string
Description

Application Title. Will be used as the website title. If omitted the app name is used.

webcomponent (Optional)
Type WebcomponentConfiguration
Description

Configuration for generating a webcomponent out of this application

workInProgressIndicator (Optional)
Type boolean
Default value false
Description

set to true to show WORK IN PROGRESS text on top of the application. false

import { dirname, join, relative } from 'path';
import { mkdirSync, rmSync, writeFileSync } from 'fs';
import { assign, stringify } from 'comment-json';
import chalk from 'chalk';
import { loadJourneyFromFolder } from '../../node/journey/load/load';
import { PfeJsonSchema } from '../../lib/model/pfe-json.schema';
import { SPLIT_JOURNEY_PATHS } from '../../node/journey/load/split-journey/split-journey';
import { PagesJsonSchema } from '../../lib/model/pages-json.schema';
import { PageConfiguration } from '@allianz/taly-core/schemas';
import { ensurePosixPathSeparators } from '../../utils/windows-combat';
import { WithSchema } from '../../lib/model/split-journey-configuration.schema';

const SCHEMA_PATHS = {
  GLOBAL_ACTION: 'schemas/global-actions-json.schema.json',
  GLOBAL_SERVICE_ACTIVATOR: 'schemas/global-service-activators-json.schema.json',
  PAGE: 'schemas/page-json.schema.json',
  NAVIGATION: 'schemas/navigation-json.schema.json',
  APPLICATION: 'schemas/application-json.schema.json'
};

export async function splitJourney(configDirectory: string, hideLogs = false) {
  const { pagesConfiguration, pfeConfiguration } = await loadJourneyFromFolder(configDirectory);

  createGlobalActions(pfeConfiguration, configDirectory);
  createGlobalServiceActivators(pfeConfiguration, configDirectory);
  createPages(pagesConfiguration, configDirectory);
  createNavigation(pfeConfiguration, configDirectory);
  createApplicationJson(pagesConfiguration, pfeConfiguration, configDirectory);
  deleteClassicJourneyFiles(configDirectory);

  if (hideLogs) return;

  console.log();
  console.log(
    chalk.green(
      ` > ${chalk.inverse.bold(' TALY ')} The journey configuration in ${chalk.white(
        configDirectory
      )} is now a split journey ✂️`
    )
  );
  console.log();
}

function createGlobalActions(pfeConfiguration: PfeJsonSchema, configDirectory: string) {
  const globalActions = pfeConfiguration?.globalConfiguration?.actions;

  if (!globalActions) return;

  const actionsDir = join(configDirectory, SPLIT_JOURNEY_PATHS.FOLDERS.ACTIONS);
  const schemaPath = getSchemaPath(
    SCHEMA_PATHS.GLOBAL_ACTION,
    join(configDirectory, SPLIT_JOURNEY_PATHS.FOLDERS.ACTIONS)
  );
  mkdirSync(actionsDir, { recursive: true });

  for (const actionId in globalActions) {
    const actionPath = join(actionsDir, `${sanitizeFilename(actionId)}.jsonc`);
    const actionWithSchema = addSchemaToObject(globalActions, schemaPath, actionId);

    writeFileSync(actionPath, stringify(actionWithSchema, null, 2));
  }
}

function createGlobalServiceActivators(pfeConfiguration: PfeJsonSchema, configDirectory: string) {
  const globalServiceActivators = pfeConfiguration.navConfiguration.serviceActivators;

  if (!globalServiceActivators) return;

  const globalServiceActivatorDir = join(
    configDirectory,
    SPLIT_JOURNEY_PATHS.FOLDERS.SERVICE_ACTIVATORS
  );
  const schemaPath = getSchemaPath(
    SCHEMA_PATHS.GLOBAL_SERVICE_ACTIVATOR,
    join(configDirectory, SPLIT_JOURNEY_PATHS.FOLDERS.SERVICE_ACTIVATORS)
  );
  mkdirSync(globalServiceActivatorDir, { recursive: true });

  for (const serviceActivatorId in globalServiceActivators) {
    const serviceActivatorPath = join(
      globalServiceActivatorDir,
      `${sanitizeFilename(serviceActivatorId)}.jsonc`
    );
    const serviceActivatorWithSchema = addSchemaToObject(
      globalServiceActivators,
      schemaPath,
      serviceActivatorId
    );

    writeFileSync(serviceActivatorPath, stringify(serviceActivatorWithSchema, null, 2));
  }
}

function createPages(pagesConfiguration: PagesJsonSchema, configDirectory: string) {
  const globalPagesDir = join(configDirectory, SPLIT_JOURNEY_PATHS.FOLDERS.PAGES);
  const schemaPath = getSchemaPath(
    SCHEMA_PATHS.PAGE,
    join(configDirectory, SPLIT_JOURNEY_PATHS.FOLDERS.PAGES)
  );
  mkdirSync(globalPagesDir, { recursive: true });

  for (const page of pagesConfiguration.pages) {
    const pagePath = join(globalPagesDir, `${sanitizeFilename(page.id)}.jsonc`);
    const pageConfigWithSchema = addSchemaToObject(page, schemaPath);

    writeFileSync(pagePath, stringify(pageConfigWithSchema, null, 2));
  }
}

function createNavigation(pfeConfiguration: PfeJsonSchema, configDirectory: string) {
  const navigationJsonPath = join(configDirectory, `${SPLIT_JOURNEY_PATHS.FILES.NAVIGATION}.jsonc`);
  const navigation = pfeConfiguration.navConfiguration;
  delete navigation?.serviceActivators;
  const schemaPath = getSchemaPath(SCHEMA_PATHS.NAVIGATION, configDirectory);
  const navigationConfigWithSchema = addSchemaToObject(navigation, schemaPath);

  writeFileSync(navigationJsonPath, stringify(navigationConfigWithSchema, null, 2));
}

interface PagesJsonSchemaWithOptionalPages extends Omit<PagesJsonSchema, 'pages'> {
  pages?: PageConfiguration[];
}

function createApplicationJson(
  pagesConfiguration: PagesJsonSchemaWithOptionalPages,
  pfeConfiguration: PfeJsonSchema,
  configDirectory: string
) {
  const applicationJsonPath = join(
    configDirectory,
    `${SPLIT_JOURNEY_PATHS.FILES.APPLICATION}.jsonc`
  );

  delete pagesConfiguration.pages;

  const applicationConfig = assign(
    pagesConfiguration,
    pfeConfiguration.appConfiguration?.pfeConfig
  );
  const schemaPath = getSchemaPath(SCHEMA_PATHS.APPLICATION, configDirectory);
  const applicationConfigWithSchema = addSchemaToObject(applicationConfig, schemaPath);

  writeFileSync(applicationJsonPath, stringify(applicationConfigWithSchema, null, 2));
}

function deleteClassicJourneyFiles(configDirectory: string) {
  const pagesJsonPath = join(configDirectory, 'pages.json');
  const pagesJsoncPath = join(configDirectory, 'pages.jsonc');
  const pfeJsonPath = join(configDirectory, 'pfe.json');
  const pfeJsoncPath = join(configDirectory, 'pfe.jsonc');

  rmSync(pagesJsonPath, { force: true });
  rmSync(pagesJsoncPath, { force: true });
  rmSync(pfeJsonPath, { force: true });
  rmSync(pfeJsoncPath, { force: true });
}

function sanitizeFilename(key: string) {
  return (
    key
      //eslint-disable-next-line no-control-regex
      .replace(/[<>:"/\\|?*\x00-\x1F]/g, '_')
      .replace(/\s+/g, '_')
      .substring(0, 255)
  );
}

function getSchemaPath(schemaPath: string, configDirectory: string) {
  try {
    // eslint-disable-next-line @nx/enforce-module-boundaries
    const packagePath = require.resolve('@allianz/taly-sdk');
    let packageDir = dirname(packagePath);

    // removes "src" at the end of the package dir string
    const srcPattern = /[/\\]src$/;
    if (srcPattern.test(packageDir)) {
      packageDir = packageDir.replace(srcPattern, '');
    }
    const absolutePath = join(packageDir, schemaPath);
    const relativePathToSchema = relative(configDirectory, absolutePath);

    return ensurePosixPathSeparators(relativePathToSchema);
  } catch (error) {
    console.error(
      `Couldn't find path to ${schemaPath}. Please add the $schema manually to your config file.`,
      error
    );
    return schemaPath;
  }
}

function addSchemaToObject<T>(sourceObject: T, schemaPath: string, sourceKey?: string) {
  // assign() ensures that all comments are preserved
  if (sourceKey) {
    return assign({ $schema: schemaPath }, sourceObject, [sourceKey]) as T & WithSchema;
  } else {
    return assign({ $schema: schemaPath }, sourceObject) as T & WithSchema;
  }
}

results matching ""

    No results matching ""