@magnolia/cli-jumpstart-plugin 1.1.0 → 1.1.1

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 CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.1 (2025-08-07)
4
+ * Set allowVariants property for the magnoliaAuthor ([MGNLCLI-407](https://magnolia-cms.atlassian.net/browse/MGNLCLI-407))
5
+ * Add optional [name] argument to jumpstart command ([MGNLCLI-408](https://magnolia-cms.atlassian.net/browse/MGNLCLI-408))
6
+ * Download correct tomcat version ([MGNLCLI-413](https://magnolia-cms.atlassian.net/browse/MGNLCLI-413))
7
+
3
8
  ## 1.1.0 (2025-06-06)
4
9
  * Add support for named auth profiles in project templates for reusing credentials across bundles ([MGNLCLI-387](https://magnolia-cms.atlassian.net/browse/MGNLCLI-387))
5
10
  * Add support for 6.4 version ([MGNLCLI-389](https://magnolia-cms.atlassian.net/browse/MGNLCLI-389))
package/README.md CHANGED
@@ -5,6 +5,15 @@ A plugin for [Magnolia CLI](https://docs.magnolia-cms.com/magnolia-cli) to downl
5
5
  Within the Magnolia CLI plugin system, this plugin is pre-installed and ready to be used.
6
6
 
7
7
  ## Usage
8
+ ```
9
+ jumpstart [name] [options]
10
+ ```
11
+
12
+ ### Arguments
13
+ | Argument | Description |
14
+ |----------|-------------------------------------------------------------------------------------------------|
15
+ | `name` | Optional project directory name. If provided, the project will be created in this directory. |
16
+
8
17
  ### Options
9
18
 
10
19
  | Short | Long | Description |
@@ -17,11 +26,17 @@ Within the Magnolia CLI plugin system, this plugin is pre-installed and ready to
17
26
  | `-h` | `--help` | display help for command |
18
27
 
19
28
  ### Examples
20
- #### Jumpstart a project
29
+ #### Jumpstart a project in current directory
21
30
  ```bash
22
31
  npx @magnolia/cli@latest jumpstart
23
32
  ```
24
- This command will prompt you with a list of available templates to choose from. Once you select a template, the CLI will download and configure the project with the latest Magnolia version (or with version associated with that template)
33
+ This command will prompt you with a list of available templates to choose from. Once you select a template, the CLI will download and configure the project in the current working directory with the latest Magnolia version (or with version associated with that template).
34
+
35
+ #### Jumpstart a project in a new directory
36
+ ```bash
37
+ npx @magnolia/cli@latest jumpstart my-project
38
+ ```
39
+ This command will create a new directory called `my-project` (if it doesn't exist) and set up the project inside it.
25
40
 
26
41
  #### Jumpstart a project with specific template
27
42
  ```bash
@@ -35,6 +50,12 @@ npx @magnolia/cli@latest jumpstart --template "standard-webapps/magnolia-communi
35
50
  ```
36
51
  This command will start downloading and configuring project based on "standard-webapps/magnolia-community-webapp" template with 6.2.11 Magnolia version.
37
52
 
53
+ #### Jumpstart a project in a specific directory with template and version
54
+ ```bash
55
+ npx @magnolia/cli@latest jumpstart my-magnolia-app --template "standard-webapps/magnolia-community-webapp" --magnolia "6.2.11"
56
+ ```
57
+ This command will create the `my-magnolia-app` directory (if needed) and set up the project with the specified template and Magnolia version.
58
+
38
59
  ## Plugin Documentation
39
60
  For detailed documentation of the plugin, please refer to [Plugin Documentation](https://docs.magnolia-cms.com/magnolia-cli)
40
61
 
@@ -22,7 +22,10 @@ export default class JumpstartPlugin extends PluginTemplate {
22
22
  promptTemplateSelection(templates: Array<Template>, names?: string[]): Promise<TemplateWithoutChildren | undefined>;
23
23
  findTemplateByIdentifier(identifier: string): TemplateWithoutChildren | undefined;
24
24
  chooseTemplate(options: PluginOptions): Promise<void>;
25
+ private extractProjectName;
26
+ validateAndGetDirectoryName(projectName?: string): Promise<string | undefined>;
27
+ handleProjectDirectory(projectName?: string): string;
25
28
  init(winstonLogger: Logger): Promise<void>;
26
- start(options: PluginOptions): Promise<void>;
29
+ start(options: PluginOptions, args?: string[]): Promise<void>;
27
30
  stop(): Promise<void>;
28
31
  }
@@ -13,12 +13,15 @@ import { createRequire } from 'module';
13
13
  const requireFn = createRequire(import.meta.url);
14
14
  const pkg = requireFn('./package.json');
15
15
  import inquirer from 'inquirer';
16
+ import filenamify from 'filenamify';
16
17
  import axios from 'axios';
17
18
  import { extract } from './lib/extract.js';
18
19
  import { downloadBundle } from './lib/download.js';
19
20
  import { PostCommands, } from './types/types.js';
20
21
  import { installDependencies } from './lib/install.js';
21
22
  import path from 'path';
23
+ import fs from 'fs-extra';
24
+ import process from 'process';
22
25
  import { askForCredentials, copyDownloadedFile, handleLightModulesFolder, handleLightModulesPathInTemplate, initializeNodeProject, } from './lib/helper.js';
23
26
  import { compileCustomPrompts, evaluateCustomPrompts, } from './lib/extensions.js';
24
27
  import { addConfigProps } from './lib/config-helper.js';
@@ -40,7 +43,7 @@ export default class JumpstartPlugin extends PluginTemplate {
40
43
  super();
41
44
  this.name = 'jumpstart';
42
45
  this.version = pkg.version;
43
- this.usage = '[options]';
46
+ this.usage = '[name] [options]';
44
47
  this.authProfiles = {};
45
48
  i18nInstance = initI18n(this.name, 'translation', path.join(__dirname, 'lib/locales'));
46
49
  this.description = i18nInstance.t('description');
@@ -98,7 +101,7 @@ export default class JumpstartPlugin extends PluginTemplate {
98
101
  ? this.authProfiles[bundle.auth] ||
99
102
  (yield askForCredentials(bundle.auth))
100
103
  : this.credentials;
101
- const file = yield downloadBundle(bundle, credentials, undefined, options);
104
+ const file = yield downloadBundle(bundle, credentials, undefined, options, template.bundles || []);
102
105
  if (file) {
103
106
  yield this.executePostCommands(bundle, file);
104
107
  }
@@ -223,22 +226,125 @@ export default class JumpstartPlugin extends PluginTemplate {
223
226
  }
224
227
  });
225
228
  }
229
+ extractProjectName(args) {
230
+ if (!Array.isArray(args)) {
231
+ const argv = process.argv;
232
+ if (argv.length > 3) {
233
+ const jumpstartIndex = argv.findIndex((arg) => arg === 'jumpstart');
234
+ if (jumpstartIndex !== -1 && argv.length > jumpstartIndex + 1) {
235
+ const nextArg = argv[jumpstartIndex + 1];
236
+ if (nextArg && !nextArg.startsWith('-')) {
237
+ return nextArg;
238
+ }
239
+ }
240
+ }
241
+ }
242
+ else if (Array.isArray(args) && args.length > 0) {
243
+ return args[0];
244
+ }
245
+ return undefined;
246
+ }
247
+ validateAndGetDirectoryName(projectName) {
248
+ return __awaiter(this, void 0, void 0, function* () {
249
+ if (!projectName) {
250
+ return undefined;
251
+ }
252
+ const sanitizedName = filenamify(projectName, { replacement: '' });
253
+ if (sanitizedName !== projectName || sanitizedName.trim() === '') {
254
+ logger === null || logger === void 0 ? void 0 : logger.warn(i18nInstance.t('warn-invalid-directory-name', {
255
+ name: projectName,
256
+ }));
257
+ const { validDirectoryName } = yield inquirer.prompt([
258
+ {
259
+ type: 'input',
260
+ name: 'validDirectoryName',
261
+ message: i18nInstance.t('prompt-enter-valid-directory-name'),
262
+ validate: (input) => {
263
+ if (!input || input.trim() === '') {
264
+ return i18nInstance.t('error-directory-name-required');
265
+ }
266
+ const sanitized = filenamify(input, {
267
+ replacement: '',
268
+ });
269
+ if (sanitized !== input || sanitized.trim() === '') {
270
+ return i18nInstance.t('error-directory-name-invalid');
271
+ }
272
+ return true;
273
+ },
274
+ default: sanitizedName || 'my-magnolia-project',
275
+ },
276
+ ]);
277
+ return validDirectoryName;
278
+ }
279
+ return projectName;
280
+ });
281
+ }
282
+ handleProjectDirectory(projectName) {
283
+ if (!projectName) {
284
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-will-be-in-cwd'));
285
+ return process.cwd();
286
+ }
287
+ const targetDir = path.resolve(projectName);
288
+ const dirExists = fs.existsSync(targetDir);
289
+ if (!dirExists) {
290
+ fs.mkdirSync(targetDir, { recursive: true });
291
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-directory-created', {
292
+ directory: projectName,
293
+ }));
294
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-project-will-be-in-directory', {
295
+ directory: projectName,
296
+ }));
297
+ }
298
+ else {
299
+ const files = fs.readdirSync(targetDir);
300
+ if (files.length === 0) {
301
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-directory-exists-empty', {
302
+ directory: projectName,
303
+ }));
304
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-project-will-be-in-directory', {
305
+ directory: projectName,
306
+ }));
307
+ }
308
+ else {
309
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-directory-exists-contains-files', {
310
+ directory: projectName,
311
+ }));
312
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-project-will-be-in-directory', {
313
+ directory: projectName,
314
+ }));
315
+ }
316
+ }
317
+ return targetDir;
318
+ }
226
319
  init(winstonLogger) {
227
320
  return __awaiter(this, void 0, void 0, function* () {
228
321
  logger = winstonLogger;
229
322
  });
230
323
  }
231
- start(options) {
324
+ start(options, args) {
232
325
  return __awaiter(this, void 0, void 0, function* () {
233
326
  checkFlagsValue(this.options, options);
234
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-will-be-in-cwd'));
235
- yield this.setProjectTemplates(options);
236
- yield this.chooseTemplate(options);
237
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-project-downloaded'));
238
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-registered-commands'));
239
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-start-project'));
240
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-add-plugin-plugin'));
241
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-refer-to-documentation'));
327
+ const projectName = this.extractProjectName(args);
328
+ const validatedProjectName = yield this.validateAndGetDirectoryName(projectName);
329
+ const targetDir = this.handleProjectDirectory(validatedProjectName);
330
+ const originalCwd = process.cwd();
331
+ if (targetDir !== originalCwd) {
332
+ process.chdir(targetDir);
333
+ }
334
+ try {
335
+ yield this.setProjectTemplates(options);
336
+ yield this.chooseTemplate(options);
337
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-project-downloaded'));
338
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-registered-commands'));
339
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-start-project'));
340
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-add-plugin-plugin'));
341
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-refer-to-documentation'));
342
+ }
343
+ finally {
344
+ if (targetDir !== originalCwd) {
345
+ process.chdir(originalCwd);
346
+ }
347
+ }
242
348
  });
243
349
  }
244
350
  stop() {
@@ -1,4 +1,4 @@
1
1
  import { Bundle, Credentials, PluginOptions } from '../types/types.js';
2
- export declare const downloadBundle: (bundle: Bundle, credentials: Credentials, dest: string | undefined, options: PluginOptions) => Promise<string>;
2
+ export declare const downloadBundle: (bundle: Bundle, credentials: Credentials, dest: string | undefined, options: PluginOptions, allBundles?: Bundle[]) => Promise<string>;
3
3
  export declare const getDownloadUrl: (bundle: Bundle, credentials: Credentials, options: PluginOptions) => Promise<string>;
4
4
  export declare const selectTag: (url: string, credentials: Credentials) => Promise<string>;
@@ -17,7 +17,151 @@ import axios from 'axios';
17
17
  import { CreateError, prependNumbersToChoices, } from '@magnolia/cli-helper/general-utils';
18
18
  import { HttpsProxyAgent } from 'https-proxy-agent';
19
19
  import { HttpProxyAgent } from 'http-proxy-agent';
20
- export const downloadBundle = (bundle, credentials, dest, options) => __awaiter(void 0, void 0, void 0, function* () {
20
+ let discoveredMagnoliaVersion = null;
21
+ const constructMavenSearchUrl = (bundle, options, isTomcatExcluded = false) => {
22
+ const bundleCopy = Object.assign({}, bundle);
23
+ const url = new URL(bundleCopy.url);
24
+ url.searchParams.set('prerelease', 'false');
25
+ url.searchParams.set('maven.classifier', '');
26
+ if (bundleCopy.version) {
27
+ if (options.snapshot ||
28
+ bundleCopy.version.toLowerCase().includes('snapshot')) {
29
+ url.searchParams.set('prerelease', 'true');
30
+ if (options.magnolia === undefined &&
31
+ !bundleCopy.version.match(/^\d/)) {
32
+ options.magnolia = '6.3';
33
+ }
34
+ }
35
+ if (options.magnolia &&
36
+ (!isTomcatExcluded ||
37
+ !bundle.url.includes('magnolia-tomcat-barebone'))) {
38
+ bundleCopy.version = options.magnolia;
39
+ }
40
+ if ((bundleCopy.version.startsWith('latest') ||
41
+ bundleCopy.version.startsWith('6.3') ||
42
+ bundleCopy.version.startsWith('6.4') ||
43
+ bundleCopy.version.includes('alpha') ||
44
+ bundleCopy.version.includes('beta') ||
45
+ bundleCopy.version.includes('rc')) &&
46
+ bundleCopy.alternative) {
47
+ url.searchParams.set('maven.groupId', bundleCopy.alternative.groupId);
48
+ url.searchParams.set('maven.artifactId', bundleCopy.alternative.artifactId);
49
+ }
50
+ if (bundleCopy.version.toLowerCase() !== 'latest' &&
51
+ bundleCopy.version.toLowerCase() !== 'alpha' &&
52
+ bundleCopy.version.toLowerCase() !== 'beta' &&
53
+ bundleCopy.version.toLowerCase() !== 'rc') {
54
+ url.searchParams.set('maven.baseVersion', options.snapshot
55
+ ? bundleCopy.version + '-SNAPSHOT'
56
+ : bundleCopy.version);
57
+ }
58
+ }
59
+ return { url, modifiedBundle: bundleCopy };
60
+ };
61
+ const findItemFromResponse = (response, version) => {
62
+ let item = response.data.items[0];
63
+ if ((version === null || version === void 0 ? void 0 : version.toLowerCase()) === 'latest') {
64
+ item = response.data.items.find((item) => {
65
+ var _a;
66
+ const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
67
+ return (!(itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-alpha')) &&
68
+ !(itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-beta')) &&
69
+ !(itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-rc')));
70
+ });
71
+ }
72
+ else if ((version === null || version === void 0 ? void 0 : version.toLowerCase()) === 'alpha') {
73
+ item = response.data.items.find((item) => {
74
+ var _a;
75
+ const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
76
+ return itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-alpha');
77
+ });
78
+ }
79
+ else if ((version === null || version === void 0 ? void 0 : version.toLowerCase()) === 'beta') {
80
+ item = response.data.items.find((item) => {
81
+ var _a;
82
+ const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
83
+ return itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-beta');
84
+ });
85
+ }
86
+ else if ((version === null || version === void 0 ? void 0 : version.toLowerCase()) === 'rc') {
87
+ item = response.data.items.find((item) => {
88
+ var _a;
89
+ const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
90
+ return itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-rc');
91
+ });
92
+ }
93
+ return item;
94
+ };
95
+ const fetchMavenArtifact = (bundle_1, options_1, credentials_1, ...args_1) => __awaiter(void 0, [bundle_1, options_1, credentials_1, ...args_1], void 0, function* (bundle, options, credentials, isTomcatExcluded = false) {
96
+ const opts = {
97
+ method: 'get',
98
+ responseType: 'json',
99
+ headers: {
100
+ Accept: 'application/json',
101
+ },
102
+ };
103
+ const { url, modifiedBundle } = constructMavenSearchUrl(bundle, options, isTomcatExcluded);
104
+ const response = (yield get(url.toString(), opts, credentials, modifiedBundle.name || modifiedBundle.url));
105
+ const item = findItemFromResponse(response, modifiedBundle.version);
106
+ return { item, modifiedBundle };
107
+ });
108
+ const getMagnoliaVersionFromBundle = (bundle, options, credentials) => __awaiter(void 0, void 0, void 0, function* () {
109
+ var _a;
110
+ try {
111
+ const { item } = yield fetchMavenArtifact(bundle, options, credentials);
112
+ if ((_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version) {
113
+ return item.maven2.version;
114
+ }
115
+ return null;
116
+ }
117
+ catch (_b) {
118
+ return null;
119
+ }
120
+ });
121
+ const modifyTomcatBundleUrl = (bundle, allBundles, credentials, options) => __awaiter(void 0, void 0, void 0, function* () {
122
+ if (!bundle.url.includes('magnolia-tomcat-barebone')) {
123
+ return bundle;
124
+ }
125
+ if (discoveredMagnoliaVersion) {
126
+ return updateTomcatBundleUrl(bundle, discoveredMagnoliaVersion);
127
+ }
128
+ if (allBundles && options) {
129
+ for (const otherBundle of allBundles) {
130
+ if (isMagnoliaBundle(otherBundle)) {
131
+ const magnoliaVersion = yield getMagnoliaVersionFromBundle(otherBundle, options, credentials);
132
+ if (magnoliaVersion === null) {
133
+ throw new Error(i18nInstance.t('error-no-artifact-available', {
134
+ version: options.magnolia || otherBundle.version,
135
+ }));
136
+ }
137
+ if (magnoliaVersion) {
138
+ discoveredMagnoliaVersion = magnoliaVersion;
139
+ return updateTomcatBundleUrl(bundle, magnoliaVersion);
140
+ }
141
+ }
142
+ }
143
+ }
144
+ return bundle;
145
+ });
146
+ const isMagnoliaBundle = (bundle) => {
147
+ return (bundle.url.includes('maven.groupId=info.magnolia') &&
148
+ !bundle.url.includes('magnolia-tomcat-barebone'));
149
+ };
150
+ const updateTomcatBundleUrl = (bundle, magnoliaVersion) => {
151
+ const versionParts = magnoliaVersion.split('.');
152
+ const majorVersion = parseInt(versionParts[0]);
153
+ const minorVersion = parseInt(versionParts[1]);
154
+ let baseVersion = '1.*'; // Default for 6.3 and below
155
+ if (majorVersion > 6 || (majorVersion === 6 && minorVersion >= 4)) {
156
+ baseVersion = '2.*';
157
+ }
158
+ // Change the version only if the version isn't set in projectTemplates
159
+ if (!bundle.url.includes('maven.baseVersion=') || bundle.version) {
160
+ bundle.url = `${bundle.url}&maven.baseVersion=${baseVersion}`;
161
+ }
162
+ return bundle;
163
+ };
164
+ export const downloadBundle = (bundle, credentials, dest, options, allBundles) => __awaiter(void 0, void 0, void 0, function* () {
21
165
  try {
22
166
  const url = bundle.url;
23
167
  const downloadDest = dest ? dest : './download-' + new Date().getTime();
@@ -30,7 +174,8 @@ export const downloadBundle = (bundle, credentials, dest, options) => __awaiter(
30
174
  logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('info-download-preparing', {
31
175
  url,
32
176
  }));
33
- downloadUrl = yield getDownloadUrl(bundle, credentials, options);
177
+ const modifiedBundle = yield modifyTomcatBundleUrl(bundle, allBundles, credentials, options);
178
+ downloadUrl = yield getDownloadUrl(modifiedBundle, credentials, options);
34
179
  }
35
180
  else {
36
181
  downloadUrl = url;
@@ -91,88 +236,20 @@ export const downloadBundle = (bundle, credentials, dest, options) => __awaiter(
91
236
  }
92
237
  });
93
238
  export const getDownloadUrl = (bundle, credentials, options) => __awaiter(void 0, void 0, void 0, function* () {
94
- var _a, _b, _c, _d, _e, _f;
95
- const opts = {
96
- method: 'get',
97
- responseType: 'json',
98
- headers: {
99
- Accept: 'application/json',
100
- },
101
- };
239
+ var _a, _b, _c;
102
240
  try {
103
- const url = new URL(bundle.url);
104
- url.searchParams.set('prerelease', 'false');
105
- url.searchParams.set('maven.classifier', '');
106
- if (bundle.version) {
107
- if (options.snapshot ||
108
- bundle.version.toLowerCase().includes('snapshot')) {
109
- url.searchParams.set('prerelease', 'true');
110
- if (options.magnolia === undefined &&
111
- !bundle.version.match(/^\d/)) {
112
- options.magnolia = '6.3';
113
- }
114
- }
115
- if (options.magnolia) {
116
- bundle.version = options.magnolia;
117
- }
118
- if ((bundle.version.startsWith('latest') ||
119
- bundle.version.startsWith('6.3') ||
120
- bundle.version.startsWith('6.4') ||
121
- bundle.version.includes('alpha') ||
122
- bundle.version.includes('beta') ||
123
- bundle.version.includes('rc')) &&
124
- bundle.alternative) {
125
- url.searchParams.set('maven.groupId', bundle.alternative.groupId);
126
- url.searchParams.set('maven.artifactId', bundle.alternative.artifactId);
127
- }
128
- if (bundle.version.toLowerCase() !== 'latest' &&
129
- bundle.version.toLowerCase() !== 'alpha' &&
130
- bundle.version.toLowerCase() !== 'beta' &&
131
- bundle.version.toLowerCase() !== 'rc') {
132
- url.searchParams.set('maven.baseVersion', options.snapshot
133
- ? bundle.version + '-SNAPSHOT'
134
- : bundle.version);
135
- }
136
- }
137
- const response = (yield get(url.toString(), opts, credentials, bundle.name || bundle.url));
241
+ const { item, modifiedBundle } = yield fetchMavenArtifact(bundle, options, credentials, true);
138
242
  const params = new URLSearchParams(bundle.url.split('?')[1]);
139
- let item = response.data.items[0];
140
- if (((_a = bundle.version) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'latest') {
141
- item = response.data.items.find((item) => {
142
- var _a;
143
- const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
144
- return (!(itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-alpha')) &&
145
- !(itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-beta')) &&
146
- !(itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-rc')));
147
- });
148
- }
149
- else if (((_b = bundle.version) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'alpha') {
150
- item = response.data.items.find((item) => {
151
- var _a;
152
- const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
153
- return itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-alpha');
154
- });
155
- }
156
- else if (((_c = bundle.version) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === 'beta') {
157
- item = response.data.items.find((item) => {
158
- var _a;
159
- const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
160
- return itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-beta');
161
- });
162
- }
163
- else if (((_d = bundle.version) === null || _d === void 0 ? void 0 : _d.toLowerCase()) === 'rc') {
164
- item = response.data.items.find((item) => {
165
- var _a;
166
- const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
167
- return itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes('-rc');
168
- });
169
- }
243
+ bundle.version = modifiedBundle.version;
170
244
  if (!item) {
171
245
  throw new Error(i18nInstance.t('error-no-artifact-available', {
172
246
  version: bundle.version,
173
247
  }));
174
248
  }
175
- bundle.version = (_f = (_e = item === null || item === void 0 ? void 0 : item.maven2) === null || _e === void 0 ? void 0 : _e.version) !== null && _f !== void 0 ? _f : bundle.version;
249
+ bundle.version = (_b = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version) !== null && _b !== void 0 ? _b : bundle.version;
250
+ if (isMagnoliaBundle(bundle) && ((_c = item === null || item === void 0 ? void 0 : item.maven2) === null || _c === void 0 ? void 0 : _c.version)) {
251
+ discoveredMagnoliaVersion = item.maven2.version;
252
+ }
176
253
  let downloadUrl = item.downloadUrl;
177
254
  downloadUrl = downloadUrl === null || downloadUrl === void 0 ? void 0 : downloadUrl.split('/magnolia.');
178
255
  downloadUrl =
@@ -66,6 +66,7 @@ export const handleLightModulesFolder = () => __awaiter(void 0, void 0, void 0,
66
66
  if (webApp.endsWith('magnoliaAuthor')) {
67
67
  props['magnolia.develop'] = 'true';
68
68
  props['magnolia.graphql.introspection.enabled'] = 'true';
69
+ props['magnolia.personalization.rest.allowVariants'] = 'true';
69
70
  }
70
71
  const webAppPropertiesFilePath = path.join(webApp, 'WEB-INF', 'config', 'default', 'magnolia.properties');
71
72
  editProperties(webAppPropertiesFilePath, props);
@@ -28,12 +28,17 @@
28
28
  "info-refer-to-documentation": "For additional plugins and features, refer to the Magnolia CLI documentation: https://docs.magnolia-cms.com/magnolia-cli",
29
29
  "info-file-downloaded-to": "Downloaded to {{path}}",
30
30
  "info-will-be-in-cwd": "The project will be created in the current working directory",
31
+ "info-directory-created": "Directory '{{directory}}' was created",
32
+ "info-directory-exists-empty": "Directory '{{directory}}' exists and is empty",
33
+ "info-directory-exists-contains-files": "Directory '{{directory}}' exists and contains files",
34
+ "info-project-will-be-in-directory": "The project will be set up inside the '{{directory}}' directory",
31
35
 
32
36
  "warn-install-plugins-manually": "Please install following plugins:\n{{installPluginsText}}and register them in \"mgnl.config.js\" file",
33
37
  "warn-changed-type": "Changed 'type' property to \"module\" in \"package.json\"",
34
38
  "warn-webapp-props-not-exist": "File \"{{filePath}}\" not found; skipping configuration",
35
39
  "warn-cannot-modify-webapp": "An error occurred while modifying webapps:\n{{errorMsg}}",
36
40
  "warn-cannot-parse-plugin-args": "The provided object:\n{{pluginArgs}}\nis not a valid JSON5 object; arguments will not be added to the plugin: \"{{plugin}}\"",
41
+ "warn-invalid-directory-name": "The directory name '{{name}}' contains invalid characters and cannot be used",
37
42
 
38
43
  "error-no-tags": "No available tags found",
39
44
  "error-problem-accessing-url": "A problem occurred while accessing: {{url}}",
@@ -63,9 +68,12 @@
63
68
  "error-download-fail-status": "Download failed from: {{downloadUrl}}; expected status \"200\"; received: \"{{status}}\"",
64
69
  "error-while-downloading-bundle": "An error occurred while downloading bundle from: {{url}}",
65
70
  "error-auth-fail": "Authentication failed for {{url}}; received 401 status; verify your credentials and try again",
71
+ "error-directory-name-required": "Directory name is required",
72
+ "error-directory-name-invalid": "Directory name contains invalid characters. Please use only letters, numbers, hyphens, and underscores",
66
73
 
67
74
  "inquirer-prompt-select-tag": "Choose a tag",
68
75
  "inquirer-prompt-choose-template": "Choose a template",
76
+ "prompt-enter-valid-directory-name": "Please enter a valid directory name",
69
77
 
70
78
  "ora-start-checking-add-plugin": "Looking for \"@magnolia/cli add-plugin\" command...",
71
79
  "ora-start-extracting": "Extracting...",
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magnolia/cli-jumpstart-plugin",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "A plugin for Magnolia CLI to download and set up a new headless or freemarker-based project with Magnolia webapp",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -54,6 +54,7 @@
54
54
  "decompress": "^4.2.1",
55
55
  "dotenv": "^16.4.7",
56
56
  "execa": "^9.5.2",
57
+ "filenamify": "^6.0.0",
57
58
  "fs-extra": "^11.3.0",
58
59
  "glob": "^11.0.1",
59
60
  "http-proxy-agent": "^7.0.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magnolia/cli-jumpstart-plugin",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "A plugin for Magnolia CLI to download and set up a new headless or freemarker-based project with Magnolia webapp",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -54,6 +54,7 @@
54
54
  "decompress": "^4.2.1",
55
55
  "dotenv": "^16.4.7",
56
56
  "execa": "^9.5.2",
57
+ "filenamify": "^6.0.0",
57
58
  "fs-extra": "^11.3.0",
58
59
  "glob": "^11.0.1",
59
60
  "http-proxy-agent": "^7.0.2",