@sap-ux/adp-tooling 0.2.4 → 0.3.0

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 CHANGED
@@ -1,12 +1,17 @@
1
1
  # `@sap-ux/adp-tooling`
2
2
 
3
- Module containing different tooling modules helpful when working with SAP UI5 adaptation projects.
3
+ A module containing different tooling modules helpful when working with SAP UI5 adaptation projects.
4
4
 
5
- ## preview
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
- ## writer
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
- ## base
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
@@ -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.2.4",
12
+ "version": "0.3.0",
13
13
  "license": "Apache-2.0",
14
14
  "author": "@SAP/ux-tools-team",
15
15
  "main": "dist/index.js",
@@ -23,22 +23,23 @@
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.6",
32
- "@sap-ux/logger": "0.3.7",
33
- "@sap-ux/system-access": "0.2.6",
34
- "@sap-ux/ui5-config": "0.19.2"
32
+ "@sap-ux/axios-extension": "1.4.7",
33
+ "@sap-ux/logger": "0.3.8",
34
+ "@sap-ux/system-access": "0.2.7",
35
+ "@sap-ux/ui5-config": "0.19.3"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@types/ejs": "3.1.2",
38
39
  "@types/express": "4.17.17",
39
40
  "@types/mem-fs": "1.1.2",
40
41
  "@types/mem-fs-editor": "7.0.1",
41
- "@types/prompts": "2.0.14",
42
+ "@types/prompts": "2.4.4",
42
43
  "@types/supertest": "2.0.12",
43
44
  "@types/yazl": "2.4.2",
44
45
  "dotenv": "16.3.1",
@@ -46,8 +47,8 @@
46
47
  "nock": "13.2.1",
47
48
  "rimraf": "5.0.1",
48
49
  "supertest": "6.3.3",
49
- "@sap-ux/project-access": "1.13.5",
50
- "@sap-ux/store": "0.3.13"
50
+ "@sap-ux/project-access": "1.13.6",
51
+ "@sap-ux/store": "0.3.14"
51
52
  },
52
53
  "engines": {
53
54
  "pnpm": ">=6.26.1 < 7.0.0 || >=7.1.0",
@@ -0,0 +1,4 @@
1
+ <!-- Use stable and unique IDs!-->
2
+ <core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
3
+ <!-- add your xml here -->
4
+ </core:FragmentDefinition>
File without changes