@sap-ux/fe-fpm-writer 0.17.2 → 0.17.4

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.
@@ -77,7 +77,7 @@ function generateCustomAction(basePath, actionConfig, fs) {
77
77
  const config = enhanceConfig(actionConfig, manifestPath, manifest);
78
78
  // Apply event handler
79
79
  if (config.eventHandler) {
80
- config.eventHandler = event_handler_1.applyEventHandlerConfiguration(fs, config, config.eventHandler, false, config.typescript);
80
+ config.eventHandler = event_handler_1.applyEventHandlerConfiguration(fs, config, config.eventHandler, false, config.typescript, event_handler_1.contextParameter);
81
81
  }
82
82
  // enhance manifest with action definition and controller reference
83
83
  const actions = enhanceManifestAndGetActionsElementReference(manifest, config.target);
@@ -13,6 +13,9 @@ export interface FPMConfig {
13
13
  * (Note: if set to false, nothing will be done i.e. FCL is not disabled)
14
14
  */
15
15
  fcl?: boolean;
16
+ /**
17
+ * If set to true then all code snippets are generated in Typescript instead of Javascript.
18
+ */
16
19
  typescript?: boolean;
17
20
  }
18
21
  export declare const MIN_VERSION = "1.94.0";
package/dist/app/index.js CHANGED
@@ -7,6 +7,7 @@ const path_1 = require("path");
7
7
  const semver_1 = require("semver");
8
8
  const defaults_1 = require("../common/defaults");
9
9
  const templates_1 = require("../templates");
10
+ const utils_1 = require("../common/utils");
10
11
  exports.MIN_VERSION = '1.94.0';
11
12
  /**
12
13
  * Enable the flexible programming model for an application.
@@ -17,7 +18,7 @@ exports.MIN_VERSION = '1.94.0';
17
18
  * @returns {Promise<Editor>} the updated mem-fs editor instance
18
19
  */
19
20
  function enableFPM(basePath, config = {}, fs) {
20
- var _a, _b, _c, _d, _e;
21
+ var _a, _b, _c, _d, _e, _f;
21
22
  if (!fs) {
22
23
  fs = mem_fs_editor_1.create(mem_fs_1.create());
23
24
  }
@@ -49,6 +50,10 @@ function enableFPM(basePath, config = {}, fs) {
49
50
  }
50
51
  });
51
52
  }
53
+ // add type extensions if required
54
+ if (config.typescript) {
55
+ utils_1.addExtensionTypes(basePath, (_f = manifest['sap.ui5']) === null || _f === void 0 ? void 0 : _f.dependencies.minUI5Version, fs);
56
+ }
52
57
  // enable FCL if requested
53
58
  if (config.fcl) {
54
59
  fs.extendJSON(manifestPath, {
@@ -1,14 +1,32 @@
1
1
  import type { Editor } from 'mem-fs-editor';
2
2
  import type { EventHandlerConfiguration, InternalCustomElement } from '../common/types';
3
+ /**
4
+ * Interface to describe the input parameters for the generated event handler function.
5
+ */
6
+ export interface EventHandlerTypescriptParameters {
7
+ name: string;
8
+ description: string;
9
+ importType: string;
10
+ importSource: string;
11
+ }
12
+ /**
13
+ * Default values for the input parameters of newly created event handlers.
14
+ */
15
+ export declare const defaultParameter: EventHandlerTypescriptParameters;
16
+ /**
17
+ * Values for the input parameters of newly created event handlers that are added as manifest actions.
18
+ */
19
+ export declare const contextParameter: EventHandlerTypescriptParameters;
3
20
  /**
4
21
  * Method creates or updates handler js file and update 'settings.eventHandler' entry with namespace path entry to method.
5
22
  *
6
- * @param {Editor} fs - the memfs editor instance
7
- * @param {InternalCustomElement} config - configuration
8
- * @param {EventHandlerConfiguration | true | string} [eventHandler] - eventHandler for creation
9
- * @param {boolean} [controllerSuffix=false] - append controller suffix to new file
10
- * @param {boolean} typescript - create Typescript file instead of Javascript
23
+ * @param fs - the memfs editor instance
24
+ * @param config - configuration
25
+ * @param eventHandler - eventHandler for creation
26
+ * @param controllerSuffix - append controller suffix to new file
27
+ * @param typescript - create Typescript file instead of Javascript
28
+ * @param parameters - parameter configurations for the event handler
11
29
  * @returns {string} full namespace path to method
12
30
  */
13
- export declare function applyEventHandlerConfiguration(fs: Editor, config: Partial<InternalCustomElement>, eventHandler: EventHandlerConfiguration | true | string, controllerSuffix?: boolean, typescript?: boolean): string;
31
+ export declare function applyEventHandlerConfiguration(fs: Editor, config: Partial<InternalCustomElement>, eventHandler: EventHandlerConfiguration | true | string, controllerSuffix?: boolean, typescript?: boolean, parameters?: EventHandlerTypescriptParameters): string;
14
32
  //# sourceMappingURL=event-handler.d.ts.map
@@ -1,20 +1,39 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.applyEventHandlerConfiguration = void 0;
3
+ exports.applyEventHandlerConfiguration = exports.contextParameter = exports.defaultParameter = void 0;
4
4
  const path_1 = require("path");
5
5
  const templates_1 = require("../templates");
6
6
  const utils_1 = require("../common/utils");
7
+ /**
8
+ * Default values for the input parameters of newly created event handlers.
9
+ */
10
+ exports.defaultParameter = {
11
+ name: 'event',
12
+ description: 'the event object provided by the event provider',
13
+ importType: 'UI5Event',
14
+ importSource: 'sap/ui/base/Event'
15
+ };
16
+ /**
17
+ * Values for the input parameters of newly created event handlers that are added as manifest actions.
18
+ */
19
+ exports.contextParameter = {
20
+ name: 'pageContext',
21
+ description: 'the context of the page on which the event was fired',
22
+ importType: 'Context',
23
+ importSource: 'sap/ui/model/odata/v4/Context'
24
+ };
7
25
  /**
8
26
  * Method creates or updates handler js file and update 'settings.eventHandler' entry with namespace path entry to method.
9
27
  *
10
- * @param {Editor} fs - the memfs editor instance
11
- * @param {InternalCustomElement} config - configuration
12
- * @param {EventHandlerConfiguration | true | string} [eventHandler] - eventHandler for creation
13
- * @param {boolean} [controllerSuffix=false] - append controller suffix to new file
14
- * @param {boolean} typescript - create Typescript file instead of Javascript
28
+ * @param fs - the memfs editor instance
29
+ * @param config - configuration
30
+ * @param eventHandler - eventHandler for creation
31
+ * @param controllerSuffix - append controller suffix to new file
32
+ * @param typescript - create Typescript file instead of Javascript
33
+ * @param parameters - parameter configurations for the event handler
15
34
  * @returns {string} full namespace path to method
16
35
  */
17
- function applyEventHandlerConfiguration(fs, config, eventHandler, controllerSuffix = false, typescript) {
36
+ function applyEventHandlerConfiguration(fs, config, eventHandler, controllerSuffix = false, typescript, parameters = exports.defaultParameter) {
18
37
  if (typeof eventHandler === 'string') {
19
38
  // Existing event handler is passed - no need for file creation/update
20
39
  return eventHandler;
@@ -38,7 +57,8 @@ function applyEventHandlerConfiguration(fs, config, eventHandler, controllerSuff
38
57
  const controllerPath = path_1.join(config.path || '', `${fileName}${controllerSuffix ? '.controller' : ''}.${ext}`);
39
58
  if (!fs.exists(controllerPath)) {
40
59
  fs.copyTpl(templates_1.getTemplatePath(`common/EventHandler.${ext}`), controllerPath, {
41
- eventHandlerFnName
60
+ eventHandlerFnName,
61
+ parameters
42
62
  });
43
63
  }
44
64
  else if (insertScript) {
@@ -1,3 +1,4 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  import type { FileContentPosition } from '../common/types';
2
3
  /**
3
4
  * Method inserts passed text into content by char index position.
@@ -21,4 +22,13 @@ export declare function insertTextAtAbsolutePosition(text: string, content: stri
21
22
  * @returns new content with inserted text
22
23
  */
23
24
  export declare function insertTextAtPosition(text: string, content: string, position: FileContentPosition): string;
25
+ /**
26
+ * Adds type extensions for sap.fe types if an older version is used.
27
+ * The types were fixed in 1.108 and downported to 1.102.
28
+ *
29
+ * @param basePath - the base path
30
+ * @param minUI5Version - minimal required UI5 version
31
+ * @param fs - the memfs editor instance
32
+ */
33
+ export declare function addExtensionTypes(basePath: string, minUI5Version: string | undefined, fs: Editor): void;
24
34
  //# sourceMappingURL=utils.d.ts.map
@@ -3,8 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.insertTextAtPosition = exports.insertTextAtAbsolutePosition = void 0;
6
+ exports.addExtensionTypes = exports.insertTextAtPosition = exports.insertTextAtAbsolutePosition = void 0;
7
7
  const os_1 = __importDefault(require("os"));
8
+ const path_1 = require("path");
9
+ const semver_1 = require("semver");
10
+ const templates_1 = require("../templates");
8
11
  /**
9
12
  * Method inserts passed text into content by char index position.
10
13
  * In case if position is out of range, then whitespaces would be created.
@@ -53,4 +56,21 @@ function insertTextAtPosition(text, content, position) {
53
56
  return lines.join(os_1.default.EOL);
54
57
  }
55
58
  exports.insertTextAtPosition = insertTextAtPosition;
59
+ /**
60
+ * Adds type extensions for sap.fe types if an older version is used.
61
+ * The types were fixed in 1.108 and downported to 1.102.
62
+ *
63
+ * @param basePath - the base path
64
+ * @param minUI5Version - minimal required UI5 version
65
+ * @param fs - the memfs editor instance
66
+ */
67
+ function addExtensionTypes(basePath, minUI5Version, fs) {
68
+ var _a;
69
+ const version = semver_1.minor((_a = semver_1.coerce(minUI5Version)) !== null && _a !== void 0 ? _a : '1.108.0');
70
+ const path = path_1.join(basePath, '/webapp/ext/sap.fe.d.ts');
71
+ if (version < 108 && version !== 102 && !fs.exists(path)) {
72
+ fs.copyTpl(templates_1.getTemplatePath('common/sap.fe.d.ts'), path, { version });
73
+ }
74
+ }
75
+ exports.addExtensionTypes = addExtensionTypes;
56
76
  //# sourceMappingURL=utils.js.map
@@ -9,6 +9,7 @@ const types_1 = require("./types");
9
9
  const validate_1 = require("../common/validate");
10
10
  const defaults_1 = require("../common/defaults");
11
11
  const templates_1 = require("../templates");
12
+ const utils_1 = require("../common/utils");
12
13
  exports.UI5_CONTROLLER_EXTENSION_LIST_REPORT = 'sap.fe.templates.ListReport.ListReportController';
13
14
  exports.UI5_CONTROLLER_EXTENSION_OBJECT_PAGE = 'sap.fe.templates.ObjectPage.ObjectPageController';
14
15
  const UI5_CONTROLLER_EXTENSIONS = 'sap.ui.controllerExtensions';
@@ -189,6 +190,9 @@ function generateControllerExtension(basePath, controllerConfig, fs) {
189
190
  if (!fs.exists(viewPath)) {
190
191
  fs.copyTpl(templates_1.getTemplatePath(`controller-extension/Controller.${ext}`), viewPath, internalConfig);
191
192
  }
193
+ if (controllerConfig.typescript) {
194
+ utils_1.addExtensionTypes(basePath, controllerConfig.minUI5Version, fs);
195
+ }
192
196
  return fs;
193
197
  }
194
198
  exports.generateControllerExtension = generateControllerExtension;
@@ -10,6 +10,7 @@ const defaults_1 = require("../common/defaults");
10
10
  const validate_1 = require("../common/validate");
11
11
  const templates_1 = require("../templates");
12
12
  const semver_1 = require("semver");
13
+ const utils_1 = require("../common/utils");
13
14
  /**
14
15
  * Enhances the provided custom page configuration with default data.
15
16
  *
@@ -80,6 +81,9 @@ function generate(basePath, data, fs) {
80
81
  if (!fs.exists(controllerPath)) {
81
82
  fs.copyTpl(path_1.join(root, `ext/Controller.${ext}`), controllerPath, config);
82
83
  }
84
+ if (data.typescript) {
85
+ utils_1.addExtensionTypes(basePath, data.minUI5Version, fs);
86
+ }
83
87
  return fs;
84
88
  }
85
89
  exports.generate = generate;
@@ -26,6 +26,16 @@ function getManifestRoot(ui5Version) {
26
26
  }
27
27
  }
28
28
  exports.getManifestRoot = getManifestRoot;
29
+ /**
30
+ * Get additional dependencies for fragment.xml template based on passed ui5 version.
31
+ *
32
+ * @param ui5Version required UI5 version.
33
+ * @returns Additional dependencies for fragment.xml
34
+ */
35
+ function getAdditionalDependencies(ui5Version) {
36
+ const minVersion = semver_1.coerce(ui5Version);
37
+ return !minVersion || minVersion.minor >= 90 ? { 'xmlns:macros': 'sap.fe.macros' } : undefined;
38
+ }
29
39
  /**
30
40
  * Enhances the provided custom section configuration with additonal data.
31
41
  *
@@ -44,6 +54,8 @@ function enhanceConfig(fs, data, manifestPath, manifest) {
44
54
  }
45
55
  // generate section content
46
56
  config.content = config.control || defaults_1.getDefaultFragmentContent(config.name, config.eventHandler);
57
+ // Additional dependencies to include into 'Fragment.xml'
58
+ config.dependencies = getAdditionalDependencies(config.minUI5Version);
47
59
  return config;
48
60
  }
49
61
  /**
@@ -17,7 +17,11 @@ export interface CustomSection extends CustomElement, EventHandler {
17
17
  */
18
18
  control?: string;
19
19
  }
20
+ export interface CustomSectionDependencies {
21
+ [key: string]: string;
22
+ }
20
23
  export interface InternalCustomSection extends CustomSection, InternalCustomElement {
21
24
  content: string;
25
+ dependencies?: CustomSectionDependencies;
22
26
  }
23
27
  //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sap-ux/fe-fpm-writer",
3
3
  "description": "SAP Fiori elements flexible programming model writer",
4
- "version": "0.17.2",
4
+ "version": "0.17.4",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -40,8 +40,8 @@
40
40
  "node": ">= 14.16.0 < 15.0.0 || >=16.1.0 < 17.0.0 || >=18.0.0 < 19.0.0"
41
41
  },
42
42
  "scripts": {
43
- "build": "pnpm clean && tsc",
44
- "clean": "rimraf dist",
43
+ "build": "pnpm clean && tsc -p tsconfig-build.json",
44
+ "clean": "rimraf dist test/test-output",
45
45
  "format": "prettier --write '**/*.{js,json,ts,yaml,yml}' --ignore-path ../../.prettierignore",
46
46
  "lint": "eslint . --ext .ts",
47
47
  "lint:fix": "eslint . --ext .ts --fix",
@@ -4,7 +4,7 @@ sap.ui.define([
4
4
  'use strict';
5
5
 
6
6
  return {
7
- <%- (typeof eventHandlerFnName !== 'undefined' && eventHandlerFnName) || 'onPress' %>: function() {
7
+ <%- (typeof eventHandlerFnName !== 'undefined' && eventHandlerFnName) || 'onPress' %>: function(oEvent) {
8
8
  MessageToast.show("Custom handler invoked.");
9
9
  }
10
10
  };
@@ -1,5 +1,13 @@
1
+ import ExtensionAPI from 'sap/fe/core/ExtensionAPI';
2
+ import <%- parameters.importType %> from '<%- parameters.importSource %>';
1
3
  import MessageToast from 'sap/m/MessageToast';
2
4
 
3
- export function <%- (typeof eventHandlerFnName !== 'undefined' && eventHandlerFnName) || 'onPress' %>() {
5
+ /**
6
+ * Generated event handler.
7
+ *
8
+ * @param this reference to the 'this' that the event handler is bound to.
9
+ * @param <%- parameters.name %> <%- parameters.description %>
10
+ */
11
+ export function <%- (typeof eventHandlerFnName !== 'undefined' && eventHandlerFnName) || 'onPress' %>(this: ExtensionAPI, <%- parameters.name %>: <%- parameters.importType %>) {
4
12
  MessageToast.show("Custom handler invoked.");
5
13
  }
@@ -1,3 +1,3 @@
1
- <core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m">
1
+ <core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m"<%- typeof dependencies !== 'undefined' ? Object.entries(dependencies).map((dependency) => ` ${dependency[0]}="${dependency[1]}"`).join('') : '' %>>
2
2
  <%- content %>
3
3
  </core:FragmentDefinition>
@@ -0,0 +1,43 @@
1
+ import ExtensionAPI from 'sap/fe/core/ExtensionAPI';
2
+ import Routing from 'sap/fe/core/controllerextensions/Routing';
3
+ import EditFlow from 'sap/fe/core/controllerextensions/EditFlow';
4
+ import IntentBasedNavigation from 'sap/fe/core/controllerextensions/IntentBasedNavigation';
5
+
6
+ /**
7
+ * Missing public properties (https://ui5.sap.com/#/api/sap.fe.core.ExtensionAPI)
8
+ */
9
+ interface ExtensionAPIProperties {
10
+ routing: Routing;
11
+ editFlow: EditFlow;
12
+ intentBasedNavigation: IntentBasedNavigation;
13
+ }
14
+
15
+ /**
16
+ * Add missing public properties
17
+ */
18
+ declare module 'sap/fe/core/ExtensionAPI' {
19
+ export default interface ExtensionAPI extends ExtensionAPIProperties {}
20
+ }
21
+
22
+ /**
23
+ * Add missing public properties
24
+ */
25
+ declare module 'sap/fe/templates/ObjectPage/ExtensionAPI' {
26
+ export default interface ExtensionAPI extends ExtensionAPIProperties {}
27
+ }
28
+
29
+ /**
30
+ * Add missing public properties
31
+ */
32
+ declare module 'sap/fe/templates/ListReport/ExtensionAPI' {
33
+ export default interface ExtensionAPI extends ExtensionAPIProperties {}
34
+ }
35
+
36
+ /**
37
+ * Enhancing the PageController type to simplify the work with the extension API
38
+ */
39
+ declare module 'sap/fe/core/PageController' {
40
+ export default interface PageController {
41
+ getExtensionAPI() : ExtensionAPI;
42
+ }
43
+ }
@@ -2,14 +2,19 @@ import ControllerExtension from 'sap/ui/core/mvc/ControllerExtension';
2
2
  import ExtensionAPI from 'sap/fe/<%- typeof extension === "object" ? `templates/${extension.pageType}` : "core" -%>/ExtensionAPI';
3
3
 
4
4
  /**
5
- * Definition of the override interface as workaround until https://github.com/SAP/ui5-typescript/issues/332 is fixed.
5
+ * Helper to be able to define how to get the extension API when writing a controller extension.
6
6
  */
7
- interface ExtensionOverride {
8
- base: {
9
- getExtensionAPI(): ExtensionAPI;
10
- }
7
+ declare module 'sap/ui/core/mvc/ControllerExtension' {
8
+ export default interface ControllerExtension {
9
+ base: {
10
+ getExtensionAPI(): ExtensionAPI;
11
+ }
12
+ }
11
13
  }
12
14
 
15
+ /**
16
+ * Cannot change to class syntax until https://github.com/SAP/ui5-typescript/issues/332 is fixed.
17
+ */
13
18
  export default ControllerExtension.extend('<%- ns %>.<%- name %>', {
14
19
  // this section allows to extend lifecycle hooks or hooks provided by Fiori elements
15
20
  override: {
@@ -18,7 +23,7 @@ export default ControllerExtension.extend('<%- ns %>.<%- name %>', {
18
23
  * Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
19
24
  * @memberOf <%- ns %>.<%- name %>
20
25
  */
21
- onInit(this: ExtensionOverride) {
26
+ onInit(this: ControllerExtension) {
22
27
  // you can access the Fiori elements extensionAPI via this.base.getExtensionAPI
23
28
  const model = this.base.getExtensionAPI().getModel();
24
29
  }