├── AureliaNest.code-workspace ├── LICENSE ├── README.md ├── client ├── .editorconfig ├── .gitignore ├── .vscode │ ├── extensions.json │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── README.md ├── assets │ ├── favicon.ico │ ├── loader.css │ ├── loader.min.css │ └── styles.css ├── aurelia_project │ ├── aurelia.json │ ├── generators │ │ ├── attribute.json │ │ ├── attribute.ts │ │ ├── binding-behavior.json │ │ ├── binding-behavior.ts │ │ ├── component.json │ │ ├── component.ts │ │ ├── element.json │ │ ├── element.ts │ │ ├── generator.json │ │ ├── generator.ts │ │ ├── task.json │ │ ├── task.ts │ │ ├── value-converter.json │ │ └── value-converter.ts │ └── tasks │ │ ├── build.json │ │ ├── build.ts │ │ ├── jest.json │ │ ├── jest.ts │ │ ├── run.json │ │ ├── run.ts │ │ ├── test.json │ │ └── test.ts ├── config.js ├── config │ ├── environment.json │ └── environment.production.json ├── custom_typings │ ├── fetch.d.ts │ └── system.d.ts ├── index.ejs ├── package.json ├── src │ ├── app-router-config.ts │ ├── app.html │ ├── app.ts │ ├── auth-interceptor.ts │ ├── auth │ │ ├── auth-config.development.ts │ │ ├── auth-data.service.ts │ │ ├── auth-utility.service.ts │ │ ├── login.html │ │ ├── login.ts │ │ ├── logout.html │ │ ├── logout.ts │ │ ├── profile.html │ │ ├── profile.ts │ │ ├── signup.html │ │ └── signup.ts │ ├── cats │ │ ├── cat.interface.ts │ │ ├── cats-data.service.ts │ │ ├── cats-list.html │ │ └── cats-list.ts │ ├── contacts │ │ ├── contact-detail.html │ │ ├── contact-detail.ts │ │ ├── contact-list.html │ │ ├── contact-list.ts │ │ ├── contact.ts │ │ ├── index.html │ │ ├── index.ts │ │ ├── messages.ts │ │ ├── no-selection.html │ │ ├── no-selection.ts │ │ ├── style.css │ │ ├── utility.ts │ │ └── web-api.ts │ ├── custom-http-client.ts │ ├── environment.ts │ ├── favicon.ico │ ├── main.ts │ ├── nav-bar.html │ ├── nav-bar.ts │ ├── resources │ │ ├── elements │ │ │ ├── abp-modal.html │ │ │ ├── abp-modal.ts │ │ │ ├── bootstrap-tooltip.ts │ │ │ └── loading-indicator.ts │ │ ├── index.ts │ │ └── value-converters │ │ │ ├── admin-filter.ts │ │ │ ├── auth-filter.ts │ │ │ ├── date-format.ts │ │ │ ├── number.ts │ │ │ └── stringify.ts │ ├── shared │ │ ├── bootstrap-form-renderer.ts │ │ ├── globals.ts │ │ └── services │ │ │ ├── auth.service.ts │ │ │ ├── authentication.service.ts │ │ │ ├── authorize-step.ts │ │ │ ├── data.service.ts │ │ │ ├── fetch-config.service.ts │ │ │ ├── popup.service.ts │ │ │ └── storage.service.ts │ ├── styles │ │ ├── bootstrap-social.scss │ │ ├── bootstrap.scss │ │ └── styles.scss │ ├── users │ │ ├── user.interface.ts │ │ ├── users-data.service.ts │ │ ├── users-list.html │ │ ├── users-list.scss │ │ └── users-list.ts │ ├── welcome.html │ └── welcome.ts ├── test │ ├── e2e │ │ ├── demo.e2e.ts │ │ ├── skeleton.po.ts │ │ └── welcome.po.ts │ ├── jest-pretest.ts │ ├── protractor.conf.js │ └── unit │ │ └── app.spec.ts ├── tsconfig.json ├── tslint.json ├── webpack.config.js └── yarn.lock ├── server ├── .editorconfig ├── .env.dev ├── .env.prod ├── .eslintrc ├── .gitignore ├── .prettierrc ├── .vscode │ ├── launch.json │ └── tasks.json ├── README.md ├── nest-cli.json ├── package.json ├── schema.gql ├── src │ ├── app.controller.ts │ ├── app.module.ts │ ├── app.service.ts │ ├── auth │ │ ├── auth-config.development.template.ts │ │ ├── auth.controller.spec.ts │ │ ├── auth.controller.ts │ │ ├── auth.module.ts │ │ ├── dto │ │ │ ├── index.ts │ │ │ ├── token.dto.ts │ │ │ ├── user.dto.ts │ │ │ ├── userLogin.dto.ts │ │ │ ├── userSignup.dto.ts │ │ │ └── username.dto.ts │ │ ├── models │ │ │ ├── index.ts │ │ │ ├── provider.interface.ts │ │ │ └── user.interface.ts │ │ ├── services │ │ │ ├── auth.service.spec.ts │ │ │ ├── auth.service.ts │ │ │ ├── facebook.service.ts │ │ │ ├── user.service.ts │ │ │ └── windowslive.service.ts │ │ └── strategies │ │ │ ├── facebook.strategy.ts │ │ │ ├── github.strategy.ts │ │ │ ├── google.strategy.ts │ │ │ ├── jwt.strategy.ts │ │ │ ├── linkedin.strategy.ts │ │ │ ├── local.strategy.ts │ │ │ ├── microsoft.strategy.ts │ │ │ ├── twitter.strategy.ts │ │ │ └── windowslive.strategy.ts │ ├── cats │ │ ├── cats.module.ts │ │ ├── cats.resolver.ts │ │ ├── graphql │ │ │ ├── enums │ │ │ │ └── catFields.enum.ts │ │ │ ├── inputs │ │ │ │ ├── cat-input.ts │ │ │ │ └── catQueryArgs.input.ts │ │ │ └── types │ │ │ │ ├── cat.type.ts │ │ │ │ └── owner.type.ts │ │ ├── models │ │ │ ├── cat.interface.ts │ │ │ └── index.ts │ │ ├── schemas │ │ │ └── cats.schema.ts │ │ └── services │ │ │ ├── cats.service.ts │ │ │ └── owners.service.ts │ ├── main.hmr.ts │ ├── main.ts │ ├── shared │ │ ├── common.module.ts │ │ ├── decorators │ │ │ ├── currentUser.decorator.ts │ │ │ ├── index.ts │ │ │ └── roles.decorator.ts │ │ ├── filters │ │ │ └── http-exception.filter.ts │ │ ├── graphql │ │ │ ├── enums │ │ │ │ ├── direction.enum.ts │ │ │ │ ├── index.ts │ │ │ │ └── operator.enum.ts │ │ │ ├── inputs │ │ │ │ ├── index.ts │ │ │ │ └── stringQueryArgs.input.ts │ │ │ ├── scalars │ │ │ │ └── date.scalar.ts │ │ │ ├── types │ │ │ │ ├── filterByGeneric.type.ts │ │ │ │ ├── filterByString.type.ts │ │ │ │ ├── index.ts │ │ │ │ ├── orderByGeneric.type.ts │ │ │ │ ├── orderByString.type.ts │ │ │ │ ├── pageInfo.type.ts │ │ │ │ └── paginatedResponse.type.ts │ │ │ └── utils │ │ │ │ └── utilities.ts │ │ ├── guards │ │ │ ├── graphql-passport-auth.guard.ts │ │ │ └── index.ts │ │ ├── interceptors │ │ │ ├── exception.interceptor.ts │ │ │ ├── logging.interceptor.ts │ │ │ ├── timeout.interceptor.ts │ │ │ └── transform.interceptor.ts │ │ ├── middleware │ │ │ └── logger.middleware.ts │ │ ├── models │ │ │ ├── direction.enum.ts │ │ │ ├── filterBy.interface.ts │ │ │ ├── index.ts │ │ │ ├── operator.enum.ts │ │ │ ├── provider.interface.ts │ │ │ └── user.interface.ts │ │ ├── pipes │ │ │ ├── parse-int.pipe.ts │ │ │ └── validation.pipe.ts │ │ └── schemas │ │ │ └── user.schema.ts │ ├── swagger.ts │ └── users │ │ ├── graphql │ │ ├── inputs │ │ │ └── pagination.input.ts │ │ └── types │ │ │ ├── provider.type.ts │ │ │ └── user.type.ts │ │ ├── models │ │ ├── index.ts │ │ ├── provider.interface.ts │ │ └── user.interface.ts │ │ ├── users.module.ts │ │ ├── users.resolver.ts │ │ └── users.service.ts ├── test │ ├── app.e2e-spec.ts │ └── jest-e2e.json ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock └── tsconfig.json /AureliaNest.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "server" 5 | }, 6 | { 7 | "path": "client" 8 | } 9 | ], 10 | "settings": { 11 | "typescript.tsdk": "server\\node_modules\\typescript\\lib" 12 | } 13 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2022 Ghislain B. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /client/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # 2 space indentation 12 | [**.*] 13 | indent_style = space 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # You may want to customise this file depending on your Operating System 2 | # and the editor that you use. 3 | # 4 | # We recommend that you use a Global Gitignore for files that are not related 5 | # to the project. (https://help.github.com/articles/ignoring-files/#create-a-global-gitignore) 6 | 7 | # OS 8 | # 9 | # Ref: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore 10 | # Ref: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore 11 | # Ref: https://github.com/github/gitignore/blob/master/Global/Linux.gitignore 12 | .DS_STORE 13 | Thumbs.db 14 | 15 | # Editors 16 | # 17 | # Ref: https://github.com/github/gitignore/blob/master/Global 18 | # Ref: https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore 19 | # Ref: https://github.com/github/gitignore/blob/master/Global/VisualStudioCode.gitignore 20 | .idea 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # Dependencies 28 | node_modules 29 | 30 | # Compiled files 31 | scripts 32 | 33 | ## NPM / Yarn / Lock / Log / Debugger / Tests 34 | npm-debug.log* 35 | yarn-error.log 36 | /dist 37 | /build 38 | /test/*coverage 39 | /test/coverage* 40 | /.chrome 41 | 42 | ## Remove NPM/Yarn logs and lock files 43 | npm-debug.log 44 | yarn-error.log 45 | -------------------------------------------------------------------------------- /client/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "AureliaEffect.aurelia", 4 | "msjsdiag.debugger-for-chrome", 5 | "EditorConfig.EditorConfig", 6 | "behzad88.Aurelia" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /client/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for node debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Chrome Debugger", 9 | "type": "chrome", 10 | "request": "launch", 11 | "url": "http://localhost:9000", 12 | "webRoot": "${workspaceRoot}/src", 13 | "userDataDir": "${workspaceRoot}/.chrome", 14 | "sourceMapPathOverrides": { 15 | "webpack:///./src/*": "${webRoot}/*" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /client/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "typescript.tsdk": "node_modules/typescript/lib", 4 | "html.suggest.angular1": false, 5 | "html.suggest.ionic": false 6 | } 7 | -------------------------------------------------------------------------------- /client/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "Aurelia (client)", 6 | "command": "yarn", 7 | "type": "shell", 8 | "args": [ 9 | "start" 10 | ], 11 | "problemMatcher": [] 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | ## Client TypeScript Webpack 2 | 3 | ### Client installation 4 | Start by cloning the repo and then install it (with `npm` or [yarn](https://yarnpkg.com/)) 5 | ```bash 6 | cd aurelia-nest-auth-mongodb/client 7 | npm install # or: yarn install 8 | ``` 9 | 10 | ### VScode Workspaces 11 | If you use VSCode (Visual Studio Code) as your main editor, you can load the VSCode workspace. Once the workspace is loaded, you will then have access to multiple tasks (defined in `client/tasks.json`) which makes it easy to execute the code without even typing any command in the shell (you still have to make sure to `npm install` in both `client` and `server` folders). 12 | 13 | ### Running the App 14 | The simplest way of running the App is to use the VSCode tasks there were created **Aurelia (client)** and **NestJS Dev (server)** (or _NestJS Debug (server)_ if you wish to debug your code with NestJS) 15 | 16 | The second way would be to type the shell command `yarn start` in both `client` and `server` folders. 17 | ```bash 18 | npm start # or: yarn start 19 | ``` 20 | 21 | ### Web UI 22 | If everything goes well, your application should now run locally on port `9000`. So, in your browser just go to the URL [http://localhost:9000](http://localhost:9000). 23 | 24 | ## License 25 | MIT 26 | 27 | ## Getting started 28 | 29 | Before you start, make sure you have a recent version of [NodeJS](http://nodejs.org/) environment *>=10.0* with NPM 6 or Yarn. 30 | 31 | From the project folder, execute the following commands: 32 | 33 | ```shell 34 | npm install # or: yarn install 35 | ``` 36 | 37 | This will install all required dependencies, including a local version of Webpack that is going to 38 | build and bundle the app. There is no need to install Webpack globally. 39 | 40 | To run the app execute the following command: 41 | 42 | ```shell 43 | npm start # or: yarn start 44 | ``` 45 | -------------------------------------------------------------------------------- /client/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiscoding/aurelia-nest-auth-mongodb/56ec8b9c178c5b7bbb60dd361ef3f421c7eb5449/client/assets/favicon.ico -------------------------------------------------------------------------------- /client/assets/loader.min.css: -------------------------------------------------------------------------------- 1 | .splash{text-align:center;margin:-10% 0 0 0;box-sizing:border-box}.splash .message{color:#3275b3;font-size:52px;line-height:52px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.splash .fa-spinner{color:#213679;text-align:center;display:inline-block;font-size:52px;margin-top:50px}.splash{position:absolute;display:flex;height:100vh;width:100vw;align-items:center;justify-content:center;flex-direction:column}.splash .spinner{text-align:center}.splash .spinner .fa-spinner{display:inline-block;font-size:48px;color:#3275b3} 2 | .loader{font-size:10px;margin:30px auto;width:1em;height:1em;border-radius:50%;position:relative;text-indent:-9999em;-webkit-animation:load4 1s infinite linear;animation:load4 1s infinite linear;-webkit-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0)}@-webkit-keyframes load4{0%,100%{box-shadow:0 -3em 0 .2em #213679,2em -2em 0 0 #213679,3em 0 0 -1em #213679,2em 2em 0 -1em #213679,0 3em 0 -1em #213679,-2em 2em 0 -1em #213679,-3em 0 0 -1em #213679,-2em -2em 0 0 #213679} 3 | 12.5%{box-shadow:0 -3em 0 0 #213679,2em -2em 0 .2em #213679,3em 0 0 0 #213679,2em 2em 0 -1em #213679,0 3em 0 -1em #213679,-2em 2em 0 -1em #213679,-3em 0 0 -1em #213679,-2em -2em 0 -1em #213679}25%{box-shadow:0 -3em 0 -0.5em #213679,2em -2em 0 0 #213679,3em 0 0 .2em #213679,2em 2em 0 0 #213679,0 3em 0 -1em #213679,-2em 2em 0 -1em #213679,-3em 0 0 -1em #213679,-2em -2em 0 -1em #213679}37.5%{box-shadow:0 -3em 0 -1em #213679,2em -2em 0 -1em #213679,3em 0 0 0 #213679,2em 2em 0 .2em #213679,0 3em 0 0 #213679,-2em 2em 0 -1em #213679,-3em 0 0 -1em #213679,-2em -2em 0 -1em #213679} 4 | 50%{box-shadow:0 -3em 0 -1em #213679,2em -2em 0 -1em #213679,3em 0 0 -1em #213679,2em 2em 0 0 #213679,0 3em 0 .2em #213679,-2em 2em 0 0 #213679,-3em 0 0 -1em #213679,-2em -2em 0 -1em #213679}62.5%{box-shadow:0 -3em 0 -1em #213679,2em -2em 0 -1em #213679,3em 0 0 -1em #213679,2em 2em 0 -1em #213679,0 3em 0 0 #213679,-2em 2em 0 .2em #213679,-3em 0 0 0 #213679,-2em -2em 0 -1em #213679}75%{box-shadow:0 -3em 0 -1em #213679,2em -2em 0 -1em #213679,3em 0 0 -1em #213679,2em 2em 0 -1em #213679,0 3em 0 -1em #213679,-2em 2em 0 0 #213679,-3em 0 0 .2em #213679,-2em -2em 0 0 #213679} 5 | 87.5%{box-shadow:0 -3em 0 0 #213679,2em -2em 0 -1em #213679,3em 0 0 -1em #213679,2em 2em 0 -1em #213679,0 3em 0 -1em #213679,-2em 2em 0 0 #213679,-3em 0 0 0 #213679,-2em -2em 0 .2em #213679}}@keyframes load4{0%,100%{box-shadow:0 -3em 0 .2em #213679,2em -2em 0 0 #213679,3em 0 0 -1em #213679,2em 2em 0 -1em #213679,0 3em 0 -1em #213679,-2em 2em 0 -1em #213679,-3em 0 0 -1em #213679,-2em -2em 0 0 #213679}12.5%{box-shadow:0 -3em 0 0 #213679,2em -2em 0 .2em #213679,3em 0 0 0 #213679,2em 2em 0 -1em #213679,0 3em 0 -1em #213679,-2em 2em 0 -1em #213679,-3em 0 0 -1em #213679,-2em -2em 0 -1em #213679} 6 | 25%{box-shadow:0 -3em 0 -0.5em #213679,2em -2em 0 0 #213679,3em 0 0 .2em #213679,2em 2em 0 0 #213679,0 3em 0 -1em #213679,-2em 2em 0 -1em #213679,-3em 0 0 -1em #213679,-2em -2em 0 -1em #213679}37.5%{box-shadow:0 -3em 0 -1em #213679,2em -2em 0 -1em #213679,3em 0 0 0 #213679,2em 2em 0 .2em #213679,0 3em 0 0 #213679,-2em 2em 0 -1em #213679,-3em 0 0 -1em #213679,-2em -2em 0 -1em #213679}50%{box-shadow:0 -3em 0 -1em #213679,2em -2em 0 -1em #213679,3em 0 0 -1em #213679,2em 2em 0 0 #213679,0 3em 0 .2em #213679,-2em 2em 0 0 #213679,-3em 0 0 -1em #213679,-2em -2em 0 -1em #213679} 7 | 62.5%{box-shadow:0 -3em 0 -1em #213679,2em -2em 0 -1em #213679,3em 0 0 -1em #213679,2em 2em 0 -1em #213679,0 3em 0 0 #213679,-2em 2em 0 .2em #213679,-3em 0 0 0 #213679,-2em -2em 0 -1em #213679}75%{box-shadow:0 -3em 0 -1em #213679,2em -2em 0 -1em #213679,3em 0 0 -1em #213679,2em 2em 0 -1em #213679,0 3em 0 -1em #213679,-2em 2em 0 0 #213679,-3em 0 0 .2em #213679,-2em -2em 0 0 #213679}87.5%{box-shadow:0 -3em 0 0 #213679,2em -2em 0 -1em #213679,3em 0 0 -1em #213679,2em 2em 0 -1em #213679,0 3em 0 -1em #213679,-2em 2em 0 0 #213679,-3em 0 0 0 #213679,-2em -2em 0 .2em #213679} 8 | } -------------------------------------------------------------------------------- /client/assets/styles.css: -------------------------------------------------------------------------------- 1 | .splash { 2 | text-align: center; 3 | margin: 10% 0 0 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | .splash .message { 8 | font-size: 72px; 9 | line-height: 72px; 10 | text-shadow: rgba(0, 0, 0, 0.5) 0 0 15px; 11 | text-transform: uppercase; 12 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 13 | } 14 | 15 | .splash .fa-spinner { 16 | text-align: center; 17 | display: inline-block; 18 | font-size: 72px; 19 | margin-top: 50px; 20 | } 21 | 22 | .page-host { 23 | position: absolute; 24 | left: 0; 25 | right: 0; 26 | top: 56px; 27 | bottom: 0; 28 | overflow-x: hidden; 29 | overflow-y: auto; 30 | } 31 | 32 | section { 33 | margin: 0 20px; 34 | } 35 | 36 | .navbar-nav li.loader { 37 | margin: 12px 24px 0 6px; 38 | } 39 | 40 | .pictureDetail { 41 | max-width: 425px; 42 | } 43 | 44 | /* animate page transitions */ 45 | section.au-enter-active { 46 | animation: fadeInRight 1s; 47 | } 48 | 49 | div.au-stagger { 50 | /* 50ms will be applied between each successive enter operation */ 51 | animation-delay: 50ms; 52 | } 53 | 54 | .card-container.au-enter { 55 | opacity: 0 !important; 56 | } 57 | 58 | .card-container.au-enter-active { 59 | animation: fadeIn 2s; 60 | } 61 | 62 | .card { 63 | overflow: hidden; 64 | position: relative; 65 | border: 1px solid #CCC; 66 | border-radius: 8px; 67 | text-align: center; 68 | padding: 0; 69 | background-color: #337ab7; 70 | color: rgb(136, 172, 217); 71 | margin-bottom: 32px; 72 | box-shadow: 0 0 5px rgba(0, 0, 0, .5); 73 | } 74 | 75 | .card .content { 76 | margin-top: 10px; 77 | } 78 | 79 | .card .content .name { 80 | color: white; 81 | text-shadow: 0 0 6px rgba(0, 0, 0, .5); 82 | font-size: 18px; 83 | } 84 | 85 | .card .header-bg { 86 | /* This stretches the canvas across the entire hero unit */ 87 | position: absolute; 88 | top: 0; 89 | left: 0; 90 | width: 100%; 91 | height: 70px; 92 | border-bottom: 1px #FFF solid; 93 | border-radius: 6px 6px 0 0; 94 | } 95 | 96 | .card .avatar { 97 | position: relative; 98 | margin-top: 15px; 99 | z-index: 100; 100 | } 101 | 102 | .card .avatar img { 103 | width: 100px; 104 | height: 100px; 105 | border-radius: 50%; 106 | border: 2px #FFF solid; 107 | } 108 | 109 | /* animation definitions */ 110 | @-webkit-keyframes fadeInRight { 111 | 0% { 112 | opacity: 0; 113 | transform: translate3d(100%, 0, 0) 114 | } 115 | 100% { 116 | opacity: 1; 117 | transform: none 118 | } 119 | } 120 | 121 | @keyframes fadeInRight { 122 | 0% { 123 | opacity: 0; 124 | transform: translate3d(100%, 0, 0) 125 | } 126 | 100% { 127 | opacity: 1; 128 | transform: none 129 | } 130 | } 131 | 132 | @-webkit-keyframes fadeIn { 133 | 0% { 134 | opacity: 0; 135 | } 136 | 100% { 137 | opacity: 1; 138 | } 139 | } 140 | 141 | @keyframes fadeIn { 142 | 0% { 143 | opacity: 0; 144 | } 145 | 100% { 146 | opacity: 1; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /client/aurelia_project/aurelia.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aurelia-nest-mongo-graphql", 3 | "type": "project:application", 4 | "paths": { 5 | "root": "src", 6 | "resources": "resources", 7 | "elements": "resources/elements", 8 | "attributes": "resources/attributes", 9 | "valueConverters": "resources/value-converters", 10 | "bindingBehaviors": "resources/binding-behaviors" 11 | }, 12 | "transpiler": { 13 | "id": "typescript", 14 | "fileExtension": ".ts" 15 | }, 16 | "build": { 17 | "options": { 18 | "server": "dev", 19 | "extractCss": "prod", 20 | "coverage": false 21 | } 22 | }, 23 | "platform": { 24 | "compress": true, 25 | "liveReload": true, 26 | "historyApiFallback": true, 27 | "hmr": false, 28 | "open": true, 29 | "port": 9000, 30 | "host": "localhost", 31 | "output": "dist", 32 | "outputProd": "dist" 33 | }, 34 | "packageManager": "yarn" 35 | } 36 | -------------------------------------------------------------------------------- /client/aurelia_project/generators/attribute.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "attribute", 3 | "description": "Creates a custom attribute class and places it in the project resources." 4 | } -------------------------------------------------------------------------------- /client/aurelia_project/generators/attribute.ts: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli'; 3 | 4 | @inject(Project, CLIOptions, UI) 5 | export default class AttributeGenerator { 6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { } 7 | 8 | async execute() { 9 | const name = await this.ui.ensureAnswer( 10 | this.options.args[0], 11 | 'What would you like to call the custom attribute?' 12 | ); 13 | 14 | let fileName = this.project.makeFileName(name); 15 | let className = this.project.makeClassName(name); 16 | 17 | this.project.attributes.add( 18 | ProjectItem.text(`${fileName}.ts`, this.generateSource(className)) 19 | ); 20 | 21 | await this.project.commitChanges(); 22 | await this.ui.log(`Created ${fileName}.`); 23 | } 24 | 25 | generateSource(className) { 26 | return `import {autoinject} from 'aurelia-framework'; 27 | 28 | @autoinject() 29 | export class ${className}CustomAttribute { 30 | constructor(private element: Element) { } 31 | 32 | valueChanged(newValue, oldValue) { 33 | // 34 | } 35 | } 36 | `; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /client/aurelia_project/generators/binding-behavior.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "binding-behavior", 3 | "description": "Creates a binding behavior class and places it in the project resources." 4 | } -------------------------------------------------------------------------------- /client/aurelia_project/generators/binding-behavior.ts: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli'; 3 | 4 | @inject(Project, CLIOptions, UI) 5 | export default class BindingBehaviorGenerator { 6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { } 7 | 8 | async execute() { 9 | const name = await this.ui.ensureAnswer( 10 | this.options.args[0], 11 | 'What would you like to call the binding behavior?' 12 | ); 13 | 14 | let fileName = this.project.makeFileName(name); 15 | let className = this.project.makeClassName(name); 16 | 17 | this.project.bindingBehaviors.add( 18 | ProjectItem.text(`${fileName}.ts`, this.generateSource(className)) 19 | ); 20 | 21 | await this.project.commitChanges(); 22 | await this.ui.log(`Created ${fileName}.`); 23 | } 24 | 25 | generateSource(className) { 26 | return `export class ${className}BindingBehavior { 27 | bind(binding, source) { 28 | // 29 | } 30 | 31 | unbind(binding, source) { 32 | // 33 | } 34 | } 35 | ` 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /client/aurelia_project/generators/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "component", 3 | "description": "Creates a custom component class and template (view model and view), placing them in the project source folder (or optionally in sub folders)." 4 | } -------------------------------------------------------------------------------- /client/aurelia_project/generators/component.ts: -------------------------------------------------------------------------------- 1 | import { inject } from 'aurelia-dependency-injection'; 2 | import { Project, ProjectItem, CLIOptions, UI } from 'aurelia-cli'; 3 | 4 | var path = require('path'); 5 | 6 | @inject(Project, CLIOptions, UI) 7 | export default class ElementGenerator { 8 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { } 9 | 10 | async execute() { 11 | const name = await this.ui.ensureAnswer( 12 | this.options.args[0], 13 | 'What would you like to call the component?' 14 | ); 15 | 16 | const subFolders = await this.ui.ensureAnswer( 17 | this.options.args[1], 18 | 'What sub-folder would you like to add it to?\nIf it doesn\'t exist it will be created for you.\n\nDefault folder is the source folder (src).', "." 19 | ); 20 | 21 | let fileName = this.project.makeFileName(name); 22 | let className = this.project.makeClassName(name); 23 | 24 | this.project.root.add( 25 | ProjectItem.text(path.join(subFolders, fileName + '.ts'), this.generateJSSource(className)), 26 | ProjectItem.text(path.join(subFolders, fileName + '.html'), this.generateHTMLSource(className)) 27 | ); 28 | 29 | await this.project.commitChanges(); 30 | await this.ui.log(`Created ${name} in the '${path.join(this.project.root.name, subFolders)}' folder`); 31 | } 32 | 33 | generateJSSource(className) { 34 | return `export class ${className} { 35 | message: string; 36 | 37 | constructor() { 38 | this.message = 'Hello world'; 39 | } 40 | } 41 | ` 42 | } 43 | 44 | generateHTMLSource(className) { 45 | return ` 46 | \${message} 47 | 48 | ` 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /client/aurelia_project/generators/element.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element", 3 | "description": "Creates a custom element class and template, placing them in the project resources." 4 | } -------------------------------------------------------------------------------- /client/aurelia_project/generators/element.ts: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli'; 3 | 4 | @inject(Project, CLIOptions, UI) 5 | export default class ElementGenerator { 6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { } 7 | 8 | async execute() { 9 | const name = await this.ui.ensureAnswer( 10 | this.options.args[0], 11 | 'What would you like to call the custom element?' 12 | ); 13 | 14 | let fileName = this.project.makeFileName(name); 15 | let className = this.project.makeClassName(name); 16 | 17 | this.project.elements.add( 18 | ProjectItem.text(`${fileName}.ts`, this.generateJSSource(className)), 19 | ProjectItem.text(`${fileName}.html`, this.generateHTMLSource(className)) 20 | ); 21 | 22 | await this.project.commitChanges(); 23 | await this.ui.log(`Created ${fileName}.`); 24 | } 25 | 26 | generateJSSource(className) { 27 | return `import {bindable} from 'aurelia-framework'; 28 | 29 | export class ${className} { 30 | @bindable value; 31 | 32 | valueChanged(newValue, oldValue) { 33 | // 34 | } 35 | } 36 | `; 37 | } 38 | 39 | generateHTMLSource(className) { 40 | return ` 41 | \${value} 42 | 43 | `; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /client/aurelia_project/generators/generator.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator", 3 | "description": "Creates a generator class and places it in the project generators folder." 4 | } -------------------------------------------------------------------------------- /client/aurelia_project/generators/generator.ts: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli'; 3 | 4 | @inject(Project, CLIOptions, UI) 5 | export default class GeneratorGenerator { 6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { } 7 | 8 | async execute() { 9 | const name = await this.ui.ensureAnswer( 10 | this.options.args[0], 11 | 'What would you like to call the generator?' 12 | ); 13 | 14 | let fileName = this.project.makeFileName(name); 15 | let className = this.project.makeClassName(name); 16 | 17 | this.project.generators.add( 18 | ProjectItem.text(`${fileName}.ts`, this.generateSource(className)) 19 | ); 20 | 21 | await this.project.commitChanges() 22 | await this.ui.log(`Created ${fileName}.`); 23 | } 24 | 25 | generateSource(className) { 26 | return `import {inject} from 'aurelia-dependency-injection'; 27 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli'; 28 | 29 | @inject(Project, CLIOptions, UI) 30 | export default class ${className}Generator { 31 | constructor(project, options, ui) { 32 | this.project = project; 33 | this.options = options; 34 | this.ui = ui; 35 | } 36 | 37 | execute() { 38 | return this.ui 39 | .ensureAnswer(this.options.args[0], 'What would you like to call the new item?') 40 | .then(name => { 41 | let fileName = this.project.makeFileName(name); 42 | let className = this.project.makeClassName(name); 43 | 44 | this.project.elements.add( 45 | ProjectItem.text(\`\${fileName}.ts\`, this.generateSource(className)) 46 | ); 47 | 48 | return this.project.commitChanges() 49 | .then(() => this.ui.log(\`Created \${fileName}.\`)); 50 | }); 51 | } 52 | 53 | generateSource(className) { 54 | return \`import {bindable} from 'aurelia-framework'; 55 | 56 | export class \${className} { 57 | @bindable value; 58 | 59 | valueChanged(newValue, oldValue) { 60 | // 61 | } 62 | } 63 | \` 64 | } 65 | } 66 | `; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /client/aurelia_project/generators/task.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "task", 3 | "description": "Creates a task and places it in the project tasks folder." 4 | } -------------------------------------------------------------------------------- /client/aurelia_project/generators/task.ts: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli'; 3 | 4 | @inject(Project, CLIOptions, UI) 5 | export default class TaskGenerator { 6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { } 7 | 8 | async execute() { 9 | const name = await this.ui.ensureAnswer( 10 | this.options.args[0], 11 | 'What would you like to call the task?' 12 | ); 13 | 14 | let fileName = this.project.makeFileName(name); 15 | let functionName = this.project.makeFunctionName(name); 16 | 17 | this.project.tasks.add( 18 | ProjectItem.text(`${fileName}.ts`, this.generateSource(functionName)) 19 | ); 20 | 21 | await this.project.commitChanges(); 22 | await this.ui.log(`Created ${fileName}.`); 23 | } 24 | 25 | generateSource(functionName) { 26 | return `import * as gulp from 'gulp'; 27 | import * as project from '../aurelia.json'; 28 | 29 | export default function ${functionName}() { 30 | return gulp.src(project.paths.???) 31 | .pipe(gulp.dest(project.paths.output)); 32 | } 33 | `; 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /client/aurelia_project/generators/value-converter.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "value-converter", 3 | "description": "Creates a value converter class and places it in the project resources." 4 | } -------------------------------------------------------------------------------- /client/aurelia_project/generators/value-converter.ts: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli'; 3 | 4 | @inject(Project, CLIOptions, UI) 5 | export default class ValueConverterGenerator { 6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { } 7 | 8 | async execute() { 9 | const name = await this.ui.ensureAnswer( 10 | this.options.args[0], 11 | 'What would you like to call the value converter?' 12 | ); 13 | 14 | let fileName = this.project.makeFileName(name); 15 | let className = this.project.makeClassName(name); 16 | 17 | this.project.valueConverters.add( 18 | ProjectItem.text(`${fileName}.ts`, this.generateSource(className)) 19 | ); 20 | 21 | await this.project.commitChanges(); 22 | await this.ui.log(`Created ${fileName}.`); 23 | } 24 | 25 | generateSource(className) { 26 | return `export class ${className}ValueConverter { 27 | toView(value) { 28 | // 29 | } 30 | 31 | fromView(value) { 32 | // 33 | } 34 | } 35 | `; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /client/aurelia_project/tasks/build.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build", 3 | "description": "Builds and processes all application assets. It is an alias of the `npm run build:dev`, you may use either of those; see README for more details.", 4 | "flags": [ 5 | { 6 | "name": "analyze", 7 | "description": "Enable Webpack Bundle Analyzer. Typically paired with --env prod", 8 | "type": "boolean" 9 | }, 10 | { 11 | "name": "env", 12 | "description": "Sets the build environment.", 13 | "type": "string" 14 | }, 15 | { 16 | "name": "watch", 17 | "description": "Watches source files for changes and refreshes the bundles automatically.", 18 | "type": "boolean" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /client/aurelia_project/tasks/build.ts: -------------------------------------------------------------------------------- 1 | import { NPM } from 'aurelia-cli'; 2 | 3 | export default function() { 4 | console.log('`au build` is an alias of the `npm run build:dev`, you may use either of those; see README for more details.'); 5 | const args = process.argv.slice(3); 6 | return (new NPM()).run('run', ['build:dev', '--', ... cleanArgs(args)]); 7 | } 8 | 9 | // Cleanup --env prod to --env.production 10 | // for backwards compatibility 11 | function cleanArgs(args) { 12 | const cleaned = []; 13 | for (let i = 0, ii = args.length; i < ii; i++) { 14 | if (args[i] === '--env' && i < ii - 1) { 15 | const env = args[++i].toLowerCase(); 16 | if (env.startsWith('prod')) { 17 | cleaned.push('--env.production'); 18 | } else if (env.startsWith('test')) { 19 | cleaned.push('--tests'); 20 | } 21 | } else { 22 | cleaned.push(args[i]); 23 | } 24 | } 25 | return cleaned; 26 | } 27 | -------------------------------------------------------------------------------- /client/aurelia_project/tasks/jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest", 3 | "description": "Runs Jest and reports the results.", 4 | "flags": [ 5 | { 6 | "name": "watch", 7 | "description": "Watches test files for changes and re-runs the tests automatically.", 8 | "type": "boolean" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /client/aurelia_project/tasks/jest.ts: -------------------------------------------------------------------------------- 1 | export {default} from './test'; 2 | -------------------------------------------------------------------------------- /client/aurelia_project/tasks/run.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "run", 3 | "description": "Builds the application and serves up the assets via a local web server, watching files for changes as you work. It is an alias of the `npm start`, you may use either of those; see README for more details.", 4 | "flags": [ 5 | { 6 | "name": "analyze", 7 | "description": "Enable Webpack Bundle Analyzer. Typically paired with --env prod", 8 | "type": "boolean" 9 | }, 10 | { 11 | "name": "env", 12 | "description": "Sets the build environment.", 13 | "type": "string" 14 | }, 15 | { 16 | "name": "hmr", 17 | "description": "Enable Hot Module Reload", 18 | "type": "boolean" 19 | }, 20 | { 21 | "name": "port", 22 | "description": "Set port number of the dev server", 23 | "type": "string" 24 | }, 25 | { 26 | "name": "host", 27 | "description": "Set host address of the dev server, the accessible URL", 28 | "type": "string" 29 | }, 30 | { 31 | "name": "open", 32 | "description": "Open the default browser at the application location.", 33 | "type": "boolean" 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /client/aurelia_project/tasks/run.ts: -------------------------------------------------------------------------------- 1 | import { NPM } from 'aurelia-cli'; 2 | import * as kill from 'tree-kill'; 3 | 4 | const npm = new NPM(); 5 | 6 | function run() { 7 | console.log('`au run` is an alias of the `npm start`, you may use either of those; see README for more details.'); 8 | const args = process.argv.slice(3); 9 | return npm.run('start', ['--', ... cleanArgs(args)]); 10 | } 11 | 12 | // Cleanup --env prod to --env.production 13 | // for backwards compatibility 14 | function cleanArgs(args) { 15 | const cleaned = []; 16 | for (let i = 0, ii = args.length; i < ii; i++) { 17 | if (args[i] === '--env' && i < ii - 1) { 18 | const env = args[++i].toLowerCase(); 19 | if (env.startsWith('prod')) { 20 | cleaned.push('--env.production'); 21 | } else if (env.startsWith('test')) { 22 | cleaned.push('--tests'); 23 | } 24 | } else { 25 | cleaned.push(args[i]); 26 | } 27 | } 28 | return cleaned; 29 | } 30 | 31 | const shutdownAppServer = () => { 32 | if (npm && npm.proc) { 33 | kill(npm.proc.pid); 34 | } 35 | }; 36 | 37 | export { run as default, shutdownAppServer }; 38 | -------------------------------------------------------------------------------- /client/aurelia_project/tasks/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "description": "Runs Jest and reports the results.", 4 | "flags": [ 5 | { 6 | "name": "watch", 7 | "description": "Watches test files for changes and re-runs the tests automatically.", 8 | "type": "boolean" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /client/aurelia_project/tasks/test.ts: -------------------------------------------------------------------------------- 1 | import * as jest from 'jest-cli'; 2 | import * as path from 'path'; 3 | import * as packageJson from '../../package.json'; 4 | 5 | import { CLIOptions } from 'aurelia-cli'; 6 | 7 | export default (cb) => { 8 | let options = packageJson.jest; 9 | 10 | if (CLIOptions.hasFlag('watch')) { 11 | Object.assign(options, { watchAll: true}); 12 | } 13 | 14 | 15 | jest.runCLI(options, [path.resolve(__dirname, '../../')]).then(({ results }) => { 16 | if (results.numFailedTests || results.numFailedTestSuites) { 17 | cb('Tests Failed'); 18 | } else { 19 | cb(); 20 | } 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /client/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | baseUrl: 'http://localhost:9000/', 3 | webUiPort: 9000, 4 | webApiPort: 3000 5 | } 6 | -------------------------------------------------------------------------------- /client/config/environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true, 3 | "testing": true 4 | } -------------------------------------------------------------------------------- /client/config/environment.production.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": false, 3 | "testing": false 4 | } -------------------------------------------------------------------------------- /client/custom_typings/fetch.d.ts: -------------------------------------------------------------------------------- 1 | declare module "isomorphic-fetch" { 2 | export = fetch; 3 | } 4 | -------------------------------------------------------------------------------- /client/custom_typings/system.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'system' { 2 | import fetch = require('isomorphic-fetch'); 3 | import * as Aurelia from 'aurelia-framework'; 4 | 5 | /* 6 | * List your dynamically imported modules to get typing support 7 | */ 8 | interface System { 9 | import(name: string): Promise; 10 | import(name: 'aurelia-framework'): Promise; 11 | import(name: 'isomorphic-fetch'): Promise; 12 | } 13 | 14 | global { 15 | var System: System; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /client/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%- htmlWebpackPlugin.options.metadata.title %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | <%- htmlWebpackPlugin.options.metadata.title %> 20 | 21 | 22 | 23 | <% if (htmlWebpackPlugin.options.metadata.server) { %> 24 | 25 | 26 | <% } %> 27 | 28 | 31 | 32 | 33 |