@sap/cli-core 2023.12.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.
Files changed (179) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/LICENSE +44 -0
  3. package/README.md +13 -0
  4. package/assets/error.html +20 -0
  5. package/assets/success.html +20 -0
  6. package/cache/cache.d.ts +6 -0
  7. package/cache/cache.js +82 -0
  8. package/cache/index.d.ts +2 -0
  9. package/cache/index.js +12 -0
  10. package/cache/utils.d.ts +1 -0
  11. package/cache/utils.js +16 -0
  12. package/commands/cache.command/clean.command.d.ts +3 -0
  13. package/commands/cache.command/clean.command.js +15 -0
  14. package/commands/cache.command/index.d.ts +3 -0
  15. package/commands/cache.command/index.js +15 -0
  16. package/commands/cache.command/init.command.d.ts +3 -0
  17. package/commands/cache.command/init.command.js +36 -0
  18. package/commands/cache.command/show.command.d.ts +3 -0
  19. package/commands/cache.command/show.command.js +30 -0
  20. package/commands/handler/authentication/index.d.ts +2 -0
  21. package/commands/handler/authentication/index.js +21 -0
  22. package/commands/handler/authentication/oauth/index.d.ts +2 -0
  23. package/commands/handler/authentication/oauth/index.js +18 -0
  24. package/commands/handler/authentication/oauth/secretsProvider/cache.d.ts +2 -0
  25. package/commands/handler/authentication/oauth/secretsProvider/cache.js +19 -0
  26. package/commands/handler/authentication/oauth/secretsProvider/file.d.ts +2 -0
  27. package/commands/handler/authentication/oauth/secretsProvider/file.js +25 -0
  28. package/commands/handler/authentication/oauth/secretsProvider/index.d.ts +2 -0
  29. package/commands/handler/authentication/oauth/secretsProvider/index.js +10 -0
  30. package/commands/handler/authentication/oauth/secretsProvider/options.d.ts +2 -0
  31. package/commands/handler/authentication/oauth/secretsProvider/options.js +30 -0
  32. package/commands/handler/authentication/oauth/tokenProvider/getToken.d.ts +2 -0
  33. package/commands/handler/authentication/oauth/tokenProvider/getToken.js +88 -0
  34. package/commands/handler/authentication/oauth/tokenProvider/index.d.ts +2 -0
  35. package/commands/handler/authentication/oauth/tokenProvider/index.js +11 -0
  36. package/commands/handler/authentication/oauth/tokenProvider/refreshToken.d.ts +2 -0
  37. package/commands/handler/authentication/oauth/tokenProvider/refreshToken.js +15 -0
  38. package/commands/handler/authentication/oauth/tokenProvider/setAuthorization.d.ts +3 -0
  39. package/commands/handler/authentication/oauth/tokenProvider/setAuthorization.js +35 -0
  40. package/commands/handler/authentication/oauth/tokenProvider/utils.d.ts +1 -0
  41. package/commands/handler/authentication/oauth/tokenProvider/utils.js +27 -0
  42. package/commands/handler/authentication/oauth/utils.d.ts +15 -0
  43. package/commands/handler/authentication/oauth/utils.js +58 -0
  44. package/commands/handler/authentication/passcode/function.d.ts +2 -0
  45. package/commands/handler/authentication/passcode/function.js +22 -0
  46. package/commands/handler/authentication/passcode/index.d.ts +2 -0
  47. package/commands/handler/authentication/passcode/index.js +19 -0
  48. package/commands/handler/authentication/passcode/input.d.ts +2 -0
  49. package/commands/handler/authentication/passcode/input.js +42 -0
  50. package/commands/handler/authentication/passcode/setPasscode.d.ts +2 -0
  51. package/commands/handler/authentication/passcode/setPasscode.js +16 -0
  52. package/commands/handler/authentication/passcode/types.d.ts +1 -0
  53. package/commands/handler/authentication/passcode/types.js +2 -0
  54. package/commands/handler/authentication/technicalJWT/cf.d.ts +4 -0
  55. package/commands/handler/authentication/technicalJWT/cf.js +133 -0
  56. package/commands/handler/authentication/technicalJWT/exec.d.ts +9 -0
  57. package/commands/handler/authentication/technicalJWT/exec.js +196 -0
  58. package/commands/handler/authentication/technicalJWT/index.d.ts +2 -0
  59. package/commands/handler/authentication/technicalJWT/index.js +15 -0
  60. package/commands/handler/authentication/technicalJWT/types.d.ts +2 -0
  61. package/commands/handler/authentication/technicalJWT/types.js +8 -0
  62. package/commands/handler/authentication/technicalJWT/utils.d.ts +1 -0
  63. package/commands/handler/authentication/technicalJWT/utils.js +70 -0
  64. package/commands/handler/authentication/utils.d.ts +3 -0
  65. package/commands/handler/authentication/utils.js +8 -0
  66. package/commands/handler/checkOptionsExistence.d.ts +2 -0
  67. package/commands/handler/checkOptionsExistence.js +17 -0
  68. package/commands/handler/error.d.ts +2 -0
  69. package/commands/handler/error.js +21 -0
  70. package/commands/handler/fail.d.ts +2 -0
  71. package/commands/handler/fail.js +10 -0
  72. package/commands/handler/fetch/fetch.d.ts +2 -0
  73. package/commands/handler/fetch/fetch.js +83 -0
  74. package/commands/handler/fetch/index.d.ts +2 -0
  75. package/commands/handler/fetch/index.js +25 -0
  76. package/commands/handler/fetch/utils.d.ts +14 -0
  77. package/commands/handler/fetch/utils.js +152 -0
  78. package/commands/handler/force.d.ts +2 -0
  79. package/commands/handler/force.js +35 -0
  80. package/commands/handler/index.d.ts +18 -0
  81. package/commands/handler/index.js +39 -0
  82. package/commands/handler/input/file.d.ts +2 -0
  83. package/commands/handler/input/file.js +34 -0
  84. package/commands/handler/input/index.d.ts +2 -0
  85. package/commands/handler/input/index.js +8 -0
  86. package/commands/handler/input/input.d.ts +2 -0
  87. package/commands/handler/input/input.js +44 -0
  88. package/commands/handler/mandatoryOptions.d.ts +2 -0
  89. package/commands/handler/mandatoryOptions.js +25 -0
  90. package/commands/handler/next.d.ts +2 -0
  91. package/commands/handler/next.js +19 -0
  92. package/commands/handler/options/env.d.ts +2 -0
  93. package/commands/handler/options/env.js +18 -0
  94. package/commands/handler/options/file.d.ts +2 -0
  95. package/commands/handler/options/file.js +21 -0
  96. package/commands/handler/options/index.d.ts +7 -0
  97. package/commands/handler/options/index.js +32 -0
  98. package/commands/handler/options/option.d.ts +2 -0
  99. package/commands/handler/options/option.js +20 -0
  100. package/commands/handler/options/pipe.d.ts +2 -0
  101. package/commands/handler/options/pipe.js +34 -0
  102. package/commands/handler/options/utils.d.ts +6 -0
  103. package/commands/handler/options/utils.js +63 -0
  104. package/commands/handler/or.d.ts +2 -0
  105. package/commands/handler/or.js +37 -0
  106. package/commands/handler/parseArguments.d.ts +4 -0
  107. package/commands/handler/parseArguments.js +22 -0
  108. package/commands/handler/resilient.d.ts +2 -0
  109. package/commands/handler/resilient.js +18 -0
  110. package/commands/handler/root/index.d.ts +2 -0
  111. package/commands/handler/root/index.js +18 -0
  112. package/commands/handler/stackTrace.d.ts +2 -0
  113. package/commands/handler/stackTrace.js +22 -0
  114. package/commands/handler/succeed.d.ts +2 -0
  115. package/commands/handler/succeed.js +9 -0
  116. package/commands/handler/utils.d.ts +7 -0
  117. package/commands/handler/utils.js +56 -0
  118. package/commands/host.command.d.ts +2 -0
  119. package/commands/host.command.js +68 -0
  120. package/commands/login.command.d.ts +3 -0
  121. package/commands/login.command.js +16 -0
  122. package/commands/logout.command.d.ts +3 -0
  123. package/commands/logout.command.js +21 -0
  124. package/commands/openAPI.command/index.d.ts +2 -0
  125. package/commands/openAPI.command/index.js +102 -0
  126. package/commands/openAPI.command/utils.d.ts +19 -0
  127. package/commands/openAPI.command/utils.js +334 -0
  128. package/commands/passcode.command.d.ts +2 -0
  129. package/commands/passcode.command.js +26 -0
  130. package/commands/secrets.command/index.d.ts +3 -0
  131. package/commands/secrets.command/index.js +13 -0
  132. package/commands/secrets.command/show.command.d.ts +3 -0
  133. package/commands/secrets.command/show.command.js +25 -0
  134. package/config/core.d.ts +10 -0
  135. package/config/core.js +23 -0
  136. package/config/index.d.ts +5 -0
  137. package/config/index.js +90 -0
  138. package/configureLoggers.d.ts +1 -0
  139. package/configureLoggers.js +11 -0
  140. package/constants.d.ts +43 -0
  141. package/constants.js +175 -0
  142. package/discovery/index.d.ts +10 -0
  143. package/discovery/index.js +142 -0
  144. package/discovery/utils.d.ts +7 -0
  145. package/discovery/utils.js +27 -0
  146. package/dwc/dwc.d.ts +10 -0
  147. package/dwc/dwc.js +180 -0
  148. package/dwc/run.d.ts +1 -0
  149. package/dwc/run.js +37 -0
  150. package/dwc/utils.d.ts +4 -0
  151. package/dwc/utils.js +37 -0
  152. package/index.d.ts +16 -0
  153. package/index.js +59 -0
  154. package/logger/index.d.ts +28 -0
  155. package/logger/index.js +63 -0
  156. package/module.d.ts +4 -0
  157. package/module.js +45 -0
  158. package/package.json +32 -0
  159. package/result/ResultHandlerFactory.d.ts +6 -0
  160. package/result/ResultHandlerFactory.js +12 -0
  161. package/result/ResultHandlerImpl.d.ts +6 -0
  162. package/result/ResultHandlerImpl.js +12 -0
  163. package/result/types.d.ts +4 -0
  164. package/result/types.js +2 -0
  165. package/schemas/discovery.json +347 -0
  166. package/settings/index.d.ts +4 -0
  167. package/settings/index.js +34 -0
  168. package/types.d.ts +182 -0
  169. package/types.js +67 -0
  170. package/utils/commands.d.ts +8 -0
  171. package/utils/commands.js +115 -0
  172. package/utils/http/index.d.ts +7 -0
  173. package/utils/http/index.js +69 -0
  174. package/utils/http/utils.d.ts +7 -0
  175. package/utils/http/utils.js +47 -0
  176. package/utils/options.d.ts +3 -0
  177. package/utils/options.js +25 -0
  178. package/utils/utils.d.ts +24 -0
  179. package/utils/utils.js +163 -0
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ /* eslint-disable */
3
+ var fs = require("fs-extra");
4
+ var http = require("https");
5
+ var path = require("path");
6
+ var childProcess = require("child_process");
7
+ process.on("message", (m) => {
8
+ if (m.kill) {
9
+ module.exports.kill().then(() => {
10
+ process.send({ killed: true });
11
+ });
12
+ }
13
+ });
14
+ // Define exec
15
+ var processes = {};
16
+ var killCallbacks = {};
17
+ var exec = function (cmd, args, options) {
18
+ options = options || {};
19
+ options.stdio = options.stdio || [0, 1, 2];
20
+ options.cwd = options.cwd || path.resolve(__dirname);
21
+ console.log("Executing command: " + cmd + " " + args.join(" "));
22
+ return new Promise((resolve, reject) => {
23
+ var output = [];
24
+ var proc = childProcess.spawn(cmd, args, options);
25
+ processes[proc.pid] = proc;
26
+ if (proc.stdout) {
27
+ proc.stdout.on("data", (chunk) => {
28
+ output.push(`${chunk}`);
29
+ });
30
+ }
31
+ proc.on("error", reject);
32
+ proc.on("exit", (code, signal) => {
33
+ if (processes[proc.pid] === proc) {
34
+ delete processes[proc.pid];
35
+ }
36
+ if (typeof killCallbacks[proc.pid] === "function") {
37
+ console.log("Killed process: " + proc.spawnargs.join(" "));
38
+ return killCallbacks[proc.pid]();
39
+ }
40
+ if (code !== 0) {
41
+ return reject(new Error("Failed command: " +
42
+ cmd +
43
+ " " +
44
+ args.join(" ") +
45
+ ` (exited ${code})`));
46
+ }
47
+ return resolve(output.join(""));
48
+ });
49
+ });
50
+ };
51
+ var kill = function () {
52
+ var pids = Object.keys(processes);
53
+ var proms = [];
54
+ for (const pid of pids) {
55
+ var curProc = processes[pid];
56
+ if (!curProc.iskilled) {
57
+ proms.push(
58
+ // NOSONAR
59
+ new Promise((resolve) => {
60
+ setTimeout(resolve, 30 * 1000);
61
+ killCallbacks[curProc.pid] = resolve;
62
+ console.log("Killing process: " + curProc.spawnargs.join(" "));
63
+ curProc.kill();
64
+ }));
65
+ }
66
+ }
67
+ return Promise.all(proms);
68
+ };
69
+ module.exports.exec = exec;
70
+ module.exports.kill = kill;
71
+ module.exports.getResults = { stdio: [0, "pipe", 2] };
72
+ // Define cf
73
+ var cfReady;
74
+ var cfCmd = "cf";
75
+ process.env.CF_DEBUG = "1";
76
+ var internalMessaging = process.env.CF_DEBUG === "1" ? "inherit" : "ignore";
77
+ var checkCF = function () {
78
+ var win = process.platform === "win32";
79
+ var mac = process.platform === "darwin";
80
+ var plat = win ? "windows64-exe" : mac ? "macosx64-binary" : "linux64-binary";
81
+ var tmpFolder = path.resolve(__dirname, "../.tmp/cf");
82
+ var cfZipFile = path.resolve(tmpFolder, "client.zip");
83
+ var cfExeFile = path.resolve(tmpFolder, "cf.exe");
84
+ var cfBinFile = path.resolve(tmpFolder, "cf");
85
+ var downloadLink = `https://packages.cloudfoundry.org/stable?release=${plat}&source=github`;
86
+ if (cfReady) {
87
+ return cfReady;
88
+ }
89
+ cfReady = exec("cf", ["version"], { stdio: internalMessaging })
90
+ .then(() => {
91
+ console.log("Using global cf client");
92
+ cfCmd = "cf";
93
+ })
94
+ .catch(() => {
95
+ // TODO: enable local cf client after downloading
96
+ return (fs
97
+ .ensureDir(tmpFolder)
98
+ .then(() => fs.exists(cfZipFile))
99
+ .then((exists) => {
100
+ if (exists) {
101
+ return;
102
+ }
103
+ return new Promise((resolve, reject) => {
104
+ console.log(`Downloading cf client for platform ${plat}`);
105
+ console.log(downloadLink);
106
+ var file = fs.createWriteStream(cfZipFile, { mode: 777 });
107
+ var fnDownload = function (url) {
108
+ http.get(url, (res, err) => {
109
+ if (err) {
110
+ return reject(err);
111
+ }
112
+ if (res.statusCode === 302 &&
113
+ res.headers &&
114
+ res.headers.location) {
115
+ return fnDownload(res.headers.location);
116
+ }
117
+ res.pipe(file).on("finish", resolve);
118
+ });
119
+ };
120
+ fnDownload(downloadLink);
121
+ }).then(() => console.log("Downloading cf client Finished ..."));
122
+ })
123
+ // Unzip
124
+ .then(() => {
125
+ if (win) {
126
+ console.log("Unzipping cf client");
127
+ return fs
128
+ .readFile(cfZipFile)
129
+ .then((data) => {
130
+ var jsZip = require("jszip");
131
+ // NOSONAR we're dealing with cf and we're pretty sure nobody messes it up
132
+ return jsZip.loadAsync(data);
133
+ })
134
+ .then((zip) => {
135
+ var prom = [];
136
+ Object.keys(zip.files).forEach((filename) => {
137
+ if (zip.files[filename].dir) {
138
+ return;
139
+ }
140
+ prom.push(zip.files[filename]
141
+ .async("nodebuffer")
142
+ .then((fileData) => {
143
+ let dest = path.resolve(tmpFolder, filename);
144
+ return fs.outputFile(dest, fileData);
145
+ }));
146
+ });
147
+ return Promise.all(prom)
148
+ .then(() => console.log("Unzipping cf client finished"))
149
+ .then(() => {
150
+ cfCmd = cfExeFile;
151
+ });
152
+ });
153
+ }
154
+ else {
155
+ // Could be done with node as well
156
+ // TODO: test for linux and mac os
157
+ console.log("Unzipping cf client");
158
+ console.log(cfZipFile);
159
+ return exec("tar", ["-xf", cfZipFile, "-C", tmpFolder])
160
+ .then(() => console.log("Unzipping cf client finished"))
161
+ .then(() => {
162
+ cfCmd = cfBinFile;
163
+ });
164
+ }
165
+ }));
166
+ })
167
+ .then(() => {
168
+ // This is expected
169
+ });
170
+ return cfReady;
171
+ };
172
+ var execCF = function (args, options) {
173
+ return checkCF().then(() => exec(cfCmd, args, options));
174
+ };
175
+ module.exports.cf = execCF;
176
+ // Define npm
177
+ var execNpm = function (args, options) {
178
+ if (typeof args === "string") {
179
+ return execNpmRun(args);
180
+ }
181
+ var cmd = process.platform === "win32" ? "npm.cmd" : "npm";
182
+ options = options || {};
183
+ options.cwd = options.cwd || path.resolve(__dirname, "..");
184
+ return exec(cmd, args, options);
185
+ };
186
+ var execNpmRun = function (script) {
187
+ return execNpm(["run", script], { cwd: path.resolve(__dirname, "..") });
188
+ };
189
+ module.exports.npm = execNpm;
190
+ // Define git
191
+ var execGit = function (args, options) {
192
+ options = options || {};
193
+ options.stdio = options.stdio || ["pipe", 1, 2];
194
+ return exec("git", args, options);
195
+ };
196
+ module.exports.git = execGit;
@@ -0,0 +1,2 @@
1
+ import { Handler } from "../../../../types";
2
+ export declare const create: () => Handler;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = void 0;
4
+ const config_1 = require("../../../../config");
5
+ const commands_1 = require("../../../../utils/commands");
6
+ const types_1 = require("./types");
7
+ const utils_1 = require("./utils");
8
+ const create = () => (command) => {
9
+ command.addOption((0, commands_1.buildOption)(types_1.OPTION_SECRET));
10
+ return async () => {
11
+ const token = await (0, utils_1.getTechnicalJwt)();
12
+ (0, config_1.set)({ authorization: { Authorization: `Bearer ${token}` } });
13
+ };
14
+ };
15
+ exports.create = create;
@@ -0,0 +1,2 @@
1
+ import { Option } from "../../../../types";
2
+ export declare const OPTION_SECRET: Option;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OPTION_SECRET = void 0;
4
+ exports.OPTION_SECRET = {
5
+ longName: "secret",
6
+ description: "specifies the path to the secret file",
7
+ args: [{ name: "secret" }],
8
+ };
@@ -0,0 +1 @@
1
+ export declare const getTechnicalJwt: () => Promise<string>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getTechnicalJwt = void 0;
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const url_1 = require("url");
10
+ const config_1 = require("../../../../config");
11
+ const logger_1 = require("../../../../logger");
12
+ const http_1 = require("../../../../utils/http");
13
+ const types_1 = require("./types");
14
+ const getLogger = () => (0, logger_1.get)("commands.handler.authentication.technicalJWT.utils");
15
+ // eslint-disable-next-line
16
+ const cf = require("./cf.js");
17
+ const APPNAME_GLOBAL = "dwaas-core";
18
+ const getSecret = async () => {
19
+ const { trace } = getLogger();
20
+ const config = (0, config_1.get)();
21
+ const secretsFile = config.options[types_1.OPTION_SECRET.longName] ||
22
+ path_1.default.join(process.cwd(), ".secret.json");
23
+ trace("reading secret from", secretsFile);
24
+ if (fs_extra_1.default.existsSync(secretsFile)) {
25
+ const content = await fs_extra_1.default.readFile(secretsFile, "utf8");
26
+ return JSON.parse(content);
27
+ }
28
+ const currentTarget = await cf.getCurrentTarget();
29
+ let [env] = await cf.getEnv(APPNAME_GLOBAL, currentTarget.org, currentTarget.space);
30
+ env = JSON.parse(env);
31
+ const vcap = Object.keys(env)
32
+ .map((k) => env[k].VCAP_SERVICES)
33
+ .find((v) => v);
34
+ const url = Object.keys(env)
35
+ .map((k) => env[k].VCAP_APPLICATION)
36
+ .find((v) => v && v.uris && v.uris[0]).uris[0];
37
+ if (!vcap || !vcap.xsuaa) {
38
+ throw new Error("The target application is missing a uaa binding.");
39
+ }
40
+ const uaa = vcap.xsuaa.find((v) => v.credentials);
41
+ if (!uaa) {
42
+ throw new Error("The target application is missing a uaa binding with credentials.");
43
+ }
44
+ return {
45
+ url: `https://${url}`,
46
+ uaaUrl: uaa.credentials.url,
47
+ clientid: uaa.credentials.clientid,
48
+ clientsecret: uaa.credentials.clientsecret,
49
+ tenantid: uaa.credentials.tenantid,
50
+ };
51
+ };
52
+ const getTechnicalJwt = async () => {
53
+ const secret = await getSecret();
54
+ const { data } = await (0, http_1.fetch)({
55
+ method: "POST",
56
+ url: `${secret.uaaUrl}/oauth/token`,
57
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
58
+ data: new url_1.URLSearchParams({
59
+ grant_type: "client_credentials",
60
+ response_type: "token",
61
+ client_id: secret.clientid,
62
+ client_secret: secret.clientsecret,
63
+ }).toString(),
64
+ });
65
+ if (!data.access_token) {
66
+ throw new Error("No token could be retrieved from the application.");
67
+ }
68
+ return data.access_token;
69
+ };
70
+ exports.getTechnicalJwt = getTechnicalJwt;
@@ -0,0 +1,3 @@
1
+ export declare const setAuthorization: (authorization: {
2
+ [key: string]: string;
3
+ }) => void;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setAuthorization = void 0;
4
+ const config_1 = require("../../../config");
5
+ const setAuthorization = (authorization) => {
6
+ (0, config_1.set)({ authorization: { ...authorization } });
7
+ };
8
+ exports.setAuthorization = setAuthorization;
@@ -0,0 +1,2 @@
1
+ import { Handler, Option } from "../../types";
2
+ export declare const create: (option: Option, throwIfExists?: boolean) => Handler;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = void 0;
4
+ const config_1 = require("../../config");
5
+ const logger_1 = require("../../logger");
6
+ const create = (option, throwIfExists = true) => () => async () => {
7
+ const config = (0, config_1.get)();
8
+ const { trace } = (0, logger_1.get)("commands.handler.checkOptionsExistence");
9
+ trace(`checking options existence ${option.longName} in config, value in config is ${config.options[option.longName]}, throw error if option exists ${throwIfExists}`);
10
+ if (config.options[option.longName] && throwIfExists) {
11
+ throw new Error(`option ${option.longName} already set`);
12
+ }
13
+ else if (!config.options[option.longName] && !throwIfExists) {
14
+ throw new Error(`option ${option.longName} is not set`);
15
+ }
16
+ };
17
+ exports.create = create;
@@ -0,0 +1,2 @@
1
+ import { Handler } from "../../types";
2
+ export declare const create: (errorMessage: string, handler: Handler) => Handler;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = void 0;
4
+ const logger_1 = require("../../logger");
5
+ const stackTrace_1 = require("./stackTrace");
6
+ const errorHandler = (errorMessage, handler) => (command) => {
7
+ const commandHandler = handler(command);
8
+ return async (...args) => {
9
+ try {
10
+ await commandHandler(...args);
11
+ }
12
+ catch (err) {
13
+ const { error } = (0, logger_1.get)("commands.handler.error");
14
+ error(errorMessage, err);
15
+ throw new Error(`handler failed: ${errorMessage}`);
16
+ }
17
+ };
18
+ };
19
+ const create = (errorMessage, handler) => (0, stackTrace_1.create)(errorHandler(errorMessage, handler));
20
+ exports.create = create;
21
+ /* jscpd:ignore-end */
@@ -0,0 +1,2 @@
1
+ import { Handler } from "../../types";
2
+ export declare const create: () => Handler;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = void 0;
4
+ const logger_1 = require("../../logger");
5
+ const create = () => () => async () => {
6
+ const { debug } = (0, logger_1.get)("commands.handler.fail");
7
+ debug(`running fail handler`);
8
+ throw new Error("Fail I must");
9
+ };
10
+ exports.create = create;
@@ -0,0 +1,2 @@
1
+ import { Handler, HTTPMethod, ParameterMappings, ResponsePostProcessor } from "../../../types";
2
+ export declare const create: (method: HTTPMethod, path: string, parameterMappings?: ParameterMappings, responsePostProcessor?: ResponsePostProcessor) => Handler;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = void 0;
4
+ const config_1 = require("../../../config");
5
+ const http_1 = require("../../../utils/http");
6
+ const utils_1 = require("./utils");
7
+ const utils_2 = require("../authentication/oauth/tokenProvider/utils");
8
+ const logger_1 = require("../../../logger");
9
+ const constants_1 = require("../../../constants");
10
+ const getLogger = () => (0, logger_1.get)("commands.handler.fetch");
11
+ const removeCsrfTokenFromConfig = () => {
12
+ const config = (0, config_1.get)();
13
+ delete config[constants_1.X_CSRF_TOKEN];
14
+ };
15
+ // developer.mozilla.org/en-US/docs/Web/HTTP/Redirections
16
+ const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308];
17
+ const REDIRECT_WITHOUT_CHANGE = [307, 308];
18
+ const fetchData = async (method, path, parameterMappings, responsePostProcessor) => {
19
+ const config = (0, config_1.get)();
20
+ (0, utils_1.checkConfiguration)(config);
21
+ const conf = (0, utils_1.buildHttpConfig)(method, path, parameterMappings);
22
+ const response = await (0, http_1.fetch)(conf);
23
+ removeCsrfTokenFromConfig();
24
+ await (0, utils_1.handleResponse)(response.data, response.headers);
25
+ if (responsePostProcessor) {
26
+ await responsePostProcessor(response);
27
+ }
28
+ };
29
+ const handle401 = async (method, path, parameterMappings) => {
30
+ const { debug, error } = getLogger();
31
+ debug("response status is 401, trying to refresh access_token");
32
+ try {
33
+ await (0, utils_2.refreshToken)(true);
34
+ await fetchData(method, path, parameterMappings);
35
+ debug("refreshing token and fetching data succeeded");
36
+ }
37
+ catch (errRefresh) {
38
+ error("refreshing token and fetching data again failed", errRefresh);
39
+ throw errRefresh;
40
+ }
41
+ };
42
+ const handleRedirect = async (error, method, redirect) => {
43
+ const location = error.response?.headers.location;
44
+ if (!location) {
45
+ throw new Error("location header is not present for redirect");
46
+ }
47
+ let newMethod = method;
48
+ if (!REDIRECT_WITHOUT_CHANGE.includes(error.response?.status)) {
49
+ newMethod = "GET";
50
+ }
51
+ await redirect(newMethod, location);
52
+ };
53
+ const handleError = async (error, method, redirect, path, parameterMappings) => {
54
+ const { error: logError } = getLogger();
55
+ logError("failed to fetch data", error);
56
+ if (error.response?.data && (0, config_1.get)().verbose) {
57
+ await (0, utils_1.handleResponseData)(error.response?.data);
58
+ }
59
+ if (error.response?.status === 401) {
60
+ await handle401(method, path, parameterMappings);
61
+ }
62
+ else if (REDIRECT_STATUS_CODES.includes(error.response?.status)) {
63
+ await handleRedirect(error, method, redirect);
64
+ }
65
+ else {
66
+ throw error;
67
+ }
68
+ };
69
+ const runRequest = (method, path, parameterMappings, responsePostProcessor) => async () => {
70
+ try {
71
+ await fetchData(method, path, parameterMappings, responsePostProcessor);
72
+ }
73
+ catch (errFetch) {
74
+ const redirect = (newMethod, location) => runRequest(newMethod, location, parameterMappings, responsePostProcessor)();
75
+ await handleError(errFetch, method, redirect, path, parameterMappings);
76
+ }
77
+ };
78
+ /* jscpd:ignore-start */
79
+ const create = (method, path, parameterMappings, responsePostProcessor) => {
80
+ /* jscpd:ignore-end */
81
+ return () => runRequest(method, path, parameterMappings, responsePostProcessor);
82
+ };
83
+ exports.create = create;
@@ -0,0 +1,2 @@
1
+ import { Handler, HTTPMethod, ParameterMappings, ResponsePostProcessor } from "../../../types";
2
+ export declare const create: (method: HTTPMethod, path: string, parameterMappings?: ParameterMappings, responsePostProcessor?: ResponsePostProcessor) => Handler;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = void 0;
4
+ const constants_1 = require("../../../constants");
5
+ const fetch_1 = require("./fetch");
6
+ const next_1 = require("../next");
7
+ const requiresCsrfToken = (parameterMappings) => !!parameterMappings?.find((param) => param.name === constants_1.X_CSRF_TOKEN);
8
+ const createCsrfTokenFetchHandler = (path, parameterMappings) => (0, fetch_1.create)("GET", path, parameterMappings
9
+ ?.filter((param) => param.name !== constants_1.X_CSRF_TOKEN)
10
+ .concat([
11
+ {
12
+ name: constants_1.X_CSRF_TOKEN,
13
+ in: "header",
14
+ source: { type: "value", value: "fetch" },
15
+ },
16
+ ]));
17
+ /* jscpd:ignore-start */
18
+ const create = (method, path, parameterMappings, responsePostProcessor) => {
19
+ /* jscpd:ignore-end */
20
+ if (requiresCsrfToken(parameterMappings)) {
21
+ return (0, next_1.create)(createCsrfTokenFetchHandler(path, parameterMappings), (0, fetch_1.create)(method, path, parameterMappings, responsePostProcessor));
22
+ }
23
+ return (0, fetch_1.create)(method, path, parameterMappings, responsePostProcessor);
24
+ };
25
+ exports.create = create;
@@ -0,0 +1,14 @@
1
+ import { URL } from "url";
2
+ import { AxiosResponseHeaders, RawAxiosResponseHeaders } from "axios";
3
+ import { HTTPConfig, HTTPMethod, KeyValuePair, ParameterMappings } from "../../../types";
4
+ export declare const checkConfiguration: (config: KeyValuePair) => void;
5
+ export declare const removeLeadingPathSegmentForPasscode: (path: string) => string;
6
+ export declare const buildParameters: (path: string, parameterMappings?: ParameterMappings) => {
7
+ url: URL;
8
+ headers: KeyValuePair;
9
+ body: any;
10
+ };
11
+ export declare const handleResponseData: (data: any) => Promise<void>;
12
+ export declare const handleResponse: (data: any, headers?: RawAxiosResponseHeaders | AxiosResponseHeaders) => Promise<void>;
13
+ export declare const configRequiresBody: (method: HTTPMethod) => boolean;
14
+ export declare const buildHttpConfig: (method: HTTPMethod, path: string, parameterMappings?: ParameterMappings) => HTTPConfig;
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildHttpConfig = exports.configRequiresBody = exports.handleResponse = exports.handleResponseData = exports.buildParameters = exports.removeLeadingPathSegmentForPasscode = exports.checkConfiguration = void 0;
7
+ const url_1 = require("url");
8
+ const lodash_1 = __importDefault(require("lodash"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const constants_1 = require("../../../constants");
11
+ const logger_1 = require("../../../logger");
12
+ const config_1 = require("../../../config");
13
+ const utils_1 = require("../utils");
14
+ const ResultHandlerFactory_1 = require("../../../result/ResultHandlerFactory");
15
+ const CURLY_OPEN_ENCODED = encodeURIComponent("{");
16
+ const CURLY_CLOSED_ENCODED = encodeURIComponent("}");
17
+ const checkConfiguration = (config) => {
18
+ if (!config.authorization) {
19
+ throw new Error("no authorization header");
20
+ }
21
+ if (!config.host) {
22
+ throw new Error("no host");
23
+ }
24
+ if (!config.publicfqdn) {
25
+ throw new Error("no publicfqdn");
26
+ }
27
+ };
28
+ exports.checkConfiguration = checkConfiguration;
29
+ const removeLeadingPathSegmentForPasscode = (path) => {
30
+ const authenticationMethod = (0, utils_1.getAuthenticationMethod)();
31
+ if (authenticationMethod === constants_1.AuthenticationMethod.passcode) {
32
+ const segments = path.split("/");
33
+ if (constants_1.SEGMENTS_TO_REMOVE_FOR_PASSCODE_AUTH.includes(segments[1])) {
34
+ segments.splice(1, 1);
35
+ return segments.join("/");
36
+ }
37
+ }
38
+ return path;
39
+ };
40
+ exports.removeLeadingPathSegmentForPasscode = removeLeadingPathSegmentForPasscode;
41
+ const getUrl = (path) => {
42
+ if (path.startsWith("http")) {
43
+ return new url_1.URL(path);
44
+ }
45
+ const pathInt = (0, exports.removeLeadingPathSegmentForPasscode)(path);
46
+ const targetHost = (0, utils_1.getTargetHost)();
47
+ return new url_1.URL(`${targetHost}${pathInt}`);
48
+ };
49
+ const handleMappingIn = (mapping, url, value, headers, bodyWrapper) => {
50
+ if (mapping.in === "query") {
51
+ url.searchParams.append(mapping.name, value);
52
+ }
53
+ else if (mapping.in === "header") {
54
+ // eslint-disable-next-line no-param-reassign
55
+ headers[mapping.name] = value;
56
+ }
57
+ else if (mapping.in === "path") {
58
+ // eslint-disable-next-line no-param-reassign
59
+ url.pathname = url.pathname.replace(new RegExp(`${CURLY_OPEN_ENCODED}${mapping.name}${CURLY_CLOSED_ENCODED}`, "g"), value);
60
+ }
61
+ else {
62
+ // NOSONAR
63
+ // if (mapping.in === "body") {
64
+ if (!bodyWrapper.body) {
65
+ // eslint-disable-next-line no-param-reassign
66
+ bodyWrapper.body = {};
67
+ }
68
+ lodash_1.default.set(bodyWrapper.body, mapping.name, value);
69
+ }
70
+ };
71
+ const getValueFromMappping = (mapping, config) => {
72
+ if (mapping.source.type === "value") {
73
+ return mapping.source.value;
74
+ }
75
+ if (
76
+ // mapping.source.type === "option"
77
+ config.options[mapping.source.name] === undefined &&
78
+ mapping.source.dataType === "boolean") {
79
+ return false;
80
+ }
81
+ // mapping.source.type === "option"
82
+ return config.options[mapping.source.name];
83
+ };
84
+ const handleParameterMapping = (config, url, headers, bodyWrapper) => (mapping) => {
85
+ const value = getValueFromMappping(mapping, config);
86
+ if (value === undefined || value === null) {
87
+ return;
88
+ }
89
+ handleMappingIn(mapping, url, value, headers, bodyWrapper);
90
+ };
91
+ const buildParameters = (path, parameterMappings) => {
92
+ const config = (0, config_1.get)();
93
+ const headers = {};
94
+ const bodyWrapper = {
95
+ body: config.data,
96
+ };
97
+ const url = getUrl(path);
98
+ parameterMappings?.forEach(handleParameterMapping(config, url, headers, bodyWrapper));
99
+ return {
100
+ url,
101
+ headers,
102
+ body: bodyWrapper.body,
103
+ };
104
+ };
105
+ exports.buildParameters = buildParameters;
106
+ const handleResponseData = async (data) => {
107
+ const config = (0, config_1.get)();
108
+ if (!config.doNotStoreResult) {
109
+ ResultHandlerFactory_1.ResultHandlerFactory.get().setResult(data);
110
+ }
111
+ const { output } = (0, logger_1.get)("handler.fetch");
112
+ const formatted = config.options[constants_1.OPTION_PRETTY.longName]
113
+ ? JSON.stringify(data, null, 2)
114
+ : JSON.stringify(data);
115
+ if (config.options[constants_1.OPTION_OUTPUT.longName]) {
116
+ await fs_extra_1.default.writeFile(config.options[constants_1.OPTION_OUTPUT.longName], formatted);
117
+ }
118
+ else {
119
+ output(formatted);
120
+ }
121
+ };
122
+ exports.handleResponseData = handleResponseData;
123
+ const handleResponse = async (data, headers) => {
124
+ if (headers?.[constants_1.X_CSRF_TOKEN]) {
125
+ (0, config_1.set)({ [constants_1.X_CSRF_TOKEN]: headers[constants_1.X_CSRF_TOKEN] });
126
+ }
127
+ else if (data) {
128
+ await (0, exports.handleResponseData)(data);
129
+ }
130
+ };
131
+ exports.handleResponse = handleResponse;
132
+ const configRequiresBody = (method) => ["POST", "PUT", "PATCH"].includes(method.toUpperCase());
133
+ exports.configRequiresBody = configRequiresBody;
134
+ const buildHttpConfig = (method, path, parameterMappings) => {
135
+ const config = (0, config_1.get)();
136
+ const { url, body, headers } = (0, exports.buildParameters)(path, parameterMappings);
137
+ const httpConfig = {
138
+ url: url.toString(),
139
+ method,
140
+ data: (0, exports.configRequiresBody)(method) ? body : undefined,
141
+ headers: {
142
+ ...config.authorization,
143
+ ...headers,
144
+ publicfqdn: config.publicfqdn,
145
+ },
146
+ };
147
+ if ((0, utils_1.getAuthenticationMethod)() === constants_1.AuthenticationMethod.oauth) {
148
+ delete httpConfig.headers.publicfqdn;
149
+ }
150
+ return httpConfig;
151
+ };
152
+ exports.buildHttpConfig = buildHttpConfig;