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

Allow loading RTA plugins for adaptation projects #1166

Closed
wants to merge 68 commits into from
Closed
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
57055d0
initial crude implementation
tobiasqueck Aug 10, 2023
38c06e8
Empty-Commit
tobiasqueck Aug 11, 2023
aeb5974
merge from main
tobiasqueck Aug 11, 2023
155e0b8
typescript support for rta coding
tobiasqueck Aug 11, 2023
4825515
removed odd change
tobiasqueck Aug 11, 2023
e461d8f
removed hardcoded file hosting
tobiasqueck Aug 11, 2023
de1e458
enhanced example to also use a submodule
tobiasqueck Aug 14, 2023
26ad8b0
changing folder and export name
tobiasqueck Aug 14, 2023
57d14bb
enable ui5 types
tobiasqueck Aug 14, 2023
2f13f73
enable ui5 transpiling
tobiasqueck Aug 14, 2023
b187492
fix: script path issue
tobiasqueck Aug 14, 2023
f8f2f01
lock file
tobiasqueck Aug 14, 2023
ce3106d
Merge branch 'main' into feat/1149/enable-enhancements
tobiasqueck Aug 14, 2023
a75c853
config again
tobiasqueck Aug 14, 2023
c49b323
linting
tobiasqueck Aug 14, 2023
c8d8dc8
win issue
tobiasqueck Aug 14, 2023
1aa47e3
fix tests
tobiasqueck Aug 14, 2023
e430098
added info to readme
tobiasqueck Aug 14, 2023
34ef8b1
fix: typo
tobiasqueck Aug 14, 2023
fbb2253
feat: add ADP API;
tobiasqueck Aug 14, 2023
e75b1be
linting errors
tobiasqueck Aug 14, 2023
53c9836
fix: tests
tobiasqueck Aug 14, 2023
4d191ec
added enum example
tobiasqueck Aug 14, 2023
56245da
Linting auto fix commit
github-actions[bot] Aug 14, 2023
ecdb79a
fixed auto-completion in VSCode
tobiasqueck Aug 14, 2023
4bf65f5
Merge branch 'feat/1149/enable-enhancements' of https://github.com/SA…
tobiasqueck Aug 14, 2023
66fe43b
fix
tobiasqueck Aug 14, 2023
2a5e050
fix: tests again
tobiasqueck Aug 14, 2023
ecbf4b7
Merge branch 'main' into feat/1149/enable-enhancements
tobiasqueck Aug 15, 2023
8287c49
removed wrong entry
tobiasqueck Aug 15, 2023
a899267
Merge branch 'feat/1149/enable-enhancements' of https://github.com/SA…
tobiasqueck Aug 15, 2023
2d7481a
enhanced the types module with SAPUI5 types and required enhancements
tobiasqueck Aug 16, 2023
ebc4b05
moved sapui5 types and enhancements into central types module and use…
tobiasqueck Aug 16, 2023
2414eff
Merge branch 'main' into feat/1149/enable-enhancements
tobiasqueck Aug 16, 2023
28b3ebd
Linting auto fix commit
github-actions[bot] Aug 16, 2023
1991c38
fix: build issues
tobiasqueck Aug 16, 2023
52a5b2e
fix the build
tobiasqueck Aug 16, 2023
9ce59c6
Linting auto fix commit
github-actions[bot] Aug 16, 2023
4663ff8
Merge branch 'main' into feat/1149/enable-enhancements
tobiasqueck Aug 16, 2023
0151ebb
fix tell jest to ignore ui5 files
tobiasqueck Aug 16, 2023
908639d
merging type fixes
tobiasqueck Aug 16, 2023
4db5180
Linting auto fix commit
github-actions[bot] Aug 16, 2023
2e958a8
set browserlist to remove polyfills from generated ui5 code
tobiasqueck Aug 17, 2023
b36678e
merge from main
tobiasqueck Aug 17, 2023
e3c003c
merge from main;
tobiasqueck Aug 17, 2023
3496fcb
revert wrong comma
tobiasqueck Aug 17, 2023
42d1619
revert wrong comma
tobiasqueck Aug 17, 2023
a6b8f06
enhanced the readme
tobiasqueck Aug 21, 2023
f18541b
Merge branch 'main' into feat/1149/enable-enhancements
tobiasqueck Aug 21, 2023
9d4a549
chore: added --glob flag to rimraf dist
nikmace Aug 14, 2023
07acb63
refactor: made templates into two folders, fixed paths
nikmace Aug 16, 2023
2963d94
added test for new functionality
tobiasqueck Aug 21, 2023
3bf5642
setup for jest testing of client sources
tobiasqueck Aug 21, 2023
bff0350
turn-off contradicting rule
tobiasqueck Aug 21, 2023
10ea593
Merge branch 'main' into feat/1149/enable-enhancements
tobiasqueck Aug 22, 2023
1f321a2
Merge branch 'main' into feat/1149/enable-enhancements
tobiasqueck Aug 22, 2023
c1efcf9
more specific rule ignore
tobiasqueck Aug 29, 2023
2ba64bb
merge from main
tobiasqueck Aug 29, 2023
2937d00
Merge branch 'main' into feat/1149/enable-enhancements
tobiasqueck Aug 29, 2023
00c9bc1
merge from main
tobiasqueck Aug 30, 2023
c92882d
review feedback: supertest
tobiasqueck Aug 31, 2023
5872397
merge from main
tobiasqueck Aug 31, 2023
c56ee27
forgetful me
tobiasqueck Aug 31, 2023
653b29d
merge from main
tobiasqueck Sep 1, 2023
199ef11
merge from main
tobiasqueck Sep 7, 2023
5c231b7
simplify enablement
tobiasqueck Sep 7, 2023
fea46a9
further cleanup
tobiasqueck Sep 7, 2023
495cec8
fix: tests
tobiasqueck Sep 7, 2023
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
16 changes: 16 additions & 0 deletions packages/adp-tooling/.babelrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"ignore": [
"**/*.d.ts"
],
"presets": [
"@babel/preset-env",
[
"transform-ui5",
{
"overridesToOverride": true
}
],
"@babel/preset-typescript"
],
"sourceMaps": true
}
2 changes: 1 addition & 1 deletion packages/adp-tooling/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
test/fixtures
dist
dist
4 changes: 4 additions & 0 deletions packages/adp-tooling/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ module.exports = {
parserOptions: {
project: './tsconfig.eslint.json',
tsconfigRootDir: __dirname
},
rules: {
// ui5 modules are not available in file system
'import/no-unresolved': ['error', { ignore: ['^sap/'] }]
}
};
21 changes: 16 additions & 5 deletions packages/adp-tooling/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
# `@sap-ux/adp-tooling`

Module containing different tooling modules helpful when working with SAP UI5 adaptation projects.
A module containing different tooling modules helpful when working with SAP UI5 adaptation projects.

## preview
## Submodules

### preview
The submodule preview contains functionality allowing to preview adaptation projects. It is not a standalone UI5 middleware but designed to be integrated into the `@sap-ux/preview-middleware.`.

## writer
#### preview/client
This is a special module that is transpiled separately to run in the browser as part of the UI5 RTA overlay. Any communication with the middleware middleware (server) code is done via http.

### writer
The submodule writer contains functionality to generate the core project structure of an SAP UI5 adaptation project. It is not a standalone generator but designed to be integrated into `@sap-ux/create` or any kind of yeoman generator.

## base
The submodule contains functionality required in different scenarios, e.g. prompting for generation or when initializing the preview.
### base
The submodule contains functionality required in different scenarios, e.g. prompting for generation or when initializing the preview.

## Development
The standard `src` folder except the subfolder `src/preview/client` is transpiled into the dist folder. Additionally, the sources from `src/preview/client` are transpiled using babel into UI5 compatible client sources that can be used in previews to extend the runtime adaption with additional plugins.

## Templates
The templates folder contains ejs templates to be used for the generation of new adaptation projects as well as to generate artifacts in existing adaptation projects.
14 changes: 13 additions & 1 deletion packages/adp-tooling/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
const config = require('../../jest.base');
module.exports = config;
config.coveragePathIgnorePatterns = ['src/preview/client'];
config.moduleNameMapper = {
'^sap/(.+)$': `<rootDir>/test/__mock__/sap/$1.ts`
};
config.transform = {
'^.+\\.ts$': [
'ts-jest',
{
tsConfig: 'tsconfig.jest.json'
}
]
};
module.exports = config;
9 changes: 7 additions & 2 deletions packages/adp-tooling/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
"author": "@SAP/ux-tools-team",
"main": "dist/index.js",
"scripts": {
"build": "tsc --build",
"build": "pnpm build:server && pnpm build:client",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use npm-run-all -l -p to run these in parallel.

"build:server": "tsc --build",
"build:client": "tsc --noEmit --project src/preview/client/tsconfig.json && babel --extensions .ts ./src/preview/client -d ./dist/preview/client",
"watch": "tsc --watch",
"clean": "rimraf --glob dist test/test-output coverage *.tsbuildinfo",
"format": "prettier --write '**/*.{js,json,ts,yaml,yml}' --ignore-path ../../.prettierignore",
Expand Down Expand Up @@ -46,6 +48,7 @@
"yazl": "2.5.1"
},
"devDependencies": {
"@babel/cli": "7.22.10",
"@sap-ux/project-access": "workspace:*",
"@sap-ux/store": "workspace:*",
"@types/ejs": "3.1.0",
Expand All @@ -55,6 +58,7 @@
"@types/prompts": "2.0.14",
"@types/supertest": "2.0.12",
"@types/yazl": "2.4.2",
"babel-preset-transform-ui5": "7.2.4",
"dotenv": "16.0.0",
"express": "4.18.2",
"nock": "13.2.1",
Expand All @@ -64,5 +68,6 @@
"engines": {
"pnpm": ">=6.26.1 < 7.0.0 || >=7.1.0",
"node": ">= 14.16.0 < 15.0.0 || >=16.1.0 < 17.0.0 || >=18.0.0 < 19.0.0"
}
},
"browserslist": "defaults"
}
36 changes: 34 additions & 2 deletions packages/adp-tooling/src/preview/adp-preview.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { ToolsLogger } from '@sap-ux/logger';
import { ZipFile } from 'yazl';
import type { AdpPreviewConfig, DescriptorVariant } from '../types';
import type { NextFunction, Request, Response } from 'express';
import type { NextFunction, Request, RequestHandler, Response, Router } from 'express';
import type { MergedAppDescriptor } from '@sap-ux/axios-extension';
import type { ReaderCollection } from '@ui5/fs';
import type { UI5FlexLayer } from '@sap-ux/project-access';
import { createAbapServiceProvider } from '@sap-ux/system-access';
import { join } from 'path';

/**
* Create a buffer based on the given zip file object.
Expand Down Expand Up @@ -54,7 +55,8 @@ export class AdpPreview {
get resources() {
if (this.mergedDescriptor) {
const resources = {
[this.mergedDescriptor.name]: this.mergedDescriptor.url
[this.mergedDescriptor.name]: this.mergedDescriptor.url,
[this.extensionScript.namespace]: this.extensionScript.namespace.split('.').join('/')
};
this.mergedDescriptor.asyncHints.libs.forEach((lib) => {
if (lib.url?.url) {
Expand All @@ -67,6 +69,17 @@ export class AdpPreview {
}
}

/**
* @returns an object with all information about the provided RTA extension script.
*/
get extensionScript() {
return {
local: join(__dirname, 'client'),
namespace: 'adp.extension',
module: 'index'
};
}

/**
* Constructor taking the config and a logger as input.
*
Expand Down Expand Up @@ -131,4 +144,23 @@ export class AdpPreview {
}
}
}

/**
* Add additional APIs to the router that are required for adaptation projects only.
*
* @param router router that is to be enhanced with the API
*/
addApis(router: Router): void {
router.get('/adp/api/fragment', (async (_req: Request, res: Response) => {
const files = await this.project.byGlob('/**/changes/**/*.fragment.xml');
try {
const names = files.map((file) => file.getPath());
res.status(200).contentType('application/json').send(JSON.stringify(names));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #1224 Shouldn't we use here also writeHead, write and end?

this.logger.debug(`Read fragments${JSON.stringify(names)}`);
} catch (error) {
this.logger.warn(error.message);
res.status(500);
}
}) as RequestHandler);
}
}
5 changes: 5 additions & 0 deletions packages/adp-tooling/src/preview/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';

export default (_rta: RuntimeAuthoring) => {
// add code to load custom plugins here
};
10 changes: 10 additions & 0 deletions packages/adp-tooling/src/preview/client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../../tsconfig.json",
"include": [".", "../../../../../types/sapui5"],
"compilerOptions": {
"rootDir": ".",
"module": "es6",
"lib": ["ES2020", "dom"],
"allowJs": true
}
}
2 changes: 1 addition & 1 deletion packages/adp-tooling/src/writer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export async function generate(basePath: string, config: AdpWriterConfig, fs?: E
if (!fs) {
fs = create(createStorage());
}
const tmplPath = join(__dirname, '../../templates');
const tmplPath = join(__dirname, '../../templates/project');
const fullConfig = setDefaults(config);

fs.copyTpl(join(tmplPath, '**/*.*'), join(basePath), fullConfig, undefined, {
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to separate writer module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say no as explained at #1166 (comment)

File renamed without changes.
34 changes: 34 additions & 0 deletions packages/adp-tooling/test/unit/preview/adp-preview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ describe('AdaptationProject', () => {
await adp.init(JSON.parse(descriptorVariant));
expect(adp.descriptor).toEqual(mockMergedDescriptor);
expect(adp.resources).toEqual({
'adp.extension': 'adp/extension',
'sap.reuse.lib': '/sap/reuse/lib',
'the.original.app': mockMergedDescriptor.url
});
Expand Down Expand Up @@ -161,4 +162,37 @@ describe('AdaptationProject', () => {
expect(next).toBeCalled();
});
});
describe('addApis', () => {
let server!: SuperTest<Test>;
beforeAll(async () => {
const adp = new AdpPreview(
{
target: {
url: backend
}
},
mockProject as unknown as ReaderCollection,
logger
);

const app = express();
adp.addApis(app);
server = await supertest(app);
});

test('/adp/api/fragment', async () => {
const expectedNames = ['/changes/fragments/my.fragment.xml', '/changes/other/path/other.fragment.xml'];
mockProject.byGlob.mockResolvedValueOnce([
{
getPath: () => expectedNames[0]
},
{
getPath: () => expectedNames[1]
}
]);
const response = await server.get('/adp/api/fragment').expect(200);
const names = JSON.parse(response.text);
expect(names).toEqual(expectedNames);
});
});
});
3 changes: 2 additions & 1 deletion packages/adp-tooling/tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"extends": "./tsconfig.json",
"include": ["src", "test", ".eslintrc.js"]
"include": ["src", "test", ".eslintrc.js"],
"exclude": []
}
9 changes: 9 additions & 0 deletions packages/adp-tooling/tsconfig.jest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"include": [
"../../types/ui5.d.ts",
"../../types/mem-fs-editor.d.ts",
"../../types/sapui5",
"src"
]
}
3 changes: 3 additions & 0 deletions packages/adp-tooling/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"../../types/mem-fs-editor.d.ts",
"src"
],
"exclude": [
"src/preview/client"
],
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"
Expand Down
2 changes: 1 addition & 1 deletion packages/preview-middleware/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"start:fixture": "ui5 serve --config test/fixtures/simple-app/ui5.yaml",
"build": "tsc --build",
"watch": "tsc --watch",
"clean": "rimraf dist test/test-output coverage *.tsbuildinfo",
"clean": "rimraf --glob dist test/test-output coverage *.tsbuildinfo",
"format": "prettier --write '**/*.{js,json,ts,yaml,yml}' --ignore-path ../../.prettierignore",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
Expand Down
2 changes: 2 additions & 0 deletions packages/preview-middleware/src/base/flp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export interface TemplateConfig {
flex?: {
layer: UI5FlexLayer;
developerMode: boolean;
pluginModule?: string;
};
locateReuseLibsScript?: string;
}
Expand Down Expand Up @@ -155,6 +156,7 @@ export class FlpSandbox {
if (this.config.rta?.layer) {
config.flex = {
layer: this.config.rta?.layer,
pluginModule: this.config.rta?.pluginModule,
developerMode: fioriToolsRtaMode === 'forAdaptation'
};
} else {
Expand Down
4 changes: 4 additions & 0 deletions packages/preview-middleware/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export interface FlpConfig {
intent: Intent;
rta?: {
layer?: UI5FlexLayer;
/**
* Optional UI5 module exporting as default a function that adds RTA plugins
*/
pluginModule?: string;
};
/**
* Optional: if set to true then a locate-reuse-libs script will be attached to the html
Expand Down
14 changes: 13 additions & 1 deletion packages/preview-middleware/src/ui5/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { AdpPreviewConfig } from '@sap-ux/adp-tooling';
import type { Config } from '../types';
import { AdpPreview } from '@sap-ux/adp-tooling';
import type { ReaderCollection } from '@ui5/fs';
import { static as serveStatic } from 'express';

/**
* Initialize the preview for an adaptation project.
Expand All @@ -20,9 +21,20 @@ async function initAdp(rootProject: ReaderCollection, config: AdpPreviewConfig,
if (appVariant) {
const adp = new AdpPreview(config, rootProject, logger);
const layer = await adp.init(JSON.parse(await appVariant.getString()));
flp.config.rta = { layer };
flp.config.rta = {
layer,
pluginModule: `${adp.extensionScript.namespace.replace('.', '/')}/${adp.extensionScript.module}`
};

const ns = adp.extensionScript.namespace.split('.');
const path = flp.config.path.split('/');
path.pop();
ns.forEach((segment) => path.push(segment));

await flp.init(adp.descriptor.manifest, adp.descriptor.name, adp.resources);
flp.router.use(adp.descriptor.url, adp.proxy.bind(adp) as RequestHandler);
flp.router.use(path.join('/'), serveStatic(adp.extensionScript.local));
adp.addApis(flp.router);
} else {
throw new Error('ADP configured but no manifest.appdescr_variant found.');
}
Expand Down
4 changes: 2 additions & 2 deletions packages/preview-middleware/templates/flp/sandbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
sap.ushell.Container.getServiceAsync('AppLifeCycle').then((serviceInstance) => {
serviceInstance.attachAppLoaded((event) => {
var oView = event.getParameter('componentInstance');
sap.ui.require(["sap/ui/rta/api/startAdaptation"], async function (startAdaptation) {
sap.ui.require(["sap/ui/rta/api/startAdaptation"<% if (locals.flex?.pluginModule) { %>, "<%- flex.pluginModule %>"<% } %>], async function (startAdaptation<% if (locals.flex?.pluginModule) { %>, loadPlugin<% } %>) {
var options = {
rootControl: oView,
validateAppVersion: false,
Expand All @@ -72,7 +72,7 @@
developerMode: <%- flex.developerMode %>
}
};
await startAdaptation(options);
await startAdaptation(options<% if (locals.flex?.pluginModule) { %>, loadPlugin<% } %>);
});
})
});
Expand Down
Loading