create-cwa 0.1.1 → 2.0.0-alpha.1
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/dist/index.js +44 -15
- package/package.json +1 -1
- package/src/index.ts +44 -16
- package/src/types.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -3,22 +3,51 @@ import { downloadTemplate } from 'giget';
|
|
|
3
3
|
import fse from 'fs-extra';
|
|
4
4
|
import fg from 'fast-glob';
|
|
5
5
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
6
|
-
import { existsSync } from 'node:fs';
|
|
6
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
7
7
|
import { join, resolve } from 'node:path';
|
|
8
8
|
import { tmpdir } from 'node:os';
|
|
9
9
|
import { randomBytes } from 'node:crypto';
|
|
10
10
|
import { spawnSync } from 'node:child_process';
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const REPO = 'components-web-app/components-web-app';
|
|
12
|
+
// The CLI and the template share a version: create-cwa X downloads the template at
|
|
13
|
+
// tag vX, so an install is reproducible. `--ref <branch|tag>` overrides it, for
|
|
14
|
+
// example `--ref main` for the latest unreleased template.
|
|
15
|
+
const CLI_VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
|
|
16
|
+
function parseArgs(argv) {
|
|
17
|
+
const args = argv.slice(2);
|
|
18
|
+
let ref = `v${CLI_VERSION}`;
|
|
19
|
+
const positional = [];
|
|
20
|
+
for (let i = 0; i < args.length; i++) {
|
|
21
|
+
const arg = args[i];
|
|
22
|
+
if (arg === '--ref' && args[i + 1])
|
|
23
|
+
ref = args[++i];
|
|
24
|
+
else if (arg.startsWith('--ref='))
|
|
25
|
+
ref = arg.slice('--ref='.length);
|
|
26
|
+
else
|
|
27
|
+
positional.push(arg);
|
|
28
|
+
}
|
|
29
|
+
return { projectName: positional[0], ref };
|
|
30
|
+
}
|
|
31
|
+
async function fetchManifest(ref) {
|
|
32
|
+
let res;
|
|
13
33
|
try {
|
|
14
|
-
|
|
15
|
-
if (!res.ok)
|
|
16
|
-
throw new Error(`HTTP ${res.status}`);
|
|
17
|
-
return (await res.json());
|
|
34
|
+
res = await fetch(`https://raw.githubusercontent.com/${REPO}/${ref}/cwa-manifest.json`);
|
|
18
35
|
}
|
|
19
36
|
catch {
|
|
20
37
|
throw new Error('Could not fetch the CWA manifest. Check your internet connection and try again.');
|
|
21
38
|
}
|
|
39
|
+
if (res.status === 404) {
|
|
40
|
+
throw new Error(`No CWA template found at "${ref}". Check the --ref value.`);
|
|
41
|
+
}
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
throw new Error(`Could not fetch the CWA manifest (HTTP ${res.status}). Try again shortly.`);
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
return (await res.json());
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
throw new Error(`The CWA manifest at "${ref}" is not valid JSON.`);
|
|
50
|
+
}
|
|
22
51
|
}
|
|
23
52
|
function checkCancel(value) {
|
|
24
53
|
if (isCancel(value)) {
|
|
@@ -37,8 +66,7 @@ function run(cmd, args, cwd) {
|
|
|
37
66
|
const result = spawnSync(cmd, args, { stdio: 'inherit', cwd });
|
|
38
67
|
return result.status === 0;
|
|
39
68
|
}
|
|
40
|
-
async function askQuestions(manifest,
|
|
41
|
-
const targetArg = argv[2];
|
|
69
|
+
async function askQuestions(manifest, targetArg) {
|
|
42
70
|
const projectName = checkCancel(await text({
|
|
43
71
|
message: 'Project name?',
|
|
44
72
|
placeholder: 'my-cwa-app',
|
|
@@ -79,11 +107,11 @@ async function askQuestions(manifest, argv) {
|
|
|
79
107
|
}));
|
|
80
108
|
return { projectName: projectName.trim(), ci, features: [...resolved], fixtures };
|
|
81
109
|
}
|
|
82
|
-
async function downloadRepo(manifest, tempDir) {
|
|
110
|
+
async function downloadRepo(manifest, ref, tempDir) {
|
|
83
111
|
const s = spinner();
|
|
84
|
-
s.start(
|
|
112
|
+
s.start(`Downloading template (${ref})...`);
|
|
85
113
|
try {
|
|
86
|
-
await downloadTemplate(`github:${manifest.repo}#${
|
|
114
|
+
await downloadTemplate(`github:${manifest.repo}#${ref}`, {
|
|
87
115
|
dir: tempDir,
|
|
88
116
|
force: true,
|
|
89
117
|
});
|
|
@@ -208,21 +236,22 @@ async function moveToTarget(tempDir, targetDir) {
|
|
|
208
236
|
}
|
|
209
237
|
async function main() {
|
|
210
238
|
intro('create-cwa — Components Web App scaffolder');
|
|
239
|
+
const args = parseArgs(process.argv);
|
|
211
240
|
const s = spinner();
|
|
212
241
|
s.start('Fetching manifest...');
|
|
213
242
|
let manifest;
|
|
214
243
|
try {
|
|
215
|
-
manifest = await fetchManifest();
|
|
244
|
+
manifest = await fetchManifest(args.ref);
|
|
216
245
|
s.stop('Manifest loaded.');
|
|
217
246
|
}
|
|
218
247
|
catch (err) {
|
|
219
248
|
s.stop(err.message);
|
|
220
249
|
process.exit(1);
|
|
221
250
|
}
|
|
222
|
-
const answers = await askQuestions(manifest,
|
|
251
|
+
const answers = await askQuestions(manifest, args.projectName);
|
|
223
252
|
const targetDir = resolve(process.cwd(), answers.projectName);
|
|
224
253
|
const tempDir = join(tmpdir(), `cwa-${randomBytes(6).toString('hex')}`);
|
|
225
|
-
await downloadRepo(manifest, tempDir);
|
|
254
|
+
await downloadRepo(manifest, args.ref, tempDir);
|
|
226
255
|
const s2 = spinner();
|
|
227
256
|
s2.start('Configuring project...');
|
|
228
257
|
try {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -15,26 +15,55 @@ import { downloadTemplate } from 'giget'
|
|
|
15
15
|
import fse from 'fs-extra'
|
|
16
16
|
import fg from 'fast-glob'
|
|
17
17
|
import { readFile, writeFile } from 'node:fs/promises'
|
|
18
|
-
import { existsSync } from 'node:fs'
|
|
18
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
19
19
|
import { join, resolve } from 'node:path'
|
|
20
20
|
import { tmpdir } from 'node:os'
|
|
21
21
|
import { randomBytes } from 'node:crypto'
|
|
22
22
|
import { spawnSync } from 'node:child_process'
|
|
23
23
|
import type { Manifest, Answers } from './types.js'
|
|
24
24
|
|
|
25
|
-
const
|
|
26
|
-
|
|
25
|
+
const REPO = 'components-web-app/components-web-app'
|
|
26
|
+
|
|
27
|
+
// The CLI and the template share a version: create-cwa X downloads the template at
|
|
28
|
+
// tag vX, so an install is reproducible. `--ref <branch|tag>` overrides it, for
|
|
29
|
+
// example `--ref main` for the latest unreleased template.
|
|
30
|
+
const CLI_VERSION: string = JSON.parse(
|
|
31
|
+
readFileSync(new URL('../package.json', import.meta.url), 'utf8')
|
|
32
|
+
).version
|
|
33
|
+
|
|
34
|
+
function parseArgs(argv: string[]): { projectName?: string; ref: string } {
|
|
35
|
+
const args = argv.slice(2)
|
|
36
|
+
let ref = `v${CLI_VERSION}`
|
|
37
|
+
const positional: string[] = []
|
|
38
|
+
for (let i = 0; i < args.length; i++) {
|
|
39
|
+
const arg = args[i]
|
|
40
|
+
if (arg === '--ref' && args[i + 1]) ref = args[++i]
|
|
41
|
+
else if (arg.startsWith('--ref=')) ref = arg.slice('--ref='.length)
|
|
42
|
+
else positional.push(arg)
|
|
43
|
+
}
|
|
44
|
+
return { projectName: positional[0], ref }
|
|
45
|
+
}
|
|
27
46
|
|
|
28
|
-
async function fetchManifest(): Promise<Manifest> {
|
|
47
|
+
async function fetchManifest(ref: string): Promise<Manifest> {
|
|
48
|
+
let res: Response
|
|
29
49
|
try {
|
|
30
|
-
|
|
31
|
-
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
|
32
|
-
return (await res.json()) as Manifest
|
|
50
|
+
res = await fetch(`https://raw.githubusercontent.com/${REPO}/${ref}/cwa-manifest.json`)
|
|
33
51
|
} catch {
|
|
34
52
|
throw new Error(
|
|
35
53
|
'Could not fetch the CWA manifest. Check your internet connection and try again.'
|
|
36
54
|
)
|
|
37
55
|
}
|
|
56
|
+
if (res.status === 404) {
|
|
57
|
+
throw new Error(`No CWA template found at "${ref}". Check the --ref value.`)
|
|
58
|
+
}
|
|
59
|
+
if (!res.ok) {
|
|
60
|
+
throw new Error(`Could not fetch the CWA manifest (HTTP ${res.status}). Try again shortly.`)
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
return (await res.json()) as Manifest
|
|
64
|
+
} catch {
|
|
65
|
+
throw new Error(`The CWA manifest at "${ref}" is not valid JSON.`)
|
|
66
|
+
}
|
|
38
67
|
}
|
|
39
68
|
|
|
40
69
|
function checkCancel<T>(value: T | symbol): T {
|
|
@@ -57,9 +86,7 @@ function run(cmd: string, args: string[], cwd: string): boolean {
|
|
|
57
86
|
return result.status === 0
|
|
58
87
|
}
|
|
59
88
|
|
|
60
|
-
async function askQuestions(manifest: Manifest,
|
|
61
|
-
const targetArg = argv[2]
|
|
62
|
-
|
|
89
|
+
async function askQuestions(manifest: Manifest, targetArg?: string): Promise<Answers> {
|
|
63
90
|
const projectName = checkCancel(
|
|
64
91
|
await text({
|
|
65
92
|
message: 'Project name?',
|
|
@@ -118,11 +145,11 @@ async function askQuestions(manifest: Manifest, argv: string[]): Promise<Answers
|
|
|
118
145
|
return { projectName: projectName.trim(), ci, features: [...resolved], fixtures }
|
|
119
146
|
}
|
|
120
147
|
|
|
121
|
-
async function downloadRepo(manifest: Manifest, tempDir: string): Promise<void> {
|
|
148
|
+
async function downloadRepo(manifest: Manifest, ref: string, tempDir: string): Promise<void> {
|
|
122
149
|
const s = spinner()
|
|
123
|
-
s.start(
|
|
150
|
+
s.start(`Downloading template (${ref})...`)
|
|
124
151
|
try {
|
|
125
|
-
await downloadTemplate(`github:${manifest.repo}#${
|
|
152
|
+
await downloadTemplate(`github:${manifest.repo}#${ref}`, {
|
|
126
153
|
dir: tempDir,
|
|
127
154
|
force: true,
|
|
128
155
|
})
|
|
@@ -268,22 +295,23 @@ async function moveToTarget(tempDir: string, targetDir: string): Promise<void> {
|
|
|
268
295
|
async function main(): Promise<void> {
|
|
269
296
|
intro('create-cwa — Components Web App scaffolder')
|
|
270
297
|
|
|
298
|
+
const args = parseArgs(process.argv)
|
|
271
299
|
const s = spinner()
|
|
272
300
|
s.start('Fetching manifest...')
|
|
273
301
|
let manifest: Manifest
|
|
274
302
|
try {
|
|
275
|
-
manifest = await fetchManifest()
|
|
303
|
+
manifest = await fetchManifest(args.ref)
|
|
276
304
|
s.stop('Manifest loaded.')
|
|
277
305
|
} catch (err) {
|
|
278
306
|
s.stop((err as Error).message)
|
|
279
307
|
process.exit(1)
|
|
280
308
|
}
|
|
281
309
|
|
|
282
|
-
const answers = await askQuestions(manifest,
|
|
310
|
+
const answers = await askQuestions(manifest, args.projectName)
|
|
283
311
|
const targetDir = resolve(process.cwd(), answers.projectName)
|
|
284
312
|
const tempDir = join(tmpdir(), `cwa-${randomBytes(6).toString('hex')}`)
|
|
285
313
|
|
|
286
|
-
await downloadRepo(manifest, tempDir)
|
|
314
|
+
await downloadRepo(manifest, args.ref, tempDir)
|
|
287
315
|
|
|
288
316
|
const s2 = spinner()
|
|
289
317
|
s2.start('Configuring project...')
|
package/src/types.ts
CHANGED
|
@@ -26,6 +26,8 @@ export interface ManifestCi {
|
|
|
26
26
|
export interface Manifest {
|
|
27
27
|
version: string
|
|
28
28
|
repo: string
|
|
29
|
+
// Read only by create-cwa 0.x, which downloads this branch. Newer versions download
|
|
30
|
+
// the tag matching their own version, or --ref.
|
|
29
31
|
branch: string
|
|
30
32
|
alwaysExclude: string[]
|
|
31
33
|
questions: ManifestQuestion[]
|