From 10c6ce0733d7cf59930f2d623a045d925ec99cf0 Mon Sep 17 00:00:00 2001 From: ddryo <31400297+ddryo@users.noreply.github.com> Date: Wed, 30 Sep 2026 13:50:45 +0900 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20LP=E3=83=86=E3=83=B3=E3=83=97?= =?UTF-8?q?=E3=83=AC=E3=81=AEHTML=E7=89=88=E9=85=8D=E5=B8=83=E3=82=92?= =?UTF-8?q?=E8=A6=8B=E9=80=81=E3=82=8A=E3=80=81=E5=85=88=E8=A1=8C=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=E3=81=AEstatic-html=E5=9E=8B=E3=81=A8html=20stack?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01DWnryT8C2ehisFTnFkKjfr --- apps/site/src/config/templates.ts | 3 +- docs/decisions.md | 10 +++- documents/cli-guide.md | 1 - packages/lism-cli/src/commands/create.test.ts | 50 ------------------- packages/lism-cli/src/commands/create.ts | 20 +------- packages/lism-cli/src/messages.ts | 8 --- scripts/build-previews.mjs | 6 +-- templates/manifest.ts | 9 +--- 8 files changed, 17 insertions(+), 90 deletions(-) diff --git a/apps/site/src/config/templates.ts b/apps/site/src/config/templates.ts index fa0156b98..36eaa96b0 100644 --- a/apps/site/src/config/templates.ts +++ b/apps/site/src/config/templates.ts @@ -118,10 +118,9 @@ export const stackLabels: Record = { astro: 'Astro', next: 'Next.js', vite: 'Vite + React', - html: 'Static HTML', }; -export const stackOrder: Stack[] = ['astro', 'html', 'vite', 'next']; +export const stackOrder: Stack[] = ['astro', 'vite', 'next']; function hasSourcePath(tpl: TemplateDef): tpl is Extract { return 'sourcePath' in tpl; diff --git a/docs/decisions.md b/docs/decisions.md index 44f6a82fa..b43ec3b7e 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -1,7 +1,15 @@ -基準日: 2026-09-30・コミット4dc696023 +基準日: 2026-09-30・コミットcd06232fa # 意思決定の記録 +## 2026-09-30: LPテンプレのHTML版はCLIで配らない + +#375では、LPテンプレ(`templates/lp/astro/`)のビルド結果をHTML版としてCLIから配る予定だった。`static-html`型とCLIの分岐だけが先に実装されていた。調べると、Astroの出力はminify済みで手編集に向かない。JSは`type="module"`のため、`file://`で開くと動かない。さらにCLIはgigetでGitHubから取得するため、生成物をコミットし、sourceとのずれをCIで検査し続ける必要がある。 + +- 決定: HTML版は配らない。`static-html`型とstackの`html`、関連するCLIの分岐・文言・テストを削除する。 +- 却下: #375の計画どおり`templates/lp/html/_generated/`を生成してコミットする案。整形・スクリプト変換・ずれ検査を保守し続ける手間に、利用価値が見合わない。 +- 受容: HTMLが欲しい利用者には、Astro版を`npm run build`して`dist/`を使ってもらう。 + ## 2026-09-30: `@lism-css/mcp`はlism-cssと同じバージョンで出す 同日の決定「1.0.0以降、3つのバージョンは揃えない」のうち、mcpの部分を覆す。mcpはapps/siteから作ったdocs-indexと`skills/lism-css-guide`をビルド時に同梱して配るため、coreのリリースに合わせて出し直さないと古い情報を返し続ける。v0.26.0〜v0.30.0もcoreと同じバージョンで出していたが`/release`に書かれておらず、v0.31.0では出し忘れかけた。 diff --git a/documents/cli-guide.md b/documents/cli-guide.md index 842ad18ad..617d41bb0 100644 --- a/documents/cli-guide.md +++ b/documents/cli-guide.md @@ -47,7 +47,6 @@ nr publish:cli # build → lism-cli publish → create-lism publish - 各テンプレの`package.json`に必ず`"private": true`を付ける(npmへの誤公開防止)。階層の深さは問わない(`scripts/check-templates-private.mjs`が`package.json`まで再帰して検出する)。 - `base-overlay`型(現在の`TEMPLATES`に登録なし)を追加する場合、overlay側に`package.json`を置かない。CLIはbaseの`package.json`を採用し、overlayは差分ファイルだけ上書きする。置くと`name`の書き換えが二重化し、`workspace:*`置換も崩れる。共通設定はbaseに集約する。 - `single-project-variant`型(例: `templates/lp/astro/`)は`src/pages/{variant}/`を並べる構成。CLIは選択variantの`index.astro`を`src/pages/index.astro`へ持ち上げ、他variantを削除する。variant追加は`src/pages/{variant}/index.astro`を作り、`TEMPLATES`にslugを足す。 -- `templates/lp/html/_generated/`(未実装、#375で追加予定)はsourceからの生成物置き場。追加後は手編集禁止で、修正はgenerator側で行う。 ### 言語 diff --git a/packages/lism-cli/src/commands/create.test.ts b/packages/lism-cli/src/commands/create.test.ts index c452ec5f5..52a1db011 100644 --- a/packages/lism-cli/src/commands/create.test.ts +++ b/packages/lism-cli/src/commands/create.test.ts @@ -841,34 +841,6 @@ describe('runCreate', () => { expect(fs.existsSync(path.join(outDir, 'src/pages/en'))).toBe(false); }); - it('static-html型はpackage.jsonなしでもindex.htmlがあれば完了し、HTML向けNext stepsを出す', async () => { - const templates: Parameters[1] = [ - { - slug: 'lp-html-saas', - kind: 'static-html', - category: 'lp', - stack: 'html', - variant: 'saas', - variantLabel: { ja: 'SaaS', en: 'SaaS' }, - sourcePath: 'lp/html/_generated/saas', - title: { ja: 'LP SaaS HTML', en: 'LP SaaS HTML' }, - description: { ja: 'SaaS LP HTML', en: 'SaaS landing page HTML' }, - }, - ]; - vi.mocked(downloadTemplate).mockImplementation((_source, options) => { - const dir = (options as { dir: string }).dir; - fs.mkdirSync(dir, { recursive: true }); - writeFile(path.join(dir, 'index.html'), ''); - return Promise.resolve({} as Awaited>); - }); - - await runCreateWithTemplates({ template: 'lp-html-saas', targetDir: 'html-app', force: true }, templates); - - const outDir = path.join(tmpDir, 'html-app'); - expect(fs.existsSync(path.join(outDir, 'package.json'))).toBe(false); - expect(console.log).toHaveBeenCalledWith(' Open index.html in your browser'); - }); - it('--templateにカテゴリslugを指定するとstack選択へ降りる', async () => { const templates: Parameters[1] = [ { @@ -932,28 +904,6 @@ describe('runCreate', () => { await expect(runCreate({ template: 'minimal-astro', targetDir: 'broken', force: true })).rejects.toThrow('package.json'); }); - it('static-html型でindex.htmlがない場合はtemplateIndexMissingを返す', async () => { - const templates: Parameters[1] = [ - { - slug: 'lp-html-empty', - kind: 'static-html', - category: 'lp', - stack: 'html', - sourcePath: 'lp/html/_generated/empty', - title: { ja: 'LP Empty', en: 'LP Empty' }, - description: { ja: 'empty', en: 'empty' }, - }, - ]; - vi.mocked(downloadTemplate).mockImplementation((_source, options) => { - fs.mkdirSync((options as { dir: string }).dir, { recursive: true }); - return Promise.resolve({} as Awaited>); - }); - - await expect(runCreateWithTemplates({ template: 'lp-html-empty', targetDir: 'empty-html', force: true }, templates)).rejects.toThrow( - 'index.html' - ); - }); - it('上書き確認でnoなら中断してdownloadしない', async () => { const outDir = path.join(tmpDir, 'occupied'); fs.mkdirSync(outDir, { recursive: true }); diff --git a/packages/lism-cli/src/commands/create.ts b/packages/lism-cli/src/commands/create.ts index 59b45326b..eb89abbd5 100644 --- a/packages/lism-cli/src/commands/create.ts +++ b/packages/lism-cli/src/commands/create.ts @@ -35,7 +35,6 @@ const STACK_LABELS: Record = { astro: { ja: 'Astro', en: 'Astro' }, next: { ja: 'Next.js', en: 'Next.js' }, vite: { ja: 'Vite + React', en: 'Vite + React' }, - html: { ja: 'Static HTML', en: 'Static HTML' }, }; const CATEGORIES: CategoryDef[] = [ @@ -123,7 +122,7 @@ export async function runCreateWithTemplates( await postProcessTemplate(outDir, tpl, resolvedLang); logger.success(t('create.created', { dir: outDir })); - printNextSteps(outDir, tpl); + printNextSteps(outDir); } export async function createCommand(targetDir: string | undefined, options: CreateOptions, command?: CommandLike): Promise { @@ -229,12 +228,6 @@ async function resolveTargetDir(provided: string | undefined, templateName: stri } function ensureTemplateDownloaded(projectDir: string, tpl: TemplateDef): void { - if (tpl.kind === 'static-html') { - const indexPath = path.join(projectDir, 'index.html'); - if (fs.existsSync(indexPath)) return; - throw new Error(t('create.templateIndexMissing', { name: tpl.slug, path: getTemplateSourcePath(tpl) })); - } - const pkgPath = path.join(projectDir, 'package.json'); if (fs.existsSync(pkgPath)) return; throw new Error(t('create.templatePackageMissing', { name: tpl.slug, path: getTemplateSourcePath(tpl) })); @@ -282,8 +275,6 @@ async function applyLangOverlay(tpl: TemplateDef, outDir: string, ref: string, l /** テンプレート種別固有の変換後、配布不要ファイルとworkspace依存を整理する。 */ async function postProcessTemplate(projectDir: string, tpl: TemplateDef, lang: Lang): Promise { - if (tpl.kind === 'static-html') return; - if (tpl.kind === 'base-overlay' && tpl.rewritePackageName !== false) { rewritePackageName(projectDir, tpl.slug); } @@ -452,17 +443,10 @@ function escapeRegExp(s: string): string { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } -function printNextSteps(projectDir: string, tpl: TemplateDef): void { +function printNextSteps(projectDir: string): void { logger.heading(t('create.nextSteps')); const rel = path.relative(process.cwd(), projectDir) || '.'; logger.log(` cd ${rel}`); - - if (tpl.kind === 'static-html') { - logger.log(t('create.nextStepsHtmlOpen')); - logger.log(''); - return; - } - logger.log(' npm install # or pnpm install / yarn'); logger.log(' npm run dev'); logger.log(''); diff --git a/packages/lism-cli/src/messages.ts b/packages/lism-cli/src/messages.ts index 599630ace..3750264ce 100644 --- a/packages/lism-cli/src/messages.ts +++ b/packages/lism-cli/src/messages.ts @@ -201,10 +201,6 @@ export const messages = { ja: 'テンプレート"{name}"の取得結果にpackage.jsonがありません。取得元パスを確認してください: {path}', en: 'Downloaded template "{name}" does not contain package.json. Check the source path: {path}', }, - 'create.templateIndexMissing': { - ja: 'テンプレート"{name}"の取得結果にindex.htmlがありません。取得元パスを確認してください: {path}', - en: 'Downloaded template "{name}" does not contain index.html. Check the source path: {path}', - }, 'create.variantMissing': { ja: 'variant "{variant}" のディレクトリが見つかりません。取得元パスを確認してください: {path}', en: 'Variant "{variant}" directory not found. Check the source path: {path}', @@ -217,10 +213,6 @@ export const messages = { ja: '次のコマンドで開発を開始できます:', en: 'Next steps:', }, - 'create.nextStepsHtmlOpen': { - ja: ' index.htmlをブラウザで開いてください', - en: ' Open index.html in your browser', - }, 'create.packageNameRewritten': { ja: ' package.jsonのnameを"{name}"に変更しました。', en: ' Updated package.json name to "{name}".', diff --git a/scripts/build-previews.mjs b/scripts/build-previews.mjs index f2cf033b8..a16f3f5e0 100644 --- a/scripts/build-previews.mjs +++ b/scripts/build-previews.mjs @@ -7,7 +7,7 @@ // に通して `.preview/merged//` へ配置する。最後に全体 noindex の `_headers` を出力する。 // // 配信パス設計(PR の決定事項どおり): -// - project / static-html : /{slug}/ (en overlay があれば /{slug}/en/ も) +// - project : /{slug}/ (en overlay があれば /{slug}/en/ も) // - single-project-variant(lp/astro): /{prefix}/ (en は dist 同梱の /{prefix}/en/...) // prefix = sourcePath.replace('/', '-')(lp/astro → lp-astro) // - draft variant は merged から除外する @@ -55,7 +55,7 @@ const CATEGORY_ORDER = [ ]; // stack 表示ラベル(docs の stackLabels と揃える) -const STACK_LABELS = { astro: 'Astro', next: 'Next.js', vite: 'Vite + React', html: 'Static HTML' }; +const STACK_LABELS = { astro: 'Astro', next: 'Next.js', vite: 'Vite + React' }; // テンプレ定義から ja / en の配信パスを導出(build-previews のパス設計と対)。 // 配信非対応 kind は null。 @@ -163,7 +163,7 @@ function writeLanding() { const units = []; -// --- project / static-html: slug ごとに 1 ユニット(en overlay があれば en も) --- +// --- project: slug ごとに 1 ユニット(en overlay があれば en も) --- for (const t of TEMPLATES) { if (t.kind === 'single-project-variant') continue; if (t.draft) continue; // 単独 draft は配信しない diff --git a/templates/manifest.ts b/templates/manifest.ts index 2b30f8590..912cfe4ec 100644 --- a/templates/manifest.ts +++ b/templates/manifest.ts @@ -9,7 +9,7 @@ * `templates/{sourcePath}/screenshots/{top または variant}.png` の規約から解決する。 */ -export type Stack = 'astro' | 'next' | 'vite' | 'html'; +export type Stack = 'astro' | 'next' | 'vite'; export type CategoryId = 'minimal' | 'blog' | 'lp' | 'web'; export interface LocalizedText { @@ -72,11 +72,6 @@ export interface BaseOverlayTemplateDef extends TemplateMetaBase { rewritePackageName?: boolean; } -export interface StaticHtmlTemplateDef extends TemplateMetaBase { - kind: 'static-html'; - sourcePath: string; -} - /** * 単一の Astro / Vite プロジェクト内に複数 variant(src/pages/{variant}/)を同居させた構成。 * CLI 抽出時に選択 variant の index.astro を src/pages/index.astro に持ち上げ、 @@ -99,7 +94,7 @@ export interface SingleProjectVariantTemplateDef extends TemplateMetaBase { packageName?: string; } -export type TemplateDef = ProjectTemplateDef | BaseOverlayTemplateDef | StaticHtmlTemplateDef | SingleProjectVariantTemplateDef; +export type TemplateDef = ProjectTemplateDef | BaseOverlayTemplateDef | SingleProjectVariantTemplateDef; /** * テンプレプレビュー集約サイトのオリジン。全 previewUrl をこの 1 箇所で束ねる。 From 295cb87589eb299b16b8a7a2870f01c3918c950f Mon Sep 17 00:00:00 2001 From: ddryo <31400297+ddryo@users.noreply.github.com> Date: Wed, 30 Sep 2026 14:20:46 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20=E6=9C=AA=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E3=81=AE=E3=83=86=E3=83=B3=E3=83=97=E3=83=AC=E7=A8=AE=E5=88=A5?= =?UTF-8?q?base-overlay=E3=81=A8=E9=96=A2=E9=80=A3=E3=81=99=E3=82=8BCLI?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=83=BB=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01DWnryT8C2ehisFTnFkKjfr --- apps/site/src/config/templates.ts | 10 +--- docs/decisions.md | 8 ++++ documents/cli-guide.md | 1 - packages/lism-cli/src/commands/create.test.ts | 48 ------------------- packages/lism-cli/src/commands/create.ts | 30 +----------- scripts/build-previews.mjs | 11 +---- templates/manifest.ts | 9 +--- 7 files changed, 13 insertions(+), 104 deletions(-) diff --git a/apps/site/src/config/templates.ts b/apps/site/src/config/templates.ts index 36eaa96b0..bf79926fa 100644 --- a/apps/site/src/config/templates.ts +++ b/apps/site/src/config/templates.ts @@ -122,19 +122,12 @@ export const stackLabels: Record = { export const stackOrder: Stack[] = ['astro', 'vite', 'next']; -function hasSourcePath(tpl: TemplateDef): tpl is Extract { - return 'sourcePath' in tpl; -} - -function thumbFileName(tpl: Extract): string { +function thumbFileName(tpl: TemplateDef): string { return tpl.kind === 'single-project-variant' ? `${tpl.variant}.png` : 'top.png'; } /** 規約ベースで thumb を解決(解決できなければビルド時に失敗させる) */ function resolveThumb(tpl: TemplateDef): ImageMetadata { - if (!hasSourcePath(tpl)) { - throw new Error(`[templates] thumb resolution unsupported for kind "${tpl.kind}" (slug: ${tpl.slug})`); - } const key = `../../../../templates/${tpl.sourcePath}/screenshots/${thumbFileName(tpl)}`; const mod = screenshotModules[key]; if (!mod) { @@ -145,7 +138,6 @@ function resolveThumb(tpl: TemplateDef): ImageMetadata { /** en 用 thumb を解決(`screenshots/en/` 未撮影なら undefined → 呼び出し側で ja にフォールバック) */ function resolveThumbEn(tpl: TemplateDef): ImageMetadata | undefined { - if (!hasSourcePath(tpl)) return undefined; const key = `../../../../templates/${tpl.sourcePath}/screenshots/en/${thumbFileName(tpl)}`; return screenshotModules[key]?.default; } diff --git a/docs/decisions.md b/docs/decisions.md index b43ec3b7e..2226f7d94 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -2,6 +2,14 @@ # 意思決定の記録 +## 2026-09-30: テンプレ種別`base-overlay`を削除し、variant違いは`single-project-variant`で持つ + +#366では、`lp`と`web`のAstro版を「共通base + variantごとの差分(overlay)」で配る設計だった。`base-overlay`型はそのための型。しかし#372でLPには採用されず、`single-project-variant`型が作られた。variant間で構造の違い(独自のkeyframesやclass prefix)が大きく、共通baseにする利点が薄いため。以後、この型を使うテンプレは1つも無かった。 + +- 決定: `base-overlay`型と、CLIの取得・マージ・package名の書き換え処理、テストを削除する。 +- 決定: variant違いのテンプレは`single-project-variant`型で持つ。今後`web`カテゴリを作るときもこれに倣う。プレビューも1サイトにまとめてビルドできる。 +- 却下: 将来の`web`カテゴリ用に残す案。LPで却下した理由は、業種ごとに構造が違う`web`にも当てはまる。 + ## 2026-09-30: LPテンプレのHTML版はCLIで配らない #375では、LPテンプレ(`templates/lp/astro/`)のビルド結果をHTML版としてCLIから配る予定だった。`static-html`型とCLIの分岐だけが先に実装されていた。調べると、Astroの出力はminify済みで手編集に向かない。JSは`type="module"`のため、`file://`で開くと動かない。さらにCLIはgigetでGitHubから取得するため、生成物をコミットし、sourceとのずれをCIで検査し続ける必要がある。 diff --git a/documents/cli-guide.md b/documents/cli-guide.md index 617d41bb0..50500f803 100644 --- a/documents/cli-guide.md +++ b/documents/cli-guide.md @@ -45,7 +45,6 @@ nr publish:cli # build → lism-cli publish → create-lism publish ### 規約 - 各テンプレの`package.json`に必ず`"private": true`を付ける(npmへの誤公開防止)。階層の深さは問わない(`scripts/check-templates-private.mjs`が`package.json`まで再帰して検出する)。 -- `base-overlay`型(現在の`TEMPLATES`に登録なし)を追加する場合、overlay側に`package.json`を置かない。CLIはbaseの`package.json`を採用し、overlayは差分ファイルだけ上書きする。置くと`name`の書き換えが二重化し、`workspace:*`置換も崩れる。共通設定はbaseに集約する。 - `single-project-variant`型(例: `templates/lp/astro/`)は`src/pages/{variant}/`を並べる構成。CLIは選択variantの`index.astro`を`src/pages/index.astro`へ持ち上げ、他variantを削除する。variant追加は`src/pages/{variant}/index.astro`を作り、`TEMPLATES`にslugを足す。 ### 言語 diff --git a/packages/lism-cli/src/commands/create.test.ts b/packages/lism-cli/src/commands/create.test.ts index 52a1db011..cc71fc114 100644 --- a/packages/lism-cli/src/commands/create.test.ts +++ b/packages/lism-cli/src/commands/create.test.ts @@ -295,54 +295,6 @@ describe('runCreate', () => { }); }); - it('base-overlay型はbase取得後にoverlayをmergeし、package.json.nameをslugにする', async () => { - const templates: Parameters[1] = [ - { - slug: 'lp-astro-saas', - kind: 'base-overlay', - category: 'lp', - stack: 'astro', - variant: 'saas', - variantLabel: { ja: 'SaaS', en: 'SaaS' }, - basePath: 'lp/astro/_base', - overlayPath: 'lp/astro/_variants/saas', - title: { ja: 'LP SaaS', en: 'LP SaaS' }, - description: { ja: 'SaaS LP', en: 'SaaS landing page' }, - }, - ]; - vi.mocked(downloadTemplate).mockImplementation((source, options) => { - const dir = (options as { dir: string }).dir; - fs.mkdirSync(dir, { recursive: true }); - if (String(source).includes('/_base#')) { - writePackageJson(dir, { name: 'lp-astro-base', dependencies: { 'lism-css': 'workspace:*' } }); - writeFile(path.join(dir, 'src/pages/index.astro'), 'base'); - } else { - writeFile(path.join(dir, 'src/pages/index.astro'), 'overlay'); - writeFile(path.join(dir, 'src/styles/variant.css'), '.hero{}'); - } - return Promise.resolve({} as Awaited>); - }); - - await runCreateWithTemplates({ template: 'lp-astro-saas', targetDir: 'lp-app', force: true }, templates); - - const outDir = path.join(tmpDir, 'lp-app'); - expect(downloadTemplate).toHaveBeenCalledTimes(2); - expect(downloadTemplate).toHaveBeenNthCalledWith(1, 'github:lism-css/core/templates/lp/astro/_base#main', { - dir: outDir, - force: true, - forceClean: true, - }); - expect(downloadTemplate).toHaveBeenNthCalledWith(2, 'github:lism-css/core/templates/lp/astro/_variants/saas#main', { - dir: expect.any(String), - force: true, - forceClean: true, - }); - expect(fs.readFileSync(path.join(outDir, 'src/pages/index.astro'), 'utf-8')).toBe('overlay'); - expect(fs.existsSync(path.join(outDir, 'src/styles/variant.css'))).toBe(true); - const pkg = JSON.parse(fs.readFileSync(path.join(outDir, 'package.json'), 'utf-8')) as { name: string }; - expect(pkg.name).toBe('lp-astro-saas'); - }); - it('project型はlangOverlaysに要求言語があればbase取得後にoverlayをmergeし、.langを除去する', async () => { const templates: Parameters[1] = [ { diff --git a/packages/lism-cli/src/commands/create.ts b/packages/lism-cli/src/commands/create.ts index eb89abbd5..ab44e6b4e 100644 --- a/packages/lism-cli/src/commands/create.ts +++ b/packages/lism-cli/src/commands/create.ts @@ -113,7 +113,7 @@ export async function runCreateWithTemplates( } logger.info(t('create.fetching', { name: tpl.slug, ref })); - await downloadTemplateSource(tpl, outDir, ref, force); + await downloadTemplatePath(tpl.sourcePath, outDir, ref, force); await applyLangOverlay(tpl, outDir, ref, resolvedLang); @@ -230,24 +230,7 @@ async function resolveTargetDir(provided: string | undefined, templateName: stri function ensureTemplateDownloaded(projectDir: string, tpl: TemplateDef): void { const pkgPath = path.join(projectDir, 'package.json'); if (fs.existsSync(pkgPath)) return; - throw new Error(t('create.templatePackageMissing', { name: tpl.slug, path: getTemplateSourcePath(tpl) })); -} - -async function downloadTemplateSource(tpl: TemplateDef, outDir: string, ref: string, forceClean: boolean): Promise { - if (tpl.kind === 'base-overlay') { - await downloadTemplatePath(tpl.basePath, outDir, ref, forceClean); - - const overlayDir = fs.mkdtempSync(path.join(os.tmpdir(), 'lism-template-overlay-')); - try { - await downloadTemplatePath(tpl.overlayPath, overlayDir, ref, true); - mergeDirectory(overlayDir, outDir); - } finally { - fs.rmSync(overlayDir, { recursive: true, force: true }); - } - return; - } - - await downloadTemplatePath(tpl.sourcePath, outDir, ref, forceClean); + throw new Error(t('create.templatePackageMissing', { name: tpl.slug, path: formatTemplatePath(tpl.sourcePath) })); } async function downloadTemplatePath(sourcePath: string, outDir: string, ref: string, forceClean: boolean): Promise { @@ -275,10 +258,6 @@ async function applyLangOverlay(tpl: TemplateDef, outDir: string, ref: string, l /** テンプレート種別固有の変換後、配布不要ファイルとworkspace依存を整理する。 */ async function postProcessTemplate(projectDir: string, tpl: TemplateDef, lang: Lang): Promise { - if (tpl.kind === 'base-overlay' && tpl.rewritePackageName !== false) { - rewritePackageName(projectDir, tpl.slug); - } - if (tpl.kind === 'single-project-variant') { extractVariantFiles(projectDir, tpl, lang); rewritePackageName(projectDir, tpl.packageName ?? tpl.slug); @@ -452,11 +431,6 @@ function printNextSteps(projectDir: string): void { logger.log(''); } -function getTemplateSourcePath(tpl: TemplateDef): string { - if (tpl.kind === 'base-overlay') return `${formatTemplatePath(tpl.basePath)} + ${formatTemplatePath(tpl.overlayPath)}`; - return formatTemplatePath(tpl.sourcePath); -} - function formatTemplatePath(sourcePath: string): string { return `${TEMPLATES_PATH}/${sourcePath}`; } diff --git a/scripts/build-previews.mjs b/scripts/build-previews.mjs index a16f3f5e0..4dbc564f2 100644 --- a/scripts/build-previews.mjs +++ b/scripts/build-previews.mjs @@ -58,16 +58,12 @@ const CATEGORY_ORDER = [ const STACK_LABELS = { astro: 'Astro', next: 'Next.js', vite: 'Vite + React' }; // テンプレ定義から ja / en の配信パスを導出(build-previews のパス設計と対)。 -// 配信非対応 kind は null。 function previewPaths(t) { if (t.kind === 'single-project-variant') { const prefix = t.sourcePath.replace(/\//g, '-'); return { jaPath: `/${prefix}/${t.variant}/`, enPath: `/${prefix}/en/${t.variant}/` }; } - if ('sourcePath' in t) { - return { jaPath: `/${t.slug}/`, enPath: `/${t.slug}/en/` }; - } - return null; + return { jaPath: `/${t.slug}/`, enPath: `/${t.slug}/en/` }; } // 実際に merged へ出力された index.html の有無で掲載カードを集める(カテゴリ別)。 @@ -76,7 +72,6 @@ function collectLandingCards() { for (const t of TEMPLATES) { if (t.draft) continue; const paths = previewPaths(t); - if (!paths) continue; if (!existsSync(path.join(MERGED, paths.jaPath, 'index.html'))) continue; // 未配信は載せない const enExists = existsSync(path.join(MERGED, paths.enPath, 'index.html')); const card = { title: t.title.ja, stack: t.stack, jaPath: paths.jaPath, ...(enExists ? { enPath: paths.enPath } : {}) }; @@ -167,10 +162,6 @@ const units = []; for (const t of TEMPLATES) { if (t.kind === 'single-project-variant') continue; if (t.draft) continue; // 単独 draft は配信しない - if (!('sourcePath' in t)) { - console.warn(`⚠ skip ${t.slug}: kind="${t.kind}" は build-previews 未対応`); - continue; - } if (t.stack !== 'astro' && t.stack !== 'vite') { console.warn(`⚠ skip ${t.slug}: stack="${t.stack}" は build-previews 未対応`); continue; diff --git a/templates/manifest.ts b/templates/manifest.ts index 912cfe4ec..76e3ca267 100644 --- a/templates/manifest.ts +++ b/templates/manifest.ts @@ -65,13 +65,6 @@ export interface ProjectTemplateDef extends TemplateMetaBase { langOverlays?: Partial>; } -export interface BaseOverlayTemplateDef extends TemplateMetaBase { - kind: 'base-overlay'; - basePath: string; - overlayPath: string; - rewritePackageName?: boolean; -} - /** * 単一の Astro / Vite プロジェクト内に複数 variant(src/pages/{variant}/)を同居させた構成。 * CLI 抽出時に選択 variant の index.astro を src/pages/index.astro に持ち上げ、 @@ -94,7 +87,7 @@ export interface SingleProjectVariantTemplateDef extends TemplateMetaBase { packageName?: string; } -export type TemplateDef = ProjectTemplateDef | BaseOverlayTemplateDef | SingleProjectVariantTemplateDef; +export type TemplateDef = ProjectTemplateDef | SingleProjectVariantTemplateDef; /** * テンプレプレビュー集約サイトのオリジン。全 previewUrl をこの 1 箇所で束ねる。