How to replicate `ipfs add --only-hash` in pure Javascript, for a particular case

For my Banana Split project I want to be able to compute IPFS links in the exact same way ipfs add --only-hash does it right now, under a set of specific assumptions:

  1. I’m only going to be hashing a single (html) file, never a directory or any other data.
  2. That file can be assumed to be under 1MB, so it should always be technically possible to store and transfer it in a single IPFS data node (no chunking and linking is required).
  3. There’s no need to assume the current defaults of the ipfs add, explicitly replicating the behaviour of ipfs add --cid-version=0 --chunker=size-1048576 --hash=sha2-256 will be enough.

Why do I need this?

My project is an webapp, contained in a single HTML file.
I need that single self-contained HTML file to output an IPFS address of itself (for printing on paper), and obviously just compiling that hash in would require a full SHA256 bruteforce.
So I’m going to compile the address in the runtime — and that runtime should be possible without any network connectivity, and also without any additional software being installed on the consumer’s device.

Ergo, the only feasible way for me to do that would be to reimplement the ipfs add --hash-only behaviour in JS code embedded in my HTML app, and print the resulting hash.
Then I can actually upload the file to the IPFS, pin the resulting hash — and expect exactly the same app being available (and re-uploadable, in an event of the original upload being inaccessible in a year or 5 or ten from now) under exactly the same address.

My problem

I have no issues with getting my file into a buffer in Javascript, SHA256-hashing it and even converting a hash into a base58-encoded multihash.

But as far as I understand this, I would have to add some protobuf layer with metainformation on top of my file’s hash — than hash that metainformation, and only then the resulting multihash will be a valid IPFS address.

My questions are:

  • where should I look for that protobuf definition?
  • Is there any compact description of the whole process (file → IPFS address), which I can use to double-check my understanding of the process?

As far as I can see, IPFS specs and implementations are scattered over enormous amount of different repositories, even hosted in the different Github organisations, which makes it hard to grasp — and there’s even a similar question asked on this forum, which hasn’t been answered…