Skip to content

Commit

Permalink
feat(ui5-tooling-transpile): integrate ts-interface-generator
Browse files Browse the repository at this point in the history
If a TypeScript project adds the dependency to the ts-interface-generator
the ui5-tooling-transpile-middleware tries to start the watch mode so
that changes to control files will automatically update the interfaces
and that code completion can work properly. For now this only works for
the local project, not for dependencies.
  • Loading branch information
petermuessig committed Aug 7, 2023
1 parent ba5d734 commit 0f530b5
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 4 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ pnpm-lock.yaml
/**/*.svg
/**/*.png
/**/*.md
/**/*.gen.d.ts
3 changes: 3 additions & 0 deletions packages/ui5-tooling-transpile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ npm install ui5-tooling-transpile --save-dev
- transformTypeScript: `boolean` (old alias: transpileTypeScript)
if enabled, the tooling extension transforms TypeScript sources; the default value is derived from the existence of a `tsconfig.json` in the root folder of the project - if the file exists the configuration option is `true` otherwise `false`; setting this configuration option overrules the automatic determination

- generateTsInterfaces: `boolean|undefined` (*experimental feature*)
option requires a dependency to the `@ui5/ts-interface-generator` when either the value of the option is `true` or `undefined` and the project is a TypeScript-based project or the `transformTypeScript` option is set to `true` - can be forced to be inactive by setting the option to `false` (only relevant for the middleware)

- generateDts: `boolean`
if enabled, the tooling extension will generate type definitions (`.d.ts`) files; by default for projects of type `library` this option is considered as `true` and for other projects such as `application` this option is considered as `false` by default (is only relevant in case of transformTypeScript is `true`)

Expand Down
22 changes: 22 additions & 0 deletions packages/ui5-tooling-transpile/lib/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,28 @@ module.exports = async function ({ log, resources, options, middlewareUtil }) {
);
}

// if the project is a TypeScript-based project
// let's try to start the ts-interface-generator
// if the dependency is present
if (config.generateTsInterfaces) {
const argvOrg = process.argv;
try {
// check if the dependency could be found
const module = require.resolve("@ui5/ts-interface-generator", {
paths: [cwd]
});
// launch the ts-interface-generator in watch mode
process.argv = [process.argv[0], process.argv[1], "--watch", "--logLevel", log.constructor.getLevel()];
require(module);
} catch (e) {
config.debug &&
log.error(
"Failed to generate the control interfaces! The dependency to the @ui5/ts-interface-generator is missing!"
);
}
process.argv = argvOrg;
}

return async (req, res, next) => {
const pathname = parseurl(req)?.pathname;
if (pathname.endsWith(".js") && shouldHandlePath(pathname, config.excludes, config.includes)) {
Expand Down
2 changes: 2 additions & 0 deletions packages/ui5-tooling-transpile/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ module.exports = function (log) {
excludes,
filePattern,
omitTSFromBuildResult: config.omitTSFromBuildResult,
generateTsInterfaces:
config.generateTsInterfaces !== undefined ? config.generateTsInterfaces : transformTypeScript,
generateDts: config.generateDts,
transpileDependencies: config.transpileDependencies,
transformAtStartup: config.transformAtStartup,
Expand Down
8 changes: 8 additions & 0 deletions packages/ui5-tooling-transpile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
"devDependencies": {
"ava": "^5.3.1"
},
"peerDependencies": {
"@ui5/ts-interface-generator": ">=0.7.0"
},
"peerDependenciesMeta": {
"@ui5/ts-interface-generator": {
"optional": true
}
},
"scripts": {
"lint": "eslint lib",
"test": "ava --no-worker-threads"
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions showcases/ui5-tsapp-simple/webapp/control/SimpleControl.gen.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { PropertyBindingInfo } from "sap/ui/base/ManagedObject";
import { $ControlSettings } from "sap/ui/core/Control";

declare module "./SimpleControl" {

/**
* Interface defining the settings object used in constructor calls
*/
interface $SimpleControlSettings extends $ControlSettings {
text?: string | PropertyBindingInfo;
}

export default interface SimpleControl {

// property: text

/**
* Gets current value of property "text".
*
* @returns Value of property "text"
*/
getText(): string;

/**
* Sets a new value for property "text".
*
* When called with a value of "null" or "undefined", the default value of the property will be restored.
*
* @param text New value for property "text"
* @returns Reference to "this" in order to allow method chaining
*/
setText(text: string): this;
}
}
36 changes: 36 additions & 0 deletions showcases/ui5-tsapp-simple/webapp/control/SimpleControl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Control from "sap/ui/core/Control";
import RenderManager from "sap/ui/core/RenderManager";
import type { MetadataOptions } from "sap/ui/core/Element";

/**
* @namespace ui5.ecosystem.demo.simpletsapp.control
*/
export default class SimpleControl extends Control {
static readonly metadata: MetadataOptions = {
properties: {
text: "string",
},
};

// The following three lines were generated and should remain as-is to make TypeScript aware of the constructor signatures
constructor(idOrSettings?: string | $SimpleControlSettings);
constructor(id?: string, settings?: $SimpleControlSettings);
constructor(id?: string, settings?: $SimpleControlSettings) {
super(id, settings);
}

renderer = {
apiVersion: 2,
render: (rm: RenderManager, control: SimpleControl) => {
rm.openStart("div", control);
rm.style("font-size", "2rem");
rm.style("width", "2rem");
rm.style("height", "2rem");
rm.style("display", "inline-block");
rm.style("color", "blue");
rm.openEnd();
rm.text(control.getText());
rm.close("div");
},
};
}

0 comments on commit 0f530b5

Please sign in to comment.