isaacs / node-tar

tar for node
ISC License
837 stars 183 forks source link

[FEATURE] Extract a single file to a specific location #357

Closed emmercm closed 1 year ago

emmercm commented 1 year ago

What / Why

node-tar supports the ability to extract a list of specific files, but I would love the ability to specify their output file location, rather than just the output directory. Something to the effect of:

await tar.extractSingle({
  file: 'some_file.tar',
  strict: true,
}, 'file_in_tar.txt', '/home/some_other_filename.txt');
isaacs commented 1 year ago

You can do this with a custom filter already:

const tar = require('tar')
const { resolve } = require('path')

const extractOne = (tarOpts, filename, outputFilename) =>
  tar.x({
    ...tarOpts,
    filter: (path, entry) => {
      if (path === filename) {
        entry.path = outputFilename
        return true
      } else {
        return false
      }
    }
  })

extractOne({ file: 'tar_file.tgz', strict: true},
  'file_in_tar.txt',
  'other_filename.txt')

Doc patch welcome to show how :)

emmercm commented 1 year ago

Oh interesting, I didn't expect that I could manipulate the entry like that, but it makes sense.

Unfortunately, the typing here is wrong for TypeScript: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/3b052a3e5b59b0efaa22669d9bd8f268bd689835/types/tar/index.d.ts#L74

isaacs commented 1 year ago

Yeah, I need to ship a proper .d.ts for it. DT packages are a good fill in, but they tend to miss nuance and context that the module developer would have.

isaacs commented 1 year ago

Oh, I think that line is accurate though? That object is the index of where each field lives in the header, so fields.path is just zero. The entry is a different object.

emmercm commented 1 year ago

It looks like filter is on FileStat which is the linked Fields. I think it should be path: string.

isaacs commented 1 year ago

The real answer is that this library needs to be rewritten in TypeScript and built as a hybrid module, like everything else I maintain.

But it's lower on the priority list than finishing node-tap.