oprogramador / json-schema-faker-cli

A CLI for json-schema-faker.
28 stars 12 forks source link

add usage(), user-friendly error messages, and support for the various options offered by the underling json-schema-faker library #25

Open liquidaty opened 3 years ago

liquidaty commented 3 years ago

I did not see any way to pass command-line options corresponding to the various options offered by the underling json-schema-faker library, so I made some changes for it to do so.

In addition, the CLI does not provide any usage message or user-friendly error messages if, for example, it is run with an insufficient number of arguments.

Lastly, if no output file is specified, it should output to stdout.

Could you please incorporate these changes to address these issues? They are pretty simple, so I didn't bother with a PR. This will allow you to do the following:

generate-json # outputs error message and usage message
generate-json --alwaysFakeOptionals my.schema.json > my-fake.json # saves to my-fake.json
generate-json --notAValidOption my.schema.json # outputs error message and usage message

The changes were to two files, generate.js and generate-json:

// --- app/generate.js ---

const _ = require('lodash');
const jsonfile = require('jsonfile');

function generate(inputPath, outputPath, itemsLength, options) {
  var faker = require('json-schema-faker');
  const inputObject = jsonfile.readFileSync(inputPath);
  if(options)
    faker.option(options);

  const output = itemsLength === undefined
    ? faker(inputObject)
    : _.times(itemsLength, () => faker(inputObject));

  if(!outputPath)
    console.log(JSON.stringify(output));
  else
    jsonfile.writeFileSync(outputPath, output);
}

module.exports = generate;

// --- .bin/generate_json

#!/usr/bin/env node
const generate = require('./app/generate');
const supportedOptions = {
  failOnInvalidTypes: true,
  defaultInvalidTypeProduct: null,
  useDefaultValue: false,
  requiredOnly: false,
  maxItems: null,
  maxLength: null,
  defaultMinItems: 0,
  defaultRandExpMax: 10,
  alwaysFakeOptionals: false
};

const optionUsage = Object.keys(supportedOptions).map(function(optName) {
  return '  --' + optName + '=' + JSON.stringify(supportedOptions[optName]);
});

const usage = [
  'Example:', '  ' + process.argv[1] + ' --alwaysFakeOptionals[=true] schema.json [output.json]',
  'Options and default values:'
].concat(optionUsage).join('\n') + '\n';

var options = {};
var files = [];
for(var i = 2; i < process.argv.length; i++) {
  var arg = process.argv[i];
  if(!arg.startsWith('--'))
    files.push(arg);
  else {
    var parts = arg.slice(2).split('=');
    var optName = parts[0];
    var optValue = parts[1];
    var showUsage = false;
    if(optName == 'help')
      showUsage = true;
    else if(!(optName in supportedOptions)) {
      console.error('Option ' + optName + ' not recognized');
      showUsage = true;
    }

    if(showUsage) {
      console.log(usage);
      return;
    }

    if(!optValue)
      options[optName] = true;
    else {
      try {
        options[optName] = JSON.parse(optValue);
      } catch(e) {
        options[optName] = optValue;
      }
    }
  }
}

if(!files[0])
  console.error('Input schema file not provided\n' + usage);
else
  generate(files[0], files[1], files[2], options);
oprogramador commented 3 years ago

Thanks for these suggestions but I'm not sure whether I'll have time to implement that.

liquidaty commented 3 years ago

OK thanks for the response. We will fork it ourselves and start a separate repo.

Before doing so, just wanted to confirm: you did see that all the code needed for the requested change is already there, and all that is needed to make these changes is to copy/paste those two snippets, and entirely replace the target files (probably all of 3 minutes)? Just don't want to duplicate a repo if not needed to do so

oprogramador commented 3 years ago

@liquidaty

Maybe it's easy to integrate this code but it's needed to check whether it works.

Generally, it's simpler if you open a PR. I don't promise to merge it as I'll need to check it but it'll be simpler for me than to copy-paste your code.

oprogramador commented 2 years ago

@liquidaty

I see that nobody has voted for resolving this issue with :+1: or :heart:, and there are no comments from people other than you and me.

Neither I need these updates.

Your code contains no tests and no descriptive README update.

Your updates seem to contain much more code than my current business logic (when we count only JS files, excluding tests).

Therefore, I decided to close this issue, without implementing it.

Anyway, thanks for this proposal and your code.

oprogramador commented 2 years ago

Regarding the output, maybe it would be better if this library supported only stdout so we could write to a file with the > bash operator.

However, currently, it doesn't seem to be a major problem as you can use cat e.g. generate-json schema.json output.json && cat output.json or possibly if you don't want any file created at the end: generate-json schema.json output.json && cat output.json && rm output.json

oprogramador commented 2 years ago

Btw. If I decided to use your code, I would change some parts like:

reubano commented 2 years ago

I agree. CLI usage and a way to provide options would be very useful.

sectoreleven commented 2 years ago

This would be of great interest to my org as well.

oprogramador commented 2 years ago

@liquidaty @reubano @sectoreleven

Could you check json-schema-faker-cli@5.0.3?

sectoreleven commented 2 years ago

@liquidaty @reubano @sectoreleven

Could you check json-schema-faker-cli@5.0.3?

We've been using the @liquidaty fork successfully, so changing that will be a bit low on our list currently.