@webnumseoagent/next 0.7.1 → 0.7.2

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.
Files changed (2) hide show
  1. package/bin/cli.mjs +14 -9
  2. package/package.json +1 -1
package/bin/cli.mjs CHANGED
@@ -406,7 +406,7 @@ async function init() {
406
406
  // generateMetadata: у блог-роута свой generateMetadata (seoBlogPost), его НЕ оборачиваем seoMeta.
407
407
  if (!args.includes("--no-blog")) {
408
408
  const jsxExt = ext === "ts" ? "tsx" : "jsx";
409
- const mdParam = ext === "ts" ? "{ params }: { params: { slug: string } }" : "{ params }";
409
+ const mdParam = ext === "ts" ? "{ params }: { params: Promise<{ slug: string }> }" : "{ params }";
410
410
  const madeIndex = await ensureFile(
411
411
  path.join(root, appDir, `blog/page.${jsxExt}`),
412
412
  `import { SeoBlogIndex } from "${blogFor("blog/page.tsx")}";\nexport const dynamic = "force-static";\nexport default function BlogPage() {\n return <SeoBlogIndex title="Блог" />;\n}\n`,
@@ -426,7 +426,7 @@ async function init() {
426
426
  } else {
427
427
  madeArticle = await ensureFile(
428
428
  path.join(root, appDir, `blog/[slug]/page.${jsxExt}`),
429
- `import { notFound } from "next/navigation";\nimport { seoBlogPost, seoBlogStaticParams, SeoBlogArticle } from "${blogFor("blog/[slug]/page.tsx")}";\nexport const dynamic = "force-static";\nexport const dynamicParams = false;\n\n// Полностью статический рендер: все статьи пре-рендерятся на сборке из файлов content/blog. Контент\n// меняется git-коммитом → редеплой. dynamicParams=false: неизвестный слаг → 404 (без рантайм-чтения).\nexport async function generateStaticParams() {\n return seoBlogStaticParams();\n}\n\nexport async function generateMetadata(${mdParam}) {\n const post = await seoBlogPost(params.slug);\n if (!post) return {};\n return { title: post.title, description: post.excerpt, openGraph: { images: post.cover ? [post.cover] : [] } };\n}\n\nexport default async function BlogPostPage(${mdParam}) {\n const post = await seoBlogPost(params.slug);\n if (!post) notFound();\n return <SeoBlogArticle post={post} />;\n}\n`,
429
+ `import { notFound } from "next/navigation";\nimport { seoBlogPost, seoBlogStaticParams, SeoBlogArticle } from "${blogFor("blog/[slug]/page.tsx")}";\nexport const dynamic = "force-static";\nexport const dynamicParams = false;\n\n// Полностью статический рендер: все статьи пре-рендерятся на сборке из файлов content/blog. Контент\n// меняется git-коммитом → редеплой. dynamicParams=false: неизвестный слаг → 404 (без рантайм-чтения).\nexport async function generateStaticParams() {\n return seoBlogStaticParams();\n}\n\nexport async function generateMetadata(${mdParam}) {\n const { slug } = await params;\n const post = await seoBlogPost(slug);\n if (!post) return {};\n return { title: post.title, description: post.excerpt, openGraph: { images: post.cover ? [post.cover] : [] } };\n}\n\nexport default async function BlogPostPage(${mdParam}) {\n const { slug } = await params;\n const post = await seoBlogPost(slug);\n if (!post) notFound();\n return <SeoBlogArticle post={post} />;\n}\n`,
430
430
  );
431
431
  }
432
432
  if (madeIndex || madeArticle) {
@@ -694,30 +694,35 @@ async function blogPage() {
694
694
  // index-роут (список): в [locale] прокидываем locale + basePath. СТАТИЧЕСКИЙ (Фаза 1 git-native):
695
695
  // без searchParams (иначе роут стал бы динамическим и в рантайме Vercel не увидел бы файлы content/blog).
696
696
  const idxSig = param
697
- ? (ext === "ts" ? `{ params }: { params: { ${param}: string } }` : "{ params }")
697
+ ? (ext === "ts" ? `{ params }: { params: Promise<{ ${param}: string }> }` : "{ params }")
698
698
  : "";
699
+ // Next 15: params — Promise, читаем через await (в Next 14 await над объектом тоже безвреден).
700
+ // param==="locale" — деструктурим без переименования (иначе eslint no-useless-rename).
701
+ const idxAwait = param ? ` const { ${param === "locale" ? "locale" : `${param}: locale`} } = await params;\n` : "";
699
702
  const idxBody = param
700
- ? `<SeoBlogIndex locale={params.${param}} basePath={\`/\${params.${param}}/blog\`} />`
703
+ ? `<SeoBlogIndex locale={locale} basePath={\`/\${locale}/blog\`} />`
701
704
  : `<SeoBlogIndex />`;
702
705
  await writeOurRoute(
703
706
  path.join(root, appDir, under, `blog/page.${jsxExt}`),
704
- `import { SeoBlogIndex } from "${blogFor(`${under}blog/page.tsx`)}";\nexport const dynamic = "force-static";\nexport default function BlogPage(${idxSig}) {\n return ${idxBody};\n}\n`,
707
+ `import { SeoBlogIndex } from "${blogFor(`${under}blog/page.tsx`)}";\nexport const dynamic = "force-static";\nexport default async function BlogPage(${idxSig}) {\n${idxAwait} return ${idxBody};\n}\n`,
705
708
  );
706
709
 
707
710
  if (blogDynConflict) {
708
711
  log(`\n \x1b[1mУ сайта уже есть blog/[иной-сегмент]\x1b[0m — роут статьи /blog/[slug] не создаю. Подключи вручную: \x1b[36mimport { seoBlogPost, SeoBlogArticle } from "${blogFor(`${under}blog/[slug]/page.tsx`)}";\x1b[0m`);
709
712
  } else {
710
713
  const artSig = ext === "ts"
711
- ? (param ? `{ params }: { params: { ${param}: string; slug: string } }` : `{ params }: { params: { slug: string } }`)
714
+ ? (param ? `{ params }: { params: Promise<{ ${param}: string; slug: string }> }` : `{ params }: { params: Promise<{ slug: string }> }`)
712
715
  : "{ params }";
713
- const localeArg = param ? `, { locale: params.${param} }` : "";
714
- const localeProp = param ? ` locale={params.${param}}` : "";
716
+ // Next 15: params Promise, читаем через await. Локаль переименовываем в locale (кроме param==="locale").
717
+ const artAwait = param ? ` const { slug, ${param === "locale" ? "locale" : `${param}: locale`} } = await params;\n` : ` const { slug } = await params;\n`;
718
+ const localeArg = param ? `, { locale }` : "";
719
+ const localeProp = param ? ` locale={locale}` : "";
715
720
  // Мультиязычный роут /[locale]/blog/[slug]: пре-рендерим КАЖДУЮ статью под КАЖДУЮ локаль (передаём имя
716
721
  // сегмента локали) — иначе force-static не покроет комбинацию locale×slug и статьи отдадут 404.
717
722
  const gsp = param ? `seoBlogStaticParams({ localeParam: "${param}" })` : `seoBlogStaticParams()`;
718
723
  await writeOurRoute(
719
724
  path.join(root, appDir, under, `blog/[slug]/page.${jsxExt}`),
720
- `import { notFound } from "next/navigation";\nimport { seoBlogPost, seoBlogStaticParams, SeoBlogArticle } from "${blogFor(`${under}blog/[slug]/page.tsx`)}";\nexport const dynamic = "force-static";\nexport const dynamicParams = false;\n\n// Полностью статический рендер: все статьи пре-рендерятся на сборке из файлов content/blog. Контент\n// меняется git-коммитом → редеплой. dynamicParams=false: неизвестный слаг → 404 (без рантайм-чтения).\nexport async function generateStaticParams() {\n return ${gsp};\n}\n\nexport async function generateMetadata(${artSig}) {\n const post = await seoBlogPost(params.slug${localeArg});\n if (!post) return {};\n return { title: post.title, description: post.excerpt, openGraph: { images: post.cover ? [post.cover] : [] } };\n}\n\nexport default async function BlogPostPage(${artSig}) {\n const post = await seoBlogPost(params.slug${localeArg});\n if (!post) notFound();\n return <SeoBlogArticle post={post}${localeProp} />;\n}\n`,
725
+ `import { notFound } from "next/navigation";\nimport { seoBlogPost, seoBlogStaticParams, SeoBlogArticle } from "${blogFor(`${under}blog/[slug]/page.tsx`)}";\nexport const dynamic = "force-static";\nexport const dynamicParams = false;\n\n// Полностью статический рендер: все статьи пре-рендерятся на сборке из файлов content/blog. Контент\n// меняется git-коммитом → редеплой. dynamicParams=false: неизвестный слаг → 404 (без рантайм-чтения).\nexport async function generateStaticParams() {\n return ${gsp};\n}\n\nexport async function generateMetadata(${artSig}) {\n${artAwait} const post = await seoBlogPost(slug${localeArg});\n if (!post) return {};\n return { title: post.title, description: post.excerpt, openGraph: { images: post.cover ? [post.cover] : [] } };\n}\n\nexport default async function BlogPostPage(${artSig}) {\n${artAwait} const post = await seoBlogPost(slug${localeArg});\n if (!post) notFound();\n return <SeoBlogArticle post={post}${localeProp} />;\n}\n`,
721
726
  );
722
727
  }
723
728
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webnumseoagent/next",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Runtime SEO adapter + installer for Next.js App Router sites (SEO Agent platform)",
5
5
  "main": "dist/client.js",
6
6
  "types": "dist/client.d.ts",