@valbuild/server 0.60.16 → 0.60.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,9 +32,9 @@ export declare abstract class ValServer implements IValServer {
|
|
32
32
|
patch?: string;
|
33
33
|
schema?: string;
|
34
34
|
source?: string;
|
35
|
-
}, cookies: ValCookies<VAL_SESSION_COOKIE
|
36
|
-
postValidate(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE
|
37
|
-
postCommit(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE
|
35
|
+
}, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiTreeResponse>>;
|
36
|
+
postValidate(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiPostValidationResponse | ApiPostValidationErrorResponse>>;
|
37
|
+
postCommit(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiCommitResponse, ApiPostValidationErrorResponse>>;
|
38
38
|
private applyAllPatchesThenValidate;
|
39
39
|
private revalidateImageAndFileValidation;
|
40
40
|
protected sortPatchIds(patchesByModule: Record<ModuleId, {
|
@@ -69,7 +69,7 @@ export declare abstract class ValServer implements IValServer {
|
|
69
69
|
} | ValServerError>;
|
70
70
|
abstract getFiles(filePath: string, query: {
|
71
71
|
sha256?: string;
|
72
|
-
}, cookies: ValCookies<VAL_SESSION_COOKIE
|
72
|
+
}, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerResult<never, ReadableStream<Uint8Array>> | ValServerRedirectResult<VAL_ENABLE_COOKIE_NAME>>;
|
73
73
|
abstract session(cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ValSession>>;
|
74
74
|
abstract authorize(query: {
|
75
75
|
redirect_to?: string;
|
@@ -129,7 +129,7 @@ export interface IValServer {
|
|
129
129
|
patch?: string;
|
130
130
|
schema?: string;
|
131
131
|
source?: string;
|
132
|
-
}, cookies: ValCookies<VAL_SESSION_COOKIE
|
132
|
+
}, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiTreeResponse>>;
|
133
133
|
getPatches(query: {
|
134
134
|
id?: string[];
|
135
135
|
}, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiGetPatchResponse>>;
|
@@ -137,11 +137,11 @@ export interface IValServer {
|
|
137
137
|
deletePatches(query: {
|
138
138
|
id?: string[];
|
139
139
|
}, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiDeletePatchResponse>>;
|
140
|
-
postValidate(body: unknown, cookies: ValCookies<VAL_SESSION_COOKIE
|
141
|
-
postCommit(body: unknown, cookies: ValCookies<VAL_SESSION_COOKIE
|
140
|
+
postValidate(body: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiPostValidationResponse | ApiPostValidationErrorResponse>>;
|
141
|
+
postCommit(body: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiCommitResponse, ApiPostValidationErrorResponse>>;
|
142
142
|
getFiles(filePath: string, query: {
|
143
143
|
sha256?: string;
|
144
|
-
}, cookies: ValCookies<VAL_SESSION_COOKIE
|
144
|
+
}, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerResult<never, ReadableStream<Uint8Array>> | ValServerRedirectResult<VAL_ENABLE_COOKIE_NAME>>;
|
145
145
|
}
|
146
146
|
export declare function guessMimeTypeFromPath(filePath: string): string | null;
|
147
147
|
export declare function isCachedPatchFileOp(op: Operation): op is {
|
@@ -152,3 +152,7 @@ export declare function isCachedPatchFileOp(op: Operation): op is {
|
|
152
152
|
sha256: string;
|
153
153
|
};
|
154
154
|
};
|
155
|
+
export type RequestHeaders = {
|
156
|
+
host?: string | null;
|
157
|
+
"x-forwarded-proto"?: string | null;
|
158
|
+
};
|
@@ -1032,12 +1032,12 @@ export const IS_DEV = false;
|
|
1032
1032
|
}
|
1033
1033
|
if (modulePath.startsWith("react/jsx-runtime")) {
|
1034
1034
|
return {
|
1035
|
-
value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
|
1035
|
+
value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export const Fragment = () => { throw Error(`Cannot use 'Fragment' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
|
1036
1036
|
};
|
1037
1037
|
}
|
1038
1038
|
if (modulePath.startsWith("react")) {
|
1039
1039
|
return {
|
1040
|
-
value: "export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
|
1040
|
+
value: "export const createContext = () => new Proxy({}, { get() { return () => { throw new Error(`Cannot use 'createContext' in this file`) } } } ); export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
|
1041
1041
|
};
|
1042
1042
|
}
|
1043
1043
|
if (modulePath.includes("/ValNextProvider")) {
|
@@ -1045,6 +1045,11 @@ export const IS_DEV = false;
|
|
1045
1045
|
value: "export const ValNextProvider = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValNextProvider' in this file`) } } } )"
|
1046
1046
|
};
|
1047
1047
|
}
|
1048
|
+
if (modulePath.includes("/ValContext")) {
|
1049
|
+
return {
|
1050
|
+
value: "export const useValEvents = () => { throw Error(`Cannot use 'useValEvents' in this type of file`) }; export const ValContext = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValContext' in this file`) } } } ) export const ValEvents = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValEvents' in this file`) } } } )"
|
1051
|
+
};
|
1052
|
+
}
|
1048
1053
|
if (modulePath.includes("/ValImage")) {
|
1049
1054
|
return {
|
1050
1055
|
value: "export const ValImage = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValImage' in this file`) } } } )"
|
@@ -1110,6 +1115,11 @@ export const IS_DEV = false;
|
|
1110
1115
|
value: requestedName
|
1111
1116
|
};
|
1112
1117
|
}
|
1118
|
+
if (requestedName.includes("/ValContext")) {
|
1119
|
+
return {
|
1120
|
+
value: requestedName
|
1121
|
+
};
|
1122
|
+
}
|
1113
1123
|
if (requestedName.includes("/ValImage")) {
|
1114
1124
|
return {
|
1115
1125
|
value: requestedName
|
@@ -1419,7 +1429,7 @@ class ValServer {
|
|
1419
1429
|
}
|
1420
1430
|
async getTree(treePath,
|
1421
1431
|
// TODO: use the params: patch, schema, source now we return everything, every time
|
1422
|
-
query, cookies) {
|
1432
|
+
query, cookies, requestHeaders) {
|
1423
1433
|
const ensureRes = await this.ensureRemoteFSInitialized("getTree", cookies);
|
1424
1434
|
if (fp.result.isErr(ensureRes)) {
|
1425
1435
|
return ensureRes.error;
|
@@ -1445,7 +1455,7 @@ class ValServer {
|
|
1445
1455
|
fileUpdates = res.value.fileUpdates;
|
1446
1456
|
}
|
1447
1457
|
const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
|
1448
|
-
return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies);
|
1458
|
+
return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders);
|
1449
1459
|
}));
|
1450
1460
|
const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
|
1451
1461
|
const module = {
|
@@ -1464,19 +1474,19 @@ class ValServer {
|
|
1464
1474
|
json: apiTreeResponse
|
1465
1475
|
};
|
1466
1476
|
}
|
1467
|
-
async postValidate(rawBody, cookies) {
|
1477
|
+
async postValidate(rawBody, cookies, requestHeaders) {
|
1468
1478
|
const ensureRes = await this.ensureRemoteFSInitialized("postValidate", cookies);
|
1469
1479
|
if (fp.result.isErr(ensureRes)) {
|
1470
1480
|
return ensureRes.error;
|
1471
1481
|
}
|
1472
|
-
return this.validateThenMaybeCommit(rawBody, false, cookies);
|
1482
|
+
return this.validateThenMaybeCommit(rawBody, false, cookies, requestHeaders);
|
1473
1483
|
}
|
1474
|
-
async postCommit(rawBody, cookies) {
|
1484
|
+
async postCommit(rawBody, cookies, requestHeaders) {
|
1475
1485
|
const ensureRes = await this.ensureRemoteFSInitialized("postCommit", cookies);
|
1476
1486
|
if (fp.result.isErr(ensureRes)) {
|
1477
1487
|
return ensureRes.error;
|
1478
1488
|
}
|
1479
|
-
const res = await this.validateThenMaybeCommit(rawBody, true, cookies);
|
1489
|
+
const res = await this.validateThenMaybeCommit(rawBody, true, cookies, requestHeaders);
|
1480
1490
|
if (res.status === 200) {
|
1481
1491
|
if (res.json.validationErrors) {
|
1482
1492
|
return {
|
@@ -1499,7 +1509,7 @@ class ValServer {
|
|
1499
1509
|
|
1500
1510
|
/* */
|
1501
1511
|
|
1502
|
-
async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies) {
|
1512
|
+
async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders) {
|
1503
1513
|
const serializedModuleContent = await this.getModule(moduleId);
|
1504
1514
|
const schema = serializedModuleContent.schema;
|
1505
1515
|
const maybeSource = serializedModuleContent.source;
|
@@ -1543,7 +1553,7 @@ class ValServer {
|
|
1543
1553
|
}
|
1544
1554
|
const validationErrors = core.deserializeSchema(schema).validate(moduleId, source);
|
1545
1555
|
if (validationErrors) {
|
1546
|
-
const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies);
|
1556
|
+
const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
|
1547
1557
|
return {
|
1548
1558
|
path: moduleId,
|
1549
1559
|
schema,
|
@@ -1566,7 +1576,7 @@ class ValServer {
|
|
1566
1576
|
// The reason is that validate will be called inside QuickJS (in the future, hopefully),
|
1567
1577
|
// which does not have access to the filesystem, at least not at the time of writing this comment.
|
1568
1578
|
// If you are reading this, and we still are not using QuickJS to validate, this assumption might be wrong.
|
1569
|
-
async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies) {
|
1579
|
+
async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders) {
|
1570
1580
|
const revalidatedValidationErrors = {};
|
1571
1581
|
for (const pathStr in validationErrors) {
|
1572
1582
|
const errorSourcePath = pathStr;
|
@@ -1588,7 +1598,7 @@ class ValServer {
|
|
1588
1598
|
if (updatedFileMetadata) {
|
1589
1599
|
const fileRes = await this.getFiles(fileRef, {
|
1590
1600
|
sha256: updatedFileMetadata.sha256
|
1591
|
-
}, cookies);
|
1601
|
+
}, cookies, requestHeaders);
|
1592
1602
|
if (fileRes.status === 200 && fileRes.body) {
|
1593
1603
|
const res = new Response(fileRes.body);
|
1594
1604
|
fileBuffer = Buffer.from(await res.arrayBuffer());
|
@@ -1724,7 +1734,7 @@ class ValServer {
|
|
1724
1734
|
});
|
1725
1735
|
}
|
1726
1736
|
}
|
1727
|
-
async validateThenMaybeCommit(rawBody, commit, cookies) {
|
1737
|
+
async validateThenMaybeCommit(rawBody, commit, cookies, requestHeaders) {
|
1728
1738
|
const filterPatchesByModuleIdRes = z.z.object({
|
1729
1739
|
patches: z.z.record(z.z.array(z.z.string())).optional()
|
1730
1740
|
}).safeParse(rawBody);
|
@@ -1752,7 +1762,7 @@ class ValServer {
|
|
1752
1762
|
const moduleId = moduleIdStr;
|
1753
1763
|
const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
|
1754
1764
|
// TODO: refine to ModuleId and PatchId when parsing
|
1755
|
-
patchIdsByModuleId, patchesById, fileUpdates, true, cookies);
|
1765
|
+
patchIdsByModuleId, patchesById, fileUpdates, true, cookies, requestHeaders);
|
1756
1766
|
if (serializedModuleContent.errors) {
|
1757
1767
|
validationErrorsByModuleId[moduleId] = serializedModuleContent;
|
1758
1768
|
}
|
@@ -2970,7 +2980,7 @@ class ProxyValServer extends ValServer {
|
|
2970
2980
|
}
|
2971
2981
|
});
|
2972
2982
|
}
|
2973
|
-
async getFiles(filePath, query, cookies) {
|
2983
|
+
async getFiles(filePath, query, cookies, reqHeaders) {
|
2974
2984
|
return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
|
2975
2985
|
const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
|
2976
2986
|
if (typeof query.sha256 === "string") {
|
@@ -3002,41 +3012,19 @@ class ProxyValServer extends ValServer {
|
|
3002
3012
|
};
|
3003
3013
|
}
|
3004
3014
|
} else {
|
3005
|
-
|
3006
|
-
let buffer;
|
3007
|
-
if (fileExists) {
|
3008
|
-
buffer = await this.readStaticBinaryFile(path__namespace["default"].join(this.cwd, filePath));
|
3009
|
-
}
|
3010
|
-
if (!buffer) {
|
3015
|
+
if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
|
3011
3016
|
return {
|
3012
|
-
status:
|
3017
|
+
status: 500,
|
3013
3018
|
json: {
|
3014
|
-
message: "
|
3019
|
+
message: "Missing host or x-forwarded-proto header"
|
3015
3020
|
}
|
3016
3021
|
};
|
3017
3022
|
}
|
3018
|
-
const
|
3019
|
-
|
3020
|
-
const sha256 = getSha256(mimeType, buffer);
|
3021
|
-
if (sha256 === query.sha256) {
|
3022
|
-
return {
|
3023
|
-
status: 200,
|
3024
|
-
headers: {
|
3025
|
-
"Content-Type": mimeType,
|
3026
|
-
"Content-Length": buffer.byteLength.toString(),
|
3027
|
-
"Cache-Control": "public, max-age=31536000, immutable"
|
3028
|
-
},
|
3029
|
-
body: bufferToReadableStream(buffer)
|
3030
|
-
};
|
3031
|
-
}
|
3032
|
-
}
|
3023
|
+
const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
|
3024
|
+
const fileUrl = filePath.slice("/public".length);
|
3033
3025
|
return {
|
3034
|
-
status:
|
3035
|
-
|
3036
|
-
"Content-Type": mimeType,
|
3037
|
-
"Content-Length": buffer.byteLength.toString()
|
3038
|
-
},
|
3039
|
-
body: bufferToReadableStream(buffer)
|
3026
|
+
status: 302,
|
3027
|
+
redirectTo: new URL(fileUrl, host).toString()
|
3040
3028
|
};
|
3041
3029
|
}
|
3042
3030
|
});
|
@@ -3359,8 +3347,10 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3359
3347
|
return async req => {
|
3360
3348
|
var _req$method;
|
3361
3349
|
const valServer = await valServerPromise;
|
3362
|
-
|
3363
|
-
|
3350
|
+
const requestHeaders = {
|
3351
|
+
host: req.headers.get("host"),
|
3352
|
+
"x-forwarded-proto": req.headers.get("x-forwarded-proto")
|
3353
|
+
};
|
3364
3354
|
const url = new URL(req.url);
|
3365
3355
|
if (!url.pathname.startsWith(route)) {
|
3366
3356
|
const error = {
|
@@ -3423,16 +3413,16 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3423
3413
|
}));
|
3424
3414
|
} else if (method === "POST" && path === "/commit") {
|
3425
3415
|
const body = await req.json();
|
3426
|
-
return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE])));
|
3416
|
+
return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3427
3417
|
} else if (method === "POST" && path === "/validate") {
|
3428
3418
|
const body = await req.json();
|
3429
|
-
return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE])));
|
3419
|
+
return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3430
3420
|
} else if (method === "GET" && path.startsWith(TREE_PATH_PREFIX)) {
|
3431
3421
|
return withTreePath(path, TREE_PATH_PREFIX)(async treePath => convert(await valServer.getTree(treePath, {
|
3432
3422
|
patch: url.searchParams.get("patch") || undefined,
|
3433
3423
|
schema: url.searchParams.get("schema") || undefined,
|
3434
3424
|
source: url.searchParams.get("source") || undefined
|
3435
|
-
}, getCookies(req, [VAL_SESSION_COOKIE]))));
|
3425
|
+
}, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders)));
|
3436
3426
|
} else if (method === "GET" && path.startsWith(PATCHES_PATH_PREFIX)) {
|
3437
3427
|
return withTreePath(path, PATCHES_PATH_PREFIX)(async () => convert(await valServer.getPatches({
|
3438
3428
|
id: url.searchParams.getAll("id")
|
@@ -3448,7 +3438,7 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3448
3438
|
const treePath = path.slice(FILES_PATH_PREFIX.length);
|
3449
3439
|
return convert(await valServer.getFiles(treePath, {
|
3450
3440
|
sha256: url.searchParams.get("sha256") || undefined
|
3451
|
-
}, getCookies(req, [VAL_SESSION_COOKIE])));
|
3441
|
+
}, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3452
3442
|
} else {
|
3453
3443
|
return convert({
|
3454
3444
|
status: 404,
|
@@ -1032,12 +1032,12 @@ export const IS_DEV = false;
|
|
1032
1032
|
}
|
1033
1033
|
if (modulePath.startsWith("react/jsx-runtime")) {
|
1034
1034
|
return {
|
1035
|
-
value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
|
1035
|
+
value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export const Fragment = () => { throw Error(`Cannot use 'Fragment' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
|
1036
1036
|
};
|
1037
1037
|
}
|
1038
1038
|
if (modulePath.startsWith("react")) {
|
1039
1039
|
return {
|
1040
|
-
value: "export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
|
1040
|
+
value: "export const createContext = () => new Proxy({}, { get() { return () => { throw new Error(`Cannot use 'createContext' in this file`) } } } ); export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
|
1041
1041
|
};
|
1042
1042
|
}
|
1043
1043
|
if (modulePath.includes("/ValNextProvider")) {
|
@@ -1045,6 +1045,11 @@ export const IS_DEV = false;
|
|
1045
1045
|
value: "export const ValNextProvider = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValNextProvider' in this file`) } } } )"
|
1046
1046
|
};
|
1047
1047
|
}
|
1048
|
+
if (modulePath.includes("/ValContext")) {
|
1049
|
+
return {
|
1050
|
+
value: "export const useValEvents = () => { throw Error(`Cannot use 'useValEvents' in this type of file`) }; export const ValContext = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValContext' in this file`) } } } ) export const ValEvents = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValEvents' in this file`) } } } )"
|
1051
|
+
};
|
1052
|
+
}
|
1048
1053
|
if (modulePath.includes("/ValImage")) {
|
1049
1054
|
return {
|
1050
1055
|
value: "export const ValImage = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValImage' in this file`) } } } )"
|
@@ -1110,6 +1115,11 @@ export const IS_DEV = false;
|
|
1110
1115
|
value: requestedName
|
1111
1116
|
};
|
1112
1117
|
}
|
1118
|
+
if (requestedName.includes("/ValContext")) {
|
1119
|
+
return {
|
1120
|
+
value: requestedName
|
1121
|
+
};
|
1122
|
+
}
|
1113
1123
|
if (requestedName.includes("/ValImage")) {
|
1114
1124
|
return {
|
1115
1125
|
value: requestedName
|
@@ -1419,7 +1429,7 @@ class ValServer {
|
|
1419
1429
|
}
|
1420
1430
|
async getTree(treePath,
|
1421
1431
|
// TODO: use the params: patch, schema, source now we return everything, every time
|
1422
|
-
query, cookies) {
|
1432
|
+
query, cookies, requestHeaders) {
|
1423
1433
|
const ensureRes = await this.ensureRemoteFSInitialized("getTree", cookies);
|
1424
1434
|
if (fp.result.isErr(ensureRes)) {
|
1425
1435
|
return ensureRes.error;
|
@@ -1445,7 +1455,7 @@ class ValServer {
|
|
1445
1455
|
fileUpdates = res.value.fileUpdates;
|
1446
1456
|
}
|
1447
1457
|
const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
|
1448
|
-
return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies);
|
1458
|
+
return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders);
|
1449
1459
|
}));
|
1450
1460
|
const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
|
1451
1461
|
const module = {
|
@@ -1464,19 +1474,19 @@ class ValServer {
|
|
1464
1474
|
json: apiTreeResponse
|
1465
1475
|
};
|
1466
1476
|
}
|
1467
|
-
async postValidate(rawBody, cookies) {
|
1477
|
+
async postValidate(rawBody, cookies, requestHeaders) {
|
1468
1478
|
const ensureRes = await this.ensureRemoteFSInitialized("postValidate", cookies);
|
1469
1479
|
if (fp.result.isErr(ensureRes)) {
|
1470
1480
|
return ensureRes.error;
|
1471
1481
|
}
|
1472
|
-
return this.validateThenMaybeCommit(rawBody, false, cookies);
|
1482
|
+
return this.validateThenMaybeCommit(rawBody, false, cookies, requestHeaders);
|
1473
1483
|
}
|
1474
|
-
async postCommit(rawBody, cookies) {
|
1484
|
+
async postCommit(rawBody, cookies, requestHeaders) {
|
1475
1485
|
const ensureRes = await this.ensureRemoteFSInitialized("postCommit", cookies);
|
1476
1486
|
if (fp.result.isErr(ensureRes)) {
|
1477
1487
|
return ensureRes.error;
|
1478
1488
|
}
|
1479
|
-
const res = await this.validateThenMaybeCommit(rawBody, true, cookies);
|
1489
|
+
const res = await this.validateThenMaybeCommit(rawBody, true, cookies, requestHeaders);
|
1480
1490
|
if (res.status === 200) {
|
1481
1491
|
if (res.json.validationErrors) {
|
1482
1492
|
return {
|
@@ -1499,7 +1509,7 @@ class ValServer {
|
|
1499
1509
|
|
1500
1510
|
/* */
|
1501
1511
|
|
1502
|
-
async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies) {
|
1512
|
+
async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders) {
|
1503
1513
|
const serializedModuleContent = await this.getModule(moduleId);
|
1504
1514
|
const schema = serializedModuleContent.schema;
|
1505
1515
|
const maybeSource = serializedModuleContent.source;
|
@@ -1543,7 +1553,7 @@ class ValServer {
|
|
1543
1553
|
}
|
1544
1554
|
const validationErrors = core.deserializeSchema(schema).validate(moduleId, source);
|
1545
1555
|
if (validationErrors) {
|
1546
|
-
const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies);
|
1556
|
+
const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
|
1547
1557
|
return {
|
1548
1558
|
path: moduleId,
|
1549
1559
|
schema,
|
@@ -1566,7 +1576,7 @@ class ValServer {
|
|
1566
1576
|
// The reason is that validate will be called inside QuickJS (in the future, hopefully),
|
1567
1577
|
// which does not have access to the filesystem, at least not at the time of writing this comment.
|
1568
1578
|
// If you are reading this, and we still are not using QuickJS to validate, this assumption might be wrong.
|
1569
|
-
async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies) {
|
1579
|
+
async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders) {
|
1570
1580
|
const revalidatedValidationErrors = {};
|
1571
1581
|
for (const pathStr in validationErrors) {
|
1572
1582
|
const errorSourcePath = pathStr;
|
@@ -1588,7 +1598,7 @@ class ValServer {
|
|
1588
1598
|
if (updatedFileMetadata) {
|
1589
1599
|
const fileRes = await this.getFiles(fileRef, {
|
1590
1600
|
sha256: updatedFileMetadata.sha256
|
1591
|
-
}, cookies);
|
1601
|
+
}, cookies, requestHeaders);
|
1592
1602
|
if (fileRes.status === 200 && fileRes.body) {
|
1593
1603
|
const res = new Response(fileRes.body);
|
1594
1604
|
fileBuffer = Buffer.from(await res.arrayBuffer());
|
@@ -1724,7 +1734,7 @@ class ValServer {
|
|
1724
1734
|
});
|
1725
1735
|
}
|
1726
1736
|
}
|
1727
|
-
async validateThenMaybeCommit(rawBody, commit, cookies) {
|
1737
|
+
async validateThenMaybeCommit(rawBody, commit, cookies, requestHeaders) {
|
1728
1738
|
const filterPatchesByModuleIdRes = z.z.object({
|
1729
1739
|
patches: z.z.record(z.z.array(z.z.string())).optional()
|
1730
1740
|
}).safeParse(rawBody);
|
@@ -1752,7 +1762,7 @@ class ValServer {
|
|
1752
1762
|
const moduleId = moduleIdStr;
|
1753
1763
|
const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
|
1754
1764
|
// TODO: refine to ModuleId and PatchId when parsing
|
1755
|
-
patchIdsByModuleId, patchesById, fileUpdates, true, cookies);
|
1765
|
+
patchIdsByModuleId, patchesById, fileUpdates, true, cookies, requestHeaders);
|
1756
1766
|
if (serializedModuleContent.errors) {
|
1757
1767
|
validationErrorsByModuleId[moduleId] = serializedModuleContent;
|
1758
1768
|
}
|
@@ -2970,7 +2980,7 @@ class ProxyValServer extends ValServer {
|
|
2970
2980
|
}
|
2971
2981
|
});
|
2972
2982
|
}
|
2973
|
-
async getFiles(filePath, query, cookies) {
|
2983
|
+
async getFiles(filePath, query, cookies, reqHeaders) {
|
2974
2984
|
return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
|
2975
2985
|
const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
|
2976
2986
|
if (typeof query.sha256 === "string") {
|
@@ -3002,41 +3012,19 @@ class ProxyValServer extends ValServer {
|
|
3002
3012
|
};
|
3003
3013
|
}
|
3004
3014
|
} else {
|
3005
|
-
|
3006
|
-
let buffer;
|
3007
|
-
if (fileExists) {
|
3008
|
-
buffer = await this.readStaticBinaryFile(path__namespace["default"].join(this.cwd, filePath));
|
3009
|
-
}
|
3010
|
-
if (!buffer) {
|
3015
|
+
if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
|
3011
3016
|
return {
|
3012
|
-
status:
|
3017
|
+
status: 500,
|
3013
3018
|
json: {
|
3014
|
-
message: "
|
3019
|
+
message: "Missing host or x-forwarded-proto header"
|
3015
3020
|
}
|
3016
3021
|
};
|
3017
3022
|
}
|
3018
|
-
const
|
3019
|
-
|
3020
|
-
const sha256 = getSha256(mimeType, buffer);
|
3021
|
-
if (sha256 === query.sha256) {
|
3022
|
-
return {
|
3023
|
-
status: 200,
|
3024
|
-
headers: {
|
3025
|
-
"Content-Type": mimeType,
|
3026
|
-
"Content-Length": buffer.byteLength.toString(),
|
3027
|
-
"Cache-Control": "public, max-age=31536000, immutable"
|
3028
|
-
},
|
3029
|
-
body: bufferToReadableStream(buffer)
|
3030
|
-
};
|
3031
|
-
}
|
3032
|
-
}
|
3023
|
+
const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
|
3024
|
+
const fileUrl = filePath.slice("/public".length);
|
3033
3025
|
return {
|
3034
|
-
status:
|
3035
|
-
|
3036
|
-
"Content-Type": mimeType,
|
3037
|
-
"Content-Length": buffer.byteLength.toString()
|
3038
|
-
},
|
3039
|
-
body: bufferToReadableStream(buffer)
|
3026
|
+
status: 302,
|
3027
|
+
redirectTo: new URL(fileUrl, host).toString()
|
3040
3028
|
};
|
3041
3029
|
}
|
3042
3030
|
});
|
@@ -3359,8 +3347,10 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3359
3347
|
return async req => {
|
3360
3348
|
var _req$method;
|
3361
3349
|
const valServer = await valServerPromise;
|
3362
|
-
|
3363
|
-
|
3350
|
+
const requestHeaders = {
|
3351
|
+
host: req.headers.get("host"),
|
3352
|
+
"x-forwarded-proto": req.headers.get("x-forwarded-proto")
|
3353
|
+
};
|
3364
3354
|
const url = new URL(req.url);
|
3365
3355
|
if (!url.pathname.startsWith(route)) {
|
3366
3356
|
const error = {
|
@@ -3423,16 +3413,16 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3423
3413
|
}));
|
3424
3414
|
} else if (method === "POST" && path === "/commit") {
|
3425
3415
|
const body = await req.json();
|
3426
|
-
return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE])));
|
3416
|
+
return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3427
3417
|
} else if (method === "POST" && path === "/validate") {
|
3428
3418
|
const body = await req.json();
|
3429
|
-
return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE])));
|
3419
|
+
return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3430
3420
|
} else if (method === "GET" && path.startsWith(TREE_PATH_PREFIX)) {
|
3431
3421
|
return withTreePath(path, TREE_PATH_PREFIX)(async treePath => convert(await valServer.getTree(treePath, {
|
3432
3422
|
patch: url.searchParams.get("patch") || undefined,
|
3433
3423
|
schema: url.searchParams.get("schema") || undefined,
|
3434
3424
|
source: url.searchParams.get("source") || undefined
|
3435
|
-
}, getCookies(req, [VAL_SESSION_COOKIE]))));
|
3425
|
+
}, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders)));
|
3436
3426
|
} else if (method === "GET" && path.startsWith(PATCHES_PATH_PREFIX)) {
|
3437
3427
|
return withTreePath(path, PATCHES_PATH_PREFIX)(async () => convert(await valServer.getPatches({
|
3438
3428
|
id: url.searchParams.getAll("id")
|
@@ -3448,7 +3438,7 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3448
3438
|
const treePath = path.slice(FILES_PATH_PREFIX.length);
|
3449
3439
|
return convert(await valServer.getFiles(treePath, {
|
3450
3440
|
sha256: url.searchParams.get("sha256") || undefined
|
3451
|
-
}, getCookies(req, [VAL_SESSION_COOKIE])));
|
3441
|
+
}, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3452
3442
|
} else {
|
3453
3443
|
return convert({
|
3454
3444
|
status: 404,
|
@@ -1001,12 +1001,12 @@ export const IS_DEV = false;
|
|
1001
1001
|
}
|
1002
1002
|
if (modulePath.startsWith("react/jsx-runtime")) {
|
1003
1003
|
return {
|
1004
|
-
value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
|
1004
|
+
value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export const Fragment = () => { throw Error(`Cannot use 'Fragment' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
|
1005
1005
|
};
|
1006
1006
|
}
|
1007
1007
|
if (modulePath.startsWith("react")) {
|
1008
1008
|
return {
|
1009
|
-
value: "export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
|
1009
|
+
value: "export const createContext = () => new Proxy({}, { get() { return () => { throw new Error(`Cannot use 'createContext' in this file`) } } } ); export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
|
1010
1010
|
};
|
1011
1011
|
}
|
1012
1012
|
if (modulePath.includes("/ValNextProvider")) {
|
@@ -1014,6 +1014,11 @@ export const IS_DEV = false;
|
|
1014
1014
|
value: "export const ValNextProvider = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValNextProvider' in this file`) } } } )"
|
1015
1015
|
};
|
1016
1016
|
}
|
1017
|
+
if (modulePath.includes("/ValContext")) {
|
1018
|
+
return {
|
1019
|
+
value: "export const useValEvents = () => { throw Error(`Cannot use 'useValEvents' in this type of file`) }; export const ValContext = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValContext' in this file`) } } } ) export const ValEvents = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValEvents' in this file`) } } } )"
|
1020
|
+
};
|
1021
|
+
}
|
1017
1022
|
if (modulePath.includes("/ValImage")) {
|
1018
1023
|
return {
|
1019
1024
|
value: "export const ValImage = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValImage' in this file`) } } } )"
|
@@ -1079,6 +1084,11 @@ export const IS_DEV = false;
|
|
1079
1084
|
value: requestedName
|
1080
1085
|
};
|
1081
1086
|
}
|
1087
|
+
if (requestedName.includes("/ValContext")) {
|
1088
|
+
return {
|
1089
|
+
value: requestedName
|
1090
|
+
};
|
1091
|
+
}
|
1082
1092
|
if (requestedName.includes("/ValImage")) {
|
1083
1093
|
return {
|
1084
1094
|
value: requestedName
|
@@ -1388,7 +1398,7 @@ class ValServer {
|
|
1388
1398
|
}
|
1389
1399
|
async getTree(treePath,
|
1390
1400
|
// TODO: use the params: patch, schema, source now we return everything, every time
|
1391
|
-
query, cookies) {
|
1401
|
+
query, cookies, requestHeaders) {
|
1392
1402
|
const ensureRes = await this.ensureRemoteFSInitialized("getTree", cookies);
|
1393
1403
|
if (result.isErr(ensureRes)) {
|
1394
1404
|
return ensureRes.error;
|
@@ -1414,7 +1424,7 @@ class ValServer {
|
|
1414
1424
|
fileUpdates = res.value.fileUpdates;
|
1415
1425
|
}
|
1416
1426
|
const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
|
1417
|
-
return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies);
|
1427
|
+
return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders);
|
1418
1428
|
}));
|
1419
1429
|
const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
|
1420
1430
|
const module = {
|
@@ -1433,19 +1443,19 @@ class ValServer {
|
|
1433
1443
|
json: apiTreeResponse
|
1434
1444
|
};
|
1435
1445
|
}
|
1436
|
-
async postValidate(rawBody, cookies) {
|
1446
|
+
async postValidate(rawBody, cookies, requestHeaders) {
|
1437
1447
|
const ensureRes = await this.ensureRemoteFSInitialized("postValidate", cookies);
|
1438
1448
|
if (result.isErr(ensureRes)) {
|
1439
1449
|
return ensureRes.error;
|
1440
1450
|
}
|
1441
|
-
return this.validateThenMaybeCommit(rawBody, false, cookies);
|
1451
|
+
return this.validateThenMaybeCommit(rawBody, false, cookies, requestHeaders);
|
1442
1452
|
}
|
1443
|
-
async postCommit(rawBody, cookies) {
|
1453
|
+
async postCommit(rawBody, cookies, requestHeaders) {
|
1444
1454
|
const ensureRes = await this.ensureRemoteFSInitialized("postCommit", cookies);
|
1445
1455
|
if (result.isErr(ensureRes)) {
|
1446
1456
|
return ensureRes.error;
|
1447
1457
|
}
|
1448
|
-
const res = await this.validateThenMaybeCommit(rawBody, true, cookies);
|
1458
|
+
const res = await this.validateThenMaybeCommit(rawBody, true, cookies, requestHeaders);
|
1449
1459
|
if (res.status === 200) {
|
1450
1460
|
if (res.json.validationErrors) {
|
1451
1461
|
return {
|
@@ -1468,7 +1478,7 @@ class ValServer {
|
|
1468
1478
|
|
1469
1479
|
/* */
|
1470
1480
|
|
1471
|
-
async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies) {
|
1481
|
+
async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders) {
|
1472
1482
|
const serializedModuleContent = await this.getModule(moduleId);
|
1473
1483
|
const schema = serializedModuleContent.schema;
|
1474
1484
|
const maybeSource = serializedModuleContent.source;
|
@@ -1512,7 +1522,7 @@ class ValServer {
|
|
1512
1522
|
}
|
1513
1523
|
const validationErrors = deserializeSchema(schema).validate(moduleId, source);
|
1514
1524
|
if (validationErrors) {
|
1515
|
-
const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies);
|
1525
|
+
const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
|
1516
1526
|
return {
|
1517
1527
|
path: moduleId,
|
1518
1528
|
schema,
|
@@ -1535,7 +1545,7 @@ class ValServer {
|
|
1535
1545
|
// The reason is that validate will be called inside QuickJS (in the future, hopefully),
|
1536
1546
|
// which does not have access to the filesystem, at least not at the time of writing this comment.
|
1537
1547
|
// If you are reading this, and we still are not using QuickJS to validate, this assumption might be wrong.
|
1538
|
-
async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies) {
|
1548
|
+
async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders) {
|
1539
1549
|
const revalidatedValidationErrors = {};
|
1540
1550
|
for (const pathStr in validationErrors) {
|
1541
1551
|
const errorSourcePath = pathStr;
|
@@ -1557,7 +1567,7 @@ class ValServer {
|
|
1557
1567
|
if (updatedFileMetadata) {
|
1558
1568
|
const fileRes = await this.getFiles(fileRef, {
|
1559
1569
|
sha256: updatedFileMetadata.sha256
|
1560
|
-
}, cookies);
|
1570
|
+
}, cookies, requestHeaders);
|
1561
1571
|
if (fileRes.status === 200 && fileRes.body) {
|
1562
1572
|
const res = new Response(fileRes.body);
|
1563
1573
|
fileBuffer = Buffer.from(await res.arrayBuffer());
|
@@ -1693,7 +1703,7 @@ class ValServer {
|
|
1693
1703
|
});
|
1694
1704
|
}
|
1695
1705
|
}
|
1696
|
-
async validateThenMaybeCommit(rawBody, commit, cookies) {
|
1706
|
+
async validateThenMaybeCommit(rawBody, commit, cookies, requestHeaders) {
|
1697
1707
|
const filterPatchesByModuleIdRes = z$1.object({
|
1698
1708
|
patches: z$1.record(z$1.array(z$1.string())).optional()
|
1699
1709
|
}).safeParse(rawBody);
|
@@ -1721,7 +1731,7 @@ class ValServer {
|
|
1721
1731
|
const moduleId = moduleIdStr;
|
1722
1732
|
const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
|
1723
1733
|
// TODO: refine to ModuleId and PatchId when parsing
|
1724
|
-
patchIdsByModuleId, patchesById, fileUpdates, true, cookies);
|
1734
|
+
patchIdsByModuleId, patchesById, fileUpdates, true, cookies, requestHeaders);
|
1725
1735
|
if (serializedModuleContent.errors) {
|
1726
1736
|
validationErrorsByModuleId[moduleId] = serializedModuleContent;
|
1727
1737
|
}
|
@@ -2939,7 +2949,7 @@ class ProxyValServer extends ValServer {
|
|
2939
2949
|
}
|
2940
2950
|
});
|
2941
2951
|
}
|
2942
|
-
async getFiles(filePath, query, cookies) {
|
2952
|
+
async getFiles(filePath, query, cookies, reqHeaders) {
|
2943
2953
|
return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
|
2944
2954
|
const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
|
2945
2955
|
if (typeof query.sha256 === "string") {
|
@@ -2971,41 +2981,19 @@ class ProxyValServer extends ValServer {
|
|
2971
2981
|
};
|
2972
2982
|
}
|
2973
2983
|
} else {
|
2974
|
-
|
2975
|
-
let buffer;
|
2976
|
-
if (fileExists) {
|
2977
|
-
buffer = await this.readStaticBinaryFile(path__default.join(this.cwd, filePath));
|
2978
|
-
}
|
2979
|
-
if (!buffer) {
|
2984
|
+
if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
|
2980
2985
|
return {
|
2981
|
-
status:
|
2986
|
+
status: 500,
|
2982
2987
|
json: {
|
2983
|
-
message: "
|
2988
|
+
message: "Missing host or x-forwarded-proto header"
|
2984
2989
|
}
|
2985
2990
|
};
|
2986
2991
|
}
|
2987
|
-
const
|
2988
|
-
|
2989
|
-
const sha256 = getSha256(mimeType, buffer);
|
2990
|
-
if (sha256 === query.sha256) {
|
2991
|
-
return {
|
2992
|
-
status: 200,
|
2993
|
-
headers: {
|
2994
|
-
"Content-Type": mimeType,
|
2995
|
-
"Content-Length": buffer.byteLength.toString(),
|
2996
|
-
"Cache-Control": "public, max-age=31536000, immutable"
|
2997
|
-
},
|
2998
|
-
body: bufferToReadableStream(buffer)
|
2999
|
-
};
|
3000
|
-
}
|
3001
|
-
}
|
2992
|
+
const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
|
2993
|
+
const fileUrl = filePath.slice("/public".length);
|
3002
2994
|
return {
|
3003
|
-
status:
|
3004
|
-
|
3005
|
-
"Content-Type": mimeType,
|
3006
|
-
"Content-Length": buffer.byteLength.toString()
|
3007
|
-
},
|
3008
|
-
body: bufferToReadableStream(buffer)
|
2995
|
+
status: 302,
|
2996
|
+
redirectTo: new URL(fileUrl, host).toString()
|
3009
2997
|
};
|
3010
2998
|
}
|
3011
2999
|
});
|
@@ -3328,8 +3316,10 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3328
3316
|
return async req => {
|
3329
3317
|
var _req$method;
|
3330
3318
|
const valServer = await valServerPromise;
|
3331
|
-
|
3332
|
-
|
3319
|
+
const requestHeaders = {
|
3320
|
+
host: req.headers.get("host"),
|
3321
|
+
"x-forwarded-proto": req.headers.get("x-forwarded-proto")
|
3322
|
+
};
|
3333
3323
|
const url = new URL(req.url);
|
3334
3324
|
if (!url.pathname.startsWith(route)) {
|
3335
3325
|
const error = {
|
@@ -3392,16 +3382,16 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3392
3382
|
}));
|
3393
3383
|
} else if (method === "POST" && path === "/commit") {
|
3394
3384
|
const body = await req.json();
|
3395
|
-
return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE])));
|
3385
|
+
return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3396
3386
|
} else if (method === "POST" && path === "/validate") {
|
3397
3387
|
const body = await req.json();
|
3398
|
-
return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE])));
|
3388
|
+
return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3399
3389
|
} else if (method === "GET" && path.startsWith(TREE_PATH_PREFIX)) {
|
3400
3390
|
return withTreePath(path, TREE_PATH_PREFIX)(async treePath => convert(await valServer.getTree(treePath, {
|
3401
3391
|
patch: url.searchParams.get("patch") || undefined,
|
3402
3392
|
schema: url.searchParams.get("schema") || undefined,
|
3403
3393
|
source: url.searchParams.get("source") || undefined
|
3404
|
-
}, getCookies(req, [VAL_SESSION_COOKIE]))));
|
3394
|
+
}, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders)));
|
3405
3395
|
} else if (method === "GET" && path.startsWith(PATCHES_PATH_PREFIX)) {
|
3406
3396
|
return withTreePath(path, PATCHES_PATH_PREFIX)(async () => convert(await valServer.getPatches({
|
3407
3397
|
id: url.searchParams.getAll("id")
|
@@ -3417,7 +3407,7 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
3417
3407
|
const treePath = path.slice(FILES_PATH_PREFIX.length);
|
3418
3408
|
return convert(await valServer.getFiles(treePath, {
|
3419
3409
|
sha256: url.searchParams.get("sha256") || undefined
|
3420
|
-
}, getCookies(req, [VAL_SESSION_COOKIE])));
|
3410
|
+
}, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
|
3421
3411
|
} else {
|
3422
3412
|
return convert({
|
3423
3413
|
status: 404,
|
package/package.json
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
"./package.json": "./package.json"
|
13
13
|
},
|
14
14
|
"types": "dist/valbuild-server.cjs.d.ts",
|
15
|
-
"version": "0.60.
|
15
|
+
"version": "0.60.18",
|
16
16
|
"scripts": {
|
17
17
|
"typecheck": "tsc --noEmit",
|
18
18
|
"test": "jest",
|
@@ -24,9 +24,9 @@
|
|
24
24
|
"concurrently": "^7.6.0"
|
25
25
|
},
|
26
26
|
"dependencies": {
|
27
|
-
"@valbuild/core": "~0.60.
|
28
|
-
"@valbuild/shared": "~0.60.
|
29
|
-
"@valbuild/ui": "~0.60.
|
27
|
+
"@valbuild/core": "~0.60.18",
|
28
|
+
"@valbuild/shared": "~0.60.18",
|
29
|
+
"@valbuild/ui": "~0.60.18",
|
30
30
|
"express": "^4.18.2",
|
31
31
|
"image-size": "^1.0.2",
|
32
32
|
"minimatch": "^3.0.4",
|