InputOutput.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { flags } from '@oclif/command'
  2. import { CLIError } from '@oclif/errors'
  3. import ExitCodes from '../ExitCodes'
  4. import fs from 'fs'
  5. import path from 'path'
  6. import Ajv from 'ajv'
  7. import $RefParser, { JSONSchema } from '@apidevtools/json-schema-ref-parser'
  8. import { getSchemasLocation } from 'cd-schemas'
  9. import chalk from 'chalk'
  10. // Default schema path for resolving refs
  11. const DEFAULT_SCHEMA_PATH = getSchemasLocation('entities') + path.sep
  12. export const IOFlags = {
  13. input: flags.string({
  14. char: 'i',
  15. required: false,
  16. description: `Path to JSON file to use as input (if not specified - the input can be provided interactively)`,
  17. }),
  18. output: flags.string({
  19. char: 'o',
  20. required: false,
  21. description:
  22. 'Path to the directory where the output JSON file should be placed (the output file can be then reused as input)',
  23. }),
  24. }
  25. export async function getInputJson<T>(inputPath?: string, schema?: JSONSchema, schemaPath?: string): Promise<T | null> {
  26. if (inputPath) {
  27. let content, jsonObj
  28. try {
  29. content = fs.readFileSync(inputPath).toString()
  30. } catch (e) {
  31. throw new CLIError(`Cannot access the input file at: ${inputPath}`, { exit: ExitCodes.FsOperationFailed })
  32. }
  33. try {
  34. jsonObj = JSON.parse(content)
  35. } catch (e) {
  36. throw new CLIError(`JSON parsing failed for file: ${inputPath}`, { exit: ExitCodes.InvalidInput })
  37. }
  38. if (schema) {
  39. const ajv = new Ajv()
  40. schema = await $RefParser.dereference(schemaPath || DEFAULT_SCHEMA_PATH, schema, {})
  41. const valid = ajv.validate(schema, jsonObj) as boolean
  42. if (!valid) {
  43. throw new CLIError(`Input JSON file is not valid: ${ajv.errorsText()}`)
  44. }
  45. }
  46. return jsonObj as T
  47. }
  48. return null
  49. }
  50. export function saveOutputJson(outputPath: string | undefined, fileName: string, data: any): void {
  51. if (outputPath) {
  52. let outputFilePath = path.join(outputPath, fileName)
  53. let postfix = 0
  54. while (fs.existsSync(outputFilePath)) {
  55. fileName = fileName.replace(/(_[0-9]+)?\.json/, `_${++postfix}.json`)
  56. outputFilePath = path.join(outputPath, fileName)
  57. }
  58. try {
  59. fs.writeFileSync(outputFilePath, JSON.stringify(data, null, 4))
  60. } catch (e) {
  61. throw new CLIError(`Could not save the output to: ${outputFilePath}. Check directory permissions`, {
  62. exit: ExitCodes.FsOperationFailed,
  63. })
  64. }
  65. console.log(`${chalk.green('Output succesfully saved to:')} ${chalk.white(outputFilePath)}`)
  66. }
  67. }