@sap-ux/adp-tooling 0.3.4 → 0.4.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.
@@ -167,11 +167,10 @@ class AdpPreview {
167
167
  * @param router router that is to be enhanced with the API
168
168
  */
169
169
  addApis(router) {
170
- /**
171
- * FRAGMENT Routes
172
- */
173
170
  router.get("/adp/api/fragment" /* ApiRoutes.FRAGMENT */, this.routesHandler.handleReadAllFragments);
174
171
  router.post("/adp/api/fragment" /* ApiRoutes.FRAGMENT */, express_1.default.json(), this.routesHandler.handleWriteFragment);
172
+ router.get("/adp/api/controller" /* ApiRoutes.CONTROLLER */, this.routesHandler.handleReadAllControllers);
173
+ router.post("/adp/api/controller" /* ApiRoutes.CONTROLLER */, express_1.default.json(), this.routesHandler.handleWriteControllerExt);
175
174
  }
176
175
  }
177
176
  exports.AdpPreview = AdpPreview;
@@ -17,6 +17,30 @@ export default class RoutesHandler {
17
17
  * @param logger Logger instance
18
18
  */
19
19
  constructor(project: ReaderCollection, util: MiddlewareUtils, logger: ToolsLogger);
20
+ /**
21
+ * Reads files from workspace by given search pattern.
22
+ *
23
+ * @param pattern Search pattern
24
+ * @returns Array of files
25
+ */
26
+ private readAllFilesByGlob;
27
+ /**
28
+ * Sends response with data to the client.
29
+ *
30
+ * @param res Response
31
+ * @param data Data that is sent to the client
32
+ * @param contentType Content type, defaults to json
33
+ */
34
+ private sendFilesResponse;
35
+ /**
36
+ * Sanitizes and handles error messages.
37
+ *
38
+ * @param res Response
39
+ * @param next Next function
40
+ * @param e Error
41
+ * @param e.message Error message
42
+ */
43
+ private handleErrorMessage;
20
44
  /**
21
45
  * Handler for reading all fragment files from the workspace.
22
46
  *
@@ -33,5 +57,21 @@ export default class RoutesHandler {
33
57
  * @param next Next Function
34
58
  */
35
59
  handleWriteFragment: (req: Request, res: Response, next: NextFunction) => Promise<void>;
60
+ /**
61
+ * Handler for reading all controller extension files from the workspace.
62
+ *
63
+ * @param _ Request
64
+ * @param res Response
65
+ * @param next Next Function
66
+ */
67
+ handleReadAllControllers: (_: Request, res: Response, next: NextFunction) => Promise<void>;
68
+ /**
69
+ * Handler for writing a controller extension file to the workspace.
70
+ *
71
+ * @param req Request
72
+ * @param res Response
73
+ * @param next Next Function
74
+ */
75
+ handleWriteControllerExt: (req: Request, res: Response, next: NextFunction) => Promise<void>;
36
76
  }
37
77
  //# sourceMappingURL=routes-handler.d.ts.map
@@ -38,6 +38,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
38
38
  const fs = __importStar(require("fs"));
39
39
  const path = __importStar(require("path"));
40
40
  const sanitize_filename_1 = __importDefault(require("sanitize-filename"));
41
+ const ejs_1 = require("ejs");
41
42
  /**
42
43
  * @description Handles API Routes
43
44
  */
@@ -62,28 +63,18 @@ class RoutesHandler {
62
63
  */
63
64
  this.handleReadAllFragments = (_, res, next) => __awaiter(this, void 0, void 0, function* () {
64
65
  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) => ({
66
+ const files = yield this.readAllFilesByGlob('/**/changes/fragments/*.fragment.xml');
67
+ const fileNames = files.map((f) => ({
73
68
  fragmentName: f.getName()
74
69
  }));
75
- res.status(200 /* HttpStatusCodes.OK */)
76
- .contentType('application/json')
77
- .send({
78
- fragments,
79
- message: `${fragments.length} fragments found in the project workspace.`
70
+ this.sendFilesResponse(res, {
71
+ fragments: fileNames,
72
+ message: `${fileNames.length} fragments found in the project workspace.`
80
73
  });
81
- this.logger.debug(`Read fragments ${JSON.stringify(fragments)}`);
74
+ this.logger.debug(`Read fragments ${JSON.stringify(fileNames)}`);
82
75
  }
83
76
  catch (e) {
84
- this.logger.error(e.message);
85
- res.status(500 /* HttpStatusCodes.INTERNAL_SERVER_ERROR */).send({ message: e.message });
86
- next(e);
77
+ this.handleErrorMessage(res, next, e);
87
78
  }
88
79
  });
89
80
  /**
@@ -98,28 +89,97 @@ class RoutesHandler {
98
89
  const data = req.body;
99
90
  const fragmentName = (0, sanitize_filename_1.default)(data.fragmentName);
100
91
  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 {
92
+ if (!fragmentName) {
120
93
  res.status(400 /* HttpStatusCodes.BAD_REQUEST */).send('Fragment name was not provided!');
121
94
  this.logger.debug('Bad request. Fragment name was not provided!');
95
+ return;
96
+ }
97
+ const fullPath = path.join(sourcePath, "changes" /* FolderNames.Changes */, "fragments" /* FolderNames.Fragments */);
98
+ const filePath = path.join(fullPath, `${fragmentName}.fragment.xml`);
99
+ if (!fs.existsSync(fullPath)) {
100
+ fs.mkdirSync(fullPath, { recursive: true });
101
+ }
102
+ if (fs.existsSync(filePath)) {
103
+ res.status(409 /* HttpStatusCodes.CONFLICT */).send(`Fragment with name "${fragmentName}" already exists`);
104
+ this.logger.debug(`XML Fragment with name "${fragmentName}" was created`);
105
+ return;
106
+ }
107
+ // Copy the template XML Fragment to the project's workspace
108
+ const fragmentTemplatePath = path.join(__dirname, '../../templates/rta', "fragment.xml" /* TemplateFileName.Fragment */);
109
+ fs.copyFileSync(fragmentTemplatePath, filePath);
110
+ const message = 'XML Fragment created';
111
+ res.status(201 /* HttpStatusCodes.CREATED */).send(message);
112
+ this.logger.debug(`XML Fragment with name "${fragmentName}" was created`);
113
+ }
114
+ catch (e) {
115
+ const sanitizedMsg = (0, sanitize_filename_1.default)(e.message);
116
+ this.logger.error(sanitizedMsg);
117
+ res.status(500 /* HttpStatusCodes.INTERNAL_SERVER_ERROR */).send(sanitizedMsg);
118
+ next(e);
119
+ }
120
+ });
121
+ /**
122
+ * Handler for reading all controller extension files from the workspace.
123
+ *
124
+ * @param _ Request
125
+ * @param res Response
126
+ * @param next Next Function
127
+ */
128
+ this.handleReadAllControllers = (_, res, next) => __awaiter(this, void 0, void 0, function* () {
129
+ try {
130
+ const files = yield this.readAllFilesByGlob('/**/changes/coding/*.js');
131
+ const fileNames = files.map((f) => ({
132
+ controllerName: f.getName()
133
+ }));
134
+ this.sendFilesResponse(res, {
135
+ controllers: fileNames,
136
+ message: `${fileNames.length} controllers found in the project workspace.`
137
+ });
138
+ this.logger.debug(`Read controllers ${JSON.stringify(fileNames)}`);
139
+ }
140
+ catch (e) {
141
+ this.handleErrorMessage(res, next, e);
142
+ }
143
+ });
144
+ /**
145
+ * Handler for writing a controller extension file to the workspace.
146
+ *
147
+ * @param req Request
148
+ * @param res Response
149
+ * @param next Next Function
150
+ */
151
+ this.handleWriteControllerExt = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
152
+ try {
153
+ const data = req.body;
154
+ const controllerExtName = (0, sanitize_filename_1.default)(data.controllerName);
155
+ const projectId = data.projectId;
156
+ const sourcePath = this.util.getProject().getSourcePath();
157
+ if (!controllerExtName) {
158
+ res.status(400 /* HttpStatusCodes.BAD_REQUEST */).send('Controller extension name was not provided!');
159
+ this.logger.debug('Bad request. Controller extension name was not provided!');
160
+ return;
161
+ }
162
+ const fullPath = path.join(sourcePath, "changes" /* FolderNames.Changes */, "coding" /* FolderNames.Coding */);
163
+ const filePath = path.join(fullPath, `${controllerExtName}.js`);
164
+ if (!fs.existsSync(fullPath)) {
165
+ fs.mkdirSync(fullPath, { recursive: true });
166
+ }
167
+ if (fs.existsSync(filePath)) {
168
+ res.status(409 /* HttpStatusCodes.CONFLICT */).send(`Controller extension with name "${controllerExtName}" already exists`);
169
+ this.logger.debug(`Controller extension with name "${controllerExtName}" already exists`);
170
+ return;
122
171
  }
172
+ const controllerExtPath = `${projectId}.${controllerExtName}`;
173
+ const controllerTemplateFilePath = path.join(__dirname, '../../templates/rta', "controller.ejs" /* TemplateFileName.Controller */);
174
+ (0, ejs_1.renderFile)(controllerTemplateFilePath, { controllerExtPath }, {}, (err, str) => {
175
+ if (err) {
176
+ throw new Error('Error rendering template: ' + err.message);
177
+ }
178
+ fs.writeFileSync(filePath, str, { encoding: 'utf8' });
179
+ });
180
+ const message = 'Controller extension created!';
181
+ res.status(201 /* HttpStatusCodes.CREATED */).send(message);
182
+ this.logger.debug(`Controller extension with name "${controllerExtName}" was created`);
123
183
  }
124
184
  catch (e) {
125
185
  const sanitizedMsg = (0, sanitize_filename_1.default)(e.message);
@@ -129,6 +189,41 @@ class RoutesHandler {
129
189
  }
130
190
  });
131
191
  }
192
+ /**
193
+ * Reads files from workspace by given search pattern.
194
+ *
195
+ * @param pattern Search pattern
196
+ * @returns Array of files
197
+ */
198
+ readAllFilesByGlob(pattern) {
199
+ return __awaiter(this, void 0, void 0, function* () {
200
+ return this.project.byGlob(pattern);
201
+ });
202
+ }
203
+ /**
204
+ * Sends response with data to the client.
205
+ *
206
+ * @param res Response
207
+ * @param data Data that is sent to the client
208
+ * @param contentType Content type, defaults to json
209
+ */
210
+ sendFilesResponse(res, data, contentType = 'application/json') {
211
+ res.status(200 /* HttpStatusCodes.OK */).contentType(contentType).send(data);
212
+ }
213
+ /**
214
+ * Sanitizes and handles error messages.
215
+ *
216
+ * @param res Response
217
+ * @param next Next function
218
+ * @param e Error
219
+ * @param e.message Error message
220
+ */
221
+ handleErrorMessage(res, next, e) {
222
+ const sanitizedMsg = (0, sanitize_filename_1.default)(e.message);
223
+ this.logger.error(sanitizedMsg);
224
+ res.status(500 /* HttpStatusCodes.INTERNAL_SERVER_ERROR */).send({ message: sanitizedMsg });
225
+ next(e);
226
+ }
132
227
  }
133
228
  exports.default = RoutesHandler;
134
229
  //# sourceMappingURL=routes-handler.js.map
package/dist/types.d.ts CHANGED
@@ -51,10 +51,12 @@ export interface Content {
51
51
  }
52
52
  export declare const enum FolderNames {
53
53
  Changes = "changes",
54
- Fragments = "fragments"
54
+ Fragments = "fragments",
55
+ Coding = "coding"
55
56
  }
56
57
  export declare const enum TemplateFileName {
57
- Fragment = "fragment.xml"
58
+ Fragment = "fragment.xml",
59
+ Controller = "controller.ejs"
58
60
  }
59
61
  export declare const enum HttpStatusCodes {
60
62
  OK = 200,
@@ -69,7 +69,7 @@ function generate(basePath, config, fs) {
69
69
  rta: {
70
70
  editors: [
71
71
  {
72
- path: 'local/editor.html',
72
+ path: '/local/editor.html',
73
73
  developerMode: true
74
74
  }
75
75
  ]
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.3.4",
12
+ "version": "0.4.1",
13
13
  "license": "Apache-2.0",
14
14
  "author": "@SAP/ux-tools-team",
15
15
  "main": "dist/index.js",
@@ -16,7 +16,7 @@
16
16
  "@ui5/cli": "^3.6.0"
17
17
  },
18
18
  "scripts": {
19
- "build": "ui5 build --clean-dest",
19
+ "build": "ui5 build --exclude-task generateFlexChangesBundle generateComponentPreload --clean-dest",
20
20
  "start": "ui5 serve --open /test/flp.html#app-preview",
21
21
  "editor": "ui5 serve --open /local/editor.html"
22
22
  }
@@ -0,0 +1,80 @@
1
+ sap.ui.define(
2
+ [
3
+ 'sap/ui/core/mvc/ControllerExtension'
4
+ // ,'sap/ui/core/mvc/OverrideExecution'
5
+ ],
6
+ function (
7
+ ControllerExtension
8
+ // ,OverrideExecution
9
+ ) {
10
+ 'use strict';
11
+ return ControllerExtension.extend("<%= controllerExtPath %>", {
12
+ // metadata: {
13
+ // // extension can declare the public methods
14
+ // // in general methods that start with "_" are private
15
+ // methods: {
16
+ // publicMethod: {
17
+ // public: true /*default*/ ,
18
+ // final: false /*default*/ ,
19
+ // overrideExecution: OverrideExecution.Instead /*default*/
20
+ // },
21
+ // finalPublicMethod: {
22
+ // final: true
23
+ // },
24
+ // onMyHook: {
25
+ // public: true /*default*/ ,
26
+ // final: false /*default*/ ,
27
+ // overrideExecution: OverrideExecution.After
28
+ // },
29
+ // couldBePrivate: {
30
+ // public: false
31
+ // }
32
+ // }
33
+ // },
34
+ // // adding a private method, only accessible from this controller extension
35
+ // _privateMethod: function() {},
36
+ // // adding a public method, might be called from or overridden by other controller extensions as well
37
+ // publicMethod: function() {},
38
+ // // adding final public method, might be called from, but not overridden by other controller extensions as well
39
+ // finalPublicMethod: function() {},
40
+ // // adding a hook method, might be called by or overridden from other controller extensions
41
+ // // override these method does not replace the implementation, but executes after the original method
42
+ // onMyHook: function() {},
43
+ // // method public per default, but made private via metadata
44
+ // couldBePrivate: function() {},
45
+ // // this section allows to extend lifecycle hooks or override public methods of the base controller
46
+ // override: {
47
+ // /**
48
+ // * Called when a controller is instantiated and its View controls (if available) are already created.
49
+ // * Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
50
+ // * @memberOf {{controllerExtPath}}
51
+ // */
52
+ // onInit: function() {
53
+ // },
54
+ // /**
55
+ // * Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
56
+ // * (NOT before the first rendering! onInit() is used for that one!).
57
+ // * @memberOf {{controllerExtPath}}
58
+ // */
59
+ // onBeforeRendering: function() {
60
+ // },
61
+ // /**
62
+ // * Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
63
+ // * This hook is the same one that SAPUI5 controls get after being rendered.
64
+ // * @memberOf {{controllerExtPath}}
65
+ // */
66
+ // onAfterRendering: function() {
67
+ // },
68
+ // /**
69
+ // * Called when the Controller is destroyed. Use this one to free resources and finalize activities.
70
+ // * @memberOf {{controllerExtPath}}
71
+ // */
72
+ // onExit: function() {
73
+ // },
74
+ // // override public method of the base controller
75
+ // basePublicMethod: function() {
76
+ // }
77
+ // }
78
+ });
79
+ }
80
+ );