11const fs = require ( 'fs' ) ;
22const TOML = require ( '@iarna/toml' ) ;
33const { parse : csvParse } = require ( 'fast-csv' ) ;
4+ const deepmerge = require ( 'deepmerge' ) ;
45
56const inputFormats = {
67 json : readJsonFile ,
@@ -46,6 +47,11 @@ exports.builder = {
4647 type : 'boolean' ,
4748 default : false ,
4849 } ,
50+ 'patch-existing' : {
51+ describe : 'For existing records, patch in provided values so that additional properties not included in the input are preserved' ,
52+ type : 'boolean' ,
53+ default : false ,
54+ } ,
4955} ;
5056
5157exports . handler = async function upsert ( {
@@ -57,6 +63,7 @@ exports.handler = async function upsert({
5763 encoding,
5864 attachments = null ,
5965 deleteMissing,
66+ patchExisting,
6067 ...argv
6168} ) {
6269 const logger = require ( '../lib/logger.js' ) ;
@@ -96,7 +103,13 @@ exports.handler = async function upsert({
96103
97104
98105 // clear sheet
106+ let inputSheet = sheet ;
107+
99108 if ( deleteMissing ) {
109+ // re-open input sheet
110+ inputSheet = await sheet . clone ( ) ;
111+
112+ // clear target sheet
100113 await sheet . clear ( ) ;
101114 }
102115
@@ -113,8 +126,28 @@ exports.handler = async function upsert({
113126
114127
115128 // upsert record(s) into sheet
116- for await ( const inputRecord of inputRecords ) {
117- const { blob : outputBlob , path : outputPath } = await sheet . upsert ( inputRecord ) ;
129+ for await ( let inputRecord of inputRecords ) {
130+
131+ if ( patchExisting ) {
132+ // TODO: move more of this logic inside Sheet class
133+
134+ // fetch existing record from inputSheet
135+ const inputRecordPath = await inputSheet . pathForRecord ( await inputSheet . normalizeRecord ( inputRecord ) ) ;
136+
137+ if ( inputRecordPath ) {
138+ const { root : inputSheetRoot } = await inputSheet . getCachedConfig ( ) ;
139+
140+ // existing record find, merge
141+ const existingBlob = await inputSheet . dataTree . getChild ( `${ path . join ( inputSheetRoot , inputRecordPath ) } .toml` ) ;
142+
143+ if ( existingBlob ) {
144+ const existingRecord = await inputSheet . readRecord ( existingBlob ) ;
145+ inputRecord = deepmerge ( inputRecord , existingRecord ) ;
146+ }
147+ }
148+ }
149+
150+ const { blob : outputBlob , path : outputPath } = await sheet . upsert ( inputRecord , { patchExisting } ) ;
118151 console . log ( `${ outputBlob . hash } \t${ outputPath } ` ) ;
119152
120153 if ( attachments ) {
0 commit comments