@onruntime/next-sitemap 0.6.1 → 0.7.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/app/index.cjs +193 -208
- package/dist/app/index.d.cts +6 -11
- package/dist/app/index.d.ts +6 -11
- package/dist/app/index.js +194 -205
- package/dist/index.cjs +207 -0
- package/dist/index.d.cts +56 -1
- package/dist/index.d.ts +56 -1
- package/dist/index.js +179 -1
- package/dist/loader.js +38 -0
- package/dist/pages/index.cjs +194 -200
- package/dist/pages/index.d.cts +9 -27
- package/dist/pages/index.d.ts +9 -27
- package/dist/pages/index.js +195 -197
- package/dist/worker.cjs +207 -0
- package/package.json +2 -2
package/dist/app/index.cjs
CHANGED
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('fs');
|
|
4
4
|
var path = require('path');
|
|
5
|
-
var
|
|
6
|
-
var
|
|
5
|
+
var childProcess = require('child_process');
|
|
6
|
+
var url = require('url');
|
|
7
7
|
|
|
8
8
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
9
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
-
|
|
11
9
|
function _interopNamespace(e) {
|
|
12
10
|
if (e && e.__esModule) return e;
|
|
13
11
|
var n = Object.create(null);
|
|
@@ -26,11 +24,168 @@ function _interopNamespace(e) {
|
|
|
26
24
|
return Object.freeze(n);
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
var
|
|
30
|
-
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
31
|
-
var stripJsonComments__default = /*#__PURE__*/_interopDefault(stripJsonComments);
|
|
27
|
+
var childProcess__namespace = /*#__PURE__*/_interopNamespace(childProcess);
|
|
32
28
|
|
|
33
29
|
// src/app/index.ts
|
|
30
|
+
var NO_STATIC_PARAMS = "NO_STATIC_PARAMS";
|
|
31
|
+
var spawnProcess = childProcess__namespace.spawn;
|
|
32
|
+
var __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
33
|
+
var paramsCache = /* @__PURE__ */ new Map();
|
|
34
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
35
|
+
async function executeWorker(directory, fileKey, debug) {
|
|
36
|
+
const absolutePath = path.join(directory, fileKey.replace("./", ""));
|
|
37
|
+
const projectRoot = process.cwd();
|
|
38
|
+
const distRoot = path.join(__dirname$1, "..");
|
|
39
|
+
const workerPath = path.join(distRoot, "worker.cjs");
|
|
40
|
+
const loaderPath = path.join(distRoot, "loader.js");
|
|
41
|
+
if (debug) {
|
|
42
|
+
console.log(`[next-sitemap] Worker path: ${workerPath}`);
|
|
43
|
+
console.log(`[next-sitemap] Worker exists: ${fs.existsSync(workerPath)}`);
|
|
44
|
+
console.log(`[next-sitemap] Loader path: ${loaderPath}`);
|
|
45
|
+
console.log(`[next-sitemap] Loader exists: ${fs.existsSync(loaderPath)}`);
|
|
46
|
+
}
|
|
47
|
+
return new Promise((resolve) => {
|
|
48
|
+
const nodePath = [
|
|
49
|
+
path.join(projectRoot, "node_modules"),
|
|
50
|
+
path.join(__dirname$1, "..", "node_modules")
|
|
51
|
+
].join(path.delimiter);
|
|
52
|
+
const importFlag = ["--import", loaderPath];
|
|
53
|
+
const args = [...importFlag, workerPath, absolutePath, projectRoot];
|
|
54
|
+
const child = spawnProcess("node", args, {
|
|
55
|
+
cwd: projectRoot,
|
|
56
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
57
|
+
env: { ...process.env, NODE_PATH: nodePath }
|
|
58
|
+
});
|
|
59
|
+
let stdout = "";
|
|
60
|
+
let stderr = "";
|
|
61
|
+
child.stdout.on("data", (data) => {
|
|
62
|
+
stdout += data.toString();
|
|
63
|
+
});
|
|
64
|
+
child.stderr.on("data", (data) => {
|
|
65
|
+
stderr += data.toString();
|
|
66
|
+
});
|
|
67
|
+
child.on("close", (code) => {
|
|
68
|
+
if (debug && stderr) {
|
|
69
|
+
console.warn(`[next-sitemap] Worker stderr: ${stderr}`);
|
|
70
|
+
}
|
|
71
|
+
if (code !== 0 && code !== null) {
|
|
72
|
+
if (debug) console.warn(`[next-sitemap] Worker exited with code ${code}`);
|
|
73
|
+
resolve(null);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const lines = stdout.trim().split("\n");
|
|
78
|
+
const result = JSON.parse(lines[lines.length - 1]);
|
|
79
|
+
if (result.success) {
|
|
80
|
+
resolve(result.params);
|
|
81
|
+
} else {
|
|
82
|
+
if (result.error !== NO_STATIC_PARAMS && debug) {
|
|
83
|
+
console.warn(`[next-sitemap] Worker error: ${result.error}`);
|
|
84
|
+
}
|
|
85
|
+
resolve(null);
|
|
86
|
+
}
|
|
87
|
+
} catch {
|
|
88
|
+
if (debug) console.warn(`[next-sitemap] Failed to parse worker output: ${stdout}`);
|
|
89
|
+
resolve(null);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
child.on("error", (err) => {
|
|
93
|
+
if (debug) console.warn(`[next-sitemap] Failed to spawn worker: ${err.message}`);
|
|
94
|
+
resolve(null);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async function getRouteParams(route, directory, debug) {
|
|
99
|
+
const cacheKey = route.fileKey;
|
|
100
|
+
if (paramsCache.has(cacheKey)) {
|
|
101
|
+
return paramsCache.get(cacheKey);
|
|
102
|
+
}
|
|
103
|
+
if (debug) {
|
|
104
|
+
console.log(`[next-sitemap] ${route.pathname}: executing static params via worker`);
|
|
105
|
+
}
|
|
106
|
+
const params = await executeWorker(directory, route.fileKey, debug);
|
|
107
|
+
paramsCache.set(cacheKey, params);
|
|
108
|
+
if (debug && params) {
|
|
109
|
+
console.log(`[next-sitemap] ${route.pathname}: got ${params.length} params`);
|
|
110
|
+
}
|
|
111
|
+
return params;
|
|
112
|
+
}
|
|
113
|
+
async function generateAllPaths(routes, directory, debug) {
|
|
114
|
+
const staticPaths = ["/"];
|
|
115
|
+
const dynamicRoutes = [];
|
|
116
|
+
for (const route of routes) {
|
|
117
|
+
if (route.dynamicSegments.length === 0) {
|
|
118
|
+
if (route.pathname !== "/") {
|
|
119
|
+
staticPaths.push(route.pathname);
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
dynamicRoutes.push(route);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const startTime = isDev ? Date.now() : 0;
|
|
126
|
+
if (isDev && dynamicRoutes.length > 0) {
|
|
127
|
+
console.log(`[next-sitemap] Generating sitemap for ${dynamicRoutes.length} dynamic routes (dev only, instant in production)...`);
|
|
128
|
+
}
|
|
129
|
+
const dynamicResults = await Promise.all(
|
|
130
|
+
dynamicRoutes.map(async (route) => {
|
|
131
|
+
const params = await getRouteParams(route, directory, debug);
|
|
132
|
+
if (!params || params.length === 0) {
|
|
133
|
+
if (debug) {
|
|
134
|
+
console.warn(`[next-sitemap] Skipping dynamic route ${route.pathname}: no static params or empty result.`);
|
|
135
|
+
}
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
const paths = [];
|
|
139
|
+
for (const param of params) {
|
|
140
|
+
let path = route.pathname;
|
|
141
|
+
let valid = true;
|
|
142
|
+
for (const segment of route.dynamicSegments) {
|
|
143
|
+
const value = param[segment];
|
|
144
|
+
if (value === void 0) {
|
|
145
|
+
if (debug) {
|
|
146
|
+
console.warn(`[next-sitemap] ${route.pathname}: missing param "${segment}" in`, param);
|
|
147
|
+
}
|
|
148
|
+
valid = false;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
path = path.replace(`[${segment}]`, value);
|
|
152
|
+
}
|
|
153
|
+
if (valid) paths.push(path);
|
|
154
|
+
}
|
|
155
|
+
return paths;
|
|
156
|
+
})
|
|
157
|
+
);
|
|
158
|
+
const allPaths = new Set(staticPaths);
|
|
159
|
+
for (const paths of dynamicResults) {
|
|
160
|
+
for (const path of paths) {
|
|
161
|
+
allPaths.add(path);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (isDev && dynamicRoutes.length > 0) {
|
|
165
|
+
const elapsed = Date.now() - startTime;
|
|
166
|
+
console.log(`[next-sitemap] Done! Found ${allPaths.size} total URLs in ${elapsed}ms.`);
|
|
167
|
+
}
|
|
168
|
+
return Array.from(allPaths);
|
|
169
|
+
}
|
|
170
|
+
function pathsToEntries(paths, config) {
|
|
171
|
+
const { baseUrl, locales = [], defaultLocale, exclude, priority, changeFreq } = config;
|
|
172
|
+
return paths.filter((pathname) => !shouldExclude(pathname, exclude)).map((pathname) => {
|
|
173
|
+
const entry = {
|
|
174
|
+
url: buildUrl(baseUrl, pathname, defaultLocale, defaultLocale),
|
|
175
|
+
lastModified: /* @__PURE__ */ new Date(),
|
|
176
|
+
changeFrequency: getChangeFreq(pathname, changeFreq),
|
|
177
|
+
priority: getPriority(pathname, priority)
|
|
178
|
+
};
|
|
179
|
+
if (locales.length > 0) {
|
|
180
|
+
entry.alternates = {
|
|
181
|
+
languages: Object.fromEntries(
|
|
182
|
+
locales.map((locale) => [locale, buildUrl(baseUrl, pathname, locale, defaultLocale)])
|
|
183
|
+
)
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return entry;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
34
189
|
|
|
35
190
|
// src/index.ts
|
|
36
191
|
function calculateDepthPriority(pathname) {
|
|
@@ -136,13 +291,13 @@ ${allEntries}
|
|
|
136
291
|
function findPageFiles(dir, baseDir = dir) {
|
|
137
292
|
const files = [];
|
|
138
293
|
try {
|
|
139
|
-
const entries =
|
|
294
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
140
295
|
for (const entry of entries) {
|
|
141
|
-
const fullPath =
|
|
296
|
+
const fullPath = path.join(dir, entry.name);
|
|
142
297
|
if (entry.isDirectory()) {
|
|
143
298
|
files.push(...findPageFiles(fullPath, baseDir));
|
|
144
299
|
} else if (/^page\.(tsx?|jsx?)$/.test(entry.name)) {
|
|
145
|
-
const relativePath = "./" +
|
|
300
|
+
const relativePath = "./" + path.relative(baseDir, fullPath).replace(/\\/g, "/");
|
|
146
301
|
files.push(relativePath);
|
|
147
302
|
}
|
|
148
303
|
}
|
|
@@ -150,83 +305,12 @@ function findPageFiles(dir, baseDir = dir) {
|
|
|
150
305
|
}
|
|
151
306
|
return files;
|
|
152
307
|
}
|
|
153
|
-
function
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return srcApp;
|
|
157
|
-
}
|
|
158
|
-
return path__namespace.join(process.cwd(), "app");
|
|
159
|
-
}
|
|
160
|
-
function resolveAppDirectory(options) {
|
|
161
|
-
if (options.appDirectory) {
|
|
162
|
-
return path__namespace.isAbsolute(options.appDirectory) ? options.appDirectory : path__namespace.join(process.cwd(), options.appDirectory);
|
|
308
|
+
function resolveAppDirectory(appDirectory) {
|
|
309
|
+
if (appDirectory) {
|
|
310
|
+
return path.isAbsolute(appDirectory) ? appDirectory : path.join(process.cwd(), appDirectory);
|
|
163
311
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
function getPageKeys(options) {
|
|
167
|
-
return findPageFiles(resolveAppDirectory(options));
|
|
168
|
-
}
|
|
169
|
-
var jitiCache = /* @__PURE__ */ new Map();
|
|
170
|
-
function getTsconfigPaths(projectRoot, debug = false) {
|
|
171
|
-
const alias = {};
|
|
172
|
-
try {
|
|
173
|
-
const tsconfigPath = path__namespace.join(projectRoot, "tsconfig.json");
|
|
174
|
-
if (debug) {
|
|
175
|
-
console.log("[next-sitemap] Looking for tsconfig at:", tsconfigPath);
|
|
176
|
-
console.log("[next-sitemap] tsconfig exists:", fs__namespace.existsSync(tsconfigPath));
|
|
177
|
-
}
|
|
178
|
-
if (fs__namespace.existsSync(tsconfigPath)) {
|
|
179
|
-
const content = fs__namespace.readFileSync(tsconfigPath, "utf-8");
|
|
180
|
-
const withoutComments = stripJsonComments__default.default(content);
|
|
181
|
-
const cleaned = withoutComments.replace(/,(\s*[}\]])/g, "$1");
|
|
182
|
-
if (debug) {
|
|
183
|
-
console.log("[next-sitemap] Cleaned tsconfig (first 500 chars):", cleaned.slice(0, 500));
|
|
184
|
-
}
|
|
185
|
-
const tsconfig = JSON.parse(cleaned);
|
|
186
|
-
if (debug) {
|
|
187
|
-
console.log("[next-sitemap] Parsed tsconfig paths:", tsconfig.compilerOptions?.paths);
|
|
188
|
-
}
|
|
189
|
-
const baseUrl = tsconfig.compilerOptions?.baseUrl || ".";
|
|
190
|
-
const paths = tsconfig.compilerOptions?.paths || {};
|
|
191
|
-
for (const [key, values] of Object.entries(paths)) {
|
|
192
|
-
if (values.length > 0) {
|
|
193
|
-
const aliasKey = key.replace(/\*$/, "");
|
|
194
|
-
const aliasValue = path__namespace.join(projectRoot, baseUrl, values[0].replace(/\*$/, ""));
|
|
195
|
-
alias[aliasKey] = aliasValue;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
} catch (error) {
|
|
200
|
-
if (debug) {
|
|
201
|
-
console.error("[next-sitemap] Error parsing tsconfig:", error);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return alias;
|
|
205
|
-
}
|
|
206
|
-
function getJiti(projectRoot, debug = false) {
|
|
207
|
-
if (jitiCache.has(projectRoot)) {
|
|
208
|
-
return jitiCache.get(projectRoot);
|
|
209
|
-
}
|
|
210
|
-
const alias = getTsconfigPaths(projectRoot, debug);
|
|
211
|
-
if (debug) {
|
|
212
|
-
console.log("[next-sitemap] Final alias config:", JSON.stringify(alias));
|
|
213
|
-
}
|
|
214
|
-
const jiti$1 = jiti.createJiti((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)), {
|
|
215
|
-
moduleCache: false,
|
|
216
|
-
interopDefault: true,
|
|
217
|
-
jsx: true,
|
|
218
|
-
alias
|
|
219
|
-
});
|
|
220
|
-
jitiCache.set(projectRoot, jiti$1);
|
|
221
|
-
return jiti$1;
|
|
222
|
-
}
|
|
223
|
-
async function importPage(appDirectory, key, debug = false) {
|
|
224
|
-
const relativePath = key.replace("./", "");
|
|
225
|
-
const absolutePath = path__namespace.join(appDirectory, relativePath);
|
|
226
|
-
const projectRoot = process.cwd();
|
|
227
|
-
const jiti = getJiti(projectRoot, debug);
|
|
228
|
-
const module = await jiti.import(absolutePath);
|
|
229
|
-
return module.default || module;
|
|
312
|
+
const srcApp = path.join(process.cwd(), "src/app");
|
|
313
|
+
return fs.existsSync(srcApp) ? srcApp : path.join(process.cwd(), "app");
|
|
230
314
|
}
|
|
231
315
|
function extractRoutes(pageKeys, localeSegment) {
|
|
232
316
|
const routes = [];
|
|
@@ -234,163 +318,64 @@ function extractRoutes(pageKeys, localeSegment) {
|
|
|
234
318
|
if (key.includes("[...")) continue;
|
|
235
319
|
let pathname = key.replace("./", "/").replace(/\/page\.(tsx?|jsx?)$/, "");
|
|
236
320
|
if (localeSegment) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
""
|
|
240
|
-
);
|
|
321
|
+
const escapedSegment = localeSegment.replace(/[[\]]/g, "\\$&");
|
|
322
|
+
pathname = pathname.replace(new RegExp(`^/${escapedSegment}`), "");
|
|
241
323
|
}
|
|
242
324
|
pathname = pathname.replace(/\/\([^)]+\)/g, "");
|
|
243
325
|
if (/(?:^|\/)(src|app)(?:\/|$)/.test(pathname)) continue;
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
} else if (!pathname.startsWith("/")) {
|
|
326
|
+
pathname = pathname || "/";
|
|
327
|
+
if (pathname !== "/" && !pathname.startsWith("/")) {
|
|
247
328
|
pathname = "/" + pathname;
|
|
248
329
|
}
|
|
249
|
-
const dynamicSegments = pathname.match(/\[([^\]]+)\]/g)?.map((s) => s.slice(1, -1))
|
|
250
|
-
routes.push({
|
|
251
|
-
pathname,
|
|
252
|
-
dynamicSegments,
|
|
253
|
-
key
|
|
254
|
-
});
|
|
330
|
+
const dynamicSegments = pathname.match(/\[([^\]]+)\]/g)?.map((s) => s.slice(1, -1)) ?? [];
|
|
331
|
+
routes.push({ pathname, dynamicSegments, fileKey: key });
|
|
255
332
|
}
|
|
256
333
|
return routes;
|
|
257
334
|
}
|
|
258
|
-
async function getAllPaths(routes, appDirectory, debug = false) {
|
|
259
|
-
const allPaths = ["/"];
|
|
260
|
-
const seenPaths = /* @__PURE__ */ new Set(["/"]);
|
|
261
|
-
for (const route of routes) {
|
|
262
|
-
if (route.dynamicSegments.length === 0) {
|
|
263
|
-
if (route.pathname !== "/" && !seenPaths.has(route.pathname)) {
|
|
264
|
-
allPaths.push(route.pathname);
|
|
265
|
-
seenPaths.add(route.pathname);
|
|
266
|
-
}
|
|
267
|
-
} else {
|
|
268
|
-
let getParams = null;
|
|
269
|
-
try {
|
|
270
|
-
if (debug) {
|
|
271
|
-
console.log(`[next-sitemap] ${route.pathname}: importing ${route.key}`);
|
|
272
|
-
}
|
|
273
|
-
const module = await importPage(appDirectory, route.key, debug);
|
|
274
|
-
getParams = module.generateStaticParams || null;
|
|
275
|
-
} catch (error) {
|
|
276
|
-
if (debug) {
|
|
277
|
-
console.warn(`[next-sitemap] ${route.pathname}: import failed:`, error);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
if (getParams) {
|
|
281
|
-
try {
|
|
282
|
-
const params = await getParams();
|
|
283
|
-
if (debug) {
|
|
284
|
-
console.log(`[next-sitemap] ${route.pathname}: generateStaticParams returned ${params.length} params`);
|
|
285
|
-
}
|
|
286
|
-
for (const param of params) {
|
|
287
|
-
let dynamicPath = route.pathname;
|
|
288
|
-
for (const segment of route.dynamicSegments) {
|
|
289
|
-
const value = param[segment];
|
|
290
|
-
if (value === void 0) {
|
|
291
|
-
if (debug) {
|
|
292
|
-
console.warn(`[next-sitemap] ${route.pathname}: missing param "${segment}" in`, param);
|
|
293
|
-
}
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
dynamicPath = dynamicPath.replace(`[${segment}]`, value);
|
|
297
|
-
}
|
|
298
|
-
if (!seenPaths.has(dynamicPath)) {
|
|
299
|
-
allPaths.push(dynamicPath);
|
|
300
|
-
seenPaths.add(dynamicPath);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
} catch (error) {
|
|
304
|
-
console.error(`[next-sitemap] Error calling generateStaticParams for ${route.pathname}:`, error);
|
|
305
|
-
}
|
|
306
|
-
} else {
|
|
307
|
-
if (debug) {
|
|
308
|
-
console.warn(
|
|
309
|
-
`[next-sitemap] Skipping dynamic route ${route.pathname}: no generateStaticParams exported. Use additionalSitemaps for routes that fetch data at runtime.`
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
return allPaths;
|
|
316
|
-
}
|
|
317
|
-
function pathsToEntries(paths, config) {
|
|
318
|
-
const { baseUrl, locales = [], defaultLocale, exclude, priority, changeFreq } = config;
|
|
319
|
-
const filteredPaths = paths.filter((pathname) => !shouldExclude(pathname, exclude));
|
|
320
|
-
return filteredPaths.map((pathname) => {
|
|
321
|
-
const entry = {
|
|
322
|
-
url: buildUrl(baseUrl, pathname, defaultLocale, defaultLocale),
|
|
323
|
-
lastModified: /* @__PURE__ */ new Date(),
|
|
324
|
-
changeFrequency: getChangeFreq(pathname, changeFreq),
|
|
325
|
-
priority: getPriority(pathname, priority)
|
|
326
|
-
};
|
|
327
|
-
if (locales.length > 0) {
|
|
328
|
-
entry.alternates = {
|
|
329
|
-
languages: Object.fromEntries(
|
|
330
|
-
locales.map((locale) => [
|
|
331
|
-
locale,
|
|
332
|
-
buildUrl(baseUrl, pathname, locale, defaultLocale)
|
|
333
|
-
])
|
|
334
|
-
)
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
return entry;
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
335
|
function createSitemapIndexHandler(options) {
|
|
341
336
|
const { urlsPerSitemap = 5e3, locales = [], defaultLocale, additionalSitemaps, exclude, debug = false } = options;
|
|
342
337
|
const localeSegment = options.localeSegment ?? (locales.length > 0 || defaultLocale ? "[locale]" : "");
|
|
343
|
-
const appDir = resolveAppDirectory(options);
|
|
344
|
-
const pageKeys =
|
|
338
|
+
const appDir = resolveAppDirectory(options.appDirectory);
|
|
339
|
+
const pageKeys = findPageFiles(appDir);
|
|
345
340
|
const routes = extractRoutes(pageKeys, localeSegment);
|
|
346
341
|
return {
|
|
347
342
|
GET: async () => {
|
|
348
343
|
if (debug) {
|
|
349
|
-
console.log(`[next-sitemap] Found ${routes.length} routes
|
|
350
|
-
routes.forEach((r) => {
|
|
351
|
-
const isDynamic = r.dynamicSegments.length > 0;
|
|
352
|
-
const segments = isDynamic ? ` [${r.dynamicSegments.join(", ")}]` : "";
|
|
353
|
-
console.log(` ${r.pathname}${segments}${isDynamic ? " (dynamic)" : ""}`);
|
|
354
|
-
});
|
|
344
|
+
console.log(`[next-sitemap] Found ${routes.length} routes`);
|
|
355
345
|
}
|
|
356
|
-
const allPaths = await
|
|
357
|
-
const filteredPaths = allPaths.filter((
|
|
346
|
+
const allPaths = await generateAllPaths(routes, appDir, debug);
|
|
347
|
+
const filteredPaths = allPaths.filter((p) => !shouldExclude(p, exclude));
|
|
358
348
|
const sitemapCount = Math.max(1, Math.ceil(filteredPaths.length / urlsPerSitemap));
|
|
359
|
-
|
|
360
|
-
additionalSitemaps
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
headers: { "Content-Type": "application/xml" }
|
|
364
|
-
});
|
|
349
|
+
return new Response(
|
|
350
|
+
generateSitemapIndexXml(options.baseUrl, sitemapCount, { additionalSitemaps }),
|
|
351
|
+
{ headers: { "Content-Type": "application/xml" } }
|
|
352
|
+
);
|
|
365
353
|
}
|
|
366
354
|
};
|
|
367
355
|
}
|
|
368
356
|
function createSitemapHandler(options) {
|
|
369
357
|
const { urlsPerSitemap = 5e3, locales = [], defaultLocale, exclude, debug = false } = options;
|
|
370
358
|
const localeSegment = options.localeSegment ?? (locales.length > 0 || defaultLocale ? "[locale]" : "");
|
|
371
|
-
const appDir = resolveAppDirectory(options);
|
|
372
|
-
const pageKeys =
|
|
359
|
+
const appDir = resolveAppDirectory(options.appDirectory);
|
|
360
|
+
const pageKeys = findPageFiles(appDir);
|
|
373
361
|
const routes = extractRoutes(pageKeys, localeSegment);
|
|
374
362
|
const getFilteredPaths = async () => {
|
|
375
|
-
const allPaths = await
|
|
376
|
-
return allPaths.filter((
|
|
363
|
+
const allPaths = await generateAllPaths(routes, appDir, debug);
|
|
364
|
+
return allPaths.filter((p) => !shouldExclude(p, exclude));
|
|
377
365
|
};
|
|
378
366
|
return {
|
|
379
367
|
generateStaticParams: async () => {
|
|
380
368
|
const filteredPaths = await getFilteredPaths();
|
|
381
|
-
const
|
|
382
|
-
return Array.from({ length:
|
|
369
|
+
const count = Math.max(1, Math.ceil(filteredPaths.length / urlsPerSitemap));
|
|
370
|
+
return Array.from({ length: count }, (_, i) => ({ id: String(i) }));
|
|
383
371
|
},
|
|
384
372
|
GET: async (_request, { params }) => {
|
|
385
373
|
const { id } = await params;
|
|
386
374
|
const sitemapId = parseInt(id, 10);
|
|
387
375
|
const filteredPaths = await getFilteredPaths();
|
|
388
|
-
const
|
|
389
|
-
const end = start + urlsPerSitemap;
|
|
390
|
-
const paths = filteredPaths.slice(start, end);
|
|
376
|
+
const paths = filteredPaths.slice(sitemapId * urlsPerSitemap, (sitemapId + 1) * urlsPerSitemap);
|
|
391
377
|
const entries = pathsToEntries(paths, { ...options, exclude: void 0 });
|
|
392
|
-
|
|
393
|
-
return new Response(xml, {
|
|
378
|
+
return new Response(generateSitemapXml(entries), {
|
|
394
379
|
headers: { "Content-Type": "application/xml" }
|
|
395
380
|
});
|
|
396
381
|
}
|
package/dist/app/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
type ChangeFrequency = "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
2
|
+
|
|
2
3
|
interface SitemapConfig {
|
|
3
4
|
/**
|
|
4
5
|
* Base URL of the site (e.g., "https://example.com")
|
|
@@ -51,6 +52,11 @@ interface SitemapConfig {
|
|
|
51
52
|
* @example additionalSitemaps: ["/products-sitemap.xml", "/blog-sitemap.xml"]
|
|
52
53
|
*/
|
|
53
54
|
additionalSitemaps?: string[];
|
|
55
|
+
/**
|
|
56
|
+
* Enable debug logging to diagnose issues with route discovery
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
59
|
+
debug?: boolean;
|
|
54
60
|
}
|
|
55
61
|
interface SitemapEntry {
|
|
56
62
|
url: string;
|
|
@@ -67,19 +73,8 @@ interface CreateSitemapHandlerOptions extends SitemapConfig {
|
|
|
67
73
|
* Path to the app directory to scan for page.tsx files.
|
|
68
74
|
* Can be absolute or relative to process.cwd().
|
|
69
75
|
* If not provided, auto-detects src/app or app.
|
|
70
|
-
*
|
|
71
|
-
* Example:
|
|
72
|
-
* ```ts
|
|
73
|
-
* appDirectory: 'src/app/(frontend)'
|
|
74
|
-
* ```
|
|
75
76
|
*/
|
|
76
77
|
appDirectory?: string;
|
|
77
|
-
/**
|
|
78
|
-
* Enable debug logging to diagnose issues with route discovery
|
|
79
|
-
* Logs info about generateStaticParams calls and skipped routes
|
|
80
|
-
* @default false
|
|
81
|
-
*/
|
|
82
|
-
debug?: boolean;
|
|
83
78
|
}
|
|
84
79
|
/**
|
|
85
80
|
* Create handlers for sitemap index route
|
package/dist/app/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
type ChangeFrequency = "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
2
|
+
|
|
2
3
|
interface SitemapConfig {
|
|
3
4
|
/**
|
|
4
5
|
* Base URL of the site (e.g., "https://example.com")
|
|
@@ -51,6 +52,11 @@ interface SitemapConfig {
|
|
|
51
52
|
* @example additionalSitemaps: ["/products-sitemap.xml", "/blog-sitemap.xml"]
|
|
52
53
|
*/
|
|
53
54
|
additionalSitemaps?: string[];
|
|
55
|
+
/**
|
|
56
|
+
* Enable debug logging to diagnose issues with route discovery
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
59
|
+
debug?: boolean;
|
|
54
60
|
}
|
|
55
61
|
interface SitemapEntry {
|
|
56
62
|
url: string;
|
|
@@ -67,19 +73,8 @@ interface CreateSitemapHandlerOptions extends SitemapConfig {
|
|
|
67
73
|
* Path to the app directory to scan for page.tsx files.
|
|
68
74
|
* Can be absolute or relative to process.cwd().
|
|
69
75
|
* If not provided, auto-detects src/app or app.
|
|
70
|
-
*
|
|
71
|
-
* Example:
|
|
72
|
-
* ```ts
|
|
73
|
-
* appDirectory: 'src/app/(frontend)'
|
|
74
|
-
* ```
|
|
75
76
|
*/
|
|
76
77
|
appDirectory?: string;
|
|
77
|
-
/**
|
|
78
|
-
* Enable debug logging to diagnose issues with route discovery
|
|
79
|
-
* Logs info about generateStaticParams calls and skipped routes
|
|
80
|
-
* @default false
|
|
81
|
-
*/
|
|
82
|
-
debug?: boolean;
|
|
83
78
|
}
|
|
84
79
|
/**
|
|
85
80
|
* Create handlers for sitemap index route
|