modules/shared/path.mjs

// module: TRUE

export { JSPath };

/* Used to locate files relative to the script or template being run */

/* Filename of the parent script file (the script actually run in PRIMER/POST) */
// @ts-ignore
const __PARENT_FILENAME__ = arguments[0];

class JSPath {
    /** PRIMER script
     * @type {string} */
    static get PRE() {
        return "Pre";
    }

    /** POST script
     * @type {string} */
    static get POST() {
        return "Post";
    }

    /** REPORTER template
     * @type {string} */
    static get TEMPLATE() {
        return "Template";
    }

    /** Sets the path to the workflow definitions directory
     * @param {string} location Where this is being called from
     * @param {string} [template_dir] REPORTER template directory (only needed when what == JSPath.Template)
     * @example
     * JSPath.SetWorkflowsDirectory(JSPath.POST);
     */
    static SetWorkflowsDirectory(location, template_dir = "") {
        let parent_path = __PARENT_FILENAME__.substring(
            0,
            Math.max(__PARENT_FILENAME__.lastIndexOf("/"), __PARENT_FILENAME__.lastIndexOf("\\"))
        );

        switch (location) {
            case JSPath.PRE:
                /* Assume that PRIMER scripts are at:
                 *     ${workflows_dir}/scripts/automotive_assessments/pre
                 */
                this._workflows_dir = `${parent_path}/../../../`;
                break;
            case JSPath.POST:
                /* Assume that POST scripts are at:
                 *     ${workflows_dir}/scripts/automotive_assessments/post/t-his
                 * or:
                 *     ${workflows_dir}/scripts/automotive_assessments/post/d3plot
                 * or:
                 *     ${workflows_dir}/scripts/automotive_assessments/post/primer
                 */
                this._workflows_dir = `${parent_path}/../../../../`;
                break;
            case JSPath.TEMPLATE:
                if (template_dir == "") {
                    ErrorMessage("Argument <template_dir> not defined in JSPath.WorkflowsDirectory");
                    this._workflows_dir = null;
                    break;
                }
                /* Assume that REPORTER templates are at:
                 *     ${workflows_dir}/templates/automotive_assessments
                 */
                this._workflows_dir = `${template_dir}/../../`;
                break;
            default:
                ErrorMessage("Unexpected <location> in JSPath.WorkflowsDirectory");
                this._workflows_dir = null;
                break;
        }
    }

    /** Returns the path to the workflow definitions directory
     * @returns {string}
     * @example
     * const workflows_dir = JSPath.GetWorkflowsDirectory();
     */
    static GetWorkflowsDirectory() {
        if (!this._workflows_dir) {
            ErrorMessage(
                "Workflow directory needs to be set with JSPath.SetWorkflowsDirectory() before it can be retrieved."
            );
        }
        return FormatPath(this._workflows_dir);
    }

    /** Returns the path to the datums definitions directory
     * Assumes that the path is relative to workflow directory
     * Done like this so that we can change it in one place
     * @returns {string}
     * @example
     * const datums_dir = JSPath.GetDatumsDirectory();
     */
    static GetDatumsDirectory() {
        return FormatPath(`${this.GetWorkflowsDirectory()}scripts/automotive_assessments/datums`);
    }

    /** Returns the path to the occupants definitions directory
     * Assumes that the path is relative to workflow directory
     * Done like this so that we can change it in one place
     * @returns {string}
     * @example
     * const occupants_dir = JSPath.GetOccupantsDirectory();
     */
    static GetOccupantsDirectory() {
        return FormatPath(`${this.GetWorkflowsDirectory()}scripts/automotive_assessments/occupants`);
    }

    /** Returns the path to the protocols definitions directory
     * Assumes that the path is relative to workflow directory
     * Done like this so that we can change it in one place
     * @returns {string}
     * @example
     * const protocols_dir = JSPath.GetProtocolsDirectory();
     */
    static GetProtocolsDirectory() {
        return FormatPath(`${this.GetWorkflowsDirectory()}scripts/automotive_assessments/protocols`);
    }

    /** Returns the path to the images directory
     * Assumes that the path is relative to workflow directory
     * Done like this so that we can change it in one place
     * @returns {string}
     * @example
     * const images_dir = JSPath.GetImagesDirectory();
     */
    static GetImagesDirectory() {
        return FormatPath(`${this.GetWorkflowsDirectory()}scripts/automotive_assessments/images`);
    }
}

/**
 * format path by changing all backslashes to forward slashes, remove any double slashes and resolve any ../ directories
 * @param {string} path
 * @returns {string} formatted_path
 */
function FormatPath(path) {
    /* This doesn't work correctly yet, so just return the original path */

    return path;

    //deal with UNC paths (assumption they are absolute paths that start with "\\")
    //if (/^\\\\.*/.test(path)) {
    //    //replace all forward slashes back slashes
    //    path = path.replace(/\//g, "\\");
    //} else {
    //    //replace all back slashes with forward slashes
    //    path = path.replace(/\\/g, "/");
    //    //replace any occurrences of 2 or more slashes with just one
    //    path = path.replace(/\/{2,}/g, "/");
    //}

    //let match = path.match(/^([\/\\\.]*)(.*)/);
    //let prefix = "";
    //if (match) {
    //    prefix = match[1];
    //    path = match[2];
    //}

    // Message(`prefix="${prefix}", path="${path}"`);

    //let re = /[\\\/]([^\\\/]+)[\\\/]\.\./g;
    //remove any "/<dir>/..", "\<dir>\.." etc. strings (i.e. 'swallow' up-directory ("/.." or "\.."") strings in path )
    //note this does not remove ../ or ..\ at the begining of a file path because they are held in the prefix variable
    //while (re.test(path)) {
    //    path = path.replace(re, "");
    //}

    //put the path back together with any intial ../../... etc. first
    //path = `${prefix}${path}`;

    //if (File.IsDirectory(path)) return path;

    //ErrorMessage(`Path "${path}" did not exist.`);
}