rankdeploy-middleware 1.0.0 → 1.2.0
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/{chunk-FPOJYG2E.mjs → chunk-C43DAMVJ.mjs} +19 -8
- package/dist/chunk-C43DAMVJ.mjs.map +1 -0
- package/dist/express.js +21 -13
- package/dist/express.js.map +1 -1
- package/dist/express.mjs +5 -8
- package/dist/express.mjs.map +1 -1
- package/dist/index.js +17 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/netlify.js +22 -16
- package/dist/netlify.js.map +1 -1
- package/dist/netlify.mjs +6 -11
- package/dist/netlify.mjs.map +1 -1
- package/dist/next.js +26 -15
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +9 -8
- package/dist/next.mjs.map +1 -1
- package/package.json +15 -3
- package/dist/chunk-FPOJYG2E.mjs.map +0 -1
- package/dist/express.d.mts +0 -34
- package/dist/express.d.ts +0 -34
- package/dist/index.d.mts +0 -41
- package/dist/index.d.ts +0 -41
- package/dist/netlify.d.mts +0 -16
- package/dist/netlify.d.ts +0 -16
- package/dist/next.d.mts +0 -25
- package/dist/next.d.ts +0 -25
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
var RANKDEPLOY_API = "https://proxy.unikium.com";
|
|
3
|
+
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
3
4
|
var BOT_USER_AGENTS = [
|
|
4
5
|
"googlebot",
|
|
5
6
|
"bingbot",
|
|
@@ -30,9 +31,20 @@ var BOT_USER_AGENTS = [
|
|
|
30
31
|
"anthropic",
|
|
31
32
|
"claudebot",
|
|
32
33
|
"perplexitybot",
|
|
33
|
-
"cohere"
|
|
34
|
+
"cohere",
|
|
35
|
+
// SEO tools & OG checkers
|
|
36
|
+
"opengraph",
|
|
37
|
+
"metatags",
|
|
38
|
+
"preview",
|
|
39
|
+
"crawler",
|
|
40
|
+
"spider",
|
|
41
|
+
"fetch",
|
|
42
|
+
"curl",
|
|
43
|
+
"wget",
|
|
44
|
+
"python-requests",
|
|
45
|
+
"node-fetch",
|
|
46
|
+
"axios"
|
|
34
47
|
];
|
|
35
|
-
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
36
48
|
function isBot(userAgent, extraBots) {
|
|
37
49
|
const ua = userAgent.toLowerCase();
|
|
38
50
|
const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;
|
|
@@ -45,14 +57,13 @@ function isExcluded(pathname, excludePaths) {
|
|
|
45
57
|
if (!excludePaths) return false;
|
|
46
58
|
return excludePaths.some((p) => pathname.startsWith(p));
|
|
47
59
|
}
|
|
48
|
-
async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
60
|
+
async function fetchPrerendered(url, userAgent, siteKey, apiUrl = RANKDEPLOY_API) {
|
|
49
61
|
try {
|
|
50
62
|
const res = await fetch(
|
|
51
|
-
`${apiUrl}/render?url=${encodeURIComponent(url)}`,
|
|
63
|
+
`${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,
|
|
52
64
|
{
|
|
53
|
-
headers: { "User-Agent": userAgent },
|
|
65
|
+
headers: { "User-Agent": userAgent || "Googlebot/2.1" },
|
|
54
66
|
signal: AbortSignal.timeout(1e4)
|
|
55
|
-
// 10s timeout
|
|
56
67
|
}
|
|
57
68
|
);
|
|
58
69
|
if (res.status === 200) {
|
|
@@ -66,11 +77,11 @@ async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
|
66
77
|
|
|
67
78
|
export {
|
|
68
79
|
RANKDEPLOY_API,
|
|
69
|
-
BOT_USER_AGENTS,
|
|
70
80
|
STATIC_EXTENSIONS,
|
|
81
|
+
BOT_USER_AGENTS,
|
|
71
82
|
isBot,
|
|
72
83
|
isStaticAsset,
|
|
73
84
|
isExcluded,
|
|
74
85
|
fetchPrerendered
|
|
75
86
|
};
|
|
76
|
-
//# sourceMappingURL=chunk-
|
|
87
|
+
//# sourceMappingURL=chunk-C43DAMVJ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * rankdeploy-middleware — Core SEO middleware engine\n *\n * Serves pre-rendered HTML with SEO overrides to all visitors.\n * The pre-rendered HTML is visually identical to the original page\n * but includes injected meta tags (title, description, canonical, og:tags).\n */\n\nexport const RANKDEPLOY_API = \"https://proxy.unikium.com\";\n\nexport const STATIC_EXTENSIONS = /\\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;\n\nexport interface RankDeployOptions {\n /** Your site key from Rank Deploy dashboard (required) */\n siteKey: string;\n /** Rank Deploy API URL. Default: https://proxy.unikium.com */\n apiUrl?: string;\n /** Paths to exclude from pre-rendering */\n excludePaths?: string[];\n /** Only serve to bots (default: false — serves to everyone for OG checker compatibility) */\n botsOnly?: boolean;\n /** Additional bot user agents to detect (used when botsOnly=true) */\n extraBots?: string[];\n}\n\nexport const BOT_USER_AGENTS = [\n \"googlebot\", \"bingbot\", \"yandexbot\", \"duckduckbot\", \"baiduspider\",\n \"slurp\", \"sogou\", \"exabot\",\n \"facebot\", \"facebookexternalhit\", \"twitterbot\", \"linkedinbot\",\n \"whatsapp\", \"telegrambot\", \"applebot\", \"discordbot\", \"slackbot\", \"pinterest\",\n \"screaming frog\", \"ahrefs\", \"semrush\", \"moz.com\", \"rogerbot\", \"dotbot\",\n \"gptbot\", \"chatgpt\", \"anthropic\", \"claudebot\", \"perplexitybot\", \"cohere\",\n // SEO tools & OG checkers\n \"opengraph\", \"metatags\", \"preview\", \"crawler\", \"spider\", \"fetch\",\n \"curl\", \"wget\", \"python-requests\", \"node-fetch\", \"axios\",\n];\n\nexport function isBot(userAgent: string, extraBots?: string[]): boolean {\n const ua = userAgent.toLowerCase();\n const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;\n return allBots.some((bot) => ua.includes(bot));\n}\n\nexport function isStaticAsset(pathname: string): boolean {\n return STATIC_EXTENSIONS.test(pathname);\n}\n\nexport function isExcluded(pathname: string, excludePaths?: string[]): boolean {\n if (!excludePaths) return false;\n return excludePaths.some((p) => pathname.startsWith(p));\n}\n\n/**\n * Fetch pre-rendered HTML from Rank Deploy API.\n */\nexport async function fetchPrerendered(\n url: string,\n userAgent: string,\n siteKey: string,\n apiUrl = RANKDEPLOY_API,\n): Promise<string | null> {\n try {\n const res = await fetch(\n `${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,\n {\n headers: { \"User-Agent\": userAgent || \"Googlebot/2.1\" },\n signal: AbortSignal.timeout(10_000),\n },\n );\n\n if (res.status === 200) {\n return res.text();\n }\n return null;\n } catch {\n return null;\n }\n}\n"],"mappings":";AAQO,IAAM,iBAAiB;AAEvB,IAAM,oBAAoB;AAe1B,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EAAa;AAAA,EAAW;AAAA,EAAa;AAAA,EAAe;AAAA,EACpD;AAAA,EAAS;AAAA,EAAS;AAAA,EAClB;AAAA,EAAW;AAAA,EAAuB;AAAA,EAAc;AAAA,EAChD;AAAA,EAAY;AAAA,EAAe;AAAA,EAAY;AAAA,EAAc;AAAA,EAAY;AAAA,EACjE;AAAA,EAAkB;AAAA,EAAU;AAAA,EAAW;AAAA,EAAW;AAAA,EAAY;AAAA,EAC9D;AAAA,EAAU;AAAA,EAAW;AAAA,EAAa;AAAA,EAAa;AAAA,EAAiB;AAAA;AAAA,EAEhE;AAAA,EAAa;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAAU;AAAA,EACzD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAmB;AAAA,EAAc;AACnD;AAEO,SAAS,MAAM,WAAmB,WAA+B;AACtE,QAAM,KAAK,UAAU,YAAY;AACjC,QAAM,UAAU,YAAY,CAAC,GAAG,iBAAiB,GAAG,SAAS,IAAI;AACjE,SAAO,QAAQ,KAAK,CAAC,QAAQ,GAAG,SAAS,GAAG,CAAC;AAC/C;AAEO,SAAS,cAAc,UAA2B;AACvD,SAAO,kBAAkB,KAAK,QAAQ;AACxC;AAEO,SAAS,WAAW,UAAkB,cAAkC;AAC7E,MAAI,CAAC,aAAc,QAAO;AAC1B,SAAO,aAAa,KAAK,CAAC,MAAM,SAAS,WAAW,CAAC,CAAC;AACxD;AAKA,eAAsB,iBACpB,KACA,WACA,SACA,SAAS,gBACe;AACxB,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAG,MAAM,eAAe,mBAAmB,GAAG,CAAC,QAAQ,mBAAmB,OAAO,CAAC;AAAA,MAClF;AAAA,QACE,SAAS,EAAE,cAAc,aAAa,gBAAgB;AAAA,QACtD,QAAQ,YAAY,QAAQ,GAAM;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,KAAK;AACtB,aAAO,IAAI,KAAK;AAAA,IAClB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/dist/express.js
CHANGED
|
@@ -27,6 +27,7 @@ module.exports = __toCommonJS(express_exports);
|
|
|
27
27
|
|
|
28
28
|
// src/index.ts
|
|
29
29
|
var RANKDEPLOY_API = "https://proxy.unikium.com";
|
|
30
|
+
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
30
31
|
var BOT_USER_AGENTS = [
|
|
31
32
|
"googlebot",
|
|
32
33
|
"bingbot",
|
|
@@ -57,9 +58,20 @@ var BOT_USER_AGENTS = [
|
|
|
57
58
|
"anthropic",
|
|
58
59
|
"claudebot",
|
|
59
60
|
"perplexitybot",
|
|
60
|
-
"cohere"
|
|
61
|
+
"cohere",
|
|
62
|
+
// SEO tools & OG checkers
|
|
63
|
+
"opengraph",
|
|
64
|
+
"metatags",
|
|
65
|
+
"preview",
|
|
66
|
+
"crawler",
|
|
67
|
+
"spider",
|
|
68
|
+
"fetch",
|
|
69
|
+
"curl",
|
|
70
|
+
"wget",
|
|
71
|
+
"python-requests",
|
|
72
|
+
"node-fetch",
|
|
73
|
+
"axios"
|
|
61
74
|
];
|
|
62
|
-
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
63
75
|
function isBot(userAgent, extraBots) {
|
|
64
76
|
const ua = userAgent.toLowerCase();
|
|
65
77
|
const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;
|
|
@@ -72,14 +84,13 @@ function isExcluded(pathname, excludePaths) {
|
|
|
72
84
|
if (!excludePaths) return false;
|
|
73
85
|
return excludePaths.some((p) => pathname.startsWith(p));
|
|
74
86
|
}
|
|
75
|
-
async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
87
|
+
async function fetchPrerendered(url, userAgent, siteKey, apiUrl = RANKDEPLOY_API) {
|
|
76
88
|
try {
|
|
77
89
|
const res = await fetch(
|
|
78
|
-
`${apiUrl}/render?url=${encodeURIComponent(url)}`,
|
|
90
|
+
`${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,
|
|
79
91
|
{
|
|
80
|
-
headers: { "User-Agent": userAgent },
|
|
92
|
+
headers: { "User-Agent": userAgent || "Googlebot/2.1" },
|
|
81
93
|
signal: AbortSignal.timeout(1e4)
|
|
82
|
-
// 10s timeout
|
|
83
94
|
}
|
|
84
95
|
);
|
|
85
96
|
if (res.status === 200) {
|
|
@@ -92,23 +103,20 @@ async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
|
92
103
|
}
|
|
93
104
|
|
|
94
105
|
// src/express.ts
|
|
95
|
-
function rankdeploy(options
|
|
106
|
+
function rankdeploy(options) {
|
|
96
107
|
return async function middleware(req, res, next) {
|
|
97
108
|
const userAgent = req.headers["user-agent"] || req.get?.("user-agent") || "";
|
|
98
109
|
const pathname = req.url.split("?")[0];
|
|
99
|
-
if (
|
|
100
|
-
return next();
|
|
101
|
-
}
|
|
102
|
-
if (isStaticAsset(pathname)) {
|
|
110
|
+
if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {
|
|
103
111
|
return next();
|
|
104
112
|
}
|
|
105
|
-
if (
|
|
113
|
+
if (options.botsOnly && !isBot(userAgent, options.extraBots)) {
|
|
106
114
|
return next();
|
|
107
115
|
}
|
|
108
116
|
const protocol = req.protocol || "https";
|
|
109
117
|
const host = req.get?.("host") || req.headers.host || "";
|
|
110
118
|
const fullUrl = `${protocol}://${host}${req.url}`;
|
|
111
|
-
const html = await fetchPrerendered(fullUrl, userAgent, options.apiUrl);
|
|
119
|
+
const html = await fetchPrerendered(fullUrl, userAgent, options.siteKey, options.apiUrl);
|
|
112
120
|
if (html) {
|
|
113
121
|
res.set("Content-Type", "text/html; charset=utf-8");
|
|
114
122
|
res.set("X-Prerendered", "true");
|
package/dist/express.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/express.ts","../src/index.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/express.ts","../src/index.ts"],"sourcesContent":["/**\n * rankdeploy-middleware/express — Express.js middleware\n */\n\nimport { isBot, isStaticAsset, isExcluded, fetchPrerendered, type RankDeployOptions } from \"./index\";\n\ninterface ExpressRequest {\n headers: Record<string, string | string[] | undefined>;\n url: string;\n protocol: string;\n get?(name: string): string | undefined;\n}\n\ninterface ExpressResponse {\n set(name: string, value: string): void;\n status(code: number): ExpressResponse;\n send(body: string): void;\n}\n\ntype NextFunction = () => void;\n\nexport function rankdeploy(options: RankDeployOptions) {\n return async function middleware(req: ExpressRequest, res: ExpressResponse, next: NextFunction) {\n const userAgent = (req.headers[\"user-agent\"] as string) || req.get?.(\"user-agent\") || \"\";\n const pathname = req.url.split(\"?\")[0];\n\n if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {\n return next();\n }\n\n if (options.botsOnly && !isBot(userAgent, options.extraBots)) {\n return next();\n }\n\n const protocol = req.protocol || \"https\";\n const host = req.get?.(\"host\") || req.headers.host || \"\";\n const fullUrl = `${protocol}://${host}${req.url}`;\n\n const html = await fetchPrerendered(fullUrl, userAgent, options.siteKey, options.apiUrl);\n\n if (html) {\n res.set(\"Content-Type\", \"text/html; charset=utf-8\");\n res.set(\"X-Prerendered\", \"true\");\n res.set(\"X-Powered-By\", \"Rank Deploy\");\n return res.status(200).send(html);\n }\n\n next();\n };\n}\n\nexport default rankdeploy;\n","/**\n * rankdeploy-middleware — Core SEO middleware engine\n *\n * Serves pre-rendered HTML with SEO overrides to all visitors.\n * The pre-rendered HTML is visually identical to the original page\n * but includes injected meta tags (title, description, canonical, og:tags).\n */\n\nexport const RANKDEPLOY_API = \"https://proxy.unikium.com\";\n\nexport const STATIC_EXTENSIONS = /\\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;\n\nexport interface RankDeployOptions {\n /** Your site key from Rank Deploy dashboard (required) */\n siteKey: string;\n /** Rank Deploy API URL. Default: https://proxy.unikium.com */\n apiUrl?: string;\n /** Paths to exclude from pre-rendering */\n excludePaths?: string[];\n /** Only serve to bots (default: false — serves to everyone for OG checker compatibility) */\n botsOnly?: boolean;\n /** Additional bot user agents to detect (used when botsOnly=true) */\n extraBots?: string[];\n}\n\nexport const BOT_USER_AGENTS = [\n \"googlebot\", \"bingbot\", \"yandexbot\", \"duckduckbot\", \"baiduspider\",\n \"slurp\", \"sogou\", \"exabot\",\n \"facebot\", \"facebookexternalhit\", \"twitterbot\", \"linkedinbot\",\n \"whatsapp\", \"telegrambot\", \"applebot\", \"discordbot\", \"slackbot\", \"pinterest\",\n \"screaming frog\", \"ahrefs\", \"semrush\", \"moz.com\", \"rogerbot\", \"dotbot\",\n \"gptbot\", \"chatgpt\", \"anthropic\", \"claudebot\", \"perplexitybot\", \"cohere\",\n // SEO tools & OG checkers\n \"opengraph\", \"metatags\", \"preview\", \"crawler\", \"spider\", \"fetch\",\n \"curl\", \"wget\", \"python-requests\", \"node-fetch\", \"axios\",\n];\n\nexport function isBot(userAgent: string, extraBots?: string[]): boolean {\n const ua = userAgent.toLowerCase();\n const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;\n return allBots.some((bot) => ua.includes(bot));\n}\n\nexport function isStaticAsset(pathname: string): boolean {\n return STATIC_EXTENSIONS.test(pathname);\n}\n\nexport function isExcluded(pathname: string, excludePaths?: string[]): boolean {\n if (!excludePaths) return false;\n return excludePaths.some((p) => pathname.startsWith(p));\n}\n\n/**\n * Fetch pre-rendered HTML from Rank Deploy API.\n */\nexport async function fetchPrerendered(\n url: string,\n userAgent: string,\n siteKey: string,\n apiUrl = RANKDEPLOY_API,\n): Promise<string | null> {\n try {\n const res = await fetch(\n `${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,\n {\n headers: { \"User-Agent\": userAgent || \"Googlebot/2.1\" },\n signal: AbortSignal.timeout(10_000),\n },\n );\n\n if (res.status === 200) {\n return res.text();\n }\n return null;\n } catch {\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAM,iBAAiB;AAEvB,IAAM,oBAAoB;AAe1B,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EAAa;AAAA,EAAW;AAAA,EAAa;AAAA,EAAe;AAAA,EACpD;AAAA,EAAS;AAAA,EAAS;AAAA,EAClB;AAAA,EAAW;AAAA,EAAuB;AAAA,EAAc;AAAA,EAChD;AAAA,EAAY;AAAA,EAAe;AAAA,EAAY;AAAA,EAAc;AAAA,EAAY;AAAA,EACjE;AAAA,EAAkB;AAAA,EAAU;AAAA,EAAW;AAAA,EAAW;AAAA,EAAY;AAAA,EAC9D;AAAA,EAAU;AAAA,EAAW;AAAA,EAAa;AAAA,EAAa;AAAA,EAAiB;AAAA;AAAA,EAEhE;AAAA,EAAa;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAAU;AAAA,EACzD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAmB;AAAA,EAAc;AACnD;AAEO,SAAS,MAAM,WAAmB,WAA+B;AACtE,QAAM,KAAK,UAAU,YAAY;AACjC,QAAM,UAAU,YAAY,CAAC,GAAG,iBAAiB,GAAG,SAAS,IAAI;AACjE,SAAO,QAAQ,KAAK,CAAC,QAAQ,GAAG,SAAS,GAAG,CAAC;AAC/C;AAEO,SAAS,cAAc,UAA2B;AACvD,SAAO,kBAAkB,KAAK,QAAQ;AACxC;AAEO,SAAS,WAAW,UAAkB,cAAkC;AAC7E,MAAI,CAAC,aAAc,QAAO;AAC1B,SAAO,aAAa,KAAK,CAAC,MAAM,SAAS,WAAW,CAAC,CAAC;AACxD;AAKA,eAAsB,iBACpB,KACA,WACA,SACA,SAAS,gBACe;AACxB,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAG,MAAM,eAAe,mBAAmB,GAAG,CAAC,QAAQ,mBAAmB,OAAO,CAAC;AAAA,MAClF;AAAA,QACE,SAAS,EAAE,cAAc,aAAa,gBAAgB;AAAA,QACtD,QAAQ,YAAY,QAAQ,GAAM;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,KAAK;AACtB,aAAO,IAAI,KAAK;AAAA,IAClB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ADxDO,SAAS,WAAW,SAA4B;AACrD,SAAO,eAAe,WAAW,KAAqB,KAAsB,MAAoB;AAC9F,UAAM,YAAa,IAAI,QAAQ,YAAY,KAAgB,IAAI,MAAM,YAAY,KAAK;AACtF,UAAM,WAAW,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC;AAErC,QAAI,cAAc,QAAQ,KAAK,WAAW,UAAU,QAAQ,YAAY,GAAG;AACzE,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,QAAQ,YAAY,CAAC,MAAM,WAAW,QAAQ,SAAS,GAAG;AAC5D,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,WAAW,IAAI,YAAY;AACjC,UAAM,OAAO,IAAI,MAAM,MAAM,KAAK,IAAI,QAAQ,QAAQ;AACtD,UAAM,UAAU,GAAG,QAAQ,MAAM,IAAI,GAAG,IAAI,GAAG;AAE/C,UAAM,OAAO,MAAM,iBAAiB,SAAS,WAAW,QAAQ,SAAS,QAAQ,MAAM;AAEvF,QAAI,MAAM;AACR,UAAI,IAAI,gBAAgB,0BAA0B;AAClD,UAAI,IAAI,iBAAiB,MAAM;AAC/B,UAAI,IAAI,gBAAgB,aAAa;AACrC,aAAO,IAAI,OAAO,GAAG,EAAE,KAAK,IAAI;AAAA,IAClC;AAEA,SAAK;AAAA,EACP;AACF;AAEA,IAAO,kBAAQ;","names":[]}
|
package/dist/express.mjs
CHANGED
|
@@ -3,26 +3,23 @@ import {
|
|
|
3
3
|
isBot,
|
|
4
4
|
isExcluded,
|
|
5
5
|
isStaticAsset
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-C43DAMVJ.mjs";
|
|
7
7
|
|
|
8
8
|
// src/express.ts
|
|
9
|
-
function rankdeploy(options
|
|
9
|
+
function rankdeploy(options) {
|
|
10
10
|
return async function middleware(req, res, next) {
|
|
11
11
|
const userAgent = req.headers["user-agent"] || req.get?.("user-agent") || "";
|
|
12
12
|
const pathname = req.url.split("?")[0];
|
|
13
|
-
if (
|
|
13
|
+
if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {
|
|
14
14
|
return next();
|
|
15
15
|
}
|
|
16
|
-
if (
|
|
17
|
-
return next();
|
|
18
|
-
}
|
|
19
|
-
if (isExcluded(pathname, options.excludePaths)) {
|
|
16
|
+
if (options.botsOnly && !isBot(userAgent, options.extraBots)) {
|
|
20
17
|
return next();
|
|
21
18
|
}
|
|
22
19
|
const protocol = req.protocol || "https";
|
|
23
20
|
const host = req.get?.("host") || req.headers.host || "";
|
|
24
21
|
const fullUrl = `${protocol}://${host}${req.url}`;
|
|
25
|
-
const html = await fetchPrerendered(fullUrl, userAgent, options.apiUrl);
|
|
22
|
+
const html = await fetchPrerendered(fullUrl, userAgent, options.siteKey, options.apiUrl);
|
|
26
23
|
if (html) {
|
|
27
24
|
res.set("Content-Type", "text/html; charset=utf-8");
|
|
28
25
|
res.set("X-Prerendered", "true");
|
package/dist/express.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/express.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/express.ts"],"sourcesContent":["/**\n * rankdeploy-middleware/express — Express.js middleware\n */\n\nimport { isBot, isStaticAsset, isExcluded, fetchPrerendered, type RankDeployOptions } from \"./index\";\n\ninterface ExpressRequest {\n headers: Record<string, string | string[] | undefined>;\n url: string;\n protocol: string;\n get?(name: string): string | undefined;\n}\n\ninterface ExpressResponse {\n set(name: string, value: string): void;\n status(code: number): ExpressResponse;\n send(body: string): void;\n}\n\ntype NextFunction = () => void;\n\nexport function rankdeploy(options: RankDeployOptions) {\n return async function middleware(req: ExpressRequest, res: ExpressResponse, next: NextFunction) {\n const userAgent = (req.headers[\"user-agent\"] as string) || req.get?.(\"user-agent\") || \"\";\n const pathname = req.url.split(\"?\")[0];\n\n if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {\n return next();\n }\n\n if (options.botsOnly && !isBot(userAgent, options.extraBots)) {\n return next();\n }\n\n const protocol = req.protocol || \"https\";\n const host = req.get?.(\"host\") || req.headers.host || \"\";\n const fullUrl = `${protocol}://${host}${req.url}`;\n\n const html = await fetchPrerendered(fullUrl, userAgent, options.siteKey, options.apiUrl);\n\n if (html) {\n res.set(\"Content-Type\", \"text/html; charset=utf-8\");\n res.set(\"X-Prerendered\", \"true\");\n res.set(\"X-Powered-By\", \"Rank Deploy\");\n return res.status(200).send(html);\n }\n\n next();\n };\n}\n\nexport default rankdeploy;\n"],"mappings":";;;;;;;;AAqBO,SAAS,WAAW,SAA4B;AACrD,SAAO,eAAe,WAAW,KAAqB,KAAsB,MAAoB;AAC9F,UAAM,YAAa,IAAI,QAAQ,YAAY,KAAgB,IAAI,MAAM,YAAY,KAAK;AACtF,UAAM,WAAW,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC;AAErC,QAAI,cAAc,QAAQ,KAAK,WAAW,UAAU,QAAQ,YAAY,GAAG;AACzE,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,QAAQ,YAAY,CAAC,MAAM,WAAW,QAAQ,SAAS,GAAG;AAC5D,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,WAAW,IAAI,YAAY;AACjC,UAAM,OAAO,IAAI,MAAM,MAAM,KAAK,IAAI,QAAQ,QAAQ;AACtD,UAAM,UAAU,GAAG,QAAQ,MAAM,IAAI,GAAG,IAAI,GAAG;AAE/C,UAAM,OAAO,MAAM,iBAAiB,SAAS,WAAW,QAAQ,SAAS,QAAQ,MAAM;AAEvF,QAAI,MAAM;AACR,UAAI,IAAI,gBAAgB,0BAA0B;AAClD,UAAI,IAAI,iBAAiB,MAAM;AAC/B,UAAI,IAAI,gBAAgB,aAAa;AACrC,aAAO,IAAI,OAAO,GAAG,EAAE,KAAK,IAAI;AAAA,IAClC;AAEA,SAAK;AAAA,EACP;AACF;AAEA,IAAO,kBAAQ;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ __export(src_exports, {
|
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(src_exports);
|
|
32
32
|
var RANKDEPLOY_API = "https://proxy.unikium.com";
|
|
33
|
+
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
33
34
|
var BOT_USER_AGENTS = [
|
|
34
35
|
"googlebot",
|
|
35
36
|
"bingbot",
|
|
@@ -60,9 +61,20 @@ var BOT_USER_AGENTS = [
|
|
|
60
61
|
"anthropic",
|
|
61
62
|
"claudebot",
|
|
62
63
|
"perplexitybot",
|
|
63
|
-
"cohere"
|
|
64
|
+
"cohere",
|
|
65
|
+
// SEO tools & OG checkers
|
|
66
|
+
"opengraph",
|
|
67
|
+
"metatags",
|
|
68
|
+
"preview",
|
|
69
|
+
"crawler",
|
|
70
|
+
"spider",
|
|
71
|
+
"fetch",
|
|
72
|
+
"curl",
|
|
73
|
+
"wget",
|
|
74
|
+
"python-requests",
|
|
75
|
+
"node-fetch",
|
|
76
|
+
"axios"
|
|
64
77
|
];
|
|
65
|
-
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
66
78
|
function isBot(userAgent, extraBots) {
|
|
67
79
|
const ua = userAgent.toLowerCase();
|
|
68
80
|
const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;
|
|
@@ -75,14 +87,13 @@ function isExcluded(pathname, excludePaths) {
|
|
|
75
87
|
if (!excludePaths) return false;
|
|
76
88
|
return excludePaths.some((p) => pathname.startsWith(p));
|
|
77
89
|
}
|
|
78
|
-
async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
90
|
+
async function fetchPrerendered(url, userAgent, siteKey, apiUrl = RANKDEPLOY_API) {
|
|
79
91
|
try {
|
|
80
92
|
const res = await fetch(
|
|
81
|
-
`${apiUrl}/render?url=${encodeURIComponent(url)}`,
|
|
93
|
+
`${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,
|
|
82
94
|
{
|
|
83
|
-
headers: { "User-Agent": userAgent },
|
|
95
|
+
headers: { "User-Agent": userAgent || "Googlebot/2.1" },
|
|
84
96
|
signal: AbortSignal.timeout(1e4)
|
|
85
|
-
// 10s timeout
|
|
86
97
|
}
|
|
87
98
|
);
|
|
88
99
|
if (res.status === 200) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * rankdeploy-middleware — Core SEO middleware engine\n *\n * Serves pre-rendered HTML with SEO overrides to all visitors.\n * The pre-rendered HTML is visually identical to the original page\n * but includes injected meta tags (title, description, canonical, og:tags).\n */\n\nexport const RANKDEPLOY_API = \"https://proxy.unikium.com\";\n\nexport const STATIC_EXTENSIONS = /\\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;\n\nexport interface RankDeployOptions {\n /** Your site key from Rank Deploy dashboard (required) */\n siteKey: string;\n /** Rank Deploy API URL. Default: https://proxy.unikium.com */\n apiUrl?: string;\n /** Paths to exclude from pre-rendering */\n excludePaths?: string[];\n /** Only serve to bots (default: false — serves to everyone for OG checker compatibility) */\n botsOnly?: boolean;\n /** Additional bot user agents to detect (used when botsOnly=true) */\n extraBots?: string[];\n}\n\nexport const BOT_USER_AGENTS = [\n \"googlebot\", \"bingbot\", \"yandexbot\", \"duckduckbot\", \"baiduspider\",\n \"slurp\", \"sogou\", \"exabot\",\n \"facebot\", \"facebookexternalhit\", \"twitterbot\", \"linkedinbot\",\n \"whatsapp\", \"telegrambot\", \"applebot\", \"discordbot\", \"slackbot\", \"pinterest\",\n \"screaming frog\", \"ahrefs\", \"semrush\", \"moz.com\", \"rogerbot\", \"dotbot\",\n \"gptbot\", \"chatgpt\", \"anthropic\", \"claudebot\", \"perplexitybot\", \"cohere\",\n // SEO tools & OG checkers\n \"opengraph\", \"metatags\", \"preview\", \"crawler\", \"spider\", \"fetch\",\n \"curl\", \"wget\", \"python-requests\", \"node-fetch\", \"axios\",\n];\n\nexport function isBot(userAgent: string, extraBots?: string[]): boolean {\n const ua = userAgent.toLowerCase();\n const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;\n return allBots.some((bot) => ua.includes(bot));\n}\n\nexport function isStaticAsset(pathname: string): boolean {\n return STATIC_EXTENSIONS.test(pathname);\n}\n\nexport function isExcluded(pathname: string, excludePaths?: string[]): boolean {\n if (!excludePaths) return false;\n return excludePaths.some((p) => pathname.startsWith(p));\n}\n\n/**\n * Fetch pre-rendered HTML from Rank Deploy API.\n */\nexport async function fetchPrerendered(\n url: string,\n userAgent: string,\n siteKey: string,\n apiUrl = RANKDEPLOY_API,\n): Promise<string | null> {\n try {\n const res = await fetch(\n `${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,\n {\n headers: { \"User-Agent\": userAgent || \"Googlebot/2.1\" },\n signal: AbortSignal.timeout(10_000),\n },\n );\n\n if (res.status === 200) {\n return res.text();\n }\n return null;\n } catch {\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQO,IAAM,iBAAiB;AAEvB,IAAM,oBAAoB;AAe1B,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EAAa;AAAA,EAAW;AAAA,EAAa;AAAA,EAAe;AAAA,EACpD;AAAA,EAAS;AAAA,EAAS;AAAA,EAClB;AAAA,EAAW;AAAA,EAAuB;AAAA,EAAc;AAAA,EAChD;AAAA,EAAY;AAAA,EAAe;AAAA,EAAY;AAAA,EAAc;AAAA,EAAY;AAAA,EACjE;AAAA,EAAkB;AAAA,EAAU;AAAA,EAAW;AAAA,EAAW;AAAA,EAAY;AAAA,EAC9D;AAAA,EAAU;AAAA,EAAW;AAAA,EAAa;AAAA,EAAa;AAAA,EAAiB;AAAA;AAAA,EAEhE;AAAA,EAAa;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAAU;AAAA,EACzD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAmB;AAAA,EAAc;AACnD;AAEO,SAAS,MAAM,WAAmB,WAA+B;AACtE,QAAM,KAAK,UAAU,YAAY;AACjC,QAAM,UAAU,YAAY,CAAC,GAAG,iBAAiB,GAAG,SAAS,IAAI;AACjE,SAAO,QAAQ,KAAK,CAAC,QAAQ,GAAG,SAAS,GAAG,CAAC;AAC/C;AAEO,SAAS,cAAc,UAA2B;AACvD,SAAO,kBAAkB,KAAK,QAAQ;AACxC;AAEO,SAAS,WAAW,UAAkB,cAAkC;AAC7E,MAAI,CAAC,aAAc,QAAO;AAC1B,SAAO,aAAa,KAAK,CAAC,MAAM,SAAS,WAAW,CAAC,CAAC;AACxD;AAKA,eAAsB,iBACpB,KACA,WACA,SACA,SAAS,gBACe;AACxB,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAG,MAAM,eAAe,mBAAmB,GAAG,CAAC,QAAQ,mBAAmB,OAAO,CAAC;AAAA,MAClF;AAAA,QACE,SAAS,EAAE,cAAc,aAAa,gBAAgB;AAAA,QACtD,QAAQ,YAAY,QAAQ,GAAM;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,KAAK;AACtB,aAAO,IAAI,KAAK;AAAA,IAClB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/dist/index.mjs
CHANGED
package/dist/netlify.js
CHANGED
|
@@ -20,13 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/netlify.ts
|
|
21
21
|
var netlify_exports = {};
|
|
22
22
|
__export(netlify_exports, {
|
|
23
|
-
createHandler: () => createHandler
|
|
24
|
-
default: () => netlify_default
|
|
23
|
+
createHandler: () => createHandler
|
|
25
24
|
});
|
|
26
25
|
module.exports = __toCommonJS(netlify_exports);
|
|
27
26
|
|
|
28
27
|
// src/index.ts
|
|
29
28
|
var RANKDEPLOY_API = "https://proxy.unikium.com";
|
|
29
|
+
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
30
30
|
var BOT_USER_AGENTS = [
|
|
31
31
|
"googlebot",
|
|
32
32
|
"bingbot",
|
|
@@ -57,9 +57,20 @@ var BOT_USER_AGENTS = [
|
|
|
57
57
|
"anthropic",
|
|
58
58
|
"claudebot",
|
|
59
59
|
"perplexitybot",
|
|
60
|
-
"cohere"
|
|
60
|
+
"cohere",
|
|
61
|
+
// SEO tools & OG checkers
|
|
62
|
+
"opengraph",
|
|
63
|
+
"metatags",
|
|
64
|
+
"preview",
|
|
65
|
+
"crawler",
|
|
66
|
+
"spider",
|
|
67
|
+
"fetch",
|
|
68
|
+
"curl",
|
|
69
|
+
"wget",
|
|
70
|
+
"python-requests",
|
|
71
|
+
"node-fetch",
|
|
72
|
+
"axios"
|
|
61
73
|
];
|
|
62
|
-
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
63
74
|
function isBot(userAgent, extraBots) {
|
|
64
75
|
const ua = userAgent.toLowerCase();
|
|
65
76
|
const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;
|
|
@@ -72,14 +83,13 @@ function isExcluded(pathname, excludePaths) {
|
|
|
72
83
|
if (!excludePaths) return false;
|
|
73
84
|
return excludePaths.some((p) => pathname.startsWith(p));
|
|
74
85
|
}
|
|
75
|
-
async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
86
|
+
async function fetchPrerendered(url, userAgent, siteKey, apiUrl = RANKDEPLOY_API) {
|
|
76
87
|
try {
|
|
77
88
|
const res = await fetch(
|
|
78
|
-
`${apiUrl}/render?url=${encodeURIComponent(url)}`,
|
|
89
|
+
`${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,
|
|
79
90
|
{
|
|
80
|
-
headers: { "User-Agent": userAgent },
|
|
91
|
+
headers: { "User-Agent": userAgent || "Googlebot/2.1" },
|
|
81
92
|
signal: AbortSignal.timeout(1e4)
|
|
82
|
-
// 10s timeout
|
|
83
93
|
}
|
|
84
94
|
);
|
|
85
95
|
if (res.status === 200) {
|
|
@@ -92,20 +102,17 @@ async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
|
92
102
|
}
|
|
93
103
|
|
|
94
104
|
// src/netlify.ts
|
|
95
|
-
function createHandler(options
|
|
105
|
+
function createHandler(options) {
|
|
96
106
|
return async function handler(request, context) {
|
|
97
107
|
const userAgent = request.headers.get("user-agent") || "";
|
|
98
108
|
const pathname = new URL(request.url).pathname;
|
|
99
|
-
if (
|
|
100
|
-
return context.next();
|
|
101
|
-
}
|
|
102
|
-
if (isStaticAsset(pathname)) {
|
|
109
|
+
if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {
|
|
103
110
|
return context.next();
|
|
104
111
|
}
|
|
105
|
-
if (
|
|
112
|
+
if (options.botsOnly && !isBot(userAgent, options.extraBots)) {
|
|
106
113
|
return context.next();
|
|
107
114
|
}
|
|
108
|
-
const html = await fetchPrerendered(request.url, userAgent, options.apiUrl);
|
|
115
|
+
const html = await fetchPrerendered(request.url, userAgent, options.siteKey, options.apiUrl);
|
|
109
116
|
if (html) {
|
|
110
117
|
return new Response(html, {
|
|
111
118
|
status: 200,
|
|
@@ -119,7 +126,6 @@ function createHandler(options = {}) {
|
|
|
119
126
|
return context.next();
|
|
120
127
|
};
|
|
121
128
|
}
|
|
122
|
-
var netlify_default = createHandler();
|
|
123
129
|
// Annotate the CommonJS export names for ESM import in node:
|
|
124
130
|
0 && (module.exports = {
|
|
125
131
|
createHandler
|
package/dist/netlify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/netlify.ts","../src/index.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/netlify.ts","../src/index.ts"],"sourcesContent":["/**\n * rankdeploy-middleware/netlify — Netlify Edge Function middleware\n */\n\nimport { isBot, isStaticAsset, isExcluded, fetchPrerendered, type RankDeployOptions } from \"./index\";\n\ninterface NetlifyContext {\n next(): Promise<Response>;\n}\n\nexport function createHandler(options: RankDeployOptions) {\n return async function handler(request: Request, context: NetlifyContext) {\n const userAgent = request.headers.get(\"user-agent\") || \"\";\n const pathname = new URL(request.url).pathname;\n\n if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {\n return context.next();\n }\n\n if (options.botsOnly && !isBot(userAgent, options.extraBots)) {\n return context.next();\n }\n\n const html = await fetchPrerendered(request.url, userAgent, options.siteKey, options.apiUrl);\n\n if (html) {\n return new Response(html, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"X-Prerendered\": \"true\",\n \"X-Powered-By\": \"Rank Deploy\",\n },\n });\n }\n\n return context.next();\n };\n}\n","/**\n * rankdeploy-middleware — Core SEO middleware engine\n *\n * Serves pre-rendered HTML with SEO overrides to all visitors.\n * The pre-rendered HTML is visually identical to the original page\n * but includes injected meta tags (title, description, canonical, og:tags).\n */\n\nexport const RANKDEPLOY_API = \"https://proxy.unikium.com\";\n\nexport const STATIC_EXTENSIONS = /\\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;\n\nexport interface RankDeployOptions {\n /** Your site key from Rank Deploy dashboard (required) */\n siteKey: string;\n /** Rank Deploy API URL. Default: https://proxy.unikium.com */\n apiUrl?: string;\n /** Paths to exclude from pre-rendering */\n excludePaths?: string[];\n /** Only serve to bots (default: false — serves to everyone for OG checker compatibility) */\n botsOnly?: boolean;\n /** Additional bot user agents to detect (used when botsOnly=true) */\n extraBots?: string[];\n}\n\nexport const BOT_USER_AGENTS = [\n \"googlebot\", \"bingbot\", \"yandexbot\", \"duckduckbot\", \"baiduspider\",\n \"slurp\", \"sogou\", \"exabot\",\n \"facebot\", \"facebookexternalhit\", \"twitterbot\", \"linkedinbot\",\n \"whatsapp\", \"telegrambot\", \"applebot\", \"discordbot\", \"slackbot\", \"pinterest\",\n \"screaming frog\", \"ahrefs\", \"semrush\", \"moz.com\", \"rogerbot\", \"dotbot\",\n \"gptbot\", \"chatgpt\", \"anthropic\", \"claudebot\", \"perplexitybot\", \"cohere\",\n // SEO tools & OG checkers\n \"opengraph\", \"metatags\", \"preview\", \"crawler\", \"spider\", \"fetch\",\n \"curl\", \"wget\", \"python-requests\", \"node-fetch\", \"axios\",\n];\n\nexport function isBot(userAgent: string, extraBots?: string[]): boolean {\n const ua = userAgent.toLowerCase();\n const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;\n return allBots.some((bot) => ua.includes(bot));\n}\n\nexport function isStaticAsset(pathname: string): boolean {\n return STATIC_EXTENSIONS.test(pathname);\n}\n\nexport function isExcluded(pathname: string, excludePaths?: string[]): boolean {\n if (!excludePaths) return false;\n return excludePaths.some((p) => pathname.startsWith(p));\n}\n\n/**\n * Fetch pre-rendered HTML from Rank Deploy API.\n */\nexport async function fetchPrerendered(\n url: string,\n userAgent: string,\n siteKey: string,\n apiUrl = RANKDEPLOY_API,\n): Promise<string | null> {\n try {\n const res = await fetch(\n `${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,\n {\n headers: { \"User-Agent\": userAgent || \"Googlebot/2.1\" },\n signal: AbortSignal.timeout(10_000),\n },\n );\n\n if (res.status === 200) {\n return res.text();\n }\n return null;\n } catch {\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAM,iBAAiB;AAEvB,IAAM,oBAAoB;AAe1B,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EAAa;AAAA,EAAW;AAAA,EAAa;AAAA,EAAe;AAAA,EACpD;AAAA,EAAS;AAAA,EAAS;AAAA,EAClB;AAAA,EAAW;AAAA,EAAuB;AAAA,EAAc;AAAA,EAChD;AAAA,EAAY;AAAA,EAAe;AAAA,EAAY;AAAA,EAAc;AAAA,EAAY;AAAA,EACjE;AAAA,EAAkB;AAAA,EAAU;AAAA,EAAW;AAAA,EAAW;AAAA,EAAY;AAAA,EAC9D;AAAA,EAAU;AAAA,EAAW;AAAA,EAAa;AAAA,EAAa;AAAA,EAAiB;AAAA;AAAA,EAEhE;AAAA,EAAa;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAAU;AAAA,EACzD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAmB;AAAA,EAAc;AACnD;AAEO,SAAS,MAAM,WAAmB,WAA+B;AACtE,QAAM,KAAK,UAAU,YAAY;AACjC,QAAM,UAAU,YAAY,CAAC,GAAG,iBAAiB,GAAG,SAAS,IAAI;AACjE,SAAO,QAAQ,KAAK,CAAC,QAAQ,GAAG,SAAS,GAAG,CAAC;AAC/C;AAEO,SAAS,cAAc,UAA2B;AACvD,SAAO,kBAAkB,KAAK,QAAQ;AACxC;AAEO,SAAS,WAAW,UAAkB,cAAkC;AAC7E,MAAI,CAAC,aAAc,QAAO;AAC1B,SAAO,aAAa,KAAK,CAAC,MAAM,SAAS,WAAW,CAAC,CAAC;AACxD;AAKA,eAAsB,iBACpB,KACA,WACA,SACA,SAAS,gBACe;AACxB,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAG,MAAM,eAAe,mBAAmB,GAAG,CAAC,QAAQ,mBAAmB,OAAO,CAAC;AAAA,MAClF;AAAA,QACE,SAAS,EAAE,cAAc,aAAa,gBAAgB;AAAA,QACtD,QAAQ,YAAY,QAAQ,GAAM;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,KAAK;AACtB,aAAO,IAAI,KAAK;AAAA,IAClB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ADnEO,SAAS,cAAc,SAA4B;AACxD,SAAO,eAAe,QAAQ,SAAkB,SAAyB;AACvE,UAAM,YAAY,QAAQ,QAAQ,IAAI,YAAY,KAAK;AACvD,UAAM,WAAW,IAAI,IAAI,QAAQ,GAAG,EAAE;AAEtC,QAAI,cAAc,QAAQ,KAAK,WAAW,UAAU,QAAQ,YAAY,GAAG;AACzE,aAAO,QAAQ,KAAK;AAAA,IACtB;AAEA,QAAI,QAAQ,YAAY,CAAC,MAAM,WAAW,QAAQ,SAAS,GAAG;AAC5D,aAAO,QAAQ,KAAK;AAAA,IACtB;AAEA,UAAM,OAAO,MAAM,iBAAiB,QAAQ,KAAK,WAAW,QAAQ,SAAS,QAAQ,MAAM;AAE3F,QAAI,MAAM;AACR,aAAO,IAAI,SAAS,MAAM;AAAA,QACxB,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,QAAQ,KAAK;AAAA,EACtB;AACF;","names":[]}
|
package/dist/netlify.mjs
CHANGED
|
@@ -3,23 +3,20 @@ import {
|
|
|
3
3
|
isBot,
|
|
4
4
|
isExcluded,
|
|
5
5
|
isStaticAsset
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-C43DAMVJ.mjs";
|
|
7
7
|
|
|
8
8
|
// src/netlify.ts
|
|
9
|
-
function createHandler(options
|
|
9
|
+
function createHandler(options) {
|
|
10
10
|
return async function handler(request, context) {
|
|
11
11
|
const userAgent = request.headers.get("user-agent") || "";
|
|
12
12
|
const pathname = new URL(request.url).pathname;
|
|
13
|
-
if (
|
|
13
|
+
if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {
|
|
14
14
|
return context.next();
|
|
15
15
|
}
|
|
16
|
-
if (
|
|
16
|
+
if (options.botsOnly && !isBot(userAgent, options.extraBots)) {
|
|
17
17
|
return context.next();
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
return context.next();
|
|
21
|
-
}
|
|
22
|
-
const html = await fetchPrerendered(request.url, userAgent, options.apiUrl);
|
|
19
|
+
const html = await fetchPrerendered(request.url, userAgent, options.siteKey, options.apiUrl);
|
|
23
20
|
if (html) {
|
|
24
21
|
return new Response(html, {
|
|
25
22
|
status: 200,
|
|
@@ -33,9 +30,7 @@ function createHandler(options = {}) {
|
|
|
33
30
|
return context.next();
|
|
34
31
|
};
|
|
35
32
|
}
|
|
36
|
-
var netlify_default = createHandler();
|
|
37
33
|
export {
|
|
38
|
-
createHandler
|
|
39
|
-
netlify_default as default
|
|
34
|
+
createHandler
|
|
40
35
|
};
|
|
41
36
|
//# sourceMappingURL=netlify.mjs.map
|
package/dist/netlify.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/netlify.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/netlify.ts"],"sourcesContent":["/**\n * rankdeploy-middleware/netlify — Netlify Edge Function middleware\n */\n\nimport { isBot, isStaticAsset, isExcluded, fetchPrerendered, type RankDeployOptions } from \"./index\";\n\ninterface NetlifyContext {\n next(): Promise<Response>;\n}\n\nexport function createHandler(options: RankDeployOptions) {\n return async function handler(request: Request, context: NetlifyContext) {\n const userAgent = request.headers.get(\"user-agent\") || \"\";\n const pathname = new URL(request.url).pathname;\n\n if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {\n return context.next();\n }\n\n if (options.botsOnly && !isBot(userAgent, options.extraBots)) {\n return context.next();\n }\n\n const html = await fetchPrerendered(request.url, userAgent, options.siteKey, options.apiUrl);\n\n if (html) {\n return new Response(html, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"X-Prerendered\": \"true\",\n \"X-Powered-By\": \"Rank Deploy\",\n },\n });\n }\n\n return context.next();\n };\n}\n"],"mappings":";;;;;;;;AAUO,SAAS,cAAc,SAA4B;AACxD,SAAO,eAAe,QAAQ,SAAkB,SAAyB;AACvE,UAAM,YAAY,QAAQ,QAAQ,IAAI,YAAY,KAAK;AACvD,UAAM,WAAW,IAAI,IAAI,QAAQ,GAAG,EAAE;AAEtC,QAAI,cAAc,QAAQ,KAAK,WAAW,UAAU,QAAQ,YAAY,GAAG;AACzE,aAAO,QAAQ,KAAK;AAAA,IACtB;AAEA,QAAI,QAAQ,YAAY,CAAC,MAAM,WAAW,QAAQ,SAAS,GAAG;AAC5D,aAAO,QAAQ,KAAK;AAAA,IACtB;AAEA,UAAM,OAAO,MAAM,iBAAiB,QAAQ,KAAK,WAAW,QAAQ,SAAS,QAAQ,MAAM;AAE3F,QAAI,MAAM;AACR,aAAO,IAAI,SAAS,MAAM;AAAA,QACxB,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,QAAQ,KAAK;AAAA,EACtB;AACF;","names":[]}
|
package/dist/next.js
CHANGED
|
@@ -21,13 +21,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var next_exports = {};
|
|
22
22
|
__export(next_exports, {
|
|
23
23
|
config: () => config,
|
|
24
|
-
createMiddleware: () => createMiddleware
|
|
25
|
-
middleware: () => middleware
|
|
24
|
+
createMiddleware: () => createMiddleware
|
|
26
25
|
});
|
|
27
26
|
module.exports = __toCommonJS(next_exports);
|
|
28
27
|
|
|
29
28
|
// src/index.ts
|
|
30
29
|
var RANKDEPLOY_API = "https://proxy.unikium.com";
|
|
30
|
+
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
31
31
|
var BOT_USER_AGENTS = [
|
|
32
32
|
"googlebot",
|
|
33
33
|
"bingbot",
|
|
@@ -58,9 +58,20 @@ var BOT_USER_AGENTS = [
|
|
|
58
58
|
"anthropic",
|
|
59
59
|
"claudebot",
|
|
60
60
|
"perplexitybot",
|
|
61
|
-
"cohere"
|
|
61
|
+
"cohere",
|
|
62
|
+
// SEO tools & OG checkers
|
|
63
|
+
"opengraph",
|
|
64
|
+
"metatags",
|
|
65
|
+
"preview",
|
|
66
|
+
"crawler",
|
|
67
|
+
"spider",
|
|
68
|
+
"fetch",
|
|
69
|
+
"curl",
|
|
70
|
+
"wget",
|
|
71
|
+
"python-requests",
|
|
72
|
+
"node-fetch",
|
|
73
|
+
"axios"
|
|
62
74
|
];
|
|
63
|
-
var STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;
|
|
64
75
|
function isBot(userAgent, extraBots) {
|
|
65
76
|
const ua = userAgent.toLowerCase();
|
|
66
77
|
const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;
|
|
@@ -73,14 +84,13 @@ function isExcluded(pathname, excludePaths) {
|
|
|
73
84
|
if (!excludePaths) return false;
|
|
74
85
|
return excludePaths.some((p) => pathname.startsWith(p));
|
|
75
86
|
}
|
|
76
|
-
async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
87
|
+
async function fetchPrerendered(url, userAgent, siteKey, apiUrl = RANKDEPLOY_API) {
|
|
77
88
|
try {
|
|
78
89
|
const res = await fetch(
|
|
79
|
-
`${apiUrl}/render?url=${encodeURIComponent(url)}`,
|
|
90
|
+
`${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,
|
|
80
91
|
{
|
|
81
|
-
headers: { "User-Agent": userAgent },
|
|
92
|
+
headers: { "User-Agent": userAgent || "Googlebot/2.1" },
|
|
82
93
|
signal: AbortSignal.timeout(1e4)
|
|
83
|
-
// 10s timeout
|
|
84
94
|
}
|
|
85
95
|
);
|
|
86
96
|
if (res.status === 200) {
|
|
@@ -93,14 +103,17 @@ async function fetchPrerendered(url, userAgent, apiUrl = RANKDEPLOY_API) {
|
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
// src/next.ts
|
|
96
|
-
function createMiddleware(options
|
|
97
|
-
return async function
|
|
106
|
+
function createMiddleware(options) {
|
|
107
|
+
return async function middleware(request) {
|
|
98
108
|
const userAgent = request.headers.get("user-agent") || "";
|
|
99
109
|
const pathname = request.nextUrl.pathname;
|
|
100
|
-
if (
|
|
110
|
+
if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (options.botsOnly && !isBot(userAgent, options.extraBots)) {
|
|
101
114
|
return;
|
|
102
115
|
}
|
|
103
|
-
const html = await fetchPrerendered(request.nextUrl.toString(), userAgent, options.apiUrl);
|
|
116
|
+
const html = await fetchPrerendered(request.nextUrl.toString(), userAgent, options.siteKey, options.apiUrl);
|
|
104
117
|
if (html) {
|
|
105
118
|
return new Response(html, {
|
|
106
119
|
status: 200,
|
|
@@ -114,14 +127,12 @@ function createMiddleware(options = {}) {
|
|
|
114
127
|
return;
|
|
115
128
|
};
|
|
116
129
|
}
|
|
117
|
-
var middleware = createMiddleware();
|
|
118
130
|
var config = {
|
|
119
131
|
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"]
|
|
120
132
|
};
|
|
121
133
|
// Annotate the CommonJS export names for ESM import in node:
|
|
122
134
|
0 && (module.exports = {
|
|
123
135
|
config,
|
|
124
|
-
createMiddleware
|
|
125
|
-
middleware
|
|
136
|
+
createMiddleware
|
|
126
137
|
});
|
|
127
138
|
//# sourceMappingURL=next.js.map
|
package/dist/next.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/next.ts","../src/index.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/next.ts","../src/index.ts"],"sourcesContent":["/**\n * rankdeploy-middleware/next — Next.js / Vercel middleware\n *\n * Serves pre-rendered HTML with SEO overrides.\n * By default serves to ALL requests (so OG checkers work).\n * Set botsOnly: true to only serve to search engine bots.\n */\n\nimport { isBot, isStaticAsset, isExcluded, fetchPrerendered, type RankDeployOptions } from \"./index\";\n\ninterface NextMiddlewareRequest {\n headers: { get(name: string): string | null };\n nextUrl: { pathname: string; toString(): string };\n}\n\nexport function createMiddleware(options: RankDeployOptions) {\n return async function middleware(request: NextMiddlewareRequest) {\n const userAgent = request.headers.get(\"user-agent\") || \"\";\n const pathname = request.nextUrl.pathname;\n\n // Skip static assets and excluded paths\n if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {\n return;\n }\n\n // If botsOnly mode, only intercept bot requests\n if (options.botsOnly && !isBot(userAgent, options.extraBots)) {\n return;\n }\n\n const html = await fetchPrerendered(request.nextUrl.toString(), userAgent, options.siteKey, options.apiUrl);\n\n if (html) {\n return new Response(html, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"X-Prerendered\": \"true\",\n \"X-Powered-By\": \"Rank Deploy\",\n },\n });\n }\n\n return;\n };\n}\n\nexport const config = {\n matcher: [\"/((?!api|_next/static|_next/image|favicon.ico).*)\"],\n};\n","/**\n * rankdeploy-middleware — Core SEO middleware engine\n *\n * Serves pre-rendered HTML with SEO overrides to all visitors.\n * The pre-rendered HTML is visually identical to the original page\n * but includes injected meta tags (title, description, canonical, og:tags).\n */\n\nexport const RANKDEPLOY_API = \"https://proxy.unikium.com\";\n\nexport const STATIC_EXTENSIONS = /\\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;\n\nexport interface RankDeployOptions {\n /** Your site key from Rank Deploy dashboard (required) */\n siteKey: string;\n /** Rank Deploy API URL. Default: https://proxy.unikium.com */\n apiUrl?: string;\n /** Paths to exclude from pre-rendering */\n excludePaths?: string[];\n /** Only serve to bots (default: false — serves to everyone for OG checker compatibility) */\n botsOnly?: boolean;\n /** Additional bot user agents to detect (used when botsOnly=true) */\n extraBots?: string[];\n}\n\nexport const BOT_USER_AGENTS = [\n \"googlebot\", \"bingbot\", \"yandexbot\", \"duckduckbot\", \"baiduspider\",\n \"slurp\", \"sogou\", \"exabot\",\n \"facebot\", \"facebookexternalhit\", \"twitterbot\", \"linkedinbot\",\n \"whatsapp\", \"telegrambot\", \"applebot\", \"discordbot\", \"slackbot\", \"pinterest\",\n \"screaming frog\", \"ahrefs\", \"semrush\", \"moz.com\", \"rogerbot\", \"dotbot\",\n \"gptbot\", \"chatgpt\", \"anthropic\", \"claudebot\", \"perplexitybot\", \"cohere\",\n // SEO tools & OG checkers\n \"opengraph\", \"metatags\", \"preview\", \"crawler\", \"spider\", \"fetch\",\n \"curl\", \"wget\", \"python-requests\", \"node-fetch\", \"axios\",\n];\n\nexport function isBot(userAgent: string, extraBots?: string[]): boolean {\n const ua = userAgent.toLowerCase();\n const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;\n return allBots.some((bot) => ua.includes(bot));\n}\n\nexport function isStaticAsset(pathname: string): boolean {\n return STATIC_EXTENSIONS.test(pathname);\n}\n\nexport function isExcluded(pathname: string, excludePaths?: string[]): boolean {\n if (!excludePaths) return false;\n return excludePaths.some((p) => pathname.startsWith(p));\n}\n\n/**\n * Fetch pre-rendered HTML from Rank Deploy API.\n */\nexport async function fetchPrerendered(\n url: string,\n userAgent: string,\n siteKey: string,\n apiUrl = RANKDEPLOY_API,\n): Promise<string | null> {\n try {\n const res = await fetch(\n `${apiUrl}/render?url=${encodeURIComponent(url)}&key=${encodeURIComponent(siteKey)}`,\n {\n headers: { \"User-Agent\": userAgent || \"Googlebot/2.1\" },\n signal: AbortSignal.timeout(10_000),\n },\n );\n\n if (res.status === 200) {\n return res.text();\n }\n return null;\n } catch {\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAM,iBAAiB;AAEvB,IAAM,oBAAoB;AAe1B,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EAAa;AAAA,EAAW;AAAA,EAAa;AAAA,EAAe;AAAA,EACpD;AAAA,EAAS;AAAA,EAAS;AAAA,EAClB;AAAA,EAAW;AAAA,EAAuB;AAAA,EAAc;AAAA,EAChD;AAAA,EAAY;AAAA,EAAe;AAAA,EAAY;AAAA,EAAc;AAAA,EAAY;AAAA,EACjE;AAAA,EAAkB;AAAA,EAAU;AAAA,EAAW;AAAA,EAAW;AAAA,EAAY;AAAA,EAC9D;AAAA,EAAU;AAAA,EAAW;AAAA,EAAa;AAAA,EAAa;AAAA,EAAiB;AAAA;AAAA,EAEhE;AAAA,EAAa;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAAU;AAAA,EACzD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAmB;AAAA,EAAc;AACnD;AAEO,SAAS,MAAM,WAAmB,WAA+B;AACtE,QAAM,KAAK,UAAU,YAAY;AACjC,QAAM,UAAU,YAAY,CAAC,GAAG,iBAAiB,GAAG,SAAS,IAAI;AACjE,SAAO,QAAQ,KAAK,CAAC,QAAQ,GAAG,SAAS,GAAG,CAAC;AAC/C;AAEO,SAAS,cAAc,UAA2B;AACvD,SAAO,kBAAkB,KAAK,QAAQ;AACxC;AAEO,SAAS,WAAW,UAAkB,cAAkC;AAC7E,MAAI,CAAC,aAAc,QAAO;AAC1B,SAAO,aAAa,KAAK,CAAC,MAAM,SAAS,WAAW,CAAC,CAAC;AACxD;AAKA,eAAsB,iBACpB,KACA,WACA,SACA,SAAS,gBACe;AACxB,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAG,MAAM,eAAe,mBAAmB,GAAG,CAAC,QAAQ,mBAAmB,OAAO,CAAC;AAAA,MAClF;AAAA,QACE,SAAS,EAAE,cAAc,aAAa,gBAAgB;AAAA,QACtD,QAAQ,YAAY,QAAQ,GAAM;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,KAAK;AACtB,aAAO,IAAI,KAAK;AAAA,IAClB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AD9DO,SAAS,iBAAiB,SAA4B;AAC3D,SAAO,eAAe,WAAW,SAAgC;AAC/D,UAAM,YAAY,QAAQ,QAAQ,IAAI,YAAY,KAAK;AACvD,UAAM,WAAW,QAAQ,QAAQ;AAGjC,QAAI,cAAc,QAAQ,KAAK,WAAW,UAAU,QAAQ,YAAY,GAAG;AACzE;AAAA,IACF;AAGA,QAAI,QAAQ,YAAY,CAAC,MAAM,WAAW,QAAQ,SAAS,GAAG;AAC5D;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,iBAAiB,QAAQ,QAAQ,SAAS,GAAG,WAAW,QAAQ,SAAS,QAAQ,MAAM;AAE1G,QAAI,MAAM;AACR,aAAO,IAAI,SAAS,MAAM;AAAA,QACxB,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,IACH;AAEA;AAAA,EACF;AACF;AAEO,IAAM,SAAS;AAAA,EACpB,SAAS,CAAC,mDAAmD;AAC/D;","names":[]}
|
package/dist/next.mjs
CHANGED
|
@@ -3,17 +3,20 @@ import {
|
|
|
3
3
|
isBot,
|
|
4
4
|
isExcluded,
|
|
5
5
|
isStaticAsset
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-C43DAMVJ.mjs";
|
|
7
7
|
|
|
8
8
|
// src/next.ts
|
|
9
|
-
function createMiddleware(options
|
|
10
|
-
return async function
|
|
9
|
+
function createMiddleware(options) {
|
|
10
|
+
return async function middleware(request) {
|
|
11
11
|
const userAgent = request.headers.get("user-agent") || "";
|
|
12
12
|
const pathname = request.nextUrl.pathname;
|
|
13
|
-
if (
|
|
13
|
+
if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
if (options.botsOnly && !isBot(userAgent, options.extraBots)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const html = await fetchPrerendered(request.nextUrl.toString(), userAgent, options.siteKey, options.apiUrl);
|
|
17
20
|
if (html) {
|
|
18
21
|
return new Response(html, {
|
|
19
22
|
status: 200,
|
|
@@ -27,13 +30,11 @@ function createMiddleware(options = {}) {
|
|
|
27
30
|
return;
|
|
28
31
|
};
|
|
29
32
|
}
|
|
30
|
-
var middleware = createMiddleware();
|
|
31
33
|
var config = {
|
|
32
34
|
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"]
|
|
33
35
|
};
|
|
34
36
|
export {
|
|
35
37
|
config,
|
|
36
|
-
createMiddleware
|
|
37
|
-
middleware
|
|
38
|
+
createMiddleware
|
|
38
39
|
};
|
|
39
40
|
//# sourceMappingURL=next.mjs.map
|
package/dist/next.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/next.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/next.ts"],"sourcesContent":["/**\n * rankdeploy-middleware/next — Next.js / Vercel middleware\n *\n * Serves pre-rendered HTML with SEO overrides.\n * By default serves to ALL requests (so OG checkers work).\n * Set botsOnly: true to only serve to search engine bots.\n */\n\nimport { isBot, isStaticAsset, isExcluded, fetchPrerendered, type RankDeployOptions } from \"./index\";\n\ninterface NextMiddlewareRequest {\n headers: { get(name: string): string | null };\n nextUrl: { pathname: string; toString(): string };\n}\n\nexport function createMiddleware(options: RankDeployOptions) {\n return async function middleware(request: NextMiddlewareRequest) {\n const userAgent = request.headers.get(\"user-agent\") || \"\";\n const pathname = request.nextUrl.pathname;\n\n // Skip static assets and excluded paths\n if (isStaticAsset(pathname) || isExcluded(pathname, options.excludePaths)) {\n return;\n }\n\n // If botsOnly mode, only intercept bot requests\n if (options.botsOnly && !isBot(userAgent, options.extraBots)) {\n return;\n }\n\n const html = await fetchPrerendered(request.nextUrl.toString(), userAgent, options.siteKey, options.apiUrl);\n\n if (html) {\n return new Response(html, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"X-Prerendered\": \"true\",\n \"X-Powered-By\": \"Rank Deploy\",\n },\n });\n }\n\n return;\n };\n}\n\nexport const config = {\n matcher: [\"/((?!api|_next/static|_next/image|favicon.ico).*)\"],\n};\n"],"mappings":";;;;;;;;AAeO,SAAS,iBAAiB,SAA4B;AAC3D,SAAO,eAAe,WAAW,SAAgC;AAC/D,UAAM,YAAY,QAAQ,QAAQ,IAAI,YAAY,KAAK;AACvD,UAAM,WAAW,QAAQ,QAAQ;AAGjC,QAAI,cAAc,QAAQ,KAAK,WAAW,UAAU,QAAQ,YAAY,GAAG;AACzE;AAAA,IACF;AAGA,QAAI,QAAQ,YAAY,CAAC,MAAM,WAAW,QAAQ,SAAS,GAAG;AAC5D;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,iBAAiB,QAAQ,QAAQ,SAAS,GAAG,WAAW,QAAQ,SAAS,QAAQ,MAAM;AAE1G,QAAI,MAAM;AACR,aAAO,IAAI,SAAS,MAAM;AAAA,QACxB,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,IACH;AAEA;AAAA,EACF;AACF;AAEO,IAAM,SAAS;AAAA,EACpB,SAAS,CAAC,mDAAmD;AAC/D;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rankdeploy-middleware",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "SEO middleware for Rank Deploy — serves pre-rendered HTML to search engine bots",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -27,12 +27,24 @@
|
|
|
27
27
|
"types": "./dist/express.d.ts"
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
|
-
"files": [
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
31
34
|
"scripts": {
|
|
32
35
|
"build": "tsup",
|
|
33
36
|
"prepublishOnly": "npm run build"
|
|
34
37
|
},
|
|
35
|
-
"keywords": [
|
|
38
|
+
"keywords": [
|
|
39
|
+
"seo",
|
|
40
|
+
"prerender",
|
|
41
|
+
"middleware",
|
|
42
|
+
"nextjs",
|
|
43
|
+
"netlify",
|
|
44
|
+
"express",
|
|
45
|
+
"rankdeploy",
|
|
46
|
+
"googlebot"
|
|
47
|
+
],
|
|
36
48
|
"author": "Rank Deploy",
|
|
37
49
|
"license": "MIT",
|
|
38
50
|
"devDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @rankdeploy/middleware — Core SEO middleware engine\n *\n * Detects search engine bots and serves pre-rendered HTML from Rank Deploy API.\n * Human visitors are not affected.\n *\n * Usage:\n * import { middleware } from '@rankdeploy/middleware/next' // Next.js\n * import { default } from '@rankdeploy/middleware/netlify' // Netlify\n * import { rankdeploy } from '@rankdeploy/middleware/express' // Express\n */\n\nexport const RANKDEPLOY_API = \"https://proxy.unikium.com\";\n\nexport const BOT_USER_AGENTS = [\n \"googlebot\", \"bingbot\", \"yandexbot\", \"duckduckbot\", \"baiduspider\",\n \"slurp\", \"sogou\", \"exabot\",\n \"facebot\", \"facebookexternalhit\", \"twitterbot\", \"linkedinbot\",\n \"whatsapp\", \"telegrambot\", \"applebot\", \"discordbot\", \"slackbot\", \"pinterest\",\n \"screaming frog\", \"ahrefs\", \"semrush\", \"moz.com\", \"rogerbot\", \"dotbot\",\n \"gptbot\", \"chatgpt\", \"anthropic\", \"claudebot\", \"perplexitybot\", \"cohere\",\n];\n\nexport const STATIC_EXTENSIONS = /\\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|json|xml|txt|mp4|webm|pdf|zip)$/i;\n\nexport interface RankDeployOptions {\n /** Rank Deploy API URL. Default: https://proxy.unikium.com */\n apiUrl?: string;\n /** Additional bot user agents to detect */\n extraBots?: string[];\n /** Paths to exclude from pre-rendering */\n excludePaths?: string[];\n}\n\n/**\n * Check if a user agent string belongs to a bot.\n */\nexport function isBot(userAgent: string, extraBots?: string[]): boolean {\n const ua = userAgent.toLowerCase();\n const allBots = extraBots ? [...BOT_USER_AGENTS, ...extraBots] : BOT_USER_AGENTS;\n return allBots.some((bot) => ua.includes(bot));\n}\n\n/**\n * Check if a path is a static asset.\n */\nexport function isStaticAsset(pathname: string): boolean {\n return STATIC_EXTENSIONS.test(pathname);\n}\n\n/**\n * Check if a path should be excluded.\n */\nexport function isExcluded(pathname: string, excludePaths?: string[]): boolean {\n if (!excludePaths) return false;\n return excludePaths.some((p) => pathname.startsWith(p));\n}\n\n/**\n * Fetch pre-rendered HTML from Rank Deploy API.\n * Returns the HTML string if available, null otherwise.\n */\nexport async function fetchPrerendered(\n url: string,\n userAgent: string,\n apiUrl = RANKDEPLOY_API,\n): Promise<string | null> {\n try {\n const res = await fetch(\n `${apiUrl}/render?url=${encodeURIComponent(url)}`,\n {\n headers: { \"User-Agent\": userAgent },\n signal: AbortSignal.timeout(10_000), // 10s timeout\n },\n );\n\n if (res.status === 200) {\n return res.text();\n }\n\n // 204 = passthrough (no cache), anything else = error\n return null;\n } catch {\n // Network error, timeout — fail silently\n return null;\n }\n}\n"],"mappings":";AAYO,IAAM,iBAAiB;AAEvB,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EAAa;AAAA,EAAW;AAAA,EAAa;AAAA,EAAe;AAAA,EACpD;AAAA,EAAS;AAAA,EAAS;AAAA,EAClB;AAAA,EAAW;AAAA,EAAuB;AAAA,EAAc;AAAA,EAChD;AAAA,EAAY;AAAA,EAAe;AAAA,EAAY;AAAA,EAAc;AAAA,EAAY;AAAA,EACjE;AAAA,EAAkB;AAAA,EAAU;AAAA,EAAW;AAAA,EAAW;AAAA,EAAY;AAAA,EAC9D;AAAA,EAAU;AAAA,EAAW;AAAA,EAAa;AAAA,EAAa;AAAA,EAAiB;AAClE;AAEO,IAAM,oBAAoB;AAc1B,SAAS,MAAM,WAAmB,WAA+B;AACtE,QAAM,KAAK,UAAU,YAAY;AACjC,QAAM,UAAU,YAAY,CAAC,GAAG,iBAAiB,GAAG,SAAS,IAAI;AACjE,SAAO,QAAQ,KAAK,CAAC,QAAQ,GAAG,SAAS,GAAG,CAAC;AAC/C;AAKO,SAAS,cAAc,UAA2B;AACvD,SAAO,kBAAkB,KAAK,QAAQ;AACxC;AAKO,SAAS,WAAW,UAAkB,cAAkC;AAC7E,MAAI,CAAC,aAAc,QAAO;AAC1B,SAAO,aAAa,KAAK,CAAC,MAAM,SAAS,WAAW,CAAC,CAAC;AACxD;AAMA,eAAsB,iBACpB,KACA,WACA,SAAS,gBACe;AACxB,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAG,MAAM,eAAe,mBAAmB,GAAG,CAAC;AAAA,MAC/C;AAAA,QACE,SAAS,EAAE,cAAc,UAAU;AAAA,QACnC,QAAQ,YAAY,QAAQ,GAAM;AAAA;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,KAAK;AACtB,aAAO,IAAI,KAAK;AAAA,IAClB;AAGA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/dist/express.d.mts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { RankDeployOptions } from './index.mjs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @rankdeploy/middleware/express — Express.js middleware
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* import { rankdeploy } from '@rankdeploy/middleware/express'
|
|
8
|
-
* app.use(rankdeploy())
|
|
9
|
-
*
|
|
10
|
-
* With options:
|
|
11
|
-
* app.use(rankdeploy({ excludePaths: ['/api', '/admin'] }))
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
interface ExpressRequest {
|
|
15
|
-
headers: Record<string, string | string[] | undefined>;
|
|
16
|
-
url: string;
|
|
17
|
-
protocol: string;
|
|
18
|
-
get(name: string): string | undefined;
|
|
19
|
-
}
|
|
20
|
-
interface ExpressResponse {
|
|
21
|
-
set(name: string, value: string): void;
|
|
22
|
-
status(code: number): ExpressResponse;
|
|
23
|
-
send(body: string): void;
|
|
24
|
-
}
|
|
25
|
-
type NextFunction = () => void;
|
|
26
|
-
/**
|
|
27
|
-
* Create Express middleware for Rank Deploy.
|
|
28
|
-
*
|
|
29
|
-
* Usage:
|
|
30
|
-
* app.use(rankdeploy())
|
|
31
|
-
*/
|
|
32
|
-
declare function rankdeploy(options?: RankDeployOptions): (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => Promise<void>;
|
|
33
|
-
|
|
34
|
-
export { rankdeploy as default, rankdeploy };
|
package/dist/express.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { RankDeployOptions } from './index.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @rankdeploy/middleware/express — Express.js middleware
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* import { rankdeploy } from '@rankdeploy/middleware/express'
|
|
8
|
-
* app.use(rankdeploy())
|
|
9
|
-
*
|
|
10
|
-
* With options:
|
|
11
|
-
* app.use(rankdeploy({ excludePaths: ['/api', '/admin'] }))
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
interface ExpressRequest {
|
|
15
|
-
headers: Record<string, string | string[] | undefined>;
|
|
16
|
-
url: string;
|
|
17
|
-
protocol: string;
|
|
18
|
-
get(name: string): string | undefined;
|
|
19
|
-
}
|
|
20
|
-
interface ExpressResponse {
|
|
21
|
-
set(name: string, value: string): void;
|
|
22
|
-
status(code: number): ExpressResponse;
|
|
23
|
-
send(body: string): void;
|
|
24
|
-
}
|
|
25
|
-
type NextFunction = () => void;
|
|
26
|
-
/**
|
|
27
|
-
* Create Express middleware for Rank Deploy.
|
|
28
|
-
*
|
|
29
|
-
* Usage:
|
|
30
|
-
* app.use(rankdeploy())
|
|
31
|
-
*/
|
|
32
|
-
declare function rankdeploy(options?: RankDeployOptions): (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => Promise<void>;
|
|
33
|
-
|
|
34
|
-
export { rankdeploy as default, rankdeploy };
|
package/dist/index.d.mts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @rankdeploy/middleware — Core SEO middleware engine
|
|
3
|
-
*
|
|
4
|
-
* Detects search engine bots and serves pre-rendered HTML from Rank Deploy API.
|
|
5
|
-
* Human visitors are not affected.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* import { middleware } from '@rankdeploy/middleware/next' // Next.js
|
|
9
|
-
* import { default } from '@rankdeploy/middleware/netlify' // Netlify
|
|
10
|
-
* import { rankdeploy } from '@rankdeploy/middleware/express' // Express
|
|
11
|
-
*/
|
|
12
|
-
declare const RANKDEPLOY_API = "https://proxy.unikium.com";
|
|
13
|
-
declare const BOT_USER_AGENTS: string[];
|
|
14
|
-
declare const STATIC_EXTENSIONS: RegExp;
|
|
15
|
-
interface RankDeployOptions {
|
|
16
|
-
/** Rank Deploy API URL. Default: https://proxy.unikium.com */
|
|
17
|
-
apiUrl?: string;
|
|
18
|
-
/** Additional bot user agents to detect */
|
|
19
|
-
extraBots?: string[];
|
|
20
|
-
/** Paths to exclude from pre-rendering */
|
|
21
|
-
excludePaths?: string[];
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Check if a user agent string belongs to a bot.
|
|
25
|
-
*/
|
|
26
|
-
declare function isBot(userAgent: string, extraBots?: string[]): boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Check if a path is a static asset.
|
|
29
|
-
*/
|
|
30
|
-
declare function isStaticAsset(pathname: string): boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Check if a path should be excluded.
|
|
33
|
-
*/
|
|
34
|
-
declare function isExcluded(pathname: string, excludePaths?: string[]): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Fetch pre-rendered HTML from Rank Deploy API.
|
|
37
|
-
* Returns the HTML string if available, null otherwise.
|
|
38
|
-
*/
|
|
39
|
-
declare function fetchPrerendered(url: string, userAgent: string, apiUrl?: string): Promise<string | null>;
|
|
40
|
-
|
|
41
|
-
export { BOT_USER_AGENTS, RANKDEPLOY_API, type RankDeployOptions, STATIC_EXTENSIONS, fetchPrerendered, isBot, isExcluded, isStaticAsset };
|
package/dist/index.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @rankdeploy/middleware — Core SEO middleware engine
|
|
3
|
-
*
|
|
4
|
-
* Detects search engine bots and serves pre-rendered HTML from Rank Deploy API.
|
|
5
|
-
* Human visitors are not affected.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* import { middleware } from '@rankdeploy/middleware/next' // Next.js
|
|
9
|
-
* import { default } from '@rankdeploy/middleware/netlify' // Netlify
|
|
10
|
-
* import { rankdeploy } from '@rankdeploy/middleware/express' // Express
|
|
11
|
-
*/
|
|
12
|
-
declare const RANKDEPLOY_API = "https://proxy.unikium.com";
|
|
13
|
-
declare const BOT_USER_AGENTS: string[];
|
|
14
|
-
declare const STATIC_EXTENSIONS: RegExp;
|
|
15
|
-
interface RankDeployOptions {
|
|
16
|
-
/** Rank Deploy API URL. Default: https://proxy.unikium.com */
|
|
17
|
-
apiUrl?: string;
|
|
18
|
-
/** Additional bot user agents to detect */
|
|
19
|
-
extraBots?: string[];
|
|
20
|
-
/** Paths to exclude from pre-rendering */
|
|
21
|
-
excludePaths?: string[];
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Check if a user agent string belongs to a bot.
|
|
25
|
-
*/
|
|
26
|
-
declare function isBot(userAgent: string, extraBots?: string[]): boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Check if a path is a static asset.
|
|
29
|
-
*/
|
|
30
|
-
declare function isStaticAsset(pathname: string): boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Check if a path should be excluded.
|
|
33
|
-
*/
|
|
34
|
-
declare function isExcluded(pathname: string, excludePaths?: string[]): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Fetch pre-rendered HTML from Rank Deploy API.
|
|
37
|
-
* Returns the HTML string if available, null otherwise.
|
|
38
|
-
*/
|
|
39
|
-
declare function fetchPrerendered(url: string, userAgent: string, apiUrl?: string): Promise<string | null>;
|
|
40
|
-
|
|
41
|
-
export { BOT_USER_AGENTS, RANKDEPLOY_API, type RankDeployOptions, STATIC_EXTENSIONS, fetchPrerendered, isBot, isExcluded, isStaticAsset };
|
package/dist/netlify.d.mts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import * as undici_types from 'undici-types';
|
|
2
|
-
import { RankDeployOptions } from './index.mjs';
|
|
3
|
-
|
|
4
|
-
interface NetlifyContext {
|
|
5
|
-
next(): Promise<Response>;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Create a Netlify Edge Function handler with custom options.
|
|
9
|
-
*/
|
|
10
|
-
declare function createHandler(options?: RankDeployOptions): (request: Request, context: NetlifyContext) => Promise<undici_types.Response>;
|
|
11
|
-
/**
|
|
12
|
-
* Default handler — ready to use as-is.
|
|
13
|
-
*/
|
|
14
|
-
declare const _default: (request: Request, context: NetlifyContext) => Promise<undici_types.Response>;
|
|
15
|
-
|
|
16
|
-
export { createHandler, _default as default };
|
package/dist/netlify.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import * as undici_types from 'undici-types';
|
|
2
|
-
import { RankDeployOptions } from './index.js';
|
|
3
|
-
|
|
4
|
-
interface NetlifyContext {
|
|
5
|
-
next(): Promise<Response>;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Create a Netlify Edge Function handler with custom options.
|
|
9
|
-
*/
|
|
10
|
-
declare function createHandler(options?: RankDeployOptions): (request: Request, context: NetlifyContext) => Promise<undici_types.Response>;
|
|
11
|
-
/**
|
|
12
|
-
* Default handler — ready to use as-is.
|
|
13
|
-
*/
|
|
14
|
-
declare const _default: (request: Request, context: NetlifyContext) => Promise<undici_types.Response>;
|
|
15
|
-
|
|
16
|
-
export { createHandler, _default as default };
|
package/dist/next.d.mts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import * as undici_types from 'undici-types';
|
|
2
|
-
import { RankDeployOptions } from './index.mjs';
|
|
3
|
-
|
|
4
|
-
interface NextMiddlewareRequest {
|
|
5
|
-
headers: {
|
|
6
|
-
get(name: string): string | null;
|
|
7
|
-
};
|
|
8
|
-
nextUrl: {
|
|
9
|
-
pathname: string;
|
|
10
|
-
toString(): string;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Create a Next.js middleware function with custom options.
|
|
15
|
-
*/
|
|
16
|
-
declare function createMiddleware(options?: RankDeployOptions): (request: NextMiddlewareRequest) => Promise<undici_types.Response | undefined>;
|
|
17
|
-
/**
|
|
18
|
-
* Default middleware — ready to use.
|
|
19
|
-
*/
|
|
20
|
-
declare const middleware: (request: NextMiddlewareRequest) => Promise<undici_types.Response | undefined>;
|
|
21
|
-
declare const config: {
|
|
22
|
-
matcher: string[];
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export { config, createMiddleware, middleware };
|
package/dist/next.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import * as undici_types from 'undici-types';
|
|
2
|
-
import { RankDeployOptions } from './index.js';
|
|
3
|
-
|
|
4
|
-
interface NextMiddlewareRequest {
|
|
5
|
-
headers: {
|
|
6
|
-
get(name: string): string | null;
|
|
7
|
-
};
|
|
8
|
-
nextUrl: {
|
|
9
|
-
pathname: string;
|
|
10
|
-
toString(): string;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Create a Next.js middleware function with custom options.
|
|
15
|
-
*/
|
|
16
|
-
declare function createMiddleware(options?: RankDeployOptions): (request: NextMiddlewareRequest) => Promise<undici_types.Response | undefined>;
|
|
17
|
-
/**
|
|
18
|
-
* Default middleware — ready to use.
|
|
19
|
-
*/
|
|
20
|
-
declare const middleware: (request: NextMiddlewareRequest) => Promise<undici_types.Response | undefined>;
|
|
21
|
-
declare const config: {
|
|
22
|
-
matcher: string[];
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export { config, createMiddleware, middleware };
|