lism-cli 0.5.0 → 0.6.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/README.md +6 -1
- package/dist/{chunk-USFIDRTL.js → chunk-G4RBP3W6.js} +91 -21
- package/dist/index.js +1 -1
- package/dist/lib.d.ts +9 -11
- package/dist/lib.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,9 +27,14 @@ pnpm dlx lism-cli create --template minimal-astro ./my-app
|
|
|
27
27
|
|
|
28
28
|
# カテゴリ名を指定(stack 以下の選択を対話で続行)
|
|
29
29
|
pnpm dlx lism-cli create --template minimal ./my-app
|
|
30
|
+
|
|
31
|
+
# 言語を指定(CLI 表示 + 生成テンプレートの言語)
|
|
32
|
+
pnpm dlx lism-cli create --template blog-astro-minimal --lang en ./my-blog
|
|
30
33
|
```
|
|
31
34
|
|
|
32
|
-
同じ動作は `pnpm create lism` / `npm create lism@latest` でも呼び出せます(`create-lism`
|
|
35
|
+
同じ動作は `pnpm create lism` / `npm create lism@latest` でも呼び出せます(`create-lism` パッケージ経由)。挙動は両者で共通です。
|
|
36
|
+
|
|
37
|
+
`--lang <ja|en>` は CLI の表示言語に加えて、**生成されるテンプレート本体の言語**にも反映されます。`--lang` を指定しない場合は、対話端末(TTY)ではほかのどの選択よりも先に言語選択プロンプトが表示され、選んだ言語で以降の表示とテンプレート生成が確定します(非対話環境・CI 等では `en` にフォールバック)。対応言語版を持つテンプレート(`blog-astro-minimal` / `blog-astro-personal` / `blog-astro-techlog` / `lp-astro-corporate` / `lp-astro-interior`)では、指定言語のサイト文言・サンプルコンテンツで生成されます。言語版が無いテンプレートは、指定言語に関わらず既存(ベース)の内容で生成されます。
|
|
33
38
|
|
|
34
39
|
### UI コンポーネントの追加
|
|
35
40
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/i18n.ts
|
|
2
|
+
import { execFileSync } from "child_process";
|
|
3
|
+
|
|
1
4
|
// src/messages.ts
|
|
2
5
|
var messages = {
|
|
3
6
|
// ---------------------------------------------------------------------------
|
|
@@ -8,8 +11,8 @@ var messages = {
|
|
|
8
11
|
en: "CLI for Lism CSS / UI"
|
|
9
12
|
},
|
|
10
13
|
"cli.opt.lang": {
|
|
11
|
-
ja: "CLI \
|
|
12
|
-
en: "
|
|
14
|
+
ja: "CLI \u8868\u793A\u3068\u751F\u6210\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u306E\u8A00\u8A9E\uFF08ja | en\u3001\u672A\u6307\u5B9A\u306A\u3089\u5BFE\u8A71\u6642\u306B\u9078\u629E\uFF09",
|
|
15
|
+
en: "Language for the CLI and generated template (ja | en; prompted when omitted)"
|
|
13
16
|
},
|
|
14
17
|
// create
|
|
15
18
|
"cli.create.description": {
|
|
@@ -466,10 +469,25 @@ var messages = {
|
|
|
466
469
|
};
|
|
467
470
|
|
|
468
471
|
// src/i18n.ts
|
|
472
|
+
function detectAppleLanguage() {
|
|
473
|
+
if (process.platform !== "darwin") return null;
|
|
474
|
+
try {
|
|
475
|
+
const out = execFileSync("/usr/bin/defaults", ["read", "-g", "AppleLanguages"], {
|
|
476
|
+
encoding: "utf8",
|
|
477
|
+
timeout: 1e3,
|
|
478
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
479
|
+
});
|
|
480
|
+
const match = out.match(/"?([A-Za-z]{2,}[-_A-Za-z]*)"?/);
|
|
481
|
+
return match ? match[1].toLowerCase() : null;
|
|
482
|
+
} catch {
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
469
486
|
function detectLang(override) {
|
|
470
487
|
if (override === "ja" || override === "en") return override;
|
|
471
488
|
const raw = (process.env.LC_ALL || process.env.LANG || "").toLowerCase();
|
|
472
489
|
if (raw.startsWith("ja")) return "ja";
|
|
490
|
+
if (detectAppleLanguage()?.startsWith("ja")) return "ja";
|
|
473
491
|
try {
|
|
474
492
|
const locale = Intl.DateTimeFormat().resolvedOptions().locale.toLowerCase();
|
|
475
493
|
if (locale.startsWith("ja")) return "ja";
|
|
@@ -547,8 +565,8 @@ var logger = {
|
|
|
547
565
|
};
|
|
548
566
|
|
|
549
567
|
// src/version.ts
|
|
550
|
-
var LISM_CSS_VERSION = "0.
|
|
551
|
-
var CLI_VERSION = "0.
|
|
568
|
+
var LISM_CSS_VERSION = "0.22.2" ? "0.22.2" : "unknown";
|
|
569
|
+
var CLI_VERSION = "0.6.0" ? "0.6.0" : "unknown";
|
|
552
570
|
|
|
553
571
|
// src/constants.ts
|
|
554
572
|
var SOURCE_REPO = "lism-css/lism-css";
|
|
@@ -563,6 +581,7 @@ var SKILL_SOURCE_PATH = "skills/lism-css-guide";
|
|
|
563
581
|
var TEMPLATES_PATH = "templates";
|
|
564
582
|
|
|
565
583
|
// ../../templates/manifest.ts
|
|
584
|
+
var PREVIEW_ORIGIN = "https://templates.lism-css.com";
|
|
566
585
|
var TEMPLATES = [
|
|
567
586
|
{
|
|
568
587
|
slug: "minimal-astro",
|
|
@@ -581,7 +600,7 @@ var TEMPLATES = [
|
|
|
581
600
|
sourcePath: "minimal/vite",
|
|
582
601
|
title: { ja: "Minimal Vite", en: "Minimal Vite" },
|
|
583
602
|
description: { ja: "Vite + React \u30D9\u30FC\u30B9\u306E\u6700\u5C0F\u69CB\u6210", en: "Minimal Vite + React setup" },
|
|
584
|
-
previewUrl:
|
|
603
|
+
previewUrl: `${PREVIEW_ORIGIN}/minimal-vite/`
|
|
585
604
|
},
|
|
586
605
|
{
|
|
587
606
|
slug: "blog-astro-minimal",
|
|
@@ -591,9 +610,13 @@ var TEMPLATES = [
|
|
|
591
610
|
variantLabel: { ja: "Minimal", en: "Minimal" },
|
|
592
611
|
stack: "astro",
|
|
593
612
|
sourcePath: "blog/astro/minimal",
|
|
613
|
+
langOverlays: {
|
|
614
|
+
en: "blog/astro/minimal/.lang/en"
|
|
615
|
+
},
|
|
594
616
|
title: { ja: "Blog Minimal", en: "Blog Minimal" },
|
|
595
617
|
description: { ja: "\u8A18\u4E8B\u4E00\u89A7 / \u8A73\u7D30 / Tags \u306E\u307F\u306E\u6700\u5C0F\u69CB\u6210\u306E Astro \u30D6\u30ED\u30B0", en: "Minimal Astro blog with posts and tags only" },
|
|
596
|
-
previewUrl:
|
|
618
|
+
previewUrl: `${PREVIEW_ORIGIN}/blog-astro-minimal/`,
|
|
619
|
+
previewUrlEn: `${PREVIEW_ORIGIN}/blog-astro-minimal/en/`,
|
|
597
620
|
features: {
|
|
598
621
|
ja: ["\u30BF\u30B0", "sitemap"],
|
|
599
622
|
en: ["Tags", "sitemap"]
|
|
@@ -607,12 +630,16 @@ var TEMPLATES = [
|
|
|
607
630
|
variantLabel: { ja: "Personal", en: "Personal" },
|
|
608
631
|
stack: "astro",
|
|
609
632
|
sourcePath: "blog/astro/personal",
|
|
633
|
+
langOverlays: {
|
|
634
|
+
en: "blog/astro/personal/.lang/en"
|
|
635
|
+
},
|
|
610
636
|
title: { ja: "Blog Personal", en: "Blog Personal" },
|
|
611
637
|
description: {
|
|
612
638
|
ja: "\u500B\u4EBA\u30D6\u30ED\u30B0\u30FB\u30A8\u30C3\u30BB\u30A4\u5411\u3051\u3002\u5E74\u6708\u30A2\u30FC\u30AB\u30A4\u30D6\u3064\u304D\u306E\u843D\u3061\u7740\u3044\u305F Astro \u30D6\u30ED\u30B0",
|
|
613
639
|
en: "Personal / essay-style Astro blog with monthly archives"
|
|
614
640
|
},
|
|
615
|
-
previewUrl:
|
|
641
|
+
previewUrl: `${PREVIEW_ORIGIN}/blog-astro-personal/`,
|
|
642
|
+
previewUrlEn: `${PREVIEW_ORIGIN}/blog-astro-personal/en/`,
|
|
616
643
|
features: {
|
|
617
644
|
ja: ["\u30BF\u30B0", "\u5E74\u6708\u30A2\u30FC\u30AB\u30A4\u30D6", "\u30B7\u30A7\u30A2\u30DC\u30BF\u30F3", "OGP\u753B\u50CF\u81EA\u52D5\u751F\u6210", "sitemap\uFF08lastmod \u5BFE\u5FDC\uFF09"],
|
|
618
645
|
en: ["Tags", "Monthly archives", "Share buttons", "Auto-generated OG images", "sitemap (with lastmod)"]
|
|
@@ -626,12 +653,16 @@ var TEMPLATES = [
|
|
|
626
653
|
variantLabel: { ja: "Tech Log", en: "Tech Log" },
|
|
627
654
|
stack: "astro",
|
|
628
655
|
sourcePath: "blog/astro/techlog",
|
|
656
|
+
langOverlays: {
|
|
657
|
+
en: "blog/astro/techlog/.lang/en"
|
|
658
|
+
},
|
|
629
659
|
title: { ja: "Blog Tech Log", en: "Blog Tech Log" },
|
|
630
660
|
description: {
|
|
631
661
|
ja: "\u6280\u8853\u30D6\u30ED\u30B0\u5411\u3051\u3002\u30B3\u30FC\u30C9\u30CF\u30A4\u30E9\u30A4\u30C8\u30FB\u30AB\u30C6\u30B4\u30EA\u30FB\u30BF\u30B0\u30FBTOC\u30FB\u5E74\u6708\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u691C\u7D22\u3092\u88C5\u5099\u3057\u305F Astro \u30D6\u30ED\u30B0",
|
|
632
662
|
en: "Tech blog with code highlighting, categories, tags, TOC, monthly archives and search"
|
|
633
663
|
},
|
|
634
|
-
previewUrl:
|
|
664
|
+
previewUrl: `${PREVIEW_ORIGIN}/blog-astro-techlog/`,
|
|
665
|
+
previewUrlEn: `${PREVIEW_ORIGIN}/blog-astro-techlog/en/`,
|
|
635
666
|
features: {
|
|
636
667
|
ja: [
|
|
637
668
|
"\u30AB\u30C6\u30B4\u30EA / \u30BF\u30B0",
|
|
@@ -667,7 +698,8 @@ var TEMPLATES = [
|
|
|
667
698
|
sourcePath: "lp/astro",
|
|
668
699
|
title: { ja: "LP Corporate", en: "LP Corporate" },
|
|
669
700
|
description: { ja: "\u30B3\u30FC\u30DD\u30EC\u30FC\u30C8\u30B5\u30A4\u30C8\u5411\u3051\u306E Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8", en: "Astro landing page for corporate sites" },
|
|
670
|
-
previewUrl:
|
|
701
|
+
previewUrl: `${PREVIEW_ORIGIN}/lp-astro/corporate/`,
|
|
702
|
+
previewUrlEn: `${PREVIEW_ORIGIN}/lp-astro/en/corporate/`
|
|
671
703
|
},
|
|
672
704
|
{
|
|
673
705
|
slug: "lp-astro-interior",
|
|
@@ -679,7 +711,8 @@ var TEMPLATES = [
|
|
|
679
711
|
sourcePath: "lp/astro",
|
|
680
712
|
title: { ja: "LP Interior", en: "LP Interior" },
|
|
681
713
|
description: { ja: "\u30A4\u30F3\u30C6\u30EA\u30A2\u30FB\u66AE\u3089\u3057\u7CFB\u30B5\u30FC\u30D3\u30B9\u5411\u3051\u306E Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8", en: "Astro landing page for interior / lifestyle services" },
|
|
682
|
-
previewUrl:
|
|
714
|
+
previewUrl: `${PREVIEW_ORIGIN}/lp-astro/interior/`,
|
|
715
|
+
previewUrlEn: `${PREVIEW_ORIGIN}/lp-astro/en/interior/`
|
|
683
716
|
},
|
|
684
717
|
{
|
|
685
718
|
slug: "lp-astro-ryokan",
|
|
@@ -714,7 +747,7 @@ var CATEGORIES = [
|
|
|
714
747
|
},
|
|
715
748
|
{
|
|
716
749
|
id: "lp",
|
|
717
|
-
label: { ja: "
|
|
750
|
+
label: { ja: "LP", en: "LP" },
|
|
718
751
|
variantPromptKey: "create.promptSelectVariant.lp"
|
|
719
752
|
},
|
|
720
753
|
{
|
|
@@ -723,10 +756,12 @@ var CATEGORIES = [
|
|
|
723
756
|
variantPromptKey: "create.promptSelectVariant.web"
|
|
724
757
|
}
|
|
725
758
|
];
|
|
726
|
-
async function runCreate({ template, targetDir, force = false }) {
|
|
727
|
-
await runCreateWithTemplates({ template, targetDir, force }, TEMPLATES);
|
|
759
|
+
async function runCreate({ template, targetDir, force = false, lang }) {
|
|
760
|
+
await runCreateWithTemplates({ template, targetDir, force, lang }, TEMPLATES);
|
|
728
761
|
}
|
|
729
|
-
async function runCreateWithTemplates({ template, targetDir, force = false }, templates) {
|
|
762
|
+
async function runCreateWithTemplates({ template, targetDir, force = false, lang }, templates) {
|
|
763
|
+
const resolvedLang = await resolveLang(lang);
|
|
764
|
+
setLang(resolvedLang);
|
|
730
765
|
const availableTemplates = templates.filter((tpl2) => !tpl2.draft);
|
|
731
766
|
const tpl = await resolveTemplate(template, availableTemplates);
|
|
732
767
|
const outDir = path.resolve(process.cwd(), await resolveTargetDir(targetDir, tpl.slug));
|
|
@@ -743,13 +778,27 @@ async function runCreateWithTemplates({ template, targetDir, force = false }, te
|
|
|
743
778
|
const ref = DEFAULT_TEMPLATES_REF;
|
|
744
779
|
logger.info(t("create.fetching", { name: tpl.slug, ref }));
|
|
745
780
|
await downloadTemplateSource(tpl, outDir, ref, force);
|
|
781
|
+
await applyLangOverlay(tpl, outDir, ref, resolvedLang);
|
|
746
782
|
ensureTemplateDownloaded(outDir, tpl);
|
|
747
|
-
postProcessTemplate(outDir, tpl);
|
|
783
|
+
postProcessTemplate(outDir, tpl, resolvedLang);
|
|
748
784
|
logger.success(t("create.created", { dir: outDir }));
|
|
749
785
|
printNextSteps(outDir, tpl);
|
|
750
786
|
}
|
|
751
|
-
async function createCommand(targetDir, options) {
|
|
752
|
-
|
|
787
|
+
async function createCommand(targetDir, options, command) {
|
|
788
|
+
const langOpt = command?.optsWithGlobals().lang;
|
|
789
|
+
const lang = typeof langOpt === "string" ? langOpt : void 0;
|
|
790
|
+
await runCreate({ template: options.template, targetDir, force: options.force, lang });
|
|
791
|
+
}
|
|
792
|
+
async function resolveLang(explicit) {
|
|
793
|
+
if (explicit === "ja" || explicit === "en") return explicit;
|
|
794
|
+
if (!process.stdin.isTTY) return "en";
|
|
795
|
+
return select({
|
|
796
|
+
message: "Select language / \u8A00\u8A9E\u3092\u9078\u629E:",
|
|
797
|
+
choices: [
|
|
798
|
+
{ name: "English", value: "en" },
|
|
799
|
+
{ name: "\u65E5\u672C\u8A9E", value: "ja" }
|
|
800
|
+
]
|
|
801
|
+
});
|
|
753
802
|
}
|
|
754
803
|
async function resolveTemplate(requested, templates) {
|
|
755
804
|
if (requested) {
|
|
@@ -850,13 +899,25 @@ async function downloadTemplatePath(sourcePath, outDir, ref, forceClean) {
|
|
|
850
899
|
forceClean
|
|
851
900
|
});
|
|
852
901
|
}
|
|
853
|
-
function
|
|
902
|
+
async function applyLangOverlay(tpl, outDir, ref, lang) {
|
|
903
|
+
if (tpl.kind !== "project") return;
|
|
904
|
+
const overlayPath = tpl.langOverlays?.[lang];
|
|
905
|
+
if (!overlayPath) return;
|
|
906
|
+
const overlayDir = fs.mkdtempSync(path.join(os.tmpdir(), "lism-template-lang-"));
|
|
907
|
+
try {
|
|
908
|
+
await downloadTemplatePath(overlayPath, overlayDir, ref, true);
|
|
909
|
+
mergeDirectory(overlayDir, outDir);
|
|
910
|
+
} finally {
|
|
911
|
+
fs.rmSync(overlayDir, { recursive: true, force: true });
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
function postProcessTemplate(projectDir, tpl, lang) {
|
|
854
915
|
if (tpl.kind === "static-html") return;
|
|
855
916
|
if (tpl.kind === "base-overlay" && tpl.rewritePackageName !== false) {
|
|
856
917
|
rewritePackageName(projectDir, tpl.slug);
|
|
857
918
|
}
|
|
858
919
|
if (tpl.kind === "single-project-variant") {
|
|
859
|
-
extractVariantFiles(projectDir, tpl);
|
|
920
|
+
extractVariantFiles(projectDir, tpl, lang);
|
|
860
921
|
rewritePackageName(projectDir, tpl.packageName ?? tpl.slug);
|
|
861
922
|
}
|
|
862
923
|
cleanupDevArtifacts(projectDir);
|
|
@@ -871,10 +932,19 @@ function cleanupDevArtifacts(projectDir) {
|
|
|
871
932
|
if (fs.existsSync(screenshotsConfig)) {
|
|
872
933
|
fs.rmSync(screenshotsConfig, { force: true });
|
|
873
934
|
}
|
|
935
|
+
const langDir = path.join(projectDir, ".lang");
|
|
936
|
+
if (fs.existsSync(langDir)) {
|
|
937
|
+
fs.rmSync(langDir, { recursive: true, force: true });
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function resolveVariantDir(srcDir, variant, lang) {
|
|
941
|
+
const langVariant = `${lang}/${variant}`;
|
|
942
|
+
const hasLangVariant = fs.existsSync(path.join(srcDir, "pages", langVariant, "index.astro"));
|
|
943
|
+
return hasLangVariant ? langVariant : variant;
|
|
874
944
|
}
|
|
875
|
-
function extractVariantFiles(projectDir, tpl) {
|
|
945
|
+
function extractVariantFiles(projectDir, tpl, lang) {
|
|
876
946
|
const srcDir = path.join(projectDir, "src");
|
|
877
|
-
const variant = tpl.variant;
|
|
947
|
+
const variant = resolveVariantDir(srcDir, tpl.variant, lang);
|
|
878
948
|
const pagesVariantIndex = path.join(srcDir, "pages", variant, "index.astro");
|
|
879
949
|
if (!fs.existsSync(pagesVariantIndex)) {
|
|
880
950
|
throw new Error(
|
package/dist/index.js
CHANGED
package/dist/lib.d.ts
CHANGED
|
@@ -2,9 +2,15 @@ interface RunCreateArgs {
|
|
|
2
2
|
template?: string;
|
|
3
3
|
targetDir?: string;
|
|
4
4
|
force?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* 明示指定された言語(`--lang`)。`ja` / `en` のときその言語で CLI 表示・テンプレ生成を確定する。
|
|
7
|
+
* 未指定(undefined / 不正値)の場合は、対話端末では最初に言語選択プロンプトを出し、
|
|
8
|
+
* 非対話端末(CI・パイプ等)では `en` にフォールバックする。
|
|
9
|
+
*/
|
|
10
|
+
lang?: string;
|
|
5
11
|
}
|
|
6
12
|
/** `lism create` / `create-lism` から共通で使える実体関数 */
|
|
7
|
-
declare function runCreate({ template, targetDir, force }: RunCreateArgs): Promise<void>;
|
|
13
|
+
declare function runCreate({ template, targetDir, force, lang }: RunCreateArgs): Promise<void>;
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
16
|
* CLI 表示用のメッセージ辞書(ja / en)。
|
|
@@ -25,8 +31,8 @@ declare const messages: {
|
|
|
25
31
|
readonly en: "CLI for Lism CSS / UI";
|
|
26
32
|
};
|
|
27
33
|
readonly 'cli.opt.lang': {
|
|
28
|
-
readonly ja: "CLI
|
|
29
|
-
readonly en: "
|
|
34
|
+
readonly ja: "CLI 表示と生成テンプレートの言語(ja | en、未指定なら対話時に選択)";
|
|
35
|
+
readonly en: "Language for the CLI and generated template (ja | en; prompted when omitted)";
|
|
30
36
|
};
|
|
31
37
|
readonly 'cli.create.description': {
|
|
32
38
|
readonly ja: "templates から新規プロジェクトを生成する";
|
|
@@ -459,14 +465,6 @@ declare const messages: {
|
|
|
459
465
|
};
|
|
460
466
|
type MessageKey = keyof typeof messages;
|
|
461
467
|
|
|
462
|
-
/**
|
|
463
|
-
* CLI の i18n(多言語化)基盤。
|
|
464
|
-
*
|
|
465
|
-
* - 既定は英語(`en`)。環境ロケールが `ja*` のときのみ日本語(`ja`)に切り替わる。
|
|
466
|
-
* - `--lang <code>` オプションで明示上書き可能。
|
|
467
|
-
* - メッセージ辞書は `messages.ts` に集約。
|
|
468
|
-
*/
|
|
469
|
-
|
|
470
468
|
type Lang = 'ja' | 'en';
|
|
471
469
|
/** 現在の言語を設定する(未知の値は無視) */
|
|
472
470
|
declare function setLang(lang: string | undefined): void;
|
package/dist/lib.js
CHANGED