@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
@@ -0,0 +1,256 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import { logger } from '@rock-js/tools';
5
+ import {
6
+ DEFAULT_ANDROID_JAVA_PACKAGE,
7
+ getNavigationPackagePath,
8
+ } from './config.js';
9
+ import { parseNavigationSpec } from './parser.js';
10
+ import { resolveNavigationSpecPath } from './spec-discovery.js';
11
+ import {
12
+ generateIndexDts,
13
+ generateIndexTs,
14
+ generateTurboModuleSpec,
15
+ transpileWithConsumerBabel,
16
+ } from './generators/ts.js';
17
+ import {
18
+ generateObjCImplementation,
19
+ generateSwiftDelegate,
20
+ } from './generators/ios.js';
21
+ import {
22
+ generateKotlinDelegate,
23
+ generateKotlinModule,
24
+ } from './generators/android.js';
25
+ import { generateNavigationModels } from './generators/models.js';
26
+ import type { GeneratedNavigationArtifacts } from './types.js';
27
+
28
+ interface RunNavigationCodegenOptions {
29
+ specPath?: string;
30
+ dryRun?: boolean;
31
+ projectRoot?: string;
32
+ }
33
+
34
+ interface NavigationOutputPaths {
35
+ turboModuleSpec: string;
36
+ navigationTs: string;
37
+ commonjsIndexJs: string;
38
+ moduleIndexJs: string;
39
+ commonjsIndexDts: string;
40
+ moduleIndexDts: string;
41
+ swiftDelegate: string;
42
+ swiftModels: string;
43
+ objcImplementation: string;
44
+ kotlinDelegate: string;
45
+ kotlinModule: string;
46
+ kotlinModels: string;
47
+ }
48
+
49
+ function getOutputPaths(
50
+ packageRoot: string,
51
+ androidJavaPackageName: string
52
+ ): NavigationOutputPaths {
53
+ const androidPackagePathSegments = androidJavaPackageName.split('.');
54
+
55
+ return {
56
+ turboModuleSpec: path.join(packageRoot, 'src', 'NativeBrownfieldNavigation.ts'),
57
+ navigationTs: path.join(packageRoot, 'src', 'index.ts'),
58
+ commonjsIndexJs: path.join(packageRoot, 'lib', 'commonjs', 'index.js'),
59
+ moduleIndexJs: path.join(packageRoot, 'lib', 'module', 'index.js'),
60
+ commonjsIndexDts: path.join(
61
+ packageRoot,
62
+ 'lib',
63
+ 'typescript',
64
+ 'commonjs',
65
+ 'src',
66
+ 'index.d.ts'
67
+ ),
68
+ moduleIndexDts: path.join(
69
+ packageRoot,
70
+ 'lib',
71
+ 'typescript',
72
+ 'module',
73
+ 'src',
74
+ 'index.d.ts'
75
+ ),
76
+ swiftDelegate: path.join(
77
+ packageRoot,
78
+ 'ios',
79
+ 'BrownfieldNavigationDelegate.swift'
80
+ ),
81
+ swiftModels: path.join(packageRoot, 'ios', 'BrownfieldNavigationModels.swift'),
82
+ objcImplementation: path.join(
83
+ packageRoot,
84
+ 'ios',
85
+ 'NativeBrownfieldNavigation.mm'
86
+ ),
87
+ kotlinDelegate: path.join(
88
+ packageRoot,
89
+ 'android',
90
+ 'src',
91
+ 'main',
92
+ 'java',
93
+ ...androidPackagePathSegments,
94
+ 'BrownfieldNavigationDelegate.kt'
95
+ ),
96
+ kotlinModule: path.join(
97
+ packageRoot,
98
+ 'android',
99
+ 'src',
100
+ 'main',
101
+ 'java',
102
+ ...androidPackagePathSegments,
103
+ 'NativeBrownfieldNavigationModule.kt'
104
+ ),
105
+ kotlinModels: path.join(
106
+ packageRoot,
107
+ 'android',
108
+ 'src',
109
+ 'main',
110
+ 'java',
111
+ ...androidPackagePathSegments,
112
+ 'BrownfieldNavigationModels.kt'
113
+ ),
114
+ };
115
+ }
116
+
117
+ function writeArtifacts(
118
+ paths: NavigationOutputPaths,
119
+ artifacts: GeneratedNavigationArtifacts
120
+ ): void {
121
+ fs.writeFileSync(paths.turboModuleSpec, artifacts.turboModuleSpec);
122
+ logger.success(`Generated ${paths.turboModuleSpec}`);
123
+
124
+ fs.writeFileSync(paths.navigationTs, artifacts.indexTs);
125
+ logger.success(`Generated ${paths.navigationTs}`);
126
+
127
+ fs.writeFileSync(paths.commonjsIndexJs, artifacts.indexJs);
128
+ logger.success(`Generated ${paths.commonjsIndexJs}`);
129
+
130
+ fs.writeFileSync(paths.moduleIndexJs, artifacts.indexJs);
131
+ logger.success(`Generated ${paths.moduleIndexJs}`);
132
+
133
+ fs.writeFileSync(paths.commonjsIndexDts, artifacts.indexDts);
134
+ logger.success(`Generated ${paths.commonjsIndexDts}`);
135
+
136
+ fs.writeFileSync(paths.moduleIndexDts, artifacts.indexDts);
137
+ logger.success(`Generated ${paths.moduleIndexDts}`);
138
+
139
+ fs.writeFileSync(paths.swiftDelegate, artifacts.swiftDelegate);
140
+ logger.success(`Generated ${paths.swiftDelegate}`);
141
+
142
+ if (artifacts.swiftModels) {
143
+ fs.writeFileSync(paths.swiftModels, artifacts.swiftModels);
144
+ logger.success(`Generated ${paths.swiftModels}`);
145
+ }
146
+
147
+ fs.writeFileSync(paths.objcImplementation, artifacts.objcImplementation);
148
+ logger.success(`Generated ${paths.objcImplementation}`);
149
+
150
+ fs.writeFileSync(paths.kotlinDelegate, artifacts.kotlinDelegate);
151
+ logger.success(`Generated ${paths.kotlinDelegate}`);
152
+
153
+ fs.writeFileSync(paths.kotlinModule, artifacts.kotlinModule);
154
+ logger.success(`Generated ${paths.kotlinModule}`);
155
+
156
+ if (artifacts.kotlinModels) {
157
+ fs.writeFileSync(paths.kotlinModels, artifacts.kotlinModels);
158
+ logger.success(`Generated ${paths.kotlinModels}`);
159
+ }
160
+ }
161
+
162
+ function printDryRun(
163
+ androidJavaPackageName: string,
164
+ artifacts: GeneratedNavigationArtifacts
165
+ ): void {
166
+ logger.info('\n--- Generated: src/NativeBrownfieldNavigation.ts ---\n');
167
+ logger.log(artifacts.turboModuleSpec);
168
+ logger.info('\n--- Generated: src/index.ts ---\n');
169
+ logger.log(artifacts.indexTs);
170
+ logger.info('\n--- Generated (Babel): lib/{commonjs,module}/index.js ---\n');
171
+ logger.log(artifacts.indexJs);
172
+ logger.info(
173
+ '\n--- Generated: lib/typescript/{commonjs,module}/src/index.d.ts ---\n'
174
+ );
175
+ logger.log(artifacts.indexDts);
176
+ logger.info('\n--- Generated: ios/BrownfieldNavigationDelegate.swift ---\n');
177
+ logger.log(artifacts.swiftDelegate);
178
+ if (artifacts.swiftModels) {
179
+ logger.info('\n--- Generated: ios/BrownfieldNavigationModels.swift ---\n');
180
+ logger.log(artifacts.swiftModels);
181
+ }
182
+ logger.info('\n--- Generated: ios/NativeBrownfieldNavigation.mm ---\n');
183
+ logger.log(artifacts.objcImplementation);
184
+ logger.info(
185
+ `\n--- Generated: android/src/main/java/${androidJavaPackageName.replaceAll('.', '/')}/BrownfieldNavigationDelegate.kt ---\n`
186
+ );
187
+ logger.log(artifacts.kotlinDelegate);
188
+ logger.info(
189
+ `\n--- Generated: android/src/main/java/${androidJavaPackageName.replaceAll('.', '/')}/NativeBrownfieldNavigationModule.kt ---\n`
190
+ );
191
+ logger.log(artifacts.kotlinModule);
192
+ if (artifacts.kotlinModels) {
193
+ logger.info(
194
+ `\n--- Generated: android/src/main/java/${androidJavaPackageName.replaceAll('.', '/')}/BrownfieldNavigationModels.kt ---\n`
195
+ );
196
+ logger.log(artifacts.kotlinModels);
197
+ }
198
+ }
199
+
200
+ export async function runNavigationCodegen({
201
+ specPath,
202
+ dryRun = false,
203
+ projectRoot = process.cwd(),
204
+ }: RunNavigationCodegenOptions): Promise<void> {
205
+ const resolvedSpecPath = resolveNavigationSpecPath(specPath, projectRoot);
206
+ if (!fs.existsSync(resolvedSpecPath)) {
207
+ throw new Error(`Spec file not found: ${resolvedSpecPath}`);
208
+ }
209
+
210
+ logger.info(`Parsing spec file: ${resolvedSpecPath}`);
211
+ const methods = parseNavigationSpec(resolvedSpecPath);
212
+ if (methods.length === 0) {
213
+ throw new Error('No methods found in spec file');
214
+ }
215
+
216
+ logger.info(
217
+ `Found ${methods.length} method(s): ${methods.map((method) => method.name).join(', ')}`
218
+ );
219
+
220
+ const packageRoot = getNavigationPackagePath(projectRoot);
221
+ const androidJavaPackageName = DEFAULT_ANDROID_JAVA_PACKAGE;
222
+ const indexTs = generateIndexTs(methods);
223
+ const models = await generateNavigationModels({
224
+ specPath: resolvedSpecPath,
225
+ methods,
226
+ kotlinPackageName: androidJavaPackageName,
227
+ });
228
+
229
+ const artifacts: GeneratedNavigationArtifacts = {
230
+ turboModuleSpec: generateTurboModuleSpec(methods),
231
+ indexTs,
232
+ indexJs: transpileWithConsumerBabel(indexTs, projectRoot, packageRoot),
233
+ indexDts: generateIndexDts(methods),
234
+ swiftDelegate: generateSwiftDelegate(methods),
235
+ objcImplementation: generateObjCImplementation(methods),
236
+ kotlinDelegate: generateKotlinDelegate(methods, androidJavaPackageName),
237
+ kotlinModule: generateKotlinModule(methods, androidJavaPackageName),
238
+ };
239
+
240
+ if (models.modelTypeNames.length > 0) {
241
+ logger.info(
242
+ `Generating quicktype models for types: ${models.modelTypeNames.join(', ')}`
243
+ );
244
+ artifacts.swiftModels = models.swiftModels;
245
+ artifacts.kotlinModels = models.kotlinModels;
246
+ } else {
247
+ logger.info('No complex model types found; skipping quicktype model generation');
248
+ }
249
+
250
+ if (dryRun) {
251
+ printDryRun(androidJavaPackageName, artifacts);
252
+ return;
253
+ }
254
+
255
+ writeArtifacts(getOutputPaths(packageRoot, androidJavaPackageName), artifacts);
256
+ }
@@ -0,0 +1,25 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import { DEFAULT_SPEC_FILENAME } from './config.js';
5
+
6
+ export function resolveNavigationSpecPath(
7
+ specPath: string | undefined,
8
+ projectRoot: string
9
+ ): string {
10
+ if (specPath) {
11
+ return path.isAbsolute(specPath)
12
+ ? specPath
13
+ : path.resolve(projectRoot, specPath);
14
+ }
15
+
16
+ return path.resolve(projectRoot, DEFAULT_SPEC_FILENAME);
17
+ }
18
+
19
+ export function isNavigationSpecPresent(
20
+ specPath: string | undefined,
21
+ projectRoot: string = process.cwd()
22
+ ): boolean {
23
+ const resolvedSpecPath = resolveNavigationSpecPath(specPath, projectRoot);
24
+ return fs.existsSync(resolvedSpecPath);
25
+ }
@@ -0,0 +1,25 @@
1
+ export interface MethodParam {
2
+ name: string;
3
+ type: string;
4
+ optional: boolean;
5
+ }
6
+
7
+ export interface MethodSignature {
8
+ name: string;
9
+ params: MethodParam[];
10
+ returnType: string;
11
+ isAsync: boolean;
12
+ }
13
+
14
+ export interface GeneratedNavigationArtifacts {
15
+ turboModuleSpec: string;
16
+ indexTs: string;
17
+ indexJs: string;
18
+ indexDts: string;
19
+ swiftDelegate: string;
20
+ objcImplementation: string;
21
+ kotlinDelegate: string;
22
+ kotlinModule: string;
23
+ swiftModels?: string;
24
+ kotlinModels?: string;
25
+ }
@@ -1,4 +0,0 @@
1
- export * from './paths.js';
2
- export * from './rn-cli.js';
3
- export * from './stripFrameworkBinary.js';
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC"}
@@ -1,3 +0,0 @@
1
- export * from './paths.js';
2
- export * from './rn-cli.js';
3
- export * from './stripFrameworkBinary.js';
@@ -1,17 +0,0 @@
1
- import type { PackageAarFlags } from '@rock-js/platform-android';
2
- import type { AndroidProjectConfig, Config as UserConfig, ProjectConfig } from '@react-native-community/cli-types';
3
- /**
4
- * Gets the project info for the given platform from the current working directory
5
- * @param platform the platform for which to get project info
6
- * @returns project root and android project config
7
- */
8
- export declare function getProjectInfo<Platform extends 'ios' | 'android'>(platform: Platform): {
9
- projectRoot: string;
10
- userConfig: UserConfig;
11
- platformConfig: ProjectConfig[Platform];
12
- };
13
- export declare const getAarConfig: (args: PackageAarFlags, androidConfig: AndroidProjectConfig) => {
14
- sourceDir: string;
15
- moduleName: string;
16
- };
17
- //# sourceMappingURL=rn-cli.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rn-cli.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/rn-cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EACV,oBAAoB,EACpB,MAAM,IAAI,UAAU,EACpB,aAAa,EACd,MAAM,mCAAmC,CAAC;AAW3C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,SAAS,KAAK,GAAG,SAAS,EAC/D,QAAQ,EAAE,QAAQ,GACjB;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CACzC,CAmBA;AAED,eAAO,MAAM,YAAY,GACvB,MAAM,eAAe,EACrB,eAAe,oBAAoB;;;CAOpC,CAAC"}
@@ -1,31 +0,0 @@
1
- import cliConfigImport from '@react-native-community/cli-config';
2
- const cliConfig = typeof cliConfigImport === 'function'
3
- ? cliConfigImport
4
- : // @ts-expect-error: interop default
5
- cliConfigImport.default;
6
- import { findProjectRoot, makeRelativeProjectConfigPaths } from './paths.js';
7
- /**
8
- * Gets the project info for the given platform from the current working directory
9
- * @param platform the platform for which to get project info
10
- * @returns project root and android project config
11
- */
12
- export function getProjectInfo(platform) {
13
- const projectRoot = findProjectRoot();
14
- const userConfig = cliConfig({
15
- projectRoot,
16
- selectedPlatform: platform,
17
- });
18
- // below: relative sourceDir path is required by RN CLI's API
19
- const platformConfig = makeRelativeProjectConfigPaths(projectRoot, userConfig.project[platform]);
20
- if (!platformConfig) {
21
- throw new Error(`${platform} project not found.`);
22
- }
23
- return { projectRoot, userConfig, platformConfig };
24
- }
25
- export const getAarConfig = (args, androidConfig) => {
26
- const config = {
27
- sourceDir: androidConfig.sourceDir,
28
- moduleName: args.moduleName ?? '',
29
- };
30
- return config;
31
- };