├── .gitignore ├── README.md ├── client ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ ├── Validator.vue │ ├── boolean │ │ └── boolean.vue │ ├── dateTime │ │ └── dateTime.vue │ ├── number │ │ └── number.vue │ └── string │ │ └── string.vue │ ├── main.js │ ├── router │ └── index.js │ ├── store │ ├── actions.js │ ├── boolean │ │ └── index.js │ ├── dateTime │ │ └── index.js │ ├── getters.js │ ├── index.js │ ├── modules.js │ ├── mutations.js │ ├── number │ │ └── index.js │ ├── state.js │ └── string │ │ └── index.js │ └── views │ ├── About.vue │ └── Home.vue └── server ├── Configurations ├── ApiRouting.cs ├── Authentication.cs ├── Database.cs ├── Logging.cs ├── Parsing.cs ├── ServiceRegistrar.cs └── SpaRouting.cs ├── Controllers ├── ValidatorController.cs └── ValuesController.cs ├── Helpers ├── AsyncResult.cs ├── Errors │ ├── Error.cs │ ├── ErrorCodes.cs │ ├── ErrorException.cs │ └── ErrorObjectResult.cs ├── IAsyncResult.cs ├── Paging.cs ├── RouteController.cs ├── Secrets.cs ├── StartupConfig.cs └── Validation │ ├── BoolProperty.cs │ ├── DateTimeProperty.cs │ ├── DoubleProperty.cs │ ├── IntProperty.cs │ ├── ObjectProperty.cs │ ├── Property.cs │ ├── Result.cs │ ├── StringProperty.cs │ ├── TimeSpanProperty.cs │ └── Validator.cs ├── Program.cs ├── Properties └── launchSettings.json ├── README.md ├── Startup.cs ├── appsettings.Development.json ├── appsettings.json ├── bin └── Debug │ └── netcoreapp2.2 │ ├── server.deps.json │ ├── server.dll │ ├── server.pdb │ ├── server.runtimeconfig.dev.json │ └── server.runtimeconfig.json ├── obj ├── Debug │ └── netcoreapp2.2 │ │ ├── server.AssemblyInfo.cs │ │ ├── server.AssemblyInfoInputs.cache │ │ ├── server.RazorAssemblyInfo.cache │ │ ├── server.RazorAssemblyInfo.cs │ │ ├── server.RazorTargetAssemblyInfo.cache │ │ ├── server.assets.cache │ │ ├── server.csproj.CoreCompileInputs.cache │ │ ├── server.csproj.FileListAbsolute.txt │ │ ├── server.csprojAssemblyReference.cache │ │ ├── server.dll │ │ └── server.pdb ├── project.assets.json ├── server.csproj.nuget.cache ├── server.csproj.nuget.g.props └── server.csproj.nuget.g.targets ├── server.csproj └── wwwroot ├── css ├── app.20847301.css └── chunk-vendors.df973d85.css ├── favicon.ico ├── img └── logo.82b9c7a5.png ├── index.html └── js ├── about.46ca718d.js ├── about.46ca718d.js.map ├── app.94ec2a54.js ├── app.94ec2a54.js.map ├── chunk-vendors.5126bf34.js └── chunk-vendors.5126bf34.js.map /.gitignore: -------------------------------------------------------------------------------- 1 | # External Project Modules 2 | # 3 | 4 | # VSCode 5 | # 6 | **/.vscode 7 | 8 | # Visual Studio 9 | # 10 | **/.vs 11 | 12 | # Output Dirs 13 | # 14 | **/build/ 15 | **/bld/ 16 | **/[Bb]in/ 17 | **/[Oo]bj/ 18 | **/[Oo]ut/ 19 | **/dist/ 20 | 21 | 22 | # node.js 23 | # 24 | client/node_modules/ 25 | **/*.log 26 | **/*.log 27 | **/.npm 28 | **/.eslintcache 29 | **/*.tgz 30 | **/.yarn-integrity 31 | **/.env 32 | **/.cache 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ASP.NET Core & VueJS Starter Kit 2 | A *decoupled* and *light-weight* starter kit template for ASP.NET core 2.2 and VueJS 2.6. 3 | Includes custom property validator on server side, decoupled state management for Vuex 4 | Webpack(Hot Module Replacement). 5 | 6 | # Features 7 | * ASP.NET Core 2.2 8 | * Web API 9 | * Custom property validator 10 | *number* *string* *boolean* *datetime* *object* 11 | * Custom api routing, and exception 12 | * Custom validation error result 13 | * JWT authencation service configuration 14 | * VueJS 2 15 | * Vuex *modular state management, store* 16 | * Webpack *(Hot Module Replacement)* 17 | * Boostrap 4 18 | 19 | # Requirements 20 | * .NET Core 2.2 21 | * VSCode 22 | * NodeJS V11 23 | 24 | # Running the application: 25 | 1. Server 26 | Command line: 27 | * *dotnet run* or *dotnet watch run* 28 | 2. Client 29 | Command line: 30 | * *npm install* to install dependencies(once), *npm run serve* to run the application. 31 | 32 | ## Please make a donate if you like it. :blush: 33 | **KBANK QR Code:** 34 | 35 | ![KBANK](https://i.imgur.com/jYtO74p.jpg) 36 | 37 | # Want to Contribute? 38 | Ever tired of getting bugs yet too difficult to solve? Worry no more, create an issue (just make sure it isn’t an existing one) and i will do my best to fix it. Great ideas are welcome too; just make an issue with the Proposal or a PR from your Fork. 39 | 40 | --- 41 | #### Looking for a asynchronous modular micro-framework [Reser](https://github.com/rhaldkhein/reser) by [RhaldKhein](https://github.com/rhaldkhein/) 42 | --- 43 | 44 | # License 45 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 46 | Copyright (c) 2019 [Joever Monceda](https://github.com/Ethan0007) 47 | 48 | 49 | Linkedin: [Joever Monceda](https://www.linkedin.com/in/joever-monceda-55242779/) 50 | Medium: [Joever Monceda](https://medium.com/@joever.monceda/new-net-core-vuejs-vuex-router-webpack-starter-kit-e94b6fdb7481) 51 | Twitter [@_EthanHunt07](https://twitter.com/_EthanHunt07) 52 | Facebook: [Ethan Hunt](https://m.facebook.com/groups/215192935559397?view=permalink&id=688430418235644) 53 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | # client 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | 31 | # server 32 | 33 | ### Run your server 34 | ``` 35 | dotnet watch run 36 | ``` 37 | -------------------------------------------------------------------------------- /client/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "axios": "^0.19.0", 11 | "bootstrap": "^4.3.1", 12 | "core-js": "^2.6.5", 13 | "jquery": "^3.4.1", 14 | "popper.js": "^1.15.0", 15 | "vue": "^2.6.10", 16 | "vue-router": "^3.0.3", 17 | "vuex": "^3.0.1" 18 | }, 19 | "devDependencies": { 20 | "@vue/cli-plugin-babel": "^3.8.0", 21 | "@vue/cli-service": "^3.8.0", 22 | "vue-template-compiler": "^2.6.10" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | client 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /client/src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 32 | -------------------------------------------------------------------------------- /client/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/client/src/assets/logo.png -------------------------------------------------------------------------------- /client/src/components/Validator.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 67 | 68 | 69 | 71 | 72 | -------------------------------------------------------------------------------- /client/src/components/boolean/boolean.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 41 | -------------------------------------------------------------------------------- /client/src/components/dateTime/dateTime.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 39 | -------------------------------------------------------------------------------- /client/src/components/number/number.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /client/src/components/string/string.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 30 | 64 | -------------------------------------------------------------------------------- /client/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router/index' 4 | import {store} from './store/index' 5 | import 'bootstrap' 6 | import 'bootstrap/dist/css/bootstrap.min.css' 7 | import axios from 'axios'; 8 | 9 | axios.defaults.baseURL = 'http://localhost:5001/api/'; 10 | Vue.config.productionTip = false 11 | 12 | new Vue({ 13 | router, 14 | store, 15 | render: h => h(App) 16 | }).$mount('#app') 17 | -------------------------------------------------------------------------------- /client/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Home from '../views/Home.vue' 4 | 5 | Vue.use(Router) 6 | 7 | export default new Router({ 8 | mode: 'history', 9 | base: process.env.BASE_URL, 10 | routes: [ 11 | { 12 | path: '/', 13 | name: 'home', 14 | component: Home 15 | }, 16 | { 17 | path: '/about', 18 | name: 'about', 19 | // route level code-splitting 20 | // this generates a separate chunk (about.[hash].js) for this route 21 | // which is lazy-loaded when the route is visited. 22 | component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') 23 | } 24 | ] 25 | }) 26 | -------------------------------------------------------------------------------- /client/src/store/actions.js: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /client/src/store/boolean/index.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export default { 4 | namespaced: true, 5 | state: { 6 | booleanValErrors: null 7 | }, 8 | 9 | mutations: { 10 | booleanValErrors: function(state, payload) { 11 | state.booleanValErrors = payload.Message; 12 | } 13 | }, 14 | 15 | //Note: Its not a good practice to commit errors in catch callback, 16 | //this is just for a demo purposes of using vuex with validation errors from server. 17 | actions: { 18 | validateBoolean: async function({ commit }, params) { 19 | axios 20 | .post("validator/isBool", params) 21 | .then(commit("booleanValErrors", {})) 22 | .catch(err => { 23 | commit("booleanValErrors", err.response.data.payload); 24 | }); 25 | } 26 | }, 27 | modules: {} 28 | }; 29 | -------------------------------------------------------------------------------- /client/src/store/dateTime/index.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export default { 4 | namespaced: true, 5 | state: { 6 | dateTimeValErrors: null 7 | }, 8 | 9 | mutations: { 10 | dateTimeValErrors: function(state, payload) { 11 | state.dateTimeValErrors = payload.Message; 12 | } 13 | }, 14 | 15 | //Note: Its not a good practice to commit errors in catch callback, 16 | //this is just for a demo purposes of using vuex with validation errors from server. 17 | actions: { 18 | validateDateTime: async function({ commit }, params) { 19 | axios 20 | .post("validator/isDateTime", params) 21 | .then(commit("dateTimeValErrors", {})) 22 | .catch(err => { 23 | commit("dateTimeValErrors", err.response.data.payload); 24 | }); 25 | } 26 | }, 27 | modules: {} 28 | }; 29 | -------------------------------------------------------------------------------- /client/src/store/getters.js: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /client/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | import state from './state'; 4 | import getters from './getters'; 5 | import mutations from './mutations'; 6 | import actions from './actions'; 7 | import modules from './modules'; 8 | 9 | 10 | Vue.use(Vuex); 11 | 12 | export const store = new Vuex.Store({ 13 | state, 14 | getters, 15 | mutations, 16 | actions, 17 | modules 18 | }) 19 | 20 | -------------------------------------------------------------------------------- /client/src/store/modules.js: -------------------------------------------------------------------------------- 1 | import stringValidator from './string/index'; 2 | import numberValidator from './number/index'; 3 | import booleanValidator from './boolean/index'; 4 | import dateTimeValidator from './dateTime/index'; 5 | 6 | export default { 7 | stringValidator, 8 | numberValidator, 9 | booleanValidator, 10 | dateTimeValidator 11 | } 12 | -------------------------------------------------------------------------------- /client/src/store/mutations.js: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /client/src/store/number/index.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export default { 4 | namespaced: true, 5 | state: { 6 | numberValErrors: null 7 | }, 8 | 9 | mutations: { 10 | numberValErrors: function(state, payload) { 11 | state.numberValErrors = payload.Message; 12 | } 13 | }, 14 | 15 | //Note: Its not a good practice to commit errors in catch callback, 16 | //this is just for a demo purposes of using vuex with validation errors from server. 17 | actions: { 18 | validateNum: async function({ commit }, params) { 19 | axios 20 | .post("validator/isNumber", params) 21 | .then(commit("numberValErrors", {})) 22 | .catch(err => { 23 | commit("numberValErrors", err.response.data.payload); 24 | }); 25 | } 26 | }, 27 | modules: {} 28 | }; 29 | -------------------------------------------------------------------------------- /client/src/store/state.js: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /client/src/store/string/index.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export default { 4 | namespaced: true, 5 | state: { 6 | stringValErrors: { 7 | fnameError: null, 8 | lnameError: null 9 | } 10 | }, 11 | 12 | mutations: { 13 | stringValError: async function(state, data) { 14 | state.stringValErrors = {}; 15 | if (data.payload) { 16 | data.payload.map(item => { 17 | if (item.name == "firstName") 18 | state.stringValErrors.fnameError = `${item.name} ${item.errors[0]}`; 19 | if (item.name == "lastName") 20 | state.stringValErrors.lnameError = `${item.name} ${item.errors[0]}`; 21 | }); 22 | } 23 | } 24 | }, 25 | //Note: Its not a good practice to commit errors in catch callback, 26 | //this is just for a demo purposes of using vuex with validation errors from server. 27 | actions: { 28 | validateString: async function({ commit }, params) { 29 | axios 30 | .post("validator/isString", params) 31 | .then(() => { 32 | commit("stringValError", {}); 33 | }) 34 | .catch(err => { 35 | commit("stringValError", err.response.data); 36 | }); 37 | }, 38 | 39 | validateStringWithMaxMin: async function({ commit }, params) { 40 | axios 41 | .post("validator/IsStringWithMinMax", params) 42 | .then(() => { 43 | commit("stringValError", {}); 44 | }) 45 | .catch(err => commit("stringValError", err.response.data)); 46 | } 47 | }, 48 | modules: {} 49 | }; 50 | -------------------------------------------------------------------------------- /client/src/views/About.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /client/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 19 | -------------------------------------------------------------------------------- /server/Configurations/ApiRouting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using server.Helpers; 3 | using server.Helpers.Errors; 4 | using Microsoft.AspNetCore.Builder; 5 | using Microsoft.AspNetCore.Diagnostics; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Newtonsoft.Json; 11 | using Newtonsoft.Json.Serialization; 12 | 13 | 14 | namespace server.Configurations 15 | { 16 | public class ApiRouting : StartupConfig 17 | { 18 | 19 | public ApiRouting(IHostingEnvironment env, IConfiguration config) : base(env, config) { } 20 | 21 | public override IServiceProvider ConfigureServices(IServiceCollection services) 22 | { 23 | services.AddMvc().AddJsonOptions(options => 24 | { 25 | options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 26 | options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 27 | }); 28 | return null; 29 | } 30 | 31 | public override void Configure(IApplicationBuilder app) 32 | { 33 | 34 | // Global error handler for API 35 | app.UseWhen(http => http.Request.Path.StartsWithSegments("/api"), appApi => 36 | { 37 | var routeController = new RouteController(appApi.ApplicationServices); 38 | 39 | // Native error 40 | appApi.UseExceptionHandler(appB => 41 | { 42 | appB.Run(async http => 43 | { 44 | var exf = http.Features.Get(); 45 | System.Exception error = (exf != null) ? exf.Error : new ErrorException(); 46 | http.Response.ContentType = "application/json"; 47 | http.Response.Headers.Add("x-api-standard", "1"); 48 | await http.Response.WriteAsync( 49 | JsonConvert.SerializeObject( 50 | routeController.WrapError(error, error.Message) 51 | ) 52 | ); 53 | // Will log on file on production and console on development 54 | 55 | }); 56 | }); 57 | 58 | // Custom error 59 | appApi.UseStatusCodePages(async context => 60 | { 61 | context.HttpContext.Response.ContentType = "application/json"; 62 | Error error; 63 | switch (context.HttpContext.Response.StatusCode) 64 | { 65 | case 401: error = new Unauthorized(); break; 66 | case 404: error = new RouteNotFound(); break; 67 | case 403: error = new Forbidden(); break; 68 | default: error = new Error(); break; 69 | } 70 | context.HttpContext.Response.Headers.Add("x-api-standard", "1"); 71 | await context.HttpContext.Response.WriteAsync( 72 | JsonConvert.SerializeObject( 73 | routeController.WrapError(error, null) 74 | ) 75 | ); 76 | }); 77 | 78 | // Use MVC 79 | appApi.UseMvc(routes => 80 | { 81 | routes.MapRoute( 82 | name: "default", 83 | template: "{controller}/{action=Index}/{id?}"); 84 | }); 85 | 86 | // At this point status code must be already set by MVC 87 | // If not, respond with 404 Not Found 88 | appApi.Use(async (context, next) => 89 | { 90 | context.Response.ContentType = "application/json"; 91 | await context.Response.WriteAsync( 92 | JsonConvert.SerializeObject( 93 | routeController.WrapError(new RouteNotFound(), null) 94 | ) 95 | ); 96 | }); 97 | }); 98 | 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /server/Configurations/Authentication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IdentityModel.Tokens.Jwt; 3 | using System.Text; 4 | using server.Helpers; 5 | using Microsoft.AspNetCore.Authentication.JwtBearer; 6 | using Microsoft.AspNetCore.Builder; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.IdentityModel.Tokens; 11 | 12 | namespace server.Configurations 13 | { 14 | public class Authentication : StartupConfig 15 | { 16 | 17 | public Authentication(IHostingEnvironment env, IConfiguration config) : base(env, config) { } 18 | 19 | public override IServiceProvider ConfigureServices(IServiceCollection services) 20 | { 21 | 22 | JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();//clear default settings 23 | 24 | services.AddAuthentication(options => 25 | { 26 | options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 27 | options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; 28 | options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 29 | }).AddJwtBearer(cfg => 30 | { 31 | cfg.RequireHttpsMetadata = false; 32 | cfg.SaveToken = true; 33 | cfg.TokenValidationParameters = new TokenValidationParameters 34 | { 35 | ValidIssuer = Config["Issuer"], 36 | ValidAudience = Config["Audience"], 37 | IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Config["Key"])), 38 | ClockSkew = TimeSpan.Zero // remove delay of token when expire 39 | }; 40 | }); 41 | 42 | return null; 43 | } 44 | 45 | public override void Configure(IApplicationBuilder app) 46 | { 47 | app.UseAuthentication(); 48 | } 49 | 50 | } 51 | } -------------------------------------------------------------------------------- /server/Configurations/Database.cs: -------------------------------------------------------------------------------- 1 | namespace server.Configurations 2 | { 3 | public class Database 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /server/Configurations/Logging.cs: -------------------------------------------------------------------------------- 1 | namespace server.Configurations 2 | { 3 | public class Logging 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /server/Configurations/Parsing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using server.Helpers; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | 8 | namespace server.Configurations 9 | { 10 | public class Parsing : StartupConfig 11 | { 12 | 13 | public Parsing(IHostingEnvironment env, IConfiguration config) : base(env, config) { } 14 | 15 | public override IServiceProvider ConfigureServices(IServiceCollection services) 16 | { 17 | services.AddCors(); 18 | return null; 19 | } 20 | 21 | public override void Configure(IApplicationBuilder app) 22 | { 23 | 24 | app.UseCors(builder => 25 | { 26 | builder.WithOrigins(new string[] { "*" }) 27 | .AllowAnyHeader() 28 | .AllowAnyMethod() 29 | .AllowCredentials(); 30 | }); 31 | 32 | if (Env.IsDevelopment()) 33 | { 34 | app.UseDeveloperExceptionPage(); 35 | } 36 | else 37 | { 38 | app.UseExceptionHandler("/Error"); 39 | app.UseHsts(); 40 | } 41 | 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /server/Configurations/ServiceRegistrar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using server.Helpers; 3 | using Microsoft.AspNetCore.Hosting; 4 | using Microsoft.AspNetCore.Http; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | 8 | namespace server.Configurations 9 | { 10 | public class ServiceRegistrar : StartupConfig 11 | { 12 | public ServiceRegistrar(IHostingEnvironment env, IConfiguration config) : base(env, config) { } 13 | 14 | public override IServiceProvider ConfigureServices(IServiceCollection services) 15 | { 16 | 17 | // Hosting environment 18 | services.AddSingleton(Env); 19 | // Register all configuration to services 20 | services.AddSingleton(Config); 21 | services.AddSingleton(); 22 | 23 | return null; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /server/Configurations/SpaRouting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.AspNetCore.Mvc.Authorization; 8 | using Microsoft.AspNetCore.StaticFiles.Infrastructure; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.FileProviders; 12 | using server.Helpers; 13 | 14 | namespace server.Configurations 15 | { 16 | public class SpaRouting : StartupConfig 17 | { 18 | 19 | public SpaRouting(IHostingEnvironment env, IConfiguration config) : base(env, config) { } 20 | 21 | public override IServiceProvider ConfigureServices(IServiceCollection services) 22 | { 23 | 24 | services.AddSpaStaticFiles(configuration => 25 | { 26 | configuration.RootPath = "client/dist"; 27 | }); 28 | 29 | return null; 30 | } 31 | 32 | public override void Configure(IApplicationBuilder app) 33 | { 34 | 35 | app.UseStaticFiles(); 36 | app.UseSpaStaticFiles(); 37 | app.UseDefaultFiles(); 38 | 39 | app.UseSpa(spa => 40 | { 41 | if (Env.IsDevelopment()) 42 | { 43 | spa.Options.SourcePath = "wwwroot"; 44 | app.Run(async (context) => 45 | { 46 | context.Response.ContentType = "text/html"; 47 | await context.Response.SendFileAsync("wwwroot/index.html"); 48 | }); 49 | } 50 | else 51 | { 52 | spa.Options.SourcePath = "wwwroot"; 53 | app.Run(async (context) => 54 | { 55 | context.Response.ContentType = "text/html"; 56 | await context.Response.SendFileAsync(Path.Combine(Env.WebRootPath, "index.html")); 57 | }); 58 | } 59 | }); 60 | 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /server/Controllers/ValidatorController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using server.Helpers; 7 | using server.Helpers.Errors; 8 | using server.Helpers.Validation; 9 | using server.Configurations; 10 | 11 | 12 | namespace server.Controllers 13 | { 14 | // 15 | // Model for testing it can be modify according to user preferences 16 | // 17 | public class TestModel 18 | { 19 | public string FirstName { set; get; } 20 | public string LastName { set; get; } 21 | public int One { set; get; } 22 | public bool IsTrue { set; get; } 23 | public DateTime DateTime { set; get; } 24 | public object Object { set; get; } 25 | } 26 | 27 | [Route("api/[controller]")] 28 | public class ValidatorController : RouteController 29 | { 30 | // 31 | // String type validator. 32 | // Parameters: 33 | // property, property name , required(true/false) 34 | // 35 | [HttpPost("[action]")] 36 | public IActionResult IsString([FromBody]TestModel model) 37 | { 38 | var v = new Validator(); 39 | v.IsString(model.FirstName, "firstName", true); 40 | v.IsString(model.LastName, "lastName", true); 41 | if (v.ContainsError()) 42 | return Error(v.AsValidationError()); 43 | return Success(); 44 | } 45 | 46 | // 47 | // String type validator. 48 | // Parameters: 49 | // property, property name , required(true/false), min , max 50 | // 51 | [HttpPost("[action]")] 52 | public IActionResult IsStringWithMinMax([FromBody]TestModel model) 53 | { 54 | var v = new Validator(); 55 | v.IsString(model.FirstName, "firstName", true).Min(3).Max(10); 56 | v.IsString(model.LastName, "lastName", true).Min(5).Max(15); 57 | if (v.ContainsError()) 58 | return Error(v.AsValidationError()); 59 | return Success(); 60 | } 61 | 62 | // 63 | // Number type validator. 64 | // Parameters: 65 | // property, property name , required(true/false) 66 | // 67 | [HttpPost("[action]")] 68 | public IActionResult IsNumber([FromBody]TestModel model) 69 | { 70 | var v = new Validator(); 71 | v.IsNumber(model.One, "one", true); 72 | if (v.ContainsError()) 73 | return Error(v.AsValidationError()); 74 | return Success(); 75 | } 76 | 77 | // 78 | // Boolean type validator. 79 | // Parameters: 80 | // property, property name , required(true/false) 81 | // 82 | [HttpPost("[action]")] 83 | public IActionResult IsBool([FromBody]TestModel model) 84 | { 85 | var v = new Validator(); 86 | v.IsBool(model.IsTrue, "isTrue", true); 87 | if (v.ContainsError()) 88 | return Error(v.AsValidationError()); 89 | return Success(); 90 | } 91 | 92 | // 93 | // DateTime type validator. 94 | // Parameters: 95 | // property, property name , required(true/false) 96 | // 97 | [HttpPost("[action]")] 98 | public IActionResult IsDateTime([FromBody]TestModel model) 99 | { 100 | var v = new Validator(); 101 | v.IsDateTime(model.DateTime, "dateTime", true); 102 | if (v.ContainsError()) 103 | return Error(v.AsValidationError()); 104 | return Success(); 105 | } 106 | 107 | // 108 | // Object type validator. 109 | // Parameters: 110 | // property, property name , required(true/false) 111 | // 112 | [HttpPost("[action]")] 113 | public IActionResult IsObject([FromBody]TestModel model) 114 | { 115 | var v = new Validator(); 116 | v.IsObject(model.Object, "object", true); 117 | if (v.ContainsError()) 118 | return Error(v.AsValidationError()); 119 | return Success(); 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /server/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using server.Helpers; 7 | 8 | namespace server.Controllers 9 | { 10 | [Route("api/[controller]")] 11 | public class ValuesController : RouteController 12 | { 13 | // GET api/values 14 | [HttpGet] 15 | public ActionResult> Get() 16 | { 17 | return new string[] { "value1", "value2" }; 18 | } 19 | 20 | // GET api/values/5 21 | [HttpGet("{id}")] 22 | public ActionResult Get(int id) 23 | { 24 | return "value"; 25 | } 26 | 27 | // POST api/values 28 | [HttpPost] 29 | public void Post([FromBody] string value) 30 | { 31 | } 32 | 33 | // PUT api/values/5 34 | [HttpPut("{id}")] 35 | public void Put(int id, [FromBody] string value) 36 | { 37 | } 38 | 39 | // DELETE api/values/5 40 | [HttpDelete("{id}")] 41 | public void Delete(int id) 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /server/Helpers/AsyncResult.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System.Threading.Tasks; 8 | using server.Helpers.Errors; 9 | 10 | namespace server.Helpers { 11 | public class Metadata { 12 | public object Payload { get; set; } 13 | public Metadata(object payload) { 14 | Payload = payload; 15 | } 16 | } 17 | 18 | // Async result that bundles payload and error object 19 | // without throwing an exception for performance boost 20 | public class AsyncResult : IAsyncResult { 21 | 22 | private bool resolved = false; 23 | public Error Error { get; set; } 24 | public Metadata Metadata { get; set; } 25 | public T Payload { get; set; } 26 | 27 | public AsyncResult() { } 28 | public AsyncResult(T payload) { 29 | resolved = true; 30 | Payload = payload; 31 | } 32 | public AsyncResult(T payload, Metadata meta) { 33 | resolved = true; 34 | Payload = payload; 35 | Metadata = meta; 36 | } 37 | public AsyncResult(Error error) { 38 | Error = error; 39 | } 40 | public AsyncResult(T payload, Error error) { 41 | resolved = true; 42 | Payload = payload; 43 | Error = error; 44 | } 45 | 46 | public IAsyncResult Resolve(T payload, Metadata metadata = null) { 47 | resolved = true; 48 | this.Payload = payload; 49 | this.Metadata = metadata; 50 | return this; 51 | } 52 | public IAsyncResult Reject(Error error) { 53 | this.Error = error; 54 | return this; 55 | } 56 | public IAsyncResult Reject(IAsyncResult asyncResult) { 57 | this.Error = asyncResult.Error; 58 | return this; 59 | } 60 | 61 | public bool IsResolved() { 62 | return this.resolved; 63 | } 64 | public bool IsRejected() { 65 | return this.Error != null; 66 | } 67 | 68 | public IAsyncResult Clear() { 69 | return new AsyncResult(); 70 | } 71 | public IAsyncResult Cast() { 72 | return new AsyncResult(this.Error); 73 | } 74 | public IAsyncResult Cast(T1 payload) { 75 | return new AsyncResult(payload, this.Error); 76 | } 77 | public IAsyncResult Cast(System.Func payloadMapper) { 78 | var to = new AsyncResult(this.Error); 79 | to.Resolve(payloadMapper.Invoke(this.Payload)); 80 | return to; 81 | } 82 | 83 | public IAsyncResult AsIAsyncResult() { 84 | return (IAsyncResult)this; 85 | } 86 | public Task> AsTaskResult() { 87 | return Task.FromResult(this.AsIAsyncResult()); 88 | } 89 | 90 | } 91 | } -------------------------------------------------------------------------------- /server/Helpers/Errors/Error.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers.Errors { 8 | public class Error { 9 | public int StatusCode = 400; 10 | public string Title = "Bad Request"; 11 | public string Message = "Something is wrong with the request"; 12 | public object Payload = null; 13 | public string Tag = null; 14 | public string Type = "Error"; 15 | } 16 | } -------------------------------------------------------------------------------- /server/Helpers/Errors/ErrorCodes.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers.Errors { 8 | 9 | // 400 error types 10 | public class BadRequest : Error { 11 | public BadRequest() { 12 | StatusCode = 400; 13 | Title = "Bad Request"; 14 | Message = "Something is wrong with the request"; 15 | } 16 | } 17 | public class Unauthorized : Error { 18 | public Unauthorized() { 19 | StatusCode = 401; 20 | Title = "Not Authorized"; 21 | Message = "A valid authentication credentials are required"; 22 | } 23 | } 24 | public class Forbidden : Error { 25 | public Forbidden() { 26 | StatusCode = 403; 27 | Title = "Forbidden"; 28 | Message = "Request is not allowed"; 29 | } 30 | } 31 | public class NotFound : Error { 32 | public NotFound() { 33 | StatusCode = 404; 34 | Title = "Not Found"; 35 | Message = "Did not found anything matching the request"; 36 | } 37 | } 38 | public class Conflict : Error { 39 | public Conflict() { 40 | StatusCode = 409; 41 | Title = "Conflict"; 42 | Message = "Could not be completed due to a conflict"; 43 | } 44 | } 45 | public class ValidationError : Error { 46 | public ValidationError() { 47 | StatusCode = 400; 48 | Title = "Validation Failed"; 49 | Message = "The form contains invalid fields"; 50 | } 51 | } 52 | 53 | // 500 error types 54 | public class Unavailable : Error { 55 | public Unavailable() { 56 | StatusCode = 503; 57 | Title = "Not Available"; 58 | Message = "Request is currently unavailable"; 59 | } 60 | } 61 | 62 | // Custom error types 63 | public class RouteNotFound : Error { 64 | public RouteNotFound() { 65 | StatusCode = 404; 66 | Title = "Route Not Found"; 67 | Message = "No route for the request"; 68 | } 69 | } 70 | public class NotImplemented : Error { 71 | public NotImplemented() { 72 | StatusCode = 501; 73 | Title = "Not Implemented"; 74 | Message = "Functionality not supported yet"; 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /server/Helpers/Errors/ErrorException.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers.Errors { 8 | public class ErrorException : System.Exception { 9 | public int StatusCode = 500; 10 | } 11 | } -------------------------------------------------------------------------------- /server/Helpers/Errors/ErrorObjectResult.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using Microsoft.AspNetCore.Mvc; 8 | 9 | namespace server.Helpers.Errors { 10 | public class ErrorObjectResult : ObjectResult { 11 | public ErrorObjectResult(object o) : base(o) { } 12 | } 13 | } -------------------------------------------------------------------------------- /server/Helpers/IAsyncResult.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System.Threading.Tasks; 8 | using server.Helpers.Errors; 9 | 10 | namespace server.Helpers { 11 | public interface IAsyncResult { 12 | 13 | Error Error { get; set; } 14 | T Payload { get; set; } 15 | Metadata Metadata { get; set; } 16 | 17 | 18 | IAsyncResult Resolve(T payload, Metadata metadata = null); 19 | IAsyncResult Reject(Error error); 20 | IAsyncResult Reject(IAsyncResult error); 21 | 22 | bool IsResolved(); 23 | bool IsRejected(); 24 | 25 | IAsyncResult Clear(); 26 | IAsyncResult Cast(); 27 | IAsyncResult Cast(T1 payload); 28 | IAsyncResult Cast(System.Func payloadMapper); 29 | 30 | IAsyncResult AsIAsyncResult(); 31 | Task> AsTaskResult(); 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /server/Helpers/Paging.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers { 8 | public class Paging { 9 | public int Page { get; set; } = 1; 10 | public int Items { get; set; } = 10; 11 | public int Total { get; set; } = 0; 12 | } 13 | } -------------------------------------------------------------------------------- /server/Helpers/RouteController.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System; 8 | using server.Helpers.Errors; 9 | using Microsoft.AspNetCore.Hosting; 10 | using Microsoft.AspNetCore.Mvc; 11 | using Microsoft.Extensions.DependencyInjection; 12 | 13 | 14 | namespace server.Helpers { 15 | public class RouteController : Controller { 16 | protected IServiceProvider ServiceProvider; 17 | protected IHostingEnvironment Env; 18 | private object defaultPayload = new object { }; 19 | private string defaultTitle = "Internal Server Error"; 20 | private string defaultMessage = "Oops! Something went wrong"; 21 | 22 | public RouteController() { } 23 | 24 | public RouteController(IServiceProvider sp) { 25 | ServiceProvider = sp; 26 | Env = sp.GetRequiredService(); 27 | } 28 | 29 | private object StripPayload(object payload) { 30 | if (payload is Exception) 31 | return Env.IsProduction() ? defaultPayload : payload; 32 | return payload; 33 | } 34 | 35 | public object WrapSuccess(object payload, object meta, string code = "Ok") { 36 | return new { 37 | success = new { code = code }, 38 | meta = meta, 39 | payload = payload 40 | }; 41 | } 42 | 43 | public object WrapError(Error payload, string message = null) { 44 | return new { 45 | error = new { 46 | code = payload.GetType().Name, 47 | tag = payload.Tag, 48 | type = payload.Type, 49 | title = payload.Title, 50 | message = message ?? payload.Message 51 | }, 52 | payload = StripPayload(payload.Payload ?? payload) 53 | }; 54 | } 55 | 56 | public object WrapError(Exception payload, string message = null) { 57 | // #CHECK Make sure to strip out sensitive data on production 58 | return new { 59 | error = new { 60 | code = payload.GetType().Name, 61 | title = defaultTitle, 62 | message = Env.IsProduction() ? defaultMessage : message 63 | }, 64 | payload = Env.IsProduction() ? defaultPayload : payload 65 | }; 66 | } 67 | 68 | public OkObjectResult Success(string code = "Ok") { 69 | Response.Headers.Add("x-api-standard", "1"); 70 | return new OkObjectResult(WrapSuccess(null, null, code)); 71 | } 72 | 73 | public OkObjectResult Success(object payload, string code = "Ok") { 74 | Response.Headers.Add("x-api-standard", "1"); 75 | return new OkObjectResult(WrapSuccess(payload, null, code)); 76 | } 77 | 78 | public OkObjectResult Success(object payload, object meta, string code = "Ok") { 79 | Response.Headers.Add("x-api-standard", "1"); 80 | return new OkObjectResult(WrapSuccess(payload, meta, code)); 81 | } 82 | 83 | public ErrorObjectResult Error(Error payload, string message = null) { 84 | Response.Headers.Add("x-api-standard", "1"); 85 | var err = new ErrorObjectResult( 86 | WrapError(payload, message != null ? message : payload.Message)); 87 | err.StatusCode = payload.StatusCode; 88 | return err; 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /server/Helpers/Secrets.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.Primitives; 11 | 12 | namespace server.Helpers { 13 | public class Secrets : IConfiguration { 14 | 15 | public string this[string key] { 16 | get => throw new System.NotImplementedException(); 17 | set => throw new System.NotImplementedException(); 18 | } 19 | 20 | private IConfigurationRoot Configuration; 21 | 22 | public Secrets(IServiceProvider sp, IConfiguration configBase) { 23 | var builder = new ConfigurationBuilder(); 24 | var file = "appsettings.json"; 25 | builder.AddJsonFile(file, optional: true, reloadOnChange: true); 26 | Configuration = builder.Build(); 27 | } 28 | 29 | public IEnumerable GetChildren() { 30 | return Configuration.GetChildren(); 31 | } 32 | 33 | public IChangeToken GetReloadToken() { 34 | return Configuration.GetReloadToken(); 35 | } 36 | 37 | public IConfigurationSection GetSection(string key) { 38 | return Configuration.GetSection(key); 39 | } 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /server/Helpers/StartupConfig.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System; 8 | using Microsoft.AspNetCore.Builder; 9 | using Microsoft.AspNetCore.Hosting; 10 | using Microsoft.Extensions.Configuration; 11 | using Microsoft.Extensions.DependencyInjection; 12 | 13 | namespace server.Helpers { 14 | public class StartupConfig : IStartup { 15 | 16 | protected readonly IHostingEnvironment Env; 17 | protected readonly IConfiguration Config; 18 | 19 | public StartupConfig(IHostingEnvironment env, IConfiguration config) { 20 | Env = env; 21 | Config = config; 22 | } 23 | 24 | public virtual void Configure( 25 | IApplicationBuilder app) { } 26 | 27 | public virtual IServiceProvider ConfigureServices( 28 | IServiceCollection services) { 29 | return null; 30 | } 31 | 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/BoolProperty.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers.Validation { 8 | public class BoolProperty : Property { 9 | 10 | protected bool? Value; 11 | 12 | public BoolProperty(bool? val, string name, bool required) : base(name, required) { 13 | Value = val; 14 | IsNull = val == null; 15 | Prepare(); 16 | } 17 | 18 | public BoolProperty True() { 19 | if (!Validate) return this; 20 | if (Value != null && Value != true) 21 | Errors.Add($"Must be true"); 22 | return this; 23 | } 24 | 25 | public BoolProperty False() { 26 | if (!Validate) return this; 27 | if (Value != null && Value != false) 28 | Errors.Add($"Must be false"); 29 | return this; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/DateTimeProperty.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System; 8 | 9 | namespace server.Helpers.Validation { 10 | public class DateTimeProperty : Property { 11 | 12 | 13 | protected DateTime? Value; 14 | 15 | public DateTimeProperty(DateTime? val, string name, bool required) : base(name, required) { 16 | Value = val; 17 | IsNull = val == null; 18 | Prepare(); 19 | } 20 | 21 | public DateTimeProperty Range(DateTime min, DateTime max) { 22 | return this.Min(min).Max(max); 23 | } 24 | 25 | public DateTimeProperty Min(DateTime min) { 26 | if (!Validate) return this; 27 | if (Value != null && Value < min) 28 | Errors.Add($"Must be {min} or above"); 29 | return this; 30 | } 31 | 32 | public DateTimeProperty Max(DateTime max) { 33 | if (!Validate) return this; 34 | if (Value != null && Value > max) 35 | Errors.Add($"Must be {max} or below"); 36 | return this; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/DoubleProperty.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers.Validation { 8 | public class DoubleProperty : Property { 9 | protected double? Value; 10 | public DoubleProperty(double? val, string name, bool required) : base(name, required) { 11 | Value = val; 12 | IsNull = val == null; 13 | Prepare(); 14 | } 15 | 16 | public DoubleProperty Range(double min, double max) { 17 | return this.Min(min).Max(max); 18 | } 19 | 20 | public DoubleProperty Min(double min) { 21 | if (!Validate) return this; 22 | if (Value != null && Value < min) 23 | Errors.Add($"Must be {min} or above"); 24 | return this; 25 | } 26 | 27 | public DoubleProperty Max(double max) { 28 | if (!Validate) return this; 29 | if (Value != null && Value > max) 30 | Errors.Add($"Must be {max} or below"); 31 | return this; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/IntProperty.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers.Validation { 8 | public class IntProperty : Property { 9 | protected int? Value; 10 | 11 | public IntProperty(int? val, string name, bool required) : base(name, required) { 12 | Value = val; 13 | IsNull = val == null; 14 | Prepare(); 15 | } 16 | 17 | public IntProperty Range(int min, int max) { 18 | return this.Min(min).Max(max); 19 | }/* ß */ 20 | 21 | public IntProperty Min(int min) { 22 | if (!Validate) return this; 23 | if (Value != null && Value < min) 24 | Errors.Add($"Must be {min} or above"); 25 | return this; 26 | } 27 | 28 | public IntProperty Max(int max) { 29 | if (!Validate) return this; 30 | if (Value != null && Value > max) 31 | Errors.Add($"Must be {max} or below"); 32 | return this; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/ObjectProperty.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers.Validation { 8 | public class ObjectProperty : Property { 9 | protected object Value; 10 | public ObjectProperty(object val, string name, bool required) : base(name, required) { 11 | Value = val; 12 | IsNull = val == null; 13 | Prepare(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/Property.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System.Collections.Generic; 8 | namespace server.Helpers.Validation { 9 | public class Property { 10 | protected readonly string Name; 11 | protected bool Required; 12 | protected bool Validate = true; 13 | protected bool IsNull = true; 14 | protected List Errors = new List(); 15 | 16 | public Property(string name, bool required) { 17 | Name = name; 18 | Required = required; 19 | } 20 | 21 | protected void Prepare() { 22 | if (!Required && IsNull) Validate = false; 23 | if (Validate && IsNull) Errors.Add($"Must be set"); 24 | } 25 | 26 | public Result Results() { 27 | return new Result() { 28 | Name = Name, 29 | Errors = Errors.ToArray() 30 | }; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/Result.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | namespace server.Helpers.Validation { 8 | public class Result { 9 | public string Name { get; set; } 10 | public string[] Errors { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/StringProperty.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System; 8 | using System.Globalization; 9 | using System.Text.RegularExpressions; 10 | 11 | namespace server.Helpers.Validation { 12 | public class StringProperty : Property { 13 | 14 | protected string Value; 15 | 16 | public StringProperty(string val, string name, bool required) : base(name, required) { 17 | Value = val; 18 | IsNull = string.IsNullOrWhiteSpace(Value); 19 | Prepare(); 20 | } 21 | 22 | public StringProperty IsEmail() { 23 | if (!Validate) return this; 24 | if (!IsValidEmail(Value)) 25 | Errors.Add("Must be a valid email"); 26 | return this; 27 | } 28 | 29 | public StringProperty MatchRegex(string str, string msg = "Must match with pattern") { 30 | if (!Validate) return this; 31 | Regex rgx = new Regex(str); 32 | if (Value == null || !rgx.IsMatch(Value)) 33 | Errors.Add(msg); 34 | return this; 35 | } 36 | 37 | public StringProperty IsAlphaNumeric(string msg = "Must contain letter and number") { 38 | return this.MatchRegex(@"^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{0,}$", msg); 39 | } 40 | 41 | public StringProperty IsAlphaNumericSymbol(string msg = "Must contain letter, number and special character") { 42 | return this.MatchRegex(@"^(?=(.*\d){1})(?=.*[a-zA-Z])(?=.*[^a-zA-Z\d]).{0,}$", msg); 43 | } 44 | 45 | public StringProperty Length(int min, int max) { 46 | return this.Min(min).Max(max); 47 | } 48 | 49 | public StringProperty Min(int min) { 50 | if (!Validate) return this; 51 | if (Value == null || Value.Length < min) 52 | Errors.Add($"Must be at least {min} characters"); 53 | return this; 54 | } 55 | 56 | public StringProperty Max(int max) { 57 | if (!Validate) return this; 58 | if (Value != null && Value.Length > max) 59 | Errors.Add($"Must not exceed {max} characters"); 60 | return this; 61 | } 62 | 63 | public StringProperty In(string[] arr) { 64 | if (!Validate) return this; 65 | if (Array.IndexOf(arr, Value) == -1) 66 | Errors.Add($"Invalid value"); 67 | return this; 68 | } 69 | 70 | public StringProperty Match(string str, string msg = "Must be matching") { 71 | if (!Validate) return this; 72 | if (Value != null && Value != str) 73 | Errors.Add(msg); 74 | return this; 75 | } 76 | 77 | private bool IsValidEmail(string email) { 78 | if (string.IsNullOrWhiteSpace(email)) 79 | return false; 80 | try { 81 | // Normalize the domain 82 | email = Regex.Replace(email, @"(@)(.+)$", DomainMapper, 83 | RegexOptions.None, TimeSpan.FromMilliseconds(200)); 84 | // Examines the domain part of the email and normalizes it. 85 | string DomainMapper(Match match) { 86 | // Use IdnMapping class to convert Unicode domain names. 87 | var idn = new IdnMapping(); 88 | // Pull out and process domain name (throws ArgumentException on invalid) 89 | var domainName = idn.GetAscii(match.Groups[2].Value); 90 | return match.Groups[1].Value + domainName; 91 | } 92 | } catch (RegexMatchTimeoutException) { 93 | return false; 94 | } catch (ArgumentException) { 95 | return false; 96 | } 97 | try { 98 | return Regex.IsMatch(email, 99 | @"^(?("")("".+?(? max) 33 | Errors.Add($"Must be {max} or below"); 34 | return this; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /server/Helpers/Validation/Validator.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * License: MIT 3 | * Author: Kevin Villanueva 4 | * Contact: https://github.com/rhaldkhein 5 | */ 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using server.Helpers; 11 | using server.Helpers.Errors; 12 | 13 | namespace server.Helpers.Validation { 14 | public class Validator { 15 | public IEnumerable Errors { get; private set; } 16 | 17 | private List Validations = new List(); 18 | 19 | /* 20 | * Type validations 21 | */ 22 | 23 | public ObjectProperty IsObject(object val, string name, bool required = false) { 24 | var validation = new ObjectProperty(val, name, required); 25 | Validations.Add(validation); 26 | return validation; 27 | } 28 | 29 | public StringProperty IsString(string val, string name, bool required = false) { 30 | var validation = new StringProperty(val, name, required); 31 | Validations.Add(validation); 32 | return validation; 33 | } 34 | 35 | public IntProperty IsNumber(int? val, string name, bool required = false) { 36 | var validation = new IntProperty(val, name, required); 37 | Validations.Add(validation); 38 | return validation; 39 | } 40 | 41 | public DoubleProperty IsNumber(double? val, string name, bool required = false) { 42 | var validation = new DoubleProperty(val, name, required); 43 | Validations.Add(validation); 44 | return validation; 45 | } 46 | 47 | public BoolProperty IsBool(bool? val, string name, bool required = false) { 48 | var validation = new BoolProperty(val, name, required); 49 | Validations.Add(validation); 50 | return validation; 51 | } 52 | 53 | public DateTimeProperty IsDateTime(DateTime? val, string name, bool required = false) { 54 | var validation = new DateTimeProperty(val, name, required); 55 | Validations.Add(validation); 56 | return validation; 57 | } 58 | 59 | public TimeSpanProperty IsTimeSpan(TimeSpan? val, string name, bool required = false) { 60 | var validation = new TimeSpanProperty(val, name, required); 61 | Validations.Add(validation); 62 | return validation; 63 | } 64 | 65 | /* 66 | * Utils 67 | */ 68 | 69 | public bool Validate() { 70 | var mapped = Validations.Select(v => v.Results()); 71 | Errors = mapped.Where(v => v.Errors.Length > 0); 72 | return Errors.Count() <= 0; 73 | } 74 | 75 | public bool ContainsError() { 76 | return !Validate(); 77 | } 78 | 79 | public ValidationError AsValidationError() { 80 | return new ValidationError() { Payload = Errors }; 81 | } 82 | 83 | public IAsyncResult AsIAsyncResultError() { 84 | return new AsyncResult().Reject(AsValidationError()); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /server/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace server 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /server/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:64956", 8 | "sslPort": 44320 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "server": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "http://localhost:5001;http://localhost:5002", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 | # server 2 | 3 | ### Run your server 4 | ``` 5 | dotnet watch run 6 | ``` 7 | # client 8 | 9 | ## Project setup 10 | ``` 11 | npm install 12 | ``` 13 | 14 | ### Compiles and hot-reloads for development 15 | ``` 16 | npm run serve 17 | ``` 18 | 19 | ### Compiles and minifies for production 20 | ``` 21 | npm run build 22 | ``` 23 | 24 | ### Run your tests 25 | ``` 26 | npm run test 27 | ``` 28 | 29 | ### Lints and fixes files 30 | ``` 31 | npm run lint 32 | ``` 33 | 34 | ### Customize configuration 35 | See [Configuration Reference](https://cli.vuejs.org/config/). 36 | -------------------------------------------------------------------------------- /server/Startup.cs: -------------------------------------------------------------------------------- 1 | using server.Helpers; 2 | using server.Configurations; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using System.Collections.Generic; 8 | 9 | namespace server 10 | { 11 | public class Startup 12 | { 13 | public IConfiguration Configuration { get; } 14 | private List Startups; 15 | public Startup(IHostingEnvironment env, IConfiguration configuration) 16 | { 17 | Configuration = configuration; 18 | this.BuildServiceConfigurations(env); 19 | } 20 | 21 | private void BuildServiceConfigurations(IHostingEnvironment env) 22 | { 23 | Startups = new List(); 24 | Startups.Add(new ServiceRegistrar(env, Configuration)); 25 | Startups.Add(new Parsing(env, Configuration)); 26 | Startups.Add(new Authentication(env, Configuration)); 27 | Startups.Add(new ApiRouting(env, Configuration)); 28 | Startups.Add(new SpaRouting(env, Configuration)); 29 | 30 | // #ADD more service startup config 31 | } 32 | 33 | // This method gets called by the runtime. Use this method to add services to the container. 34 | public void ConfigureServices(IServiceCollection services) 35 | { 36 | 37 | services.AddOptions(); 38 | foreach (var startup in Startups) startup.ConfigureServices(services); 39 | 40 | } 41 | 42 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 43 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 44 | { 45 | 46 | foreach (var startup in Startups) startup.Configure(app); 47 | // Done configuring, clean up collection. 48 | 49 | Startups.Clear(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /server/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*", 8 | "Key": "abcdefjmonceda", 9 | "Issuer": "issuer", 10 | "Audience": "audience" 11 | } 12 | -------------------------------------------------------------------------------- /server/bin/Debug/netcoreapp2.2/server.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/server/bin/Debug/netcoreapp2.2/server.dll -------------------------------------------------------------------------------- /server/bin/Debug/netcoreapp2.2/server.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/server/bin/Debug/netcoreapp2.2/server.pdb -------------------------------------------------------------------------------- /server/bin/Debug/netcoreapp2.2/server.runtimeconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "additionalProbingPaths": [ 4 | "/Users/joevermonceda/.dotnet/store/|arch|/|tfm|", 5 | "/Users/joevermonceda/.nuget/packages", 6 | "/usr/local/share/dotnet/sdk/NuGetFallbackFolder" 7 | ] 8 | } 9 | } -------------------------------------------------------------------------------- /server/bin/Debug/netcoreapp2.2/server.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "netcoreapp2.2", 4 | "framework": { 5 | "name": "Microsoft.AspNetCore.App", 6 | "version": "2.2.0" 7 | }, 8 | "configProperties": { 9 | "System.GC.Server": true 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("server")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 17 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 18 | [assembly: System.Reflection.AssemblyProductAttribute("server")] 19 | [assembly: System.Reflection.AssemblyTitleAttribute("server")] 20 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 21 | 22 | // Generated by the MSBuild WriteCodeFragment class. 23 | 24 | -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 7550e82ffe0e1175cb956ef1940dcdca83c9a728 2 | -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.RazorAssemblyInfo.cache: -------------------------------------------------------------------------------- 1 | a35a5bf597b8833c4304f9608eeefc8226f069b8 2 | -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.RazorAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Generated by the MSBuild WriteCodeFragment class. 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | using System; 8 | using System.Reflection; 9 | 10 | [assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.RelatedAssemblyAttribute("server.Views")] 11 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorLanguageVersionAttribute("2.1")] 12 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorConfigurationNameAttribute("MVC-2.1")] 13 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorExtensionAssemblyNameAttribute("MVC-2.1", "Microsoft.AspNetCore.Mvc.Razor.Extensions")] 14 | -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.RazorTargetAssemblyInfo.cache: -------------------------------------------------------------------------------- 1 | 969d06c35fb3ea5035f365faad741e6c6212fd79 2 | -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/server/obj/Debug/netcoreapp2.2/server.assets.cache -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | e26b398c2a457bb3c60cdb0c34450c69afe5172d 2 | -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | /Users/joevermonceda/Documents/vuecore/server/bin/Debug/netcoreapp2.2/server.deps.json 2 | /Users/joevermonceda/Documents/vuecore/server/bin/Debug/netcoreapp2.2/server.runtimeconfig.json 3 | /Users/joevermonceda/Documents/vuecore/server/bin/Debug/netcoreapp2.2/server.runtimeconfig.dev.json 4 | /Users/joevermonceda/Documents/vuecore/server/bin/Debug/netcoreapp2.2/server.dll 5 | /Users/joevermonceda/Documents/vuecore/server/bin/Debug/netcoreapp2.2/server.pdb 6 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.csprojAssemblyReference.cache 7 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.csproj.CoreCompileInputs.cache 8 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.RazorAssemblyInfo.cache 9 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.RazorAssemblyInfo.cs 10 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.AssemblyInfoInputs.cache 11 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.AssemblyInfo.cs 12 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.RazorTargetAssemblyInfo.cache 13 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.dll 14 | /Users/joevermonceda/Documents/vuecore/server/obj/Debug/netcoreapp2.2/server.pdb 15 | -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.csprojAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/server/obj/Debug/netcoreapp2.2/server.csprojAssemblyReference.cache -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/server/obj/Debug/netcoreapp2.2/server.dll -------------------------------------------------------------------------------- /server/obj/Debug/netcoreapp2.2/server.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/server/obj/Debug/netcoreapp2.2/server.pdb -------------------------------------------------------------------------------- /server/obj/server.csproj.nuget.cache: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "dgSpecHash": "VIuPfG0dLNCUhA4JqDid3EXfs9eUDa0qvG/KVGxKrG0Ejesb8VHMUoGoAiKDcQ4v4GaRd9X15/npOCnddwKdrA==", 4 | "success": true 5 | } -------------------------------------------------------------------------------- /server/obj/server.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | NuGet 6 | /Users/joevermonceda/Documents/vuecore/server/obj/project.assets.json 7 | /Users/joevermonceda/.nuget/packages/ 8 | /Users/joevermonceda/.nuget/packages/;/usr/local/share/dotnet/sdk/NuGetFallbackFolder 9 | PackageReference 10 | 4.9.4 11 | 12 | 13 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | /usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.entityframeworkcore.tools/2.2.0 26 | /usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.codeanalysis.analyzers/1.1.0 27 | /usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.aspnetcore.razor.design/2.2.0 28 | 29 | -------------------------------------------------------------------------------- /server/obj/server.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /server/server.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /server/wwwroot/css/app.20847301.css: -------------------------------------------------------------------------------- 1 | #app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50}#nav{padding:30px}#nav a{font-weight:700;color:#2c3e50}#nav a.router-link-exact-active{color:#42b983}h3[data-v-379548a4]{margin:40px 0 0}ul[data-v-379548a4]{list-style-type:none;padding:0}li[data-v-379548a4]{display:inline-block;margin:0 10px}a[data-v-379548a4]{color:#42b983} -------------------------------------------------------------------------------- /server/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/server/wwwroot/favicon.ico -------------------------------------------------------------------------------- /server/wwwroot/img/logo.82b9c7a5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ethan0007/aspnetcore-vue-starterkit/fbf3ddfe1be61e9aeae93842d3716bb95ba8716e/server/wwwroot/img/logo.82b9c7a5.png -------------------------------------------------------------------------------- /server/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | client
-------------------------------------------------------------------------------- /server/wwwroot/js/about.46ca718d.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["about"],{f820:function(t,e,n){"use strict";n.r(e);var a=function(){var t=this,e=t.$createElement;t._self._c;return t._m(0)},s=[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"about"},[n("h1",[t._v("This is an about page")])])}],u=n("2877"),c={},i=Object(u["a"])(c,a,s,!1,null,null,null);e["default"]=i.exports}}]); 2 | //# sourceMappingURL=about.46ca718d.js.map -------------------------------------------------------------------------------- /server/wwwroot/js/about.46ca718d.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./src/views/About.vue?7642","webpack:///./src/views/About.vue"],"names":["render","_vm","this","_h","$createElement","_self","_c","_m","staticRenderFns","staticClass","_v","script","component","Object","componentNormalizer","__webpack_exports__"],"mappings":"8GAAA,IAAAA,EAAA,WAA0B,IAAAC,EAAAC,KAAaC,EAAAF,EAAAG,eAA0BH,EAAAI,MAAAC,GAAwB,OAAAL,EAAAM,GAAA,IACzFC,EAAA,YAAoC,IAAAP,EAAAC,KAAaC,EAAAF,EAAAG,eAA0BE,EAAAL,EAAAI,MAAAC,IAAAH,EAAwB,OAAAG,EAAA,OAAiBG,YAAA,SAAoB,CAAAH,EAAA,MAAAL,EAAAS,GAAA,2CCAxIC,EAAA,GAKAC,EAAgBC,OAAAC,EAAA,KAAAD,CAChBF,EACEX,EACAQ,GACF,EACA,KACA,KACA,MAIeO,EAAA,WAAAH","file":"js/about.46ca718d.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _vm._m(0)}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"about\"},[_c('h1',[_vm._v(\"This is an about page\")])])}]\n\nexport { render, staticRenderFns }","import { render, staticRenderFns } from \"./About.vue?vue&type=template&id=1ae8a7be&\"\nvar script = {}\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""} -------------------------------------------------------------------------------- /server/wwwroot/js/app.94ec2a54.js: -------------------------------------------------------------------------------- 1 | (function(e){function t(t){for(var n,u,l=t[0],s=t[1],i=t[2],c=0,p=[];c\n
\n

{{ msg }}

\n

\n For a guide and recipes on how to configure / customize this project,
\n check out the\n vue-cli documentation.\n

\n

Installed CLI Plugins

\n \n

Essential Links

\n \n

Ecosystem

\n \n
\n\n\n\n\n\n\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./HelloWorld.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./HelloWorld.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./HelloWorld.vue?vue&type=template&id=379548a4&scoped=true&\"\nimport script from \"./HelloWorld.vue?vue&type=script&lang=js&\"\nexport * from \"./HelloWorld.vue?vue&type=script&lang=js&\"\nimport style0 from \"./HelloWorld.vue?vue&type=style&index=0&id=379548a4&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"379548a4\",\n null\n \n)\n\nexport default component.exports","\n\n\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Home.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Home.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./Home.vue?vue&type=template&id=59ba5f92&\"\nimport script from \"./Home.vue?vue&type=script&lang=js&\"\nexport * from \"./Home.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import Vue from 'vue'\nimport Router from 'vue-router'\nimport Home from './views/Home.vue'\n\nVue.use(Router)\n\nexport default new Router({\n mode: 'history',\n base: process.env.BASE_URL,\n routes: [\n {\n path: '/',\n name: 'home',\n component: Home\n },\n {\n path: '/about',\n name: 'about',\n // route level code-splitting\n // this generates a separate chunk (about.[hash].js) for this route\n // which is lazy-loaded when the route is visited.\n component: () => import(/* webpackChunkName: \"about\" */ './views/About.vue')\n }\n ]\n})\n","import Vue from 'vue'\nimport Vuex from 'vuex'\n\nVue.use(Vuex)\n\nexport default new Vuex.Store({\n state: {\n\n },\n mutations: {\n\n },\n actions: {\n\n }\n})\n","import Vue from 'vue'\nimport App from './App.vue'\nimport router from './router'\nimport store from './store'\nimport 'bootstrap'\nimport 'bootstrap/dist/css/bootstrap.min.css'\n\nVue.config.productionTip = false\n\nnew Vue({\n router,\n store,\n render: h => h(App)\n}).$mount('#app')\n","import mod from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./HelloWorld.vue?vue&type=style&index=0&id=379548a4&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./HelloWorld.vue?vue&type=style&index=0&id=379548a4&scoped=true&lang=css&\"","module.exports = __webpack_public_path__ + \"img/logo.82b9c7a5.png\";"],"sourceRoot":""} --------------------------------------------------------------------------------