@things-factory/shell 10.0.0-zeta.3 → 10.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.
- package/client/entries/public/home.js +1 -1
- package/client/themes/app-theme.css +8 -24
- package/client/themes/calendar-theme.css +0 -7
- package/client/themes/grist-theme.css +13 -37
- package/client/themes/layout-theme.css +3 -23
- package/client/themes/report-theme.css +0 -9
- package/client/themes/theme-base.css +30 -0
- package/client/themes/tooltip-theme.css +0 -4
- package/dist-server/bootstrap-hooks.d.ts +51 -0
- package/dist-server/bootstrap-hooks.js +39 -0
- package/dist-server/bootstrap-hooks.js.map +1 -0
- package/dist-server/index.d.ts +1 -0
- package/dist-server/index.js +1 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/initializers/database.js +4 -1
- package/dist-server/initializers/database.js.map +1 -1
- package/dist-server/server-dev.js +13 -10
- package/dist-server/server-dev.js.map +1 -1
- package/dist-server/server.js +12 -8
- package/dist-server/server.js.map +1 -1
- package/dist-server/service/domain/domain-mutation.js +3 -2
- package/dist-server/service/domain/domain-mutation.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/dist-server/typeorm/get-data-encryption-key.js +11 -1
- package/dist-server/typeorm/get-data-encryption-key.js.map +1 -1
- package/dist-server/utils/apply-domain-filter.d.ts +17 -0
- package/dist-server/utils/apply-domain-filter.js +30 -0
- package/dist-server/utils/apply-domain-filter.js.map +1 -0
- package/dist-server/utils/condition-builder.js +15 -7
- package/dist-server/utils/condition-builder.js.map +1 -1
- package/dist-server/utils/get-query-builder-from-list-params.d.ts +39 -9
- package/dist-server/utils/get-query-builder-from-list-params.js +83 -40
- package/dist-server/utils/get-query-builder-from-list-params.js.map +1 -1
- package/dist-server/utils/list-params-converter.js +8 -6
- package/dist-server/utils/list-params-converter.js.map +1 -1
- package/dist-server/utils/list-query-builder.js +2 -14
- package/dist-server/utils/list-query-builder.js.map +1 -1
- package/jest.config.js +5 -0
- package/package.json +12 -12
- package/tests/get-query-builder-features.test.ts +229 -0
- package/tests/list-param-operators.test.ts +87 -0
- package/tests/manifest-contract.test.ts +38 -0
- package/client/store.ts +0 -15
|
@@ -83,7 +83,7 @@ export class HomePage extends LitElement {
|
|
|
83
83
|
var descriptionMeta = document.querySelector('meta[name="application-description"]')
|
|
84
84
|
|
|
85
85
|
this._applicationMeta = {
|
|
86
|
-
icon: iconLink ? iconLink.href :
|
|
86
|
+
icon: iconLink ? iconLink.href : undefined,
|
|
87
87
|
title: titleMeta ? titleMeta.content : 'Things Factory',
|
|
88
88
|
description: descriptionMeta ? descriptionMeta.content : 'Reimagining Software'
|
|
89
89
|
}
|
|
@@ -12,7 +12,10 @@ body {
|
|
|
12
12
|
|
|
13
13
|
/* common style */
|
|
14
14
|
--border-radius: 4px;
|
|
15
|
-
|
|
15
|
+
/* 라이트/다크 모두 대비되는 캐럿 — 별도 .dark override 불필요 */
|
|
16
|
+
caret-color: var(--md-sys-color-on-surface);
|
|
17
|
+
|
|
18
|
+
--border-dim-color: 1px solid var(--md-sys-color-outline-variant);
|
|
16
19
|
--border-light-color: 1px solid rgba(255, 255, 255, 0.3);
|
|
17
20
|
|
|
18
21
|
--box-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.1);
|
|
@@ -40,7 +43,6 @@ body {
|
|
|
40
43
|
--title-margin: var(--margin-narrow) 0;
|
|
41
44
|
--title-font: bold 24px var(--theme-font);
|
|
42
45
|
--title-text-color: var(--md-sys-color-secondary);
|
|
43
|
-
--title-font-mobile: bold 20px var(--theme-font);
|
|
44
46
|
|
|
45
47
|
--page-description-margin: var(--margin-narrow) 0 var(--margin-wide) 0;
|
|
46
48
|
--page-description-font: normal var(--fontsize-default) / 1.2rem var(--theme-font);
|
|
@@ -54,19 +56,9 @@ body {
|
|
|
54
56
|
/* icon style */
|
|
55
57
|
--icon-tiny-size: var(--icon-size-medium, 24px);
|
|
56
58
|
--icon-default-size: var(--icon-size-large, 32px);
|
|
57
|
-
--icon-big-size: var(--icon-size-huge, 48px);
|
|
58
|
-
--icon-default-color: var(--md-sys-color-on-primary);
|
|
59
59
|
|
|
60
60
|
/* material design component themes */
|
|
61
|
-
--mdc-theme-on-primary: var(--md-sys-color-on-primary);
|
|
62
|
-
--mdc-theme-primary: var(--secondary-text-color);
|
|
63
|
-
--mdc-theme-on-secondary: var(--md-sys-color-on-primary);
|
|
64
|
-
--mdc-theme-secondary: var(--md-sys-color-primary);
|
|
65
|
-
--mdc-button-outline-color: var(--md-sys-color-primary);
|
|
66
61
|
--mdc-danger-button-primary-color: var(--status-danger-color);
|
|
67
|
-
--mdc-danger-button-outline-color: var(--status-danger-color);
|
|
68
|
-
--mdc-button-outline-width: 1px;
|
|
69
|
-
--mdc-button-horizontal-padding: 16px;
|
|
70
62
|
|
|
71
63
|
/* button style */
|
|
72
64
|
--button-background-color: var(--md-sys-color-surface-variant);
|
|
@@ -81,8 +73,6 @@ body {
|
|
|
81
73
|
--button-active-box-shadow: 1px 1px 1px 0px rgba(0, 0, 0, 0.2);
|
|
82
74
|
--button-activ-border: 1px solid var(--md-sys-color-primary);
|
|
83
75
|
--button-activ-background-color: var(--md-sys-color-primary);
|
|
84
|
-
--button-activ-color: var(--md-sys-color-on-primary);
|
|
85
|
-
--iconbtn-padding: var(--padding-narrow);
|
|
86
76
|
|
|
87
77
|
--button-primary-background-color: var(--md-sys-color-primary);
|
|
88
78
|
--button-primary-active-background-color: var(--status-success-color);
|
|
@@ -99,9 +89,9 @@ body {
|
|
|
99
89
|
|
|
100
90
|
--tr-background-color: var(--md-sys-color-surface-variant);
|
|
101
91
|
--tr-background-odd-color: rgba(255, 255, 255, 0.4);
|
|
102
|
-
--tr-background-hover-color:
|
|
103
|
-
--td-border-line: 1px solid
|
|
104
|
-
--td-border-bottom: 1px solid
|
|
92
|
+
--tr-background-hover-color: var(--md-sys-color-secondary-container);
|
|
93
|
+
--td-border-line: 1px solid var(--md-sys-color-outline-variant);
|
|
94
|
+
--td-border-bottom: 1px solid var(--md-sys-color-outline-variant);
|
|
105
95
|
--td-padding: var(--padding-default);
|
|
106
96
|
--td-font: normal 13px var(--theme-font);
|
|
107
97
|
--td-color: var(--md-sys-color-secondary);
|
|
@@ -114,10 +104,9 @@ body {
|
|
|
114
104
|
--label-text-transform: capitalize;
|
|
115
105
|
--input-margin: var(--margin-narrow) 0;
|
|
116
106
|
--input-padding: 6px 2px;
|
|
117
|
-
--input-min-width: 200px;
|
|
118
107
|
--input-font: normal var(--fontsize-default) var(--theme-font);
|
|
119
108
|
--input-hint-font: normal var(--fontsize-small) var(--theme-font);
|
|
120
|
-
--input-hint-color:
|
|
109
|
+
--input-hint-color: var(--md-sys-color-on-surface-variant);
|
|
121
110
|
--input-container-max-width: 900px;
|
|
122
111
|
--fieldset-margin: var(--padding-wide) 0;
|
|
123
112
|
--fieldset-padding: 0 var(--padding-wide) var(--padding-wide) var(--padding-wide);
|
|
@@ -126,12 +115,7 @@ body {
|
|
|
126
115
|
--legend-font: bold 16px var(--theme-font);
|
|
127
116
|
}
|
|
128
117
|
|
|
129
|
-
body.dark {
|
|
130
|
-
caret-color: white;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
118
|
html {
|
|
134
|
-
--scene-theme-font-family: 'Roboto', Helvetica;
|
|
135
119
|
}
|
|
136
120
|
|
|
137
121
|
@media only screen and (max-width: 460px) {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
body {
|
|
2
|
-
--ox-calendar-padding: var(--padding-default);
|
|
3
2
|
|
|
4
3
|
/* monthly common color */
|
|
5
|
-
--calendar-monthly-text-color: var(--md-sys-color-secondary);
|
|
6
4
|
--calendar-monthly-border: 1px solid rgba(0, 0, 0, 0.1);
|
|
7
5
|
--calendar-monthly-border-width: 0 1px 1px 0px;
|
|
8
6
|
|
|
@@ -13,7 +11,6 @@ body {
|
|
|
13
11
|
--calendar-current-month-color: var(--md-sys-color-on-surface);
|
|
14
12
|
--calendar-monthly-label-align: left;
|
|
15
13
|
--calendar-monthly-label-padding: var(--padding-narrow) 0;
|
|
16
|
-
--calendar-monthly-label-color: var(--md-sys-color-secondary);
|
|
17
14
|
--calendar-monthly-opacity: 0.5;
|
|
18
15
|
--calendar-monthly-date-label-background-color: var(--status-danger-color);
|
|
19
16
|
--calendar-monthly-date-label-margin: var(--margin-narrow);
|
|
@@ -21,7 +18,6 @@ body {
|
|
|
21
18
|
--calendar-monthly-date-label-color: var(--md-sys-color-on-primary);
|
|
22
19
|
|
|
23
20
|
--calendar-monthly-background-color: #f4f4f4;
|
|
24
|
-
--calendar-monthly-event-border-radius: var(--border-radius);
|
|
25
21
|
--calendar-monthly-event-margin: var(--padding-narrow) 0 0 0;
|
|
26
22
|
--calendar-monthly-event-padding: 2px var(--padding-default);
|
|
27
23
|
--calendar-monthly-event-border: 3px solid #ccc;
|
|
@@ -39,7 +35,6 @@ body {
|
|
|
39
35
|
--calendar-current-week-color: var(--md-sys-color-on-surface);
|
|
40
36
|
--calendar-weekly-label-align: center;
|
|
41
37
|
--calendar-weekly-label-padding: var(--padding-narrow) 0;
|
|
42
|
-
--calendar-weekly-label-color: var(--md-sys-color-secondary);
|
|
43
38
|
--calendar-weekly-opacity: 0.5;
|
|
44
39
|
--calendar-weekly-date-label-background-color: var(--status-danger-color);
|
|
45
40
|
--calendar-weekly-date-label-margin: var(--margin-narrow);
|
|
@@ -47,7 +42,6 @@ body {
|
|
|
47
42
|
--calendar-weekly-date-label-color: var(--md-sys-color-on-primary);
|
|
48
43
|
|
|
49
44
|
--calendar-weekly-background-color: #f4f4f4;
|
|
50
|
-
--calendar-weekly-event-border-radius: var(--border-radius);
|
|
51
45
|
--calendar-weekly-event-margin: var(--padding-narrow) 0 0 0;
|
|
52
46
|
--calendar-weekly-event-padding: 2px var(--padding-default);
|
|
53
47
|
--calendar-weekly-event-border: 3px solid #ccc;
|
|
@@ -56,6 +50,5 @@ body {
|
|
|
56
50
|
|
|
57
51
|
@media only screen and (max-width: 460px) {
|
|
58
52
|
body {
|
|
59
|
-
--calendar-monthly-text-color: tomato;
|
|
60
53
|
}
|
|
61
54
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
body {
|
|
2
|
-
|
|
2
|
+
/* 토큰 파생 — 라이트/다크가 자동 정합되므로 별도 .dark override 불필요 */
|
|
3
|
+
--grid-container-border-color: 1px solid var(--md-sys-color-outline-variant);
|
|
3
4
|
--grid-container-border-width: 1px 0;
|
|
4
5
|
--grid-wrap-container-border: 0px solid transparent;
|
|
5
6
|
--grid-wrap-container-border-width: 0;
|
|
@@ -9,7 +10,6 @@ body {
|
|
|
9
10
|
--grist-title-border: none;
|
|
10
11
|
--grist-title-font: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)) 1.1em
|
|
11
12
|
var(--theme-font, 'Roboto');
|
|
12
|
-
--grist-title-color: var(--md-sys-color-on-surface);
|
|
13
13
|
--grist-title-icon-color: var(--md-sys-color-on-surface-variant);
|
|
14
14
|
--grist-title-icon-margin: 0 3px 2px 0;
|
|
15
15
|
--grist-title-icon-size: var(--md-sys-typescale-label-large-size, 0.875rem);
|
|
@@ -18,15 +18,14 @@ body {
|
|
|
18
18
|
--grist-object-editor-font: normal 1em var(--theme-font, 'Roboto');
|
|
19
19
|
--grist-object-editor-color: var(--md-sys-color-on-surface);
|
|
20
20
|
|
|
21
|
-
--grist-input-progress-border: 1px solid
|
|
22
|
-
--grist-input-progress-background:
|
|
23
|
-
--grist-input-progress-bar-background: var(--md-sys-color-primary-
|
|
21
|
+
--grist-input-progress-border: 1px solid var(--md-sys-color-outline-variant);
|
|
22
|
+
--grist-input-progress-background: var(--md-sys-color-surface-container-high);
|
|
23
|
+
--grist-input-progress-bar-background: var(--md-sys-color-primary-container);
|
|
24
24
|
--grist-input-progress-bar-color: var(--md-sys-color-on-surface-variant);
|
|
25
25
|
|
|
26
26
|
--grid-header-background-color: var(--md-sys-color-surface-container-low);
|
|
27
27
|
--grid-header-top-border: 2px solid var(--md-sys-color-primary);
|
|
28
28
|
--grid-header-bottom-border: var(--grid-container-border-color);
|
|
29
|
-
--grid-header-border-color: var(--md-sys-color-outline);
|
|
30
29
|
--grid-header-padding: var(--spacing-small) var(--spacing-tiny);
|
|
31
30
|
--grid-header-sorter-size: 18px;
|
|
32
31
|
--grid-header-splitter-border: var(--grid-container-border-color);
|
|
@@ -46,16 +45,14 @@ body {
|
|
|
46
45
|
--grid-record-odd-background-color: var(--md-sys-color-surface-container-low);
|
|
47
46
|
--grid-record-padding: var(--spacing-small) var(--spacing-medium);
|
|
48
47
|
--grid-record-color: var(--md-sys-color-on-surface-variant);
|
|
49
|
-
--grid-record-color-hover: var(--md-sys-color-primary);
|
|
50
48
|
--grid-record-wide-fontsize: var(--md-sys-typescale-label-large-size, 0.875rem);
|
|
51
49
|
--grid-record-selected-background-color: var(--md-sys-color-primary-container);
|
|
52
50
|
--grid-record-selected-color: var(--md-sys-color-on-primary-container);
|
|
53
|
-
--grid-record-focused-border: 1px solid var(--md-sys-color-outline-variant);
|
|
54
|
-
--grid-record-focused-cell-background-color: var(--md-sys-color-secondary-container);
|
|
55
51
|
--grid-record-focused-cell-border: 1px dashed var(--md-sys-color-outline);
|
|
56
52
|
--grid-record-focused-box-shadow: 0px 2px 0px 0px rgb(0 0 0 / 10%);
|
|
57
|
-
|
|
58
|
-
--grid-record-emphasized-color: var(--md-sys-color-
|
|
53
|
+
/* -fixed 는 라이트/다크 동일(고정)이라 다크에서 잔존 → 적응형 -container 짝으로 */
|
|
54
|
+
--grid-record-emphasized-background-color: var(--md-sys-color-secondary-container);
|
|
55
|
+
--grid-record-emphasized-color: var(--md-sys-color-on-secondary-container);
|
|
59
56
|
--grid-record-editing-background-color: var(--md-sys-color-inverse-primary);
|
|
60
57
|
--grid-record-editing-border: 1px dashed rgba(var(--md-sys-color-primary-rgb), 0.4);
|
|
61
58
|
--grid-record-fontsize: var(--md-sys-typescale-label-large-size, 0.875rem);
|
|
@@ -70,13 +67,11 @@ body {
|
|
|
70
67
|
--grid-footer-background-color: var(--md-sys-color-surface-container-low);
|
|
71
68
|
--grid-footer-font-size: var(--md-sys-typescale-label-large-size, 0.875rem);
|
|
72
69
|
--grid-footer-color: var(--md-sys-color-primary);
|
|
73
|
-
--grid-footer-limit-color: var(--md-
|
|
74
|
-
--grid-footer-inactive-color: var(--md-
|
|
70
|
+
--grid-footer-limit-color: var(--md-sys-color-on-surface-variant);
|
|
71
|
+
--grid-footer-inactive-color: var(--md-sys-color-on-surface-variant);
|
|
75
72
|
--grid-footer-padding: var(--spacing-small) var(--spacing-medium);
|
|
76
73
|
|
|
77
74
|
--data-list-background-color: var(--md-sys-color-surface-container-lowest);
|
|
78
|
-
--data-list-item-margin: var(--spacing-medium);
|
|
79
|
-
--data-list-item-padding: var(--spacing-medium) var(--spacing-large);
|
|
80
75
|
--data-list-item-border-bottom: var(--grid-container-border-color);
|
|
81
76
|
--data-list-item-name-font: bold 1.1em var(--theme-font, 'Roboto');
|
|
82
77
|
--data-list-item-name-color: var(--md-sys-color-secondary);
|
|
@@ -84,47 +79,34 @@ body {
|
|
|
84
79
|
--data-list-item-disc-color: var(--md-sys-color-on-tertiary-container);
|
|
85
80
|
--data-list-item-etc-label-font: bold 1em/1em var(--theme-font, 'Roboto');
|
|
86
81
|
--data-list-item-etc-font: normal 0.9em/1em var(--theme-font, 'Roboto');
|
|
87
|
-
--data-list-item-etc-color: var(--md-
|
|
88
|
-
--data-list-item-icon-font: normal 1em/1em;
|
|
89
|
-
--data-list-item-icon-color: var(--md-sys-color-on-secondary);
|
|
82
|
+
--data-list-item-etc-color: var(--md-sys-color-on-surface-variant);
|
|
90
83
|
--data-list-selected-background-color: var(--grid-record-selected-background-color);
|
|
91
84
|
--data-list-fab-position-horizontal: 15px;
|
|
92
85
|
--data-list-fab-position-vertical: 15px;
|
|
93
86
|
--data-list-fab-color: var(--md-sys-color-primary);
|
|
94
87
|
--data-list-fab-shadow: var(--box-shadow);
|
|
95
88
|
|
|
96
|
-
--data-card-background-color: var(--md-sys-color-surface-container);
|
|
97
89
|
--data-card-record-card-background-color: var(--md-sys-color-surface-container-lowest);
|
|
98
90
|
--data-card-record-card-border: var(--grid-container-border-color);
|
|
99
91
|
--data-card-record-card-border-hover: 1px solid var(--md-sys-color-primary);
|
|
100
92
|
--data-card-record-card-boxshadow-hover: 1px 1px 2px 1px rgba(0, 0, 0, 0.15);
|
|
101
|
-
--data-card-record-card-selected-border: 1px solid var(--md-sys-color-primary);
|
|
102
93
|
--data-card-record-card-border-radius: var(--md-sys-shape-corner-medium);
|
|
103
94
|
--data-card-item-margin: var(--spacing-medium);
|
|
104
|
-
--data-card-item-padding: var(--spacing-medium) var(--spacing-large);
|
|
105
|
-
--data-card-item-border-bottom: var(--grid-container-border-color);
|
|
106
95
|
--data-card-item-name-font: bold 1.1em var(--theme-font, 'Roboto');
|
|
107
96
|
--data-card-item-name-color: var(--md-sys-color-secondary);
|
|
108
|
-
--data-card-item-name-label-font: normal 0.65em/0.8em var(--theme-font, 'Roboto');
|
|
109
|
-
--data-card-item-name-label-color: var(--md-sys-color-secondary);
|
|
110
97
|
--data-card-item-disc-font: normal 0.9em var(--theme-font, 'Roboto');
|
|
111
98
|
--data-card-item-disc-color: var(--md-sys-color-tertiary);
|
|
112
99
|
--data-card-item-etc-label-font: normal 1em/1em var(--theme-font, 'Roboto');
|
|
113
100
|
--data-card-item-etc-font: normal 0.9em/1em var(--theme-font, 'Roboto');
|
|
114
|
-
--data-card-item-etc-color: var(--md-
|
|
115
|
-
--data-card-item-icon-font: normal 1em/1em;
|
|
116
|
-
--data-card-item-icon-color: var(--md-sys-color-on-secondary);
|
|
101
|
+
--data-card-item-etc-color: var(--md-sys-color-on-surface-variant);
|
|
117
102
|
--data-card-item-btn-border: var(--grid-container-border-color);
|
|
118
103
|
--data-card-item-btn-border-radius: var(--md-sys-shape-corner-small);
|
|
119
104
|
--data-card-item-btn-padding: var(--spacing-small);
|
|
120
|
-
--data-card-selected-background-color: var(--grid-record-selected-background-color);
|
|
121
105
|
--data-card-fab-position-horizontal: 15px;
|
|
122
106
|
--data-card-fab-position-vertical: 15px;
|
|
123
107
|
--data-card-fab-color: var(--md-sys-color-primary);
|
|
124
108
|
--data-card-fab-shadow: var(--box-shadow);
|
|
125
109
|
--data-card-thumbnail-height: 140px;
|
|
126
|
-
--data-card-thumbnail-border-bottom: var(--grid-container-border-color);
|
|
127
|
-
--data-card-attachimg-height: 70px;
|
|
128
110
|
|
|
129
111
|
--record-view-background-color: var(--md-sys-color-surface-container);
|
|
130
112
|
--record-view-gap: var(--spacing-small) 0;
|
|
@@ -140,12 +122,10 @@ body {
|
|
|
140
122
|
--record-view-edit-border-bottom: 2px solid var(--md-sys-color-primary);
|
|
141
123
|
--record-view-item-padding: var(--spacing-medium);
|
|
142
124
|
|
|
143
|
-
--record-view-footer-background: var(--md-
|
|
125
|
+
--record-view-footer-background: var(--md-sys-color-on-surface-variant);
|
|
144
126
|
--record-view-footer-button-border: var(--grid-container-border-color);
|
|
145
127
|
--record-view-footer-button-border-width: 0 0 0 1px;
|
|
146
|
-
--record-view-footer-button-font: 17px;
|
|
147
128
|
--record-view-footer-button-color: var(--md-sys-color-surface);
|
|
148
|
-
--record-view-footer-iconbutton-size: 35px;
|
|
149
129
|
--record-view-footer-focus-background: var(--md-sys-color-primary);
|
|
150
130
|
|
|
151
131
|
--ox-grist-padding: var(--spacing-medium);
|
|
@@ -166,10 +146,6 @@ body {
|
|
|
166
146
|
}
|
|
167
147
|
@media (min-width: 461px) and (max-width: 1024px) {
|
|
168
148
|
body {
|
|
169
|
-
--data-card-create-form-padding: 7px;
|
|
170
149
|
}
|
|
171
150
|
}
|
|
172
151
|
|
|
173
|
-
body.dark {
|
|
174
|
-
--grid-container-border-color: 1px solid rgba(255, 255, 255, 0.09);
|
|
175
|
-
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
body {
|
|
2
2
|
--header-bar-background-color: var(--md-sys-color-primary);
|
|
3
|
-
--header-bar-icon-size: var(--icon-default-size);
|
|
4
3
|
--header-bar-title: bold 17.5px var(--theme-font);
|
|
5
4
|
--header-bar-color: var(--md-sys-color-on-primary);
|
|
6
5
|
--header-bar-height: 42px;
|
|
@@ -11,18 +10,7 @@ body {
|
|
|
11
10
|
--group-bar-textbutton: 16px/32px var(--theme-font);
|
|
12
11
|
--group-bar-textbutton-active: bold var(--group-bar-textbutton);
|
|
13
12
|
--group-bar-active-line-color: var(--md-sys-color-on-secondary-container);
|
|
14
|
-
--group-bar-line: solid 3px
|
|
15
|
-
|
|
16
|
-
--footer-bar-border-top: 1px solid rgba(0, 0, 0, 0.2);
|
|
17
|
-
|
|
18
|
-
--aside-background-color: var(--md-sys-color-secondary-container);
|
|
19
|
-
--aside-list-textbtton: 18px var(--theme-font);
|
|
20
|
-
--aside-list-icon: var(--icon-default-size);
|
|
21
|
-
--aside-list-bottom-line: var(--md-sys-color-outline);
|
|
22
|
-
--aside-list-detail-background-color: #fff;
|
|
23
|
-
--aside-list-detail-text: 14px var(--md-sys-color-on-secondary-container);
|
|
24
|
-
|
|
25
|
-
--footer-bar-border-top: 1px solid rgba(0, 0, 0, 0.2);
|
|
13
|
+
--group-bar-line: solid 3px var(--md-sys-color-outline);
|
|
26
14
|
|
|
27
15
|
--button-container-margin: inintial;
|
|
28
16
|
--button-container-padding: 0 var(--padding-default) var(--padding-wide) var(--padding-default);
|
|
@@ -32,8 +20,6 @@ body {
|
|
|
32
20
|
--button-container-button-background-color: var(--md-sys-color-secondary);
|
|
33
21
|
--button-container-button-border-radius: var(--button-border-radius);
|
|
34
22
|
--button-container-button-margin: var(--button-margin);
|
|
35
|
-
--button-container-button-font: bold var(--fontsize-large) var(--theme-font);
|
|
36
|
-
--button-container-button-color: var(--md-sys-color-on-primary);
|
|
37
23
|
--button-container-button-height: initial;
|
|
38
24
|
--button-container-button-border: var(--button-border);
|
|
39
25
|
|
|
@@ -48,16 +34,10 @@ body {
|
|
|
48
34
|
--overlay-center-normal-height: 50%;
|
|
49
35
|
--overlay-center-large-width: 75%;
|
|
50
36
|
--overlay-center-large-height: 75%;
|
|
51
|
-
--overlay-header-height: var(--header-bar-height);
|
|
52
|
-
--overlay-header-background-color: var(--header-bar-background-color);
|
|
53
|
-
--overlay-header-color: #fff;
|
|
54
|
-
--overlay-header-font: var(--header-bar-title);
|
|
55
|
-
--overlay-background-color: rgba(0, 0, 0, 0.5);
|
|
56
|
-
--overlay-margin-bottom: 0px;
|
|
57
37
|
|
|
58
38
|
/* components - resize splitter style */
|
|
59
|
-
--splitter-background-color:
|
|
60
|
-
--splitter-hover-background-color:
|
|
39
|
+
--splitter-background-color: var(--md-sys-color-surface-variant);
|
|
40
|
+
--splitter-hover-background-color: var(--md-sys-color-surface-variant);
|
|
61
41
|
}
|
|
62
42
|
|
|
63
43
|
@media only screen and (max-width: 460px) {
|
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
body {
|
|
2
2
|
--report-background-color: var(--md-sys-color-background);
|
|
3
3
|
--report-padding: 15px;
|
|
4
|
-
--report-title-margin: 0 0 0 10px;
|
|
5
|
-
--report-title-border: none;
|
|
6
|
-
--report-title-color: var(--md-sys-color-secondary);
|
|
7
|
-
--report-title-icon-color: var(--md-sys-color-primary);
|
|
8
|
-
--report-title-icon-margin: 0 3px 2px 0;
|
|
9
|
-
--report-title-icon-size: 14px;
|
|
10
|
-
--report-title-with-grid-padding: 0;
|
|
11
4
|
--report-component-border-radius: var(--border-radius);
|
|
12
5
|
|
|
13
6
|
--report-header-background-color: var(--md-sys-color-surface);
|
|
14
|
-
--report-header-border: 1px solid var(--report-header-border-color);
|
|
15
7
|
--report-header-border-color: var(--md-sys-color-outline);
|
|
16
8
|
--report-header-padding: 5px 0 5px 5px;
|
|
17
9
|
--report-header-color: var(--secondary-text-color);
|
|
@@ -19,7 +11,6 @@ body {
|
|
|
19
11
|
--report-header-fontsize: 13px;
|
|
20
12
|
|
|
21
13
|
--report-record-background-color: #fff;
|
|
22
|
-
--report-record-odd-background-color: #f6f6f6;
|
|
23
14
|
--report-record-field-padding: 7px 10px;
|
|
24
15
|
--report-record-field-border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
25
16
|
--report-record-wide-fontsize: 13px;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* theme-base — 모든 앱이 공유하는 테마 기반 규칙.
|
|
3
|
+
*
|
|
4
|
+
* [왜 이 파일이 따로 있는가]
|
|
5
|
+
* builder 의 ThemeOverridePlugin 은 테마를 **파일명 단위로 완전 대체**한다(병합이 아님).
|
|
6
|
+
* 즉 앱이 `themes/light.css` 를 가지면 shell 의 `light.css` 는 빌드에서 제외된다.
|
|
7
|
+
* 그래서 공통 규칙을 light/dark 에 넣으면 앱마다 복제해야 하고, 누락이 필연적이다.
|
|
8
|
+
* (실제로 `color-scheme` 이 6개 앱에서 누락되어 있었다.)
|
|
9
|
+
*
|
|
10
|
+
* `theme-base.css` 는 **어떤 앱도 같은 이름으로 override 하지 않는 파일**이므로 항상 번들에 포함된다.
|
|
11
|
+
* → 공통 불변 규칙은 여기 한 곳에만 두면 전 앱에 적용된다.
|
|
12
|
+
*
|
|
13
|
+
* [넣는 것] 브랜드와 무관하게 항상 성립해야 하는 규칙(테마 스킴, 공통 접근성 기본값 등)
|
|
14
|
+
* [넣지 않는 것] 브랜드 색값 — 그것은 각 앱의 `light.css` / `dark.css` 소관(49개 md-sys 슬롯)
|
|
15
|
+
*
|
|
16
|
+
* 참고: v10/UI-PILOT-THEME-CONSISTENCY.md §3.5
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
* UA 네이티브 표면(스크롤바·폼 컨트롤·초기 배경)을 앱 테마와 일치시킨다.
|
|
21
|
+
* 선언이 없으면 다크 테마에서 native input/textarea/select·스크롤바가 밝은 OS 크롬으로 렌더된다.
|
|
22
|
+
* 색값이 아니라 스킴 선언이므로 브랜드 팔레트와 무관하게 공통 적용 가능하다.
|
|
23
|
+
*/
|
|
24
|
+
.light {
|
|
25
|
+
color-scheme: light;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.dark {
|
|
29
|
+
color-scheme: dark;
|
|
30
|
+
}
|
|
@@ -3,9 +3,5 @@ body {
|
|
|
3
3
|
--tooltip-background-color: rgba(0, 0, 0, 0.7);
|
|
4
4
|
--tooltip-font: bold 11px var(--theme-font);
|
|
5
5
|
/*
|
|
6
|
-
--tooltip-left-positon-left: auto;
|
|
7
|
-
--tooltip-left-position-top: 7px;
|
|
8
|
-
--tooltip-left-position-right: 110%;
|
|
9
|
-
--tooltip-left-position-animation: tooltip-left 0.3s ease-out 0s 1 normal;
|
|
10
6
|
*/
|
|
11
7
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import Koa from 'koa';
|
|
2
|
+
import Router from 'koa-router';
|
|
3
|
+
/**
|
|
4
|
+
* 부트스트랩 훅 레지스트리 (P1: 타입드 모듈 매니페스트 — 3단계).
|
|
5
|
+
*
|
|
6
|
+
* shell 은 부트스트랩 과정에서 `process` EventEmitter 로 일련의 라이프사이클 이벤트를 emit 하고,
|
|
7
|
+
* 각 모듈은 이를 listen 해 라우터/미들웨어/구독을 등록한다. 이 파일은 그 문자열 이벤트명과
|
|
8
|
+
* 페이로드를 한곳에서 타입으로 고정한다.
|
|
9
|
+
*
|
|
10
|
+
* 원칙(하위호환):
|
|
11
|
+
* - 내부는 여전히 동일한 `process.emit/on` 을 사용한다 → 기존 136개 모듈의
|
|
12
|
+
* `process.on('bootstrap-module-*', ...)` 는 그대로 동작한다(무변경).
|
|
13
|
+
* - shell 의 emit 측을 `emitHook` 으로 전환해 이벤트명 오타·페이로드 시그니처를 컴파일 체크한다.
|
|
14
|
+
* - 모듈은 원하면 `onHook` 으로 자발적 전환 가능(강제 아님).
|
|
15
|
+
*/
|
|
16
|
+
/** 부트스트랩 훅 이름 상수 (오타 방지용 단일 소스). */
|
|
17
|
+
export declare const BOOTSTRAP_HOOKS: {
|
|
18
|
+
readonly moduleSubscription: "bootstrap-module-subscription";
|
|
19
|
+
readonly collectSsoMiddleware: "bootstrap-collect-sso-middleware";
|
|
20
|
+
readonly globalPublicRoute: "bootstrap-module-global-public-route";
|
|
21
|
+
readonly globalPrivateRoute: "bootstrap-module-global-private-route";
|
|
22
|
+
readonly domainPublicRoute: "bootstrap-module-domain-public-route";
|
|
23
|
+
readonly domainPrivateRoute: "bootstrap-module-domain-private-route";
|
|
24
|
+
readonly moduleStart: "bootstrap-module-start";
|
|
25
|
+
readonly clientRebuilt: "client-rebuilt";
|
|
26
|
+
};
|
|
27
|
+
/** module-start 훅 페이로드. */
|
|
28
|
+
export interface BootstrapModuleStartPayload {
|
|
29
|
+
app: Koa;
|
|
30
|
+
config: any;
|
|
31
|
+
builtSchema: any;
|
|
32
|
+
httpServer: any;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 훅 이벤트명 → emit/on 인자 튜플 매핑.
|
|
36
|
+
* (동적 수집 지점인 middleware/collection 인자는 any 로 둔다.)
|
|
37
|
+
*/
|
|
38
|
+
export interface BootstrapHookArgs {
|
|
39
|
+
'bootstrap-module-subscription': [app: Koa, subscriptionMiddleware: any];
|
|
40
|
+
'bootstrap-collect-sso-middleware': [value: null, ssoMiddlewares: any[]];
|
|
41
|
+
'bootstrap-module-global-public-route': [app: Koa, router: Router];
|
|
42
|
+
'bootstrap-module-global-private-route': [app: Koa, router: Router];
|
|
43
|
+
'bootstrap-module-domain-public-route': [app: Koa, router: Router];
|
|
44
|
+
'bootstrap-module-domain-private-route': [app: Koa, router: Router];
|
|
45
|
+
'bootstrap-module-start': [payload: BootstrapModuleStartPayload];
|
|
46
|
+
'client-rebuilt': [app: Koa, outputFileSystem: any];
|
|
47
|
+
}
|
|
48
|
+
/** 부트스트랩 훅을 타입 안전하게 emit 한다(내부적으로 process.emit). */
|
|
49
|
+
export declare function emitHook<K extends keyof BootstrapHookArgs>(name: K, ...args: BootstrapHookArgs[K]): void;
|
|
50
|
+
/** 부트스트랩 훅을 타입 안전하게 구독한다(내부적으로 process.on). 기존 process.on 과 병존. */
|
|
51
|
+
export declare function onHook<K extends keyof BootstrapHookArgs>(name: K, handler: (...args: BootstrapHookArgs[K]) => void): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BOOTSTRAP_HOOKS = void 0;
|
|
4
|
+
exports.emitHook = emitHook;
|
|
5
|
+
exports.onHook = onHook;
|
|
6
|
+
/**
|
|
7
|
+
* 부트스트랩 훅 레지스트리 (P1: 타입드 모듈 매니페스트 — 3단계).
|
|
8
|
+
*
|
|
9
|
+
* shell 은 부트스트랩 과정에서 `process` EventEmitter 로 일련의 라이프사이클 이벤트를 emit 하고,
|
|
10
|
+
* 각 모듈은 이를 listen 해 라우터/미들웨어/구독을 등록한다. 이 파일은 그 문자열 이벤트명과
|
|
11
|
+
* 페이로드를 한곳에서 타입으로 고정한다.
|
|
12
|
+
*
|
|
13
|
+
* 원칙(하위호환):
|
|
14
|
+
* - 내부는 여전히 동일한 `process.emit/on` 을 사용한다 → 기존 136개 모듈의
|
|
15
|
+
* `process.on('bootstrap-module-*', ...)` 는 그대로 동작한다(무변경).
|
|
16
|
+
* - shell 의 emit 측을 `emitHook` 으로 전환해 이벤트명 오타·페이로드 시그니처를 컴파일 체크한다.
|
|
17
|
+
* - 모듈은 원하면 `onHook` 으로 자발적 전환 가능(강제 아님).
|
|
18
|
+
*/
|
|
19
|
+
/** 부트스트랩 훅 이름 상수 (오타 방지용 단일 소스). */
|
|
20
|
+
exports.BOOTSTRAP_HOOKS = {
|
|
21
|
+
moduleSubscription: 'bootstrap-module-subscription',
|
|
22
|
+
collectSsoMiddleware: 'bootstrap-collect-sso-middleware',
|
|
23
|
+
globalPublicRoute: 'bootstrap-module-global-public-route',
|
|
24
|
+
globalPrivateRoute: 'bootstrap-module-global-private-route',
|
|
25
|
+
domainPublicRoute: 'bootstrap-module-domain-public-route',
|
|
26
|
+
domainPrivateRoute: 'bootstrap-module-domain-private-route',
|
|
27
|
+
moduleStart: 'bootstrap-module-start',
|
|
28
|
+
clientRebuilt: 'client-rebuilt'
|
|
29
|
+
};
|
|
30
|
+
/** 부트스트랩 훅을 타입 안전하게 emit 한다(내부적으로 process.emit). */
|
|
31
|
+
function emitHook(name, ...args) {
|
|
32
|
+
;
|
|
33
|
+
process.emit(name, ...args);
|
|
34
|
+
}
|
|
35
|
+
/** 부트스트랩 훅을 타입 안전하게 구독한다(내부적으로 process.on). 기존 process.on 과 병존. */
|
|
36
|
+
function onHook(name, handler) {
|
|
37
|
+
process.on(name, handler);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=bootstrap-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-hooks.js","sourceRoot":"","sources":["../server/bootstrap-hooks.ts"],"names":[],"mappings":";;;AAqDA,4BAEC;AAGD,wBAKC;AA5DD;;;;;;;;;;;;GAYG;AAEH,oCAAoC;AACvB,QAAA,eAAe,GAAG;IAC7B,kBAAkB,EAAE,+BAA+B;IACnD,oBAAoB,EAAE,kCAAkC;IACxD,iBAAiB,EAAE,sCAAsC;IACzD,kBAAkB,EAAE,uCAAuC;IAC3D,iBAAiB,EAAE,sCAAsC;IACzD,kBAAkB,EAAE,uCAAuC;IAC3D,WAAW,EAAE,wBAAwB;IACrC,aAAa,EAAE,gBAAgB;CACvB,CAAA;AAyBV,oDAAoD;AACpD,SAAgB,QAAQ,CAAoC,IAAO,EAAE,GAAG,IAA0B;IAChG,CAAC;IAAC,OAAe,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAA;AACvC,CAAC;AAED,mEAAmE;AACnE,SAAgB,MAAM,CACpB,IAAO,EACP,OAAgD;IAEhD,OAAO,CAAC,EAAE,CAAC,IAAW,EAAE,OAAc,CAAC,CAAA;AACzC,CAAC","sourcesContent":["import Koa from 'koa'\nimport Router from 'koa-router'\n\n/**\n * 부트스트랩 훅 레지스트리 (P1: 타입드 모듈 매니페스트 — 3단계).\n *\n * shell 은 부트스트랩 과정에서 `process` EventEmitter 로 일련의 라이프사이클 이벤트를 emit 하고,\n * 각 모듈은 이를 listen 해 라우터/미들웨어/구독을 등록한다. 이 파일은 그 문자열 이벤트명과\n * 페이로드를 한곳에서 타입으로 고정한다.\n *\n * 원칙(하위호환):\n * - 내부는 여전히 동일한 `process.emit/on` 을 사용한다 → 기존 136개 모듈의\n * `process.on('bootstrap-module-*', ...)` 는 그대로 동작한다(무변경).\n * - shell 의 emit 측을 `emitHook` 으로 전환해 이벤트명 오타·페이로드 시그니처를 컴파일 체크한다.\n * - 모듈은 원하면 `onHook` 으로 자발적 전환 가능(강제 아님).\n */\n\n/** 부트스트랩 훅 이름 상수 (오타 방지용 단일 소스). */\nexport const BOOTSTRAP_HOOKS = {\n moduleSubscription: 'bootstrap-module-subscription',\n collectSsoMiddleware: 'bootstrap-collect-sso-middleware',\n globalPublicRoute: 'bootstrap-module-global-public-route',\n globalPrivateRoute: 'bootstrap-module-global-private-route',\n domainPublicRoute: 'bootstrap-module-domain-public-route',\n domainPrivateRoute: 'bootstrap-module-domain-private-route',\n moduleStart: 'bootstrap-module-start',\n clientRebuilt: 'client-rebuilt'\n} as const\n\n/** module-start 훅 페이로드. */\nexport interface BootstrapModuleStartPayload {\n app: Koa\n config: any\n builtSchema: any\n httpServer: any\n}\n\n/**\n * 훅 이벤트명 → emit/on 인자 튜플 매핑.\n * (동적 수집 지점인 middleware/collection 인자는 any 로 둔다.)\n */\nexport interface BootstrapHookArgs {\n 'bootstrap-module-subscription': [app: Koa, subscriptionMiddleware: any]\n 'bootstrap-collect-sso-middleware': [value: null, ssoMiddlewares: any[]]\n 'bootstrap-module-global-public-route': [app: Koa, router: Router]\n 'bootstrap-module-global-private-route': [app: Koa, router: Router]\n 'bootstrap-module-domain-public-route': [app: Koa, router: Router]\n 'bootstrap-module-domain-private-route': [app: Koa, router: Router]\n 'bootstrap-module-start': [payload: BootstrapModuleStartPayload]\n 'client-rebuilt': [app: Koa, outputFileSystem: any]\n}\n\n/** 부트스트랩 훅을 타입 안전하게 emit 한다(내부적으로 process.emit). */\nexport function emitHook<K extends keyof BootstrapHookArgs>(name: K, ...args: BootstrapHookArgs[K]): void {\n ;(process as any).emit(name, ...args)\n}\n\n/** 부트스트랩 훅을 타입 안전하게 구독한다(내부적으로 process.on). 기존 process.on 과 병존. */\nexport function onHook<K extends keyof BootstrapHookArgs>(\n name: K,\n handler: (...args: BootstrapHookArgs[K]) => void\n): void {\n process.on(name as any, handler as any)\n}\n"]}
|
package/dist-server/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './utils/index.js';
|
|
|
5
5
|
export * from './pubsub.js';
|
|
6
6
|
export * from './pubsub-log-transport.js';
|
|
7
7
|
export * from './middlewares/index.js';
|
|
8
|
+
export * from './bootstrap-hooks.js';
|
|
8
9
|
export * from './graphql-local-client.js';
|
|
9
10
|
export * from './service/index.js';
|
|
10
11
|
export * from './typeorm/encrypt-transform.js';
|
package/dist-server/index.js
CHANGED
|
@@ -8,6 +8,7 @@ tslib_1.__exportStar(require("./utils/index.js"), exports);
|
|
|
8
8
|
tslib_1.__exportStar(require("./pubsub.js"), exports);
|
|
9
9
|
tslib_1.__exportStar(require("./pubsub-log-transport.js"), exports);
|
|
10
10
|
tslib_1.__exportStar(require("./middlewares/index.js"), exports);
|
|
11
|
+
tslib_1.__exportStar(require("./bootstrap-hooks.js"), exports);
|
|
11
12
|
tslib_1.__exportStar(require("./graphql-local-client.js"), exports);
|
|
12
13
|
tslib_1.__exportStar(require("./service/index.js"), exports);
|
|
13
14
|
tslib_1.__exportStar(require("./typeorm/encrypt-transform.js"), exports);
|
package/dist-server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;AAAA,gEAAqC;AACrC,4EAAiD;AACjD,qEAA0C;AAC1C,2DAAgC;AAChC,sDAA2B;AAC3B,oEAAyC;AACzC,iEAAsC;AACtC,oEAAyC;AACzC,6DAAkC;AAElC,yEAA8C;AAC9C,8EAAmD;AACnD,uEAA4C;AAC5C,uEAA4C","sourcesContent":["export * from './migrations/index.js'\nexport * from './initializers/naming-strategy.js'\nexport * from './initializers/database.js'\nexport * from './utils/index.js'\nexport * from './pubsub.js'\nexport * from './pubsub-log-transport.js'\nexport * from './middlewares/index.js'\nexport * from './graphql-local-client.js'\nexport * from './service/index.js'\n\nexport * from './typeorm/encrypt-transform.js'\nexport * from './typeorm/encrypt-json-transform.js'\nexport * from './typeorm/json5-transform.js'\nexport * from './typeorm/round-transform.js'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;AAAA,gEAAqC;AACrC,4EAAiD;AACjD,qEAA0C;AAC1C,2DAAgC;AAChC,sDAA2B;AAC3B,oEAAyC;AACzC,iEAAsC;AACtC,+DAAoC;AACpC,oEAAyC;AACzC,6DAAkC;AAElC,yEAA8C;AAC9C,8EAAmD;AACnD,uEAA4C;AAC5C,uEAA4C","sourcesContent":["export * from './migrations/index.js'\nexport * from './initializers/naming-strategy.js'\nexport * from './initializers/database.js'\nexport * from './utils/index.js'\nexport * from './pubsub.js'\nexport * from './pubsub-log-transport.js'\nexport * from './middlewares/index.js'\nexport * from './bootstrap-hooks.js'\nexport * from './graphql-local-client.js'\nexport * from './service/index.js'\n\nexport * from './typeorm/encrypt-transform.js'\nexport * from './typeorm/encrypt-json-transform.js'\nexport * from './typeorm/json5-transform.js'\nexport * from './typeorm/round-transform.js'\n"]}
|
|
@@ -80,7 +80,10 @@ const databaseInitializer = async () => {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
catch (e) {
|
|
83
|
-
|
|
83
|
+
/* DB 는 필수 인프라 — 초기화 실패를 삼키면 'default' DataSource 없이 부팅되어
|
|
84
|
+
이후 모든 요청이 런타임에 터진다(좀비 부팅). 실패를 전파해 즉시 중단(fail-fast)한다. */
|
|
85
|
+
env_1.logger.error('Failed to initialize database', e);
|
|
86
|
+
throw e;
|
|
84
87
|
}
|
|
85
88
|
};
|
|
86
89
|
exports.databaseInitializer = databaseInitializer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../server/initializers/database.ts"],"names":[],"mappings":";;;AAYA,sCAEC;AAOD,sCAEC;AAMD,4CAEC;AAMD,gDAEC;AAOD,sCAEC;;AAhDD,qCAA+F;AAE/F,6CAAoD;AACpD,0EAAsC;AAEtC,MAAM,WAAW,GAAmC,EAAE,CAAA;AAEtD;;;;GAIG;AACH,SAAgB,aAAa,CAAC,IAAa;IACzC,OAAO,WAAW,CAAC,IAAI,IAAI,SAAS,CAAC,CAAA;AACvC,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAC,IAAY,EAAE,UAAsB;IAChE,WAAW,CAAC,IAAI,CAAC,GAAG,UAAU,CAAA;AAChC,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,OAAO,WAAW,CAAC,IAAI,CAAC,CAAA;AAC1B,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAI,MAAuB,EAAE,EAAkB;IAC1E,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAI,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,aAAa,CAAI,MAAM,CAAC,CAAA;AAC7F,CAAC;AAED;;GAEG;AACI,MAAM,mBAAmB,GAAG,KAAK,IAAI,EAAE;IAC5C,IAAI,CAAC;QACH,MAAM,oBAAoB,GAAG,YAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAEpD,MAAM,UAAU,GAAG,MAAM,IAAA,0BAAgB,EAAC;YACxC,GAAG,sBAAS;YACZ,GAAG,oBAAoB;SACxB,CAAC,CAAA;QAEF,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;QAEpC,YAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;QAE7C,IAAI,oBAAoB,CAAC,IAAI,IAAI,QAAQ,IAAI,oBAAoB,CAAC,WAAW,IAAI,KAAK,EAAE,CAAC;YACvF,MAAM,UAAU,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAA;YACjD,MAAM,UAAU,CAAC,WAAW,EAAE,CAAA;YAC9B,MAAM,UAAU,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;QAClD,CAAC;QAED,IAAI,YAAM,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,MAAM,aAAa,GAAG,IAAI,oBAAU,CAAC;gBACnC,GAAG,sBAAS;gBACZ,GAAG,YAAM,CAAC,GAAG,CAAC,cAAc,CAAC;aAC9B,CAAC,CAAA;YACF,MAAM,aAAa,CAAC,UAAU,EAAE,CAAA;YAChC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YAElC,YAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAA;QACnD,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,YAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../server/initializers/database.ts"],"names":[],"mappings":";;;AAYA,sCAEC;AAOD,sCAEC;AAMD,4CAEC;AAMD,gDAEC;AAOD,sCAEC;;AAhDD,qCAA+F;AAE/F,6CAAoD;AACpD,0EAAsC;AAEtC,MAAM,WAAW,GAAmC,EAAE,CAAA;AAEtD;;;;GAIG;AACH,SAAgB,aAAa,CAAC,IAAa;IACzC,OAAO,WAAW,CAAC,IAAI,IAAI,SAAS,CAAC,CAAA;AACvC,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAC,IAAY,EAAE,UAAsB;IAChE,WAAW,CAAC,IAAI,CAAC,GAAG,UAAU,CAAA;AAChC,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,OAAO,WAAW,CAAC,IAAI,CAAC,CAAA;AAC1B,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAI,MAAuB,EAAE,EAAkB;IAC1E,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAI,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,aAAa,CAAI,MAAM,CAAC,CAAA;AAC7F,CAAC;AAED;;GAEG;AACI,MAAM,mBAAmB,GAAG,KAAK,IAAI,EAAE;IAC5C,IAAI,CAAC;QACH,MAAM,oBAAoB,GAAG,YAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAEpD,MAAM,UAAU,GAAG,MAAM,IAAA,0BAAgB,EAAC;YACxC,GAAG,sBAAS;YACZ,GAAG,oBAAoB;SACxB,CAAC,CAAA;QAEF,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;QAEpC,YAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;QAE7C,IAAI,oBAAoB,CAAC,IAAI,IAAI,QAAQ,IAAI,oBAAoB,CAAC,WAAW,IAAI,KAAK,EAAE,CAAC;YACvF,MAAM,UAAU,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAA;YACjD,MAAM,UAAU,CAAC,WAAW,EAAE,CAAA;YAC9B,MAAM,UAAU,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;QAClD,CAAC;QAED,IAAI,YAAM,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,MAAM,aAAa,GAAG,IAAI,oBAAU,CAAC;gBACnC,GAAG,sBAAS;gBACZ,GAAG,YAAM,CAAC,GAAG,CAAC,cAAc,CAAC;aAC9B,CAAC,CAAA;YACF,MAAM,aAAa,CAAC,UAAU,EAAE,CAAA;YAChC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YAElC,YAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAA;QACnD,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX;oEAC4D;QAC5D,YAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAA;QAChD,MAAM,CAAC,CAAA;IACT,CAAC;AACH,CAAC,CAAA;AArCY,QAAA,mBAAmB,uBAqC/B","sourcesContent":["import { createConnection, DataSource, EntityManager, EntityTarget, Repository } from 'typeorm'\n\nimport { config, logger } from '@things-factory/env'\nimport ormconfig from './ormconfig.js'\n\nconst dataSources: { [name: string]: DataSource } = {}\n\n/**\n * Returns the specified DataSource by name.\n * @param {string} name - The name of the DataSource.\n * @returns {DataSource} - The DataSource with the specified name.\n */\nexport function getDataSource(name?: string): DataSource {\n return dataSources[name || 'default']\n}\n\n/**\n * Adds a new DataSource with the specified name.\n * @param {string} name - The name of the DataSource to add.\n * @param {DataSource} dataSource - The DataSource to add.\n */\nexport function addDataSource(name: string, dataSource: DataSource) {\n dataSources[name] = dataSource\n}\n\n/**\n * Removes a DataSource with the specified name.\n * @param {string} name - The name of the DataSource to remove.\n */\nexport function removeDataSource(name: string) {\n delete dataSources[name]\n}\n\n/**\n * Returns an array of all registered DataSource names.\n * @returns {string[]} - An array of DataSource names.\n */\nexport function getDataSourceNames() {\n return Object.keys(dataSources)\n}\n\n/**\n * Returns a repository for the specified entity.\n * @param {EntityTarget<X>} target - The target entity for which to get the repository.\n * @returns {Repository<X>} - The repository for the specified entity.\n */\nexport function getRepository<X>(target: EntityTarget<X>, tx?: EntityManager): Repository<X> {\n return tx ? tx.getRepository<X>(target) : getDataSource('default').getRepository<X>(target)\n}\n\n/**\n * Initializes the database connections and data sources.\n */\nexport const databaseInitializer = async () => {\n try {\n const readConnectionConfig = config.get('ormconfig')\n\n const dataSource = await createConnection({\n ...ormconfig,\n ...readConnectionConfig\n })\n\n addDataSource('default', dataSource)\n\n logger.info('Default DataSource established')\n\n if (readConnectionConfig.type == 'sqlite' && readConnectionConfig.synchronize == false) {\n await dataSource.query('PRAGMA foreign_keys=OFF')\n await dataSource.synchronize()\n await dataSource.query('PRAGMA foreign_keys=ON')\n }\n\n if (config.get('ormconfig4Tx')) {\n const dataSource4Tx = new DataSource({\n ...ormconfig,\n ...config.get('ormconfig4Tx')\n })\n await dataSource4Tx.initialize()\n addDataSource('tx', dataSource4Tx)\n\n logger.info('Transaction DataSource established')\n } else {\n addDataSource('tx', dataSource)\n }\n } catch (e) {\n /* DB 는 필수 인프라 — 초기화 실패를 삼키면 'default' DataSource 없이 부팅되어\n 이후 모든 요청이 런타임에 터진다(좀비 부팅). 실패를 전파해 즉시 중단(fail-fast)한다. */\n logger.error('Failed to initialize database', e)\n throw e\n }\n}\n"]}
|
|
@@ -31,6 +31,7 @@ const env_1 = require("@things-factory/env");
|
|
|
31
31
|
const operato_license_checker_1 = require("@things-factory/operato-license-checker");
|
|
32
32
|
const graphql_local_client_js_1 = require("./graphql-local-client.js");
|
|
33
33
|
const database_js_1 = require("./initializers/database.js");
|
|
34
|
+
const bootstrap_hooks_js_1 = require("./bootstrap-hooks.js");
|
|
34
35
|
const index_js_1 = require("./routers/index.js");
|
|
35
36
|
const schema_js_1 = require("./schema.js");
|
|
36
37
|
const domain_middleware_js_1 = require("./middlewares/domain-middleware.js");
|
|
@@ -86,7 +87,7 @@ const bootstrap = async () => {
|
|
|
86
87
|
await next();
|
|
87
88
|
});
|
|
88
89
|
var subscriptionMiddleware = [];
|
|
89
|
-
|
|
90
|
+
(0, bootstrap_hooks_js_1.emitHook)('bootstrap-module-subscription', app, subscriptionMiddleware);
|
|
90
91
|
const builtSchema = await (0, schema_js_1.schema)();
|
|
91
92
|
const httpServer = (0, http_1.createServer)(app.callback());
|
|
92
93
|
const websocketServer = new ws_2.WebSocketServer({
|
|
@@ -176,8 +177,7 @@ const bootstrap = async () => {
|
|
|
176
177
|
});
|
|
177
178
|
// only for development mode. triggered after webpack compilation is done.
|
|
178
179
|
compiler.hooks.done.tap({ name: 'server-dev' }, stats => {
|
|
179
|
-
;
|
|
180
|
-
process.emit('client-rebuilt', app, compiler.outputFileSystem);
|
|
180
|
+
(0, bootstrap_hooks_js_1.emitHook)('client-rebuilt', app, compiler.outputFileSystem);
|
|
181
181
|
});
|
|
182
182
|
// Skip body parser for proxy paths to allow raw body forwarding
|
|
183
183
|
app.use(async (ctx, next) => {
|
|
@@ -189,12 +189,12 @@ const bootstrap = async () => {
|
|
|
189
189
|
});
|
|
190
190
|
/* routers */
|
|
191
191
|
const ssoMiddlewares = [];
|
|
192
|
-
|
|
192
|
+
(0, bootstrap_hooks_js_1.emitHook)('bootstrap-collect-sso-middleware', null, ssoMiddlewares);
|
|
193
193
|
app.ssoMiddlewares = ssoMiddlewares;
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
(0, bootstrap_hooks_js_1.emitHook)('bootstrap-module-global-public-route', app, index_js_1.globalPublicRouter);
|
|
195
|
+
(0, bootstrap_hooks_js_1.emitHook)('bootstrap-module-global-private-route', app, index_js_1.globalPrivateRouter);
|
|
196
|
+
(0, bootstrap_hooks_js_1.emitHook)('bootstrap-module-domain-public-route', app, index_js_1.domainPublicRouter);
|
|
197
|
+
(0, bootstrap_hooks_js_1.emitHook)('bootstrap-module-domain-private-route', app, index_js_1.domainPrivateRouter);
|
|
198
198
|
app.use(operato_license_checker_1.checkValidity); /* Check the license after most of the context has been built */
|
|
199
199
|
app
|
|
200
200
|
.use(index_js_1.globalPublicRouter.routes())
|
|
@@ -220,8 +220,11 @@ const bootstrap = async () => {
|
|
|
220
220
|
httpServer.listen({ port: PORT }, () => {
|
|
221
221
|
env_1.logger.info(`🚀 Server ready at http://0.0.0.0:${PORT}/graphql`);
|
|
222
222
|
env_1.logger.info(`🚀 Subscriptions ready at ws://0.0.0.0:${PORT}/graphql`);
|
|
223
|
-
|
|
223
|
+
(0, bootstrap_hooks_js_1.emitHook)('bootstrap-module-start', { app, config: env_1.config, builtSchema, httpServer });
|
|
224
224
|
});
|
|
225
225
|
};
|
|
226
|
-
bootstrap()
|
|
226
|
+
bootstrap().catch(error => {
|
|
227
|
+
env_1.logger.error('Failed to bootstrap server', error);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
});
|
|
227
230
|
//# sourceMappingURL=server-dev.js.map
|