@cocreate/file-server 1.18.5 → 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 +13 -0
- package/package.json +1 -1
- package/src/index.js +69 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
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
|
+
|
|
1
14
|
## [1.18.5](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.18.4...v1.18.5) (2025-09-02)
|
|
2
15
|
|
|
3
16
|
|
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
|
}
|
|
@@ -226,10 +276,7 @@ class CoCreateFileSystem {
|
|
|
226
276
|
file["cache-control"] !== null
|
|
227
277
|
) {
|
|
228
278
|
const val = file["cache-control"];
|
|
229
|
-
if (
|
|
230
|
-
typeof val === "number" ||
|
|
231
|
-
/^\s*\d+\s*$/.test(val)
|
|
232
|
-
) {
|
|
279
|
+
if (typeof val === "number" || /^\s*\d+\s*$/.test(val)) {
|
|
233
280
|
// If it's numeric (number or numeric string) treat it as max-age.
|
|
234
281
|
cacheControl = `public, max-age=${String(
|
|
235
282
|
val
|
|
@@ -239,19 +286,14 @@ class CoCreateFileSystem {
|
|
|
239
286
|
cacheControl = val;
|
|
240
287
|
}
|
|
241
288
|
} else {
|
|
242
|
-
cacheControl =
|
|
243
|
-
organization["cache-control"] ||
|
|
244
|
-
"public, max-age=3600";
|
|
289
|
+
cacheControl = organization["cache-control"] || "public, max-age=3600";
|
|
245
290
|
}
|
|
246
291
|
|
|
247
292
|
// Always override/set Cache-Control header so the response aligns with the file metadata/defaults
|
|
248
293
|
headers["Cache-Control"] = cacheControl;
|
|
249
294
|
|
|
250
|
-
if (src instanceof Uint8Array) {
|
|
251
|
-
|
|
252
|
-
} else if (Buffer.isBuffer(src)) {
|
|
253
|
-
// Buffer is fine to send — don't bail out here (previous code returned early)
|
|
254
|
-
// keep src as-is
|
|
295
|
+
if (src instanceof Uint8Array || Buffer.isBuffer(src)) {
|
|
296
|
+
// Ensure binary data is sent as-is
|
|
255
297
|
} else if (typeof src === "object") {
|
|
256
298
|
src = JSON.stringify(src);
|
|
257
299
|
}
|