@magnolia/cli-jumpstart-plugin 1.0.0-preview.4 → 1.0.0-preview.6

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/README.md CHANGED
@@ -27,21 +27,23 @@ When run, the plugin will prompt the user to select a template. It will then pro
27
27
  ### **command-line options**
28
28
 
29
29
  You can customize the **jumpstart** plugin's actions using these command-line options:
30
- - `-t, --template <name>`: Choose template.
31
- - `-p, --projectTemplatesPath <path>`: Specify from where the projectTemplates should be loaded.
30
+ - `-t, --template <name>`, choose a template from available project templates
31
+ - `-p, --project-templates-path <path>`, specify the path to load project templates from
32
+ - `-m, --magnolia-version <version>`, set the Magnolia version; defaults to the latest stable version
33
+ - `-s, --snapshot`, download the latest snapshot version of the specified or latest stable webapp
32
34
 
33
35
  **Template option:**
34
36
 
35
37
  With this option, you can specify which template to use:
36
38
 
37
39
  ```bash
38
- magnolia-cli jumpstart --template "headless/minimal-headless-spa-demos/dx-core/latest"
40
+ magnolia-cli jumpstart --template "headless/minimal-headless-spa-demos/dx-core"
39
41
  ```
40
42
 
41
43
 
42
44
  **Project templates list:**
43
45
 
44
- The **jumpstart** plugin relies on a list of predefined project templates stored in an external [repository](https://git.magnolia-cms.com/projects/SERVICES/repos/cli-project-templates/raw/projectTemplates.json).
46
+ The **jumpstart** plugin relies on a list of predefined project templates stored in an external [repository](https://bitbucket.org/magnolia-cms/cli-project-templates/raw/HEAD/projectTemplates.json).
45
47
  You can specify your own project templates list with the *--project-templates-path* command:
46
48
 
47
49
  ```bash
@@ -9,10 +9,10 @@ export declare let i18nInstance: {
9
9
  export default class JumpstartPlugin extends PluginTemplate {
10
10
  name: string;
11
11
  version: any;
12
- description: any;
13
12
  projectTemplates?: Array<Template>;
14
13
  options: Option[];
15
14
  credentials?: Credentials;
15
+ description: string;
16
16
  constructor();
17
17
  executePostCommands(bundle: Bundle, file: string): Promise<void>;
18
18
  handleTemplate(template: TemplateWithoutChildren, options: PluginOptions): Promise<void>;
@@ -20,6 +20,8 @@ export default class JumpstartPlugin extends PluginTemplate {
20
20
  promptTemplateSelection(templates: Array<Template>, names?: string[]): Promise<TemplateWithoutChildren | undefined>;
21
21
  findTemplateByIdentifier(identifier: string): TemplateWithoutChildren | undefined;
22
22
  chooseTemplate(options: PluginOptions): Promise<void>;
23
+ private isFlag;
24
+ private checkFlagsArguments;
23
25
  init(winstonLogger: Logger): Promise<void>;
24
26
  start(options: PluginOptions): Promise<void>;
25
27
  stop(): Promise<void>;
@@ -19,8 +19,10 @@ import { downloadBundle } from "./lib/download.js";
19
19
  import { PostCommands } from "./types/types.js";
20
20
  import { installDependencies } from "./lib/install.js";
21
21
  import path from "path";
22
- import { askForCredentials, handleLightModulesFolder, initI18n, initializeNodeProject, installAdditionalPlugins } from "./lib/helper.js";
22
+ import { askForCredentials, handleLightModulesFolder, initI18n, initializeNodeProject } from "./lib/helper.js";
23
23
  import { compileCustomPrompts, evaluateCustomPrompts } from "./lib/extensions.js";
24
+ import { addConfigProps } from "./lib/config-helper.js";
25
+ import { installAdditionalPlugins } from "./lib/config-helper.js";
24
26
  const extensionsPath = path.resolve("./extensions/extension.yaml");
25
27
  export let logger;
26
28
  export let i18nInstance = {
@@ -31,11 +33,13 @@ export default class JumpstartPlugin extends PluginTemplate {
31
33
  super();
32
34
  this.name = "jumpstart";
33
35
  this.version = pkg.version;
34
- this.description = pkg.description;
35
36
  i18nInstance = initI18n(this.name);
37
+ this.description = i18nInstance.t('cmd-option-description');
36
38
  this.options = [
37
39
  new Option('-t, --template <name>', i18nInstance.t("cmd-option-template")),
38
- new Option('-p, --project-templates-path <path>', i18nInstance.t("cmd-option-project-templates-path"))
40
+ new Option('-p, --project-templates-path <path>', i18nInstance.t("cmd-option-project-templates-path")),
41
+ new Option('-m, --magnolia-version <version>', i18nInstance.t('cmd-option-magnolia-version')),
42
+ new Option('-s, --snapshot', i18nInstance.t('cmd-option-snapshot'))
39
43
  ];
40
44
  }
41
45
  executePostCommands(bundle, file) {
@@ -46,6 +50,7 @@ export default class JumpstartPlugin extends PluginTemplate {
46
50
  switch (command) {
47
51
  case PostCommands.Extract:
48
52
  case PostCommands.ExtractAndOverride:
53
+ case PostCommands.ExtractAndUnfold:
49
54
  yield extract(bundle, file, command);
50
55
  break;
51
56
  case PostCommands.NpmInstall:
@@ -72,10 +77,10 @@ export default class JumpstartPlugin extends PluginTemplate {
72
77
  bundle: bundle.name ? bundle.name : bundle.url
73
78
  }));
74
79
  const bundleCredentials = yield askForCredentials();
75
- file = yield downloadBundle(bundle, bundleCredentials, undefined);
80
+ file = yield downloadBundle(bundle, bundleCredentials, undefined, options);
76
81
  }
77
82
  else {
78
- file = yield downloadBundle(bundle, this.credentials, undefined);
83
+ file = yield downloadBundle(bundle, this.credentials, undefined, options);
79
84
  }
80
85
  if (file) {
81
86
  yield this.executePostCommands(bundle, file);
@@ -88,7 +93,10 @@ export default class JumpstartPlugin extends PluginTemplate {
88
93
  yield handleLightModulesFolder();
89
94
  yield initializeNodeProject();
90
95
  if (template.plugins) {
91
- yield installAdditionalPlugins(template.plugins, this.credentials);
96
+ yield installAdditionalPlugins(template.plugins);
97
+ }
98
+ if (template.configVars) {
99
+ yield addConfigProps(template.configVars);
92
100
  }
93
101
  const extensions = yield evaluateCustomPrompts(extensionsPath);
94
102
  if (extensions === null || extensions === void 0 ? void 0 : extensions.answers) {
@@ -104,22 +112,14 @@ export default class JumpstartPlugin extends PluginTemplate {
104
112
  var _a;
105
113
  try {
106
114
  if ((_a = options.projectTemplatesPath) === null || _a === void 0 ? void 0 : _a.startsWith("http", 0)) {
107
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('prompt-project-templates-credentials'));
108
- this.credentials = yield askForCredentials();
109
- const res = yield axios.get(options.projectTemplatesPath, {
110
- auth: this.credentials
111
- });
115
+ const res = yield axios.get(options.projectTemplatesPath);
112
116
  this.projectTemplates = res.data.projectTemplates;
113
117
  }
114
118
  else if (options.projectTemplatesPath) {
115
119
  this.projectTemplates = requireFn(path.resolve(options.projectTemplatesPath)).projectTemplates;
116
120
  }
117
121
  else {
118
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('prompt-project-templates-credentials'));
119
- this.credentials = yield askForCredentials();
120
- const res = yield axios.get("https://git.magnolia-cms.com/rest/api/latest/projects/SERVICES/repos/cli-project-templates/raw/projectTemplates.json", {
121
- auth: this.credentials
122
- });
122
+ const res = yield axios.get("https://bitbucket.org/magnolia-cms/cli-project-templates/raw/HEAD/projectTemplates.json");
123
123
  this.projectTemplates = res.data.projectTemplates;
124
124
  }
125
125
  }
@@ -193,6 +193,19 @@ export default class JumpstartPlugin extends PluginTemplate {
193
193
  }
194
194
  });
195
195
  }
196
+ isFlag(value) {
197
+ return this.options.some(it => it.long === value || it.short === value);
198
+ }
199
+ checkFlagsArguments(options) {
200
+ Object.keys(options).forEach(key => {
201
+ const value = options[key];
202
+ if (this.isFlag(value)) {
203
+ const optionLong = "--" + key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
204
+ const option = this.options.find(it => it.long === optionLong);
205
+ throw new Error(i18nInstance.t('error-option-param-is-flag', { option: option === null || option === void 0 ? void 0 : option.flags, value: value }));
206
+ }
207
+ });
208
+ }
196
209
  init(winstonLogger) {
197
210
  return __awaiter(this, void 0, void 0, function* () {
198
211
  logger = winstonLogger;
@@ -201,6 +214,7 @@ export default class JumpstartPlugin extends PluginTemplate {
201
214
  start(options) {
202
215
  return __awaiter(this, void 0, void 0, function* () {
203
216
  logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t("info-jumpstart_started"));
217
+ this.checkFlagsArguments(options);
204
218
  yield this.setProjectTemplates(options);
205
219
  yield this.chooseTemplate(options);
206
220
  });
@@ -1,3 +1,4 @@
1
- import { Credentials, PluginRequirement } from "../types/types.js";
1
+ import { PluginRequirement } from "../types/types";
2
+ export declare const installAdditionalPlugins: (plugins: Array<PluginRequirement>) => Promise<void>;
2
3
  export declare const handleMGNLConfigFile: () => Promise<void>;
3
- export declare const installAndConfigPlugins: (plugins: Array<PluginRequirement>, credentials?: Credentials) => Promise<void>;
4
+ export declare const addConfigProps: (vars: any) => Promise<void>;
@@ -10,21 +10,64 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import fs from "fs-extra";
11
11
  import parser from "@babel/parser";
12
12
  import t from "@babel/types";
13
+ const generate = _generate.default;
14
+ const traverse = _traverse.default;
13
15
  import beautifyModule from "js-beautify";
14
16
  import path from "path";
15
- import { determinePackageManager, extractRepoName, installPackage, isValidURL } from "./helper.js";
17
+ import { determinePackageManager, installPackage } from "./helper.js";
16
18
  import ora from "ora";
17
19
  import { i18nInstance, logger } from "../jumpstart-plugin.js";
20
+ import _generate from "@babel/generator";
21
+ import _traverse from "@babel/traverse";
22
+ import { execa } from "execa";
23
+ import JSON5 from "json5";
18
24
  const { js_beautify } = beautifyModule;
19
25
  const BEAUTIFY_OPTIONS = {
20
26
  indent_size: 2,
21
27
  end_with_newline: true,
22
28
  max_preserve_newlines: 2,
23
29
  keep_array_indentation: false,
24
- preserve_newlines: true
30
+ preserve_newlines: true,
31
+ wrap_line_length: 1
25
32
  };
26
33
  const getLocalConfigPath = () => path.join(process.cwd(), 'mgnl.config.js');
27
34
  const getPackageConfigPath = () => path.join(process.cwd(), 'node_modules/@magnolia/cli/mgnl.config.js');
35
+ export const installAdditionalPlugins = (plugins) => __awaiter(void 0, void 0, void 0, function* () {
36
+ const pm = determinePackageManager();
37
+ const addPluginExists = yield execa(pm, 'run mgnl -s -- add-plugin -v'.split(' '), { cwd: process.cwd() });
38
+ if (addPluginExists.exitCode !== 0 || !addPluginExists.stdout.match(/(\d.)+(\d).*/)) {
39
+ logger.warn(i18nInstance.t("warn-config-h-no-add-plugin"));
40
+ let installPluginsText = "";
41
+ plugins.forEach(plugin => {
42
+ installPluginsText = `${installPluginsText} - ${plugin.plugin}\n`;
43
+ if (plugin.pluginArgs) {
44
+ installPluginsText = `${installPluginsText}${i18nInstance.t("install-plugin-with-args-text", { pluginArgs: JSON5.stringify(plugin.pluginArgs) })}`;
45
+ }
46
+ });
47
+ logger.warn(i18nInstance.t("warn-config-h-install-plugins-manually", { installPluginsText: installPluginsText }));
48
+ return;
49
+ }
50
+ for (const plugin of plugins) {
51
+ try {
52
+ const addPluginArgs = `run mgnl -s -- add-plugin ${plugin.plugin}`.split(' ');
53
+ try {
54
+ if (plugin.pluginArgs !== undefined && plugin.pluginArgs !== 'undefined' && plugin.pluginArgs !== '') {
55
+ addPluginArgs.push(JSON5.stringify(JSON5.parse(JSON5.stringify(plugin.pluginArgs))));
56
+ }
57
+ }
58
+ catch (e) {
59
+ logger.warn(i18nInstance.t('warn-config-h-error-cannot-parse-plugin-args', { pluginArgs: plugin.pluginArgs }));
60
+ }
61
+ yield execa(pm, addPluginArgs, {
62
+ stdio: 'inherit',
63
+ cwd: process.cwd()
64
+ });
65
+ }
66
+ catch (e) {
67
+ logger.error(i18nInstance.t('error-config-h-while-add-plugin', { plugin: plugin }));
68
+ }
69
+ }
70
+ });
28
71
  export const handleMGNLConfigFile = () => __awaiter(void 0, void 0, void 0, function* () {
29
72
  let isMgnlCliInstalled = true;
30
73
  if (!fs.existsSync(getPackageConfigPath())) {
@@ -44,18 +87,6 @@ export const handleMGNLConfigFile = () => __awaiter(void 0, void 0, void 0, func
44
87
  // the mgnl.config.js exist, do not do anything
45
88
  }
46
89
  });
47
- export const installAndConfigPlugins = (plugins, credentials) => __awaiter(void 0, void 0, void 0, function* () {
48
- const localConfig = parseConfigFile(getLocalConfigPath());
49
- if (!localConfig)
50
- return;
51
- const missingPlugins = findMissingPlugins(plugins, localConfig);
52
- if (missingPlugins.length === 0)
53
- return;
54
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t("info-config-h-will-install-missing-plugins"));
55
- const installedPlugins = yield installPlugins(missingPlugins, credentials);
56
- const pluginsConfig = createCustomConfigForPlugins(installedPlugins);
57
- updateLocalConfig(pluginsConfig, localConfig);
58
- });
59
90
  const handleExistingConfigFile = () => {
60
91
  const localConfigContent = fs.readFileSync(getLocalConfigPath(), "utf8");
61
92
  const packageConfigContent = fs.readFileSync(getPackageConfigPath(), "utf8");
@@ -77,7 +108,7 @@ function createMgnlConfigFile() {
77
108
  : '';
78
109
  const mgnlConfigSufix = `
79
110
  // Here you can add plugins you want to use with MGNL CLI
80
- commands: []
111
+ plugins: []
81
112
  };`;
82
113
  const mgnlConfigContent = mgnlConfigPrefix + logger + mgnlConfigSufix;
83
114
  writeConfigContent(mgnlConfigContent);
@@ -86,7 +117,7 @@ function createSimpleMgnlConfigFile() {
86
117
  const mgnlConfigContent = `
87
118
  export default {
88
119
  // Here you can add plugins you want to use with MGNL CLI
89
- commands: []
120
+ plugins: []
90
121
  };`;
91
122
  writeConfigContent(mgnlConfigContent);
92
123
  }
@@ -100,141 +131,80 @@ const extractLoggerConfig = (content) => {
100
131
  const loggerRegex = /(logger\s*:\s*{[^}]*})/s;
101
132
  return loggerRegex.exec(content);
102
133
  };
103
- const findMissingPlugins = (plugins, config) => {
104
- return plugins.filter(plugin => {
105
- let packageName = plugin.name;
106
- return !config.imports.some(customImport => customImport.importedNames === packageName);
107
- });
108
- };
109
- const installPlugins = (plugins, credentials) => __awaiter(void 0, void 0, void 0, function* () {
110
- const packageManager = determinePackageManager();
111
- let installedPlugins = [];
112
- for (const plugin of plugins) {
113
- const installed = yield installPackage(packageManager, plugin.installReference, plugin.name, credentials);
114
- if (installed)
115
- installedPlugins.push(plugin);
116
- }
117
- return installedPlugins;
118
- });
119
- const extractPackageName = (installReference) => {
120
- // Use a regular expression to match the package name.
121
- const regex = /^(?:@([^/]+)\/)?([^@]+)/;
122
- const match = installReference.match(regex);
123
- if (!match)
124
- return null;
125
- // Construct package name. If it's a scoped package, prepend the scope.
126
- return match[1] ? `@${match[1]}/${match[2]}` : match[2];
127
- };
128
- const createCustomConfigForPlugins = (plugins) => {
129
- const defaultConfig = { configContent: "", imports: [], commands: [] };
130
- plugins.forEach(plugin => {
131
- let importSource;
132
- if (isValidURL(plugin.installReference)) {
133
- importSource = extractRepoName(plugin.installReference);
134
- }
135
- if (!importSource) {
136
- importSource = plugin.installReference;
137
- }
138
- defaultConfig.imports.push({ importedNames: plugin.name, importSource: extractPackageName(importSource) || importSource });
139
- defaultConfig.commands.push({ commandName: plugin.name, options: plugin.options });
140
- });
141
- return defaultConfig;
142
- };
143
- const parseConfigFile = (configPath) => {
144
- let configContent;
145
- try {
146
- configContent = fs.readFileSync(configPath, 'utf-8');
147
- }
148
- catch (e) {
149
- logger === null || logger === void 0 ? void 0 : logger.error(i18nInstance.t("error-config-h-could-not-read-mgnl-config", {
150
- configPath: configPath
151
- }));
152
- console.error(e);
153
- return null;
154
- }
155
- let parsedConfig;
134
+ const writeConfigContent = (content) => {
135
+ const spinner = ora().start(i18nInstance.t("ora-updating-mgnl-config"));
156
136
  try {
157
- parsedConfig = parser.parse(configContent, { sourceType: 'module' });
137
+ fs.writeFileSync(getLocalConfigPath(), js_beautify(content.trim(), BEAUTIFY_OPTIONS), 'utf-8');
158
138
  }
159
139
  catch (e) {
160
- logger === null || logger === void 0 ? void 0 : logger.error(i18nInstance.t("error-config-h-could-not-parse-mgnl-config", {
161
- configPath: configPath
162
- }));
140
+ spinner.stop();
141
+ logger === null || logger === void 0 ? void 0 : logger.error(i18nInstance.t("error-config-h-while-updating-mgnl-config"));
163
142
  console.error(e);
164
- return null;
165
143
  }
166
- if (!parsedConfig)
167
- return null;
168
- const { imports, commands } = extractImportsAndCommands(parsedConfig);
169
- return { configContent, imports, commands };
144
+ spinner.stop();
145
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t("info-config-h-mgnl-config-updated"));
170
146
  };
171
- const extractImportsAndCommands = (ast) => {
172
- const imports = [];
173
- const commands = [];
174
- ast.program.body.forEach(node => {
175
- if (t.isImportDeclaration(node)) {
176
- imports.push({
177
- importedNames: node.specifiers.map(specifier => specifier.local.name).join(', '),
178
- importSource: node.source.value
179
- });
180
- }
181
- if (t.isExportDefaultDeclaration(node) && t.isObjectExpression(node.declaration)) {
182
- node.declaration.properties.forEach(property => {
183
- if (t.isObjectProperty(property) && t.isArrayExpression(property.value)) {
184
- property.value.elements.forEach(element => {
185
- if (t.isNewExpression(element) && t.isIdentifier(element.callee)) {
186
- commands.push({ commandName: element.callee.name });
147
+ export const addConfigProps = (vars) => __awaiter(void 0, void 0, void 0, function* () {
148
+ const spinner = ora().start(i18nInstance.t("ora-adding-shared-vars"));
149
+ try {
150
+ const filePath = getLocalConfigPath();
151
+ let content = fs.readFileSync(filePath, 'utf-8');
152
+ const valueToAstNode = (value) => {
153
+ if (typeof value === 'string') {
154
+ return t.stringLiteral(value);
155
+ }
156
+ else if (typeof value === 'boolean') {
157
+ return t.booleanLiteral(value);
158
+ }
159
+ else if (typeof value === 'number') {
160
+ return t.numericLiteral(value);
161
+ }
162
+ else if (Array.isArray(value)) {
163
+ return t.arrayExpression(value.map(item => valueToAstNode(item)));
164
+ }
165
+ else if (typeof value === 'object') {
166
+ return t.objectExpression(Object.entries(value).map(([key, val]) => t.objectProperty(t.isValidIdentifier(key)
167
+ ? t.identifier(key)
168
+ : t.stringLiteral(key), valueToAstNode(val))));
169
+ }
170
+ else {
171
+ throw new TypeError('Unsupported type');
172
+ }
173
+ };
174
+ const ast = parser.parse(content, {
175
+ sourceType: 'module',
176
+ plugins: ['typescript'], // if you're using TypeScript
177
+ attachComment: true
178
+ });
179
+ let modificationsMade = false;
180
+ traverse(ast, {
181
+ ExportDefaultDeclaration({ node }) {
182
+ if (t.isObjectExpression(node.declaration)) {
183
+ // Check each required property to see if it exists in the declaration
184
+ Object.entries(vars).forEach(([key, value]) => {
185
+ let propExists = node.declaration.properties.some((property) => t.isObjectProperty(property) &&
186
+ ((t.isIdentifier(property.key) && property.key.name === key) ||
187
+ (t.isStringLiteral(property.key) && property.key.value === key)));
188
+ if (!propExists) {
189
+ // If the property doesn't exist, add it
190
+ node.declaration.properties.push(t.objectProperty(t.isValidIdentifier(key)
191
+ ? t.identifier(key) : t.stringLiteral(key), valueToAstNode(value)));
192
+ modificationsMade = true;
187
193
  }
188
194
  });
189
195
  }
190
- });
196
+ },
197
+ });
198
+ if (modificationsMade) {
199
+ const output = generate(ast, {}, content);
200
+ fs.writeFileSync(getLocalConfigPath(), js_beautify(output.code.trim(), BEAUTIFY_OPTIONS), 'utf-8');
201
+ spinner.stop();
202
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t("info-config-h-mgnl-vars-added"));
191
203
  }
192
- });
193
- return { imports, commands };
194
- };
195
- const updateLocalConfig = (defaultConfig, localConfig) => {
196
- const getMissingItems = (defaultItems, customItems, comparator) => {
197
- return defaultItems.filter(defaultItem => !customItems.some(customItem => comparator(defaultItem, customItem)));
198
- };
199
- const mergeImports = (customImports, missingImports) => {
200
- return customImports.concat(missingImports)
201
- .map(i => `import ${i.importedNames} from "${i.importSource}";`).join('\n');
202
- };
203
- const missingImports = getMissingItems(defaultConfig.imports, localConfig.imports, (a, b) => a.importSource === b.importSource);
204
- const missingCommands = getMissingItems(defaultConfig.commands, localConfig.commands, (a, b) => a.commandName === b.commandName);
205
- const mergedImports = mergeImports(localConfig.imports, missingImports);
206
- const updatedConfigContent = mergeCommandsWithConfigContent(localConfig.configContent, missingCommands);
207
- writeToLocalConfigFile(mergedImports, updatedConfigContent);
208
- };
209
- const formatOptions = (options) => {
210
- if (!options)
211
- return '()';
212
- const formattedOptions = JSON.stringify(options, null);
213
- return `(${formattedOptions})`;
214
- };
215
- const mergeCommandsWithConfigContent = (configContent, missingCommands) => {
216
- const missingCommandsStr = missingCommands.map(c => `new ${c.commandName}${formatOptions(c.options)}`).join(',\n');
217
- const commandsPattern = /(commands\s*:\s*\[)([^\]]*?)(,\s*)?(\])/;
218
- return configContent.replace(commandsPattern, (match, p1, p2, p3, p4) => {
219
- const separator = (p2.trim() !== "" && missingCommandsStr.trim() !== "") ? "," : "";
220
- return `${p1}${p2}${separator}${missingCommandsStr}${p4}`;
221
- });
222
- };
223
- const writeToLocalConfigFile = (mergedImports, updatedConfigContent) => {
224
- const importPattern = /import .* from ['"].*['"];\s*/g;
225
- const configContentWithImports = `${mergedImports}\n\n${updatedConfigContent.replace(importPattern, '')}`;
226
- writeConfigContent(configContentWithImports);
227
- };
228
- const writeConfigContent = (content) => {
229
- const spinner = ora().start(i18nInstance.t("ora-updating-mgnl-config"));
230
- try {
231
- fs.writeFileSync(getLocalConfigPath(), js_beautify(content.trim(), BEAUTIFY_OPTIONS), 'utf-8');
232
204
  }
233
205
  catch (e) {
234
206
  spinner.stop();
235
- logger === null || logger === void 0 ? void 0 : logger.error(i18nInstance.t("error-config-h-while-updating-mgnl-config"));
207
+ logger === null || logger === void 0 ? void 0 : logger.error(i18nInstance.t("error-config-h-while-adding-vars"));
236
208
  console.error(e);
237
209
  }
238
- spinner.stop();
239
- logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t("info-config-h-mgnl-config-updated"));
240
- };
210
+ });
@@ -1,4 +1,4 @@
1
- import { Bundle, Credentials } from "../types/types.js";
2
- export declare const downloadBundle: (bundle: Bundle, credentials: Credentials, dest: string | undefined) => Promise<string>;
3
- export declare const getDownloadUrl: (bundle: Bundle, credentials: Credentials) => Promise<string>;
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>;
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>;
@@ -13,7 +13,7 @@ import axios from "axios";
13
13
  import ProgressBar from "progress";
14
14
  import inquirer from "inquirer";
15
15
  import { i18nInstance, logger } from "../jumpstart-plugin.js";
16
- export const downloadBundle = (bundle, credentials, dest) => __awaiter(void 0, void 0, void 0, function* () {
16
+ export const downloadBundle = (bundle, credentials, dest, options) => __awaiter(void 0, void 0, void 0, function* () {
17
17
  try {
18
18
  let url = bundle.url;
19
19
  const downloadDest = dest ? dest : "./download-" + new Date().getTime();
@@ -25,7 +25,7 @@ export const downloadBundle = (bundle, credentials, dest) => __awaiter(void 0, v
25
25
  downloadUrl = yield selectTag(url, credentials);
26
26
  }
27
27
  else if (url.includes('https://nexus.magnolia-cms.com/service/rest/v1/search')) {
28
- downloadUrl = yield getDownloadUrl(bundle, credentials);
28
+ downloadUrl = yield getDownloadUrl(bundle, credentials, options);
29
29
  }
30
30
  else {
31
31
  downloadUrl = url;
@@ -84,7 +84,8 @@ export const downloadBundle = (bundle, credentials, dest) => __awaiter(void 0, v
84
84
  throw new Error(error);
85
85
  }
86
86
  });
87
- export const getDownloadUrl = (bundle, credentials) => __awaiter(void 0, void 0, void 0, function* () {
87
+ export const getDownloadUrl = (bundle, credentials, options) => __awaiter(void 0, void 0, void 0, function* () {
88
+ var _a, _b, _c, _d, _e;
88
89
  const opts = {
89
90
  method: 'get',
90
91
  responseType: 'json',
@@ -96,11 +97,54 @@ export const getDownloadUrl = (bundle, credentials) => __awaiter(void 0, void 0,
96
97
  opts.auth = credentials;
97
98
  }
98
99
  try {
99
- const response = yield axios.get(bundle.url + '&prerelease=false', opts);
100
+ const url = new URL(bundle.url);
101
+ url.searchParams.set('prerelease', "false");
102
+ if (bundle.version) {
103
+ if (options.snapshot || bundle.version.toLowerCase().includes("snapshot")) {
104
+ url.searchParams.set('prerelease', "true");
105
+ }
106
+ if (options.magnoliaVersion) {
107
+ bundle.version = options.magnoliaVersion;
108
+ if (bundle.version.startsWith('6.3') && bundle.alternative) {
109
+ url.searchParams.set('maven.groupId', bundle.alternative.groupId);
110
+ url.searchParams.set('maven.artifactId', bundle.alternative.artifactId);
111
+ }
112
+ }
113
+ if (bundle.version.toLowerCase() !== "latest" && bundle.version.toLowerCase() !== "alpha" && bundle.version.toLowerCase() !== "beta") {
114
+ url.searchParams.set('maven.baseVersion', options.snapshot ? bundle.version + "-SNAPSHOT" : bundle.version);
115
+ }
116
+ }
117
+ const response = yield axios.get(url.toString(), opts);
100
118
  const params = new URLSearchParams(bundle.url.split("?")[1]);
101
- let downloadUrl = response.data.items[0].downloadUrl;
119
+ let item = response.data.items[0];
120
+ if (((_a = bundle.version) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "latest") {
121
+ item = response.data.items.find((item) => {
122
+ var _a;
123
+ const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
124
+ return !(itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes("-alpha")) && !(itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes("-beta"));
125
+ });
126
+ }
127
+ else if (((_b = bundle.version) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === "alpha") {
128
+ item = response.data.items.find((item) => {
129
+ var _a;
130
+ const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
131
+ return itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes("-alpha");
132
+ });
133
+ }
134
+ else if (((_c = bundle.version) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === "beta") {
135
+ item = response.data.items.find((item) => {
136
+ var _a;
137
+ const itemVersion = (_a = item === null || item === void 0 ? void 0 : item.maven2) === null || _a === void 0 ? void 0 : _a.version;
138
+ return itemVersion === null || itemVersion === void 0 ? void 0 : itemVersion.includes("-beta");
139
+ });
140
+ }
141
+ if (!item) {
142
+ throw new Error(i18nInstance.t('error-download-no-artifact-available', { version: bundle.version, interpolation: { escapeValue: false } }));
143
+ }
144
+ bundle.version = (_e = (_d = item === null || item === void 0 ? void 0 : item.maven2) === null || _d === void 0 ? void 0 : _d.version) !== null && _e !== void 0 ? _e : bundle.version;
145
+ let downloadUrl = item.downloadUrl;
102
146
  downloadUrl = downloadUrl === null || downloadUrl === void 0 ? void 0 : downloadUrl.split('/magnolia.');
103
- downloadUrl = downloadUrl && `${downloadUrl[0]}/${params.get('repository')}/${response.data.items[0].path}`;
147
+ downloadUrl = downloadUrl && `${downloadUrl[0]}/${params.get('repository')}${item.path}`;
104
148
  return downloadUrl;
105
149
  }
106
150
  catch (error) {
@@ -110,11 +154,11 @@ export const getDownloadUrl = (bundle, credentials) => __awaiter(void 0, void 0,
110
154
  }));
111
155
  logger === null || logger === void 0 ? void 0 : logger.error(i18nInstance.t("error-download-unable-to-get-local-issuer-certificate"));
112
156
  }
113
- throw new Error(error);
157
+ throw new Error(error.message);
114
158
  }
115
159
  });
116
160
  export const selectTag = (url, credentials) => __awaiter(void 0, void 0, void 0, function* () {
117
- var _a;
161
+ var _f;
118
162
  const opts = {
119
163
  method: 'get',
120
164
  headers: {
@@ -125,7 +169,7 @@ export const selectTag = (url, credentials) => __awaiter(void 0, void 0, void 0,
125
169
  opts.auth = credentials;
126
170
  }
127
171
  const res = yield axios.get(url, opts);
128
- if (!((_a = res.data) === null || _a === void 0 ? void 0 : _a.values) || res.data.values.length <= 0) {
172
+ if (!((_f = res.data) === null || _f === void 0 ? void 0 : _f.values) || res.data.values.length <= 0) {
129
173
  throw new Error(i18nInstance.t("error-download-no-tags"));
130
174
  }
131
175
  const { tag } = yield inquirer
@@ -14,6 +14,7 @@ import fs from "fs-extra";
14
14
  import { PostCommands } from "../types/types.js";
15
15
  import url from "url";
16
16
  import { i18nInstance, logger } from "../jumpstart-plugin.js";
17
+ import { handleMicroprofileConfig } from "./handleMicroprofileConfig.js";
17
18
  export const extract = (bundle, file, command) => __awaiter(void 0, void 0, void 0, function* () {
18
19
  var _a;
19
20
  logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t("info-extract-extracting"));
@@ -28,7 +29,16 @@ export const extract = (bundle, file, command) => __awaiter(void 0, void 0, void
28
29
  yield extractApacheTomcat(dest, unzipFolder);
29
30
  }
30
31
  else {
31
- fs.copySync(unzipFolder, dest, { overwrite: true });
32
+ let sourceFolder = unzipFolder;
33
+ if (command === PostCommands.ExtractAndUnfold) {
34
+ const firstDir = fs.readdirSync(unzipFolder).find(item => {
35
+ const itemPath = path.join(unzipFolder, item);
36
+ return fs.statSync(itemPath).isDirectory();
37
+ });
38
+ sourceFolder = firstDir ? path.join(unzipFolder, firstDir) : unzipFolder;
39
+ }
40
+ fs.copySync(sourceFolder, dest, { overwrite: true });
41
+ yield handleMicroprofileConfig(bundle, dest);
32
42
  }
33
43
  fs.rmSync(unzipFolder, { recursive: true, force: true });
34
44
  fs.rmSync(path.dirname(file), { recursive: true, force: true });
@@ -0,0 +1,3 @@
1
+ import { Bundle } from "../types/types";
2
+ export declare const handleMicroprofileConfig: (bundle: Bundle, dest: string) => Promise<void>;
3
+ export declare function convertObjectToProperties(obj: any): any[];
@@ -0,0 +1,61 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import fs from "fs";
11
+ import path from "path";
12
+ import { getMicroprofileConfigLocation } from "./helper.js";
13
+ import { i18nInstance, logger } from "../jumpstart-plugin.js";
14
+ export const handleMicroprofileConfig = (bundle, dest) => __awaiter(void 0, void 0, void 0, function* () {
15
+ var _a;
16
+ if (!((_a = bundle.version) === null || _a === void 0 ? void 0 : _a.startsWith("6.3")))
17
+ return;
18
+ const tomcatPath = path.join(path.resolve(dest), '../../');
19
+ const webappName = path.basename(dest);
20
+ const pathToMicroprofileConfig = getMicroprofileConfigLocation(tomcatPath, webappName);
21
+ processMicroprofileConfigFile(pathToMicroprofileConfig);
22
+ });
23
+ export function convertObjectToProperties(obj) {
24
+ const props = [];
25
+ Object.keys(obj).forEach((key) => {
26
+ const val = obj[key];
27
+ if (val && typeof val === 'object' && !Array.isArray(val)) {
28
+ const children = convertObjectToProperties(val);
29
+ for (const child of children) {
30
+ props.push(key + '.' + child);
31
+ }
32
+ }
33
+ else {
34
+ props.push(key + '=' + val);
35
+ }
36
+ });
37
+ return props;
38
+ }
39
+ function createMicroprofileConfigFile(file) {
40
+ const microprofileConfig = {
41
+ magnolia: {
42
+ publishing: {
43
+ 'receivers[0]': {
44
+ name: 'magnoliaPublic8080',
45
+ url: 'http://localhost:8080/magnoliaPublic',
46
+ enabled: true
47
+ }
48
+ }
49
+ }
50
+ };
51
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('create-microprofile--info-creating-file', { file }));
52
+ return fs.writeFileSync(file, convertObjectToProperties(microprofileConfig).join('\n'), 'utf8');
53
+ }
54
+ function processMicroprofileConfigFile(file) {
55
+ if (fs.existsSync(file)) {
56
+ logger === null || logger === void 0 ? void 0 : logger.info(i18nInstance.t('create-microprofile--info-file-exists-skipping'));
57
+ }
58
+ else {
59
+ createMicroprofileConfigFile(file);
60
+ }
61
+ }
@@ -1,13 +1,14 @@
1
- import { Credentials, PluginRequirement } from "../types/types.js";
1
+ import { Credentials } from "../types/types.js";
2
2
  import { i18n } from "i18next";
3
3
  export declare function initI18n(pluginName: string, namespace?: string): i18n;
4
4
  export declare const handleLightModulesFolder: () => Promise<void>;
5
5
  export declare const findLightModulesFolder: (p: string) => Promise<unknown>;
6
6
  export declare const findWebAppsList: (apacheTomcatPath: string) => string[];
7
- export declare const installAdditionalPlugins: (plugins: Array<PluginRequirement>, credentials?: Credentials) => Promise<void>;
8
7
  export declare const initializeNodeProject: () => Promise<void>;
9
8
  export declare const installPackage: (packageManager: string, packageReference: string, packageName?: string, credentials?: Credentials) => Promise<boolean>;
10
9
  export declare const isValidURL: (str: string) => boolean;
11
10
  export declare const extractRepoName: (gitUrl: string) => string | null;
12
11
  export declare const determinePackageManager: (baseDirectory?: string) => "yarn" | "npm";
13
12
  export declare const askForCredentials: () => Promise<Credentials>;
13
+ export declare function getWebAppConfigDefaultFolderLocation(tomcatFolder: string, instance: string): string;
14
+ export declare function getMicroprofileConfigLocation(tomcatFolder: string, instance: string): string;
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { handleMGNLConfigFile, installAndConfigPlugins } from "./config-helper.js";
10
+ import { handleMGNLConfigFile } from "./config-helper.js";
11
11
  import { handlePackageJSON } from "./pj-helper.js";
12
12
  import i18next from "i18next";
13
13
  import Backend from 'i18next-fs-backend';
@@ -160,9 +160,6 @@ export const findWebAppsList = (apacheTomcatPath) => {
160
160
  }
161
161
  return webApps;
162
162
  };
163
- export const installAdditionalPlugins = (plugins, credentials) => __awaiter(void 0, void 0, void 0, function* () {
164
- yield installAndConfigPlugins(plugins, credentials);
165
- });
166
163
  export const initializeNodeProject = () => __awaiter(void 0, void 0, void 0, function* () {
167
164
  yield handlePackageJSON();
168
165
  yield handleMGNLConfigFile();
@@ -238,3 +235,9 @@ export const askForCredentials = () => __awaiter(void 0, void 0, void 0, functio
238
235
  }
239
236
  ]);
240
237
  });
238
+ export function getWebAppConfigDefaultFolderLocation(tomcatFolder, instance) {
239
+ return path.join(tomcatFolder, 'webapps', instance, 'WEB-INF', 'config', 'default');
240
+ }
241
+ export function getMicroprofileConfigLocation(tomcatFolder, instance) {
242
+ return path.join(getWebAppConfigDefaultFolderLocation(tomcatFolder, instance), 'microprofile-config.properties');
243
+ }
@@ -1,15 +1,18 @@
1
1
  {
2
- "cmd-option-template": "Choose template",
3
- "cmd-option-project-templates-path": "Specify from where the projectTemplates should be loaded",
2
+ "cmd-option-description": "download and set up a new headless or freemarker-based project with Magnolia webapp",
3
+ "cmd-option-template": "choose a template from available project templates",
4
+ "cmd-option-project-templates-path": "specify the path to load project templates from",
5
+ "cmd-option-magnolia-version": "set the Magnolia version; defaults to the latest stable version",
6
+ "cmd-option-snapshot": "download the latest snapshot version of the specified or latest stable webapp",
4
7
 
5
8
  "prompt-enter-credentials": "Please enter credentials for {{bundle}}",
6
- "prompt-project-templates-credentials": "Please enter credentials",
7
9
 
8
10
  "info-template_not_found": "The '{{template}}' template was not found.",
9
11
  "info-jumpstart_started": "'JumpstartPlugin' plugin started successfully.",
10
12
  "info-jumpstart_stopped": "'JumpstartPlugin' stopped",
11
13
  "info-config-h-will-install-missing-plugins": "Will attempt to install missing plugins",
12
14
  "info-config-h-mgnl-config-updated": "mgnl.config.js updated",
15
+ "info-config-h-mgnl-vars-added": "Shared variables added to mgnl.config.js",
13
16
  "info-download-preparing": "Preparing to download {{url}}",
14
17
  "info-download-starting": "Starting download from: {{downloadUrl}}",
15
18
  "info-download-finished": "Download finished",
@@ -28,16 +31,22 @@
28
31
  "info-helper-package-installed": "{{packageName}} installed",
29
32
 
30
33
  "warn-config-h-could-not-install-cli": "Couldn't install @magnolia/cli",
34
+ "warn-config-h-no-add-plugin": "Cannot find add-plugin command. Please update @magnolia/cli package.",
35
+ "warn-config-h-install-plugins-manually": "Please install following plugins:\n{{installPluginsText}}and add them to mgnl.config.js manually.",
31
36
  "warn-pj-helper-changing-type": "Changing 'type' to \"module\"",
32
37
  "warn-helper-webapp-props-not-exist": "File {{filePath}} doesn't exists, skipping configuration.",
33
38
  "warn-helper-cannot-modify-webapp": "Cannot modify webapps: {{errorMsg}}",
39
+ "warn-config-h-error-cannot-parse-plugin-args": "Provided plugin argument:\n{{pluginArgs}}\nis not a valid JSON5 object.",
34
40
 
35
41
  "error-config-h-could-not-read-mgnl-config": "Couldn't read {{configPath}}",
36
42
  "error-config-h-could-not-parse-mgnl-config": "Couldn't parse {{configPath}}, please check the file for issues",
37
43
  "error-config-h-while-updating-mgnl-config": "Error occurred while updating mgnl.config.js",
44
+ "error-config-h-while-adding-vars": "Error occurred while adding variables to mgnl.config.js",
45
+ "error-config-h-while-add-plugin": "An error occurred while installing following plugin: {{plugin}}",
38
46
  "error-download-no-tags": "There are no available tags",
39
47
  "error-download-problem-accessing-url": "A problem was detected while accessing: {{url}}.",
40
48
  "error-download-unable-to-get-local-issuer-certificate": "The \"unable to get local issuer certificate\" error indicates that something in your infrastructure is preventing the CLI from downloading the Magnolia artifacts. This is not a bug in the CLI. For example, you may be behind a proxy that requires certain certificates. You might be able to ask your infrastructure team to allow requests to the Magnolia artifact repository: https://nexus.magnolia-cms.com/ Please search the web on \"unable to get local issuer certificate\" for more information.",
49
+ "error-download-no-artifact-available": "No Magnolia bundle with \"{{version}}\" version is available.",
41
50
  "error-extensions-calling-fn-retry": "Error Calling Function {{name}}. {{retry}}/{{maxRetry}}. Waiting {{delay}}ms before retry.",
42
51
  "error-extensions-fn-not-found": "{{function}} Function not found",
43
52
  "error-extensions-path-not-found": "{{extensionsPath}} not found. Could not evaluate custom prompts.",
@@ -51,11 +60,18 @@
51
60
  "error-helper-webapp-props-update-error": "An error occurred while updating 'magnolia.properties': {{errorMsg}}",
52
61
  "error-helper-lm-not-found": "light-modules was not found",
53
62
  "error-helper-fail-to-install-package": "Failed to install {{packageName}}",
63
+ "error-option-param-is-flag": "option \"{{option}}\" argument missing. Provided value: \"{{value}}\" is a flag",
54
64
 
55
65
  "ora-updating-mgnl-config": "Updating mgnl.config.js",
66
+ "ora-adding-shared-vars": "Adding variables to mgnl.config.js",
56
67
  "ora-installing-ext-dep": "Installing Extension Dependencies",
57
68
  "ora-installing-dep": "Installing dependencies",
58
69
  "ora-running-npm-install": "Didn't find 'node_modules' folder. Running 'npm install'",
59
70
  "ora-creating-pj": "Creating package.json",
60
- "ora-installing-package": "Installing {{packageName}}"
71
+ "ora-installing-package": "Installing {{packageName}}",
72
+
73
+ "install-plugin-with-args-text": "\twith following args: {{pluginArgs}}\n",
74
+
75
+ "create-microprofile--info-file-exists-skipping": "File microprofile-config.properties already exists. Skipping...",
76
+ "create-microprofile--info-creating-file": "Creating microprofile-config.properties at {{file}}"
61
77
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magnolia/cli-jumpstart-plugin",
3
- "version": "1.0.0-preview.4",
3
+ "version": "1.0.0-preview.6",
4
4
  "description": "Plugin to set up new projects using predefined templates and bundles. Easily select and configure project templates, and let the plugin handle bundle downloads, extraction, and post-command execution.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -28,7 +28,9 @@
28
28
  "typescript": "^5.1.6"
29
29
  },
30
30
  "dependencies": {
31
+ "@babel/generator": "^7.24.4",
31
32
  "@babel/parser": "^7.23.6",
33
+ "@babel/traverse": "^7.24.1",
32
34
  "@babel/types": "^7.23.6",
33
35
  "@magnolia/cli-plugin-template": "^1.1.0",
34
36
  "axios": "^1.4.0",
@@ -43,6 +45,7 @@
43
45
  "i18next-fs-backend": "^2.3.1",
44
46
  "inquirer": "^9.2.8",
45
47
  "js-beautify": "^1.14.9",
48
+ "json5": "^2.2.3",
46
49
  "ora": "^7.0.1",
47
50
  "progress": "^2.0.3",
48
51
  "underscore": "^1.13.6",
@@ -1,6 +1,8 @@
1
1
  export interface PluginOptions {
2
2
  template: string | boolean;
3
3
  projectTemplatesPath: string;
4
+ magnoliaVersion?: string;
5
+ snapshot?: boolean;
4
6
  }
5
7
  export interface Bundle {
6
8
  url: string;
@@ -10,6 +12,11 @@ export interface Bundle {
10
12
  dest?: string;
11
13
  downloadDest?: string;
12
14
  name?: string;
15
+ version?: string;
16
+ alternative: {
17
+ groupId: string;
18
+ artifactId: string;
19
+ };
13
20
  }
14
21
  export interface TemplateBase {
15
22
  name: string;
@@ -19,28 +26,33 @@ export interface TemplateWithChildren extends TemplateBase {
19
26
  children: Array<Template>;
20
27
  bundles?: never;
21
28
  plugins?: never;
29
+ configVars?: never;
22
30
  }
23
31
  export interface TemplateWithBundles extends TemplateBase {
24
32
  bundles: Array<Bundle>;
25
33
  children?: never;
26
34
  plugins?: never;
35
+ configVars?: never;
27
36
  }
28
37
  export interface TemplateWithPlugins extends TemplateBase {
29
38
  plugins: Array<PluginRequirement>;
30
39
  bundles?: never;
31
40
  children?: never;
41
+ configVars?: never;
32
42
  }
33
43
  export interface TemplateWithBundlesAndPlugins extends TemplateBase {
34
44
  bundles: Array<Bundle>;
35
45
  plugins: Array<PluginRequirement>;
36
46
  children?: never;
47
+ configVars?: {
48
+ [key: string]: any;
49
+ };
37
50
  }
38
51
  export type TemplateWithoutChildren = TemplateWithBundles | TemplateWithPlugins | TemplateWithBundlesAndPlugins;
39
52
  export type Template = TemplateWithChildren | TemplateWithoutChildren;
40
53
  export interface PluginRequirement {
41
- name: string;
42
- installReference: string;
43
- options?: any;
54
+ plugin: string;
55
+ pluginArgs?: any;
44
56
  }
45
57
  export type Credentials = {
46
58
  username: string;
@@ -49,26 +61,10 @@ export type Credentials = {
49
61
  export declare enum PostCommands {
50
62
  Extract = "extract",
51
63
  ExtractAndOverride = "extract and override",
64
+ ExtractAndUnfold = "extract and unfold",
52
65
  NpmInstall = "npm install",
53
66
  YarnInstall = "yarn install"
54
67
  }
55
- export interface PluginRequirement {
56
- name: string;
57
- installReference: string;
58
- }
59
- export type ImportItem = {
60
- importedNames: string;
61
- importSource: string;
62
- };
63
- export interface CommandItem {
64
- commandName: string;
65
- options?: any;
66
- }
67
- export type ParsedConfigData = {
68
- configContent: string;
69
- imports: ImportItem[];
70
- commands: CommandItem[];
71
- };
72
68
  export interface PostCommandFunction {
73
69
  function: string;
74
70
  delay: number;
@@ -2,6 +2,7 @@ export var PostCommands;
2
2
  (function (PostCommands) {
3
3
  PostCommands["Extract"] = "extract";
4
4
  PostCommands["ExtractAndOverride"] = "extract and override";
5
+ PostCommands["ExtractAndUnfold"] = "extract and unfold";
5
6
  PostCommands["NpmInstall"] = "npm install";
6
7
  PostCommands["YarnInstall"] = "yarn install";
7
8
  })(PostCommands || (PostCommands = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magnolia/cli-jumpstart-plugin",
3
- "version": "1.0.0-preview.4",
3
+ "version": "1.0.0-preview.6",
4
4
  "description": "Plugin to set up new projects using predefined templates and bundles. Easily select and configure project templates, and let the plugin handle bundle downloads, extraction, and post-command execution.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -28,7 +28,9 @@
28
28
  "typescript": "^5.1.6"
29
29
  },
30
30
  "dependencies": {
31
+ "@babel/generator": "^7.24.4",
31
32
  "@babel/parser": "^7.23.6",
33
+ "@babel/traverse": "^7.24.1",
32
34
  "@babel/types": "^7.23.6",
33
35
  "@magnolia/cli-plugin-template": "^1.1.0",
34
36
  "axios": "^1.4.0",
@@ -43,6 +45,7 @@
43
45
  "i18next-fs-backend": "^2.3.1",
44
46
  "inquirer": "^9.2.8",
45
47
  "js-beautify": "^1.14.9",
48
+ "json5": "^2.2.3",
46
49
  "ora": "^7.0.1",
47
50
  "progress": "^2.0.3",
48
51
  "underscore": "^1.13.6",