Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 090c1ec

Browse filesBrowse files
committed
add vue todo-2
1 parent b0be51b commit 090c1ec
Copy full SHA for 090c1ec
Expand file treeCollapse file tree

27 files changed

+17932
-0
lines changed
Open diff view settings
Collapse file
+25Lines 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+
}
Collapse file
+38Lines 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...');
Collapse file
+49Lines 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+
};
Collapse file
+98Lines 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+
}
Collapse file
+31Lines 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+
}
Collapse file
+31Lines 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+
};
Collapse file
+5Lines 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');
Collapse file
+22Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.