binhend 1.1.12 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/backend.js +3 -0
- package/bin/frontend.js +3 -0
- package/bin/index.js +31 -0
- package/package.json +6 -2
- package/src/binh.js +10 -0
- package/src/binh.web.builder.js +113 -8
- package/src/component.build.js +52 -0
- package/src/component.file.js +115 -0
- package/src/component.format.js +51 -0
- package/example_api/config.js +0 -13
- package/example_api/index.js +0 -15
- package/example_api/routes/test/bb.js +0 -9
- package/example_api/routes/test/index.js +0 -13
- package/example_api/routes/test/some.js +0 -9
- package/example_api/routes/test.js +0 -13
- package/example_api/routes/testa.js +0 -13
- package/example_webcomp/components/AnUserInterface.js +0 -0
- package/example_webcomp/components/common/InputText.js +0 -24
- package/example_webcomp/components/common/Link.js +0 -16
- package/example_webcomp/components/common/Link2.js +0 -13
- package/example_webcomp/components/index.html +0 -18
- package/example_webcomp/components/index.js +0 -14
- package/example_webcomp/components/layouts/AppMainLayout.js +0 -22
- package/example_webcomp/components/layouts/AppToDos.js +0 -49
- package/example_webcomp/components/layouts/Link.js +0 -16
- package/example_webcomp/components/layouts/PageContent.js +0 -25
- package/example_webcomp/components/layouts/PageHeader.js +0 -49
- package/example_webcomp/components/layouts/ToDoItem.js +0 -26
- package/example_webcomp/components/services/AnyService.js +0 -6
- package/example_webcomp/components/services/ServiceToDos.js +0 -42
- package/example_webcomp/components/styles/ToDoItemStyle.js +0 -40
- package/example_webcomp/components/styles/ToDoItemStyle2.js +0 -2
- package/example_webcomp/components/styles/temp.css +0 -7
- package/example_webcomp/components/styles/todo.css +0 -31
- package/example_webcomp/components/styles/todo.css.js +0 -2
- package/example_webcomp/config.js +0 -13
- package/example_webcomp/index.js +0 -10
package/bin/backend.js
ADDED
package/bin/frontend.js
ADDED
package/bin/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// console.log('Welcome to the binh!');
|
|
3
|
+
// console.log('process.argv', process.argv);
|
|
4
|
+
|
|
5
|
+
const argves = process.argv;
|
|
6
|
+
const command = argves[2];
|
|
7
|
+
|
|
8
|
+
// switch (command) {
|
|
9
|
+
// case 'backend':
|
|
10
|
+
// console.log('Generate back-end structure...');
|
|
11
|
+
// break;
|
|
12
|
+
|
|
13
|
+
// case 'frontend':
|
|
14
|
+
// console.log('Generate front-end structure...');
|
|
15
|
+
// break;
|
|
16
|
+
|
|
17
|
+
// default:
|
|
18
|
+
// console.log('Unknown command...');
|
|
19
|
+
// break;
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
const map = {
|
|
23
|
+
backend: require('./backend'),
|
|
24
|
+
frontend: require('./frontend'),
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const handler = map[command];
|
|
28
|
+
|
|
29
|
+
if (handler) handler();
|
|
30
|
+
else console.log('Unknown command...');
|
|
31
|
+
|
package/package.json
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "binhend",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Nguyen Duc Binh",
|
|
7
7
|
"license": "UNLICENSED",
|
|
8
|
+
"bin": {
|
|
9
|
+
"binh": "./bin/index.js"
|
|
10
|
+
},
|
|
8
11
|
"scripts": {
|
|
9
12
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
10
13
|
"example-api": "node example_api PORT=5555",
|
|
11
|
-
"example-webcomp": "node example_webcomp"
|
|
14
|
+
"example-webcomp": "node example_webcomp",
|
|
15
|
+
"example-web2": "node example_web2"
|
|
12
16
|
},
|
|
13
17
|
"dependencies": {
|
|
14
18
|
"express": "^4.17.1"
|
package/src/binh.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
1
2
|
const path = require('path');
|
|
2
3
|
const Crypto = require('./cryptography');
|
|
3
4
|
|
|
@@ -30,6 +31,15 @@ function Binh() {
|
|
|
30
31
|
return rootpath;
|
|
31
32
|
};
|
|
32
33
|
|
|
34
|
+
this.remove = function(path, callbackError) {
|
|
35
|
+
try {
|
|
36
|
+
fs.rmSync(path, { recursive: true, force: true, maxRetries: 3, retryDelay: 1000 });
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
callbackError(error);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
33
43
|
function binh(modulePath) {
|
|
34
44
|
return modulePath == undefined ? module.exports : require(path.join(rootpath, modulePath));
|
|
35
45
|
};
|
package/src/binh.web.builder.js
CHANGED
|
@@ -2,8 +2,59 @@
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
4
|
const Component = require('./component');
|
|
5
|
+
const ComponentFormat = require('./component.format');
|
|
6
|
+
const ComponentBuild = require('./component.build');
|
|
5
7
|
|
|
6
8
|
function WebBuilder(binh, Binh) {
|
|
9
|
+
binh.context = function(module) {
|
|
10
|
+
var context = { module };
|
|
11
|
+
return {
|
|
12
|
+
context,
|
|
13
|
+
tag: tag.bind(context),
|
|
14
|
+
script: script.bind(context)
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function tag(tagNames) {
|
|
19
|
+
var tags = typeof tagNames === 'string' ? tagNames.split(/\s+/) : [];
|
|
20
|
+
var htmltags = this.component.htmltags;
|
|
21
|
+
htmltags.push.apply(htmltags, tags);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function script() {
|
|
25
|
+
var scripts = Array.from(arguments);
|
|
26
|
+
var links = this.component.links;
|
|
27
|
+
links.push.apply(links, scripts);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
binh.component = function(context, ui, service, style) {
|
|
31
|
+
var component = ui || service || style;
|
|
32
|
+
var type = ui && 'ui' || service && 'service' || style && 'style';
|
|
33
|
+
|
|
34
|
+
if (component == null) return;
|
|
35
|
+
|
|
36
|
+
context.component = component;
|
|
37
|
+
component.htmltags = [];
|
|
38
|
+
component.links = [];
|
|
39
|
+
|
|
40
|
+
binh.bundle(type, context.module, component);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
binh.final = function(module) {
|
|
44
|
+
var component = module.exports;
|
|
45
|
+
|
|
46
|
+
if (!(component instanceof Function)) return;
|
|
47
|
+
if (component && component.constructor !== Component) return;
|
|
48
|
+
|
|
49
|
+
module.children.forEach(function(child) {
|
|
50
|
+
child = child.exports;
|
|
51
|
+
if (child.constructor !== Component) return;
|
|
52
|
+
if (child.alias) {
|
|
53
|
+
component.vars[child.filename] = child.alias;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
7
58
|
binh.ui = function(module, component, htmltags, links) {
|
|
8
59
|
component.htmltags = htmltags;
|
|
9
60
|
component.links = links;
|
|
@@ -50,21 +101,75 @@ function WebBuilder(binh, Binh) {
|
|
|
50
101
|
this.alias = name;
|
|
51
102
|
}
|
|
52
103
|
|
|
53
|
-
Binh.web = function(
|
|
54
|
-
|
|
104
|
+
Binh.web = function(webPath, sourcePath, modulePath) {
|
|
105
|
+
switch (arguments.length) {
|
|
106
|
+
case 1:
|
|
107
|
+
Binh.webStatic(webPath);
|
|
108
|
+
break;
|
|
55
109
|
|
|
56
|
-
|
|
57
|
-
|
|
110
|
+
case 2:
|
|
111
|
+
Binh.webApp(sourcePath, webPath);
|
|
112
|
+
break;
|
|
58
113
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
114
|
+
default:
|
|
115
|
+
if (arguments.length > 2) {
|
|
116
|
+
Binh.webApp(webPath, sourcePath, modulePath);
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
62
119
|
}
|
|
63
120
|
|
|
64
|
-
Binh
|
|
121
|
+
return Binh;
|
|
122
|
+
};
|
|
65
123
|
|
|
124
|
+
Binh.webStatic = function(webPath) {
|
|
125
|
+
if (!isString(webPath)) return Binh;
|
|
126
|
+
Binh.web.value = getAbsolutePaths(webPath).web;
|
|
66
127
|
return Binh;
|
|
67
128
|
};
|
|
129
|
+
|
|
130
|
+
Binh.webApp = function(sourcePath, webPath, modulePath) {
|
|
131
|
+
if (!isString(sourcePath)) return Binh;
|
|
132
|
+
|
|
133
|
+
modulePath = isString(modulePath) ? modulePath : isString(webPath) ? webPath : null;
|
|
134
|
+
|
|
135
|
+
var { source, web, module } = getAbsolutePaths(webPath, sourcePath, modulePath);
|
|
136
|
+
|
|
137
|
+
ComponentFormat.generate(source, web, () => ComponentBuild.generate(source, web, module));
|
|
138
|
+
|
|
139
|
+
Binh.web.value = web;
|
|
140
|
+
|
|
141
|
+
return Binh;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
Binh.webModule = function(sourcePath, modulePath) {
|
|
145
|
+
if (!isString(sourcePath)) return Binh;
|
|
146
|
+
|
|
147
|
+
var { source, module } = getAbsolutePaths(null, sourcePath, modulePath);
|
|
148
|
+
|
|
149
|
+
ComponentFormat.generate(source, module);
|
|
150
|
+
|
|
151
|
+
return Binh;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
function getAbsolutePaths(webPath, sourcePath, modulePath) {
|
|
155
|
+
webPath = isString(webPath) ? webPath : 'web/app';
|
|
156
|
+
modulePath = isString(modulePath) ? modulePath : 'web/modules';
|
|
157
|
+
|
|
158
|
+
var rootpath = Binh.getRootpath(),
|
|
159
|
+
sourcePathAbsolute = isString(sourcePath) ? path.join(rootpath, sourcePath) : null,
|
|
160
|
+
webPathAbsolute = path.join(rootpath, webPath),
|
|
161
|
+
modulePathAbsolute = path.join(rootpath, modulePath);
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
web: webPathAbsolute,
|
|
165
|
+
source: sourcePathAbsolute,
|
|
166
|
+
module: modulePathAbsolute
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function isString(input) {
|
|
171
|
+
return typeof input === 'string';
|
|
172
|
+
}
|
|
68
173
|
}
|
|
69
174
|
|
|
70
175
|
module.exports = {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
const { parse } = require('path');
|
|
3
|
+
const { scanNestedFiles, cloneFile, writeToFile } = require('./component.file');
|
|
4
|
+
const CodeFormat = require('./code');
|
|
5
|
+
const Component = require('./component');
|
|
6
|
+
|
|
7
|
+
// TODO
|
|
8
|
+
// [-] Able to minify/beautify generated files
|
|
9
|
+
|
|
10
|
+
function generate(sourceRootPath, outputRootPath, stageRootPath) {
|
|
11
|
+
if (sourceRootPath == undefined || outputRootPath == undefined) return;
|
|
12
|
+
stageRootPath = stageRootPath || outputRootPath;
|
|
13
|
+
console.info('[BINHEND][COMPONENT] Build web components from:', stageRootPath);
|
|
14
|
+
console.info('[BINHEND][COMPONENT] to:', outputRootPath);
|
|
15
|
+
|
|
16
|
+
scanNestedFiles(stageRootPath, (file) => {
|
|
17
|
+
var fileSourcePath = file.path.replace(stageRootPath, sourceRootPath);
|
|
18
|
+
var fileOutputPath = file.path.replace(stageRootPath, outputRootPath);
|
|
19
|
+
|
|
20
|
+
if (parse(file.name).ext !== '.js') {
|
|
21
|
+
return cloneFile(fileSourcePath, fileOutputPath);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
var component = require(file.path);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return cloneFile(fileSourcePath, fileOutputPath);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!(component instanceof Function) || component.constructor !== Component) {
|
|
32
|
+
return cloneFile(fileSourcePath, fileOutputPath);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var code = joinCodes(component, outputRootPath);
|
|
36
|
+
|
|
37
|
+
writeToFile(fileOutputPath, code);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function joinCodes(component, rootPath) {
|
|
42
|
+
var fullcode = CodeFormat.prequire(component, [
|
|
43
|
+
CodeFormat.bundle(component, rootPath),
|
|
44
|
+
CodeFormat.htmltags(component)
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
return fullcode;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = {
|
|
51
|
+
generate
|
|
52
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
|
|
2
|
+
const { readdir, statSync, copyFile, writeFile } = require('fs');
|
|
3
|
+
const { join } = require('path');
|
|
4
|
+
|
|
5
|
+
// TODO
|
|
6
|
+
// [-] Enhance code by removing sync logics (except for existsSync, mkdirSync): readdir, readFileSync, (statSync?)
|
|
7
|
+
|
|
8
|
+
function getItemInfo(itemPath) {
|
|
9
|
+
var info = {};
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
var stat = statSync(itemPath);
|
|
13
|
+
info.isFile = stat.isFile();
|
|
14
|
+
info.isDirectory = stat.isDirectory();
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
console.error('Failed getting info for item:', path, error);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return info;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function scanItems(path, callback) {
|
|
24
|
+
readdir(path, (error, dirents) => {
|
|
25
|
+
if (error) return console.error('Failed reading directory', path, error);
|
|
26
|
+
|
|
27
|
+
dirents.forEach((dirent) => {
|
|
28
|
+
var fullPath = join(path, dirent),
|
|
29
|
+
info = getItemInfo(fullPath);
|
|
30
|
+
|
|
31
|
+
callback({
|
|
32
|
+
name: dirent,
|
|
33
|
+
path: fullPath,
|
|
34
|
+
isFile: info.isFile,
|
|
35
|
+
isDirectory: info.isDirectory
|
|
36
|
+
}, false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (callback.length > 1) callback(null, true);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function scanNestedItems(path, callback, counter) {
|
|
44
|
+
counter = counter || { current: 1 };
|
|
45
|
+
|
|
46
|
+
scanItems(path, (item, done) => {
|
|
47
|
+
if (done) {
|
|
48
|
+
--counter.current;
|
|
49
|
+
if (counter.current > 0) return;
|
|
50
|
+
else if (onComplete(done, callback)) return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
callback(item, false);
|
|
54
|
+
|
|
55
|
+
if (item.isDirectory) {
|
|
56
|
+
++counter.current;
|
|
57
|
+
scanNestedItems(item.path, callback, counter);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function scanFiles(path, callback) {
|
|
63
|
+
scanItems(path, (item, done) => {
|
|
64
|
+
if (onComplete(done, callback)) return;
|
|
65
|
+
if (item.isFile) callback(item, false);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function scanNestedFiles(path, callback) {
|
|
70
|
+
scanNestedItems(path, (item, done) => {
|
|
71
|
+
if (onComplete(done, callback)) return;
|
|
72
|
+
if (item.isFile) callback(item, false);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function onComplete(done, callback) {
|
|
77
|
+
if (done && callback.length > 1) {
|
|
78
|
+
callback(null, done);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (done) return true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function cloneFile(filepath, outpath) {
|
|
85
|
+
copyFile(filepath, outpath, function(error) {
|
|
86
|
+
if (error) {
|
|
87
|
+
console.error(`[BINHEND][COMPONENT] Failed copying file from:`, filepath);
|
|
88
|
+
console.error(`[BINHEND][COMPONENT] to:`, outpath);
|
|
89
|
+
console.error('[BINHEND][COMPONENT] Error details:', error);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function writeToFile(fileOutputPath, content) {
|
|
95
|
+
writeFile(fileOutputPath, content, { encoding: 'utf8', flag: 'w' }, function(error) {
|
|
96
|
+
if (error) {
|
|
97
|
+
printError('Failed writing file', filepath, error);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function printError(message, id, error) {
|
|
103
|
+
console.error(`[BINHEND][COMPONENT] ${message}:`, id);
|
|
104
|
+
console.error('[BINHEND][COMPONENT] Error details:', error);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module.exports = {
|
|
108
|
+
scanItems,
|
|
109
|
+
scanNestedItems,
|
|
110
|
+
scanFiles,
|
|
111
|
+
scanNestedFiles,
|
|
112
|
+
cloneFile,
|
|
113
|
+
writeToFile,
|
|
114
|
+
printError
|
|
115
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
|
|
2
|
+
const { writeFileSync, existsSync, mkdirSync, readFileSync } = require('fs');
|
|
3
|
+
const { dirname, parse } = require('path');
|
|
4
|
+
const { scanNestedFiles, cloneFile, printError } = require('./component.file');
|
|
5
|
+
|
|
6
|
+
// TODO
|
|
7
|
+
// [-] Enhance code by removing sync logics (except for existsSync, mkdirSync): readdir, readFileSync, (statSync?)
|
|
8
|
+
|
|
9
|
+
const PREFIX_CODE =
|
|
10
|
+
`var { context, tag, script } = binh.context(module);
|
|
11
|
+
binh.component(context, ui, service, style);
|
|
12
|
+
var ui = null, service = null, style = null;\r\n`;
|
|
13
|
+
|
|
14
|
+
function generate(sourceRootPath, outputRootPath, callbackDone) {
|
|
15
|
+
if (sourceRootPath == undefined || outputRootPath == undefined) return;
|
|
16
|
+
console.log('[BINHEND][COMPONENT] Format files from:', sourceRootPath);
|
|
17
|
+
console.log('[BINHEND][COMPONENT] to:', outputRootPath);
|
|
18
|
+
|
|
19
|
+
scanNestedFiles(sourceRootPath, (file, done) => {
|
|
20
|
+
if (done) return callbackDone instanceof Function ? callbackDone() : null;
|
|
21
|
+
|
|
22
|
+
var fileSourcePath = file.path;
|
|
23
|
+
var fileOutputPath = fileSourcePath.replace(sourceRootPath, outputRootPath);
|
|
24
|
+
|
|
25
|
+
ensureDirectoryExistence(fileOutputPath);
|
|
26
|
+
|
|
27
|
+
if (parse(file.name).ext !== '.js') {
|
|
28
|
+
return cloneFile(fileSourcePath, fileOutputPath);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
var content = readFileSync(fileSourcePath, { encoding: 'utf8', flag: 'r' });
|
|
33
|
+
var code = PREFIX_CODE + content + '\r\n;binh.final(module);';
|
|
34
|
+
writeFileSync(fileOutputPath, code, { encoding: 'utf8', flag: 'w' });
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
printError('Failed formatting file:', fileSourcePath, error);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function ensureDirectoryExistence(filePath) {
|
|
43
|
+
var dirPath = dirname(filePath);
|
|
44
|
+
if (existsSync(dirPath)) return true;
|
|
45
|
+
ensureDirectoryExistence(dirPath);
|
|
46
|
+
mkdirSync(dirPath);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = {
|
|
50
|
+
generate
|
|
51
|
+
};
|
package/example_api/config.js
DELETED
package/example_api/index.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { Binh } = require('../src/binh');
|
|
4
|
-
|
|
5
|
-
new Binh()
|
|
6
|
-
.id()
|
|
7
|
-
.global('config', binh.config)
|
|
8
|
-
.config('config')
|
|
9
|
-
.api('routes')
|
|
10
|
-
.cors()
|
|
11
|
-
.port('PORT')
|
|
12
|
-
.cluster.fork(0)
|
|
13
|
-
.start(function(server, configs) {
|
|
14
|
-
console.log('### START >>> configs:', configs);
|
|
15
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const { router, get, post } = binh.router(module);
|
|
2
|
-
|
|
3
|
-
get('/', function(req, res) {
|
|
4
|
-
res.json({ path:'/', dir: __dirname, file: __filename });
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
get('/sub', function(req, res) {
|
|
8
|
-
res.json({ path:'/sub', dir: __dirname, file: __filename });
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
get('/goo', function(req, res) {
|
|
12
|
-
res.json({ path:'/goo', dir: __dirname, file: __filename });
|
|
13
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const { get } = binh.router(module);
|
|
2
|
-
|
|
3
|
-
get('/', function(req, res) {
|
|
4
|
-
res.json({ path:'/', dir: __dirname, file: __filename });
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
get('/bb', function(req, res) {
|
|
8
|
-
res.json({ path:'/bb', dir: __dirname, file: __filename });
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
get('/cc', function(req, res) {
|
|
12
|
-
res.json({ path:'/cc', dir: __dirname, file: __filename });
|
|
13
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const { router, get, post } = binh.router(module);
|
|
2
|
-
|
|
3
|
-
get('/', function(req, res) {
|
|
4
|
-
res.json({ path:'/', dir: __dirname, file: __filename });
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
get('/sub', function(req, res) {
|
|
8
|
-
res.json({ path:'/sub', dir: __dirname, file: __filename });
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
get('/gaa', function(req, res) {
|
|
12
|
-
res.json({ path:'/gaa', dir: __dirname, file: __filename });
|
|
13
|
-
});
|
|
File without changes
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
require('./../services/ServiceToDos').as('Toto');
|
|
3
|
-
|
|
4
|
-
function main() {
|
|
5
|
-
// var addTodoItem = Toto.debounce('add', 1500, true);
|
|
6
|
-
|
|
7
|
-
// setTimeout(function() {
|
|
8
|
-
// addTodoItem('over 10kms');
|
|
9
|
-
// }, 10000);
|
|
10
|
-
|
|
11
|
-
var inputbox = input({ type: 'text', placeholder: 'Enter to-do item' });
|
|
12
|
-
|
|
13
|
-
var submit = inputbox.action('submit');
|
|
14
|
-
|
|
15
|
-
inputbox.on('keypress', function (event) {
|
|
16
|
-
if (event.key === "Enter") {
|
|
17
|
-
submit(inputbox.element.value);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
return inputbox;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
binh.ui(module, main, ['input']);
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<title>Binh Demo</title>
|
|
5
|
-
<meta charset="utf-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
-
<!-- <link rel="stylesheet" href="/lib/bootstrap.3.4.1.min.css"> -->
|
|
8
|
-
<!-- <link rel="stylesheet" href="style.css"> -->
|
|
9
|
-
<!-- <script src="/lib/jquery.3.5.1.min.js"></script>
|
|
10
|
-
<script src="/lib/bootstrap.3.4.1.min.js"></script> -->
|
|
11
|
-
|
|
12
|
-
<script src="http://localhost:1300/dev/binh.min.js"></script>
|
|
13
|
-
<!-- <script src="https://binhjs.pages.dev/dist/binh.min.js"></script> -->
|
|
14
|
-
<!-- <script src="https://cdn.jsdelivr.net/gh/penciless/binhjs/dist/binh.min.js"></script> -->
|
|
15
|
-
<script src="/index.js"></script>
|
|
16
|
-
</head>
|
|
17
|
-
<body></body>
|
|
18
|
-
</html>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
Binh.script('https://cdn.jsdelivr.net/gh/jquery/jquery@3.5.1/dist/jquery.min.js', function() {
|
|
3
|
-
Binh.link('https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css');
|
|
4
|
-
Binh.script('https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js');
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
Binh.Router.onload(function() {
|
|
8
|
-
console.log('#### ON ROUTING !!!');
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
Binh({
|
|
12
|
-
'': '/layouts/AppMainLayout.js',
|
|
13
|
-
'/todos': '/layouts/AppToDos.js'
|
|
14
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
require('./PageHeader');
|
|
3
|
-
require('./PageContent');
|
|
4
|
-
require('./../services/AnyService');
|
|
5
|
-
|
|
6
|
-
function AppMainLayout() {
|
|
7
|
-
var MainLayout = div({ id: 'app-main-layout' });
|
|
8
|
-
|
|
9
|
-
MainLayout(
|
|
10
|
-
PageHeader,
|
|
11
|
-
PageContent,
|
|
12
|
-
function (thisEl) {
|
|
13
|
-
setTimeout(function() {
|
|
14
|
-
console.log('>>> App Main Layout:', thisEl);
|
|
15
|
-
}, 1000);
|
|
16
|
-
}
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
return MainLayout;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
binh.ui(module, AppMainLayout, ['div'], ['https://code.jquery.com/jquery-3.7.0.min.js', 'https://code.jquery.com/jquery-3.7.0.min.js']);
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
require('./PageHeader');
|
|
3
|
-
// require('./ToDoItem');
|
|
4
|
-
require('./../common/InputText');
|
|
5
|
-
require('./Link');
|
|
6
|
-
require('./../services/ServiceToDos').as('Dodo');
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
function main() {
|
|
10
|
-
var ServiceToDos = Dodo;
|
|
11
|
-
// var PageHeader = Binh.ui('/layouts/PageHeader.js');
|
|
12
|
-
var ToDoItem = Binh.ui('/layouts/ToDoItem.js');
|
|
13
|
-
// var addTodoItem = ServiceToDos.does('add');
|
|
14
|
-
// var addTodoItem = ServiceToDos.debounce('add', 1500); // trailing only
|
|
15
|
-
var addTodoItem = ServiceToDos.debounce('add', 1500, true); // both leading & trailing
|
|
16
|
-
// var addTodoItem = ServiceToDos.debounce('add', 1500, true, true); // leading only
|
|
17
|
-
// var addTodoItem = ServiceToDos.throttle('add', 1500);
|
|
18
|
-
// var addTodoItem = ServiceToDos.once('add', 1500);
|
|
19
|
-
|
|
20
|
-
var inputbox = InputText().when('submit', addTodoItem);
|
|
21
|
-
|
|
22
|
-
var todolist = div({ class: 'todo-items' });
|
|
23
|
-
|
|
24
|
-
todolist.subscribe('todos', function(data) {
|
|
25
|
-
todolist.empty();
|
|
26
|
-
data.forEach(function(datum) {
|
|
27
|
-
todolist(
|
|
28
|
-
ToDoItem(datum).when('remove', ServiceToDos.instant('remove'))
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
var maindiv = div({ class: 'container' });
|
|
34
|
-
var left_section = div({ id: 'left-section' })('left section')(PageHeader);
|
|
35
|
-
var right_section = div({ id: 'right-section' })('right section');
|
|
36
|
-
|
|
37
|
-
maindiv(
|
|
38
|
-
left_section,
|
|
39
|
-
right_section(
|
|
40
|
-
div('To-Do List'),
|
|
41
|
-
inputbox,
|
|
42
|
-
todolist
|
|
43
|
-
)
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
return maindiv;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
binh.ui(module, main, ['div', 'span'], ['https://code.jquery.com/jquery-3.7.0.min.js']);
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function Link() {
|
|
4
|
-
var { a } = Binh.element('a');
|
|
5
|
-
|
|
6
|
-
var text = arguments[0];
|
|
7
|
-
var path = arguments[1];
|
|
8
|
-
|
|
9
|
-
var link = a(text).on('click', function() {
|
|
10
|
-
Binh.Router.navigate(path);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
return link;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
binh.ui(module, Link);
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
function PageContent() {
|
|
3
|
-
var { Router } = Binh;
|
|
4
|
-
|
|
5
|
-
var PageContent = div({ id: 'page-content' });
|
|
6
|
-
|
|
7
|
-
PageContent(
|
|
8
|
-
new Router({
|
|
9
|
-
'': div('default work!'),
|
|
10
|
-
'/abc': div('abc work!'),
|
|
11
|
-
'/haha': trans('haha work!')
|
|
12
|
-
})
|
|
13
|
-
)
|
|
14
|
-
(
|
|
15
|
-
function (thisEl) {
|
|
16
|
-
setTimeout(function() {
|
|
17
|
-
console.log('>>> Page Content:', thisEl);
|
|
18
|
-
}, 1000);
|
|
19
|
-
}
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
return PageContent;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
binh.ui(module, PageContent, ['div', 'trans'], ['https://code.jquery.com/jquery-3.7.0.min.js']);
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
var { Link } = require('./../common/Link');
|
|
3
|
-
|
|
4
|
-
function PageHeader() {
|
|
5
|
-
// var Link = Binh.ui('/common/Link2.js');
|
|
6
|
-
|
|
7
|
-
var PageHeader = div({ id: 'page-header' });
|
|
8
|
-
|
|
9
|
-
PageHeader(
|
|
10
|
-
div({ class: 'container' })(
|
|
11
|
-
div({ class: 'row' })(
|
|
12
|
-
nav({ class: 'navbar navbar-default' })(
|
|
13
|
-
div({ class: 'container-fluid' })([
|
|
14
|
-
div({ class: 'navbar-header' })(
|
|
15
|
-
a({ class: 'navbar-brand', href: '#' })(
|
|
16
|
-
'Website Name'
|
|
17
|
-
)
|
|
18
|
-
),
|
|
19
|
-
ul({ class: 'nav navbar-nav' })(
|
|
20
|
-
li({ class: 'active' })(
|
|
21
|
-
Link('Home', '/')
|
|
22
|
-
),
|
|
23
|
-
li(
|
|
24
|
-
Link('Abc', '/abc')
|
|
25
|
-
),
|
|
26
|
-
li(
|
|
27
|
-
Link('Haha', '/haha')
|
|
28
|
-
),
|
|
29
|
-
li(
|
|
30
|
-
a('Page 3')
|
|
31
|
-
)
|
|
32
|
-
)
|
|
33
|
-
])
|
|
34
|
-
)
|
|
35
|
-
)
|
|
36
|
-
),
|
|
37
|
-
function (thisEl) {
|
|
38
|
-
setTimeout(function() {
|
|
39
|
-
console.log('>>> Page Header:', thisEl);
|
|
40
|
-
}, 1000);
|
|
41
|
-
}
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
return PageHeader;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
var htmltags = ['div', 'nav', 'ul', 'li', 'a'];
|
|
48
|
-
|
|
49
|
-
binh.ui(module, PageHeader, htmltags);
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
// require('./../styles/ToDoItemStyle');
|
|
3
|
-
require('./../styles/ToDoItemStyle2');
|
|
4
|
-
// require('../styles/todo.css.js');
|
|
5
|
-
|
|
6
|
-
function main(props) {
|
|
7
|
-
// var ToDoItemStyle = Binh.style('/styles/todo.css');
|
|
8
|
-
|
|
9
|
-
var todoitem = div({ style: 'margin: 3px;' });
|
|
10
|
-
var removeToDoItem = todoitem.action('remove');
|
|
11
|
-
|
|
12
|
-
var remove_button = span({ class: 'btn-remove' })('X');
|
|
13
|
-
|
|
14
|
-
remove_button.on('click', function() {
|
|
15
|
-
removeToDoItem(props.id);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
todoitem(span(props.text), span('-------'), remove_button);
|
|
19
|
-
|
|
20
|
-
// return todoitem.style(ToDoItemStyle);
|
|
21
|
-
// return todoitem.style('styles/todo.css');
|
|
22
|
-
return todoitem.style(ToDoItemStyle2);
|
|
23
|
-
// return todoitem.style(todo);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
binh.ui(module, main, ['div', 'span']);
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
binh.service(module, function(define, state, http) {
|
|
3
|
-
var todos = state.as('todos');
|
|
4
|
-
|
|
5
|
-
todos.schema(function(resolve) {
|
|
6
|
-
new http(api('get'))
|
|
7
|
-
.get(function(response) {
|
|
8
|
-
resolve(parseResponse(response));
|
|
9
|
-
});
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
function handleResponse(response) {
|
|
13
|
-
todos.set(parseResponse(response));
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function parseResponse(response) {
|
|
17
|
-
var todoitems = [];
|
|
18
|
-
|
|
19
|
-
Object.keys(response).forEach(function(key) {
|
|
20
|
-
var each = response[key];
|
|
21
|
-
todoitems.push({ id: key, text: each.text });
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
return todoitems;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
define('add', function(value) {
|
|
28
|
-
new http(api('add'))
|
|
29
|
-
.body({ text: value })
|
|
30
|
-
.post(handleResponse);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
define('remove', function(id) {
|
|
34
|
-
new http(api('remove'))
|
|
35
|
-
.body({ id: id })
|
|
36
|
-
.post(handleResponse);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
function api(relative_url) {
|
|
40
|
-
return 'https://todolist-of-binh.fly.dev/todos/' + relative_url;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
binh.style(module, function(css) {
|
|
3
|
-
// css('@charset "utf-8";');
|
|
4
|
-
|
|
5
|
-
css(`@import url("styles/temp.css");`);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
css('.btn-remove', [
|
|
9
|
-
'color: purple;',
|
|
10
|
-
'margin-left: 10px'
|
|
11
|
-
]);
|
|
12
|
-
|
|
13
|
-
css(
|
|
14
|
-
`@media (min-width: 800px) {
|
|
15
|
-
.btn-remove {
|
|
16
|
-
color: red;
|
|
17
|
-
margin-left: '15px';
|
|
18
|
-
}
|
|
19
|
-
}`
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
css(`
|
|
23
|
-
@keyframes slidein {
|
|
24
|
-
from {
|
|
25
|
-
transform: translateX(0%);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
to {
|
|
29
|
-
transform: translateX(100%);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
`);
|
|
33
|
-
|
|
34
|
-
css(`
|
|
35
|
-
@page {
|
|
36
|
-
size: 8.5in 9in;
|
|
37
|
-
margin-top: 4in;
|
|
38
|
-
}
|
|
39
|
-
`);
|
|
40
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
@charset "utf-8";
|
|
2
|
-
|
|
3
|
-
@import url("/styles/temp.css");
|
|
4
|
-
|
|
5
|
-
/* .btn-remove {
|
|
6
|
-
color: blue;
|
|
7
|
-
margin-left: '15px';
|
|
8
|
-
} */
|
|
9
|
-
|
|
10
|
-
@media (min-width: 800px) {
|
|
11
|
-
|
|
12
|
-
.btn-remove {
|
|
13
|
-
color: red;
|
|
14
|
-
margin-left: '15px';
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@keyframes slidein {
|
|
19
|
-
from {
|
|
20
|
-
transform: translateX(0%);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
to {
|
|
24
|
-
transform: translateX(100%);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@page {
|
|
29
|
-
size: 8.5in 9in;
|
|
30
|
-
margin-top: 4in;
|
|
31
|
-
}
|