@travetto/scaffold 2.1.2 → 2.2.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/bin/cli-scaffold.ts +22 -11
- package/bin/lib/context.ts +16 -15
- package/package.json +3 -3
- package/templates/todo/eslintrc.json +36 -2
package/bin/cli-scaffold.ts
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import * as enquirer from 'enquirer';
|
|
2
2
|
|
|
3
3
|
import { PathUtil, EnvUtil } from '@travetto/boot';
|
|
4
|
-
import { BasePlugin } from '@travetto/cli/src/plugin-base';
|
|
4
|
+
import { BasePlugin, OptionConfig } from '@travetto/cli/src/plugin-base';
|
|
5
5
|
|
|
6
6
|
import { Context } from './lib/context';
|
|
7
7
|
import { Feature, FEATURES } from './lib/features';
|
|
8
8
|
|
|
9
|
+
type Options = {
|
|
10
|
+
template: OptionConfig<string>;
|
|
11
|
+
dir: OptionConfig<string>;
|
|
12
|
+
force: OptionConfig<boolean>;
|
|
13
|
+
};
|
|
14
|
+
|
|
9
15
|
/**
|
|
10
16
|
* Plugin to run scaffolding
|
|
11
17
|
*/
|
|
12
|
-
export class ScaffoldPlugin extends BasePlugin {
|
|
18
|
+
export class ScaffoldPlugin extends BasePlugin<Options> {
|
|
13
19
|
name = 'scaffold';
|
|
14
20
|
|
|
15
|
-
getOptions() {
|
|
21
|
+
getOptions(): Options {
|
|
16
22
|
return {
|
|
17
23
|
template: this.option({ def: 'todo', desc: 'Template' }),
|
|
18
24
|
dir: this.option({ desc: 'Target Directory' }),
|
|
@@ -20,11 +26,11 @@ export class ScaffoldPlugin extends BasePlugin {
|
|
|
20
26
|
};
|
|
21
27
|
}
|
|
22
28
|
|
|
23
|
-
getArgs() {
|
|
29
|
+
getArgs(): string {
|
|
24
30
|
return '[name]';
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
async #getName(name?: string) {
|
|
33
|
+
async #getName(name?: string): Promise<string> {
|
|
28
34
|
if (!name) {
|
|
29
35
|
const res = await enquirer.prompt<{ name: string }>([
|
|
30
36
|
{
|
|
@@ -39,14 +45,15 @@ export class ScaffoldPlugin extends BasePlugin {
|
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
async #chooseFeature(feature: Feature): Promise<Feature | undefined> {
|
|
42
|
-
const
|
|
48
|
+
const choice: (Parameters<typeof enquirer['prompt']>[0] & { type: 'select' }) = {
|
|
43
49
|
type: 'select' as const,
|
|
44
50
|
name: 'choice',
|
|
45
51
|
message: 'Please select one',
|
|
46
52
|
initial: feature.default,
|
|
47
|
-
choices: feature.choices!.map(x => x.title),
|
|
48
|
-
}
|
|
53
|
+
choices: feature.choices!.map(x => x.title).filter((x?: string): x is string => !!x),
|
|
54
|
+
};
|
|
49
55
|
|
|
56
|
+
const res = await enquirer.prompt<{ choice: string }>(choice);
|
|
50
57
|
return feature.choices?.find(x => x.title === res.choice);
|
|
51
58
|
}
|
|
52
59
|
|
|
@@ -79,11 +86,13 @@ export class ScaffoldPlugin extends BasePlugin {
|
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
88
|
|
|
82
|
-
async action(name?: string) {
|
|
89
|
+
async action(name?: string): Promise<void> {
|
|
83
90
|
try {
|
|
84
91
|
name = await this.#getName(name);
|
|
85
92
|
} catch (err) {
|
|
86
|
-
|
|
93
|
+
if (err instanceof Error) {
|
|
94
|
+
console.error('Failed to provide correct input', err.message);
|
|
95
|
+
}
|
|
87
96
|
process.exit(1);
|
|
88
97
|
}
|
|
89
98
|
|
|
@@ -100,7 +109,9 @@ export class ScaffoldPlugin extends BasePlugin {
|
|
|
100
109
|
await ctx.addDependency(dep);
|
|
101
110
|
}
|
|
102
111
|
} catch (err) {
|
|
103
|
-
|
|
112
|
+
if (err instanceof Error) {
|
|
113
|
+
console.error('Failed to provide correct input', err.message);
|
|
114
|
+
}
|
|
104
115
|
process.exit(1);
|
|
105
116
|
}
|
|
106
117
|
|
package/bin/lib/context.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as path from 'path';
|
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import * as mustache from 'mustache';
|
|
4
4
|
|
|
5
|
-
import { EnvUtil, ExecUtil, FsUtil, PathUtil } from '@travetto/boot';
|
|
5
|
+
import { EnvUtil, ExecUtil, ExecutionResult, FsUtil, PathUtil } from '@travetto/boot';
|
|
6
6
|
import { version } from '@travetto/boot/package.json';
|
|
7
7
|
|
|
8
8
|
import { Feature } from './features';
|
|
@@ -12,7 +12,7 @@ type Listing = Record<string, ListingEntry>;
|
|
|
12
12
|
|
|
13
13
|
export class Context {
|
|
14
14
|
|
|
15
|
-
static #meetsRequirement(modules: string[], desired: string[]) {
|
|
15
|
+
static #meetsRequirement(modules: string[], desired: string[]): boolean {
|
|
16
16
|
let valid = true;
|
|
17
17
|
for (const mod of desired) {
|
|
18
18
|
if (mod.endsWith('-')) {
|
|
@@ -46,43 +46,44 @@ export class Context {
|
|
|
46
46
|
this.#targetDir = PathUtil.resolveUnix(targetDir);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
get modules() {
|
|
49
|
+
get modules(): Record<string, boolean> {
|
|
50
50
|
if (!this.#modules) {
|
|
51
51
|
this.#modules = this.#frameworkDependencies.map(x => x.split('/')).reduce((acc, [, v]) => ({ ...acc, [v]: true }), {});
|
|
52
52
|
}
|
|
53
53
|
return this.#modules;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
get frameworkDependencies() {
|
|
56
|
+
get frameworkDependencies(): string[] {
|
|
57
57
|
return this.#frameworkDependencies;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
get peerDependencies() {
|
|
60
|
+
get peerDependencies(): string[] {
|
|
61
61
|
return this.#peerDependencies;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
get moduleNames() {
|
|
64
|
+
get moduleNames(): string[] {
|
|
65
65
|
return [...Object.keys(this.modules)].filter(x => !x.includes('-'));
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
source(file?: string) {
|
|
68
|
+
source(file?: string): string {
|
|
69
69
|
return PathUtil.resolveUnix(__dirname, '..', '..', 'templates', this.#template, ...file ? [file] : []);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
destination(file?: string) {
|
|
72
|
+
destination(file?: string): string {
|
|
73
73
|
return PathUtil.resolveUnix(this.#targetDir, ...file ? [file] : []);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
get sourceListing() {
|
|
76
|
+
get sourceListing(): Promise<Listing> {
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
77
78
|
return import(this.source('listing.json')) as Promise<Listing>;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
async resolvedSourceListing() {
|
|
81
|
+
async resolvedSourceListing(): Promise<[string, ListingEntry][]> {
|
|
81
82
|
return Object.entries(await this.sourceListing)
|
|
82
83
|
.filter(([, conf]) => !conf.requires || Context.#meetsRequirement(this.#frameworkDependencies, conf.requires));
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
async initialize() {
|
|
86
|
+
async initialize(): Promise<void> {
|
|
86
87
|
let base = this.destination();
|
|
87
88
|
while (base) {
|
|
88
89
|
if (await FsUtil.exists(`${base}/package.json`)) {
|
|
@@ -96,7 +97,7 @@ export class Context {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
async template(file: string, { rename }: ListingEntry) {
|
|
100
|
+
async template(file: string, { rename }: ListingEntry): Promise<void> {
|
|
100
101
|
const contents = await fs.readFile(this.source(file), 'utf-8');
|
|
101
102
|
const out = this.destination(rename ?? file);
|
|
102
103
|
const rendered = mustache.render(contents, this).replace(/^\s*(\/\/|#)\s*\n/gsm, '');
|
|
@@ -104,13 +105,13 @@ export class Context {
|
|
|
104
105
|
await fs.writeFile(out, rendered, 'utf8');
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
async templateResolvedFiles() {
|
|
108
|
+
async templateResolvedFiles(): Promise<void> {
|
|
108
109
|
for (const [key, config] of await this.resolvedSourceListing()) {
|
|
109
110
|
await this.template(key, config);
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
async addDependency(feat: Feature) {
|
|
114
|
+
async addDependency(feat: Feature): Promise<void> {
|
|
114
115
|
if (feat.npm.startsWith('@travetto')) {
|
|
115
116
|
this.#frameworkDependencies.push(feat.npm);
|
|
116
117
|
} else {
|
|
@@ -122,7 +123,7 @@ export class Context {
|
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
exec(cmd: string, args: string[]) {
|
|
126
|
+
exec(cmd: string, args: string[]): Promise<ExecutionResult> {
|
|
126
127
|
return ExecUtil.spawn(cmd, args, { cwd: this.destination(), stdio: [0, 1, 2], isolatedEnv: true }).result;
|
|
127
128
|
}
|
|
128
129
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/scaffold",
|
|
3
3
|
"displayName": "App Scaffold",
|
|
4
|
-
"version": "2.1
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"description": "App Scaffold for the Travetto framework",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"generator",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"trv-scaffold": "./bin/trv-scaffold.js"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@travetto/boot": "^2.1
|
|
36
|
-
"@travetto/cli": "^2.1
|
|
35
|
+
"@travetto/boot": "^2.2.1",
|
|
36
|
+
"@travetto/cli": "^2.2.1",
|
|
37
37
|
"mustache": "^4.2.0",
|
|
38
38
|
"enquirer": "^2.3.6"
|
|
39
39
|
},
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
],
|
|
25
25
|
"rules": {
|
|
26
26
|
"@typescript-eslint/array-type": "error",
|
|
27
|
-
"@typescript-eslint/explicit-function-return-type":
|
|
27
|
+
"@typescript-eslint/explicit-function-return-type": [
|
|
28
|
+
"off"
|
|
29
|
+
],
|
|
28
30
|
"@typescript-eslint/no-non-null-assertion": "off",
|
|
29
31
|
"@typescript-eslint/no-explicit-any": "warn",
|
|
30
32
|
"@typescript-eslint/explicit-member-accessibility": [
|
|
@@ -39,10 +41,14 @@
|
|
|
39
41
|
2,
|
|
40
42
|
{
|
|
41
43
|
"ignoredNodes": [
|
|
44
|
+
"PropertyDefinition[decorators]",
|
|
45
|
+
"TSUnionType",
|
|
46
|
+
"TSTypeParameterInstantiation",
|
|
42
47
|
"FunctionExpression > .params[decorators.length > 0]",
|
|
43
48
|
"FunctionExpression > .params > :matches(Decorator, :not(:first-child))",
|
|
44
49
|
"ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"
|
|
45
|
-
]
|
|
50
|
+
],
|
|
51
|
+
"SwitchCase": 1
|
|
46
52
|
}
|
|
47
53
|
],
|
|
48
54
|
"@typescript-eslint/member-delimiter-style": [
|
|
@@ -209,6 +215,28 @@
|
|
|
209
215
|
"PascalCase",
|
|
210
216
|
"camelCase"
|
|
211
217
|
]
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"selector": "objectLiteralProperty",
|
|
221
|
+
"modifiers": [
|
|
222
|
+
"requiresQuotes"
|
|
223
|
+
],
|
|
224
|
+
"format": null,
|
|
225
|
+
"custom": {
|
|
226
|
+
"regex": ".*",
|
|
227
|
+
"match": true
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"selector": "objectLiteralMethod",
|
|
232
|
+
"modifiers": [
|
|
233
|
+
"requiresQuotes"
|
|
234
|
+
],
|
|
235
|
+
"format": null,
|
|
236
|
+
"custom": {
|
|
237
|
+
"regex": ".*",
|
|
238
|
+
"match": true
|
|
239
|
+
}
|
|
212
240
|
}
|
|
213
241
|
],
|
|
214
242
|
"curly": "error",
|
|
@@ -297,6 +325,12 @@
|
|
|
297
325
|
]
|
|
298
326
|
}
|
|
299
327
|
}
|
|
328
|
+
],
|
|
329
|
+
"@typescript-eslint/consistent-type-assertions": [
|
|
330
|
+
"warn",
|
|
331
|
+
{
|
|
332
|
+
"assertionStyle": "never"
|
|
333
|
+
}
|
|
300
334
|
]
|
|
301
335
|
},
|
|
302
336
|
"overrides": [
|