From ee3d2216eeb46ccdc80ed1f2e35b41090cecd4b5 Mon Sep 17 00:00:00 2001 From: Illia Obukhau <8282906+iobuhov@users.noreply.github.com> Date: Wed, 11 Mar 2026 16:04:36 +0100 Subject: [PATCH 01/13] Extract typings-generator into separate @mendix/widget-typings-generator package Co-Authored-By: Claude Sonnet 4.5 --- .../configs/rollup-plugin-widget-typing.mjs | 3 +- .../pluggable-widgets-tools/jest.config.js | 1 - packages/pluggable-widgets-tools/package.json | 1 + packages/widget-typings-generator/README.md | 81 +++++++++++++++++++ .../widget-typings-generator/jest.config.js | 17 ++++ .../widget-typings-generator/package.json | 59 ++++++++++++++ .../src}/PackageXml.ts | 0 .../src}/WidgetXml.ts | 0 .../src}/__tests__/index.spec.ts | 2 +- .../src}/__tests__/inputs/association.ts | 0 .../inputs/atribute-linked-action.ts | 0 .../src}/__tests__/inputs/containment.ts | 0 .../src}/__tests__/inputs/datasource.ts | 0 .../src}/__tests__/inputs/expression.ts | 0 .../src}/__tests__/inputs/file.ts | 0 .../src}/__tests__/inputs/icon.ts | 0 .../src}/__tests__/inputs/image.ts | 0 .../src}/__tests__/inputs/index.ts | 0 .../inputs/list-action-with-variables.ts | 0 .../src}/__tests__/inputs/list-action.ts | 0 .../src}/__tests__/inputs/list-association.ts | 0 .../__tests__/inputs/list-attribute-refset.ts | 0 .../src}/__tests__/inputs/list-files.ts | 0 .../src}/__tests__/inputs/list-image.ts | 0 .../__tests__/inputs/metadata-association.ts | 0 .../__tests__/inputs/metadata-attribute.ts | 0 .../non-linked-list-attribute-refset.ts | 0 .../src}/__tests__/inputs/selection.ts | 0 .../src}/__tests__/outputs/association.ts | 0 .../outputs/atribute-linked-action.ts | 0 .../src}/__tests__/outputs/containment.ts | 0 .../src}/__tests__/outputs/datasource.ts | 0 .../src}/__tests__/outputs/expression.ts | 0 .../src}/__tests__/outputs/file.ts | 0 .../src}/__tests__/outputs/icon.ts | 0 .../src}/__tests__/outputs/image.ts | 0 .../src}/__tests__/outputs/index.ts | 0 .../outputs/list-action-with-variables.ts | 0 .../src}/__tests__/outputs/list-action.ts | 0 .../__tests__/outputs/list-association.ts | 0 .../outputs/list-attribute-refset.ts | 0 .../src}/__tests__/outputs/list-files.ts | 0 .../src}/__tests__/outputs/list-image.ts | 0 .../__tests__/outputs/metadata-association.ts | 0 .../__tests__/outputs/metadata-attribute.ts | 0 .../non-linked-list-attribute-refset.ts | 0 .../src}/__tests__/outputs/selection.ts | 0 .../src}/generate.ts | 0 .../src}/generateClientTypes.ts | 0 .../src}/generatePreviewTypes.ts | 0 .../src}/helpers.ts | 0 .../src}/index.ts | 3 +- .../widget-typings-generator/tsconfig.json | 21 +++++ pnpm-lock.yaml | 50 +++++++++++- 54 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 packages/widget-typings-generator/README.md create mode 100644 packages/widget-typings-generator/jest.config.js create mode 100644 packages/widget-typings-generator/package.json rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/PackageXml.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/WidgetXml.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/index.spec.ts (99%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/association.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/atribute-linked-action.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/containment.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/datasource.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/expression.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/file.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/icon.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/image.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/index.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/list-action-with-variables.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/list-action.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/list-association.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/list-attribute-refset.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/list-files.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/list-image.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/metadata-association.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/metadata-attribute.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/non-linked-list-attribute-refset.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/inputs/selection.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/association.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/atribute-linked-action.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/containment.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/datasource.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/expression.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/file.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/icon.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/image.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/index.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/list-action-with-variables.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/list-action.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/list-association.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/list-attribute-refset.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/list-files.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/list-image.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/metadata-association.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/metadata-attribute.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/non-linked-list-attribute-refset.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/__tests__/outputs/selection.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/generate.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/generateClientTypes.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/generatePreviewTypes.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/helpers.ts (100%) rename packages/{pluggable-widgets-tools/src/typings-generator => widget-typings-generator/src}/index.ts (93%) create mode 100644 packages/widget-typings-generator/tsconfig.json diff --git a/packages/pluggable-widgets-tools/configs/rollup-plugin-widget-typing.mjs b/packages/pluggable-widgets-tools/configs/rollup-plugin-widget-typing.mjs index 0fbe0b05..9458fd3e 100644 --- a/packages/pluggable-widgets-tools/configs/rollup-plugin-widget-typing.mjs +++ b/packages/pluggable-widgets-tools/configs/rollup-plugin-widget-typing.mjs @@ -1,8 +1,7 @@ import { promises as fs } from "fs"; import { extname, join } from "path"; import { listDir } from "./shared.mjs"; - -const { transformPackage } = await import(new URL("../dist/typings-generator/index.js", import.meta.url)); +import { transformPackage } from "@mendix/widget-typings-generator"; export function widgetTyping({ sourceDir }) { let firstRun = true; diff --git a/packages/pluggable-widgets-tools/jest.config.js b/packages/pluggable-widgets-tools/jest.config.js index f6582d1b..ff91b7e9 100644 --- a/packages/pluggable-widgets-tools/jest.config.js +++ b/packages/pluggable-widgets-tools/jest.config.js @@ -7,7 +7,6 @@ const webConfig = { rootDir: ".", testMatch: [ "/src/web/**/*.spec.{ts,tsx}", - "/src/typings-generator/**/*.spec.{ts,tsx}", "/src/utils/**/*.spec.{ts,tsx}" ] }; diff --git a/packages/pluggable-widgets-tools/package.json b/packages/pluggable-widgets-tools/package.json index 7410d883..6955754c 100644 --- a/packages/pluggable-widgets-tools/package.json +++ b/packages/pluggable-widgets-tools/package.json @@ -25,6 +25,7 @@ "utils" ], "dependencies": { + "@mendix/widget-typings-generator": "workspace:*", "@babel/core": "^7.26.0", "@babel/plugin-transform-class-properties": "^7.25.9", "@babel/plugin-transform-private-methods": "^7.25.9", diff --git a/packages/widget-typings-generator/README.md b/packages/widget-typings-generator/README.md new file mode 100644 index 00000000..80396869 --- /dev/null +++ b/packages/widget-typings-generator/README.md @@ -0,0 +1,81 @@ +# @mendix/widget-typings-generator + +TypeScript typings generator for Mendix Pluggable Widgets. + +## Overview + +Generates TypeScript definition files (`.d.ts`) from Mendix widget XML schema files, providing type-safe development experience for widget creators. + +## Usage + +### Basic Usage + +```typescript +import { transformPackage } from "@mendix/widget-typings-generator"; +import { readFile } from "fs/promises"; + +// Read your widget's package.xml +const packageXml = await readFile("./src/{WidgetName}.xml", "utf-8"); + +// Generate TypeScript definitions +await transformPackage(packageXml, "./src"); +``` + +This will: +1. Parse `{WidgetName}.xml` to find all widget XML files +2. Generate TypeScript interfaces for each widget +3. Create `.d.ts` files in `../typings/{WidgetName}.xml/` directory + +### Generated Types + +For a widget named `MyWidget`, it generates: +- **Web:** `MyWidgetContainerProps` (runtime) and `MyWidgetPreviewProps` (Studio Pro) +- **Native:** `MyWidgetProps