@@ -44,6 +44,7 @@ import { ClassicLevel } from "classic-level";
4444 * @property {object } [yamlOptions] Options to pass to yaml.dump when serializing Documents.
4545 * @property {JSONOptions } [jsonOptions] Options to pass to JSON.stringify when serializing Documents.
4646 * @property {DocumentType } [documentType] Required only for NeDB packs in order to generate a correct key.
47+ * @property {boolean } [clean] Delete the destination directory before unpacking.
4748 * @property {DocumentCollection } [collection] Required only for NeDB packs in order to generate a correct key. Can be
4849 * used instead of documentType if known.
4950 * @property {NameTransformer } [transformName] A function that is used to generate a filename for the extracted
@@ -206,7 +207,14 @@ async function compileNedb(pack, files, { log, transformEntry }={}) {
206207
207208 // Create a new NeDB Datastore.
208209 const db = Datastore . create ( pack ) ;
209- const packDoc = applyHierarchy ( doc => delete doc . _key ) ;
210+ const seenKeys = new Set ( ) ;
211+ const packDoc = applyHierarchy ( doc => {
212+ if ( seenKeys . has ( doc . _key ) ) {
213+ throw new Error ( `An entry with key '${ key } ' was already packed and would be overwritten by this entry.` ) ;
214+ }
215+ seenKeys . add ( doc . _key ) ;
216+ delete doc . _key ;
217+ } ) ;
210218
211219 // Iterate over all source files, writing them to the DB.
212220 for ( const file of files ) {
@@ -224,7 +232,7 @@ async function compileNedb(pack, files, { log, transformEntry }={}) {
224232 await db . insert ( doc ) ;
225233 if ( log ) console . log ( `Packed ${ chalk . blue ( doc . _id ) } ${ chalk . blue ( doc . name ? ` (${ doc . name } )` : "" ) } ` ) ;
226234 } catch ( err ) {
227- if ( log ) console . error ( `Failed to parse ${ chalk . red ( file ) } . See error below.` ) ;
235+ if ( log ) console . error ( `Failed to pack ${ chalk . red ( file ) } . See error below.` ) ;
228236 throw err ;
229237 }
230238 }
@@ -255,6 +263,9 @@ async function compileClassicLevel(pack, files, { log, transformEntry }={}) {
255263 const packDoc = applyHierarchy ( async ( doc , collection ) => {
256264 const key = doc . _key ;
257265 delete doc . _key ;
266+ if ( seenKeys . has ( key ) ) {
267+ throw new Error ( `An entry with key '${ key } ' was already packed and would be overwritten by this entry.` ) ;
268+ }
258269 seenKeys . add ( key ) ;
259270 const value = structuredClone ( doc ) ;
260271 await mapHierarchy ( value , collection , d => d . _id ) ;
@@ -273,7 +284,7 @@ async function compileClassicLevel(pack, files, { log, transformEntry }={}) {
273284 await packDoc ( doc , collection ) ;
274285 if ( log ) console . log ( `Packed ${ chalk . blue ( doc . _id ) } ${ chalk . blue ( doc . name ? ` (${ doc . name } )` : "" ) } ` ) ;
275286 } catch ( err ) {
276- if ( log ) console . error ( `Failed to parse ${ chalk . red ( file ) } . See error below.` ) ;
287+ if ( log ) console . error ( `Failed to pack ${ chalk . red ( file ) } . See error below.` ) ;
277288 throw err ;
278289 }
279290 }
@@ -323,7 +334,7 @@ async function compactClassicLevel(db) {
323334 * @returns {Promise<void> }
324335 */
325336export async function extractPack ( src , dest , {
326- nedb= false , yaml= false , yamlOptions= { } , jsonOptions= { } , log= false , documentType, collection, transformEntry,
337+ nedb= false , yaml= false , yamlOptions= { } , jsonOptions= { } , log= false , documentType, collection, clean , transformEntry,
327338 transformName
328339} = { } ) {
329340 if ( nedb && ( path . extname ( src ) !== ".db" ) ) {
@@ -333,6 +344,7 @@ export async function extractPack(src, dest, {
333344 if ( nedb && ! collection ) {
334345 throw new Error ( "For NeDB operations, a documentType or collection must be provided." ) ;
335346 }
347+ if ( clean ) fs . rmSync ( dest , { force : true , recursive : true , maxRetries : 10 } ) ;
336348 // Create the output directory if it doesn't exist already.
337349 fs . mkdirSync ( dest , { recursive : true } ) ;
338350 if ( nedb ) {
0 commit comments