@codemoreira/esad 2.0.1-29 β†’ 2.0.1-30

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.
package/README.md CHANGED
@@ -1,88 +1,88 @@
1
- # ESAD (Easy Super App Development) πŸš€
1
+ # ESAD: Easy Super App Development πŸš€
2
2
 
3
- Zero-Config CLI and DevTools for React Native Module Federation + Expo.
3
+ **Zero-Config CLI & Framework for React Native Module Federation + Expo.**
4
4
 
5
- ESAD is a unified toolkit designed to abstract all the complexity from Super App development using **Re.Pack (Rspack)** and **Expo**. It provides a professional, linear workflow from scaffolding to deployment.
5
+ ESAD is a unified toolkit designed to abstract all the complexity of Super App development. It bridges **Expo SDK 52** and **Re.Pack 5 (Rspack)** into a professional, linear workflow.
6
6
 
7
7
  ---
8
8
 
9
- ## πŸ—οΈ CLI Workflow (V2)
9
+ ## πŸ”₯ Key Features
10
+
11
+ - **⚑ Zero-Config Native**: Automatic Android/iOS patching via **Expo Config Plugins**. No more manual Gradle or Manifest edits.
12
+ - **πŸš€ Rspack Powered**: Blazing fast bundle generation for both Host and Remote Modules.
13
+ - **πŸ›‘οΈ Authenticated Remotes**: Built-in support for **JWT-signed bundle resolution** and dynamic module discovery.
14
+ - **πŸ“¦ Shared Memory Bridge**: Reactive global state across federation boundaries using the ESAD Client SDK.
15
+ - **🧹 Lifecycle Maestro**: Automated `prebuild`, script fixing, and dev-server management.
16
+
17
+ ---
18
+
19
+ ## πŸ—οΈ Quick Start (V2)
10
20
 
11
21
  ### 1. Initialize a Workspace
12
22
  Creates the project root, a programmable `esad.config.js`, and the Host Application.
13
23
  ```bash
14
- npx @codemoreira/esad init my-project
24
+ npx @codemoreira/esad init my-super-app
15
25
  ```
16
26
 
17
27
  ### 2. Expand your Workspace
18
- Create new Federated Modules or a Local Registry/CDN.
28
+ Create new Federated Modules with built-in navigation and shared state examples.
19
29
  ```bash
20
- esad create my-module # Creates a new module (Feature)
21
- esad create --type cdn # Scaffolds a local registry for testing
30
+ esad create my-feature --type module
22
31
  ```
23
32
 
24
- ### 3. Development Manager (Unified)
25
- The `dev` command is the single entry point for development. It automatically detects if it should run the Host or a Module.
33
+ ### 3. Development Manager (The Maestro)
34
+ The `dev` command handles everything: Prebuilds, Script Fixing, and Native Launch.
26
35
 
27
- **Run the Host App (Interactive):**
36
+ **Run the Host App:**
28
37
  ```bash
29
38
  esad dev
30
39
  ```
31
- *Allows selecting Android, iOS, or Bundler Only. Automatically patches native files.*
32
-
33
- **Run a specific Module:**
34
- ```bash
35
- esad dev my-module --port 9000
36
- ```
37
- *Starts the module server and updates the Host's local mapping automatically.*
40
+ *Choose Android or iOS. The CLI will automatically run `expo prebuild` if native folders are missing.*
38
41
 
39
- ### 4. Build & Deploy
40
- Prepare and push your features to the registry.
41
-
42
- **Build for Production:**
43
- ```bash
44
- esad build my-module --platform android
45
- ```
46
-
47
- **Execute Programmable Deploy:**
42
+ **Run a specific Module (in a separate terminal):**
48
43
  ```bash
49
- esad deploy my-module --version 1.0.0
44
+ esad dev my-feature --port 9000
50
45
  ```
51
46
 
52
47
  ---
53
48
 
54
- ## πŸ› οΈ Library Usage
49
+ ## πŸ› οΈ Toolset Usage
55
50
 
56
51
  ### 🎨 Bundler Plugin (`@codemoreira/esad/plugin`)
57
- Wrap your configuration to enable ESAD's smart resolution and redirection logic:
52
+ The `withESAD` wrapper automates Module Federation v2 setup and dynamic exposes:
58
53
  ```javascript
59
54
  import { withESAD } from '@codemoreira/esad/plugin';
60
55
 
61
- export default withESAD({
62
- type: 'module', // or 'host'
63
- id: 'my-mini-app'
56
+ export default withESAD(env, {
57
+ type: 'module',
58
+ id: 'my-feature',
59
+ dirname: __dirname
64
60
  });
65
61
  ```
66
62
 
67
- ### ⚑ Global State SDK (`@codemoreira/esad/client`)
63
+ ### ⚑ Client SDK (`@codemoreira/esad/client`)
68
64
  Share state across the Host and all Remote Modules reactively:
69
65
  ```javascript
70
66
  import { useESADState } from '@codemoreira/esad/client';
71
67
 
72
- const [user, setUser] = useESADState('user');
68
+ const [user, setUser] = useESADState('auth_user');
69
+ const [counter, setCounter] = useESADState('global_counter', 0);
73
70
  ```
74
71
 
75
72
  ---
76
73
 
77
- ## 🏠 Template Features (Host & Module)
74
+ ## πŸ›οΈ Architecture & Deep Dive
75
+ For technical diagrams, lifecycle details, and the "Zero-Config" philosophy, see [ESAD_ARCHITECTURE.md](./ESAD_ARCHITECTURE.md).
76
+
77
+ ---
78
+
79
+ ## 🏠 Modern Templates
78
80
  ESAD templates provide a high-end starting point:
79
- - **πŸš€ Rspack + Re.Pack**: Blazing fast builds.
80
- - **πŸ“± Professional Architecture**: Modular structure (`src/api`, `src/components`, `src/navigation`).
81
- - **πŸ›€οΈ Dynamic Navigation**: Pre-configured Module Viewer with **Suspense** and **ErrorBoundary** support.
82
- - **πŸ” State-Driven Auth**: Built-in login and session management via the ESAD SDK.
83
- - **πŸ”§ Automated Native Patching**: Zero-config injection into Android/iOS projects.
81
+ - **Navigation Multi-pΓ‘gina**: Federated modules with internal stack navigators.
82
+ - **Real Auth**: Integration-ready for Simple-CDN registries via JWT.
83
+ - **Smart UI**: Pre-configured Skeletons, Typography, and Modern Dark Mode.
84
84
 
85
85
  ---
86
86
 
87
- ## 🎨 Architecture & Workflow
88
- For technical diagrams and the full lifecycle, see [ESAD_ARCHITECTURE.md](./ESAD_ARCHITECTURE.md).
87
+ > [!TIP]
88
+ > **Why ESAD?** React Native Module Federation is hard. ESAD makes it as easy as a standard Expo app while keeping the power of dynamic micro-frontends.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemoreira/esad",
3
- "version": "2.0.1-29",
3
+ "version": "2.0.1-30",
4
4
  "description": "Easy Super App Development - Zero-Config CLI and DevTools for React Native Module Federation",
5
5
  "main": "src/plugin/index.js",
6
6
  "types": "./src/plugin/index.d.ts",
@@ -16,6 +16,9 @@
16
16
  "./client": {
17
17
  "types": "./src/client/index.d.ts",
18
18
  "default": "./src/client/index.js"
19
+ },
20
+ "./expo-plugin": {
21
+ "default": "./src/plugin/withRepack.js"
19
22
  }
20
23
  },
21
24
  "bin": {
@@ -37,14 +40,11 @@
37
40
  "@babel/core": "^7.20.0",
38
41
  "@callstack/repack": "^5.2.5",
39
42
  "@callstack/repack-plugin-expo-modules": "^5.2.5",
40
- "@callstack/repack-plugin-reanimated": "^5.2.5",
41
- "@module-federation/enhanced": "^2.3.1",
43
+ "@module-federation/enhanced": "^2.4.0",
42
44
  "@rspack/core": "^1.7.8",
43
45
  "@swc/core": "^1.7.0",
44
46
  "@swc/helpers": "^0.5.11",
45
47
  "adm-zip": "^0.5.10",
46
- "babel-loader": "^9.1.3",
47
- "babel-plugin-transform-define": "^2.1.4",
48
48
  "babel-preset-expo": "~12.0.0",
49
49
  "chalk": "^4.1.2",
50
50
  "commander": "^11.1.0",
@@ -38,6 +38,13 @@ async function renameProject(targetDir, newName) {
38
38
  if (appJson.expo.android) {
39
39
  appJson.expo.android.package = `com.anonymous.${newName.replace(/[^a-zA-Z0-9]/g, '')}`;
40
40
  }
41
+
42
+ // Auto-register ESAD Expo Config Plugin
43
+ if (!appJson.expo.plugins) appJson.expo.plugins = [];
44
+ if (!appJson.expo.plugins.includes('@codemoreira/esad/expo-plugin')) {
45
+ appJson.expo.plugins.push('@codemoreira/esad/expo-plugin');
46
+ console.log(`βœ… Registered @codemoreira/esad/expo-plugin in app.json.`);
47
+ }
41
48
  } else {
42
49
  appJson.name = newName;
43
50
  appJson.slug = newName;
@@ -60,44 +67,32 @@ async function renameProject(targetDir, newName) {
60
67
  }
61
68
 
62
69
  /**
63
- * Prepares the native folders and applies Re.Pack patches
70
+ * Prepares the native folders and applies Re.Pack patches via Config Plugin
64
71
  */
65
72
  async function prepareNative(cwd, platform = 'android') {
66
- if (!fs.existsSync(path.join(cwd, 'android')) && (platform === 'android' || platform === 'all')) {
67
- console.log(`πŸ“¦ Native folder not found. Running expo prebuild...`);
68
- await runProcess('npx', ['expo', 'prebuild', '--platform', 'android'], cwd);
69
- }
70
-
71
- // Apply Gradle Patch (Android)
72
- const buildGradlePath = path.join(cwd, 'android/app/build.gradle');
73
- if (fs.existsSync(buildGradlePath)) {
74
- let content = await fs.readFile(buildGradlePath, 'utf8');
75
- if (!content.includes('project.ext.react')) {
76
- const patch = `\nproject.ext.react = [\n bundleCommand: "repack-bundle",\n bundleConfig: "rspack.config.mjs"\n]\n\n`;
77
- content = content.replace(/react \{/, `${patch}react {`);
78
-
79
- // Force androidx.core version to avoid SDK 36 requirement conflict
80
- if (!content.includes('androidx.core:core:')) {
81
- const forcePatch = `\nconfigurations.all {\n resolutionStrategy {\n force 'androidx.core:core:1.15.0'\n force 'androidx.core:core-ktx:1.15.0'\n }\n}\n\n`;
82
- content = forcePatch + content;
83
- }
73
+ const hasAndroid = fs.existsSync(path.join(cwd, 'android'));
74
+ const hasIos = fs.existsSync(path.join(cwd, 'ios'));
84
75
 
85
- await fs.writeFile(buildGradlePath, content);
86
- console.log(`βœ… Patched android/app/build.gradle for Re.Pack and AndroidX versions.`);
87
- }
76
+ if ((!hasAndroid && (platform === 'android' || platform === 'all')) ||
77
+ (!hasIos && (platform === 'ios' || platform === 'all'))) {
78
+
79
+ console.log(`\nπŸ“¦ Native folder(s) missing. Running expo prebuild...`);
80
+ await runProcess('npx', ['expo', 'prebuild', '--platform', platform === 'all' ? 'all' : platform], cwd);
88
81
 
89
- const gradlePropsPath = path.join(cwd, 'android', 'gradle.properties');
90
- if (fs.existsSync(gradlePropsPath)) {
91
- let props = await fs.readFile(gradlePropsPath, 'utf8');
92
- if (!props.includes('newArchEnabled=true')) {
93
- props += '\nnewArchEnabled=true\n';
94
- await fs.writeFile(gradlePropsPath, props);
95
- console.log(`βœ… Enabled New Architecture in android/gradle.properties.`);
96
- }
82
+ // FIX SCRIPTS: Revert Expo's overwrite and point to ESAD CLI
83
+ console.log(`\n🧹 Cleaning up package.json scripts (pointing to ESAD CLI)...`);
84
+ const pkgPath = path.join(cwd, 'package.json');
85
+ if (fs.existsSync(pkgPath)) {
86
+ const pkg = await fs.readJson(pkgPath);
87
+ pkg.scripts.android = 'esad dev --platform android';
88
+ pkg.scripts.ios = 'esad dev --platform ios';
89
+ pkg.scripts.start = 'esad dev';
90
+ await fs.writeJson(pkgPath, pkg, { spaces: 2 });
91
+ console.log(`βœ… Scripts updated to use ESAD CLI (start, android, ios).`);
97
92
  }
98
93
  }
99
94
 
100
- // Create react-native.config.js if missing
95
+ // Create react-native.config.js if missing (Essential for Re.Pack commands)
101
96
  const rnConfigPath = path.join(cwd, 'react-native.config.js');
102
97
  if (!fs.existsSync(rnConfigPath)) {
103
98
  const content = `module.exports = {\n commands: require('@callstack/repack/commands/rspack'),\n};\n`;
@@ -1,174 +1,83 @@
1
- const path = require('node:path');
2
- const fs = require('node:fs');
3
- const Repack = require('@callstack/repack');
4
- const { ExpoModulesPlugin } = require('@callstack/repack-plugin-expo-modules');
5
- const { DefinePlugin } = require('@rspack/core');
6
-
7
- /**
8
- * ESAD Re.Pack Plugin Wrapper
9
- * Abstracts away the boilerplate of Module Federation and SDK integration for SuperApps.
10
- *
11
- * @param {Object} env Rspack environment
12
- * @param {Object} options
13
- * @param {string} options.type 'host' | 'module'
14
- * @param {string} options.id Unique module or host ID
15
- * @param {string} options.dirname Base directory (__dirname)
16
- * @param {Object} [options.shared] Additional shared dependencies
17
- * @param {Object} [options.exposes] Modules to expose (for modules)
18
- * @param {Object} [options.remotes] Remote modules (for host)
19
- */
20
- function withESAD(env, options) {
21
- const { platform, dev } = env;
22
- const isDev = dev !== false;
23
-
24
- // Force environment variables for babel-preset-expo and other loaders
25
- process.env.EXPO_OS = platform;
26
- process.env.NODE_ENV = isDev ? 'development' : 'production';
27
- process.env.BABEL_ENV = isDev ? 'development' : 'production';
28
- const dirname = options.dirname;
29
- const pkgPath = path.resolve(dirname, 'package.json');
30
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
31
- const id = options.id.replace(/-/g, '_');
32
- const sdkPkgPath = path.resolve(__dirname, '..', '..', 'package.json');
33
- const sdkPkg = JSON.parse(fs.readFileSync(sdkPkgPath, 'utf8'));
34
- const clientPath = path.resolve(__dirname, '..', 'client', 'index.js');
35
-
36
- console.log(`[ESAD] Applying Mega-Zero-Config profile for ${options.type.toUpperCase()} (${platform}): ${id}`);
37
-
38
- const config = {
39
- mode: isDev ? 'development' : 'production',
40
- context: dirname,
41
- entry: [
42
- path.resolve(__dirname, 'env-shim.js'),
43
- options.entry || './index.js'
44
- ],
45
- output: {
46
- path: path.resolve(dirname, 'build', platform),
47
- filename: 'index.bundle',
48
- clean: true,
49
- },
50
- resolve: {
51
- ...Repack.getResolveOptions(),
52
- alias: {
53
- '@': path.resolve(dirname, '.'),
54
- // Internal MFv2 & Re.Pack Aliases (Magic)
55
- '@module-federation/runtime/helpers': path.resolve(dirname, 'node_modules/@module-federation/runtime/dist/helpers.js'),
56
- '@module-federation/error-codes/browser': path.resolve(dirname, 'node_modules/@module-federation/error-codes/dist/browser.cjs'),
57
- '@module-federation/sdk': path.resolve(dirname, 'node_modules/@module-federation/sdk'),
58
-
59
- ...Repack.getResolveOptions().alias,
60
- ...(options.alias || {}),
61
- }
62
- },
63
- module: {
64
- rules: [
65
- {
66
- oneOf: [
67
- {
68
- test: /\.[cm]?[jt]sx?$/,
69
- include: [
70
- /node_modules[\\/](react-native|@react-native|expo|expo-modules-core|@expo|react-navigation|@react-navigation|@unimodules|unimodules|native-base)/,
71
- ],
72
- type: 'javascript/auto',
73
- resolve: { fullySpecified: false },
74
- use: {
75
- loader: '@callstack/repack/babel-swc-loader',
76
- options: {
77
- babelrc: false,
78
- configFile: false,
79
- presets: [
80
- ['babel-preset-expo', { platform }],
81
- ],
82
- sourceType: 'unambiguous',
83
- caller: { name: 'repack', platform },
84
- },
85
- },
86
- },
87
- {
88
- test: /\.[cm]?[jt]sx?$/,
89
- include: [dirname],
90
- exclude: [/node_modules/],
91
- type: 'javascript/auto',
92
- use: {
93
- loader: '@callstack/repack/babel-swc-loader',
94
- options: {
95
- babelrc: true,
96
- sourceType: 'unambiguous',
97
- presets: [
98
- ['babel-preset-expo', { platform }],
99
- ],
100
- caller: { name: 'repack', platform },
101
- },
102
- },
103
- },
104
- ...Repack.getJsTransformRules(),
105
- ]
106
- },
107
- ...Repack.getAssetTransformRules(),
108
- ],
109
- },
110
- plugins: [
111
- new DefinePlugin({
112
- '__EXPO_OS__': JSON.stringify(platform),
113
- '__NODE_ENV__': JSON.stringify(isDev ? 'development' : 'production'),
114
- '__REPACK_PLATFORM__': JSON.stringify(platform),
115
- 'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'),
116
- 'process.env.EXPO_OS': JSON.stringify(platform),
117
- 'process.env.REPACK_PLATFORM': JSON.stringify(platform),
118
- '__DEV__': JSON.stringify(isDev),
119
- }),
120
- new ExpoModulesPlugin(),
121
- new Repack.RepackPlugin(),
122
- new Repack.plugins.ModuleFederationPluginV2({
123
- name: id,
124
- filename: `${id}.container.js.bundle`,
125
- remotes: options.remotes || {},
126
- ...(options.type === 'module' ? { exposes: options.exposes || {} } : {}),
127
- dts: false,
128
- dev: isDev,
129
- shared: {
130
- 'react': { singleton: true, eager: true, requiredVersion: pkg.dependencies.react },
131
- 'react/jsx-runtime': { singleton: true, eager: true, requiredVersion: pkg.dependencies.react },
132
- 'react-native': { singleton: true, eager: true, requiredVersion: pkg.dependencies['react-native'] },
133
- 'react-native-safe-area-context': { singleton: true, eager: true, requiredVersion: pkg.dependencies['react-native-safe-area-context'] },
134
- '@codemoreira/esad/client': {
135
- singleton: true,
136
- eager: options.type === 'host',
137
- version: sdkPkg.version,
138
- requiredVersion: sdkPkg.version,
139
- import: clientPath
140
- },
141
- ...(options.shared || {})
142
- }
143
- })
144
- ],
145
- experiments: {
146
- parallelLoader: false,
147
- },
148
- };
149
-
150
- // Add Host-specific DevServer magic for Expo
151
- if (options.type === 'host') {
152
- config.devServer = {
153
- setupMiddlewares: (middlewares) => {
154
- middlewares.unshift((req, res, next) => {
155
- if (req.url.startsWith('/.expo/.virtual-metro-entry.bundle')) {
156
- const query = req.url.split('?')[1];
157
- const isMap = req.url.includes('.map');
158
- const target = isMap ? '/index.bundle.map' : '/index.bundle';
159
- const location = query ? `${target}?${query}` : target;
160
- res.writeHead(302, { Location: location });
161
- res.end();
162
- return;
163
- }
164
- next();
165
- });
166
- return middlewares;
167
- },
168
- };
169
- }
170
-
171
- return config;
172
- }
173
-
174
- module.exports = { withESAD };
1
+ const path = require('node:path');
2
+ const fs = require('node:fs');
3
+ const Repack = require('@callstack/repack');
4
+ const { ExpoModulesPlugin } = require('@callstack/repack-plugin-expo-modules');
5
+
6
+ /**
7
+ * ESAD Re.Pack Plugin Wrapper (v2.0 - POC Mirror)
8
+ * Totalmente alinhado com a POC funcional para Expo 52 + Re.Pack 5.
9
+ *
10
+ * @param {Object} env Rspack environment
11
+ * @param {Object} options
12
+ */
13
+ function withESAD(env, options) {
14
+ const { platform, dev } = env;
15
+ const isDev = dev !== false;
16
+
17
+ const dirname = options.dirname;
18
+ const pkgPath = path.resolve(dirname, 'package.json');
19
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
20
+ const id = options.id.replace(/-/g, '_');
21
+
22
+ const sdkPkgPath = path.resolve(__dirname, '..', '..', 'package.json');
23
+ const sdkPkg = JSON.parse(fs.readFileSync(sdkPkgPath, 'utf8'));
24
+ const clientPath = path.resolve(__dirname, '..', 'client', 'index.js');
25
+
26
+ return Repack.defineRspackConfig({
27
+ context: dirname,
28
+ mode: isDev ? 'development' : 'production',
29
+ entry: options.entry || './index.js',
30
+ resolve: {
31
+ ...Repack.getResolveOptions(),
32
+ conditionNames: ['require', 'import', 'module', 'browser', 'react-native'],
33
+ exportsFields: ['exports'],
34
+ },
35
+ module: {
36
+ rules: [
37
+ {
38
+ test: /\.[cm]?[jt]sx?$/,
39
+ type: 'javascript/auto',
40
+ use: {
41
+ loader: '@callstack/repack/babel-swc-loader',
42
+ options: {
43
+ parallel: true,
44
+ },
45
+ },
46
+ },
47
+ ...Repack.getAssetTransformRules(),
48
+ ],
49
+ },
50
+ plugins: [
51
+ new Repack.RepackPlugin(),
52
+ new Repack.plugins.ModuleFederationPluginV2({
53
+ name: id,
54
+ filename: `${id}.container.js.bundle`,
55
+ remotes: options.remotes || {},
56
+ ...(options.type === 'module' ? {
57
+ exposes: options.exposes || {
58
+ './Main': options.entry || './index.js'
59
+ }
60
+ } : {}),
61
+ dts: false,
62
+ dev: isDev,
63
+ shared: {
64
+ 'react': { singleton: true, eager: true, requiredVersion: pkg.dependencies.react },
65
+ 'react/jsx-runtime': { singleton: true, eager: true, requiredVersion: pkg.dependencies.react },
66
+ 'react-native': { singleton: true, eager: true, requiredVersion: pkg.dependencies['react-native'] },
67
+ 'react-native-safe-area-context': { singleton: true, eager: true, requiredVersion: pkg.dependencies['react-native-safe-area-context'] },
68
+ '@codemoreira/esad/client': {
69
+ singleton: true,
70
+ eager: options.type === 'host',
71
+ version: sdkPkg.version,
72
+ requiredVersion: sdkPkg.version,
73
+ import: clientPath
74
+ },
75
+ ...(options.shared || {})
76
+ }
77
+ }),
78
+ new ExpoModulesPlugin(),
79
+ ],
80
+ });
81
+ }
82
+
83
+ module.exports = { withESAD };
@@ -0,0 +1,90 @@
1
+ const { withAppBuildGradle, withProjectBuildGradle, withMainApplication, withMainActivity, withGradleProperties, withAndroidManifest } = require('@expo/config-plugins');
2
+
3
+ /**
4
+ * ESAD Expo Config Plugin
5
+ * Automates native patches for Re.Pack 5 + Expo 52.
6
+ */
7
+ const withESADRepack = (config) => {
8
+ // 1. Disable New Architecture (Fabric) for stability with MF
9
+ config = withGradleProperties(config, (config) => {
10
+ config.modResults = config.modResults.map((item) => {
11
+ if (item.key === 'newArchEnabled') {
12
+ return { ...item, value: 'false' };
13
+ }
14
+ return item;
15
+ });
16
+ return config;
17
+ });
18
+
19
+ // 2. Adjust root build.gradle (Kotlin 1.9.25 for Compose Compiler)
20
+ config = withProjectBuildGradle(config, (config) => {
21
+ if (config.modResults.language === 'groovy') {
22
+ config.modResults.contents = config.modResults.contents.replace(
23
+ /kotlinVersion = findProperty\('android\.kotlinVersion'\) \?: '.+?'/,
24
+ "kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.25'"
25
+ );
26
+ config.modResults.contents = config.modResults.contents.replace(
27
+ /classpath\('org\.jetbrains\.kotlin:kotlin-gradle-plugin'\)/,
28
+ 'classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")'
29
+ );
30
+ }
31
+ return config;
32
+ });
33
+
34
+ // 3. Adjust app/build.gradle (bundleCommand and ABI Filters)
35
+ config = withAppBuildGradle(config, (config) => {
36
+ if (config.modResults.language === 'groovy') {
37
+ let contents = config.modResults.contents;
38
+
39
+ if (!contents.includes('bundleCommand = "repack-bundle"')) {
40
+ contents = contents.replace(
41
+ /react \{/,
42
+ 'react {\n bundleCommand = "repack-bundle"\n bundleConfig = "rspack.config.mjs"'
43
+ );
44
+ }
45
+
46
+ if (!contents.includes('abiFilters')) {
47
+ contents = contents.replace(
48
+ /defaultConfig \{/,
49
+ 'defaultConfig {\n ndk {\n abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"\n }'
50
+ );
51
+ }
52
+
53
+ config.modResults.contents = contents;
54
+ }
55
+ return config;
56
+ });
57
+
58
+ // 4. Android Manifest (Cleartext Traffic for Dev Server)
59
+ config = withAndroidManifest(config, (config) => {
60
+ const mainApplication = config.modResults.manifest.application[0];
61
+ mainApplication.$['android:usesCleartextTraffic'] = 'true';
62
+ return config;
63
+ });
64
+
65
+ // 5. MainApplication (JS Main Module Name)
66
+ config = withMainApplication(config, (config) => {
67
+ if (config.modResults.language === 'kotlin' || config.modResults.language === 'kt') {
68
+ config.modResults.contents = config.modResults.contents.replace(
69
+ /getJSMainModuleName\(\): String = .*/,
70
+ 'getJSMainModuleName(): String = "index"'
71
+ );
72
+ }
73
+ return config;
74
+ });
75
+
76
+ // 6. MainActivity (Main Component Name Sync)
77
+ config = withMainActivity(config, (config) => {
78
+ if (config.modResults.language === 'kotlin' || config.modResults.language === 'kt') {
79
+ config.modResults.contents = config.modResults.contents.replace(
80
+ /getMainComponentName\(\): String = .*/,
81
+ `getMainComponentName(): String = "${config.name}"`
82
+ );
83
+ }
84
+ return config;
85
+ });
86
+
87
+ return config;
88
+ };
89
+
90
+ module.exports = withESADRepack;
@@ -1,17 +0,0 @@
1
- /**
2
- * ESAD Runtime Environment Shim
3
- * Injected at the very beginning of the bundle to prevent "TypeError: right operand of 'in' is not an object"
4
- */
5
- var g = typeof globalThis !== 'undefined' ? globalThis : (typeof global !== 'undefined' ? global : this);
6
- if (!g['process']) {
7
- g['process'] = {};
8
- }
9
- if (!g['process']['env']) {
10
- g['process']['env'] = {};
11
- }
12
-
13
- g['process']['env']['EXPO_OS'] = '__EXPO_OS__';
14
- g['process']['env']['NODE_ENV'] = '__NODE_ENV__';
15
- g['process']['env']['REPACK_PLATFORM'] = '__REPACK_PLATFORM__';
16
-
17
-