44
55import 'dart:async' ;
66import 'dart:convert' ;
7- import 'dart:js_util' ;
87
8+ import 'package:cli_pkg/js.dart' ;
99import 'package:js/js.dart' ;
1010import 'package:node_interop/fs.dart' ;
1111import 'package:node_interop/node_interop.dart' hide process;
12+ import 'package:node_interop/util.dart' ;
1213import 'package:path/path.dart' as p;
1314import 'package:source_span/source_span.dart' ;
1415import 'package:watcher/watcher.dart' ;
@@ -17,7 +18,12 @@ import '../exception.dart';
1718import '../js/chokidar.dart' ;
1819
1920@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 ;
2127
2228class FileSystemException {
2329 final String message;
@@ -29,23 +35,23 @@ class FileSystemException {
2935}
3036
3137void safePrint (Object ? message) {
32- if (process case var process? ) {
38+ if (_process case var process? ) {
3339 process.stdout.write ("${message ?? '' }\n " );
3440 } else {
3541 console.log (message ?? '' );
3642 }
3743}
3844
3945void printError (Object ? message) {
40- if (process case var process? ) {
46+ if (_process case var process? ) {
4147 process.stderr.write ("${message ?? '' }\n " );
4248 } else {
4349 console.error (message ?? '' );
4450 }
4551}
4652
4753String readFile (String path) {
48- if (! isNode ) {
54+ if (! isNodeJs ) {
4955 throw UnsupportedError ("readFile() is only supported on Node.js" );
5056 }
5157 // 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]) =>
6975 _systemErrorToFileSystemException (() => fs.readFileSync (path, encoding));
7076
7177void writeFile (String path, String contents) {
72- if (! isNode ) {
78+ if (! isNodeJs ) {
7379 throw UnsupportedError ("writeFile() is only supported on Node.js" );
7480 }
7581 return _systemErrorToFileSystemException (
7682 () => fs.writeFileSync (path, contents));
7783}
7884
7985void deleteFile (String path) {
80- if (! isNode ) {
86+ if (! isNodeJs ) {
8187 throw UnsupportedError ("deleteFile() is only supported on Node.js" );
8288 }
8389 return _systemErrorToFileSystemException (() => fs.unlinkSync (path));
8490}
8591
8692Future <String > readStdin () async {
87- var process_ = process ;
88- if (process_ == null ) {
93+ var process = _process ;
94+ if (process == null ) {
8995 throw UnsupportedError ("readStdin() is only supported on Node.js" );
9096 }
9197 var completer = Completer <String >();
@@ -96,15 +102,15 @@ Future<String> readStdin() async {
96102 });
97103 // Node defaults all buffers to 'utf8'.
98104 var sink = utf8.decoder.startChunkedConversion (innerSink);
99- process_ .stdin.on ('data' , allowInterop (([Object ? chunk]) {
105+ process .stdin.on ('data' , allowInterop (([Object ? chunk]) {
100106 sink.add (chunk as List <int >);
101107 }));
102- process_ .stdin.on ('end' , allowInterop (([Object ? _]) {
108+ process .stdin.on ('end' , allowInterop (([Object ? _]) {
103109 // Callback for 'end' receives no args.
104110 assert (_ == null );
105111 sink.close ();
106112 }));
107- process_ .stdin.on ('error' , allowInterop (([Object ? e]) {
113+ process .stdin.on ('error' , allowInterop (([Object ? e]) {
108114 printError ('Failed to read from stdin' );
109115 printError (e);
110116 completer.completeError (e! );
@@ -121,7 +127,7 @@ String _cleanErrorMessage(JsSystemError error) {
121127}
122128
123129bool fileExists (String path) {
124- if (! isNode ) {
130+ if (! isNodeJs ) {
125131 throw UnsupportedError ("fileExists() is only supported on Node.js" );
126132 }
127133 return _systemErrorToFileSystemException (() {
@@ -142,7 +148,7 @@ bool fileExists(String path) {
142148}
143149
144150bool dirExists (String path) {
145- if (! isNode ) {
151+ if (! isNodeJs ) {
146152 throw UnsupportedError ("dirExists() is only supported on Node.js" );
147153 }
148154 return _systemErrorToFileSystemException (() {
@@ -163,7 +169,7 @@ bool dirExists(String path) {
163169}
164170
165171void ensureDir (String path) {
166- if (! isNode ) {
172+ if (! isNodeJs ) {
167173 throw UnsupportedError ("ensureDir() is only supported on Node.js" );
168174 }
169175 return _systemErrorToFileSystemException (() {
@@ -180,7 +186,7 @@ void ensureDir(String path) {
180186}
181187
182188Iterable <String > listDir (String path, {bool recursive = false }) {
183- if (! isNode ) {
189+ if (! isNodeJs ) {
184190 throw UnsupportedError ("listDir() is only supported on Node.js" );
185191 }
186192 return _systemErrorToFileSystemException (() {
@@ -202,15 +208,15 @@ Iterable<String> listDir(String path, {bool recursive = false}) {
202208}
203209
204210DateTime modificationTime (String path) {
205- if (! isNode ) {
211+ if (! isNodeJs ) {
206212 throw UnsupportedError ("modificationTime() is only supported on Node.js" );
207213 }
208214 return _systemErrorToFileSystemException (() =>
209215 DateTime .fromMillisecondsSinceEpoch (fs.statSync (path).mtime.getTime ()));
210216}
211217
212218String ? getEnvironmentVariable (String name) {
213- var env = process ? .env;
219+ var env = _process ? .env;
214220 return env == null ? null : getProperty (env as Object , name) as String ? ;
215221}
216222
@@ -229,36 +235,21 @@ T _systemErrorToFileSystemException<T>(T callback()) {
229235/// from `node_interop` declares `isTTY` as always non-nullably available, but
230236/// in practice it's undefined if stdout isn't a TTY.
231237/// 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 ;
248239
249- bool get isNode => _fsNullable != null ;
240+ bool get isWindows => _process ? .platform == 'win32' ;
250241
251- bool get isBrowser => isJS && ! isNode ;
242+ bool get isMacOS => _process ? .platform == 'darwin' ;
252243
253244// Node seems to support ANSI escapes on all terminals.
254245bool get supportsAnsiEscapes => hasTerminal;
255246
256- int get exitCode => process ? .exitCode ?? 0 ;
247+ int get exitCode => _process ? .exitCode ?? 0 ;
257248
258- set exitCode (int code) => process ? .exitCode = code;
249+ set exitCode (int code) => _process ? .exitCode = code;
259250
260251Future <Stream <WatchEvent >> watchDir (String path, {bool poll = false }) {
261- if (! isNode ) {
252+ if (! isNodeJs ) {
262253 throw UnsupportedError ("watchDir() is only supported on Node.js" );
263254 }
264255 var watcher = chokidar.watch (
0 commit comments