78 lines
2.7 KiB
JavaScript
78 lines
2.7 KiB
JavaScript
import { getQuery, createError } from "h3";
|
|
import { jsonParse, jsonStringify } from "./json.js";
|
|
const parseJSONQueryParams = (body) => {
|
|
try {
|
|
return jsonParse(body);
|
|
} catch {
|
|
throw createError({ statusCode: 400, message: "Invalid _params query" });
|
|
}
|
|
};
|
|
export const encodeQueryParams = (params) => {
|
|
let encoded = jsonStringify(params);
|
|
encoded = typeof Buffer !== "undefined" ? Buffer.from(encoded).toString("base64") : btoa(encoded);
|
|
encoded = encoded.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
const chunks = encoded.match(/.{1,100}/g) || [];
|
|
return chunks.join("/");
|
|
};
|
|
export const decodeQueryParams = (encoded) => {
|
|
encoded = encoded.replace(/\//g, "");
|
|
encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
encoded = encoded.padEnd(encoded.length + (4 - encoded.length % 4) % 4, "=");
|
|
return parseJSONQueryParams(typeof Buffer !== "undefined" ? Buffer.from(encoded, "base64").toString() : atob(encoded));
|
|
};
|
|
const memory = {};
|
|
export const getContentQuery = (event) => {
|
|
const { params } = event.context.params || {};
|
|
if (params) {
|
|
return decodeQueryParams(params.replace(/.json$/, ""));
|
|
}
|
|
const qid = event.context.params?.qid?.replace(/.json$/, "");
|
|
const query = getQuery(event) || {};
|
|
if (qid && query._params) {
|
|
memory[qid] = parseJSONQueryParams(decodeURIComponent(query._params));
|
|
if (memory[qid]?.where && !Array.isArray(memory[qid]?.where)) {
|
|
memory[qid].where = [memory[qid].where];
|
|
}
|
|
return memory[qid];
|
|
}
|
|
if (qid && memory[qid]) {
|
|
return memory[qid];
|
|
}
|
|
if (query._params) {
|
|
return parseJSONQueryParams(decodeURIComponent(query._params));
|
|
}
|
|
if (typeof query.only === "string" && query.only.includes(",")) {
|
|
query.only = query.only.split(",").map((s) => s.trim());
|
|
}
|
|
if (typeof query.without === "string" && query.without.includes(",")) {
|
|
query.without = query.without.split(",").map((s) => s.trim());
|
|
}
|
|
const where = query.where || {};
|
|
for (const key of ["draft", "partial", "empty"]) {
|
|
if (query[key] && ["true", "false"].includes(query[key])) {
|
|
where[key] = query[key] === "true";
|
|
delete query[key];
|
|
}
|
|
}
|
|
if (query.sort) {
|
|
query.sort = String(query.sort).split(",").map((s) => {
|
|
const [key, order] = s.split(":");
|
|
return [key, Number.parseInt(order || "0", 10)];
|
|
});
|
|
}
|
|
const reservedKeys = ["partial", "draft", "only", "without", "where", "sort", "limit", "skip"];
|
|
for (const key of Object.keys(query)) {
|
|
if (reservedKeys.includes(key)) {
|
|
continue;
|
|
}
|
|
query.where = query.where || {};
|
|
query.where[key] = query[key];
|
|
}
|
|
if (Object.keys(where).length > 0) {
|
|
query.where = [where];
|
|
} else {
|
|
delete query.where;
|
|
}
|
|
return query;
|
|
};
|