@makano/rew 1.4.1 → 1.4.2

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.
@@ -117,6 +117,7 @@ module.exports.imp = function (runPath, context) {
117
117
  const pkg = getPackage(filename)(context, options);
118
118
  exports = pkg._onImport ? pkg._onImport() : pkg;
119
119
  if(options.useDefaultForPackages) exports = { default: exports };
120
+ // console.log(exports, options.useDefaultForPackages);
120
121
  } else if (foundCache) {
121
122
  } else if (type == REW_FILE_TYPE.TYPE || type == "coffee") {
122
123
  exports = exec({});
@@ -497,6 +497,7 @@ function compileRewStuff(content, options) {
497
497
  straceLog('==> WARN: SLOWS DOWN COMPILATION');
498
498
  let ind = i + n + 2;
499
499
  let isAs = false;
500
+ let usedDefault = false;
500
501
 
501
502
  let defaultName;
502
503
  if (nextToken.type === 'STRING') {
@@ -514,7 +515,7 @@ function compileRewStuff(content, options) {
514
515
  if(next?.token?.value == 'as'){
515
516
  const ebraceOpen = gnextToken(next.token.ti, 1, tokens);
516
517
  const ebraceClose = fnextToken(ebraceOpen.ti, tokens, 'OTHER', ')');
517
- const exportsTokens = tokens.slice(ebraceOpen.ti+1, ebraceClose.ti);
518
+ const exportsTokens = tokens.slice(ebraceOpen.ti+1, ebraceClose?.ti);
518
519
  exports = mapTokensToStrings(exportsTokens.filter(token => token.type !== 'WHITESPACE'));
519
520
  lastindex = ebraceClose.ti;
520
521
  } else lastindex = closingBraceToken.ti;
@@ -573,10 +574,12 @@ function compileRewStuff(content, options) {
573
574
  if(useImp(nameToken, options)) updateAliases(aliases);
574
575
  result += `{ default: ${defaultName}, ${exports} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken?.value || ''}`;
575
576
  i = closingBraceToken.ti + 4;
577
+ usedDefault = true;
576
578
  }
577
579
  } else {
578
580
  if(useImp(nameToken || {}, options)) updateAliases(aliases);
579
581
  result += `{ default: ${defaultName} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken?.value || ''}`;
582
+ usedDefault = true;
580
583
  i = ind + 2;
581
584
  }
582
585
  }
@@ -590,14 +593,14 @@ function compileRewStuff(content, options) {
590
593
  if(assertionToken.token.type == 'OTHER' && assertionToken.token.value == '{'){
591
594
  hooks.push({
592
595
  index: assertionToken.token.ti,
593
- value: ' useDefaultForPackages: '+(isAs?'false':'true')+', '
596
+ value: ' useDefaultForPackages: '+(isAs?'false':usedDefault.toString())+', '
594
597
  })
595
598
  } else {
596
- result += 'useDefaultForPackages: '+(isAs?'false':'true')+', '
599
+ result += 'useDefaultForPackages: '+(isAs?'false':usedDefault.toString())+', '
597
600
  }
598
601
  i += 3;
599
602
  } else {
600
- result += ", { useDefaultForPackages: "+(isAs?'false':'true')+" }"
603
+ result += ", { useDefaultForPackages: "+(isAs?'false':usedDefault.toString())+" }"
601
604
  }
602
605
 
603
606
  continue;
@@ -789,7 +792,7 @@ module.exports.compileFile = function (filepath, options = {}) {
789
792
  f.content = from_qrew(readFileSync(f.path), options.package || findAppInfo(filepath)?.config.manifest.package || path.basename(filepath).split('.').slice(0, -1).join('.')).toString();
790
793
  options.type = f.content.split('\n')[0]?.match(/"initFile (.+)"/)?.[1]?.split('.').pop();
791
794
  straceLog('QREW_DECODE() as', options.type, 'for CURRENTFILE');
792
- }
795
+ }
793
796
 
794
797
  let compiled_code = cpl(f, { ...options });
795
798
 
@@ -39,7 +39,10 @@ module.exports.prepareContext = function (
39
39
  app: findAppInfo(filepath),
40
40
  ...fsLib(filepath),
41
41
  ...reval(filepath),
42
- __using__: {}
42
+ __using__: {},
43
+ get _(){
44
+ return void 0;
45
+ }
43
46
  };
44
47
  if (options.useContext) {
45
48
  context = {
@@ -0,0 +1,402 @@
1
+ const { typex } = require("../const/default");
2
+ const emitter = require("../functions/emitter");
3
+ const path = require('path');
4
+
5
+ module.exports = (context) => {
6
+ const svr = context.imp('serve');
7
+
8
+ let appOptions = {};
9
+
10
+ const mkRouter = (options = {}) => svr.prototype.router({ type: 'auto', ...appOptions, ...options });
11
+
12
+ class Events {
13
+ target = emitter();
14
+ on(...args){
15
+ this.target.on(...args);
16
+ return this;
17
+ }
18
+ off(...args){
19
+ this.target.off(...args);
20
+ return this;
21
+ }
22
+ emit(...args){
23
+ this.target.emit(...args);
24
+ return this;
25
+ }
26
+ }
27
+
28
+ const Context = (name, inherit = []) => {
29
+ const ctxC = class Context {
30
+
31
+ constructor(item){
32
+ this[name] = item;
33
+ }
34
+
35
+ on(evt, cb){
36
+ this[name].on(evt, cb);
37
+ return this;
38
+ }
39
+
40
+ off(evt, cb){
41
+ this[name].off(evt, cb);
42
+ return this;
43
+ }
44
+
45
+ emit(evt, ...data){
46
+ this[name].emit(evt, ...data);
47
+ return this;
48
+ }
49
+ };
50
+
51
+ inherit?.forEach(fname => {
52
+ ctxC.prototype[fname] = function(...args){
53
+ this[name][fname](...args);
54
+ return this;
55
+ }
56
+ });
57
+
58
+ return ctxC;
59
+ }
60
+
61
+ class AppContext extends Context('app', ['start', 'redirect']) {
62
+ inject(item){
63
+ this.app.inject(item);
64
+ return this;
65
+ }
66
+
67
+ module(...items){
68
+ return this.inject(...items);
69
+ }
70
+ }
71
+
72
+ class ServeApp extends Events {
73
+ #injectables = [];
74
+ server;
75
+ router;
76
+
77
+ constructor(options){
78
+ super();
79
+ appOptions = options;
80
+ this.router = mkRouter(options);
81
+ this.server = svr.prototype.create({
82
+ fetch: this.router.fetch
83
+ });
84
+ }
85
+
86
+ /** @param {Injectable[]} injectables */
87
+ inject(...injectables){
88
+ injectables.filter(i => i instanceof Injectable)
89
+ .forEach(injectable => {
90
+ this.#injectables.push(injectable);
91
+ injectable.emit('activate', this);
92
+ this.emit('activate', this);
93
+ });
94
+ return this;
95
+ }
96
+
97
+ redirect(at = '*', router){
98
+ this.router.all(at, typeof router == 'function' ? router : router.fetch);
99
+ return this;
100
+ }
101
+
102
+ new(options = {}){
103
+ return (cb) => new context.Usage('', () => {
104
+ const app = new ServeApp(options);
105
+ const appContext = new AppContext(app);
106
+ cb.call(appContext);
107
+ return app;
108
+ });
109
+ }
110
+
111
+ raw(){
112
+ return context.using(this.new(() => {}));
113
+ }
114
+
115
+ #setup(){
116
+ this.#injectables
117
+ .filter(injectable => injectable instanceof SModule)
118
+ .forEach(module => {
119
+ /** @type {SController[]} */
120
+ const controllers = module.getControllers();
121
+ controllers.forEach(controller => {
122
+ // console.log(path.join('/', controller.root, '*'), controller);
123
+ this.redirect(path.join('/', controller.root, '*'), controller.router);
124
+ })
125
+ });
126
+ }
127
+
128
+ start(port){
129
+ this.#setup();
130
+ this.server.port(port).listen;
131
+ this.emit('start', port);
132
+ return this;
133
+ }
134
+ }
135
+
136
+ class Injectable extends Events {
137
+ #injected = [];
138
+ forEachInjectable(cb, event, ...injectables){
139
+ injectables.filter(i => i instanceof Injectable)
140
+ .forEach(injectable => {
141
+ cb(injectable);
142
+ injectable.emit(event, this);
143
+ this.emit(event, this);
144
+ });
145
+ return this;
146
+ }
147
+ inject(...injectables){
148
+ return this.forEachInjectable(
149
+ (injectable) => this.#injected.push(injectable),
150
+ 'activate',
151
+ ...injectables
152
+ );
153
+ }
154
+ }
155
+
156
+
157
+ class SModuleContext extends Context('module') {
158
+
159
+ provider(...provider){
160
+ this.module.addProvider(...provider);
161
+ return this;
162
+ }
163
+
164
+ controller(...controller){
165
+ this.module.addController(...controller);
166
+ return this;
167
+ }
168
+ }
169
+
170
+ class SModule extends Injectable {
171
+ #providers = [];
172
+ #controllers = [];
173
+ #app = {};
174
+
175
+ constructor(){
176
+ super();
177
+ this.on('activate', (app) => {
178
+ this.#app = app;
179
+ this.#controllers.concat(
180
+ this.#providers
181
+ ).forEach(injectable => injectable.emit('activate:app', app));
182
+ });
183
+ }
184
+
185
+ addProvider(...providers){
186
+ return this.forEachInjectable(
187
+ (injectable) => this.#providers.push(injectable),
188
+ 'activate',
189
+ ...providers
190
+ );
191
+ }
192
+
193
+ hasProvider(provider){
194
+ return this.#providers.find(p => p == provider);
195
+ }
196
+
197
+ addController(...controllers){
198
+ return this.forEachInjectable(
199
+ (injectable) => this.#controllers.push(injectable),
200
+ 'activate',
201
+ ...controllers
202
+ );
203
+ }
204
+
205
+ getControllers(){
206
+ return this.#controllers;
207
+ }
208
+
209
+ new(cb){
210
+ return new context.Usage('', () => {
211
+ const module = new SModule();
212
+ const moduleContext = new SModuleContext(module);
213
+ cb.call(moduleContext);
214
+ return module;
215
+ });
216
+ }
217
+ }
218
+
219
+ class SServiceContext extends Context('service') {
220
+ function(name){
221
+ return (cb) => {
222
+ this[name] = (...args) => cb.call(this, ...args);
223
+ this.service[name] = this[name];
224
+ return this[name];
225
+ }
226
+ }
227
+ }
228
+ class SProvider {
229
+ constructor(name, injectable){
230
+ this.name = name;
231
+ this.injectable = injectable;
232
+ }
233
+ }
234
+ class SService extends Injectable {
235
+ new(cb){
236
+ return new context.Usage('', () => {
237
+ const service = new SService();
238
+ const serviceContext = new SServiceContext(service);
239
+ cb.call(serviceContext);
240
+ return service;
241
+ });
242
+ }
243
+
244
+ as(name){
245
+ return new SProvider(name, this);
246
+ }
247
+ }
248
+
249
+ const ggreq = (that, method, _path, middleWare) => (cb) => {
250
+ cb.parent = that;
251
+ that.controller.register(method, _path, cb, middleWare);
252
+ return cb;
253
+ }
254
+ const mkReq = (usage) => (req, ctx) => usage.call(req, req, ctx);
255
+ class SControllerContext extends Context('controller') {
256
+
257
+ middleWares = [];
258
+
259
+ getMiddleWares(md){
260
+ return (...args) => {
261
+ this.middleWares.forEach(middleWare => {
262
+ mkReq(middleWare)(...args);
263
+ });
264
+ if(md){
265
+ mkReq(md)(...args);
266
+ }
267
+ }
268
+ }
269
+
270
+ withCookies(){
271
+ return svr.prototype.withCookies;
272
+ }
273
+ withContent(){
274
+ return svr.prototype.withContent;
275
+ }
276
+
277
+ get(_path, middleWare){
278
+ return ggreq(this, 'get', _path, this.getMiddleWares(middleWare));
279
+ }
280
+ post(_path, middleWare){
281
+ return ggreq(this, 'post', _path, this.getMiddleWares(middleWare));
282
+ }
283
+ delete(_path, middleWare){
284
+ return ggreq(this, 'delete', _path, this.getMiddleWares(middleWare));
285
+ }
286
+ patch(_path, middleWare){
287
+ return ggreq(this, 'patch', _path, this.getMiddleWares(middleWare));
288
+ }
289
+ put(_path, middleWare){
290
+ return ggreq(this, 'put', _path, this.getMiddleWares(middleWare));
291
+ }
292
+ all(_path, middleWare){
293
+ return ggreq(this, 'all', _path, this.getMiddleWares(middleWare));
294
+ }
295
+
296
+ use(usage){
297
+ this.controller.router.all('*', mkReq(usage));
298
+ return this;
299
+ }
300
+
301
+ useEach(usage){
302
+ this.middleWares.push(usage);
303
+ return this;
304
+ }
305
+
306
+ usem(...middleWares){
307
+ return function(...args){
308
+ middleWares.forEach(middleWare => middleWare.call(this, ...args));
309
+ }
310
+ }
311
+
312
+ normal(cb){
313
+ return function(){
314
+ return cb(this.request, this);
315
+ }
316
+ }
317
+ }
318
+
319
+ function mkBody(req){
320
+ const type = req.headers.get('content-type');
321
+ if(type == 'application/json'){
322
+ return req.data.json();
323
+ } else {
324
+ try {
325
+ return req.data.json();
326
+ } catch(e){
327
+ return req.data.text();
328
+ }
329
+ }
330
+ }
331
+
332
+ class SController extends Injectable {
333
+
334
+ constructor(root){
335
+ super();
336
+ this.root = root;
337
+ this.router = mkRouter({ base: path.join('/', root) });
338
+ }
339
+
340
+ mkCallback(cb){
341
+ return async (req, ctx) => {
342
+ let context = {...{
343
+ request: req,
344
+ 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
+ }};
352
+ return await cb.call(context, ...Object.keys(context).map(i => context[i]));
353
+ }
354
+ }
355
+
356
+ register(method, url, cb, middleWare){
357
+ this.router[method](url || '/', middleWare || this.mkCallback(cb), middleWare ? this.mkCallback(cb) : undefined);
358
+ return this;
359
+ }
360
+
361
+ new(root = '/'){
362
+ const controller = new SController(root || '/');
363
+ const controllerContext = new SControllerContext(controller);
364
+ const cb = (cb) => new context.Usage('', () => {
365
+ cb.call(controllerContext);
366
+ return controller;
367
+ });
368
+ cb.with = (...args) => {
369
+ controller.on('activate', (parentModule) => {
370
+ args
371
+ .filter(arg => arg instanceof SProvider)
372
+ .filter(arg => parentModule.hasProvider(arg.injectable))
373
+ .forEach(e => {
374
+ controllerContext[e.name] = e.injectable;
375
+ });
376
+ });
377
+ return cb;
378
+ }
379
+ return cb;
380
+ }
381
+ }
382
+
383
+ class SControllerMiddleware extends Injectable {
384
+ constructor(root, router){
385
+ super();
386
+ this.root = root;
387
+ this.router = router;
388
+ }
389
+ }
390
+
391
+ function createSControllerMiddleware(root = '') {
392
+ return (cb) => new SControllerMiddleware(root, cb);
393
+ }
394
+
395
+ return {
396
+ ServeApp,
397
+ SModule,
398
+ SService,
399
+ SController,
400
+ SControllerMiddleware: createSControllerMiddleware
401
+ };
402
+ }
@@ -30,6 +30,35 @@ module.exports = (context) => {
30
30
  return new Request(url, options);
31
31
  }
32
32
 
33
+ function getBody(req){
34
+ return new Promise((resolve, reject) => {
35
+ const chunks = [];
36
+
37
+ req.on('data', chunk => {
38
+ chunks.push(chunk);
39
+ });
40
+
41
+ req.on('end', () => {
42
+ let buffer = chunks.length ? Buffer.concat(chunks) : null;
43
+ resolve(buffer ? {
44
+ text(){
45
+ return buffer.toString();
46
+ },
47
+ json(){
48
+ return JSON.parse(buffer.toString());
49
+ },
50
+ buffer(){
51
+ return buffer;
52
+ }
53
+ } : null);
54
+ });
55
+
56
+ req.on('error', (err) => {
57
+ reject(err);
58
+ });
59
+ });
60
+ }
61
+
33
62
  class Server {
34
63
  _server = {};
35
64
  routers = {};
@@ -47,12 +76,18 @@ module.exports = (context) => {
47
76
  async handleRequest(req, res){
48
77
  try {
49
78
  let response = new Response();
79
+ const context = {};
50
80
  const request = mkReq(req);
81
+
82
+ context.getRealRequest = () => req;
83
+
84
+ request.data = await getBody(req);
85
+
51
86
  if(this.options.fetch == 'router'){
52
87
  if(!Object.keys(this.options.routers).length) throw new Error('No fetch function nor routers found');
53
- response = await this.options.routers[Object.keys(this.options.routers)[0]].fetch(request);
88
+ response = await this.options.routers[Object.keys(this.options.routers)[0]].fetch(request, context).catch((e) => this.catch(e));
54
89
  } else {
55
- response = await this.options.fetch(request);
90
+ response = await this.options.fetch(request, context).catch((e) => this.catch(e));
56
91
  }
57
92
 
58
93
  if(!response){
@@ -60,6 +95,10 @@ module.exports = (context) => {
60
95
  return;
61
96
  }
62
97
 
98
+ if(typeof response == 'string'){
99
+ response = new Response(response);
100
+ }
101
+
63
102
  response.headers.forEach((value, name) => {
64
103
  res.setHeader(name, value);
65
104
  });
@@ -97,6 +136,23 @@ module.exports = (context) => {
97
136
  return this;
98
137
  }
99
138
 
139
+ _onError = (e) => {
140
+ console.error(e);
141
+ return json({
142
+ error: true,
143
+ exception: e.name,
144
+ message: e.message
145
+ });
146
+ };
147
+ onError(fn){
148
+ this._onError = fn;
149
+ return this;
150
+ }
151
+
152
+ catch(e){
153
+ return this._onError(e);
154
+ }
155
+
100
156
  port(port){
101
157
  this.listen = port;
102
158
  return this;
@@ -190,7 +246,6 @@ module.exports = (context) => {
190
246
  const routeParts = pathname.split('/').filter(Boolean);
191
247
  let routePath = root;
192
248
 
193
-
194
249
  Object.keys(params).forEach(key => delete params[key]);
195
250
 
196
251
  for (const part of routeParts) {
@@ -294,6 +349,7 @@ module.exports = (context) => {
294
349
  return async (req) => {
295
350
  const url = new URL(req.url);
296
351
  const pathname = basePath ? url.pathname.replace(new RegExp('^'+basePath), '') : url.pathname;
352
+
297
353
  const file = lookUp(pathname);
298
354
  cleanCache();
299
355
 
@@ -324,6 +380,8 @@ module.exports = (context) => {
324
380
  if(type == 'default') router = SvrRouter.new(IttyRouter, {...options}, { id });
325
381
  if(type == 'auto') router = SvrRouter.new(AutoRouter, {...options}, { id });
326
382
  if(type == 'normal') router = SvrRouter.new(Router, {...options}, { id });
383
+
384
+ router.auto = true;
327
385
 
328
386
  return router;
329
387
  }
@@ -241,8 +241,8 @@ function renderToString(element, js = false) {
241
241
  }
242
242
  delete eltJSON.parent;
243
243
  delete eltJSON._target;
244
-
245
- return js ? js === 'raw' ? eltJSON : JSON.stringify(eltJSON) : element instanceof TextNode ? `${type.text}` : `<${type.element}${propsString}>${selfClosingElements.has(type.element) ? '' : childrenHTML}${selfClosingElements.has(type.element) ? '' : `</${type.element}>`}`;
244
+
245
+ return js ? (js === 'raw' ? eltJSON : JSON.stringify(eltJSON)) : element instanceof TextNode ? `${type.text}` : `<${type.element}${propsString}>${selfClosingElements.has(type.element) ? '' : childrenHTML}${selfClosingElements.has(type.element) ? '' : `</${type.element}>`}`;
246
246
  }
247
247
 
248
248
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makano/rew",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "A simple coffescript runtime and app manager",
5
5
  "main": "main.js",
6
6
  "directories": {
@@ -50,5 +50,8 @@
50
50
  "vite": "^5.2.13",
51
51
  "vm": "^0.1.0",
52
52
  "yargs": "^17.7.2"
53
+ },
54
+ "devDependencies": {
55
+ "@danielx/civet": "^0.7.23"
53
56
  }
54
57
  }