@commercetools-frontend/create-mc-app 21.8.1 → 21.11.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/CHANGELOG.md +14 -0
- package/README.md +1 -12
- package/bin/cli.js +1 -90
- package/dist/commercetools-frontend-create-mc-app.cjs.d.ts +1 -0
- package/dist/commercetools-frontend-create-mc-app.cjs.dev.js +792 -0
- package/dist/commercetools-frontend-create-mc-app.cjs.js +7 -0
- package/dist/commercetools-frontend-create-mc-app.cjs.prod.js +787 -0
- package/dist/commercetools-frontend-create-mc-app.esm.js +764 -0
- package/dist/declarations/src/cli.d.ts +2 -0
- package/dist/declarations/src/hint-outdated-version.d.ts +2 -0
- package/dist/declarations/src/index.d.ts +2 -0
- package/dist/declarations/src/process-options.d.ts +3 -0
- package/dist/declarations/src/tasks/download-template.d.ts +4 -0
- package/dist/declarations/src/tasks/index.d.ts +5 -0
- package/dist/declarations/src/tasks/install-dependencies.d.ts +4 -0
- package/dist/declarations/src/tasks/update-application-constants.d.ts +4 -0
- package/dist/declarations/src/tasks/update-custom-application-config.d.ts +4 -0
- package/dist/declarations/src/tasks/update-package-json.d.ts +4 -0
- package/dist/declarations/src/types.d.ts +19 -0
- package/dist/declarations/src/utils.d.ts +7 -0
- package/dist/declarations/src/validations.d.ts +7 -0
- package/package.json +8 -4
- package/src/cli.ts +109 -0
- package/src/hint-outdated-version.ts +39 -0
- package/src/index.ts +3 -0
- package/src/process-options.ts +97 -0
- package/src/tasks/{download-template.js → download-template.ts} +11 -8
- package/src/tasks/index.ts +5 -0
- package/src/tasks/{install-dependencies.js → install-dependencies.ts} +8 -4
- package/src/tasks/update-application-constants.ts +61 -0
- package/src/tasks/update-custom-application-config.ts +85 -0
- package/src/tasks/{update-package-json.js → update-package-json.ts} +10 -6
- package/src/types.ts +21 -0
- package/src/utils.ts +41 -0
- package/src/{validations.js → validations.ts} +44 -15
- package/tsconfig.json +6 -0
- package/src/hint-outdated-version.js +0 -34
- package/src/index.js +0 -12
- package/src/parse-arguments.js +0 -87
- package/src/tasks/index.js +0 -13
- package/src/tasks/update-application-constants.js +0 -48
- package/src/tasks/update-custom-application-config.js +0 -64
- package/src/utils.js +0 -56
|
@@ -1,18 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import semver from 'semver';
|
|
4
|
+
import type { TCliCommandOptions } from './types';
|
|
5
|
+
import { isSemVer } from './utils';
|
|
4
6
|
|
|
5
|
-
const availableTemplates =
|
|
7
|
+
const availableTemplates = {
|
|
8
|
+
starter: 'starter',
|
|
9
|
+
'starter-typescript': 'starter-typescript',
|
|
10
|
+
} as const;
|
|
6
11
|
|
|
7
|
-
const throwIfTemplateIsNotSupported = (
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
const throwIfTemplateIsNotSupported = (
|
|
13
|
+
templateName: TCliCommandOptions['template']
|
|
14
|
+
) => {
|
|
15
|
+
switch (templateName) {
|
|
16
|
+
case availableTemplates.starter:
|
|
17
|
+
case availableTemplates['starter-typescript']:
|
|
18
|
+
break;
|
|
19
|
+
default:
|
|
20
|
+
const templateNamesList = Object.keys(availableTemplates).toString();
|
|
21
|
+
throw new Error(
|
|
22
|
+
`The provided template name "${templateName}" does not exist. Available templates are "${templateNamesList}". Make sure you are also using the latest version of "@commercetools-frontend/create-mc-app".`
|
|
23
|
+
);
|
|
12
24
|
}
|
|
13
25
|
};
|
|
14
26
|
|
|
15
|
-
const throwIfProjectDirectoryExists = (dirName, dirPath) => {
|
|
27
|
+
const throwIfProjectDirectoryExists = (dirName: string, dirPath: string) => {
|
|
16
28
|
if (fs.existsSync(dirPath)) {
|
|
17
29
|
throw new Error(
|
|
18
30
|
`A directory named "${dirName}" already exists at this location "${dirPath}". Please choose a different project name or remove the directory, then try running the command again.`
|
|
@@ -21,9 +33,9 @@ const throwIfProjectDirectoryExists = (dirName, dirPath) => {
|
|
|
21
33
|
};
|
|
22
34
|
|
|
23
35
|
const throwIfTemplateVersionDoesNotExist = (
|
|
24
|
-
templateName,
|
|
25
|
-
templateFolderPath,
|
|
26
|
-
versionToCheck
|
|
36
|
+
templateName: string,
|
|
37
|
+
templateFolderPath: string,
|
|
38
|
+
versionToCheck: string
|
|
27
39
|
) => {
|
|
28
40
|
if (!fs.existsSync(templateFolderPath)) {
|
|
29
41
|
throw new Error(
|
|
@@ -47,15 +59,32 @@ const throwIfTemplateVersionDoesNotExist = (
|
|
|
47
59
|
}
|
|
48
60
|
};
|
|
49
61
|
|
|
50
|
-
const throwIfInitialProjectKeyIsMissing = (initialProjectKey) => {
|
|
62
|
+
const throwIfInitialProjectKeyIsMissing = (initialProjectKey?: string) => {
|
|
51
63
|
if (!initialProjectKey) {
|
|
52
64
|
throw new Error(`Provide a valid project key that you have access to.`);
|
|
53
65
|
}
|
|
54
66
|
};
|
|
55
67
|
|
|
56
|
-
|
|
68
|
+
const throwIfNodeVersionIsNotSupported = (
|
|
69
|
+
currentNodeVersion: string,
|
|
70
|
+
expectedVersionRange: string
|
|
71
|
+
) => {
|
|
72
|
+
const hasValidNodeVersion = semver.satisfies(
|
|
73
|
+
currentNodeVersion,
|
|
74
|
+
expectedVersionRange
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
if (!hasValidNodeVersion) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`You are running Node ${currentNodeVersion} but create-mc-app requires Node ${expectedVersionRange}. Please update your version of Node.`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export {
|
|
57
85
|
throwIfTemplateIsNotSupported,
|
|
58
86
|
throwIfProjectDirectoryExists,
|
|
59
87
|
throwIfTemplateVersionDoesNotExist,
|
|
60
88
|
throwIfInitialProjectKeyIsMissing,
|
|
89
|
+
throwIfNodeVersionIsNotSupported,
|
|
61
90
|
};
|
package/tsconfig.json
ADDED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
const semver = require('semver');
|
|
2
|
-
const execa = require('execa');
|
|
3
|
-
|
|
4
|
-
module.exports = function hintOutdatedVersion(currentVersion) {
|
|
5
|
-
try {
|
|
6
|
-
const packageInfoForTagLatest = JSON.parse(
|
|
7
|
-
execa.sync(
|
|
8
|
-
'npm',
|
|
9
|
-
['view', '@commercetools-frontend/create-mc-app', '--json'],
|
|
10
|
-
{
|
|
11
|
-
encoding: 'utf-8',
|
|
12
|
-
stdio: 'ignore',
|
|
13
|
-
}
|
|
14
|
-
)
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
const hasBeenReleastedInLatestTag = semver.gt(
|
|
18
|
-
packageInfoForTagLatest.version,
|
|
19
|
-
currentVersion
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
const hintNewerVersions = [
|
|
23
|
-
hasBeenReleastedInLatestTag && `${packageInfoForTagLatest.version}`,
|
|
24
|
-
]
|
|
25
|
-
.filter(Boolean)
|
|
26
|
-
.join(', ');
|
|
27
|
-
|
|
28
|
-
if (hintNewerVersions.length > 0) {
|
|
29
|
-
console.log(`New version available! ${hintNewerVersions}`);
|
|
30
|
-
}
|
|
31
|
-
} catch (error) {
|
|
32
|
-
// Ignore errors, as this function should not affect the exit code of the command
|
|
33
|
-
}
|
|
34
|
-
};
|
package/src/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const { isValidNodeVersion, shouldUseYarn } = require('./utils');
|
|
2
|
-
const tasks = require('./tasks');
|
|
3
|
-
const hintOutdatedVersion = require('./hint-outdated-version');
|
|
4
|
-
const parseArguments = require('./parse-arguments');
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
isValidNodeVersion,
|
|
8
|
-
shouldUseYarn,
|
|
9
|
-
tasks,
|
|
10
|
-
hintOutdatedVersion,
|
|
11
|
-
parseArguments,
|
|
12
|
-
};
|
package/src/parse-arguments.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const readline = require('readline');
|
|
4
|
-
const crypto = require('crypto');
|
|
5
|
-
const {
|
|
6
|
-
throwIfTemplateIsNotSupported,
|
|
7
|
-
throwIfProjectDirectoryExists,
|
|
8
|
-
throwIfInitialProjectKeyIsMissing,
|
|
9
|
-
} = require('./validations');
|
|
10
|
-
const { isSemVer } = require('./utils');
|
|
11
|
-
|
|
12
|
-
const rl = readline.createInterface({
|
|
13
|
-
input: process.stdin,
|
|
14
|
-
output: process.stdout,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
const question = (query) =>
|
|
18
|
-
new Promise((resolve) => rl.question(query, resolve));
|
|
19
|
-
|
|
20
|
-
const getTemplateName = (flags) => flags.template || 'starter';
|
|
21
|
-
const getEntryPointUriPath = async (flags) => {
|
|
22
|
-
if (flags['entry-point-uri-path']) {
|
|
23
|
-
return flags['entry-point-uri-path'];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const templateName = getTemplateName(flags);
|
|
27
|
-
const randomEntryPointUriPath = `${templateName}-${crypto
|
|
28
|
-
.randomBytes(3)
|
|
29
|
-
.toString('hex')}`;
|
|
30
|
-
|
|
31
|
-
if (flags.yes) {
|
|
32
|
-
return randomEntryPointUriPath;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const answerEntryPointUriPath = await question(
|
|
36
|
-
`Provide the Custom Application entryPointUriPath (default "${randomEntryPointUriPath}"): `
|
|
37
|
-
);
|
|
38
|
-
return answerEntryPointUriPath || randomEntryPointUriPath;
|
|
39
|
-
};
|
|
40
|
-
const getInitialProjectKey = async (flags) => {
|
|
41
|
-
if (flags['initial-project-key']) {
|
|
42
|
-
return flags['initial-project-key'];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const initialProjectKey = await question(
|
|
46
|
-
`Provide the initial project key for local development: `
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
throwIfInitialProjectKeyIsMissing(initialProjectKey);
|
|
50
|
-
|
|
51
|
-
return initialProjectKey;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
module.exports = async function parseArguments(flags) {
|
|
55
|
-
const [projectDirectoryName] = flags._;
|
|
56
|
-
if (!projectDirectoryName) {
|
|
57
|
-
throw new Error('Missing required argument "<project-directory>"');
|
|
58
|
-
}
|
|
59
|
-
const projectDirectoryPath = path.resolve(projectDirectoryName);
|
|
60
|
-
|
|
61
|
-
// Parse options
|
|
62
|
-
const templateName = getTemplateName(flags);
|
|
63
|
-
let tagOrBranchVersion = flags['template-version'] || 'main';
|
|
64
|
-
tagOrBranchVersion =
|
|
65
|
-
isSemVer(tagOrBranchVersion) && !tagOrBranchVersion.startsWith('v')
|
|
66
|
-
? `v${tagOrBranchVersion}`
|
|
67
|
-
: tagOrBranchVersion;
|
|
68
|
-
|
|
69
|
-
// Validate options
|
|
70
|
-
throwIfProjectDirectoryExists(projectDirectoryName, projectDirectoryPath);
|
|
71
|
-
throwIfTemplateIsNotSupported(templateName);
|
|
72
|
-
|
|
73
|
-
// Read prompts
|
|
74
|
-
const entryPointUriPath = await getEntryPointUriPath(flags);
|
|
75
|
-
const initialProjectKey = await getInitialProjectKey(flags);
|
|
76
|
-
|
|
77
|
-
rl.close();
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
projectDirectoryName,
|
|
81
|
-
projectDirectoryPath,
|
|
82
|
-
templateName,
|
|
83
|
-
tagOrBranchVersion,
|
|
84
|
-
entryPointUriPath,
|
|
85
|
-
initialProjectKey,
|
|
86
|
-
};
|
|
87
|
-
};
|
package/src/tasks/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const downloadTemplate = require('./download-template');
|
|
2
|
-
const installDependencies = require('./install-dependencies');
|
|
3
|
-
const updatePackageJson = require('./update-package-json');
|
|
4
|
-
const updateCustomApplicationConfig = require('./update-custom-application-config');
|
|
5
|
-
const updateApplicationConstants = require('./update-application-constants');
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
downloadTemplate,
|
|
9
|
-
installDependencies,
|
|
10
|
-
updatePackageJson,
|
|
11
|
-
updateCustomApplicationConfig,
|
|
12
|
-
updateApplicationConstants,
|
|
13
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const os = require('os');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const rcfile = require('rcfile');
|
|
5
|
-
const prettier = require('prettier');
|
|
6
|
-
const babel = require('@babel/core');
|
|
7
|
-
const { resolveFilePathByExtension } = require('../utils');
|
|
8
|
-
|
|
9
|
-
function replaceEntryPointUriPathInConstants(filePath, options) {
|
|
10
|
-
const result = babel.transformFileSync(filePath, {
|
|
11
|
-
plugins: [
|
|
12
|
-
function replaceConstants() {
|
|
13
|
-
return {
|
|
14
|
-
visitor: {
|
|
15
|
-
VariableDeclarator(nodePath) {
|
|
16
|
-
if (nodePath.node.id.name === 'entryPointUriPath') {
|
|
17
|
-
nodePath.node.init = babel.types.stringLiteral(
|
|
18
|
-
options.entryPointUriPath
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
retainLines: true,
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const prettierConfig = rcfile('prettier', {
|
|
30
|
-
cwd: options.projectDirectoryPath,
|
|
31
|
-
});
|
|
32
|
-
const formattedData = prettier.format(result.code + os.EOL, prettierConfig);
|
|
33
|
-
fs.writeFileSync(filePath, formattedData, {
|
|
34
|
-
encoding: 'utf8',
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
module.exports = function updateApplicationConstants(options) {
|
|
39
|
-
return {
|
|
40
|
-
title: 'Updating application constants',
|
|
41
|
-
task: () => {
|
|
42
|
-
const applicationConstantsPath = resolveFilePathByExtension(
|
|
43
|
-
path.join(options.projectDirectoryPath, 'src/constants')
|
|
44
|
-
);
|
|
45
|
-
replaceEntryPointUriPathInConstants(applicationConstantsPath, options);
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
};
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const rcfile = require('rcfile');
|
|
4
|
-
const prettier = require('prettier');
|
|
5
|
-
const babel = require('@babel/core');
|
|
6
|
-
const { wordify, resolveFilePathByExtension } = require('../utils');
|
|
7
|
-
|
|
8
|
-
function replaceApplicationInfoInCustomApplicationConfig(filePath, options) {
|
|
9
|
-
const appName = wordify(options.entryPointUriPath);
|
|
10
|
-
|
|
11
|
-
const result = babel.transformFileSync(filePath, {
|
|
12
|
-
plugins: [
|
|
13
|
-
function replaceCustomApplicationConfig() {
|
|
14
|
-
return {
|
|
15
|
-
visitor: {
|
|
16
|
-
Identifier(nodePath) {
|
|
17
|
-
if (nodePath.isIdentifier({ name: 'name' })) {
|
|
18
|
-
nodePath.parent.value = babel.types.stringLiteral(appName);
|
|
19
|
-
}
|
|
20
|
-
if (nodePath.isIdentifier({ name: 'initialProjectKey' })) {
|
|
21
|
-
nodePath.parent.value = babel.types.stringLiteral(
|
|
22
|
-
options.initialProjectKey
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
if (nodePath.isIdentifier({ name: 'defaultLabel' })) {
|
|
26
|
-
if (
|
|
27
|
-
nodePath.findParent((parentPath) =>
|
|
28
|
-
parentPath.get('key').isIdentifier({ name: 'mainMenuLink' })
|
|
29
|
-
)
|
|
30
|
-
) {
|
|
31
|
-
nodePath.parent.value = babel.types.stringLiteral(appName);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
retainLines: true,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const prettierConfig = rcfile('prettier', {
|
|
43
|
-
cwd: options.projectDirectoryPath,
|
|
44
|
-
});
|
|
45
|
-
const formattedData = prettier.format(result.code, prettierConfig);
|
|
46
|
-
fs.writeFileSync(filePath, formattedData, {
|
|
47
|
-
encoding: 'utf8',
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
module.exports = function updateCustomApplicationConfig(options) {
|
|
52
|
-
return {
|
|
53
|
-
title: 'Updating Custom Applications config',
|
|
54
|
-
task: () => {
|
|
55
|
-
const customApplicationConfigPath = resolveFilePathByExtension(
|
|
56
|
-
path.join(options.projectDirectoryPath, 'custom-application-config')
|
|
57
|
-
);
|
|
58
|
-
replaceApplicationInfoInCustomApplicationConfig(
|
|
59
|
-
customApplicationConfigPath,
|
|
60
|
-
options
|
|
61
|
-
);
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
};
|
package/src/utils.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const execa = require('execa');
|
|
3
|
-
const semver = require('semver');
|
|
4
|
-
|
|
5
|
-
const isValidNodeVersion = (currentNodeVersion, expectedVersionRange) => {
|
|
6
|
-
const hasValidNodeVersion = semver.satisfies(
|
|
7
|
-
currentNodeVersion,
|
|
8
|
-
expectedVersionRange
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
if (!hasValidNodeVersion) {
|
|
12
|
-
console.error(
|
|
13
|
-
`You are running Node ${currentNodeVersion} but create-mc-app requires Node ${expectedVersionRange}. Please update your version of Node.`
|
|
14
|
-
);
|
|
15
|
-
process.exit(1);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const isSemVer = (version) => /^(v?)([0-9].[0-9].[0-9])+/.test(version);
|
|
20
|
-
|
|
21
|
-
const shouldUseYarn = () => {
|
|
22
|
-
try {
|
|
23
|
-
const result = execa.sync('yarn', ['--version'], { stdio: 'ignore' });
|
|
24
|
-
return !result.failed;
|
|
25
|
-
} catch (error) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const slugify = (name) => name.toLowerCase().replace(/_/gi, '-');
|
|
31
|
-
|
|
32
|
-
const upperFirst = (value) => value.charAt(0).toUpperCase() + value.slice(1);
|
|
33
|
-
|
|
34
|
-
const wordify = (slug) =>
|
|
35
|
-
slug
|
|
36
|
-
.split('-')
|
|
37
|
-
.map((word) => upperFirst(word))
|
|
38
|
-
.join(' ');
|
|
39
|
-
|
|
40
|
-
const resolveFilePathByExtension = (requestedModule) => {
|
|
41
|
-
const fileExtension = ['.js', '.ts', '.mjs', '.cjs'].find((ext) => {
|
|
42
|
-
const filePath = `${requestedModule}${ext}`;
|
|
43
|
-
return fs.existsSync(filePath);
|
|
44
|
-
});
|
|
45
|
-
return `${requestedModule}${fileExtension}`;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
module.exports = {
|
|
49
|
-
isValidNodeVersion,
|
|
50
|
-
isSemVer,
|
|
51
|
-
shouldUseYarn,
|
|
52
|
-
slugify,
|
|
53
|
-
wordify,
|
|
54
|
-
upperFirst,
|
|
55
|
-
resolveFilePathByExtension,
|
|
56
|
-
};
|