@bleedingdev/modern-js-server-core 3.2.0-ultramodern.99 → 3.4.0-ultramodern.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/dist/cjs/adapters/node/helper/index.js +9 -5
- package/dist/cjs/adapters/node/helper/loadCache.js +9 -5
- package/dist/cjs/adapters/node/helper/loadConfig.js +9 -5
- package/dist/cjs/adapters/node/helper/loadEnv.js +9 -5
- package/dist/cjs/adapters/node/helper/loadPlugin.js +9 -5
- package/dist/cjs/adapters/node/helper/utils.js +12 -8
- package/dist/cjs/adapters/node/hono.js +9 -5
- package/dist/cjs/adapters/node/index.js +9 -5
- package/dist/cjs/adapters/node/node.js +9 -5
- package/dist/cjs/adapters/node/plugins/index.js +9 -5
- package/dist/cjs/adapters/node/plugins/nodeServer.js +12 -8
- package/dist/cjs/adapters/node/plugins/resource.js +10 -11
- package/dist/cjs/adapters/node/plugins/static.js +20 -190
- package/dist/cjs/adapters/node/plugins/staticModuleFederation.js +165 -0
- package/dist/cjs/adapters/node/plugins/staticPrecompressed.js +135 -0
- package/dist/cjs/constants.js +18 -13
- package/dist/cjs/context.js +9 -5
- package/dist/cjs/helper.js +12 -8
- package/dist/cjs/hono.js +9 -5
- package/dist/cjs/index.js +60 -32
- package/dist/cjs/plugins/compat/hooks.js +14 -10
- package/dist/cjs/plugins/compat/index.js +9 -5
- package/dist/cjs/plugins/default.js +9 -7
- package/dist/cjs/plugins/favicon.js +12 -8
- package/dist/cjs/plugins/index.js +11 -88
- package/dist/cjs/plugins/log.js +9 -5
- package/dist/cjs/plugins/middlewares.js +12 -8
- package/dist/cjs/plugins/monitors.js +9 -5
- package/dist/cjs/plugins/processedBy.js +12 -8
- package/dist/cjs/plugins/render/csrRscRender.js +9 -5
- package/dist/cjs/plugins/render/dataHandler.js +9 -5
- package/dist/cjs/plugins/render/index.js +12 -8
- package/dist/cjs/plugins/render/inject.js +12 -7
- package/dist/cjs/plugins/render/render.js +14 -6
- package/dist/cjs/plugins/render/renderRscHandler.js +9 -5
- package/dist/cjs/plugins/render/serverActionHandler.js +9 -5
- package/dist/cjs/plugins/render/ssrCache.js +9 -5
- package/dist/cjs/plugins/render/ssrRender.js +9 -5
- package/dist/cjs/plugins/render/utils.js +12 -8
- package/dist/cjs/plugins/route.js +9 -5
- package/dist/cjs/serverBase.js +9 -5
- package/dist/cjs/types/config/bffRuntime.js +18 -0
- package/dist/cjs/types/config/index.js +9 -5
- package/dist/cjs/types/config/serverTelemetry.js +18 -0
- package/dist/cjs/types/index.js +9 -5
- package/dist/cjs/types/plugins/index.js +9 -5
- package/dist/cjs/utils/entry.js +13 -9
- package/dist/cjs/utils/env.js +13 -9
- package/dist/cjs/utils/error.js +71 -5
- package/dist/cjs/utils/index.js +9 -5
- package/dist/cjs/utils/middlewareCollector.js +13 -9
- package/dist/cjs/utils/publicDir.js +9 -5
- package/dist/cjs/utils/request.js +16 -12
- package/dist/cjs/utils/serverConfig.js +9 -5
- package/dist/cjs/utils/storage.js +9 -5
- package/dist/cjs/utils/transformStream.js +13 -9
- package/dist/cjs/utils/warmup.js +12 -8
- package/dist/esm/adapters/node/plugins/resource.mjs +1 -6
- package/dist/esm/adapters/node/plugins/static.mjs +7 -181
- package/dist/esm/adapters/node/plugins/staticModuleFederation.mjs +96 -0
- package/dist/esm/adapters/node/plugins/staticPrecompressed.mjs +91 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/plugins/default.mjs +0 -2
- package/dist/esm/plugins/index.mjs +0 -3
- package/dist/esm/plugins/render/inject.mjs +3 -2
- package/dist/esm/plugins/render/render.mjs +7 -3
- package/dist/esm/types/config/bffRuntime.mjs +0 -0
- package/dist/esm/types/config/serverTelemetry.mjs +0 -0
- package/dist/esm/utils/error.mjs +54 -1
- package/dist/esm-node/adapters/node/plugins/resource.mjs +1 -6
- package/dist/esm-node/adapters/node/plugins/static.mjs +7 -181
- package/dist/esm-node/adapters/node/plugins/staticModuleFederation.mjs +97 -0
- package/dist/esm-node/adapters/node/plugins/staticPrecompressed.mjs +92 -0
- package/dist/esm-node/index.mjs +1 -1
- package/dist/esm-node/plugins/default.mjs +0 -2
- package/dist/esm-node/plugins/index.mjs +0 -3
- package/dist/esm-node/plugins/render/inject.mjs +3 -2
- package/dist/esm-node/plugins/render/render.mjs +5 -1
- package/dist/esm-node/types/config/bffRuntime.mjs +1 -0
- package/dist/esm-node/types/config/serverTelemetry.mjs +1 -0
- package/dist/esm-node/utils/error.mjs +54 -1
- package/dist/types/adapters/node/plugins/staticModuleFederation.d.ts +13 -0
- package/dist/types/adapters/node/plugins/staticPrecompressed.d.ts +13 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/plugins/index.d.ts +0 -3
- package/dist/types/types/config/bff.d.ts +2 -97
- package/dist/types/types/config/bffRuntime.d.ts +105 -0
- package/dist/types/types/config/server.d.ts +3 -337
- package/dist/types/types/config/serverTelemetry.d.ts +319 -0
- package/dist/types/types/plugins/base.d.ts +7 -2
- package/dist/types/types/plugins/index.d.ts +1 -1
- package/dist/types/utils/error.d.ts +16 -0
- package/package.json +12 -12
- package/dist/cjs/adapters/node/plugins/moduleFederationCss.js +0 -172
- package/dist/cjs/plugins/contractGateAutopilot.js +0 -158
- package/dist/cjs/plugins/contractGateSnapshotStore.js +0 -239
- package/dist/cjs/plugins/mfCache.js +0 -78
- package/dist/cjs/plugins/telemetry.js +0 -1283
- package/dist/esm/adapters/node/plugins/moduleFederationCss.mjs +0 -125
- package/dist/esm/plugins/contractGateAutopilot.mjs +0 -124
- package/dist/esm/plugins/contractGateSnapshotStore.mjs +0 -180
- package/dist/esm/plugins/mfCache.mjs +0 -35
- package/dist/esm/plugins/telemetry.mjs +0 -1195
- package/dist/esm-node/adapters/node/plugins/moduleFederationCss.mjs +0 -126
- package/dist/esm-node/plugins/contractGateAutopilot.mjs +0 -125
- package/dist/esm-node/plugins/contractGateSnapshotStore.mjs +0 -182
- package/dist/esm-node/plugins/mfCache.mjs +0 -36
- package/dist/esm-node/plugins/telemetry.mjs +0 -1196
- package/dist/types/adapters/node/plugins/moduleFederationCss.d.ts +0 -33
- package/dist/types/plugins/contractGateAutopilot.d.ts +0 -35
- package/dist/types/plugins/contractGateSnapshotStore.d.ts +0 -57
- package/dist/types/plugins/mfCache.d.ts +0 -12
- package/dist/types/plugins/telemetry.d.ts +0 -309
|
@@ -3,7 +3,6 @@ import { fileReader } from "@modern-js/runtime-utils/fileReader";
|
|
|
3
3
|
import { LOADABLE_STATS_FILE, MAIN_ENTRY_NAME, NESTED_ROUTE_SPEC_FILE, ROUTE_MANIFEST_FILE, SERVER_BUNDLE_DIRECTORY, compatibleRequire, fs, isProd } from "@modern-js/utils";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { uniqueKeyByRoute } from "../../../utils/index.mjs";
|
|
6
|
-
import { collectDirectRemoteModuleFederationCss } from "./moduleFederationCss.mjs";
|
|
7
6
|
async function getHtmlTemplates(pwd, routes) {
|
|
8
7
|
const htmlRoutes = routes.filter((route)=>route.entryName);
|
|
9
8
|
const htmls = await Promise.all(htmlRoutes.map(async (route)=>{
|
|
@@ -58,16 +57,12 @@ async function getServerManifest(pwd, routes, monitors) {
|
|
|
58
57
|
const routeManifest = await compatibleRequire(routesManifestUri).catch((_)=>({}));
|
|
59
58
|
const nestedRoutesJsonPath = path.join(pwd, NESTED_ROUTE_SPEC_FILE);
|
|
60
59
|
const nestedRoutesJson = await compatibleRequire(nestedRoutesJsonPath).catch((_)=>({}));
|
|
61
|
-
const moduleFederationCssAssets = await collectDirectRemoteModuleFederationCss(pwd, {
|
|
62
|
-
monitors
|
|
63
|
-
});
|
|
64
60
|
return {
|
|
65
61
|
loaderBundles,
|
|
66
62
|
renderBundles,
|
|
67
63
|
loadableStats,
|
|
68
64
|
routeManifest,
|
|
69
|
-
nestedRoutesJson
|
|
70
|
-
moduleFederationCssAssets
|
|
65
|
+
nestedRoutesJson
|
|
71
66
|
};
|
|
72
67
|
}
|
|
73
68
|
function injectServerManifest(pwd, routes, manifestPromise) {
|
|
@@ -5,6 +5,8 @@ import { getMimeType } from "hono/utils/mime";
|
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { sortRoutes } from "../../../utils/index.mjs";
|
|
7
7
|
import { getPublicDirPatterns } from "../../../utils/publicDir.mjs";
|
|
8
|
+
import { applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath } from "./staticModuleFederation.mjs";
|
|
9
|
+
import { applyPreCompressedAssetHeaders, resolvePreCompressedAsset } from "./staticPrecompressed.mjs";
|
|
8
10
|
const serverStaticPlugin = ()=>({
|
|
9
11
|
name: '@modern-js/plugin-server-static',
|
|
10
12
|
setup (api) {
|
|
@@ -25,91 +27,6 @@ const serverStaticPlugin = ()=>({
|
|
|
25
27
|
});
|
|
26
28
|
}
|
|
27
29
|
});
|
|
28
|
-
const PRE_COMPRESSED_ASSET_EXTENSIONS = {
|
|
29
|
-
br: '.br',
|
|
30
|
-
gzip: '.gz'
|
|
31
|
-
};
|
|
32
|
-
const PRE_COMPRESSED_SUPPORTED_ENCODINGS = [
|
|
33
|
-
'br',
|
|
34
|
-
'gzip'
|
|
35
|
-
];
|
|
36
|
-
const parseAcceptEncoding = (value)=>value.split(',').map((item)=>item.trim()).filter(Boolean).map((item)=>{
|
|
37
|
-
const [rawName, ...params] = item.split(';');
|
|
38
|
-
const name = rawName.trim().toLowerCase();
|
|
39
|
-
let q = 1;
|
|
40
|
-
for (const param of params){
|
|
41
|
-
const [key, rawValue] = param.split('=').map((v)=>v.trim());
|
|
42
|
-
if ('q' !== key.toLowerCase() || null == rawValue) continue;
|
|
43
|
-
const parsedQ = Number(rawValue);
|
|
44
|
-
if (!Number.isNaN(parsedQ)) q = Math.max(0, Math.min(parsedQ, 1));
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
name,
|
|
48
|
-
q
|
|
49
|
-
};
|
|
50
|
-
});
|
|
51
|
-
const getAcceptedEncodings = (value)=>{
|
|
52
|
-
if (!value) return [];
|
|
53
|
-
const parsed = parseAcceptEncoding(value);
|
|
54
|
-
const qualityByEncoding = new Map();
|
|
55
|
-
let wildcardQuality;
|
|
56
|
-
for (const { name, q } of parsed){
|
|
57
|
-
if ('*' === name) {
|
|
58
|
-
wildcardQuality = q;
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
qualityByEncoding.set(name, q);
|
|
62
|
-
}
|
|
63
|
-
const getQuality = (encoding)=>{
|
|
64
|
-
const explicit = qualityByEncoding.get(encoding);
|
|
65
|
-
if (void 0 !== explicit) return explicit;
|
|
66
|
-
return wildcardQuality ?? 0;
|
|
67
|
-
};
|
|
68
|
-
return PRE_COMPRESSED_SUPPORTED_ENCODINGS.map((encoding)=>({
|
|
69
|
-
encoding,
|
|
70
|
-
quality: getQuality(encoding)
|
|
71
|
-
})).filter((item)=>item.quality > 0).sort((a, b)=>b.quality - a.quality).map((item)=>item.encoding);
|
|
72
|
-
};
|
|
73
|
-
const appendVaryHeader = (c, value)=>{
|
|
74
|
-
const current = c.res.headers.get('Vary');
|
|
75
|
-
if (!current) return void c.header('Vary', value);
|
|
76
|
-
const values = current.split(',').map((item)=>item.trim().toLowerCase()).filter(Boolean);
|
|
77
|
-
if (!values.includes(value.toLowerCase())) c.header('Vary', `${current}, ${value}`);
|
|
78
|
-
};
|
|
79
|
-
const resolvePreCompressedAsset = async (c, filepath)=>{
|
|
80
|
-
const brPath = `${filepath}${PRE_COMPRESSED_ASSET_EXTENSIONS.br}`;
|
|
81
|
-
const gzipPath = `${filepath}${PRE_COMPRESSED_ASSET_EXTENSIONS.gzip}`;
|
|
82
|
-
const [hasBr, hasGzip] = await Promise.all([
|
|
83
|
-
fs.pathExists(brPath),
|
|
84
|
-
fs.pathExists(gzipPath)
|
|
85
|
-
]);
|
|
86
|
-
const hasVariant = hasBr || hasGzip;
|
|
87
|
-
if (!hasVariant) return {
|
|
88
|
-
selected: null,
|
|
89
|
-
hasVariant: false
|
|
90
|
-
};
|
|
91
|
-
const acceptedEncodings = getAcceptedEncodings(c.req.header('accept-encoding'));
|
|
92
|
-
for (const encoding of acceptedEncodings){
|
|
93
|
-
if ('br' === encoding && hasBr) return {
|
|
94
|
-
selected: {
|
|
95
|
-
filepath: brPath,
|
|
96
|
-
encoding
|
|
97
|
-
},
|
|
98
|
-
hasVariant: true
|
|
99
|
-
};
|
|
100
|
-
if ('gzip' === encoding && hasGzip) return {
|
|
101
|
-
selected: {
|
|
102
|
-
filepath: gzipPath,
|
|
103
|
-
encoding
|
|
104
|
-
},
|
|
105
|
-
hasVariant: true
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
return {
|
|
109
|
-
selected: null,
|
|
110
|
-
hasVariant: true
|
|
111
|
-
};
|
|
112
|
-
};
|
|
113
30
|
function createPublicMiddleware({ pwd, routes }) {
|
|
114
31
|
return async (c, next)=>{
|
|
115
32
|
const route = matchPublicRoute(c.req, routes);
|
|
@@ -126,8 +43,7 @@ function createPublicMiddleware({ pwd, routes }) {
|
|
|
126
43
|
Object.entries(route.responseHeaders || {}).forEach(([k, v])=>{
|
|
127
44
|
c.header(k, v);
|
|
128
45
|
});
|
|
129
|
-
|
|
130
|
-
if (preCompressedAsset.selected) c.header('Content-Encoding', preCompressedAsset.selected.encoding);
|
|
46
|
+
applyPreCompressedAssetHeaders(c, preCompressedAsset);
|
|
131
47
|
c.header('Content-Length', String(data.byteLength));
|
|
132
48
|
return c.body(body, 200);
|
|
133
49
|
}
|
|
@@ -147,91 +63,6 @@ const extractPathname = (url)=>{
|
|
|
147
63
|
return url;
|
|
148
64
|
}
|
|
149
65
|
};
|
|
150
|
-
const MODULE_FEDERATION_MANIFEST_FILE = 'mf-manifest.json';
|
|
151
|
-
const MODULE_FEDERATION_OPTIONAL_FILES = [
|
|
152
|
-
'mf-stats.json'
|
|
153
|
-
];
|
|
154
|
-
const trimLeadingSlash = (value)=>value.replace(/^\/+/, '');
|
|
155
|
-
const joinModuleFederationAssetPath = (assetPath, assetName)=>{
|
|
156
|
-
if (!assetName) return '';
|
|
157
|
-
return trimLeadingSlash(path.posix.join(assetPath || '', assetName));
|
|
158
|
-
};
|
|
159
|
-
const appendModuleFederationAsset = (set, assetPath)=>{
|
|
160
|
-
if (!assetPath) return;
|
|
161
|
-
set.add(trimLeadingSlash(assetPath));
|
|
162
|
-
};
|
|
163
|
-
const appendModuleFederationAssets = (set, assets)=>{
|
|
164
|
-
assets?.js?.sync?.forEach((asset)=>appendModuleFederationAsset(set, asset));
|
|
165
|
-
assets?.js?.async?.forEach((asset)=>appendModuleFederationAsset(set, asset));
|
|
166
|
-
assets?.css?.sync?.forEach((asset)=>appendModuleFederationAsset(set, asset));
|
|
167
|
-
assets?.css?.async?.forEach((asset)=>appendModuleFederationAsset(set, asset));
|
|
168
|
-
};
|
|
169
|
-
const hasAbsoluteProtocol = (value)=>/^https?:\/\//i.test(value) || value.startsWith('//');
|
|
170
|
-
const ensureLeadingSlash = (value)=>{
|
|
171
|
-
if ('' === value) return '/';
|
|
172
|
-
return value.startsWith('/') ? value : `/${value}`;
|
|
173
|
-
};
|
|
174
|
-
const ensureTrailingSlash = (value)=>value.endsWith('/') ? value : `${value}/`;
|
|
175
|
-
const patchModuleFederationManifestPublicPath = (c, manifestBuffer, pathPrefix)=>{
|
|
176
|
-
try {
|
|
177
|
-
const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
|
|
178
|
-
const publicPath = manifest.metaData?.publicPath;
|
|
179
|
-
if (!publicPath || hasAbsoluteProtocol(publicPath)) return manifestBuffer;
|
|
180
|
-
const requestURL = new URL(c.req.url);
|
|
181
|
-
const prefixPath = ensureTrailingSlash(ensureLeadingSlash(pathPrefix || '/'));
|
|
182
|
-
manifest.metaData = {
|
|
183
|
-
...manifest.metaData,
|
|
184
|
-
publicPath: `${requestURL.origin}${prefixPath}`
|
|
185
|
-
};
|
|
186
|
-
return Buffer.from(JSON.stringify(manifest), 'utf-8');
|
|
187
|
-
} catch {
|
|
188
|
-
return manifestBuffer;
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
const patchModuleFederationRemoteEntryPublicPath = (c, remoteEntryBuffer, pathPrefix)=>{
|
|
192
|
-
const requestURL = new URL(c.req.url);
|
|
193
|
-
const prefixPath = ensureTrailingSlash(ensureLeadingSlash(pathPrefix || '/'));
|
|
194
|
-
const publicPath = `${requestURL.origin}${prefixPath}`;
|
|
195
|
-
const source = remoteEntryBuffer.toString('utf-8');
|
|
196
|
-
const patched = source.replace(/__webpack_require__\.p\s*=\s*(['"`])[^'"`]*\1;/, `__webpack_require__.p = ${JSON.stringify(publicPath)};`).replace(/__rspack_require__\.p\s*=\s*(['"`])[^'"`]*\1;/, `__rspack_require__.p = ${JSON.stringify(publicPath)};`);
|
|
197
|
-
if (patched === source) return remoteEntryBuffer;
|
|
198
|
-
return Buffer.from(patched, 'utf-8');
|
|
199
|
-
};
|
|
200
|
-
const getModuleFederationAssetList = async (pwd)=>{
|
|
201
|
-
const assets = new Set();
|
|
202
|
-
const manifestPath = path.join(pwd, MODULE_FEDERATION_MANIFEST_FILE);
|
|
203
|
-
if (!await fs.pathExists(manifestPath)) return {
|
|
204
|
-
assets,
|
|
205
|
-
remoteEntry: null
|
|
206
|
-
};
|
|
207
|
-
assets.add(MODULE_FEDERATION_MANIFEST_FILE);
|
|
208
|
-
const manifestBuffer = await fileReader.readFileFromSystem(manifestPath, 'buffer');
|
|
209
|
-
if (null === manifestBuffer) return {
|
|
210
|
-
assets,
|
|
211
|
-
remoteEntry: null
|
|
212
|
-
};
|
|
213
|
-
for (const filename of MODULE_FEDERATION_OPTIONAL_FILES)if (await fs.pathExists(path.join(pwd, filename))) assets.add(filename);
|
|
214
|
-
let remoteEntryFile = null;
|
|
215
|
-
try {
|
|
216
|
-
const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
|
|
217
|
-
const remoteEntry = joinModuleFederationAssetPath(manifest.metaData?.remoteEntry?.path, manifest.metaData?.remoteEntry?.name);
|
|
218
|
-
const dtsZip = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.zip);
|
|
219
|
-
const dtsApi = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.api);
|
|
220
|
-
if (remoteEntry) {
|
|
221
|
-
assets.add(remoteEntry);
|
|
222
|
-
remoteEntryFile = remoteEntry;
|
|
223
|
-
}
|
|
224
|
-
if (dtsZip) assets.add(dtsZip);
|
|
225
|
-
if (dtsApi) assets.add(dtsApi);
|
|
226
|
-
manifest.shared?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
|
|
227
|
-
manifest.remotes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
|
|
228
|
-
manifest.exposes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
|
|
229
|
-
} catch {}
|
|
230
|
-
return {
|
|
231
|
-
assets,
|
|
232
|
-
remoteEntry: remoteEntryFile
|
|
233
|
-
};
|
|
234
|
-
};
|
|
235
66
|
function createStaticMiddleware(options) {
|
|
236
67
|
const { pwd, routes } = options;
|
|
237
68
|
const prefix = options.output.assetPrefix || '/';
|
|
@@ -272,14 +103,10 @@ function createStaticMiddleware(options) {
|
|
|
272
103
|
return moduleFederationAssetsPromise;
|
|
273
104
|
};
|
|
274
105
|
const serveFile = async (c, filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false, requestPath = '')=>{
|
|
275
|
-
if (moduleFederationAsset)
|
|
276
|
-
c.header('Access-Control-Allow-Origin', '*');
|
|
277
|
-
c.header('Access-Control-Allow-Headers', '*');
|
|
278
|
-
c.header('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS');
|
|
279
|
-
}
|
|
106
|
+
if (moduleFederationAsset) applyModuleFederationAssetHeaders(c);
|
|
280
107
|
const mimeType = getMimeType(filepath);
|
|
281
108
|
if (mimeType) c.header('Content-Type', mimeType);
|
|
282
|
-
const shouldPatchManifest = moduleFederationAsset && requestPath
|
|
109
|
+
const shouldPatchManifest = moduleFederationAsset && isModuleFederationManifestRequest(requestPath);
|
|
283
110
|
const shouldPatchRemoteEntry = moduleFederationRemoteEntry;
|
|
284
111
|
const canUsePreCompressed = !shouldPatchManifest && !shouldPatchRemoteEntry;
|
|
285
112
|
const preCompressedAsset = canUsePreCompressed ? await resolvePreCompressedAsset(c, filepath) : {
|
|
@@ -290,8 +117,7 @@ function createStaticMiddleware(options) {
|
|
|
290
117
|
const chunk = await fileReader.readFileFromSystem(targetFilepath, 'buffer');
|
|
291
118
|
if (null === chunk) return null;
|
|
292
119
|
const responseChunk = shouldPatchManifest ? patchModuleFederationManifestPublicPath(c, chunk, pathPrefix) : shouldPatchRemoteEntry ? patchModuleFederationRemoteEntryPublicPath(c, chunk, pathPrefix) : chunk;
|
|
293
|
-
|
|
294
|
-
if (preCompressedAsset.selected) c.header('Content-Encoding', preCompressedAsset.selected.encoding);
|
|
120
|
+
applyPreCompressedAssetHeaders(c, preCompressedAsset);
|
|
295
121
|
c.header('Content-Length', String(responseChunk.byteLength));
|
|
296
122
|
const body = new Uint8Array(responseChunk.buffer, responseChunk.byteOffset, responseChunk.byteLength);
|
|
297
123
|
return c.body(body, 200);
|
|
@@ -301,7 +127,7 @@ function createStaticMiddleware(options) {
|
|
|
301
127
|
const pathname = c.req.path;
|
|
302
128
|
if (pageRoute && '' === path.extname(pathname)) return next();
|
|
303
129
|
const hit = staticPathRegExp.test(pathname);
|
|
304
|
-
const requestPath =
|
|
130
|
+
const requestPath = getModuleFederationRequestPath(pathname, pathPrefix);
|
|
305
131
|
if (requestPath.includes('..')) return next();
|
|
306
132
|
const moduleFederationAssetMeta = await getModuleFederationAssets();
|
|
307
133
|
const isModuleFederationAsset = moduleFederationAssetMeta.assets.has(requestPath);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { fileReader } from "@modern-js/runtime-utils/fileReader";
|
|
3
|
+
import { fs } from "@modern-js/utils";
|
|
4
|
+
import path from "path";
|
|
5
|
+
const MODULE_FEDERATION_MANIFEST_FILE = 'mf-manifest.json';
|
|
6
|
+
const MODULE_FEDERATION_OPTIONAL_FILES = [
|
|
7
|
+
'mf-stats.json'
|
|
8
|
+
];
|
|
9
|
+
const trimLeadingSlash = (value)=>value.replace(/^\/+/, '');
|
|
10
|
+
const getModuleFederationRequestPath = (pathname, pathPrefix)=>trimLeadingSlash(pathname.replace(pathPrefix, ()=>''));
|
|
11
|
+
const isModuleFederationManifestRequest = (requestPath)=>requestPath === MODULE_FEDERATION_MANIFEST_FILE;
|
|
12
|
+
const applyModuleFederationAssetHeaders = (c)=>{
|
|
13
|
+
c.header('Access-Control-Allow-Origin', '*');
|
|
14
|
+
c.header('Access-Control-Allow-Headers', '*');
|
|
15
|
+
c.header('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS');
|
|
16
|
+
};
|
|
17
|
+
const joinModuleFederationAssetPath = (assetPath, assetName)=>{
|
|
18
|
+
if (!assetName) return '';
|
|
19
|
+
return trimLeadingSlash(path.posix.join(assetPath || '', assetName));
|
|
20
|
+
};
|
|
21
|
+
const appendModuleFederationAsset = (set, assetPath)=>{
|
|
22
|
+
if (!assetPath) return;
|
|
23
|
+
set.add(trimLeadingSlash(assetPath));
|
|
24
|
+
};
|
|
25
|
+
const appendModuleFederationAssets = (set, assets)=>{
|
|
26
|
+
assets?.js?.sync?.forEach((asset)=>appendModuleFederationAsset(set, asset));
|
|
27
|
+
assets?.js?.async?.forEach((asset)=>appendModuleFederationAsset(set, asset));
|
|
28
|
+
assets?.css?.sync?.forEach((asset)=>appendModuleFederationAsset(set, asset));
|
|
29
|
+
assets?.css?.async?.forEach((asset)=>appendModuleFederationAsset(set, asset));
|
|
30
|
+
};
|
|
31
|
+
const hasAbsoluteProtocol = (value)=>/^https?:\/\//i.test(value) || value.startsWith('//');
|
|
32
|
+
const ensureLeadingSlash = (value)=>{
|
|
33
|
+
if ('' === value) return '/';
|
|
34
|
+
return value.startsWith('/') ? value : `/${value}`;
|
|
35
|
+
};
|
|
36
|
+
const ensureTrailingSlash = (value)=>value.endsWith('/') ? value : `${value}/`;
|
|
37
|
+
const patchModuleFederationManifestPublicPath = (c, manifestBuffer, pathPrefix)=>{
|
|
38
|
+
try {
|
|
39
|
+
const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
|
|
40
|
+
const publicPath = manifest.metaData?.publicPath;
|
|
41
|
+
if (!publicPath || hasAbsoluteProtocol(publicPath)) return manifestBuffer;
|
|
42
|
+
const requestURL = new URL(c.req.url);
|
|
43
|
+
const prefixPath = ensureTrailingSlash(ensureLeadingSlash(pathPrefix || '/'));
|
|
44
|
+
manifest.metaData = {
|
|
45
|
+
...manifest.metaData,
|
|
46
|
+
publicPath: `${requestURL.origin}${prefixPath}`
|
|
47
|
+
};
|
|
48
|
+
return Buffer.from(JSON.stringify(manifest), 'utf-8');
|
|
49
|
+
} catch {
|
|
50
|
+
return manifestBuffer;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const patchModuleFederationRemoteEntryPublicPath = (c, remoteEntryBuffer, pathPrefix)=>{
|
|
54
|
+
const requestURL = new URL(c.req.url);
|
|
55
|
+
const prefixPath = ensureTrailingSlash(ensureLeadingSlash(pathPrefix || '/'));
|
|
56
|
+
const publicPath = `${requestURL.origin}${prefixPath}`;
|
|
57
|
+
const source = remoteEntryBuffer.toString('utf-8');
|
|
58
|
+
const patched = source.replace(/__webpack_require__\.p\s*=\s*(['"`])[^'"`]*\1;/, `__webpack_require__.p = ${JSON.stringify(publicPath)};`).replace(/__rspack_require__\.p\s*=\s*(['"`])[^'"`]*\1;/, `__rspack_require__.p = ${JSON.stringify(publicPath)};`);
|
|
59
|
+
if (patched === source) return remoteEntryBuffer;
|
|
60
|
+
return Buffer.from(patched, 'utf-8');
|
|
61
|
+
};
|
|
62
|
+
const getModuleFederationAssetList = async (pwd)=>{
|
|
63
|
+
const assets = new Set();
|
|
64
|
+
const manifestPath = path.join(pwd, MODULE_FEDERATION_MANIFEST_FILE);
|
|
65
|
+
if (!await fs.pathExists(manifestPath)) return {
|
|
66
|
+
assets,
|
|
67
|
+
remoteEntry: null
|
|
68
|
+
};
|
|
69
|
+
assets.add(MODULE_FEDERATION_MANIFEST_FILE);
|
|
70
|
+
const manifestBuffer = await fileReader.readFileFromSystem(manifestPath, 'buffer');
|
|
71
|
+
if (null === manifestBuffer) return {
|
|
72
|
+
assets,
|
|
73
|
+
remoteEntry: null
|
|
74
|
+
};
|
|
75
|
+
for (const filename of MODULE_FEDERATION_OPTIONAL_FILES)if (await fs.pathExists(path.join(pwd, filename))) assets.add(filename);
|
|
76
|
+
let remoteEntryFile = null;
|
|
77
|
+
try {
|
|
78
|
+
const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
|
|
79
|
+
const remoteEntry = joinModuleFederationAssetPath(manifest.metaData?.remoteEntry?.path, manifest.metaData?.remoteEntry?.name);
|
|
80
|
+
const dtsZip = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.zip);
|
|
81
|
+
const dtsApi = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.api);
|
|
82
|
+
if (remoteEntry) {
|
|
83
|
+
assets.add(remoteEntry);
|
|
84
|
+
remoteEntryFile = remoteEntry;
|
|
85
|
+
}
|
|
86
|
+
if (dtsZip) assets.add(dtsZip);
|
|
87
|
+
if (dtsApi) assets.add(dtsApi);
|
|
88
|
+
manifest.shared?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
|
|
89
|
+
manifest.remotes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
|
|
90
|
+
manifest.exposes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
|
|
91
|
+
} catch {}
|
|
92
|
+
return {
|
|
93
|
+
assets,
|
|
94
|
+
remoteEntry: remoteEntryFile
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
export { MODULE_FEDERATION_MANIFEST_FILE, applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath, trimLeadingSlash };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { fs } from "@modern-js/utils";
|
|
3
|
+
const PRE_COMPRESSED_ASSET_EXTENSIONS = {
|
|
4
|
+
br: '.br',
|
|
5
|
+
gzip: '.gz'
|
|
6
|
+
};
|
|
7
|
+
const PRE_COMPRESSED_SUPPORTED_ENCODINGS = [
|
|
8
|
+
'br',
|
|
9
|
+
'gzip'
|
|
10
|
+
];
|
|
11
|
+
const parseAcceptEncoding = (value)=>value.split(',').map((item)=>item.trim()).filter(Boolean).map((item)=>{
|
|
12
|
+
const [rawName, ...params] = item.split(';');
|
|
13
|
+
const name = rawName.trim().toLowerCase();
|
|
14
|
+
let q = 1;
|
|
15
|
+
for (const param of params){
|
|
16
|
+
const [key, rawValue] = param.split('=').map((v)=>v.trim());
|
|
17
|
+
if ('q' !== key.toLowerCase() || null == rawValue) continue;
|
|
18
|
+
const parsedQ = Number(rawValue);
|
|
19
|
+
if (!Number.isNaN(parsedQ)) q = Math.max(0, Math.min(parsedQ, 1));
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
name,
|
|
23
|
+
q
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
const getAcceptedEncodings = (value)=>{
|
|
27
|
+
if (!value) return [];
|
|
28
|
+
const parsed = parseAcceptEncoding(value);
|
|
29
|
+
const qualityByEncoding = new Map();
|
|
30
|
+
let wildcardQuality;
|
|
31
|
+
for (const { name, q } of parsed){
|
|
32
|
+
if ('*' === name) {
|
|
33
|
+
wildcardQuality = q;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
qualityByEncoding.set(name, q);
|
|
37
|
+
}
|
|
38
|
+
const getQuality = (encoding)=>{
|
|
39
|
+
const explicit = qualityByEncoding.get(encoding);
|
|
40
|
+
if (void 0 !== explicit) return explicit;
|
|
41
|
+
return wildcardQuality ?? 0;
|
|
42
|
+
};
|
|
43
|
+
return PRE_COMPRESSED_SUPPORTED_ENCODINGS.map((encoding)=>({
|
|
44
|
+
encoding,
|
|
45
|
+
quality: getQuality(encoding)
|
|
46
|
+
})).filter((item)=>item.quality > 0).sort((a, b)=>b.quality - a.quality).map((item)=>item.encoding);
|
|
47
|
+
};
|
|
48
|
+
const appendVaryHeader = (c, value)=>{
|
|
49
|
+
const current = c.res.headers.get('Vary');
|
|
50
|
+
if (!current) return void c.header('Vary', value);
|
|
51
|
+
const values = current.split(',').map((item)=>item.trim().toLowerCase()).filter(Boolean);
|
|
52
|
+
if (!values.includes(value.toLowerCase())) c.header('Vary', `${current}, ${value}`);
|
|
53
|
+
};
|
|
54
|
+
const resolvePreCompressedAsset = async (c, filepath)=>{
|
|
55
|
+
const brPath = `${filepath}${PRE_COMPRESSED_ASSET_EXTENSIONS.br}`;
|
|
56
|
+
const gzipPath = `${filepath}${PRE_COMPRESSED_ASSET_EXTENSIONS.gzip}`;
|
|
57
|
+
const [hasBr, hasGzip] = await Promise.all([
|
|
58
|
+
fs.pathExists(brPath),
|
|
59
|
+
fs.pathExists(gzipPath)
|
|
60
|
+
]);
|
|
61
|
+
const hasVariant = hasBr || hasGzip;
|
|
62
|
+
if (!hasVariant) return {
|
|
63
|
+
selected: null,
|
|
64
|
+
hasVariant: false
|
|
65
|
+
};
|
|
66
|
+
const acceptedEncodings = getAcceptedEncodings(c.req.header('accept-encoding'));
|
|
67
|
+
for (const encoding of acceptedEncodings){
|
|
68
|
+
if ('br' === encoding && hasBr) return {
|
|
69
|
+
selected: {
|
|
70
|
+
filepath: brPath,
|
|
71
|
+
encoding
|
|
72
|
+
},
|
|
73
|
+
hasVariant: true
|
|
74
|
+
};
|
|
75
|
+
if ('gzip' === encoding && hasGzip) return {
|
|
76
|
+
selected: {
|
|
77
|
+
filepath: gzipPath,
|
|
78
|
+
encoding
|
|
79
|
+
},
|
|
80
|
+
hasVariant: true
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
selected: null,
|
|
85
|
+
hasVariant: true
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const applyPreCompressedAssetHeaders = (c, preCompressedAsset)=>{
|
|
89
|
+
if (preCompressedAsset.hasVariant) appendVaryHeader(c, 'Accept-Encoding');
|
|
90
|
+
if (preCompressedAsset.selected) c.header('Content-Encoding', preCompressedAsset.selected.encoding);
|
|
91
|
+
};
|
|
92
|
+
export { appendVaryHeader, applyPreCompressedAssetHeaders, resolvePreCompressedAsset };
|
package/dist/esm-node/index.mjs
CHANGED
|
@@ -9,5 +9,5 @@ export { AGGRED_DIR } from "./constants.mjs";
|
|
|
9
9
|
export { run, useHonoContext } from "./context.mjs";
|
|
10
10
|
export { getLoaderCtx } from "./helper.mjs";
|
|
11
11
|
export { createServerBase } from "./serverBase.mjs";
|
|
12
|
-
export { ErrorDigest, createErrorHtml, onError } from "./utils/index.mjs";
|
|
12
|
+
export { ErrorDigest, createErrorHtml, createSafeFailureHttpResult, createSafeJsonFailureResponse, getSafeFailureStatus, onError } from "./utils/index.mjs";
|
|
13
13
|
export { getPublicDirConfig, getPublicDirPatterns, getPublicDirRoutePrefixes, normalizePublicDir, normalizePublicDirPath, resolvePublicDirPaths } from "./utils/publicDir.mjs";
|
|
@@ -5,7 +5,6 @@ import { initMonitorsPlugin, injectServerTiming, injectloggerPlugin } from "./mo
|
|
|
5
5
|
import { processedByPlugin } from "./processedBy.mjs";
|
|
6
6
|
import { injectRenderHandlerPlugin } from "./render/index.mjs";
|
|
7
7
|
import { injectRoutePlugin } from "./route.mjs";
|
|
8
|
-
import { injectTelemetryPlugin } from "./telemetry.mjs";
|
|
9
8
|
function createSilenceLogger() {
|
|
10
9
|
return new Proxy({}, {
|
|
11
10
|
get: ()=>()=>{}
|
|
@@ -16,7 +15,6 @@ function createDefaultPlugins(options = {}) {
|
|
|
16
15
|
compatPlugin(),
|
|
17
16
|
logPlugin(),
|
|
18
17
|
initMonitorsPlugin(),
|
|
19
|
-
injectTelemetryPlugin(),
|
|
20
18
|
injectRenderHandlerPlugin(options),
|
|
21
19
|
injectloggerPlugin(options.logger ? options.logger : createSilenceLogger()),
|
|
22
20
|
injectServerTiming(),
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
export { compatPlugin, handleSetupResult } from "./compat/index.mjs";
|
|
3
|
-
export { ContractGateAutopilot } from "./contractGateAutopilot.mjs";
|
|
4
|
-
export { CONTRACT_GATE_SNAPSHOT_SCHEMA_VERSION, DEFAULT_CONTRACT_GATE_SNAPSHOT_PATH, createFileContractGateSnapshotStore, createHttpContractGateSnapshotStore, resolveContractGateSnapshotPath, resolveContractGateSnapshotStore } from "./contractGateSnapshotStore.mjs";
|
|
5
3
|
export { createDefaultPlugins } from "./default.mjs";
|
|
6
4
|
export { faviconPlugin } from "./favicon.mjs";
|
|
7
5
|
export { logPlugin } from "./log.mjs";
|
|
@@ -9,4 +7,3 @@ export { injectConfigMiddlewarePlugin } from "./middlewares.mjs";
|
|
|
9
7
|
export { injectServerTiming, injectloggerPlugin } from "./monitors.mjs";
|
|
10
8
|
export { processedByPlugin } from "./processedBy.mjs";
|
|
11
9
|
export { getRenderHandler, injectRenderHandlerPlugin, renderPlugin } from "./render/index.mjs";
|
|
12
|
-
export { DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT, DEFAULT_RUNTIME_STATUS_ENDPOINT, TelemetryCanaryOrchestrator, TelemetryRegistry, TelemetryStartupHealthError, createOtlpTelemetryExporter, createRuntimeFallbackSignalRuntimeState, createRuntimeSignalError, createTelemetryAwareMetrics, createVictoriaMetricsTelemetryExporter, enforceRuntimeFallbackSignalAuthToken, enforceRuntimeFallbackSignalTrustPolicy, getRuntimeSignalErrorStatusCode, hasEnabledTelemetryExporters, injectTelemetryPlugin, normalizeRuntimeFallbackSignalAuthConfig, normalizeRuntimeFallbackTrustPolicy, parseRuntimeFallbackSignalPayloadFromRawBody, resolveRuntimeFallbackSignalEndpoint } from "./telemetry.mjs";
|
|
@@ -8,10 +8,11 @@ const injectRenderHandlerPlugin = ({ staticGenerate, cacheConfig })=>({
|
|
|
8
8
|
const config = api.getServerConfig();
|
|
9
9
|
const hooks = api.getHooks();
|
|
10
10
|
if (!routes) return;
|
|
11
|
-
const onFallback = async (reason, error)=>{
|
|
11
|
+
const onFallback = async (reason, error, context)=>{
|
|
12
12
|
await hooks.fallback.call({
|
|
13
13
|
reason,
|
|
14
|
-
error
|
|
14
|
+
error,
|
|
15
|
+
context
|
|
15
16
|
});
|
|
16
17
|
};
|
|
17
18
|
const getRenderHandlerOptions = {
|
|
@@ -76,9 +76,13 @@ async function createRender({ routes, pwd, metaName, staticGenerate, cacheConfig
|
|
|
76
76
|
const framework = cutNameByHyphen(metaName || 'modern-js');
|
|
77
77
|
const fallbackHeader = `x-${framework}-ssr-fallback`;
|
|
78
78
|
let fallbackReason = null;
|
|
79
|
+
const fallbackContext = {
|
|
80
|
+
request: req,
|
|
81
|
+
monitors
|
|
82
|
+
};
|
|
79
83
|
const fallbackWrapper = async (reason, error)=>{
|
|
80
84
|
fallbackReason = reason;
|
|
81
|
-
return onFallback?.(reason, error);
|
|
85
|
+
return onFallback?.(reason, error, fallbackContext);
|
|
82
86
|
};
|
|
83
87
|
if (!routeInfo) return new Response(createErrorHtml(404), {
|
|
84
88
|
status: 404,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "node:module";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "node:module";
|
|
@@ -4,6 +4,59 @@ const ERROR_PAGE_TEXT = {
|
|
|
4
4
|
404: 'This page could not be found.',
|
|
5
5
|
500: 'Internal Server Error.'
|
|
6
6
|
};
|
|
7
|
+
const SAFE_FAILURE_MESSAGES = {
|
|
8
|
+
500: 'Internal Server Error',
|
|
9
|
+
503: 'Service Unavailable'
|
|
10
|
+
};
|
|
11
|
+
const SAFE_FAILURE_CODES = {
|
|
12
|
+
500: 'INTERNAL_SERVER_ERROR',
|
|
13
|
+
503: 'SERVICE_UNAVAILABLE'
|
|
14
|
+
};
|
|
15
|
+
const readErrorProperty = (error, key)=>{
|
|
16
|
+
if ('object' != typeof error || null === error || !(key in error)) return;
|
|
17
|
+
return error[key];
|
|
18
|
+
};
|
|
19
|
+
const normalizeFailureStatus = (value)=>{
|
|
20
|
+
if ('number' != typeof value || !Number.isInteger(value)) return;
|
|
21
|
+
return value >= 400 && value <= 599 ? value : void 0;
|
|
22
|
+
};
|
|
23
|
+
const normalizeRetryAfter = (value)=>{
|
|
24
|
+
if ('number' == typeof value && Number.isFinite(value) && value >= 0) return String(Math.ceil(value));
|
|
25
|
+
if ('string' == typeof value) {
|
|
26
|
+
const trimmed = value.trim();
|
|
27
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
28
|
+
}
|
|
29
|
+
if (value instanceof Date) return value.toUTCString();
|
|
30
|
+
};
|
|
31
|
+
const getSafeFailureStatus = (error)=>normalizeFailureStatus(readErrorProperty(error, 'status')) ?? normalizeFailureStatus(readErrorProperty(error, 'statusCode')) ?? 500;
|
|
32
|
+
const createSafeFailureHttpResult = (error)=>{
|
|
33
|
+
const status = getSafeFailureStatus(error);
|
|
34
|
+
const retryAfter = 503 === status ? normalizeRetryAfter(readErrorProperty(error, 'retryAfter')) ?? normalizeRetryAfter(readErrorProperty(error, 'retryAfterSeconds')) ?? normalizeRetryAfter('number' == typeof readErrorProperty(error, 'retryAfterMs') ? readErrorProperty(error, 'retryAfterMs') / 1000 : void 0) : void 0;
|
|
35
|
+
return {
|
|
36
|
+
status,
|
|
37
|
+
body: {
|
|
38
|
+
success: false,
|
|
39
|
+
error: {
|
|
40
|
+
code: SAFE_FAILURE_CODES[status] ?? 'REQUEST_FAILED',
|
|
41
|
+
message: SAFE_FAILURE_MESSAGES[status] ?? 'Request failed',
|
|
42
|
+
status
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
headers: {
|
|
46
|
+
'content-type': 'application/json; charset=utf-8',
|
|
47
|
+
...retryAfter ? {
|
|
48
|
+
'Retry-After': retryAfter
|
|
49
|
+
} : {}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const createSafeJsonFailureResponse = (error)=>{
|
|
54
|
+
const result = createSafeFailureHttpResult(error);
|
|
55
|
+
return new Response(JSON.stringify(result.body), {
|
|
56
|
+
status: result.status,
|
|
57
|
+
headers: result.headers
|
|
58
|
+
});
|
|
59
|
+
};
|
|
7
60
|
const createErrorHtml = (status)=>{
|
|
8
61
|
const text = ERROR_PAGE_TEXT[status] || '';
|
|
9
62
|
const title = `${status}: ${text}`;
|
|
@@ -51,4 +104,4 @@ function onError(digest, error, monitors, req) {
|
|
|
51
104
|
else if (req) console.error(`Server Error - ${digest}, error = ${error instanceof Error ? error.stack || error.message : error}, req.url = ${req.url}, req.headers = ${JSON.stringify(headerData)}`);
|
|
52
105
|
else console.error(`Server Error - ${digest}, error = ${error instanceof Error ? error.stack || error.message : error} `);
|
|
53
106
|
}
|
|
54
|
-
export { createErrorHtml, error_ErrorDigest as ErrorDigest, onError };
|
|
107
|
+
export { createErrorHtml, createSafeFailureHttpResult, createSafeJsonFailureResponse, error_ErrorDigest as ErrorDigest, getSafeFailureStatus, onError };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Middleware } from '../../../types';
|
|
2
|
+
export declare const MODULE_FEDERATION_MANIFEST_FILE = "mf-manifest.json";
|
|
3
|
+
export type ModuleFederationServeAssets = {
|
|
4
|
+
assets: Set<string>;
|
|
5
|
+
remoteEntry: string | null;
|
|
6
|
+
};
|
|
7
|
+
export declare const trimLeadingSlash: (value: string) => string;
|
|
8
|
+
export declare const getModuleFederationRequestPath: (pathname: string, pathPrefix: string) => string;
|
|
9
|
+
export declare const isModuleFederationManifestRequest: (requestPath: string) => requestPath is "mf-manifest.json";
|
|
10
|
+
export declare const applyModuleFederationAssetHeaders: (c: Parameters<Middleware>[0]) => void;
|
|
11
|
+
export declare const patchModuleFederationManifestPublicPath: (c: Parameters<Middleware>[0], manifestBuffer: Buffer, pathPrefix: string) => Buffer<ArrayBufferLike>;
|
|
12
|
+
export declare const patchModuleFederationRemoteEntryPublicPath: (c: Parameters<Middleware>[0], remoteEntryBuffer: Buffer, pathPrefix: string) => Buffer<ArrayBufferLike>;
|
|
13
|
+
export declare const getModuleFederationAssetList: (pwd: string) => Promise<ModuleFederationServeAssets>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Middleware } from '../../../types';
|
|
2
|
+
type SupportedEncoding = 'br' | 'gzip';
|
|
3
|
+
export type ResolvePreCompressedAssetResult = {
|
|
4
|
+
selected: {
|
|
5
|
+
filepath: string;
|
|
6
|
+
encoding: SupportedEncoding;
|
|
7
|
+
} | null;
|
|
8
|
+
hasVariant: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare const appendVaryHeader: (c: Parameters<Middleware>[0], value: string) => void;
|
|
11
|
+
export declare const resolvePreCompressedAsset: (c: Parameters<Middleware>[0], filepath: string) => Promise<ResolvePreCompressedAssetResult>;
|
|
12
|
+
export declare const applyPreCompressedAssetHeaders: (c: Parameters<Middleware>[0], preCompressedAsset: ResolvePreCompressedAssetResult) => void;
|
|
13
|
+
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -10,5 +10,6 @@ export * from './types/config';
|
|
|
10
10
|
export * from './types/plugins';
|
|
11
11
|
export * from './types/render';
|
|
12
12
|
export * from './types/requestHandler';
|
|
13
|
-
export {
|
|
13
|
+
export type { SafeFailureEnvelope, SafeFailureHttpResult } from './utils';
|
|
14
|
+
export { createErrorHtml, createSafeFailureHttpResult, createSafeJsonFailureResponse, ErrorDigest, getSafeFailureStatus, onError, } from './utils';
|
|
14
15
|
export { getPublicDirConfig, getPublicDirPatterns, getPublicDirRoutePrefixes, normalizePublicDir, normalizePublicDirPath, resolvePublicDirPaths, } from './utils/publicDir';
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
export { compatPlugin, handleSetupResult } from './compat';
|
|
2
|
-
export { ContractGateAutopilot, type ContractGateAutopilotOptions, } from './contractGateAutopilot';
|
|
3
|
-
export { CONTRACT_GATE_SNAPSHOT_SCHEMA_VERSION, type ContractGateSnapshotHttpStoreOptions, type ContractGateSnapshotStore, type ContractGateSnapshotStoreFactory, type ContractGateSnapshotStoreFactoryContext, type ContractGateSnapshotStoreModule, type ContractGateSnapshotStoreUserConfig, createFileContractGateSnapshotStore, createHttpContractGateSnapshotStore, DEFAULT_CONTRACT_GATE_SNAPSHOT_PATH, type GateSnapshot, type GateSnapshotGateValue, resolveContractGateSnapshotPath, resolveContractGateSnapshotStore, } from './contractGateSnapshotStore';
|
|
4
2
|
export { type CreateDefaultPluginsOptions, createDefaultPlugins, } from './default';
|
|
5
3
|
export { faviconPlugin } from './favicon';
|
|
6
4
|
export { logPlugin } from './log';
|
|
@@ -8,4 +6,3 @@ export { injectConfigMiddlewarePlugin } from './middlewares';
|
|
|
8
6
|
export { injectloggerPlugin, injectServerTiming } from './monitors';
|
|
9
7
|
export { processedByPlugin } from './processedBy';
|
|
10
8
|
export { getRenderHandler, type InjectRenderHandlerOptions, injectRenderHandlerPlugin, renderPlugin, } from './render';
|
|
11
|
-
export { createOtlpTelemetryExporter, createRuntimeFallbackSignalRuntimeState, createRuntimeSignalError, createTelemetryAwareMetrics, createVictoriaMetricsTelemetryExporter, DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT, DEFAULT_RUNTIME_STATUS_ENDPOINT, enforceRuntimeFallbackSignalAuthToken, enforceRuntimeFallbackSignalTrustPolicy, getRuntimeSignalErrorStatusCode, hasEnabledTelemetryExporters, injectTelemetryPlugin, normalizeRuntimeFallbackSignalAuthConfig, normalizeRuntimeFallbackTrustPolicy, type OtlpExporterOptions, parseRuntimeFallbackSignalPayloadFromRawBody, type RuntimeFallbackSignalAuthConfig, type RuntimeFallbackSignalRuntimeState, type RuntimeFallbackSignalTrustContext, type RuntimeFallbackSignalTrustPolicy, type RuntimeSignalError, type RuntimeSignalErrorCode, resolveRuntimeFallbackSignalEndpoint, type TelemetryCanaryDecision, TelemetryCanaryOrchestrator, type TelemetryCanaryStatusSnapshot, type TelemetryEnvelope, type TelemetryExporter, type TelemetryQueueStats, TelemetryRegistry, type TelemetryRegistryOptions, type TelemetrySignalType, type TelemetrySloAlert, TelemetryStartupHealthError, type VictoriaMetricsExporterOptions, } from './telemetry';
|