@sap-ux/adp-tooling 0.2.5 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -5
- package/dist/preview/adp-preview.d.ts +22 -5
- package/dist/preview/adp-preview.js +21 -1
- package/dist/preview/routes-handler.d.ts +37 -0
- package/dist/preview/routes-handler.js +134 -0
- package/dist/types.d.ts +36 -0
- package/dist/writer/index.js +1 -1
- package/package.json +4 -3
- package/templates/rta/fragment.xml +4 -0
- /package/templates/{gitignore.tmpl → project/gitignore.tmpl} +0 -0
- /package/templates/{package.json → project/package.json} +0 -0
- /package/templates/{ui5.yaml → project/ui5.yaml} +0 -0
- /package/templates/{webapp → project/webapp}/i18n/i18n.properties +0 -0
- /package/templates/{webapp → project/webapp}/manifest.appdescr_variant +0 -0
package/README.md
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
# `@sap-ux/adp-tooling`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A module containing different tooling modules helpful when working with SAP UI5 adaptation projects.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Submodules
|
|
6
|
+
|
|
7
|
+
### preview
|
|
6
8
|
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.`.
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
### writer
|
|
9
11
|
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.
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
The submodule contains functionality required in different scenarios, e.g. prompting for generation or when initializing the preview.
|
|
13
|
+
### base
|
|
14
|
+
The submodule contains functionality required in different scenarios, e.g. prompting for generation or when initializing the preview.
|
|
15
|
+
|
|
16
|
+
## Templates
|
|
17
|
+
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.
|
|
@@ -1,20 +1,30 @@
|
|
|
1
|
-
import type { ToolsLogger } from '@sap-ux/logger';
|
|
2
|
-
import type { AdpPreviewConfig, DescriptorVariant } from '../types';
|
|
3
|
-
import type { NextFunction, Request, Response } from 'express';
|
|
4
|
-
import type { MergedAppDescriptor } from '@sap-ux/axios-extension';
|
|
5
1
|
import type { ReaderCollection } from '@ui5/fs';
|
|
2
|
+
import type { MiddlewareUtils } from '@ui5/server';
|
|
3
|
+
import type { NextFunction, Request, Response, Router } from 'express';
|
|
4
|
+
import type { ToolsLogger } from '@sap-ux/logger';
|
|
6
5
|
import type { UI5FlexLayer } from '@sap-ux/project-access';
|
|
6
|
+
import type { MergedAppDescriptor } from '@sap-ux/axios-extension';
|
|
7
|
+
import type { AdpPreviewConfig, DescriptorVariant } from '../types';
|
|
8
|
+
export declare const enum ApiRoutes {
|
|
9
|
+
FRAGMENT = "/adp/api/fragment",
|
|
10
|
+
CONTROLLER = "/adp/api/controller"
|
|
11
|
+
}
|
|
7
12
|
/**
|
|
8
13
|
* Instance of an adaptation project handling requests and data transformation.
|
|
9
14
|
*/
|
|
10
15
|
export declare class AdpPreview {
|
|
11
16
|
private readonly config;
|
|
12
17
|
private readonly project;
|
|
18
|
+
private readonly util;
|
|
13
19
|
private readonly logger;
|
|
14
20
|
/**
|
|
15
21
|
* Merged descriptor variant with reference app manifest
|
|
16
22
|
*/
|
|
17
23
|
private mergedDescriptor;
|
|
24
|
+
/**
|
|
25
|
+
* Routes handler class to handle API requests
|
|
26
|
+
*/
|
|
27
|
+
private routesHandler;
|
|
18
28
|
/**
|
|
19
29
|
* @returns merged manifest.
|
|
20
30
|
*/
|
|
@@ -30,9 +40,10 @@ export declare class AdpPreview {
|
|
|
30
40
|
*
|
|
31
41
|
* @param config adp config
|
|
32
42
|
* @param project reference to the root of the project
|
|
43
|
+
* @param util middleware utilities provided by the UI5 CLI
|
|
33
44
|
* @param logger logger instance
|
|
34
45
|
*/
|
|
35
|
-
constructor(config: AdpPreviewConfig, project: ReaderCollection, logger: ToolsLogger);
|
|
46
|
+
constructor(config: AdpPreviewConfig, project: ReaderCollection, util: MiddlewareUtils, logger: ToolsLogger);
|
|
36
47
|
/**
|
|
37
48
|
* Fetch all required configurations from the backend and initialize all configurations.
|
|
38
49
|
*
|
|
@@ -48,5 +59,11 @@ export declare class AdpPreview {
|
|
|
48
59
|
* @param next next middleware that is to be called if the request cannot be handled
|
|
49
60
|
*/
|
|
50
61
|
proxy(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Add additional APIs to the router that are required for adaptation projects only.
|
|
64
|
+
*
|
|
65
|
+
* @param router router that is to be enhanced with the API
|
|
66
|
+
*/
|
|
67
|
+
addApis(router: Router): void;
|
|
51
68
|
}
|
|
52
69
|
//# sourceMappingURL=adp-preview.d.ts.map
|
|
@@ -15,10 +15,15 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
|
15
15
|
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
16
16
|
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
17
17
|
};
|
|
18
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
+
};
|
|
18
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
22
|
exports.AdpPreview = void 0;
|
|
23
|
+
const express_1 = __importDefault(require("express"));
|
|
20
24
|
const yazl_1 = require("yazl");
|
|
21
25
|
const system_access_1 = require("@sap-ux/system-access");
|
|
26
|
+
const routes_handler_1 = __importDefault(require("./routes-handler"));
|
|
22
27
|
/**
|
|
23
28
|
* Create a buffer based on the given zip file object.
|
|
24
29
|
*
|
|
@@ -97,12 +102,15 @@ class AdpPreview {
|
|
|
97
102
|
*
|
|
98
103
|
* @param config adp config
|
|
99
104
|
* @param project reference to the root of the project
|
|
105
|
+
* @param util middleware utilities provided by the UI5 CLI
|
|
100
106
|
* @param logger logger instance
|
|
101
107
|
*/
|
|
102
|
-
constructor(config, project, logger) {
|
|
108
|
+
constructor(config, project, util, logger) {
|
|
103
109
|
this.config = config;
|
|
104
110
|
this.project = project;
|
|
111
|
+
this.util = util;
|
|
105
112
|
this.logger = logger;
|
|
113
|
+
this.routesHandler = new routes_handler_1.default(project, util, logger);
|
|
106
114
|
}
|
|
107
115
|
/**
|
|
108
116
|
* Fetch all required configurations from the backend and initialize all configurations.
|
|
@@ -153,6 +161,18 @@ class AdpPreview {
|
|
|
153
161
|
}
|
|
154
162
|
});
|
|
155
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Add additional APIs to the router that are required for adaptation projects only.
|
|
166
|
+
*
|
|
167
|
+
* @param router router that is to be enhanced with the API
|
|
168
|
+
*/
|
|
169
|
+
addApis(router) {
|
|
170
|
+
/**
|
|
171
|
+
* FRAGMENT Routes
|
|
172
|
+
*/
|
|
173
|
+
router.get("/adp/api/fragment" /* ApiRoutes.FRAGMENT */, this.routesHandler.handleReadAllFragments);
|
|
174
|
+
router.post("/adp/api/fragment" /* ApiRoutes.FRAGMENT */, express_1.default.json(), this.routesHandler.handleWriteFragment);
|
|
175
|
+
}
|
|
156
176
|
}
|
|
157
177
|
exports.AdpPreview = AdpPreview;
|
|
158
178
|
//# sourceMappingURL=adp-preview.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ReaderCollection } from '@ui5/fs';
|
|
2
|
+
import type { ToolsLogger } from '@sap-ux/logger';
|
|
3
|
+
import type { MiddlewareUtils } from '@ui5/server';
|
|
4
|
+
import type { NextFunction, Request, Response } from 'express';
|
|
5
|
+
/**
|
|
6
|
+
* @description Handles API Routes
|
|
7
|
+
*/
|
|
8
|
+
export default class RoutesHandler {
|
|
9
|
+
private readonly project;
|
|
10
|
+
private readonly util;
|
|
11
|
+
private readonly logger;
|
|
12
|
+
/**
|
|
13
|
+
* Constructor taking project as input.
|
|
14
|
+
*
|
|
15
|
+
* @param project Reference to the root of the project
|
|
16
|
+
* @param util middleware utilities provided by the UI5 CLI
|
|
17
|
+
* @param logger Logger instance
|
|
18
|
+
*/
|
|
19
|
+
constructor(project: ReaderCollection, util: MiddlewareUtils, logger: ToolsLogger);
|
|
20
|
+
/**
|
|
21
|
+
* Handler for reading all fragment files from the workspace.
|
|
22
|
+
*
|
|
23
|
+
* @param _ Request
|
|
24
|
+
* @param res Response
|
|
25
|
+
* @param next Next Function
|
|
26
|
+
*/
|
|
27
|
+
handleReadAllFragments: (_: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Handler for writing a fragment file to the workspace.
|
|
30
|
+
*
|
|
31
|
+
* @param req Request
|
|
32
|
+
* @param res Response
|
|
33
|
+
* @param next Next Function
|
|
34
|
+
*/
|
|
35
|
+
handleWriteFragment: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=routes-handler.d.ts.map
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const sanitize_filename_1 = __importDefault(require("sanitize-filename"));
|
|
41
|
+
/**
|
|
42
|
+
* @description Handles API Routes
|
|
43
|
+
*/
|
|
44
|
+
class RoutesHandler {
|
|
45
|
+
/**
|
|
46
|
+
* Constructor taking project as input.
|
|
47
|
+
*
|
|
48
|
+
* @param project Reference to the root of the project
|
|
49
|
+
* @param util middleware utilities provided by the UI5 CLI
|
|
50
|
+
* @param logger Logger instance
|
|
51
|
+
*/
|
|
52
|
+
constructor(project, util, logger) {
|
|
53
|
+
this.project = project;
|
|
54
|
+
this.util = util;
|
|
55
|
+
this.logger = logger;
|
|
56
|
+
/**
|
|
57
|
+
* Handler for reading all fragment files from the workspace.
|
|
58
|
+
*
|
|
59
|
+
* @param _ Request
|
|
60
|
+
* @param res Response
|
|
61
|
+
* @param next Next Function
|
|
62
|
+
*/
|
|
63
|
+
this.handleReadAllFragments = (_, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
try {
|
|
65
|
+
const files = yield this.project.byGlob('/**/changes/**/*.fragment.xml');
|
|
66
|
+
if (!files || files.length === 0) {
|
|
67
|
+
res.status(200 /* HttpStatusCodes.OK */)
|
|
68
|
+
.contentType('application/json')
|
|
69
|
+
.send({ fragments: [], message: `No fragments found in the project workspace.` });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const fragments = files.map((f) => ({
|
|
73
|
+
fragmentName: f.getName()
|
|
74
|
+
}));
|
|
75
|
+
res.status(200 /* HttpStatusCodes.OK */)
|
|
76
|
+
.contentType('application/json')
|
|
77
|
+
.send({
|
|
78
|
+
fragments,
|
|
79
|
+
message: `${fragments.length} fragments found in the project workspace.`
|
|
80
|
+
});
|
|
81
|
+
this.logger.debug(`Read fragments ${JSON.stringify(fragments)}`);
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
this.logger.error(e.message);
|
|
85
|
+
res.status(500 /* HttpStatusCodes.INTERNAL_SERVER_ERROR */).send({ message: e.message });
|
|
86
|
+
next(e);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* Handler for writing a fragment file to the workspace.
|
|
91
|
+
*
|
|
92
|
+
* @param req Request
|
|
93
|
+
* @param res Response
|
|
94
|
+
* @param next Next Function
|
|
95
|
+
*/
|
|
96
|
+
this.handleWriteFragment = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
try {
|
|
98
|
+
const data = req.body;
|
|
99
|
+
const fragmentName = (0, sanitize_filename_1.default)(data.fragmentName);
|
|
100
|
+
const sourcePath = this.util.getProject().getSourcePath();
|
|
101
|
+
if (fragmentName) {
|
|
102
|
+
const fullPath = path.join(sourcePath, "changes" /* FolderNames.Changes */, "fragments" /* FolderNames.Fragments */);
|
|
103
|
+
const filePath = path.join(fullPath, `${fragmentName}.fragment.xml`);
|
|
104
|
+
if (!fs.existsSync(fullPath)) {
|
|
105
|
+
fs.mkdirSync(fullPath);
|
|
106
|
+
}
|
|
107
|
+
if (fs.existsSync(filePath)) {
|
|
108
|
+
res.status(409 /* HttpStatusCodes.CONFLICT */).send(`Fragment with name "${fragmentName}" already exists`);
|
|
109
|
+
this.logger.debug(`XML Fragment with name "${fragmentName}" was created`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Copy the template XML Fragment to the project's workspace
|
|
113
|
+
const fragmentTemplatePath = path.join(__dirname, '../../templates/rta', "fragment.xml" /* TemplateFileName.Fragment */);
|
|
114
|
+
fs.copyFileSync(fragmentTemplatePath, filePath);
|
|
115
|
+
const message = 'XML Fragment created';
|
|
116
|
+
res.status(201 /* HttpStatusCodes.CREATED */).send(message);
|
|
117
|
+
this.logger.debug(`XML Fragment with name "${fragmentName}" was created`);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
res.status(400 /* HttpStatusCodes.BAD_REQUEST */).send('Fragment name was not provided!');
|
|
121
|
+
this.logger.debug('Bad request. Fragment name was not provided!');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
const sanitizedMsg = (0, sanitize_filename_1.default)(e.message);
|
|
126
|
+
this.logger.error(sanitizedMsg);
|
|
127
|
+
res.status(500 /* HttpStatusCodes.INTERNAL_SERVER_ERROR */).send(sanitizedMsg);
|
|
128
|
+
next(e);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
exports.default = RoutesHandler;
|
|
134
|
+
//# sourceMappingURL=routes-handler.js.map
|
package/dist/types.d.ts
CHANGED
|
@@ -34,5 +34,41 @@ export interface AdpWriterConfig {
|
|
|
34
34
|
description?: string;
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
+
export interface ManifestAppdescr {
|
|
38
|
+
fileName: string;
|
|
39
|
+
layer: string;
|
|
40
|
+
fileType: string;
|
|
41
|
+
reference: string;
|
|
42
|
+
id: string;
|
|
43
|
+
namespace: string;
|
|
44
|
+
version: string;
|
|
45
|
+
content: Content[];
|
|
46
|
+
}
|
|
47
|
+
export interface Content {
|
|
48
|
+
changeType: string;
|
|
49
|
+
content: object;
|
|
50
|
+
texts?: object;
|
|
51
|
+
}
|
|
52
|
+
export declare const enum FolderNames {
|
|
53
|
+
Changes = "changes",
|
|
54
|
+
Fragments = "fragments"
|
|
55
|
+
}
|
|
56
|
+
export declare const enum TemplateFileName {
|
|
57
|
+
Fragment = "fragment.xml"
|
|
58
|
+
}
|
|
59
|
+
export declare const enum HttpStatusCodes {
|
|
60
|
+
OK = 200,
|
|
61
|
+
CREATED = 201,
|
|
62
|
+
NO_CONTENT = 204,
|
|
63
|
+
BAD_REQUEST = 400,
|
|
64
|
+
UNAUTHORIZED = 401,
|
|
65
|
+
FORBIDDEN = 403,
|
|
66
|
+
NOT_FOUND = 404,
|
|
67
|
+
METHOD_NOT_ALLOWED = 405,
|
|
68
|
+
CONFLICT = 409,
|
|
69
|
+
INTERNAL_SERVER_ERROR = 500,
|
|
70
|
+
NOT_IMPLEMETED = 501,
|
|
71
|
+
SERVICE_UNAVAILABLE = 503
|
|
72
|
+
}
|
|
37
73
|
export {};
|
|
38
74
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/writer/index.js
CHANGED
|
@@ -48,7 +48,7 @@ function generate(basePath, config, fs) {
|
|
|
48
48
|
if (!fs) {
|
|
49
49
|
fs = (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
|
|
50
50
|
}
|
|
51
|
-
const tmplPath = (0, path_1.join)(__dirname, '../../templates');
|
|
51
|
+
const tmplPath = (0, path_1.join)(__dirname, '../../templates/project');
|
|
52
52
|
const fullConfig = setDefaults(config);
|
|
53
53
|
fs.copyTpl((0, path_1.join)(tmplPath, '**/*.*'), (0, path_1.join)(basePath), fullConfig, undefined, {
|
|
54
54
|
globOptions: { dot: true },
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"bugs": {
|
|
10
10
|
"url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Aadp-tooling"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.3.1",
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"author": "@SAP/ux-tools-team",
|
|
15
15
|
"main": "dist/index.js",
|
|
@@ -23,14 +23,15 @@
|
|
|
23
23
|
"!dist/**/*.map"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
+
"sanitize-filename": "1.6.3",
|
|
26
27
|
"ejs": "3.1.9",
|
|
27
28
|
"mem-fs": "2.1.0",
|
|
28
29
|
"mem-fs-editor": "9.4.0",
|
|
29
30
|
"prompts": "2.4.2",
|
|
30
31
|
"yazl": "2.5.1",
|
|
31
|
-
"@sap-ux/axios-extension": "1.4.
|
|
32
|
+
"@sap-ux/axios-extension": "1.4.8",
|
|
32
33
|
"@sap-ux/logger": "0.3.8",
|
|
33
|
-
"@sap-ux/system-access": "0.2.
|
|
34
|
+
"@sap-ux/system-access": "0.2.8",
|
|
34
35
|
"@sap-ux/ui5-config": "0.19.3"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|