/**
* Repository definition.
*
* @typedef {Object} Repository
* @property {string} type - Repository type. Can be one of `github`, `url`
* or `local`.
* @property {string} [repository] - When type is `github` this is a
* **mandatory** field. If your GitHub repository is at
* `https://github.com/user/repository` then this value should be
* `user/repository`.
* @property {string} [path] - When type is `github` this is an **optional**
* field. The path under the repository where the plugins are. Default is
* `src`.
* @property {string} [version] - When type is `github` this is an **optional**
* field. This is the branch, tag or commit of the repository you want to
* use.
* @property {string} [url] - When type is `url` this is a **mandatory**
* field. The URL to your repository. Take care that your host has CORS
* enabled.
* @property {object} [plugins] - When type is `local` this is a
* **mandatory** field. This property contains the code for plugins in
* a `local` repository.
*
* e.g.
* ```js
* {
* type: 'local',
* plugins: {
* 'pluginName1': 'JavaScript code',
* 'pluginName2': 'JavaScript code'
* }
* }
* ```
* @property {string} [path] - When type is `local` this is an
* **optional** field. This property contains the path from where the
* local repository has been loaded.
*/
/**
* Repository data.
*
* @typedef {Object} RepositoryData
*
* @property {string} name - Name of the repository.
* @property {string} [description] - Description of repository.
* @property {string} [author] - Author of the repository.
* @property {Array.<string>} [plugins] - Plugins that the repository contains.
* @property {object} [config] - Configuration object for this repository.
* Can for example define the path of where to load the plugins.
*/
/**
* Class for controlling Haxball Headless Manager (HHM) repositories.
*/
class RepositoryController {
constructor({ page, defaultRepoVersion }) {
this.page = page;
this.defaultRepoVersion = defaultRepoVersion;
this.running = false;
this._usable = false;
}
/**
* Adds a repository.
*
* If append is set to true, the new repository will be added with the
* lowest priority, i.e. plugins will only be loaded from it they can't
* be found in any other repository. Otherwise the repository will be
* added with the highest priority.
*
* @param {Repository} repository - The repository to be added.
* @param {boolean} [append] - Whether to append or prepend the repository
* to the Array of repositories.
* @returns {Promise.<boolean>} - Whether the repository was successfully added.
*
*/
async addRepository(repository, append) {
if (!repository) {
throw new TypeError('Missing required argument: repository');
}
return this.page.evaluate(
async (repository, append) => {
const repoFactory = HHM.manager.getPluginRepositoryFactory();
const pluginLoader = HHM.manager.getPluginLoader();
const r = await repoFactory.createRepository(repository);
return pluginLoader.addRepository(r, append);
},
repository,
append
);
}
/**
* Sets the repositories.
*
* Overwrites all repositories with the given array of repositories. Adds
* saviolas default repository if its not defined in the given array.
*
* @param {Array.<Repository>} repository - The repository to be added.
* @returns {Promise}
*/
async setRepositories(repositories) {
return this.page.evaluate(async (repositories) => {
const repoFactory = HHM.manager.getPluginRepositoryFactory();
const pluginLoader = HHM.manager.getPluginLoader();
pluginLoader.repositories = [];
let hasDefaultRepo = false;
for (let repo of repositories) {
if (
repo.type === `github` &&
repo.repository === `saviola777/hhm-plugins`
) {
hasDefaultRepo = true;
break;
}
}
if (!hasDefaultRepo) {
// Add default plugin repository.
const defaultRepo = await repoFactory.createRepository({
type: 'github',
repository: 'saviola777/hhm-plugins',
version: this.defaultRepoVersion,
});
pluginLoader.addRepository(defaultRepo);
}
for (const repoDefinition of repositories) {
const repo = await repoFactory.createRepository(repoDefinition);
pluginLoader.addRepository(repo);
}
}, repositories);
}
/**
* Returns whether the given repository already exists.
* Repositories are considered equal if their configuration is the same.
* @param {Repository} repository - Repository config.
* @returns {boolean} - Did the repository exist.
*/
async hasRepository(repository) {
if (!repository) {
return false;
}
return this.page.evaluate(async (repository) => {
const repoFactory = HHM.manager.getPluginRepositoryFactory();
const pluginLoader = HHM.manager.getPluginLoader();
const r = await repoFactory.createRepository(repository);
return pluginLoader.hasRepository(r);
}, repository);
}
/**
* Returns available repositories.
* @returns {Array.<Repository>} - An array of available repositories.
*
*/
async getRepositories() {
return this.page.evaluate(() => {
return HHM.manager.getPluginLoader().repositories;
});
}
/**
* Retrieves information about the given repository.
*
* The information is loaded from repositorys `repository.json` config file.
* @param {Repository} repository - The repository that you want to get
* information from.
* @returns {RepositoryData} - The metadata of the repository.
*/
async getRepositoryInformation(repository) {
return this.page.evaluate(async (rd) => {
let r = await HHM.manager
.getPluginRepositoryFactory()
.createRepository(rd);
return r.repositoryInformation;
}, repository);
}
}
module.exports = RepositoryController;