Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fe-fpm-writer): reuse 'async getManifest' function and make API methods async #2367

Merged
merged 10 commits into from
Sep 16, 2024
5 changes: 5 additions & 0 deletions .changeset/short-brooms-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sap-ux/fe-fpm-writer': minor
---

The API methods `generateCustomAction`, `generateCustomColumn`, `generateControllerExtension`, `generateCustomFilter`, `generateCustomHeaderSection`, `generateCustomSection`, `generateCustomSubSection`, `generateCustomPage`, `generateObjectPage`, `generateListReport`, `enableFPM` changed from synchronous to asynchronous.
5 changes: 5 additions & 0 deletions .changeset/warm-days-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sap-ux/fiori-elements-writer': patch
---

call 'generateCustomPage' from 'fe-fpm-writer' as async function
7 changes: 3 additions & 4 deletions packages/fe-fpm-writer/src/action/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import type { Editor } from 'mem-fs-editor';
import { create } from 'mem-fs-editor';
import type { CustomAction, CustomActionTarget, InternalCustomAction } from './types';
import { TargetControl } from './types';
import { join } from 'path';
import { render } from 'ejs';
import { validateVersion, validateBasePath } from '../common/validate';
import type { Manifest } from '../common/types';
import { setCommonDefaults } from '../common/defaults';
import { applyEventHandlerConfiguration, contextParameter } from '../common/event-handler';
import { getTemplatePath } from '../templates';
import { getJsonSpace } from '../common/file';
import { getManifest } from '../common/utils';

/**
* Enhances the provided custom action configuration with default data.
Expand Down Expand Up @@ -88,15 +88,14 @@ export function enhanceManifestAndGetActionsElementReference(manifest: any, targ
* @param {Editor} [fs] - the memfs editor instance
* @returns {Promise<Editor>} the updated memfs editor instance
*/
export function generateCustomAction(basePath: string, actionConfig: CustomAction, fs?: Editor): Editor {
export async function generateCustomAction(basePath: string, actionConfig: CustomAction, fs?: Editor): Promise<Editor> {
validateVersion(actionConfig.minUI5Version);
if (!fs) {
fs = create(createStorage());
}
validateBasePath(basePath, fs);

const manifestPath = join(basePath, 'webapp/manifest.json');
const manifest = fs.readJSON(manifestPath) as Manifest;
const { path: manifestPath, content: manifest } = await getManifest(basePath, fs);

const config = enhanceConfig(actionConfig, manifestPath, manifest);

Expand Down
10 changes: 3 additions & 7 deletions packages/fe-fpm-writer/src/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { lt, valid } from 'semver';
import { getMinUI5VersionAsArray, getMinimumUI5Version, type Manifest } from '@sap-ux/project-access';
import { FCL_ROUTER } from '../common/defaults';
import { getTemplatePath } from '../templates';
import { addExtensionTypes } from '../common/utils';
import { addExtensionTypes, getManifest } from '../common/utils';

/**
* Configurable options when enabling the Flexible Programming Model in a UI5 application.
Expand Down Expand Up @@ -79,16 +79,12 @@ function adaptMinUI5Version(manifest: Manifest, fs: Editor, manifestPath: string
* @param {Editor} [fs] - the mem-fs editor instance
* @returns {Promise<Editor>} the updated mem-fs editor instance
*/
export function enableFPM(basePath: string, config: FPMConfig = {}, fs?: Editor): Editor {
export async function enableFPM(basePath: string, config: FPMConfig = {}, fs?: Editor): Promise<Editor> {
if (!fs) {
fs = create(createStorage());
}

const manifestPath = join(basePath, 'webapp/manifest.json');
if (!fs.exists(manifestPath)) {
throw new Error(`Invalid project folder. Cannot find required file ${manifestPath}`);
}
const manifest = fs.readJSON(manifestPath) as any as Manifest;
const { path: manifestPath, content: manifest } = await getManifest(basePath, fs);

// add FE libs is not yet added
if (!manifest['sap.ui5']?.dependencies?.libs?.['sap.fe.templates']) {
Expand Down
30 changes: 4 additions & 26 deletions packages/fe-fpm-writer/src/building-block/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import { getTemplatePath } from '../templates';
import { CodeSnippetLanguage, type FilePathProps, type CodeSnippet } from '../prompts/types';
import { coerce, lt } from 'semver';
import type { Manifest } from '../common/types';
import { getMinimumUI5Version, getWebappPath } from '@sap-ux/project-access';
import { getMinimumUI5Version } from '@sap-ux/project-access';
import { detectTabSpacing, extendJSON } from '../common/file';
import { getManifest, getManifestPath } from '../common/utils';

const PLACEHOLDERS = {
'id': 'REPLACE_WITH_BUILDING_BLOCK_ID',
Expand All @@ -26,29 +27,6 @@ interface MetadataPath {
metaPath: string;
}

/**
* Gets manifest path.
*
* @param {string} basePath the base path
* @param {Editor} fs the memfs editor instance
* @returns {Manifest | undefined} path to manifest file
*/
async function getManifestPath(basePath: string, fs: Editor): Promise<string> {
return join(await getWebappPath(basePath, fs), 'manifest.json');
}

/**
* Gets manifest content.
*
* @param {string} basePath the base path
* @param {Editor} fs the memfs editor instance
* @returns {Manifest | undefined} the manifest content
*/
async function getManifest(basePath: string, fs: Editor): Promise<Manifest | undefined> {
const manifestPath = await getManifestPath(basePath, fs);
return fs.readJSON(manifestPath) as Manifest;
}

/**
* Generates a building block into the provided xml view file.
*
Expand All @@ -74,7 +52,7 @@ export async function generateBuildingBlock<T extends BuildingBlock>(

// Read the view xml and template files and update contents of the view xml file
const xmlDocument = getUI5XmlDocument(basePath, config.viewOrFragmentPath, fs);
const manifest = await getManifest(basePath, fs);
const { content: manifest } = await getManifest(basePath, fs);
const templateDocument = getTemplateDocument(config.buildingBlockData, xmlDocument, fs, manifest);
fs = updateViewFile(basePath, config.viewOrFragmentPath, config.aggregationPath, xmlDocument, templateDocument, fs);

Expand Down Expand Up @@ -352,7 +330,7 @@ export async function getSerializedFileContent<T extends BuildingBlock>(
const xmlDocument = config.viewOrFragmentPath
? getUI5XmlDocument(basePath, config.viewOrFragmentPath, fs)
: undefined;
const manifest = await getManifest(basePath, fs);
const { content: manifest } = await getManifest(basePath, fs, false);
const content = getTemplateContent(config.buildingBlockData, xmlDocument, manifest, fs, true);
const filePathProps = getFilePathProps(basePath, config.viewOrFragmentPath);
return {
Expand Down
12 changes: 8 additions & 4 deletions packages/fe-fpm-writer/src/column/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { applyEventHandlerConfiguration } from '../common/event-handler';
import { extendJSON } from '../common/file';
import { getTemplatePath } from '../templates';
import { coerce, gte } from 'semver';
import { getManifest } from '../common/utils';

/**
* Get the template folder for the given UI5 version.
Expand Down Expand Up @@ -72,17 +73,20 @@ function enhanceConfig(
* @returns {Promise<Editor>} the updated mem-fs editor instance
* @param {string} basePath - the base path
* @param {CustomTableColumn} customColumn - the custom column configuration
* @param {Editor} [fs] - the mem-fs editor instance
* @param {Promise<Editor>} [fs] - the mem-fs editor instance
*/
export function generateCustomColumn(basePath: string, customColumn: CustomTableColumn, fs?: Editor): Editor {
export async function generateCustomColumn(
basePath: string,
customColumn: CustomTableColumn,
fs?: Editor
): Promise<Editor> {
validateVersion(customColumn.minUI5Version);
if (!fs) {
fs = create(createStorage());
}
validateBasePath(basePath, fs);

const manifestPath = join(basePath, 'webapp/manifest.json');
const manifest = fs.readJSON(manifestPath) as Manifest;
const { path: manifestPath, content: manifest } = await getManifest(basePath, fs);

// merge with defaults
const completeColumn = enhanceConfig(fs, customColumn, manifestPath, manifest);
Expand Down
14 changes: 14 additions & 0 deletions packages/fe-fpm-writer/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,17 @@ export interface FragmentContentData {
content: string;
requireAttribute?: string;
}

/**
* Interface contain information about application manifest.
*/
export interface ManifestData {
/**
* Path to manifest.json file.
*/
path: string;
/**
* Parsed content of manifest.json file.
*/
content: Manifest;
}
33 changes: 32 additions & 1 deletion packages/fe-fpm-writer/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type { Editor } from 'mem-fs-editor';
import os from 'os';
import { join } from 'path';
import { coerce, minor } from 'semver';
import { getWebappPath } from '@sap-ux/project-access';
import { getTemplatePath } from '../templates';
import type { FileContentPosition } from '../common/types';
import type { FileContentPosition, Manifest, ManifestData } from './types';

/**
* Method inserts passed text into content by char index position.
Expand Down Expand Up @@ -68,3 +69,33 @@ export function addExtensionTypes(basePath: string, minUI5Version: string | unde
fs.copyTpl(getTemplatePath('common/sap.fe.d.ts'), path, { version });
}
}

/**
* Gets manifest path.
*
* @param {string} basePath the base path
* @param {Editor} fs the memfs editor instance
* @returns {Manifest | undefined} path to manifest file
*/
export async function getManifestPath(basePath: string, fs: Editor): Promise<string> {
return join(await getWebappPath(basePath, fs), 'manifest.json');
}

/**
* Gets content and path of the manifest.
*
* @param {string} basePath the base path
* @param {Editor} fs the memfs editor instance
* @param {boolean} [validate] validate if 'manifest.json' file exists - throw error if file does not exist
* @returns {Manifest | undefined} The content and path of the manifest
*/
export async function getManifest(basePath: string, fs: Editor, validate = true): Promise<ManifestData> {
const path = await getManifestPath(basePath, fs);
if (validate && !fs.exists(path)) {
throw new Error(`Invalid project folder. Cannot find required file ${path}`);
}
return {
path,
content: fs.readJSON(path) as Manifest
};
}
11 changes: 5 additions & 6 deletions packages/fe-fpm-writer/src/controller-extension/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { validateBasePath } from '../common/validate';
import type { Manifest } from '../common/types';
import { setCommonDefaults } from '../common/defaults';
import { getTemplatePath } from '../templates';
import { addExtensionTypes } from '../common/utils';
import { addExtensionTypes, getManifest } from '../common/utils';
import { extendJSON } from '../common/file';

export const UI5_CONTROLLER_EXTENSION_LIST_REPORT = 'sap.fe.templates.ListReport.ListReportController';
Expand Down Expand Up @@ -206,21 +206,20 @@ function getManifestReplacer(
* @param {string} basePath - the base path
* @param {ControllerExtension} controllerConfig - the controller extension configuration
* @param {Editor} [fs] - the memfs editor instance
* @returns {Editor} the updated memfs editor instance
* @returns {Promise<Editor>} the updated memfs editor instance
*/
export function generateControllerExtension(
export async function generateControllerExtension(
basePath: string,
controllerConfig: ControllerExtension,
fs?: Editor
): Editor {
): Promise<Editor> {
// Validate the base and view paths
if (!fs) {
fs = create(createStorage());
}
validateBasePath(basePath, fs);

const manifestPath = join(basePath, 'webapp/manifest.json');
const manifest = fs.readJSON(manifestPath) as Manifest;
const { path: manifestPath, content: manifest } = await getManifest(basePath, fs);

// merge with defaults
const internalConfig = enhanceConfig(controllerConfig, manifestPath, manifest);
Expand Down
6 changes: 3 additions & 3 deletions packages/fe-fpm-writer/src/filter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getJsonSpace } from '../common/file';
import { applyEventHandlerConfiguration, contextParameter } from '../common/event-handler';
import type { FilterField } from '../building-block/types';
import type { ManifestNamespace } from '@sap-ux/project-access';
import { getManifest } from '../common/utils';

/**
* Enhances the provided custom filter configuration with default data.
Expand Down Expand Up @@ -49,14 +50,13 @@ function enhanceConfig(data: CustomFilter, manifestPath: string, manifest: Manif
* @param {Editor} [fs] - the memfs editor instance
* @returns {Promise<Editor>} the updated memfs editor instance
*/
export function generateCustomFilter(basePath: string, filterConfig: CustomFilter, fs?: Editor): Editor {
export async function generateCustomFilter(basePath: string, filterConfig: CustomFilter, fs?: Editor): Promise<Editor> {
if (!fs) {
fs = create(createStorage());
}
validateBasePath(basePath, fs);

const manifestPath = join(basePath, 'webapp/manifest.json');
const manifest = fs.readJSON(manifestPath) as Manifest;
const { path: manifestPath, content: manifest } = await getManifest(basePath, fs);
const config = enhanceConfig(filterConfig, manifestPath, manifest);

// Apply event handler
Expand Down
18 changes: 9 additions & 9 deletions packages/fe-fpm-writer/src/page/common.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Editor } from 'mem-fs-editor';
import { create as createStorage } from 'mem-fs';
import { create } from 'mem-fs-editor';
import { join } from 'path';
import { render } from 'ejs';
import type { ManifestNamespace } from '@sap-ux/project-access';
import { validateBasePath } from '../common/validate';
Expand All @@ -23,6 +22,7 @@ import { FCL_ROUTER } from '../common/defaults';
import { extendJSON } from '../common/file';
import { getTemplatePath } from '../templates';
import { coerce, gte } from 'semver';
import { getManifest } from '../common/utils';

type EnhancePageConfigFunction = (
data: ObjectPage | ListReport,
Expand Down Expand Up @@ -212,19 +212,20 @@ export function initializeTargetSettings(
* @param dependencies - expected dependencies
* @returns the updated memfs editor instance
*/
export function validatePageConfig(
export async function validatePageConfig(
basePath: string,
config: CustomPage | ObjectPage,
fs: Editor,
dependencies = []
): Editor {
): Promise<Editor> {
// common validators

validateBasePath(basePath, fs, dependencies);

// validate config against the manifest
if (config.navigation?.sourcePage) {
const manifest = fs.readJSON(join(basePath, 'webapp/manifest.json')) as Manifest;
const { content: manifest } = await getManifest(basePath, fs);

if (!manifest['sap.ui5']?.routing?.targets?.[config.navigation.sourcePage]) {
throw new Error(`Could not find navigation source ${config.navigation.sourcePage}!`);
}
Expand Down Expand Up @@ -257,20 +258,19 @@ export function validatePageConfig(
* @param fs - the memfs editor instance
* @returns the updated memfs editor instance
*/
export function extendPageJSON(
export async function extendPageJSON(
basePath: string,
data: ObjectPage,
enhanceDataFn: EnhancePageConfigFunction,
templatePath: string,
fs?: Editor
): Editor {
): Promise<Editor> {
if (!fs) {
fs = create(createStorage());
}
validatePageConfig(basePath, data, fs);
await validatePageConfig(basePath, data, fs);

const manifestPath = join(basePath, 'webapp/manifest.json');
const manifest = fs.readJSON(manifestPath) as Manifest;
const { path: manifestPath, content: manifest } = await getManifest(basePath, fs);

const config = enhanceDataFn(data, manifest);

Expand Down
8 changes: 4 additions & 4 deletions packages/fe-fpm-writer/src/page/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type { Manifest } from '../common/types';
import { validateVersion } from '../common/validate';
import { getTemplatePath } from '../templates';
import { coerce, gte } from 'semver';
import { addExtensionTypes } from '../common/utils';
import { addExtensionTypes, getManifestPath } from '../common/utils';
import { extendJSON } from '../common/file';

/**
Expand Down Expand Up @@ -74,14 +74,14 @@ export function getTemplateRoot(ui5Version?: string): string {
* @param {Editor} [fs] - the memfs editor instance
* @returns {Promise<Editor>} the updated memfs editor instance
*/
export function generate(basePath: string, data: CustomPage, fs?: Editor): Editor {
export async function generate(basePath: string, data: CustomPage, fs?: Editor): Promise<Editor> {
if (!fs) {
fs = create(createStorage());
}
validateVersion(data.minUI5Version);
validatePageConfig(basePath, data, fs, []);
await validatePageConfig(basePath, data, fs, []);

const manifestPath = join(basePath, 'webapp/manifest.json');
const manifestPath = await getManifestPath(basePath, fs);

const config = enhanceData(data, manifestPath, fs);

Expand Down
2 changes: 1 addition & 1 deletion packages/fe-fpm-writer/src/page/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ function enhanceData(data: ListReport, manifest: Manifest): InternalListReport {
* @param fs - the memfs editor instance
* @returns the updated memfs editor instance
*/
export function generate(basePath: string, data: ListReport, fs?: Editor): Editor {
export async function generate(basePath: string, data: ListReport, fs?: Editor): Promise<Editor> {
return extendPageJSON(basePath, data, enhanceData, 'page/list/manifest.json', fs);
}
2 changes: 1 addition & 1 deletion packages/fe-fpm-writer/src/page/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ function enhanceData(data: ObjectPage, manifest: Manifest): InternalObjectPage {
* @param fs - the memfs editor instance
* @returns the updated memfs editor instance
*/
export function generate(basePath: string, data: ObjectPage, fs?: Editor): Editor {
export async function generate(basePath: string, data: ObjectPage, fs?: Editor): Promise<Editor> {
return extendPageJSON(basePath, data, enhanceData, '/page/object/manifest.json', fs);
}
Loading
Loading