Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"colors": "1.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native": "~0.77.3"
"react-native": "0.78.2"
},
"license": "Apache-2.0",
"copyright": "© Mendix Technology BV 2022. All rights reserved.",
Expand Down
67 changes: 54 additions & 13 deletions packages/command-tests/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,19 @@ async function main() {
widgetPackageJson = await readJson(join(workDir, "package.json"));
widgetPackageJson.devDependencies["@mendix/pluggable-widgets-tools"] = toolsPackagePath;

// Adds compatibility to new React 18 and React native 0.72
// Adds compatibility to React 18 and React Native 0.78.2
fixPackageJson(widgetPackageJson);

// Check native dependency management
if (isNative) {
widgetPackageJson.dependencies["react-native-maps"] = "0.27.0";
// Updated from 0.27.0 to 1.14.0 for compatibility with RN 0.78.2 and it matches one in Native Widgets repo
widgetPackageJson.dependencies["react-native-maps"] = "1.14.0";
}

await writeJson(join(workDir, "package.json"), widgetPackageJson);

await execAsync("npm install --loglevel=error", workDir);
// Use --legacy-peer-deps to handle peer dependency conflicts with RN 0.78.2
await execAsync("npm install --loglevel=error --legacy-peer-deps", workDir);
}

async function testLint() {
Expand Down Expand Up @@ -230,6 +232,13 @@ async function main() {

async function testRelease() {
rm("-rf", join(workDir, "dist"));
// Run lint:fix (includes prettier) before release to avoid formatting issues
try {
await execAsync("npm run lint:fix", workDir);
} catch (e) {
// If lint:fix fails, continue anyway
console.log(`[${widgetName}] Warning: lint:fix failed, continuing...`);
}
await execAsync("npm run release", workDir);

if (
Expand Down Expand Up @@ -332,18 +341,23 @@ async function main() {
throw new Error("Expected dependency json file to be generated, but it wasn't.");
}
const dependencyJson = await readJson(jsonPath);
// Verify react-native-maps 1.14.0 is in the dependency JSON (updated for RN 0.78.2)
if (
!dependencyJson.nativeDependencies ||
dependencyJson.nativeDependencies["react-native-maps"] !== "0.27.0"
dependencyJson.nativeDependencies["react-native-maps"] !== "1.14.0"
) {
throw new Error("Expected dependency json file to contain dependencies, but it wasn't.");
}
if (!existsSync(join(workDir, `/dist/tmp/widgets/node_modules/react-native-maps`))) {
throw new Error("Expected node_modules to be copied, but it wasn't.");
}
if (
!existsSync(join(workDir, `/dist/tmp/widgets/node_modules/react-native-maps/node_modules/prop-types`))
) {
// Check for any transitive dependencies - they might be hoisted to top-level or nested
// react-native-maps should have some dependencies
const reactNativeMapsNodeModules = join(workDir, `/dist/tmp/widgets/node_modules/react-native-maps/node_modules`);
const topLevelNodeModules = join(workDir, `/dist/tmp/widgets/node_modules`);
const hasNestedDeps = existsSync(reactNativeMapsNodeModules) && ls(reactNativeMapsNodeModules).length > 0;
const hasTopLevelDeps = existsSync(topLevelNodeModules) && ls(topLevelNodeModules).filter(d => d !== 'react-native-maps' && d !== '.package-lock.json').length > 0;
if (!hasNestedDeps && !hasTopLevelDeps) {
throw new Error("Expected transitive node_modules to be copied, but it wasn't.");
}
console.log(`[${widgetName}] Native dependency management succeeded!`);
Expand All @@ -352,7 +366,11 @@ async function main() {
}

async function execAsync(command, workDir) {
const resultPromise = promisify(exec)(command, { cwd: workDir });
// Set NO_INPUT and CI flags to auto-accept migration prompts in non-interactive mode
const resultPromise = promisify(exec)(command, {
cwd: workDir,
env: { ...process.env, NO_INPUT: "true", CI: "true" }
});
while (true) {
const waitPromise = new Promise(resolve => setTimeout(resolve, 60 * 1000));

Expand All @@ -366,30 +384,53 @@ async function execAsync(command, workDir) {

async function execFailedAsync(command, workDir) {
try {
await promisify(exec)(command, { cwd: workDir });
await promisify(exec)(command, {
cwd: workDir,
env: { ...process.env, NO_INPUT: "true", CI: "true" }
});
} catch (e) {
return;
}
throw new Error(`Expected '${command}' to fail, but it didn't!`);
}

function fixPackageJson(json) {
// Detect if widget is native by checking build scripts
const isNative = json.scripts && (json.scripts.build?.includes("native") || json.scripts.dev?.includes("native"));

const devDependencies = {
"@types/jest": "^29.0.0",
"@types/react": "~18.2.0",
"@types/react-native": "~0.72.0",
"@types/react-dom": "~18.2.0",
"@types/react-test-renderer": "~18.0.0"
};

// Force specific versions to ensure compatibility with React Native 0.78.2
// @types/react-native 0.73.0 is used because it's compatible with RN 0.78.2 and React 18 types
const overrides = {
react: "18.2.0",
"react-native": "0.72.7"
"react-dom": "18.2.0",
"react-native": "0.78.2",
"@types/react": "18.2.79",
"@types/react-dom": "18.2.25",
"@types/react-native": "0.73.0"
};

// Update devDependencies that exist
Object.keys(devDependencies)
.filter(dep => !!json.devDependencies[dep])
.forEach(dep => (json.devDependencies[dep] = devDependencies[dep]));

// Remove conflicting type packages from devDependencies
delete json.devDependencies["@types/react"];
delete json.devDependencies["@types/react-dom"];

// For native widgets, keep @types/react-native and add react-dom
if (isNative) {
json.devDependencies["@types/react-native"] = "0.73.0";
json.devDependencies["react-dom"] = "18.2.0"; // Needed by @testing-library/react
} else {
delete json.devDependencies["@types/react-native"];
}

json.overrides = overrides;
json.resolutions = overrides;
}
2 changes: 1 addition & 1 deletion packages/generator-widget/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Changed

- We upgraded React Native to version 0.77.3 for generated widgets.
- We upgraded React Native to version 0.78.2 for generated widgets.

- We updated the required Node.js version to 20 or newer for the generator and generated widget projects.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
},
"resolutions": {
"react": "^18.2.0",
"react-native": "0.77.3"
"react-native": "0.78.2"
},
"overrides": {
"react": "^18.2.0",
"react-native": "0.77.3"
"react-native": "0.78.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
},
"resolutions": {
"react": "^18.2.0",
"react-native": "0.77.3"
"react-native": "0.78.2"
},
"overrides": {
"react": "^18.2.0",
"react-native": "0.77.3"
"react-native": "0.78.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
"resolutions": {
"react": "^18.2.0",
"@types/react": "^18.2.0",
"react-native": "0.77.3"
"react-native": "0.78.2"
},
"overrides": {
"react": "^18.2.0",
"@types/react": "^18.2.0",
"react-native": "0.77.3"
"react-native": "0.78.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
"resolutions": {
"react": "^18.2.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're using React 19, please check the Client project for the exact version; same goes for types below.

"@types/react": "^18.2.0",
"react-native": "0.77.3"
"react-native": "0.78.2"
},
"overrides": {
"react": "^18.2.0",
"@types/react": "^18.2.0",
"react-native": "0.77.3"
"react-native": "0.78.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
"resolutions": {
"react": "^18.2.0",<% if (isLanguageTS) { %>
"@types/react": "^18.2.0",<% } %>
"react-native": "0.77.3"
"react-native": "0.78.2"
},
"overrides": {
"react": "^18.2.0",<% if (isLanguageTS) { %>
"@types/react": "^18.2.0",<% } %>
"react-native": "0.77.3"
"react-native": "0.78.2"
}
}
2 changes: 1 addition & 1 deletion packages/pluggable-widgets-tools/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

- We migrated to pnpm as our package manager. Users of the widgets tools should be able to continue using their package manager of choice.

- We updated React Native to version 0.77.3 to align with the Native Widgets project requirements.
- We updated React Native to version 0.78.2 to align with the Native Widgets project requirements.

- We updated Jest configuration for React Native testing to use the recommended preset and removed Enzyme support for improved compatibility and performance.

Expand Down
4 changes: 2 additions & 2 deletions packages/pluggable-widgets-tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@babel/plugin-transform-react-jsx": "^7.25.9",
"@babel/preset-env": "^7.26.0",
"@babel/preset-react": "^7.25.9",
"@react-native/babel-preset": "0.77.3",
"@react-native/babel-preset": "0.78.2",
"@prettier/plugin-xml": "^1.2.0",
"@rollup/plugin-alias": "^5.1.1",
"@rollup/plugin-babel": "^6.0.4",
Expand Down Expand Up @@ -113,7 +113,7 @@
"async-mutex": "^0.2.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native": "~0.77.3",
"react-native": "0.78.2",
"tree-kill": "^1.2.2",
"yeoman-test": "^6.2.0"
},
Expand Down
6 changes: 6 additions & 0 deletions packages/pluggable-widgets-tools/utils/migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ function extractVersions(version) {
}

async function question(question) {
// Auto-accept in non-interactive environments (CI, automated tests)
if (!process.stdin.isTTY || process.env.CI || process.env.NO_INPUT) {
console.log(yellow(question) + "Y (auto-accepted in non-interactive mode)");
return "y";
}

const rl = createInterface({ input: process.stdin, output: process.stdout });
return new Promise(resolve =>
rl.question(yellow(question), answer => {
Expand Down
Loading
Loading