287 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			287 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
"use strict";
 | 
						|
Object.defineProperty(exports, "__esModule", {
 | 
						|
    value: true
 | 
						|
});
 | 
						|
Object.defineProperty(exports, "draftMode", {
 | 
						|
    enumerable: true,
 | 
						|
    get: function() {
 | 
						|
        return draftMode;
 | 
						|
    }
 | 
						|
});
 | 
						|
const _workunitasyncstorageexternal = require("../app-render/work-unit-async-storage.external");
 | 
						|
const _workasyncstorageexternal = require("../app-render/work-async-storage.external");
 | 
						|
const _dynamicrendering = require("../app-render/dynamic-rendering");
 | 
						|
const _creatededupedbycallsiteservererrorlogger = require("../create-deduped-by-callsite-server-error-logger");
 | 
						|
const _staticgenerationbailout = require("../../client/components/static-generation-bailout");
 | 
						|
const _hooksservercontext = require("../../client/components/hooks-server-context");
 | 
						|
const _invarianterror = require("../../shared/lib/invariant-error");
 | 
						|
const _reflect = require("../web/spec-extension/adapters/reflect");
 | 
						|
function draftMode() {
 | 
						|
    const callingExpression = 'draftMode';
 | 
						|
    const workStore = _workasyncstorageexternal.workAsyncStorage.getStore();
 | 
						|
    const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
 | 
						|
    if (!workStore || !workUnitStore) {
 | 
						|
        (0, _workunitasyncstorageexternal.throwForMissingRequestStore)(callingExpression);
 | 
						|
    }
 | 
						|
    switch(workUnitStore.type){
 | 
						|
        case 'prerender-runtime':
 | 
						|
            // TODO(runtime-ppr): does it make sense to delay this? normally it's always microtasky
 | 
						|
            return (0, _dynamicrendering.delayUntilRuntimeStage)(workUnitStore, createOrGetCachedDraftMode(workUnitStore.draftMode, workStore));
 | 
						|
        case 'request':
 | 
						|
            return createOrGetCachedDraftMode(workUnitStore.draftMode, workStore);
 | 
						|
        case 'cache':
 | 
						|
        case 'private-cache':
 | 
						|
        case 'unstable-cache':
 | 
						|
            // Inside of `"use cache"` or `unstable_cache`, draft mode is available if
 | 
						|
            // the outmost work unit store is a request store (or a runtime prerender),
 | 
						|
            // and if draft mode is enabled.
 | 
						|
            const draftModeProvider = (0, _workunitasyncstorageexternal.getDraftModeProviderForCacheScope)(workStore, workUnitStore);
 | 
						|
            if (draftModeProvider) {
 | 
						|
                return createOrGetCachedDraftMode(draftModeProvider, workStore);
 | 
						|
            }
 | 
						|
        // Otherwise, we fall through to providing an empty draft mode.
 | 
						|
        // eslint-disable-next-line no-fallthrough
 | 
						|
        case 'prerender':
 | 
						|
        case 'prerender-client':
 | 
						|
        case 'prerender-ppr':
 | 
						|
        case 'prerender-legacy':
 | 
						|
            // Return empty draft mode
 | 
						|
            return createOrGetCachedDraftMode(null, workStore);
 | 
						|
        default:
 | 
						|
            return workUnitStore;
 | 
						|
    }
 | 
						|
}
 | 
						|
function createOrGetCachedDraftMode(draftModeProvider, workStore) {
 | 
						|
    const cacheKey = draftModeProvider ?? NullDraftMode;
 | 
						|
    const cachedDraftMode = CachedDraftModes.get(cacheKey);
 | 
						|
    if (cachedDraftMode) {
 | 
						|
        return cachedDraftMode;
 | 
						|
    }
 | 
						|
    let promise;
 | 
						|
    if (process.env.NODE_ENV === 'development' && !(workStore == null ? void 0 : workStore.isPrefetchRequest)) {
 | 
						|
        const route = workStore == null ? void 0 : workStore.route;
 | 
						|
        if (process.env.__NEXT_CACHE_COMPONENTS) {
 | 
						|
            return createDraftModeWithDevWarnings(draftModeProvider, route);
 | 
						|
        }
 | 
						|
        promise = createExoticDraftModeWithDevWarnings(draftModeProvider, route);
 | 
						|
    } else {
 | 
						|
        if (process.env.__NEXT_CACHE_COMPONENTS) {
 | 
						|
            return Promise.resolve(new DraftMode(draftModeProvider));
 | 
						|
        }
 | 
						|
        promise = createExoticDraftMode(draftModeProvider);
 | 
						|
    }
 | 
						|
    CachedDraftModes.set(cacheKey, promise);
 | 
						|
    return promise;
 | 
						|
}
 | 
						|
const NullDraftMode = {};
 | 
						|
const CachedDraftModes = new WeakMap();
 | 
						|
function createExoticDraftMode(underlyingProvider) {
 | 
						|
    const instance = new DraftMode(underlyingProvider);
 | 
						|
    const promise = Promise.resolve(instance);
 | 
						|
    Object.defineProperty(promise, 'isEnabled', {
 | 
						|
        get () {
 | 
						|
            return instance.isEnabled;
 | 
						|
        },
 | 
						|
        enumerable: true,
 | 
						|
        configurable: true
 | 
						|
    });
 | 
						|
    promise.enable = instance.enable.bind(instance);
 | 
						|
    promise.disable = instance.disable.bind(instance);
 | 
						|
    return promise;
 | 
						|
}
 | 
						|
function createExoticDraftModeWithDevWarnings(underlyingProvider, route) {
 | 
						|
    const instance = new DraftMode(underlyingProvider);
 | 
						|
    const promise = Promise.resolve(instance);
 | 
						|
    Object.defineProperty(promise, 'isEnabled', {
 | 
						|
        get () {
 | 
						|
            const expression = '`draftMode().isEnabled`';
 | 
						|
            syncIODev(route, expression);
 | 
						|
            return instance.isEnabled;
 | 
						|
        },
 | 
						|
        enumerable: true,
 | 
						|
        configurable: true
 | 
						|
    });
 | 
						|
    Object.defineProperty(promise, 'enable', {
 | 
						|
        value: function get() {
 | 
						|
            const expression = '`draftMode().enable()`';
 | 
						|
            syncIODev(route, expression);
 | 
						|
            return instance.enable.apply(instance, arguments);
 | 
						|
        }
 | 
						|
    });
 | 
						|
    Object.defineProperty(promise, 'disable', {
 | 
						|
        value: function get() {
 | 
						|
            const expression = '`draftMode().disable()`';
 | 
						|
            syncIODev(route, expression);
 | 
						|
            return instance.disable.apply(instance, arguments);
 | 
						|
        }
 | 
						|
    });
 | 
						|
    return promise;
 | 
						|
}
 | 
						|
// Similar to `createExoticDraftModeWithDevWarnings`, but just logging the sync
 | 
						|
// access without actually defining the draftMode properties on the promise.
 | 
						|
function createDraftModeWithDevWarnings(underlyingProvider, route) {
 | 
						|
    const instance = new DraftMode(underlyingProvider);
 | 
						|
    const promise = Promise.resolve(instance);
 | 
						|
    const proxiedPromise = new Proxy(promise, {
 | 
						|
        get (target, prop, receiver) {
 | 
						|
            switch(prop){
 | 
						|
                case 'isEnabled':
 | 
						|
                    warnForSyncAccess(route, `\`draftMode().${prop}\``);
 | 
						|
                    break;
 | 
						|
                case 'enable':
 | 
						|
                case 'disable':
 | 
						|
                    {
 | 
						|
                        warnForSyncAccess(route, `\`draftMode().${prop}()\``);
 | 
						|
                        break;
 | 
						|
                    }
 | 
						|
                default:
 | 
						|
                    {
 | 
						|
                    // We only warn for well-defined properties of the draftMode object.
 | 
						|
                    }
 | 
						|
            }
 | 
						|
            return _reflect.ReflectAdapter.get(target, prop, receiver);
 | 
						|
        }
 | 
						|
    });
 | 
						|
    return proxiedPromise;
 | 
						|
}
 | 
						|
class DraftMode {
 | 
						|
    constructor(provider){
 | 
						|
        this._provider = provider;
 | 
						|
    }
 | 
						|
    get isEnabled() {
 | 
						|
        if (this._provider !== null) {
 | 
						|
            return this._provider.isEnabled;
 | 
						|
        }
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
    enable() {
 | 
						|
        // We have a store we want to track dynamic data access to ensure we
 | 
						|
        // don't statically generate routes that manipulate draft mode.
 | 
						|
        trackDynamicDraftMode('draftMode().enable()', this.enable);
 | 
						|
        if (this._provider !== null) {
 | 
						|
            this._provider.enable();
 | 
						|
        }
 | 
						|
    }
 | 
						|
    disable() {
 | 
						|
        trackDynamicDraftMode('draftMode().disable()', this.disable);
 | 
						|
        if (this._provider !== null) {
 | 
						|
            this._provider.disable();
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
function syncIODev(route, expression) {
 | 
						|
    const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
 | 
						|
    if (workUnitStore) {
 | 
						|
        switch(workUnitStore.type){
 | 
						|
            case 'request':
 | 
						|
                if (workUnitStore.prerenderPhase === true) {
 | 
						|
                    // When we're rendering dynamically in dev, we need to advance out of
 | 
						|
                    // the Prerender environment when we read Request data synchronously.
 | 
						|
                    (0, _dynamicrendering.trackSynchronousRequestDataAccessInDev)(workUnitStore);
 | 
						|
                }
 | 
						|
                break;
 | 
						|
            case 'prerender':
 | 
						|
            case 'prerender-client':
 | 
						|
            case 'prerender-runtime':
 | 
						|
            case 'prerender-ppr':
 | 
						|
            case 'prerender-legacy':
 | 
						|
            case 'cache':
 | 
						|
            case 'private-cache':
 | 
						|
            case 'unstable-cache':
 | 
						|
                break;
 | 
						|
            default:
 | 
						|
                workUnitStore;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    // In all cases we warn normally
 | 
						|
    warnForSyncAccess(route, expression);
 | 
						|
}
 | 
						|
const warnForSyncAccess = (0, _creatededupedbycallsiteservererrorlogger.createDedupedByCallsiteServerErrorLoggerDev)(createDraftModeAccessError);
 | 
						|
function createDraftModeAccessError(route, expression) {
 | 
						|
    const prefix = route ? `Route "${route}" ` : 'This route ';
 | 
						|
    return Object.defineProperty(new Error(`${prefix}used ${expression}. ` + `\`draftMode()\` should be awaited before using its value. ` + `Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis`), "__NEXT_ERROR_CODE", {
 | 
						|
        value: "E377",
 | 
						|
        enumerable: false,
 | 
						|
        configurable: true
 | 
						|
    });
 | 
						|
}
 | 
						|
function trackDynamicDraftMode(expression, constructorOpt) {
 | 
						|
    const workStore = _workasyncstorageexternal.workAsyncStorage.getStore();
 | 
						|
    const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
 | 
						|
    if (workStore) {
 | 
						|
        // We have a store we want to track dynamic data access to ensure we
 | 
						|
        // don't statically generate routes that manipulate draft mode.
 | 
						|
        if ((workUnitStore == null ? void 0 : workUnitStore.phase) === 'after') {
 | 
						|
            throw Object.defineProperty(new Error(`Route ${workStore.route} used "${expression}" inside \`after\`. The enabled status of draftMode can be read inside \`after\` but you cannot enable or disable draftMode. See more info here: https://nextjs.org/docs/app/api-reference/functions/after`), "__NEXT_ERROR_CODE", {
 | 
						|
                value: "E348",
 | 
						|
                enumerable: false,
 | 
						|
                configurable: true
 | 
						|
            });
 | 
						|
        }
 | 
						|
        if (workStore.dynamicShouldError) {
 | 
						|
            throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route ${workStore.route} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`), "__NEXT_ERROR_CODE", {
 | 
						|
                value: "E553",
 | 
						|
                enumerable: false,
 | 
						|
                configurable: true
 | 
						|
            });
 | 
						|
        }
 | 
						|
        if (workUnitStore) {
 | 
						|
            switch(workUnitStore.type){
 | 
						|
                case 'cache':
 | 
						|
                case 'private-cache':
 | 
						|
                    {
 | 
						|
                        const error = Object.defineProperty(new Error(`Route ${workStore.route} used "${expression}" inside "use cache". The enabled status of draftMode can be read in caches but you must not enable or disable draftMode inside a cache. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache`), "__NEXT_ERROR_CODE", {
 | 
						|
                            value: "E246",
 | 
						|
                            enumerable: false,
 | 
						|
                            configurable: true
 | 
						|
                        });
 | 
						|
                        Error.captureStackTrace(error, constructorOpt);
 | 
						|
                        workStore.invalidDynamicUsageError ??= error;
 | 
						|
                        throw error;
 | 
						|
                    }
 | 
						|
                case 'unstable-cache':
 | 
						|
                    throw Object.defineProperty(new Error(`Route ${workStore.route} used "${expression}" inside a function cached with "unstable_cache(...)". The enabled status of draftMode can be read in caches but you must not enable or disable draftMode inside a cache. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`), "__NEXT_ERROR_CODE", {
 | 
						|
                        value: "E259",
 | 
						|
                        enumerable: false,
 | 
						|
                        configurable: true
 | 
						|
                    });
 | 
						|
                case 'prerender':
 | 
						|
                case 'prerender-runtime':
 | 
						|
                    {
 | 
						|
                        const error = Object.defineProperty(new Error(`Route ${workStore.route} used ${expression} without first calling \`await connection()\`. See more info here: https://nextjs.org/docs/messages/next-prerender-sync-headers`), "__NEXT_ERROR_CODE", {
 | 
						|
                            value: "E126",
 | 
						|
                            enumerable: false,
 | 
						|
                            configurable: true
 | 
						|
                        });
 | 
						|
                        return (0, _dynamicrendering.abortAndThrowOnSynchronousRequestDataAccess)(workStore.route, expression, error, workUnitStore);
 | 
						|
                    }
 | 
						|
                case 'prerender-client':
 | 
						|
                    const exportName = '`draftMode`';
 | 
						|
                    throw Object.defineProperty(new _invarianterror.InvariantError(`${exportName} must not be used within a client component. Next.js should be preventing ${exportName} from being included in client components statically, but did not in this case.`), "__NEXT_ERROR_CODE", {
 | 
						|
                        value: "E693",
 | 
						|
                        enumerable: false,
 | 
						|
                        configurable: true
 | 
						|
                    });
 | 
						|
                case 'prerender-ppr':
 | 
						|
                    return (0, _dynamicrendering.postponeWithTracking)(workStore.route, expression, workUnitStore.dynamicTracking);
 | 
						|
                case 'prerender-legacy':
 | 
						|
                    workUnitStore.revalidate = 0;
 | 
						|
                    const err = Object.defineProperty(new _hooksservercontext.DynamicServerError(`Route ${workStore.route} couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`), "__NEXT_ERROR_CODE", {
 | 
						|
                        value: "E558",
 | 
						|
                        enumerable: false,
 | 
						|
                        configurable: true
 | 
						|
                    });
 | 
						|
                    workStore.dynamicUsageDescription = expression;
 | 
						|
                    workStore.dynamicUsageStack = err.stack;
 | 
						|
                    throw err;
 | 
						|
                case 'request':
 | 
						|
                    (0, _dynamicrendering.trackDynamicDataInDynamicRender)(workUnitStore);
 | 
						|
                    break;
 | 
						|
                default:
 | 
						|
                    workUnitStore;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//# sourceMappingURL=draft-mode.js.map
 |