@commercetools-frontend/create-mc-app 22.2.0 → 22.3.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 +12 -0
- package/dist/commercetools-frontend-create-mc-app.cjs.dev.js +48 -91
- package/dist/commercetools-frontend-create-mc-app.cjs.prod.js +48 -91
- package/dist/commercetools-frontend-create-mc-app.esm.js +48 -91
- package/dist/declarations/src/types.d.ts +5 -1
- package/dist/declarations/src/utils.d.ts +3 -1
- package/dist/declarations/src/validations.d.ts +2 -2
- package/package.json +10 -3
- package/src/cli.ts +15 -6
- package/src/process-options.ts +1 -0
- package/src/tasks/install-dependencies.ts +3 -3
- package/src/tasks/update-package-json.ts +8 -1
- package/src/types.ts +6 -1
- package/src/utils.ts +16 -0
- package/src/validations.ts +2 -4
|
@@ -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.
|
|
36
|
+
version: "22.3.0",
|
|
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: {
|
|
@@ -59,6 +59,8 @@ var pkgJson = {
|
|
|
59
59
|
"@babel/core": "^7.20.12",
|
|
60
60
|
"@babel/runtime": "^7.20.13",
|
|
61
61
|
"@babel/runtime-corejs3": "^7.20.13",
|
|
62
|
+
"@types/babel__core": "^7.20.0",
|
|
63
|
+
"@types/semver": "^7.5.0",
|
|
62
64
|
cac: "6.7.14",
|
|
63
65
|
execa: "5.1.1",
|
|
64
66
|
listr2: "5.0.8",
|
|
@@ -83,14 +85,10 @@ async function getLatestReleaseVersion() {
|
|
|
83
85
|
|
|
84
86
|
function hintOutdatedVersion(currentVersion, releaseVersion) {
|
|
85
87
|
var _context;
|
|
86
|
-
|
|
87
88
|
const hasBeenReleastedInLatestTag = semver.gt(releaseVersion, currentVersion);
|
|
88
|
-
|
|
89
89
|
const hintNewerVersions = _filterInstanceProperty(_context = [hasBeenReleastedInLatestTag && "".concat(releaseVersion)]).call(_context, Boolean).join(', ');
|
|
90
|
-
|
|
91
90
|
if (hintNewerVersions.length > 0) {
|
|
92
91
|
var _context2;
|
|
93
|
-
|
|
94
92
|
console.log('');
|
|
95
93
|
console.log(_concatInstanceProperty(_context2 = "New version available! ".concat(currentVersion, " -> ")).call(_context2, hintNewerVersions));
|
|
96
94
|
console.log('');
|
|
@@ -98,7 +96,6 @@ function hintOutdatedVersion(currentVersion, releaseVersion) {
|
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
const isSemVer = version => /^(v?)([0-9].[0-9].[0-9])+/.test(version);
|
|
101
|
-
|
|
102
99
|
const shouldUseYarn = () => {
|
|
103
100
|
try {
|
|
104
101
|
const result = execa.commandSync('yarn --version', {
|
|
@@ -109,28 +106,30 @@ const shouldUseYarn = () => {
|
|
|
109
106
|
return false;
|
|
110
107
|
}
|
|
111
108
|
};
|
|
112
|
-
|
|
109
|
+
const getPreferredPackageManager = options => {
|
|
110
|
+
if (options.packageManager) {
|
|
111
|
+
return options.packageManager;
|
|
112
|
+
}
|
|
113
|
+
// Attempt to use yarn (backwards compatibility)
|
|
114
|
+
if (shouldUseYarn()) {
|
|
115
|
+
return 'yarn';
|
|
116
|
+
}
|
|
117
|
+
// Fall back to npm
|
|
118
|
+
return 'npm';
|
|
119
|
+
};
|
|
113
120
|
const slugify = name => name.toLowerCase().replace(/_/gi, '-');
|
|
114
|
-
|
|
115
121
|
const upperFirst = value => value.charAt(0).toUpperCase() + _sliceInstanceProperty(value).call(value, 1);
|
|
116
|
-
|
|
117
122
|
const wordify = slug => {
|
|
118
123
|
var _context;
|
|
119
|
-
|
|
120
124
|
return _mapInstanceProperty(_context = slug.split('-')).call(_context, word => upperFirst(word)).join(' ');
|
|
121
125
|
};
|
|
122
|
-
|
|
123
126
|
const resolveFilePathByExtension = requestedModule => {
|
|
124
127
|
var _context2, _context4;
|
|
125
|
-
|
|
126
128
|
const fileExtension = _findInstanceProperty(_context2 = ['.js', '.ts', '.mjs', '.cjs']).call(_context2, ext => {
|
|
127
129
|
var _context3;
|
|
128
|
-
|
|
129
130
|
const filePath = _concatInstanceProperty(_context3 = "".concat(requestedModule)).call(_context3, ext);
|
|
130
|
-
|
|
131
131
|
return fs.existsSync(filePath);
|
|
132
132
|
});
|
|
133
|
-
|
|
134
133
|
return _concatInstanceProperty(_context4 = "".concat(requestedModule)).call(_context4, fileExtension);
|
|
135
134
|
};
|
|
136
135
|
|
|
@@ -138,112 +137,91 @@ const availableTemplates = {
|
|
|
138
137
|
starter: 'starter',
|
|
139
138
|
'starter-typescript': 'starter-typescript'
|
|
140
139
|
};
|
|
141
|
-
|
|
142
140
|
const throwIfTemplateIsNotSupported = templateName => {
|
|
143
141
|
var _context;
|
|
144
|
-
|
|
145
142
|
switch (templateName) {
|
|
146
143
|
case availableTemplates.starter:
|
|
147
144
|
case availableTemplates['starter-typescript']:
|
|
148
145
|
break;
|
|
149
|
-
|
|
150
146
|
default:
|
|
151
147
|
const templateNamesList = _Object$keys(availableTemplates).toString();
|
|
152
|
-
|
|
153
148
|
throw new Error(_concatInstanceProperty(_context = "The provided template name \"".concat(templateName, "\" does not exist. Available templates are \"")).call(_context, templateNamesList, "\". Make sure you are also using the latest version of \"@commercetools-frontend/create-mc-app\"."));
|
|
154
149
|
}
|
|
155
150
|
};
|
|
156
|
-
|
|
157
151
|
const throwIfProjectDirectoryExists = (dirName, dirPath) => {
|
|
158
152
|
if (fs.existsSync(dirPath)) {
|
|
159
153
|
var _context2;
|
|
160
|
-
|
|
161
154
|
throw new Error(_concatInstanceProperty(_context2 = "A directory named \"".concat(dirName, "\" already exists at this location \"")).call(_context2, dirPath, "\". Please choose a different project name or remove the directory, then try running the command again."));
|
|
162
155
|
}
|
|
163
156
|
};
|
|
164
|
-
|
|
165
157
|
const throwIfTemplateVersionDoesNotExist = (templateName, templateFolderPath, versionToCheck) => {
|
|
166
158
|
if (!fs.existsSync(templateFolderPath)) {
|
|
167
159
|
var _context3;
|
|
168
|
-
|
|
169
160
|
throw new Error(_concatInstanceProperty(_context3 = "The downloaded template \"".concat(templateName, "\" does not exist for the given version \"")).call(_context3, versionToCheck, "\". Check the releases page if you are looking for a specific version: https://github.com/commercetools/merchant-center-application-kit/releases"));
|
|
170
|
-
}
|
|
161
|
+
}
|
|
162
|
+
// In case the version is semver (usually release tags) we check that
|
|
171
163
|
// the cloned repository contains the template matching the given version
|
|
172
|
-
|
|
173
|
-
|
|
174
164
|
if (isSemVer(versionToCheck)) {
|
|
175
165
|
const templatePackageJson = JSON.parse(fs.readFileSync(path.join(templateFolderPath, 'package.json'), {
|
|
176
166
|
encoding: 'utf8'
|
|
177
167
|
}));
|
|
178
168
|
const versionAsNumber = versionToCheck.replace('v', '');
|
|
179
|
-
|
|
180
169
|
if (templatePackageJson.version !== versionAsNumber) {
|
|
181
170
|
var _context4, _context5;
|
|
182
|
-
|
|
183
171
|
throw new Error(_concatInstanceProperty(_context4 = _concatInstanceProperty(_context5 = "The downloaded template \"".concat(templateName, "\" does not match the version \"")).call(_context5, versionAsNumber, "\", instead got \"")).call(_context4, templatePackageJson.version, "\". Check the releases page if you want to provide a specific version: https://github.com/commercetools/merchant-center-application-kit/releases"));
|
|
184
172
|
}
|
|
185
173
|
}
|
|
186
174
|
};
|
|
187
|
-
|
|
188
175
|
const throwIfInitialProjectKeyIsMissing = initialProjectKey => {
|
|
189
176
|
if (!initialProjectKey) {
|
|
190
177
|
throw new Error("Provide a valid project key that you have access to.");
|
|
191
178
|
}
|
|
192
179
|
};
|
|
193
|
-
|
|
194
180
|
const throwIfNodeVersionIsNotSupported = (currentNodeVersion, expectedVersionRange) => {
|
|
195
181
|
const hasValidNodeVersion = semver.satisfies(currentNodeVersion, expectedVersionRange);
|
|
196
|
-
|
|
197
182
|
if (!hasValidNodeVersion) {
|
|
198
183
|
var _context6;
|
|
199
|
-
|
|
200
184
|
throw new Error(_concatInstanceProperty(_context6 = "You are running Node ".concat(currentNodeVersion, " but create-mc-app requires Node ")).call(_context6, expectedVersionRange, ". Please update your version of Node."));
|
|
201
185
|
}
|
|
202
186
|
};
|
|
203
187
|
|
|
204
188
|
const question = (rl, value) => new _Promise(resolve => rl.question(value, resolve));
|
|
205
|
-
|
|
206
189
|
const getEntryPointUriPath = async (rl, options) => {
|
|
207
190
|
var _context;
|
|
208
|
-
|
|
209
191
|
if (options.entryPointUriPath) {
|
|
210
192
|
return options.entryPointUriPath;
|
|
211
193
|
}
|
|
212
|
-
|
|
213
194
|
const randomEntryPointUriPath = _concatInstanceProperty(_context = "".concat(options.template, "-")).call(_context, crypto.randomBytes(3).toString('hex'));
|
|
214
|
-
|
|
215
195
|
if (options.yes) {
|
|
216
196
|
return randomEntryPointUriPath;
|
|
217
197
|
}
|
|
218
|
-
|
|
219
198
|
const answerEntryPointUriPath = await question(rl, "Provide the Custom Application entryPointUriPath (default \"".concat(randomEntryPointUriPath, "\"): "));
|
|
220
199
|
return answerEntryPointUriPath || randomEntryPointUriPath;
|
|
221
200
|
};
|
|
222
|
-
|
|
223
201
|
const getInitialProjectKey = async (rl, options) => {
|
|
224
202
|
if (options.initialProjectKey) {
|
|
225
203
|
return options.initialProjectKey;
|
|
226
204
|
}
|
|
227
|
-
|
|
228
205
|
const initialProjectKey = await question(rl, "Provide the initial project key for local development: ");
|
|
229
206
|
throwIfInitialProjectKeyIsMissing(initialProjectKey);
|
|
230
207
|
return initialProjectKey;
|
|
231
208
|
};
|
|
232
|
-
|
|
233
209
|
async function processOptions(projectDirectoryName, options) {
|
|
234
210
|
if (!projectDirectoryName) {
|
|
235
211
|
throw new Error('Missing required argument "[project-directory]"');
|
|
236
212
|
}
|
|
213
|
+
const projectDirectoryPath = path.resolve(projectDirectoryName);
|
|
237
214
|
|
|
238
|
-
|
|
239
|
-
|
|
215
|
+
// Parse options
|
|
240
216
|
let tagOrBranchVersion = options.templateVersion || 'main';
|
|
241
217
|
tagOrBranchVersion = isSemVer(tagOrBranchVersion) && !_startsWithInstanceProperty(tagOrBranchVersion).call(tagOrBranchVersion, 'v') ? "v".concat(tagOrBranchVersion) : tagOrBranchVersion;
|
|
242
|
-
const templateName = options.template;
|
|
218
|
+
const templateName = options.template;
|
|
243
219
|
|
|
220
|
+
// Validate options
|
|
244
221
|
throwIfProjectDirectoryExists(projectDirectoryName, projectDirectoryPath);
|
|
245
|
-
throwIfTemplateIsNotSupported(templateName);
|
|
222
|
+
throwIfTemplateIsNotSupported(templateName);
|
|
246
223
|
|
|
224
|
+
// Read prompts
|
|
247
225
|
const rl = readline.createInterface({
|
|
248
226
|
input: process.stdin,
|
|
249
227
|
output: process.stdout
|
|
@@ -257,18 +235,17 @@ async function processOptions(projectDirectoryName, options) {
|
|
|
257
235
|
templateName,
|
|
258
236
|
tagOrBranchVersion,
|
|
259
237
|
entryPointUriPath,
|
|
260
|
-
initialProjectKey
|
|
238
|
+
initialProjectKey,
|
|
239
|
+
packageManager: options.packageManager
|
|
261
240
|
};
|
|
262
241
|
}
|
|
263
242
|
|
|
264
243
|
const filesToBeRemoved = ['CHANGELOG.md'];
|
|
265
|
-
|
|
266
244
|
function downloadTemplate(options) {
|
|
267
245
|
return {
|
|
268
246
|
title: 'Downloading template',
|
|
269
247
|
task: () => {
|
|
270
248
|
var _context;
|
|
271
|
-
|
|
272
249
|
const tmpDir = os.tmpdir();
|
|
273
250
|
const tmpFolderNameForClonedRepository = ['merchant-center-application-kit', '--', options.tagOrBranchVersion, '--', _Date$now().toString()].join('');
|
|
274
251
|
const clonedRepositoryPath = path.join(tmpDir, tmpFolderNameForClonedRepository);
|
|
@@ -281,11 +258,9 @@ function downloadTemplate(options) {
|
|
|
281
258
|
cwd: tmpDir,
|
|
282
259
|
encoding: 'utf-8'
|
|
283
260
|
});
|
|
284
|
-
|
|
285
261
|
if (result.failed) {
|
|
286
262
|
throw new Error(result.stderr);
|
|
287
263
|
}
|
|
288
|
-
|
|
289
264
|
throwIfTemplateVersionDoesNotExist(options.templateName, clonedRepositoryPath, options.tagOrBranchVersion);
|
|
290
265
|
return result.stdout;
|
|
291
266
|
}
|
|
@@ -293,21 +268,18 @@ function downloadTemplate(options) {
|
|
|
293
268
|
title: _concatInstanceProperty(_context = "Copying template ".concat(options.templateName, " into project directory ")).call(_context, options.projectDirectoryPath),
|
|
294
269
|
task: async () => {
|
|
295
270
|
const command = process.platform === 'win32' || process.platform === 'cygwin' ? 'move' : 'mv';
|
|
296
|
-
const result = await execa(command, [templateFolderPath,
|
|
271
|
+
const result = await execa(command, [templateFolderPath,
|
|
272
|
+
// Wrap folder path in quotes to avoid issues with empty spaces in the folder names.
|
|
297
273
|
options.projectDirectoryPath], {
|
|
298
274
|
encoding: 'utf-8'
|
|
299
275
|
});
|
|
300
|
-
|
|
301
276
|
if (result.failed) {
|
|
302
277
|
throw new Error(result.stderr);
|
|
303
278
|
}
|
|
304
|
-
|
|
305
279
|
const templatePackageJsonPath = path.join(options.projectDirectoryPath, 'package.json');
|
|
306
|
-
|
|
307
280
|
if (!fs.existsSync(templatePackageJsonPath)) {
|
|
308
281
|
throw new Error("Unable to verify that the template application has a package.json at \"".concat(templatePackageJsonPath, "\""));
|
|
309
282
|
}
|
|
310
|
-
|
|
311
283
|
return result.stdout;
|
|
312
284
|
}
|
|
313
285
|
}, {
|
|
@@ -317,11 +289,9 @@ function downloadTemplate(options) {
|
|
|
317
289
|
const result = await execa(command, _mapInstanceProperty(filesToBeRemoved).call(filesToBeRemoved, filePath => path.join(options.projectDirectoryPath, filePath)), {
|
|
318
290
|
encoding: 'utf-8'
|
|
319
291
|
});
|
|
320
|
-
|
|
321
292
|
if (result.failed) {
|
|
322
293
|
throw new Error(result.stderr);
|
|
323
294
|
}
|
|
324
|
-
|
|
325
295
|
return result.stdout;
|
|
326
296
|
}
|
|
327
297
|
}]);
|
|
@@ -333,10 +303,10 @@ function installDependencies(options) {
|
|
|
333
303
|
return {
|
|
334
304
|
title: 'Installing dependencies (this might take a while)',
|
|
335
305
|
task: () => {
|
|
336
|
-
const
|
|
337
|
-
const packageManager = useYarn ? 'yarn' : 'npm'; // TODO: we could check for min yarn/npm versions
|
|
338
|
-
// See https://github.com/facebook/create-react-app/blob/0f4781e8507249ce29a9ac1409fece67c1a53c38/packages/create-react-app/createReactApp.js#L225-L254
|
|
306
|
+
const packageManager = getPreferredPackageManager(options);
|
|
339
307
|
|
|
308
|
+
// TODO: we could check for min yarn/npm versions
|
|
309
|
+
// See https://github.com/facebook/create-react-app/blob/0f4781e8507249ce29a9ac1409fece67c1a53c38/packages/create-react-app/createReactApp.js#L225-L254
|
|
340
310
|
return execa(packageManager, ['install'], {
|
|
341
311
|
cwd: options.projectDirectoryPath,
|
|
342
312
|
encoding: 'utf-8'
|
|
@@ -346,25 +316,20 @@ function installDependencies(options) {
|
|
|
346
316
|
}
|
|
347
317
|
|
|
348
318
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
349
|
-
|
|
350
319
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context2, _context3; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context2 = ownKeys(Object(source), !0)).call(_context2, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context3 = ownKeys(Object(source))).call(_context3, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
351
|
-
|
|
352
320
|
const replaceApplicationKitPackageVersionWith = function (releaseVersion) {
|
|
353
321
|
var _context;
|
|
354
|
-
|
|
355
322
|
let dependencies = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
356
323
|
return _reduceInstanceProperty(_context = _Object$entries(dependencies)).call(_context, (updatedDependencies, _ref) => {
|
|
357
324
|
let _ref2 = _slicedToArray(_ref, 2),
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
325
|
+
dependencyName = _ref2[0],
|
|
326
|
+
dependencyVersion = _ref2[1];
|
|
361
327
|
const updatedVersion = dependencyVersion === 'workspace:*' ? releaseVersion : dependencyVersion;
|
|
362
328
|
return _objectSpread(_objectSpread({}, updatedDependencies), {}, {
|
|
363
329
|
[dependencyName]: updatedVersion
|
|
364
330
|
});
|
|
365
331
|
}, {});
|
|
366
332
|
};
|
|
367
|
-
|
|
368
333
|
function updatePackageJson(options, releaseVersion) {
|
|
369
334
|
return {
|
|
370
335
|
title: 'Updating package.json',
|
|
@@ -373,7 +338,7 @@ function updatePackageJson(options, releaseVersion) {
|
|
|
373
338
|
const appPackageJson = JSON.parse(fs.readFileSync(packageJsonPath, {
|
|
374
339
|
encoding: 'utf8'
|
|
375
340
|
}));
|
|
376
|
-
|
|
341
|
+
const packageManager = getPreferredPackageManager(options);
|
|
377
342
|
const updatedAppPackageJson = _Object$assign({}, appPackageJson, {
|
|
378
343
|
version: '1.0.0',
|
|
379
344
|
// Given the package name is derived from the `projectDirectoryName`
|
|
@@ -384,9 +349,11 @@ function updatePackageJson(options, releaseVersion) {
|
|
|
384
349
|
description: '',
|
|
385
350
|
// Replace the package versions with the `workspace:` syntax to the real version.
|
|
386
351
|
dependencies: replaceApplicationKitPackageVersionWith(releaseVersion, appPackageJson.dependencies),
|
|
387
|
-
devDependencies: replaceApplicationKitPackageVersionWith(releaseVersion, appPackageJson.devDependencies)
|
|
352
|
+
devDependencies: replaceApplicationKitPackageVersionWith(releaseVersion, appPackageJson.devDependencies),
|
|
353
|
+
scripts: _objectSpread(_objectSpread({}, appPackageJson.scripts), {}, {
|
|
354
|
+
'start:prod:local': appPackageJson.scripts['start:prod:local'].replace('yarn', packageManager)
|
|
355
|
+
})
|
|
388
356
|
});
|
|
389
|
-
|
|
390
357
|
fs.writeFileSync(packageJsonPath, _JSON$stringify(updatedAppPackageJson, null, 2) + os.EOL, {
|
|
391
358
|
encoding: 'utf8'
|
|
392
359
|
});
|
|
@@ -406,32 +373,27 @@ function replaceApplicationInfoInCustomApplicationConfig(filePath, options) {
|
|
|
406
373
|
}) && nodePath.parent.type === 'ObjectProperty') {
|
|
407
374
|
nodePath.parent.value = types.stringLiteral(appName);
|
|
408
375
|
}
|
|
409
|
-
|
|
410
376
|
if (nodePath.isIdentifier({
|
|
411
377
|
name: 'initialProjectKey'
|
|
412
378
|
}) && nodePath.parent.type === 'ObjectProperty') {
|
|
413
379
|
nodePath.parent.value = types.stringLiteral(options.initialProjectKey);
|
|
414
380
|
}
|
|
415
|
-
|
|
416
381
|
if (nodePath.isIdentifier({
|
|
417
382
|
name: 'defaultLabel'
|
|
418
383
|
})) {
|
|
419
384
|
const isMainMenuLinkParent = nodePath.findParent(parentPath => parentPath.isIdentifier({
|
|
420
385
|
name: 'mainMenuLink'
|
|
421
386
|
}));
|
|
422
|
-
|
|
423
387
|
if (isMainMenuLinkParent && nodePath.parent.type === 'ObjectProperty') {
|
|
424
388
|
nodePath.parent.value = types.stringLiteral(appName);
|
|
425
389
|
}
|
|
426
390
|
}
|
|
427
391
|
}
|
|
428
|
-
|
|
429
392
|
}
|
|
430
393
|
};
|
|
431
394
|
}],
|
|
432
395
|
retainLines: true
|
|
433
396
|
});
|
|
434
|
-
|
|
435
397
|
if (result !== null && result !== void 0 && result.code) {
|
|
436
398
|
const prettierConfig = prettier.resolveConfig.sync(options.projectDirectoryPath);
|
|
437
399
|
const formattedData = prettier.format(result.code + os.EOL, prettierConfig !== null && prettierConfig !== void 0 ? prettierConfig : undefined);
|
|
@@ -440,7 +402,6 @@ function replaceApplicationInfoInCustomApplicationConfig(filePath, options) {
|
|
|
440
402
|
});
|
|
441
403
|
}
|
|
442
404
|
}
|
|
443
|
-
|
|
444
405
|
function updateCustomApplicationConfig(options) {
|
|
445
406
|
return {
|
|
446
407
|
title: 'Updating Custom Applications config',
|
|
@@ -461,13 +422,11 @@ function replaceEntryPointUriPathInConstants(filePath, options) {
|
|
|
461
422
|
nodePath.node.init = types.stringLiteral(options.entryPointUriPath);
|
|
462
423
|
}
|
|
463
424
|
}
|
|
464
|
-
|
|
465
425
|
}
|
|
466
426
|
};
|
|
467
427
|
}],
|
|
468
428
|
retainLines: true
|
|
469
429
|
});
|
|
470
|
-
|
|
471
430
|
if (result !== null && result !== void 0 && result.code) {
|
|
472
431
|
const prettierConfig = prettier.resolveConfig.sync(options.projectDirectoryPath);
|
|
473
432
|
const formattedData = prettier.format(result.code + os.EOL, prettierConfig !== null && prettierConfig !== void 0 ? prettierConfig : undefined);
|
|
@@ -476,7 +435,6 @@ function replaceEntryPointUriPathInConstants(filePath, options) {
|
|
|
476
435
|
});
|
|
477
436
|
}
|
|
478
437
|
}
|
|
479
|
-
|
|
480
438
|
function updateApplicationConstants(options) {
|
|
481
439
|
return {
|
|
482
440
|
title: 'Updating application constants',
|
|
@@ -488,14 +446,14 @@ function updateApplicationConstants(options) {
|
|
|
488
446
|
}
|
|
489
447
|
|
|
490
448
|
throwIfNodeVersionIsNotSupported(process.versions.node, pkgJson.engines.node);
|
|
491
|
-
const cli = cac('create-mc-app');
|
|
449
|
+
const cli = cac('create-mc-app');
|
|
450
|
+
|
|
451
|
+
// Makes the script crash on unhandled rejections instead of silently
|
|
492
452
|
// ignoring them. In the future, promise rejections that are not handled will
|
|
493
453
|
// terminate the Node.js process with a non-zero exit code.
|
|
494
|
-
|
|
495
454
|
process.on('unhandledRejection', err => {
|
|
496
455
|
throw err;
|
|
497
456
|
});
|
|
498
|
-
|
|
499
457
|
const run = () => {
|
|
500
458
|
// Default command
|
|
501
459
|
cli.command('[project-directory]').usage('[project-directory]\n\n Bootstraps a new Custom Application project using one of the predefined templates.').option('--template <name>', '(optional) The name of the template to install.', {
|
|
@@ -506,34 +464,33 @@ const run = () => {
|
|
|
506
464
|
default: false
|
|
507
465
|
}).option('--yes', '(optional) If set, the prompt options with default values will be skipped.', {
|
|
508
466
|
default: false
|
|
509
|
-
}).option('--entry-point-uri-path <value>', '(optional) The version of the template to install. (default: starter-<hash>)').option('--initial-project-key <value>', '(optional) A commercetools project key used for the initial login in development. By default, the value is prompted in the terminal.').action(async (projectDirectory, options) => {
|
|
467
|
+
}).option('--entry-point-uri-path <value>', '(optional) The version of the template to install. (default: starter-<hash>)').option('--initial-project-key <value>', '(optional) A commercetools project key used for the initial login in development. By default, the value is prompted in the terminal.').option('--package-manager <value>', '(optional) The preferred package manager to use: npm, yarn, pnpm.').action(async (projectDirectory, options) => {
|
|
510
468
|
var _context;
|
|
511
|
-
|
|
512
469
|
if (!projectDirectory) {
|
|
513
470
|
cli.outputHelp();
|
|
514
471
|
return;
|
|
515
472
|
}
|
|
516
|
-
|
|
517
473
|
const releaseVersion = await getLatestReleaseVersion();
|
|
518
474
|
hintOutdatedVersion(pkgJson.version, releaseVersion);
|
|
519
475
|
console.log('');
|
|
520
476
|
console.log("Documentation available at https://docs.commercetools.com/custom-applications");
|
|
521
477
|
console.log('');
|
|
522
478
|
const taskOptions = await processOptions(projectDirectory, options);
|
|
523
|
-
const
|
|
479
|
+
const shouldInstallDependencies = !options.skipInstall ||
|
|
480
|
+
// TODO: remove once we manage to ensure the package manager is installed, for example via Corepack.
|
|
481
|
+
options.packageManager === 'pnpm';
|
|
482
|
+
const taskList = new Listr(_filterInstanceProperty(_context = [downloadTemplate(taskOptions), updatePackageJson(taskOptions, releaseVersion), updateCustomApplicationConfig(taskOptions), updateApplicationConstants(taskOptions), shouldInstallDependencies && installDependencies(taskOptions)]).call(_context, Boolean));
|
|
524
483
|
await taskList.run();
|
|
525
|
-
const
|
|
484
|
+
const packageManager = getPreferredPackageManager(taskOptions);
|
|
526
485
|
console.log('');
|
|
527
486
|
console.log("\uD83C\uDF89 \uD83C\uDF89 \uD83C\uDF89 The Custom Application has been created in the \"".concat(taskOptions.projectDirectoryName, "\" folder."));
|
|
528
487
|
console.log('');
|
|
529
488
|
console.log("To get started:");
|
|
530
489
|
console.log("$ cd ".concat(taskOptions.projectDirectoryName));
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
console.log("$ ".concat(useYarn ? 'yarn' : 'npm', " install"));
|
|
490
|
+
if (!shouldInstallDependencies) {
|
|
491
|
+
console.log("$ ".concat(packageManager, " install"));
|
|
534
492
|
}
|
|
535
|
-
|
|
536
|
-
console.log("$ ".concat(useYarn ? 'yarn' : 'npm', " start"));
|
|
493
|
+
console.log("$ ".concat(packageManager, " start"));
|
|
537
494
|
console.log('');
|
|
538
495
|
console.log("Visit https://docs.commercetools.com/custom-applications for more info about developing Custom Applications. Enjoy \uD83D\uDE80");
|
|
539
496
|
});
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
export type TCliGlobalOptions = {
|
|
2
2
|
'--'?: string[];
|
|
3
3
|
};
|
|
4
|
+
export type TTemplate = 'starter' | 'starter-typescript';
|
|
5
|
+
export type TPackageManager = 'npm' | 'yarn' | 'pnpm';
|
|
4
6
|
export type TCliCommandOptions = {
|
|
5
|
-
template:
|
|
7
|
+
template: TTemplate;
|
|
6
8
|
templateVersion: string;
|
|
7
9
|
skipInstall: boolean;
|
|
8
10
|
yes: boolean;
|
|
9
11
|
entryPointUriPath?: string;
|
|
10
12
|
initialProjectKey?: string;
|
|
13
|
+
packageManager?: TPackageManager;
|
|
11
14
|
};
|
|
12
15
|
export type TCliTaskOptions = {
|
|
13
16
|
projectDirectoryName: string;
|
|
@@ -16,4 +19,5 @@ export type TCliTaskOptions = {
|
|
|
16
19
|
tagOrBranchVersion: string;
|
|
17
20
|
entryPointUriPath: string;
|
|
18
21
|
initialProjectKey: string;
|
|
22
|
+
packageManager: TCliCommandOptions['packageManager'];
|
|
19
23
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { TCliTaskOptions, TPackageManager } from './types';
|
|
1
2
|
declare const isSemVer: (version: string) => boolean;
|
|
2
3
|
declare const shouldUseYarn: () => boolean;
|
|
4
|
+
declare const getPreferredPackageManager: (options: TCliTaskOptions) => TPackageManager;
|
|
3
5
|
declare const slugify: (name: string) => string;
|
|
4
6
|
declare const upperFirst: (value: string) => string;
|
|
5
7
|
declare const wordify: (slug: string) => string;
|
|
6
8
|
declare const resolveFilePathByExtension: (requestedModule: string) => string;
|
|
7
|
-
export { isSemVer, shouldUseYarn, slugify, wordify, upperFirst, resolveFilePathByExtension, };
|
|
9
|
+
export { isSemVer, shouldUseYarn, slugify, wordify, upperFirst, resolveFilePathByExtension, getPreferredPackageManager, };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
declare const throwIfTemplateIsNotSupported: (templateName:
|
|
1
|
+
import type { TTemplate } from './types';
|
|
2
|
+
declare const throwIfTemplateIsNotSupported: (templateName: TTemplate) => void;
|
|
3
3
|
declare const throwIfProjectDirectoryExists: (dirName: string, dirPath: string) => void;
|
|
4
4
|
declare const throwIfTemplateVersionDoesNotExist: (templateName: string, templateFolderPath: string, versionToCheck: string) => void;
|
|
5
5
|
declare const throwIfInitialProjectKeyIsMissing: (initialProjectKey?: string) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools-frontend/create-mc-app",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.3.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": {
|
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
"directory": "packages/create-mc-app"
|
|
10
10
|
},
|
|
11
11
|
"homepage": "https://docs.commercetools.com/custom-applications",
|
|
12
|
-
"keywords": [
|
|
12
|
+
"keywords": [
|
|
13
|
+
"javascript",
|
|
14
|
+
"frontend",
|
|
15
|
+
"react",
|
|
16
|
+
"toolkit"
|
|
17
|
+
],
|
|
13
18
|
"license": "MIT",
|
|
14
19
|
"publishConfig": {
|
|
15
20
|
"access": "public"
|
|
@@ -21,6 +26,8 @@
|
|
|
21
26
|
"@babel/core": "^7.20.12",
|
|
22
27
|
"@babel/runtime": "^7.20.13",
|
|
23
28
|
"@babel/runtime-corejs3": "^7.20.13",
|
|
29
|
+
"@types/babel__core": "^7.20.0",
|
|
30
|
+
"@types/semver": "^7.5.0",
|
|
24
31
|
"cac": "6.7.14",
|
|
25
32
|
"execa": "5.1.1",
|
|
26
33
|
"listr2": "5.0.8",
|
|
@@ -33,4 +40,4 @@
|
|
|
33
40
|
"engines": {
|
|
34
41
|
"node": "16.x || >=18.0.0"
|
|
35
42
|
}
|
|
36
|
-
}
|
|
43
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -6,7 +6,7 @@ import hintOutdatedVersion from './hint-outdated-version';
|
|
|
6
6
|
import processOptions from './process-options';
|
|
7
7
|
import * as tasks from './tasks';
|
|
8
8
|
import type { TCliCommandOptions } from './types';
|
|
9
|
-
import {
|
|
9
|
+
import { getPreferredPackageManager } from './utils';
|
|
10
10
|
import { throwIfNodeVersionIsNotSupported } from './validations';
|
|
11
11
|
|
|
12
12
|
throwIfNodeVersionIsNotSupported(process.versions.node, pkgJson.engines.node);
|
|
@@ -55,6 +55,10 @@ const run = () => {
|
|
|
55
55
|
'--initial-project-key <value>',
|
|
56
56
|
'(optional) A commercetools project key used for the initial login in development. By default, the value is prompted in the terminal.'
|
|
57
57
|
)
|
|
58
|
+
.option(
|
|
59
|
+
'--package-manager <value>',
|
|
60
|
+
'(optional) The preferred package manager to use: npm, yarn, pnpm.'
|
|
61
|
+
)
|
|
58
62
|
.action(async (projectDirectory, options: TCliCommandOptions) => {
|
|
59
63
|
if (!projectDirectory) {
|
|
60
64
|
cli.outputHelp();
|
|
@@ -73,18 +77,23 @@ const run = () => {
|
|
|
73
77
|
|
|
74
78
|
const taskOptions = await processOptions(projectDirectory, options);
|
|
75
79
|
|
|
80
|
+
const shouldInstallDependencies =
|
|
81
|
+
!options.skipInstall ||
|
|
82
|
+
// TODO: remove once we manage to ensure the package manager is installed, for example via Corepack.
|
|
83
|
+
options.packageManager === 'pnpm';
|
|
84
|
+
|
|
76
85
|
const taskList = new Listr(
|
|
77
86
|
[
|
|
78
87
|
tasks.downloadTemplate(taskOptions),
|
|
79
88
|
tasks.updatePackageJson(taskOptions, releaseVersion),
|
|
80
89
|
tasks.updateCustomApplicationConfig(taskOptions),
|
|
81
90
|
tasks.updateApplicationConstants(taskOptions),
|
|
82
|
-
|
|
91
|
+
shouldInstallDependencies && tasks.installDependencies(taskOptions),
|
|
83
92
|
].filter(Boolean) as ListrTask[]
|
|
84
93
|
);
|
|
85
94
|
|
|
86
95
|
await taskList.run();
|
|
87
|
-
const
|
|
96
|
+
const packageManager = getPreferredPackageManager(taskOptions);
|
|
88
97
|
|
|
89
98
|
console.log('');
|
|
90
99
|
console.log(
|
|
@@ -93,10 +102,10 @@ const run = () => {
|
|
|
93
102
|
console.log('');
|
|
94
103
|
console.log(`To get started:`);
|
|
95
104
|
console.log(`$ cd ${taskOptions.projectDirectoryName}`);
|
|
96
|
-
if (
|
|
97
|
-
console.log(`$ ${
|
|
105
|
+
if (!shouldInstallDependencies) {
|
|
106
|
+
console.log(`$ ${packageManager} install`);
|
|
98
107
|
}
|
|
99
|
-
console.log(`$ ${
|
|
108
|
+
console.log(`$ ${packageManager} start`);
|
|
100
109
|
console.log('');
|
|
101
110
|
console.log(
|
|
102
111
|
`Visit https://docs.commercetools.com/custom-applications for more info about developing Custom Applications. Enjoy 🚀`
|
package/src/process-options.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import execa from 'execa';
|
|
2
2
|
import type { ListrTask } from 'listr2';
|
|
3
3
|
import type { TCliTaskOptions } from '../types';
|
|
4
|
-
import {
|
|
4
|
+
import { getPreferredPackageManager } from '../utils';
|
|
5
5
|
|
|
6
6
|
function installDependencies(options: TCliTaskOptions): ListrTask {
|
|
7
7
|
return {
|
|
8
8
|
title: 'Installing dependencies (this might take a while)',
|
|
9
9
|
task: () => {
|
|
10
|
-
const
|
|
11
|
-
|
|
10
|
+
const packageManager = getPreferredPackageManager(options);
|
|
11
|
+
|
|
12
12
|
// TODO: we could check for min yarn/npm versions
|
|
13
13
|
// See https://github.com/facebook/create-react-app/blob/0f4781e8507249ce29a9ac1409fece67c1a53c38/packages/create-react-app/createReactApp.js#L225-L254
|
|
14
14
|
return execa(packageManager, ['install'], {
|
|
@@ -3,7 +3,7 @@ import os from 'os';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import type { ListrTask } from 'listr2';
|
|
5
5
|
import type { TCliTaskOptions } from '../types';
|
|
6
|
-
import { slugify } from '../utils';
|
|
6
|
+
import { getPreferredPackageManager, slugify } from '../utils';
|
|
7
7
|
|
|
8
8
|
const replaceApplicationKitPackageVersionWith = (
|
|
9
9
|
releaseVersion: string,
|
|
@@ -37,6 +37,7 @@ function updatePackageJson(
|
|
|
37
37
|
const appPackageJson = JSON.parse(
|
|
38
38
|
fs.readFileSync(packageJsonPath, { encoding: 'utf8' })
|
|
39
39
|
);
|
|
40
|
+
const packageManager = getPreferredPackageManager(options);
|
|
40
41
|
|
|
41
42
|
const updatedAppPackageJson = Object.assign({}, appPackageJson, {
|
|
42
43
|
version: '1.0.0',
|
|
@@ -55,6 +56,12 @@ function updatePackageJson(
|
|
|
55
56
|
releaseVersion,
|
|
56
57
|
appPackageJson.devDependencies
|
|
57
58
|
),
|
|
59
|
+
scripts: {
|
|
60
|
+
...appPackageJson.scripts,
|
|
61
|
+
'start:prod:local': appPackageJson.scripts[
|
|
62
|
+
'start:prod:local'
|
|
63
|
+
].replace('yarn', packageManager),
|
|
64
|
+
},
|
|
58
65
|
});
|
|
59
66
|
|
|
60
67
|
fs.writeFileSync(
|