Showing
24 changed files
with
4165 additions
and
41 deletions
... | @@ -122,6 +122,7 @@ io.sockets.on('connection', function(socket) { | ... | @@ -122,6 +122,7 @@ io.sockets.on('connection', function(socket) { |
122 | }) | 122 | }) |
123 | }) | 123 | }) |
124 | 124 | ||
125 | -server.listen(PORT, function(){ | 125 | +// 서버 가동(IPv4 형식으로 express 설정) |
126 | +server.listen(PORT, '127.0.0.1', function(){ | ||
126 | console.log(logString+"서버가 시작되었습니다.(Port: "+PORT+")"); | 127 | console.log(logString+"서버가 시작되었습니다.(Port: "+PORT+")"); |
127 | }); | 128 | }); |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
node_modules/is_js/LICENSE
0 → 100644
1 | +The MIT License (MIT) | ||
2 | + | ||
3 | +Copyright (c) 2014-2016 Aras Atasaygin | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | +of this software and associated documentation files (the "Software"), to deal | ||
7 | +in the Software without restriction, including without limitation the rights | ||
8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | +copies of the Software, and to permit persons to whom the Software is | ||
10 | +furnished to do so, subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in all | ||
13 | +copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | +SOFTWARE. |
node_modules/is_js/README.md
0 → 100644
1 | +is.js | ||
2 | +===== | ||
3 | + | ||
4 | +[![JS.ORG](https://img.shields.io/badge/js.org-is-ffb400.svg?style=flat-square)](http://js.org) | ||
5 | + | ||
6 | +####This is a general-purpose check library. | ||
7 | +- No dependencies | ||
8 | +- AMD, Node & browser ready | ||
9 | + | ||
10 | +####Usage: | ||
11 | + | ||
12 | +Node.js: | ||
13 | +``` | ||
14 | +npm install is_js | ||
15 | +``` | ||
16 | + | ||
17 | +Bower: | ||
18 | +``` | ||
19 | +bower install is_js | ||
20 | +``` | ||
21 | + | ||
22 | +Build: | ||
23 | +``` | ||
24 | +npm run build | ||
25 | +``` | ||
26 | + | ||
27 | +Test: | ||
28 | +``` | ||
29 | +npm test | ||
30 | +``` | ||
31 | + | ||
32 | +####Contributing: | ||
33 | +Thanks for considering to contribute. Check [here](CONTRIBUTING.md) | ||
34 | + | ||
35 | +####Contributors: | ||
36 | +Many thanks to our contributors: https://github.com/arasatasaygin/is.js/graphs/contributors | ||
37 | + | ||
38 | +Type checks | ||
39 | +=========== | ||
40 | + | ||
41 | +is.arguments(value:any) | ||
42 | +----------------------- | ||
43 | +####Checks if the given value type is arguments. | ||
44 | +interfaces: not, all, any | ||
45 | + | ||
46 | +```javascript | ||
47 | +var getArguments = function() { | ||
48 | + return arguments; | ||
49 | +}; | ||
50 | +var arguments = getArguments(); | ||
51 | + | ||
52 | +is.arguments(arguments); | ||
53 | +=> true | ||
54 | + | ||
55 | +is.not.arguments({foo: 'bar'}); | ||
56 | +=> true | ||
57 | + | ||
58 | +is.all.arguments(arguments, 'bar'); | ||
59 | +=> false | ||
60 | + | ||
61 | +is.any.arguments(['foo'], arguments); | ||
62 | +=> true | ||
63 | + | ||
64 | +// 'all' and 'any' interfaces can also take array parameter | ||
65 | +is.all.arguments([arguments, 'foo', 'bar']); | ||
66 | +=> false | ||
67 | +``` | ||
68 | + | ||
69 | +is.array(value:any) | ||
70 | +------------------- | ||
71 | +####Checks if the given value type is array. | ||
72 | +interfaces: not, all, any | ||
73 | + | ||
74 | +```javascript | ||
75 | +is.array(['foo', 'bar', 'baz']); | ||
76 | +=> true | ||
77 | + | ||
78 | +is.not.array({foo: 'bar'}); | ||
79 | +=> true | ||
80 | + | ||
81 | +is.all.array(['foo'], 'bar'); | ||
82 | +=> false | ||
83 | + | ||
84 | +is.any.array(['foo'], 'bar'); | ||
85 | +=> true | ||
86 | + | ||
87 | +// 'all' and 'any' interfaces can also take array parameter | ||
88 | +is.all.array([[1, 2], 'foo', 'bar']); | ||
89 | +=> false | ||
90 | +``` | ||
91 | + | ||
92 | +is.boolean(value:any) | ||
93 | +--------------------- | ||
94 | +####Checks if the given value type is boolean. | ||
95 | +interfaces: not, all, any | ||
96 | + | ||
97 | +```javascript | ||
98 | +is.boolean(true); | ||
99 | +=> true | ||
100 | + | ||
101 | +is.not.boolean({foo: 'bar'}); | ||
102 | +=> true | ||
103 | + | ||
104 | +is.all.boolean(true, 'bar'); | ||
105 | +=> false | ||
106 | + | ||
107 | +is.any.boolean(true, 'bar'); | ||
108 | +=> true | ||
109 | + | ||
110 | +// 'all' and 'any' interfaces can also take array parameter | ||
111 | +is.all.boolean([true, 'foo', 'bar']); | ||
112 | +=> false | ||
113 | +``` | ||
114 | + | ||
115 | +is.date(value:any) | ||
116 | +------------------ | ||
117 | +####Checks if the given value type is date. | ||
118 | +interfaces: not, all, any | ||
119 | + | ||
120 | +```javascript | ||
121 | +is.date(new Date()); | ||
122 | +=> true | ||
123 | + | ||
124 | +is.not.date({foo: 'bar'}); | ||
125 | +=> true | ||
126 | + | ||
127 | +is.all.date(new Date(), 'bar'); | ||
128 | +=> false | ||
129 | + | ||
130 | +is.any.date(new Date(), 'bar'); | ||
131 | +=> true | ||
132 | + | ||
133 | +// 'all' and 'any' interfaces can also take array parameter | ||
134 | +is.all.date([new Date(), 'foo', 'bar']); | ||
135 | +=> false | ||
136 | +``` | ||
137 | + | ||
138 | +is.domNode(value:any) | ||
139 | +----------------------------- | ||
140 | +####Checks if the given object is a dom node. | ||
141 | +interfaces: not, all, any | ||
142 | + | ||
143 | +```javascript | ||
144 | +var obj = document.createElement('div'); | ||
145 | +is.domNode(obj); | ||
146 | +=> true | ||
147 | + | ||
148 | +is.domNode({nope: 'nope'}); | ||
149 | +=> false | ||
150 | + | ||
151 | +is.not.domNode({}); | ||
152 | +=> true | ||
153 | + | ||
154 | +is.all.domNode(obj, obj); | ||
155 | +=> true | ||
156 | + | ||
157 | +is.any.domNode(obj, {nope: 'nope'}); | ||
158 | +=> true | ||
159 | + | ||
160 | +// 'all' and 'any' interfaces can also take array parameter | ||
161 | +is.all.domNode([obj, {nope: 'nope'}]); | ||
162 | +=> false | ||
163 | +``` | ||
164 | + | ||
165 | +is.error(value:any) | ||
166 | +------------------- | ||
167 | +####Checks if the given value type is error. | ||
168 | +interfaces: not, all, any | ||
169 | + | ||
170 | +```javascript | ||
171 | +is.error(new Error()); | ||
172 | +=> true | ||
173 | + | ||
174 | +is.not.error({foo: 'bar'}); | ||
175 | +=> true | ||
176 | + | ||
177 | +is.all.error(new Error(), 'bar'); | ||
178 | +=> false | ||
179 | + | ||
180 | +is.any.error(new Error(), 'bar'); | ||
181 | +=> true | ||
182 | + | ||
183 | +// 'all' and 'any' interfaces can also take array parameter | ||
184 | +is.all.error([new Error(), 'foo', 'bar']); | ||
185 | +=> false | ||
186 | +``` | ||
187 | + | ||
188 | +is.function(value:any) | ||
189 | +---------------------- | ||
190 | +####Checks if the given value type is function. | ||
191 | +interfaces: not, all, any | ||
192 | + | ||
193 | +```javascript | ||
194 | +is.function(toString); | ||
195 | +=> true | ||
196 | + | ||
197 | +is.not.function({foo: 'bar'}); | ||
198 | +=> true | ||
199 | + | ||
200 | +is.all.function(toString, 'bar'); | ||
201 | +=> false | ||
202 | + | ||
203 | +is.any.function(toString, 'bar'); | ||
204 | +=> true | ||
205 | + | ||
206 | +// 'all' and 'any' interfaces can also take array parameter | ||
207 | +is.all.function([toString, 'foo', 'bar']); | ||
208 | +=> false | ||
209 | +``` | ||
210 | + | ||
211 | +is.nan(value:any) | ||
212 | +----------------- | ||
213 | +####Checks if the given value type is NaN. | ||
214 | +interfaces: not, all, any | ||
215 | + | ||
216 | +```javascript | ||
217 | +is.nan(NaN); | ||
218 | +=> true | ||
219 | + | ||
220 | +is.not.nan(42); | ||
221 | +=> true | ||
222 | + | ||
223 | +is.all.nan(NaN, 1); | ||
224 | +=> false | ||
225 | + | ||
226 | +is.any.nan(NaN, 2); | ||
227 | +=> true | ||
228 | + | ||
229 | +// 'all' and 'any' interfaces can also take array parameter | ||
230 | +is.all.nan([NaN, 'foo', 1]); | ||
231 | +=> false | ||
232 | +``` | ||
233 | + | ||
234 | +is.null(value:any) | ||
235 | +------------------ | ||
236 | +####Checks if the given value type is null. | ||
237 | +interfaces: not, all, any | ||
238 | + | ||
239 | +```javascript | ||
240 | +is.null(null); | ||
241 | +=> true | ||
242 | + | ||
243 | +is.not.null(42); | ||
244 | +=> true | ||
245 | + | ||
246 | +is.all.null(null, 1); | ||
247 | +=> false | ||
248 | + | ||
249 | +is.any.null(null, 2); | ||
250 | +=> true | ||
251 | + | ||
252 | +// 'all' and 'any' interfaces can also take array parameter | ||
253 | +is.all.null([null, 'foo', 1]); | ||
254 | +=> false | ||
255 | +``` | ||
256 | + | ||
257 | +is.number(value:any) | ||
258 | +-------------------- | ||
259 | +####Checks if the given value type is number. | ||
260 | +interfaces: not, all, any | ||
261 | + | ||
262 | +```javascript | ||
263 | +is.number(42); | ||
264 | +=> true | ||
265 | + | ||
266 | +is.number(NaN); | ||
267 | +=> false | ||
268 | + | ||
269 | +is.not.number('42'); | ||
270 | +=> true | ||
271 | + | ||
272 | +is.all.number('foo', 1); | ||
273 | +=> false | ||
274 | + | ||
275 | +is.any.number({}, 2); | ||
276 | +=> true | ||
277 | + | ||
278 | +// 'all' and 'any' interfaces can also take array parameter | ||
279 | +is.all.number([42, 'foo', 1]); | ||
280 | +=> false | ||
281 | +``` | ||
282 | + | ||
283 | +is.object(value:any) | ||
284 | +-------------------- | ||
285 | +####Checks if the given value type is object. | ||
286 | +interfaces: not, all, any | ||
287 | + | ||
288 | +```javascript | ||
289 | +is.object({foo: 'bar'}); | ||
290 | +=> true | ||
291 | + | ||
292 | +// functions are also returning as true | ||
293 | +is.object(toString); | ||
294 | +=> true | ||
295 | + | ||
296 | +is.not.object('foo'); | ||
297 | +=> true | ||
298 | + | ||
299 | +is.all.object({}, 1); | ||
300 | +=> false | ||
301 | + | ||
302 | +is.any.object({}, 2); | ||
303 | +=> true | ||
304 | + | ||
305 | +// 'all' and 'any' interfaces can also take array parameter | ||
306 | +is.all.object([{}, new Object()]); | ||
307 | +=> true | ||
308 | +``` | ||
309 | + | ||
310 | +is.json(value:any) | ||
311 | +-------------------- | ||
312 | +####Checks if the given value type is pure json object. | ||
313 | +interfaces: not, all, any | ||
314 | + | ||
315 | +```javascript | ||
316 | +is.json({foo: 'bar'}); | ||
317 | +=> true | ||
318 | + | ||
319 | +// functions are returning as false | ||
320 | +is.json(toString); | ||
321 | +=> false | ||
322 | + | ||
323 | +is.not.json([]); | ||
324 | +=> true | ||
325 | + | ||
326 | +is.all.json({}, 1); | ||
327 | +=> false | ||
328 | + | ||
329 | +is.any.json({}, 2); | ||
330 | +=> true | ||
331 | + | ||
332 | +// 'all' and 'any' interfaces can also take array parameter | ||
333 | +is.all.json([{}, {foo: 'bar'}]); | ||
334 | +=> true | ||
335 | +``` | ||
336 | + | ||
337 | +is.regexp(value:any) | ||
338 | +-------------------- | ||
339 | +####Checks if the given value type is RegExp. | ||
340 | +interfaces: not, all, any | ||
341 | + | ||
342 | +```javascript | ||
343 | +is.regexp(/test/); | ||
344 | +=> true | ||
345 | + | ||
346 | +is.not.regexp(['foo']); | ||
347 | +=> true | ||
348 | + | ||
349 | +is.all.regexp(/test/, 1); | ||
350 | +=> false | ||
351 | + | ||
352 | +is.any.regexp(new RegExp('ab+c'), 2); | ||
353 | +=> true | ||
354 | + | ||
355 | +// 'all' and 'any' interfaces can also take array parameter | ||
356 | +is.all.regexp([{}, /test/]); | ||
357 | +=> false | ||
358 | +``` | ||
359 | + | ||
360 | +is.string(value:any) | ||
361 | +-------------------- | ||
362 | +####Checks if the given value type is string. | ||
363 | +interfaces: not, all, any | ||
364 | + | ||
365 | +```javascript | ||
366 | +is.string('foo'); | ||
367 | +=> true | ||
368 | + | ||
369 | +is.not.string(['foo']); | ||
370 | +=> true | ||
371 | + | ||
372 | +is.all.string('foo', 1); | ||
373 | +=> false | ||
374 | + | ||
375 | +is.any.string('foo', 2); | ||
376 | +=> true | ||
377 | + | ||
378 | +// 'all' and 'any' interfaces can also take array parameter | ||
379 | +is.all.string([{}, 'foo']); | ||
380 | +=> false | ||
381 | +``` | ||
382 | + | ||
383 | +is.char(value:any) | ||
384 | +-------------------- | ||
385 | +####Checks if the given value type is char. | ||
386 | +interfaces: not, all, any | ||
387 | + | ||
388 | +```javascript | ||
389 | +is.char('f'); | ||
390 | +=> true | ||
391 | + | ||
392 | +is.not.char(['foo']); | ||
393 | +=> true | ||
394 | + | ||
395 | +is.all.char('f', 1); | ||
396 | +=> false | ||
397 | + | ||
398 | +is.any.char('f', 2); | ||
399 | +=> true | ||
400 | + | ||
401 | +// 'all' and 'any' interfaces can also take array parameter | ||
402 | +is.all.char(['f', 'o', 'o']); | ||
403 | +=> true | ||
404 | +``` | ||
405 | + | ||
406 | +is.undefined(value:any) | ||
407 | +----------------------- | ||
408 | +####Checks if the given value type is undefined. | ||
409 | +interfaces: not, all, any | ||
410 | + | ||
411 | +```javascript | ||
412 | +is.undefined(undefined); | ||
413 | +=> true | ||
414 | + | ||
415 | +is.not.undefined(null); | ||
416 | +=> true | ||
417 | + | ||
418 | +is.all.undefined(undefined, 1); | ||
419 | +=> false | ||
420 | + | ||
421 | +is.any.undefined(undefined, 2); | ||
422 | +=> true | ||
423 | + | ||
424 | +// 'all' and 'any' interfaces can also take array parameter | ||
425 | +is.all.undefined([{}, undefined]); | ||
426 | +=> false | ||
427 | +``` | ||
428 | + | ||
429 | +is.sameType(value:any, other:any) | ||
430 | +--------------------------------- | ||
431 | +####Checks if the given value types are same type. | ||
432 | +interface: not | ||
433 | + | ||
434 | +```javascript | ||
435 | +is.sameType(42, 7); | ||
436 | +=> true | ||
437 | + | ||
438 | +is.sameType(42, '7'); | ||
439 | +=> false | ||
440 | + | ||
441 | +is.not.sameType(42, 7); | ||
442 | +=> false | ||
443 | +``` | ||
444 | + | ||
445 | +is.windowObject(value:any) | ||
446 | +----------------------------- | ||
447 | +####Checks if the given object is window object. | ||
448 | +interfaces: not, all, any | ||
449 | + | ||
450 | +```javascript | ||
451 | +is.windowObject(window); | ||
452 | +=> true | ||
453 | + | ||
454 | +is.windowObject({nope: 'nope'}); | ||
455 | +=> false | ||
456 | + | ||
457 | +is.not.windowObject({}); | ||
458 | +=> true | ||
459 | + | ||
460 | +is.all.windowObject(window, {nope: 'nope'}); | ||
461 | +=> false | ||
462 | + | ||
463 | +is.any.windowObject(window, {nope: 'nope'}); | ||
464 | +=> true | ||
465 | + | ||
466 | +// 'all' and 'any' interfaces can also take array parameter | ||
467 | +is.all.windowObject([window, {nope: 'nope'}]); | ||
468 | +=> false | ||
469 | +``` | ||
470 | + | ||
471 | +Presence checks | ||
472 | +=============== | ||
473 | + | ||
474 | +is.empty(value:array|object|string) | ||
475 | +----------------------------------- | ||
476 | +####Checks if the given value is empty. | ||
477 | +interfaces: not, all, any | ||
478 | + | ||
479 | +```javascript | ||
480 | +is.empty({}); | ||
481 | +=> true | ||
482 | + | ||
483 | +is.empty([]); | ||
484 | +=> true | ||
485 | + | ||
486 | +is.empty(''); | ||
487 | +=> true | ||
488 | + | ||
489 | +is.not.empty(['foo']); | ||
490 | +=> true | ||
491 | + | ||
492 | +is.all.empty('', {}, ['foo']); | ||
493 | +=> false | ||
494 | + | ||
495 | +is.any.empty([], 42); | ||
496 | +=> true | ||
497 | + | ||
498 | +// 'all' and 'any' interfaces can also take array parameter | ||
499 | +is.all.empty([{}, 'foo']); | ||
500 | +=> false | ||
501 | +``` | ||
502 | + | ||
503 | +is.existy(value:any) | ||
504 | +-------------------- | ||
505 | +####Checks if the given value is existy. (not null or undefined) | ||
506 | +interfaces: not, all, any | ||
507 | + | ||
508 | +```javascript | ||
509 | +is.existy({}); | ||
510 | +=> true | ||
511 | + | ||
512 | +is.existy(null); | ||
513 | +=> false | ||
514 | + | ||
515 | +is.not.existy(undefined); | ||
516 | +=> true | ||
517 | + | ||
518 | +is.all.existy(null, ['foo']); | ||
519 | +=> false | ||
520 | + | ||
521 | +is.any.existy(undefined, 42); | ||
522 | +=> true | ||
523 | + | ||
524 | +// 'all' and 'any' interfaces can also take array parameter | ||
525 | +is.all.existy([{}, 'foo']); | ||
526 | +=> true | ||
527 | +``` | ||
528 | + | ||
529 | +is.truthy(value:any) | ||
530 | +-------------------- | ||
531 | +####Checks if the given value is truthy. (existy and not false) | ||
532 | +interfaces: not, all, any | ||
533 | + | ||
534 | +```javascript | ||
535 | +is.truthy(true); | ||
536 | +=> true | ||
537 | + | ||
538 | +is.truthy(null); | ||
539 | +=> false | ||
540 | + | ||
541 | +is.not.truthy(false); | ||
542 | +=> true | ||
543 | + | ||
544 | +is.all.truthy(null, true); | ||
545 | +=> false | ||
546 | + | ||
547 | +is.any.truthy(undefined, true); | ||
548 | +=> true | ||
549 | + | ||
550 | +// 'all' and 'any' interfaces can also take array parameter | ||
551 | +is.all.truthy([{}, true]); | ||
552 | +=> true | ||
553 | +``` | ||
554 | + | ||
555 | +is.falsy(value:any) | ||
556 | +------------------- | ||
557 | +####Checks if the given value is falsy. | ||
558 | +interfaces: not, all, any | ||
559 | + | ||
560 | +```javascript | ||
561 | +is.falsy(false); | ||
562 | +=> true | ||
563 | + | ||
564 | +is.falsy(null); | ||
565 | +=> true | ||
566 | + | ||
567 | +is.not.falsy(true); | ||
568 | +=> true | ||
569 | + | ||
570 | +is.all.falsy(null, false); | ||
571 | +=> true | ||
572 | + | ||
573 | +is.any.falsy(undefined, true); | ||
574 | +=> true | ||
575 | + | ||
576 | +// 'all' and 'any' interfaces can also take array parameter | ||
577 | +is.all.falsy([false, true, undefined]); | ||
578 | +=> false | ||
579 | +``` | ||
580 | + | ||
581 | +is.space(value:any) | ||
582 | +---------------------- | ||
583 | +####Checks if the given value is space. | ||
584 | +interfaces: not, all, any | ||
585 | + | ||
586 | +```javascript | ||
587 | +is.space(' '); | ||
588 | +=> true | ||
589 | + | ||
590 | +is.space('foo'); | ||
591 | +=> false | ||
592 | + | ||
593 | +is.not.space(true); | ||
594 | +=> true | ||
595 | + | ||
596 | +is.all.space(' ', 'foo'); | ||
597 | +=> false | ||
598 | + | ||
599 | +is.any.space(' ', true); | ||
600 | +=> true | ||
601 | + | ||
602 | +// 'all' and 'any' interfaces can also take array parameter | ||
603 | +is.all.space([' ', 'foo', undefined]); | ||
604 | +=> false | ||
605 | +``` | ||
606 | + | ||
607 | +RegExp checks | ||
608 | +============= | ||
609 | + | ||
610 | +is.url(value:any) | ||
611 | +----------------- | ||
612 | +####Checks if the given value matches url regexp. | ||
613 | +interfaces: not, all, any | ||
614 | + | ||
615 | +```javascript | ||
616 | +is.url('http://www.test.com'); | ||
617 | +=> true | ||
618 | + | ||
619 | +is.url('foo'); | ||
620 | +=> false | ||
621 | + | ||
622 | +is.not.url(true); | ||
623 | +=> true | ||
624 | + | ||
625 | +is.all.url('http://www.test.com', 'foo'); | ||
626 | +=> false | ||
627 | + | ||
628 | +is.any.url('http://www.test.com', true); | ||
629 | +=> true | ||
630 | + | ||
631 | +// 'all' and 'any' interfaces can also take array parameter | ||
632 | +is.all.url(['http://www.test.com', 'foo', undefined]); | ||
633 | +=> false | ||
634 | +``` | ||
635 | + | ||
636 | +is.email(value:any) | ||
637 | +------------------- | ||
638 | +####Checks if the given value matches email regexp. | ||
639 | +interfaces: not, all, any | ||
640 | + | ||
641 | +```javascript | ||
642 | +is.email('test@test.com'); | ||
643 | +=> true | ||
644 | + | ||
645 | +is.email('foo'); | ||
646 | +=> false | ||
647 | + | ||
648 | +is.not.email('foo'); | ||
649 | +=> true | ||
650 | + | ||
651 | +is.all.email('test@test.com', 'foo'); | ||
652 | +=> false | ||
653 | + | ||
654 | +is.any.email('test@test.com', 'foo'); | ||
655 | +=> true | ||
656 | + | ||
657 | +// 'all' and 'any' interfaces can also take array parameter | ||
658 | +is.all.email(['test@test.com', 'foo', undefined]); | ||
659 | +=> false | ||
660 | +``` | ||
661 | + | ||
662 | +is.creditCard(value:any) | ||
663 | +------------------------ | ||
664 | +####Checks if the given value matches credit card regexp. | ||
665 | +interfaces: not, all, any | ||
666 | + | ||
667 | +```javascript | ||
668 | +is.creditCard(378282246310005); | ||
669 | +=> true | ||
670 | + | ||
671 | +is.creditCard(123); | ||
672 | +=> false | ||
673 | + | ||
674 | +is.not.creditCard(123); | ||
675 | +=> true | ||
676 | + | ||
677 | +is.all.creditCard(378282246310005, 123); | ||
678 | +=> false | ||
679 | + | ||
680 | +is.any.creditCard(378282246310005, 123); | ||
681 | +=> true | ||
682 | + | ||
683 | +// 'all' and 'any' interfaces can also take array parameter | ||
684 | +is.all.creditCard([378282246310005, 123, undefined]); | ||
685 | +=> false | ||
686 | +``` | ||
687 | + | ||
688 | +is.alphaNumeric(value:any) | ||
689 | +-------------------------- | ||
690 | +####Checks if the given value matches alpha numeric regexp. | ||
691 | +interfaces: not, all, any | ||
692 | + | ||
693 | +```javascript | ||
694 | +is.alphaNumeric('alphaNu3er1k'); | ||
695 | +=> true | ||
696 | + | ||
697 | +is.alphaNumeric('*?'); | ||
698 | +=> false | ||
699 | + | ||
700 | +is.not.alphaNumeric('*?'); | ||
701 | +=> true | ||
702 | + | ||
703 | +is.all.alphaNumeric('alphaNu3er1k', '*?'); | ||
704 | +=> false | ||
705 | + | ||
706 | +is.any.alphaNumeric('alphaNu3er1k', '*?'); | ||
707 | +=> true | ||
708 | + | ||
709 | +// 'all' and 'any' interfaces can also take array parameter | ||
710 | +is.all.alphaNumeric(['alphaNu3er1k', '*?']); | ||
711 | +=> false | ||
712 | +``` | ||
713 | + | ||
714 | +is.timeString(value:any) | ||
715 | +------------------------ | ||
716 | +####Checks if the given value matches time string regexp. | ||
717 | +interfaces: not, all, any | ||
718 | + | ||
719 | +```javascript | ||
720 | +is.timeString('13:45:30'); | ||
721 | +=> true | ||
722 | + | ||
723 | +is.timeString('90:90:90'); | ||
724 | +=> false | ||
725 | + | ||
726 | +is.not.timeString('90:90:90'); | ||
727 | +=> true | ||
728 | + | ||
729 | +is.all.timeString('13:45:30', '90:90:90'); | ||
730 | +=> false | ||
731 | + | ||
732 | +is.any.timeString('13:45:30', '90:90:90'); | ||
733 | +=> true | ||
734 | + | ||
735 | +// 'all' and 'any' interfaces can also take array parameter | ||
736 | +is.all.timeString(['13:45:30', '90:90:90']); | ||
737 | +=> false | ||
738 | +``` | ||
739 | + | ||
740 | +is.dateString(value:any) | ||
741 | +------------------------ | ||
742 | +####Checks if the given value matches date string regexp. | ||
743 | +interfaces: not, all, any | ||
744 | + | ||
745 | +```javascript | ||
746 | +is.dateString('11/11/2011'); | ||
747 | +=> true | ||
748 | + | ||
749 | +is.dateString('10-21-2012'); | ||
750 | +=> true | ||
751 | + | ||
752 | +is.dateString('90/11/2011'); | ||
753 | +=> false | ||
754 | + | ||
755 | +is.not.dateString('90/11/2011'); | ||
756 | +=> true | ||
757 | + | ||
758 | +is.all.dateString('11/11/2011', '90/11/2011'); | ||
759 | +=> false | ||
760 | + | ||
761 | +is.any.dateString('11-11-2011', '90/11/2011'); | ||
762 | +=> true | ||
763 | + | ||
764 | +// 'all' and 'any' interfaces can also take array parameter | ||
765 | +is.all.dateString(['11/11/2011', '90/11/2011']); | ||
766 | +=> false | ||
767 | +``` | ||
768 | + | ||
769 | +is.usZipCode(value:any) | ||
770 | +----------------------- | ||
771 | +####Checks if the given value matches US zip code regexp. | ||
772 | +interfaces: not, all, any | ||
773 | + | ||
774 | +```javascript | ||
775 | +is.usZipCode('02201-1020'); | ||
776 | +=> true | ||
777 | + | ||
778 | +is.usZipCode('123'); | ||
779 | +=> false | ||
780 | + | ||
781 | +is.not.usZipCode('123'); | ||
782 | +=> true | ||
783 | + | ||
784 | +is.all.usZipCode('02201-1020', '123'); | ||
785 | +=> false | ||
786 | + | ||
787 | +is.any.usZipCode('02201-1020', '123'); | ||
788 | +=> true | ||
789 | + | ||
790 | +// 'all' and 'any' interfaces can also take array parameter | ||
791 | +is.all.usZipCode(['02201-1020', '123']); | ||
792 | +=> false | ||
793 | +``` | ||
794 | + | ||
795 | +is.caPostalCode(value:any) | ||
796 | +-------------------------- | ||
797 | +####Checks if the given value matches Canada postal code regexp. | ||
798 | +interfaces: not, all, any | ||
799 | + | ||
800 | +```javascript | ||
801 | +is.caPostalCode('L8V3Y1'); | ||
802 | +=> true | ||
803 | + | ||
804 | +is.caPostalCode('L8V 3Y1'); | ||
805 | +=> true | ||
806 | + | ||
807 | +is.caPostalCode('123'); | ||
808 | +=> false | ||
809 | + | ||
810 | +is.not.caPostalCode('123'); | ||
811 | +=> true | ||
812 | + | ||
813 | +is.all.caPostalCode('L8V3Y1', '123'); | ||
814 | +=> false | ||
815 | + | ||
816 | +is.any.caPostalCode('L8V3Y1', '123'); | ||
817 | +=> true | ||
818 | + | ||
819 | +// 'all' and 'any' interfaces can also take array parameter | ||
820 | +is.all.caPostalCode(['L8V3Y1', '123']); | ||
821 | +=> false | ||
822 | +``` | ||
823 | + | ||
824 | +is.ukPostCode(value:any) | ||
825 | +------------------------ | ||
826 | +####Checks if the given value matches UK post code regexp. | ||
827 | +interfaces: not, all, any | ||
828 | + | ||
829 | +```javascript | ||
830 | +is.ukPostCode('B184BJ'); | ||
831 | +=> true | ||
832 | + | ||
833 | +is.ukPostCode('123'); | ||
834 | +=> false | ||
835 | + | ||
836 | +is.not.ukPostCode('123'); | ||
837 | +=> true | ||
838 | + | ||
839 | +is.all.ukPostCode('B184BJ', '123'); | ||
840 | +=> false | ||
841 | + | ||
842 | +is.any.ukPostCode('B184BJ', '123'); | ||
843 | +=> true | ||
844 | + | ||
845 | +// 'all' and 'any' interfaces can also take array parameter | ||
846 | +is.all.ukPostCode(['B184BJ', '123']); | ||
847 | +=> false | ||
848 | +``` | ||
849 | + | ||
850 | +is.nanpPhone(value:any) | ||
851 | +----------------------- | ||
852 | +####Checks if the given value matches North American numbering plan phone regexp. | ||
853 | +interfaces: not, all, any | ||
854 | + | ||
855 | +```javascript | ||
856 | +is.nanpPhone('609-555-0175'); | ||
857 | +=> true | ||
858 | + | ||
859 | +is.nanpPhone('123'); | ||
860 | +=> false | ||
861 | + | ||
862 | +is.not.nanpPhone('123'); | ||
863 | +=> true | ||
864 | + | ||
865 | +is.all.nanpPhone('609-555-0175', '123'); | ||
866 | +=> false | ||
867 | + | ||
868 | +is.any.nanpPhone('609-555-0175', '123'); | ||
869 | +=> true | ||
870 | + | ||
871 | +// 'all' and 'any' interfaces can also take array parameter | ||
872 | +is.all.nanpPhone(['609-555-0175', '123']); | ||
873 | +=> false | ||
874 | +``` | ||
875 | + | ||
876 | +is.eppPhone(value:any) | ||
877 | +---------------------- | ||
878 | +####Checks if the given value matches extensible provisioning protocol phone regexp. | ||
879 | +interfaces: not, all, any | ||
880 | + | ||
881 | +```javascript | ||
882 | +is.eppPhone('+90.2322456789'); | ||
883 | +=> true | ||
884 | + | ||
885 | +is.eppPhone('123'); | ||
886 | +=> false | ||
887 | + | ||
888 | +is.not.eppPhone('123'); | ||
889 | +=> true | ||
890 | + | ||
891 | +is.all.eppPhone('+90.2322456789', '123'); | ||
892 | +=> false | ||
893 | + | ||
894 | +is.any.eppPhone('+90.2322456789', '123'); | ||
895 | +=> true | ||
896 | + | ||
897 | +// 'all' and 'any' interfaces can also take array parameter | ||
898 | +is.all.eppPhone(['+90.2322456789', '123']); | ||
899 | +=> false | ||
900 | +``` | ||
901 | + | ||
902 | +is.socialSecurityNumber(value:any) | ||
903 | +---------------------------------- | ||
904 | +####Checks if the given value matches social security number regexp. | ||
905 | +interfaces: not, all, any | ||
906 | + | ||
907 | +```javascript | ||
908 | +is.socialSecurityNumber('017-90-7890'); | ||
909 | +=> true | ||
910 | + | ||
911 | +is.socialSecurityNumber('017907890'); | ||
912 | +=> true | ||
913 | + | ||
914 | +is.socialSecurityNumber('123'); | ||
915 | +=> false | ||
916 | + | ||
917 | +is.not.socialSecurityNumber('123'); | ||
918 | +=> true | ||
919 | + | ||
920 | +is.all.socialSecurityNumber('017-90-7890', '123'); | ||
921 | +=> false | ||
922 | + | ||
923 | +is.any.socialSecurityNumber('017907890', '123'); | ||
924 | +=> true | ||
925 | + | ||
926 | +// 'all' and 'any' interfaces can also take array parameter | ||
927 | +is.all.socialSecurityNumber(['017-90-7890', '123']); | ||
928 | +=> false | ||
929 | +``` | ||
930 | + | ||
931 | +is.affirmative(value:any) | ||
932 | +------------------------- | ||
933 | +####Checks if the given value matches affirmative regexp. | ||
934 | +interfaces: not, all, any | ||
935 | + | ||
936 | +```javascript | ||
937 | +is.affirmative('yes'); | ||
938 | +=> true | ||
939 | + | ||
940 | +is.affirmative('no'); | ||
941 | +=> false | ||
942 | + | ||
943 | +is.not.affirmative('no'); | ||
944 | +=> true | ||
945 | + | ||
946 | +is.all.affirmative('yes', 'no'); | ||
947 | +=> false | ||
948 | + | ||
949 | +is.any.affirmative('yes', 'no'); | ||
950 | +=> true | ||
951 | + | ||
952 | +// 'all' and 'any' interfaces can also take array parameter | ||
953 | +is.all.affirmative(['yes', 'y', 'true', 't', 'ok', 'okay']); | ||
954 | +=> true | ||
955 | +``` | ||
956 | + | ||
957 | +is.hexadecimal(value:any) | ||
958 | +------------------------- | ||
959 | +####Checks if the given value matches hexadecimal regexp. | ||
960 | +interfaces: not, all, any | ||
961 | + | ||
962 | +```javascript | ||
963 | +is.hexadecimal('f0f0f0'); | ||
964 | +=> true | ||
965 | + | ||
966 | +is.hexadecimal('0xf0f0f0'); | ||
967 | +=> true | ||
968 | + | ||
969 | +is.hexadecimal(2.5); | ||
970 | +=> false | ||
971 | + | ||
972 | +is.not.hexadecimal('string'); | ||
973 | +=> true | ||
974 | + | ||
975 | +is.all.hexadecimal('ff', 'f50'); | ||
976 | +=> true | ||
977 | + | ||
978 | +is.any.hexadecimal('0xff5500', true); | ||
979 | +=> true | ||
980 | + | ||
981 | +// 'all' and 'any' interfaces can also take array parameter | ||
982 | +is.all.hexadecimal(['fff', '333', 'f50']); | ||
983 | +=> true | ||
984 | +``` | ||
985 | + | ||
986 | +is.hexColor(value:any) | ||
987 | +------------------------- | ||
988 | +####Checks if the given value matches hexcolor regexp. | ||
989 | +interfaces: not, all, any | ||
990 | + | ||
991 | +```javascript | ||
992 | +is.hexColor('#333'); | ||
993 | +=> true | ||
994 | + | ||
995 | +is.hexColor('#3333'); | ||
996 | +=> false | ||
997 | + | ||
998 | +is.not.hexColor(0.5); | ||
999 | +=> true | ||
1000 | + | ||
1001 | +is.all.hexColor('fff', 'f50'); | ||
1002 | +=> true | ||
1003 | + | ||
1004 | +is.any.hexColor('ff5500', 0.5); | ||
1005 | +=> false | ||
1006 | + | ||
1007 | +// 'all' and 'any' interfaces can also take array parameter | ||
1008 | +is.all.hexColor(['fff', '333', 'f50']); | ||
1009 | +=> true | ||
1010 | +``` | ||
1011 | + | ||
1012 | +is.ip(value:any) | ||
1013 | +------------------------- | ||
1014 | +####Checks if the given value matches ip regexp | ||
1015 | +interfaces: not, all, any | ||
1016 | + | ||
1017 | +```javascript | ||
1018 | +is.ip('198.156.23.5'); | ||
1019 | +=> true | ||
1020 | + | ||
1021 | +is.ip('1.2..5'); | ||
1022 | +=> false | ||
1023 | + | ||
1024 | +is.not.ip('8:::::::7'); | ||
1025 | +=> true | ||
1026 | + | ||
1027 | +is.all.ip('0:1::4:ff5:54:987:C', '123.123.123.123'); | ||
1028 | +=> true | ||
1029 | + | ||
1030 | +is.any.ip('123.8.4.3', '0.0.0.0'); | ||
1031 | +=> true | ||
1032 | + | ||
1033 | +// 'all' and 'any' interfaces can also take array parameter | ||
1034 | +is.all.ip(['123.123.23.12', 'A:B:C:D:E:F:0:0']); | ||
1035 | +=> true | ||
1036 | +``` | ||
1037 | + | ||
1038 | +is.ipv4(value:any) | ||
1039 | +------------------------- | ||
1040 | +####Checks if the given value matches ipv4 regexp | ||
1041 | +interfaces: not, all, any | ||
1042 | + | ||
1043 | +```javascript | ||
1044 | +is.ipv4('198.12.3.142'); | ||
1045 | +=> true | ||
1046 | + | ||
1047 | +is.ipv4('1.2..5'); | ||
1048 | +=> false | ||
1049 | + | ||
1050 | +is.not.ipv4('8:::::::7'); | ||
1051 | +=> true | ||
1052 | + | ||
1053 | +is.all.ipv4('198.12.3.142', '123.123.123.123'); | ||
1054 | +=> true | ||
1055 | + | ||
1056 | +is.any.ipv4('255.255.255.255', '850..1.4'); | ||
1057 | +=> true | ||
1058 | + | ||
1059 | +// 'all' and 'any' interfaces can also take array parameter | ||
1060 | +is.all.ipv4(['198.12.3.142', '1.2.3']); | ||
1061 | +=> false | ||
1062 | + | ||
1063 | +``` | ||
1064 | + | ||
1065 | +is.ipv6(value:any) | ||
1066 | +------------------------- | ||
1067 | +####Checks if the given value matches ipv6 regexp | ||
1068 | +interfaces: not, all, any | ||
1069 | + | ||
1070 | +```javascript | ||
1071 | +is.ipv6('2001:DB8:0:0:1::1'); | ||
1072 | +=> true | ||
1073 | + | ||
1074 | +is.ipv6('985.12.3.4'); | ||
1075 | +=> true | ||
1076 | + | ||
1077 | +is.not.ipv6('8:::::::7'); | ||
1078 | +=> true | ||
1079 | + | ||
1080 | +is.all.ipv6('2001:DB8:0:0:1::1', '1:50:198:2::1:2:8'); | ||
1081 | +=> true | ||
1082 | + | ||
1083 | +is.any.ipv6('255.255.255.255', '2001:DB8:0:0:1::1'); | ||
1084 | +=> true | ||
1085 | + | ||
1086 | +// 'all' and 'any' interfaces can also take array parameter | ||
1087 | +is.all.ipv6(['2001:DB8:0:0:1::1', '1.2.3']); | ||
1088 | +=> false | ||
1089 | +``` | ||
1090 | + | ||
1091 | +String checks | ||
1092 | +============= | ||
1093 | + | ||
1094 | +is.include(value:string, target:string) | ||
1095 | +----------------------------------------- | ||
1096 | +####Checks if the given string contains a substring. | ||
1097 | +interface: not | ||
1098 | + | ||
1099 | +```javascript | ||
1100 | +is.include('Some text goes here', 'text'); | ||
1101 | +=> true | ||
1102 | + | ||
1103 | +is.include('test', 'text'); | ||
1104 | +=> false | ||
1105 | + | ||
1106 | +is.not.include('test', 'text'); | ||
1107 | +=> true | ||
1108 | +``` | ||
1109 | + | ||
1110 | +is.upperCase(value:string) | ||
1111 | +-------------------------- | ||
1112 | +####Checks if the given string is UPPERCASE. | ||
1113 | +interfaces: not, all, any | ||
1114 | + | ||
1115 | +```javascript | ||
1116 | +is.upperCase('YEAP'); | ||
1117 | +=> true | ||
1118 | + | ||
1119 | +is.upperCase('nope'); | ||
1120 | +=> false | ||
1121 | + | ||
1122 | +is.not.upperCase('Nope'); | ||
1123 | +=> true | ||
1124 | + | ||
1125 | +is.all.upperCase('YEAP', 'nope'); | ||
1126 | +=> false | ||
1127 | + | ||
1128 | +is.any.upperCase('YEAP', 'nope'); | ||
1129 | +=> true | ||
1130 | + | ||
1131 | +// 'all' and 'any' interfaces can also take array parameter | ||
1132 | +is.all.upperCase(['YEAP', 'ALL UPPERCASE']); | ||
1133 | +=> true | ||
1134 | +``` | ||
1135 | + | ||
1136 | + | ||
1137 | +is.lowerCase(value:string) | ||
1138 | +-------------------------- | ||
1139 | +####Checks if the given string is lowercase. | ||
1140 | +interfaces: not, all, any | ||
1141 | + | ||
1142 | +```javascript | ||
1143 | +is.lowerCase('yeap'); | ||
1144 | +=> true | ||
1145 | + | ||
1146 | +is.lowerCase('NOPE'); | ||
1147 | +=> false | ||
1148 | + | ||
1149 | +is.not.lowerCase('Nope'); | ||
1150 | +=> true | ||
1151 | + | ||
1152 | +is.all.lowerCase('yeap', 'NOPE'); | ||
1153 | +=> false | ||
1154 | + | ||
1155 | +is.any.lowerCase('yeap', 'NOPE'); | ||
1156 | +=> true | ||
1157 | + | ||
1158 | +// 'all' and 'any' interfaces can also take array parameter | ||
1159 | +is.all.lowerCase(['yeap', 'all lowercase']); | ||
1160 | +=> true | ||
1161 | +``` | ||
1162 | + | ||
1163 | +is.startWith(value:string, target:string) | ||
1164 | +------------------------------------------- | ||
1165 | +####Checks if the given string starts with substring. | ||
1166 | +interface: not | ||
1167 | + | ||
1168 | +```javascript | ||
1169 | +is.startWith('yeap', 'ye'); | ||
1170 | +=> true | ||
1171 | + | ||
1172 | +is.startWith('nope', 'ye'); | ||
1173 | +=> false | ||
1174 | + | ||
1175 | +is.not.startWith('nope not that', 'not'); | ||
1176 | +=> true | ||
1177 | +``` | ||
1178 | + | ||
1179 | +is.endWith(value:string, target:string) | ||
1180 | +----------------------------------------- | ||
1181 | +####Checks if the given string ends with substring. | ||
1182 | +interfaces: not | ||
1183 | + | ||
1184 | +```javascript | ||
1185 | +is.endWith('yeap', 'ap'); | ||
1186 | +=> true | ||
1187 | + | ||
1188 | +is.endWith('nope', 'no'); | ||
1189 | +=> false | ||
1190 | + | ||
1191 | +is.not.endWith('nope not that', 'not'); | ||
1192 | +=> true | ||
1193 | + | ||
1194 | +is.endWith('yeap that one', 'one'); | ||
1195 | +=> true | ||
1196 | +``` | ||
1197 | + | ||
1198 | +is.capitalized(value:string) | ||
1199 | +--------------------------------------------- | ||
1200 | +####Checks if the given string is capitalized. | ||
1201 | +interfaces: not, all, any | ||
1202 | + | ||
1203 | +```javascript | ||
1204 | +is.capitalized('Yeap'); | ||
1205 | +=> true | ||
1206 | + | ||
1207 | +is.capitalized('nope'); | ||
1208 | +=> false | ||
1209 | + | ||
1210 | +is.not.capitalized('nope not capitalized'); | ||
1211 | +=> true | ||
1212 | + | ||
1213 | +is.not.capitalized('nope Capitalized'); | ||
1214 | +=> true | ||
1215 | + | ||
1216 | +is.all.capitalized('Yeap', 'All', 'Capitalized'); | ||
1217 | +=> true | ||
1218 | + | ||
1219 | +is.any.capitalized('Yeap', 'some', 'Capitalized'); | ||
1220 | +=> true | ||
1221 | + | ||
1222 | +// 'all' and 'any' interfaces can also take array parameter | ||
1223 | +is.all.capitalized(['Nope', 'not']); | ||
1224 | +=> false | ||
1225 | +``` | ||
1226 | + | ||
1227 | +is.palindrome(value:string) | ||
1228 | +--------------------------------------------- | ||
1229 | +####Checks if the given string is palindrome. | ||
1230 | +interfaces: not, all, any | ||
1231 | + | ||
1232 | +```javascript | ||
1233 | +is.palindrome('testset'); | ||
1234 | +=> true | ||
1235 | + | ||
1236 | +is.palindrome('A man, a plan, a canal - Panama!'); | ||
1237 | +=> true | ||
1238 | + | ||
1239 | +is.palindrome('nope'); | ||
1240 | +=> false | ||
1241 | + | ||
1242 | +is.not.palindrome('nope not palindrome'); | ||
1243 | +=> true | ||
1244 | + | ||
1245 | +is.not.palindrome('tt'); | ||
1246 | +=> false | ||
1247 | + | ||
1248 | +is.all.palindrome('testset', 'tt'); | ||
1249 | +=> true | ||
1250 | + | ||
1251 | +is.any.palindrome('Yeap', 'some', 'testset'); | ||
1252 | +=> true | ||
1253 | + | ||
1254 | +// 'all' and 'any' interfaces can also take array parameter | ||
1255 | +is.all.palindrome(['Nope', 'testset']); | ||
1256 | +=> false | ||
1257 | +``` | ||
1258 | + | ||
1259 | +Arithmetic checks | ||
1260 | +================= | ||
1261 | + | ||
1262 | +is.equal(value:any, other:any) | ||
1263 | +------------------------------ | ||
1264 | +####Checks if the given values are equal. | ||
1265 | +interfaces: not | ||
1266 | + | ||
1267 | +```javascript | ||
1268 | +is.equal(42, 40 + 2); | ||
1269 | +=> true | ||
1270 | + | ||
1271 | +is.equal('yeap', 'yeap'); | ||
1272 | +=> true | ||
1273 | + | ||
1274 | +is.equal(true, true); | ||
1275 | +=> true | ||
1276 | + | ||
1277 | +is.not.equal('yeap', 'nope'); | ||
1278 | +=> true | ||
1279 | +``` | ||
1280 | + | ||
1281 | +is.even(value:number) | ||
1282 | +--------------------- | ||
1283 | +####Checks if the given value is even. | ||
1284 | +interfaces: not, all, any | ||
1285 | + | ||
1286 | +```javascript | ||
1287 | +is.even(42); | ||
1288 | +=> true | ||
1289 | + | ||
1290 | +is.not.even(41); | ||
1291 | +=> true | ||
1292 | + | ||
1293 | +is.all.even(40, 42, 44); | ||
1294 | +=> true | ||
1295 | + | ||
1296 | +is.any.even(39, 42, 43); | ||
1297 | +=> true | ||
1298 | + | ||
1299 | +// 'all' and 'any' interfaces can also take array parameter | ||
1300 | +is.all.even([40, 42, 43]); | ||
1301 | +=> false | ||
1302 | +``` | ||
1303 | + | ||
1304 | +is.odd(value:number) | ||
1305 | +-------------------- | ||
1306 | +####Checks if the given value is odd. | ||
1307 | +interfaces: not, all, any | ||
1308 | + | ||
1309 | +```javascript | ||
1310 | +is.odd(41); | ||
1311 | +=> true | ||
1312 | + | ||
1313 | +is.not.odd(42); | ||
1314 | +=> true | ||
1315 | + | ||
1316 | +is.all.odd(39, 41, 43); | ||
1317 | +=> true | ||
1318 | + | ||
1319 | +is.any.odd(39, 42, 44); | ||
1320 | +=> true | ||
1321 | + | ||
1322 | +// 'all' and 'any' interfaces can also take array parameter | ||
1323 | +is.all.odd([40, 42, 43]); | ||
1324 | +=> false | ||
1325 | +``` | ||
1326 | + | ||
1327 | +is.positive(value:number) | ||
1328 | +------------------------- | ||
1329 | +####Checks if the given value is positive. | ||
1330 | +interfaces: not, all, any | ||
1331 | + | ||
1332 | +```javascript | ||
1333 | +is.positive(41); | ||
1334 | +=> true | ||
1335 | + | ||
1336 | +is.not.positive(-42); | ||
1337 | +=> true | ||
1338 | + | ||
1339 | +is.all.positive(39, 41, 43); | ||
1340 | +=> true | ||
1341 | + | ||
1342 | +is.any.positive(-39, 42, -44); | ||
1343 | +=> true | ||
1344 | + | ||
1345 | +// 'all' and 'any' interfaces can also take array parameter | ||
1346 | +is.all.positive([40, 42, -43]); | ||
1347 | +=> false | ||
1348 | +``` | ||
1349 | + | ||
1350 | +is.negative(value:number) | ||
1351 | +------------------------- | ||
1352 | +####Checks if the given value is negative. | ||
1353 | +interfaces: not, all, any | ||
1354 | + | ||
1355 | +```javascript | ||
1356 | +is.negative(-41); | ||
1357 | +=> true | ||
1358 | + | ||
1359 | +is.not.negative(42); | ||
1360 | +=> true | ||
1361 | + | ||
1362 | +is.all.negative(-39, -41, -43); | ||
1363 | +=> true | ||
1364 | + | ||
1365 | +is.any.negative(-39, 42, 44); | ||
1366 | +=> true | ||
1367 | + | ||
1368 | +// 'all' and 'any' interfaces can also take array parameter | ||
1369 | +is.all.negative([40, 42, -43]); | ||
1370 | +=> false | ||
1371 | +``` | ||
1372 | + | ||
1373 | +is.above(value:number, min:number) | ||
1374 | +--------------------------- | ||
1375 | +####Checks if the given value is above minimum value. | ||
1376 | +interface: not | ||
1377 | + | ||
1378 | +```javascript | ||
1379 | +is.above(41, 30); | ||
1380 | +=> true | ||
1381 | + | ||
1382 | +is.not.above(42, 50); | ||
1383 | +=> true | ||
1384 | +``` | ||
1385 | + | ||
1386 | +is.under(value:number, max:number) | ||
1387 | +--------------------------- | ||
1388 | +####Checks if the given value is under maximum value. | ||
1389 | +interface: not | ||
1390 | + | ||
1391 | +```javascript | ||
1392 | +is.under(30, 35); | ||
1393 | +=> true | ||
1394 | + | ||
1395 | +is.not.under(42, 30); | ||
1396 | +=> true | ||
1397 | +``` | ||
1398 | + | ||
1399 | +is.within(value:number, min:number, max:number) | ||
1400 | +--------------------------------- | ||
1401 | +####Checks if the given value is within minimum and maximum values. | ||
1402 | +interface: not | ||
1403 | + | ||
1404 | +```javascript | ||
1405 | +is.within(30, 20, 40); | ||
1406 | +=> true | ||
1407 | + | ||
1408 | +is.not.within(40, 30, 35); | ||
1409 | +=> true | ||
1410 | +``` | ||
1411 | + | ||
1412 | +is.decimal(value:number) | ||
1413 | +------------------------ | ||
1414 | +####Checks if the given value is decimal. | ||
1415 | +interfaces: not, all, any | ||
1416 | + | ||
1417 | +```javascript | ||
1418 | +is.decimal(41.5); | ||
1419 | +=> true | ||
1420 | + | ||
1421 | +is.not.decimal(42); | ||
1422 | +=> true | ||
1423 | + | ||
1424 | +is.all.decimal(39.5, 41.5, -43.5); | ||
1425 | +=> true | ||
1426 | + | ||
1427 | +is.any.decimal(-39, 42.5, 44); | ||
1428 | +=> true | ||
1429 | + | ||
1430 | +// 'all' and 'any' interfaces can also take array parameter | ||
1431 | +is.all.decimal([40, 42.5, -43]); | ||
1432 | +=> false | ||
1433 | +``` | ||
1434 | + | ||
1435 | +is.integer(value:number) | ||
1436 | +------------------------ | ||
1437 | +####Checks if the given value is integer. | ||
1438 | +interfaces: not, all, any | ||
1439 | + | ||
1440 | +```javascript | ||
1441 | +is.integer(41); | ||
1442 | +=> true | ||
1443 | + | ||
1444 | +is.not.integer(42.5); | ||
1445 | +=> true | ||
1446 | + | ||
1447 | +is.all.integer(39, 41, -43); | ||
1448 | +=> true | ||
1449 | + | ||
1450 | +is.any.integer(-39, 42.5, 44); | ||
1451 | +=> true | ||
1452 | + | ||
1453 | +// 'all' and 'any' interfaces can also take array parameter | ||
1454 | +is.all.integer([40, 42.5, -43]); | ||
1455 | +=> false | ||
1456 | +``` | ||
1457 | + | ||
1458 | +is.finite(value:number) | ||
1459 | +----------------------- | ||
1460 | +####Checks if the given value is finite. | ||
1461 | +interfaces: not, all, any | ||
1462 | + | ||
1463 | +```javascript | ||
1464 | +is.finite(41); | ||
1465 | +=> true | ||
1466 | + | ||
1467 | +is.not.finite(42 / 0); | ||
1468 | +=> true | ||
1469 | + | ||
1470 | +is.all.finite(39, 41, -43); | ||
1471 | +=> true | ||
1472 | + | ||
1473 | +is.any.finite(-39, Infinity, 44); | ||
1474 | +=> true | ||
1475 | + | ||
1476 | +// 'all' and 'any' interfaces can also take array parameter | ||
1477 | +is.all.finite([Infinity, -Infinity, 42.5]); | ||
1478 | +=> false | ||
1479 | +``` | ||
1480 | + | ||
1481 | +is.infinite(value:number) | ||
1482 | +------------------------- | ||
1483 | +####Checks if the given value is infinite. | ||
1484 | +interfaces: not, all, any | ||
1485 | + | ||
1486 | +```javascript | ||
1487 | +is.infinite(Infinity); | ||
1488 | +=> true | ||
1489 | + | ||
1490 | +is.not.infinite(42); | ||
1491 | +=> true | ||
1492 | + | ||
1493 | +is.all.infinite(Infinity, -Infinity, -43 / 0); | ||
1494 | +=> true | ||
1495 | + | ||
1496 | +is.any.infinite(-39, Infinity, 44); | ||
1497 | +=> true | ||
1498 | + | ||
1499 | +// 'all' and 'any' interfaces can also take array parameter | ||
1500 | +is.all.infinite([Infinity, -Infinity, 42.5]); | ||
1501 | +=> false | ||
1502 | +``` | ||
1503 | + | ||
1504 | +Object checks | ||
1505 | +============= | ||
1506 | + | ||
1507 | +is.propertyCount(value:object, count:number) | ||
1508 | +------------------------------------- | ||
1509 | +####Checks if objects' property count is equal to given count. | ||
1510 | +interface: not | ||
1511 | + | ||
1512 | +```javascript | ||
1513 | +is.propertyCount({this: 'is', 'sample': object}, 2); | ||
1514 | +=> true | ||
1515 | + | ||
1516 | +is.propertyCount({this: 'is', 'sample': object}, 3); | ||
1517 | +=> false | ||
1518 | + | ||
1519 | +is.not.propertyCount({}, 2); | ||
1520 | +=> true | ||
1521 | +``` | ||
1522 | + | ||
1523 | +is.propertyDefined(value:object, property:string) | ||
1524 | +------------------------------------------ | ||
1525 | +####Checks if the given property is defined on object. | ||
1526 | +interface: not | ||
1527 | + | ||
1528 | +```javascript | ||
1529 | +is.propertyDefined({yeap: 'yeap'}, 'yeap'); | ||
1530 | +=> true | ||
1531 | + | ||
1532 | +is.propertyDefined({yeap: 'yeap'}, 'nope'); | ||
1533 | +=> false | ||
1534 | + | ||
1535 | +is.not.propertyDefined({}, 'nope'); | ||
1536 | +=> true | ||
1537 | +``` | ||
1538 | + | ||
1539 | +Array checks | ||
1540 | +============ | ||
1541 | + | ||
1542 | +is.inArray(value:any, array) | ||
1543 | +--------------------- | ||
1544 | +####Checks if the given item is in array? | ||
1545 | +interface: not | ||
1546 | +```javascript | ||
1547 | +is.inArray(2, [1, 2, 3]); | ||
1548 | +=> true | ||
1549 | + | ||
1550 | +is.inArray(4, [1, 2, 3]); | ||
1551 | +=> false | ||
1552 | + | ||
1553 | +is.not.inArray(4, [1, 2, 3]); | ||
1554 | +=> true | ||
1555 | +``` | ||
1556 | + | ||
1557 | +is.sorted(value:array, sign:string) | ||
1558 | +---------------------- | ||
1559 | +####Checks if the given array is sorted. Sign is optional parameter. | ||
1560 | +interfaces: not, all, any | ||
1561 | + | ||
1562 | +```javascript | ||
1563 | +is.sorted([1, 2, 3]); | ||
1564 | +=> true | ||
1565 | + | ||
1566 | +is.sorted([1, 2, 4, 3]); | ||
1567 | +=> false | ||
1568 | + | ||
1569 | +is.sorted([1, 1, 2, 2], '>='); | ||
1570 | +=> true | ||
1571 | + | ||
1572 | +is.sorted([1, 2, 3, 4], '>'); | ||
1573 | +=> true | ||
1574 | + | ||
1575 | +is.sorted([4, 3, 3, 1], '<='); | ||
1576 | +=> true | ||
1577 | + | ||
1578 | +is.sorted([4, 3, 2, 1], '<'); | ||
1579 | +=> true | ||
1580 | + | ||
1581 | +is.sorted([1, 2, 3, 3], '>'); | ||
1582 | +=> false | ||
1583 | + | ||
1584 | +is.not.sorted([5, 4, 3]); | ||
1585 | +=> true | ||
1586 | + | ||
1587 | +is.not.sorted([5, 4, 3], '<'); | ||
1588 | +=> false | ||
1589 | + | ||
1590 | +is.all.sorted([1, 2], [3, 4]); | ||
1591 | +=> true | ||
1592 | + | ||
1593 | +is.any.sorted([1, 2], [5, 4]); | ||
1594 | +=> true | ||
1595 | + | ||
1596 | +// 'all' and 'any' interfaces can also take array parameter | ||
1597 | +is.all.sorted([[1, 2], [5, 4]]); | ||
1598 | +=> false | ||
1599 | +``` | ||
1600 | + | ||
1601 | +Environment checks | ||
1602 | +================== | ||
1603 | +####Environment checks are not available as node module. | ||
1604 | + | ||
1605 | +is.ie(range:number|string) | ||
1606 | +------------------- | ||
1607 | +####Checks if current browser is ie. Parameter is optional version range (or number) of browser. | ||
1608 | +interface: not | ||
1609 | + | ||
1610 | +```javascript | ||
1611 | +is.ie(); | ||
1612 | +=> true if current browser is ie | ||
1613 | + | ||
1614 | +is.not.ie(); | ||
1615 | +=> false if current browser is ie | ||
1616 | + | ||
1617 | +// also supports version number | ||
1618 | +is.ie(10); | ||
1619 | +=> true if current version of ie is 10 | ||
1620 | + | ||
1621 | +is.ie('>=10'); | ||
1622 | +=> true if current version of ie is greater than or equal to 10 | ||
1623 | + | ||
1624 | +is.not.ie('<9'); | ||
1625 | +=> true if current version of ie is not less than 9 | ||
1626 | +``` | ||
1627 | + | ||
1628 | +is.chrome(range:number|string) | ||
1629 | +----------- | ||
1630 | +####Checks if current browser is chrome. Parameter is optional version range (or number) of browser. | ||
1631 | +interface: not | ||
1632 | + | ||
1633 | +```javascript | ||
1634 | +is.chrome(); | ||
1635 | +=> true if current browser is chrome | ||
1636 | + | ||
1637 | +is.not.chrome(); | ||
1638 | +=> false if current browser is chrome | ||
1639 | + | ||
1640 | +// also supports version number | ||
1641 | +is.chrome(50); | ||
1642 | +=> true if current version of chrome is 50 | ||
1643 | + | ||
1644 | +is.chrome('>=40'); | ||
1645 | +=> true if current version of chrome is greater than or equal to 40 | ||
1646 | + | ||
1647 | +is.not.chrome('<30'); | ||
1648 | +=> true if current version of chrome is not less than 30 | ||
1649 | +``` | ||
1650 | + | ||
1651 | +is.firefox(range:number|string) | ||
1652 | +------------ | ||
1653 | +####Checks if current browser is firefox. Parameter is optional version range (or number) of browser. | ||
1654 | +interface: not | ||
1655 | + | ||
1656 | +```javascript | ||
1657 | +is.firefox(); | ||
1658 | +=> true if current browser is firefox | ||
1659 | + | ||
1660 | +is.not.firefox(); | ||
1661 | +=> false if current browser is firefox | ||
1662 | + | ||
1663 | +// also supports version number | ||
1664 | +is.firefox(41); | ||
1665 | +=> true if current version of firefox is 41 | ||
1666 | + | ||
1667 | +is.firefox('>=40'); | ||
1668 | +=> true if current version of firefox is greater than or equal to 40 | ||
1669 | + | ||
1670 | +is.not.firefox('<30'); | ||
1671 | +=> true if current version of firefox is not less than 30 | ||
1672 | +``` | ||
1673 | + | ||
1674 | +is.edge(range:number|string) | ||
1675 | +------------ | ||
1676 | +####Checks if current browser is edge. Parameter is optional version range (or number) of browser. | ||
1677 | +interface: not | ||
1678 | + | ||
1679 | +```javascript | ||
1680 | +is.edge(); | ||
1681 | +=> true if current browser is edge | ||
1682 | + | ||
1683 | +is.not.edge(); | ||
1684 | +=> false if current browser is edge | ||
1685 | + | ||
1686 | +// also supports version number | ||
1687 | +is.edge(13); | ||
1688 | +=> true if current version of edge is 13 | ||
1689 | + | ||
1690 | +is.edge('>=12'); | ||
1691 | +=> true if current version of edge is greater than or equal to 12 | ||
1692 | + | ||
1693 | +is.not.edge('<13'); | ||
1694 | +=> true if current version of edge is not less than 13 | ||
1695 | +``` | ||
1696 | + | ||
1697 | +is.opera(range:number|string) | ||
1698 | +---------- | ||
1699 | +####Checks if current browser is opera. Parameter is optional version range (or number) of browser. | ||
1700 | +interface: not | ||
1701 | + | ||
1702 | +```javascript | ||
1703 | +is.opera(); | ||
1704 | +=> true if current browser is opera | ||
1705 | + | ||
1706 | +is.not.opera(); | ||
1707 | +=> false if current browser is opera | ||
1708 | + | ||
1709 | +// also supports version number | ||
1710 | +is.opera(36); | ||
1711 | +=> true if current version of opera is 36 | ||
1712 | + | ||
1713 | +is.opera('>=35'); | ||
1714 | +=> true if current version of opera is greater than or equal to 35 | ||
1715 | + | ||
1716 | +is.not.opera('<20'); | ||
1717 | +=> true if current version of opera is not less than 20 | ||
1718 | +``` | ||
1719 | + | ||
1720 | +is.safari(range:number|string) | ||
1721 | +----------- | ||
1722 | +####Checks if current browser is safari. Parameter is optional version range (or number) of browser. | ||
1723 | +interface: not | ||
1724 | + | ||
1725 | +```javascript | ||
1726 | +is.safari(); | ||
1727 | +=> true if current browser is safari | ||
1728 | + | ||
1729 | +is.not.safari(); | ||
1730 | +=> false if current browser is safari | ||
1731 | + | ||
1732 | +// also supports version number | ||
1733 | +is.safari(9); | ||
1734 | +=> true if current version of safari is 9 | ||
1735 | + | ||
1736 | +is.safari('>=8'); | ||
1737 | +=> true if current version of safari is greater than or equal to 8 | ||
1738 | + | ||
1739 | +is.not.safari('<7'); | ||
1740 | +=> true if current version of safari is not less than 7 | ||
1741 | +``` | ||
1742 | + | ||
1743 | +is.phantom(range:number|string) | ||
1744 | +----------- | ||
1745 | +####Checks if current browser is phantomjs. Parameter is optional version range (or number) of browser. | ||
1746 | +interface: not | ||
1747 | + | ||
1748 | +```javascript | ||
1749 | +is.phantom(); | ||
1750 | +=> true if current browser is phantomjs | ||
1751 | + | ||
1752 | +is.not.phantom(); | ||
1753 | +=> false if current browser is phantomjs | ||
1754 | + | ||
1755 | +// also supports version number | ||
1756 | +is.phantom(2); | ||
1757 | +=> true if current version of phantom is 2 | ||
1758 | + | ||
1759 | +is.phantom('>=1'); | ||
1760 | +=> true if current version of phantomjs is greater than or equal to 1 | ||
1761 | + | ||
1762 | +is.not.phantom('<2'); | ||
1763 | +=> true if current version of phantomjs is not less than 2 | ||
1764 | +``` | ||
1765 | + | ||
1766 | +is.ios() | ||
1767 | +-------- | ||
1768 | +####Checks if current device has ios. | ||
1769 | +interface: not | ||
1770 | + | ||
1771 | +```javascript | ||
1772 | +is.ios(); | ||
1773 | +=> true if current device is iPhone, iPad or iPod | ||
1774 | + | ||
1775 | +is.not.ios(); | ||
1776 | +=> true if current device is not iPhone, iPad or iPod | ||
1777 | +``` | ||
1778 | + | ||
1779 | +is.iphone(range:number|string) | ||
1780 | +----------- | ||
1781 | +####Checks if current device is iPhone. Parameter is optional version range (or number) of browser. | ||
1782 | +interface: not | ||
1783 | + | ||
1784 | +```javascript | ||
1785 | +is.iphone(); | ||
1786 | +=> true if current device is iPhone | ||
1787 | + | ||
1788 | +is.not.iphone(); | ||
1789 | +=> true if current device is not iPhone | ||
1790 | + | ||
1791 | +// also supports version number | ||
1792 | +is.iphone(9); | ||
1793 | +=> true if current version of iPhone is 9 | ||
1794 | + | ||
1795 | +is.iphone('>=7'); | ||
1796 | +=> true if current version of iPhone is greater than or equal to 7 | ||
1797 | + | ||
1798 | +is.not.iphone('<8'); | ||
1799 | +=> true if current version of iPhone is not less than 8 | ||
1800 | +``` | ||
1801 | + | ||
1802 | +is.ipad(range:number|string) | ||
1803 | +--------- | ||
1804 | +####Checks if current device is iPad. | ||
1805 | +interface: not | ||
1806 | + | ||
1807 | +```javascript | ||
1808 | +is.ipad(); | ||
1809 | +=> true if current device is iPad | ||
1810 | + | ||
1811 | +is.not.ipad(); | ||
1812 | +=> true if current device is not iPad | ||
1813 | + | ||
1814 | +// also supports version number | ||
1815 | +is.ipad(9); | ||
1816 | +=> true if current version of iPad is 9 | ||
1817 | + | ||
1818 | +is.ipad('>=7'); | ||
1819 | +=> true if current version of iPad is greater than or equal to 7 | ||
1820 | + | ||
1821 | +is.not.ipad('<8'); | ||
1822 | +=> true if current version of iPad is not less than 8 | ||
1823 | +``` | ||
1824 | + | ||
1825 | +is.ipod(range:number|string) | ||
1826 | +--------- | ||
1827 | +####Checks if current device is iPod. | ||
1828 | +interface: not | ||
1829 | + | ||
1830 | +```javascript | ||
1831 | +is.ipod(); | ||
1832 | +=> true if current device is iPod | ||
1833 | + | ||
1834 | +is.not.ipod(); | ||
1835 | +=> true if current device is not iPod | ||
1836 | + | ||
1837 | +// also supports version number | ||
1838 | +is.ipod(7); | ||
1839 | +=> true if current version of iPod is 7 | ||
1840 | + | ||
1841 | +is.ipod('>=5'); | ||
1842 | +=> true if current version of iPod is greater than or equal to 5 | ||
1843 | + | ||
1844 | +is.not.ipod('<5'); | ||
1845 | +=> true if current version of iPod is not less than 5 | ||
1846 | +``` | ||
1847 | + | ||
1848 | +is.android() | ||
1849 | +------------ | ||
1850 | +####Checks if current device has Android. | ||
1851 | +interface: not | ||
1852 | + | ||
1853 | +```javascript | ||
1854 | +is.android(); | ||
1855 | +=> true if current device has Android OS | ||
1856 | + | ||
1857 | +is.not.android(); | ||
1858 | +=> true if current device has not Android OS | ||
1859 | +``` | ||
1860 | + | ||
1861 | +is.androidPhone() | ||
1862 | +----------------- | ||
1863 | +####Checks if current device is Android phone. | ||
1864 | +interface: not | ||
1865 | + | ||
1866 | +```javascript | ||
1867 | +is.androidPhone(); | ||
1868 | +=> true if current device is Android phone | ||
1869 | + | ||
1870 | +is.not.androidPhone(); | ||
1871 | +=> true if current device is not Android phone | ||
1872 | +``` | ||
1873 | + | ||
1874 | +is.androidTablet() | ||
1875 | +------------------ | ||
1876 | +####Checks if current device is Android tablet. | ||
1877 | +interface: not | ||
1878 | + | ||
1879 | +```javascript | ||
1880 | +is.androidTablet(); | ||
1881 | +=> true if current device is Android tablet | ||
1882 | + | ||
1883 | +is.not.androidTablet(); | ||
1884 | +=> true if current device is not Android tablet | ||
1885 | +``` | ||
1886 | + | ||
1887 | +is.blackberry() | ||
1888 | +--------------- | ||
1889 | +####Checks if current device is Blackberry. | ||
1890 | +interface: not | ||
1891 | + | ||
1892 | +```javascript | ||
1893 | +is.blackberry(); | ||
1894 | +=> true if current device is Blackberry | ||
1895 | + | ||
1896 | +is.not.blackberry(); | ||
1897 | +=> true if current device is not Blackberry | ||
1898 | +``` | ||
1899 | + | ||
1900 | +is.windowsPhone() | ||
1901 | +----------------- | ||
1902 | +####Checks if current device is Windows phone. | ||
1903 | +interface: not | ||
1904 | + | ||
1905 | +```javascript | ||
1906 | +is.windowsPhone(); | ||
1907 | +=> true if current device is Windows phone | ||
1908 | + | ||
1909 | +is.not.windowsPhone(); | ||
1910 | +=> true if current device is not Windows Phone | ||
1911 | +``` | ||
1912 | + | ||
1913 | +is.windowsTablet() | ||
1914 | +------------------ | ||
1915 | +####Checks if current device is Windows tablet. | ||
1916 | +interface: not | ||
1917 | + | ||
1918 | +```javascript | ||
1919 | +is.windowsTablet(); | ||
1920 | +=> true if current device is Windows tablet | ||
1921 | + | ||
1922 | +is.not.windowsTablet(); | ||
1923 | +=> true if current device is not Windows tablet | ||
1924 | +``` | ||
1925 | + | ||
1926 | +is.windows() | ||
1927 | +------------ | ||
1928 | +####Checks if current OS is Windows. | ||
1929 | +interface: not | ||
1930 | + | ||
1931 | +```javascript | ||
1932 | +is.windows(); | ||
1933 | +=> true if current OS is Windows | ||
1934 | + | ||
1935 | +is.not.windows(); | ||
1936 | +=> true if current OS is not Windows | ||
1937 | +``` | ||
1938 | + | ||
1939 | +is.mac() | ||
1940 | +-------- | ||
1941 | +####Checks if current OS is Mac OS X. | ||
1942 | +interface: not | ||
1943 | + | ||
1944 | +```javascript | ||
1945 | +is.mac(); | ||
1946 | +=> true if current OS is Mac OS X | ||
1947 | + | ||
1948 | +is.not.mac(); | ||
1949 | +=> true if current OS is not Mac OS X | ||
1950 | +``` | ||
1951 | + | ||
1952 | +is.linux() | ||
1953 | +---------- | ||
1954 | +####Checks if current OS is linux. | ||
1955 | +interface: not | ||
1956 | + | ||
1957 | +```javascript | ||
1958 | +is.linux(); | ||
1959 | +=> true if current OS is linux | ||
1960 | + | ||
1961 | +is.not.linux(); | ||
1962 | +=> true if current OS is not linux | ||
1963 | +``` | ||
1964 | + | ||
1965 | +is.desktop() | ||
1966 | +------------ | ||
1967 | +####Checks if current device is desktop. | ||
1968 | +interface: not | ||
1969 | + | ||
1970 | +```javascript | ||
1971 | +is.desktop(); | ||
1972 | +=> true if current device is desktop | ||
1973 | + | ||
1974 | +is.not.desktop(); | ||
1975 | +=> true if current device is not desktop | ||
1976 | +``` | ||
1977 | + | ||
1978 | +is.mobile() | ||
1979 | +----------- | ||
1980 | +####Checks if current device is mobile. | ||
1981 | +interface: not | ||
1982 | +iPhone, iPod, Android Phone, Windows Phone, Blackberry. | ||
1983 | +```javascript | ||
1984 | + | ||
1985 | +is.mobile(); | ||
1986 | +=> true if current device is mobile | ||
1987 | + | ||
1988 | +is.not.mobile(); | ||
1989 | +=> true if current device is not mobile | ||
1990 | +``` | ||
1991 | + | ||
1992 | +is.tablet() | ||
1993 | +----------- | ||
1994 | +####Checks if current device is tablet. | ||
1995 | +interface: not | ||
1996 | +iPad, Android Tablet, Windows Tablet | ||
1997 | +```javascript | ||
1998 | + | ||
1999 | +is.tablet(); | ||
2000 | +=> true if current device is tablet | ||
2001 | + | ||
2002 | +is.not.tablet(); | ||
2003 | +=> true if current device is not tablet | ||
2004 | +``` | ||
2005 | + | ||
2006 | +is.online() | ||
2007 | +----------- | ||
2008 | +####Checks if current device is online. | ||
2009 | +interface: not | ||
2010 | + | ||
2011 | +```javascript | ||
2012 | +is.online(); | ||
2013 | +=> true if current device is online | ||
2014 | + | ||
2015 | +is.not.online(); | ||
2016 | +=> true if current device is not online | ||
2017 | +``` | ||
2018 | + | ||
2019 | +is.offline() | ||
2020 | +------------ | ||
2021 | +####Checks if current device is offline. | ||
2022 | +interface: not | ||
2023 | + | ||
2024 | +```javascript | ||
2025 | +is.offline(); | ||
2026 | +=> true if current device is offline | ||
2027 | + | ||
2028 | +is.not.offline(); | ||
2029 | +=> true if current device is not offline | ||
2030 | +``` | ||
2031 | + | ||
2032 | +is.touchDevice() | ||
2033 | +------------ | ||
2034 | +####Checks if current device supports touch. | ||
2035 | +interface: not | ||
2036 | + | ||
2037 | +```javascript | ||
2038 | +is.touchDevice(); | ||
2039 | +=> true if current device supports touch | ||
2040 | + | ||
2041 | +is.not.touchDevice(); | ||
2042 | +=> true if current device does not support touch | ||
2043 | +``` | ||
2044 | + | ||
2045 | +Time checks | ||
2046 | +=========== | ||
2047 | + | ||
2048 | +is.today(value:date) | ||
2049 | +---------------------- | ||
2050 | +####Checks if the given date object indicate today. | ||
2051 | +interfaces: not, all, any | ||
2052 | + | ||
2053 | +```javascript | ||
2054 | +var today = new Date(); | ||
2055 | +is.today(today); | ||
2056 | +=> true | ||
2057 | + | ||
2058 | +var yesterday = new Date(new Date().setDate(new Date().getDate() - 1)); | ||
2059 | +is.today(yesterday); | ||
2060 | +=> false | ||
2061 | + | ||
2062 | +is.not.today(yesterday); | ||
2063 | +=> true | ||
2064 | + | ||
2065 | +is.all.today(today, today); | ||
2066 | +=> true | ||
2067 | + | ||
2068 | +is.any.today(today, yesterday); | ||
2069 | +=> true | ||
2070 | + | ||
2071 | +// 'all' and 'any' interfaces can also take array parameter | ||
2072 | +is.all.today([today, yesterday]); | ||
2073 | +=> false | ||
2074 | +``` | ||
2075 | + | ||
2076 | +is.yesterday(value:date) | ||
2077 | +-------------------------- | ||
2078 | +####Checks if the given date object indicate yesterday. | ||
2079 | +interfaces: not, all, any | ||
2080 | + | ||
2081 | +```javascript | ||
2082 | +var today = new Date(); | ||
2083 | +is.yesterday(today); | ||
2084 | +=> false | ||
2085 | + | ||
2086 | +var yesterday = new Date(new Date().setDate(new Date().getDate() - 1)); | ||
2087 | +is.yesterday(yesterday); | ||
2088 | +=> true | ||
2089 | + | ||
2090 | +is.not.yesterday(today); | ||
2091 | +=> true | ||
2092 | + | ||
2093 | +is.all.yesterday(yesterday, today); | ||
2094 | +=> false | ||
2095 | + | ||
2096 | +is.any.yesterday(today, yesterday); | ||
2097 | +=> true | ||
2098 | + | ||
2099 | +// 'all' and 'any' interfaces can also take array parameter | ||
2100 | +is.all.yesterday([today, yesterday]); | ||
2101 | +=> false | ||
2102 | +``` | ||
2103 | + | ||
2104 | +is.tomorrow(value:date) | ||
2105 | +------------------------- | ||
2106 | +####Checks if the given date object indicate tomorrow. | ||
2107 | +interfaces: not, all, any | ||
2108 | + | ||
2109 | +```javascript | ||
2110 | +var today = new Date(); | ||
2111 | +is.tomorrow(today); | ||
2112 | +=> false | ||
2113 | + | ||
2114 | +var tomorrow = new Date(new Date().setDate(new Date().getDate() + 1)); | ||
2115 | +is.tomorrow(tomorrow); | ||
2116 | +=> true | ||
2117 | + | ||
2118 | +is.not.tomorrow(today); | ||
2119 | +=> true | ||
2120 | + | ||
2121 | +is.all.tomorrow(tomorrow, today); | ||
2122 | +=> false | ||
2123 | + | ||
2124 | +is.any.tomorrow(today, tomorrow); | ||
2125 | +=> true | ||
2126 | + | ||
2127 | +// 'all' and 'any' interfaces can also take array parameter | ||
2128 | +is.all.tomorrow([today, tomorrow]); | ||
2129 | +=> false | ||
2130 | +``` | ||
2131 | + | ||
2132 | +is.past(value:date) | ||
2133 | +--------------------- | ||
2134 | +####Checks if the given date object indicate past. | ||
2135 | +interfaces: not, all, any | ||
2136 | + | ||
2137 | +```javascript | ||
2138 | +var yesterday = new Date(new Date().setDate(new Date().getDate() - 1)); | ||
2139 | +var tomorrow = new Date(new Date().setDate(new Date().getDate() + 1)); | ||
2140 | + | ||
2141 | +is.past(yesterday); | ||
2142 | +=> true | ||
2143 | + | ||
2144 | +is.past(tomorrow); | ||
2145 | +=> false | ||
2146 | + | ||
2147 | +is.not.past(tomorrow); | ||
2148 | +=> true | ||
2149 | + | ||
2150 | +is.all.past(tomorrow, yesterday); | ||
2151 | +=> false | ||
2152 | + | ||
2153 | +is.any.past(yesterday, tomorrow); | ||
2154 | +=> true | ||
2155 | + | ||
2156 | +// 'all' and 'any' interfaces can also take array parameter | ||
2157 | +is.all.past([yesterday, tomorrow]); | ||
2158 | +=> false | ||
2159 | +``` | ||
2160 | + | ||
2161 | +is.future(value:date) | ||
2162 | +----------------------- | ||
2163 | +####Checks if the given date object indicate future. | ||
2164 | +interfaces: not, all, any | ||
2165 | + | ||
2166 | +```javascript | ||
2167 | +var yesterday = new Date(new Date().setDate(new Date().getDate() - 1)); | ||
2168 | +var tomorrow = new Date(new Date().setDate(new Date().getDate() + 1)); | ||
2169 | + | ||
2170 | +is.future(yesterday); | ||
2171 | +=> false | ||
2172 | + | ||
2173 | +is.future(tomorrow); | ||
2174 | +=> true | ||
2175 | + | ||
2176 | +is.not.future(yesterday); | ||
2177 | +=> true | ||
2178 | + | ||
2179 | +is.all.future(tomorrow, yesterday); | ||
2180 | +=> false | ||
2181 | + | ||
2182 | +is.any.future(yesterday, tomorrow); | ||
2183 | +=> true | ||
2184 | + | ||
2185 | +// 'all' and 'any' interfaces can also take array parameter | ||
2186 | +is.all.future([yesterday, tomorrow]); | ||
2187 | +=> false | ||
2188 | +``` | ||
2189 | + | ||
2190 | +is.day(value:date, day:string) | ||
2191 | +------------------------------- | ||
2192 | +####Checks if the given date objects' day equal given dayString parameter. | ||
2193 | +interface: not | ||
2194 | + | ||
2195 | +```javascript | ||
2196 | +var mondayObj = new Date('01/26/2015'); | ||
2197 | +var tuesdayObj = new Date('01/27/2015'); | ||
2198 | +is.day(mondayObj, 'monday'); | ||
2199 | +=> true | ||
2200 | + | ||
2201 | +is.day(mondayObj, 'tuesday'); | ||
2202 | +=> false | ||
2203 | + | ||
2204 | +is.not.day(mondayObj, 'tuesday'); | ||
2205 | +=> true | ||
2206 | +``` | ||
2207 | + | ||
2208 | +is.month(value:date, month:string) | ||
2209 | +----------------------------------- | ||
2210 | +####Checks if the given date objects' month equal given monthString parameter. | ||
2211 | +interface: not | ||
2212 | + | ||
2213 | +```javascript | ||
2214 | +var januaryObj = new Date('01/26/2015'); | ||
2215 | +var februaryObj = new Date('02/26/2015'); | ||
2216 | +is.month(januaryObj, 'january'); | ||
2217 | +=> true | ||
2218 | + | ||
2219 | +is.month(februaryObj, 'january'); | ||
2220 | +=> false | ||
2221 | + | ||
2222 | +is.not.month(februaryObj, 'january'); | ||
2223 | +=> true | ||
2224 | +``` | ||
2225 | + | ||
2226 | +is.year(value:date, year:number) | ||
2227 | +--------------------------------- | ||
2228 | +####Checks if the given date objects' year equal given yearNumber parameter. | ||
2229 | +interface: not | ||
2230 | + | ||
2231 | +```javascript | ||
2232 | +var year2015 = new Date('01/26/2015'); | ||
2233 | +var year2016 = new Date('01/26/2016'); | ||
2234 | +is.year(year2015, 2015); | ||
2235 | +=> true | ||
2236 | + | ||
2237 | +is.year(year2016, 2015); | ||
2238 | +=> false | ||
2239 | + | ||
2240 | +is.not.year(year2016, 2015); | ||
2241 | +=> true | ||
2242 | +``` | ||
2243 | + | ||
2244 | +is.leapYear(value:number) | ||
2245 | +--------------------------------- | ||
2246 | +####Checks if the given year number is a leap year | ||
2247 | +interfaces: not, all, any | ||
2248 | + | ||
2249 | +```javascript | ||
2250 | +is.leapYear(2016); | ||
2251 | +=> true | ||
2252 | + | ||
2253 | +is.leapYear(2015); | ||
2254 | +=> false | ||
2255 | + | ||
2256 | +is.not.leapYear(2015); | ||
2257 | +=> true | ||
2258 | + | ||
2259 | +is.all.leapYear(2015, 2016); | ||
2260 | +=> false | ||
2261 | + | ||
2262 | +is.any.leapYear(2015, 2016); | ||
2263 | +=> true | ||
2264 | + | ||
2265 | +// 'all' and 'any' interfaces can also take array parameter | ||
2266 | +is.all.leapYear([2016, 2080]); | ||
2267 | +=> true | ||
2268 | +``` | ||
2269 | + | ||
2270 | +is.weekend(value:date) | ||
2271 | +------------------------ | ||
2272 | +####Checks if the given date objects' day is weekend. | ||
2273 | +interfaces: not, all, any | ||
2274 | + | ||
2275 | +```javascript | ||
2276 | +var monday = new Date('01/26/2015'); | ||
2277 | +var sunday = new Date('01/25/2015'); | ||
2278 | +var saturday = new Date('01/24/2015'); | ||
2279 | +is.weekend(sunday); | ||
2280 | +=> true | ||
2281 | + | ||
2282 | +is.weekend(monday); | ||
2283 | +=> false | ||
2284 | + | ||
2285 | +is.not.weekend(monday); | ||
2286 | +=> true | ||
2287 | + | ||
2288 | +is.all.weekend(sunday, saturday); | ||
2289 | +=> true | ||
2290 | + | ||
2291 | +is.any.weekend(sunday, saturday, monday); | ||
2292 | +=> true | ||
2293 | + | ||
2294 | +// 'all' and 'any' interfaces can also take array parameter | ||
2295 | +is.all.weekend([sunday, saturday, monday]); | ||
2296 | +=> false | ||
2297 | +``` | ||
2298 | + | ||
2299 | +is.weekday(value:date) | ||
2300 | +------------------------ | ||
2301 | +####Checks if the given date objects' day is weekday. | ||
2302 | +interfaces: not, all, any | ||
2303 | + | ||
2304 | +```javascript | ||
2305 | +var monday = new Date('01/26/2015'); | ||
2306 | +var sunday = new Date('01/25/2015'); | ||
2307 | +var saturday = new Date('01/24/2015'); | ||
2308 | +is.weekday(monday); | ||
2309 | +=> true | ||
2310 | + | ||
2311 | +is.weekday(sunday); | ||
2312 | +=> false | ||
2313 | + | ||
2314 | +is.not.weekday(sunday); | ||
2315 | +=> true | ||
2316 | + | ||
2317 | +is.all.weekday(monday, saturday); | ||
2318 | +=> false | ||
2319 | + | ||
2320 | +is.any.weekday(sunday, saturday, monday); | ||
2321 | +=> true | ||
2322 | + | ||
2323 | +// 'all' and 'any' interfaces can also take array parameter | ||
2324 | +is.all.weekday([sunday, saturday, monday]); | ||
2325 | +=> false | ||
2326 | +``` | ||
2327 | + | ||
2328 | +is.inDateRange(value:date, start:date, end:date) | ||
2329 | +---------------------------------------------------- | ||
2330 | +####Checks if date is within given range. | ||
2331 | +interface: not | ||
2332 | + | ||
2333 | +```javascript | ||
2334 | +var saturday = new Date('01/24/2015'); | ||
2335 | +var sunday = new Date('01/25/2015'); | ||
2336 | +var monday = new Date('01/26/2015'); | ||
2337 | +is.inDateRange(sunday, saturday, monday); | ||
2338 | +=> true | ||
2339 | + | ||
2340 | +is.inDateRange(saturday, sunday, monday); | ||
2341 | +=> false | ||
2342 | + | ||
2343 | +is.not.inDateRange(saturday, sunday, monday); | ||
2344 | +=> true | ||
2345 | +``` | ||
2346 | + | ||
2347 | +is.inLastWeek(value:date) | ||
2348 | +--------------------------- | ||
2349 | +####Checks if the given date is between now and 7 days ago. | ||
2350 | +interface: not | ||
2351 | + | ||
2352 | +```javascript | ||
2353 | +var twoDaysAgo = new Date(new Date().setDate(new Date().getDate() - 2)); | ||
2354 | +var nineDaysAgo = new Date(new Date().setDate(new Date().getDate() - 9)); | ||
2355 | +is.inLastWeek(twoDaysAgo); | ||
2356 | +=> true | ||
2357 | + | ||
2358 | +is.inLastWeek(nineDaysAgo); | ||
2359 | +=> false | ||
2360 | + | ||
2361 | +is.not.inLastWeek(nineDaysAgo); | ||
2362 | +=> true | ||
2363 | +``` | ||
2364 | + | ||
2365 | +is.inLastMonth(value:date) | ||
2366 | +---------------------------- | ||
2367 | +####Checks if the given date is between now and a month ago. | ||
2368 | +interface: not | ||
2369 | + | ||
2370 | +```javascript | ||
2371 | +var tenDaysAgo = new Date(new Date().setDate(new Date().getDate() - 10)); | ||
2372 | +var fortyDaysAgo = new Date(new Date().setDate(new Date().getDate() - 40)); | ||
2373 | +is.inLastMonth(tenDaysAgo); | ||
2374 | +=> true | ||
2375 | + | ||
2376 | +is.inLastMonth(fortyDaysAgo); | ||
2377 | +=> false | ||
2378 | + | ||
2379 | +is.not.inLastMonth(fortyDaysAgo); | ||
2380 | +=> true | ||
2381 | +``` | ||
2382 | + | ||
2383 | +is.inLastYear(value:date) | ||
2384 | +--------------------------- | ||
2385 | +####Checks if the given date is between now and a year ago. | ||
2386 | +interface: not | ||
2387 | + | ||
2388 | +```javascript | ||
2389 | +var twoMonthsAgo = new Date(new Date().setMonth(new Date().getMonth() - 2)); | ||
2390 | +var thirteenMonthsAgo = new Date(new Date().setMonth(new Date().getMonth() - 13)); | ||
2391 | +is.inLastYear(twoMonthsAgo); | ||
2392 | +=> true | ||
2393 | + | ||
2394 | +is.inLastYear(thirteenMonthsAgo); | ||
2395 | +=> false | ||
2396 | + | ||
2397 | +is.not.inLastYear(thirteenMonthsAgo); | ||
2398 | +=> true | ||
2399 | +``` | ||
2400 | + | ||
2401 | +is.inNextWeek(value:date) | ||
2402 | +--------------------------- | ||
2403 | +####Checks if the given date is between now and 7 days later. | ||
2404 | +interface: not | ||
2405 | + | ||
2406 | +```javascript | ||
2407 | +var twoDaysLater = new Date(new Date().setDate(new Date().getDate() + 2)); | ||
2408 | +var nineDaysLater = new Date(new Date().setDate(new Date().getDate() + 9)); | ||
2409 | +is.inNextWeek(twoDaysLater); | ||
2410 | +=> true | ||
2411 | + | ||
2412 | +is.inNextWeek(nineDaysLater); | ||
2413 | +=> false | ||
2414 | + | ||
2415 | +is.not.inNextWeek(nineDaysLater); | ||
2416 | +=> true | ||
2417 | +``` | ||
2418 | + | ||
2419 | +is.inNextMonth(value:date) | ||
2420 | +---------------------------- | ||
2421 | +####Checks if the given date is between now and a month later. | ||
2422 | +interface: not | ||
2423 | + | ||
2424 | +```javascript | ||
2425 | +var tenDaysLater = new Date(new Date().setDate(new Date().getDate() + 10)); | ||
2426 | +var fortyDaysLater = new Date(new Date().setDate(new Date().getDate() + 40)); | ||
2427 | +is.inNextMonth(tenDaysLater); | ||
2428 | +=> true | ||
2429 | + | ||
2430 | +is.inNextMonth(fortyDaysLater); | ||
2431 | +=> false | ||
2432 | + | ||
2433 | +is.not.inNextMonth(fortyDaysLater); | ||
2434 | +=> true | ||
2435 | +``` | ||
2436 | + | ||
2437 | +is.inNextYear(value:date) | ||
2438 | +--------------------------- | ||
2439 | +####Checks if the given date is between now and a year later. | ||
2440 | +interface: not | ||
2441 | + | ||
2442 | +```javascript | ||
2443 | +var twoMonthsLater = new Date(new Date().setMonth(new Date().getMonth() + 2)); | ||
2444 | +var thirteenMonthsLater = new Date(new Date().setMonth(new Date().getMonth() + 13)); | ||
2445 | +is.inNextYear(twoMonthsLater); | ||
2446 | +=> true | ||
2447 | + | ||
2448 | +is.inNextYear(thirteenMonthsLater); | ||
2449 | +=> false | ||
2450 | + | ||
2451 | +is.not.inNextYear(thirteenMonthsLater); | ||
2452 | +=> true | ||
2453 | +``` | ||
2454 | + | ||
2455 | +is.quarterOfYear(value:date, quarter:number) | ||
2456 | +--------------------------------------------- | ||
2457 | +####Checks if the given date is in the parameter quarter. | ||
2458 | +interface: not | ||
2459 | + | ||
2460 | +```javascript | ||
2461 | +var firstQuarter = new Date('01/26/2015'); | ||
2462 | +var secondQuarter = new Date('05/26/2015'); | ||
2463 | +is.quarterOfYear(firstQuarter, 1); | ||
2464 | +=> true | ||
2465 | + | ||
2466 | +is.quarterOfYear(secondQuarter, 1); | ||
2467 | +=> false | ||
2468 | + | ||
2469 | +is.not.quarterOfYear(secondQuarter, 1); | ||
2470 | +=> true | ||
2471 | +``` | ||
2472 | + | ||
2473 | +is.dayLightSavingTime(value:date) | ||
2474 | +-------------------------------------------------- | ||
2475 | +####Checks if the given date is in daylight saving time. | ||
2476 | +interface: not | ||
2477 | + | ||
2478 | +```javascript | ||
2479 | +// For Turkey Time Zone | ||
2480 | +var january1 = new Date('01/01/2015'); | ||
2481 | +var june1 = new Date('06/01/2015'); | ||
2482 | + | ||
2483 | +is.dayLightSavingTime(june1); | ||
2484 | +=> true | ||
2485 | + | ||
2486 | +is.dayLightSavingTime(january1); | ||
2487 | +=> false | ||
2488 | + | ||
2489 | +is.not.dayLightSavingTime(january1); | ||
2490 | +=> true | ||
2491 | +``` | ||
2492 | + | ||
2493 | +Configuration methods | ||
2494 | +===================== | ||
2495 | + | ||
2496 | +is.setNamespace() | ||
2497 | +----------------- | ||
2498 | +Change namespace of library to prevent name collisions. | ||
2499 | + | ||
2500 | +```javascript | ||
2501 | +var customName = is.setNamespace(); | ||
2502 | +customName.odd(3); | ||
2503 | +=> true | ||
2504 | +``` | ||
2505 | + | ||
2506 | +is.setRegexp(value:regexp, name:string) | ||
2507 | +---------------------------------------- | ||
2508 | +Override RegExps if you think they suck. | ||
2509 | + | ||
2510 | +```javascript | ||
2511 | +is.url('https://www.duckduckgo.com'); | ||
2512 | +=> true | ||
2513 | + | ||
2514 | +is.setRegexp(/quack/, 'url'); | ||
2515 | +is.url('quack'); | ||
2516 | +=> true | ||
2517 | +``` |
node_modules/is_js/is.js
0 → 100644
1 | +/*! | ||
2 | + * is.js 0.8.0 | ||
3 | + * Author: Aras Atasaygin | ||
4 | + */ | ||
5 | + | ||
6 | +// AMD with global, Node, or global | ||
7 | +;(function(root, factory) { // eslint-disable-line no-extra-semi | ||
8 | + if (typeof define === 'function' && define.amd) { | ||
9 | + // AMD. Register as an anonymous module. | ||
10 | + define(function() { | ||
11 | + // Also create a global in case some scripts | ||
12 | + // that are loaded still are looking for | ||
13 | + // a global even when an AMD loader is in use. | ||
14 | + return (root.is = factory()); | ||
15 | + }); | ||
16 | + } else if (typeof exports === 'object') { | ||
17 | + // Node. Does not work with strict CommonJS, but | ||
18 | + // only CommonJS-like enviroments that support module.exports, | ||
19 | + // like Node. | ||
20 | + module.exports = factory(); | ||
21 | + } else { | ||
22 | + // Browser globals (root is self) | ||
23 | + root.is = factory(); | ||
24 | + } | ||
25 | +}(this, function() { | ||
26 | + | ||
27 | + // Baseline | ||
28 | + /* -------------------------------------------------------------------------- */ | ||
29 | + | ||
30 | + // define 'is' object and current version | ||
31 | + var is = {}; | ||
32 | + is.VERSION = '0.8.0'; | ||
33 | + | ||
34 | + // define interfaces | ||
35 | + is.not = {}; | ||
36 | + is.all = {}; | ||
37 | + is.any = {}; | ||
38 | + | ||
39 | + // cache some methods to call later on | ||
40 | + var toString = Object.prototype.toString; | ||
41 | + var slice = Array.prototype.slice; | ||
42 | + var hasOwnProperty = Object.prototype.hasOwnProperty; | ||
43 | + | ||
44 | + // helper function which reverses the sense of predicate result | ||
45 | + function not(func) { | ||
46 | + return function() { | ||
47 | + return !func.apply(null, slice.call(arguments)); | ||
48 | + }; | ||
49 | + } | ||
50 | + | ||
51 | + // helper function which call predicate function per parameter and return true if all pass | ||
52 | + function all(func) { | ||
53 | + return function() { | ||
54 | + var params = getParams(arguments); | ||
55 | + var length = params.length; | ||
56 | + for (var i = 0; i < length; i++) { | ||
57 | + if (!func.call(null, params[i])) { | ||
58 | + return false; | ||
59 | + } | ||
60 | + } | ||
61 | + return true; | ||
62 | + }; | ||
63 | + } | ||
64 | + | ||
65 | + // helper function which call predicate function per parameter and return true if any pass | ||
66 | + function any(func) { | ||
67 | + return function() { | ||
68 | + var params = getParams(arguments); | ||
69 | + var length = params.length; | ||
70 | + for (var i = 0; i < length; i++) { | ||
71 | + if (func.call(null, params[i])) { | ||
72 | + return true; | ||
73 | + } | ||
74 | + } | ||
75 | + return false; | ||
76 | + }; | ||
77 | + } | ||
78 | + | ||
79 | + // build a 'comparator' object for various comparison checks | ||
80 | + var comparator = { | ||
81 | + '<': function(a, b) { return a < b; }, | ||
82 | + '<=': function(a, b) { return a <= b; }, | ||
83 | + '>': function(a, b) { return a > b; }, | ||
84 | + '>=': function(a, b) { return a >= b; } | ||
85 | + } | ||
86 | + | ||
87 | + // helper function which compares a version to a range | ||
88 | + function compareVersion(version, range) { | ||
89 | + var string = (range + ''); | ||
90 | + var n = +(string.match(/\d+/) || NaN); | ||
91 | + var op = string.match(/^[<>]=?|/)[0]; | ||
92 | + return comparator[op] ? comparator[op](version, n) : (version == n || n !== n); | ||
93 | + } | ||
94 | + | ||
95 | + // helper function which extracts params from arguments | ||
96 | + function getParams(args) { | ||
97 | + var params = slice.call(args); | ||
98 | + var length = params.length; | ||
99 | + if (length === 1 && is.array(params[0])) { // support array | ||
100 | + params = params[0]; | ||
101 | + } | ||
102 | + return params; | ||
103 | + } | ||
104 | + | ||
105 | + // Type checks | ||
106 | + /* -------------------------------------------------------------------------- */ | ||
107 | + | ||
108 | + // is a given value Arguments? | ||
109 | + is.arguments = function(value) { // fallback check is for IE | ||
110 | + return toString.call(value) === '[object Arguments]' || | ||
111 | + (value != null && typeof value === 'object' && 'callee' in value); | ||
112 | + }; | ||
113 | + | ||
114 | + // is a given value Array? | ||
115 | + is.array = Array.isArray || function(value) { // check native isArray first | ||
116 | + return toString.call(value) === '[object Array]'; | ||
117 | + }; | ||
118 | + | ||
119 | + // is a given value Boolean? | ||
120 | + is.boolean = function(value) { | ||
121 | + return value === true || value === false || toString.call(value) === '[object Boolean]'; | ||
122 | + }; | ||
123 | + | ||
124 | + // is a given value Char? | ||
125 | + is.char = function(value) { | ||
126 | + return is.string(value) && value.length === 1; | ||
127 | + }; | ||
128 | + | ||
129 | + // is a given value Date Object? | ||
130 | + is.date = function(value) { | ||
131 | + return toString.call(value) === '[object Date]'; | ||
132 | + }; | ||
133 | + | ||
134 | + // is a given object a DOM node? | ||
135 | + is.domNode = function(object) { | ||
136 | + return is.object(object) && object.nodeType > 0; | ||
137 | + }; | ||
138 | + | ||
139 | + // is a given value Error object? | ||
140 | + is.error = function(value) { | ||
141 | + return toString.call(value) === '[object Error]'; | ||
142 | + }; | ||
143 | + | ||
144 | + // is a given value function? | ||
145 | + is['function'] = function(value) { // fallback check is for IE | ||
146 | + return toString.call(value) === '[object Function]' || typeof value === 'function'; | ||
147 | + }; | ||
148 | + | ||
149 | + // is given value a pure JSON object? | ||
150 | + is.json = function(value) { | ||
151 | + return toString.call(value) === '[object Object]'; | ||
152 | + }; | ||
153 | + | ||
154 | + // is a given value NaN? | ||
155 | + is.nan = function(value) { // NaN is number :) Also it is the only value which does not equal itself | ||
156 | + return value !== value; | ||
157 | + }; | ||
158 | + | ||
159 | + // is a given value null? | ||
160 | + is['null'] = function(value) { | ||
161 | + return value === null; | ||
162 | + }; | ||
163 | + | ||
164 | + // is a given value number? | ||
165 | + is.number = function(value) { | ||
166 | + return is.not.nan(value) && toString.call(value) === '[object Number]'; | ||
167 | + }; | ||
168 | + | ||
169 | + // is a given value object? | ||
170 | + is.object = function(value) { | ||
171 | + return Object(value) === value; | ||
172 | + }; | ||
173 | + | ||
174 | + // is a given value RegExp? | ||
175 | + is.regexp = function(value) { | ||
176 | + return toString.call(value) === '[object RegExp]'; | ||
177 | + }; | ||
178 | + | ||
179 | + // are given values same type? | ||
180 | + // prevent NaN, Number same type check | ||
181 | + is.sameType = function(value, other) { | ||
182 | + var tag = toString.call(value); | ||
183 | + if (tag !== toString.call(other)) { | ||
184 | + return false; | ||
185 | + } | ||
186 | + if (tag === '[object Number]') { | ||
187 | + return !is.any.nan(value, other) || is.all.nan(value, other); | ||
188 | + } | ||
189 | + return true; | ||
190 | + }; | ||
191 | + // sameType method does not support 'all' and 'any' interfaces | ||
192 | + is.sameType.api = ['not']; | ||
193 | + | ||
194 | + // is a given value String? | ||
195 | + is.string = function(value) { | ||
196 | + return toString.call(value) === '[object String]'; | ||
197 | + }; | ||
198 | + | ||
199 | + // is a given value undefined? | ||
200 | + is.undefined = function(value) { | ||
201 | + return value === void 0; | ||
202 | + }; | ||
203 | + | ||
204 | + // is a given value window? | ||
205 | + // setInterval method is only available for window object | ||
206 | + is.windowObject = function(value) { | ||
207 | + return value != null && typeof value === 'object' && 'setInterval' in value; | ||
208 | + }; | ||
209 | + | ||
210 | + // Presence checks | ||
211 | + /* -------------------------------------------------------------------------- */ | ||
212 | + | ||
213 | + //is a given value empty? Objects, arrays, strings | ||
214 | + is.empty = function(value) { | ||
215 | + if (is.object(value)) { | ||
216 | + var length = Object.getOwnPropertyNames(value).length; | ||
217 | + if (length === 0 || (length === 1 && is.array(value)) || | ||
218 | + (length === 2 && is.arguments(value))) { | ||
219 | + return true; | ||
220 | + } | ||
221 | + return false; | ||
222 | + } | ||
223 | + return value === ''; | ||
224 | + }; | ||
225 | + | ||
226 | + // is a given value existy? | ||
227 | + is.existy = function(value) { | ||
228 | + return value != null; | ||
229 | + }; | ||
230 | + | ||
231 | + // is a given value falsy? | ||
232 | + is.falsy = function(value) { | ||
233 | + return !value; | ||
234 | + }; | ||
235 | + | ||
236 | + // is a given value truthy? | ||
237 | + is.truthy = not(is.falsy); | ||
238 | + | ||
239 | + // Arithmetic checks | ||
240 | + /* -------------------------------------------------------------------------- */ | ||
241 | + | ||
242 | + // is a given number above minimum parameter? | ||
243 | + is.above = function(n, min) { | ||
244 | + return is.all.number(n, min) && n > min; | ||
245 | + }; | ||
246 | + // above method does not support 'all' and 'any' interfaces | ||
247 | + is.above.api = ['not']; | ||
248 | + | ||
249 | + // is a given number decimal? | ||
250 | + is.decimal = function(n) { | ||
251 | + return is.number(n) && n % 1 !== 0; | ||
252 | + }; | ||
253 | + | ||
254 | + // are given values equal? supports numbers, strings, regexes, booleans | ||
255 | + // TODO: Add object and array support | ||
256 | + is.equal = function(value, other) { | ||
257 | + // check 0 and -0 equity with Infinity and -Infinity | ||
258 | + if (is.all.number(value, other)) { | ||
259 | + return value === other && 1 / value === 1 / other; | ||
260 | + } | ||
261 | + // check regexes as strings too | ||
262 | + if (is.all.string(value, other) || is.all.regexp(value, other)) { | ||
263 | + return '' + value === '' + other; | ||
264 | + } | ||
265 | + if (is.all.boolean(value, other)) { | ||
266 | + return value === other; | ||
267 | + } | ||
268 | + return false; | ||
269 | + }; | ||
270 | + // equal method does not support 'all' and 'any' interfaces | ||
271 | + is.equal.api = ['not']; | ||
272 | + | ||
273 | + // is a given number even? | ||
274 | + is.even = function(n) { | ||
275 | + return is.number(n) && n % 2 === 0; | ||
276 | + }; | ||
277 | + | ||
278 | + // is a given number finite? | ||
279 | + is.finite = isFinite || function(n) { | ||
280 | + return is.not.infinite(n) && is.not.nan(n); | ||
281 | + }; | ||
282 | + | ||
283 | + // is a given number infinite? | ||
284 | + is.infinite = function(n) { | ||
285 | + return n === Infinity || n === -Infinity; | ||
286 | + }; | ||
287 | + | ||
288 | + // is a given number integer? | ||
289 | + is.integer = function(n) { | ||
290 | + return is.number(n) && n % 1 === 0; | ||
291 | + }; | ||
292 | + | ||
293 | + // is a given number negative? | ||
294 | + is.negative = function(n) { | ||
295 | + return is.number(n) && n < 0; | ||
296 | + }; | ||
297 | + | ||
298 | + // is a given number odd? | ||
299 | + is.odd = function(n) { | ||
300 | + return is.number(n) && n % 2 === 1; | ||
301 | + }; | ||
302 | + | ||
303 | + // is a given number positive? | ||
304 | + is.positive = function(n) { | ||
305 | + return is.number(n) && n > 0; | ||
306 | + }; | ||
307 | + | ||
308 | + // is a given number above maximum parameter? | ||
309 | + is.under = function(n, max) { | ||
310 | + return is.all.number(n, max) && n < max; | ||
311 | + }; | ||
312 | + // least method does not support 'all' and 'any' interfaces | ||
313 | + is.under.api = ['not']; | ||
314 | + | ||
315 | + // is a given number within minimum and maximum parameters? | ||
316 | + is.within = function(n, min, max) { | ||
317 | + return is.all.number(n, min, max) && n > min && n < max; | ||
318 | + }; | ||
319 | + // within method does not support 'all' and 'any' interfaces | ||
320 | + is.within.api = ['not']; | ||
321 | + | ||
322 | + // Regexp checks | ||
323 | + /* -------------------------------------------------------------------------- */ | ||
324 | + // Steven Levithan, Jan Goyvaerts: Regular Expressions Cookbook | ||
325 | + // Scott Gonzalez: Email address validation | ||
326 | + | ||
327 | + // dateString match m/d/yy and mm/dd/yyyy, allowing any combination of one or two digits for the day and month, and two or four digits for the year | ||
328 | + // eppPhone match extensible provisioning protocol format | ||
329 | + // nanpPhone match north american number plan format | ||
330 | + // time match hours, minutes, and seconds, 24-hour clock | ||
331 | + var regexes = { | ||
332 | + affirmative: /^(?:1|t(?:rue)?|y(?:es)?|ok(?:ay)?)$/, | ||
333 | + alphaNumeric: /^[A-Za-z0-9]+$/, | ||
334 | + caPostalCode: /^(?!.*[DFIOQU])[A-VXY][0-9][A-Z]\s?[0-9][A-Z][0-9]$/, | ||
335 | + creditCard: /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/, | ||
336 | + dateString: /^(1[0-2]|0?[1-9])([\/-])(3[01]|[12][0-9]|0?[1-9])(?:\2)(?:[0-9]{2})?[0-9]{2}$/, | ||
337 | + email: /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i, // eslint-disable-line no-control-regex | ||
338 | + eppPhone: /^\+[0-9]{1,3}\.[0-9]{4,14}(?:x.+)?$/, | ||
339 | + hexadecimal: /^(?:0x)?[0-9a-fA-F]+$/, | ||
340 | + hexColor: /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, | ||
341 | + ipv4: /^(?:(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/, | ||
342 | + ipv6: /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i, | ||
343 | + nanpPhone: /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/, | ||
344 | + socialSecurityNumber: /^(?!000|666)[0-8][0-9]{2}-?(?!00)[0-9]{2}-?(?!0000)[0-9]{4}$/, | ||
345 | + timeString: /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$/, | ||
346 | + ukPostCode: /^[A-Z]{1,2}[0-9RCHNQ][0-9A-Z]?\s?[0-9][ABD-HJLNP-UW-Z]{2}$|^[A-Z]{2}-?[0-9]{4}$/, | ||
347 | + url: /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/i, | ||
348 | + usZipCode: /^[0-9]{5}(?:-[0-9]{4})?$/ | ||
349 | + }; | ||
350 | + | ||
351 | + function regexpCheck(regexp, regexes) { | ||
352 | + is[regexp] = function(value) { | ||
353 | + return regexes[regexp].test(value); | ||
354 | + }; | ||
355 | + } | ||
356 | + | ||
357 | + // create regexp checks methods from 'regexes' object | ||
358 | + for (var regexp in regexes) { | ||
359 | + if (regexes.hasOwnProperty(regexp)) { | ||
360 | + regexpCheck(regexp, regexes); | ||
361 | + } | ||
362 | + } | ||
363 | + | ||
364 | + // simplify IP checks by calling the regex helpers for IPv4 and IPv6 | ||
365 | + is.ip = function(value) { | ||
366 | + return is.ipv4(value) || is.ipv6(value); | ||
367 | + }; | ||
368 | + | ||
369 | + // String checks | ||
370 | + /* -------------------------------------------------------------------------- */ | ||
371 | + | ||
372 | + // is a given string or sentence capitalized? | ||
373 | + is.capitalized = function(string) { | ||
374 | + if (is.not.string(string)) { | ||
375 | + return false; | ||
376 | + } | ||
377 | + var words = string.split(' '); | ||
378 | + for (var i = 0; i < words.length; i++) { | ||
379 | + var word = words[i]; | ||
380 | + if (word.length) { | ||
381 | + var chr = word.charAt(0); | ||
382 | + if (chr !== chr.toUpperCase()) { | ||
383 | + return false; | ||
384 | + } | ||
385 | + } | ||
386 | + } | ||
387 | + return true; | ||
388 | + }; | ||
389 | + | ||
390 | + // is string end with a given target parameter? | ||
391 | + is.endWith = function(string, target) { | ||
392 | + if (is.not.string(string)) { | ||
393 | + return false; | ||
394 | + } | ||
395 | + target += ''; | ||
396 | + var position = string.length - target.length; | ||
397 | + return position >= 0 && string.indexOf(target, position) === position; | ||
398 | + }; | ||
399 | + // endWith method does not support 'all' and 'any' interfaces | ||
400 | + is.endWith.api = ['not']; | ||
401 | + | ||
402 | + // is a given string include parameter target? | ||
403 | + is.include = function(string, target) { | ||
404 | + return string.indexOf(target) > -1; | ||
405 | + }; | ||
406 | + // include method does not support 'all' and 'any' interfaces | ||
407 | + is.include.api = ['not']; | ||
408 | + | ||
409 | + // is a given string all lowercase? | ||
410 | + is.lowerCase = function(string) { | ||
411 | + return is.string(string) && string === string.toLowerCase(); | ||
412 | + }; | ||
413 | + | ||
414 | + // is a given string palindrome? | ||
415 | + is.palindrome = function(string) { | ||
416 | + if (is.not.string(string)) { | ||
417 | + return false; | ||
418 | + } | ||
419 | + string = string.replace(/[^a-zA-Z0-9]+/g, '').toLowerCase(); | ||
420 | + var length = string.length - 1; | ||
421 | + for (var i = 0, half = Math.floor(length / 2); i <= half; i++) { | ||
422 | + if (string.charAt(i) !== string.charAt(length - i)) { | ||
423 | + return false; | ||
424 | + } | ||
425 | + } | ||
426 | + return true; | ||
427 | + }; | ||
428 | + | ||
429 | + // is a given value space? | ||
430 | + // horizantal tab: 9, line feed: 10, vertical tab: 11, form feed: 12, carriage return: 13, space: 32 | ||
431 | + is.space = function(value) { | ||
432 | + if (is.not.char(value)) { | ||
433 | + return false; | ||
434 | + } | ||
435 | + var charCode = value.charCodeAt(0); | ||
436 | + return (charCode > 8 && charCode < 14) || charCode === 32; | ||
437 | + }; | ||
438 | + | ||
439 | + // is string start with a given target parameter? | ||
440 | + is.startWith = function(string, target) { | ||
441 | + return is.string(string) && string.indexOf(target) === 0; | ||
442 | + }; | ||
443 | + // startWith method does not support 'all' and 'any' interfaces | ||
444 | + is.startWith.api = ['not']; | ||
445 | + | ||
446 | + // is a given string all uppercase? | ||
447 | + is.upperCase = function(string) { | ||
448 | + return is.string(string) && string === string.toUpperCase(); | ||
449 | + }; | ||
450 | + | ||
451 | + // Time checks | ||
452 | + /* -------------------------------------------------------------------------- */ | ||
453 | + | ||
454 | + var days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; | ||
455 | + var months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; | ||
456 | + | ||
457 | + // is a given dates day equal given day parameter? | ||
458 | + is.day = function(date, day) { | ||
459 | + return is.date(date) && day.toLowerCase() === days[date.getDay()]; | ||
460 | + }; | ||
461 | + // day method does not support 'all' and 'any' interfaces | ||
462 | + is.day.api = ['not']; | ||
463 | + | ||
464 | + // is a given date in daylight saving time? | ||
465 | + is.dayLightSavingTime = function(date) { | ||
466 | + var january = new Date(date.getFullYear(), 0, 1); | ||
467 | + var july = new Date(date.getFullYear(), 6, 1); | ||
468 | + var stdTimezoneOffset = Math.max(january.getTimezoneOffset(), july.getTimezoneOffset()); | ||
469 | + return date.getTimezoneOffset() < stdTimezoneOffset; | ||
470 | + }; | ||
471 | + | ||
472 | + // is a given date future? | ||
473 | + is.future = function(date) { | ||
474 | + var now = new Date(); | ||
475 | + return is.date(date) && date.getTime() > now.getTime(); | ||
476 | + }; | ||
477 | + | ||
478 | + // is date within given range? | ||
479 | + is.inDateRange = function(date, start, end) { | ||
480 | + if (is.not.date(date) || is.not.date(start) || is.not.date(end)) { | ||
481 | + return false; | ||
482 | + } | ||
483 | + var stamp = date.getTime(); | ||
484 | + return stamp > start.getTime() && stamp < end.getTime(); | ||
485 | + }; | ||
486 | + // inDateRange method does not support 'all' and 'any' interfaces | ||
487 | + is.inDateRange.api = ['not']; | ||
488 | + | ||
489 | + // is a given date in last month range? | ||
490 | + is.inLastMonth = function(date) { | ||
491 | + return is.inDateRange(date, new Date(new Date().setMonth(new Date().getMonth() - 1)), new Date()); | ||
492 | + }; | ||
493 | + | ||
494 | + // is a given date in last week range? | ||
495 | + is.inLastWeek = function(date) { | ||
496 | + return is.inDateRange(date, new Date(new Date().setDate(new Date().getDate() - 7)), new Date()); | ||
497 | + }; | ||
498 | + | ||
499 | + // is a given date in last year range? | ||
500 | + is.inLastYear = function(date) { | ||
501 | + return is.inDateRange(date, new Date(new Date().setFullYear(new Date().getFullYear() - 1)), new Date()); | ||
502 | + }; | ||
503 | + | ||
504 | + // is a given date in next month range? | ||
505 | + is.inNextMonth = function(date) { | ||
506 | + return is.inDateRange(date, new Date(), new Date(new Date().setMonth(new Date().getMonth() + 1))); | ||
507 | + }; | ||
508 | + | ||
509 | + // is a given date in next week range? | ||
510 | + is.inNextWeek = function(date) { | ||
511 | + return is.inDateRange(date, new Date(), new Date(new Date().setDate(new Date().getDate() + 7))); | ||
512 | + }; | ||
513 | + | ||
514 | + // is a given date in next year range? | ||
515 | + is.inNextYear = function(date) { | ||
516 | + return is.inDateRange(date, new Date(), new Date(new Date().setFullYear(new Date().getFullYear() + 1))); | ||
517 | + }; | ||
518 | + | ||
519 | + // is the given year a leap year? | ||
520 | + is.leapYear = function(year) { | ||
521 | + return is.number(year) && ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0); | ||
522 | + }; | ||
523 | + | ||
524 | + // is a given dates month equal given month parameter? | ||
525 | + is.month = function(date, month) { | ||
526 | + return is.date(date) && month.toLowerCase() === months[date.getMonth()]; | ||
527 | + }; | ||
528 | + // month method does not support 'all' and 'any' interfaces | ||
529 | + is.month.api = ['not']; | ||
530 | + | ||
531 | + // is a given date past? | ||
532 | + is.past = function(date) { | ||
533 | + var now = new Date(); | ||
534 | + return is.date(date) && date.getTime() < now.getTime(); | ||
535 | + }; | ||
536 | + | ||
537 | + // is a given date in the parameter quarter? | ||
538 | + is.quarterOfYear = function(date, quarter) { | ||
539 | + return is.date(date) && is.number(quarter) && quarter === Math.floor((date.getMonth() + 3) / 3); | ||
540 | + }; | ||
541 | + // quarterOfYear method does not support 'all' and 'any' interfaces | ||
542 | + is.quarterOfYear.api = ['not']; | ||
543 | + | ||
544 | + // is a given date indicate today? | ||
545 | + is.today = function(date) { | ||
546 | + var now = new Date(); | ||
547 | + var todayString = now.toDateString(); | ||
548 | + return is.date(date) && date.toDateString() === todayString; | ||
549 | + }; | ||
550 | + | ||
551 | + // is a given date indicate tomorrow? | ||
552 | + is.tomorrow = function(date) { | ||
553 | + var now = new Date(); | ||
554 | + var tomorrowString = new Date(now.setDate(now.getDate() + 1)).toDateString(); | ||
555 | + return is.date(date) && date.toDateString() === tomorrowString; | ||
556 | + }; | ||
557 | + | ||
558 | + // is a given date weekend? | ||
559 | + // 6: Saturday, 0: Sunday | ||
560 | + is.weekend = function(date) { | ||
561 | + return is.date(date) && (date.getDay() === 6 || date.getDay() === 0); | ||
562 | + }; | ||
563 | + | ||
564 | + // is a given date weekday? | ||
565 | + is.weekday = not(is.weekend); | ||
566 | + | ||
567 | + // is a given dates year equal given year parameter? | ||
568 | + is.year = function(date, year) { | ||
569 | + return is.date(date) && is.number(year) && year === date.getFullYear(); | ||
570 | + }; | ||
571 | + // year method does not support 'all' and 'any' interfaces | ||
572 | + is.year.api = ['not']; | ||
573 | + | ||
574 | + // is a given date indicate yesterday? | ||
575 | + is.yesterday = function(date) { | ||
576 | + var now = new Date(); | ||
577 | + var yesterdayString = new Date(now.setDate(now.getDate() - 1)).toDateString(); | ||
578 | + return is.date(date) && date.toDateString() === yesterdayString; | ||
579 | + }; | ||
580 | + | ||
581 | + // Environment checks | ||
582 | + /* -------------------------------------------------------------------------- */ | ||
583 | + | ||
584 | + var freeGlobal = is.windowObject(typeof global == 'object' && global) && global; | ||
585 | + var freeSelf = is.windowObject(typeof self == 'object' && self) && self; | ||
586 | + var thisGlobal = is.windowObject(typeof this == 'object' && this) && this; | ||
587 | + var root = freeGlobal || freeSelf || thisGlobal || Function('return this')(); | ||
588 | + | ||
589 | + var document = freeSelf && freeSelf.document; | ||
590 | + var previousIs = root.is; | ||
591 | + | ||
592 | + // store navigator properties to use later | ||
593 | + var navigator = freeSelf && freeSelf.navigator; | ||
594 | + var appVersion = (navigator && navigator.appVersion || '').toLowerCase(); | ||
595 | + var userAgent = (navigator && navigator.userAgent || '').toLowerCase(); | ||
596 | + var vendor = (navigator && navigator.vendor || '').toLowerCase(); | ||
597 | + | ||
598 | + // is current device android? | ||
599 | + is.android = function() { | ||
600 | + return /android/.test(userAgent); | ||
601 | + }; | ||
602 | + // android method does not support 'all' and 'any' interfaces | ||
603 | + is.android.api = ['not']; | ||
604 | + | ||
605 | + // is current device android phone? | ||
606 | + is.androidPhone = function() { | ||
607 | + return /android/.test(userAgent) && /mobile/.test(userAgent); | ||
608 | + }; | ||
609 | + // androidPhone method does not support 'all' and 'any' interfaces | ||
610 | + is.androidPhone.api = ['not']; | ||
611 | + | ||
612 | + // is current device android tablet? | ||
613 | + is.androidTablet = function() { | ||
614 | + return /android/.test(userAgent) && !/mobile/.test(userAgent); | ||
615 | + }; | ||
616 | + // androidTablet method does not support 'all' and 'any' interfaces | ||
617 | + is.androidTablet.api = ['not']; | ||
618 | + | ||
619 | + // is current device blackberry? | ||
620 | + is.blackberry = function() { | ||
621 | + return /blackberry/.test(userAgent) || /bb10/.test(userAgent); | ||
622 | + }; | ||
623 | + // blackberry method does not support 'all' and 'any' interfaces | ||
624 | + is.blackberry.api = ['not']; | ||
625 | + | ||
626 | + // is current browser chrome? | ||
627 | + // parameter is optional | ||
628 | + is.chrome = function(range) { | ||
629 | + var match = /google inc/.test(vendor) ? userAgent.match(/(?:chrome|crios)\/(\d+)/) : null; | ||
630 | + return match !== null && compareVersion(match[1], range); | ||
631 | + }; | ||
632 | + // chrome method does not support 'all' and 'any' interfaces | ||
633 | + is.chrome.api = ['not']; | ||
634 | + | ||
635 | + // is current device desktop? | ||
636 | + is.desktop = function() { | ||
637 | + return is.not.mobile() && is.not.tablet(); | ||
638 | + }; | ||
639 | + // desktop method does not support 'all' and 'any' interfaces | ||
640 | + is.desktop.api = ['not']; | ||
641 | + | ||
642 | + // is current browser edge? | ||
643 | + // parameter is optional | ||
644 | + is.edge = function(range) { | ||
645 | + var match = userAgent.match(/edge\/(\d+)/); | ||
646 | + return match !== null && compareVersion(match[1], range); | ||
647 | + }; | ||
648 | + // edge method does not support 'all' and 'any' interfaces | ||
649 | + is.edge.api = ['not']; | ||
650 | + | ||
651 | + // is current browser firefox? | ||
652 | + // parameter is optional | ||
653 | + is.firefox = function(range) { | ||
654 | + var match = userAgent.match(/(?:firefox|fxios)\/(\d+)/); | ||
655 | + return match !== null && compareVersion(match[1], range); | ||
656 | + }; | ||
657 | + // firefox method does not support 'all' and 'any' interfaces | ||
658 | + is.firefox.api = ['not']; | ||
659 | + | ||
660 | + // is current browser internet explorer? | ||
661 | + // parameter is optional | ||
662 | + is.ie = function(range) { | ||
663 | + var match = userAgent.match(/(?:msie |trident.+?; rv:)(\d+)/); | ||
664 | + return match !== null && compareVersion(match[1], range); | ||
665 | + }; | ||
666 | + // ie method does not support 'all' and 'any' interfaces | ||
667 | + is.ie.api = ['not']; | ||
668 | + | ||
669 | + // is current device ios? | ||
670 | + is.ios = function() { | ||
671 | + return is.iphone() || is.ipad() || is.ipod(); | ||
672 | + }; | ||
673 | + // ios method does not support 'all' and 'any' interfaces | ||
674 | + is.ios.api = ['not']; | ||
675 | + | ||
676 | + // is current device ipad? | ||
677 | + // parameter is optional | ||
678 | + is.ipad = function(range) { | ||
679 | + var match = userAgent.match(/ipad.+?os (\d+)/); | ||
680 | + return match !== null && compareVersion(match[1], range); | ||
681 | + }; | ||
682 | + // ipad method does not support 'all' and 'any' interfaces | ||
683 | + is.ipad.api = ['not']; | ||
684 | + | ||
685 | + // is current device iphone? | ||
686 | + // parameter is optional | ||
687 | + is.iphone = function(range) { | ||
688 | + // original iPhone doesn't have the os portion of the UA | ||
689 | + var match = userAgent.match(/iphone(?:.+?os (\d+))?/); | ||
690 | + return match !== null && compareVersion(match[1] || 1, range); | ||
691 | + }; | ||
692 | + // iphone method does not support 'all' and 'any' interfaces | ||
693 | + is.iphone.api = ['not']; | ||
694 | + | ||
695 | + // is current device ipod? | ||
696 | + // parameter is optional | ||
697 | + is.ipod = function(range) { | ||
698 | + var match = userAgent.match(/ipod.+?os (\d+)/); | ||
699 | + return match !== null && compareVersion(match[1], range); | ||
700 | + }; | ||
701 | + // ipod method does not support 'all' and 'any' interfaces | ||
702 | + is.ipod.api = ['not']; | ||
703 | + | ||
704 | + // is current operating system linux? | ||
705 | + is.linux = function() { | ||
706 | + return /linux/.test(appVersion); | ||
707 | + }; | ||
708 | + // linux method does not support 'all' and 'any' interfaces | ||
709 | + is.linux.api = ['not']; | ||
710 | + | ||
711 | + // is current operating system mac? | ||
712 | + is.mac = function() { | ||
713 | + return /mac/.test(appVersion); | ||
714 | + }; | ||
715 | + // mac method does not support 'all' and 'any' interfaces | ||
716 | + is.mac.api = ['not']; | ||
717 | + | ||
718 | + // is current device mobile? | ||
719 | + is.mobile = function() { | ||
720 | + return is.iphone() || is.ipod() || is.androidPhone() || is.blackberry() || is.windowsPhone(); | ||
721 | + }; | ||
722 | + // mobile method does not support 'all' and 'any' interfaces | ||
723 | + is.mobile.api = ['not']; | ||
724 | + | ||
725 | + // is current state offline? | ||
726 | + is.offline = not(is.online); | ||
727 | + // offline method does not support 'all' and 'any' interfaces | ||
728 | + is.offline.api = ['not']; | ||
729 | + | ||
730 | + // is current state online? | ||
731 | + is.online = function() { | ||
732 | + return !navigator || navigator.onLine === true; | ||
733 | + }; | ||
734 | + // online method does not support 'all' and 'any' interfaces | ||
735 | + is.online.api = ['not']; | ||
736 | + | ||
737 | + // is current browser opera? | ||
738 | + // parameter is optional | ||
739 | + is.opera = function(range) { | ||
740 | + var match = userAgent.match(/(?:^opera.+?version|opr)\/(\d+)/); | ||
741 | + return match !== null && compareVersion(match[1], range); | ||
742 | + }; | ||
743 | + // opera method does not support 'all' and 'any' interfaces | ||
744 | + is.opera.api = ['not']; | ||
745 | + | ||
746 | + // is current browser phantomjs? | ||
747 | + // parameter is optional | ||
748 | + is.phantom = function(range) { | ||
749 | + var match = userAgent.match(/phantomjs\/(\d+)/); | ||
750 | + return match !== null && compareVersion(match[1], range); | ||
751 | + }; | ||
752 | + // phantom method does not support 'all' and 'any' interfaces | ||
753 | + is.phantom.api = ['not']; | ||
754 | + | ||
755 | + // is current browser safari? | ||
756 | + // parameter is optional | ||
757 | + is.safari = function(range) { | ||
758 | + var match = userAgent.match(/version\/(\d+).+?safari/); | ||
759 | + return match !== null && compareVersion(match[1], range); | ||
760 | + }; | ||
761 | + // safari method does not support 'all' and 'any' interfaces | ||
762 | + is.safari.api = ['not']; | ||
763 | + | ||
764 | + // is current device tablet? | ||
765 | + is.tablet = function() { | ||
766 | + return is.ipad() || is.androidTablet() || is.windowsTablet(); | ||
767 | + }; | ||
768 | + // tablet method does not support 'all' and 'any' interfaces | ||
769 | + is.tablet.api = ['not']; | ||
770 | + | ||
771 | + // is current device supports touch? | ||
772 | + is.touchDevice = function() { | ||
773 | + return !!document && ('ontouchstart' in freeSelf || | ||
774 | + ('DocumentTouch' in freeSelf && document instanceof DocumentTouch)); | ||
775 | + }; | ||
776 | + // touchDevice method does not support 'all' and 'any' interfaces | ||
777 | + is.touchDevice.api = ['not']; | ||
778 | + | ||
779 | + // is current operating system windows? | ||
780 | + is.windows = function() { | ||
781 | + return /win/.test(appVersion); | ||
782 | + }; | ||
783 | + // windows method does not support 'all' and 'any' interfaces | ||
784 | + is.windows.api = ['not']; | ||
785 | + | ||
786 | + // is current device windows phone? | ||
787 | + is.windowsPhone = function() { | ||
788 | + return is.windows() && /phone/.test(userAgent); | ||
789 | + }; | ||
790 | + // windowsPhone method does not support 'all' and 'any' interfaces | ||
791 | + is.windowsPhone.api = ['not']; | ||
792 | + | ||
793 | + // is current device windows tablet? | ||
794 | + is.windowsTablet = function() { | ||
795 | + return is.windows() && is.not.windowsPhone() && /touch/.test(userAgent); | ||
796 | + }; | ||
797 | + // windowsTablet method does not support 'all' and 'any' interfaces | ||
798 | + is.windowsTablet.api = ['not']; | ||
799 | + | ||
800 | + // Object checks | ||
801 | + /* -------------------------------------------------------------------------- */ | ||
802 | + | ||
803 | + // has a given object got parameterized count property? | ||
804 | + is.propertyCount = function(object, count) { | ||
805 | + if (is.not.object(object) || is.not.number(count)) { | ||
806 | + return false; | ||
807 | + } | ||
808 | + var n = 0; | ||
809 | + for (var property in object) { | ||
810 | + if (hasOwnProperty.call(object, property) && ++n > count) { | ||
811 | + return false; | ||
812 | + } | ||
813 | + } | ||
814 | + return n === count; | ||
815 | + }; | ||
816 | + // propertyCount method does not support 'all' and 'any' interfaces | ||
817 | + is.propertyCount.api = ['not']; | ||
818 | + | ||
819 | + // is given object has parameterized property? | ||
820 | + is.propertyDefined = function(object, property) { | ||
821 | + return is.object(object) && is.string(property) && property in object; | ||
822 | + }; | ||
823 | + // propertyDefined method does not support 'all' and 'any' interfaces | ||
824 | + is.propertyDefined.api = ['not']; | ||
825 | + | ||
826 | + // Array checks | ||
827 | + /* -------------------------------------------------------------------------- */ | ||
828 | + | ||
829 | + // is a given item in an array? | ||
830 | + is.inArray = function(value, array) { | ||
831 | + if (is.not.array(array)) { | ||
832 | + return false; | ||
833 | + } | ||
834 | + for (var i = 0; i < array.length; i++) { | ||
835 | + if (array[i] === value) { | ||
836 | + return true; | ||
837 | + } | ||
838 | + } | ||
839 | + return false; | ||
840 | + }; | ||
841 | + // inArray method does not support 'all' and 'any' interfaces | ||
842 | + is.inArray.api = ['not']; | ||
843 | + | ||
844 | + // is a given array sorted? | ||
845 | + is.sorted = function(array, sign) { | ||
846 | + if (is.not.array(array)) { | ||
847 | + return false; | ||
848 | + } | ||
849 | + var predicate = comparator[sign] || comparator['>=']; | ||
850 | + for (var i = 1; i < array.length; i++) { | ||
851 | + if (!predicate(array[i], array[i - 1])) { | ||
852 | + return false; | ||
853 | + } | ||
854 | + } | ||
855 | + return true; | ||
856 | + }; | ||
857 | + | ||
858 | + // API | ||
859 | + // Set 'not', 'all' and 'any' interfaces to methods based on their api property | ||
860 | + /* -------------------------------------------------------------------------- */ | ||
861 | + | ||
862 | + function setInterfaces() { | ||
863 | + var options = is; | ||
864 | + for (var option in options) { | ||
865 | + if (hasOwnProperty.call(options, option) && is['function'](options[option])) { | ||
866 | + var interfaces = options[option].api || ['not', 'all', 'any']; | ||
867 | + for (var i = 0; i < interfaces.length; i++) { | ||
868 | + if (interfaces[i] === 'not') { | ||
869 | + is.not[option] = not(is[option]); | ||
870 | + } | ||
871 | + if (interfaces[i] === 'all') { | ||
872 | + is.all[option] = all(is[option]); | ||
873 | + } | ||
874 | + if (interfaces[i] === 'any') { | ||
875 | + is.any[option] = any(is[option]); | ||
876 | + } | ||
877 | + } | ||
878 | + } | ||
879 | + } | ||
880 | + } | ||
881 | + setInterfaces(); | ||
882 | + | ||
883 | + // Configuration methods | ||
884 | + // Intentionally added after setInterfaces function | ||
885 | + /* -------------------------------------------------------------------------- */ | ||
886 | + | ||
887 | + // change namespace of library to prevent name collisions | ||
888 | + // var preferredName = is.setNamespace(); | ||
889 | + // preferredName.odd(3); | ||
890 | + // => true | ||
891 | + is.setNamespace = function() { | ||
892 | + root.is = previousIs; | ||
893 | + return this; | ||
894 | + }; | ||
895 | + | ||
896 | + // set optional regexes to methods | ||
897 | + is.setRegexp = function(regexp, name) { | ||
898 | + for (var r in regexes) { | ||
899 | + if (hasOwnProperty.call(regexes, r) && (name === r)) { | ||
900 | + regexes[r] = regexp; | ||
901 | + } | ||
902 | + } | ||
903 | + }; | ||
904 | + | ||
905 | + return is; | ||
906 | +})); |
node_modules/is_js/is.min.js
0 → 100644
1 | +/*! | ||
2 | + * is.js 0.8.0 | ||
3 | + * Author: Aras Atasaygin | ||
4 | + */ | ||
5 | +(function(n,t){if(typeof define==="function"&&define.amd){define(function(){return n.is=t()})}else if(typeof exports==="object"){module.exports=t()}else{n.is=t()}})(this,function(){var n={};n.VERSION="0.8.0";n.not={};n.all={};n.any={};var t=Object.prototype.toString;var e=Array.prototype.slice;var r=Object.prototype.hasOwnProperty;function a(n){return function(){return!n.apply(null,e.call(arguments))}}function u(n){return function(){var t=c(arguments);var e=t.length;for(var r=0;r<e;r++){if(!n.call(null,t[r])){return false}}return true}}function o(n){return function(){var t=c(arguments);var e=t.length;for(var r=0;r<e;r++){if(n.call(null,t[r])){return true}}return false}}var i={"<":function(n,t){return n<t},"<=":function(n,t){return n<=t},">":function(n,t){return n>t},">=":function(n,t){return n>=t}};function f(n,t){var e=t+"";var r=+(e.match(/\d+/)||NaN);var a=e.match(/^[<>]=?|/)[0];return i[a]?i[a](n,r):n==r||r!==r}function c(t){var r=e.call(t);var a=r.length;if(a===1&&n.array(r[0])){r=r[0]}return r}n.arguments=function(n){return t.call(n)==="[object Arguments]"||n!=null&&typeof n==="object"&&"callee"in n};n.array=Array.isArray||function(n){return t.call(n)==="[object Array]"};n.boolean=function(n){return n===true||n===false||t.call(n)==="[object Boolean]"};n.char=function(t){return n.string(t)&&t.length===1};n.date=function(n){return t.call(n)==="[object Date]"};n.domNode=function(t){return n.object(t)&&t.nodeType>0};n.error=function(n){return t.call(n)==="[object Error]"};n["function"]=function(n){return t.call(n)==="[object Function]"||typeof n==="function"};n.json=function(n){return t.call(n)==="[object Object]"};n.nan=function(n){return n!==n};n["null"]=function(n){return n===null};n.number=function(e){return n.not.nan(e)&&t.call(e)==="[object Number]"};n.object=function(n){return Object(n)===n};n.regexp=function(n){return t.call(n)==="[object RegExp]"};n.sameType=function(e,r){var a=t.call(e);if(a!==t.call(r)){return false}if(a==="[object Number]"){return!n.any.nan(e,r)||n.all.nan(e,r)}return true};n.sameType.api=["not"];n.string=function(n){return t.call(n)==="[object String]"};n.undefined=function(n){return n===void 0};n.windowObject=function(n){return n!=null&&typeof n==="object"&&"setInterval"in n};n.empty=function(t){if(n.object(t)){var e=Object.getOwnPropertyNames(t).length;if(e===0||e===1&&n.array(t)||e===2&&n.arguments(t)){return true}return false}return t===""};n.existy=function(n){return n!=null};n.falsy=function(n){return!n};n.truthy=a(n.falsy);n.above=function(t,e){return n.all.number(t,e)&&t>e};n.above.api=["not"];n.decimal=function(t){return n.number(t)&&t%1!==0};n.equal=function(t,e){if(n.all.number(t,e)){return t===e&&1/t===1/e}if(n.all.string(t,e)||n.all.regexp(t,e)){return""+t===""+e}if(n.all.boolean(t,e)){return t===e}return false};n.equal.api=["not"];n.even=function(t){return n.number(t)&&t%2===0};n.finite=isFinite||function(t){return n.not.infinite(t)&&n.not.nan(t)};n.infinite=function(n){return n===Infinity||n===-Infinity};n.integer=function(t){return n.number(t)&&t%1===0};n.negative=function(t){return n.number(t)&&t<0};n.odd=function(t){return n.number(t)&&t%2===1};n.positive=function(t){return n.number(t)&&t>0};n.under=function(t,e){return n.all.number(t,e)&&t<e};n.under.api=["not"];n.within=function(t,e,r){return n.all.number(t,e,r)&&t>e&&t<r};n.within.api=["not"];var l={affirmative:/^(?:1|t(?:rue)?|y(?:es)?|ok(?:ay)?)$/,alphaNumeric:/^[A-Za-z0-9]+$/,caPostalCode:/^(?!.*[DFIOQU])[A-VXY][0-9][A-Z]\s?[0-9][A-Z][0-9]$/,creditCard:/^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/,dateString:/^(1[0-2]|0?[1-9])([\/-])(3[01]|[12][0-9]|0?[1-9])(?:\2)(?:[0-9]{2})?[0-9]{2}$/,email:/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,eppPhone:/^\+[0-9]{1,3}\.[0-9]{4,14}(?:x.+)?$/,hexadecimal:/^(?:0x)?[0-9a-fA-F]+$/,hexColor:/^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/,ipv4:/^(?:(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/,ipv6:/^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i,nanpPhone:/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,socialSecurityNumber:/^(?!000|666)[0-8][0-9]{2}-?(?!00)[0-9]{2}-?(?!0000)[0-9]{4}$/,timeString:/^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$/,ukPostCode:/^[A-Z]{1,2}[0-9RCHNQ][0-9A-Z]?\s?[0-9][ABD-HJLNP-UW-Z]{2}$|^[A-Z]{2}-?[0-9]{4}$/,url:/^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/i,usZipCode:/^[0-9]{5}(?:-[0-9]{4})?$/};function d(t,e){n[t]=function(n){return e[t].test(n)}}for(var s in l){if(l.hasOwnProperty(s)){d(s,l)}}n.ip=function(t){return n.ipv4(t)||n.ipv6(t)};n.capitalized=function(t){if(n.not.string(t)){return false}var e=t.split(" ");for(var r=0;r<e.length;r++){var a=e[r];if(a.length){var u=a.charAt(0);if(u!==u.toUpperCase()){return false}}}return true};n.endWith=function(t,e){if(n.not.string(t)){return false}e+="";var r=t.length-e.length;return r>=0&&t.indexOf(e,r)===r};n.endWith.api=["not"];n.include=function(n,t){return n.indexOf(t)>-1};n.include.api=["not"];n.lowerCase=function(t){return n.string(t)&&t===t.toLowerCase()};n.palindrome=function(t){if(n.not.string(t)){return false}t=t.replace(/[^a-zA-Z0-9]+/g,"").toLowerCase();var e=t.length-1;for(var r=0,a=Math.floor(e/2);r<=a;r++){if(t.charAt(r)!==t.charAt(e-r)){return false}}return true};n.space=function(t){if(n.not.char(t)){return false}var e=t.charCodeAt(0);return e>8&&e<14||e===32};n.startWith=function(t,e){return n.string(t)&&t.indexOf(e)===0};n.startWith.api=["not"];n.upperCase=function(t){return n.string(t)&&t===t.toUpperCase()};var F=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"];var p=["january","february","march","april","may","june","july","august","september","october","november","december"];n.day=function(t,e){return n.date(t)&&e.toLowerCase()===F[t.getDay()]};n.day.api=["not"];n.dayLightSavingTime=function(n){var t=new Date(n.getFullYear(),0,1);var e=new Date(n.getFullYear(),6,1);var r=Math.max(t.getTimezoneOffset(),e.getTimezoneOffset());return n.getTimezoneOffset()<r};n.future=function(t){var e=new Date;return n.date(t)&&t.getTime()>e.getTime()};n.inDateRange=function(t,e,r){if(n.not.date(t)||n.not.date(e)||n.not.date(r)){return false}var a=t.getTime();return a>e.getTime()&&a<r.getTime()};n.inDateRange.api=["not"];n.inLastMonth=function(t){return n.inDateRange(t,new Date((new Date).setMonth((new Date).getMonth()-1)),new Date)};n.inLastWeek=function(t){return n.inDateRange(t,new Date((new Date).setDate((new Date).getDate()-7)),new Date)};n.inLastYear=function(t){return n.inDateRange(t,new Date((new Date).setFullYear((new Date).getFullYear()-1)),new Date)};n.inNextMonth=function(t){return n.inDateRange(t,new Date,new Date((new Date).setMonth((new Date).getMonth()+1)))};n.inNextWeek=function(t){return n.inDateRange(t,new Date,new Date((new Date).setDate((new Date).getDate()+7)))};n.inNextYear=function(t){return n.inDateRange(t,new Date,new Date((new Date).setFullYear((new Date).getFullYear()+1)))};n.leapYear=function(t){return n.number(t)&&(t%4===0&&t%100!==0||t%400===0)};n.month=function(t,e){return n.date(t)&&e.toLowerCase()===p[t.getMonth()]};n.month.api=["not"];n.past=function(t){var e=new Date;return n.date(t)&&t.getTime()<e.getTime()};n.quarterOfYear=function(t,e){return n.date(t)&&n.number(e)&&e===Math.floor((t.getMonth()+3)/3)};n.quarterOfYear.api=["not"];n.today=function(t){var e=new Date;var r=e.toDateString();return n.date(t)&&t.toDateString()===r};n.tomorrow=function(t){var e=new Date;var r=new Date(e.setDate(e.getDate()+1)).toDateString();return n.date(t)&&t.toDateString()===r};n.weekend=function(t){return n.date(t)&&(t.getDay()===6||t.getDay()===0)};n.weekday=a(n.weekend);n.year=function(t,e){return n.date(t)&&n.number(e)&&e===t.getFullYear()};n.year.api=["not"];n.yesterday=function(t){var e=new Date;var r=new Date(e.setDate(e.getDate()-1)).toDateString();return n.date(t)&&t.toDateString()===r};var D=n.windowObject(typeof global=="object"&&global)&&global;var h=n.windowObject(typeof self=="object"&&self)&&self;var v=n.windowObject(typeof this=="object"&&this)&&this;var b=D||h||v||Function("return this")();var g=h&&h.document;var m=b.is;var w=h&&h.navigator;var y=(w&&w.appVersion||"").toLowerCase();var x=(w&&w.userAgent||"").toLowerCase();var A=(w&&w.vendor||"").toLowerCase();n.android=function(){return/android/.test(x)};n.android.api=["not"];n.androidPhone=function(){return/android/.test(x)&&/mobile/.test(x)};n.androidPhone.api=["not"];n.androidTablet=function(){return/android/.test(x)&&!/mobile/.test(x)};n.androidTablet.api=["not"];n.blackberry=function(){return/blackberry/.test(x)||/bb10/.test(x)};n.blackberry.api=["not"];n.chrome=function(n){var t=/google inc/.test(A)?x.match(/(?:chrome|crios)\/(\d+)/):null;return t!==null&&f(t[1],n)};n.chrome.api=["not"];n.desktop=function(){return n.not.mobile()&&n.not.tablet()};n.desktop.api=["not"];n.edge=function(n){var t=x.match(/edge\/(\d+)/);return t!==null&&f(t[1],n)};n.edge.api=["not"];n.firefox=function(n){var t=x.match(/(?:firefox|fxios)\/(\d+)/);return t!==null&&f(t[1],n)};n.firefox.api=["not"];n.ie=function(n){var t=x.match(/(?:msie |trident.+?; rv:)(\d+)/);return t!==null&&f(t[1],n)};n.ie.api=["not"];n.ios=function(){return n.iphone()||n.ipad()||n.ipod()};n.ios.api=["not"];n.ipad=function(n){var t=x.match(/ipad.+?os (\d+)/);return t!==null&&f(t[1],n)};n.ipad.api=["not"];n.iphone=function(n){var t=x.match(/iphone(?:.+?os (\d+))?/);return t!==null&&f(t[1]||1,n)};n.iphone.api=["not"];n.ipod=function(n){var t=x.match(/ipod.+?os (\d+)/);return t!==null&&f(t[1],n)};n.ipod.api=["not"];n.linux=function(){return/linux/.test(y)};n.linux.api=["not"];n.mac=function(){return/mac/.test(y)};n.mac.api=["not"];n.mobile=function(){return n.iphone()||n.ipod()||n.androidPhone()||n.blackberry()||n.windowsPhone()};n.mobile.api=["not"];n.offline=a(n.online);n.offline.api=["not"];n.online=function(){return!w||w.onLine===true};n.online.api=["not"];n.opera=function(n){var t=x.match(/(?:^opera.+?version|opr)\/(\d+)/);return t!==null&&f(t[1],n)};n.opera.api=["not"];n.phantom=function(n){var t=x.match(/phantomjs\/(\d+)/);return t!==null&&f(t[1],n)};n.phantom.api=["not"];n.safari=function(n){var t=x.match(/version\/(\d+).+?safari/);return t!==null&&f(t[1],n)};n.safari.api=["not"];n.tablet=function(){return n.ipad()||n.androidTablet()||n.windowsTablet()};n.tablet.api=["not"];n.touchDevice=function(){return!!g&&("ontouchstart"in h||"DocumentTouch"in h&&g instanceof DocumentTouch)};n.touchDevice.api=["not"];n.windows=function(){return/win/.test(y)};n.windows.api=["not"];n.windowsPhone=function(){return n.windows()&&/phone/.test(x)};n.windowsPhone.api=["not"];n.windowsTablet=function(){return n.windows()&&n.not.windowsPhone()&&/touch/.test(x)};n.windowsTablet.api=["not"];n.propertyCount=function(t,e){if(n.not.object(t)||n.not.number(e)){return false}var a=0;for(var u in t){if(r.call(t,u)&&++a>e){return false}}return a===e};n.propertyCount.api=["not"];n.propertyDefined=function(t,e){return n.object(t)&&n.string(e)&&e in t};n.propertyDefined.api=["not"];n.inArray=function(t,e){if(n.not.array(e)){return false}for(var r=0;r<e.length;r++){if(e[r]===t){return true}}return false};n.inArray.api=["not"];n.sorted=function(t,e){if(n.not.array(t)){return false}var r=i[e]||i[">="];for(var a=1;a<t.length;a++){if(!r(t[a],t[a-1])){return false}}return true};function j(){var t=n;for(var e in t){if(r.call(t,e)&&n["function"](t[e])){var i=t[e].api||["not","all","any"];for(var f=0;f<i.length;f++){if(i[f]==="not"){n.not[e]=a(n[e])}if(i[f]==="all"){n.all[e]=u(n[e])}if(i[f]==="any"){n.any[e]=o(n[e])}}}}}j();n.setNamespace=function(){b.is=m;return this};n.setRegexp=function(n,t){for(var e in l){if(r.call(l,e)&&t===e){l[e]=n}}};return n}); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/is_js/package.json
0 → 100644
1 | +{ | ||
2 | + "_from": "is_js@^0.9.0", | ||
3 | + "_id": "is_js@0.9.0", | ||
4 | + "_inBundle": false, | ||
5 | + "_integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=", | ||
6 | + "_location": "/is_js", | ||
7 | + "_phantomChildren": {}, | ||
8 | + "_requested": { | ||
9 | + "type": "range", | ||
10 | + "registry": true, | ||
11 | + "raw": "is_js@^0.9.0", | ||
12 | + "name": "is_js", | ||
13 | + "escapedName": "is_js", | ||
14 | + "rawSpec": "^0.9.0", | ||
15 | + "saveSpec": null, | ||
16 | + "fetchSpec": "^0.9.0" | ||
17 | + }, | ||
18 | + "_requiredBy": [ | ||
19 | + "/request-ip" | ||
20 | + ], | ||
21 | + "_resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", | ||
22 | + "_shasum": "0ab94540502ba7afa24c856aa985561669e9c52d", | ||
23 | + "_spec": "is_js@^0.9.0", | ||
24 | + "_where": "C:\\Users\\KoMoGoon\\Desktop\\oss_project\\Singer-Composer\\node_modules\\request-ip", | ||
25 | + "bugs": { | ||
26 | + "url": "https://github.com/arasatasaygin/is.js/issues" | ||
27 | + }, | ||
28 | + "bundleDependencies": false, | ||
29 | + "deprecated": false, | ||
30 | + "description": "micro check library", | ||
31 | + "devDependencies": { | ||
32 | + "chai": "^3.4.0", | ||
33 | + "eslint": "^2.13.1", | ||
34 | + "lodash": "^4.15.0", | ||
35 | + "mocha": "^2.2.1", | ||
36 | + "mocha-phantomjs": "^4.1.0", | ||
37 | + "pre-commit": "^1.1.3", | ||
38 | + "uglify-js": "^2.7.3" | ||
39 | + }, | ||
40 | + "files": [ | ||
41 | + "is.js", | ||
42 | + "is.min.js" | ||
43 | + ], | ||
44 | + "homepage": "http://is.js.org/", | ||
45 | + "license": "MIT", | ||
46 | + "main": "is.js", | ||
47 | + "name": "is_js", | ||
48 | + "pre-commit": [ | ||
49 | + "lint" | ||
50 | + ], | ||
51 | + "repository": { | ||
52 | + "type": "git", | ||
53 | + "url": "git+https://github.com/arasatasaygin/is.js.git" | ||
54 | + }, | ||
55 | + "scripts": { | ||
56 | + "build": "npm run lint && npm run min", | ||
57 | + "lint": "eslint .", | ||
58 | + "min": "uglifyjs is.js -m --comments \"/^!/\" -o is.min.js", | ||
59 | + "test": "mocha --check-leaks -R dot", | ||
60 | + "test:phantom": "mocha-phantomjs -R dot test/index.html" | ||
61 | + }, | ||
62 | + "version": "0.9.0" | ||
63 | +} |
node_modules/request-ip/CHANGELOG.md
0 → 100644
1 | +# Change Log | ||
2 | + | ||
3 | +## [2.1.2](https://github.com/pbojinov/request-ip/tree/2.1.2) (2018-10-29) | ||
4 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.1.1...2.1.2) | ||
5 | + | ||
6 | +**Closed issues:** | ||
7 | + | ||
8 | +- Handle Firebase hosting header fastly-client-ip [\#37](https://github.com/pbojinov/request-ip/issues/37) | ||
9 | + | ||
10 | +**Merged pull requests:** | ||
11 | + | ||
12 | +- chore: improve packaging [\#40](https://github.com/pbojinov/request-ip/pull/40) ([pi0](https://github.com/pi0)) | ||
13 | +- fixed Cannot redefine property: clientIp error [\#39](https://github.com/pbojinov/request-ip/pull/39) ([karankohli13](https://github.com/karankohli13)) | ||
14 | +- Add firebase hosting header [\#38](https://github.com/pbojinov/request-ip/pull/38) ([vishalvijay](https://github.com/vishalvijay)) | ||
15 | + | ||
16 | +## [2.1.1](https://github.com/pbojinov/request-ip/tree/2.1.1) (2018-07-03) | ||
17 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.1.0...2.1.1) | ||
18 | + | ||
19 | +## [2.1.0](https://github.com/pbojinov/request-ip/tree/2.1.0) (2018-07-03) | ||
20 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.2...2.1.0) | ||
21 | + | ||
22 | +**Closed issues:** | ||
23 | + | ||
24 | +- Not getting the right ip first time [\#28](https://github.com/pbojinov/request-ip/issues/28) | ||
25 | +- Allow using node \> 6 [\#27](https://github.com/pbojinov/request-ip/issues/27) | ||
26 | + | ||
27 | +**Merged pull requests:** | ||
28 | + | ||
29 | +- Get client ip when using AWS Api Gateway + Lambda. [\#35](https://github.com/pbojinov/request-ip/pull/35) ([rafaelthemendes](https://github.com/rafaelthemendes)) | ||
30 | +- redefine attribute getter [\#34](https://github.com/pbojinov/request-ip/pull/34) ([isayme](https://github.com/isayme)) | ||
31 | + | ||
32 | +## [2.0.2](https://github.com/pbojinov/request-ip/tree/2.0.2) (2017-06-26) | ||
33 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.1...2.0.2) | ||
34 | + | ||
35 | +**Closed issues:** | ||
36 | + | ||
37 | +- azure web app adds port to x-forwarded-for [\#29](https://github.com/pbojinov/request-ip/issues/29) | ||
38 | + | ||
39 | +**Merged pull requests:** | ||
40 | + | ||
41 | +- handling x-forwarded-for with ip:port [\#30](https://github.com/pbojinov/request-ip/pull/30) ([luisrudge](https://github.com/luisrudge)) | ||
42 | + | ||
43 | +## [2.0.1](https://github.com/pbojinov/request-ip/tree/2.0.1) (2017-03-09) | ||
44 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.0...2.0.1) | ||
45 | + | ||
46 | +**Implemented enhancements:** | ||
47 | + | ||
48 | +- ES2015 Support [\#22](https://github.com/pbojinov/request-ip/issues/22) | ||
49 | + | ||
50 | +## [2.0.0](https://github.com/pbojinov/request-ip/tree/2.0.0) (2017-03-07) | ||
51 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.3.0...2.0.0) | ||
52 | + | ||
53 | +**Closed issues:** | ||
54 | + | ||
55 | +- optimized your code a bit \(no need to evalutate every option before choosing first one that matches. just evaluate then return on first match\) [\#15](https://github.com/pbojinov/request-ip/issues/15) | ||
56 | + | ||
57 | +**Merged pull requests:** | ||
58 | + | ||
59 | +- Refactor to ES6 [\#23](https://github.com/pbojinov/request-ip/pull/23) ([fluxsauce](https://github.com/fluxsauce)) | ||
60 | + | ||
61 | +## [1.3.0](https://github.com/pbojinov/request-ip/tree/1.3.0) (2017-03-03) | ||
62 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.3...1.3.0) | ||
63 | + | ||
64 | +**Closed issues:** | ||
65 | + | ||
66 | +- Support Cloudflare? [\#20](https://github.com/pbojinov/request-ip/issues/20) | ||
67 | +- How to receive IP in client [\#17](https://github.com/pbojinov/request-ip/issues/17) | ||
68 | + | ||
69 | +**Merged pull requests:** | ||
70 | + | ||
71 | +- Adding support for CF-Connecting-IP and True-Client-IP [\#21](https://github.com/pbojinov/request-ip/pull/21) ([fluxsauce](https://github.com/fluxsauce)) | ||
72 | +- Return once we find something and don't crash if req.headers is undefined [\#19](https://github.com/pbojinov/request-ip/pull/19) ([rokob](https://github.com/rokob)) | ||
73 | +- Ignore 'unknown' ip addresses in X-Forwarded-For header [\#18](https://github.com/pbojinov/request-ip/pull/18) ([raunc](https://github.com/raunc)) | ||
74 | + | ||
75 | +## [1.2.3](https://github.com/pbojinov/request-ip/tree/1.2.3) (2016-11-02) | ||
76 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.2...1.2.3) | ||
77 | + | ||
78 | +**Closed issues:** | ||
79 | + | ||
80 | +- Are there any security concerns when saving the IP directly to a database? [\#16](https://github.com/pbojinov/request-ip/issues/16) | ||
81 | +- I'm not getting local host ip address 127.0.0.1 [\#14](https://github.com/pbojinov/request-ip/issues/14) | ||
82 | + | ||
83 | +## [1.2.2](https://github.com/pbojinov/request-ip/tree/1.2.2) (2016-01-27) | ||
84 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.1...1.2.2) | ||
85 | + | ||
86 | +## [1.2.1](https://github.com/pbojinov/request-ip/tree/1.2.1) (2016-01-27) | ||
87 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.0...1.2.1) | ||
88 | + | ||
89 | +**Merged pull requests:** | ||
90 | + | ||
91 | +- introduce a built-in default implementation for a connect-middleware [\#12](https://github.com/pbojinov/request-ip/pull/12) ([osherx](https://github.com/osherx)) | ||
92 | + | ||
93 | +## [1.2.0](https://github.com/pbojinov/request-ip/tree/1.2.0) (2016-01-27) | ||
94 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.4...1.2.0) | ||
95 | + | ||
96 | +**Merged pull requests:** | ||
97 | + | ||
98 | +- Cleanup [\#13](https://github.com/pbojinov/request-ip/pull/13) ([minecrawler](https://github.com/minecrawler)) | ||
99 | +- Got it working in a case that was returning null [\#11](https://github.com/pbojinov/request-ip/pull/11) ([andfaulkner](https://github.com/andfaulkner)) | ||
100 | + | ||
101 | +## [1.1.4](https://github.com/pbojinov/request-ip/tree/1.1.4) (2015-07-23) | ||
102 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.3...1.1.4) | ||
103 | + | ||
104 | +**Merged pull requests:** | ||
105 | + | ||
106 | +- Add case management where you can not find the IP address [\#10](https://github.com/pbojinov/request-ip/pull/10) ([sitexw](https://github.com/sitexw)) | ||
107 | + | ||
108 | +## [1.1.3](https://github.com/pbojinov/request-ip/tree/1.1.3) (2015-04-20) | ||
109 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.2...1.1.3) | ||
110 | + | ||
111 | +## [1.1.2](https://github.com/pbojinov/request-ip/tree/1.1.2) (2015-04-04) | ||
112 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.1...1.1.2) | ||
113 | + | ||
114 | +## [1.1.1](https://github.com/pbojinov/request-ip/tree/1.1.1) (2015-04-04) | ||
115 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.0...1.1.1) | ||
116 | + | ||
117 | +**Closed issues:** | ||
118 | + | ||
119 | +- needs semver [\#7](https://github.com/pbojinov/request-ip/issues/7) | ||
120 | + | ||
121 | +## [1.1.0](https://github.com/pbojinov/request-ip/tree/1.1.0) (2015-04-04) | ||
122 | +[Full Changelog](https://github.com/pbojinov/request-ip/compare/v0.0.4...1.1.0) | ||
123 | + | ||
124 | +**Merged pull requests:** | ||
125 | + | ||
126 | +- Update README.md [\#9](https://github.com/pbojinov/request-ip/pull/9) ([coolaj86](https://github.com/coolaj86)) | ||
127 | +- This deserves a production version number. [\#8](https://github.com/pbojinov/request-ip/pull/8) ([coolaj86](https://github.com/coolaj86)) | ||
128 | + | ||
129 | +## [v0.0.4](https://github.com/pbojinov/request-ip/tree/v0.0.4) (2015-01-16) | ||
130 | +**Closed issues:** | ||
131 | + | ||
132 | +- Invalid header [\#5](https://github.com/pbojinov/request-ip/issues/5) | ||
133 | +- replace req.header\('X-Forwarded-For'\) for req.header\('X-Forwarder-For'\)\); [\#3](https://github.com/pbojinov/request-ip/issues/3) | ||
134 | +- Nginx problems [\#2](https://github.com/pbojinov/request-ip/issues/2) | ||
135 | + | ||
136 | +**Merged pull requests:** | ||
137 | + | ||
138 | +- Add support for X-Real-IP Header [\#6](https://github.com/pbojinov/request-ip/pull/6) ([pmarques](https://github.com/pmarques)) | ||
139 | +- fix bug X-Forwarder-For [\#4](https://github.com/pbojinov/request-ip/pull/4) ([morello-cl](https://github.com/morello-cl)) | ||
140 | +- Add a Bitdeli Badge to README [\#1](https://github.com/pbojinov/request-ip/pull/1) ([bitdeli-chef](https://github.com/bitdeli-chef)) | ||
141 | + | ||
142 | + | ||
143 | + | ||
144 | +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/request-ip/LICENSE.md
0 → 100644
1 | +The MIT License (MIT) | ||
2 | + | ||
3 | +Copyright (c) 2018 Petar Bojinov - petarbojinov@gmail.com | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
6 | +this software and associated documentation files (the "Software"), to deal in | ||
7 | +the Software without restriction, including without limitation the rights to | ||
8 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
9 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
10 | +subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in all | ||
13 | +copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
17 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
18 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
19 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
20 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
node_modules/request-ip/README.md
0 → 100644
1 | +# request-ip | ||
2 | + | ||
3 | +A tiny Node.js module for retrieving a request's IP address. | ||
4 | + | ||
5 | +![](https://nodei.co/npm/request-ip.png?downloads=true&cacheBust=2) | ||
6 | + | ||
7 | +![](https://travis-ci.org/pbojinov/request-ip.svg?branch=master) | ||
8 | +[![Coverage Status](https://coveralls.io/repos/pbojinov/request-ip/badge.svg)](https://coveralls.io/r/pbojinov/request-ip) | ||
9 | +![](https://img.shields.io/npm/l/express.svg) | ||
10 | +[![npm version](https://badge.fury.io/js/request-ip.svg)](https://badge.fury.io/js/request-ip) | ||
11 | + | ||
12 | +## Installation | ||
13 | + | ||
14 | +```bash | ||
15 | +npm install request-ip --save | ||
16 | +``` | ||
17 | + | ||
18 | +## Getting Started | ||
19 | + | ||
20 | +```javascript | ||
21 | +const requestIp = require('request-ip'); | ||
22 | + | ||
23 | +// inside middleware handler | ||
24 | +const ipMiddleware = function(req, res, next) { | ||
25 | + const clientIp = requestIp.getClientIp(req); | ||
26 | + next(); | ||
27 | +}; | ||
28 | + | ||
29 | +// on localhost you'll see 127.0.0.1 if you're using IPv4 | ||
30 | +// or ::1, ::ffff:127.0.0.1 if you're using IPv6 | ||
31 | +``` | ||
32 | + | ||
33 | +### As Connect Middleware | ||
34 | + | ||
35 | +```javascript | ||
36 | +const requestIp = require('request-ip'); | ||
37 | +app.use(requestIp.mw()) | ||
38 | + | ||
39 | +app.use(function(req, res) { | ||
40 | + const ip = req.clientIp; | ||
41 | + res.end(ip); | ||
42 | +}); | ||
43 | +``` | ||
44 | + | ||
45 | +To see a full working code for the middleware, check out the [examples](https://github.com/pbojinov/request-ip/tree/master/examples) folder. | ||
46 | + | ||
47 | +The connect-middleware also supports retrieving the ip address under a custom attribute name, which also works as a container for any future settings. | ||
48 | + | ||
49 | +## How It Works | ||
50 | + | ||
51 | +It looks for specific headers in the request and falls back to some defaults if they do not exist. | ||
52 | + | ||
53 | +The user ip is determined by the following order: | ||
54 | + | ||
55 | +1. `X-Client-IP` | ||
56 | +2. `X-Forwarded-For` (Header may return multiple IP addresses in the format: "client IP, proxy 1 IP, proxy 2 IP", so we take the the first one.) | ||
57 | +3. `CF-Connecting-IP` (Cloudflare) | ||
58 | +4. `Fastly-Client-Ip` (Fastly CDN and Firebase hosting header when forwared to a cloud function) | ||
59 | +5. `True-Client-Ip` (Akamai and Cloudflare) | ||
60 | +6. `X-Real-IP` (Nginx proxy/FastCGI) | ||
61 | +7. `X-Cluster-Client-IP` (Rackspace LB, Riverbed Stingray) | ||
62 | +8. `X-Forwarded`, `Forwarded-For` and `Forwarded` (Variations of #2) | ||
63 | +9. `req.connection.remoteAddress` | ||
64 | +10. `req.socket.remoteAddress` | ||
65 | +11. `req.connection.socket.remoteAddress` | ||
66 | +12. `req.info.remoteAddress` | ||
67 | + | ||
68 | +If an IP address cannot be found, it will return `null`. | ||
69 | + | ||
70 | +## Samples Use Cases | ||
71 | + | ||
72 | +* Getting a user's IP for geolocation. | ||
73 | + | ||
74 | + | ||
75 | +## Running the Tests | ||
76 | + | ||
77 | +Make sure you have the necessary dev dependencies needed to run the tests: | ||
78 | + | ||
79 | +``` | ||
80 | +npm install | ||
81 | +``` | ||
82 | + | ||
83 | +Run the integration tests | ||
84 | + | ||
85 | +``` | ||
86 | +npm test | ||
87 | +``` | ||
88 | + | ||
89 | +## Release Notes | ||
90 | + | ||
91 | +See the wonderful [changelog](https://github.com/pbojinov/request-ip/blob/master/CHANGELOG.md) | ||
92 | + | ||
93 | +To easily generate a new changelog, install [github-changelog-generator](https://github.com/skywinder/github-changelog-generator) then run `npm run changelog`. | ||
94 | + | ||
95 | +## Contributors | ||
96 | + | ||
97 | +* Thanks to [@osherx](https://github.com/osherx) for adding the connect-middleware. | ||
98 | +* Thanks to [@raunc](https://github.com/raunc) for adding Squid proxy support. | ||
99 | +* Thanks to [@fluxsauce](https://github.com/fluxsauce) for adding `CF-Connecting-IP`, `True-Client-IP`, and ES6 support. | ||
100 | +* Thanks to [@vishalvijay](https://github.com/vishalvijay) for adding Fastly/Firebase hosting support. | ||
101 | + | ||
102 | +## License | ||
103 | + | ||
104 | +The MIT License (MIT) - 2018 |
node_modules/request-ip/dist/.DS_Store
0 → 100644
No preview for this file type
node_modules/request-ip/dist/index.js
0 → 100644
1 | +"use strict"; | ||
2 | + | ||
3 | +function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } | ||
4 | + | ||
5 | +var is = require('is_js'); | ||
6 | +/** | ||
7 | + * Parse x-forwarded-for headers. | ||
8 | + * | ||
9 | + * @param {string} value - The value to be parsed. | ||
10 | + * @return {string|null} First known IP address, if any. | ||
11 | + */ | ||
12 | + | ||
13 | + | ||
14 | +function getClientIpFromXForwardedFor(value) { | ||
15 | + if (!is.existy(value)) { | ||
16 | + return null; | ||
17 | + } | ||
18 | + | ||
19 | + if (is.not.string(value)) { | ||
20 | + throw new TypeError("Expected a string, got \"".concat(_typeof(value), "\"")); | ||
21 | + } // x-forwarded-for may return multiple IP addresses in the format: | ||
22 | + // "client IP, proxy 1 IP, proxy 2 IP" | ||
23 | + // Therefore, the right-most IP address is the IP address of the most recent proxy | ||
24 | + // and the left-most IP address is the IP address of the originating client. | ||
25 | + // source: http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html | ||
26 | + // Azure Web App's also adds a port for some reason, so we'll only use the first part (the IP) | ||
27 | + | ||
28 | + | ||
29 | + var forwardedIps = value.split(',').map(function (e) { | ||
30 | + var ip = e.trim(); | ||
31 | + | ||
32 | + if (ip.includes(':')) { | ||
33 | + var splitted = ip.split(':'); // make sure we only use this if it's ipv4 (ip:port) | ||
34 | + | ||
35 | + if (splitted.length === 2) { | ||
36 | + return splitted[0]; | ||
37 | + } | ||
38 | + } | ||
39 | + | ||
40 | + return ip; | ||
41 | + }); // Sometimes IP addresses in this header can be 'unknown' (http://stackoverflow.com/a/11285650). | ||
42 | + // Therefore taking the left-most IP address that is not unknown | ||
43 | + // A Squid configuration directive can also set the value to "unknown" (http://www.squid-cache.org/Doc/config/forwarded_for/) | ||
44 | + | ||
45 | + return forwardedIps.find(is.ip); | ||
46 | +} | ||
47 | +/** | ||
48 | + * Determine client IP address. | ||
49 | + * | ||
50 | + * @param req | ||
51 | + * @returns {string} ip - The IP address if known, defaulting to empty string if unknown. | ||
52 | + */ | ||
53 | + | ||
54 | + | ||
55 | +function getClientIp(req) { | ||
56 | + // Server is probably behind a proxy. | ||
57 | + if (req.headers) { | ||
58 | + // Standard headers used by Amazon EC2, Heroku, and others. | ||
59 | + if (is.ip(req.headers['x-client-ip'])) { | ||
60 | + return req.headers['x-client-ip']; | ||
61 | + } // Load-balancers (AWS ELB) or proxies. | ||
62 | + | ||
63 | + | ||
64 | + var xForwardedFor = getClientIpFromXForwardedFor(req.headers['x-forwarded-for']); | ||
65 | + | ||
66 | + if (is.ip(xForwardedFor)) { | ||
67 | + return xForwardedFor; | ||
68 | + } // Cloudflare. | ||
69 | + // @see https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers- | ||
70 | + // CF-Connecting-IP - applied to every request to the origin. | ||
71 | + | ||
72 | + | ||
73 | + if (is.ip(req.headers['cf-connecting-ip'])) { | ||
74 | + return req.headers['cf-connecting-ip']; | ||
75 | + } // Fastly and Firebase hosting header (When forwared to cloud function) | ||
76 | + | ||
77 | + | ||
78 | + if (is.ip(req.headers['fastly-client-ip'])) { | ||
79 | + return req.headers['fastly-client-ip']; | ||
80 | + } // Akamai and Cloudflare: True-Client-IP. | ||
81 | + | ||
82 | + | ||
83 | + if (is.ip(req.headers['true-client-ip'])) { | ||
84 | + return req.headers['true-client-ip']; | ||
85 | + } // Default nginx proxy/fcgi; alternative to x-forwarded-for, used by some proxies. | ||
86 | + | ||
87 | + | ||
88 | + if (is.ip(req.headers['x-real-ip'])) { | ||
89 | + return req.headers['x-real-ip']; | ||
90 | + } // (Rackspace LB and Riverbed's Stingray) | ||
91 | + // http://www.rackspace.com/knowledge_center/article/controlling-access-to-linux-cloud-sites-based-on-the-client-ip-address | ||
92 | + // https://splash.riverbed.com/docs/DOC-1926 | ||
93 | + | ||
94 | + | ||
95 | + if (is.ip(req.headers['x-cluster-client-ip'])) { | ||
96 | + return req.headers['x-cluster-client-ip']; | ||
97 | + } | ||
98 | + | ||
99 | + if (is.ip(req.headers['x-forwarded'])) { | ||
100 | + return req.headers['x-forwarded']; | ||
101 | + } | ||
102 | + | ||
103 | + if (is.ip(req.headers['forwarded-for'])) { | ||
104 | + return req.headers['forwarded-for']; | ||
105 | + } | ||
106 | + | ||
107 | + if (is.ip(req.headers.forwarded)) { | ||
108 | + return req.headers.forwarded; | ||
109 | + } | ||
110 | + } // Remote address checks. | ||
111 | + | ||
112 | + | ||
113 | + if (is.existy(req.connection)) { | ||
114 | + if (is.ip(req.connection.remoteAddress)) { | ||
115 | + return req.connection.remoteAddress; | ||
116 | + } | ||
117 | + | ||
118 | + if (is.existy(req.connection.socket) && is.ip(req.connection.socket.remoteAddress)) { | ||
119 | + return req.connection.socket.remoteAddress; | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | + if (is.existy(req.socket) && is.ip(req.socket.remoteAddress)) { | ||
124 | + return req.socket.remoteAddress; | ||
125 | + } | ||
126 | + | ||
127 | + if (is.existy(req.info) && is.ip(req.info.remoteAddress)) { | ||
128 | + return req.info.remoteAddress; | ||
129 | + } // AWS Api Gateway + Lambda | ||
130 | + | ||
131 | + | ||
132 | + if (is.existy(req.requestContext) && is.existy(req.requestContext.identity) && is.ip(req.requestContext.identity.sourceIp)) { | ||
133 | + return req.requestContext.identity.sourceIp; | ||
134 | + } | ||
135 | + | ||
136 | + return null; | ||
137 | +} | ||
138 | +/** | ||
139 | + * Expose request IP as a middleware. | ||
140 | + * | ||
141 | + * @param {object} [options] - Configuration. | ||
142 | + * @param {string} [options.attributeName] - Name of attribute to augment request object with. | ||
143 | + * @return {*} | ||
144 | + */ | ||
145 | + | ||
146 | + | ||
147 | +function mw(options) { | ||
148 | + // Defaults. | ||
149 | + var configuration = is.not.existy(options) ? {} : options; // Validation. | ||
150 | + | ||
151 | + if (is.not.object(configuration)) { | ||
152 | + throw new TypeError('Options must be an object!'); | ||
153 | + } | ||
154 | + | ||
155 | + var attributeName = configuration.attributeName || 'clientIp'; | ||
156 | + return function (req, res, next) { | ||
157 | + var ip = getClientIp(req); | ||
158 | + Object.defineProperty(req, attributeName, { | ||
159 | + get: function get() { | ||
160 | + return ip; | ||
161 | + }, | ||
162 | + configurable: true | ||
163 | + }); | ||
164 | + next(); | ||
165 | + }; | ||
166 | +} | ||
167 | + | ||
168 | +module.exports = { | ||
169 | + getClientIpFromXForwardedFor: getClientIpFromXForwardedFor, | ||
170 | + getClientIp: getClientIp, | ||
171 | + mw: mw | ||
172 | +}; | ||
173 | + |
node_modules/request-ip/package.json
0 → 100644
1 | +{ | ||
2 | + "_from": "request-ip", | ||
3 | + "_id": "request-ip@2.1.3", | ||
4 | + "_inBundle": false, | ||
5 | + "_integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==", | ||
6 | + "_location": "/request-ip", | ||
7 | + "_phantomChildren": {}, | ||
8 | + "_requested": { | ||
9 | + "type": "tag", | ||
10 | + "registry": true, | ||
11 | + "raw": "request-ip", | ||
12 | + "name": "request-ip", | ||
13 | + "escapedName": "request-ip", | ||
14 | + "rawSpec": "", | ||
15 | + "saveSpec": null, | ||
16 | + "fetchSpec": "latest" | ||
17 | + }, | ||
18 | + "_requiredBy": [ | ||
19 | + "#USER", | ||
20 | + "/" | ||
21 | + ], | ||
22 | + "_resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz", | ||
23 | + "_shasum": "99ab2bafdeaf2002626e28083cb10597511d9e14", | ||
24 | + "_spec": "request-ip", | ||
25 | + "_where": "C:\\Users\\KoMoGoon\\Desktop\\oss_project\\Singer-Composer", | ||
26 | + "author": { | ||
27 | + "name": "Petar Bojinov", | ||
28 | + "email": "petarbojinov@gmail.com" | ||
29 | + }, | ||
30 | + "bugs": { | ||
31 | + "url": "https://github.com/pbojinov/request-ip/issues" | ||
32 | + }, | ||
33 | + "bundleDependencies": false, | ||
34 | + "contributors": [ | ||
35 | + { | ||
36 | + "name": "Jon Peck", | ||
37 | + "email": "jpeck@fluxsauce.com" | ||
38 | + } | ||
39 | + ], | ||
40 | + "dependencies": { | ||
41 | + "is_js": "^0.9.0" | ||
42 | + }, | ||
43 | + "deprecated": false, | ||
44 | + "description": "A small node.js module to retrieve the request's IP address", | ||
45 | + "devDependencies": { | ||
46 | + "@babel/cli": "^7.0.0-beta.51", | ||
47 | + "@babel/core": "^7.0.0-beta.51", | ||
48 | + "@babel/preset-env": "^7.0.0-beta.51", | ||
49 | + "coveralls": "^3.0.2", | ||
50 | + "eslint": "^5.8.0", | ||
51 | + "eslint-config-airbnb-base": "^13.1.0", | ||
52 | + "eslint-plugin-import": "^2.2.0", | ||
53 | + "nyc": "^13.1.0", | ||
54 | + "request": "^2.54.0", | ||
55 | + "tap-spec": "^5.0.0", | ||
56 | + "tape": "^4.9.1" | ||
57 | + }, | ||
58 | + "files": [ | ||
59 | + "dist" | ||
60 | + ], | ||
61 | + "homepage": "https://github.com/pbojinov/request-ip", | ||
62 | + "keywords": [ | ||
63 | + "request ip", | ||
64 | + "ip", | ||
65 | + "address", | ||
66 | + "request", | ||
67 | + "proxy", | ||
68 | + "client", | ||
69 | + "header", | ||
70 | + "X-Client-IP", | ||
71 | + "X-Forwarded-For", | ||
72 | + "CF-Connecting-IP", | ||
73 | + "Fastly-Client-IP", | ||
74 | + "True-Client-IP", | ||
75 | + "X-Real-IP", | ||
76 | + "X-Cluster-Client-IP", | ||
77 | + "X-Forwarded", | ||
78 | + "Forwarded-For", | ||
79 | + "connection.remoteAddress", | ||
80 | + "connection.socket.remoteAddress", | ||
81 | + "req.info.remoteAddress", | ||
82 | + "middleware", | ||
83 | + "ipv4", | ||
84 | + "ipv6" | ||
85 | + ], | ||
86 | + "license": "MIT", | ||
87 | + "main": "./dist/index.js", | ||
88 | + "name": "request-ip", | ||
89 | + "repository": { | ||
90 | + "type": "git", | ||
91 | + "url": "git+https://github.com/pbojinov/request-ip.git" | ||
92 | + }, | ||
93 | + "scripts": { | ||
94 | + "build": "babel ./src/index.js > ./dist/index.js", | ||
95 | + "changelog": "github_changelog_generator -u pbojinov -p request-ip", | ||
96 | + "coverage": "nyc report --reporter=text-lcov | coveralls", | ||
97 | + "test": "nyc --reporter=html --reporter=text --check-coverage --lines=100 --statements=100 tape ./test/index.js" | ||
98 | + }, | ||
99 | + "version": "2.1.3" | ||
100 | +} |
... | @@ -750,6 +750,11 @@ | ... | @@ -750,6 +750,11 @@ |
750 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", | 750 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", |
751 | "dev": true | 751 | "dev": true |
752 | }, | 752 | }, |
753 | + "is_js": { | ||
754 | + "version": "0.9.0", | ||
755 | + "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", | ||
756 | + "integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=" | ||
757 | + }, | ||
753 | "isarray": { | 758 | "isarray": { |
754 | "version": "1.0.0", | 759 | "version": "1.0.0", |
755 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", | 760 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", |
... | @@ -1154,6 +1159,14 @@ | ... | @@ -1154,6 +1159,14 @@ |
1154 | } | 1159 | } |
1155 | } | 1160 | } |
1156 | }, | 1161 | }, |
1162 | + "request-ip": { | ||
1163 | + "version": "2.1.3", | ||
1164 | + "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz", | ||
1165 | + "integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==", | ||
1166 | + "requires": { | ||
1167 | + "is_js": "^0.9.0" | ||
1168 | + } | ||
1169 | + }, | ||
1157 | "request-promise-core": { | 1170 | "request-promise-core": { |
1158 | "version": "1.1.4", | 1171 | "version": "1.1.4", |
1159 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", | 1172 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", | ... | ... |
... | @@ -12,6 +12,7 @@ | ... | @@ -12,6 +12,7 @@ |
12 | "ejs": "^3.1.6", | 12 | "ejs": "^3.1.6", |
13 | "express": "^4.17.1", | 13 | "express": "^4.17.1", |
14 | "mysql": "^2.18.1", | 14 | "mysql": "^2.18.1", |
15 | + "request-ip": "^2.1.3", | ||
15 | "socket.io": "^4.4.0" | 16 | "socket.io": "^4.4.0" |
16 | }, | 17 | }, |
17 | "devDependencies": { | 18 | "devDependencies": { | ... | ... |
... | @@ -60,10 +60,10 @@ create table board( | ... | @@ -60,10 +60,10 @@ create table board( |
60 | >UPDATE board SET idx = @COUNT:=@COUNT+1; | 60 | >UPDATE board SET idx = @COUNT:=@COUNT+1; |
61 | 61 | ||
62 | --- | 62 | --- |
63 | -### 최종 수정: 2021-11-23 01:53<br> | 63 | +### 최종 수정: 2021-11-23 02:49<br> |
64 | ### 수정 내용: | 64 | ### 수정 내용: |
65 | 0. 채팅기능에 버그가 있는 것 같음-피드백 바람(undefined님이 나가셨습니다. -> 콘솔에 계속 출력됨) | 65 | 0. 채팅기능에 버그가 있는 것 같음-피드백 바람(undefined님이 나가셨습니다. -> 콘솔에 계속 출력됨) |
66 | -1. 일부 수정 | 66 | +1. 로그에 IP 추가 |
67 | 2. 로그에 시간 추가 | 67 | 2. 로그에 시간 추가 |
68 | 3. 시간 실시간 반영 | 68 | 3. 시간 실시간 반영 |
69 | 4. 게시글 수정 및 삭제 세션+권한 연동/DB수정 | 69 | 4. 게시글 수정 및 삭제 세션+권한 연동/DB수정 | ... | ... |
... | @@ -2,6 +2,7 @@ var express = require('express') | ... | @@ -2,6 +2,7 @@ var express = require('express') |
2 | var app = express() | 2 | var app = express() |
3 | var router = express.Router(); | 3 | var router = express.Router(); |
4 | var path = require('path') // 상대경로 | 4 | var path = require('path') // 상대경로 |
5 | +var requestIp = require('request-ip'); | ||
5 | 6 | ||
6 | // 로그용 | 7 | // 로그용 |
7 | var logString; | 8 | var logString; |
... | @@ -24,14 +25,15 @@ init() | ... | @@ -24,14 +25,15 @@ init() |
24 | 25 | ||
25 | // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. | 26 | // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. |
26 | router.get('/', function(req, res){ | 27 | router.get('/', function(req, res){ |
28 | + var ip = requestIp.getClientIp(req); | ||
27 | var id = req.user; | 29 | var id = req.user; |
28 | if(!id){ | 30 | if(!id){ |
29 | - console.log(logString+'익명의 유저가 about 페이지에서 작업 중입니다.') | 31 | + console.log(logString+'익명의 유저가 about 페이지에서 작업 중입니다.('+ip+')') |
30 | res.sendFile(path.join(__dirname, "../../public/about.html")) | 32 | res.sendFile(path.join(__dirname, "../../public/about.html")) |
31 | } | 33 | } |
32 | if(id){ | 34 | if(id){ |
33 | var nickname = req.user.nickname; | 35 | var nickname = req.user.nickname; |
34 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 about 페이지에서 작업 중입니다.') | 36 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 about 페이지에서 작업 중입니다.('+ip+')') |
35 | res.render('about.ejs', {'ID': id, 'nickname': nickname}); | 37 | res.render('about.ejs', {'ID': id, 'nickname': nickname}); |
36 | } | 38 | } |
37 | }); | 39 | }); | ... | ... |
... | @@ -7,6 +7,7 @@ var mysql = require('mysql'); | ... | @@ -7,6 +7,7 @@ var mysql = require('mysql'); |
7 | var path = require('path') // 상대경로 | 7 | var path = require('path') // 상대경로 |
8 | var mysql_odbc = require('../../db/db_board')(); | 8 | var mysql_odbc = require('../../db/db_board')(); |
9 | var board = mysql_odbc.init(); | 9 | var board = mysql_odbc.init(); |
10 | +var requestIp = require('request-ip'); | ||
10 | 11 | ||
11 | // 로그용 | 12 | // 로그용 |
12 | var logString; | 13 | var logString; |
... | @@ -28,9 +29,10 @@ function init(){ | ... | @@ -28,9 +29,10 @@ function init(){ |
28 | init() | 29 | init() |
29 | 30 | ||
30 | router.get('/list/:page', function(req, res, next) { | 31 | router.get('/list/:page', function(req, res, next) { |
32 | + var ip = requestIp.getClientIp(req); | ||
31 | var id = req.user; | 33 | var id = req.user; |
32 | if(!id){ | 34 | if(!id){ |
33 | - console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.') | 35 | + console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.('+ip+')') |
34 | res.redirect('/board/list/1') | 36 | res.redirect('/board/list/1') |
35 | } | 37 | } |
36 | else{ | 38 | else{ |
... | @@ -41,36 +43,39 @@ router.get('/list/:page', function(req, res, next) { | ... | @@ -41,36 +43,39 @@ router.get('/list/:page', function(req, res, next) { |
41 | if (err) console.error("err : " + err); | 43 | if (err) console.error("err : " + err); |
42 | var id = req.user.ID; | 44 | var id = req.user.ID; |
43 | var nickname = req.user.nickname; | 45 | var nickname = req.user.nickname; |
44 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 게시판을 보고있습니다.') | 46 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 게시판을 보고있습니다.('+ip+')') |
45 | res.render('list.ejs', {'ID':id, 'nickname': nickname, title: '게시판 리스트', rows: rows, page:page, length:rows.length-1,page_num:10,pass:true}) | 47 | res.render('list.ejs', {'ID':id, 'nickname': nickname, title: '게시판 리스트', rows: rows, page:page, length:rows.length-1,page_num:10,pass:true}) |
46 | }) | 48 | }) |
47 | } | 49 | } |
48 | }); | 50 | }); |
49 | 51 | ||
50 | router.get('/list', function(req,res,next){ | 52 | router.get('/list', function(req,res,next){ |
53 | + var ip = requestIp.getClientIp(req); | ||
51 | var id = req.user; | 54 | var id = req.user; |
52 | if(!id){ | 55 | if(!id){ |
53 | - console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.') | 56 | + console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.('+ip+')') |
54 | res.sendFile(path.join(__dirname, "../../public/login.html")) | 57 | res.sendFile(path.join(__dirname, "../../public/login.html")) |
55 | } | 58 | } |
56 | else res.redirect('/board/list/1') | 59 | else res.redirect('/board/list/1') |
57 | }) | 60 | }) |
58 | 61 | ||
59 | router.get('/write', function(req,res,next){ | 62 | router.get('/write', function(req,res,next){ |
63 | + var ip = requestIp.getClientIp(req); | ||
60 | var id = req.user; | 64 | var id = req.user; |
61 | if(!id){ | 65 | if(!id){ |
62 | - console.log(logString+'익명 유저의 글쓰기 시도를 거부했습니다.') | 66 | + console.log(logString+'익명 유저의 글쓰기 시도를 거부했습니다.('+ip+')') |
63 | res.sendFile(path.join(__dirname, "../../public/login.html")) | 67 | res.sendFile(path.join(__dirname, "../../public/login.html")) |
64 | } | 68 | } |
65 | else{ | 69 | else{ |
66 | var id = req.user.ID; | 70 | var id = req.user.ID; |
67 | var nickname = req.user.nickname; | 71 | var nickname = req.user.nickname; |
68 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 게시글 작성 중입니다.') | 72 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 게시글 작성 중입니다.('+ip+')') |
69 | res.render('write.ejs', {'ID':id, 'nickname': nickname, title:"게시판 글 쓰기"}) | 73 | res.render('write.ejs', {'ID':id, 'nickname': nickname, title:"게시판 글 쓰기"}) |
70 | } | 74 | } |
71 | }) | 75 | }) |
72 | 76 | ||
73 | router.post('/write', function(req,res,next){ | 77 | router.post('/write', function(req,res,next){ |
78 | + var ip = requestIp.getClientIp(req); | ||
74 | var nickname = req.user.nickname // var name = req.body.name | 79 | var nickname = req.user.nickname // var name = req.body.name |
75 | var title = req.body.title | 80 | var title = req.body.title |
76 | var content = req.body.content | 81 | var content = req.body.content |
... | @@ -91,12 +96,13 @@ router.post('/write', function(req,res,next){ | ... | @@ -91,12 +96,13 @@ router.post('/write', function(req,res,next){ |
91 | if(!idx_) // 글이 없으면 NULL | 96 | if(!idx_) // 글이 없으면 NULL |
92 | idx_ = 1; | 97 | idx_ = 1; |
93 | 98 | ||
94 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx_+'번 게시글을 작성했습니다.') | 99 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx_+'번 게시글을 작성했습니다.('+ip+')') |
95 | res.redirect('/board/read/'+idx_); | 100 | res.redirect('/board/read/'+idx_); |
96 | }); | 101 | }); |
97 | }) | 102 | }) |
98 | 103 | ||
99 | router.get('/read/:idx', function(req,res,next){ | 104 | router.get('/read/:idx', function(req,res,next){ |
105 | + var ip = requestIp.getClientIp(req); | ||
100 | var idx = req.params.idx | 106 | var idx = req.params.idx |
101 | var sql = "select idx, nickname, title, content, date_format(modidate,'%Y-%m-%d %H:%i:%s') modidate, " + | 107 | var sql = "select idx, nickname, title, content, date_format(modidate,'%Y-%m-%d %H:%i:%s') modidate, " + |
102 | "date_format(regdate,'%Y-%m-%d %H:%i:%s') regdate, hit, ID from board where idx=?"; | 108 | "date_format(regdate,'%Y-%m-%d %H:%i:%s') regdate, hit, ID from board where idx=?"; |
... | @@ -105,7 +111,7 @@ router.get('/read/:idx', function(req,res,next){ | ... | @@ -105,7 +111,7 @@ router.get('/read/:idx', function(req,res,next){ |
105 | 111 | ||
106 | var id = req.user; | 112 | var id = req.user; |
107 | if(!id){ | 113 | if(!id){ |
108 | - console.log(logString+'익명 유저의 '+idx+'번 게시물 접근을 거부했습니다.') | 114 | + console.log(logString+'익명 유저의 '+idx+'번 게시물 접근을 거부했습니다.('+ip+')') |
109 | res.redirect('/login') | 115 | res.redirect('/login') |
110 | } | 116 | } |
111 | else{ | 117 | else{ |
... | @@ -118,13 +124,14 @@ router.get('/read/:idx', function(req,res,next){ | ... | @@ -118,13 +124,14 @@ router.get('/read/:idx', function(req,res,next){ |
118 | if(err) console.error(err) | 124 | if(err) console.error(err) |
119 | }) | 125 | }) |
120 | 126 | ||
121 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 보고있습니다.') | 127 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 보고있습니다.('+ip+')') |
122 | res.render('read.ejs', {'ID':id, 'nickname': nickname, title:"글 상세", row:row[0]}) | 128 | res.render('read.ejs', {'ID':id, 'nickname': nickname, title:"글 상세", row:row[0]}) |
123 | } | 129 | } |
124 | }) | 130 | }) |
125 | }) | 131 | }) |
126 | 132 | ||
127 | router.post('/update', function(req,res,next){ | 133 | router.post('/update', function(req,res,next){ |
134 | + var ip = requestIp.getClientIp(req); | ||
128 | var ID = req.user.ID; | 135 | var ID = req.user.ID; |
129 | var idx = req.body.idx | 136 | var idx = req.body.idx |
130 | var title = req.body.title | 137 | var title = req.body.title |
... | @@ -135,19 +142,20 @@ router.post('/update', function(req,res,next){ | ... | @@ -135,19 +142,20 @@ router.post('/update', function(req,res,next){ |
135 | board.query(sql,datas,function(err,result){ | 142 | board.query(sql,datas,function(err,result){ |
136 | if(err) console.error(err) | 143 | if(err) console.error(err) |
137 | if(result.affectedRows==0){ | 144 | if(result.affectedRows==0){ |
138 | - console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 수정을 거부했습니다.(권한없음)') | 145 | + console.log(logString+req.user.ID+'('+req.user.nickname+') 유저의 '+idx+'번 게시글 수정을 거부했습니다.(권한없음 // '+ip+')') |
139 | res.send("<script>alert('게시글 작성자가 아닙니다.');history.back();</script>") | 146 | res.send("<script>alert('게시글 작성자가 아닙니다.');history.back();</script>") |
140 | } | 147 | } |
141 | else{ | 148 | else{ |
142 | var id = req.user.ID; | 149 | var id = req.user.ID; |
143 | var nickname = req.user.nickname; | 150 | var nickname = req.user.nickname; |
144 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 수정했습니다.') | 151 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 수정했습니다.('+ip+')') |
145 | res.redirect('/board/read/'+idx) | 152 | res.redirect('/board/read/'+idx) |
146 | } | 153 | } |
147 | }) | 154 | }) |
148 | }) | 155 | }) |
149 | 156 | ||
150 | router.post('/delete', function(req,res,next){ | 157 | router.post('/delete', function(req,res,next){ |
158 | + var ip = requestIp.getClientIp(req); | ||
151 | var idx = req.body.idx | 159 | var idx = req.body.idx |
152 | var ID = req.user.ID; | 160 | var ID = req.user.ID; |
153 | var datas = [idx,ID] | 161 | var datas = [idx,ID] |
... | @@ -170,12 +178,12 @@ router.post('/delete', function(req,res,next){ | ... | @@ -170,12 +178,12 @@ router.post('/delete', function(req,res,next){ |
170 | 178 | ||
171 | var nickname = req.user.nickname; | 179 | var nickname = req.user.nickname; |
172 | res.send("<script>alert('게시글이 운영자에 의해 삭제되었습니다.');window.location.href='/board/list/';</script>"); | 180 | res.send("<script>alert('게시글이 운영자에 의해 삭제되었습니다.');window.location.href='/board/list/';</script>"); |
173 | - console.log(logString+"[Admin] "+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.') | 181 | + console.log(logString+"[Admin] "+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.('+ip+')') |
174 | }) | 182 | }) |
175 | } | 183 | } |
176 | else{ // 작성자도, 운영자도 아니면 | 184 | else{ // 작성자도, 운영자도 아니면 |
177 | var nickname = req.user.nickname; | 185 | var nickname = req.user.nickname; |
178 | - console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 삭제를 거부했습니다.(권한없음)') | 186 | + console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 삭제를 거부했습니다.(권한없음 // '+ip+')') |
179 | res.send("<script>alert('게시글 작성자가 아닙니다');history.back();</script>"); | 187 | res.send("<script>alert('게시글 작성자가 아닙니다');history.back();</script>"); |
180 | } | 188 | } |
181 | }) | 189 | }) |
... | @@ -184,7 +192,7 @@ router.post('/delete', function(req,res,next){ | ... | @@ -184,7 +192,7 @@ router.post('/delete', function(req,res,next){ |
184 | var id = req.user.ID; | 192 | var id = req.user.ID; |
185 | var nickname = req.user.nickname; | 193 | var nickname = req.user.nickname; |
186 | res.send("<script>alert('게시글이 삭제되었습니다.');window.location.href='/board/list/';</script>"); | 194 | res.send("<script>alert('게시글이 삭제되었습니다.');window.location.href='/board/list/';</script>"); |
187 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.') | 195 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.('+ip+')') |
188 | } | 196 | } |
189 | }) | 197 | }) |
190 | }) | 198 | }) | ... | ... |
... | @@ -4,6 +4,7 @@ var router = express.Router(); | ... | @@ -4,6 +4,7 @@ var router = express.Router(); |
4 | var path = require('path') // 상대경로 | 4 | var path = require('path') // 상대경로 |
5 | var mysql_odbc = require('../../db/db_board')(); | 5 | var mysql_odbc = require('../../db/db_board')(); |
6 | var myinfo = mysql_odbc.init(); | 6 | var myinfo = mysql_odbc.init(); |
7 | +var requestIp = require('request-ip'); | ||
7 | 8 | ||
8 | // 로그용 | 9 | // 로그용 |
9 | var logString; | 10 | var logString; |
... | @@ -25,14 +26,15 @@ function init(){ | ... | @@ -25,14 +26,15 @@ function init(){ |
25 | init() | 26 | init() |
26 | 27 | ||
27 | router.get('/', function(req, res){ | 28 | router.get('/', function(req, res){ |
29 | + var ip = requestIp.getClientIp(req); | ||
28 | var id = req.user; | 30 | var id = req.user; |
29 | if(!id){ | 31 | if(!id){ |
30 | - console.log(logString+'익명 유저의 채팅 접근을 거부했습니다.') | 32 | + console.log(logString+'익명 유저의 채팅 접근을 거부했습니다.('+ip+')') |
31 | res.sendFile(path.join(__dirname, "../../public/login.html")) | 33 | res.sendFile(path.join(__dirname, "../../public/login.html")) |
32 | } | 34 | } |
33 | if(id){ | 35 | if(id){ |
34 | var nickname = req.user.nickname | 36 | var nickname = req.user.nickname |
35 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 채팅 중입니다.') | 37 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 채팅 중입니다.('+ip+')') |
36 | res.render('chat.ejs', {'nickname':nickname}) | 38 | res.render('chat.ejs', {'nickname':nickname}) |
37 | } | 39 | } |
38 | }); | 40 | }); | ... | ... |
... | @@ -2,6 +2,7 @@ var express = require('express') | ... | @@ -2,6 +2,7 @@ var express = require('express') |
2 | var app = express() | 2 | var app = express() |
3 | var router = express.Router(); | 3 | var router = express.Router(); |
4 | var path = require('path') | 4 | var path = require('path') |
5 | +var requestIp = require('request-ip'); | ||
5 | 6 | ||
6 | var main = require('./main/main') | 7 | var main = require('./main/main') |
7 | var register = require('./register/index') | 8 | var register = require('./register/index') |
... | @@ -12,10 +13,39 @@ var profile = require('./profile/index') | ... | @@ -12,10 +13,39 @@ var profile = require('./profile/index') |
12 | var about = require('./about/index') | 13 | var about = require('./about/index') |
13 | var chat = require('./chat/chat') | 14 | var chat = require('./chat/chat') |
14 | 15 | ||
16 | +// 로그용 | ||
17 | +var logString; | ||
18 | +function getTime(){ | ||
19 | + var today = new Date(); | ||
20 | + var year = today.getFullYear(); | ||
21 | + var month = ('0' + (today.getMonth()+1)).slice(-2); | ||
22 | + var day = ('0' + today.getDate()).slice(-2); | ||
23 | + var hour = ('0' + today.getHours()).slice(-2); | ||
24 | + var minute = ('0' + today.getMinutes()).slice(-2); | ||
25 | + var second = ('0' + today.getSeconds()).slice(-2); | ||
26 | + logString = '['+year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second+'] '; | ||
27 | +} | ||
28 | +// 시간 갱신용 | ||
29 | +function init(){ | ||
30 | + getTime(); | ||
31 | + setInterval(getTime, 1000) | ||
32 | +} | ||
33 | +init() | ||
34 | + | ||
15 | // URL routing | 35 | // URL routing |
16 | // req = request, res = respond | 36 | // req = request, res = respond |
17 | router.get('/', function(req, res){ | 37 | router.get('/', function(req, res){ |
18 | - res.sendFile(path.join(__dirname, "../public/main.html")); | 38 | + var ip = requestIp.getClientIp(req); |
39 | + var id = req.user; | ||
40 | + if(!id){ | ||
41 | + console.log(logString+'익명의 유저가 작업 중입니다.('+ip+')') | ||
42 | + res.sendFile(path.join(__dirname, "../public/main.html")) | ||
43 | + } | ||
44 | + if(id){ | ||
45 | + var nickname = req.user.nickname; | ||
46 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.('+ip+')') | ||
47 | + res.render('main.ejs', {'ID': id, 'nickname': nickname}); | ||
48 | + } | ||
19 | }); | 49 | }); |
20 | 50 | ||
21 | // router 정의 | 51 | // router 정의 | ... | ... |
... | @@ -5,6 +5,7 @@ var path = require('path') // 상대경로 | ... | @@ -5,6 +5,7 @@ var path = require('path') // 상대경로 |
5 | var mysql = require('mysql') | 5 | var mysql = require('mysql') |
6 | var passport = require('passport') | 6 | var passport = require('passport') |
7 | var LocalStrategy = require('passport-local').Strategy | 7 | var LocalStrategy = require('passport-local').Strategy |
8 | +var requestIp = require('request-ip'); | ||
8 | 9 | ||
9 | // 로그용 | 10 | // 로그용 |
10 | var logString; | 11 | var logString; |
... | @@ -39,7 +40,8 @@ router.get('/', function(req, res){ | ... | @@ -39,7 +40,8 @@ router.get('/', function(req, res){ |
39 | var msg; | 40 | var msg; |
40 | var errMsg = req.flash('error') | 41 | var errMsg = req.flash('error') |
41 | if(errMsg) msg = errMsg; | 42 | if(errMsg) msg = errMsg; |
42 | - console.log(logString+'익명의 유저가 로그인 중입니다.') | 43 | + var ip = requestIp.getClientIp(req); |
44 | + console.log(logString+'익명의 유저가 로그인 중입니다.('+ip+')') | ||
43 | res.render('login.ejs', {'message' : msg}); | 45 | res.render('login.ejs', {'message' : msg}); |
44 | }) | 46 | }) |
45 | 47 | ||
... | @@ -62,18 +64,19 @@ passport.use('local-login', new LocalStrategy({ | ... | @@ -62,18 +64,19 @@ passport.use('local-login', new LocalStrategy({ |
62 | var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){ | 64 | var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){ |
63 | if(err) return done(err); | 65 | if(err) return done(err); |
64 | 66 | ||
67 | + var ip = requestIp.getClientIp(req); | ||
65 | if(rows.length){ // database에 입력한 ID값이 있는가? | 68 | if(rows.length){ // database에 입력한 ID값이 있는가? |
66 | if(password == rows[0].password){ // 비밀번호와 확인이 같은가? | 69 | if(password == rows[0].password){ // 비밀번호와 확인이 같은가? |
67 | - console.log(logString+"로그인 알림: "+ ID +"(" + rows[0].nickname + ")") | 70 | + console.log(logString+"로그인 알림: "+ ID +"(" + rows[0].nickname +" // "+ip+')') |
68 | return done(null, {'ID' : ID, 'nickname' : rows[0].nickname}); | 71 | return done(null, {'ID' : ID, 'nickname' : rows[0].nickname}); |
69 | } | 72 | } |
70 | else{ | 73 | else{ |
71 | - console.log(logString+"로그인 알림: 잘못된 비밀번호입니다.(시도된 아이디: "+ID+")") | 74 | + console.log(logString+"로그인 알림: 잘못된 비밀번호입니다.(시도된 아이디: "+ID+" // "+ip+')') |
72 | return done(null, false, {message : '잘못된 비밀번호입니다.'}) | 75 | return done(null, false, {message : '잘못된 비밀번호입니다.'}) |
73 | } | 76 | } |
74 | } | 77 | } |
75 | else{ | 78 | else{ |
76 | - console.log(logString+"로그인 알림: ID를 찾을 수 없습니다.(시도된 아이디: "+ID+")") | 79 | + console.log(logString+"로그인 알림: ID를 찾을 수 없습니다.(시도된 아이디: "+ID+" // "+ip+')') |
77 | return done(null, false, {message : 'ID를 찾을 수 없습니다.'}) | 80 | return done(null, false, {message : 'ID를 찾을 수 없습니다.'}) |
78 | } | 81 | } |
79 | }) | 82 | }) | ... | ... |
... | @@ -2,6 +2,7 @@ var express = require('express') | ... | @@ -2,6 +2,7 @@ var express = require('express') |
2 | var app = express() | 2 | var app = express() |
3 | var router = express.Router(); | 3 | var router = express.Router(); |
4 | var path = require('path') | 4 | var path = require('path') |
5 | +var requestIp = require('request-ip'); | ||
5 | 6 | ||
6 | // 로그용 | 7 | // 로그용 |
7 | var logString; | 8 | var logString; |
... | @@ -23,13 +24,14 @@ function init(){ | ... | @@ -23,13 +24,14 @@ function init(){ |
23 | init() | 24 | init() |
24 | 25 | ||
25 | router.get('/', function(req, res){ | 26 | router.get('/', function(req, res){ |
27 | + var ip = requestIp.getClientIp(req); | ||
26 | var id = req.user; | 28 | var id = req.user; |
27 | if(!id){ | 29 | if(!id){ |
28 | - console.log(logString+"익명 유저의 로그아웃 시도를 거부했습니다.") | 30 | + console.log(logString+"익명 유저의 로그아웃 시도를 거부했습니다.("+ip+')') |
29 | res.redirect('/main') | 31 | res.redirect('/main') |
30 | } | 32 | } |
31 | else{ | 33 | else{ |
32 | - console.log(logString+req.user.ID+"("+req.user.nickname+") 유저가 로그아웃합니다.") | 34 | + console.log(logString+req.user.ID+"("+req.user.nickname+") 유저가 로그아웃합니다.("+ip+')') |
33 | req.logout(); | 35 | req.logout(); |
34 | req.session.save(function(){ | 36 | req.session.save(function(){ |
35 | res.redirect('/'); | 37 | res.redirect('/'); | ... | ... |
... | @@ -2,6 +2,7 @@ var express = require('express') | ... | @@ -2,6 +2,7 @@ var express = require('express') |
2 | var app = express() | 2 | var app = express() |
3 | var router = express.Router(); | 3 | var router = express.Router(); |
4 | var path = require('path') // 상대경로 | 4 | var path = require('path') // 상대경로 |
5 | +var requestIp = require('request-ip'); | ||
5 | 6 | ||
6 | // 로그용 | 7 | // 로그용 |
7 | var logString; | 8 | var logString; |
... | @@ -24,14 +25,15 @@ init() | ... | @@ -24,14 +25,15 @@ init() |
24 | 25 | ||
25 | // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. | 26 | // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. |
26 | router.get('/', function(req, res){ | 27 | router.get('/', function(req, res){ |
28 | + var ip = requestIp.getClientIp(req); | ||
27 | var id = req.user; | 29 | var id = req.user; |
28 | if(!id){ | 30 | if(!id){ |
29 | - console.log(logString+'익명의 유저가 작업 중입니다.') | 31 | + console.log(logString+'익명의 유저가 작업 중입니다.('+ip+')') |
30 | res.sendFile(path.join(__dirname, "../../public/main.html")) | 32 | res.sendFile(path.join(__dirname, "../../public/main.html")) |
31 | } | 33 | } |
32 | if(id){ | 34 | if(id){ |
33 | var nickname = req.user.nickname; | 35 | var nickname = req.user.nickname; |
34 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.') | 36 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.('+ip+')') |
35 | res.render('main.ejs', {'ID': id, 'nickname': nickname}); | 37 | res.render('main.ejs', {'ID': id, 'nickname': nickname}); |
36 | } | 38 | } |
37 | }); | 39 | }); | ... | ... |
... | @@ -6,6 +6,7 @@ var mysql_odbc = require('../../db/db_board')(); | ... | @@ -6,6 +6,7 @@ var mysql_odbc = require('../../db/db_board')(); |
6 | var myinfo = mysql_odbc.init(); | 6 | var myinfo = mysql_odbc.init(); |
7 | var passport = require('passport') | 7 | var passport = require('passport') |
8 | var LocalStrategy = require('passport-local').Strategy | 8 | var LocalStrategy = require('passport-local').Strategy |
9 | +var requestIp = require('request-ip'); | ||
9 | 10 | ||
10 | // 로그용 | 11 | // 로그용 |
11 | var logString; | 12 | var logString; |
... | @@ -39,6 +40,7 @@ passport.deserializeUser(function(user, done){ | ... | @@ -39,6 +40,7 @@ passport.deserializeUser(function(user, done){ |
39 | 40 | ||
40 | // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. | 41 | // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. |
41 | router.get('/', function(req, res){ | 42 | router.get('/', function(req, res){ |
43 | + var ip = requestIp.getClientIp(req); | ||
42 | try{ | 44 | try{ |
43 | var id = req.session.passport.user.ID; | 45 | var id = req.session.passport.user.ID; |
44 | // if(!id){ | 46 | // if(!id){ |
... | @@ -53,18 +55,19 @@ router.get('/', function(req, res){ | ... | @@ -53,18 +55,19 @@ router.get('/', function(req, res){ |
53 | var nickname = req.user.nickname; | 55 | var nickname = req.user.nickname; |
54 | var type = rows[0].type; | 56 | var type = rows[0].type; |
55 | var profilemsg = rows[0].profilemsg; | 57 | var profilemsg = rows[0].profilemsg; |
56 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필을 보고있습니다.') | 58 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필을 보고있습니다.('+ip+')') |
57 | res.render('profile.ejs', {'ID':id, 'nickname': nickname, 'type': type, 'profilemsg': profilemsg}) | 59 | res.render('profile.ejs', {'ID':id, 'nickname': nickname, 'type': type, 'profilemsg': profilemsg}) |
58 | }) | 60 | }) |
59 | } | 61 | } |
60 | catch{ | 62 | catch{ |
61 | - console.log(logString+'익명 유저의 프로필 접근 시도를 거부했습니다.') | 63 | + console.log(logString+'익명 유저의 프로필 접근 시도를 거부했습니다.('+ip+')') |
62 | res.sendFile(path.join(__dirname, "../../public/login.html")) | 64 | res.sendFile(path.join(__dirname, "../../public/login.html")) |
63 | } | 65 | } |
64 | 66 | ||
65 | }); | 67 | }); |
66 | 68 | ||
67 | router.get('/update', function(req,res){ | 69 | router.get('/update', function(req,res){ |
70 | + var ip = requestIp.getClientIp(req); | ||
68 | try{ | 71 | try{ |
69 | var id = req.user.ID; | 72 | var id = req.user.ID; |
70 | // if(!id){ | 73 | // if(!id){ |
... | @@ -80,19 +83,20 @@ router.get('/update', function(req,res){ | ... | @@ -80,19 +83,20 @@ router.get('/update', function(req,res){ |
80 | var nickname = req.user.nickname; | 83 | var nickname = req.user.nickname; |
81 | var type = req.user.type; | 84 | var type = req.user.type; |
82 | var profilemsg = rows[0].profilemsg; | 85 | var profilemsg = rows[0].profilemsg; |
83 | - console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필 수정 중입니다.') | 86 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필 수정 중입니다.('+ip+')') |
84 | res.render('profmsgedit.ejs', {'ID':id, 'nickname': nickname, 'type':type, 'profilemsg': profilemsg, 'message':''}); | 87 | res.render('profmsgedit.ejs', {'ID':id, 'nickname': nickname, 'type':type, 'profilemsg': profilemsg, 'message':''}); |
85 | }) | 88 | }) |
86 | } | 89 | } |
87 | catch{ | 90 | catch{ |
88 | if(!id){ | 91 | if(!id){ |
89 | - console.log(logString+'익명 유저의 프로필 수정 시도를 거부했습니다.') | 92 | + console.log(logString+'익명 유저의 프로필 수정 시도를 거부했습니다.('+ip+')') |
90 | res.sendFile(path.join(__dirname, "../../public/login.html")) | 93 | res.sendFile(path.join(__dirname, "../../public/login.html")) |
91 | } | 94 | } |
92 | } | 95 | } |
93 | }) | 96 | }) |
94 | 97 | ||
95 | router.post('/update', function(req,res,next){ | 98 | router.post('/update', function(req,res,next){ |
99 | + var ip = requestIp.getClientIp(req); | ||
96 | var id = req.user.ID; | 100 | var id = req.user.ID; |
97 | var profilemsg = req.body.profilemsg; | 101 | var profilemsg = req.body.profilemsg; |
98 | var nickname = req.body.nickname; | 102 | var nickname = req.body.nickname; |
... | @@ -127,7 +131,7 @@ router.post('/update', function(req,res,next){ | ... | @@ -127,7 +131,7 @@ router.post('/update', function(req,res,next){ |
127 | myinfo.query(sql,datas,function(err,result){ | 131 | myinfo.query(sql,datas,function(err,result){ |
128 | if(err) console.error(err) | 132 | if(err) console.error(err) |
129 | 133 | ||
130 | - console.log(logString+req.user.ID+'('+req.session.passport.user.nickname+') 유저가 프로필을 수정했습니다.') | 134 | + console.log(logString+req.user.ID+'('+req.session.passport.user.nickname+') 유저가 프로필을 수정했습니다.('+ip+')') |
131 | console.log(" ▷ 변경전: "+id+"("+req.user.nickname+") "+oldType+" // "+oldProfilemsg) | 135 | console.log(" ▷ 변경전: "+id+"("+req.user.nickname+") "+oldType+" // "+oldProfilemsg) |
132 | req.session.passport.user.nickname = nickname; | 136 | req.session.passport.user.nickname = nickname; |
133 | console.log(" ▶ 변경후: "+id+"("+nickname+") "+type+" // "+profilemsg) | 137 | console.log(" ▶ 변경후: "+id+"("+nickname+") "+type+" // "+profilemsg) |
... | @@ -135,7 +139,7 @@ router.post('/update', function(req,res,next){ | ... | @@ -135,7 +139,7 @@ router.post('/update', function(req,res,next){ |
135 | }) | 139 | }) |
136 | } | 140 | } |
137 | else{ // 다른 유저의 닉네임과 중복되는 경우 | 141 | else{ // 다른 유저의 닉네임과 중복되는 경우 |
138 | - console.log(logString+id+" 유저가 중복된 닉네임으로 변경을 시도했습니다.(시도한 닉네임: "+req.body.nickname+")") | 142 | + console.log(logString+id+" 유저가 중복된 닉네임으로 변경을 시도했습니다.(시도한 닉네임: "+req.body.nickname+" // ("+ip+')') |
139 | res.render('profmsgedit.ejs', {nickname: req.session.passport.user.nickname, profilemsg: oldProfilemsg, message : '중복된 닉네임입니다.'}) | 143 | res.render('profmsgedit.ejs', {nickname: req.session.passport.user.nickname, profilemsg: oldProfilemsg, message : '중복된 닉네임입니다.'}) |
140 | } | 144 | } |
141 | }) | 145 | }) | ... | ... |
... | @@ -5,6 +5,7 @@ var path = require('path') // 상대경로 | ... | @@ -5,6 +5,7 @@ var path = require('path') // 상대경로 |
5 | var mysql = require('mysql') | 5 | var mysql = require('mysql') |
6 | var passport = require('passport') | 6 | var passport = require('passport') |
7 | var LocalStrategy = require('passport-local').Strategy | 7 | var LocalStrategy = require('passport-local').Strategy |
8 | +var requestIp = require('request-ip'); | ||
8 | 9 | ||
9 | // 로그용 | 10 | // 로그용 |
10 | var logString; | 11 | var logString; |
... | @@ -39,7 +40,8 @@ router.get('/', function(req, res){ | ... | @@ -39,7 +40,8 @@ router.get('/', function(req, res){ |
39 | var msg; | 40 | var msg; |
40 | var errMsg = req.flash('error') | 41 | var errMsg = req.flash('error') |
41 | if(errMsg) msg = errMsg; | 42 | if(errMsg) msg = errMsg; |
42 | - console.log(logString+'익명의 유저가 회원가입 중입니다.') | 43 | + var ip = requestIp.getClientIp(req); |
44 | + console.log(logString+'익명의 유저가 회원가입 중입니다.('+ip+')') | ||
43 | res.render('register.ejs', {'message' : msg}); | 45 | res.render('register.ejs', {'message' : msg}); |
44 | }) | 46 | }) |
45 | 47 | ||
... | @@ -63,29 +65,30 @@ passport.use('local-join', new LocalStrategy({ | ... | @@ -63,29 +65,30 @@ passport.use('local-join', new LocalStrategy({ |
63 | passReqToCallback: true | 65 | passReqToCallback: true |
64 | }, function(req, ID, password, done){ | 66 | }, function(req, ID, password, done){ |
65 | var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){ | 67 | var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){ |
66 | - if(err) return done(err); | 68 | + var ip = requestIp.getClientIp(req); |
69 | + if(err) return done(err); | ||
67 | 70 | ||
68 | if(rows.length){ // database에 입력한 ID값이 있는가? | 71 | if(rows.length){ // database에 입력한 ID값이 있는가? |
69 | - console.log(logString+"회원가입 알림: 중복된 ID입니다.("+ID+")") | 72 | + console.log(logString+"회원가입 알림: 중복된 ID입니다.("+ID+" // "+ip+')') |
70 | return done(null, false, {message : '중복된 ID입니다.'}) | 73 | return done(null, false, {message : '중복된 ID입니다.'}) |
71 | } | 74 | } |
72 | else{ | 75 | else{ |
73 | if(password != req.body.pw_com){ // 비밀번호와 확인이 같지 않은가? | 76 | if(password != req.body.pw_com){ // 비밀번호와 확인이 같지 않은가? |
74 | - console.log(logString+"회원가입 알림: 비밀번호가 일치하지 않습니다.(시도 중인 아이디: "+ID+")") | 77 | + console.log(logString+"회원가입 알림: 비밀번호가 일치하지 않습니다.(시도 중인 아이디: "+ID+" // "+ip+')') |
75 | return done(null, false, {message : '비밀번호가 일치하지 않습니다.'}) | 78 | return done(null, false, {message : '비밀번호가 일치하지 않습니다.'}) |
76 | } | 79 | } |
77 | else{ | 80 | else{ |
78 | var subqry = connection.query('select * from userDB where nickname=?', [req.body.nickname], function(err, rows_){ | 81 | var subqry = connection.query('select * from userDB where nickname=?', [req.body.nickname], function(err, rows_){ |
79 | if(err) return done(err); | 82 | if(err) return done(err); |
80 | if(rows_.length){ | 83 | if(rows_.length){ |
81 | - console.log(logString+"회원가입 알림: 중복된 닉네임입니다.("+req.body.nickname+")") | 84 | + console.log(logString+"회원가입 알림: 중복된 닉네임입니다.("+req.body.nickname+" // "+ip+')') |
82 | return done(null, false, {message : '중복된 닉네임입니다.'}) | 85 | return done(null, false, {message : '중복된 닉네임입니다.'}) |
83 | } | 86 | } |
84 | else{ | 87 | else{ |
85 | var sql = {ID: ID, password: password, type:req.body.type, nickname:req.body.nickname}; | 88 | var sql = {ID: ID, password: password, type:req.body.type, nickname:req.body.nickname}; |
86 | var query = connection.query('insert into userDB set ?', sql, function(err, rows){ | 89 | var query = connection.query('insert into userDB set ?', sql, function(err, rows){ |
87 | if(err) throw err | 90 | if(err) throw err |
88 | - console.log(logString+"회원가입 알림: 사용자가 추가되었습니다.(" + ID +", " + req.body.nickname + ")") | 91 | + console.log(logString+"회원가입 알림: 사용자가 추가되었습니다.(" + ID +", " + req.body.nickname + " // "+ip+')') |
89 | return done(null, {'ID' : ID, 'nickname' : req.body.nickname}); | 92 | return done(null, {'ID' : ID, 'nickname' : req.body.nickname}); |
90 | }) | 93 | }) |
91 | } | 94 | } | ... | ... |
-
Please register or login to post a comment