@fontoxml/fontoxml-development-tools
Version:
Development tools for Fonto.
137 lines (117 loc) • 3.48 kB
JavaScript
import fs from 'fs';
import path from 'path';
import { pathToFileURL } from 'url';
import getParentDirectoryContainingFileSync from './getParentDirectoryContainingFileSync.js';
import Version from './Version.js';
/** @typedef {import('./App').default} App */
/** @typedef {import('./request/FdtCommand').default} FdtCommand */
/** @typedef {import('./request/FdtRequest').default} FdtRequest */
/** @typedef {{ location?: string }} Overrides */
/** @typedef {(request: FdtRequest) => Overrides} GetOverrides */
export default class EditorRepository {
/** @type {Map<FdtCommand, GetOverrides>} */
static _overridesByCommand = new Map();
/**
* @param {FdtCommand} command
* @param {GetOverrides} getOverrides
*/
static registerOverrideForCommand(command, getOverrides) {
this._overridesByCommand.set(command, getOverrides);
}
/**
* @param {FdtRequest} request
*
* @return {Overrides}
*/
static getOverridesForRequest(request) {
/** @type {GetOverrides | undefined} */
const getOverrides = this._overridesByCommand.get(request.command);
let location;
if (getOverrides) {
const overrides = getOverrides(request);
location = overrides.location;
}
return { location };
}
/**
* @param {App} app
*
* @return {Promise<void>}
*/
async init(app, request) {
this._app = app;
this.path = null;
this.config = null;
this.configSource = null;
this.hasPlatformLinked = null;
this.name = null;
/** @type {Version | null} */
this.sdkVersion = null;
/** @type {Error | null} */
this.manifestError = null;
const overrides = EditorRepository.getOverridesForRequest(request);
const editorPath = getParentDirectoryContainingFileSync(
path.resolve(overrides.location || process.cwd()),
'manifest.json'
);
if (!editorPath) {
return;
}
try {
const manifestJSON = JSON.parse(
fs.readFileSync(path.join(editorPath, 'manifest.json'), 'utf8')
);
manifestJSON.sdkVersion = new Version(manifestJSON.sdkVersion);
Object.assign(this, manifestJSON);
} catch (error) {
this.manifestError = error;
this.sdkVersion = null;
this._app.logger.notice(`Could not read manifest.json.`);
this._app.logger.notice(
"Please check and fix your editor's manifest.json file."
);
this._app.logger.break();
return;
}
this.path = editorPath;
try {
const platformLinkedPath = path.join(this.path, 'platform-linked');
this.hasPlatformLinked =
fs.existsSync(platformLinkedPath) &&
fs.statSync(platformLinkedPath).isDirectory() &&
fs
.readdirSync(platformLinkedPath)
.some((e) => e.startsWith('fontoxml-'));
} catch (_error) {
// No-op
}
try {
const configJsPath = path.join(this.path, 'config.js');
this.config = (await import(pathToFileURL(configJsPath))).default();
this.configSource = configJsPath;
} catch (_error) {
// No-op
}
if (!this.configSource) {
try {
const configJsonPath = path.join(this.path, 'config.json');
this.config = JSON.parse(
fs.readFileSync(configJsonPath),
'utf8'
);
this.configSource = configJsonPath;
} catch (_error) {
// No-op
}
}
}
throwIfNotInsideEditorRepository() {
if (!this.path) {
throw new this._app.logger.ErrorWithSolution(
`Not running from inside a Fonto Editor repository.`,
'This command requires to be run from inside a Fonto Editor repository.',
this.manifestError ? this.manifestError : undefined
);
}
}
}