├── .gitignore ├── hexagonal-architecture ├── src │ ├── infrastructure │ │ ├── views │ │ │ ├── reactnative-ui │ │ │ │ ├── .watchmanconfig │ │ │ │ ├── .gitattributes │ │ │ │ ├── app.json │ │ │ │ ├── android │ │ │ │ │ ├── app │ │ │ │ │ │ ├── src │ │ │ │ │ │ │ ├── main │ │ │ │ │ │ │ │ ├── res │ │ │ │ │ │ │ │ │ ├── values │ │ │ │ │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ │ │ │ └── mipmap-xxxhdpi │ │ │ │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ │ │ ├── java │ │ │ │ │ │ │ │ │ └── com │ │ │ │ │ │ │ │ │ │ └── reactnativeui │ │ │ │ │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ │ │ │ │ └── MainApplication.java │ │ │ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ │ │ │ └── debug │ │ │ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ │ │ │ └── java │ │ │ │ │ │ │ │ └── com │ │ │ │ │ │ │ │ └── reactnativeui │ │ │ │ │ │ │ │ └── ReactNativeFlipper.java │ │ │ │ │ │ ├── debug.keystore │ │ │ │ │ │ ├── proguard-rules.pro │ │ │ │ │ │ ├── build_defs.bzl │ │ │ │ │ │ ├── _BUCK │ │ │ │ │ │ └── build.gradle │ │ │ │ │ ├── gradle │ │ │ │ │ │ └── wrapper │ │ │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ │ │ └── gradle-wrapper.properties │ │ │ │ │ ├── settings.gradle │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── gradle.properties │ │ │ │ │ ├── gradlew.bat │ │ │ │ │ └── gradlew │ │ │ │ ├── ios │ │ │ │ │ ├── reactnativeui │ │ │ │ │ │ ├── Images.xcassets │ │ │ │ │ │ │ ├── Contents.json │ │ │ │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ ├── AppDelegate.h │ │ │ │ │ │ ├── main.m │ │ │ │ │ │ ├── Info.plist │ │ │ │ │ │ ├── AppDelegate.m │ │ │ │ │ │ └── LaunchScreen.storyboard │ │ │ │ │ ├── reactnativeuiTests │ │ │ │ │ │ ├── Info.plist │ │ │ │ │ │ └── reactnativeuiTests.m │ │ │ │ │ ├── reactnativeui-tvOSTests │ │ │ │ │ │ └── Info.plist │ │ │ │ │ ├── Podfile │ │ │ │ │ ├── reactnativeui-tvOS │ │ │ │ │ │ └── Info.plist │ │ │ │ │ └── reactnativeui.xcodeproj │ │ │ │ │ │ ├── xcshareddata │ │ │ │ │ │ └── xcschemes │ │ │ │ │ │ │ ├── reactnativeui.xcscheme │ │ │ │ │ │ │ └── reactnativeui-tvOS.xcscheme │ │ │ │ │ │ └── project.pbxproj │ │ │ │ ├── .buckconfig │ │ │ │ ├── index.js │ │ │ │ ├── .editorconfig │ │ │ │ ├── .prettierrc.js │ │ │ │ ├── __tests__ │ │ │ │ │ └── App-test.tsx │ │ │ │ ├── babel.config.js │ │ │ │ ├── .gitignore │ │ │ │ ├── metro.config.js │ │ │ │ ├── .eslintrc.js │ │ │ │ ├── package.json │ │ │ │ ├── src │ │ │ │ │ └── components │ │ │ │ │ │ └── ProductList.tsx │ │ │ │ ├── App.tsx │ │ │ │ └── tsconfig.json │ │ │ ├── vue-ui │ │ │ │ ├── src │ │ │ │ │ ├── main.d.ts │ │ │ │ │ ├── shims-vue.d.ts │ │ │ │ │ ├── main.ts │ │ │ │ │ ├── shims-tsx.d.ts │ │ │ │ │ ├── views │ │ │ │ │ │ └── ProductList.vue │ │ │ │ │ └── App.vue │ │ │ │ ├── tsconfig.tsbuildinfo │ │ │ │ ├── babel.config.js │ │ │ │ ├── public │ │ │ │ │ ├── favicon.ico │ │ │ │ │ └── index.html │ │ │ │ ├── jestconfig.json │ │ │ │ ├── .editorconfig │ │ │ │ ├── .prettierrc │ │ │ │ ├── .babelrc.json │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── vue.config.js │ │ │ │ ├── .eslintrc.js │ │ │ │ ├── tsconfig.json │ │ │ │ └── package.json │ │ │ └── react-ui │ │ │ │ ├── .env │ │ │ │ ├── src │ │ │ │ ├── setupTests.d.ts │ │ │ │ ├── react-app-env.d.ts │ │ │ │ ├── reportWebVitals.d.ts │ │ │ │ ├── setupTests.ts │ │ │ │ ├── reportWebVitals.ts │ │ │ │ ├── index.tsx │ │ │ │ ├── views │ │ │ │ │ └── ProductList.tsx │ │ │ │ ├── App.tsx │ │ │ │ └── logo.svg │ │ │ │ ├── public │ │ │ │ ├── robots.txt │ │ │ │ ├── favicon.ico │ │ │ │ ├── logo192.png │ │ │ │ ├── logo512.png │ │ │ │ ├── manifest.json │ │ │ │ └── index.html │ │ │ │ ├── jestconfig.json │ │ │ │ ├── .editorconfig │ │ │ │ ├── .babelrc.json │ │ │ │ ├── .prettierrc │ │ │ │ ├── config-overrides.js │ │ │ │ ├── tsconfig.paths.json │ │ │ │ ├── .gitignore │ │ │ │ ├── tsconfig.json │ │ │ │ ├── package.json │ │ │ │ ├── README.md │ │ │ │ └── .eslintrc.js │ │ ├── instances │ │ │ ├── httpAxios.d.ts │ │ │ ├── httpFake.d.ts │ │ │ ├── productRepositoryFake.d.ts │ │ │ ├── productRepositoryFake.ts │ │ │ ├── httpFake.ts │ │ │ └── httpAxios.ts │ │ ├── http │ │ │ └── dto │ │ │ │ ├── ProductDTO.d.ts │ │ │ │ └── ProductDTO.ts │ │ └── repositories │ │ │ ├── productRepository.d.ts │ │ │ └── productRepository.ts │ ├── domain │ │ ├── services │ │ │ ├── CartService.d.ts │ │ │ ├── ProductService.d.ts │ │ │ ├── ProductService.ts │ │ │ └── CartService.ts │ │ ├── models │ │ │ ├── Product.d.ts │ │ │ ├── Product.ts │ │ │ ├── Cart.d.ts │ │ │ └── Cart.ts │ │ └── repositories │ │ │ ├── ProductRepository.d.ts │ │ │ ├── ProductRepository.ts │ │ │ ├── Http.d.ts │ │ │ └── Http.ts │ ├── mocks │ │ ├── products.d.ts │ │ ├── products.js │ │ └── products.ts │ └── tests │ │ └── cart.test.ts ├── .npmignore ├── .gitignore ├── .editorconfig ├── jest.config.js ├── .prettierrc ├── tsconfig.json ├── package.json └── .eslintrc.js ├── resources ├── directories.png ├── directories_vue.png ├── directories_react.png └── hexagonal_architecture.png └── .idea ├── vcs.xml ├── misc.xml ├── inspectionProfiles └── Project_Default.xml ├── compiler.xml ├── hexagonal-architecture-frontend.iml └── modules.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.map 2 | *.js.map 3 | *.lock 4 | /.idea/ 5 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/src/main.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /hexagonal-architecture/.npmignore: -------------------------------------------------------------------------------- 1 | #.npmignore 2 | __test__ 3 | infrastructure/views 4 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true 2 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/tsconfig.tsbuildinfo: -------------------------------------------------------------------------------- 1 | { 2 | "version": "4.1.5" 3 | } -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/setupTests.d.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /resources/directories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/resources/directories.png -------------------------------------------------------------------------------- /resources/directories_vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/resources/directories_vue.png -------------------------------------------------------------------------------- /resources/directories_react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/resources/directories_react.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/services/CartService.d.ts: -------------------------------------------------------------------------------- 1 | import { ICart } from '../models/Cart'; 2 | export declare const cartService: ICart; 3 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactnativeui", 3 | "displayName": "reactnativeui" 4 | } -------------------------------------------------------------------------------- /resources/hexagonal_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/resources/hexagonal_architecture.png -------------------------------------------------------------------------------- /hexagonal-architecture/.gitignore: -------------------------------------------------------------------------------- 1 | *.map 2 | *.js.map 3 | *.lock 4 | /node_modules 5 | /lib 6 | /src/domain/**/*.js 7 | /src/infrastructure/**/*.js 8 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/cli-plugin-babel/preset'] 3 | }; 4 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/models/Product.d.ts: -------------------------------------------------------------------------------- 1 | export declare type Product = { 2 | id: string; 3 | title: string; 4 | price: number; 5 | }; 6 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/instances/httpAxios.d.ts: -------------------------------------------------------------------------------- 1 | import { Http } from '../../domain/repositories/Http'; 2 | export declare const httpAxios: Http; 3 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/instances/httpFake.d.ts: -------------------------------------------------------------------------------- 1 | import { Http } from '../../domain/repositories/Http'; 2 | export declare const httpFake: Http; 3 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue'; 3 | export default Vue; 4 | } 5 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/mocks/products.d.ts: -------------------------------------------------------------------------------- 1 | import { ProductDTO } from '../infrastructure/http/dto/ProductDTO'; 2 | export declare const productListMock: ProductDTO[]; 3 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/models/Product.ts: -------------------------------------------------------------------------------- 1 | // src/domain/models/Product.ts 2 | 3 | export type Product = { 4 | id: string; 5 | title: string; 6 | price: number; 7 | }; 8 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | reactnativeui 3 | 4 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeui/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/http/dto/ProductDTO.d.ts: -------------------------------------------------------------------------------- 1 | export interface ProductDTO { 2 | id: string; 3 | title: string; 4 | description: string; 5 | price: number; 6 | } 7 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/vue-ui/public/favicon.ico -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/react-ui/public/favicon.ico -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/react-ui/public/logo192.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/react-ui/public/logo512.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/services/ProductService.d.ts: -------------------------------------------------------------------------------- 1 | import { ProductRepository } from '../repositories/ProductRepository'; 2 | export declare const productService: (repository: ProductRepository) => ProductRepository; 3 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/instances/productRepositoryFake.d.ts: -------------------------------------------------------------------------------- 1 | import { ProductRepository } from '../../domain/repositories/ProductRepository'; 2 | export declare const productRepositoryFake: ProductRepository; 3 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | 4 | Vue.config.productionTip = false; 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount("#app"); 9 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/http/dto/ProductDTO.ts: -------------------------------------------------------------------------------- 1 | // src/infrastructure/http/dto/ProductDTO.ts 2 | 3 | export interface ProductDTO { 4 | id: string; 5 | title: string; 6 | description: string; 7 | price: number; 8 | } 9 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/reportWebVitals.d.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | declare const reportWebVitals: (onPerfEntry?: ReportHandler | undefined) => void; 3 | export default reportWebVitals; 4 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/debug.keystore -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/repositories/ProductRepository.d.ts: -------------------------------------------------------------------------------- 1 | import { Product } from '../models/Product'; 2 | export interface ProductRepository { 3 | getProducts: () => Promise; 4 | getProductsById: (id: string) => Promise; 5 | } 6 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/repositories/ProductRepository.ts: -------------------------------------------------------------------------------- 1 | import { Product } from '../models/Product'; 2 | 3 | export interface ProductRepository { 4 | getProducts: () => Promise; 5 | getProductsById: (id: string) => Promise; 6 | } 7 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'reactnativeui' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/repositories/productRepository.d.ts: -------------------------------------------------------------------------------- 1 | import { ProductRepository } from '../../domain/repositories/ProductRepository'; 2 | import { Http } from '../../domain/repositories/Http'; 3 | export declare const productRepository: (client: Http) => ProductRepository; 4 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/jestconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.(t|j)sx?$": "ts-jest" 4 | }, 5 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 6 | "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"] 7 | } 8 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import { AppRegistry } from 'react-native'; 6 | import App from './App'; 7 | import { name as appName } from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/jestconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.(t|j)sx?$": "ts-jest" 4 | }, 5 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 6 | "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"] 7 | } 8 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanm4/hexagonal-architecture-frontend/HEAD/hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeui/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /hexagonal-architecture/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | # 4 space indentation 12 | # [*.py] 13 | # indent_style = space 14 | # indent_size = 4 15 | -------------------------------------------------------------------------------- /hexagonal-architecture/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | testMatch: ['**/tests/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'], 5 | testPathIgnorePatterns: ['/node_modules/'], 6 | globals: { 'ts-jest': { diagnostics: false } }, 7 | transform: {} 8 | }; 9 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeui/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /hexagonal-architecture/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "printWidth": 140, 4 | "tabWidth": 4, 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "jsxBracketSameLine": false, 8 | "useTabs": false, 9 | "arrowParens": "avoid", 10 | "jsxSingleQuote": true, 11 | "trailingComma": "none" 12 | } 13 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | # 4 space indentation 12 | # [*.py] 13 | # indent_style = space 14 | # indent_size = 4 15 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | # 4 space indentation 12 | # [*.py] 13 | # indent_style = space 14 | # indent_size = 4 15 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | # 4 space indentation 12 | # [*.py] 13 | # indent_style = space 14 | # indent_size = 4 15 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "printWidth": 140, 4 | "tabWidth": 4, 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "jsxBracketSameLine": false, 8 | "useTabs": false, 9 | "arrowParens": "avoid", 10 | "jsxSingleQuote": true, 11 | "trailingComma": "none" 12 | } 13 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/.babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ["module-resolver", { 4 | "alias": { 5 | "@domain": "./../../../domain", 6 | "@infrastructure": "./../../../infrastructure", 7 | "@mocks": "./../../../mocks" 8 | } 9 | }] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "printWidth": 140, 4 | "tabWidth": 4, 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "jsxBracketSameLine": false, 8 | "useTabs": false, 9 | "arrowParens": "avoid", 10 | "jsxSingleQuote": true, 11 | "trailingComma": "none" 12 | } 13 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/config-overrides.js: -------------------------------------------------------------------------------- 1 | const { aliasDangerous } = require('react-app-rewire-alias/lib/aliasDangerous'); 2 | 3 | const aliasMap = { 4 | '@domain': '../../../domain', 5 | '@infrastructure': '../../../infrastructure', 6 | '@mocks': '../../../mocks' 7 | }; 8 | 9 | module.exports = aliasDangerous(aliasMap); 10 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/.babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ["module-resolver", { 4 | "alias": { 5 | "@domain": "./../../../domain", 6 | "@infrastructure": "./../../../infrastructure", 7 | "@mocks": "./../../../mocks" 8 | } 9 | }] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/models/Cart.d.ts: -------------------------------------------------------------------------------- 1 | import { Product } from './Product'; 2 | export interface ICart { 3 | createCart: () => Cart; 4 | addProductToCart: (cart: Cart, product: Product) => Cart; 5 | removeProductFromCart: (cart: Cart, product: Product) => Cart; 6 | } 7 | export declare type Cart = { 8 | id: string; 9 | products: Product[]; 10 | }; 11 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "semi": true, 3 | "printWidth": 140, 4 | "tabWidth": 4, 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "jsxBracketSameLine": false, 8 | "useTabs": false, 9 | "arrowParens": "avoid", 10 | "jsxSingleQuote": true, 11 | "trailingComma": "none" 12 | }; 13 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/__tests__/App-test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/src/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from "vue"; 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/repositories/Http.d.ts: -------------------------------------------------------------------------------- 1 | export interface Http { 2 | get: (path: string, params?: Record, config?: any) => Promise; 3 | post: (path: string, params?: Record, config?: any) => Promise; 4 | put: (path: string, params?: Record, config?: any) => Promise; 5 | delete: (path: string, params?: any, config?: any) => Promise; 6 | } 7 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/tsconfig.paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@domain/*": [ 6 | "../../../domain/*" 7 | ], 8 | "@infrastructure/*": [ 9 | "../../../infrastructure/*" 10 | ], 11 | "@mocks/*": [ 12 | "../../../mocks/*" 13 | ] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/repositories/Http.ts: -------------------------------------------------------------------------------- 1 | // src/domain/repositories/Http.ts 2 | 3 | export interface Http { 4 | get: (path: string, params?: Record, config?: any) => Promise; 5 | post: (path: string, params?: Record, config?: any) => Promise; 6 | put: (path: string, params?: Record, config?: any) => Promise; 7 | delete: (path: string, params?: any, config?: any) => Promise; 8 | } 9 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/models/Cart.ts: -------------------------------------------------------------------------------- 1 | // src/domain/models/Carts.ts 2 | 3 | import { Product } from './Product'; 4 | 5 | // This interface define what operations we can perform on a Cart 6 | export interface ICart { 7 | createCart: () => Cart; 8 | addProductToCart: (cart: Cart, product: Product) => Cart; 9 | removeProductFromCart: (cart: Cart, product: Product) => Cart; 10 | } 11 | 12 | export type Cart = { 13 | id: string; 14 | products: Product[]; 15 | }; 16 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | /package-lock.json 25 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/java/com/reactnativeui/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.reactnativeui; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. This is used to schedule 9 | * rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "reactnativeui"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | plugins: [ 4 | [ 5 | 'module-resolver', 6 | { 7 | alias: { 8 | '@domain': './../../../domain', 9 | '@infrastructure': './../../../infrastructure', 10 | '@mocks': './../../../mocks', 11 | '@': './src' 12 | } 13 | } 14 | ] 15 | ] 16 | }; 17 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/instances/productRepositoryFake.ts: -------------------------------------------------------------------------------- 1 | // src/infrastructure/repositories/product.repository.ts 2 | 3 | import { ProductRepository } from '../../domain/repositories/ProductRepository'; 4 | import { Http } from '../../domain/repositories/Http'; 5 | import { httpFake } from '../../infrastructure/instances/httpFake'; 6 | import { productRepository } from '../../infrastructure/repositories/productRepository'; 7 | 8 | const client: Http = httpFake; 9 | 10 | export const productRepositoryFake: ProductRepository = productRepository(client); 11 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/README.md: -------------------------------------------------------------------------------- 1 | # hexagonal-architecture-vue 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your unit tests 19 | ``` 20 | npm run test:unit 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import reportWebVitals from './reportWebVitals'; 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById('root') 11 | ); 12 | 13 | // If you want to start measuring performance in your app, pass a function 14 | // to log results (for example: reportWebVitals(console.log)) 15 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 16 | reportWebVitals(); 17 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/services/ProductService.ts: -------------------------------------------------------------------------------- 1 | // src/domain/services/ProductService.ts 2 | 3 | import { ProductRepository } from '../repositories/ProductRepository'; 4 | 5 | // Here we can change the repository by one that implement the IProductRepository interface 6 | //const repository: IProductRepository = productRepository; 7 | 8 | export const productService = (repository: ProductRepository): ProductRepository => ({ 9 | getProducts: () => { 10 | return repository.getProducts(); 11 | }, 12 | getProductsById: id => { 13 | return repository.getProductsById(id); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | module.exports = { 3 | chainWebpack: config => { 4 | config.module 5 | .rule('eslint') 6 | .use('eslint-loader') 7 | .tap(options => { 8 | options.configFile = path.resolve(__dirname, '.eslintrc.js'); 9 | return options; 10 | }); 11 | }, 12 | css: { 13 | loaderOptions: { 14 | postcss: { 15 | config: { 16 | path: __dirname 17 | } 18 | } 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /.idea/hexagonal-architecture-frontend.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.paths.json", 3 | "compilerOptions": { 4 | "target": "es5", 5 | "lib": [ 6 | "dom", 7 | "dom.iterable", 8 | "esnext" 9 | ], 10 | "allowJs": true, 11 | "skipLibCheck": true, 12 | "esModuleInterop": true, 13 | "allowSyntheticDefaultImports": true, 14 | "strict": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "noEmit": true, 22 | "jsx": "react-jsx" 23 | }, 24 | "include": [ 25 | "src" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/instances/httpFake.ts: -------------------------------------------------------------------------------- 1 | // src/infrastructure/instances/httpAxios.ts 2 | 3 | import { Http } from '../../domain/repositories/Http'; 4 | import { productListMock } from '../../mocks/products'; 5 | 6 | export const httpFake: Http = { 7 | get: async (path: string, params?: Record, config?: any) => { 8 | const response = await productListMock; 9 | return response; 10 | }, 11 | post: async (path: string, params?: Record, config?: any) => { 12 | const response = await productListMock; 13 | return response; 14 | }, 15 | put: async (path: string, params?: Record, config?: any) => {}, 16 | delete: async (path: string, params?: any, config?: any) => {} 17 | }; 18 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeui/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeuiTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeui-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "root": true, 3 | "env": { 4 | "node": true 5 | }, 6 | "extends": [ 7 | "plugin:vue/essential", 8 | "eslint:recommended", 9 | "@vue/typescript/recommended", 10 | "@vue/prettier", 11 | "@vue/prettier/@typescript-eslint" 12 | ], 13 | "parserOptions": { 14 | "ecmaVersion": 2020 15 | }, 16 | "rules": { 17 | "@typescript-eslint/interface-name-prefix": 'Off', 18 | "@typescript-eslint/no-var-requires": 'Off', 19 | "@typescript-eslint/no-empty-function": 'Off' 20 | }, 21 | "overrides": [ 22 | { 23 | "files": [ 24 | "**/__tests__/*.{j,t}s?(x)", 25 | "**/tests/unit/**/*.spec.{j,t}s?(x)" 26 | ], 27 | "env": { 28 | "jest": true 29 | } 30 | } 31 | ] 32 | }; 33 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/repositories/productRepository.ts: -------------------------------------------------------------------------------- 1 | // src/infrastructure/repositories/productRepository.ts 2 | 3 | import { Product } from '../../domain/models/Product'; 4 | import { ProductRepository } from '../../domain/repositories/ProductRepository'; 5 | import { Http } from '../../domain/repositories/Http'; 6 | import { ProductDTO } from '../../infrastructure/http/dto/ProductDTO'; 7 | 8 | export const productRepository = (client: Http): ProductRepository => ({ 9 | getProducts: async () => { 10 | const products = await client.get(''); 11 | return products.map((productDto): Product => ({ id: productDto.id, title: productDto.title, price: productDto.price })); 12 | }, 13 | 14 | getProductsById: async id => { 15 | const products = await client.get('', { id }); 16 | return products.map((productDto): Product => ({ id: productDto.id, title: productDto.title, price: productDto.price })); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | platform :ios, '10.0' 5 | 6 | target 'reactnativeui' do 7 | config = use_native_modules! 8 | 9 | use_react_native!(:path => config["reactNativePath"]) 10 | 11 | target 'reactnativeuiTests' do 12 | inherit! :complete 13 | # Pods for testing 14 | end 15 | 16 | # Enables Flipper. 17 | # 18 | # Note that if you have use_frameworks! enabled, Flipper will not work and 19 | # you should disable these next few lines. 20 | use_flipper! 21 | post_install do |installer| 22 | flipper_post_install(installer) 23 | end 24 | end 25 | 26 | target 'reactnativeui-tvOS' do 27 | # Pods for reactnativeui-tvOS 28 | 29 | target 'reactnativeui-tvOSTests' do 30 | inherit! :search_paths 31 | # Pods for testing 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/mocks/products.js: -------------------------------------------------------------------------------- 1 | export const productListMock = [ 2 | { 3 | id: '1', 4 | title: 'Product 1', 5 | description: 'Product 1 description', 6 | price: 10 7 | }, 8 | { 9 | id: '2', 10 | title: 'Product 2', 11 | description: 'Product 2 description', 12 | price: 10.5 13 | }, 14 | { 15 | id: '3', 16 | title: 'Product 3', 17 | description: 'Product 3 description', 18 | price: 15.7 19 | }, 20 | { 21 | id: '4', 22 | title: 'Product 4', 23 | description: 'Product 4 description', 24 | price: 20 25 | }, 26 | { 27 | id: '5', 28 | title: 'Product 5', 29 | description: 'Product 5 description', 30 | price: 25 31 | }, 32 | { 33 | id: '6', 34 | title: 'Product 6', 35 | description: 'Product 6 description', 36 | price: 40 37 | }, 38 | { 39 | id: '7', 40 | title: 'Product 7', 41 | description: 'Product 7 description', 42 | price: 80 43 | } 44 | ]; 45 | -------------------------------------------------------------------------------- /hexagonal-architecture/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ "es5", "es6", "es7", 5 | "es2015", "es2016", 6 | "es2017", "es2018", 7 | "esnext" ], 8 | "allowJs": true, 9 | "skipLibCheck": true, 10 | "esModuleInterop": true, 11 | "allowSyntheticDefaultImports": true, 12 | "strict": true, 13 | "jsx": "react", 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "forceConsistentCasingInFileNames": true, 17 | "module": "esnext", 18 | "resolveJsonModule": true, 19 | "noImplicitAny": false, 20 | "sourceMap": false, 21 | "typeRoots": [ 22 | "./node_modules/@types" 23 | ], 24 | "moduleResolution": "Node", 25 | "noFallthroughCasesInSwitch": true, 26 | "declaration": true, 27 | "rootDir": "./src", 28 | "outDir": "./lib", 29 | "checkJs": false 30 | }, 31 | "include": [ 32 | "./src/**/*" 33 | ], 34 | "exclude": [ 35 | "node_modules", 36 | "./src/infrastructure/views/*" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | 32 | # Visual Studio Code 33 | # 34 | .vscode/ 35 | 36 | # node.js 37 | # 38 | node_modules/ 39 | npm-debug.log 40 | yarn-error.log 41 | 42 | # BUCK 43 | buck-out/ 44 | \.buckd/ 45 | *.keystore 46 | !debug.keystore 47 | 48 | # fastlane 49 | # 50 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 51 | # screenshots whenever they are needed. 52 | # For more information about the recommended setup visit: 53 | # https://docs.fastlane.tools/best-practices/source-control/ 54 | 55 | */fastlane/report.xml 56 | */fastlane/Preview.html 57 | */fastlane/screenshots 58 | 59 | # Bundle artifact 60 | *.jsbundle 61 | 62 | # CocoaPods 63 | /ios/Pods/ 64 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/mocks/products.ts: -------------------------------------------------------------------------------- 1 | import { ProductDTO } from '../infrastructure/http/dto/ProductDTO'; 2 | 3 | export const productListMock: ProductDTO[] = [ 4 | { 5 | id: '1', 6 | title: 'Product 1', 7 | description: 'Product 1 description', 8 | price: 10 9 | }, 10 | { 11 | id: '2', 12 | title: 'Product 2', 13 | description: 'Product 2 description', 14 | price: 10.5 15 | }, 16 | { 17 | id: '3', 18 | title: 'Product 3', 19 | description: 'Product 3 description', 20 | price: 15.7 21 | }, 22 | { 23 | id: '4', 24 | title: 'Product 4', 25 | description: 'Product 4 description', 26 | price: 20 27 | }, 28 | { 29 | id: '5', 30 | title: 'Product 5', 31 | description: 'Product 5 description', 32 | price: 25 33 | }, 34 | { 35 | id: '6', 36 | title: 'Product 6', 37 | description: 'Product 6 description', 38 | price: 40 39 | }, 40 | { 41 | id: '7', 42 | title: 'Product 7', 43 | description: 'Product 7 description', 44 | price: 80 45 | } 46 | ]; 47 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/instances/httpAxios.ts: -------------------------------------------------------------------------------- 1 | // src/infrastructure/instances/httpAxios.ts 2 | 3 | import axios from 'axios'; 4 | import { Http } from '../../domain/repositories/Http'; 5 | 6 | const headers = { 7 | 'Content-Type': 'application/json' 8 | }; 9 | 10 | export const httpAxios: Http = { 11 | get: async (path: string, params?: Record, config?: any) => { 12 | const response = await axios.get(path, { ...config, params: params, headers }); 13 | return response.data as T; 14 | }, 15 | post: async (path: string, params?: Record, config?: any) => { 16 | const response = await axios.post(path, { ...params }, { ...config, headers }); 17 | return response.data as T; 18 | }, 19 | put: async (path: string, params?: Record, config?: any) => { 20 | const response = await axios.put(path, { ...params }, { ...config, headers }); 21 | return response.data as T; 22 | }, 23 | delete: async (path: string, params?: any, config?: any) => { 24 | const response = await axios.delete(path, { ...config, params: params, headers }); 25 | return response.data as T; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "29.0.2" 6 | minSdkVersion = 16 7 | compileSdkVersion = 29 8 | targetSdkVersion = 29 9 | } 10 | repositories { 11 | google() 12 | jcenter() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle:3.5.3") 16 | // NOTE: Do not place your application dependencies here; they belong 17 | // in the individual module build.gradle files 18 | } 19 | } 20 | 21 | allprojects { 22 | repositories { 23 | mavenLocal() 24 | maven { 25 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 26 | url("$rootDir/../node_modules/react-native/android") 27 | } 28 | maven { 29 | // Android JSC is installed from npm 30 | url("$rootDir/../node_modules/jsc-android/dist") 31 | } 32 | 33 | google() 34 | jcenter() 35 | maven { url 'https://www.jitpack.io' } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/src/views/ProductList.vue: -------------------------------------------------------------------------------- 1 | 4 | 14 | 15 | 43 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.54.0 29 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | const path = require('path'); 9 | 10 | const extraNodeModules = { 11 | '@': path.resolve(__dirname, './src'), 12 | '@domain': path.resolve(__dirname, '../../../domain'), 13 | '@infrastructure': path.resolve(__dirname, '../../../infrastructure'), 14 | '@mocks': path.resolve(__dirname, '../../../mocks') 15 | }; 16 | const watchFolders = [ 17 | path.resolve(__dirname, '.'), 18 | path.resolve(__dirname, '../../../domain'), 19 | path.resolve(__dirname, '../../../infrastructure/http'), 20 | path.resolve(__dirname, '../../../infrastructure/repositories'), 21 | path.resolve(__dirname, '../../../infrastructure/instances'), 22 | path.resolve(__dirname, '../../../mocks') 23 | ]; 24 | 25 | module.exports = { 26 | transformer: { 27 | getTransformOptions: async () => ({ 28 | transform: { 29 | experimentalImportSupport: false, 30 | inlineRequires: false 31 | } 32 | }) 33 | }, 34 | resolver: { 35 | extraNodeModules: new Proxy(extraNodeModules, { 36 | get: (target, name) => 37 | //redirects dependencies referenced from common/ to local node_modules 38 | name in target ? target[name] : path.join(process.cwd(), `node_modules/${name}`) 39 | }) 40 | }, 41 | watchFolders 42 | }; 43 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "experimentalDecorators": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "sourceMap": false, 14 | "baseUrl": ".", 15 | "composite": true, 16 | "types": [ 17 | "webpack-env", 18 | "jest" 19 | ], 20 | "paths": { 21 | "@/*": [ 22 | "src/*" 23 | ], 24 | "@domain/*": [ 25 | "../../../domain/*" 26 | ], 27 | "@infrastructure/*": [ 28 | "../../../infrastructure/*" 29 | ], 30 | "@mocks/*": [ 31 | "../../../mocks/*" 32 | ] 33 | }, 34 | "lib": [ 35 | "esnext", 36 | "dom", 37 | "dom.iterable", 38 | "scripthost" 39 | ] 40 | }, 41 | "include": [ 42 | "src/**/*.ts", 43 | "src/**/*.tsx", 44 | "src/**/*.vue", 45 | "tests/**/*.ts", 46 | "tests/**/*.tsx", 47 | "../../../domain/**/*.ts", 48 | "../../../infrastructure/**/*.ts", 49 | "../../../mocks/**/*.ts" 50 | ], 51 | "exclude": [ 52 | "node_modules" 53 | ], 54 | } 55 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/tests/cart.test.ts: -------------------------------------------------------------------------------- 1 | // src/tests/cart.test.ts 2 | 3 | import { cartService } from '../domain/services/CartService'; 4 | import { Product } from '../domain/models/Product'; 5 | 6 | const anyProduct = (id: string, price: number): Product => ({ 7 | id, 8 | title: 'Any title', 9 | price 10 | }); 11 | 12 | test('If I add more than five products, the sixth will not be added', async () => { 13 | const cart = cartService.createCart(); 14 | 15 | cartService.addProductToCart(cart, anyProduct('1', 0)); 16 | cartService.addProductToCart(cart, anyProduct('2', 0)); 17 | cartService.addProductToCart(cart, anyProduct('3', 0)); 18 | cartService.addProductToCart(cart, anyProduct('4', 0)); 19 | cartService.addProductToCart(cart, anyProduct('5', 0)); 20 | cartService.addProductToCart(cart, anyProduct('6', 0)); 21 | expect(cart.products.length).toEqual(5); 22 | }); 23 | 24 | test('If I add a product and it already exist in the cart, the product will not be added', async () => { 25 | const cart = cartService.createCart(); 26 | 27 | cartService.addProductToCart(cart, anyProduct('1', 0)); 28 | cartService.addProductToCart(cart, anyProduct('1', 0)); 29 | expect(cart.products.length).toEqual(1); 30 | }); 31 | 32 | test('If I add a product and it will exceed 100€, the product will not be added', async () => { 33 | const cart = cartService.createCart(); 34 | 35 | cartService.addProductToCart(cart, anyProduct('1', 50)); 36 | cartService.addProductToCart(cart, anyProduct('2', 60)); 37 | expect(cart.products.length).toEqual(1); 38 | }); 39 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/android/app/_BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.reactnativeui", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.reactnativeui", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/domain/services/CartService.ts: -------------------------------------------------------------------------------- 1 | // src/domain/services/Cart.service.ts 2 | 3 | import { Cart, ICart } from '../models/Cart'; 4 | import { Product } from '../models/Product'; 5 | 6 | const createCart = (): Cart => { 7 | return { id: Date.now().toString(), products: [] }; 8 | }; 9 | 10 | const hasProduct = (cart: Cart, product: Product): boolean => { 11 | return !!cart.products.find(item => item.id === product.id); 12 | }; 13 | 14 | const isCartFull = (cart: Cart): boolean => { 15 | return cart.products.length >= 5; 16 | }; 17 | 18 | const isCartLimitPriceExceeded = (cart: Cart, product: Product, limit: number): boolean => { 19 | let totalPriceCart = 0; 20 | cart.products.forEach(item => { 21 | totalPriceCart += item.price; 22 | }); 23 | totalPriceCart += product.price; 24 | 25 | return totalPriceCart > limit; 26 | }; 27 | 28 | const addProductToCart = (cart: Cart, product: Product): Cart => { 29 | if (!hasProduct(cart, product) && !isCartFull(cart) && !isCartLimitPriceExceeded(cart, product, 100)) 30 | cart.products = [...cart.products, product]; 31 | return { ...cart }; 32 | }; 33 | 34 | const removeProductFromCart = (cart: Cart, product: Product): Cart => { 35 | const productsWithRemovedItem: Product[] = []; 36 | cart.products.forEach(item => { 37 | if (item.id !== product.id) productsWithRemovedItem.push(item); 38 | }); 39 | cart.products = [...productsWithRemovedItem]; 40 | return { ...cart }; 41 | }; 42 | 43 | // This service must implement the operations defined for the Cart interface 44 | export const cartService: ICart = { 45 | createCart, 46 | addProductToCart, 47 | removeProductFromCart 48 | }; 49 | -------------------------------------------------------------------------------- /hexagonal-architecture/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexagonal-architecture", 3 | "version": "1.0.0", 4 | "description": "How to implement Hexagonal architecture in frontend (Javascript/Typescript)", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "keywords": [ 8 | "hexagonal", 9 | "architecture", 10 | "DDD", 11 | "clean", 12 | "SOLID", 13 | "React", 14 | "Vue" 15 | ], 16 | "scripts": { 17 | "test": "jest --verbose ./src/tests", 18 | "build": "tsc", 19 | "watch": "tsc --watch", 20 | "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", 21 | "lint": "eslint -c .eslintrc.js --ext .ts src" 22 | }, 23 | "author": "juanm4@gmail.com", 24 | "license": "ISC", 25 | "devDependencies": { 26 | "@types/jest": "^26.0.20", 27 | "@typescript-eslint/eslint-plugin": "^4.15.0", 28 | "@typescript-eslint/parser": "^4.15.0", 29 | "babel-plugin-module-resolver": "^4.1.0", 30 | "babel-plugin-root-import": "^6.6.0", 31 | "eslint": "^7.20.0", 32 | "eslint-config-prettier": "^7.2.0", 33 | "eslint-plugin-import": "^2.22.1", 34 | "eslint-plugin-jest": "^24.1.3", 35 | "eslint-plugin-json": "^2.1.2", 36 | "eslint-plugin-prettier": "^3.3.1", 37 | "prettier": "^2.2.1", 38 | "prettier-eslint": "^12.0.0", 39 | "ts-jest": "^26.5.1", 40 | "ts-node": "^9.1.1", 41 | "tslint": "^6.1.3", 42 | "typescript": "^4.1.5" 43 | }, 44 | "dependencies": { 45 | "axios": "^0.21.1" 46 | }, 47 | "files": [ 48 | "lib/**/*", 49 | "package.json" 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeui-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSExceptionDomains 28 | 29 | localhost 30 | 31 | NSExceptionAllowsInsecureHTTPLoads 32 | 33 | 34 | 35 | 36 | NSLocationWhenInUseUsageDescription 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/views/ProductList.tsx: -------------------------------------------------------------------------------- 1 | // src/infrastructure/views/react-ui/src/views/ProductList.tsx 2 | 3 | import React, { useCallback } from 'react'; 4 | import { Product } from '@domain/models/Product'; 5 | import { productService } from '@domain/services/ProductService'; 6 | import { productRepositoryFake } from '@infrastructure/instances/productRepositoryFake'; 7 | 8 | interface ProductListProps { 9 | onSelectProduct: (product: Product) => void; 10 | } 11 | 12 | export const ProductList: React.FC = ({ onSelectProduct }) => { 13 | const [products, setProducts] = React.useState([]); 14 | 15 | const getProducts = useCallback(async () => { 16 | try { 17 | const responseProducts = await productService(productRepositoryFake).getProducts(); 18 | setProducts(responseProducts); 19 | } catch (exception) { 20 | console.error(exception); 21 | } 22 | }, []); 23 | 24 | React.useEffect(() => { 25 | getProducts(); 26 | }, []); 27 | 28 | const handleSelectProduct = (product: Product) => { 29 | onSelectProduct(product); 30 | }; 31 | 32 | return ( 33 |
34 |

List of products

35 |
    36 | {products.map(product => ( 37 |
  • 38 | 45 |
  • 46 | ))} 47 |
48 |
49 | ); 50 | }; 51 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-ui", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "test:unit": "vue-cli-service test:unit", 9 | "lint": "vue-cli-service lint" 10 | }, 11 | "dependencies": { 12 | "axios": "^0.21.1", 13 | "core-js": "^3.6.5", 14 | "vue": "^2.6.11", 15 | "vue-class-component": "^7.2.3", 16 | "vue-property-decorator": "^9.1.2" 17 | }, 18 | "devDependencies": { 19 | "@types/jest": "^24.0.19", 20 | "@typescript-eslint/eslint-plugin": "^2.33.0", 21 | "@typescript-eslint/parser": "^2.33.0", 22 | "@vue/cli-plugin-babel": "~4.5.0", 23 | "@vue/cli-plugin-eslint": "~4.5.0", 24 | "@vue/cli-plugin-typescript": "~4.5.0", 25 | "@vue/cli-plugin-unit-jest": "~4.5.0", 26 | "@vue/cli-service": "~4.5.0", 27 | "@vue/eslint-config-prettier": "^6.0.0", 28 | "@vue/eslint-config-typescript": "^5.0.2", 29 | "@vue/test-utils": "^1.0.3", 30 | "babel-plugin-module-resolver": "^4.1.0", 31 | "eslint": "^6.7.2", 32 | "eslint-import-resolver-babel-module": "^5.2.0", 33 | "eslint-loader": "^2.2.1", 34 | "eslint-plugin-import": "^2.22.1", 35 | "eslint-plugin-prettier": "^3.1.3", 36 | "eslint-plugin-vue": "^6.2.2", 37 | "prettier": "^1.19.1", 38 | "typescript": "~3.9.3", 39 | "vue-template-compiler": "^2.6.11" 40 | }, 41 | "browserslist": [ 42 | "> 1%", 43 | "last 2 versions", 44 | "not dead" 45 | ], 46 | "jest": { 47 | "preset": "@vue/cli-plugin-unit-jest/presets/typescript-and-babel" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | rules: { 5 | 'linebreak-style': 'off', 6 | 'prettier/prettier': 'warn', 7 | 'no-unused-vars': 'off', 8 | '@typescript-eslint/no-explicit-any': 'off', 9 | '@typescript-eslint/no-parameter-properties': 'off', 10 | '@typescript-eslint/no-unused-vars': ['warn', {argsIgnorePattern: '^_', varsIgnorePattern: '^ignored?$'}], 11 | '@typescript-eslint/no-unused-vars-experimental': 'off', 12 | 'no-empty-function': 'warn', 13 | '@typescript-eslint/no-empty-function': 0, 14 | '@typescript-eslint/explicit-module-boundary-types': 'off', 15 | '@typescript-eslint/ban-ts-comment': 'off', 16 | // Existing rules 17 | 'comma-dangle': ['warn', 'never'], // https://eslint.org/docs/rules/comma-dangle 18 | trailingComma: 'off', 19 | 'function-paren-newline': 'off', // https://eslint.org/docs/rules/function-paren-newline 20 | 'global-require': 'off', // https://eslint.org/docs/rules/global-require 21 | 'import/no-dynamic-require': 'off', // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-dynamic-require.md 22 | 'no-inner-declarations': 'off', // https://eslint.org/docs/rules/no-inner-declarations 23 | // New rules 24 | 'class-methods-use-this': 'off', 25 | 'import/extensions': 'off', 26 | 'import/prefer-default-export': 'off', 27 | '@typescript-eslint/explicit-function-return-type': 'off', 28 | '@typescript-eslint/no-var-requires': 'off', 29 | 'react/no-unescaped-entities': 'warn', 30 | 'react/prop-types': ['Off'], 31 | 'jsx-quotes': ["warn", "prefer-single"], 32 | 'react-hooks/exhaustive-deps': 'off' 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeui/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | reactnativeui 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSLocationWhenInUseUsageDescription 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UIViewControllerBasedStatusBarAppearance 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/App.tsx: -------------------------------------------------------------------------------- 1 | // src/infrastructure/views/react-ui/src/App.tsx 2 | 3 | import React, { useState } from 'react'; 4 | import { ProductList } from './views/ProductList'; 5 | import { Cart } from '@domain/models/Cart'; 6 | import { Product } from '@domain/models/Product'; 7 | import { cartService } from '@domain/services/CartService'; 8 | 9 | const App = () => { 10 | const [cart, setCart] = useState(cartService.createCart()); 11 | 12 | const handleAddToCart = (product: Product) => { 13 | setCart(cartService.addProductToCart(cart, product)); 14 | }; 15 | 16 | const handleRemoveToCart = (product: Product) => { 17 | setCart(cartService.removeProductFromCart(cart, product)); 18 | }; 19 | 20 | const renderCartProducts = (): JSX.Element[] => { 21 | const cartProducts: JSX.Element[] = []; 22 | let totalCart = 0; 23 | 24 | cart.products.forEach(product => { 25 | totalCart += product.price; 26 | cartProducts.push( 27 |
28 | 29 | ({product.price} €) 30 | 31 |
32 |
33 | ); 34 | }); 35 | 36 | cartProducts.push( 37 |
38 |
39 | 42 | {totalCart} € 43 |
44 |
45 | ); 46 | return cartProducts; 47 | }; 48 | 49 | return ( 50 |
51 |

Shopping cart

52 |

Products in the cart

53 | {renderCartProducts()} 54 | 55 |
56 | ); 57 | }; 58 | 59 | export default App; 60 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/vue-ui/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 25 | 26 | 65 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactnativeui", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint . --ext .js,.jsx,.ts,.tsx", 11 | "restart-cache-sh": "rm -rf $TMPDIR/metro-* && rm -rf $TMPDIR/haste-* && watchman watch-del-all && rm -rf node_modules/ && npm install && npm start -- --reset-cache" 12 | }, 13 | "dependencies": { 14 | "axios": "^0.21.1", 15 | "react": "16.13.1", 16 | "react-native": "0.63.4", 17 | "react-native-cli": "^2.0.1" 18 | }, 19 | "devDependencies": { 20 | "@babel/core": "^7.8.4", 21 | "@babel/runtime": "^7.8.4", 22 | "@react-native-community/eslint-config": "^1.1.0", 23 | "@types/jest": "^25.2.3", 24 | "@types/react-native": "^0.63.2", 25 | "@types/react-test-renderer": "^16.9.2", 26 | "babel-jest": "^25.1.0", 27 | "babel-plugin-module-resolver": "^4.1.0", 28 | "babel-plugin-root-import": "^6.6.0", 29 | "eslint": "^6.5.1", 30 | "eslint-loader": "^4.0.2", 31 | "eslint-plugin-import": "^2.22.1", 32 | "eslint-plugin-jest": "^24.1.3", 33 | "eslint-plugin-json": "^2.1.2", 34 | "eslint-plugin-prettier": "^3.3.1", 35 | "eslint-plugin-react": "^7.22.0", 36 | "jest": "^25.1.0", 37 | "metro-react-native-babel-preset": "^0.59.0", 38 | "prettier": "^2.2.1", 39 | "prettier-eslint": "^12.0.0", 40 | "react-test-renderer": "16.13.1", 41 | "typescript": "^3.8.3" 42 | }, 43 | "resolutions": { 44 | "@types/react": "^16" 45 | }, 46 | "jest": { 47 | "preset": "react-native", 48 | "moduleFileExtensions": [ 49 | "ts", 50 | "tsx", 51 | "js", 52 | "jsx", 53 | "json", 54 | "node" 55 | ] 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-ui", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "@types/jest": "^26.0.15", 10 | "@types/node": "^12.0.0", 11 | "@types/react": "^17.0.0", 12 | "@types/react-dom": "^17.0.0", 13 | "react": "^17.0.1", 14 | "react-dom": "^17.0.1", 15 | "react-scripts": "4.0.2", 16 | "typescript": "^4.1.2", 17 | "web-vitals": "^1.0.1" 18 | }, 19 | "scripts": { 20 | "start": "react-app-rewired start", 21 | "build": "react-app-rewired build", 22 | "test": "react-app-rewired test", 23 | "eject": "react-scripts eject" 24 | }, 25 | "eslintConfig": { 26 | "extends": [ 27 | "react-app", 28 | "react-app/jest" 29 | ] 30 | }, 31 | "browserslist": { 32 | "production": [ 33 | ">0.2%", 34 | "not dead", 35 | "not op_mini all" 36 | ], 37 | "development": [ 38 | "last 1 chrome version", 39 | "last 1 firefox version", 40 | "last 1 safari version" 41 | ] 42 | }, 43 | "devDependencies": { 44 | "@testing-library/react": "^11.2.5", 45 | "@types/jest": "^26.0.20", 46 | "@typescript-eslint/eslint-plugin": "^4.14.2", 47 | "babel-plugin-module-resolver": "^4.1.0", 48 | "babel-plugin-root-import": "^6.6.0", 49 | "eslint-config-prettier": "^7.2.0", 50 | "eslint-loader": "^4.0.2", 51 | "eslint-plugin-import": "^2.22.1", 52 | "eslint-plugin-jest": "^24.1.3", 53 | "eslint-plugin-json": "^2.1.2", 54 | "eslint-plugin-prettier": "^3.3.1", 55 | "eslint-plugin-react": "^7.22.0", 56 | "prettier": "^2.2.1", 57 | "prettier-eslint": "^12.0.0", 58 | "react-app-rewire-alias": "^1.0.0", 59 | "react-app-rewired": "^2.1.8" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeuiTests/reactnativeuiTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface reactnativeuiTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation reactnativeuiTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 38 | if (level >= RCTLogLevelError) { 39 | redboxError = message; 40 | } 41 | }); 42 | #endif 43 | 44 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 45 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 46 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | 48 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 49 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 50 | return YES; 51 | } 52 | return NO; 53 | }]; 54 | } 55 | 56 | #ifdef DEBUG 57 | RCTSetLogFunction(RCTDefaultLogFunction); 58 | #endif 59 | 60 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 61 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/src/components/ProductList.tsx: -------------------------------------------------------------------------------- 1 | // src/infrastructure/views/reactnative-ui/src/components/ProductList.tsx 2 | 3 | import React, { useCallback, useState } from 'react'; 4 | import { StyleSheet, View, Text, Button } from 'react-native'; 5 | 6 | import { Product } from '@domain/models/Product'; 7 | import { productService } from '@domain/services/ProductService'; 8 | import { productRepositoryFake } from '@infrastructure/instances/productRepositoryFake'; 9 | 10 | interface ProductListProps { 11 | onSelectProduct: (product: Product) => void; 12 | } 13 | 14 | export const ProductList: React.FC = ({ onSelectProduct }) => { 15 | const [products, setProducts] = useState([]); 16 | 17 | const getProducts = useCallback(async () => { 18 | try { 19 | const responseProducts = await productService(productRepositoryFake).getProducts(); 20 | setProducts(responseProducts); 21 | } catch (exception) { 22 | console.error(exception); 23 | } 24 | }, []); 25 | 26 | React.useEffect(() => { 27 | getProducts(); 28 | }, []); 29 | 30 | const handleSelectProduct = (product: Product) => { 31 | onSelectProduct(product); 32 | }; 33 | 34 | return ( 35 | 36 | List of products 37 | 38 | {products.map(product => ( 39 | 40 | 48 | 49 | ))} 50 | 51 | 52 | ); 53 | }; 54 | 55 | const styles = StyleSheet.create({ 56 | title: { 57 | fontWeight: 'bold', 58 | margin: 5 59 | }, 60 | buttonProduct: { 61 | margin: 5 62 | } 63 | }); 64 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm run start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `npm run test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/ios/reactnativeui/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | #import 6 | 7 | #ifdef FB_SONARKIT_ENABLED 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | 15 | static void InitializeFlipper(UIApplication *application) { 16 | FlipperClient *client = [FlipperClient sharedClient]; 17 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; 18 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; 19 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; 20 | [client addPlugin:[FlipperKitReactPlugin new]]; 21 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; 22 | [client start]; 23 | } 24 | #endif 25 | 26 | @implementation AppDelegate 27 | 28 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 29 | { 30 | #ifdef FB_SONARKIT_ENABLED 31 | InitializeFlipper(application); 32 | #endif 33 | 34 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 35 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 36 | moduleName:@"reactnativeui" 37 | initialProperties:nil]; 38 | 39 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 40 | 41 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 42 | UIViewController *rootViewController = [UIViewController new]; 43 | rootViewController.view = rootView; 44 | self.window.rootViewController = rootViewController; 45 | [self.window makeKeyAndVisible]; 46 | return YES; 47 | } 48 | 49 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 50 | { 51 | #if DEBUG 52 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 53 | #else 54 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 55 | #endif 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/react-ui/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hexagonal-architecture/src/infrastructure/views/reactnative-ui/App.tsx: -------------------------------------------------------------------------------- 1 | // src/infrastructure/views/reactnative-ui/App.tsx 2 | 3 | import React, { useState } from 'react'; 4 | import { SafeAreaView, StyleSheet, ScrollView, View, Text, StatusBar, Button } from 'react-native'; 5 | 6 | import { Colors } from 'react-native/Libraries/NewAppScreen'; 7 | import { Cart } from '@domain/models/Cart'; 8 | import { cartService } from '@domain/services/CartService'; 9 | import { Product } from '@domain/models/Product'; 10 | import { ProductList } from '@/components/ProductList'; 11 | 12 | const App = () => { 13 | const [cart, setCart] = useState(cartService.createCart()); 14 | 15 | const handleAddToCart = (product: Product) => { 16 | setCart(cartService.addProductToCart(cart, product)); 17 | }; 18 | 19 | const handleRemoveToCart = (product: Product) => { 20 | setCart(cartService.removeProductFromCart(cart, product)); 21 | }; 22 | 23 | const renderCartProducts = (): JSX.Element[] => { 24 | const cartProducts: JSX.Element[] = []; 25 | let totalCart = 0; 26 | 27 | cart.products.forEach(product => { 28 | totalCart += product.price; 29 | cartProducts.push( 30 | 31 | {product.title} 32 | ({product.price} €) 33 |