File

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

Extends

Omit

Index

Properties

Properties

pages (Optional)
Type PageConfiguration[]
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) {
  const { pagesConfiguration, pfeConfiguration } = await loadJourneyFromFolder(configDirectory);

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

  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 {
    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 ""