Skip to content

Commit 090c1ec

Browse files
committed
add vue todo-2
1 parent b0be51b commit 090c1ec

27 files changed

Lines changed: 17932 additions & 0 deletions
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Start",
6+
"type": "node",
7+
"request": "launch",
8+
"program": "${workspaceRoot}/start.js",
9+
"stopOnEntry": false,
10+
"args": [],
11+
"cwd": "${workspaceRoot}",
12+
"preLaunchTask": null,
13+
"runtimeExecutable": null,
14+
"runtimeArgs": [
15+
"--nolazy", "--use_strict"
16+
],
17+
"env": {
18+
"NODE_ENV": "development"
19+
},
20+
"externalConsole": false,
21+
"sourceMaps": false,
22+
"outDir": null
23+
}
24+
]
25+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const Koa = require('koa');
2+
3+
const bodyParser = require('koa-bodyparser');
4+
5+
const controller = require('./controller');
6+
7+
const rest = require('./rest');
8+
9+
const app = new Koa();
10+
11+
const isProduction = process.env.NODE_ENV === 'production';
12+
13+
// log request URL:
14+
app.use(async (ctx, next) => {
15+
console.log(`Process ${ctx.request.method} ${ctx.request.url}...`);
16+
var
17+
start = new Date().getTime(),
18+
execTime;
19+
await next();
20+
execTime = new Date().getTime() - start;
21+
ctx.response.set('X-Response-Time', `${execTime}ms`);
22+
});
23+
24+
// static file support:
25+
let staticFiles = require('./static-files');
26+
app.use(staticFiles('/static/', __dirname + '/static'));
27+
28+
// parse request body:
29+
app.use(bodyParser());
30+
31+
// bind .rest() for ctx:
32+
app.use(rest.restify());
33+
34+
// add controllers:
35+
app.use(controller());
36+
37+
app.listen(3000);
38+
console.log('app started at port 3000...');
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
const fs = require('fs');
3+
4+
// add url-route in /controllers:
5+
6+
function addMapping(router, mapping) {
7+
for (var url in mapping) {
8+
if (url.startsWith('GET ')) {
9+
var path = url.substring(4);
10+
router.get(path, mapping[url]);
11+
console.log(`register URL mapping: GET ${path}`);
12+
} else if (url.startsWith('POST ')) {
13+
var path = url.substring(5);
14+
router.post(path, mapping[url]);
15+
console.log(`register URL mapping: POST ${path}`);
16+
} else if (url.startsWith('PUT ')) {
17+
var path = url.substring(4);
18+
router.put(path, mapping[url]);
19+
console.log(`register URL mapping: PUT ${path}`);
20+
} else if (url.startsWith('DELETE ')) {
21+
var path = url.substring(7);
22+
router.del(path, mapping[url]);
23+
console.log(`register URL mapping: DELETE ${path}`);
24+
} else {
25+
console.log(`invalid URL: ${url}`);
26+
}
27+
}
28+
}
29+
30+
function addControllers(router, dir) {
31+
var files = fs.readdirSync(__dirname + '/' + dir);
32+
var js_files = files.filter((f) => {
33+
return f.endsWith('.js');
34+
}, files);
35+
36+
for (var f of js_files) {
37+
console.log(`process controller: ${f}...`);
38+
let mapping = require(__dirname + '/' + dir + '/' + f);
39+
addMapping(router, mapping);
40+
}
41+
}
42+
43+
module.exports = function (dir) {
44+
let
45+
controllers_dir = dir || 'controllers',
46+
router = require('koa-router')();
47+
addControllers(router, controllers_dir);
48+
return router.routes();
49+
};
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
const APIError = require('../rest').APIError;
2+
3+
var gid = 0;
4+
5+
function nextId() {
6+
gid ++;
7+
return 't' + gid;
8+
}
9+
10+
var todos = [
11+
{
12+
id: nextId(),
13+
name: 'Learn Git',
14+
description: 'Learn how to use git as distributed version control'
15+
},
16+
{
17+
id: nextId(),
18+
name: 'Learn JavaScript',
19+
description: 'Learn JavaScript, Node.js, NPM and other libraries'
20+
},
21+
{
22+
id: nextId(),
23+
name: 'Learn Python',
24+
description: 'Learn Python, WSGI, asyncio and NumPy'
25+
},
26+
{
27+
id: nextId(),
28+
name: 'Learn Java',
29+
description: 'Learn Java, Servlet, Maven and Spring'
30+
}
31+
];
32+
33+
module.exports = {
34+
'GET /api/todos': async (ctx, next) => {
35+
ctx.rest({
36+
todos: todos
37+
});
38+
},
39+
40+
'POST /api/todos': async (ctx, next) => {
41+
var
42+
t = ctx.request.body,
43+
todo;
44+
if (!t.name || !t.name.trim()) {
45+
throw new APIError('invalid_input', 'Missing name');
46+
}
47+
if (!t.description || !t.description.trim()) {
48+
throw new APIError('invalid_input', 'Missing description');
49+
}
50+
todo = {
51+
id: nextId(),
52+
name: t.name.trim(),
53+
description: t.description.trim()
54+
};
55+
todos.push(todo);
56+
ctx.rest(todo);
57+
},
58+
59+
'PUT /api/todos/:id': async (ctx, next) => {
60+
var
61+
t = ctx.request.body,
62+
index = -1,
63+
i, todo;
64+
if (!t.name || !t.name.trim()) {
65+
throw new APIError('invalid_input', 'Missing name');
66+
}
67+
if (!t.description || !t.description.trim()) {
68+
throw new APIError('invalid_input', 'Missing description');
69+
}
70+
for (i=0; i<todos.length; i++) {
71+
if (todos[i].id === ctx.params.id) {
72+
index = i;
73+
break;
74+
}
75+
}
76+
if (index === -1) {
77+
throw new APIError('notfound', 'Todo not found by id: ' + ctx.params.id);
78+
}
79+
todo = todos[index];
80+
todo.name = t.name.trim();
81+
todo.description = t.description.trim();
82+
ctx.rest(todo);
83+
},
84+
85+
'DELETE /api/todos/:id': async (ctx, next) => {
86+
var i, index = -1;
87+
for (i=0; i<todos.length; i++) {
88+
if (todos[i].id === ctx.params.id) {
89+
index = i;
90+
break;
91+
}
92+
}
93+
if (index === -1) {
94+
throw new APIError('notfound', 'Todo not found by id: ' + ctx.params.id);
95+
}
96+
ctx.rest(todos.splice(index, 1)[0]);
97+
}
98+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "view-koa",
3+
"version": "1.0.0",
4+
"description": "koa 2 example with nunjucks as view",
5+
"main": "start.js",
6+
"scripts": {
7+
"start": "node --use_strict start.js"
8+
},
9+
"keywords": [
10+
"vue",
11+
"mvvm"
12+
],
13+
"author": "Michael Liao",
14+
"license": "Apache-2.0",
15+
"repository": {
16+
"type": "git",
17+
"url": "https://github.com/michaelliao/learn-javascript.git"
18+
},
19+
"dependencies": {
20+
"babel-core": "6.13.2",
21+
"babel-polyfill": "6.13.0",
22+
"babel-preset-es2015-node6": "0.3.0",
23+
"babel-preset-stage-3": "6.5.0",
24+
"koa": "2.0.0",
25+
"koa-bodyparser": "3.2.0",
26+
"koa-router": "7.0.0",
27+
"nunjucks": "2.4.2",
28+
"mime": "1.3.4",
29+
"mz": "2.4.0"
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module.exports = {
2+
APIError: function (code, message) {
3+
this.code = code || 'internal:unknown_error';
4+
this.message = message || '';
5+
},
6+
restify: (pathPrefix) => {
7+
pathPrefix = pathPrefix || '/api/';
8+
return async (ctx, next) => {
9+
if (ctx.request.path.startsWith(pathPrefix)) {
10+
console.log(`Process API ${ctx.request.method} ${ctx.request.url}...`);
11+
ctx.rest = (data) => {
12+
ctx.response.type = 'application/json';
13+
ctx.response.body = data;
14+
}
15+
try {
16+
await next();
17+
} catch (e) {
18+
console.log('Process API error...');
19+
ctx.response.status = 400;
20+
ctx.response.type = 'application/json';
21+
ctx.response.body = {
22+
code: e.code || 'internal:unknown_error',
23+
message: e.message || ''
24+
};
25+
}
26+
} else {
27+
await next();
28+
}
29+
};
30+
}
31+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
require('babel-core/register')({
2+
presets: ['stage-3']
3+
});
4+
5+
require('./app.js');
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const path = require('path');
2+
const mime = require('mime');
3+
const fs = require('mz/fs');
4+
5+
function staticFiles(url, dir) {
6+
return async (ctx, next) => {
7+
let rpath = ctx.request.path;
8+
if (rpath.startsWith(url)) {
9+
let fp = path.join(dir, rpath.substring(url.length));
10+
if (await fs.exists(fp)) {
11+
ctx.response.type = mime.lookup(rpath);
12+
ctx.response.body = await fs.readFile(fp);
13+
} else {
14+
ctx.response.status = 404;
15+
}
16+
} else {
17+
await next();
18+
}
19+
};
20+
}
21+
22+
module.exports = staticFiles;

0 commit comments

Comments
 (0)