@spicato-inc/create-fortenv 0.1.7 → 1.0.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/bin/create-fortenv.js +74 -16
- package/package.json +2 -6
package/bin/create-fortenv.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as p from '@clack/prompts';
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
|
-
import {
|
|
4
|
+
import { createWriteStream } from 'node:fs';
|
|
5
|
+
import { access, cp, mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
6
|
+
import os from 'node:os';
|
|
5
7
|
import path from 'node:path';
|
|
8
|
+
import { Readable } from 'node:stream';
|
|
9
|
+
import { pipeline } from 'node:stream/promises';
|
|
6
10
|
import { fileURLToPath } from 'node:url';
|
|
7
11
|
|
|
8
12
|
const TEMPLATES = [
|
|
@@ -82,10 +86,30 @@ function cancel() {
|
|
|
82
86
|
process.exit(0);
|
|
83
87
|
}
|
|
84
88
|
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
function run(command, args, options = {}) {
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const child = spawn(command, args, {
|
|
92
|
+
...options,
|
|
93
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
94
|
+
});
|
|
95
|
+
let stdout = '';
|
|
96
|
+
let stderr = '';
|
|
97
|
+
child.stdout.on('data', (chunk) => {
|
|
98
|
+
stdout += chunk;
|
|
99
|
+
});
|
|
100
|
+
child.stderr.on('data', (chunk) => {
|
|
101
|
+
stderr += chunk;
|
|
102
|
+
});
|
|
103
|
+
child.on('error', reject);
|
|
104
|
+
child.on('exit', (code) => {
|
|
105
|
+
if (code === 0) {
|
|
106
|
+
resolve(stdout);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const detail = stderr.trim();
|
|
110
|
+
reject(new Error(detail || `${command} が終了コード ${code} で失敗しました`));
|
|
111
|
+
});
|
|
112
|
+
});
|
|
89
113
|
}
|
|
90
114
|
|
|
91
115
|
async function exists(target) {
|
|
@@ -97,12 +121,39 @@ async function exists(target) {
|
|
|
97
121
|
}
|
|
98
122
|
}
|
|
99
123
|
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
throw new Error(
|
|
124
|
+
function tarballUrl(value, spec) {
|
|
125
|
+
const url = Array.isArray(value) ? value.at(-1) : value;
|
|
126
|
+
if (typeof url !== 'string' || !url) {
|
|
127
|
+
throw new Error(`雛形の取得先が不正です: ${spec}`);
|
|
128
|
+
}
|
|
129
|
+
return url;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async function fetchTemplate(type) {
|
|
133
|
+
const packageName = TEMPLATE_PACKAGES[type];
|
|
134
|
+
const spec = `${packageName}@latest`;
|
|
135
|
+
const root = await mkdtemp(path.join(os.tmpdir(), 'create-fortenv-'));
|
|
136
|
+
try {
|
|
137
|
+
const output = await run('npm', ['view', spec, 'dist.tarball', '--json'], {
|
|
138
|
+
cwd: root,
|
|
139
|
+
});
|
|
140
|
+
const url = tarballUrl(JSON.parse(output), spec);
|
|
141
|
+
const response = await fetch(url);
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
throw new Error(`雛形の取得に失敗しました: ${spec}`);
|
|
144
|
+
}
|
|
145
|
+
const archive = path.join(root, 'template.tgz');
|
|
146
|
+
await pipeline(Readable.fromWeb(response.body), createWriteStream(archive));
|
|
147
|
+
await run('tar', ['-xzf', archive, '-C', root]);
|
|
148
|
+
const dir = path.join(root, 'package');
|
|
149
|
+
if (!(await exists(path.join(dir, 'package.json')))) {
|
|
150
|
+
throw new Error(`雛形が見つかりません: ${spec}`);
|
|
151
|
+
}
|
|
152
|
+
return { dir, root };
|
|
153
|
+
} catch (error) {
|
|
154
|
+
await rm(root, { recursive: true, force: true });
|
|
155
|
+
throw error;
|
|
104
156
|
}
|
|
105
|
-
return dir;
|
|
106
157
|
}
|
|
107
158
|
|
|
108
159
|
async function promptValues(args) {
|
|
@@ -198,18 +249,25 @@ async function main() {
|
|
|
198
249
|
}
|
|
199
250
|
|
|
200
251
|
const { type, destination, name, install: shouldInstall } = await promptValues(args);
|
|
201
|
-
const source = await assertTemplate(type);
|
|
202
252
|
if (await exists(destination)) {
|
|
203
253
|
throw new Error(`作成先が既にあります: ${destination}`);
|
|
204
254
|
}
|
|
205
255
|
await mkdir(path.dirname(destination), { recursive: true });
|
|
206
256
|
|
|
207
257
|
const spinner = p.spinner();
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
258
|
+
let downloaded;
|
|
259
|
+
try {
|
|
260
|
+
spinner.start('最新の雛形を取得しています');
|
|
261
|
+
downloaded = await fetchTemplate(type);
|
|
262
|
+
await copyTemplate(downloaded.dir, destination);
|
|
263
|
+
await ensureGitignore(type, destination);
|
|
264
|
+
await rewritePackage(destination, name);
|
|
265
|
+
spinner.stop('雛形をコピーしました');
|
|
266
|
+
} finally {
|
|
267
|
+
if (downloaded) {
|
|
268
|
+
await rm(downloaded.root, { recursive: true, force: true });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
213
271
|
|
|
214
272
|
if (shouldInstall) {
|
|
215
273
|
spinner.start('npm install を実行しています');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spicato-inc/create-fortenv",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -15,11 +15,7 @@
|
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@clack/prompts": "^1.8.1"
|
|
19
|
-
"@spicato-inc/fortenv-mpa": "*",
|
|
20
|
-
"@spicato-inc/fortenv-spa": "*",
|
|
21
|
-
"@spicato-inc/fortenv-wp-mpa": "*",
|
|
22
|
-
"@spicato-inc/fortenv-wp-spa": "*"
|
|
18
|
+
"@clack/prompts": "^1.8.1"
|
|
23
19
|
},
|
|
24
20
|
"engines": {
|
|
25
21
|
"node": ">=22.18.0"
|