Except that is a false dichotomy. This isn't about inlining 'pure' functions (I know your example is IO, but they aren't mutating your program's state), it is about avoiding functions that are only used once and/or that mutate state.
I've used the same technique - instead of creating a function that might be awkward due to all the inputs and outputs, I'll create an inner scope {} with nothing around it. Only the variables that it modifies/initializes are left on the outside. This is a simple way to enforce more of a data flow style within a function and ends up being a useful organizational tool. It is also similar to 'let' in some languages.
Best of both worlds in Javascript. Use "IIFE" to make an anonymous function and call it. The editor lets you elide the function if you don't want to see the details, or leave it "open" if you want to read it.
If it turns out said little dance needs to be done twice, instead, assign the function expression to a name (in an appropriate scope) and call it twice.
Nested funcs/procs in Pascal were useful for this kind of local partitioning, as well (before C; C++; Java came and peed in the development mindshare pool), even if you couldn't make closures out of them.
That's all good, unless you need to do it twice. Then you're repeating yourself, and you're in a whole other world of pain next time you want to change some of the code.
2x copy-paste is a "whole other world of pain"? I've worked in shops where the rule was you didn't make a method or otherwise refactor until there were 3 repeats of the same code. If you're in an environment where you can make the prophylactic search for that code pattern, this works well. (I could easily make searches with full syntactic expressiveness.)
Sorry, but this isn't a "whole other world of pain." Increase the multiple to dozens, hundreds, or thousands. That is a whole other world of pain. (I've worked in a project that started with literally 500 re-implementations of doubly linked lists.)
Is get_config_filename() a large function that gets the filename directly or is the end result nested another hundred lines of callstack down? If it is a large function that directly returns results then that is my pick, high level "story" with shallow, direct access to the details. No dicking about for half an hour trying to figure out where A, B, or C happen, yet hidden details for when you are focusing on a different part of the code.
config_filename = get_config_filename()
config = read_config(config_filename)
endpoint_url = config["endpoint_url"]
auth_data = get_auth_data(endpoint_url)
to just dumping all of that inline.