4
4
5
5
import 'dart:async' ;
6
6
import 'dart:convert' ;
7
- import 'dart:js_util' ;
8
7
8
+ import 'package:cli_pkg/js.dart' ;
9
9
import 'package:js/js.dart' ;
10
10
import 'package:node_interop/fs.dart' ;
11
11
import 'package:node_interop/node_interop.dart' hide process;
12
+ import 'package:node_interop/util.dart' ;
12
13
import 'package:path/path.dart' as p;
13
14
import 'package:source_span/source_span.dart' ;
14
15
import 'package:watcher/watcher.dart' ;
@@ -17,7 +18,12 @@ import '../exception.dart';
17
18
import '../js/chokidar.dart' ;
18
19
19
20
@JS ('process' )
20
- external final Process ? process; // process is null in the browser
21
+ external final Process ? _nodeJsProcess; // process is null in the browser
22
+
23
+ /// The Node.JS [Process] global variable.
24
+ ///
25
+ /// This value is `null` when running the script is not run from Node.JS
26
+ Process ? get _process => isNodeJs ? _nodeJsProcess : null ;
21
27
22
28
class FileSystemException {
23
29
final String message;
@@ -29,23 +35,23 @@ class FileSystemException {
29
35
}
30
36
31
37
void safePrint (Object ? message) {
32
- if (process case var process? ) {
38
+ if (_process case var process? ) {
33
39
process.stdout.write ("${message ?? '' }\n " );
34
40
} else {
35
41
console.log (message ?? '' );
36
42
}
37
43
}
38
44
39
45
void printError (Object ? message) {
40
- if (process case var process? ) {
46
+ if (_process case var process? ) {
41
47
process.stderr.write ("${message ?? '' }\n " );
42
48
} else {
43
49
console.error (message ?? '' );
44
50
}
45
51
}
46
52
47
53
String readFile (String path) {
48
- if (! isNode ) {
54
+ if (! isNodeJs ) {
49
55
throw UnsupportedError ("readFile() is only supported on Node.js" );
50
56
}
51
57
// TODO(nweiz): explicitly decode the bytes as UTF-8 like we do in the VM when
@@ -69,23 +75,23 @@ Object? _readFile(String path, [String? encoding]) =>
69
75
_systemErrorToFileSystemException (() => fs.readFileSync (path, encoding));
70
76
71
77
void writeFile (String path, String contents) {
72
- if (! isNode ) {
78
+ if (! isNodeJs ) {
73
79
throw UnsupportedError ("writeFile() is only supported on Node.js" );
74
80
}
75
81
return _systemErrorToFileSystemException (
76
82
() => fs.writeFileSync (path, contents));
77
83
}
78
84
79
85
void deleteFile (String path) {
80
- if (! isNode ) {
86
+ if (! isNodeJs ) {
81
87
throw UnsupportedError ("deleteFile() is only supported on Node.js" );
82
88
}
83
89
return _systemErrorToFileSystemException (() => fs.unlinkSync (path));
84
90
}
85
91
86
92
Future <String > readStdin () async {
87
- var process_ = process ;
88
- if (process_ == null ) {
93
+ var process = _process ;
94
+ if (process == null ) {
89
95
throw UnsupportedError ("readStdin() is only supported on Node.js" );
90
96
}
91
97
var completer = Completer <String >();
@@ -96,15 +102,15 @@ Future<String> readStdin() async {
96
102
});
97
103
// Node defaults all buffers to 'utf8'.
98
104
var sink = utf8.decoder.startChunkedConversion (innerSink);
99
- process_ .stdin.on ('data' , allowInterop (([Object ? chunk]) {
105
+ process .stdin.on ('data' , allowInterop (([Object ? chunk]) {
100
106
sink.add (chunk as List <int >);
101
107
}));
102
- process_ .stdin.on ('end' , allowInterop (([Object ? _]) {
108
+ process .stdin.on ('end' , allowInterop (([Object ? _]) {
103
109
// Callback for 'end' receives no args.
104
110
assert (_ == null );
105
111
sink.close ();
106
112
}));
107
- process_ .stdin.on ('error' , allowInterop (([Object ? e]) {
113
+ process .stdin.on ('error' , allowInterop (([Object ? e]) {
108
114
printError ('Failed to read from stdin' );
109
115
printError (e);
110
116
completer.completeError (e! );
@@ -121,7 +127,7 @@ String _cleanErrorMessage(JsSystemError error) {
121
127
}
122
128
123
129
bool fileExists (String path) {
124
- if (! isNode ) {
130
+ if (! isNodeJs ) {
125
131
throw UnsupportedError ("fileExists() is only supported on Node.js" );
126
132
}
127
133
return _systemErrorToFileSystemException (() {
@@ -142,7 +148,7 @@ bool fileExists(String path) {
142
148
}
143
149
144
150
bool dirExists (String path) {
145
- if (! isNode ) {
151
+ if (! isNodeJs ) {
146
152
throw UnsupportedError ("dirExists() is only supported on Node.js" );
147
153
}
148
154
return _systemErrorToFileSystemException (() {
@@ -163,7 +169,7 @@ bool dirExists(String path) {
163
169
}
164
170
165
171
void ensureDir (String path) {
166
- if (! isNode ) {
172
+ if (! isNodeJs ) {
167
173
throw UnsupportedError ("ensureDir() is only supported on Node.js" );
168
174
}
169
175
return _systemErrorToFileSystemException (() {
@@ -180,7 +186,7 @@ void ensureDir(String path) {
180
186
}
181
187
182
188
Iterable <String > listDir (String path, {bool recursive = false }) {
183
- if (! isNode ) {
189
+ if (! isNodeJs ) {
184
190
throw UnsupportedError ("listDir() is only supported on Node.js" );
185
191
}
186
192
return _systemErrorToFileSystemException (() {
@@ -202,15 +208,15 @@ Iterable<String> listDir(String path, {bool recursive = false}) {
202
208
}
203
209
204
210
DateTime modificationTime (String path) {
205
- if (! isNode ) {
211
+ if (! isNodeJs ) {
206
212
throw UnsupportedError ("modificationTime() is only supported on Node.js" );
207
213
}
208
214
return _systemErrorToFileSystemException (() =>
209
215
DateTime .fromMillisecondsSinceEpoch (fs.statSync (path).mtime.getTime ()));
210
216
}
211
217
212
218
String ? getEnvironmentVariable (String name) {
213
- var env = process ? .env;
219
+ var env = _process ? .env;
214
220
return env == null ? null : getProperty (env as Object , name) as String ? ;
215
221
}
216
222
@@ -229,36 +235,21 @@ T _systemErrorToFileSystemException<T>(T callback()) {
229
235
/// from `node_interop` declares `isTTY` as always non-nullably available, but
230
236
/// in practice it's undefined if stdout isn't a TTY.
231
237
/// See: https://github.com/pulyaevskiy/node-interop/issues/93
232
- bool get hasTerminal => process? .stdout.isTTY == true ;
233
-
234
- bool get isWindows => process? .platform == 'win32' ;
235
-
236
- bool get isMacOS => process? .platform == 'darwin' ;
237
-
238
- const bool isJS = true ;
239
-
240
- /// The fs module object, used to check whether this has been loaded as Node.
241
- ///
242
- /// It's safest to check for a library we load in manually rather than one
243
- /// that's ambiently available so that we don't get into a weird state in
244
- /// environments like VS Code that support some Node.js libraries but don't load
245
- /// Node.js entrypoints for dependencies.
246
- @JS ('fs' )
247
- external final Object ? _fsNullable;
238
+ bool get hasTerminal => _process? .stdout.isTTY == true ;
248
239
249
- bool get isNode => _fsNullable != null ;
240
+ bool get isWindows => _process ? .platform == 'win32' ;
250
241
251
- bool get isBrowser => isJS && ! isNode ;
242
+ bool get isMacOS => _process ? .platform == 'darwin' ;
252
243
253
244
// Node seems to support ANSI escapes on all terminals.
254
245
bool get supportsAnsiEscapes => hasTerminal;
255
246
256
- int get exitCode => process ? .exitCode ?? 0 ;
247
+ int get exitCode => _process ? .exitCode ?? 0 ;
257
248
258
- set exitCode (int code) => process ? .exitCode = code;
249
+ set exitCode (int code) => _process ? .exitCode = code;
259
250
260
251
Future <Stream <WatchEvent >> watchDir (String path, {bool poll = false }) {
261
- if (! isNode ) {
252
+ if (! isNodeJs ) {
262
253
throw UnsupportedError ("watchDir() is only supported on Node.js" );
263
254
}
264
255
var watcher = chokidar.watch (
0 commit comments