@fuzionx/framework 0.1.42 → 0.1.44

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.
Files changed (80) hide show
  1. package/README.md +501 -501
  2. package/bin/fx.js +12 -12
  3. package/cli/db-sync.js +100 -100
  4. package/cli/index.js +494 -494
  5. package/cli/templates/make/app/controllers/HomeController.js +14 -14
  6. package/cli/templates/make/app/routes/api.js +7 -7
  7. package/cli/templates/make/app/routes/web.js +5 -5
  8. package/cli/templates/make/app/views/default/errors/404.html +11 -11
  9. package/cli/templates/make/app/views/default/errors/500.html +14 -14
  10. package/cli/templates/make/app/views/default/layouts/main.html +22 -22
  11. package/cli/templates/make/app/views/default/pages/home.html +11 -11
  12. package/cli/templates/make/controller.js.tpl +40 -40
  13. package/cli/templates/make/event.js.tpl +8 -8
  14. package/cli/templates/make/job.js.tpl +10 -10
  15. package/cli/templates/make/middleware.js.tpl +10 -10
  16. package/cli/templates/make/model.js.tpl +15 -15
  17. package/cli/templates/make/service.js.tpl +15 -15
  18. package/cli/templates/make/task.js.tpl +15 -15
  19. package/cli/templates/make/test.js.tpl +7 -7
  20. package/cli/templates/make/worker.js.tpl +14 -14
  21. package/cli/templates/make/ws.js.tpl +18 -18
  22. package/index.js +67 -67
  23. package/lib/core/AppError.js +46 -46
  24. package/lib/core/Application.js +1006 -1006
  25. package/lib/core/AutoLoader.js +227 -227
  26. package/lib/core/Base.js +64 -64
  27. package/lib/core/Config.js +331 -228
  28. package/lib/core/Context.js +484 -484
  29. package/lib/database/ConnectionManager.js +208 -208
  30. package/lib/database/MariaModel.js +29 -29
  31. package/lib/database/Model.js +247 -247
  32. package/lib/database/ModelRegistry.js +72 -72
  33. package/lib/database/MongoModel.js +232 -232
  34. package/lib/database/Pagination.js +37 -37
  35. package/lib/database/PostgreModel.js +29 -29
  36. package/lib/database/QueryBuilder.js +172 -172
  37. package/lib/database/SQLiteModel.js +27 -27
  38. package/lib/database/SqlModel.js +257 -257
  39. package/lib/database/SqlQueryBuilder.js +332 -332
  40. package/lib/helpers/CryptoHelper.js +48 -48
  41. package/lib/helpers/FileHelper.js +61 -61
  42. package/lib/helpers/HashHelper.js +39 -39
  43. package/lib/helpers/I18nHelper.js +174 -174
  44. package/lib/helpers/Logger.js +108 -108
  45. package/lib/helpers/MediaHelper.js +84 -84
  46. package/lib/http/Controller.js +34 -34
  47. package/lib/http/ErrorHandler.js +136 -136
  48. package/lib/http/Middleware.js +43 -43
  49. package/lib/http/Router.js +109 -109
  50. package/lib/http/Validation.js +125 -125
  51. package/lib/middleware/apiAuth.js +79 -79
  52. package/lib/middleware/auth.js +42 -42
  53. package/lib/middleware/bodyParser.js +19 -19
  54. package/lib/middleware/cors.js +47 -47
  55. package/lib/middleware/csrf.js +32 -32
  56. package/lib/middleware/index.js +13 -13
  57. package/lib/middleware/session.js +27 -27
  58. package/lib/middleware/theme.js +20 -20
  59. package/lib/realtime/RoomManager.js +85 -85
  60. package/lib/realtime/WsHandler.js +107 -107
  61. package/lib/schedule/Job.js +38 -38
  62. package/lib/schedule/Queue.js +103 -103
  63. package/lib/schedule/Scheduler.js +171 -171
  64. package/lib/schedule/Task.js +39 -39
  65. package/lib/schedule/WorkerPool.js +225 -225
  66. package/lib/services/EventBus.js +94 -94
  67. package/lib/services/Service.js +261 -261
  68. package/lib/services/Storage.js +112 -112
  69. package/lib/utilities/ArrUtil.js +112 -112
  70. package/lib/utilities/DateUtil.js +98 -98
  71. package/lib/utilities/FunctionUtil.js +119 -119
  72. package/lib/utilities/NumUtil.js +75 -75
  73. package/lib/utilities/ObjectUtil.js +170 -170
  74. package/lib/utilities/PaginationUtil.js +81 -81
  75. package/lib/utilities/StrUtil.js +105 -105
  76. package/lib/utilities/index.js +18 -18
  77. package/lib/view/OpenAPI.js +231 -231
  78. package/lib/view/View.js +83 -83
  79. package/package.json +2 -2
  80. package/testing/index.js +232 -232
@@ -1,172 +1,172 @@
1
- /**
2
- * QueryBuilder — SQL/MongoDB 쿼리 빌더 (체이닝)
3
- *
4
- * @see docs/framework/02-database-orm.md
5
- * @see docs/framework/class-design.mm.md (QueryBuilder)
6
- */
7
- export default class QueryBuilder {
8
- constructor(model) {
9
- this._model = model;
10
- this._wheres = [];
11
- this._orders = [];
12
- this._limit = null;
13
- this._offset = null;
14
- this._selects = null;
15
- this._withs = [];
16
- // softDelete 자동 적용
17
- this._softDelete = model?.softDelete || false;
18
- this._withTrashed = false;
19
- this._onlyTrashed = false;
20
- }
21
-
22
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
23
- // 체이닝 메서드
24
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
25
-
26
- where(key, op, value) {
27
- if (value === undefined) { value = op; op = '='; }
28
- this._wheres.push({ key, op, value, type: 'and' });
29
- return this;
30
- }
31
-
32
- /** OR 조건 */
33
- orWhere(key, op, value) {
34
- if (value === undefined) { value = op; op = '='; }
35
- this._wheres.push({ key, op, value, type: 'or' });
36
- return this;
37
- }
38
-
39
- /** IN 조건 */
40
- whereIn(key, values) {
41
- this._wheres.push({ key, op: 'IN', value: values, type: 'and' });
42
- return this;
43
- }
44
-
45
- /** NOT NULL 조건 */
46
- whereNotNull(key) {
47
- this._wheres.push({ key, op: 'IS NOT NULL', value: null, type: 'and' });
48
- return this;
49
- }
50
-
51
- /** NULL 조건 */
52
- whereNull(key) {
53
- this._wheres.push({ key, op: 'IS NULL', value: null, type: 'and' });
54
- return this;
55
- }
56
-
57
- orderBy(column, direction = 'asc') {
58
- this._orders.push({ column, direction });
59
- return this;
60
- }
61
-
62
- limit(n) { this._limit = n; return this; }
63
- offset(n) { this._offset = n; return this; }
64
-
65
- select(...columns) {
66
- this._selects = columns.flat();
67
- return this;
68
- }
69
-
70
- with(...relations) {
71
- this._withs.push(...relations.flat());
72
- return this;
73
- }
74
-
75
- /** softDelete 포함 (삭제된 레코드도 조회) */
76
- withTrashed() {
77
- this._withTrashed = true;
78
- return this;
79
- }
80
-
81
- /** softDelete만 조회 (삭제된 레코드만) */
82
- onlyTrashed() {
83
- this._onlyTrashed = true;
84
- return this;
85
- }
86
-
87
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
88
- // 터미널 메서드
89
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
90
-
91
- /**
92
- * 페이지네이션
93
- * @param {number} page
94
- * @param {number} perPage
95
- * @returns {Promise<Pagination>}
96
- */
97
- async paginate(page = 1, perPage = 20) {
98
- // Model 서브클래스에서 오버라이드하여 실제 DB 쿼리 실행
99
- return {
100
- data: [],
101
- page,
102
- perPage,
103
- total: 0,
104
- lastPage: 0,
105
- _query: this._buildQuery(),
106
- };
107
- }
108
-
109
- /**
110
- * 전체 결과 반환
111
- * @returns {Promise<Array>}
112
- */
113
- async get() {
114
- // 서브클래스에서 오버라이드
115
- return [];
116
- }
117
-
118
- /**
119
- * 단일 결과
120
- * @returns {Promise<object|null>}
121
- */
122
- async first() {
123
- this._limit = 1;
124
- const results = await this.get();
125
- return results[0] || null;
126
- }
127
-
128
- /**
129
- * 결과 수
130
- * @returns {Promise<number>}
131
- */
132
- async count() {
133
- // 서브클래스에서 오버라이드
134
- return 0;
135
- }
136
-
137
- /**
138
- * 조건부 수정
139
- * @param {object} data
140
- * @returns {Promise<number>} 수정된 행 수
141
- */
142
- async update(data) {
143
- // 서브클래스에서 오버라이드
144
- return 0;
145
- }
146
-
147
- /**
148
- * 조건부 삭제
149
- * @returns {Promise<number>} 삭제된 행 수
150
- */
151
- async delete() {
152
- // 서브클래스에서 오버라이드
153
- return 0;
154
- }
155
-
156
- /**
157
- * 빌드된 쿼리 파라미터 (디버깅/테스트용)
158
- */
159
- _buildQuery() {
160
- return {
161
- wheres: this._wheres,
162
- orders: this._orders,
163
- limit: this._limit,
164
- offset: this._offset,
165
- selects: this._selects,
166
- withs: this._withs,
167
- softDelete: this._softDelete,
168
- withTrashed: this._withTrashed,
169
- onlyTrashed: this._onlyTrashed,
170
- };
171
- }
172
- }
1
+ /**
2
+ * QueryBuilder — SQL/MongoDB 쿼리 빌더 (체이닝)
3
+ *
4
+ * @see docs/framework/02-database-orm.md
5
+ * @see docs/framework/class-design.mm.md (QueryBuilder)
6
+ */
7
+ export default class QueryBuilder {
8
+ constructor(model) {
9
+ this._model = model;
10
+ this._wheres = [];
11
+ this._orders = [];
12
+ this._limit = null;
13
+ this._offset = null;
14
+ this._selects = null;
15
+ this._withs = [];
16
+ // softDelete 자동 적용
17
+ this._softDelete = model?.softDelete || false;
18
+ this._withTrashed = false;
19
+ this._onlyTrashed = false;
20
+ }
21
+
22
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
23
+ // 체이닝 메서드
24
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
25
+
26
+ where(key, op, value) {
27
+ if (value === undefined) { value = op; op = '='; }
28
+ this._wheres.push({ key, op, value, type: 'and' });
29
+ return this;
30
+ }
31
+
32
+ /** OR 조건 */
33
+ orWhere(key, op, value) {
34
+ if (value === undefined) { value = op; op = '='; }
35
+ this._wheres.push({ key, op, value, type: 'or' });
36
+ return this;
37
+ }
38
+
39
+ /** IN 조건 */
40
+ whereIn(key, values) {
41
+ this._wheres.push({ key, op: 'IN', value: values, type: 'and' });
42
+ return this;
43
+ }
44
+
45
+ /** NOT NULL 조건 */
46
+ whereNotNull(key) {
47
+ this._wheres.push({ key, op: 'IS NOT NULL', value: null, type: 'and' });
48
+ return this;
49
+ }
50
+
51
+ /** NULL 조건 */
52
+ whereNull(key) {
53
+ this._wheres.push({ key, op: 'IS NULL', value: null, type: 'and' });
54
+ return this;
55
+ }
56
+
57
+ orderBy(column, direction = 'asc') {
58
+ this._orders.push({ column, direction });
59
+ return this;
60
+ }
61
+
62
+ limit(n) { this._limit = n; return this; }
63
+ offset(n) { this._offset = n; return this; }
64
+
65
+ select(...columns) {
66
+ this._selects = columns.flat();
67
+ return this;
68
+ }
69
+
70
+ with(...relations) {
71
+ this._withs.push(...relations.flat());
72
+ return this;
73
+ }
74
+
75
+ /** softDelete 포함 (삭제된 레코드도 조회) */
76
+ withTrashed() {
77
+ this._withTrashed = true;
78
+ return this;
79
+ }
80
+
81
+ /** softDelete만 조회 (삭제된 레코드만) */
82
+ onlyTrashed() {
83
+ this._onlyTrashed = true;
84
+ return this;
85
+ }
86
+
87
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
88
+ // 터미널 메서드
89
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
90
+
91
+ /**
92
+ * 페이지네이션
93
+ * @param {number} page
94
+ * @param {number} perPage
95
+ * @returns {Promise<Pagination>}
96
+ */
97
+ async paginate(page = 1, perPage = 20) {
98
+ // Model 서브클래스에서 오버라이드하여 실제 DB 쿼리 실행
99
+ return {
100
+ data: [],
101
+ page,
102
+ perPage,
103
+ total: 0,
104
+ lastPage: 0,
105
+ _query: this._buildQuery(),
106
+ };
107
+ }
108
+
109
+ /**
110
+ * 전체 결과 반환
111
+ * @returns {Promise<Array>}
112
+ */
113
+ async get() {
114
+ // 서브클래스에서 오버라이드
115
+ return [];
116
+ }
117
+
118
+ /**
119
+ * 단일 결과
120
+ * @returns {Promise<object|null>}
121
+ */
122
+ async first() {
123
+ this._limit = 1;
124
+ const results = await this.get();
125
+ return results[0] || null;
126
+ }
127
+
128
+ /**
129
+ * 결과 수
130
+ * @returns {Promise<number>}
131
+ */
132
+ async count() {
133
+ // 서브클래스에서 오버라이드
134
+ return 0;
135
+ }
136
+
137
+ /**
138
+ * 조건부 수정
139
+ * @param {object} data
140
+ * @returns {Promise<number>} 수정된 행 수
141
+ */
142
+ async update(data) {
143
+ // 서브클래스에서 오버라이드
144
+ return 0;
145
+ }
146
+
147
+ /**
148
+ * 조건부 삭제
149
+ * @returns {Promise<number>} 삭제된 행 수
150
+ */
151
+ async delete() {
152
+ // 서브클래스에서 오버라이드
153
+ return 0;
154
+ }
155
+
156
+ /**
157
+ * 빌드된 쿼리 파라미터 (디버깅/테스트용)
158
+ */
159
+ _buildQuery() {
160
+ return {
161
+ wheres: this._wheres,
162
+ orders: this._orders,
163
+ limit: this._limit,
164
+ offset: this._offset,
165
+ selects: this._selects,
166
+ withs: this._withs,
167
+ softDelete: this._softDelete,
168
+ withTrashed: this._withTrashed,
169
+ onlyTrashed: this._onlyTrashed,
170
+ };
171
+ }
172
+ }
@@ -1,27 +1,27 @@
1
- /**
2
- * SQLiteModel — SQLite 모델 서브클래스 (기본 드라이버)
3
- *
4
- * better-sqlite3 기반 동기 API.
5
- * 개발 환경에서 별도 DB 서버 없이 즉시 사용 가능.
6
- *
7
- * @see docs/framework/02-database-orm.md
8
- *
9
- * @example
10
- * import { SQLiteModel } from '@fuzionx/framework';
11
- *
12
- * export default class User extends SQLiteModel {
13
- * static table = 'users';
14
- * static timestamps = true;
15
- * static columns = {
16
- * id: { type: 'increments' },
17
- * name: { type: 'string', length: 100 },
18
- * email: { type: 'string', length: 150, unique: true },
19
- * };
20
- * }
21
- */
22
- import SqlModel from './SqlModel.js';
23
-
24
- export default class SQLiteModel extends SqlModel {
25
- static driver = 'sqlite';
26
- static connection = 'main';
27
- }
1
+ /**
2
+ * SQLiteModel — SQLite 모델 서브클래스 (기본 드라이버)
3
+ *
4
+ * better-sqlite3 기반 동기 API.
5
+ * 개발 환경에서 별도 DB 서버 없이 즉시 사용 가능.
6
+ *
7
+ * @see docs/framework/02-database-orm.md
8
+ *
9
+ * @example
10
+ * import { SQLiteModel } from '@fuzionx/framework';
11
+ *
12
+ * export default class User extends SQLiteModel {
13
+ * static table = 'users';
14
+ * static timestamps = true;
15
+ * static columns = {
16
+ * id: { type: 'increments' },
17
+ * name: { type: 'string', length: 100 },
18
+ * email: { type: 'string', length: 150, unique: true },
19
+ * };
20
+ * }
21
+ */
22
+ import SqlModel from './SqlModel.js';
23
+
24
+ export default class SQLiteModel extends SqlModel {
25
+ static driver = 'sqlite';
26
+ static connection = 'main';
27
+ }