@arcticnotes/node-wsh 0.0.10 → 0.0.12
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/index.js +1 -0
- package/lib/node/node-wsh.js +144 -177
- package/lib/node/utils.js +24 -0
- package/lib/wsh/host.js +23 -28
- package/lib/wsh/host.vbs +9 -0
- package/lib/wsh/host.wsf +4 -0
- package/package.json +2 -2
package/lib/index.js
CHANGED
package/lib/node/node-wsh.js
CHANGED
|
@@ -3,8 +3,8 @@ import PATH from 'node:path';
|
|
|
3
3
|
import { Syncline} from "@arcticnotes/syncline";
|
|
4
4
|
|
|
5
5
|
const COMMAND = 'cscript.exe';
|
|
6
|
-
const ARGS = [ '//
|
|
7
|
-
const SCRIPT_FILE = PATH.join( PATH.dirname( import.meta.dirname), 'wsh', 'host.
|
|
6
|
+
const ARGS = [ '//NoLogo'];
|
|
7
|
+
const SCRIPT_FILE = PATH.join( PATH.dirname( import.meta.dirname), 'wsh', 'host.wsf');
|
|
8
8
|
|
|
9
9
|
export class WindowsScriptingHost extends EventEmitter {
|
|
10
10
|
|
|
@@ -12,84 +12,24 @@ export class WindowsScriptingHost extends EventEmitter {
|
|
|
12
12
|
const command = options.command || COMMAND;
|
|
13
13
|
const args = options.args || ARGS;
|
|
14
14
|
const scriptFile = options.scriptFile || SCRIPT_FILE;
|
|
15
|
-
|
|
16
|
-
return new WindowsScriptingHost( await Syncline.spawn( command, [ ...args, scriptFile], { trace}));
|
|
15
|
+
return new WindowsScriptingHost( await Syncline.spawn( command, [ ...args, scriptFile], options.syncline), options);
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
#syncline;
|
|
19
|
+
#closed = false;
|
|
20
20
|
#finalizer = new FinalizationRegistry( this.#finalized.bind( this));
|
|
21
|
-
#ref2proxy = new Map();
|
|
22
|
-
#proxy2ref = new WeakMap();
|
|
21
|
+
#ref2proxy = new Map(); // Map< string, WeakRef< Proxy | <custom-mapped>>>
|
|
22
|
+
#proxy2ref = new WeakMap(); // Map< Proxy | <custom-mapped>, string>
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
wsh: this,
|
|
27
|
-
|
|
28
|
-
get( target, prop) {
|
|
29
|
-
if( prop === Symbol.toPrimitive)
|
|
30
|
-
return () => `ref#${ target.ref}`;
|
|
31
|
-
const encodedTarget = this.wsh.#encode( target.proxy);
|
|
32
|
-
const encodedProp = this.wsh.#encode( prop);
|
|
33
|
-
const output = JSON.parse( this.wsh.#syncline.exchange( JSON.stringify( [ 'get', encodedTarget, encodedProp])));
|
|
34
|
-
switch( output[ 0]) {
|
|
35
|
-
case 'value': return this.wsh.#decode( output[ 1]);
|
|
36
|
-
case 'error': throw new Error( output[ 1]);
|
|
37
|
-
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
set( target, prop, value) {
|
|
42
|
-
const encodedTarget = this.wsh.#encode( target.proxy);
|
|
43
|
-
const encodedProp = this.wsh.#encode( prop);
|
|
44
|
-
const encodedValue = this.wsh.#encode( value);
|
|
45
|
-
const output = JSON.parse( this.wsh.#syncline.exchange( JSON.stringify( [ 'set', encodedTarget, encodedProp, encodedValue])));
|
|
46
|
-
switch( output[ 0]) {
|
|
47
|
-
case 'set': return;
|
|
48
|
-
case 'error': throw new Error( output[ 1]);
|
|
49
|
-
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
#functionHandler = {
|
|
55
|
-
|
|
56
|
-
wsh: this,
|
|
57
|
-
|
|
58
|
-
get( target, prop) {
|
|
59
|
-
if( prop === Symbol.toPrimitive)
|
|
60
|
-
return () => `ref#${ target.ref}`;
|
|
61
|
-
return undefined;
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
apply( target, thisArg, argumentList) {
|
|
65
|
-
const encodedTarget = this.wsh.#encode( target.proxy);
|
|
66
|
-
const encodedThisArg = this.wsh.#encode( thisArg);
|
|
67
|
-
const encodedArgumentList = this.wsh.#encode( argumentList);
|
|
68
|
-
const output = JSON.parse( this.wsh.#syncline.exchange( JSON.stringify( [ 'apply', encodedTarget, encodedThisArg, encodedArgumentList])));
|
|
69
|
-
switch( output[ 0]) {
|
|
70
|
-
case 'value': return this.wsh.#decode( output[ 1]);
|
|
71
|
-
case 'error': throw new Error( output[ 1]);
|
|
72
|
-
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
construct( target, argumentList) {
|
|
77
|
-
const encodedTarget = this.wsh.#encode( target.proxy);
|
|
78
|
-
const encodedArgumentList = this.wsh.#encode( argumentList);
|
|
79
|
-
const output = JSON.parse( this.wsh.#syncline.exchange( JSON.stringify( [ 'construct', encodedTarget, encodedArgumentList])));
|
|
80
|
-
switch( output[ 0]) {
|
|
81
|
-
case 'value': return this.wsh.#decode( output[ 1]);
|
|
82
|
-
case 'error': throw new Error( output[ 1]);
|
|
83
|
-
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
constructor( syncline) {
|
|
24
|
+
constructor( syncline, options) {
|
|
89
25
|
super();
|
|
90
26
|
this.#syncline = syncline;
|
|
91
|
-
this.#syncline.on( 'stderr', line => console.log( 'wsh:', line));
|
|
92
|
-
this.#syncline.on( 'stdout', line => console.log( 'wsh:', line));
|
|
27
|
+
this.#syncline.on( 'stderr', line => console.log( 'wsh-stderr:', line));
|
|
28
|
+
this.#syncline.on( 'stdout', line => console.log( 'wsh-stdout:', line));
|
|
29
|
+
if( options.printSynclineIO) {
|
|
30
|
+
this.#syncline.on( 'input', line => console.log( 'syncline-input:', line));
|
|
31
|
+
this.#syncline.on( 'output', line => console.log( 'syncline-output', line));
|
|
32
|
+
}
|
|
93
33
|
}
|
|
94
34
|
|
|
95
35
|
get remoteObjects() {
|
|
@@ -101,90 +41,21 @@ export class WindowsScriptingHost extends EventEmitter {
|
|
|
101
41
|
};
|
|
102
42
|
}
|
|
103
43
|
|
|
104
|
-
global( name) {
|
|
44
|
+
global( name, mapper = undefined) {
|
|
105
45
|
const output = JSON.parse( this.#syncline.exchange( JSON.stringify( [ 'global', name])));
|
|
106
46
|
switch( output[ 0]) {
|
|
107
|
-
case 'value': return this.#decode( output[ 1]);
|
|
47
|
+
case 'value': return this.#decode( output[ 1], mapper);
|
|
108
48
|
case 'error': throw new Error( output[ 1]);
|
|
109
|
-
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
49
|
+
default: throw new Error( `unknown status: ${ output[ 0]}`); // bug
|
|
110
50
|
}
|
|
111
51
|
}
|
|
112
52
|
|
|
113
53
|
async disconnect() {
|
|
54
|
+
this.#closed = true;
|
|
114
55
|
await this.#syncline.close();
|
|
115
56
|
}
|
|
116
57
|
|
|
117
|
-
#
|
|
118
|
-
return this.#getOrCreate( ref, this.#objectHandler);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
#getOrCreateFunction( ref) {
|
|
122
|
-
return this.#getOrCreate( ref, this.#functionHandler);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
#getOrCreate( ref, handler) {
|
|
126
|
-
const existingWeakRef = this.#ref2proxy.get( ref);
|
|
127
|
-
const existingProxy = existingWeakRef && existingWeakRef.deref();
|
|
128
|
-
if( existingProxy)
|
|
129
|
-
return existingProxy;
|
|
130
|
-
|
|
131
|
-
const target = handler === this.#objectHandler? new RemoteObject( ref): new RemoteFunction( ref);
|
|
132
|
-
const newProxy = new Proxy( target, handler);
|
|
133
|
-
target.proxy = newProxy;
|
|
134
|
-
this.#ref2proxy.set( ref, new WeakRef( newProxy)); // may be overwriting a dead WeakRef
|
|
135
|
-
this.#proxy2ref.set( newProxy, ref);
|
|
136
|
-
this.#finalizer.register( newProxy, ref);
|
|
137
|
-
this.emit( 'ref', ref, newProxy);
|
|
138
|
-
return newProxy;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
#finalized( ref) {
|
|
142
|
-
if( this.#ref2proxy.get( ref).deref() === undefined) // otherwise, it's overwritten by a refreshed proxy
|
|
143
|
-
this.#ref2proxy.delete( ref);
|
|
144
|
-
const output = this.#syncline.exchange( JSON.stringify( [ 'unref', ref]));
|
|
145
|
-
this.emit( 'unref', ref);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
#encode( decoded) {
|
|
149
|
-
switch( typeof decoded) {
|
|
150
|
-
case 'boolean':
|
|
151
|
-
case 'number':
|
|
152
|
-
case 'string':
|
|
153
|
-
return decoded;
|
|
154
|
-
case 'undefined':
|
|
155
|
-
return { type: 'undefined'};
|
|
156
|
-
case 'object':
|
|
157
|
-
if( decoded === null)
|
|
158
|
-
return decoded;
|
|
159
|
-
if( decoded instanceof Array) {
|
|
160
|
-
const encoded = [];
|
|
161
|
-
for( const item of decoded)
|
|
162
|
-
encoded.push( this.#encode( item));
|
|
163
|
-
return encoded;
|
|
164
|
-
}
|
|
165
|
-
if( decoded instanceof RemoteObject) {
|
|
166
|
-
const objref = this.#proxy2ref.get( decoded);
|
|
167
|
-
if( objref === undefined) // not because garbage-collected, because clearly `decoded` is still alive
|
|
168
|
-
throw new Error( `remote object reference not found: ${ decoded}`);
|
|
169
|
-
return { type: 'objref', value: objref};
|
|
170
|
-
}
|
|
171
|
-
const encoded = { type: 'object', value: {}};
|
|
172
|
-
for( const [ name, value] of Object.entries( decoded))
|
|
173
|
-
encoded.value[ name] = this.#encode( value);
|
|
174
|
-
return encoded;
|
|
175
|
-
case 'function':
|
|
176
|
-
const funref = this.#proxy2ref.get( decoded);
|
|
177
|
-
if( funref === undefined) // not because garbage-collected, because clearly `decoded` is still alive
|
|
178
|
-
throw new Error( `functions from node are disallowed: ${ decoded}`);
|
|
179
|
-
return { type: 'funref', value: funref};
|
|
180
|
-
case 'bigint':
|
|
181
|
-
case 'symbol':
|
|
182
|
-
default:
|
|
183
|
-
throw new Error( `unsupported value: ${ decoded}`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
#decode( encoded) {
|
|
58
|
+
#decode( encoded, mapper) {
|
|
188
59
|
switch( typeof encoded) {
|
|
189
60
|
case 'boolean':
|
|
190
61
|
case 'number':
|
|
@@ -193,10 +64,10 @@ export class WindowsScriptingHost extends EventEmitter {
|
|
|
193
64
|
case 'object':
|
|
194
65
|
if( encoded === null)
|
|
195
66
|
return encoded;
|
|
196
|
-
if( encoded
|
|
67
|
+
if( Array.isArray( encoded)) {
|
|
197
68
|
const decoded = [];
|
|
198
69
|
for( const item of encoded)
|
|
199
|
-
decoded.push( this.#decode( item));
|
|
70
|
+
decoded.push( this.#decode( item, mapper));
|
|
200
71
|
return decoded;
|
|
201
72
|
}
|
|
202
73
|
switch( encoded.type) {
|
|
@@ -205,12 +76,10 @@ export class WindowsScriptingHost extends EventEmitter {
|
|
|
205
76
|
case 'object':
|
|
206
77
|
const decoded = {};
|
|
207
78
|
for( const [ name, value] of Object.entries( encoded.value))
|
|
208
|
-
decoded[ name] = this.#decode( value);
|
|
79
|
+
decoded[ name] = this.#decode( value, mapper);
|
|
209
80
|
return decoded;
|
|
210
|
-
case '
|
|
211
|
-
return this.#
|
|
212
|
-
case 'funref':
|
|
213
|
-
return this.#getOrCreateFunction( encoded.value);
|
|
81
|
+
case 'ref':
|
|
82
|
+
return this.#getOrCreate( encoded.value, mapper);
|
|
214
83
|
default:
|
|
215
84
|
throw new Error( `illegal value: ${ encoded}`);
|
|
216
85
|
}
|
|
@@ -222,49 +91,147 @@ export class WindowsScriptingHost extends EventEmitter {
|
|
|
222
91
|
throw new Error( `illegal value: ${ encoded}`);
|
|
223
92
|
}
|
|
224
93
|
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
class RemoteObject {
|
|
228
94
|
|
|
229
|
-
#
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
95
|
+
#encode( decoded) {
|
|
96
|
+
switch( typeof decoded) {
|
|
97
|
+
case 'boolean':
|
|
98
|
+
case 'number':
|
|
99
|
+
case 'string':
|
|
100
|
+
return decoded;
|
|
101
|
+
case 'undefined':
|
|
102
|
+
return { type: 'undefined'};
|
|
103
|
+
case 'object': {
|
|
104
|
+
if( decoded === null)
|
|
105
|
+
return decoded;
|
|
106
|
+
const ref = this.#proxy2ref.get( decoded);
|
|
107
|
+
if( ref !== undefined)
|
|
108
|
+
return { type: 'ref', value: ref};
|
|
109
|
+
if( Array.isArray( decoded)) {
|
|
110
|
+
const encoded = [];
|
|
111
|
+
for( const item of decoded)
|
|
112
|
+
encoded.push( this.#encode( item));
|
|
113
|
+
return encoded;
|
|
114
|
+
}
|
|
115
|
+
const encoded = { type: 'object', value: {}};
|
|
116
|
+
for( const [ name, value] of Object.entries( decoded))
|
|
117
|
+
encoded.value[ name] = this.#encode( value);
|
|
118
|
+
return encoded;
|
|
119
|
+
}
|
|
120
|
+
case 'function': {
|
|
121
|
+
const ref = this.#proxy2ref.get( decoded);
|
|
122
|
+
if( ref !== undefined)
|
|
123
|
+
return { type: 'ref', value: ref};
|
|
124
|
+
throw new Error( `functions from node cannot be sent: ${ decoded}`);
|
|
125
|
+
}
|
|
126
|
+
case 'bigint':
|
|
127
|
+
case 'symbol':
|
|
128
|
+
default:
|
|
129
|
+
throw new Error( `unsupported value: ${ decoded}`);
|
|
130
|
+
}
|
|
234
131
|
}
|
|
235
132
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
133
|
+
#getOrCreate( ref, mapper) {
|
|
134
|
+
const existingWeakRef = this.#ref2proxy.get( ref);
|
|
135
|
+
const existingProxy = existingWeakRef && existingWeakRef.deref();
|
|
136
|
+
if( existingProxy)
|
|
137
|
+
return existingProxy;
|
|
239
138
|
|
|
240
|
-
|
|
241
|
-
|
|
139
|
+
const newProxy = new RemoteObject( this.#syncline, this.#encode.bind( this), this.#decode.bind( this), ref, mapper).proxy;
|
|
140
|
+
if( this.#proxy2ref.has( newProxy)) // sanity check, doesn't catch all misbehaving mappers
|
|
141
|
+
throw new Error( `mapper must return new objects: ${ newProxy}`);
|
|
142
|
+
this.#ref2proxy.set( ref, new WeakRef( newProxy)); // may be overwriting a dead WeakRef
|
|
143
|
+
this.#proxy2ref.set( newProxy, ref);
|
|
144
|
+
this.#finalizer.register( newProxy, ref);
|
|
145
|
+
this.emit( 'ref', ref, newProxy);
|
|
146
|
+
return newProxy;
|
|
242
147
|
}
|
|
243
148
|
|
|
244
|
-
|
|
245
|
-
this.#
|
|
149
|
+
#finalized( ref) {
|
|
150
|
+
if( this.#ref2proxy.get( ref).deref() === undefined) // otherwise, it's overwritten by a refreshed proxy
|
|
151
|
+
this.#ref2proxy.delete( ref);
|
|
152
|
+
if( !this.#closed)
|
|
153
|
+
this.#syncline.exchange( JSON.stringify( [ 'unref', ref]));
|
|
154
|
+
this.emit( 'unref', ref);
|
|
246
155
|
}
|
|
247
156
|
}
|
|
248
157
|
|
|
249
|
-
class
|
|
158
|
+
class RemoteObject extends Function {
|
|
159
|
+
|
|
160
|
+
static #handler = {
|
|
161
|
+
get: ( ticket, prop) => ticket.get( prop, undefined),
|
|
162
|
+
set: ( ticket, prop, value) => ticket.set( prop, value),
|
|
163
|
+
apply: ( ticket, thisArg, argumentsList) => ticket.apply( thisArg, argumentsList, undefined),
|
|
164
|
+
construct: ( ticket, argumentsList) => ticket.construct( argumentsList, undefined),
|
|
165
|
+
};
|
|
250
166
|
|
|
167
|
+
#syncline;
|
|
168
|
+
#encode;
|
|
169
|
+
#decode;
|
|
251
170
|
#ref;
|
|
252
171
|
#proxy;
|
|
253
172
|
|
|
254
|
-
constructor( ref) {
|
|
173
|
+
constructor( syncline, encode, decode, ref, mapper) {
|
|
255
174
|
super();
|
|
175
|
+
this.#syncline = syncline;
|
|
176
|
+
this.#encode = encode;
|
|
177
|
+
this.#decode = decode;
|
|
256
178
|
this.#ref = ref;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
get ref() {
|
|
260
|
-
return this.#ref;
|
|
179
|
+
this.#proxy = mapper? mapper( this): this.newProxy();
|
|
261
180
|
}
|
|
262
181
|
|
|
263
182
|
get proxy() {
|
|
264
183
|
return this.#proxy;
|
|
265
184
|
}
|
|
266
185
|
|
|
267
|
-
|
|
268
|
-
this.#
|
|
186
|
+
newProxy() {
|
|
187
|
+
return new Proxy( this, RemoteObject.#handler);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
get( prop, mapper) {
|
|
191
|
+
if( prop === Symbol.toPrimitive)
|
|
192
|
+
return () => `ref#${ this.#ref}`;
|
|
193
|
+
const encodedTarget = this.#encode( this.#proxy);
|
|
194
|
+
const encodedProp = this.#encode( prop);
|
|
195
|
+
const output = JSON.parse( this.#syncline.exchange( JSON.stringify( [ 'get', encodedTarget, encodedProp])));
|
|
196
|
+
switch( output[ 0]) {
|
|
197
|
+
case 'value': return this.#decode( output[ 1], mapper);
|
|
198
|
+
case 'error': throw new Error( output[ 1]);
|
|
199
|
+
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
set( prop, value) {
|
|
204
|
+
const encodedTarget = this.#encode( this.#proxy);
|
|
205
|
+
const encodedProp = this.#encode( prop);
|
|
206
|
+
const encodedValue = this.#encode( value);
|
|
207
|
+
const output = JSON.parse( this.#syncline.exchange( JSON.stringify( [ 'set', encodedTarget, encodedProp, encodedValue])));
|
|
208
|
+
switch( output[ 0]) {
|
|
209
|
+
case 'set': return true;
|
|
210
|
+
case 'error': throw new Error( output[ 1]);
|
|
211
|
+
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
apply( thisArg, argumentsList, mapper) {
|
|
216
|
+
const encodedTarget = this.#encode( this.#proxy);
|
|
217
|
+
const encodedThisArg = this.#encode( thisArg);
|
|
218
|
+
const encodedArgumentList = this.#encode( [ ...argumentsList]); // argumentsList may not be instanceof Array
|
|
219
|
+
const output = JSON.parse( this.#syncline.exchange( JSON.stringify( [ 'apply', encodedTarget, encodedThisArg, encodedArgumentList])));
|
|
220
|
+
switch( output[ 0]) {
|
|
221
|
+
case 'value': return this.#decode( output[ 1], mapper);
|
|
222
|
+
case 'error': throw new Error( output[ 1]);
|
|
223
|
+
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
construct( argumentsList, mapper) {
|
|
228
|
+
const encodedTarget = this.#encode( this.#proxy);
|
|
229
|
+
const encodedArgumentList = this.#encode( [ ...argumentsList]); // argumentsList may not be instanceof Array
|
|
230
|
+
const output = JSON.parse( this.#syncline.exchange( JSON.stringify( [ 'construct', encodedTarget, encodedArgumentList])));
|
|
231
|
+
switch( output[ 0]) {
|
|
232
|
+
case 'value': return this.#decode( output[ 1], mapper);
|
|
233
|
+
case 'error': throw new Error( output[ 1]);
|
|
234
|
+
default: throw new Error( `unknown status: ${ output[ 0]}`);
|
|
235
|
+
}
|
|
269
236
|
}
|
|
270
237
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class Collection {
|
|
2
|
+
|
|
3
|
+
#ticket;
|
|
4
|
+
#type;
|
|
5
|
+
|
|
6
|
+
constructor( ticket, type) {
|
|
7
|
+
this.#ticket = ticket;
|
|
8
|
+
this.#type = type;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get length() {
|
|
12
|
+
return this.#ticket.get( 'Count');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get( indexBase0) {
|
|
16
|
+
return this.#ticket.get( 'Item', t2 => t2.apply.bind( t2))( this, [ indexBase0 + 1], t3 => new this.#type( t3));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
*[ Symbol.iterator]() {
|
|
20
|
+
const length = this.length; // expect anomoly if the underlying collect is changing
|
|
21
|
+
for( let i = 0; i < length; i++)
|
|
22
|
+
yield this.get( i);
|
|
23
|
+
}
|
|
24
|
+
}
|
package/lib/wsh/host.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
// This file is in JScript, not in JavaScript. It is executed in Windows Scripting Host (WSH).
|
|
2
2
|
|
|
3
|
+
function CreateVBArray( jsArray) {
|
|
4
|
+
var dict = new ActiveXObject( 'Scripting.Dictionary');
|
|
5
|
+
for( var i = 0; i < jsArray.length; i++)
|
|
6
|
+
dict.Add( i, jsArray[ i]);
|
|
7
|
+
dict.Add( 'length', jsArray.length);
|
|
8
|
+
return Dict2VBArray( dict);
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
var FSO = new ActiveXObject( 'Scripting.FileSystemObject');
|
|
4
12
|
var OBJECT_TOSTRING = Object.toString();
|
|
5
13
|
var GLOBAL = this;
|
|
@@ -34,21 +42,12 @@ function decode( encoded) {
|
|
|
34
42
|
for( i in encoded.value)
|
|
35
43
|
decoded[ i] = decode( encoded.value[ i]);
|
|
36
44
|
return decoded;
|
|
37
|
-
case '
|
|
38
|
-
item = REFERENCES[ encoded.value];
|
|
39
|
-
if( item === undefined)
|
|
40
|
-
throw new Error( 'reference not found: ' + encoded.value);
|
|
41
|
-
if( item.type !== 'obj')
|
|
42
|
-
throw new Error( 'reference type mismatch: ' + encoded.value);
|
|
43
|
-
return item.value;
|
|
44
|
-
case 'funref':
|
|
45
|
+
case 'ref':
|
|
45
46
|
item = REFERENCES[ encoded.value];
|
|
46
47
|
if( item === undefined)
|
|
47
48
|
throw new Error( 'reference not found: ' + encoded.value);
|
|
48
49
|
if( item.type === 'potential-method')
|
|
49
50
|
throw new Error( 'potentially a method, cannot be evaluated standalone: ' + encoded.value);
|
|
50
|
-
if( item.type !== 'fun')
|
|
51
|
-
throw new Error( 'reference type mismatch: ' + encoded.value);
|
|
52
51
|
return item.value;
|
|
53
52
|
default:
|
|
54
53
|
throw new Error( 'unknown object type: ' + encoded.type);
|
|
@@ -87,19 +86,15 @@ function encode( decoded) {
|
|
|
87
86
|
encoded.value[ i] = encode( decoded[ i]);
|
|
88
87
|
return encoded;
|
|
89
88
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return { type: 'objref', value: i};
|
|
93
|
-
i = '' + nextRefId++;
|
|
94
|
-
REFERENCES[ i] = { type: 'obj', value: decoded};
|
|
95
|
-
return { type: 'objref', value: i};
|
|
89
|
+
// warning: intentional fall-through here!
|
|
90
|
+
case 'unknown':
|
|
96
91
|
case 'function':
|
|
97
92
|
for( i in REFERENCES)
|
|
98
93
|
if( REFERENCES[ i].value === decoded)
|
|
99
|
-
return { type: '
|
|
94
|
+
return { type: 'ref', value: i};
|
|
100
95
|
i = '' + nextRefId++;
|
|
101
|
-
REFERENCES[ i] = {
|
|
102
|
-
return { type: '
|
|
96
|
+
REFERENCES[ i] = { value: decoded};
|
|
97
|
+
return { type: 'ref', value: i};
|
|
103
98
|
case 'symbol':
|
|
104
99
|
case 'bigint':
|
|
105
100
|
default:
|
|
@@ -112,22 +107,22 @@ function encodePotentialMethod( target, prop) {
|
|
|
112
107
|
var item;
|
|
113
108
|
for( i in REFERENCES) {
|
|
114
109
|
item = REFERENCES[ i];
|
|
115
|
-
if( item.type === 'potential-method' && item.target === target
|
|
116
|
-
return { type: '
|
|
110
|
+
if( item.type === 'potential-method' && item.target === target && item.prop === prop)
|
|
111
|
+
return { type: 'ref', value: i};
|
|
117
112
|
}
|
|
118
113
|
i = '' + nextRefId++;
|
|
119
114
|
REFERENCES[ i] = { type: 'potential-method', target: target, prop: prop};
|
|
120
|
-
return { type: '
|
|
115
|
+
return { type: 'ref', value: i};
|
|
121
116
|
}
|
|
122
117
|
|
|
123
118
|
function decodePotentialMethod( encoded) {
|
|
124
119
|
var item;
|
|
125
|
-
if( typeof encoded === 'object' && encoded.type === '
|
|
120
|
+
if( typeof encoded === 'object' && encoded.type === 'ref') {
|
|
126
121
|
item = REFERENCES[ encoded.value];
|
|
127
122
|
if( item.type === 'potential-method')
|
|
128
|
-
return
|
|
123
|
+
return item;
|
|
129
124
|
}
|
|
130
|
-
return { '
|
|
125
|
+
return { type: 'regular', value: decode( encoded)};
|
|
131
126
|
}
|
|
132
127
|
|
|
133
128
|
( function() {
|
|
@@ -174,11 +169,11 @@ function decodePotentialMethod( encoded) {
|
|
|
174
169
|
target = decodePotentialMethod( input[ 1]);
|
|
175
170
|
thisArg = decode( input[ 2]);
|
|
176
171
|
args = decode( input[ 3]);
|
|
177
|
-
if( target
|
|
172
|
+
if( target.type === 'potential-method') {
|
|
178
173
|
if( thisArg === undefined)
|
|
179
|
-
throw new Error( 'potentially a method,
|
|
174
|
+
throw new Error( 'potentially a method, use with a "this"');
|
|
180
175
|
if( thisArg !== target.target)
|
|
181
|
-
throw new Error( 'potentially a method,
|
|
176
|
+
throw new Error( 'potentially a method, "this" has changed');
|
|
182
177
|
switch( args.length) {
|
|
183
178
|
case 0: output = [ 'value', encode( target.target[ target.prop]())]; break;
|
|
184
179
|
case 1: output = [ 'value', encode( target.target[ target.prop]( args[ 0]))]; break;
|
package/lib/wsh/host.vbs
ADDED
package/lib/wsh/host.wsf
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcticnotes/node-wsh",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "A Node.js package that runs Windows Scripting Host (WSH) as a child process and exposes the resources from the WSH world to the Node.js world",
|
|
5
5
|
"author": "Paul <paul@arcticnotes.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
".": "./lib/index.js"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@arcticnotes/syncline": "0.0.
|
|
24
|
+
"@arcticnotes/syncline": "0.0.4"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"/lib/"
|