import { isObject } from "alcalzone-shared/typeguards" ; import fs from "fs-extra" ; import "reflect-metadata" ; import yargs from "yargs" ; import { json500To700 , json700To500 , jsonToNVM , jsonToNVM500 , migrateNVM , nvm500ToJSON , nvmToJSON , } from "./convert" ; import "./index" ; void yargs . env ( "NVMEDIT" ) . strict ( ) . usage ( "Z-Wave JS NVM converter utility\n\nUsage: $0 [options]" ) . alias ( "h" , "help" ) . alias ( "v" , "version" ) . wrap ( Math . min ( 100 , yargs . terminalWidth ( ) ) ) . options ( { verbose : { alias : "vv" , describe : "Print verbose output" , type : "boolean" } } ) . command ( "nvm2json" , "Convert an NVM backup to JSON" , ( yargs ) => yargs . usage ( "$0 nvm2json --in <input> --out <output>" ) . options ( { in : { describe : "NVM backup filename" , type : "string" , required : true } , out : { describe : "JSON output filename" , type : "string" , required : true } } ) , async ( argv ) => { const buffer = await fs . readFile ( argv . in ) ; let json ; try { json = nvmToJSON ( buffer , argv . verbose ) ; } catch ( e ) { try { json = nvm500ToJSON ( buffer ) ; } catch ( ee ) { console . error ( e ) ; process . exit ( 1 ) ; } } await fs . writeJSON ( argv . out , json , { spaces : "\t" } ) ; console . error ( `NVM (JSON) written to ${ argv . out }` ) ; process . exit ( 0 ) ; } ) . command ( "json2nvm" , "Convert the JSON representation of an NVM to binary" , ( yargs ) => yargs . usage ( "$0 json2nvm --in <input> --out <output> --protocolVersion <version>" ) . options ( { in : { describe : "JSON input filename" , type : "string" , required : true } , out : { describe : "NVM output filename" , type : "string" , required : true } , protocolVersion : { alias : "V" , describe : "target protocol version, determines the NVM format" , type : "string" , required : true } } ) , async ( argv ) => { const { protocolVersion } = argv ; const versionIs500 = /^\d\.\d+$/ . test ( protocolVersion ) ; const json = await fs . readJson ( argv . in ) ; const jsonIs500 = json . format === 500 ; if ( versionIs500 && ! jsonIs500 ) { console . error ( `ERROR: Protocol version ${ protocolVersion } looks like a 500-series version, but the JSON file does not belong to a 500-series NVM!
Convert it first using the 700to500 command.` ) ; process . exit ( 1 ) ; } else if ( jsonIs500 && ! versionIs500 ) { console . error ( `ERROR: Protocol version ${ protocolVersion } looks like a 700-series version, but the JSON file belong to a 500-series NVM!
Convert it first using the 500to700 command.` ) ; process . exit ( 1 ) ; } if ( ! isObject ( json . meta ) ) { console . error ( `ERROR: The JSON file does not contain the meta section, which is required for the conversion to a binary NVM!
Create a backup of the target stick, use the nvm2json command to convert it to JSON and copy the meta section from there.` ) ; process . exit ( 1 ) ; } const nvm = versionIs500 ? jsonToNVM500 ( json , protocolVersion ) : jsonToNVM ( json , protocolVersion ) ; await fs . writeFile ( argv . out , nvm ) ; console . error ( `NVM (binary) written to ${ argv . out }` ) ; process . exit ( 0 ) ; } ) . command ( "500to700" , "Convert a 500-series JSON file into a 700-series JSON file" , ( yargs ) => yargs . usage ( "$0 500to700 --in <input> --out <output> [--truncate]" ) . options ( { in : { describe : "500 series JSON input filename" , type : "string" , required : true } , out : { describe : "700 series output filename" , type : "string" , required : true } , truncate : { alias : "t" , describe : "Truncate application data if it is too large (> 512 bytes)" , type : "boolean" , required : false , default : false } } ) , async ( argv ) => { const json500 = await fs . readJson ( argv . in ) ; const json700 = json500To700 ( json500 , argv . truncate ) ; await fs . writeJSON ( argv . out , json700 , { spaces : "\t" } ) ; console . error ( `700-series NVM (JSON) written to ${ argv . out }` ) ; process . exit ( 0 ) ; } ) . command ( "700to500" , "Convert a 700-series JSON file into a 500-series JSON file" , ( yargs ) => yargs . usage ( "$0 700to500 --in <input> --out <output>" ) . options ( { in : { describe : "700 series JSON input filename" , type : "string" , required : true } , out : { describe : "500 series output filename" , type : "string" , required : true } } ) , async ( argv ) => { const json700 = await fs . readJson ( argv . in ) ; const json500 = json700To500 ( json700 ) ; await fs . writeJSON ( argv . out , json500 , { spaces : "\t" } ) ; console . error ( `500-series NVM (JSON) written to ${ argv . out }` ) ; process . exit ( 0 ) ; } ) . command ( "convert" , "Convert the format of an NVM backup between different Z-Wave modules" , ( yargs ) => yargs . usage ( "$0 convert --source <source> --target <target> --out <output>" ) . options ( { source : { describe : "The source NVM filename. This file will be converted to match the target NVM." , type : "string" , required : true } , target : { describe : "The target NVM filename. This file will used to determine how to convert the source NVM." , type : "string" , required : true } , out : { describe : "The output filename where the convert NVM will be written." , type : "string" , required : true } } ) , async ( argv ) => { const source = await fs . readFile ( argv . source ) ; const target = await fs . readFile ( argv . target ) ; const output = migrateNVM ( source , target ) ; await fs . writeFile ( argv . out , output ) ; console . error ( `Converted NVM written to ${ argv . out }` ) ; process . exit ( 0 ) ; } ) . demandCommand ( 1 , "Please specify a command" ) . parseAsync ( ) ;