@twobirds/microcomponents 0.4.0 → 0.4.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/README.md +28 -14
- package/dist/cli/create.js +1 -1
- package/dist/cli/dispatch.d.ts.map +1 -1
- package/dist/cli/dispatch.js +52 -16
- package/dist/cli/writeScaffold.d.ts +35 -6
- package/dist/cli/writeScaffold.d.ts.map +1 -1
- package/dist/cli/writeScaffold.js +75 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,40 +58,54 @@ A small command-line tool scaffolds new components so the tag-to-file convention
|
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
60
|
pnpm run cli -- new my-card --target-html --target-css
|
|
61
|
-
# created my/card.ts
|
|
62
|
-
# created my/card.target.html
|
|
63
|
-
# created my/card.target.css
|
|
61
|
+
# created src/my/card.ts
|
|
62
|
+
# created src/my/card.target.html
|
|
63
|
+
# created src/my/card.target.css
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
`--dry-run` prints the plan without touching disk, so you can check the derived paths first:
|
|
66
|
+
Paths are printed as they appear from the current directory, so every line is a file you can open with `ls`. `--dry-run` prints the plan without touching disk, so you can check the derived paths first:
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
69
|
pnpm run cli -- new my-card --target-html --target-css --dry-run
|
|
70
|
-
# would create my/card.ts
|
|
71
|
-
# would create my/card.target.html
|
|
72
|
-
# would create my/card.target.css
|
|
70
|
+
# would create src/my/card.ts
|
|
71
|
+
# would create src/my/card.target.html
|
|
72
|
+
# would create src/my/card.target.css
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
`mc create` scaffolds a complete dev environment for a namespace — a Vite dev server serving `src/` straight, a page shell that turns on `autoload(true)`, and a starter component with companion assets:
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
78
|
pnpm run cli -- create --namespace mc --dir mc-app
|
|
79
|
-
# created package.json
|
|
80
|
-
# created src/index.html
|
|
81
|
-
# created src/mc/app.ts
|
|
82
|
-
# created src/mc/app.target.html
|
|
83
|
-
# created src/mc/app.target.css
|
|
79
|
+
# created mc-app/package.json
|
|
80
|
+
# created mc-app/src/index.html
|
|
81
|
+
# created mc-app/src/mc/app.ts
|
|
82
|
+
# created mc-app/src/mc/app.target.html
|
|
83
|
+
# created mc-app/src/mc/app.target.css
|
|
84
84
|
# ...
|
|
85
85
|
# project "mc" created in mc-app/ — run: cd mc-app && pnpm install && pnpm dev
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
The namespace (1 to 4 lowercase letters) becomes the `src/<namespace>/` folder and the first segment of every component tag, so `mc` is the home of tags like `<mc-app>`. Because the page shell is the autoload base, `import.meta.url` + the tag-to-path rule resolves `<mc-app>` to `src/mc/app.js` — the compiled starter. `--dir` defaults to the namespace, `--dry-run` prints the plan without touching disk.
|
|
89
89
|
|
|
90
|
+
The project is written into a folder of its own, so its files are reported under that folder (`mc-app/src/mc/app.ts`) — the path you can find from the directory you ran the command in, not relative to the project root.
|
|
91
|
+
|
|
92
|
+
Existing files are never overwritten silently: every target is checked before the first write, so a rerun in a populated directory lists the conflicts and touches nothing. `--force` opts into overwriting:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pnpm run cli -- create --namespace mc
|
|
96
|
+
# refusing to overwrite 10 existing file(s):
|
|
97
|
+
# mc/package.json
|
|
98
|
+
# mc/src/mc/app.ts
|
|
99
|
+
# ...
|
|
100
|
+
#
|
|
101
|
+
# rerun with --force to overwrite
|
|
102
|
+
```
|
|
103
|
+
|
|
90
104
|
Once installed from npm the same command is available as `mc`:
|
|
91
105
|
|
|
92
106
|
```bash
|
|
93
|
-
mc new my-card [--css] [--html] [--target-html] [--shadow-html] [--target-css] [--shadow-css] [--js] [--dir <path>] [--dry-run]
|
|
94
|
-
mc create --namespace <ns> [--dir <path>] [--dry-run]
|
|
107
|
+
mc new my-card [--css] [--html] [--target-html] [--shadow-html] [--target-css] [--shadow-css] [--js] [--dir <path>] [--force] [--dry-run]
|
|
108
|
+
mc create --namespace <ns> [--dir <path>] [--force] [--dry-run]
|
|
95
109
|
mc clean
|
|
96
110
|
mc check
|
|
97
111
|
```
|
package/dist/cli/create.js
CHANGED
|
@@ -81,7 +81,7 @@ function packageJson(namespace) {
|
|
|
81
81
|
typecheck: 'tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.vc.json',
|
|
82
82
|
},
|
|
83
83
|
dependencies: {
|
|
84
|
-
'@twobirds/microcomponents': '^0.4.
|
|
84
|
+
'@twobirds/microcomponents': '^0.4.1',
|
|
85
85
|
},
|
|
86
86
|
devDependencies: {
|
|
87
87
|
vite: '^8.1.5',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;EAYE;
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;EAYE;AAsDF,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAqGzD;;;;;;;;;;;;EAYE;AACF,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAED;;;;;;;;;;;;EAYE;AACF,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,MAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwGnF"}
|
package/dist/cli/dispatch.js
CHANGED
|
@@ -16,14 +16,14 @@ import { parseArgs } from 'node:util';
|
|
|
16
16
|
import { readFile, rm } from 'node:fs/promises';
|
|
17
17
|
import { existsSync } from 'node:fs';
|
|
18
18
|
import path from 'node:path';
|
|
19
|
-
import { writeScaffold, writeProject } from './writeScaffold.js';
|
|
19
|
+
import { writeScaffold, writeProject, displayPath } from './writeScaffold.js';
|
|
20
20
|
import { scaffoldComponent } from './scaffold.js';
|
|
21
21
|
import { scaffoldProject } from './create.js';
|
|
22
22
|
const USAGE = `mc — Micro Components build tools
|
|
23
23
|
|
|
24
24
|
Usage:
|
|
25
|
-
mc new <tag> [--css] [--html] [--target-html] [--shadow-html] [--target-css] [--shadow-css] [--js] [--dir <path>] [--dry-run]
|
|
26
|
-
mc create --namespace <ns> [--dir <path>] [--dry-run]
|
|
25
|
+
mc new <tag> [--css] [--html] [--target-html] [--shadow-html] [--target-css] [--shadow-css] [--js] [--dir <path>] [--force] [--dry-run]
|
|
26
|
+
mc create --namespace <ns> [--dir <path>] [--force] [--dry-run]
|
|
27
27
|
mc clean
|
|
28
28
|
mc check
|
|
29
29
|
|
|
@@ -44,7 +44,12 @@ Companion assets:
|
|
|
44
44
|
Other options:
|
|
45
45
|
--js emit plain JavaScript instead of TypeScript
|
|
46
46
|
--dir <path> scaffold root (default: src)
|
|
47
|
+
--force overwrite files that already exist
|
|
47
48
|
--dry-run print what would be written; touch nothing on disk
|
|
49
|
+
|
|
50
|
+
Created paths are printed as they appear from the current directory. mc create writes
|
|
51
|
+
a whole project into a folder of its own (default: the namespace), so its files show
|
|
52
|
+
up under that folder, e.g. mc-app/src/mc/app.ts.
|
|
48
53
|
`;
|
|
49
54
|
// Map CLI flags to the runtime's camelCase asset descriptors.
|
|
50
55
|
const ASSET_FLAGS = {
|
|
@@ -56,6 +61,23 @@ const ASSET_FLAGS = {
|
|
|
56
61
|
'shadow-css': 'shadowCss',
|
|
57
62
|
};
|
|
58
63
|
/**
|
|
64
|
+
A scaffolded file as it appears from the current directory: the file `rel` under
|
|
65
|
+
`root`, resolved and made readable. `mc create` writes a project into a folder of
|
|
66
|
+
its own, so `src/mc/app.ts` under `mc-app` prints as `mc-app/src/mc/app.ts` — the
|
|
67
|
+
path the user can find with `ls`.
|
|
68
|
+
|
|
69
|
+
@example
|
|
70
|
+
```ts
|
|
71
|
+
createdPath('mc-app', 'src/mc/app.ts');
|
|
72
|
+
createdPath('src', 'my/card.ts');
|
|
73
|
+
```
|
|
74
|
+
@param root - Scaffold root the file is written under.
|
|
75
|
+
@param rel - Path of the file relative to `root`.
|
|
76
|
+
*/
|
|
77
|
+
function createdPath(root, rel) {
|
|
78
|
+
return displayPath(path.resolve(root, rel));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
59
81
|
Spawns a command and resolves with its exit code.
|
|
60
82
|
|
|
61
83
|
@example
|
|
@@ -181,6 +203,7 @@ export async function main(argv, run = runScript) {
|
|
|
181
203
|
js: { type: 'boolean' },
|
|
182
204
|
dir: { type: 'string' },
|
|
183
205
|
namespace: { type: 'string' },
|
|
206
|
+
force: { type: 'boolean' },
|
|
184
207
|
'dry-run': { type: 'boolean' },
|
|
185
208
|
help: { type: 'boolean', short: 'h' },
|
|
186
209
|
},
|
|
@@ -204,16 +227,22 @@ export async function main(argv, run = runScript) {
|
|
|
204
227
|
}
|
|
205
228
|
if (values['dry-run']) {
|
|
206
229
|
const { files } = scaffoldComponent(tag, { assets, js: values.js });
|
|
207
|
-
|
|
208
|
-
|
|
230
|
+
const root = values.dir ?? 'src';
|
|
231
|
+
for (const rel of Object.keys(files).sort())
|
|
232
|
+
console.log(`would create ${createdPath(root, rel)}`);
|
|
209
233
|
return 0;
|
|
210
234
|
}
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
235
|
+
const root = values.dir ?? 'src';
|
|
236
|
+
let written;
|
|
237
|
+
try {
|
|
238
|
+
written = await writeScaffold(tag, root, { assets, js: values.js, force: values.force });
|
|
239
|
+
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
console.error(e.message);
|
|
242
|
+
return 1;
|
|
243
|
+
}
|
|
244
|
+
for (const rel of written)
|
|
245
|
+
console.log(`created ${createdPath(root, rel)}`);
|
|
217
246
|
return 0;
|
|
218
247
|
}
|
|
219
248
|
if (command === 'create') {
|
|
@@ -232,13 +261,20 @@ export async function main(argv, run = runScript) {
|
|
|
232
261
|
return 1;
|
|
233
262
|
}
|
|
234
263
|
if (values['dry-run']) {
|
|
235
|
-
for (const
|
|
236
|
-
console.log(`would create ${
|
|
264
|
+
for (const rel of Object.keys(files).sort())
|
|
265
|
+
console.log(`would create ${createdPath(root, rel)}`);
|
|
237
266
|
return 0;
|
|
238
267
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
268
|
+
let written;
|
|
269
|
+
try {
|
|
270
|
+
written = await writeProject(namespace, root, { force: values.force });
|
|
271
|
+
}
|
|
272
|
+
catch (e) {
|
|
273
|
+
console.error(e.message);
|
|
274
|
+
return 1;
|
|
275
|
+
}
|
|
276
|
+
for (const rel of written)
|
|
277
|
+
console.log(`created ${createdPath(root, rel)}`);
|
|
242
278
|
console.log(`\nproject "${namespace}" created in ${root}/ — run: cd ${root} && pnpm install && pnpm dev`);
|
|
243
279
|
return 0;
|
|
244
280
|
}
|
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
Filesystem side of {@link scaffoldComponent}: writes the
|
|
3
|
-
root directory, creating nested folders as needed.
|
|
2
|
+
Filesystem side of {@link scaffoldComponent} and {@link scaffoldProject}: writes the
|
|
3
|
+
generated files under a root directory, creating nested folders as needed.
|
|
4
|
+
|
|
5
|
+
Existing files are never overwritten silently: every target is checked before the
|
|
6
|
+
first write, so a rerun in a populated directory reports the conflicts and touches
|
|
7
|
+
nothing. `force` opts into overwriting.
|
|
4
8
|
|
|
5
9
|
@module CLI/Scaffold
|
|
6
10
|
*/
|
|
7
11
|
import { type ScaffoldOptions } from './scaffold.js';
|
|
12
|
+
/** Whether files that already exist may be overwritten. */
|
|
13
|
+
export interface WriteOptions {
|
|
14
|
+
force?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
The path of a target file as it appears from the current working directory.
|
|
18
|
+
`mc create` writes a project into a folder of its own, so a path relative to the
|
|
19
|
+
project root cannot be found from the directory the command ran in: this turns
|
|
20
|
+
`src/mc/app.ts` under `mc-app/` into `mc-app/src/mc/app.ts`. Falls back to the
|
|
21
|
+
absolute path when the target lies outside the current directory, so the log never
|
|
22
|
+
prints `../../..` chains.
|
|
23
|
+
|
|
24
|
+
@example
|
|
25
|
+
```ts
|
|
26
|
+
// in a directory containing mc-app/src/mc/app.ts
|
|
27
|
+
displayPath(path.resolve('mc-app', 'src/mc/app.ts'));
|
|
28
|
+
displayPath('/tmp/mc-app/package.json');
|
|
29
|
+
```
|
|
30
|
+
@param abs - Absolute path of the target file.
|
|
31
|
+
@group CLI
|
|
32
|
+
*/
|
|
33
|
+
export declare function displayPath(abs: string): string;
|
|
8
34
|
/**
|
|
9
35
|
Scaffolds a component onto disk under `root`.
|
|
10
36
|
|
|
@@ -15,10 +41,11 @@ console.log(written);
|
|
|
15
41
|
```
|
|
16
42
|
@param tag - Kebab-case component tag.
|
|
17
43
|
@param root - Directory to scaffold under (e.g. `src`).
|
|
18
|
-
@param options - Which companion files to emit.
|
|
44
|
+
@param options - Which companion files to emit, and whether to overwrite existing ones.
|
|
19
45
|
@returns The written file paths, relative to `root`.
|
|
46
|
+
@throws If a target file exists and `force` is false.
|
|
20
47
|
*/
|
|
21
|
-
export declare function writeScaffold(tag: string, root: string, options?: ScaffoldOptions): Promise<string[]>;
|
|
48
|
+
export declare function writeScaffold(tag: string, root: string, options?: ScaffoldOptions & WriteOptions): Promise<string[]>;
|
|
22
49
|
/**
|
|
23
50
|
Filesystem side of {@link scaffoldProject}: writes a complete dev environment for a
|
|
24
51
|
namespace under a project root, creating nested folders as needed.
|
|
@@ -30,8 +57,10 @@ console.log(written);
|
|
|
30
57
|
```
|
|
31
58
|
@param namespace - 1 to 4 lowercase letters.
|
|
32
59
|
@param root - Directory to create the project in (e.g. `mc-app`).
|
|
60
|
+
@param options - Whether to overwrite existing files.
|
|
33
61
|
@returns The written file paths, relative to `root`.
|
|
34
|
-
@throws If `namespace` is not 1 to 4 lowercase letters
|
|
62
|
+
@throws If `namespace` is not 1 to 4 lowercase letters, or a target file exists and
|
|
63
|
+
`force` is false.
|
|
35
64
|
*/
|
|
36
|
-
export declare function writeProject(namespace: string, root: string): Promise<string[]>;
|
|
65
|
+
export declare function writeProject(namespace: string, root: string, options?: WriteOptions): Promise<string[]>;
|
|
37
66
|
//# sourceMappingURL=writeScaffold.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeScaffold.d.ts","sourceRoot":"","sources":["../../src/cli/writeScaffold.ts"],"names":[],"mappings":"AACA
|
|
1
|
+
{"version":3,"file":"writeScaffold.d.ts","sourceRoot":"","sources":["../../src/cli/writeScaffold.ts"],"names":[],"mappings":"AACA;;;;;;;;;EASE;AAKF,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGxE,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAE5B,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;EAgBE;AACF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG/C;AAmDD;;;;;;;;;;;;;EAaE;AACF,wBAAsB,aAAa,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,eAAe,GAAG,YAAiB,GAC1C,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB;AAED;;;;;;;;;;;;;;;EAeE;AACF,wBAAsB,YAAY,CACjC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,YAAiB,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB"}
|
|
@@ -1,32 +1,73 @@
|
|
|
1
1
|
// oxlint-disable no-await-in-loop
|
|
2
2
|
/**
|
|
3
|
-
Filesystem side of {@link scaffoldComponent}: writes the
|
|
4
|
-
root directory, creating nested folders as needed.
|
|
3
|
+
Filesystem side of {@link scaffoldComponent} and {@link scaffoldProject}: writes the
|
|
4
|
+
generated files under a root directory, creating nested folders as needed.
|
|
5
|
+
|
|
6
|
+
Existing files are never overwritten silently: every target is checked before the
|
|
7
|
+
first write, so a rerun in a populated directory reports the conflicts and touches
|
|
8
|
+
nothing. `force` opts into overwriting.
|
|
5
9
|
|
|
6
10
|
@module CLI/Scaffold
|
|
7
11
|
*/
|
|
12
|
+
import { existsSync } from 'node:fs';
|
|
8
13
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
9
14
|
import path from 'node:path';
|
|
10
15
|
import { scaffoldComponent } from './scaffold.js';
|
|
11
16
|
import { scaffoldProject } from './create.js';
|
|
12
17
|
/**
|
|
13
|
-
|
|
18
|
+
The path of a target file as it appears from the current working directory.
|
|
19
|
+
`mc create` writes a project into a folder of its own, so a path relative to the
|
|
20
|
+
project root cannot be found from the directory the command ran in: this turns
|
|
21
|
+
`src/mc/app.ts` under `mc-app/` into `mc-app/src/mc/app.ts`. Falls back to the
|
|
22
|
+
absolute path when the target lies outside the current directory, so the log never
|
|
23
|
+
prints `../../..` chains.
|
|
14
24
|
|
|
15
25
|
@example
|
|
16
26
|
```ts
|
|
17
|
-
|
|
27
|
+
// in a directory containing mc-app/src/mc/app.ts
|
|
28
|
+
displayPath(path.resolve('mc-app', 'src/mc/app.ts'));
|
|
29
|
+
displayPath('/tmp/mc-app/package.json');
|
|
30
|
+
```
|
|
31
|
+
@param abs - Absolute path of the target file.
|
|
32
|
+
@group CLI
|
|
33
|
+
*/
|
|
34
|
+
export function displayPath(abs) {
|
|
35
|
+
const rel = path.relative(process.cwd(), abs);
|
|
36
|
+
return rel.startsWith('..') ? abs : rel;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
Writes generated files under `root`, creating nested folders as needed, and reports
|
|
40
|
+
the written paths relative to `root`.
|
|
41
|
+
|
|
42
|
+
@example
|
|
43
|
+
```ts
|
|
44
|
+
const written = await writeGenerated({ 'my/card.ts': 'source' }, 'src', false);
|
|
18
45
|
console.log(written);
|
|
19
46
|
```
|
|
20
|
-
@param
|
|
21
|
-
@param root - Directory to
|
|
22
|
-
@param
|
|
47
|
+
@param files - Files to write, keyed by path relative to `root`.
|
|
48
|
+
@param root - Directory to write under (`src` for a component, `mc-app` for a project).
|
|
49
|
+
@param force - Overwrite files that already exist.
|
|
23
50
|
@returns The written file paths, relative to `root`.
|
|
51
|
+
@throws If any target file exists and `force` is false. Nothing is written in that case.
|
|
24
52
|
*/
|
|
25
|
-
|
|
26
|
-
const
|
|
53
|
+
async function writeGenerated(files, root, force) {
|
|
54
|
+
const targets = Object.entries(files).map(([rel, contents]) => ({
|
|
55
|
+
rel,
|
|
56
|
+
abs: path.resolve(root, rel),
|
|
57
|
+
contents,
|
|
58
|
+
}));
|
|
59
|
+
if (!force) {
|
|
60
|
+
const conflicts = targets
|
|
61
|
+
.filter((target) => existsSync(target.abs))
|
|
62
|
+
.map((t) => displayPath(t.abs));
|
|
63
|
+
if (conflicts.length) {
|
|
64
|
+
throw new Error(`refusing to overwrite ${conflicts.length} existing file(s):\n${conflicts
|
|
65
|
+
.map((file) => `\t${file}`)
|
|
66
|
+
.join('\n')}\n\nrerun with --force to overwrite`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
27
69
|
const written = [];
|
|
28
|
-
for (const
|
|
29
|
-
const abs = path.join(root, rel);
|
|
70
|
+
for (const { rel, abs, contents } of targets) {
|
|
30
71
|
await mkdir(path.dirname(abs), { recursive: true });
|
|
31
72
|
await writeFile(abs, contents, 'utf8');
|
|
32
73
|
written.push(rel);
|
|
@@ -34,6 +75,24 @@ export async function writeScaffold(tag, root, options = {}) {
|
|
|
34
75
|
return written;
|
|
35
76
|
}
|
|
36
77
|
/**
|
|
78
|
+
Scaffolds a component onto disk under `root`.
|
|
79
|
+
|
|
80
|
+
@example
|
|
81
|
+
```ts
|
|
82
|
+
const written = await writeScaffold('my-card', 'src', { assets: ['css'] });
|
|
83
|
+
console.log(written);
|
|
84
|
+
```
|
|
85
|
+
@param tag - Kebab-case component tag.
|
|
86
|
+
@param root - Directory to scaffold under (e.g. `src`).
|
|
87
|
+
@param options - Which companion files to emit, and whether to overwrite existing ones.
|
|
88
|
+
@returns The written file paths, relative to `root`.
|
|
89
|
+
@throws If a target file exists and `force` is false.
|
|
90
|
+
*/
|
|
91
|
+
export async function writeScaffold(tag, root, options = {}) {
|
|
92
|
+
const { files } = scaffoldComponent(tag, options);
|
|
93
|
+
return writeGenerated(files, root, options.force ?? false);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
37
96
|
Filesystem side of {@link scaffoldProject}: writes a complete dev environment for a
|
|
38
97
|
namespace under a project root, creating nested folders as needed.
|
|
39
98
|
|
|
@@ -44,17 +103,12 @@ console.log(written);
|
|
|
44
103
|
```
|
|
45
104
|
@param namespace - 1 to 4 lowercase letters.
|
|
46
105
|
@param root - Directory to create the project in (e.g. `mc-app`).
|
|
106
|
+
@param options - Whether to overwrite existing files.
|
|
47
107
|
@returns The written file paths, relative to `root`.
|
|
48
|
-
@throws If `namespace` is not 1 to 4 lowercase letters
|
|
108
|
+
@throws If `namespace` is not 1 to 4 lowercase letters, or a target file exists and
|
|
109
|
+
`force` is false.
|
|
49
110
|
*/
|
|
50
|
-
export async function writeProject(namespace, root) {
|
|
111
|
+
export async function writeProject(namespace, root, options = {}) {
|
|
51
112
|
const { files } = scaffoldProject(namespace);
|
|
52
|
-
|
|
53
|
-
for (const [rel, contents] of Object.entries(files)) {
|
|
54
|
-
const abs = path.join(root, rel);
|
|
55
|
-
await mkdir(path.dirname(abs), { recursive: true });
|
|
56
|
-
await writeFile(abs, contents, 'utf8');
|
|
57
|
-
written.push(rel);
|
|
58
|
-
}
|
|
59
|
-
return written;
|
|
113
|
+
return writeGenerated(files, root, options.force ?? false);
|
|
60
114
|
}
|