lism-cli 0.3.1 → 0.4.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 +2 -2
- package/dist/{chunk-3PSCUHIC.js → chunk-ZSHT6RXM.js} +355 -35
- package/dist/index.js +1 -1
- package/dist/lib.d.ts +55 -7
- package/dist/lib.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
## コマンド体系
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
lism create [targetDir] [--template <name>] #
|
|
12
|
+
lism create [targetDir] [--template <name>] # templates から新規プロジェクト
|
|
13
13
|
lism ui { init | add <names...> | list } # Lism UI コンポーネントの追加
|
|
14
14
|
lism skill { add | check | update } # AI エージェント向け SKILL.md 配置
|
|
15
15
|
```
|
|
@@ -23,7 +23,7 @@ lism skill { add | check | update } # AI エージェント向け SKIL
|
|
|
23
23
|
pnpm dlx lism-cli create
|
|
24
24
|
|
|
25
25
|
# テンプレート名・出力先を指定
|
|
26
|
-
pnpm dlx lism-cli create --template astro
|
|
26
|
+
pnpm dlx lism-cli create --template minimal-astro ./my-app
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
同じ動作は `pnpm create lism` / `npm create lism@latest` でも呼び出せます(`create-lism` パッケージ経由)。
|
|
@@ -13,16 +13,16 @@ var messages = {
|
|
|
13
13
|
},
|
|
14
14
|
// create
|
|
15
15
|
"cli.create.description": {
|
|
16
|
-
ja: "
|
|
17
|
-
en: "Create a new project from
|
|
16
|
+
ja: "templates \u304B\u3089\u65B0\u898F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u751F\u6210\u3059\u308B",
|
|
17
|
+
en: "Create a new project from a template"
|
|
18
18
|
},
|
|
19
19
|
"cli.create.arg.targetDir": {
|
|
20
20
|
ja: "\u51FA\u529B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA",
|
|
21
21
|
en: "Target directory"
|
|
22
22
|
},
|
|
23
23
|
"cli.create.opt.template": {
|
|
24
|
-
ja: "\u4F7F\u7528\u3059\u308B\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u540D\uFF08\u4F8B: astro
|
|
25
|
-
en: "Template name to use (e.g. astro
|
|
24
|
+
ja: "\u4F7F\u7528\u3059\u308B\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u540D\uFF08\u4F8B: minimal-astro\uFF09",
|
|
25
|
+
en: "Template name to use (e.g. minimal-astro)"
|
|
26
26
|
},
|
|
27
27
|
"cli.create.opt.force": {
|
|
28
28
|
ja: "\u65E2\u5B58\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u5F37\u5236\u4E0A\u66F8\u304D",
|
|
@@ -121,9 +121,33 @@ var messages = {
|
|
|
121
121
|
ja: '\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8 "{name}" \u306F\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u5229\u7528\u53EF\u80FD: {list}',
|
|
122
122
|
en: 'Template "{name}" not found. Available: {list}'
|
|
123
123
|
},
|
|
124
|
-
"create.
|
|
125
|
-
ja: "\u30C6\
|
|
126
|
-
en: "Select a
|
|
124
|
+
"create.promptSelectCategory": {
|
|
125
|
+
ja: "\u30AB\u30C6\u30B4\u30EA\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044:",
|
|
126
|
+
en: "Select a category:"
|
|
127
|
+
},
|
|
128
|
+
"create.promptSelectVariant": {
|
|
129
|
+
ja: "\u30D0\u30EA\u30A2\u30F3\u30C8\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF08{count}\u4EF6\uFF09:",
|
|
130
|
+
en: "Select a variant ({count} options):"
|
|
131
|
+
},
|
|
132
|
+
"create.promptSelectVariant.blog": {
|
|
133
|
+
ja: "\u6A5F\u80FD\u30EC\u30D9\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF08{count}\u4EF6\uFF09:",
|
|
134
|
+
en: "Select a feature level ({count} options):"
|
|
135
|
+
},
|
|
136
|
+
"create.promptSelectVariant.lp": {
|
|
137
|
+
ja: "\u696D\u7A2E\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF08{count}\u4EF6\uFF09:",
|
|
138
|
+
en: "Select an industry ({count} options):"
|
|
139
|
+
},
|
|
140
|
+
"create.promptSelectVariant.web": {
|
|
141
|
+
ja: "\u696D\u7A2E\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF08{count}\u4EF6\uFF09:",
|
|
142
|
+
en: "Select an industry ({count} options):"
|
|
143
|
+
},
|
|
144
|
+
"create.promptSelectStack": {
|
|
145
|
+
ja: "\u30B9\u30BF\u30C3\u30AF\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF08{count}\u4EF6\uFF09:",
|
|
146
|
+
en: "Select a stack ({count} options):"
|
|
147
|
+
},
|
|
148
|
+
"create.usingStack": {
|
|
149
|
+
ja: "\u30B9\u30BF\u30C3\u30AF\u306F{stack}\u3092\u4F7F\u7528\u3057\u307E\u3059\uFF08{count}\u4EF6\uFF09\u3002",
|
|
150
|
+
en: "Using {stack} stack ({count} option)."
|
|
127
151
|
},
|
|
128
152
|
"create.promptTargetDir": {
|
|
129
153
|
ja: "\u51FA\u529B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA:",
|
|
@@ -141,6 +165,18 @@ var messages = {
|
|
|
141
165
|
ja: '\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8 "{name}" \u3092\u53D6\u5F97\u4E2D\uFF08ref: {ref}\uFF09...',
|
|
142
166
|
en: 'Fetching template "{name}" (ref: {ref})...'
|
|
143
167
|
},
|
|
168
|
+
"create.templatePackageMissing": {
|
|
169
|
+
ja: '\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8"{name}"\u306E\u53D6\u5F97\u7D50\u679C\u306Bpackage.json\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u53D6\u5F97\u5143\u30D1\u30B9\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044: {path}',
|
|
170
|
+
en: 'Downloaded template "{name}" does not contain package.json. Check the source path: {path}'
|
|
171
|
+
},
|
|
172
|
+
"create.templateIndexMissing": {
|
|
173
|
+
ja: '\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8"{name}"\u306E\u53D6\u5F97\u7D50\u679C\u306Bindex.html\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u53D6\u5F97\u5143\u30D1\u30B9\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044: {path}',
|
|
174
|
+
en: 'Downloaded template "{name}" does not contain index.html. Check the source path: {path}'
|
|
175
|
+
},
|
|
176
|
+
"create.variantMissing": {
|
|
177
|
+
ja: 'variant "{variant}" \u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u53D6\u5F97\u5143\u30D1\u30B9\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044: {path}',
|
|
178
|
+
en: 'Variant "{variant}" directory not found. Check the source path: {path}'
|
|
179
|
+
},
|
|
144
180
|
"create.created": {
|
|
145
181
|
ja: "{dir} \u306B\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u751F\u6210\u3057\u307E\u3057\u305F\u3002",
|
|
146
182
|
en: "Generated project at {dir}."
|
|
@@ -149,6 +185,18 @@ var messages = {
|
|
|
149
185
|
ja: "\u6B21\u306E\u30B3\u30DE\u30F3\u30C9\u3067\u958B\u767A\u3092\u958B\u59CB\u3067\u304D\u307E\u3059:",
|
|
150
186
|
en: "Next steps:"
|
|
151
187
|
},
|
|
188
|
+
"create.nextStepsHtmlOpen": {
|
|
189
|
+
ja: " index.html\u3092\u30D6\u30E9\u30A6\u30B6\u3067\u958B\u3044\u3066\u304F\u3060\u3055\u3044",
|
|
190
|
+
en: " Open index.html in your browser"
|
|
191
|
+
},
|
|
192
|
+
"create.packageNameRewritten": {
|
|
193
|
+
ja: ' package.json\u306Ename\u3092"{name}"\u306B\u5909\u66F4\u3057\u307E\u3057\u305F\u3002',
|
|
194
|
+
en: ' Updated package.json name to "{name}".'
|
|
195
|
+
},
|
|
196
|
+
"create.packageNameFailed": {
|
|
197
|
+
ja: "package.json\u306Ename\u66F8\u304D\u63DB\u3048\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {reason}",
|
|
198
|
+
en: "Failed to rewrite package.json name: {reason}"
|
|
199
|
+
},
|
|
152
200
|
"create.workspaceReplaced": {
|
|
153
201
|
ja: " package.json \u306E workspace:* \u3092 ^{version} \u306B\u7F6E\u63DB\u3057\u307E\u3057\u305F\u3002",
|
|
154
202
|
en: " Replaced workspace:* in package.json with ^{version}."
|
|
@@ -469,6 +517,7 @@ function interpolate(template, vars) {
|
|
|
469
517
|
|
|
470
518
|
// src/commands/create.ts
|
|
471
519
|
import fs from "fs";
|
|
520
|
+
import os from "os";
|
|
472
521
|
import path from "path";
|
|
473
522
|
import { downloadTemplate } from "giget";
|
|
474
523
|
import { select, input, confirm } from "@inquirer/prompts";
|
|
@@ -498,8 +547,8 @@ var logger = {
|
|
|
498
547
|
};
|
|
499
548
|
|
|
500
549
|
// src/version.ts
|
|
501
|
-
var LISM_CSS_VERSION = "0.
|
|
502
|
-
var CLI_VERSION = "0.
|
|
550
|
+
var LISM_CSS_VERSION = "0.18.0" ? "0.18.0" : "unknown";
|
|
551
|
+
var CLI_VERSION = "0.4.0" ? "0.4.0" : "unknown";
|
|
503
552
|
|
|
504
553
|
// src/constants.ts
|
|
505
554
|
var SOURCE_REPO = "lism-css/lism-css";
|
|
@@ -511,19 +560,126 @@ var UI_COMPONENTS_PATH = "packages/lism-ui/src/components";
|
|
|
511
560
|
var UI_HELPER_PATH = "packages/lism-ui/src/helper";
|
|
512
561
|
var UI_REGISTRY_INDEX_PATH = "packages/lism-ui/registry-index.json";
|
|
513
562
|
var SKILL_SOURCE_PATH = "skills/lism-css-guide";
|
|
514
|
-
var
|
|
563
|
+
var TEMPLATES_PATH = "templates";
|
|
515
564
|
|
|
516
|
-
//
|
|
565
|
+
// ../../templates/manifest.ts
|
|
517
566
|
var TEMPLATES = [
|
|
518
567
|
{
|
|
519
|
-
|
|
520
|
-
|
|
568
|
+
slug: "minimal-astro",
|
|
569
|
+
kind: "project",
|
|
570
|
+
category: "minimal",
|
|
571
|
+
stack: "astro",
|
|
572
|
+
sourcePath: "minimal/astro",
|
|
573
|
+
title: { ja: "Minimal Astro", en: "Minimal Astro" },
|
|
521
574
|
description: { ja: "Astro \u30D9\u30FC\u30B9\u306E\u6700\u5C0F\u69CB\u6210", en: "Minimal Astro setup" }
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
slug: "minimal-vite",
|
|
578
|
+
kind: "project",
|
|
579
|
+
category: "minimal",
|
|
580
|
+
stack: "vite",
|
|
581
|
+
sourcePath: "minimal/vite",
|
|
582
|
+
title: { ja: "Minimal Vite", en: "Minimal Vite" },
|
|
583
|
+
description: { ja: "Vite + React \u30D9\u30FC\u30B9\u306E\u6700\u5C0F\u69CB\u6210", en: "Minimal Vite + React setup" },
|
|
584
|
+
previewUrl: "https://lism-minimal-vite.pages.dev/"
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
slug: "blog-astro-simple",
|
|
588
|
+
kind: "project",
|
|
589
|
+
category: "blog",
|
|
590
|
+
variant: "simple",
|
|
591
|
+
variantLabel: { ja: "Simple", en: "Simple" },
|
|
592
|
+
stack: "astro",
|
|
593
|
+
sourcePath: "blog/astro/simple",
|
|
594
|
+
title: { ja: "Blog Astro Simple", en: "Blog Astro Simple" },
|
|
595
|
+
description: { ja: "\u30BF\u30B0\u306E\u307F\u306E\u30B7\u30F3\u30D7\u30EB\u306A Astro \u30D6\u30ED\u30B0", en: "Simple Astro blog with tags" },
|
|
596
|
+
draft: true
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
slug: "blog-astro-full",
|
|
600
|
+
kind: "project",
|
|
601
|
+
category: "blog",
|
|
602
|
+
variant: "full",
|
|
603
|
+
variantLabel: { ja: "Full", en: "Full" },
|
|
604
|
+
stack: "astro",
|
|
605
|
+
sourcePath: "blog/astro/full",
|
|
606
|
+
title: { ja: "Blog Astro Full", en: "Blog Astro Full" },
|
|
607
|
+
description: { ja: "\u30AB\u30C6\u30B4\u30EA\u30FB\u76EE\u6B21\u3064\u304D\u306E Astro \u30D6\u30ED\u30B0", en: "Astro blog with categories and table of contents" },
|
|
608
|
+
draft: true
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
slug: "lp-astro-minimal",
|
|
612
|
+
kind: "single-project-variant",
|
|
613
|
+
category: "lp",
|
|
614
|
+
stack: "astro",
|
|
615
|
+
variant: "minimal",
|
|
616
|
+
variantLabel: { ja: "Minimal", en: "Minimal" },
|
|
617
|
+
sourcePath: "lp/astro",
|
|
618
|
+
title: { ja: "LP Minimal", en: "LP Minimal" },
|
|
619
|
+
description: { ja: "\u30DF\u30CB\u30DE\u30EB\u306A Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8", en: "Minimal Astro landing page" },
|
|
620
|
+
draft: true
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
slug: "lp-astro-natural",
|
|
624
|
+
kind: "single-project-variant",
|
|
625
|
+
category: "lp",
|
|
626
|
+
stack: "astro",
|
|
627
|
+
variant: "natural",
|
|
628
|
+
variantLabel: { ja: "Natural", en: "Natural" },
|
|
629
|
+
sourcePath: "lp/astro",
|
|
630
|
+
title: { ja: "LP Natural", en: "LP Natural" },
|
|
631
|
+
description: { ja: "\u30CA\u30C1\u30E5\u30E9\u30EB\u306A\u96F0\u56F2\u6C17\u306E Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8", en: "Natural-themed Astro landing page" },
|
|
632
|
+
draft: true
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
slug: "lp-astro-ryokan",
|
|
636
|
+
kind: "single-project-variant",
|
|
637
|
+
category: "lp",
|
|
638
|
+
stack: "astro",
|
|
639
|
+
variant: "ryokan",
|
|
640
|
+
variantLabel: { ja: "Ryokan", en: "Ryokan" },
|
|
641
|
+
sourcePath: "lp/astro",
|
|
642
|
+
title: { ja: "LP Ryokan", en: "LP Ryokan" },
|
|
643
|
+
description: { ja: "\u65C5\u9928\u30FB\u5BBF\u6CCA\u696D\u5411\u3051\u306E Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8", en: "Astro landing page for ryokan / lodging" },
|
|
644
|
+
draft: true
|
|
645
|
+
}
|
|
646
|
+
];
|
|
647
|
+
|
|
648
|
+
// src/commands/create.ts
|
|
649
|
+
var STACK_LABELS = {
|
|
650
|
+
astro: { ja: "Astro", en: "Astro" },
|
|
651
|
+
next: { ja: "Next.js", en: "Next.js" },
|
|
652
|
+
vite: { ja: "Vite + React", en: "Vite + React" },
|
|
653
|
+
html: { ja: "Static HTML", en: "Static HTML" }
|
|
654
|
+
};
|
|
655
|
+
var CATEGORIES = [
|
|
656
|
+
{
|
|
657
|
+
id: "minimal",
|
|
658
|
+
label: { ja: "Minimal", en: "Minimal" }
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
id: "blog",
|
|
662
|
+
label: { ja: "Blog", en: "Blog" },
|
|
663
|
+
variantPromptKey: "create.promptSelectVariant.blog"
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
id: "lp",
|
|
667
|
+
label: { ja: "Landing Page", en: "Landing Page" },
|
|
668
|
+
variantPromptKey: "create.promptSelectVariant.lp"
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
id: "web",
|
|
672
|
+
label: { ja: "Web", en: "Web" },
|
|
673
|
+
variantPromptKey: "create.promptSelectVariant.web"
|
|
522
674
|
}
|
|
523
675
|
];
|
|
524
676
|
async function runCreate({ template, targetDir, force = false }) {
|
|
525
|
-
|
|
526
|
-
|
|
677
|
+
await runCreateWithTemplates({ template, targetDir, force }, TEMPLATES);
|
|
678
|
+
}
|
|
679
|
+
async function runCreateWithTemplates({ template, targetDir, force = false }, templates) {
|
|
680
|
+
const availableTemplates = templates.filter((tpl2) => !tpl2.draft);
|
|
681
|
+
const tpl = await resolveTemplate(template, availableTemplates);
|
|
682
|
+
const outDir = path.resolve(process.cwd(), await resolveTargetDir(targetDir, tpl.slug));
|
|
527
683
|
if (fs.existsSync(outDir) && fs.readdirSync(outDir).length > 0 && !force) {
|
|
528
684
|
const ok = await confirm({
|
|
529
685
|
message: t("create.confirmOverwrite", { dir: outDir }),
|
|
@@ -535,37 +691,68 @@ async function runCreate({ template, targetDir, force = false }) {
|
|
|
535
691
|
}
|
|
536
692
|
}
|
|
537
693
|
const ref = DEFAULT_TEMPLATES_REF;
|
|
538
|
-
logger.info(t("create.fetching", { name: tpl.
|
|
539
|
-
await
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
forceClean: force
|
|
543
|
-
});
|
|
544
|
-
rewriteWorkspaceDeps(outDir);
|
|
694
|
+
logger.info(t("create.fetching", { name: tpl.slug, ref }));
|
|
695
|
+
await downloadTemplateSource(tpl, outDir, ref, force);
|
|
696
|
+
ensureTemplateDownloaded(outDir, tpl);
|
|
697
|
+
postProcessTemplate(outDir, tpl);
|
|
545
698
|
logger.success(t("create.created", { dir: outDir }));
|
|
546
|
-
|
|
547
|
-
const rel = path.relative(process.cwd(), outDir) || ".";
|
|
548
|
-
logger.log(` cd ${rel}`);
|
|
549
|
-
logger.log(" npm install # or pnpm install / yarn");
|
|
550
|
-
logger.log(" npm run dev");
|
|
551
|
-
logger.log("");
|
|
699
|
+
printNextSteps(outDir, tpl);
|
|
552
700
|
}
|
|
553
701
|
async function createCommand(targetDir, options) {
|
|
554
702
|
await runCreate({ template: options.template, targetDir, force: options.force });
|
|
555
703
|
}
|
|
556
|
-
async function resolveTemplate(requested) {
|
|
704
|
+
async function resolveTemplate(requested, templates) {
|
|
557
705
|
if (requested) {
|
|
558
|
-
const found =
|
|
706
|
+
const found = templates.find((t2) => t2.slug === requested);
|
|
559
707
|
if (!found) {
|
|
560
|
-
throw new Error(t("create.templateNotFound", { name: requested, list:
|
|
708
|
+
throw new Error(t("create.templateNotFound", { name: requested, list: templates.map((x) => x.slug).join(", ") }));
|
|
561
709
|
}
|
|
562
710
|
return found;
|
|
563
711
|
}
|
|
564
|
-
const
|
|
565
|
-
message: t("create.
|
|
566
|
-
choices:
|
|
712
|
+
const category = await select({
|
|
713
|
+
message: t("create.promptSelectCategory"),
|
|
714
|
+
choices: CATEGORIES.filter((category2) => templates.some((tpl) => tpl.category === category2.id)).map((category2) => ({
|
|
715
|
+
name: tOf(category2.label),
|
|
716
|
+
value: category2.id
|
|
717
|
+
}))
|
|
718
|
+
});
|
|
719
|
+
const categoryTemplates = templates.filter((tpl) => tpl.category === category);
|
|
720
|
+
const stack = await resolveStack(categoryTemplates);
|
|
721
|
+
const stackTemplates = categoryTemplates.filter((tpl) => tpl.stack === stack);
|
|
722
|
+
const variant = await resolveVariant(category, stackTemplates);
|
|
723
|
+
const variantTemplates = variant === void 0 ? stackTemplates : stackTemplates.filter((tpl) => tpl.variant === variant);
|
|
724
|
+
return variantTemplates[0];
|
|
725
|
+
}
|
|
726
|
+
async function resolveVariant(category, templates) {
|
|
727
|
+
const variants = uniqueDefined(templates.map((tpl) => tpl.variant));
|
|
728
|
+
if (variants.length <= 1) return variants[0];
|
|
729
|
+
const categoryDef = CATEGORIES.find((item) => item.id === category);
|
|
730
|
+
const messageKey = categoryDef?.variantPromptKey ?? "create.promptSelectVariant";
|
|
731
|
+
return select({
|
|
732
|
+
message: t(messageKey, { count: variants.length }),
|
|
733
|
+
choices: variants.map((variant) => {
|
|
734
|
+
const tpl = templates.find((item) => item.variant === variant);
|
|
735
|
+
return {
|
|
736
|
+
name: `${tOf(tpl.variantLabel ?? { ja: variant ?? "", en: variant ?? "" })} \u2014 ${tOf(tpl.description)}`,
|
|
737
|
+
value: variant
|
|
738
|
+
};
|
|
739
|
+
})
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
async function resolveStack(templates) {
|
|
743
|
+
const stacks = uniqueDefined(templates.map((tpl) => tpl.stack));
|
|
744
|
+
if (stacks.length === 1) {
|
|
745
|
+
const stack = stacks[0];
|
|
746
|
+
logger.info(t("create.usingStack", { stack: tOf(STACK_LABELS[stack]), count: stacks.length }));
|
|
747
|
+
return stack;
|
|
748
|
+
}
|
|
749
|
+
return select({
|
|
750
|
+
message: t("create.promptSelectStack", { count: stacks.length }),
|
|
751
|
+
choices: stacks.map((stack) => ({
|
|
752
|
+
name: tOf(STACK_LABELS[stack]),
|
|
753
|
+
value: stack
|
|
754
|
+
}))
|
|
567
755
|
});
|
|
568
|
-
return TEMPLATES.find((x) => x.name === picked);
|
|
569
756
|
}
|
|
570
757
|
async function resolveTargetDir(provided, templateName) {
|
|
571
758
|
if (provided) return provided;
|
|
@@ -574,6 +761,139 @@ async function resolveTargetDir(provided, templateName) {
|
|
|
574
761
|
default: `./${templateName}`
|
|
575
762
|
});
|
|
576
763
|
}
|
|
764
|
+
function ensureTemplateDownloaded(projectDir, tpl) {
|
|
765
|
+
if (tpl.kind === "static-html") {
|
|
766
|
+
const indexPath = path.join(projectDir, "index.html");
|
|
767
|
+
if (fs.existsSync(indexPath)) return;
|
|
768
|
+
throw new Error(t("create.templateIndexMissing", { name: tpl.slug, path: getTemplateSourcePath(tpl) }));
|
|
769
|
+
}
|
|
770
|
+
const pkgPath = path.join(projectDir, "package.json");
|
|
771
|
+
if (fs.existsSync(pkgPath)) return;
|
|
772
|
+
throw new Error(t("create.templatePackageMissing", { name: tpl.slug, path: getTemplateSourcePath(tpl) }));
|
|
773
|
+
}
|
|
774
|
+
async function downloadTemplateSource(tpl, outDir, ref, forceClean) {
|
|
775
|
+
if (tpl.kind === "base-overlay") {
|
|
776
|
+
await downloadTemplatePath(tpl.basePath, outDir, ref, forceClean);
|
|
777
|
+
const overlayDir = fs.mkdtempSync(path.join(os.tmpdir(), "lism-template-overlay-"));
|
|
778
|
+
try {
|
|
779
|
+
await downloadTemplatePath(tpl.overlayPath, overlayDir, ref, true);
|
|
780
|
+
mergeDirectory(overlayDir, outDir);
|
|
781
|
+
} finally {
|
|
782
|
+
fs.rmSync(overlayDir, { recursive: true, force: true });
|
|
783
|
+
}
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
await downloadTemplatePath(tpl.sourcePath, outDir, ref, forceClean);
|
|
787
|
+
}
|
|
788
|
+
async function downloadTemplatePath(sourcePath, outDir, ref, forceClean) {
|
|
789
|
+
await downloadTemplate(`github:${SOURCE_REPO}/${TEMPLATES_PATH}/${sourcePath}#${ref}`, {
|
|
790
|
+
dir: outDir,
|
|
791
|
+
force: true,
|
|
792
|
+
forceClean
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
function postProcessTemplate(projectDir, tpl) {
|
|
796
|
+
if (tpl.kind === "static-html") return;
|
|
797
|
+
if (tpl.kind === "base-overlay" && tpl.rewritePackageName !== false) {
|
|
798
|
+
rewritePackageName(projectDir, tpl.slug);
|
|
799
|
+
}
|
|
800
|
+
if (tpl.kind === "single-project-variant") {
|
|
801
|
+
extractVariantPages(projectDir, tpl);
|
|
802
|
+
rewritePackageName(projectDir, tpl.packageName ?? tpl.slug);
|
|
803
|
+
}
|
|
804
|
+
cleanupDevArtifacts(projectDir);
|
|
805
|
+
rewriteWorkspaceDeps(projectDir);
|
|
806
|
+
}
|
|
807
|
+
function cleanupDevArtifacts(projectDir) {
|
|
808
|
+
const screenshotsDir = path.join(projectDir, "screenshots");
|
|
809
|
+
if (fs.existsSync(screenshotsDir)) {
|
|
810
|
+
fs.rmSync(screenshotsDir, { recursive: true, force: true });
|
|
811
|
+
}
|
|
812
|
+
const screenshotsConfig = path.join(projectDir, "screenshots.config.json");
|
|
813
|
+
if (fs.existsSync(screenshotsConfig)) {
|
|
814
|
+
fs.rmSync(screenshotsConfig, { force: true });
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
function extractVariantPages(projectDir, tpl) {
|
|
818
|
+
const pagesDir = path.join(projectDir, "src", "pages");
|
|
819
|
+
const variantDir = path.join(pagesDir, tpl.variant);
|
|
820
|
+
const variantIndex = path.join(variantDir, "index.astro");
|
|
821
|
+
const targetIndex = path.join(pagesDir, "index.astro");
|
|
822
|
+
if (!fs.existsSync(variantIndex)) {
|
|
823
|
+
throw new Error(
|
|
824
|
+
t("create.variantMissing", {
|
|
825
|
+
variant: tpl.variant,
|
|
826
|
+
path: `${formatTemplatePath(tpl.sourcePath)}/src/pages/${tpl.variant}/index.astro`
|
|
827
|
+
})
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
if (fs.existsSync(targetIndex)) {
|
|
831
|
+
fs.rmSync(targetIndex, { force: true });
|
|
832
|
+
}
|
|
833
|
+
fs.renameSync(variantIndex, targetIndex);
|
|
834
|
+
for (const entry of fs.readdirSync(pagesDir, { withFileTypes: true })) {
|
|
835
|
+
if (!entry.isDirectory()) continue;
|
|
836
|
+
fs.rmSync(path.join(pagesDir, entry.name), { recursive: true, force: true });
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
function printNextSteps(projectDir, tpl) {
|
|
840
|
+
logger.heading(t("create.nextSteps"));
|
|
841
|
+
const rel = path.relative(process.cwd(), projectDir) || ".";
|
|
842
|
+
logger.log(` cd ${rel}`);
|
|
843
|
+
if (tpl.kind === "static-html") {
|
|
844
|
+
logger.log(t("create.nextStepsHtmlOpen"));
|
|
845
|
+
logger.log("");
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
logger.log(" npm install # or pnpm install / yarn");
|
|
849
|
+
logger.log(" npm run dev");
|
|
850
|
+
logger.log("");
|
|
851
|
+
}
|
|
852
|
+
function getTemplateSourcePath(tpl) {
|
|
853
|
+
if (tpl.kind === "base-overlay") return `${formatTemplatePath(tpl.basePath)} + ${formatTemplatePath(tpl.overlayPath)}`;
|
|
854
|
+
return formatTemplatePath(tpl.sourcePath);
|
|
855
|
+
}
|
|
856
|
+
function formatTemplatePath(sourcePath) {
|
|
857
|
+
return `${TEMPLATES_PATH}/${sourcePath}`;
|
|
858
|
+
}
|
|
859
|
+
function uniqueDefined(values) {
|
|
860
|
+
return [...new Set(values.filter((value) => value !== void 0))];
|
|
861
|
+
}
|
|
862
|
+
function mergeDirectory(fromDir, toDir) {
|
|
863
|
+
fs.mkdirSync(toDir, { recursive: true });
|
|
864
|
+
for (const entry of fs.readdirSync(fromDir, { withFileTypes: true })) {
|
|
865
|
+
const fromPath = path.join(fromDir, entry.name);
|
|
866
|
+
const toPath = path.join(toDir, entry.name);
|
|
867
|
+
if (entry.isDirectory()) {
|
|
868
|
+
if (fs.existsSync(toPath) && !fs.statSync(toPath).isDirectory()) {
|
|
869
|
+
fs.rmSync(toPath, { recursive: true, force: true });
|
|
870
|
+
}
|
|
871
|
+
mergeDirectory(fromPath, toPath);
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
874
|
+
if (fs.existsSync(toPath)) {
|
|
875
|
+
fs.rmSync(toPath, { recursive: true, force: true });
|
|
876
|
+
}
|
|
877
|
+
if (entry.isSymbolicLink()) {
|
|
878
|
+
fs.symlinkSync(fs.readlinkSync(fromPath), toPath);
|
|
879
|
+
} else {
|
|
880
|
+
fs.copyFileSync(fromPath, toPath);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
function rewritePackageName(projectDir, name) {
|
|
885
|
+
const pkgPath = path.join(projectDir, "package.json");
|
|
886
|
+
if (!fs.existsSync(pkgPath)) return;
|
|
887
|
+
try {
|
|
888
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
889
|
+
if (pkg.name === name) return;
|
|
890
|
+
pkg.name = name;
|
|
891
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
892
|
+
logger.log(t("create.packageNameRewritten", { name }));
|
|
893
|
+
} catch (err) {
|
|
894
|
+
logger.warn(t("create.packageNameFailed", { reason: String(err) }));
|
|
895
|
+
}
|
|
896
|
+
}
|
|
577
897
|
function rewriteWorkspaceDeps(projectDir) {
|
|
578
898
|
const pkgPath = path.join(projectDir, "package.json");
|
|
579
899
|
if (!fs.existsSync(pkgPath)) return;
|
package/dist/index.js
CHANGED
package/dist/lib.d.ts
CHANGED
|
@@ -29,16 +29,16 @@ declare const messages: {
|
|
|
29
29
|
readonly en: "Display language for the CLI (ja | en)";
|
|
30
30
|
};
|
|
31
31
|
readonly 'cli.create.description': {
|
|
32
|
-
readonly ja: "
|
|
33
|
-
readonly en: "Create a new project from
|
|
32
|
+
readonly ja: "templates から新規プロジェクトを生成する";
|
|
33
|
+
readonly en: "Create a new project from a template";
|
|
34
34
|
};
|
|
35
35
|
readonly 'cli.create.arg.targetDir': {
|
|
36
36
|
readonly ja: "出力先ディレクトリ";
|
|
37
37
|
readonly en: "Target directory";
|
|
38
38
|
};
|
|
39
39
|
readonly 'cli.create.opt.template': {
|
|
40
|
-
readonly ja: "使用するテンプレート名(例: astro
|
|
41
|
-
readonly en: "Template name to use (e.g. astro
|
|
40
|
+
readonly ja: "使用するテンプレート名(例: minimal-astro)";
|
|
41
|
+
readonly en: "Template name to use (e.g. minimal-astro)";
|
|
42
42
|
};
|
|
43
43
|
readonly 'cli.create.opt.force': {
|
|
44
44
|
readonly ja: "既存ディレクトリを強制上書き";
|
|
@@ -132,9 +132,33 @@ declare const messages: {
|
|
|
132
132
|
readonly ja: "テンプレート \"{name}\" は見つかりません。利用可能: {list}";
|
|
133
133
|
readonly en: "Template \"{name}\" not found. Available: {list}";
|
|
134
134
|
};
|
|
135
|
-
readonly 'create.
|
|
136
|
-
readonly ja: "
|
|
137
|
-
readonly en: "Select a
|
|
135
|
+
readonly 'create.promptSelectCategory': {
|
|
136
|
+
readonly ja: "カテゴリを選択してください:";
|
|
137
|
+
readonly en: "Select a category:";
|
|
138
|
+
};
|
|
139
|
+
readonly 'create.promptSelectVariant': {
|
|
140
|
+
readonly ja: "バリアントを選択してください({count}件):";
|
|
141
|
+
readonly en: "Select a variant ({count} options):";
|
|
142
|
+
};
|
|
143
|
+
readonly 'create.promptSelectVariant.blog': {
|
|
144
|
+
readonly ja: "機能レベルを選択してください({count}件):";
|
|
145
|
+
readonly en: "Select a feature level ({count} options):";
|
|
146
|
+
};
|
|
147
|
+
readonly 'create.promptSelectVariant.lp': {
|
|
148
|
+
readonly ja: "業種を選択してください({count}件):";
|
|
149
|
+
readonly en: "Select an industry ({count} options):";
|
|
150
|
+
};
|
|
151
|
+
readonly 'create.promptSelectVariant.web': {
|
|
152
|
+
readonly ja: "業種を選択してください({count}件):";
|
|
153
|
+
readonly en: "Select an industry ({count} options):";
|
|
154
|
+
};
|
|
155
|
+
readonly 'create.promptSelectStack': {
|
|
156
|
+
readonly ja: "スタックを選択してください({count}件):";
|
|
157
|
+
readonly en: "Select a stack ({count} options):";
|
|
158
|
+
};
|
|
159
|
+
readonly 'create.usingStack': {
|
|
160
|
+
readonly ja: "スタックは{stack}を使用します({count}件)。";
|
|
161
|
+
readonly en: "Using {stack} stack ({count} option).";
|
|
138
162
|
};
|
|
139
163
|
readonly 'create.promptTargetDir': {
|
|
140
164
|
readonly ja: "出力先ディレクトリ:";
|
|
@@ -152,6 +176,18 @@ declare const messages: {
|
|
|
152
176
|
readonly ja: "テンプレート \"{name}\" を取得中(ref: {ref})...";
|
|
153
177
|
readonly en: "Fetching template \"{name}\" (ref: {ref})...";
|
|
154
178
|
};
|
|
179
|
+
readonly 'create.templatePackageMissing': {
|
|
180
|
+
readonly ja: "テンプレート\"{name}\"の取得結果にpackage.jsonがありません。取得元パスを確認してください: {path}";
|
|
181
|
+
readonly en: "Downloaded template \"{name}\" does not contain package.json. Check the source path: {path}";
|
|
182
|
+
};
|
|
183
|
+
readonly 'create.templateIndexMissing': {
|
|
184
|
+
readonly ja: "テンプレート\"{name}\"の取得結果にindex.htmlがありません。取得元パスを確認してください: {path}";
|
|
185
|
+
readonly en: "Downloaded template \"{name}\" does not contain index.html. Check the source path: {path}";
|
|
186
|
+
};
|
|
187
|
+
readonly 'create.variantMissing': {
|
|
188
|
+
readonly ja: "variant \"{variant}\" のディレクトリが見つかりません。取得元パスを確認してください: {path}";
|
|
189
|
+
readonly en: "Variant \"{variant}\" directory not found. Check the source path: {path}";
|
|
190
|
+
};
|
|
155
191
|
readonly 'create.created': {
|
|
156
192
|
readonly ja: "{dir} にプロジェクトを生成しました。";
|
|
157
193
|
readonly en: "Generated project at {dir}.";
|
|
@@ -160,6 +196,18 @@ declare const messages: {
|
|
|
160
196
|
readonly ja: "次のコマンドで開発を開始できます:";
|
|
161
197
|
readonly en: "Next steps:";
|
|
162
198
|
};
|
|
199
|
+
readonly 'create.nextStepsHtmlOpen': {
|
|
200
|
+
readonly ja: " index.htmlをブラウザで開いてください";
|
|
201
|
+
readonly en: " Open index.html in your browser";
|
|
202
|
+
};
|
|
203
|
+
readonly 'create.packageNameRewritten': {
|
|
204
|
+
readonly ja: " package.jsonのnameを\"{name}\"に変更しました。";
|
|
205
|
+
readonly en: " Updated package.json name to \"{name}\".";
|
|
206
|
+
};
|
|
207
|
+
readonly 'create.packageNameFailed': {
|
|
208
|
+
readonly ja: "package.jsonのname書き換えに失敗しました: {reason}";
|
|
209
|
+
readonly en: "Failed to rewrite package.json name: {reason}";
|
|
210
|
+
};
|
|
163
211
|
readonly 'create.workspaceReplaced': {
|
|
164
212
|
readonly ja: " package.json の workspace:* を ^{version} に置換しました。";
|
|
165
213
|
readonly en: " Replaced workspace:* in package.json with ^{version}.";
|
package/dist/lib.js
CHANGED