@nuka9510/simple-validation 1.0.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,24 +38,38 @@
38
38
  npm i @nuka9510/simple-validation
39
39
  ```
40
40
  ## Usage
41
- ### npm
41
+ ### js (> 1.1.0)
42
+ #### cdn
43
+ ```
44
+ <script src="https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation/dist/index.min.js"> </script>
45
+ ```
46
+ or
47
+ ```
48
+ <script src="https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation@latest/dist/index.min.js"> </script>
49
+ ```
50
+ or
51
+ ```
52
+ <script src="https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation@<specific-version>/dist/index.min.js"> </script>
53
+ ```
54
+ ### module
55
+ #### npm
42
56
  ```
43
57
  <script type="importmap">
44
58
  {
45
59
  "imports": {
46
- "@nuka9510/js-util": "<path>/node_modules/@nuka9510/js-util/dist/index.js",
47
- "@nuka9510/simple-validation": "<path>/node_modules/@nuka9510/simple-validation/dist/index.js"
60
+ "@nuka9510/js-util": "<path>/node_modules/@nuka9510/js-util/dist/index.mjs",
61
+ "@nuka9510/simple-validation": "<path>/node_modules/@nuka9510/simple-validation/dist/index.mjs"
48
62
  }
49
63
  }
50
64
  </script>
51
65
  ```
52
- ### cdn
66
+ #### cdn
53
67
  ```
54
68
  <script type="importmap">
55
69
  {
56
70
  "imports": {
57
- "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util/dist/index.js",
58
- "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation/dist/index.js"
71
+ "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util/dist/index.mjs",
72
+ "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation/dist/index.mjs"
59
73
  }
60
74
  }
61
75
  </script>
@@ -65,8 +79,8 @@ or
65
79
  <script type="importmap">
66
80
  {
67
81
  "imports": {
68
- "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util@latest/dist/index.js",
69
- "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation@latest/dist/index.js"
82
+ "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util@latest/dist/index.mjs",
83
+ "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation@latest/dist/index.mjs"
70
84
  }
71
85
  }
72
86
  </script>
@@ -76,8 +90,8 @@ or
76
90
  <script type="importmap">
77
91
  {
78
92
  "imports": {
79
- "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util@<specific-version>/dist/index.js",
80
- "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation@<specific-version>/dist/index.js"
93
+ "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util@<specific-version>/dist/index.mjs",
94
+ "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation@<specific-version>/dist/index.mjs"
81
95
  }
82
96
  }
83
97
  </script>
@@ -86,11 +100,11 @@ or
86
100
  ```
87
101
  example
88
102
  ├── js
89
- │ └── index.js
103
+ │ └── index.mjs
90
104
  └── view
91
105
  └── index.html
92
106
  ```
93
- * example/js/index.js
107
+ * example/js/index.mjs
94
108
  ```
95
109
  import { SValidation } from "@nuka9510/simple-validation";
96
110
 
@@ -139,11 +153,11 @@ new Index();
139
153
  <script type="importmap">
140
154
  {
141
155
  "imports": {
142
- "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util/dist/index.js",
143
- "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation/dist/index.js"
156
+ "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util/dist/index.mjs",
157
+ "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation/dist/index.mjs"
144
158
  }
145
159
  }
146
160
  </script>
147
- <script type="module" src="../js/index.js"></script>
161
+ <script type="module" src="../js/index.mjs"></script>
148
162
  </html>
149
163
  ```
@@ -0,0 +1,2 @@
1
+ import Validation from "./validation.mjs";
2
+ export { Validation as SValidation };
package/dist/index.js CHANGED
@@ -1,2 +1,884 @@
1
- import Validation from "./validation.js";
2
- export { Validation as SValidation };
1
+ /******/ (() => { // webpackBootstrap
2
+ /******/ var __webpack_modules__ = ([
3
+ /* 0 */,
4
+ /* 1 */
5
+ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
6
+
7
+ "use strict";
8
+ __webpack_require__.r(__webpack_exports__);
9
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10
+ /* harmony export */ "default": () => (/* binding */ Validation)
11
+ /* harmony export */ });
12
+ /* harmony import */ var _nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
13
+
14
+ /**
15
+ * Validation Check를 위한 객체
16
+ */
17
+ class Validation {
18
+ /** 결과 값 객체 */
19
+ result;
20
+ /** validation check할 Element를 담는 객체 */
21
+ #el;
22
+ /** validation check할 radio Element를 담는 객체 */
23
+ #radio;
24
+ /** validation check에 사용할 정규식을 담은 객체 */
25
+ #regex;
26
+ /**
27
+ * Validation Check를 위한 객체
28
+ *
29
+ * ```
30
+ * <form name="form">
31
+ * <input type="text" name="text" data-sv-pattern="password" data-sv-input-name="비밀번호" minlength="0" maxlength="10">
32
+ * <input type="text" name="text" data-sv-pattern="password" minlength="0" maxlength="10" required="비밀번호">
33
+ * <input type="date" name="sdate1" data-sv-date="date1" data-sv-date-state="S" data-sv-input-name="검색일1">
34
+ * <input type="date" name="edate1" data-sv-date="date1" data-sv-date-state="E" data-sv-input-name="검색일1">
35
+ * <input type="date" name="sdate2" data-sv-date="date2" data-sv-date-state="S" required="검색일2">
36
+ * <input type="date" name="edate2" data-sv-date="date2" data-sv-date-state="E" required="검색일2">
37
+ * </form>
38
+ * <script type="importmap">
39
+ * {
40
+ * "imports": {
41
+ * "@nuka9510/js-util": "https://cdn.jsdelivr.net/npm/@nuka9510/js-util/dist/index.js",
42
+ * "@nuka9510/simple-validation": "https://cdn.jsdelivr.net/npm/@nuka9510/simple-validation/dist/index.js"
43
+ * }
44
+ * }
45
+ * </script>
46
+ * <script type="module">
47
+ * import { SValidation } from "@nuka9510/simple-validation";
48
+ *
49
+ * const validation = new SValidation({regex: {password: /^[\S!?@#$%^&*():;+-=~{}<>\_\[\]\|\\\"\'\,\.\/\`]{6,10}$/}});
50
+ *
51
+ * validation.run(form);
52
+ *
53
+ * if (validation.result.flag) {
54
+ * form.submit();
55
+ * } else {
56
+ * alert(validation.result.alertMsg);
57
+ * validation.result.el.focus();
58
+ * }
59
+ * </script>
60
+ * ```
61
+ */
62
+ constructor(config) { this.init(config); }
63
+ /** 객체 초기화 */
64
+ init(
65
+ /** validation 초기화를 위한 객체 */ config = null) {
66
+ this.#resultInit();
67
+ this.#elInit();
68
+ this.#radioInit();
69
+ this.#regexInit(config?.regex);
70
+ }
71
+ /** 결과 값 초기화 */
72
+ #resultInit() {
73
+ this.result = {
74
+ flag: true,
75
+ alertMsg: null,
76
+ el: null
77
+ };
78
+ }
79
+ /** validation check할 Element를 담는 객체 초기화 */
80
+ #elInit() { this.#el = {}; }
81
+ /** validation check할 radio Element를 담는 객체 초기화 */
82
+ #radioInit() { this.#radio = {}; }
83
+ /** validation check에 사용할 정규식을 담은 객체 초기화 */
84
+ #regexInit(regex = null) {
85
+ this.#regex = (!_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(regex) &&
86
+ _nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.isObject(regex))
87
+ ? {
88
+ ...this.#regex,
89
+ ...regex
90
+ }
91
+ : { ...this.#regex };
92
+ }
93
+ /** el에 있는 Element들을 required check한다. */
94
+ #required(el) {
95
+ const required = el.getAttribute('required');
96
+ if (!_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(required)) {
97
+ if (el.type == 'radio') {
98
+ this.#setRadio(el);
99
+ }
100
+ else if (_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(el.value)) {
101
+ this.result.flag = false;
102
+ this.result.alertMsg = `'${required}'을/를 입력해 주세요.`;
103
+ this.result.el = el;
104
+ }
105
+ }
106
+ }
107
+ /** radio에 있는 Element들을 required check한다. */
108
+ #requiredRadio() {
109
+ for (const i in this.#radio) {
110
+ const el = this.#radio[i][0], flag = this.#radio[i].some((...arg) => arg[0].checked);
111
+ if (!flag) {
112
+ this.result.flag = false;
113
+ this.result.alertMsg = `'${i}'을/를 선택해주세요.`;
114
+ this.result.el = el;
115
+ break;
116
+ }
117
+ }
118
+ }
119
+ /** el에 Element를 담는다. */
120
+ #setEl(el) {
121
+ const pattern = el.dataset['svPattern'], date = el.dataset['svDate'];
122
+ if (!_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(pattern)) {
123
+ if (_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(this.#el.el)) {
124
+ this.#el.el = [];
125
+ }
126
+ this.#el.el?.push(el);
127
+ }
128
+ if (!_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(date)) {
129
+ const state = el.dataset['svDateState'];
130
+ switch (state) {
131
+ case 'S':
132
+ case 'E':
133
+ if (_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(this.#el.date)) {
134
+ this.#el.date = {};
135
+ }
136
+ if (_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(this.#el.date[date])) {
137
+ this.#el.date[date] = {};
138
+ }
139
+ this.#el.date[date][state] = el;
140
+ break;
141
+ }
142
+ }
143
+ }
144
+ /** `#radio`에 type이 'radio'인 Element를 담는다. */
145
+ #setRadio(el) {
146
+ const required = el.getAttribute('required');
147
+ if (!_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(required)) {
148
+ if (_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(this.#radio[required])) {
149
+ this.#radio[required] = [el];
150
+ }
151
+ else {
152
+ this.#radio[required].push(el);
153
+ }
154
+ }
155
+ }
156
+ /**
157
+ * Element들을 validation check 한다.
158
+ * ```
159
+ * -----------------------
160
+ * date : isDate
161
+ * -----------------------
162
+ * el : isPattern
163
+ * ```
164
+ */
165
+ #match() {
166
+ for (const i in this.#el) {
167
+ if (this.result.flag) {
168
+ switch (i) {
169
+ case 'date':
170
+ this.#isDate(this.#el[i]);
171
+ break;
172
+ case 'el':
173
+ this.#isPattern(this.#el[i]);
174
+ break;
175
+ }
176
+ }
177
+ else {
178
+ break;
179
+ }
180
+ }
181
+ }
182
+ /** date check */
183
+ #isDate(el) {
184
+ for (const i in el) {
185
+ if (this.result.flag) {
186
+ const sdate = el[i].S.value, edate = el[i].E.value;
187
+ if (!_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(sdate) &&
188
+ !_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(edate)) {
189
+ const inputName = el[i].S.dataset['svInputName'] ||
190
+ el[i].E.dataset['svInputName'], required = el[i].S.getAttribute('required') ||
191
+ el[i].E.getAttribute('required');
192
+ if ((new Date(sdate)).getTime() > (new Date(edate)).getTime()) {
193
+ this.result.flag = false;
194
+ this.result.alertMsg = `'${inputName || required}'의 시작일이 종료일 보다 늦습니다.`;
195
+ this.result.el = el[i].S;
196
+ }
197
+ }
198
+ }
199
+ else {
200
+ break;
201
+ }
202
+ }
203
+ }
204
+ /** regex check */
205
+ #isPattern(el) {
206
+ if (Array.isArray(el)) {
207
+ for (const i of el) {
208
+ const pattern = i.dataset['svPattern'], inputName = i.dataset['svInputName'], required = i.getAttribute('required'), val = i.value;
209
+ if (Object.keys(this.#regex).includes(pattern)) {
210
+ if (!_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(val) &&
211
+ !this.#regex[pattern].test(val)) {
212
+ this.result.flag = false;
213
+ this.result.alertMsg = `'${inputName || required}'의 형식이 올바르지 않습니다.`;
214
+ this.result.el = i;
215
+ break;
216
+ }
217
+ }
218
+ }
219
+ }
220
+ else {
221
+ const pattern = el.dataset['svPattern'], inputName = el.dataset['svInputName'], required = el.getAttribute('required'), val = el.value;
222
+ if (Object.keys(this.#regex).includes(pattern)) {
223
+ if (!_nuka9510_js_util__WEBPACK_IMPORTED_MODULE_0__.JUtil.empty(val) &&
224
+ !this.#regex[pattern].test(val)) {
225
+ this.result.flag = false;
226
+ this.result.alertMsg = `'${inputName || required}'의 형식이 올바르지 않습니다.`;
227
+ this.result.el = el;
228
+ }
229
+ }
230
+ }
231
+ }
232
+ /** Element value의 length를 check 한다. */
233
+ #length() {
234
+ for (const i in this.#el) {
235
+ if (i == 'el' &&
236
+ this.result.flag) {
237
+ for (const j of this.#el[i]) {
238
+ const inputName = j.dataset['svInputName'], required = j.getAttribute('required'), val = j.value.length;
239
+ if (!(j instanceof HTMLSelectElement)) {
240
+ if (j.minLength >= 0 &&
241
+ j.maxLength >= 0) {
242
+ if (val < j.minLength ||
243
+ val > j.maxLength) {
244
+ this.result.flag = false;
245
+ this.result.alertMsg = `'${inputName || required}'은/는 ${j.minLength}~${j.maxLength}자 이내로 입력해주세요.`;
246
+ this.result.el = j;
247
+ break;
248
+ }
249
+ }
250
+ else if (j.minLength >= 0 &&
251
+ j.maxLength < 0) {
252
+ if (val < j.minLength) {
253
+ this.result.flag = false;
254
+ this.result.alertMsg = `'${inputName || required}'은/는 ${j.minLength}자 이상으로 입력해주세요.`;
255
+ this.result.el = j;
256
+ break;
257
+ }
258
+ }
259
+ else if (j.minLength < 0 &&
260
+ j.maxLength >= 0) {
261
+ if (val > j.maxLength) {
262
+ this.result.flag = false;
263
+ this.result.alertMsg = `'${inputName || required}'은/는 ${j.maxLength}자 이하로 입력해주세요.`;
264
+ this.result.el = j;
265
+ break;
266
+ }
267
+ }
268
+ }
269
+ }
270
+ }
271
+ else if (!this.result.flag) {
272
+ break;
273
+ }
274
+ }
275
+ }
276
+ /** validation을 실행한다. */
277
+ run(form) {
278
+ this.init();
279
+ for (const el of form.elements) {
280
+ if (this.result.flag) {
281
+ if (['INPUT', 'SELECT', 'TEXTAREA'].includes(el.tagName)) {
282
+ if (!el.disabled) {
283
+ this.#required(el);
284
+ this.#setEl(el);
285
+ }
286
+ }
287
+ }
288
+ else {
289
+ break;
290
+ }
291
+ }
292
+ if (this.result.flag) {
293
+ this.#requiredRadio();
294
+ }
295
+ if (this.result.flag) {
296
+ this.#match();
297
+ }
298
+ if (this.result.flag) {
299
+ this.#length();
300
+ }
301
+ }
302
+ }
303
+
304
+
305
+ /***/ }),
306
+ /* 2 */
307
+ /***/ ((__unused_webpack_module, exports) => {
308
+
309
+ /******/ (() => { // webpackBootstrap
310
+ /******/ "use strict";
311
+ /******/ var __webpack_modules__ = ([
312
+ /* 0 */,
313
+ /* 1 */
314
+ /***/ ((__unused_webpack___webpack_module__, __nested_webpack_exports__, __nested_webpack_require_184__) => {
315
+
316
+ __nested_webpack_require_184__.r(__nested_webpack_exports__);
317
+ /* harmony export */ __nested_webpack_require_184__.d(__nested_webpack_exports__, {
318
+ /* harmony export */ "default": () => (/* binding */ Util)
319
+ /* harmony export */ });
320
+ class Util {
321
+ /**
322
+ * 값이 비어있는지 확인한다.
323
+ *
324
+ * ```
325
+ * // returns true
326
+ * empty(undefined);
327
+ * empty(null);
328
+ * empty(0);
329
+ * empty('');
330
+ * empty([]);
331
+ * empty({});
332
+ * ```
333
+ */
334
+ static empty(
335
+ /** 확인할 값 */ arg) {
336
+ let result = [undefined, null, 0, ''].includes(arg);
337
+ if (!result) {
338
+ if (arg.constructor == Object) {
339
+ result = Object.keys(arg).length == 0 &&
340
+ Object.keys(Object.getPrototypeOf(arg)).length == 0;
341
+ }
342
+ else if (arg.constructor == NodeList) {
343
+ result = arg.length == 0;
344
+ }
345
+ else if (Array.isArray(arg)) {
346
+ result = arg.length == 0;
347
+ }
348
+ }
349
+ return result;
350
+ }
351
+ /**
352
+ * 값이 숫자인지 확인한다.
353
+ *
354
+ * ```
355
+ * // returns true
356
+ * isNumber(1);
357
+ * isNumber('1');
358
+ *
359
+ * // returns false
360
+ * isNumber('test');
361
+ * isNumber('1', true);
362
+ * ```
363
+ */
364
+ static isNumber(
365
+ /** 확인할 값 */ arg,
366
+ /** `true`일 경우 `arg`의 `type`도 확인 #default `false` */ strict = false) {
367
+ let result = !Number.isNaN(Number(arg)) &&
368
+ ['number', 'string'].includes(typeof arg) &&
369
+ !/^\s*$/.test(`${arg}`);
370
+ if (result &&
371
+ strict) {
372
+ result = typeof arg == 'number';
373
+ }
374
+ return result;
375
+ }
376
+ /**
377
+ * 해당 값이 객체인지 확인
378
+ *
379
+ * ```
380
+ * // returns true
381
+ * isObject({});
382
+ *
383
+ * // returns false
384
+ * isObject(undefined);
385
+ * isObject(null);
386
+ * isObject(0);
387
+ * isObject('');
388
+ * isObject([]);
389
+ * ```
390
+ */
391
+ static isObject(
392
+ /** 확인할 값 */ arg) { return arg?.constructor == Object; }
393
+ /**
394
+ * 천 단위 마다 그룹화 된 숫자 형식으로 변환한 문자열을 반환 한다.
395
+ *
396
+ * ```
397
+ * // returns '1,000'
398
+ * numberFormat(1000);
399
+ * numberFormat(1000.01);
400
+ *
401
+ * // returns '1,000.0'
402
+ * numberFormat(1000.01, 1);
403
+ *
404
+ * // returns '1,000 0'
405
+ * numberFormat(1000.01, 1, ' ');
406
+ *
407
+ * // returns '1.000 0'
408
+ * numberFormat(1000.01, 1, ' ', '.');
409
+ * ```
410
+ */
411
+ static numberFormat(
412
+ /** 변환할 숫자 */ num,
413
+ /** 소숫점 아래 자리 수 #default `0` */ decimals = 0,
414
+ /** 소수점 구분자 #default `'.'` */ decimalSeparator = '.',
415
+ /** 천 단위 구분자 #default `','` */ thousandsSeparator = ',') {
416
+ const result = String(num).split('.');
417
+ result[0] = result[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
418
+ if (!Util.empty(result[1])) {
419
+ result[1] = result[1].substring(0, decimals);
420
+ }
421
+ return (!Util.empty(result[1])) ? result[0].concat(decimalSeparator, result[1]) : result[0];
422
+ }
423
+ /**
424
+ * 주어진 포맷에 따라 `Date`객체를 문자열로 변환
425
+ *
426
+ * ```
427
+ * const date = new Date(2022, 9, 27);
428
+ *
429
+ * // returns '2022-10-27'
430
+ * strftime(date, '%Y-%m-%d');
431
+ *
432
+ * // returns '2022/10/27'
433
+ * strftime(date, '%Y/%m/%d');
434
+ * ```
435
+ *
436
+ * `%a`: 요일을 축약된 이름으로 - Sun, Mon, …, Sat \
437
+ * `%A`: 요일을 전체 이름으로 - Sunday, Monday, …, Saturday \
438
+ * `%d`: 월중 일(day of the month)을 0으로 채워진 10진수로 - 01, 02, …, 31 \
439
+ * `%b`: 월을 축약된 이름으로 - Jan, Feb, …, Dec \
440
+ * `%B`: 월을 전체 이름으로 - January, February, …, December \
441
+ * `%m`: 월을 0으로 채워진 10진수로 - 01, 02, …, 12 \
442
+ * `%y`: 세기가 없는 해(year)를 0으로 채워진 10진수로 - 00, 01, …, 99 \
443
+ * `%Y`: 세기가 있는 해(year)를 10진수로 - 0001, 0002, …, 2013, 2014, …, 9998, 9999 \
444
+ * `%H`: 시(24시간제)를 0으로 채워진 십진수로 - 00, 01, …, 23 \
445
+ * `%I`: 시(12시간제)를 0으로 채워진 십진수로 - 01, 02, …, 12 \
446
+ * `%p`: 오전이나 오후에 해당하는 것 - AM, PM \
447
+ * `%M`: 분을 0으로 채워진 십진수로 - 00, 01, …, 59 \
448
+ * `%S`: 초를 0으로 채워진 10진수로 - 00, 01, …, 59 \
449
+ * `%%`: 리터럴 '%' 문자 - %
450
+ */
451
+ static strftime(
452
+ /** 변환할 `Date`객체 */ date,
453
+ /** 변활할 포맷 문자열 */ format) {
454
+ const month = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], week = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
455
+ format = format.replace(/(%{1})/g, '\\$1');
456
+ format = format.replace(/(\\%){2}/g, '%');
457
+ format = format.replace(/\\%Y/g, String(date.getFullYear()));
458
+ format = format.replace(/\\%y/g, String(date.getFullYear()).replace(/^\d+(\d{2})$/, '$1'));
459
+ format = format.replace(/\\%B/g, month[date.getMonth()]);
460
+ format = format.replace(/\\%b/g, month[date.getMonth()].replace(/^(\w{3})\w*$/, '$1'));
461
+ format = format.replace(/\\%m/g, String(date.getMonth() + 1).replace(/^(\d{1})$/, '0$1'));
462
+ format = format.replace(/\\%d/g, String(date.getDate()).replace(/^(\d{1})$/, '0$1'));
463
+ format = format.replace(/\\%A/g, week[date.getDay()]);
464
+ format = format.replace(/\\%a/g, week[date.getDay()].replace(/^(\w{3})\w*$/, '$1'));
465
+ format = format.replace(/\\%H/g, String(date.getHours()).replace(/^(\d{1})$/, '0$1'));
466
+ format = format.replace(/\\%I/g, String((date.getHours() > 12) ? (date.getHours() - 12) : date.getHours()).replace(/^0$/, '12').replace(/^(\d{1})$/, '0$1'));
467
+ format = format.replace(/\\%p/g, (date.getHours() < 12) ? 'AM' : 'PM');
468
+ format = format.replace(/\\%M/g, String(date.getMinutes()).replace(/^(\d{1})$/, '0$1'));
469
+ format = format.replace(/\\%S/g, String(date.getSeconds()).replace(/^(\d{1})$/, '0$1'));
470
+ return format;
471
+ }
472
+ /**
473
+ * 유효한 날짜인지 확인
474
+ *
475
+ * ```
476
+ * // returns true
477
+ * checkdate(2022, 10, 28);
478
+ *
479
+ * // returns false
480
+ * checkdate(2022, 10, 32);
481
+ * ```
482
+ */
483
+ static checkdate(
484
+ /** 년 */ year,
485
+ /** 월 */ month,
486
+ /** 일 */ day) {
487
+ const date = new Date(year, (month - 1), day);
488
+ return date.getFullYear() == year &&
489
+ (date.getMonth() + 1) == month &&
490
+ date.getDate() == day;
491
+ }
492
+ /**
493
+ * 같은 날짜인지 비교
494
+ *
495
+ * ```
496
+ * const date1 = new Date();
497
+ * const date2 = new Date();
498
+ *
499
+ * // returns true
500
+ * equaldate(date1);
501
+ * equaldate(date1, date2);
502
+ *
503
+ * // returns false
504
+ * date1.setDate(date1.getDate() + 1);
505
+ * date2.setDate(date2.getDate() + 2);
506
+ * equaldate(date1);
507
+ * equaldate(date1, date2);
508
+ * ```
509
+ */
510
+ static equaldate(
511
+ /** 기준 날짜 */ date1,
512
+ /** 비교할 날짜 #default `new Date()` */ date2 = new Date()) { return Util.strftime(date1, '%Y-%m-%d') == Util.strftime(date2, '%Y-%m-%d'); }
513
+ /**
514
+ * Date객체에서 해당 하는 요일을 반환한다.
515
+ *
516
+ * ```
517
+ * const date = new Date(2022, 9, 27);
518
+ *
519
+ * // returns '목요일'
520
+ * getWeek(date);
521
+ *
522
+ * // returns '목'
523
+ * getWeek(date, false);
524
+ * ```
525
+ */
526
+ static getWeek(
527
+ /** 요일을 반환할 `Date` 객체 */ date,
528
+ /** 해당 요일의 약어반환 대한 구분 값 `false`일 경우 약어 반환 #default `true` */ flag = true) {
529
+ const week = ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일'], result = week[date.getDay()];
530
+ return (flag) ? result : result.replace(/^([ㄱ-ㅎㅏ-ㅣ가-힣]{1})[ㄱ-ㅎㅏ-ㅣ가-힣]+$/, '$1');
531
+ }
532
+ /**
533
+ * `Date`객체에 `interval`를 더한 값을 반환한다.
534
+ *
535
+ * ```
536
+ * const date = new Date(2022, 8, 27);
537
+ *
538
+ * // returns '2022-10-28'
539
+ * strftime(util.addDate(date, {month: 1, day: 1}), '%Y-%m-%d');
540
+ * ```
541
+ */
542
+ static addDate(
543
+ /** 기준 `Date`객체 */ date,
544
+ /** `Date`객체에 계산할 `interval` */ interval) {
545
+ return new Date(date.getFullYear() + (Util.isNumber(interval.year, true) ? interval.year : 0), date.getMonth() + (Util.isNumber(interval.month, true) ? interval.month : 0), date.getDate() + (Util.isNumber(interval.day, true) ? interval.day : 0), date.getHours() + (Util.isNumber(interval.hour, true) ? interval.hour : 0), date.getMinutes() + (Util.isNumber(interval.minute, true) ? interval.minute : 0), date.getSeconds() + (Util.isNumber(interval.second, true) ? interval.second : 0), date.getMilliseconds() + (Util.isNumber(interval.millisecond, true) ? interval.millisecond : 0));
546
+ }
547
+ /**
548
+ * `Date`객체에 `interval`를 뺀 값을 반환한다.
549
+ *
550
+ * ```
551
+ * const date = new Date(2022, 8, 27);
552
+ *
553
+ * // returns '2022-08-26'
554
+ * strftime(util.subDate(date, {month: 1, day: 1}), '%Y-%m-%d');
555
+ * ```
556
+ */
557
+ static subDate(
558
+ /** 기준 `Date`객체 */ date,
559
+ /** `Date`객체에 계산할 `interval` */ interval) {
560
+ return new Date(date.getFullYear() - (Util.isNumber(interval.year, true) ? interval.year : 0), date.getMonth() - (Util.isNumber(interval.month, true) ? interval.month : 0), date.getDate() - (Util.isNumber(interval.day, true) ? interval.day : 0), date.getHours() - (Util.isNumber(interval.hour, true) ? interval.hour : 0), date.getMinutes() - (Util.isNumber(interval.minute, true) ? interval.minute : 0), date.getSeconds() - (Util.isNumber(interval.second, true) ? interval.second : 0), date.getMilliseconds() - (Util.isNumber(interval.millisecond, true) ? interval.millisecond : 0));
561
+ }
562
+ /**
563
+ * xor 비교
564
+ *
565
+ * ```
566
+ * // returns true
567
+ * xor(true, false);
568
+ * xor(false, true);
569
+ *
570
+ * // returns false
571
+ * xor(true, true);
572
+ * xor(false, false);
573
+ * ```
574
+ */
575
+ static xor(
576
+ /** 비교할 값 1 */ arg1,
577
+ /** 비교할 값 2 */ arg2) {
578
+ return !(arg1 && arg2) &&
579
+ (arg1 || arg2);
580
+ }
581
+ /**
582
+ * `FormDate`객체에 설정된 값을 `json`문자열로 반환 한다.
583
+ *
584
+ * ```
585
+ * const data = new FormData();
586
+ *
587
+ * data.append('key', value);
588
+ *
589
+ * const json = formDataToJson(data);
590
+ * ```
591
+ */
592
+ static formDataToJson(
593
+ /** `json`문자열로 반환할 `FormData`객체 */ formData) {
594
+ return JSON.stringify(Object.fromEntries([...new Set(formData.keys())].map((...arg) => [
595
+ arg[0],
596
+ (formData.getAll(arg[0]).length > 1)
597
+ ? formData.getAll(arg[0])
598
+ : formData.get(arg[0])
599
+ ])));
600
+ }
601
+ /**
602
+ * 기준 숫자의 백분율 값을 적용했을 경우의 값을 반환한다.
603
+ *
604
+ * ```
605
+ * // returns 10
606
+ * percentage(100, 10);
607
+ * ```
608
+ */
609
+ static percentage(
610
+ /** 기준 숫자 */ num,
611
+ /** 백분율 */ per) { return num * (per / 100); }
612
+ /**
613
+ * 기준 숫자의 비율 대비 값을 반환한다.
614
+ *
615
+ * ```
616
+ * // returns 8
617
+ * // 1 : 2 = 4 : x
618
+ * ratio([1, 2], 4);
619
+ *
620
+ * // returns 2
621
+ * // 1 : 2 = x : 4
622
+ * ratio([1, 2], 4, false);
623
+ * ```
624
+ */
625
+ static ratio(
626
+ /** 비율 */ ratio,
627
+ /** 기준 숫자 */ num,
628
+ /** 비율 적용 기준 #default `true` */ flag = true) {
629
+ const index = flag
630
+ ? [1, 0]
631
+ : [0, 1];
632
+ return (num * ratio[index[0]]) / ratio[index[1]];
633
+ }
634
+ /**
635
+ * `x` 번째의 항이 `a`이고 공차가 `d`인 등차수열의 `n` 번째 항을 반환 한다.
636
+ */
637
+ static arithmeticSequence(
638
+ /** 기준 항 */ a,
639
+ /** 기준 위치 `x > 0`인 정수 */ x,
640
+ /** 공차 */ d,
641
+ /** 반환 위치 */ n) { return a + ((n - x) * d); }
642
+ /**
643
+ * `x` 번째의 항이 `a`이고 공비가 `r`인 등비수열의 `n` 번째 항을 반환 한다.
644
+ */
645
+ static geometricSequence(
646
+ /** 기준 항 */ a,
647
+ /** 기준 위치 `x > 0`인 정수 */ x,
648
+ /** 공비 */ r,
649
+ /** 반환 위치 */ n) { return (a / (r ** (x - 1))) * (r ** (n - 1)); }
650
+ /**
651
+ * `value`를 반올림(round), 내림(floor), 올림(ceil) 한 값을 반환한다.
652
+ */
653
+ static decimalAdjust(
654
+ /** 구분 기준 `반올림(round)`, `내림(floor)`, `올림(ceil)` */ type,
655
+ /** 기준 값 */ value,
656
+ /** 소숫점 아래 자리 수 #default `0` */ exp = 0) {
657
+ const [m, n = '0'] = value.toString().split('e'), adjustValue = Math[type](Number(`${m}e${parseInt(n) + exp}`)), [nm, nn = '0'] = adjustValue.toString().split('e');
658
+ return Number(`${nm}e${parseInt(nn) - exp}`);
659
+ }
660
+ /**
661
+ * html entity를 인코딩 한다.
662
+ */
663
+ static encodeHtmlEntity(
664
+ /** html entity를 인코딩 할 문자열 */ arg) {
665
+ const textarea = document.createElement('textarea');
666
+ textarea.innerText = arg;
667
+ return textarea.innerHTML;
668
+ }
669
+ /**
670
+ * html entity를 디코딩 한다.
671
+ */
672
+ static decodeHtmlEntity(
673
+ /** html entity를 디코딩 할 문자열 */ arg) {
674
+ const textarea = document.createElement('textarea');
675
+ textarea.innerHTML = arg;
676
+ return textarea.innerText;
677
+ }
678
+ /**
679
+ * `Object`의 `deepCopy`를 반환 한다.
680
+ */
681
+ static copy(
682
+ /** `deepCopy`할 `object` */ arg) {
683
+ if (Util.isObject(arg)) {
684
+ const result = {};
685
+ for (const i in arg) {
686
+ result[i] = Util.copy(arg[i]);
687
+ }
688
+ return result;
689
+ }
690
+ else if (Array.isArray(arg)) {
691
+ const result = [];
692
+ for (const i of arg) {
693
+ result.push(Util.copy(i));
694
+ }
695
+ return result;
696
+ }
697
+ else {
698
+ return arg;
699
+ }
700
+ }
701
+ /**
702
+ * `sNum` <= x <= `eNum` 범위의 배열을 반환한다.
703
+ */
704
+ static numRange(
705
+ /** 시작 값 */ sNum,
706
+ /** 종료 값 */ eNum) {
707
+ let range = (eNum - sNum);
708
+ const flag = (range > 0);
709
+ range = Math.abs(range) + 1;
710
+ return [...new Array(range)].map((...arg) => (arg[1] * ((flag) ? 1 : -1)) + sNum);
711
+ }
712
+ /**
713
+ * `size`를 크기로 하는 `chunk`를 담은 배열을 반환한다.
714
+ */
715
+ static arrayChunk(
716
+ /** 기준 배열 */ arr,
717
+ /** `chunk`의 크기 (`size > 0`인 정수) */ size) {
718
+ if (!Util.isNumber(size, true)) {
719
+ throw new TypeError("size는 숫자 타입 이어야 합니다.");
720
+ }
721
+ if (size <= 0 &&
722
+ Number.isInteger(size)) {
723
+ throw new RangeError("size는 0보다 큰 정수여야 합니다.");
724
+ }
725
+ const _arr = [];
726
+ Util.numRange(0, Util.decimalAdjust('ceil', arr.length / size) + ((arr.length > 0) ? -1 : 0))
727
+ .forEach((...arg) => { _arr.push(arr.slice(arg[0] * size, (arg[0] + 1) * size)); });
728
+ return _arr;
729
+ }
730
+ }
731
+
732
+
733
+ /***/ })
734
+ /******/ ]);
735
+ /************************************************************************/
736
+ /******/ // The module cache
737
+ /******/ var __webpack_module_cache__ = {};
738
+ /******/
739
+ /******/ // The require function
740
+ /******/ function __nested_webpack_require_14055__(moduleId) {
741
+ /******/ // Check if module is in cache
742
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
743
+ /******/ if (cachedModule !== undefined) {
744
+ /******/ return cachedModule.exports;
745
+ /******/ }
746
+ /******/ // Create a new module (and put it into the cache)
747
+ /******/ var module = __webpack_module_cache__[moduleId] = {
748
+ /******/ // no module.id needed
749
+ /******/ // no module.loaded needed
750
+ /******/ exports: {}
751
+ /******/ };
752
+ /******/
753
+ /******/ // Execute the module function
754
+ /******/ __webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_14055__);
755
+ /******/
756
+ /******/ // Return the exports of the module
757
+ /******/ return module.exports;
758
+ /******/ }
759
+ /******/
760
+ /************************************************************************/
761
+ /******/ /* webpack/runtime/define property getters */
762
+ /******/ (() => {
763
+ /******/ // define getter functions for harmony exports
764
+ /******/ __nested_webpack_require_14055__.d = (exports, definition) => {
765
+ /******/ for(var key in definition) {
766
+ /******/ if(__nested_webpack_require_14055__.o(definition, key) && !__nested_webpack_require_14055__.o(exports, key)) {
767
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
768
+ /******/ }
769
+ /******/ }
770
+ /******/ };
771
+ /******/ })();
772
+ /******/
773
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
774
+ /******/ (() => {
775
+ /******/ __nested_webpack_require_14055__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
776
+ /******/ })();
777
+ /******/
778
+ /******/ /* webpack/runtime/make namespace object */
779
+ /******/ (() => {
780
+ /******/ // define __esModule on exports
781
+ /******/ __nested_webpack_require_14055__.r = (exports) => {
782
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
783
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
784
+ /******/ }
785
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
786
+ /******/ };
787
+ /******/ })();
788
+ /******/
789
+ /************************************************************************/
790
+ var __nested_webpack_exports__ = {};
791
+ // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
792
+ (() => {
793
+ __nested_webpack_require_14055__.r(__nested_webpack_exports__);
794
+ /* harmony export */ __nested_webpack_require_14055__.d(__nested_webpack_exports__, {
795
+ /* harmony export */ JUtil: () => (/* reexport safe */ _util_mjs__WEBPACK_IMPORTED_MODULE_0__["default"])
796
+ /* harmony export */ });
797
+ /* harmony import */ var _util_mjs__WEBPACK_IMPORTED_MODULE_0__ = __nested_webpack_require_14055__(1);
798
+
799
+
800
+
801
+ })();
802
+
803
+ var __webpack_export_target__ = exports;
804
+ for(var __webpack_i__ in __nested_webpack_exports__) __webpack_export_target__[__webpack_i__] = __nested_webpack_exports__[__webpack_i__];
805
+ if(__nested_webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
806
+ /******/ })()
807
+ ;
808
+
809
+ /***/ })
810
+ /******/ ]);
811
+ /************************************************************************/
812
+ /******/ // The module cache
813
+ /******/ var __webpack_module_cache__ = {};
814
+ /******/
815
+ /******/ // The require function
816
+ /******/ function __webpack_require__(moduleId) {
817
+ /******/ // Check if module is in cache
818
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
819
+ /******/ if (cachedModule !== undefined) {
820
+ /******/ return cachedModule.exports;
821
+ /******/ }
822
+ /******/ // Create a new module (and put it into the cache)
823
+ /******/ var module = __webpack_module_cache__[moduleId] = {
824
+ /******/ // no module.id needed
825
+ /******/ // no module.loaded needed
826
+ /******/ exports: {}
827
+ /******/ };
828
+ /******/
829
+ /******/ // Execute the module function
830
+ /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
831
+ /******/
832
+ /******/ // Return the exports of the module
833
+ /******/ return module.exports;
834
+ /******/ }
835
+ /******/
836
+ /************************************************************************/
837
+ /******/ /* webpack/runtime/define property getters */
838
+ /******/ (() => {
839
+ /******/ // define getter functions for harmony exports
840
+ /******/ __webpack_require__.d = (exports, definition) => {
841
+ /******/ for(var key in definition) {
842
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
843
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
844
+ /******/ }
845
+ /******/ }
846
+ /******/ };
847
+ /******/ })();
848
+ /******/
849
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
850
+ /******/ (() => {
851
+ /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
852
+ /******/ })();
853
+ /******/
854
+ /******/ /* webpack/runtime/make namespace object */
855
+ /******/ (() => {
856
+ /******/ // define __esModule on exports
857
+ /******/ __webpack_require__.r = (exports) => {
858
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
859
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
860
+ /******/ }
861
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
862
+ /******/ };
863
+ /******/ })();
864
+ /******/
865
+ /************************************************************************/
866
+ var __webpack_exports__ = {};
867
+ // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
868
+ (() => {
869
+ "use strict";
870
+ __webpack_require__.r(__webpack_exports__);
871
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
872
+ /* harmony export */ SValidation: () => (/* reexport safe */ _validation_mjs__WEBPACK_IMPORTED_MODULE_0__["default"])
873
+ /* harmony export */ });
874
+ /* harmony import */ var _validation_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
875
+
876
+
877
+
878
+ })();
879
+
880
+ var __webpack_export_target__ = exports;
881
+ for(var __webpack_i__ in __webpack_exports__) __webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
882
+ if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
883
+ /******/ })()
884
+ ;
@@ -0,0 +1 @@
1
+ (()=>{var e={577:(e,t)=>{(()=>{"use strict";var e=[,(e,t,r)=>{r.r(t),r.d(t,{default:()=>s});class s{static empty(e){let t=[void 0,null,0,""].includes(e);return t||(e.constructor==Object?t=0==Object.keys(e).length&&0==Object.keys(Object.getPrototypeOf(e)).length:(e.constructor==NodeList||Array.isArray(e))&&(t=0==e.length)),t}static isNumber(e,t=!1){let r=!Number.isNaN(Number(e))&&["number","string"].includes(typeof e)&&!/^\s*$/.test(`${e}`);return r&&t&&(r="number"==typeof e),r}static isObject(e){return e?.constructor==Object}static numberFormat(e,t=0,r=".",i=","){const a=String(e).split(".");return a[0]=a[0].replace(/\B(?=(\d{3})+(?!\d))/g,i),s.empty(a[1])||(a[1]=a[1].substring(0,t)),s.empty(a[1])?a[0]:a[0].concat(r,a[1])}static strftime(e,t){const r=["January","February","March","April","May","June","July","August","September","October","November","December"],s=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];return(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace(/(%{1})/g,"\\$1")).replace(/(\\%){2}/g,"%")).replace(/\\%Y/g,String(e.getFullYear()))).replace(/\\%y/g,String(e.getFullYear()).replace(/^\d+(\d{2})$/,"$1"))).replace(/\\%B/g,r[e.getMonth()])).replace(/\\%b/g,r[e.getMonth()].replace(/^(\w{3})\w*$/,"$1"))).replace(/\\%m/g,String(e.getMonth()+1).replace(/^(\d{1})$/,"0$1"))).replace(/\\%d/g,String(e.getDate()).replace(/^(\d{1})$/,"0$1"))).replace(/\\%A/g,s[e.getDay()])).replace(/\\%a/g,s[e.getDay()].replace(/^(\w{3})\w*$/,"$1"))).replace(/\\%H/g,String(e.getHours()).replace(/^(\d{1})$/,"0$1"))).replace(/\\%I/g,String(e.getHours()>12?e.getHours()-12:e.getHours()).replace(/^0$/,"12").replace(/^(\d{1})$/,"0$1"))).replace(/\\%p/g,e.getHours()<12?"AM":"PM")).replace(/\\%M/g,String(e.getMinutes()).replace(/^(\d{1})$/,"0$1"))).replace(/\\%S/g,String(e.getSeconds()).replace(/^(\d{1})$/,"0$1"))}static checkdate(e,t,r){const s=new Date(e,t-1,r);return s.getFullYear()==e&&s.getMonth()+1==t&&s.getDate()==r}static equaldate(e,t=new Date){return s.strftime(e,"%Y-%m-%d")==s.strftime(t,"%Y-%m-%d")}static getWeek(e,t=!0){const r=["일요일","월요일","화요일","수요일","목요일","금요일","토요일"][e.getDay()];return t?r:r.replace(/^([ㄱ-ㅎㅏ-ㅣ가-힣]{1})[ㄱ-ㅎㅏ-ㅣ가-힣]+$/,"$1")}static addDate(e,t){return new Date(e.getFullYear()+(s.isNumber(t.year,!0)?t.year:0),e.getMonth()+(s.isNumber(t.month,!0)?t.month:0),e.getDate()+(s.isNumber(t.day,!0)?t.day:0),e.getHours()+(s.isNumber(t.hour,!0)?t.hour:0),e.getMinutes()+(s.isNumber(t.minute,!0)?t.minute:0),e.getSeconds()+(s.isNumber(t.second,!0)?t.second:0),e.getMilliseconds()+(s.isNumber(t.millisecond,!0)?t.millisecond:0))}static subDate(e,t){return new Date(e.getFullYear()-(s.isNumber(t.year,!0)?t.year:0),e.getMonth()-(s.isNumber(t.month,!0)?t.month:0),e.getDate()-(s.isNumber(t.day,!0)?t.day:0),e.getHours()-(s.isNumber(t.hour,!0)?t.hour:0),e.getMinutes()-(s.isNumber(t.minute,!0)?t.minute:0),e.getSeconds()-(s.isNumber(t.second,!0)?t.second:0),e.getMilliseconds()-(s.isNumber(t.millisecond,!0)?t.millisecond:0))}static xor(e,t){return!(e&&t)&&(e||t)}static formDataToJson(e){return JSON.stringify(Object.fromEntries([...new Set(e.keys())].map(((...t)=>[t[0],e.getAll(t[0]).length>1?e.getAll(t[0]):e.get(t[0])]))))}static percentage(e,t){return e*(t/100)}static ratio(e,t,r=!0){const s=r?[1,0]:[0,1];return t*e[s[0]]/e[s[1]]}static arithmeticSequence(e,t,r,s){return e+(s-t)*r}static geometricSequence(e,t,r,s){return e/r**(t-1)*r**(s-1)}static decimalAdjust(e,t,r=0){const[s,i="0"]=t.toString().split("e"),a=Math[e](Number(`${s}e${parseInt(i)+r}`)),[n,l="0"]=a.toString().split("e");return Number(`${n}e${parseInt(l)-r}`)}static encodeHtmlEntity(e){const t=document.createElement("textarea");return t.innerText=e,t.innerHTML}static decodeHtmlEntity(e){const t=document.createElement("textarea");return t.innerHTML=e,t.innerText}static copy(e){if(s.isObject(e)){const t={};for(const r in e)t[r]=s.copy(e[r]);return t}if(Array.isArray(e)){const t=[];for(const r of e)t.push(s.copy(r));return t}return e}static numRange(e,t){let r=t-e;const s=r>0;return r=Math.abs(r)+1,[...new Array(r)].map(((...t)=>t[1]*(s?1:-1)+e))}static arrayChunk(e,t){if(!s.isNumber(t,!0))throw new TypeError("size는 숫자 타입 이어야 합니다.");if(t<=0&&Number.isInteger(t))throw new RangeError("size는 0보다 큰 정수여야 합니다.");const r=[];return s.numRange(0,s.decimalAdjust("ceil",e.length/t)+(e.length>0?-1:0)).forEach(((...s)=>{r.push(e.slice(s[0]*t,(s[0]+1)*t))})),r}}}],r={};function s(t){var i=r[t];if(void 0!==i)return i.exports;var a=r[t]={exports:{}};return e[t](a,a.exports,s),a.exports}s.d=(e,t)=>{for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};(()=>{s.r(i),s.d(i,{JUtil:()=>e.default});var e=s(1)})();var a=t;for(var n in i)a[n]=i[n];i.__esModule&&Object.defineProperty(a,"__esModule",{value:!0})})()}},t={};function r(s){var i=t[s];if(void 0!==i)return i.exports;var a=t[s]={exports:{}};return e[s](a,a.exports,r),a.exports}r.d=(e,t)=>{for(var s in t)r.o(t,s)&&!r.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var s={};(()=>{"use strict";r.r(s),r.d(s,{SValidation:()=>t});var e=r(577);class t{result;#e;#t;#r;constructor(e){this.init(e)}init(e=null){this.#s(),this.#i(),this.#a(),this.#n(e?.regex)}#s(){this.result={flag:!0,alertMsg:null,el:null}}#i(){this.#e={}}#a(){this.#t={}}#n(t=null){this.#r=!e.JUtil.empty(t)&&e.JUtil.isObject(t)?{...this.#r,...t}:{...this.#r}}#l(t){const r=t.getAttribute("required");e.JUtil.empty(r)||("radio"==t.type?this.#u(t):e.JUtil.empty(t.value)&&(this.result.flag=!1,this.result.alertMsg=`'${r}'을/를 입력해 주세요.`,this.result.el=t))}#o(){for(const e in this.#t){const t=this.#t[e][0];if(!this.#t[e].some(((...e)=>e[0].checked))){this.result.flag=!1,this.result.alertMsg=`'${e}'을/를 선택해주세요.`,this.result.el=t;break}}}#c(t){const r=t.dataset.svPattern,s=t.dataset.svDate;if(e.JUtil.empty(r)||(e.JUtil.empty(this.#e.el)&&(this.#e.el=[]),this.#e.el?.push(t)),!e.JUtil.empty(s)){const r=t.dataset.svDateState;switch(r){case"S":case"E":e.JUtil.empty(this.#e.date)&&(this.#e.date={}),e.JUtil.empty(this.#e.date[s])&&(this.#e.date[s]={}),this.#e.date[s][r]=t}}}#u(t){const r=t.getAttribute("required");e.JUtil.empty(r)||(e.JUtil.empty(this.#t[r])?this.#t[r]=[t]:this.#t[r].push(t))}#g(){for(const e in this.#e){if(!this.result.flag)break;switch(e){case"date":this.#d(this.#e[e]);break;case"el":this.#h(this.#e[e])}}}#d(t){for(const r in t){if(!this.result.flag)break;{const s=t[r].S.value,i=t[r].E.value;if(!e.JUtil.empty(s)&&!e.JUtil.empty(i)){const e=t[r].S.dataset.svInputName||t[r].E.dataset.svInputName,a=t[r].S.getAttribute("required")||t[r].E.getAttribute("required");new Date(s).getTime()>new Date(i).getTime()&&(this.result.flag=!1,this.result.alertMsg=`'${e||a}'의 시작일이 종료일 보다 늦습니다.`,this.result.el=t[r].S)}}}}#h(t){if(Array.isArray(t))for(const r of t){const t=r.dataset.svPattern,s=r.dataset.svInputName,i=r.getAttribute("required"),a=r.value;if(Object.keys(this.#r).includes(t)&&!e.JUtil.empty(a)&&!this.#r[t].test(a)){this.result.flag=!1,this.result.alertMsg=`'${s||i}'의 형식이 올바르지 않습니다.`,this.result.el=r;break}}else{const r=t.dataset.svPattern,s=t.dataset.svInputName,i=t.getAttribute("required"),a=t.value;Object.keys(this.#r).includes(r)&&(e.JUtil.empty(a)||this.#r[r].test(a)||(this.result.flag=!1,this.result.alertMsg=`'${s||i}'의 형식이 올바르지 않습니다.`,this.result.el=t))}}#m(){for(const e in this.#e)if("el"==e&&this.result.flag)for(const t of this.#e[e]){const e=t.dataset.svInputName,r=t.getAttribute("required"),s=t.value.length;if(!(t instanceof HTMLSelectElement))if(t.minLength>=0&&t.maxLength>=0){if(s<t.minLength||s>t.maxLength){this.result.flag=!1,this.result.alertMsg=`'${e||r}'은/는 ${t.minLength}~${t.maxLength}자 이내로 입력해주세요.`,this.result.el=t;break}}else if(t.minLength>=0&&t.maxLength<0){if(s<t.minLength){this.result.flag=!1,this.result.alertMsg=`'${e||r}'은/는 ${t.minLength}자 이상으로 입력해주세요.`,this.result.el=t;break}}else if(t.minLength<0&&t.maxLength>=0&&s>t.maxLength){this.result.flag=!1,this.result.alertMsg=`'${e||r}'은/는 ${t.maxLength}자 이하로 입력해주세요.`,this.result.el=t;break}}else if(!this.result.flag)break}run(e){this.init();for(const t of e.elements){if(!this.result.flag)break;["INPUT","SELECT","TEXTAREA"].includes(t.tagName)&&(t.disabled||(this.#l(t),this.#c(t)))}this.result.flag&&this.#o(),this.result.flag&&this.#g(),this.result.flag&&this.#m()}}})();var i=exports;for(var a in s)i[a]=s[a];s.__esModule&&Object.defineProperty(i,"__esModule",{value:!0})})();
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import Validation from "./validation.mjs";
2
+ export { Validation as SValidation };
package/package.json CHANGED
@@ -1,15 +1,11 @@
1
1
  {
2
2
  "name": "@nuka9510/simple-validation",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
4
  "description": "simple validation util for web front-end",
5
5
  "main": "dist/index.js",
6
- "type": "module",
7
- "directories": {
8
- "example": "example"
9
- },
10
6
  "scripts": {
11
7
  "test": "echo \"Error: no test specified\" && exit 1",
12
- "build": "rm -r -f dist && tsc",
8
+ "build": "rm -r -f dist && tsc && webpack --config webpack.config.js",
13
9
  "postversion": "git push && git push --tag && npm publish --access=public"
14
10
  },
15
11
  "repository": {
@@ -30,6 +26,13 @@
30
26
  },
31
27
  "homepage": "https://github.com/nuka9510/simple-validation",
32
28
  "dependencies": {
33
- "@nuka9510/js-util": "^1.0.25"
29
+ "@nuka9510/js-util": "^1.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.14.0",
33
+ "@types/webpack": "^5.28.5",
34
+ "ts-node": "^10.9.2",
35
+ "webpack": "^5.99.5",
36
+ "webpack-cli": "^6.0.1"
34
37
  }
35
38
  }
package/src/index.mts ADDED
@@ -0,0 +1,3 @@
1
+ import Validation from "./validation.mjs";
2
+
3
+ export { Validation as SValidation };
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "checkJs": true,
4
+ "strictNullChecks": false,
5
+ "noPropertyAccessFromIndexSignature": true,
6
+ "noUncheckedIndexedAccess": true,
7
+ "moduleResolution": "node",
8
+ "useDefineForClassFields": true,
9
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
10
+ "target": "ESNext",
11
+ "declaration": true,
12
+ "outDir": "dist"
13
+ },
14
+ "include": ["src/index.mts"]
15
+ }
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import Validation from "./validation.js";
2
- export { Validation as SValidation };
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- import Validation from "./validation.js";
2
-
3
- export { Validation as SValidation };
File without changes
File without changes
File without changes