"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.getPageStaticInfo = getPageStaticInfo;
var _configShared = require("../../server/config-shared");
var _extractConstValue = require("./extract-const-value");
var _escapeRegexp = require("../../shared/lib/escape-regexp");
var _parseModule = require("./parse-module");
var _fs = require("fs");
var _tryToParsePath = require("../../lib/try-to-parse-path");
var Log = _interopRequireWildcard(require("../output/log"));
var _constants = require("../../lib/constants");
function _getRequireWildcardCache() {
    if (typeof WeakMap !== "function") return null;
    var cache = new WeakMap();
    _getRequireWildcardCache = function() {
        return cache;
    };
    return cache;
}
function _interopRequireWildcard(obj) {
    if (obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache();
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {};
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
async function getPageStaticInfo(params) {
    const { isDev , pageFilePath , nextConfig , page  } = params;
    const fileContent = await tryToReadFile(pageFilePath, !isDev) || "";
    if (/runtime|getStaticProps|getServerSideProps|matcher/.test(fileContent)) {
        var ref;
        const swcAST = await (0, _parseModule).parseModule(pageFilePath, fileContent);
        const { ssg , ssr  } = checkExports(swcAST);
        // default / failsafe value for config
        let config = {};
        try {
            config = (0, _extractConstValue).extractExportedConstValue(swcAST, "config");
        } catch (e) {
            if (e instanceof _extractConstValue.UnsupportedValueError) {
                warnAboutUnsupportedValue(pageFilePath, page, e);
            }
        // `export config` doesn't exist, or other unknown error throw by swc, silence them
        }
        if (typeof config.runtime !== "string" && typeof config.runtime !== "undefined") {
            throw new Error(`Provided runtime `);
        } else if (!(0, _configShared).isServerRuntime(config.runtime)) {
            const options = Object.values(_constants.SERVER_RUNTIME).join(", ");
            if (typeof config.runtime !== "string") {
                throw new Error(`The \`runtime\` config must be a string. Please leave it empty or choose one of: ${options}`);
            } else {
                throw new Error(`Provided runtime "${config.runtime}" is not supported. Please leave it empty or choose one of: ${options}`);
            }
        }
        let runtime = _constants.SERVER_RUNTIME.edge === (config == null ? void 0 : config.runtime) ? _constants.SERVER_RUNTIME.edge : ssr || ssg ? (config == null ? void 0 : config.runtime) || ((ref = nextConfig.experimental) == null ? void 0 : ref.runtime) : undefined;
        if (runtime === _constants.SERVER_RUNTIME.edge) {
            warnAboutExperimentalEdgeApiFunctions();
        }
        const middlewareConfig = getMiddlewareConfig(config, nextConfig);
        return {
            ssr,
            ssg,
            ...middlewareConfig && {
                middleware: middlewareConfig
            },
            ...runtime && {
                runtime
            }
        };
    }
    return {
        ssr: false,
        ssg: false
    };
}
/**
 * Receives a parsed AST from SWC and checks if it belongs to a module that
 * requires a runtime to be specified. Those are:
 *   - Modules with `export function getStaticProps | getServerSideProps`
 *   - Modules with `export { getStaticProps | getServerSideProps } <from ...>`
 */ function checkExports(swcAST) {
    if (Array.isArray(swcAST == null ? void 0 : swcAST.body)) {
        try {
            for (const node of swcAST.body){
                var ref3, ref1;
                if (node.type === "ExportDeclaration" && ((ref3 = node.declaration) == null ? void 0 : ref3.type) === "FunctionDeclaration" && [
                    "getStaticProps",
                    "getServerSideProps"
                ].includes((ref1 = node.declaration.identifier) == null ? void 0 : ref1.value)) {
                    return {
                        ssg: node.declaration.identifier.value === "getStaticProps",
                        ssr: node.declaration.identifier.value === "getServerSideProps"
                    };
                }
                if (node.type === "ExportNamedDeclaration") {
                    const values = node.specifiers.map((specifier)=>{
                        var ref, ref2;
                        return specifier.type === "ExportSpecifier" && ((ref = specifier.orig) == null ? void 0 : ref.type) === "Identifier" && ((ref2 = specifier.orig) == null ? void 0 : ref2.value);
                    });
                    return {
                        ssg: values.some((value)=>[
                                "getStaticProps"
                            ].includes(value)),
                        ssr: values.some((value)=>[
                                "getServerSideProps"
                            ].includes(value))
                    };
                }
            }
        } catch (err) {}
    }
    return {
        ssg: false,
        ssr: false
    };
}
async function tryToReadFile(filePath, shouldThrow) {
    try {
        return await _fs.promises.readFile(filePath, {
            encoding: "utf8"
        });
    } catch (error) {
        if (shouldThrow) {
            throw error;
        }
    }
}
function getMiddlewareConfig(config, nextConfig) {
    const result = {};
    if (config.matcher) {
        result.pathMatcher = new RegExp(getMiddlewareRegExpStrings(config.matcher, nextConfig).join("|"));
        if (result.pathMatcher.source.length > 4096) {
            throw new Error(`generated matcher config must be less than 4096 characters.`);
        }
    }
    return result;
}
function getMiddlewareRegExpStrings(matcherOrMatchers, nextConfig) {
    var ref;
    if (Array.isArray(matcherOrMatchers)) {
        return matcherOrMatchers.flatMap((matcher)=>getMiddlewareRegExpStrings(matcher, nextConfig));
    }
    if (typeof matcherOrMatchers !== "string") {
        throw new Error("`matcher` must be a path matcher or an array of path matchers");
    }
    let matcher1 = matcherOrMatchers;
    if (!matcher1.startsWith("/")) {
        throw new Error("`matcher`: path matcher must start with /");
    }
    if ((ref = nextConfig.i18n) == null ? void 0 : ref.locales) {
        matcher1 = `/:nextInternalLocale(${nextConfig.i18n.locales.map((locale)=>(0, _escapeRegexp).escapeStringRegexp(locale)).join("|")})${matcher1 === "/" && !nextConfig.trailingSlash ? "" : matcher1}`;
    }
    if (nextConfig.basePath) {
        matcher1 = `${nextConfig.basePath}${matcher1 === "/" ? "" : matcher1}`;
    }
    const parsedPage = (0, _tryToParsePath).tryToParsePath(matcher1);
    if (parsedPage.error) {
        throw new Error(`Invalid path matcher: ${matcher1}`);
    }
    const regexes = [
        parsedPage.regexStr
    ].filter((x)=>!!x);
    if (regexes.length < 1) {
        throw new Error("Can't parse matcher");
    } else {
        return regexes;
    }
}
function warnAboutExperimentalEdgeApiFunctions() {
    if (warnedAboutExperimentalEdgeApiFunctions) {
        return;
    }
    Log.warn(`You are using an experimental edge runtime, the API might change.`);
    warnedAboutExperimentalEdgeApiFunctions = true;
}
let warnedAboutExperimentalEdgeApiFunctions = false;
const warnedUnsupportedValueMap = new Map();
function warnAboutUnsupportedValue(pageFilePath, page, error) {
    if (warnedUnsupportedValueMap.has(pageFilePath)) {
        return;
    }
    Log.warn(`Next.js can't recognize the exported \`config\` field in ` + (page ? `route "${page}"` : `"${pageFilePath}"`) + ":\n" + error.message + (error.path ? ` at "${error.path}"` : "") + ".\n" + "The default config will be used instead.\n" + "Read More - https://nextjs.org/docs/messages/invalid-page-config");
    warnedUnsupportedValueMap.set(pageFilePath, true);
}

//# sourceMappingURL=get-page-static-info.js.map