@djangocfg/nextjs 2.1.411 → 2.1.413
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -36
- package/dist/config/index.mjs +1 -1
- package/dist/config/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +110 -137
- package/dist/index.mjs.map +1 -1
- package/dist/sitemap/index.d.mts +126 -56
- package/dist/sitemap/index.mjs +107 -134
- package/dist/sitemap/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/sitemap/README.md +315 -0
- package/src/sitemap/fetch.ts +66 -0
- package/src/sitemap/ids.ts +21 -0
- package/src/sitemap/index.ts +22 -4
- package/src/sitemap/robots.ts +34 -0
- package/src/sitemap/sitemap.ts +94 -0
- package/src/sitemap/types.ts +67 -17
- package/src/sitemap/generator.ts +0 -144
- package/src/sitemap/route.ts +0 -146
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports, module) {
|
|
15
15
|
module.exports = {
|
|
16
16
|
name: "@djangocfg/nextjs",
|
|
17
|
-
version: "2.1.
|
|
17
|
+
version: "2.1.413",
|
|
18
18
|
description: "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
19
19
|
keywords: [
|
|
20
20
|
"nextjs",
|
|
@@ -204,155 +204,125 @@ var require_package = __commonJS({
|
|
|
204
204
|
}
|
|
205
205
|
});
|
|
206
206
|
|
|
207
|
-
// src/sitemap/
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
<loc>${escapeXml(loc)}</loc>${hreflangLinks}
|
|
230
|
-
${lastmod ? `<lastmod>${formatDate(lastmod)}</lastmod>` : ""}
|
|
231
|
-
${changefreq ? `<changefreq>${changefreq}</changefreq>` : ""}
|
|
232
|
-
${priority !== void 0 ? `<priority>${priority.toFixed(1)}</priority>` : ""}
|
|
233
|
-
</url>`;
|
|
234
|
-
}).join("\n")}
|
|
235
|
-
</urlset>`;
|
|
236
|
-
}
|
|
237
|
-
function generateHreflangLinks(loc, i18n, siteUrl) {
|
|
238
|
-
const { locales, defaultLocale } = i18n;
|
|
239
|
-
const baseSiteUrl = siteUrl.endsWith("/") ? siteUrl.slice(0, -1) : siteUrl;
|
|
240
|
-
let path = loc.replace(baseSiteUrl, "");
|
|
241
|
-
for (const locale of locales) {
|
|
242
|
-
const localePrefix = `/${locale}`;
|
|
243
|
-
if (path === localePrefix || path.startsWith(`${localePrefix}/`)) {
|
|
244
|
-
path = path.slice(localePrefix.length) || "/";
|
|
245
|
-
break;
|
|
207
|
+
// src/sitemap/fetch.ts
|
|
208
|
+
var EMPTY_INDEX = {
|
|
209
|
+
sources: [],
|
|
210
|
+
generated_at: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
211
|
+
ttl_seconds: 60
|
|
212
|
+
};
|
|
213
|
+
var emptyFeed = (source, cursor) => ({
|
|
214
|
+
source,
|
|
215
|
+
chunk_id: `${source}-empty`,
|
|
216
|
+
count: 0,
|
|
217
|
+
has_more: false,
|
|
218
|
+
next_cursor: cursor,
|
|
219
|
+
entries: []
|
|
220
|
+
});
|
|
221
|
+
async function fetchSitemapIndex(apiUrl, revalidate) {
|
|
222
|
+
try {
|
|
223
|
+
const r = await fetch(`${apiUrl}/cfg/sitemap/index/`, {
|
|
224
|
+
next: { revalidate }
|
|
225
|
+
});
|
|
226
|
+
if (!r.ok) {
|
|
227
|
+
console.warn(`[sitemap] index fetch returned ${r.status}; falling back to empty`);
|
|
228
|
+
return EMPTY_INDEX;
|
|
246
229
|
}
|
|
230
|
+
return await r.json();
|
|
231
|
+
} catch (err) {
|
|
232
|
+
console.warn("[sitemap] index fetch failed:", err);
|
|
233
|
+
return EMPTY_INDEX;
|
|
247
234
|
}
|
|
248
|
-
const links = [];
|
|
249
|
-
for (const locale of locales) {
|
|
250
|
-
const localePath = locale === defaultLocale ? path : path === "/" ? `/${locale}` : `/${locale}${path}`;
|
|
251
|
-
const fullUrl = `${baseSiteUrl}${localePath}`;
|
|
252
|
-
links.push(
|
|
253
|
-
` <xhtml:link rel="alternate" hreflang="${locale}" href="${escapeXml(fullUrl)}"/>`
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
const defaultUrl = `${baseSiteUrl}${path}`;
|
|
257
|
-
links.push(
|
|
258
|
-
` <xhtml:link rel="alternate" hreflang="x-default" href="${escapeXml(defaultUrl)}"/>`
|
|
259
|
-
);
|
|
260
|
-
return "\n" + links.join("\n");
|
|
261
235
|
}
|
|
262
|
-
function
|
|
263
|
-
|
|
264
|
-
|
|
236
|
+
async function fetchSitemapFeed(apiUrl, source, cursor, revalidate) {
|
|
237
|
+
const params = new URLSearchParams({ source });
|
|
238
|
+
if (cursor) params.set("cursor", cursor);
|
|
239
|
+
try {
|
|
240
|
+
const r = await fetch(`${apiUrl}/cfg/sitemap/feed/?${params}`, {
|
|
241
|
+
next: { revalidate }
|
|
242
|
+
});
|
|
243
|
+
if (!r.ok) {
|
|
244
|
+
console.warn(`[sitemap] feed ${source} returned ${r.status}; falling back to empty`);
|
|
245
|
+
return emptyFeed(source, cursor);
|
|
246
|
+
}
|
|
247
|
+
return await r.json();
|
|
248
|
+
} catch (err) {
|
|
249
|
+
console.warn(`[sitemap] feed ${source} fetch failed:`, err);
|
|
250
|
+
return emptyFeed(source, cursor);
|
|
265
251
|
}
|
|
266
|
-
return date.toISOString().split("T")[0];
|
|
267
252
|
}
|
|
268
|
-
|
|
269
|
-
|
|
253
|
+
|
|
254
|
+
// src/sitemap/ids.ts
|
|
255
|
+
function encodeChunkId(source, cursor) {
|
|
256
|
+
return `${source}--${cursor ?? ""}`;
|
|
270
257
|
}
|
|
271
|
-
function
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
return `${baseUrl}${path}`;
|
|
258
|
+
function decodeChunkId(id) {
|
|
259
|
+
const sep = id.indexOf("--");
|
|
260
|
+
if (sep === -1) return { source: id, cursor: null };
|
|
261
|
+
const source = id.slice(0, sep);
|
|
262
|
+
const cursorRaw = id.slice(sep + 2);
|
|
263
|
+
return { source, cursor: cursorRaw === "" ? null : cursorRaw };
|
|
278
264
|
}
|
|
279
265
|
|
|
280
|
-
// src/sitemap/
|
|
281
|
-
|
|
266
|
+
// src/sitemap/sitemap.ts
|
|
267
|
+
var STATIC_ID = "static";
|
|
268
|
+
var DEFAULT_INDEX_REVALIDATE = 600;
|
|
269
|
+
var DEFAULT_FEED_REVALIDATE = 3600;
|
|
270
|
+
function createDjangoSitemap(opts) {
|
|
282
271
|
const {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
} =
|
|
289
|
-
return
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
272
|
+
host,
|
|
273
|
+
apiUrl,
|
|
274
|
+
staticRoutes = [],
|
|
275
|
+
indexRevalidate = DEFAULT_INDEX_REVALIDATE,
|
|
276
|
+
feedRevalidate = DEFAULT_FEED_REVALIDATE
|
|
277
|
+
} = opts;
|
|
278
|
+
return {
|
|
279
|
+
async generateSitemaps() {
|
|
280
|
+
const ids = [{ id: STATIC_ID }];
|
|
281
|
+
if (!apiUrl) return ids;
|
|
282
|
+
const index = await fetchSitemapIndex(apiUrl, indexRevalidate);
|
|
283
|
+
for (const s of index.sources) {
|
|
284
|
+
for (const c of s.chunks) {
|
|
285
|
+
ids.push({ id: encodeChunkId(s.name, c.cursor_to) });
|
|
286
|
+
}
|
|
297
287
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
288
|
+
return ids;
|
|
289
|
+
},
|
|
290
|
+
async sitemap({ id: idPromise }) {
|
|
291
|
+
const id = await idPromise;
|
|
292
|
+
if (id === STATIC_ID) {
|
|
293
|
+
return renderStatic(host, staticRoutes);
|
|
294
|
+
}
|
|
295
|
+
if (!apiUrl) return [];
|
|
296
|
+
const { source, cursor } = decodeChunkId(id);
|
|
297
|
+
const feed = await fetchSitemapFeed(apiUrl, source, cursor, feedRevalidate);
|
|
298
|
+
return feed.entries.map((e) => ({
|
|
299
|
+
url: `${host}${e.loc}`,
|
|
300
|
+
lastModified: e.lastmod ? new Date(e.lastmod) : void 0
|
|
306
301
|
}));
|
|
307
302
|
}
|
|
308
|
-
const sitemap = generateSitemapXml({
|
|
309
|
-
urls: expandedUrls,
|
|
310
|
-
i18n,
|
|
311
|
-
siteUrl
|
|
312
|
-
});
|
|
313
|
-
return new NextResponse(sitemap, {
|
|
314
|
-
status: 200,
|
|
315
|
-
headers: {
|
|
316
|
-
"Content-Type": "application/xml",
|
|
317
|
-
"Cache-Control": cacheControl
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
303
|
};
|
|
321
304
|
}
|
|
322
|
-
function
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
loc: normalizeUrl(path, siteUrl)
|
|
340
|
-
});
|
|
341
|
-
} else {
|
|
342
|
-
for (const locale of locales) {
|
|
343
|
-
const localePath = locale === defaultLocale ? path : path === "/" ? `/${locale}` : `/${locale}${path}`;
|
|
344
|
-
expandedUrls.push({
|
|
345
|
-
...url,
|
|
346
|
-
loc: `${baseSiteUrl}${localePath}`
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return expandedUrls;
|
|
305
|
+
function renderStatic(host, routes) {
|
|
306
|
+
return routes.map((r) => ({
|
|
307
|
+
url: `${host}${r.path}`,
|
|
308
|
+
changeFrequency: r.changeFrequency,
|
|
309
|
+
priority: r.priority
|
|
310
|
+
}));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// src/sitemap/robots.ts
|
|
314
|
+
var DEFAULT_DISALLOW = ["/account/", "/auth", "/api/"];
|
|
315
|
+
function createRobots(opts) {
|
|
316
|
+
const { host, disallow = DEFAULT_DISALLOW, sitemap } = opts;
|
|
317
|
+
return () => ({
|
|
318
|
+
rules: [{ userAgent: "*", allow: "/", disallow }],
|
|
319
|
+
sitemap: sitemap ?? `${host}/sitemap.xml`,
|
|
320
|
+
host
|
|
321
|
+
});
|
|
352
322
|
}
|
|
353
323
|
|
|
354
324
|
// src/health/route.ts
|
|
355
|
-
import { NextResponse
|
|
325
|
+
import { NextResponse } from "next/server";
|
|
356
326
|
function createHealthHandler(config = {}) {
|
|
357
327
|
const { version, checks = [], customData = {} } = config;
|
|
358
328
|
return async function GET() {
|
|
@@ -382,7 +352,7 @@ function createHealthHandler(config = {}) {
|
|
|
382
352
|
...customData
|
|
383
353
|
};
|
|
384
354
|
const statusCode = status === "ok" ? 200 : 503;
|
|
385
|
-
return
|
|
355
|
+
return NextResponse.json(response, { status: statusCode });
|
|
386
356
|
};
|
|
387
357
|
}
|
|
388
358
|
|
|
@@ -1900,15 +1870,19 @@ export {
|
|
|
1900
1870
|
checkForUpdates,
|
|
1901
1871
|
checkPackages,
|
|
1902
1872
|
createBaseNextConfig,
|
|
1873
|
+
createDjangoSitemap,
|
|
1903
1874
|
createHealthHandler,
|
|
1904
|
-
|
|
1875
|
+
createRobots,
|
|
1876
|
+
decodeChunkId,
|
|
1905
1877
|
deepMerge,
|
|
1906
1878
|
defineRoute,
|
|
1907
1879
|
detectPackageManager,
|
|
1880
|
+
encodeChunkId,
|
|
1908
1881
|
fetchLatestVersion2 as fetchLatestVersion,
|
|
1882
|
+
fetchSitemapFeed,
|
|
1883
|
+
fetchSitemapIndex,
|
|
1909
1884
|
findRoute,
|
|
1910
1885
|
findRouteByPattern,
|
|
1911
|
-
generateSitemapXml,
|
|
1912
1886
|
getApiUrl,
|
|
1913
1887
|
getBasePath,
|
|
1914
1888
|
getCurrentVersion,
|
|
@@ -1933,7 +1907,6 @@ export {
|
|
|
1933
1907
|
isPackageInstalled,
|
|
1934
1908
|
isProduction,
|
|
1935
1909
|
isStaticBuild,
|
|
1936
|
-
normalizeUrl,
|
|
1937
1910
|
printVersionInfo,
|
|
1938
1911
|
redirectToAuth,
|
|
1939
1912
|
resetDevStartupState,
|