@elo/elo-cli 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3827 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { unlinkSync, readFileSync as readFileSync$1 } from "fs";
4
+ import pathLib, { dirname, join } from "path";
5
+ import { fileURLToPath } from "url";
6
+ import { createHash, createDecipheriv, randomBytes, createCipheriv } from "node:crypto";
7
+ import { readFile, writeFile as writeFile$2, accessSync, readFileSync, readdirSync, createReadStream, mkdirSync, createWriteStream } from "node:fs";
8
+ import { access, writeFile as writeFile$1, rm, readFile as readFile$1, readdir } from "node:fs/promises";
9
+ import chalk from "chalk";
10
+ import archiver from "archiver";
11
+ import axios from "axios";
12
+ import { wrapper } from "axios-cookiejar-support";
13
+ import { JSDOM } from "jsdom";
14
+ import readline from "readline";
15
+ import { CookieJar } from "tough-cookie";
16
+ import { Client, LockC, PackageC, ConflictHandlingE } from "@elo/ix-client-typescript";
17
+ import { pipeline } from "stream/promises";
18
+ import prompts from "prompts";
19
+ import { execSync, exec } from "child_process";
20
+ import { readdir as readdir$1 } from "fs/promises";
21
+ import readline$1 from "node:readline";
22
+ import FastGlob from "fast-glob";
23
+ import os from "os";
24
+ const CONSTANTS = {
25
+ PLACEHOLDER: {
26
+ PATH: "[path]",
27
+ URL: "[url]",
28
+ LANG: "[lang]",
29
+ NAME: "[name]",
30
+ NUMBER: "[number]",
31
+ YESNO: "[y/n]",
32
+ PW: "[pw]"
33
+ },
34
+ MANIFESTFILE: "manifest.json",
35
+ MAINTSFILE: "main.ts",
36
+ MAINJSFILE: "main.js",
37
+ PACKAGEFILE: "package.json",
38
+ LICENSECASES: [
39
+ "LICENCE",
40
+ "LICENSE",
41
+ "License",
42
+ "license",
43
+ "LICENSE-MIT",
44
+ "LICENSE.txt",
45
+ "License.txt",
46
+ "license.txt",
47
+ "LICENSE.md",
48
+ "License.md",
49
+ "license.md",
50
+ "LICENSE.BSD",
51
+ "LICENSE-MIT.txt",
52
+ "LICENCE.md"
53
+ ],
54
+ NOTICECASES: [
55
+ "NOTICE",
56
+ "Notice",
57
+ "notice",
58
+ "NOTICE.txt",
59
+ "Notice.txt",
60
+ "notice.txt",
61
+ "NOTICE.md",
62
+ "Notice.md",
63
+ "notice.md"
64
+ ],
65
+ GLOBBYPATTERN: "**/*.{js,ts,vue}",
66
+ GLOBBYOPTIONS: {
67
+ ignore: [
68
+ "public/**",
69
+ "coverage/**",
70
+ "dist/**",
71
+ "node_modules/**",
72
+ "tests/**",
73
+ "elo-vue-libs/**",
74
+ "locales/**",
75
+ "src/locales/**",
76
+ "jsLocales/**",
77
+ "src/lib/jsLocales/**",
78
+ "src/lib/misc/**",
79
+ "main.js",
80
+ "babel.config.js",
81
+ "nyc.config.js",
82
+ "postcss.config.js",
83
+ "vue.config.js",
84
+ "nav.config"
85
+ ]
86
+ },
87
+ DEPENDENCIETYPES: ["dependencies", "devDependencies", "peerDependencies"],
88
+ DASHEDLINE: "--------------------------------------------------------------------------------",
89
+ LICENSEFILEHEADER: `THIRD-PARTY SOFTWARE LICENSES, NOTICES AND INFORMATION FOR %s.
90
+
91
+ Do Not Translate or Localize
92
+
93
+ This file is based on or incorporates material from third party (Third Party IP). Therefore this file contain third party notices or additional terms and conditions applicable to certain software technologies which may be used in one or more ELO products and/or services.
94
+ Please be sure to consult the individual product files, about box and/or install or manual documentation for specific copyright notices and author attributions. Notices in this file are current for ELO products released on or after February, 2020.
95
+ The original copyright notice and the license under which ELO received such Third Party IP, are set forth below. Such licenses and notices are provided for informational purposes only. ELO licenses the Third Party IP to you under the licensing terms for the ELO product.
96
+ ELO reserves all other rights not expressly granted under this agreement, whether by implication, estoppel or otherwise.
97
+
98
+
99
+ Written Offer for Source Code
100
+
101
+ For Third-Partry IP received from ELO that are licensed under any version of the GNU General Public License (GPL) or the GNU LGPL, or another license that claim to provide the sources, you can receive a complete machine-readable copy of the source code by sending a written request to:
102
+
103
+ ELO Digital Office GmbH
104
+ Tübinger Straße 43
105
+ 70178 Stuttgart
106
+
107
+ Your request should include: (i) the name of the covered binary, (ii) the version number of the Oracle product containing the covered binary, (iii) your name, (iv) your company name (if applicable) and (v) your return mailing and email address (if available).
108
+
109
+ We may charge you a nominal fee to cover the cost of the media and distribution.
110
+
111
+ Your request must be sent within three (3) years of the date you received the GPL or LGPL covered code.
112
+
113
+ Additionally, the source code may also be found at:
114
+ https://download.elo.com/oss/
115
+
116
+
117
+ `
118
+ };
119
+ const STRING = {
120
+ INIT: {
121
+ INFO: "ELO Apps command line build system for Node.js.",
122
+ START: "Running init command",
123
+ DESCRIPTION: "Init nodejs web application as ELO app.",
124
+ OPTIONS: {
125
+ WFURL: { DESC: "Url to the ELOwf instance, for example: %s" },
126
+ INDEXHTML: { DESC: "The name of the index file, for example: %s" },
127
+ SORDTYPEICONS: {
128
+ DESC: "Are 'ELO Sordtype Icons' required for this project? For example: %s"
129
+ },
130
+ ARCHIVEICON: { DESC: "Are 'Archive Icons' required for this project? For example: %s" },
131
+ SRC: {
132
+ DESC: "The relative path where the source files, like the index.html, are, for example: %s"
133
+ },
134
+ DIST: {
135
+ DESC: "The relative path where the output files, like the index.html, will be, for example: %s"
136
+ },
137
+ INDEXHTMLPATH: {
138
+ DESC: "The relative path where the index.html file is located, for example in Vue2: %s for Vue3 it is ."
139
+ },
140
+ NAMESPACE: { DESC: "The app namespace, for example: %s" },
141
+ ID: { DESC: "The app id, for example: %s" },
142
+ DEFAULTLANGUAGE: { DESC: "The default language, for example: %s" },
143
+ BUILD: { DESC: "The build number of the app, for example: %s" },
144
+ USEELOSESSION: { DESC: "Enable, to use elo session, for example: %s" },
145
+ DEVREDIRECT: {
146
+ DESC: "Dev url of the app, which the login site of the ELOwf will redirect after successfull login. Necessary if elo session is enabled, for example: %s"
147
+ }
148
+ },
149
+ DEPLOY: {
150
+ OPTIONS: {
151
+ REPOSYTORY: { DESC: "Repository containing json config file, for example: %s" }
152
+ }
153
+ }
154
+ },
155
+ SETUP: {
156
+ DESC: "Create default settings for all upcoming initializations.",
157
+ OPTIONS: {
158
+ SERVERURL: { DESC: "Url of the server, for example: %s" },
159
+ ADMINNAME: { DESC: "Username of an administrator for a ix login." },
160
+ ADMINPW: {
161
+ DESC: "According administrator password. This password will be stored encrypted but the key is not secure and can be read from the current machines hard drive. Only use test installations."
162
+ },
163
+ NEWREPO: { DESC: "Creates new project archive settings." }
164
+ }
165
+ },
166
+ NEWREPO: {
167
+ DESC: "Creates '.elo-repositories/[archiveName].json' file containing project archive settings.",
168
+ OPTIONS: {}
169
+ },
170
+ DEPLOY: {
171
+ DESC: "Deploys the web application into the ELOwf",
172
+ OPTIONS: {
173
+ REPOSITORY: {
174
+ DESC: "Repository containing json config file, for example: %s"
175
+ },
176
+ NEON: {
177
+ DESC: "To deploy a Neon extension the client plugin, instead of an ELO App to the ELOwf."
178
+ }
179
+ }
180
+ },
181
+ BUILD: {
182
+ DESC: "Builds the web application.",
183
+ OPTIONS: {
184
+ KEY: {
185
+ DESC: "Sets the an arbitrary json key in the manifest.json, for example: %s"
186
+ },
187
+ VALUE: {
188
+ DESC: "Sets the value of the key value pair, defined by --key, for example: %s"
189
+ }
190
+ }
191
+ },
192
+ IMPORT: {
193
+ DESC: "Imports package or archive data into the ELO repository.",
194
+ OPTIONS: {
195
+ MODE: {
196
+ DESC: "The type of import 'archive' for archive data, 'workflow' for a workflow-template, 'entry' for an arbitrary file or 'package' for an ELO package."
197
+ },
198
+ GUID: {
199
+ DESC: "[archive|entry] The guid of the folder in the repository to import the data to. [workflow] The user id unknown person nodes will be replaced with."
200
+ },
201
+ SRC: {
202
+ DESC: "The file of the import data."
203
+ },
204
+ FLOWNAME: {
205
+ DESC: "[workflow] The template name of the imported workflow."
206
+ },
207
+ RELOADSCRIPTS: {
208
+ DESC: "[entry: type=script] Reloads the scripts after the import."
209
+ }
210
+ }
211
+ },
212
+ EXPORT: {
213
+ DESC: "Exports package or archive data from the ELO repository.",
214
+ OPTIONS: {
215
+ GUID: {
216
+ DESC: "The guid of the entry or the name/guid of the package to export."
217
+ },
218
+ DIST: {
219
+ DESC: "The file of the export data."
220
+ }
221
+ }
222
+ },
223
+ LOCALIZE: {
224
+ DESC: "Creates the language files for the web application.",
225
+ OPTIONS: {
226
+ SRC: { DESC: "The path where the properties files are." },
227
+ DIST: { DESC: "The path where the js files will be. The directory will be cleared." }
228
+ }
229
+ },
230
+ HELPER: {
231
+ CRYPTKEY: "NW7jFhExSLRtwtZWvMq9HKGb3yZTPS89d4ebEbR7mmWHcuVNYfU9XqJrbBw6Ms2uNTePNBBp67WV7KTe6FeVZNr7rdvGY3ZyjBYTWdNpxuVBKtDEfZRYm7Lqn8BHpNSsQp3tAqEuhva4wKwyTHwdEhx7qSwCAw7qaGxKdSYNqQeRuCCrKzDjX4URvAFmreTtruVrj88EBznS4CPeDHqnCsF6YAg2sSm9JyRgtCTwgGaQ6uFgvH8WZ6X4Hefvj8nZ",
232
+ DEPRECATED_ENCRYPTION: "The settings file uses an old, deprecated encryption. Please update the settings file using 'elo setup'.",
233
+ EMPTYPATH: "The file could not be located in the specified path.",
234
+ NOPATH: "The specified path does not exist.",
235
+ PATH_NOT_EXIST: "%s does not exist!"
236
+ },
237
+ UTILS: {
238
+ OPTION_NOT_VALID: "%s is not valid!"
239
+ },
240
+ INFO: {
241
+ SETTINGSBUILD: "Setting build to %s",
242
+ COPYFILES: "Copying files into ELOwf",
243
+ IXCONNECT: "Creating ix connection",
244
+ SETKEYVALUE: "Existing value of key '%s' will be overwritten in dist/manifest.json.",
245
+ CHARSREPLACED: "All restricted characters in 'id' were replaced with an underscore ('_').",
246
+ MANIFESTSTORED: "Manifest stored",
247
+ COPYMANIFEST: "Copying manifest into ELOwf",
248
+ WFREQUEST: "Sending request to ELOwf",
249
+ WFREQUESTSUCCESS: "ELOwf successfully called",
250
+ IXCONNSUCCESS: "Connection to ix was successful",
251
+ MAINJSEMPTY: "'main.js' is empty",
252
+ MAINJS: "Please make sure, that your 'main.js' looks like this:",
253
+ MAINTS: "Please make sure, that your 'main.ts' looks like this:",
254
+ INITCOMPLETE: "Initialization completed",
255
+ VUECONFJS: "Please create or modify your 'vue.config.js' file to the following:",
256
+ VITECONFTS: "Please create or modify your 'vite.config.ts' file to the following:",
257
+ NOVUEAPP: "No Vue.js app",
258
+ WFREFRESH: "Trying a refresh in ELOwf AppManager at: ",
259
+ WFREFRESHCOMPLETED: "Refresh in ELOwf AppManager completed",
260
+ WRITINGSETUP: "Writing setup file (%s)",
261
+ PATHCREATED: "'%s' created.",
262
+ REPOCONFSAVE: "Repository settings saved %s",
263
+ SETUPCOMPLETE: "Setup completed",
264
+ SKIP: "Pressing enter will skip the current option",
265
+ SETUPCOMPLETED: "Setup completed",
266
+ BUILDCOMPLETED: "Build completed",
267
+ DEPLOYCOMPLETED: "Deploy completed",
268
+ NEONDEPLOY: "Trying a send extension to neon: ",
269
+ NEONDEPLOYCOMPLETED: "Extension upload to neon was successful",
270
+ RELOADCOMPLETE: "The reload was successful",
271
+ IMPORTCOMPLETE: "The import was successful",
272
+ EXPORTCOMPLETE: "The export was successful",
273
+ LICENSESAVED: "in '3rdpartylicenses.txt' saved.",
274
+ NPMFOUND: "Detected npm as package manager.",
275
+ PNPMFOUND: "Detected pnpm as package manager.",
276
+ YARNFOUND: "Detected yarn as package manager.",
277
+ CREATINGPATH: "Creating path %s",
278
+ CREATINGDEFAULTLANGFILE: "Creating default language file",
279
+ CHECKDUPLICATEKEYS: "Checking '%s' file for key duplicates",
280
+ NOKEYDUPLICATESFOUND: "No key duplicates found",
281
+ CHECKUNUSEDKEYS: "Checking '%s' files for unused keys",
282
+ NOUNUSEDKEYSFOUND: "No unused keys in '%s' files found.",
283
+ CREATEDISTDIR: "Create dist folder at '%s'.",
284
+ CREATELOCALESDIR: "Create locales folder at '%s'.",
285
+ NOUNUSEDKEYS: "No unused keys found.",
286
+ PROPERTIESPROCESSED: "Process properties file '%s' completed.",
287
+ STARTINTIGRITYCHECK: "Starting language integrity check...",
288
+ LANGUAGEINTEGRITYCHECK: "Language integrity check for '%s' completed.",
289
+ NEWLANGUAGEFOUND: "Language '%s' found in properties file but not listed in manifest supported locales.",
290
+ WRITELOCALESFILE: "Completing writing locales file '%s'.",
291
+ LOCALIZATIONCOMPLETE: "Localization complete.",
292
+ WRITEREPORTFILE: "Writing localization report file to '%s'.",
293
+ REPORTCOMPOLETED: "Localization report file written.",
294
+ MUTATEPACKAGEJSON: "Mutating package.json versions for package '%s'.",
295
+ MUTATEMANIFEST: "Mutating manifest.json version for package '%s'.",
296
+ CONFIGVALIDATED: "Multi-repo configuration validated successfully.",
297
+ STARTPUBLISHCOMMAND: "Starting publish command...",
298
+ MULTIREPOMODE: "Multi-repo mode enabled.",
299
+ PUBLISHSUCCESS: "Publish for package '%s' successful.",
300
+ PUBLISHLATESTSUCCESS: "Publish latest tag for package '%s' successful.",
301
+ PUBLISHCOMMANDCOMPLETED: "Publish command completed successfully."
302
+ },
303
+ WARN: {
304
+ IXNOTINIT: "IXClient was not initialized.",
305
+ IDLENMSG: "'id' (ELO App id) exceeds the maximum amount of 30 characters ('id' length restriction). 'id' has currently %s characters.",
306
+ NOID: "'id' (ELO App id) is empty.",
307
+ NOCLILINKING: "Linking of 'elo-cli' is not supported by 'elo link'. This may fail. Consider removing it from your 'package.json' eloDependencies array key.",
308
+ LICENSENOTFOUND: "No license found for: %s",
309
+ CHANGELANGUAGEVALUE: "Key '%s' in language '%s' is missing. Using language '%s' value."
310
+ },
311
+ ERROR: {
312
+ INDEXHTMLNOTFOUND: "'index.html' not found in: %s",
313
+ WFREFRESHSKIP: "Skipped refresh in ELOwf AppManager, because %s is not given. It can be set with the elo setup command.",
314
+ IXCONNECTSKIP: "The try to connect to IX was skipped because credentials were not provided. This can be configured using the elo setup command.",
315
+ PATHNOTEXIST: "%s does not exist!",
316
+ NOVALUE: "--value <undefined>' parameter is undefined. Use '--key myKey --value myValue.",
317
+ NOKEY: "--key <undefined>' parameter is undefined. Use '--key myKey --value myValue.",
318
+ WFREFRESH: "Refresh in ELOwf AppManager failed",
319
+ IXCONN: "Could not create ix connection",
320
+ MAINJSNOTFOUND: "'main.js' not found!",
321
+ WFREQUEST: "Request to ELOwf failed",
322
+ PROMPT: "Couldnt prompt for input. If this has occurred during a password prompt, then your command line does not support this.",
323
+ OPTIONNOTVALID: "%s is not valid!",
324
+ NOSETTINGSPATH: "Path '%s' does not exist.",
325
+ NOSETTINGSFOUND: 'No settings found. Please run "elo setup" first.',
326
+ NOMANIFEST: "No 'manifest.json' found in the project root",
327
+ NEONDEPLOY: "Error uploading extension to neon.",
328
+ IMPORT: "Could not import file.",
329
+ EXPORT: "Could not export file.",
330
+ NOTENOUGHARGSFORINJECT: "Not enough arguments for an injection given!",
331
+ PACKAGENOTFOUND: 'Package "%s" does not exist in the repository.',
332
+ NOELODEPENDENCIES: "'No 'ELO Dependencies' found to link in 'package.json'.\nDoes 'package.json' contain 'eloDependencies' key?'",
333
+ LINKDEPENDENCY: "Could not link dependencies.",
334
+ NOPACKAGEMANAGERFOUND: "No supported package manager found in the project directory tree.",
335
+ SRCPATHREQIRED: "* Source path is required.",
336
+ DISTPATHREQIRED: "* Distribution path is required.",
337
+ NODEFAULTLANG: "* No default language found in manifest data.",
338
+ NOSUPPORTEDLOCALES: "* No supported locales found in manifest data.",
339
+ PROPERTIESNOTFOUND: "No properties file found in src directory.",
340
+ CREATENEWLOCALES: "Could not create new localization files: %s",
341
+ CHECKUNUSEDKEYS: "Error while checking unused keys: %s",
342
+ DUPDEFAULTLANGFILE: "Duplicate default language file found. Only one default language file is allowed.",
343
+ WRITELOCALESFILE: "Error while writing locales file: %s",
344
+ GETPROPERTYFILES: "Error while getting property files: %s",
345
+ GETKEYSCHECKDUPLICATES: "Error while getting keys and checking duplicates: %s",
346
+ CREATELOCALESMAP: "Error while creating locales map: %s",
347
+ MULTIREPOCONFIGEMPTYPART: 'Each repository in multi-repo configuration must have a "path" and "name" property.',
348
+ PACKAGEJSONNOTFOUND: "package.json not found at path: %s",
349
+ CREDENTIALSWROMGFORMAT: "Credentials must be in the format username:password",
350
+ CONFIGFILENOTFOUND: "Multi-repo configuration file not found at path: %s",
351
+ PUBLISHPRIVATEPACKAGE: 'Cannot publish a private package. Please set "private": false in package.json. Package: %s'
352
+ },
353
+ CODE: {
354
+ MAINJSCODE: [
355
+ "import Vue from 'vue';",
356
+ "import App from './App.vue';",
357
+ "import { WebApp } from '@elo/core';",
358
+ "// if IXConnecttion is needed",
359
+ "import de from '@elo/eloixclient';",
360
+ "// if ELO session is needed",
361
+ "import { Session } from '@elo/session';",
362
+ "",
363
+ "// Initialize Vue after initializing the ELO App.",
364
+ "WebApp.setOnLoad(function() {",
365
+ " new Vue({",
366
+ " render: (h) => h(App)",
367
+ " }).$mount('#app');",
368
+ "});",
369
+ "// Initialize the ELO App.",
370
+ "// if no ELO session is needed",
371
+ "// WebApp.init();",
372
+ "// if ELO session is needed, but no IXConnection",
373
+ "// Session.init();",
374
+ "// if IXConnection is needed",
375
+ "Session.init(de.elo.ix.client);"
376
+ ],
377
+ MAINTSCODE: [
378
+ "import { createApp } from 'vue'",
379
+ "import { initEloBaseServices, ixService, logger } from '@elo/elo-base-lib';",
380
+ "import { LockC, EditInfoC } from '@elo/ix-client-typescript';",
381
+ "...",
382
+ "import App from './App.vue'",
383
+ "",
384
+ "// Initialize the elo base services",
385
+ "try {",
386
+ " await initEloBaseServices() // perform redirect to ELO login if not authenticated.",
387
+ "",
388
+ " // --- example call to ix: checkout root repository folder.",
389
+ " const sord = await ixService.callIxEndpoint('checkoutSord', {",
390
+ " objId: '1',",
391
+ " editInfoZ: EditInfoC.mbSord,",
392
+ " lockZ: LockC.NO",
393
+ " })",
394
+ " logger.info('Checked out sord:', sord.sord!.name);",
395
+ " // ---",
396
+ "",
397
+ " createApp(App).mount('#app') // <- mount the app after initialization is complete",
398
+ "} catch (error) {",
399
+ " console.error('Failed to initialize ELO Base Lib:', error);",
400
+ "}"
401
+ ],
402
+ VITECONFTSCODE: [
403
+ "import { defineConfig, ProxyOptions } from 'vite'",
404
+ "import TestHelpers from '@elo/elo-cli'; // load global config from elo-cli",
405
+ "...",
406
+ "",
407
+ "TestHelpers.init(<repository?>); //repository is optional",
408
+ "",
409
+ "const config = {",
410
+ " ...,",
411
+ " base: '',",
412
+ " server: {",
413
+ " ...,",
414
+ " port: <port>, // must be the same as devRedirect in manifest.json",
415
+ " proxy: {} as Record<string, string | ProxyOptions>",
416
+ " }",
417
+ "};",
418
+ "config.server.proxy[TestHelpers.getIxContext()] = {",
419
+ " target: TestHelpers.getIxServer(),",
420
+ " changeOrigin: true",
421
+ "};",
422
+ "export default defineConfig(config);"
423
+ ],
424
+ VUECONFJSCODE: [
425
+ "import TestHelpers from '@elo/elo-cli'; // load global config from elo-cli",
426
+ "",
427
+ "TestHelpers.init(<repository?>); //repository is optional",
428
+ "",
429
+ "let config = {",
430
+ " publicPath: './',",
431
+ " devServer: {",
432
+ " disableHostCheck: true,",
433
+ " proxy: {}",
434
+ " }",
435
+ "};",
436
+ "config.devServer.proxy[TestHelpers.getIxContext()] = {",
437
+ " target: TestHelpers.getIxServer(),",
438
+ " secure: false,",
439
+ " logLevel: `debug`",
440
+ "};",
441
+ "module.exports = config;"
442
+ ]
443
+ }
444
+ };
445
+ var messageTypes = /* @__PURE__ */ ((messageTypes2) => {
446
+ messageTypes2["INFO"] = "INFO";
447
+ messageTypes2["WARN"] = "WARN";
448
+ messageTypes2["ERROR"] = "ERROR";
449
+ messageTypes2["DEFAULT"] = "";
450
+ return messageTypes2;
451
+ })(messageTypes || {});
452
+ const EXIT_WITH_ERROR = 1;
453
+ process.env.ELOBUILDSETTINGSPATH = `${process.env[process.platform === "win32" ? "USERPROFILE" : "HOME"]}/.elo-cli-settings.json`;
454
+ const globalSettingsPath = process.env.ELOBUILDSETTINGSPATH;
455
+ const cryptKey = STRING.HELPER.CRYPTKEY;
456
+ function ensureSlash(text = "") {
457
+ return text.endsWith("/") ? text : `${text}/`;
458
+ }
459
+ function unixPathSep(path = "") {
460
+ return path.replace(/\\+/g, "/");
461
+ }
462
+ function message(type, msg, ..._opt) {
463
+ switch (type) {
464
+ case messageTypes.INFO:
465
+ console.log(chalk.cyan(` [${type}] ${msg}`), ..._opt);
466
+ break;
467
+ case messageTypes.WARN:
468
+ console.log(chalk.yellow(` [${type}] ${msg}`), ..._opt);
469
+ break;
470
+ case messageTypes.ERROR:
471
+ console.log(chalk.red(` [${type}] ${msg}`), ..._opt);
472
+ break;
473
+ case messageTypes.DEFAULT:
474
+ default:
475
+ console.log(` ${msg}`, ..._opt);
476
+ }
477
+ }
478
+ function error(error2, noExit, ..._opt) {
479
+ console.log(chalk.red(` [${messageTypes.ERROR}] ${error2}`), ..._opt);
480
+ if (!noExit) {
481
+ process.exit(EXIT_WITH_ERROR);
482
+ }
483
+ }
484
+ function handleConnectionError(error2, msg) {
485
+ console.log(chalk.red(` [${messageTypes.ERROR}] ${msg}`));
486
+ console.log(chalk.red(` [${messageTypes.ERROR}] Message: ${error2.message}`));
487
+ if (error2.code !== void 0) {
488
+ console.log(chalk.red(` [${messageTypes.ERROR}] Code: ${error2.code}`));
489
+ }
490
+ process.exit(EXIT_WITH_ERROR);
491
+ }
492
+ function encrypt(text) {
493
+ const iv = randomBytes(16);
494
+ const key = createHash("sha256").update(cryptKey).digest();
495
+ const cipher = createCipheriv("aes-256-ctr", key, iv);
496
+ const encrypted = Buffer.concat([cipher.update(text, "utf8"), cipher.final()]);
497
+ return {
498
+ iv: iv.toString("hex"),
499
+ content: encrypted.toString("hex")
500
+ };
501
+ }
502
+ function decrypt(encryptedData) {
503
+ if (encryptedData && encryptedData.value === "4c9cd7706a" && encryptedData.alg === "aes-256-ctr") {
504
+ message(messageTypes.WARN, STRING.HELPER.DEPRECATED_ENCRYPTION);
505
+ return "elo";
506
+ }
507
+ const key = createHash("sha256").update(cryptKey).digest();
508
+ const decipher = createDecipheriv("aes-256-ctr", key, Buffer.from(encryptedData.iv, "hex"));
509
+ const decrypted = Buffer.concat([
510
+ decipher.update(Buffer.from(encryptedData.content, "hex")),
511
+ decipher.final()
512
+ ]);
513
+ return decrypted.toString("utf8");
514
+ }
515
+ function getFileContentSync(filePath) {
516
+ let content;
517
+ if (existsSync(filePath)) {
518
+ content = String(readFileSyncFunction(filePath));
519
+ if (content !== "") {
520
+ return content;
521
+ } else {
522
+ message(messageTypes.WARN, STRING.HELPER.EMPTYPATH);
523
+ }
524
+ } else {
525
+ message(messageTypes.WARN, STRING.HELPER.NOPATH);
526
+ }
527
+ }
528
+ async function getFileContent(filePath) {
529
+ let content;
530
+ if (await exists(filePath)) {
531
+ content = await readFileFunction(filePath);
532
+ if (content !== "") {
533
+ return content;
534
+ } else {
535
+ message(messageTypes.WARN, STRING.HELPER.EMPTYPATH);
536
+ }
537
+ } else {
538
+ message(messageTypes.WARN, STRING.HELPER.NOPATH);
539
+ }
540
+ }
541
+ async function findRepository() {
542
+ try {
543
+ const dirNamePath = pathLib.resolve(".elo-repository");
544
+ const files = await readDir(dirNamePath);
545
+ if (files.length === 0) return "NONE";
546
+ if (files.length > 1)
547
+ message(
548
+ messageTypes.WARN,
549
+ "Multiple repositories found in .elo-repository. Using the first one found."
550
+ );
551
+ return files[0].replace(".json", "");
552
+ } catch (error2) {
553
+ message(messageTypes.WARN, `Can not reading .elo-repository directory: ${error2}`);
554
+ return "NONE";
555
+ }
556
+ }
557
+ function findRepositorySync() {
558
+ try {
559
+ const dirNamePath = pathLib.resolve(".elo-repository");
560
+ const files = readDirSync(dirNamePath);
561
+ if (files.length === 0) return "NONE";
562
+ if (files.length > 1)
563
+ message(
564
+ messageTypes.WARN,
565
+ "Multiple repositories found in .elo-repository. Using the first one found."
566
+ );
567
+ return String(files[0]).replace(".json", "");
568
+ } catch (error2) {
569
+ message(messageTypes.WARN, `Can not reading .elo-repository directory: ${error2}`);
570
+ return "NONE";
571
+ }
572
+ }
573
+ async function getRepositoryName(repoName) {
574
+ if (repoName === void 0 || repoName === "") {
575
+ const currentRepoPath = "./.elo-current-repository";
576
+ if (await exists(currentRepoPath)) {
577
+ repoName = await getFileContent(currentRepoPath);
578
+ message(messageTypes.INFO, `Using archive from file .elo-current-repository: ${repoName}`);
579
+ } else {
580
+ repoName = await findRepository();
581
+ }
582
+ }
583
+ return repoName?.trim() ?? "ELO_GLOBAL";
584
+ }
585
+ function getRepositoryNameSync(repoName) {
586
+ if (repoName === void 0 || repoName === "") {
587
+ const currentRepoPath = pathLib.resolve(".elo-current-repository");
588
+ if (existsSync(currentRepoPath)) {
589
+ repoName = getFileContentSync(currentRepoPath);
590
+ message(messageTypes.INFO, `Using archive from file .elo-current-repository: ${repoName}`);
591
+ } else {
592
+ repoName = findRepositorySync();
593
+ }
594
+ }
595
+ return repoName?.trim() ?? "ELO_GLOBAL";
596
+ }
597
+ function getSettingsJsonSync(repoName) {
598
+ repoName = getRepositoryNameSync(repoName);
599
+ message(messageTypes.INFO, `testhelpers.init:${repoName}`);
600
+ if (repoName === "ELO_GLOBAL") {
601
+ return getGlobalSettingsJsonSync();
602
+ } else {
603
+ return getLocalSettingsJsonSync(repoName, true);
604
+ }
605
+ }
606
+ async function getSettingsJson(repoName) {
607
+ repoName = await getRepositoryName(repoName);
608
+ message(messageTypes.INFO, `testhelpers.init:${repoName}`);
609
+ if (repoName === "ELO_GLOBAL") {
610
+ return await getGlobalSettingsJson();
611
+ } else {
612
+ return await getLocalSettingsJson(repoName, true);
613
+ }
614
+ }
615
+ function getGlobalSettingsJsonSync(errorIfNotExist = false) {
616
+ let settingsJson = {
617
+ manifest: {},
618
+ ixLogin: { adminName: "", adminPw: { content: "", iv: "" } }
619
+ };
620
+ if (existsSync(globalSettingsPath)) {
621
+ message(messageTypes.INFO, `path: ${globalSettingsPath}`);
622
+ settingsJson = JSON.parse(String(readFileSyncFunction(globalSettingsPath)));
623
+ } else if (errorIfNotExist) {
624
+ error(STRING.HELPER.PATH_NOT_EXIST, false, unixPathSep(globalSettingsPath));
625
+ }
626
+ return settingsJson;
627
+ }
628
+ async function getGlobalSettingsJson(errorIfNotExist = false) {
629
+ let settingsJson = {
630
+ manifest: {},
631
+ ixLogin: { adminName: "", adminPw: { content: "", iv: "" } }
632
+ };
633
+ if (await exists(globalSettingsPath)) {
634
+ message(messageTypes.INFO, `path: ${globalSettingsPath}`);
635
+ settingsJson = JSON.parse(await readFileFunction(globalSettingsPath));
636
+ } else if (errorIfNotExist) {
637
+ error(STRING.HELPER.PATH_NOT_EXIST, false, unixPathSep(globalSettingsPath));
638
+ }
639
+ return settingsJson;
640
+ }
641
+ function getLocalSettingsJsonSync(archivName, errorIfNotExist = false) {
642
+ let settingsJson = {};
643
+ const path = `./.elo-repository/${archivName}.json`;
644
+ message(messageTypes.INFO, `helpers.getArchiveJson:${archivName}`);
645
+ if (!existsSync(path)) {
646
+ if (errorIfNotExist) {
647
+ message(messageTypes.ERROR, STRING.HELPER.PATH_NOT_EXIST, unixPathSep(globalSettingsPath));
648
+ }
649
+ } else {
650
+ settingsJson = existsSync(path) ? JSON.parse(getFileContentSync(path)) : void 0;
651
+ }
652
+ return settingsJson;
653
+ }
654
+ async function getLocalSettingsJson(archivName, errorIfNotExist = false) {
655
+ let settingsJson = {};
656
+ const path = `./.elo-repository/${archivName}.json`;
657
+ message(messageTypes.INFO, `helpers.getArchiveJson:${archivName}`);
658
+ if (!await exists(path)) {
659
+ if (errorIfNotExist) {
660
+ message(messageTypes.ERROR, STRING.HELPER.PATH_NOT_EXIST, unixPathSep(globalSettingsPath));
661
+ }
662
+ } else {
663
+ settingsJson = await exists(path) ? JSON.parse(await getFileContent(path)) : void 0;
664
+ }
665
+ return settingsJson;
666
+ }
667
+ function getParameterInObject(object, key) {
668
+ return object[key];
669
+ }
670
+ function setParameterInObject(object, key, val) {
671
+ const obj = object;
672
+ obj[key] = val;
673
+ return obj;
674
+ }
675
+ async function exists(path) {
676
+ try {
677
+ await access(path);
678
+ return true;
679
+ } catch (e) {
680
+ if (e.code === "ENOENT") {
681
+ return false;
682
+ } else {
683
+ error(e, true);
684
+ }
685
+ }
686
+ return false;
687
+ }
688
+ function existsSync(path) {
689
+ try {
690
+ accessSync(path);
691
+ return true;
692
+ } catch (e) {
693
+ if (e.code === "ENOENT") {
694
+ return false;
695
+ } else {
696
+ error(e, true);
697
+ }
698
+ }
699
+ return false;
700
+ }
701
+ async function readFileFunction(path) {
702
+ const resolvedPath = pathLib.resolve(path);
703
+ return await readFile$1(resolvedPath, "utf8");
704
+ }
705
+ function readFileSyncFunction(path) {
706
+ return readFileSync(path);
707
+ }
708
+ function readFileBase64(path) {
709
+ return readFileSync(path, { encoding: "base64" });
710
+ }
711
+ async function writeFile(path, input) {
712
+ return await writeFile$1(path, input);
713
+ }
714
+ function readFileCB(path, callback) {
715
+ return readFile(path, callback);
716
+ }
717
+ function writeFileCB(path, manifest, callback) {
718
+ return writeFile$2(path, manifest, callback);
719
+ }
720
+ function createReadStreamSync(src) {
721
+ return createReadStream(src);
722
+ }
723
+ function createWriteStreamSync(file) {
724
+ return createWriteStream(file);
725
+ }
726
+ function mkdir(path, recursive) {
727
+ if (recursive) {
728
+ return mkdirSync(path, { recursive: true });
729
+ }
730
+ return mkdirSync(path);
731
+ }
732
+ async function readDir(path) {
733
+ return await readdir(path, { recursive: true });
734
+ }
735
+ function readDirSync(path) {
736
+ return readdirSync(path, { recursive: true });
737
+ }
738
+ async function removeFile(filePath) {
739
+ try {
740
+ if (await exists(filePath)) {
741
+ await rm(filePath, { recursive: true });
742
+ message(messageTypes.INFO, `File deleted: ${filePath}`);
743
+ }
744
+ } catch (err) {
745
+ throw new Error(err);
746
+ }
747
+ }
748
+ async function isFolderEmpty(folderPath) {
749
+ try {
750
+ const files = await readdir(folderPath);
751
+ return files.length === 0;
752
+ } catch {
753
+ return true;
754
+ }
755
+ }
756
+ const commands = {
757
+ init: {},
758
+ setup: {},
759
+ newrepo: {},
760
+ deploy: {},
761
+ import: {},
762
+ export: {},
763
+ localize: {}
764
+ };
765
+ commands.init = {
766
+ description: STRING.INIT.DESCRIPTION,
767
+ path: CONSTANTS.PLACEHOLDER.PATH,
768
+ noManifest: ["repository"],
769
+ options: {
770
+ repository: {
771
+ ignore: true,
772
+ value: "repository",
773
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
774
+ description: STRING.INIT.DEPLOY.OPTIONS.REPOSYTORY.DESC,
775
+ eg: "myArchive"
776
+ },
777
+ indexHtml: {
778
+ value: "index_Html",
779
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
780
+ description: STRING.INIT.OPTIONS.INDEXHTML.DESC,
781
+ defaultValue: "index.html",
782
+ eg: "index.html"
783
+ },
784
+ sordTypeIcons: {
785
+ value: "use_sordType_icons",
786
+ placeHolder: CONSTANTS.PLACEHOLDER.YESNO,
787
+ description: STRING.INIT.OPTIONS.SORDTYPEICONS.DESC,
788
+ eg: "y"
789
+ },
790
+ archiveIcons: {
791
+ value: "use_archive_icons",
792
+ placeHolder: CONSTANTS.PLACEHOLDER.YESNO,
793
+ description: STRING.INIT.OPTIONS.ARCHIVEICON.DESC,
794
+ eg: "y"
795
+ },
796
+ src: {
797
+ value: "src",
798
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
799
+ description: STRING.INIT.OPTIONS.SRC.DESC,
800
+ defaultValue: "src/",
801
+ eg: "src/"
802
+ },
803
+ dist: {
804
+ value: "dist",
805
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
806
+ description: STRING.INIT.OPTIONS.DIST.DESC,
807
+ defaultValue: "dist/",
808
+ eg: "dist/"
809
+ },
810
+ indexHtmlPath: {
811
+ value: "indexHtmlPath",
812
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
813
+ description: STRING.INIT.OPTIONS.INDEXHTMLPATH.DESC,
814
+ defaultValue: ".",
815
+ eg: "public/"
816
+ },
817
+ namespace: {
818
+ value: "namespace",
819
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
820
+ description: STRING.INIT.OPTIONS.NAMESPACE.DESC,
821
+ eg: "my.example.namespace"
822
+ },
823
+ id: {
824
+ value: "id",
825
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
826
+ description: STRING.INIT.OPTIONS.ID.DESC,
827
+ eg: "exampleId"
828
+ },
829
+ defaultLanguage: {
830
+ value: "default_lang",
831
+ placeHolder: CONSTANTS.PLACEHOLDER.LANG,
832
+ description: STRING.INIT.OPTIONS.DEFAULTLANGUAGE.DESC,
833
+ eg: "de"
834
+ },
835
+ build: {
836
+ value: "build_number",
837
+ placeHolder: CONSTANTS.PLACEHOLDER.NUMBER,
838
+ description: STRING.INIT.OPTIONS.BUILD.DESC,
839
+ defaultValue: "0",
840
+ eg: "0"
841
+ },
842
+ useEloSession: {
843
+ value: "useEloSession",
844
+ placeHolder: CONSTANTS.PLACEHOLDER.YESNO,
845
+ description: STRING.INIT.OPTIONS.USEELOSESSION.DESC,
846
+ eg: "y"
847
+ },
848
+ devRedirect: {
849
+ value: "dev_redirect",
850
+ placeHolder: CONSTANTS.PLACEHOLDER.URL,
851
+ description: STRING.INIT.OPTIONS.DEVREDIRECT.DESC,
852
+ checkFirst: "useEloSession",
853
+ eg: "http://localhost:4200/"
854
+ }
855
+ }
856
+ };
857
+ commands.setup = {
858
+ desc: STRING.SETUP.DESC,
859
+ options: (function() {
860
+ let obj = {};
861
+ let copy;
862
+ const fromInit = ["repository", "indexHtml", "src", "dist", "namespace", "defaultLanguage"];
863
+ for (const init of fromInit) {
864
+ copy = Object.assign({}, getParameterInObject(commands.init.options, init));
865
+ if (copy === commands.init.options.repository) {
866
+ copy.ignore = true;
867
+ }
868
+ delete copy.defaultValue;
869
+ obj = setParameterInObject(obj, init, copy);
870
+ }
871
+ obj.serverUrl = {
872
+ value: "server_url",
873
+ placeholder: CONSTANTS.PLACEHOLDER.URL,
874
+ description: STRING.SETUP.OPTIONS.SERVERURL.DESC,
875
+ intoRoot: true,
876
+ eg: "http://myServer:9090/ix-Repository/"
877
+ };
878
+ obj.adminName = {
879
+ value: "admin_name",
880
+ placeholder: CONSTANTS.PLACEHOLDER.NAME,
881
+ description: STRING.SETUP.OPTIONS.ADMINNAME.DESC,
882
+ intoObj: "ixLogin"
883
+ };
884
+ obj.adminPw = {
885
+ value: "admin_pw",
886
+ placeholder: CONSTANTS.PLACEHOLDER.PW,
887
+ description: STRING.SETUP.OPTIONS.ADMINPW.DESC,
888
+ intoObj: "ixLogin",
889
+ encrypt: true
890
+ };
891
+ return obj;
892
+ })()
893
+ };
894
+ commands.newrepo = {
895
+ description: STRING.NEWREPO.DESC,
896
+ options: (function() {
897
+ let obj = {};
898
+ let copy;
899
+ const fromInit = ["repository"];
900
+ const fromSetup = ["serverUrl", "adminName", "adminPw"];
901
+ for (const init of fromInit) {
902
+ copy = Object.assign({}, getParameterInObject(commands.init.options, init));
903
+ if (copy === commands.init.options.repository) {
904
+ delete copy.ignore;
905
+ }
906
+ delete copy.defaultValue;
907
+ obj = setParameterInObject(obj, init, copy);
908
+ }
909
+ for (const setup of fromSetup) {
910
+ copy = Object.assign({}, getParameterInObject(commands.setup.options, setup));
911
+ delete copy.defaultValue;
912
+ obj = setParameterInObject(obj, setup, copy);
913
+ }
914
+ return obj;
915
+ })()
916
+ };
917
+ commands.deploy = {
918
+ description: STRING.DEPLOY.DESC,
919
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
920
+ options: {
921
+ repository: {
922
+ ignore: true,
923
+ value: "repository",
924
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
925
+ description: STRING.DEPLOY.OPTIONS.REPOSITORY.DESC,
926
+ eg: "myArchive"
927
+ },
928
+ key: {
929
+ value: "key",
930
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
931
+ description: STRING.BUILD.OPTIONS.KEY.DESC,
932
+ eg: "any json key name"
933
+ },
934
+ value: {
935
+ value: "value",
936
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
937
+ description: STRING.BUILD.OPTIONS.VALUE.DESC,
938
+ eg: "a string or number"
939
+ },
940
+ neon: {
941
+ value: "neon",
942
+ placeHolder: CONSTANTS.PLACEHOLDER.YESNO,
943
+ description: STRING.DEPLOY.OPTIONS.NEON.DESC
944
+ }
945
+ }
946
+ };
947
+ commands.import = {
948
+ description: STRING.IMPORT.DESC,
949
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
950
+ options: {
951
+ repository: {
952
+ ignore: true,
953
+ value: "repository",
954
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
955
+ description: STRING.DEPLOY.OPTIONS.REPOSITORY.DESC,
956
+ eg: "myArchive"
957
+ },
958
+ mode: {
959
+ value: "mode",
960
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
961
+ description: STRING.IMPORT.OPTIONS.MODE.DESC
962
+ },
963
+ src: {
964
+ value: "src",
965
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
966
+ description: STRING.IMPORT.OPTIONS.SRC.DESC
967
+ },
968
+ guid: {
969
+ value: "guid",
970
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
971
+ description: STRING.IMPORT.OPTIONS.GUID.DESC
972
+ },
973
+ flowName: {
974
+ value: "flowName",
975
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
976
+ description: STRING.IMPORT.OPTIONS.FLOWNAME.DESC
977
+ },
978
+ reloadScripts: {
979
+ value: "reloadScripts",
980
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
981
+ description: STRING.IMPORT.OPTIONS.RELOADSCRIPTS.DESC
982
+ }
983
+ }
984
+ };
985
+ commands.export = {
986
+ description: STRING.EXPORT.DESC,
987
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
988
+ options: {
989
+ repository: {
990
+ ignore: true,
991
+ value: "repository",
992
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
993
+ description: STRING.DEPLOY.OPTIONS.REPOSITORY.DESC,
994
+ eg: "myArchive"
995
+ },
996
+ guid: {
997
+ value: "guid",
998
+ placeHolder: CONSTANTS.PLACEHOLDER.NAME,
999
+ description: STRING.EXPORT.OPTIONS.GUID.DESC
1000
+ },
1001
+ dist: {
1002
+ value: "dist",
1003
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
1004
+ description: STRING.EXPORT.OPTIONS.DIST.DESC
1005
+ }
1006
+ }
1007
+ };
1008
+ commands.localize = {
1009
+ description: "Creates the language files for the web application.",
1010
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
1011
+ options: {
1012
+ src: {
1013
+ value: "src",
1014
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
1015
+ description: STRING.LOCALIZE.OPTIONS.SRC.DESC
1016
+ },
1017
+ dist: {
1018
+ value: "dist",
1019
+ placeHolder: CONSTANTS.PLACEHOLDER.PATH,
1020
+ description: STRING.LOCALIZE.OPTIONS.DIST.DESC
1021
+ }
1022
+ }
1023
+ };
1024
+ class ConnectionManager {
1025
+ constructor() {
1026
+ this.initialized = false;
1027
+ }
1028
+ async init(settingsJson) {
1029
+ try {
1030
+ if (!this.initialized) {
1031
+ if (settingsJson && settingsJson.ixUrl !== void 0) {
1032
+ this.ixClient = new Client({
1033
+ IX_URL: settingsJson.ixUrl,
1034
+ WITH_CREDENTIALS: true,
1035
+ USERNAME: settingsJson.ixLogin.adminName,
1036
+ PASSWORD: decrypt(settingsJson.ixLogin.adminPw),
1037
+ USE_SESSION: false,
1038
+ XHR_TIMEOUT: 3e4,
1039
+ CLIENT_INFO: {
1040
+ language: "en",
1041
+ timeZone: "UTC"
1042
+ }
1043
+ });
1044
+ } else {
1045
+ error(STRING.ERROR.IXCONNECTSKIP, false);
1046
+ return;
1047
+ }
1048
+ await this.ixClient.connect();
1049
+ axios.defaults.headers.common["ELO-Approved"] = this.ixClient.session.eloApproved;
1050
+ axios.defaults.headers.common["Authorization"] = "Basic " + Buffer.from(
1051
+ `${settingsJson.ixLogin.adminName}:${decrypt(settingsJson.ixLogin.adminPw)}`,
1052
+ "utf8"
1053
+ ).toString("base64");
1054
+ this.initialized = true;
1055
+ } else {
1056
+ message(messageTypes.INFO, "Ix is already connected");
1057
+ }
1058
+ } catch (err) {
1059
+ handleConnectionError(err, "Can't connect to IX: ");
1060
+ }
1061
+ }
1062
+ async getixClient() {
1063
+ return this.ixClient;
1064
+ }
1065
+ }
1066
+ const connectionManager = new ConnectionManager();
1067
+ const jar = new CookieJar();
1068
+ const client = wrapper(axios.create({ jar }));
1069
+ const initConfig = commands.init;
1070
+ const setupConfig$1 = commands.setup;
1071
+ const JSON_SPACES = 4;
1072
+ const APPID_MAXLENGTH = 30;
1073
+ function isEmpty(value) {
1074
+ if (value === void 0) {
1075
+ return true;
1076
+ } else {
1077
+ return value === null || value === "" || Array.isArray(value) && value.length === 0;
1078
+ }
1079
+ }
1080
+ async function getManifestData() {
1081
+ const path2 = ensureSlash(process.cwd()) + CONSTANTS.MANIFESTFILE;
1082
+ if (await exists(path2)) {
1083
+ return await getJsonFile(path2, true);
1084
+ } else {
1085
+ error(STRING.ERROR.NOMANIFEST, false, path2);
1086
+ }
1087
+ }
1088
+ async function getJsonFile(filePath, errorIfNotExist = false) {
1089
+ if (await exists(filePath)) {
1090
+ if (!filePath) return {};
1091
+ try {
1092
+ const filePathSync = await readFileFunction(filePath);
1093
+ const json = JSON.parse(String(filePathSync));
1094
+ return json;
1095
+ } catch {
1096
+ message(messageTypes.WARN, "Path is empty: ", filePath);
1097
+ return {};
1098
+ }
1099
+ } else if (errorIfNotExist) {
1100
+ error(STRING.ERROR.PATHNOTEXIST, false, filePath);
1101
+ }
1102
+ }
1103
+ async function applyKeyValueOptionsToManifest(path2, options, mData) {
1104
+ if (options.key !== void 0 && options.value === void 0) {
1105
+ message(messageTypes.WARN, STRING.ERROR.NOVALUE);
1106
+ return {};
1107
+ }
1108
+ if (options.value !== void 0 && options.key === void 0) {
1109
+ message(messageTypes.WARN, STRING.ERROR.NOKEY);
1110
+ return {};
1111
+ }
1112
+ if (options.key !== void 0 && options.value !== void 0) {
1113
+ if (typeof options.key === "string" && options.key !== "") {
1114
+ const distManifestPath = pathLib.join(path2, mData.dist, CONSTANTS.MANIFESTFILE);
1115
+ const manifestDist = await exists(distManifestPath) ? await getJsonFile(distManifestPath, true) : {};
1116
+ if (manifestDist.hasOwnProperty(options.key)) {
1117
+ message(messageTypes.INFO, STRING.INFO.SETKEYVALUE, options.key);
1118
+ }
1119
+ manifestDist[options.key] = parseValue(options.value);
1120
+ return manifestDist;
1121
+ } else {
1122
+ message(messageTypes.ERROR, `Key '${options.key}' has to be a string or is empty.`);
1123
+ }
1124
+ }
1125
+ return {};
1126
+ }
1127
+ function parseValue(value) {
1128
+ if (value === "undefined") return void 0;
1129
+ if (value === "true") return true;
1130
+ if (value === "false") return false;
1131
+ const numberValue = Number(value);
1132
+ if (!Number.isNaN(numberValue)) return numberValue;
1133
+ return value;
1134
+ }
1135
+ async function validateManifestData(manifestData2, path2) {
1136
+ const m = manifestData2;
1137
+ let packagePath;
1138
+ let packageJson2;
1139
+ if (!m.name || m.version) {
1140
+ packagePath = path2 + CONSTANTS.PACKAGEFILE;
1141
+ packageJson2 = await getJsonFile(packagePath, true);
1142
+ message(messageTypes.INFO, `Using packagePath: ${packagePath}`);
1143
+ if (!m.name) {
1144
+ m.name = packageJson2.name;
1145
+ }
1146
+ if (!m.version) {
1147
+ m.version = packageJson2.version;
1148
+ }
1149
+ }
1150
+ if (m.licenseMap === void 0) {
1151
+ m.licenseMap = /* @__PURE__ */ new Map();
1152
+ }
1153
+ m.status = 101;
1154
+ return m;
1155
+ }
1156
+ function validateOptionValue(options, optionConfig, optionVal, optionKey, manifestData2, settingsJson) {
1157
+ const m = manifestData2;
1158
+ if (options[optionConfig.value]) {
1159
+ optionVal = options[optionConfig.value];
1160
+ } else {
1161
+ optionVal = isEmpty(getParameterInObject(m, optionKey)) ? getParameterInObject(settingsJson.manifest, optionKey) : getParameterInObject(m, optionKey);
1162
+ }
1163
+ return optionVal;
1164
+ }
1165
+ function setOptionValueIfEmptyAndPlaceholder(optionVal, optionConfig) {
1166
+ if (isEmpty(optionVal) && optionConfig.defaultValue) {
1167
+ optionVal = optionConfig.defaultValue;
1168
+ }
1169
+ return optionVal;
1170
+ }
1171
+ function setPlaceholder(optionConfig, optionVal) {
1172
+ if (optionConfig.placeHolder === CONSTANTS.PLACEHOLDER.YESNO) {
1173
+ optionVal = optionVal === true || optionVal === "y" || optionVal === "1" || optionVal === "true";
1174
+ } else if (optionConfig.placeHolder === CONSTANTS.PLACEHOLDER.PATH && typeof optionVal === "string") {
1175
+ optionVal = unixPathSep(optionVal);
1176
+ }
1177
+ return optionVal;
1178
+ }
1179
+ function replaceIdChars(id) {
1180
+ try {
1181
+ const length = id.length;
1182
+ if (!length) {
1183
+ message(messageTypes.WARN, STRING.WARN.NOID);
1184
+ } else if (length > APPID_MAXLENGTH) {
1185
+ message(messageTypes.WARN, STRING.WARN.IDLENMSG, length);
1186
+ } else {
1187
+ id = id.replace(/[^a-zA-Z0-9_]/g, "_");
1188
+ message(messageTypes.INFO, STRING.INFO.CHARSREPLACED);
1189
+ return id;
1190
+ }
1191
+ } catch {
1192
+ message(messageTypes.WARN, '"id" is empty or undefined: ', id);
1193
+ return;
1194
+ }
1195
+ }
1196
+ async function pingEloWf(wfUrl) {
1197
+ try {
1198
+ const result = await axios.get(wfUrl, { timeout: 15e3 });
1199
+ message(messageTypes.INFO, `${STRING.INFO.WFREQUESTSUCCESS}: ${wfUrl}`);
1200
+ return result;
1201
+ } catch (err) {
1202
+ throw new Error(err.message);
1203
+ }
1204
+ }
1205
+ async function createIXConnection(settingsJson) {
1206
+ message(messageTypes.INFO, STRING.INFO.IXCONNECT);
1207
+ await connectionManager.init(settingsJson);
1208
+ return await connectionManager.getixClient();
1209
+ }
1210
+ async function createIXRestLogin(settingsJson) {
1211
+ if (!validateSettingsObject(settingsJson)) {
1212
+ error(new Error("Wrong Settings "), true, "The settings are not valid.");
1213
+ }
1214
+ try {
1215
+ const result = await client.post(
1216
+ `${settingsJson.ixUrl.substring(0, settingsJson.ixUrl.length - 3)}/rest/IXServicePortIF/login`,
1217
+ {
1218
+ ci: { ticket: "de.elo.ix.client.ticket_from_cookie" },
1219
+ userName: settingsJson.ixLogin.adminName,
1220
+ userPwd: decrypt(settingsJson.ixLogin.adminPw),
1221
+ clientComputer: "elo-cli",
1222
+ runAs: ""
1223
+ },
1224
+ {
1225
+ withCredentials: true,
1226
+ timeout: 1500
1227
+ }
1228
+ );
1229
+ message(messageTypes.INFO, STRING.INFO.IXCONNSUCCESS);
1230
+ return result.headers["elo-approved"];
1231
+ } catch (err) {
1232
+ throw new Error(err.message);
1233
+ }
1234
+ }
1235
+ function writeCSSDevDataString(jsCode, name, rel, url) {
1236
+ return jsCode += `const ${name} = document.createElement('link')
1237
+
1238
+ ${name}.rel = '${rel}'
1239
+ ${name}.type = 'text/css'
1240
+ ${name}.href = elo.data.server.relativeAppUrl + '${url}'
1241
+ ${name}.media = 'all'
1242
+ document.getElementsByTagName('head')[0].appendChild(${name})`;
1243
+ }
1244
+ function insertScriptTag(cfg, window2) {
1245
+ const tag = window2.document.createElement("script");
1246
+ tag.setAttribute("elo", cfg.eloAttr);
1247
+ tag.type = "text/javascript";
1248
+ if (cfg.src) {
1249
+ tag.src = cfg.src;
1250
+ }
1251
+ if (cfg.content) {
1252
+ tag.innerHTML = cfg.content;
1253
+ }
1254
+ window2.document.body.insertBefore(tag, window2.document.body.firstChild);
1255
+ }
1256
+ function writeAppData(window2, manifestData2) {
1257
+ insertScriptTag(
1258
+ {
1259
+ eloAttr: "appData",
1260
+ content: `var elo = elo || {}
1261
+ elo.data = elo.data || {}
1262
+ elo.data.server = elo.data.server || {}
1263
+ elo.data.server.appDefaultLanguage = "${manifestData2.defaultLanguage}"
1264
+ elo.data.server.appSupportedLocales = ${JSON.stringify(manifestData2.supportedLocales)}
1265
+ elo.data.server.appId = "${manifestData2.id}"
1266
+ elo.data.server.appNamespace = "${manifestData2.namespace}"
1267
+ elo.data.server.appVersion = "${manifestData2.version || ""}"
1268
+ elo.data.server.appUseEloSession = ${manifestData2.useEloSession}
1269
+ elo.appInfo = {
1270
+ application: {
1271
+ name: "${manifestData2.name}"
1272
+ },
1273
+ page: {
1274
+ name: "${manifestData2.namespace}.${manifestData2.id}"
1275
+ }}`
1276
+ },
1277
+ window2
1278
+ );
1279
+ }
1280
+ function isVue2App(code) {
1281
+ if (code === "") {
1282
+ message(messageTypes.INFO, STRING.INFO.MAINJSEMPTY);
1283
+ return false;
1284
+ }
1285
+ return code.includes("new Vue(");
1286
+ }
1287
+ function isVue3App(code) {
1288
+ if (code === "") {
1289
+ message(messageTypes.INFO, STRING.INFO.MAINJSEMPTY);
1290
+ return false;
1291
+ }
1292
+ return code.includes("createApp(");
1293
+ }
1294
+ async function getMainScriptFile(path2, manifestData2) {
1295
+ const mainPath = ensureSlash(path2) + ensureSlash(manifestData2.src);
1296
+ if (await exists(mainPath + CONSTANTS.MAINJSFILE)) {
1297
+ return mainPath + CONSTANTS.MAINJSFILE;
1298
+ } else if (await exists(mainPath + CONSTANTS.MAINTSFILE)) {
1299
+ return mainPath + CONSTANTS.MAINTSFILE;
1300
+ }
1301
+ return void 0;
1302
+ }
1303
+ function logConfigurationHints(configCreateInfo, configContentArray, mainScriptCreateInfo, mainScriptContentArray) {
1304
+ message(messageTypes.INFO, configCreateInfo);
1305
+ message(messageTypes.INFO, "---------------------------------------------------------");
1306
+ configContentArray.forEach((str) => {
1307
+ message(messageTypes.DEFAULT, str);
1308
+ });
1309
+ message(messageTypes.INFO, "---------------------------------------------------------");
1310
+ message(messageTypes.INFO, mainScriptCreateInfo);
1311
+ message(messageTypes.INFO, "---------------------------------------------------------");
1312
+ mainScriptContentArray.forEach((str) => {
1313
+ message(messageTypes.DEFAULT, str);
1314
+ });
1315
+ message(messageTypes.INFO, "---------------------------------------------------------");
1316
+ }
1317
+ async function outputHelpAndWriteFiles(indexHtmlPath, path2, manifestData2, window2) {
1318
+ writeFileCB(
1319
+ indexHtmlPath,
1320
+ `<!DOCTYPE html>${window2.document.documentElement.outerHTML}`,
1321
+ async (err) => {
1322
+ if (err) {
1323
+ error(err);
1324
+ }
1325
+ message(messageTypes.INFO, STRING.INFO.INITCOMPLETE);
1326
+ const mainScriptPath = await getMainScriptFile(path2, manifestData2);
1327
+ if (!mainScriptPath) {
1328
+ error(STRING.ERROR.MAINJSNOTFOUND);
1329
+ process.exit(0);
1330
+ }
1331
+ const mainScriptContent = await getFileContent(mainScriptPath);
1332
+ const isVue2AppVar = isVue2App(mainScriptContent);
1333
+ const isVue3AppVar = isVue3App(mainScriptContent);
1334
+ if (isVue2AppVar) {
1335
+ logConfigurationHints(
1336
+ STRING.INFO.VUECONFJS,
1337
+ STRING.CODE.VUECONFJSCODE,
1338
+ STRING.INFO.MAINJS,
1339
+ STRING.CODE.MAINJSCODE
1340
+ );
1341
+ process.exit(0);
1342
+ } else if (isVue3AppVar) {
1343
+ logConfigurationHints(
1344
+ STRING.INFO.VITECONFTS,
1345
+ STRING.CODE.VITECONFTSCODE,
1346
+ STRING.INFO.MAINTS,
1347
+ STRING.CODE.MAINTSCODE
1348
+ );
1349
+ process.exit(0);
1350
+ } else {
1351
+ message(messageTypes.INFO, STRING.INFO.NOVUEAPP);
1352
+ process.exit(0);
1353
+ }
1354
+ }
1355
+ );
1356
+ }
1357
+ async function ixRestLogout(settingsJson, approvedToken) {
1358
+ if (!validateSettingsObject(settingsJson)) {
1359
+ error(new Error("Wrong Settings"), true, "The settings are not valid.");
1360
+ }
1361
+ try {
1362
+ const result = await client.post(
1363
+ `${settingsJson.ixUrl.substring(0, settingsJson.ixUrl.length - 3)}/rest/IXServicePortIF/logout`,
1364
+ { ci: { ticket: "de.elo.ix.client.ticket_from_cookie" } },
1365
+ {
1366
+ withCredentials: true,
1367
+ timeout: 15e3,
1368
+ headers: {
1369
+ "ELO-Approved": approvedToken,
1370
+ Authorization: "Basic " + Buffer.from(
1371
+ `${settingsJson.ixLogin.adminName}:${decrypt(settingsJson.ixLogin.adminPw)}`,
1372
+ "utf8"
1373
+ ).toString("base64")
1374
+ }
1375
+ }
1376
+ );
1377
+ message(messageTypes.INFO, "Logging out has been successful");
1378
+ return result;
1379
+ } catch (err) {
1380
+ throw new Error(err.message);
1381
+ }
1382
+ }
1383
+ function validateSettingsObject(settingsJson) {
1384
+ if (!settingsJson.ixUrl) {
1385
+ error(STRING.ERROR.WFREFRESHSKIP, true, "ixUrl");
1386
+ return false;
1387
+ } else if (!settingsJson.ixLogin.adminName) {
1388
+ error(STRING.ERROR.WFREFRESHSKIP, true, setupConfig$1.options.adminName.value);
1389
+ return false;
1390
+ } else if (!settingsJson.ixLogin.adminPw) {
1391
+ error(STRING.ERROR.WFREFRESHSKIP, true, setupConfig$1.options.adminPw.value);
1392
+ return false;
1393
+ } else {
1394
+ message(messageTypes.INFO, STRING.INFO.IXCONNECT);
1395
+ message(messageTypes.INFO, settingsJson.ixUrl);
1396
+ return true;
1397
+ }
1398
+ }
1399
+ async function initNodeJsOnEloWf(settingsJson, manifest) {
1400
+ const wfUrl = settingsJson.manifest.wfUrl || manifest.wfUrl;
1401
+ const approvedToken = await createIXRestLogin(settingsJson);
1402
+ const url = `${ensureSlash(wfUrl)}apps/rest/cmd/app/initnodejs/`;
1403
+ message(messageTypes.INFO, STRING.INFO.WFREFRESH, url);
1404
+ try {
1405
+ const res = await client.post(url, manifest, {
1406
+ withCredentials: true,
1407
+ timeout: 15e3,
1408
+ headers: {
1409
+ "ELO-Approved": approvedToken
1410
+ }
1411
+ });
1412
+ message(messageTypes.INFO, STRING.INFO.WFREFRESHCOMPLETED);
1413
+ await ixRestLogout(settingsJson, approvedToken);
1414
+ return res.data;
1415
+ } catch (err) {
1416
+ throw new Error(err.message);
1417
+ }
1418
+ }
1419
+ async function propertiesToObject(src) {
1420
+ let res = {};
1421
+ try {
1422
+ const rl = readline.createInterface({
1423
+ input: createReadStreamSync(src),
1424
+ crlfDelay: Infinity
1425
+ });
1426
+ for await (const line of rl) {
1427
+ if (line && line.indexOf("#") !== 0) {
1428
+ const lineSplit = line.split("=");
1429
+ const key = lineSplit[0].trim();
1430
+ const value = lineSplit[1].trim();
1431
+ if (key && value) {
1432
+ res = setParameterInObject(res, key, value);
1433
+ }
1434
+ }
1435
+ }
1436
+ return res;
1437
+ } catch (err) {
1438
+ throw new Error(err.message);
1439
+ }
1440
+ }
1441
+ async function writeSettingsJson(archiveName, path2, settings2) {
1442
+ if (archiveName !== void 0) {
1443
+ const repoFolder = "/.elo-repository";
1444
+ const confPath = `${path2}${ensureSlash(repoFolder)}`;
1445
+ if (!await exists(confPath)) {
1446
+ mkdir(confPath, true);
1447
+ message(messageTypes.INFO, STRING.INFO.PATHCREATED, `.${ensureSlash(repoFolder)}`);
1448
+ }
1449
+ const archivePath = `${confPath}${archiveName}.json`;
1450
+ await writeFile(archivePath, JSON.stringify(settings2, null, JSON_SPACES));
1451
+ message(messageTypes.INFO, STRING.INFO.REPOCONFSAVE, `in .${repoFolder}/${archiveName}.json.`);
1452
+ } else {
1453
+ await writeFile(globalSettingsPath, JSON.stringify(settings2, null, JSON_SPACES));
1454
+ }
1455
+ }
1456
+ async function build(path2, manifestData2, manifestPath, distManifestData) {
1457
+ try {
1458
+ if (!manifestData2.dist || !await exists(pathLib.join(path2, manifestData2.dist))) {
1459
+ error(STRING.ERROR.OPTIONNOTVALID, false, initConfig.options.dist.value);
1460
+ }
1461
+ if (!manifestData2.defaultLanguage) {
1462
+ error(STRING.ERROR.OPTIONNOTVALID, false, initConfig.options.defaultLanguage.value);
1463
+ }
1464
+ manifestData2.supportedLocales = manifestData2.supportedLocales || [
1465
+ manifestData2.defaultLanguage
1466
+ ];
1467
+ manifestData2.build++;
1468
+ message(messageTypes.INFO, STRING.INFO.SETTINGSBUILD, manifestData2.build);
1469
+ await writeFile(manifestPath, JSON.stringify(manifestData2, null, JSON_SPACES));
1470
+ message(messageTypes.INFO, STRING.INFO.COPYFILES);
1471
+ const indexHtmlPath = pathLib.join(
1472
+ ensureSlash(path2),
1473
+ ensureSlash(manifestData2.dist),
1474
+ manifestData2.indexHtml
1475
+ );
1476
+ message(messageTypes.INFO, `Check dist index file: ${indexHtmlPath}`);
1477
+ const distManifestPath = pathLib.join(
1478
+ ensureSlash(path2),
1479
+ ensureSlash(manifestData2.dist),
1480
+ CONSTANTS.MANIFESTFILE
1481
+ );
1482
+ message(messageTypes.INFO, `Write updated manifest to: ${distManifestPath}`);
1483
+ delete manifestData2.devRedirect;
1484
+ const manifestDataCopy = Object.assign(
1485
+ {},
1486
+ manifestData2,
1487
+ typeof distManifestData === "string" ? JSON.parse(distManifestData) : distManifestData
1488
+ );
1489
+ await writeFile(distManifestPath, JSON.stringify(manifestDataCopy, null, JSON_SPACES));
1490
+ message(messageTypes.INFO, `Manifest copied to dist file: ${distManifestPath}`);
1491
+ const distDevData = `${ensureSlash(path2) + ensureSlash(manifestData2.dist)}devData.js`;
1492
+ message(messageTypes.INFO, `Delete devData.js in dist: ${distDevData}`);
1493
+ await removeFile(distDevData);
1494
+ if (!await exists(indexHtmlPath)) {
1495
+ error(STRING.ERROR.NOSETTINGSPATH, false, indexHtmlPath);
1496
+ }
1497
+ readFileCB(indexHtmlPath, (err, data) => {
1498
+ if (err) {
1499
+ error(err);
1500
+ }
1501
+ const { window: window2 } = new JSDOM(data, {});
1502
+ const baseTagList = window2.document.head.getElementsByTagName("base");
1503
+ let baseTag;
1504
+ const scriptServerData = window2.document.body.querySelector("script[elo=serverData]");
1505
+ const scriptConfigData = window2.document.body.querySelector("script[elo=configData]");
1506
+ const scriptDevData = window2.document.body.querySelector("script[elo=devData]");
1507
+ const scriptAppData = window2.document.body.querySelector("script[elo=appData]");
1508
+ if (baseTagList.length) {
1509
+ baseTag = baseTagList[0];
1510
+ baseTag.href = "${baseHref}";
1511
+ }
1512
+ if (scriptServerData) {
1513
+ scriptServerData.remove();
1514
+ }
1515
+ if (scriptConfigData) {
1516
+ scriptConfigData.remove();
1517
+ }
1518
+ if (scriptDevData) {
1519
+ scriptDevData.remove();
1520
+ }
1521
+ if (scriptAppData) {
1522
+ scriptAppData.remove();
1523
+ }
1524
+ overwriteCssTag(window2, "favIcon", "icon", true, "../../resources/images/elo-favicon.ico");
1525
+ overwriteCssTag(
1526
+ window2,
1527
+ "fontCss",
1528
+ "stylesheet",
1529
+ true,
1530
+ "../../mapping/modules/elo.module.font.01/resources/css/elo-sans-pro.css"
1531
+ );
1532
+ overwriteCssTag(
1533
+ window2,
1534
+ "levelIconsCss",
1535
+ "stylesheet",
1536
+ manifestData2.sordTypeIcons,
1537
+ "../../mapping/modules/elo.module.icons/resources/levels/levels-200.css"
1538
+ );
1539
+ overwriteCssTag(
1540
+ window2,
1541
+ "archiveIconsCss",
1542
+ "stylesheet",
1543
+ manifestData2.archiveIcons,
1544
+ "../../mapping/modules/elo.module.icons/resources/archiveicons/archiveicons-200.css"
1545
+ );
1546
+ insertScriptTag(
1547
+ {
1548
+ eloAttr: "configData",
1549
+ src: `../../pages/appConfig.jsp?id=${manifestData2.id}&namespace=${manifestData2.namespace}`
1550
+ },
1551
+ window2
1552
+ );
1553
+ insertScriptTag(
1554
+ {
1555
+ eloAttr: "serverData",
1556
+ src: "../../pages/serverData.jsp"
1557
+ },
1558
+ window2
1559
+ );
1560
+ writeAppData(window2, manifestData2);
1561
+ writeFileCB(
1562
+ indexHtmlPath,
1563
+ `<!DOCTYPE html>${window2.document.documentElement.outerHTML}`,
1564
+ (err2) => {
1565
+ if (err2) {
1566
+ error(err2);
1567
+ }
1568
+ message(messageTypes.INFO, STRING.INFO.BUILDCOMPLETED);
1569
+ }
1570
+ );
1571
+ });
1572
+ } catch (err) {
1573
+ throw new Error(err.message);
1574
+ }
1575
+ }
1576
+ function overwriteCssTag(window2, name, rel, overwrite, url) {
1577
+ const cssEl = window2.document.head.querySelector(`link[elo=${name}]`);
1578
+ if (cssEl) {
1579
+ cssEl.remove();
1580
+ }
1581
+ if (overwrite) {
1582
+ insertLinkTag(
1583
+ {
1584
+ relAttr: rel,
1585
+ eloAttr: name,
1586
+ href: url
1587
+ },
1588
+ window2
1589
+ );
1590
+ }
1591
+ }
1592
+ function insertLinkTag(cfg, window2) {
1593
+ const tag = window2.document.createElement("link");
1594
+ tag.setAttribute("rel", cfg.relAttr);
1595
+ tag.setAttribute("elo", cfg.eloAttr);
1596
+ tag.type = "text/css";
1597
+ if (cfg.href) {
1598
+ tag.href = cfg.href;
1599
+ }
1600
+ window2.document.head.insertBefore(tag, window2.document.head.firstChild);
1601
+ }
1602
+ async function zipFilesInFolder(srcFolder, targetFolder, targetFile) {
1603
+ message(messageTypes.INFO, `Start zip folder ${srcFolder} to ${targetFile} as ${targetFile}`);
1604
+ await removeFile(ensureSlash(targetFolder));
1605
+ mkdir(ensureSlash(targetFolder), false);
1606
+ const output = createWriteStreamSync(ensureSlash(targetFolder) + targetFile);
1607
+ const archive = archiver("zip", { zlib: { level: 9 } });
1608
+ output.on("close", () => {
1609
+ message(messageTypes.INFO, `${archive.pointer()} total bytes`);
1610
+ message(
1611
+ messageTypes.INFO,
1612
+ "archiver has been finalized and the output file descriptor has closed."
1613
+ );
1614
+ });
1615
+ archive.on("warning", (err) => {
1616
+ if (err.code === "ENOENT") {
1617
+ error(err);
1618
+ } else {
1619
+ throw err;
1620
+ }
1621
+ });
1622
+ archive.on("error", (err) => {
1623
+ throw err;
1624
+ });
1625
+ archive.pipe(output);
1626
+ archive.directory(srcFolder, false);
1627
+ await archive.finalize();
1628
+ }
1629
+ async function deployNodeJsOnEloWf(settingsJson, manifest, projectPath) {
1630
+ if (!manifest.wfUrl && !settingsJson.manifest?.wfUrl) {
1631
+ error("No wfUrl defined in manifest", false);
1632
+ }
1633
+ const wfUrl = manifest.wfUrl || settingsJson.manifest.wfUrl;
1634
+ const zipPath = `${ensureSlash(projectPath)}zip/`;
1635
+ const distPath = ensureSlash(projectPath) + manifest.dist;
1636
+ try {
1637
+ await zipFilesInFolder(distPath, zipPath, "app.zip");
1638
+ await pingEloWf(wfUrl);
1639
+ const approvedToken = await createIXRestLogin(settingsJson);
1640
+ const url = `${ensureSlash(wfUrl)}apps/rest/cmd/app/deploynodejs/`;
1641
+ message(messageTypes.INFO, STRING.INFO.WFREFRESH, url);
1642
+ const stream = createReadStreamSync(`${ensureSlash(zipPath)}app.zip`);
1643
+ const res = await client.post(url, stream, {
1644
+ withCredentials: true,
1645
+ timeout: 6e4,
1646
+ params: {
1647
+ namespace: manifest.namespace,
1648
+ id: manifest.id,
1649
+ ticket: "de.elo.ix.client.ticket_from_cookie"
1650
+ },
1651
+ headers: {
1652
+ "Content-Type": "application/zip",
1653
+ "ELO-Approved": approvedToken
1654
+ }
1655
+ });
1656
+ message(messageTypes.INFO, STRING.INFO.WFREFRESHCOMPLETED);
1657
+ await removeFile(zipPath);
1658
+ await ixRestLogout(settingsJson, approvedToken);
1659
+ return res;
1660
+ } catch (err) {
1661
+ await removeFile(zipPath);
1662
+ throw new Error(err);
1663
+ }
1664
+ }
1665
+ async function deployNodeJsOnNeon(settingsJson, manifest, projectPath) {
1666
+ const ixUrl = settingsJson.ixUrl.endsWith("/ix") ? settingsJson.ixUrl.substring(0, settingsJson.ixUrl.length - 3) : settingsJson.ixUrl;
1667
+ const zipPath = `${ensureSlash(projectPath)}zip/`;
1668
+ const distPath = ensureSlash(projectPath) + manifest.dist;
1669
+ const approvedToken = await createIXRestLogin(settingsJson);
1670
+ try {
1671
+ await zipFilesInFolder(`${ensureSlash(distPath)}assets/`, zipPath, "app.zip");
1672
+ await pingEloWf(settingsJson.manifest.wfUrl);
1673
+ const url = `${ensureSlash(ixUrl)}plugin/de.elo.ix.plugin.rest/neon/extensions/`;
1674
+ message(messageTypes.INFO, STRING.INFO.NEONDEPLOY, url);
1675
+ const stream = createReadStreamSync(`${zipPath}app.zip`);
1676
+ const res = await client.post(url, stream, {
1677
+ timeout: 6e4,
1678
+ params: { ticket: "de.elo.ix.client.ticket_from_cookie" },
1679
+ headers: {
1680
+ "Content-Type": "application/octet-stream",
1681
+ "ELO-Approved": approvedToken
1682
+ }
1683
+ });
1684
+ await removeFile(ensureSlash(zipPath));
1685
+ await ixRestLogout(settingsJson, approvedToken);
1686
+ return res;
1687
+ } catch (err) {
1688
+ await removeFile(ensureSlash(zipPath));
1689
+ await ixRestLogout(settingsJson, approvedToken);
1690
+ throw new Error(err.message);
1691
+ }
1692
+ }
1693
+ async function updateManifestData(manifestData2) {
1694
+ const manifestPath = pathLib.resolve(ensureSlash(process.cwd()) + CONSTANTS.MANIFESTFILE);
1695
+ await removeFile(manifestPath);
1696
+ await writeFile(manifestPath, JSON.stringify(manifestData2, null, JSON_SPACES));
1697
+ }
1698
+ function mapToObj(map) {
1699
+ if (map instanceof Map) {
1700
+ const obj = {};
1701
+ for (const [key, value] of map) {
1702
+ obj[key] = mapToObj(value);
1703
+ }
1704
+ return obj;
1705
+ }
1706
+ return map;
1707
+ }
1708
+ async function delay(seconds) {
1709
+ if (Number.isFinite(seconds) && seconds > 0) {
1710
+ message(messageTypes.INFO, `Waiting for ${seconds} seconds before continue...`);
1711
+ await new Promise((resolve) => setTimeout(resolve, seconds * 1e3));
1712
+ } else {
1713
+ message(messageTypes.WARN, `Invalid delay value: ${seconds}. Skipping delay.`);
1714
+ }
1715
+ }
1716
+ const buildCommand = new Command("build").description("Build a App").option(
1717
+ "--k, --key <string>",
1718
+ "Sets the value of the key value pair, defined by --key, for example: a string or number"
1719
+ ).option(
1720
+ "--v, --value <string>",
1721
+ "Sets the value for the arbitrary json key, for example: any json value"
1722
+ ).action(async (options, path) => {
1723
+ path = ensureSlash(pathLib.resolve(unixPathSep(process.cwd())));
1724
+ const manifesData = await getManifestData();
1725
+ const mDist = await applyKeyValueOptionsToManifest(path, options, manifesData);
1726
+ await build(path, manifesData, path + CONSTANTS.MANIFESTFILE, mDist);
1727
+ });
1728
+ let settings;
1729
+ class TestHelpers {
1730
+ constructor(options) {
1731
+ this.initialized = options?.initialized ?? false;
1732
+ this.user = options?.user ?? "";
1733
+ this.pw = options?.pw ? { content: options.pw.content, iv: options.pw.iv } : { content: "", iv: "" };
1734
+ this.eloWfUrl = options?.eloWfUrl ?? "";
1735
+ this.ixUrl = options?.ixUrl ?? "";
1736
+ this.ixContext = options?.ixContext ?? "";
1737
+ this.ixServer = options?.ixServer ?? "";
1738
+ if (typeof window !== "undefined") {
1739
+ window.elo = Object.assign({}, window.elo, { data: { server: {} } });
1740
+ }
1741
+ }
1742
+ /**
1743
+ * Initializes the test helper by reading the settings.json file.
1744
+ * This method used synchronous file reading.
1745
+ * @param repoName Optional repository name to read settings from.
1746
+ * @returns The settings data.
1747
+ */
1748
+ init(repoName) {
1749
+ settings = getSettingsJsonSync(repoName);
1750
+ return this.innerInit(settings);
1751
+ }
1752
+ /**
1753
+ * Initializes the test helper by reading the settings.json file.
1754
+ * This method uses asynchronous file reading.
1755
+ * @param repoName Optional repository name to read settings from.
1756
+ * @returns A promise that resolves to the settings data.
1757
+ */
1758
+ async asyncInit(repoName) {
1759
+ settings = await getSettingsJson(repoName);
1760
+ return this.innerInit(settings);
1761
+ }
1762
+ /**
1763
+ * Extract the settings data and compute the urls.
1764
+ * @param settings The settings data.
1765
+ * @private
1766
+ * @returns The settings data.
1767
+ */
1768
+ innerInit(settings2) {
1769
+ if (!settings2) error("No settings available", false);
1770
+ try {
1771
+ this.eloWfUrl = settings2.manifest.wfUrl;
1772
+ this.ixUrl = settings2.ixUrl;
1773
+ this.user = settings2.ixLogin.adminName;
1774
+ this.pw = {
1775
+ content: settings2.ixLogin.adminPw.content,
1776
+ iv: settings2.ixLogin.adminPw.iv,
1777
+ // NEON-388: Be compatible for old settings.json structure
1778
+ alg: settings2.ixLogin.adminPw.alg,
1779
+ value: settings2.ixLogin.adminPw.value
1780
+ };
1781
+ const url = new URL(this.ixUrl);
1782
+ const parts = url.pathname.split("/").filter(Boolean);
1783
+ this.ixContext = `/${parts[0]}`;
1784
+ this.ixServer = `${url.protocol}//${url.hostname}${url.port ? ":" + url.port : ""}`;
1785
+ this.initialized = true;
1786
+ message(messageTypes.INFO, "TestHelper initialized");
1787
+ return settings2;
1788
+ } catch (e) {
1789
+ message(messageTypes.ERROR, "Error reading settings");
1790
+ error(e, true);
1791
+ }
1792
+ }
1793
+ /**
1794
+ * Sets the default language.
1795
+ *
1796
+ * @param language default language
1797
+ */
1798
+ initLang(language) {
1799
+ if (typeof window !== "undefined") {
1800
+ window.elo = Object.assign({}, window.elo, { data: { server: {} } });
1801
+ window.elo.data.server.language = language || settings.manifest.defaultLanguage || "de";
1802
+ }
1803
+ }
1804
+ /**
1805
+ * EVLIB-1138: returns the user after class variables are initialized
1806
+ * with "init()" or "asyncInit()"
1807
+ * @returns user
1808
+ */
1809
+ getUser() {
1810
+ if (!this.initialized) {
1811
+ message(messageTypes.ERROR, "testHelper not initialized!");
1812
+ return "";
1813
+ }
1814
+ return this.user;
1815
+ }
1816
+ /**
1817
+ * EVLIB-1138: returns the pw after class variables are initialized
1818
+ * with "init()" or "asyncInit()"
1819
+ * @returns password
1820
+ */
1821
+ getPw() {
1822
+ if (!this.initialized) {
1823
+ message(messageTypes.ERROR, "testHelper not initialized!");
1824
+ return "";
1825
+ }
1826
+ return decrypt(this.pw);
1827
+ }
1828
+ /**
1829
+ * Returns the indexserver url (ixUrl) after class variables are initialized
1830
+ * with "init()" or "asyncInit()"
1831
+ * @returns url
1832
+ */
1833
+ getIxUrl() {
1834
+ if (!this.initialized) {
1835
+ message(messageTypes.ERROR, "testHelper not initialized!");
1836
+ return "";
1837
+ }
1838
+ return this.ixUrl;
1839
+ }
1840
+ /**
1841
+ * Returns the ixContext after class variables are initialized
1842
+ * with "init()" or "asyncInit()"
1843
+ * @returns ixContext
1844
+ */
1845
+ getIxContext() {
1846
+ if (!this.initialized) {
1847
+ message(messageTypes.ERROR, "testHelper not initialized!");
1848
+ return "";
1849
+ }
1850
+ return this.ixContext;
1851
+ }
1852
+ /**
1853
+ * Returns the ixServer after class variables are initialized
1854
+ * with "init()" or "asyncInit()"
1855
+ * @returns ixServer
1856
+ */
1857
+ getIxServer() {
1858
+ if (!this.initialized) {
1859
+ message(messageTypes.ERROR, "testHelper not initialized!");
1860
+ return "";
1861
+ }
1862
+ return this.ixServer;
1863
+ }
1864
+ /**
1865
+ * Returns the eloWfUrl after class variables are initialized
1866
+ * with "init()" or "asyncInit()"
1867
+ * @returns url
1868
+ */
1869
+ getWfUrl() {
1870
+ if (!this.initialized) {
1871
+ message(messageTypes.ERROR, "testHelper not initialized!");
1872
+ return "";
1873
+ }
1874
+ return this.eloWfUrl;
1875
+ }
1876
+ }
1877
+ const testHelper = new TestHelpers();
1878
+ const deployCommand = new Command("deploy").description("Deploy a App into wf").option("--r, --repository <string>", "Use a specific local repository (for projects)").option(
1879
+ "--n, --neon",
1880
+ "To deploy a Neon extension the client plugin, instead of an ELO App to the ELOwf."
1881
+ ).option(
1882
+ "--k, --key <string>",
1883
+ "Sets the value of the key value pair, defined by --key, for example: a string or number"
1884
+ ).option(
1885
+ "--v, --value <string>",
1886
+ "Sets the value for the arbitrary json key, for example: any json value"
1887
+ ).action(async (options, path) => {
1888
+ path = ensureSlash(pathLib.resolve(unixPathSep(process.cwd())));
1889
+ let archiveName;
1890
+ if (options.repository) {
1891
+ archiveName = options.repository;
1892
+ message(messageTypes.INFO, `Using archive parameter ${archiveName}`);
1893
+ }
1894
+ const settingsJson = await testHelper.asyncInit(archiveName);
1895
+ const manifest = await getManifestData();
1896
+ const isNeonDeploy = options.neon;
1897
+ try {
1898
+ if (!isNeonDeploy) {
1899
+ const wfUrl = settingsJson.manifest.wfUrl;
1900
+ if (!wfUrl) {
1901
+ error(STRING.ERROR.OPTIONNOTVALID, false, "wfUrl");
1902
+ }
1903
+ const mDist = await applyKeyValueOptionsToManifest(path, options, manifest);
1904
+ await build(path, manifest, path + CONSTANTS.MANIFESTFILE, mDist);
1905
+ await deployNodeJsOnEloWf(settingsJson, manifest, path);
1906
+ message(messageTypes.INFO, STRING.INFO.DEPLOYCOMPLETED);
1907
+ } else {
1908
+ await deployNodeJsOnNeon(settingsJson, manifest, path);
1909
+ message(messageTypes.INFO, STRING.INFO.DEPLOYCOMPLETED);
1910
+ }
1911
+ } catch (err) {
1912
+ handleConnectionError(err, STRING.ERROR.WFREQUEST);
1913
+ }
1914
+ });
1915
+ const exportConfig = commands.export;
1916
+ const exportCommand = new Command("export").description("Export a package or archive area from the ELO repository").option(
1917
+ "--r, --repository <string>",
1918
+ "Repository containing json config file, for example: myArchive"
1919
+ ).option(
1920
+ "--g, --guid <string>",
1921
+ "The guid of the entry or the name/guid of the package to export."
1922
+ ).option("--d, --dist <string>", "The file of the export data.").action(async (options, path) => {
1923
+ path = ensureSlash(pathLib.resolve(unixPathSep(process.cwd())));
1924
+ const guid = getParameterInObject(options, exportConfig.options.guid.value);
1925
+ const distOption = getParameterInObject(options, exportConfig.options.dist.value);
1926
+ const dist = ensureSlash(path) + distOption;
1927
+ let archiveName = "";
1928
+ if (options.repository) {
1929
+ archiveName = options.repository;
1930
+ message(messageTypes.INFO, `Using archive parameter ${archiveName}`);
1931
+ }
1932
+ try {
1933
+ const settingsJson = await testHelper.asyncInit(archiveName);
1934
+ message(messageTypes.INFO, `export package from ${guid} to file ${dist}.`);
1935
+ const ixConnection = await createIXConnection(settingsJson);
1936
+ const packageInfo = (await ixConnection.packageService.eServiceCheckoutPackages({
1937
+ checkoutInfo: {
1938
+ nameOrGuids: [guid]
1939
+ },
1940
+ packageZ: PackageC.mbAll,
1941
+ lockZ: LockC.NO
1942
+ })).result;
1943
+ if (packageInfo.packageDataList === void 0) {
1944
+ error(STRING.ERROR.PACKAGENOTFOUND, false, guid);
1945
+ }
1946
+ const startExportResult = (await ixConnection.fioService.serviceStartExport({
1947
+ options: {
1948
+ compressionLevel: 1,
1949
+ packageGuids: [packageInfo.packageDataList[0].guid]
1950
+ }
1951
+ })).result;
1952
+ const downloadUrl = new URL(
1953
+ ensureSlash(settingsJson.ixUrl.replace(/\/ix$/, "")) + "byps?" + String(startExportResult.downloadStream.url).replace("getstream?", "") + "&a=a"
1954
+ );
1955
+ const response = await axios.get(downloadUrl.toString(), { responseType: "stream" });
1956
+ await pipeline(response.data, createWriteStreamSync(dist));
1957
+ message(messageTypes.INFO, `Exported package to file ${dist}.`);
1958
+ await ixConnection.fioService.serviceFinishExport({
1959
+ options: {
1960
+ jobState: startExportResult.jobState
1961
+ }
1962
+ });
1963
+ message(messageTypes.INFO, STRING.INFO.EXPORTCOMPLETE);
1964
+ } catch (err) {
1965
+ handleConnectionError(err, STRING.ERROR.EXPORT);
1966
+ }
1967
+ });
1968
+ const importConfig = commands.import;
1969
+ const importArchiveZip = async (con, src, guid, guidFlag = 1) => {
1970
+ message(messageTypes.INFO, `importArchiveZip:${guid}`);
1971
+ try {
1972
+ const importId = (await con.ix.startImport({
1973
+ filingPath: guid,
1974
+ guidMethod: guidFlag
1975
+ })).result;
1976
+ message(messageTypes.INFO, `importId:${importId}`);
1977
+ const uploadUrl = (await con.ix.getImportZipUrl({
1978
+ importId
1979
+ })).result;
1980
+ message(messageTypes.INFO, `uploadUrl:${uploadUrl}`);
1981
+ const stream = createReadStreamSync(src);
1982
+ await axios.post(uploadUrl, stream, { timeout: 6e4 });
1983
+ message(messageTypes.INFO, STRING.INFO.IMPORTCOMPLETE);
1984
+ } catch (err) {
1985
+ handleConnectionError(err, STRING.ERROR.IMPORT);
1986
+ }
1987
+ };
1988
+ const importWorkflow = async (con, src, flowName, guid) => {
1989
+ try {
1990
+ const data = readFileBase64(src);
1991
+ await con.ix.importWorkFlow2({
1992
+ flowName,
1993
+ fileData: data,
1994
+ importOptions: {
1995
+ replaceMissingUserByUserId: guid
1996
+ }
1997
+ });
1998
+ message(messageTypes.INFO, STRING.INFO.IMPORTCOMPLETE);
1999
+ } catch (err) {
2000
+ handleConnectionError(err, STRING.ERROR.IXCONN);
2001
+ }
2002
+ };
2003
+ const importEntry = async (con, src, guid) => {
2004
+ try {
2005
+ const constants = (await con.ix.getConstants()).result;
2006
+ const editInfo = (await con.ix.createDoc({
2007
+ parentId: guid,
2008
+ maskId: constants.DOC_MASK.GUID_BASIC,
2009
+ editInfoZ: { sordZ: constants.EDIT_INFO.mbAll }
2010
+ })).result;
2011
+ const name = pathLib.basename(src);
2012
+ const ext = name.substring(name.lastIndexOf(".") + 1);
2013
+ const data = createReadStreamSync(src);
2014
+ const doc = {
2015
+ docs: [
2016
+ {
2017
+ ext,
2018
+ version: "1",
2019
+ comment: "neon-cli import"
2020
+ }
2021
+ ]
2022
+ };
2023
+ const beginDoc = (await con.ix.checkinDocBegin({
2024
+ document: doc
2025
+ })).result;
2026
+ const uploadUrl = beginDoc.docs[0].url;
2027
+ const uploadResult = await axios.post(uploadUrl, data, {
2028
+ headers: {
2029
+ "content-type": "application/elodm-" + ext
2030
+ }
2031
+ });
2032
+ doc.docs = beginDoc.docs;
2033
+ doc.docs[0].uploadResult = uploadResult.data;
2034
+ editInfo.sord.name = pathLib.basename(src, pathLib.extname(src));
2035
+ editInfo.sord.docVersion = doc.docs[0];
2036
+ await con.ix.checkinDocEnd({
2037
+ document: doc,
2038
+ sord: editInfo.sord,
2039
+ sordZ: constants.SORD.mbAll
2040
+ });
2041
+ message(messageTypes.INFO, STRING.INFO.IMPORTCOMPLETE);
2042
+ } catch (err) {
2043
+ handleConnectionError(err, STRING.ERROR.IMPORT);
2044
+ }
2045
+ };
2046
+ const importPackage = async (con, src) => {
2047
+ try {
2048
+ const data = readFileSyncFunction(src);
2049
+ const name = pathLib.basename(src);
2050
+ const file = new File([data], name);
2051
+ const uploadResponse = await axios.post(
2052
+ `${con.session.config.IX_URL}/rest/BUtility/upload`,
2053
+ file
2054
+ );
2055
+ const uploadResult = uploadResponse.data.result;
2056
+ const importOptions = {
2057
+ conflictHandling: ConflictHandlingE.TSTAMP,
2058
+ uploadStream: {
2059
+ streamId: uploadResult.streamId,
2060
+ url: uploadResult.url
2061
+ },
2062
+ packagesImported: true
2063
+ };
2064
+ await con.fioService.serviceStartImport({
2065
+ options: importOptions
2066
+ });
2067
+ message(messageTypes.INFO, STRING.INFO.IMPORTCOMPLETE);
2068
+ } catch (err) {
2069
+ handleConnectionError(err, STRING.ERROR.IMPORT);
2070
+ }
2071
+ };
2072
+ const importCommand = new Command("import").description("Import some data").option("--r, --repository <string>", "Read the local repository (for projects)").option("--m, --mode <string>", "The selected import mode: archiv, workflow or entry").option("--s, --src <string>", "The path to the file to be exported").option("--f, --flowName <string>", "Name of the workflow template").option("--guid <string>", "Guid of the entry").option("--guidMode <number>", "Selects the guide mode (Default: 1)", parseInt, 1).option("--reloadScripts <string>", "Reloads the scripts after the import.").action(async (options, path) => {
2073
+ path = ensureSlash(pathLib.resolve(unixPathSep(process.cwd())));
2074
+ const guid = getParameterInObject(options, importConfig.options.guid.value) ?? "0";
2075
+ const src = path + options[importConfig.options.src.value];
2076
+ let archiveName = await getRepositoryName(options.repository);
2077
+ let con;
2078
+ const settingsJson = archiveName !== "ELO_GLOBAL" ? await getLocalSettingsJson(archiveName, true) : await getGlobalSettingsJson();
2079
+ try {
2080
+ const connection = await createIXConnection(settingsJson);
2081
+ if (!connection) {
2082
+ throw new Error("Failed to create IX connection.");
2083
+ }
2084
+ con = connection;
2085
+ } catch (err) {
2086
+ handleConnectionError(err, STRING.ERROR.IXCONN);
2087
+ }
2088
+ let mode = options.mode;
2089
+ let flowName = options.flowName;
2090
+ if (mode !== "archive" && mode !== "workflow" && mode !== "entry") {
2091
+ mode = "package";
2092
+ }
2093
+ if (!flowName && mode === "workflow") {
2094
+ flowName = pathLib.basename(src, pathLib.extname(src));
2095
+ }
2096
+ if (options.repository) {
2097
+ archiveName = options.repository;
2098
+ message(messageTypes.INFO, `Using archive parameter ${archiveName}`);
2099
+ }
2100
+ if (options.reloadScripts) {
2101
+ message(messageTypes.INFO, "import trigger reloadScripts");
2102
+ const reloadScriptsResult = await con.ix.reloadScripts();
2103
+ if (!reloadScriptsResult.exception) {
2104
+ message(messageTypes.INFO, STRING.INFO.RELOADCOMPLETE);
2105
+ }
2106
+ } else if (mode === "archive") {
2107
+ message(messageTypes.INFO, `import archive from file ${src} to ${guid}.`);
2108
+ await importArchiveZip(con, src, guid, options.guidMode ?? 1);
2109
+ } else if (mode === "workflow") {
2110
+ message(
2111
+ messageTypes.INFO,
2112
+ `import workflow from file ${src} to ${flowName}, replace unknown user with ${guid}.`
2113
+ );
2114
+ await importWorkflow(con, src, flowName, guid);
2115
+ } else if (mode === "entry") {
2116
+ message(messageTypes.INFO, `import entry from file ${src} to ${guid}.`);
2117
+ await importEntry(con, src, guid);
2118
+ } else {
2119
+ message(messageTypes.INFO, `import package from file ${src}.`);
2120
+ await importPackage(con, src);
2121
+ }
2122
+ });
2123
+ const initCommand = new Command("init").description("Init the project").option("--r, --repository <string>", "Read the local repository (for projects)").option(
2124
+ "--index_html <string>",
2125
+ "The name of the index.html, for example: index.html (default: index.html)"
2126
+ ).option(
2127
+ "--use_SordType_Icons <y/n>",
2128
+ 'Are "ELO Sordtype Icons" required for this project? For example: y'
2129
+ ).option(
2130
+ "--use_Archive_Icons <y/n>",
2131
+ 'Are "Archive Icons" required for this project? For example: y'
2132
+ ).option(
2133
+ "--src <string>",
2134
+ "The relative path where the source files, like the index.html, are, for example: src/"
2135
+ ).option(
2136
+ "--dist <string>",
2137
+ "The relative path where the output files, like the index.html, will be, for example: dist/"
2138
+ ).option(
2139
+ "--indexHtmlPath <string>",
2140
+ "The relative path where the index.html file is located, for example in Vue2: public/ for Vue3 it is ."
2141
+ ).option("--namespace <string>", "The app namespace, for example: my.example.namespace").option("--id <string>", "The app id, for example: exampleId").option("--default_lang <string>", "The default language, for example: de").option("--build_number <number>", "The build number of the app, for example: 0").option("--use_elo_session <y/n>", "Enable, to use elo session, for example: y").option(
2142
+ "--dev_redirect <string>",
2143
+ "Dev url of the app, which the login site of the ELOwf will redirect after successfull login. Necessary if elo session is enabled, for example: http://localhost:4200/"
2144
+ ).action(async (options, path) => {
2145
+ message(messageTypes.INFO, STRING.INIT.START);
2146
+ path = ensureSlash(pathLib.resolve(unixPathSep(process.cwd())));
2147
+ const manifestPath = path + CONSTANTS.MANIFESTFILE;
2148
+ let manifestData2 = await getJsonFile(manifestPath) || {};
2149
+ let optionKey;
2150
+ let optionVal;
2151
+ let optionConfig;
2152
+ let defaultVal;
2153
+ const currentRepoPath = pathLib.resolve(".elo-current-repository");
2154
+ const initConfig2 = commands.init;
2155
+ const archiveName = await getRepositoryName(options.repository);
2156
+ try {
2157
+ await writeFile(currentRepoPath, archiveName.trim());
2158
+ } catch (e) {
2159
+ error(e);
2160
+ }
2161
+ const settingsJson = await testHelper.asyncInit(archiveName) || void 0;
2162
+ if (settingsJson === void 0) error(STRING.ERROR.NOSETTINGSFOUND, false);
2163
+ manifestData2 = await validateManifestData(manifestData2, path);
2164
+ try {
2165
+ for (optionKey in initConfig2.options) {
2166
+ const option = getParameterInObject(initConfig2.options, optionKey);
2167
+ if (initConfig2.options.hasOwnProperty(optionKey)) {
2168
+ if (option.ignore) {
2169
+ continue;
2170
+ }
2171
+ optionConfig = option;
2172
+ optionVal = validateOptionValue(
2173
+ options,
2174
+ optionConfig,
2175
+ optionVal,
2176
+ optionKey,
2177
+ manifestData2,
2178
+ settingsJson
2179
+ );
2180
+ message(messageTypes.INFO, `Using - ${optionConfig.value} = ${optionVal}`);
2181
+ while (isEmpty(optionVal)) {
2182
+ if (optionConfig.checkFirst && manifestData2[optionConfig.checkFirst] !== true) {
2183
+ break;
2184
+ }
2185
+ defaultVal = "";
2186
+ message(messageTypes.DEFAULT, optionConfig.description, optionConfig.eg);
2187
+ if (optionConfig.defaultValue) {
2188
+ defaultVal = `(${optionConfig.defaultValue}) `;
2189
+ }
2190
+ const tmp = await prompts({
2191
+ type: "text",
2192
+ name: "value",
2193
+ message: `${optionConfig.value} ${defaultVal}`
2194
+ });
2195
+ optionVal = tmp.value;
2196
+ optionVal = setOptionValueIfEmptyAndPlaceholder(optionVal, optionConfig);
2197
+ }
2198
+ optionVal = setPlaceholder(optionConfig, optionVal);
2199
+ manifestData2 = setParameterInObject(manifestData2, optionKey, optionVal);
2200
+ }
2201
+ }
2202
+ } catch (err) {
2203
+ error(err, false);
2204
+ }
2205
+ manifestData2.id = replaceIdChars(manifestData2.id);
2206
+ manifestData2.supportedLocales = manifestData2.supportedLocales || [manifestData2.defaultLanguage];
2207
+ manifestData2.build++;
2208
+ message(messageTypes.INFO, `Writing manifest (${unixPathSep(manifestPath)}):`);
2209
+ const manifestToWrite = Object.assign({}, manifestData2);
2210
+ initConfig2.noManifest.forEach((option) => {
2211
+ delete manifestToWrite[option];
2212
+ });
2213
+ message(messageTypes.INFO, JSON.stringify(manifestToWrite, null, JSON_SPACES));
2214
+ try {
2215
+ await writeFile(manifestPath, JSON.stringify(manifestToWrite, null, JSON_SPACES));
2216
+ message(messageTypes.INFO, STRING.INFO.MANIFESTSTORED);
2217
+ } catch (e) {
2218
+ message(messageTypes.ERROR, `Something went wrong storing manifest: ${e}`);
2219
+ }
2220
+ message(messageTypes.INFO, STRING.INFO.COPYMANIFEST);
2221
+ try {
2222
+ await initNodeJsOnEloWf(settingsJson, manifestData2);
2223
+ } catch (err) {
2224
+ handleConnectionError(err, STRING.ERROR.WFREQUEST);
2225
+ }
2226
+ const indexHtmlPath = ensureSlash(path) + ensureSlash(manifestData2.indexHtmlPath) + manifestData2.indexHtml;
2227
+ message(messageTypes.INFO, `Preparing ${initConfig2.options.indexHtml.value}`);
2228
+ if (!await exists(indexHtmlPath)) {
2229
+ error(STRING.ERROR.INDEXHTMLNOTFOUND, false, indexHtmlPath);
2230
+ }
2231
+ readFileCB(indexHtmlPath, async (err, data) => {
2232
+ if (err) {
2233
+ error(err);
2234
+ }
2235
+ const { window: window2 } = new JSDOM(data, {});
2236
+ const scriptTagList = window2.document.body.querySelectorAll("script[elo]");
2237
+ if (scriptTagList !== null) {
2238
+ if (scriptTagList.length) {
2239
+ scriptTagList.forEach((element) => {
2240
+ element.remove();
2241
+ });
2242
+ }
2243
+ }
2244
+ const faviconEl = window2.document.head.querySelector("link[rel=icon]");
2245
+ if (faviconEl) {
2246
+ faviconEl.remove();
2247
+ }
2248
+ try {
2249
+ const idx = indexHtmlPath.lastIndexOf("/");
2250
+ const devDataPath = `${ensureSlash(indexHtmlPath.substring(0, idx))}devData.js`;
2251
+ const context = testHelper.getIxContext();
2252
+ let jsCode = `(function() {
2253
+ const elo = window.elo = window.elo || {};
2254
+
2255
+ window.api = window.api || {};
2256
+
2257
+ const loadAndExecute = function(src) {
2258
+ // get some kind of XMLHttpRequest
2259
+ const xhrObj = new XMLHttpRequest();
2260
+
2261
+ // open and send a synchronous request
2262
+ xhrObj.open('GET', src, false);
2263
+ xhrObj.send('');
2264
+ // eslint-disable-next-line no-magic-numbers
2265
+ if (xhrObj.status === 200) {
2266
+ // add the returned content to a newly created script tag
2267
+ let code = xhrObj.responseText;
2268
+
2269
+ // replace local variable with global one so data is not written to function scope
2270
+ code = code.replace('var elo = elo', 'var elo = window.elo');
2271
+ // create function to execute loaded script code
2272
+ const fct = new Function(code);
2273
+
2274
+ fct();
2275
+ } else {
2276
+ // eslint-disable-next-line no-console
2277
+ console.error('Error loading devData scripts!', xhrObj.responseText);
2278
+ }
2279
+ };
2280
+
2281
+ loadAndExecute('${context}/plugin/de.elo.ix.plugin.proxy/wf/apps/pages/serverData.jsp');
2282
+ loadAndExecute('${context}/plugin/de.elo.ix.plugin.proxy/wf/apps/pages/appConfig.jsp?id=${manifestData2.id}&namespace=${manifestData2.namespace}');
2283
+ elo.data = elo.data || {};
2284
+ elo.data.server = elo.data.server || {};
2285
+ elo.data.server.ixUrlContext = '${context}';
2286
+ elo.data.server.ixUrl = '${context}/ix';
2287
+ elo.data.server.relativeAppUrl = '${context}/plugin/de.elo.ix.plugin.proxy/wf';
2288
+ elo.data.server.isDevEnv = true;`;
2289
+ jsCode = writeCSSDevDataString(
2290
+ jsCode,
2291
+ "favIcon",
2292
+ "icon",
2293
+ "/apps/resources/images/elo-favicon.ico"
2294
+ ) + "\n";
2295
+ jsCode = writeCSSDevDataString(
2296
+ jsCode,
2297
+ "fontCss",
2298
+ "stylesheet",
2299
+ "/apps/mapping/modules/elo.module.icons/resources/levels/levels-200.css"
2300
+ ) + "\n";
2301
+ if (manifestData2.sordTypeIcons === true) {
2302
+ jsCode = writeCSSDevDataString(
2303
+ jsCode,
2304
+ "sordTypeIconsCss",
2305
+ "stylesheet",
2306
+ "/apps/mapping/modules/elo.module.icons/resources/levels/levels-200.css"
2307
+ ) + "\n";
2308
+ }
2309
+ if (manifestData2.archiveIcons === true) {
2310
+ jsCode = writeCSSDevDataString(
2311
+ jsCode,
2312
+ "archiveIconsCss",
2313
+ "stylesheet",
2314
+ "/apps/mapping/modules/elo.module.icons/resources/archiveicons/archiveicons-200.css"
2315
+ ) + "\n";
2316
+ }
2317
+ jsCode = `${jsCode}}());`;
2318
+ await writeFile(devDataPath, jsCode);
2319
+ message(messageTypes.INFO, "successfully created devData File");
2320
+ } catch (err2) {
2321
+ error("Something went wrong: ", false, err2);
2322
+ }
2323
+ insertScriptTag({ eloAttr: "devData", src: "./devData.js" }, window2);
2324
+ writeAppData(window2, manifestData2);
2325
+ await outputHelpAndWriteFiles(indexHtmlPath, path, manifestData2, window2);
2326
+ });
2327
+ });
2328
+ class LicenseBuilder {
2329
+ constructor(projectName, writeStream) {
2330
+ this.projectName = projectName;
2331
+ this.writeStream = writeStream;
2332
+ this.dependencyArray = [];
2333
+ this.fileObjList = [];
2334
+ this.fundCounter = 0;
2335
+ this.missingLicenses = [];
2336
+ this.missingCounter = 0;
2337
+ }
2338
+ setDependencyArray(dependencyArray) {
2339
+ this.dependencyArray = dependencyArray;
2340
+ }
2341
+ getDependencyArray() {
2342
+ return this.dependencyArray;
2343
+ }
2344
+ setFileObjList(fileObjList) {
2345
+ this.fileObjList = fileObjList;
2346
+ }
2347
+ getFileObjList() {
2348
+ return this.fileObjList;
2349
+ }
2350
+ addMissingLicense(packageName) {
2351
+ this.missingLicenses.push(packageName);
2352
+ }
2353
+ getMissingLicenses() {
2354
+ return this.missingLicenses;
2355
+ }
2356
+ getMissingCounter() {
2357
+ return this.missingCounter;
2358
+ }
2359
+ getFoundCounter() {
2360
+ return this.fundCounter;
2361
+ }
2362
+ createHeader() {
2363
+ this.writeStream.write(CONSTANTS.LICENSEFILEHEADER.replace("%s", this.projectName));
2364
+ }
2365
+ /**
2366
+ * Creates the license file by writing the license and notice texts of the dependencies into the file. If a license is missing, it adds the dependency to the missing licenses list.
2367
+ * If an error occurs during the file generation, it logs the error message.
2368
+ *
2369
+ * @returns void
2370
+ */
2371
+ async createLicenseFile(inputLicensePath2, manifestData2) {
2372
+ try {
2373
+ this.createHeader();
2374
+ await this.searchForLicenses();
2375
+ if (this.getDependencyArray().length > 0)
2376
+ message(
2377
+ messageTypes.INFO,
2378
+ `Found ${this.getDependencyArray().length} dependencies in 'package.json'.`
2379
+ );
2380
+ else error("No dependencies found in package.json.", false);
2381
+ await this.findModuleLicenses(inputLicensePath2, manifestData2);
2382
+ for (const fileObj of this.getFileObjList()) {
2383
+ this.writeStream.write(
2384
+ `${CONSTANTS.DASHEDLINE + "\n" + CONSTANTS.DASHEDLINE + "\n"}--- ${fileObj.packageObject.fullname}
2385
+ ${CONSTANTS.DASHEDLINE}
2386
+
2387
+ `
2388
+ );
2389
+ if (fileObj.noticeFilePath !== void 0) {
2390
+ const noticeText = await readFileFunction(fileObj.noticeFilePath);
2391
+ this.writeInFile(noticeText);
2392
+ }
2393
+ if (fileObj.found) {
2394
+ const text = await readFileFunction(fileObj.licenseFilePath);
2395
+ this.writeInFile(text);
2396
+ this.fundCounter += 1;
2397
+ continue;
2398
+ } else {
2399
+ this.addMissingLicense(fileObj.packageObject.fullname || fileObj.packageObject.name);
2400
+ this.missingCounter += 1;
2401
+ continue;
2402
+ }
2403
+ }
2404
+ } catch (err) {
2405
+ throw new Error(err.message);
2406
+ }
2407
+ }
2408
+ filterDependencies(dependencieTree) {
2409
+ const dependencieMap = /* @__PURE__ */ new Map();
2410
+ for (const dependencie of dependencieTree) {
2411
+ if (dependencie.extraneous) continue;
2412
+ let path2 = "";
2413
+ let splittetName = "";
2414
+ if (dependencie.name.startsWith("@")) {
2415
+ const splitName = dependencie.name.split("/");
2416
+ path2 = splitName[0];
2417
+ splittetName = splitName[1];
2418
+ }
2419
+ if (dependencie.name === void 0 || dependencie.version === void 0 || dependencie.name.includes(".bin") || dependencie.name.includes("@elo") || dependencie.name.includes(this.projectName))
2420
+ continue;
2421
+ const dependencieObject = {
2422
+ fullname: `${dependencie.name}@${dependencie.version}`,
2423
+ path: path2,
2424
+ name: splittetName !== "" ? splittetName : dependencie.name,
2425
+ version: dependencie.version,
2426
+ resolved: dependencie.resolved,
2427
+ overridden: dependencie.overridden,
2428
+ extraneous: dependencie.extraneous,
2429
+ problems: dependencie.problems || [],
2430
+ hasSubDirectory: splittetName.length > 0,
2431
+ license: dependencie.license ? dependencie.license : "UNKNOWN"
2432
+ };
2433
+ if (dependencieMap.has(dependencieObject.fullname)) {
2434
+ continue;
2435
+ }
2436
+ dependencieMap.set(dependencieObject.fullname, dependencieObject);
2437
+ }
2438
+ removeFile(pathLib.resolve("./dependencies.json"));
2439
+ return Array.from(dependencieMap.values());
2440
+ }
2441
+ /**
2442
+ * Writes the given data into the license file. If the data is not empty, it adds two new lines after the data and increases the found counter by one.
2443
+ *
2444
+ * @param data the data to write into the license file.
2445
+ * @return void
2446
+ */
2447
+ writeInFile(data) {
2448
+ if (data !== "") {
2449
+ this.writeStream.write(`${data}
2450
+
2451
+ \r`);
2452
+ }
2453
+ }
2454
+ /**
2455
+ * Builds the path for third-party licenses project.
2456
+ *
2457
+ * @param packageObject the package object.
2458
+ * @param map the manifest license map.
2459
+ * @param inputLicensePath the input license path.
2460
+ * @returns the path for the third-party licenses project.
2461
+ */
2462
+ buildPathForThirdPartyLicensesProject(packageObject, map, inputLicensePath2) {
2463
+ const name = packageObject.hasSubDirectory ? `${packageObject.path} ${packageObject.name}` : packageObject.name;
2464
+ return pathLib.resolve(`${inputLicensePath2}/${map.get(name)}/${packageObject.version}/`);
2465
+ }
2466
+ /**
2467
+ * Searches for license and notice files in the given path.
2468
+ *
2469
+ * @param path the path to search in.
2470
+ * @param packageObject the package object.
2471
+ * @returns a FileObj containing the license and notice file paths.
2472
+ */
2473
+ async getLicenseAndNoticeFile(searchPath, packageObject) {
2474
+ const fileObj = {};
2475
+ const contentFiles = await readdir$1(pathLib.resolve(searchPath));
2476
+ fileObj.packageObject = packageObject;
2477
+ const foundLicense = contentFiles.find((file) => {
2478
+ if (file.toLowerCase().includes("license") || file.toLowerCase().includes("licence"))
2479
+ return file;
2480
+ });
2481
+ const foundNotice = contentFiles.find((file) => {
2482
+ if (file.toLowerCase().includes("notice")) return file;
2483
+ });
2484
+ if (foundLicense) {
2485
+ fileObj.licenseFilePath = pathLib.resolve(searchPath, foundLicense);
2486
+ fileObj.found = true;
2487
+ }
2488
+ if (foundNotice) fileObj.noticeFilePath = pathLib.resolve(searchPath, foundNotice);
2489
+ message(messageTypes.INFO, foundLicense ? "LICENSE found!" : "LICENSE not found!");
2490
+ message(messageTypes.INFO, foundNotice ? "NOTICE found!" : "NOTICE not found!");
2491
+ return fileObj;
2492
+ }
2493
+ }
2494
+ class NpmLicenseBuilder extends LicenseBuilder {
2495
+ constructor(projectName, writeStream) {
2496
+ super(projectName, writeStream);
2497
+ }
2498
+ async searchForLicenses() {
2499
+ const dependencieTree = await this.getDependencies();
2500
+ const parsedDependencies = this.parseDependencies(dependencieTree);
2501
+ const fullList = this.filterDependencies(parsedDependencies);
2502
+ this.setDependencyArray(fullList);
2503
+ }
2504
+ async findModuleLicenses(inputLicensePath2, manifestData2) {
2505
+ const fileObjList = this.getFileObjList();
2506
+ const manifesrLicenseMap = manifestData2 !== void 0 ? new Map(Object.entries(manifestData2.licenseMap)) : /* @__PURE__ */ new Map();
2507
+ for (const dep of this.getDependencyArray()) {
2508
+ let fileObj = {};
2509
+ if (inputLicensePath2 !== "" && manifesrLicenseMap.has(dep.name)) {
2510
+ const thirdPartyPath = this.buildPathForThirdPartyLicensesProject(
2511
+ dep,
2512
+ manifesrLicenseMap,
2513
+ inputLicensePath2
2514
+ );
2515
+ if (await exists(thirdPartyPath)) {
2516
+ fileObj = await this.getLicenseAndNoticeFile(thirdPartyPath, dep);
2517
+ if (fileObj.found) {
2518
+ fileObjList.push(fileObj);
2519
+ continue;
2520
+ }
2521
+ }
2522
+ }
2523
+ const nodeModulesPath = this.buildContentPath(dep);
2524
+ if (await exists(nodeModulesPath)) {
2525
+ fileObj = await this.getLicenseAndNoticeFile(nodeModulesPath, dep);
2526
+ if (fileObj.found) {
2527
+ fileObjList.push(fileObj);
2528
+ continue;
2529
+ }
2530
+ }
2531
+ message(messageTypes.WARN, STRING.WARN.LICENSENOTFOUND, dep.fullname || dep.name);
2532
+ fileObj.found = false;
2533
+ fileObj.packageObject = dep;
2534
+ fileObjList.push(fileObj);
2535
+ }
2536
+ this.fileObjList = fileObjList;
2537
+ }
2538
+ parseDependencies(dependencies) {
2539
+ const dependencieList = [];
2540
+ const deps = dependencies.dependencies || {};
2541
+ for (const [name, dependencie] of Object.entries(deps)) {
2542
+ const newDependencie = {
2543
+ name,
2544
+ version: dependencie.version,
2545
+ dependencies: dependencie.dependencies,
2546
+ extraneous: dependencie.extraneous,
2547
+ resolved: dependencie.resolved,
2548
+ overridden: dependencie.overridden,
2549
+ license: dependencie.license,
2550
+ hasSubDirectory: false
2551
+ };
2552
+ dependencieList.push(newDependencie);
2553
+ const subDependencies = this.parseDependencies(dependencie);
2554
+ if (subDependencies.length > 0) {
2555
+ dependencieList.push(...subDependencies);
2556
+ }
2557
+ }
2558
+ return dependencieList;
2559
+ }
2560
+ async getDependencies() {
2561
+ let parsedDependencies = {};
2562
+ try {
2563
+ execSync(
2564
+ "npm ls --package-lock-only --depth=Infinity --omit=dev --omit=optional --omit=peer --json > dependencies.json",
2565
+ {
2566
+ encoding: "utf8",
2567
+ stdio: ["pipe", "pipe", "pipe"]
2568
+ }
2569
+ );
2570
+ const dependencieJson = await readFileFunction(pathLib.resolve("./dependencies.json"));
2571
+ parsedDependencies = JSON.parse(dependencieJson);
2572
+ } catch (err) {
2573
+ error(err);
2574
+ }
2575
+ return parsedDependencies;
2576
+ }
2577
+ /**
2578
+ * Builds the content path.
2579
+ *
2580
+ * @param packageObject The package object.
2581
+ * @param fileName The file name to search for.
2582
+ * @returns The constructed content path.
2583
+ */
2584
+ buildContentPath(packageObject) {
2585
+ return packageObject.hasSubDirectory ? `./node_modules/${packageObject.path}/${packageObject.name}/` : `./node_modules/${packageObject.name}/`;
2586
+ }
2587
+ }
2588
+ class PnpmLicenseBuilder extends LicenseBuilder {
2589
+ constructor(projectName, writeStream, rootPath) {
2590
+ super(projectName, writeStream);
2591
+ this.files = [];
2592
+ this.rootPath = rootPath;
2593
+ this.files = [];
2594
+ }
2595
+ async searchForLicenses() {
2596
+ const dependencieTree = await this.getDependencies();
2597
+ const parsedDependencies = [];
2598
+ for (const dependencie of dependencieTree) {
2599
+ const tempDependencies = this.parseDependencies(dependencie);
2600
+ parsedDependencies.push(...tempDependencies);
2601
+ }
2602
+ const fullList = this.filterDependencies(parsedDependencies);
2603
+ this.setDependencyArray(fullList);
2604
+ }
2605
+ async findModuleLicenses(inputLicensePath2, manifestData2) {
2606
+ const fileObjList = [];
2607
+ const manifesrLicenseMap = manifestData2 !== void 0 ? new Map(Object.entries(manifestData2.licenseMap)) : /* @__PURE__ */ new Map();
2608
+ for (const dep of this.getDependencyArray()) {
2609
+ let fileObj = {};
2610
+ if (inputLicensePath2 !== "" && manifesrLicenseMap.has(dep.name)) {
2611
+ const thirdPartyPath = this.buildPathForThirdPartyLicensesProject(
2612
+ dep,
2613
+ manifesrLicenseMap,
2614
+ inputLicensePath2
2615
+ );
2616
+ if (await exists(thirdPartyPath)) {
2617
+ fileObj = await this.getLicenseAndNoticeFile(thirdPartyPath, dep);
2618
+ if (fileObj.found) {
2619
+ fileObjList.push(fileObj);
2620
+ continue;
2621
+ }
2622
+ }
2623
+ }
2624
+ const pnpmInnerPath = this.buildPnpmLicenseInnerPath(dep);
2625
+ if (await exists(pnpmInnerPath)) {
2626
+ fileObj = await this.getLicenseAndNoticeFile(pnpmInnerPath, dep);
2627
+ if (fileObj.found) {
2628
+ fileObjList.push(fileObj);
2629
+ continue;
2630
+ }
2631
+ }
2632
+ const fallbackPath = await this.buildFallbackPath(dep);
2633
+ if (fallbackPath !== "none") {
2634
+ fileObj = await this.getLicenseAndNoticeFile(fallbackPath, dep);
2635
+ if (fileObj.found) {
2636
+ fileObjList.push(fileObj);
2637
+ continue;
2638
+ }
2639
+ }
2640
+ const pnpmOuterPath = this.buildPnpmLicenseOuterPath(dep);
2641
+ if (await exists(pnpmOuterPath)) {
2642
+ fileObj = await this.getLicenseAndNoticeFile(pnpmOuterPath, dep);
2643
+ if (fileObj.found) {
2644
+ fileObjList.push(fileObj);
2645
+ continue;
2646
+ }
2647
+ }
2648
+ message(messageTypes.WARN, STRING.WARN.LICENSENOTFOUND, dep.fullname || dep.name);
2649
+ fileObj.found = false;
2650
+ fileObj.packageObject = dep;
2651
+ fileObjList.push(fileObj);
2652
+ }
2653
+ this.setFileObjList(fileObjList);
2654
+ }
2655
+ parseDependencies(dependencies) {
2656
+ const dependencieList = [];
2657
+ const deps = dependencies.dependencies || {};
2658
+ for (const [name, dependencie] of Object.entries(deps)) {
2659
+ const newDependencie = {
2660
+ name,
2661
+ version: dependencie.version,
2662
+ dependencies: dependencie.dependencies,
2663
+ extraneous: dependencie.extraneous,
2664
+ resolved: dependencie.resolved,
2665
+ overridden: dependencie.overridden,
2666
+ license: dependencie.license,
2667
+ hasSubDirectory: false
2668
+ };
2669
+ dependencieList.push(newDependencie);
2670
+ const subDependencies = this.parseDependencies(dependencie);
2671
+ if (subDependencies.length > 0) {
2672
+ dependencieList.push(...subDependencies);
2673
+ }
2674
+ }
2675
+ return dependencieList;
2676
+ }
2677
+ async getDependencies() {
2678
+ let parsedDependencies = [];
2679
+ try {
2680
+ execSync("pnpm list --long --json --prod --depth Infinity > dependencies.json", {
2681
+ encoding: "utf8",
2682
+ stdio: ["pipe", "pipe", "pipe"]
2683
+ });
2684
+ const dependencieJson = await readFileFunction(pathLib.resolve("./dependencies.json"));
2685
+ parsedDependencies = JSON.parse(dependencieJson);
2686
+ } catch (err) {
2687
+ error(err);
2688
+ }
2689
+ return parsedDependencies;
2690
+ }
2691
+ /**
2692
+ * Builds the fallback path to locate the package in the pnpm structure.
2693
+ *
2694
+ * @param packageObject the package object.
2695
+ * @returns the fallback path to locate the package, or 'none' if not found.
2696
+ */
2697
+ async buildFallbackPath(packageObject) {
2698
+ if (this.files.length === 0) {
2699
+ this.files = await readdir$1(pathLib.resolve(ensureSlash(this.rootPath), "node_modules/.pnpm/"));
2700
+ }
2701
+ const matchedFolder = this.searchInPnpmModules(this.files, packageObject);
2702
+ if (matchedFolder) {
2703
+ const searchPath = packageObject.hasSubDirectory ? pathLib.resolve(
2704
+ ensureSlash(this.rootPath) + "node_modules/.pnpm/",
2705
+ `${matchedFolder}/node_modules/${packageObject.path}/${packageObject.name}/`
2706
+ ) : pathLib.resolve(
2707
+ ensureSlash(this.rootPath) + "node_modules/.pnpm/",
2708
+ `${matchedFolder}/node_modules/${packageObject.name}/`
2709
+ );
2710
+ if (!await exists(pathLib.resolve(searchPath))) return "none";
2711
+ return searchPath;
2712
+ }
2713
+ return "none";
2714
+ }
2715
+ /**
2716
+ * Searches for a package in the list of pnpm module folders.
2717
+ *
2718
+ * @param fileList list of files in the .pnpm directory.
2719
+ * @param packageObject the package object to search for.
2720
+ * @returns the matched folder name, or an empty string if not found.
2721
+ */
2722
+ searchInPnpmModules(fileList, packageObject) {
2723
+ const findPositions = [];
2724
+ fileList.forEach((file) => {
2725
+ if (file.includes(packageObject.name)) {
2726
+ findPositions.push(file);
2727
+ }
2728
+ });
2729
+ const matchedFile = findPositions.find((position) => {
2730
+ let name = false, path2 = false, version = false;
2731
+ if (position.includes(packageObject.version)) {
2732
+ version = true;
2733
+ }
2734
+ if (packageObject.hasSubDirectory) {
2735
+ if (position.includes(packageObject.path)) {
2736
+ path2 = true;
2737
+ }
2738
+ }
2739
+ if (position.includes(packageObject.name)) {
2740
+ name = true;
2741
+ }
2742
+ if (name && version && (packageObject.hasSubDirectory ? path2 : true)) {
2743
+ return position;
2744
+ }
2745
+ });
2746
+ return matchedFile || "";
2747
+ }
2748
+ /**
2749
+ * Builds the path to the license file inside the .pnpm folder.
2750
+ *
2751
+ * @param packageObject the package object.
2752
+ * @returns the path to the license file.
2753
+ */
2754
+ buildPnpmLicenseInnerPath(packageObject) {
2755
+ return packageObject.hasSubDirectory ? pathLib.resolve(
2756
+ this.rootPath,
2757
+ `node_modules/.pnpm/${packageObject.fullname?.replace("/", "+")}/node_modules/${packageObject.path}/${packageObject.name}/`
2758
+ ) : pathLib.resolve(
2759
+ this.rootPath,
2760
+ `node_modules/.pnpm/${packageObject.fullname}/node_modules/${packageObject.name}/`
2761
+ );
2762
+ }
2763
+ /**
2764
+ * Builds the path to the license file outside the .pnpm folder.
2765
+ *
2766
+ * @param packageObject the package object.
2767
+ * @returns the path to the license file.
2768
+ */
2769
+ buildPnpmLicenseOuterPath(packageObject) {
2770
+ return packageObject.hasSubDirectory ? pathLib.resolve(this.rootPath, `node_modules/${packageObject.path}/${packageObject.name}/`) : pathLib.resolve(this.rootPath, `node_modules/${packageObject.name}/`);
2771
+ }
2772
+ }
2773
+ class YarnLicenseBuilder extends LicenseBuilder {
2774
+ async searchForLicenses() {
2775
+ const dependencieTree = await this.getDependencies();
2776
+ const { dependencieList, uncompleteDependencies } = this.parseDependencies(
2777
+ dependencieTree[0].data.trees
2778
+ );
2779
+ const completeList = this.completeYarnDependencies(uncompleteDependencies);
2780
+ dependencieList.push(...completeList);
2781
+ const fullList = this.filterDependencies(dependencieList);
2782
+ this.setDependencyArray(fullList);
2783
+ }
2784
+ async findModuleLicenses(inputLicensePath2, manifestData2) {
2785
+ const fileObjList = this.getFileObjList();
2786
+ const manifesrLicenseMap = manifestData2 !== void 0 ? new Map(Object.entries(manifestData2.licenseMap)) : /* @__PURE__ */ new Map();
2787
+ for (const dep of this.getDependencyArray()) {
2788
+ let fileObj = {};
2789
+ if (inputLicensePath2 !== "" && manifesrLicenseMap.has(dep.name)) {
2790
+ const thirdPartyPath = this.buildPathForThirdPartyLicensesProject(
2791
+ dep,
2792
+ manifesrLicenseMap,
2793
+ inputLicensePath2
2794
+ );
2795
+ if (await exists(thirdPartyPath)) {
2796
+ fileObj = await this.getLicenseAndNoticeFile(thirdPartyPath, dep);
2797
+ if (fileObj.found) {
2798
+ fileObjList.push(fileObj);
2799
+ continue;
2800
+ }
2801
+ }
2802
+ }
2803
+ const nodeModulesPath = this.buildContentPath(dep);
2804
+ if (await exists(nodeModulesPath)) {
2805
+ fileObj = await this.getLicenseAndNoticeFile(nodeModulesPath, dep);
2806
+ if (fileObj.found) {
2807
+ fileObjList.push(fileObj);
2808
+ continue;
2809
+ }
2810
+ }
2811
+ message(messageTypes.WARN, STRING.WARN.LICENSENOTFOUND, dep.fullname || dep.name);
2812
+ fileObj.found = false;
2813
+ fileObj.packageObject = dep;
2814
+ fileObjList.push(fileObj);
2815
+ }
2816
+ this.fileObjList = fileObjList;
2817
+ }
2818
+ parseDependencies(dependencies) {
2819
+ const dependencieList = [];
2820
+ const uncompleteDependencies = [];
2821
+ const AMBIGIUOUS_YARN_VERSION_LENGTH = 6;
2822
+ for (const dependencie of dependencies) {
2823
+ if (!dependencie.name) {
2824
+ continue;
2825
+ }
2826
+ const atIndex = dependencie.name.lastIndexOf("@");
2827
+ const newDependencie = {
2828
+ name: atIndex > 0 ? dependencie.name.slice(0, atIndex) : dependencie.name,
2829
+ version: atIndex > 0 ? dependencie.name.slice(atIndex + 1).replace(/^[\^~><=]+/, "") : "UNKNOWN"
2830
+ };
2831
+ if (newDependencie.version.length <= 1 || newDependencie.version.length > AMBIGIUOUS_YARN_VERSION_LENGTH) {
2832
+ uncompleteDependencies.push(newDependencie);
2833
+ } else {
2834
+ dependencieList.push(newDependencie);
2835
+ }
2836
+ if (dependencie.children && dependencie.children.length > 0) {
2837
+ const {
2838
+ dependencieList: subDependencieList,
2839
+ uncompleteDependencies: subUncompleteDependencies
2840
+ } = this.parseDependencies(dependencie.children);
2841
+ dependencieList.push(...subDependencieList);
2842
+ uncompleteDependencies.push(...subUncompleteDependencies);
2843
+ }
2844
+ }
2845
+ return { dependencieList, uncompleteDependencies };
2846
+ }
2847
+ async getDependencies() {
2848
+ let parsedDependencies = [];
2849
+ try {
2850
+ execSync("yarn list --json --production --depth=Infinity > dependencies.json", {
2851
+ encoding: "utf8",
2852
+ stdio: ["pipe", "pipe", "pipe"]
2853
+ });
2854
+ parsedDependencies = await this.parseNewlineDelimitedJsonToJson(
2855
+ pathLib.resolve("./dependencies.json")
2856
+ );
2857
+ } catch (err) {
2858
+ error(err);
2859
+ }
2860
+ return parsedDependencies;
2861
+ }
2862
+ async parseNewlineDelimitedJsonToJson(filePath) {
2863
+ try {
2864
+ const fileStream = createReadStreamSync(pathLib.resolve(filePath));
2865
+ const readLine = readline$1.createInterface({ input: fileStream });
2866
+ const result = [];
2867
+ for await (const line of readLine) {
2868
+ if (line.trim() === "") continue;
2869
+ result.push(JSON.parse(line));
2870
+ }
2871
+ return result;
2872
+ } catch (err) {
2873
+ error(err);
2874
+ }
2875
+ return [];
2876
+ }
2877
+ /**
2878
+ * Completes the information of uncomplete Yarn dependencies
2879
+ *
2880
+ * @param uncompleteDependencies a list of uncomplete dependencies
2881
+ * @returns a list of completed dependencies
2882
+ */
2883
+ completeYarnDependencies(uncompleteDependencies) {
2884
+ const completedDependencies = [];
2885
+ for (const dep of uncompleteDependencies) {
2886
+ const versions = execSync(`yarn info ${dep.name} --json`, { encoding: "utf8" });
2887
+ const parsedVersions = JSON.parse(versions);
2888
+ const completedDep = {
2889
+ name: dep.name,
2890
+ version: parsedVersions.data.version || "UNKNOWN"
2891
+ };
2892
+ completedDependencies.push(completedDep);
2893
+ }
2894
+ return completedDependencies;
2895
+ }
2896
+ /**
2897
+ * Builds the content path.
2898
+ *
2899
+ * @param packageObject The package object.
2900
+ * @param fileName The file name to search for.
2901
+ * @returns The constructed content path.
2902
+ */
2903
+ buildContentPath(packageObject) {
2904
+ return packageObject.hasSubDirectory ? `./node_modules/${packageObject.path}/${packageObject.name}/` : `./node_modules/${packageObject.name}/`;
2905
+ }
2906
+ }
2907
+ class LicenseBuilderFactory {
2908
+ async getLicenseBuilder(projectName, writeStream) {
2909
+ const result = await this.searchPackageManager(process.cwd());
2910
+ if (result === void 0)
2911
+ error(
2912
+ `No supported package manager found in the current directory or any parent directories.`
2913
+ );
2914
+ const packageManager = typeof result === "string" ? result : result.packageManager;
2915
+ const rootPath = typeof result === "string" ? process.cwd() : result.rootPath;
2916
+ switch (packageManager) {
2917
+ case "npm":
2918
+ message(messageTypes.INFO, `Using npm as package manager.`);
2919
+ return new NpmLicenseBuilder(projectName, writeStream);
2920
+ case "yarn":
2921
+ message(messageTypes.INFO, `Using yarn as package manager.`);
2922
+ return new YarnLicenseBuilder(projectName, writeStream);
2923
+ case "pnpm":
2924
+ message(messageTypes.INFO, `Using pnpm as package manager.`);
2925
+ return new PnpmLicenseBuilder(projectName, writeStream, rootPath);
2926
+ default:
2927
+ throw new Error(`Unsupported package manager: ${packageManager}`);
2928
+ }
2929
+ }
2930
+ /**
2931
+ * checks which package manager is used in the current project
2932
+ *
2933
+ * @param startDir the directory to start searching from
2934
+ * @returns the package manager used in the project
2935
+ */
2936
+ async searchPackageManager(startDir) {
2937
+ const lockFiles = {
2938
+ npm: "package-lock.json",
2939
+ pnpm: "pnpm-lock.yaml",
2940
+ yarn: "yarn.lock"
2941
+ };
2942
+ for (const [manager, lock] of Object.entries(lockFiles)) {
2943
+ const packagePath = pathLib.join(startDir, lock);
2944
+ if (await exists(packagePath)) {
2945
+ return { packageManager: manager.toString(), rootPath: pathLib.dirname(packagePath) };
2946
+ }
2947
+ }
2948
+ const parentDir = pathLib.dirname(startDir);
2949
+ if (parentDir === startDir) return "unknown";
2950
+ return await this.searchPackageManager(parentDir);
2951
+ }
2952
+ }
2953
+ const missingLicenses = [];
2954
+ let findLicenseCounter = 0;
2955
+ let missingLicenseCount = 0;
2956
+ let licenseWriteStream;
2957
+ let inputLicensePath = "";
2958
+ let manifestData$1;
2959
+ let packageJsonData;
2960
+ const licenseCommand = new Command("license").description(
2961
+ "Create a 3rdpartylicenses.txt file, which contains the licenses of all dependencies."
2962
+ ).option("--p, --path <string>", "The local 3rd-party-license folder").action(async (options) => {
2963
+ manifestData$1 = await getJsonFile(pathLib.resolve("./manifest.json"), false);
2964
+ packageJsonData = await getJsonFile(
2965
+ pathLib.resolve("./package.json"),
2966
+ false
2967
+ );
2968
+ if (!manifestData$1 && !packageJsonData) error("No manifest or package.json found", false);
2969
+ if (!manifestData$1 && options.path !== void 0)
2970
+ error("The --path parameter can only be used if a manifest.json file exists.", false);
2971
+ licenseWriteStream = createWriteStreamSync("./3rdpartylicenses.txt");
2972
+ const projectName = manifestData$1?.name ?? packageJsonData?.name;
2973
+ if (options.path !== void 0) {
2974
+ if (options.path !== "") {
2975
+ inputLicensePath = `./${options.path}`;
2976
+ message(messageTypes.INFO, `Searching for licenses in '${inputLicensePath}' folder.`);
2977
+ if (!await exists(inputLicensePath))
2978
+ message(
2979
+ messageTypes.WARN,
2980
+ `The specified path '${inputLicensePath}' does not exists. Default paths will be used.`
2981
+ );
2982
+ } else {
2983
+ error(
2984
+ `'--p' <path> parameter has to be of type 'String' and isn't allowed to be empty.`,
2985
+ false
2986
+ );
2987
+ }
2988
+ }
2989
+ try {
2990
+ const licenseBuilderFactory = new LicenseBuilderFactory();
2991
+ const licenseBuilder = await licenseBuilderFactory.getLicenseBuilder(
2992
+ projectName,
2993
+ licenseWriteStream
2994
+ );
2995
+ await licenseBuilder.createLicenseFile(inputLicensePath, manifestData$1 || {});
2996
+ findLicenseCounter = licenseBuilder.getFoundCounter();
2997
+ missingLicenseCount = licenseBuilder.getMissingCounter();
2998
+ missingLicenses.push(...licenseBuilder.getMissingLicenses());
2999
+ if (missingLicenseCount > 0) {
3000
+ if (inputLicensePath !== "" && !await exists(inputLicensePath)) {
3001
+ unlinkSync("./3rdpartylicenses.txt");
3002
+ }
3003
+ const totalModules = findLicenseCounter + missingLicenseCount;
3004
+ message(
3005
+ messageTypes.WARN,
3006
+ `${missingLicenseCount + (missingLicenseCount > 1 ? " licenses " : " license ")}out of ${totalModules}${totalModules > 1 ? " modules " : " module "}not found.`
3007
+ );
3008
+ error(`Not all licenses found.
3009
+ ${missingLicenses.join("\n")}`, false);
3010
+ } else {
3011
+ message(
3012
+ messageTypes.INFO,
3013
+ `${findLicenseCounter + (findLicenseCounter > 1 ? " licenses" : " license")} ${STRING.INFO.LICENSESAVED}`
3014
+ );
3015
+ }
3016
+ } catch (err) {
3017
+ error(`Error generating license file: ${err}`, false);
3018
+ }
3019
+ });
3020
+ const linkCommand = new Command("link").description("It links the ELO dependencies").option("--source_path <string>", 'The "elo-vue-libs" project path.').option("--no_source_link", 'No "npm link" execution.').option("--no_build", 'No "npm run build" execution.').action(async (options, path) => {
3021
+ path = ensureSlash(pathLib.resolve(unixPathSep(process.cwd())));
3022
+ const simpleLink = !!options.no_source_link;
3023
+ const shouldBuild = !options.no_build;
3024
+ const packageJson2 = await getJsonFile(
3025
+ pathLib.resolve(path, CONSTANTS.PACKAGEFILE),
3026
+ true
3027
+ );
3028
+ let linkFolder = "";
3029
+ let sourcePath = "";
3030
+ if (options.source_path) {
3031
+ sourcePath = options.source_path;
3032
+ message(messageTypes.INFO, `source path: ${sourcePath}`);
3033
+ }
3034
+ if (!packageJson2.eloDependencies) {
3035
+ error(STRING.ERROR.NOELODEPENDENCIES, false);
3036
+ }
3037
+ if (!simpleLink) {
3038
+ const folderCandidates = [
3039
+ "elo-vue-libs",
3040
+ sourcePath,
3041
+ pathLib.resolve(path, "../elo-vue-libs"),
3042
+ pathLib.resolve(path, "../../elo-vue-libs")
3043
+ ];
3044
+ for (const dependency of packageJson2.eloDependencies) {
3045
+ try {
3046
+ if (dependency.name === "elo-cli") {
3047
+ message(messageTypes.WARN, STRING.WARN.NOCLILINKING);
3048
+ continue;
3049
+ }
3050
+ linkFolder = folderCandidates.find(async (path2) => {
3051
+ if (await exists(pathLib.resolve(path2))) {
3052
+ return path2;
3053
+ }
3054
+ }) || "";
3055
+ if (linkFolder === "") continue;
3056
+ const dependencyFolder = pathLib.resolve(linkFolder, dependency.folder);
3057
+ const command22 = shouldBuild && dependency.buildCommand !== "NONE" && typeof dependency.buildCommand === "string" ? `cd ${dependencyFolder} && npm link && npm run ${dependency.buildCommand}` : `cd ${dependencyFolder} && npm link`;
3058
+ message(messageTypes.DEFAULT, command22);
3059
+ const result = execSync(command22);
3060
+ message(messageTypes.DEFAULT, result.toString());
3061
+ } catch (err) {
3062
+ error(err, false, STRING.ERROR.LINKDEPENDENCY);
3063
+ }
3064
+ }
3065
+ }
3066
+ message(messageTypes.DEFAULT, "link elo dependencies");
3067
+ let command2 = "npm link";
3068
+ packageJson2.eloDependencies.forEach((dependency) => {
3069
+ if (dependency.name === "elo-cli") {
3070
+ message(messageTypes.WARN, STRING.WARN.NOCLILINKING);
3071
+ return;
3072
+ }
3073
+ command2 = `${command2} @elo/${dependency.name}`;
3074
+ });
3075
+ try {
3076
+ message(messageTypes.DEFAULT, command2);
3077
+ const result = execSync(command2);
3078
+ message(messageTypes.DEFAULT, result.toString());
3079
+ message(messageTypes.INFO, "link complete");
3080
+ } catch (err) {
3081
+ error(err, false, STRING.ERROR.LINKDEPENDENCY);
3082
+ }
3083
+ });
3084
+ let manifestData;
3085
+ let defaultPropertiesFile = "";
3086
+ let supportedLocales = [];
3087
+ const foundProperties = [];
3088
+ async function getPropertyFiles(src) {
3089
+ try {
3090
+ const files = await FastGlob([`${src}/**/*.properties`]);
3091
+ foundProperties.push(...files);
3092
+ if (foundProperties.length === 0) error("No properties found", false);
3093
+ foundProperties.forEach((props) => {
3094
+ if (!props.includes("_")) defaultPropertiesFile = props;
3095
+ });
3096
+ } catch (err) {
3097
+ error(STRING.ERROR.GETPROPERTYFILES, false, err);
3098
+ }
3099
+ }
3100
+ async function createNewLocalizationFiles(manifestData2, path2) {
3101
+ try {
3102
+ message(messageTypes.INFO, STRING.INFO.CREATELOCALESDIR, path2);
3103
+ const name = manifestData2.name?.includes("/") ? manifestData2.name.split("/")[1] : manifestData2.name;
3104
+ mkdir(path2, false);
3105
+ await writeFile(ensureSlash(path2) + `${name}-app.properties`, `APP.NAME=${name}`);
3106
+ } catch (err) {
3107
+ error(STRING.ERROR.CREATENEWLOCALES, false, err);
3108
+ }
3109
+ }
3110
+ function checkConditions(src, dist, manifestData2) {
3111
+ const foundErrors = [];
3112
+ const tab = " ";
3113
+ if (!src) foundErrors.push(tab + STRING.ERROR.SRCPATHREQIRED);
3114
+ if (!dist) foundErrors.push(tab + STRING.ERROR.DISTPATHREQIRED);
3115
+ if (!manifestData2.defaultLanguage || manifestData2.defaultLanguage === "")
3116
+ foundErrors.push(tab + STRING.ERROR.NODEFAULTLANG);
3117
+ if (!supportedLocales || supportedLocales.length === 0)
3118
+ foundErrors.push(tab + STRING.ERROR.NOSUPPORTEDLOCALES);
3119
+ if (foundErrors.length > 0)
3120
+ error("Cannot localize, found errors:\n" + foundErrors.join("\n"), false);
3121
+ }
3122
+ async function getKeysAndCheckKeyDuplicates() {
3123
+ const keyMap = /* @__PURE__ */ new Map();
3124
+ const doubleKeys = /* @__PURE__ */ new Map();
3125
+ console.log("Default properties file: " + defaultPropertiesFile);
3126
+ try {
3127
+ const readProperties = (await readFileFunction(defaultPropertiesFile)).trim();
3128
+ const splittetLines = readProperties.split(os.EOL);
3129
+ splittetLines.forEach((line) => {
3130
+ const splittKeyValue = line.split("=");
3131
+ if (splittKeyValue.length !== 2) {
3132
+ message(messageTypes.WARN, `Invalid line in default properties file: ` + line);
3133
+ return;
3134
+ }
3135
+ if (keyMap.has(splittKeyValue[0])) {
3136
+ doubleKeys.set(splittKeyValue[0], splittKeyValue[1]);
3137
+ return;
3138
+ }
3139
+ keyMap.set(splittKeyValue[0], splittKeyValue[1]);
3140
+ });
3141
+ if (doubleKeys.size > 0)
3142
+ message(
3143
+ messageTypes.WARN,
3144
+ "Duplicate keys found: " + Array.from(doubleKeys.keys()).join(", ")
3145
+ );
3146
+ else message(messageTypes.INFO, STRING.INFO.NOKEYDUPLICATESFOUND);
3147
+ } catch (err) {
3148
+ error(STRING.ERROR.GETKEYSCHECKDUPLICATES, false, err);
3149
+ }
3150
+ return { keyMap, doubleKeys };
3151
+ }
3152
+ async function checkUnusedKeys(keyMap) {
3153
+ const unusedKeys = new Map(keyMap);
3154
+ try {
3155
+ const files = await FastGlob.async(CONSTANTS.GLOBBYPATTERN, {
3156
+ ignore: CONSTANTS.GLOBBYOPTIONS.ignore
3157
+ });
3158
+ for (const file of files) {
3159
+ if (file.endsWith("properties") || file.includes("all_locales.js")) continue;
3160
+ const fileContent = await readFileFunction(file);
3161
+ for (const [key] of unusedKeys) {
3162
+ if (fileContent.includes(key)) unusedKeys.delete(key);
3163
+ }
3164
+ }
3165
+ if (unusedKeys.size > 0)
3166
+ message(
3167
+ messageTypes.WARN,
3168
+ `Unused ${unusedKeys.size > 1 ? "keys" : "key"} found: ` + Array.from(unusedKeys.keys()).join(", ")
3169
+ );
3170
+ else message(messageTypes.INFO, STRING.INFO.NOUNUSEDKEYS);
3171
+ } catch (err) {
3172
+ error(STRING.ERROR.CHECKUNUSEDKEYS, false, err);
3173
+ }
3174
+ return unusedKeys;
3175
+ }
3176
+ async function createLocalesMap(keyMap, manifestData2, propertiesFiles) {
3177
+ const localesMap = /* @__PURE__ */ new Map();
3178
+ const issueReport = /* @__PURE__ */ new Map();
3179
+ issueReport.set("unusedKeys", /* @__PURE__ */ new Map());
3180
+ issueReport.set("duplicateKeys", /* @__PURE__ */ new Map());
3181
+ issueReport.set("unnecessaryKeys", /* @__PURE__ */ new Map());
3182
+ try {
3183
+ for (const propertiesFile of propertiesFiles) {
3184
+ const lang = getLangFromFilename(propertiesFile);
3185
+ const duplicateKeysMap = /* @__PURE__ */ new Map();
3186
+ const unnecessaryKeysMap = /* @__PURE__ */ new Map();
3187
+ const unusedKeysMap = new Map(keyMap);
3188
+ if (localesMap.has(lang)) continue;
3189
+ if (lang && !supportedLocales.includes(lang)) {
3190
+ message(messageTypes.WARN, STRING.INFO.NEWLANGUAGEFOUND, lang);
3191
+ manifestData2.supportedLocales.push(lang);
3192
+ await updateManifestData(manifestData2);
3193
+ }
3194
+ if (lang === "") {
3195
+ if (localesMap.has(manifestData2.defaultLanguage))
3196
+ error(STRING.ERROR.DUPDEFAULTLANGFILE, false);
3197
+ localesMap.set(manifestData2.defaultLanguage, /* @__PURE__ */ new Map());
3198
+ keyMap.forEach((value, key) => {
3199
+ localesMap.get(manifestData2.defaultLanguage)?.set(key, value);
3200
+ });
3201
+ } else {
3202
+ const readProperties = await readFileFunction(propertiesFile);
3203
+ const splittetLines = readProperties.split(os.EOL);
3204
+ localesMap.set(lang, /* @__PURE__ */ new Map());
3205
+ for (const line of splittetLines) {
3206
+ if (!line.trim() || line.trim().startsWith("#") || line.trim().startsWith("!")) continue;
3207
+ if (!line.includes("=")) {
3208
+ message(messageTypes.WARN, `Invalid line in '${lang}' properties file: ` + line);
3209
+ continue;
3210
+ }
3211
+ const splittKeyValue = line.split("=");
3212
+ if (!keyMap.has(splittKeyValue[0])) {
3213
+ unnecessaryKeysMap.set(splittKeyValue[0], splittKeyValue[1]);
3214
+ continue;
3215
+ }
3216
+ if (splittKeyValue.length > 2) {
3217
+ message(messageTypes.WARN, `Invalid line in '${lang}' properties file: ` + line);
3218
+ continue;
3219
+ }
3220
+ if (localesMap.get(lang)?.has(splittKeyValue[0]))
3221
+ duplicateKeysMap.set(splittKeyValue[0], splittKeyValue[1]);
3222
+ if (unusedKeysMap.has(splittKeyValue[0])) unusedKeysMap.delete(splittKeyValue[0]);
3223
+ localesMap.get(lang)?.set(splittKeyValue[0], splittKeyValue[1]);
3224
+ }
3225
+ if (duplicateKeysMap.size > 0) {
3226
+ issueReport.get("duplicateKeys").set(lang, duplicateKeysMap);
3227
+ message(
3228
+ messageTypes.WARN,
3229
+ `Duplicate ${duplicateKeysMap.size > 1 ? "keys" : "key"} found: ` + Array.from(duplicateKeysMap.keys()).join(", ")
3230
+ );
3231
+ }
3232
+ if (unnecessaryKeysMap.size > 0) {
3233
+ issueReport.get("unnecessaryKeys").set(lang, unnecessaryKeysMap);
3234
+ message(
3235
+ messageTypes.WARN,
3236
+ `Unnecessary ${unnecessaryKeysMap.size > 1 ? "keys" : "key"} found: ` + Array.from(unnecessaryKeysMap.keys()).join(", ")
3237
+ );
3238
+ }
3239
+ if (unusedKeysMap.size > 0) {
3240
+ issueReport.get("unusedKeys").set(lang, unusedKeysMap);
3241
+ message(
3242
+ messageTypes.WARN,
3243
+ `Unused ${unusedKeysMap.size > 1 ? "keys" : "key"} found: ` + Array.from(unusedKeysMap.keys()).join(", ")
3244
+ );
3245
+ }
3246
+ message(messageTypes.INFO, STRING.INFO.PROPERTIESPROCESSED, propertiesFile);
3247
+ }
3248
+ }
3249
+ } catch (err) {
3250
+ error(STRING.ERROR.CREATELOCALESMAP, false, err);
3251
+ }
3252
+ return { localesMap, issueReport };
3253
+ }
3254
+ function checkLanguageIntegrity(localesMap, manifestData2) {
3255
+ const completeMap = localesMap;
3256
+ message(messageTypes.INFO, STRING.INFO.STARTINTIGRITYCHECK);
3257
+ for (const [lang, langMap] of completeMap) {
3258
+ if (lang === manifestData2.defaultLanguage) continue;
3259
+ const checkKeysMap = completeMap.get(manifestData2.defaultLanguage);
3260
+ const fallBackLang = getFallbackLanguage(lang);
3261
+ for (const [key, value] of checkKeysMap) {
3262
+ if (!langMap.has(key)) {
3263
+ if (fallBackLang && completeMap.get(fallBackLang).has(key)) {
3264
+ message(messageTypes.WARN, STRING.WARN.CHANGELANGUAGEVALUE, key, lang, fallBackLang);
3265
+ completeMap.get(lang).set(key, completeMap.get(fallBackLang).get(key));
3266
+ } else {
3267
+ message(
3268
+ messageTypes.WARN,
3269
+ STRING.WARN.CHANGELANGUAGEVALUE,
3270
+ key,
3271
+ lang,
3272
+ manifestData2.defaultLanguage
3273
+ );
3274
+ completeMap.get(lang).set(key, value);
3275
+ }
3276
+ }
3277
+ }
3278
+ message(messageTypes.INFO, STRING.INFO.LANGUAGEINTEGRITYCHECK, lang);
3279
+ }
3280
+ return completeMap;
3281
+ }
3282
+ async function writeAllLocalesFile(completeLocalesMap, distPath) {
3283
+ try {
3284
+ let localesString = "";
3285
+ localesString += `(function (factory) {${os.EOL}var elo = factory(window);${os.EOL}if (typeof exports === 'object') {${os.EOL}exports = elo;${os.EOL}}${os.EOL}}(function (win) {${os.EOL}var elo = (win ? win.elo : false) || elo || {};${os.EOL}elo.locale = elo.locale || {};${os.EOL}elo.locale.localeMap = elo.locale.localeMap || {};${os.EOL}`;
3286
+ for (const [lang, langMap] of completeLocalesMap) {
3287
+ localesString += `elo.locale.localeMap["${lang}"] = elo.locale.localeMap["${lang}"] || {};${os.EOL}`;
3288
+ for (const [key, value] of langMap) {
3289
+ localesString += `elo.locale.localeMap["${lang}"]["${key}"] = ${JSON.stringify(value)};${os.EOL}`;
3290
+ }
3291
+ }
3292
+ localesString += `if (elo.data && elo.data.server && elo.data.server.language) {${os.EOL}elo.locale.language = elo.data.server.language;${os.EOL}elo.locale.store = elo.locale.localeMap[elo.locale.language];${os.EOL}}${os.EOL}return elo;${os.EOL}}));`;
3293
+ message(
3294
+ messageTypes.INFO,
3295
+ STRING.INFO.WRITELOCALESFILE,
3296
+ pathLib.resolve(ensureSlash(distPath), "all_locales.js")
3297
+ );
3298
+ await writeFile(ensureSlash(distPath) + "all_locales.js", localesString);
3299
+ } catch (err) {
3300
+ error(STRING.ERROR.WRITELOCALESFILE, false, err);
3301
+ }
3302
+ }
3303
+ async function writeReportFile(issueReport) {
3304
+ message(
3305
+ messageTypes.INFO,
3306
+ STRING.INFO.WRITEREPORTFILE,
3307
+ pathLib.resolve(ensureSlash(process.cwd()), "localization_report.json")
3308
+ );
3309
+ await writeFile("./localization_report.json", JSON.stringify(mapToObj(issueReport), void 0, 4));
3310
+ message(messageTypes.INFO, STRING.INFO.REPORTCOMPOLETED);
3311
+ }
3312
+ function getLangFromFilename(filename) {
3313
+ const file = filename.split("/").pop();
3314
+ const fileNameOnly = file.split(".")[0];
3315
+ const split = fileNameOnly.split("_");
3316
+ const langCode = split.length > 2 ? split.slice(1).join("_") : split[1] || "";
3317
+ return langCode;
3318
+ }
3319
+ function getFallbackLanguage(lang) {
3320
+ let langParts;
3321
+ if (lang.includes("_")) langParts = lang.split("_")[0];
3322
+ else langParts = lang;
3323
+ const foundLang = manifestData.supportedLocales.find((language) => {
3324
+ if (lang === language) return;
3325
+ if (language.includes(langParts)) return language;
3326
+ });
3327
+ return foundLang ?? "";
3328
+ }
3329
+ const localizeCommand = new Command("localize").description("Localize language files and parse them to JSON format.").option(
3330
+ "--s, --src <string>",
3331
+ "The path where the properties files are. If no folder is given, new localization files will be created based on the manifest data."
3332
+ ).option(
3333
+ "--d, --dist <string>",
3334
+ "The path where the js files will be. The directory will be cleared."
3335
+ ).option(
3336
+ "--r, --report",
3337
+ "Generate a report.json of unused and duplicate keys in the localization files."
3338
+ ).action(async (options) => {
3339
+ manifestData = await getManifestData();
3340
+ supportedLocales = manifestData.supportedLocales;
3341
+ checkConditions(options.src, options.dist, manifestData);
3342
+ if (!await exists(pathLib.resolve(options.src))) {
3343
+ await createNewLocalizationFiles(manifestData, options.src);
3344
+ } else {
3345
+ if (await isFolderEmpty(pathLib.resolve(options.src)))
3346
+ error(STRING.ERROR.PROPERTIESNOTFOUND, false);
3347
+ }
3348
+ if (!await exists(pathLib.resolve(options.dist))) {
3349
+ message(messageTypes.INFO, STRING.INFO.CREATEDISTDIR, pathLib.resolve(options.dist));
3350
+ mkdir(pathLib.resolve(options.dist), false);
3351
+ }
3352
+ await getPropertyFiles(options.src);
3353
+ const { keyMap, doubleKeys } = await getKeysAndCheckKeyDuplicates();
3354
+ const unusedKeys = await checkUnusedKeys(keyMap);
3355
+ const { localesMap, issueReport } = await createLocalesMap(
3356
+ keyMap,
3357
+ manifestData,
3358
+ foundProperties
3359
+ );
3360
+ const completeLocalesMap = checkLanguageIntegrity(localesMap, manifestData);
3361
+ await writeAllLocalesFile(completeLocalesMap, options.dist);
3362
+ message(messageTypes.INFO, STRING.INFO.LOCALIZATIONCOMPLETE);
3363
+ if (options.report) {
3364
+ if (doubleKeys.size > 0)
3365
+ issueReport.get("duplicateKeys").set(manifestData.defaultLanguage, doubleKeys);
3366
+ if (unusedKeys.size > 0)
3367
+ issueReport.get("unusedKeys").set(manifestData.defaultLanguage, unusedKeys);
3368
+ await writeReportFile(issueReport);
3369
+ }
3370
+ });
3371
+ const command = process.platform === "win32" ? "npm.cmd" : "npm";
3372
+ async function getVersionFromRegistry(rootPath, repoInfo, tag, server) {
3373
+ return new Promise((resolve) => {
3374
+ const nameAndTag = `${repoInfo.packageJson.name}@${tag}`;
3375
+ const args = ["view", nameAndTag, "--registry", server, "--json"];
3376
+ exec(command + ` ${args.join(" ")}`, { cwd: rootPath }, (err, stdout) => {
3377
+ if (err) return resolve("none");
3378
+ const json = JSON.parse(stdout);
3379
+ return resolve(json.version);
3380
+ });
3381
+ });
3382
+ }
3383
+ async function increaseRegistryVersion(rootPath, version) {
3384
+ return new Promise((resolve, reject) => {
3385
+ const args = ["version", version];
3386
+ exec(command + ` ${args.join(" ")}`, { cwd: rootPath }, async (err, stdout, stderr) => {
3387
+ if (err) {
3388
+ if (err.message.includes("Version not changed")) {
3389
+ if (await checkNewVersionInPackageJson(rootPath, version)) return resolve(stdout.trim());
3390
+ }
3391
+ return reject(new Error(stderr || err.message));
3392
+ }
3393
+ return resolve(stdout.trim());
3394
+ });
3395
+ });
3396
+ }
3397
+ async function publishPackage(rootPath, tag, server) {
3398
+ return new Promise((resolve, reject) => {
3399
+ const args = ["publish", "--tag", tag, "--registry", server];
3400
+ exec(command + ` ${args.join(" ")}`, { cwd: rootPath }, (err, stdout, stderr) => {
3401
+ if (err) reject(new Error(stderr || err.message));
3402
+ return resolve(stdout.trim());
3403
+ });
3404
+ });
3405
+ }
3406
+ async function addTag(rootPath, repoInfo, tag, server) {
3407
+ return new Promise((resolve, reject) => {
3408
+ const args = [
3409
+ "dist-tag",
3410
+ "add",
3411
+ repoInfo.packageJson.name + "@" + repoInfo.newVersion,
3412
+ tag,
3413
+ "--registry",
3414
+ server
3415
+ ];
3416
+ exec(command + ` ${args.join(" ")}`, { cwd: rootPath }, (err, stdout, stderr) => {
3417
+ if (err) reject(new Error(stderr || err.message));
3418
+ return resolve(stdout.trim());
3419
+ });
3420
+ });
3421
+ }
3422
+ async function checkNewVersionInPackageJson(rootPath, version) {
3423
+ const packageJson2 = await getJsonFile(
3424
+ pathLib.resolve(rootPath, "package.json")
3425
+ );
3426
+ return packageJson2.version === version;
3427
+ }
3428
+ const npmComManager = {
3429
+ async getVersionFromRegistry(repoInfo, server, tag) {
3430
+ const rootPath = pathLib.resolve(ensureSlash(repoInfo.repository.path));
3431
+ try {
3432
+ return await getVersionFromRegistry(rootPath, repoInfo, tag, server);
3433
+ } catch (err) {
3434
+ throw Error(`Get version from registry failed: ${err}`);
3435
+ }
3436
+ },
3437
+ async increaseRegistryVersion(repoInfo, version) {
3438
+ const rootPath = pathLib.resolve(ensureSlash(repoInfo.repository.path));
3439
+ try {
3440
+ await increaseRegistryVersion(rootPath, version);
3441
+ } catch (err) {
3442
+ throw Error(`Set higher version failed: ${err}`);
3443
+ }
3444
+ },
3445
+ async publishPackage(repoInfo, tag, server) {
3446
+ const rootPath = pathLib.resolve(ensureSlash(repoInfo.repository.path));
3447
+ try {
3448
+ await publishPackage(rootPath, tag, server);
3449
+ } catch (err) {
3450
+ throw Error(`Publish package failed: ${err}`);
3451
+ }
3452
+ },
3453
+ async addTag(repoInfo, tag, server) {
3454
+ const rootPath = pathLib.resolve(ensureSlash(repoInfo.repository.path));
3455
+ try {
3456
+ await addTag(rootPath, repoInfo, tag, server);
3457
+ } catch (err) {
3458
+ throw Error(`Add tag failed: ${err}`);
3459
+ }
3460
+ }
3461
+ };
3462
+ const multiRepoInfos = [];
3463
+ async function validateMultiRepoConfig(config) {
3464
+ for (const repoConfig2 of config) {
3465
+ const packageJsonPath2 = pathLib.resolve(ensureSlash(repoConfig2.path), "package.json");
3466
+ if (!repoConfig2.path || !repoConfig2.name) error(STRING.ERROR.MULTIREPOCONFIGEMPTYPART, false);
3467
+ if (!await exists(packageJsonPath2))
3468
+ error(STRING.ERROR.PACKAGEJSONNOTFOUND, false, packageJsonPath2);
3469
+ const packageJson2 = await getJsonFile(packageJsonPath2);
3470
+ if (packageJson2.private === true)
3471
+ error(STRING.ERROR.PUBLISHPRIVATEPACKAGE, false, packageJson2.name);
3472
+ multiRepoInfos.push({
3473
+ repository: repoConfig2,
3474
+ packageJson: packageJson2
3475
+ });
3476
+ }
3477
+ message(messageTypes.INFO, STRING.INFO.CONFIGVALIDATED);
3478
+ }
3479
+ function increasePatchVersion(version) {
3480
+ const versionParts = version.split(".").map((num) => parseInt(num, 10));
3481
+ versionParts[2] += 1;
3482
+ return versionParts.join(".");
3483
+ }
3484
+ function handleMultiRepoVersions(packageJson2, field) {
3485
+ const deps = packageJson2[field];
3486
+ if (!deps) return;
3487
+ for (const [depName, depVersion] of Object.entries(deps)) {
3488
+ const matchedRepo = multiRepoInfos.find((repoInfo) => repoInfo.packageJson.name === depName);
3489
+ if (matchedRepo && matchedRepo.newVersion) {
3490
+ deps[depName] = matchedRepo.newVersion;
3491
+ message(
3492
+ messageTypes.INFO,
3493
+ `Updated ${field} "${depName}" = "${depVersion}" >> "${matchedRepo.newVersion}" in package "${packageJson2.name}".`
3494
+ );
3495
+ }
3496
+ }
3497
+ }
3498
+ async function mutateVersionFiles(info) {
3499
+ const packageJsonPath2 = pathLib.resolve(ensureSlash(info.repository.path), "package.json");
3500
+ const manifestPath = pathLib.resolve(ensureSlash(info.repository.path), "dist/manifest.json");
3501
+ const manifestDistPath = pathLib.resolve(ensureSlash(info.repository.path), "dist/manifest.json");
3502
+ const packageJson2 = info.packageJson;
3503
+ CONSTANTS.DEPENDENCIETYPES.forEach((type) => {
3504
+ handleMultiRepoVersions(packageJson2, type);
3505
+ });
3506
+ await writeFile(packageJsonPath2, JSON.stringify(packageJson2, null, 2) + "\n");
3507
+ message(messageTypes.INFO, STRING.INFO.MUTATEPACKAGEJSON, info.packageJson.name);
3508
+ if (await exists(manifestPath)) await mutateManifestVersion(manifestDistPath, info.newVersion);
3509
+ if (await exists(manifestDistPath))
3510
+ await mutateManifestVersion(manifestDistPath, info.newVersion);
3511
+ }
3512
+ async function mutateManifestVersion(manifestPath, newVersion) {
3513
+ const manifest = await getJsonFile(manifestPath);
3514
+ manifest.version = newVersion;
3515
+ await writeFile(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
3516
+ message(messageTypes.INFO, STRING.INFO.MUTATEMANIFEST, manifest.name);
3517
+ }
3518
+ async function checkVersion(tag, server, packageInfo) {
3519
+ const npmVersion = await npmComManager.getVersionFromRegistry(multiRepoInfos[0], server, tag) || "none";
3520
+ message(
3521
+ messageTypes.INFO,
3522
+ npmVersion != "none" ? `Latest version in registry for tag "${tag}": ${npmVersion}` : `No Version found for tag ${tag}, taking current package version: ${packageInfo.packageJson.version}`
3523
+ );
3524
+ return increasePatchVersion(npmVersion === "none" ? packageInfo.packageJson.version : npmVersion);
3525
+ }
3526
+ async function checkReleaseVersion(tag, server, packageInfo) {
3527
+ try {
3528
+ const npmVersion = await npmComManager.getVersionFromRegistry(multiRepoInfos[0], server, tag) || "none";
3529
+ const splitNpmVersion = npmVersion !== "none" ? npmVersion.split(".") : [];
3530
+ const [_, majorVersion, minorVersion] = tag.split("-");
3531
+ if (splitNpmVersion.length > 0 && splitNpmVersion[0] !== majorVersion)
3532
+ return increasePatchVersion(npmVersion);
3533
+ const patchVersion = splitNpmVersion.length > 0 ? parseInt(splitNpmVersion[2], 10) + 1 : 0;
3534
+ const releaseVersion = `${majorVersion}.${minorVersion ?? "0"}.${patchVersion}`;
3535
+ message(
3536
+ messageTypes.INFO,
3537
+ npmVersion !== "none" ? `Latest version in registry for tag "${tag}": ${npmVersion}` : `No Version found for tag ${tag}, taking current tag release version ${releaseVersion}.`
3538
+ );
3539
+ return releaseVersion;
3540
+ } catch (error2) {
3541
+ message(
3542
+ messageTypes.INFO,
3543
+ `Error fetching version from registry: ${error2.message}. Taking current package version: ${packageInfo.packageJson.version}`
3544
+ );
3545
+ return increasePatchVersion(packageInfo.packageJson.version);
3546
+ }
3547
+ }
3548
+ const publishCommand = new Command("publish").description("Set a new version for a package and publish it.").option("--t, --tag <string>", 'The tag under which the package is published. Example: "master"').option(
3549
+ "--s, --server <string>",
3550
+ 'Repository manager URL. Example: "http://nexus.example.com/repository/npm-registry/"'
3551
+ ).option(
3552
+ "--m, --multirepoconfig <string>",
3553
+ 'Path to the multi-repo configuration file. Example: "./elo-cli-multirepo.json"'
3554
+ ).option(
3555
+ "--d, --delay <number>",
3556
+ "Delay in seconds before checking if the package is published successfully."
3557
+ ).option("--l, --latest", "Set also the latest tag to the published package.").action(async (options) => {
3558
+ message(messageTypes.INFO, STRING.INFO.STARTPUBLISHCOMMAND);
3559
+ const multiRepoMode = options.multirepoconfig !== void 0;
3560
+ let multiRepoConfigPath = "";
3561
+ let multiRepoConfig = [];
3562
+ if (multiRepoMode) {
3563
+ multiRepoConfigPath = pathLib.resolve(options.multirepoconfig);
3564
+ if (!await exists(multiRepoConfigPath))
3565
+ error(STRING.ERROR.CONFIGFILENOTFOUND, false, multiRepoConfigPath);
3566
+ message(messageTypes.INFO, STRING.INFO.MULTIREPOMODE);
3567
+ multiRepoConfig = await getJsonFile(multiRepoConfigPath);
3568
+ await validateMultiRepoConfig(multiRepoConfig);
3569
+ } else {
3570
+ const packageJsonPath2 = pathLib.resolve("package.json");
3571
+ if (!await exists(packageJsonPath2))
3572
+ error(STRING.ERROR.PACKAGEJSONNOTFOUND, false, packageJsonPath2);
3573
+ const packageJson2 = await getJsonFile(packageJsonPath2);
3574
+ if (packageJson2.private === true)
3575
+ error(STRING.ERROR.PUBLISHPRIVATEPACKAGE, false, packageJson2.name);
3576
+ multiRepoInfos.push({
3577
+ repository: { name: "", path: "./" },
3578
+ packageJson: packageJson2
3579
+ });
3580
+ }
3581
+ try {
3582
+ const repoInfo = multiRepoInfos[0];
3583
+ const version = options.tag.startsWith("release") ? await checkReleaseVersion(options.tag, options.server, repoInfo) : await checkVersion(options.tag, options.server, repoInfo);
3584
+ for (const info of multiRepoInfos) {
3585
+ message(
3586
+ messageTypes.INFO,
3587
+ `Setting new version for package "${info.packageJson.name}": ${version}`
3588
+ );
3589
+ info.newVersion = version;
3590
+ info.packageJson.version = version;
3591
+ await npmComManager.increaseRegistryVersion(info, version);
3592
+ }
3593
+ for (const repoInfo2 of multiRepoInfos) {
3594
+ await mutateVersionFiles(repoInfo2);
3595
+ await npmComManager.publishPackage(repoInfo2, options.tag, options.server);
3596
+ message(messageTypes.INFO, STRING.INFO.PUBLISHSUCCESS, repoInfo2.packageJson.name);
3597
+ }
3598
+ await delay(Number(options.delay));
3599
+ if (options.latest) {
3600
+ for (const repoInfo2 of multiRepoInfos) {
3601
+ await npmComManager.addTag(repoInfo2, "latest", options.server);
3602
+ message(messageTypes.INFO, STRING.INFO.PUBLISHLATESTSUCCESS, repoInfo2.packageJson.name);
3603
+ }
3604
+ }
3605
+ for (const repoInfo2 of multiRepoInfos) {
3606
+ const publishedVersion = await npmComManager.getVersionFromRegistry(
3607
+ repoInfo2,
3608
+ options.server,
3609
+ options.tag
3610
+ );
3611
+ if (publishedVersion !== repoInfo2.newVersion)
3612
+ error(
3613
+ `Published version mismatch for package "${repoInfo2.packageJson.name}": expected ${repoInfo2.newVersion}, got ${publishedVersion}`,
3614
+ false
3615
+ );
3616
+ message(
3617
+ messageTypes.INFO,
3618
+ `Verified published version for package "${repoInfo2.packageJson.name}": ${publishedVersion}`
3619
+ );
3620
+ }
3621
+ message(messageTypes.INFO, STRING.INFO.PUBLISHCOMMANDCOMPLETED);
3622
+ } catch (err) {
3623
+ error(`Publish command failed: ${err.message}`, false);
3624
+ }
3625
+ });
3626
+ const setupConfig = commands.setup;
3627
+ const repoConfig = commands.newrepo;
3628
+ function setLookUpObj(settings2, optionConfig) {
3629
+ let lookUpObj;
3630
+ if (optionConfig.intoRoot) {
3631
+ lookUpObj = settings2;
3632
+ } else if (optionConfig.intoObj) {
3633
+ lookUpObj = settings2[optionConfig.intoObj];
3634
+ } else {
3635
+ lookUpObj = settings2.manifest;
3636
+ }
3637
+ return lookUpObj;
3638
+ }
3639
+ function setOptionValue(value, optionConfig) {
3640
+ if (optionConfig.placeholder === CONSTANTS.PLACEHOLDER.PATH) {
3641
+ value = unixPathSep(String(value));
3642
+ }
3643
+ if (optionConfig.encrypt) {
3644
+ value = encrypt(String(value));
3645
+ }
3646
+ return value;
3647
+ }
3648
+ function configOutput(settings2, archiveName) {
3649
+ if (archiveName === void 0) {
3650
+ message(messageTypes.INFO, STRING.INFO.WRITINGSETUP, unixPathSep(globalSettingsPath));
3651
+ message(messageTypes.INFO, JSON.stringify(settings2, null, JSON_SPACES));
3652
+ }
3653
+ }
3654
+ function currentSetupConfig(options) {
3655
+ let config;
3656
+ if (options.repository !== void 0) {
3657
+ if (options.repository == "true") {
3658
+ delete options.repository;
3659
+ }
3660
+ delete repoConfig.options.repository.ignore;
3661
+ config = repoConfig;
3662
+ } else {
3663
+ config = setupConfig;
3664
+ }
3665
+ return config;
3666
+ }
3667
+ function checkCurrentValue(currentValue, lookUpObj, optionConfig, optionKey) {
3668
+ if (getParameterInObject(lookUpObj, optionKey) && !optionConfig.encrypt) {
3669
+ currentValue = `(${getParameterInObject(lookUpObj, optionKey)}) `;
3670
+ }
3671
+ return currentValue;
3672
+ }
3673
+ async function processConfigParameter(options, path) {
3674
+ if (options.config && options.repository) {
3675
+ message(messageTypes.INFO, `Read Configuration: ${options.config}`);
3676
+ message(messageTypes.INFO, `Repository: ${options.repository}`);
3677
+ try {
3678
+ const props = await propertiesToObject(options.config);
3679
+ const settings2 = {
3680
+ manifest: {
3681
+ wfUrl: `${props.baseUrl}${props.port ? `:${props.port}` : ""}${props.ixContextPath}/plugin/de.elo.ix.plugin.proxy/wf/`,
3682
+ indexHtml: "index.html",
3683
+ src: "src",
3684
+ dist: "dist",
3685
+ namespace: "",
3686
+ id: "",
3687
+ defaultLanguage: "de"
3688
+ },
3689
+ ixLogin: {
3690
+ adminName: props.username,
3691
+ adminPw: encrypt(props.password)
3692
+ },
3693
+ ixUrl: `${props.baseUrl}${props.port ? `:${props.port}` : ""}${props.ixContextPath}/ix`
3694
+ };
3695
+ await writeSettingsJson(options.repository, path, settings2);
3696
+ await writeFile(".elo-current-repository", options.repository);
3697
+ message(messageTypes.INFO, STRING.INFO.SETUPCOMPLETE);
3698
+ process.exit(0);
3699
+ } catch (err) {
3700
+ error(`Could not read file ${options.config}`, false, err);
3701
+ }
3702
+ }
3703
+ }
3704
+ const setupCommand = new Command("setup").description("Setup the project").option("--r, --repository <string>", "Create a local repository (for projects)").option("--c, --config <string>", 'Create settings from a ".properties" file').option(
3705
+ "--index_html <string>",
3706
+ "The name of the index.html, for example: index.html (default: index.html)"
3707
+ ).option(
3708
+ "--src <string>",
3709
+ "The relative path where the source files, like the index.html, are, for example: src/"
3710
+ ).option(
3711
+ "--dist <string>",
3712
+ "The relative path where the output files, like the index.html, will be, for example: dist/"
3713
+ ).option("--namespace <string>", "The app namespace, for example: my.example.namespace").option("--default_lang <string>", "The default language, for example: de").option(
3714
+ "--server_url <string>",
3715
+ "Url of the server, for example: http://myServer:9090/ix-Repository/"
3716
+ ).option("--admin_name <string>", "Name of the ix admin user, for example: Administrator").option(
3717
+ "--admin_pw <string>",
3718
+ "According administrator password. This password will be stored encrypted but the key is not secure and can be read from the current machines hard drive. Only use test installations."
3719
+ ).action(async (options) => {
3720
+ message(messageTypes.INFO, "Setup CLI");
3721
+ const settings2 = await getGlobalSettingsJson();
3722
+ const path = process.cwd();
3723
+ let optionKey;
3724
+ let optionConfig;
3725
+ let promptValue;
3726
+ let value;
3727
+ let lookUpObj;
3728
+ let currentValue;
3729
+ let archiveName = void 0;
3730
+ if (options.config && options.repository) {
3731
+ await processConfigParameter(options, path);
3732
+ } else {
3733
+ message(messageTypes.INFO, STRING.INFO.SKIP);
3734
+ const config = currentSetupConfig(options);
3735
+ for (optionKey in config.options) {
3736
+ const option = getParameterInObject(config.options, optionKey);
3737
+ if (config.options.hasOwnProperty(optionKey)) {
3738
+ if (option.ignore) {
3739
+ continue;
3740
+ }
3741
+ currentValue = "";
3742
+ if (config.options.hasOwnProperty(optionKey)) {
3743
+ optionConfig = option;
3744
+ lookUpObj = setLookUpObj(settings2, optionConfig);
3745
+ if (options[optionConfig.value]) {
3746
+ value = options[optionConfig.value];
3747
+ } else {
3748
+ currentValue = checkCurrentValue(currentValue, lookUpObj, optionConfig, optionKey);
3749
+ message(messageTypes.INFO, optionConfig.description, optionConfig.eg || "");
3750
+ try {
3751
+ promptValue = await prompts({
3752
+ type: optionConfig.encrypt ? "password" : "text",
3753
+ name: "value",
3754
+ message: optionConfig.value,
3755
+ initial: getParameterInObject(lookUpObj, optionKey) || "",
3756
+ hint: optionConfig.eg || ""
3757
+ });
3758
+ value = promptValue.value;
3759
+ } catch {
3760
+ error(STRING.ERROR.PROMPT, true);
3761
+ message(messageTypes.DEFAULT);
3762
+ message(
3763
+ messageTypes.DEFAULT,
3764
+ "--------------------------------------------------------------"
3765
+ );
3766
+ message(
3767
+ messageTypes.WARN,
3768
+ "Retrying without pw security. Password will be visible here! Abort if you are not alone."
3769
+ );
3770
+ message(
3771
+ messageTypes.DEFAULT,
3772
+ "--------------------------------------------------------------"
3773
+ );
3774
+ message(messageTypes.DEFAULT, optionConfig.description, optionConfig.eg || "");
3775
+ promptValue = await prompts({
3776
+ type: "text",
3777
+ name: "value",
3778
+ message: optionConfig.value
3779
+ });
3780
+ value = promptValue.value;
3781
+ }
3782
+ }
3783
+ if (!isEmpty(value)) {
3784
+ value = setOptionValue(value, optionConfig);
3785
+ if (optionConfig.value === "server_url") {
3786
+ let name = String(value);
3787
+ if (name.endsWith("/ix")) name = name.substring(0, name.length - 3);
3788
+ settings2.ixUrl = `${ensureSlash(name)}ix`;
3789
+ settings2.manifest.wfUrl = `${ensureSlash(name)}plugin/de.elo.ix.plugin.proxy/wf/`;
3790
+ } else if (optionConfig.value === repoConfig.options.repository.value && typeof value === "string") {
3791
+ archiveName = value;
3792
+ } else {
3793
+ lookUpObj = setParameterInObject(lookUpObj, optionKey, value);
3794
+ }
3795
+ }
3796
+ }
3797
+ }
3798
+ }
3799
+ configOutput(settings2, archiveName);
3800
+ await writeSettingsJson(archiveName, path, settings2);
3801
+ message(messageTypes.INFO, STRING.INFO.SETUPCOMPLETE);
3802
+ process.exit(0);
3803
+ }
3804
+ });
3805
+ const metaFileName = fileURLToPath(import.meta.url);
3806
+ const metaDirName = dirname(metaFileName);
3807
+ const packageJsonPath = join(metaDirName, "../package.json");
3808
+ const packageJson = JSON.parse(readFileSync$1(packageJsonPath, "utf-8"));
3809
+ const program = new Command();
3810
+ program.name("elo").description(STRING.INIT.INFO).version(packageJson.version);
3811
+ program.hook("preAction", (thisCommand, actionCommand) => {
3812
+ message(
3813
+ messageTypes.INFO,
3814
+ `${thisCommand.name()}-cli ${actionCommand.name() || actionCommand.parent?.name()} ${packageJson.version}`
3815
+ );
3816
+ });
3817
+ program.addCommand(initCommand);
3818
+ program.addCommand(setupCommand);
3819
+ program.addCommand(buildCommand);
3820
+ program.addCommand(deployCommand);
3821
+ program.addCommand(importCommand);
3822
+ program.addCommand(exportCommand);
3823
+ program.addCommand(linkCommand);
3824
+ program.addCommand(licenseCommand);
3825
+ program.addCommand(localizeCommand);
3826
+ program.addCommand(publishCommand);
3827
+ program.parse(process.argv);