Creare un applicazione a linea di comando con Node

Creare un applicazione a linea di comando con Node

Node oltre ad essere adatto per applicazioni client server veloci è scalabili, è indicato anche per la creazioni di strumenti utilizzabili da linea di comando.

In questo esempio, creeremo un applicazione (CLI) che permette di gestire in modo semplice degli ipotetici clienti come ad esempio ricercarli, aggiungerli ed eliminarli.

Per la creazione di quest'applicazione, utilizzeremo moduli nativi, moduli custom e moduli di terze parti.

indice

Inzializziamo la nostra app

Creiamo una cartella : cli-app ed inizializziamo la nostra applicazione nominata app.js

npm init --yes

Creiamo un file JSON contenente la lista dei Clienti

[
    {
        "orderId": "406-1234567-7894561",
        "purchaseDate": "2022-10-14",
        "paymentsDate": "2022-10-14",
        "buyerEmail": "bananajoe@yutubbe.it",
        "buyerName": "Banana Joe",
        "buyerPhoneNumber": "+39 347 1234567",
        "productName": "Mocassassini",
        "quantityPurchased": 10,
        "shipAddress1": "via degli anatroccoli,1",
        "shipAddress2": "c/o FunkyTech",
        "shipCity": "Melano",
        "shipState": "Me",
        "shipPostalCode": "83099",
        "shipCountry": "IT",
        "totalOrder": 200
    },
    {
        "orderId": "406-1234567-4567891",
        "purchaseDate": "2022-10-14",
        "paymentsDate": "2022-10-14",
        "buyerEmail": "nina@tekken.it",
        "buyerName": "Nina Tekken",
        "buyerPhoneNumber": "+39 347 7891238",
        "productName": "Scarponcini da trekking",
        "quantityPurchased": 450,
        "shipAddress1": "via della pizza, 1",
        "shipAddress2": "c/o Tekken3",
        "shipCity": "Siraccusa",
        "shipState": "Me",
        "shipPostalCode": "82079",
        "shipCountry": "IT",
        "totalOrder": 600
    },
    {
        "orderId": "406-7894561-1234567",
        "purchaseDate": "2022-10-14",
        "paymentsDate": "2022-10-14",
        "buyerEmail": "donato@pirolo.dev",
        "buyerName": "Donato Pirolo",
        "buyerPhoneNumber": "+39 347 4864261",
        "productName": "Fiordi di Nutella",
        "quantityPurchased": 600,
        "shipAddress1": "via dell'imbarazzo, 1",
        "shipAddress2": "c/o HealtyFood",
        "shipCity": "Mammolo",
        "shipState": "Ma",
        "shipPostal-code": "8109",
        "shipCountry": "IT",
        "totalOrder": 1000
    },
    {
        "orderId": "406-4864237-1234567",
        "purchaseDate": "2022-10-17",
        "paymentsDate": "2022-10-17",
        "buyerEmail": "dennis@devito.org",
        "buyerName": "Dennis De Vito",
        "buyerPhoneNumber": "+39 346 4864265",
        "productName": "Apollonia",
        "quantityPurchased": 486,
        "shipAddress1": "via zeus, 69",
        "shipAddress2": "c/o Tempio Shaolin",
        "shipCity": "Atene",
        "shipState": "GR",
        "shipPostal-code": "5462",
        "shipCountry": "GR",
        "totalOrder": 231
    }
]

Installiamo ed importiamo o i moduli di terze parti Chalk e yargs

Per rendere più accattivanti i nostri messaggi di errore, di successo ed informativi, useremo il modulo di terze parti chalk, mentre per fare parsing delle stringhe e definire i comandi usiamo il modulo yargs. Non ci resta che installarli ed importarli

Da terminale:

npm i chalk
npm i yargs

all'interno del file app.js

const chalk = require('chalk');
const yargs = require('yargs');

Creazione del comando get per il flag --nome

Andremo a creare un istruzione che ci restituisca l'oggetto cercato attraverso il nome.

All'interno della nostra app.js definiamo il comando a cui diamo il nome di get ed assicuriamoci che corrisponda ad il flag --nome

const chalk = require('chalk'); const yargs = require('yargs'); const { getCliente } = require('./app-fn'); yargs.command({ command : 'get', describe : 'Ricerca cliente in base al suo nome', builder : { nome :{ describe:'Nome del cliente da cercare', demandOption : true, type: 'string' } }, handler(argv) { const ris = getCliente(argv.nome); if(ris.status) { console.log(chalk.green.bold('Cliente trovato:\n')); console.log(ris.cliente); }else{ console.log(chalk.red.bold('Cliente non trovato. Forse cercavi:\n')); console.log(ris.suggerimenti); }; } }); yargs.parse();
  • Aggiungiamo const {getCliente} = require('./app-fn');
  • inserendo getCliente all'interno delle graffe facciamo destrutturazione, in quanto ritorneremo un oggetto con una serie di proprietà.

Definiamo il comando get a cui farà riferimento il flag --nome

  • A command() dobbiamo passare in input l'oggetto.
  • L'oggetto conterrà 4 proprietà:
    • command : nome del comando, in questo caso get
    • describe: descrive il comando
    • builder : {contiene a sua volta un oggetto che conterrà a sua volta i flag che ci aspettiamo quando viene lanciato il command appena descritto}
      • flag : nome del flag
        • describe : descrizione del flag
        • demandOption : true (per indicare che obbligatorio)
        • type : la tipologia del flag, in questo caso 'string'
    • handler(argv){}: questa funzione conterrà al suo interno l'oggetto argv di yargs, ed in input avrà la funzione getCliente(argv.nome)
      • const ris = getCliente(argv.nome) definiamo una costante che riporta la funzione getcliente con il nome cliente da ricercare. Questa funzione viene definita in un modulo esterno (in questo caso app-fn.js)
        • if(ris.status){console.log()} indica che il cliente è stato trovato, quindi restituiamo una stringa di testo abbellita con chalk che indica che il cliente è stato trovato e restituiamo il cliente trovato
        • else{} altrimenti se il cliente non è stato trovato, restituiamo una stringa di testo abbellitta con chalk ed i relativi suggerimenti.
      • console.log(cliente)
  • yargs.parse() : Con questa funzione abilitiamo yargs con il metodo parse()

Creazione del modulo (app-fn) per la lettura del file JSON e la ricerca del cliente

All'interno di questo modulo dovremmo effettuare la lettura di un file del file-system (il file JSON contenente i clienti), dobbiamo importare il modulo fs nativo di node.

const fs = require('fs');

function getCliente(buyerName) {
    const clientiJSON = fs.readFileSync('clienti.json','utf-8'),
        clienti = JSON.parse(clientiJSON),
        cliente = clienti.find(clienteItem => clienteItem.buyerName === buyerName),
        ris = {status: false, suggerimenti: '', cliente: null};
        
        if(!cliente){
            clienti.map(clienteItem => {
                if(clienteItem.buyerName[0] === buyerName[0]) {
                    ris.suggerimenti += `${clienteItem.buyerName} \n`;
                }
            });
            return ris;
        }
        ris.status = true;
        ris.cliente = cliente;
        return ris;

    return cliente;
};

module.exports = {
    getCliente
}

Spiegazione del modulo step by step

All'interno di questo modulo abbiamo bisogno di leggere un file all'interno del file system, quindi bisogna importare il modulo nativo di node fs

const fs = require('fs');

Definiamo la funzione getCliente() che riceverà in input il nome del cliente cercato

function getCliente(buyerName) {}

Per leggere in modo sincrono i dati del file system, possiamo utilizzare il metodo readFileSync del modulo fs di node, passando come primo parametro 'clienti.json' e come secondo parametro 'utf-8'

const clientiJSON = fs.readFileSync('clienti.json','utf-8')

Per trasformare i dati ricevuti (di tipo stringa) in oggetti javascript usiamo la funzione JSON.parse() di Javascript

const clienti = JSON.parse(clientiJSON);

Per ricercare il cliente il cui nome è all'interno della variabile buyerName, usiamo il metodo find di Javascript con cui controlliamo se il nome di clienteItem.buyerName è uguale al nome del cliente ricercato buyerName.

const cliente = clienti.find(clienteItem => clienteItem.buyerName === buyerName)

Definiamo la costante ris con al suo interno un oggetto con la proprietà status che inizializziamo con false, una proprietà suggerimenti che inizializziamo con una stringa vuota, una proprietà cliente che inizializziamo con null

ris = {status: false, suggerimenti: '', cliente: null};

Con if(!cliente){} indichiamo che se il cliente non viene trovato, vogliamo suggerire tutti i clienti che iniziano con la prima lettera del cliente cercato. Per fare questo useremo il metodo map di javascript

        if(!cliente){
            clienti.map(clienteItem => {
                if(clienteItem.buyerName[0] === buyerName[0]) {
                    ris.suggerimenti += `${clienteItem.buyerName} \n`;
                }
            });
return ris;

Se il cliente viene trovato, portiamo la proprietà status a true

ris.status = true;

Se il cliente viene trovato, restituiamo il cliente trovato.

ris.cliente = cliente;

Ritorniamo ris

return ris;

Esportiamo la funzione getCliente con module.exports

module.exports = {
    getCliente
}

Creazione del comando add con i vari --flag da aggiungere

Andremo a creare un istruzione che ci restituisca l'oggetto cercato attraverso il nome.

All'interno della nostra app.js definiamo il comando a cui diamo il nome di add ed assicuriamoci che corrispondano ad i vari flag: orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder

const chalk = require('chalk'); const yargs = require('yargs'); const { getCliente, addCliente } = require('./app-fn'); /* yargs.command({ command : 'get', describe : 'Ricerca cliente in base al suo nome', builder : { nome :{ describe:'Nome del cliente da cercare', demandOption : true, type: 'string' } }, handler(argv) { const ris = getCliente(argv.nome); if(ris.status) { console.log(chalk.green.bold('Cliente trovato:\n')); console.log(ris.cliente); }else{ console.log(chalk.red.bold('Cliente non trovato. Forse cercavi:\n')); console.log(ris.suggerimenti); }; } }); */ yargs.command({ command : 'add', describe : 'Aggiunta nuovo cliente', builder : { orderId :{ describe:'Nome del cliente da Aggiungere', demandOption : true, type: 'string' }, purchaseDate :{ describe:'Data di acquisto', demandOption : true, type: 'string' }, paymentsDate :{ describe:'Data di Pagamento', demandOption : true, type: 'string' }, buyerEmail :{ describe:'Email del Cliente', demandOption : true, type: 'string' }, buyerPhoneNumber :{ describe:'Numero telefonico del Cliente', demandOption : true, type: 'string' }, productName :{ describe:'Nome del Prodotto Acquistato', demandOption : true, type: 'string' }, quantityPurchased :{ describe:'Quantità acquistata (in numeri)', demandOption : true, type: 'number' }, shipAddress1 :{ describe:'Indirizzo Primario del Cliente', demandOption : true, type: 'string' }, shipAddress2 :{ describe:'Indirizzo Secondario del Cliente', demandOption : false, type: 'string' }, shipCity :{ describe:'Città del Cliente', demandOption : true, type: 'string' }, shipState :{ describe:'Provincia del Cliente', demandOption : true, type: 'string' }, shipPostalCode :{ describe:'Cap del Cliente', demandOption : true, type: 'string' }, shipCountry :{ describe:'Sigla Nazione', demandOption : true, type: 'string' }, totalOrder :{ describe:'Totale dell\'ordine in Euro', demandOption : true, type: 'number' } }, handler(argv) { addCliente(argv) } }); yargs.parse();
  • inserendo getCliente, addCliente all'interno delle graffe facciamo destrutturazione, in quanto ritorneremo un oggetto con una serie di proprietà.

Come per il comando get ed il flag nome, creiamo un comando add con tutti i vari flag che dobbiamo inserire per creare il cliente

  • handler(argv){}: questa funzione conterrà al suo interno l'oggetto argv di yargs, ed in input avrà la funzione getCliente(argv.nome)
    • const ris = getCliente(argv.nome) definiamo una costante che riporta la funzione getcliente con il nome cliente da ricercare. Questa funzione viene definita in un modulo esterno (in questo caso app-fn.js)
      • if(ris.status){console.log()} indica che il cliente è stato trovato, quindi restituiamo una stringa di testo abbellita con chalk che indica che il cliente è stato trovato e restituiamo il cliente trovato
      • else{} altrimenti se il cliente non è stato trovato, restituiamo una stringa di testo abbellitta con chalk ed i relativi suggerimenti.
    • console.log(cliente)

Creazione della funzione addCliente all'interno del modulo app-fn

Dopo aver creato una funzione per cercare i clienti, vogliamo creare una funzione per aggiungere i clienti, con tutti i valori e le proprietà usati dai precedenti clienti.

Per farlo, apriamo il file app-fn.js andremo a definire la funzione addCliente()

const fs = require('fs');

function getCliente(buyerName) {
    const clientiJSON = fs.readFileSync('clienti.json','utf-8'),
        clienti = JSON.parse(clientiJSON),
        cliente = clienti.find(clienteItem => clienteItem.buyerName === buyerName),
        ris = {status: false, suggerimenti: '', cliente: null};
        
        if(!cliente){
            clienti.map(clienteItem => {
                if(clienteItem.buyerName[0] === buyerName[0]) {
                    ris.suggerimenti += `${clienteItem.buyerName} \n`;
                }
            });
            return ris;
        }
        ris.status = true;
        ris.cliente = cliente;
        return ris;

    return cliente;
};
function addCliente({orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder}){
    const clientiJSON = fs.readFileSync('clienti.json','utf-8'),
            clienti = JSON.parse(clientiJSON);
    
    clienti.push({orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder});
    fs.writeFileSync('clienti.json',JSON.stringify(clienti));
    console.log(clienti);
};

module.exports = {
    getCliente,
    addCliente
}

Spiegazione del modulo step by step

All'interno di questo modulo abbiamo bisogno di leggere un file all'interno del file system, quindi bisogna importare il modulo nativo di node fs

const fs = require('fs');

Definiamo la funzione addCliente() e facciamo destrutturazione (passare un oggetto con una serie di proprietà)

function addCliente({orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder}) {}

Per leggere in modo sincrono i dati del file system, possiamo utilizzare il metodo readFileSync del modulo fs di node, passando come primo parametro 'clienti.json' e come secondo parametro 'utf-8'

const clientiJSON = fs.readFileSync('clienti.json','utf-8')

Per trasformare i dati ricevuti (di tipo stringa) in oggetti javascript usiamo la funzione JSON.parse() di Javascript

const clienti = JSON.parse(clientiJSON);

Per aggiungere il cliente usiamo il metodo push di Javascript e passiamo un oggetto con le varie proprietà orderID,purchaseDate,paymentsDate ecc...

clienti.push({orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder});

Adesso, con l'array aggiornato non ci resta che scrivere nel file clienti.json, per farlo useremo fs.writeFileSynch() scrivendo il file dove vogliamo scrivere, in questo caso clienti.json e come secondo parametro JSON.stringify dell'array clienti.

fs.writeFileSync('clienti.json',JSON.stringify(clienti));

Facciamo un console.log dell'array clienti.

console.log(clienti)

Esportiamo la funzione addCliente con module.exports

module.exports = {
    getCliente,
    addCliente
}

Funzionamento della funzione addCliente()

Ora possiamo aggiungere un cliente da linea di comando

node app.js add --orderId='406-1597535-7531598', >> --purchaseDate='20-10-2022', >> --paymentsDate='20-10-2022', >> --buyerEmail='piergerosvaldino@smititi.it', >> --buyerName='Piergerosvaldo Toraldo', >> --buyerPhoneNumber='+39 34900100203', >> --productName='Geranei Subacquei', >> --quantityPurchased=400, >> --shipAddress1='Via poseidonia 3', >> --shipAddress2='c/o Bevilacqua', >> --shipCity='Atlantide', >> --shipState='SS', >> --shipPostalCode='00509', >> --shipCountry='AT', >> --totalOrder=159;

Possiamo quindi vedere all'interno del file clienti.json che il cliente aggiunto da terminale è stato aggiunto correttamente al file.

Funzione AddClient Funzionamento

Creazione del comando del con i vari --flag da aggiungere

Andremo a creare l'ultimo comando, cioè cancellare l'utente in base al numero dell'ordine.

All'interno della nostra app.js definiamo il comando a cui diamo il nome di del ed assicuriamoci che corrisponda ad il flag --orderId

const chalk = require('chalk'); const yargs = require('yargs'); const { getCliente, addCliente, delCliente} = require('./app-fn'); /* yargs.command({ command : 'get', describe : 'Ricerca cliente in base al suo nome', builder : { nome :{ describe:'Nome del cliente da cercare', demandOption : true, type: 'string' } }, handler(argv) { const ris = getCliente(argv.nome); if(ris.status) { console.log(chalk.green.bold('Cliente trovato:\n')); console.log(ris.cliente); }else{ console.log(chalk.red.bold('Cliente non trovato. Forse cercavi:\n')); console.log(ris.suggerimenti); }; } }); yargs.command({ command : 'add', describe : 'Aggiunta nuovo cliente', builder : { orderId :{ describe:'Nome del cliente da Aggiungere', demandOption : true, type: 'string' }, purchaseDate :{ describe:'Data di acquisto', demandOption : true, type: 'string' }, paymentsDate :{ describe:'Data di Pagamento', demandOption : true, type: 'string' }, buyerEmail :{ describe:'Email del Cliente', demandOption : true, type: 'string' }, buyerPhoneNumber :{ describe:'Numero telefonico del Cliente', demandOption : true, type: 'string' }, productName :{ describe:'Nome del Prodotto Acquistato', demandOption : true, type: 'string' }, quantityPurchased :{ describe:'Quantità acquistata (in numeri)', demandOption : true, type: 'number' }, shipAddress1 :{ describe:'Indirizzo Primario del Cliente', demandOption : true, type: 'string' }, shipAddress2 :{ describe:'Indirizzo Secondario del Cliente', demandOption : false, type: 'string' }, shipCity :{ describe:'Città del Cliente', demandOption : true, type: 'string' }, shipState :{ describe:'Provincia del Cliente', demandOption : true, type: 'string' }, shipPostalCode :{ describe:'Cap del Cliente', demandOption : true, type: 'string' }, shipCountry :{ describe:'Sigla Nazione', demandOption : true, type: 'string' }, totalOrder :{ describe:'Totale dell\'ordine in Euro', demandOption : true, type: 'number' } }, handler(argv) { addCliente(argv) } }); */ yargs.command({ command : 'del', describe : 'Cancellare cliente in base al numero dell\'ordine', builder : { orderId :{ describe:'Numero dell\'ordine da cancellare', demandOption : true, type: 'string' } }, handler(argv) { delCliente(argv.orderId); } }); yargs.parse();
  • inserendo getCliente, addCliente , delCliente all'interno delle graffe facciamo destrutturazione, in quanto ritorneremo un oggetto con una serie di proprietà.

Come per il comando get ed add, creiamo un comando del con con il flag orderId che dobbiamo inserire per eliminare il cliente

  • handler(argv){}: questa funzione conterrà al suo interno l'oggetto argv di yargs, ed in input avrà la funzione delCliente(argv.orderId)
    • Invochiamo la funzione delCliente() passando in input argv.orderId;

Creazione della funzione delCliente all'interno del modulo app-fn

Per creare la funzione delCliente, apriamo il file app-fn.js dove andremo a definire la funzione delCliente()

const fs = require('fs');

function getCliente(buyerName) {
    const clientiJSON = fs.readFileSync('clienti.json','utf-8'),
        clienti = JSON.parse(clientiJSON),
        cliente = clienti.find(clienteItem => clienteItem.buyerName === buyerName),
        ris = {status: false, suggerimenti: '', cliente: null};
        
        if(!cliente){
            clienti.map(clienteItem => {
                if(clienteItem.buyerName[0] === buyerName[0]) {
                    ris.suggerimenti += `${clienteItem.buyerName} \n`;
                }
            });
            return ris;
        }
        ris.status = true;
        ris.cliente = cliente;
        return ris;

    return cliente;
};
function addCliente({orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder}){
    const clientiJSON = fs.readFileSync('clienti.json','utf-8'),
            clienti = JSON.parse(clientiJSON);
    
    clienti.push({orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder});
    fs.writeFileSync('clienti.json',JSON.stringify(clienti));
    console.log(clienti);
};

module.exports = {
    getCliente,
    addCliente
}

Spiegazione del modulo step by step

All'interno di questo modulo abbiamo bisogno di leggere un file all'interno del file system, quindi bisogna importare il modulo nativo di node fs

const fs = require('fs');

Definiamo la funzione delCliente()

function addCliente(orderId) {}

Per leggere in modo sincrono i dati del file system, possiamo utilizzare il metodo readFileSync del modulo fs di node, passando come primo parametro 'clienti.json' e come secondo parametro 'utf-8'

const clientiJSON = fs.readFileSync('clienti.json','utf-8')

Per trasformare i dati ricevuti (di tipo stringa) in oggetti javascript usiamo la funzione JSON.parse() di Javascript

const clienti = JSON.parse(clientiJSON);

Per ricercare all'interno dell'area clienti l'indice del cliente che vogliamo ricercare usiamo il metodo findIndex alla quale passiamo una callback che riceverà di volta in volta gli elementi dell'area clienti cliente => e controlliamo se il valore della proprietà orderId dell'area clienti è uguale all'orderId ricevuto in input dalla funzione del cliente.

ClienteIndex = clienti.findIndex(cliente => cliente.orderId === orderId);

Se il cliente non viene trovato if(clienteIndex === -1) ,restituisci 'Cliente non trovato' ed usciamo dalla funzione con return;

        if(clienteIndex === -1) {
            console.log('Cliente non trovato');
            return;
        }

Se il cliente invece esiste, vogliamo rimuverlo. Per farlo usiamo il metodo slice di Javascript (lavorando sull'array clienti), scriveremo quindi clienti.splice() passando come primo parametro l'indice dell'elemento che vogliamo eliminare clienteIndex e come secondo parametro, quanti elementi vogliamo eliminare (in questo caso 1)

clienti.splice(clienteIndex, 1);

Ora dobbiamo riscrivere il file clienti.json con i clienti aggiornati. Per farlo useremo fs.writeFileSync passando come primo parametro il percorso ed il nome del file, e come secondo parametro la stringa JSON dell'area clienti JSON.stringify passando in input l'array clienti ed infine per conferma e controllo clienti mostriamo il tutto con console.log(clienti);

fs.writeFileSync('clienti.json', JSON.stringify(clienti)); console.log(clienti);

Esportiamo la funzione delCliente con module.exports

module.exports = {
    getCliente,
    addCliente,
delCliente }

Funzionamento della funzione delCliente()

Ora possiamo eliminare un cliente (se esiste) oppure se non esiste ricevere un avviso che ci informa che il cliente non esite.

// esempio di cliente non trovato node app.js del --orderId='123456789'
// esempio di cliente trovato (da eliminare) node app.js del --orderId='406-1597535-7531598'

Possiamo quindi vedere all'interno del file clienti.json che il cliente aggiunto da terminale è stato eliminato correttamente dal file.

Funzione delCliente funzionamento

Refactoring applicazione

Fino ad ora abbiamo creato un applicazione funzionante, ma la sua strutturazione non è delle migliori. Questo perché scrivendo in questo modo, è poco leggibile e poco gestibile. Come ad esempio il caso di app.js dove sono contenuti solo 3 comandi ed è già abbastanza lungo.

Per risolvere, possiamo creare un modulo per ogni singolo comando. Ad esempio. creiamo una cartella cmd ed al suo interno creiamo i moduli get.js, add.js e del.js

Il Modulo get.js

Come possiamo vedere abbiamo copiato da get.js il comando get, lo abbiamo chiuso all'interno di una funzione chiamata get. Abbiamo importato i moduli usati dal comando (in questo caso fs), abbiamo copiato da app-fn.js la funzione getCliente ed infine abbiamo esportato la funzione con module.export=get;

const fs = require('fs');
const chalk = require('chalk');

function get(yargs){
    yargs.command({
        command : 'get',
        describe : 'Ricerca cliente in base al suo nome',
        builder : {
            nome :{
                describe:'Nome del cliente da cercare',
                demandOption : true,
                type: 'string'
            }
        },
        handler(argv) {
        const ris = getCliente(argv.nome);
            if(ris.status) {
                console.log(chalk.green.bold('Cliente trovato:\n'));
                console.log(ris.cliente);
            }else{
                console.log(chalk.red.bold('Cliente non trovato. Forse cercavi:\n'));
                console.log(ris.suggerimenti);
            };
        }
    });
}

function getCliente(buyerName) {
    const clientiJSON = fs.readFileSync('clienti.json','utf-8'),
        clienti = JSON.parse(clientiJSON),
        cliente = clienti.find(clienteItem => clienteItem.buyerName === buyerName),
        ris = {status: false, suggerimenti: '', cliente: null};
        
        if(!cliente){
            clienti.map(clienteItem => {
                if(clienteItem.buyerName[0] === buyerName[0]) {
                    ris.suggerimenti += `${clienteItem.buyerName} \n`;
                }
            });
            return ris;
        }
        ris.status = true;
        ris.cliente = cliente;
        return ris;

    return cliente;
};

module.exports = get;

Il Modulo add.js

Come possiamo vedere abbiamo copiato da app.js il comando add, lo abbiamo chiuso all'interno di una funzione chiamata add. Abbiamo importato i moduli usati dal comando (in questo caso fs), abbiamo copiato da app-fn.js la funzione addCliente ed infine abbiamo esportato la funzione con module.export=add;

const fs = require('fs');

function add(yargs) {
    yargs.command({
        command : 'add',
        describe : 'Aggiunta nuovo cliente',
        builder : {
            orderId :{
                describe:'Nome del cliente da Aggiungere',
                demandOption : true,
                type: 'string'
            },
            purchaseDate :{
                describe:'Data di acquisto',
                demandOption : true,
                type: 'string'
            },
            paymentsDate :{
                describe:'Data di Pagamento',
                demandOption : true,
                type: 'string'
            },
            buyerEmail :{
                describe:'Email del Cliente',
                demandOption : true,
                type: 'string'
            },
            buyerPhoneNumber :{
                describe:'Numero telefonico del Cliente',
                demandOption : true,
                type: 'string'
            },
            productName :{
                describe:'Nome del Prodotto Acquistato',
                demandOption : true,
                type: 'string'
            },
            quantityPurchased :{
                describe:'Quantità acquistata (in numeri)',
                demandOption : true,
                type: 'number'
            },
            shipAddress1 :{
                describe:'Indirizzo Primario del Cliente',
                demandOption : true,
                type: 'string'
            },
            shipAddress2 :{
                describe:'Indirizzo Secondario del Cliente',
                demandOption : false,
                type: 'string'
            },
            shipCity :{
                describe:'Città del Cliente',
                demandOption : true,
                type: 'string'
            },
            shipState :{
                describe:'Provincia del Cliente',
                demandOption : true,
                type: 'string'
            },
            shipPostalCode :{
                describe:'Cap del Cliente',
                demandOption : true,
                type: 'string'
            },
            shipCountry :{
                describe:'Sigla Nazione',
                demandOption : true,
                type: 'string'
            },
            totalOrder :{
                describe:'Totale dell\'ordine in Euro',
                demandOption : true,
                type: 'number'
            }
        },
        handler(argv) {
            addCliente(argv)
        }
    });
}

function addCliente({orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder}){
    const clientiJSON = fs.readFileSync('clienti.json','utf-8'),
            clienti = JSON.parse(clientiJSON);
    
    clienti.push({orderId,purchaseDate,paymentsDate,buyerEmail,buyerName,buyerPhoneNumber,productName,quantityPurchased,shipAddress1,shipAddress2,shipCity,shipState,shipPostalCode,shipCountry,totalOrder});
    fs.writeFileSync('clienti.json',JSON.stringify(clienti));
    console.log(clienti);
};

module.exports= add;

Il Modulo del.js

Come possiamo vedere abbiamo copiato da del.js il comando del, lo abbiamo chiuso all'interno di una funzione chiamata del. Abbiamo importato i moduli usati dal comando (in questo caso fs e chalk), abbiamo copiato da app-fn.js la funzione addCliente ed infine abbiamo esportato la funzione con module.export=del;

const fs = require('fs');
const chalk = require('chalk');

function del(yargs) {
    yargs.command({
        command : 'del',
        describe : 'Cancellare cliente in base al numero dell\'ordine',
        builder : {
            orderId :{
                describe:'Numero dell\'ordine da cancellare',
                demandOption : true,
                type: 'string'
            }
        },
        handler(argv) {
            delCliente(argv.orderId);
        }
    });
}

function delCliente(orderId){
    const clientiJSON = fs.readFileSync('clienti.json','utf-8'),
        clienti = JSON.parse(clientiJSON);
        clienteIndex = clienti.findIndex(cliente => cliente.orderId === orderId);
        if(clienteIndex === -1) {
            console.log('Cliente non trovato');
            return;
        }
        clienti.splice(clienteIndex, 1);
        fs.writeFileSync('clienti.json', JSON.stringify(clienti));
        console.log(clienti);
}

module.exports = del;

Il Modulo app.js

Importiamo i vari moduli all'interno dell'applicazione app.js e poi invochiamo le funzioni get, add e del facendo passare l'oggetto yargs

const yargs = require('yargs');
const get = require('./cmd/get');
const add = require('./cmd/add');
const del = require('./cmd/del');

get(yargs); // Ricerca del Cliente
add(yargs); // Aggiungere un Cliente
del(yargs); // Rimuovere un cliente tramite orderId

yargs.parse();

Scarica l'applicazione

Scarica l'applicazione node.js per cercare clienti, aggiungere clienti, ed eliminare clienti con nodeJS.

Scritto da Donato Pirolo

Ciao, sono Donato, frontend developer con una smisurata passione per la SEO. Creo strumenti ad hoc per aiutare aziende e professionisti ad essere cercati sul web e trovare clienti.

Potrebbero interessarti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Copyright © 2022
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram