├── .gitignore
├── .bowerrc
├── client
├── views
│ ├── about.html
│ └── main.html
├── src
│ ├── about.js
│ └── main.js
├── sass
│ ├── main.scss
│ ├── _partial1.scss
│ └── _partial2.scss
├── app.js
└── index.html
├── test
├── run.sh
├── server
│ └── index_test.js
└── test-helper.js
├── bower.json
├── README.md
├── package.json
└── server
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | client/lib/
--------------------------------------------------------------------------------
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "client/lib"
3 | }
--------------------------------------------------------------------------------
/client/views/about.html:
--------------------------------------------------------------------------------
1 |
2 |
{{header}}
3 |
--------------------------------------------------------------------------------
/test/run.sh:
--------------------------------------------------------------------------------
1 | ./node_modules/.bin/mocha --recursive -r test/test-helper.js "$@"
2 |
--------------------------------------------------------------------------------
/client/views/main.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/client/src/about.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp')
4 | .controller('AboutCtrl', ['$scope','$http', function($scope,$http) {
5 | $scope.header = 'I am ready to be built!';
6 | }]);
7 |
--------------------------------------------------------------------------------
/client/src/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp')
4 | .controller('MainCtrl', ['$scope', function($scope) {
5 | $scope.welcome = 'Welcome to your App!';
6 | $scope.buttonText = 'This is your Button';
7 | }]);
8 |
--------------------------------------------------------------------------------
/client/sass/main.scss:
--------------------------------------------------------------------------------
1 | /* remember to set all global css and variables before importing */
2 |
3 | $black: #000;
4 |
5 | body {
6 | background-color: $black;
7 | }
8 |
9 | /* import partials */
10 | @import 'partial1';
11 | @import 'partial2';
--------------------------------------------------------------------------------
/client/sass/_partial1.scss:
--------------------------------------------------------------------------------
1 | /* This is a partial, you can rename this or create your own */
2 |
3 | .btn {
4 | background: #639FDE;
5 | border-radius: 28px;
6 | font-family: sans-serif;
7 | color: #ffffff;
8 | font-size: 20px;
9 | padding: 10px 20px 10px 20px;
10 | text-decoration: none;
11 | text-align: center;
12 | }
13 |
14 | .btn:hover{
15 | background-color: #2380E2;
16 | }
--------------------------------------------------------------------------------
/client/sass/_partial2.scss:
--------------------------------------------------------------------------------
1 | /* This is a partial, you can rename this or create your own */
2 |
3 | .jumbotron{
4 | background-color: #303430;
5 | margin: 0 auto;
6 | width: 80%;
7 | padding: 30px;
8 | margin-top: 100px;
9 | text-align: center;
10 | border-radius: 2px;
11 |
12 | /* nesting html elements */
13 | h1{
14 | color: #2380E2;
15 | font-family: sans-serif;
16 | }
17 | }
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "myApp",
3 | "version": "0.0.0",
4 | "dependencies": {
5 | "angular": "^1.4.0",
6 | "angular-animate": "^1.4.0",
7 | "angular-cookies": "^1.4.0",
8 | "angular-resource": "^1.4.0",
9 | "angular-sanitize": "^1.4.0",
10 | "angular-touch": "^1.4.0",
11 | "angular-ui-router": "^0.2.15"
12 | },
13 | "devDependencies": {
14 | "angular-mocks": "^1.4.0"
15 | },
16 | "appPath": "app"
17 | }
18 |
--------------------------------------------------------------------------------
/test/server/index_test.js:
--------------------------------------------------------------------------------
1 | var request = require('supertest')
2 | var routes = require(__server + '/index.js')
3 |
4 | describe("The Server", function() {
5 |
6 | var app = TestHelper.createApp()
7 | app.use('/', routes)
8 | app.testReady()
9 |
10 | it("serves an example endpoint", function() {
11 |
12 | // Mocha will wait for returned promises to complete
13 | return request(app)
14 | .get('/api/tags-example')
15 | .expect(200)
16 | .expect(function(response) {
17 | expect(response.body).to.include('node')
18 | })
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/client/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp', [
4 | 'ui.router'
5 | ])
6 |
7 | .config(function($stateProvider, $urlRouterProvider) {
8 |
9 | $urlRouterProvider.otherwise('/');
10 |
11 | $stateProvider
12 | .state('home', {
13 | url: '/',
14 | templateUrl: 'views/main.html',
15 | controller: 'MainCtrl'
16 | })
17 |
18 | .state('about', {
19 | url: '/about',
20 | templateUrl: 'views/about.html',
21 | controller: 'AboutCtrl'
22 | });
23 |
24 | });
25 |
--------------------------------------------------------------------------------
/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Node Catapult - Angular & Sass
2 |
3 | A boilerplate starter project that includes Node, Express, Angular and -now- Sass:
4 |
5 | * Lightweight - Comprehend everything.
6 | * Logical - Firm basics for development and production.
7 | * Swift - Get started immediately.
8 |
9 | ## Getting Started
10 |
11 | ```
12 | $ git clone https://github.com/fmaredia/node-catapult-angular-sass my-project
13 | $ cd my-project
14 | $ npm install
15 | $ bower install
16 | $ npm start
17 | ```
18 |
19 | Now visit [localhost:4000](http://localhost:4000/)
20 |
21 | ### Running the Tests
22 | There is a basic test framework in your `test/` folder. To run the tests, simply run `npm test`.
23 |
24 | ## Credits
25 | This version of the Node Catapult boilerplate utilizes the Angular version (https://github.com/dyale/node-catapult-angular) of mindeavor's original (https://github.com/mindeavor/node-catapult) and implements mindeavor's Node endpoint for compiling Sass (https://github.com/mindeavor/node-sass-endpoint)
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Node-Catapult-Angular-Sass",
3 | "version": "1.0.0",
4 | "main": "server/index.js",
5 | "description": "A rapid project starter for Node, Express, Angular and Sass.",
6 | "engines": {
7 | "node": ">=4.0.0"
8 | },
9 | "dependencies": {
10 | "body-parser": "^1.14.1",
11 | "es6-object-assign": "^1.0.1",
12 | "express": "^4.13.1",
13 | "node-sass-endpoint": "^0.2.1",
14 | "nodemon": "^1.3.7"
15 | },
16 | "devDependencies": {
17 | "chai": "^3.4.0",
18 | "mocha": "^2.3.3",
19 | "nodemon": "^1.3.7",
20 | "supertest": "^1.1.0",
21 | "supertest-as-promised": "^2.0.2"
22 | },
23 | "author": "Gilbert Garza, Dan Corman and Farah Maredia",
24 | "license": "MIT",
25 | "scripts": {
26 | "start": "./node_modules/.bin/nodemon server/index.js --ignore client/ --ignore node_modules/",
27 | "test": "./test/run.sh"
28 | },
29 | "bugs": {
30 | "url": "https://github.com/node-catapult/node-catapult-angular-sass/issues"
31 | },
32 | "homepage": "https://github.com/node-catapult/node-catapult-angular-sass/"
33 | }
34 |
--------------------------------------------------------------------------------
/test/test-helper.js:
--------------------------------------------------------------------------------
1 | process.env.NODE_ENV = 'test'
2 |
3 | // The following allows you to require files independent of
4 | // the location of your test file.
5 | // Example:
6 | // var User = require(__server + '/models/user.js')
7 | //
8 | global.__server = __dirname + '/../server'
9 | global.__client = __dirname + '/../client'
10 |
11 | //
12 | // Assertions
13 | //
14 | var chai = require('chai')
15 | // Option 1: Make the `expect` function available in every test file
16 | global.expect = chai.expect
17 | // Option 2: Make everything should-able
18 | // chai.should()
19 |
20 |
21 | //
22 | // Helper Functions
23 | //
24 | // This is the object you can attach any helper functions used across
25 | // several test files.
26 | global.TestHelper = {}
27 |
28 | //
29 | // Mock apps for API testing
30 | //
31 | var express = require('express')
32 |
33 | TestHelper.createApp = function (loader) {
34 | var app = express()
35 | app.use(require('body-parser').json())
36 |
37 | app.testReady = function () {
38 | // Log all errors
39 | app.use(function (err, req, res, next) {
40 | console.error("==Error==")
41 | console.error(" " + err.stack)
42 | next(err)
43 | })
44 | }
45 | return app
46 | }
47 |
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var Path = require('path');
3 | var routes = express.Router();
4 | var sass = require('node-sass-endpoint');
5 |
6 | //route to your index.html
7 | var assetFolder = Path.resolve(__dirname, '../client/');
8 | routes.use(express.static(assetFolder));
9 |
10 | // Example endpoint (also tested in test/server/index_test.js)
11 | routes.get('/api/tags-example', function(req, res) {
12 | res.send(['node', 'express', 'angular'])
13 | });
14 |
15 | if(process.env.NODE_ENV !== 'test') {
16 | // The Catch-all Route
17 | // This is for supporting browser history pushstate.
18 | // NOTE: Make sure this route is always LAST.
19 | routes.get('/*', function(req, res){
20 | res.sendFile( assetFolder + '/index.html' )
21 | })
22 |
23 | // We're in development or production mode;
24 | // create and run a real server.
25 | var app = express();
26 |
27 | // Parse incoming request bodies as JSON
28 | app.use( require('body-parser').json() );
29 |
30 | // This compiles your Sass files
31 | // Remember to change file paths or directories
32 | app.get(
33 | '/main.css',
34 | sass.serve('./client/sass/main.scss', {
35 |
36 | // (dev only) defaults to parent folder of scss file.
37 | // Any sass file changes in this directory will clear the output cache.
38 | watchDir: './client/sass/',
39 |
40 | // defaults to parent folder of scss file
41 | includePaths: ['./client/sass/'],
42 |
43 | // defaults to false
44 | debug: false
45 | })
46 | )
47 |
48 | // Mount our main router
49 | app.use('/', routes);
50 |
51 | // Start the server!
52 | var port = process.env.PORT || 4000;
53 | app.listen(port);
54 | console.log("Listening on port", port);
55 | } else {
56 | // We're in test mode; make this file importable instead.
57 | module.exports = routes;
58 | }
--------------------------------------------------------------------------------