@reckona/mreact-router 0.0.151 → 0.0.153
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/README.md +1 -1
- package/dist/actions.d.ts +10 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +6 -0
- package/dist/actions.js.map +1 -1
- package/dist/adapters/aws-lambda.d.ts +18 -0
- package/dist/adapters/aws-lambda.d.ts.map +1 -1
- package/dist/adapters/aws-lambda.js +18 -0
- package/dist/adapters/aws-lambda.js.map +1 -1
- package/dist/adapters/cloudflare.d.ts +33 -0
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +33 -0
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/edge.d.ts +5 -0
- package/dist/adapters/edge.d.ts.map +1 -1
- package/dist/adapters/edge.js +5 -0
- package/dist/adapters/edge.js.map +1 -1
- package/dist/adapters/node.d.ts +5 -0
- package/dist/adapters/node.d.ts.map +1 -1
- package/dist/adapters/node.js +5 -0
- package/dist/adapters/node.js.map +1 -1
- package/dist/adapters/static.d.ts +5 -0
- package/dist/adapters/static.d.ts.map +1 -1
- package/dist/adapters/static.js +5 -0
- package/dist/adapters/static.js.map +1 -1
- package/dist/build.d.ts +15 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +71 -1
- package/dist/build.js.map +1 -1
- package/dist/cache.d.ts +15 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +15 -0
- package/dist/cache.js.map +1 -1
- package/dist/cookies.d.ts +16 -0
- package/dist/cookies.d.ts.map +1 -1
- package/dist/cookies.js +16 -0
- package/dist/cookies.js.map +1 -1
- package/dist/dev-server.d.ts +5 -0
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +5 -0
- package/dist/dev-server.js.map +1 -1
- package/dist/link.d.ts +10 -0
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +5 -0
- package/dist/link.js.map +1 -1
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +39 -4
- package/dist/middleware.js.map +1 -1
- package/dist/navigation.d.ts +53 -0
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +48 -0
- package/dist/navigation.js.map +1 -1
- package/dist/render.d.ts +28 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +127 -27
- package/dist/render.js.map +1 -1
- package/dist/route-module-loader.d.ts +6 -1
- package/dist/route-module-loader.d.ts.map +1 -1
- package/dist/route-module-loader.js +8 -1
- package/dist/route-module-loader.js.map +1 -1
- package/dist/serve.d.ts +5 -0
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +5 -0
- package/dist/serve.js.map +1 -1
- package/dist/session.d.ts +19 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +19 -0
- package/dist/session.js.map +1 -1
- package/dist/tailwind-source.d.ts +6 -0
- package/dist/tailwind-source.d.ts.map +1 -0
- package/dist/tailwind-source.js +25 -0
- package/dist/tailwind-source.js.map +1 -0
- package/dist/typed-routes.d.ts +5 -0
- package/dist/typed-routes.d.ts.map +1 -1
- package/dist/typed-routes.js +5 -0
- package/dist/typed-routes.js.map +1 -1
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +3 -25
- package/dist/vite.js.map +1 -1
- package/package.json +11 -11
- package/src/actions.ts +18 -0
- package/src/adapters/aws-lambda.ts +18 -0
- package/src/adapters/cloudflare.ts +33 -0
- package/src/adapters/edge.ts +5 -0
- package/src/adapters/node.ts +5 -0
- package/src/adapters/static.ts +5 -0
- package/src/build.ts +92 -2
- package/src/cache.ts +15 -0
- package/src/cookies.ts +16 -0
- package/src/dev-server.ts +5 -0
- package/src/link.ts +10 -0
- package/src/middleware.ts +54 -4
- package/src/navigation.ts +53 -0
- package/src/render.ts +164 -25
- package/src/route-module-loader.ts +15 -0
- package/src/serve.ts +5 -0
- package/src/session.ts +19 -0
- package/src/tailwind-source.ts +37 -0
- package/src/typed-routes.ts +5 -0
- package/src/types.ts +15 -0
- package/src/vite.ts +3 -38
package/dist/render.js
CHANGED
|
@@ -29,7 +29,7 @@ import { invokeRouterInstrumentation, traceContextFromRequest, } from "./trace.j
|
|
|
29
29
|
import { mergeRouteMiddlewareControls, middlewareMatches, parseRouteMiddlewareControl, parseStaticMiddlewareConfig, shouldSkipMiddleware, validateRouteMiddlewareControl, } from "./middleware.js";
|
|
30
30
|
import { applyFileConventionMetadata, injectHeadMetadata, mergeRouteMetadata, responseHeadersForMetadata, serializeRobots, serializeSitemap, validateRouteMetadata, } from "./metadata.js";
|
|
31
31
|
import { createSlotRenderContext, markShellBoundary, shellBoundaryId, splitLayoutSlot, warnUnconsumedRouteSlots, } from "./layout-composer.js";
|
|
32
|
-
import { importPolicyCacheKey, memoizedHashText, prebuiltRequestModuleArtifact, prebuiltRouteLoaderModuleArtifact, prebuiltServerComponentModuleCode, prebuiltServerModuleOutputMatches, } from "./route-module-loader.js";
|
|
32
|
+
import { importPolicyCacheKey, memoizedHashText, prebuiltRequestModuleArtifact, prebuiltRouteLoaderModuleArtifact, prebuiltServerComponentModuleCode, prebuiltServerModuleOutputMatches, prebuiltServerModuleOutputOptionsMatch, } from "./route-module-loader.js";
|
|
33
33
|
const nativeEscapeTransform = {
|
|
34
34
|
batchImportName: "escapeHtmlBatch",
|
|
35
35
|
batchImportSource: "@reckona/mreact-router/native-escape",
|
|
@@ -134,7 +134,7 @@ async function preloadBuiltPageRouteModules(options) {
|
|
|
134
134
|
serverAwaitHydration: options.analysis.clientInference.client,
|
|
135
135
|
});
|
|
136
136
|
assertNoFatalServerDiagnostics(options.file, streamOutput.diagnostics);
|
|
137
|
-
await loadServerStreamModule(streamOutput.code, options.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins);
|
|
137
|
+
await loadServerStreamModule(streamOutput.code, options.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, undefined, { serverAwaitHydration: options.analysis.clientInference.client });
|
|
138
138
|
}
|
|
139
139
|
await preloadShellModulesForPage({
|
|
140
140
|
appDir: options.appDir,
|
|
@@ -193,6 +193,7 @@ function assertNoFatalServerDiagnostics(filename, diagnostics) {
|
|
|
193
193
|
}
|
|
194
194
|
const serverTransformCache = new Map();
|
|
195
195
|
const serverTransformCacheCounters = createRouterRuntimeCacheCounters();
|
|
196
|
+
let productionDynamicServerTransformWarned = false;
|
|
196
197
|
const serverSourceFileCache = new Map();
|
|
197
198
|
const serverSourceFileCacheCounters = createRouterRuntimeCacheCounters();
|
|
198
199
|
const routeSourceAnalysisCache = new Map();
|
|
@@ -275,12 +276,25 @@ function finishRenderTimingPhase(timing, startedAt, phaseName) {
|
|
|
275
276
|
}
|
|
276
277
|
timing.phases[phaseName] = logDurationMs(startedAt);
|
|
277
278
|
}
|
|
279
|
+
async function readSettledPromiseAtNextTask(promise) {
|
|
280
|
+
return await Promise.race([
|
|
281
|
+
promise.then((value) => ({ settled: true, value })),
|
|
282
|
+
new Promise((resolve) => {
|
|
283
|
+
setTimeout(() => resolve({ settled: false }), 0);
|
|
284
|
+
}),
|
|
285
|
+
]);
|
|
286
|
+
}
|
|
278
287
|
function addRenderTimingPhaseDuration(timing, startedAt, phaseName) {
|
|
279
288
|
if (timing === undefined || startedAt === undefined) {
|
|
280
289
|
return;
|
|
281
290
|
}
|
|
282
291
|
timing.phases[phaseName] = (timing.phases[phaseName] ?? 0) + logDurationMs(startedAt);
|
|
283
292
|
}
|
|
293
|
+
function routeLoaderMayReturnControlResponse(code) {
|
|
294
|
+
return /\b(?:redirect|redirectExternal|rewrite|notFound|throwNotFound)\s*\(/.test(code) ||
|
|
295
|
+
/\bnew\s+Response\s*\(/.test(code) ||
|
|
296
|
+
/\bResponse\.(?:redirect|json)\s*\(/.test(code);
|
|
297
|
+
}
|
|
284
298
|
async function waitForRenderPreload(options, timing) {
|
|
285
299
|
if (options.preload?.wait !== "before-render") {
|
|
286
300
|
return;
|
|
@@ -413,6 +427,7 @@ async function renderAppRequestInternal(options) {
|
|
|
413
427
|
appDir: options.appDir,
|
|
414
428
|
filename: "not-found.mreact.tsx",
|
|
415
429
|
pathname: url.pathname,
|
|
430
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
416
431
|
});
|
|
417
432
|
const response = await renderSpecialRoute({
|
|
418
433
|
appDir: options.appDir,
|
|
@@ -735,8 +750,9 @@ async function renderAppRequestInternal(options) {
|
|
|
735
750
|
return response;
|
|
736
751
|
}
|
|
737
752
|
let streamData;
|
|
738
|
-
|
|
739
|
-
|
|
753
|
+
let streamDataPromise = dataPromise ?? Promise.resolve(undefined);
|
|
754
|
+
phaseStartedAt = renderTimingPhaseStartedAt(timing);
|
|
755
|
+
if (loadingFile === undefined || routeLoaderMayReturnControlResponse(code)) {
|
|
740
756
|
try {
|
|
741
757
|
streamData = dataPromise === undefined ? undefined : await dataPromise;
|
|
742
758
|
}
|
|
@@ -747,6 +763,22 @@ async function renderAppRequestInternal(options) {
|
|
|
747
763
|
emitRenderTiming(options, timing, streamData.status);
|
|
748
764
|
return streamData;
|
|
749
765
|
}
|
|
766
|
+
streamDataPromise = Promise.resolve(streamData);
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
try {
|
|
770
|
+
const settledData = await readSettledPromiseAtNextTask(streamDataPromise);
|
|
771
|
+
if (settledData.settled) {
|
|
772
|
+
if (settledData.value instanceof Response) {
|
|
773
|
+
emitRenderTiming(options, timing, settledData.value.status);
|
|
774
|
+
return settledData.value;
|
|
775
|
+
}
|
|
776
|
+
streamDataPromise = Promise.resolve(settledData.value);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
finally {
|
|
780
|
+
finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
|
|
781
|
+
}
|
|
750
782
|
}
|
|
751
783
|
await waitForRenderPreload(options, timing);
|
|
752
784
|
await loadServerRenderArtifacts(options, matched.route.file, timing);
|
|
@@ -774,7 +806,7 @@ async function renderAppRequestInternal(options) {
|
|
|
774
806
|
appDir: options.appDir,
|
|
775
807
|
assetBaseUrl: options.assetBaseUrl,
|
|
776
808
|
clientRoute,
|
|
777
|
-
data:
|
|
809
|
+
data: streamDataPromise,
|
|
778
810
|
define: options.define,
|
|
779
811
|
loadingFile,
|
|
780
812
|
pageFile: matched.route.file,
|
|
@@ -1149,17 +1181,24 @@ async function nearestBoundaryFileForPath(options) {
|
|
|
1149
1181
|
const parts = options.pathname
|
|
1150
1182
|
.replace(/^\/+|\/+$/g, "")
|
|
1151
1183
|
.split("/")
|
|
1152
|
-
.filter((part) => part.length > 0);
|
|
1153
|
-
return nearestBoundaryFileFromParts({
|
|
1184
|
+
.filter((part) => part.length > 0 && part !== "." && part !== "..");
|
|
1185
|
+
return await nearestBoundaryFileFromParts({
|
|
1154
1186
|
appDir: options.appDir,
|
|
1155
1187
|
filename: options.filename,
|
|
1156
1188
|
parts,
|
|
1189
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
1157
1190
|
});
|
|
1158
1191
|
}
|
|
1159
1192
|
async function nearestBoundaryFileFromParts(options) {
|
|
1160
1193
|
for (let count = options.parts.length; count >= 0; count -= 1) {
|
|
1161
1194
|
for (const filename of boundaryFilenameCandidates(options.filename)) {
|
|
1162
1195
|
const candidate = join(options.appDir, ...options.parts.slice(0, count), filename);
|
|
1196
|
+
if (options.serverSourceFiles !== undefined) {
|
|
1197
|
+
if (options.serverSourceFiles.has(candidate)) {
|
|
1198
|
+
return candidate;
|
|
1199
|
+
}
|
|
1200
|
+
continue;
|
|
1201
|
+
}
|
|
1163
1202
|
try {
|
|
1164
1203
|
await access(candidate);
|
|
1165
1204
|
return candidate;
|
|
@@ -1200,11 +1239,18 @@ function boundaryFilenameCandidates(filename) {
|
|
|
1200
1239
|
return [standardFilename, filename];
|
|
1201
1240
|
}
|
|
1202
1241
|
async function renderSpecialRoute(options) {
|
|
1203
|
-
|
|
1204
|
-
|
|
1242
|
+
if (options.serverSourceFiles !== undefined) {
|
|
1243
|
+
if (!options.serverSourceFiles.has(options.routeFile)) {
|
|
1244
|
+
return new Response(options.textFallback, { status: options.status });
|
|
1245
|
+
}
|
|
1205
1246
|
}
|
|
1206
|
-
|
|
1207
|
-
|
|
1247
|
+
else {
|
|
1248
|
+
try {
|
|
1249
|
+
await access(options.routeFile);
|
|
1250
|
+
}
|
|
1251
|
+
catch {
|
|
1252
|
+
return new Response(options.textFallback, { status: options.status });
|
|
1253
|
+
}
|
|
1208
1254
|
}
|
|
1209
1255
|
const props = {
|
|
1210
1256
|
data: undefined,
|
|
@@ -1286,7 +1332,10 @@ async function dispatchServerRoute(options) {
|
|
|
1286
1332
|
const module = await loadServerRouteModule(options);
|
|
1287
1333
|
const handler = module[options.request.method] ?? module.ALL ?? module.default;
|
|
1288
1334
|
if (typeof handler !== "function") {
|
|
1289
|
-
return new Response("Method Not Allowed", {
|
|
1335
|
+
return new Response("Method Not Allowed", {
|
|
1336
|
+
headers: { allow: allowedServerRouteMethods(module).join(", ") },
|
|
1337
|
+
status: 405,
|
|
1338
|
+
});
|
|
1290
1339
|
}
|
|
1291
1340
|
let response;
|
|
1292
1341
|
try {
|
|
@@ -1307,6 +1356,9 @@ async function dispatchServerRoute(options) {
|
|
|
1307
1356
|
? response
|
|
1308
1357
|
: new Response("Invalid route response", { status: 500 });
|
|
1309
1358
|
}
|
|
1359
|
+
function allowedServerRouteMethods(module) {
|
|
1360
|
+
return ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"].filter((method) => typeof module[method] === "function");
|
|
1361
|
+
}
|
|
1310
1362
|
async function dispatchConventionAssetRoute(options) {
|
|
1311
1363
|
if (options.request.method !== "GET" && options.request.method !== "HEAD") {
|
|
1312
1364
|
return new Response("Method Not Allowed", {
|
|
@@ -1664,7 +1716,7 @@ function transformServerModule(options) {
|
|
|
1664
1716
|
const artifact = options.serverModules?.get(options.filename)?.[options.serverOutput];
|
|
1665
1717
|
if (artifact !== undefined &&
|
|
1666
1718
|
artifact.sourceHash === sourceHash &&
|
|
1667
|
-
options.serverAwaitHydration
|
|
1719
|
+
prebuiltServerModuleOutputOptionsMatch(artifact, options.serverAwaitHydration === true ? { serverAwaitHydration: true } : {})) {
|
|
1668
1720
|
return {
|
|
1669
1721
|
code: artifact.code,
|
|
1670
1722
|
diagnostics: [],
|
|
@@ -1690,6 +1742,7 @@ function transformServerModule(options) {
|
|
|
1690
1742
|
if (cached !== undefined) {
|
|
1691
1743
|
return cached;
|
|
1692
1744
|
}
|
|
1745
|
+
warnProductionDynamicServerTransform();
|
|
1693
1746
|
const output = transform({
|
|
1694
1747
|
code: options.code,
|
|
1695
1748
|
...(options.clientBoundaryImports === undefined
|
|
@@ -1708,6 +1761,14 @@ function transformServerModule(options) {
|
|
|
1708
1761
|
setBoundedCacheEntry(serverTransformCache, key, output, maxServerTransformCacheEntries, serverTransformCacheCounters);
|
|
1709
1762
|
return output;
|
|
1710
1763
|
}
|
|
1764
|
+
export const __transformServerModuleForTesting = transformServerModule;
|
|
1765
|
+
function warnProductionDynamicServerTransform() {
|
|
1766
|
+
if (process.env.NODE_ENV !== "production" || productionDynamicServerTransformWarned) {
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
productionDynamicServerTransformWarned = true;
|
|
1770
|
+
console.warn("mreact router: dynamic server transform path ran in production. Production deployments should provide prebuilt serverModules; otherwise request-time transforms use development compiler settings.");
|
|
1771
|
+
}
|
|
1711
1772
|
async function analyzeRouteSource(options) {
|
|
1712
1773
|
const sourceHash = memoizedHashText(options.code);
|
|
1713
1774
|
if (options.artifact !== undefined &&
|
|
@@ -2123,11 +2184,12 @@ async function renderServerStreamSlots(code, options) {
|
|
|
2123
2184
|
function hasRouteSlotsExport(code) {
|
|
2124
2185
|
return /^\s*export\s+const\s+slots\s*=/m.test(code);
|
|
2125
2186
|
}
|
|
2126
|
-
async function loadServerStreamModule(code, sourcefile, serverModules, serverModuleCacheVersion, define, vitePlugins, importPolicy) {
|
|
2187
|
+
async function loadServerStreamModule(code, sourcefile, serverModules, serverModuleCacheVersion, define, vitePlugins, importPolicy, outputOptions = {}) {
|
|
2127
2188
|
const artifactCode = serverModules?.get(sourcefile)?.stream;
|
|
2128
2189
|
const codeHash = memoizedHashText(code);
|
|
2129
|
-
const prebuiltCode = prebuiltServerComponentModuleCode(artifactCode, code, codeHash);
|
|
2190
|
+
const prebuiltCode = prebuiltServerComponentModuleCode(artifactCode, code, codeHash, outputOptions);
|
|
2130
2191
|
if (artifactCode !== undefined &&
|
|
2192
|
+
prebuiltServerModuleOutputOptionsMatch(artifactCode, outputOptions) &&
|
|
2131
2193
|
prebuiltServerModuleOutputMatches(artifactCode, code, codeHash) &&
|
|
2132
2194
|
artifactCode.moduleFile !== undefined) {
|
|
2133
2195
|
return await importBuiltServerModuleFile({
|
|
@@ -2806,9 +2868,7 @@ async function bundleRouteMetadataModuleCode(options) {
|
|
|
2806
2868
|
return code;
|
|
2807
2869
|
}
|
|
2808
2870
|
async function loadComposedRouteMetadata(options) {
|
|
2809
|
-
const cacheKey = options
|
|
2810
|
-
? undefined
|
|
2811
|
-
: `${options.appDir}\0${options.filename}\0${options.serverModuleCacheVersion}\0${memoizedHashText(options.code)}\0${viteDefineCacheKey(options.define)}\0${vitePluginsCacheKey(options.vitePlugins)}`;
|
|
2871
|
+
const cacheKey = composedRouteMetadataCacheKey(options);
|
|
2812
2872
|
if (cacheKey !== undefined) {
|
|
2813
2873
|
const cached = readRouterRuntimeCacheEntry(composedRouteMetadataCache, cacheKey, composedRouteMetadataCacheCounters);
|
|
2814
2874
|
if (cached !== undefined) {
|
|
@@ -2829,6 +2889,12 @@ async function loadComposedRouteMetadata(options) {
|
|
|
2829
2889
|
throw error;
|
|
2830
2890
|
}
|
|
2831
2891
|
}
|
|
2892
|
+
function composedRouteMetadataCacheKey(options) {
|
|
2893
|
+
return options.serverModuleCacheVersion === undefined
|
|
2894
|
+
? undefined
|
|
2895
|
+
: `${options.appDir}\0${options.filename}\0${options.serverModuleCacheVersion}\0${memoizedHashText(options.code)}\0${importPolicyCacheKey(options.importPolicy)}\0${viteDefineCacheKey(options.define)}\0${vitePluginsCacheKey(options.vitePlugins)}`;
|
|
2896
|
+
}
|
|
2897
|
+
export const __composedRouteMetadataCacheKeyForTesting = composedRouteMetadataCacheKey;
|
|
2832
2898
|
async function loadComposedRouteMetadataUncached(options) {
|
|
2833
2899
|
const layoutFiles = await shellFilesForPage(options.appDir, options.filename, options.serverModuleCacheVersion);
|
|
2834
2900
|
const metadata = [];
|
|
@@ -2951,21 +3017,47 @@ function cspDirectiveNonces(csp, directive) {
|
|
|
2951
3017
|
}
|
|
2952
3018
|
function inlineCspTags(html) {
|
|
2953
3019
|
const tags = [];
|
|
2954
|
-
const
|
|
2955
|
-
let
|
|
2956
|
-
while (
|
|
2957
|
-
const
|
|
2958
|
-
|
|
3020
|
+
const lowerHtml = html.toLowerCase();
|
|
3021
|
+
let position = 0;
|
|
3022
|
+
while (position < html.length) {
|
|
3023
|
+
const scriptIndex = lowerHtml.indexOf("<script", position);
|
|
3024
|
+
const styleIndex = lowerHtml.indexOf("<style", position);
|
|
3025
|
+
const openerIndex = scriptIndex === -1
|
|
3026
|
+
? styleIndex
|
|
3027
|
+
: styleIndex === -1
|
|
3028
|
+
? scriptIndex
|
|
3029
|
+
: Math.min(scriptIndex, styleIndex);
|
|
3030
|
+
if (openerIndex === -1) {
|
|
3031
|
+
break;
|
|
3032
|
+
}
|
|
3033
|
+
const name = lowerHtml.startsWith("<script", openerIndex) ? "script" : "style";
|
|
3034
|
+
const tagEnd = html.indexOf(">", openerIndex + 1);
|
|
3035
|
+
if (tagEnd === -1) {
|
|
3036
|
+
break;
|
|
3037
|
+
}
|
|
3038
|
+
const closeToken = `</${name}>`;
|
|
3039
|
+
const closeIndex = lowerHtml.indexOf(closeToken, tagEnd + 1);
|
|
3040
|
+
const nextScriptIndex = lowerHtml.indexOf("<script", tagEnd + 1);
|
|
3041
|
+
const nextStyleIndex = lowerHtml.indexOf("<style", tagEnd + 1);
|
|
3042
|
+
const nextOpenerIndex = nextScriptIndex === -1
|
|
3043
|
+
? nextStyleIndex
|
|
3044
|
+
: nextStyleIndex === -1
|
|
3045
|
+
? nextScriptIndex
|
|
3046
|
+
: Math.min(nextScriptIndex, nextStyleIndex);
|
|
3047
|
+
if (closeIndex === -1 || (nextOpenerIndex !== -1 && nextOpenerIndex < closeIndex)) {
|
|
3048
|
+
position = tagEnd + 1;
|
|
2959
3049
|
continue;
|
|
2960
3050
|
}
|
|
2961
3051
|
tags.push({
|
|
2962
|
-
attributes: parseTagAttributes(
|
|
2963
|
-
content:
|
|
3052
|
+
attributes: parseTagAttributes(html.slice(openerIndex + name.length + 1, tagEnd)),
|
|
3053
|
+
content: html.slice(tagEnd + 1, closeIndex),
|
|
2964
3054
|
name,
|
|
2965
3055
|
});
|
|
3056
|
+
position = closeIndex + closeToken.length;
|
|
2966
3057
|
}
|
|
2967
3058
|
return tags;
|
|
2968
3059
|
}
|
|
3060
|
+
export const __inlineCspTagsForTesting = inlineCspTags;
|
|
2969
3061
|
function parseTagAttributes(source) {
|
|
2970
3062
|
const attributes = new Map();
|
|
2971
3063
|
const pattern = /([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
@@ -2996,7 +3088,7 @@ function injectQueryState(html, state) {
|
|
|
2996
3088
|
}
|
|
2997
3089
|
const script = `<script type="application/json" id="${__MREACT_QUERY_STATE_SCRIPT_ID}">${escapeJsonForHtml(JSON.stringify(state))}</script>`;
|
|
2998
3090
|
return /<\/body>/i.test(html)
|
|
2999
|
-
? html
|
|
3091
|
+
? replaceFinalBodyCloseTag(html, script)
|
|
3000
3092
|
: `${html}${script}`;
|
|
3001
3093
|
}
|
|
3002
3094
|
function injectAuthSessionClaims(html, claims) {
|
|
@@ -3005,9 +3097,17 @@ function injectAuthSessionClaims(html, claims) {
|
|
|
3005
3097
|
}
|
|
3006
3098
|
const script = `<script type="application/json" id="${authSessionScriptId}">${escapeJsonForHtml(JSON.stringify(claims))}</script>`;
|
|
3007
3099
|
return /<\/body>/i.test(html)
|
|
3008
|
-
? html
|
|
3100
|
+
? replaceFinalBodyCloseTag(html, script)
|
|
3009
3101
|
: `${html}${script}`;
|
|
3010
3102
|
}
|
|
3103
|
+
function replaceFinalBodyCloseTag(html, insertion) {
|
|
3104
|
+
const matches = [...html.matchAll(/<\/body>/gi)];
|
|
3105
|
+
const last = matches.at(-1);
|
|
3106
|
+
if (last?.index === undefined) {
|
|
3107
|
+
return `${html}${insertion}`;
|
|
3108
|
+
}
|
|
3109
|
+
return `${html.slice(0, last.index)}${insertion}${html.slice(last.index)}`;
|
|
3110
|
+
}
|
|
3011
3111
|
function authIncludesClaims(code) {
|
|
3012
3112
|
return /\bexport\s+const\s+auth\s*=\s*["']include-claims["']\s*;?/.test(code);
|
|
3013
3113
|
}
|