c0ckp1t 1.0.17 → 1.0.18
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/Config.mjs +1 -192
- package/components/xjson.vue +28 -2
- package/core/ConfigUtils.mjs +363 -0
- package/core/GlobalStore.mjs +26 -33
- package/core/Island.mjs +26 -0
- package/core/IslandDefault.mjs +25 -0
- package/core/LogoAnimated.vue +204 -0
- package/core/PageFooter.vue +1 -1
- package/core/PageNavigation.vue +9 -15
- package/core/VueUtils.mjs +47 -0
- package/core/pages/Connection.vue +16 -14
- package/core/pages/Connections.vue +1 -1
- package/core/pages/Documentation.vue +2 -1
- package/core/pages/connections/ConfigIsland.vue +8 -0
- package/index-cdn.html +1 -1
- package/index.html +1 -1
- package/package.json +1 -1
- package/core/CoreUtils.mjs +0 -161
package/Config.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {deepMerge, DEFAULTS} from "
|
|
1
|
+
import {deepMerge, DEFAULTS, buildNavTree, buildRoutes, defaultVueComponents} from "ConfigUtils";
|
|
2
2
|
/**
|
|
3
3
|
* Configuration Factory for C0ckp1t Applications
|
|
4
4
|
*
|
|
@@ -20,197 +20,6 @@ import {deepMerge, DEFAULTS} from "CoreUtils";
|
|
|
20
20
|
* isDev: false,
|
|
21
21
|
* });
|
|
22
22
|
*/
|
|
23
|
-
// ________________________________________________________________________________
|
|
24
|
-
// Default Nav Tree Builder
|
|
25
|
-
// ________________________________________________________________________________
|
|
26
|
-
export function buildNavTree(instanceId) {
|
|
27
|
-
return {
|
|
28
|
-
icon: "fa-house",
|
|
29
|
-
depth: 0,
|
|
30
|
-
endpoint: "/",
|
|
31
|
-
isLeaf: false,
|
|
32
|
-
isRoot: true,
|
|
33
|
-
name: "",
|
|
34
|
-
path: [],
|
|
35
|
-
children: [
|
|
36
|
-
{
|
|
37
|
-
depth: 1,
|
|
38
|
-
endpoint: `/${instanceId}/connections`,
|
|
39
|
-
isLeaf: true,
|
|
40
|
-
isRoot: false,
|
|
41
|
-
path: ["connections"],
|
|
42
|
-
name: "Connections",
|
|
43
|
-
children: []
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
depth: 1,
|
|
47
|
-
endpoint: `/${instanceId}/cache`,
|
|
48
|
-
isLeaf: true,
|
|
49
|
-
isRoot: false,
|
|
50
|
-
path: ["cache"],
|
|
51
|
-
name: "Cache",
|
|
52
|
-
children: []
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
icon: "fa-network-wired",
|
|
56
|
-
depth: 1,
|
|
57
|
-
endpoint: `/${instanceId}/traffic`,
|
|
58
|
-
isLeaf: true,
|
|
59
|
-
isRoot: false,
|
|
60
|
-
path: ["traffic"],
|
|
61
|
-
name: "Traffic",
|
|
62
|
-
children: []
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
icon: "fa-bell",
|
|
66
|
-
depth: 1,
|
|
67
|
-
endpoint: `/${instanceId}/notifies`,
|
|
68
|
-
isLeaf: true,
|
|
69
|
-
isRoot: false,
|
|
70
|
-
path: ["notifies"],
|
|
71
|
-
name: "Notifies",
|
|
72
|
-
children: []
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
icon: "fa-info",
|
|
76
|
-
depth: 1,
|
|
77
|
-
endpoint: `/${instanceId}/docs`,
|
|
78
|
-
isLeaf: true,
|
|
79
|
-
isRoot: false,
|
|
80
|
-
path: ["docs"],
|
|
81
|
-
name: "Documentation",
|
|
82
|
-
children: []
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
icon: "fa-info",
|
|
86
|
-
depth: 1,
|
|
87
|
-
endpoint: `/${instanceId}/components`,
|
|
88
|
-
isLeaf: true,
|
|
89
|
-
isRoot: false,
|
|
90
|
-
path: ["components"],
|
|
91
|
-
name: "Components",
|
|
92
|
-
children: [
|
|
93
|
-
{
|
|
94
|
-
icon: "fa-info",
|
|
95
|
-
depth: 2,
|
|
96
|
-
endpoint: `/${instanceId}/components/bootstrap`,
|
|
97
|
-
isLeaf: true,
|
|
98
|
-
isRoot: false,
|
|
99
|
-
path: ["bootstrap"],
|
|
100
|
-
name: "Bootstrap",
|
|
101
|
-
children: []
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
icon: "fa-info",
|
|
105
|
-
depth: 2,
|
|
106
|
-
endpoint: `/${instanceId}/components/basic`,
|
|
107
|
-
isLeaf: true,
|
|
108
|
-
isRoot: false,
|
|
109
|
-
path: ["basic"],
|
|
110
|
-
name: "Basic",
|
|
111
|
-
children: []
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
icon: "fa-info",
|
|
115
|
-
depth: 2,
|
|
116
|
-
endpoint: `/${instanceId}/components/advanced`,
|
|
117
|
-
isLeaf: true,
|
|
118
|
-
isRoot: false,
|
|
119
|
-
path: ["advanced"],
|
|
120
|
-
name: "Advanced",
|
|
121
|
-
children: []
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
icon: "fa-info",
|
|
125
|
-
depth: 2,
|
|
126
|
-
endpoint: `/${instanceId}/components/theme`,
|
|
127
|
-
isLeaf: true,
|
|
128
|
-
isRoot: false,
|
|
129
|
-
path: ["theme"],
|
|
130
|
-
name: "Theme",
|
|
131
|
-
children: []
|
|
132
|
-
},
|
|
133
|
-
]
|
|
134
|
-
}
|
|
135
|
-
]
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// ________________________________________________________________________________
|
|
140
|
-
// Routes Builder
|
|
141
|
-
// ________________________________________________________________________________
|
|
142
|
-
export function buildRoutes(instanceId = "default", prefix = "") {
|
|
143
|
-
return [
|
|
144
|
-
{ path: '/', name: 'root', children: [
|
|
145
|
-
{path: '', redirect: `/${instanceId}/docs/Introduction.md`},
|
|
146
|
-
{path: `${instanceId}`, children: [
|
|
147
|
-
{path: 'docs', redirect: `/${instanceId}/docs/Introduction.md`},
|
|
148
|
-
{path: 'docs/:pathMatch(.*)*', location: `${prefix}/core/pages/Documentation.vue`},
|
|
149
|
-
{path: 'connections', location: `${prefix}/core/pages/Connections.vue`},
|
|
150
|
-
{path: 'connections/:id', location: `${prefix}/core/pages/Connection.vue`},
|
|
151
|
-
{path: 'cache', location: `${prefix}/core/pages/Cache.vue`},
|
|
152
|
-
{path: 'traffic', location: `${prefix}/core/pages/Traffic.vue`},
|
|
153
|
-
{path: 'notifies', location: `${prefix}/core/pages/Notifies.vue`},
|
|
154
|
-
{path: 'components', location: `${prefix}/core/pages/frontend/Components.vue`, children: [
|
|
155
|
-
{path: 'basic', location: `${prefix}/core/pages/frontend/ComponentsBasic.vue`},
|
|
156
|
-
{path: 'advanced', location: `${prefix}/core/pages/frontend/ComponentsAdv.vue`},
|
|
157
|
-
{path: 'theme', location: `${prefix}/core/pages/frontend/Theme.vue`},
|
|
158
|
-
{path: 'bootstrap', location: `${prefix}/core/pages/frontend/Bootstrap.vue`},
|
|
159
|
-
]},
|
|
160
|
-
]}
|
|
161
|
-
] },
|
|
162
|
-
{ path: '/:pathMatch(.*)*', name: '404', location: `${prefix}/core/Page404.vue` }
|
|
163
|
-
];
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// ________________________________________________________________________________
|
|
167
|
-
// Components
|
|
168
|
-
// ________________________________________________________________________________
|
|
169
|
-
/**
|
|
170
|
-
* Return the default Vue components
|
|
171
|
-
* using sha1 hashes
|
|
172
|
-
* @returns {Object}
|
|
173
|
-
*/
|
|
174
|
-
export function defaultVueComponents(prefix = "") {
|
|
175
|
-
return {
|
|
176
|
-
ExecButton: { path: `${prefix}/components/ExecButton.vue`, hash: `97e3d2ce89808c5a69f41404e1337f743015f0cc` },
|
|
177
|
-
XInput: { path: `${prefix}/components/xinput.vue`, hash: `cd47d7d038316367df6fd7e265aa3625b72a7777` },
|
|
178
|
-
XInput2: { path: `${prefix}/components/xinput2.vue`, hash: `320e52ac991baebded7c2a9f52a4cfc2cde47b55` },
|
|
179
|
-
XLabel: { path: `${prefix}/components/xlabel.vue`, hash: `90a9837aa8e06f1d3a5b7601337afd78a872d181` },
|
|
180
|
-
XDropdown: { path: `${prefix}/components/xdropdown.vue`, hash: `52b29b72fd6512eefccd9caa76e26dd91d9f9f9e` },
|
|
181
|
-
XDropdown2: { path: `${prefix}/components/xdropdown2.vue`, hash: `e7b163eda42fb7e1a6f07b011c423f8f275eb65d` },
|
|
182
|
-
XSection: { path: `${prefix}/components/xsection.vue`, hash: `27285d606f57d13f80156bb11cd34449f88df950` },
|
|
183
|
-
XTableOpen: { path: `${prefix}/components/xtable-open.vue`, hash: `a1b9a4f670817978022a4c596e2e2f89dd4568c2` },
|
|
184
|
-
XCollapse: { path: `${prefix}/components/xcollapse.vue`, hash: `ba1479bd1080a4fa5abdf6c91c7328ae679f78e6` },
|
|
185
|
-
XToggle: { path: `${prefix}/components/xtoggle.vue`, hash: `2f6871d2d3069ac8f35b6bf76de6c2109f42d9d1` },
|
|
186
|
-
XToggle3: { path: `${prefix}/components/xtoggle3.vue`, hash: `61d0464e6ed9983e817eb0cde928dceb7c0fdc75` },
|
|
187
|
-
XCheck: { path: `${prefix}/components/xcheck.vue`, hash: `ee0d6b30600fb41589123f6d66f2791f1332d4f7` },
|
|
188
|
-
XCheckbox: { path: `${prefix}/components/xcheckbox.vue`, hash: `a290c0cbb7bffce83c235dd5a1c98ed9c441a5b0` },
|
|
189
|
-
XTextarea: { path: `${prefix}/components/xtextarea.vue`, hash: `f8bb08419082aa5443630ab07172674b50c7a248` },
|
|
190
|
-
XHidden: { path: `${prefix}/components/xhidden.vue`, hash: `ecb396e12dd894040e715c0854275e4d5016fcb9` },
|
|
191
|
-
XCode: { path: `${prefix}/components/xcode.vue`, hash: `4d9d9165fea0539c9a983fcdffae8dedcfd537ae` },
|
|
192
|
-
XCodeSlot: { path: `${prefix}/components/xcode-slot.vue`, hash: `` },
|
|
193
|
-
XButton: { path: `${prefix}/components/xbutton.vue`, hash: `2e956caa47e46377ea5a809f7438d0fc38be73b9` },
|
|
194
|
-
XTabs: { path: `${prefix}/components/xtabs.vue`, hash: `83dc219106bdc86ae86dcd16cf95ebd7f11bc952` },
|
|
195
|
-
XKv: { path: `${prefix}/components/xkv.vue`, hash: `8951d3a5e3786cfc9c705b13c1f71e3f90dd2552` },
|
|
196
|
-
XNav: { path: `${prefix}/components/xnav.vue`, hash: `8d51c73e5716deed3577652e362c50526ddbe4e1` },
|
|
197
|
-
XMap: { path: `${prefix}/components/xmap.vue`, hash: `daee357d9e2ef96df0166dd7add0339d46a1cc01` },
|
|
198
|
-
XList: { path: `${prefix}/components/xlist.vue`, hash: `217ced04a333238d169c300a721b75f0ddd5e95b` },
|
|
199
|
-
XJson: { path: `${prefix}/components/xjson.vue`, hash: `0a3ef6265b4070b0f002d659776c02756cc1da5a` },
|
|
200
|
-
XCard: { path: `${prefix}/components/xcard.vue`, hash: `de3fbb23ae7b00d4c90a717dd361cb9315e9ded6` },
|
|
201
|
-
XCardH: { path: `${prefix}/components/xcard-h.vue`, hash: `de4d42f1056c5d2b8431f15e6b1180d9f9898ac2` },
|
|
202
|
-
XColor: { path: `${prefix}/components/xcolor.vue`, hash: `9bf9497ff66e213277f17af290c21c0a35752510` },
|
|
203
|
-
"v-ace-editor": { path: `${prefix}/components/vue3-ace-editor.vue`, hash: `70ce4a39152af5cf0f7cb6b1d4fdafc8b6225edc` },
|
|
204
|
-
XMarkdown: { path: `${prefix}/components/xmarkdown.vue`, hash: `15f835547fab8a8c8aad47d72640c8e918a7b9da` },
|
|
205
|
-
XSound: { path: `${prefix}/components/xsound.vue`, hash: `3e8ad4aa3c767f757dd49b99aa6f961547caf970` },
|
|
206
|
-
XUpload: { path: `${prefix}/components/xupload.vue`, hash: `7a872277e0047fca11e950efe08f2bffa670abdb` },
|
|
207
|
-
XTree: { path: `${prefix}/components/xtree.vue`, hash: `3b6534e86996c48ab05072a9b793ecc78d83a0eb` },
|
|
208
|
-
CodeMirror: { path: `${prefix}/components/code-mirror.vue`, hash: `3ce1028adb75831e01c4264d5764c14f60a1bd00` },
|
|
209
|
-
XTerminal: { path: `${prefix}/components/xterminal.vue`, hash: `1c01f92c0a08bd4937f9768a1d49f12a9a84feea` },
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
23
|
// ________________________________________________________________________________
|
|
215
24
|
// Factory
|
|
216
25
|
// ________________________________________________________________________________
|
package/components/xjson.vue
CHANGED
|
@@ -20,6 +20,32 @@ const emit = defineEmits(['select'])
|
|
|
20
20
|
|
|
21
21
|
const id = `json${Math.floor(Math.random() * 100000000)}`
|
|
22
22
|
|
|
23
|
+
// ________________________________________________________________________________
|
|
24
|
+
// SANITIZE - deep-clean objects for json-viewer (handles undefined, functions,
|
|
25
|
+
// circular refs, symbols, and Vue reactive proxies)
|
|
26
|
+
// ________________________________________________________________________________
|
|
27
|
+
function sanitize(obj, seen = new WeakSet()) {
|
|
28
|
+
if (obj === undefined) return null
|
|
29
|
+
if (obj === null) return null
|
|
30
|
+
if (typeof obj === 'function') return `[Function: ${obj.name || 'anonymous'}]`
|
|
31
|
+
if (typeof obj === 'symbol') return obj.toString()
|
|
32
|
+
if (typeof obj !== 'object') return obj
|
|
33
|
+
|
|
34
|
+
// Handle circular references
|
|
35
|
+
if (seen.has(obj)) return '[Circular]'
|
|
36
|
+
seen.add(obj)
|
|
37
|
+
|
|
38
|
+
if (Array.isArray(obj)) {
|
|
39
|
+
return obj.map(item => sanitize(item, seen))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const result = {}
|
|
43
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
44
|
+
result[key] = sanitize(value, seen)
|
|
45
|
+
}
|
|
46
|
+
return result
|
|
47
|
+
}
|
|
48
|
+
|
|
23
49
|
// ________________________________________________________________________________
|
|
24
50
|
// LOCAL STATE
|
|
25
51
|
// ________________________________________________________________________________
|
|
@@ -33,7 +59,7 @@ watch(
|
|
|
33
59
|
() => props.obj,
|
|
34
60
|
(curr, prev) => {
|
|
35
61
|
// console.log(`json watch triggered`)
|
|
36
|
-
local.el.data =
|
|
62
|
+
local.el.data = sanitize(curr)
|
|
37
63
|
},
|
|
38
64
|
{ deep: true }
|
|
39
65
|
)
|
|
@@ -66,7 +92,7 @@ function toggleExpand() {
|
|
|
66
92
|
async function init() {
|
|
67
93
|
// document.querySelector('#json').data = { prop1: true, prop2: 'test' };
|
|
68
94
|
local.el = markRaw(document.querySelector(`#${id}`))
|
|
69
|
-
local.el.data = props.obj
|
|
95
|
+
local.el.data = sanitize(props.obj)
|
|
70
96
|
if (local.isExpanded) {
|
|
71
97
|
setTimeout(() => {
|
|
72
98
|
expandAll()
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
// ________________________________________________________________________________
|
|
2
|
+
// Application Configuration
|
|
3
|
+
// ________________________________________________________________________________
|
|
4
|
+
export const DEFAULTS = {
|
|
5
|
+
isDev: true,
|
|
6
|
+
/**
|
|
7
|
+
* XMLHttpRequest from a different domain cannot set cookie values for their own
|
|
8
|
+
* domain unless withCredentials is set to true before making the request.
|
|
9
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredential/
|
|
10
|
+
*
|
|
11
|
+
* `true` tells the browser “this cross-origin request should include credentials”,
|
|
12
|
+
* meaning: - send cookies (and HTTP auth) *with* the request, and
|
|
13
|
+
* allow the browser to store cookies from the response, *if* the server also opts in.
|
|
14
|
+
*/
|
|
15
|
+
WITH_CREDENTIALS: false,
|
|
16
|
+
|
|
17
|
+
// ________________________________________________________________________________
|
|
18
|
+
// Island Configuration
|
|
19
|
+
// ________________________________________________________________________________
|
|
20
|
+
defaultInstanceId: "default",
|
|
21
|
+
instanceId: "default",
|
|
22
|
+
type: "IslandDefault",
|
|
23
|
+
|
|
24
|
+
// Main entry point
|
|
25
|
+
appMainComponent: "/core/PageMain.vue",
|
|
26
|
+
// Used for requestion app components and files (GlobalStore.appEndpoint)
|
|
27
|
+
appEndpoint: "",
|
|
28
|
+
|
|
29
|
+
showSidebar: false,
|
|
30
|
+
// ________________________________________________________________________________
|
|
31
|
+
// Components Configuration
|
|
32
|
+
// ________________________________________________________________________________
|
|
33
|
+
componentsDefaultExpand: true,
|
|
34
|
+
// Used for default components prefix (used only in config)
|
|
35
|
+
componentPrefix: "",
|
|
36
|
+
|
|
37
|
+
// ________________________________________________________________________________
|
|
38
|
+
// Nav Configuration
|
|
39
|
+
// ________________________________________________________________________________
|
|
40
|
+
appName: "C0ckp1t Application",
|
|
41
|
+
showTopNavBar: true,
|
|
42
|
+
navItems: [],
|
|
43
|
+
navHasSearch: false,
|
|
44
|
+
navHasThemeSel: false,
|
|
45
|
+
|
|
46
|
+
// ________________________________________________________________________________
|
|
47
|
+
// Footer Configuration
|
|
48
|
+
// ________________________________________________________________________________
|
|
49
|
+
showFooter: true,
|
|
50
|
+
|
|
51
|
+
// ________________________________________________________________________________
|
|
52
|
+
// Documentation Configuration
|
|
53
|
+
// ________________________________________________________________________________
|
|
54
|
+
showDocNav: true,
|
|
55
|
+
showDocReload: true,
|
|
56
|
+
showDocTrail: false,
|
|
57
|
+
allowDocWrite: true,
|
|
58
|
+
allowDocReload: true,
|
|
59
|
+
|
|
60
|
+
// ________________________________________________________________________________
|
|
61
|
+
// Router Configuration
|
|
62
|
+
// ________________________________________________________________________________
|
|
63
|
+
// Determine if VueRouter is createWebHashHistory or createWebHistory
|
|
64
|
+
vueRouterModeIsHash: true,
|
|
65
|
+
// Used for default routes prefix (used only in config)
|
|
66
|
+
routePrefix: "",
|
|
67
|
+
|
|
68
|
+
// ________________________________________________________________________________
|
|
69
|
+
// Logger Config (see Logging.mjs)
|
|
70
|
+
// ________________________________________________________________________________
|
|
71
|
+
defaultLogLevel: "INFO",
|
|
72
|
+
defaultLoggerLevels: {
|
|
73
|
+
"GlobalStore.mjs": "INFO",
|
|
74
|
+
"VueUtils.mjs": "INFO",
|
|
75
|
+
"Connection.mjs": "INFO",
|
|
76
|
+
"default": "INFO",
|
|
77
|
+
"anonymous": "INFO",
|
|
78
|
+
"demo": "INFO"
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
// ________________________________________________________________________________
|
|
82
|
+
// Theming Configuration
|
|
83
|
+
// ________________________________________________________________________________
|
|
84
|
+
bootswatchURL: "https://cdn.jsdelivr.net/npm/bootswatch@5.3.8/dist",
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// ________________________________________________________________________________
|
|
88
|
+
// Default Nav Tree
|
|
89
|
+
// ________________________________________________________________________________
|
|
90
|
+
export function buildNavTree(instanceId) {
|
|
91
|
+
return {
|
|
92
|
+
icon: "fa-house",
|
|
93
|
+
depth: 0,
|
|
94
|
+
endpoint: "/",
|
|
95
|
+
isLeaf: false,
|
|
96
|
+
isRoot: true,
|
|
97
|
+
name: "",
|
|
98
|
+
path: [],
|
|
99
|
+
children: [
|
|
100
|
+
{
|
|
101
|
+
depth: 1,
|
|
102
|
+
endpoint: `/${instanceId}/connections`,
|
|
103
|
+
isLeaf: true,
|
|
104
|
+
isRoot: false,
|
|
105
|
+
path: ["connections"],
|
|
106
|
+
name: "Connections",
|
|
107
|
+
children: []
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
depth: 1,
|
|
111
|
+
endpoint: `/${instanceId}/cache`,
|
|
112
|
+
isLeaf: true,
|
|
113
|
+
isRoot: false,
|
|
114
|
+
path: ["cache"],
|
|
115
|
+
name: "Cache",
|
|
116
|
+
children: []
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
icon: "fa-network-wired",
|
|
120
|
+
depth: 1,
|
|
121
|
+
endpoint: `/${instanceId}/traffic`,
|
|
122
|
+
isLeaf: true,
|
|
123
|
+
isRoot: false,
|
|
124
|
+
path: ["traffic"],
|
|
125
|
+
name: "Traffic",
|
|
126
|
+
children: []
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
icon: "fa-bell",
|
|
130
|
+
depth: 1,
|
|
131
|
+
endpoint: `/${instanceId}/notifies`,
|
|
132
|
+
isLeaf: true,
|
|
133
|
+
isRoot: false,
|
|
134
|
+
path: ["notifies"],
|
|
135
|
+
name: "Notifies",
|
|
136
|
+
children: []
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
icon: "fa-info",
|
|
140
|
+
depth: 1,
|
|
141
|
+
endpoint: `/${instanceId}/docs`,
|
|
142
|
+
isLeaf: true,
|
|
143
|
+
isRoot: false,
|
|
144
|
+
path: ["docs"],
|
|
145
|
+
name: "Documentation",
|
|
146
|
+
children: []
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
icon: "fa-info",
|
|
150
|
+
depth: 1,
|
|
151
|
+
endpoint: `/${instanceId}/components`,
|
|
152
|
+
isLeaf: true,
|
|
153
|
+
isRoot: false,
|
|
154
|
+
path: ["components"],
|
|
155
|
+
name: "Components",
|
|
156
|
+
children: [
|
|
157
|
+
{
|
|
158
|
+
icon: "fa-info",
|
|
159
|
+
depth: 2,
|
|
160
|
+
endpoint: `/${instanceId}/components/bootstrap`,
|
|
161
|
+
isLeaf: true,
|
|
162
|
+
isRoot: false,
|
|
163
|
+
path: ["bootstrap"],
|
|
164
|
+
name: "Bootstrap",
|
|
165
|
+
children: []
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
icon: "fa-info",
|
|
169
|
+
depth: 2,
|
|
170
|
+
endpoint: `/${instanceId}/components/basic`,
|
|
171
|
+
isLeaf: true,
|
|
172
|
+
isRoot: false,
|
|
173
|
+
path: ["basic"],
|
|
174
|
+
name: "Basic",
|
|
175
|
+
children: []
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
icon: "fa-info",
|
|
179
|
+
depth: 2,
|
|
180
|
+
endpoint: `/${instanceId}/components/advanced`,
|
|
181
|
+
isLeaf: true,
|
|
182
|
+
isRoot: false,
|
|
183
|
+
path: ["advanced"],
|
|
184
|
+
name: "Advanced",
|
|
185
|
+
children: []
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
icon: "fa-info",
|
|
189
|
+
depth: 2,
|
|
190
|
+
endpoint: `/${instanceId}/components/theme`,
|
|
191
|
+
isLeaf: true,
|
|
192
|
+
isRoot: false,
|
|
193
|
+
path: ["theme"],
|
|
194
|
+
name: "Theme",
|
|
195
|
+
children: []
|
|
196
|
+
},
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ________________________________________________________________________________
|
|
204
|
+
// Default Routes
|
|
205
|
+
// ________________________________________________________________________________
|
|
206
|
+
export function buildRoutes(instanceId = "default", prefix = "") {
|
|
207
|
+
return [
|
|
208
|
+
{ path: '/', name: 'root', children: [
|
|
209
|
+
{path: '', redirect: `/${instanceId}/docs/Introduction.md`},
|
|
210
|
+
{path: `${instanceId}`, children: [
|
|
211
|
+
{path: 'docs', redirect: `/${instanceId}/docs/Introduction.md`},
|
|
212
|
+
{path: 'docs/:pathMatch(.*)*', location: `${prefix}/core/pages/Documentation.vue`},
|
|
213
|
+
{path: 'connections', location: `${prefix}/core/pages/Connections.vue`},
|
|
214
|
+
{path: 'connections/:id', location: `${prefix}/core/pages/Connection.vue`},
|
|
215
|
+
{path: 'cache', location: `${prefix}/core/pages/Cache.vue`},
|
|
216
|
+
{path: 'traffic', location: `${prefix}/core/pages/Traffic.vue`},
|
|
217
|
+
{path: 'notifies', location: `${prefix}/core/pages/Notifies.vue`},
|
|
218
|
+
{path: 'components', location: `${prefix}/core/pages/frontend/Components.vue`, children: [
|
|
219
|
+
{path: 'basic', location: `${prefix}/core/pages/frontend/ComponentsBasic.vue`},
|
|
220
|
+
{path: 'advanced', location: `${prefix}/core/pages/frontend/ComponentsAdv.vue`},
|
|
221
|
+
{path: 'theme', location: `${prefix}/core/pages/frontend/Theme.vue`},
|
|
222
|
+
{path: 'bootstrap', location: `${prefix}/core/pages/frontend/Bootstrap.vue`},
|
|
223
|
+
]},
|
|
224
|
+
]}
|
|
225
|
+
] },
|
|
226
|
+
{ path: '/:pathMatch(.*)*', name: '404', location: `${prefix}/core/Page404.vue` }
|
|
227
|
+
];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ________________________________________________________________________________
|
|
231
|
+
// Components
|
|
232
|
+
// ________________________________________________________________________________
|
|
233
|
+
/**
|
|
234
|
+
* Return the default Vue components
|
|
235
|
+
* using sha1 hashes
|
|
236
|
+
* @returns {Object}
|
|
237
|
+
*/
|
|
238
|
+
export function defaultVueComponents(prefix = "") {
|
|
239
|
+
return {
|
|
240
|
+
ExecButton: { path: `${prefix}/components/ExecButton.vue`, hash: `97e3d2ce89808c5a69f41404e1337f743015f0cc` },
|
|
241
|
+
XInput: { path: `${prefix}/components/xinput.vue`, hash: `cd47d7d038316367df6fd7e265aa3625b72a7777` },
|
|
242
|
+
XInput2: { path: `${prefix}/components/xinput2.vue`, hash: `320e52ac991baebded7c2a9f52a4cfc2cde47b55` },
|
|
243
|
+
XLabel: { path: `${prefix}/components/xlabel.vue`, hash: `90a9837aa8e06f1d3a5b7601337afd78a872d181` },
|
|
244
|
+
XDropdown: { path: `${prefix}/components/xdropdown.vue`, hash: `52b29b72fd6512eefccd9caa76e26dd91d9f9f9e` },
|
|
245
|
+
XDropdown2: { path: `${prefix}/components/xdropdown2.vue`, hash: `e7b163eda42fb7e1a6f07b011c423f8f275eb65d` },
|
|
246
|
+
XSection: { path: `${prefix}/components/xsection.vue`, hash: `27285d606f57d13f80156bb11cd34449f88df950` },
|
|
247
|
+
XTableOpen: { path: `${prefix}/components/xtable-open.vue`, hash: `a1b9a4f670817978022a4c596e2e2f89dd4568c2` },
|
|
248
|
+
XCollapse: { path: `${prefix}/components/xcollapse.vue`, hash: `ba1479bd1080a4fa5abdf6c91c7328ae679f78e6` },
|
|
249
|
+
XToggle: { path: `${prefix}/components/xtoggle.vue`, hash: `2f6871d2d3069ac8f35b6bf76de6c2109f42d9d1` },
|
|
250
|
+
XToggle3: { path: `${prefix}/components/xtoggle3.vue`, hash: `61d0464e6ed9983e817eb0cde928dceb7c0fdc75` },
|
|
251
|
+
XCheck: { path: `${prefix}/components/xcheck.vue`, hash: `ee0d6b30600fb41589123f6d66f2791f1332d4f7` },
|
|
252
|
+
XCheckbox: { path: `${prefix}/components/xcheckbox.vue`, hash: `a290c0cbb7bffce83c235dd5a1c98ed9c441a5b0` },
|
|
253
|
+
XTextarea: { path: `${prefix}/components/xtextarea.vue`, hash: `f8bb08419082aa5443630ab07172674b50c7a248` },
|
|
254
|
+
XHidden: { path: `${prefix}/components/xhidden.vue`, hash: `ecb396e12dd894040e715c0854275e4d5016fcb9` },
|
|
255
|
+
XCode: { path: `${prefix}/components/xcode.vue`, hash: `4d9d9165fea0539c9a983fcdffae8dedcfd537ae` },
|
|
256
|
+
XCodeSlot: { path: `${prefix}/components/xcode-slot.vue`, hash: `` },
|
|
257
|
+
XButton: { path: `${prefix}/components/xbutton.vue`, hash: `2e956caa47e46377ea5a809f7438d0fc38be73b9` },
|
|
258
|
+
XTabs: { path: `${prefix}/components/xtabs.vue`, hash: `83dc219106bdc86ae86dcd16cf95ebd7f11bc952` },
|
|
259
|
+
XKv: { path: `${prefix}/components/xkv.vue`, hash: `8951d3a5e3786cfc9c705b13c1f71e3f90dd2552` },
|
|
260
|
+
XNav: { path: `${prefix}/components/xnav.vue`, hash: `8d51c73e5716deed3577652e362c50526ddbe4e1` },
|
|
261
|
+
XMap: { path: `${prefix}/components/xmap.vue`, hash: `daee357d9e2ef96df0166dd7add0339d46a1cc01` },
|
|
262
|
+
XList: { path: `${prefix}/components/xlist.vue`, hash: `217ced04a333238d169c300a721b75f0ddd5e95b` },
|
|
263
|
+
XJson: { path: `${prefix}/components/xjson.vue`, hash: `0a3ef6265b4070b0f002d659776c02756cc1da5a` },
|
|
264
|
+
XCard: { path: `${prefix}/components/xcard.vue`, hash: `de3fbb23ae7b00d4c90a717dd361cb9315e9ded6` },
|
|
265
|
+
XCardH: { path: `${prefix}/components/xcard-h.vue`, hash: `de4d42f1056c5d2b8431f15e6b1180d9f9898ac2` },
|
|
266
|
+
XColor: { path: `${prefix}/components/xcolor.vue`, hash: `9bf9497ff66e213277f17af290c21c0a35752510` },
|
|
267
|
+
"v-ace-editor": { path: `${prefix}/components/vue3-ace-editor.vue`, hash: `70ce4a39152af5cf0f7cb6b1d4fdafc8b6225edc` },
|
|
268
|
+
XMarkdown: { path: `${prefix}/components/xmarkdown.vue`, hash: `15f835547fab8a8c8aad47d72640c8e918a7b9da` },
|
|
269
|
+
XSound: { path: `${prefix}/components/xsound.vue`, hash: `3e8ad4aa3c767f757dd49b99aa6f961547caf970` },
|
|
270
|
+
XUpload: { path: `${prefix}/components/xupload.vue`, hash: `7a872277e0047fca11e950efe08f2bffa670abdb` },
|
|
271
|
+
XTree: { path: `${prefix}/components/xtree.vue`, hash: `3b6534e86996c48ab05072a9b793ecc78d83a0eb` },
|
|
272
|
+
CodeMirror: { path: `${prefix}/components/code-mirror.vue`, hash: `3ce1028adb75831e01c4264d5764c14f60a1bd00` },
|
|
273
|
+
XTerminal: { path: `${prefix}/components/xterminal.vue`, hash: `1c01f92c0a08bd4937f9768a1d49f12a9a84feea` },
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// ________________________________________________________________________________
|
|
278
|
+
// UTILITY FUNCTIONS
|
|
279
|
+
// ________________________________________________________________________________
|
|
280
|
+
/**
|
|
281
|
+
* Validate and set defaults for the config object.
|
|
282
|
+
* @param config
|
|
283
|
+
* @returns {*}
|
|
284
|
+
*/
|
|
285
|
+
export function validateAppConfig(config) {
|
|
286
|
+
if (!config) {
|
|
287
|
+
throw new Error("config is required")
|
|
288
|
+
}
|
|
289
|
+
if (typeof config !== 'object') {
|
|
290
|
+
throw new Error("Config must be an object must was `" + typeof config + "`")
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Apply all DEFAULTS — fill in any missing properties
|
|
294
|
+
for (const key of Object.keys(DEFAULTS)) {
|
|
295
|
+
if (config[key] === undefined || config[key] === null) {
|
|
296
|
+
config[key] = structuredClone(DEFAULTS[key]);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Special validations (type coercion / empty-string guards)
|
|
301
|
+
if (typeof config.instanceId !== 'string' || config.instanceId.trim() === '') {
|
|
302
|
+
config.instanceId = DEFAULTS.instanceId;
|
|
303
|
+
}
|
|
304
|
+
if (typeof config.type !== 'string' || config.type.trim() === '') {
|
|
305
|
+
config.type = DEFAULTS.type;
|
|
306
|
+
}
|
|
307
|
+
if (!Array.isArray(config.navItems)) {
|
|
308
|
+
config.navItems = DEFAULTS.navItems;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Derived defaults that depend on other config values
|
|
312
|
+
if (!Array.isArray(config.routes) || config.routes.length < 1) {
|
|
313
|
+
config.routes = buildRoutes(config.instanceId, config.routePrefix);
|
|
314
|
+
}
|
|
315
|
+
if (typeof config.components !== 'object' || config.components === null) {
|
|
316
|
+
config.components = defaultVueComponents(config.componentPrefix);
|
|
317
|
+
}
|
|
318
|
+
if (!config.root || typeof config.root !== 'object') {
|
|
319
|
+
config.root = buildNavTree(config.instanceId);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return config
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Use window to extract the hostname, port, protocol, and whether the connection is secure.
|
|
327
|
+
* @returns {{hostname: string, port: string, protocol: string, isSecure: boolean}}
|
|
328
|
+
*/
|
|
329
|
+
export function findHostnamePortProtocol() {
|
|
330
|
+
const hostname = window.location.hostname
|
|
331
|
+
const protocol = window.location.protocol.toLowerCase()
|
|
332
|
+
const isSecure = protocol.toLowerCase() === 'https:'
|
|
333
|
+
const port = window.location.port || (isSecure ? "443" : "80")
|
|
334
|
+
const serverUrl = `${protocol}//${hostname}:${port}`
|
|
335
|
+
return {hostname, port, protocol, isSecure, serverUrl}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Deep merge source into target. Returns a new object.
|
|
340
|
+
* - Objects are recursively merged (source keys override target keys)
|
|
341
|
+
* - Arrays are replaced entirely (source array wins)
|
|
342
|
+
* - Scalars are replaced (source wins)
|
|
343
|
+
*/
|
|
344
|
+
export function deepMerge(target, source) {
|
|
345
|
+
const result = { ...target };
|
|
346
|
+
for (const key of Object.keys(source)) {
|
|
347
|
+
const sourceVal = source[key];
|
|
348
|
+
const targetVal = target[key];
|
|
349
|
+
if (
|
|
350
|
+
sourceVal !== null &&
|
|
351
|
+
typeof sourceVal === 'object' &&
|
|
352
|
+
!Array.isArray(sourceVal) &&
|
|
353
|
+
targetVal !== null &&
|
|
354
|
+
typeof targetVal === 'object' &&
|
|
355
|
+
!Array.isArray(targetVal)
|
|
356
|
+
) {
|
|
357
|
+
result[key] = deepMerge(targetVal, sourceVal);
|
|
358
|
+
} else {
|
|
359
|
+
result[key] = sourceVal;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return result;
|
|
363
|
+
}
|