@commercetools-frontend/create-mc-app 21.9.0 → 21.10.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -12
  3. package/bin/cli.js +1 -90
  4. package/dist/commercetools-frontend-create-mc-app.cjs.d.ts +1 -0
  5. package/dist/commercetools-frontend-create-mc-app.cjs.dev.js +792 -0
  6. package/dist/commercetools-frontend-create-mc-app.cjs.js +7 -0
  7. package/dist/commercetools-frontend-create-mc-app.cjs.prod.js +787 -0
  8. package/dist/commercetools-frontend-create-mc-app.esm.js +764 -0
  9. package/dist/declarations/src/cli.d.ts +2 -0
  10. package/dist/declarations/src/hint-outdated-version.d.ts +2 -0
  11. package/dist/declarations/src/index.d.ts +2 -0
  12. package/dist/declarations/src/process-options.d.ts +3 -0
  13. package/dist/declarations/src/tasks/download-template.d.ts +4 -0
  14. package/dist/declarations/src/tasks/index.d.ts +5 -0
  15. package/dist/declarations/src/tasks/install-dependencies.d.ts +4 -0
  16. package/dist/declarations/src/tasks/update-application-constants.d.ts +4 -0
  17. package/dist/declarations/src/tasks/update-custom-application-config.d.ts +4 -0
  18. package/dist/declarations/src/tasks/update-package-json.d.ts +4 -0
  19. package/dist/declarations/src/types.d.ts +19 -0
  20. package/dist/declarations/src/utils.d.ts +7 -0
  21. package/dist/declarations/src/validations.d.ts +7 -0
  22. package/package.json +7 -3
  23. package/src/cli.ts +109 -0
  24. package/src/hint-outdated-version.ts +39 -0
  25. package/src/index.ts +3 -0
  26. package/src/process-options.ts +97 -0
  27. package/src/tasks/{download-template.js → download-template.ts} +11 -8
  28. package/src/tasks/index.ts +5 -0
  29. package/src/tasks/{install-dependencies.js → install-dependencies.ts} +8 -4
  30. package/src/tasks/update-application-constants.ts +61 -0
  31. package/src/tasks/update-custom-application-config.ts +85 -0
  32. package/src/tasks/{update-package-json.js → update-package-json.ts} +10 -6
  33. package/src/types.ts +21 -0
  34. package/src/utils.ts +41 -0
  35. package/src/{validations.js → validations.ts} +44 -15
  36. package/tsconfig.json +6 -0
  37. package/src/hint-outdated-version.js +0 -34
  38. package/src/index.js +0 -12
  39. package/src/parse-arguments.js +0 -87
  40. package/src/tasks/index.js +0 -13
  41. package/src/tasks/update-application-constants.js +0 -48
  42. package/src/tasks/update-custom-application-config.js +0 -64
  43. package/src/utils.js +0 -56
@@ -0,0 +1,2 @@
1
+ declare const run: () => void;
2
+ export default run;
@@ -0,0 +1,2 @@
1
+ declare function hintOutdatedVersion(currentVersion: string): Promise<void>;
2
+ export default hintOutdatedVersion;
@@ -0,0 +1,2 @@
1
+ import cli from './cli';
2
+ export { cli };
@@ -0,0 +1,3 @@
1
+ import type { TCliCommandOptions, TCliTaskOptions } from './types';
2
+ declare function processOptions(projectDirectoryName: string, options: TCliCommandOptions): Promise<TCliTaskOptions>;
3
+ export default processOptions;
@@ -0,0 +1,4 @@
1
+ import { type ListrTask } from 'listr2';
2
+ import type { TCliTaskOptions } from '../types';
3
+ declare function downloadTemplate(options: TCliTaskOptions): ListrTask;
4
+ export default downloadTemplate;
@@ -0,0 +1,5 @@
1
+ export { default as downloadTemplate } from './download-template';
2
+ export { default as installDependencies } from './install-dependencies';
3
+ export { default as updatePackageJson } from './update-package-json';
4
+ export { default as updateCustomApplicationConfig } from './update-custom-application-config';
5
+ export { default as updateApplicationConstants } from './update-application-constants';
@@ -0,0 +1,4 @@
1
+ import type { ListrTask } from 'listr2';
2
+ import type { TCliTaskOptions } from '../types';
3
+ declare function installDependencies(options: TCliTaskOptions): ListrTask;
4
+ export default installDependencies;
@@ -0,0 +1,4 @@
1
+ import type { ListrTask } from 'listr2';
2
+ import type { TCliTaskOptions } from '../types';
3
+ declare function updateApplicationConstants(options: TCliTaskOptions): ListrTask;
4
+ export default updateApplicationConstants;
@@ -0,0 +1,4 @@
1
+ import type { ListrTask } from 'listr2';
2
+ import type { TCliTaskOptions } from '../types';
3
+ declare function updateCustomApplicationConfig(options: TCliTaskOptions): ListrTask;
4
+ export default updateCustomApplicationConfig;
@@ -0,0 +1,4 @@
1
+ import type { ListrTask } from 'listr2';
2
+ import type { TCliTaskOptions } from '../types';
3
+ declare function updatePackageJson(options: TCliTaskOptions): ListrTask;
4
+ export default updatePackageJson;
@@ -0,0 +1,19 @@
1
+ export declare type TCliGlobalOptions = {
2
+ '--'?: string[];
3
+ };
4
+ export declare type TCliCommandOptions = {
5
+ template: 'starter' | 'starter-typescript';
6
+ templateVersion: string;
7
+ skipInstall: boolean;
8
+ yes: boolean;
9
+ entryPointUriPath?: string;
10
+ initialProjectKey?: string;
11
+ };
12
+ export declare type TCliTaskOptions = {
13
+ projectDirectoryName: string;
14
+ projectDirectoryPath: string;
15
+ templateName: TCliCommandOptions['template'];
16
+ tagOrBranchVersion: string;
17
+ entryPointUriPath: string;
18
+ initialProjectKey: string;
19
+ };
@@ -0,0 +1,7 @@
1
+ declare const isSemVer: (version: string) => boolean;
2
+ declare const shouldUseYarn: () => boolean;
3
+ declare const slugify: (name: string) => string;
4
+ declare const upperFirst: (value: string) => string;
5
+ declare const wordify: (slug: string) => string;
6
+ declare const resolveFilePathByExtension: (requestedModule: string) => string;
7
+ export { isSemVer, shouldUseYarn, slugify, wordify, upperFirst, resolveFilePathByExtension, };
@@ -0,0 +1,7 @@
1
+ import type { TCliCommandOptions } from './types';
2
+ declare const throwIfTemplateIsNotSupported: (templateName: TCliCommandOptions['template']) => void;
3
+ declare const throwIfProjectDirectoryExists: (dirName: string, dirPath: string) => void;
4
+ declare const throwIfTemplateVersionDoesNotExist: (templateName: string, templateFolderPath: string, versionToCheck: string) => void;
5
+ declare const throwIfInitialProjectKeyIsMissing: (initialProjectKey?: string) => void;
6
+ declare const throwIfNodeVersionIsNotSupported: (currentNodeVersion: string, expectedVersionRange: string) => void;
7
+ export { throwIfTemplateIsNotSupported, throwIfProjectDirectoryExists, throwIfTemplateVersionDoesNotExist, throwIfInitialProjectKeyIsMissing, throwIfNodeVersionIsNotSupported, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools-frontend/create-mc-app",
3
- "version": "21.9.0",
3
+ "version": "21.10.0",
4
4
  "description": "Create Merchant Center applications to quickly get up and running",
5
5
  "bugs": "https://github.com/commercetools/merchant-center-application-kit/issues",
6
6
  "repository": {
@@ -14,12 +14,16 @@
14
14
  "publishConfig": {
15
15
  "access": "public"
16
16
  },
17
+ "main": "dist/commercetools-frontend-create-mc-app.cjs.js",
18
+ "module": "dist/commercetools-frontend-create-mc-app.esm.js",
17
19
  "bin": "./bin/cli.js",
18
20
  "dependencies": {
19
21
  "@babel/core": "^7.18.6",
22
+ "@babel/runtime": "^7.18.6",
23
+ "@babel/runtime-corejs3": "^7.18.6",
24
+ "cac": "6.7.12",
20
25
  "execa": "5.1.1",
21
- "listr": "0.14.3",
22
- "mri": "1.2.0",
26
+ "listr2": "4.0.5",
23
27
  "prettier": "2.6.2",
24
28
  "rcfile": "1.0.3",
25
29
  "semver": "7.3.7"
package/src/cli.ts ADDED
@@ -0,0 +1,109 @@
1
+ import { cac } from 'cac';
2
+ import { Listr, type ListrTask } from 'listr2';
3
+ import * as tasks from './tasks';
4
+ import { throwIfNodeVersionIsNotSupported } from './validations';
5
+ import { shouldUseYarn } from './utils';
6
+ import hintOutdatedVersion from './hint-outdated-version';
7
+ import processOptions from './process-options';
8
+ import type { TCliCommandOptions } from './types';
9
+ import pkgJson from '../package.json';
10
+
11
+ throwIfNodeVersionIsNotSupported(process.versions.node, pkgJson.engines.node);
12
+
13
+ const cli = cac('create-mc-app');
14
+
15
+ // Makes the script crash on unhandled rejections instead of silently
16
+ // ignoring them. In the future, promise rejections that are not handled will
17
+ // terminate the Node.js process with a non-zero exit code.
18
+ process.on('unhandledRejection', (err) => {
19
+ throw err;
20
+ });
21
+
22
+ const run = () => {
23
+ // Default command
24
+ cli
25
+ .command('[project-directory]')
26
+ .usage(
27
+ '[project-directory]\n\n Bootstraps a new Custom Application project using one of the predefined templates.'
28
+ )
29
+ .option(
30
+ '--template <name>',
31
+ '(optional) The name of the template to install.',
32
+ { default: 'starter' }
33
+ )
34
+ .option(
35
+ '--template-version <version>',
36
+ '(optional) The version of the template to install (either a git tag or a git branch of the "commercetools/merchant-center-application-kit" repository).',
37
+ { default: 'main' }
38
+ )
39
+ .option(
40
+ '--skip-install',
41
+ '(optional) Skip installing the dependencies after cloning the template.',
42
+ { default: false }
43
+ )
44
+ .option(
45
+ '--yes',
46
+ '(optional) If set, the prompt options with default values will be skipped.',
47
+ { default: false }
48
+ )
49
+ .option(
50
+ '--entry-point-uri-path <value>',
51
+ '(optional) The version of the template to install. (default: starter-<hash>)'
52
+ )
53
+ .option(
54
+ '--initial-project-key <value>',
55
+ '(optional) A commercetools project key used for the initial login in development. By default, the value is prompted in the terminal.'
56
+ )
57
+ .action(async (projectDirectory, options: TCliCommandOptions) => {
58
+ if (!projectDirectory) {
59
+ cli.outputHelp();
60
+ return;
61
+ }
62
+
63
+ await hintOutdatedVersion(pkgJson.version);
64
+
65
+ console.log('');
66
+ console.log(
67
+ `Documentation available at https://docs.commercetools.com/custom-applications`
68
+ );
69
+ console.log('');
70
+
71
+ const taskOptions = await processOptions(projectDirectory, options);
72
+
73
+ const taskList = new Listr(
74
+ [
75
+ tasks.downloadTemplate(taskOptions),
76
+ tasks.updatePackageJson(taskOptions),
77
+ tasks.updateCustomApplicationConfig(taskOptions),
78
+ tasks.updateApplicationConstants(taskOptions),
79
+ !options.skipInstall && tasks.installDependencies(taskOptions),
80
+ ].filter(Boolean) as ListrTask[]
81
+ );
82
+
83
+ await taskList.run();
84
+ const useYarn = shouldUseYarn();
85
+
86
+ console.log('');
87
+ console.log(
88
+ `🎉 🎉 🎉 The Custom Application has been created in the "${taskOptions.projectDirectoryName}" folder.`
89
+ );
90
+ console.log('');
91
+ console.log(`To get started:`);
92
+ console.log(`$ cd ${taskOptions.projectDirectoryName}`);
93
+ if (options.skipInstall) {
94
+ console.log(`$ ${useYarn ? 'yarn' : 'npm'} install`);
95
+ }
96
+ console.log(`$ ${useYarn ? 'yarn' : 'npm'} start`);
97
+ console.log('');
98
+ console.log(
99
+ `Visit https://docs.commercetools.com/custom-applications for more info about developing Custom Applications. Enjoy 🚀`
100
+ );
101
+ });
102
+
103
+ cli.help();
104
+ cli.version(pkgJson.version);
105
+
106
+ cli.parse();
107
+ };
108
+
109
+ export default run;
@@ -0,0 +1,39 @@
1
+ import semver from 'semver';
2
+ import execa from 'execa';
3
+
4
+ async function hintOutdatedVersion(currentVersion: string) {
5
+ try {
6
+ const commandResult = await execa.command(
7
+ 'npm view @commercetools-frontend/create-mc-app --json',
8
+ { encoding: 'utf-8' }
9
+ );
10
+
11
+ const packageInfoForTagLatest = JSON.parse(commandResult.stdout);
12
+
13
+ const hasBeenReleastedInLatestTag = semver.gt(
14
+ packageInfoForTagLatest.version,
15
+ currentVersion
16
+ );
17
+
18
+ const hintNewerVersions = [
19
+ hasBeenReleastedInLatestTag && `${packageInfoForTagLatest.version}`,
20
+ ]
21
+ .filter(Boolean)
22
+ .join(', ');
23
+
24
+ if (hintNewerVersions.length > 0) {
25
+ console.log('');
26
+ console.log(
27
+ `New version available! ${currentVersion} -> ${hintNewerVersions}`
28
+ );
29
+ console.log('');
30
+ }
31
+ } catch (error) {
32
+ // Ignore errors, as this function should not affect the exit code of the command
33
+ if (process.env.NODE_ENV === 'test') {
34
+ console.error(error);
35
+ }
36
+ }
37
+ }
38
+
39
+ export default hintOutdatedVersion;
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import cli from './cli';
2
+
3
+ export { cli };
@@ -0,0 +1,97 @@
1
+ import path from 'path';
2
+ import readline, { type Interface } from 'readline';
3
+ import crypto from 'crypto';
4
+ import {
5
+ throwIfTemplateIsNotSupported,
6
+ throwIfProjectDirectoryExists,
7
+ throwIfInitialProjectKeyIsMissing,
8
+ } from './validations';
9
+ import { isSemVer } from './utils';
10
+ import type { TCliCommandOptions, TCliTaskOptions } from './types';
11
+
12
+ const question = (rl: Interface, value: string) =>
13
+ new Promise<string>((resolve) => rl.question(value, resolve));
14
+
15
+ const getEntryPointUriPath = async (
16
+ rl: Interface,
17
+ options: TCliCommandOptions
18
+ ) => {
19
+ if (options.entryPointUriPath) {
20
+ return options.entryPointUriPath;
21
+ }
22
+
23
+ const randomEntryPointUriPath = `${options.template}-${crypto
24
+ .randomBytes(3)
25
+ .toString('hex')}`;
26
+
27
+ if (options.yes) {
28
+ return randomEntryPointUriPath;
29
+ }
30
+
31
+ const answerEntryPointUriPath = await question(
32
+ rl,
33
+ `Provide the Custom Application entryPointUriPath (default "${randomEntryPointUriPath}"): `
34
+ );
35
+ return answerEntryPointUriPath || randomEntryPointUriPath;
36
+ };
37
+
38
+ const getInitialProjectKey = async (
39
+ rl: Interface,
40
+ options: TCliCommandOptions
41
+ ) => {
42
+ if (options.initialProjectKey) {
43
+ return options.initialProjectKey;
44
+ }
45
+
46
+ const initialProjectKey = await question(
47
+ rl,
48
+ `Provide the initial project key for local development: `
49
+ );
50
+
51
+ throwIfInitialProjectKeyIsMissing(initialProjectKey);
52
+
53
+ return initialProjectKey;
54
+ };
55
+
56
+ async function processOptions(
57
+ projectDirectoryName: string,
58
+ options: TCliCommandOptions
59
+ ): Promise<TCliTaskOptions> {
60
+ if (!projectDirectoryName) {
61
+ throw new Error('Missing required argument "[project-directory]"');
62
+ }
63
+ const projectDirectoryPath = path.resolve(projectDirectoryName);
64
+
65
+ // Parse options
66
+ let tagOrBranchVersion = options.templateVersion || 'main';
67
+ tagOrBranchVersion =
68
+ isSemVer(tagOrBranchVersion) && !tagOrBranchVersion.startsWith('v')
69
+ ? `v${tagOrBranchVersion}`
70
+ : tagOrBranchVersion;
71
+
72
+ const templateName = options.template;
73
+
74
+ // Validate options
75
+ throwIfProjectDirectoryExists(projectDirectoryName, projectDirectoryPath);
76
+ throwIfTemplateIsNotSupported(templateName);
77
+
78
+ // Read prompts
79
+ const rl = readline.createInterface({
80
+ input: process.stdin,
81
+ output: process.stdout,
82
+ });
83
+ const entryPointUriPath = await getEntryPointUriPath(rl, options);
84
+ const initialProjectKey = await getInitialProjectKey(rl, options);
85
+ rl.close();
86
+
87
+ return {
88
+ projectDirectoryName,
89
+ projectDirectoryPath,
90
+ templateName,
91
+ tagOrBranchVersion,
92
+ entryPointUriPath,
93
+ initialProjectKey,
94
+ };
95
+ }
96
+
97
+ export default processOptions;
@@ -1,13 +1,14 @@
1
- const fs = require('fs');
2
- const os = require('os');
3
- const path = require('path');
4
- const execa = require('execa');
5
- const Listr = require('listr');
6
- const { throwIfTemplateVersionDoesNotExist } = require('../validations');
1
+ import fs from 'fs';
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import execa from 'execa';
5
+ import { Listr, type ListrTask } from 'listr2';
6
+ import { throwIfTemplateVersionDoesNotExist } from '../validations';
7
+ import type { TCliTaskOptions } from '../types';
7
8
 
8
9
  const filesToBeRemoved = ['CHANGELOG.md'];
9
10
 
10
- module.exports = function downloadTemplate(options) {
11
+ function downloadTemplate(options: TCliTaskOptions): ListrTask {
11
12
  return {
12
13
  title: 'Downloading template',
13
14
  task: () => {
@@ -121,4 +122,6 @@ module.exports = function downloadTemplate(options) {
121
122
  ]);
122
123
  },
123
124
  };
124
- };
125
+ }
126
+
127
+ export default downloadTemplate;
@@ -0,0 +1,5 @@
1
+ export { default as downloadTemplate } from './download-template';
2
+ export { default as installDependencies } from './install-dependencies';
3
+ export { default as updatePackageJson } from './update-package-json';
4
+ export { default as updateCustomApplicationConfig } from './update-custom-application-config';
5
+ export { default as updateApplicationConstants } from './update-application-constants';
@@ -1,7 +1,9 @@
1
- const execa = require('execa');
2
- const { shouldUseYarn } = require('../utils');
1
+ import execa from 'execa';
2
+ import type { ListrTask } from 'listr2';
3
+ import { shouldUseYarn } from '../utils';
4
+ import type { TCliTaskOptions } from '../types';
3
5
 
4
- module.exports = function installDependencies(options) {
6
+ function installDependencies(options: TCliTaskOptions): ListrTask {
5
7
  return {
6
8
  title: 'Installing dependencies (this might take a while)',
7
9
  task: () => {
@@ -15,4 +17,6 @@ module.exports = function installDependencies(options) {
15
17
  });
16
18
  },
17
19
  };
18
- };
20
+ }
21
+
22
+ export default installDependencies;
@@ -0,0 +1,61 @@
1
+ import os from 'os';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ // @ts-ignore
5
+ import rcfile from 'rcfile';
6
+ import prettier from 'prettier';
7
+ import { type PluginItem, transformFileSync, types } from '@babel/core';
8
+ import type { ListrTask } from 'listr2';
9
+ import { resolveFilePathByExtension } from '../utils';
10
+ import type { TCliTaskOptions } from '../types';
11
+
12
+ function replaceEntryPointUriPathInConstants(
13
+ filePath: string,
14
+ options: TCliTaskOptions
15
+ ) {
16
+ const result = transformFileSync(filePath, {
17
+ plugins: [
18
+ function replaceConstants(): PluginItem {
19
+ return {
20
+ visitor: {
21
+ VariableDeclarator(nodePath) {
22
+ if (
23
+ nodePath.node.id.type === 'Identifier' &&
24
+ nodePath.node.id.name === 'entryPointUriPath'
25
+ ) {
26
+ nodePath.node.init = types.stringLiteral(
27
+ options.entryPointUriPath
28
+ );
29
+ }
30
+ },
31
+ },
32
+ };
33
+ },
34
+ ],
35
+ retainLines: true,
36
+ });
37
+
38
+ if (result?.code) {
39
+ const prettierConfig = rcfile('prettier', {
40
+ cwd: options.projectDirectoryPath,
41
+ });
42
+ const formattedData = prettier.format(result.code + os.EOL, prettierConfig);
43
+ fs.writeFileSync(filePath, formattedData, {
44
+ encoding: 'utf8',
45
+ });
46
+ }
47
+ }
48
+
49
+ function updateApplicationConstants(options: TCliTaskOptions): ListrTask {
50
+ return {
51
+ title: 'Updating application constants',
52
+ task: () => {
53
+ const applicationConstantsPath = resolveFilePathByExtension(
54
+ path.join(options.projectDirectoryPath, 'src/constants')
55
+ );
56
+ replaceEntryPointUriPathInConstants(applicationConstantsPath, options);
57
+ },
58
+ };
59
+ }
60
+
61
+ export default updateApplicationConstants;
@@ -0,0 +1,85 @@
1
+ import os from 'os';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ // @ts-ignore
5
+ import rcfile from 'rcfile';
6
+ import prettier from 'prettier';
7
+ import { transformFileSync, types, type PluginItem } from '@babel/core';
8
+ import type { ListrTask } from 'listr2';
9
+ import { wordify, resolveFilePathByExtension } from '../utils';
10
+ import type { TCliTaskOptions } from '../types';
11
+
12
+ function replaceApplicationInfoInCustomApplicationConfig(
13
+ filePath: string,
14
+ options: TCliTaskOptions
15
+ ) {
16
+ const appName = wordify(options.entryPointUriPath);
17
+
18
+ const result = transformFileSync(filePath, {
19
+ plugins: [
20
+ function replaceCustomApplicationConfig(): PluginItem {
21
+ return {
22
+ visitor: {
23
+ Identifier(nodePath) {
24
+ if (
25
+ nodePath.isIdentifier({ name: 'name' }) &&
26
+ nodePath.parent.type === 'ObjectProperty'
27
+ ) {
28
+ nodePath.parent.value = types.stringLiteral(appName);
29
+ }
30
+ if (
31
+ nodePath.isIdentifier({ name: 'initialProjectKey' }) &&
32
+ nodePath.parent.type === 'ObjectProperty'
33
+ ) {
34
+ nodePath.parent.value = types.stringLiteral(
35
+ options.initialProjectKey
36
+ );
37
+ }
38
+ if (nodePath.isIdentifier({ name: 'defaultLabel' })) {
39
+ const isMainMenuLinkParent = nodePath.findParent((parentPath) =>
40
+ parentPath.isIdentifier({
41
+ name: 'mainMenuLink',
42
+ })
43
+ );
44
+ if (
45
+ isMainMenuLinkParent &&
46
+ nodePath.parent.type === 'ObjectProperty'
47
+ ) {
48
+ nodePath.parent.value = types.stringLiteral(appName);
49
+ }
50
+ }
51
+ },
52
+ },
53
+ };
54
+ },
55
+ ],
56
+ retainLines: true,
57
+ });
58
+
59
+ if (result?.code) {
60
+ const prettierConfig = rcfile('prettier', {
61
+ cwd: options.projectDirectoryPath,
62
+ });
63
+ const formattedData = prettier.format(result.code + os.EOL, prettierConfig);
64
+ fs.writeFileSync(filePath, formattedData, {
65
+ encoding: 'utf8',
66
+ });
67
+ }
68
+ }
69
+
70
+ function updateCustomApplicationConfig(options: TCliTaskOptions): ListrTask {
71
+ return {
72
+ title: 'Updating Custom Applications config',
73
+ task: () => {
74
+ const customApplicationConfigPath = resolveFilePathByExtension(
75
+ path.join(options.projectDirectoryPath, 'custom-application-config')
76
+ );
77
+ replaceApplicationInfoInCustomApplicationConfig(
78
+ customApplicationConfigPath,
79
+ options
80
+ );
81
+ },
82
+ };
83
+ }
84
+
85
+ export default updateCustomApplicationConfig;
@@ -1,9 +1,11 @@
1
- const os = require('os');
2
- const fs = require('fs');
3
- const path = require('path');
4
- const { slugify } = require('../utils');
1
+ import os from 'os';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import type { ListrTask } from 'listr2';
5
+ import { slugify } from '../utils';
6
+ import type { TCliTaskOptions } from '../types';
5
7
 
6
- module.exports = function updatePackageJson(options) {
8
+ function updatePackageJson(options: TCliTaskOptions): ListrTask {
7
9
  return {
8
10
  title: 'Updating package.json',
9
11
  task: () => {
@@ -32,4 +34,6 @@ module.exports = function updatePackageJson(options) {
32
34
  );
33
35
  },
34
36
  };
35
- };
37
+ }
38
+
39
+ export default updatePackageJson;
package/src/types.ts ADDED
@@ -0,0 +1,21 @@
1
+ export type TCliGlobalOptions = {
2
+ '--'?: string[];
3
+ };
4
+
5
+ export type TCliCommandOptions = {
6
+ template: 'starter' | 'starter-typescript';
7
+ templateVersion: string;
8
+ skipInstall: boolean;
9
+ yes: boolean;
10
+ entryPointUriPath?: string;
11
+ initialProjectKey?: string;
12
+ };
13
+
14
+ export type TCliTaskOptions = {
15
+ projectDirectoryName: string;
16
+ projectDirectoryPath: string;
17
+ templateName: TCliCommandOptions['template'];
18
+ tagOrBranchVersion: string;
19
+ entryPointUriPath: string;
20
+ initialProjectKey: string;
21
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,41 @@
1
+ import fs from 'fs';
2
+ import execa from 'execa';
3
+
4
+ const isSemVer = (version: string) => /^(v?)([0-9].[0-9].[0-9])+/.test(version);
5
+
6
+ const shouldUseYarn = () => {
7
+ try {
8
+ const result = execa.commandSync('yarn --version', { stdio: 'ignore' });
9
+ return !result.failed;
10
+ } catch (error) {
11
+ return false;
12
+ }
13
+ };
14
+
15
+ const slugify = (name: string) => name.toLowerCase().replace(/_/gi, '-');
16
+
17
+ const upperFirst = (value: string) =>
18
+ value.charAt(0).toUpperCase() + value.slice(1);
19
+
20
+ const wordify = (slug: string) =>
21
+ slug
22
+ .split('-')
23
+ .map((word) => upperFirst(word))
24
+ .join(' ');
25
+
26
+ const resolveFilePathByExtension = (requestedModule: string) => {
27
+ const fileExtension = ['.js', '.ts', '.mjs', '.cjs'].find((ext) => {
28
+ const filePath = `${requestedModule}${ext}`;
29
+ return fs.existsSync(filePath);
30
+ });
31
+ return `${requestedModule}${fileExtension}`;
32
+ };
33
+
34
+ export {
35
+ isSemVer,
36
+ shouldUseYarn,
37
+ slugify,
38
+ wordify,
39
+ upperFirst,
40
+ resolveFilePathByExtension,
41
+ };