Nicholai 16cee69250 __Admin dashboard scaffolded with D1 database and R2 file uploads__
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.
2025-09-17 16:08:34 -06:00

504 lines
21 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
checkCustomRoutes: null,
default: null,
normalizeRouteRegex: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
checkCustomRoutes: function() {
return checkCustomRoutes;
},
default: function() {
return loadCustomRoutes;
},
normalizeRouteRegex: function() {
return normalizeRouteRegex;
}
});
const _picocolors = require("./picocolors");
const _escaperegexp = require("../shared/lib/escape-regexp");
const _trytoparsepath = require("./try-to-parse-path");
const _redirectstatus = require("./redirect-status");
const allowedHasTypes = new Set([
"header",
"cookie",
"query",
"host"
]);
const namedGroupsRegex = /\(\?<([a-zA-Z][a-zA-Z0-9]*)>/g;
function normalizeRouteRegex(regex) {
// clean up un-necessary escaping from regex.source which turns / into \\/
return regex.replace(/\\\//g, "/");
}
function checkRedirect(route) {
const invalidParts = [];
let hadInvalidStatus = false;
if (route.statusCode && !_redirectstatus.allowedStatusCodes.has(route["statusCode"])) {
hadInvalidStatus = true;
invalidParts.push(`\`statusCode\` is not undefined or valid statusCode`);
}
if (typeof route.permanent !== "boolean" && !route["statusCode"]) {
invalidParts.push(`\`permanent\` is not set to \`true\` or \`false\``);
}
return {
invalidParts,
hadInvalidStatus
};
}
function checkHeader(route) {
const invalidParts = [];
if (!Array.isArray(route.headers)) {
invalidParts.push("`headers` field must be an array");
} else if (route.headers.length === 0) {
invalidParts.push("`headers` field cannot be empty");
} else {
for (const header of route.headers){
if (!header || typeof header !== "object") {
invalidParts.push("`headers` items must be object with { key: '', value: '' }");
break;
}
if (typeof header.key !== "string") {
invalidParts.push("`key` in header item must be string");
break;
}
if (typeof header.value !== "string") {
invalidParts.push("`value` in header item must be string");
break;
}
}
}
return invalidParts;
}
function checkCustomRoutes(routes, type) {
if (!Array.isArray(routes)) {
console.error(`Error: ${type}s must return an array, received ${typeof routes}.\n` + `See here for more info: https://nextjs.org/docs/messages/routes-must-be-array`);
process.exit(1);
}
let numInvalidRoutes = 0;
let hadInvalidStatus = false;
let hadInvalidHas = false;
let hadInvalidMissing = false;
const allowedKeys = new Set([
"source",
"locale",
"has",
"missing"
]);
if (type === "rewrite") {
allowedKeys.add("basePath");
allowedKeys.add("destination");
}
if (type === "redirect") {
allowedKeys.add("basePath");
allowedKeys.add("statusCode");
allowedKeys.add("permanent");
allowedKeys.add("destination");
}
if (type === "header") {
allowedKeys.add("basePath");
allowedKeys.add("headers");
}
for (const route of routes){
if (!route || typeof route !== "object") {
console.error(`The route ${JSON.stringify(route)} is not a valid object with \`source\`${type !== "middleware" ? ` and \`${type === "header" ? "headers" : "destination"}\`` : ""}`);
numInvalidRoutes++;
continue;
}
if (type === "rewrite" && route.basePath === false && !(route.destination.startsWith("http://") || route.destination.startsWith("https://"))) {
console.error(`The route ${route.source} rewrites urls outside of the basePath. Please use a destination that starts with \`http://\` or \`https://\` https://nextjs.org/docs/messages/invalid-external-rewrite`);
numInvalidRoutes++;
continue;
}
const keys = Object.keys(route);
const invalidKeys = keys.filter((key)=>!allowedKeys.has(key));
const invalidParts = [];
if ("basePath" in route && typeof route.basePath !== "undefined" && route.basePath !== false) {
invalidParts.push("`basePath` must be undefined or false");
}
if (typeof route.locale !== "undefined" && route.locale !== false) {
invalidParts.push("`locale` must be undefined or false");
}
const checkInvalidHasMissing = (items, fieldName)=>{
let hadInvalidItem = false;
if (typeof items !== "undefined" && !Array.isArray(items)) {
invalidParts.push(`\`${fieldName}\` must be undefined or valid has object`);
hadInvalidItem = true;
} else if (items) {
const invalidHasItems = [];
for (const hasItem of items){
let invalidHasParts = [];
if (!allowedHasTypes.has(hasItem.type)) {
invalidHasParts.push(`invalid type "${hasItem.type}"`);
}
if (typeof hasItem.key !== "string" && hasItem.type !== "host") {
invalidHasParts.push(`invalid key "${hasItem.key}"`);
}
if (typeof hasItem.value !== "undefined" && typeof hasItem.value !== "string") {
invalidHasParts.push(`invalid value "${hasItem.value}"`);
}
if (typeof hasItem.value === "undefined" && hasItem.type === "host") {
invalidHasParts.push(`value is required for "host" type`);
}
if (invalidHasParts.length > 0) {
invalidHasItems.push(`${invalidHasParts.join(", ")} for ${JSON.stringify(hasItem)}`);
}
}
if (invalidHasItems.length > 0) {
hadInvalidItem = true;
const itemStr = `item${invalidHasItems.length === 1 ? "" : "s"}`;
console.error(`Invalid \`${fieldName}\` ${itemStr}:\n` + invalidHasItems.join("\n"));
console.error();
invalidParts.push(`invalid \`${fieldName}\` ${itemStr} found`);
}
}
return hadInvalidItem;
};
if (checkInvalidHasMissing(route.has, "has")) {
hadInvalidHas = true;
}
if (checkInvalidHasMissing(route.missing, "missing")) {
hadInvalidMissing = true;
}
if (!route.source) {
invalidParts.push("`source` is missing");
} else if (typeof route.source !== "string") {
invalidParts.push("`source` is not a string");
} else if (!route.source.startsWith("/")) {
invalidParts.push("`source` does not start with /");
}
if (type === "header") {
invalidParts.push(...checkHeader(route));
} else if (type !== "middleware") {
let _route = route;
if (!_route.destination) {
invalidParts.push("`destination` is missing");
} else if (typeof _route.destination !== "string") {
invalidParts.push("`destination` is not a string");
} else if (type === "rewrite" && !_route.destination.match(/^(\/|https:\/\/|http:\/\/)/)) {
invalidParts.push("`destination` does not start with `/`, `http://`, or `https://`");
}
}
if (type === "redirect") {
const result = checkRedirect(route);
hadInvalidStatus = hadInvalidStatus || result.hadInvalidStatus;
invalidParts.push(...result.invalidParts);
}
let sourceTokens;
if (typeof route.source === "string" && route.source.startsWith("/")) {
// only show parse error if we didn't already show error
// for not being a string
const { tokens, error, regexStr } = (0, _trytoparsepath.tryToParsePath)(route.source);
if (error) {
invalidParts.push("`source` parse failed");
}
if (regexStr && regexStr.length > 4096) {
invalidParts.push("`source` exceeds max built length of 4096");
}
sourceTokens = tokens;
}
const hasSegments = new Set();
if (route.has) {
for (const hasItem of route.has){
if (!hasItem.value && hasItem.key) {
hasSegments.add(hasItem.key);
}
if (hasItem.value) {
for (const match of hasItem.value.matchAll(namedGroupsRegex)){
if (match[1]) {
hasSegments.add(match[1]);
}
}
if (hasItem.type === "host") {
hasSegments.add("host");
}
}
}
}
// make sure no unnamed patterns are attempted to be used in the
// destination as this can cause confusion and is not allowed
if (typeof route.destination === "string") {
if (route.destination.startsWith("/") && Array.isArray(sourceTokens)) {
const unnamedInDest = new Set();
for (const token of sourceTokens){
if (typeof token === "object" && typeof token.name === "number") {
const unnamedIndex = new RegExp(`:${token.name}(?!\\d)`);
if (route.destination.match(unnamedIndex)) {
unnamedInDest.add(`:${token.name}`);
}
}
}
if (unnamedInDest.size > 0) {
invalidParts.push(`\`destination\` has unnamed params ${[
...unnamedInDest
].join(", ")}`);
} else {
const { tokens: destTokens, regexStr: destRegexStr, error: destinationParseFailed } = (0, _trytoparsepath.tryToParsePath)(route.destination, {
handleUrl: true
});
if (destRegexStr && destRegexStr.length > 4096) {
invalidParts.push("`destination` exceeds max built length of 4096");
}
if (destinationParseFailed) {
invalidParts.push("`destination` parse failed");
} else {
const sourceSegments = new Set(sourceTokens.map((item)=>typeof item === "object" && item.name).filter(Boolean));
const invalidDestSegments = new Set();
for (const token of destTokens){
if (typeof token === "object" && !sourceSegments.has(token.name) && !hasSegments.has(token.name)) {
invalidDestSegments.add(token.name);
}
}
if (invalidDestSegments.size) {
invalidParts.push(`\`destination\` has segments not in \`source\` or \`has\` (${[
...invalidDestSegments
].join(", ")})`);
}
}
}
}
}
const hasInvalidKeys = invalidKeys.length > 0;
const hasInvalidParts = invalidParts.length > 0;
if (hasInvalidKeys || hasInvalidParts) {
console.error(`${invalidParts.join(", ")}${invalidKeys.length ? (hasInvalidParts ? "," : "") + ` invalid field${invalidKeys.length === 1 ? "" : "s"}: ` + invalidKeys.join(",") : ""} for route ${JSON.stringify(route)}`);
console.error();
numInvalidRoutes++;
}
}
if (numInvalidRoutes > 0) {
if (hadInvalidStatus) {
console.error(`\nValid redirect statusCode values are ${[
..._redirectstatus.allowedStatusCodes
].join(", ")}`);
}
if (hadInvalidHas) {
console.error(`\nValid \`has\` object shape is ${JSON.stringify({
type: [
...allowedHasTypes
].join(", "),
key: "the key to check for",
value: "undefined or a value string to match against"
}, null, 2)}`);
}
if (hadInvalidMissing) {
console.error(`\nValid \`missing\` object shape is ${JSON.stringify({
type: [
...allowedHasTypes
].join(", "),
key: "the key to check for",
value: "undefined or a value string to match against"
}, null, 2)}`);
}
console.error();
console.error(`Error: Invalid ${type}${numInvalidRoutes === 1 ? "" : "s"} found`);
process.exit(1);
}
}
function processRoutes(routes, config, type) {
const _routes = routes;
const newRoutes = [];
const defaultLocales = [];
if (config.i18n && type === "redirect") {
var _config_i18n;
for (const item of ((_config_i18n = config.i18n) == null ? void 0 : _config_i18n.domains) || []){
defaultLocales.push({
locale: item.defaultLocale,
base: `http${item.http ? "" : "s"}://${item.domain}`
});
}
defaultLocales.push({
locale: config.i18n.defaultLocale,
base: ""
});
}
for (const r of _routes){
var _r_destination;
const srcBasePath = config.basePath && r.basePath !== false ? config.basePath : "";
const isExternal = !((_r_destination = r.destination) == null ? void 0 : _r_destination.startsWith("/"));
const destBasePath = srcBasePath && !isExternal ? srcBasePath : "";
if (config.i18n && r.locale !== false) {
var _r_destination1;
if (!isExternal) {
defaultLocales.forEach((item)=>{
let destination;
if (r.destination) {
destination = item.base ? `${item.base}${destBasePath}${r.destination}` : `${destBasePath}${r.destination}`;
}
newRoutes.push({
...r,
destination,
source: `${srcBasePath}/${item.locale}${r.source === "/" && !config.trailingSlash ? "" : r.source}`
});
});
}
r.source = `/:nextInternalLocale(${config.i18n.locales.map((locale)=>(0, _escaperegexp.escapeStringRegexp)(locale)).join("|")})${r.source === "/" && !config.trailingSlash ? "" : r.source}`;
if (r.destination && ((_r_destination1 = r.destination) == null ? void 0 : _r_destination1.startsWith("/"))) {
r.destination = `/:nextInternalLocale${r.destination === "/" && !config.trailingSlash ? "" : r.destination}`;
}
}
r.source = `${srcBasePath}${r.source === "/" && srcBasePath ? "" : r.source}`;
if (r.destination) {
r.destination = `${destBasePath}${r.destination === "/" && destBasePath ? "" : r.destination}`;
}
newRoutes.push(r);
}
return newRoutes;
}
async function loadRedirects(config) {
if (typeof config.redirects !== "function") {
return [];
}
let redirects = await config.redirects();
// check before we process the routes and after to ensure
// they are still valid
checkCustomRoutes(redirects, "redirect");
// save original redirects before transforms
if (Array.isArray(redirects)) {
config._originalRedirects = redirects.map((r)=>({
...r
}));
}
redirects = processRoutes(redirects, config, "redirect");
checkCustomRoutes(redirects, "redirect");
return redirects;
}
async function loadRewrites(config) {
if (typeof config.rewrites !== "function") {
return {
beforeFiles: [],
afterFiles: [],
fallback: []
};
}
const _rewrites = await config.rewrites();
let beforeFiles = [];
let afterFiles = [];
let fallback = [];
if (!Array.isArray(_rewrites) && typeof _rewrites === "object" && Object.keys(_rewrites).every((key)=>key === "beforeFiles" || key === "afterFiles" || key === "fallback")) {
beforeFiles = _rewrites.beforeFiles || [];
afterFiles = _rewrites.afterFiles || [];
fallback = _rewrites.fallback || [];
} else {
afterFiles = _rewrites;
}
// check before we process the routes and after to ensure
// they are still valid
checkCustomRoutes(beforeFiles, "rewrite");
checkCustomRoutes(afterFiles, "rewrite");
checkCustomRoutes(fallback, "rewrite");
// save original rewrites before transforms
config._originalRewrites = {
beforeFiles: beforeFiles.map((r)=>({
...r
})),
afterFiles: afterFiles.map((r)=>({
...r
})),
fallback: fallback.map((r)=>({
...r
}))
};
beforeFiles = processRoutes(beforeFiles, config, "rewrite");
afterFiles = processRoutes(afterFiles, config, "rewrite");
fallback = processRoutes(fallback, config, "rewrite");
checkCustomRoutes(beforeFiles, "rewrite");
checkCustomRoutes(afterFiles, "rewrite");
checkCustomRoutes(fallback, "rewrite");
return {
beforeFiles,
afterFiles,
fallback
};
}
async function loadHeaders(config) {
if (typeof config.headers !== "function") {
return [];
}
let headers = await config.headers();
// check before we process the routes and after to ensure
// they are still valid
checkCustomRoutes(headers, "header");
headers = processRoutes(headers, config, "header");
checkCustomRoutes(headers, "header");
return headers;
}
async function loadCustomRoutes(config) {
const [headers, rewrites, redirects] = await Promise.all([
loadHeaders(config),
loadRewrites(config),
loadRedirects(config)
]);
const totalRewrites = rewrites.beforeFiles.length + rewrites.afterFiles.length + rewrites.fallback.length;
const totalRoutes = headers.length + redirects.length + totalRewrites;
if (totalRoutes > 1000) {
console.warn((0, _picocolors.bold)((0, _picocolors.yellow)(`Warning: `)) + `total number of custom routes exceeds 1000, this can reduce performance. Route counts:\n` + `headers: ${headers.length}\n` + `rewrites: ${totalRewrites}\n` + `redirects: ${redirects.length}\n` + `See more info: https://nextjs.org/docs/messages/max-custom-routes-reached`);
}
if (!config.skipTrailingSlashRedirect) {
if (config.trailingSlash) {
redirects.unshift({
source: "/:file((?!\\.well-known(?:/.*)?)(?:[^/]+/)*[^/]+\\.\\w+)/",
destination: "/:file",
permanent: true,
locale: config.i18n ? false : undefined,
internal: true,
// don't run this redirect for _next/data requests
missing: [
{
type: "header",
key: "x-nextjs-data"
}
]
}, {
source: "/:notfile((?!\\.well-known(?:/.*)?)(?:[^/]+/)*[^/\\.]+)",
destination: "/:notfile/",
permanent: true,
locale: config.i18n ? false : undefined,
internal: true
});
if (config.basePath) {
redirects.unshift({
source: config.basePath,
destination: config.basePath + "/",
permanent: true,
basePath: false,
locale: config.i18n ? false : undefined,
internal: true
});
}
} else {
redirects.unshift({
source: "/:path+/",
destination: "/:path+",
permanent: true,
locale: config.i18n ? false : undefined,
internal: true
});
if (config.basePath) {
redirects.unshift({
source: config.basePath + "/",
destination: config.basePath,
permanent: true,
basePath: false,
locale: config.i18n ? false : undefined,
internal: true
});
}
}
}
return {
headers,
rewrites,
redirects
};
}
//# sourceMappingURL=load-custom-routes.js.map