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

fix: static webapp path #2931

Merged
merged 25 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
437dfcd
get rid of static webapp path
heimwege Feb 17, 2025
fbac962
get rid of static webapp path (2)
heimwege Feb 17, 2025
b0ae942
fix readme
heimwege Feb 17, 2025
142db20
fixes
heimwege Feb 17, 2025
8371fe4
fixes
heimwege Feb 17, 2025
17d81a5
refactoring
heimwege Feb 17, 2025
2258600
fix unit test
heimwege Feb 17, 2025
d6cd911
fix unit test
heimwege Feb 17, 2025
66ae4cc
adjust snapshots
heimwege Feb 17, 2025
25845d5
adjust snapshots
heimwege Feb 17, 2025
01ba2f6
adjust snapshots
heimwege Feb 17, 2025
c5b65ab
backward compatibility
devinea Feb 17, 2025
5ac81c0
force posix path
devinea Feb 17, 2025
9513c76
adjust snapshots
heimwege Feb 18, 2025
defc2ba
review comments + refactoring
heimwege Feb 19, 2025
8200424
Merge branch 'main' of github.com:SAP/open-ux-tools into fix/2589/sta…
heimwege Feb 19, 2025
73c579d
Merge branch 'main' into fix/2589/static-webapp-path
johannes-kolbe Feb 20, 2025
1f410d6
Merge branch 'main' into fix/2589/static-webapp-path
mmilko01 Feb 24, 2025
1e7b587
Merge branch 'main' into fix/2589/static-webapp-path
Klaus-Keller Feb 24, 2025
9d877d7
adjust JSDoc
heimwege Feb 26, 2025
8d9ca24
Merge branch 'main' of github.com:SAP/open-ux-tools into fix/2589/sta…
heimwege Feb 26, 2025
68605cf
add missing await + add missing return types to functions
heimwege Feb 26, 2025
ae14c9b
refactoring
heimwege Feb 26, 2025
aa2d5fa
Merge branch 'main' into fix/2589/static-webapp-path
johannes-kolbe Feb 26, 2025
0f31b39
Merge branch 'main' into fix/2589/static-webapp-path
heimwege Feb 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/orange-donkeys-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@sap-ux/adp-flp-config-sub-generator': patch
'@sap-ux/mockserver-config-writer': patch
'@sap-ux/odata-service-writer': patch
'@sap-ux/adp-tooling': patch
'@sap-ux/telemetry': patch
'@sap-ux/create': patch
'@sap-ux/i18n': patch
---

fix: usage of static webapp path
2 changes: 1 addition & 1 deletion packages/adp-flp-config-sub-generator/src/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export default class extends Generator {
requestOptions['auth'] = { username: this.credentials.username, password: this.credentials.password };
}
const provider = await createAbapServiceProvider(target, requestOptions, false, this.toolsLogger);
const variant = getVariant(this.projectRootPath);
const variant = await getVariant(this.projectRootPath);
const manifestService = await ManifestService.initMergedManifest(
provider,
this.projectRootPath,
Expand Down
2 changes: 1 addition & 1 deletion packages/adp-tooling/src/base/abap/manifest-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export class ManifestService {
*/
private async fetchMergedManifest(basePath: string, descriptorVariantId: string): Promise<void> {
const zip = new ZipFile();
const files = getWebappFiles(basePath);
const files = await getWebappFiles(basePath);
for (const file of files) {
zip.addFile(file.relativePath, Buffer.from(file.content, 'utf-8'));
}
Expand Down
49 changes: 28 additions & 21 deletions packages/adp-tooling/src/base/helper.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Editor } from 'mem-fs-editor';
import { existsSync, readdirSync, readFileSync } from 'fs';
import { join, isAbsolute, relative } from 'path';

import { UI5Config } from '@sap-ux/ui5-config';
import { join, isAbsolute, relative, basename, dirname } from 'path';
import { getWebappPath, FileName, readUi5Yaml } from '@sap-ux/project-access';
import type { UI5Config } from '@sap-ux/ui5-config';

import type { DescriptorVariant, AdpPreviewConfig } from '../types';

Expand All @@ -11,13 +11,14 @@ import type { DescriptorVariant, AdpPreviewConfig } from '../types';
*
* @param {string} basePath - The path to the adaptation project.
* @param {Editor} fs - The mem-fs editor instance.
* @returns {DescriptorVariant} The app descriptor variant.
* @returns {Promise<DescriptorVariant>} The app descriptor variant.
*/
export function getVariant(basePath: string, fs?: Editor): DescriptorVariant {
export async function getVariant(basePath: string, fs?: Editor): Promise<DescriptorVariant> {
const webappPath = await getWebappPath(basePath);
if (fs) {
return fs.readJSON(join(basePath, 'webapp', 'manifest.appdescr_variant')) as unknown as DescriptorVariant;
return fs.readJSON(join(webappPath, FileName.ManifestAppDescrVar)) as unknown as DescriptorVariant;
}
return JSON.parse(readFileSync(join(basePath, 'webapp', 'manifest.appdescr_variant'), 'utf-8'));
return JSON.parse(readFileSync(join(webappPath, FileName.ManifestAppDescrVar), 'utf-8'));
}

/**
Expand All @@ -27,8 +28,8 @@ export function getVariant(basePath: string, fs?: Editor): DescriptorVariant {
* @param {DescriptorVariant} variant - The descriptor variant object.
* @param {Editor} fs - The mem-fs editor instance.
*/
export function updateVariant(basePath: string, variant: DescriptorVariant, fs: Editor) {
fs.writeJSON(join(basePath, 'webapp', 'manifest.appdescr_variant'), variant);
export async function updateVariant(basePath: string, variant: DescriptorVariant, fs: Editor): Promise<void> {
fs.writeJSON(join(await getWebappPath(basePath), FileName.ManifestAppDescrVar), variant);
}

/**
Expand All @@ -38,12 +39,12 @@ export function updateVariant(basePath: string, variant: DescriptorVariant, fs:
* or `appdescr_app_addNewInbound` present in the content of the descriptor variant.
*
* @param {string} basePath - The base path of the project where the manifest.appdescr_variant is located.
* @returns {boolean} Returns `true` if FLP configuration changes exist, otherwise `false`.
* @returns {Promise<boolean>} Returns `true` if FLP configuration changes exist, otherwise `false`.
* @throws {Error} Throws an error if the variant could not be retrieved.
*/
export function flpConfigurationExists(basePath: string): boolean {
export async function flpConfigurationExists(basePath: string): Promise<boolean> {
try {
const variant = getVariant(basePath);
const variant = await getVariant(basePath);
return variant.content?.some(
({ changeType }) =>
changeType === 'appdescr_app_changeInbound' || changeType === 'appdescr_app_addNewInbound'
Expand Down Expand Up @@ -74,13 +75,19 @@ export function isTypescriptSupported(basePath: string, fs?: Editor): boolean {
*/
export async function getAdpConfig(basePath: string, yamlPath: string): Promise<AdpPreviewConfig> {
const ui5ConfigPath = isAbsolute(yamlPath) ? yamlPath : join(basePath, yamlPath);
const ui5Conf = await UI5Config.newInstance(readFileSync(ui5ConfigPath, 'utf-8'));
const customMiddlerware =
ui5Conf.findCustomMiddleware<{ adp: AdpPreviewConfig }>('fiori-tools-preview') ??
ui5Conf.findCustomMiddleware<{ adp: AdpPreviewConfig }>('preview-middleware');
const adp = customMiddlerware?.configuration?.adp;
let ui5Conf: UI5Config;
let adp: AdpPreviewConfig | undefined;
try {
ui5Conf = await readUi5Yaml(dirname(ui5ConfigPath), basename(ui5ConfigPath));
const customMiddleware =
ui5Conf.findCustomMiddleware<{ adp: AdpPreviewConfig }>('fiori-tools-preview') ??
ui5Conf.findCustomMiddleware<{ adp: AdpPreviewConfig }>('preview-middleware');
adp = customMiddleware?.configuration?.adp;
} catch (error) {
// do nothing here
}
if (!adp) {
throw new Error('No system configuration found in ui5.yaml');
throw new Error(`No system configuration found in ${basename(ui5ConfigPath)}`);
}
return adp;
}
Expand All @@ -89,10 +96,10 @@ export async function getAdpConfig(basePath: string, yamlPath: string): Promise<
* Get all files in the webapp folder.
*
* @param {string} basePath - The path to the adaptation project.
* @returns {Array<{ relativePath: string; content: string }>} The files in the webapp folder.
* @returns {Promise<{ relativePath: string; content: string }[]>} The files in the webapp folder.
*/
export function getWebappFiles(basePath: string): { relativePath: string; content: string }[] {
const dir = join(basePath, 'webapp');
export async function getWebappFiles(basePath: string): Promise<{ relativePath: string; content: string }[]> {
const dir = await getWebappPath(basePath);
const files: { relativePath: string; content: string }[] = [];

const getFilesRecursivelySync = (directory: string): void => {
Expand Down
4 changes: 2 additions & 2 deletions packages/adp-tooling/src/preview/change-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export async function addAnnotationFile(
serviceUrl: datasoruces[dataSourceId].uri,
fileName: basename(dataSource[annotationDataSourceKey].uri)
},
variant: getVariant(projectRoot),
variant: await getVariant(projectRoot),
isCommand: false
},
fs
Expand All @@ -289,7 +289,7 @@ export async function addAnnotationFile(
* @returns Promise<ManifestService>
*/
async function getManifestService(basePath: string, logger: Logger): Promise<ManifestService> {
const variant = getVariant(basePath);
const variant = await getVariant(basePath);
const { target, ignoreCertErrors = false } = await getAdpConfig(basePath, join(basePath, FileName.Ui5Yaml));
const provider = await createAbapServiceProvider(target, { ignoreCertErrors }, true, logger);
return await ManifestService.initMergedManifest(provider, basePath, variant, logger as unknown as ToolsLogger);
Expand Down
36 changes: 22 additions & 14 deletions packages/adp-tooling/src/preview/routes-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export default class RoutesHandler {
* @param data Data that is sent to the client
* @param contentType Content type, defaults to json
*/
private sendFilesResponse(res: Response, data: object | string, contentType: string = 'application/json') {
private sendFilesResponse(res: Response, data: object | string, contentType: string = 'application/json'): void {
res.status(HttpStatusCodes.OK).contentType(contentType).send(data);
}

Expand All @@ -100,12 +100,12 @@ export default class RoutesHandler {
* @param res Response
* @param next Next Function
*/
public handleReadAllFragments = async (_: Request, res: Response, next: NextFunction) => {
public handleReadAllFragments = async (_: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const files = await this.readAllFilesByGlob('/**/changes/fragments/*.fragment.xml');

const fileNames = files.map((f) => ({
fragmentName: f.getName()
const fileNames = files.map((file) => ({
fragmentName: file.getName()
}));

this.sendFilesResponse(res, {
Expand All @@ -125,12 +125,12 @@ export default class RoutesHandler {
* @param res Response
* @param next Next Function
*/
public handleReadAllControllers = async (_: Request, res: Response, next: NextFunction) => {
public handleReadAllControllers = async (_: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const files = await this.readAllFilesByGlob('/**/changes/coding/*.js');

const fileNames = files.map((f) => ({
controllerName: f.getName()
const fileNames = files.map((file) => ({
controllerName: file.getName()
}));

this.sendFilesResponse(res, {
Expand All @@ -150,7 +150,11 @@ export default class RoutesHandler {
* @param res Response
* @param next Next Function
*/
public handleGetControllerExtensionData = async (req: Request, res: Response, next: NextFunction) => {
public handleGetControllerExtensionData = async (
req: Request,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const params = req.params as { controllerName: string };
const controllerName = sanitize(params.controllerName);
Expand Down Expand Up @@ -219,7 +223,7 @@ export default class RoutesHandler {
* @param res Response
* @param next Next Function
*/
public handleWriteControllerExt = async (req: Request, res: Response, next: NextFunction) => {
public handleWriteControllerExt = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const data = req.body as WriteControllerBody;

Expand Down Expand Up @@ -249,7 +253,7 @@ export default class RoutesHandler {
return;
}

generateControllerFile(rootPath, filePath, name);
await generateControllerFile(rootPath, filePath, name);

const message = 'Controller extension created!';
res.status(HttpStatusCodes.CREATED).send(message);
Expand All @@ -269,7 +273,11 @@ export default class RoutesHandler {
* @param res Response
* @param next Next Function
*/
public handleGetAllAnnotationFilesMappedByDataSource = async (_req: Request, res: Response, next: NextFunction) => {
public handleGetAllAnnotationFilesMappedByDataSource = async (
_req: Request,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const isRunningInBAS = isAppStudio();

Expand Down Expand Up @@ -344,7 +352,7 @@ export default class RoutesHandler {
private async getManifestService(): Promise<ManifestService> {
const project = this.util.getProject();
const basePath = project.getRootPath();
const variant = getVariant(basePath);
const variant = await getVariant(basePath);
const { target, ignoreCertErrors = false } = await getAdpConfig(
basePath,
path.join(basePath, FileName.Ui5Yaml)
Expand All @@ -365,8 +373,8 @@ export default class RoutesHandler {
* @param {string} name - The name of the controller extension (used in TypeScript templates).
* @throws {Error} Throws an error if rendering the template fails.
*/
function generateControllerFile(rootPath: string, filePath: string, name: string): void {
const id = getVariant(rootPath)?.id;
async function generateControllerFile(rootPath: string, filePath: string, name: string): Promise<void> {
const id = (await getVariant(rootPath))?.id;
const isTsSupported = isTypescriptSupported(rootPath);
const tmplFileName = isTsSupported ? TemplateFileName.TSController : TemplateFileName.Controller;
const tmplPath = path.join(__dirname, '../../templates/rta', tmplFileName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import type { ListQuestion, FileBrowserQuestion, YUIQuestion } from '@sap-ux/inq
import type { ManifestNamespace } from '@sap-ux/project-access';
import { AnnotationFileSelectType, type AddAnnotationsAnswers } from '../../types';
import { t } from '../../i18n';
import { filterDataSourcesByType } from '@sap-ux/project-access';
import { filterDataSourcesByType, getWebappPath, DirName } from '@sap-ux/project-access';
import { existsSync } from 'fs';
import { validateEmptyString } from '@sap-ux/project-input-validator';
import { join, isAbsolute, sep } from 'path';
import { join, isAbsolute, basename } from 'path';

/**
* Gets the prompts for adding annotations to OData service.
Expand Down Expand Up @@ -60,7 +60,7 @@ export function getPrompts(
default: '',
when: (answers: AddAnnotationsAnswers) =>
answers.id !== '' && answers.fileSelectOption === AnnotationFileSelectType.ExistingFile,
validate: (value) => {
validate: async (value: string) => {
const validationResult = validateEmptyString(value);
if (typeof validationResult === 'string') {
return validationResult;
Expand All @@ -71,8 +71,11 @@ export function getPrompts(
return t('validators.fileDoesNotExist');
}

const fileName = filePath.split(sep).pop();
if (existsSync(join(basePath, 'webapp', 'changes', 'annotations', fileName))) {
if (
existsSync(
join(await getWebappPath(basePath), DirName.Changes, DirName.Annotations, basename(filePath))
)
) {
return t('validators.annotationFileAlreadyExists');
}

Expand Down
4 changes: 2 additions & 2 deletions packages/adp-tooling/src/writer/inbound-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function generateInboundConfig(
fs = create(createStorage());
}

const variant = getVariant(basePath, fs);
const variant = await getVariant(basePath, fs);

if (!config?.inboundId) {
config.addInboundId = true;
Expand All @@ -34,7 +34,7 @@ export async function generateInboundConfig(

enhanceInboundConfig(config, variant.id, variant.content as Content[]);

updateVariant(basePath, variant, fs);
await updateVariant(basePath, variant, fs);
await updateI18n(basePath, variant.id, config, fs);

return fs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ describe('ManifestService', () => {
describe('initMergedManifest', () => {
it('should initialize and fetch the merged manifest', async () => {
const variant = { id: 'descriptorVariantId', reference: 'referenceAppId' };
(getWebappFiles as jest.MockedFunction<typeof getWebappFiles>).mockReturnValue([
{ relativePath: 'path', content: 'content' }
]);
(getWebappFiles as jest.MockedFunction<typeof getWebappFiles>).mockReturnValue(
Promise.resolve([{ relativePath: 'path', content: 'content' }])
);
manifestService = await ManifestService.initMergedManifest(
provider,
'basePath',
Expand Down
Loading