@cocreate/file-server 1.18.4 → 1.18.6
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/CHANGELOG.md +20 -0
- package/package.json +1 -1
- package/src/index.js +92 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## [1.18.6](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.18.5...v1.18.6) (2025-10-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add handling for font files and improve error processing in CoCreateFileSystem ([de3c618](https://github.com/CoCreate-app/CoCreate-file-server/commit/de3c6186eebef00bfb6c237dc6d5c7435773ba41))
|
|
7
|
+
* correct pathname handling by ensuring language region is prefixed with a slash ([680832b](https://github.com/CoCreate-app/CoCreate-file-server/commit/680832b7cf710f48afd28a2fe2b425c7eb41d4b1))
|
|
8
|
+
* enhance language detection in pathname processing and support Accept-Language header ([cccc35d](https://github.com/CoCreate-app/CoCreate-file-server/commit/cccc35dc68107a5f39fbf2af053181825eb252fa))
|
|
9
|
+
* enhance language handling in pathname processing and improve file retrieval logic ([b499141](https://github.com/CoCreate-app/CoCreate-file-server/commit/b499141fe599e095a3d0a051ccede4b6131d3fa7))
|
|
10
|
+
* simplify pathname query handling in CoCreateFileSystem ([1632670](https://github.com/CoCreate-app/CoCreate-file-server/commit/1632670b17b7c76775094b2726178248e4e903d6))
|
|
11
|
+
* streamline HTML rendering logic by removing unnecessary language handling ([924041b](https://github.com/CoCreate-app/CoCreate-file-server/commit/924041bc4fba30fbeef5bcd85b6fe42f811af695))
|
|
12
|
+
* streamline language handling in pathname processing and simplify file retrieval logic ([fd43225](https://github.com/CoCreate-app/CoCreate-file-server/commit/fd432258880c33ba9f417d7a0d40eba8a9997863))
|
|
13
|
+
|
|
14
|
+
## [1.18.5](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.18.4...v1.18.5) (2025-09-02)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* enhance Cache-Control header handling in sendResponse function ([7b6f29c](https://github.com/CoCreate-app/CoCreate-file-server/commit/7b6f29cbe1511be4fa41670db55747e8ad61bc00))
|
|
20
|
+
|
|
1
21
|
## [1.18.4](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.18.3...v1.18.4) (2025-09-01)
|
|
2
22
|
|
|
3
23
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -86,15 +86,32 @@ class CoCreateFileSystem {
|
|
|
86
86
|
if (!directory.includes(".")) pathname += "/index.html";
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
const
|
|
89
|
+
// Match both /en/ and /en-US/ style URLs
|
|
90
|
+
const bcp47Regex = /^\/([a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})?)\//;
|
|
91
|
+
const langMatch = pathname.match(bcp47Regex);
|
|
91
92
|
let lang, langRegion;
|
|
92
|
-
if (
|
|
93
|
-
langRegion =
|
|
93
|
+
if (langMatch) {
|
|
94
|
+
langRegion = langMatch[1];
|
|
94
95
|
lang = langRegion.split("-")[0]; // Get just the base language (e.g., 'en', 'es', 'fr')
|
|
95
|
-
let
|
|
96
|
-
data.$filter.query.pathname =
|
|
96
|
+
let basePathname = pathname.replace("/" + langRegion, "");
|
|
97
|
+
data.$filter.query.pathname = basePathname;
|
|
97
98
|
} else {
|
|
99
|
+
// No language in URL, try Accept-Language header
|
|
100
|
+
let acceptLang = req.headers && req.headers["accept-language"];
|
|
101
|
+
if (acceptLang) {
|
|
102
|
+
// Parse the Accept-Language header, get the first language
|
|
103
|
+
let preferred = acceptLang.split(",")[0].trim();
|
|
104
|
+
if (preferred) {
|
|
105
|
+
lang = preferred.split("-")[0];
|
|
106
|
+
langRegion = preferred;
|
|
107
|
+
// --- BEGIN OPTIONAL REDIRECT ---
|
|
108
|
+
// Uncomment to enable automatic redirect to language-specific path
|
|
109
|
+
// let newPath = `/${preferred}${pathname.startsWith('/') ? '' : '/'}${pathname.replace(/^\//, '')}`;
|
|
110
|
+
// res.writeHead(302, { Location: newPath });
|
|
111
|
+
// return res.end();
|
|
112
|
+
// --- END OPTIONAL REDIRECT ---
|
|
113
|
+
}
|
|
114
|
+
}
|
|
98
115
|
data.$filter.query.pathname = pathname;
|
|
99
116
|
}
|
|
100
117
|
|
|
@@ -182,7 +199,39 @@ class CoCreateFileSystem {
|
|
|
182
199
|
|
|
183
200
|
let contentType = file["content-type"] || "text/html";
|
|
184
201
|
|
|
185
|
-
|
|
202
|
+
// Add handling for font files
|
|
203
|
+
if (contentType.startsWith("font/") || /\.(woff2?|ttf|otf)$/i.test(pathname)) {
|
|
204
|
+
try {
|
|
205
|
+
if (typeof src === "string") {
|
|
206
|
+
if (/^([A-Za-z0-9+/]+={0,2})$/.test(src)) {
|
|
207
|
+
// Decode base64-encoded font data
|
|
208
|
+
src = Buffer.from(src, "base64");
|
|
209
|
+
} else {
|
|
210
|
+
throw new Error("Font data is not valid base64");
|
|
211
|
+
}
|
|
212
|
+
} else if (typeof src === "object" && src.src) {
|
|
213
|
+
// Handle case where src is an object containing base64 data
|
|
214
|
+
if (/^([A-Za-z0-9+/]+={0,2})$/.test(src.src)) {
|
|
215
|
+
src = Buffer.from(src.src, "base64");
|
|
216
|
+
} else {
|
|
217
|
+
throw new Error("Font data inside object is not valid base64");
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
throw new Error("Font data is not a valid base64 string or object");
|
|
221
|
+
}
|
|
222
|
+
} catch (err) {
|
|
223
|
+
console.error("Error processing font file:", {
|
|
224
|
+
message: err.message,
|
|
225
|
+
contentType,
|
|
226
|
+
srcType: typeof src,
|
|
227
|
+
srcPreview: typeof src === "string" ? src.slice(0, 50) : null
|
|
228
|
+
});
|
|
229
|
+
let pageNotFound = await getDefaultFile("/404.html");
|
|
230
|
+
return sendResponse(pageNotFound.object[0].src, 404, {
|
|
231
|
+
"Content-Type": "text/html"
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
} else if (
|
|
186
235
|
/^data:image\/[a-zA-Z0-9+.-]+;base64,([A-Za-z0-9+/]+={0,2})$/.test(
|
|
187
236
|
src
|
|
188
237
|
)
|
|
@@ -193,14 +242,15 @@ class CoCreateFileSystem {
|
|
|
193
242
|
src = Buffer.from(src, "base64");
|
|
194
243
|
} else if (contentType === "text/html") {
|
|
195
244
|
try {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
245
|
+
let data = {};
|
|
246
|
+
|
|
247
|
+
src = await this.render.HTML(
|
|
248
|
+
file,
|
|
249
|
+
organization,
|
|
250
|
+
urlObject,
|
|
251
|
+
langRegion,
|
|
252
|
+
lang
|
|
253
|
+
);
|
|
204
254
|
} catch (err) {
|
|
205
255
|
console.warn("server-side-render: " + err.message);
|
|
206
256
|
}
|
|
@@ -217,11 +267,33 @@ class CoCreateFileSystem {
|
|
|
217
267
|
|
|
218
268
|
function sendResponse(src, statusCode, headers) {
|
|
219
269
|
try {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
270
|
+
let cacheControl;
|
|
271
|
+
if (statusCode >= 400) {
|
|
272
|
+
cacheControl = "no-cache, no-store, must-revalidate";
|
|
273
|
+
} else if (
|
|
274
|
+
file &&
|
|
275
|
+
file["cache-control"] !== undefined &&
|
|
276
|
+
file["cache-control"] !== null
|
|
277
|
+
) {
|
|
278
|
+
const val = file["cache-control"];
|
|
279
|
+
if (typeof val === "number" || /^\s*\d+\s*$/.test(val)) {
|
|
280
|
+
// If it's numeric (number or numeric string) treat it as max-age.
|
|
281
|
+
cacheControl = `public, max-age=${String(
|
|
282
|
+
val
|
|
283
|
+
).trim()};`;
|
|
284
|
+
} else {
|
|
285
|
+
// use the value verbatim (allow full Cache-Control strings like "no-cache" or "public, max-age=600")
|
|
286
|
+
cacheControl = val;
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
cacheControl = organization["cache-control"] || "public, max-age=3600";
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Always override/set Cache-Control header so the response aligns with the file metadata/defaults
|
|
293
|
+
headers["Cache-Control"] = cacheControl;
|
|
294
|
+
|
|
295
|
+
if (src instanceof Uint8Array || Buffer.isBuffer(src)) {
|
|
296
|
+
// Ensure binary data is sent as-is
|
|
225
297
|
} else if (typeof src === "object") {
|
|
226
298
|
src = JSON.stringify(src);
|
|
227
299
|
}
|