@commercetools-frontend/create-mc-app 22.8.0 → 22.8.2
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 +4 -0
- package/dist/commercetools-frontend-create-mc-app.cjs.dev.js +82 -35
- package/dist/commercetools-frontend-create-mc-app.cjs.prod.js +82 -35
- package/dist/commercetools-frontend-create-mc-app.esm.js +82 -35
- package/dist/declarations/src/constants.d.ts +9 -0
- package/dist/declarations/src/tasks/index.d.ts +1 -1
- package/dist/declarations/src/tasks/update-application-config.d.ts +4 -0
- package/dist/declarations/src/types.d.ts +6 -2
- package/dist/declarations/src/utils.d.ts +3 -2
- package/dist/declarations/src/validations.d.ts +3 -2
- package/package.json +1 -1
- package/src/cli.ts +11 -3
- package/src/constants.ts +11 -0
- package/src/process-options.ts +11 -3
- package/src/tasks/download-template.ts +7 -4
- package/src/tasks/index.ts +1 -1
- package/src/tasks/{update-custom-application-config.ts → update-application-config.ts} +34 -17
- package/src/tasks/update-application-constants.ts +6 -4
- package/src/tasks/update-package-json.ts +3 -3
- package/src/types.ts +7 -2
- package/src/utils.ts +10 -2
- package/src/validations.ts +27 -8
- package/dist/declarations/src/tasks/update-custom-application-config.d.ts +0 -4
|
@@ -6,16 +6,16 @@ import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/insta
|
|
|
6
6
|
import semver from 'semver';
|
|
7
7
|
import _Promise from '@babel/runtime-corejs3/core-js-stable/promise';
|
|
8
8
|
import _startsWithInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/starts-with';
|
|
9
|
-
import crypto from 'crypto';
|
|
10
|
-
import path from 'path';
|
|
11
|
-
import readline from 'readline';
|
|
9
|
+
import crypto from 'node:crypto';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import readline from 'node:readline';
|
|
12
12
|
import _sliceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/slice';
|
|
13
13
|
import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
|
|
14
14
|
import _findInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/find';
|
|
15
|
-
import fs from 'fs';
|
|
15
|
+
import fs from 'node:fs';
|
|
16
16
|
import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
|
|
17
17
|
import _Date$now from '@babel/runtime-corejs3/core-js-stable/date/now';
|
|
18
|
-
import os from 'os';
|
|
18
|
+
import os from 'node:os';
|
|
19
19
|
import _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols';
|
|
20
20
|
import _Object$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
|
|
21
21
|
import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each';
|
|
@@ -33,7 +33,7 @@ import prettier from 'prettier';
|
|
|
33
33
|
|
|
34
34
|
var pkgJson = {
|
|
35
35
|
name: "@commercetools-frontend/create-mc-app",
|
|
36
|
-
version: "22.8.
|
|
36
|
+
version: "22.8.2",
|
|
37
37
|
description: "Create Merchant Center applications to quickly get up and running",
|
|
38
38
|
bugs: "https://github.com/commercetools/merchant-center-application-kit/issues",
|
|
39
39
|
repository: {
|
|
@@ -75,6 +75,15 @@ var pkgJson = {
|
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
+
const applicationTypes = {
|
|
79
|
+
'custom-application': 'custom-application',
|
|
80
|
+
'custom-view': 'custom-view'
|
|
81
|
+
};
|
|
82
|
+
const availableTemplates = {
|
|
83
|
+
starter: 'starter',
|
|
84
|
+
'starter-typescript': 'starter-typescript'
|
|
85
|
+
};
|
|
86
|
+
|
|
78
87
|
async function getLatestReleaseVersion() {
|
|
79
88
|
const commandResult = await execa.command('npm view @commercetools-frontend/create-mc-app --json', {
|
|
80
89
|
encoding: 'utf-8'
|
|
@@ -142,31 +151,48 @@ const resolveFilePathByExtension = requestedModule => {
|
|
|
142
151
|
return _concatInstanceProperty(_context4 = "".concat(requestedModule)).call(_context4, fileExtension);
|
|
143
152
|
};
|
|
144
153
|
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
154
|
+
const throwIfApplicationTypeIsNotSupported = applicationType => {
|
|
155
|
+
switch (applicationType) {
|
|
156
|
+
case applicationTypes['custom-view']:
|
|
157
|
+
{
|
|
158
|
+
if (process.env.ENABLE_EXPERIMENTAL_CUSTOM_VIEWS !== 'true') {
|
|
159
|
+
throw new Error("Custom Views generation is not yet supported.");
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case applicationTypes['custom-application']:
|
|
164
|
+
break;
|
|
165
|
+
default:
|
|
166
|
+
{
|
|
167
|
+
var _context;
|
|
168
|
+
const applicationTypesList = _Object$keys(applicationTypes).toString();
|
|
169
|
+
throw new Error(_concatInstanceProperty(_context = "The provided application type \"".concat(applicationType, "\" does not exist. Available types are \"")).call(_context, applicationTypesList, "\". Make sure you are also using the latest version of \"@commercetools-frontend/create-mc-app\"."));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
148
172
|
};
|
|
149
173
|
const throwIfTemplateIsNotSupported = templateName => {
|
|
150
|
-
var _context;
|
|
151
174
|
switch (templateName) {
|
|
152
175
|
case availableTemplates.starter:
|
|
153
176
|
case availableTemplates['starter-typescript']:
|
|
154
177
|
break;
|
|
155
178
|
default:
|
|
156
|
-
|
|
157
|
-
|
|
179
|
+
{
|
|
180
|
+
var _context2;
|
|
181
|
+
const templateNamesList = _Object$keys(availableTemplates).toString();
|
|
182
|
+
throw new Error(_concatInstanceProperty(_context2 = "The provided template name \"".concat(templateName, "\" does not exist. Available templates are \"")).call(_context2, templateNamesList, "\". Make sure you are also using the latest version of \"@commercetools-frontend/create-mc-app\"."));
|
|
183
|
+
}
|
|
158
184
|
}
|
|
159
185
|
};
|
|
160
186
|
const throwIfProjectDirectoryExists = (dirName, dirPath) => {
|
|
161
187
|
if (fs.existsSync(dirPath)) {
|
|
162
|
-
var
|
|
163
|
-
throw new Error(_concatInstanceProperty(
|
|
188
|
+
var _context3;
|
|
189
|
+
throw new Error(_concatInstanceProperty(_context3 = "A directory named \"".concat(dirName, "\" already exists at this location \"")).call(_context3, dirPath, "\". Please choose a different project name or remove the directory, then try running the command again."));
|
|
164
190
|
}
|
|
165
191
|
};
|
|
166
192
|
const throwIfTemplateVersionDoesNotExist = (templateName, templateFolderPath, versionToCheck) => {
|
|
167
193
|
if (!fs.existsSync(templateFolderPath)) {
|
|
168
|
-
var
|
|
169
|
-
throw new Error(_concatInstanceProperty(
|
|
194
|
+
var _context4;
|
|
195
|
+
throw new Error(_concatInstanceProperty(_context4 = "The downloaded template \"".concat(templateName, "\" does not exist for the given version \"")).call(_context4, versionToCheck, "\". Check the releases page if you are looking for a specific version: https://github.com/commercetools/merchant-center-application-kit/releases"));
|
|
170
196
|
}
|
|
171
197
|
// In case the version is semver (usually release tags) we check that
|
|
172
198
|
// the cloned repository contains the template matching the given version
|
|
@@ -176,8 +202,8 @@ const throwIfTemplateVersionDoesNotExist = (templateName, templateFolderPath, ve
|
|
|
176
202
|
}));
|
|
177
203
|
const versionAsNumber = versionToCheck.replace('v', '');
|
|
178
204
|
if (templatePackageJson.version !== versionAsNumber) {
|
|
179
|
-
var
|
|
180
|
-
throw new Error(_concatInstanceProperty(
|
|
205
|
+
var _context5, _context6;
|
|
206
|
+
throw new Error(_concatInstanceProperty(_context5 = _concatInstanceProperty(_context6 = "The downloaded template \"".concat(templateName, "\" does not match the version \"")).call(_context6, versionAsNumber, "\", instead got \"")).call(_context5, templatePackageJson.version, "\". Check the releases page if you want to provide a specific version: https://github.com/commercetools/merchant-center-application-kit/releases"));
|
|
181
207
|
}
|
|
182
208
|
}
|
|
183
209
|
};
|
|
@@ -189,14 +215,17 @@ const throwIfInitialProjectKeyIsMissing = initialProjectKey => {
|
|
|
189
215
|
const throwIfNodeVersionIsNotSupported = (currentNodeVersion, expectedVersionRange) => {
|
|
190
216
|
const hasValidNodeVersion = semver.satisfies(currentNodeVersion, expectedVersionRange);
|
|
191
217
|
if (!hasValidNodeVersion) {
|
|
192
|
-
var
|
|
193
|
-
throw new Error(_concatInstanceProperty(
|
|
218
|
+
var _context7;
|
|
219
|
+
throw new Error(_concatInstanceProperty(_context7 = "You are running Node ".concat(currentNodeVersion, " but create-mc-app requires Node ")).call(_context7, expectedVersionRange, ". Please update your version of Node."));
|
|
194
220
|
}
|
|
195
221
|
};
|
|
196
222
|
|
|
197
223
|
const question = (rl, value) => new _Promise(resolve => rl.question(value, resolve));
|
|
198
224
|
const getEntryPointUriPath = async (rl, options) => {
|
|
199
225
|
var _context;
|
|
226
|
+
if (options.applicationType === applicationTypes['custom-view']) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
200
229
|
if (options.entryPointUriPath) {
|
|
201
230
|
return options.entryPointUriPath;
|
|
202
231
|
}
|
|
@@ -227,6 +256,7 @@ async function processOptions(projectDirectoryName, options) {
|
|
|
227
256
|
const templateName = options.template;
|
|
228
257
|
|
|
229
258
|
// Validate options
|
|
259
|
+
throwIfApplicationTypeIsNotSupported(options.applicationType);
|
|
230
260
|
throwIfProjectDirectoryExists(projectDirectoryName, projectDirectoryPath);
|
|
231
261
|
throwIfTemplateIsNotSupported(templateName);
|
|
232
262
|
|
|
@@ -239,6 +269,7 @@ async function processOptions(projectDirectoryName, options) {
|
|
|
239
269
|
const initialProjectKey = await getInitialProjectKey(rl, options);
|
|
240
270
|
rl.close();
|
|
241
271
|
return {
|
|
272
|
+
applicationType: options.applicationType,
|
|
242
273
|
projectDirectoryName,
|
|
243
274
|
projectDirectoryPath,
|
|
244
275
|
templateName,
|
|
@@ -258,7 +289,7 @@ function downloadTemplate(options) {
|
|
|
258
289
|
const tmpDir = os.tmpdir();
|
|
259
290
|
const tmpFolderNameForClonedRepository = ['merchant-center-application-kit', '--', options.tagOrBranchVersion, '--', _Date$now().toString()].join('');
|
|
260
291
|
const clonedRepositoryPath = path.join(tmpDir, tmpFolderNameForClonedRepository);
|
|
261
|
-
const templateFolderPath = path.join(clonedRepositoryPath, 'application-templates', options.templateName);
|
|
292
|
+
const templateFolderPath = path.join(clonedRepositoryPath, options.applicationType === applicationTypes['custom-view'] ? 'custom-views-templates' : 'application-templates', options.templateName);
|
|
262
293
|
return new Listr([{
|
|
263
294
|
title: "Cloning repository using branch ".concat(options.tagOrBranchVersion),
|
|
264
295
|
task: async () => {
|
|
@@ -370,10 +401,11 @@ function updatePackageJson(options, releaseVersion) {
|
|
|
370
401
|
};
|
|
371
402
|
}
|
|
372
403
|
|
|
373
|
-
function
|
|
374
|
-
const appName = wordify(options.entryPointUriPath);
|
|
404
|
+
function replaceApplicationInfoInApplicationConfig(filePath, options) {
|
|
375
405
|
const result = transformFileSync(filePath, {
|
|
376
|
-
plugins: [function
|
|
406
|
+
plugins: [function replaceConfig() {
|
|
407
|
+
var _options$entryPointUr;
|
|
408
|
+
const appName = wordify((_options$entryPointUr = options.entryPointUriPath) !== null && _options$entryPointUr !== void 0 ? _options$entryPointUr : options.projectDirectoryName);
|
|
377
409
|
return {
|
|
378
410
|
visitor: {
|
|
379
411
|
Identifier(nodePath) {
|
|
@@ -387,7 +419,7 @@ function replaceApplicationInfoInCustomApplicationConfig(filePath, options) {
|
|
|
387
419
|
}) && nodePath.parent.type === 'ObjectProperty') {
|
|
388
420
|
nodePath.parent.value = types.stringLiteral(options.initialProjectKey);
|
|
389
421
|
}
|
|
390
|
-
if (nodePath.isIdentifier({
|
|
422
|
+
if (options.applicationType === applicationTypes['custom-application'] && nodePath.isIdentifier({
|
|
391
423
|
name: 'defaultLabel'
|
|
392
424
|
})) {
|
|
393
425
|
const isMainMenuLinkParent = nodePath.findParent(parentPath => parentPath.isIdentifier({
|
|
@@ -411,12 +443,22 @@ function replaceApplicationInfoInCustomApplicationConfig(filePath, options) {
|
|
|
411
443
|
});
|
|
412
444
|
}
|
|
413
445
|
}
|
|
414
|
-
function
|
|
446
|
+
function getApplicationConfigName(options) {
|
|
447
|
+
switch (options.applicationType) {
|
|
448
|
+
case applicationTypes['custom-application']:
|
|
449
|
+
return 'custom-application-config';
|
|
450
|
+
case applicationTypes['custom-view']:
|
|
451
|
+
return 'custom-view-config';
|
|
452
|
+
default:
|
|
453
|
+
throw new Error("Unknown application type ".concat(options.applicationType));
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function updateApplicationConfig(options) {
|
|
415
457
|
return {
|
|
416
|
-
title: 'Updating
|
|
458
|
+
title: 'Updating application config file',
|
|
417
459
|
task: () => {
|
|
418
|
-
const
|
|
419
|
-
|
|
460
|
+
const configPath = resolveFilePathByExtension(path.join(options.projectDirectoryPath, getApplicationConfigName(options)));
|
|
461
|
+
replaceApplicationInfoInApplicationConfig(configPath, options);
|
|
420
462
|
}
|
|
421
463
|
};
|
|
422
464
|
}
|
|
@@ -447,6 +489,7 @@ function replaceEntryPointUriPathInConstants(filePath, options) {
|
|
|
447
489
|
function updateApplicationConstants(options) {
|
|
448
490
|
return {
|
|
449
491
|
title: 'Updating application constants',
|
|
492
|
+
enabled: options.applicationType === applicationTypes['custom-application'],
|
|
450
493
|
task: () => {
|
|
451
494
|
const applicationConstantsPath = resolveFilePathByExtension(path.join(options.projectDirectoryPath, 'src/constants'));
|
|
452
495
|
replaceEntryPointUriPathInConstants(applicationConstantsPath, options);
|
|
@@ -465,8 +508,10 @@ process.on('unhandledRejection', err => {
|
|
|
465
508
|
});
|
|
466
509
|
const run = () => {
|
|
467
510
|
// Default command
|
|
468
|
-
cli.command('[project-directory]').usage('[project-directory]\n\n Bootstraps a new Custom Application project using one of the predefined templates.').option('--
|
|
469
|
-
default: '
|
|
511
|
+
cli.command('[project-directory]').usage('[project-directory]\n\n Bootstraps a new Custom Application project using one of the predefined templates.').option('--application-type <type>', '(optional) The type of the application to create: custom-application (default) or custom-view.', {
|
|
512
|
+
default: applicationTypes['custom-application']
|
|
513
|
+
}).option('--template <name>', '(optional) The name of the template to install.', {
|
|
514
|
+
default: availableTemplates.starter
|
|
470
515
|
}).option('--template-version <version>', '(optional) The version of the template to install (either a git tag or a git branch of the "commercetools/merchant-center-application-kit" repository).', {
|
|
471
516
|
default: 'main'
|
|
472
517
|
}).option('--skip-install', '(optional) Skip installing the dependencies after cloning the template.', {
|
|
@@ -482,17 +527,18 @@ const run = () => {
|
|
|
482
527
|
const releaseVersion = await getLatestReleaseVersion();
|
|
483
528
|
hintOutdatedVersion(pkgJson.version, releaseVersion);
|
|
484
529
|
console.log('');
|
|
485
|
-
console.log(
|
|
530
|
+
console.log( // TODO: Use link based on the application type
|
|
531
|
+
"Documentation available at https://docs.commercetools.com/custom-applications");
|
|
486
532
|
console.log('');
|
|
487
533
|
const taskOptions = await processOptions(projectDirectory, options);
|
|
488
534
|
const shouldInstallDependencies = !options.skipInstall ||
|
|
489
535
|
// TODO: remove once we manage to ensure the package manager is installed, for example via Corepack.
|
|
490
536
|
options.packageManager === 'pnpm';
|
|
491
|
-
const taskList = new Listr(_filterInstanceProperty(_context = [downloadTemplate(taskOptions), updatePackageJson(taskOptions, releaseVersion),
|
|
537
|
+
const taskList = new Listr(_filterInstanceProperty(_context = [downloadTemplate(taskOptions), updatePackageJson(taskOptions, releaseVersion), updateApplicationConfig(taskOptions), updateApplicationConstants(taskOptions), shouldInstallDependencies && installDependencies(taskOptions)]).call(_context, Boolean));
|
|
492
538
|
await taskList.run();
|
|
493
539
|
const packageManager = getPreferredPackageManager(taskOptions);
|
|
494
540
|
console.log('');
|
|
495
|
-
console.log("\uD83C\uDF89 \uD83C\uDF89 \uD83C\uDF89 The
|
|
541
|
+
console.log("\uD83C\uDF89 \uD83C\uDF89 \uD83C\uDF89 The application has been created in the \"".concat(taskOptions.projectDirectoryName, "\" folder."));
|
|
496
542
|
console.log('');
|
|
497
543
|
console.log("To get started:");
|
|
498
544
|
console.log("$ cd ".concat(taskOptions.projectDirectoryName));
|
|
@@ -501,7 +547,8 @@ const run = () => {
|
|
|
501
547
|
}
|
|
502
548
|
console.log("$ ".concat(packageManager, " start"));
|
|
503
549
|
console.log('');
|
|
504
|
-
console.log(
|
|
550
|
+
console.log( // TODO: Use link based on the application type
|
|
551
|
+
"Visit https://docs.commercetools.com/custom-applications for more info about developing Custom Applications. Enjoy \uD83D\uDE80");
|
|
505
552
|
});
|
|
506
553
|
cli.help();
|
|
507
554
|
cli.version(pkgJson.version);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare const applicationTypes: {
|
|
2
|
+
readonly 'custom-application': "custom-application";
|
|
3
|
+
readonly 'custom-view': "custom-view";
|
|
4
|
+
};
|
|
5
|
+
declare const availableTemplates: {
|
|
6
|
+
readonly starter: "starter";
|
|
7
|
+
readonly 'starter-typescript': "starter-typescript";
|
|
8
|
+
};
|
|
9
|
+
export { applicationTypes, availableTemplates };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as downloadTemplate } from './download-template';
|
|
2
2
|
export { default as installDependencies } from './install-dependencies';
|
|
3
3
|
export { default as updatePackageJson } from './update-package-json';
|
|
4
|
-
export { default as
|
|
4
|
+
export { default as updateApplicationConfig } from './update-application-config';
|
|
5
5
|
export { default as updateApplicationConstants } from './update-application-constants';
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { applicationTypes, availableTemplates } from './constants';
|
|
1
2
|
export type TCliGlobalOptions = {
|
|
2
3
|
'--'?: string[];
|
|
3
4
|
};
|
|
4
|
-
export type
|
|
5
|
+
export type TApplicationType = keyof typeof applicationTypes;
|
|
6
|
+
export type TTemplate = keyof typeof availableTemplates;
|
|
5
7
|
export type TPackageManager = 'npm' | 'yarn' | 'pnpm';
|
|
6
8
|
export type TCliCommandOptions = {
|
|
9
|
+
applicationType: TApplicationType;
|
|
7
10
|
template: TTemplate;
|
|
8
11
|
templateVersion: string;
|
|
9
12
|
skipInstall: boolean;
|
|
@@ -13,11 +16,12 @@ export type TCliCommandOptions = {
|
|
|
13
16
|
packageManager?: TPackageManager;
|
|
14
17
|
};
|
|
15
18
|
export type TCliTaskOptions = {
|
|
19
|
+
applicationType: TApplicationType;
|
|
16
20
|
projectDirectoryName: string;
|
|
17
21
|
projectDirectoryPath: string;
|
|
18
22
|
templateName: TCliCommandOptions['template'];
|
|
19
23
|
tagOrBranchVersion: string;
|
|
20
|
-
entryPointUriPath
|
|
24
|
+
entryPointUriPath?: string;
|
|
21
25
|
initialProjectKey: string;
|
|
22
26
|
packageManager: TCliCommandOptions['packageManager'];
|
|
23
27
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TCliTaskOptions, TPackageManager } from './types';
|
|
1
|
+
import type { TApplicationType, TCliTaskOptions, TPackageManager } from './types';
|
|
2
2
|
declare const isSemVer: (version: string) => boolean;
|
|
3
3
|
declare const shouldUseYarn: () => boolean;
|
|
4
4
|
declare const getPreferredPackageManager: (options: TCliTaskOptions) => TPackageManager;
|
|
@@ -7,4 +7,5 @@ declare const slugify: (name: string) => string;
|
|
|
7
7
|
declare const upperFirst: (value: string) => string;
|
|
8
8
|
declare const wordify: (slug: string) => string;
|
|
9
9
|
declare const resolveFilePathByExtension: (requestedModule: string) => string;
|
|
10
|
-
|
|
10
|
+
declare const isCustomView: (applicationType: TApplicationType) => boolean;
|
|
11
|
+
export { isSemVer, shouldUseYarn, slugify, wordify, upperFirst, resolveFilePathByExtension, getPreferredPackageManager, getInstallCommand, isCustomView, };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { TTemplate } from './types';
|
|
1
|
+
import type { TApplicationType, TTemplate } from './types';
|
|
2
|
+
declare const throwIfApplicationTypeIsNotSupported: (applicationType: TApplicationType) => void;
|
|
2
3
|
declare const throwIfTemplateIsNotSupported: (templateName: TTemplate) => void;
|
|
3
4
|
declare const throwIfProjectDirectoryExists: (dirName: string, dirPath: string) => void;
|
|
4
5
|
declare const throwIfTemplateVersionDoesNotExist: (templateName: string, templateFolderPath: string, versionToCheck: string) => void;
|
|
5
6
|
declare const throwIfInitialProjectKeyIsMissing: (initialProjectKey?: string) => void;
|
|
6
7
|
declare const throwIfNodeVersionIsNotSupported: (currentNodeVersion: string, expectedVersionRange: string) => void;
|
|
7
|
-
export { throwIfTemplateIsNotSupported, throwIfProjectDirectoryExists, throwIfTemplateVersionDoesNotExist, throwIfInitialProjectKeyIsMissing, throwIfNodeVersionIsNotSupported, };
|
|
8
|
+
export { throwIfApplicationTypeIsNotSupported, 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": "22.8.
|
|
3
|
+
"version": "22.8.2",
|
|
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": {
|
package/src/cli.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cac } from 'cac';
|
|
2
2
|
import { Listr, type ListrTask } from 'listr2';
|
|
3
3
|
import pkgJson from '../package.json';
|
|
4
|
+
import { applicationTypes, availableTemplates } from './constants';
|
|
4
5
|
import getLatestReleaseVersion from './get-latest-release-version';
|
|
5
6
|
import hintOutdatedVersion from './hint-outdated-version';
|
|
6
7
|
import processOptions from './process-options';
|
|
@@ -27,10 +28,15 @@ const run = () => {
|
|
|
27
28
|
.usage(
|
|
28
29
|
'[project-directory]\n\n Bootstraps a new Custom Application project using one of the predefined templates.'
|
|
29
30
|
)
|
|
31
|
+
.option(
|
|
32
|
+
'--application-type <type>',
|
|
33
|
+
'(optional) The type of the application to create: custom-application (default) or custom-view.',
|
|
34
|
+
{ default: applicationTypes['custom-application'] }
|
|
35
|
+
)
|
|
30
36
|
.option(
|
|
31
37
|
'--template <name>',
|
|
32
38
|
'(optional) The name of the template to install.',
|
|
33
|
-
{ default:
|
|
39
|
+
{ default: availableTemplates.starter }
|
|
34
40
|
)
|
|
35
41
|
.option(
|
|
36
42
|
'--template-version <version>',
|
|
@@ -71,6 +77,7 @@ const run = () => {
|
|
|
71
77
|
|
|
72
78
|
console.log('');
|
|
73
79
|
console.log(
|
|
80
|
+
// TODO: Use link based on the application type
|
|
74
81
|
`Documentation available at https://docs.commercetools.com/custom-applications`
|
|
75
82
|
);
|
|
76
83
|
console.log('');
|
|
@@ -86,7 +93,7 @@ const run = () => {
|
|
|
86
93
|
[
|
|
87
94
|
tasks.downloadTemplate(taskOptions),
|
|
88
95
|
tasks.updatePackageJson(taskOptions, releaseVersion),
|
|
89
|
-
tasks.
|
|
96
|
+
tasks.updateApplicationConfig(taskOptions),
|
|
90
97
|
tasks.updateApplicationConstants(taskOptions),
|
|
91
98
|
shouldInstallDependencies && tasks.installDependencies(taskOptions),
|
|
92
99
|
].filter(Boolean) as ListrTask[]
|
|
@@ -97,7 +104,7 @@ const run = () => {
|
|
|
97
104
|
|
|
98
105
|
console.log('');
|
|
99
106
|
console.log(
|
|
100
|
-
`🎉 🎉 🎉 The
|
|
107
|
+
`🎉 🎉 🎉 The application has been created in the "${taskOptions.projectDirectoryName}" folder.`
|
|
101
108
|
);
|
|
102
109
|
console.log('');
|
|
103
110
|
console.log(`To get started:`);
|
|
@@ -108,6 +115,7 @@ const run = () => {
|
|
|
108
115
|
console.log(`$ ${packageManager} start`);
|
|
109
116
|
console.log('');
|
|
110
117
|
console.log(
|
|
118
|
+
// TODO: Use link based on the application type
|
|
111
119
|
`Visit https://docs.commercetools.com/custom-applications for more info about developing Custom Applications. Enjoy 🚀`
|
|
112
120
|
);
|
|
113
121
|
});
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const applicationTypes = {
|
|
2
|
+
'custom-application': 'custom-application',
|
|
3
|
+
'custom-view': 'custom-view',
|
|
4
|
+
} as const;
|
|
5
|
+
|
|
6
|
+
const availableTemplates = {
|
|
7
|
+
starter: 'starter',
|
|
8
|
+
'starter-typescript': 'starter-typescript',
|
|
9
|
+
} as const;
|
|
10
|
+
|
|
11
|
+
export { applicationTypes, availableTemplates };
|
package/src/process-options.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import readline, { type Interface } from 'readline';
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import readline, { type Interface } from 'node:readline';
|
|
4
|
+
import { applicationTypes } from './constants';
|
|
4
5
|
import type { TCliCommandOptions, TCliTaskOptions } from './types';
|
|
5
6
|
import { isSemVer } from './utils';
|
|
6
7
|
import {
|
|
7
8
|
throwIfTemplateIsNotSupported,
|
|
8
9
|
throwIfProjectDirectoryExists,
|
|
9
10
|
throwIfInitialProjectKeyIsMissing,
|
|
11
|
+
throwIfApplicationTypeIsNotSupported,
|
|
10
12
|
} from './validations';
|
|
11
13
|
|
|
12
14
|
const question = (rl: Interface, value: string) =>
|
|
@@ -16,6 +18,10 @@ const getEntryPointUriPath = async (
|
|
|
16
18
|
rl: Interface,
|
|
17
19
|
options: TCliCommandOptions
|
|
18
20
|
) => {
|
|
21
|
+
if (options.applicationType === applicationTypes['custom-view']) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
if (options.entryPointUriPath) {
|
|
20
26
|
return options.entryPointUriPath;
|
|
21
27
|
}
|
|
@@ -72,6 +78,7 @@ async function processOptions(
|
|
|
72
78
|
const templateName = options.template;
|
|
73
79
|
|
|
74
80
|
// Validate options
|
|
81
|
+
throwIfApplicationTypeIsNotSupported(options.applicationType);
|
|
75
82
|
throwIfProjectDirectoryExists(projectDirectoryName, projectDirectoryPath);
|
|
76
83
|
throwIfTemplateIsNotSupported(templateName);
|
|
77
84
|
|
|
@@ -85,6 +92,7 @@ async function processOptions(
|
|
|
85
92
|
rl.close();
|
|
86
93
|
|
|
87
94
|
return {
|
|
95
|
+
applicationType: options.applicationType,
|
|
88
96
|
projectDirectoryName,
|
|
89
97
|
projectDirectoryPath,
|
|
90
98
|
templateName,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
import path from 'path';
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import execa from 'execa';
|
|
5
5
|
import { Listr, type ListrTask } from 'listr2';
|
|
6
|
+
import { applicationTypes } from '../constants';
|
|
6
7
|
import type { TCliTaskOptions } from '../types';
|
|
7
8
|
import { throwIfTemplateVersionDoesNotExist } from '../validations';
|
|
8
9
|
|
|
@@ -26,7 +27,9 @@ function downloadTemplate(options: TCliTaskOptions): ListrTask {
|
|
|
26
27
|
);
|
|
27
28
|
const templateFolderPath = path.join(
|
|
28
29
|
clonedRepositoryPath,
|
|
29
|
-
'
|
|
30
|
+
options.applicationType === applicationTypes['custom-view']
|
|
31
|
+
? 'custom-views-templates'
|
|
32
|
+
: 'application-templates',
|
|
30
33
|
options.templateName
|
|
31
34
|
);
|
|
32
35
|
return new Listr([
|
package/src/tasks/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as downloadTemplate } from './download-template';
|
|
2
2
|
export { default as installDependencies } from './install-dependencies';
|
|
3
3
|
export { default as updatePackageJson } from './update-package-json';
|
|
4
|
-
export { default as
|
|
4
|
+
export { default as updateApplicationConfig } from './update-application-config';
|
|
5
5
|
export { default as updateApplicationConstants } from './update-application-constants';
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
import path from 'path';
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import { transformFileSync, types, type PluginItem } from '@babel/core';
|
|
5
5
|
import type { ListrTask } from 'listr2';
|
|
6
6
|
import prettier from 'prettier';
|
|
7
|
+
import { applicationTypes } from '../constants';
|
|
7
8
|
import type { TCliTaskOptions } from '../types';
|
|
8
9
|
import { wordify, resolveFilePathByExtension } from '../utils';
|
|
9
10
|
|
|
10
|
-
function
|
|
11
|
+
function replaceApplicationInfoInApplicationConfig(
|
|
11
12
|
filePath: string,
|
|
12
13
|
options: TCliTaskOptions
|
|
13
14
|
) {
|
|
14
|
-
const appName = wordify(options.entryPointUriPath);
|
|
15
|
-
|
|
16
15
|
const result = transformFileSync(filePath, {
|
|
17
16
|
plugins: [
|
|
18
|
-
function
|
|
17
|
+
function replaceConfig(): PluginItem {
|
|
18
|
+
const appName = wordify(
|
|
19
|
+
options.entryPointUriPath ?? options.projectDirectoryName
|
|
20
|
+
);
|
|
19
21
|
return {
|
|
20
22
|
visitor: {
|
|
21
23
|
Identifier(nodePath) {
|
|
@@ -33,7 +35,11 @@ function replaceApplicationInfoInCustomApplicationConfig(
|
|
|
33
35
|
options.initialProjectKey
|
|
34
36
|
);
|
|
35
37
|
}
|
|
36
|
-
if (
|
|
38
|
+
if (
|
|
39
|
+
options.applicationType ===
|
|
40
|
+
applicationTypes['custom-application'] &&
|
|
41
|
+
nodePath.isIdentifier({ name: 'defaultLabel' })
|
|
42
|
+
) {
|
|
37
43
|
const isMainMenuLinkParent = nodePath.findParent((parentPath) =>
|
|
38
44
|
parentPath.isIdentifier({
|
|
39
45
|
name: 'mainMenuLink',
|
|
@@ -68,19 +74,30 @@ function replaceApplicationInfoInCustomApplicationConfig(
|
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
76
|
|
|
71
|
-
function
|
|
77
|
+
function getApplicationConfigName(options: TCliTaskOptions) {
|
|
78
|
+
switch (options.applicationType) {
|
|
79
|
+
case applicationTypes['custom-application']:
|
|
80
|
+
return 'custom-application-config';
|
|
81
|
+
case applicationTypes['custom-view']:
|
|
82
|
+
return 'custom-view-config';
|
|
83
|
+
default:
|
|
84
|
+
throw new Error(`Unknown application type ${options.applicationType}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function updateApplicationConfig(options: TCliTaskOptions): ListrTask {
|
|
72
89
|
return {
|
|
73
|
-
title: 'Updating
|
|
90
|
+
title: 'Updating application config file',
|
|
74
91
|
task: () => {
|
|
75
|
-
const
|
|
76
|
-
path.join(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
options
|
|
92
|
+
const configPath = resolveFilePathByExtension(
|
|
93
|
+
path.join(
|
|
94
|
+
options.projectDirectoryPath,
|
|
95
|
+
getApplicationConfigName(options)
|
|
96
|
+
)
|
|
81
97
|
);
|
|
98
|
+
replaceApplicationInfoInApplicationConfig(configPath, options);
|
|
82
99
|
},
|
|
83
100
|
};
|
|
84
101
|
}
|
|
85
102
|
|
|
86
|
-
export default
|
|
103
|
+
export default updateApplicationConfig;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
import path from 'path';
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import { type PluginItem, transformFileSync, types } from '@babel/core';
|
|
5
5
|
import type { ListrTask } from 'listr2';
|
|
6
6
|
import prettier from 'prettier';
|
|
7
|
+
import { applicationTypes } from '../constants';
|
|
7
8
|
import type { TCliTaskOptions } from '../types';
|
|
8
9
|
import { resolveFilePathByExtension } from '../utils';
|
|
9
10
|
|
|
@@ -22,7 +23,7 @@ function replaceEntryPointUriPathInConstants(
|
|
|
22
23
|
nodePath.node.id.name === 'entryPointUriPath'
|
|
23
24
|
) {
|
|
24
25
|
nodePath.node.init = types.stringLiteral(
|
|
25
|
-
options.entryPointUriPath
|
|
26
|
+
options.entryPointUriPath!
|
|
26
27
|
);
|
|
27
28
|
}
|
|
28
29
|
},
|
|
@@ -50,6 +51,7 @@ function replaceEntryPointUriPathInConstants(
|
|
|
50
51
|
function updateApplicationConstants(options: TCliTaskOptions): ListrTask {
|
|
51
52
|
return {
|
|
52
53
|
title: 'Updating application constants',
|
|
54
|
+
enabled: options.applicationType === applicationTypes['custom-application'],
|
|
53
55
|
task: () => {
|
|
54
56
|
const applicationConstantsPath = resolveFilePathByExtension(
|
|
55
57
|
path.join(options.projectDirectoryPath, 'src/constants')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
import path from 'path';
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import type { ListrTask } from 'listr2';
|
|
5
5
|
import type { TCliTaskOptions } from '../types';
|
|
6
6
|
import { getPreferredPackageManager, slugify } from '../utils';
|