vite-plugin-files-server 1.0.3 → 1.1.1

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,747 @@ 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: #2a2a2a; /* \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{1F4C1}';\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
+ \r
122
+ /* \u6587\u4EF6\u7F51\u683C\u5E03\u5C40 - \u4E09\u5217 */\r
123
+ .file-grid {\r
124
+ margin: 12px 0 20px 0;\r
125
+ display: block;\r
126
+ }\r
127
+ .file-row {\r
128
+ display: flex;\r
129
+ margin: 8px 0;\r
130
+ }\r
131
+ .file-column {\r
132
+ flex: 1;\r
133
+ min-width: 0;\r
134
+ margin: 0 6px;\r
135
+ padding: 8px 12px;\r
136
+ border-radius: 8px;\r
137
+ transition: all 0.2s;\r
138
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
139
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
140
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
141
+ }\r
142
+ .file-column:hover {\r
143
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #3a3a3a */\r
144
+ transform: translateY(-2px);\r
145
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
146
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
147
+ }\r
148
+ .empty-column {\r
149
+ background-color: transparent;\r
150
+ border: 1px solid transparent;\r
151
+ box-shadow: none;\r
152
+ }\r
153
+ .empty-column:hover {\r
154
+ background-color: transparent;\r
155
+ transform: none;\r
156
+ box-shadow: none;\r
157
+ border-color: transparent;\r
158
+ }\r
159
+ .html-file-link {\r
160
+ color: #e0e0e0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #212529 \u2192 \u6697\u8272 #e0e0e0 */\r
161
+ text-decoration: none;\r
162
+ display: block;\r
163
+ white-space: nowrap;\r
164
+ overflow: hidden;\r
165
+ text-overflow: ellipsis;\r
166
+ padding-left: 24px;\r
167
+ position: relative;\r
168
+ font-size: 13px;\r
169
+ }\r
170
+ .html-file-link:hover {\r
171
+ color: #ffffff; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #ffffff */\r
172
+ }\r
173
+ .html-file-link::before {\r
174
+ content: '\u{1F4C4}';\r
175
+ position: absolute;\r
176
+ left: 0;\r
177
+ top: 0;\r
178
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
82
179
  }\r
83
180
  \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
181
+ .back-all-link {\r
182
+ font-family:\r
183
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;\r
184
+ }\r
185
+ .back-all-link a {\r
186
+ text-decoration: none;\r
187
+ padding: 10px 16px;\r
188
+ display: block;\r
189
+ border-radius: 8px;\r
190
+ transition: all 0.2s;\r
191
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
192
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
193
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
194
+ }\r
195
+ .back-all-link a:hover {\r
196
+ transform: translateY(-2px);\r
197
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
198
+ }\r
199
+ .back-all-link a.back-link {\r
200
+ color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
201
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
202
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #cfe2ff \u2192 \u6697\u8272 #3a3a3a */\r
203
+ padding-left: 48px;\r
204
+ position: relative;\r
205
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
206
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #2a2a2a */\r
207
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
208
+ }\r
209
+ .back-all-link a.back-link:hover {\r
210
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #3a3a3a */\r
211
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
212
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
213
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #4dabf7 */\r
214
+ }\r
215
+ .back-all-link a.back-link::before {\r
216
+ content: '\u{1F4C1}';\r
217
+ position: absolute;\r
218
+ left: 16px;\r
219
+ top: 50%;\r
220
+ transform: translateY(-50%);\r
221
+ font-size: 16px;\r
222
+ content: '\u2190';\r
223
+ margin-right: 8px;\r
224
+ }\r
225
+ \r
226
+ /* \u6587\u4EF6\u5217\u8868\u89C6\u56FE - \u6697\u8272\u4E3B\u9898 */\r
227
+ .file-list {\r
118
228
  list-style: none;\r
229
+ padding: 0;\r
230
+ margin: 0;\r
119
231
  }\r
120
- ul li:hover {\r
121
- cursor: pointer;\r
122
- color: #2e2e2e;\r
232
+ .file-list li {\r
233
+ margin: 6px 0;\r
123
234
  }\r
124
- ul li .path {\r
125
- padding-left: 5px;\r
126
- font-weight: bold;\r
235
+ .file-list a {\r
236
+ text-decoration: none;\r
237
+ padding: 10px 16px;\r
238
+ display: block;\r
239
+ border-radius: 8px;\r
240
+ transition: all 0.2s;\r
241
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
242
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
243
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
244
+ }\r
245
+ .file-list a:hover {\r
246
+ transform: translateY(-2px);\r
247
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
248
+ }\r
249
+ .file-list a.folder-link {\r
250
+ color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
251
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
252
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #cfe2ff \u2192 \u6697\u8272 #3a3a3a */\r
253
+ padding-left: 48px;\r
254
+ position: relative;\r
255
+ }\r
256
+ .file-list a.folder-link:hover {\r
257
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #3a3a3a */\r
258
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
259
+ }\r
260
+ .file-list a.folder-link::before {\r
261
+ content: '\u{1F4C1}';\r
262
+ position: absolute;\r
263
+ left: 16px;\r
264
+ top: 50%;\r
265
+ transform: translateY(-50%);\r
266
+ font-size: 16px;\r
267
+ }\r
268
+ .file-list a.back-link {\r
269
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
270
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #2a2a2a */\r
271
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
272
+ }\r
273
+ .file-list a.back-link:hover {\r
274
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #e9ecef \u2192 \u6697\u8272 #3a3a3a */\r
275
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #4dabf7 */\r
276
+ }\r
277
+ .file-list a.back-link::before {\r
278
+ content: '\u2190';\r
279
+ margin-right: 8px;\r
280
+ }\r
281
+ .file-list a.file-link {\r
282
+ color: #e0e0e0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #212529 \u2192 \u6697\u8272 #e0e0e0 */\r
283
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
284
+ border: 1px solid #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
285
+ padding-left: 48px;\r
286
+ position: relative;\r
287
+ }\r
288
+ .file-list a.file-link:hover {\r
289
+ background-color: #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #f8f9fa \u2192 \u6697\u8272 #3a3a3a */\r
290
+ border-color: #4dabf7; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #0d6efd \u2192 \u6697\u8272 #4dabf7 */\r
291
+ }\r
292
+ .file-list a.file-link::before {\r
293
+ content: '\u{1F4C4}';\r
294
+ position: absolute;\r
295
+ left: 16px;\r
296
+ top: 50%;\r
297
+ transform: translateY(-50%);\r
298
+ font-size: 16px;\r
299
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
127
300
  }\r
128
- ul li .line {\r
129
- padding-right: 5px;\r
301
+ \r
302
+ /* \u7A7A\u72B6\u6001 - \u6697\u8272 */\r
303
+ .empty-message {\r
304
+ color: #a0a0a0; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #6c757d \u2192 \u6697\u8272 #a0a0a0 */\r
130
305
  font-style: italic;\r
306
+ text-align: center;\r
307
+ padding: 32px;\r
308
+ background-color: #2a2a2a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #ffffff \u2192 \u6697\u8272 #2a2a2a */\r
309
+ border-radius: 8px;\r
310
+ border: 1px dashed #3a3a3a; /* \u4FEE\u6539\uFF1A\u4EAE\u8272 #dee2e6 \u2192 \u6697\u8272 #3a3a3a */\r
311
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* \u4FEE\u6539\uFF1A\u9634\u5F71\u52A0\u6DF1 */\r
131
312
  }\r
132
- ul li:first-child .path {\r
133
- padding-left: 0;\r
313
+ \r
314
+ /* \u54CD\u5E94\u5F0F\u8BBE\u8BA1 */\r
315
+ @media (max-width: 768px) {\r
316
+ body {\r
317
+ padding: 12px;\r
318
+ }\r
319
+ .file-row {\r
320
+ flex-direction: column;\r
321
+ }\r
322
+ .file-column {\r
323
+ margin: 4px 0;\r
324
+ }\r
134
325
  }\r
135
- p {\r
326
+ </style>\r
327
+ </head>\r
328
+ <body>\r
329
+ <div class="breadcrumb">{{breadcrumb}}</div>\r
330
+ <div class="content-area">{{list}}</div>\r
331
+ </body>\r
332
+ </html>\r
333
+ `;
334
+
335
+ // src/v1_1_0_theme/tempFolderLight.html?raw
336
+ var tempFolderLight_default = `<!doctype html>\r
337
+ <html lang="en">\r
338
+ <head>\r
339
+ <meta charset="UTF-8" />\r
340
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />\r
341
+ <title>Demo List {{pageTitle}}</title>\r
342
+ <style>\r
343
+ /* \u4EAE\u8272\u4E3B\u9898 - \u6574\u4F53\u660E\u4EAE\u98CE\u683C */\r
344
+ body {\r
345
+ background-color: #f8f9fa;\r
346
+ color: #212529;\r
347
+ font-family:\r
348
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;\r
349
+ margin: 0;\r
350
+ padding: 20px;\r
351
+ font-size: 14px;\r
136
352
  line-height: 1.5;\r
137
353
  }\r
138
- a {\r
139
- color: #555;\r
354
+ \r
355
+ /* \u9762\u5305\u5C51\u5BFC\u822A - \u4EAE\u8272 */\r
356
+ .breadcrumb {\r
357
+ color: #6c757d;\r
358
+ margin-bottom: 20px;\r
359
+ font-size: 13px;\r
360
+ background-color: #ffffff;\r
361
+ padding: 12px 16px;\r
362
+ border-radius: 8px;\r
363
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
364
+ border: 1px solid #e9ecef;\r
365
+ }\r
366
+ .breadcrumb-link {\r
367
+ color: #0d6efd;\r
368
+ text-decoration: none;\r
369
+ font-weight: 500;\r
370
+ transition: all 0.2s;\r
371
+ padding: 4px 8px;\r
372
+ border-radius: 4px;\r
373
+ }\r
374
+ .breadcrumb-link:hover {\r
375
+ background-color: #e7f1ff;\r
376
+ color: #0a58ca;\r
140
377
  text-decoration: none;\r
141
378
  }\r
142
- a:hover {\r
143
- color: #303030;\r
144
- }\r
145
- #stacktrace {\r
146
- margin-top: 15px;\r
379
+ \r
380
+ /* \u5185\u5BB9\u533A\u57DF */\r
381
+ .content-area {\r
382
+ margin-top: 20px;\r
147
383
  }\r
148
- .directory h1 {\r
149
- margin-bottom: 15px;\r
150
- font-size: 18px;\r
384
+ \r
385
+ /* gallery\u6811\u5F62\u89C6\u56FE - \u4EAE\u8272 */\r
386
+ .gallery-tree {\r
387
+ font-family: 'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', monospace;\r
388
+ line-height: 1.6;\r
389
+ color: #212529;\r
151
390
  }\r
152
- ul#files {\r
153
- width: 100%;\r
154
- height: 100%;\r
155
- overflow: hidden;\r
391
+ \r
392
+ /* \u6587\u4EF6\u5939\u9879 - \u4EAE\u8272\u4E3B\u9898 */\r
393
+ .folder-item {\r
394
+ cursor: default;\r
395
+ margin: 6px 0;\r
396
+ padding-left: 20px;\r
397
+ position: relative;\r
398
+ }\r
399
+ .folder-item:hover {\r
400
+ background-color: #f8f9fa;\r
401
+ }\r
402
+ .folder-name {\r
403
+ color: #0d6efd;\r
404
+ text-decoration: none;\r
405
+ display: inline-block;\r
406
+ padding: 6px 12px;\r
407
+ border-radius: 6px;\r
408
+ font-weight: 500;\r
409
+ background-color: #e7f1ff;\r
410
+ border: 1px solid #cfe2ff;\r
411
+ transition: all 0.2s;\r
156
412
  }\r
157
- ul#files li {\r
158
- float: left;\r
159
- width: 30%;\r
160
- line-height: 25px;\r
161
- margin: 1px;\r
413
+ .folder-name::before {\r
414
+ content: '\u{1F4C1}';\r
415
+ margin-right: 8px;\r
162
416
  }\r
163
- ul#files li a {\r
417
+ \r
418
+ /* \u6587\u4EF6\u7F51\u683C\u5E03\u5C40 - \u4E09\u5217 */\r
419
+ .file-grid {\r
420
+ margin: 12px 0 20px 0;\r
164
421
  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
422
  }\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
423
+ .file-row {\r
424
+ display: flex;\r
425
+ margin: 8px 0;\r
426
+ }\r
427
+ .file-column {\r
428
+ flex: 1;\r
429
+ min-width: 0;\r
430
+ margin: 0 6px;\r
431
+ padding: 8px 12px;\r
432
+ border-radius: 8px;\r
433
+ transition: all 0.2s;\r
434
+ background-color: #ffffff;\r
435
+ border: 1px solid #dee2e6;\r
436
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
437
+ }\r
438
+ .file-column:hover {\r
439
+ background-color: #f8f9fa;\r
440
+ transform: translateY(-2px);\r
441
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\r
442
+ border-color: #0d6efd;\r
443
+ }\r
444
+ .empty-column {\r
445
+ background-color: transparent;\r
446
+ border: 1px solid transparent;\r
447
+ box-shadow: none;\r
177
448
  }\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
449
+ .empty-column:hover {\r
450
+ background-color: transparent;\r
451
+ transform: none;\r
452
+ box-shadow: none;\r
453
+ border-color: transparent;\r
182
454
  }\r
183
- #search {\r
455
+ .html-file-link {\r
456
+ color: #212529;\r
457
+ text-decoration: none;\r
184
458
  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
459
+ white-space: nowrap;\r
216
460
  overflow: hidden;\r
217
461
  text-overflow: ellipsis;\r
218
- text-indent: 10px;\r
462
+ padding-left: 24px;\r
463
+ position: relative;\r
464
+ font-size: 13px;\r
219
465
  }\r
220
- #files .name {\r
221
- background-repeat: no-repeat;\r
466
+ .html-file-link:hover {\r
467
+ color: #0d6efd;\r
222
468
  }\r
223
- #files .icon .name {\r
224
- text-indent: 28px;\r
469
+ .html-file-link::before {\r
470
+ content: '\u{1F4C4}';\r
471
+ position: absolute;\r
472
+ left: 0;\r
473
+ top: 0;\r
474
+ color: #6c757d;\r
225
475
  }\r
226
476
  \r
227
- /*tiles*/\r
228
- .view-tiles .name {\r
229
- width: 100%;\r
230
- background-position: 8px 5px;\r
477
+ .back-all-link {\r
478
+ font-family:\r
479
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;\r
231
480
  }\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
481
+ .back-all-link a {\r
482
+ text-decoration: none;\r
483
+ padding: 10px 16px;\r
240
484
  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
485
+ border-radius: 8px;\r
486
+ transition: all 0.2s;\r
487
+ background-color: #ffffff;\r
488
+ border: 1px solid #dee2e6;\r
489
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
490
+ }\r
491
+ .back-all-link a:hover {\r
492
+ transform: translateY(-2px);\r
493
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\r
494
+ }\r
495
+ .back-all-link a.back-link {\r
496
+ color: #0d6efd;\r
497
+ background-color: #ffffff;\r
498
+ border: 1px solid #cfe2ff;\r
499
+ padding-left: 48px;\r
500
+ position: relative;\r
501
+ color: #6c757d;\r
502
+ background-color: #f8f9fa;\r
503
+ border: 1px solid #e9ecef;\r
504
+ }\r
505
+ .back-all-link a.back-link:hover {\r
506
+ background-color: #e9ecef;\r
507
+ border-color: #dee2e6;\r
508
+ background-color: #f8f9fa;\r
509
+ border-color: #0d6efd;\r
510
+ }\r
511
+ .back-all-link a.back-link::before {\r
512
+ content: '\u{1F4C1}';\r
513
+ position: absolute;\r
514
+ left: 16px;\r
515
+ top: 50%;\r
516
+ transform: translateY(-50%);\r
517
+ font-size: 16px;\r
518
+ content: '\u2190';\r
519
+ margin-right: 8px;\r
248
520
  }\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
521
+ \r
522
+ /* \u6587\u4EF6\u5217\u8868\u89C6\u56FE - \u4EAE\u8272\u4E3B\u9898 */\r
523
+ .file-list {\r
524
+ list-style: none;\r
525
+ padding: 0;\r
526
+ margin: 0;\r
255
527
  }\r
256
- .view-details .size {\r
257
- width: 10%;\r
528
+ .file-list li {\r
529
+ margin: 6px 0;\r
258
530
  }\r
259
- .view-details .date {\r
260
- width: 30%;\r
531
+ .file-list a {\r
532
+ text-decoration: none;\r
533
+ padding: 10px 16px;\r
534
+ display: block;\r
535
+ border-radius: 8px;\r
536
+ transition: all 0.2s;\r
537
+ background-color: #ffffff;\r
538
+ border: 1px solid #dee2e6;\r
539
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
540
+ }\r
541
+ .file-list a:hover {\r
542
+ transform: translateY(-2px);\r
543
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\r
544
+ }\r
545
+ .file-list a.folder-link {\r
546
+ color: #0d6efd;\r
547
+ background-color: #ffffff;\r
548
+ border: 1px solid #cfe2ff;\r
549
+ padding-left: 48px;\r
550
+ position: relative;\r
551
+ }\r
552
+ .file-list a.folder-link:hover {\r
553
+ background-color: #f8f9fa;\r
554
+ border-color: #0d6efd;\r
555
+ }\r
556
+ .file-list a.folder-link::before {\r
557
+ content: '\u{1F4C1}';\r
558
+ position: absolute;\r
559
+ left: 16px;\r
560
+ top: 50%;\r
561
+ transform: translateY(-50%);\r
562
+ font-size: 16px;\r
563
+ }\r
564
+ .file-list a.back-link {\r
565
+ color: #6c757d;\r
566
+ background-color: #f8f9fa;\r
567
+ border: 1px solid #e9ecef;\r
568
+ }\r
569
+ .file-list a.back-link:hover {\r
570
+ background-color: #e9ecef;\r
571
+ border-color: #dee2e6;\r
572
+ }\r
573
+ .file-list a.back-link::before {\r
574
+ content: '\u2190';\r
575
+ margin-right: 8px;\r
576
+ }\r
577
+ .file-list a.file-link {\r
578
+ color: #212529;\r
579
+ background-color: #ffffff;\r
580
+ border: 1px solid #dee2e6;\r
581
+ padding-left: 48px;\r
582
+ position: relative;\r
583
+ }\r
584
+ .file-list a.file-link:hover {\r
585
+ background-color: #f8f9fa;\r
586
+ border-color: #0d6efd;\r
587
+ }\r
588
+ .file-list a.file-link::before {\r
589
+ content: '\u{1F4C4}';\r
590
+ position: absolute;\r
591
+ left: 16px;\r
592
+ top: 50%;\r
593
+ transform: translateY(-50%);\r
594
+ font-size: 16px;\r
595
+ color: #6c757d;\r
261
596
  }\r
262
- .view-details .size,\r
263
- .view-details .date {\r
264
- text-align: right;\r
265
- direction: rtl;\r
597
+ \r
598
+ /* \u7A7A\u72B6\u6001 - \u4EAE\u8272 */\r
599
+ .empty-message {\r
600
+ color: #6c757d;\r
601
+ font-style: italic;\r
602
+ text-align: center;\r
603
+ padding: 32px;\r
604
+ background-color: #ffffff;\r
605
+ border-radius: 8px;\r
606
+ border: 1px dashed #dee2e6;\r
607
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r
266
608
  }\r
267
609
  \r
268
- /*mobile*/\r
610
+ /* \u54CD\u5E94\u5F0F\u8BBE\u8BA1 */\r
269
611
  @media (max-width: 768px) {\r
270
612
  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
613
+ padding: 12px;\r
311
614
  }\r
312
- ul#files li:nth-child(odd) {\r
313
- background: #e0e0e0;\r
615
+ .file-row {\r
616
+ flex-direction: column;\r
314
617
  }\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
618
+ .file-column {\r
619
+ margin: 4px 0;\r
339
620
  }\r
340
621
  }\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
622
  </style>\r
348
623
  </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
624
+ <body>\r
625
+ <div class="breadcrumb">{{breadcrumb}}</div>\r
626
+ <div class="content-area">{{list}}</div>\r
356
627
  </body>\r
357
628
  </html>\r
358
629
  `;
359
630
 
360
- // src/index.ts
631
+ // src/v1_1_0_theme/index.ts
361
632
  function fileServerPlugin(options = {}) {
362
- const { enable = true } = options;
633
+ const { enable = true, root = "", theme = "dark" } = options;
363
634
  return {
364
635
  name: "vite-plugin-files-server",
365
- // 必须唯一
366
- // 核心钩子:配置开发服务器
367
636
  configureServer(server) {
368
637
  if (!enable) return;
638
+ let templateString;
639
+ try {
640
+ if (theme === "light") {
641
+ templateString = tempFolderLight_default;
642
+ } else {
643
+ templateString = tempFolderDark_default;
644
+ }
645
+ } catch (e) {
646
+ console.error("Failed to load template:", e);
647
+ templateString = tempFolderDark_default;
648
+ }
649
+ function buildGalleryTree(dirPath, baseUrl = "", depth = 0) {
650
+ try {
651
+ const files = import_fs.default.readdirSync(dirPath);
652
+ let html = "";
653
+ files.sort((a, b) => {
654
+ const aPath = import_path.default.join(dirPath, a);
655
+ const bPath = import_path.default.join(dirPath, b);
656
+ const aIsDir = import_fs.default.statSync(aPath).isDirectory();
657
+ const bIsDir = import_fs.default.statSync(bPath).isDirectory();
658
+ if (aIsDir && !bIsDir) return -1;
659
+ if (!aIsDir && bIsDir) return 1;
660
+ return a.localeCompare(b);
661
+ });
662
+ const folderItems = [];
663
+ const htmlFiles = [];
664
+ files.forEach((file) => {
665
+ const filePath = import_path.default.join(dirPath, file);
666
+ const relativePath = import_path.default.join(baseUrl, file).replace(/\\/g, "/");
667
+ try {
668
+ const stats = import_fs.default.statSync(filePath);
669
+ if (stats.isDirectory()) {
670
+ folderItems.push({ file, filePath, relativePath });
671
+ } else if (import_path.default.extname(file).toLowerCase() === ".html" || import_path.default.extname(file).toLowerCase() === ".htm") {
672
+ htmlFiles.push({ file, relativePath });
673
+ }
674
+ } catch (e) {
675
+ console.error(`Error reading ${filePath}:`, e);
676
+ }
677
+ });
678
+ folderItems.forEach(({ file, filePath, relativePath }) => {
679
+ html += `<div class="folder-item">
680
+ <a class="folder-name">${file}</a>
681
+ </div>`;
682
+ const subTree = buildGalleryTree(filePath, relativePath, depth + 1);
683
+ if (subTree) {
684
+ html += subTree;
685
+ }
686
+ });
687
+ if (htmlFiles.length > 0) {
688
+ html += `<div class="file-grid">`;
689
+ for (let i = 0; i < htmlFiles.length; i += 3) {
690
+ const rowFiles = htmlFiles.slice(i, i + 3);
691
+ html += `<div class="file-row">`;
692
+ rowFiles.forEach(({ file, relativePath }) => {
693
+ html += `<div class="file-column">
694
+ <a href="${relativePath}" class="html-file-link">${file}</a>
695
+ </div>`;
696
+ });
697
+ for (let j = rowFiles.length; j < 3; j++) {
698
+ html += `<div class="file-column empty-column"></div>`;
699
+ }
700
+ html += `</div>`;
701
+ }
702
+ html += `</div>`;
703
+ }
704
+ return html;
705
+ } catch (e) {
706
+ console.error(`Error reading directory ${dirPath}:`, e);
707
+ return "";
708
+ }
709
+ }
710
+ function generateFileList(fullPath, url) {
711
+ try {
712
+ const files = import_fs.default.readdirSync(fullPath);
713
+ let listItems = "";
714
+ const sortedFiles = files.sort((a, b) => {
715
+ const aPath = import_path.default.join(fullPath, a);
716
+ const bPath = import_path.default.join(fullPath, b);
717
+ const aIsDir = import_fs.default.statSync(aPath).isDirectory();
718
+ const bIsDir = import_fs.default.statSync(bPath).isDirectory();
719
+ if (aIsDir && !bIsDir) return -1;
720
+ if (!aIsDir && bIsDir) return 1;
721
+ return a.localeCompare(b);
722
+ });
723
+ if (url !== "/") {
724
+ const backUrl = url.split("/").slice(0, -1).join("/") || "/";
725
+ listItems += `<li><a href="${backUrl}" class="folder-link back-link">..</a></li>
726
+ `;
727
+ }
728
+ sortedFiles.forEach((file) => {
729
+ const filePath = import_path.default.join(fullPath, file);
730
+ const stats = import_fs.default.statSync(filePath);
731
+ const isDir = stats.isDirectory();
732
+ const href = import_path.default.join(url, file).replace(/\\/g, "/");
733
+ if (isDir) {
734
+ listItems += `<li><a href="${href}" class="folder-link">${file}</a></li>
735
+ `;
736
+ } else {
737
+ listItems += `<li><a href="${href}" class="file-link">${file}</a></li>
738
+ `;
739
+ }
740
+ });
741
+ return listItems;
742
+ } catch (e) {
743
+ console.error(`Error generating file list:`, e);
744
+ return "";
745
+ }
746
+ }
747
+ function generateHtmlPage(url, content, isGalleryTree = false) {
748
+ let urlSplitArray = url.split("/").filter(Boolean);
749
+ let breadcrumb = "";
750
+ if (url === "/") {
751
+ breadcrumb = '<a href="/" class="breadcrumb-link">/</a>';
752
+ } else {
753
+ breadcrumb = '<a href="/" class="breadcrumb-link">Home</a> ';
754
+ urlSplitArray.forEach((p, index) => {
755
+ const href = "/" + urlSplitArray.slice(0, index + 1).join("/");
756
+ breadcrumb += `<a href="${href}" class="breadcrumb-link"> / ${p}</a>`;
757
+ if (index < urlSplitArray.length - 1) {
758
+ breadcrumb += " ";
759
+ }
760
+ });
761
+ }
762
+ const pageTitle = url === "/" ? "/" : url;
763
+ const list = isGalleryTree ? `<div class="gallery-tree">${content || '<div class="empty-message">No HTML files found</div>'}</div>` : `
764
+ <ul class="file-list">
765
+ ${content || '<li class="empty-message">No files found</li>'}
766
+ </ul>
767
+ `;
768
+ const html = templateString.replace(/{{pageTitle}}/g, pageTitle).replace(/{{breadcrumb}}/g, breadcrumb).replace(/{{list}}/g, list);
769
+ return html;
770
+ }
369
771
  server.middlewares.use((req, res, next) => {
370
772
  const url = req.url ? decodeURIComponent(req.url.split("?")[0]) : "/";
371
773
  if (url.startsWith("/@") || url.includes("vite")) {
@@ -378,48 +780,76 @@ function fileServerPlugin(options = {}) {
378
780
  if (import_fs.default.existsSync(import_path.default.join(fullPath, "index.html"))) {
379
781
  return next();
380
782
  }
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);
783
+ let content = "";
784
+ const isGalleryTree = url === "/apps/gallery" || url.startsWith("/gallery/");
785
+ if (isGalleryTree) {
786
+ content = `<p class="back-all-link"><a href="/apps" class="back-link">..</a></p>`;
787
+ content += buildGalleryTree(fullPath, url === "/" ? "" : url);
788
+ } else {
789
+ content = generateFileList(fullPath, url);
790
+ }
791
+ const html = generateHtmlPage(url, content, isGalleryTree);
408
792
  res.setHeader("Content-Type", "text/html");
409
793
  res.end(html);
410
794
  return;
411
795
  } 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);
796
+ setStatus404(res, url, theme);
416
797
  return;
417
798
  }
418
799
  } catch (e) {
419
- console.error("File Server Plugin Error:", e);
800
+ setStatus500(res, e, theme);
801
+ return;
420
802
  }
421
803
  next();
422
804
  });
423
805
  }
424
806
  };
425
807
  }
808
+ function setStatus404(res, url, theme) {
809
+ res.statusCode = 404;
810
+ res.setHeader("Content-Type", "text/html");
811
+ if (theme === "light") {
812
+ res.end(`
813
+ <!DOCTYPE html>
814
+ <html>
815
+ <head><title>404 Not Found</title></head>
816
+ <body style="background:#f8f9fa;color:#212529;font-family:Consolas;padding:20px;">
817
+ <h1>404 Not Found</h1>
818
+ <p>The requested URL ${url} was not found on this server.</p>
819
+ <p><a href="/" style="color:#0d6efd;">Return to home</a></p>
820
+ </body>
821
+ </html>
822
+ `);
823
+ } else {
824
+ res.end(`
825
+ <!DOCTYPE html>
826
+ <html>
827
+ <head><title>404 Not Found</title></head>
828
+ <body style="background:#000;color:#fff;font-family:Consolas;padding:20px;">
829
+ <h1>404 Not Found</h1>
830
+ <p>The requested URL ${url} was not found on this server.</p>
831
+ <p><a href="/" style="color:#569cd6;">Return to home</a></p>
832
+ </body>
833
+ </html>
834
+ `);
835
+ }
836
+ }
837
+ function setStatus500(res, error, theme) {
838
+ console.error("File Server Plugin Error:", error);
839
+ res.statusCode = 500;
840
+ if (theme === "light") {
841
+ res.end(`
842
+ <!DOCTYPE html>
843
+ <html>
844
+ <head><title>500 Internal Server Error</title></head>
845
+ <body style="background:#f8f9fa;color:#212529;font-family:Consolas;padding:20px;">
846
+ <h1>500 Internal Server Error</h1>
847
+ <p>An error occurred on the server.</p>
848
+ <p><a href="/" style="color:#0d6efd;">Return to home</a></p>
849
+ </body>
850
+ </html>
851
+ `);
852
+ } else {
853
+ res.end("Internal Server Error");
854
+ }
855
+ }