@makano/rew 1.2.901 → 1.2.971

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -12,9 +12,15 @@ Rew
12
12
  <a href="https://www.npmjs.com/package/rayous"> <img src="https://img.shields.io/npm/v/@makano/rew?style=for-the-badge&logo=npm&color=b4befe&logoColor=9399b2&labelColor=181825" alt="npm version" /></a>
13
13
  </p>
14
14
 
15
- Rew is a simple lightweight coffeescript runtime, made to simply using coffescript and revive it
15
+ Rew is a simple lightweight coffeescript runtime, made to simplify using coffescript and revive it
16
16
  in the process.
17
17
 
18
+ ```coffee
19
+ using namespace std::ns ->
20
+ define Main ->
21
+ print 'hello world' |> str
22
+ ```
23
+
18
24
  ## Getting Started
19
25
  1. Install `rew` globally
20
26
  ```bash
@@ -338,18 +338,45 @@ yargs(hideBin(process.argv))
338
338
  }
339
339
  },
340
340
  )
341
-
342
341
  .command(
343
342
  'cache <command>',
344
343
  'Manage cache',
344
+ (yargs) => {
345
+ yargs
346
+ .positional('command', {
347
+ describe: 'Command to clear/list/show',
348
+ type: 'string',
349
+ })
350
+ .example('rew cache list', 'Lists all caches')
351
+ .example('rew cache clear', 'Clears all caches')
352
+ .example('rew cache clear all', 'Clears all caches')
353
+ .example('rew cache clear [id]', 'Clears all caches for id [id]')
354
+ .example('rew cache show [id]', 'Shows commits downloaded for [id]')
355
+ .example('rew cache show [id]', 'Shows commits downloaded for [id]')
356
+ .example('rew cache show [id]/clone', 'Shows the contents for [id]')
357
+ .example('rew cache show [id]#tag', 'Shows the tag for [id]')
358
+ .example('rew cache show [id]#commit', 'Shows the current commit for [id]')
359
+ .example('rew cache show [id]#name', 'Shows the name for [id]')
360
+ .example('rew cache show [id]/clone/app.yaml', 'Shows the app config for [id]')
361
+ .example('rew cache show [id]/clone/path/to/file', 'Gives you the path to the file inside [id]')
362
+ .example('rew cache show [id]/clone/path/to/file', 'Gives you the path to the file inside [id]')
363
+ .example('rew cache install [id]', 'Installs cache')
364
+ },
365
+ async (argv) => {
366
+ require('./utils').cache(argv.command, ...argv._.slice(1));
367
+ },
368
+ )
369
+ .command(
370
+ 'misc <command>',
371
+ 'Misc functions',
345
372
  (yargs) => {
346
373
  yargs.positional('command', {
347
- describe: 'Command to clear/list',
374
+ describe: 'Misc command name',
348
375
  type: 'string',
349
376
  });
350
377
  },
351
- async (argv) => {
352
- require('./utils').cache(argv.command)
378
+ (argv) => {
379
+ require('./miscUtils')[argv.command](...argv._.slice(1));
353
380
  },
354
381
  )
355
382
  .command(
@@ -35,11 +35,36 @@ function getAllPipeInput(){
35
35
  });
36
36
  }
37
37
 
38
+ /**
39
+ *
40
+ * @param {string} string
41
+ * @param {Record<string,(replacedString: string, originalString: string) => any>} order
42
+ * @returns { { string: string, [key: string]: any } }
43
+ */
44
+ function hashTags(string, order){
45
+ const hashes = Object.keys(order);
46
+ const h = {};
47
+ let s = string;
48
+ for(let i of hashes){
49
+ if(string.includes(`#${i}`)){
50
+ const str = s.replace(`#${i}`, '');
51
+ h[i] = order[i](str, string);
52
+ if(h[i]?.$set) {s = h[i].$set; string = s }
53
+ else s = str;
54
+ }
55
+ }
56
+ return {
57
+ string: s,
58
+ ...h
59
+ };
60
+ }
61
+
38
62
  module.exports = {
39
63
  binpath,
40
64
  logspath,
41
65
  cachepath,
42
66
  localBinPath,
43
67
  npm_package_name,
44
- getAllPipeInput
68
+ getAllPipeInput,
69
+ hashTags
45
70
  }
@@ -0,0 +1,41 @@
1
+ const { findAppInfo } = require("../misc/findAppInfo");
2
+ const { log } = require("./log");
3
+ const colors = require('colors');
4
+ const path = require('path');
5
+ const fs = require('fs');
6
+ const { CONFIG_PATH } = require("../const/config_path");
7
+
8
+ module.exports = {
9
+ types(projectPath){
10
+ if(!projectPath) projectPath = process.cwd();
11
+ else projectPath = path.resolve(process.cwd(), projectPath);
12
+ const projectinfo = findAppInfo(projectPath+'/app.yaml');
13
+ if(!projectinfo){
14
+ log('Path not a rew app'.red.bold, ':end')
15
+ return;
16
+ }
17
+ let typesToLoad = ['rew'];
18
+ if(projectinfo.config?.types){
19
+ typesToLoad = projectinfo.config?.types;
20
+ }
21
+ fs.mkdirSync(path.join(projectPath, 'node_modules/@types/rew'), { recursive: true });
22
+
23
+
24
+ typesToLoad.forEach(name => {
25
+ let filename = name+'.d.ts';
26
+ if(name == 'rew'){
27
+ fs.copyFileSync(path.join(__dirname, '../../../runtime.d.ts'), path.join(projectPath, 'node_modules/@types/rew/index.d.ts'));
28
+ return;
29
+ }
30
+ let p = path.resolve(CONFIG_PATH, name, 'app', 'types.d.ts');
31
+
32
+ if(name.indexOf('/') > -1) {
33
+ const fn = name.split('/').slice(1).join('/')+'.d.ts';
34
+ p = path.resolve(CONFIG_PATH, name.split('/')[0], 'app', fn);
35
+ filename = name.split('/')[0]+'-'+path.basename(fn);
36
+ }
37
+ if(fs.existsSync(p)) fs.copyFileSync(p, path.join(projectPath, 'node_modules/@types/rew/'+filename));
38
+ });
39
+ },
40
+
41
+ }
@@ -12,9 +12,7 @@ const { to_qrew } = require('../qrew/compile');
12
12
  const { findAppInfo } = require('../misc/findAppInfo');
13
13
  const { req } = require('../misc/req');
14
14
  const { CONFIG_PATH } = require('../const/config_path');
15
- const { watch } = require('chokidar');
16
- const { execRewFile, runFileWithArgv } = require('./run');
17
- const { seededID } = require('../misc/seededid');
15
+ const { runFileWithArgv } = require('./run');
18
16
  const loading = require('loading-cli');
19
17
  const sleep = require('../functions/sleep');
20
18
  const { gen_key } = require('../misc/bin');
@@ -24,7 +22,8 @@ const {
24
22
  binpath,
25
23
  logspath,
26
24
  cachepath,
27
- localBinPath
25
+ localBinPath,
26
+ hashTags
28
27
  } = require('./helpers');
29
28
  const { input } = require('../functions/stdout');
30
29
 
@@ -94,9 +93,13 @@ module.exports = {
94
93
  const project = {};
95
94
  const create = () => {
96
95
  fs.mkdirSync(projectPath, { recursive: true });
96
+ const confObj = { manifest: { package: project.package, private: false }, exec: { entry: 'main'+(project.civet ? REW_FILE_TYPE.EXTENSION : '.coffee') }, assets: { icon: 'assets/icon.png', folder: './assets' }, install: { requirements: [] } };
97
97
  const confPath = path.join(projectPath, 'app.yaml');
98
98
  const entryFile = path.join(projectPath, 'main'+(project.civet ? REW_FILE_TYPE.EXTENSION : '.coffee'));
99
- fs.writeFileSync(confPath, jsYaml.dump({ manifest: { package: project.package, private: false }, exec: { entry: 'main'+(project.civet ? REW_FILE_TYPE.EXTENSION : '.coffee') }, assets: { icon: 'assets/icon.png', folder: './assets' }, install: { requirements: [] } }));
99
+ if(project.intellisense) {
100
+ confObj.types = ['rew'];
101
+ }
102
+ fs.writeFileSync(confPath, jsYaml.dump(confObj));
100
103
  fs.writeFileSync(entryFile, `print("Hello World!")`);
101
104
  fs.mkdirSync(path.join(projectPath, 'assets'), { recursive: true });
102
105
  if (project.git) {
@@ -104,8 +107,8 @@ module.exports = {
104
107
  execSync('cd ' + projectPath + ' && git init . && git branch -m main', { stdio: 'ignore' });
105
108
  }
106
109
  if(project.intellisense){
107
- fs.mkdirSync(path.join(projectPath, 'node_modules/@types/rew'), { recursive: true });
108
- fs.copyFileSync(path.join(__dirname, '../../../runtime.d.ts'), path.join(projectPath, 'node_modules/@types/rew/index.d.ts'));
110
+ require('./miscUtils')
111
+ .types(projectPath);
109
112
  }
110
113
  execSync('cd ' + projectPath + ' && npm init -y', { stdio: 'ignore' });
111
114
  if(project.civet){
@@ -382,11 +385,50 @@ module.exports = {
382
385
  processFile(filePath, importsArray);
383
386
  log('󰈔 Compiled'.yellow, (importsArray.length + 1 + '').blue, `file${importsArray.length ? 's' : ''}.`.yellow, ':end');
384
387
  },
385
- cache(command){
388
+ cache(command, file){
389
+
390
+ const findGitCommitPath = (p) => {
391
+ const heads = path.join(p, '.git/refs/heads');
392
+ if(!fs.existsSync(heads)) return '';
393
+ const refs = fs.readdirSync(heads);
394
+ if(!refs.length) return '';
395
+ return fs.readFileSync(path.join(heads, refs[0]), { encoding: 'utf-8' }).trim();
396
+ }
397
+
386
398
  if(command == 'list'){
387
399
  console.log(fs.readdirSync(cachepath).join('\n').trim());
388
- } else {
389
- fs.readdirSync(cachepath).forEach(file => fs.rmSync(path.join(cachepath, file), { recursive: true }));
400
+ } else if(command == 'clear'){
401
+ if(file) fs.rmSync(path.join(cachepath, file), { recursive: true });
402
+ else if(file == 'all') fs.readdirSync(cachepath).forEach(file => fs.rmSync(path.join(cachepath, file), { recursive: true }));
403
+ } else if(command == 'install'){
404
+ if(!file) return process.exit(1);
405
+ this.installApp(path.join(cachepath, file, 'clone'), {
406
+ update: true
407
+ });
408
+ } else if(command == 'show'){
409
+ if(!file) return console.log(fs.readdirSync(cachepath).join('\n').trim());
410
+
411
+ const hashed = hashTags(file, {
412
+ tag: (str) => ({ $set: str + '#name#commit' }),
413
+ commit: (file) => findGitCommitPath(path.join(cachepath, file.replace(/#name/, ''), 'clone')),
414
+ name: (file) => jsYaml.load(fs.readFileSync(path.join(cachepath, file, 'clone/app.yaml'), { encoding: 'utf-8' }).trim()).manifest.package
415
+ });
416
+ file = hashed.string;
417
+
418
+ if(hashed.tag){
419
+ return console.log(hashed.name +':'+ hashed.commit);
420
+ }
421
+ if(hashed.commit) return console.log(hashed.commit);
422
+ if(hashed.name) return console.log(hashed.name);
423
+
424
+ const f = path.join(cachepath, file);
425
+ if(!fs.existsSync(f)) return;
426
+ if(fs.statSync(f).isDirectory()) console.log(
427
+ fs.readdirSync(f).join('\n')
428
+ );
429
+ else if(file.endsWith('app.yaml')){
430
+ console.log(fs.readFileSync(f, { encoding: 'utf-8' }).trim());
431
+ } else console.log(f);
390
432
  }
391
433
  },
392
434
  async cloneGit(gitpath, opts) {
@@ -5,7 +5,7 @@ const future = require('../functions/future');
5
5
  const sleep = require('../functions/sleep');
6
6
  const { match } = require('../functions/match');
7
7
  const { map } = require('../functions/map');
8
- const { typex, typeis, typedef, typei, int, float, num, str, bool } = require('../functions/types');
8
+ const { typex, typeis, typedef, typei, int, float, num, str, bool, typef } = require('../functions/types');
9
9
  const { isEmpty, clone, deepClone, merge, uniqueId, compose, curry, getters, setters } = require('../functions/core');
10
10
  const { print, input, clear, printf } = require('../functions/stdout');
11
11
  const { curl } = require('../functions/curl');
@@ -31,6 +31,7 @@ module.exports = {
31
31
  typei,
32
32
  typeis,
33
33
  typedef,
34
+ typef,
34
35
 
35
36
  int,
36
37
  float,
@@ -0,0 +1 @@
1
+ module.exports = class STDNS {}
@@ -1,8 +1,9 @@
1
+ const STDNS = require("./stdns");
1
2
 
2
3
 
3
4
 
4
5
  const JSX_FRAGMENT_SYMBOL = Symbol('fragment');
5
- module.exports.USING_DEFAULT = {
6
+ const USING_DEFAULT = module.exports.USING_DEFAULT = {
6
7
  JSX: {
7
8
  param: (param, fragment) => param ? ({ createElement: param, Fragment: fragment || param(JSX_FRAGMENT_SYMBOL, { isFragment: true }), fragmentSymbol: JSX_FRAGMENT_SYMBOL }) : {},
8
9
  use: (options) => options.jsx = true
@@ -15,7 +16,7 @@ module.exports.USING_DEFAULT = {
15
16
  }
16
17
  }
17
18
 
18
- module.exports.Usage = class Usage {
19
+ class Usage {
19
20
  name = "null";
20
21
  trigger = () => {};
21
22
  save = true;
@@ -61,6 +62,7 @@ module.exports.Usage = class Usage {
61
62
  }
62
63
  }
63
64
  }
65
+ module.exports.Usage = Usage;
64
66
 
65
67
  class Namespace extends module.exports.Usage {
66
68
  namespace = {};
@@ -84,7 +86,44 @@ class Namespace extends module.exports.Usage {
84
86
  module.exports.Namespace = Namespace;
85
87
 
86
88
  module.exports.namespace = (namespace, cb, parent) => {
89
+ if(namespace instanceof STDNS) {
90
+ if(namespace['@cb'] && !cb) {
91
+ cb = namespace['@cb'];
92
+ delete namespace['@cb'];
93
+ }
94
+ }
87
95
  return new Namespace(namespace, cb, parent);
88
96
  }
89
97
 
98
+ module.exports.usingFunction = (context, runtime) => {
99
+ return function using(name, ...params) {
100
+ if(name instanceof Usage.Group){
101
+ params.unshift(...name.g.slice(1));
102
+ name = name.g[0];
103
+ }
104
+ if(USING_DEFAULT[name]){
105
+ if(USING_DEFAULT[name].param) {
106
+ context.__using__[name] = USING_DEFAULT[name].param(...params);
107
+ }
108
+ } else if(name instanceof Namespace) {
109
+ const trigger = name.trigger;
110
+ const parentContext = name.parent || context;
111
+ const childContext = {...parentContext, ...name.namespace, trigger};
112
+ childContext.$self = name.namespace;
113
+ childContext.$parent = parentContext;
114
+ const code = `(${trigger.toString()})()`;
115
+ if(name.onUse) name.onUse();
116
+ const r = runtime.exec(code, childContext, code, context.module.filepath);
117
+ if(name.onAfterUse) name.onAfterUse();
118
+ return r;
119
+ } else if(name instanceof Usage) {
120
+ const v = name.trigger(...params) || true;
121
+ if(name.save !== false) context.__using__[name.name] = v;
122
+ return v;
123
+ } else {
124
+ context.__using__[name] = params.length ? params.length > 1 ? [...params] : params : true;
125
+ }
126
+ }
127
+ }
128
+
90
129
  module.exports.namespace.group = (group, props) => new Namespace.Group(group, props);
@@ -9,6 +9,12 @@ const { execOptions } = require('../const/opt');
9
9
  const { REW_FILE_TYPE } = require('../const/ext');
10
10
  const { straceLog } = require('../misc/strace');
11
11
 
12
+ const _returns = (options, content) => {
13
+ if(options.useDefaultForPackages){
14
+ return content?.default ? content : { default: content };
15
+ } else return content;
16
+ }
17
+
12
18
  const cachedFiles = [];
13
19
  module.exports.cleanCache = () => {
14
20
  while(cachedFiles.length) cachedFiles.pop();
@@ -37,7 +43,11 @@ const lookUpInOtherApps = (fullPath) => {
37
43
  module.exports.imp = function (runPath, context) {
38
44
  return function (filename, options = {}) {
39
45
  if (!options) options = {};
40
- let type = options.type || filename.endsWith('.coffee') ? 'coffee' : REW_FILE_TYPE.TYPE;
46
+ if(filename == 'std' || filename == '#std') return {};
47
+ let type = options.type ? options.type : filename.endsWith('.coffee') ? 'coffee' : (
48
+ filename.endsWith(REW_FILE_TYPE.EXTENSION) ? REW_FILE_TYPE.TYPE :
49
+ 'coffee'
50
+ );
41
51
  let exports,
42
52
  ispkg = findPackage(filename);
43
53
 
@@ -58,10 +68,10 @@ module.exports.imp = function (runPath, context) {
58
68
  else filepath = otherPath;
59
69
  };
60
70
 
61
- const foundCache = cachedFiles.find((f) => f.filepath == filepath);
71
+ const foundCache = cachedFiles.find((f) => f.filepath == type+':'+filepath);
62
72
 
63
73
  if (!ispkg && foundCache) {
64
- exports = foundCache.exports;
74
+ exports = options.useDefaultForPackages === false ? foundCache.exports.default || foundCache.exports : _returns(options, foundCache.exports);
65
75
  }
66
76
 
67
77
  if (!ispkg && !existsSync(filepath) && !foundCache) {
@@ -117,17 +127,17 @@ module.exports.imp = function (runPath, context) {
117
127
  const f = getFile(filepath);
118
128
  if (type == 'yaml') {
119
129
  straceLog('===> FROM_YAML()');
120
- exports = importYaml(f.path, f);
130
+ exports = _returns(options, importYaml(f.path, f));
121
131
  } else if (type == 'json') {
122
132
  straceLog('===>');
123
133
  try {
124
- exports = JSON.parse(f.content);
134
+ exports = _returns(options, JSON.parse(f.content));
125
135
  } catch (e) {
126
- exports = {};
136
+ exports = _returns(options, {});
127
137
  }
128
138
  } else {
129
139
  straceLog('===> FROM_TEXT');
130
- exports = f.content;
140
+ exports = _returns(options, f.content);
131
141
  }
132
142
  }
133
143
 
@@ -143,13 +153,13 @@ module.exports.imp = function (runPath, context) {
143
153
  // descriptive code
144
154
  // you put them in comment blocks
145
155
  // and name it something
146
- // then you can simple see
156
+ // then you can simply see
147
157
  // which part of a code contains a certain
148
158
  // task. cool right?
149
159
 
150
160
  //** If is not package, post exec section
151
161
  /**/ if (!ispkg) context.module.imports.push(filepath);
152
- /**/ if (!ispkg) cachedFiles.push({ filepath, exports });
162
+ /**/ if (!ispkg) cachedFiles.push({ filepath: type+':'+filepath, exports });
153
163
  //**
154
164
 
155
165
  //** Mock imports section
@@ -0,0 +1,16 @@
1
+ const { compile } = require("../modules/compiler")
2
+
3
+ const _compilePart = (code, filepath) => compile(
4
+ {
5
+ path: filepath,
6
+ content: code
7
+ },
8
+ {}
9
+ );
10
+
11
+ module.exports = (filepath) => ({
12
+ _compilePart: (code) => {
13
+ return _compilePart(code, filepath);
14
+ },
15
+ _call: (fn, ...args) => args.length ? fn.call(...args) : fn()
16
+ })
@@ -14,8 +14,19 @@ function getType(value) {
14
14
  return typeof value === 'object' ? (Array.isArray(value) ? 'array' : typeof value) : typeof value;
15
15
  }
16
16
 
17
+ class Type{
18
+ constructor(o){
19
+ for(let i in o){
20
+ this[i] = o[i];
21
+ }
22
+ }
23
+ }
24
+
17
25
  function typedef(value, strict = false) {
18
- return {
26
+ if(typeof value == "function" && value.type instanceof Type){
27
+ value = value.type;
28
+ }
29
+ return value instanceof Type ? value : new Type({
19
30
  strict,
20
31
  defaultValue: value,
21
32
  class:
@@ -25,25 +36,50 @@ function typedef(value, strict = false) {
25
36
  ? value.constructor
26
37
  : _defaultConstructors[getType(value)],
27
38
  type: getType(value),
28
- isConstucted: typeof value === 'object' && value !== null && !Array.isArray(value),
39
+ isConstructed: typeof value === 'object' && value !== null && !Array.isArray(value),
29
40
  isEmpty: typeof value == 'object' ? !Object.keys(value).length : typeof value == 'string' ? value == '' : typeof value !== 'function',
30
- };
41
+ });
42
+ }
43
+
44
+ function typef(fn, returnType) {
45
+ if(typeof returnType == "function"){
46
+ const ref = fn;
47
+ fn = returnType;
48
+ returnType = ref;
49
+ }
50
+ if (typeof fn !== 'function') {
51
+ throw new Error('First argument must be a function');
52
+ }
53
+ if (typeof returnType == 'function' && returnType.type instanceof Type) returnType = returnType.type;
54
+ const wrappedFn = function(...args){
55
+ const result = fn.call(this, ...args);
56
+ if(!typeis(result, wrappedFn.returnType)){
57
+ throw new TypeError(`Function ${fn.name || '<anonymous>'} does not return it's own return type.`);
58
+ }
59
+ return result;
60
+ }
61
+ wrappedFn.returnType = returnType;
62
+ wrappedFn.type = returnType;
63
+ return wrappedFn;
64
+ }
65
+ typef.is = function(func, returnType){
66
+ return typeis(func.returnType.defaultValue, returnType);
31
67
  }
32
68
 
33
- function typeis(obj, typeDef) {
69
+ function typeis(obj, typeDef, missingObjects = false) {
34
70
  // Resolve Type
35
- if (typeof typeDef == 'function' && typeDef.type) typeDef = typeDef.type;
71
+ if (typeof typeDef == 'function' && typeDef.type instanceof Type) typeDef = typeDef.type;
36
72
 
37
- if (typeDef.isConstucted && typeDef.class && !(obj instanceof typeDef.class)) {
38
- return false;
73
+ if (typeDef.isConstructed && typeDef.class && !(obj instanceof typeDef.class)) {
74
+ return missingObjects ? [false] : false;
39
75
  }
40
76
 
41
77
  if (getType(obj) == 'object' && typeDef.type == 'function') {
42
- return obj instanceof typeDef.class;
78
+ return missingObjects ? [obj instanceof typeDef.class] : obj instanceof typeDef.class;
43
79
  }
44
80
 
45
81
  if (getType(obj) !== typeDef.type) {
46
- return false;
82
+ return missingObjects ? [false] : false;
47
83
  }
48
84
 
49
85
  if (!typeDef.isEmpty) {
@@ -55,14 +91,28 @@ function typeis(obj, typeDef) {
55
91
 
56
92
  if (typeof propTypeDef === 'object') {
57
93
  if (!typeis(obj[key], propTypeDef)) {
58
- return false;
94
+ return missingObjects ? [false, {
95
+ [key]: {
96
+ type_mismatch: propTypeDef,
97
+ given: obj[gen_key]
98
+ }
99
+ }] : false;
59
100
  }
60
- } else if (typeof obj[key] !== propTypeDef) {
61
- return false;
101
+ } else if (typeof obj[key] !== typeof propTypeDef) {
102
+ return missingObjects ? [false, {
103
+ [key]: obj[key] ? {
104
+ type_mismatch: typeof propTypeDef,
105
+ given: typeof obj[key]
106
+ } : {
107
+ not_found: true
108
+ }
109
+ }] : false;
62
110
  }
63
111
  }
64
112
  if (typeDef.strict) {
65
- if (Object.keys(obj).some((key) => !Object.keys(typeDef.defaultValue).includes(key))) return false;
113
+ if (Object.keys(obj).some((key) => !Object.keys(typeDef.defaultValue).includes(key))) return missingObjects ?
114
+ [false, Object.fromEntries(Object.keys(obj).filter((key) => !Object.keys(typeDef.defaultValue).includes(key)).map((key) => [key, { is_extra: true }]))]
115
+ : false;
66
116
  }
67
117
  } else if (typeDef.type == 'string') {
68
118
  return typeDef.defaultValue == obj;
@@ -71,7 +121,7 @@ function typeis(obj, typeDef) {
71
121
  }
72
122
  }
73
123
 
74
- return true;
124
+ return missingObjects ? [true] : true;
75
125
  }
76
126
 
77
127
  function typex(child, parent) {
@@ -112,6 +162,7 @@ module.exports = {
112
162
  typei,
113
163
  typeis,
114
164
  typedef,
165
+ typef,
115
166
 
116
167
  int,
117
168
  float,
@@ -86,6 +86,15 @@ function tokenizeCoffeeScript(code) {
86
86
  }
87
87
  tokens.push({ type: 'IDENTIFIER', value: identifier });
88
88
  i--; // Move back one character to recheck
89
+ } else if (/[a-f0-9.n]/.test(char)) {
90
+ let num = char;
91
+ i++;
92
+ while (i < code.length && /[a-f0-9.n]/.test(code[i])) {
93
+ num += code[i];
94
+ i++;
95
+ }
96
+ tokens.push({ type: 'NUMBER', value: num });
97
+ i--; // Move back one character to recheck
89
98
  } else {
90
99
  // Other characters
91
100
  tokens.push({ type: 'OTHER', value: char });
@@ -106,6 +115,13 @@ const ValueIfy = (val) => {
106
115
  }
107
116
  }
108
117
 
118
+ function insertTokenAt(array, index, value) {
119
+ if (index < 0 || index > array.length) {
120
+ throw new RangeError('Index out of bounds');
121
+ }
122
+ array.splice(index, 0, value);
123
+ }
124
+
109
125
  const gnextToken = (i, n, tokens) => {
110
126
  return tokens[i + n] ? (tokens[i + n].type == 'WHITESPACE' ? gnextToken(i, n + 1, tokens) : { token: tokens[i + n], n, ti: i + n }) : null;
111
127
  };
@@ -153,7 +169,7 @@ function declareAlias(aliases, token) {
153
169
  aliasValue = (token, tokens, code, hooks, index, setIndex) => {
154
170
  const nextToken = tokens[index+1]
155
171
  let nextToken2 = gnextToken(index, 3, tokens);
156
- if (nextToken.value == '(' || tokens[index+2]?.value == '(') {
172
+ if (nextToken?.value == '(' || tokens[index+2]?.value == '(') {
157
173
  let params = '';
158
174
  index += 2;
159
175
  let openBrackets = 1;
@@ -172,7 +188,7 @@ function declareAlias(aliases, token) {
172
188
  let nextToken = gnextToken(index, offset+1, tokens);
173
189
  const args = nextToken.token.value;
174
190
  setIndex(ti + offset);
175
- return `${nextToken2.value} = ${token.value} ${args && args !== '(' ? `${args},` : ''} ${params.trim()}, ${args == '(' ? args : ''}`;
191
+ return `${nextToken2.value} = ${token.value} ${args && args !== '(' && args !== '{' && args !== '[' && args !== '-' && args !== '=' ? `${args},` : ''} ${params.trim() ? params.trim() + ', ' : ''}${args == '(' || args == '[' || args == '{' || args == '=' || args == '-' ? args : ''}`.replace(/,(| )$/, '');
176
192
  } else if(nextToken?.value == ' ' && (isDecOnly || nextToken2?.token.value == '=' || nextToken2?.token.value == ':')){
177
193
  nextToken.value = '';
178
194
  if(isDecOnly){
@@ -204,7 +220,21 @@ function declareAlias(aliases, token) {
204
220
  }
205
221
  }
206
222
 
207
-
223
+ const stdTypes = (isPublic) => {
224
+ let r = '';
225
+ const dec = (name, fn) => {
226
+ r += `#declare${isPublic?'*':''} key "=${name}" = ${fn || name};\n`
227
+ }
228
+ dec('int');
229
+ dec('str');
230
+ dec('float');
231
+ dec('num');
232
+ dec('bool');
233
+ dec('typedef');
234
+ dec('typef');
235
+ dec('struct');
236
+ return r;
237
+ };
208
238
  const includeFile = (includeContent, options) => {
209
239
  straceLog('INCLUDE()', includeContent);
210
240
  const dontInclude = includeContent.startsWith('*');
@@ -212,21 +242,30 @@ const includeFile = (includeContent, options) => {
212
242
  includeContent = includeContent.slice(1);
213
243
  straceLog('==> IGNORING OUTPUT', includeContent);
214
244
  };
215
- let filename = options.filename ? path.resolve(path.dirname(options.filename), includeContent) : includeContent;
216
- const _inc = (filename) => '\n'+ compileRewStuff(readFileSync(filename).toString(), {
217
- ...options,
218
- filename,
219
- included: true
220
- })+'\n';
245
+ const fp = path.resolve(path.dirname(options.filename || ''), includeContent);
246
+ let packageName = options.filename ? (existsSync(fp) ? fp : includeContent) : includeContent;
247
+ const file = packageName.startsWith('./') || packageName.startsWith('../');
248
+ if(!(file) && packageName.match('/')) packageName = packageName.split('/').pop();
249
+ if(file) packageName = path.extname(packageName) ? packageName.replace(path.extname(packageName), '.h.coffee') : packageName;
250
+ if(file && !packageName.endsWith('.h.coffee')) packageName += '.h.coffee';
251
+ if(includeContent == 'std') packageName = 'std';
252
+
253
+ const _inc = (filename, c) => {
254
+ options.included = true;
255
+ options.filename = filename;
256
+ return '\n'+ compileRewStuff(c ? filename : readFileSync(filename).toString(), options)+'\n'
257
+ };
221
258
  let r = '';
222
- if (existsSync(filename)) {
223
- straceLog('==> INCLUDE FILE', filename);
224
- r = _inc(filename);
259
+ if(packageName == 'std'){
260
+ r = _inc(stdTypes(dontInclude), true);
261
+ } else if (existsSync(packageName)) {
262
+ straceLog('==> INCLUDE FILE', packageName);
263
+ r = _inc(packageName);
225
264
  } else {
226
265
  const packageName = includeContent.match('/') ? includeContent.split('/')[0] : includeContent;
227
266
  const headerFile = includeContent.match('/') ? includeContent.replace(packageName+'/', '') : 'main.h.coffee';
228
267
  const pathname = path.join(CONFIG_PATH, packageName, 'app', headerFile);
229
- straceLog('==> INCLUDE PACKAGE', filename);
268
+ straceLog('==> INCLUDE PACKAGE', packageName);
230
269
  if(existsSync(pathname)) r = _inc(pathname);
231
270
  }
232
271
  if(dontInclude){
@@ -245,16 +284,22 @@ function useImp(token, options){
245
284
  const value = token.value.slice(1, -1);
246
285
  let packageName = value.slice(1);
247
286
  token.value = dem+packageName+dem;
248
- const file = packageName.startsWith('./') || packageName.startsWith('../');
249
- if(!(file) && packageName.match('/')) packageName = packageName.split('/').pop();
250
- if(file) packageName = path.extname(packageName) ? packageName.replace(path.extname(packageName), '.h.coffee') : packageName;
251
- if(file && !packageName.endsWith('.h.coffee')) packageName += '.h.coffee';
252
287
  straceLog('IMP() with HEADER for', packageName);
253
- return includeFile(packageName, options);
288
+ return includeFile(packageName !== 'std' ? packageName : '*'+packageName, options);
254
289
  }
255
290
  return '';
256
291
  }
257
292
 
293
+ function updateAliases(aliases, o = execOptions._syntaxAliases){
294
+ for(let h in o){
295
+ for(let i in o[h]){
296
+ if(!aliases[h]) aliases[h] = {};
297
+ aliases[h][i] = o[h][i]
298
+ }
299
+ }
300
+ return aliases;
301
+ }
302
+
258
303
  function compileRewStuff(content, options) {
259
304
  straceLog('TOKENIZE() for CURRENTFILE');
260
305
  const tokens = tokenizeCoffeeScript(content);
@@ -292,6 +337,19 @@ function compileRewStuff(content, options) {
292
337
  }
293
338
  }
294
339
 
340
+ if (token.type === "COMMENT" && token.value.startsWith('#alias')) {
341
+ let value = '#declare';
342
+ if(token.value.match(/^#alias\*/)) value += '*';
343
+ let subs;
344
+ subs = token.value.replace(/^#alias/, '');
345
+ if(token.value.endsWith('*')) subs.split('*')[1];
346
+
347
+ value += ' key';
348
+ value += ' ' + subs.replace(/([\S]+)\s*=\s*([\S]+)/, '"$1" = $2').trim();
349
+ value += ';';
350
+ declareAlias(aliases, {...token, value});
351
+ }
352
+
295
353
  if (token.type === "COMMENT" && token.value.startsWith('#declare')) {
296
354
  if (token.value.includes(';')) {
297
355
  declareAlias(aliases, token);
@@ -309,28 +367,6 @@ function compileRewStuff(content, options) {
309
367
  }
310
368
  }
311
369
 
312
- if (token.type === 'IDENTIFIER' && token.value === 'imp') {
313
- straceLog('IMP() Detected');
314
- let { token: t1 } = gnextToken(i, 1, tokens) || {};
315
- let { token: t2 } = gnextToken(i, 2, tokens) || {};
316
- let r = '';
317
-
318
- if(t1.value == '('){
319
- if(t2.type == 'STRING'){
320
- r = useImp(t2, options);
321
- }
322
- } else if(t1.type == 'STRING'){
323
- r = useImp(t1, options);
324
- }
325
-
326
- if(r) {
327
- aliases = {
328
- ...aliases,
329
- ...execOptions._syntaxAliases
330
- }
331
- }
332
- }
333
-
334
370
  if (token.type === 'COMMENT' && token.value.slice(1).trim().startsWith('@jsx')) {
335
371
  options.jsx = true;
336
372
  straceLog('JSX() ENABLE WITH COMMENTS');
@@ -342,7 +378,7 @@ function compileRewStuff(content, options) {
342
378
 
343
379
  if (token.type === 'COMMENT' && token.value.slice(1).trim() === '@cls') {
344
380
  options.cls = true;
345
- straceLog('CLITOKENIZATION() ENABLE');
381
+ straceLog('CLI_SYNTAX() ENABLE');
346
382
  straceLog('===> HIGHLY EXPERIMENTAL FEATURE DETECTED');
347
383
  }
348
384
 
@@ -365,6 +401,11 @@ function compileRewStuff(content, options) {
365
401
  token.value = 'pub';
366
402
  straceLog('EXPORT() => TRANSLATING TO pub');
367
403
  }
404
+
405
+ if (token.type === 'IDENTIFIER' && token.value === 'package' && nextToken.type == 'STRING') {
406
+ token.value = 'appPackage';
407
+ straceLog('APP_PACKAGE_CHANGE()');
408
+ }
368
409
 
369
410
  if (token.type === 'IDENTIFIER' && token.value === 'using' && !options.disableUse) {
370
411
  straceLog('USING()');
@@ -380,15 +421,30 @@ function compileRewStuff(content, options) {
380
421
  } else straceLog('==> UNKNOWN');
381
422
  }
382
423
 
424
+ if (token.type === 'IDENTIFIER' && token.value === 'as' && !options.keepImports) {
425
+ const isFrom = gnextToken(i, 3, tokens);
426
+ const isInImport = tokens[i-2];
427
+ if(isFrom?.token.value == 'from' && isInImport?.value !== '*'){
428
+ insertTokenAt(tokens, i, { type: 'WHITESPACE', value: ' ' });
429
+ insertTokenAt(tokens, i, { type: 'OTHER', value: '*' });
430
+ insertTokenAt(tokens, i, { type: 'WHITESPACE', value: ' ' });
431
+ insertTokenAt(tokens, i, { type: 'IDENTIFIER', value: 'import' });
432
+ i -= 1;
433
+ continue;
434
+ }
435
+ }
436
+
383
437
  if (token.type === 'IDENTIFIER' && token.value === 'import' && !options.keepImports) {
384
438
  // console.log(nextToken.type);
385
439
  straceLog('IMPORT()');
386
- straceLog('==> WARN: SLOWS DOWN TOKENIZATION');
440
+ straceLog('==> WARN: SLOWS DOWN COMPILATION');
387
441
  let ind = i + n + 2;
442
+ let isAs = false;
388
443
 
389
444
  let defaultName;
390
445
  if (nextToken.type === 'STRING') {
391
446
  straceLog('==> SIMPLE');
447
+ if(useImp(nextToken, options)) updateAliases(aliases);
392
448
  result += `inc ${nextToken.value}`;
393
449
  i += n;
394
450
  } else if (nextToken.value === '{') {
@@ -405,18 +461,21 @@ function compileRewStuff(content, options) {
405
461
 
406
462
  straceLog('==>', exports, 'from', nameToken.value);
407
463
 
464
+ if(useImp(nameToken, options)) updateAliases(aliases);
408
465
  result += `{ ${exports} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken.value}`;
409
466
  i = nameToken.ti;
410
467
  }
411
468
  } else if (nextToken.value === '*') {
412
469
  const asToken = fnextToken(ind, tokens, 'IDENTIFIER', 'as');
413
- const nameToken = fnextToken(asToken.ri, tokens, 'STRING');
414
470
  if (asToken) {
471
+ const nameToken = fnextToken(asToken.ti, tokens, 'STRING');
415
472
  const nextToken = fnextToken(asToken.ti + 1, tokens, 'IDENTIFIER');
416
473
  defaultName = nextToken.value;
417
474
  straceLog('==>', defaultName, 'from', nameToken.value);
475
+ if(useImp(nameToken, options)) updateAliases(aliases);
418
476
  result += `${defaultName} ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken.value}`;
419
477
  i = ind + 6;
478
+ isAs = true;
420
479
  }
421
480
  } else if (nextToken) {
422
481
  const nameToken = fnextToken(ind, tokens, 'STRING');
@@ -433,10 +492,12 @@ function compileRewStuff(content, options) {
433
492
  .filter((t, i, arr) => !arr[i+1]?.match(':') && !arr[i-1]?.match(':'))
434
493
  .join(', ');
435
494
  straceLog('==>', defaultName, 'and', exports, 'from', nameToken.value);
495
+ if(useImp(nameToken, options)) updateAliases(aliases);
436
496
  result += `{ default: ${defaultName}, ${exports} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken?.value || ''}`;
437
497
  i = closingBraceToken.ti + 4;
438
498
  }
439
499
  } else {
500
+ if(useImp(nameToken || {}, options)) updateAliases(aliases);
440
501
  result += `{ default: ${defaultName} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken?.value || ''}`;
441
502
  i = ind + 2;
442
503
  }
@@ -451,19 +512,38 @@ function compileRewStuff(content, options) {
451
512
  if(assertionToken.token.type == 'OTHER' && assertionToken.token.value == '{'){
452
513
  hooks.push({
453
514
  index: assertionToken.token.ti,
454
- value: ' useDefaultForPackages: true, '
515
+ value: ' useDefaultForPackages: '+(isAs?'false':'true')+', '
455
516
  })
456
517
  } else {
457
- result += 'useDefaultForPackages: true, '
518
+ result += 'useDefaultForPackages: '+(isAs?'false':'true')+', '
458
519
  }
459
520
  i += 3;
460
521
  } else {
461
- result += ", { useDefaultForPackages: true }"
522
+ result += ", { useDefaultForPackages: "+(isAs?'false':'true')+" }"
462
523
  }
463
524
 
464
525
  continue;
465
526
  }
466
527
 
528
+ if (token.type === 'IDENTIFIER' && (token.value === 'imp' || token.value === 'inc')) {
529
+ straceLog('IMP() Detected');
530
+ let { token: t1 } = gnextToken(i, 1, tokens) || {};
531
+ let { token: t2 } = gnextToken(i, 2, tokens) || {};
532
+ let r = '';
533
+
534
+ if(t1?.value == '('){
535
+ if(t2?.type == 'STRING'){
536
+ r = useImp(t2, options);
537
+ }
538
+ } else if(t1?.type == 'STRING'){
539
+ r = useImp(t1, options);
540
+ }
541
+
542
+ if(r) {
543
+ updateAliases(aliases);
544
+ }
545
+ }
546
+
467
547
  if (
468
548
  token.type === 'IDENTIFIER' &&
469
549
  token.value === 'pub' &&
@@ -516,16 +596,18 @@ function compileRewStuff(content, options) {
516
596
 
517
597
  if (token.type === "COMMENT" && token.value.startsWith('#include')) {
518
598
  const includeContent = token.value.split(' ')[1].trim() || '';
519
- const r = includeFile(includeContent, options);
599
+ const _o = {...options};
600
+ const r = includeFile(includeContent, _o);
520
601
  if(r){
521
602
  result += r == 'intentional-nothing' ? '' : r;
522
- aliases = {
523
- ...aliases,
524
- ...execOptions._syntaxAliases
525
- }
603
+ updateAliases(aliases, _o.aliases);
526
604
  }
527
605
  }
528
606
  }
607
+
608
+ if(options.included){
609
+ options.aliases = aliases;
610
+ }
529
611
  // console.log(aliases);
530
612
  // console.log(result);
531
613
  return result;
@@ -540,6 +622,8 @@ const compileCivetStuff = (file, options) => {
540
622
  straceLog('OPTION_PREPARE() for CURRENTFILE as', preCompileOptions);
541
623
  const prepared = compileRewStuff(file.content, preCompileOptions);
542
624
 
625
+ // console.log(prepared);
626
+
543
627
  const compileOptions = {
544
628
  ...preCompileOptions,
545
629
  bare: true,
@@ -8,10 +8,11 @@ const pathLib = require("../functions/path");
8
8
  const path = require("path");
9
9
  const execLib = require("../functions/exec");
10
10
  const { findAppInfo } = require("../misc/findAppInfo");
11
- const { USING_DEFAULT, Usage, Namespace } = require("../const/usage");
11
+ const { Usage, usingFunction } = require("../const/usage");
12
12
  const runtime = require("./runtime");
13
- const { permission } = require("process");
14
13
  const { straceLog } = require("../misc/strace");
14
+ const reval = require("../functions/reval");
15
+ const STDNS = require("../const/stdns");
15
16
 
16
17
  let mainFile = "";
17
18
  const isMainFile = (filepath) => filepath == mainFile;
@@ -37,6 +38,7 @@ module.exports.prepareContext = function (
37
38
  },
38
39
  app: findAppInfo(filepath),
39
40
  ...fsLib(filepath),
41
+ ...reval(filepath),
40
42
  __using__: {}
41
43
  };
42
44
  if (options.useContext) {
@@ -45,14 +47,41 @@ module.exports.prepareContext = function (
45
47
  ...context,
46
48
  };
47
49
  } else {
50
+ const std = {...defaultContext};
48
51
  context = {
49
52
  ...context,
50
- ...defaultContext,
53
+ ...std,
51
54
  ...pathLib(filepath),
52
55
  ...execLib(filepath),
53
56
  ...custom_context,
54
57
  Usage
55
58
  };
59
+ std.prototype = { ns: (cb) => {
60
+ return new (class extends STDNS {
61
+ constructor(){
62
+ super();
63
+ for(let i in std){
64
+ this[i] = std[i];
65
+ }
66
+ this.define = std.prototype.define;
67
+ this.Main = std.prototype.Main;
68
+ this['@cb'] = cb;
69
+ }
70
+ });
71
+ }, define: (name, object) => {
72
+ if(Array.isArray(name) && name.length == 2 && typeof name[0] == 'string'){
73
+ object = name[1];
74
+ name = name[0];
75
+ }
76
+ if(!context.module.exports) context.module.exports = {};
77
+ context.module.exports[name] = object;
78
+ context[name] = object;
79
+ }, Main: (cb) => (['main', cb?.main ?? cb]), attach: (object) => {
80
+ for(let i in object){
81
+ if(!context[i]) context[i] = object[i];
82
+ }
83
+ } }
84
+ context.std = std;
56
85
  }
57
86
  if (!context.process)
58
87
  context.process = {
@@ -68,10 +97,19 @@ module.exports.prepareContext = function (
68
97
  abort: () => process.abort(),
69
98
  kill: () => process.kill(),
70
99
  exit: (code) => process.exit(code),
100
+ chdir: (dir) => process.chdir(dir),
101
+ disconnect: () => process.disconnect(),
71
102
  arch: process.arch,
72
103
  pid: process.pid,
73
104
  platform: process.platform,
74
- permission: process.permission
105
+ channel: process.channel,
106
+ uptime: () => process.uptime(),
107
+ nextTick: (callback, ...args) => process.nextTick(callback, ...args),
108
+ permission: process.permission,
109
+ transmit: {
110
+ send: (...data) => process.send(...data),
111
+ recieve: (cb) => process.on('message', cb)
112
+ }
75
113
  };
76
114
 
77
115
  context.global = context;
@@ -118,34 +156,7 @@ module.exports.prepareContext = function (
118
156
  context.pub = pubFunction(context);
119
157
  context.exports = exportsFunction(context);
120
158
 
121
- context.using = (name, ...params) => {
122
- if(name instanceof Usage.Group){
123
- params.unshift(...name.g.slice(1));
124
- name = name.g[0];
125
- }
126
- if(USING_DEFAULT[name]){
127
- if(USING_DEFAULT[name].param) {
128
- context.__using__[name] = USING_DEFAULT[name].param(...params);
129
- }
130
- } else if(name instanceof Namespace) {
131
- const trigger = name.trigger;
132
- const parentContext = name.parent || context;
133
- const childContext = {...parentContext, ...name.namespace, trigger};
134
- childContext.currentNamespace = name.namespace;
135
- childContext.parentNamespace = parentContext;
136
- const code = `(${trigger.toString()})()`;
137
- if(name.onUse) name.onUse();
138
- const r = runtime.exec(code, childContext, code, context.module.filepath);
139
- if(name.onAfterUse) name.onAfterUse();
140
- return r;
141
- } else if(name instanceof Usage) {
142
- const v = name.trigger(...params) || true;
143
- if(name.save !== false) context.__using__[name.name] = v;
144
- return v;
145
- } else {
146
- context.__using__[name] = params.length ? params.length > 1 ? [...params] : params : true;
147
- }
148
- };
159
+ context.using = usingFunction(context, runtime);
149
160
 
150
161
  if(context.app?.config?.exec?.['auto import']){
151
162
  const autoipath = path.join(context.app.path, context.app.config?.exec?.['auto import']);
@@ -36,7 +36,8 @@ module.exports.runPath = function runPath(filepath, options = {}, custom_context
36
36
 
37
37
  if(context.app){
38
38
  const p = path.join(CONFIG_PATH, context.app.config.manifest.package, 'app');
39
- if(existsSync(p) && context.app.path !== p){
39
+ const p2 = path.join(CONFIG_PATH, context.app.config.manifest.package, 'app/.allow');
40
+ if(existsSync(p) && context.app.path !== p && !existsSync(p2)){
40
41
  console.log("App with the same package name has been installed. Conflicts happened. \nTo fix this, change your app's package name or remove the app making the conflict.");
41
42
  return {
42
43
  context: { module: { exports: null } },
@@ -46,11 +47,21 @@ module.exports.runPath = function runPath(filepath, options = {}, custom_context
46
47
  }
47
48
 
48
49
  compiled_code = preScript+'\n'+compiled_code;
49
-
50
- return {
51
- context,
52
- returns: exec(compiled_code, context, file.content),
53
- };
50
+
51
+ let execd = exec(compiled_code, context, file.content);
52
+
53
+ if(context.module.main && (context.module.exports?.main || (typeof context.module.exports == "function" && context.module.exports.name == 'main'))){
54
+ const mainFn = context.module.exports.main ?? context.module.exports;
55
+ return {
56
+ context,
57
+ returns: mainFn.call(context, context.process.argv)
58
+ }
59
+ } else {
60
+ return {
61
+ context,
62
+ returns: execd,
63
+ };
64
+ }
54
65
  }
55
66
 
56
67
  if(options.async){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makano/rew",
3
- "version": "1.2.901",
3
+ "version": "1.2.971",
4
4
  "description": "A simple coffescript runtime and app manager",
5
5
  "main": "main.js",
6
6
  "directories": {