This commit implements the core admin dashboard functionality including NextAuth authentication, Cloudflare D1 database integration with complete schema, and Cloudflare R2 file upload system for portfolio images. Features include artist management, appointment scheduling, and data migration capabilities.
120 lines
3.5 KiB
JavaScript
120 lines
3.5 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
Object.defineProperty(exports, "acceptLanguage", {
|
|
enumerable: true,
|
|
get: function() {
|
|
return acceptLanguage;
|
|
}
|
|
});
|
|
function parse(raw, preferences, options) {
|
|
const lowers = new Map();
|
|
const header = raw.replace(/[ \t]/g, "");
|
|
if (preferences) {
|
|
let pos = 0;
|
|
for (const preference of preferences){
|
|
const lower = preference.toLowerCase();
|
|
lowers.set(lower, {
|
|
orig: preference,
|
|
pos: pos++
|
|
});
|
|
if (options.prefixMatch) {
|
|
const parts = lower.split("-");
|
|
while(parts.pop(), parts.length > 0){
|
|
const joined = parts.join("-");
|
|
if (!lowers.has(joined)) {
|
|
lowers.set(joined, {
|
|
orig: preference,
|
|
pos: pos++
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const parts = header.split(",");
|
|
const selections = [];
|
|
const map = new Set();
|
|
for(let i = 0; i < parts.length; ++i){
|
|
const part = parts[i];
|
|
if (!part) {
|
|
continue;
|
|
}
|
|
const params = part.split(";");
|
|
if (params.length > 2) {
|
|
throw new Error(`Invalid ${options.type} header`);
|
|
}
|
|
let token = params[0].toLowerCase();
|
|
if (!token) {
|
|
throw new Error(`Invalid ${options.type} header`);
|
|
}
|
|
const selection = {
|
|
token,
|
|
pos: i,
|
|
q: 1
|
|
};
|
|
if (preferences && lowers.has(token)) {
|
|
selection.pref = lowers.get(token).pos;
|
|
}
|
|
map.add(selection.token);
|
|
if (params.length === 2) {
|
|
const q = params[1];
|
|
const [key, value] = q.split("=");
|
|
if (!value || key !== "q" && key !== "Q") {
|
|
throw new Error(`Invalid ${options.type} header`);
|
|
}
|
|
const score = parseFloat(value);
|
|
if (score === 0) {
|
|
continue;
|
|
}
|
|
if (Number.isFinite(score) && score <= 1 && score >= 0.001) {
|
|
selection.q = score;
|
|
}
|
|
}
|
|
selections.push(selection);
|
|
}
|
|
selections.sort((a, b)=>{
|
|
if (b.q !== a.q) {
|
|
return b.q - a.q;
|
|
}
|
|
if (b.pref !== a.pref) {
|
|
if (a.pref === undefined) {
|
|
return 1;
|
|
}
|
|
if (b.pref === undefined) {
|
|
return -1;
|
|
}
|
|
return a.pref - b.pref;
|
|
}
|
|
return a.pos - b.pos;
|
|
});
|
|
const values = selections.map((selection)=>selection.token);
|
|
if (!preferences || !preferences.length) {
|
|
return values;
|
|
}
|
|
const preferred = [];
|
|
for (const selection of values){
|
|
if (selection === "*") {
|
|
for (const [preference, value] of lowers){
|
|
if (!map.has(preference)) {
|
|
preferred.push(value.orig);
|
|
}
|
|
}
|
|
} else {
|
|
const lower = selection.toLowerCase();
|
|
if (lowers.has(lower)) {
|
|
preferred.push(lowers.get(lower).orig);
|
|
}
|
|
}
|
|
}
|
|
return preferred;
|
|
}
|
|
function acceptLanguage(header = "", preferences) {
|
|
return parse(header, preferences, {
|
|
type: "accept-language",
|
|
prefixMatch: true
|
|
})[0] || "";
|
|
}
|
|
|
|
//# sourceMappingURL=accept-header.js.map
|