@callstack/brownfield-cli 1.0.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 (98) hide show
  1. package/dist/brownfield/commands/index.d.ts +4 -0
  2. package/dist/brownfield/commands/index.d.ts.map +1 -0
  3. package/dist/brownfield/commands/index.js +3 -0
  4. package/dist/brownfield/commands/packageAndroid.d.ts +5 -0
  5. package/dist/brownfield/commands/packageAndroid.d.ts.map +1 -0
  6. package/dist/brownfield/commands/packageAndroid.js +17 -0
  7. package/dist/brownfield/commands/packageIos.d.ts +5 -0
  8. package/dist/brownfield/commands/packageIos.d.ts.map +1 -0
  9. package/dist/brownfield/commands/packageIos.js +57 -0
  10. package/dist/brownfield/commands/publishAndroid.d.ts +5 -0
  11. package/dist/brownfield/commands/publishAndroid.d.ts.map +1 -0
  12. package/dist/brownfield/commands/publishAndroid.js +14 -0
  13. package/dist/brownfield/index.d.ts +12 -0
  14. package/dist/brownfield/index.d.ts.map +1 -0
  15. package/dist/brownfield/index.js +15 -0
  16. package/dist/brownfield/types/actionRunner.test.d.ts +2 -0
  17. package/dist/brownfield/types/actionRunner.test.d.ts.map +1 -0
  18. package/dist/brownfield/types/actionRunner.test.js +1 -0
  19. package/dist/brownfield/utils/index.d.ts +3 -0
  20. package/dist/brownfield/utils/index.d.ts.map +1 -0
  21. package/dist/brownfield/utils/index.js +2 -0
  22. package/dist/brownfield/utils/paths.d.ts +8 -0
  23. package/dist/brownfield/utils/paths.d.ts.map +1 -0
  24. package/dist/brownfield/utils/paths.js +24 -0
  25. package/dist/brownfield/utils/rn-cli.d.ts +17 -0
  26. package/dist/brownfield/utils/rn-cli.d.ts.map +1 -0
  27. package/dist/brownfield/utils/rn-cli.js +31 -0
  28. package/dist/brownie/commands/codegen.d.ts +11 -0
  29. package/dist/brownie/commands/codegen.d.ts.map +1 -0
  30. package/dist/brownie/commands/codegen.js +96 -0
  31. package/dist/brownie/commands/index.d.ts +2 -0
  32. package/dist/brownie/commands/index.d.ts.map +1 -0
  33. package/dist/brownie/commands/index.js +1 -0
  34. package/dist/brownie/config.d.ts +21 -0
  35. package/dist/brownie/config.d.ts.map +1 -0
  36. package/dist/brownie/config.js +47 -0
  37. package/dist/brownie/generators/kotlin.d.ts +12 -0
  38. package/dist/brownie/generators/kotlin.d.ts.map +1 -0
  39. package/dist/brownie/generators/kotlin.js +69 -0
  40. package/dist/brownie/generators/swift.d.ts +11 -0
  41. package/dist/brownie/generators/swift.d.ts.map +1 -0
  42. package/dist/brownie/generators/swift.js +55 -0
  43. package/dist/brownie/index.d.ts +7 -0
  44. package/dist/brownie/index.d.ts.map +1 -0
  45. package/dist/brownie/index.js +6 -0
  46. package/dist/brownie/store-discovery.d.ts +10 -0
  47. package/dist/brownie/store-discovery.d.ts.map +1 -0
  48. package/dist/brownie/store-discovery.js +75 -0
  49. package/dist/brownie/types.d.ts +2 -0
  50. package/dist/brownie/types.d.ts.map +1 -0
  51. package/dist/brownie/types.js +1 -0
  52. package/dist/cli.d.ts +3 -0
  53. package/dist/cli.d.ts.map +1 -0
  54. package/dist/cli.js +54 -0
  55. package/dist/index.d.ts +2 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +55 -0
  58. package/dist/main.d.ts +3 -0
  59. package/dist/main.d.ts.map +1 -0
  60. package/dist/main.js +3 -0
  61. package/dist/shared/classes/ExampleUsage.d.ts +6 -0
  62. package/dist/shared/classes/ExampleUsage.d.ts.map +1 -0
  63. package/dist/shared/classes/ExampleUsage.js +8 -0
  64. package/dist/shared/classes/index.d.ts +2 -0
  65. package/dist/shared/classes/index.d.ts.map +1 -0
  66. package/dist/shared/classes/index.js +1 -0
  67. package/dist/shared/index.d.ts +3 -0
  68. package/dist/shared/index.d.ts.map +1 -0
  69. package/dist/shared/index.js +2 -0
  70. package/dist/shared/utils/cli.d.ts +5 -0
  71. package/dist/shared/utils/cli.d.ts.map +1 -0
  72. package/dist/shared/utils/cli.js +36 -0
  73. package/dist/shared/utils/index.d.ts +2 -0
  74. package/dist/shared/utils/index.d.ts.map +1 -0
  75. package/dist/shared/utils/index.js +1 -0
  76. package/package.json +98 -0
  77. package/src/brownfield/commands/packageAndroid.ts +39 -0
  78. package/src/brownfield/commands/packageIos.ts +114 -0
  79. package/src/brownfield/commands/publishAndroid.ts +36 -0
  80. package/src/brownfield/index.ts +24 -0
  81. package/src/brownfield/utils/index.ts +2 -0
  82. package/src/brownfield/utils/paths.ts +40 -0
  83. package/src/brownfield/utils/rn-cli.ts +58 -0
  84. package/src/brownie/commands/codegen.ts +139 -0
  85. package/src/brownie/commands/index.ts +1 -0
  86. package/src/brownie/config.ts +71 -0
  87. package/src/brownie/generators/kotlin.ts +113 -0
  88. package/src/brownie/generators/swift.ts +87 -0
  89. package/src/brownie/index.ts +11 -0
  90. package/src/brownie/store-discovery.ts +108 -0
  91. package/src/brownie/types.ts +1 -0
  92. package/src/index.ts +84 -0
  93. package/src/main.ts +5 -0
  94. package/src/shared/classes/ExampleUsage.ts +6 -0
  95. package/src/shared/classes/index.ts +1 -0
  96. package/src/shared/index.ts +2 -0
  97. package/src/shared/utils/cli.ts +47 -0
  98. package/src/shared/utils/index.ts +1 -0
@@ -0,0 +1,55 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { quicktype, InputData, JSONSchemaInput, FetchingJSONSchemaStore, } from 'quicktype-core';
4
+ import { schemaForTypeScriptSources } from 'quicktype-typescript-input';
5
+ /**
6
+ * Generates Swift Codable struct from TypeScript schema.
7
+ */
8
+ export async function generateSwift(options) {
9
+ const { name, schemaPath, typeName, outputPath } = options;
10
+ const absoluteSchemaPath = path.resolve(process.cwd(), schemaPath);
11
+ if (!fs.existsSync(absoluteSchemaPath)) {
12
+ throw new Error(`Schema file not found: ${absoluteSchemaPath}`);
13
+ }
14
+ const schemaData = schemaForTypeScriptSources([absoluteSchemaPath]);
15
+ if (!schemaData.schema) {
16
+ throw new Error('Failed to generate schema from TypeScript');
17
+ }
18
+ const parsedSchema = JSON.parse(schemaData.schema);
19
+ const definitions = parsedSchema.definitions;
20
+ if (!definitions?.[typeName]) {
21
+ throw new Error(`Type "${typeName}" not found in schema. Available types: ${Object.keys(definitions || {}).join(', ')}`);
22
+ }
23
+ parsedSchema.$ref = `#/definitions/${typeName}`;
24
+ const modifiedSchema = JSON.stringify(parsedSchema);
25
+ const schemaInput = new JSONSchemaInput(new FetchingJSONSchemaStore());
26
+ await schemaInput.addSource({
27
+ name: typeName,
28
+ schema: modifiedSchema,
29
+ });
30
+ const inputData = new InputData();
31
+ inputData.addInput(schemaInput);
32
+ const { lines } = await quicktype({
33
+ inputData,
34
+ lang: 'swift',
35
+ rendererOptions: {
36
+ 'access-level': 'public',
37
+ 'mutable-properties': 'true',
38
+ initializers: 'false',
39
+ 'swift-5-support': 'true',
40
+ protocol: 'equatable',
41
+ },
42
+ });
43
+ const storeNameExtension = `
44
+ extension ${typeName}: BrownieStoreProtocol {
45
+ public static let storeName = "${name}"
46
+ }
47
+ `;
48
+ const swiftOutput = lines.join('\n') + storeNameExtension;
49
+ const absoluteOutputPath = path.resolve(process.cwd(), outputPath);
50
+ const outputDir = path.dirname(absoluteOutputPath);
51
+ if (!fs.existsSync(outputDir)) {
52
+ fs.mkdirSync(outputDir, { recursive: true });
53
+ }
54
+ fs.writeFileSync(absoluteOutputPath, swiftOutput);
55
+ }
@@ -0,0 +1,7 @@
1
+ import * as Commands from './commands/index.js';
2
+ export type * from './types.js';
3
+ export * from './store-discovery.js';
4
+ export declare const groupName: string;
5
+ export { Commands };
6
+ export default Commands;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/brownie/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAEhD,mBAAmB,YAAY,CAAC;AAChC,cAAc,sBAAsB,CAAC;AAErC,eAAO,MAAM,SAAS,QAAwJ,CAAC;AAE/K,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { styleText } from 'node:util';
2
+ import * as Commands from './commands/index.js';
3
+ export * from './store-discovery.js';
4
+ export const groupName = `${styleText(['bold', 'blueBright'], '@callstack/brownie')}${styleText('whiteBright', ' - Shared state management CLI for React Native Brownfield')}`;
5
+ export { Commands };
6
+ export default Commands;
@@ -0,0 +1,10 @@
1
+ export interface DiscoveredStore {
2
+ name: string;
3
+ schemaPath: string;
4
+ }
5
+ /**
6
+ * Discovers all brownie stores by parsing BrownieStores interface
7
+ * from declare module '@callstack/brownie' blocks.
8
+ */
9
+ export declare function discoverStores(rootDir?: string): DiscoveredStore[];
10
+ //# sourceMappingURL=store-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-discovery.d.ts","sourceRoot":"","sources":["../../src/brownie/store-discovery.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AA4DD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAsB,GAC9B,eAAe,EAAE,CAkCnB"}
@@ -0,0 +1,75 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { Project } from 'ts-morph';
4
+ /**
5
+ * Recursively finds all *.brownie.ts files in a directory.
6
+ */
7
+ function findBrownieFiles(dir, files = []) {
8
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
9
+ for (const entry of entries) {
10
+ const fullPath = path.join(dir, entry.name);
11
+ if (entry.isDirectory()) {
12
+ if (entry.name === 'node_modules' || entry.name.startsWith('.')) {
13
+ continue;
14
+ }
15
+ findBrownieFiles(fullPath, files);
16
+ }
17
+ else if (entry.name.endsWith('.brownie.ts')) {
18
+ files.push(fullPath);
19
+ }
20
+ }
21
+ return files;
22
+ }
23
+ /**
24
+ * Parses a brownie file and extracts store names from BrownieStores interface.
25
+ */
26
+ function parseStoresFromFile(project, filePath) {
27
+ const sourceFile = project.addSourceFileAtPath(filePath);
28
+ const stores = [];
29
+ const modules = sourceFile.getModules();
30
+ for (const mod of modules) {
31
+ const moduleName = mod.getName();
32
+ if (moduleName !== "'@callstack/brownie'" &&
33
+ moduleName !== '"@callstack/brownie"') {
34
+ continue;
35
+ }
36
+ const iface = mod.getInterface('BrownieStores');
37
+ if (!iface) {
38
+ continue;
39
+ }
40
+ for (const prop of iface.getProperties()) {
41
+ stores.push({
42
+ name: prop.getName(),
43
+ schemaPath: filePath,
44
+ });
45
+ }
46
+ }
47
+ return stores;
48
+ }
49
+ /**
50
+ * Discovers all brownie stores by parsing BrownieStores interface
51
+ * from declare module '@callstack/brownie' blocks.
52
+ */
53
+ export function discoverStores(rootDir = process.cwd()) {
54
+ const brownieFiles = findBrownieFiles(rootDir);
55
+ if (brownieFiles.length === 0) {
56
+ throw new Error('No brownie store files found. Create a file ending with .brownie.ts ' +
57
+ '(e.g., MyStore.brownie.ts)');
58
+ }
59
+ const project = new Project({ skipAddingFilesFromTsConfig: true });
60
+ const allStores = [];
61
+ for (const filePath of brownieFiles) {
62
+ const stores = parseStoresFromFile(project, filePath);
63
+ allStores.push(...stores);
64
+ }
65
+ if (allStores.length === 0) {
66
+ throw new Error('No stores found in brownie files. Make sure to declare module ' +
67
+ "'@callstack/brownie' with BrownieStores interface.");
68
+ }
69
+ const names = allStores.map((s) => s.name);
70
+ const duplicates = names.filter((n, i) => names.indexOf(n) !== i);
71
+ if (duplicates.length > 0) {
72
+ throw new Error(`Duplicate store names found: ${[...new Set(duplicates)].join(', ')}`);
73
+ }
74
+ return allStores;
75
+ }
@@ -0,0 +1,2 @@
1
+ export type Platform = 'swift' | 'kotlin';
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/brownie/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ import { styleText } from 'node:util';
3
+ import { logger } from '@rock-js/tools';
4
+ import { Command } from 'commander';
5
+ import { ExampleUsage } from './shared/index.js';
6
+ import brownfieldCommands, { groupName as brownfieldCommandsGroupName, } from './brownfield/index.js';
7
+ import brownieCommands, { groupName as brownieCommandsGroupName, } from './brownie/index.js';
8
+ const program = new Command();
9
+ program
10
+ .name(styleText('magenta', 'brownie'))
11
+ .usage(styleText('yellow', '[options] [command]'))
12
+ .description(styleText('magentaBright', 'React Native Brownfield CLI - ') +
13
+ styleText(['magenta', 'bold', 'underline'], 'Brownie'))
14
+ .version(process.env.npm_package_version ?? '0.0.0');
15
+ program
16
+ .optionsGroup('Global options:')
17
+ .option('--verbose', 'enable verbose logging')
18
+ .hook('preAction', () => {
19
+ const opts = program.opts();
20
+ if (opts.verbose) {
21
+ logger.setVerbose(opts.verbose ?? false);
22
+ }
23
+ });
24
+ program.configureHelp({
25
+ styleTitle: (str) => styleText('bold', str),
26
+ styleCommandText: (str) => styleText('cyan', str),
27
+ styleArgumentText: (str) => styleText('yellow', str),
28
+ styleSubcommandText: (str) => styleText('blue', str),
29
+ });
30
+ function registrationHelper(commandsRegistration, groupName) {
31
+ program.commandsGroup(groupName);
32
+ const exampleUsageItems = [];
33
+ Object.values(commandsRegistration).forEach((commandOrExampleUsage) => {
34
+ if (commandOrExampleUsage instanceof Command) {
35
+ // command
36
+ program.addCommand(commandOrExampleUsage);
37
+ }
38
+ else if (commandOrExampleUsage instanceof ExampleUsage) {
39
+ // piece of example usage for the command group
40
+ exampleUsageItems.push(commandOrExampleUsage);
41
+ }
42
+ });
43
+ if (exampleUsageItems.length) {
44
+ const longestUsageItemCommandLength = exampleUsageItems.reduce((max, item) => Math.max(max, item.command.length), 0);
45
+ program.addHelpText('after', `\nExamples:\n${exampleUsageItems.map((item) => `\t ${styleText('dim', item.command.padEnd(longestUsageItemCommandLength))}\t${item.description}`).join('\n')}\n`);
46
+ }
47
+ }
48
+ registrationHelper(brownfieldCommands, brownfieldCommandsGroupName);
49
+ registrationHelper(brownieCommands, brownieCommandsGroupName);
50
+ program.commandsGroup('Utility commands').helpCommand('help [command]');
51
+ program.parse(process.argv);
52
+ if (!process.argv.slice(2).length) {
53
+ program.outputHelp();
54
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runCLI(argv: string[]): void;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ import { styleText } from 'node:util';
2
+ import { logger } from '@rock-js/tools';
3
+ import { Command } from 'commander';
4
+ import { ExampleUsage } from './shared/index.js';
5
+ import brownfieldCommands, { groupName as brownfieldCommandsGroupName, } from './brownfield/index.js';
6
+ import brownieCommands, { groupName as brownieCommandsGroupName, } from './brownie/index.js';
7
+ const program = new Command();
8
+ program
9
+ .name(styleText('magenta', 'brownie'))
10
+ .usage(styleText('yellow', '[options] [command]'))
11
+ .description(styleText('magentaBright', 'React Native Brownfield CLI - ') +
12
+ styleText(['magenta', 'bold', 'underline'], 'Brownie'))
13
+ .version(process.env.npm_package_version ?? '0.0.0');
14
+ program
15
+ .optionsGroup('Global options:')
16
+ .option('--verbose', 'enable verbose logging')
17
+ .hook('preAction', () => {
18
+ const opts = program.opts();
19
+ if (opts.verbose) {
20
+ logger.setVerbose(opts.verbose ?? false);
21
+ }
22
+ });
23
+ program.configureHelp({
24
+ styleTitle: (str) => styleText('bold', str),
25
+ styleCommandText: (str) => styleText('cyan', str),
26
+ styleArgumentText: (str) => styleText('yellow', str),
27
+ styleSubcommandText: (str) => styleText('blue', str),
28
+ });
29
+ function registrationHelper(commandsRegistration, groupName) {
30
+ program.commandsGroup(groupName);
31
+ const exampleUsageItems = [];
32
+ Object.values(commandsRegistration).forEach((commandOrExampleUsage) => {
33
+ if (commandOrExampleUsage instanceof Command) {
34
+ // command
35
+ program.addCommand(commandOrExampleUsage);
36
+ }
37
+ else if (commandOrExampleUsage instanceof ExampleUsage) {
38
+ // piece of example usage for the command group
39
+ exampleUsageItems.push(commandOrExampleUsage);
40
+ }
41
+ });
42
+ if (exampleUsageItems.length) {
43
+ const longestUsageItemCommandLength = exampleUsageItems.reduce((max, item) => Math.max(max, item.command.length), 0);
44
+ program.addHelpText('after', `\nExamples:\n${exampleUsageItems.map((item) => `\t ${styleText('dim', item.command.padEnd(longestUsageItemCommandLength))}\t${item.description}`).join('\n')}\n`);
45
+ }
46
+ }
47
+ registrationHelper(brownfieldCommands, brownfieldCommandsGroupName);
48
+ registrationHelper(brownieCommands, brownieCommandsGroupName);
49
+ program.commandsGroup('Utility commands').helpCommand('help [command]');
50
+ export function runCLI(argv) {
51
+ program.parse(argv);
52
+ if (!argv.slice(2).length) {
53
+ program.outputHelp();
54
+ }
55
+ }
package/dist/main.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
package/dist/main.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { runCLI } from './index.js';
3
+ runCLI(process.argv);
@@ -0,0 +1,6 @@
1
+ export declare class ExampleUsage {
2
+ readonly command: string;
3
+ readonly description: string;
4
+ constructor(command: string, description: string);
5
+ }
6
+ //# sourceMappingURL=ExampleUsage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExampleUsage.d.ts","sourceRoot":"","sources":["../../../src/shared/classes/ExampleUsage.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;aAEL,OAAO,EAAE,MAAM;aACf,WAAW,EAAE,MAAM;gBADnB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM;CAEtC"}
@@ -0,0 +1,8 @@
1
+ export class ExampleUsage {
2
+ command;
3
+ description;
4
+ constructor(command, description) {
5
+ this.command = command;
6
+ this.description = description;
7
+ }
8
+ }
@@ -0,0 +1,2 @@
1
+ export * from './ExampleUsage.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/classes/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './ExampleUsage.js';
@@ -0,0 +1,3 @@
1
+ export * from './utils/index.js';
2
+ export * from './classes/index.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './utils/index.js';
2
+ export * from './classes/index.js';
@@ -0,0 +1,5 @@
1
+ import { type RockCLIOptions } from '@rock-js/tools';
2
+ import type { Command } from 'commander';
3
+ export declare function curryOptions(programCommand: Command, options: RockCLIOptions): Command;
4
+ export declare function actionRunner<T, R>(fn: (...args: T[]) => Promise<R>): (...args: T[]) => Promise<void>;
5
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAExE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,wBAAgB,YAAY,CAAC,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,WAmB5E;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,IAC1B,GAAG,MAAM,CAAC,EAAE,mBAoBpD"}
@@ -0,0 +1,36 @@
1
+ import { logger, RockError } from '@rock-js/tools';
2
+ export function curryOptions(programCommand, options) {
3
+ options.forEach((option) => {
4
+ if (option.parse) {
5
+ programCommand = programCommand.option(option.name, option.description, option.parse, option.default);
6
+ }
7
+ else {
8
+ programCommand = programCommand.option(option.name, option.description, option.default);
9
+ }
10
+ });
11
+ return programCommand;
12
+ }
13
+ export function actionRunner(fn) {
14
+ return async function wrappedCLIAction(...args) {
15
+ try {
16
+ await fn(...args);
17
+ }
18
+ catch (error) {
19
+ if (error instanceof RockError) {
20
+ if (logger.isVerbose()) {
21
+ logger.error(error);
22
+ }
23
+ else {
24
+ logger.error(error.message);
25
+ if (error.cause) {
26
+ logger.error(`Cause: ${error.cause}`);
27
+ }
28
+ }
29
+ }
30
+ else {
31
+ logger.error(`Unexpected error while running command:`, error);
32
+ }
33
+ process.exit(1);
34
+ }
35
+ };
36
+ }
@@ -0,0 +1,2 @@
1
+ export * from './cli.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './cli.js';
package/package.json ADDED
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "@callstack/brownfield-cli",
3
+ "version": "1.0.0",
4
+ "license": "MIT",
5
+ "author": "Artur Morys-Magiera <artus9033@gmail.com>",
6
+ "bin": {
7
+ "brownfield": "./dist/main.js"
8
+ },
9
+ "type": "module",
10
+ "contributors": [
11
+ "Artur Morys-Magiera <artus9033@gmail.com>",
12
+ "Oskar Kwasniewski <oskarkwasniewski@icloud.com>"
13
+ ],
14
+ "homepage": "https://github.com/callstack/react-native-brownfield",
15
+ "description": "Brownfield CLI for React Native, gathering all packages of the RN brownfield ecosystem",
16
+ "exports": {
17
+ ".": {
18
+ "source": "./src/index.ts",
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ },
22
+ "./brownfield": {
23
+ "source": "./src/brownfield/index.ts",
24
+ "types": "./dist/brownfield/index.d.ts",
25
+ "default": "./dist/brownfield/index.js"
26
+ },
27
+ "./brownie": {
28
+ "source": "./src/brownie/index.ts",
29
+ "types": "./dist/brownie/index.d.ts",
30
+ "default": "./dist/brownie/index.js"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "scripts": {
35
+ "lint": "eslint .",
36
+ "typecheck": "tsc --noEmit",
37
+ "build": "tsc -p tsconfig.json",
38
+ "dev": "tsc -p tsconfig.json --watch",
39
+ "test": "vitest run"
40
+ },
41
+ "keywords": [
42
+ "react-native-brownfield",
43
+ "react native brownfield",
44
+ "native",
45
+ "react native integration",
46
+ "cli",
47
+ "brownie",
48
+ "tooling"
49
+ ],
50
+ "files": [
51
+ "src",
52
+ "dist",
53
+ "!**/__tests__",
54
+ "!**/__fixtures__",
55
+ "!**/__mocks__",
56
+ "!**/.*"
57
+ ],
58
+ "publishConfig": {
59
+ "access": "public"
60
+ },
61
+ "peerDependencies": {
62
+ "@react-native-community/cli-config": "*",
63
+ "@react-native-community/cli-config-android": "*"
64
+ },
65
+ "dependencies": {
66
+ "@react-native-community/cli-config": "^20.0.0",
67
+ "@react-native-community/cli-config-android": "^20.0.0",
68
+ "@rock-js/platform-android": "^0.12.6",
69
+ "@rock-js/platform-apple-helpers": "^0.12.6",
70
+ "@rock-js/plugin-brownfield-android": "^0.12.6",
71
+ "@rock-js/plugin-brownfield-ios": "^0.12.6",
72
+ "@rock-js/tools": "^0.12.6",
73
+ "commander": "^14.0.2",
74
+ "lodash.clonedeep": "^4.5.0",
75
+ "ts-morph": "^27.0.2"
76
+ },
77
+ "devDependencies": {
78
+ "@babel/core": "^7.28.5",
79
+ "@babel/preset-env": "^7.28.5",
80
+ "@babel/preset-typescript": "^7.28.5",
81
+ "@react-native-community/cli-types": "^20.0.0",
82
+ "@react-native/babel-preset": "0.82.1",
83
+ "@react-native/eslint-config": "0.82.1",
84
+ "@types/babel__core": "^7.20.5",
85
+ "@types/babel__preset-env": "^7.10.0",
86
+ "@types/lodash.clonedeep": "^4.5.9",
87
+ "@types/node": "^25.0.8",
88
+ "@vitest/coverage-v8": "^4.0.17",
89
+ "eslint": "^9.28.0",
90
+ "globals": "^16.2.0",
91
+ "nodemon": "^3.1.11",
92
+ "typescript": "5.9.3",
93
+ "vitest": "^4.0.17"
94
+ },
95
+ "engines": {
96
+ "node": ">=20"
97
+ }
98
+ }
@@ -0,0 +1,39 @@
1
+ import { Command } from 'commander';
2
+
3
+ import {
4
+ type PackageAarFlags,
5
+ packageAarOptions,
6
+ } from '@rock-js/platform-android';
7
+ import { packageAarAction } from '@rock-js/plugin-brownfield-android';
8
+
9
+ import {
10
+ ExampleUsage,
11
+ actionRunner,
12
+ curryOptions,
13
+ } from '../../shared/index.js';
14
+ import { getProjectInfo } from '../utils/index.js';
15
+
16
+ export const packageAndroidCommand = curryOptions(
17
+ new Command('package:android').description('Build Android AAR'),
18
+ packageAarOptions.map((option) =>
19
+ option.name.startsWith('--variant')
20
+ ? { ...option, default: 'debug' }
21
+ : option
22
+ )
23
+ ).action(
24
+ actionRunner(async (options: PackageAarFlags) => {
25
+ const { projectRoot, platformConfig } = getProjectInfo('android');
26
+
27
+ await packageAarAction({
28
+ projectRoot,
29
+ pluginConfig: platformConfig,
30
+ moduleName: options.moduleName,
31
+ variant: options.variant,
32
+ });
33
+ })
34
+ );
35
+
36
+ export const packageAndroidExample = new ExampleUsage(
37
+ 'package:android --module-name :BrownfieldLib --variant release',
38
+ "Build Android AAR for 'BrownfieldLib' module in release variant"
39
+ );