text: #!/usr/bin/env node
  const express = require('express')
  const crypto = require('crypto')
  const path = require('path')
  const os = require('os')
  const fs = require('fs')
  const fsPromises = require('fs/promises')
  const multer = require('multer')
  const compression = require('compression')
  const yargs = require('yargs')
  const semverValid = require('semver/functions/valid')
  
  const argv = yargs
      .usage(
          '$0',
          'Allows to host Enso libraries and editions from the local filesystem through HTTP.'
      )
      .option('port', {
          description: 'The port to listen on.',
          type: 'number',
          default: 8080,
      })
      .option('root', {
          description:
              'The root of the repository. It should contain a `libraries` or `editions` directory. See the documentation for more details.',
          type: 'string',
          default: '.',
      })
      .option('upload', {
          description:
              'Specifies whether to allow uploading libraries and which authentication model to choose.',
          choices: ['disabled', 'no-auth', 'constant-token'],
          default: 'disabled',
      })
      .help()
      .alias('help', 'h').argv
  
  const libraryRoot = path.join(argv.root, 'libraries')
  
  const app = express()
  const tmpDir = path.join(os.tmpdir(), 'enso-library-repo-uploads')
  const upload = multer({ dest: tmpDir })
  app.use(compression({ filter: shouldCompress }))
  
  /** The token to compare against for simple authentication.
   *
   * If it is not set, no authentication checks are made.
   */
  let token = null
  if (argv.upload == 'disabled') {
      console.log('Uploads are disabled.')
  } else {
      app.post('/upload', upload.any(), handleUpload)
  
      if (argv.upload == 'constant-token') {
          const envVar = 'ENSO_AUTH_TOKEN'
          token = process.env[envVar]
          if (!token) {
              throw `${envVar} is not defined.`
          } else {
              console.log(`Checking the ${envVar} to authorize requests.`)
          }
      } else {
          console.log('WARNING: Uploads are enabled without any authentication.')
      }
  }
  
  app.get('/health', function (req, res) {
      res.status(200).send('OK')
  })
  
  app.use(express.static(argv.root))
  
  let port = argv.port
  if (process.env.PORT) {
      port = process.env.PORT
      console.log(`Overriding the port to ${port} set by the PORT environment variable.`)
  }
  console.log(`Serving the repository located under ${argv.root} on port ${port}.`)
  
  const server = app.listen(port)
  
  function handleShutdown() {
      console.log('Received a signal - shutting down.')
      server.close(() => {
          console.log('Server terminated.')
      })
  }
  process.on('SIGTERM', handleShutdown)
  process.on('SIGINT', handleShutdown)
  
  /// Specifies if a particular file can be compressed in transfer, if supported.
  function shouldCompress(req, res) {
      if (req.path.endsWith('.yaml')) {
          return true
      }
  
      return compression.filter(req, res)
  }
  
  /** Handles upload of a library. */
  async function handleUpload(req, res) {
      function fail(code, message) {
          res.status(code).json({ error: message })
          cleanFiles(req.files)
      }
  
      if (token !== null) {
          const userToken = req.get('Auth-Token')
          if (userToken != token) {
              return fail(403, 'Authorization failed.')
          }
      }
  
      const version = req.query.version
      const namespace = req.query.namespace
      const name = req.query.name
  
      if (version === undefined || namespace == undefined || name === undefined) {
          return fail(400, 'One or more required fields were missing.')
      }
  
      if (!isVersionValid(version)) {
          return fail(400, `Invalid semver version string [${version}].`)
      }
  
      if (!isNamespaceValid(namespace)) {
          return fail(400, `Invalid username [${namespace}].`)
      }
  
      if (!isNameValid(name)) {
          return fail(400, `Invalid library name [${name}].`)
      }
  
      for (var i = 0; i < req.files.length; ++i) {
          const filename = req.files[i].originalname
          if (!isFilenameValid(filename)) {
              return fail(400, `Invalid filename: ${filename}.`)
          }
      }
  
      const libraryBasePath = path.join(libraryRoot, namespace, name)
      const libraryPath = path.join(libraryBasePath, version)
  
      /** Finds a name for a temporary directory to move the files to,
        so that the upload can then be committed atomically by renaming
        a single directory. */
      function findRandomTemporaryDirectory() {
          const randomName = crypto.randomBytes(32).toString('hex')
          const temporaryPath = path.join(libraryBasePath, randomName)
          if (fs.existsSync(temporaryPath)) {
              return findRandomTemporaryDirectory()
          }
  
          return temporaryPath
      }
  
      if (fs.existsSync(libraryPath)) {
          return fail(
              409,
              'A library with the given name and version ' +
                  'combination already exists. Versions are immutable, so you must ' +
                  'bump the library version when uploading a newer version.'
          )
      }
  
      const temporaryPath = findRandomTemporaryDirectory()
      await fsPromises.mkdir(libraryBasePath, { recursive: true })
      await fsPromises.mkdir(temporaryPath, { recursive: true })
  
      console.log(`Uploading library [${namespace}.${name}:${version}].`)
      try {
          await putFiles(temporaryPath, req.files)
          await fsPromises.rename(temporaryPath, libraryPath)
      } catch (error) {
          console.log(`Upload failed: [${error}].`)
          console.error(error.stack)
          return fail(500, 'Upload failed due to an internal error.')
      }
  
      console.log('Upload complete.')
      res.status(200).json({ message: 'Successfully uploaded the library.' })
  }
  
  /// Checks if a version complies with the semver specification.
  function isVersionValid(version) {
      return semverValid(version) !== null
  }
  
  /// Checks if the namespace/username is valid.
  function isNamespaceValid(namespace) {
      return /^[A-Za-z][a-z0-9]*$/.test(namespace) && namespace.length >= 3
  }
  
  /** Checks if the library name is valid.
   *
   * It may actually accept more identifiers as valid than Enso would, the actual
   * check should be done when creating the library. This is just a sanity check
   * for safety.
   */
  function isNameValid(name) {
      return /^[A-Za-z0-9_]+$/.test(name)
  }
  
  // TODO [RW] for now slashes are not permitted to avoid attacks; later on at least the `meta` directory should be allowed, but not much besides that
  /// Checks if the uploaded filename is valid.
  function isFilenameValid(name) {
      return /^[A-Za-z0-9][A-Za-z0-9\._\-]*$/.test(name)
  }
  
  /// Schedules to remove the files, if they still exist.
  function cleanFiles(files) {
      files.forEach(file => {
          if (fs.existsSync(file.path)) {
              fs.unlink(file.path, err => {
                  if (err) {
                      console.error(
                          `Failed to remove ${file.path} ($file.originalname) from a failed upload: ${err}.`
                      )
                  }
              })
          }
      })
  }
  
  /// Moves the files to the provided destination directory.
  async function putFiles(directory, files) {
      for (var i = 0; i < files.length; ++i) {
          const file = files[i]
          const filename = file.originalname
          const destination = path.join(directory, filename)
          await fsPromises.copyFile(file.path, destination)
          await fsPromises.unlink(file.path)
      }
  }
  