@sasjs/cli 3.8.9 → 3.9.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.
@@ -113,78 +113,66 @@ function build(target) {
113
113
  }
114
114
  exports.build = build;
115
115
  function createFinalSasFiles(target) {
116
- var _a;
116
+ var _a, _b, _c, _d, _e, _f, _g;
117
117
  return __awaiter(this, void 0, void 0, function () {
118
- var streamConfig;
119
- return __generator(this, function (_b) {
120
- switch (_b.label) {
118
+ var streamConfig, streamWeb, buildConfig, serverType, name, macroFolders, buildOutputFileName, buildDestinationFolder, finalSasFileContent, finalFilePath, finalFilePathJSON, buildInfo, buildInit, buildTerm, macroCorePath, dependencyFilePaths, dependenciesContent, _h, folderContent, folderContentJSON;
119
+ return __generator(this, function (_j) {
120
+ switch (_j.label) {
121
121
  case 0:
122
122
  (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info('Creating output SAS and JSON files.');
123
123
  return [4 /*yield*/, (0, config_1.getStreamConfig)(target)];
124
124
  case 1:
125
- streamConfig = _b.sent();
126
- return [4 /*yield*/, createFinalSasFile(target, streamConfig)];
127
- case 2:
128
- _b.sent();
129
- return [2 /*return*/];
130
- }
131
- });
132
- });
133
- }
134
- function createFinalSasFile(target, streamConfig) {
135
- var _a, _b, _c, _d, _e, _f;
136
- return __awaiter(this, void 0, void 0, function () {
137
- var streamWeb, buildConfig, serverType, name, macroFolders, buildOutputFileName, buildDestinationFolder, finalSasFileContent, finalFilePath, finalFilePathJSON, buildInfo, buildInit, buildTerm, macroCorePath, dependencyFilePaths, dependenciesContent, _g, folderContent, folderContentJSON;
138
- return __generator(this, function (_h) {
139
- switch (_h.label) {
140
- case 0:
141
- streamWeb = (_a = streamConfig.streamWeb) !== null && _a !== void 0 ? _a : false;
125
+ streamConfig = _j.sent();
126
+ streamWeb = (_b = streamConfig.streamWeb) !== null && _b !== void 0 ? _b : false;
142
127
  buildConfig = target.buildConfig, serverType = target.serverType, name = target.name;
143
128
  return [4 /*yield*/, (0, config_1.getMacroFolders)(target)];
144
- case 1:
145
- macroFolders = _h.sent();
146
- buildOutputFileName = (_b = buildConfig === null || buildConfig === void 0 ? void 0 : buildConfig.buildOutputFileName) !== null && _b !== void 0 ? _b : "".concat(name, ".sas");
129
+ case 2:
130
+ macroFolders = _j.sent();
131
+ buildOutputFileName = (_c = buildConfig === null || buildConfig === void 0 ? void 0 : buildConfig.buildOutputFileName) !== null && _c !== void 0 ? _c : "".concat(name, ".sas");
147
132
  buildDestinationFolder = process.sasjsConstants.buildDestinationFolder;
148
133
  finalSasFileContent = '';
149
134
  finalFilePath = path_1.default.join(buildDestinationFolder, buildOutputFileName);
150
135
  finalFilePathJSON = path_1.default.join(buildDestinationFolder, "".concat(name, ".json"));
151
136
  return [4 /*yield*/, getBuildInfo(target, streamWeb)];
152
- case 2:
153
- buildInfo = _h.sent();
137
+ case 3:
138
+ buildInfo = _j.sent();
154
139
  finalSasFileContent += "\n".concat(buildInfo);
155
140
  return [4 /*yield*/, (0, config_2.getBuildInit)(target)];
156
- case 3:
157
- buildInit = _h.sent();
158
- return [4 /*yield*/, (0, config_2.getBuildTerm)(target)];
159
141
  case 4:
160
- buildTerm = _h.sent();
142
+ buildInit = _j.sent();
143
+ return [4 /*yield*/, (0, config_2.getBuildTerm)(target)];
144
+ case 5:
145
+ buildTerm = _j.sent();
161
146
  macroCorePath = (0, config_1.getMacroCorePath)();
162
147
  return [4 /*yield*/, (0, utils_1.getDependencyPaths)("".concat(buildTerm, "\n").concat(buildInit), macroFolders, macroCorePath)];
163
- case 5:
164
- dependencyFilePaths = _h.sent();
165
- return [4 /*yield*/, getDependencies(dependencyFilePaths)];
166
148
  case 6:
167
- dependenciesContent = _h.sent();
149
+ dependencyFilePaths = _j.sent();
150
+ return [4 /*yield*/, getDependencies(dependencyFilePaths)];
151
+ case 7:
152
+ dependenciesContent = _j.sent();
168
153
  finalSasFileContent += "\n".concat(dependenciesContent, "\n\n").concat(buildInit, "\n");
169
154
  return [4 /*yield*/, getFolderContent(serverType)];
170
- case 7:
171
- _g = _h.sent(), folderContent = _g.folderContent, folderContentJSON = _g.folderContentJSON;
155
+ case 8:
156
+ _h = _j.sent(), folderContent = _h.folderContent, folderContentJSON = _h.folderContentJSON;
172
157
  finalSasFileContent += "\n".concat(folderContent);
173
158
  finalSasFileContent += "\n".concat(buildTerm);
174
159
  if (streamWeb) {
175
- finalSasFileContent += (0, getLaunchPageCode_1.getLaunchPageCode)(target.serverType, streamConfig.streamServiceName);
160
+ if (target.serverType === utils_1.ServerType.SasViya ||
161
+ target.serverType === utils_1.ServerType.Sas9) {
162
+ finalSasFileContent += (0, getLaunchPageCode_1.getLaunchPageCode)(target.serverType, streamConfig.streamServiceName);
163
+ }
176
164
  }
177
165
  finalSasFileContent = (0, utils_2.removeComments)(finalSasFileContent);
178
- (_c = process.logger) === null || _c === void 0 ? void 0 : _c.debug("Creating file ".concat(finalFilePath, " ."));
166
+ (_d = process.logger) === null || _d === void 0 ? void 0 : _d.debug("Creating file ".concat(finalFilePath, " ."));
179
167
  return [4 /*yield*/, (0, utils_1.createFile)(finalFilePath, finalSasFileContent)];
180
- case 8:
181
- _h.sent();
182
- (_d = process.logger) === null || _d === void 0 ? void 0 : _d.success("File ".concat(finalFilePath, " has been created."));
183
- (_e = process.logger) === null || _e === void 0 ? void 0 : _e.debug("Creating file ".concat(finalFilePathJSON, " ."));
184
- return [4 /*yield*/, (0, utils_1.createFile)(finalFilePathJSON, JSON.stringify(folderContentJSON, null, 1))];
185
168
  case 9:
186
- _h.sent();
187
- (_f = process.logger) === null || _f === void 0 ? void 0 : _f.success("File ".concat(finalFilePathJSON, " has been created."));
169
+ _j.sent();
170
+ (_e = process.logger) === null || _e === void 0 ? void 0 : _e.success("File ".concat(finalFilePath, " has been created."));
171
+ (_f = process.logger) === null || _f === void 0 ? void 0 : _f.debug("Creating file ".concat(finalFilePathJSON, " ."));
172
+ return [4 /*yield*/, (0, utils_1.createFile)(finalFilePathJSON, JSON.stringify(folderContentJSON, null, 1))];
173
+ case 10:
174
+ _j.sent();
175
+ (_g = process.logger) === null || _g === void 0 ? void 0 : _g.success("File ".concat(finalFilePathJSON, " has been created."));
188
176
  return [2 /*return*/];
189
177
  }
190
178
  });
@@ -59,14 +59,14 @@ var deployToSasViyaWithServicePack_1 = require("../shared/deployToSasViyaWithSer
59
59
  function deploy(target, isLocal, sasjs) {
60
60
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
61
61
  return __awaiter(this, void 0, void 0, function () {
62
- var appLoc, buildDestinationFolder_1, finalFilePathJSON, jsonObject, webIndexFileName, deployScripts, buildDestinationFolder, logFilePath;
62
+ var appLoc, buildDestinationFolder_1, finalFilePathJSON, jsonObject, webIndexFileName, deployScripts, buildDestinationFolder, logFilePath, streamConfig;
63
63
  var _this = this;
64
64
  return __generator(this, function (_k) {
65
65
  switch (_k.label) {
66
66
  case 0:
67
67
  if (!(target.serverType === utils_2.ServerType.SasViya &&
68
68
  ((_a = target.deployConfig) === null || _a === void 0 ? void 0 : _a.deployServicePack))) return [3 /*break*/, 2];
69
- appLoc = target.appLoc.replace(/\ /g, '%20');
69
+ appLoc = encodeURI(target.appLoc);
70
70
  (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Deploying service pack to ".concat(target.serverUrl, " at location ").concat(appLoc, " ."));
71
71
  buildDestinationFolder_1 = process.sasjsConstants.buildDestinationFolder;
72
72
  finalFilePathJSON = path_1.default.join(buildDestinationFolder_1, "".concat(target.name, ".json"));
@@ -89,19 +89,22 @@ function deploy(target, isLocal, sasjs) {
89
89
  }
90
90
  buildDestinationFolder = process.sasjsConstants.buildDestinationFolder;
91
91
  logFilePath = buildDestinationFolder;
92
- if (!(target.serverType === utils_2.ServerType.Sasjs)) return [3 /*break*/, 5];
93
- return [4 /*yield*/, deployToSasjs(target, sasjs)];
92
+ return [4 /*yield*/, (0, config_1.getStreamConfig)(target)];
94
93
  case 4:
94
+ streamConfig = _k.sent();
95
+ if (!(target.serverType === utils_2.ServerType.Sasjs)) return [3 /*break*/, 6];
96
+ return [4 /*yield*/, deployToSasjs(target, sasjs, streamConfig)];
97
+ case 5:
95
98
  _k.sent();
96
- return [3 /*break*/, 7];
97
- case 5: return [4 /*yield*/, (0, utils_2.asyncForEach)(deployScripts, function (deployScript) { return __awaiter(_this, void 0, void 0, function () {
98
- var deployScriptPath, deployScriptContent, linesToExecute, streamConfig, deployScriptName, logPath;
99
+ return [3 /*break*/, 8];
100
+ case 6: return [4 /*yield*/, (0, utils_2.asyncForEach)(deployScripts, function (deployScript) { return __awaiter(_this, void 0, void 0, function () {
101
+ var deployScriptPath, deployScriptContent, linesToExecute, deployScriptName, logPath;
99
102
  var _a, _b, _c;
100
103
  return __generator(this, function (_d) {
101
104
  switch (_d.label) {
102
105
  case 0:
103
106
  deployScriptPath = (0, utils_2.getAbsolutePath)(deployScript, process.projectDir);
104
- if (!(0, file_1.isSasFile)(deployScript)) return [3 /*break*/, 7];
107
+ if (!(0, file_1.isSasFile)(deployScript)) return [3 /*break*/, 6];
105
108
  (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Processing SAS file ".concat(path_1.default.basename(deployScript), " ..."));
106
109
  return [4 /*yield*/, (0, utils_2.readFile)(deployScriptPath)
107
110
  // split into lines
@@ -111,37 +114,34 @@ function deploy(target, isLocal, sasjs) {
111
114
  linesToExecute = deployScriptContent
112
115
  .replace(/\r\n/g, '\n')
113
116
  .split('\n');
114
- return [4 /*yield*/, (0, config_1.getStreamConfig)(target)];
115
- case 2:
116
- streamConfig = _d.sent();
117
117
  deployScriptName = path_1.default.basename(deployScript);
118
- if (!(target.serverType === utils_2.ServerType.SasViya)) return [3 /*break*/, 4];
118
+ if (!(target.serverType === utils_2.ServerType.SasViya)) return [3 /*break*/, 3];
119
119
  return [4 /*yield*/, deployToSasViya(deployScriptName, target, isLocal, linesToExecute, logFilePath, streamConfig)];
120
- case 3:
120
+ case 2:
121
121
  _d.sent();
122
- return [3 /*break*/, 6];
123
- case 4: return [4 /*yield*/, deployToSas9(deployScriptName, target, linesToExecute, logFilePath, streamConfig)];
124
- case 5:
122
+ return [3 /*break*/, 5];
123
+ case 3: return [4 /*yield*/, deployToSas9(deployScriptName, target, linesToExecute, logFilePath, streamConfig)];
124
+ case 4:
125
125
  _d.sent();
126
- _d.label = 6;
127
- case 6: return [3 /*break*/, 9];
128
- case 7:
129
- if (!(0, file_1.isShellScript)(deployScript)) return [3 /*break*/, 9];
126
+ _d.label = 5;
127
+ case 5: return [3 /*break*/, 8];
128
+ case 6:
129
+ if (!(0, file_1.isShellScript)(deployScript)) return [3 /*break*/, 8];
130
130
  (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Executing shell script ".concat(deployScript, " ..."));
131
131
  logPath = path_1.default.join(process.projectDir, 'sasjsbuild', "".concat(path_1.default.basename(deployScript).replace('.sh', ''), ".log"));
132
132
  return [4 /*yield*/, (0, utils_1.executeShellScript)(deployScriptPath, logPath)];
133
- case 8:
133
+ case 7:
134
134
  _d.sent();
135
135
  (_c = process.logger) === null || _c === void 0 ? void 0 : _c.success("Shell script execution completed! Log is here: ".concat(logPath));
136
- _d.label = 9;
137
- case 9: return [2 /*return*/];
136
+ _d.label = 8;
137
+ case 8: return [2 /*return*/];
138
138
  }
139
139
  });
140
140
  }); })];
141
- case 6:
141
+ case 7:
142
142
  _k.sent();
143
- _k.label = 7;
144
- case 7: return [2 /*return*/];
143
+ _k.label = 8;
144
+ case 8: return [2 /*return*/];
145
145
  }
146
146
  });
147
147
  });
@@ -239,7 +239,7 @@ function deployToSasViya(deployScriptName, target, isLocal, linesToExecute, logF
239
239
  _g.label = 5;
240
240
  case 5:
241
241
  if (streamConfig === null || streamConfig === void 0 ? void 0 : streamConfig.streamWeb) {
242
- appLoc = target.appLoc.replace(/\ /g, '%20');
242
+ appLoc = encodeURI(target.appLoc);
243
243
  webAppStreamUrl = "".concat(target.serverUrl, "/SASJobExecution?_FILE=").concat(appLoc, "/services/").concat(streamConfig.streamServiceName, ".html&_debug=2");
244
244
  (_e = process.logger) === null || _e === void 0 ? void 0 : _e.info("Web app is available at ".concat(webAppStreamUrl));
245
245
  }
@@ -317,7 +317,7 @@ function deployToSas9(deployScriptName, target, linesToExecute, logFolder, strea
317
317
  }
318
318
  (_d = process.logger) === null || _d === void 0 ? void 0 : _d.success("Deployment completed! Log is available at ".concat(logFilePath));
319
319
  if (streamConfig === null || streamConfig === void 0 ? void 0 : streamConfig.streamWeb) {
320
- appLoc = target.appLoc.replace(/\ /g, '%20');
320
+ appLoc = encodeURI(target.appLoc);
321
321
  webAppStreamUrl = "".concat(target.serverUrl, "/SASStoredProcess/?_PROGRAM=").concat(appLoc, "/services/").concat(streamConfig.streamServiceName);
322
322
  (_e = process.logger) === null || _e === void 0 ? void 0 : _e.info("Web app is available at ".concat(webAppStreamUrl));
323
323
  }
@@ -331,18 +331,18 @@ function deployToSas9(deployScriptName, target, linesToExecute, logFolder, strea
331
331
  * @param {Target} target- the target having deploy configuration.
332
332
  * @param {object} sasjs - optional configuration object of SAS adapter.
333
333
  */
334
- function deployToSasjs(target, sasjs) {
335
- var _a, _b;
334
+ function deployToSasjs(target, sasjs, streamConfig) {
335
+ var _a, _b, _c;
336
336
  return __awaiter(this, void 0, void 0, function () {
337
- var buildDestinationFolder, finalFilePathJSON, jsonContent, payload, authConfig, e_2, result;
338
- return __generator(this, function (_c) {
339
- switch (_c.label) {
337
+ var buildDestinationFolder, finalFilePathJSON, jsonContent, payload, authConfig, e_2, result, appLoc, webAppStreamUrl;
338
+ return __generator(this, function (_d) {
339
+ switch (_d.label) {
340
340
  case 0:
341
341
  buildDestinationFolder = process.sasjsConstants.buildDestinationFolder;
342
342
  finalFilePathJSON = path_1.default.join(buildDestinationFolder, "".concat(target.name, ".json"));
343
343
  return [4 /*yield*/, (0, utils_2.readFile)(finalFilePathJSON)];
344
344
  case 1:
345
- jsonContent = _c.sent();
345
+ jsonContent = _d.sent();
346
346
  payload = JSON.parse(jsonContent);
347
347
  if (!!sasjs) return [3 /*break*/, 5];
348
348
  sasjs = new node_1.default({
@@ -352,15 +352,15 @@ function deployToSasjs(target, sasjs) {
352
352
  httpsAgentOptions: target.httpsAgentOptions,
353
353
  debug: true
354
354
  });
355
- _c.label = 2;
355
+ _d.label = 2;
356
356
  case 2:
357
- _c.trys.push([2, 4, , 5]);
357
+ _d.trys.push([2, 4, , 5]);
358
358
  return [4 /*yield*/, (0, config_1.getAuthConfig)(target)];
359
359
  case 3:
360
- authConfig = _c.sent();
360
+ authConfig = _d.sent();
361
361
  return [3 /*break*/, 5];
362
362
  case 4:
363
- e_2 = _c.sent();
363
+ e_2 = _d.sent();
364
364
  return [3 /*break*/, 5];
365
365
  case 5: return [4 /*yield*/, sasjs
366
366
  .deployToSASjs(payload, undefined, authConfig)
@@ -369,13 +369,18 @@ function deployToSasjs(target, sasjs) {
369
369
  (_a = process.logger) === null || _a === void 0 ? void 0 : _a.error(err);
370
370
  })];
371
371
  case 6:
372
- result = _c.sent();
372
+ result = _d.sent();
373
373
  if ((result === null || result === void 0 ? void 0 : result.status) === 'failure') {
374
374
  (_a = process.logger) === null || _a === void 0 ? void 0 : _a.error(result.message);
375
375
  if (result.example) {
376
376
  (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Payload example:\n".concat(JSON.stringify(result.example, null, 2)));
377
377
  }
378
378
  }
379
+ if (streamConfig === null || streamConfig === void 0 ? void 0 : streamConfig.streamWeb) {
380
+ appLoc = encodeURI(target.appLoc);
381
+ webAppStreamUrl = "".concat(target.serverUrl, "/AppStream").concat(appLoc);
382
+ (_c = process.logger) === null || _c === void 0 ? void 0 : _c.info("Web app is available at ".concat(webAppStreamUrl));
383
+ }
379
384
  return [2 /*return*/];
380
385
  }
381
386
  });
@@ -56,56 +56,66 @@ var exampleStreamConfig = {
56
56
  streamServiceName: 'clickme'
57
57
  };
58
58
  function createWebAppServices(target) {
59
- var _a;
59
+ var _a, _b;
60
60
  return __awaiter(this, void 0, void 0, function () {
61
- var buildDestinationServicesFolder, streamConfig, _b, webSourcePathFull, indexHtmlPath, destinationPath, assetPathMap, indexHtml;
62
- return __generator(this, function (_c) {
63
- switch (_c.label) {
61
+ var buildDestinationServicesFolder, streamConfig, _c, webSourcePathFull, indexHtmlPath, destinationPath, assetPathMap, indexHtml;
62
+ return __generator(this, function (_d) {
63
+ switch (_d.label) {
64
64
  case 0:
65
65
  buildDestinationServicesFolder = process.sasjsConstants.buildDestinationServicesFolder;
66
66
  return [4 /*yield*/, (0, config_1.getStreamConfig)(target)];
67
67
  case 1:
68
- streamConfig = _c.sent();
68
+ streamConfig = _d.sent();
69
69
  return [4 /*yield*/, validateStreamConfig(streamConfig)];
70
70
  case 2:
71
- _b = _c.sent(), webSourcePathFull = _b.webSourcePathFull, indexHtmlPath = _b.indexHtmlPath;
72
- (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Compiling web app services for target ".concat(target.name, "..."));
71
+ _c = _d.sent(), webSourcePathFull = _c.webSourcePathFull, indexHtmlPath = _c.indexHtmlPath;
73
72
  return [4 /*yield*/, createBuildDestinationFolder()];
74
73
  case 3:
75
- _c.sent();
74
+ _d.sent();
76
75
  destinationPath = path_1.default.join(buildDestinationServicesFolder, streamConfig.streamWebFolder);
77
- return [4 /*yield*/, createTargetDestinationFolder(destinationPath)];
76
+ return [4 /*yield*/, createTargetDestinationFolder(destinationPath)
77
+ // For server type SASjs, just need to copy webSourcePath
78
+ // to streamWebFolder, no need to create service files.
79
+ ];
78
80
  case 4:
79
- _c.sent();
81
+ _d.sent();
82
+ if (!(target.serverType === utils_1.ServerType.Sasjs)) return [3 /*break*/, 6];
83
+ (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Copying web app files for target ".concat(target.name, "..."));
84
+ return [4 /*yield*/, (0, utils_1.copy)(webSourcePathFull, destinationPath)];
85
+ case 5:
86
+ _d.sent();
87
+ return [2 /*return*/];
88
+ case 6:
89
+ (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Compiling web app services for target ".concat(target.name, "..."));
80
90
  return [4 /*yield*/, (0, createAssetServices_1.createAssetServices)(target, destinationPath, streamConfig).then(function (map) {
81
91
  var indexHtmlIndex = map.findIndex(function (assetPath) { return assetPath.source === 'index.html'; });
82
92
  map.splice(indexHtmlIndex, 1);
83
93
  return map;
84
94
  })];
85
- case 5:
86
- assetPathMap = _c.sent();
95
+ case 7:
96
+ assetPathMap = _d.sent();
87
97
  return [4 /*yield*/, (0, utils_1.readFile)(indexHtmlPath).then(function (content) { return new jsdom_1.default.JSDOM(content); })];
88
- case 6:
89
- indexHtml = _c.sent();
98
+ case 8:
99
+ indexHtml = _d.sent();
90
100
  return [4 /*yield*/, (0, updateAllTags_1.updateAllTags)(indexHtml, {
91
101
  webSourcePathFull: webSourcePathFull,
92
102
  destinationPath: destinationPath,
93
103
  serverType: target.serverType,
94
104
  assetPathMap: assetPathMap
95
105
  })];
96
- case 7:
97
- _c.sent();
98
- if (!(target.serverType === utils_1.ServerType.SasViya)) return [3 /*break*/, 9];
106
+ case 9:
107
+ _d.sent();
108
+ if (!(target.serverType === utils_1.ServerType.SasViya)) return [3 /*break*/, 11];
99
109
  indexHtml.window.document.body.innerHTML += adjustIframeScript_1.adjustIframeScript;
100
110
  return [4 /*yield*/, createClickMeFile(indexHtml.serialize(), streamConfig.streamServiceName)];
101
- case 8:
102
- _c.sent();
103
- return [3 /*break*/, 11];
104
- case 9: return [4 /*yield*/, createClickMeService(indexHtml.serialize(), streamConfig.streamServiceName)];
105
111
  case 10:
106
- _c.sent();
107
- _c.label = 11;
108
- case 11: return [2 /*return*/];
112
+ _d.sent();
113
+ return [3 /*break*/, 13];
114
+ case 11: return [4 /*yield*/, createClickMeService(indexHtml.serialize(), streamConfig.streamServiceName)];
115
+ case 12:
116
+ _d.sent();
117
+ _d.label = 13;
118
+ case 13: return [2 /*return*/];
109
119
  }
110
120
  });
111
121
  });
package/package.json CHANGED
@@ -94,5 +94,5 @@
94
94
  "typescript": "4.5.4",
95
95
  "util": "0.12.4"
96
96
  },
97
- "version": "3.8.9"
97
+ "version": "3.9.0"
98
98
  }