Skip to content

Commit

Permalink
Merge branch '016/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
BenGitsCode committed Jan 23, 2017
2 parents 314f5bb + 1c5b757 commit deb4fdc
Show file tree
Hide file tree
Showing 21 changed files with 194 additions and 59 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ tmp
dist
vendor.js
specs.js
*bundle.js
application.js
_SpecRunner.html
*.woff2
*.woff
*.svg
*.ttf
*.eot
public/

# Created by https://www.gitignore.io/api/node,osx,linux,windows,ruby,node,rails,express,ember

Expand Down Expand Up @@ -218,6 +219,7 @@ jspm_packages
### Rails ###
*.rbc
capybara-*.html
.rspec
/log
/tmp
/db/*.sqlite3
Expand Down Expand Up @@ -252,6 +254,7 @@ config/initializers/secret_token.rb
# if using bower-rails ignore default bower_components path bower.json files
/vendor/assets/bower_components
*.bowerrc
bower.json

# Ignore pow environment settings
.powenv
Expand Down
1 change: 1 addition & 0 deletions .scss-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exclude: 'node_modules/*'
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ repository.

## Using web APIs

Why is authentication an important topic?

Web APIs often require some sort of authentication. The game API requires users
to register and then login to gain an authentication token.

We'll use `curl`, `httpbin.org`, and `jQuery.ajax` to explore HTTP further.
The we'll connect to an authenticated API, [library-api](https://github.com/ga-wdi-boston/library-api).
We'll use `curl`, [httpbin.org](http://httpbin.org/), and `jQuery.ajax` to
explore HTTP further. Then we'll connect to an authenticated API,
[library-api](https://github.com/ga-wdi-boston/library-api).

The operations we'll perform:

Expand Down
3 changes: 3 additions & 0 deletions assets/scripts/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
'use strict';

const config = {
apiOrigins: {
production: 'https://ga-wdi-boston.herokuapp.com',
},
};

module.exports = config;
3 changes: 0 additions & 3 deletions assets/scripts/example.js

This file was deleted.

13 changes: 13 additions & 0 deletions assets/scripts/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
'use strict';

const setAPIOrigin = require('../../lib/set-api-origin');
const config = require('./config');

$(() => {
setAPIOrigin(location, config);
});

// use require with a reference to bundle the file and use it in this file
// const example = require('./example');

// use require without a reference to ensure a file is bundled
// require('./example');

const authEvents = require('./auth/events.js');

// On document ready
Expand Down
Empty file.
7 changes: 7 additions & 0 deletions grunt/aliases.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{
"default": ["nag"],
"deploy": [
"shell:git-is-clean",
"shell:git-push-master",
"shell:deploy-prepare",
"build",
"shell:deploy-publish"
],
"build": ["webpack:build"],
"server": ["webpack-dev-server:start"],
"serve": ["server"],
Expand Down
4 changes: 2 additions & 2 deletions grunt/jasmine.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"tests": {
"src": ["vendor.bundle.js", "bundle.js"],
"src": ["public/vendor.js", "public/application.js"],
"options": {
"specs": "specs.js"
"specs": "public/specs.js"
}
}
}
39 changes: 39 additions & 0 deletions grunt/shell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

const ghPagesList = [
'index.html',
'favicon.ico',
'public',
].join(' ');

module.exports = {
'git-is-clean': {
// `$(git status --porcelain)` will evaluate to the empty string if the
// working directory is clean.
// `test -z` will exit 0 (true) if its argument is an empty string.
// If it doesn't exit true, `(git status && false)` will show why the
// repository isn't clean and exit false causing the grunt tasks to end.
command: 'test -z "$(git status --porcelain)" || (git status && false)',
},
'git-push-master': {
command: 'git push origin master',
},
'deploy-prepare': {
command: [
'git checkout master',
'git branch -D gh-pages || echo "so not removed"',
'git checkout --orphan gh-pages',
'git rm --cached \'*\'',
].join(' && '),
},
'deploy-publish': {
command: [
'touch .nojekyll',
`git add --force .nojekyll ${ghPagesList}`,
'git commit -m "deploy task"',
'git push origin gh-pages --force',
'git clean -x -d --force --exclude=node_modules',
'git checkout master',
].join(' && '),
},
};
11 changes: 8 additions & 3 deletions grunt/webpack-dev-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ let clone = require('clone');
// clone the webpack config to separate configuration of webpack and dev server
let webpackConfig = clone(require('./webpack').options);

//port for webpack-dev-server
// port for development server
const port = +('GA'.split('').reduce((p, c)=> p + c.charCodeAt(), ''));

// enable live reload without a script tag
webpackConfig.entry.vendor.unshift(`webpack-dev-server/client?http://localhost:${port}`);
// make `jQuery` and `$` available in the development console
webpackConfig.module.loaders.push({
test: require.resolve('jquery'),
loader: 'expose?jQuery!expose?$',
});

module.exports = {
options: {
port,
inline: true, // reload on change
webpack: webpackConfig,
publicPath: '/public/',
},

start: {
Expand Down
24 changes: 17 additions & 7 deletions grunt/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ let path = require('path');
module.exports = {
options: {
entry: {
bundle: './index.js',
application: './index.js',
specs: './spec/_all.js',
vendor: ['jquery', 'bootstrap-sass'],
},

output: {
path: './',
filename: '[name].js',
path: __dirname + '/../public',
publicPath: 'public/',
},

plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Expand Down Expand Up @@ -56,14 +60,20 @@ module.exports = {
{
test: /\.(hbs|handlebars)$/,
loader: 'handlebars-loader',
},
{
test: /\.html\.(hbs|handlebars)$/,
loader: 'handlebars-loader!html',
query: {
helperDirs: [
__dirname + '/../assets/scripts/templates/helpers',
],
},
},
],
},

resolve: {
alias: {
handlebars: 'handlebars/dist/handlebars.js',
},
},
stats: {
colors: true,
modules: true,
Expand Down
8 changes: 6 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@

<meta name="viewport" content="width=device-width, initial-scale=1">

<script src="vendor.bundle.js" type="text/javascript" charset="utf-8" defer></script>
<script src="bundle.js" type="text/javascript" charset="utf-8" defer></script>
<!-- Do not add `link` tags unless you know what you are doing -->
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">

<!-- Do not add `script` tags unless you know what you are doing -->
<script src="public/vendor.js" type="text/javascript" charset="utf-8" defer></script>
<script src="public/application.js" type="text/javascript" charset="utf-8" defer></script>
</head>
<body class="container-fluid">
<h1>API Token Auth</h1>
Expand Down
8 changes: 0 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,3 @@ require('./assets/scripts/index.js');

// styles
require('./assets/styles/index.scss');

// attach jQuery globally
require('expose?$!jquery');
require('expose?jQuery!jquery');

// attach getFormFields globally

require('expose?getFormFields!./lib/get-form-fields.js');
25 changes: 25 additions & 0 deletions lib/add-nested-value.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

const addNestedValue = function (pojo, name, value) {
const recurse = function recurse(pojo, keys, value) {
value = decodeURIComponent(value);
let key = decodeURIComponent(keys.shift());
let next = keys[0];
if (next === '') { // key is an array
pojo[key] = pojo[key] || [];
pojo[key].push(value);
} else if (next) { // key is a parent key
pojo[key] = pojo[key] || {};
recurse(pojo[key], keys, value);
} else { // key is the key for value
pojo[key] = value;
}

return pojo;
};

let keys = name.split('[').map((k) => k.replace(/]$/, ''));
return recurse(pojo, keys, value);
};

module.exports = addNestedValue;
23 changes: 4 additions & 19 deletions lib/get-form-fields.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
'use strict';

const addFormField = function addFormField(target, names, value) {
let name = names.shift();
let next = names[0];
if (next === '') { // name is an array
target[name] = target[name] || [];
target[name].push(value);
} else if (next) { // name is a parent key
target[name] = target[name] || {};
addFormField(target[name], names, value);
} else { // name is the key for value
target[name] = value;
}

return target;
};
const addNestedValue = require('./add-nested-value');

const getFormFields = (form) => {
let target = {};
Expand All @@ -36,17 +22,16 @@ const getFormFields = (form) => {
break;
}

let names = e.getAttribute('name').split('[')
.map((k) => k.replace(/]$/, ''));
let name = e.getAttribute('name');

if (type === 'MULTIPLE') {
for (let i = 0; i < e.length; i++) {
if (e[i].selected) {
addFormField(target, names.slice(), e[i].value);
addNestedValue(target, name, e[i].value);
}
}
} else if ((type !== 'RADIO' && type !== 'CHECKBOX') || e.checked) {
addFormField(target, names, e.value);
addNestedValue(target, name, e.value);
}
}

Expand Down
16 changes: 16 additions & 0 deletions lib/parse-nested-query.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const addNestedValue = require('./add-nested-value');

const parseNestedQuery = queryString =>
queryString.split('&')
.reduce((memo, element) => {
if (element) {
let keyValuePair = element.split('=');
memo = addNestedValue(memo, keyValuePair[0], keyValuePair[1]);
}

return memo;
}, {});

module.exports = parseNestedQuery;
37 changes: 37 additions & 0 deletions lib/set-api-origin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

const parseNestedQuery = require('./parse-nested-query');

/*
possibilites to handle and example URLs:
client local, api local
http://localhost:7165/
client local, api remote
http://localhost:7165/?environment=production
client remote, api local
https://ga-wdi-boston.github.io/browser-template/?environment=development
This will require allowing "unsafe scripts" in Chrome
client remote, api remote
https://ga-wdi-boston.github.io/browser-template/
*/

const setAPIOrigin = (location, config) => {
// strip the leading `'?'`
const search = parseNestedQuery(location.search.slice(1));

if (search.environment === 'development' ||
location.hostname === 'localhost' &&
search.environment !== 'production') {
if (!(config.apiOrigin = config.apiOrigins.development)) {
let port = +('GA'.split('').reduce((p, c) =>
p + c.charCodeAt().toString(16), '')
);
config.apiOrigin = `http://localhost:${port}`;
}
} else {
config.apiOrigin = config.apiOrigins.production;
}
};

module.exports = setAPIOrigin;
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{
"name": "ga-wdi-boston.browser-template",
"name": "ga-wdi-boston.api-token-auth",
"version": "0.0.3",
"private": true,
"license": "MIT",
"license": {
"software": "GNU GPLv3",
"content": "CC­BY­NC­SA 4.0"
},
"dependencies": {
"jquery": "^3.1.1"
},
Expand All @@ -23,6 +26,7 @@
"grunt-jsonlint": "^1.1.0",
"grunt-nodemon": "^0.4.2",
"grunt-open": "^0.2.3",
"grunt-shell": "^2.1.0",
"grunt-webpack": "^1.0.18",
"handlebars": "^4.0.5",
"handlebars-loader": "^1.4.0",
Expand Down
Loading

0 comments on commit deb4fdc

Please sign in to comment.