libs/sdk/src/node/journey/generate/generate.ts
Omit<JourneySrcGenerationOptions, 'project'>
Properties |
|
| directory | |
| Type |
string
|
|
Description
|
Path where the new workspace will be generated |
| ignoreLibraryCompatibility (Optional) | |
| Type |
boolean
|
|
Description
|
Skip the library compatibility check and always use the TALY version that is installed already regardless of potential incompatibilities. |
| legacyDependencyResolution (Optional) | |
| Type |
boolean
|
|
Description
|
With this flag the peer dependencies are collected by TALY and not automatically by npm. It can be used to work around peer dependency conflicts. |
| name | |
| Type |
string
|
|
Description
|
The name of the journey project that will be created inside of the new workspace |
| skipInstall | |
| Type |
boolean
|
|
Description
|
Skip the installation of the Building Block libraries consumed by the journey |
| aquilaChannel (Optional) | |
| Type |
CHANNEL
|
| Default value |
"retail"
|
|
Description
|
Provide a value of 'expert' to specify that this journey is meant for internal usage (Experts, insurance agents) or a value of 'retail' for user-facing journeys. It will be 'retail' by default. "retail" |
| aquilaTheme (Optional) | |
| Type |
string
|
|
Description
|
Provide a path to a css file for a custom Aquila theme.
When |
| baseConfigDirectory (Optional) | |
| Type |
string
|
|
Description
|
Path to the base configuration you extend from. It's required for multi-tenant journeys. |
| configDirectory (Optional) | |
| Type |
string
|
|
Description
|
The path to the config directory that contains journey configuration files (relative to the project root). |
| debugDfPort (Optional) | |
| Type |
number
|
|
Description
|
Port for the Dynamic Form editor server.
Only used by the |
| deployUrl (Optional) | |
| Type |
string
|
|
Description
|
Only for web components: The url at which the web component will be served. |
| env (Optional) | |
| Type |
string[]
|
| Default value |
[]
|
|
Description
|
You can provide individual overrides or new env values in the form of KEY=value. Repeat the env option if necessary. [] |
| envPath (Optional) | |
| Type |
string
|
|
Description
|
Provide path to a file with the environment config. In this file each environment variable needs to be on a separate line and in the format VARIABLE=VALUE (e.g. BFF_BASE_URL=http://my-bff.url). |
| experimental (Optional) | |
| Type |
Experiments[]
|
| Default value |
[]
|
|
Description
|
Enable specific features that are not yet available by default and that can change any day (unstable). Use at your own risk. You can find more information under https://taly.frameworks.allianz.io/additional-documentation/app-generation.html#experimental-features. [] |
| pfeAutomaticStateSessionStorage (Optional) | |
| Type |
boolean
|
| Default value |
false
|
|
Description
|
Enable PFE to automatically store state in session storage whenever the state changes.
This option alone has no effect unless |
| scripts (Optional) | |
| Type |
string[]
|
|
Description
|
Scripts (URLs) to be loaded with the application. These will be added as to the index.html. |
| showDevtools (Optional) | |
| Type |
boolean
|
| Default value |
false
|
|
Description
|
Whether to include the TALY devtools. This enables all devtools surfaces
(ACL Inspector, ACL Hierarchical Inspector, PFE Debugger, Building Block Debugger and
Dynamic Form Debugger) through |
| showroom (Optional) | |
| Type |
boolean
|
| Default value |
false
|
|
Description
|
Generate the journey in showroom mode false |
| stripLocaleBaseHref (Optional) | |
| Type |
boolean
|
| Default value |
false
|
|
Description
|
Set the |
| target (Optional) | |
| Type |
JourneyTargetType
|
| Default value |
"app"
|
|
Description
|
Intended integration strategy for this journey. Choose |
| tsStrictMode (Optional) | |
| Type |
boolean
|
| Default value |
false
|
|
Description
|
Whether the generated app should use TypeScript's strict mode for compilation false |
| useEnhancedVerticalSpacing (Optional) | |
| Type |
boolean
|
| Default value |
false
|
|
Description
|
Whether to use enhanced vertical spacing instead of the standard vertical spacing. false |
| useHashLocationStrategy (Optional) | |
| Type |
boolean
|
| Default value |
false
|
|
Description
|
Whether to use a hash location strategy. Only has an effect when the target is 'app' (standalone journey). Recommended only for special cases where the app server does not support the default path location strategy. false |
| useNoopLocationStrategy (Optional) | |
| Type |
boolean
|
| Default value |
false
|
|
Description
|
Whether to use a noop location strategy. Only has an effect when the target is 'webcomponent'. false |
import { kebabCase } from 'lodash-es';
import { existsSync } from 'node:fs';
import { readFile, rm } from 'node:fs/promises';
import { join, resolve } from 'node:path';
import { lt, neq } from 'semver';
import { version as TALY_VERSION } from '../../../../package.json';
import { assertValidName } from '../../../lib/journey/utils/validate-parameters';
import { JourneySrcGenerationOptions } from '../../../lib/model/journey-src-generation-options';
import { loadJourneyFromFolder } from '../load/load';
import { addWebComponentConfigs } from './lib/add-web-component-configs/add-web-component-configs';
import { createJourney } from './lib/create-journey/create-journey';
import { createWorkspace } from './lib/create-workspace/create-workspace';
import { generateJourneySrc } from './lib/generate-journey-src/generate-journey-src';
import { installJourneyDependencies } from './lib/install-journey-dependencies/install-journey-dependencies';
import { proceedWithTemporaryTalyVersion } from './lib/proceed-with-temp-taly/proceed-with-temp-taly';
import { findLatestCompatibleTalyVersion } from './utils/taly-version-compatibility';
import { assertValidExperiments, assertValidPaths } from './utils/validate-parameters';
export interface GenerateJourneyOptions extends Omit<JourneySrcGenerationOptions, 'project'> {
/**
* Path where the new workspace will be generated
*/
directory: string;
/**
* With this flag the peer dependencies are collected by TALY and not automatically by npm. It can be used to work around peer dependency conflicts.
*/
legacyDependencyResolution?: boolean;
/**
* The name of the journey project that will be created inside of the new workspace
*/
name: string;
/**
* Skip the installation of the Building Block libraries consumed by the journey
*/
skipInstall: boolean;
/**
* Skip the library compatibility check and always use the TALY version that is
* installed already regardless of potential incompatibilities.
*/
ignoreLibraryCompatibility?: boolean;
}
export interface ProgressReport {
type: 'start' | 'success' | 'info' | 'warning';
text: string;
}
/**
* This function generates a journey in a new Nx workspace.
*
* It returns an AsyncIterator that yields the generation progress.
*
* Usage:
* ```ts
* for await (const progress of generateJourney(options)) {
* console.log(progress.text);
* }
* ```
*/
export async function* generateJourney(
options: GenerateJourneyOptions
): AsyncGenerator<ProgressReport, void> {
const configDirectory = resolve(options.configDirectory ?? 'config');
const destinationDirectory = resolve(options.directory);
const normalizedOptions: GenerateJourneyOptions = {
...options,
configDirectory,
directory: destinationDirectory
};
assertValidName(normalizedOptions.name);
assertValidPaths(normalizedOptions);
assertValidExperiments(normalizedOptions);
let yieldIncompatibleTalyVersionWarning = false;
let compatibleTalyVersion: string;
let compatibilityError: Error | null = null;
if (process.env['TALY_SKIP_COMPATIBILITY_CHECK'] !== 'true') {
yield {
type: 'start',
text: 'Checking the compatibility of the libraries used in your journey configuration'
};
compatibleTalyVersion = await findLatestCompatibleTalyVersion(
configDirectory,
TALY_VERSION
).catch((error) => (compatibilityError = error));
if (compatibleTalyVersion === TALY_VERSION) {
yield {
type: 'success',
text: 'All of the libraries used in your journey configuration are compatible with this version of TALY'
};
} else if (normalizedOptions.ignoreLibraryCompatibility) {
if (compatibilityError) {
yield {
type: 'warning',
text: `Could not find a compatible TALY version for the given combination of libraries and their versions.`
};
yield {
type: 'warning',
text: `Due to the 'ignoreLibraryCompatibility' option, I will proceed with your local TALY version ${TALY_VERSION}.`
};
yieldIncompatibleTalyVersionWarning = true;
} else if (compatibleTalyVersion !== TALY_VERSION) {
yield {
type: 'warning',
text: `The latest TALY version that is compatible with your journey configuration is ${compatibleTalyVersion}.`
};
yield {
type: 'warning',
text: `Due to the 'ignoreLibraryCompatibility' option, I will proceed with your local TALY version ${TALY_VERSION}.`
};
yieldIncompatibleTalyVersionWarning = true;
}
} else {
if (compatibilityError) {
throw compatibilityError;
} else if (lt(compatibleTalyVersion, '23.1.0')) {
// v23.1.0 was the first to include the `generate-journey` CLI command
// so we don't support anything below that
throw new Error(
`Your journey configuration requires TALY version ${compatibleTalyVersion}. This command only supports Journey configurations with libraries that require TALY version 23.1.0 or above. Please update your journey configuration to use libraries that are compatible with TALY version 23.1.0 or above. It is not recommended, but if you need to disable this check, pass the 'ignoreLibraryCompatibility' option.`
);
} else if (compatibleTalyVersion !== TALY_VERSION) {
yield {
type: 'success',
text: `The latest TALY version that is compatible with your journey configuration is ${compatibleTalyVersion} (currently installed: ${TALY_VERSION})`
};
// we need to remove the `ignoreLibraryCompatibility` option from the options object
// otherwise the schema validation from our Nx generator will fail
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { ignoreLibraryCompatibility, ...otherGenerationOptions } = normalizedOptions;
yield* proceedWithTemporaryTalyVersion(compatibleTalyVersion, {
...otherGenerationOptions,
configDirectory
});
return;
}
}
}
yield { type: 'start', text: 'Loading Journey Config from Folder' };
const journeyConfig = await loadJourneyFromFolder(configDirectory);
yield { type: 'success', text: 'Loaded Journey Config from Folder' };
if (!existsSync(destinationDirectory)) {
yield { type: 'start', text: 'Creating a fresh workspace' };
await createWorkspace(destinationDirectory, normalizedOptions.legacyDependencyResolution);
yield { type: 'success', text: 'Created a fresh workspace' };
} else {
const existingWorkspacePackageJson = JSON.parse(
await readFile(join(destinationDirectory, 'package.json'), 'utf-8')
) as { dependencies: Record<string, string> };
const talyDependencyVersion = existingWorkspacePackageJson.dependencies['@allianz/taly-nx'];
const talyDependencyVersionWithoutRange = talyDependencyVersion.replace(/^\^|~/, '');
if (neq(TALY_VERSION, talyDependencyVersionWithoutRange)) {
yield {
type: 'start',
text: `The existing workspace does not provide the required TALY version (Available: ${talyDependencyVersionWithoutRange}. Required: ${TALY_VERSION}). Removing existing workspace and creating a new one...`
};
await rm(destinationDirectory, { recursive: true });
await createWorkspace(destinationDirectory, normalizedOptions.legacyDependencyResolution);
yield { type: 'success', text: 'Created a new workspace' };
} else {
yield {
type: 'info',
text: `Reusing existing workspace in "${destinationDirectory}"`
};
}
}
const projectName = kebabCase(normalizedOptions.name);
yield {
type: 'start',
text: 'Integrating your journey configuration into the generated workspace'
};
await createJourney({
destinationDirectory: destinationDirectory,
configDirectory: configDirectory,
journeyConfig,
journeyName: projectName,
envPath: normalizedOptions.envPath,
aquilaTheme: normalizedOptions.aquilaTheme
});
yield {
type: 'success',
text: 'Integrated your journey configuration into the generated workspace'
};
const isWebcomponent = normalizedOptions.target === 'webcomponent';
if (isWebcomponent) {
yield {
type: 'start',
text: 'Adding the webcomponent configurations to the journey project'
};
await addWebComponentConfigs(projectName, destinationDirectory);
yield {
type: 'success',
text: 'Added the webcomponent configurations to the journey project'
};
}
if (normalizedOptions.skipInstall) {
yield {
type: 'warning',
text: 'Skipping installation of Building Block libraries. This is an advanced feature and should only be used if you know what you are doing.'
};
} else {
yield {
type: 'start',
text: 'Installing the required Building Block libraries'
};
await installJourneyDependencies(
destinationDirectory,
journeyConfig,
normalizedOptions.legacyDependencyResolution
);
yield {
type: 'success',
text: 'Installed the required Building Block libraries'
};
}
yield {
type: 'start',
text: 'Generating the source code of your journey'
};
// we only want to pass the options that are relevant for the `journey-src` generator,
// so we use object destructuring with the spread operator to "remove" the additional options
const {
/* eslint-disable @typescript-eslint/no-unused-vars */
name,
directory,
ignoreLibraryCompatibility,
legacyDependencyResolution,
skipInstall,
...journeySrcOptions
} = normalizedOptions;
await generateJourneySrc(destinationDirectory, {
...journeySrcOptions,
project: projectName
});
yield {
type: 'success',
text: 'Generated the source code of your journey'
};
if (yieldIncompatibleTalyVersionWarning) {
yield {
type: 'warning',
text: 'Please note that the generated journey might not work as expected due to a potentially incompatible TALY version.'
};
if (compatibilityError) {
yield {
type: 'warning',
text: `The TALY version that was used to generate your journey is ${TALY_VERSION}, however there is no TALY version that satisfies all of the libraries in your journey configuration.`
};
yield {
type: 'warning',
text: 'Please make sure to test your journey thoroughly and update your journey configuration to use up-to-date libraries that share a common TALY dependency.'
};
yield {
type: 'warning',
text: compatibilityError
};
} else {
yield {
type: 'warning',
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
text: `The TALY version that was used to generate your journey is ${TALY_VERSION}, however the TALY version that is guaranteed to be compatible with your journey configuration is ${compatibleTalyVersion!}.`
};
yield {
type: 'warning',
text: 'Please make sure to test your journey thoroughly and consider removing the "ignoreLibraryCompatibility" option to use the compatible TALY version to generate your journey.'
};
}
yield {
type: 'warning',
text: 'See the documentation for more information: https://taly.frameworks.allianz.io/additional-documentation/app-generation.html#requirement-library-compatibility'
};
}
}