@lidofinance/next-cache-files-middleware 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # @lidofinance/next-cache-files-middleware
2
+
3
+ Next.js middleware to add cache-control headers to file requests
4
+ You can read about middleware [there](https://nextjs.org/docs/advanced-features/middleware)
5
+
6
+ ## Installation
7
+
8
+ `yarn add @lidofinance/next-cache-files-middleware`.
9
+
10
+ ## Getting started
11
+
12
+ ### Usage
13
+
14
+ 1. Create file middleware.ts in root folder
15
+ 2. Put the code from the example in this file
16
+ 3. Update configuration constants if necessary
17
+
18
+ ---
19
+
20
+ #### About constant `config`
21
+
22
+ The matcher values need to be constants so they can be statically analyzed at build-time.
23
+ Dynamic values such as variables will be ignored.
24
+ **Therefore, you need to manually register the specified paths from the example.**
25
+ Example [there](src/constants.ts) `exampleMiddlewareConfig`
26
+
27
+ ---
28
+
29
+ ```ts
30
+ import { cacheControlMiddlewareFactory } from '@lidofinance/next-cache-files-middleware'
31
+
32
+ export const middleware = cacheControlMiddlewareFactory()
33
+
34
+ export const config = {
35
+ // paths where use middleware
36
+ matcher: ['/manifest.json', '/favicon:size*'],
37
+ }
38
+
39
+ export default middleware
40
+ ```
41
+
42
+ ### Use with your own allowed list
43
+
44
+ ```ts
45
+ import {
46
+ cacheControlMiddlewareFactory,
47
+ CacheAllowedItem,
48
+ CACHE_FILE_DEFAULT_HEADERS
49
+ } from '@lidofinance/next-cache-files-middleware'
50
+
51
+ // cache allowed list
52
+ const SomePathConfig: CacheAllowedItem[] = [{
53
+ { path: /^\/someStaticFileRegExp.json?$/, headers: CACHE_FILE_DEFAULT_HEADERS },
54
+ { path: '/someStaticFileString.json', headers: CACHE_FILE_DEFAULT_HEADERS },
55
+ }]
56
+
57
+ // Use allowed list
58
+ export const middleware = cacheControlMiddlewareFactory(SomePathConfig)
59
+
60
+ // Note: The matcher values need to be constants so they can be statically analyzed at build-time.
61
+ // Dynamic values such as variables will be ignored.
62
+ export const config = {
63
+ // paths where use middleware
64
+ matcher: ['/manifest.json', '/favicon:size*', '/someStaticFile.json']
65
+ }
66
+
67
+ export default middleware
68
+ ```
69
+
70
+ ### Use with your own middleware
71
+
72
+ ```ts
73
+ import {
74
+ cacheControlMiddlewareFactory,
75
+ CacheAllowedItem,
76
+ CACHE_FILE_DEFAULT_HEADERS
77
+ } from '@lidofinance/next-cache-files-middleware'
78
+
79
+ // cache allowed list
80
+ const SomePathConfig: CacheAllowedItem[] = [{
81
+ { path: /^\/someStaticFileRegExp.json?$/, headers: CACHE_FILE_DEFAULT_HEADERS },
82
+ { path: '/someStaticFileString.json', headers: CACHE_FILE_DEFAULT_HEADERS },
83
+ }]
84
+
85
+ // Use allowed list
86
+ export const cacheControlMiddleware = cacheControlMiddlewareFactory(SomePathConfig)
87
+ // or
88
+ export const cacheControlMiddleware = cacheControlMiddlewareFactory()
89
+
90
+ // use only for cache files
91
+ const middleware = (req: NextRequest): NextResponse => {
92
+ // add cache control middleware
93
+ const response = cacheControlMiddleware(req);
94
+
95
+ // some code
96
+
97
+ return response;
98
+ }
99
+
100
+ // or use wrapper
101
+ export const middleware = cacheControlMiddlewareWrapper(SomePathConfig)((req, res) => {
102
+ // some code
103
+
104
+ return res;
105
+ });
106
+
107
+ export const config = {
108
+ // paths where use middleware
109
+ matcher: ['/manifest.json', '/favicon:size*', '/someUrl'],
110
+ };
111
+
112
+ export default middleware;
113
+
114
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,143 @@
1
+ var $2Aiq4$nextserver = require("next/server");
2
+
3
+ function $parcel$exportWildcard(dest, source) {
4
+ Object.keys(source).forEach(function(key) {
5
+ if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) {
6
+ return;
7
+ }
8
+
9
+ Object.defineProperty(dest, key, {
10
+ enumerable: true,
11
+ get: function get() {
12
+ return source[key];
13
+ }
14
+ });
15
+ });
16
+
17
+ return dest;
18
+ }
19
+ function $parcel$export(e, n, v, s) {
20
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
21
+ }
22
+ var $9295f689042d9f46$exports = {};
23
+
24
+ $parcel$export($9295f689042d9f46$exports, "cacheControlMiddlewareFactory", function () { return $9295f689042d9f46$export$772f11b002f0df57; });
25
+ $parcel$export($9295f689042d9f46$exports, "cacheControlMiddlewareWrapper", function () { return $9295f689042d9f46$export$b9d63b233c9c06f; });
26
+
27
+ var $db38a4f6de2a3704$exports = {};
28
+
29
+ $parcel$export($db38a4f6de2a3704$exports, "findCacheControlFileHeaders", function () { return $db38a4f6de2a3704$export$2cbb5ba6d79dc635; });
30
+ var $35b96dc7f51731b2$exports = {};
31
+
32
+ $parcel$export($35b96dc7f51731b2$exports, "CacheStorage", function () { return $35b96dc7f51731b2$export$2b715f8922748263; });
33
+ const $35b96dc7f51731b2$var$DEFAULT_CACHE_LIMIT = 1000;
34
+ class $35b96dc7f51731b2$export$2b715f8922748263 {
35
+ set(key, value) {
36
+ // refresh key
37
+ if (this._storage.has(key)) this._storage.delete(key);
38
+ else if (this._storage.size == this._cacheLimit) this._storage.delete(this.getFirst());
39
+ this._storage.set(key, value);
40
+ }
41
+ get(key) {
42
+ const item = this._storage.get(key);
43
+ if (item) {
44
+ // refresh key
45
+ this._storage.delete(key);
46
+ this._storage.set(key, item);
47
+ }
48
+ return item;
49
+ }
50
+ delete(key) {
51
+ if (this._storage.has(key)) this._storage.delete(key);
52
+ }
53
+ getFirst() {
54
+ return this._storage.keys().next().value;
55
+ }
56
+ constructor(limit){
57
+ this._cacheLimit = limit || $35b96dc7f51731b2$var$DEFAULT_CACHE_LIMIT;
58
+ this._storage = new Map();
59
+ }
60
+ }
61
+
62
+
63
+ var $5d01ba631015e899$exports = {};
64
+
65
+ $parcel$export($5d01ba631015e899$exports, "CACHE_FILE_DEFAULT_HEADERS", function () { return $5d01ba631015e899$export$5133cce848cb94ba; });
66
+ $parcel$export($5d01ba631015e899$exports, "CACHE_ALLOWED_LIST_FILES_PATHS", function () { return $5d01ba631015e899$export$a0fb92f5bd6f13d2; });
67
+ $parcel$export($5d01ba631015e899$exports, "exampleMiddlewareConfig", function () { return $5d01ba631015e899$export$6f78ef01998c9e53; });
68
+ const $5d01ba631015e899$export$5133cce848cb94ba = "public, max-age=180, stale-if-error=1200, stale-while-revalidate=60";
69
+ const $5d01ba631015e899$export$a0fb92f5bd6f13d2 = [
70
+ {
71
+ path: /^\/favicon-?[^@]*.(svg|ico)?$/,
72
+ headers: $5d01ba631015e899$export$5133cce848cb94ba
73
+ },
74
+ {
75
+ path: "/manifest.json",
76
+ headers: $5d01ba631015e899$export$5133cce848cb94ba
77
+ },
78
+ ];
79
+ const $5d01ba631015e899$export$6f78ef01998c9e53 = {
80
+ // paths where use middleware
81
+ matcher: [
82
+ "/manifest.json",
83
+ "/favicon:size*"
84
+ ]
85
+ };
86
+
87
+
88
+ const $db38a4f6de2a3704$var$cache = new (0, $35b96dc7f51731b2$export$2b715f8922748263)();
89
+ const $db38a4f6de2a3704$var$checkValueIsString = (value)=>{
90
+ return value !== null && typeof value === "string";
91
+ };
92
+ const $db38a4f6de2a3704$export$2cbb5ba6d79dc635 = (data)=>{
93
+ var ref;
94
+ const { allowedList: allowedList , url: url } = data;
95
+ const requestPath = url === null || url === void 0 ? void 0 : url.split("?")[0];
96
+ if (!requestPath) return;
97
+ const cacheValue = $db38a4f6de2a3704$var$cache.get(requestPath);
98
+ if (cacheValue) return cacheValue;
99
+ const list = [
100
+ ...(0, $5d01ba631015e899$export$a0fb92f5bd6f13d2),
101
+ ...allowedList || []
102
+ ];
103
+ const urlHeaders = (ref = list.find(({ path: path })=>{
104
+ if ($db38a4f6de2a3704$var$checkValueIsString(path)) return path === requestPath;
105
+ return path.test(requestPath);
106
+ })) === null || ref === void 0 ? void 0 : ref.headers;
107
+ if (urlHeaders) $db38a4f6de2a3704$var$cache.set(requestPath, urlHeaders);
108
+ return urlHeaders;
109
+ };
110
+
111
+
112
+ const $9295f689042d9f46$export$772f11b002f0df57 = (allowedList)=>(req)=>{
113
+ const response = (0, $2Aiq4$nextserver.NextResponse).next();
114
+ const { pathname: pathname } = req.nextUrl;
115
+ // Use allowed list
116
+ const headers = (0, $db38a4f6de2a3704$export$2cbb5ba6d79dc635)({
117
+ allowedList: allowedList,
118
+ url: pathname
119
+ });
120
+ if (!headers) return response;
121
+ response.headers.append("Cache-Control", headers);
122
+ return response;
123
+ };
124
+ const $9295f689042d9f46$export$b9d63b233c9c06f = (allowedList)=>(next)=>(req)=>{
125
+ const response = $9295f689042d9f46$export$772f11b002f0df57(allowedList)(req);
126
+ return next(req, response);
127
+ };
128
+
129
+
130
+
131
+
132
+ var $0990bb00b11648b5$exports = {};
133
+
134
+
135
+
136
+ $parcel$exportWildcard(module.exports, $9295f689042d9f46$exports);
137
+ $parcel$exportWildcard(module.exports, $db38a4f6de2a3704$exports);
138
+ $parcel$exportWildcard(module.exports, $5d01ba631015e899$exports);
139
+ $parcel$exportWildcard(module.exports, $0990bb00b11648b5$exports);
140
+ $parcel$exportWildcard(module.exports, $35b96dc7f51731b2$exports);
141
+
142
+
143
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["packages/next/cache-files-middleware/src/index.ts","packages/next/cache-files-middleware/src/middleware.ts","packages/next/cache-files-middleware/src/utils.ts","packages/next/cache-files-middleware/src/cache.ts","packages/next/cache-files-middleware/src/constants.ts","packages/next/cache-files-middleware/src/types.ts"],"sourcesContent":["export * from './middleware'\nexport * from './utils'\nexport * from './constants'\nexport * from './types'\nexport * from './cache'\n","import { NextResponse } from 'next/server'\nimport type { NextRequest } from 'next/server'\nimport { findCacheControlFileHeaders } from './utils'\nimport { CacheAllowedItem } from './types'\n\n// use only for cache files\nexport const cacheControlMiddlewareFactory =\n (allowedList?: CacheAllowedItem[]) =>\n (req: NextRequest): NextResponse => {\n const response = NextResponse.next()\n const { pathname } = req.nextUrl\n\n // Use allowed list\n const headers = findCacheControlFileHeaders({ allowedList, url: pathname })\n if (!headers) return response\n\n response.headers.append('Cache-Control', headers)\n\n return response\n }\n\nexport const cacheControlMiddlewareWrapper =\n (allowedList?: CacheAllowedItem[]) =>\n (next: (req: NextRequest, res: NextResponse) => NextResponse) =>\n (req: NextRequest): NextResponse => {\n const response = cacheControlMiddlewareFactory(allowedList)(req)\n\n return next(req, response)\n }\n","import { CacheStorage } from './cache'\nimport { CACHE_ALLOWED_LIST_FILES_PATHS } from './constants'\nimport { CacheAllowedItem } from './types'\n\nconst cache = new CacheStorage()\n\nconst checkValueIsString = (value: unknown): value is string => {\n return value !== null && typeof value === 'string'\n}\n\nexport const findCacheControlFileHeaders = (data: {\n allowedList?: CacheAllowedItem[]\n url?: string\n}): string | undefined => {\n const { allowedList, url } = data\n const requestPath = url?.split('?')[0]\n\n if (!requestPath) return\n\n const cacheValue = cache.get(requestPath)\n if (cacheValue) return cacheValue\n\n const list = [...CACHE_ALLOWED_LIST_FILES_PATHS, ...(allowedList || [])]\n\n const urlHeaders = list.find(({ path }) => {\n if (checkValueIsString(path)) return path === requestPath\n return path.test(requestPath)\n })?.headers\n if (urlHeaders) cache.set(requestPath, urlHeaders)\n\n return urlHeaders\n}\n","const DEFAULT_CACHE_LIMIT = 1000\n\nexport class CacheStorage {\n private _storage: Map<string, string>\n private _cacheLimit: number\n\n constructor(limit?: number) {\n this._cacheLimit = limit || DEFAULT_CACHE_LIMIT\n this._storage = new Map<string, string>()\n }\n\n set(key: string, value: string) {\n // refresh key\n if (this._storage.has(key)) this._storage.delete(key)\n // delete oldest\n else if (this._storage.size == this._cacheLimit) this._storage.delete(this.getFirst())\n\n this._storage.set(key, value)\n }\n\n get(key: string) {\n const item = this._storage.get(key)\n if (item) {\n // refresh key\n this._storage.delete(key)\n this._storage.set(key, item)\n }\n\n return item\n }\n\n delete(key: string) {\n if (this._storage.has(key)) {\n this._storage.delete(key)\n }\n }\n\n getFirst() {\n return this._storage.keys().next().value as string\n }\n}\n","import { CacheAllowedItem } from './types'\n\nexport const CACHE_FILE_DEFAULT_HEADERS = 'public, max-age=180, stale-if-error=1200, stale-while-revalidate=60'\n\nexport const CACHE_ALLOWED_LIST_FILES_PATHS: CacheAllowedItem[] = [\n { path: /^\\/favicon-?[^@]*.(svg|ico)?$/, headers: CACHE_FILE_DEFAULT_HEADERS },\n { path: '/manifest.json', headers: CACHE_FILE_DEFAULT_HEADERS },\n]\n\n// It is example.\n// Note: The matcher values need to be constants so they can be statically analyzed at build-time.\n// Dynamic values such as variables will be ignored.\nexport const exampleMiddlewareConfig = {\n // paths where use middleware\n matcher: ['/manifest.json', '/favicon:size*'],\n}\n","export type CacheAllowedItem = {\n path: RegExp | string\n headers: string\n}\n"],"names":[],"version":3,"file":"index.cjs.map"}
@@ -0,0 +1,25 @@
1
+ import { NextResponse, NextRequest } from "next/server";
2
+ export class CacheStorage {
3
+ constructor(limit?: number);
4
+ set(key: string, value: string): void;
5
+ get(key: string): string | undefined;
6
+ delete(key: string): void;
7
+ getFirst(): string;
8
+ }
9
+ export type CacheAllowedItem = {
10
+ path: RegExp | string;
11
+ headers: string;
12
+ };
13
+ export const CACHE_FILE_DEFAULT_HEADERS = "public, max-age=180, stale-if-error=1200, stale-while-revalidate=60";
14
+ export const CACHE_ALLOWED_LIST_FILES_PATHS: CacheAllowedItem[];
15
+ export const exampleMiddlewareConfig: {
16
+ matcher: string[];
17
+ };
18
+ export const findCacheControlFileHeaders: (data: {
19
+ allowedList?: CacheAllowedItem[] | undefined;
20
+ url?: string | undefined;
21
+ }) => string | undefined;
22
+ export const cacheControlMiddlewareFactory: (allowedList?: CacheAllowedItem[]) => (req: NextRequest) => NextResponse;
23
+ export const cacheControlMiddlewareWrapper: (allowedList?: CacheAllowedItem[]) => (next: (req: NextRequest, res: NextResponse) => NextResponse) => (req: NextRequest) => NextResponse;
24
+
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"mappings":";AAEA;gBAIc,KAAK,CAAC,EAAE,MAAM;IAK1B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAS9B,GAAG,CAAC,GAAG,EAAE,MAAM;IAWf,MAAM,CAAC,GAAG,EAAE,MAAM;IAMlB,QAAQ;CAGT;ACxCD,+BAA+B;IAC7B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;ACDD,OAAO,MAAM,kGAAkG,CAAA;AAE/G,OAAO,MAAM,gCAAgC,gBAAgB,EAG5D,CAAA;AAKD,OAAO,MAAM;;CAGZ,CAAA;ACLD,OAAO,MAAM;;;MAGT,MAAM,GAAG,SAkBZ,CAAA;ACzBD,OAAO,MAAM,8CACI,gBAAgB,EAAE,WAC3B,WAAW,KAAG,YAWnB,CAAA;AAEH,OAAO,MAAM,8CACI,gBAAgB,EAAE,kBACpB,WAAW,OAAO,YAAY,KAAK,YAAY,WACtD,WAAW,KAAG,YAInB,CAAA","sources":["packages/next/cache-files-middleware/src/src/cache.ts","packages/next/cache-files-middleware/src/src/types.ts","packages/next/cache-files-middleware/src/src/constants.ts","packages/next/cache-files-middleware/src/src/utils.ts","packages/next/cache-files-middleware/src/src/middleware.ts","packages/next/cache-files-middleware/src/src/index.ts","packages/next/cache-files-middleware/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,"export * from './middleware'\nexport * from './utils'\nexport * from './constants'\nexport * from './types'\nexport * from './cache'\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.mjs ADDED
@@ -0,0 +1,123 @@
1
+ import {NextResponse as $eTMD6$NextResponse} from "next/server";
2
+
3
+ function $parcel$export(e, n, v, s) {
4
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
5
+ }
6
+ var $b299b3c58bd52b75$exports = {};
7
+
8
+ $parcel$export($b299b3c58bd52b75$exports, "cacheControlMiddlewareFactory", function () { return $b299b3c58bd52b75$export$772f11b002f0df57; });
9
+ $parcel$export($b299b3c58bd52b75$exports, "cacheControlMiddlewareWrapper", function () { return $b299b3c58bd52b75$export$b9d63b233c9c06f; });
10
+
11
+ var $43f369dac868c8fa$exports = {};
12
+
13
+ $parcel$export($43f369dac868c8fa$exports, "findCacheControlFileHeaders", function () { return $43f369dac868c8fa$export$2cbb5ba6d79dc635; });
14
+ var $60acf04ea0909747$exports = {};
15
+
16
+ $parcel$export($60acf04ea0909747$exports, "CacheStorage", function () { return $60acf04ea0909747$export$2b715f8922748263; });
17
+ const $60acf04ea0909747$var$DEFAULT_CACHE_LIMIT = 1000;
18
+ class $60acf04ea0909747$export$2b715f8922748263 {
19
+ set(key, value) {
20
+ // refresh key
21
+ if (this._storage.has(key)) this._storage.delete(key);
22
+ else if (this._storage.size == this._cacheLimit) this._storage.delete(this.getFirst());
23
+ this._storage.set(key, value);
24
+ }
25
+ get(key) {
26
+ const item = this._storage.get(key);
27
+ if (item) {
28
+ // refresh key
29
+ this._storage.delete(key);
30
+ this._storage.set(key, item);
31
+ }
32
+ return item;
33
+ }
34
+ delete(key) {
35
+ if (this._storage.has(key)) this._storage.delete(key);
36
+ }
37
+ getFirst() {
38
+ return this._storage.keys().next().value;
39
+ }
40
+ constructor(limit){
41
+ this._cacheLimit = limit || $60acf04ea0909747$var$DEFAULT_CACHE_LIMIT;
42
+ this._storage = new Map();
43
+ }
44
+ }
45
+
46
+
47
+ var $7d49ed295294e3c0$exports = {};
48
+
49
+ $parcel$export($7d49ed295294e3c0$exports, "CACHE_FILE_DEFAULT_HEADERS", function () { return $7d49ed295294e3c0$export$5133cce848cb94ba; });
50
+ $parcel$export($7d49ed295294e3c0$exports, "CACHE_ALLOWED_LIST_FILES_PATHS", function () { return $7d49ed295294e3c0$export$a0fb92f5bd6f13d2; });
51
+ $parcel$export($7d49ed295294e3c0$exports, "exampleMiddlewareConfig", function () { return $7d49ed295294e3c0$export$6f78ef01998c9e53; });
52
+ const $7d49ed295294e3c0$export$5133cce848cb94ba = "public, max-age=180, stale-if-error=1200, stale-while-revalidate=60";
53
+ const $7d49ed295294e3c0$export$a0fb92f5bd6f13d2 = [
54
+ {
55
+ path: /^\/favicon-?[^@]*.(svg|ico)?$/,
56
+ headers: $7d49ed295294e3c0$export$5133cce848cb94ba
57
+ },
58
+ {
59
+ path: "/manifest.json",
60
+ headers: $7d49ed295294e3c0$export$5133cce848cb94ba
61
+ },
62
+ ];
63
+ const $7d49ed295294e3c0$export$6f78ef01998c9e53 = {
64
+ // paths where use middleware
65
+ matcher: [
66
+ "/manifest.json",
67
+ "/favicon:size*"
68
+ ]
69
+ };
70
+
71
+
72
+ const $43f369dac868c8fa$var$cache = new (0, $60acf04ea0909747$export$2b715f8922748263)();
73
+ const $43f369dac868c8fa$var$checkValueIsString = (value)=>{
74
+ return value !== null && typeof value === "string";
75
+ };
76
+ const $43f369dac868c8fa$export$2cbb5ba6d79dc635 = (data)=>{
77
+ var ref;
78
+ const { allowedList: allowedList , url: url } = data;
79
+ const requestPath = url === null || url === void 0 ? void 0 : url.split("?")[0];
80
+ if (!requestPath) return;
81
+ const cacheValue = $43f369dac868c8fa$var$cache.get(requestPath);
82
+ if (cacheValue) return cacheValue;
83
+ const list = [
84
+ ...(0, $7d49ed295294e3c0$export$a0fb92f5bd6f13d2),
85
+ ...allowedList || []
86
+ ];
87
+ const urlHeaders = (ref = list.find(({ path: path })=>{
88
+ if ($43f369dac868c8fa$var$checkValueIsString(path)) return path === requestPath;
89
+ return path.test(requestPath);
90
+ })) === null || ref === void 0 ? void 0 : ref.headers;
91
+ if (urlHeaders) $43f369dac868c8fa$var$cache.set(requestPath, urlHeaders);
92
+ return urlHeaders;
93
+ };
94
+
95
+
96
+ const $b299b3c58bd52b75$export$772f11b002f0df57 = (allowedList)=>(req)=>{
97
+ const response = (0, $eTMD6$NextResponse).next();
98
+ const { pathname: pathname } = req.nextUrl;
99
+ // Use allowed list
100
+ const headers = (0, $43f369dac868c8fa$export$2cbb5ba6d79dc635)({
101
+ allowedList: allowedList,
102
+ url: pathname
103
+ });
104
+ if (!headers) return response;
105
+ response.headers.append("Cache-Control", headers);
106
+ return response;
107
+ };
108
+ const $b299b3c58bd52b75$export$b9d63b233c9c06f = (allowedList)=>(next)=>(req)=>{
109
+ const response = $b299b3c58bd52b75$export$772f11b002f0df57(allowedList)(req);
110
+ return next(req, response);
111
+ };
112
+
113
+
114
+
115
+
116
+ var $9476757477c2b6d6$exports = {};
117
+
118
+
119
+
120
+
121
+
122
+ export {$b299b3c58bd52b75$export$772f11b002f0df57 as cacheControlMiddlewareFactory, $b299b3c58bd52b75$export$b9d63b233c9c06f as cacheControlMiddlewareWrapper, $43f369dac868c8fa$export$2cbb5ba6d79dc635 as findCacheControlFileHeaders, $7d49ed295294e3c0$export$5133cce848cb94ba as CACHE_FILE_DEFAULT_HEADERS, $7d49ed295294e3c0$export$a0fb92f5bd6f13d2 as CACHE_ALLOWED_LIST_FILES_PATHS, $7d49ed295294e3c0$export$6f78ef01998c9e53 as exampleMiddlewareConfig, $60acf04ea0909747$export$2b715f8922748263 as CacheStorage};
123
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["packages/next/cache-files-middleware/src/index.ts","packages/next/cache-files-middleware/src/middleware.ts","packages/next/cache-files-middleware/src/utils.ts","packages/next/cache-files-middleware/src/cache.ts","packages/next/cache-files-middleware/src/constants.ts","packages/next/cache-files-middleware/src/types.ts"],"sourcesContent":["export * from './middleware'\nexport * from './utils'\nexport * from './constants'\nexport * from './types'\nexport * from './cache'\n","import { NextResponse } from 'next/server'\nimport type { NextRequest } from 'next/server'\nimport { findCacheControlFileHeaders } from './utils'\nimport { CacheAllowedItem } from './types'\n\n// use only for cache files\nexport const cacheControlMiddlewareFactory =\n (allowedList?: CacheAllowedItem[]) =>\n (req: NextRequest): NextResponse => {\n const response = NextResponse.next()\n const { pathname } = req.nextUrl\n\n // Use allowed list\n const headers = findCacheControlFileHeaders({ allowedList, url: pathname })\n if (!headers) return response\n\n response.headers.append('Cache-Control', headers)\n\n return response\n }\n\nexport const cacheControlMiddlewareWrapper =\n (allowedList?: CacheAllowedItem[]) =>\n (next: (req: NextRequest, res: NextResponse) => NextResponse) =>\n (req: NextRequest): NextResponse => {\n const response = cacheControlMiddlewareFactory(allowedList)(req)\n\n return next(req, response)\n }\n","import { CacheStorage } from './cache'\nimport { CACHE_ALLOWED_LIST_FILES_PATHS } from './constants'\nimport { CacheAllowedItem } from './types'\n\nconst cache = new CacheStorage()\n\nconst checkValueIsString = (value: unknown): value is string => {\n return value !== null && typeof value === 'string'\n}\n\nexport const findCacheControlFileHeaders = (data: {\n allowedList?: CacheAllowedItem[]\n url?: string\n}): string | undefined => {\n const { allowedList, url } = data\n const requestPath = url?.split('?')[0]\n\n if (!requestPath) return\n\n const cacheValue = cache.get(requestPath)\n if (cacheValue) return cacheValue\n\n const list = [...CACHE_ALLOWED_LIST_FILES_PATHS, ...(allowedList || [])]\n\n const urlHeaders = list.find(({ path }) => {\n if (checkValueIsString(path)) return path === requestPath\n return path.test(requestPath)\n })?.headers\n if (urlHeaders) cache.set(requestPath, urlHeaders)\n\n return urlHeaders\n}\n","const DEFAULT_CACHE_LIMIT = 1000\n\nexport class CacheStorage {\n private _storage: Map<string, string>\n private _cacheLimit: number\n\n constructor(limit?: number) {\n this._cacheLimit = limit || DEFAULT_CACHE_LIMIT\n this._storage = new Map<string, string>()\n }\n\n set(key: string, value: string) {\n // refresh key\n if (this._storage.has(key)) this._storage.delete(key)\n // delete oldest\n else if (this._storage.size == this._cacheLimit) this._storage.delete(this.getFirst())\n\n this._storage.set(key, value)\n }\n\n get(key: string) {\n const item = this._storage.get(key)\n if (item) {\n // refresh key\n this._storage.delete(key)\n this._storage.set(key, item)\n }\n\n return item\n }\n\n delete(key: string) {\n if (this._storage.has(key)) {\n this._storage.delete(key)\n }\n }\n\n getFirst() {\n return this._storage.keys().next().value as string\n }\n}\n","import { CacheAllowedItem } from './types'\n\nexport const CACHE_FILE_DEFAULT_HEADERS = 'public, max-age=180, stale-if-error=1200, stale-while-revalidate=60'\n\nexport const CACHE_ALLOWED_LIST_FILES_PATHS: CacheAllowedItem[] = [\n { path: /^\\/favicon-?[^@]*.(svg|ico)?$/, headers: CACHE_FILE_DEFAULT_HEADERS },\n { path: '/manifest.json', headers: CACHE_FILE_DEFAULT_HEADERS },\n]\n\n// It is example.\n// Note: The matcher values need to be constants so they can be statically analyzed at build-time.\n// Dynamic values such as variables will be ignored.\nexport const exampleMiddlewareConfig = {\n // paths where use middleware\n matcher: ['/manifest.json', '/favicon:size*'],\n}\n","export type CacheAllowedItem = {\n path: RegExp | string\n headers: string\n}\n"],"names":[],"version":3,"file":"index.mjs.map"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@lidofinance/next-cache-files-middleware",
3
+ "description": "Next middleware for cache files",
4
+ "repository": "git@github.com:lidofinance/warehouse.git",
5
+ "license": "MIT",
6
+ "version": "0.3.0",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "engines": {
11
+ "node": ">= 16",
12
+ "browsers": "> 0.5%, last 2 versions, not dead"
13
+ },
14
+ "source": "./src/index.ts",
15
+ "main": "dist/index.cjs",
16
+ "module": "dist/index.mjs",
17
+ "types": "dist/index.d.ts",
18
+ "scripts": {
19
+ "build": "parcel build",
20
+ "format": "prettier --check src",
21
+ "format:fix": "yarn format --write",
22
+ "types": "tsc --noEmit",
23
+ "test": "jest"
24
+ },
25
+ "peerDependencies": {
26
+ "next": "^12.2.0"
27
+ },
28
+ "devDependencies": {
29
+ "@lidofinance/config-prettier": "~0.3.0",
30
+ "next": "^12.2.0",
31
+ "@types/jest": "^28.1.6",
32
+ "@types/node": "^18.0.6",
33
+ "jest": "^28.1.3",
34
+ "ts-jest": "^28.0.7"
35
+ }
36
+ }