sptc 0.0.0 → 0.0.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.
- package/README.md +72 -0
- package/bin/sptc.js +25 -0
- package/bin/sptcd.js +39 -0
- package/dist/httpServer.js +147 -0
- package/dist/webpack.loader.js +48 -0
- package/engine/compiler-macro.js +237 -0
- package/engine/compiler.js +81 -0
- package/engine/index.js +64 -0
- package/engine/interpreter-macro.js +77 -0
- package/engine/interpreter.js +291 -0
- package/package.json +8 -1
- package/tests/bin.sh +9 -0
- package/tests/engine/TestModel.sjs +7 -0
- package/tests/engine/a.sjs +58 -0
- package/tests/engine/ee.sjs +17 -0
- package/tests/engine/m1.js +20 -0
- package/tests/engine/ppp.sjs +6 -0
- package/tests/engine/test-macro.js +16 -0
- package/tests/engine/test.js +33 -0
- package/tests/www/index.sjs +17 -0
- package/utils/base.js +65 -0
- package/utils/compileFile.js +38 -0
- package/utils/fpm.js +15 -0
- package/utils/index.js +6 -0
package/engine/index.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const Compiler=require('./compiler')
|
|
2
|
+
const Interpreter=require('./interpreter')
|
|
3
|
+
const CompilerMacro=require('./compiler-macro')
|
|
4
|
+
const InterpreterMacro=require('./interpreter-macro')
|
|
5
|
+
|
|
6
|
+
const {md5}=require('../utils')
|
|
7
|
+
|
|
8
|
+
function executeSptcFile(filename, payload, option={}) {
|
|
9
|
+
const {__DEV__, macroOption, mockFileContent}=option
|
|
10
|
+
|
|
11
|
+
// using macro preprocessor or provides a mock content will critically degrade the performance
|
|
12
|
+
// if you really want to use them, specified the option.__DEV__ as true
|
|
13
|
+
const _option=__DEV__!==true? {}: {
|
|
14
|
+
mockFileContent,
|
|
15
|
+
contentWrapper: macroOption?
|
|
16
|
+
content=>executeSptcMacroFile(filename, macroOption, content):
|
|
17
|
+
undefined,
|
|
18
|
+
cacheKeyWrapper: (!mockFileContent && !macroOption)?
|
|
19
|
+
undefined:
|
|
20
|
+
filename=>md5(filename+'\n'+[mockFileContent || '', ...(macroOption.defs || [])].join('\n')),
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const [ctx0, vm]=Compiler.compileSptcFile(filename, _option)
|
|
24
|
+
const [ctx, priv]=Interpreter.buildContext({...payload, ...ctx0}, option)
|
|
25
|
+
Interpreter.executeVm(vm, ctx, priv)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function executeSptcFileEx(...x) {
|
|
29
|
+
const e=new Promise((resolve, reject)=>{
|
|
30
|
+
const {end, onError, readAsBinary}=(x[2]=x[2] || {})
|
|
31
|
+
const buf=[]
|
|
32
|
+
x[2].write=(...x)=>{
|
|
33
|
+
buf.push(...x)
|
|
34
|
+
}
|
|
35
|
+
x[2].end=_=>{
|
|
36
|
+
end && end()
|
|
37
|
+
resolve(readAsBinary? Buffer.concat(buf): buf.join(''))
|
|
38
|
+
}
|
|
39
|
+
x[2].onError=e=>{
|
|
40
|
+
onError && onError(e)
|
|
41
|
+
reject(e)
|
|
42
|
+
}
|
|
43
|
+
executeSptcFile(...x)
|
|
44
|
+
})
|
|
45
|
+
e.catch(_=>null)
|
|
46
|
+
return e
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function executeSptcMacroFile(filename, config, mockContent) {
|
|
50
|
+
const ast=CompilerMacro.compileSptcMacroFile(filename, mockContent)
|
|
51
|
+
const ctx=InterpreterMacro.buildMacroContext({filename, ...config})
|
|
52
|
+
return InterpreterMacro.executeMacroContext(ctx, ast)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports={
|
|
56
|
+
...Compiler,
|
|
57
|
+
...Interpreter,
|
|
58
|
+
...CompilerMacro,
|
|
59
|
+
...InterpreterMacro,
|
|
60
|
+
executeSptcFile,
|
|
61
|
+
executeSptcFileEx,
|
|
62
|
+
executeSptcMacroFile,
|
|
63
|
+
version: require('../package.json').version
|
|
64
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const {compileSptcMacroFile, MACRO_TYPES}=require('./compiler-macro')
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
O_IFDEF,
|
|
5
|
+
O_STR,
|
|
6
|
+
O_DEFINE_CONST,
|
|
7
|
+
O_DEFINE_CALL,
|
|
8
|
+
O_CALL_CONST,
|
|
9
|
+
O_CALL_DEFINE,
|
|
10
|
+
O_DEF,
|
|
11
|
+
O_INCLUDE,
|
|
12
|
+
O_UNDEF,
|
|
13
|
+
}=MACRO_TYPES
|
|
14
|
+
|
|
15
|
+
function buildMacroContext({filename, ...inherits}) {
|
|
16
|
+
const ctx=Object.assign({
|
|
17
|
+
defs: new Set,
|
|
18
|
+
defines: {},
|
|
19
|
+
filename: filename || '',
|
|
20
|
+
}, inherits || {})
|
|
21
|
+
if(filename) {
|
|
22
|
+
ctx.filename=filename
|
|
23
|
+
}
|
|
24
|
+
if(Array.isArray(ctx.defs)) {
|
|
25
|
+
ctx.defs=new Set(ctx.defs)
|
|
26
|
+
}
|
|
27
|
+
return ctx
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function execute(ctx, ast) {
|
|
31
|
+
let ret=''
|
|
32
|
+
for(let i=0; i<ast.length; i++) {
|
|
33
|
+
const p=ast[i]
|
|
34
|
+
if(p.type===O_IFDEF) {
|
|
35
|
+
const {match, consequent, alternate}=p
|
|
36
|
+
const sub_tree=ctx.defs.has(match)? consequent: alternate
|
|
37
|
+
ret+=execute(ctx, sub_tree)
|
|
38
|
+
}else if(p.type===O_STR) {
|
|
39
|
+
ret+=p.str
|
|
40
|
+
}else if(p.type===O_DEFINE_CONST) {
|
|
41
|
+
ctx.defines[p.cname]=p.cvalue
|
|
42
|
+
}else if(p.type===O_DEFINE_CALL) {
|
|
43
|
+
ctx.defines[p.fname]=p.fcall
|
|
44
|
+
}else if([O_CALL_CONST, O_CALL_DEFINE].includes(p.type)) {
|
|
45
|
+
if(!(p.call in ctx.defines)) {
|
|
46
|
+
ret+=p.source
|
|
47
|
+
}else{
|
|
48
|
+
if(p.type===O_CALL_CONST) {
|
|
49
|
+
ret+=ctx.defines[p.call]
|
|
50
|
+
}else{
|
|
51
|
+
ret+=ctx.defines[p.call](...p.argv)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}else if(p.type===O_DEF) {
|
|
55
|
+
ctx.defs.add(p.def)
|
|
56
|
+
}else if(p.type===O_UNDEF) {
|
|
57
|
+
ctx.defs.delete(p.def)
|
|
58
|
+
}else if(p.type===O_INCLUDE) {
|
|
59
|
+
const filename=path.resolve(ctx.filename+'/..', p.include)
|
|
60
|
+
const nctx=Object.assign({}, ctx, {filename})
|
|
61
|
+
ret+=executeContext(nctx)
|
|
62
|
+
}else{
|
|
63
|
+
throw new Error('unsupported node: '+JSON.stringify(p))
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return ret
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function executeMacroContext(ctx, ast) {
|
|
70
|
+
const {filename}=ctx
|
|
71
|
+
return execute(ctx, ast || compileSptcMacroFile(filename))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports={
|
|
75
|
+
buildMacroContext,
|
|
76
|
+
executeMacroContext,
|
|
77
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
const _module=require('module')
|
|
2
|
+
const vm=require('vm')
|
|
3
|
+
const path=require('path')
|
|
4
|
+
const Compiler=require('./compiler')
|
|
5
|
+
const {generate_uuid}=require('../utils')
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
const tt={x: 2, b: [2, 5], c: _=>2, d: /xx/ig}
|
|
9
|
+
tt.y=tt
|
|
10
|
+
tt.qq=[{r: tt}]
|
|
11
|
+
const r1={zzz: 44}
|
|
12
|
+
r1.rrr=r1
|
|
13
|
+
tt.H=r1
|
|
14
|
+
console.log(var_dump(tt))
|
|
15
|
+
*/
|
|
16
|
+
function var_dump(...x) {
|
|
17
|
+
return x.map(_var_dump).join('\n')
|
|
18
|
+
}
|
|
19
|
+
function _var_dump(x) {
|
|
20
|
+
let i=new WeakSet, b=0, K=generate_uuid('VAR_DUMP__'), ls=[]
|
|
21
|
+
JSON.stringify(x, (k, v)=>{
|
|
22
|
+
if(v && typeof v==='object') {
|
|
23
|
+
if(!i.has(v)) {
|
|
24
|
+
v[K]=b++
|
|
25
|
+
i.add(v)
|
|
26
|
+
ls.push(v)
|
|
27
|
+
}else return 0
|
|
28
|
+
}
|
|
29
|
+
return v
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
i=new WeakSet
|
|
33
|
+
b=0
|
|
34
|
+
ls=[]
|
|
35
|
+
|
|
36
|
+
const e=JSON.stringify(x, (k, v)=>{
|
|
37
|
+
if(v && typeof v==='object') {
|
|
38
|
+
if(!i.has(v)) {
|
|
39
|
+
v[K]=b++
|
|
40
|
+
i.add(v)
|
|
41
|
+
ls.push(v)
|
|
42
|
+
}else{
|
|
43
|
+
return `[Circular] #`+v[K]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if(k===K) {
|
|
47
|
+
return '[*Ref] #'+v
|
|
48
|
+
}
|
|
49
|
+
if(typeof v==='function') {
|
|
50
|
+
return `[Function] ${v.toString()}`
|
|
51
|
+
}
|
|
52
|
+
if(v && v.constructor===RegExp) {
|
|
53
|
+
return `[RegExp] ${v.toString()}`
|
|
54
|
+
}
|
|
55
|
+
return v
|
|
56
|
+
}, 2)
|
|
57
|
+
|
|
58
|
+
for(let o of ls) {
|
|
59
|
+
delete o[K]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return e && e.replace(new RegExp(K, 'g'), '__ref_key__')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function buildGlobal() {
|
|
66
|
+
const ctx={
|
|
67
|
+
// nodejs
|
|
68
|
+
setTimeout,
|
|
69
|
+
setInterval,
|
|
70
|
+
clearTimeout,
|
|
71
|
+
clearInterval,
|
|
72
|
+
queueMicrotask,
|
|
73
|
+
clearImmediate,
|
|
74
|
+
setImmediate,
|
|
75
|
+
|
|
76
|
+
console,
|
|
77
|
+
Buffer,
|
|
78
|
+
process,
|
|
79
|
+
|
|
80
|
+
TextDecoder,
|
|
81
|
+
TextEncoder,
|
|
82
|
+
URL,
|
|
83
|
+
URLSearchParams,
|
|
84
|
+
|
|
85
|
+
Promise,
|
|
86
|
+
// require
|
|
87
|
+
|
|
88
|
+
// v8
|
|
89
|
+
JSON,
|
|
90
|
+
RegExp,
|
|
91
|
+
Object,
|
|
92
|
+
Array,
|
|
93
|
+
String,
|
|
94
|
+
Number,
|
|
95
|
+
Boolean,
|
|
96
|
+
Date,
|
|
97
|
+
Math,
|
|
98
|
+
Set, WeakSet,
|
|
99
|
+
Map, WeakMap,
|
|
100
|
+
Proxy,
|
|
101
|
+
Symbol,
|
|
102
|
+
Error,
|
|
103
|
+
Function,
|
|
104
|
+
// eval,
|
|
105
|
+
|
|
106
|
+
escape, unescape,
|
|
107
|
+
encodeURI, decodeURI,
|
|
108
|
+
encodeURIComponent, decodeURIComponent,
|
|
109
|
+
isNaN, isFinite,
|
|
110
|
+
parseInt, parseFloat,
|
|
111
|
+
}
|
|
112
|
+
ctx.global=ctx
|
|
113
|
+
ctx.globalThis=ctx
|
|
114
|
+
return ctx
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let _patched=false
|
|
118
|
+
function securityPatch() {
|
|
119
|
+
if(_patched) return;
|
|
120
|
+
_patched=true
|
|
121
|
+
const sfunc=(new vm.Script(`(_=>null).constructor`)).runInNewContext({})
|
|
122
|
+
parseInt.constructor.prototype.constructor=sfunc
|
|
123
|
+
global.Function=sfunc
|
|
124
|
+
global.global=buildGlobal()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const NOOP=_=>null
|
|
128
|
+
function buildContext(ctx0, option) {
|
|
129
|
+
|
|
130
|
+
const {
|
|
131
|
+
write=NOOP,
|
|
132
|
+
end=NOOP,
|
|
133
|
+
onError=NOOP,
|
|
134
|
+
masterPriv=null,
|
|
135
|
+
readAsBinary=false,
|
|
136
|
+
}=option
|
|
137
|
+
|
|
138
|
+
const ctx=buildGlobal()
|
|
139
|
+
|
|
140
|
+
const priv=masterPriv || {
|
|
141
|
+
isEnd: false,
|
|
142
|
+
echos: [],
|
|
143
|
+
syncs: [],
|
|
144
|
+
_defers: [],
|
|
145
|
+
__autoload_func: null,
|
|
146
|
+
__autoload_vars: {},
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
Object.assign(ctx, {
|
|
150
|
+
end,
|
|
151
|
+
onError,
|
|
152
|
+
isMaster: !masterPriv,
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
ctx.echo=(...x)=>{
|
|
156
|
+
if(priv.isEnd) return;
|
|
157
|
+
priv.echos.push(...x)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
ctx.flush=_=>{
|
|
161
|
+
if(priv.isEnd) return;
|
|
162
|
+
const {echos}=priv
|
|
163
|
+
echos.splice(0).map(x=>write(toWritable(x, readAsBinary)))
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
ctx.var_dump=(...x)=>{
|
|
167
|
+
for(let o of x) {
|
|
168
|
+
ctx.echo(var_dump(o))
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
ctx.Sync={
|
|
173
|
+
Push: (...x)=>{
|
|
174
|
+
if(priv.isEnd) return;
|
|
175
|
+
priv.syncs.push(...x)
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
ctx.defer=fn=>{
|
|
180
|
+
if(priv.isEnd) return;
|
|
181
|
+
priv._defers.push(fn)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
try{
|
|
185
|
+
ctx.require=_module.createRequire(ctx0.__filefullname)
|
|
186
|
+
}catch(e) {
|
|
187
|
+
ctx.require=require
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
ctx._exports={}
|
|
191
|
+
ctx.exports=o=>{
|
|
192
|
+
Object.assign(ctx._exports, o)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
ctx.eval=code=>(new vm.Script(code)).runInNewContext(ctx)
|
|
196
|
+
|
|
197
|
+
ctx.include=(inc_filename, payload={})=>{
|
|
198
|
+
const inc=path.resolve(ctx0.__dirname, inc_filename)
|
|
199
|
+
const [_ctx0, _vm]=Compiler.compileSptcFile(inc)
|
|
200
|
+
const [_ctx, _]=buildContext({...payload, ..._ctx0}, {
|
|
201
|
+
write: ctx.write,
|
|
202
|
+
// end: ctx.end,
|
|
203
|
+
onError: ctx.onError,
|
|
204
|
+
masterPriv: priv,
|
|
205
|
+
readAsBinary,
|
|
206
|
+
})
|
|
207
|
+
const ret=executeVm(_vm, _ctx, priv)
|
|
208
|
+
return [_ctx._exports, x=>ret.constructor('return '+x)()]
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
ctx.__autoload=fn=>{
|
|
212
|
+
priv.__autoload_func=fn
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
let pctx=Object.assign({}, ctx0, ctx)
|
|
216
|
+
pctx=new Proxy(pctx, {
|
|
217
|
+
get: (target, prop, receiver)=>{
|
|
218
|
+
if(false===prop in target) {
|
|
219
|
+
if(prop in priv.__autoload_vars) {
|
|
220
|
+
return priv.__autoload_vars[prop]
|
|
221
|
+
}
|
|
222
|
+
if(priv.__autoload_func) {
|
|
223
|
+
let inc_fn=priv.__autoload_func(prop)
|
|
224
|
+
if(inc_fn) {
|
|
225
|
+
const [{default: d}, q]=ctx.include(inc_fn)
|
|
226
|
+
return priv.__autoload_vars[prop]=d || q(prop)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return target[prop]
|
|
231
|
+
},
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
return [pctx, priv]
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function toWritable(x, asBinary=false) {
|
|
238
|
+
if(x && [Uint8Array, Buffer].includes(x.constructor)) {
|
|
239
|
+
return asBinary? x: Buffer.from(x).toString('utf8')
|
|
240
|
+
}
|
|
241
|
+
const str=(_=>{
|
|
242
|
+
if(typeof x==='string') return x
|
|
243
|
+
if(typeof x==='undefined') return 'undefined'
|
|
244
|
+
if(typeof x==='number') {
|
|
245
|
+
if(isNaN(x))return 'NaN'
|
|
246
|
+
if(x===Infinity) return 'Infinity'
|
|
247
|
+
if(x===-Infinity) return '-Infinity'
|
|
248
|
+
}
|
|
249
|
+
return JSON.stringify(x)+''
|
|
250
|
+
})()
|
|
251
|
+
return asBinary? Buffer.from(str): str
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function executeVm(vm, ctx, priv) {
|
|
255
|
+
const {onError, end, flush, isMaster}=ctx
|
|
256
|
+
let ret
|
|
257
|
+
try{
|
|
258
|
+
ret=vm.runInNewContext(ctx)
|
|
259
|
+
}catch(e) {
|
|
260
|
+
onError(e)
|
|
261
|
+
}
|
|
262
|
+
; (async _=>{
|
|
263
|
+
|
|
264
|
+
try{
|
|
265
|
+
const syncs=priv.syncs.length? Promise.all(priv.syncs): null
|
|
266
|
+
await Promise.resolve(syncs)
|
|
267
|
+
flush()
|
|
268
|
+
end()
|
|
269
|
+
if(isMaster) priv.isEnd=true
|
|
270
|
+
}catch(e) {
|
|
271
|
+
onError(e)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
for(let fn of priv._defers.splice(0)) {
|
|
275
|
+
try{
|
|
276
|
+
fn()
|
|
277
|
+
}catch(e) {
|
|
278
|
+
onError(e)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
})()
|
|
283
|
+
return ret
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
module.exports={
|
|
288
|
+
buildContext,
|
|
289
|
+
executeVm,
|
|
290
|
+
securityPatch,
|
|
291
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sptc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Simple Pretreat Toolkit CLI",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=12"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"sptc": "./bin/sptc.js",
|
|
11
|
+
"sptcd": "./bin/sptcd.js"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"commander": "^10.0.1"
|
|
8
15
|
}
|
|
9
16
|
}
|
package/tests/bin.sh
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<?js
|
|
2
|
+
/*
|
|
3
|
+
function test(key, fn) {
|
|
4
|
+
console.log('--> '+key+' :')
|
|
5
|
+
try{
|
|
6
|
+
const p=[GLOBAL, THIS, TOP].indexOf(o)
|
|
7
|
+
console.log(p<0? '-- pass --': (' -->'+['GLOBAL', 'this', 'globalThis'][p]))
|
|
8
|
+
}catch(e) {
|
|
9
|
+
console.log('-- pass --')
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
test('nodeGlobal', _=>parseInt.constructor('return global')())
|
|
15
|
+
test('nodeGlobalThis', _=>parseInt.constructor('return this')())
|
|
16
|
+
test('realGlobal', _=>Function('return global')())
|
|
17
|
+
test('realGlobalThis', _=>Function('return this')())
|
|
18
|
+
test('controllableGlobal', _=>global)
|
|
19
|
+
test('currentContext', _=>globalThis)
|
|
20
|
+
test('currentThis', _=>this)
|
|
21
|
+
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
#ifdef W1
|
|
26
|
+
console.log('W1 defined!')
|
|
27
|
+
process.exit()
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
console.log(_x)
|
|
32
|
+
function sleep(t) {
|
|
33
|
+
return new Promise(r=>setTimeout(r, t))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
__autoload(varname=>{
|
|
37
|
+
if(varname==='TestModel') return './TestModel.sjs'
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const [v, _]=include('./ee.sjs', {P: 55})
|
|
41
|
+
echo('['+v.ee+']')
|
|
42
|
+
|
|
43
|
+
Sync.Push((async _=>{
|
|
44
|
+
echo(aa, 'LLL')
|
|
45
|
+
flush()
|
|
46
|
+
echo(1919)
|
|
47
|
+
var_dump({x: 3})
|
|
48
|
+
console.log(">>", eval+'')
|
|
49
|
+
defer(_=>{
|
|
50
|
+
console.log('defer')
|
|
51
|
+
})
|
|
52
|
+
flush()
|
|
53
|
+
await sleep(2e3)
|
|
54
|
+
echo('SLEEP=1e3')
|
|
55
|
+
setTimeout(_=>{
|
|
56
|
+
echo(2929)
|
|
57
|
+
}, 2e3)
|
|
58
|
+
})())
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
exports.A=_=>'m1 -> A'
|
|
2
|
+
|
|
3
|
+
console.log('global.XXX - global.YYY', global.XXX, global.YYY)
|
|
4
|
+
|
|
5
|
+
function test(key, fn) {
|
|
6
|
+
console.log('--> '+key+' :')
|
|
7
|
+
try{
|
|
8
|
+
console.log(fn())
|
|
9
|
+
}catch(e) {
|
|
10
|
+
console.log(' -- pass --')
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
test('nodeGlobal', _=>parseInt.constructor('return global')())
|
|
15
|
+
test('nodeGlobalThis', _=>parseInt.constructor('return this')())
|
|
16
|
+
test('realGlobal', _=>Function('return global')())
|
|
17
|
+
test('realGlobalThis', _=>Function('return this')())
|
|
18
|
+
test('controllableGlobal', _=>global)
|
|
19
|
+
test('currentContext', _=>globalThis)
|
|
20
|
+
test('currentThis', _=>this)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const {
|
|
2
|
+
executeSptcFile,
|
|
3
|
+
executeSptcFileEx,
|
|
4
|
+
|
|
5
|
+
securityPatch,
|
|
6
|
+
}=require('../../engine')
|
|
7
|
+
|
|
8
|
+
global.XXX=22
|
|
9
|
+
|
|
10
|
+
securityPatch()
|
|
11
|
+
|
|
12
|
+
global.YYY=22
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
executeSptcFile(__dirname+'/a.sjs', {aa: 'AAA', GLOBAL: global, THIS: this, TOP: globalThis}, {
|
|
16
|
+
write: x=>process.stdout.write(x),
|
|
17
|
+
end: _=>console.log('>>end'),
|
|
18
|
+
onError: e=>console.log(e),
|
|
19
|
+
})
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const option={
|
|
23
|
+
__DEV__: true,
|
|
24
|
+
macroOption: {
|
|
25
|
+
//defs: ['W1'],
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
executeSptcFileEx(__dirname+'/a.sjs', {aa: 'AAA', GLOBAL: global, THIS: this, TOP: globalThis}, option).then(out=>{
|
|
29
|
+
console.log(out, '<<END')
|
|
30
|
+
}, e=>{
|
|
31
|
+
console.log(e)
|
|
32
|
+
})
|
|
33
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?js
|
|
2
|
+
echo($_REQUEST_FILE)
|
|
3
|
+
echo('aaaa<pre>')
|
|
4
|
+
var_dump($_GLOBAL, this)
|
|
5
|
+
|
|
6
|
+
function sleep(t) {
|
|
7
|
+
return new Promise(r=>setTimeout(r, t))
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Sync.Push((async _=>{
|
|
11
|
+
for(let i=0; i<10; i++) {
|
|
12
|
+
echo(i*1e8+'<br/>')
|
|
13
|
+
flush()
|
|
14
|
+
await sleep(1e3)
|
|
15
|
+
}
|
|
16
|
+
echo('--done--')
|
|
17
|
+
})())
|
package/utils/base.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
|
|
2
|
+
const fs=require('fs')
|
|
3
|
+
const crypto=require('crypto')
|
|
4
|
+
const path=require('path')
|
|
5
|
+
|
|
6
|
+
function readTextFile(filename) {
|
|
7
|
+
return fs.readFileSync(filename, 'utf8')
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function mtime(filename) {
|
|
11
|
+
return fs.statSync(filename).mtime.getTime()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let _g=0
|
|
15
|
+
function generate_uuid(prefix='') {
|
|
16
|
+
return [
|
|
17
|
+
prefix,
|
|
18
|
+
(_g=(_g+1)%1e8).toString(36),
|
|
19
|
+
(Date.now()+Math.random()).toString(36),
|
|
20
|
+
].join('_')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function md5(str) {
|
|
24
|
+
return crypto.createHash('md5').update(str).digest('hex')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function safe_path(ref, dir) {
|
|
28
|
+
return path.normalize((ref? ref+'/': '')+path.normalize(dir))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function fileExists(fn) {
|
|
32
|
+
try{
|
|
33
|
+
return fs.statSync(fn).isFile()
|
|
34
|
+
}catch(e) {}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getExtension(filename) {
|
|
38
|
+
return path.parse(filename).ext
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getLocalIpv4Addresses() {
|
|
42
|
+
const os=require('os')
|
|
43
|
+
let rr={'127.0.0.1': 1}
|
|
44
|
+
try{
|
|
45
|
+
const ii=os.networkInterfaces()
|
|
46
|
+
for(let a in ii) {
|
|
47
|
+
ii[a].map(x=>{
|
|
48
|
+
if(!x.family.match(/IPV4/i)) return;
|
|
49
|
+
rr[x.address]=1
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
}catch(e) {}
|
|
53
|
+
return Object.keys(rr)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports={
|
|
57
|
+
readTextFile,
|
|
58
|
+
mtime,
|
|
59
|
+
md5,
|
|
60
|
+
safe_path,
|
|
61
|
+
fileExists,
|
|
62
|
+
generate_uuid,
|
|
63
|
+
getExtension,
|
|
64
|
+
getLocalIpv4Addresses,
|
|
65
|
+
}
|