const fs = require('fs-extra');
const { providerCreator } = require('../shared/jimpleFns');
const { deepAssign } = require('../shared/deepAssign');
/**
* @module node/packageInfo
*/
/**
* @typedef {import('./pathUtils').PathUtils} PathUtils
*/
/**
* @typedef {import('../shared/jimpleFns').ProviderCreator<O>} ProviderCreator
* @template O
*/
/**
* @typedef {Object} PackageInfoServiceMap
* @property {string | PathUtils} [pathUtils] The name of the service for
* {@link PathUtils} or an instance of it.
* `pathUtils` by default.
* @parent module:node/packageInfo
*/
/**
* @typedef {Object} PackageInfoProviderOptions
* @property {string} serviceName The name that will be used to register
* the result of
* {@link module:node/packageInfo~packageInfo|packageInfo}.
* Its default value is `packageInfo`.
* @property {PackageInfoServiceMap} services A dictionary with the services that need
* to be injected on the function.
* @parent module:node/packageInfo
*/
/**
* Gets the contents of the implementation's `package.json`.
*
* @param {PathUtils} pathUtils To build the path to the `package.json`.
* @returns {Object.<string, any>}
* @tutorial packageInfo
* @todo This should be `async`, or at least have an async alternative.
*/
const packageInfo = (pathUtils) => fs.readJsonSync(pathUtils.join('package.json'));
/**
* The service provider that once registered on the app container will set the result of
* {@link module:node/packageInfo~packageInfo|packageInfo} as a service.
*
* @type {ProviderCreator<PackageInfoProviderOptions>}
* @tutorial packageInfo
*/
const packageInfoProvider = providerCreator((options = {}) => (app) => {
app.set(options.serviceName || 'packageInfo', () => {
/**
* @type {PackageInfoProviderOptions}
* @ignore
*/
const useOptions = deepAssign(
{
services: {
pathUtils: 'pathUtils',
},
},
options,
);
const { pathUtils } = useOptions.services;
const usePathUtils = typeof pathUtils === 'string' ? app.get(pathUtils) : pathUtils;
return packageInfo(usePathUtils);
});
});
module.exports.packageInfo = packageInfo;
module.exports.packageInfoProvider = packageInfoProvider;