javascriptnode.jsmongodbswagger-uifile-copying

TypeError: mode must be int32 or null/undefined in Node JS issue when connecting to mongodb


Below is the Node.js project

api
   swagger.yaml - having visual representation of the API and its documentation
controllers
   entityApi.js file - APIs - create,delete,list,patch api
service
   entityService.js - API implementation
utils
   mongoUtils.js
index.js file
.... and other files

Below is the code in zindex.js` file:

'use strict';

const fs = require('fs'),
      path = require('path'),
      http = require('http'),
      mongoUtils = require('./utils/mongoUtils'),
      swaggerUtils = require('./utils/swaggerUtils');

const {error, errorEnum, sendError} = require('./utils/errorUtils');

const app = require('connect')();
const swaggerTools = require('swagger-tools');

const serverPort = 8080;

//error is coming here
fs.copyFileSync(path.join(__dirname, './index.html_replacement'), 
        path.join(__dirname, './node_modules/swagger-ui-dist/index.html'), (err) => {
  if(err) {
    console.log('Unable to replace swagger-ui-dist/index.html file - something wrong with the installation ??');
    process.exit(1);
  }
})

// swaggerRouter configuration
const options = {
  swaggerUi: path.join(__dirname, '/swagger.json'),
  controllers: path.join(__dirname, './controllers'),
  useStubs: process.env.NODE_ENV === 'development' // Conditionally turn on stubs (mock mode)
};

const swaggerDoc = swaggerUtils.getSwaggerDoc();

swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {

  app.use(middleware.swaggerMetadata());

  // Validate Swagger requests
  app.use(middleware.swaggerValidator({
        validateResponse: false
  }));

  // Error handling for validation
  app.use(errorHandler);

  // Route validated requests to appropriate controller
  app.use(middleware.swaggerRouter(options));

  // Serve the Swagger documents and Swagger UI
  // using the more up-to-date swagger-ui-dist - not the default app.use(middleware.swaggerUi())
  app.use(middleware.swaggerUi({ swaggerUiDir: path.join(__dirname, 'node_modules', 'swagger-ui-dist') }));

  // Start the server
  http.createServer(app).listen(serverPort, function () {
    console.log('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort);
    console.log('Swagger-ui is available on http://localhost:%d/docs', serverPort);
  });

});

// handles timed out requests
function haltOnTimedout(req, res, next) {
    if (!req.timedout) {
        next();
    } else {
        debug("\nrequest timed out!\n");
        next("the request timed out", null, null, null, 504);
    }
}

function errorHandler (err, req, res, next) {
  if(err) {
    if(err.failedValidation) {
      const message = err.results.errors.map(item => item.message).join(", ");
      
      const error = new Error(ErrorEnum.INVALID_BODY, message);
      sendError(res,error);

    } else {
      const error = new Error(ErrorEnum.INVALID_BODY, "Invalid request");
      sendError(res,error);

    }

  } else {
    next(err,req,res);
  }
};

and mongoUtils.js contents below:

'use strict';

const util = require('util')
const assert = require('assert');

const queryToMongo = require('query-to-mongo');
const querystring = require('querystring');

const MongoClient = require('mongodb').MongoClient;

const {getResponseType, getPayloadType, getTypeDefinition} = require('./swaggerUtils');

var mongodb = null; 

function connectHelper(callback) {
  var config = require('../config.json');

  var argv = require('minimist')(process.argv);
  var dbhost = argv.dbhost ? argv.dbhost: config.db_host;
  const mongourl = process.env.MONGO_URL || (config.db_prot + "://" + dbhost + ":" + config.db_port + "/" + config.db_name);
 
  MongoClient.connect(mongourl, { useNewUrlParser: true }, function (err, db) {

      if (err) {
        mongodb = null;
        callback(err,null);
      } else {
        mongodb = db.db("mydatabase");
        callback(null,mongodb);
      }
    }
  );
};


function getMongoQuery(req) {
  var res;
  if(req instanceof Object) {
    res = queryToMongo(req._parsedUrl.query);
  } else {
    res = queryToMongo(querystring.parse(req));
  }

  if(res!==undefined && res.options!==undefined && res.options.fields!==undefined) {
    res.options.fields.href = true;
    res.options.fields.id = true;
  }

  try {
    const requestType = getPayloadType(req);
    const properties = Object.keys(res.criteria);

    var typeDefinition = getTypeDefinition(requestType);
    if(typeDefinition.properties!==undefined) {
      typeDefinition = typeDefinition.properties;
    }

    properties.forEach(prop => {
      var paramDef = typeDefinition[prop];
      if(paramDef!==undefined && paramDef.type === "string" && paramDef.format === "date-time") {
        const propVal = res.criteria[prop];
        // equality test if not the value is an object
        if(!(propVal instanceof Object)) {
          if(!isNaN(Date.parse(propVal))) {
            res.criteria[prop] = {$regex: '^' + propVal + '.*' };
          }
        }
      }
    });
  }
  catch(err) {
    // ignore for now
  }

  res.options.projection = res.options.fields;
  delete res.options.fields;

  return(res);

};

function quotedString(s) {
  return s;
};

function connectDb(callback) {
  if(mongodb) {
      mongodb.stats(function(err, stats) {
        if(stats != null) {
          callback(null,mongodb);
        } else {
          connectHelper(callback);
        }
      });
  } else {
    connectHelper(callback);
  }
};

function connect() {
  return new Promise(function(resolve,reject) {
      connectDb(function(err,db) {
        if(err!=null || db==null) {
          reject(err);
        } else {
          resolve(db);
        };
      });
    });
};

function sendDoc(res,code,doc) {
  // delete internal mongo _id from all documents
  if(Array.isArray(doc)) {
    // remove _id from all documents
    doc.forEach(x => {
      delete x._id;
    });
  } else {
    delete doc._id;
  }

  if(doc.href) {
    res.setHeader('Location',  doc.href);
  }

  res.statusCode = code;
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify(doc));
}


module.exports = { connect, connectDb, getMongoQuery, sendDoc };

the npm install is fine whereas node index.js gives below error

binding.copyFile(
**          ^
TypeError: mode must be int32 or null/undefined 
    at Object.copyFileSync (node:fs:3086:11) 
    at Object.<anonymous> (C:\Users\shivashankar.g02\<<project path>>\index.js:18:4) at Module._compile (node:internal/modules/cjs/loader:1562:14) 
**
    at Object..js (node:internal/modules/cjs/loader:1699:10) 
    at Module.load (node:internal/modules/cjs/loader:1313:32) 
    at Function._load (node:internal/modules/cjs/loader:1123:12) 
    at TracingChannel.traceSync (node:diagnostics_channel:322:14) 
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24) 
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5) 
    at node:internal/main/run_main_module:36:49 { 
  code: 'ERR_INVALID_ARG_TYPE' 

Any pointers/directions on why it's happening?


Solution

  • copyFileSync takes three arguments - the source, the destination and an optional mode integer mask. Your third argument is a callback, which causes this error.

    Since you're passing a callback, it seems like you meant to use copyFile, not copyFileSync:

    fs.copyFile(
      path.join(__dirname, './index.html_replacement'), 
      path.join(__dirname, './node_modules/swagger-ui-dist/index.html'), 
      (err) => {
        if(err) {
          console.log('Unable to replace swagger-ui-dist/index.html file - something wrong with the installation ??');
          process.exit(1);
        }
      }
    )
    

    For the record, copyFile can also take a mode argument, but like with copyFileSync, this argument can be omitted.