@sasjs/cli 3.16.1 → 3.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commands/add/addCredential.js +25 -18
- package/build/commands/add/addTarget.js +14 -9
- package/build/commands/add/spec/addTarget.spec.js +7 -0
- package/build/commands/build/build.js +42 -40
- package/build/commands/build/spec/build.spec.js +51 -0
- package/build/commands/build/spec/{cb.spec.server.d.ts → cb.spec.server.viya.d.ts} +0 -0
- package/build/commands/build/spec/{cb.spec.server.js → cb.spec.server.viya.js} +1 -1
- package/build/commands/compile/internal/loadDependencies.js +29 -21
- package/build/commands/deploy/spec/cbd.spec.js +22 -18
- package/build/commands/deploy/spec/{cbd.spec.server.d.ts → cbd.spec.server.viya.d.ts} +0 -0
- package/build/commands/deploy/spec/cbd.spec.server.viya.js +334 -0
- package/build/commands/flow/spec/{flow.spec.server.d.ts → flow.spec.server.viya.d.ts} +0 -0
- package/build/commands/flow/spec/{flow.spec.server.js → flow.spec.server.viya.js} +39 -55
- package/build/commands/folder/spec/{folder.spec.server.d.ts → folder.spec.server.viya.d.ts} +0 -0
- package/build/commands/folder/spec/{folder.spec.server.js → folder.spec.server.viya.js} +17 -23
- package/build/commands/init/init.js +7 -10
- package/build/commands/init/spec/{init.spec.server.d.ts → init.spec.d.ts} +0 -0
- package/build/commands/init/spec/{init.spec.server.js → init.spec.js} +0 -0
- package/build/commands/job/spec/{job.spec.server.d.ts → job.spec.server.viya.d.ts} +0 -0
- package/build/commands/job/spec/{job.spec.server.js → job.spec.server.viya.js} +45 -56
- package/build/commands/request/request.js +3 -2
- package/build/commands/request/spec/{request.spec.server.d.ts → request.spec.server.sas9.d.ts} +0 -0
- package/build/commands/request/spec/request.spec.server.sas9.js +283 -0
- package/build/commands/{run/spec/run.spec.server.d.ts → request/spec/request.spec.server.viya.d.ts} +0 -0
- package/build/commands/request/spec/request.spec.server.viya.js +460 -0
- package/build/commands/request/spec/utils.d.ts +23 -0
- package/build/commands/request/spec/utils.js +87 -0
- package/build/commands/{servicepack/spec/servicepack.spec.server.d.ts → run/spec/run.spec.server.sas9.d.ts} +0 -0
- package/build/commands/run/spec/run.spec.server.sas9.js +115 -0
- package/build/commands/run/spec/run.spec.server.viya.d.ts +1 -0
- package/build/commands/run/spec/{run.spec.server.js → run.spec.server.viya.js} +32 -101
- package/build/commands/servicepack/spec/servicepack.spec.server.viya.d.ts +1 -0
- package/build/commands/servicepack/spec/{servicepack.spec.server.js → servicepack.spec.server.viya.js} +1 -1
- package/build/utils/test.js +4 -2
- package/build/utils/utils.d.ts +1 -7
- package/build/utils/utils.js +113 -114
- package/package.json +4 -3
- package/build/commands/deploy/spec/cbd.spec.server.js +0 -331
- package/build/commands/request/spec/request.spec.server.js +0 -709
- package/build/utils/spec/removeComments.spec.d.ts +0 -1
- package/build/utils/spec/removeComments.spec.js +0 -47
|
@@ -75,7 +75,8 @@ var logger_1 = require("@sasjs/utils/logger");
|
|
|
75
75
|
var types_1 = require("@sasjs/utils/types");
|
|
76
76
|
var node_1 = __importStar(require("@sasjs/adapter/node"));
|
|
77
77
|
var auth_1 = require("../../utils/auth");
|
|
78
|
-
var utils_1 = require("
|
|
78
|
+
var utils_1 = require("../../utils");
|
|
79
|
+
var utils_2 = require("@sasjs/utils");
|
|
79
80
|
var input_1 = require("./internal/input");
|
|
80
81
|
var targetScope_1 = require("../../types/targetScope");
|
|
81
82
|
var saveConfig_1 = require("./internal/saveConfig");
|
|
@@ -114,7 +115,7 @@ var addCredential = function (target, insecure, targetScope) { return __awaiter(
|
|
|
114
115
|
case types_1.ServerType.Sas9: return [3 /*break*/, 10];
|
|
115
116
|
case types_1.ServerType.Sasjs: return [3 /*break*/, 15];
|
|
116
117
|
}
|
|
117
|
-
return [3 /*break*/,
|
|
118
|
+
return [3 /*break*/, 22];
|
|
118
119
|
case 4: return [4 /*yield*/, (0, input_1.getCredentialsInputForViya)(target.name)];
|
|
119
120
|
case 5:
|
|
120
121
|
_b = _j.sent(), client = _b.client, secret = _b.secret;
|
|
@@ -129,7 +130,7 @@ var addCredential = function (target, insecure, targetScope) { return __awaiter(
|
|
|
129
130
|
case 8:
|
|
130
131
|
target = new types_1.Target(__assign(__assign({}, target.toJson(false)), { authConfig: { client: client, secret: secret, access_token: access_token, refresh_token: refresh_token } }));
|
|
131
132
|
_j.label = 9;
|
|
132
|
-
case 9: return [3 /*break*/,
|
|
133
|
+
case 9: return [3 /*break*/, 23];
|
|
133
134
|
case 10: return [4 /*yield*/, (0, input_1.getCredentialsInputSas9)(target, targetScope)];
|
|
134
135
|
case 11:
|
|
135
136
|
_d = _j.sent(), userName = _d.userName, password = _d.password;
|
|
@@ -141,25 +142,31 @@ var addCredential = function (target, insecure, targetScope) { return __awaiter(
|
|
|
141
142
|
case 13:
|
|
142
143
|
target = new types_1.Target(__assign(__assign({}, target.toJson(false)), { authConfigSas9: { userName: userName, password: password } }));
|
|
143
144
|
_j.label = 14;
|
|
144
|
-
case 14: return [3 /*break*/,
|
|
145
|
-
case 15: return [4 /*yield*/, (0,
|
|
145
|
+
case 14: return [3 /*break*/, 23];
|
|
146
|
+
case 15: return [4 /*yield*/, (0, utils_1.isSasJsServerInServerMode)(target)];
|
|
146
147
|
case 16:
|
|
148
|
+
if (!(_j.sent())) {
|
|
149
|
+
process.logger.info('No need to authenticate against the sasjs server running in desktop mode.');
|
|
150
|
+
return [2 /*return*/, target];
|
|
151
|
+
}
|
|
152
|
+
return [4 /*yield*/, (0, input_1.getCredentialsInputSasjs)(target)];
|
|
153
|
+
case 17:
|
|
147
154
|
client = (_j.sent()).client;
|
|
148
155
|
return [4 /*yield*/, (0, exports.getTokens)(target, client, '', httpsAgentOptions)];
|
|
149
|
-
case
|
|
156
|
+
case 18:
|
|
150
157
|
_e = _j.sent(), access_token = _e.access_token, refresh_token = _e.refresh_token;
|
|
151
|
-
if (!(targetScope === targetScope_1.TargetScope.Local)) return [3 /*break*/,
|
|
158
|
+
if (!(targetScope === targetScope_1.TargetScope.Local)) return [3 /*break*/, 20];
|
|
152
159
|
return [4 /*yield*/, (0, exports.createEnvFileForSasjs)(target.name, client, access_token, refresh_token)];
|
|
153
|
-
case 18:
|
|
154
|
-
_j.sent();
|
|
155
|
-
return [3 /*break*/, 20];
|
|
156
160
|
case 19:
|
|
161
|
+
_j.sent();
|
|
162
|
+
return [3 /*break*/, 21];
|
|
163
|
+
case 20:
|
|
157
164
|
target = new types_1.Target(__assign(__assign({}, target.toJson(false)), { authConfig: { client: client, secret: '', access_token: access_token, refresh_token: refresh_token } }));
|
|
158
|
-
_j.label =
|
|
159
|
-
case
|
|
160
|
-
case
|
|
161
|
-
case
|
|
162
|
-
case
|
|
165
|
+
_j.label = 21;
|
|
166
|
+
case 21: return [3 /*break*/, 23];
|
|
167
|
+
case 22: throw new Error('Target contains invalid serverType. Possible types could be SASVIYA, SAS9 and SASJS');
|
|
168
|
+
case 23: return [4 /*yield*/, (0, saveConfig_1.saveConfig)(targetScope, target, false, false)];
|
|
169
|
+
case 24:
|
|
163
170
|
filePath = _j.sent();
|
|
164
171
|
(_h = process.logger) === null || _h === void 0 ? void 0 : _h.info("Target configuration has been saved to ".concat(filePath, " ."));
|
|
165
172
|
return [2 /*return*/, target];
|
|
@@ -216,7 +223,7 @@ var createEnvFileForViya = function (targetName, client, secret, accessToken, re
|
|
|
216
223
|
case 0:
|
|
217
224
|
envFileContent = "CLIENT=".concat(client, "\nSECRET=").concat(secret, "\nACCESS_TOKEN=").concat(accessToken, "\nREFRESH_TOKEN=").concat(refreshToken, "\n");
|
|
218
225
|
envFilePath = path_1.default.join(process.projectDir, ".env.".concat(targetName));
|
|
219
|
-
return [4 /*yield*/, (0,
|
|
226
|
+
return [4 /*yield*/, (0, utils_2.createFile)(envFilePath, envFileContent)];
|
|
220
227
|
case 1:
|
|
221
228
|
_b.sent();
|
|
222
229
|
(_a = process.logger) === null || _a === void 0 ? void 0 : _a.success("Environment file saved at ".concat(envFilePath));
|
|
@@ -233,7 +240,7 @@ var createEnvFileForSas9 = function (targetName, userName, password) { return __
|
|
|
233
240
|
case 0:
|
|
234
241
|
envFileContent = "SAS_USERNAME=".concat(userName, "\nSAS_PASSWORD=").concat(password, "\n");
|
|
235
242
|
envFilePath = path_1.default.join(process.projectDir, ".env.".concat(targetName));
|
|
236
|
-
return [4 /*yield*/, (0,
|
|
243
|
+
return [4 /*yield*/, (0, utils_2.createFile)(envFilePath, envFileContent)];
|
|
237
244
|
case 1:
|
|
238
245
|
_b.sent();
|
|
239
246
|
(_a = process.logger) === null || _a === void 0 ? void 0 : _a.success("Environment file saved at ".concat(envFilePath));
|
|
@@ -250,7 +257,7 @@ var createEnvFileForSasjs = function (targetName, client, accessToken, refreshTo
|
|
|
250
257
|
case 0:
|
|
251
258
|
envFileContent = "CLIENT=".concat(client, "\nACCESS_TOKEN=").concat(accessToken, "\nREFRESH_TOKEN=").concat(refreshToken, "\n");
|
|
252
259
|
envFilePath = path_1.default.join(process.projectDir, ".env.".concat(targetName));
|
|
253
|
-
return [4 /*yield*/, (0,
|
|
260
|
+
return [4 /*yield*/, (0, utils_2.createFile)(envFilePath, envFileContent)];
|
|
254
261
|
case 1:
|
|
255
262
|
_b.sent();
|
|
256
263
|
(_a = process.logger) === null || _a === void 0 ? void 0 : _a.success("Environment file saved at ".concat(envFilePath));
|
|
@@ -53,6 +53,7 @@ var targetScope_1 = require("../../types/targetScope");
|
|
|
53
53
|
var input_1 = require("./internal/input");
|
|
54
54
|
var saveConfig_1 = require("./internal/saveConfig");
|
|
55
55
|
var addCredential_1 = require("./addCredential");
|
|
56
|
+
var utils_1 = require("../../utils");
|
|
56
57
|
/**
|
|
57
58
|
* Creates new target/ updates current target(if found) for either local config or global config file.
|
|
58
59
|
* @param {boolean} insecure- boolean to use insecure connection, default is false. lf true the server will not reject any connection which is not authorized with the list of supplied CAs
|
|
@@ -81,7 +82,7 @@ function addTarget(insecure) {
|
|
|
81
82
|
case types_1.ServerType.SasViya: return [3 /*break*/, 5];
|
|
82
83
|
case types_1.ServerType.Sasjs: return [3 /*break*/, 7];
|
|
83
84
|
}
|
|
84
|
-
return [3 /*break*/,
|
|
85
|
+
return [3 /*break*/, 11];
|
|
85
86
|
case 3: return [4 /*yield*/, (0, input_1.getAndValidateSas9Fields)(target, scope)];
|
|
86
87
|
case 4:
|
|
87
88
|
_f = _h.sent(), serverName = _f.serverName, repositoryName = _f.repositoryName, userName = _f.userName, password = _f.password;
|
|
@@ -92,7 +93,7 @@ function addTarget(insecure) {
|
|
|
92
93
|
else {
|
|
93
94
|
targetJson = __assign(__assign({}, targetJson), { authConfigSas9: { userName: userName, password: password } });
|
|
94
95
|
}
|
|
95
|
-
return [3 /*break*/,
|
|
96
|
+
return [3 /*break*/, 12];
|
|
96
97
|
case 5: return [4 /*yield*/, (0, input_1.getAndValidateSasViyaFields)(target, scope, serverUrl, insecure, addCredential_1.addCredential)];
|
|
97
98
|
case 6:
|
|
98
99
|
_g = _h.sent(), contextName = _g.contextName, updatedViyaTarget = _g.target;
|
|
@@ -100,18 +101,22 @@ function addTarget(insecure) {
|
|
|
100
101
|
contextName: contextName
|
|
101
102
|
};
|
|
102
103
|
targetJson = __assign(__assign({}, updatedViyaTarget.toJson(false)), targetJson);
|
|
103
|
-
return [3 /*break*/,
|
|
104
|
-
case 7: return [4 /*yield*/, (0,
|
|
104
|
+
return [3 /*break*/, 12];
|
|
105
|
+
case 7: return [4 /*yield*/, (0, utils_1.isSasJsServerInServerMode)(target)];
|
|
105
106
|
case 8:
|
|
107
|
+
if (!_h.sent()) return [3 /*break*/, 10];
|
|
108
|
+
return [4 /*yield*/, (0, input_1.getAndValidateSasjsFields)(target, scope, insecure, addCredential_1.addCredential)];
|
|
109
|
+
case 9:
|
|
106
110
|
updatedSasjsTarget = (_h.sent()).target;
|
|
107
111
|
targetJson = updatedSasjsTarget.toJson(false);
|
|
108
|
-
|
|
109
|
-
case
|
|
110
|
-
case
|
|
111
|
-
case
|
|
112
|
+
_h.label = 10;
|
|
113
|
+
case 10: return [3 /*break*/, 12];
|
|
114
|
+
case 11: throw new Error('Target contains invalid serverType. Possible types could be SASVIYA, SAS9 and SASJS');
|
|
115
|
+
case 12: return [4 /*yield*/, (0, input_1.getIsDefault)()];
|
|
116
|
+
case 13:
|
|
112
117
|
isDefault = _h.sent();
|
|
113
118
|
return [4 /*yield*/, (0, saveConfig_1.saveConfig)(scope, new types_1.Target(targetJson), isDefault, false)];
|
|
114
|
-
case
|
|
119
|
+
case 14:
|
|
115
120
|
filePath = _h.sent();
|
|
116
121
|
(_c = process.logger) === null || _c === void 0 ? void 0 : _c.info("Target configuration has been saved to ".concat(filePath));
|
|
117
122
|
return [2 /*return*/, true];
|
|
@@ -73,6 +73,7 @@ var utils_1 = require("@sasjs/utils");
|
|
|
73
73
|
var dotenv_1 = __importDefault(require("dotenv"));
|
|
74
74
|
var path_1 = __importDefault(require("path"));
|
|
75
75
|
var inputModule = __importStar(require("../internal/input"));
|
|
76
|
+
var utilsModule = __importStar(require("../../../utils/utils"));
|
|
76
77
|
var addTarget_1 = require("../addTarget");
|
|
77
78
|
var config_1 = require("../../../utils/config");
|
|
78
79
|
var targetScope_1 = require("../../../types/targetScope");
|
|
@@ -192,6 +193,9 @@ describe('addTarget', function () {
|
|
|
192
193
|
target: new utils_1.Target(commonFields)
|
|
193
194
|
});
|
|
194
195
|
});
|
|
196
|
+
jest
|
|
197
|
+
.spyOn(utilsModule, 'isSasJsServerInServerMode')
|
|
198
|
+
.mockImplementation(function () { return Promise.resolve(true); });
|
|
195
199
|
return [4 /*yield*/, expect((0, addTarget_1.addTarget)(false)).resolves.toEqual(true)];
|
|
196
200
|
case 1:
|
|
197
201
|
_a.sent();
|
|
@@ -392,6 +396,9 @@ describe('addTarget', function () {
|
|
|
392
396
|
target: new utils_1.Target(__assign(__assign({}, targetJson), commonFields))
|
|
393
397
|
});
|
|
394
398
|
});
|
|
399
|
+
jest
|
|
400
|
+
.spyOn(utilsModule, 'isSasJsServerInServerMode')
|
|
401
|
+
.mockImplementation(function () { return Promise.resolve(true); });
|
|
395
402
|
return [4 /*yield*/, expect((0, addTarget_1.addTarget)(false)).resolves.toEqual(true)];
|
|
396
403
|
case 2:
|
|
397
404
|
_a.sent();
|
|
@@ -90,7 +90,6 @@ exports.getBuildVars = exports.build = void 0;
|
|
|
90
90
|
var path_1 = __importDefault(require("path"));
|
|
91
91
|
var utils_1 = require("@sasjs/utils");
|
|
92
92
|
var error_1 = require("@sasjs/utils/error");
|
|
93
|
-
var utils_2 = require("../../utils/utils");
|
|
94
93
|
var file_1 = require("../../utils/file");
|
|
95
94
|
var config_1 = require("../../utils/config");
|
|
96
95
|
var compile_1 = require("../compile/compile");
|
|
@@ -98,6 +97,7 @@ var config_2 = require("./internal/config");
|
|
|
98
97
|
var getLaunchPageCode_1 = require("./internal/getLaunchPageCode");
|
|
99
98
|
var types_1 = require("@sasjs/utils/types");
|
|
100
99
|
var compressAndSave_1 = require("../../utils/compressAndSave");
|
|
100
|
+
var loadDependencies_1 = require("../compile/internal/loadDependencies");
|
|
101
101
|
function build(target) {
|
|
102
102
|
return __awaiter(this, void 0, void 0, function () {
|
|
103
103
|
return __generator(this, function (_a) {
|
|
@@ -150,7 +150,7 @@ function createFinalSasFiles(target) {
|
|
|
150
150
|
return [4 /*yield*/, (0, utils_1.getDependencyPaths)("".concat(buildTerm, "\n").concat(buildInit), macroFolders, macroCorePath)];
|
|
151
151
|
case 6:
|
|
152
152
|
dependencyFilePaths = _l.sent();
|
|
153
|
-
return [4 /*yield*/,
|
|
153
|
+
return [4 /*yield*/, getDepsContent(dependencyFilePaths, target, macroFolders)];
|
|
154
154
|
case 7:
|
|
155
155
|
dependenciesContent = _l.sent();
|
|
156
156
|
finalSasFileContent += "\n".concat(dependenciesContent, "\n\n").concat(buildInit, "\n");
|
|
@@ -174,7 +174,7 @@ function createFinalSasFiles(target) {
|
|
|
174
174
|
servicePackSASjs.streamWebFolder = streamConfig.streamWebFolder;
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
|
-
finalSasFileContent = (0,
|
|
177
|
+
finalSasFileContent = (0, utils_1.removeHeader)(finalSasFileContent);
|
|
178
178
|
(_d = process.logger) === null || _d === void 0 ? void 0 : _d.debug("Creating file ".concat(finalFilePath, " ."));
|
|
179
179
|
return [4 /*yield*/, (0, utils_1.createFile)(finalFilePath, finalSasFileContent)];
|
|
180
180
|
case 9:
|
|
@@ -238,13 +238,13 @@ function getBuildInfo(target, streamWeb) {
|
|
|
238
238
|
dependencyFilePathsForGsubScript = _a.sent();
|
|
239
239
|
dependencyFilePaths = __spreadArray([], __read(new Set(__spreadArray(__spreadArray(__spreadArray([], __read(dependencyFilePaths), false), __read(dependencyFilePathsForCreateFile), false), __read(dependencyFilePathsForGsubScript), false))), false);
|
|
240
240
|
_a.label = 8;
|
|
241
|
-
case 8: return [4 /*yield*/,
|
|
241
|
+
case 8: return [4 /*yield*/, getDepsContent(dependencyFilePaths, target, macroFolders)];
|
|
242
242
|
case 9:
|
|
243
243
|
dependenciesContent = _a.sent();
|
|
244
244
|
return [4 /*yield*/, getBuildVars(target)];
|
|
245
245
|
case 10:
|
|
246
246
|
buildVars = _a.sent();
|
|
247
|
-
return [2 /*return*/, "\n/**\n * The appLoc represents the metadata or SAS Drive location of the app you\n * are about to deploy\n *\n * To set an alternative appLoc, simply populate the appLoc variable prior\n * to running this program, eg:\n *\n * %let apploc=/my/apploc;\n * %inc thisfile;\n *\n */\n\n%global appLoc serverName;\n%let compiled_apploc=".concat(appLoc, ";\n\n").concat(serverType === utils_1.ServerType.Sas9 ? "%let serverName=".concat(serverName, ";") : '', "\n\n%let appLoc=%sysfunc(coalescec(&appLoc,&compiled_apploc));\n\n%let sasjs_clickmeservice=clickme;\n%let syscc=0;\noptions ps=max nonotes nosgen nomprint nomlogic nosource2 nosource noquotelenmax;\n/* user supplied build vars */\n").concat(buildVars, "\n/* user supplied build vars end */\n/* system macro dependencies for build process */\n").concat(dependenciesContent, "\n/* system macro dependencies for build process end*/\n/* system macros for build process */\n").concat(buildConfig, "\n/* system macros for build process end */\n")];
|
|
247
|
+
return [2 /*return*/, "\n/**\n * The appLoc represents the metadata or SAS Drive location of the app you\n * are about to deploy\n *\n * To set an alternative appLoc, simply populate the appLoc variable prior\n * to running this program, eg:\n *\n * %let apploc=/my/apploc;\n * %inc thisfile;\n *\n */\n\n%global appLoc serverName;\n%let compiled_apploc=".concat(appLoc, ";\n\n").concat(serverType === utils_1.ServerType.Sas9 ? "%let serverName=".concat(serverName, ";") : '', "\n\n%let appLoc=%sysfunc(coalescec(&appLoc,&compiled_apploc));\n\n%let sasjs_clickmeservice=clickme;\n%let syscc=0;\noptions ps=max nonotes nosgen nomprint nomlogic nosource2 nosource noquotelenmax;\n/* user supplied build vars */\n").concat(buildVars, "\n/* user supplied build vars end */\n/* system macro dependencies for build process */\n").concat(dependenciesContent, "\n/* system macro dependencies for build process end*/\n/* system macros for build process */\n").concat((0, utils_1.removeHeader)(buildConfig), "\n/* system macros for build process end */\n")];
|
|
248
248
|
}
|
|
249
249
|
});
|
|
250
250
|
});
|
|
@@ -364,33 +364,6 @@ function getFolderContent(serverType) {
|
|
|
364
364
|
});
|
|
365
365
|
});
|
|
366
366
|
}
|
|
367
|
-
function getDependencies(filePaths) {
|
|
368
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
369
|
-
var dependenciesContent;
|
|
370
|
-
var _this = this;
|
|
371
|
-
return __generator(this, function (_a) {
|
|
372
|
-
switch (_a.label) {
|
|
373
|
-
case 0:
|
|
374
|
-
dependenciesContent = [];
|
|
375
|
-
return [4 /*yield*/, (0, utils_1.asyncForEach)(__spreadArray([], __read(new Set(filePaths)), false), function (filePath) { return __awaiter(_this, void 0, void 0, function () {
|
|
376
|
-
var depFileContent;
|
|
377
|
-
return __generator(this, function (_a) {
|
|
378
|
-
switch (_a.label) {
|
|
379
|
-
case 0: return [4 /*yield*/, (0, utils_1.readFile)(filePath)];
|
|
380
|
-
case 1:
|
|
381
|
-
depFileContent = _a.sent();
|
|
382
|
-
dependenciesContent.push(depFileContent);
|
|
383
|
-
return [2 /*return*/];
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
}); })];
|
|
387
|
-
case 1:
|
|
388
|
-
_a.sent();
|
|
389
|
-
return [2 /*return*/, dependenciesContent.join('\n')];
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
367
|
function getContentFor(rootDirectory, folderPath, serverType) {
|
|
395
368
|
return __awaiter(this, void 0, void 0, function () {
|
|
396
369
|
var folderName, content, contentJSON, files, subFolders;
|
|
@@ -413,26 +386,27 @@ function getContentFor(rootDirectory, folderPath, serverType) {
|
|
|
413
386
|
case 1:
|
|
414
387
|
files = _a.sent();
|
|
415
388
|
return [4 /*yield*/, (0, utils_1.asyncForEach)(files, function (file) { return __awaiter(_this, void 0, void 0, function () {
|
|
416
|
-
var filePath, fileContent, transformedContent, fileContentEncoded, transformedContent;
|
|
417
|
-
return __generator(this, function (
|
|
418
|
-
switch (
|
|
389
|
+
var filePath, fileContent, _a, transformedContent, fileContentEncoded, transformedContent;
|
|
390
|
+
return __generator(this, function (_b) {
|
|
391
|
+
switch (_b.label) {
|
|
419
392
|
case 0:
|
|
420
393
|
filePath = path_1.default.join(folderPath, file);
|
|
421
394
|
if (!(0, file_1.isSasFile)(file)) return [3 /*break*/, 2];
|
|
395
|
+
_a = utils_1.removeHeader;
|
|
422
396
|
return [4 /*yield*/, (0, utils_1.readFile)(filePath)];
|
|
423
397
|
case 1:
|
|
424
|
-
fileContent = _a.sent();
|
|
398
|
+
fileContent = _a.apply(void 0, [_b.sent()]);
|
|
425
399
|
transformedContent = getServiceText(file, fileContent, serverType);
|
|
426
400
|
content += "\n".concat(transformedContent, "\n");
|
|
427
401
|
contentJSON.members.push({
|
|
428
402
|
name: file.replace(/.sas$/, ''),
|
|
429
403
|
type: types_1.MemberType.service,
|
|
430
|
-
code: (0,
|
|
404
|
+
code: (0, utils_1.removeHeader)(fileContent)
|
|
431
405
|
});
|
|
432
406
|
return [3 /*break*/, 4];
|
|
433
407
|
case 2: return [4 /*yield*/, (0, utils_1.base64EncodeFile)(filePath)];
|
|
434
408
|
case 3:
|
|
435
|
-
fileContentEncoded =
|
|
409
|
+
fileContentEncoded = _b.sent();
|
|
436
410
|
transformedContent = getFileText(file, fileContentEncoded, serverType);
|
|
437
411
|
content += "\n".concat(transformedContent, "\n");
|
|
438
412
|
contentJSON.members.push({
|
|
@@ -440,7 +414,7 @@ function getContentFor(rootDirectory, folderPath, serverType) {
|
|
|
440
414
|
type: types_1.MemberType.file,
|
|
441
415
|
code: fileContentEncoded
|
|
442
416
|
});
|
|
443
|
-
|
|
417
|
+
_b.label = 4;
|
|
444
418
|
case 4: return [2 /*return*/];
|
|
445
419
|
}
|
|
446
420
|
});
|
|
@@ -472,7 +446,7 @@ function getContentFor(rootDirectory, folderPath, serverType) {
|
|
|
472
446
|
}
|
|
473
447
|
function getServiceText(serviceFileName, fileContent, serverType) {
|
|
474
448
|
var serviceName = serviceFileName.replace(/.sas$/, '');
|
|
475
|
-
var sourceCodeLines = getLines(
|
|
449
|
+
var sourceCodeLines = getLines(fileContent);
|
|
476
450
|
var content = "";
|
|
477
451
|
sourceCodeLines.forEach(function (line) {
|
|
478
452
|
var escapedLine = line.split("'").join("''");
|
|
@@ -561,3 +535,31 @@ var convertVarsToSasFormat = function (vars) {
|
|
|
561
535
|
}
|
|
562
536
|
return varsContent;
|
|
563
537
|
};
|
|
538
|
+
var getDepsContent = function (deps, target, macroFolders) { return __awaiter(void 0, void 0, void 0, function () {
|
|
539
|
+
var dependenciesContent, compileTree;
|
|
540
|
+
return __generator(this, function (_a) {
|
|
541
|
+
switch (_a.label) {
|
|
542
|
+
case 0:
|
|
543
|
+
dependenciesContent = '';
|
|
544
|
+
compileTree = (0, loadDependencies_1.getCompileTree)(target);
|
|
545
|
+
return [4 /*yield*/, (0, utils_1.asyncForEach)(deps, function (fp) { return __awaiter(void 0, void 0, void 0, function () {
|
|
546
|
+
var _a, _b;
|
|
547
|
+
return __generator(this, function (_c) {
|
|
548
|
+
switch (_c.label) {
|
|
549
|
+
case 0:
|
|
550
|
+
_a = dependenciesContent;
|
|
551
|
+
_b = '\n';
|
|
552
|
+
return [4 /*yield*/, (0, loadDependencies_1.loadDependencies)(target, fp, macroFolders, [], types_1.SASJsFileType.file, compileTree)];
|
|
553
|
+
case 1:
|
|
554
|
+
dependenciesContent = _a + (_b +
|
|
555
|
+
(_c.sent()));
|
|
556
|
+
return [2 /*return*/];
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
}); })];
|
|
560
|
+
case 1:
|
|
561
|
+
_a.sent();
|
|
562
|
+
return [2 /*return*/, dependenciesContent];
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
}); };
|
|
@@ -35,12 +35,16 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
35
35
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
38
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
42
|
var test_1 = require("../../../utils/test");
|
|
40
43
|
var utils_1 = require("@sasjs/utils");
|
|
41
44
|
var utils_2 = require("../../../utils");
|
|
42
45
|
var build_1 = require("../build");
|
|
43
46
|
var __1 = require("../..");
|
|
47
|
+
var path_1 = __importDefault(require("path"));
|
|
44
48
|
describe('sasjs build', function () {
|
|
45
49
|
var appName;
|
|
46
50
|
beforeAll(function () {
|
|
@@ -97,4 +101,51 @@ describe('sasjs build', function () {
|
|
|
97
101
|
}
|
|
98
102
|
});
|
|
99
103
|
}); }, 2 * 60 * 1000);
|
|
104
|
+
it("should compile and build remaining multiline comments", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
105
|
+
var beforeComment, afterComment, commentLine1, commentLine2, testContent, macroPath, _a, _b, target, finalSasFilePath, finalSasFile;
|
|
106
|
+
return __generator(this, function (_c) {
|
|
107
|
+
switch (_c.label) {
|
|
108
|
+
case 0:
|
|
109
|
+
beforeComment = 'before comment;';
|
|
110
|
+
afterComment = 'after comment;';
|
|
111
|
+
commentLine1 = "/*Name_corrected2=translate(trim(Name_corrected),'_','~!@#$%^&*()+-=[]{}|;:\",./<>?\u00C2\u00B0\u00B2\u00B3\u00B5 ');";
|
|
112
|
+
commentLine2 = "/* Name_corrected2=translate(trim(Name_corrected),'_','/','(',')','?','\u00C2\u00B2','#','\u00B0C','\u00B5','\u00B3'); */";
|
|
113
|
+
testContent = [
|
|
114
|
+
beforeComment,
|
|
115
|
+
commentLine1,
|
|
116
|
+
commentLine2,
|
|
117
|
+
afterComment
|
|
118
|
+
].join('\n');
|
|
119
|
+
appName = "test-app-build-".concat((0, utils_1.generateTimestamp)());
|
|
120
|
+
return [4 /*yield*/, (0, test_1.createTestApp)(__dirname, appName)];
|
|
121
|
+
case 1:
|
|
122
|
+
_c.sent();
|
|
123
|
+
macroPath = path_1.default.join(__dirname, appName, 'sasjs', 'macros', 'examplemacro.sas');
|
|
124
|
+
_a = utils_1.createFile;
|
|
125
|
+
_b = [macroPath];
|
|
126
|
+
return [4 /*yield*/, (0, utils_1.readFile)(macroPath)];
|
|
127
|
+
case 2: return [4 /*yield*/, _a.apply(void 0, _b.concat([(_c.sent()) + testContent]))];
|
|
128
|
+
case 3:
|
|
129
|
+
_c.sent();
|
|
130
|
+
return [4 /*yield*/, (0, utils_2.findTargetInConfiguration)('viya')];
|
|
131
|
+
case 4:
|
|
132
|
+
target = (_c.sent()).target;
|
|
133
|
+
return [4 /*yield*/, (0, __1.compile)(target)];
|
|
134
|
+
case 5:
|
|
135
|
+
_c.sent();
|
|
136
|
+
return [4 /*yield*/, (0, build_1.build)(target)];
|
|
137
|
+
case 6:
|
|
138
|
+
_c.sent();
|
|
139
|
+
finalSasFilePath = path_1.default.join(__dirname, appName, 'sasjsbuild', target.buildConfig.buildOutputFileName);
|
|
140
|
+
return [4 /*yield*/, (0, utils_1.readFile)(finalSasFilePath)];
|
|
141
|
+
case 7:
|
|
142
|
+
finalSasFile = _c.sent();
|
|
143
|
+
expect(finalSasFile.includes(beforeComment)).toBeTruthy();
|
|
144
|
+
expect(finalSasFile.includes(commentLine1.split("'").join("'".repeat(2)))).toBeTruthy();
|
|
145
|
+
expect(commentLine2.split("'").join("'".repeat(2))).toBeTruthy();
|
|
146
|
+
expect(finalSasFile.includes(afterComment)).toBeTruthy();
|
|
147
|
+
return [2 /*return*/];
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}); });
|
|
100
151
|
});
|
|
File without changes
|
|
@@ -44,7 +44,7 @@ var test_1 = require("../../../utils/test");
|
|
|
44
44
|
var utils_1 = require("@sasjs/utils");
|
|
45
45
|
var compile_1 = require("../../compile/compile");
|
|
46
46
|
var build_1 = require("../build");
|
|
47
|
-
describe('sasjs compile', function () {
|
|
47
|
+
describe('sasjs compile with Viya', function () {
|
|
48
48
|
var target;
|
|
49
49
|
beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
50
50
|
var appName;
|
|
@@ -46,33 +46,41 @@ var path_1 = __importDefault(require("path"));
|
|
|
46
46
|
function loadDependencies(target, filePath, macroFolders, programFolders, type, compileTree) {
|
|
47
47
|
var _a;
|
|
48
48
|
return __awaiter(this, void 0, void 0, function () {
|
|
49
|
-
var fileContent, leaf, configuration,
|
|
50
|
-
return __generator(this, function (
|
|
51
|
-
switch (
|
|
49
|
+
var fileContent, _b, leaf, configuration, _c, buildSourceFolder, macroCorePath, binaryFolders;
|
|
50
|
+
return __generator(this, function (_d) {
|
|
51
|
+
switch (_d.label) {
|
|
52
52
|
case 0:
|
|
53
53
|
(_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Loading dependencies for ".concat(filePath));
|
|
54
54
|
fileContent = '';
|
|
55
|
-
if (!(compileTree && Object.keys(compileTree).length)) return [3 /*break*/,
|
|
55
|
+
if (!(compileTree && Object.keys(compileTree).length)) return [3 /*break*/, 6];
|
|
56
|
+
if (!(type === utils_1.SASJsFileType.file)) return [3 /*break*/, 2];
|
|
57
|
+
_b = utils_1.removeHeader;
|
|
58
|
+
return [4 /*yield*/, (0, utils_1.readFile)(filePath)];
|
|
59
|
+
case 1:
|
|
60
|
+
// If file is of a generic type SASJsFileType.file, then just read the file content without header
|
|
61
|
+
fileContent = _b.apply(void 0, [_d.sent()]);
|
|
62
|
+
return [3 /*break*/, 5];
|
|
63
|
+
case 2:
|
|
56
64
|
leaf = compileTree.getLeaf(filePath);
|
|
57
|
-
if (!leaf) return [3 /*break*/,
|
|
65
|
+
if (!leaf) return [3 /*break*/, 3];
|
|
58
66
|
fileContent = leaf.content;
|
|
59
|
-
return [3 /*break*/,
|
|
60
|
-
case
|
|
61
|
-
case
|
|
62
|
-
fileContent =
|
|
63
|
-
|
|
64
|
-
case
|
|
65
|
-
case
|
|
66
|
-
case 5:
|
|
67
|
-
fileContent = _c.sent();
|
|
68
|
-
_c.label = 6;
|
|
69
|
-
case 6: return [4 /*yield*/, (0, config_1.getLocalOrGlobalConfig)()];
|
|
67
|
+
return [3 /*break*/, 5];
|
|
68
|
+
case 3: return [4 /*yield*/, (0, utils_1.readFile)(filePath)];
|
|
69
|
+
case 4:
|
|
70
|
+
fileContent = _d.sent();
|
|
71
|
+
_d.label = 5;
|
|
72
|
+
case 5: return [3 /*break*/, 8];
|
|
73
|
+
case 6: return [4 /*yield*/, (0, utils_1.readFile)(filePath)];
|
|
70
74
|
case 7:
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
fileContent = _d.sent();
|
|
76
|
+
_d.label = 8;
|
|
77
|
+
case 8: return [4 /*yield*/, (0, config_1.getLocalOrGlobalConfig)()];
|
|
78
|
+
case 9:
|
|
79
|
+
configuration = (_d.sent()).configuration;
|
|
80
|
+
_c = process.sasjsConstants, buildSourceFolder = _c.buildSourceFolder, macroCorePath = _c.macroCorePath;
|
|
73
81
|
return [4 /*yield*/, (0, config_1.getBinaryFolders)(target)];
|
|
74
|
-
case
|
|
75
|
-
binaryFolders =
|
|
82
|
+
case 10:
|
|
83
|
+
binaryFolders = _d.sent();
|
|
76
84
|
headerSyntaxNotices(fileContent);
|
|
77
85
|
return [4 /*yield*/, (0, utils_1.loadDependenciesFile)({
|
|
78
86
|
fileContent: fileContent,
|
|
@@ -87,7 +95,7 @@ function loadDependencies(target, filePath, macroFolders, programFolders, type,
|
|
|
87
95
|
binaryFolders: binaryFolders,
|
|
88
96
|
compileTree: compileTree
|
|
89
97
|
})];
|
|
90
|
-
case
|
|
98
|
+
case 11: return [2 /*return*/, _d.sent()];
|
|
91
99
|
}
|
|
92
100
|
});
|
|
93
101
|
});
|
|
@@ -49,7 +49,6 @@ var build_1 = require("../../build/build");
|
|
|
49
49
|
var deploy_1 = require("../deploy");
|
|
50
50
|
var utils_2 = require("./utils");
|
|
51
51
|
var config_1 = require("../../../utils/config");
|
|
52
|
-
var utils_3 = require("../../../utils");
|
|
53
52
|
describe('sasjs cbd with server type SASJS', function () {
|
|
54
53
|
var target;
|
|
55
54
|
var appName;
|
|
@@ -80,9 +79,9 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
80
79
|
});
|
|
81
80
|
}); });
|
|
82
81
|
it("should deploy compile and build to sasjs/server", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
83
|
-
var sasjs, customTarget, macroCorePath, mf_getuser, mp_jsonout, ms_webout, webout, mocksPath, appinitJSPath, getdataJSPath, appinitJSContents, getdataJSContents;
|
|
84
|
-
return __generator(this, function (
|
|
85
|
-
switch (
|
|
82
|
+
var sasjs, customTarget, macroCorePath, mf_getuser, _a, mp_jsonout, ms_webout, webout, mocksPath, appinitJSPath, getdataJSPath, appinitJSContents, getdataJSContents, depsInserts, appinit, getdata, getCode;
|
|
83
|
+
return __generator(this, function (_b) {
|
|
84
|
+
switch (_b.label) {
|
|
86
85
|
case 0:
|
|
87
86
|
sasjs = new node_1.default();
|
|
88
87
|
jest.mock('@sasjs/adapter');
|
|
@@ -98,7 +97,7 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
98
97
|
}
|
|
99
98
|
})];
|
|
100
99
|
case 1:
|
|
101
|
-
|
|
100
|
+
_b.sent();
|
|
102
101
|
return [4 /*yield*/, (0, utils_2.updateLocalTarget)(target.name, {
|
|
103
102
|
jobConfig: undefined,
|
|
104
103
|
serviceConfig: undefined,
|
|
@@ -108,26 +107,27 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
108
107
|
}
|
|
109
108
|
})];
|
|
110
109
|
case 2:
|
|
111
|
-
|
|
110
|
+
_b.sent();
|
|
112
111
|
return [4 /*yield*/, (0, config_1.findTargetInConfiguration)(target.name, types_1.TargetScope.Local)];
|
|
113
112
|
case 3:
|
|
114
|
-
customTarget = (
|
|
113
|
+
customTarget = (_b.sent()).target;
|
|
115
114
|
return [4 /*yield*/, expect((0, build_1.build)(customTarget)).toResolve()];
|
|
116
115
|
case 4:
|
|
117
|
-
|
|
116
|
+
_b.sent();
|
|
118
117
|
return [4 /*yield*/, (0, deploy_1.deploy)(customTarget, true, sasjs)];
|
|
119
118
|
case 5:
|
|
120
|
-
|
|
119
|
+
_b.sent();
|
|
121
120
|
macroCorePath = process.sasjsConstants.macroCorePath;
|
|
121
|
+
_a = utils_1.removeHeader;
|
|
122
122
|
return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/base/mf_getuser.sas"))];
|
|
123
123
|
case 6:
|
|
124
|
-
mf_getuser = _a.sent();
|
|
124
|
+
mf_getuser = _a.apply(void 0, [_b.sent()]);
|
|
125
125
|
return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/base/mp_jsonout.sas"))];
|
|
126
126
|
case 7:
|
|
127
|
-
mp_jsonout =
|
|
127
|
+
mp_jsonout = _b.sent();
|
|
128
128
|
return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/server/ms_webout.sas"))];
|
|
129
129
|
case 8:
|
|
130
|
-
ms_webout =
|
|
130
|
+
ms_webout = _b.sent();
|
|
131
131
|
webout = ' %macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO);\n' +
|
|
132
132
|
' %ms_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt\n' +
|
|
133
133
|
' ,missing=&missing\n' +
|
|
@@ -139,10 +139,16 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
139
139
|
getdataJSPath = path_1.default.join(mocksPath, 'services', 'common', 'getdata.js');
|
|
140
140
|
return [4 /*yield*/, (0, utils_1.readFile)(appinitJSPath)];
|
|
141
141
|
case 9:
|
|
142
|
-
appinitJSContents =
|
|
142
|
+
appinitJSContents = _b.sent();
|
|
143
143
|
return [4 /*yield*/, (0, utils_1.readFile)(getdataJSPath)];
|
|
144
144
|
case 10:
|
|
145
|
-
getdataJSContents =
|
|
145
|
+
getdataJSContents = _b.sent();
|
|
146
|
+
depsInserts = "\n\n* Service Variables start;\n\n\n* Service Variables end;\n* SAS Macros start;\n\n\n\n* SAS Macros end;\n* SAS Includes start;\n\n* SAS Includes end;\n* Binary Files start;\n\n* Binary Files end;\n\n \n* Service start;\n";
|
|
147
|
+
appinit = "/**\n @file appinit.sas\n @brief Initialisation service - runs on app startup\n @details This is always the first service called when the app is opened.\n\n <h4> SAS Macros </h4>\n\n**/\n\nproc sql;\ncreate table areas as select distinct area\n from mydb.springs;\n\n%webout(OPEN)\n%webout(OBJ,areas)\n%webout(CLOSE)\n\n";
|
|
148
|
+
getdata = "/**\n @file getdata.sas\n @brief Get Data service - runs on app startup\n @details This is always the first service called when the app is opened.\n\n <h4> SAS Macros </h4>\n\n**/\n\n%webout(FETCH)\n\nproc sql;\ncreate table springs as select * from mydb.springs\n where area in (select area from work.areas);\n\n%webout(OPEN)\n%webout(OBJ,springs)\n%webout(CLOSE)\n\n";
|
|
149
|
+
getCode = function (file) {
|
|
150
|
+
return "".concat(mf_getuser).concat(mp_jsonout).concat(ms_webout).concat(webout, "/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);").concat(depsInserts).concat(file, "* Service end;");
|
|
151
|
+
};
|
|
146
152
|
expect(sasjs.deployToSASjs).toHaveBeenCalledWith({
|
|
147
153
|
appLoc: target.appLoc,
|
|
148
154
|
fileTree: {
|
|
@@ -163,8 +169,7 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
163
169
|
{
|
|
164
170
|
name: 'appinit',
|
|
165
171
|
type: 'service',
|
|
166
|
-
code: (
|
|
167
|
-
'/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n* Service Variables end;\n* SAS Macros start;\n* SAS Macros end;\n* SAS Includes start;\n* SAS Includes end;\n* Binary Files start;\n* Binary Files end;\n* Service start;\nproc sql;\ncreate table areas as select distinct area\n from mydb.springs;\n%webout(OPEN)\n%webout(OBJ,areas)\n%webout(CLOSE)\n* Service end;')
|
|
172
|
+
code: getCode(appinit)
|
|
168
173
|
},
|
|
169
174
|
{
|
|
170
175
|
name: 'getdata.js',
|
|
@@ -174,8 +179,7 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
174
179
|
{
|
|
175
180
|
name: 'getdata',
|
|
176
181
|
type: 'service',
|
|
177
|
-
code: (
|
|
178
|
-
'/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n* Service Variables end;\n* SAS Macros start;\n* SAS Macros end;\n* SAS Includes start;\n* SAS Includes end;\n* Binary Files start;\n* Binary Files end;\n* Service start;\n%webout(FETCH)\nproc sql;\ncreate table springs as select * from mydb.springs\n where area in (select area from work.areas);\n%webout(OPEN)\n%webout(OBJ,springs)\n%webout(CLOSE)\n* Service end;')
|
|
182
|
+
code: getCode(getdata)
|
|
179
183
|
}
|
|
180
184
|
]
|
|
181
185
|
}
|
|
File without changes
|