@makano/rew 1.5.2 → 1.5.4
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/lib/rew/const/default.js +2 -1
- package/lib/rew/const/pre-exec.js +8 -1
- package/lib/rew/functions/core.js +23 -0
- package/lib/rew/pkgs/rune.js +22 -0
- package/lib/rew/pkgs/serve.app.js +21 -15
- package/lib/rew/pkgs/serve.js +63 -10
- package/lib/rew/pkgs/styleway.js +152 -70
- package/package.json +1 -1
package/lib/rew/const/default.js
CHANGED
@@ -6,7 +6,7 @@ const sleep = require('../functions/sleep');
|
|
6
6
|
const { match } = require('../functions/match');
|
7
7
|
const { map } = require('../functions/map');
|
8
8
|
const { typex, typeis, typedef, typei, int, float, num, str, bool, typef } = require('../functions/types');
|
9
|
-
const { isEmpty, clone, deepClone, merge, uniqueId, compose, curry, getters, setters } = require('../functions/core');
|
9
|
+
const { isEmpty, clone, deepClone, merge, uniqueId, compose, curry, getters, setters, deepMerge } = require('../functions/core');
|
10
10
|
const { print, input, clear, printf } = require('../functions/stdout');
|
11
11
|
const { curl } = require('../functions/curl');
|
12
12
|
const { wait } = require('../functions/wait');
|
@@ -43,6 +43,7 @@ module.exports = {
|
|
43
43
|
clone,
|
44
44
|
deepClone,
|
45
45
|
merge,
|
46
|
+
deepMerge,
|
46
47
|
uniqueId,
|
47
48
|
compose,
|
48
49
|
curry,
|
@@ -1,3 +1,10 @@
|
|
1
1
|
Function.prototype.wait = function(...args) {
|
2
2
|
return wait(this, ...args);
|
3
|
-
};
|
3
|
+
};
|
4
|
+
Object.without = function(object, ...keys){
|
5
|
+
let newObject = {...object};
|
6
|
+
for(let i = 0; i < keys.length; i++){
|
7
|
+
delete newObject[keys[i]];
|
8
|
+
}
|
9
|
+
return newObject;
|
10
|
+
}
|
@@ -34,6 +34,28 @@ function deepClone(value) {
|
|
34
34
|
}
|
35
35
|
}
|
36
36
|
|
37
|
+
function isObject(item) {
|
38
|
+
return (item && typeof item === 'object' && !Array.isArray(item));
|
39
|
+
}
|
40
|
+
|
41
|
+
function deepMerge(target, ...sources) {
|
42
|
+
if (!sources.length) return target;
|
43
|
+
const source = sources.shift();
|
44
|
+
|
45
|
+
if (isObject(target) && isObject(source)) {
|
46
|
+
for (const key in source) {
|
47
|
+
if (isObject(source[key])) {
|
48
|
+
if (!target[key]) Object.assign(target, { [key]: {} });
|
49
|
+
deepMerge(target[key], source[key]);
|
50
|
+
} else {
|
51
|
+
Object.assign(target, { [key]: source[key] });
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
return deepMerge(target, ...sources);
|
57
|
+
}
|
58
|
+
|
37
59
|
function merge(obj1, obj2) {
|
38
60
|
return Object.assign({}, obj1, obj2);
|
39
61
|
}
|
@@ -100,6 +122,7 @@ module.exports = {
|
|
100
122
|
clone,
|
101
123
|
deepClone,
|
102
124
|
merge,
|
125
|
+
deepMerge,
|
103
126
|
uniqueId,
|
104
127
|
filter,
|
105
128
|
reduce,
|
package/lib/rew/pkgs/rune.js
CHANGED
@@ -410,4 +410,26 @@ module.exports = (context) => ({
|
|
410
410
|
push: runePush,
|
411
411
|
pop: runePop,
|
412
412
|
createDB,
|
413
|
+
localState(name, options){
|
414
|
+
const map = this.db('_' + name).map('_' + name + '_map');
|
415
|
+
const firstValue = map.get(name);
|
416
|
+
const _set = () => {
|
417
|
+
let item = options.get();
|
418
|
+
if(item.then){
|
419
|
+
item.then((i) => map.set(i));
|
420
|
+
} else {
|
421
|
+
map.set(name, item);
|
422
|
+
}
|
423
|
+
}
|
424
|
+
if(!firstValue) {
|
425
|
+
_set();
|
426
|
+
} else {
|
427
|
+
options.set(firstValue);
|
428
|
+
}
|
429
|
+
if(options.trigger){
|
430
|
+
options.trigger(() => {
|
431
|
+
_set();
|
432
|
+
});
|
433
|
+
}
|
434
|
+
}
|
413
435
|
});
|
@@ -7,6 +7,14 @@ module.exports = (context) => {
|
|
7
7
|
|
8
8
|
let appOptions = {};
|
9
9
|
|
10
|
+
const additionalParams = {
|
11
|
+
text: svr.prototype.text,
|
12
|
+
html: svr.prototype.html,
|
13
|
+
status: svr.prototype.status,
|
14
|
+
json: svr.prototype.json,
|
15
|
+
error: svr.prototype.error
|
16
|
+
};
|
17
|
+
|
10
18
|
const mkRouter = (options = {}) => svr.prototype.router({ type: 'auto', ...appOptions, ...options });
|
11
19
|
|
12
20
|
class Events {
|
@@ -251,7 +259,7 @@ module.exports = (context) => {
|
|
251
259
|
that.controller.register(method, _path, cb, middleWare);
|
252
260
|
return cb;
|
253
261
|
}
|
254
|
-
const mkReq = (usage) => (req,
|
262
|
+
const mkReq = (usage) => (req, ...args) => usage.call(req, req, ...args);
|
255
263
|
class SControllerContext extends Context('controller') {
|
256
264
|
|
257
265
|
middleWares = [];
|
@@ -317,18 +325,21 @@ module.exports = (context) => {
|
|
317
325
|
}
|
318
326
|
|
319
327
|
function mkBody(req){
|
328
|
+
if(!req.data) return null;
|
320
329
|
const type = req.headers.get('content-type');
|
321
330
|
if(type == 'application/json'){
|
322
331
|
return req.data.json();
|
323
|
-
} else {
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
332
|
+
} else if(type.startsWith('multipart/form-data')){
|
333
|
+
return req.data.multipart();
|
334
|
+
} else if(type == 'multipart/form-data'){
|
335
|
+
return req.data;
|
336
|
+
} else try {
|
337
|
+
return req.data.json();
|
338
|
+
} catch(e){
|
339
|
+
return req.data?.text();
|
329
340
|
}
|
330
341
|
}
|
331
|
-
|
342
|
+
let f;
|
332
343
|
class SController extends Injectable {
|
333
344
|
|
334
345
|
constructor(root){
|
@@ -341,14 +352,9 @@ module.exports = (context) => {
|
|
341
352
|
return async (req, ctx) => {
|
342
353
|
let context = {...{
|
343
354
|
request: req,
|
355
|
+
params: req.params || {},
|
344
356
|
body: mkBody(req)
|
345
|
-
},...ctx, ...(cb.parent || {}), ...
|
346
|
-
text: svr.prototype.text,
|
347
|
-
html: svr.prototype.html,
|
348
|
-
status: svr.prototype.status,
|
349
|
-
json: svr.prototype.json,
|
350
|
-
error: svr.prototype.error
|
351
|
-
}};
|
357
|
+
},...ctx, ...(cb.parent || {}), ...additionalParams};
|
352
358
|
return await cb.call(context, ...Object.keys(context).map(i => context[i]));
|
353
359
|
}
|
354
360
|
}
|
package/lib/rew/pkgs/serve.js
CHANGED
@@ -30,7 +30,65 @@ module.exports = (context) => {
|
|
30
30
|
return new Request(url, options);
|
31
31
|
}
|
32
32
|
|
33
|
-
|
33
|
+
|
34
|
+
function parseMultipart(req, content) {
|
35
|
+
const contentType = req.headers.get('content-type');
|
36
|
+
const boundary = contentType.split('boundary=')[1];
|
37
|
+
if (!boundary) throw new Error('No boundary in multipart/form-data');
|
38
|
+
|
39
|
+
const body = content;
|
40
|
+
const parts = body.split(`--${boundary}`).filter(part => part.trim() !== '--' && part.trim() !== '');
|
41
|
+
|
42
|
+
const fields = {};
|
43
|
+
const files = {};
|
44
|
+
|
45
|
+
parts.forEach(part => {
|
46
|
+
const [headers, ...content] = part.split('\r\n\r\n');
|
47
|
+
const contentBody = content.join('\r\n\r\n').trim();
|
48
|
+
const headerLines = headers.split('\r\n');
|
49
|
+
|
50
|
+
let name, filename, contentType;
|
51
|
+
headerLines.forEach(line => {
|
52
|
+
if (line.startsWith('Content-Disposition')) {
|
53
|
+
const matchName = /name="([^"]+)"/.exec(line);
|
54
|
+
const matchFilename = /filename="([^"]+)"/.exec(line);
|
55
|
+
if (matchName) name = matchName[1];
|
56
|
+
if (matchFilename) filename = matchFilename[1];
|
57
|
+
}
|
58
|
+
if (line.startsWith('Content-Type')) {
|
59
|
+
contentType = line.split(': ')[1];
|
60
|
+
}
|
61
|
+
});
|
62
|
+
|
63
|
+
if (filename) {
|
64
|
+
files[name] = {
|
65
|
+
filename,
|
66
|
+
contentType,
|
67
|
+
...handleBuffer(Buffer.from(contentBody, 'binary'))
|
68
|
+
};
|
69
|
+
} else {
|
70
|
+
fields[name] = contentBody;
|
71
|
+
}
|
72
|
+
});
|
73
|
+
|
74
|
+
return { ...fields, ...files };
|
75
|
+
}
|
76
|
+
|
77
|
+
function handleBuffer(buffer){
|
78
|
+
return {
|
79
|
+
text(){
|
80
|
+
return buffer.toString();
|
81
|
+
},
|
82
|
+
json(){
|
83
|
+
return JSON.parse(buffer.toString());
|
84
|
+
},
|
85
|
+
buffer(){
|
86
|
+
return buffer;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
function getBody(req, request){
|
34
92
|
return new Promise((resolve, reject) => {
|
35
93
|
const chunks = [];
|
36
94
|
|
@@ -41,14 +99,9 @@ module.exports = (context) => {
|
|
41
99
|
req.on('end', () => {
|
42
100
|
let buffer = chunks.length ? Buffer.concat(chunks) : null;
|
43
101
|
resolve(buffer ? {
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
json(){
|
48
|
-
return JSON.parse(buffer.toString());
|
49
|
-
},
|
50
|
-
buffer(){
|
51
|
-
return buffer;
|
102
|
+
...handleBuffer(buffer),
|
103
|
+
multipart(){
|
104
|
+
return parseMultipart(request, buffer.toString());
|
52
105
|
}
|
53
106
|
} : null);
|
54
107
|
});
|
@@ -81,7 +134,7 @@ module.exports = (context) => {
|
|
81
134
|
|
82
135
|
context.getRealRequest = () => req;
|
83
136
|
|
84
|
-
request.data = await getBody(req);
|
137
|
+
request.data = await getBody(req, request);
|
85
138
|
|
86
139
|
if(this.options.fetch == 'router'){
|
87
140
|
if(!Object.keys(this.options.routers).length) throw new Error('No fetch function nor routers found');
|
package/lib/rew/pkgs/styleway.js
CHANGED
@@ -1,88 +1,170 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
let
|
4
|
-
|
5
|
-
|
2
|
+
function normalizeCamelCase (camelCase) {
|
3
|
+
let all = "";
|
4
|
+
for(let i of camelCase){
|
5
|
+
if(i.match(/[A-Z]/)){
|
6
|
+
all += '-';
|
7
|
+
i = i.toLowerCase();
|
8
|
+
}
|
9
|
+
all += i;
|
10
|
+
}
|
11
|
+
if(all.startsWith('-')) all = all.slice(1);
|
12
|
+
return all;
|
13
|
+
}
|
14
|
+
const known_states = [
|
15
|
+
'hover',
|
16
|
+
'active',
|
17
|
+
'focus',
|
18
|
+
'focus-within',
|
19
|
+
'focus-visible',
|
20
|
+
'visited',
|
21
|
+
'link',
|
22
|
+
'disabled',
|
23
|
+
'checked',
|
24
|
+
'unchecked',
|
25
|
+
'first-child',
|
26
|
+
'last-child',
|
27
|
+
'nth-child',
|
28
|
+
'nth-of-type',
|
29
|
+
'empty',
|
30
|
+
'not',
|
31
|
+
'before',
|
32
|
+
'after',
|
33
|
+
'first-of-type',
|
34
|
+
'last-of-type',
|
35
|
+
'only-child',
|
36
|
+
'only-of-type',
|
37
|
+
'valid',
|
38
|
+
'invalid',
|
39
|
+
'in-range',
|
40
|
+
'out-of-range',
|
41
|
+
'required',
|
42
|
+
'optional',
|
43
|
+
'disabled',
|
44
|
+
'enabled',
|
45
|
+
'enabled',
|
46
|
+
'default',
|
47
|
+
'selection',
|
48
|
+
'target',
|
49
|
+
'lang',
|
50
|
+
'dir',
|
51
|
+
];
|
52
|
+
|
6
53
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
54
|
+
const parseValue = (O, v, self, name, vars) => {
|
55
|
+
const vs = {...O.variables, ...vars, name, ...Object.fromEntries(Object.entries(self).map(i => ['prop_'+i[0], i[1]]))};
|
56
|
+
return v.startsWith('@v') ? vs[v.split('@v')[1].trim()] : v
|
57
|
+
.toString()
|
58
|
+
.replace(/\$([A-Za-z0-9-_]+)/g, (_, name) => (vs)[name])
|
59
|
+
}
|
60
|
+
|
61
|
+
const declectProp = (O, value, name, selector, start, parent, self, vars = {}) => {
|
62
|
+
let prop = "";
|
63
|
+
self.__parent = parent;
|
64
|
+
if (typeof value == 'object') {
|
65
|
+
for (let state in value) {
|
66
|
+
if (state == 'default') {
|
67
|
+
prop += `\n${selector}{ ${name}: ${parseValue(O, value.default || 'unset', self, name, vars) + ';'} }`;
|
68
|
+
} else if (state.startsWith('@media')) {
|
69
|
+
prop += `\n${state} { ${selector}: ${parseValue(O, value[state], self, name, vars)}; }`
|
70
|
+
} else if (state.startsWith(':') || known_states.includes(state)) {
|
71
|
+
prop += `\n${selector}${!state.startsWith(':') ? ':' : ''}${state} { ${name}: ${parseValue(O, value[state], self, name, vars)}; }`
|
72
|
+
}
|
73
|
+
}
|
74
|
+
} else {
|
75
|
+
prop += `\n${selector}{ ${name}: `;
|
76
|
+
let v = parseValue(O, value, self, name, vars);
|
77
|
+
if(typeof v == 'object') return declectProp(v, name, selector, start, parent, self, vars);
|
78
|
+
prop += v + ';';
|
79
|
+
prop += '}\n';
|
12
80
|
}
|
81
|
+
return prop;
|
82
|
+
}
|
83
|
+
|
84
|
+
const declectNames = (O, names, $name, parent, values = {}, free = true) => {
|
85
|
+
const start = $name && free ? $name + ' {' : '';
|
86
|
+
let nameStyles = "";
|
87
|
+
for (let name in names) {
|
88
|
+
let selector = name.replace(/,/g, ', &').replace(/&/g, $name || '');
|
89
|
+
if (name == '@variables') {
|
90
|
+
for (let i in names[name]) {
|
91
|
+
O.variables[i] = names[name][i];
|
92
|
+
}
|
93
|
+
} else if (name.startsWith('@mixin')) {
|
94
|
+
const mame = name.split('@mixin')[1].trim();
|
95
|
+
const mname = mame.split('(')[0];
|
96
|
+
const args = mame.replace(mname, '').slice(1, -1);
|
97
|
+
O.mixins[mname] = {
|
98
|
+
args: args.split(','),
|
99
|
+
value: names[name]
|
100
|
+
}
|
101
|
+
} else if (name.startsWith('@keyframes')) {
|
102
|
+
nameStyles += $name ? '' : name + '{';
|
13
103
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
104
|
+
for(let keyFrame in names[name]){
|
105
|
+
nameStyles += declectNames(O, names[name][keyFrame], keyFrame, names[name], values);
|
106
|
+
}
|
107
|
+
|
108
|
+
if(!$name) nameStyles += '}\n';
|
109
|
+
} else if ($name) {
|
110
|
+
if (name.startsWith('&')) {
|
111
|
+
nameStyles += '}\n';
|
112
|
+
nameStyles += declectNames(O, names[name], selector, names, values);
|
113
|
+
nameStyles += start;
|
114
|
+
} else if(name.startsWith('@include')) {
|
115
|
+
const mame = names[name];
|
116
|
+
const mname = mame.split('(')[0];
|
117
|
+
const args = mame.replace(mname, '').slice(1, -1).split(',');
|
118
|
+
if(O.mixins[mname]){
|
119
|
+
nameStyles += declectNames(O, O.mixins[mname].value, $name, parent, {...values, ...Object.fromEntries(O.mixins[mname].args.map((n, i) => [n, args[i]]))}, false).trim();
|
26
120
|
}
|
121
|
+
} else {
|
122
|
+
nameStyles += declectProp(O, names[name], normalizeCamelCase(name), $name, start, parent || styles, names, values);
|
27
123
|
}
|
28
|
-
prop += start;
|
29
124
|
} else {
|
30
|
-
|
31
|
-
if(typeof v == 'object') return declectProp(v, name, selector, start, parent, self, vars);
|
32
|
-
prop += v + ';';
|
125
|
+
nameStyles += declectNames(O, names[name], selector, names, values);
|
33
126
|
}
|
34
|
-
return prop;
|
35
127
|
}
|
128
|
+
return nameStyles;
|
129
|
+
}
|
36
130
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
for (let name in names) {
|
41
|
-
let selector = name.replace(/,/g, ', &').replace(/&/g, $name || '');
|
42
|
-
if (name == '@variables') {
|
43
|
-
for (let i in names[name]) {
|
44
|
-
variables[i] = names[name][i];
|
45
|
-
}
|
46
|
-
} else if (name.startsWith('@mixin')) {
|
47
|
-
const mame = name.split('@mixin')[1].trim();
|
48
|
-
const mname = mame.split('(')[0];
|
49
|
-
const args = mame.replace(mname, '').slice(1, -1);
|
50
|
-
mixins[mname] = {
|
51
|
-
args: args.split(','),
|
52
|
-
value: names[name]
|
53
|
-
}
|
54
|
-
} else if (name.startsWith('@keyframes')) {
|
55
|
-
nameStyles += $name ? '' : name + '{';
|
131
|
+
const collectAndCleanUp = (css) => {
|
132
|
+
const selectorMap = {};
|
133
|
+
const cleanedCSS = [];
|
56
134
|
|
57
|
-
|
58
|
-
nameStyles += declectNames(names[name][keyFrame], keyFrame, names[name], values);
|
59
|
-
}
|
135
|
+
const lines = css.split('\n');
|
60
136
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
const mame = names[name];
|
69
|
-
const mname = mame.split('(')[0];
|
70
|
-
const args = mame.replace(mname, '').slice(1, -1).split(',');
|
71
|
-
if(mixins[mname]){
|
72
|
-
nameStyles += declectNames(mixins[mname].value, selector, names, {...values, ...Object.fromEntries(mixins[mname].args.map((n, i) => [n, args[i]]))}).trim().replace('@include ', '').slice(1, -1);
|
73
|
-
}
|
74
|
-
} else {
|
75
|
-
nameStyles += declectProp(names[name], name, $name, start, parent || styles, names, values);
|
76
|
-
}
|
77
|
-
} else {
|
78
|
-
nameStyles += declectNames(names[name], selector, names, values);
|
137
|
+
lines.forEach(line => {
|
138
|
+
const match = line.match(/([^\{]+){(.+)}/);
|
139
|
+
if (match) {
|
140
|
+
const selector = match[1].trim();
|
141
|
+
|
142
|
+
if (!selectorMap[selector]) {
|
143
|
+
selectorMap[selector] = "";
|
79
144
|
}
|
145
|
+
|
146
|
+
selectorMap[selector] += match[2];
|
80
147
|
}
|
81
|
-
|
82
|
-
|
148
|
+
});
|
149
|
+
|
150
|
+
for (const selector in selectorMap) {
|
151
|
+
const selectorBlock = selectorMap[selector];
|
152
|
+
cleanedCSS.push(`${selector} { ${selectorBlock} }`);
|
83
153
|
}
|
84
154
|
|
85
|
-
|
155
|
+
return cleanedCSS.join('\n');
|
156
|
+
};
|
157
|
+
|
158
|
+
|
159
|
+
module.exports = () => ((styles) => {
|
160
|
+
let css = "";
|
161
|
+
const variables = {};
|
162
|
+
const mixins = {};
|
163
|
+
|
164
|
+
css += declectNames({
|
165
|
+
variables,
|
166
|
+
mixins
|
167
|
+
}, styles);
|
86
168
|
|
87
|
-
return css
|
169
|
+
return collectAndCleanUp(css);
|
88
170
|
})
|