binhend 2.2.8 → 2.2.10
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/demo.js +9 -7
- package/index.js +6 -3
- package/package.json +1 -1
- package/packages/config/package.json +2 -1
- package/packages/config/src/configuration.js +3 -2
- package/packages/core/src/server.js +1 -4
- package/packages/middlewares/package.json +1 -0
- package/packages/middlewares/src/cors.js +5 -4
- package/packages/module-alias/index.js +1 -1
- package/packages/module-alias/package.json +1 -4
- package/packages/module-alias/src/alias-cjs-loader.js +12 -6
- package/packages/types/src/typeCheck.js +74 -56
- package/packages/web/package.json +1 -0
- package/packages/web/src/WebBuild.js +10 -12
- package/packages/web/src/component.js +2 -107
package/demo.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
|
|
2
|
-
const { HttpCodes, ConfigLoader, HttpError, validation: must } = require('./index');
|
|
3
|
-
const path = require('path');
|
|
2
|
+
// const { HttpCodes, ConfigLoader, HttpError, validation: must } = require('./index');
|
|
3
|
+
// const path = require('path');
|
|
4
4
|
|
|
5
|
-
function Testa(input) {
|
|
6
|
-
|
|
7
|
-
}
|
|
5
|
+
// function Testa(input) {
|
|
6
|
+
// this.a = must.Function(input.a);
|
|
7
|
+
// }
|
|
8
8
|
|
|
9
|
-
var p = new Testa();
|
|
9
|
+
// var p = new Testa();
|
|
10
10
|
|
|
11
|
-
p.a();
|
|
11
|
+
// p.a();
|
|
12
|
+
|
|
13
|
+
require('./packages/module-alias');
|
package/index.js
CHANGED
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
//___ Run scripts ___//
|
|
12
|
+
const moduleAlias = require('./packages/module-alias'); // path alias '@' for requiring modules: require('@/any/path') - use jsconfig.json
|
|
13
|
+
moduleAlias.paths['@binhend/*'] = [ path.join(__dirname, './packages') ]; // set path alias '@binhend' for all packages to call each others when 'npm install' in another project
|
|
14
|
+
|
|
9
15
|
const server = require('./packages/core/src/server');
|
|
10
16
|
const Router = require('./packages/core/src/Router');
|
|
11
17
|
const { routes } = require('./packages/core/src/routes');
|
|
@@ -33,9 +39,6 @@ const validation = require('./packages/validation/src/typeValidation');
|
|
|
33
39
|
const { WebBuild } = require('./packages/web/src/WebBuild');
|
|
34
40
|
const { binh } = require('./packages/web/src/component.method');
|
|
35
41
|
|
|
36
|
-
//___ Run scripts ___//
|
|
37
|
-
require('./packages/module-alias'); //--- alias path '@' for requiring modules: require('@/any/path')
|
|
38
|
-
|
|
39
42
|
module.exports = {
|
|
40
43
|
server, routes, Router,
|
|
41
44
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { isEmptyArray, isArray, isObject,
|
|
3
|
+
const { isEmptyArray, isArray, isObject, isNullish, isString } = require('@binhend/types');
|
|
4
|
+
const must = require('@binhend/validation');
|
|
4
5
|
|
|
5
6
|
// @ts-ignore
|
|
6
7
|
function ConfigLoader(configObject, { rootPath } = {}) {
|
|
7
8
|
const configs = configObject || {};
|
|
8
9
|
|
|
9
|
-
rootPath =
|
|
10
|
+
rootPath = must.String(rootPath, { default: require.main.path });
|
|
10
11
|
|
|
11
12
|
function getConfigPosition(key) {
|
|
12
13
|
return key == undefined ? configs : configs[key] || (configs[key] = {});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
const { isArray
|
|
2
|
+
const { isArray } = require('@binhend/types');
|
|
3
|
+
const must = require('@binhend/validation');
|
|
3
4
|
|
|
4
5
|
const defaultOptions = {
|
|
5
6
|
origins: [],
|
|
@@ -24,7 +25,7 @@ module.exports = (options) => {
|
|
|
24
25
|
// Parse options
|
|
25
26
|
var { origins, credentials, methods, preflightContinue, optionsSuccessStatus, exposedHeaders, allowHeaders, maxAge } = Object.assign({}, defaultOptions, options);
|
|
26
27
|
|
|
27
|
-
const allowedOrigins =
|
|
28
|
+
const allowedOrigins = must.Array(origins, { default: [] });
|
|
28
29
|
|
|
29
30
|
// Create a new middleware
|
|
30
31
|
return function (req, res, next) {
|
|
@@ -52,11 +53,11 @@ module.exports = (options) => {
|
|
|
52
53
|
addHeader(res, 'Access-Control-Allow-Headers', arrayToString(allowHeaders));
|
|
53
54
|
|
|
54
55
|
// Cache preflight response
|
|
55
|
-
addHeader(res, 'Access-Control-Max-Age',
|
|
56
|
+
addHeader(res, 'Access-Control-Max-Age', must.Number(maxAge, { default: 0 }));
|
|
56
57
|
|
|
57
58
|
// Handle preflight OPTIONS request
|
|
58
59
|
if (req.method === 'OPTIONS' && !preflightContinue) {
|
|
59
|
-
var statusCode =
|
|
60
|
+
var statusCode = must.Number(optionsSuccessStatus, { default: 204 }); // 204 - No Content
|
|
60
61
|
return res.sendStatus(statusCode);
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const DefaultModule = require('module');
|
|
5
|
-
const { binh } = require('@binhend/web'); // TODO handle this 'binh' object again, more properly, workspaces will not recognize global 'binh'
|
|
6
5
|
|
|
7
6
|
// Protect against improperly customized module constructors by other frameworks/packages
|
|
8
7
|
const Module = module.constructor.length > 1 ? module.constructor : DefaultModule;
|
|
@@ -22,11 +21,17 @@ catch (error) {
|
|
|
22
21
|
const baseUrl = jsconfig?.compilerOptions?.baseUrl || '.';
|
|
23
22
|
const paths = jsconfig?.compilerOptions?.paths || {};
|
|
24
23
|
|
|
24
|
+
const settings = { // for external modification in run-time
|
|
25
|
+
paths,
|
|
26
|
+
webSourcePath: null,
|
|
27
|
+
webModulePath: null
|
|
28
|
+
};
|
|
29
|
+
|
|
25
30
|
/** Step 2: Create an alias map with all possible paths */
|
|
26
31
|
const aliasMap = {};
|
|
27
32
|
|
|
28
33
|
for (const alias in paths) {
|
|
29
|
-
const aliasPath = alias.replace('/*', ''); // Strip the '/*' for matching
|
|
34
|
+
const aliasPath = alias.replace('/*', ''); // Strip the '/*' for matching // TODO write regex for ending with /*
|
|
30
35
|
const originalPaths = paths[alias]; // Get the array of paths
|
|
31
36
|
|
|
32
37
|
aliasMap[aliasPath] = originalPaths.map((originalPath) => {
|
|
@@ -46,10 +51,9 @@ Module._resolveFilename = function (request, parent, isMain, options) {
|
|
|
46
51
|
// Construct the new request path
|
|
47
52
|
var newRequest = request.replace(alias, resolvedPath);
|
|
48
53
|
|
|
49
|
-
// BINHEND web components load each others
|
|
50
|
-
if (parent.filename.startsWith(
|
|
51
|
-
|
|
52
|
-
newRequest = newRequest.replace(binh.webSourcePath, binh.webModulePath);
|
|
54
|
+
// BINHEND web components load each others still requiring src paths (src file paths), not module paths (formatted file paths)
|
|
55
|
+
if (parent.filename.startsWith(settings.webModulePath)) {
|
|
56
|
+
newRequest = newRequest.replace(settings.webSourcePath, settings.webModulePath);
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
// Attempt to resolve the new request
|
|
@@ -65,3 +69,5 @@ Module._resolveFilename = function (request, parent, isMain, options) {
|
|
|
65
69
|
// Fallback to the original resolution if no alias matches
|
|
66
70
|
return originalResolveFilename.call(this, request, parent, isMain, options);
|
|
67
71
|
};
|
|
72
|
+
|
|
73
|
+
module.exports = settings;
|
|
@@ -1,61 +1,36 @@
|
|
|
1
1
|
|
|
2
|
+
// Generic
|
|
3
|
+
function isPrimitive(input) {
|
|
4
|
+
return input === null || (typeof input !== 'object' && typeof input !== 'function');
|
|
5
|
+
}
|
|
6
|
+
|
|
2
7
|
function typeOf(input) {
|
|
3
8
|
return Object.prototype.toString.call(input).slice(8, -1);
|
|
4
9
|
}
|
|
5
10
|
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
}
|
|
11
|
+
function strictTypeOf(input) {
|
|
12
|
+
if (input === null) return 'Null';
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
if (typeof input === 'object') {
|
|
15
|
+
if (input instanceof Number) return 'NumberObject';
|
|
16
|
+
if (input instanceof String) return 'StringObject';
|
|
17
|
+
if (input instanceof Boolean) return 'BooleanObject';
|
|
18
|
+
}
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
return isObject(input) && Object.keys(input).length === 0;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const { isArray } = Array;
|
|
19
|
-
|
|
20
|
-
function isEmptyArray(input) {
|
|
21
|
-
return isArray(input) && input.length === 0;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function mustArray(input, defaultValue = []) {
|
|
25
|
-
return isArray(input) ? input : isArray(defaultValue) ? defaultValue : [];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function isFunction(input) {
|
|
29
|
-
return typeof input === 'function';
|
|
20
|
+
return typeOf(input);
|
|
30
21
|
}
|
|
31
22
|
|
|
23
|
+
// Primitive
|
|
32
24
|
function isString(input) {
|
|
33
|
-
return typeof input === 'string'
|
|
25
|
+
return typeof input === 'string';
|
|
34
26
|
}
|
|
35
27
|
|
|
36
28
|
function isEmptyString(input) {
|
|
37
29
|
return isString(input) && input.length === 0;
|
|
38
30
|
}
|
|
39
31
|
|
|
40
|
-
function mustString(input) {
|
|
41
|
-
return isString(input) ? input : '';
|
|
42
|
-
}
|
|
43
|
-
|
|
44
32
|
function isNumber(input) {
|
|
45
|
-
return typeof input === 'number'
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function mustNumber(input, defaultValue) {
|
|
49
|
-
return isNumber(input) ? input : isNumber(defaultValue) ? defaultValue : 0;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function isDate(input) {
|
|
53
|
-
return typeOf(input) === 'Date' && !isNaN(input.getTime());
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function isDateLike(value) {
|
|
57
|
-
const date = new Date(value);
|
|
58
|
-
return !isNaN(date.getTime());
|
|
33
|
+
return typeof input === 'number' && Number.isFinite(input);
|
|
59
34
|
}
|
|
60
35
|
|
|
61
36
|
function isBigInt(input) {
|
|
@@ -67,7 +42,7 @@ function isSymbol(input) {
|
|
|
67
42
|
}
|
|
68
43
|
|
|
69
44
|
function isBoolean(input) {
|
|
70
|
-
return typeof input === 'boolean'
|
|
45
|
+
return typeof input === 'boolean';
|
|
71
46
|
}
|
|
72
47
|
|
|
73
48
|
function isNull(input) {
|
|
@@ -86,27 +61,70 @@ function isNullish(input) {
|
|
|
86
61
|
return input == null;
|
|
87
62
|
}
|
|
88
63
|
|
|
64
|
+
|
|
65
|
+
// Class, object
|
|
66
|
+
function isObject(input) {
|
|
67
|
+
return typeOf(input) === 'Object'; // typeOf() excludes null, arrays, functions, dates, etc.
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isPlainObject(input) {
|
|
71
|
+
// [input != null] => not allow input values as undefined or null, since Object.getPrototypeOf(input) throws error for undefined and null.
|
|
72
|
+
return input != null && Object.getPrototypeOf(input) === Object.prototype;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function isEmptyObject(input) {
|
|
76
|
+
return isObject(input) && Object.keys(input).length === 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const { isArray } = Array;
|
|
80
|
+
|
|
81
|
+
function isEmptyArray(input) {
|
|
82
|
+
return isArray(input) && input.length === 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function isFunction(input) {
|
|
86
|
+
return typeof input === 'function';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function isDate(input) {
|
|
90
|
+
return input instanceof Date && !isNaN(input.getTime());
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function isDateLike(input) {
|
|
94
|
+
const date = new Date(input);
|
|
95
|
+
return !isNaN(date.getTime());
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
89
99
|
module.exports = {
|
|
100
|
+
// Generic
|
|
90
101
|
typeOf,
|
|
102
|
+
strictTypeOf,
|
|
103
|
+
isPrimitive,
|
|
104
|
+
|
|
105
|
+
// Primitive
|
|
106
|
+
isString,
|
|
107
|
+
isEmptyString,
|
|
108
|
+
isNumber,
|
|
109
|
+
isBoolean,
|
|
110
|
+
isSymbol,
|
|
111
|
+
isBigInt,
|
|
112
|
+
|
|
113
|
+
isNull,
|
|
114
|
+
isUndefined,
|
|
115
|
+
isNullOrUndefined,
|
|
116
|
+
isNullish,
|
|
117
|
+
|
|
118
|
+
// Class, object
|
|
91
119
|
isObject,
|
|
120
|
+
isPlainObject,
|
|
92
121
|
isEmptyObject,
|
|
93
|
-
|
|
122
|
+
|
|
94
123
|
isArray,
|
|
95
124
|
isEmptyArray,
|
|
96
|
-
|
|
125
|
+
|
|
97
126
|
isFunction,
|
|
98
|
-
|
|
99
|
-
isUndefined,
|
|
100
|
-
isNullOrUndefined,
|
|
101
|
-
isNullish,
|
|
102
|
-
isBoolean,
|
|
103
|
-
isNumber,
|
|
104
|
-
mustNumber,
|
|
105
|
-
isString,
|
|
106
|
-
isEmptyString,
|
|
107
|
-
mustString,
|
|
108
|
-
isSymbol,
|
|
109
|
-
isBigInt,
|
|
127
|
+
|
|
110
128
|
isDate,
|
|
111
129
|
isDateLike
|
|
112
130
|
};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
|
|
2
2
|
const path = require('path');
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const express = require('express');
|
|
4
|
+
|
|
5
|
+
const { server } = require('@binhend/core');
|
|
6
|
+
const { isEmptyString, isString } = require('@binhend/types');
|
|
7
|
+
const must = require('@binhend/validation');
|
|
8
|
+
const moduleAlias = require('@binhend/module-alias');
|
|
9
|
+
|
|
5
10
|
const ComponentFormat = require('./component.format');
|
|
6
11
|
const ComponentBuild = require('./component.build');
|
|
7
12
|
const Component = require('./component');
|
|
8
|
-
// @ts-ignore
|
|
9
|
-
const { server } = require('@binhend/core');
|
|
10
|
-
const express = require('express');
|
|
11
13
|
|
|
12
14
|
const DEFAULT_DIR_BUILD = 'build';
|
|
13
15
|
const DEFAULT_DIR_BUILD_WEB = 'web';
|
|
@@ -26,7 +28,7 @@ function WebBuild(source, { output, external } = {}) {
|
|
|
26
28
|
|
|
27
29
|
var web = path.resolve(output, DEFAULT_DIR_BUILD_WEB);
|
|
28
30
|
var module = path.resolve(output, DEFAULT_DIR_BUILD_MODULE);
|
|
29
|
-
var external =
|
|
31
|
+
var external = must.String(external, { default: DEFAULT_DIR_BUILD_EXTERNAL });
|
|
30
32
|
|
|
31
33
|
this.bundle = () => {
|
|
32
34
|
Component.isLazy = false;
|
|
@@ -57,15 +59,11 @@ function WebBuild(source, { output, external } = {}) {
|
|
|
57
59
|
|
|
58
60
|
setTimeout(() => {
|
|
59
61
|
server().use(express.static(web));
|
|
60
|
-
// @ts-ignore
|
|
61
62
|
server().get('/*', (req, res) => res.sendFile('index.html', { root: web }));
|
|
62
63
|
});
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// @ts-ignore
|
|
67
|
-
binh.webSourcePath = source;
|
|
68
|
-
|
|
65
|
+
moduleAlias.webModulePath = module;
|
|
66
|
+
moduleAlias.webSourcePath = source;
|
|
69
67
|
}
|
|
70
68
|
|
|
71
69
|
module.exports = {
|
|
@@ -1,110 +1,5 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const CodeFormat = require('./code');
|
|
6
|
-
|
|
7
|
-
// TODO
|
|
8
|
-
// [-] Enhance code by removing sync logics (except for existsSync, mkdirSync): readdir, readFileSync, (statSync?)
|
|
9
|
-
// [-] Able to minify/beautify generated files
|
|
10
|
-
|
|
11
|
-
function generate(source, destination) {
|
|
12
|
-
if (source == undefined) return;
|
|
13
|
-
console.log('[BINHEND][WEB-BUILD] Start building components from:', source);
|
|
14
|
-
console.log('[BINHEND][WEB-BUILD] to:', destination);
|
|
15
|
-
processDirectory(source, source, destination);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function processDirectory(root, current, destination) {
|
|
19
|
-
readdir(current, function (error, dirents) {
|
|
20
|
-
if (error) {
|
|
21
|
-
showError('Failed scanning directory', current, error);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
dirents.forEach(function (dirent) {
|
|
26
|
-
var filepath = join(current, dirent);
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
var stat = statSync(filepath);
|
|
30
|
-
|
|
31
|
-
if (stat.isFile()) {
|
|
32
|
-
var outpath = filepath.replace(root, destination);
|
|
33
|
-
ensureDirectoryExistence(outpath);
|
|
34
|
-
|
|
35
|
-
if (parse(dirent).ext !== '.js') {
|
|
36
|
-
return cloneFile(filepath, outpath);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
var component = require(filepath);
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
var content = readFileSync(filepath, { encoding: 'utf8', flag: 'r' });
|
|
44
|
-
var isComponent = content.match(/\s*binh\s*.(ui|service|style)\s*\(\s*module\s*,.*\)/);
|
|
45
|
-
if (isComponent) {
|
|
46
|
-
showError('Failed requiring module', filepath, error);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
return cloneFile(filepath, outpath);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!(component instanceof Function) || component.constructor !== Component) {
|
|
53
|
-
return cloneFile(filepath, outpath);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
var code = joinCodes(component, root);
|
|
57
|
-
|
|
58
|
-
writeFile(outpath, code, { encoding: 'utf8', flag: 'w' }, function(error) {
|
|
59
|
-
if (error) {
|
|
60
|
-
showError('Failed writing file', filepath, error);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
else if (stat.isDirectory()) {
|
|
66
|
-
processDirectory(root, filepath, destination);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
showError('Failed processing file', filepath, error);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function ensureDirectoryExistence(filepath) {
|
|
77
|
-
var dirpath = dirname(filepath);
|
|
78
|
-
if (existsSync(dirpath)) return true;
|
|
79
|
-
ensureDirectoryExistence(dirpath);
|
|
80
|
-
mkdirSync(dirpath);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function joinCodes(component, root) {
|
|
84
|
-
var fullcode = CodeFormat.prequire(component, [
|
|
85
|
-
CodeFormat.bundle(component, root),
|
|
86
|
-
CodeFormat.htmltags(component)
|
|
87
|
-
]);
|
|
88
|
-
|
|
89
|
-
return fullcode;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function cloneFile(filepath, outpath) {
|
|
93
|
-
copyFile(filepath, outpath, function(error) {
|
|
94
|
-
if (error) {
|
|
95
|
-
showError('Failed copying file to', outpath, error);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function showError(message, id, error) {
|
|
101
|
-
console.log(`[BINHEND][WEB-BUILD] ${message}:`, id);
|
|
102
|
-
console.log('[BINHEND][WEB-BUILD] Error details:', error);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
var Component = {
|
|
106
|
-
generate,
|
|
2
|
+
module.exports = {
|
|
3
|
+
isLazy: false,
|
|
107
4
|
minification: false
|
|
108
5
|
};
|
|
109
|
-
|
|
110
|
-
module.exports = Component;
|