@callstack/brownfield-cli 3.0.0-rc.2 → 3.1.0

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +1 -1
  3. package/dist/brownfield/commands/packageAndroid.d.ts.map +1 -1
  4. package/dist/brownfield/commands/packageAndroid.js +2 -0
  5. package/dist/brownfield/commands/packageIos.d.ts.map +1 -1
  6. package/dist/brownfield/commands/packageIos.js +17 -1
  7. package/dist/brownfield/commands/publishAndroid.d.ts.map +1 -1
  8. package/dist/brownfield/commands/publishAndroid.js +2 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2 -0
  11. package/dist/navigation/commands/codegen.d.ts +9 -0
  12. package/dist/navigation/commands/codegen.d.ts.map +1 -0
  13. package/dist/navigation/commands/codegen.js +24 -0
  14. package/dist/navigation/commands/index.d.ts +2 -0
  15. package/dist/navigation/commands/index.d.ts.map +1 -0
  16. package/dist/navigation/commands/index.js +1 -0
  17. package/dist/navigation/config.d.ts +6 -0
  18. package/dist/navigation/config.d.ts.map +1 -0
  19. package/dist/navigation/config.js +25 -0
  20. package/dist/navigation/generators/android.d.ts +4 -0
  21. package/dist/navigation/generators/android.d.ts.map +1 -0
  22. package/dist/navigation/generators/android.js +91 -0
  23. package/dist/navigation/generators/ios.d.ts +4 -0
  24. package/dist/navigation/generators/ios.d.ts.map +1 -0
  25. package/dist/navigation/generators/ios.js +141 -0
  26. package/dist/navigation/generators/models.d.ts +13 -0
  27. package/dist/navigation/generators/models.d.ts.map +1 -0
  28. package/dist/navigation/generators/models.js +112 -0
  29. package/dist/navigation/generators/ts.d.ts +6 -0
  30. package/dist/navigation/generators/ts.d.ts.map +1 -0
  31. package/dist/navigation/generators/ts.js +96 -0
  32. package/dist/navigation/helpers/runNavigationCodegenIfApplicable.d.ts +5 -0
  33. package/dist/navigation/helpers/runNavigationCodegenIfApplicable.d.ts.map +1 -0
  34. package/dist/navigation/helpers/runNavigationCodegenIfApplicable.js +11 -0
  35. package/dist/navigation/index.d.ts +7 -0
  36. package/dist/navigation/index.d.ts.map +1 -0
  37. package/dist/navigation/index.js +6 -0
  38. package/dist/navigation/parser.d.ts +3 -0
  39. package/dist/navigation/parser.d.ts.map +1 -0
  40. package/dist/navigation/parser.js +33 -0
  41. package/dist/navigation/runner.d.ts +8 -0
  42. package/dist/navigation/runner.d.ts.map +1 -0
  43. package/dist/navigation/runner.js +126 -0
  44. package/dist/navigation/spec-discovery.d.ts +3 -0
  45. package/dist/navigation/spec-discovery.d.ts.map +1 -0
  46. package/dist/navigation/spec-discovery.js +15 -0
  47. package/dist/navigation/types.d.ts +24 -0
  48. package/dist/navigation/types.d.ts.map +1 -0
  49. package/dist/navigation/types.js +1 -0
  50. package/package.json +7 -2
  51. package/src/brownfield/commands/packageAndroid.ts +2 -0
  52. package/src/brownfield/commands/packageIos.ts +34 -1
  53. package/src/brownfield/commands/publishAndroid.ts +2 -0
  54. package/src/index.ts +4 -0
  55. package/src/navigation/commands/codegen.ts +57 -0
  56. package/src/navigation/commands/index.ts +1 -0
  57. package/src/navigation/config.ts +35 -0
  58. package/src/navigation/generators/android.ts +127 -0
  59. package/src/navigation/generators/ios.ts +169 -0
  60. package/src/navigation/generators/models.ts +170 -0
  61. package/src/navigation/generators/ts.ts +123 -0
  62. package/src/navigation/helpers/runNavigationCodegenIfApplicable.ts +17 -0
  63. package/src/navigation/index.ts +10 -0
  64. package/src/navigation/parser.ts +43 -0
  65. package/src/navigation/runner.ts +256 -0
  66. package/src/navigation/spec-discovery.ts +25 -0
  67. package/src/navigation/types.ts +25 -0
  68. package/dist/brownfield/utils/index.d.ts +0 -4
  69. package/dist/brownfield/utils/index.d.ts.map +0 -1
  70. package/dist/brownfield/utils/index.js +0 -3
  71. package/dist/brownfield/utils/rn-cli.d.ts +0 -17
  72. package/dist/brownfield/utils/rn-cli.d.ts.map +0 -1
  73. package/dist/brownfield/utils/rn-cli.js +0 -31
package/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # @callstack/brownfield-cli
2
+
3
+ ## 3.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#236](https://github.com/callstack/react-native-brownfield/pull/236) [`3e33b89`](https://github.com/callstack/react-native-brownfield/commit/3e33b890e6f647f6bbebe32f8068a38b1ed85ea0) Thanks [@hurali97](https://github.com/hurali97)! - add brownfield navigation
8
+
9
+ ## 3.0.0
10
+
11
+ ### Patch Changes
12
+
13
+ - [#255](https://github.com/callstack/react-native-brownfield/pull/255) [`48358b2`](https://github.com/callstack/react-native-brownfield/commit/48358b2dcce578aa5052e66cc3454524da8c7992) Thanks [@artus9033](https://github.com/artus9033)! - chore: release stable v3
14
+
15
+ ## 1.0.4
16
+
17
+ ### Patch Changes
18
+
19
+ - [#216](https://github.com/callstack/react-native-brownfield/pull/216) [`8ce3ea1`](https://github.com/callstack/react-native-brownfield/commit/8ce3ea10e0719adac7396dea8f171753e901b31d) Thanks [@thymikee](https://github.com/thymikee)! - chore: remove release-it
20
+
21
+ ## 1.0.3
22
+
23
+ ### Patch Changes
24
+
25
+ - [#213](https://github.com/callstack/react-native-brownfield/pull/213) [`2347775`](https://github.com/callstack/react-native-brownfield/commit/23477753b16ee189b82c1aee3eac98a56c79f52a) Thanks [@thymikee](https://github.com/thymikee)! - feat: create brownfield package as CLI proxy
26
+
27
+ ## 1.0.2
28
+
29
+ ### Patch Changes
30
+
31
+ - [`2a8563f`](https://github.com/callstack/react-native-brownfield/commit/2a8563f65ed152054ad1290caf963791a368ee9a) Thanks [@okwasniewski](https://github.com/okwasniewski)! - feat: strip framework binaries to avoid duplicate symbol errors
32
+
33
+ ## 1.0.1
34
+
35
+ ### Patch Changes
36
+
37
+ - [#198](https://github.com/callstack/react-native-brownfield/pull/198) [`c8c903d`](https://github.com/callstack/react-native-brownfield/commit/c8c903d0d2b78a8c06a41213dfbe781a2daf3d25) Thanks [@artus9033](https://github.com/artus9033)! - docs: added README files to all packages
package/README.md CHANGED
@@ -29,7 +29,7 @@
29
29
 
30
30
  ## Documentation
31
31
 
32
- For full documentation, visit [our documentation](https://oss.callstack.com/react-native-brownfield/brownie/overview).
32
+ For full documentation, visit [our documentation](https://oss.callstack.com/react-native-brownfield/docs/cli/introduction).
33
33
 
34
34
  <a href="https://www.callstack.com/ebooks/incremental-react-native-adoption-in-native-apps?utm_campaign=brownfield&utm_source=github&utm_medium=referral&utm_content=react-native-brownfield" align="center">
35
35
  <img alt="Download a free copy of Incremental React Native adoption in native apps ebook" src="https://github.com/user-attachments/assets/ba42bb29-1e7a-4683-80c5-2602afb1a7e6">
@@ -1 +1 @@
1
- {"version":3,"file":"packageAndroid.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageAndroid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EACL,YAAY,EAGb,MAAM,uBAAuB,CAAC;AAK/B,eAAO,MAAM,qBAAqB,SAwBjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,cAGjC,CAAC"}
1
+ {"version":3,"file":"packageAndroid.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageAndroid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EACL,YAAY,EAGb,MAAM,uBAAuB,CAAC;AAM/B,eAAO,MAAM,qBAAqB,SAyBjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,cAGjC,CAAC"}
@@ -5,6 +5,7 @@ import { ExampleUsage, actionRunner, curryOptions, } from '../../shared/index.js
5
5
  import { runExpoPrebuildIfNeeded } from '../utils/expo.js';
6
6
  import { getProjectInfo } from '../utils/project.js';
7
7
  import { runBrownieCodegenIfApplicable } from '../../brownie/helpers/runBrownieCodegenIfApplicable.js';
8
+ import { runNavigationCodegenIfApplicable } from '../../navigation/helpers/runNavigationCodegenIfApplicable.js';
8
9
  export const packageAndroidCommand = curryOptions(new Command('package:android').description('Build Android AAR'), packageAarOptions.map((option) => option.name.startsWith('--variant')
9
10
  ? { ...option, default: 'debug' }
10
11
  : option)).action(actionRunner(async (options) => {
@@ -14,6 +15,7 @@ export const packageAndroidCommand = curryOptions(new Command('package:android')
14
15
  platform: 'android',
15
16
  });
16
17
  await runBrownieCodegenIfApplicable(projectRoot, 'kotlin');
18
+ await runNavigationCodegenIfApplicable(projectRoot);
17
19
  await packageAarAction({
18
20
  projectRoot,
19
21
  pluginConfig: platformConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"packageIos.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageIos.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAGL,YAAY,EACb,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,iBAAiB,SAqG7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,cAG7B,CAAC"}
1
+ {"version":3,"file":"packageIos.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageIos.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAGL,YAAY,EACb,MAAM,uBAAuB,CAAC;AAK/B,eAAO,MAAM,iBAAiB,SAqI7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,cAG7B,CAAC"}
@@ -7,6 +7,7 @@ import { runExpoPrebuildIfNeeded } from '../utils/expo.js';
7
7
  import { getProjectInfo } from '../utils/project.js';
8
8
  import { actionRunner, curryOptions, ExampleUsage, } from '../../shared/index.js';
9
9
  import { runBrownieCodegenIfApplicable } from '../../brownie/helpers/runBrownieCodegenIfApplicable.js';
10
+ import { runNavigationCodegenIfApplicable } from '../../navigation/helpers/runNavigationCodegenIfApplicable.js';
10
11
  import { stripFrameworkBinary } from '../utils/stripFrameworkBinary.js';
11
12
  export const packageIosCommand = curryOptions(new Command('package:ios').description('Build iOS XCFramework'), getBuildOptions({ platformName: 'ios' }).map((option) => option.name.startsWith('--build-folder')
12
13
  ? {
@@ -40,6 +41,7 @@ export const packageIosCommand = curryOptions(new Command('package:ios').descrip
40
41
  const packageDir = path.join(dotBrownfieldDir, 'package', 'build');
41
42
  const configuration = options.configuration ?? 'Debug';
42
43
  const { hasBrownie } = await runBrownieCodegenIfApplicable(projectRoot, 'swift');
44
+ const { hasNavigation } = await runNavigationCodegenIfApplicable(projectRoot);
43
45
  await packageIosAction(options, {
44
46
  projectRoot,
45
47
  reactNativePath: userConfig.reactNativePath,
@@ -62,11 +64,25 @@ export const packageIosCommand = curryOptions(new Command('package:ios').descrip
62
64
  ],
63
65
  outputPath: brownieOutputPath,
64
66
  });
65
- // Strip the binary from Brownie.xcframework to make it interface-only.
67
+ // Strip the binary from Browniexcframework to make it interface-only.
66
68
  // This avoids duplicate symbols when consumer apps embed both BrownfieldLib
67
69
  // (which contains Brownie symbols) and Brownie.xcframework.
68
70
  stripFrameworkBinary(brownieOutputPath);
69
71
  logger.success(`Brownie.xcframework created at ${colorLink(relativeToCwd(brownieOutputPath))}`);
70
72
  }
73
+ if (hasNavigation) {
74
+ const productsPath = path.join(options.buildFolder, 'Build', 'Products');
75
+ const brownfieldNavigationOutputPath = path.join(packageDir, 'BrownfieldNavigation.xcframework');
76
+ await mergeFrameworks({
77
+ sourceDir: userConfig.project.ios.sourceDir,
78
+ frameworkPaths: [
79
+ path.join(productsPath, `${configuration}-iphoneos`, 'BrownfieldNavigation', 'BrownfieldNavigation.framework'),
80
+ path.join(productsPath, `${configuration}-iphonesimulator`, 'BrownfieldNavigation', 'BrownfieldNavigation.framework'),
81
+ ],
82
+ outputPath: brownfieldNavigationOutputPath,
83
+ });
84
+ stripFrameworkBinary(brownfieldNavigationOutputPath);
85
+ logger.success(`BrownfieldNavigation.xcframework created at ${colorLink(relativeToCwd(brownfieldNavigationOutputPath))}`);
86
+ }
71
87
  }));
72
88
  export const packageIosExample = new ExampleUsage('package:ios --scheme BrownfieldLib --configuration Release', "Build iOS XCFramework for 'BrownfieldLib' scheme in Release configuration");
@@ -1 +1 @@
1
- {"version":3,"file":"publishAndroid.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/publishAndroid.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAGL,YAAY,EACb,MAAM,uBAAuB,CAAC;AAK/B,eAAO,MAAM,qBAAqB,SAqBjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,cAGjC,CAAC"}
1
+ {"version":3,"file":"publishAndroid.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/publishAndroid.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAGL,YAAY,EACb,MAAM,uBAAuB,CAAC;AAM/B,eAAO,MAAM,qBAAqB,SAsBjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,cAGjC,CAAC"}
@@ -5,6 +5,7 @@ import { actionRunner, curryOptions, ExampleUsage, } from '../../shared/index.js
5
5
  import { getProjectInfo } from '../utils/project.js';
6
6
  import { runExpoPrebuildIfNeeded } from '../utils/expo.js';
7
7
  import { runBrownieCodegenIfApplicable } from '../../brownie/helpers/runBrownieCodegenIfApplicable.js';
8
+ import { runNavigationCodegenIfApplicable } from '../../navigation/helpers/runNavigationCodegenIfApplicable.js';
8
9
  export const publishAndroidCommand = curryOptions(new Command('publish:android').description('Publish Android package to Maven local'), publishLocalAarOptions).action(actionRunner(async (options) => {
9
10
  const { projectRoot, platformConfig } = getProjectInfo('android');
10
11
  await runExpoPrebuildIfNeeded({
@@ -12,6 +13,7 @@ export const publishAndroidCommand = curryOptions(new Command('publish:android')
12
13
  platform: 'android',
13
14
  });
14
15
  await runBrownieCodegenIfApplicable(projectRoot, 'kotlin');
16
+ await runNavigationCodegenIfApplicable(projectRoot);
15
17
  await publishLocalAarAction({
16
18
  projectRoot,
17
19
  pluginConfig: platformConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA6EA,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAM3C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiFA,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAM3C"}
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import { Command } from 'commander';
4
4
  import { ExampleUsage } from './shared/index.js';
5
5
  import brownfieldCommands, { groupName as brownfieldCommandsGroupName, } from './brownfield/index.js';
6
6
  import brownieCommands, { groupName as brownieCommandsGroupName, } from './brownie/index.js';
7
+ import navigationCommands, { groupName as navigationCommandsGroupName, } from './navigation/index.js';
7
8
  const program = new Command();
8
9
  program
9
10
  .name(styleText('magenta', 'brownfield'))
@@ -46,6 +47,7 @@ function registrationHelper(commandsRegistration, groupName) {
46
47
  }
47
48
  registrationHelper(brownfieldCommands, brownfieldCommandsGroupName);
48
49
  registrationHelper(brownieCommands, brownieCommandsGroupName);
50
+ registrationHelper(navigationCommands, navigationCommandsGroupName);
49
51
  program.commandsGroup('Utility commands').helpCommand('help [command]');
50
52
  export function runCLI(argv) {
51
53
  program.parse(argv);
@@ -0,0 +1,9 @@
1
+ import { Command } from 'commander';
2
+ interface NavigationCodegenActionOptions {
3
+ specPath?: string;
4
+ dryRun?: boolean;
5
+ }
6
+ export declare function runNavigationCodegenCommand({ specPath, dryRun, }: NavigationCodegenActionOptions): Promise<void>;
7
+ export declare const navigationCodegenCommand: Command;
8
+ export {};
9
+ //# sourceMappingURL=codegen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../../src/navigation/commands/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,UAAU,8BAA8B;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,2BAA2B,CAAC,EAChD,QAAQ,EACR,MAAc,GACf,EAAE,8BAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhD;AAED,eAAO,MAAM,wBAAwB,SA6BlC,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { Command } from 'commander';
2
+ import { intro, outro } from '@rock-js/tools';
3
+ import { actionRunner } from '../../shared/index.js';
4
+ import { runNavigationCodegen } from '../runner.js';
5
+ export async function runNavigationCodegenCommand({ specPath, dryRun = false, }) {
6
+ intro('Running Brownfield Navigation codegen');
7
+ await runNavigationCodegen({
8
+ specPath,
9
+ dryRun,
10
+ });
11
+ outro('Done!');
12
+ }
13
+ export const navigationCodegenCommand = new Command('navigation:codegen')
14
+ .description('Generate Brownfield Navigation native bindings from brownfield.navigation.ts')
15
+ .argument('[specPath]', 'Path to navigation spec file (defaults to brownfield.navigation.ts)')
16
+ .option('--dry-run', 'Print generated code without writing files')
17
+ .action(actionRunner(async (...args) => {
18
+ const specPath = typeof args[0] === 'string' ? args[0] : undefined;
19
+ const options = args.find((arg) => typeof arg === 'object' && arg !== null && 'dryRun' in arg) ?? {};
20
+ await runNavigationCodegenCommand({
21
+ specPath,
22
+ dryRun: Boolean(options.dryRun),
23
+ });
24
+ }));
@@ -0,0 +1,2 @@
1
+ export * from './codegen.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/navigation/commands/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './codegen.js';
@@ -0,0 +1,6 @@
1
+ export declare const NAVIGATION_PACKAGE_NAME = "@callstack/brownfield-navigation";
2
+ export declare const DEFAULT_SPEC_FILENAME = "brownfield.navigation.ts";
3
+ export declare const DEFAULT_ANDROID_JAVA_PACKAGE = "com.callstack.nativebrownfieldnavigation";
4
+ export declare function isNavigationInstalled(projectRoot?: string): boolean;
5
+ export declare function getNavigationPackagePath(projectRoot?: string): string;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/navigation/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,uBAAuB,qCAAqC,CAAC;AAC1E,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAChE,eAAO,MAAM,4BAA4B,6CACG,CAAC;AAE7C,wBAAgB,qBAAqB,CACnC,WAAW,GAAE,MAAsB,GAClC,OAAO,CAQT;AAED,wBAAgB,wBAAwB,CACtC,WAAW,GAAE,MAAsB,GAClC,MAAM,CAYR"}
@@ -0,0 +1,25 @@
1
+ import path from 'node:path';
2
+ import { createRequire } from 'node:module';
3
+ export const NAVIGATION_PACKAGE_NAME = '@callstack/brownfield-navigation';
4
+ export const DEFAULT_SPEC_FILENAME = 'brownfield.navigation.ts';
5
+ export const DEFAULT_ANDROID_JAVA_PACKAGE = 'com.callstack.nativebrownfieldnavigation';
6
+ export function isNavigationInstalled(projectRoot = process.cwd()) {
7
+ const require = createRequire(path.join(projectRoot, 'package.json'));
8
+ try {
9
+ require.resolve(`${NAVIGATION_PACKAGE_NAME}/package.json`);
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ export function getNavigationPackagePath(projectRoot = process.cwd()) {
17
+ const require = createRequire(path.join(projectRoot, 'package.json'));
18
+ try {
19
+ const packageJsonPath = require.resolve(`${NAVIGATION_PACKAGE_NAME}/package.json`);
20
+ return path.dirname(packageJsonPath);
21
+ }
22
+ catch {
23
+ throw new Error(`${NAVIGATION_PACKAGE_NAME} is not installed. Run 'npm install ${NAVIGATION_PACKAGE_NAME}' or 'yarn add ${NAVIGATION_PACKAGE_NAME}'`);
24
+ }
25
+ }
@@ -0,0 +1,4 @@
1
+ import type { MethodSignature } from '../types.js';
2
+ export declare function generateKotlinDelegate(methods: MethodSignature[], kotlinPackageName: string): string;
3
+ export declare function generateKotlinModule(methods: MethodSignature[], kotlinPackageName: string): string;
4
+ //# sourceMappingURL=android.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"android.d.ts","sourceRoot":"","sources":["../../../src/navigation/generators/android.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAwBnD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EAAE,EAC1B,iBAAiB,EAAE,MAAM,GACxB,MAAM,CAuBR;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,eAAe,EAAE,EAC1B,iBAAiB,EAAE,MAAM,GACxB,MAAM,CAiCR"}
@@ -0,0 +1,91 @@
1
+ const TS_TO_KOTLIN_TYPE = {
2
+ string: 'String',
3
+ number: 'Double',
4
+ boolean: 'Boolean',
5
+ void: 'Unit',
6
+ Object: 'ReadableMap',
7
+ };
8
+ function mapTsTypeToKotlin(tsType, optional = false) {
9
+ if (tsType.startsWith('Promise<')) {
10
+ const inner = tsType.slice(8, -1);
11
+ return mapTsTypeToKotlin(inner, optional);
12
+ }
13
+ const mapped = TS_TO_KOTLIN_TYPE[tsType];
14
+ if (mapped) {
15
+ return optional ? `${mapped}?` : mapped;
16
+ }
17
+ return optional ? 'Any?' : 'Any';
18
+ }
19
+ export function generateKotlinDelegate(methods, kotlinPackageName) {
20
+ const methodSignatures = methods
21
+ .map((method) => {
22
+ const params = method.params
23
+ .map((param) => `${param.name}: ${mapTsTypeToKotlin(param.type, param.optional)}`)
24
+ .join(', ');
25
+ const returnType = method.returnType === 'void'
26
+ ? ''
27
+ : `: ${mapTsTypeToKotlin(method.returnType, false)}`;
28
+ return ` fun ${method.name}(${params})${returnType}`;
29
+ })
30
+ .join('\n');
31
+ return `package ${kotlinPackageName}
32
+
33
+ interface BrownfieldNavigationDelegate {
34
+ ${methodSignatures}
35
+ }
36
+ `;
37
+ }
38
+ export function generateKotlinModule(methods, kotlinPackageName) {
39
+ const hasAsyncMethod = methods.some((method) => method.isAsync);
40
+ const hasObjectType = methods.some((method) => method.returnType.includes('Object') ||
41
+ method.params.some((param) => param.type === 'Object'));
42
+ const methodImplementations = methods
43
+ .map((method) => method.isAsync
44
+ ? generateAsyncKotlinMethod(method)
45
+ : generateSyncKotlinMethod(method))
46
+ .join('\n\n');
47
+ return `package ${kotlinPackageName}
48
+
49
+ import com.facebook.react.bridge.ReactApplicationContext
50
+ import com.facebook.react.bridge.ReactMethod${hasAsyncMethod ? '\nimport com.facebook.react.bridge.Promise' : ''}${hasObjectType ? '\nimport com.facebook.react.bridge.ReadableMap' : ''}
51
+
52
+ class NativeBrownfieldNavigationModule(
53
+ reactContext: ReactApplicationContext
54
+ ) : NativeBrownfieldNavigationSpec(reactContext) {
55
+ ${methodImplementations}
56
+
57
+ companion object {
58
+ const val NAME = "NativeBrownfieldNavigation"
59
+ }
60
+ }
61
+ `;
62
+ }
63
+ function generateSyncKotlinMethod(method) {
64
+ const params = method.params
65
+ .map((param) => `${param.name}: ${mapTsTypeToKotlin(param.type, param.optional)}`)
66
+ .join(', ');
67
+ const args = method.params.map((param) => param.name).join(', ');
68
+ const signature = ` @ReactMethod\n override fun ${method.name}(${params})${method.returnType === 'void'
69
+ ? ''
70
+ : `: ${mapTsTypeToKotlin(method.returnType, false)}`}`;
71
+ if (method.returnType === 'void') {
72
+ return `${signature} {
73
+ BrownfieldNavigationManager.getDelegate().${method.name}(${args})
74
+ }`;
75
+ }
76
+ return `${signature} {
77
+ return BrownfieldNavigationManager.getDelegate().${method.name}(${args})
78
+ }`;
79
+ }
80
+ function generateAsyncKotlinMethod(method) {
81
+ const paramsWithTypes = method.params
82
+ .map((param) => `${param.name}: ${mapTsTypeToKotlin(param.type, param.optional)}`)
83
+ .join(', ');
84
+ const params = paramsWithTypes.length > 0
85
+ ? `${paramsWithTypes}, promise: Promise`
86
+ : 'promise: Promise';
87
+ return ` @ReactMethod
88
+ override fun ${method.name}(${params}) {
89
+ promise.reject("not_implemented", "${method.name} is not implemented")
90
+ }`;
91
+ }
@@ -0,0 +1,4 @@
1
+ import type { MethodSignature } from '../types.js';
2
+ export declare function generateSwiftDelegate(methods: MethodSignature[]): string;
3
+ export declare function generateObjCImplementation(methods: MethodSignature[]): string;
4
+ //# sourceMappingURL=ios.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ios.d.ts","sourceRoot":"","sources":["../../../src/navigation/generators/ios.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgDnD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CA0BxE;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAgC7E"}
@@ -0,0 +1,141 @@
1
+ const TS_TO_OBJC_TYPE = {
2
+ string: 'NSString *',
3
+ number: 'double',
4
+ boolean: 'BOOL',
5
+ void: 'void',
6
+ Object: 'NSDictionary *',
7
+ };
8
+ const TS_TO_SWIFT_TYPE = {
9
+ string: 'String',
10
+ number: 'Double',
11
+ boolean: 'Bool',
12
+ void: 'Void',
13
+ Object: '[String: Any]',
14
+ };
15
+ function mapTsTypeToObjC(tsType, nullable = false) {
16
+ if (tsType.startsWith('Promise<')) {
17
+ return 'void';
18
+ }
19
+ const mapped = TS_TO_OBJC_TYPE[tsType];
20
+ if (mapped) {
21
+ if (nullable && mapped.includes('*')) {
22
+ return mapped.replace(' *', ' * _Nullable');
23
+ }
24
+ return mapped;
25
+ }
26
+ return nullable ? 'id _Nullable' : 'id';
27
+ }
28
+ function mapTsTypeToSwift(tsType, optional = false) {
29
+ if (tsType.startsWith('Promise<')) {
30
+ const inner = tsType.slice(8, -1);
31
+ return mapTsTypeToSwift(inner, optional);
32
+ }
33
+ const mapped = TS_TO_SWIFT_TYPE[tsType];
34
+ if (mapped) {
35
+ return optional ? `${mapped}?` : mapped;
36
+ }
37
+ return optional ? 'Any?' : 'Any';
38
+ }
39
+ export function generateSwiftDelegate(methods) {
40
+ const protocolMethods = methods
41
+ .map((method) => {
42
+ const params = method.params
43
+ .map((param, index) => {
44
+ const swiftType = mapTsTypeToSwift(param.type, param.optional);
45
+ const label = index === 0 ? '_' : param.name;
46
+ return `${label} ${param.name}: ${swiftType}`;
47
+ })
48
+ .join(', ');
49
+ const returnType = method.returnType === 'void'
50
+ ? ''
51
+ : ` -> ${mapTsTypeToSwift(method.returnType, false)}`;
52
+ return ` @objc func ${method.name}(${params})${returnType}`;
53
+ })
54
+ .join('\n');
55
+ return `import Foundation
56
+
57
+ @objc public protocol BrownfieldNavigationDelegate: AnyObject {
58
+ ${protocolMethods}
59
+ }
60
+ `;
61
+ }
62
+ export function generateObjCImplementation(methods) {
63
+ const methodImplementations = methods
64
+ .map((method) => method.isAsync ? generateAsyncObjCMethod(method) : generateSyncObjCMethod(method))
65
+ .join('\n\n');
66
+ return `#import "NativeBrownfieldNavigation.h"
67
+
68
+ #if __has_include("BrownfieldNavigation/BrownfieldNavigation-Swift.h")
69
+ #import "BrownfieldNavigation/BrownfieldNavigation-Swift.h"
70
+ #else
71
+ #import "BrownfieldNavigation-Swift.h"
72
+ #endif
73
+
74
+ @implementation NativeBrownfieldNavigation
75
+
76
+ ${methodImplementations}
77
+
78
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
79
+ (const facebook::react::ObjCTurboModule::InitParams &)params
80
+ {
81
+ return std::make_shared<facebook::react::NativeBrownfieldNavigationSpecJSI>(params);
82
+ }
83
+
84
+ + (NSString *)moduleName
85
+ {
86
+ return @"NativeBrownfieldNavigation";
87
+ }
88
+
89
+ @end
90
+ `;
91
+ }
92
+ function generateSyncObjCMethod(method) {
93
+ const { name, params, returnType } = method;
94
+ let signature = `- (${mapTsTypeToObjC(returnType)})${name}`;
95
+ if (params.length > 0) {
96
+ signature += params
97
+ .map((param, index) => {
98
+ const prefix = index === 0 ? ':' : ` ${param.name}:`;
99
+ return `${prefix}(${mapTsTypeToObjC(param.type, param.optional)})${param.name}`;
100
+ })
101
+ .join('');
102
+ }
103
+ let delegateCall = `[[[BrownfieldNavigationManager shared] getDelegate] ${name}`;
104
+ if (params.length > 0) {
105
+ delegateCall += params
106
+ .map((param, index) => {
107
+ const label = index === 0 ? '' : param.name;
108
+ return `${label}:${param.name}`;
109
+ })
110
+ .join(' ');
111
+ }
112
+ delegateCall += ']';
113
+ const returnPrefix = returnType === 'void' ? '' : 'return ';
114
+ return `${signature} {
115
+ ${returnPrefix}${delegateCall};
116
+ }`;
117
+ }
118
+ function generateAsyncObjCMethod(method) {
119
+ const { name, params } = method;
120
+ let signature = `- (void)${name}`;
121
+ const allParams = [
122
+ ...params,
123
+ { name: 'resolve', type: 'RCTPromiseResolveBlock', optional: false },
124
+ { name: 'reject', type: 'RCTPromiseRejectBlock', optional: false },
125
+ ];
126
+ signature += ':';
127
+ signature += allParams
128
+ .map((param, index) => {
129
+ const prefix = index === 0 ? '' : param.name;
130
+ const type = param.type === 'RCTPromiseResolveBlock'
131
+ ? 'RCTPromiseResolveBlock'
132
+ : param.type === 'RCTPromiseRejectBlock'
133
+ ? 'RCTPromiseRejectBlock'
134
+ : mapTsTypeToObjC(param.type, param.optional);
135
+ return `${prefix}(${type})${param.name}`;
136
+ })
137
+ .join(' ');
138
+ return `${signature} {
139
+ reject(@"not_implemented", @"${name} is not implemented", nil);
140
+ }`;
141
+ }
@@ -0,0 +1,13 @@
1
+ import type { MethodSignature } from '../types.js';
2
+ export interface NavigationModelsOptions {
3
+ specPath: string;
4
+ methods: MethodSignature[];
5
+ kotlinPackageName: string;
6
+ }
7
+ export interface GeneratedNavigationModels {
8
+ swiftModels?: string;
9
+ kotlinModels?: string;
10
+ modelTypeNames: string[];
11
+ }
12
+ export declare function generateNavigationModels({ specPath, methods, kotlinPackageName, }: NavigationModelsOptions): Promise<GeneratedNavigationModels>;
13
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../src/navigation/generators/models.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAkGD,wBAAsB,wBAAwB,CAAC,EAC7C,QAAQ,EACR,OAAO,EACP,iBAAiB,GAClB,EAAE,uBAAuB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CA6C9D"}
@@ -0,0 +1,112 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { FetchingJSONSchemaStore, InputData, JSONSchemaInput, quicktype, } from 'quicktype-core';
4
+ import { schemaForTypeScriptSources } from 'quicktype-typescript-input';
5
+ const SKIP_TYPE_TOKENS = new Set([
6
+ 'Array',
7
+ 'Date',
8
+ 'Map',
9
+ 'Object',
10
+ 'Promise',
11
+ 'ReadonlyArray',
12
+ 'Record',
13
+ 'Set',
14
+ 'any',
15
+ 'boolean',
16
+ 'false',
17
+ 'null',
18
+ 'number',
19
+ 'object',
20
+ 'string',
21
+ 'true',
22
+ 'undefined',
23
+ 'unknown',
24
+ 'void',
25
+ ]);
26
+ function collectReferencedTypes(methods) {
27
+ const referenced = new Set();
28
+ for (const method of methods) {
29
+ const typeTexts = [
30
+ method.returnType,
31
+ ...method.params.map((param) => param.type),
32
+ ];
33
+ for (const typeText of typeTexts) {
34
+ const matches = typeText.match(/\b[A-Za-z_]\w*\b/g);
35
+ if (!matches) {
36
+ continue;
37
+ }
38
+ for (const match of matches) {
39
+ if (!SKIP_TYPE_TOKENS.has(match)) {
40
+ referenced.add(match);
41
+ }
42
+ }
43
+ }
44
+ }
45
+ return referenced;
46
+ }
47
+ async function generateModelsForLanguage({ typeNames, schema, lang, kotlinPackageName, }) {
48
+ const schemaInput = new JSONSchemaInput(new FetchingJSONSchemaStore());
49
+ for (const typeName of typeNames) {
50
+ const rootSchema = JSON.parse(JSON.stringify(schema));
51
+ rootSchema.$ref = `#/definitions/${typeName}`;
52
+ await schemaInput.addSource({
53
+ name: typeName,
54
+ schema: JSON.stringify(rootSchema),
55
+ });
56
+ }
57
+ const inputData = new InputData();
58
+ inputData.addInput(schemaInput);
59
+ const rendererOptions = lang === 'swift'
60
+ ? {
61
+ 'access-level': 'public',
62
+ 'mutable-properties': 'true',
63
+ initializers: 'false',
64
+ 'swift-5-support': 'true',
65
+ }
66
+ : {
67
+ framework: 'just-types',
68
+ package: kotlinPackageName,
69
+ };
70
+ const { lines } = await quicktype({
71
+ inputData,
72
+ lang,
73
+ rendererOptions,
74
+ });
75
+ return lines.join('\n');
76
+ }
77
+ export async function generateNavigationModels({ specPath, methods, kotlinPackageName, }) {
78
+ const absoluteSpecPath = path.resolve(process.cwd(), specPath);
79
+ if (!fs.existsSync(absoluteSpecPath)) {
80
+ throw new Error(`Spec file not found: ${absoluteSpecPath}`);
81
+ }
82
+ const schemaData = schemaForTypeScriptSources([absoluteSpecPath]);
83
+ if (!schemaData.schema) {
84
+ throw new Error('Failed to generate schema from TypeScript spec');
85
+ }
86
+ const parsedSchema = JSON.parse(schemaData.schema);
87
+ const referencedTypes = collectReferencedTypes(methods);
88
+ const definitions = parsedSchema.definitions ?? {};
89
+ const modelTypeNames = [...referencedTypes].filter((typeName) => Object.hasOwn(definitions, typeName));
90
+ if (modelTypeNames.length === 0) {
91
+ return { modelTypeNames: [] };
92
+ }
93
+ const [swiftModels, kotlinModels] = await Promise.all([
94
+ generateModelsForLanguage({
95
+ typeNames: modelTypeNames,
96
+ schema: parsedSchema,
97
+ lang: 'swift',
98
+ kotlinPackageName,
99
+ }),
100
+ generateModelsForLanguage({
101
+ typeNames: modelTypeNames,
102
+ schema: parsedSchema,
103
+ lang: 'kotlin',
104
+ kotlinPackageName,
105
+ }),
106
+ ]);
107
+ return {
108
+ swiftModels,
109
+ kotlinModels,
110
+ modelTypeNames,
111
+ };
112
+ }
@@ -0,0 +1,6 @@
1
+ import type { MethodSignature } from '../types.js';
2
+ export declare function generateTurboModuleSpec(methods: MethodSignature[]): string;
3
+ export declare function generateIndexTs(methods: MethodSignature[]): string;
4
+ export declare function transpileWithConsumerBabel(tsCode: string, projectRoot: string, packageRoot: string): string;
5
+ export declare function generateIndexDts(methods: MethodSignature[]): string;
6
+ //# sourceMappingURL=ts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts.d.ts","sourceRoot":"","sources":["../../../src/navigation/generators/ts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAoB1E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CA6BlE;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,MAAM,CA0CR;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAgBnE"}