1 |
|
2 |
|
3 | import { replaceAll } from "./util/utils";
|
4 |
|
5 |
|
6 |
|
7 | var URLQuery = (function () {
|
8 | function URLQuery() {
|
9 | this._rawQuery = {};
|
10 | }
|
11 | |
12 |
|
13 |
|
14 | URLQuery.prototype.any = function () {
|
15 | return Object.keys(this._rawQuery).length > 0;
|
16 | };
|
17 | |
18 |
|
19 |
|
20 |
|
21 |
|
22 | URLQuery.prototype.set = function (parameterName, parameterValue) {
|
23 | if (parameterName) {
|
24 | if (parameterValue != undefined) {
|
25 | var newValue = Array.isArray(parameterValue) ? parameterValue : parameterValue.toString();
|
26 | this._rawQuery[parameterName] = newValue;
|
27 | }
|
28 | else {
|
29 | delete this._rawQuery[parameterName];
|
30 | }
|
31 | }
|
32 | };
|
33 | |
34 |
|
35 |
|
36 |
|
37 | URLQuery.prototype.get = function (parameterName) {
|
38 | return parameterName ? this._rawQuery[parameterName] : undefined;
|
39 | };
|
40 | |
41 |
|
42 |
|
43 | URLQuery.prototype.toString = function () {
|
44 | var result = "";
|
45 | for (var parameterName in this._rawQuery) {
|
46 | if (result) {
|
47 | result += "&";
|
48 | }
|
49 | var parameterValue = this._rawQuery[parameterName];
|
50 | if (Array.isArray(parameterValue)) {
|
51 | var parameterStrings = [];
|
52 | for (var _i = 0, parameterValue_1 = parameterValue; _i < parameterValue_1.length; _i++) {
|
53 | var parameterValueElement = parameterValue_1[_i];
|
54 | parameterStrings.push(parameterName + "=" + parameterValueElement);
|
55 | }
|
56 | result += parameterStrings.join("&");
|
57 | }
|
58 | else {
|
59 | result += parameterName + "=" + parameterValue;
|
60 | }
|
61 | }
|
62 | return result;
|
63 | };
|
64 | |
65 |
|
66 |
|
67 | URLQuery.parse = function (text) {
|
68 | var result = new URLQuery();
|
69 | if (text) {
|
70 | if (text.startsWith("?")) {
|
71 | text = text.substring(1);
|
72 | }
|
73 | var currentState = "ParameterName";
|
74 | var parameterName = "";
|
75 | var parameterValue = "";
|
76 | for (var i = 0; i < text.length; ++i) {
|
77 | var currentCharacter = text[i];
|
78 | switch (currentState) {
|
79 | case "ParameterName":
|
80 | switch (currentCharacter) {
|
81 | case "=":
|
82 | currentState = "ParameterValue";
|
83 | break;
|
84 | case "&":
|
85 | parameterName = "";
|
86 | parameterValue = "";
|
87 | break;
|
88 | default:
|
89 | parameterName += currentCharacter;
|
90 | break;
|
91 | }
|
92 | break;
|
93 | case "ParameterValue":
|
94 | switch (currentCharacter) {
|
95 | case "&":
|
96 | result.set(parameterName, parameterValue);
|
97 | parameterName = "";
|
98 | parameterValue = "";
|
99 | currentState = "ParameterName";
|
100 | break;
|
101 | default:
|
102 | parameterValue += currentCharacter;
|
103 | break;
|
104 | }
|
105 | break;
|
106 | default:
|
107 | throw new Error("Unrecognized URLQuery parse state: " + currentState);
|
108 | }
|
109 | }
|
110 | if (currentState === "ParameterValue") {
|
111 | result.set(parameterName, parameterValue);
|
112 | }
|
113 | }
|
114 | return result;
|
115 | };
|
116 | return URLQuery;
|
117 | }());
|
118 | export { URLQuery };
|
119 |
|
120 |
|
121 |
|
122 | var URLBuilder = (function () {
|
123 | function URLBuilder() {
|
124 | }
|
125 | |
126 |
|
127 |
|
128 |
|
129 | URLBuilder.prototype.setScheme = function (scheme) {
|
130 | if (!scheme) {
|
131 | this._scheme = undefined;
|
132 | }
|
133 | else {
|
134 | this.set(scheme, "SCHEME");
|
135 | }
|
136 | };
|
137 | |
138 |
|
139 |
|
140 | URLBuilder.prototype.getScheme = function () {
|
141 | return this._scheme;
|
142 | };
|
143 | |
144 |
|
145 |
|
146 |
|
147 | URLBuilder.prototype.setHost = function (host) {
|
148 | if (!host) {
|
149 | this._host = undefined;
|
150 | }
|
151 | else {
|
152 | this.set(host, "SCHEME_OR_HOST");
|
153 | }
|
154 | };
|
155 | |
156 |
|
157 |
|
158 | URLBuilder.prototype.getHost = function () {
|
159 | return this._host;
|
160 | };
|
161 | |
162 |
|
163 |
|
164 |
|
165 | URLBuilder.prototype.setPort = function (port) {
|
166 | if (port == undefined || port === "") {
|
167 | this._port = undefined;
|
168 | }
|
169 | else {
|
170 | this.set(port.toString(), "PORT");
|
171 | }
|
172 | };
|
173 | |
174 |
|
175 |
|
176 | URLBuilder.prototype.getPort = function () {
|
177 | return this._port;
|
178 | };
|
179 | |
180 |
|
181 |
|
182 |
|
183 | URLBuilder.prototype.setPath = function (path) {
|
184 | if (!path) {
|
185 | this._path = undefined;
|
186 | }
|
187 | else {
|
188 | var schemeIndex = path.indexOf("://");
|
189 | if (schemeIndex !== -1) {
|
190 | var schemeStart = path.lastIndexOf("/", schemeIndex);
|
191 |
|
192 |
|
193 | this.set(schemeStart === -1 ? path : path.substr(schemeStart + 1), "SCHEME");
|
194 | }
|
195 | else {
|
196 | this.set(path, "PATH");
|
197 | }
|
198 | }
|
199 | };
|
200 | |
201 |
|
202 |
|
203 |
|
204 | URLBuilder.prototype.appendPath = function (path) {
|
205 | if (path) {
|
206 | var currentPath = this.getPath();
|
207 | if (currentPath) {
|
208 | if (!currentPath.endsWith("/")) {
|
209 | currentPath += "/";
|
210 | }
|
211 | if (path.startsWith("/")) {
|
212 | path = path.substring(1);
|
213 | }
|
214 | path = currentPath + path;
|
215 | }
|
216 | this.set(path, "PATH");
|
217 | }
|
218 | };
|
219 | |
220 |
|
221 |
|
222 | URLBuilder.prototype.getPath = function () {
|
223 | return this._path;
|
224 | };
|
225 | |
226 |
|
227 |
|
228 | URLBuilder.prototype.setQuery = function (query) {
|
229 | if (!query) {
|
230 | this._query = undefined;
|
231 | }
|
232 | else {
|
233 | this._query = URLQuery.parse(query);
|
234 | }
|
235 | };
|
236 | |
237 |
|
238 |
|
239 |
|
240 |
|
241 | URLBuilder.prototype.setQueryParameter = function (queryParameterName, queryParameterValue) {
|
242 | if (queryParameterName) {
|
243 | if (!this._query) {
|
244 | this._query = new URLQuery();
|
245 | }
|
246 | this._query.set(queryParameterName, queryParameterValue);
|
247 | }
|
248 | };
|
249 | |
250 |
|
251 |
|
252 |
|
253 | URLBuilder.prototype.getQueryParameterValue = function (queryParameterName) {
|
254 | return this._query ? this._query.get(queryParameterName) : undefined;
|
255 | };
|
256 | |
257 |
|
258 |
|
259 | URLBuilder.prototype.getQuery = function () {
|
260 | return this._query ? this._query.toString() : undefined;
|
261 | };
|
262 | |
263 |
|
264 |
|
265 | URLBuilder.prototype.set = function (text, startState) {
|
266 | var tokenizer = new URLTokenizer(text, startState);
|
267 | while (tokenizer.next()) {
|
268 | var token = tokenizer.current();
|
269 | if (token) {
|
270 | switch (token.type) {
|
271 | case "SCHEME":
|
272 | this._scheme = token.text || undefined;
|
273 | break;
|
274 | case "HOST":
|
275 | this._host = token.text || undefined;
|
276 | break;
|
277 | case "PORT":
|
278 | this._port = token.text || undefined;
|
279 | break;
|
280 | case "PATH":
|
281 | var tokenPath = token.text || undefined;
|
282 | if (!this._path || this._path === "/" || tokenPath !== "/") {
|
283 | this._path = tokenPath;
|
284 | }
|
285 | break;
|
286 | case "QUERY":
|
287 | this._query = URLQuery.parse(token.text);
|
288 | break;
|
289 | default:
|
290 | throw new Error("Unrecognized URLTokenType: " + token.type);
|
291 | }
|
292 | }
|
293 | }
|
294 | };
|
295 | URLBuilder.prototype.toString = function () {
|
296 | var result = "";
|
297 | if (this._scheme) {
|
298 | result += this._scheme + "://";
|
299 | }
|
300 | if (this._host) {
|
301 | result += this._host;
|
302 | }
|
303 | if (this._port) {
|
304 | result += ":" + this._port;
|
305 | }
|
306 | if (this._path) {
|
307 | if (!this._path.startsWith("/")) {
|
308 | result += "/";
|
309 | }
|
310 | result += this._path;
|
311 | }
|
312 | if (this._query && this._query.any()) {
|
313 | result += "?" + this._query.toString();
|
314 | }
|
315 | return result;
|
316 | };
|
317 | |
318 |
|
319 |
|
320 |
|
321 | URLBuilder.prototype.replaceAll = function (searchValue, replaceValue) {
|
322 | if (searchValue) {
|
323 | this.setScheme(replaceAll(this.getScheme(), searchValue, replaceValue));
|
324 | this.setHost(replaceAll(this.getHost(), searchValue, replaceValue));
|
325 | this.setPort(replaceAll(this.getPort(), searchValue, replaceValue));
|
326 | this.setPath(replaceAll(this.getPath(), searchValue, replaceValue));
|
327 | this.setQuery(replaceAll(this.getQuery(), searchValue, replaceValue));
|
328 | }
|
329 | };
|
330 | URLBuilder.parse = function (text) {
|
331 | var result = new URLBuilder();
|
332 | result.set(text, "SCHEME_OR_HOST");
|
333 | return result;
|
334 | };
|
335 | return URLBuilder;
|
336 | }());
|
337 | export { URLBuilder };
|
338 | var URLToken = (function () {
|
339 | function URLToken(text, type) {
|
340 | this.text = text;
|
341 | this.type = type;
|
342 | }
|
343 | URLToken.scheme = function (text) {
|
344 | return new URLToken(text, "SCHEME");
|
345 | };
|
346 | URLToken.host = function (text) {
|
347 | return new URLToken(text, "HOST");
|
348 | };
|
349 | URLToken.port = function (text) {
|
350 | return new URLToken(text, "PORT");
|
351 | };
|
352 | URLToken.path = function (text) {
|
353 | return new URLToken(text, "PATH");
|
354 | };
|
355 | URLToken.query = function (text) {
|
356 | return new URLToken(text, "QUERY");
|
357 | };
|
358 | return URLToken;
|
359 | }());
|
360 | export { URLToken };
|
361 |
|
362 |
|
363 |
|
364 |
|
365 | export function isAlphaNumericCharacter(character) {
|
366 | var characterCode = character.charCodeAt(0);
|
367 | return ((48 <= characterCode && characterCode <= 57) ||
|
368 | (65 <= characterCode && characterCode <= 90) ||
|
369 | (97 <= characterCode && characterCode <= 122) );
|
370 | }
|
371 |
|
372 |
|
373 |
|
374 | var URLTokenizer = (function () {
|
375 | function URLTokenizer(_text, state) {
|
376 | this._text = _text;
|
377 | this._textLength = _text ? _text.length : 0;
|
378 | this._currentState = state != undefined ? state : "SCHEME_OR_HOST";
|
379 | this._currentIndex = 0;
|
380 | }
|
381 | |
382 |
|
383 |
|
384 |
|
385 | URLTokenizer.prototype.current = function () {
|
386 | return this._currentToken;
|
387 | };
|
388 | |
389 |
|
390 |
|
391 | URLTokenizer.prototype.next = function () {
|
392 | if (!hasCurrentCharacter(this)) {
|
393 | this._currentToken = undefined;
|
394 | }
|
395 | else {
|
396 | switch (this._currentState) {
|
397 | case "SCHEME":
|
398 | nextScheme(this);
|
399 | break;
|
400 | case "SCHEME_OR_HOST":
|
401 | nextSchemeOrHost(this);
|
402 | break;
|
403 | case "HOST":
|
404 | nextHost(this);
|
405 | break;
|
406 | case "PORT":
|
407 | nextPort(this);
|
408 | break;
|
409 | case "PATH":
|
410 | nextPath(this);
|
411 | break;
|
412 | case "QUERY":
|
413 | nextQuery(this);
|
414 | break;
|
415 | default:
|
416 | throw new Error("Unrecognized URLTokenizerState: " + this._currentState);
|
417 | }
|
418 | }
|
419 | return !!this._currentToken;
|
420 | };
|
421 | return URLTokenizer;
|
422 | }());
|
423 | export { URLTokenizer };
|
424 |
|
425 |
|
426 |
|
427 | function readRemaining(tokenizer) {
|
428 | var result = "";
|
429 | if (tokenizer._currentIndex < tokenizer._textLength) {
|
430 | result = tokenizer._text.substring(tokenizer._currentIndex);
|
431 | tokenizer._currentIndex = tokenizer._textLength;
|
432 | }
|
433 | return result;
|
434 | }
|
435 |
|
436 |
|
437 |
|
438 | function hasCurrentCharacter(tokenizer) {
|
439 | return tokenizer._currentIndex < tokenizer._textLength;
|
440 | }
|
441 |
|
442 |
|
443 |
|
444 | function getCurrentCharacter(tokenizer) {
|
445 | return tokenizer._text[tokenizer._currentIndex];
|
446 | }
|
447 |
|
448 |
|
449 |
|
450 |
|
451 | function nextCharacter(tokenizer, step) {
|
452 | if (hasCurrentCharacter(tokenizer)) {
|
453 | if (!step) {
|
454 | step = 1;
|
455 | }
|
456 | tokenizer._currentIndex += step;
|
457 | }
|
458 | }
|
459 |
|
460 |
|
461 |
|
462 |
|
463 | function peekCharacters(tokenizer, charactersToPeek) {
|
464 | var endIndex = tokenizer._currentIndex + charactersToPeek;
|
465 | if (tokenizer._textLength < endIndex) {
|
466 | endIndex = tokenizer._textLength;
|
467 | }
|
468 | return tokenizer._text.substring(tokenizer._currentIndex, endIndex);
|
469 | }
|
470 |
|
471 |
|
472 |
|
473 |
|
474 | function readWhile(tokenizer, condition) {
|
475 | var result = "";
|
476 | while (hasCurrentCharacter(tokenizer)) {
|
477 | var currentCharacter = getCurrentCharacter(tokenizer);
|
478 | if (!condition(currentCharacter)) {
|
479 | break;
|
480 | }
|
481 | else {
|
482 | result += currentCharacter;
|
483 | nextCharacter(tokenizer);
|
484 | }
|
485 | }
|
486 | return result;
|
487 | }
|
488 |
|
489 |
|
490 |
|
491 |
|
492 | function readWhileLetterOrDigit(tokenizer) {
|
493 | return readWhile(tokenizer, function (character) { return isAlphaNumericCharacter(character); });
|
494 | }
|
495 |
|
496 |
|
497 |
|
498 |
|
499 | function readUntilCharacter(tokenizer) {
|
500 | var terminatingCharacters = [];
|
501 | for (var _i = 1; _i < arguments.length; _i++) {
|
502 | terminatingCharacters[_i - 1] = arguments[_i];
|
503 | }
|
504 | return readWhile(tokenizer, function (character) { return terminatingCharacters.indexOf(character) === -1; });
|
505 | }
|
506 | function nextScheme(tokenizer) {
|
507 | var scheme = readWhileLetterOrDigit(tokenizer);
|
508 | tokenizer._currentToken = URLToken.scheme(scheme);
|
509 | if (!hasCurrentCharacter(tokenizer)) {
|
510 | tokenizer._currentState = "DONE";
|
511 | }
|
512 | else {
|
513 | tokenizer._currentState = "HOST";
|
514 | }
|
515 | }
|
516 | function nextSchemeOrHost(tokenizer) {
|
517 | var schemeOrHost = readUntilCharacter(tokenizer, ":", "/", "?");
|
518 | if (!hasCurrentCharacter(tokenizer)) {
|
519 | tokenizer._currentToken = URLToken.host(schemeOrHost);
|
520 | tokenizer._currentState = "DONE";
|
521 | }
|
522 | else if (getCurrentCharacter(tokenizer) === ":") {
|
523 | if (peekCharacters(tokenizer, 3) === "://") {
|
524 | tokenizer._currentToken = URLToken.scheme(schemeOrHost);
|
525 | tokenizer._currentState = "HOST";
|
526 | }
|
527 | else {
|
528 | tokenizer._currentToken = URLToken.host(schemeOrHost);
|
529 | tokenizer._currentState = "PORT";
|
530 | }
|
531 | }
|
532 | else {
|
533 | tokenizer._currentToken = URLToken.host(schemeOrHost);
|
534 | if (getCurrentCharacter(tokenizer) === "/") {
|
535 | tokenizer._currentState = "PATH";
|
536 | }
|
537 | else {
|
538 | tokenizer._currentState = "QUERY";
|
539 | }
|
540 | }
|
541 | }
|
542 | function nextHost(tokenizer) {
|
543 | if (peekCharacters(tokenizer, 3) === "://") {
|
544 | nextCharacter(tokenizer, 3);
|
545 | }
|
546 | var host = readUntilCharacter(tokenizer, ":", "/", "?");
|
547 | tokenizer._currentToken = URLToken.host(host);
|
548 | if (!hasCurrentCharacter(tokenizer)) {
|
549 | tokenizer._currentState = "DONE";
|
550 | }
|
551 | else if (getCurrentCharacter(tokenizer) === ":") {
|
552 | tokenizer._currentState = "PORT";
|
553 | }
|
554 | else if (getCurrentCharacter(tokenizer) === "/") {
|
555 | tokenizer._currentState = "PATH";
|
556 | }
|
557 | else {
|
558 | tokenizer._currentState = "QUERY";
|
559 | }
|
560 | }
|
561 | function nextPort(tokenizer) {
|
562 | if (getCurrentCharacter(tokenizer) === ":") {
|
563 | nextCharacter(tokenizer);
|
564 | }
|
565 | var port = readUntilCharacter(tokenizer, "/", "?");
|
566 | tokenizer._currentToken = URLToken.port(port);
|
567 | if (!hasCurrentCharacter(tokenizer)) {
|
568 | tokenizer._currentState = "DONE";
|
569 | }
|
570 | else if (getCurrentCharacter(tokenizer) === "/") {
|
571 | tokenizer._currentState = "PATH";
|
572 | }
|
573 | else {
|
574 | tokenizer._currentState = "QUERY";
|
575 | }
|
576 | }
|
577 | function nextPath(tokenizer) {
|
578 | var path = readUntilCharacter(tokenizer, "?");
|
579 | tokenizer._currentToken = URLToken.path(path);
|
580 | if (!hasCurrentCharacter(tokenizer)) {
|
581 | tokenizer._currentState = "DONE";
|
582 | }
|
583 | else {
|
584 | tokenizer._currentState = "QUERY";
|
585 | }
|
586 | }
|
587 | function nextQuery(tokenizer) {
|
588 | if (getCurrentCharacter(tokenizer) === "?") {
|
589 | nextCharacter(tokenizer);
|
590 | }
|
591 | var query = readRemaining(tokenizer);
|
592 | tokenizer._currentToken = URLToken.query(query);
|
593 | tokenizer._currentState = "DONE";
|
594 | }
|
595 |
|
\ | No newline at end of file |