react-native-architecture-generator 1.1.0 → 1.1.2
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
package/dist/bin/rn_arch_gen.js
CHANGED
|
@@ -8,7 +8,7 @@ const program = new Command();
|
|
|
8
8
|
program
|
|
9
9
|
.name('rn-arch-gen')
|
|
10
10
|
.description('A powerful CLI tool to instantly generate a production-ready React Native project architecture.')
|
|
11
|
-
.version('1.1.
|
|
11
|
+
.version('1.1.1');
|
|
12
12
|
program
|
|
13
13
|
.command('init')
|
|
14
14
|
.description('Initialize React Native project architecture.')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import inquirer from 'inquirer';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import ora from 'ora';
|
|
4
|
-
import { Architecture, ArchitectureLabels, StateManagement, Routing } from '../models/config.js';
|
|
4
|
+
import { Architecture, ArchitectureLabels, StateManagement, StateManagementLabels, Routing, RoutingLabels } from '../models/config.js';
|
|
5
5
|
import { FileHelper } from '../utils/file-helper.js';
|
|
6
6
|
import { FeatureHelper } from '../utils/feature-helper.js';
|
|
7
7
|
export class InitCommand {
|
|
@@ -10,27 +10,36 @@ export class InitCommand {
|
|
|
10
10
|
console.log('');
|
|
11
11
|
const answers = await inquirer.prompt([
|
|
12
12
|
{
|
|
13
|
-
type: '
|
|
13
|
+
type: 'select',
|
|
14
14
|
name: 'architecture',
|
|
15
15
|
message: 'Select architecture pattern:',
|
|
16
|
-
choices:
|
|
17
|
-
name: ArchitectureLabels[
|
|
18
|
-
value:
|
|
19
|
-
|
|
16
|
+
choices: [
|
|
17
|
+
{ name: ArchitectureLabels[Architecture.cleanArchitecture], value: Architecture.cleanArchitecture },
|
|
18
|
+
{ name: ArchitectureLabels[Architecture.featureBased], value: Architecture.featureBased },
|
|
19
|
+
{ name: ArchitectureLabels[Architecture.atomicDesign], value: Architecture.atomicDesign },
|
|
20
|
+
{ name: ArchitectureLabels[Architecture.mvvm], value: Architecture.mvvm },
|
|
21
|
+
],
|
|
20
22
|
default: Architecture.cleanArchitecture,
|
|
21
23
|
},
|
|
22
24
|
{
|
|
23
|
-
type: '
|
|
25
|
+
type: 'select',
|
|
24
26
|
name: 'stateManagement',
|
|
25
27
|
message: 'Select state management:',
|
|
26
|
-
choices:
|
|
28
|
+
choices: [
|
|
29
|
+
{ name: StateManagementLabels[StateManagement.redux], value: StateManagement.redux },
|
|
30
|
+
{ name: StateManagementLabels[StateManagement.zustand], value: StateManagement.zustand },
|
|
31
|
+
{ name: StateManagementLabels[StateManagement.context], value: StateManagement.context },
|
|
32
|
+
],
|
|
27
33
|
default: StateManagement.redux,
|
|
28
34
|
},
|
|
29
35
|
{
|
|
30
|
-
type: '
|
|
36
|
+
type: 'select',
|
|
31
37
|
name: 'routing',
|
|
32
38
|
message: 'Select routing:',
|
|
33
|
-
choices:
|
|
39
|
+
choices: [
|
|
40
|
+
{ name: RoutingLabels[Routing.reactNavigation], value: Routing.reactNavigation },
|
|
41
|
+
{ name: RoutingLabels[Routing.expoRouter], value: Routing.expoRouter },
|
|
42
|
+
],
|
|
34
43
|
default: Routing.reactNavigation,
|
|
35
44
|
},
|
|
36
45
|
{
|
|
@@ -25,3 +25,5 @@ export interface GeneratorConfig {
|
|
|
25
25
|
* Friendly display names for architecture choices.
|
|
26
26
|
*/
|
|
27
27
|
export declare const ArchitectureLabels: Record<Architecture, string>;
|
|
28
|
+
export declare const StateManagementLabels: Record<StateManagement, string>;
|
|
29
|
+
export declare const RoutingLabels: Record<Routing, string>;
|
|
@@ -25,3 +25,12 @@ export const ArchitectureLabels = {
|
|
|
25
25
|
[Architecture.atomicDesign]: '⚛️ Atomic Design + Feature (Atoms → Molecules → Organisms)',
|
|
26
26
|
[Architecture.mvvm]: '🧩 MVVM with Hooks (Model → ViewModel → View)',
|
|
27
27
|
};
|
|
28
|
+
export const StateManagementLabels = {
|
|
29
|
+
[StateManagement.redux]: 'Redux Toolkit (Professional State Management)',
|
|
30
|
+
[StateManagement.zustand]: 'Zustand (Lightweight & Fast)',
|
|
31
|
+
[StateManagement.context]: 'Context API (Built-in React State)',
|
|
32
|
+
};
|
|
33
|
+
export const RoutingLabels = {
|
|
34
|
+
[Routing.reactNavigation]: 'React Navigation (Standard & Customisable)',
|
|
35
|
+
[Routing.expoRouter]: 'Expo Router (File-based routing)',
|
|
36
|
+
};
|
|
@@ -382,11 +382,35 @@ const styles = StyleSheet.create({
|
|
|
382
382
|
const snakeName = StringUtils.toSnakeCase(name);
|
|
383
383
|
const screenDir = screenSubPath || (config.architecture === Architecture.cleanArchitecture ? 'presentation/screens' : config.architecture === Architecture.mvvm ? 'views/screens' : 'screens');
|
|
384
384
|
let contents = await fs.readFile(navFile, 'utf-8');
|
|
385
|
-
|
|
385
|
+
// 1. Add Imports
|
|
386
|
+
const imports = name === 'auth'
|
|
386
387
|
? `import { LoginScreen } from '../features/auth/${screenDir}/LoginScreen';\nimport { RegisterScreen } from '../features/auth/${screenDir}/RegisterScreen';`
|
|
387
388
|
: `import { ${pascalName}Screen } from '../features/${snakeName}/${screenDir}/${pascalName}Screen';`;
|
|
388
|
-
if (!contents.includes(
|
|
389
|
-
contents = `${
|
|
389
|
+
if (!contents.includes(imports.split('\n')[0])) {
|
|
390
|
+
contents = `${imports}\n${contents}`;
|
|
391
|
+
}
|
|
392
|
+
// 2. Add Route Parameters
|
|
393
|
+
if (name === 'auth') {
|
|
394
|
+
if (!contents.includes('Login: undefined')) {
|
|
395
|
+
contents = contents.replace('// Define your route params here', '// Define your route params here\n Login: undefined;\n Register: undefined;');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
if (!contents.includes(`${pascalName}: undefined`)) {
|
|
400
|
+
contents = contents.replace('// Define your route params here', `// Define your route params here\n ${pascalName}: undefined;`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// 3. Add Screen Components
|
|
404
|
+
if (name === 'auth') {
|
|
405
|
+
if (!contents.includes('name="Login"')) {
|
|
406
|
+
contents = contents.replace('{/* Add your screens here */}', `<Stack.Screen name="Login" component={LoginScreen} />\n <Stack.Screen name="Register" component={RegisterScreen} />\n {/* Add your screens here */}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
if (!contents.includes(`name="${pascalName}"`)) {
|
|
411
|
+
contents = contents.replace('{/* Add your screens here */}', `<Stack.Screen name="${pascalName}" component={${pascalName}Screen} />\n {/* Add your screens here */}`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
390
414
|
await fs.writeFile(navFile, contents);
|
|
391
415
|
}
|
|
392
416
|
static async generateCleanArchTest(name, _config) { }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-architecture-generator",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "A professional CLI tool to scaffold React Native apps with Clean Architecture, MVVM, Atomic Design, or Feature-Based patterns.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/lib/index.js",
|