From b9f3958ff8ac377f0a06bd53c958bf6b9b617829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 21 Jan 2026 15:16:59 +0100 Subject: [PATCH 1/2] feat: create brownfield package as CLI proxy --- packages/brownfield/.gitignore | 1 + packages/brownfield/README.md | 63 ++++++++++++++ packages/brownfield/eslint.config.mjs | 4 + packages/brownfield/package.json | 66 +++++++++++++++ packages/brownfield/src/index.ts | 5 ++ packages/brownfield/tsconfig.json | 114 ++++++++++++++++++++++++++ packages/brownfield/turbo.json | 10 +++ packages/cli/src/index.ts | 2 +- yarn.lock | 17 ++++ 9 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 packages/brownfield/.gitignore create mode 100644 packages/brownfield/README.md create mode 100644 packages/brownfield/eslint.config.mjs create mode 100644 packages/brownfield/package.json create mode 100644 packages/brownfield/src/index.ts create mode 100644 packages/brownfield/tsconfig.json create mode 100644 packages/brownfield/turbo.json diff --git a/packages/brownfield/.gitignore b/packages/brownfield/.gitignore new file mode 100644 index 00000000..1521c8b7 --- /dev/null +++ b/packages/brownfield/.gitignore @@ -0,0 +1 @@ +dist diff --git a/packages/brownfield/README.md b/packages/brownfield/README.md new file mode 100644 index 00000000..8563811a --- /dev/null +++ b/packages/brownfield/README.md @@ -0,0 +1,63 @@ + + Brownfield CLI + + +

+ CLI for Brownie and Brownfield, a tool for generating state management code, packaging & publishing Brownfield artifacts. +

+ +--- + +[![Build Status][build-badge]][build] +[![Version][version-badge]][package] +[![MIT License][license-badge]][license] + +[![PRs Welcome][prs-welcome-badge]][prs-welcome] +[![Chat][chat-badge]][chat] +[![Code of Conduct][coc-badge]][coc] +[![Sponsored by Callstack][callstack-badge]][callstack] + +[![tweet][tweet-badge]][tweet] + +## Features + +- **Shared State** - Single source of truth accessible from both TypeScript and Swift +- **Type Safety** - Full type inference from TypeScript schema to generated Swift types +- **React Integration** - `useStore` hook with selector support for optimal re-renders +- **SwiftUI Integration** - `@UseStore` property wrapper for reactive UI updates +- **UIKit Support** - Subscribe-based API for imperative UI updates + +## Documentation + +For full documentation, visit [our documentation](https://oss.callstack.com/react-native-brownfield/brownie/overview). + + + Download a free copy of Incremental React Native adoption in native apps ebook + + +## Made with ❤️ at Callstack + +React Native Brownfield is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack](https://callstack.com) is a group of React and React Native geeks, contact us at [hello@callstack.com](mailto:hello@callstack.com) if you need any help with these or just want to say hi! + +Like the project? ⚛️ [Join the team](https://callstack.com/careers/?utm_campaign=Senior_RN&utm_source=github&utm_medium=readme) who does amazing stuff for clients and drives React Native Open Source! 🔥 + + + +[build-badge]: https://img.shields.io/circleci/build/github/callstack/react-native-brownfield/master.svg?style=flat-square +[build]: https://circleci.com/gh/callstack/react-native-brownfield +[ci]: https://github.com/callstack/react-native-brownfield/actions/workflows/ci.yml/badge.svg +[version-badge]: https://img.shields.io/npm/v/@callstack/react-native-brownfield.svg?style=flat-square +[package]: https://www.npmjs.com/package/@callstack/react-native-brownfield +[license-badge]: https://img.shields.io/npm/l/@callstack/react-native-brownfield.svg?style=flat-square +[license]: https://opensource.org/licenses/MIT +[prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square +[prs-welcome]: http://makeapullrequest.com +[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square +[coc]: https://github.com/callstack/react-native-brownfield/blob/master/CODE_OF_CONDUCT.md +[all-contributors-badge]: https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square +[chat-badge]: https://img.shields.io/discord/613446453762719798.svg?style=flat-square&colorB=758ED3 +[chat]: https://discord.gg/2SR9Mua +[tweet-badge]: https://img.shields.io/badge/tweet-%23reactnativebrownfield-blue.svg?style=flat-square&colorB=1DA1F2&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAUCAYAAACXtf2DAAAAAXNSR0IArs4c6QAAAaRJREFUOBGtlM8rBGEYx3cWtRHJRaKcuMtBSitxkCQ3LtzkP9iUUu5ODspRHLhRLtq0FxeicEBC2cOivcge%2FMgan3fNM8bbzL4zm6c%2BPT%2Fe7%2FO8887svrFYBWbbtgWzsAt3sAcpqJFxxF1QV8oJFqFPFst5dLWQAT87oTgPB7DtziFRT1EA4yZolsFkhwjGYFRO8Op0KD8HVe7unoB6PRTBZG8IctAmG1xrHcfkQ2B55sfI%2ByGMXSBqV71xZ8CWdxBxN6ThFuECDEAL%2Bc9HIzDYumVZ966GZnX0SzCZvEqTbkaGywkyFE6hKAsBPhFQ18uPUqh2ggJ%2BUor%2F4M%2F%2FzOC8g6YzR1i%2F8g4vvSI%2ByD7FFNjexQrjHd8%2BnjABI3AU4Wl16TuF1qANGll81jsi5qu%2Bw6XIsCn4ijhU5FmCJpkV6BGNw410hfSf6JKBQ%2FUFxHGYBnWnmOwDwYQ%2BwzdHqO75HtiAMJfaC7ph32FSRJCENUhDHsLaJkL%2FX4wMF4%2BwA5bgAcrZE4sr0Cu9Jq9fxyrvBHWbNkMD5CEHWTjjT2m6r5D92jfmbbKJEWuMMAAAAABJRU5ErkJggg%3D%3D +[tweet]: https://twitter.com/intent/tweet?text=Check%20out%20react-native-brownfield!%20https://github.com/callstack/react-native-brownfield%20%F0%9F%91%8D +[callstack-badge]: https://callstack.com/images/callstack-badge.svg +[callstack]: https://callstack.com/open-source/?utm_source=github.com&utm_medium=referral&utm_campaign=rnbrownfield&utm_term=readme diff --git a/packages/brownfield/eslint.config.mjs b/packages/brownfield/eslint.config.mjs new file mode 100644 index 00000000..237c6515 --- /dev/null +++ b/packages/brownfield/eslint.config.mjs @@ -0,0 +1,4 @@ +import eslintBaseConfig from '../../eslint.config.base.mjs'; + +/** @type {import('eslint').Linter.Config[]} */ +export default eslintBaseConfig; diff --git a/packages/brownfield/package.json b/packages/brownfield/package.json new file mode 100644 index 00000000..eb5468d0 --- /dev/null +++ b/packages/brownfield/package.json @@ -0,0 +1,66 @@ +{ + "name": "brownfield", + "version": "1.0.2", + "license": "MIT", + "author": "Artur Morys-Magiera ", + "bin": "dist/index.js", + "type": "module", + "contributors": [ + "Artur Morys-Magiera ", + "Oskar Kwasniewski " + ], + "homepage": "https://oss.callstack.com/react-native-brownfield", + "repository": { + "url": "https://github.com/callstack/react-native-brownfield/packages/brownfield" + }, + "description": "Brownfield CLI for React Native, gathering all packages of the RN brownfield ecosystem", + "exports": { + ".": { + "source": "./src/index.ts", + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "scripts": { + "lint": "eslint .", + "typecheck": "tsc --noEmit", + "build": "tsc -p tsconfig.json", + "dev": "tsc -p tsconfig.json --watch", + "test": "echo 'No tests'" + }, + "keywords": [ + "react-native-brownfield", + "brownfield", + "native", + "react native integration", + "cli" + ], + "files": [ + "src", + "dist", + "!**/__tests__", + "!**/__fixtures__", + "!**/__mocks__", + "!**/.*", + "README.md" + ], + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@callstack/brownfield-cli": "workspace:^" + }, + "devDependencies": { + "@types/node": "^25.0.8", + "eslint": "^9.28.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-node-import": "^1.0.5", + "eslint-plugin-prettier": "^5.1.3", + "prettier": "^3.7.4", + "typescript": "5.9.3" + }, + "engines": { + "node": ">=20" + } +} diff --git a/packages/brownfield/src/index.ts b/packages/brownfield/src/index.ts new file mode 100644 index 00000000..0b38f185 --- /dev/null +++ b/packages/brownfield/src/index.ts @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +import { runCLI } from '@callstack/brownfield-cli'; + +runCLI(process.argv); diff --git a/packages/brownfield/tsconfig.json b/packages/brownfield/tsconfig.json new file mode 100644 index 00000000..417b0251 --- /dev/null +++ b/packages/brownfield/tsconfig.json @@ -0,0 +1,114 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "libReplacement": true, /* Enable lib replacement. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "esnext", /* Specify what module code is generated. */ + "rootDir": "./src", /* Specify the root folder within your source files. */ + "moduleResolution": "bundler", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */ + "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "exclude": ["__tests__", "__fixtures__", "dist", "vitest.config.ts"], +} diff --git a/packages/brownfield/turbo.json b/packages/brownfield/turbo.json new file mode 100644 index 00000000..3bafb127 --- /dev/null +++ b/packages/brownfield/turbo.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**/*"], + "outputs": ["dist/**"] + } + } +} diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 1c6ff762..53e05d9c 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -15,7 +15,7 @@ import brownieCommands, { const program = new Command(); program - .name(styleText('magenta', 'brownie')) + .name(styleText('magenta', 'brownfield')) .usage(styleText('yellow', '[options] [command]')) .description( styleText('magentaBright', 'React Native Brownfield CLI - ') + diff --git a/yarn.lock b/yarn.lock index 760654b4..30106db0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6963,6 +6963,23 @@ __metadata: languageName: node linkType: hard +"brownfield@workspace:packages/brownfield": + version: 0.0.0-use.local + resolution: "brownfield@workspace:packages/brownfield" + dependencies: + "@callstack/brownfield-cli": "workspace:^" + "@types/node": "npm:^25.0.8" + eslint: "npm:^9.28.0" + eslint-config-prettier: "npm:^10.1.8" + eslint-plugin-node-import: "npm:^1.0.5" + eslint-plugin-prettier: "npm:^5.1.3" + prettier: "npm:^3.7.4" + typescript: "npm:5.9.3" + bin: + brownfield: dist/index.js + languageName: unknown + linkType: soft + "browser-or-node@npm:^3.0.0": version: 3.0.0 resolution: "browser-or-node@npm:3.0.0" From e669e37a6006be3e0a4eb9c2a9e57188389258ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 21 Jan 2026 15:19:15 +0100 Subject: [PATCH 2/2] chore: changeset --- .changeset/curvy-keys-shine.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/curvy-keys-shine.md diff --git a/.changeset/curvy-keys-shine.md b/.changeset/curvy-keys-shine.md new file mode 100644 index 00000000..244db99f --- /dev/null +++ b/.changeset/curvy-keys-shine.md @@ -0,0 +1,6 @@ +--- +'brownfield': patch +'@callstack/brownfield-cli': patch +--- + +feat: create brownfield package as CLI proxy