logic-auto 1.0.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.
@@ -0,0 +1,762 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { MetaElement, PropertyCollection, MetaObject, Observer } = require('white-core');
4
+ // const { MetaElement, PropertyCollection, MetaObject, Observer } = require('entitybind');
5
+ const { DependResolver } = require('./depend-resolver');
6
+ const { FileCollection, FolderCollection } = require('./original-path');
7
+ const { InstallMap } = require('./source-batch');
8
+ const { AutoTemplate } = require('auto-template');
9
+ const at = require('./auto-task');
10
+
11
+ /**
12
+ * 오토메이션 클래스
13
+ * @constructs Automation
14
+ */
15
+ class Automation {
16
+
17
+ /*_______________________________________*/
18
+ // public
19
+ // 주요 객체
20
+ /**
21
+ * 오토 모듈
22
+ * @type {FileCollection}
23
+ * @public
24
+ */
25
+ mod = new AutoCollection(this);
26
+ /**
27
+ * src 소스
28
+ * @type {FileCollection}
29
+ * @public
30
+ */
31
+ src = new FileCollection(this);
32
+ /**
33
+ * out 소스
34
+ * @type {FileCollection}
35
+ * @public
36
+ */
37
+ out = new FileCollection(this);
38
+ /**
39
+ * 가상 폴더 컬렉션
40
+ * @type {FileCollection}
41
+ * @public
42
+ */
43
+ vir = new FolderCollection(this);
44
+ /**
45
+ * 의존 소스
46
+ * @type {DependCollection}
47
+ * @public
48
+ */
49
+ dep = new DependCollection(this);
50
+ /**
51
+ * 메타 컬렉션
52
+ * @type {MetaCollection}
53
+ * @public
54
+ */
55
+ meta = new MetaCollection(this);
56
+ /**
57
+ * 의존성 해결자
58
+ * @type {DependResolver}
59
+ * @public
60
+ */
61
+ resolver = null;
62
+ /**
63
+ * install 지도
64
+ * @type {InstallMap}
65
+ * @public
66
+ */
67
+ install = null;
68
+
69
+ template = null;
70
+
71
+ /**
72
+ * prop 속성
73
+ * @type {Object}
74
+ * @public
75
+ */prop = {};
76
+ // 주요 속성
77
+ isStatic = false;
78
+ isSaveRelation = false; // 관계파일 저장 여부
79
+ isFinal = false; // 상속 금지 설정
80
+ title = ''; // 제목(설명)
81
+ isLog = false;
82
+ /**
83
+ * 상위폴더 위치
84
+ * @public
85
+ */
86
+ LOC = {
87
+ OUT: 'out',
88
+ SRC: 'src',
89
+ DEP: 'dep',
90
+ INS: 'install',
91
+ PUB: 'publish',
92
+ DIS: 'dist',
93
+ VIR: 'vir'
94
+ };
95
+ // 파일명
96
+ FILE = {
97
+ PACKAGE: 'package.json',
98
+ INSTALL: 'install.json',
99
+ RESOLVER: 'resolver.json',
100
+ PROP: 'prop.json',
101
+ LIST: 'List.json', // 목록 저장 파일명
102
+ MAP: 'Map.json', // 맵 저장 파일명
103
+ };
104
+ // 주요경로
105
+ PATH = {
106
+ auto: this, // auto
107
+ get PACKAGE() { return this.auto.dir + path.sep + this.auto.FILE.PACKAGE },
108
+ get INSTALL() { return this.auto.dir + path.sep + this.auto.FILE.INSTALL },
109
+ get RESOLVER() { return this.auto.dir + path.sep + this.auto.FILE.RESOLVER },
110
+ get PROP() { return this.auto.dir + path.sep + this.auto.FILE.PROP }
111
+ };
112
+ /*_______________________________________*/
113
+ // protected
114
+ static _instance = null; // 싱글톤 객체 위치
115
+ _isSingleton = false; // getInstance 생성시 true 변경됨
116
+ _owner = null;
117
+ _file = [];
118
+ _subTitle = ''; // add 설명
119
+ _task = at.AutoTask.getInstance();
120
+ /*_______________________________________*/
121
+ // private
122
+ #modName = '';
123
+ #dir = [];
124
+ #alias = '';
125
+ #modTyped = 0;
126
+ #event = new Observer(this, this);
127
+ /*_______________________________________*/
128
+ // property
129
+ get modName() {
130
+ return this.#modName;
131
+ }
132
+ get alias() {
133
+ return this.#alias;
134
+ }
135
+ set alias(val) {
136
+ this.#alias = val;
137
+ }
138
+ get dir() {
139
+ let size = this.#dir.length;
140
+ if (size === 0) throw new Error(' start [dir] request fail...');
141
+ return this.#dir[size - 1];
142
+ }
143
+ set dir(val) {
144
+ if (this.isFinal === true && this.#dir.length > 0) throw new Error('최종 오토 (상속금지)는 dir 설정할 수 없습니다.');
145
+ this.#dir.push(val);
146
+ // package, prop, install, resolver.json 로딩
147
+ // setter별 처리
148
+ this.#loadDir(val);
149
+ if (this.isLog) console.log('Automation load path :: ' + val);
150
+ }
151
+ get dirs() {
152
+ return this.#dir;
153
+ }
154
+ get modTyped() {
155
+ return this.#modTyped;
156
+ }
157
+ set modTyped(val) {
158
+ this.#modTyped = val;
159
+ }
160
+ /*_______________________________________*/
161
+ // event property
162
+ set onLoad(fun) {
163
+ this._task.onLoad = fun;
164
+ }
165
+ set onRead(fun) {
166
+ this.#event.subscribe(fun, 'read');
167
+ }
168
+ set onResolve(fun) {
169
+ this.#event.subscribe(fun, 'resolve');
170
+ }
171
+ set onResolved(fun) {
172
+ this.#event.subscribe(fun, 'resolved');
173
+ }
174
+ set onSave(fun) {
175
+ this._task.onSave = fun;
176
+ }
177
+ set onSaved(fun) {
178
+ this._task.onSaved = fun;
179
+ }
180
+
181
+ /**
182
+ * 생성자
183
+ */
184
+ constructor(dir) {
185
+ // if (typeof dir === 'string' && dir.length > 0) {
186
+ // this.dir = dir;
187
+ // this.#isFinal = true; // 최종 auto 로 설정
188
+ // }
189
+ // console.log('Automation load..');
190
+ if (dir) this.dir = dir; // Automation 설정시 사용
191
+ }
192
+
193
+ /*_______________________________________*/
194
+ // public method
195
+
196
+ /**
197
+ * isStatic = true 인 경우 객체 생성
198
+ * @returns {*}
199
+ */
200
+ static getInstance() {
201
+
202
+ let instance = this._instance;
203
+
204
+ if (!instance) {
205
+ instance = new this();
206
+ }
207
+ /**
208
+ * REVIEW:: 특수한 경우여서 생성후 검사한다. static 이슈
209
+ */
210
+ // getInstace() 사용타입 검사
211
+ if (instance.isStatic !== true) {
212
+ throw new Error(' static 으로 설정된 auto만 사용할수 있습니다. new 을 사용해서 생성.');
213
+ }
214
+ instance._isSingleton = true; // add 시점에 검사함
215
+ return instance;
216
+ }
217
+
218
+ /**
219
+ * 준비가 된 상태, overriding 으로 사용함
220
+ * @virtual
221
+ */
222
+ ready() {/** 가상함수 */}
223
+
224
+ /**
225
+ * 초기화
226
+ */
227
+ init() {
228
+ if (this.isLog) console.log('init() :'+ this.modName);
229
+ // 템플릿 같이 1회만 초기화 해야 하는 곳에 활용
230
+
231
+ for (let i = 0; i < this.mod.count; i++) {
232
+ this.mod[i].init(); // 재귀 호출함
233
+ }
234
+ // 템플릿 초기화
235
+ this.template.init();
236
+
237
+ // 가상함수 호출
238
+ this.ready();
239
+ }
240
+
241
+ /**
242
+ * 소스 읽기 (src, out)
243
+ * @param {boolean} isSrc false: 구조 로딩, true 구조/데이터 로딩
244
+ * @param {boolean} isOut false: 구조 로딩, true 구조/데이터 로딩
245
+ */
246
+ readSource(isSrc, isOut) {
247
+ if (typeof isSrc === 'boolean') {
248
+ this.src.addLocation(this.LOC.SRC);
249
+ if (isSrc === true) this.src.fillData();
250
+ }
251
+ if (typeof isOut === 'boolean') {
252
+ this.out.addLocation(this.LOC.OUT);
253
+ if (isOut === true) this.out.fillData();
254
+ }
255
+ // 이벤트 발생
256
+ this._onRead(this._task.cursor, this);
257
+ }
258
+
259
+ /**
260
+ * 강제 의존성 설정
261
+ * @param {string | array} oriPath 원본 경로
262
+ * @param {string | array} depPath 의존 경로
263
+ * @param {object} pos
264
+ */
265
+ setDepend(oriPath, depPath, pos) {
266
+ // TODO::
267
+ }
268
+
269
+ /**
270
+ * 부모의 객체를 가져와 파일로 쓰다
271
+ * install, resolver, prop, src, out
272
+ */
273
+ writeParentObject() {
274
+ // console.log('보모 객체 및 파일 덮어쓰기');
275
+
276
+ let data, dirname;
277
+
278
+ function copySource(collection, dir) {
279
+
280
+ let fullPath, savePath;
281
+
282
+ for (let i = 0; i < collection.count; i++) {
283
+ fullPath = collection[i].fullPath;
284
+ savePath = dir + path.sep + collection[i].localPath;
285
+ if (!fs.existsSync(savePath)) {
286
+ dirname = path.dirname(savePath);
287
+ if(!fs.existsSync(dirname)) {
288
+ fs.mkdirSync(dirname, {recursive: true} ); // 디렉토리 만들기
289
+ }
290
+ fs.copyFileSync(fullPath, savePath);
291
+ }
292
+ }
293
+ }
294
+
295
+ if (!fs.existsSync(this.PATH.INSTALL)) {
296
+ data = JSON.stringify(this.install.getObject(), null, '\t');
297
+ fs.writeFileSync(this.PATH.INSTALL, data, 'utf8');
298
+ }
299
+ if (!fs.existsSync(this.PATH.RESOLVER)) {
300
+ data = JSON.stringify(this.resolver.getObject(), null, '\t');
301
+ fs.writeFileSync(this.PATH.RESOLVER, data, 'utf8');
302
+ }
303
+ if (!fs.existsSync(this.PATH.PROP)) {
304
+ data = JSON.stringify(this._getpropObject(), null, '\t');
305
+ fs.writeFileSync(this.PATH.PROP, data, 'utf8');
306
+ }
307
+ // src, out 가져오기
308
+ copySource(this.src, this.dir);
309
+ copySource(this.out, this.dir);
310
+ }
311
+
312
+
313
+
314
+ /**
315
+ * 객체(오토모듈) 맵 쓰기
316
+ * @param {*} opt 옵션 0: -all, 1: "기본", 2: -detail, 3: -depend
317
+ */
318
+ writeObjectMap(opt = 1) {
319
+
320
+ let _this = this;
321
+
322
+ // modType = 0:entry, 1:mod, 2:sub, 3: super
323
+ // isSubCall
324
+ function createModObject(auto, option, modType = 0, isSubCall = true) {
325
+
326
+ let obj = {}, child;
327
+ let arrDepend = [];
328
+
329
+ obj.name = auto.modName;
330
+ if (auto.alias.length > 0) obj.alias = auto.alias;
331
+ if (auto.title.length > 0) obj.title = auto.title;
332
+ if (auto._subTitle.length > 0) obj.subTitle = auto._subTitle;
333
+ if (auto.isStatic === true) obj.static = true;
334
+ if (modType === 2) obj.sub = true;
335
+ if (modType === 3) obj.super = true;
336
+ if (Array.isArray(auto._interface) && auto._interface.length > 0) {
337
+ obj.interface = [];
338
+ auto._interface.forEach(val => obj.interface.push(val.name));
339
+ }
340
+ // -detail
341
+ if (option === 2 || option === 3) {
342
+ obj.file = [];
343
+ for (let i = 0; i < auto.src.count; i++) {
344
+ obj.file.push(auto.src[i].localPath);
345
+ }
346
+ for (let i = 0; i < auto.out.count; i++) {
347
+ obj.file.push(auto.out[i].localPath);
348
+ }
349
+ }
350
+
351
+ if (isSubCall !== true) return obj; // 하위호출 안함
352
+
353
+ if (option === 3) { // option : -depend
354
+
355
+ arrDepend = _this._getDependList(false);
356
+ if (arrDepend.length > 0) {
357
+ child = obj.depend = [];
358
+ arrDepend.forEach(val => child.push(createModObject(val, option, val.modTyped, false)));
359
+ }
360
+ } else { // option 0, 1 기본타입
361
+
362
+ if (auto.mod.count > 0) {
363
+ child = obj.module = [];
364
+ for (let i = 0; i < auto.mod.count; i++) {
365
+ child.push(createModObject(auto.mod[i], option, auto.mod[i].modTyped, true));
366
+ }
367
+ }
368
+ }
369
+ return obj;
370
+ }
371
+
372
+ //
373
+ function saveFile(option) {
374
+
375
+ let wriObj = {}, data, saveName;
376
+
377
+ wriObj = createModObject(_this, option, 0);
378
+ saveName = path.basename(_this.FILE.MAP, '.json');
379
+ if (option === 2) saveName += '_Detail';
380
+ if (option === 3) saveName += '_Depend';
381
+ saveName += '_'+ _this.modName + '.json';
382
+
383
+ data = JSON.stringify(wriObj, null, '\t');
384
+ fs.writeFileSync(_this.dir + path.sep + saveName, data, 'utf8');
385
+ }
386
+
387
+ if (opt === 0) { // 전체 파일 쓰기
388
+ saveFile(1);
389
+ saveFile(2);
390
+ saveFile(3);
391
+ // 함수 추가시 확장함
392
+ } else { // 단일 파일 쓰기
393
+ saveFile(opt);
394
+ }
395
+ }
396
+
397
+ /**
398
+ * 객체(오토모듈) 목록 쓰기
399
+ * @param {*} opt 옵션 0: -all, 1: "기본", 2: -detail, 3: -history
400
+ */
401
+ writeObjectList(opt = 1) {
402
+
403
+ let _this = this, list;
404
+
405
+ function createModObject(auto, option, modType = 0) {
406
+
407
+ let obj = {}, child;
408
+ let arrDepend = [];
409
+
410
+ function fileInfoObject(file) {
411
+
412
+ let fileObj = {}, histry = [];
413
+
414
+ // fileObj.name = file.localPath;
415
+ if (file.isStatic === true) fileObj.static = true;
416
+ if (file.comment.length > 0) fileObj.comment = file.comment;
417
+ if (option === 3) { // --history 옵션
418
+ fileObj.history = [];
419
+ }
420
+ if (file._auto._owner !== null) { // auto 이면
421
+
422
+ }
423
+
424
+ return fileObj;
425
+ }
426
+
427
+ obj.name = auto.modName;
428
+ if (auto.alias.length > 0) obj.alias = auto.alias;
429
+ if (auto.title.length > 0) obj.title = auto.title;
430
+ if (auto._subTitle.length > 0) obj.subTitle = auto._subTitle;
431
+ if (auto.isStatic === true) obj.static = true;
432
+ if (modType === 2) obj.sub = true;
433
+ if (modType === 3) obj.super = true;
434
+ if (Array.isArray(auto._interface) && auto._interface.length > 0) {
435
+ obj.interface = [];
436
+ auto._interface.forEach(val => obj.interface.push(val.name));
437
+ }
438
+ // location : 위치
439
+ // -detail, -history
440
+ if (option === 2 || option === 3) {
441
+ obj.file = {};
442
+ for (let i = 0; i < auto.src.count; i++) {
443
+ obj.file[auto.src[i].localPath] = fileInfoObject(auto.src[i]);
444
+
445
+ // obj.file.push( fileInfoObject(auto.src[i]));
446
+ // comment : 파일 설명
447
+ }
448
+ for (let i = 0; i < auto.out.count; i++) {
449
+ obj.file[auto.out[i].localPath] = fileInfoObject(auto.out[i]);
450
+ }
451
+ }
452
+ return obj;
453
+ }
454
+
455
+ function saveFile(option) {
456
+
457
+ let wriList = [], data, saveName;
458
+
459
+ list = _this._getAllList(true);
460
+ for (let i = list.length - 1; i > -1; i--) {
461
+ wriList.push(createModObject(list[i], option));
462
+ }
463
+
464
+ saveName = path.basename(_this.FILE.LIST, '.json');
465
+ if (option === 2) saveName += '_Detail';
466
+ if (option === 3) saveName += '_History';
467
+ saveName += '_'+ _this.modName + '.json';
468
+
469
+ data = JSON.stringify(wriList, null, '\t');
470
+ fs.writeFileSync(_this.dir + path.sep + saveName, data, 'utf8');
471
+ }
472
+
473
+ if (opt === 0) { // 전체 파일 쓰기
474
+ saveFile(1);
475
+ saveFile(2);
476
+ saveFile(3);
477
+ // 함수 추가시 확장함
478
+ } else { // 단일 파일 쓰기
479
+ saveFile(opt);
480
+ }
481
+ }
482
+
483
+ /*_______________________________________*/
484
+ // protected method
485
+
486
+ /**
487
+ * prop 객체 가져오기
488
+ */
489
+ _getpropObject() {
490
+ return this.prop;
491
+ }
492
+
493
+ /**
494
+ * 오토모듈이 의존하는 sub, super(상위 super 포함)의 목록
495
+ * 최하위(Leaf)에서 호출처까지 순차인 목록
496
+ * @param {boolean} isSelf 최상위 호출처(오토) 포함 여부
497
+ * @returns {arrary}
498
+ */
499
+ _getDependList(isSelf) {
500
+
501
+ let list = [], prop, auto;
502
+
503
+ // sub 가져오기
504
+ for (let i = 0; i < this.mod.count; i++) {
505
+ if (this.mod[i].modTyped === 3) {
506
+ list = list.concat(this.mod[i]._getSuperList());
507
+ } else if (this.mod[i].modTyped === 2) {
508
+ list.push(this.mod[i]);
509
+ }
510
+ }
511
+
512
+ if (isSelf === null || isSelf === true) list.push(this); // 자신포함
513
+ return list;
514
+ }
515
+
516
+ /**
517
+ * 오토모듈이 의존하는 super(상위 super 포함)의 목록
518
+ * 최하위(Leaf)에서 호출처까지 순차인 목록
519
+ * @param {boolean} isSelf 최상위 호출처(오토) 포함 여부
520
+ * @returns {arrary}
521
+ */
522
+ _getSuperList(isSelf = null) {
523
+
524
+ let list = [], prop, auto;
525
+
526
+ for (let i = 0; i < this.mod.count; i++) {
527
+ if (this.mod[i].modTyped === 3) {
528
+ list = list.concat(this.mod[i]._getSuperList(false));
529
+ list.push(this.mod[i]);
530
+ }
531
+ }
532
+ if (isSelf === null || isSelf === true) list.push(this); // 자신포함
533
+ return list;
534
+ }
535
+
536
+
537
+ /**
538
+ * 전체 오토 목록
539
+ * 최하위(Leaf)에서 호출처까지 순차인 목록
540
+ * @param {boolean} isSelf 최상위 호출처(오토) 포함 여부
541
+ * @returns {arrary}
542
+ */
543
+ _getAllList(isSelf = null) {
544
+
545
+ let list = [], auto;
546
+
547
+ for (let i = 0; i < this.mod.count; i++) {
548
+ auto = this.mod[i];
549
+ if (auto.mod.count > 0) list = list.concat(auto._getAllList());
550
+ else list.push(auto);
551
+ }
552
+ if (isSelf === null || isSelf === true) list.push(this); // 자신포함
553
+ return list;
554
+ }
555
+
556
+ /*_______________________________________*/
557
+ // event call
558
+
559
+ // 소스 읽은 후 호출 이벤트
560
+ _onRead(task, auto) {
561
+ this.#event.publish('read', task, this);
562
+ }
563
+ // 의존성 해결 전 호출 이벤트
564
+ _onResolve(task, auto) {
565
+ this.#event.publish('resolve', task, this);
566
+ }
567
+ // 의존성 해결 후 호출 이벤트
568
+ _onResolved(task, auto) {
569
+ this.#event.publish('resolved', task, this);
570
+ }
571
+
572
+ /*_______________________________________*/
573
+ // private method
574
+
575
+ /**
576
+ * 오토 경로를 기준으로 로딩
577
+ * package.json, install.json, resolver.json, prop.json
578
+ * @param {string} dir auto 의 경로
579
+ */
580
+ #loadDir(dir) {
581
+
582
+ let _package, _install, _resolver, _prop;
583
+
584
+ // 필수 파일 검사
585
+ if (!fs.existsSync(this.PATH.PACKAGE)) {
586
+ throw new Error('package.json file fail...');
587
+ } else {
588
+ _package = require(this.PATH.PACKAGE);
589
+ this.#modName = _package.name; // auto.modName 설정
590
+ }
591
+
592
+ // 선택 파일 검사
593
+ /**
594
+ * 파일이 존재하면 새로 만들어고(덮어씀), 파일이 없으면 기존 객체 사용
595
+ */
596
+ if (fs.existsSync(this.PATH.INSTALL)) _install = require(this.PATH.INSTALL);
597
+ if (this.install === null || _install) this.install = new InstallMap(this, _install);
598
+
599
+ if (fs.existsSync(this.PATH.RESOLVER)) _resolver = require(this.PATH.RESOLVER);
600
+ if (this.resolver === null || _resolver) this.resolver = new DependResolver(this, _resolver);
601
+
602
+ if (fs.existsSync(this.PATH.PROP)) _prop = require(this.PATH.PROP);
603
+ if (_prop) this.prop = _prop;
604
+
605
+ // 템플릿 생성
606
+ this.template = new AutoTemplate(dir, this);
607
+ }
608
+ }
609
+
610
+ /**
611
+ * 오토컬렉션 클래스
612
+ */
613
+ class AutoCollection extends PropertyCollection {
614
+
615
+ /*_______________________________________*/
616
+ // protected
617
+ _super = [];
618
+ _sub = [];
619
+ _auto = null;
620
+
621
+ // TODO:: _W.Collection 에서 owner 명칭 변경 (오타) !!
622
+ constructor(owner) {
623
+ super(owner);
624
+ this._auto = owner;
625
+ }
626
+
627
+ /*_______________________________________*/
628
+ // public method
629
+
630
+ /**
631
+ * 객체 얻기
632
+ * @param {*} p_context
633
+ * @returns {*}
634
+ */
635
+ getObject(p_context) {
636
+
637
+ let obj = {};
638
+
639
+ for (let prop in this) {
640
+ if (this[prop] instanceof MetaElement) {
641
+ obj[prop] = this[prop].getObject(p_context);
642
+ } else if (prop.substring(0, 1) !== '_') {
643
+ obj[prop] = this[prop];
644
+ }
645
+ }
646
+ return obj;
647
+ }
648
+
649
+ /**
650
+ * 오토를 mod 에 추가한다.
651
+ * @param {*} alias 별칭
652
+ * @param {*} auto 오토 객체
653
+ * @param {*} modType 오토 객체
654
+ */
655
+ add(alias, auto, subTitle = '', modType = 1) {
656
+ if (this._valid(alias, auto)) {
657
+ // auto._owner = this._onwer; // TODO:: 명칭 바꿔야함
658
+
659
+ auto._owner = this._auto; // TODO:: 명칭 바꿔야함
660
+ auto._subTitle = subTitle;
661
+ auto.alias = alias;
662
+ auto.modTyped = modType;
663
+
664
+ super.add(alias, auto);
665
+ // this[alias]._owner = this._auto;
666
+ // this[alias].alias = alias;
667
+ }
668
+ }
669
+
670
+ /**
671
+ * sub 로 추가 : 단일 의존성
672
+ * @param {*} alias
673
+ * @param {*} auto
674
+ * @param {*} subTitle
675
+ */
676
+ sub(alias, auto, subTitle = '') {
677
+ this.add(alias, auto, subTitle, 2);
678
+ // 별칭 이름 등록
679
+ this._sub.push(alias);
680
+ // 의존성 등록
681
+ this._onwer.dep.add(alias, auto.src);
682
+ }
683
+
684
+ /**
685
+ * super 로 추가, 대상의 super 까지 같이 의존함
686
+ * @param {*} alias
687
+ * @param {*} auto
688
+ * @param {*} subTitle
689
+ */
690
+ super(alias, auto, subTitle = '') {
691
+ this.add(alias, auto, subTitle, 3);
692
+ // 별칭 이름 등록
693
+ this._super.push(alias);
694
+ // 의존성 등록
695
+ this._onwer.dep.add(alias, auto.src);
696
+ }
697
+
698
+ /**
699
+ * 오토 모듈 조회
700
+ * @param {*} selector
701
+ * @param {*} obj
702
+ */
703
+ select(selector, obj) {
704
+ // TODO::
705
+ }
706
+
707
+ /*_______________________________________*/
708
+ // protected method
709
+
710
+ /**
711
+ * 별칭 중복 검사 및 버전 검사
712
+ *
713
+ * @param {*} alias 오토 별칭
714
+ * @param {*} auto 오토 객체
715
+ * @return {boolean}
716
+ */
717
+ _valid(alias, auto) {
718
+ // 별칭 중복 검사
719
+ if (super.indexOfName(alias) > -1) {
720
+ throw new Error(' 별칭 중복 오류!! ');
721
+ }
722
+ // static 검사
723
+ if (auto.isStatic == true && auto._isSingleton !== true) {
724
+ throw new Error('static auto 는 getInstance() 를 통해서 생성해야 합니다. ');
725
+ }
726
+ /**
727
+ * TODO::
728
+ * 엔트리 오토를 기준으로 semmver로 정해진 버전 검사
729
+ */
730
+ return true;
731
+ }
732
+ }
733
+
734
+ /**
735
+ * 의존성컬렉션 클ㅐㅡ
736
+ */
737
+ class DependCollection extends PropertyCollection {
738
+
739
+ /**
740
+ * 생성자
741
+ * @param {*} owner
742
+ */
743
+ constructor(owner) {
744
+ super(owner);
745
+ }
746
+ }
747
+
748
+ /**
749
+ * 메타컬렉션 클래스
750
+ */
751
+ class MetaCollection extends PropertyCollection {
752
+
753
+ /**
754
+ * 생성자
755
+ * @param {*} owner
756
+ */
757
+ constructor(owner) {
758
+ super(owner);
759
+ }
760
+ }
761
+
762
+ exports.Automation = Automation;