UNPKG

@antora/file-publisher

Version:

Publishes the publishable files in the virtual file catalog(s) to the destination(s) specified in the playbook.

108 lines (97 loc) 4.62 kB
'use strict' const { inspect } = require('util') const ReadableOutputFileArray = require('./readable-output-file-array') const userRequire = require('@antora/user-require-helper') const { DEFAULT_DEST_FS } = require('./constants.js') /** * Publishes all publishable files in the specified catalogs using the * destination providers specified in the playbook. * * This function starts by retrieving all publishable files from the specified * collection of catalogs (currently those files with an out property). It then * resolves the publish function for each destination provider specified in the * playbook (i.e., `output.destinations`). If the provider is not known, the * publish function for that provider is resolved by requiring a module (or * relative path) having the same name as the provider. Once the publish * function is resolved, the configuration specified in the playbook for that * provider is bound to the function as its first argument. This function then * iterates over all publish providers and passes a Readable of the publishable * files as the second argument and the playbook as the third. The path of each * file has been updated to match the `out.path` value (currently by * instantiating a copy of the file). * * If a directory is specified directly on the output property of the playbook * (i.e., `output.dir`), that directory is used to create or override the first * fs provider in the list of destinations. If the clean property is set directly * on the output property of the playbook (i.e., `output.clean`), the clean * property is added to the configuration for each provider. * * @memberof file-publisher * * @param {Object} playbook - The configuration object for Antora that provides * access to the output destinations. * @param {Array<Catalog>} catalogs - The collection of catalogs from which to retrieve the * publishable virtual files. If catalogs is not an array, it will be wrapped in one. * @returns {Array<Object>} An array of reports that provide information about where the files were published. */ async function publishFiles (playbook, catalogs) { const output = playbook.output const destinations = getDestinations(output) if (!destinations.length) return [] const clean = output.clean const publishers = destinations.map((destination) => { const { provider, options } = resolveDestination(destination, clean) switch (provider) { case 'archive': case 'fs': return require('./providers/' + provider).bind(null, options) default: try { const userRequireContext = { dot: playbook.dir, paths: [playbook.dir || '', __dirname] } return userRequire(provider, userRequireContext).bind(null, options) } catch (err) { const errWrapper = new Error(`Unsupported destination provider: ${provider}`) errWrapper.stack += `\nCaused by: ${err.stack ? inspect(err).replace(/^Error \[(.+)\](?=: )/, '$1') : err}` throw errWrapper } } }) // Q: add getPublishableFiles / getOutFiles; return a stream? or getOutFilesAsStream? const files = (Array.isArray(catalogs) ? catalogs : [catalogs]).reduce((accum, catalog) => { // the check for getAll on catalogs is @deprecated; scheduled to be removed in Antora 4 accum.push(...(catalog.getFiles || catalog.getAll).apply(catalog).filter((file) => file.out)) return accum }, []) return Promise.all( publishers.length > 1 ? publishers .map((publish) => publish.bind(null, new ReadableOutputFileArray(files, true), playbook)) .map((publish) => publish()) : [publishers[0](new ReadableOutputFileArray(files), playbook)] ) } function getDestinations (output) { let destinations = output.destinations if (output.dir) { if (destinations?.length) { destinations = destinations.slice() const primaryFsDestIdx = destinations.findIndex(({ provider: candidate }) => candidate === 'fs') if (~primaryFsDestIdx) { ;(destinations[primaryFsDestIdx] = Object.assign({}, destinations[primaryFsDestIdx])).path = output.dir } else { destinations.unshift({ provider: 'fs', path: output.dir }) } } else { destinations = [{ provider: 'fs', path: output.dir }] } } else if (!destinations) { destinations = [{ provider: 'fs', path: DEFAULT_DEST_FS }] } return destinations } function resolveDestination (destination, clean) { const { provider, ...options } = destination if (clean) options.clean = true return { provider, options } } module.exports = publishFiles