vite-plugin-files-server 1.0.3 → 1.1.2

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/plugin/index.cjs CHANGED
@@ -27,345 +27,770 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
30
+ // src/v1_1_0_theme/index.ts
31
+ var v1_1_0_theme_exports = {};
32
+ __export(v1_1_0_theme_exports, {
33
33
  default: () => fileServerPlugin
34
34
  });
35
- module.exports = __toCommonJS(index_exports);
35
+ module.exports = __toCommonJS(v1_1_0_theme_exports);
36
36
  var import_fs = __toESM(require("fs"), 1);
37
37
  var import_path = __toESM(require("path"), 1);
38
38
 
39
- // src/temp.html?raw
40
- var temp_default = `<!DOCTYPE html>\r
41
- <html>\r
39
+ // src/v1_1_0_theme/tempFolderDark.html?raw
40
+ var tempFolderDark_default = `<!doctype html>\r
41
+ <html lang="en">\r
42
42
  <head>\r
43
43
  <meta charset="UTF-8" />\r
44
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />\r
45
- <title>listing directory {{url}}</title>\r
44
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />\r
45
+ <title>Demo List {{pageTitle}}</title>\r
46
46
  <style>\r
47
- /* body {\r
48
- font-family: system-ui;\r
49
- padding: 2rem;\r
50
- max-width: 800px;\r
51
- margin: 0 auto;\r
47
+ /* \u6697\u8272\u4E3B\u9898 - \u53EA\u4FEE\u6539\u989C\u8272\uFF0C\u4FDD\u6301\u4E0E\u4EAE\u8272\u4E3B\u9898\u76F8\u540C\u7684\u5E03\u5C40\u548C\u5C3A\u5BF8 */\r
48
+ body {\r
49
+ background-color: #1a1a1a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #1a1a1a */\r
50
+ color: #e0e0e0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #212529 \u2192 \u6697\u8272 #e0e0e0 */\r
51
+ font-family:\r
52
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;\r
53
+ margin: 0;\r
54
+ padding: 20px;\r
55
+ font-size: 14px;\r
56
+ line-height: 1.5;\r
52
57
  }\r
53
- h2 {\r
54
- border-bottom: 1px solid #eee;\r
55
- padding-bottom: 10px;\r
58
+ \r
59
+ /* \u9762\u5305\u5C51\u5BFC\u822A - \u6697\u8272 */\r
60
+ .breadcrumb {\r
61
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
62
+ margin-bottom: 20px;\r
63
+ font-size: 13px;\r
64
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
65
+ padding: 12px 16px;\r
66
+ border-radius: 8px;\r
67
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
68
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
69
+ }\r
70
+ .breadcrumb-link {\r
71
+ color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
72
+ text-decoration: none;\r
73
+ font-weight: 500;\r
74
+ transition: all 0.2s;\r
75
+ padding: 4px 8px;\r
76
+ border-radius: 4px;\r
77
+ }\r
78
+ .breadcrumb-link:hover {\r
79
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e7f1ff \u2192 \u6697\u8272 #3a3a3a */\r
80
+ color: #74c0fc; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0a58ca \u2192 \u6697\u8272 #74c0fc */\r
81
+ text-decoration: none;\r
56
82
  }\r
57
- table {\r
58
- width: 100%;\r
59
- border-collapse: collapse;\r
83
+ \r
84
+ /* \u5185\u5BB9\u533A\u57DF */\r
85
+ .content-area {\r
86
+ margin-top: 20px;\r
60
87
  }\r
61
- td {\r
62
- padding: 8px;\r
63
- border-bottom: 1px solid #f5f5f5;\r
88
+ \r
89
+ /* gallery\u6811\u5F62\u89C6\u56FE - \u6697\u8272 */\r
90
+ .gallery-tree {\r
91
+ font-family: 'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', monospace;\r
92
+ line-height: 1.6;\r
93
+ color: #e0e0e0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #212529 \u2192 \u6697\u8272 #e0e0e0 */\r
64
94
  }\r
65
- a {\r
95
+ \r
96
+ /* \u6587\u4EF6\u5939\u9879 - \u6697\u8272\u4E3B\u9898 */\r
97
+ .folder-item {\r
98
+ cursor: default;\r
99
+ margin: 6px 0;\r
100
+ padding-left: 20px;\r
101
+ position: relative;\r
102
+ }\r
103
+ /* .folder-item:hover {\r
104
+ background-color: #2a2a2a; \r
105
+ } */\r
106
+ .folder-name {\r
107
+ color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
66
108
  text-decoration: none;\r
67
- color: #646cff;\r
109
+ display: inline-block;\r
110
+ padding: 6px 12px;\r
111
+ border-radius: 6px;\r
112
+ font-weight: 500;\r
113
+ background-color: #525252; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e7f1ff \u2192 \u6697\u8272 #2a2a2a */\r
114
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #cfe2ff \u2192 \u6697\u8272 #3a3a3a */\r
115
+ transition: all 0.2s;\r
68
116
  }\r
69
- a:hover {\r
70
- text-decoration: underline;\r
117
+ .folder-name::before {\r
118
+ content: '\u{1F5C2}\uFE0F';\r
119
+ margin-right: 8px;\r
71
120
  }\r
72
- ul,\r
73
- li {\r
74
- list-style: none;\r
75
- margin: 0;\r
76
- padding: 0;\r
77
- } */\r
78
- * {\r
79
- margin: 0;\r
80
- padding: 0;\r
81
- outline: 0;\r
121
+ .level-sub {\r
122
+ background-color: #2a2a2a;\r
123
+ padding: 1px 12px;\r
124
+ }\r
125
+ .level-sub::before {\r
126
+ content: '\u{1F4C1}';\r
127
+ margin-right: 8px;\r
82
128
  }\r
83
129
  \r
84
- body {\r
85
- padding: 80px 100px;\r
86
- font: 13px 'Helvetica Neue', 'Lucida Grande', 'Arial';\r
87
- background: #ece9e9 -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ece9e9));\r
88
- background: #ece9e9 -moz-linear-gradient(top, #fff, #ece9e9);\r
89
- background-repeat: no-repeat;\r
90
- color: #555;\r
91
- -webkit-font-smoothing: antialiased;\r
92
- }\r
93
- h1,\r
94
- h2,\r
95
- h3 {\r
96
- padding-left: 10px;\r
97
- font-size: 22px;\r
98
- color: #343434;\r
99
- }\r
100
- h1 em,\r
101
- h2 em {\r
102
- padding: 0 5px;\r
103
- font-weight: normal;\r
104
- }\r
105
- h1 {\r
106
- font-size: 60px;\r
107
- }\r
108
- h2 {\r
109
- margin-top: 10px;\r
110
- }\r
111
- h3 {\r
112
- margin: 5px 0 10px 0;\r
113
- padding-bottom: 5px;\r
114
- border-bottom: 1px solid #eee;\r
115
- font-size: 18px;\r
116
- }\r
117
- ul li {\r
130
+ /* \u6587\u4EF6\u7F51\u683C\u5E03\u5C40 - \u4E09\u5217 */\r
131
+ .file-grid {\r
132
+ margin: 12px 0 20px 0;\r
133
+ display: block;\r
134
+ }\r
135
+ .file-row {\r
136
+ display: flex;\r
137
+ margin: 8px 0;\r
138
+ }\r
139
+ .file-column {\r
140
+ flex: 1;\r
141
+ min-width: 0;\r
142
+ margin: 0 6px;\r
143
+ padding: 8px 12px;\r
144
+ border-radius: 8px;\r
145
+ transition: all 0.2s;\r
146
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
147
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
148
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
149
+ }\r
150
+ .file-column:hover {\r
151
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #3a3a3a */\r
152
+ transform: translateY(-2px);\r
153
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
154
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
155
+ }\r
156
+ .empty-column {\r
157
+ background-color: transparent;\r
158
+ border: 1px solid transparent;\r
159
+ box-shadow: none;\r
160
+ }\r
161
+ .empty-column:hover {\r
162
+ background-color: transparent;\r
163
+ transform: none;\r
164
+ box-shadow: none;\r
165
+ border-color: transparent;\r
166
+ }\r
167
+ .html-file-link {\r
168
+ color: #e0e0e0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #212529 \u2192 \u6697\u8272 #e0e0e0 */\r
169
+ text-decoration: none;\r
170
+ display: block;\r
171
+ white-space: nowrap;\r
172
+ overflow: hidden;\r
173
+ text-overflow: ellipsis;\r
174
+ padding-left: 24px;\r
175
+ position: relative;\r
176
+ font-size: 13px;\r
177
+ }\r
178
+ .html-file-link:hover {\r
179
+ color: #ffffff; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #ffffff */\r
180
+ }\r
181
+ .html-file-link::before {\r
182
+ content: '\u{1F4C4}';\r
183
+ position: absolute;\r
184
+ left: 0;\r
185
+ top: 0;\r
186
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
187
+ }\r
188
+ \r
189
+ .back-all-link {\r
190
+ font-family:\r
191
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;\r
192
+ }\r
193
+ .back-all-link a {\r
194
+ text-decoration: none;\r
195
+ padding: 10px 16px;\r
196
+ display: block;\r
197
+ border-radius: 8px;\r
198
+ transition: all 0.2s;\r
199
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
200
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
201
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
202
+ }\r
203
+ .back-all-link a:hover {\r
204
+ transform: translateY(-2px);\r
205
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
206
+ }\r
207
+ .back-all-link a.back-link {\r
208
+ color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
209
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
210
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #cfe2ff \u2192 \u6697\u8272 #3a3a3a */\r
211
+ padding-left: 48px;\r
212
+ position: relative;\r
213
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
214
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #2a2a2a */\r
215
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
216
+ }\r
217
+ .back-all-link a.back-link:hover {\r
218
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #3a3a3a */\r
219
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
220
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
221
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #4dabf7 */\r
222
+ }\r
223
+ .back-all-link a.back-link::before {\r
224
+ content: '\u{1F4C1}';\r
225
+ position: absolute;\r
226
+ left: 16px;\r
227
+ top: 50%;\r
228
+ transform: translateY(-50%);\r
229
+ font-size: 16px;\r
230
+ content: '\u2190';\r
231
+ margin-right: 8px;\r
232
+ }\r
233
+ \r
234
+ /* \u6587\u4EF6\u5217\u8868\u89C6\u56FE - \u6697\u8272\u4E3B\u9898 */\r
235
+ .file-list {\r
118
236
  list-style: none;\r
237
+ padding: 0;\r
238
+ margin: 0;\r
119
239
  }\r
120
- ul li:hover {\r
121
- cursor: pointer;\r
122
- color: #2e2e2e;\r
240
+ .file-list li {\r
241
+ margin: 6px 0;\r
123
242
  }\r
124
- ul li .path {\r
125
- padding-left: 5px;\r
126
- font-weight: bold;\r
243
+ .file-list a {\r
244
+ text-decoration: none;\r
245
+ padding: 10px 16px;\r
246
+ display: block;\r
247
+ border-radius: 8px;\r
248
+ transition: all 0.2s;\r
249
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
250
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
251
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
252
+ }\r
253
+ .file-list a:hover {\r
254
+ transform: translateY(-2px);\r
255
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
256
+ }\r
257
+ .file-list a.folder-link {\r
258
+ color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
259
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
260
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #cfe2ff \u2192 \u6697\u8272 #3a3a3a */\r
261
+ padding-left: 48px;\r
262
+ position: relative;\r
263
+ }\r
264
+ .file-list a.folder-link:hover {\r
265
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #3a3a3a */\r
266
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
267
+ }\r
268
+ .file-list a.folder-link::before {\r
269
+ content: '\u{1F4C1}';\r
270
+ position: absolute;\r
271
+ left: 16px;\r
272
+ top: 50%;\r
273
+ transform: translateY(-50%);\r
274
+ font-size: 16px;\r
275
+ }\r
276
+ .file-list a.back-link {\r
277
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
278
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #2a2a2a */\r
279
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
280
+ }\r
281
+ .file-list a.back-link:hover {\r
282
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
283
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #4dabf7 */\r
284
+ }\r
285
+ .file-list a.back-link::before {\r
286
+ content: '\u2190';\r
287
+ margin-right: 8px;\r
288
+ }\r
289
+ .file-list a.file-link {\r
290
+ color: #e0e0e0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #212529 \u2192 \u6697\u8272 #e0e0e0 */\r
291
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
292
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
293
+ padding-left: 48px;\r
294
+ position: relative;\r
295
+ }\r
296
+ .file-list a.file-link:hover {\r
297
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #3a3a3a */\r
298
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
299
+ }\r
300
+ .file-list a.file-link::before {\r
301
+ content: '\u{1F4C4}';\r
302
+ position: absolute;\r
303
+ left: 16px;\r
304
+ top: 50%;\r
305
+ transform: translateY(-50%);\r
306
+ font-size: 16px;\r
307
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
127
308
  }\r
128
- ul li .line {\r
129
- padding-right: 5px;\r
309
+ \r
310
+ /* \u7A7A\u72B6\u6001 - \u6697\u8272 */\r
311
+ .empty-message {\r
312
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
130
313
  font-style: italic;\r
314
+ text-align: center;\r
315
+ padding: 32px;\r
316
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
317
+ border-radius: 8px;\r
318
+ border: 1px dashed #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
319
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
131
320
  }\r
132
- ul li:first-child .path {\r
133
- padding-left: 0;\r
321
+ \r
322
+ /* \u54CD\u5E94\u5F0F\u8BBE\u8BA1 */\r
323
+ @media (max-width: 768px) {\r
324
+ body {\r
325
+ padding: 12px;\r
326
+ }\r
327
+ .file-row {\r
328
+ flex-direction: column;\r
329
+ }\r
330
+ .file-column {\r
331
+ margin: 4px 0;\r
332
+ }\r
134
333
  }\r
135
- p {\r
334
+ </style>\r
335
+ </head>\r
336
+ <body>\r
337
+ <div class="breadcrumb">{{breadcrumb}}</div>\r
338
+ <div class="content-area">{{list}}</div>\r
339
+ </body>\r
340
+ </html>\r
341
+ `;
342
+
343
+ // src/v1_1_0_theme/tempFolderLight.html?raw
344
+ var tempFolderLight_default = `<!doctype html>\r
345
+ <html lang="en">\r
346
+ <head>\r
347
+ <meta charset="UTF-8" />\r
348
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />\r
349
+ <title>Demo List {{pageTitle}}</title>\r
350
+ <style>\r
351
+ /* \u4EAE\u8272\u4E3B\u9898 - \u6574\u4F53\u660E\u4EAE\u98CE\u683C */\r
352
+ body {\r
353
+ background-color: #f8f9fa;\r
354
+ color: #212529;\r
355
+ font-family:\r
356
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;\r
357
+ margin: 0;\r
358
+ padding: 20px;\r
359
+ font-size: 14px;\r
136
360
  line-height: 1.5;\r
137
361
  }\r
138
- a {\r
139
- color: #555;\r
362
+ \r
363
+ /* \u9762\u5305\u5C51\u5BFC\u822A - \u4EAE\u8272 */\r
364
+ .breadcrumb {\r
365
+ color: #6c757d;\r
366
+ margin-bottom: 20px;\r
367
+ font-size: 13px;\r
368
+ background-color: #ffffff;\r
369
+ padding: 12px 16px;\r
370
+ border-radius: 8px;\r
371
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
372
+ border: 1px solid #e9ecef;\r
373
+ }\r
374
+ .breadcrumb-link {\r
375
+ color: #0d6efd;\r
376
+ text-decoration: none;\r
377
+ font-weight: 500;\r
378
+ transition: all 0.2s;\r
379
+ padding: 4px 8px;\r
380
+ border-radius: 4px;\r
381
+ }\r
382
+ .breadcrumb-link:hover {\r
383
+ background-color: #e7f1ff;\r
384
+ color: #0a58ca;\r
140
385
  text-decoration: none;\r
141
386
  }\r
142
- a:hover {\r
143
- color: #303030;\r
387
+ \r
388
+ /* \u5185\u5BB9\u533A\u57DF */\r
389
+ .content-area {\r
390
+ margin-top: 20px;\r
144
391
  }\r
145
- #stacktrace {\r
146
- margin-top: 15px;\r
392
+ \r
393
+ /* gallery\u6811\u5F62\u89C6\u56FE - \u4EAE\u8272 */\r
394
+ .gallery-tree {\r
395
+ font-family: 'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', monospace;\r
396
+ line-height: 1.6;\r
397
+ color: #212529;\r
147
398
  }\r
148
- .directory h1 {\r
149
- margin-bottom: 15px;\r
150
- font-size: 18px;\r
399
+ \r
400
+ /* \u6587\u4EF6\u5939\u9879 - \u4EAE\u8272\u4E3B\u9898 */\r
401
+ .folder-item {\r
402
+ cursor: default;\r
403
+ margin: 6px 0;\r
404
+ padding-left: 20px;\r
405
+ position: relative;\r
406
+ }\r
407
+ .folder-item:hover {\r
408
+ background-color: #f8f9fa;\r
409
+ }\r
410
+ .folder-name {\r
411
+ color: #0d6efd;\r
412
+ text-decoration: none;\r
413
+ display: inline-block;\r
414
+ padding: 6px 12px;\r
415
+ border-radius: 6px;\r
416
+ font-weight: 500;\r
417
+ background-color: #a8ccff;\r
418
+ border: 1px solid #cfe2ff;\r
419
+ transition: all 0.2s;\r
151
420
  }\r
152
- ul#files {\r
153
- width: 100%;\r
154
- height: 100%;\r
155
- overflow: hidden;\r
421
+ .folder-name::before {\r
422
+ content: '\u{1F5C2}\uFE0F';\r
423
+ margin-right: 8px;\r
424
+ }\r
425
+ .level-sub {\r
426
+ background-color: #e7f1ff;\r
427
+ padding: 1px 12px;\r
156
428
  }\r
157
- ul#files li {\r
158
- float: left;\r
159
- width: 30%;\r
160
- line-height: 25px;\r
161
- margin: 1px;\r
429
+ .level-sub::before {\r
430
+ content: '\u{1F4C1}';\r
431
+ margin-right: 8px;\r
162
432
  }\r
163
- ul#files li a {\r
433
+ \r
434
+ /* \u6587\u4EF6\u7F51\u683C\u5E03\u5C40 - \u4E09\u5217 */\r
435
+ .file-grid {\r
436
+ margin: 12px 0 20px 0;\r
164
437
  display: block;\r
165
- height: 25px;\r
166
- border: 1px solid transparent;\r
167
- -webkit-border-radius: 5px;\r
168
- -moz-border-radius: 5px;\r
169
- border-radius: 5px;\r
170
- overflow: hidden;\r
171
- white-space: nowrap;\r
172
438
  }\r
173
- ul#files li a:focus,\r
174
- ul#files li a:hover {\r
175
- background: rgba(255, 255, 255, 0.65);\r
176
- border: 1px solid #ececec;\r
439
+ .file-row {\r
440
+ display: flex;\r
441
+ margin: 8px 0;\r
442
+ }\r
443
+ .file-column {\r
444
+ flex: 1;\r
445
+ min-width: 0;\r
446
+ margin: 0 6px;\r
447
+ padding: 8px 12px;\r
448
+ border-radius: 8px;\r
449
+ transition: all 0.2s;\r
450
+ background-color: #ffffff;\r
451
+ border: 1px solid #dee2e6;\r
452
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
453
+ }\r
454
+ .file-column:hover {\r
455
+ background-color: #f8f9fa;\r
456
+ transform: translateY(-2px);\r
457
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\r
458
+ border-color: #0d6efd;\r
459
+ }\r
460
+ .empty-column {\r
461
+ background-color: transparent;\r
462
+ border: 1px solid transparent;\r
463
+ box-shadow: none;\r
177
464
  }\r
178
- ul#files li a.highlight {\r
179
- -webkit-transition: background 0.4s ease-in-out;\r
180
- background: #ffff4f;\r
181
- border-color: #e9dc51;\r
465
+ .empty-column:hover {\r
466
+ background-color: transparent;\r
467
+ transform: none;\r
468
+ box-shadow: none;\r
469
+ border-color: transparent;\r
182
470
  }\r
183
- #search {\r
471
+ .html-file-link {\r
472
+ color: #212529;\r
473
+ text-decoration: none;\r
184
474
  display: block;\r
185
- position: fixed;\r
186
- top: 20px;\r
187
- right: 20px;\r
188
- width: 90px;\r
189
- -webkit-transition: width ease 0.2s, opacity ease 0.4s;\r
190
- -moz-transition: width ease 0.2s, opacity ease 0.4s;\r
191
- -webkit-border-radius: 32px;\r
192
- -moz-border-radius: 32px;\r
193
- -webkit-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7),\r
194
- 0px 1px 0px rgba(255, 255, 255, 0.03);\r
195
- -moz-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7),\r
196
- 0px 1px 0px rgba(255, 255, 255, 0.03);\r
197
- -webkit-font-smoothing: antialiased;\r
198
- text-align: left;\r
199
- font: 13px 'Helvetica Neue', Arial, sans-serif;\r
200
- padding: 4px 10px;\r
201
- border: none;\r
202
- background: transparent;\r
203
- margin-bottom: 0;\r
204
- outline: none;\r
205
- opacity: 0.7;\r
206
- color: #888;\r
207
- }\r
208
- #search:focus {\r
209
- width: 120px;\r
210
- opacity: 1;\r
211
- }\r
212
- \r
213
- /*views*/\r
214
- #files span {\r
215
- display: inline-block;\r
475
+ white-space: nowrap;\r
216
476
  overflow: hidden;\r
217
477
  text-overflow: ellipsis;\r
218
- text-indent: 10px;\r
478
+ padding-left: 24px;\r
479
+ position: relative;\r
480
+ font-size: 13px;\r
219
481
  }\r
220
- #files .name {\r
221
- background-repeat: no-repeat;\r
482
+ .html-file-link:hover {\r
483
+ color: #0d6efd;\r
222
484
  }\r
223
- #files .icon .name {\r
224
- text-indent: 28px;\r
485
+ .html-file-link::before {\r
486
+ content: '\u{1F4C4}';\r
487
+ position: absolute;\r
488
+ left: 0;\r
489
+ top: 0;\r
490
+ color: #6c757d;\r
225
491
  }\r
226
492
  \r
227
- /*tiles*/\r
228
- .view-tiles .name {\r
229
- width: 100%;\r
230
- background-position: 8px 5px;\r
493
+ .back-all-link {\r
494
+ font-family:\r
495
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;\r
231
496
  }\r
232
- .view-tiles .size,\r
233
- .view-tiles .date {\r
234
- display: none;\r
235
- }\r
236
- \r
237
- /*details*/\r
238
- ul#files.view-details li {\r
239
- float: none;\r
497
+ .back-all-link a {\r
498
+ text-decoration: none;\r
499
+ padding: 10px 16px;\r
240
500
  display: block;\r
241
- width: 90%;\r
242
- }\r
243
- ul#files.view-details li.header {\r
244
- height: 25px;\r
245
- background: #000;\r
246
- color: #fff;\r
247
- font-weight: bold;\r
501
+ border-radius: 8px;\r
502
+ transition: all 0.2s;\r
503
+ background-color: #ffffff;\r
504
+ border: 1px solid #dee2e6;\r
505
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
506
+ }\r
507
+ .back-all-link a:hover {\r
508
+ transform: translateY(-2px);\r
509
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\r
510
+ }\r
511
+ .back-all-link a.back-link {\r
512
+ color: #0d6efd;\r
513
+ background-color: #ffffff;\r
514
+ border: 1px solid #cfe2ff;\r
515
+ padding-left: 48px;\r
516
+ position: relative;\r
517
+ color: #6c757d;\r
518
+ background-color: #f8f9fa;\r
519
+ border: 1px solid #e9ecef;\r
520
+ }\r
521
+ .back-all-link a.back-link:hover {\r
522
+ background-color: #e9ecef;\r
523
+ border-color: #dee2e6;\r
524
+ background-color: #f8f9fa;\r
525
+ border-color: #0d6efd;\r
526
+ }\r
527
+ .back-all-link a.back-link::before {\r
528
+ content: '\u{1F4C1}';\r
529
+ position: absolute;\r
530
+ left: 16px;\r
531
+ top: 50%;\r
532
+ transform: translateY(-50%);\r
533
+ font-size: 16px;\r
534
+ content: '\u2190';\r
535
+ margin-right: 8px;\r
248
536
  }\r
249
- .view-details .header {\r
250
- border-radius: 5px;\r
251
- }\r
252
- .view-details .name {\r
253
- width: 60%;\r
254
- background-position: 8px 5px;\r
537
+ \r
538
+ /* \u6587\u4EF6\u5217\u8868\u89C6\u56FE - \u4EAE\u8272\u4E3B\u9898 */\r
539
+ .file-list {\r
540
+ list-style: none;\r
541
+ padding: 0;\r
542
+ margin: 0;\r
255
543
  }\r
256
- .view-details .size {\r
257
- width: 10%;\r
544
+ .file-list li {\r
545
+ margin: 6px 0;\r
258
546
  }\r
259
- .view-details .date {\r
260
- width: 30%;\r
547
+ .file-list a {\r
548
+ text-decoration: none;\r
549
+ padding: 10px 16px;\r
550
+ display: block;\r
551
+ border-radius: 8px;\r
552
+ transition: all 0.2s;\r
553
+ background-color: #ffffff;\r
554
+ border: 1px solid #dee2e6;\r
555
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
556
+ }\r
557
+ .file-list a:hover {\r
558
+ transform: translateY(-2px);\r
559
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\r
560
+ }\r
561
+ .file-list a.folder-link {\r
562
+ color: #0d6efd;\r
563
+ background-color: #ffffff;\r
564
+ border: 1px solid #cfe2ff;\r
565
+ padding-left: 48px;\r
566
+ position: relative;\r
567
+ }\r
568
+ .file-list a.folder-link:hover {\r
569
+ background-color: #f8f9fa;\r
570
+ border-color: #0d6efd;\r
571
+ }\r
572
+ .file-list a.folder-link::before {\r
573
+ content: '\u{1F4C1}';\r
574
+ position: absolute;\r
575
+ left: 16px;\r
576
+ top: 50%;\r
577
+ transform: translateY(-50%);\r
578
+ font-size: 16px;\r
579
+ }\r
580
+ .file-list a.back-link {\r
581
+ color: #6c757d;\r
582
+ background-color: #f8f9fa;\r
583
+ border: 1px solid #e9ecef;\r
584
+ }\r
585
+ .file-list a.back-link:hover {\r
586
+ background-color: #e9ecef;\r
587
+ border-color: #dee2e6;\r
588
+ }\r
589
+ .file-list a.back-link::before {\r
590
+ content: '\u2190';\r
591
+ margin-right: 8px;\r
592
+ }\r
593
+ .file-list a.file-link {\r
594
+ color: #212529;\r
595
+ background-color: #ffffff;\r
596
+ border: 1px solid #dee2e6;\r
597
+ padding-left: 48px;\r
598
+ position: relative;\r
599
+ }\r
600
+ .file-list a.file-link:hover {\r
601
+ background-color: #f8f9fa;\r
602
+ border-color: #0d6efd;\r
603
+ }\r
604
+ .file-list a.file-link::before {\r
605
+ content: '\u{1F4C4}';\r
606
+ position: absolute;\r
607
+ left: 16px;\r
608
+ top: 50%;\r
609
+ transform: translateY(-50%);\r
610
+ font-size: 16px;\r
611
+ color: #6c757d;\r
261
612
  }\r
262
- .view-details .size,\r
263
- .view-details .date {\r
264
- text-align: right;\r
265
- direction: rtl;\r
613
+ \r
614
+ /* \u7A7A\u72B6\u6001 - \u4EAE\u8272 */\r
615
+ .empty-message {\r
616
+ color: #6c757d;\r
617
+ font-style: italic;\r
618
+ text-align: center;\r
619
+ padding: 32px;\r
620
+ background-color: #ffffff;\r
621
+ border-radius: 8px;\r
622
+ border: 1px dashed #dee2e6;\r
623
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
266
624
  }\r
267
625
  \r
268
- /*mobile*/\r
626
+ /* \u54CD\u5E94\u5F0F\u8BBE\u8BA1 */\r
269
627
  @media (max-width: 768px) {\r
270
628
  body {\r
271
- font-size: 13px;\r
272
- line-height: 16px;\r
273
- padding: 0;\r
274
- }\r
275
- #search {\r
276
- position: static;\r
277
- width: 100%;\r
278
- font-size: 2em;\r
279
- line-height: 1.8em;\r
280
- text-indent: 10px;\r
281
- border: 0;\r
282
- border-radius: 0;\r
283
- padding: 10px 0;\r
284
- margin: 0;\r
285
- }\r
286
- #search:focus {\r
287
- width: 100%;\r
288
- border: 0;\r
289
- opacity: 1;\r
290
- }\r
291
- .directory h1 {\r
292
- font-size: 2em;\r
293
- line-height: 1.5em;\r
294
- color: #fff;\r
295
- background: #000;\r
296
- padding: 15px 10px;\r
297
- margin: 0;\r
298
- }\r
299
- ul#files {\r
300
- border-top: 1px solid #cacaca;\r
301
- }\r
302
- ul#files li {\r
303
- float: none;\r
304
- width: auto !important;\r
305
- display: block;\r
306
- border-bottom: 1px solid #cacaca;\r
307
- font-size: 2em;\r
308
- line-height: 1.2em;\r
309
- text-indent: 0;\r
310
- margin: 0;\r
629
+ padding: 12px;\r
311
630
  }\r
312
- ul#files li:nth-child(odd) {\r
313
- background: #e0e0e0;\r
631
+ .file-row {\r
632
+ flex-direction: column;\r
314
633
  }\r
315
- ul#files li a {\r
316
- height: auto;\r
317
- border: 0;\r
318
- border-radius: 0;\r
319
- padding: 15px 10px;\r
320
- }\r
321
- ul#files li a:focus,\r
322
- ul#files li a:hover {\r
323
- border: 0;\r
324
- }\r
325
- #files .header,\r
326
- #files .size,\r
327
- #files .date {\r
328
- display: none !important;\r
329
- }\r
330
- #files .name {\r
331
- float: none;\r
332
- display: inline-block;\r
333
- width: 100%;\r
334
- text-indent: 0;\r
335
- background-position: 0 50%;\r
336
- }\r
337
- #files .icon .name {\r
338
- text-indent: 41px;\r
634
+ .file-column {\r
635
+ margin: 4px 0;\r
339
636
  }\r
340
637
  }\r
341
- #files .icon-directory .name {\r
342
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAWtQTFRFAAAA/PPQ9Nhc2q402qQ12qs2/PTX2pg12p81+/LM89NE9dto2q82+/fp2rM22qY39d6U+/bo2qo2/frx/vz32q812qs12qE279SU8c4w9NZP+/LK//367s9y7s925cp0/vzw9t92//342po2/vz25s1579B6+OSO2bQ0/v799NyT8tE79dld8Msm+OrC/vzx79KA2IYs7s6I9d6R4cJe9+OF/PLI/fry79OF/v30//328tWB89RJ8c9p8c0u9eCf//7+9txs6sts5Mdr+++5+u2z/vrv+/fq6cFz8dBs8tA57cpq+OaU9uGs27Y8//799NdX/PbY9uB89unJ//z14sNf+emh+emk+vDc+uys9+OL8dJy89NH+eic8tN5+OaV+OWR9N2n9dtl9t529+KF9+GB9Nue9NdU8tR/9t5y89qW9dpj89iO89eG/vvu2pQ12Y4z/vzy2Ict/vvv48dr/vzz4sNg///+2Igty3PqwQAAAAF0Uk5TAEDm2GYAAACtSURBVBjTY2AgA2iYlJWVhfohBPg0yx38y92dS0pKVOVBAqIi6sb2vsWWpfrFeTI8QAEhYQEta28nCwM1OVleZqCAmKCEkUdwYWmhQnFeOStQgL9cySqkNNDHVJGbiY0FKCCuYuYSGRsV5KgjxcXIARRQNncNj09JTgqw0ZbkZAcK5LuFJaRmZqfHeNnpSucDBQoiEtOycnIz4qI9bfUKQA6pKKqAgqIKQyK8BgAZ5yfODmnHrQAAAABJRU5ErkJggg==);\r
343
- }\r
344
- #files .icon-text-html .name {\r
345
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHtSURBVDjLjZM9T9tQFIYpQ5eOMBKlW6eWIQipa8RfQKQghEAKqZgKFQgmFn5AWyVDCipVQZC2EqBWlEqdO2RCpAssQBRsx1+1ndix8wFvfW6wcUhQsfTI0j33PD7n+N4uAF2E+/S5RFwG/8Njl24/LyCIOI6j1+v1y0ajgU64cSSTybdBSVAwSMmmacKyLB/DMKBpGkRRZBJBEJBKpXyJl/yABLTBtm1Uq1X2JsrlMnRdhyRJTFCpVEAfSafTTUlQoFs1luxBAkoolUqQZbmtJTYTT/AoHInOfpcwtVtkwcSBgrkDGYph+60oisIq4Xm+VfB0+U/P0Lvj3NwPGfHPTcHMvoyFXwpe7UmQtAqTUCU0D1VVbwTPVk5jY19Fe3ZfQny7CE51WJDXqpjeEUHr45ki9rIqa4dmQiJfMLItGEs/FcQ2ucbRmdnSYy5vYWyLx/w3EaMfLmBaDpMQvuDJ65PY8Dpnz3wpYmLtApzcrIAqmfrEgdZH1grY/a36w6Xz0DKD8ES25/niYS6+wWE8mWfByY8cXmYEJFYLkHUHtVqNQcltAvoLD3v7o/FUHsNvzlnwxfsCEukC/ho3yUHaBN5Buo17Ojtyl+DqrnvQgUtfcC0ZcAdkUeA+ye7eMru9AUGIJPe4zh509UP/AAfNypi8oj/mAAAAAElFTkSuQmCC);\r
346
- }\r
347
638
  </style>\r
348
639
  </head>\r
349
- <body class="directory">\r
350
- <div class="wrapper">\r
351
- <h1>{{headItem}}</h1>\r
352
- <ul id="files" class="view-tiles">\r
353
- {{listItems}}\r
354
- </ul>\r
355
- </div>\r
640
+ <body>\r
641
+ <div class="breadcrumb">{{breadcrumb}}</div>\r
642
+ <div class="content-area">{{list}}</div>\r
356
643
  </body>\r
357
644
  </html>\r
358
645
  `;
359
646
 
360
- // src/index.ts
647
+ // src/v1_1_0_theme/index.ts
361
648
  function fileServerPlugin(options = {}) {
362
- const { enable = true } = options;
649
+ const { enable = true, root = "", theme = "dark" } = options;
363
650
  return {
364
651
  name: "vite-plugin-files-server",
365
- // 必须唯一
366
- // 核心钩子:配置开发服务器
367
652
  configureServer(server) {
368
653
  if (!enable) return;
654
+ let templateString;
655
+ try {
656
+ if (theme === "light") {
657
+ templateString = tempFolderLight_default;
658
+ } else {
659
+ templateString = tempFolderDark_default;
660
+ }
661
+ } catch (e) {
662
+ console.error("Failed to load template:", e);
663
+ templateString = tempFolderDark_default;
664
+ }
665
+ function buildGalleryTree(dirPath, baseUrl = "", depth = 0) {
666
+ try {
667
+ const files = import_fs.default.readdirSync(dirPath);
668
+ let html = "";
669
+ files.sort((a, b) => {
670
+ const aPath = import_path.default.join(dirPath, a);
671
+ const bPath = import_path.default.join(dirPath, b);
672
+ const aIsDir = import_fs.default.statSync(aPath).isDirectory();
673
+ const bIsDir = import_fs.default.statSync(bPath).isDirectory();
674
+ if (aIsDir && !bIsDir) return -1;
675
+ if (!aIsDir && bIsDir) return 1;
676
+ return a.localeCompare(b);
677
+ });
678
+ const folderItems = [];
679
+ const htmlFiles = [];
680
+ files.forEach((file) => {
681
+ const filePath = import_path.default.join(dirPath, file);
682
+ const relativePath = import_path.default.join(baseUrl, file).replace(/\\/g, "/");
683
+ try {
684
+ const stats = import_fs.default.statSync(filePath);
685
+ if (stats.isDirectory()) {
686
+ folderItems.push({ file, filePath, relativePath });
687
+ } else if (import_path.default.extname(file).toLowerCase() === ".html" || import_path.default.extname(file).toLowerCase() === ".htm") {
688
+ htmlFiles.push({ file, relativePath });
689
+ }
690
+ } catch (e) {
691
+ console.error(`Error reading ${filePath}:`, e);
692
+ }
693
+ });
694
+ folderItems.forEach(({ file, filePath, relativePath }) => {
695
+ let level = relativePath.split("/");
696
+ if (level.length == 4) {
697
+ html += `<div class="folder-item">
698
+ <a class="folder-name">${file}</a>
699
+ </div>`;
700
+ } else if (level.length == 5) {
701
+ html += `<div class="folder-item">
702
+ <a class="folder-name level-sub">${file}</a>
703
+ </div>`;
704
+ }
705
+ const subTree = buildGalleryTree(filePath, relativePath, depth + 1);
706
+ if (subTree) {
707
+ html += subTree;
708
+ }
709
+ });
710
+ if (htmlFiles.length > 0) {
711
+ html += `<div class="file-grid">`;
712
+ for (let i = 0; i < htmlFiles.length; i += 3) {
713
+ const rowFiles = htmlFiles.slice(i, i + 3);
714
+ html += `<div class="file-row">`;
715
+ rowFiles.forEach(({ file, relativePath }) => {
716
+ html += `<div class="file-column">
717
+ <a href="${relativePath}" class="html-file-link">${file}</a>
718
+ </div>`;
719
+ });
720
+ for (let j = rowFiles.length; j < 3; j++) {
721
+ html += `<div class="file-column empty-column"></div>`;
722
+ }
723
+ html += `</div>`;
724
+ }
725
+ html += `</div>`;
726
+ }
727
+ return html;
728
+ } catch (e) {
729
+ console.error(`Error reading directory ${dirPath}:`, e);
730
+ return "";
731
+ }
732
+ }
733
+ function generateFileList(fullPath, url) {
734
+ try {
735
+ const files = import_fs.default.readdirSync(fullPath);
736
+ let listItems = "";
737
+ const sortedFiles = files.sort((a, b) => {
738
+ const aPath = import_path.default.join(fullPath, a);
739
+ const bPath = import_path.default.join(fullPath, b);
740
+ const aIsDir = import_fs.default.statSync(aPath).isDirectory();
741
+ const bIsDir = import_fs.default.statSync(bPath).isDirectory();
742
+ if (aIsDir && !bIsDir) return -1;
743
+ if (!aIsDir && bIsDir) return 1;
744
+ return a.localeCompare(b);
745
+ });
746
+ if (url !== "/") {
747
+ const backUrl = url.split("/").slice(0, -1).join("/") || "/";
748
+ listItems += `<li><a href="${backUrl}" class="folder-link back-link">..</a></li>
749
+ `;
750
+ }
751
+ sortedFiles.forEach((file) => {
752
+ const filePath = import_path.default.join(fullPath, file);
753
+ const stats = import_fs.default.statSync(filePath);
754
+ const isDir = stats.isDirectory();
755
+ const href = import_path.default.join(url, file).replace(/\\/g, "/");
756
+ if (isDir) {
757
+ listItems += `<li><a href="${href}" class="folder-link">${file}</a></li>
758
+ `;
759
+ } else {
760
+ listItems += `<li><a href="${href}" class="file-link">${file}</a></li>
761
+ `;
762
+ }
763
+ });
764
+ return listItems;
765
+ } catch (e) {
766
+ console.error(`Error generating file list:`, e);
767
+ return "";
768
+ }
769
+ }
770
+ function generateHtmlPage(url, content, isGalleryTree = false) {
771
+ let urlSplitArray = url.split("/").filter(Boolean);
772
+ let breadcrumb = "";
773
+ if (url === "/") {
774
+ breadcrumb = '<a href="/" class="breadcrumb-link">/</a>';
775
+ } else {
776
+ breadcrumb = '<a href="/" class="breadcrumb-link">Home</a> ';
777
+ urlSplitArray.forEach((p, index) => {
778
+ const href = "/" + urlSplitArray.slice(0, index + 1).join("/");
779
+ breadcrumb += `<a href="${href}" class="breadcrumb-link"> / ${p}</a>`;
780
+ if (index < urlSplitArray.length - 1) {
781
+ breadcrumb += " ";
782
+ }
783
+ });
784
+ }
785
+ const pageTitle = url === "/" ? "/" : url;
786
+ const list = isGalleryTree ? `<div class="gallery-tree">${content || '<div class="empty-message">No HTML files found</div>'}</div>` : `
787
+ <ul class="file-list">
788
+ ${content || '<li class="empty-message">No files found</li>'}
789
+ </ul>
790
+ `;
791
+ const html = templateString.replace(/{{pageTitle}}/g, pageTitle).replace(/{{breadcrumb}}/g, breadcrumb).replace(/{{list}}/g, list);
792
+ return html;
793
+ }
369
794
  server.middlewares.use((req, res, next) => {
370
795
  const url = req.url ? decodeURIComponent(req.url.split("?")[0]) : "/";
371
796
  if (url.startsWith("/@") || url.includes("vite")) {
@@ -378,48 +803,76 @@ function fileServerPlugin(options = {}) {
378
803
  if (import_fs.default.existsSync(import_path.default.join(fullPath, "index.html"))) {
379
804
  return next();
380
805
  }
381
- let urlSplitArray = url.split("/");
382
- if (urlSplitArray[urlSplitArray.length - 1] == "") urlSplitArray = urlSplitArray.slice(0, -1);
383
- let headItem = '<a href="/">\u{1F3E0}\uFE0E</a> / ';
384
- urlSplitArray.forEach((p) => {
385
- p && (headItem += `<a href="/${p}">${p}</a> / `);
386
- });
387
- const files = import_fs.default.readdirSync(fullPath);
388
- const listItems = files.map((file) => {
389
- const filePath = import_path.default.join(fullPath, file);
390
- const isDir = import_fs.default.statSync(filePath).isDirectory();
391
- const href = import_path.default.join(url, file).replace(/\\/g, "/");
392
- const item = `
393
- <li>
394
- <a href="${href}" class="icon ${isDir ? "icon-directory" : "icon-html icon-text-html"}">
395
- <span class="name">${file}</span>
396
- </a>
397
- </li>`;
398
- return item;
399
- }).join("");
400
- urlSplitArray = urlSplitArray.slice(0, -1);
401
- let backUrl = urlSplitArray.join("/");
402
- const backItem = `
403
- <li>
404
- <a href="${backUrl}" class="icon icon-directory"><span class="name">..</span></a>
405
- </li>`;
406
- let fullList = urlSplitArray.length > 1 ? backItem + listItems : listItems;
407
- const html = temp_default.replace(/{{title}}/g, `Index of ${url}`).replace(/{{headItem}}/g, headItem).replace(/{{url}}/g, url).replace(/{{listItems}}/g, fullList);
806
+ let content = "";
807
+ const isGalleryTree = url === "/apps/gallery" || url.startsWith("/gallery/");
808
+ if (isGalleryTree) {
809
+ content = `<p class="back-all-link"><a href="/apps" class="back-link">..</a></p>`;
810
+ content += buildGalleryTree(fullPath, url === "/" ? "" : url);
811
+ } else {
812
+ content = generateFileList(fullPath, url);
813
+ }
814
+ const html = generateHtmlPage(url, content, isGalleryTree);
408
815
  res.setHeader("Content-Type", "text/html");
409
816
  res.end(html);
410
817
  return;
411
818
  } else if (!import_fs.default.existsSync(fullPath)) {
412
- res.statusCode = 404;
413
- const html = "404 Not Found";
414
- res.setHeader("Content-Type", "text/html");
415
- res.end(html);
819
+ setStatus404(res, url, theme);
416
820
  return;
417
821
  }
418
822
  } catch (e) {
419
- console.error("File Server Plugin Error:", e);
823
+ setStatus500(res, e, theme);
824
+ return;
420
825
  }
421
826
  next();
422
827
  });
423
828
  }
424
829
  };
425
830
  }
831
+ function setStatus404(res, url, theme) {
832
+ res.statusCode = 404;
833
+ res.setHeader("Content-Type", "text/html");
834
+ if (theme === "light") {
835
+ res.end(`
836
+ <!DOCTYPE html>
837
+ <html>
838
+ <head><title>404 Not Found</title></head>
839
+ <body style="background:#f8f9fa;color:#212529;font-family:Consolas;padding:20px;">
840
+ <h1>404 Not Found</h1>
841
+ <p>The requested URL ${url} was not found on this server.</p>
842
+ <p><a href="/" style="color:#0d6efd;">Return to home</a></p>
843
+ </body>
844
+ </html>
845
+ `);
846
+ } else {
847
+ res.end(`
848
+ <!DOCTYPE html>
849
+ <html>
850
+ <head><title>404 Not Found</title></head>
851
+ <body style="background:#000;color:#fff;font-family:Consolas;padding:20px;">
852
+ <h1>404 Not Found</h1>
853
+ <p>The requested URL ${url} was not found on this server.</p>
854
+ <p><a href="/" style="color:#569cd6;">Return to home</a></p>
855
+ </body>
856
+ </html>
857
+ `);
858
+ }
859
+ }
860
+ function setStatus500(res, error, theme) {
861
+ console.error("File Server Plugin Error:", error);
862
+ res.statusCode = 500;
863
+ if (theme === "light") {
864
+ res.end(`
865
+ <!DOCTYPE html>
866
+ <html>
867
+ <head><title>500 Internal Server Error</title></head>
868
+ <body style="background:#f8f9fa;color:#212529;font-family:Consolas;padding:20px;">
869
+ <h1>500 Internal Server Error</h1>
870
+ <p>An error occurred on the server.</p>
871
+ <p><a href="/" style="color:#0d6efd;">Return to home</a></p>
872
+ </body>
873
+ </html>
874
+ `);
875
+ } else {
876
+ res.end("Internal Server Error");
877
+ }
878
+ }