UI: Optimized legend grid columns for better mobile width matching
539
.open-next 2/.build/cache.cjs
Normal file
@ -0,0 +1,539 @@
|
||||
globalThis.disableIncrementalCache = false;globalThis.disableDynamoDBCache = false;globalThis.isNextAfter15 = true;globalThis.openNextDebug = false;globalThis.openNextVersion = "3.9.12";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/cache.js
|
||||
var cache_exports = {};
|
||||
__export(cache_exports, {
|
||||
SOFT_TAG_PREFIX: () => SOFT_TAG_PREFIX,
|
||||
default: () => Cache
|
||||
});
|
||||
module.exports = __toCommonJS(cache_exports);
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/utils/error.js
|
||||
function isOpenNextError(e) {
|
||||
try {
|
||||
return "__openNextInternal" in e;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/logger.js
|
||||
function debug(...args) {
|
||||
if (globalThis.openNextDebug) {
|
||||
console.log(...args);
|
||||
}
|
||||
}
|
||||
function warn(...args) {
|
||||
console.warn(...args);
|
||||
}
|
||||
var DOWNPLAYED_ERROR_LOGS = [
|
||||
{
|
||||
clientName: "S3Client",
|
||||
commandName: "GetObjectCommand",
|
||||
errorName: "NoSuchKey"
|
||||
}
|
||||
];
|
||||
var isDownplayedErrorLog = (errorLog) => DOWNPLAYED_ERROR_LOGS.some((downplayedInput) => downplayedInput.clientName === errorLog?.clientName && downplayedInput.commandName === errorLog?.commandName && (downplayedInput.errorName === errorLog?.error?.name || downplayedInput.errorName === errorLog?.error?.Code));
|
||||
function error(...args) {
|
||||
if (args.some((arg) => isDownplayedErrorLog(arg))) {
|
||||
return debug(...args);
|
||||
}
|
||||
if (args.some((arg) => isOpenNextError(arg))) {
|
||||
const error2 = args.find((arg) => isOpenNextError(arg));
|
||||
if (error2.logLevel < getOpenNextErrorLogLevel()) {
|
||||
return;
|
||||
}
|
||||
if (error2.logLevel === 0) {
|
||||
return console.log(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
||||
}
|
||||
if (error2.logLevel === 1) {
|
||||
return warn(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
||||
}
|
||||
return console.error(...args);
|
||||
}
|
||||
console.error(...args);
|
||||
}
|
||||
function getOpenNextErrorLogLevel() {
|
||||
const strLevel = process.env.OPEN_NEXT_ERROR_LOG_LEVEL ?? "1";
|
||||
switch (strLevel.toLowerCase()) {
|
||||
case "debug":
|
||||
case "0":
|
||||
return 0;
|
||||
case "error":
|
||||
case "2":
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/utils/cache.js
|
||||
async function hasBeenRevalidated(key, tags, cacheEntry) {
|
||||
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
||||
return false;
|
||||
}
|
||||
const value = cacheEntry.value;
|
||||
if (!value) {
|
||||
return true;
|
||||
}
|
||||
if ("type" in cacheEntry && cacheEntry.type === "page") {
|
||||
return false;
|
||||
}
|
||||
const lastModified = cacheEntry.lastModified ?? Date.now();
|
||||
if (globalThis.tagCache.mode === "nextMode") {
|
||||
return tags.length === 0 ? false : await globalThis.tagCache.hasBeenRevalidated(tags, lastModified);
|
||||
}
|
||||
const _lastModified = await globalThis.tagCache.getLastModified(key, lastModified);
|
||||
return _lastModified === -1;
|
||||
}
|
||||
function getTagsFromValue(value) {
|
||||
if (!value) {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const cacheTags = value.meta?.headers?.["x-next-cache-tags"]?.split(",") ?? [];
|
||||
delete value.meta?.headers?.["x-next-cache-tags"];
|
||||
return cacheTags;
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
function getTagKey(tag) {
|
||||
if (typeof tag === "string") {
|
||||
return tag;
|
||||
}
|
||||
return JSON.stringify({
|
||||
tag: tag.tag,
|
||||
path: tag.path
|
||||
});
|
||||
}
|
||||
async function writeTags(tags) {
|
||||
const store = globalThis.__openNextAls.getStore();
|
||||
debug("Writing tags", tags, store);
|
||||
if (!store || globalThis.openNextConfig.dangerous?.disableTagCache) {
|
||||
return;
|
||||
}
|
||||
const tagsToWrite = tags.filter((t) => {
|
||||
const tagKey = getTagKey(t);
|
||||
const shouldWrite = !store.writtenTags.has(tagKey);
|
||||
if (shouldWrite) {
|
||||
store.writtenTags.add(tagKey);
|
||||
}
|
||||
return shouldWrite;
|
||||
});
|
||||
if (tagsToWrite.length === 0) {
|
||||
return;
|
||||
}
|
||||
await globalThis.tagCache.writeTags(tagsToWrite);
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/utils/binary.js
|
||||
var commonBinaryMimeTypes = /* @__PURE__ */ new Set([
|
||||
"application/octet-stream",
|
||||
// Docs
|
||||
"application/epub+zip",
|
||||
"application/msword",
|
||||
"application/pdf",
|
||||
"application/rtf",
|
||||
"application/vnd.amazon.ebook",
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.ms-powerpoint",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
// Fonts
|
||||
"font/otf",
|
||||
"font/woff",
|
||||
"font/woff2",
|
||||
// Images
|
||||
"image/bmp",
|
||||
"image/gif",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/tiff",
|
||||
"image/vnd.microsoft.icon",
|
||||
"image/webp",
|
||||
// Audio
|
||||
"audio/3gpp",
|
||||
"audio/aac",
|
||||
"audio/basic",
|
||||
"audio/flac",
|
||||
"audio/mpeg",
|
||||
"audio/ogg",
|
||||
"audio/wavaudio/webm",
|
||||
"audio/x-aiff",
|
||||
"audio/x-midi",
|
||||
"audio/x-wav",
|
||||
// Video
|
||||
"video/3gpp",
|
||||
"video/mp2t",
|
||||
"video/mpeg",
|
||||
"video/ogg",
|
||||
"video/quicktime",
|
||||
"video/webm",
|
||||
"video/x-msvideo",
|
||||
// Archives
|
||||
"application/java-archive",
|
||||
"application/vnd.apple.installer+xml",
|
||||
"application/x-7z-compressed",
|
||||
"application/x-apple-diskimage",
|
||||
"application/x-bzip",
|
||||
"application/x-bzip2",
|
||||
"application/x-gzip",
|
||||
"application/x-java-archive",
|
||||
"application/x-rar-compressed",
|
||||
"application/x-tar",
|
||||
"application/x-zip",
|
||||
"application/zip",
|
||||
// Serialized data
|
||||
"application/x-protobuf"
|
||||
]);
|
||||
function isBinaryContentType(contentType) {
|
||||
if (!contentType)
|
||||
return false;
|
||||
const value = contentType.split(";")[0];
|
||||
return commonBinaryMimeTypes.has(value);
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/cache.js
|
||||
var SOFT_TAG_PREFIX = "_N_T_/";
|
||||
function isFetchCache(options) {
|
||||
if (typeof options === "boolean") {
|
||||
return options;
|
||||
}
|
||||
if (typeof options === "object") {
|
||||
return options.kindHint === "fetch" || options.fetchCache || options.kind === "FETCH";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
var Cache = class {
|
||||
async get(key, options) {
|
||||
if (globalThis.openNextConfig.dangerous?.disableIncrementalCache) {
|
||||
return null;
|
||||
}
|
||||
const softTags = typeof options === "object" ? options.softTags : [];
|
||||
const tags = typeof options === "object" ? options.tags : [];
|
||||
return isFetchCache(options) ? this.getFetchCache(key, softTags, tags) : this.getIncrementalCache(key);
|
||||
}
|
||||
async getFetchCache(key, softTags, tags) {
|
||||
debug("get fetch cache", { key, softTags, tags });
|
||||
try {
|
||||
const cachedEntry = await globalThis.incrementalCache.get(key, "fetch");
|
||||
if (cachedEntry?.value === void 0)
|
||||
return null;
|
||||
const _tags = [...tags ?? [], ...softTags ?? []];
|
||||
const _lastModified = cachedEntry.lastModified ?? Date.now();
|
||||
const _hasBeenRevalidated = cachedEntry.shouldBypassTagCache ? false : await hasBeenRevalidated(key, _tags, cachedEntry);
|
||||
if (_hasBeenRevalidated)
|
||||
return null;
|
||||
if ((tags ?? []).length === 0) {
|
||||
const path = softTags?.find((tag) => tag.startsWith(SOFT_TAG_PREFIX) && !tag.endsWith("layout") && !tag.endsWith("page"));
|
||||
if (path) {
|
||||
const hasPathBeenUpdated = cachedEntry.shouldBypassTagCache ? false : await hasBeenRevalidated(path.replace(SOFT_TAG_PREFIX, ""), [], cachedEntry);
|
||||
if (hasPathBeenUpdated) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
lastModified: _lastModified,
|
||||
value: cachedEntry.value
|
||||
};
|
||||
} catch (e) {
|
||||
debug("Failed to get fetch cache", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async getIncrementalCache(key) {
|
||||
try {
|
||||
const cachedEntry = await globalThis.incrementalCache.get(key, "cache");
|
||||
if (!cachedEntry?.value) {
|
||||
return null;
|
||||
}
|
||||
const cacheData = cachedEntry.value;
|
||||
const meta = cacheData.meta;
|
||||
const tags = getTagsFromValue(cacheData);
|
||||
const _lastModified = cachedEntry.lastModified ?? Date.now();
|
||||
const _hasBeenRevalidated = cachedEntry.shouldBypassTagCache ? false : await hasBeenRevalidated(key, tags, cachedEntry);
|
||||
if (_hasBeenRevalidated)
|
||||
return null;
|
||||
const store = globalThis.__openNextAls.getStore();
|
||||
if (store) {
|
||||
store.lastModified = _lastModified;
|
||||
}
|
||||
if (cacheData?.type === "route") {
|
||||
return {
|
||||
lastModified: _lastModified,
|
||||
value: {
|
||||
kind: globalThis.isNextAfter15 ? "APP_ROUTE" : "ROUTE",
|
||||
body: Buffer.from(cacheData.body ?? Buffer.alloc(0), isBinaryContentType(String(meta?.headers?.["content-type"])) ? "base64" : "utf8"),
|
||||
status: meta?.status,
|
||||
headers: meta?.headers
|
||||
}
|
||||
};
|
||||
}
|
||||
if (cacheData?.type === "page" || cacheData?.type === "app") {
|
||||
if (globalThis.isNextAfter15 && cacheData?.type === "app") {
|
||||
const segmentData = /* @__PURE__ */ new Map();
|
||||
if (cacheData.segmentData) {
|
||||
for (const [segmentPath, segmentContent] of Object.entries(cacheData.segmentData ?? {})) {
|
||||
segmentData.set(segmentPath, Buffer.from(segmentContent));
|
||||
}
|
||||
}
|
||||
return {
|
||||
lastModified: _lastModified,
|
||||
value: {
|
||||
kind: "APP_PAGE",
|
||||
html: cacheData.html,
|
||||
rscData: Buffer.from(cacheData.rsc),
|
||||
status: meta?.status,
|
||||
headers: meta?.headers,
|
||||
postponed: meta?.postponed,
|
||||
segmentData
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
lastModified: _lastModified,
|
||||
value: {
|
||||
kind: globalThis.isNextAfter15 ? "PAGES" : "PAGE",
|
||||
html: cacheData.html,
|
||||
pageData: cacheData.type === "page" ? cacheData.json : cacheData.rsc,
|
||||
status: meta?.status,
|
||||
headers: meta?.headers
|
||||
}
|
||||
};
|
||||
}
|
||||
if (cacheData?.type === "redirect") {
|
||||
return {
|
||||
lastModified: _lastModified,
|
||||
value: {
|
||||
kind: "REDIRECT",
|
||||
props: cacheData.props
|
||||
}
|
||||
};
|
||||
}
|
||||
warn("Unknown cache type", cacheData);
|
||||
return null;
|
||||
} catch (e) {
|
||||
debug("Failed to get body cache", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async set(key, data, ctx) {
|
||||
if (globalThis.openNextConfig.dangerous?.disableIncrementalCache) {
|
||||
return;
|
||||
}
|
||||
const detachedPromise = globalThis.__openNextAls.getStore()?.pendingPromiseRunner.withResolvers();
|
||||
try {
|
||||
if (data === null || data === void 0) {
|
||||
await globalThis.incrementalCache.delete(key);
|
||||
} else {
|
||||
const revalidate = this.extractRevalidateForSet(ctx);
|
||||
switch (data.kind) {
|
||||
case "ROUTE":
|
||||
case "APP_ROUTE": {
|
||||
const { body, status, headers } = data;
|
||||
await globalThis.incrementalCache.set(key, {
|
||||
type: "route",
|
||||
body: body.toString(isBinaryContentType(String(headers["content-type"])) ? "base64" : "utf8"),
|
||||
meta: {
|
||||
status,
|
||||
headers
|
||||
},
|
||||
revalidate
|
||||
}, "cache");
|
||||
break;
|
||||
}
|
||||
case "PAGE":
|
||||
case "PAGES": {
|
||||
const { html, pageData, status, headers } = data;
|
||||
const isAppPath = typeof pageData === "string";
|
||||
if (isAppPath) {
|
||||
await globalThis.incrementalCache.set(key, {
|
||||
type: "app",
|
||||
html,
|
||||
rsc: pageData,
|
||||
meta: {
|
||||
status,
|
||||
headers
|
||||
},
|
||||
revalidate
|
||||
}, "cache");
|
||||
} else {
|
||||
await globalThis.incrementalCache.set(key, {
|
||||
type: "page",
|
||||
html,
|
||||
json: pageData,
|
||||
revalidate
|
||||
}, "cache");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "APP_PAGE": {
|
||||
const { html, rscData, headers, status } = data;
|
||||
await globalThis.incrementalCache.set(key, {
|
||||
type: "app",
|
||||
html,
|
||||
rsc: rscData.toString("utf8"),
|
||||
meta: {
|
||||
status,
|
||||
headers
|
||||
},
|
||||
revalidate
|
||||
}, "cache");
|
||||
break;
|
||||
}
|
||||
case "FETCH":
|
||||
await globalThis.incrementalCache.set(key, data, "fetch");
|
||||
break;
|
||||
case "REDIRECT":
|
||||
await globalThis.incrementalCache.set(key, {
|
||||
type: "redirect",
|
||||
props: data.props,
|
||||
revalidate
|
||||
}, "cache");
|
||||
break;
|
||||
case "IMAGE":
|
||||
break;
|
||||
}
|
||||
}
|
||||
await this.updateTagsOnSet(key, data, ctx);
|
||||
debug("Finished setting cache");
|
||||
} catch (e) {
|
||||
error("Failed to set cache", e);
|
||||
} finally {
|
||||
detachedPromise?.resolve();
|
||||
}
|
||||
}
|
||||
async revalidateTag(tags) {
|
||||
const config = globalThis.openNextConfig.dangerous;
|
||||
if (config?.disableTagCache || config?.disableIncrementalCache) {
|
||||
return;
|
||||
}
|
||||
const _tags = Array.isArray(tags) ? tags : [tags];
|
||||
if (_tags.length === 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (globalThis.tagCache.mode === "nextMode") {
|
||||
const paths = await globalThis.tagCache.getPathsByTags?.(_tags) ?? [];
|
||||
await writeTags(_tags);
|
||||
if (paths.length > 0) {
|
||||
await globalThis.cdnInvalidationHandler.invalidatePaths(paths.map((path) => ({
|
||||
initialPath: path,
|
||||
rawPath: path,
|
||||
resolvedRoutes: [
|
||||
{
|
||||
route: path,
|
||||
// TODO: ideally here we should check if it's an app router page or route
|
||||
type: "app"
|
||||
}
|
||||
]
|
||||
})));
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (const tag of _tags) {
|
||||
debug("revalidateTag", tag);
|
||||
const paths = await globalThis.tagCache.getByTag(tag);
|
||||
debug("Items", paths);
|
||||
const toInsert = paths.map((path) => ({
|
||||
path,
|
||||
tag
|
||||
}));
|
||||
if (tag.startsWith(SOFT_TAG_PREFIX)) {
|
||||
for (const path of paths) {
|
||||
const _tags2 = await globalThis.tagCache.getByPath(path);
|
||||
const hardTags = _tags2.filter((t) => !t.startsWith(SOFT_TAG_PREFIX));
|
||||
for (const hardTag of hardTags) {
|
||||
const _paths = await globalThis.tagCache.getByTag(hardTag);
|
||||
debug({ hardTag, _paths });
|
||||
toInsert.push(..._paths.map((path2) => ({
|
||||
path: path2,
|
||||
tag: hardTag
|
||||
})));
|
||||
}
|
||||
}
|
||||
}
|
||||
await writeTags(toInsert);
|
||||
const uniquePaths = Array.from(new Set(toInsert.filter((t) => t.tag.startsWith(SOFT_TAG_PREFIX)).map((t) => `/${t.path}`)));
|
||||
if (uniquePaths.length > 0) {
|
||||
await globalThis.cdnInvalidationHandler.invalidatePaths(uniquePaths.map((path) => ({
|
||||
initialPath: path,
|
||||
rawPath: path,
|
||||
resolvedRoutes: [
|
||||
{
|
||||
route: path,
|
||||
// TODO: ideally here we should check if it's an app router page or route
|
||||
type: "app"
|
||||
}
|
||||
]
|
||||
})));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
error("Failed to revalidate tag", e);
|
||||
}
|
||||
}
|
||||
// TODO: We should delete/update tags in this method
|
||||
// This will require an update to the tag cache interface
|
||||
async updateTagsOnSet(key, data, ctx) {
|
||||
if (globalThis.openNextConfig.dangerous?.disableTagCache || globalThis.tagCache.mode === "nextMode" || // Here it means it's a delete
|
||||
!data) {
|
||||
return;
|
||||
}
|
||||
const derivedTags = data?.kind === "FETCH" ? (
|
||||
//@ts-expect-error - On older versions of next, ctx was a number, but for these cases we use data?.data?.tags
|
||||
ctx?.tags ?? data?.data?.tags ?? []
|
||||
) : data?.kind === "PAGE" ? data.headers?.["x-next-cache-tags"]?.split(",") ?? [] : [];
|
||||
debug("derivedTags", derivedTags);
|
||||
const storedTags = await globalThis.tagCache.getByPath(key);
|
||||
const tagsToWrite = derivedTags.filter((tag) => !storedTags.includes(tag));
|
||||
if (tagsToWrite.length > 0) {
|
||||
await writeTags(tagsToWrite.map((tag) => ({
|
||||
path: key,
|
||||
tag,
|
||||
// In case the tags are not there we just need to create them
|
||||
// but we don't want them to return from `getLastModified` as they are not stale
|
||||
revalidatedAt: 1
|
||||
})));
|
||||
}
|
||||
}
|
||||
extractRevalidateForSet(ctx) {
|
||||
if (ctx === void 0) {
|
||||
return void 0;
|
||||
}
|
||||
if (typeof ctx === "number" || ctx === false) {
|
||||
return ctx;
|
||||
}
|
||||
if ("revalidate" in ctx) {
|
||||
return ctx.revalidate;
|
||||
}
|
||||
if ("cacheControl" in ctx) {
|
||||
return ctx.cacheControl?.revalidate;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
SOFT_TAG_PREFIX
|
||||
});
|
||||
195
.open-next 2/.build/composable-cache.cjs
Normal file
@ -0,0 +1,195 @@
|
||||
globalThis.disableIncrementalCache = false;globalThis.disableDynamoDBCache = false;globalThis.isNextAfter15 = true;globalThis.openNextDebug = false;globalThis.openNextVersion = "3.9.12";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/composable-cache.js
|
||||
var composable_cache_exports = {};
|
||||
__export(composable_cache_exports, {
|
||||
default: () => composable_cache_default
|
||||
});
|
||||
module.exports = __toCommonJS(composable_cache_exports);
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/logger.js
|
||||
function debug(...args) {
|
||||
if (globalThis.openNextDebug) {
|
||||
console.log(...args);
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/utils/cache.js
|
||||
function getTagKey(tag) {
|
||||
if (typeof tag === "string") {
|
||||
return tag;
|
||||
}
|
||||
return JSON.stringify({
|
||||
tag: tag.tag,
|
||||
path: tag.path
|
||||
});
|
||||
}
|
||||
async function writeTags(tags) {
|
||||
const store = globalThis.__openNextAls.getStore();
|
||||
debug("Writing tags", tags, store);
|
||||
if (!store || globalThis.openNextConfig.dangerous?.disableTagCache) {
|
||||
return;
|
||||
}
|
||||
const tagsToWrite = tags.filter((t) => {
|
||||
const tagKey = getTagKey(t);
|
||||
const shouldWrite = !store.writtenTags.has(tagKey);
|
||||
if (shouldWrite) {
|
||||
store.writtenTags.add(tagKey);
|
||||
}
|
||||
return shouldWrite;
|
||||
});
|
||||
if (tagsToWrite.length === 0) {
|
||||
return;
|
||||
}
|
||||
await globalThis.tagCache.writeTags(tagsToWrite);
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/utils/stream.js
|
||||
var import_web = require("node:stream/web");
|
||||
async function fromReadableStream(stream, base64) {
|
||||
const chunks = [];
|
||||
let totalLength = 0;
|
||||
for await (const chunk of stream) {
|
||||
chunks.push(chunk);
|
||||
totalLength += chunk.length;
|
||||
}
|
||||
if (chunks.length === 0) {
|
||||
return "";
|
||||
}
|
||||
if (chunks.length === 1) {
|
||||
return Buffer.from(chunks[0]).toString(base64 ? "base64" : "utf8");
|
||||
}
|
||||
const buffer = Buffer.alloc(totalLength);
|
||||
let offset = 0;
|
||||
for (const chunk of chunks) {
|
||||
buffer.set(chunk, offset);
|
||||
offset += chunk.length;
|
||||
}
|
||||
return buffer.toString(base64 ? "base64" : "utf8");
|
||||
}
|
||||
function toReadableStream(value, isBase64) {
|
||||
return new import_web.ReadableStream({
|
||||
pull(controller) {
|
||||
controller.enqueue(Buffer.from(value, isBase64 ? "base64" : "utf8"));
|
||||
controller.close();
|
||||
}
|
||||
}, { highWaterMark: 0 });
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/composable-cache.js
|
||||
var pendingWritePromiseMap = /* @__PURE__ */ new Map();
|
||||
var composable_cache_default = {
|
||||
async get(cacheKey) {
|
||||
try {
|
||||
if (pendingWritePromiseMap.has(cacheKey)) {
|
||||
const stored = pendingWritePromiseMap.get(cacheKey);
|
||||
if (stored) {
|
||||
return stored.then((entry) => ({
|
||||
...entry,
|
||||
value: toReadableStream(entry.value)
|
||||
}));
|
||||
}
|
||||
}
|
||||
const result = await globalThis.incrementalCache.get(cacheKey, "composable");
|
||||
if (!result?.value?.value) {
|
||||
return void 0;
|
||||
}
|
||||
debug("composable cache result", result);
|
||||
if (globalThis.tagCache.mode === "nextMode" && result.value.tags.length > 0) {
|
||||
const hasBeenRevalidated = result.shouldBypassTagCache ? false : await globalThis.tagCache.hasBeenRevalidated(result.value.tags, result.lastModified);
|
||||
if (hasBeenRevalidated)
|
||||
return void 0;
|
||||
} else if (globalThis.tagCache.mode === "original" || globalThis.tagCache.mode === void 0) {
|
||||
const hasBeenRevalidated = result.shouldBypassTagCache ? false : await globalThis.tagCache.getLastModified(cacheKey, result.lastModified) === -1;
|
||||
if (hasBeenRevalidated)
|
||||
return void 0;
|
||||
}
|
||||
return {
|
||||
...result.value,
|
||||
value: toReadableStream(result.value.value)
|
||||
};
|
||||
} catch (e) {
|
||||
debug("Cannot read composable cache entry");
|
||||
return void 0;
|
||||
}
|
||||
},
|
||||
async set(cacheKey, pendingEntry) {
|
||||
const promiseEntry = pendingEntry.then(async (entry2) => ({
|
||||
...entry2,
|
||||
value: await fromReadableStream(entry2.value)
|
||||
}));
|
||||
pendingWritePromiseMap.set(cacheKey, promiseEntry);
|
||||
const entry = await promiseEntry.finally(() => {
|
||||
pendingWritePromiseMap.delete(cacheKey);
|
||||
});
|
||||
await globalThis.incrementalCache.set(cacheKey, {
|
||||
...entry,
|
||||
value: entry.value
|
||||
}, "composable");
|
||||
if (globalThis.tagCache.mode === "original") {
|
||||
const storedTags = await globalThis.tagCache.getByPath(cacheKey);
|
||||
const tagsToWrite = entry.tags.filter((tag) => !storedTags.includes(tag));
|
||||
if (tagsToWrite.length > 0) {
|
||||
await writeTags(tagsToWrite.map((tag) => ({ tag, path: cacheKey })));
|
||||
}
|
||||
}
|
||||
},
|
||||
async refreshTags() {
|
||||
return;
|
||||
},
|
||||
/**
|
||||
* The signature has changed in Next.js 16
|
||||
* - Before Next.js 16, the method takes `...tags: string[]`
|
||||
* - From Next.js 16, the method takes `tags: string[]`
|
||||
*/
|
||||
async getExpiration(...tags) {
|
||||
if (globalThis.tagCache.mode === "nextMode") {
|
||||
return globalThis.tagCache.getLastRevalidated(tags.flat());
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
/**
|
||||
* This method is only used before Next.js 16
|
||||
*/
|
||||
async expireTags(...tags) {
|
||||
if (globalThis.tagCache.mode === "nextMode") {
|
||||
return writeTags(tags);
|
||||
}
|
||||
const tagCache = globalThis.tagCache;
|
||||
const revalidatedAt = Date.now();
|
||||
const pathsToUpdate = await Promise.all(tags.map(async (tag) => {
|
||||
const paths = await tagCache.getByTag(tag);
|
||||
return paths.map((path) => ({
|
||||
path,
|
||||
tag,
|
||||
revalidatedAt
|
||||
}));
|
||||
}));
|
||||
const setToWrite = /* @__PURE__ */ new Set();
|
||||
for (const entry of pathsToUpdate.flat()) {
|
||||
setToWrite.add(entry);
|
||||
}
|
||||
await writeTags(Array.from(setToWrite));
|
||||
},
|
||||
// This one is necessary for older versions of next
|
||||
async receiveExpiredTags(...tags) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
169
.open-next 2/.build/durable-objects/bucket-cache-purge.js
Normal file
@ -0,0 +1,169 @@
|
||||
globalThis.openNextDebug = false;globalThis.openNextVersion = "3.9.12";
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/durable-objects/bucket-cache-purge.js
|
||||
import { DurableObject } from "cloudflare:workers";
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/utils/error.js
|
||||
function isOpenNextError(e) {
|
||||
try {
|
||||
return "__openNextInternal" in e;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/logger.js
|
||||
function debug(...args) {
|
||||
if (globalThis.openNextDebug) {
|
||||
console.log(...args);
|
||||
}
|
||||
}
|
||||
function warn(...args) {
|
||||
console.warn(...args);
|
||||
}
|
||||
var DOWNPLAYED_ERROR_LOGS = [
|
||||
{
|
||||
clientName: "S3Client",
|
||||
commandName: "GetObjectCommand",
|
||||
errorName: "NoSuchKey"
|
||||
}
|
||||
];
|
||||
var isDownplayedErrorLog = (errorLog) => DOWNPLAYED_ERROR_LOGS.some((downplayedInput) => downplayedInput.clientName === errorLog?.clientName && downplayedInput.commandName === errorLog?.commandName && (downplayedInput.errorName === errorLog?.error?.name || downplayedInput.errorName === errorLog?.error?.Code));
|
||||
function error(...args) {
|
||||
if (args.some((arg) => isDownplayedErrorLog(arg))) {
|
||||
return debug(...args);
|
||||
}
|
||||
if (args.some((arg) => isOpenNextError(arg))) {
|
||||
const error2 = args.find((arg) => isOpenNextError(arg));
|
||||
if (error2.logLevel < getOpenNextErrorLogLevel()) {
|
||||
return;
|
||||
}
|
||||
if (error2.logLevel === 0) {
|
||||
return console.log(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
||||
}
|
||||
if (error2.logLevel === 1) {
|
||||
return warn(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
||||
}
|
||||
return console.error(...args);
|
||||
}
|
||||
console.error(...args);
|
||||
}
|
||||
function getOpenNextErrorLogLevel() {
|
||||
const strLevel = process.env.OPEN_NEXT_ERROR_LOG_LEVEL ?? "1";
|
||||
switch (strLevel.toLowerCase()) {
|
||||
case "debug":
|
||||
case "0":
|
||||
return 0;
|
||||
case "error":
|
||||
case "2":
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/cloudflare-context.js
|
||||
var cloudflareContextSymbol = Symbol.for("__cloudflare-context__");
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/overrides/internal.js
|
||||
var debugCache = (name, ...args) => {
|
||||
if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {
|
||||
console.log(`[${name}] `, ...args);
|
||||
}
|
||||
};
|
||||
async function internalPurgeCacheByTags(env, tags) {
|
||||
if (!env.CACHE_PURGE_ZONE_ID || !env.CACHE_PURGE_API_TOKEN) {
|
||||
error("No cache zone ID or API token provided. Skipping cache purge.");
|
||||
return "missing-credentials";
|
||||
}
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(`https://api.cloudflare.com/client/v4/zones/${env.CACHE_PURGE_ZONE_ID}/purge_cache`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${env.CACHE_PURGE_API_TOKEN}`,
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
tags
|
||||
})
|
||||
});
|
||||
if (response.status === 429) {
|
||||
error("purgeCacheByTags: Rate limit exceeded. Skipping cache purge.");
|
||||
return "rate-limit-exceeded";
|
||||
}
|
||||
const bodyResponse = await response.json();
|
||||
if (!bodyResponse.success) {
|
||||
error("purgeCacheByTags: Cache purge failed. Errors:", bodyResponse.errors.map((error2) => `${error2.code}: ${error2.message}`));
|
||||
return "purge-failed";
|
||||
}
|
||||
debugCache("purgeCacheByTags", "Cache purged successfully for tags:", tags);
|
||||
return "purge-success";
|
||||
} catch (error2) {
|
||||
console.error("Error purging cache by tags:", error2);
|
||||
return "purge-failed";
|
||||
} finally {
|
||||
try {
|
||||
await response?.body?.cancel();
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/durable-objects/bucket-cache-purge.js
|
||||
var DEFAULT_BUFFER_TIME_IN_SECONDS = 5;
|
||||
var MAX_NUMBER_OF_TAGS_PER_PURGE = 100;
|
||||
var BucketCachePurge = class extends DurableObject {
|
||||
bufferTimeInSeconds;
|
||||
constructor(state, env) {
|
||||
super(state, env);
|
||||
this.bufferTimeInSeconds = env.NEXT_CACHE_DO_PURGE_BUFFER_TIME_IN_SECONDS ? parseInt(env.NEXT_CACHE_DO_PURGE_BUFFER_TIME_IN_SECONDS) : DEFAULT_BUFFER_TIME_IN_SECONDS;
|
||||
state.blockConcurrencyWhile(async () => {
|
||||
state.storage.sql.exec(`
|
||||
CREATE TABLE IF NOT EXISTS cache_purge (
|
||||
tag TEXT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS tag_index ON cache_purge (tag);
|
||||
`);
|
||||
});
|
||||
}
|
||||
async purgeCacheByTags(tags) {
|
||||
for (const tag of tags) {
|
||||
this.ctx.storage.sql.exec(`
|
||||
INSERT OR REPLACE INTO cache_purge (tag)
|
||||
VALUES (?)`, [tag]);
|
||||
}
|
||||
const nextAlarm = await this.ctx.storage.getAlarm();
|
||||
if (!nextAlarm) {
|
||||
this.ctx.storage.setAlarm(Date.now() + this.bufferTimeInSeconds * 1e3);
|
||||
}
|
||||
}
|
||||
async alarm() {
|
||||
let tags = this.ctx.storage.sql.exec(`
|
||||
SELECT * FROM cache_purge LIMIT ${MAX_NUMBER_OF_TAGS_PER_PURGE}
|
||||
`).toArray();
|
||||
do {
|
||||
if (tags.length === 0) {
|
||||
return;
|
||||
}
|
||||
const result = await internalPurgeCacheByTags(this.env, tags.map((row) => row.tag));
|
||||
if (result === "rate-limit-exceeded") {
|
||||
throw new Error("Rate limit exceeded");
|
||||
}
|
||||
this.ctx.storage.sql.exec(`
|
||||
DELETE FROM cache_purge
|
||||
WHERE tag IN (${tags.map(() => "?").join(",")})
|
||||
`, tags.map((row) => row.tag));
|
||||
if (tags.length < MAX_NUMBER_OF_TAGS_PER_PURGE) {
|
||||
tags = [];
|
||||
} else {
|
||||
tags = this.ctx.storage.sql.exec(`
|
||||
SELECT * FROM cache_purge LIMIT ${MAX_NUMBER_OF_TAGS_PER_PURGE}
|
||||
`).toArray();
|
||||
}
|
||||
} while (tags.length >= 0);
|
||||
}
|
||||
};
|
||||
export {
|
||||
BucketCachePurge
|
||||
};
|
||||
283
.open-next 2/.build/durable-objects/queue.js
Normal file
@ -0,0 +1,283 @@
|
||||
globalThis.openNextDebug = false;globalThis.openNextVersion = "3.9.12";
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/utils/error.js
|
||||
var IgnorableError = class extends Error {
|
||||
__openNextInternal = true;
|
||||
canIgnore = true;
|
||||
logLevel = 0;
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "IgnorableError";
|
||||
}
|
||||
};
|
||||
var RecoverableError = class extends Error {
|
||||
__openNextInternal = true;
|
||||
canIgnore = true;
|
||||
logLevel = 1;
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "RecoverableError";
|
||||
}
|
||||
};
|
||||
var FatalError = class extends Error {
|
||||
__openNextInternal = true;
|
||||
canIgnore = false;
|
||||
logLevel = 2;
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "FatalError";
|
||||
}
|
||||
};
|
||||
function isOpenNextError(e) {
|
||||
try {
|
||||
return "__openNextInternal" in e;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/logger.js
|
||||
function debug(...args) {
|
||||
if (globalThis.openNextDebug) {
|
||||
console.log(...args);
|
||||
}
|
||||
}
|
||||
function warn(...args) {
|
||||
console.warn(...args);
|
||||
}
|
||||
var DOWNPLAYED_ERROR_LOGS = [
|
||||
{
|
||||
clientName: "S3Client",
|
||||
commandName: "GetObjectCommand",
|
||||
errorName: "NoSuchKey"
|
||||
}
|
||||
];
|
||||
var isDownplayedErrorLog = (errorLog) => DOWNPLAYED_ERROR_LOGS.some((downplayedInput) => downplayedInput.clientName === errorLog?.clientName && downplayedInput.commandName === errorLog?.commandName && (downplayedInput.errorName === errorLog?.error?.name || downplayedInput.errorName === errorLog?.error?.Code));
|
||||
function error(...args) {
|
||||
if (args.some((arg) => isDownplayedErrorLog(arg))) {
|
||||
return debug(...args);
|
||||
}
|
||||
if (args.some((arg) => isOpenNextError(arg))) {
|
||||
const error2 = args.find((arg) => isOpenNextError(arg));
|
||||
if (error2.logLevel < getOpenNextErrorLogLevel()) {
|
||||
return;
|
||||
}
|
||||
if (error2.logLevel === 0) {
|
||||
return console.log(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
||||
}
|
||||
if (error2.logLevel === 1) {
|
||||
return warn(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
||||
}
|
||||
return console.error(...args);
|
||||
}
|
||||
console.error(...args);
|
||||
}
|
||||
function getOpenNextErrorLogLevel() {
|
||||
const strLevel = process.env.OPEN_NEXT_ERROR_LOG_LEVEL ?? "1";
|
||||
switch (strLevel.toLowerCase()) {
|
||||
case "debug":
|
||||
case "0":
|
||||
return 0;
|
||||
case "error":
|
||||
case "2":
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/durable-objects/queue.js
|
||||
import { DurableObject } from "cloudflare:workers";
|
||||
var DEFAULT_MAX_REVALIDATION = 5;
|
||||
var DEFAULT_REVALIDATION_TIMEOUT_MS = 1e4;
|
||||
var DEFAULT_RETRY_INTERVAL_MS = 2e3;
|
||||
var DEFAULT_MAX_RETRIES = 6;
|
||||
var DOQueueHandler = class extends DurableObject {
|
||||
// Ongoing revalidations are deduped by the deduplication id
|
||||
// Since this is running in waitUntil, we expect the durable object state to persist this during the duration of the revalidation
|
||||
// TODO: handle incremental cache with only eventual consistency (i.e. KV or R2/D1 with the optional cache layer on top)
|
||||
ongoingRevalidations = /* @__PURE__ */ new Map();
|
||||
sql;
|
||||
routeInFailedState = /* @__PURE__ */ new Map();
|
||||
service;
|
||||
// Configurable params
|
||||
maxRevalidations;
|
||||
revalidationTimeout;
|
||||
revalidationRetryInterval;
|
||||
maxRetries;
|
||||
disableSQLite;
|
||||
constructor(ctx, env) {
|
||||
super(ctx, env);
|
||||
this.service = env.WORKER_SELF_REFERENCE;
|
||||
if (!this.service)
|
||||
throw new IgnorableError("No service binding for cache revalidation worker");
|
||||
this.sql = ctx.storage.sql;
|
||||
this.maxRevalidations = env.NEXT_CACHE_DO_QUEUE_MAX_REVALIDATION ? parseInt(env.NEXT_CACHE_DO_QUEUE_MAX_REVALIDATION) : DEFAULT_MAX_REVALIDATION;
|
||||
this.revalidationTimeout = env.NEXT_CACHE_DO_QUEUE_REVALIDATION_TIMEOUT_MS ? parseInt(env.NEXT_CACHE_DO_QUEUE_REVALIDATION_TIMEOUT_MS) : DEFAULT_REVALIDATION_TIMEOUT_MS;
|
||||
this.revalidationRetryInterval = env.NEXT_CACHE_DO_QUEUE_RETRY_INTERVAL_MS ? parseInt(env.NEXT_CACHE_DO_QUEUE_RETRY_INTERVAL_MS) : DEFAULT_RETRY_INTERVAL_MS;
|
||||
this.maxRetries = env.NEXT_CACHE_DO_QUEUE_MAX_RETRIES ? parseInt(env.NEXT_CACHE_DO_QUEUE_MAX_RETRIES) : DEFAULT_MAX_RETRIES;
|
||||
this.disableSQLite = env.NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE === "true";
|
||||
ctx.blockConcurrencyWhile(async () => {
|
||||
debug(`Restoring the state of the durable object`);
|
||||
await this.initState();
|
||||
});
|
||||
debug(`Durable object initialized`);
|
||||
}
|
||||
async revalidate(msg) {
|
||||
if (this.ongoingRevalidations.size > 2 * this.maxRevalidations) {
|
||||
warn(`Your durable object has 2 times the maximum number of revalidations (${this.maxRevalidations}) in progress. If this happens often, you should consider increasing the NEXT_CACHE_DO_QUEUE_MAX_REVALIDATION or the number of durable objects with the MAX_REVALIDATE_CONCURRENCY env var.`);
|
||||
}
|
||||
if (this.ongoingRevalidations.has(msg.MessageDeduplicationId))
|
||||
return;
|
||||
if (this.routeInFailedState.has(msg.MessageDeduplicationId))
|
||||
return;
|
||||
if (this.checkSyncTable(msg))
|
||||
return;
|
||||
if (this.ongoingRevalidations.size >= this.maxRevalidations) {
|
||||
debug(`The maximum number of revalidations (${this.maxRevalidations}) is reached. Blocking until one of the revalidations finishes.`);
|
||||
while (this.ongoingRevalidations.size >= this.maxRevalidations) {
|
||||
const ongoingRevalidations = this.ongoingRevalidations.values();
|
||||
debug(`Waiting for one of the revalidations to finish`);
|
||||
await Promise.race(ongoingRevalidations);
|
||||
}
|
||||
}
|
||||
const revalidationPromise = this.executeRevalidation(msg);
|
||||
this.ongoingRevalidations.set(msg.MessageDeduplicationId, revalidationPromise);
|
||||
this.ctx.waitUntil(revalidationPromise);
|
||||
}
|
||||
async executeRevalidation(msg) {
|
||||
let response;
|
||||
try {
|
||||
debug(`Revalidating ${msg.MessageBody.host}${msg.MessageBody.url}`);
|
||||
const { MessageBody: { host, url } } = msg;
|
||||
const protocol = host.includes("localhost") ? "http" : "https";
|
||||
response = await this.service.fetch(`${protocol}://${host}${url}`, {
|
||||
method: "HEAD",
|
||||
headers: {
|
||||
// This is defined during build
|
||||
"x-prerender-revalidate": "9212b8c54d8f2aaa5cb15dca46a16684",
|
||||
"x-isr": "1"
|
||||
},
|
||||
// This one is kind of problematic, it will always show the wall time of the revalidation to `this.revalidationTimeout`
|
||||
signal: AbortSignal.timeout(this.revalidationTimeout)
|
||||
});
|
||||
if (response.status === 200 && response.headers.get("x-nextjs-cache") !== "REVALIDATED") {
|
||||
this.routeInFailedState.delete(msg.MessageDeduplicationId);
|
||||
throw new FatalError(`The revalidation for ${host}${url} cannot be done. This error should never happen.`);
|
||||
} else if (response.status === 404) {
|
||||
this.routeInFailedState.delete(msg.MessageDeduplicationId);
|
||||
throw new IgnorableError(`The revalidation for ${host}${url} cannot be done because the page is not found. It's either expected or an error in user code itself`);
|
||||
} else if (response.status === 500) {
|
||||
await this.addToFailedState(msg);
|
||||
throw new IgnorableError(`Something went wrong while revalidating ${host}${url}`);
|
||||
} else if (response.status !== 200) {
|
||||
await this.addToFailedState(msg);
|
||||
throw new RecoverableError(`An unknown error occurred while revalidating ${host}${url}`);
|
||||
}
|
||||
if (!this.disableSQLite) {
|
||||
this.sql.exec(
|
||||
"INSERT OR REPLACE INTO sync (id, lastSuccess, buildId) VALUES (?, unixepoch(), ?)",
|
||||
// We cannot use the deduplication id because it's not unique per route - every time a route is revalidated, the deduplication id is different.
|
||||
`${host}${url}`,
|
||||
"Bi3XXPy0fxaJxYXDBsshm"
|
||||
);
|
||||
}
|
||||
this.routeInFailedState.delete(msg.MessageDeduplicationId);
|
||||
} catch (e) {
|
||||
if (!isOpenNextError(e)) {
|
||||
await this.addToFailedState(msg);
|
||||
}
|
||||
error(e);
|
||||
} finally {
|
||||
this.ongoingRevalidations.delete(msg.MessageDeduplicationId);
|
||||
try {
|
||||
await response?.body?.cancel();
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
async alarm() {
|
||||
const currentDateTime = Date.now();
|
||||
const nextEventToRetry = Array.from(this.routeInFailedState.values()).filter(({ nextAlarmMs }) => nextAlarmMs > currentDateTime).sort(({ nextAlarmMs: a }, { nextAlarmMs: b }) => a - b)[0];
|
||||
const expiredEvents = Array.from(this.routeInFailedState.values()).filter(({ nextAlarmMs }) => nextAlarmMs <= currentDateTime);
|
||||
const allEventsToRetry = nextEventToRetry ? [nextEventToRetry, ...expiredEvents] : expiredEvents;
|
||||
for (const event of allEventsToRetry) {
|
||||
debug(`Retrying revalidation for ${event.msg.MessageBody.host}${event.msg.MessageBody.url}`);
|
||||
await this.executeRevalidation(event.msg);
|
||||
}
|
||||
}
|
||||
async addToFailedState(msg) {
|
||||
debug(`Adding ${msg.MessageBody.host}${msg.MessageBody.url} to the failed state`);
|
||||
const existingFailedState = this.routeInFailedState.get(msg.MessageDeduplicationId);
|
||||
let updatedFailedState;
|
||||
if (existingFailedState) {
|
||||
if (existingFailedState.retryCount >= this.maxRetries) {
|
||||
error(`The revalidation for ${msg.MessageBody.host}${msg.MessageBody.url} has failed after ${this.maxRetries} retries. It will not be tried again, but subsequent ISR requests will retry.`);
|
||||
this.routeInFailedState.delete(msg.MessageDeduplicationId);
|
||||
return;
|
||||
}
|
||||
const nextAlarmMs = Date.now() + Math.pow(2, existingFailedState.retryCount + 1) * this.revalidationRetryInterval;
|
||||
updatedFailedState = {
|
||||
...existingFailedState,
|
||||
retryCount: existingFailedState.retryCount + 1,
|
||||
nextAlarmMs
|
||||
};
|
||||
} else {
|
||||
updatedFailedState = {
|
||||
msg,
|
||||
retryCount: 1,
|
||||
nextAlarmMs: Date.now() + 2e3
|
||||
};
|
||||
}
|
||||
this.routeInFailedState.set(msg.MessageDeduplicationId, updatedFailedState);
|
||||
if (!this.disableSQLite) {
|
||||
this.sql.exec("INSERT OR REPLACE INTO failed_state (id, data, buildId) VALUES (?, ?, ?)", msg.MessageDeduplicationId, JSON.stringify(updatedFailedState), "Bi3XXPy0fxaJxYXDBsshm");
|
||||
}
|
||||
await this.addAlarm();
|
||||
}
|
||||
async addAlarm() {
|
||||
const existingAlarm = await this.ctx.storage.getAlarm({ allowConcurrency: false });
|
||||
if (existingAlarm)
|
||||
return;
|
||||
if (this.routeInFailedState.size === 0)
|
||||
return;
|
||||
let nextAlarmToSetup = Math.min(...Array.from(this.routeInFailedState.values()).map(({ nextAlarmMs }) => nextAlarmMs));
|
||||
if (nextAlarmToSetup < Date.now()) {
|
||||
nextAlarmToSetup = Date.now() + this.revalidationRetryInterval;
|
||||
}
|
||||
await this.ctx.storage.setAlarm(nextAlarmToSetup);
|
||||
}
|
||||
// This function is used to restore the state of the durable object
|
||||
// We don't restore the ongoing revalidations because we cannot know in which state they are
|
||||
// We only restore the failed state and the alarm
|
||||
async initState() {
|
||||
if (this.disableSQLite)
|
||||
return;
|
||||
this.sql.exec("CREATE TABLE IF NOT EXISTS failed_state (id TEXT PRIMARY KEY, data TEXT, buildId TEXT)");
|
||||
this.sql.exec("CREATE TABLE IF NOT EXISTS sync (id TEXT PRIMARY KEY, lastSuccess INTEGER, buildId TEXT)");
|
||||
this.sql.exec("DELETE FROM failed_state WHERE buildId != ?", "Bi3XXPy0fxaJxYXDBsshm");
|
||||
this.sql.exec("DELETE FROM sync WHERE buildId != ?", "Bi3XXPy0fxaJxYXDBsshm");
|
||||
const failedStateCursor = this.sql.exec("SELECT * FROM failed_state");
|
||||
for (const row of failedStateCursor) {
|
||||
this.routeInFailedState.set(row.id, JSON.parse(row.data));
|
||||
}
|
||||
await this.addAlarm();
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param msg
|
||||
* @returns `true` if the route has been revalidated since the lastModified from the message, `false` otherwise
|
||||
*/
|
||||
checkSyncTable(msg) {
|
||||
try {
|
||||
if (this.disableSQLite)
|
||||
return false;
|
||||
return this.sql.exec("SELECT 1 FROM sync WHERE id = ? AND lastSuccess > ? LIMIT 1", `${msg.MessageBody.host}${msg.MessageBody.url}`, Math.round(msg.MessageBody.lastModified / 1e3)).toArray().length > 0;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
export {
|
||||
DOQueueHandler
|
||||
};
|
||||
55
.open-next 2/.build/durable-objects/sharded-tag-cache.js
Normal file
@ -0,0 +1,55 @@
|
||||
globalThis.openNextDebug = false;globalThis.openNextVersion = "3.9.12";
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/durable-objects/sharded-tag-cache.js
|
||||
import { DurableObject } from "cloudflare:workers";
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/cloudflare-context.js
|
||||
var cloudflareContextSymbol = Symbol.for("__cloudflare-context__");
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/overrides/internal.js
|
||||
var debugCache = (name, ...args) => {
|
||||
if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {
|
||||
console.log(`[${name}] `, ...args);
|
||||
}
|
||||
};
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/api/durable-objects/sharded-tag-cache.js
|
||||
var DOShardedTagCache = class extends DurableObject {
|
||||
sql;
|
||||
constructor(state, env) {
|
||||
super(state, env);
|
||||
this.sql = state.storage.sql;
|
||||
state.blockConcurrencyWhile(async () => {
|
||||
this.sql.exec(`CREATE TABLE IF NOT EXISTS revalidations (tag TEXT PRIMARY KEY, revalidatedAt INTEGER)`);
|
||||
});
|
||||
}
|
||||
async getLastRevalidated(tags) {
|
||||
try {
|
||||
const result = this.sql.exec(`SELECT MAX(revalidatedAt) AS time FROM revalidations WHERE tag IN (${tags.map(() => "?").join(", ")})`, ...tags).toArray();
|
||||
const timeMs = result[0]?.time ?? 0;
|
||||
debugCache("DOShardedTagCache", `getLastRevalidated tags=${tags} -> time=${timeMs}`);
|
||||
return timeMs;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
async hasBeenRevalidated(tags, lastModified) {
|
||||
const revalidated = this.sql.exec(`SELECT 1 FROM revalidations WHERE tag IN (${tags.map(() => "?").join(", ")}) AND revalidatedAt > ? LIMIT 1`, ...tags, lastModified ?? Date.now()).toArray().length > 0;
|
||||
debugCache("DOShardedTagCache", `hasBeenRevalidated tags=${tags} -> revalidated=${revalidated}`);
|
||||
return revalidated;
|
||||
}
|
||||
async writeTags(tags, lastModified) {
|
||||
debugCache("DOShardedTagCache", `writeTags tags=${tags} time=${lastModified}`);
|
||||
tags.forEach((tag) => {
|
||||
this.sql.exec(`INSERT OR REPLACE INTO revalidations (tag, revalidatedAt) VALUES (?, ?)`, tag, lastModified);
|
||||
});
|
||||
}
|
||||
async getRevalidationTimes(tags) {
|
||||
const result = this.sql.exec(`SELECT tag, revalidatedAt FROM revalidations WHERE tag IN (${tags.map(() => "?").join(", ")})`, ...tags).toArray();
|
||||
return Object.fromEntries(result.map((row) => [row.tag, row.revalidatedAt]));
|
||||
}
|
||||
};
|
||||
export {
|
||||
DOShardedTagCache
|
||||
};
|
||||
29
.open-next 2/.build/open-next.config.edge.mjs
Normal file
@ -0,0 +1,29 @@
|
||||
// open-next.config.ts
|
||||
var config = {
|
||||
default: {
|
||||
override: {
|
||||
wrapper: "cloudflare-node",
|
||||
converter: "edge",
|
||||
proxyExternalRequest: "fetch",
|
||||
incrementalCache: "dummy",
|
||||
tagCache: "dummy",
|
||||
queue: "dummy"
|
||||
}
|
||||
},
|
||||
edgeExternals: ["node:crypto"],
|
||||
middleware: {
|
||||
external: true,
|
||||
override: {
|
||||
wrapper: "cloudflare-edge",
|
||||
converter: "edge",
|
||||
proxyExternalRequest: "fetch",
|
||||
incrementalCache: "dummy",
|
||||
tagCache: "dummy",
|
||||
queue: "dummy"
|
||||
}
|
||||
}
|
||||
};
|
||||
var open_next_config_default = config;
|
||||
export {
|
||||
open_next_config_default as default
|
||||
};
|
||||
31
.open-next 2/.build/open-next.config.mjs
Normal file
@ -0,0 +1,31 @@
|
||||
import { createRequire as topLevelCreateRequire } from 'module';const require = topLevelCreateRequire(import.meta.url);import bannerUrl from 'url';const __dirname = bannerUrl.fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
// open-next.config.ts
|
||||
var config = {
|
||||
default: {
|
||||
override: {
|
||||
wrapper: "cloudflare-node",
|
||||
converter: "edge",
|
||||
proxyExternalRequest: "fetch",
|
||||
incrementalCache: "dummy",
|
||||
tagCache: "dummy",
|
||||
queue: "dummy"
|
||||
}
|
||||
},
|
||||
edgeExternals: ["node:crypto"],
|
||||
middleware: {
|
||||
external: true,
|
||||
override: {
|
||||
wrapper: "cloudflare-edge",
|
||||
converter: "edge",
|
||||
proxyExternalRequest: "fetch",
|
||||
incrementalCache: "dummy",
|
||||
tagCache: "dummy",
|
||||
queue: "dummy"
|
||||
}
|
||||
}
|
||||
};
|
||||
var open_next_config_default = config;
|
||||
export {
|
||||
open_next_config_default as default
|
||||
};
|
||||
1
.open-next 2/assets/BUILD_ID
Normal file
@ -0,0 +1 @@
|
||||
Bi3XXPy0fxaJxYXDBsshm
|
||||
@ -0,0 +1,11 @@
|
||||
self.__BUILD_MANIFEST = {
|
||||
"__rewrites": {
|
||||
"afterFiles": [],
|
||||
"beforeFiles": [],
|
||||
"fallback": []
|
||||
},
|
||||
"sortedPages": [
|
||||
"/_app",
|
||||
"/_error"
|
||||
]
|
||||
};self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()
|
||||
@ -0,0 +1 @@
|
||||
[]
|
||||
@ -0,0 +1 @@
|
||||
self.__SSG_MANIFEST=new Set([]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|
||||
@ -0,0 +1 @@
|
||||
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,33525,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"warnOnce",{enumerable:!0,get:function(){return o}});let o=e=>{}},97703,e=>{"use strict";var t=e.i(43476),r=e.i(71645);let o=(0,r.createContext)(void 0);function i({children:e}){let[i,s]=(0,r.useState)("dark");return(0,r.useEffect)(()=>{let e=localStorage.getItem("theme");e&&s(e)},[]),(0,r.useEffect)(()=>{let e=document.documentElement;"dark"===i?e.classList.add("dark"):e.classList.remove("dark")},[i]),(0,t.jsx)(o.Provider,{value:{theme:i,toggleTheme:()=>{let e="dark"===i?"light":"dark";s(e),localStorage.setItem("theme",e)}},children:e})}function s(){let e=(0,r.useContext)(o);if(!e)throw Error("useTheme must be used within a ThemeProvider");return e}e.s(["ThemeProvider",()=>i,"useTheme",()=>s])},30824,e=>{"use strict";var t=e.i(43476),r=e.i(97703);function o({children:e}){return(0,t.jsx)(r.ThemeProvider,{children:e})}e.s(["Providers",()=>o])}]);
|
||||
@ -0,0 +1 @@
|
||||
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,82365,65960,a=>{"use strict";var t=a.i(75254);let e=(0,t.default)("wind",[["path",{d:"M12.8 19.6A2 2 0 1 0 14 16H2",key:"148xed"}],["path",{d:"M17.5 8a2.5 2.5 0 1 1 2 4H2",key:"1u4tom"}],["path",{d:"M9.8 4.4A2 2 0 1 1 11 8H2",key:"75valh"}]]);a.s(["Wind",()=>e],82365);let d=(0,t.default)("quote",[["path",{d:"M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z",key:"rib7q0"}],["path",{d:"M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z",key:"1ymkrd"}]]);a.s(["Quote",()=>d],65960)}]);
|
||||
@ -0,0 +1 @@
|
||||
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,97703,e=>{"use strict";var t=e.i(43476),r=e.i(71645);let o=(0,r.createContext)(void 0);function i({children:e}){let[i,s]=(0,r.useState)("dark");return(0,r.useEffect)(()=>{let e=localStorage.getItem("theme");e&&s(e)},[]),(0,r.useEffect)(()=>{let e=document.documentElement;"dark"===i?e.classList.add("dark"):e.classList.remove("dark")},[i]),(0,t.jsx)(o.Provider,{value:{theme:i,toggleTheme:()=>{let e="dark"===i?"light":"dark";s(e),localStorage.setItem("theme",e)}},children:e})}function s(){let e=(0,r.useContext)(o);if(!e)throw Error("useTheme must be used within a ThemeProvider");return e}e.s(["ThemeProvider",()=>i,"useTheme",()=>s])},30824,e=>{"use strict";var t=e.i(43476),r=e.i(97703);function o({children:e}){return(0,t.jsx)(r.ThemeProvider,{children:e})}e.s(["Providers",()=>o])}]);
|
||||
@ -0,0 +1 @@
|
||||
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,33525,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"warnOnce",{enumerable:!0,get:function(){return n}});let n=e=>{}}]);
|
||||
1
.open-next 2/assets/file.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 391 B |
1
.open-next 2/assets/globe.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
BIN
.open-next 2/assets/icons/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 413 KiB |
BIN
.open-next 2/assets/icons/icon-512.png
Normal file
|
After Width: | Height: | Size: 413 KiB |
29
.open-next 2/assets/manifest.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "QuitTraq - Track Your Progress",
|
||||
"short_name": "QuitTraq",
|
||||
"description": "Track your nicotine and marijuana usage to quit smoking",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#0a0a0f",
|
||||
"theme_color": "#8b5cf6",
|
||||
"orientation": "portrait-primary",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icons/icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
},
|
||||
{
|
||||
"src": "/icons/icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
"health",
|
||||
"lifestyle",
|
||||
"medical"
|
||||
]
|
||||
}
|
||||
1
.open-next 2/assets/next.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
11
.open-next 2/assets/smoke.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<filter id="noiseFilter">
|
||||
<feTurbulence
|
||||
type="fractalNoise"
|
||||
baseFrequency="0.04"
|
||||
numOctaves="6"
|
||||
stitchTiles="stitch" />
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 -1.5 0 0.2 0"/>
|
||||
</filter>
|
||||
<rect width="100%" height="100%" filter="url(#noiseFilter)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 395 B |
49
.open-next 2/assets/sw.js
Normal file
@ -0,0 +1,49 @@
|
||||
self.addEventListener('push', function (event) {
|
||||
if (!(self.Notification && self.Notification.permission === 'granted')) {
|
||||
return;
|
||||
}
|
||||
|
||||
let data = {};
|
||||
if (event.data) {
|
||||
try {
|
||||
data = event.data.json();
|
||||
} catch (e) {
|
||||
data = { title: 'QuitTraq', body: event.data.text() };
|
||||
}
|
||||
}
|
||||
|
||||
const title = data.title || 'QuitTraq Update';
|
||||
const options = {
|
||||
body: data.body || 'Check in on your progress!',
|
||||
icon: '/icon-192.png',
|
||||
badge: '/icon-192.png',
|
||||
tag: data.tag || 'generic-notification',
|
||||
data: data.data || {},
|
||||
requireInteraction: true
|
||||
};
|
||||
|
||||
event.waitUntil(
|
||||
self.registration.showNotification(title, options)
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('notificationclick', function (event) {
|
||||
event.notification.close();
|
||||
|
||||
// This looks to see if the current is already open and focuses if it is
|
||||
event.waitUntil(
|
||||
clients.matchAll({
|
||||
type: "window"
|
||||
})
|
||||
.then(function (clientList) {
|
||||
for (var i = 0; i < clientList.length; i++) {
|
||||
var client = clientList[i];
|
||||
if (client.url == '/' && 'focus' in client)
|
||||
return client.focus();
|
||||
}
|
||||
if (clients.openWindow) {
|
||||
return clients.openWindow('/');
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
1
.open-next 2/assets/vercel.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 128 B |
1
.open-next 2/assets/window.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||
|
After Width: | Height: | Size: 385 B |
1
.open-next 2/cache/Bi3XXPy0fxaJxYXDBsshm/_global-error.cache
vendored
Normal file
1
.open-next 2/cache/Bi3XXPy0fxaJxYXDBsshm/_not-found.cache
vendored
Normal file
1
.open-next 2/cache/Bi3XXPy0fxaJxYXDBsshm/login.cache
vendored
Normal file
55
.open-next 2/cloudflare-templates/images.d.ts
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
export type RemotePattern = {
|
||||
protocol?: "http" | "https";
|
||||
hostname: string;
|
||||
port?: string;
|
||||
pathname: string;
|
||||
search?: string;
|
||||
};
|
||||
export type LocalPattern = {
|
||||
pathname: string;
|
||||
search?: string;
|
||||
};
|
||||
/**
|
||||
* Handles requests to /_next/image(/), including image optimizations.
|
||||
*
|
||||
* Image optimization is disabled and the original image is returned if `env.IMAGES` is undefined.
|
||||
*
|
||||
* Throws an exception on unexpected errors.
|
||||
*
|
||||
* @param requestURL
|
||||
* @param requestHeaders
|
||||
* @param env
|
||||
* @returns A promise that resolves to the resolved request.
|
||||
*/
|
||||
export declare function handleImageRequest(requestURL: URL, requestHeaders: Headers, env: CloudflareEnv): Promise<Response>;
|
||||
export type OptimizedImageFormat = "image/avif" | "image/webp";
|
||||
export declare function matchLocalPattern(pattern: LocalPattern, url: {
|
||||
pathname: string;
|
||||
search: string;
|
||||
}): boolean;
|
||||
export declare function matchRemotePattern(pattern: RemotePattern, url: URL): boolean;
|
||||
type ImageContentType = "image/avif" | "image/webp" | "image/png" | "image/jpeg" | "image/jxl" | "image/jp2" | "image/heic" | "image/gif" | "image/svg+xml" | "image/x-icon" | "image/x-icns" | "image/tiff" | "image/bmp";
|
||||
/**
|
||||
* Detects the content type by looking at the first few bytes of a file
|
||||
*
|
||||
* Based on https://github.com/vercel/next.js/blob/72c9635/packages/next/src/server/image-optimizer.ts#L155
|
||||
*
|
||||
* @param buffer The image bytes
|
||||
* @returns a content type of undefined for unsupported content
|
||||
*/
|
||||
export declare function detectImageContentType(buffer: Uint8Array): ImageContentType | null;
|
||||
declare global {
|
||||
var __IMAGES_REMOTE_PATTERNS__: RemotePattern[];
|
||||
var __IMAGES_LOCAL_PATTERNS__: LocalPattern[];
|
||||
var __IMAGES_DEVICE_SIZES__: number[];
|
||||
var __IMAGES_IMAGE_SIZES__: number[];
|
||||
var __IMAGES_QUALITIES__: number[];
|
||||
var __IMAGES_FORMATS__: NextConfigImageFormat[];
|
||||
var __IMAGES_MINIMUM_CACHE_TTL_SEC__: number;
|
||||
var __IMAGES_ALLOW_SVG__: boolean;
|
||||
var __IMAGES_CONTENT_SECURITY_POLICY__: string;
|
||||
var __IMAGES_CONTENT_DISPOSITION__: string;
|
||||
var __IMAGES_MAX_REDIRECTS__: number;
|
||||
type NextConfigImageFormat = "image/avif" | "image/webp";
|
||||
}
|
||||
export {};
|
||||
573
.open-next 2/cloudflare-templates/images.js
Normal file
@ -0,0 +1,573 @@
|
||||
import { error, warn } from "@opennextjs/aws/adapters/logger.js";
|
||||
/**
|
||||
* Handles requests to /_next/image(/), including image optimizations.
|
||||
*
|
||||
* Image optimization is disabled and the original image is returned if `env.IMAGES` is undefined.
|
||||
*
|
||||
* Throws an exception on unexpected errors.
|
||||
*
|
||||
* @param requestURL
|
||||
* @param requestHeaders
|
||||
* @param env
|
||||
* @returns A promise that resolves to the resolved request.
|
||||
*/
|
||||
export async function handleImageRequest(requestURL, requestHeaders, env) {
|
||||
const parseResult = parseImageRequest(requestURL, requestHeaders);
|
||||
if (!parseResult.ok) {
|
||||
return new Response(parseResult.message, {
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
let imageResponse;
|
||||
if (parseResult.url.startsWith("/")) {
|
||||
if (env.ASSETS === undefined) {
|
||||
error("env.ASSETS binding is not defined");
|
||||
return new Response('"url" parameter is valid but upstream response is invalid', {
|
||||
status: 404,
|
||||
});
|
||||
}
|
||||
const absoluteURL = new URL(parseResult.url, requestURL);
|
||||
imageResponse = await env.ASSETS.fetch(absoluteURL);
|
||||
}
|
||||
else {
|
||||
let fetchImageResult;
|
||||
try {
|
||||
fetchImageResult = await fetchWithRedirects(parseResult.url, 7_000, __IMAGES_MAX_REDIRECTS__);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error("Failed to fetch image", { cause: e });
|
||||
}
|
||||
if (!fetchImageResult.ok) {
|
||||
if (fetchImageResult.error === "timed_out") {
|
||||
return new Response('"url" parameter is valid but upstream response timed out', {
|
||||
status: 504,
|
||||
});
|
||||
}
|
||||
if (fetchImageResult.error === "too_many_redirects") {
|
||||
return new Response('"url" parameter is valid but upstream response is invalid', {
|
||||
status: 508,
|
||||
});
|
||||
}
|
||||
throw new Error("Failed to fetch image");
|
||||
}
|
||||
imageResponse = fetchImageResult.response;
|
||||
}
|
||||
if (!imageResponse.ok || imageResponse.body === null) {
|
||||
return new Response('"url" parameter is valid but upstream response is invalid', {
|
||||
status: imageResponse.status,
|
||||
});
|
||||
}
|
||||
let immutable = false;
|
||||
if (parseResult.static) {
|
||||
immutable = true;
|
||||
}
|
||||
else {
|
||||
const cacheControlHeader = imageResponse.headers.get("Cache-Control");
|
||||
if (cacheControlHeader !== null) {
|
||||
// TODO: Properly parse header
|
||||
immutable = cacheControlHeader.includes("immutable");
|
||||
}
|
||||
}
|
||||
const [contentTypeImageStream, imageStream] = imageResponse.body.tee();
|
||||
const imageHeaderBytes = new Uint8Array(32);
|
||||
const contentTypeImageReader = contentTypeImageStream.getReader({
|
||||
mode: "byob",
|
||||
});
|
||||
const readImageHeaderBytesResult = await contentTypeImageReader.readAtLeast(32, imageHeaderBytes);
|
||||
if (readImageHeaderBytesResult.value === undefined) {
|
||||
await imageResponse.body.cancel();
|
||||
return new Response('"url" parameter is valid but upstream response is invalid', {
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
const contentType = detectImageContentType(readImageHeaderBytesResult.value);
|
||||
if (contentType === null) {
|
||||
warn(`Failed to detect content type of "${parseResult.url}"`);
|
||||
return new Response('"url" parameter is valid but image type is not allowed', {
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
if (contentType === SVG) {
|
||||
if (!__IMAGES_ALLOW_SVG__) {
|
||||
return new Response('"url" parameter is valid but image type is not allowed', {
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
const response = createImageResponse(imageStream, contentType, {
|
||||
immutable,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
if (contentType === GIF) {
|
||||
if (env.IMAGES === undefined) {
|
||||
warn("env.IMAGES binding is not defined");
|
||||
const response = createImageResponse(imageStream, contentType, {
|
||||
immutable,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
const imageSource = env.IMAGES.input(imageStream);
|
||||
const imageTransformationResult = await imageSource
|
||||
.transform({
|
||||
width: parseResult.width,
|
||||
fit: "scale-down",
|
||||
})
|
||||
.output({
|
||||
quality: parseResult.quality,
|
||||
format: GIF,
|
||||
});
|
||||
const outputImageStream = imageTransformationResult.image();
|
||||
const response = createImageResponse(outputImageStream, GIF, {
|
||||
immutable,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
if (contentType === AVIF || contentType === WEBP || contentType === JPEG || contentType === PNG) {
|
||||
if (env.IMAGES === undefined) {
|
||||
warn("env.IMAGES binding is not defined");
|
||||
const response = createImageResponse(imageStream, contentType, {
|
||||
immutable,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
const outputFormat = parseResult.format ?? contentType;
|
||||
const imageSource = env.IMAGES.input(imageStream);
|
||||
const imageTransformationResult = await imageSource
|
||||
.transform({
|
||||
width: parseResult.width,
|
||||
fit: "scale-down",
|
||||
})
|
||||
.output({
|
||||
quality: parseResult.quality,
|
||||
format: outputFormat,
|
||||
});
|
||||
const outputImageStream = imageTransformationResult.image();
|
||||
const response = createImageResponse(outputImageStream, outputFormat, {
|
||||
immutable,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
warn(`Image content type ${contentType} not supported`);
|
||||
const response = createImageResponse(imageStream, contentType, {
|
||||
immutable,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
/**
|
||||
* Fetch call with max redirects and timeouts.
|
||||
*
|
||||
* Re-throws the exception thrown by a fetch call.
|
||||
* @param url
|
||||
* @param timeoutMS Timeout for a single fetch call.
|
||||
* @param maxRedirectCount
|
||||
* @returns
|
||||
*/
|
||||
async function fetchWithRedirects(url, timeoutMS, maxRedirectCount) {
|
||||
// TODO: Add dangerouslyAllowLocalIP support
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(url, {
|
||||
signal: AbortSignal.timeout(timeoutMS),
|
||||
redirect: "manual",
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof Error && e.name === "TimeoutError") {
|
||||
const result = {
|
||||
ok: false,
|
||||
error: "timed_out",
|
||||
};
|
||||
return result;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
if (redirectResponseStatuses.includes(response.status)) {
|
||||
const locationHeader = response.headers.get("Location");
|
||||
if (locationHeader !== null) {
|
||||
if (maxRedirectCount < 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
error: "too_many_redirects",
|
||||
};
|
||||
return result;
|
||||
}
|
||||
let redirectTarget;
|
||||
if (locationHeader.startsWith("/")) {
|
||||
redirectTarget = new URL(locationHeader, url).href;
|
||||
}
|
||||
else {
|
||||
redirectTarget = locationHeader;
|
||||
}
|
||||
const result = await fetchWithRedirects(redirectTarget, timeoutMS, maxRedirectCount - 1);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
const result = {
|
||||
ok: true,
|
||||
response: response,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const redirectResponseStatuses = [301, 302, 303, 307, 308];
|
||||
function createImageResponse(image, contentType, imageResponseFlags) {
|
||||
const response = new Response(image, {
|
||||
headers: {
|
||||
Vary: "Accept",
|
||||
"Content-Type": contentType,
|
||||
"Content-Disposition": __IMAGES_CONTENT_DISPOSITION__,
|
||||
"Content-Security-Policy": __IMAGES_CONTENT_SECURITY_POLICY__,
|
||||
},
|
||||
});
|
||||
if (imageResponseFlags.immutable) {
|
||||
response.headers.set("Cache-Control", "public, max-age=315360000, immutable");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
/**
|
||||
* Parses the image request URL and headers.
|
||||
*
|
||||
* This function validates the parameters and returns either the parsed result or an error message.
|
||||
*
|
||||
* @param requestURL request URL
|
||||
* @param requestHeaders request headers
|
||||
* @returns an instance of `ParseImageRequestURLSuccessResult` when successful, or an instance of `ErrorResult` when failed.
|
||||
*/
|
||||
function parseImageRequest(requestURL, requestHeaders) {
|
||||
const formats = __IMAGES_FORMATS__;
|
||||
const parsedUrlOrError = validateUrlQueryParameter(requestURL);
|
||||
if (!("url" in parsedUrlOrError)) {
|
||||
return parsedUrlOrError;
|
||||
}
|
||||
const widthOrError = validateWidthQueryParameter(requestURL);
|
||||
if (typeof widthOrError !== "number") {
|
||||
return widthOrError;
|
||||
}
|
||||
const qualityOrError = validateQualityQueryParameter(requestURL);
|
||||
if (typeof qualityOrError !== "number") {
|
||||
return qualityOrError;
|
||||
}
|
||||
const acceptHeader = requestHeaders.get("Accept") ?? "";
|
||||
let format = null;
|
||||
// Find a more specific format that the client accepts.
|
||||
for (const allowedFormat of formats) {
|
||||
if (acceptHeader.includes(allowedFormat)) {
|
||||
format = allowedFormat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const result = {
|
||||
ok: true,
|
||||
url: parsedUrlOrError.url,
|
||||
width: widthOrError,
|
||||
quality: qualityOrError,
|
||||
format,
|
||||
static: parsedUrlOrError.static,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Validates that there is exactly one "url" query parameter.
|
||||
*
|
||||
* @returns the validated URL or an error result.
|
||||
*/
|
||||
function validateUrlQueryParameter(requestURL) {
|
||||
// There should be a single "url" parameter.
|
||||
const urls = requestURL.searchParams.getAll("url");
|
||||
if (urls.length < 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter is required',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (urls.length > 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter cannot be an array',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
// The url parameter value should be a valid URL or a valid relative URL.
|
||||
const url = urls[0];
|
||||
if (url.length > 3072) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter is too long',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (url.startsWith("//")) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter cannot be a protocol-relative URL (//)',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (url.startsWith("/")) {
|
||||
const staticAsset = url.startsWith(`${__NEXT_BASE_PATH__ || ""}/_next/static/media`);
|
||||
const pathname = getPathnameFromRelativeURL(url);
|
||||
if (/\/_next\/image($|\/)/.test(decodeURIComponent(pathname))) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter cannot be recursive',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (!staticAsset) {
|
||||
if (!hasLocalMatch(__IMAGES_LOCAL_PATTERNS__, url)) {
|
||||
const result = { ok: false, message: '"url" parameter is not allowed' };
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return { url, static: staticAsset };
|
||||
}
|
||||
let parsedURL;
|
||||
try {
|
||||
parsedURL = new URL(url);
|
||||
}
|
||||
catch {
|
||||
const result = { ok: false, message: '"url" parameter is invalid' };
|
||||
return result;
|
||||
}
|
||||
const validProtocols = ["http:", "https:"];
|
||||
if (!validProtocols.includes(parsedURL.protocol)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter is invalid',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (!hasRemoteMatch(__IMAGES_REMOTE_PATTERNS__, parsedURL)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter is not allowed',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
return { url: parsedURL.href, static: false };
|
||||
}
|
||||
/**
|
||||
* Validates the "w" (width) query parameter.
|
||||
*
|
||||
* @returns the validated width number or an error result.
|
||||
*/
|
||||
function validateWidthQueryParameter(requestURL) {
|
||||
const widthQueryValues = requestURL.searchParams.getAll("w");
|
||||
if (widthQueryValues.length < 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"w" parameter (width) is required',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (widthQueryValues.length > 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"w" parameter (width) cannot be an array',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const widthQueryValue = widthQueryValues[0];
|
||||
if (!/^[0-9]+$/.test(widthQueryValue)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"w" parameter (width) must be an integer greater than 0',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const width = parseInt(widthQueryValue, 10);
|
||||
if (width <= 0 || isNaN(width)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"w" parameter (width) must be an integer greater than 0',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const sizeValid = __IMAGES_DEVICE_SIZES__.includes(width) || __IMAGES_IMAGE_SIZES__.includes(width);
|
||||
if (!sizeValid) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: `"w" parameter (width) of ${width} is not allowed`,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
/**
|
||||
* Validates the "q" (quality) query parameter.
|
||||
*
|
||||
* @returns the validated quality number or an error result.
|
||||
*/
|
||||
function validateQualityQueryParameter(requestURL) {
|
||||
const qualityQueryValues = requestURL.searchParams.getAll("q");
|
||||
if (qualityQueryValues.length < 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"q" parameter (quality) is required',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (qualityQueryValues.length > 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"q" parameter (quality) cannot be an array',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const qualityQueryValue = qualityQueryValues[0];
|
||||
if (!/^[0-9]+$/.test(qualityQueryValue)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"q" parameter (quality) must be an integer between 1 and 100',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const quality = parseInt(qualityQueryValue, 10);
|
||||
if (isNaN(quality) || quality < 1 || quality > 100) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"q" parameter (quality) must be an integer between 1 and 100',
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (!__IMAGES_QUALITIES__.includes(quality)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: `"q" parameter (quality) of ${quality} is not allowed`,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
return quality;
|
||||
}
|
||||
function getPathnameFromRelativeURL(relativeURL) {
|
||||
return relativeURL.split("?")[0];
|
||||
}
|
||||
function hasLocalMatch(localPatterns, relativeURL) {
|
||||
const parseRelativeURLResult = parseRelativeURL(relativeURL);
|
||||
for (const localPattern of localPatterns) {
|
||||
const matched = matchLocalPattern(localPattern, parseRelativeURLResult);
|
||||
if (matched) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function parseRelativeURL(relativeURL) {
|
||||
if (!relativeURL.includes("?")) {
|
||||
const result = {
|
||||
pathname: relativeURL,
|
||||
search: "",
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const parts = relativeURL.split("?");
|
||||
const pathname = parts[0];
|
||||
const search = "?" + parts.slice(1).join("?");
|
||||
const result = {
|
||||
pathname,
|
||||
search,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
export function matchLocalPattern(pattern, url) {
|
||||
if (pattern.search !== undefined && pattern.search !== url.search) {
|
||||
return false;
|
||||
}
|
||||
return new RegExp(pattern.pathname).test(url.pathname);
|
||||
}
|
||||
function hasRemoteMatch(remotePatterns, url) {
|
||||
for (const remotePattern of remotePatterns) {
|
||||
const matched = matchRemotePattern(remotePattern, url);
|
||||
if (matched) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function matchRemotePattern(pattern, url) {
|
||||
// https://github.com/vercel/next.js/blob/d76f0b1/packages/next/src/shared/lib/match-remote-pattern.ts
|
||||
if (pattern.protocol !== undefined &&
|
||||
pattern.protocol.replace(/:$/, "") !== url.protocol.replace(/:$/, "")) {
|
||||
return false;
|
||||
}
|
||||
if (pattern.port !== undefined && pattern.port !== url.port) {
|
||||
return false;
|
||||
}
|
||||
if (pattern.hostname === undefined || !new RegExp(pattern.hostname).test(url.hostname)) {
|
||||
return false;
|
||||
}
|
||||
if (pattern.search !== undefined && pattern.search !== url.search) {
|
||||
return false;
|
||||
}
|
||||
// Should be the same as writeImagesManifest()
|
||||
return new RegExp(pattern.pathname).test(url.pathname);
|
||||
}
|
||||
const AVIF = "image/avif";
|
||||
const WEBP = "image/webp";
|
||||
const PNG = "image/png";
|
||||
const JPEG = "image/jpeg";
|
||||
const JXL = "image/jxl";
|
||||
const JP2 = "image/jp2";
|
||||
const HEIC = "image/heic";
|
||||
const GIF = "image/gif";
|
||||
const SVG = "image/svg+xml";
|
||||
const ICO = "image/x-icon";
|
||||
const ICNS = "image/x-icns";
|
||||
const TIFF = "image/tiff";
|
||||
const BMP = "image/bmp";
|
||||
/**
|
||||
* Detects the content type by looking at the first few bytes of a file
|
||||
*
|
||||
* Based on https://github.com/vercel/next.js/blob/72c9635/packages/next/src/server/image-optimizer.ts#L155
|
||||
*
|
||||
* @param buffer The image bytes
|
||||
* @returns a content type of undefined for unsupported content
|
||||
*/
|
||||
export function detectImageContentType(buffer) {
|
||||
if ([0xff, 0xd8, 0xff].every((b, i) => buffer[i] === b)) {
|
||||
return JPEG;
|
||||
}
|
||||
if ([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a].every((b, i) => buffer[i] === b)) {
|
||||
return PNG;
|
||||
}
|
||||
if ([0x47, 0x49, 0x46, 0x38].every((b, i) => buffer[i] === b)) {
|
||||
return GIF;
|
||||
}
|
||||
if ([0x52, 0x49, 0x46, 0x46, 0, 0, 0, 0, 0x57, 0x45, 0x42, 0x50].every((b, i) => !b || buffer[i] === b)) {
|
||||
return WEBP;
|
||||
}
|
||||
if ([0x3c, 0x3f, 0x78, 0x6d, 0x6c].every((b, i) => buffer[i] === b)) {
|
||||
return SVG;
|
||||
}
|
||||
if ([0x3c, 0x73, 0x76, 0x67].every((b, i) => buffer[i] === b)) {
|
||||
return SVG;
|
||||
}
|
||||
if ([0, 0, 0, 0, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66].every((b, i) => !b || buffer[i] === b)) {
|
||||
return AVIF;
|
||||
}
|
||||
if ([0x00, 0x00, 0x01, 0x00].every((b, i) => buffer[i] === b)) {
|
||||
return ICO;
|
||||
}
|
||||
if ([0x69, 0x63, 0x6e, 0x73].every((b, i) => buffer[i] === b)) {
|
||||
return ICNS;
|
||||
}
|
||||
if ([0x49, 0x49, 0x2a, 0x00].every((b, i) => buffer[i] === b)) {
|
||||
return TIFF;
|
||||
}
|
||||
if ([0x42, 0x4d].every((b, i) => buffer[i] === b)) {
|
||||
return BMP;
|
||||
}
|
||||
if ([0xff, 0x0a].every((b, i) => buffer[i] === b)) {
|
||||
return JXL;
|
||||
}
|
||||
if ([0x00, 0x00, 0x00, 0x0c, 0x4a, 0x58, 0x4c, 0x20, 0x0d, 0x0a, 0x87, 0x0a].every((b, i) => buffer[i] === b)) {
|
||||
return JXL;
|
||||
}
|
||||
if ([0, 0, 0, 0, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63].every((b, i) => !b || buffer[i] === b)) {
|
||||
return HEIC;
|
||||
}
|
||||
if ([0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a].every((b, i) => buffer[i] === b)) {
|
||||
return JP2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
16
.open-next 2/cloudflare-templates/init.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Initialization for the workerd runtime.
|
||||
*
|
||||
* The file must be imported at the top level the worker.
|
||||
*/
|
||||
/**
|
||||
* Executes the handler with the Cloudflare context.
|
||||
*/
|
||||
export declare function runWithCloudflareRequestContext(request: Request, env: CloudflareEnv, ctx: ExecutionContext, handler: () => Promise<Response>): Promise<Response>;
|
||||
declare global {
|
||||
var __BUILD_TIMESTAMP_MS__: number;
|
||||
var __NEXT_BASE_PATH__: string;
|
||||
var __ASSETS_RUN_WORKER_FIRST__: boolean | string[] | undefined;
|
||||
var __DEPLOYMENT_ID__: string;
|
||||
var __TRAILING_SLASH__: boolean;
|
||||
}
|
||||
122
.open-next 2/cloudflare-templates/init.js
Normal file
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Initialization for the workerd runtime.
|
||||
*
|
||||
* The file must be imported at the top level the worker.
|
||||
*/
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
import process from "node:process";
|
||||
import stream from "node:stream";
|
||||
// @ts-expect-error: resolved by wrangler build
|
||||
import * as nextEnvVars from "./next-env.mjs";
|
||||
const cloudflareContextALS = new AsyncLocalStorage();
|
||||
// Note: this symbol needs to be kept in sync with `src/api/get-cloudflare-context.ts`
|
||||
Object.defineProperty(globalThis, Symbol.for("__cloudflare-context__"), {
|
||||
get() {
|
||||
return cloudflareContextALS.getStore();
|
||||
},
|
||||
});
|
||||
/**
|
||||
* Executes the handler with the Cloudflare context.
|
||||
*/
|
||||
export async function runWithCloudflareRequestContext(request, env, ctx, handler) {
|
||||
init(request, env);
|
||||
return cloudflareContextALS.run({ env, ctx, cf: request.cf }, handler);
|
||||
}
|
||||
let initialized = false;
|
||||
/**
|
||||
* Initializes the runtime on the first call,
|
||||
* no-op on subsequent invocations.
|
||||
*/
|
||||
function init(request, env) {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
const url = new URL(request.url);
|
||||
initRuntime();
|
||||
populateProcessEnv(url, env);
|
||||
}
|
||||
function initRuntime() {
|
||||
// Some packages rely on `process.version` and `process.versions.node` (i.e. Jose@4)
|
||||
// TODO: Remove when https://github.com/unjs/unenv/pull/493 is merged
|
||||
Object.assign(process, { version: process.version || "v22.14.0" });
|
||||
// @ts-expect-error Node type does not match workerd
|
||||
Object.assign(process.versions, { node: "22.14.0", ...process.versions });
|
||||
globalThis.__dirname ??= "";
|
||||
globalThis.__filename ??= "";
|
||||
// Some packages rely on `import.meta.url` but it is undefined in workerd
|
||||
// For example it causes a bunch of issues, and will make even import crash with payload
|
||||
import.meta.url ??= "file:///worker.js";
|
||||
// Do not crash on cache not supported
|
||||
// https://github.com/cloudflare/workerd/pull/2434
|
||||
// compatibility flag "cache_option_enabled" -> does not support "force-cache"
|
||||
const __original_fetch = globalThis.fetch;
|
||||
globalThis.fetch = (input, init) => {
|
||||
if (init) {
|
||||
delete init.cache;
|
||||
}
|
||||
return __original_fetch(input, init);
|
||||
};
|
||||
const CustomRequest = class extends globalThis.Request {
|
||||
constructor(input, init) {
|
||||
if (init) {
|
||||
delete init.cache;
|
||||
// https://github.com/cloudflare/workerd/issues/2746
|
||||
// https://github.com/cloudflare/workerd/issues/3245
|
||||
Object.defineProperty(init, "body", {
|
||||
// @ts-ignore
|
||||
value: init.body instanceof stream.Readable ? ReadableStream.from(init.body) : init.body,
|
||||
});
|
||||
}
|
||||
super(input, init);
|
||||
}
|
||||
};
|
||||
Object.assign(globalThis, {
|
||||
Request: CustomRequest,
|
||||
__BUILD_TIMESTAMP_MS__,
|
||||
__NEXT_BASE_PATH__,
|
||||
__ASSETS_RUN_WORKER_FIRST__,
|
||||
__TRAILING_SLASH__,
|
||||
// The external middleware will use the convertTo function of the `edge` converter
|
||||
// by default it will try to fetch the request, but since we are running everything in the same worker
|
||||
// we need to use the request as is.
|
||||
__dangerous_ON_edge_converter_returns_request: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Populate process.env with:
|
||||
* - the environment variables and secrets from the cloudflare platform
|
||||
* - the variables from Next .env* files
|
||||
* - the origin resolver information
|
||||
*/
|
||||
function populateProcessEnv(url, env) {
|
||||
for (const [key, value] of Object.entries(env)) {
|
||||
if (typeof value === "string") {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
const mode = env.NEXTJS_ENV ?? "production";
|
||||
if (nextEnvVars[mode]) {
|
||||
for (const key in nextEnvVars[mode]) {
|
||||
process.env[key] ??= nextEnvVars[mode][key];
|
||||
}
|
||||
}
|
||||
// Set the default Origin for the origin resolver.
|
||||
// This is only needed for an external middleware bundle
|
||||
process.env.OPEN_NEXT_ORIGIN = JSON.stringify({
|
||||
default: {
|
||||
host: url.hostname,
|
||||
protocol: url.protocol.slice(0, -1),
|
||||
port: url.port,
|
||||
},
|
||||
});
|
||||
/* We need to set this environment variable to make redirects work properly in preview mode.
|
||||
* Next sets this in standalone mode during `startServer`. Without this the protocol would always be `https` here:
|
||||
* https://github.com/vercel/next.js/blob/6b1e48080e896e0d44a05fe009cb79d2d3f91774/packages/next/src/server/app-render/action-handler.ts#L307-L316
|
||||
*/
|
||||
process.env.__NEXT_PRIVATE_ORIGIN = url.origin;
|
||||
// `__DEPLOYMENT_ID__` is a string (passed via ESBuild).
|
||||
if (__DEPLOYMENT_ID__) {
|
||||
process.env.DEPLOYMENT_ID = __DEPLOYMENT_ID__;
|
||||
}
|
||||
}
|
||||
2
.open-next 2/cloudflare-templates/shims/empty.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const _default: {};
|
||||
export default _default;
|
||||
1
.open-next 2/cloudflare-templates/shims/empty.js
Normal file
@ -0,0 +1 @@
|
||||
export default {};
|
||||
1
.open-next 2/cloudflare-templates/shims/env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export declare function loadEnvConfig(): void;
|
||||
1
.open-next 2/cloudflare-templates/shims/env.js
Normal file
@ -0,0 +1 @@
|
||||
export function loadEnvConfig() { }
|
||||
1
.open-next 2/cloudflare-templates/shims/fetch.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export default fetch;
|
||||
1
.open-next 2/cloudflare-templates/shims/fetch.js
Normal file
@ -0,0 +1 @@
|
||||
export default fetch;
|
||||
2
.open-next 2/cloudflare-templates/shims/throw.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const _default: {};
|
||||
export default _default;
|
||||
2
.open-next 2/cloudflare-templates/shims/throw.js
Normal file
@ -0,0 +1,2 @@
|
||||
throw "OpenNext shim";
|
||||
export default {};
|
||||
28
.open-next 2/cloudflare-templates/skew-protection.d.ts
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/** Name of the env var containing the mapping */
|
||||
export declare const DEPLOYMENT_MAPPING_ENV_NAME = "CF_DEPLOYMENT_MAPPING";
|
||||
/** Version used for the latest worker */
|
||||
export declare const CURRENT_VERSION_ID = "current";
|
||||
/**
|
||||
* Routes the request to the requested deployment.
|
||||
*
|
||||
* A specific deployment can be requested via:
|
||||
* - the `dpl` search parameter for assets
|
||||
* - the `x-deployment-id` for other requests
|
||||
*
|
||||
* When a specific deployment is requested, we route to that deployment via the preview URLs.
|
||||
* See https://developers.cloudflare.com/workers/configuration/previews/
|
||||
*
|
||||
* When the requested deployment is not supported a 400 response is returned.
|
||||
*
|
||||
* Notes:
|
||||
* - The re-routing is only active for the deployed version of the app (on a custom domain)
|
||||
* - Assets are also handled when `run_worker_first` is enabled.
|
||||
* See https://developers.cloudflare.com/workers/static-assets/binding/#run_worker_first
|
||||
*
|
||||
* @param request
|
||||
* @returns
|
||||
*/
|
||||
export declare function maybeGetSkewProtectionResponse(request: Request): Promise<Response> | Response | undefined;
|
||||
declare global {
|
||||
var __SKEW_PROTECTION_ENABLED__: boolean;
|
||||
}
|
||||
60
.open-next 2/cloudflare-templates/skew-protection.js
Normal file
@ -0,0 +1,60 @@
|
||||
import process from "node:process";
|
||||
/** Name of the env var containing the mapping */
|
||||
export const DEPLOYMENT_MAPPING_ENV_NAME = "CF_DEPLOYMENT_MAPPING";
|
||||
/** Version used for the latest worker */
|
||||
export const CURRENT_VERSION_ID = "current";
|
||||
let deploymentMapping;
|
||||
/**
|
||||
* Routes the request to the requested deployment.
|
||||
*
|
||||
* A specific deployment can be requested via:
|
||||
* - the `dpl` search parameter for assets
|
||||
* - the `x-deployment-id` for other requests
|
||||
*
|
||||
* When a specific deployment is requested, we route to that deployment via the preview URLs.
|
||||
* See https://developers.cloudflare.com/workers/configuration/previews/
|
||||
*
|
||||
* When the requested deployment is not supported a 400 response is returned.
|
||||
*
|
||||
* Notes:
|
||||
* - The re-routing is only active for the deployed version of the app (on a custom domain)
|
||||
* - Assets are also handled when `run_worker_first` is enabled.
|
||||
* See https://developers.cloudflare.com/workers/static-assets/binding/#run_worker_first
|
||||
*
|
||||
* @param request
|
||||
* @returns
|
||||
*/
|
||||
export function maybeGetSkewProtectionResponse(request) {
|
||||
// no early return as esbuild would not treeshake the code.
|
||||
if (__SKEW_PROTECTION_ENABLED__) {
|
||||
const url = new URL(request.url);
|
||||
// Skew protection is only active for the latest version of the app served on a custom domain.
|
||||
if (url.hostname === "localhost" || url.hostname.endsWith(".workers.dev")) {
|
||||
return undefined;
|
||||
}
|
||||
const requestDeploymentId = request.headers.get("x-deployment-id") ?? url.searchParams.get("dpl");
|
||||
if (!requestDeploymentId || requestDeploymentId === process.env.DEPLOYMENT_ID) {
|
||||
// The request does not specify a deployment id or it is the current deployment id
|
||||
return undefined;
|
||||
}
|
||||
deploymentMapping ??= process.env[DEPLOYMENT_MAPPING_ENV_NAME]
|
||||
? JSON.parse(process.env[DEPLOYMENT_MAPPING_ENV_NAME])
|
||||
: {};
|
||||
if (!(requestDeploymentId in deploymentMapping)) {
|
||||
// Unknown deployment id, serve the current version
|
||||
return undefined;
|
||||
}
|
||||
const version = deploymentMapping[requestDeploymentId];
|
||||
if (!version || version === CURRENT_VERSION_ID) {
|
||||
return undefined;
|
||||
}
|
||||
const versionDomain = version.split("-")[0];
|
||||
const hostname = `${versionDomain}-${process.env.CF_WORKER_NAME}.${process.env.CF_PREVIEW_DOMAIN}.workers.dev`;
|
||||
url.hostname = hostname;
|
||||
const requestToOlderDeployment = new Request(url, request);
|
||||
// Remove the origin header to prevent an error with POST requests
|
||||
const headers = new Headers(request.headers);
|
||||
headers.delete("origin");
|
||||
return fetch(requestToOlderDeployment, { headers });
|
||||
}
|
||||
}
|
||||
7
.open-next 2/cloudflare-templates/worker.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
export { DOQueueHandler } from "./.build/durable-objects/queue.js";
|
||||
export { DOShardedTagCache } from "./.build/durable-objects/sharded-tag-cache.js";
|
||||
export { BucketCachePurge } from "./.build/durable-objects/bucket-cache-purge.js";
|
||||
declare const _default: {
|
||||
fetch(request: Request<unknown, IncomingRequestCfProperties<unknown>>, env: CloudflareEnv, ctx: ExecutionContext<unknown>): Promise<any>;
|
||||
};
|
||||
export default _default;
|
||||
50
.open-next 2/cloudflare-templates/worker.js
Normal file
@ -0,0 +1,50 @@
|
||||
//@ts-expect-error: Will be resolved by wrangler build
|
||||
import { handleImageRequest } from "./cloudflare/images.js";
|
||||
//@ts-expect-error: Will be resolved by wrangler build
|
||||
import { runWithCloudflareRequestContext } from "./cloudflare/init.js";
|
||||
//@ts-expect-error: Will be resolved by wrangler build
|
||||
import { maybeGetSkewProtectionResponse } from "./cloudflare/skew-protection.js";
|
||||
// @ts-expect-error: Will be resolved by wrangler build
|
||||
import { handler as middlewareHandler } from "./middleware/handler.mjs";
|
||||
//@ts-expect-error: Will be resolved by wrangler build
|
||||
export { DOQueueHandler } from "./.build/durable-objects/queue.js";
|
||||
//@ts-expect-error: Will be resolved by wrangler build
|
||||
export { DOShardedTagCache } from "./.build/durable-objects/sharded-tag-cache.js";
|
||||
//@ts-expect-error: Will be resolved by wrangler build
|
||||
export { BucketCachePurge } from "./.build/durable-objects/bucket-cache-purge.js";
|
||||
export default {
|
||||
async fetch(request, env, ctx) {
|
||||
return runWithCloudflareRequestContext(request, env, ctx, async () => {
|
||||
const response = maybeGetSkewProtectionResponse(request);
|
||||
if (response) {
|
||||
return response;
|
||||
}
|
||||
const url = new URL(request.url);
|
||||
// Serve images in development.
|
||||
// Note: "/cdn-cgi/image/..." requests do not reach production workers.
|
||||
if (url.pathname.startsWith("/cdn-cgi/image/")) {
|
||||
const m = url.pathname.match(/\/cdn-cgi\/image\/.+?\/(?<url>.+)$/);
|
||||
if (m === null) {
|
||||
return new Response("Not Found!", { status: 404 });
|
||||
}
|
||||
const imageUrl = m.groups.url;
|
||||
return imageUrl.match(/^https?:\/\//)
|
||||
? fetch(imageUrl, { cf: { cacheEverything: true } })
|
||||
: env.ASSETS?.fetch(new URL(`/${imageUrl}`, url));
|
||||
}
|
||||
// Fallback for the Next default image loader.
|
||||
if (url.pathname ===
|
||||
`${globalThis.__NEXT_BASE_PATH__}/_next/image${globalThis.__TRAILING_SLASH__ ? "/" : ""}`) {
|
||||
return await handleImageRequest(url, request.headers, env);
|
||||
}
|
||||
// - `Request`s are handled by the Next server
|
||||
const reqOrResp = await middlewareHandler(request, env, ctx);
|
||||
if (reqOrResp instanceof Response) {
|
||||
return reqOrResp;
|
||||
}
|
||||
// @ts-expect-error: resolved by wrangler build
|
||||
const { handler } = await import("./server-functions/default/handler.mjs");
|
||||
return handler(reqOrResp, env, ctx, request.signal);
|
||||
});
|
||||
},
|
||||
};
|
||||
3
.open-next 2/cloudflare/cache-assets-manifest.sql
Normal file
@ -0,0 +1,3 @@
|
||||
CREATE TABLE IF NOT EXISTS tags (tag TEXT NOT NULL, path TEXT NOT NULL, UNIQUE(tag, path) ON CONFLICT REPLACE);
|
||||
CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE);
|
||||
INSERT INTO tags (tag, path) VALUES ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/layout", "Bi3XXPy0fxaJxYXDBsshm/_global-error"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/_global-error/layout", "Bi3XXPy0fxaJxYXDBsshm/_global-error"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/_global-error/page", "Bi3XXPy0fxaJxYXDBsshm/_global-error"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/_global-error", "Bi3XXPy0fxaJxYXDBsshm/_global-error"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/layout", "Bi3XXPy0fxaJxYXDBsshm/_not-found"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/_not-found/layout", "Bi3XXPy0fxaJxYXDBsshm/_not-found"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/_not-found/page", "Bi3XXPy0fxaJxYXDBsshm/_not-found"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/_not-found", "Bi3XXPy0fxaJxYXDBsshm/_not-found"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/layout", "Bi3XXPy0fxaJxYXDBsshm/login"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/login/layout", "Bi3XXPy0fxaJxYXDBsshm/login"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/login/page", "Bi3XXPy0fxaJxYXDBsshm/login"), ("Bi3XXPy0fxaJxYXDBsshm/_N_T_/login", "Bi3XXPy0fxaJxYXDBsshm/login");
|
||||
585
.open-next 2/cloudflare/images.js
Normal file
@ -0,0 +1,585 @@
|
||||
// <define:__IMAGES_DEVICE_SIZES__>
|
||||
var define_IMAGES_DEVICE_SIZES_default = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
|
||||
|
||||
// <define:__IMAGES_FORMATS__>
|
||||
var define_IMAGES_FORMATS_default = ["image/webp"];
|
||||
|
||||
// <define:__IMAGES_IMAGE_SIZES__>
|
||||
var define_IMAGES_IMAGE_SIZES_default = [32, 48, 64, 96, 128, 256, 384];
|
||||
|
||||
// <define:__IMAGES_LOCAL_PATTERNS__>
|
||||
var define_IMAGES_LOCAL_PATTERNS_default = [{ pathname: "^(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$))(?:(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$)).)*?)\\/?)$", search: "" }];
|
||||
|
||||
// <define:__IMAGES_QUALITIES__>
|
||||
var define_IMAGES_QUALITIES_default = [75];
|
||||
|
||||
// <define:__IMAGES_REMOTE_PATTERNS__>
|
||||
var define_IMAGES_REMOTE_PATTERNS_default = [{ protocol: "https", hostname: "^(?:^(?:m\\.media\\-amazon\\.com)$)$", pathname: "^(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$))(?:(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$)).)*?)\\/?)$" }];
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/utils/error.js
|
||||
function isOpenNextError(e) {
|
||||
try {
|
||||
return "__openNextInternal" in e;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/aws/dist/adapters/logger.js
|
||||
function debug(...args) {
|
||||
if (globalThis.openNextDebug) {
|
||||
console.log(...args);
|
||||
}
|
||||
}
|
||||
function warn(...args) {
|
||||
console.warn(...args);
|
||||
}
|
||||
var DOWNPLAYED_ERROR_LOGS = [
|
||||
{
|
||||
clientName: "S3Client",
|
||||
commandName: "GetObjectCommand",
|
||||
errorName: "NoSuchKey"
|
||||
}
|
||||
];
|
||||
var isDownplayedErrorLog = (errorLog) => DOWNPLAYED_ERROR_LOGS.some((downplayedInput) => downplayedInput.clientName === errorLog?.clientName && downplayedInput.commandName === errorLog?.commandName && (downplayedInput.errorName === errorLog?.error?.name || downplayedInput.errorName === errorLog?.error?.Code));
|
||||
function error(...args) {
|
||||
if (args.some((arg) => isDownplayedErrorLog(arg))) {
|
||||
return debug(...args);
|
||||
}
|
||||
if (args.some((arg) => isOpenNextError(arg))) {
|
||||
const error2 = args.find((arg) => isOpenNextError(arg));
|
||||
if (error2.logLevel < getOpenNextErrorLogLevel()) {
|
||||
return;
|
||||
}
|
||||
if (error2.logLevel === 0) {
|
||||
return console.log(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
||||
}
|
||||
if (error2.logLevel === 1) {
|
||||
return warn(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
||||
}
|
||||
return console.error(...args);
|
||||
}
|
||||
console.error(...args);
|
||||
}
|
||||
function getOpenNextErrorLogLevel() {
|
||||
const strLevel = process.env.OPEN_NEXT_ERROR_LOG_LEVEL ?? "1";
|
||||
switch (strLevel.toLowerCase()) {
|
||||
case "debug":
|
||||
case "0":
|
||||
return 0;
|
||||
case "error":
|
||||
case "2":
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/@opennextjs/cloudflare/dist/cli/templates/images.js
|
||||
async function handleImageRequest(requestURL, requestHeaders, env) {
|
||||
const parseResult = parseImageRequest(requestURL, requestHeaders);
|
||||
if (!parseResult.ok) {
|
||||
return new Response(parseResult.message, {
|
||||
status: 400
|
||||
});
|
||||
}
|
||||
let imageResponse;
|
||||
if (parseResult.url.startsWith("/")) {
|
||||
if (env.ASSETS === void 0) {
|
||||
error("env.ASSETS binding is not defined");
|
||||
return new Response('"url" parameter is valid but upstream response is invalid', {
|
||||
status: 404
|
||||
});
|
||||
}
|
||||
const absoluteURL = new URL(parseResult.url, requestURL);
|
||||
imageResponse = await env.ASSETS.fetch(absoluteURL);
|
||||
} else {
|
||||
let fetchImageResult;
|
||||
try {
|
||||
fetchImageResult = await fetchWithRedirects(parseResult.url, 7e3, 3);
|
||||
} catch (e) {
|
||||
throw new Error("Failed to fetch image", { cause: e });
|
||||
}
|
||||
if (!fetchImageResult.ok) {
|
||||
if (fetchImageResult.error === "timed_out") {
|
||||
return new Response('"url" parameter is valid but upstream response timed out', {
|
||||
status: 504
|
||||
});
|
||||
}
|
||||
if (fetchImageResult.error === "too_many_redirects") {
|
||||
return new Response('"url" parameter is valid but upstream response is invalid', {
|
||||
status: 508
|
||||
});
|
||||
}
|
||||
throw new Error("Failed to fetch image");
|
||||
}
|
||||
imageResponse = fetchImageResult.response;
|
||||
}
|
||||
if (!imageResponse.ok || imageResponse.body === null) {
|
||||
return new Response('"url" parameter is valid but upstream response is invalid', {
|
||||
status: imageResponse.status
|
||||
});
|
||||
}
|
||||
let immutable = false;
|
||||
if (parseResult.static) {
|
||||
immutable = true;
|
||||
} else {
|
||||
const cacheControlHeader = imageResponse.headers.get("Cache-Control");
|
||||
if (cacheControlHeader !== null) {
|
||||
immutable = cacheControlHeader.includes("immutable");
|
||||
}
|
||||
}
|
||||
const [contentTypeImageStream, imageStream] = imageResponse.body.tee();
|
||||
const imageHeaderBytes = new Uint8Array(32);
|
||||
const contentTypeImageReader = contentTypeImageStream.getReader({
|
||||
mode: "byob"
|
||||
});
|
||||
const readImageHeaderBytesResult = await contentTypeImageReader.readAtLeast(32, imageHeaderBytes);
|
||||
if (readImageHeaderBytesResult.value === void 0) {
|
||||
await imageResponse.body.cancel();
|
||||
return new Response('"url" parameter is valid but upstream response is invalid', {
|
||||
status: 400
|
||||
});
|
||||
}
|
||||
const contentType = detectImageContentType(readImageHeaderBytesResult.value);
|
||||
if (contentType === null) {
|
||||
warn(`Failed to detect content type of "${parseResult.url}"`);
|
||||
return new Response('"url" parameter is valid but image type is not allowed', {
|
||||
status: 400
|
||||
});
|
||||
}
|
||||
if (contentType === SVG) {
|
||||
if (true) {
|
||||
return new Response('"url" parameter is valid but image type is not allowed', {
|
||||
status: 400
|
||||
});
|
||||
}
|
||||
const response2 = createImageResponse(imageStream, contentType, {
|
||||
immutable
|
||||
});
|
||||
return response2;
|
||||
}
|
||||
if (contentType === GIF) {
|
||||
if (env.IMAGES === void 0) {
|
||||
warn("env.IMAGES binding is not defined");
|
||||
const response3 = createImageResponse(imageStream, contentType, {
|
||||
immutable
|
||||
});
|
||||
return response3;
|
||||
}
|
||||
const imageSource = env.IMAGES.input(imageStream);
|
||||
const imageTransformationResult = await imageSource.transform({
|
||||
width: parseResult.width,
|
||||
fit: "scale-down"
|
||||
}).output({
|
||||
quality: parseResult.quality,
|
||||
format: GIF
|
||||
});
|
||||
const outputImageStream = imageTransformationResult.image();
|
||||
const response2 = createImageResponse(outputImageStream, GIF, {
|
||||
immutable
|
||||
});
|
||||
return response2;
|
||||
}
|
||||
if (contentType === AVIF || contentType === WEBP || contentType === JPEG || contentType === PNG) {
|
||||
if (env.IMAGES === void 0) {
|
||||
warn("env.IMAGES binding is not defined");
|
||||
const response3 = createImageResponse(imageStream, contentType, {
|
||||
immutable
|
||||
});
|
||||
return response3;
|
||||
}
|
||||
const outputFormat = parseResult.format ?? contentType;
|
||||
const imageSource = env.IMAGES.input(imageStream);
|
||||
const imageTransformationResult = await imageSource.transform({
|
||||
width: parseResult.width,
|
||||
fit: "scale-down"
|
||||
}).output({
|
||||
quality: parseResult.quality,
|
||||
format: outputFormat
|
||||
});
|
||||
const outputImageStream = imageTransformationResult.image();
|
||||
const response2 = createImageResponse(outputImageStream, outputFormat, {
|
||||
immutable
|
||||
});
|
||||
return response2;
|
||||
}
|
||||
warn(`Image content type ${contentType} not supported`);
|
||||
const response = createImageResponse(imageStream, contentType, {
|
||||
immutable
|
||||
});
|
||||
return response;
|
||||
}
|
||||
async function fetchWithRedirects(url, timeoutMS, maxRedirectCount) {
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(url, {
|
||||
signal: AbortSignal.timeout(timeoutMS),
|
||||
redirect: "manual"
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error && e.name === "TimeoutError") {
|
||||
const result2 = {
|
||||
ok: false,
|
||||
error: "timed_out"
|
||||
};
|
||||
return result2;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
if (redirectResponseStatuses.includes(response.status)) {
|
||||
const locationHeader = response.headers.get("Location");
|
||||
if (locationHeader !== null) {
|
||||
if (maxRedirectCount < 1) {
|
||||
const result3 = {
|
||||
ok: false,
|
||||
error: "too_many_redirects"
|
||||
};
|
||||
return result3;
|
||||
}
|
||||
let redirectTarget;
|
||||
if (locationHeader.startsWith("/")) {
|
||||
redirectTarget = new URL(locationHeader, url).href;
|
||||
} else {
|
||||
redirectTarget = locationHeader;
|
||||
}
|
||||
const result2 = await fetchWithRedirects(redirectTarget, timeoutMS, maxRedirectCount - 1);
|
||||
return result2;
|
||||
}
|
||||
}
|
||||
const result = {
|
||||
ok: true,
|
||||
response
|
||||
};
|
||||
return result;
|
||||
}
|
||||
var redirectResponseStatuses = [301, 302, 303, 307, 308];
|
||||
function createImageResponse(image, contentType, imageResponseFlags) {
|
||||
const response = new Response(image, {
|
||||
headers: {
|
||||
Vary: "Accept",
|
||||
"Content-Type": contentType,
|
||||
"Content-Disposition": "attachment",
|
||||
"Content-Security-Policy": "script-src 'none'; frame-src 'none'; sandbox;"
|
||||
}
|
||||
});
|
||||
if (imageResponseFlags.immutable) {
|
||||
response.headers.set("Cache-Control", "public, max-age=315360000, immutable");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
function parseImageRequest(requestURL, requestHeaders) {
|
||||
const formats = define_IMAGES_FORMATS_default;
|
||||
const parsedUrlOrError = validateUrlQueryParameter(requestURL);
|
||||
if (!("url" in parsedUrlOrError)) {
|
||||
return parsedUrlOrError;
|
||||
}
|
||||
const widthOrError = validateWidthQueryParameter(requestURL);
|
||||
if (typeof widthOrError !== "number") {
|
||||
return widthOrError;
|
||||
}
|
||||
const qualityOrError = validateQualityQueryParameter(requestURL);
|
||||
if (typeof qualityOrError !== "number") {
|
||||
return qualityOrError;
|
||||
}
|
||||
const acceptHeader = requestHeaders.get("Accept") ?? "";
|
||||
let format = null;
|
||||
for (const allowedFormat of formats) {
|
||||
if (acceptHeader.includes(allowedFormat)) {
|
||||
format = allowedFormat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const result = {
|
||||
ok: true,
|
||||
url: parsedUrlOrError.url,
|
||||
width: widthOrError,
|
||||
quality: qualityOrError,
|
||||
format,
|
||||
static: parsedUrlOrError.static
|
||||
};
|
||||
return result;
|
||||
}
|
||||
function validateUrlQueryParameter(requestURL) {
|
||||
const urls = requestURL.searchParams.getAll("url");
|
||||
if (urls.length < 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter is required'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (urls.length > 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter cannot be an array'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const url = urls[0];
|
||||
if (url.length > 3072) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter is too long'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (url.startsWith("//")) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter cannot be a protocol-relative URL (//)'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (url.startsWith("/")) {
|
||||
const staticAsset = url.startsWith(`${__NEXT_BASE_PATH__ || ""}/_next/static/media`);
|
||||
const pathname = getPathnameFromRelativeURL(url);
|
||||
if (/\/_next\/image($|\/)/.test(decodeURIComponent(pathname))) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter cannot be recursive'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (!staticAsset) {
|
||||
if (!hasLocalMatch(define_IMAGES_LOCAL_PATTERNS_default, url)) {
|
||||
const result = { ok: false, message: '"url" parameter is not allowed' };
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return { url, static: staticAsset };
|
||||
}
|
||||
let parsedURL;
|
||||
try {
|
||||
parsedURL = new URL(url);
|
||||
} catch {
|
||||
const result = { ok: false, message: '"url" parameter is invalid' };
|
||||
return result;
|
||||
}
|
||||
const validProtocols = ["http:", "https:"];
|
||||
if (!validProtocols.includes(parsedURL.protocol)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter is invalid'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (!hasRemoteMatch(define_IMAGES_REMOTE_PATTERNS_default, parsedURL)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"url" parameter is not allowed'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
return { url: parsedURL.href, static: false };
|
||||
}
|
||||
function validateWidthQueryParameter(requestURL) {
|
||||
const widthQueryValues = requestURL.searchParams.getAll("w");
|
||||
if (widthQueryValues.length < 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"w" parameter (width) is required'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (widthQueryValues.length > 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"w" parameter (width) cannot be an array'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const widthQueryValue = widthQueryValues[0];
|
||||
if (!/^[0-9]+$/.test(widthQueryValue)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"w" parameter (width) must be an integer greater than 0'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const width = parseInt(widthQueryValue, 10);
|
||||
if (width <= 0 || isNaN(width)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"w" parameter (width) must be an integer greater than 0'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const sizeValid = define_IMAGES_DEVICE_SIZES_default.includes(width) || define_IMAGES_IMAGE_SIZES_default.includes(width);
|
||||
if (!sizeValid) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: `"w" parameter (width) of ${width} is not allowed`
|
||||
};
|
||||
return result;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
function validateQualityQueryParameter(requestURL) {
|
||||
const qualityQueryValues = requestURL.searchParams.getAll("q");
|
||||
if (qualityQueryValues.length < 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"q" parameter (quality) is required'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (qualityQueryValues.length > 1) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"q" parameter (quality) cannot be an array'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const qualityQueryValue = qualityQueryValues[0];
|
||||
if (!/^[0-9]+$/.test(qualityQueryValue)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"q" parameter (quality) must be an integer between 1 and 100'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
const quality = parseInt(qualityQueryValue, 10);
|
||||
if (isNaN(quality) || quality < 1 || quality > 100) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: '"q" parameter (quality) must be an integer between 1 and 100'
|
||||
};
|
||||
return result;
|
||||
}
|
||||
if (!define_IMAGES_QUALITIES_default.includes(quality)) {
|
||||
const result = {
|
||||
ok: false,
|
||||
message: `"q" parameter (quality) of ${quality} is not allowed`
|
||||
};
|
||||
return result;
|
||||
}
|
||||
return quality;
|
||||
}
|
||||
function getPathnameFromRelativeURL(relativeURL) {
|
||||
return relativeURL.split("?")[0];
|
||||
}
|
||||
function hasLocalMatch(localPatterns, relativeURL) {
|
||||
const parseRelativeURLResult = parseRelativeURL(relativeURL);
|
||||
for (const localPattern of localPatterns) {
|
||||
const matched = matchLocalPattern(localPattern, parseRelativeURLResult);
|
||||
if (matched) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function parseRelativeURL(relativeURL) {
|
||||
if (!relativeURL.includes("?")) {
|
||||
const result2 = {
|
||||
pathname: relativeURL,
|
||||
search: ""
|
||||
};
|
||||
return result2;
|
||||
}
|
||||
const parts = relativeURL.split("?");
|
||||
const pathname = parts[0];
|
||||
const search = "?" + parts.slice(1).join("?");
|
||||
const result = {
|
||||
pathname,
|
||||
search
|
||||
};
|
||||
return result;
|
||||
}
|
||||
function matchLocalPattern(pattern, url) {
|
||||
if (pattern.search !== void 0 && pattern.search !== url.search) {
|
||||
return false;
|
||||
}
|
||||
return new RegExp(pattern.pathname).test(url.pathname);
|
||||
}
|
||||
function hasRemoteMatch(remotePatterns, url) {
|
||||
for (const remotePattern of remotePatterns) {
|
||||
const matched = matchRemotePattern(remotePattern, url);
|
||||
if (matched) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function matchRemotePattern(pattern, url) {
|
||||
if (pattern.protocol !== void 0 && pattern.protocol.replace(/:$/, "") !== url.protocol.replace(/:$/, "")) {
|
||||
return false;
|
||||
}
|
||||
if (pattern.port !== void 0 && pattern.port !== url.port) {
|
||||
return false;
|
||||
}
|
||||
if (pattern.hostname === void 0 || !new RegExp(pattern.hostname).test(url.hostname)) {
|
||||
return false;
|
||||
}
|
||||
if (pattern.search !== void 0 && pattern.search !== url.search) {
|
||||
return false;
|
||||
}
|
||||
return new RegExp(pattern.pathname).test(url.pathname);
|
||||
}
|
||||
var AVIF = "image/avif";
|
||||
var WEBP = "image/webp";
|
||||
var PNG = "image/png";
|
||||
var JPEG = "image/jpeg";
|
||||
var JXL = "image/jxl";
|
||||
var JP2 = "image/jp2";
|
||||
var HEIC = "image/heic";
|
||||
var GIF = "image/gif";
|
||||
var SVG = "image/svg+xml";
|
||||
var ICO = "image/x-icon";
|
||||
var ICNS = "image/x-icns";
|
||||
var TIFF = "image/tiff";
|
||||
var BMP = "image/bmp";
|
||||
function detectImageContentType(buffer) {
|
||||
if ([255, 216, 255].every((b, i) => buffer[i] === b)) {
|
||||
return JPEG;
|
||||
}
|
||||
if ([137, 80, 78, 71, 13, 10, 26, 10].every((b, i) => buffer[i] === b)) {
|
||||
return PNG;
|
||||
}
|
||||
if ([71, 73, 70, 56].every((b, i) => buffer[i] === b)) {
|
||||
return GIF;
|
||||
}
|
||||
if ([82, 73, 70, 70, 0, 0, 0, 0, 87, 69, 66, 80].every((b, i) => !b || buffer[i] === b)) {
|
||||
return WEBP;
|
||||
}
|
||||
if ([60, 63, 120, 109, 108].every((b, i) => buffer[i] === b)) {
|
||||
return SVG;
|
||||
}
|
||||
if ([60, 115, 118, 103].every((b, i) => buffer[i] === b)) {
|
||||
return SVG;
|
||||
}
|
||||
if ([0, 0, 0, 0, 102, 116, 121, 112, 97, 118, 105, 102].every((b, i) => !b || buffer[i] === b)) {
|
||||
return AVIF;
|
||||
}
|
||||
if ([0, 0, 1, 0].every((b, i) => buffer[i] === b)) {
|
||||
return ICO;
|
||||
}
|
||||
if ([105, 99, 110, 115].every((b, i) => buffer[i] === b)) {
|
||||
return ICNS;
|
||||
}
|
||||
if ([73, 73, 42, 0].every((b, i) => buffer[i] === b)) {
|
||||
return TIFF;
|
||||
}
|
||||
if ([66, 77].every((b, i) => buffer[i] === b)) {
|
||||
return BMP;
|
||||
}
|
||||
if ([255, 10].every((b, i) => buffer[i] === b)) {
|
||||
return JXL;
|
||||
}
|
||||
if ([0, 0, 0, 12, 74, 88, 76, 32, 13, 10, 135, 10].every((b, i) => buffer[i] === b)) {
|
||||
return JXL;
|
||||
}
|
||||
if ([0, 0, 0, 0, 102, 116, 121, 112, 104, 101, 105, 99].every((b, i) => !b || buffer[i] === b)) {
|
||||
return HEIC;
|
||||
}
|
||||
if ([0, 0, 0, 12, 106, 80, 32, 32, 13, 10, 135, 10].every((b, i) => buffer[i] === b)) {
|
||||
return JP2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export {
|
||||
detectImageContentType,
|
||||
handleImageRequest,
|
||||
matchLocalPattern,
|
||||
matchRemotePattern
|
||||
};
|
||||
88
.open-next 2/cloudflare/init.js
Normal file
@ -0,0 +1,88 @@
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
import process from "node:process";
|
||||
import stream from "node:stream";
|
||||
import * as nextEnvVars from "./next-env.mjs";
|
||||
const cloudflareContextALS = new AsyncLocalStorage();
|
||||
Object.defineProperty(globalThis, Symbol.for("__cloudflare-context__"), {
|
||||
get() {
|
||||
return cloudflareContextALS.getStore();
|
||||
}
|
||||
});
|
||||
async function runWithCloudflareRequestContext(request, env, ctx, handler) {
|
||||
init(request, env);
|
||||
return cloudflareContextALS.run({ env, ctx, cf: request.cf }, handler);
|
||||
}
|
||||
let initialized = false;
|
||||
function init(request, env) {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
const url = new URL(request.url);
|
||||
initRuntime();
|
||||
populateProcessEnv(url, env);
|
||||
}
|
||||
function initRuntime() {
|
||||
Object.assign(process, { version: process.version || "v22.14.0" });
|
||||
Object.assign(process.versions, { node: "22.14.0", ...process.versions });
|
||||
globalThis.__dirname ??= "";
|
||||
globalThis.__filename ??= "";
|
||||
import.meta.url ??= "file:///worker.js";
|
||||
const __original_fetch = globalThis.fetch;
|
||||
globalThis.fetch = (input, init2) => {
|
||||
if (init2) {
|
||||
delete init2.cache;
|
||||
}
|
||||
return __original_fetch(input, init2);
|
||||
};
|
||||
const CustomRequest = class extends globalThis.Request {
|
||||
constructor(input, init2) {
|
||||
if (init2) {
|
||||
delete init2.cache;
|
||||
Object.defineProperty(init2, "body", {
|
||||
// @ts-ignore
|
||||
value: init2.body instanceof stream.Readable ? ReadableStream.from(init2.body) : init2.body
|
||||
});
|
||||
}
|
||||
super(input, init2);
|
||||
}
|
||||
};
|
||||
Object.assign(globalThis, {
|
||||
Request: CustomRequest,
|
||||
__BUILD_TIMESTAMP_MS__: 1769585780929,
|
||||
__NEXT_BASE_PATH__: "",
|
||||
__ASSETS_RUN_WORKER_FIRST__: false,
|
||||
__TRAILING_SLASH__: false,
|
||||
// The external middleware will use the convertTo function of the `edge` converter
|
||||
// by default it will try to fetch the request, but since we are running everything in the same worker
|
||||
// we need to use the request as is.
|
||||
__dangerous_ON_edge_converter_returns_request: true
|
||||
});
|
||||
}
|
||||
function populateProcessEnv(url, env) {
|
||||
for (const [key, value] of Object.entries(env)) {
|
||||
if (typeof value === "string") {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
const mode = env.NEXTJS_ENV ?? "production";
|
||||
if (nextEnvVars[mode]) {
|
||||
for (const key in nextEnvVars[mode]) {
|
||||
process.env[key] ??= nextEnvVars[mode][key];
|
||||
}
|
||||
}
|
||||
process.env.OPEN_NEXT_ORIGIN = JSON.stringify({
|
||||
default: {
|
||||
host: url.hostname,
|
||||
protocol: url.protocol.slice(0, -1),
|
||||
port: url.port
|
||||
}
|
||||
});
|
||||
process.env.__NEXT_PRIVATE_ORIGIN = url.origin;
|
||||
if ("") {
|
||||
process.env.DEPLOYMENT_ID = "";
|
||||
}
|
||||
}
|
||||
export {
|
||||
runWithCloudflareRequestContext
|
||||
};
|
||||
3
.open-next 2/cloudflare/next-env.mjs
Normal file
@ -0,0 +1,3 @@
|
||||
export const production = {"DATABASE_URL":"file:./prisma/dev.db","WORKOS_CLIENT_ID":"client_01KFPE94C2VGN7KHB59DD4RR52","WORKOS_API_KEY":"sk_test_a2V5XzAxS0ZWU1AyWTFDNkNDS1BSV1lKMERaNkNXLDBmUU5TN0RKYzJXNlFUeUR6Qk96cTY2ZVg","WORKOS_REDIRECT_URI":"http://localhost:3000/api/auth/callback","NEXT_PUBLIC_VAPID_PUBLIC_KEY":"BG7JgPf8BGBj-msDaGWl3osAa8OSbNjUm1ktC_0oNuyqNPzd6XJ91VT40RaPzyC5n91HkGifLLYxSG-Uj5DBh94","VAPID_PRIVATE_KEY":"f6Vd3ECXGOB3FTuNl1y2q77NzjK-Xq5Z0pekcD8qTVY","VAPID_SUBJECT":"mailto:admin@quittraq.com"};
|
||||
export const development = {"DATABASE_URL":"file:./prisma/dev.db","WORKOS_CLIENT_ID":"client_01KFPE94C2VGN7KHB59DD4RR52","WORKOS_API_KEY":"sk_test_a2V5XzAxS0ZWU1AyWTFDNkNDS1BSV1lKMERaNkNXLDBmUU5TN0RKYzJXNlFUeUR6Qk96cTY2ZVg","WORKOS_REDIRECT_URI":"http://localhost:3000/api/auth/callback","NEXT_PUBLIC_VAPID_PUBLIC_KEY":"BG7JgPf8BGBj-msDaGWl3osAa8OSbNjUm1ktC_0oNuyqNPzd6XJ91VT40RaPzyC5n91HkGifLLYxSG-Uj5DBh94","VAPID_PRIVATE_KEY":"f6Vd3ECXGOB3FTuNl1y2q77NzjK-Xq5Z0pekcD8qTVY","VAPID_SUBJECT":"mailto:admin@quittraq.com"};
|
||||
export const test = {"DATABASE_URL":"file:./dev.db"};
|
||||
36
.open-next 2/cloudflare/skew-protection.js
Normal file
@ -0,0 +1,36 @@
|
||||
import process from "node:process";
|
||||
const DEPLOYMENT_MAPPING_ENV_NAME = "CF_DEPLOYMENT_MAPPING";
|
||||
const CURRENT_VERSION_ID = "current";
|
||||
let deploymentMapping;
|
||||
function maybeGetSkewProtectionResponse(request) {
|
||||
if (false) {
|
||||
const url = new URL(request.url);
|
||||
if (url.hostname === "localhost" || url.hostname.endsWith(".workers.dev")) {
|
||||
return void 0;
|
||||
}
|
||||
const requestDeploymentId = request.headers.get("x-deployment-id") ?? url.searchParams.get("dpl");
|
||||
if (!requestDeploymentId || requestDeploymentId === process.env.DEPLOYMENT_ID) {
|
||||
return void 0;
|
||||
}
|
||||
deploymentMapping ??= process.env[DEPLOYMENT_MAPPING_ENV_NAME] ? JSON.parse(process.env[DEPLOYMENT_MAPPING_ENV_NAME]) : {};
|
||||
if (!(requestDeploymentId in deploymentMapping)) {
|
||||
return void 0;
|
||||
}
|
||||
const version = deploymentMapping[requestDeploymentId];
|
||||
if (!version || version === CURRENT_VERSION_ID) {
|
||||
return void 0;
|
||||
}
|
||||
const versionDomain = version.split("-")[0];
|
||||
const hostname = `${versionDomain}-${process.env.CF_WORKER_NAME}.${process.env.CF_PREVIEW_DOMAIN}.workers.dev`;
|
||||
url.hostname = hostname;
|
||||
const requestToOlderDeployment = new Request(url, request);
|
||||
const headers = new Headers(request.headers);
|
||||
headers.delete("origin");
|
||||
return fetch(requestToOlderDeployment, { headers });
|
||||
}
|
||||
}
|
||||
export {
|
||||
CURRENT_VERSION_ID,
|
||||
DEPLOYMENT_MAPPING_ENV_NAME,
|
||||
maybeGetSkewProtectionResponse
|
||||
};
|
||||
1
.open-next 2/dynamodb-provider/dynamodb-cache.json
Normal file
@ -0,0 +1 @@
|
||||
[{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/layout"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/_global-error"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/_global-error/layout"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/_global-error"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/_global-error/page"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/_global-error"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/_global-error"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/_global-error"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/layout"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/_not-found"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/_not-found/layout"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/_not-found"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/_not-found/page"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/_not-found"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/_not-found"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/_not-found"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/layout"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/login"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/login/layout"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/login"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/login/page"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/login"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"Bi3XXPy0fxaJxYXDBsshm/_N_T_/login"},"path":{"S":"Bi3XXPy0fxaJxYXDBsshm/login"},"revalidatedAt":{"N":"1"}}]
|
||||
31
.open-next 2/dynamodb-provider/open-next.config.mjs
Normal file
@ -0,0 +1,31 @@
|
||||
import { createRequire as topLevelCreateRequire } from 'module';const require = topLevelCreateRequire(import.meta.url);import bannerUrl from 'url';const __dirname = bannerUrl.fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
// open-next.config.ts
|
||||
var config = {
|
||||
default: {
|
||||
override: {
|
||||
wrapper: "cloudflare-node",
|
||||
converter: "edge",
|
||||
proxyExternalRequest: "fetch",
|
||||
incrementalCache: "dummy",
|
||||
tagCache: "dummy",
|
||||
queue: "dummy"
|
||||
}
|
||||
},
|
||||
edgeExternals: ["node:crypto"],
|
||||
middleware: {
|
||||
external: true,
|
||||
override: {
|
||||
wrapper: "cloudflare-edge",
|
||||
converter: "edge",
|
||||
proxyExternalRequest: "fetch",
|
||||
incrementalCache: "dummy",
|
||||
tagCache: "dummy",
|
||||
queue: "dummy"
|
||||
}
|
||||
}
|
||||
};
|
||||
var open_next_config_default = config;
|
||||
export {
|
||||
open_next_config_default as default
|
||||
};
|
||||
2660
.open-next 2/middleware/handler.mjs
Normal file
29
.open-next 2/middleware/open-next.config.mjs
Normal file
@ -0,0 +1,29 @@
|
||||
// open-next.config.ts
|
||||
var config = {
|
||||
default: {
|
||||
override: {
|
||||
wrapper: "cloudflare-node",
|
||||
converter: "edge",
|
||||
proxyExternalRequest: "fetch",
|
||||
incrementalCache: "dummy",
|
||||
tagCache: "dummy",
|
||||
queue: "dummy"
|
||||
}
|
||||
},
|
||||
edgeExternals: ["node:crypto"],
|
||||
middleware: {
|
||||
external: true,
|
||||
override: {
|
||||
wrapper: "cloudflare-edge",
|
||||
converter: "edge",
|
||||
proxyExternalRequest: "fetch",
|
||||
incrementalCache: "dummy",
|
||||
tagCache: "dummy",
|
||||
queue: "dummy"
|
||||
}
|
||||
}
|
||||
};
|
||||
var open_next_config_default = config;
|
||||
export {
|
||||
open_next_config_default as default
|
||||
};
|
||||
1
.open-next 2/server-functions/default/.next/BUILD_ID
Normal file
@ -0,0 +1 @@
|
||||
Bi3XXPy0fxaJxYXDBsshm
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"/_global-error/page": "/_global-error",
|
||||
"/_not-found/page": "/_not-found",
|
||||
"/api/achievements/route": "/api/achievements",
|
||||
"/api/auth/callback/route": "/api/auth/callback",
|
||||
"/api/auth/login/route": "/api/auth/login",
|
||||
"/api/auth/logout/route": "/api/auth/logout",
|
||||
"/api/cron/reminders/route": "/api/cron/reminders",
|
||||
"/api/mood/route": "/api/mood",
|
||||
"/api/notifications/subscribe/route": "/api/notifications/subscribe",
|
||||
"/api/notifications/test/route": "/api/notifications/test",
|
||||
"/api/preferences/route": "/api/preferences",
|
||||
"/api/reminders/route": "/api/reminders",
|
||||
"/api/savings/route": "/api/savings",
|
||||
"/api/usage/route": "/api/usage",
|
||||
"/callback/route": "/callback",
|
||||
"/login/page": "/login",
|
||||
"/page": "/",
|
||||
"/signout/page": "/signout",
|
||||
"/smoking-aids/page": "/smoking-aids",
|
||||
"/track/marijuana/page": "/track/marijuana",
|
||||
"/track/nicotine/page": "/track/nicotine"
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"pages": {
|
||||
"/_app": []
|
||||
},
|
||||
"devFiles": [],
|
||||
"polyfillFiles": [
|
||||
"static/chunks/a6dad97d9634a72d.js"
|
||||
],
|
||||
"lowPriorityFiles": [
|
||||
"static/Bi3XXPy0fxaJxYXDBsshm/_ssgManifest.js",
|
||||
"static/Bi3XXPy0fxaJxYXDBsshm/_buildManifest.js"
|
||||
],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/e4b22ef044a981d1.js",
|
||||
"static/chunks/2de67ac572655c64.js",
|
||||
"static/chunks/6584b0a4f26ac208.js",
|
||||
"static/chunks/773abe17875a49cc.js",
|
||||
"static/chunks/turbopack-e62c010088b67350.js"
|
||||
]
|
||||
}
|
||||
1
.open-next 2/server-functions/default/.next/package.json
Normal file
@ -0,0 +1 @@
|
||||
{"type": "commonjs"}
|
||||
@ -0,0 +1,85 @@
|
||||
{
|
||||
"version": 4,
|
||||
"routes": {
|
||||
"/_global-error": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/_global-error",
|
||||
"dataRoute": "/_global-error.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/_not-found": {
|
||||
"initialStatus": 404,
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/_not-found",
|
||||
"dataRoute": "/_not-found.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/login": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/login",
|
||||
"dataRoute": "/login.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
}
|
||||
},
|
||||
"dynamicRoutes": {},
|
||||
"notFoundRoutes": [],
|
||||
"preview": {
|
||||
"previewModeId": "9212b8c54d8f2aaa5cb15dca46a16684",
|
||||
"previewModeSigningKey": "970022af34c137d34636787754aa5b8e46159f8524197b5b3d66d7ace9ce3c6a",
|
||||
"previewModeEncryptionKey": "d6060e1793fa715d98400804ca07bb25f76906348149090433c9ce4ce78f050a"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,325 @@
|
||||
{
|
||||
"version": 1,
|
||||
"config": {
|
||||
"env": {},
|
||||
"webpack": null,
|
||||
"typescript": {
|
||||
"ignoreBuildErrors": false
|
||||
},
|
||||
"typedRoutes": false,
|
||||
"distDir": ".next",
|
||||
"cleanDistDir": true,
|
||||
"assetPrefix": "",
|
||||
"cacheMaxMemorySize": 52428800,
|
||||
"configOrigin": "next.config.ts",
|
||||
"useFileSystemPublicRoutes": true,
|
||||
"generateEtags": true,
|
||||
"pageExtensions": [
|
||||
"tsx",
|
||||
"ts",
|
||||
"jsx",
|
||||
"js"
|
||||
],
|
||||
"poweredByHeader": true,
|
||||
"compress": true,
|
||||
"images": {
|
||||
"deviceSizes": [
|
||||
640,
|
||||
750,
|
||||
828,
|
||||
1080,
|
||||
1200,
|
||||
1920,
|
||||
2048,
|
||||
3840
|
||||
],
|
||||
"imageSizes": [
|
||||
32,
|
||||
48,
|
||||
64,
|
||||
96,
|
||||
128,
|
||||
256,
|
||||
384
|
||||
],
|
||||
"path": "/_next/image",
|
||||
"loader": "default",
|
||||
"loaderFile": "",
|
||||
"domains": [],
|
||||
"disableStaticImages": false,
|
||||
"minimumCacheTTL": 14400,
|
||||
"formats": [
|
||||
"image/webp"
|
||||
],
|
||||
"maximumRedirects": 3,
|
||||
"dangerouslyAllowLocalIP": false,
|
||||
"dangerouslyAllowSVG": false,
|
||||
"contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;",
|
||||
"contentDispositionType": "attachment",
|
||||
"localPatterns": [
|
||||
{
|
||||
"pathname": "**",
|
||||
"search": ""
|
||||
}
|
||||
],
|
||||
"remotePatterns": [
|
||||
{
|
||||
"protocol": "https",
|
||||
"hostname": "m.media-amazon.com"
|
||||
}
|
||||
],
|
||||
"qualities": [
|
||||
75
|
||||
],
|
||||
"unoptimized": false
|
||||
},
|
||||
"devIndicators": {
|
||||
"position": "bottom-left"
|
||||
},
|
||||
"onDemandEntries": {
|
||||
"maxInactiveAge": 60000,
|
||||
"pagesBufferLength": 5
|
||||
},
|
||||
"basePath": "",
|
||||
"sassOptions": {},
|
||||
"trailingSlash": false,
|
||||
"i18n": null,
|
||||
"productionBrowserSourceMaps": false,
|
||||
"excludeDefaultMomentLocales": true,
|
||||
"reactProductionProfiling": false,
|
||||
"reactStrictMode": null,
|
||||
"reactMaxHeadersLength": 6000,
|
||||
"httpAgentOptions": {
|
||||
"keepAlive": true
|
||||
},
|
||||
"logging": {},
|
||||
"compiler": {},
|
||||
"expireTime": 31536000,
|
||||
"staticPageGenerationTimeout": 60,
|
||||
"output": "standalone",
|
||||
"modularizeImports": {
|
||||
"@mui/icons-material": {
|
||||
"transform": "@mui/icons-material/{{member}}"
|
||||
},
|
||||
"lodash": {
|
||||
"transform": "lodash/{{member}}"
|
||||
}
|
||||
},
|
||||
"outputFileTracingRoot": "/Users/averyfelts/Documents/dev/quit_smoking_website",
|
||||
"cacheComponents": false,
|
||||
"cacheLife": {
|
||||
"default": {
|
||||
"stale": 300,
|
||||
"revalidate": 900,
|
||||
"expire": 4294967294
|
||||
},
|
||||
"seconds": {
|
||||
"stale": 30,
|
||||
"revalidate": 1,
|
||||
"expire": 60
|
||||
},
|
||||
"minutes": {
|
||||
"stale": 300,
|
||||
"revalidate": 60,
|
||||
"expire": 3600
|
||||
},
|
||||
"hours": {
|
||||
"stale": 300,
|
||||
"revalidate": 3600,
|
||||
"expire": 86400
|
||||
},
|
||||
"days": {
|
||||
"stale": 300,
|
||||
"revalidate": 86400,
|
||||
"expire": 604800
|
||||
},
|
||||
"weeks": {
|
||||
"stale": 300,
|
||||
"revalidate": 604800,
|
||||
"expire": 2592000
|
||||
},
|
||||
"max": {
|
||||
"stale": 300,
|
||||
"revalidate": 2592000,
|
||||
"expire": 31536000
|
||||
}
|
||||
},
|
||||
"cacheHandlers": {},
|
||||
"experimental": {
|
||||
"useSkewCookie": false,
|
||||
"cssChunking": true,
|
||||
"multiZoneDraftMode": false,
|
||||
"appNavFailHandling": false,
|
||||
"prerenderEarlyExit": true,
|
||||
"serverMinification": true,
|
||||
"linkNoTouchStart": false,
|
||||
"caseSensitiveRoutes": false,
|
||||
"dynamicOnHover": false,
|
||||
"preloadEntriesOnStart": true,
|
||||
"clientRouterFilter": true,
|
||||
"clientRouterFilterRedirects": false,
|
||||
"fetchCacheKeyPrefix": "",
|
||||
"proxyPrefetch": "flexible",
|
||||
"optimisticClientCache": true,
|
||||
"manualClientBasePath": false,
|
||||
"cpus": 9,
|
||||
"memoryBasedWorkersCount": false,
|
||||
"imgOptConcurrency": null,
|
||||
"imgOptTimeoutInSeconds": 7,
|
||||
"imgOptMaxInputPixels": 268402689,
|
||||
"imgOptSequentialRead": null,
|
||||
"imgOptSkipMetadata": null,
|
||||
"isrFlushToDisk": true,
|
||||
"workerThreads": false,
|
||||
"optimizeCss": false,
|
||||
"nextScriptWorkers": false,
|
||||
"scrollRestoration": false,
|
||||
"externalDir": false,
|
||||
"disableOptimizedLoading": false,
|
||||
"gzipSize": true,
|
||||
"craCompat": false,
|
||||
"esmExternals": true,
|
||||
"fullySpecified": false,
|
||||
"swcTraceProfiling": false,
|
||||
"forceSwcTransforms": false,
|
||||
"largePageDataBytes": 128000,
|
||||
"typedEnv": false,
|
||||
"parallelServerCompiles": false,
|
||||
"parallelServerBuildTraces": false,
|
||||
"ppr": false,
|
||||
"authInterrupts": false,
|
||||
"webpackMemoryOptimizations": false,
|
||||
"optimizeServerReact": true,
|
||||
"viewTransition": false,
|
||||
"removeUncaughtErrorAndRejectionListeners": false,
|
||||
"validateRSCRequestHeaders": false,
|
||||
"staleTimes": {
|
||||
"dynamic": 0,
|
||||
"static": 300
|
||||
},
|
||||
"reactDebugChannel": false,
|
||||
"serverComponentsHmrCache": true,
|
||||
"staticGenerationMaxConcurrency": 8,
|
||||
"staticGenerationMinPagesPerWorker": 25,
|
||||
"transitionIndicator": false,
|
||||
"inlineCss": false,
|
||||
"useCache": false,
|
||||
"globalNotFound": false,
|
||||
"browserDebugInfoInTerminal": false,
|
||||
"lockDistDir": true,
|
||||
"isolatedDevBuild": true,
|
||||
"proxyClientMaxBodySize": 10485760,
|
||||
"hideLogsAfterAbort": false,
|
||||
"mcpServer": true,
|
||||
"turbopackFileSystemCacheForDev": true,
|
||||
"turbopackFileSystemCacheForBuild": false,
|
||||
"turbopackInferModuleSideEffects": false,
|
||||
"optimizePackageImports": [
|
||||
"lucide-react",
|
||||
"date-fns",
|
||||
"lodash-es",
|
||||
"ramda",
|
||||
"antd",
|
||||
"react-bootstrap",
|
||||
"ahooks",
|
||||
"@ant-design/icons",
|
||||
"@headlessui/react",
|
||||
"@headlessui-float/react",
|
||||
"@heroicons/react/20/solid",
|
||||
"@heroicons/react/24/solid",
|
||||
"@heroicons/react/24/outline",
|
||||
"@visx/visx",
|
||||
"@tremor/react",
|
||||
"rxjs",
|
||||
"@mui/material",
|
||||
"@mui/icons-material",
|
||||
"recharts",
|
||||
"react-use",
|
||||
"effect",
|
||||
"@effect/schema",
|
||||
"@effect/platform",
|
||||
"@effect/platform-node",
|
||||
"@effect/platform-browser",
|
||||
"@effect/platform-bun",
|
||||
"@effect/sql",
|
||||
"@effect/sql-mssql",
|
||||
"@effect/sql-mysql2",
|
||||
"@effect/sql-pg",
|
||||
"@effect/sql-sqlite-node",
|
||||
"@effect/sql-sqlite-bun",
|
||||
"@effect/sql-sqlite-wasm",
|
||||
"@effect/sql-sqlite-react-native",
|
||||
"@effect/rpc",
|
||||
"@effect/rpc-http",
|
||||
"@effect/typeclass",
|
||||
"@effect/experimental",
|
||||
"@effect/opentelemetry",
|
||||
"@material-ui/core",
|
||||
"@material-ui/icons",
|
||||
"@tabler/icons-react",
|
||||
"mui-core",
|
||||
"react-icons/ai",
|
||||
"react-icons/bi",
|
||||
"react-icons/bs",
|
||||
"react-icons/cg",
|
||||
"react-icons/ci",
|
||||
"react-icons/di",
|
||||
"react-icons/fa",
|
||||
"react-icons/fa6",
|
||||
"react-icons/fc",
|
||||
"react-icons/fi",
|
||||
"react-icons/gi",
|
||||
"react-icons/go",
|
||||
"react-icons/gr",
|
||||
"react-icons/hi",
|
||||
"react-icons/hi2",
|
||||
"react-icons/im",
|
||||
"react-icons/io",
|
||||
"react-icons/io5",
|
||||
"react-icons/lia",
|
||||
"react-icons/lib",
|
||||
"react-icons/lu",
|
||||
"react-icons/md",
|
||||
"react-icons/pi",
|
||||
"react-icons/ri",
|
||||
"react-icons/rx",
|
||||
"react-icons/si",
|
||||
"react-icons/sl",
|
||||
"react-icons/tb",
|
||||
"react-icons/tfi",
|
||||
"react-icons/ti",
|
||||
"react-icons/vsc",
|
||||
"react-icons/wi"
|
||||
],
|
||||
"trustHostHeader": false,
|
||||
"isExperimentalCompile": false
|
||||
},
|
||||
"htmlLimitedBots": "[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight",
|
||||
"bundlePagesRouterDependencies": false,
|
||||
"configFileName": "next.config.ts",
|
||||
"turbopack": {
|
||||
"root": "/Users/averyfelts/Documents/dev/quit_smoking_website"
|
||||
},
|
||||
"distDirRoot": ".next"
|
||||
},
|
||||
"appDir": "/Users/averyfelts/Documents/dev/quit_smoking_website",
|
||||
"relativeAppDir": "",
|
||||
"files": [
|
||||
".next/routes-manifest.json",
|
||||
".next/server/pages-manifest.json",
|
||||
".next/build-manifest.json",
|
||||
".next/prerender-manifest.json",
|
||||
".next/server/functions-config-manifest.json",
|
||||
".next/server/middleware-manifest.json",
|
||||
".next/server/middleware-build-manifest.js",
|
||||
".next/server/app-paths-manifest.json",
|
||||
".next/app-path-routes-manifest.json",
|
||||
".next/server/server-reference-manifest.js",
|
||||
".next/server/server-reference-manifest.json",
|
||||
".next/BUILD_ID",
|
||||
".next/server/next-font-manifest.js",
|
||||
".next/server/next-font-manifest.json",
|
||||
".next/required-server-files.json"
|
||||
],
|
||||
"ignore": []
|
||||
}
|
||||
170
.open-next 2/server-functions/default/.next/routes-manifest.json
Normal file
@ -0,0 +1,170 @@
|
||||
{
|
||||
"version": 3,
|
||||
"pages404": true,
|
||||
"appType": "app",
|
||||
"caseSensitive": false,
|
||||
"basePath": "",
|
||||
"redirects": [
|
||||
{
|
||||
"source": "/:path+/",
|
||||
"destination": "/:path+",
|
||||
"internal": true,
|
||||
"priority": true,
|
||||
"statusCode": 308,
|
||||
"regex": "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$"
|
||||
}
|
||||
],
|
||||
"headers": [],
|
||||
"rewrites": {
|
||||
"beforeFiles": [],
|
||||
"afterFiles": [],
|
||||
"fallback": []
|
||||
},
|
||||
"dynamicRoutes": [],
|
||||
"staticRoutes": [
|
||||
{
|
||||
"page": "/",
|
||||
"regex": "^/(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/_global-error",
|
||||
"regex": "^/_global\\-error(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/_global\\-error(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/_not-found",
|
||||
"regex": "^/_not\\-found(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/_not\\-found(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/achievements",
|
||||
"regex": "^/api/achievements(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/achievements(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/auth/callback",
|
||||
"regex": "^/api/auth/callback(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/auth/callback(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/auth/login",
|
||||
"regex": "^/api/auth/login(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/auth/login(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/auth/logout",
|
||||
"regex": "^/api/auth/logout(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/auth/logout(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/cron/reminders",
|
||||
"regex": "^/api/cron/reminders(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/cron/reminders(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/mood",
|
||||
"regex": "^/api/mood(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/mood(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/notifications/subscribe",
|
||||
"regex": "^/api/notifications/subscribe(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/notifications/subscribe(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/notifications/test",
|
||||
"regex": "^/api/notifications/test(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/notifications/test(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/preferences",
|
||||
"regex": "^/api/preferences(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/preferences(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/reminders",
|
||||
"regex": "^/api/reminders(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/reminders(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/savings",
|
||||
"regex": "^/api/savings(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/savings(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/api/usage",
|
||||
"regex": "^/api/usage(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/api/usage(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/callback",
|
||||
"regex": "^/callback(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/callback(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/login",
|
||||
"regex": "^/login(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/login(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/signout",
|
||||
"regex": "^/signout(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/signout(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/smoking-aids",
|
||||
"regex": "^/smoking\\-aids(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/smoking\\-aids(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/track/marijuana",
|
||||
"regex": "^/track/marijuana(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/track/marijuana(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/track/nicotine",
|
||||
"regex": "^/track/nicotine(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/track/nicotine(?:/)?$"
|
||||
}
|
||||
],
|
||||
"dataRoutes": [],
|
||||
"rsc": {
|
||||
"header": "rsc",
|
||||
"varyHeader": "rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch",
|
||||
"prefetchHeader": "next-router-prefetch",
|
||||
"didPostponeHeader": "x-nextjs-postponed",
|
||||
"contentTypeHeader": "text/x-component",
|
||||
"suffix": ".rsc",
|
||||
"prefetchSegmentHeader": "next-router-segment-prefetch",
|
||||
"prefetchSegmentSuffix": ".segment.rsc",
|
||||
"prefetchSegmentDirSuffix": ".segments",
|
||||
"clientParamParsing": false,
|
||||
"dynamicRSCPrerender": false
|
||||
},
|
||||
"rewriteHeaders": {
|
||||
"pathHeader": "x-nextjs-rewritten-path",
|
||||
"queryHeader": "x-nextjs-rewritten-query"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"/_global-error/page": "app/_global-error/page.js",
|
||||
"/_not-found/page": "app/_not-found/page.js",
|
||||
"/api/achievements/route": "app/api/achievements/route.js",
|
||||
"/api/auth/callback/route": "app/api/auth/callback/route.js",
|
||||
"/api/auth/login/route": "app/api/auth/login/route.js",
|
||||
"/api/auth/logout/route": "app/api/auth/logout/route.js",
|
||||
"/api/cron/reminders/route": "app/api/cron/reminders/route.js",
|
||||
"/api/mood/route": "app/api/mood/route.js",
|
||||
"/api/notifications/subscribe/route": "app/api/notifications/subscribe/route.js",
|
||||
"/api/notifications/test/route": "app/api/notifications/test/route.js",
|
||||
"/api/preferences/route": "app/api/preferences/route.js",
|
||||
"/api/reminders/route": "app/api/reminders/route.js",
|
||||
"/api/savings/route": "app/api/savings/route.js",
|
||||
"/api/usage/route": "app/api/usage/route.js",
|
||||
"/callback/route": "app/callback/route.js",
|
||||
"/login/page": "app/login/page.js",
|
||||
"/page": "app/page.js",
|
||||
"/signout/page": "app/signout/page.js",
|
||||
"/smoking-aids/page": "app/smoking-aids/page.js",
|
||||
"/track/marijuana/page": "app/track/marijuana/page.js",
|
||||
"/track/nicotine/page": "app/track/nicotine/page.js"
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
var R=require("../../chunks/ssr/[turbopack]_runtime.js")("server/app/_global-error/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__b9356576._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_4b9a0874._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_08570d7f._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__03cf7906._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__e17d8479._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_2e5d1b2c._.js")
|
||||
R.c("server/chunks/ssr/_next-internal_server_app__global-error_page_actions_75761787.js")
|
||||
R.m(37823)
|
||||
module.exports=R.m(37823).exports
|
||||
@ -0,0 +1 @@
|
||||
{}
|
||||
@ -0,0 +1,13 @@
|
||||
var R=require("../../chunks/ssr/[turbopack]_runtime.js")("server/app/_not-found/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__15600e29._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_4b9a0874._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_65a7265e.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__03cf7906._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__e17d8479._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_2e5d1b2c._.js")
|
||||
R.c("server/chunks/ssr/src_e0b6e6ca._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_client_components_9774470f._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_45780354.js")
|
||||
R.c("server/chunks/ssr/_next-internal_server_app__not-found_page_actions_554ec2bf.js")
|
||||
R.m(68592)
|
||||
module.exports=R.m(68592).exports
|
||||
@ -0,0 +1 @@
|
||||
{}
|
||||
@ -0,0 +1,8 @@
|
||||
var R=require("../../../chunks/[turbopack]_runtime.js")("server/app/api/achievements/route.js")
|
||||
R.c("server/chunks/[root-of-the-server]__16959b0c._.js")
|
||||
R.c("server/chunks/_07602783._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__f408c708._.js")
|
||||
R.c("server/chunks/node_modules_next_f5199d09._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_api_achievements_route_actions_2d2fdfd2.js")
|
||||
R.m(3148)
|
||||
module.exports=R.m(3148).exports
|
||||
@ -0,0 +1,2 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/api/achievements/route"] = {"moduleLoading":{"prefix":"","crossOrigin":null},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}}
|
||||
@ -0,0 +1,8 @@
|
||||
var R=require("../../../../chunks/[turbopack]_runtime.js")("server/app/api/auth/callback/route.js")
|
||||
R.c("server/chunks/[root-of-the-server]__cc235ee5._.js")
|
||||
R.c("server/chunks/node_modules_next_f5199d09._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__f408c708._.js")
|
||||
R.c("server/chunks/src_lib_workos_ts_4f077b01._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_api_auth_callback_route_actions_66c10d83.js")
|
||||
R.m(42986)
|
||||
module.exports=R.m(42986).exports
|
||||
@ -0,0 +1,2 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/api/auth/callback/route"] = {"moduleLoading":{"prefix":"","crossOrigin":null},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}}
|
||||
@ -0,0 +1,8 @@
|
||||
var R=require("../../../../chunks/[turbopack]_runtime.js")("server/app/api/auth/login/route.js")
|
||||
R.c("server/chunks/[root-of-the-server]__a2345b9f._.js")
|
||||
R.c("server/chunks/node_modules_next_f5199d09._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__f408c708._.js")
|
||||
R.c("server/chunks/src_lib_workos_ts_4f077b01._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_api_auth_login_route_actions_d02a8f19.js")
|
||||
R.m(30450)
|
||||
module.exports=R.m(30450).exports
|
||||
@ -0,0 +1,2 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/api/auth/login/route"] = {"moduleLoading":{"prefix":"","crossOrigin":null},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}}
|
||||
@ -0,0 +1,7 @@
|
||||
var R=require("../../../../chunks/[turbopack]_runtime.js")("server/app/api/auth/logout/route.js")
|
||||
R.c("server/chunks/[root-of-the-server]__6cdb832a._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__f408c708._.js")
|
||||
R.c("server/chunks/node_modules_next_f5199d09._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_api_auth_logout_route_actions_5aa6c6ca.js")
|
||||
R.m(83932)
|
||||
module.exports=R.m(83932).exports
|
||||
@ -0,0 +1,2 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/api/auth/logout/route"] = {"moduleLoading":{"prefix":"","crossOrigin":null},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}}
|
||||
@ -0,0 +1,8 @@
|
||||
var R=require("../../../../chunks/[turbopack]_runtime.js")("server/app/api/cron/reminders/route.js")
|
||||
R.c("server/chunks/[root-of-the-server]__728e5b1d._.js")
|
||||
R.c("server/chunks/_07602783._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__f408c708._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__2015e3ee._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_api_cron_reminders_route_actions_10b682dc.js")
|
||||
R.m(9044)
|
||||
module.exports=R.m(9044).exports
|
||||
@ -0,0 +1,2 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/api/cron/reminders/route"] = {"moduleLoading":{"prefix":"","crossOrigin":null},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}}
|
||||
@ -0,0 +1,8 @@
|
||||
var R=require("../../../chunks/[turbopack]_runtime.js")("server/app/api/mood/route.js")
|
||||
R.c("server/chunks/[root-of-the-server]__fb987859._.js")
|
||||
R.c("server/chunks/_07602783._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__f408c708._.js")
|
||||
R.c("server/chunks/node_modules_next_f5199d09._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_api_mood_route_actions_7bf7970f.js")
|
||||
R.m(60194)
|
||||
module.exports=R.m(60194).exports
|
||||
@ -0,0 +1,2 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/api/mood/route"] = {"moduleLoading":{"prefix":"","crossOrigin":null},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}}
|
||||
@ -0,0 +1,8 @@
|
||||
var R=require("../../../../chunks/[turbopack]_runtime.js")("server/app/api/notifications/subscribe/route.js")
|
||||
R.c("server/chunks/[root-of-the-server]__3dd70be1._.js")
|
||||
R.c("server/chunks/_07602783._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__f408c708._.js")
|
||||
R.c("server/chunks/node_modules_next_f5199d09._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_api_notifications_subscribe_route_actions_de38c3e2.js")
|
||||
R.m(43716)
|
||||
module.exports=R.m(43716).exports
|
||||
@ -0,0 +1,2 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/api/notifications/subscribe/route"] = {"moduleLoading":{"prefix":"","crossOrigin":null},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}}
|
||||