"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.load = exports.resolveSync = void 0;
const fs = __importStar(require("fs"));
const fast_glob_1 = require("fast-glob");
const path_1 = require("path");
const gather_deps_1 = require("./gather-deps");
const file_1 = require("./file");
const enhanced_resolve_1 = require("enhanced-resolve");
const { readFileSync, lstatSync, statSync, realpathSync } = fs;
const supportedJsExtensions = ['.js', '.cjs', '.mjs'];
const fileSystem = new enhanced_resolve_1.CachedInputFileSystem(fs, 4000), esmResolver = enhanced_resolve_1.ResolverFactory.createResolver({
    extensions: ['.js', '.cjs', '.mjs', '.json', '.node'],
    conditionNames: ['node', 'import', 'require', 'default'],
    useSyncFileSystemCalls: true,
    symlinks: false,
    fileSystem,
}), cjsResolver = enhanced_resolve_1.ResolverFactory.createResolver({
    extensions: ['.js', '.cjs', '.mjs', '.json', '.node'],
    conditionNames: ['node', 'require', 'default'],
    useSyncFileSystemCalls: true,
    symlinks: false,
    fileSystem,
}), defaultOptions = {
    loadContent: true,
    expand: 'none',
    isEntry: false,
    type: 'commonjs',
};
const ModulesDir = 'node_modules';
function stripControlCharacters(path) {
    return path && path.replace(/[\u0000-\u001F\u007F-\u009F]/g, '');
}
const emptyContext = {}, emptyResolveContext = {};
function resolveSync(from, request, resolver = cjsResolver) {
    const result = {
        absPath: '',
        pkgPath: '',
        pkg: null,
        warning: '',
    };
    resolver.resolve(emptyContext, from, request, emptyResolveContext, (err, path, data) => {
        if (err) {
            result.warning = err.message;
            return;
        }
        result.absPath = stripControlCharacters(path);
        result.pkgPath = stripControlCharacters(data.descriptionFilePath);
        result.pkg = data.descriptionFileData;
        return;
    });
    return result;
}
exports.resolveSync = resolveSync;
async function expand(file, fileDir, baseDir, globs) {
    const files = (0, fast_glob_1.sync)(globs, {
        onlyFiles: true,
        cwd: baseDir,
        followSymbolicLinks: false,
    });
    files
        .sort() //glob search is width first and not deterministic
        .map((dep) => (0, file_1.ensureDottedRelative)(fileDir, (0, path_1.join)(baseDir, dep)))
        .filter((relDep) => file.absPath !== (0, path_1.join)(baseDir, relDep))
        .forEach((relDep) => {
        file.deps[relDep] = file.deps[relDep] || null;
    });
    const currentDeps = Object.keys(file.deps);
    file.package &&
        file.package.dependencies &&
        Object.keys(file.package.dependencies || {}).forEach((dependency) => {
            if (!currentDeps.some((curDep) => curDep.startsWith(dependency))) {
                file.deps[dependency] = file.deps[dependency] || null;
            }
        });
}
function load(workingDirectory, request, options = defaultOptions) {
    var _a;
    const resolver = options.type === 'module' ? esmResolver : cjsResolver, { absPath, pkg, pkgPath, warning } = resolveSync(workingDirectory, request, resolver);
    if (!absPath) {
        return { warning: warning };
    }
    const file = (0, file_1.createFile)(absPath), isJs = options.isEntry || supportedJsExtensions.some((x) => absPath.endsWith(x));
    file.absPath = absPath;
    if (isJs || absPath.endsWith('json')) {
        file.contents = readFileSync(absPath, 'utf-8');
    }
    if (isJs) {
        try {
            const isModule = absPath.endsWith('.mjs') || !(0, file_1.isScript)(file.contents);
            const parseResult = (0, gather_deps_1.gatherDependencies)(file.contents, isModule);
            Object.assign(file.deps, parseResult.deps);
            file.moduleType = isModule ? 'module' : 'commonjs';
            file.variableImports = parseResult.variable;
        }
        catch (e) {
            return { warning: `Error parsing file: "${file.absPath}"\n${e.stack}` };
        }
    }
    const fileDir = (0, path_1.dirname)(file.absPath), expandVariable = Boolean(options.expand === 'variable' && file.variableImports);
    if ((0, file_1.isNodeModule)(request) && pkg && pkgPath) {
        file.package = pkg;
        file.deps[(0, file_1.ensureDottedRelative)(fileDir, pkgPath)] = null;
        const pkgDir = (file.moduleRoot = (0, path_1.dirname)(pkgPath)), expandAll = options.expand === 'all';
        const pkgPathParts = pkgPath.split(ModulesDir);
        const [_, ...pkgRootPrefix] = pkgPathParts.slice().reverse();
        const rootPkgDir = pkgPathParts[pkgRootPrefix.length].split(/\\|\//).filter((x) => x)[0];
        const pkgRoot = (0, path_1.join)(pkgRootPrefix.join(ModulesDir), ModulesDir, rootPkgDir);
        if (expandVariable || expandAll) {
            expand(file, fileDir, pkgDir, (0, file_1.nodeModuleGlobs)(file));
            file.contextExpanded = true;
        }
        expand(file, fileDir, pkgRoot, (0, file_1.extraGlobs)(file));
    }
    else if (expandVariable && ((_a = options.context) === null || _a === void 0 ? void 0 : _a.moduleRoot) && !options.context.expanded) {
        expand(file, fileDir, options.context.moduleRoot, (0, file_1.nodeModuleGlobs)({ package: { files: options.context.globs } }));
        file.contextExpanded = true;
    }
    if (!options.loadContent) {
        file.contents = null;
    }
    const stats = lstatSync(file.absPath);
    if (stats.isSymbolicLink()) {
        const path = realpathSync(file.absPath);
        const absStat = statSync(file.absPath);
        file.realPath = path;
        file.realSize = absStat.size;
    }
    file.size = stats.size;
    return file;
}
exports.load = load;
//# sourceMappingURL=data:application/json;base64,[encoded data, 7692 characters]