"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
0 && (module.exports = {
    createPrerenderParamsForClientSegment: null,
    createPrerenderParamsFromClient: null,
    createRenderParamsFromClient: null,
    createServerParamsForMetadata: null,
    createServerParamsForRoute: null,
    createServerParamsForServerSegment: null
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    createPrerenderParamsForClientSegment: function() {
        return createPrerenderParamsForClientSegment;
    },
    createPrerenderParamsFromClient: function() {
        return createPrerenderParamsFromClient;
    },
    createRenderParamsFromClient: function() {
        return createRenderParamsFromClient;
    },
    createServerParamsForMetadata: function() {
        return createServerParamsForMetadata;
    },
    createServerParamsForRoute: function() {
        return createServerParamsForRoute;
    },
    createServerParamsForServerSegment: function() {
        return createServerParamsForServerSegment;
    }
});
const _reflect = require("../web/spec-extension/adapters/reflect");
const _dynamicrendering = require("../app-render/dynamic-rendering");
const _prerenderasyncstorageexternal = require("../app-render/prerender-async-storage.external");
const _invarianterror = require("../../shared/lib/invariant-error");
const _utils = require("./utils");
const _dynamicrenderingutils = require("../dynamic-rendering-utils");
const _creatededupedbycallsiteservererrorloger = require("../create-deduped-by-callsite-server-error-loger");
function createPrerenderParamsFromClient(underlyingParams, workStore) {
    return createPrerenderParams(underlyingParams, workStore);
}
function createRenderParamsFromClient(underlyingParams, workStore) {
    return createRenderParams(underlyingParams, workStore);
}
const createServerParamsForMetadata = createServerParamsForServerSegment;
function createServerParamsForRoute(underlyingParams, workStore) {
    if (workStore.isStaticGeneration) {
        return createPrerenderParams(underlyingParams, workStore);
    } else {
        return createRenderParams(underlyingParams, workStore);
    }
}
function createServerParamsForServerSegment(underlyingParams, workStore) {
    if (workStore.isStaticGeneration) {
        return createPrerenderParams(underlyingParams, workStore);
    } else {
        return createRenderParams(underlyingParams, workStore);
    }
}
function createPrerenderParamsForClientSegment(underlyingParams, workStore) {
    const prerenderStore = _prerenderasyncstorageexternal.prerenderAsyncStorage.getStore();
    if (prerenderStore && prerenderStore.type === 'prerender') {
        if ((0, _prerenderasyncstorageexternal.isDynamicIOPrerender)(prerenderStore)) {
            const fallbackParams = workStore.fallbackRouteParams;
            if (fallbackParams) {
                for(let key in underlyingParams){
                    if (fallbackParams.has(key)) {
                        // This params object has one of more fallback params so we need to consider
                        // the awaiting of this params object "dynamic". Since we are in dynamicIO mode
                        // we encode this as a promise that never resolves
                        return (0, _dynamicrenderingutils.makeHangingPromise)();
                    }
                }
            }
        }
    }
    // We're prerendering in a mode that does not abort. We resolve the promise without
    // any tracking because we're just transporting a value from server to client where the tracking
    // will be applied.
    return (0, _utils.makeResolvedReactPromise)(underlyingParams);
}
function createPrerenderParams(underlyingParams, workStore) {
    const fallbackParams = workStore.fallbackRouteParams;
    if (fallbackParams) {
        let hasSomeFallbackParams = false;
        for(const key in underlyingParams){
            if (fallbackParams.has(key)) {
                hasSomeFallbackParams = true;
                break;
            }
        }
        if (hasSomeFallbackParams) {
            // params need to be treated as dynamic because we have at least one fallback param
            const prerenderStore = _prerenderasyncstorageexternal.prerenderAsyncStorage.getStore();
            if (prerenderStore && prerenderStore.type === 'prerender') {
                if ((0, _prerenderasyncstorageexternal.isDynamicIOPrerender)(prerenderStore)) {
                    // We are in a dynamicIO (PPR or otherwise) prerender
                    return makeAbortingExoticParams(underlyingParams, workStore.route, prerenderStore);
                }
            }
            // We aren't in a dynamicIO prerender but we do have fallback params at this
            // level so we need to make an erroring exotic params object which will postpone
            // if you access the fallback params
            return makeErroringExoticParams(underlyingParams, fallbackParams, workStore, prerenderStore);
        }
    }
    // We don't have any fallback params so we have an entirely static safe params object
    return makeUntrackedExoticParams(underlyingParams);
}
function createRenderParams(underlyingParams, workStore) {
    if (process.env.NODE_ENV === 'development' && !workStore.isPrefetchRequest) {
        return makeDynamicallyTrackedExoticParamsWithDevWarnings(underlyingParams, workStore);
    } else {
        return makeUntrackedExoticParams(underlyingParams);
    }
}
const CachedParams = new WeakMap();
function makeAbortingExoticParams(underlyingParams, route, prerenderStore) {
    const cachedParams = CachedParams.get(underlyingParams);
    if (cachedParams) {
        return cachedParams;
    }
    const promise = (0, _dynamicrenderingutils.makeHangingPromise)();
    CachedParams.set(underlyingParams, promise);
    Object.keys(underlyingParams).forEach((prop)=>{
        switch(prop){
            // Object prototype
            case 'hasOwnProperty':
            case 'isPrototypeOf':
            case 'propertyIsEnumerable':
            case 'toString':
            case 'valueOf':
            case 'toLocaleString':
            // Promise prototype
            // fallthrough
            case 'then':
            case 'catch':
            case 'finally':
            // React Promise extension
            // fallthrough
            case 'status':
            // Common tested properties
            // fallthrough
            case 'toJSON':
            case '$$typeof':
            case '__esModule':
                {
                    break;
                }
            default:
                {
                    Object.defineProperty(promise, prop, {
                        get () {
                            const expression = (0, _utils.describeStringPropertyAccess)('params', prop);
                            (0, _dynamicrendering.abortAndThrowOnSynchronousDynamicDataAccess)(route, expression, prerenderStore);
                        },
                        set (newValue) {
                            Object.defineProperty(promise, prop, {
                                value: newValue,
                                writable: true,
                                enumerable: true
                            });
                        },
                        enumerable: true,
                        configurable: true
                    });
                }
        }
    });
    return promise;
}
function makeErroringExoticParams(underlyingParams, fallbackParams, workStore, prerenderStore) {
    const cachedParams = CachedParams.get(underlyingParams);
    if (cachedParams) {
        return cachedParams;
    }
    const augmentedUnderlying = {
        ...underlyingParams
    };
    // We don't use makeResolvedReactPromise here because params
    // supports copying with spread and we don't want to unnecessarily
    // instrument the promise with spreadable properties of ReactPromise.
    const promise = Promise.resolve(augmentedUnderlying);
    CachedParams.set(underlyingParams, promise);
    Object.keys(underlyingParams).forEach((prop)=>{
        switch(prop){
            // Object prototype
            case 'hasOwnProperty':
            case 'isPrototypeOf':
            case 'propertyIsEnumerable':
            case 'toString':
            case 'valueOf':
            case 'toLocaleString':
            // Promise prototype
            // fallthrough
            case 'then':
            case 'catch':
            case 'finally':
            // React Promise extension
            // fallthrough
            case 'status':
            // Common tested properties
            // fallthrough
            case 'toJSON':
            case '$$typeof':
            case '__esModule':
                {
                    break;
                }
            default:
                {
                    if (fallbackParams.has(prop)) {
                        Object.defineProperty(augmentedUnderlying, prop, {
                            get () {
                                const expression = (0, _utils.describeStringPropertyAccess)('params', prop);
                                // In most dynamic APIs we also throw if `dynamic = "error"` however
                                // for params is only dynamic when we're generating a fallback shell
                                // and even when `dynamic = "error"` we still support generating dynamic
                                // fallback shells
                                // TODO remove this comment when dynamicIO is the default since there
                                // will be no `dynamic = "error"`
                                if (prerenderStore && prerenderStore.type === 'prerender') {
                                    (0, _dynamicrendering.postponeWithTracking)(workStore.route, expression, prerenderStore.dynamicTracking);
                                } else {
                                    (0, _dynamicrendering.throwToInterruptStaticGeneration)(expression, workStore);
                                }
                            },
                            enumerable: true
                        });
                        Object.defineProperty(promise, prop, {
                            get () {
                                const expression = (0, _utils.describeStringPropertyAccess)('params', prop);
                                // In most dynamic APIs we also throw if `dynamic = "error"` however
                                // for params is only dynamic when we're generating a fallback shell
                                // and even when `dynamic = "error"` we still support generating dynamic
                                // fallback shells
                                // TODO remove this comment when dynamicIO is the default since there
                                // will be no `dynamic = "error"`
                                if (prerenderStore && prerenderStore.type === 'prerender') {
                                    (0, _dynamicrendering.postponeWithTracking)(workStore.route, expression, prerenderStore.dynamicTracking);
                                } else {
                                    (0, _dynamicrendering.throwToInterruptStaticGeneration)(expression, workStore);
                                }
                            },
                            set (newValue) {
                                Object.defineProperty(promise, prop, {
                                    value: newValue,
                                    writable: true,
                                    enumerable: true
                                });
                            },
                            enumerable: true,
                            configurable: true
                        });
                    } else {
                        promise[prop] = underlyingParams[prop];
                    }
                }
        }
    });
    return promise;
}
function makeUntrackedExoticParams(underlyingParams) {
    const cachedParams = CachedParams.get(underlyingParams);
    if (cachedParams) {
        return cachedParams;
    }
    // We don't use makeResolvedReactPromise here because params
    // supports copying with spread and we don't want to unnecessarily
    // instrument the promise with spreadable properties of ReactPromise.
    const promise = Promise.resolve(underlyingParams);
    CachedParams.set(underlyingParams, promise);
    Object.keys(underlyingParams).forEach((prop)=>{
        switch(prop){
            // Object prototype
            case 'hasOwnProperty':
            case 'isPrototypeOf':
            case 'propertyIsEnumerable':
            case 'toString':
            case 'valueOf':
            case 'toLocaleString':
            // Promise prototype
            // fallthrough
            case 'then':
            case 'catch':
            case 'finally':
            // React Promise extension
            // fallthrough
            case 'status':
            // Common tested properties
            // fallthrough
            case 'toJSON':
            case '$$typeof':
            case '__esModule':
                {
                    break;
                }
            default:
                {
                    promise[prop] = underlyingParams[prop];
                }
        }
    });
    return promise;
}
function makeDynamicallyTrackedExoticParamsWithDevWarnings(underlyingParams, store) {
    const cachedParams = CachedParams.get(underlyingParams);
    if (cachedParams) {
        return cachedParams;
    }
    // We don't use makeResolvedReactPromise here because params
    // supports copying with spread and we don't want to unnecessarily
    // instrument the promise with spreadable properties of ReactPromise.
    const promise = Promise.resolve(underlyingParams);
    const proxiedProperties = new Set();
    const unproxiedProperties = [];
    Object.keys(underlyingParams).forEach((prop)=>{
        switch(prop){
            // Object prototype
            case 'hasOwnProperty':
            case 'isPrototypeOf':
            case 'propertyIsEnumerable':
            case 'toString':
            case 'valueOf':
            case 'toLocaleString':
            // Promise prototype
            // fallthrough
            case 'then':
            case 'catch':
            case 'finally':
            // React Promise extension
            // fallthrough
            case 'status':
            // Common tested properties
            // fallthrough
            case 'toJSON':
            case '$$typeof':
            case '__esModule':
                {
                    // These properties cannot be shadowed because they need to be the
                    // true underlying value for Promises to work correctly at runtime
                    unproxiedProperties.push(prop);
                    break;
                }
            default:
                {
                    proxiedProperties.add(prop);
                    promise[prop] = underlyingParams[prop];
                }
        }
    });
    const proxiedPromise = new Proxy(promise, {
        get (target, prop, receiver) {
            if (typeof prop === 'string') {
                if (// We are accessing a property that was proxied to the promise instance
                proxiedProperties.has(prop)) {
                    const expression = (0, _utils.describeStringPropertyAccess)('params', prop);
                    warnForSyncAccess(store.route, expression);
                }
            }
            return _reflect.ReflectAdapter.get(target, prop, receiver);
        },
        set (target, prop, value, receiver) {
            if (typeof prop === 'string') {
                proxiedProperties.delete(prop);
            }
            return _reflect.ReflectAdapter.set(target, prop, value, receiver);
        },
        ownKeys (target) {
            warnForEnumeration(store.route, unproxiedProperties);
            return Reflect.ownKeys(target);
        }
    });
    CachedParams.set(underlyingParams, proxiedPromise);
    return proxiedPromise;
}
const noop = ()=>{};
const warnForSyncAccess = process.env.__NEXT_DISABLE_SYNC_DYNAMIC_API_WARNINGS ? noop : (0, _creatededupedbycallsiteservererrorloger.createDedupedByCallsiteServerErrorLoggerDev)(function getSyncAccessMessage(route, expression) {
    const prefix = route ? ` In route ${route} a ` : 'A ';
    return `${prefix}param property was accessed directly with ${expression}. ` + `\`params\` should be awaited before accessing its properties. ` + `Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis`;
});
const warnForEnumeration = process.env.__NEXT_DISABLE_SYNC_DYNAMIC_API_WARNINGS ? noop : (0, _creatededupedbycallsiteservererrorloger.createDedupedByCallsiteServerErrorLoggerDev)(function getEnumerationMessage(route, missingProperties) {
    const prefix = route ? ` In route ${route} ` : '';
    if (missingProperties.length) {
        const describedMissingProperties = describeListOfPropertyNames(missingProperties);
        return `${prefix}params are being enumerated incompletely missing these properties: ${describedMissingProperties}. ` + `\`params\` should be awaited before accessing its properties. ` + `Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis`;
    } else {
        return `${prefix}params are being enumerated. ` + `\`params\` should be awaited before accessing its properties. ` + `Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis`;
    }
});
function describeListOfPropertyNames(properties) {
    switch(properties.length){
        case 0:
            throw new _invarianterror.InvariantError('Expected describeListOfPropertyNames to be called with a non-empty list of strings.');
        case 1:
            return `\`${properties[0]}\``;
        case 2:
            return `\`${properties[0]}\` and \`${properties[1]}\``;
        default:
            {
                let description = '';
                for(let i = 0; i < properties.length - 1; i++){
                    description += `\`${properties[i]}\`, `;
                }
                description += `, and \`${properties[properties.length - 1]}\``;
                return description;
            }
    }
}

//# sourceMappingURL=params.js.map