vinext 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/build/static-export.d.ts +78 -0
- package/dist/build/static-export.d.ts.map +1 -0
- package/dist/build/static-export.js +553 -0
- package/dist/build/static-export.js.map +1 -0
- package/dist/check.d.ts +52 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +483 -0
- package/dist/check.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +565 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/entry.d.ts +2 -0
- package/dist/client/entry.d.ts.map +1 -0
- package/dist/client/entry.js +85 -0
- package/dist/client/entry.js.map +1 -0
- package/dist/cloudflare/index.d.ts +8 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +8 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/cloudflare/kv-cache-handler.d.ts +68 -0
- package/dist/cloudflare/kv-cache-handler.d.ts.map +1 -0
- package/dist/cloudflare/kv-cache-handler.js +304 -0
- package/dist/cloudflare/kv-cache-handler.js.map +1 -0
- package/dist/cloudflare/tpr.d.ts +78 -0
- package/dist/cloudflare/tpr.d.ts.map +1 -0
- package/dist/cloudflare/tpr.js +672 -0
- package/dist/cloudflare/tpr.js.map +1 -0
- package/dist/config/config-matchers.d.ts +106 -0
- package/dist/config/config-matchers.d.ts.map +1 -0
- package/dist/config/config-matchers.js +499 -0
- package/dist/config/config-matchers.js.map +1 -0
- package/dist/config/next-config.d.ts +153 -0
- package/dist/config/next-config.d.ts.map +1 -0
- package/dist/config/next-config.js +274 -0
- package/dist/config/next-config.js.map +1 -0
- package/dist/deploy.d.ts +87 -0
- package/dist/deploy.d.ts.map +1 -0
- package/dist/deploy.js +644 -0
- package/dist/deploy.js.map +1 -0
- package/dist/index.d.ts +156 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3287 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +55 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +201 -0
- package/dist/init.js.map +1 -0
- package/dist/routing/app-router.d.ts +96 -0
- package/dist/routing/app-router.d.ts.map +1 -0
- package/dist/routing/app-router.js +815 -0
- package/dist/routing/app-router.js.map +1 -0
- package/dist/routing/pages-router.d.ts +52 -0
- package/dist/routing/pages-router.d.ts.map +1 -0
- package/dist/routing/pages-router.js +239 -0
- package/dist/routing/pages-router.js.map +1 -0
- package/dist/server/api-handler.d.ts +18 -0
- package/dist/server/api-handler.d.ts.map +1 -0
- package/dist/server/api-handler.js +169 -0
- package/dist/server/api-handler.js.map +1 -0
- package/dist/server/app-dev-server.d.ts +42 -0
- package/dist/server/app-dev-server.d.ts.map +1 -0
- package/dist/server/app-dev-server.js +2718 -0
- package/dist/server/app-dev-server.js.map +1 -0
- package/dist/server/app-router-entry.d.ts +18 -0
- package/dist/server/app-router-entry.d.ts.map +1 -0
- package/dist/server/app-router-entry.js +34 -0
- package/dist/server/app-router-entry.js.map +1 -0
- package/dist/server/dev-server.d.ts +40 -0
- package/dist/server/dev-server.d.ts.map +1 -0
- package/dist/server/dev-server.js +758 -0
- package/dist/server/dev-server.js.map +1 -0
- package/dist/server/html.d.ts +22 -0
- package/dist/server/html.d.ts.map +1 -0
- package/dist/server/html.js +29 -0
- package/dist/server/html.js.map +1 -0
- package/dist/server/image-optimization.d.ts +56 -0
- package/dist/server/image-optimization.d.ts.map +1 -0
- package/dist/server/image-optimization.js +103 -0
- package/dist/server/image-optimization.js.map +1 -0
- package/dist/server/instrumentation.d.ts +68 -0
- package/dist/server/instrumentation.d.ts.map +1 -0
- package/dist/server/instrumentation.js +90 -0
- package/dist/server/instrumentation.js.map +1 -0
- package/dist/server/isr-cache.d.ts +61 -0
- package/dist/server/isr-cache.d.ts.map +1 -0
- package/dist/server/isr-cache.js +134 -0
- package/dist/server/isr-cache.js.map +1 -0
- package/dist/server/metadata-routes.d.ts +103 -0
- package/dist/server/metadata-routes.d.ts.map +1 -0
- package/dist/server/metadata-routes.js +270 -0
- package/dist/server/metadata-routes.js.map +1 -0
- package/dist/server/middleware.d.ts +77 -0
- package/dist/server/middleware.d.ts.map +1 -0
- package/dist/server/middleware.js +228 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/prod-server.d.ts +78 -0
- package/dist/server/prod-server.d.ts.map +1 -0
- package/dist/server/prod-server.js +712 -0
- package/dist/server/prod-server.js.map +1 -0
- package/dist/shims/amp.d.ts +17 -0
- package/dist/shims/amp.d.ts.map +1 -0
- package/dist/shims/amp.js +21 -0
- package/dist/shims/amp.js.map +1 -0
- package/dist/shims/app.d.ts +12 -0
- package/dist/shims/app.d.ts.map +1 -0
- package/dist/shims/app.js +2 -0
- package/dist/shims/app.js.map +1 -0
- package/dist/shims/cache-runtime.d.ts +68 -0
- package/dist/shims/cache-runtime.d.ts.map +1 -0
- package/dist/shims/cache-runtime.js +437 -0
- package/dist/shims/cache-runtime.js.map +1 -0
- package/dist/shims/cache.d.ts +243 -0
- package/dist/shims/cache.d.ts.map +1 -0
- package/dist/shims/cache.js +415 -0
- package/dist/shims/cache.js.map +1 -0
- package/dist/shims/client-only.d.ts +18 -0
- package/dist/shims/client-only.d.ts.map +1 -0
- package/dist/shims/client-only.js +18 -0
- package/dist/shims/client-only.js.map +1 -0
- package/dist/shims/config.d.ts +27 -0
- package/dist/shims/config.d.ts.map +1 -0
- package/dist/shims/config.js +30 -0
- package/dist/shims/config.js.map +1 -0
- package/dist/shims/constants.d.ts +13 -0
- package/dist/shims/constants.d.ts.map +1 -0
- package/dist/shims/constants.js +13 -0
- package/dist/shims/constants.js.map +1 -0
- package/dist/shims/document.d.ts +33 -0
- package/dist/shims/document.d.ts.map +1 -0
- package/dist/shims/document.js +32 -0
- package/dist/shims/document.js.map +1 -0
- package/dist/shims/dynamic.d.ts +33 -0
- package/dist/shims/dynamic.d.ts.map +1 -0
- package/dist/shims/dynamic.js +148 -0
- package/dist/shims/dynamic.js.map +1 -0
- package/dist/shims/error-boundary.d.ts +33 -0
- package/dist/shims/error-boundary.d.ts.map +1 -0
- package/dist/shims/error-boundary.js +88 -0
- package/dist/shims/error-boundary.js.map +1 -0
- package/dist/shims/error.d.ts +16 -0
- package/dist/shims/error.d.ts.map +1 -0
- package/dist/shims/error.js +45 -0
- package/dist/shims/error.js.map +1 -0
- package/dist/shims/fetch-cache.d.ts +61 -0
- package/dist/shims/fetch-cache.d.ts.map +1 -0
- package/dist/shims/fetch-cache.js +307 -0
- package/dist/shims/fetch-cache.js.map +1 -0
- package/dist/shims/font-google.d.ts +122 -0
- package/dist/shims/font-google.d.ts.map +1 -0
- package/dist/shims/font-google.js +387 -0
- package/dist/shims/font-google.js.map +1 -0
- package/dist/shims/font-local.d.ts +61 -0
- package/dist/shims/font-local.d.ts.map +1 -0
- package/dist/shims/font-local.js +303 -0
- package/dist/shims/font-local.js.map +1 -0
- package/dist/shims/form.d.ts +30 -0
- package/dist/shims/form.d.ts.map +1 -0
- package/dist/shims/form.js +78 -0
- package/dist/shims/form.js.map +1 -0
- package/dist/shims/head-state.d.ts +11 -0
- package/dist/shims/head-state.d.ts.map +1 -0
- package/dist/shims/head-state.js +47 -0
- package/dist/shims/head-state.js.map +1 -0
- package/dist/shims/head.d.ts +28 -0
- package/dist/shims/head.d.ts.map +1 -0
- package/dist/shims/head.js +148 -0
- package/dist/shims/head.js.map +1 -0
- package/dist/shims/headers.d.ts +150 -0
- package/dist/shims/headers.d.ts.map +1 -0
- package/dist/shims/headers.js +412 -0
- package/dist/shims/headers.js.map +1 -0
- package/dist/shims/image-config.d.ts +30 -0
- package/dist/shims/image-config.d.ts.map +1 -0
- package/dist/shims/image-config.js +91 -0
- package/dist/shims/image-config.js.map +1 -0
- package/dist/shims/image.d.ts +63 -0
- package/dist/shims/image.d.ts.map +1 -0
- package/dist/shims/image.js +284 -0
- package/dist/shims/image.js.map +1 -0
- package/dist/shims/internal/api-utils.d.ts +12 -0
- package/dist/shims/internal/api-utils.d.ts.map +1 -0
- package/dist/shims/internal/api-utils.js +7 -0
- package/dist/shims/internal/api-utils.js.map +1 -0
- package/dist/shims/internal/app-router-context.d.ts +21 -0
- package/dist/shims/internal/app-router-context.d.ts.map +1 -0
- package/dist/shims/internal/app-router-context.js +15 -0
- package/dist/shims/internal/app-router-context.js.map +1 -0
- package/dist/shims/internal/cookies.d.ts +9 -0
- package/dist/shims/internal/cookies.d.ts.map +1 -0
- package/dist/shims/internal/cookies.js +9 -0
- package/dist/shims/internal/cookies.js.map +1 -0
- package/dist/shims/internal/router-context.d.ts +2 -0
- package/dist/shims/internal/router-context.d.ts.map +1 -0
- package/dist/shims/internal/router-context.js +9 -0
- package/dist/shims/internal/router-context.js.map +1 -0
- package/dist/shims/internal/utils.d.ts +48 -0
- package/dist/shims/internal/utils.d.ts.map +1 -0
- package/dist/shims/internal/utils.js +35 -0
- package/dist/shims/internal/utils.js.map +1 -0
- package/dist/shims/internal/work-unit-async-storage.d.ts +12 -0
- package/dist/shims/internal/work-unit-async-storage.d.ts.map +1 -0
- package/dist/shims/internal/work-unit-async-storage.js +13 -0
- package/dist/shims/internal/work-unit-async-storage.js.map +1 -0
- package/dist/shims/layout-segment-context.d.ts +21 -0
- package/dist/shims/layout-segment-context.d.ts.map +1 -0
- package/dist/shims/layout-segment-context.js +27 -0
- package/dist/shims/layout-segment-context.js.map +1 -0
- package/dist/shims/legacy-image.d.ts +52 -0
- package/dist/shims/legacy-image.d.ts.map +1 -0
- package/dist/shims/legacy-image.js +46 -0
- package/dist/shims/legacy-image.js.map +1 -0
- package/dist/shims/link.d.ts +48 -0
- package/dist/shims/link.d.ts.map +1 -0
- package/dist/shims/link.js +395 -0
- package/dist/shims/link.js.map +1 -0
- package/dist/shims/metadata.d.ts +184 -0
- package/dist/shims/metadata.d.ts.map +1 -0
- package/dist/shims/metadata.js +472 -0
- package/dist/shims/metadata.js.map +1 -0
- package/dist/shims/navigation-state.d.ts +14 -0
- package/dist/shims/navigation-state.d.ts.map +1 -0
- package/dist/shims/navigation-state.js +77 -0
- package/dist/shims/navigation-state.js.map +1 -0
- package/dist/shims/navigation.d.ts +201 -0
- package/dist/shims/navigation.d.ts.map +1 -0
- package/dist/shims/navigation.js +672 -0
- package/dist/shims/navigation.js.map +1 -0
- package/dist/shims/og.d.ts +20 -0
- package/dist/shims/og.d.ts.map +1 -0
- package/dist/shims/og.js +19 -0
- package/dist/shims/og.js.map +1 -0
- package/dist/shims/router-state.d.ts +11 -0
- package/dist/shims/router-state.d.ts.map +1 -0
- package/dist/shims/router-state.js +56 -0
- package/dist/shims/router-state.js.map +1 -0
- package/dist/shims/router.d.ts +103 -0
- package/dist/shims/router.d.ts.map +1 -0
- package/dist/shims/router.js +536 -0
- package/dist/shims/router.js.map +1 -0
- package/dist/shims/script.d.ts +58 -0
- package/dist/shims/script.d.ts.map +1 -0
- package/dist/shims/script.js +163 -0
- package/dist/shims/script.js.map +1 -0
- package/dist/shims/server-only.d.ts +19 -0
- package/dist/shims/server-only.d.ts.map +1 -0
- package/dist/shims/server-only.js +19 -0
- package/dist/shims/server-only.js.map +1 -0
- package/dist/shims/server.d.ts +178 -0
- package/dist/shims/server.d.ts.map +1 -0
- package/dist/shims/server.js +377 -0
- package/dist/shims/server.js.map +1 -0
- package/dist/shims/web-vitals.d.ts +24 -0
- package/dist/shims/web-vitals.d.ts.map +1 -0
- package/dist/shims/web-vitals.js +17 -0
- package/dist/shims/web-vitals.js.map +1 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +20 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/project.d.ts +36 -0
- package/dist/utils/project.d.ts.map +1 -0
- package/dist/utils/project.js +112 -0
- package/dist/utils/project.js.map +1 -0
- package/dist/utils/query.d.ts +10 -0
- package/dist/utils/query.d.ts.map +1 -0
- package/dist/utils/query.js +27 -0
- package/dist/utils/query.js.map +1 -0
- package/package.json +65 -7
- package/index.js +0 -1
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* next/headers shim
|
|
3
|
+
*
|
|
4
|
+
* Provides cookies() and headers() functions for App Router Server Components.
|
|
5
|
+
* These read from a request context set by the RSC handler before rendering.
|
|
6
|
+
*
|
|
7
|
+
* In Next.js 15+, cookies() and headers() return Promises (async).
|
|
8
|
+
* We support both the sync (legacy) and async patterns.
|
|
9
|
+
*/
|
|
10
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
11
|
+
// NOTE:
|
|
12
|
+
// - This shim can be loaded under multiple module specifiers in Vite's
|
|
13
|
+
// multi-environment setup (RSC/SSR). Store the AsyncLocalStorage on
|
|
14
|
+
// globalThis so `connection()` (next/server) and `consumeDynamicUsage()`
|
|
15
|
+
// (next/headers) always share it.
|
|
16
|
+
// - We use AsyncLocalStorage so concurrent requests don't stomp each other's
|
|
17
|
+
// headers/cookies/dynamic-usage state.
|
|
18
|
+
const _ALS_KEY = Symbol.for("vinext.nextHeadersShim.als");
|
|
19
|
+
const _FALLBACK_KEY = Symbol.for("vinext.nextHeadersShim.fallback");
|
|
20
|
+
const _g = globalThis;
|
|
21
|
+
const _als = (_g[_ALS_KEY] ??= new AsyncLocalStorage());
|
|
22
|
+
const _fallbackState = (_g[_FALLBACK_KEY] ??= {
|
|
23
|
+
headersContext: null,
|
|
24
|
+
dynamicUsageDetected: false,
|
|
25
|
+
pendingSetCookies: [],
|
|
26
|
+
draftModeCookieHeader: null,
|
|
27
|
+
});
|
|
28
|
+
function _enterWith(state) {
|
|
29
|
+
// Some non-Node runtimes/polyfills provide AsyncLocalStorage but not enterWith().
|
|
30
|
+
const enterWith = _als.enterWith;
|
|
31
|
+
if (typeof enterWith === "function") {
|
|
32
|
+
try {
|
|
33
|
+
enterWith.call(_als, state);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Fall through to best-effort fallback.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Best-effort fallback: global state (not concurrency-safe).
|
|
41
|
+
_fallbackState.headersContext = state.headersContext;
|
|
42
|
+
_fallbackState.dynamicUsageDetected = state.dynamicUsageDetected;
|
|
43
|
+
_fallbackState.pendingSetCookies = state.pendingSetCookies;
|
|
44
|
+
_fallbackState.draftModeCookieHeader = state.draftModeCookieHeader;
|
|
45
|
+
}
|
|
46
|
+
function _getState() {
|
|
47
|
+
const state = _als.getStore();
|
|
48
|
+
return state ?? _fallbackState;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Dynamic usage flag — set when a component calls connection(), cookies(),
|
|
52
|
+
* headers(), or noStore() during rendering. When true, ISR caching is
|
|
53
|
+
* bypassed and the response gets Cache-Control: no-store.
|
|
54
|
+
*/
|
|
55
|
+
// (stored on _state)
|
|
56
|
+
/**
|
|
57
|
+
* Mark the current render as requiring dynamic (uncached) rendering.
|
|
58
|
+
* Called by connection(), cookies(), headers(), and noStore().
|
|
59
|
+
*/
|
|
60
|
+
export function markDynamicUsage() {
|
|
61
|
+
_getState().dynamicUsageDetected = true;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check and reset the dynamic usage flag.
|
|
65
|
+
* Called by the server after rendering to decide on caching.
|
|
66
|
+
*/
|
|
67
|
+
export function consumeDynamicUsage() {
|
|
68
|
+
const state = _getState();
|
|
69
|
+
const used = state.dynamicUsageDetected;
|
|
70
|
+
state.dynamicUsageDetected = false;
|
|
71
|
+
return used;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Set the headers/cookies context for the current RSC render.
|
|
75
|
+
* Called by the framework's RSC entry before rendering each request.
|
|
76
|
+
*
|
|
77
|
+
* NOTE: This uses enterWith() which only works reliably within the same
|
|
78
|
+
* synchronous call stack. For full async context propagation (needed for
|
|
79
|
+
* RSC streaming), use runWithHeadersContext() instead.
|
|
80
|
+
*/
|
|
81
|
+
export function setHeadersContext(ctx) {
|
|
82
|
+
// Start of request: enter a fresh per-request store.
|
|
83
|
+
if (ctx !== null) {
|
|
84
|
+
_enterWith({
|
|
85
|
+
headersContext: ctx,
|
|
86
|
+
dynamicUsageDetected: false,
|
|
87
|
+
pendingSetCookies: [],
|
|
88
|
+
draftModeCookieHeader: null,
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// End of request cleanup: keep the store (so consumeDynamicUsage and
|
|
93
|
+
// cookie flushing can still run), but clear the request headers/cookies.
|
|
94
|
+
const state = _als.getStore();
|
|
95
|
+
if (state) {
|
|
96
|
+
state.headersContext = null;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
_fallbackState.headersContext = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Run a function with headers context, ensuring the context propagates
|
|
104
|
+
* through all async operations (including RSC streaming).
|
|
105
|
+
*
|
|
106
|
+
* IMPORTANT: RSC rendering is streaming - renderToReadableStream() returns
|
|
107
|
+
* immediately but component execution happens later when the stream is consumed.
|
|
108
|
+
* AsyncLocalStorage.run() only maintains context within the callback scope,
|
|
109
|
+
* so by the time components actually render, we'd be outside that scope.
|
|
110
|
+
*
|
|
111
|
+
* Solution: We use enterWith() to set persistent context AND update the
|
|
112
|
+
* fallback state. This way, even after run() returns, getStore() still
|
|
113
|
+
* returns the right state (via enterWith), and if that fails, we have
|
|
114
|
+
* the fallback. For single-request-at-a-time scenarios (dev mode), this
|
|
115
|
+
* works correctly. For concurrent requests, the ALS should work.
|
|
116
|
+
*/
|
|
117
|
+
export function runWithHeadersContext(ctx, fn) {
|
|
118
|
+
const state = {
|
|
119
|
+
headersContext: ctx,
|
|
120
|
+
dynamicUsageDetected: false,
|
|
121
|
+
pendingSetCookies: [],
|
|
122
|
+
draftModeCookieHeader: null,
|
|
123
|
+
};
|
|
124
|
+
// Use enterWith to set persistent context for this async context
|
|
125
|
+
_enterWith(state);
|
|
126
|
+
// Also update fallback state directly for environments where ALS doesn't
|
|
127
|
+
// propagate correctly (this is not concurrency-safe but works for dev)
|
|
128
|
+
_fallbackState.headersContext = ctx;
|
|
129
|
+
_fallbackState.dynamicUsageDetected = false;
|
|
130
|
+
_fallbackState.pendingSetCookies = [];
|
|
131
|
+
_fallbackState.draftModeCookieHeader = null;
|
|
132
|
+
return fn();
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Apply middleware-forwarded request headers to the current headers context.
|
|
136
|
+
*
|
|
137
|
+
* When Next.js middleware calls `NextResponse.next({ request: { headers } })`,
|
|
138
|
+
* the modified headers are encoded as `x-middleware-request-<name>` on the
|
|
139
|
+
* middleware response. This function unpacks those prefixed headers and
|
|
140
|
+
* replaces the corresponding entries on the live `HeadersContext` so that
|
|
141
|
+
* subsequent calls to `headers()` / `cookies()` see the middleware changes.
|
|
142
|
+
*/
|
|
143
|
+
export function applyMiddlewareRequestHeaders(middlewareResponseHeaders) {
|
|
144
|
+
const state = _getState();
|
|
145
|
+
if (!state.headersContext)
|
|
146
|
+
return;
|
|
147
|
+
const ctx = state.headersContext;
|
|
148
|
+
const PREFIX = "x-middleware-request-";
|
|
149
|
+
for (const [key, value] of middlewareResponseHeaders) {
|
|
150
|
+
if (key.startsWith(PREFIX)) {
|
|
151
|
+
const realName = key.slice(PREFIX.length);
|
|
152
|
+
ctx.headers.set(realName, value);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// If middleware modified the cookie header, rebuild the cookies map.
|
|
156
|
+
const newCookieHeader = ctx.headers.get("cookie");
|
|
157
|
+
if (newCookieHeader !== null) {
|
|
158
|
+
ctx.cookies.clear();
|
|
159
|
+
for (const part of newCookieHeader.split(";")) {
|
|
160
|
+
const [k, ...rest] = part.split("=");
|
|
161
|
+
if (k) {
|
|
162
|
+
ctx.cookies.set(k.trim(), rest.join("=").trim());
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Create a HeadersContext from a standard Request object.
|
|
169
|
+
*/
|
|
170
|
+
export function headersContextFromRequest(request) {
|
|
171
|
+
const cookies = new Map();
|
|
172
|
+
const cookieHeader = request.headers.get("cookie") || "";
|
|
173
|
+
for (const part of cookieHeader.split(";")) {
|
|
174
|
+
const [key, ...rest] = part.split("=");
|
|
175
|
+
if (key) {
|
|
176
|
+
cookies.set(key.trim(), rest.join("=").trim());
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
headers: request.headers,
|
|
181
|
+
cookies,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// Public API
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
/**
|
|
188
|
+
* Read-only Headers instance from the incoming request.
|
|
189
|
+
* Returns a Promise in Next.js 15+ style (but resolves synchronously since
|
|
190
|
+
* the context is already available).
|
|
191
|
+
*/
|
|
192
|
+
export async function headers() {
|
|
193
|
+
const state = _getState();
|
|
194
|
+
if (!state.headersContext) {
|
|
195
|
+
throw new Error("headers() can only be called from a Server Component, Route Handler, " +
|
|
196
|
+
"or Server Action. Make sure you're not calling it from a Client Component.");
|
|
197
|
+
}
|
|
198
|
+
markDynamicUsage();
|
|
199
|
+
return state.headersContext.headers;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Cookie jar from the incoming request.
|
|
203
|
+
* Returns a ReadonlyRequestCookies-like object.
|
|
204
|
+
*/
|
|
205
|
+
export async function cookies() {
|
|
206
|
+
const state = _getState();
|
|
207
|
+
if (!state.headersContext) {
|
|
208
|
+
throw new Error("cookies() can only be called from a Server Component, Route Handler, " +
|
|
209
|
+
"or Server Action.");
|
|
210
|
+
}
|
|
211
|
+
markDynamicUsage();
|
|
212
|
+
return new RequestCookies(state.headersContext.cookies);
|
|
213
|
+
}
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
// Writable cookie accumulator for Route Handlers / Server Actions
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
/** Accumulated Set-Cookie headers from cookies().set() / .delete() calls */
|
|
218
|
+
// (stored on _state)
|
|
219
|
+
/**
|
|
220
|
+
* Get and clear all pending Set-Cookie headers generated by cookies().set()/delete().
|
|
221
|
+
* Called by the framework after rendering to attach headers to the response.
|
|
222
|
+
*/
|
|
223
|
+
export function getAndClearPendingCookies() {
|
|
224
|
+
const state = _getState();
|
|
225
|
+
const cookies = state.pendingSetCookies;
|
|
226
|
+
state.pendingSetCookies = [];
|
|
227
|
+
return cookies;
|
|
228
|
+
}
|
|
229
|
+
// Draft mode cookie name (matches Next.js convention)
|
|
230
|
+
const DRAFT_MODE_COOKIE = "__prerender_bypass";
|
|
231
|
+
// Draft mode secret — generated once at build time via Vite `define` so the
|
|
232
|
+
// __prerender_bypass cookie is consistent across all server instances (e.g.
|
|
233
|
+
// multiple Cloudflare Workers isolates).
|
|
234
|
+
function getDraftSecret() {
|
|
235
|
+
const secret = process.env.__VINEXT_DRAFT_SECRET;
|
|
236
|
+
if (!secret) {
|
|
237
|
+
throw new Error("[vinext] __VINEXT_DRAFT_SECRET is not defined. " +
|
|
238
|
+
"This should be set by the Vite plugin at build time.");
|
|
239
|
+
}
|
|
240
|
+
return secret;
|
|
241
|
+
}
|
|
242
|
+
// Store for Set-Cookie headers generated by draftMode().enable()/disable()
|
|
243
|
+
// (stored on _state)
|
|
244
|
+
/**
|
|
245
|
+
* Get any Set-Cookie header generated by draftMode().enable()/disable().
|
|
246
|
+
* Called by the framework after rendering to attach the header to the response.
|
|
247
|
+
*/
|
|
248
|
+
export function getDraftModeCookieHeader() {
|
|
249
|
+
const state = _getState();
|
|
250
|
+
const header = state.draftModeCookieHeader;
|
|
251
|
+
state.draftModeCookieHeader = null;
|
|
252
|
+
return header;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Draft mode — check/toggle via a `__prerender_bypass` cookie.
|
|
256
|
+
*
|
|
257
|
+
* - `isEnabled`: true if the bypass cookie is present in the request
|
|
258
|
+
* - `enable()`: sets the bypass cookie (for Route Handlers)
|
|
259
|
+
* - `disable()`: clears the bypass cookie
|
|
260
|
+
*/
|
|
261
|
+
export async function draftMode() {
|
|
262
|
+
const state = _getState();
|
|
263
|
+
const secret = getDraftSecret();
|
|
264
|
+
const isEnabled = state.headersContext
|
|
265
|
+
? state.headersContext.cookies.get(DRAFT_MODE_COOKIE) === secret
|
|
266
|
+
: false;
|
|
267
|
+
return {
|
|
268
|
+
isEnabled,
|
|
269
|
+
enable() {
|
|
270
|
+
if (state.headersContext) {
|
|
271
|
+
state.headersContext.cookies.set(DRAFT_MODE_COOKIE, secret);
|
|
272
|
+
}
|
|
273
|
+
state.draftModeCookieHeader =
|
|
274
|
+
`${DRAFT_MODE_COOKIE}=${secret}; Path=/; HttpOnly; SameSite=Lax`;
|
|
275
|
+
},
|
|
276
|
+
disable() {
|
|
277
|
+
if (state.headersContext) {
|
|
278
|
+
state.headersContext.cookies.delete(DRAFT_MODE_COOKIE);
|
|
279
|
+
}
|
|
280
|
+
state.draftModeCookieHeader =
|
|
281
|
+
`${DRAFT_MODE_COOKIE}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`;
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// ---------------------------------------------------------------------------
|
|
286
|
+
// Cookie name/value validation (RFC 6265)
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
/**
|
|
289
|
+
* RFC 6265 §4.1.1: cookie-name is a token (RFC 2616 §2.2).
|
|
290
|
+
* Allowed: any visible ASCII (0x21-0x7E) except separators: ()<>@,;:\"/[]?={}
|
|
291
|
+
*/
|
|
292
|
+
const VALID_COOKIE_NAME_RE = /^[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]+$/;
|
|
293
|
+
function validateCookieName(name) {
|
|
294
|
+
if (!name || !VALID_COOKIE_NAME_RE.test(name)) {
|
|
295
|
+
throw new Error(`Invalid cookie name: ${JSON.stringify(name)}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Validate cookie attribute values (path, domain) to prevent injection
|
|
300
|
+
* via semicolons, newlines, or other control characters.
|
|
301
|
+
*/
|
|
302
|
+
function validateCookieAttributeValue(value, attributeName) {
|
|
303
|
+
for (let i = 0; i < value.length; i++) {
|
|
304
|
+
const code = value.charCodeAt(i);
|
|
305
|
+
if (code <= 0x1F || code === 0x7F || value[i] === ";") {
|
|
306
|
+
throw new Error(`Invalid cookie ${attributeName} value: ${JSON.stringify(value)}`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// ---------------------------------------------------------------------------
|
|
311
|
+
// RequestCookies implementation
|
|
312
|
+
// ---------------------------------------------------------------------------
|
|
313
|
+
class RequestCookies {
|
|
314
|
+
_cookies;
|
|
315
|
+
constructor(cookies) {
|
|
316
|
+
this._cookies = cookies;
|
|
317
|
+
}
|
|
318
|
+
get(name) {
|
|
319
|
+
const value = this._cookies.get(name);
|
|
320
|
+
if (value === undefined)
|
|
321
|
+
return undefined;
|
|
322
|
+
return { name, value };
|
|
323
|
+
}
|
|
324
|
+
getAll() {
|
|
325
|
+
const result = [];
|
|
326
|
+
for (const [name, value] of this._cookies) {
|
|
327
|
+
result.push({ name, value });
|
|
328
|
+
}
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
has(name) {
|
|
332
|
+
return this._cookies.has(name);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Set a cookie. In Route Handlers and Server Actions, this produces
|
|
336
|
+
* a Set-Cookie header on the response.
|
|
337
|
+
*/
|
|
338
|
+
set(nameOrOptions, value, options) {
|
|
339
|
+
let cookieName;
|
|
340
|
+
let cookieValue;
|
|
341
|
+
let opts;
|
|
342
|
+
if (typeof nameOrOptions === "string") {
|
|
343
|
+
cookieName = nameOrOptions;
|
|
344
|
+
cookieValue = value ?? "";
|
|
345
|
+
opts = options;
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
cookieName = nameOrOptions.name;
|
|
349
|
+
cookieValue = nameOrOptions.value;
|
|
350
|
+
opts = nameOrOptions;
|
|
351
|
+
}
|
|
352
|
+
validateCookieName(cookieName);
|
|
353
|
+
// Update the local cookie map
|
|
354
|
+
this._cookies.set(cookieName, cookieValue);
|
|
355
|
+
// Build Set-Cookie header string
|
|
356
|
+
const parts = [`${cookieName}=${encodeURIComponent(cookieValue)}`];
|
|
357
|
+
if (opts?.path) {
|
|
358
|
+
validateCookieAttributeValue(opts.path, "Path");
|
|
359
|
+
parts.push(`Path=${opts.path}`);
|
|
360
|
+
}
|
|
361
|
+
if (opts?.domain) {
|
|
362
|
+
validateCookieAttributeValue(opts.domain, "Domain");
|
|
363
|
+
parts.push(`Domain=${opts.domain}`);
|
|
364
|
+
}
|
|
365
|
+
if (opts?.maxAge !== undefined)
|
|
366
|
+
parts.push(`Max-Age=${opts.maxAge}`);
|
|
367
|
+
if (opts?.expires)
|
|
368
|
+
parts.push(`Expires=${opts.expires.toUTCString()}`);
|
|
369
|
+
if (opts?.httpOnly)
|
|
370
|
+
parts.push("HttpOnly");
|
|
371
|
+
if (opts?.secure)
|
|
372
|
+
parts.push("Secure");
|
|
373
|
+
if (opts?.sameSite)
|
|
374
|
+
parts.push(`SameSite=${opts.sameSite}`);
|
|
375
|
+
_getState().pendingSetCookies.push(parts.join("; "));
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Delete a cookie by setting it with Max-Age=0.
|
|
380
|
+
*/
|
|
381
|
+
delete(name) {
|
|
382
|
+
validateCookieName(name);
|
|
383
|
+
this._cookies.delete(name);
|
|
384
|
+
_getState().pendingSetCookies.push(`${name}=; Path=/; Max-Age=0`);
|
|
385
|
+
return this;
|
|
386
|
+
}
|
|
387
|
+
get size() {
|
|
388
|
+
return this._cookies.size;
|
|
389
|
+
}
|
|
390
|
+
[Symbol.iterator]() {
|
|
391
|
+
const entries = this._cookies.entries();
|
|
392
|
+
const iter = {
|
|
393
|
+
[Symbol.iterator]() { return iter; },
|
|
394
|
+
next() {
|
|
395
|
+
const { value, done } = entries.next();
|
|
396
|
+
if (done)
|
|
397
|
+
return { value: undefined, done: true };
|
|
398
|
+
const [name, val] = value;
|
|
399
|
+
return { value: [name, { name, value: val }], done: false };
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
return iter;
|
|
403
|
+
}
|
|
404
|
+
toString() {
|
|
405
|
+
const parts = [];
|
|
406
|
+
for (const [name, value] of this._cookies) {
|
|
407
|
+
parts.push(`${name}=${value}`);
|
|
408
|
+
}
|
|
409
|
+
return parts.join("; ");
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../src/shims/headers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image remote pattern validation.
|
|
3
|
+
*
|
|
4
|
+
* Validates remote image URLs against the `images.remotePatterns` and
|
|
5
|
+
* `images.domains` config from next.config.js. This prevents SSRF and
|
|
6
|
+
* open-redirect attacks by blocking URLs that don't match any configured
|
|
7
|
+
* pattern.
|
|
8
|
+
*
|
|
9
|
+
* Pattern matching follows Next.js semantics:
|
|
10
|
+
* - `*` matches a single segment (subdomain in hostname, path segment in pathname)
|
|
11
|
+
* - `**` matches any number of segments
|
|
12
|
+
* - protocol, port, and search are matched exactly when specified
|
|
13
|
+
*/
|
|
14
|
+
export interface RemotePattern {
|
|
15
|
+
protocol?: string;
|
|
16
|
+
hostname: string;
|
|
17
|
+
port?: string;
|
|
18
|
+
pathname?: string;
|
|
19
|
+
search?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check whether a URL matches a single remote pattern.
|
|
23
|
+
* Follows the same semantics as Next.js's matchRemotePattern().
|
|
24
|
+
*/
|
|
25
|
+
export declare function matchRemotePattern(pattern: RemotePattern, url: URL): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Check whether a URL matches any configured remote pattern or legacy domain.
|
|
28
|
+
*/
|
|
29
|
+
export declare function hasRemoteMatch(domains: string[], remotePatterns: RemotePattern[], url: URL): boolean;
|
|
30
|
+
//# sourceMappingURL=image-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-config.d.ts","sourceRoot":"","sources":["../../src/shims/image-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAwCD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAkC5E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,aAAa,EAAE,EAC/B,GAAG,EAAE,GAAG,GACP,OAAO,CAKT"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image remote pattern validation.
|
|
3
|
+
*
|
|
4
|
+
* Validates remote image URLs against the `images.remotePatterns` and
|
|
5
|
+
* `images.domains` config from next.config.js. This prevents SSRF and
|
|
6
|
+
* open-redirect attacks by blocking URLs that don't match any configured
|
|
7
|
+
* pattern.
|
|
8
|
+
*
|
|
9
|
+
* Pattern matching follows Next.js semantics:
|
|
10
|
+
* - `*` matches a single segment (subdomain in hostname, path segment in pathname)
|
|
11
|
+
* - `**` matches any number of segments
|
|
12
|
+
* - protocol, port, and search are matched exactly when specified
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Convert a glob pattern (with `*` and `**`) to a RegExp.
|
|
16
|
+
*
|
|
17
|
+
* For hostnames, segments are separated by `.`:
|
|
18
|
+
* - `*` matches a single segment (no dots): [^.]+
|
|
19
|
+
* - `**` matches any number of segments: .+
|
|
20
|
+
*
|
|
21
|
+
* For pathnames, segments are separated by `/`:
|
|
22
|
+
* - `*` matches a single segment (no slashes): [^/]+
|
|
23
|
+
* - `**` matches any number of segments (including empty): .*
|
|
24
|
+
*
|
|
25
|
+
* Literal characters are escaped for regex safety.
|
|
26
|
+
*/
|
|
27
|
+
function globToRegex(pattern, separator) {
|
|
28
|
+
// Split by ** first, then handle * within each part
|
|
29
|
+
let regexStr = "^";
|
|
30
|
+
const doubleStar = separator === "." ? ".+" : ".*";
|
|
31
|
+
const singleStar = separator === "." ? "[^.]+" : "[^/]+";
|
|
32
|
+
const parts = pattern.split("**");
|
|
33
|
+
for (let i = 0; i < parts.length; i++) {
|
|
34
|
+
if (i > 0) {
|
|
35
|
+
regexStr += doubleStar;
|
|
36
|
+
}
|
|
37
|
+
// Within each part, split by * and escape the literals
|
|
38
|
+
const subParts = parts[i].split("*");
|
|
39
|
+
for (let j = 0; j < subParts.length; j++) {
|
|
40
|
+
if (j > 0) {
|
|
41
|
+
regexStr += singleStar;
|
|
42
|
+
}
|
|
43
|
+
// Escape regex special chars in the literal portion
|
|
44
|
+
regexStr += subParts[j].replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
regexStr += "$";
|
|
48
|
+
return new RegExp(regexStr);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check whether a URL matches a single remote pattern.
|
|
52
|
+
* Follows the same semantics as Next.js's matchRemotePattern().
|
|
53
|
+
*/
|
|
54
|
+
export function matchRemotePattern(pattern, url) {
|
|
55
|
+
// Protocol check (strip trailing colon for comparison)
|
|
56
|
+
if (pattern.protocol !== undefined) {
|
|
57
|
+
if (pattern.protocol.replace(/:$/, "") !== url.protocol.replace(/:$/, "")) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Port check
|
|
62
|
+
if (pattern.port !== undefined) {
|
|
63
|
+
if (pattern.port !== url.port) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Hostname check (required field)
|
|
68
|
+
if (!globToRegex(pattern.hostname, ".").test(url.hostname)) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
// Search/query string check
|
|
72
|
+
if (pattern.search !== undefined) {
|
|
73
|
+
if (pattern.search !== url.search) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Pathname check — defaults to ** (match everything) if not specified
|
|
78
|
+
const pathnamePattern = pattern.pathname ?? "**";
|
|
79
|
+
if (!globToRegex(pathnamePattern, "/").test(url.pathname)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Check whether a URL matches any configured remote pattern or legacy domain.
|
|
86
|
+
*/
|
|
87
|
+
export function hasRemoteMatch(domains, remotePatterns, url) {
|
|
88
|
+
return (domains.some((domain) => url.hostname === domain) ||
|
|
89
|
+
remotePatterns.some((p) => matchRemotePattern(p, url)));
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=image-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-config.js","sourceRoot":"","sources":["../../src/shims/image-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* next/image shim
|
|
3
|
+
*
|
|
4
|
+
* Translates Next.js Image props to @unpic/react Image component.
|
|
5
|
+
* @unpic/react auto-detects CDN from URL and uses native transforms.
|
|
6
|
+
* For local images (relative paths), routes through `/_vinext/image`
|
|
7
|
+
* for server-side optimization (resize, format negotiation, quality).
|
|
8
|
+
*
|
|
9
|
+
* Remote images are validated against `images.remotePatterns` and
|
|
10
|
+
* `images.domains` from next.config.js. Unmatched URLs are blocked
|
|
11
|
+
* in production and warn in development, matching Next.js behavior.
|
|
12
|
+
*/
|
|
13
|
+
import React from "react";
|
|
14
|
+
export interface StaticImageData {
|
|
15
|
+
src: string;
|
|
16
|
+
height: number;
|
|
17
|
+
width: number;
|
|
18
|
+
blurDataURL?: string;
|
|
19
|
+
}
|
|
20
|
+
interface ImageProps {
|
|
21
|
+
src: string | StaticImageData;
|
|
22
|
+
alt: string;
|
|
23
|
+
width?: number;
|
|
24
|
+
height?: number;
|
|
25
|
+
fill?: boolean;
|
|
26
|
+
priority?: boolean;
|
|
27
|
+
quality?: number;
|
|
28
|
+
placeholder?: "blur" | "empty";
|
|
29
|
+
blurDataURL?: string;
|
|
30
|
+
loader?: (params: {
|
|
31
|
+
src: string;
|
|
32
|
+
width: number;
|
|
33
|
+
quality?: number;
|
|
34
|
+
}) => string;
|
|
35
|
+
sizes?: string;
|
|
36
|
+
className?: string;
|
|
37
|
+
style?: React.CSSProperties;
|
|
38
|
+
onLoad?: React.ReactEventHandler<HTMLImageElement>;
|
|
39
|
+
onError?: React.ReactEventHandler<HTMLImageElement>;
|
|
40
|
+
onClick?: React.MouseEventHandler<HTMLImageElement>;
|
|
41
|
+
id?: string;
|
|
42
|
+
unoptimized?: boolean;
|
|
43
|
+
overrideSrc?: string;
|
|
44
|
+
loading?: "lazy" | "eager";
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Build a `/_vinext/image` optimization URL.
|
|
48
|
+
*
|
|
49
|
+
* In production (Cloudflare Workers), the worker intercepts this path and uses
|
|
50
|
+
* the Images binding to resize/transcode on the fly. In dev, the Vite dev
|
|
51
|
+
* server handles it as a passthrough (serves the original file).
|
|
52
|
+
*/
|
|
53
|
+
export declare function imageOptimizationUrl(src: string, width: number, quality?: number): string;
|
|
54
|
+
declare const Image: React.ForwardRefExoticComponent<ImageProps & React.RefAttributes<HTMLImageElement>>;
|
|
55
|
+
/**
|
|
56
|
+
* getImageProps — for advanced use cases (picture elements, background images).
|
|
57
|
+
* Returns the props that would be passed to the underlying <img> element.
|
|
58
|
+
*/
|
|
59
|
+
export declare function getImageProps(props: ImageProps): {
|
|
60
|
+
props: React.ImgHTMLAttributes<HTMLImageElement>;
|
|
61
|
+
};
|
|
62
|
+
export default Image;
|
|
63
|
+
//# sourceMappingURL=image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/shims/image.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAqB,MAAM,OAAO,CAAC;AAI1C,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAyDD,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,MAAM,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACpD,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B;AA0CD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GAAG,MAAM,CAE7F;AAeD,QAAA,MAAM,KAAK,qFAoKT,CAAC;AAEH;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG;IAChD,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;CAClD,CA4FA;AAED,eAAe,KAAK,CAAC"}
|