@c-time/frelio-cli 1.4.0 → 1.4.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.
- package/README.md +18 -14
- package/dist/commands/init.js +4 -16
- package/dist/core/content-structure.d.ts +8 -14
- package/dist/core/content-structure.js +9 -112
- package/dist/core/index.d.ts +2 -3
- package/dist/core/index.js +3 -3
- package/dist/core/template-scaffold.d.ts +14 -0
- package/dist/core/template-scaffold.js +99 -0
- package/dist/lib/template-renderer.d.ts +16 -0
- package/dist/lib/template-renderer.js +32 -0
- package/dist/lib/templates.d.ts +0 -8
- package/dist/lib/templates.js +0 -227
- package/package.json +2 -3
- package/dist/core/workflows.d.ts +0 -11
- package/dist/core/workflows.js +0 -180
- package/dist/lib/initial-content.d.ts +0 -5
- package/dist/lib/initial-content.js +0 -2183
package/README.md
CHANGED
|
@@ -142,12 +142,11 @@ frelio init
|
|
|
142
142
|
2. **対話式プロンプト** — リポジトリ名、サイトタイトル、R2 設定などを入力
|
|
143
143
|
3. **GitHub OAuth App の案内** — OAuth App の作成手順を表示し、Client ID / Secret を入力
|
|
144
144
|
4. **GitHub リポジトリ作成** — `gh repo create` でプライベートリポジトリを作成・クローン
|
|
145
|
-
5.
|
|
146
|
-
6. **
|
|
147
|
-
7.
|
|
148
|
-
8.
|
|
149
|
-
9.
|
|
150
|
-
10. **ブランチ構造の作成** — `main`、`develop`、`staging` ブランチを作成・プッシュ、デフォルトブランチを `develop` に設定
|
|
145
|
+
5. **コンテンツリポジトリのスキャフォールド** — GitHub から [`c-time/frelio-content-template`](https://github.com/c-time/frelio-content-template) をダウンロードし、設定値を埋め込んで展開(`frelio-data/`、`scripts/`、`.github/workflows/`、`vite.config.ts` 等)
|
|
146
|
+
6. **CMS Admin バンドルの展開** — 最新リリースから `admin/`、`functions/`、`workers/` を配置
|
|
147
|
+
7. **設定ファイル生成** — `admin/config.json`、`wrangler.toml`、`_redirects`、`_routes.json`
|
|
148
|
+
8. **Cloudflare セットアップ** — R2 バケット作成、本番用 Pages プロジェクト作成、ステージング用 Pages プロジェクト作成、OAuth シークレット設定
|
|
149
|
+
9. **ブランチ構造の作成** — `main`、`develop`、`staging` ブランチを作成・プッシュ、デフォルトブランチを `develop` に設定
|
|
151
150
|
|
|
152
151
|
#### プロンプトで聞かれること
|
|
153
152
|
|
|
@@ -212,7 +211,7 @@ frelio init \
|
|
|
212
211
|
|
|
213
212
|
```
|
|
214
213
|
my-site/
|
|
215
|
-
├── admin/ # CMS
|
|
214
|
+
├── admin/ # CMS 管理画面(ビルド済み、frelio update で更新)
|
|
216
215
|
│ ├── index.html
|
|
217
216
|
│ ├── config.json # 実行時設定
|
|
218
217
|
│ └── assets/
|
|
@@ -231,19 +230,24 @@ my-site/
|
|
|
231
230
|
│ │ ├── contents/
|
|
232
231
|
│ │ │ ├── published/ # 公開済み
|
|
233
232
|
│ │ │ └── private/ # 下書き
|
|
234
|
-
│ │ ├── templates/ # HTML テンプレート
|
|
235
|
-
│ │ │
|
|
236
|
-
│ │ │
|
|
237
|
-
│ │ │
|
|
233
|
+
│ │ ├── templates/ # HTML テンプレート + アセットソース
|
|
234
|
+
│ │ │ ├── _parts/ # 共通パーツ (head.htm, header.htm, footer.htm)
|
|
235
|
+
│ │ │ ├── common/ # 全ページ共通 (scripts/ + styles/)
|
|
236
|
+
│ │ │ ├── about/ # ページ別 (index.html + scripts/ + styles/)
|
|
237
|
+
│ │ │ ├── contact/
|
|
238
|
+
│ │ │ └── news/
|
|
238
239
|
│ │ └── data/data-json/ # SSG 中間データ
|
|
239
240
|
│ └── admin/
|
|
240
|
-
│ ├──
|
|
241
|
+
│ ├── content_types/ # UI/Views 設定
|
|
242
|
+
│ ├── metadata/ # content_types.json, _dashboard.json
|
|
241
243
|
│ ├── recipes/ # ビルドレシピ
|
|
242
|
-
│ └──
|
|
243
|
-
├──
|
|
244
|
+
│ └── structure/ # users.json, stages.json
|
|
245
|
+
├── scripts/ # SSG ビルドスクリプト (tsx)
|
|
246
|
+
├── .github/workflows/ # GitHub Actions(4ワークフロー)
|
|
244
247
|
├── vite.config.ts # テンプレートアセットビルド(SCSS/TS)
|
|
245
248
|
├── package.json # vite + sass + typescript
|
|
246
249
|
├── tsconfig.json
|
|
250
|
+
├── tsconfig.node.json
|
|
247
251
|
├── wrangler.toml # Cloudflare 設定(R2 バインディング)
|
|
248
252
|
├── _redirects # /admin/* → SPA, /* → /public/:splat
|
|
249
253
|
├── _routes.json # /api/*, /storage/* → Functions
|
package/dist/commands/init.js
CHANGED
|
@@ -17,7 +17,6 @@ import { createRepo, cloneRepo, getAuthenticatedUser } from '../core/github.js';
|
|
|
17
17
|
import { setupCloudflareResources } from '../core/cloudflare.js';
|
|
18
18
|
import { createFullContentStructure } from '../core/content-structure.js';
|
|
19
19
|
import { regenerateAllConfigFiles } from '../core/file-generators.js';
|
|
20
|
-
import { generateWorkflows } from '../core/workflows.js';
|
|
21
20
|
import { generateTerraformFiles } from '../core/terraform.js';
|
|
22
21
|
import { installBundle } from '../core/bundle.js';
|
|
23
22
|
import { initialCommitAndBranches } from '../core/git-operations.js';
|
|
@@ -126,28 +125,17 @@ export async function initCommand(options) {
|
|
|
126
125
|
fs.mkdirSync(projectDir, { recursive: true });
|
|
127
126
|
}
|
|
128
127
|
}
|
|
129
|
-
//
|
|
128
|
+
// コンテンツリポジトリ初期構造(ワークフロー含む)
|
|
130
129
|
step++;
|
|
131
130
|
logStep(step, totalSteps, 'コンテンツリポジトリ初期構造作成...');
|
|
132
|
-
const structResult = createFullContentStructure(projectDir, config);
|
|
131
|
+
const structResult = await createFullContentStructure(projectDir, config);
|
|
133
132
|
if (structResult.success) {
|
|
134
|
-
logSuccess('
|
|
133
|
+
logSuccess('初期構造作成完了(デモサイトテンプレート + ワークフロー)');
|
|
135
134
|
}
|
|
136
135
|
else {
|
|
137
136
|
logError(structResult.error);
|
|
138
137
|
process.exit(1);
|
|
139
138
|
}
|
|
140
|
-
// GitHub Actions ワークフロー
|
|
141
|
-
step++;
|
|
142
|
-
logStep(step, totalSteps, 'GitHub Actions ワークフロー配置...');
|
|
143
|
-
const workflowResult = generateWorkflows(projectDir, config);
|
|
144
|
-
if (workflowResult.success) {
|
|
145
|
-
logSuccess('ワークフロー配置完了');
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
logError(workflowResult.error);
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
139
|
// CMS Admin バンドル展開
|
|
152
140
|
step++;
|
|
153
141
|
logStep(step, totalSteps, 'CMS Admin バンドルをダウンロード・展開...');
|
|
@@ -396,7 +384,7 @@ function buildConfigFromOptions(options) {
|
|
|
396
384
|
};
|
|
397
385
|
}
|
|
398
386
|
function getTotalSteps(options) {
|
|
399
|
-
let steps =
|
|
387
|
+
let steps = 3; // content structure (includes workflows), bundle, config files
|
|
400
388
|
if (!options.skipGithub)
|
|
401
389
|
steps += 3; // create repo, clone, commit/push
|
|
402
390
|
if (options.terraform)
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* core/content-structure — コンテンツリポジトリのディレクトリ・ファイル構造生成
|
|
3
|
+
*
|
|
4
|
+
* テンプレートからのスキャフォールディングに委譲する。
|
|
3
5
|
*/
|
|
4
6
|
import { type ProjectConfig, type OperationResult } from './types.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}>;
|
|
11
|
-
export declare function createProjectFiles(projectDir: string, config: ProjectConfig): OperationResult<{
|
|
12
|
-
files: string[];
|
|
13
|
-
}>;
|
|
14
|
-
export declare function createDemoContent(projectDir: string): OperationResult<{
|
|
15
|
-
generated: boolean;
|
|
16
|
-
}>;
|
|
17
|
-
export declare function createFullContentStructure(projectDir: string, config: ProjectConfig): OperationResult<{
|
|
7
|
+
/**
|
|
8
|
+
* テンプレートからコンテンツリポジトリの全構造を生成する。
|
|
9
|
+
* ワークフローファイル(.github/workflows/)もテンプレートに含まれる。
|
|
10
|
+
*/
|
|
11
|
+
export declare function createFullContentStructure(projectDir: string, config: ProjectConfig): Promise<OperationResult<{
|
|
18
12
|
files: string[];
|
|
19
|
-
}
|
|
13
|
+
}>>;
|
|
@@ -1,116 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* core/content-structure — コンテンツリポジトリのディレクトリ・ファイル構造生成
|
|
3
|
+
*
|
|
4
|
+
* テンプレートからのスキャフォールディングに委譲する。
|
|
3
5
|
*/
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const CONTENT_DIRS = [
|
|
12
|
-
'frelio-data/site/content_types',
|
|
13
|
-
'frelio-data/site/contents/published',
|
|
14
|
-
'frelio-data/site/contents/private',
|
|
15
|
-
'frelio-data/site/templates/assets/scss',
|
|
16
|
-
'frelio-data/site/templates/assets/ts',
|
|
17
|
-
'frelio-data/site/templates/assets/entries',
|
|
18
|
-
'frelio-data/site/data/data-json',
|
|
19
|
-
'frelio-data/admin/metadata',
|
|
20
|
-
'frelio-data/admin/structure',
|
|
21
|
-
'frelio-data/admin/recipes',
|
|
22
|
-
'scripts',
|
|
23
|
-
'public',
|
|
24
|
-
];
|
|
25
|
-
export function createContentDirectories(projectDir) {
|
|
26
|
-
try {
|
|
27
|
-
for (const dir of CONTENT_DIRS) {
|
|
28
|
-
ensureDir(path.join(projectDir, dir));
|
|
29
|
-
}
|
|
30
|
-
return ok({ directories: CONTENT_DIRS });
|
|
31
|
-
}
|
|
32
|
-
catch (e) {
|
|
33
|
-
return fail(`ディレクトリ作成失敗: ${e.message}`, 'EXEC_FAILED');
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
// Structure files (users.json, stages.json, version.json)
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
|
-
export function createStructureFiles(projectDir, config) {
|
|
40
|
-
const files = [];
|
|
41
|
-
try {
|
|
42
|
-
const writes = [
|
|
43
|
-
['frelio-data/admin/structure/users.json', generateUsersJson(config)],
|
|
44
|
-
['frelio-data/admin/structure/stages.json', generateStagesJson()],
|
|
45
|
-
['version.json', generateVersionJson()],
|
|
46
|
-
];
|
|
47
|
-
for (const [rel, content] of writes) {
|
|
48
|
-
writeFile(path.join(projectDir, rel), content);
|
|
49
|
-
files.push(rel);
|
|
50
|
-
}
|
|
51
|
-
return ok({ files });
|
|
52
|
-
}
|
|
53
|
-
catch (e) {
|
|
54
|
-
return fail(`構造ファイル生成失敗: ${e.message}`, 'EXEC_FAILED');
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
// ---------------------------------------------------------------------------
|
|
58
|
-
// Project scaffolding files (package.json, vite.config, tsconfig, etc.)
|
|
59
|
-
// ---------------------------------------------------------------------------
|
|
60
|
-
export function createProjectFiles(projectDir, config) {
|
|
61
|
-
const files = [];
|
|
62
|
-
try {
|
|
63
|
-
const writes = [
|
|
64
|
-
['vite.config.ts', generateViteConfig()],
|
|
65
|
-
['tsconfig.json', generateTsConfig()],
|
|
66
|
-
['tsconfig.node.json', generateTsConfigNode()],
|
|
67
|
-
['package.json', generatePackageJson(config)],
|
|
68
|
-
[path.join('functions', 'storage', '[[path]].ts'), generateStorageFunction()],
|
|
69
|
-
];
|
|
70
|
-
for (const [rel, content] of writes) {
|
|
71
|
-
writeFile(path.join(projectDir, rel), content);
|
|
72
|
-
files.push(rel);
|
|
73
|
-
}
|
|
74
|
-
// .gitignore
|
|
75
|
-
const gitignoreLines = ['node_modules/', '.wrangler/', '.dev.vars'];
|
|
76
|
-
writeFile(path.join(projectDir, '.gitignore'), gitignoreLines.join('\n') + '\n');
|
|
77
|
-
files.push('.gitignore');
|
|
78
|
-
return ok({ files });
|
|
79
|
-
}
|
|
80
|
-
catch (e) {
|
|
81
|
-
return fail(`プロジェクトファイル生成失敗: ${e.message}`, 'EXEC_FAILED');
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// ---------------------------------------------------------------------------
|
|
85
|
-
// Demo content
|
|
86
|
-
// ---------------------------------------------------------------------------
|
|
87
|
-
export function createDemoContent(projectDir) {
|
|
88
|
-
try {
|
|
89
|
-
generateInitialContent(projectDir);
|
|
90
|
-
return ok({ generated: true });
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
return fail(`デモコンテンツ生成失敗: ${e.message}`, 'EXEC_FAILED');
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
// ---------------------------------------------------------------------------
|
|
97
|
-
// All-in-one
|
|
98
|
-
// ---------------------------------------------------------------------------
|
|
99
|
-
export function createFullContentStructure(projectDir, config) {
|
|
100
|
-
const allFiles = [];
|
|
101
|
-
const dirsResult = createContentDirectories(projectDir);
|
|
102
|
-
if (!dirsResult.success)
|
|
103
|
-
return dirsResult;
|
|
104
|
-
const structResult = createStructureFiles(projectDir, config);
|
|
105
|
-
if (!structResult.success)
|
|
106
|
-
return structResult;
|
|
107
|
-
allFiles.push(...structResult.data.files);
|
|
108
|
-
const projResult = createProjectFiles(projectDir, config);
|
|
109
|
-
if (!projResult.success)
|
|
110
|
-
return projResult;
|
|
111
|
-
allFiles.push(...projResult.data.files);
|
|
112
|
-
const demoResult = createDemoContent(projectDir);
|
|
113
|
-
if (!demoResult.success)
|
|
114
|
-
return demoResult;
|
|
115
|
-
return ok({ files: allFiles });
|
|
6
|
+
import { scaffoldFromTemplate } from './template-scaffold.js';
|
|
7
|
+
/**
|
|
8
|
+
* テンプレートからコンテンツリポジトリの全構造を生成する。
|
|
9
|
+
* ワークフローファイル(.github/workflows/)もテンプレートに含まれる。
|
|
10
|
+
*/
|
|
11
|
+
export async function createFullContentStructure(projectDir, config) {
|
|
12
|
+
return scaffoldFromTemplate(projectDir, config);
|
|
116
13
|
}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -14,10 +14,9 @@ export type { PrerequisiteTarget } from './prerequisites.js';
|
|
|
14
14
|
export { createRepo, cloneRepo, getAuthenticatedUser } from './github.js';
|
|
15
15
|
export { createR2Bucket, createPagesProject, setPagesSecret, setupCloudflareResources, } from './cloudflare.js';
|
|
16
16
|
export type { CloudflareSetupResult } from './cloudflare.js';
|
|
17
|
-
export {
|
|
17
|
+
export { createFullContentStructure } from './content-structure.js';
|
|
18
|
+
export { scaffoldFromTemplate } from './template-scaffold.js';
|
|
18
19
|
export { generateAndWriteConfigJson, generateAndWriteWranglerToml, generateAndWriteRedirects, generateAndWriteRoutesJson, generateAndWritePublicRoutesJson, generateAndWriteStorageFunction, regenerateAllConfigFiles, } from './file-generators.js';
|
|
19
|
-
export { generateWorkflow, generateWorkflows } from './workflows.js';
|
|
20
|
-
export type { WorkflowName } from './workflows.js';
|
|
21
20
|
export { generateTerraformFiles } from './terraform.js';
|
|
22
21
|
export { installBundle, updateBundle, getBundleVersion } from './bundle.js';
|
|
23
22
|
export { initialCommitAndBranches, createBranch, checkWorkflowBranchCoverage, } from './git-operations.js';
|
package/dist/core/index.js
CHANGED
|
@@ -17,11 +17,11 @@ export { createRepo, cloneRepo, getAuthenticatedUser } from './github.js';
|
|
|
17
17
|
// Cloudflare
|
|
18
18
|
export { createR2Bucket, createPagesProject, setPagesSecret, setupCloudflareResources, } from './cloudflare.js';
|
|
19
19
|
// Content structure
|
|
20
|
-
export {
|
|
20
|
+
export { createFullContentStructure } from './content-structure.js';
|
|
21
|
+
// Template scaffold
|
|
22
|
+
export { scaffoldFromTemplate } from './template-scaffold.js';
|
|
21
23
|
// File generators
|
|
22
24
|
export { generateAndWriteConfigJson, generateAndWriteWranglerToml, generateAndWriteRedirects, generateAndWriteRoutesJson, generateAndWritePublicRoutesJson, generateAndWriteStorageFunction, regenerateAllConfigFiles, } from './file-generators.js';
|
|
23
|
-
// Workflows
|
|
24
|
-
export { generateWorkflow, generateWorkflows } from './workflows.js';
|
|
25
25
|
// Terraform
|
|
26
26
|
export { generateTerraformFiles } from './terraform.js';
|
|
27
27
|
// Bundle
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/template-scaffold — テンプレートからのコンテンツリポジトリ生成
|
|
3
|
+
*
|
|
4
|
+
* GitHub から c-time/frelio-content-template の tarball をダウンロードし、
|
|
5
|
+
* .hbs ファイルは変数置換、それ以外はそのままコピーして出力先に展開する。
|
|
6
|
+
*/
|
|
7
|
+
import { type ProjectConfig, type OperationResult } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* テンプレートからコンテンツリポジトリを生成する。
|
|
10
|
+
* GitHub から c-time/frelio-content-template を取得して展開する。
|
|
11
|
+
*/
|
|
12
|
+
export declare function scaffoldFromTemplate(projectDir: string, config: ProjectConfig): Promise<OperationResult<{
|
|
13
|
+
files: string[];
|
|
14
|
+
}>>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/template-scaffold — テンプレートからのコンテンツリポジトリ生成
|
|
3
|
+
*
|
|
4
|
+
* GitHub から c-time/frelio-content-template の tarball をダウンロードし、
|
|
5
|
+
* .hbs ファイルは変数置換、それ以外はそのままコピーして出力先に展開する。
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { pipeline } from 'node:stream/promises';
|
|
11
|
+
import { extract } from 'tar';
|
|
12
|
+
import { ok, fail } from './types.js';
|
|
13
|
+
import { renderTemplate, projectConfigToVars } from '../lib/template-renderer.js';
|
|
14
|
+
const TEMPLATE_REPO = 'c-time/frelio-content-template';
|
|
15
|
+
const TEMPLATE_BRANCH = 'main';
|
|
16
|
+
/**
|
|
17
|
+
* GitHub から tarball をダウンロードして一時ディレクトリに展開する
|
|
18
|
+
*/
|
|
19
|
+
async function fetchTemplate() {
|
|
20
|
+
const url = `https://api.github.com/repos/${TEMPLATE_REPO}/tarball/${TEMPLATE_BRANCH}`;
|
|
21
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'frelio-template-'));
|
|
22
|
+
const tarPath = path.join(tmpDir, 'template.tar.gz');
|
|
23
|
+
const response = await fetch(url, {
|
|
24
|
+
headers: { Accept: 'application/vnd.github+json' },
|
|
25
|
+
redirect: 'follow',
|
|
26
|
+
});
|
|
27
|
+
if (!response.ok || !response.body) {
|
|
28
|
+
throw new Error(`GitHub API responded with ${response.status}`);
|
|
29
|
+
}
|
|
30
|
+
const dest = fs.createWriteStream(tarPath);
|
|
31
|
+
await pipeline(response.body, dest);
|
|
32
|
+
const extractDir = path.join(tmpDir, 'extracted');
|
|
33
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
34
|
+
await extract({ file: tarPath, cwd: extractDir });
|
|
35
|
+
// GitHub の tarball は owner-repo-sha/ というプレフィックスディレクトリに入る
|
|
36
|
+
const entries = fs.readdirSync(extractDir);
|
|
37
|
+
if (entries.length !== 1) {
|
|
38
|
+
throw new Error(`Unexpected tarball structure: ${entries.join(', ')}`);
|
|
39
|
+
}
|
|
40
|
+
return path.join(extractDir, entries[0]);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* ディレクトリを再帰的に走査してファイル一覧を返す
|
|
44
|
+
*/
|
|
45
|
+
function walkDir(dir, base = dir) {
|
|
46
|
+
const files = [];
|
|
47
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
48
|
+
const fullPath = path.join(dir, entry.name);
|
|
49
|
+
if (entry.isDirectory()) {
|
|
50
|
+
files.push(...walkDir(fullPath, base));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
files.push(path.relative(base, fullPath));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return files;
|
|
57
|
+
}
|
|
58
|
+
/** コピー対象外のファイル */
|
|
59
|
+
const SKIP_FILES = new Set(['template.config.json', 'README.md']);
|
|
60
|
+
/**
|
|
61
|
+
* テンプレートからコンテンツリポジトリを生成する。
|
|
62
|
+
* GitHub から c-time/frelio-content-template を取得して展開する。
|
|
63
|
+
*/
|
|
64
|
+
export async function scaffoldFromTemplate(projectDir, config) {
|
|
65
|
+
let templateDir;
|
|
66
|
+
try {
|
|
67
|
+
templateDir = await fetchTemplate();
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
return fail(`テンプレートの取得に失敗しました: ${e.message}`, 'EXEC_FAILED');
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const vars = projectConfigToVars(config);
|
|
74
|
+
const templateFiles = walkDir(templateDir);
|
|
75
|
+
const outputFiles = [];
|
|
76
|
+
for (const relPath of templateFiles) {
|
|
77
|
+
if (SKIP_FILES.has(relPath))
|
|
78
|
+
continue;
|
|
79
|
+
const srcPath = path.join(templateDir, relPath);
|
|
80
|
+
const content = fs.readFileSync(srcPath, 'utf-8');
|
|
81
|
+
const isHbs = relPath.endsWith('.hbs');
|
|
82
|
+
const outputRelPath = isHbs ? relPath.slice(0, -4) : relPath;
|
|
83
|
+
const outputContent = isHbs ? renderTemplate(content, vars) : content;
|
|
84
|
+
const outputPath = path.join(projectDir, outputRelPath);
|
|
85
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
86
|
+
fs.writeFileSync(outputPath, outputContent, 'utf-8');
|
|
87
|
+
outputFiles.push(outputRelPath);
|
|
88
|
+
}
|
|
89
|
+
return ok({ files: outputFiles });
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
return fail(`テンプレート展開失敗: ${e.message}`, 'EXEC_FAILED');
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
// 一時ディレクトリを削除
|
|
96
|
+
const tmpDir = path.resolve(templateDir, '..', '..');
|
|
97
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* テンプレート変数置換
|
|
3
|
+
*
|
|
4
|
+
* {{variable}} 形式のプレースホルダーを値に置換する。
|
|
5
|
+
* GitHub Actions の ${{ expression }} とは衝突しない。
|
|
6
|
+
*/
|
|
7
|
+
import type { ProjectConfig } from './templates.js';
|
|
8
|
+
export type TemplateVariables = Record<string, string>;
|
|
9
|
+
/**
|
|
10
|
+
* テンプレート文字列内の {{variable}} を置換する
|
|
11
|
+
*/
|
|
12
|
+
export declare function renderTemplate(content: string, vars: TemplateVariables): string;
|
|
13
|
+
/**
|
|
14
|
+
* ProjectConfig からテンプレート変数マップを生成する
|
|
15
|
+
*/
|
|
16
|
+
export declare function projectConfigToVars(config: ProjectConfig): TemplateVariables;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* テンプレート変数置換
|
|
3
|
+
*
|
|
4
|
+
* {{variable}} 形式のプレースホルダーを値に置換する。
|
|
5
|
+
* GitHub Actions の ${{ expression }} とは衝突しない。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* テンプレート文字列内の {{variable}} を置換する
|
|
9
|
+
*/
|
|
10
|
+
export function renderTemplate(content, vars) {
|
|
11
|
+
return content.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
12
|
+
return key in vars ? vars[key] : match;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* ProjectConfig からテンプレート変数マップを生成する
|
|
17
|
+
*/
|
|
18
|
+
export function projectConfigToVars(config) {
|
|
19
|
+
return {
|
|
20
|
+
contentRepo: config.contentRepo,
|
|
21
|
+
githubClientId: config.githubClientId,
|
|
22
|
+
siteTitle: config.siteTitle,
|
|
23
|
+
productionUrl: config.productionUrl,
|
|
24
|
+
previewUrl: config.previewUrl,
|
|
25
|
+
fileUploadUrl: '/api/storage',
|
|
26
|
+
pagesProjectName: config.pagesProjectName,
|
|
27
|
+
adminPagesProjectName: config.adminPagesProjectName,
|
|
28
|
+
r2BucketName: config.r2BucketName,
|
|
29
|
+
r2PublicUrl: config.r2PublicUrl,
|
|
30
|
+
ownerUsername: config.ownerUsername,
|
|
31
|
+
};
|
|
32
|
+
}
|
package/dist/lib/templates.d.ts
CHANGED
|
@@ -25,17 +25,9 @@ export declare function generateHash(): string;
|
|
|
25
25
|
export declare function generateStagingDomain(productionUrl: string, pagesProjectName: string): string;
|
|
26
26
|
export declare function generateConfigJson(config: ProjectConfig): string;
|
|
27
27
|
export declare function generateWranglerToml(config: ProjectConfig): string;
|
|
28
|
-
export declare function generateUsersJson(config: ProjectConfig): string;
|
|
29
|
-
export declare function generateStagesJson(): string;
|
|
30
|
-
export declare function generateContentTypesJson(): string;
|
|
31
|
-
export declare function generateVersionJson(): string;
|
|
32
28
|
export declare function generateRedirects(): string;
|
|
33
29
|
export declare function generateRoutesJson(): string;
|
|
34
30
|
export declare function generateStorageFunction(): string;
|
|
35
|
-
export declare function generateViteConfig(): string;
|
|
36
|
-
export declare function generatePackageJson(config: ProjectConfig): string;
|
|
37
|
-
export declare function generateTsConfig(): string;
|
|
38
|
-
export declare function generateTsConfigNode(): string;
|
|
39
31
|
export declare function generateTerraformProviders(): string;
|
|
40
32
|
export declare function generateTerraformVariables(config: ProjectConfig): string;
|
|
41
33
|
export declare function generateTerraformMain(config: ProjectConfig): string;
|