HEX
Server: nginx/1.24.0
System: Linux nowruzgan 6.8.0-57-generic #59-Ubuntu SMP PREEMPT_DYNAMIC Sat Mar 15 17:40:59 UTC 2025 x86_64
User: babak (1000)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: /var/dev/nowruzgan/rest/node_modules/sails/bin/sails-console.js
/**
 * Module dependencies
 */

var nodepath = require('path');
var REPL = require('repl');
var stream = require('stream');
var _ = require('@sailshq/lodash');
var chalk = require('chalk');
var CaptainsLog = require('captains-log');

var rconf = require('../lib/app/configuration/rc')();
var Sails = require('../lib/app');
var SharedErrorHelpers = require('../errors');
var readReplHistoryAndStartTranscribing = require('./private/read-repl-history-and-start-transcribing');



/**
 * `sails console`
 *
 * Enter the interactive console (aka REPL) for the app
 * in our working directory.  This is just like the default
 * Node REPL except that it starts with the Sails app in the
 * current directory lifted, and with console history enabled
 * (i.e. so you can press up arrow to browse and potentially
 *  replay commands from past runs)
 *
 * @stability 3
 * @see http://sailsjs.com/documentation/reference/command-line-interface/sails-console
 * ------------------------------------------------------------------------
 * This lifts the Sails app in the current working directory, then uses
 * the core `repl` package to spin up an interactive console.
 *
 * Note that, if `--dontLift` was set, then `sails.load()` will be used
 * instead. (By default, the `sails console` cmd runs `sails.lift()`.)
 * ------------------------------------------------------------------------
 */

module.exports = function() {

  // Get a temporary logger just for use in `sails console`.
  // > This is so that logging levels are configurable, even when a
  // > Sails app hasn't been loaded yet.
  var cliLogger = CaptainsLog(rconf.log);

  // Now grab our dictionary of configuration overrides to pass in
  // momentarily when we lift (or load) our Sails app.  This is the
  // dictionary of configuration settings built from `.sailsrc` file(s),
  // command-line options, and environment variables.
  // (No need to clone, since, even through we're modifying it below,
  //  it's not being used anywhere else.)
  var configOverrides = rconf;

  // Then tweak this configuration to make sure we always disable
  // the ASCII ship.  It just doesn't look good in the REPL.
  if (!_.isObject(configOverrides.log)) {
    configOverrides.log = {};
  }
  configOverrides.log.noShip = true;

  // Determine whether to use the local or global Sails install.
  var sailsApp = (function _determineAppropriateSailsAppInstance(){

    // Use the app's locally-installed Sails dependency (in `node_modules/sails`),
    // assuming it's extant and valid.
    // > Note that we always assume the current working directory to be the
    // > root directory of the app.
    var appPath = process.cwd();
    var localSailsPath = nodepath.resolve(appPath, 'node_modules/sails');
    if (Sails.isLocalSailsValid(localSailsPath, appPath)) {
      cliLogger.verbose('Using locally-installed Sails.');
      cliLogger.silly('(which is located at `'+localSailsPath+'`)');
      return require(localSailsPath);
    }// --•

    // Otherwise, since no workable locally-installed Sails exists,
    // run the app using the currently running version of Sails.
    // > This is probably always the global install.
    cliLogger.info('No local Sails install detected; using globally-installed Sails.');

    return Sails();

  })();

  console.log();
  if (configOverrides.dontLift) {
    cliLogger.info(chalk.blue('Loading app in interactive mode...'));
    cliLogger.info(chalk.gray('Sails is not listening for requests (since `dontLift` was enabled).'));
    cliLogger.info(chalk.gray('You still have access to your models, helpers, and `sails`.'));
  }
  else {
    cliLogger.info(chalk.blue('Starting app in interactive mode...'));
  }
  console.log();

  // Lift (or load) Sails
  (function _loadOrLift(proceed){

    // If `--dontLift` was set, then use `.load()` instead.
    if (configOverrides.dontLift) {
      sailsApp.load(configOverrides, proceed);
    }
    // Otherwise, go with the default behavior (`.lift()`)
    else {
      sailsApp.lift(configOverrides, proceed);
    }

  })(function afterwards(err){// ~∞%°
    if (err) {
      return SharedErrorHelpers.fatal.failedToLoadSails(err);
    }

    // Get the current global _ value, if any.
    var underscore = global._;

    cliLogger.info('Welcome to the Sails console.');
    cliLogger.info(chalk.grey('( to exit, type ' + '<CTRL>+<C>' + ' )'));
    console.log();

    // Define a custom output stream that will replace global._ after every command.
    // This works around the issue where the Node REPL uses the underscore to hold
    // the result of the last command.
    var outputStream = (function() {
      // Create a new writable stream.
      var writableStream = new stream.Writable();
      // Add the `_write` method to it (can't do this in the constructor b/c that's not supported in older Node versions).
      writableStream._write = function(chunk, encoding, callback) {
        // Ignore the output generated the first time the global _ is set in Node 6+.
        if (chunk.toString('utf8').indexOf('Expression assignment to _ now disabled.') !== -1) {
          return callback();
        }
        // Set the global underscore again (for Node < 6).
        // See code after `REPL.start` for more info.
        if (typeof underscore !== 'undefined') {
          global._ = underscore;
        }
        // Forward the chunk on to stdout.
        process.stdout.write(chunk, encoding, callback);
      };
      // Return the new writable stream.
      return writableStream;
    })();

    // Start a REPL.
    var repl = REPL.start({
      // Set the REPL prompt.
      prompt: 'sails> ',
      // Allow the REPL to use the same global space as the Sails app, giving it access
      // to things like globalized models.
      useGlobal: true,
      // Specify the custom output stream we created above.
      output: outputStream,
      // When an output stream is specified, an input stream must be specified as well
      // or else the REPL crashes.
      input: process.stdin,
      // Set `terminal` to true to allow arrow keys to work correctly,
      // even when we're using a custom output stream.  Otherwise pressing
      // the up arrow just outputs ^[[A instead of accessing history.
      terminal: true,
      preview: false,
      // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      // FUTURE: Potentially use custom `eval` as stopgap for `await` support in Node <v9
      // https://nodejs.org/api/repl.html#repl_repl_start_options
      // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    });

    // Replace the global _ value, if any.  This will deactivate the underscore behavior
    // in the Node REPL for Node 6+, which conflicts with the global _ in Sails apps.
    // Note that in Node 6+ this typically causes the REPL to output "Expression assignment to _ now disabled.",
    // which unfortunately gets put right next to the `sails>` prompt, making for a very confusing
    // introduction to the Sails console.  In the custom output stream we defined above, we filter out
    // that message.
    if (typeof underscore !== 'undefined') {
      global._ = underscore;
    }

    // Now attempt to read the existing REPL history file, if there is one.
    var pathToReplHistoryFile = nodepath.join(sailsApp.config.paths.tmp, '.node_history');
    try {

      // Read the REPL history file, and bind notifier functions that will listen
      // for history-making events, and keep track of them for future generations.
      readReplHistoryAndStartTranscribing(repl, pathToReplHistoryFile);

    }
    catch (e) {

      cliLogger.verbose('Encountered an error attempting to access/interpret a `.node_history` file at `'+pathToReplHistoryFile+'`.');
      cliLogger.verbose('(This session of `sails console` will still work, it just won\'t support REPL history.)');
      cliLogger.verbose('Error details:\n',e);

    }//>-

    // Bind a one-time-use handler that will run when the REPL instance emits its "exit" event.
    repl.once('exit', function(err) {

      // If an error occurred, log it, then terminate the process with an exit code of 1.
      if (err) {
        cliLogger.error(err);
        return process.exit(1);
      }// --•

      // Otherwise, everything is cool.
      // Call the core 'lower' function and terminate the process with an exit code of 0.
      sailsApp.lower(function () {
        return process.exit(0);
      });

    });//</when 'exit' event it emitted by repl instance>

  });//</after lifting or loading Sails app>

};