├── .browserslistrc ├── .eslintignore ├── .eslintrc.js ├── .git-crypt ├── .gitattributes └── keys │ └── default │ └── 0 │ ├── 147885163DF27F4877B0BC14DE8C27DDE38F1E61.gpg │ ├── 49AB3942E38DB928ACF3905EC2DB4383B4A6E5EA.gpg │ ├── 49F363DC4362D3C17B2FE0091871B202236FD41B.gpg │ ├── 54EBB791640A664510494E416177B1BAA1083A88.gpg │ ├── 70961F6ECD8220394FD8AB555E94AC25CBCBA1A3.gpg │ └── EBA4B7A860BD152BF5F9F727F12B84D048062B79.gpg ├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── .gitignore ├── .markdownlint.json ├── .markdownlintignore ├── .npmrc ├── .travis.yml ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── ISSUES.md ├── Jenkinsfile ├── LICENSE ├── README.md ├── ScreenShot.png ├── babel.config.js ├── build.config.js ├── codegen.yml ├── commitlint.config.js ├── config ├── development │ ├── .gitignore │ ├── dev.env.sample │ └── settings.json ├── production │ └── .gitignore ├── staging │ └── .gitignore └── test │ ├── .gitignore │ └── test.env.sample ├── docs ├── Moleculer.md ├── References.md └── development │ ├── CodeContribution │ ├── Adding_New_Modules.md │ ├── Desktop_Setup.md │ ├── DoAndDont.md │ ├── GitHooks.md │ ├── HowToContribute.md │ ├── How_to_Run_Various_Options.md │ ├── Known_Issues.md │ ├── Lint_And_Formatter.md │ ├── Project_Setup.md │ ├── React-Patterns │ │ ├── Dynamically_Render_Components.md │ │ ├── HOC_With_Render_Props.md │ │ ├── Mongoose_Connection.md │ │ ├── React_Componet_Extensions.md │ │ ├── RxJS_notes.md │ │ └── Styles_With_Type.md │ ├── Tutorials.md │ ├── faq.md │ ├── installation_issues.md │ ├── lerna-build-tools.md │ └── lerna-yarn-workspaces.md │ ├── Database │ └── mongodb-test.md │ ├── Deployment │ ├── How_To_Setup_Jenkins.md │ └── JenkinsDeployment.md │ ├── Expo │ └── expo-commands.md │ └── Mobile │ ├── How_To_Make_Expo_Wrok_With_Monorepos.md │ ├── React-Native-FAQ.md │ └── Run_mobile.md ├── husky.config.js ├── jenkins_variables.groovy ├── jest-mongodb-config.js ├── jest-transform-i18next.js ├── jest.config.base.js ├── jest.config.js ├── jest.config.mongodb.js ├── lerna.json ├── lint-staged.config.js ├── nx.json ├── package.json ├── packages-modules └── counter │ ├── browser │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── apollo-server-n-client │ │ │ ├── components │ │ │ │ └── CounterView.tsx │ │ │ ├── compute.tsx │ │ │ ├── containers │ │ │ │ └── Counter.tsx │ │ │ ├── generated-model.tsx │ │ │ ├── graphql │ │ │ │ ├── __tests__ │ │ │ │ │ ├── apollo-client-test-helper.ts │ │ │ │ │ └── apollo-client.test.ts │ │ │ │ ├── id-generation.ts │ │ │ │ ├── index.ts │ │ │ │ ├── mutations │ │ │ │ │ ├── AddCounter.client.gql │ │ │ │ │ ├── AddCounter.gql │ │ │ │ │ ├── AddCounter_WS.gql │ │ │ │ │ └── SyncCachedCounter.gql │ │ │ │ ├── queries │ │ │ │ │ ├── CounterCacheQuery_WS.gql │ │ │ │ │ ├── CounterQuery.client.gql │ │ │ │ │ └── CounterQuery.gql │ │ │ │ ├── resolvers │ │ │ │ │ ├── index.ts │ │ │ │ │ └── resolvers.ts │ │ │ │ ├── schema │ │ │ │ │ └── counter-state.graphql │ │ │ │ └── subscriptions │ │ │ │ │ └── CounterSubscription.gql │ │ │ ├── index.ts │ │ │ ├── module.tsx │ │ │ └── redux │ │ │ │ ├── index.ts │ │ │ │ └── reducers │ │ │ │ └── index.ts │ │ ├── common │ │ │ ├── components │ │ │ │ ├── Dashboard.tsx │ │ │ │ └── Home.tsx │ │ │ ├── compute.tsx │ │ │ ├── generated-models.ts │ │ │ ├── index.ts │ │ │ ├── interfaces │ │ │ │ └── context.ts │ │ │ └── module.tsx │ │ ├── connected-react-router │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── connected-react-router-module.test.ts.snap │ │ │ │ └── connected-react-router-module.test.ts │ │ │ ├── components │ │ │ │ ├── Counter.tsx │ │ │ │ ├── Hello.tsx │ │ │ │ ├── HelloChild.tsx │ │ │ │ ├── Home.tsx │ │ │ │ ├── NavBar.tsx │ │ │ │ └── NoMatch.tsx │ │ │ ├── compute.tsx │ │ │ ├── constants │ │ │ │ ├── action-types.ts │ │ │ │ ├── index.ts │ │ │ │ └── routes-types.ts │ │ │ ├── electron-module.tsx │ │ │ ├── index.electron.ts │ │ │ ├── index.ts │ │ │ ├── interfaces │ │ │ │ ├── index.ts │ │ │ │ └── state.ts │ │ │ ├── module.tsx │ │ │ └── redux │ │ │ │ ├── actions │ │ │ │ ├── counter.ts │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── reducers │ │ │ │ ├── counter.ts │ │ │ │ └── index.ts │ │ ├── emotion │ │ │ ├── README.md │ │ │ ├── components │ │ │ │ ├── CompledWithTheme.tsx │ │ │ │ ├── ComplexComponent.tsx │ │ │ │ ├── button.tsx │ │ │ │ ├── form.tsx │ │ │ │ ├── header.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.ts │ │ │ ├── compute.tsx │ │ │ ├── index.ts │ │ │ ├── interfaces │ │ │ │ ├── index.ts │ │ │ │ └── theme.ts │ │ │ ├── module.tsx │ │ │ └── theme.ts │ │ ├── generated-models.ts │ │ ├── index.ts │ │ └── utils │ │ │ ├── index.ts │ │ │ └── menu.ts │ ├── tsconfig.json │ ├── typings │ │ └── graphql.d.ts │ └── webpack.config.js │ ├── electron │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── epics │ │ │ ├── count-tray-updater.ts │ │ │ └── index.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── typings │ │ └── graphql.d.ts │ └── webpack.config.js │ ├── mobile │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── common │ │ │ ├── components │ │ │ │ ├── Dashboard.tsx │ │ │ │ └── Home.tsx │ │ │ ├── compute.tsx │ │ │ ├── generated-models.ts │ │ │ ├── index.ts │ │ │ ├── interfaces │ │ │ │ └── context.ts │ │ │ └── module.tsx │ │ ├── connected-react-router │ │ │ ├── README.md │ │ │ ├── components │ │ │ │ ├── Counter.tsx │ │ │ │ └── Hello.tsx │ │ │ ├── compute.tsx │ │ │ ├── constants │ │ │ │ ├── action-types.ts │ │ │ │ ├── index.ts │ │ │ │ └── routes-types.ts │ │ │ ├── index.ts │ │ │ ├── interfaces │ │ │ │ ├── index.ts │ │ │ │ └── state.ts │ │ │ ├── module.tsx │ │ │ └── redux │ │ │ │ ├── actions │ │ │ │ ├── counter.ts │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── reducers │ │ │ │ ├── counter.ts │ │ │ │ └── index.ts │ │ ├── index.ts │ │ └── utils │ │ │ ├── index.ts │ │ │ └── menu.ts │ ├── tsconfig.json │ └── typings │ │ └── graphql.d.ts │ └── server │ ├── jest.config.js │ ├── package.json │ ├── src │ ├── config │ │ ├── env-config.ts │ │ └── index.ts │ ├── constants │ │ ├── constants.ts │ │ └── index.ts │ ├── containers │ │ ├── containers.ts │ │ └── index.ts │ ├── dataloader │ │ ├── cache.ts │ │ ├── counter-dataloader.ts │ │ └── index.ts │ ├── generated-models.ts │ ├── graphqlTypes │ │ ├── index.ts │ │ ├── resolvers.ts │ │ └── schema.graphql │ ├── index.ts │ ├── interfaces │ │ ├── context.ts │ │ ├── counter-service.ts │ │ └── index.ts │ ├── module.ts │ ├── resolvers │ │ ├── index.ts │ │ └── resolver.ts │ ├── schema │ │ └── schema.graphql │ └── services │ │ ├── counter-mock-microservice.ts │ │ ├── counter-mock-moleculer-service.ts │ │ ├── counter-mock-proxy-service.ts │ │ ├── counter-mock-service.ts │ │ └── index.ts │ ├── tsconfig.json │ └── webpack.config.js ├── packages ├── assets │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── assets │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-256x256.png │ │ │ ├── apple-touch-icon-120x120.png │ │ │ ├── apple-touch-icon-180x180.png │ │ │ ├── browserconfig.xml │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon.ico │ │ │ ├── manifest.xjson │ │ │ ├── mstile-150x50.png │ │ │ └── safari-pinned-tab.svg │ │ ├── index.js │ │ └── original │ │ │ ├── master-bw.svg │ │ │ ├── master-greyed.svg │ │ │ └── master.svg │ ├── tsconfig.json │ └── webpack.config.js ├── sample-core │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── webpack.config.js ├── sample-platform │ ├── browser │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src │ │ │ ├── api.ts │ │ │ ├── components │ │ │ │ ├── Counter.tsx │ │ │ │ ├── NavBar.tsx │ │ │ │ └── index.ts │ │ │ ├── containers │ │ │ │ ├── Clock.tsx │ │ │ │ ├── Counter.tsx │ │ │ │ ├── Loading.tsx │ │ │ │ ├── PersonList.tsx │ │ │ │ ├── ServerCounter.tsx │ │ │ │ ├── __tests__ │ │ │ │ │ ├── ApolloProvider.test.tsx │ │ │ │ │ ├── Counter.test.tsx │ │ │ │ │ ├── PersonList.test.tsx │ │ │ │ │ ├── __snapshots__ │ │ │ │ │ │ ├── Counter.test.tsx.snap │ │ │ │ │ │ └── PersonList.test.tsx.snap │ │ │ │ │ ├── redux.test.tsx │ │ │ │ │ ├── setup.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── index.ts │ │ │ ├── graphql │ │ │ │ ├── index.ts │ │ │ │ ├── mutations │ │ │ │ │ ├── addCount.graphql │ │ │ │ │ ├── addPerson.graphql │ │ │ │ │ └── index.ts │ │ │ │ ├── queries │ │ │ │ │ ├── count.graphql │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── person.graphql │ │ │ │ │ └── persons.graphql │ │ │ │ └── subscriptions │ │ │ │ │ ├── count.graphql │ │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── inversify-containers │ │ │ │ ├── index.ts │ │ │ │ └── module.ts │ │ │ ├── module.ts │ │ │ ├── redux │ │ │ │ ├── __mocks__ │ │ │ │ │ └── api.ts │ │ │ │ ├── actions │ │ │ │ │ ├── __tests__ │ │ │ │ │ │ └── sampleActions.test.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── sampleActions.ts │ │ │ │ ├── index.ts │ │ │ │ └── reducers │ │ │ │ │ ├── Store.ts │ │ │ │ │ ├── __tests__ │ │ │ │ │ └── sampleReducers.test.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── sampleReducers.ts │ │ │ └── services │ │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js │ └── server │ │ ├── .npmignore │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js └── sample-store │ ├── .npmignore │ ├── README.md │ ├── package.json │ ├── src │ ├── __tests__ │ │ ├── counter-hemera-repository.test.ts │ │ ├── counter-repository.test.ts │ │ └── db │ │ │ ├── config.json │ │ │ ├── migrations │ │ │ └── counter.ts │ │ │ └── seeds │ │ │ └── counter.ts │ ├── constants │ │ ├── constants.ts │ │ └── index.ts │ ├── container │ │ ├── index.ts │ │ └── module.ts │ ├── database-store │ │ ├── migrations │ │ │ ├── counter.ts │ │ │ └── index.ts │ │ └── seeds │ │ │ ├── counter.ts │ │ │ └── index.ts │ ├── db-helpers │ │ ├── abstract-repository.ts │ │ ├── db-config.ts │ │ ├── entity.ts │ │ ├── index.ts │ │ └── repository.ts │ ├── index.ts │ ├── models │ │ ├── counter.ts │ │ ├── index.ts │ │ └── interfaces │ │ │ ├── count-model.ts │ │ │ └── index.ts │ └── repository │ │ ├── counter-hemera-repository.ts │ │ ├── counter-repository.ts │ │ ├── index.ts │ │ └── interfaces │ │ ├── counter-repository.ts │ │ └── index.ts │ ├── tsconfig.json │ └── webpack.config.js ├── portable-devices ├── browser-extension │ ├── .gitignore │ ├── README.md │ ├── assets │ │ ├── html │ │ │ ├── devtools.html │ │ │ ├── newtab.html │ │ │ ├── options.html │ │ │ ├── panel.html │ │ │ └── popup.html │ │ ├── icons │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-256x256.png │ │ │ ├── apple-touch-icon-120x120.png │ │ │ ├── apple-touch-icon-180x180.png │ │ │ ├── browserconfig.xml │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon.ico │ │ │ ├── icon.png │ │ │ ├── manifest.xjson │ │ │ ├── mstile-150x50.png │ │ │ └── safari-pinned-tab.svg │ │ └── manifest.json │ ├── build.config.js │ ├── env.js │ ├── getHttpsConfig.js │ ├── html-plugin-template.ejs │ ├── modules.js │ ├── package.json │ ├── pageConf.js │ ├── paths.js │ ├── src │ │ ├── app │ │ │ ├── 500.tsx │ │ │ ├── ErrorBoundary.tsx │ │ │ ├── Newtab.tsx │ │ │ ├── Options.tsx │ │ │ ├── Panel.tsx │ │ │ ├── Popup.tsx │ │ │ └── ServerError.tsx │ │ ├── background.ts │ │ ├── compute.tsx │ │ ├── config │ │ │ ├── base-apollo-client.ts │ │ │ ├── base-redux-config.ts │ │ │ ├── config.ts │ │ │ ├── index.ts │ │ │ ├── newtab │ │ │ │ ├── client.service.ts │ │ │ │ ├── epic-config.ts │ │ │ │ └── redux-config.ts │ │ │ ├── options │ │ │ │ ├── client.service.ts │ │ │ │ ├── epic-config.ts │ │ │ │ └── redux-config.ts │ │ │ ├── panel │ │ │ │ ├── client.service.ts │ │ │ │ ├── epic-config.ts │ │ │ │ └── redux-config.ts │ │ │ ├── popup │ │ │ │ ├── client.service.ts │ │ │ │ ├── epic-config.ts │ │ │ │ └── redux-config.ts │ │ │ ├── public-config.ts │ │ │ └── router-history.ts │ │ ├── contentScript.ts │ │ ├── devtools.ts │ │ ├── enums │ │ │ ├── extension-routes.ts │ │ │ └── index.ts │ │ ├── index.css │ │ ├── modules │ │ │ ├── background │ │ │ │ ├── index.ts │ │ │ │ └── module.ts │ │ │ ├── newtab │ │ │ │ ├── index.ts │ │ │ │ └── module.tsx │ │ │ ├── options │ │ │ │ ├── index.ts │ │ │ │ └── module.tsx │ │ │ ├── panel │ │ │ │ ├── index.ts │ │ │ │ └── module.tsx │ │ │ └── popup │ │ │ │ ├── index.ts │ │ │ │ └── module.tsx │ │ ├── newtab.tsx │ │ ├── options.tsx │ │ ├── pages │ │ │ ├── Dashboard.tsx │ │ │ ├── Home.tsx │ │ │ └── index.ts │ │ ├── panel.tsx │ │ └── popup.tsx │ ├── tsconfig.json │ ├── webpack.config.js │ ├── webpack │ │ └── persistentCache │ │ │ └── createEnvironmentHash.js │ └── webpackDevServer.config.js ├── desktop │ ├── .gitignore │ ├── assets │ │ ├── entitlements.mac.plist │ │ ├── html │ │ │ ├── about-page.html │ │ │ ├── main-page.html │ │ │ └── tray-page.html │ │ ├── icon.icns │ │ ├── icon.ico │ │ ├── icon.png │ │ ├── icon.svg │ │ ├── icons │ │ │ ├── 1024x1024.png │ │ │ ├── 128x128.png │ │ │ ├── 16x16.png │ │ │ ├── 24x24.png │ │ │ ├── 256x256.png │ │ │ ├── 32x32.png │ │ │ ├── 48x48.png │ │ │ ├── 512x512.png │ │ │ ├── 64x64.png │ │ │ ├── 96x96.png │ │ │ ├── icon-22.png │ │ │ └── icon-256.png │ │ └── preload.js │ ├── build.config.js │ ├── electron-builder.json │ ├── electron-webpack.json │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── common │ │ │ ├── channel.ts │ │ │ ├── config │ │ │ │ ├── base-apollo-client.ts │ │ │ │ ├── base-redux-config.ts │ │ │ │ └── config.ts │ │ │ ├── constants │ │ │ │ ├── index.ts │ │ │ │ └── ipcEvents.ts │ │ │ ├── index.ts │ │ │ └── utils │ │ │ │ ├── index.ts │ │ │ │ ├── is.ts │ │ │ │ └── logger.ts │ │ ├── main │ │ │ ├── app │ │ │ │ ├── App.ts │ │ │ │ ├── Service.ts │ │ │ │ ├── View.ts │ │ │ │ └── index.ts │ │ │ ├── bootstrap.ts │ │ │ ├── config │ │ │ │ ├── client.service.ts │ │ │ │ ├── epic-config.ts │ │ │ │ └── redux-electron-config.ts │ │ │ ├── index.ts │ │ │ ├── interfaces │ │ │ │ ├── index.ts │ │ │ │ ├── tray-icon.ts │ │ │ │ └── tray-window.ts │ │ │ ├── ioc │ │ │ │ ├── index.ts │ │ │ │ ├── inversify.config.ts │ │ │ │ ├── loader.ts │ │ │ │ └── types.ts │ │ │ ├── menu-template.ts │ │ │ ├── models │ │ │ │ ├── User.ts │ │ │ │ └── index.ts │ │ │ ├── modules │ │ │ │ ├── index.ts │ │ │ │ └── module.ts │ │ │ ├── services │ │ │ │ ├── Logger.ts │ │ │ │ ├── System.ts │ │ │ │ ├── User.ts │ │ │ │ └── index.ts │ │ │ ├── utils │ │ │ │ ├── AutoUpdater.ts │ │ │ │ ├── createProtocol.ts │ │ │ │ ├── index.ts │ │ │ │ ├── ioc.ts │ │ │ │ ├── logger │ │ │ │ │ ├── customLogger.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── logDecorator.ts │ │ │ │ ├── sqlite │ │ │ │ │ └── connection.ts │ │ │ │ └── window │ │ │ │ │ ├── devTools.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── protocol.ts │ │ │ └── views │ │ │ │ ├── about.ts │ │ │ │ ├── index.ts │ │ │ │ ├── main.ts │ │ │ │ └── tray.ts │ │ └── renderer │ │ │ ├── about.tsx │ │ │ ├── app │ │ │ ├── 500.tsx │ │ │ ├── About.tsx │ │ │ ├── ErrorBoundary.tsx │ │ │ ├── Main.tsx │ │ │ ├── ServerError.tsx │ │ │ └── Tray.tsx │ │ │ ├── components │ │ │ ├── WindowHeader.tsx │ │ │ └── layout │ │ │ │ ├── components │ │ │ │ ├── SideMenu.tsx │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── config │ │ │ ├── config.ts │ │ │ ├── index.ts │ │ │ ├── main │ │ │ │ ├── client.service.ts │ │ │ │ ├── epic-config.ts │ │ │ │ └── redux-config.ts │ │ │ ├── public-config.ts │ │ │ ├── router-history.ts │ │ │ └── tray │ │ │ │ ├── client.service.ts │ │ │ │ ├── epic-config.ts │ │ │ │ └── redux-config.ts │ │ │ ├── main.tsx │ │ │ ├── modules │ │ │ ├── main │ │ │ │ ├── index.ts │ │ │ │ └── module.tsx │ │ │ └── tray │ │ │ │ ├── index.ts │ │ │ │ └── module.tsx │ │ │ └── tray-main.tsx │ ├── tools │ │ ├── esm-wrapper.js │ │ └── utils.js │ ├── tsconfig.json │ ├── webpack.main.additions.js │ └── webpack.renderer.additions.js └── mobile │ ├── .expo-shared │ └── assets.json │ ├── .exprc │ ├── .gitignore │ ├── App.tsx │ ├── __generated__ │ └── AppEntry.js │ ├── app.json │ ├── assets │ ├── fonts │ │ └── SpaceMono-Regular.ttf │ └── images │ │ ├── adaptive-icon.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── favicon.png │ │ ├── icon.png │ │ └── splash.png │ ├── babel.config.js │ ├── build.config.js │ ├── eas.json │ ├── index.js │ ├── jest.config.js │ ├── metro.config.js │ ├── package.json │ ├── react-native.config.js │ ├── shim.js │ ├── src │ ├── App.tsx │ ├── assets │ │ ├── fonts │ │ │ └── SpaceMono-Regular.ttf │ │ └── images │ │ │ ├── adaptive-icon.png │ │ │ ├── favicon.png │ │ │ ├── icon.png │ │ │ └── splash.png │ ├── components │ │ ├── __tests__ │ │ │ └── StyledText-test.js │ │ └── layout │ │ │ ├── Drawer.tsx │ │ │ ├── Header.tsx │ │ │ ├── Layout.tsx │ │ │ ├── NativeBaseIcon.tsx │ │ │ ├── NativeBaseSample.tsx │ │ │ ├── SideBar.tsx │ │ │ ├── module.ts │ │ │ └── root-navigation.tsx │ ├── config │ │ ├── base-apollo-client.ts │ │ ├── base-redux-config.ts │ │ ├── client.service.ts │ │ ├── config.ts │ │ ├── epic-config.ts │ │ ├── index.ts │ │ ├── public-config.ts │ │ ├── redux-config.ts │ │ └── router-history.ts │ ├── constants │ │ ├── Colors.ts │ │ └── Layout.ts │ ├── hooks │ │ ├── useCachedResources.ts │ │ ├── useColorScheme.ts │ │ └── useColorScheme.web.ts │ ├── modules │ │ ├── index.ts │ │ ├── modules.tsx │ │ ├── navigation │ │ │ └── index.tsx │ │ ├── navigator.tsx │ │ └── render.tsx │ ├── pages │ │ ├── PersonalInfo.tsx │ │ ├── Settings.tsx │ │ ├── dashboard.tsx │ │ ├── hello.tsx │ │ └── index.ts │ ├── react-navigation │ │ ├── index.ts │ │ ├── resolveRootRoute.tsx │ │ └── types.tsx │ └── screens │ │ └── NotFoundScreen.tsx │ ├── tsconfig.json │ ├── types.tsx │ └── webpack.config.js ├── prettier.config.js ├── servers ├── backend-server │ ├── .dockerignore │ ├── .gitignore │ ├── .npmignore │ ├── .npmrc │ ├── CHANGELOG.md │ ├── Dockerfile │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ └── test.ts │ ├── babel.config.js │ ├── build.config.js │ ├── generated-schema.graphql │ ├── jest.config.js │ ├── knexfile.js │ ├── package.json │ ├── src │ │ ├── api │ │ │ ├── remote-config.ts │ │ │ ├── resolver.ts │ │ │ ├── root-schema.graphqls │ │ │ ├── scalar.ts │ │ │ ├── schema-builder.ts │ │ │ └── utils.ts │ │ ├── config │ │ │ ├── env-config.ts │ │ │ ├── index.ts │ │ │ └── moleculer.config.ts │ │ ├── connectors │ │ │ ├── connection-broker.ts │ │ │ ├── graphql-pubsub-connector.ts │ │ │ ├── mongo-connector.ts │ │ │ ├── nats-connector.ts │ │ │ └── redis-connector.ts │ │ ├── express-app.ts │ │ ├── index.ts │ │ ├── interfaces │ │ │ ├── index.ts │ │ │ └── module-interface.ts │ │ ├── main.spec.ts │ │ ├── middleware │ │ │ ├── cors.ts │ │ │ ├── error.ts │ │ │ ├── moleculer-inter-namespace.ts │ │ │ ├── persistedQuery.ts │ │ │ └── services.ts │ │ ├── modules │ │ │ ├── index.ts │ │ │ └── module.ts │ │ ├── server-setup │ │ │ ├── graphql-server.ts │ │ │ ├── graphql-subscription-server.ts │ │ │ ├── graphql-ws.ts │ │ │ ├── utils.ts │ │ │ └── websocket-multipath-update.ts │ │ ├── service.ts │ │ ├── stack-server.ts │ │ └── utils │ │ │ └── migrations.ts │ ├── tsconfig.json │ └── webpack.config.js ├── frontend-server │ ├── .browserslistrc │ ├── .dockerignore │ ├── .npmignore │ ├── .npmrc │ ├── Dockerfile │ ├── babel.config.js │ ├── build.config.js │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── 500.tsx │ │ │ ├── ErrorBoundary.tsx │ │ │ ├── Main.tsx │ │ │ └── ServerError.tsx │ │ ├── backend │ │ │ ├── app.ts │ │ │ ├── middlewares │ │ │ │ ├── cors.ts │ │ │ │ └── error.ts │ │ │ ├── modules │ │ │ │ ├── index.ts │ │ │ │ └── modules.ts │ │ │ ├── server.ts │ │ │ ├── ssr │ │ │ │ └── html.tsx │ │ │ ├── website-nossr.tsx │ │ │ └── website.tsx │ │ ├── config │ │ │ ├── __mocks__ │ │ │ │ ├── mockFetch.ts │ │ │ │ └── mockWatchQuery.ts │ │ │ ├── __tests__ │ │ │ │ └── apollo-client-subscribe-to-more.ts │ │ │ ├── base-apollo-client.ts │ │ │ ├── base-redux-config.ts │ │ │ ├── client.service.ts │ │ │ ├── env-config.ts │ │ │ ├── epic-config.ts │ │ │ ├── index.ts │ │ │ ├── public-config.ts │ │ │ └── redux-config.ts │ │ ├── index.tsx │ │ ├── modules │ │ │ ├── index.ts │ │ │ ├── layout │ │ │ │ ├── components │ │ │ │ │ ├── SideMenu.tsx │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ └── module.tsx │ │ └── postcss.config.js │ ├── tools │ │ └── webpackAppConfig.js │ ├── tsconfig.json │ └── webpack.config.js └── moleculer-server │ ├── .dockerignore │ ├── .draft-tasks.toml │ ├── .draftignore │ ├── .gitignore │ ├── .npmrc │ ├── .vscode │ └── launch.json │ ├── Dockerfile │ ├── README.md │ ├── charts │ └── chart │ │ ├── .helmignore │ │ ├── Chart.yaml │ │ ├── values-dev.yaml │ │ ├── values-prod.yaml │ │ ├── values-stage.yaml │ │ └── values.yaml │ ├── draft.toml │ ├── package.json │ ├── src │ ├── config │ │ ├── env-config.ts │ │ ├── index.ts │ │ └── moleculer.config.ts │ ├── connectors │ │ ├── connection-broker.ts │ │ ├── graphql-pubsub-connector.ts │ │ ├── mongo-connector.ts │ │ ├── nats-connector.ts │ │ └── redis-connector.ts │ ├── index.ts │ ├── modules │ │ ├── index.ts │ │ └── module.ts │ ├── stack-server.ts │ └── test │ │ └── unit │ │ └── greeter.spec.ts │ ├── tsconfig.json │ └── webpack.config.js ├── tools ├── .eslintrc ├── cli.js ├── cli │ ├── command-invoker.js │ ├── commands │ │ ├── add-module.js │ │ └── delete-module.js │ ├── config.js │ └── helpers │ │ └── util.js ├── esm-wrapper.js ├── get-symlinked-modules.js ├── html-plugin-template.ejs ├── templates │ └── module │ │ ├── browser │ │ ├── package.json │ │ ├── src │ │ │ ├── constants │ │ │ │ ├── constants.ts │ │ │ │ └── index.ts │ │ │ ├── graphql │ │ │ │ ├── index.ts │ │ │ │ ├── link │ │ │ │ │ └── index.ts │ │ │ │ ├── mutations │ │ │ │ │ └── index.ts │ │ │ │ ├── queries │ │ │ │ │ ├── index.ts │ │ │ │ │ └── module-query.gql │ │ │ │ └── schema.ts │ │ │ ├── index.tsx │ │ │ ├── locales │ │ │ │ ├── en │ │ │ │ │ └── translations.json │ │ │ │ ├── index.ts │ │ │ │ └── ru │ │ │ │ │ └── translations.json │ │ │ ├── module.tsx │ │ │ ├── selectors │ │ │ │ └── index.ts │ │ │ └── utils │ │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js │ │ └── server │ │ ├── package.json │ │ ├── src │ │ ├── config │ │ │ ├── env-config.ts │ │ │ └── index.ts │ │ ├── constants │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── containers │ │ │ ├── index.ts │ │ │ └── module.ts │ │ ├── index.ts │ │ ├── interfaces │ │ │ └── index.ts │ │ ├── module.ts │ │ ├── plugin │ │ │ └── index.ts │ │ └── services │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js ├── update-dependency-version.js ├── webpack-util.js ├── webpack │ └── server.config.js └── webpackAppConfig.js ├── transform.js ├── tsconfig.json ├── typings ├── graphql.d.ts └── index.d.ts ├── values-dev.yaml ├── values-prod.yaml ├── values-stage.yaml ├── values.secret.json └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | not IE 11 3 | not IE_Mob 11 -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | lib -------------------------------------------------------------------------------- /.git-crypt/.gitattributes: -------------------------------------------------------------------------------- 1 | # Do not edit this file. To specify the files to encrypt, create your own 2 | # .gitattributes file in the directory where your files are. 3 | * !filter !diff 4 | *.gpg binary 5 | -------------------------------------------------------------------------------- /.git-crypt/keys/default/0/147885163DF27F4877B0BC14DE8C27DDE38F1E61.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/.git-crypt/keys/default/0/147885163DF27F4877B0BC14DE8C27DDE38F1E61.gpg -------------------------------------------------------------------------------- /.git-crypt/keys/default/0/49AB3942E38DB928ACF3905EC2DB4383B4A6E5EA.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/.git-crypt/keys/default/0/49AB3942E38DB928ACF3905EC2DB4383B4A6E5EA.gpg -------------------------------------------------------------------------------- /.git-crypt/keys/default/0/49F363DC4362D3C17B2FE0091871B202236FD41B.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/.git-crypt/keys/default/0/49F363DC4362D3C17B2FE0091871B202236FD41B.gpg -------------------------------------------------------------------------------- /.git-crypt/keys/default/0/54EBB791640A664510494E416177B1BAA1083A88.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/.git-crypt/keys/default/0/54EBB791640A664510494E416177B1BAA1083A88.gpg -------------------------------------------------------------------------------- /.git-crypt/keys/default/0/70961F6ECD8220394FD8AB555E94AC25CBCBA1A3.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/.git-crypt/keys/default/0/70961F6ECD8220394FD8AB555E94AC25CBCBA1A3.gpg -------------------------------------------------------------------------------- /.git-crypt/keys/default/0/EBA4B7A860BD152BF5F9F727F12B84D048062B79.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/.git-crypt/keys/default/0/EBA4B7A860BD152BF5F9F727F12B84D048062B79.gpg -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | values.secret.json filter=git-crypt diff=git-crypt 2 | .npmrc filter=git-crypt diff=git-crypt 3 | values-dev.yaml filter=git-crypt diff=git-crypt 4 | values-stage.yaml filter=git-crypt diff=git-crypt 5 | values-prod.yaml filter=git-crypt diff=git-crypt -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD013": false, 4 | "MD042": false, 5 | "MD033": false 6 | } -------------------------------------------------------------------------------- /.markdownlintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | lib 4 | .git 5 | CHANGELOG.md -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/.npmrc -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8.4" 4 | install: 5 | - npm config set spin=false 6 | - yarn install -g npm@5.2 7 | - yarn install -g coveralls 8 | - yarn install 9 | os: 10 | - linux 11 | - osx 12 | branches: 13 | only: 14 | - publish 15 | script: 16 | - yarn test 17 | # Allow Travis tests to run in containers. 18 | sudo: false 19 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint" 4 | ] 5 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 4 | ## [0.8.0](https://github.com/cdmbase/fullstack-pro/compare/v0.0.40-alpha.12...v0.0.40-alpha.13) (2021-04-05) 5 | 6 | 7 | > Dates follow the `dd/mm/yy` notation. 8 | ## 05/06/18 (v 0.3.2) 9 | > Webpack4 10 | ** Breaking Change ** 11 | Removed `Staging` environment to go with standard `test` environment. 12 | 13 | 14 | 15 | ## 11/10/17 16 | | Package | Version | Changes | 17 | | ---- | --- | --- | 18 | | all | 0.1.1 | uses spinjs for build | 19 | 20 | Still support backward compatibility for starting server. -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jenkins/jenkins:lts 2 | USER root 3 | RUN apt-get clean && apt-get update && \ 4 | apt-get install -y make python && \ 5 | wget https://get.helm.sh/helm-v2.14.3-linux-amd64.tar.gz && \ 6 | tar -xvf helm-v2.14.3-linux-amd64.tar.gz && \ 7 | mv linux-amd64/helm /usr/bin/helm && \ 8 | echo "git config --global core.sshCommand 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'" >> /etc/profile && \ 9 | rm -rf helm-v2.14.3-linux-amd64.tar.gz linux-amd64 10 | USER jenkins 11 | -------------------------------------------------------------------------------- /ISSUES.md: -------------------------------------------------------------------------------- 1 | Resolving tags conflicts when running `lerna publish` 2 | ---- 3 | ``` 4 | $ git tag 5 | v0.0.1 6 | v0.0.4 7 | ``` 8 | - remove the tag locally 9 | ``` 10 | $ git tag -d v0.0.4 11 | Deleted tag 'v0.0.4' (was c34157b) 12 | $ git tag -d v0.0.1 13 | Deleted tag 'v0.0.1' (was edfaa93) 14 | ``` 15 | - remove the tag remotely 16 | ``` 17 | $ git push origin :refs/tags/v0.0.4 18 | To https://github.com/cdmbase/ide-stack.git 19 | - [deleted] v0.0.4 20 | $ git push origin :refs/tags/v0.0.1 21 | To https://github.com/cdmbase/ide-stack.git 22 | - [deleted] v0.0.1 23 | ``` 24 | 25 | -------------------------------------------------------------------------------- /ScreenShot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/ScreenShot.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | compact: false, 3 | presets: [ 4 | '@babel/preset-typescript', 5 | '@babel/preset-react', 6 | ['@babel/preset-env', { modules: 'commonjs', loose: true }], 7 | ], 8 | plugins: [ 9 | '@babel/plugin-transform-modules-commonjs', 10 | '@babel/plugin-transform-destructuring', 11 | '@babel/plugin-transform-for-of', 12 | '@babel/plugin-transform-regenerator', 13 | '@babel/plugin-transform-runtime', 14 | '@babel/plugin-syntax-dynamic-import', 15 | '@babel/plugin-proposal-class-properties', 16 | ['@babel/plugin-proposal-decorators', { legacy: true }], 17 | '@babel/plugin-proposal-object-rest-spread', 18 | ], 19 | env: { 20 | production: { 21 | compact: true, 22 | }, 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'header-max-length': [0, 'always', 100], // corresponding to maxHeaderWidth of commitizen 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /config/development/.gitignore: -------------------------------------------------------------------------------- 1 | env.sh 2 | *.env 3 | *.sh 4 | -------------------------------------------------------------------------------- /config/development/dev.env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # Create `dev.env` file and load following required values 3 | # 4 | NATS_URL=nats://localhost:4222/ 5 | NATS_USER=test 6 | NATS_PW=test 7 | GRAPHQL_URL=http://localhost:8080/graphql 8 | CLIENT_URL=http://localhost:3000 9 | ZIPKIN_URL=test 10 | ZIPKIN_PORT=test 11 | LOG_LEVEL=trace 12 | MONGO_URL=mongodb://localhost:27017/sample-stack 13 | REDIS_CLUSTER_URL='[{"port":6379,"host":"localhost"}]' 14 | REDIS_URL=redis://localhost:6379 15 | REDIS_CLUSTER_ENABLED=false 16 | REDIS_SENTINEL_ENABLED=false 17 | BACKEND_URL=http://localhost:8080 18 | -------------------------------------------------------------------------------- /config/development/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "database": { 3 | "client": "sqlite3", 4 | "connection": { 5 | "filename": "dev-db.sqlite3" 6 | }, 7 | "useNullAsDefault": true 8 | } 9 | } -------------------------------------------------------------------------------- /config/production/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /config/staging/.gitignore: -------------------------------------------------------------------------------- 1 | settings.json 2 | env.sh 3 | *.env 4 | *.sh 5 | *.json 6 | dev.json 7 | development-settings.json 8 | dev*.json -------------------------------------------------------------------------------- /config/test/.gitignore: -------------------------------------------------------------------------------- 1 | settings.json 2 | env.sh 3 | *.env 4 | *.sh 5 | *.json 6 | dev.json 7 | development-settings.json 8 | dev*.json -------------------------------------------------------------------------------- /config/test/test.env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # Create `test.env` file and load following required values 3 | # 4 | MONGO_URL=mongodb://localhost:27017/sample-test 5 | DB_HOST=localhost 6 | DB_USER=mysql 7 | DB_PASSWORD= 8 | DB_SOCKET_PATH= 9 | DB_DATABASE=test -------------------------------------------------------------------------------- /docs/Moleculer.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Connecting to moleculer 4 | --- 5 | 6 | moleculer connect --ns default 7 | 8 | 9 | References: 10 | https://moleculer.services/docs/0.14/moleculer-cli.html -------------------------------------------------------------------------------- /docs/References.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hot Reload in Apollo Server 2 5 | -- 6 | https://github.com/apollographql/apollo-server/issues/1275 7 | 8 | 9 | To update apollo-server 10 | ==== 11 | https://github.com/uzh-bf/klicker-uzh/blob/927512043e8b978c5874bb524eac5c5ff321e28b/apps/backend/src/app.js 12 | https://github.com/heypoom/eventkit/tree/165eb23dc8f3529b46f2cd1f187e4c592d8c9767 13 | https://github.com/cerino-ligutom/GraphQL-Starter/blob/master/src/graphql/index.ts -------------------------------------------------------------------------------- /docs/development/CodeContribution/Desktop_Setup.md: -------------------------------------------------------------------------------- 1 | 2 | # Follow steps to [install project](./Project_Setup.md) 3 | 4 | ### Start Desktop application 5 | 6 | Before to start desktop application, make sure to start the backend server of the web application first. 7 | 8 | `lerna exec --scope=*backend-server yarn watch` 9 | 10 | And then start desktop application. 11 | 12 | `lerna exec --scope=*desktop yarn watch` 13 | -------------------------------------------------------------------------------- /docs/development/CodeContribution/GitHooks.md: -------------------------------------------------------------------------------- 1 | ### Git Hooks 2 | 3 | `Husky` executes `lint-staged` and `commitlint` by git hooks. `lint-staged` makes sure staged files are to be formatted before committed. Refer to `package.json` for details. 4 | -------------------------------------------------------------------------------- /docs/development/CodeContribution/HowToContribute.md: -------------------------------------------------------------------------------- 1 | 2 | How to contribute as a developer? 3 | -- 4 | 5 | 1. Once you setup the project, switch to `develop` branch. 6 | 2. Create a new branch using `develop` branch as source based on the issue you working. 7 | 3. Update changes to that branch and create a PR agains `develop` branch. 8 | 4. As soon as PR is created, we have a build process that runs in the background to check whether it is successful or failed. 9 | 5. If it successfull you will see a green check otherwise a red cross. When you notice it has red cross then run `yarn build` locally and fix any issues and submit the commit again to check it's updated status. 10 | 11 | 12 | 13 | Note: `master` branch is read-only branch and we don't want to merge anything to it other than that from `develop` branch. So please avoid creating PRs agains master branch. 14 | 15 | -------------------------------------------------------------------------------- /docs/development/CodeContribution/Known_Issues.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Kown Issues 4 | 5 | 6 | 1. EACCES: permission denied, scandir ..... 7 | 8 | Follow the workaround https://github.com/cdmbase/fullstack-pro/issues/176 9 | 10 | 2. OS X: "Error: EMFILE: too many open files, watch" 11 | Follow https://github.com/facebook/create-react-app/issues/4540 12 | 13 | ``` 14 | brew install watchman 15 | ``` 16 | 17 | 3. Macbook Catalina: `Zsh` latest macos comes with `Zsh` as the default shell. We seeing some issues to start the project with it. Please use `bash` to run project. 18 | 19 | https://www.howtogeek.com/444596/how-to-change-the-default-shell-to-bash-in-macos-catalina/ -------------------------------------------------------------------------------- /docs/development/CodeContribution/React-Patterns/React_Componet_Extensions.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://github.com/superdesk/superdesk-client-core/blob/d5ee7b11dddd2255a77b518e177b7ec33b167311/scripts/apps/extension-points/services/ExtensionPoints.js 4 | 5 | https://github.com/taskrabbit/react-component-extension 6 | 7 | 8 | 9 | https://github.com/camwest/react-slot-fill 10 | 11 | Reference: https://www.youtube.com/watch?v=395ou6k6C6k -------------------------------------------------------------------------------- /docs/development/CodeContribution/React-Patterns/RxJS_notes.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://itnext.io/handling-redux-side-effects-the-rxjs-way-59c057b12cd4 -------------------------------------------------------------------------------- /docs/development/CodeContribution/Tutorials.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Typescript Tutorials 4 | --- 5 | https://basarat.gitbooks.io/typescript/ 6 | https://medium.com/@martin_hotell/react-children-composition-patterns-with-typescript-56dfc8923c64 7 | 8 | 9 | 10 | Cors: 11 | --- 12 | https://www.blackhillsinfosec.com/cors-lite/ -------------------------------------------------------------------------------- /docs/development/CodeContribution/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: faq-build 3 | title: Babel, JSX, and Build Steps 4 | permalink: docs/faq-build.html 5 | layout: docs 6 | category: FAQ 7 | --- 8 | 9 | 10 | ### From where this `@sample-stack/platform-browser` comes in `packages/sample-platform/browser/src/containers/Counter.tsx`? 11 | 12 | We use [lerna](https://github.com/lerna/lerna) for monorepo. For example all packages starts with `@sample-stack` are either under `packages` or `pacakges-modules` directories. 13 | 14 | 15 | ### What is use of rehydrate? 16 | 17 | It is used for SSR(server side rendering). Server generates initial browser page along with state(redux or apollo-client or css) and that state will be used in the browser to rehydated during browser rendering so the client state don't start from initial values. 18 | -------------------------------------------------------------------------------- /docs/development/CodeContribution/installation_issues.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1. Error when `node-gyp rebuild`. 5 | Could be missing `python`. Install it and rerun the install again. 6 | For more docs, check https://github.com/nodejs/node-gyp#installation 7 | 8 | 2. For Mac User to develop Desktop app need 9 | `xcode-select --install` 10 | -------------------------------------------------------------------------------- /docs/development/Database/mongodb-test.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Writing Mongodb test 4 | --- 5 | 6 | https://jestjs.io/docs/en/mongodb -------------------------------------------------------------------------------- /docs/development/Deployment/JenkinsDeployment.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Jenkins Deployment 4 | 5 | The branches used for Jenkins deployment will be `devpublish` for testing `develop` branch. This is used for pre production testing. 6 | 7 | `publish` branch is used for testing `master` branch. This is also used for production deployment. 8 | 9 | - Modifying JenkinsFile 10 | 11 | All modification in `Jenkinsfile` should be done in `develop` branch. As these changes need to be merged to `devpublish` for jenkins to use, you can run following command. 12 | 13 | ``` 14 | yarn devpublish:push 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /docs/development/Expo/expo-commands.md: -------------------------------------------------------------------------------- 1 | 2 | ## To check mobile configuration 3 | ``` 4 | lerna exec --scope=*mobile-device "expo config --type public" 5 | ``` 6 | -------------------------------------------------------------------------------- /docs/development/Mobile/How_To_Make_Expo_Wrok_With_Monorepos.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://medium.com/habilelabs/react-native-react-web-and-expo-together-in-one-monorepo-5b8f9a0fca00 4 | 5 | As per the documentation, expo-yarn-workspaces work only on macOS and UNIX based systems, Windows is not supported. 6 | If we want it to work on Windows as well, then we need to make slight modifications to it. 7 | Firstly, remove the postinstallscript from package.json and move it to the main package.json- 8 | "postinstall": "cd ./packages/ExpoApp && expo-yarn-workspaces postinstall" 9 | 10 | -------------------------------------------------------------------------------- /docs/development/Mobile/React-Native-FAQ.md: -------------------------------------------------------------------------------- 1 | 2 | Q1. Uncaught TypeError: Cannot assign to read only property 'exports' of object '#' 3 | A1. Because `import` and `module.exports` are not allowed to be mixed in webpack 2, 4 | The solution is to change it to ES6. 5 | -------------------------------------------------------------------------------- /docs/development/Mobile/Run_mobile.md: -------------------------------------------------------------------------------- 1 | 2 | ### How to run mobile? 3 | 4 | From the `` of the project, once you finish installation and building all packages, run the following command. 5 | 6 | ``` 7 | lerna exec --scope=*mobile yarn watch 8 | ``` 9 | 10 | -------------------------------------------------------------------------------- /husky.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | hooks: { 3 | 'pre-commit': 'lint-staged', 4 | //'pre-push': 'yarn test', // when production ready 5 | }, 6 | }; -------------------------------------------------------------------------------- /jenkins_variables.groovy: -------------------------------------------------------------------------------- 1 | import groovy.json.JsonSlurper 2 | 3 | def getVersion(json_file_path){ 4 | def inputFile = readFile(json_file_path) 5 | def InputJSON = new JsonSlurper().parseText(inputFile) 6 | def version = InputJSON.version 7 | return version 8 | } 9 | 10 | def getName(json_file_path){ 11 | def inputFile = readFile(json_file_path) 12 | def InputJSON = new JsonSlurper().parseText(inputFile) 13 | def name = InputJSON.name 14 | return name 15 | } 16 | 17 | def getSecrets(json_file_path, env, var){ 18 | def inputFile = new File(json_file_path) 19 | def InputJSON = new JsonSlurper().parse(inputFile) 20 | def secret = InputJSON."${env}"."${var}" 21 | return secret 22 | } 23 | -------------------------------------------------------------------------------- /jest-mongodb-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mongodbMemoryServerOptions: { 3 | instance: { 4 | dbName: 'jest' 5 | }, 6 | binary: { 7 | version: '4.0.12', // Version of MongoDB 8 | skipMD5: true 9 | }, 10 | autoStart: false 11 | } 12 | }; -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const merge = require('merge') 2 | const baseConfig = require('./jest.config.base'); 3 | const mongodbConfig = require('./jest.config.mongodb') 4 | module.exports = merge.recursive( 5 | baseConfig, 6 | mongodbConfig, 7 | { 8 | globals: { 9 | 10 | } 11 | }, 12 | // https://baltuta.eu/posts/typescript-lerna-monorepo-more-tools 13 | // { 14 | // roots: [''], 15 | // projects: [ 16 | // '/packages/ui', 17 | // '/packages/api', 18 | // '/packages/diceroll' 19 | // ], 20 | // } 21 | 22 | ); -------------------------------------------------------------------------------- /jest.config.mongodb.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '@shelf/jest-mongodb', 3 | }; 4 | -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '*.{js,jsx,ts,tsx,json,md}': ['prettier --write', 'git add'], 3 | // '*.{ts,tsx}': ['eslint --fix'], // this can be tested 4 | }; -------------------------------------------------------------------------------- /nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasksRunnerOptions": { 3 | "default": { 4 | "runner": "nx/tasks-runners/default", 5 | "options": { 6 | "cacheableOperations": [ 7 | "build" 8 | ] 9 | } 10 | } 11 | }, 12 | "namedInputs": { 13 | "adminide": [ 14 | "{projectRoot}/packages/**/*", 15 | "{projectRoot}/packages-modules/**/*" 16 | ] 17 | }, 18 | "targetDefaults": { 19 | "build": { 20 | "dependsOn": [ 21 | "^build" 22 | ], 23 | "inputs": [ 24 | "adminide" 25 | ] 26 | }, 27 | "test": { 28 | "dependsOn": [ 29 | "build" 30 | ] 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | testEnvironment: 'jsdom', // This is overriden, from the base testEnvironment 7 | name: packageJson.name, 8 | displayName: packageJson.name, 9 | }; -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/__tests__/apollo-client.test.ts: -------------------------------------------------------------------------------- 1 | import { client } from './apollo-client-test-helper'; 2 | import { AddCounterDocument } from '../../../generated-models'; 3 | import 'jest'; 4 | 5 | describe('Apollo Client tests', () => { 6 | it('client test', async () => { 7 | const result = await client.mutate({ 8 | mutation: AddCounterDocument, 9 | variables: { amount: 1 }, 10 | // data: {}, 11 | }); 12 | expect(result).toEqual({ data: { addCounterState: null }, errors: undefined }); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/id-generation.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * All the unique identifier to be used when normilizing the data in the store. 3 | * Refer: https://www.apollographql.com/docs/angular/basics/caching#configuration 4 | * We define it as Object and use a helper method to convert. 5 | * ex: const dataIdFromObject = { 6 | * 'ICounter': (result) => result.__typename + ':' + result._id, 7 | * } 8 | */ 9 | export const dataIdFromObject = {}; 10 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/index.ts: -------------------------------------------------------------------------------- 1 | export * from './resolvers'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/mutations/AddCounter.client.gql: -------------------------------------------------------------------------------- 1 | mutation addCounterState($amount: Int!) { 2 | addCounterState(amount: $amount) @client { 3 | counter 4 | } 5 | } -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/mutations/AddCounter.gql: -------------------------------------------------------------------------------- 1 | mutation addCounter($amount: Int!) { 2 | addCounter(amount: $amount) { 3 | amount 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/mutations/AddCounter_WS.gql: -------------------------------------------------------------------------------- 1 | mutation AddCounter_WS($amount: Int!) { 2 | addCounter(amount: $amount) { 3 | amount 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/mutations/SyncCachedCounter.gql: -------------------------------------------------------------------------------- 1 | mutation SyncCachedCounter { 2 | syncCachedCounter 3 | } 4 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/queries/CounterCacheQuery_WS.gql: -------------------------------------------------------------------------------- 1 | query counterCacheQuery { 2 | counterCache { 3 | amount 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/queries/CounterQuery.client.gql: -------------------------------------------------------------------------------- 1 | query CounterState { 2 | counterState @client { 3 | counter 4 | } 5 | } -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/queries/CounterQuery.gql: -------------------------------------------------------------------------------- 1 | query counterQuery { 2 | counter { 3 | amount 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/resolvers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './resolvers'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/schema/counter-state.graphql: -------------------------------------------------------------------------------- 1 | 2 | type ClientCounter { 3 | counter: Int 4 | } 5 | 6 | extend type Query { 7 | counterState: ClientCounter 8 | } 9 | extend type Mutation { 10 | addCounterState(amount: Int!): ClientCounter 11 | } -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/graphql/subscriptions/CounterSubscription.gql: -------------------------------------------------------------------------------- 1 | subscription onCounterUpdated { 2 | counterUpdated { 3 | amount 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import repository from './module'; 3 | 4 | export default new Feature(repository); 5 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/module.tsx: -------------------------------------------------------------------------------- 1 | import { reducers } from './redux'; 2 | import { resolvers, stateDefault } from './graphql'; 3 | 4 | import { Feature } from '@common-stack/client-react'; 5 | import { filteredMenus, filteredRoutes } from './compute'; 6 | 7 | export default new Feature({ 8 | menuConfig: filteredMenus, 9 | routeConfig: filteredRoutes, 10 | reducer: { counter: reducers }, 11 | clientStateParams: { resolvers, defaults: [stateDefault] }, 12 | }); 13 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/redux/index.ts: -------------------------------------------------------------------------------- 1 | export * from './reducers'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/apollo-server-n-client/redux/reducers/index.ts: -------------------------------------------------------------------------------- 1 | const defaultState = { 2 | reduxCount: 1, 3 | }; 4 | 5 | export const reducers = function (state = defaultState, action) { 6 | switch (action.type) { 7 | case 'COUNTER_INCREMENT': 8 | return { 9 | ...state, 10 | reduxCount: state.reduxCount + action.value, 11 | }; 12 | 13 | default: 14 | return state; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/common/components/Dashboard.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { renderRoutes } from 'react-router-config'; 3 | 4 | export default (props) => <>{renderRoutes(props.route.routes, { matchPath: props.route.path })}; 5 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/common/components/Home.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export default () => ( 4 |
5 |

FullStack-Pro

6 |
7 | ); 8 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/common/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import common from './module'; 3 | 4 | export default new Feature(common); 5 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/common/interfaces/context.ts: -------------------------------------------------------------------------------- 1 | import { DataProxy } from '@apollo/client/cache'; 2 | import { ApolloClient } from '@apollo/client'; 3 | 4 | export interface MyContext { 5 | cache: DataProxy; 6 | getCacheKey: (options: { __typename: string; resource?: string; id?: string }) => string; 7 | apolloClient: ApolloClient; 8 | } 9 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/common/module.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { Feature } from '@common-stack/client-react'; 4 | import { filteredMenus, filteredRoutes } from './compute'; 5 | 6 | export default new Feature({ 7 | menuConfig: filteredMenus, 8 | routeConfig: filteredRoutes, 9 | }); 10 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/README.md: -------------------------------------------------------------------------------- 1 | # Connected React Router TypeScript Example 2 | 3 | You can try changing counter value and editing some components. Components will be updated while preserving counter state. 4 | 5 | In Hello link, you will see that the HelloChild component can access router state (URL path) without passing as props via its parent. 6 | 7 | 8 | Reference: 9 | 10 | https://github.com/supasate/connected-react-router/tree/master/examples/typescript -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/__tests__/connected-react-router-module.test.ts: -------------------------------------------------------------------------------- 1 | import Module from '../module'; 2 | 3 | import 'jest'; 4 | 5 | describe('connector modules', () => { 6 | it('module configuredRoutes', () => { 7 | const configuredRoutes = Module.getConfiguredRoutes(); 8 | 9 | expect(configuredRoutes).toMatchSnapshot(); 10 | }); 11 | 12 | it('module routes', () => { 13 | const routes = Module.getRoutes(); 14 | 15 | expect(routes).toMatchSnapshot(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/components/Hello.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { HelloChild } from './HelloChild'; 3 | 4 | export default () => ( 5 |
6 |
Hello
7 | 8 |
9 | ); 10 | 11 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/components/Home.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | const Home = () => ( 4 |
5 | Home 6 |
7 | ); 8 | 9 | export { Home }; 10 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/components/NavBar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import Counter from './Counter'; 3 | 4 | const NavBar = () => ( 5 |
6 | 7 |
8 | ); 9 | 10 | export default NavBar; 11 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/components/NoMatch.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | const NoMatch = () => ( 4 |
5 | No Match 6 |
7 | ); 8 | 9 | export default NoMatch; 10 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/constants/action-types.ts: -------------------------------------------------------------------------------- 1 | export const enum CONNECTED_REACT_ROUTER_ACTION_TYPES { 2 | INCREMENT = '@connected-react-router/INCREMENT', 3 | DECREMENT = '@connected-react-router/DECREMENT', 4 | } 5 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './action-types'; 2 | export * from './routes-types'; 3 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/constants/routes-types.ts: -------------------------------------------------------------------------------- 1 | export enum CONNECTED_REACT_ROUTER_ROUTES_TYPES { 2 | ROOT = '/', 3 | HOME = '/connected-react-router', 4 | HELLO = '/connected-react-router/hello', 5 | COUNTER = '/connected-react-router/counter', 6 | } 7 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/index.electron.ts: -------------------------------------------------------------------------------- 1 | export { ElectronTrayModule } from './electron-module'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import repository from './module'; 3 | import Counter from './components/Counter'; 4 | 5 | export { Counter }; 6 | export default new Feature(repository); 7 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './state'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/interfaces/state.ts: -------------------------------------------------------------------------------- 1 | import { RouterState } from 'connected-react-router'; 2 | 3 | export interface State { 4 | connectedReactRouterCounter: number; 5 | router: RouterState; 6 | } 7 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/module.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unsafe-assignment */ 2 | import * as React from 'react'; 3 | import { Feature } from '@common-stack/client-react'; 4 | import Counter from './components/Counter'; 5 | import NavBar from './components/NavBar'; 6 | import { connectedReactRouterCounter } from './redux'; 7 | import { filteredRoutes, filteredMenus } from './compute'; 8 | 9 | export default new Feature({ 10 | navItem: , // used in electron 11 | menuConfig: filteredMenus, 12 | routeConfig: filteredRoutes, 13 | reducer: { connectedReactRouterCounter }, 14 | }); 15 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/redux/actions/counter.ts: -------------------------------------------------------------------------------- 1 | import { CONNECTED_REACT_ROUTER_ACTION_TYPES } from '../../constants'; 2 | 3 | export const increment = () => ({ 4 | type: CONNECTED_REACT_ROUTER_ACTION_TYPES.INCREMENT, 5 | }); 6 | 7 | export const decrement = () => ({ 8 | type: CONNECTED_REACT_ROUTER_ACTION_TYPES.DECREMENT, 9 | }); 10 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/redux/actions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './counter'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/redux/index.ts: -------------------------------------------------------------------------------- 1 | export * from './actions'; 2 | export * from './reducers'; 3 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/redux/reducers/counter.ts: -------------------------------------------------------------------------------- 1 | import { Action } from 'redux'; 2 | import { CONNECTED_REACT_ROUTER_ACTION_TYPES } from '../../constants'; 3 | 4 | const connectedReactRouterCounter = (state = 0, action: Action) => { 5 | switch (action.type) { 6 | case CONNECTED_REACT_ROUTER_ACTION_TYPES.INCREMENT: 7 | return state + 1; 8 | case CONNECTED_REACT_ROUTER_ACTION_TYPES.DECREMENT: 9 | return state - 1; 10 | default: 11 | return state; 12 | } 13 | }; 14 | 15 | export { connectedReactRouterCounter }; 16 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/connected-react-router/redux/reducers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './counter'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/emotion/README.md: -------------------------------------------------------------------------------- 1 |

Emotion

2 | 3 | Emotion is a small, high-performant and framework-agnostic toolbelt to handle state-driven styling in JavaScript.
4 | It is dynamic by design and renders your styles depending on your application state. 5 | 6 | Code Reference: 7 | 8 | https://github.com/emotion-js/emotion -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/emotion/components/CompledWithTheme.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { Complex } from './ComplexComponent'; 4 | import { theme } from '../theme'; 5 | 6 | export default (props) => { 7 | return ( 8 | <> 9 | 10 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/emotion/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ComplexComponent'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/emotion/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import emotion from './module'; 3 | 4 | export default new Feature(emotion); 5 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/emotion/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './theme'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/emotion/interfaces/theme.ts: -------------------------------------------------------------------------------- 1 | export interface Theme { 2 | color: { 3 | primary: string; 4 | secondary: string; 5 | additional: string; 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/emotion/module.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Feature } from '@common-stack/client-react'; 3 | import { filteredMenus, filteredRoutes } from './compute'; 4 | 5 | 6 | 7 | export default new Feature({ 8 | menuConfig: filteredMenus, 9 | routeConfig: filteredRoutes, 10 | }); 11 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/emotion/theme.ts: -------------------------------------------------------------------------------- 1 | import { Theme } from './interfaces'; 2 | 3 | export const theme: Theme = { 4 | color: { 5 | primary: '#1890ff', 6 | secondary: 'red', 7 | additional: 'lightgreen', 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | 3 | import Common from './common'; 4 | import ApolloCounter from './apollo-server-n-client'; 5 | import ConnectedReactRouter from './connected-react-router'; 6 | import emotion from './emotion'; 7 | import { ElectronTrayModule } from './connected-react-router/index.electron'; 8 | 9 | export default new Feature(Common, ConnectedReactRouter, ApolloCounter, emotion); 10 | export { ElectronTrayModule }; 11 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './menu'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/browser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "experimentalDecorators": true, 6 | "esModuleInterop": true, 7 | "skipLibCheck": true, 8 | "rootDir": "./src", 9 | "outDir": "lib", 10 | "declarationDir": "lib", 11 | "declaration": true, 12 | "declarationMap": true, 13 | "jsx": "react-jsx", 14 | "jsxImportSource": "@emotion/react", 15 | "types": [ 16 | "@types/node", 17 | "@types/jest", 18 | "../../../typings", 19 | ] 20 | }, 21 | "exclude": [ 22 | "node_modules", 23 | "lib", 24 | "dist", 25 | "webpack.config.js", 26 | "rollup.config.js" 27 | ], 28 | "include": [ 29 | "src", 30 | "./typings/*.d.ts" 31 | ] 32 | } -------------------------------------------------------------------------------- /packages-modules/counter/electron/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | testEnvironment: 'jsdom', // This is overriden, from the base testEnvironment 7 | name: packageJson.name, 8 | displayName: packageJson.name, 9 | }; -------------------------------------------------------------------------------- /packages-modules/counter/electron/src/epics/index.ts: -------------------------------------------------------------------------------- 1 | export * from './count-tray-updater'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/electron/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import { connectedReactRouterCounter } from '@sample-stack/counter-module-browser/lib/connected-react-router/redux/reducers/counter'; 3 | import { onCountChangedEpic } from './epics'; 4 | 5 | const ElectronMainModule = new Feature({ 6 | reducer: { connectedReactRouterCounter }, 7 | epic: [onCountChangedEpic], 8 | }); 9 | 10 | export default new Feature(ElectronMainModule); 11 | -------------------------------------------------------------------------------- /packages-modules/counter/electron/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "experimentalDecorators": true, 6 | "esModuleInterop": true, 7 | "skipLibCheck": true, 8 | "rootDir": "./src", 9 | "outDir": "lib", 10 | "declarationDir": "lib", 11 | "declaration": true, 12 | "declarationMap": true 13 | }, 14 | "exclude": [ 15 | "node_modules", 16 | "lib", 17 | "dist", 18 | "webpack.config.js", 19 | "rollup.config.js" 20 | ], 21 | "include": [ 22 | "src", 23 | "./typings/*.d.ts" 24 | ] 25 | } -------------------------------------------------------------------------------- /packages-modules/counter/mobile/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | testEnvironment: 'jsdom', // This is overriden, from the base testEnvironment 7 | name: packageJson.name, 8 | displayName: packageJson.name, 9 | }; 10 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/common/components/Dashboard.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { renderRoutes } from 'react-router-config'; 3 | 4 | export const Dashboard = (props) => <>{renderRoutes(props.route.routes, { matchPath: props.route.path })}; 5 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/common/components/Home.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const Home = () => ( 4 |
5 |

FullStack-Pro

6 |
7 | ); 8 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/common/compute.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IMenuPosition } from '@common-stack/client-react'; 3 | 4 | import { Home } from '../common/components/Home'; 5 | import { getFilteredRoutes } from '../utils'; 6 | 7 | export const commonPageStore: any[] = [ 8 | { 9 | path: '/', 10 | key: 'home', 11 | exact: true, 12 | name: 'Home', 13 | component: Home, 14 | position: IMenuPosition.MIDDLE, 15 | }, 16 | ]; 17 | 18 | const selectedRoutesAndMenus = ['home']; 19 | 20 | 21 | // get routes 22 | const filteredRoutes = getFilteredRoutes(commonPageStore, selectedRoutesAndMenus); 23 | 24 | export { filteredRoutes }; 25 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/common/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import common from './module'; 3 | 4 | export default new Feature(common); 5 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/common/interfaces/context.ts: -------------------------------------------------------------------------------- 1 | import { DataProxy } from '@apollo/client/cache'; 2 | import { ApolloClient } from '@apollo/client'; 3 | 4 | export interface MyContext { 5 | cache: DataProxy; 6 | getCacheKey: (options: { __typename: string; resource?: string; id?: string }) => string; 7 | apolloClient: ApolloClient; 8 | } 9 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/common/module.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { Feature } from '@common-stack/client-react'; 4 | import { filteredRoutes } from './compute'; 5 | 6 | export default new Feature({ 7 | routeConfig: filteredRoutes, 8 | }); 9 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/README.md: -------------------------------------------------------------------------------- 1 | # Connected React Router TypeScript Example 2 | 3 | You can try changing counter value and editing some components. Components will be updated while preserving counter state. 4 | 5 | In Hello link, you will see that the HelloChild component can access router state (URL path) without passing as props via its parent. 6 | 7 | 8 | Reference: 9 | 10 | https://github.com/supasate/connected-react-router/tree/master/examples/typescript -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/constants/action-types.ts: -------------------------------------------------------------------------------- 1 | export const enum CONNECTED_REACT_ROUTER_ACTION_TYPES { 2 | INCREMENT = '@connected-react-router/INCREMENT', 3 | DECREMENT = '@connected-react-router/DECREMENT', 4 | } 5 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './action-types'; 2 | export * from './routes-types'; 3 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/constants/routes-types.ts: -------------------------------------------------------------------------------- 1 | export enum CONNECTED_REACT_ROUTER_ROUTES_TYPES { 2 | HOME = '/org', 3 | HELLO = '/org/hello', 4 | COUNTER = '/org/counter', 5 | } 6 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import reactRouter from './module'; 3 | 4 | export default new Feature(reactRouter); 5 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './state'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/interfaces/state.ts: -------------------------------------------------------------------------------- 1 | import { RouterState } from 'connected-react-router'; 2 | 3 | export interface State { 4 | connectedReactRouterCounter: number; 5 | router: RouterState; 6 | } 7 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/module.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unsafe-assignment */ 2 | import { Feature } from '@common-stack/client-react'; 3 | import { connectedReactRouterCounter } from './redux'; 4 | import { filteredRoutes } from './compute'; 5 | 6 | export default new Feature({ 7 | routeConfig: filteredRoutes, 8 | reducer: { connectedReactRouterCounter }, 9 | }); 10 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/redux/actions/counter.ts: -------------------------------------------------------------------------------- 1 | import { CONNECTED_REACT_ROUTER_ACTION_TYPES } from '../../constants'; 2 | 3 | export const increment = () => ({ 4 | type: CONNECTED_REACT_ROUTER_ACTION_TYPES.INCREMENT, 5 | }); 6 | 7 | export const decrement = () => ({ 8 | type: CONNECTED_REACT_ROUTER_ACTION_TYPES.DECREMENT, 9 | }); 10 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/redux/actions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './counter'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/redux/index.ts: -------------------------------------------------------------------------------- 1 | export * from './actions'; 2 | export * from './reducers'; 3 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/redux/reducers/counter.ts: -------------------------------------------------------------------------------- 1 | import { Action } from 'redux'; 2 | import { CONNECTED_REACT_ROUTER_ACTION_TYPES } from '../../constants'; 3 | 4 | const connectedReactRouterCounter = (state = 0, action: Action) => { 5 | switch (action.type) { 6 | case CONNECTED_REACT_ROUTER_ACTION_TYPES.INCREMENT: 7 | return state + 1; 8 | case CONNECTED_REACT_ROUTER_ACTION_TYPES.DECREMENT: 9 | return state - 1; 10 | default: 11 | return state; 12 | } 13 | }; 14 | 15 | export { connectedReactRouterCounter }; 16 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/connected-react-router/redux/reducers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './counter'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import ConnectedReactRouter from './connected-react-router/index'; 3 | 4 | export default new Feature(ConnectedReactRouter); 5 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './menu'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/src/utils/menu.ts: -------------------------------------------------------------------------------- 1 | export const getFilteredRoutes = (accountPageStore, selectedRoutes) => 2 | accountPageStore 3 | .map((item) => { 4 | if (selectedRoutes.indexOf(item.key) !== -1) { 5 | const { path } = item; 6 | return { 7 | [path]: item, 8 | }; 9 | } 10 | return null; 11 | }) 12 | .filter((valid) => valid); 13 | 14 | export const getFilteredTabs = (accountPageStore, selectedTabs) => 15 | accountPageStore 16 | .map((item) => { 17 | if (selectedTabs.indexOf(item.key) !== -1) { 18 | const { component, ...rest } = item; 19 | return rest; 20 | } 21 | }) 22 | .filter((valid) => valid); 23 | -------------------------------------------------------------------------------- /packages-modules/counter/mobile/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "jsx": "react-native", 6 | "lib": ["es2017"], 7 | "esModuleInterop": true, 8 | "sourceMap": true, 9 | "resolveJsonModule": true, 10 | "allowSyntheticDefaultImports": true, 11 | "experimentalDecorators": true, 12 | "rootDir": "src", 13 | "outDir": "lib", 14 | "declaration": true, 15 | "declarationDir": "lib", 16 | "types": [ 17 | "@types/node", 18 | "@types/jest", 19 | "../../../typings", 20 | ], 21 | "skipLibCheck": true 22 | }, 23 | "include": ["src"], 24 | "exclude": [ 25 | "node_modules", 26 | "lib", 27 | "jest.config.js", 28 | "webpack.config.js", 29 | "rollup.config.js" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages-modules/counter/server/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | name: packageJson.name, 7 | displayName: packageJson.name, 8 | }; -------------------------------------------------------------------------------- /packages-modules/counter/server/src/config/env-config.ts: -------------------------------------------------------------------------------- 1 | import * as envalid from 'envalid'; 2 | 3 | const { str, num } = envalid; 4 | 5 | export const config = envalid.cleanEnv(process.env, { 6 | FILES_TTL: num({ default: 3600, desc: 'TTL for files cache in Seconds' }), 7 | }); 8 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from './env-config'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/constants/constants.ts: -------------------------------------------------------------------------------- 1 | export const NATS_MOLECULER_COUNTER_SERIVCE = 'NATS_MOLECULER_COUNTER_SERIVCE'; 2 | 3 | export enum CounterCommands { 4 | COUNTER_QUERY = 'COUNTER_QUERY', 5 | ADD_COUNTER = 'ADD_COUNTER', 6 | } 7 | 8 | export const TYPES = { 9 | CounterMockService: Symbol('CounterMockService'), 10 | CounterMockMicroservice: Symbol('CounterMockMicroservice'), 11 | CounterMockRemoteService: Symbol('CounterMockRemoteService'), 12 | }; 13 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/containers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './containers'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/dataloader/index.ts: -------------------------------------------------------------------------------- 1 | export * from './counter-dataloader'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/graphqlTypes/index.ts: -------------------------------------------------------------------------------- 1 | // Components 2 | import { Feature } from '@common-stack/server-core'; 3 | import createResolvers from './resolvers'; 4 | 5 | const graphqlFiles = (require).context('', true, /\**.graphql?/); 6 | 7 | const schema = graphqlFiles.keys().map((graphqlName) => { 8 | return graphqlFiles(graphqlName); 9 | }); 10 | 11 | export default new Feature({ schema, createResolversFunc: createResolvers } as any); 12 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/graphqlTypes/resolvers.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { GraphQLDate, GraphQLTime, GraphQLDateTime } from 'graphql-iso-date'; 3 | 4 | export default (pubsub) => ({ 5 | Date: GraphQLDate, 6 | Time: GraphQLTime, 7 | DateTime: GraphQLDateTime, 8 | }); 9 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/graphqlTypes/schema.graphql: -------------------------------------------------------------------------------- 1 | scalar Date 2 | scalar Time 3 | scalar DateTime 4 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/server-core'; 2 | import counter from './module'; 3 | 4 | export { CounterMockMoleculerService } from './services'; 5 | export * from './constants'; 6 | export default new Feature(counter); 7 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/interfaces/context.ts: -------------------------------------------------------------------------------- 1 | import { ICounterService } from './counter-service'; 2 | 3 | export interface IContext extends IService { 4 | dataSources: IDataSources; 5 | } 6 | 7 | export interface IDataSources { 8 | counterCache: ICounterService; 9 | } 10 | export interface IService { 11 | counterMockService: ICounterService; 12 | // counterMockProxyService?: ICounterService; 13 | } 14 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/interfaces/counter-service.ts: -------------------------------------------------------------------------------- 1 | import { Counter } from '../generated-models'; 2 | 3 | export interface ICounterService { 4 | counterQuery(): Counter | PromiseLike | Promise; 5 | 6 | addCounter(amount?: number): Promise | void; 7 | } 8 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './context'; 2 | export * from './counter-service'; 3 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/resolvers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './resolver'; 2 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/services/counter-mock-service.ts: -------------------------------------------------------------------------------- 1 | import { injectable } from 'inversify'; 2 | import { ICounterService } from '../interfaces'; 3 | 4 | @injectable() 5 | export class CounterMockService implements ICounterService { 6 | private amount: number; 7 | 8 | constructor() { 9 | this.amount = 0; 10 | } 11 | 12 | public counterQuery() { 13 | return { 14 | amount: this.amount, 15 | }; 16 | } 17 | 18 | public addCounter(amount) { 19 | if (amount) { 20 | this.amount += amount; 21 | } else { 22 | this.amount++; 23 | } 24 | } 25 | } 26 | 27 | // to make this instance singleton. 28 | const counterMock = new CounterMockService(); 29 | 30 | export { counterMock }; 31 | -------------------------------------------------------------------------------- /packages-modules/counter/server/src/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './counter-mock-service'; 2 | export * from './counter-mock-moleculer-service'; 3 | export * from './counter-mock-proxy-service'; 4 | -------------------------------------------------------------------------------- /packages-modules/counter/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "outDir": "../lib", 6 | "declarationDir": "lib" 7 | }, 8 | "exclude": [ 9 | "node_modules", 10 | "lib", 11 | "dist", 12 | "webpack.config.js" 13 | ] 14 | } -------------------------------------------------------------------------------- /packages/assets/.npmignore: -------------------------------------------------------------------------------- 1 | * 2 | !lib/** 3 | !src/** -------------------------------------------------------------------------------- /packages/assets/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | name: packageJson.name, 7 | displayName: packageJson.name, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/assets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@sample-stack/assets", 3 | "version": "0.0.1", 4 | "description": "Sample core for higher packages to depend on", 5 | "license": "ISC", 6 | "author": "CDMBase LLC", 7 | "main": "src/index.js", 8 | "scripts": { 9 | "build": "yarn build:clean && yarn build:lib", 10 | "build:clean": "rimraf lib", 11 | "build:lib": "webpack", 12 | "build:lib:watch": "yarn build:lib -- --watch", 13 | "jest": "./node_modules/.bin/jest", 14 | "prepublish": "yarn build", 15 | "test": "cross-env ENV_FILE=../../config/test/test.env jest", 16 | "test:debug": "npm test -- --runInBand", 17 | "test:watch": "npm test -- --watch", 18 | "watch": "yarn build:lib:watch" 19 | }, 20 | "publishConfig": { 21 | "access": "public" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/assets/src/assets/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/assets/src/assets/android-chrome-192x192.png -------------------------------------------------------------------------------- /packages/assets/src/assets/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/assets/src/assets/android-chrome-256x256.png -------------------------------------------------------------------------------- /packages/assets/src/assets/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/assets/src/assets/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /packages/assets/src/assets/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/assets/src/assets/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /packages/assets/src/assets/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #2d89ef 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/assets/src/assets/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/assets/src/assets/favicon-16x16.png -------------------------------------------------------------------------------- /packages/assets/src/assets/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/assets/src/assets/favicon-32x32.png -------------------------------------------------------------------------------- /packages/assets/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/assets/src/assets/favicon.ico -------------------------------------------------------------------------------- /packages/assets/src/assets/manifest.xjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "icons": [ 4 | { 5 | "src": "android-chrome-192x192.png", 6 | "sizes": "192x192", 7 | "type": "image/png" 8 | }, 9 | { 10 | "src": "android-chrome-256x256.png", 11 | "sizes": "256x256", 12 | "type": "image/png" 13 | } 14 | ], 15 | "theme_color": "#ffffff", 16 | "background_color": "#ffffff", 17 | "display": "standalone" 18 | } -------------------------------------------------------------------------------- /packages/assets/src/assets/mstile-150x50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/assets/src/assets/mstile-150x50.png -------------------------------------------------------------------------------- /packages/assets/src/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-self-import */ 2 | /* eslint-disable array-callback-return */ 3 | const exportedAssets = {}; 4 | let isbrowser= typeof window !== 'undefined' 5 | if (isbrowser) { 6 | // Favicon.ico should not be hashed, since browsers expect it to be exactly on /favicon.ico URL 7 | require('!file-loader?name=[name].[ext]!./assets/favicon.ico'); // eslint-disable-line 8 | 9 | // Require all files from assets dir recursively adding them into assets.json 10 | const req = require.context('!file-loader?name=[hash].[ext]!./assets', true, /.*/); 11 | req.keys().map((key) => { 12 | exportedAssets[`${key.replace('./', '')}`] = req(key); 13 | }); 14 | } 15 | 16 | export default exportedAssets; 17 | -------------------------------------------------------------------------------- /packages/assets/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "outDir": "../lib", 6 | "declarationDir": "lib", 7 | "types": [ 8 | "node", 9 | "webpack-env" 10 | ] 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | "lib", 15 | "dist", 16 | "webpack.config.js" 17 | ] 18 | } -------------------------------------------------------------------------------- /packages/sample-core/.npmignore: -------------------------------------------------------------------------------- 1 | * 2 | !lib/** 3 | -------------------------------------------------------------------------------- /packages/sample-core/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## To run tests 4 | 5 | `npm link` 6 | `npm link @xtermstack/xterm-core` 7 | `yarn install` 8 | `tsc` 9 | `yarn test` 10 | -------------------------------------------------------------------------------- /packages/sample-core/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | name: packageJson.name, 7 | displayName: packageJson.name, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/sample-core/src/index.ts: -------------------------------------------------------------------------------- 1 | export interface PersonType { 2 | name: string; 3 | id: string; 4 | sex: string; 5 | matches: [PersonType]; 6 | } 7 | export interface SomeType { 8 | testInt: number; 9 | testFloat: number; 10 | fixedString: string; 11 | } 12 | -------------------------------------------------------------------------------- /packages/sample-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "outDir": "../lib", 6 | "declarationDir": "lib" 7 | }, 8 | "exclude": [ 9 | "node_modules", 10 | "lib", 11 | "dist", 12 | "webpack.config.js" 13 | ] 14 | } -------------------------------------------------------------------------------- /packages/sample-platform/browser/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | name: packageJson.name, 7 | displayName: packageJson.name, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/components/NavBar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | const NavBar = () => ( 5 |
6 |
Home Hello Counter
7 |
8 | ); 9 | 10 | export { NavBar }; 11 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Counter'; 2 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/containers/Clock.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/sample-platform/browser/src/containers/Clock.tsx -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/containers/Loading.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | interface Props {} 4 | 5 | const Loading: React.FC = () => ( 6 |
Loading
7 | ); 8 | 9 | // export const displayLoadingState = branch( 10 | // props => props.data.loading, 11 | // renderComponent(Loading) 12 | // ); 13 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/containers/PersonList.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { graphql } from '@apollo/react-hoc'; 3 | import compose from 'lodash/flowRight'; 4 | import { PERSONS_QUERY } from '../graphql'; 5 | 6 | export interface IPersonListProps { 7 | persons; 8 | } 9 | const PersonListComponent: React.FC = ({ persons }) => ( 10 |
11 |

Persons:

12 | {persons && persons.map((person, i) =>
{person.name}
)} 13 |
14 | ); 15 | 16 | export const PersonList: React.ComponentClass<{}> = 17 | compose( 18 | graphql<{}, any, {}, {}>(PERSONS_QUERY), 19 | // flattenProp('data'), 20 | )(PersonListComponent); 21 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/containers/__tests__/setup.ts: -------------------------------------------------------------------------------- 1 | /* setup.js */ 2 | 3 | const { jsdom } = require('jsdom'); 4 | 5 | const exposedProperties = ['window', 'navigator', 'document']; 6 | 7 | (global).document = jsdom(''); 8 | (global).window = document.defaultView; 9 | Object.keys(document.defaultView).forEach((property) => { 10 | if (typeof global[property] === 'undefined') { 11 | exposedProperties.push(property); 12 | global[property] = document.defaultView[property]; 13 | } 14 | }); 15 | 16 | (global).navigator = { 17 | userAgent: 'node.js', 18 | }; 19 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/containers/__tests__/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Call this helper inside async test to let promises finish, because they are allways async. 3 | */ 4 | export const nextTick = () => 5 | new Promise((resolve) => setTimeout(resolve, 200)); 6 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/containers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Counter'; 2 | export * from './PersonList'; 3 | // export * from './Loading'; 4 | export * from './ServerCounter'; 5 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/index.ts: -------------------------------------------------------------------------------- 1 | export * from './mutations'; 2 | export * from './queries'; 3 | export * from './subscriptions'; 4 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/mutations/addCount.graphql: -------------------------------------------------------------------------------- 1 | mutation addCount($amount: Int!) { 2 | addCount(amount: $amount) { 3 | amount 4 | } 5 | } -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/mutations/addPerson.graphql: -------------------------------------------------------------------------------- 1 | mutation addPerson($name: String!, $sex: String!) { 2 | addPerson(name: $name, sex: $sex) { 3 | id 4 | name 5 | } 6 | } -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/mutations/index.ts: -------------------------------------------------------------------------------- 1 | export const ADD_PERSON_MUTATION = require('./addPerson'); 2 | export const ADD_COUNT_MUTATION = require('./addCount'); 3 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/queries/count.graphql: -------------------------------------------------------------------------------- 1 | query getCount { 2 | count { 3 | amount 4 | } 5 | } -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/queries/index.ts: -------------------------------------------------------------------------------- 1 | export const PERSON_QUERY = require('./person'); 2 | export const PERSONS_QUERY = require('./persons'); 3 | export const COUNT_QUERY = require('./count'); 4 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/queries/person.graphql: -------------------------------------------------------------------------------- 1 | query getPerson($id: String!){ 2 | getPerson(id: $id) { 3 | id 4 | name 5 | sex 6 | matches { 7 | id 8 | name 9 | sex 10 | matches { 11 | id 12 | name 13 | sex 14 | matches { 15 | id 16 | name 17 | sex 18 | } 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/queries/persons.graphql: -------------------------------------------------------------------------------- 1 | query getPersons { 2 | persons { 3 | id 4 | name 5 | } 6 | } -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/subscriptions/count.graphql: -------------------------------------------------------------------------------- 1 | subscription subscribeToCount{ 2 | subscribeToCount { 3 | amount 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/graphql/subscriptions/index.ts: -------------------------------------------------------------------------------- 1 | export const COUNT_SUBSCRIPTION = require('./count'); 2 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/index.ts: -------------------------------------------------------------------------------- 1 | import PlatformModule from './module'; 2 | export * from './graphql'; 3 | export * from './components'; 4 | export * from './containers'; 5 | 6 | 7 | export default PlatformModule; 8 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/inversify-containers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './module'; 2 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/inversify-containers/module.ts: -------------------------------------------------------------------------------- 1 | import { ContainerModule, interfaces, Container } from 'inversify'; 2 | 3 | export const platformModule: () => interfaces.ContainerModule = () => 4 | new ContainerModule((bind: interfaces.Bind) => {}); 5 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/module.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | 3 | import { interfaces } from 'inversify'; 4 | import { ApolloClient } from '@apollo/client'; 5 | import { ClientTypes as BrowserTypes } from '@common-stack/client-core'; 6 | import { platformModule } from './inversify-containers'; 7 | 8 | const platformServiceGen = (container: interfaces.Container) => ({ 9 | apolloClient: container.get>(BrowserTypes.ApolloClient), 10 | cache: container.get(BrowserTypes.InMemoryCache), 11 | utility: container.get(BrowserTypes.UtilityClass), 12 | }); 13 | export default new Feature({ 14 | createContainerFunc: platformModule, 15 | createServiceFunc: platformServiceGen, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/redux/__mocks__/api.ts: -------------------------------------------------------------------------------- 1 | export const api = { 2 | save: jest.fn(), 3 | load: jest.fn(), 4 | }; 5 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/redux/actions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sampleActions'; 2 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/redux/index.ts: -------------------------------------------------------------------------------- 1 | export * from './actions'; 2 | export * from './reducers'; 3 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/redux/reducers/Store.ts: -------------------------------------------------------------------------------- 1 | export namespace Store { 2 | export type Counter = { value: number }; 3 | 4 | export type Sample = { 5 | '@sample-stack/counter': Counter; 6 | '@sample-stack/isSaving': boolean; 7 | '@sample-stack/isLoading': boolean; 8 | '@sample-stack/error': string; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/redux/reducers/index.ts: -------------------------------------------------------------------------------- 1 | import { reducers as sampleReducers } from './sampleReducers'; 2 | 3 | export { Store } from './Store'; 4 | 5 | export const reducers = { 6 | ...sampleReducers, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/sample-platform/browser/src/services/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/sample-platform/browser/src/services/index.ts -------------------------------------------------------------------------------- /packages/sample-platform/browser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "experimentalDecorators": true, 6 | "esModuleInterop": true, 7 | "rootDir": "./src", 8 | "outDir": "../lib", 9 | "declarationDir": "lib" 10 | }, 11 | "exclude": [ 12 | "node_modules", 13 | "lib", 14 | "dist", 15 | "webpack.config.js" 16 | ] 17 | } -------------------------------------------------------------------------------- /packages/sample-platform/server/.npmignore: -------------------------------------------------------------------------------- 1 | * 2 | !lib/** 3 | -------------------------------------------------------------------------------- /packages/sample-platform/server/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## To run tests 4 | 5 | `npm link` 6 | `npm link @xtermstack/xterm-core` 7 | `yarn install` 8 | `tsc` 9 | `yarn test` 10 | -------------------------------------------------------------------------------- /packages/sample-platform/server/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | name: packageJson.name, 7 | displayName: packageJson.name, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/sample-platform/server/src/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/packages/sample-platform/server/src/index.ts -------------------------------------------------------------------------------- /packages/sample-platform/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "experimentalDecorators": true, 5 | "preserveConstEnums": true, 6 | "rootDir": "./src", 7 | "outDir": "../lib", 8 | "declarationDir": "lib" 9 | }, 10 | "exclude": [ 11 | "node_modules", 12 | "lib", 13 | "dist", 14 | "webpack.config.js", 15 | ], 16 | } -------------------------------------------------------------------------------- /packages/sample-store/.npmignore: -------------------------------------------------------------------------------- 1 | * 2 | !lib/** 3 | -------------------------------------------------------------------------------- /packages/sample-store/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## To run tests 4 | 5 | `npm link` 6 | `npm link @xtermstack/xterm-core` 7 | `yarn install` 8 | `tsc` 9 | `yarn test` 10 | -------------------------------------------------------------------------------- /packages/sample-store/src/__tests__/db/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": "sqlite3", 3 | "connection": { 4 | "filename": "packages/sample-store/__tests__/db/test-db.sqlite3" 5 | }, 6 | "seeds": { 7 | "directory": "packages/sample-store/__tests__/db/seeds" 8 | }, 9 | "migrations": { 10 | "directory": "packages/sample-store/__tests__/db/migrations" 11 | }, 12 | "useNullAsDefault": true 13 | } -------------------------------------------------------------------------------- /packages/sample-store/src/__tests__/db/migrations/counter.ts: -------------------------------------------------------------------------------- 1 | import * as Knex from 'knex'; 2 | 3 | export async function up(knex: Knex) { 4 | return knex.schema.createTable('count', (table) => { 5 | table.increments(); 6 | table.timestamps(); 7 | table.integer('amount').notNullable(); 8 | }); 9 | } 10 | 11 | export async function down(knex: Knex) { 12 | return knex.schema.dropTable('count'); 13 | } 14 | -------------------------------------------------------------------------------- /packages/sample-store/src/__tests__/db/seeds/counter.ts: -------------------------------------------------------------------------------- 1 | import * as Knex from 'knex'; 2 | 3 | const initialAmount = 5; 4 | 5 | export async function seed(knex: Knex) { 6 | await knex('count').truncate(); 7 | 8 | return knex('count').insert({ amount: initialAmount }); 9 | } 10 | -------------------------------------------------------------------------------- /packages/sample-store/src/constants/constants.ts: -------------------------------------------------------------------------------- 1 | export const TYPES = { 2 | ICounterRepository: Symbol('ICounterRepository'), 3 | }; 4 | -------------------------------------------------------------------------------- /packages/sample-store/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | -------------------------------------------------------------------------------- /packages/sample-store/src/container/index.ts: -------------------------------------------------------------------------------- 1 | export * from './module'; 2 | -------------------------------------------------------------------------------- /packages/sample-store/src/container/module.ts: -------------------------------------------------------------------------------- 1 | import { TaggedType } from '@common-stack/core'; 2 | import { ContainerModule, interfaces } from 'inversify'; 3 | 4 | import { TYPES } from '../constants'; 5 | import { DbConfig } from '../db-helpers'; 6 | import { CounterRepository, ICounterRepository } from '../repository'; 7 | 8 | export const repositoryModule: ( 9 | config: DbConfig, 10 | ) => interfaces.ContainerModule = (dbConfig) => 11 | new ContainerModule((bind: interfaces.Bind) => { 12 | bind('DefaultDbConfig').toConstantValue(dbConfig); 13 | bind(TYPES.ICounterRepository) 14 | .to(CounterRepository) 15 | .whenTargetIsDefault(); 16 | 17 | // bind(TYPES.ICounterRepository) 18 | // .to(CounterRemoteRepository) 19 | // .whenTargetNamed(TaggedType.MICROSERVICE); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/sample-store/src/database-store/migrations/counter.ts: -------------------------------------------------------------------------------- 1 | // import * as Knex from 'knex'; 2 | 3 | // export const Counter_Table = 'count'; 4 | // export const createCounter = async (driver) => 5 | // driver.schema.createTable(Counter_Table, (table) => { 6 | // table.increments(); 7 | // table.timestamps(false, true); 8 | // table.integer('amount').notNull(); 9 | // }); 10 | // export const dropCounter = async (driver) => 11 | // driver.schema.dropTable(Counter_Table); 12 | 13 | // export async function up(knex: Knex) { 14 | // return createCounter(knex); 15 | // } 16 | 17 | // export async function down(knex: Knex) { 18 | // return dropCounter(knex); 19 | // } 20 | -------------------------------------------------------------------------------- /packages/sample-store/src/database-store/migrations/index.ts: -------------------------------------------------------------------------------- 1 | // empty file on purpose 2 | exports.up = function () {}; 3 | exports.down = function () {}; 4 | -------------------------------------------------------------------------------- /packages/sample-store/src/database-store/seeds/counter.ts: -------------------------------------------------------------------------------- 1 | // import * as Knex from 'knex'; 2 | 3 | // const initialAmount = 5; 4 | 5 | // export async function seed(knex: Knex) { 6 | // await knex('count').truncate(); 7 | 8 | // return knex('count').insert({ amount: initialAmount }); 9 | // } 10 | -------------------------------------------------------------------------------- /packages/sample-store/src/database-store/seeds/index.ts: -------------------------------------------------------------------------------- 1 | // empty file on purpose 2 | // empty file on purpose 3 | exports.seed = function () {}; 4 | -------------------------------------------------------------------------------- /packages/sample-store/src/db-helpers/db-config.ts: -------------------------------------------------------------------------------- 1 | import { Config } from 'knex'; 2 | 3 | export class DbConfig { 4 | constructor(private config: Config) {} 5 | 6 | public getConfiguration(): Config { 7 | return this.config; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/sample-store/src/db-helpers/entity.ts: -------------------------------------------------------------------------------- 1 | export interface IEntity { 2 | id: number; 3 | } 4 | -------------------------------------------------------------------------------- /packages/sample-store/src/db-helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './entity'; 2 | export * from './db-config'; 3 | export * from './abstract-repository'; 4 | export * from './repository'; 5 | -------------------------------------------------------------------------------- /packages/sample-store/src/db-helpers/repository.ts: -------------------------------------------------------------------------------- 1 | export interface IRepository { 2 | getById(id: number): Promise; 3 | 4 | find(filter: string, pageNumber: number, count: number): Promise; 5 | 6 | create(dto: T): Promise; 7 | 8 | update(dto: T): Promise; 9 | } 10 | -------------------------------------------------------------------------------- /packages/sample-store/src/index.ts: -------------------------------------------------------------------------------- 1 | // export * from './constants'; 2 | // export * from './repository'; 3 | // export * from './models'; 4 | // export * from './container'; 5 | // export * from './db-helpers'; 6 | -------------------------------------------------------------------------------- /packages/sample-store/src/models/counter.ts: -------------------------------------------------------------------------------- 1 | import { DataTypes, Sequelize } from 'sequelize'; 2 | 3 | export default (sequelize: Sequelize, dataTypes: typeof DataTypes) => { 4 | // const count = sequelize.define('count', { 5 | // name: dataTypes.STRING, 6 | // }); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/sample-store/src/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './interfaces'; 2 | export * from './counter'; 3 | -------------------------------------------------------------------------------- /packages/sample-store/src/models/interfaces/count-model.ts: -------------------------------------------------------------------------------- 1 | import { IEntity } from '../../db-helpers'; 2 | 3 | export class ICount implements IEntity { 4 | public id: number; 5 | 6 | public amount: number; 7 | } 8 | -------------------------------------------------------------------------------- /packages/sample-store/src/models/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './count-model'; 2 | -------------------------------------------------------------------------------- /packages/sample-store/src/repository/index.ts: -------------------------------------------------------------------------------- 1 | export * from './counter-repository'; 2 | export * from './interfaces'; 3 | // export * from './counter-hemera-repository'; 4 | -------------------------------------------------------------------------------- /packages/sample-store/src/repository/interfaces/counter-repository.ts: -------------------------------------------------------------------------------- 1 | import { IRepository } from '../../db-helpers'; 2 | import { ICount } from '../../models'; 3 | 4 | export interface ICounterRepository extends IRepository { 5 | getCount: () => Promise; 6 | 7 | addCount: (int) => void; 8 | } 9 | -------------------------------------------------------------------------------- /packages/sample-store/src/repository/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './counter-repository'; 2 | -------------------------------------------------------------------------------- /packages/sample-store/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "rootDirs": ["./src", "../../database"], 5 | "outDir": "../lib", 6 | "declarationDir": "lib" 7 | }, 8 | "exclude": [ 9 | "node_modules", 10 | "lib", 11 | "dist", 12 | "webpack.config.js" 13 | ] 14 | } -------------------------------------------------------------------------------- /portable-devices/browser-extension/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/html/devtools.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Adminid Layout Devtools 7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/html/newtab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Adminid Layout New Tab 7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/html/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Adminid Layout Options 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/html/panel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Adminid Layout Panel 7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/html/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Adminid Layout Popup 7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/android-chrome-256x256.png -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #2d89ef 7 | 8 | 9 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/favicon-16x16.png -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/favicon-32x32.png -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/favicon.ico -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/icon.png -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/manifest.xjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "icons": [ 4 | { 5 | "src": "android-chrome-192x192.png", 6 | "sizes": "192x192", 7 | "type": "image/png" 8 | }, 9 | { 10 | "src": "android-chrome-256x256.png", 11 | "sizes": "256x256", 12 | "type": "image/png" 13 | } 14 | ], 15 | "theme_color": "#ffffff", 16 | "background_color": "#ffffff", 17 | "display": "standalone" 18 | } -------------------------------------------------------------------------------- /portable-devices/browser-extension/assets/icons/mstile-150x50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/assets/icons/mstile-150x50.png -------------------------------------------------------------------------------- /portable-devices/browser-extension/build.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable jsonc/indent */ 2 | const config = { 3 | __SSR__: true, 4 | __GRAPHQL_URL__: 'http://localhost:8080/graphql', 5 | __PERSIST_GQL__: false, 6 | __DEBUGGING__: false, 7 | __CLIENT__: true, 8 | __SERVER__: false, 9 | __DEV__: process.env.NODE_ENV !== 'production', 10 | __TEST__: false, 11 | __API_URL__: process.env.API_URL || '/graphql', 12 | __BACKEND_URL__: 'http://localhost:8080', 13 | }; 14 | 15 | module.exports = config; 16 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/html-plugin-template.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%= htmlWebpackPlugin.options.title %> 7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/pageConf.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | background: { 5 | entry: path.resolve('src/background'), 6 | }, 7 | 8 | options: { 9 | entry: './src/options', 10 | template: './assets/html/options.html', 11 | }, 12 | popup: { 13 | entry: './src/popup', 14 | template: './assets/html/popup.html', 15 | }, 16 | contentScript: { 17 | entry: path.resolve('src/contentScript'), 18 | }, 19 | devtools: { 20 | entry: './src/devtools', 21 | template: './assets/html/panel.html', 22 | }, 23 | newtab: { 24 | entry: './src/newtab', 25 | template: './assets/html/newtab.html', 26 | }, 27 | panel: { 28 | entry: './src/panel', 29 | template: './assets/html/panel.html', 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/app/500.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const Error500 = ({ error }: any) => { 4 | React.useEffect(() => { 5 | console.trace(error); 6 | }, [error]); 7 | 8 | return ( 9 |
ERROR
10 | ); 11 | } -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/app/ServerError.tsx: -------------------------------------------------------------------------------- 1 | class ServerError extends Error { 2 | constructor(error: any) { 3 | super(); 4 | for (const key of Object.getOwnPropertyNames(error)) { 5 | this[key] = error[key]; 6 | } 7 | this.name = 'ServerError'; 8 | } 9 | } 10 | 11 | export { ServerError }; 12 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/compute.tsx: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import { ExtensionRoutes } from './enums'; 3 | import { Dashboard, Home } from './pages'; 4 | 5 | export default new Feature({ 6 | routeConfig: [ 7 | { 8 | [ExtensionRoutes.Dashboard]: { 9 | exact: true, 10 | component: Dashboard 11 | } as any, 12 | [ExtensionRoutes.Home]: { 13 | exact: true, 14 | component: Home 15 | } as any, 16 | }, 17 | ], 18 | }); 19 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/config/config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-underscore-dangle */ 2 | import * as envalid from 'envalid'; 3 | 4 | const { str, bool, num } = envalid; 5 | 6 | export const config = envalid.cleanEnv(process.env, { 7 | NODE_ENV: str({ default: 'production', choices: ['production', 'staging', 'development', 'test'] }), 8 | BACKEND_URL: str({ default: __BACKEND_URL__ }), 9 | LOCAL_BACKEND_URL: str({ default: __BACKEND_URL__ }), 10 | LOCAL_GRAPHQL_URL: str({ default: __GRAPHQL_URL__ }), 11 | GRAPHQL_URL: str({ default: __GRAPHQL_URL__ }), 12 | CLIENT_URL: str({ default: __BACKEND_URL__ }), 13 | CONNECTION_ID: str({ default: 'CONNECTION_ID' }), 14 | NAMESPACE: str({ default: 'default' }), 15 | AUTH0_TOKEN_GRANTED_TIME: num({ default: 2592000000, desc: 'set to 30 days(30*24*60*60*1000) by default' }), 16 | }); 17 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from './config'; 2 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/config/newtab/epic-config.ts: -------------------------------------------------------------------------------- 1 | import { combineEpics, ofType } from 'redux-observable'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | import { mergeMap, takeUntil } from 'rxjs/operators'; 4 | import modules from '../../modules/popup'; 5 | 6 | export const epic$ = new BehaviorSubject(combineEpics(...modules.epics)); 7 | 8 | // Since we're using mergeMap, by default any new 9 | // epic that comes in will be merged into the previous 10 | // one, unless an EPIC_END action is dispatched first, 11 | // which would cause the old one(s) to be unsubscribed 12 | export const rootEpic = (action$, ...rest) => 13 | epic$.pipe(mergeMap((epic) => epic(action$, ...rest).pipe(takeUntil(action$.pipe(ofType('EPIC_END')))))); 14 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/config/options/epic-config.ts: -------------------------------------------------------------------------------- 1 | import { combineEpics, ofType } from 'redux-observable'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | import { mergeMap, takeUntil } from 'rxjs/operators'; 4 | import modules from '../../modules/options'; 5 | 6 | export const epic$ = new BehaviorSubject(combineEpics(...modules.epics)); 7 | 8 | // Since we're using mergeMap, by default any new 9 | // epic that comes in will be merged into the previous 10 | // one, unless an EPIC_END action is dispatched first, 11 | // which would cause the old one(s) to be unsubscribed 12 | export const rootEpic = (action$, ...rest) => 13 | epic$.pipe(mergeMap((epic) => epic(action$, ...rest).pipe(takeUntil(action$.pipe(ofType('EPIC_END')))))); 14 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/config/panel/epic-config.ts: -------------------------------------------------------------------------------- 1 | import { combineEpics, ofType } from 'redux-observable'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | import { mergeMap, takeUntil } from 'rxjs/operators'; 4 | import modules from '../../modules/popup'; 5 | 6 | export const epic$ = new BehaviorSubject(combineEpics(...modules.epics)); 7 | 8 | // Since we're using mergeMap, by default any new 9 | // epic that comes in will be merged into the previous 10 | // one, unless an EPIC_END action is dispatched first, 11 | // which would cause the old one(s) to be unsubscribed 12 | export const rootEpic = (action$, ...rest) => 13 | epic$.pipe(mergeMap((epic) => epic(action$, ...rest).pipe(takeUntil(action$.pipe(ofType('EPIC_END')))))); 14 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/config/popup/epic-config.ts: -------------------------------------------------------------------------------- 1 | import { combineEpics, ofType } from 'redux-observable'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | import { mergeMap, takeUntil } from 'rxjs/operators'; 4 | import modules from '../../modules/popup'; 5 | 6 | export const epic$ = new BehaviorSubject(combineEpics(...modules.epics)); 7 | 8 | // Since we're using mergeMap, by default any new 9 | // epic that comes in will be merged into the previous 10 | // one, unless an EPIC_END action is dispatched first, 11 | // which would cause the old one(s) to be unsubscribed 12 | export const rootEpic = (action$, ...rest) => 13 | epic$.pipe(mergeMap((epic) => epic(action$, ...rest).pipe(takeUntil(action$.pipe(ofType('EPIC_END')))))); 14 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/config/router-history.ts: -------------------------------------------------------------------------------- 1 | import { createMemoryHistory } from 'history'; 2 | 3 | export const history = createMemoryHistory(); 4 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/contentScript.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/browser-extension/src/contentScript.ts -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/devtools.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable jest/require-hook */ 2 | /* eslint-disable jsonc/indent */ 3 | chrome.devtools.panels.create('Dev Tools Full stack pro', 'android-chrome-192x192.png', 'panel.html'); 4 | export {}; 5 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/enums/extension-routes.ts: -------------------------------------------------------------------------------- 1 | export enum ExtensionRoutes { 2 | Dashboard = '/dashboard', 3 | Home = '/' 4 | } 5 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/enums/index.ts: -------------------------------------------------------------------------------- 1 | export * from './extension-routes'; 2 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/modules/background/index.ts: -------------------------------------------------------------------------------- 1 | import { logger } from '@cdm-logger/client'; 2 | import { ClientTypes } from '@common-stack/client-react'; 3 | import modules, { MainRoute } from './module'; 4 | 5 | class UtilityClass { 6 | // eslint-disable-next-line no-useless-constructor 7 | constructor(private modules) {} 8 | 9 | public getCacheKey(storeObj) { 10 | return this.modules.getDataIdFromObject(storeObj); 11 | } 12 | } 13 | 14 | const utility = new UtilityClass(modules); 15 | 16 | // additional bindings to container 17 | const container = modules.createContainers({}) as any; 18 | container.bind(ClientTypes.Logger).toConstantValue(logger); 19 | container.bind(ClientTypes.UtilityClass).toConstantValue(utility); 20 | 21 | export default modules; 22 | export { MainRoute, container, logger }; 23 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/modules/background/module.ts: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Feature, FeatureWithRouterFactory, renderRoutes2 } from '@common-stack/client-react'; 3 | 4 | const features = new Feature( 5 | FeatureWithRouterFactory, 6 | ); 7 | 8 | const configuredRoutes = features.getConfiguredRoutes(); 9 | 10 | const routes = renderRoutes2({ routes: configuredRoutes }); 11 | 12 | export const MainRoute = props => { 13 | return ( 14 | Loading....}> 15 | {routes} 16 | 17 | ); 18 | }; 19 | 20 | export default features; 21 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/modules/newtab/module.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Feature, FeatureWithRouterFactory, renderRoutes2 } from '@common-stack/client-react'; 3 | 4 | // import ExtensionModule from '../../compute'; 5 | 6 | 7 | const features = new Feature( 8 | FeatureWithRouterFactory, 9 | ); 10 | 11 | 12 | const configuredRoutes = features.getConfiguredRoutes(); 13 | 14 | const routes = renderRoutes2({ routes: configuredRoutes }); 15 | 16 | export const MainRoute = props => { 17 | 18 | return ( 19 | Loading....}> 20 | {routes} 21 |

Chrome Extension New Tab

22 |
23 | ); 24 | }; 25 | 26 | export default features; 27 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/modules/options/index.ts: -------------------------------------------------------------------------------- 1 | import { logger } from '@cdm-logger/client'; 2 | import { ClientTypes } from '@common-stack/client-react'; 3 | import modules, { MainRoute } from './module'; 4 | 5 | class UtilityClass { 6 | // eslint-disable-next-line no-useless-constructor 7 | constructor(private modules) {} 8 | 9 | public getCacheKey(storeObj) { 10 | return this.modules.getDataIdFromObject(storeObj); 11 | } 12 | } 13 | 14 | const utility = new UtilityClass(modules); 15 | 16 | // additional bindings to container 17 | const container = modules.createContainers({}) as any; 18 | container.bind(ClientTypes.Logger).toConstantValue(logger); 19 | container.bind(ClientTypes.UtilityClass).toConstantValue(utility); 20 | 21 | export default modules; 22 | export { MainRoute, container, logger }; 23 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/modules/options/module.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Feature, FeatureWithRouterFactory, renderRoutes2 } from '@common-stack/client-react'; 3 | 4 | const features = new Feature( 5 | FeatureWithRouterFactory, 6 | ); 7 | 8 | const configuredRoutes = features.getConfiguredRoutes(); 9 | 10 | const routes = renderRoutes2({ routes: configuredRoutes }); 11 | 12 | export const MainRoute = props => { 13 | return ( 14 | Loading....}> 15 | {routes} 16 |

Extension Options

17 |
18 | ); 19 | }; 20 | 21 | export default features; 22 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/modules/panel/module.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Feature, FeatureWithRouterFactory, renderRoutes2 } from '@common-stack/client-react'; 3 | 4 | 5 | const features = new Feature( 6 | FeatureWithRouterFactory, 7 | ); 8 | 9 | 10 | const configuredRoutes = features.getConfiguredRoutes(); 11 | 12 | const routes = renderRoutes2({ routes: configuredRoutes }); 13 | 14 | export const MainRoute = props => { 15 | 16 | return ( 17 | Loading....}> 18 | {routes} 19 |

Chrome Extension Panel

20 |
21 | ); 22 | }; 23 | 24 | export default features; 25 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/modules/popup/module.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Feature, FeatureWithRouterFactory, renderRoutes2 } from '@common-stack/client-react'; 3 | 4 | 5 | 6 | const features = new Feature( 7 | FeatureWithRouterFactory, 8 | ); 9 | 10 | 11 | const configuredRoutes = features.getConfiguredRoutes(); 12 | 13 | const routes = renderRoutes2({ routes: configuredRoutes }); 14 | 15 | export const MainRoute = props => { 16 | 17 | return ( 18 | Loading....}> 19 | {routes} 20 |

Chrome Extension Popup

21 |
22 | ); 23 | }; 24 | 25 | export default features; 26 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/newtab.tsx: -------------------------------------------------------------------------------- 1 | 2 | import * as React from 'react'; 3 | import Main from './app/Newtab'; 4 | import { createRoot } from 'react-dom/client'; 5 | import './config/public-config'; 6 | import 'reflect-metadata'; 7 | import './index.css'; 8 | 9 | 10 | 11 | const container = document.getElementById('root') as HTMLElement; 12 | const root = createRoot(container); // createRoot(container!) if you use TypeScript 13 | root.render( 14 |
15 | ); 16 | 17 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/options.tsx: -------------------------------------------------------------------------------- 1 | 2 | import * as React from 'react'; 3 | import { createRoot } from 'react-dom/client'; 4 | import Options from './app/Options'; 5 | 6 | 7 | import './config/public-config'; 8 | import 'reflect-metadata'; 9 | import './index.css'; 10 | 11 | 12 | 13 | const container = document.getElementById('root') as HTMLElement; 14 | const root = createRoot(container); // createRoot(container!) if you use TypeScript 15 | root.render( 16 | 17 | ); 18 | 19 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/pages/Dashboard.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import { useParams } from 'react-router'; 4 | 5 | export const Dashboard = () => { 6 | const { orgName } = useParams<{ orgName: string }>(); 7 | const user = useSelector((state: any) => state?.user) 8 | return
9 |
Welcome to the Dashboard. User {user?.profile?.nickname} has been logged In !
10 |
Selected org is {orgName}!
11 |
12 | } -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import { Redirect } from 'react-router'; 4 | import { ExtensionRoutes } from '../enums'; 5 | 6 | export const Home = () => { 7 | const user = useSelector((state: any) => state?.user) 8 | if (user?.auth0UserId) { 9 | return 10 | } 11 | return 12 | } -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/pages/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Dashboard'; 2 | export * from './Home'; 3 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/panel.tsx: -------------------------------------------------------------------------------- 1 | 2 | import * as React from 'react'; 3 | import Main from './app/Panel'; 4 | import { createRoot } from 'react-dom/client'; 5 | import './config/public-config'; 6 | import 'reflect-metadata'; 7 | import './index.css'; 8 | 9 | 10 | 11 | const container = document.getElementById('root') as HTMLElement; 12 | const root = createRoot(container); // createRoot(container!) if you use TypeScript 13 | root.render( 14 |
15 | ); 16 | 17 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/src/popup.tsx: -------------------------------------------------------------------------------- 1 | 2 | import * as React from 'react'; 3 | import Main from './app/Popup'; 4 | import { createRoot } from 'react-dom/client'; 5 | import './config/public-config'; 6 | import 'reflect-metadata'; 7 | import './index.css'; 8 | 9 | 10 | 11 | const container = document.getElementById('root') as HTMLElement; 12 | const root = createRoot(container); // createRoot(container!) if you use TypeScript 13 | root.render( 14 |
15 | ); 16 | 17 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "esModuleInterop": true, 6 | "sourceMap": true, 7 | "declaration": false, 8 | "jsx": "react", 9 | "outDir": "./dist", 10 | "rootDir": "./src", 11 | "skipLibCheck": true 12 | }, 13 | "include": ["../../typings/*.d.ts"], 14 | "exclude": ["node_modules", "lib", "dist", "webpack.config.js"] 15 | } 16 | -------------------------------------------------------------------------------- /portable-devices/browser-extension/webpack/persistentCache/createEnvironmentHash.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const { createHash } = require('crypto'); 3 | 4 | module.exports = env => { 5 | const hash = createHash('md5'); 6 | hash.update(JSON.stringify(env)); 7 | 8 | return hash.digest('hex'); 9 | }; 10 | -------------------------------------------------------------------------------- /portable-devices/desktop/.gitignore: -------------------------------------------------------------------------------- 1 | dll 2 | main.prod.js 3 | release 4 | .erb -------------------------------------------------------------------------------- /portable-devices/desktop/assets/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /portable-devices/desktop/assets/html/main-page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SampleDesktop 7 | 8 | 9 | 10 | 11 | 12 |
13 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /portable-devices/desktop/assets/html/tray-page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 |
14 | 15 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icon.icns -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icon.ico -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icon.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/1024x1024.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/128x128.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/16x16.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/24x24.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/256x256.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/32x32.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/48x48.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/512x512.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/64x64.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/96x96.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/icon-22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/icon-22.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/icons/icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/desktop/assets/icons/icon-256.png -------------------------------------------------------------------------------- /portable-devices/desktop/assets/preload.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unsafe-assignment */ 2 | const _require = require('esm')(module); 3 | 4 | process.once('loaded', () => { 5 | global.require = _require; 6 | }); 7 | -------------------------------------------------------------------------------- /portable-devices/desktop/build.config.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | __DEV__: process.env.NODE_ENV === 'development', 3 | __SERVER__: false, 4 | __CLIENT__: true, 5 | __SSR__: false, 6 | __DEBUGGING__: true, 7 | __TEST__: false, 8 | __GRAPHQL_URL__: process.env.API_URL || 'http://localhost:8080/graphql', 9 | __BACKEND_URL__: process.env.WEBSITE_URL || 'http://localhost:8080', 10 | }; 11 | 12 | module.exports = config; 13 | -------------------------------------------------------------------------------- /portable-devices/desktop/electron-builder.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "io.github.sample-stack", 3 | "productName": "Sample-Stack-Electron", 4 | "copyright": "Copyright © 2021 Sample-Stack", 5 | "mac": { 6 | "category": "public.app-category.productivity", 7 | "darkModeSupport": true, 8 | "hardenedRuntime": true, 9 | "gatekeeperAssess": false, 10 | "entitlements": "entitlements.mac.plist", 11 | "entitlementsInherit": "entitlements.mac.plist" 12 | }, 13 | "win": { 14 | "target": ["nsis"] 15 | }, 16 | "linux": { 17 | "executableName": "sample-stack-desktop", 18 | "category": "Application", 19 | "desktop": "sample-stack-desktop", 20 | "target": ["deb", "AppImage"] 21 | }, 22 | "directories": { 23 | "output": "release" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /portable-devices/desktop/electron-webpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "SampleDesktop", 3 | "renderer": { 4 | "dll": [], 5 | "webpackConfig": "webpack.renderer.additions.js" 6 | }, 7 | "main": { 8 | "webpackConfig": "webpack.main.additions.js" 9 | }, 10 | "whiteListedModules": [ 11 | "@emotion/react", 12 | "@emotion/css", 13 | "@emotion/styled", 14 | "antd", 15 | "react-redux", 16 | "react-helmet", 17 | "react-loadable", 18 | "react-router", 19 | "react-router-config", 20 | "react-router-dom", 21 | "react-transition-group" 22 | ] 23 | } -------------------------------------------------------------------------------- /portable-devices/desktop/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | name: packageJson.name, 7 | displayName: packageJson.name, 8 | }; -------------------------------------------------------------------------------- /portable-devices/desktop/src/common/channel.ts: -------------------------------------------------------------------------------- 1 | export const CHANNELS = { 2 | CHECK_ACCESSIBILITY_FOR_MAC_OS: 'CHECK_ACCESSIBILITY_FOR_MAC_OS', 3 | }; 4 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/common/config/config.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import * as envalid from 'envalid'; 3 | 4 | const { str, bool, json, num } = envalid; 5 | 6 | export const config = envalid.cleanEnv(process.env, { 7 | NODE_ENV: str({ default: 'production', choices: ['production', 'staging', 'development', 'test'] }), 8 | ELECTRON_WEBPACK_WDS_PORT: num({ default: 3000 }), 9 | ELECTRON_WEBPACK_WDS_HOST: str({ default: 'localhost' }), 10 | // BACKEND_URL: str({ devDefault: __BACKEND_URL__ }), 11 | // GRAPHQL_URL: str({ devDefault: __GRAPHQL_URL__ }), 12 | CLIENT_URL: str({ default: 'http://localhost' }), 13 | NAMESPACE: str({ default: 'default' }), 14 | }); 15 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/common/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ipcEvents'; 2 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/common/constants/ipcEvents.ts: -------------------------------------------------------------------------------- 1 | const enum IPC_EVENTS { 2 | // MAIN 3 | SHOW_MAIN = 'SHOW_MAIN', 4 | // ABOUT 5 | SHOW_ABOUT = 'SHOW_ABOUT', 6 | 7 | // Tray 8 | HIDE_TRAY = 'HIDE_TRAY', 9 | SHOW_TRAY = 'SHOW_TRAY', 10 | SHOW_TRAY_WINDOWED = 'SHOW_TRAY_WINDOWED', 11 | TRAY_OPEN_ITEM = 'TRAY_OPEN_ITEM', 12 | TRAY_TOGGLE_AWLAYS_ON_TOP = 'TRAY_TOGGLE_AWLAYS_ON_TOP', 13 | TRAY_WINDOWED_MODE_CHANGED = 'TRAY_WINDOWED_MODE_CHANGED', 14 | TRAY_WINDOWED_ALWAYS_ON_TOP_CHANGED = 'TRAY_WINDOWED_ALWAYS_ON_TOP_CHANGED', 15 | TOGGLE_TRAY_WITH_BOUNDS = 'TOGGLE_TRAY_WITH_BOUNDS', 16 | TRAY_ICON_CREATED = 'TRAY_ICON_CREATED', 17 | TRAY_ICON_DESTROYED = 'TRAY_ICON_DESTROYED', 18 | } 19 | 20 | export { IPC_EVENTS }; 21 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './channel'; 2 | export * from './utils'; 3 | export * from './constants'; 4 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/common/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './is'; 2 | export * from './logger'; 3 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/common/utils/is.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | import { osx, windows as _windows, main, renderer } from 'electron-is/is'; 3 | 4 | /** 5 | * Determine whether it is a mac platform 6 | */ 7 | export const isMacOS = osx(); 8 | 9 | /** 10 | * Determine whether it is windows 11 | */ 12 | export const isWindows = _windows(); 13 | 14 | export const isMain = main(); 15 | 16 | export const isRenderer = renderer(); 17 | 18 | export const isDev = process.env.NODE_ENV === 'development'; 19 | 20 | export const isTest = process.env.NODE_ENV === 'test'; 21 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/common/utils/logger.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | /* eslint-disable @typescript-eslint/ban-types */ 3 | import { CdmLogger } from '@cdm-logger/core'; 4 | /** 5 | * Create log proxy method 6 | * @param logLevel log level 7 | * @param mainLogger log object 8 | * @return {function} 9 | */ 10 | export const createLogProxy = 11 | (logLevel: string, mainLogger: CdmLogger.ILogger) => 12 | (fn: Function) => 13 | (...args: any) => { 14 | fn(...args); 15 | mainLogger[logLevel](...args); 16 | }; 17 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/app/index.ts: -------------------------------------------------------------------------------- 1 | export { Service } from './Service'; 2 | export { App } from './App'; 3 | export { View } from './View'; 4 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/config/epic-config.ts: -------------------------------------------------------------------------------- 1 | import { combineEpics, ofType } from 'redux-observable'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | import { mergeMap, takeUntil } from 'rxjs/operators'; 4 | import modules from '../modules'; 5 | 6 | export const epic$ = new BehaviorSubject(combineEpics(...modules.epics)); 7 | 8 | // Since we're using mergeMap, by default any new 9 | // epic that comes in will be merged into the previous 10 | // one, unless an EPIC_END action is dispatched first, 11 | // which would cause the old one(s) to be unsubscribed 12 | export const rootEpic = (action$, ...rest) => 13 | epic$.pipe(mergeMap((epic) => epic(action$, ...rest).pipe(takeUntil(action$.pipe(ofType('EPIC_END')))))); 14 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/index.ts: -------------------------------------------------------------------------------- 1 | import { bootstrap } from './bootstrap'; 2 | 3 | bootstrap().catch(console.error); 4 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tray-icon'; 2 | export * from './tray-window'; 3 | 4 | export const TYPES = { 5 | ITrayIcon: 'ITrayIcon', 6 | ITrayWindow: 'ITrayWindow', 7 | }; 8 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/interfaces/tray-icon.ts: -------------------------------------------------------------------------------- 1 | import { Tray } from 'electron'; 2 | 3 | export interface ITraceIcon { 4 | trayIcon: Tray; 5 | updateTitle(title: string): void; 6 | } 7 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/interfaces/tray-window.ts: -------------------------------------------------------------------------------- 1 | import { BrowserWindow } from 'electron'; 2 | 3 | export interface ITrayWindow { 4 | window: BrowserWindow; 5 | init(): void; 6 | } 7 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/ioc/index.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import container, { asyncBindings } from './inversify.config'; 3 | 4 | export default container; 5 | 6 | export const loadContainerAsync = async () => { 7 | await container.loadAsync(asyncBindings); 8 | return container; 9 | }; 10 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/ioc/inversify.config.ts: -------------------------------------------------------------------------------- 1 | import { AsyncContainerModule, Container } from 'inversify'; 2 | import { buildProviderModule } from 'inversify-binding-decorators'; 3 | import type { Repository } from 'typeorm'; 4 | import { User } from '../models'; 5 | import { getDBConnection, getRepository } from '../utils'; 6 | import TYPES from './types'; 7 | 8 | import './loader'; 9 | // container 10 | const container = new Container(); 11 | 12 | container.load(buildProviderModule()); 13 | 14 | export default container; 15 | 16 | /** 17 | * Load asynchronous objects 18 | */ 19 | export const asyncBindings = new AsyncContainerModule(async (bind) => { 20 | await getDBConnection(); 21 | 22 | bind>(TYPES.UserRepository) 23 | .toDynamicValue(() => getRepository(User)) 24 | .inRequestScope(); 25 | }); 26 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/ioc/loader.ts: -------------------------------------------------------------------------------- 1 | import '../app'; 2 | import '../services'; 3 | import '../views'; 4 | import '../utils/sqlite/connection'; 5 | import '../utils/AutoUpdater'; 6 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/ioc/types.ts: -------------------------------------------------------------------------------- 1 | const TYPES = { 2 | UserRepository: Symbol.for('UserRepository'), 3 | }; 4 | 5 | export default TYPES; 6 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/models/User.ts: -------------------------------------------------------------------------------- 1 | import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; 2 | 3 | @Entity('User') 4 | export class User { 5 | @PrimaryGeneratedColumn() 6 | id?: number; 7 | 8 | @Column('text', { nullable: true }) 9 | name?: string; 10 | 11 | @Column('text', { nullable: true }) 12 | surname?: string; 13 | } 14 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './User'; 2 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/modules/module.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '@common-stack/client-react'; 2 | import ElectronMainModule from '@sample-stack/counter-module-electron'; 3 | 4 | const modules = new Feature(ElectronMainModule); 5 | 6 | export default modules; 7 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/services/System.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable class-methods-use-this */ 2 | /* eslint-disable no-use-before-define */ 3 | import { systemPreferences } from 'electron'; 4 | import { provideSingleton } from '../utils'; 5 | import { isMacOS } from '../../common'; 6 | 7 | @provideSingleton(SystemService) 8 | export class SystemService { 9 | /** 10 | * Check availability 11 | */ 12 | checkAccessibilityForMacOS() { 13 | if (!isMacOS) return; 14 | return systemPreferences.isTrustedAccessibilityClient(true); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/services/User.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define */ 2 | import { provide } from 'inversify-binding-decorators'; 3 | import { inject } from 'inversify'; 4 | import { Repository } from 'typeorm'; 5 | 6 | import { User } from '../models'; 7 | import TYPES from '../ioc/types'; 8 | 9 | @provide(UserService) 10 | export class UserService { 11 | @inject(TYPES.UserRepository) private model!: Repository; 12 | 13 | /** 14 | * Create an object 15 | * @param name 16 | * @param surname 17 | */ 18 | public insert(name: string, surname: string): Promise { 19 | return this.model.save({ name, surname }); 20 | } 21 | 22 | public async finAll(): Promise { 23 | return this.model.find(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/services/index.ts: -------------------------------------------------------------------------------- 1 | export { UserService } from './User'; 2 | export { SystemService } from './System'; 3 | export { Logger } from './Logger'; 4 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/utils/AutoUpdater.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define */ 2 | import { autoUpdater } from 'electron-updater'; 3 | import { provide } from 'inversify-binding-decorators'; 4 | 5 | @provide(AppUpdater) 6 | export class AppUpdater { 7 | constructor() { 8 | autoUpdater.checkForUpdatesAndNotify(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/utils/createProtocol.ts: -------------------------------------------------------------------------------- 1 | import { protocol } from 'electron'; 2 | import { URL } from 'url'; 3 | import * as path from 'path'; 4 | 5 | export default (scheme: string) => { 6 | protocol.registerFileProtocol(scheme, (request, respond) => { 7 | let pathName = new URL(request.url).pathname; 8 | pathName = decodeURI(pathName); // Needed in case URL contains spaces 9 | 10 | const filePath = path.join(__dirname, pathName); 11 | respond({ path: filePath }); 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './logger'; 2 | export * from './window'; 3 | export * from './ioc'; 4 | export * from './sqlite/connection'; 5 | 6 | export * from './AutoUpdater'; 7 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/utils/ioc.ts: -------------------------------------------------------------------------------- 1 | import { fluentProvide } from 'inversify-binding-decorators'; 2 | 3 | export const provideSingleton = (identifier: any) => fluentProvide(identifier).inSingletonScope().done(); 4 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/utils/logger/customLogger.ts: -------------------------------------------------------------------------------- 1 | import { getLogger as createLogger } from '@cdm-logger/electron'; 2 | import { ConsoleLogger } from '@cdm-logger/server'; 3 | import { isDev } from '../../../common'; 4 | 5 | const logger = isDev ? ConsoleLogger.create('main') : createLogger('log'); 6 | logger.divider = (str = '-', length = 10) => { 7 | let line = ''; 8 | for (let i = 0; i < length; i += 1) { 9 | line += str; 10 | } 11 | logger.info(line); 12 | }; 13 | export { logger }; 14 | export const getLogger = (name) => logger.child({ className: name }); 15 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/utils/logger/index.ts: -------------------------------------------------------------------------------- 1 | export * from './customLogger'; 2 | export * from './logDecorator'; 3 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/main/views/index.ts: -------------------------------------------------------------------------------- 1 | export { MainWindow } from './main'; 2 | export { AboutWindow } from './about'; 3 | export { TrayWindow } from './tray'; 4 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/app/500.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const Error500 = ({ error }: any) => { 4 | React.useEffect(() => { 5 | console.trace(error); 6 | }, [error]); 7 | 8 | return ( 9 |
ERROR
10 | ); 11 | } -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/app/About.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | const pJson = require('../../../package.json'); 4 | const timeTrackerIcon = require('../../../assets/icon.png'); 5 | 6 | export default class About extends Component { 7 | 8 | render() { 9 | return ( 10 |
11 |
12 | 13 |
Version {pJson.version}
14 |
copyright © cqb325@163.com
15 |
16 |
17 | ) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/app/ServerError.tsx: -------------------------------------------------------------------------------- 1 | class ServerError extends Error { 2 | constructor(error: any) { 3 | super(); 4 | for (const key of Object.getOwnPropertyNames(error)) { 5 | this[key] = error[key]; 6 | } 7 | this.name = 'ServerError'; 8 | } 9 | } 10 | 11 | export { ServerError }; 12 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/components/layout/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SideMenu'; 2 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/components/layout/index.ts: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/config/config.ts: -------------------------------------------------------------------------------- 1 | import * as envalid from 'envalid'; 2 | 3 | const { str, bool, num } = envalid; 4 | 5 | export const config = envalid.cleanEnv(process.env, { 6 | NODE_ENV: str({ default: 'production', choices: ['production', 'staging', 'development', 'test'] }), 7 | BACKEND_URL: str({ devDefault: __BACKEND_URL__ }), 8 | LOCAL_BACKEND_URL: str({ devDefault: __BACKEND_URL__ }), 9 | LOCAL_GRAPHQL_URL: str({ default: __GRAPHQL_URL__ }), 10 | GRAPHQL_URL: str({ devDefault: __GRAPHQL_URL__ }), 11 | CLIENT_URL: str({ devDefault: __BACKEND_URL__ }), 12 | NAMESPACE: str({ default: 'default' }), 13 | AUTH0_TOKEN_GRANTED_TIME: num({ default: 2592000000, desc: 'set to 30 days(30*24*60*60*1000) by default' }), 14 | }); 15 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from './config'; 2 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/config/main/epic-config.ts: -------------------------------------------------------------------------------- 1 | import { combineEpics, ofType } from 'redux-observable'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | import { mergeMap, takeUntil } from 'rxjs/operators'; 4 | import modules from '../../modules/main'; 5 | 6 | export const epic$ = new BehaviorSubject(combineEpics(...modules.epics)); 7 | 8 | // Since we're using mergeMap, by default any new 9 | // epic that comes in will be merged into the previous 10 | // one, unless an EPIC_END action is dispatched first, 11 | // which would cause the old one(s) to be unsubscribed 12 | export const rootEpic = (action$, ...rest) => 13 | epic$.pipe(mergeMap((epic) => epic(action$, ...rest).pipe(takeUntil(action$.pipe(ofType('EPIC_END')))))); 14 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/config/router-history.ts: -------------------------------------------------------------------------------- 1 | import { createHashHistory } from 'history'; 2 | 3 | module.exports = createHashHistory(); // use hashistory in electron 4 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/config/tray/epic-config.ts: -------------------------------------------------------------------------------- 1 | import { combineEpics, ofType } from 'redux-observable'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | import { mergeMap, takeUntil } from 'rxjs/operators'; 4 | import modules from '../../modules/tray'; 5 | 6 | export const epic$ = new BehaviorSubject(combineEpics(...modules.epics)); 7 | 8 | // Since we're using mergeMap, by default any new 9 | // epic that comes in will be merged into the previous 10 | // one, unless an EPIC_END action is dispatched first, 11 | // which would cause the old one(s) to be unsubscribed 12 | export const rootEpic = (action$, ...rest) => 13 | epic$.pipe(mergeMap((epic) => epic(action$, ...rest).pipe(takeUntil(action$.pipe(ofType('EPIC_END')))))); 14 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/modules/main/index.ts: -------------------------------------------------------------------------------- 1 | import { logger } from '@cdm-logger/client'; 2 | import { ClientTypes } from '@common-stack/client-react'; 3 | import modules, { MainRoute } from './module'; 4 | 5 | class UtilityClass { 6 | // eslint-disable-next-line no-useless-constructor 7 | constructor(private modules) {} 8 | 9 | public getCacheKey(storeObj) { 10 | return this.modules.getDataIdFromObject(storeObj); 11 | } 12 | } 13 | 14 | const utility = new UtilityClass(modules); 15 | 16 | // additional bindings to container 17 | const container = modules.createContainers({}) as any; 18 | container.bind(ClientTypes.Logger).toConstantValue(logger); 19 | container.bind(ClientTypes.UtilityClass).toConstantValue(utility); 20 | 21 | export default modules; 22 | export { MainRoute, container, logger }; 23 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/modules/tray/index.ts: -------------------------------------------------------------------------------- 1 | import { logger } from '@cdm-logger/client'; 2 | import { ClientTypes } from '@common-stack/client-react'; 3 | import modules, { MainRoute } from './module'; 4 | 5 | class UtilityClass { 6 | // eslint-disable-next-line no-useless-constructor 7 | constructor(private modules) {} 8 | 9 | public getCacheKey(storeObj) { 10 | return this.modules.getDataIdFromObject(storeObj); 11 | } 12 | } 13 | 14 | const utility = new UtilityClass(modules); 15 | 16 | // additional bindings to container 17 | const container = modules.createContainers({}) as any; 18 | container.bind(ClientTypes.Logger).toConstantValue(logger); 19 | container.bind(ClientTypes.UtilityClass).toConstantValue(utility); 20 | 21 | export default modules; 22 | export { MainRoute, container, logger }; 23 | -------------------------------------------------------------------------------- /portable-devices/desktop/src/renderer/modules/tray/module.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Feature, FeatureWithRouterFactory, renderRoutes2 } from '@common-stack/client-react'; 3 | import { Layout } from 'antd'; 4 | import { ElectronTrayModule } from '@sample-stack/counter-module-browser'; 5 | 6 | const features = new Feature(FeatureWithRouterFactory, ElectronTrayModule); 7 | export const MainRoute = (props) => ( 8 | 9 | 10 |
11 | {features.getRoutes()} 12 |
13 |
14 |
15 | ); 16 | 17 | export default features; 18 | -------------------------------------------------------------------------------- /portable-devices/desktop/tools/esm-wrapper.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-unresolved */ 2 | /* eslint-disable no-global-assign */ 3 | /* eslint-disable @typescript-eslint/no-unsafe-assignment */ 4 | /* eslint-disable @typescript-eslint/no-var-requires */ 5 | /* eslint-disable @typescript-eslint/no-unsafe-call */ 6 | require = require('esm')(module, { cjs: true }); 7 | module.exports = require('./main-process.js'); 8 | -------------------------------------------------------------------------------- /portable-devices/desktop/tools/utils.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const getSymlinkedNodeModulesForDirectory = require('../../../tools/get-symlinked-modules'); 3 | 4 | function getWorkspacePackagePaths(root) { 5 | const symlinkedModules = getSymlinkedNodeModulesForDirectory(root); 6 | const symlinkedModulePaths = Object.values(symlinkedModules); 7 | return symlinkedModulePaths.map((f) => path.resolve(f, 'lib')); 8 | } 9 | module.exports = { 10 | getWorkspacePackagePaths, 11 | }; 12 | -------------------------------------------------------------------------------- /portable-devices/desktop/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "esModuleInterop": true, 6 | "sourceMap": true, 7 | "declaration": false, 8 | "jsx": "react", 9 | "outDir": "./dist", 10 | "rootDir": "./src" 11 | }, 12 | "include": ["../../typings/*.d.ts"], 13 | "exclude": ["node_modules", "lib", "dist", "webpack.config.js"] 14 | } 15 | -------------------------------------------------------------------------------- /portable-devices/mobile/.expo-shared/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "e997a5256149a4b76e6bfd6cbf519c5e5a0f1d278a3d8fa1253022b03c90473b": true, 3 | "af683c96e0ffd2cf81287651c9433fa44debc1220ca7cb431fe482747f34a505": true, 4 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true, 5 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true 6 | } 7 | -------------------------------------------------------------------------------- /portable-devices/mobile/.exprc: -------------------------------------------------------------------------------- 1 | { 2 | "extraAdbReversePorts": [8080] 3 | } -------------------------------------------------------------------------------- /portable-devices/mobile/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p8 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | *.orig.* 10 | web-build/ 11 | 12 | # macOS 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /portable-devices/mobile/App.tsx: -------------------------------------------------------------------------------- 1 | import './src/config/public-config'; 2 | import App from './src/App'; 3 | 4 | export default App; 5 | -------------------------------------------------------------------------------- /portable-devices/mobile/__generated__/AppEntry.js: -------------------------------------------------------------------------------- 1 | // @generated by expo-yarn-workspaces 2 | 3 | import 'expo/build/Expo.fx'; 4 | import { activateKeepAwake } from 'expo-keep-awake'; 5 | import registerRootComponent from 'expo/build/launch/registerRootComponent'; 6 | 7 | import App from '../App'; 8 | 9 | if (__DEV__) { 10 | activateKeepAwake(); 11 | } 12 | 13 | registerRootComponent(App); 14 | -------------------------------------------------------------------------------- /portable-devices/mobile/assets/fonts/SpaceMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/assets/fonts/SpaceMono-Regular.ttf -------------------------------------------------------------------------------- /portable-devices/mobile/assets/images/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/assets/images/adaptive-icon.png -------------------------------------------------------------------------------- /portable-devices/mobile/assets/images/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/assets/images/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /portable-devices/mobile/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/assets/images/favicon.png -------------------------------------------------------------------------------- /portable-devices/mobile/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/assets/images/icon.png -------------------------------------------------------------------------------- /portable-devices/mobile/assets/images/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/assets/images/splash.png -------------------------------------------------------------------------------- /portable-devices/mobile/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | plugins: [ 6 | [ 7 | 'module:react-native-dotenv', 8 | { 9 | moduleName: '@env', 10 | ...(!!process.env.ENV_FILE && {path: process.env.ENV_FILE}) 11 | }, 12 | ], 13 | 'react-native-reanimated/plugin', 14 | ], 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /portable-devices/mobile/build.config.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | __SERVER__: false, 3 | __CLIENT__: true, 4 | __SSR__: false, 5 | __DEBUGGING__: false, 6 | __TEST__: false, 7 | __API_URL__: process.env.API_URL || 'http://localhost:8080/graphql', 8 | __WEBSITE_URL__: process.env.WEBSITE_URL || 'http://localhost:8080' 9 | } 10 | 11 | module.exports = config; 12 | -------------------------------------------------------------------------------- /portable-devices/mobile/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable jest/require-hook */ 2 | /* eslint-disable import/no-unresolved */ 3 | /* eslint-disable import/no-extraneous-dependencies */ 4 | import { registerRootComponent } from 'expo'; 5 | import './shim'; 6 | import 'react-native-reanimated'; // to fix web crash 7 | 8 | import App from './App'; 9 | 10 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App); 11 | // It also ensures that whether you load the app in the Expo client or in a native build, 12 | // the environment is set up appropriately 13 | registerRootComponent(App); 14 | -------------------------------------------------------------------------------- /portable-devices/mobile/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../jest.config.base'); 2 | const packageJson = require('./package'); 3 | 4 | module.exports = { 5 | ...base, 6 | preset: 'jest-expo', 7 | modulePathIgnorePatterns: [ 8 | '/node_modules/react-native/Libraries/react-native/', 9 | '/node_modules/react-native/Libraries/vendor/core/whatwg-fetch.js', 10 | '/node_modules/react-native/jest/', 11 | '/node_modules/haul/', 12 | '/portable-devices/mobile/.expo/', 13 | '/portable-devices/mobile/node_modules/' 14 | ], 15 | name: packageJson.name, 16 | displayName: packageJson.name, 17 | globals: { 18 | // https://github.com/software-mansion/react-native-reanimated/issues/1380#issuecomment-865143328 19 | __reanimatedWorkletInit: jest.fn(), 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /portable-devices/mobile/metro.config.js: -------------------------------------------------------------------------------- 1 | // Learn more https://docs.expo.io/guides/customizing-metro 2 | const { getDefaultConfig } = require('expo/metro-config'); 3 | const path = require('path'); 4 | 5 | const projectRoot = __dirname; 6 | const workspaceRoot = path.resolve(__dirname, '../..'); 7 | 8 | const config = getDefaultConfig(projectRoot); 9 | 10 | config.watchFolders = [workspaceRoot]; 11 | config.resolver.nodeModulesPath = [ 12 | path.resolve(projectRoot, 'node_modules'), 13 | path.resolve(workspaceRoot, 'node_modules'), 14 | ]; 15 | 16 | module.exports = config; 17 | -------------------------------------------------------------------------------- /portable-devices/mobile/react-native.config.js: -------------------------------------------------------------------------------- 1 | // File created by expo-dev-client/app.plugin.js 2 | 3 | module.exports = { 4 | dependencies: { 5 | ...require("expo-dev-client/dependencies"), 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /portable-devices/mobile/shim.js: -------------------------------------------------------------------------------- 1 | import 'text-encoding-polyfill'; // to fix App Crash due to reference to TextEncoder 2 | 3 | if (typeof BigInt === 'undefined') global.BigInt = require('big-integer'); -------------------------------------------------------------------------------- /portable-devices/mobile/src/assets/fonts/SpaceMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/src/assets/fonts/SpaceMono-Regular.ttf -------------------------------------------------------------------------------- /portable-devices/mobile/src/assets/images/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/src/assets/images/adaptive-icon.png -------------------------------------------------------------------------------- /portable-devices/mobile/src/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/src/assets/images/favicon.png -------------------------------------------------------------------------------- /portable-devices/mobile/src/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/src/assets/images/icon.png -------------------------------------------------------------------------------- /portable-devices/mobile/src/assets/images/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/src/assets/images/splash.png -------------------------------------------------------------------------------- /portable-devices/mobile/src/components/__tests__/StyledText-test.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | 4 | import { MonoText } from '../StyledText'; 5 | 6 | it(`renders correctly`, () => { 7 | const tree = renderer.create(Snapshot test!).toJSON(); 8 | 9 | expect(tree).toMatchSnapshot(); 10 | }); 11 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/components/layout/Drawer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Drawer } from 'native-base'; 3 | import { Route } from 'react-router-native'; 4 | import SideBar from './SideBar'; 5 | 6 | export const DrawerRoute = ({ match, drawerRef, routes }: any) => { 7 | const onClose = () => { 8 | console.log("close") 9 | drawerRef.current._root.close() 10 | } 11 | 12 | return ( 13 | 17 | } 18 | onClose={onClose} 19 | > 20 | {routes.map((route: any) => ( 21 | 22 | ))} 23 | 24 | ) 25 | }; 26 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/components/layout/Header.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Header, Left, Right, Body, Text, Icon } from 'native-base'; 3 | 4 | const MainHeader = (props: any) => { 5 | const[isToggle, setIsToggle] = useState(false); 6 | 7 | const toggle = () => { 8 | if(isToggle){ 9 | props.drawerRef?.current?._root?.close(); 10 | } else{ 11 | props.drawerRef?.current?._root?.open(); 12 | } 13 | setIsToggle(!isToggle) 14 | } 15 | 16 | return ( 17 |
18 | 19 | toggle()} /> 20 | 21 | 22 | {props.title} 23 | 24 |
25 | ); 26 | }; 27 | 28 | export default MainHeader; 29 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/components/layout/Layout.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from 'react'; 2 | import { View } from 'react-native'; 3 | import { connect } from 'react-redux'; 4 | import MainHeader from './Header'; 5 | import { DrawerRoute } from './Drawer'; 6 | 7 | const Layout = (props: any, route: any) => { 8 | const drawerRef = useRef(); 9 | return ( 10 | 11 | 12 | 13 | 14 | ); 15 | }; 16 | 17 | export const ProLayout = connect((state: any) => { 18 | return { 19 | settings: state.settings, 20 | location: state.router.location, 21 | }; 22 | })(Layout); 23 | 24 | export default Layout; 25 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/components/layout/module.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | /* eslint-disable @typescript-eslint/no-unsafe-assignment */ 3 | /* eslint-disable @typescript-eslint/no-explicit-any */ 4 | import { Feature } from '@common-stack/client-react'; 5 | import NativeBaseSample from './NativeBaseSample' 6 | import Layout from './Layout'; 7 | 8 | export default new Feature({ 9 | routeConfig: [ 10 | { 11 | '/': { 12 | exact: true, 13 | component: NativeBaseSample, 14 | } as any, 15 | }, 16 | // { 17 | // '/org': { 18 | // exact: false, 19 | // component: Layout, 20 | // key: 'layout', 21 | // } as any, 22 | // }, 23 | ], 24 | }); 25 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/components/layout/root-navigation.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from 'react'; 2 | 3 | export const navigationRefs = React.createRef(); 4 | 5 | export function navigate(name: any) { 6 | navigationRefs.current?.navigate(name); 7 | } 8 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/config/config.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDEBase/fullstack-pro/21b28bf2fb87354e8d8f045b36101a0363d78e06/portable-devices/mobile/src/config/config.ts -------------------------------------------------------------------------------- /portable-devices/mobile/src/config/epic-config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unsafe-member-access */ 2 | /* eslint-disable @typescript-eslint/no-unsafe-call */ 3 | import { combineEpics, ofType } from 'redux-observable'; 4 | import { BehaviorSubject } from 'rxjs'; 5 | import { mergeMap, takeUntil } from 'rxjs/operators'; 6 | import modules from '../modules'; 7 | 8 | export const epic$ = new BehaviorSubject(combineEpics(...modules.epics)); 9 | 10 | // Since we're using mergeMap, by default any new 11 | // epic that comes in will be merged into the previous 12 | // one, unless an EPIC_END action is dispatched first, 13 | // which would cause the old one(s) to be unsubscribed 14 | export const rootEpic = (action$, ...rest) => 15 | epic$.pipe(mergeMap((epic) => epic(action$, ...rest).pipe(takeUntil(action$.pipe(ofType('EPIC_END')))))); 16 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { LOG_LEVEL } from '@env'; 2 | 3 | const config = { 4 | LOG_LEVEL, 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/config/public-config.ts: -------------------------------------------------------------------------------- 1 | import { NODE_ENV, GRAPHQL_URL, FACEBOOK_APP_ID, GA_ID, LOG_LEVEL } from '@env'; 2 | 3 | const publicEnv = { 4 | NODE_ENV, 5 | GRAPHQL_URL, 6 | FACEBOOK_APP_ID, 7 | GA_ID, 8 | LOG_LEVEL, 9 | LOCAL_GRAPHQL_URL: GRAPHQL_URL, 10 | }; 11 | 12 | const isBrowser = typeof window !== 'undefined'; 13 | 14 | export default publicEnv; 15 | 16 | if (isBrowser) { 17 | // process.env = env; 18 | process.APP_ENV = publicEnv; 19 | } 20 | 21 | export const PUBLIC_SETTINGS: __PUBLIC_SETTINGS__ = { 22 | GRAPHQL_URL: publicEnv.GRAPHQL_URL, 23 | LOCAL_GRAPHQL_URL: publicEnv.LOCAL_GRAPHQL_URL, 24 | LOG_LEVEL: publicEnv.LOG_LEVEL || 'trace', 25 | }; 26 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/config/router-history.ts: -------------------------------------------------------------------------------- 1 | import { createMemoryHistory } from 'history'; 2 | 3 | const hist = createMemoryHistory(); 4 | 5 | export default hist; 6 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/constants/Colors.ts: -------------------------------------------------------------------------------- 1 | const tintColorLight = '#2f95dc'; 2 | const tintColorDark = '#fff'; 3 | 4 | export default { 5 | light: { 6 | text: '#000', 7 | background: '#fff', 8 | tint: tintColorLight, 9 | tabIconDefault: '#ccc', 10 | tabIconSelected: tintColorLight, 11 | }, 12 | dark: { 13 | text: '#fff', 14 | background: '#000', 15 | tint: tintColorDark, 16 | tabIconDefault: '#ccc', 17 | tabIconSelected: tintColorDark, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/constants/Layout.ts: -------------------------------------------------------------------------------- 1 | import { Dimensions } from 'react-native'; 2 | 3 | const { width } = Dimensions.get('window'); 4 | const { height } = Dimensions.get('window'); 5 | 6 | export default { 7 | window: { 8 | width, 9 | height, 10 | }, 11 | isSmallDevice: width < 375, 12 | }; 13 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/hooks/useColorScheme.ts: -------------------------------------------------------------------------------- 1 | import { ColorSchemeName, useColorScheme as _useColorScheme } from 'react-native'; 2 | 3 | // The useColorScheme value is always either light or dark, but the built-in 4 | // type suggests that it can be null. This will not happen in practice, so this 5 | // makes it a bit easier to work with. 6 | export default function useColorScheme(): NonNullable { 7 | return _useColorScheme(); 8 | } 9 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/hooks/useColorScheme.web.ts: -------------------------------------------------------------------------------- 1 | // useColorScheme from react-native does not support web currently. You can replace 2 | // this with react-native-appearance if you would like theme support on web. 3 | export default function useColorScheme() { 4 | return 'light'; 5 | } 6 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/modules/navigator.tsx: -------------------------------------------------------------------------------- 1 | import { navigationRef } from '@common-stack/client-react'; 2 | 3 | export function navigate(name: string, params: never) { 4 | if (navigationRef.isReady()) { 5 | navigationRef.navigate(name as never, params); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/pages/PersonalInfo.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Box, Text } from 'native-base'; 3 | import { useRoute } from '@react-navigation/native'; 4 | 5 | export const PersonalInfo = () => { 6 | const route = useRoute(); 7 | return ( 8 | 9 | Personal Info 10 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/pages/Settings.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Box, Text } from 'native-base'; 3 | 4 | export const Settings = () => { 5 | return ( 6 | 7 | Settings 8 | 9 | ); 10 | }; 11 | -------------------------------------------------------------------------------- /portable-devices/mobile/src/pages/dashboard.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Text, ViewStyle } from 'react-native'; 3 | import { Button } from 'native-base'; 4 | import { useNavigation } from '@react-navigation/native'; 5 | interface Style { 6 | container: ViewStyle; 7 | } 8 | 9 | const Dashboard = () => { 10 | const navigation = useNavigation(); 11 | return ( 12 | 13 | Dashboard Value 14 | Calendar 15 | 16 | 17 | ); 18 | }; 19 | 20 | const styles = StyleSheet.create