trm-client 11.2.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/changelog.txt CHANGED
@@ -8,6 +8,16 @@ Legend
8
8
  + : added
9
9
  - : removed
10
10
 
11
+ 2026-10-11 v12.0.0
12
+ -------------------
13
+ ! trm-core ^10.0.1
14
+
15
+ 2026-09-23 v11.3.0
16
+ -------------------
17
+ + system alias connection data saved after connecting when changed (e.g. rotated tokens)
18
+ ! alias check saves updated connection data
19
+ ! compare reads systems one at a time, closing each connection before opening the next
20
+
11
21
  2026-09-23 v11.2.0
12
22
  -------------------
13
23
  ! trm-core ^9.10.6
package/dist/cli.js CHANGED
@@ -61,6 +61,7 @@ new implementations_1.Publish(program, 'pack', ['export']).register();
61
61
  new implementations_1.Lock(program, 'lock', ['lock-file']).register();
62
62
  new implementations_1.Unpublish(program, 'unpublish').register();
63
63
  new implementations_1.Deprecate(program, 'deprecate').register();
64
+ new implementations_1.Uninstall(program, 'uninstall').register();
64
65
  new implementations_1.Install(program, 'install', ['i']).register();
65
66
  new implementations_1.Install(program, 'clean-install', ['ci']).register();
66
67
  new implementations_1.Install(program, 'update').register();
@@ -35,6 +35,7 @@ export declare abstract class AbstractCommand {
35
35
  protected abstract handler(): Promise<void>;
36
36
  register(): void;
37
37
  private getLogger;
38
+ private getDefaultLoggerType;
38
39
  private getInquirer;
39
40
  private normalizeArgs;
40
41
  private parseCommandArgs;
@@ -190,7 +190,7 @@ class AbstractCommand {
190
190
  if (!this.command) {
191
191
  throw new Error(`Command "${this.name}" cannot be registered without a Commander program.`);
192
192
  }
193
- const defaultLogger = utils_1.GlobalContext.getInstance().getSettings().loggerType;
193
+ const defaultLogger = this.getDefaultLoggerType();
194
194
  const logOutputFolder = utils_1.GlobalContext.getInstance().getSettings().logOutputFolder;
195
195
  this.command
196
196
  .option(`--logger <logger type>`, `Logger type.`, defaultLogger)
@@ -221,7 +221,7 @@ class AbstractCommand {
221
221
  if (!this.registerOpts.onlyRegistryAlias) {
222
222
  this.command
223
223
  .option(`-E, --registry-endpoint <endpoint>`, `Registry endpoint.`)
224
- .option(`-A, --registry-auth <authentication>`, `Registry authentication (JSON or path to JSON file).`);
224
+ .option(`-A, --registry-auth <authentication>`, `Registry authentication (JSON or path to JSON file), e.g. {"token":"<token>"} or, in GitHub Actions, {"oidc":"github"}.`);
225
225
  }
226
226
  }
227
227
  if (this.registerOpts.requiresR3trans) {
@@ -242,6 +242,13 @@ class AbstractCommand {
242
242
  default: throw new Error(`Unknown logger type "${type}". Possible values are ${Object.keys(LoggerType_1.LoggerType).map(k => LoggerType_1.LoggerType[k]).join(', ')}.`);
243
243
  }
244
244
  }
245
+ getDefaultLoggerType() {
246
+ const configured = utils_1.GlobalContext.getInstance().getSettings().loggerType;
247
+ if (configured && configured.toUpperCase() !== 'AUTO') {
248
+ return configured;
249
+ }
250
+ return process.stdout.isTTY ? LoggerType_1.LoggerType.CLI : LoggerType_1.LoggerType.CONSOLE;
251
+ }
245
252
  getInquirer(type) {
246
253
  switch (type) {
247
254
  case InquirerType_1.InquirerType.CLI: return new Commons.CliInquirer();
@@ -249,7 +256,7 @@ class AbstractCommand {
249
256
  }
250
257
  }
251
258
  normalizeArgs(args = {}) {
252
- const defaultLogger = utils_1.GlobalContext.getInstance().getSettings().loggerType;
259
+ const defaultLogger = this.getDefaultLoggerType();
253
260
  const logOutputFolder = utils_1.GlobalContext.getInstance().getSettings().logOutputFolder;
254
261
  const normalized = {
255
262
  logger: defaultLogger,
@@ -434,6 +441,9 @@ class AbstractCommand {
434
441
  return value;
435
442
  }
436
443
  parseArrayArg(name) {
444
+ if (Array.isArray(this.args[name])) {
445
+ return this.args[name];
446
+ }
437
447
  if (this.args[name]) {
438
448
  try {
439
449
  return this.args[name].split(',').map(s => s.trim());
@@ -516,7 +526,7 @@ class AbstractCommand {
516
526
  }
517
527
  if (registryAlias.authData) {
518
528
  try {
519
- yield registry.authenticate(registryAlias.authData);
529
+ yield (0, registryAlias_1.authenticateRegistry)(registry, registryAlias.authData);
520
530
  }
521
531
  catch (e) {
522
532
  this.registryAuthFailed = e;
@@ -542,14 +552,34 @@ class AbstractCommand {
542
552
  });
543
553
  if (this.registerOpts.requiresConnection) {
544
554
  var system;
555
+ var systemAlias;
545
556
  if (this.args.alias) {
546
- system = systemAlias_1.SystemAlias.get(this.args.alias).getConnection();
557
+ systemAlias = systemAlias_1.SystemAlias.get(this.args.alias);
558
+ system = systemAlias.getConnection();
547
559
  }
548
560
  else {
549
561
  const connectArgs = this.getConnectArgs();
550
- system = (yield (0, prompts_1.connect)(connectArgs, !this.args.connectionType, this.registerOpts.addNoConnection)).connect.getSystemConnector();
562
+ const inquirer = Commons.Inquirer.inquirer;
563
+ if (this.args.prompts === false) {
564
+ Commons.Inquirer.inquirer = new Commons.NonInteractiveInquirer(inquirer, `Pass it with --connection-type and --connection-args (or TRM_CONNECTION_TYPE and TRM_CONNECTION_ARGS), or use a system alias (-a).`);
565
+ }
566
+ try {
567
+ system = (yield (0, prompts_1.connect)(connectArgs, !this.args.connectionType, this.registerOpts.addNoConnection)).connect.getSystemConnector();
568
+ }
569
+ finally {
570
+ Commons.Inquirer.inquirer = inquirer;
571
+ }
551
572
  }
552
573
  yield system.connect(false);
574
+ if (systemAlias) {
575
+ try {
576
+ systemAlias.saveChanges();
577
+ }
578
+ catch (e) {
579
+ Commons.Logger.warning(`Couldn't update system alias "${this.args.alias}" data.`);
580
+ Commons.Logger.error(e, true);
581
+ }
582
+ }
553
583
  Core.SystemConnector.systemConnector = system;
554
584
  yield Commons.Plugin.call("client", "onInitializeSystemConnector", Core.SystemConnector.systemConnector);
555
585
  if (this.registerOpts.requiresTrmDependencies) {
@@ -33,9 +33,10 @@ class Alias extends AbstractCommand_1.AbstractCommand {
33
33
  check(alias) {
34
34
  return __awaiter(this, void 0, void 0, function* () {
35
35
  trm_commons_1.Logger.loading(`Checking connection with alias "${alias.alias}"...`);
36
- const oSystemAlias = new systemAlias_1.SystemAlias(alias.type, alias.data);
36
+ const oSystemAlias = new systemAlias_1.SystemAlias(alias.type, alias.data, alias.alias);
37
37
  try {
38
38
  yield oSystemAlias.getConnection().connect(false);
39
+ oSystemAlias.saveChanges();
39
40
  trm_commons_1.Logger.success(`Connection to alias "${alias.alias}" OK.`);
40
41
  }
41
42
  catch (e) {
@@ -13,7 +13,6 @@ exports.Cg3z = void 0;
13
13
  const trm_commons_1 = require("trm-commons");
14
14
  const AbstractCommand_1 = require("../AbstractCommand");
15
15
  const trm_core_1 = require("trm-core");
16
- const utils_1 = require("../../utils");
17
16
  const promises_1 = require("fs/promises");
18
17
  const path_1 = require("path");
19
18
  const helpers_1 = require("../metadata/helpers");
@@ -33,14 +32,8 @@ class Cg3z extends AbstractCommand_1.AbstractCommand {
33
32
  trm_commons_1.Logger.loading(`Reading file "${this.args.filename}"...`);
34
33
  const binaries = yield (0, promises_1.readFile)(this.args.filename);
35
34
  const result = yield (0, trm_core_1.cg3z)({
36
- r3transOptions: {
37
- tempDirPath: (0, utils_1.getTempFolder)(),
38
- r3transDirPath: this.args.r3transPath,
39
- useDocker: utils_1.GlobalContext.getInstance().getSettings().r3transDocker,
40
- dockerOptions: {
41
- name: utils_1.GlobalContext.getInstance().getSettings().r3transDockerName
42
- }
43
- },
35
+ contextData: { noInquirer: !this.args.prompts },
36
+ uploadData: { overwrite: this.args.overwrite },
44
37
  binaries
45
38
  });
46
39
  trm_commons_1.Logger.success(`Uploaded ${trm_core_1.Transport.getTransportIcon()} ${result.trkorr}`);
@@ -63,10 +56,12 @@ Cg3z.metadata = {
63
56
  arguments: [
64
57
  (0, helpers_1.argument)(0, { name: "filename", label: "Transport archive", description: "Transport archive file name or path.", control: "file-picker", pickerType: "input" })
65
58
  ],
66
- options: [],
59
+ options: [
60
+ (0, helpers_1.option)("--overwrite", { name: "overwrite", label: "Overwrite transport", description: "Overwrite an existing transport without confirmation.", control: "checkbox" }),
61
+ (0, helpers_1.option)("--no-prompts", { name: "prompts", label: "Prompts", description: "Disable interactive prompts.", control: "checkbox", defaultValue: true, negated: true })
62
+ ],
67
63
  requirements: {
68
64
  requiresConnection: true,
69
- requiresTrmDependencies: true,
70
- requiresR3trans: true
65
+ requiresTrmDependencies: true
71
66
  }
72
67
  };
@@ -24,7 +24,7 @@ class Compare extends AbstractCommand_1.AbstractCommand {
24
24
  promptConnections() {
25
25
  return __awaiter(this, void 0, void 0, function* () {
26
26
  if (this.connections.length > 0) {
27
- trm_commons_1.Logger.info(`Compare systems: ${this.connections.map(o => o.getDest()).join(', ')}`);
27
+ trm_commons_1.Logger.info(`Compare systems: ${this.connections.map(o => o.connector.getDest()).join(', ')}`);
28
28
  }
29
29
  var askConnection = true;
30
30
  const inq1 = yield trm_commons_1.Inquirer.prompt([{
@@ -39,7 +39,8 @@ class Compare extends AbstractCommand_1.AbstractCommand {
39
39
  const connectArgs = yield (0, prompts_1.connect)({}, false, false);
40
40
  const systemConnector = connectArgs.connect.getSystemConnector();
41
41
  yield systemConnector.connect(false);
42
- this.connections.push(systemConnector);
42
+ yield systemConnector.closeConnection();
43
+ this.connections.push({ connector: systemConnector });
43
44
  return true;
44
45
  }
45
46
  else {
@@ -56,8 +57,7 @@ class Compare extends AbstractCommand_1.AbstractCommand {
56
57
  for (const sAlias of inputConnections) {
57
58
  if (typeof (sAlias) === 'string') {
58
59
  const oAlias = systemAlias_1.SystemAlias.get(sAlias);
59
- const oConnection = oAlias.getConnection();
60
- this.connections.push(oConnection);
60
+ this.connections.push({ connector: oAlias.getConnection(), alias: oAlias });
61
61
  }
62
62
  }
63
63
  }
@@ -67,7 +67,7 @@ class Compare extends AbstractCommand_1.AbstractCommand {
67
67
  keepPrompt = yield this.promptConnections();
68
68
  }
69
69
  }
70
- trm_commons_1.Logger.info(`Compare systems: ${this.connections.map(o => o.getDest()).join(', ')}`);
70
+ trm_commons_1.Logger.info(`Compare systems: ${this.connections.map(o => o.connector.getDest()).join(', ')}`);
71
71
  const tableHead = [`System`, `Installed`, `Version`, `Devclass`, `Import transport`];
72
72
  var tableData = [];
73
73
  trm_commons_1.Logger.loading(`Reading registry data...`);
@@ -77,21 +77,37 @@ class Compare extends AbstractCommand_1.AbstractCommand {
77
77
  }
78
78
  catch (e) { }
79
79
  trm_commons_1.Logger.loading(`Reading system data...`);
80
- for (const oConnection of this.connections) {
80
+ for (const { connector: oConnection, alias: oAlias } of this.connections) {
81
+ yield oConnection.connect(false);
82
+ if (oAlias) {
83
+ try {
84
+ oAlias.saveChanges();
85
+ }
86
+ catch (e) {
87
+ trm_commons_1.Logger.error(e, true);
88
+ }
89
+ }
81
90
  trm_core_1.SystemConnector.systemConnector = oConnection;
82
91
  const system = trm_core_1.SystemConnector.getDest() || '';
83
92
  var installed;
84
93
  var version;
85
94
  var devclass;
86
95
  var importTransport;
87
- const aSystemPackages = yield trm_core_1.SystemConnector.getInstalledPackages(true);
96
+ var aSystemPackages;
97
+ try {
98
+ aSystemPackages = yield trm_core_1.SystemConnector.getInstalledPackages(true);
99
+ }
100
+ finally {
101
+ yield oConnection.closeConnection();
102
+ trm_core_1.SystemConnector.systemConnector = undefined;
103
+ }
88
104
  const oSystemView = aSystemPackages.find(o => o.compareName(packageName) && o.compareRegistry(registry));
89
105
  if (oSystemView && oSystemView.manifest) {
90
106
  installed = 'Yes';
91
107
  version = oSystemView.manifest.get().version || 'Unknown';
92
108
  devclass = oSystemView.getDevclass() || 'Unknown';
93
- if (oSystemView.manifest.getLinkedTransport()) {
94
- importTransport = oSystemView.manifest.getLinkedTransport().trkorr;
109
+ if (oSystemView.getTransport()) {
110
+ importTransport = oSystemView.getTransport().trkorr;
95
111
  }
96
112
  else {
97
113
  importTransport = 'Unknown';
@@ -15,7 +15,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.Content = void 0;
16
16
  const trm_commons_1 = require("trm-commons");
17
17
  const AbstractCommand_1 = require("../AbstractCommand");
18
- const utils_1 = require("../../utils");
19
18
  const chalk_1 = __importDefault(require("chalk"));
20
19
  const helpers_1 = require("../metadata/helpers");
21
20
  class Content extends AbstractCommand_1.AbstractCommand {
@@ -29,49 +28,25 @@ class Content extends AbstractCommand_1.AbstractCommand {
29
28
  const data = yield registry.getPackage(this.args.package, this.args.version);
30
29
  const artifact = yield registry.downloadArtifact(this.args.package, this.args.version);
31
30
  trm_commons_1.Logger.loading(`Reading content...`);
32
- const packageContent = yield artifact.getContent({
33
- tempDirPath: (0, utils_1.getTempFolder)(),
34
- r3transDirPath: this.args.r3transPath,
35
- useDocker: utils_1.GlobalContext.getInstance().getSettings().r3transDocker,
36
- dockerOptions: {
37
- name: utils_1.GlobalContext.getInstance().getSettings().r3transDockerName
31
+ const packageTransports = yield artifact.getTransportBinaries();
32
+ let otherEntries = 0;
33
+ for (const transport of packageTransports) {
34
+ const type = transport.type || 'TADIR';
35
+ transports[type] = [...(transports[type] || []), transport.trkorr];
36
+ const entries = this.args.full ? transport.entries : { tadir: transport.entries.tadir };
37
+ if (!this.args.full) {
38
+ otherEntries += transport.entries.e071.length + transport.entries.tdevc.length + transport.entries.tdevct.length;
38
39
  }
39
- });
40
- if (this.args.tadirOnly) {
41
- transports.TADIR = packageContent.TADIR.trkorr;
42
- aNodes.push({
43
- tableName: 'TADIR',
44
- content: packageContent.TADIR.content.TADIR
45
- });
46
- Object.keys(packageContent).forEach(type => {
47
- if (type === 'TADIR') {
48
- return;
49
- }
50
- Object.keys(packageContent[type].content).forEach(tableName => {
51
- iOtherEntries += packageContent[type].content[tableName].length;
52
- });
53
- });
54
- }
55
- else {
56
- Object.keys(packageContent).forEach(type => {
57
- transports[type] = packageContent[type].trkorr;
58
- Object.keys(packageContent[type].content).forEach(tableName => {
59
- var nodeIndex = aNodes.findIndex(o => o.tableName === tableName);
60
- if (nodeIndex < 0) {
61
- nodeIndex = (aNodes.push({
62
- tableName,
63
- content: []
64
- })) - 1;
65
- }
66
- aNodes[nodeIndex].content = aNodes[nodeIndex].content.concat(packageContent[type].content[tableName].map(o => {
67
- o.__isDevc = type === 'DEVC';
68
- o.__isLang = type === 'LANG';
69
- o.__isCust = type === 'CUST';
70
- return o;
71
- }));
40
+ for (const [tableName, records] of Object.entries(entries)) {
41
+ if (!records.length)
42
+ continue;
43
+ aNodes.push({
44
+ tableName: `${tableName.toUpperCase()} (${type} ${transport.trkorr})`,
45
+ content: records.map(record => (Object.assign({}, record)))
72
46
  });
73
- });
47
+ }
74
48
  }
49
+ iOtherEntries = otherEntries;
75
50
  var tree = {
76
51
  text: `${chalk_1.default.bold(this.args.package)} v${data.manifest.version} content`,
77
52
  children: []
@@ -83,101 +58,16 @@ class Content extends AbstractCommand_1.AbstractCommand {
83
58
  children: []
84
59
  };
85
60
  node.content.forEach(record => {
86
- var sRecord = [];
87
- Object.keys(record).filter(k => !k.startsWith('__')).forEach(field => {
88
- var fieldValue = record[field];
89
- if (field && fieldValue) {
90
- if (node.tableName === 'TADIR') {
91
- if (field === 'SRCSYSTEM') {
92
- fieldValue = chalk_1.default.strikethrough(fieldValue);
93
- }
94
- else if (field === 'DEVCLASS') {
95
- fieldValue = chalk_1.default.italic(fieldValue);
96
- }
97
- }
98
- sRecord.push(`${chalk_1.default.bold(field)}: ${fieldValue}`);
99
- }
100
- });
101
- if (sRecord.length > 0) {
102
- if (record.__isDevc) {
103
- tableNode.children.push({
104
- text: chalk_1.default.bgGrey(sRecord.join(', ')),
105
- children: []
106
- });
107
- }
108
- else if (record.__isLang) {
109
- tableNode.children.push({
110
- text: chalk_1.default.bgGreen(sRecord.join(', ')),
111
- children: []
112
- });
113
- }
114
- else if (record.__isCust) {
115
- tableNode.children.push({
116
- text: chalk_1.default.bgYellow(sRecord.join(', ')),
117
- children: []
118
- });
119
- }
120
- else {
121
- tableNode.children.push({
122
- text: sRecord.join(', '),
123
- children: []
124
- });
125
- }
126
- }
61
+ const fields = Object.entries(record)
62
+ .filter(([_, value]) => value !== undefined && value !== null && value !== '')
63
+ .map(([field, value]) => `${chalk_1.default.bold(field)}: ${value}`);
64
+ tableNode.children.push({ text: fields.join(', '), children: [] });
127
65
  });
128
66
  tree.children.push(tableNode);
129
67
  }
130
68
  });
131
69
  trm_commons_1.Logger.tree(tree);
132
- var header = ['', 'Namespace', 'ABAP Package', 'TRM Transport', 'Customizing', 'Translations'];
133
- var row1 = [''];
134
- var row2 = ['Highlight color'];
135
- if (data.manifest.namespace) {
136
- row1.push(`${data.manifest.namespace.ns || 'Yes'} ${data.manifest.namespace.replicense}`);
137
- row2.push(``);
138
- }
139
- else {
140
- row1.push(`No`);
141
- row2.push(``);
142
- }
143
- if (Object.keys(packageContent).includes('DEVC')) {
144
- row1.push(packageContent['DEVC'].trkorr);
145
- row2.push(`${chalk_1.default.bgGrey('Grey')}`);
146
- }
147
- else {
148
- row1.push(`No`);
149
- row2.push(``);
150
- }
151
- if (Object.keys(packageContent).includes('TADIR')) {
152
- row1.push(packageContent['TADIR'].trkorr);
153
- row2.push(``);
154
- }
155
- else {
156
- row1.push(`No`);
157
- row2.push(``);
158
- }
159
- if (Object.keys(packageContent).includes('CUST')) {
160
- row1.push(packageContent['CUST'].trkorr);
161
- row2.push(`${chalk_1.default.bgYellow('Yellow')}`);
162
- }
163
- else {
164
- row1.push(`No`);
165
- row2.push(``);
166
- }
167
- if (Object.keys(packageContent).includes('LANG')) {
168
- row1.push(packageContent['LANG'].trkorr);
169
- row2.push(`${chalk_1.default.bgGreen('Green')}`);
170
- }
171
- else {
172
- row1.push(`No`);
173
- row2.push(``);
174
- }
175
- if (row2.filter(s => s.length > 0).length > 0) {
176
- trm_commons_1.Logger.table(header, [row1, row2]);
177
- }
178
- else {
179
- trm_commons_1.Logger.table(header, [row1]);
180
- }
70
+ trm_commons_1.Logger.table(['Type', 'Transports'], Object.entries(transports).map(([type, requests]) => [type, requests.join(', ')]));
181
71
  if (iOtherEntries > 0) {
182
72
  trm_commons_1.Logger.warning(`There are ${iOtherEntries} other entries to show. Run with option "--full" in order to see them.`);
183
73
  }
@@ -202,7 +92,6 @@ Content.metadata = {
202
92
  (0, helpers_1.option)("--full", { name: "full", label: "Full content", description: "Show all transport entries in the package.", control: "checkbox", defaultValue: false })
203
93
  ],
204
94
  requirements: {
205
- requiresRegistry: true,
206
- requiresR3trans: true
95
+ requiresRegistry: true
207
96
  }
208
97
  };
@@ -12,5 +12,6 @@ export declare class Install extends AbstractCommand {
12
12
  private formatPermsHelp;
13
13
  protected onArgs(): void;
14
14
  protected onTrmDepVersionNotSatisfied(trmPackage: TrmPackage): boolean;
15
+ private askIfNotPassed;
15
16
  protected handler(): Promise<void>;
16
17
  }
@@ -107,6 +107,13 @@ class Install extends AbstractCommand_1.AbstractCommand {
107
107
  onTrmDepVersionNotSatisfied(trmPackage) {
108
108
  return !trmPackage.compareName(this.args.package);
109
109
  }
110
+ askIfNotPassed(name) {
111
+ if (!this.args.prompts || !this.command) {
112
+ return false;
113
+ }
114
+ const source = this.command.getOptionValueSource(name);
115
+ return source === undefined || source === 'default';
116
+ }
110
117
  handler() {
111
118
  return __awaiter(this, void 0, void 0, function* () {
112
119
  if (this.name === 'update' && !this.args.package) {
@@ -117,7 +124,7 @@ class Install extends AbstractCommand_1.AbstractCommand {
117
124
  if (this.name === 'import') {
118
125
  const extension = (0, node_path_1.extname)(this.args.filename);
119
126
  if (extension !== '.trm') {
120
- this.args.filename = this.args.filename + 'trm';
127
+ this.args.filename = this.args.filename + '.trm';
121
128
  }
122
129
  this.validateInputFileArg(this.args.filename);
123
130
  registry = new trm_core_1.FileSystem(this.args.filename);
@@ -128,46 +135,39 @@ class Install extends AbstractCommand_1.AbstractCommand {
128
135
  const packages = yield this.getSystemPackages();
129
136
  const result = yield (0, trm_core_1.install)({
130
137
  contextData: {
131
- r3transOptions: {
132
- tempDirPath: (0, utils_1.getTempFolder)(),
133
- r3transDirPath: this.args.r3transPath,
134
- useDocker: utils_1.GlobalContext.getInstance().getSettings().r3transDocker,
135
- dockerOptions: {
136
- name: utils_1.GlobalContext.getInstance().getSettings().r3transDockerName
137
- }
138
- },
138
+ logTemporaryFolder: (0, utils_1.getTempFolder)(),
139
139
  noInquirer: !this.args.prompts,
140
- systemPackages: packages,
141
- noR3transInfo: false
140
+ systemPackages: packages
142
141
  },
143
142
  packageData: {
144
143
  registry,
145
144
  name: this.args.package,
146
145
  version: this.args.version,
147
- overwrite: this.name === 'update'
146
+ overwrite: this.name === 'update' || this.args.overwrite,
147
+ integrity: this.args.integrity
148
148
  },
149
149
  installData: {
150
150
  checks: {
151
151
  noDependencies: !this.args.deps,
152
- noObjectTypes: !this.args.objType,
152
+ noEngines: !this.args.engines,
153
+ allowDowngrade: this.args.allowDowngrade,
153
154
  noSapEntries: !this.args.sapEntries,
154
155
  noExistingObjects: !this.args.objCheck,
155
156
  lockfile: this.args.lockFile ? lockfile_1.Lockfile.fromJson(this.parseJsonArg('lockFile')) : undefined
156
157
  },
157
158
  import: {
158
- noLang: !this.args.langTr,
159
- noCust: !this.args.custTr,
160
- replaceExistingTransports: false
159
+ noLang: this.askIfNotPassed('langTr') ? undefined : !this.args.langTr,
160
+ noCust: this.askIfNotPassed('custTr') ? undefined : !this.args.custTr
161
161
  },
162
162
  installDevclass: {
163
- keepOriginal: false,
163
+ keepOriginal: this.args.keepOriginal,
164
164
  transportLayer: this.args.transportLayer,
165
165
  replacements: this.parseJsonArg('packageReplacements'),
166
- skipNamespace: !this.args.namespace
166
+ skipNamespace: this.askIfNotPassed('namespace') ? undefined : !this.args.namespace
167
167
  },
168
- installTransport: {
169
- create: this.args.installTr,
170
- targetSystem: this.args.installTrTarget
168
+ skipPostActivities: this.args.skipPostActivities,
169
+ landscapeTransport: {
170
+ targetSystem: this.args.landscapeTrTarget
171
171
  }
172
172
  }
173
173
  });
@@ -180,15 +180,22 @@ exports.Install = Install;
180
180
  Install.installOptions = [
181
181
  (0, helpers_1.option)("-T, --transport-layer <transport layer>", { name: "transportLayer", label: "Transport layer", description: "Transport layer for imported package objects. Defaults to the system transport layer.", control: "transport-layer-picker" }),
182
182
  (0, helpers_1.option)("--no-deps", { name: "deps", label: "Ignore dependencies", description: "Skip dependency installation.", control: "checkbox", defaultValue: true, negated: true }),
183
- (0, helpers_1.option)("--no-obj-type", { name: "objType", label: "Avoid object type checks", description: "Skip object type checks before import.", control: "checkbox", defaultValue: true, negated: true }),
184
183
  (0, helpers_1.option)("--no-obj-check", { name: "objCheck", label: "Avoid object existence checks", description: "Skip object existence checks before import.", control: "checkbox", defaultValue: true, negated: true }),
185
184
  (0, helpers_1.option)("--no-sap-entries", { name: "sapEntries", label: "Avoid SAP entries", description: "Skip SAP entry checks before import.", control: "checkbox", defaultValue: true, negated: true }),
186
185
  (0, helpers_1.option)("--no-lang-tr", { name: "langTr", label: "No language transport", description: "Skip language transport import.", control: "checkbox", defaultValue: true, negated: true }),
187
186
  (0, helpers_1.option)("--no-cust-tr", { name: "custTr", label: "No customizing transports", description: "Skip customizing transports import.", control: "checkbox", defaultValue: true, negated: true }),
188
- (0, helpers_1.option)("--no-install-tr", { name: "installTr", label: "No install transport generation", description: "Do not create an install transport.", control: "checkbox", defaultValue: true, negated: true }),
187
+ (0, helpers_1.option)("--lang-tr", { name: "langTr", label: "Language transport", description: "Import the language transport without asking.", control: "checkbox", guiRelevant: false }),
188
+ (0, helpers_1.option)("--cust-tr", { name: "custTr", label: "Customizing transports", description: "Import all customizing transports without asking.", control: "checkbox", guiRelevant: false }),
189
+ (0, helpers_1.option)("--no-engines", { name: "engines", label: "Check engines", description: "Skip manifest engine validation.", control: "checkbox", defaultValue: true, negated: true }),
190
+ (0, helpers_1.option)("--allow-downgrade", { name: "allowDowngrade", label: "Allow downgrade", description: "Allow dependency downgrades without confirmation.", control: "checkbox" }),
191
+ (0, helpers_1.option)("--keep-original", { name: "keepOriginal", label: "Keep original packages", description: "Preserve publisher SAP package names.", control: "checkbox" }),
192
+ (0, helpers_1.option)("--skip-post-activities", { name: "skipPostActivities", label: "Skip post activities", description: "Skip all manifest post-install activities.", control: "checkbox" }),
193
+ (0, helpers_1.option)("--overwrite", { name: "overwrite", label: "Overwrite", description: "Allow reinstalling the same release.", control: "checkbox" }),
194
+ (0, helpers_1.option)("--integrity <integrity>", { name: "integrity", label: "Integrity", description: "Expected release SHA-512 integrity in base64." }),
189
195
  (0, helpers_1.option)("--namespace", { name: "namespace", label: "Customer namespace", description: "Import the customer namespace.", control: "checkbox" }),
196
+ (0, helpers_1.option)("--no-namespace", { name: "namespace", label: "No customer namespace", description: "Don't import the customer namespace, without asking.", control: "checkbox", negated: true, guiRelevant: false }),
190
197
  (0, helpers_1.option)("--package-replacements <replacements>", { name: "packageReplacements", label: "Package replacements", description: "SAP package replacements as JSON, or a path to a JSON file.", control: "textarea" }),
191
- (0, helpers_1.option)("--install-tr-target <target>", { name: "installTrTarget", label: "Install transport target", description: "Target system for the install transport.", control: "transport-target-picker" }),
198
+ (0, helpers_1.option)("--landscape-tr-target <target>", { name: "landscapeTrTarget", label: "Landscape transport target", description: "TMS target for the generated landscape transport.", control: "transport-target-picker" }),
192
199
  (0, helpers_1.option)("--no-prompts", { name: "prompts", label: "Prompts", description: "Disable prompts and use automatic decisions.", control: "checkbox", defaultValue: true, guiRelevant: false, negated: true })
193
200
  ];
194
201
  Install.metadata = [
@@ -209,7 +216,6 @@ Install.metadata = [
209
216
  requirements: {
210
217
  requiresConnection: true,
211
218
  requiresTrmDependencies: true,
212
- requiresR3trans: true,
213
219
  requiresRegistry: true
214
220
  }
215
221
  },
@@ -221,19 +227,19 @@ Install.metadata = [
221
227
  group: "package",
222
228
  groupPriority: 5,
223
229
  description: "Install a package from the registry using a lockfile.",
230
+ longDescription: "The lockfile pins the package release, its integrity and its dependencies. When no version is provided, the version recorded in the lockfile is installed; a version that doesn't match it aborts the install.",
224
231
  icon: "PackageCheck",
225
232
  arguments: [
226
- (0, helpers_1.argument)(0, { name: "package", label: "Package", description: "Package name." }),
227
- (0, helpers_1.argument)(1, { name: "version", label: "Version", description: "Release version or distribution tag.", required: false, defaultValue: "latest" })
233
+ (0, helpers_1.argument)(0, { name: "package", label: "Package", description: "Package name. Must match the package of the lockfile." }),
234
+ (0, helpers_1.argument)(1, { name: "version", label: "Version", description: "Release version or distribution tag. Defaults to the lockfile version.", required: false })
228
235
  ],
229
236
  options: [
230
- (0, helpers_1.option)("-L, --lock-file", { name: "lockFile", label: "Lockfile", description: "Lockfile to use for installation.", control: "file-picker", pickerType: "input", defaultValue: "trm-lock.json" }),
237
+ (0, helpers_1.option)("-L, --lock-file <path>", { name: "lockFile", label: "Lockfile", description: "Lockfile to use for installation.", control: "file-picker", pickerType: "input", defaultValue: "trm-lock.json" }),
231
238
  ...Install.installOptions
232
239
  ],
233
240
  requirements: {
234
241
  requiresConnection: true,
235
242
  requiresTrmDependencies: true,
236
- requiresR3trans: true,
237
243
  requiresRegistry: true
238
244
  }
239
245
  },
@@ -254,7 +260,6 @@ Install.metadata = [
254
260
  requirements: {
255
261
  requiresConnection: true,
256
262
  requiresTrmDependencies: true,
257
- requiresR3trans: true,
258
263
  requiresRegistry: true
259
264
  }
260
265
  },
@@ -273,7 +278,6 @@ Install.metadata = [
273
278
  requirements: {
274
279
  requiresConnection: true,
275
280
  requiresTrmDependencies: true,
276
- requiresR3trans: true
277
281
  }
278
282
  }
279
283
  ];
@@ -37,7 +37,7 @@ class List extends AbstractCommand_1.AbstractCommand {
37
37
  var version = oPackage.manifest.get().version || '';
38
38
  const registry = oPackage.registry.getRegistryType() === trm_core_1.RegistryType.LOCAL ? chalk_1.default.bold(oPackage.registry.name) : oPackage.registry.name;
39
39
  const devclass = oPackage.getDevclass() || '';
40
- const linkedTransport = oPackage.manifest.getLinkedTransport();
40
+ const linkedTransport = oPackage.getTransport();
41
41
  const transport = linkedTransport ? linkedTransport.trkorr : '';
42
42
  var dirty = '';
43
43
  if (oPackage.isDirty()) {
@@ -128,7 +128,7 @@ List.metadata = {
128
128
  arguments: [],
129
129
  options: [
130
130
  (0, helpers_1.option)("-L, --locals", { name: "locals", label: "Include local packages", description: "Include imported and exported local packages.", control: "checkbox", defaultValue: false }),
131
- (0, helpers_1.option)("-o, --output-type", { name: "outputType", label: "Output format", description: "Output format: TREE or TABLE.", control: "select", defaultValue: "TREE" })
131
+ (0, helpers_1.option)("-o, --output-type <type>", { name: "outputType", label: "Output format", description: "Output format: TREE or TABLE.", control: "select", defaultValue: "TREE" })
132
132
  ],
133
133
  requirements: {
134
134
  requiresConnection: true
@@ -18,6 +18,9 @@ const helpers_1 = require("../metadata/helpers");
18
18
  class Login extends AbstractCommand_1.AbstractCommand {
19
19
  handler() {
20
20
  return __awaiter(this, void 0, void 0, function* () {
21
+ if ((0, registryAlias_1.isGithubOidcAuthData)(this.parseJsonArg('registryAuth'))) {
22
+ throw new Error(`GitHub OIDC tokens are short-lived and can't be saved with login: pass -A '{"oidc":"github"}' on each command instead.`);
23
+ }
21
24
  const registry = this.getRegistry();
22
25
  var authData;
23
26
  if (this.parseJsonArg('registryAuth')) {
@@ -34,7 +34,7 @@ class Publish extends AbstractCommand_1.AbstractCommand {
34
34
  return __awaiter(this, void 0, void 0, function* () {
35
35
  var registry;
36
36
  if (this.name === 'pack') {
37
- if (!this.args.prompts) {
37
+ if (this.args.prompts) {
38
38
  const pack = yield trm_commons_1.Inquirer.prompt([{
39
39
  name: 'package',
40
40
  type: 'input',
@@ -94,17 +94,20 @@ class Publish extends AbstractCommand_1.AbstractCommand {
94
94
  website: this.args.website,
95
95
  dependencies: this.parseJsonArg('dependencies'),
96
96
  sapEntries: this.parseJsonArg('sapEntries'),
97
- postActivities: this.parseJsonArg('postActivities')
97
+ postActivities: this.parseJsonArg('postActivities'),
98
+ engines: this.parseJsonArg('engines')
98
99
  },
99
100
  },
100
101
  publishData: {
101
- private: this.args.private,
102
+ private: this.args.public ? false : this.args.private,
102
103
  keepLatestReleaseManifestValues: this.args.keepManifest,
103
104
  noLanguageTransport: !this.args.langTr,
104
105
  noDependenciesDetection: !this.args.autoDeps,
105
- skipCustomizingTransports: !this.args.custTr,
106
- customizingTransports: this.args.cust,
107
- readme: this.parseTextArg('readme')
106
+ noCustomizingTransports: !this.args.custTr,
107
+ customizingTransports: this.parseArrayArg('cust'),
108
+ dropCustomizingTransports: this.parseArrayArg('dropCust'),
109
+ readme: this.parseTextArg('readme'),
110
+ changelog: this.parseTextArg('changelog')
108
111
  },
109
112
  systemData: {
110
113
  transportTarget: this.args.target
@@ -122,6 +125,8 @@ Publish.releaseOptions = [
122
125
  (0, helpers_1.option)("--no-cust-tr", { name: "custTr", label: "No customizing transport", description: "Skip customizing transports generation.", control: "checkbox", defaultValue: true, negated: true }),
123
126
  (0, helpers_1.option)("--cust <customizing>", { name: "cust", label: "Customizing transports", description: "Customizing transport requests, separated by commas.", multiple: true }),
124
127
  (0, helpers_1.option)("--no-auto-deps", { name: "autoDeps", label: "No automatic dependencies", description: "Skip automatic dependency detection.", control: "checkbox", defaultValue: true, negated: true }),
128
+ (0, helpers_1.option)("--engines <engines>", { name: "engines", label: "Engines", description: "Manifest engine requirements as JSON, or a JSON file path.", control: "textarea" }),
129
+ (0, helpers_1.option)("--changelog <changelog>", { name: "changelog", label: "Changelog", description: "Release changelog as Markdown, or a Markdown file path.", control: "textarea" }),
125
130
  (0, helpers_1.option)("--authors <authors>", { name: "authors", label: "Authors", description: "Release authors, separated by commas.", multiple: true }),
126
131
  (0, helpers_1.option)("--backwards-compatible", { name: "backwardsCompatible", label: "Backwards compatible", description: "Mark the release as backwards compatible.", control: "checkbox" }),
127
132
  (0, helpers_1.option)("--description <description>", { name: "description", label: "Description", description: "Release description." }),
@@ -153,8 +158,10 @@ Publish.metadata = [
153
158
  (0, helpers_1.option)("--pre-release-identifier <identifier>", { name: "preReleaseIdentifier", label: "Pre-release identifier", description: "Identifier to append to a pre-release version." }),
154
159
  (0, helpers_1.option)("--tag <tag>", { name: "tag", label: "Tags", description: "Release distribution tags, separated by commas.", multiple: true }),
155
160
  (0, helpers_1.option)("--private", { name: "private", label: "Private", description: "Mark the package as private. Registry visibility may not be changeable after the first publish.", control: "checkbox" }),
161
+ (0, helpers_1.option)("--public", { name: "public", label: "Public", description: "Publish with public visibility, including when prompts are disabled.", control: "checkbox" }),
156
162
  (0, helpers_1.option)("--readme <readme>", { name: "readme", label: "Readme", description: "Release readme as Markdown, or a path to a Markdown file.", control: "textarea" }),
157
163
  (0, helpers_1.option)("--no-keep-manifest", { name: "keepManifest", label: "Reuse manifest", description: "Do not reuse values from the previous release manifest.", control: "checkbox", defaultValue: true, negated: true }),
164
+ (0, helpers_1.option)("--drop-cust <customizing>", { name: "dropCust", label: "Drop carried-over customizing", description: "Customizing transports of the previous release not to carry over, separated by commas, or \"all\".", multiple: true }),
158
165
  ...Publish.releaseOptions
159
166
  ],
160
167
  requirements: {
@@ -0,0 +1,6 @@
1
+ import { AbstractCommand } from "../AbstractCommand";
2
+ import { CommandMetadata } from "../metadata/CommandMetadata";
3
+ export declare class Uninstall extends AbstractCommand {
4
+ static readonly metadata: CommandMetadata;
5
+ protected handler(): Promise<void>;
6
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Uninstall = void 0;
13
+ const trm_commons_1 = require("trm-commons");
14
+ const trm_core_1 = require("trm-core");
15
+ const AbstractCommand_1 = require("../AbstractCommand");
16
+ const helpers_1 = require("../metadata/helpers");
17
+ class Uninstall extends AbstractCommand_1.AbstractCommand {
18
+ handler() {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const result = yield (0, trm_core_1.uninstall)({
21
+ contextData: {
22
+ systemPackages: yield this.getSystemPackages(),
23
+ noInquirer: !this.args.prompts
24
+ },
25
+ packageData: { name: this.args.package, registry: this.getRegistry() },
26
+ uninstallData: {
27
+ checks: { noDependants: !this.args.dependants, ignoreDirty: this.args.ignoreDirty },
28
+ landscapeTransport: { targetSystem: this.args.landscapeTrTarget }
29
+ }
30
+ });
31
+ trm_commons_1.Logger.success(`${result.manifest.name} v${result.manifest.version} uninstalled`);
32
+ });
33
+ }
34
+ }
35
+ exports.Uninstall = Uninstall;
36
+ Uninstall.metadata = {
37
+ id: "uninstall",
38
+ command: "uninstall",
39
+ title: "Uninstall package",
40
+ group: "package",
41
+ description: "Uninstall a package and nested packages from the connected system.",
42
+ icon: "PackageMinus",
43
+ arguments: [(0, helpers_1.argument)(0, { name: "package", label: "Package", description: "Installed package name." })],
44
+ options: [
45
+ (0, helpers_1.option)("--no-dependants", { name: "dependants", label: "Check dependants", description: "Skip checking installed packages that depend on this package.", control: "checkbox", defaultValue: true, negated: true }),
46
+ (0, helpers_1.option)("--ignore-dirty", { name: "ignoreDirty", label: "Ignore dirty changes", description: "Uninstall despite local changes without confirmation.", control: "checkbox" }),
47
+ (0, helpers_1.option)("--landscape-tr-target <target>", { name: "landscapeTrTarget", label: "Landscape transport target", description: "TMS target to receive the deletion transport.", control: "transport-target-picker" }),
48
+ (0, helpers_1.option)("--no-prompts", { name: "prompts", label: "Prompts", description: "Disable interactive prompts.", control: "checkbox", defaultValue: true, negated: true })
49
+ ],
50
+ requirements: {
51
+ requiresConnection: true,
52
+ requiresTrmDependencies: true,
53
+ requiresRegistry: true
54
+ }
55
+ };
@@ -184,7 +184,7 @@ class View extends AbstractCommand_1.AbstractCommand {
184
184
  }
185
185
  var transport;
186
186
  try {
187
- transport = oSystemView.manifest.getLinkedTransport().trkorr;
187
+ transport = oSystemView.getTransport().trkorr;
188
188
  }
189
189
  catch (e) { }
190
190
  dependencies = oSystemManifest.dependencies || [];
@@ -11,6 +11,7 @@ import { DistTag } from "./DistTag";
11
11
  import { Lock } from "./Lock";
12
12
  import { Unpublish } from "./Unpublish";
13
13
  import { Deprecate } from "./Deprecate";
14
+ import { Uninstall } from "./Uninstall";
14
15
  import { Install } from "./Install";
15
16
  import { List } from "./List";
16
17
  import { Content } from "./Content";
@@ -36,6 +37,7 @@ export * from "./Lock";
36
37
  export * from "./Unpublish";
37
38
  export * from "./Deprecate";
38
39
  export * from "./Install";
40
+ export * from "./Uninstall";
39
41
  export * from "./List";
40
42
  export * from "./Content";
41
43
  export * from "./View";
@@ -47,6 +49,6 @@ export * from "./Cg3y";
47
49
  export * from "./Cg3z";
48
50
  export * from "./Settings";
49
51
  export * from "./ClearCache";
50
- export declare const commands: (typeof Ping | typeof Info | typeof Registry | typeof Login | typeof WhoAmI | typeof Logout | typeof Alias | typeof Publish | typeof DistTag | typeof Lock | typeof Unpublish | typeof Deprecate | typeof Install | typeof List | typeof Content | typeof View | typeof Compare | typeof Dirty | typeof FindDependencies | typeof Cg3y | typeof Cg3z | typeof Settings | typeof ClearCache | typeof Changelog)[];
52
+ export declare const commands: (typeof Ping | typeof Info | typeof Registry | typeof Login | typeof WhoAmI | typeof Logout | typeof Alias | typeof Publish | typeof DistTag | typeof Lock | typeof Unpublish | typeof Deprecate | typeof Uninstall | typeof Install | typeof List | typeof Content | typeof View | typeof Compare | typeof Dirty | typeof FindDependencies | typeof Cg3y | typeof Cg3z | typeof Settings | typeof ClearCache | typeof Changelog)[];
51
53
  export declare function getCommand(id: string): CommandClass | undefined;
52
54
  export declare function getCommandMetadata(id: string): import("../metadata/CommandMetadata").CommandMetadata;
@@ -29,6 +29,7 @@ const DistTag_1 = require("./DistTag");
29
29
  const Lock_1 = require("./Lock");
30
30
  const Unpublish_1 = require("./Unpublish");
31
31
  const Deprecate_1 = require("./Deprecate");
32
+ const Uninstall_1 = require("./Uninstall");
32
33
  const Install_1 = require("./Install");
33
34
  const List_1 = require("./List");
34
35
  const Content_1 = require("./Content");
@@ -54,6 +55,7 @@ __exportStar(require("./Lock"), exports);
54
55
  __exportStar(require("./Unpublish"), exports);
55
56
  __exportStar(require("./Deprecate"), exports);
56
57
  __exportStar(require("./Install"), exports);
58
+ __exportStar(require("./Uninstall"), exports);
57
59
  __exportStar(require("./List"), exports);
58
60
  __exportStar(require("./Content"), exports);
59
61
  __exportStar(require("./View"), exports);
@@ -79,6 +81,7 @@ exports.commands = [
79
81
  Unpublish_1.Unpublish,
80
82
  Deprecate_1.Deprecate,
81
83
  Install_1.Install,
84
+ Uninstall_1.Uninstall,
82
85
  List_1.List,
83
86
  Content_1.Content,
84
87
  View_1.View,
@@ -0,0 +1,18 @@
1
+ import { AbstractRegistry } from "trm-core";
2
+ export declare const GITHUB_OIDC_PUBLIC_AUDIENCE = "https://trmregistry.com";
3
+ export type GithubOidcAuthData = {
4
+ oidc: "github";
5
+ audience?: string;
6
+ };
7
+ export type GithubOidcTokenFetcher = (requestUrl: string, requestToken: string) => Promise<string>;
8
+ export declare function isGithubOidcAuthData(authData: any): authData is GithubOidcAuthData;
9
+ export declare function getGithubOidcAudience(registry: AbstractRegistry, authData: GithubOidcAuthData): string;
10
+ export declare class GithubOidcTokenProvider {
11
+ readonly audience: string;
12
+ private _fetcher;
13
+ private _token;
14
+ private _expiry;
15
+ constructor(audience: string, _fetcher?: GithubOidcTokenFetcher);
16
+ getToken(): Promise<string>;
17
+ }
18
+ export declare function authenticateRegistry(registry: AbstractRegistry, authData: any, fetcher?: GithubOidcTokenFetcher): Promise<void>;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.GithubOidcTokenProvider = exports.GITHUB_OIDC_PUBLIC_AUDIENCE = void 0;
16
+ exports.isGithubOidcAuthData = isGithubOidcAuthData;
17
+ exports.getGithubOidcAudience = getGithubOidcAudience;
18
+ exports.authenticateRegistry = authenticateRegistry;
19
+ const axios_1 = __importDefault(require("axios"));
20
+ const trm_core_1 = require("trm-core");
21
+ const trm_commons_1 = require("trm-commons");
22
+ exports.GITHUB_OIDC_PUBLIC_AUDIENCE = "https://trmregistry.com";
23
+ const REFRESH_MARGIN_SECONDS = 60;
24
+ function isGithubOidcAuthData(authData) {
25
+ return !!authData && typeof authData === "object" && typeof authData.oidc === "string" && authData.oidc.trim().toLowerCase() === "github";
26
+ }
27
+ function getGithubOidcAudience(registry, authData) {
28
+ if (authData.audience) {
29
+ return authData.audience;
30
+ }
31
+ if (registry.getRegistryType() === trm_core_1.RegistryType.PUBLIC) {
32
+ return exports.GITHUB_OIDC_PUBLIC_AUDIENCE;
33
+ }
34
+ return new URL(registry.endpoint).origin;
35
+ }
36
+ function getJwtExpiry(token) {
37
+ try {
38
+ const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString("utf8"));
39
+ return typeof payload.exp === "number" ? payload.exp : undefined;
40
+ }
41
+ catch (_a) {
42
+ return undefined;
43
+ }
44
+ }
45
+ const defaultFetcher = (requestUrl, requestToken) => __awaiter(void 0, void 0, void 0, function* () {
46
+ var _a;
47
+ const response = yield axios_1.default.get(requestUrl, {
48
+ headers: { Authorization: `Bearer ${requestToken}` }
49
+ });
50
+ return (_a = response.data) === null || _a === void 0 ? void 0 : _a.value;
51
+ });
52
+ class GithubOidcTokenProvider {
53
+ constructor(audience, _fetcher = defaultFetcher) {
54
+ this.audience = audience;
55
+ this._fetcher = _fetcher;
56
+ }
57
+ getToken() {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ const now = Math.floor(Date.now() / 1000);
60
+ if (this._token && (!this._expiry || this._expiry - REFRESH_MARGIN_SECONDS > now)) {
61
+ return this._token;
62
+ }
63
+ const requestUrl = process.env.ACTIONS_ID_TOKEN_REQUEST_URL;
64
+ const requestToken = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN;
65
+ if (!requestUrl || !requestToken) {
66
+ throw new Error(`GitHub Actions OIDC token is not available. Run the command in a GitHub Actions job with "permissions: id-token: write".`);
67
+ }
68
+ const url = new URL(requestUrl);
69
+ url.searchParams.set("audience", this.audience);
70
+ trm_commons_1.Logger.log(`Requesting GitHub Actions OIDC token for audience ${this.audience}`, true);
71
+ var token;
72
+ try {
73
+ token = yield this._fetcher(url.toString(), requestToken);
74
+ }
75
+ catch (e) {
76
+ throw new Error(`Couldn't get a GitHub Actions OIDC token: ${(e === null || e === void 0 ? void 0 : e.message) || e}`);
77
+ }
78
+ if (!token || typeof token !== "string") {
79
+ throw new Error(`Couldn't get a GitHub Actions OIDC token: empty response.`);
80
+ }
81
+ this._token = token;
82
+ this._expiry = getJwtExpiry(token);
83
+ return token;
84
+ });
85
+ }
86
+ }
87
+ exports.GithubOidcTokenProvider = GithubOidcTokenProvider;
88
+ function authenticateRegistry(registry, authData, fetcher) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ var _a;
91
+ if (!isGithubOidcAuthData(authData)) {
92
+ yield registry.authenticate(authData);
93
+ return;
94
+ }
95
+ const provider = new GithubOidcTokenProvider(getGithubOidcAudience(registry, authData), fetcher);
96
+ yield registry.authenticate({ token: yield provider.getToken() });
97
+ const axiosInstance = registry._axiosInstance;
98
+ if ((_a = axiosInstance === null || axiosInstance === void 0 ? void 0 : axiosInstance.interceptors) === null || _a === void 0 ? void 0 : _a.request) {
99
+ axiosInstance.interceptors.request.use((config) => __awaiter(this, void 0, void 0, function* () {
100
+ var _a;
101
+ if (((_a = config.headers) === null || _a === void 0 ? void 0 : _a.getAuthorization) && config.headers.getAuthorization()) {
102
+ config.headers.setAuthorization(`Bearer ${yield provider.getToken()}`);
103
+ }
104
+ return config;
105
+ }));
106
+ }
107
+ else {
108
+ trm_commons_1.Logger.warning(`Registry "${registry.name}" doesn't support GitHub OIDC token refresh: long runs may fail when the token expires.`);
109
+ }
110
+ });
111
+ }
@@ -1,2 +1,3 @@
1
1
  export * from "./RegistryAlias";
2
2
  export * from "./RegistryAliasData";
3
+ export * from "./githubOidc";
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./RegistryAlias"), exports);
18
18
  __exportStar(require("./RegistryAliasData"), exports);
19
+ __exportStar(require("./githubOidc"), exports);
@@ -4,13 +4,17 @@ import { IConnect } from "trm-commons";
4
4
  export declare class SystemAlias {
5
5
  type: string;
6
6
  private _data;
7
- constructor(type: string, _data: any);
7
+ private _name?;
8
+ private _connection;
9
+ constructor(type: string, _data: any, _name?: string);
8
10
  getConnection(): ISystemConnector;
11
+ saveChanges(): void;
9
12
  private static generateFile;
10
13
  private static getSystemAliasFilePath;
11
14
  static getAll(): SystemAliasData[];
12
15
  static get(name: string): SystemAlias;
13
16
  static create(name: string, type: string, data: any): SystemAlias;
17
+ static update(name: string, data: any): void;
14
18
  static delete(name: string): void;
15
19
  private static deepEqual;
16
20
  static compare(a: SystemAlias, b: SystemAlias): boolean;
@@ -53,9 +53,10 @@ const ini = __importStar(require("ini"));
53
53
  const trm_commons_1 = require("trm-commons");
54
54
  const SYSTEM_FILE_NAME = "systems.ini";
55
55
  class SystemAlias {
56
- constructor(type, _data) {
56
+ constructor(type, _data, _name) {
57
57
  this.type = type;
58
58
  this._data = _data;
59
+ this._name = _name;
59
60
  }
60
61
  getConnection() {
61
62
  const connection = utils_1.GlobalContext.getInstance().getConnections().find(o => o.name === this.type);
@@ -63,8 +64,28 @@ class SystemAlias {
63
64
  throw new Error(`Unknown connection type "${this.type}". Possible values are ${utils_1.GlobalContext.getInstance().getConnections().map(k => k.name).join(', ')}.`);
64
65
  }
65
66
  connection.setData(this._data.data || this._data);
67
+ this._connection = connection;
66
68
  return connection.getSystemConnector();
67
69
  }
70
+ saveChanges() {
71
+ if (!this._name || !this._connection) {
72
+ return;
73
+ }
74
+ const normalize = (data) => {
75
+ const normalized = {};
76
+ Object.keys(data || {}).sort().forEach(key => {
77
+ if (key !== 'type' && data[key] !== undefined && data[key] !== null) {
78
+ normalized[key] = `${data[key]}`;
79
+ }
80
+ });
81
+ return normalized;
82
+ };
83
+ const newData = this._connection.getData();
84
+ if (!SystemAlias.deepEqual(normalize(this._data.data || this._data), normalize(newData))) {
85
+ SystemAlias.update(this._name, newData);
86
+ this._data = newData;
87
+ }
88
+ }
68
89
  static generateFile(content, filePath) {
69
90
  if (!filePath) {
70
91
  filePath = this.getSystemAliasFilePath();
@@ -110,7 +131,7 @@ class SystemAlias {
110
131
  const aAlias = this.getAll();
111
132
  const alias = aAlias.find(o => o.alias.trim().toUpperCase() === name.trim().toUpperCase());
112
133
  if (alias) {
113
- return new SystemAlias(alias.type, alias);
134
+ return new SystemAlias(alias.type, alias, alias.alias);
114
135
  }
115
136
  else {
116
137
  throw new Error(`System alias "${name}" not found.`);
@@ -135,6 +156,15 @@ class SystemAlias {
135
156
  }
136
157
  return new SystemAlias(type, data);
137
158
  }
159
+ static update(name, data) {
160
+ const aAlias = this.getAll();
161
+ const alias = aAlias.find(o => o.alias.trim().toUpperCase() === name.trim().toUpperCase());
162
+ if (!alias) {
163
+ throw new Error(`System alias "${name}" not found.`);
164
+ }
165
+ alias.data = data;
166
+ this.generateFile(aAlias);
167
+ }
138
168
  static delete(name) {
139
169
  var aAlias = this.getAll();
140
170
  aAlias = aAlias.filter(o => o.alias.trim().toUpperCase() !== name.trim().toUpperCase());
@@ -1,5 +1,23 @@
1
1
  import { ISystemConnector, SystemConnectorSupportedBulk, TADIR } from "trm-core";
2
2
  export declare class DummyConnector implements ISystemConnector {
3
+ lockTransportObjs: () => Promise<any>;
4
+ deleteTemporaryPackage: () => Promise<any>;
5
+ importTransportMultiple: () => Promise<any>;
6
+ deleteInstallDevc: () => Promise<any>;
7
+ restoreInstallMetadata: () => Promise<any>;
8
+ setInstallTransports: () => Promise<any>;
9
+ getTransportEntries: () => Promise<any>;
10
+ acquireActionLocks: () => Promise<any>;
11
+ releaseActionLocks: () => Promise<any>;
12
+ getTrmPackageData: () => Promise<any>;
13
+ getNamespacePackages: () => Promise<any>;
14
+ getInstallTransports: () => Promise<any>;
15
+ getSoftwareComponents: () => Promise<any>;
16
+ getInstalledProducts: () => Promise<any>;
17
+ getNoteStatus: () => Promise<any>;
18
+ checkTableCondition: () => Promise<any>;
19
+ getPostActivities: () => Promise<any>;
20
+ getPostActivityParameters: () => Promise<any>;
3
21
  _throw(): any;
4
22
  supportedBulk: SystemConnectorSupportedBulk;
5
23
  isStateless: boolean;
@@ -12,6 +12,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.DummyConnector = void 0;
13
13
  class DummyConnector {
14
14
  constructor() {
15
+ this.lockTransportObjs = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
16
+ this.deleteTemporaryPackage = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
17
+ this.importTransportMultiple = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
18
+ this.deleteInstallDevc = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
19
+ this.restoreInstallMetadata = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
20
+ this.setInstallTransports = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
21
+ this.getTransportEntries = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
22
+ this.acquireActionLocks = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
23
+ this.releaseActionLocks = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
24
+ this.getTrmPackageData = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
25
+ this.getNamespacePackages = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
26
+ this.getInstallTransports = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
27
+ this.getSoftwareComponents = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
28
+ this.getInstalledProducts = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
29
+ this.getNoteStatus = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
30
+ this.checkTableCondition = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
31
+ this.getPostActivities = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
32
+ this.getPostActivityParameters = () => __awaiter(this, void 0, void 0, function* () { return this._throw(); });
15
33
  this.supportedBulk = {
16
34
  getExistingObjects: false,
17
35
  getTransportObjects: false
@@ -166,7 +166,7 @@ class GlobalContext {
166
166
  }
167
167
  const registryAliases = registryAlias_1.RegistryAlias.getAll();
168
168
  return {
169
- loggerType: 'CLI',
169
+ loggerType: 'AUTO',
170
170
  logOutputFolder: 'default',
171
171
  cliUpdateCheckCache: 60,
172
172
  npmGlobalPathCheckCache: 180,
@@ -18,7 +18,7 @@ const util_1 = require("util");
18
18
  const chalk_1 = __importDefault(require("chalk"));
19
19
  const trm_commons_1 = require("trm-commons");
20
20
  const _getUnauthorizedError = () => {
21
- return `User "${trm_core_1.SystemConnector.getLogonUser()}" is not authorized to execute TRM RFC functions. Follow this guide https://docs.trmregistry.com/#/server/docs/setup?id=user-authorization-maintenance.`;
21
+ return `User "${trm_core_1.SystemConnector.getLogonUser()}" is not authorized to execute TRM RFC functions. Follow this guide https://docs.trmregistry.com/server/setup/#maintain-authorized-users .`;
22
22
  };
23
23
  function logError(err) {
24
24
  return __awaiter(this, void 0, void 0, function* () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trm-client",
3
- "version": "11.2.0",
3
+ "version": "12.0.0",
4
4
  "description": "TRM (Transport Request Manager) Client",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -46,13 +46,13 @@
46
46
  "lodash": "^4.17.21",
47
47
  "sanitize-filename": "^1.6.3",
48
48
  "semver": "^7.7.4",
49
- "trm-commons": "^5.1.0",
50
- "trm-core": "^9.10.6",
51
- "trm-registry-types": "^2.4.0",
49
+ "trm-commons": "^5.4.0",
50
+ "trm-core": "^10.0.1",
51
+ "trm-registry-types": "^5.0.0",
52
52
  "xml2js": "^0.6.2"
53
53
  },
54
54
  "peerDependencies": {
55
- "trm-commons": "^5.1.0"
55
+ "trm-commons": "^5.4.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/ini": "^1.3.31",