"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
0 && (module.exports = {
    getTurbopackJsConfig: null,
    formatIssue: null,
    processIssues: null,
    renderStyledStringToErrorAnsi: null,
    msToNs: null,
    handleRouteType: null,
    handleEntrypoints: null,
    handlePagesErrorRoute: null
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    getTurbopackJsConfig: function() {
        return getTurbopackJsConfig;
    },
    formatIssue: function() {
        return formatIssue;
    },
    processIssues: function() {
        return processIssues;
    },
    renderStyledStringToErrorAnsi: function() {
        return renderStyledStringToErrorAnsi;
    },
    msToNs: function() {
        return msToNs;
    },
    handleRouteType: function() {
        return handleRouteType;
    },
    handleEntrypoints: function() {
        return handleEntrypoints;
    },
    handlePagesErrorRoute: function() {
        return handlePagesErrorRoute;
    }
});
const _loadjsconfig = /*#__PURE__*/ _interop_require_default(require("../../build/load-jsconfig"));
const _magicidentifier = require("../../shared/lib/magic-identifier");
const _picocolors = require("../../lib/picocolors");
const _hotreloadertypes = require("./hot-reloader-types");
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../build/output/log"));
const _entrykey = require("./turbopack/entry-key");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {};
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && 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 getTurbopackJsConfig(dir, nextConfig) {
    const { jsConfig } = await (0, _loadjsconfig.default)(dir, nextConfig);
    return jsConfig ?? {
        compilerOptions: {}
    };
}
class ModuleBuildError extends Error {
}
function getIssueKey(issue) {
    return [
        issue.severity,
        issue.filePath,
        JSON.stringify(issue.title),
        JSON.stringify(issue.description)
    ].join("-");
}
function formatIssue(issue) {
    const { filePath, title, description, source } = issue;
    let { documentationLink } = issue;
    let formattedTitle = renderStyledStringToErrorAnsi(title).replace(/\n/g, "\n    ");
    // TODO: Use error codes to identify these
    // TODO: Generalize adapting Turbopack errors to Next.js errors
    if (formattedTitle.includes("Module not found")) {
        // For compatiblity with webpack
        // TODO: include columns in webpack errors.
        documentationLink = "https://nextjs.org/docs/messages/module-not-found";
    }
    let formattedFilePath = filePath.replace("[project]/", "./").replaceAll("/./", "/").replace("\\\\?\\", "");
    let message;
    if (source && source.range) {
        const { start } = source.range;
        message = `${formattedFilePath}:${start.line + 1}:${start.column + 1}\n${formattedTitle}`;
    } else if (formattedFilePath) {
        message = `${formattedFilePath}\n${formattedTitle}`;
    } else {
        message = formattedTitle;
    }
    message += "\n";
    if ((source == null ? void 0 : source.range) && source.source.content) {
        const { start, end } = source.range;
        const { codeFrameColumns } = require("next/dist/compiled/babel/code-frame");
        message += codeFrameColumns(source.source.content, {
            start: {
                line: start.line + 1,
                column: start.column + 1
            },
            end: {
                line: end.line + 1,
                column: end.column + 1
            }
        }, {
            forceColor: true
        }).trim() + "\n\n";
    }
    if (description) {
        message += renderStyledStringToErrorAnsi(description) + "\n\n";
    }
    // TODO: make it possible to enable this for debugging, but not in tests.
    // if (detail) {
    //   message += renderStyledStringToErrorAnsi(detail) + '\n\n'
    // }
    // TODO: Include a trace from the issue.
    if (documentationLink) {
        message += documentationLink + "\n\n";
    }
    return message;
}
function processIssues(currentIssues, key, result, throwIssue = false) {
    const newIssues = new Map();
    currentIssues.set(key, newIssues);
    const relevantIssues = new Set();
    for (const issue of result.issues){
        if (issue.severity !== "error" && issue.severity !== "fatal") continue;
        const issueKey = getIssueKey(issue);
        const formatted = formatIssue(issue);
        newIssues.set(issueKey, issue);
        // We show errors in node_modules to the console, but don't throw for them
        if (/(^|\/)node_modules(\/|$)/.test(issue.filePath)) continue;
        relevantIssues.add(formatted);
    }
    if (relevantIssues.size && throwIssue) {
        throw new ModuleBuildError([
            ...relevantIssues
        ].join("\n\n"));
    }
}
function renderStyledStringToErrorAnsi(string) {
    function decodeMagicIdentifiers(str) {
        return str.replaceAll(_magicidentifier.MAGIC_IDENTIFIER_REGEX, (ident)=>{
            try {
                return (0, _picocolors.magenta)(`{${(0, _magicidentifier.decodeMagicIdentifier)(ident)}}`);
            } catch (e) {
                return (0, _picocolors.magenta)(`{${ident} (decoding failed: ${e})}`);
            }
        });
    }
    switch(string.type){
        case "text":
            return decodeMagicIdentifiers(string.value);
        case "strong":
            return (0, _picocolors.bold)((0, _picocolors.red)(decodeMagicIdentifiers(string.value)));
        case "code":
            return (0, _picocolors.green)(decodeMagicIdentifiers(string.value));
        case "line":
            return string.value.map(renderStyledStringToErrorAnsi).join("");
        case "stack":
            return string.value.map(renderStyledStringToErrorAnsi).join("\n");
        default:
            throw new Error("Unknown StyledString type", string);
    }
}
const MILLISECONDS_IN_NANOSECOND = 1000000;
function msToNs(ms) {
    return BigInt(Math.floor(ms)) * BigInt(MILLISECONDS_IN_NANOSECOND);
}
async function handleRouteType({ dev, page, pathname, route, currentIssues, entrypoints, manifestLoader, readyIds, rewrites, hooks }) {
    switch(route.type){
        case "page":
            {
                const clientKey = (0, _entrykey.getEntryKey)("pages", "client", page);
                const serverKey = (0, _entrykey.getEntryKey)("pages", "server", page);
                try {
                    if (entrypoints.global.app) {
                        const key = (0, _entrykey.getEntryKey)("pages", "server", "_app");
                        const writtenEndpoint = await entrypoints.global.app.writeToDisk();
                        hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
                        processIssues(currentIssues, key, writtenEndpoint);
                    }
                    await manifestLoader.loadBuildManifest("_app");
                    await manifestLoader.loadPagesManifest("_app");
                    if (entrypoints.global.document) {
                        const key = (0, _entrykey.getEntryKey)("pages", "server", "_document");
                        const writtenEndpoint = await entrypoints.global.document.writeToDisk();
                        hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
                        processIssues(currentIssues, key, writtenEndpoint);
                    }
                    await manifestLoader.loadPagesManifest("_document");
                    const writtenEndpoint = await route.htmlEndpoint.writeToDisk();
                    hooks == null ? void 0 : hooks.handleWrittenEndpoint(serverKey, writtenEndpoint);
                    const type = writtenEndpoint == null ? void 0 : writtenEndpoint.type;
                    await manifestLoader.loadBuildManifest(page);
                    await manifestLoader.loadPagesManifest(page);
                    if (type === "edge") {
                        await manifestLoader.loadMiddlewareManifest(page, "pages");
                    } else {
                        manifestLoader.deleteMiddlewareManifest(serverKey);
                    }
                    await manifestLoader.loadFontManifest(page, "pages");
                    await manifestLoader.loadLoadableManifest(page, "pages");
                    await manifestLoader.writeManifests({
                        rewrites,
                        pageEntrypoints: entrypoints.page
                    });
                    processIssues(currentIssues, serverKey, writtenEndpoint);
                } finally{
                    // TODO subscriptions should only be caused by the WebSocket connections
                    // otherwise we don't known when to unsubscribe and this leaking
                    hooks == null ? void 0 : hooks.subscribeToChanges(serverKey, false, route.dataEndpoint, ()=>{
                        // Report the next compilation again
                        readyIds == null ? void 0 : readyIds.delete(pathname);
                        return {
                            event: _hotreloadertypes.HMR_ACTIONS_SENT_TO_BROWSER.SERVER_ONLY_CHANGES,
                            pages: [
                                page
                            ]
                        };
                    });
                    hooks == null ? void 0 : hooks.subscribeToChanges(clientKey, false, route.htmlEndpoint, ()=>{
                        return {
                            event: _hotreloadertypes.HMR_ACTIONS_SENT_TO_BROWSER.CLIENT_CHANGES
                        };
                    });
                    if (entrypoints.global.document) {
                        hooks == null ? void 0 : hooks.subscribeToChanges((0, _entrykey.getEntryKey)("pages", "server", "_document"), false, entrypoints.global.document, ()=>{
                            return {
                                action: _hotreloadertypes.HMR_ACTIONS_SENT_TO_BROWSER.RELOAD_PAGE
                            };
                        });
                    }
                }
                break;
            }
        case "page-api":
            {
                const key = (0, _entrykey.getEntryKey)("pages", "server", page);
                const writtenEndpoint = await route.endpoint.writeToDisk();
                hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
                const type = writtenEndpoint == null ? void 0 : writtenEndpoint.type;
                await manifestLoader.loadPagesManifest(page);
                if (type === "edge") {
                    await manifestLoader.loadMiddlewareManifest(page, "pages");
                } else {
                    manifestLoader.deleteMiddlewareManifest(key);
                }
                await manifestLoader.loadLoadableManifest(page, "pages");
                await manifestLoader.writeManifests({
                    rewrites,
                    pageEntrypoints: entrypoints.page
                });
                processIssues(currentIssues, key, writtenEndpoint);
                break;
            }
        case "app-page":
            {
                const key = (0, _entrykey.getEntryKey)("app", "server", page);
                const writtenEndpoint = await route.htmlEndpoint.writeToDisk();
                hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
                // TODO subscriptions should only be caused by the WebSocket connections
                // otherwise we don't known when to unsubscribe and this leaking
                hooks == null ? void 0 : hooks.subscribeToChanges(key, true, route.rscEndpoint, (change)=>{
                    if (change.issues.some((issue)=>issue.severity === "error")) {
                        // Ignore any updates that has errors
                        // There will be another update without errors eventually
                        return;
                    }
                    // Report the next compilation again
                    readyIds == null ? void 0 : readyIds.delete(pathname);
                    return {
                        action: _hotreloadertypes.HMR_ACTIONS_SENT_TO_BROWSER.SERVER_COMPONENT_CHANGES
                    };
                });
                const type = writtenEndpoint == null ? void 0 : writtenEndpoint.type;
                if (type === "edge") {
                    await manifestLoader.loadMiddlewareManifest(page, "app");
                } else {
                    manifestLoader.deleteMiddlewareManifest(key);
                }
                await manifestLoader.loadAppBuildManifest(page);
                await manifestLoader.loadBuildManifest(page, "app");
                await manifestLoader.loadAppPathsManifest(page);
                await manifestLoader.loadActionManifest(page);
                await manifestLoader.loadFontManifest(page, "app");
                await manifestLoader.writeManifests({
                    rewrites,
                    pageEntrypoints: entrypoints.page
                });
                processIssues(currentIssues, key, writtenEndpoint, dev);
                break;
            }
        case "app-route":
            {
                const key = (0, _entrykey.getEntryKey)("app", "server", page);
                const writtenEndpoint = await route.endpoint.writeToDisk();
                hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
                const type = writtenEndpoint == null ? void 0 : writtenEndpoint.type;
                await manifestLoader.loadAppPathsManifest(page);
                if (type === "edge") {
                    await manifestLoader.loadMiddlewareManifest(page, "app");
                } else {
                    manifestLoader.deleteMiddlewareManifest(key);
                }
                await manifestLoader.writeManifests({
                    rewrites,
                    pageEntrypoints: entrypoints.page
                });
                processIssues(currentIssues, key, writtenEndpoint, true);
                break;
            }
        default:
            {
                throw new Error(`unknown route type ${route.type} for ${page}`);
            }
    }
}
async function handleEntrypoints({ entrypoints, currentEntrypoints, currentIssues, manifestLoader, nextConfig, rewrites, changeSubscriptions, serverFields, hooks }) {
    currentEntrypoints.global.app = entrypoints.pagesAppEndpoint;
    currentEntrypoints.global.document = entrypoints.pagesDocumentEndpoint;
    currentEntrypoints.global.error = entrypoints.pagesErrorEndpoint;
    currentEntrypoints.global.instrumentation = entrypoints.instrumentation;
    currentEntrypoints.page.clear();
    currentEntrypoints.app.clear();
    for (const [pathname, route] of entrypoints.routes){
        switch(route.type){
            case "page":
            case "page-api":
                currentEntrypoints.page.set(pathname, route);
                break;
            case "app-page":
                {
                    route.pages.forEach((page)=>{
                        currentEntrypoints.app.set(page.originalName, {
                            type: "app-page",
                            ...page
                        });
                    });
                    break;
                }
            case "app-route":
                {
                    currentEntrypoints.app.set(route.originalName, route);
                    break;
                }
            default:
                _log.info(`skipping ${pathname} (${route.type})`);
                break;
        }
    }
    if (changeSubscriptions) {
        for (const [key, subscriptionPromise] of changeSubscriptions){
            const { type, page } = (0, _entrykey.splitEntryKey)(key);
            // middleware is handled below
            if (type === "app" && !currentEntrypoints.page.has(page) || type === "pages" && !currentEntrypoints.app.has(page)) {
                const subscription = await subscriptionPromise;
                await (subscription.return == null ? void 0 : subscription.return.call(subscription));
                changeSubscriptions.delete(key);
            }
        }
    }
    for (const [key] of currentIssues){
        const { type, page } = (0, _entrykey.splitEntryKey)(key);
        if (type === "app" && !currentEntrypoints.page.has(page) || type === "pages" && !currentEntrypoints.app.has(page)) {
            currentIssues.delete(key);
        }
    }
    const { middleware, instrumentation } = entrypoints;
    // We check for explicit true/false, since it's initialized to
    // undefined during the first loop (middlewareChanges event is
    // unnecessary during the first serve)
    if (currentEntrypoints.global.middleware && !middleware) {
        const key = (0, _entrykey.getEntryKey)("root", "server", "middleware");
        // Went from middleware to no middleware
        await (hooks == null ? void 0 : hooks.unsubscribeFromChanges(key));
        currentIssues.delete(key);
        hooks == null ? void 0 : hooks.sendHmr("middleware", {
            event: _hotreloadertypes.HMR_ACTIONS_SENT_TO_BROWSER.MIDDLEWARE_CHANGES
        });
    } else if (!currentEntrypoints.global.middleware && middleware) {
        // Went from no middleware to middleware
        hooks == null ? void 0 : hooks.sendHmr("middleware", {
            event: _hotreloadertypes.HMR_ACTIONS_SENT_TO_BROWSER.MIDDLEWARE_CHANGES
        });
    }
    currentEntrypoints.global.middleware = entrypoints.middleware;
    if (nextConfig.experimental.instrumentationHook && instrumentation) {
        const processInstrumentation = async (name, prop)=>{
            const key = (0, _entrykey.getEntryKey)("root", "server", name);
            const writtenEndpoint = await instrumentation[prop].writeToDisk();
            hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
            processIssues(currentIssues, key, writtenEndpoint);
        };
        await processInstrumentation("instrumentation.nodeJs", "nodeJs");
        await processInstrumentation("instrumentation.edge", "edge");
        await manifestLoader.loadMiddlewareManifest("instrumentation", "instrumentation");
        await manifestLoader.writeManifests({
            rewrites: rewrites,
            pageEntrypoints: currentEntrypoints.page
        });
        if (serverFields && (hooks == null ? void 0 : hooks.propagateServerField)) {
            serverFields.actualInstrumentationHookFile = "/instrumentation";
            await hooks.propagateServerField("actualInstrumentationHookFile", serverFields.actualInstrumentationHookFile);
        }
    } else {
        if (serverFields && (hooks == null ? void 0 : hooks.propagateServerField)) {
            serverFields.actualInstrumentationHookFile = undefined;
            await hooks.propagateServerField("actualInstrumentationHookFile", serverFields.actualInstrumentationHookFile);
        }
    }
    if (middleware) {
        const key = (0, _entrykey.getEntryKey)("root", "server", "middleware");
        const processMiddleware = async ()=>{
            const writtenEndpoint = await middleware.endpoint.writeToDisk();
            hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
            processIssues(currentIssues, key, writtenEndpoint);
            await manifestLoader.loadMiddlewareManifest("middleware", "middleware");
            if (serverFields) {
                var _manifestLoader_getMiddlewareManifest;
                serverFields.middleware = {
                    match: null,
                    page: "/",
                    matchers: (_manifestLoader_getMiddlewareManifest = manifestLoader.getMiddlewareManifest(key)) == null ? void 0 : _manifestLoader_getMiddlewareManifest.middleware["/"].matchers
                };
            }
        };
        await processMiddleware();
        hooks == null ? void 0 : hooks.subscribeToChanges(key, false, middleware.endpoint, async ()=>{
            const finishBuilding = hooks.startBuilding("middleware", undefined, true);
            await processMiddleware();
            if (serverFields && hooks.propagateServerField) {
                await hooks.propagateServerField("actualMiddlewareFile", serverFields.actualMiddlewareFile);
                await hooks.propagateServerField("middleware", serverFields.middleware);
            }
            await manifestLoader.writeManifests({
                rewrites: rewrites,
                pageEntrypoints: currentEntrypoints.page
            });
            finishBuilding == null ? void 0 : finishBuilding();
            return {
                event: _hotreloadertypes.HMR_ACTIONS_SENT_TO_BROWSER.MIDDLEWARE_CHANGES
            };
        });
    } else {
        manifestLoader.deleteMiddlewareManifest((0, _entrykey.getEntryKey)("root", "server", "middleware"));
        if (serverFields) {
            serverFields.actualMiddlewareFile = undefined;
            serverFields.middleware = undefined;
        }
    }
    if (serverFields && (hooks == null ? void 0 : hooks.propagateServerField)) {
        await hooks.propagateServerField("actualMiddlewareFile", serverFields.actualMiddlewareFile);
        await hooks.propagateServerField("middleware", serverFields.middleware);
    }
}
async function handlePagesErrorRoute({ currentIssues, entrypoints, manifestLoader, rewrites, hooks }) {
    if (entrypoints.global.app) {
        const key = (0, _entrykey.getEntryKey)("pages", "server", "_app");
        const writtenEndpoint = await entrypoints.global.app.writeToDisk();
        hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
        processIssues(currentIssues, key, writtenEndpoint);
    }
    await manifestLoader.loadBuildManifest("_app");
    await manifestLoader.loadPagesManifest("_app");
    await manifestLoader.loadFontManifest("_app");
    if (entrypoints.global.document) {
        const key = (0, _entrykey.getEntryKey)("pages", "server", "_document");
        const writtenEndpoint = await entrypoints.global.document.writeToDisk();
        hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
        hooks == null ? void 0 : hooks.subscribeToChanges(key, false, entrypoints.global.document, ()=>{
            return {
                action: _hotreloadertypes.HMR_ACTIONS_SENT_TO_BROWSER.RELOAD_PAGE
            };
        });
        processIssues(currentIssues, key, writtenEndpoint);
    }
    await manifestLoader.loadPagesManifest("_document");
    if (entrypoints.global.error) {
        const key = (0, _entrykey.getEntryKey)("pages", "server", "_error");
        const writtenEndpoint = await entrypoints.global.error.writeToDisk();
        hooks == null ? void 0 : hooks.handleWrittenEndpoint(key, writtenEndpoint);
        processIssues(currentIssues, key, writtenEndpoint);
    }
    await manifestLoader.loadBuildManifest("_error");
    await manifestLoader.loadPagesManifest("_error");
    await manifestLoader.loadFontManifest("_error");
    await manifestLoader.writeManifests({
        rewrites,
        pageEntrypoints: entrypoints.page
    });
}

//# sourceMappingURL=turbopack-utils.js.map