create-lwr 0.6.0 → 0.6.4
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/build/es/index.js +49 -122
- package/build/es/types.d.ts +26 -0
- package/build/es/types.js +2 -0
- package/build/es/utils.d.ts +8 -4
- package/build/es/utils.js +129 -5
- package/package.json +3 -3
- package/template-lwc/package.json +1 -1
- package/template-lwc-ts/package.json +1 -1
- package/template-markdown-static-site/package.json +1 -1
package/build/es/index.js
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import minimist from 'minimist';
|
|
5
|
-
import {
|
|
6
|
-
import prompts from 'prompts';
|
|
7
|
-
import { isEmpty, isValidPackageName, toValidPackageName, emptyDir, copy, pkgFromUserAgent, } from './utils.js';
|
|
5
|
+
import { emptyDir, copy, pkgFromUserAgent, promptForAnswers, updateLwrVersion } from './utils.js';
|
|
8
6
|
import { dirname } from 'path';
|
|
9
7
|
import { fileURLToPath } from 'url';
|
|
10
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -13,144 +11,73 @@ const argv = minimist(process.argv.slice(2), { string: ['_'] });
|
|
|
13
11
|
const renameFiles = {
|
|
14
12
|
_gitignore: '.gitignore',
|
|
15
13
|
};
|
|
16
|
-
const PROJECTS = [
|
|
17
|
-
{
|
|
18
|
-
name: 'Static Site',
|
|
19
|
-
color: green,
|
|
20
|
-
variants: [
|
|
21
|
-
{
|
|
22
|
-
name: 'markdown-static-site',
|
|
23
|
-
display: 'Markdown Static Site',
|
|
24
|
-
color: green,
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
name: 'Single Page App',
|
|
30
|
-
color: green,
|
|
31
|
-
variants: [
|
|
32
|
-
{
|
|
33
|
-
name: 'lwc',
|
|
34
|
-
display: 'LWC',
|
|
35
|
-
color: green,
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
name: 'lwc-ts',
|
|
39
|
-
display: 'LWC (TypeScript)',
|
|
40
|
-
color: blue,
|
|
41
|
-
},
|
|
42
|
-
],
|
|
43
|
-
},
|
|
44
|
-
];
|
|
45
|
-
const TEMPLATES = PROJECTS.map((f) => (f.variants && f.variants.map((v) => v.name)) || [f.name]).reduce((a, b) => a.concat(b), []);
|
|
46
14
|
export async function init() {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
15
|
+
const targetDir = argv._[0];
|
|
16
|
+
const metadata = {
|
|
17
|
+
targetDir,
|
|
18
|
+
template: argv.template || argv.t,
|
|
19
|
+
defaultProjectName: !targetDir ? 'lwr-project' : targetDir,
|
|
20
|
+
};
|
|
21
|
+
let userFeedback = {};
|
|
51
22
|
try {
|
|
52
|
-
|
|
53
|
-
{
|
|
54
|
-
type: targetDir ? null : 'text',
|
|
55
|
-
name: 'projectName',
|
|
56
|
-
message: 'Project name:',
|
|
57
|
-
initial: defaultProjectName,
|
|
58
|
-
onState: (state) => (targetDir = state.value.trim() || defaultProjectName),
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
type: () => (!fs.existsSync(targetDir) || isEmpty(targetDir) ? null : 'confirm'),
|
|
62
|
-
name: 'overwrite',
|
|
63
|
-
message: () => (targetDir === '.' ? 'Current directory' : `Target directory "${targetDir}"`) +
|
|
64
|
-
` is not empty. Remove existing files and continue?`,
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
type: (_, { overwrite } = {}) => {
|
|
68
|
-
if (overwrite === false) {
|
|
69
|
-
throw new Error(red('✖') + ' Operation cancelled');
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
},
|
|
73
|
-
name: 'overwriteChecker',
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
type: () => (isValidPackageName(targetDir) ? null : 'text'),
|
|
77
|
-
name: 'packageName',
|
|
78
|
-
message: 'Package name:',
|
|
79
|
-
initial: () => toValidPackageName(targetDir),
|
|
80
|
-
validate: (dir) => isValidPackageName(dir) || 'Invalid package.json name',
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
type: template && TEMPLATES.includes(template) ? null : 'select',
|
|
84
|
-
name: 'projectType',
|
|
85
|
-
message: typeof template === 'string' && !TEMPLATES.includes(template)
|
|
86
|
-
? `"${template}" isn't a valid template. Please choose from below: `
|
|
87
|
-
: 'Select a type of project:',
|
|
88
|
-
initial: 0,
|
|
89
|
-
choices: PROJECTS.map((project_type) => {
|
|
90
|
-
const frameworkColor = project_type.color;
|
|
91
|
-
return {
|
|
92
|
-
title: frameworkColor(project_type.name),
|
|
93
|
-
value: project_type,
|
|
94
|
-
};
|
|
95
|
-
}),
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
type: (project_type) => project_type && project_type.variants ? 'select' : null,
|
|
99
|
-
name: 'variant',
|
|
100
|
-
message: 'Select a variant:',
|
|
101
|
-
choices: (project_type) => project_type.variants.map((variant) => {
|
|
102
|
-
const variantColor = variant.color;
|
|
103
|
-
return {
|
|
104
|
-
title: variantColor(variant.display || variant.name),
|
|
105
|
-
value: variant.name,
|
|
106
|
-
};
|
|
107
|
-
}),
|
|
108
|
-
},
|
|
109
|
-
], {
|
|
110
|
-
onCancel: () => {
|
|
111
|
-
throw new Error(red('✖') + ' Operation cancelled');
|
|
112
|
-
},
|
|
113
|
-
});
|
|
23
|
+
userFeedback = await promptForAnswers(metadata);
|
|
114
24
|
}
|
|
115
25
|
catch (cancelled) {
|
|
116
26
|
console.log(cancelled.message);
|
|
117
27
|
return;
|
|
118
28
|
}
|
|
119
|
-
|
|
120
|
-
const {
|
|
121
|
-
const
|
|
29
|
+
const { results: { overwrite, packageName, template }, } = userFeedback;
|
|
30
|
+
const { metadata: revisedMetadata } = userFeedback;
|
|
31
|
+
const projectRoot = path.join(cwd, revisedMetadata.targetDir);
|
|
32
|
+
createRootDir(projectRoot, revisedMetadata, overwrite, template);
|
|
33
|
+
const templateDir = path.join(__dirname, '../../', `template-${revisedMetadata.template}`);
|
|
34
|
+
writeFiles(projectRoot, templateDir);
|
|
35
|
+
const pkgManager = writePackageFile(projectRoot, templateDir, packageName, revisedMetadata);
|
|
36
|
+
logResult(projectRoot, pkgManager);
|
|
37
|
+
}
|
|
38
|
+
function createRootDir(projectRoot, metadata, overwrite, template) {
|
|
122
39
|
if (overwrite) {
|
|
123
|
-
emptyDir(
|
|
40
|
+
emptyDir(projectRoot);
|
|
124
41
|
}
|
|
125
|
-
else if (!fs.existsSync(
|
|
126
|
-
fs.mkdirSync(
|
|
42
|
+
else if (!fs.existsSync(projectRoot)) {
|
|
43
|
+
fs.mkdirSync(projectRoot, { recursive: true });
|
|
127
44
|
}
|
|
128
45
|
// determine template
|
|
129
|
-
template =
|
|
130
|
-
console.log(`\nScaffolding project in ${
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
46
|
+
metadata.template = template || metadata.template;
|
|
47
|
+
console.log(`\nScaffolding project in ${projectRoot}...`);
|
|
48
|
+
}
|
|
49
|
+
const write = (projectRoot, templateDir, file, content) => {
|
|
50
|
+
const targetPath = renameFiles[file]
|
|
51
|
+
? path.join(projectRoot, renameFiles[file])
|
|
52
|
+
: path.join(projectRoot, file);
|
|
53
|
+
if (content) {
|
|
54
|
+
fs.writeFileSync(targetPath, content);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
copy(path.join(templateDir, file), targetPath);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
function writeFiles(projectRoot, templateDir) {
|
|
141
61
|
const files = fs.readdirSync(templateDir);
|
|
142
62
|
for (const file of files.filter((f) => f !== 'package.json')) {
|
|
143
|
-
write(file);
|
|
63
|
+
write(projectRoot, templateDir, file);
|
|
144
64
|
}
|
|
65
|
+
}
|
|
66
|
+
function writePackageFile(projectRoot, templateDir, packageName, metadata) {
|
|
145
67
|
// modify package json name
|
|
146
68
|
const pkg = JSON.parse(fs.readFileSync(path.join(templateDir, `package.json`), 'utf-8'));
|
|
147
|
-
pkg.name = packageName || targetDir;
|
|
148
|
-
|
|
69
|
+
pkg.name = packageName || metadata.targetDir;
|
|
70
|
+
// Set the target lwr package version equal to this create-lwr package version
|
|
71
|
+
updateLwrVersion(templateDir, pkg);
|
|
72
|
+
write(projectRoot, templateDir, 'package.json', JSON.stringify(pkg, null, 2));
|
|
149
73
|
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent);
|
|
150
74
|
const pkgManager = pkgInfo ? pkgInfo.name : 'npm';
|
|
75
|
+
return pkgManager;
|
|
76
|
+
}
|
|
77
|
+
function logResult(projectRoot, pkgManager) {
|
|
151
78
|
console.log(`\nDone. Now run:\n`);
|
|
152
|
-
if (
|
|
153
|
-
console.log(` cd ${path.relative(cwd,
|
|
79
|
+
if (projectRoot !== cwd) {
|
|
80
|
+
console.log(` cd ${path.relative(cwd, projectRoot)}`);
|
|
154
81
|
}
|
|
155
82
|
switch (pkgManager) {
|
|
156
83
|
case 'yarn':
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface ProjectTemplate {
|
|
2
|
+
name: string;
|
|
3
|
+
display: string;
|
|
4
|
+
color: any;
|
|
5
|
+
}
|
|
6
|
+
export interface ProjectType {
|
|
7
|
+
name: string;
|
|
8
|
+
color: any;
|
|
9
|
+
templates: ProjectTemplate[];
|
|
10
|
+
}
|
|
11
|
+
export interface ProjectMetadata {
|
|
12
|
+
targetDir?: string;
|
|
13
|
+
template?: string;
|
|
14
|
+
defaultProjectName: string;
|
|
15
|
+
}
|
|
16
|
+
export declare type NormalizedProjectMetadata = Required<ProjectMetadata>;
|
|
17
|
+
export interface Answers {
|
|
18
|
+
overwrite: boolean;
|
|
19
|
+
packageName: string;
|
|
20
|
+
template: string;
|
|
21
|
+
}
|
|
22
|
+
export interface AnswersWithMetadata {
|
|
23
|
+
results: Answers;
|
|
24
|
+
metadata: NormalizedProjectMetadata;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
package/build/es/utils.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
export declare
|
|
3
|
-
export declare function toValidPackageName(projectName: string): string;
|
|
1
|
+
import { AnswersWithMetadata, ProjectType, ProjectMetadata } from './types';
|
|
2
|
+
export declare const PROJECTS: ProjectType[];
|
|
4
3
|
export declare function emptyDir(dir: string): void;
|
|
5
4
|
export declare function copy(src: string, dest: string): void;
|
|
6
|
-
export declare function copyDir(srcDir: string, destDir: string): void;
|
|
7
5
|
export declare function pkgFromUserAgent(userAgent: string | undefined): {
|
|
8
6
|
name: string;
|
|
9
7
|
version: string;
|
|
10
8
|
} | undefined;
|
|
9
|
+
export declare function updateLwrVersion(templateDir: string, pkg: {
|
|
10
|
+
dependencies?: {
|
|
11
|
+
lwr?: string;
|
|
12
|
+
};
|
|
13
|
+
}): void;
|
|
14
|
+
export declare function promptForAnswers(metadata: ProjectMetadata): Promise<AnswersWithMetadata>;
|
|
11
15
|
//# sourceMappingURL=utils.d.ts.map
|
package/build/es/utils.js
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
|
|
3
|
+
import { red, green, blue } from 'kolorist';
|
|
4
|
+
import prompts from 'prompts';
|
|
5
|
+
export const PROJECTS = [
|
|
6
|
+
{
|
|
7
|
+
name: 'Static Site',
|
|
8
|
+
color: green,
|
|
9
|
+
templates: [
|
|
10
|
+
{
|
|
11
|
+
name: 'markdown-static-site',
|
|
12
|
+
display: 'Markdown Static Site',
|
|
13
|
+
color: green,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Single Page App',
|
|
19
|
+
color: green,
|
|
20
|
+
templates: [
|
|
21
|
+
{
|
|
22
|
+
name: 'lwc',
|
|
23
|
+
display: 'LWC',
|
|
24
|
+
color: green,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'lwc-ts',
|
|
28
|
+
display: 'LWC (TypeScript)',
|
|
29
|
+
color: blue,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
const TEMPLATES = PROJECTS.map((t) => (t.templates && t.templates.map((t) => t.name)) || [t.name]).reduce((a, b) => a.concat(b), []);
|
|
35
|
+
function isDirEmpty(path) {
|
|
4
36
|
return fs.readdirSync(path).length === 0;
|
|
5
37
|
}
|
|
6
|
-
|
|
38
|
+
function isValidPackageName(projectName) {
|
|
7
39
|
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName);
|
|
8
40
|
}
|
|
9
|
-
|
|
41
|
+
function toValidPackageName(projectName) {
|
|
10
42
|
return projectName
|
|
11
43
|
.trim()
|
|
12
44
|
.toLowerCase()
|
|
@@ -14,15 +46,17 @@ export function toValidPackageName(projectName) {
|
|
|
14
46
|
.replace(/^[._]/, '')
|
|
15
47
|
.replace(/[^a-z0-9-~]+/g, '-');
|
|
16
48
|
}
|
|
49
|
+
// Recursively empty the given directory
|
|
17
50
|
export function emptyDir(dir) {
|
|
18
51
|
if (!fs.existsSync(dir)) {
|
|
19
52
|
return;
|
|
20
53
|
}
|
|
21
54
|
for (const file of fs.readdirSync(dir)) {
|
|
22
55
|
const abs = path.resolve(dir, file);
|
|
23
|
-
fs.rmSync(abs);
|
|
56
|
+
fs.rmSync(abs, { recursive: true, force: true });
|
|
24
57
|
}
|
|
25
58
|
}
|
|
59
|
+
// Copy a directory or file to a new destination
|
|
26
60
|
export function copy(src, dest) {
|
|
27
61
|
const stat = fs.statSync(src);
|
|
28
62
|
if (stat.isDirectory()) {
|
|
@@ -32,7 +66,8 @@ export function copy(src, dest) {
|
|
|
32
66
|
fs.copyFileSync(src, dest);
|
|
33
67
|
}
|
|
34
68
|
}
|
|
35
|
-
|
|
69
|
+
/* istanbul ignore next */
|
|
70
|
+
function copyDir(srcDir, destDir) {
|
|
36
71
|
fs.mkdirSync(destDir, { recursive: true });
|
|
37
72
|
for (const file of fs.readdirSync(srcDir)) {
|
|
38
73
|
const srcFile = path.resolve(srcDir, file);
|
|
@@ -50,4 +85,93 @@ export function pkgFromUserAgent(userAgent) {
|
|
|
50
85
|
version: pkgSpecArr[1],
|
|
51
86
|
};
|
|
52
87
|
}
|
|
88
|
+
export function updateLwrVersion(templateDir, pkg) {
|
|
89
|
+
const createLwrPkg = JSON.parse(fs.readFileSync(path.join(templateDir, `../package.json`), 'utf-8'));
|
|
90
|
+
const version = createLwrPkg.version;
|
|
91
|
+
if (!pkg.dependencies) {
|
|
92
|
+
pkg.dependencies = { lwr: version };
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
pkg.dependencies.lwr = version;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Gather project information from the user in the terminal
|
|
99
|
+
export async function promptForAnswers(metadata) {
|
|
100
|
+
const results = await prompts([
|
|
101
|
+
{
|
|
102
|
+
// Get the project name, used as the LWR project directory and saved as metadata.targetDir
|
|
103
|
+
type: metadata.targetDir ? null : 'text',
|
|
104
|
+
name: 'projectName',
|
|
105
|
+
message: 'Project directory name:',
|
|
106
|
+
initial: metadata.defaultProjectName,
|
|
107
|
+
onState: (state) => (metadata.targetDir = state.value.trim() || metadata.defaultProjectName),
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
// If the targetDir is not empty, ask if the current contents should be deleted (i.e. overwritten)
|
|
111
|
+
type: () => !fs.existsSync(metadata.targetDir) || isDirEmpty(metadata.targetDir)
|
|
112
|
+
? null
|
|
113
|
+
: 'confirm',
|
|
114
|
+
name: 'overwrite',
|
|
115
|
+
message: () => (metadata.targetDir === '.'
|
|
116
|
+
? 'Current directory'
|
|
117
|
+
: `Target directory "${metadata.targetDir}"`) +
|
|
118
|
+
` is not empty. Remove existing files and continue?`,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
// If the current contents SHOULD NOT be overwritten, throw an error and exit
|
|
122
|
+
type: (_, { overwrite } = {}) => {
|
|
123
|
+
if (overwrite === false) {
|
|
124
|
+
throw new Error(red('✖') + ' Operation cancelled');
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
},
|
|
128
|
+
name: 'overwriteChecker',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
// If the projectName/targetDir is not a valid package.json[name], prompt for a new one
|
|
132
|
+
type: () => (isValidPackageName(metadata.targetDir) ? null : 'text'),
|
|
133
|
+
name: 'packageName',
|
|
134
|
+
message: 'Package name (used in package.json):',
|
|
135
|
+
initial: () => toValidPackageName(metadata.targetDir),
|
|
136
|
+
validate: (dir) => isValidPackageName(dir) || 'Invalid package.json name',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
// Select a project type, if the user has not passed in a "--template"
|
|
140
|
+
type: metadata.template && TEMPLATES.includes(metadata.template) ? null : 'select',
|
|
141
|
+
name: 'projectType',
|
|
142
|
+
message: typeof metadata.template === 'string' && !TEMPLATES.includes(metadata.template)
|
|
143
|
+
? `"${metadata.template}" isn't a valid template. Please choose from below: `
|
|
144
|
+
: 'Select the type of project:',
|
|
145
|
+
initial: 0,
|
|
146
|
+
choices: PROJECTS.map((project_type) => {
|
|
147
|
+
const frameworkColor = project_type.color;
|
|
148
|
+
return {
|
|
149
|
+
title: frameworkColor(project_type.name),
|
|
150
|
+
value: project_type,
|
|
151
|
+
};
|
|
152
|
+
}),
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
// If the user picked a project type (i.e. "project_type") in the previous prompt, now choose a template
|
|
156
|
+
type: (project_type) => (project_type && project_type.templates ? 'select' : null),
|
|
157
|
+
name: 'template',
|
|
158
|
+
message: 'Select a project template:',
|
|
159
|
+
choices: (project_type) => project_type.templates.map((template) => {
|
|
160
|
+
const templateColor = template.color;
|
|
161
|
+
return {
|
|
162
|
+
title: templateColor(template.display || template.name),
|
|
163
|
+
value: template.name,
|
|
164
|
+
};
|
|
165
|
+
}),
|
|
166
|
+
},
|
|
167
|
+
], {
|
|
168
|
+
onCancel: () => {
|
|
169
|
+
throw new Error(red('✖') + ' Operation cancelled');
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
return {
|
|
173
|
+
results,
|
|
174
|
+
metadata: metadata, // possible mutation of metadata in prompts
|
|
175
|
+
};
|
|
176
|
+
}
|
|
53
177
|
//# sourceMappingURL=utils.js.map
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"url": "https://github.com/salesforce/lwr/issues"
|
|
11
11
|
},
|
|
12
12
|
"bin": {
|
|
13
|
-
"create-
|
|
13
|
+
"create-lwr": "build/es/index.js"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"local:bin": "node ./build/es/index.js"
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"type": "module",
|
|
23
23
|
"types": "build/es/index.d.ts",
|
|
24
|
-
"version": "0.6.
|
|
24
|
+
"version": "0.6.4",
|
|
25
25
|
"module": "build/es/index.js",
|
|
26
26
|
"main": "build/cjs/index.cjs",
|
|
27
27
|
"files": [
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"minimist": "^1.2.5",
|
|
40
40
|
"prompts": "^2.4.1"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "80b73fe4558dc3db0afcdbe80eb17f5a1464e34e"
|
|
43
43
|
}
|