1 | const h54sError = require('./error.js');
|
2 |
|
3 | const sasVersionMap = {
|
4 | v9: {
|
5 | url: '/SASStoredProcess/do',
|
6 | loginUrl: '/SASLogon/login',
|
7 | logoutUrl: '/SASStoredProcess/do?_action=logoff',
|
8 | RESTAuthLoginUrl: '/SASLogon/v1/tickets'
|
9 | },
|
10 | viya: {
|
11 | url: '/SASJobExecution/',
|
12 | loginUrl: '/SASLogon/login.do',
|
13 | logoutUrl: '/SASLogon/logout.do?',
|
14 | RESTAuthLoginUrl: ''
|
15 | }
|
16 | }
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | const h54s = module.exports = function(config) {
|
39 |
|
40 | this.sasVersion = (config && config.sasVersion) || 'v9'
|
41 | this.debug = (config && config.debug) || false;
|
42 | this.metadataRoot = (config && config.metadataRoot) || '';
|
43 | this.url = sasVersionMap[this.sasVersion].url;
|
44 | this.loginUrl = sasVersionMap[this.sasVersion].loginUrl;
|
45 | this.logoutUrl = sasVersionMap[this.sasVersion].logoutUrl;
|
46 | this.RESTauth = false;
|
47 | this.RESTauthLoginUrl = sasVersionMap[this.sasVersion].RESTAuthLoginUrl;
|
48 | this.retryAfterLogin = true;
|
49 | this.maxXhrRetries = 5;
|
50 | this.ajaxTimeout = (config && config.ajaxTimeout) || 300000;
|
51 | this.useMultipartFormData = (config && config.useMultipartFormData) || true;
|
52 | this.csrf = ''
|
53 | this.isViya = this.sasVersion === 'viya';
|
54 |
|
55 |
|
56 | this.remoteConfigUpdateCallbacks = [];
|
57 | this._pendingCalls = [];
|
58 | this._customPendingCalls = [];
|
59 | this._disableCalls = false
|
60 | this._ajax = require('./methods/ajax.js')();
|
61 |
|
62 | _setConfig.call(this, config);
|
63 |
|
64 |
|
65 | if(config && config.isRemoteConfig) {
|
66 | const self = this;
|
67 |
|
68 | this._disableCalls = true;
|
69 |
|
70 |
|
71 |
|
72 | this._ajax.get('h54sConfig.json').success(function(res) {
|
73 | const remoteConfig = JSON.parse(res.responseText)
|
74 |
|
75 |
|
76 | const localConfig = Object.assign({}, config)
|
77 | const oldMetadataRoot = localConfig.metadataRoot;
|
78 |
|
79 | for(let key in remoteConfig) {
|
80 | if(remoteConfig.hasOwnProperty(key) && key !== 'isRemoteConfig') {
|
81 | config[key] = remoteConfig[key];
|
82 | }
|
83 | }
|
84 |
|
85 | _setConfig.call(self, config);
|
86 |
|
87 |
|
88 | for(let i = 0, n = self.remoteConfigUpdateCallbacks.length; i < n; i++) {
|
89 | const fn = self.remoteConfigUpdateCallbacks[i];
|
90 | fn();
|
91 | }
|
92 |
|
93 |
|
94 | self._disableCalls = false;
|
95 | while(self._pendingCalls.length > 0) {
|
96 | const pendingCall = self._pendingCalls.shift();
|
97 | const sasProgram = pendingCall.options.sasProgram;
|
98 | const callbackPending = pendingCall.options.callback;
|
99 | const params = pendingCall.params;
|
100 |
|
101 | params._debug = self.debug ? 131 : 0;
|
102 |
|
103 |
|
104 | if(self.metadataRoot && params._program.indexOf(self.metadataRoot) === -1) {
|
105 | params._program = self.metadataRoot.replace(/\/?$/, '/') + params._program.replace(oldMetadataRoot, '').replace(/^\//, '');
|
106 | }
|
107 |
|
108 |
|
109 | params._debug = self.debug ? 131 : 0;
|
110 |
|
111 | self.call(sasProgram, null, callbackPending, params);
|
112 | }
|
113 |
|
114 |
|
115 | while(self._customPendingCalls.length > 0) {
|
116 | const pendingCall = self._customPendingCalls.shift()
|
117 | const callMethod = pendingCall.callMethod
|
118 | const _url = pendingCall._url
|
119 | const options = pendingCall.options;
|
120 |
|
121 | if(self.metadataRoot && options.params && options.params._program.indexOf(self.metadataRoot) === -1) {
|
122 | options.params._program = self.metadataRoot.replace(/\/?$/, '/') + options.params._program.replace(oldMetadataRoot, '').replace(/^\//, '');
|
123 | }
|
124 |
|
125 | if (options.params) {
|
126 | options.params._debug = self.debug ? 131 : 0;
|
127 | }
|
128 | self.managedRequest(callMethod, _url, options);
|
129 | }
|
130 | }).error(function (err) {
|
131 | throw new h54sError('ajaxError', 'Remote config file cannot be loaded. Http status code: ' + err.status);
|
132 | });
|
133 | }
|
134 |
|
135 |
|
136 | function _setConfig(config) {
|
137 | if(!config) {
|
138 | this._ajax.setTimeout(this.ajaxTimeout);
|
139 | return;
|
140 | } else if(typeof config !== 'object') {
|
141 | throw new h54sError('argumentError', 'First parameter should be config object');
|
142 | }
|
143 |
|
144 |
|
145 | for(let key in config) {
|
146 | if(config.hasOwnProperty(key)) {
|
147 | if((key === 'url' || key === 'loginUrl') && config[key].charAt(0) !== '/') {
|
148 | config[key] = '/' + config[key];
|
149 | }
|
150 | this[key] = config[key];
|
151 | }
|
152 | }
|
153 |
|
154 |
|
155 |
|
156 | if(config.hostUrl) {
|
157 | if(config.hostUrl.charAt(config.hostUrl.length - 1) === '/') {
|
158 | config.hostUrl = config.hostUrl.slice(0, -1);
|
159 | }
|
160 | this.hostUrl = config.hostUrl;
|
161 | if (!this.url.includes(this.hostUrl)) {
|
162 | this.url = config.hostUrl + this.url;
|
163 | }
|
164 | if (!this.loginUrl.includes(this.hostUrl)) {
|
165 | this.loginUrl = config.hostUrl + this.loginUrl;
|
166 | }
|
167 | if (!this.RESTauthLoginUrl.includes(this.hostUrl)) {
|
168 | this.RESTauthLoginUrl = config.hostUrl + this.RESTauthLoginUrl;
|
169 | }
|
170 | }
|
171 |
|
172 | this._ajax.setTimeout(this.ajaxTimeout);
|
173 | }
|
174 | };
|
175 |
|
176 |
|
177 | h54s.version = '__version__';
|
178 |
|
179 |
|
180 | h54s.prototype = require('./methods');
|
181 |
|
182 | h54s.Tables = require('./tables');
|
183 | h54s.Files = require('./files');
|
184 | h54s.SasData = require('./sasData.js');
|
185 |
|
186 | h54s.fromSasDateTime = require('./methods/utils.js').fromSasDateTime;
|
187 | h54s.toSasDateTime = require('./tables/utils.js').toSasDateTime;
|
188 |
|
189 |
|
190 | require('./ie_polyfills.js');
|