esa-pcg-cli 0.1.2 → 0.1.3
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 +10 -24
- package/dist/_inline-overrides.js +2 -2
- package/dist/_protocol/types.d.ts +3 -0
- package/dist/_protocol/types.js +1 -1
- package/dist/commands/build.js +25 -1
- package/dist/overrides/tagCache/gateway.d.ts +3 -0
- package/dist/overrides/tagCache/gateway.js +26 -1
- package/dist/runtime/cdn-purge.d.ts +49 -0
- package/dist/runtime/cdn-purge.js +237 -0
- package/dist/runtime/image-config.d.ts +45 -0
- package/dist/runtime/image-config.js +144 -0
- package/dist/runtime/image-proxy.js +15 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,38 +12,24 @@ npm install --save-dev esa-pcg-cli
|
|
|
12
12
|
pnpm add -D esa-pcg-cli
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
`@opennextjs/aws` is
|
|
15
|
+
`@opennextjs/aws` is bundled as a regular dependency, so you don't need to add it yourself.
|
|
16
16
|
|
|
17
17
|
## Quick start
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// `pcg build` copies the loader here automatically — your source tree
|
|
28
|
-
// and package.json stay untouched.
|
|
29
|
-
loaderFile: 'node_modules/.pcg/pcg-image-loader.js',
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
export default nextConfig;
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
2. Build and deploy:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npx pcg build --dir .
|
|
39
|
-
npx pcg deploy --dir . # or --local-dev for local-gateway mode
|
|
40
|
-
```
|
|
19
|
+
Most projects need **zero** `next.config` changes — `<Image>` continues to use Next's built-in `/_next/image` route and the wrapper transparently signs the request to the gateway.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx pcg build --dir .
|
|
23
|
+
npx pcg deploy --dir . # or --local-dev for local-gateway mode
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Declare image hosts as usual via `next.config.images.{remotePatterns,domains}`; the wrapper reuses that config to allow / reject incoming `url=` values, matching the semantics of `next dev`.
|
|
41
27
|
|
|
42
28
|
## Commands
|
|
43
29
|
|
|
44
30
|
| Command | What it does |
|
|
45
31
|
|---|---|
|
|
46
|
-
| `pcg build` | Runs OpenNext build with PCG overrides auto-injected. Generates `.open-next
|
|
32
|
+
| `pcg build` | Runs OpenNext build with PCG overrides auto-injected. Generates `.open-next/`. |
|
|
47
33
|
| `pcg deploy` | Uploads cache artifacts to OSS (via gateway-issued STS or local mode). |
|
|
48
34
|
| `pcg serve` | Local dev server backed by the built `.open-next/` (assets + spawned server function). |
|
|
49
35
|
| `pcg upload-cache` / `upload-assets` | Lower-level upload primitives. |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
exports.INLINE_OVERRIDES = {
|
|
3
|
-
"adapters/wrappers/node-server.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod) => function __require() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/runtime/image-proxy.js\nvar require_image_proxy = __commonJS({\n \"dist/runtime/image-proxy.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.handleImageProxy = void 0;\n var stream_1 = require(\"stream\");\n var gateway_auth_1 = require_gateway_auth();\n var GATEWAY_TIMEOUT_MS = 1e4;\n var PASSTHROUGH_HEADERS = [\n \"content-type\",\n \"content-length\",\n \"cache-control\",\n \"etag\",\n \"vary\",\n \"last-modified\",\n \"content-security-policy\"\n ];\n function resolveAbsoluteUrl(rawUrl, req) {\n if (rawUrl.startsWith(\"http://\") || rawUrl.startsWith(\"https://\")) {\n return rawUrl;\n }\n const host = req.headers[\"host\"];\n if (!host)\n return null;\n const protoHeader = req.headers[\"x-forwarded-proto\"];\n const proto = (Array.isArray(protoHeader) ? protoHeader[0] : protoHeader) || (Array.isArray(protoHeader) ? protoHeader[0] : protoHeader) || \"https\";\n const path2 = rawUrl.startsWith(\"/\") ? rawUrl : `/${rawUrl}`;\n return `${proto}://${host}${path2}`;\n }\n function writeJson(res, status, body) {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.end(JSON.stringify(body));\n }\n async function handleImageProxy(req, res) {\n const reqUrl = req.url || \"\";\n const qIdx = reqUrl.indexOf(\"?\");\n if (qIdx === -1) {\n return writeJson(res, 400, { error: \"Missing query parameters\" });\n }\n const params = new URLSearchParams(reqUrl.slice(qIdx + 1));\n const rawUrl = params.get(\"url\");\n const w = params.get(\"w\");\n const q = params.get(\"q\");\n if (!rawUrl || !w) {\n return writeJson(res, 400, {\n error: \"Missing required parameters: url, w\"\n });\n }\n const absoluteUrl = resolveAbsoluteUrl(rawUrl, req);\n if (!absoluteUrl) {\n return writeJson(res, 500, {\n error: \"Cannot resolve absolute URL: missing Host header\"\n });\n }\n const cfg = (0, gateway_auth_1.loadGatewayAuthConfig)();\n if (!cfg) {\n return writeJson(res, 500, {\n error: \"Gateway auth config missing\"\n });\n }\n const upstreamParams = new URLSearchParams({ url: absoluteUrl, w });\n if (q)\n upstreamParams.set(\"q\", q);\n const upstreamPath = `/image/optimize?${upstreamParams}`;\n const ifNoneMatch = req.headers[\"if-none-match\"];\n const upstreamHeaders = {};\n if (typeof ifNoneMatch === \"string\") {\n upstreamHeaders[\"if-none-match\"] = ifNoneMatch;\n }\n const accept = req.headers[\"accept\"];\n if (typeof accept === \"string\") {\n upstreamHeaders[\"accept\"] = accept;\n }\n let upstream;\n try {\n upstream = await (0, gateway_auth_1.gatewayFetch)(cfg, upstreamPath, {\n method: \"GET\",\n headers: upstreamHeaders,\n timeoutMs: GATEWAY_TIMEOUT_MS\n });\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[image-proxy] Gateway timeout after ${GATEWAY_TIMEOUT_MS}ms: ${absoluteUrl}`);\n return writeJson(res, 504, { error: \"Upstream timeout\" });\n }\n console.warn(`[image-proxy] Gateway fetch error: ${err.message} (url=${absoluteUrl})`);\n return writeJson(res, 502, { error: \"Bad gateway\" });\n }\n res.statusCode = upstream.status;\n for (const name of PASSTHROUGH_HEADERS) {\n const value = upstream.headers.get(name);\n if (value !== null) {\n res.setHeader(name, value);\n }\n }\n if (upstream.status === 304 || !upstream.body) {\n res.end();\n return;\n }\n try {\n const nodeStream = stream_1.Readable.fromWeb(upstream.body);\n nodeStream.on(\"error\", (err) => {\n console.warn(`[image-proxy] Stream error: ${err.message}`);\n if (!res.writableEnded)\n res.end();\n });\n nodeStream.pipe(res);\n } catch (err) {\n console.warn(`[image-proxy] Pipe setup failed: ${err.message}`);\n if (!res.headersSent) {\n writeJson(res, 502, { error: \"Stream setup failed\" });\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n }\n exports2.handleImageProxy = handleImageProxy;\n }\n});\n\n// dist/adapters/wrappers/node-server.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar http = require(\"http\");\nvar fs = require(\"fs\");\nvar path = require(\"path\");\nvar image_proxy_1 = require_image_proxy();\nvar MIME_TYPES = {\n \".js\": \"application/javascript\",\n \".mjs\": \"application/javascript\",\n \".css\": \"text/css\",\n \".html\": \"text/html\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".map\": \"application/json\",\n \".txt\": \"text/plain\",\n \".webp\": \"image/webp\"\n};\nfunction parseQuery(url) {\n const idx = url.indexOf(\"?\");\n if (idx === -1)\n return {};\n const params = {};\n const searchParams = new URLSearchParams(url.slice(idx + 1));\n for (const [key, value] of searchParams) {\n const existing = params[key];\n if (existing === void 0) {\n params[key] = value;\n } else if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n params[key] = [existing, value];\n }\n }\n return params;\n}\nfunction parseCookies(cookieHeader) {\n if (!cookieHeader)\n return {};\n const cookies = {};\n for (const pair of cookieHeader.split(\";\")) {\n const eqIdx = pair.indexOf(\"=\");\n if (eqIdx === -1)\n continue;\n const name = pair.slice(0, eqIdx).trim();\n const value = pair.slice(eqIdx + 1).trim();\n if (name)\n cookies[name] = value;\n }\n return cookies;\n}\nfunction flattenHeaders(rawHeaders) {\n const headers = {};\n for (const [key, value] of Object.entries(rawHeaders)) {\n if (value === void 0)\n continue;\n headers[key.toLowerCase()] = Array.isArray(value) ? value.join(\", \") : value;\n }\n return headers;\n}\nasync function readBody(req) {\n if (req.method === \"GET\" || req.method === \"HEAD\")\n return void 0;\n return new Promise((resolve, reject) => {\n const chunks = [];\n req.on(\"data\", (chunk) => chunks.push(chunk));\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n req.on(\"error\", reject);\n });\n}\nfunction serveStaticFile(assetsDir, req, res) {\n var _a, _b;\n const urlPath = (_b = (_a = req.url) === null || _a === void 0 ? void 0 : _a.split(\"?\")[0]) !== null && _b !== void 0 ? _b : \"/\";\n if (urlPath === \"/\" || !urlPath.startsWith(\"/\"))\n return false;\n const filePath = path.join(assetsDir, urlPath);\n const normalizedPath = path.normalize(filePath);\n if (!normalizedPath.startsWith(assetsDir)) {\n res.writeHead(403);\n res.end();\n return true;\n }\n let stat;\n try {\n stat = fs.statSync(normalizedPath);\n } catch (_c) {\n return false;\n }\n if (!stat.isFile())\n return false;\n const ext = path.extname(normalizedPath);\n const contentType = MIME_TYPES[ext] || \"application/octet-stream\";\n const isHashedAsset = urlPath.startsWith(\"/_next/static/\");\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Content-Length\": stat.size,\n \"Cache-Control\": isHashedAsset ? \"public, max-age=31536000, immutable\" : \"public, max-age=60\"\n });\n fs.createReadStream(normalizedPath).pipe(res);\n return true;\n}\nfunction bridgeOpenNextHandler(handler) {\n return async (req, res) => {\n var _a, _b, _c, _d, _e, _f;\n try {\n const rawUrl = req.url || \"/\";\n const headers = flattenHeaders(req.headers);\n const body = await readBody(req);\n const host = headers[\"host\"] || `localhost:${(_a = process.env.PORT) !== null && _a !== void 0 ? _a : \"3000\"}`;\n const proto = ((_c = (_b = headers[\"x-forwarded-proto\"]) === null || _b === void 0 ? void 0 : _b.split(\",\")[0]) === null || _c === void 0 ? void 0 : _c.trim()) || \"http\";\n const absoluteUrl = new URL(`${proto}://${host}${rawUrl}`);\n const event = {\n type: \"core\",\n method: req.method || \"GET\",\n rawPath: absoluteUrl.pathname,\n url: absoluteUrl.href,\n body,\n headers,\n query: parseQuery(rawUrl),\n cookies: parseCookies(headers[\"cookie\"]),\n remoteAddress: ((_e = (_d = headers[\"x-forwarded-for\"]) === null || _d === void 0 ? void 0 : _d.split(\",\")[0]) === null || _e === void 0 ? void 0 : _e.trim()) || headers[\"x-real-ip\"] || ((_f = req.socket) === null || _f === void 0 ? void 0 : _f.remoteAddress) || \"127.0.0.1\"\n };\n const abortController = new AbortController();\n res.on(\"close\", () => abortController.abort());\n const streamCreator = {\n writeHeaders(prelude) {\n res.setHeader(\"Set-Cookie\", prelude.cookies);\n res.writeHead(prelude.statusCode, prelude.headers);\n res.flushHeaders();\n return res;\n },\n abortSignal: abortController.signal\n };\n await handler(event, { streamCreator });\n } catch (err) {\n if (!res.headersSent) {\n const isDev = process.env.NODE_ENV !== \"production\";\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: \"Internal Server Error\",\n ...isDev && { message: err.message, stack: err.stack }\n }));\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n };\n}\nasync function wrapper(handler) {\n var _a;\n const port = parseInt((_a = process.env.PORT) !== null && _a !== void 0 ? _a : \"3000\", 10);\n const assetsDir = path.resolve(process.cwd(), \"..\", \"..\", \"assets\");\n if (!fs.existsSync(assetsDir)) {\n console.warn(`[pcg-node] assets directory not found at ${assetsDir} \\u2014 static file requests will fall through to Next handler`);\n }\n const dispatchToNext = bridgeOpenNextHandler(handler);\n const server = http.createServer(async (req, res) => {\n var _a2, _b;\n const urlPath = (_b = (_a2 = req.url) === null || _a2 === void 0 ? void 0 : _a2.split(\"?\")[0]) !== null && _b !== void 0 ? _b : \"/\";\n if (urlPath === \"/__health\") {\n res.writeHead(200, { \"Content-Type\": \"text/plain\" });\n res.end(\"OK\");\n return;\n }\n if (urlPath === \"/_next/image\") {\n try {\n await (0, image_proxy_1.handleImageProxy)(req, res);\n } catch (err) {\n console.error(\"[pcg-node] image-proxy error:\", err);\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Image proxy failed\" }));\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n return;\n }\n if (serveStaticFile(assetsDir, req, res))\n return;\n await dispatchToNext(req, res);\n });\n let shuttingDown = false;\n const shutdown = (signal) => {\n if (shuttingDown)\n return;\n shuttingDown = true;\n console.log(`[pcg-node] ${signal} received, shutting down...`);\n server.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 5e3).unref();\n };\n process.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n await new Promise((resolve) => {\n server.listen(port, () => {\n console.log(`[pcg-node] Listening on port ${port}`);\n console.log(`[pcg-node] assets: ${assetsDir}`);\n console.log(`[pcg-node] routes: /__health, /_next/image, /_next/static/*, <next>`);\n resolve();\n });\n });\n}\nvar wrapperDef = {\n wrapper,\n name: \"pcg-node\",\n supportStreaming: true\n};\nexports.default = wrapperDef;\n",
|
|
3
|
+
"adapters/wrappers/node-server.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod2) => function __require() {\n return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;\n};\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/runtime/image-config.js\nvar require_image_config = __commonJS({\n \"dist/runtime/image-config.js\"(exports, module) {\n \"use strict\";\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports._setMatcherForTests = exports._resetImageConfigCacheForTests = exports.validateImageUrl = void 0;\n var fs = require(\"fs\");\n var path = require(\"path\");\n var cachedConfig;\n var cachedMatcher;\n var warnedMatcherMissing = false;\n function configFilePath() {\n return path.resolve(process.cwd(), \".next\", \"required-server-files.json\");\n }\n function loadImageConfig() {\n var _a, _b, _c;\n if (cachedConfig !== void 0)\n return cachedConfig;\n const filePath = configFilePath();\n let raw;\n try {\n raw = fs.readFileSync(filePath, \"utf-8\");\n } catch (err) {\n console.warn(`[image-config] required-server-files.json not found at ${filePath} \\u2014 allowing all image URLs (${(_a = err.code) !== null && _a !== void 0 ? _a : err.message})`);\n cachedConfig = { mode: \"config-missing\" };\n return cachedConfig;\n }\n try {\n const parsed = JSON.parse(raw);\n const images = (_c = (_b = parsed === null || parsed === void 0 ? void 0 : parsed.config) === null || _b === void 0 ? void 0 : _b.images) !== null && _c !== void 0 ? _c : {};\n cachedConfig = {\n mode: \"loaded\",\n images: {\n remotePatterns: Array.isArray(images.remotePatterns) ? images.remotePatterns : [],\n domains: Array.isArray(images.domains) ? images.domains : [],\n unoptimized: images.unoptimized === true\n }\n };\n return cachedConfig;\n } catch (err) {\n console.warn(`[image-config] failed to parse ${filePath}: ${err.message} \\u2014 allowing all image URLs`);\n cachedConfig = { mode: \"config-missing\" };\n return cachedConfig;\n }\n }\n function loadMatcher() {\n if (cachedMatcher !== void 0)\n return cachedMatcher;\n try {\n const dynamicRequire = eval(\"require\");\n const mod = dynamicRequire(\"next/dist/shared/lib/match-remote-pattern\");\n const hasRemoteMatch = mod === null || mod === void 0 ? void 0 : mod.hasRemoteMatch;\n if (typeof hasRemoteMatch !== \"function\") {\n throw new Error(\"hasRemoteMatch not exported\");\n }\n cachedMatcher = hasRemoteMatch;\n return cachedMatcher;\n } catch (err) {\n if (!warnedMatcherMissing) {\n warnedMatcherMissing = true;\n console.warn(`[image-config] cannot load next/dist/shared/lib/match-remote-pattern (${err.message}) \\u2014 falling back to deny-external-only mode`);\n }\n cachedMatcher = null;\n return null;\n }\n }\n function validateImageUrl(absoluteUrl, hostHeader) {\n const cfg = loadImageConfig();\n if (cfg.mode === \"config-missing\") {\n return { ok: true, reason: \"config-missing\" };\n }\n const { images } = cfg;\n if (images.unoptimized) {\n return { ok: true, reason: \"unoptimized\" };\n }\n const reqHost = hostHeader.toLowerCase();\n const urlHost = absoluteUrl.host.toLowerCase();\n if (reqHost && reqHost === urlHost) {\n return { ok: true, reason: \"same-origin\" };\n }\n const matcher = loadMatcher();\n if (matcher === null) {\n return { ok: false, reason: \"matcher-unavailable\" };\n }\n if (matcher(images.domains, images.remotePatterns, absoluteUrl)) {\n return { ok: true, reason: \"pattern-match\" };\n }\n return { ok: false, reason: \"remote-pattern-not-matched\" };\n }\n exports.validateImageUrl = validateImageUrl;\n function _resetImageConfigCacheForTests() {\n cachedConfig = void 0;\n cachedMatcher = void 0;\n warnedMatcherMissing = false;\n }\n exports._resetImageConfigCacheForTests = _resetImageConfigCacheForTests;\n function _setMatcherForTests(impl) {\n cachedMatcher = impl;\n }\n exports._setMatcherForTests = _setMatcherForTests;\n }\n});\n\n// dist/runtime/image-proxy.js\nvar require_image_proxy = __commonJS({\n \"dist/runtime/image-proxy.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.handleImageProxy = void 0;\n var stream_1 = require(\"stream\");\n var gateway_auth_1 = require_gateway_auth();\n var image_config_1 = require_image_config();\n var GATEWAY_TIMEOUT_MS = 1e4;\n var PASSTHROUGH_HEADERS = [\n \"content-type\",\n \"content-length\",\n \"cache-control\",\n \"etag\",\n \"vary\",\n \"last-modified\",\n \"content-security-policy\"\n ];\n function resolveAbsoluteUrl(rawUrl, req) {\n if (rawUrl.startsWith(\"http://\") || rawUrl.startsWith(\"https://\")) {\n return rawUrl;\n }\n const host = req.headers[\"host\"];\n if (!host)\n return null;\n const protoHeader = req.headers[\"x-forwarded-proto\"];\n const proto = (Array.isArray(protoHeader) ? protoHeader[0] : protoHeader) || (Array.isArray(protoHeader) ? protoHeader[0] : protoHeader) || \"https\";\n const path3 = rawUrl.startsWith(\"/\") ? rawUrl : `/${rawUrl}`;\n return `${proto}://${host}${path3}`;\n }\n function writeJson(res, status, body) {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.end(JSON.stringify(body));\n }\n async function handleImageProxy(req, res) {\n const reqUrl = req.url || \"\";\n const qIdx = reqUrl.indexOf(\"?\");\n if (qIdx === -1) {\n return writeJson(res, 400, { error: \"Missing query parameters\" });\n }\n const params = new URLSearchParams(reqUrl.slice(qIdx + 1));\n const rawUrl = params.get(\"url\");\n const w = params.get(\"w\");\n const q = params.get(\"q\");\n if (!rawUrl || !w) {\n return writeJson(res, 400, {\n error: \"Missing required parameters: url, w\"\n });\n }\n const absoluteUrl = resolveAbsoluteUrl(rawUrl, req);\n if (!absoluteUrl) {\n return writeJson(res, 500, {\n error: \"Cannot resolve absolute URL: missing Host header\"\n });\n }\n let parsedUrl;\n try {\n parsedUrl = new URL(absoluteUrl);\n } catch (_a) {\n return writeJson(res, 400, { error: \"Invalid url parameter\" });\n }\n const hostHeader = req.headers[\"host\"] || \"\";\n const verdict = (0, image_config_1.validateImageUrl)(parsedUrl, hostHeader);\n if (!verdict.ok) {\n return writeJson(res, 400, { error: \"url not allowed\" });\n }\n const cfg = (0, gateway_auth_1.loadGatewayAuthConfig)();\n if (!cfg) {\n return writeJson(res, 500, {\n error: \"Gateway auth config missing\"\n });\n }\n const upstreamParams = new URLSearchParams({ url: absoluteUrl, w });\n if (q)\n upstreamParams.set(\"q\", q);\n const upstreamPath = `/image/optimize?${upstreamParams}`;\n const ifNoneMatch = req.headers[\"if-none-match\"];\n const upstreamHeaders = {};\n if (typeof ifNoneMatch === \"string\") {\n upstreamHeaders[\"if-none-match\"] = ifNoneMatch;\n }\n const accept = req.headers[\"accept\"];\n if (typeof accept === \"string\") {\n upstreamHeaders[\"accept\"] = accept;\n }\n let upstream;\n try {\n upstream = await (0, gateway_auth_1.gatewayFetch)(cfg, upstreamPath, {\n method: \"GET\",\n headers: upstreamHeaders,\n timeoutMs: GATEWAY_TIMEOUT_MS\n });\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[image-proxy] Gateway timeout after ${GATEWAY_TIMEOUT_MS}ms: ${absoluteUrl}`);\n return writeJson(res, 504, { error: \"Upstream timeout\" });\n }\n console.warn(`[image-proxy] Gateway fetch error: ${err.message} (url=${absoluteUrl})`);\n return writeJson(res, 502, { error: \"Bad gateway\" });\n }\n res.statusCode = upstream.status;\n for (const name of PASSTHROUGH_HEADERS) {\n const value = upstream.headers.get(name);\n if (value !== null) {\n res.setHeader(name, value);\n }\n }\n if (upstream.status === 304 || !upstream.body) {\n res.end();\n return;\n }\n try {\n const nodeStream = stream_1.Readable.fromWeb(upstream.body);\n nodeStream.on(\"error\", (err) => {\n console.warn(`[image-proxy] Stream error: ${err.message}`);\n if (!res.writableEnded)\n res.end();\n });\n nodeStream.pipe(res);\n } catch (err) {\n console.warn(`[image-proxy] Pipe setup failed: ${err.message}`);\n if (!res.headersSent) {\n writeJson(res, 502, { error: \"Stream setup failed\" });\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n }\n exports2.handleImageProxy = handleImageProxy;\n }\n});\n\n// dist/adapters/wrappers/node-server.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar http = require(\"http\");\nvar fs2 = require(\"fs\");\nvar path2 = require(\"path\");\nvar image_proxy_1 = require_image_proxy();\nvar MIME_TYPES = {\n \".js\": \"application/javascript\",\n \".mjs\": \"application/javascript\",\n \".css\": \"text/css\",\n \".html\": \"text/html\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".map\": \"application/json\",\n \".txt\": \"text/plain\",\n \".webp\": \"image/webp\"\n};\nfunction parseQuery(url) {\n const idx = url.indexOf(\"?\");\n if (idx === -1)\n return {};\n const params = {};\n const searchParams = new URLSearchParams(url.slice(idx + 1));\n for (const [key, value] of searchParams) {\n const existing = params[key];\n if (existing === void 0) {\n params[key] = value;\n } else if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n params[key] = [existing, value];\n }\n }\n return params;\n}\nfunction parseCookies(cookieHeader) {\n if (!cookieHeader)\n return {};\n const cookies = {};\n for (const pair of cookieHeader.split(\";\")) {\n const eqIdx = pair.indexOf(\"=\");\n if (eqIdx === -1)\n continue;\n const name = pair.slice(0, eqIdx).trim();\n const value = pair.slice(eqIdx + 1).trim();\n if (name)\n cookies[name] = value;\n }\n return cookies;\n}\nfunction flattenHeaders(rawHeaders) {\n const headers = {};\n for (const [key, value] of Object.entries(rawHeaders)) {\n if (value === void 0)\n continue;\n headers[key.toLowerCase()] = Array.isArray(value) ? value.join(\", \") : value;\n }\n return headers;\n}\nasync function readBody(req) {\n if (req.method === \"GET\" || req.method === \"HEAD\")\n return void 0;\n return new Promise((resolve, reject) => {\n const chunks = [];\n req.on(\"data\", (chunk) => chunks.push(chunk));\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n req.on(\"error\", reject);\n });\n}\nfunction serveStaticFile(assetsDir, req, res) {\n var _a, _b;\n const urlPath = (_b = (_a = req.url) === null || _a === void 0 ? void 0 : _a.split(\"?\")[0]) !== null && _b !== void 0 ? _b : \"/\";\n if (urlPath === \"/\" || !urlPath.startsWith(\"/\"))\n return false;\n const filePath = path2.join(assetsDir, urlPath);\n const normalizedPath = path2.normalize(filePath);\n if (!normalizedPath.startsWith(assetsDir)) {\n res.writeHead(403);\n res.end();\n return true;\n }\n let stat;\n try {\n stat = fs2.statSync(normalizedPath);\n } catch (_c) {\n return false;\n }\n if (!stat.isFile())\n return false;\n const ext = path2.extname(normalizedPath);\n const contentType = MIME_TYPES[ext] || \"application/octet-stream\";\n const isHashedAsset = urlPath.startsWith(\"/_next/static/\");\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Content-Length\": stat.size,\n \"Cache-Control\": isHashedAsset ? \"public, max-age=31536000, immutable\" : \"public, max-age=60\"\n });\n fs2.createReadStream(normalizedPath).pipe(res);\n return true;\n}\nfunction bridgeOpenNextHandler(handler) {\n return async (req, res) => {\n var _a, _b, _c, _d, _e, _f;\n try {\n const rawUrl = req.url || \"/\";\n const headers = flattenHeaders(req.headers);\n const body = await readBody(req);\n const host = headers[\"host\"] || `localhost:${(_a = process.env.PORT) !== null && _a !== void 0 ? _a : \"3000\"}`;\n const proto = ((_c = (_b = headers[\"x-forwarded-proto\"]) === null || _b === void 0 ? void 0 : _b.split(\",\")[0]) === null || _c === void 0 ? void 0 : _c.trim()) || \"http\";\n const absoluteUrl = new URL(`${proto}://${host}${rawUrl}`);\n const event = {\n type: \"core\",\n method: req.method || \"GET\",\n rawPath: absoluteUrl.pathname,\n url: absoluteUrl.href,\n body,\n headers,\n query: parseQuery(rawUrl),\n cookies: parseCookies(headers[\"cookie\"]),\n remoteAddress: ((_e = (_d = headers[\"x-forwarded-for\"]) === null || _d === void 0 ? void 0 : _d.split(\",\")[0]) === null || _e === void 0 ? void 0 : _e.trim()) || headers[\"x-real-ip\"] || ((_f = req.socket) === null || _f === void 0 ? void 0 : _f.remoteAddress) || \"127.0.0.1\"\n };\n const abortController = new AbortController();\n res.on(\"close\", () => abortController.abort());\n const streamCreator = {\n writeHeaders(prelude) {\n res.setHeader(\"Set-Cookie\", prelude.cookies);\n res.writeHead(prelude.statusCode, prelude.headers);\n res.flushHeaders();\n return res;\n },\n abortSignal: abortController.signal\n };\n await handler(event, { streamCreator });\n } catch (err) {\n if (!res.headersSent) {\n const isDev = process.env.NODE_ENV !== \"production\";\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: \"Internal Server Error\",\n ...isDev && { message: err.message, stack: err.stack }\n }));\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n };\n}\nasync function wrapper(handler) {\n var _a;\n const port = parseInt((_a = process.env.PORT) !== null && _a !== void 0 ? _a : \"3000\", 10);\n const assetsDir = path2.resolve(process.cwd(), \"..\", \"..\", \"assets\");\n if (!fs2.existsSync(assetsDir)) {\n console.warn(`[pcg-node] assets directory not found at ${assetsDir} \\u2014 static file requests will fall through to Next handler`);\n }\n const dispatchToNext = bridgeOpenNextHandler(handler);\n const server = http.createServer(async (req, res) => {\n var _a2, _b;\n const urlPath = (_b = (_a2 = req.url) === null || _a2 === void 0 ? void 0 : _a2.split(\"?\")[0]) !== null && _b !== void 0 ? _b : \"/\";\n if (urlPath === \"/__health\") {\n res.writeHead(200, { \"Content-Type\": \"text/plain\" });\n res.end(\"OK\");\n return;\n }\n if (urlPath === \"/_next/image\") {\n try {\n await (0, image_proxy_1.handleImageProxy)(req, res);\n } catch (err) {\n console.error(\"[pcg-node] image-proxy error:\", err);\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Image proxy failed\" }));\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n return;\n }\n if (serveStaticFile(assetsDir, req, res))\n return;\n await dispatchToNext(req, res);\n });\n let shuttingDown = false;\n const shutdown = (signal) => {\n if (shuttingDown)\n return;\n shuttingDown = true;\n console.log(`[pcg-node] ${signal} received, shutting down...`);\n server.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 5e3).unref();\n };\n process.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n await new Promise((resolve) => {\n server.listen(port, () => {\n console.log(`[pcg-node] Listening on port ${port}`);\n console.log(`[pcg-node] assets: ${assetsDir}`);\n console.log(`[pcg-node] routes: /__health, /_next/image, /_next/static/*, <next>`);\n resolve();\n });\n });\n}\nvar wrapperDef = {\n wrapper,\n name: \"pcg-node\",\n supportStreaming: true\n};\nexports.default = wrapperDef;\n",
|
|
4
4
|
"adapters/converters/passthrough.js": "\"use strict\";\n\n// dist/adapters/converters/passthrough.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar converter = {\n convertFrom: async (event) => event,\n convertTo: async (result) => result,\n name: \"passthrough\"\n};\nexports.default = converter;\n",
|
|
5
5
|
"overrides/incrementalCache/gateway.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod) => function __require() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\n\n// dist/_protocol/types.js\nvar require_types = __commonJS({\n \"dist/_protocol/types.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n }\n});\n\n// dist/_protocol/keys.js\nvar require_keys = __commonJS({\n \"dist/_protocol/keys.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.buildPageMetadataKey = exports2.buildTagKey = exports2.buildStaticAssetKey = exports2.buildOssKey = void 0;\n function stripLeadingSlash(s) {\n return s.replace(/^\\/+/, \"\");\n }\n function buildOssKey(params) {\n const { appId, buildId, cacheType = \"cache\" } = params;\n const key = stripLeadingSlash(params.key);\n if (cacheType === \"fetch\") {\n return `${appId}/__fetch/${buildId}/${key}`;\n }\n return `${appId}/${buildId}/${key}.cache`;\n }\n exports2.buildOssKey = buildOssKey;\n function buildStaticAssetKey(params) {\n const p = stripLeadingSlash(params.path);\n return `${params.appId}/_next/static/${p}`;\n }\n exports2.buildStaticAssetKey = buildStaticAssetKey;\n function buildTagKey(params) {\n return {\n app_id: params.appId,\n tag: `${params.buildId}/${params.tag}`,\n path: `${params.buildId}/${params.path}`\n };\n }\n exports2.buildTagKey = buildTagKey;\n function buildPageMetadataKey(params) {\n return {\n app_id: params.appId,\n url: params.url\n };\n }\n exports2.buildPageMetadataKey = buildPageMetadataKey;\n }\n});\n\n// dist/_protocol/endpoints.js\nvar require_endpoints = __commonJS({\n \"dist/_protocol/endpoints.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.buildCentralEndpoints = void 0;\n function stripTrailingSlashes(s) {\n return s.replace(/\\/+$/, \"\");\n }\n function buildCentralEndpoints(base) {\n const b = stripTrailingSlashes(base);\n return {\n base: b,\n cache: `${b}/cache`,\n cacheRefresh: `${b}/cache/refresh`,\n revalidateTag: `${b}/revalidate/tag`,\n revalidatePath: `${b}/revalidate/path`,\n tagByTag: `${b}/tag/by-tag`,\n tagByPath: `${b}/tag/by-path`,\n tagLastModified: `${b}/tag/last-modified`,\n tagWrite: `${b}/tag/write`,\n deploySts: `${b}/deploy/sts-token`,\n deployTags: `${b}/deploy/tags`\n };\n }\n exports2.buildCentralEndpoints = buildCentralEndpoints;\n }\n});\n\n// dist/_protocol/index.js\nvar require_protocol = __commonJS({\n \"dist/_protocol/index.js\"(exports2) {\n \"use strict\";\n var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {\n if (k2 === void 0) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() {\n return m[k];\n } };\n }\n Object.defineProperty(o, k2, desc);\n } : function(o, m, k, k2) {\n if (k2 === void 0) k2 = k;\n o[k2] = m[k];\n });\n var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);\n };\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n __exportStar(require_types(), exports2);\n __exportStar(require_keys(), exports2);\n __exportStar(require_endpoints(), exports2);\n }\n});\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/overrides/incrementalCache/gateway.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar protocol_1 = require_protocol();\nvar gateway_auth_1 = require_gateway_auth();\nvar GET_TIMEOUT = 5e3;\nvar SET_TIMEOUT = 1e4;\nvar DELETE_TIMEOUT = 5e3;\nfunction buildKey(config, key, isFetch) {\n return (0, protocol_1.buildOssKey)({\n appId: `${config.aliuid}/${config.routinename}`,\n buildId: config.version,\n key,\n cacheType: isFetch ? \"fetch\" : \"cache\"\n });\n}\nvar GatewayIncrementalCache = class {\n constructor() {\n this.name = \"gateway-incremental-cache\";\n this.config = null;\n this.configLoaded = false;\n }\n /**\n * 延迟加载配置,避免在构造函数中因环境变量缺失而阻塞 Function 启动。\n */\n getConfig() {\n if (!this.configLoaded) {\n this.config = (0, gateway_auth_1.loadGatewayAuthConfig)();\n this.configLoaded = true;\n }\n return this.config;\n }\n /**\n * 从 Gateway 读取缓存。\n */\n async get(key, isFetch) {\n const config = this.getConfig();\n if (!config)\n return null;\n const ossKey = buildKey(config, key, isFetch);\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, `/storage/${ossKey}`, {\n method: \"GET\",\n timeoutMs: GET_TIMEOUT\n });\n if (res.status === 404)\n return null;\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[incrementalCache] GET \\u88AB\\u62D2\\u7EDD: key=\"${ossKey}\" (${res.status})\\uFF0C\\u8BF7\\u68C0\\u67E5\\u7B7E\\u540D secret \\u6216 key \\u524D\\u7F00`);\n } else {\n console.warn(`[incrementalCache] GET \\u5931\\u8D25: key=\"${ossKey}\", \\u72B6\\u6001\\u7801=${res.status}`);\n }\n return null;\n }\n const body = await res.text();\n let envelope;\n try {\n envelope = JSON.parse(body);\n } catch (_a) {\n console.warn(`[incrementalCache] JSON \\u89E3\\u6790\\u5931\\u8D25: key=\"${ossKey}\"`);\n return null;\n }\n if (!envelope || typeof envelope !== \"object\" || typeof envelope.lastModified !== \"number\") {\n console.warn(`[incrementalCache] envelope \\u683C\\u5F0F\\u5F02\\u5E38\\u6216\\u7F3A lastModified: key=\"${ossKey}\"`);\n return null;\n }\n return { value: envelope.value, lastModified: envelope.lastModified };\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[incrementalCache] GET \\u8D85\\u65F6: key=\"${ossKey}\" (${GET_TIMEOUT}ms)`);\n } else {\n console.warn(`[incrementalCache] GET \\u5F02\\u5E38: key=\"${ossKey}\", ${err.message}`);\n }\n return null;\n }\n }\n /**\n * 向 Gateway 写入缓存。\n */\n async set(key, value, isFetch) {\n const config = this.getConfig();\n if (!config)\n return;\n const ossKey = buildKey(config, key, isFetch);\n const body = JSON.stringify({ lastModified: Date.now(), value });\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, `/storage/${ossKey}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n timeoutMs: SET_TIMEOUT\n });\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[incrementalCache] PUT \\u88AB\\u62D2\\u7EDD: key=\"${ossKey}\" (${res.status})\\uFF0C\\u8BF7\\u68C0\\u67E5\\u7B7E\\u540D secret \\u6216 key \\u524D\\u7F00`);\n } else {\n console.warn(`[incrementalCache] PUT \\u5931\\u8D25: key=\"${ossKey}\", \\u72B6\\u6001\\u7801=${res.status}`);\n }\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[incrementalCache] PUT \\u8D85\\u65F6: key=\"${ossKey}\" (${SET_TIMEOUT}ms)`);\n } else {\n console.warn(`[incrementalCache] PUT \\u5F02\\u5E38: key=\"${ossKey}\", ${err.message}`);\n }\n }\n }\n /**\n * 通过 Gateway 删除缓存。\n */\n async delete(key, isFetch) {\n const config = this.getConfig();\n if (!config)\n return;\n const ossKey = buildKey(config, key, isFetch);\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, `/storage/${ossKey}`, {\n method: \"DELETE\",\n timeoutMs: DELETE_TIMEOUT\n });\n if (res.status === 404)\n return;\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[incrementalCache] DELETE \\u88AB\\u62D2\\u7EDD: key=\"${ossKey}\" (${res.status})\\uFF0C\\u8BF7\\u68C0\\u67E5\\u7B7E\\u540D secret \\u6216 key \\u524D\\u7F00`);\n } else {\n console.warn(`[incrementalCache] DELETE \\u5931\\u8D25: key=\"${ossKey}\", \\u72B6\\u6001\\u7801=${res.status}`);\n }\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[incrementalCache] DELETE \\u8D85\\u65F6: key=\"${ossKey}\" (${DELETE_TIMEOUT}ms)`);\n } else {\n console.warn(`[incrementalCache] DELETE \\u5F02\\u5E38: key=\"${ossKey}\", ${err.message}`);\n }\n }\n }\n};\nexports.default = GatewayIncrementalCache;\n",
|
|
6
|
-
"overrides/tagCache/gateway.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod) => function __require() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/overrides/tagCache/gateway.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar gateway_auth_1 = require_gateway_auth();\nvar QUERY_TIMEOUT = 3e3;\nvar WRITE_TIMEOUT = 5e3;\nvar BATCH_SIZE = 200;\nfunction stripLeadingSlash(s) {\n return s.replace(/^\\/+/, \"\");\n}\nvar GatewayTagCache = class {\n constructor() {\n this.name = \"gateway-tag-cache\";\n this.mode = \"nextMode\";\n this.config = null;\n this.configLoaded = false;\n }\n getConfig() {\n if (!this.configLoaded) {\n this.config = (0, gateway_auth_1.loadGatewayAuthConfig)();\n this.configLoaded = true;\n }\n return this.config;\n }\n buildTagKey(tag) {\n const config = this.getConfig();\n if (!config)\n return tag;\n return `${config.version}/${stripLeadingSlash(tag)}`;\n }\n async getLastRevalidated(tags) {\n const config = this.getConfig();\n if (!config)\n return 0;\n try {\n const rows = await this.batchGetTags(config, tags);\n let maxRevalidatedAt = 0;\n for (const row of rows) {\n if (row.revalidatedAt && row.revalidatedAt > maxRevalidatedAt) {\n maxRevalidatedAt = row.revalidatedAt;\n }\n }\n return maxRevalidatedAt;\n } catch (err) {\n console.warn(`[tagCache] getLastRevalidated error: ${err.message}`);\n return 0;\n }\n }\n async hasBeenRevalidated(tags, lastModified) {\n const config = this.getConfig();\n if (!config)\n return false;\n if (tags.length === 0)\n return false;\n try {\n const rows = await this.batchGetTags(config, tags);\n const now = Date.now();\n const lm = lastModified !== null && lastModified !== void 0 ? lastModified : 0;\n for (const row of rows) {\n if (row.expire !== void 0) {\n if (row.expire <= now && row.expire > lm) {\n return true;\n }\n }\n if (row.revalidatedAt !== void 0 && row.revalidatedAt > lm) {\n return true;\n }\n }\n return false;\n } catch (err) {\n console.warn(`[tagCache] hasBeenRevalidated error: ${err.message}`);\n return false;\n }\n }\n async isStale(tags, lastModified) {\n var _a;\n const config = this.getConfig();\n if (!config)\n return false;\n if (tags.length === 0)\n return false;\n try {\n const rows = await this.batchGetTags(config, tags);\n const lm = lastModified !== null && lastModified !== void 0 ? lastModified : 0;\n for (const row of rows) {\n if (row.stale === void 0)\n continue;\n const revalidatedAt = (_a = row.revalidatedAt) !== null && _a !== void 0 ? _a : 0;\n if (revalidatedAt > lm && row.stale >= lm) {\n return true;\n }\n }\n return false;\n } catch (err) {\n console.warn(`[tagCache] isStale error: ${err.message}`);\n return false;\n }\n }\n async writeTags(tags) {\n if (!tags || tags.length === 0)\n return;\n const config = this.getConfig();\n if (!config)\n return;\n const writeTs = Date.now();\n const rows = tags.map((input) => {\n const tagStr = typeof input === \"string\" ? input : input.tag;\n const stale = typeof input === \"string\" ? void 0 : input.stale;\n const expire = typeof input === \"string\" ? void 0 : input.expire;\n const tagKey = this.buildTagKey(tagStr);\n const columns = [\n { name: \"revalidatedAt\", value: writeTs }\n ];\n if (stale !== void 0) {\n columns.push({ name: \"stale\", value: stale });\n }\n if (expire !== void 0) {\n columns.push({ name: \"expire\", value: expire });\n }\n return {\n primaryKey: [\n { name: \"app_id\", value: `${config.aliuid}/${config.routinename}` },\n { name: \"tag\", value: tagKey }\n ],\n columns\n };\n });\n await this.batchWrite(config, rows);\n }\n // ---- private methods ----\n async batchGetTags(config, tags) {\n const primaryKeys = tags.map((tag) => [\n { name: \"app_id\", value: `${config.aliuid}/${config.routinename}` },\n { name: \"tag\", value: this.buildTagKey(tag) }\n ]);\n const res = await (0, gateway_auth_1.gatewayFetch)(config, \"/table/batch-get-row\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ primaryKeys }),\n timeoutMs: QUERY_TIMEOUT\n });\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[tagCache] batch-get-row rejected (${res.status})`);\n } else {\n console.warn(`[tagCache] batch-get-row failed: status=${res.status}`);\n }\n return [];\n }\n const data = await res.json();\n if (!data.rows)\n return [];\n return data.rows.map((row) => {\n var _a;\n const result = {};\n for (const col of (_a = row.columns) !== null && _a !== void 0 ? _a : []) {\n if (col.name === \"revalidatedAt\" && typeof col.value === \"number\") {\n result.revalidatedAt = col.value;\n } else if (col.name === \"stale\" && typeof col.value === \"number\") {\n result.stale = col.value;\n } else if (col.name === \"expire\" && typeof col.value === \"number\") {\n result.expire = col.value;\n }\n }\n return result;\n });\n }\n async batchWrite(config, rows) {\n if (rows.length === 0)\n return;\n for (let i = 0; i < rows.length; i += BATCH_SIZE) {\n const batch = rows.slice(i, i + BATCH_SIZE);\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, \"/table/batch-write\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ rows: batch }),\n timeoutMs: WRITE_TIMEOUT\n });\n if (res.status === 401 || res.status === 403) {\n console.error(`[tagCache] batch-write rejected (${res.status})`);\n return;\n }\n if (!res.ok) {\n console.warn(`[tagCache] batch-write failed: status=${res.status}`);\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[tagCache] batch-write timeout (${WRITE_TIMEOUT}ms)`);\n } else {\n console.warn(`[tagCache] batch-write error: ${err.message}`);\n }\n }\n }\n }\n};\nexports.default = GatewayTagCache;\n",
|
|
6
|
+
"overrides/tagCache/gateway.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod) => function __require() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/runtime/cdn-purge.js\nvar require_cdn_purge = __commonJS({\n \"dist/runtime/cdn-purge.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.createCdnPurgeClient = exports2.loadCdnPurgeConfig = void 0;\n var fs = require(\"fs\");\n var path = require(\"path\");\n var gateway_auth_12 = require_gateway_auth();\n var REFRESH_TIMEOUT_MS = 15e3;\n var URL_BATCH_SIZE = 100;\n var REFRESH_CONCURRENCY = 4;\n var TAG_MANIFEST_FILENAME = \"__pcg_tag_manifest.json\";\n function stripLeadingSlash2(s) {\n return s.replace(/^\\/+/, \"\");\n }\n function ensureLeadingSlash(s) {\n return s.startsWith(\"/\") ? s : `/${s}`;\n }\n function loadCdnPurgeConfig() {\n const base = (0, gateway_auth_12.loadGatewayAuthConfig)();\n if (!base)\n return null;\n const hostname = process.env.ESA_CACHE_GW_HOSTNAME;\n const siteIdRaw = process.env.ESA_CACHE_GW_SITE_ID;\n if (!hostname || !siteIdRaw) {\n return null;\n }\n const siteIdNum = Number(siteIdRaw);\n const siteId = Number.isFinite(siteIdNum) ? siteIdNum : siteIdRaw;\n return {\n ...base,\n hostname,\n siteId\n };\n }\n exports2.loadCdnPurgeConfig = loadCdnPurgeConfig;\n function createCdnPurgeClient(cfg) {\n var _a;\n const buildId = cfg.version;\n const pathPrefix = `${buildId}/`;\n const manifestPath = (_a = cfg.manifestPath) !== null && _a !== void 0 ? _a : path.join(__dirname, TAG_MANIFEST_FILENAME);\n let manifestPromise = null;\n async function loadManifest() {\n if (manifestPromise)\n return manifestPromise;\n manifestPromise = (async () => {\n var _a2, _b, _c, _d;\n const map = /* @__PURE__ */ new Map();\n let raw;\n try {\n raw = await fs.promises.readFile(manifestPath, \"utf-8\");\n } catch (err) {\n if ((err === null || err === void 0 ? void 0 : err.code) !== \"ENOENT\") {\n console.warn(`[cdn-purge] manifest read error ${manifestPath}: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n return /* @__PURE__ */ new Map();\n }\n let rows;\n try {\n const parsed = JSON.parse(raw);\n rows = Array.isArray(parsed) ? parsed : [];\n } catch (err) {\n console.warn(`[cdn-purge] manifest parse error ${manifestPath}: ${(_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : err}`);\n return /* @__PURE__ */ new Map();\n }\n for (const row of rows) {\n const tagPk = (_c = row === null || row === void 0 ? void 0 : row.tag) === null || _c === void 0 ? void 0 : _c.S;\n const pathPk = (_d = row === null || row === void 0 ? void 0 : row.path) === null || _d === void 0 ? void 0 : _d.S;\n if (typeof tagPk !== \"string\" || typeof pathPk !== \"string\")\n continue;\n if (!tagPk.startsWith(pathPrefix))\n continue;\n if (!pathPk.startsWith(pathPrefix))\n continue;\n const tag = tagPk.slice(pathPrefix.length);\n const p = pathPk.slice(pathPrefix.length);\n if (!tag || !p)\n continue;\n let bucket = map.get(tag);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n map.set(tag, bucket);\n }\n bucket.add(p);\n }\n const result = /* @__PURE__ */ new Map();\n for (const [tag, set] of map) {\n result.set(tag, Array.from(set));\n }\n return result;\n })();\n return manifestPromise;\n }\n function expandPathsToUrls(paths) {\n const normalized = /* @__PURE__ */ new Set();\n for (const p of paths) {\n if (!p)\n continue;\n normalized.add(ensureLeadingSlash(p));\n }\n if (normalized.size === 0)\n return [];\n const urls = /* @__PURE__ */ new Set();\n for (const p of normalized) {\n urls.add(`https://${cfg.hostname}${p}`);\n const rel = stripLeadingSlash2(p);\n urls.add(`https://${cfg.hostname}/_next/data/${buildId}/${rel || \"index\"}.json`);\n }\n return Array.from(urls);\n }\n async function refreshBatch(urls) {\n var _a2;\n const body = {\n hostname: cfg.hostname,\n siteId: cfg.siteId,\n urls\n };\n let res;\n try {\n res = await (0, gateway_auth_12.gatewayFetch)(cfg, \"/cache/refresh\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n timeoutMs: REFRESH_TIMEOUT_MS\n });\n } catch (err) {\n console.warn(`[cdn-purge] cache/refresh error (${urls.length} urls): ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n return;\n }\n if (!res.ok) {\n let detail = \"\";\n try {\n detail = (await res.text()).slice(0, 200);\n } catch (_b) {\n }\n console.warn(`[cdn-purge] cache/refresh failed status=${res.status} urls=${urls.length} ${detail}`);\n }\n }\n async function refreshUrls(allUrls) {\n if (allUrls.length === 0)\n return;\n const batches = [];\n for (let i = 0; i < allUrls.length; i += URL_BATCH_SIZE) {\n batches.push(allUrls.slice(i, i + URL_BATCH_SIZE));\n }\n let cursor = 0;\n async function worker() {\n while (cursor < batches.length) {\n const idx = cursor++;\n await refreshBatch(batches[idx]);\n }\n }\n const workers = Array.from({ length: Math.min(REFRESH_CONCURRENCY, batches.length) }, () => worker());\n await Promise.all(workers);\n }\n async function purgeByPaths(paths) {\n var _a2;\n try {\n const urls = expandPathsToUrls(paths);\n await refreshUrls(urls);\n } catch (err) {\n console.warn(`[cdn-purge] purgeByPaths error: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n }\n async function purgeByTags(tags) {\n var _a2;\n try {\n const uniqueTags = Array.from(new Set(tags.map((t) => typeof t === \"string\" ? t : \"\").map((t) => t.trim()).filter(Boolean)));\n if (uniqueTags.length === 0)\n return;\n const map = await loadManifest();\n const merged = /* @__PURE__ */ new Set();\n for (const t of uniqueTags) {\n const paths = map.get(t);\n if (!paths)\n continue;\n for (const p of paths)\n merged.add(p);\n }\n if (merged.size === 0)\n return;\n const urls = expandPathsToUrls(Array.from(merged));\n await refreshUrls(urls);\n } catch (err) {\n console.warn(`[cdn-purge] purgeByTags error: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n }\n return { purgeByPaths, purgeByTags };\n }\n exports2.createCdnPurgeClient = createCdnPurgeClient;\n }\n});\n\n// dist/overrides/tagCache/gateway.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar gateway_auth_1 = require_gateway_auth();\nvar cdn_purge_1 = require_cdn_purge();\nvar QUERY_TIMEOUT = 3e3;\nvar WRITE_TIMEOUT = 5e3;\nvar BATCH_SIZE = 200;\nfunction stripLeadingSlash(s) {\n return s.replace(/^\\/+/, \"\");\n}\nvar GatewayTagCache = class {\n constructor() {\n this.name = \"gateway-tag-cache\";\n this.mode = \"nextMode\";\n this.config = null;\n this.configLoaded = false;\n this.purgeClient = null;\n this.purgeClientLoaded = false;\n }\n getConfig() {\n if (!this.configLoaded) {\n this.config = (0, gateway_auth_1.loadGatewayAuthConfig)();\n this.configLoaded = true;\n }\n return this.config;\n }\n getPurgeClient() {\n if (!this.purgeClientLoaded) {\n const cfg = (0, cdn_purge_1.loadCdnPurgeConfig)();\n this.purgeClient = cfg ? (0, cdn_purge_1.createCdnPurgeClient)(cfg) : null;\n this.purgeClientLoaded = true;\n }\n return this.purgeClient;\n }\n buildTagKey(tag) {\n const config = this.getConfig();\n if (!config)\n return tag;\n return `${config.version}/${stripLeadingSlash(tag)}`;\n }\n async getLastRevalidated(tags) {\n const config = this.getConfig();\n if (!config)\n return 0;\n try {\n const rows = await this.batchGetTags(config, tags);\n let maxRevalidatedAt = 0;\n for (const row of rows) {\n if (row.revalidatedAt && row.revalidatedAt > maxRevalidatedAt) {\n maxRevalidatedAt = row.revalidatedAt;\n }\n }\n return maxRevalidatedAt;\n } catch (err) {\n console.warn(`[tagCache] getLastRevalidated error: ${err.message}`);\n return 0;\n }\n }\n async hasBeenRevalidated(tags, lastModified) {\n const config = this.getConfig();\n if (!config)\n return false;\n if (tags.length === 0)\n return false;\n try {\n const rows = await this.batchGetTags(config, tags);\n const now = Date.now();\n const lm = lastModified !== null && lastModified !== void 0 ? lastModified : 0;\n for (const row of rows) {\n if (row.expire !== void 0) {\n if (row.expire <= now && row.expire > lm) {\n return true;\n }\n }\n if (row.revalidatedAt !== void 0 && row.revalidatedAt > lm) {\n return true;\n }\n }\n return false;\n } catch (err) {\n console.warn(`[tagCache] hasBeenRevalidated error: ${err.message}`);\n return false;\n }\n }\n async isStale(tags, lastModified) {\n var _a;\n const config = this.getConfig();\n if (!config)\n return false;\n if (tags.length === 0)\n return false;\n try {\n const rows = await this.batchGetTags(config, tags);\n const lm = lastModified !== null && lastModified !== void 0 ? lastModified : 0;\n for (const row of rows) {\n if (row.stale === void 0)\n continue;\n const revalidatedAt = (_a = row.revalidatedAt) !== null && _a !== void 0 ? _a : 0;\n if (revalidatedAt > lm && row.stale >= lm) {\n return true;\n }\n }\n return false;\n } catch (err) {\n console.warn(`[tagCache] isStale error: ${err.message}`);\n return false;\n }\n }\n async writeTags(tags) {\n if (!tags || tags.length === 0)\n return;\n const config = this.getConfig();\n if (!config)\n return;\n const writeTs = Date.now();\n const rows = tags.map((input) => {\n const tagStr = typeof input === \"string\" ? input : input.tag;\n const stale = typeof input === \"string\" ? void 0 : input.stale;\n const expire = typeof input === \"string\" ? void 0 : input.expire;\n const tagKey = this.buildTagKey(tagStr);\n const columns = [\n { name: \"revalidatedAt\", value: writeTs }\n ];\n if (stale !== void 0) {\n columns.push({ name: \"stale\", value: stale });\n }\n if (expire !== void 0) {\n columns.push({ name: \"expire\", value: expire });\n }\n return {\n primaryKey: [\n { name: \"app_id\", value: `${config.aliuid}/${config.routinename}` },\n { name: \"tag\", value: tagKey }\n ],\n columns\n };\n });\n await this.batchWrite(config, rows);\n const purgeClient = this.getPurgeClient();\n if (purgeClient) {\n const tagStrs = tags.map((t) => typeof t === \"string\" ? t : t.tag).filter((s) => typeof s === \"string\" && s.length > 0);\n if (tagStrs.length > 0) {\n purgeClient.purgeByTags(tagStrs).catch((err) => {\n var _a;\n console.warn(`[tagCache] purge fan-out failed: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);\n });\n }\n }\n }\n // ---- private methods ----\n async batchGetTags(config, tags) {\n const primaryKeys = tags.map((tag) => [\n { name: \"app_id\", value: `${config.aliuid}/${config.routinename}` },\n { name: \"tag\", value: this.buildTagKey(tag) }\n ]);\n const res = await (0, gateway_auth_1.gatewayFetch)(config, \"/table/batch-get-row\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ primaryKeys }),\n timeoutMs: QUERY_TIMEOUT\n });\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[tagCache] batch-get-row rejected (${res.status})`);\n } else {\n console.warn(`[tagCache] batch-get-row failed: status=${res.status}`);\n }\n return [];\n }\n const data = await res.json();\n if (!data.rows)\n return [];\n return data.rows.map((row) => {\n var _a;\n const result = {};\n for (const col of (_a = row.columns) !== null && _a !== void 0 ? _a : []) {\n if (col.name === \"revalidatedAt\" && typeof col.value === \"number\") {\n result.revalidatedAt = col.value;\n } else if (col.name === \"stale\" && typeof col.value === \"number\") {\n result.stale = col.value;\n } else if (col.name === \"expire\" && typeof col.value === \"number\") {\n result.expire = col.value;\n }\n }\n return result;\n });\n }\n async batchWrite(config, rows) {\n if (rows.length === 0)\n return;\n for (let i = 0; i < rows.length; i += BATCH_SIZE) {\n const batch = rows.slice(i, i + BATCH_SIZE);\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, \"/table/batch-write\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ rows: batch }),\n timeoutMs: WRITE_TIMEOUT\n });\n if (res.status === 401 || res.status === 403) {\n console.error(`[tagCache] batch-write rejected (${res.status})`);\n return;\n }\n if (!res.ok) {\n console.warn(`[tagCache] batch-write failed: status=${res.status}`);\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[tagCache] batch-write timeout (${WRITE_TIMEOUT}ms)`);\n } else {\n console.warn(`[tagCache] batch-write error: ${err.message}`);\n }\n }\n }\n }\n};\nexports.default = GatewayTagCache;\n",
|
|
7
7
|
};
|
package/dist/_protocol/types.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIENhY2hlTW9kZSA9ICdsb2NhbCcgfCAnY2VudHJhbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSldUUGF5bG9hZCB7XG4gIHVpZDogc3RyaW5nO1xuICBhcHA6IHN0cmluZztcbiAgYnVpbGRJZDogc3RyaW5nO1xuICBpYXQ/OiBudW1iZXI7XG4gIGV4cD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5hbnRDb250ZXh0IHtcbiAgdWlkOiBzdHJpbmc7XG4gIGFwcDogc3RyaW5nO1xuICBidWlsZElkOiBzdHJpbmc7XG4gIC8qKiBgJHt1aWR9LyR7YXBwfWAgKi9cbiAgYXBwSWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTVFNUb2tlblJlc3BvbnNlIHtcbiAgYWNjZXNzS2V5SWQ6IHN0cmluZztcbiAgYWNjZXNzS2V5U2VjcmV0OiBzdHJpbmc7XG4gIHNlY3VyaXR5VG9rZW46IHN0cmluZztcbiAgZXhwaXJhdGlvbjogc3RyaW5nO1xuICBidWNrZXQ6IHN0cmluZztcbiAgLyoqIFwie3VpZH0ve2FwcH0vXCIgKi9cbiAgcHJlZml4OiBzdHJpbmc7XG4gIHJlZ2lvbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlU3RvcmVQcmltYXJ5S2V5IHtcbiAgbmFtZTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlU3RvcmVDb2x1bW4ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBCdWZmZXI7XG4gIHRpbWVzdGFtcD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYWJsZVN0b3JlUm93IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgY29sdW1ucz86IFRhYmxlU3RvcmVDb2x1bW5bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHZXRSb3dSZXF1ZXN0IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQdXRSb3dSZXF1ZXN0IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgY29sdW1uczogVGFibGVTdG9yZUNvbHVtbltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlbGV0ZVJvd1JlcXVlc3Qge1xuICBwcmltYXJ5S2V5OiBUYWJsZVN0b3JlUHJpbWFyeUtleVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdldFJhbmdlUmVxdWVzdCB7XG4gIHN0YXJ0UHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgZW5kUHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgbGltaXQ/
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIENhY2hlTW9kZSA9ICdsb2NhbCcgfCAnY2VudHJhbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSldUUGF5bG9hZCB7XG4gIHVpZDogc3RyaW5nO1xuICBhcHA6IHN0cmluZztcbiAgYnVpbGRJZDogc3RyaW5nO1xuICBpYXQ/OiBudW1iZXI7XG4gIGV4cD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5hbnRDb250ZXh0IHtcbiAgdWlkOiBzdHJpbmc7XG4gIGFwcDogc3RyaW5nO1xuICBidWlsZElkOiBzdHJpbmc7XG4gIC8qKiBgJHt1aWR9LyR7YXBwfWAgKi9cbiAgYXBwSWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTVFNUb2tlblJlc3BvbnNlIHtcbiAgYWNjZXNzS2V5SWQ6IHN0cmluZztcbiAgYWNjZXNzS2V5U2VjcmV0OiBzdHJpbmc7XG4gIHNlY3VyaXR5VG9rZW46IHN0cmluZztcbiAgZXhwaXJhdGlvbjogc3RyaW5nO1xuICBidWNrZXQ6IHN0cmluZztcbiAgLyoqIFwie3VpZH0ve2FwcH0vXCIgKi9cbiAgcHJlZml4OiBzdHJpbmc7XG4gIHJlZ2lvbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlU3RvcmVQcmltYXJ5S2V5IHtcbiAgbmFtZTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlU3RvcmVDb2x1bW4ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBCdWZmZXI7XG4gIHRpbWVzdGFtcD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYWJsZVN0b3JlUm93IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgY29sdW1ucz86IFRhYmxlU3RvcmVDb2x1bW5bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHZXRSb3dSZXF1ZXN0IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQdXRSb3dSZXF1ZXN0IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgY29sdW1uczogVGFibGVTdG9yZUNvbHVtbltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlbGV0ZVJvd1JlcXVlc3Qge1xuICBwcmltYXJ5S2V5OiBUYWJsZVN0b3JlUHJpbWFyeUtleVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdldFJhbmdlUmVxdWVzdCB7XG4gIHN0YXJ0UHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgZW5kUHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgbGltaXQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2V0UmFuZ2VSZXNwb25zZSB7XG4gIHJvd3M6IFRhYmxlU3RvcmVSb3dbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYXRjaFdyaXRlUmVxdWVzdCB7XG4gIHJvd3M6IFB1dFJvd1JlcXVlc3RbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYWNoZVJlZnJlc2hSZXF1ZXN0IHtcbiAgaG9zdG5hbWU6IHN0cmluZztcbiAgc2l0ZUlkOiBzdHJpbmcgfCBudW1iZXI7XG4gIHVybHM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhY2hlUmVmcmVzaFJlc3BvbnNlIHtcbiAgc3VjY2VzczogYm9vbGVhbjtcbiAgaG9zdG5hbWU6IHN0cmluZztcbiAgc2l0ZUlkPzogc3RyaW5nIHwgbnVtYmVyO1xuICB0YXNrSWQ/OiBzdHJpbmc7XG4gIHB1cmdlZFVybENvdW50OiBudW1iZXI7XG4gIGJhY2tlbmQ6ICdpbm5lci1hcGknIHwgJ2ludGVybmFsLWFwaSc7XG4gIGFwaVJlcXVlc3RJZD86IHN0cmluZztcbiAgbm90ZT86IHN0cmluZztcbn1cbiJdfQ==
|
package/dist/commands/build.js
CHANGED
|
@@ -41,6 +41,29 @@ function isNextMajorUnsupported(major) {
|
|
|
41
41
|
// Relative form needed because absolute __dirname paths break when the CLI is
|
|
42
42
|
// ncc-bundled into a single file (subdirectory tree no longer exists).
|
|
43
43
|
const PCG_OVERRIDES_REL = '.pcg/overrides';
|
|
44
|
+
// Filename for the tag→path manifest embedded into the FC bundle. Read at
|
|
45
|
+
// FC cold start by runtime/cdn-purge to map revalidateTag → CDN purge URLs
|
|
46
|
+
// without a server round trip. Resolved via __dirname inside cache.cjs.
|
|
47
|
+
const TAG_MANIFEST_FILENAME = '__pcg_tag_manifest.json';
|
|
48
|
+
async function embedTagManifest(openNextDir) {
|
|
49
|
+
var _a;
|
|
50
|
+
const src = path.join(openNextDir, 'dynamodb-provider', 'dynamodb-cache.json');
|
|
51
|
+
const dst = path.join(openNextDir, 'server-functions', 'default', TAG_MANIFEST_FILENAME);
|
|
52
|
+
try {
|
|
53
|
+
await fs.access(src);
|
|
54
|
+
}
|
|
55
|
+
catch (_b) {
|
|
56
|
+
console.warn(`[build] dynamodb-provider/dynamodb-cache.json not found — auto CDN purge will have an empty tag map`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
await fs.copyFile(src, dst);
|
|
61
|
+
console.log(`[build] Embedded tag manifest → ${TAG_MANIFEST_FILENAME}`);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
console.warn(`[build] Failed to embed tag manifest: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
44
67
|
async function materializeOverrides(projectDir) {
|
|
45
68
|
// Lazy require — keeps the inline-overrides bundle out of the import graph
|
|
46
69
|
// for code paths that don't auto-generate the config.
|
|
@@ -141,6 +164,7 @@ async function runBuild(opts) {
|
|
|
141
164
|
finally {
|
|
142
165
|
process.chdir(prevCwd);
|
|
143
166
|
}
|
|
167
|
+
await embedTagManifest(openNextDir);
|
|
144
168
|
console.log('[build] Build complete!');
|
|
145
169
|
}
|
|
146
170
|
finally {
|
|
@@ -180,4 +204,4 @@ function createBuildCommand() {
|
|
|
180
204
|
});
|
|
181
205
|
}
|
|
182
206
|
exports.createBuildCommand = createBuildCommand;
|
|
183
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvYnVpbGQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQTZCO0FBQzdCLGtDQUFrQztBQUNsQyx5Q0FBb0M7QUFDcEMsbUNBQXVDO0FBQ3ZDLGlGQUEyRTtBQUUzRSx5RUFBeUU7QUFDekUsaUZBQWlGO0FBQ2pGLDJEQUEyRDtBQUMzRCxNQUFNLGtCQUFrQixHQUEyQjtJQUNqRCxFQUFFLEVBQUUsWUFBWTtJQUNoQixFQUFFLEVBQUUsWUFBWTtJQUNoQixFQUFFLEVBQUUsWUFBWTtJQUNoQixFQUFFLEVBQUUsWUFBWTtJQUNoQixFQUFFLEVBQUUsWUFBWTtDQUNqQixDQUFDO0FBQ0YsTUFBTSx5QkFBeUIsR0FBRyxDQUFDLENBQUM7QUFFcEMsS0FBSyxVQUFVLGVBQWUsQ0FBQyxVQUFrQjtJQUMvQyxJQUFJO1FBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FDdkIsVUFBVSxFQUNWLGNBQWMsRUFDZCxNQUFNLEVBQ04sY0FBYyxDQUNmLENBQUM7UUFDRixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUM1RCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDOUQsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztLQUMzQztJQUFDLFdBQU07UUFDTixPQUFPLElBQUksQ0FBQztLQUNiO0FBQ0gsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQUMsS0FBYTtJ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T0FBTyxFQUFDLEVBQUU7UUFDdEIsTUFBTSxRQUFRLENBQUM7WUFDYixHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUc7WUFDaEIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3RCLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztZQUNwQixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07WUFDdEIsb0JBQW9CLEVBQUUsT0FBTyxDQUFDLG9CQUFvQjtTQUNuRCxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFqQkQsZ0RBaUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IHsgZGlyRXhpc3RzIH0gZnJvbSAnLi4vdXRpbC9mcyc7XG5pbXBvcnQgeyBnZW5lcmF0ZURlZmF1bHRDb25maWcgfSBmcm9tICcuLi9jb25maWcvZGVmYXVsdC1vcGVuLW5leHQtY29uZmlnJztcblxuLy8gTWlycm9yIG9mIE9wZW5OZXh0J3MgTkVYVF9SRUxFQVNFX0RBVEVTIChoZWxwZXIuanMpLiBVc2VkIHRvIGF1dG8tcGFzc1xuLy8gLS1mb3JjZS11bnN1cHBvcnRlZC1uZXh0IHdoZW4gdGhlIHVzZXIncyBOZXh0IG1ham9yIGlzIHBhc3QgaXRzIDIteWVhciB3aW5kb3csXG4vLyBzbyBwaXBlbGluZSBidWlsZHMgZG9uJ3QgZmFpbCBvbiBPcGVuTmV4dCdzIHBvbGljeSBnYXRlLlxuY29uc3QgTkVYVF9SRUxFQVNFX0RBVEVTOiBSZWNvcmQ8bnVtYmVyLCBzdHJpbmc+ID0ge1xuICAxNjogJzIwMjUtMTAtMjEnLFxuICAxNTogJzIwMjQtMTAtMjEnLFxuICAxNDogJzIwMjMtMTAtMjYnLFxuICAxMzogJzIwMjItMTAtMjYnLFxuICAxMjogJzIwMjEtMTAtMjYnLFxufTtcbmNvbnN0IE5FWFRfU1VQUE9SVF9XSU5ET1dfWUVBUlMgPSAyO1xuXG5hc3luYyBmdW5jdGlvbiBkZXRlY3ROZXh0TWFqb3IocHJvamVjdERpcjogc3RyaW5nKTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcGtnUGF0aCA9IHBhdGguam9pbihcbiAgICAgIHByb2plY3REaXIsXG4gICAgICAnbm9kZV9tb2R1bGVzJyxcbiAgICAgICduZXh0JyxcbiAgICAgICdwYWNrYWdlLmpzb24nXG4gICAgKTtcbiAgICBjb25zdCBwa2cgPSBKU09OLnBhcnNlKGF3YWl0IGZzLnJlYWRGaWxlKHBrZ1BhdGgsICd1dGYtOCcpKTtcbiAgICBjb25zdCBtYWpvciA9IHBhcnNlSW50KFN0cmluZyhwa2cudmVyc2lvbikuc3BsaXQoJy4nKVswXSwgMTApO1xuICAgIHJldHVybiBOdW1iZXIuaXNOYU4obWFqb3IpID8gbnVsbCA6IG1ham9yO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc05leHRNYWpvclVuc3VwcG9ydGVkKG1ham9yOiBudW1iZXIpOiBib29sZWFuIHtcbiAgY29uc3QgcmVsZWFzZURhdGUgPSBORVhUX1JFTEVBU0VfREFURVNbbWFqb3JdO1xuICBpZiAoIXJlbGVhc2VEYXRlKSByZXR1cm4gbWFqb3IgPCAxMjtcbiAgY29uc3QgZW9sID0gbmV3IERhdGUocmVsZWFzZURhdGUpO1xuICBlb2wuc2V0RnVsbFllYXIoZW9sLmdldEZ1bGxZZWFyKCkgKyBORVhUX1NVUFBPUlRfV0lORE9XX1lFQVJTKTtcbiAgcmV0dXJuIERhdGUubm93KCkgPiBlb2wuZ2V0VGltZSgpO1xufVxuXG4vLyBQYXRoIGluc2lkZSA8cHJvamVjdERpcj4gd2hlcmUgd2UgbWF0ZXJpYWxpemUgb3ZlcnJpZGUgYnVuZGxlcyBzbyB0aGVcbi8vIGF1dG8tZ2VuZXJhdGVkIG9wZW4tbmV4dC5jb25maWcgY2FuIHJlZmVyZW5jZSB0aGVtIHZpYSBhIHJlbGF0aXZlIHBhdGguXG4vLyBSZWxhdGl2ZSBmb3JtIG5lZWRlZCBiZWNhdXNlIGFic29sdXRlIF9fZGlybmFtZSBwYXRocyBicmVhayB3aGVuIHRoZSBDTEkgaXNcbi8vIG5jYy1idW5kbGVkIGludG8gYSBzaW5nbGUgZmlsZSAoc3ViZGlyZWN0b3J5IHRyZWUgbm8gbG9uZ2VyIGV4aXN0cykuXG5jb25zdCBQQ0dfT1ZFUlJJREVTX1JFTCA9ICcucGNnL292ZXJyaWRlcyc7XG5cbmFzeW5jIGZ1bmN0aW9uIG1hdGVyaWFsaXplT3ZlcnJpZGVzKHByb2plY3REaXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAvLyBMYXp5IHJlcXVpcmUg4oCUIGtlZXBzIHRoZSBpbmxpbmUtb3ZlcnJpZGVzIGJ1bmRsZSBvdXQgb2YgdGhlIGltcG9ydCBncmFwaFxuICAvLyBmb3IgY29kZSBwYXRocyB0aGF0IGRvbid0IGF1dG8tZ2VuZXJhdGUgdGhlIGNvbmZpZy5cbiAgbGV0IElOTElORV9PVkVSUklERVM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIHRyeSB7XG4gICAgKHsgSU5MSU5FX09WRVJSSURFUyB9ID0gcmVxdWlyZSgnLi4vX2lubGluZS1vdmVycmlkZXMnKSk7XG4gIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgaWYgKGVyciAmJiBlcnIuY29kZSA9PT0gJ01PRFVMRV9OT1RfRk9VTkQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdbYnVpbGRdIGRpc3QvX2lubGluZS1vdmVycmlkZXMuanMgbWlzc2luZyBmcm9tIGVzYS1wY2ctY2xpLiAnICtcbiAgICAgICAgICAnVGhlIHB1Ymxpc2hlZCBwYWNrYWdlIHdhcyBidWlsdCB3aXRob3V0IHNjcmlwdHMvYnVuZGxlLW92ZXJyaWRlcy5qcy4gJyArXG4gICAgICAgICAgJ1JlaW5zdGFsbCBhIG5ld2VyIGVzYS1wY2ctY2xpIChidWlsdCB3aXRoIHRoZSBmdWxsIGBwbnBtIGJ1aWxkYCBwaXBlbGluZSkuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG4gIGNvbnN0IG92ZXJyaWRlc1Jvb3QgPSBwYXRoLmpvaW4ocHJvamVjdERpciwgUENHX09WRVJSSURFU19SRUwpO1xuICBmb3IgKGNvbnN0IFtyZWxQYXRoLCBzb3VyY2VdIG9mIE9iamVjdC5lbnRyaWVzKElOTElORV9PVkVSUklERVMpIGFzIFtcbiAgICBzdHJpbmcsXG4gICAgc3RyaW5nLFxuICBdW10pIHtcbiAgICBjb25zdCB0YXJnZXQgPSBwYXRoLmpvaW4ob3ZlcnJpZGVzUm9vdCwgcmVsUGF0aCk7XG4gICAgYXdhaXQgZnMubWtkaXIocGF0aC5kaXJuYW1lKHRhcmdldCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZSh0YXJnZXQsIHNvdXJjZSk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gY2xlYW51cE92ZXJyaWRlcyhwcm9qZWN0RGlyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qgb3ZlcnJpZGVzUm9vdCA9IHBhdGguam9pbihwcm9qZWN0RGlyLCBQQ0dfT1ZFUlJJREVTX1JFTCk7XG4gIGF3YWl0IGZzLnJtKG92ZXJyaWRlc1Jvb3QsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgLy8gQWxzbyB0cnkgdG8gcmVtb3ZlIHRoZSAucGNnIHBhcmVudCBpZiBpdCdzIGVtcHR5OyBpZ25vcmUgaWYgbm90LlxuICBhd2FpdCBmcy5ybWRpcihwYXRoLmpvaW4ocHJvamVjdERpciwgJy5wY2cnKSkuY2F0Y2goKCkgPT4ge30pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkT3B0aW9ucyB7XG4gIGRpcjogc3RyaW5nO1xuICBjb25maWc/OiBzdHJpbmc7XG4gIGRlYnVnPzogYm9vbGVhbjtcbiAgZHJ5UnVuPzogYm9vbGVhbjtcbiAgZm9yY2VVbnN1cHBvcnRlZE5leHQ/OiBib29sZWFuO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQnVpbGQob3B0czogQnVpbGRPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3REaXIgPSBwYXRoLnJlc29sdmUob3B0cy5kaXIpO1xuXG4gIGNvbnN0IHBrZ0pzb25QYXRoID0gcGF0aC5qb2luKHByb2plY3REaXIsICdwYWNrYWdlLmpzb24nKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmcy5hY2Nlc3MocGtnSnNvblBhdGgpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTmV4dC5qcyBwcm9qZWN0IG5vdCBmb3VuZCBhdCAke3Byb2plY3REaXJ9IChubyBwYWNrYWdlLmpzb24pYFxuICAgICk7XG4gIH1cblxuICBjb25zdCBvcGVuTmV4dERpciA9IHBhdGguam9pbihwcm9qZWN0RGlyLCAnLm9wZW4tbmV4dCcpO1xuXG4gIGxldCBjb25maWdQYXRoID0gb3B0cy5jb25maWc7XG4gIGxldCB0ZW1wQ29uZmlnID0gZmFsc2U7XG5cbiAgaWYgKCFjb25maWdQYXRoKSB7XG4gICAgY29uc3QgY2FuZGlkYXRlcyA9IFsnb3Blbi1uZXh0LmNvbmZpZy50cycsICdvcGVuLW5leHQuY29uZmlnLmpzJ107XG4gICAgZm9yIChjb25zdCBjIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgIGNvbnN0IHAgPSBwYXRoLmpvaW4ocHJvamVjdERpciwgYyk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBmcy5hY2Nlc3MocCk7XG4gICAgICAgIGNvbmZpZ1BhdGggPSBwO1xuICAgICAgICBicmVhaztcbiAgICAgIH0gY2F0Y2gge31cbiAgICB9XG4gIH1cblxuICBpZiAoIWNvbmZpZ1BhdGgpIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgICdbYnVpbGRdIE5vIG9wZW4tbmV4dC5jb25maWcgZm91bmQsIGdlbmVyYXRpbmcgZGVmYXVsdCBjb25maWcuLi4nXG4gICAgKTtcbiAgICBjb25maWdQYXRoID0gcGF0aC5qb2luKHByb2plY3REaXIsICdvcGVuLW5leHQuY29uZmlnLnRzJyk7XG4gICAgYXdhaXQgbWF0ZXJpYWxpemVPdmVycmlkZXMocHJvamVjdERpcik7XG4gICAgY29uc3QgY29uZmlnQ29udGVudCA9IGdlbmVyYXRlRGVmYXVsdENvbmZpZyh7XG4gICAgICBvdmVycmlkZXNEaXI6IGAuLyR7UENHX09WRVJSSURFU19SRUx9YCxcbiAgICB9KTtcbiAgICBhd2FpdCBmcy53cml0ZUZpbGUoY29uZmlnUGF0aCwgY29uZmlnQ29udGVudCk7XG4gICAgdGVtcENvbmZpZyA9IHRydWU7XG4gIH1cblxuICBpZiAob3B0cy5kcnlSdW4pIHtcbiAgICBjb25zb2xlLmxvZygnW2J1aWxkXSBEcnkgcnVuIG1vZGUg4oCUIGJ1aWxkIHBsYW46Jyk7XG4gICAgY29uc29sZS5sb2coYCAgUHJvamVjdCBkaXI6ICR7cHJvamVjdERpcn1gKTtcbiAgICBjb25zb2xlLmxvZyhgICBDb25maWc6ICR7Y29uZmlnUGF0aH1gKTtcbiAgICBjb25zb2xlLmxvZyhgICBPdXRwdXQ6ICR7b3Blbk5leHREaXJ9YCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBpZiAoYXdhaXQgZGlyRXhpc3RzKG9wZW5OZXh0RGlyKSkge1xuICAgICAgY29uc29sZS5sb2coJ1tidWlsZF0gQ2xlYW5pbmcgb2xkIC5vcGVuLW5leHQvIGRpcmVjdG9yeS4uLicpO1xuICAgICAgYXdhaXQgZnMucm0ob3Blbk5leHREaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAob3B0cy5kZWJ1Zykge1xuICAgICAgcHJvY2Vzcy5lbnYuT1BFTl9ORVhUX0RFQlVHID0gJ3RydWUnO1xuICAgIH1cblxuICAgIGxldCBmb3JjZVVuc3VwcG9ydGVkID0gb3B0cy5mb3JjZVVuc3VwcG9ydGVkTmV4dCA9PT0gdHJ1ZTtcbiAgICBpZiAoIWZvcmNlVW5zdXBwb3J0ZWQgJiYgcHJvY2Vzcy5lbnYuUENHX1NUUklDVF9ORVhUX1NVUFBPUlQgIT09ICcxJykge1xuICAgICAgY29uc3QgbmV4dE1ham9yID0gYXdhaXQgZGV0ZWN0TmV4dE1ham9yKHByb2plY3REaXIpO1xuICAgICAgaWYgKG5leHRNYWpvciAhPT0gbnVsbCAmJiBpc05leHRNYWpvclVuc3VwcG9ydGVkKG5leHRNYWpvcikpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBbYnVpbGRdIE5leHQgJHtuZXh0TWFqb3J9LnggaXMgcGFzdCBPcGVuTmV4dCdzICR7TkVYVF9TVVBQT1JUX1dJTkRPV19ZRUFSU30teWVhciBzdXBwb3J0IHdpbmRvdyDigJQgYCArXG4gICAgICAgICAgICAnYXV0by1lbmFibGluZyAtLWZvcmNlLXVuc3VwcG9ydGVkLW5leHQuICcgK1xuICAgICAgICAgICAgJ1NldCBQQ0dfU1RSSUNUX05FWFRfU1VQUE9SVD0xIHRvIGRpc2FibGUgdGhpcyBiZWhhdmlvci4nXG4gICAgICAgICk7XG4gICAgICAgIGZvcmNlVW5zdXBwb3J0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKCdbYnVpbGRdIFJ1bm5pbmcgT3Blbk5leHQgYnVpbGQuLi4nKTtcbiAgICBjb25zdCBwcmV2Q3dkID0gcHJvY2Vzcy5jd2QoKTtcbiAgICB0cnkge1xuICAgICAgcHJvY2Vzcy5jaGRpcihwcm9qZWN0RGlyKTtcbiAgICAgIC8vIE9wZW5OZXh0IHJlc29sdmVzIGBuZXh0YCB2aWEgcHJvY2Vzcy5jd2QoKSAvIHsgcGF0aHM6IFthcHBQYXRoXSB9LFxuICAgICAgLy8gc28gbG9hZGluZyBpdCBmcm9tIHRoZSBDTEkncyBvd24gbm9kZV9tb2R1bGVzIHN0aWxsIGZpbmRzIHRoZSB1c2VyJ3MgTmV4dC5cbiAgICAgIGNvbnN0IG9wZW5OZXh0QnVpbGQgPSByZXF1aXJlKCdAb3Blbm5leHRqcy9hd3MvYnVpbGQuanMnKTtcbiAgICAgIGNvbnN0IHJlbGF0aXZlQ29uZmlnUGF0aCA9IHBhdGgucmVsYXRpdmUocHJvamVjdERpciwgY29uZmlnUGF0aCEpO1xuICAgICAgYXdhaXQgb3Blbk5leHRCdWlsZC5idWlsZChcbiAgICAgICAgcmVsYXRpdmVDb25maWdQYXRoLFxuICAgICAgICAnQG9wZW5uZXh0anMvYXdzJyxcbiAgICAgICAgZm9yY2VVbnN1cHBvcnRlZFxuICAgICAgKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcHJvY2Vzcy5jaGRpcihwcmV2Q3dkKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZygnW2J1aWxkXSBCdWlsZCBjb21wbGV0ZSEnKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAodGVtcENvbmZpZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZnMudW5saW5rKGNvbmZpZ1BhdGghKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgJ1tidWlsZF0gV2FybmluZzogZmFpbGVkIHRvIGNsZWFuIHVwIHRlbXBvcmFyeSBjb25maWcgZmlsZSdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGNsZWFudXBPdmVycmlkZXMocHJvamVjdERpcik7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBbYnVpbGRdIFdhcm5pbmc6IGZhaWxlZCB0byBjbGVhbiB1cCAke1BDR19PVkVSUklERVNfUkVMfS9gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVCdWlsZENvbW1hbmQoKTogQ29tbWFuZCB7XG4gIHJldHVybiBuZXcgQ29tbWFuZCgnYnVpbGQnKVxuICAgIC5kZXNjcmlwdGlvbignQnVpbGQgTmV4dC5qcyBwcm9qZWN0IGZvciBkZXBsb3ltZW50IHZpYSBwYWdlcy1jYWNoZS1nYXRld2F5JylcbiAgICAub3B0aW9uKCctLWRpciA8cGF0aD4nLCAnTmV4dC5qcyBwcm9qZWN0IGRpcmVjdG9yeScsICcuJylcbiAgICAub3B0aW9uKCctLWNvbmZpZyA8cGF0aD4nLCAnb3Blbi1uZXh0LmNvbmZpZy50cyBwYXRoJylcbiAgICAub3B0aW9uKCctLWRlYnVnJywgJ0VuYWJsZSBkZWJ1ZyBtb2RlJylcbiAgICAub3B0aW9uKCctLWRyeS1ydW4nLCAnU2hvdyBidWlsZCBwbGFuIHdpdGhvdXQgZXhlY3V0aW5nJylcbiAgICAub3B0aW9uKCctLWZvcmNlLXVuc3VwcG9ydGVkLW5leHQnLCAnQWxsb3cgdW5zdXBwb3J0ZWQgTmV4dC5qcyB2ZXJzaW9ucycpXG4gICAgLmFjdGlvbihhc3luYyBvcHRpb25zID0+IHtcbiAgICAgIGF3YWl0IHJ1bkJ1aWxkKHtcbiAgICAgICAgZGlyOiBvcHRpb25zLmRpcixcbiAgICAgICAgY29uZmlnOiBvcHRpb25zLmNvbmZpZyxcbiAgICAgICAgZGVidWc6IG9wdGlvbnMuZGVidWcsXG4gICAgICAgIGRyeVJ1bjogb3B0aW9ucy5kcnlSdW4sXG4gICAgICAgIGZvcmNlVW5zdXBwb3J0ZWROZXh0OiBvcHRpb25zLmZvcmNlVW5zdXBwb3J0ZWROZXh0LFxuICAgICAgfSk7XG4gICAgfSk7XG59XG4iXX0=
|
|
207
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvYnVpbGQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQTZCO0FBQzdCLGtDQUFrQztBQUNsQyx5Q0FBb0M7QUFDcEMsbUNBQXVDO0FBQ3ZDLGlGQUEyRTtBQUUzRSx5RUFBeUU7QUFDekUsaUZBQWlGO0FBQ2pGLDJEQUEyRDtBQUMzRCxNQUFNLGtCQUFrQixHQUEyQjtJQUNqRCxFQUFFLEVBQUUsWUFBWTtJQUNoQixFQUFFLEVBQUUsWUFBWTtJQUNoQixFQUFFLEVBQUUsWUFBWTtJQUNoQixFQUFFLEVBQUUsWUFBWTtJQUNoQixFQUFFLEVBQUUsWUFBWTtDQUNqQixDQUFDO0FBQ0YsTUFBTSx5QkFBeUIsR0FBRyxDQUFDLENBQUM7QUFFcEMsS0FBSyxVQUFVLGVBQWUsQ0FBQyxVQUFrQjtJQUMvQyxJQUFJO1FBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FDdkIsVUFBVSxFQUNWLGNBQWMsRUFDZCxNQUFNLEVBQ04sY0FBYyxDQUNmLENBQUM7UUFDRixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUM1RCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDOUQsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztLQUMzQztJQUFDLFdBQU07UUFDTixPQUFPLElBQUksQ0FBQztLQUNiO0FBQ0gsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQUMsS0FBYTtJQUMzQyxNQUFNLFdBQVcsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxJQUFJLENBQUMsV0FBVztRQUFFLE9BQU8sS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUNwQyxNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNsQyxHQUFHLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsR0FBRyx5QkFBeUIsQ0FBQyxDQUFDO0lBQy9ELE9BQU8sSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUNwQyxDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLDBFQUEwRTtBQUMxRSw4RUFBOEU7QUFDOUUsdUVBQXVFO0FBQ3ZFLE1BQU0saUJBQWlCLEdBQUcsZ0JBQWdCLENBQUM7QUFFM0MsMEVBQTBFO0FBQzFFLDJFQUEyRTtBQUMzRSx3RUFBd0U7QUFDeEUsTUFBTSxxQkFBcUIsR0FBRyx5QkFBeUIsQ0FBQztBQUV4RCxLQUFLLFVBQVUsZ0JBQWdCLENBQUMsV0FBbUI7O0lBQ2pELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQ25CLFdBQVcsRUFDWCxtQkFBbUIsRUFDbkIscUJBQXFCLENBQ3RCLENBQUM7SUFDRixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUNuQixXQUFXLEVBQ1gsa0JBQWtCLEVBQ2xCLFNBQVMsRUFDVCxxQkFBcUIsQ0FDdEIsQ0FBQztJQUNGLElBQUk7UUFDRixNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDdEI7SUFBQyxXQUFNO1FBQ04sT0FBTyxDQUFDLElBQUksQ0FDVixxR0FBcUcsQ0FDdEcsQ0FBQztRQUNGLE9BQU87S0FDUjtJQUNELElBQUk7UUFDRixNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQW1DLHFCQUFxQixFQUFFLENBQUMsQ0FBQztLQUN6RTtJQUFDLE9BQU8sR0FBUSxFQUFFO1FBQ2pCLE9BQU8sQ0FBQyxJQUFJLENBQUMseUNBQXlDLE1BQUEsR0FBRyxhQUFILEdBQUcsdUJBQUgsR0FBRyxDQUFFLE9BQU8sbUNBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztLQUM5RTtBQUNILENBQUM7QUFFRCxLQUFLLFVBQVUsb0JBQW9CLENBQUMsVUFBa0I7SUFDcEQsMkVBQTJFO0lBQzNFLHNEQUFzRDtJQUN0RCxJQUFJLGdCQUF3QyxDQUFDO0lBQzdDLElBQUk7UUFDRixDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxPQUFPLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO0tBQzFEO0lBQUMsT0FBTyxHQUFRLEVBQUU7UUFDakIsSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxrQkFBa0IsRUFBRTtZQUMxQyxNQUFNLElBQUksS0FBSyxDQUNiLDhEQUE4RDtnQkFDNUQsdUVBQXVFO2dCQUN2RSw0RUFBNEUsQ0FDL0UsQ0FBQztTQUNIO1FBQ0QsTUFBTSxHQUFHLENBQUM7S0FDWDtJQUNELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDL0QsS0FBSyxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBRzVELEVBQUU7UUFDSCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNqRCxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFELE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDcEM7QUFDSCxDQUFDO0FBRUQsS0FBSyxVQUFVLGdCQUFnQixDQUFDLFVBQWtCO0lBQ2hELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDL0QsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDN0QsbUVBQW1FO0lBQ25FLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUMsQ0FBQztBQUNoRSxDQUFDO0FBVU0sS0FBSyxVQUFVLFFBQVEsQ0FBQyxJQUFrQjtJQUMvQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUxQyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUMxRCxJQUFJO1FBQ0YsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0tBQzlCO0lBQUMsV0FBTTtRQUNOLE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0NBQWdDLFVBQVUsb0JBQW9CLENBQy9ELENBQUM7S0FDSDtJQUVELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBRXhELElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDN0IsSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBRXZCLElBQUksQ0FBQyxVQUFVLEVBQUU7UUFDZixNQUFNLFVBQVUsR0FBRyxDQUFDLHFCQUFxQixFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDbEUsS0FBSyxNQUFNLENBQUMsSUFBSSxVQUFVLEVBQUU7WUFDMUIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbkMsSUFBSTtnQkFDRixNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLFVBQVUsR0FBRyxDQUFDLENBQUM7Z0JBQ2YsTUFBTTthQUNQO1lBQUMsV0FBTSxHQUFFO1NBQ1g7S0FDRjtJQUVELElBQUksQ0FBQyxVQUFVLEVBQUU7UUFDZixPQUFPLENBQUMsR0FBRyxDQUNULGlFQUFpRSxDQUNsRSxDQUFDO1FBQ0YsVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDMUQsTUFBTSxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN2QyxNQUFNLGFBQWEsR0FBRyxJQUFBLGdEQUFxQixFQUFDO1lBQzFDLFlBQVksRUFBRSxLQUFLLGlCQUFpQixFQUFFO1NBQ3ZDLENBQUMsQ0FBQztRQUNILE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDOUMsVUFBVSxHQUFHLElBQUksQ0FBQztLQUNuQjtJQUVELElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtRQUNmLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUNsRCxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ3hDLE9BQU87S0FDUjtJQUVELElBQUk7UUFDRixJQUFJLE1BQU0sSUFBQSxjQUFTLEVBQUMsV0FBVyxDQUFDLEVBQUU7WUFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO1lBQzdELE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1NBQzVEO1FBRUQsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ2QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLEdBQUcsTUFBTSxDQUFDO1NBQ3RDO1FBRUQsSUFBSSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsb0JBQW9CLEtBQUssSUFBSSxDQUFDO1FBQzFELElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixLQUFLLEdBQUcsRUFBRTtZQUNwRSxNQUFNLFNBQVMsR0FBRyxNQUFNLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNwRCxJQUFJLFNBQVMsS0FBSyxJQUFJLElBQUksc0JBQXNCLENBQUMsU0FBUyxDQUFDLEVBQUU7Z0JBQzNELE9BQU8sQ0FBQyxJQUFJLENBQ1YsZ0JBQWdCLFNBQVMseUJBQXlCLHlCQUF5Qix5QkFBeUI7b0JBQ2xHLDBDQUEwQztvQkFDMUMseURBQXlELENBQzVELENBQUM7Z0JBQ0YsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO2FBQ3pCO1NBQ0Y7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFDakQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzlCLElBQUk7WUFDRixPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzFCLHFFQUFxRTtZQUNyRSw2RUFBNkU7WUFDN0UsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLDBCQUEwQixDQUFDLENBQUM7WUFDMUQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxVQUFXLENBQUMsQ0FBQztZQUNsRSxNQUFNLGFBQWEsQ0FBQyxLQUFLLENBQ3ZCLGtCQUFrQixFQUNsQixpQkFBaUIsRUFDakIsZ0JBQWdCLENBQ2pCLENBQUM7U0FDSDtnQkFBUztZQUNSLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDeEI7UUFFRCxNQUFNLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXBDLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUMsQ0FBQztLQUN4QztZQUFTO1FBQ1IsSUFBSSxVQUFVLEVBQUU7WUFDZCxJQUFJO2dCQUNGLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFXLENBQUMsQ0FBQzthQUM5QjtZQUFDLFdBQU07Z0JBQ04sT0FBTyxDQUFDLElBQUksQ0FDViwyREFBMkQsQ0FDNUQsQ0FBQzthQUNIO1lBQ0QsSUFBSTtnQkFDRixNQUFNLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ3BDO1lBQUMsV0FBTTtnQkFDTixPQUFPLENBQUMsSUFBSSxDQUNWLHVDQUF1QyxpQkFBaUIsR0FBRyxDQUM1RCxDQUFDO2FBQ0g7U0FDRjtLQUNGO0FBQ0gsQ0FBQztBQS9HRCw0QkErR0M7QUFFRCxTQUFnQixrQkFBa0I7SUFDaEMsT0FBTyxJQUFJLG1CQUFPLENBQUMsT0FBTyxDQUFDO1NBQ3hCLFdBQVcsQ0FBQyw4REFBOEQsQ0FBQztTQUMzRSxNQUFNLENBQUMsY0FBYyxFQUFFLDJCQUEyQixFQUFFLEdBQUcsQ0FBQztTQUN4RCxNQUFNLENBQUMsaUJBQWlCLEVBQUUsMEJBQTBCLENBQUM7U0FDckQsTUFBTSxDQUFDLFNBQVMsRUFBRSxtQkFBbUIsQ0FBQztTQUN0QyxNQUFNLENBQUMsV0FBVyxFQUFFLG1DQUFtQyxDQUFDO1NBQ3hELE1BQU0sQ0FBQywwQkFBMEIsRUFBRSxvQ0FBb0MsQ0FBQztTQUN4RSxNQUFNLENBQUMsS0FBSyxFQUFDLE9BQU8sRUFBQyxFQUFFO1FBQ3RCLE1BQU0sUUFBUSxDQUFDO1lBQ2IsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHO1lBQ2hCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtZQUN0QixLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7WUFDcEIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3RCLG9CQUFvQixFQUFFLE9BQU8sQ0FBQyxvQkFBb0I7U0FDbkQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBakJELGdEQWlCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCB7IGRpckV4aXN0cyB9IGZyb20gJy4uL3V0aWwvZnMnO1xuaW1wb3J0IHsgZ2VuZXJhdGVEZWZhdWx0Q29uZmlnIH0gZnJvbSAnLi4vY29uZmlnL2RlZmF1bHQtb3Blbi1uZXh0LWNvbmZpZyc7XG5cbi8vIE1pcnJvciBvZiBPcGVuTmV4dCdzIE5FWFRfUkVMRUFTRV9EQVRFUyAoaGVscGVyLmpzKS4gVXNlZCB0byBhdXRvLXBhc3Ncbi8vIC0tZm9yY2UtdW5zdXBwb3J0ZWQtbmV4dCB3aGVuIHRoZSB1c2VyJ3MgTmV4dCBtYWpvciBpcyBwYXN0IGl0cyAyLXllYXIgd2luZG93LFxuLy8gc28gcGlwZWxpbmUgYnVpbGRzIGRvbid0IGZhaWwgb24gT3Blbk5leHQncyBwb2xpY3kgZ2F0ZS5cbmNvbnN0IE5FWFRfUkVMRUFTRV9EQVRFUzogUmVjb3JkPG51bWJlciwgc3RyaW5nPiA9IHtcbiAgMTY6ICcyMDI1LTEwLTIxJyxcbiAgMTU6ICcyMDI0LTEwLTIxJyxcbiAgMTQ6ICcyMDIzLTEwLTI2JyxcbiAgMTM6ICcyMDIyLTEwLTI2JyxcbiAgMTI6ICcyMDIxLTEwLTI2Jyxcbn07XG5jb25zdCBORVhUX1NVUFBPUlRfV0lORE9XX1lFQVJTID0gMjtcblxuYXN5bmMgZnVuY3Rpb24gZGV0ZWN0TmV4dE1ham9yKHByb2plY3REaXI6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHBrZ1BhdGggPSBwYXRoLmpvaW4oXG4gICAgICBwcm9qZWN0RGlyLFxuICAgICAgJ25vZGVfbW9kdWxlcycsXG4gICAgICAnbmV4dCcsXG4gICAgICAncGFja2FnZS5qc29uJ1xuICAgICk7XG4gICAgY29uc3QgcGtnID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShwa2dQYXRoLCAndXRmLTgnKSk7XG4gICAgY29uc3QgbWFqb3IgPSBwYXJzZUludChTdHJpbmcocGtnLnZlcnNpb24pLnNwbGl0KCcuJylbMF0sIDEwKTtcbiAgICByZXR1cm4gTnVtYmVyLmlzTmFOKG1ham9yKSA/IG51bGwgOiBtYWpvcjtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNOZXh0TWFqb3JVbnN1cHBvcnRlZChtYWpvcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJlbGVhc2VEYXRlID0gTkVYVF9SRUxFQVNFX0RBVEVTW21ham9yXTtcbiAgaWYgKCFyZWxlYXNlRGF0ZSkgcmV0dXJuIG1ham9yIDwgMTI7XG4gIGNvbnN0IGVvbCA9IG5ldyBEYXRlKHJlbGVhc2VEYXRlKTtcbiAgZW9sLnNldEZ1bGxZZWFyKGVvbC5nZXRGdWxsWWVhcigpICsgTkVYVF9TVVBQT1JUX1dJTkRPV19ZRUFSUyk7XG4gIHJldHVybiBEYXRlLm5vdygpID4gZW9sLmdldFRpbWUoKTtcbn1cblxuLy8gUGF0aCBpbnNpZGUgPHByb2plY3REaXI+IHdoZXJlIHdlIG1hdGVyaWFsaXplIG92ZXJyaWRlIGJ1bmRsZXMgc28gdGhlXG4vLyBhdXRvLWdlbmVyYXRlZCBvcGVuLW5leHQuY29uZmlnIGNhbiByZWZlcmVuY2UgdGhlbSB2aWEgYSByZWxhdGl2ZSBwYXRoLlxuLy8gUmVsYXRpdmUgZm9ybSBuZWVkZWQgYmVjYXVzZSBhYnNvbHV0ZSBfX2Rpcm5hbWUgcGF0aHMgYnJlYWsgd2hlbiB0aGUgQ0xJIGlzXG4vLyBuY2MtYnVuZGxlZCBpbnRvIGEgc2luZ2xlIGZpbGUgKHN1YmRpcmVjdG9yeSB0cmVlIG5vIGxvbmdlciBleGlzdHMpLlxuY29uc3QgUENHX09WRVJSSURFU19SRUwgPSAnLnBjZy9vdmVycmlkZXMnO1xuXG4vLyBGaWxlbmFtZSBmb3IgdGhlIHRhZ+KGknBhdGggbWFuaWZlc3QgZW1iZWRkZWQgaW50byB0aGUgRkMgYnVuZGxlLiBSZWFkIGF0XG4vLyBGQyBjb2xkIHN0YXJ0IGJ5IHJ1bnRpbWUvY2RuLXB1cmdlIHRvIG1hcCByZXZhbGlkYXRlVGFnIOKGkiBDRE4gcHVyZ2UgVVJMc1xuLy8gd2l0aG91dCBhIHNlcnZlciByb3VuZCB0cmlwLiBSZXNvbHZlZCB2aWEgX19kaXJuYW1lIGluc2lkZSBjYWNoZS5janMuXG5jb25zdCBUQUdfTUFOSUZFU1RfRklMRU5BTUUgPSAnX19wY2dfdGFnX21hbmlmZXN0Lmpzb24nO1xuXG5hc3luYyBmdW5jdGlvbiBlbWJlZFRhZ01hbmlmZXN0KG9wZW5OZXh0RGlyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qgc3JjID0gcGF0aC5qb2luKFxuICAgIG9wZW5OZXh0RGlyLFxuICAgICdkeW5hbW9kYi1wcm92aWRlcicsXG4gICAgJ2R5bmFtb2RiLWNhY2hlLmpzb24nXG4gICk7XG4gIGNvbnN0IGRzdCA9IHBhdGguam9pbihcbiAgICBvcGVuTmV4dERpcixcbiAgICAnc2VydmVyLWZ1bmN0aW9ucycsXG4gICAgJ2RlZmF1bHQnLFxuICAgIFRBR19NQU5JRkVTVF9GSUxFTkFNRVxuICApO1xuICB0cnkge1xuICAgIGF3YWl0IGZzLmFjY2VzcyhzcmMpO1xuICB9IGNhdGNoIHtcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgW2J1aWxkXSBkeW5hbW9kYi1wcm92aWRlci9keW5hbW9kYi1jYWNoZS5qc29uIG5vdCBmb3VuZCDigJQgYXV0byBDRE4gcHVyZ2Ugd2lsbCBoYXZlIGFuIGVtcHR5IHRhZyBtYXBgXG4gICAgKTtcbiAgICByZXR1cm47XG4gIH1cbiAgdHJ5IHtcbiAgICBhd2FpdCBmcy5jb3B5RmlsZShzcmMsIGRzdCk7XG4gICAgY29uc29sZS5sb2coYFtidWlsZF0gRW1iZWRkZWQgdGFnIG1hbmlmZXN0IOKGkiAke1RBR19NQU5JRkVTVF9GSUxFTkFNRX1gKTtcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICBjb25zb2xlLndhcm4oYFtidWlsZF0gRmFpbGVkIHRvIGVtYmVkIHRhZyBtYW5pZmVzdDogJHtlcnI/Lm1lc3NhZ2UgPz8gZXJyfWApO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1hdGVyaWFsaXplT3ZlcnJpZGVzKHByb2plY3REaXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAvLyBMYXp5IHJlcXVpcmUg4oCUIGtlZXBzIHRoZSBpbmxpbmUtb3ZlcnJpZGVzIGJ1bmRsZSBvdXQgb2YgdGhlIGltcG9ydCBncmFwaFxuICAvLyBmb3IgY29kZSBwYXRocyB0aGF0IGRvbid0IGF1dG8tZ2VuZXJhdGUgdGhlIGNvbmZpZy5cbiAgbGV0IElOTElORV9PVkVSUklERVM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIHRyeSB7XG4gICAgKHsgSU5MSU5FX09WRVJSSURFUyB9ID0gcmVxdWlyZSgnLi4vX2lubGluZS1vdmVycmlkZXMnKSk7XG4gIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgaWYgKGVyciAmJiBlcnIuY29kZSA9PT0gJ01PRFVMRV9OT1RfRk9VTkQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdbYnVpbGRdIGRpc3QvX2lubGluZS1vdmVycmlkZXMuanMgbWlzc2luZyBmcm9tIGVzYS1wY2ctY2xpLiAnICtcbiAgICAgICAgICAnVGhlIHB1Ymxpc2hlZCBwYWNrYWdlIHdhcyBidWlsdCB3aXRob3V0IHNjcmlwdHMvYnVuZGxlLW92ZXJyaWRlcy5qcy4gJyArXG4gICAgICAgICAgJ1JlaW5zdGFsbCBhIG5ld2VyIGVzYS1wY2ctY2xpIChidWlsdCB3aXRoIHRoZSBmdWxsIGBwbnBtIGJ1aWxkYCBwaXBlbGluZSkuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG4gIGNvbnN0IG92ZXJyaWRlc1Jvb3QgPSBwYXRoLmpvaW4ocHJvamVjdERpciwgUENHX09WRVJSSURFU19SRUwpO1xuICBmb3IgKGNvbnN0IFtyZWxQYXRoLCBzb3VyY2VdIG9mIE9iamVjdC5lbnRyaWVzKElOTElORV9PVkVSUklERVMpIGFzIFtcbiAgICBzdHJpbmcsXG4gICAgc3RyaW5nLFxuICBdW10pIHtcbiAgICBjb25zdCB0YXJnZXQgPSBwYXRoLmpvaW4ob3ZlcnJpZGVzUm9vdCwgcmVsUGF0aCk7XG4gICAgYXdhaXQgZnMubWtkaXIocGF0aC5kaXJuYW1lKHRhcmdldCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZSh0YXJnZXQsIHNvdXJjZSk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gY2xlYW51cE92ZXJyaWRlcyhwcm9qZWN0RGlyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qgb3ZlcnJpZGVzUm9vdCA9IHBhdGguam9pbihwcm9qZWN0RGlyLCBQQ0dfT1ZFUlJJREVTX1JFTCk7XG4gIGF3YWl0IGZzLnJtKG92ZXJyaWRlc1Jvb3QsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgLy8gQWxzbyB0cnkgdG8gcmVtb3ZlIHRoZSAucGNnIHBhcmVudCBpZiBpdCdzIGVtcHR5OyBpZ25vcmUgaWYgbm90LlxuICBhd2FpdCBmcy5ybWRpcihwYXRoLmpvaW4ocHJvamVjdERpciwgJy5wY2cnKSkuY2F0Y2goKCkgPT4ge30pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkT3B0aW9ucyB7XG4gIGRpcjogc3RyaW5nO1xuICBjb25maWc/OiBzdHJpbmc7XG4gIGRlYnVnPzogYm9vbGVhbjtcbiAgZHJ5UnVuPzogYm9vbGVhbjtcbiAgZm9yY2VVbnN1cHBvcnRlZE5leHQ/OiBib29sZWFuO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQnVpbGQob3B0czogQnVpbGRPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3REaXIgPSBwYXRoLnJlc29sdmUob3B0cy5kaXIpO1xuXG4gIGNvbnN0IHBrZ0pzb25QYXRoID0gcGF0aC5qb2luKHByb2plY3REaXIsICdwYWNrYWdlLmpzb24nKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmcy5hY2Nlc3MocGtnSnNvblBhdGgpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTmV4dC5qcyBwcm9qZWN0IG5vdCBmb3VuZCBhdCAke3Byb2plY3REaXJ9IChubyBwYWNrYWdlLmpzb24pYFxuICAgICk7XG4gIH1cblxuICBjb25zdCBvcGVuTmV4dERpciA9IHBhdGguam9pbihwcm9qZWN0RGlyLCAnLm9wZW4tbmV4dCcpO1xuXG4gIGxldCBjb25maWdQYXRoID0gb3B0cy5jb25maWc7XG4gIGxldCB0ZW1wQ29uZmlnID0gZmFsc2U7XG5cbiAgaWYgKCFjb25maWdQYXRoKSB7XG4gICAgY29uc3QgY2FuZGlkYXRlcyA9IFsnb3Blbi1uZXh0LmNvbmZpZy50cycsICdvcGVuLW5leHQuY29uZmlnLmpzJ107XG4gICAgZm9yIChjb25zdCBjIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgIGNvbnN0IHAgPSBwYXRoLmpvaW4ocHJvamVjdERpciwgYyk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBmcy5hY2Nlc3MocCk7XG4gICAgICAgIGNvbmZpZ1BhdGggPSBwO1xuICAgICAgICBicmVhaztcbiAgICAgIH0gY2F0Y2gge31cbiAgICB9XG4gIH1cblxuICBpZiAoIWNvbmZpZ1BhdGgpIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgICdbYnVpbGRdIE5vIG9wZW4tbmV4dC5jb25maWcgZm91bmQsIGdlbmVyYXRpbmcgZGVmYXVsdCBjb25maWcuLi4nXG4gICAgKTtcbiAgICBjb25maWdQYXRoID0gcGF0aC5qb2luKHByb2plY3REaXIsICdvcGVuLW5leHQuY29uZmlnLnRzJyk7XG4gICAgYXdhaXQgbWF0ZXJpYWxpemVPdmVycmlkZXMocHJvamVjdERpcik7XG4gICAgY29uc3QgY29uZmlnQ29udGVudCA9IGdlbmVyYXRlRGVmYXVsdENvbmZpZyh7XG4gICAgICBvdmVycmlkZXNEaXI6IGAuLyR7UENHX09WRVJSSURFU19SRUx9YCxcbiAgICB9KTtcbiAgICBhd2FpdCBmcy53cml0ZUZpbGUoY29uZmlnUGF0aCwgY29uZmlnQ29udGVudCk7XG4gICAgdGVtcENvbmZpZyA9IHRydWU7XG4gIH1cblxuICBpZiAob3B0cy5kcnlSdW4pIHtcbiAgICBjb25zb2xlLmxvZygnW2J1aWxkXSBEcnkgcnVuIG1vZGUg4oCUIGJ1aWxkIHBsYW46Jyk7XG4gICAgY29uc29sZS5sb2coYCAgUHJvamVjdCBkaXI6ICR7cHJvamVjdERpcn1gKTtcbiAgICBjb25zb2xlLmxvZyhgICBDb25maWc6ICR7Y29uZmlnUGF0aH1gKTtcbiAgICBjb25zb2xlLmxvZyhgICBPdXRwdXQ6ICR7b3Blbk5leHREaXJ9YCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBpZiAoYXdhaXQgZGlyRXhpc3RzKG9wZW5OZXh0RGlyKSkge1xuICAgICAgY29uc29sZS5sb2coJ1tidWlsZF0gQ2xlYW5pbmcgb2xkIC5vcGVuLW5leHQvIGRpcmVjdG9yeS4uLicpO1xuICAgICAgYXdhaXQgZnMucm0ob3Blbk5leHREaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAob3B0cy5kZWJ1Zykge1xuICAgICAgcHJvY2Vzcy5lbnYuT1BFTl9ORVhUX0RFQlVHID0gJ3RydWUnO1xuICAgIH1cblxuICAgIGxldCBmb3JjZVVuc3VwcG9ydGVkID0gb3B0cy5mb3JjZVVuc3VwcG9ydGVkTmV4dCA9PT0gdHJ1ZTtcbiAgICBpZiAoIWZvcmNlVW5zdXBwb3J0ZWQgJiYgcHJvY2Vzcy5lbnYuUENHX1NUUklDVF9ORVhUX1NVUFBPUlQgIT09ICcxJykge1xuICAgICAgY29uc3QgbmV4dE1ham9yID0gYXdhaXQgZGV0ZWN0TmV4dE1ham9yKHByb2plY3REaXIpO1xuICAgICAgaWYgKG5leHRNYWpvciAhPT0gbnVsbCAmJiBpc05leHRNYWpvclVuc3VwcG9ydGVkKG5leHRNYWpvcikpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBbYnVpbGRdIE5leHQgJHtuZXh0TWFqb3J9LnggaXMgcGFzdCBPcGVuTmV4dCdzICR7TkVYVF9TVVBQT1JUX1dJTkRPV19ZRUFSU30teWVhciBzdXBwb3J0IHdpbmRvdyDigJQgYCArXG4gICAgICAgICAgICAnYXV0by1lbmFibGluZyAtLWZvcmNlLXVuc3VwcG9ydGVkLW5leHQuICcgK1xuICAgICAgICAgICAgJ1NldCBQQ0dfU1RSSUNUX05FWFRfU1VQUE9SVD0xIHRvIGRpc2FibGUgdGhpcyBiZWhhdmlvci4nXG4gICAgICAgICk7XG4gICAgICAgIGZvcmNlVW5zdXBwb3J0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKCdbYnVpbGRdIFJ1bm5pbmcgT3Blbk5leHQgYnVpbGQuLi4nKTtcbiAgICBjb25zdCBwcmV2Q3dkID0gcHJvY2Vzcy5jd2QoKTtcbiAgICB0cnkge1xuICAgICAgcHJvY2Vzcy5jaGRpcihwcm9qZWN0RGlyKTtcbiAgICAgIC8vIE9wZW5OZXh0IHJlc29sdmVzIGBuZXh0YCB2aWEgcHJvY2Vzcy5jd2QoKSAvIHsgcGF0aHM6IFthcHBQYXRoXSB9LFxuICAgICAgLy8gc28gbG9hZGluZyBpdCBmcm9tIHRoZSBDTEkncyBvd24gbm9kZV9tb2R1bGVzIHN0aWxsIGZpbmRzIHRoZSB1c2VyJ3MgTmV4dC5cbiAgICAgIGNvbnN0IG9wZW5OZXh0QnVpbGQgPSByZXF1aXJlKCdAb3Blbm5leHRqcy9hd3MvYnVpbGQuanMnKTtcbiAgICAgIGNvbnN0IHJlbGF0aXZlQ29uZmlnUGF0aCA9IHBhdGgucmVsYXRpdmUocHJvamVjdERpciwgY29uZmlnUGF0aCEpO1xuICAgICAgYXdhaXQgb3Blbk5leHRCdWlsZC5idWlsZChcbiAgICAgICAgcmVsYXRpdmVDb25maWdQYXRoLFxuICAgICAgICAnQG9wZW5uZXh0anMvYXdzJyxcbiAgICAgICAgZm9yY2VVbnN1cHBvcnRlZFxuICAgICAgKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcHJvY2Vzcy5jaGRpcihwcmV2Q3dkKTtcbiAgICB9XG5cbiAgICBhd2FpdCBlbWJlZFRhZ01hbmlmZXN0KG9wZW5OZXh0RGlyKTtcblxuICAgIGNvbnNvbGUubG9nKCdbYnVpbGRdIEJ1aWxkIGNvbXBsZXRlIScpO1xuICB9IGZpbmFsbHkge1xuICAgIGlmICh0ZW1wQ29uZmlnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBmcy51bmxpbmsoY29uZmlnUGF0aCEpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAnW2J1aWxkXSBXYXJuaW5nOiBmYWlsZWQgdG8gY2xlYW4gdXAgdGVtcG9yYXJ5IGNvbmZpZyBmaWxlJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgY2xlYW51cE92ZXJyaWRlcyhwcm9qZWN0RGlyKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYFtidWlsZF0gV2FybmluZzogZmFpbGVkIHRvIGNsZWFuIHVwICR7UENHX09WRVJSSURFU19SRUx9L2BcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUJ1aWxkQ29tbWFuZCgpOiBDb21tYW5kIHtcbiAgcmV0dXJuIG5ldyBDb21tYW5kKCdidWlsZCcpXG4gICAgLmRlc2NyaXB0aW9uKCdCdWlsZCBOZXh0LmpzIHByb2plY3QgZm9yIGRlcGxveW1lbnQgdmlhIHBhZ2VzLWNhY2hlLWdhdGV3YXknKVxuICAgIC5vcHRpb24oJy0tZGlyIDxwYXRoPicsICdOZXh0LmpzIHByb2plY3QgZGlyZWN0b3J5JywgJy4nKVxuICAgIC5vcHRpb24oJy0tY29uZmlnIDxwYXRoPicsICdvcGVuLW5leHQuY29uZmlnLnRzIHBhdGgnKVxuICAgIC5vcHRpb24oJy0tZGVidWcnLCAnRW5hYmxlIGRlYnVnIG1vZGUnKVxuICAgIC5vcHRpb24oJy0tZHJ5LXJ1bicsICdTaG93IGJ1aWxkIHBsYW4gd2l0aG91dCBleGVjdXRpbmcnKVxuICAgIC5vcHRpb24oJy0tZm9yY2UtdW5zdXBwb3J0ZWQtbmV4dCcsICdBbGxvdyB1bnN1cHBvcnRlZCBOZXh0LmpzIHZlcnNpb25zJylcbiAgICAuYWN0aW9uKGFzeW5jIG9wdGlvbnMgPT4ge1xuICAgICAgYXdhaXQgcnVuQnVpbGQoe1xuICAgICAgICBkaXI6IG9wdGlvbnMuZGlyLFxuICAgICAgICBjb25maWc6IG9wdGlvbnMuY29uZmlnLFxuICAgICAgICBkZWJ1Zzogb3B0aW9ucy5kZWJ1ZyxcbiAgICAgICAgZHJ5UnVuOiBvcHRpb25zLmRyeVJ1bixcbiAgICAgICAgZm9yY2VVbnN1cHBvcnRlZE5leHQ6IG9wdGlvbnMuZm9yY2VVbnN1cHBvcnRlZE5leHQsXG4gICAgICB9KTtcbiAgICB9KTtcbn1cbiJdfQ==
|
|
@@ -14,7 +14,10 @@ export default class GatewayTagCache {
|
|
|
14
14
|
mode: "nextMode";
|
|
15
15
|
private config;
|
|
16
16
|
private configLoaded;
|
|
17
|
+
private purgeClient;
|
|
18
|
+
private purgeClientLoaded;
|
|
17
19
|
private getConfig;
|
|
20
|
+
private getPurgeClient;
|
|
18
21
|
private buildTagKey;
|
|
19
22
|
getLastRevalidated(tags: string[]): Promise<number>;
|
|
20
23
|
hasBeenRevalidated(tags: string[], lastModified?: number): Promise<boolean>;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
const gateway_auth_1 = require("../../runtime/gateway-auth");
|
|
10
|
+
const cdn_purge_1 = require("../../runtime/cdn-purge");
|
|
10
11
|
const QUERY_TIMEOUT = 3000;
|
|
11
12
|
const WRITE_TIMEOUT = 5000;
|
|
12
13
|
const BATCH_SIZE = 200;
|
|
@@ -19,6 +20,8 @@ class GatewayTagCache {
|
|
|
19
20
|
this.mode = 'nextMode';
|
|
20
21
|
this.config = null;
|
|
21
22
|
this.configLoaded = false;
|
|
23
|
+
this.purgeClient = null;
|
|
24
|
+
this.purgeClientLoaded = false;
|
|
22
25
|
}
|
|
23
26
|
getConfig() {
|
|
24
27
|
if (!this.configLoaded) {
|
|
@@ -27,6 +30,14 @@ class GatewayTagCache {
|
|
|
27
30
|
}
|
|
28
31
|
return this.config;
|
|
29
32
|
}
|
|
33
|
+
getPurgeClient() {
|
|
34
|
+
if (!this.purgeClientLoaded) {
|
|
35
|
+
const cfg = (0, cdn_purge_1.loadCdnPurgeConfig)();
|
|
36
|
+
this.purgeClient = cfg ? (0, cdn_purge_1.createCdnPurgeClient)(cfg) : null;
|
|
37
|
+
this.purgeClientLoaded = true;
|
|
38
|
+
}
|
|
39
|
+
return this.purgeClient;
|
|
40
|
+
}
|
|
30
41
|
buildTagKey(tag) {
|
|
31
42
|
const config = this.getConfig();
|
|
32
43
|
if (!config)
|
|
@@ -134,6 +145,20 @@ class GatewayTagCache {
|
|
|
134
145
|
};
|
|
135
146
|
});
|
|
136
147
|
await this.batchWrite(config, rows);
|
|
148
|
+
// 写库成功后,fire-and-forget 触发 ESA 边缘缓存失效。
|
|
149
|
+
// 任何失败都不应回灌到调用方,所以 catch 直接 warn,不 throw、不 await。
|
|
150
|
+
const purgeClient = this.getPurgeClient();
|
|
151
|
+
if (purgeClient) {
|
|
152
|
+
const tagStrs = tags
|
|
153
|
+
.map(t => (typeof t === 'string' ? t : t.tag))
|
|
154
|
+
.filter((s) => typeof s === 'string' && s.length > 0);
|
|
155
|
+
if (tagStrs.length > 0) {
|
|
156
|
+
purgeClient.purgeByTags(tagStrs).catch(err => {
|
|
157
|
+
var _a;
|
|
158
|
+
console.warn(`[tagCache] purge fan-out failed: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
137
162
|
}
|
|
138
163
|
// ---- private methods ----
|
|
139
164
|
async batchGetTags(config, tags) {
|
|
@@ -208,4 +233,4 @@ class GatewayTagCache {
|
|
|
208
233
|
}
|
|
209
234
|
}
|
|
210
235
|
exports.default = GatewayTagCache;
|
|
211
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZXdheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9vdmVycmlkZXMvdGFnQ2FjaGUvZ2F0ZXdheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7O0dBS0c7O0FBRUgsNkRBSW9DO0FBRXBDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQztBQUMzQixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFDM0IsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDO0FBRXZCLFNBQVMsaUJBQWlCLENBQUMsQ0FBUztJQUNsQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQy9CLENBQUM7QUFnQkQsTUFBcUIsZUFBZTtJQUFwQztRQUNFLFNBQUksR0FBRyxtQkFBNEIsQ0FBQztRQUNwQyxTQUFJLEdBQUcsVUFBbUIsQ0FBQztRQUVuQixXQUFNLEdBQTZCLElBQUksQ0FBQztRQUN4QyxpQkFBWSxHQUFHLEtBQUssQ0FBQztJQTBOL0IsQ0FBQztJQXhOUyxTQUFTO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFBLG9DQUFxQixHQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDMUI7UUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztJQUVPLFdBQVcsQ0FBQyxHQUFXO1FBQzdCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sR0FBRyxDQUFDO1FBQ3hCLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7SUFDdkQsQ0FBQztJQUVELEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFjO1FBQ3JDLE1BQU0sTUFBTSxH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RTtvQkFDWCxPQUFPLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztpQkFDckU7YUFDRjtZQUFDLE9BQU8sR0FBUSxFQUFFO2dCQUNqQixJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFO29CQUM3QixPQUFPLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxhQUFhLEtBQUssQ0FBQyxDQUFDO2lCQUNyRTtxQkFBTTtvQkFDTCxPQUFPLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztpQkFDOUQ7YUFDRjtTQUNGO0lBQ0gsQ0FBQztDQUNGO0FBL05ELGtDQStOQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2F0ZXdheSBUYWcg57yT5a2YIE92ZXJyaWRlIChuZXh0TW9kZSlcbiAqXG4gKiDkvb/nlKggT3Blbk5leHQg55qEIG5leHRNb2RlIOaOpeWPo++8jOmAmui/hyBHYXRld2F5IOS7o+eQhuivu+WGmSBUYWJsZVN0b3Jl44CCXG4gKiDpibTmnYPnu5/kuIDotbAgcnVudGltZS9nYXRld2F5LWF1dGjvvIhITUFDIOetvuWQjSArIDQgaGVhZGVy77yJ44CCXG4gKi9cblxuaW1wb3J0IHtcbiAgbG9hZEdhdGV3YXlBdXRoQ29uZmlnLFxuICBnYXRld2F5RmV0Y2gsXG4gIEdhdGV3YXlBdXRoQ29uZmlnLFxufSBmcm9tICcuLi8uLi9ydW50aW1lL2dhdGV3YXktYXV0aCc7XG5cbmNvbnN0IFFVRVJZX1RJTUVPVVQgPSAzMDAwO1xuY29uc3QgV1JJVEVfVElNRU9VVCA9IDUwMDA7XG5jb25zdCBCQVRDSF9TSVpFID0gMjAwO1xuXG5mdW5jdGlvbiBzdHJpcExlYWRpbmdTbGFzaChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKC9eXFwvKy8sICcnKTtcbn1cblxudHlwZSBOZXh0TW9kZVRhZ0NhY2hlV3JpdGVJbnB1dCA9XG4gIHwgc3RyaW5nXG4gIHwge1xuICAgICAgdGFnOiBzdHJpbmc7XG4gICAgICBzdGFsZT86IG51bWJlcjtcbiAgICAgIGV4cGlyZT86IG51bWJlcjtcbiAgICB9O1xuXG5pbnRlcmZhY2UgVGFnUm93IHtcbiAgcmV2YWxpZGF0ZWRBdD86IG51bWJlcjtcbiAgc3RhbGU/OiBudW1iZXI7XG4gIGV4cGlyZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR2F0ZXdheVRhZ0NhY2hlIHtcbiAgbmFtZSA9ICdnYXRld2F5LXRhZy1jYWNoZScgYXMgY29uc3Q7XG4gIG1vZGUgPSAnbmV4dE1vZGUnIGFzIGNvbnN0O1xuXG4gIHByaXZhdGUgY29uZmlnOiBHYXRld2F5QXV0aENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbmZpZ0xvYWRlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgZ2V0Q29uZmlnKCk6IEdhdGV3YXlBdXRoQ29uZmlnIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZ0xvYWRlZCkge1xuICAgICAgdGhpcy5jb25maWcgPSBsb2FkR2F0ZXdheUF1dGhDb25maWcoKTtcbiAgICAgIHRoaXMuY29uZmlnTG9hZGVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFRhZ0tleSh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuIHRhZztcbiAgICByZXR1cm4gYCR7Y29uZmlnLnZlcnNpb259LyR7c3RyaXBMZWFkaW5nU2xhc2godGFnKX1gO1xuICB9XG5cbiAgYXN5bmMgZ2V0TGFzdFJldmFsaWRhdGVkKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gMDtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5iYXRjaEdldFRhZ3MoY29uZmlnLCB0YWdzKTtcbiAgICAgIGxldCBtYXhSZXZhbGlkYXRlZEF0ID0gMDtcbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5yZXZhbGlkYXRlZEF0ICYmIHJvdy5yZXZhbGlkYXRlZEF0ID4gbWF4UmV2YWxpZGF0ZWRBdCkge1xuICAgICAgICAgIG1heFJldmFsaWRhdGVkQXQgPSByb3cucmV2YWxpZGF0ZWRBdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1heFJldmFsaWRhdGVkQXQ7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBnZXRMYXN0UmV2YWxpZGF0ZWQgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYXNCZWVuUmV2YWxpZGF0ZWQoXG4gICAgdGFnczogc3RyaW5nW10sXG4gICAgbGFzdE1vZGlmaWVkPzogbnVtYmVyXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0YWdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLmJhdGNoR2V0VGFncyhjb25maWcsIHRhZ3MpO1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGxtID0gbGFzdE1vZGlmaWVkID8/IDA7XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5leHBpcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyb3cuZXhwaXJlIDw9IG5vdyAmJiByb3cuZXhwaXJlID4gbG0pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocm93LnJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCAmJiByb3cucmV2YWxpZGF0ZWRBdCA+IGxtKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGhhc0JlZW5SZXZhbGlkYXRlZCBlcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBpc1N0YWxlKHRhZ3M6IHN0cmluZ1tdLCBsYXN0TW9kaWZpZWQ/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5iYXRjaEdldFRhZ3MoY29uZmlnLCB0YWdzKTtcbiAgICAgIGNvbnN0IGxtID0gbGFzdE1vZGlmaWVkID8/IDA7XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5zdGFsZSA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgcmV2YWxpZGF0ZWRBdCA9IHJvdy5yZXZhbGlkYXRlZEF0ID8/IDA7XG4gICAgICAgIGlmIChyZXZhbGlkYXRlZEF0ID4gbG0gJiYgcm93LnN0YWxlID49IGxtKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGlzU3RhbGUgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgd3JpdGVUYWdzKHRhZ3M6IE5leHRNb2RlVGFnQ2FjaGVXcml0ZUlucHV0W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRhZ3MgfHwgdGFncy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybjtcblxuICAgIGNvbnN0IHdyaXRlVHMgPSBEYXRlLm5vdygpO1xuXG4gICAgY29uc3Qgcm93cyA9IHRhZ3MubWFwKGlucHV0ID0+IHtcbiAgICAgIGNvbnN0IHRhZ1N0ciA9IHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgPyBpbnB1dCA6IGlucHV0LnRhZztcbiAgICAgIGNvbnN0IHN0YWxlID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IGlucHV0LnN0YWxlO1xuICAgICAgY29uc3QgZXhwaXJlID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IGlucHV0LmV4cGlyZTtcbiAgICAgIGNvbnN0IHRhZ0tleSA9IHRoaXMuYnVpbGRUYWdLZXkodGFnU3RyKTtcblxuICAgICAgY29uc3QgY29sdW1uczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBudW1iZXIgfVtdID0gW1xuICAgICAgICB7IG5hbWU6ICdyZXZhbGlkYXRlZEF0JywgdmFsdWU6IHdyaXRlVHMgfSxcbiAgICAgIF07XG4gICAgICBpZiAoc3RhbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb2x1bW5zLnB1c2goeyBuYW1lOiAnc3RhbGUnLCB2YWx1ZTogc3RhbGUgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXhwaXJlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29sdW1ucy5wdXNoKHsgbmFtZTogJ2V4cGlyZScsIHZhbHVlOiBleHBpcmUgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByaW1hcnlLZXk6IFtcbiAgICAgICAgICB7IG5hbWU6ICdhcHBfaWQnLCB2YWx1ZTogYCR7Y29uZmlnLmFsaXVpZH0vJHtjb25maWcucm91dGluZW5hbWV9YCB9LFxuICAgICAgICAgIHsgbmFtZTogJ3RhZycsIHZhbHVlOiB0YWdLZXkgfSxcbiAgICAgICAgXSxcbiAgICAgICAgY29sdW1ucyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0aGlzLmJhdGNoV3JpdGUoY29uZmlnLCByb3dzKTtcbiAgfVxuXG4gIC8vIC0tLS0gcHJpdmF0ZSBtZXRob2RzIC0tLS1cblxuICBwcml2YXRlIGFzeW5jIGJhdGNoR2V0VGFncyhcbiAgICBjb25maWc6IEdhdGV3YXlBdXRoQ29uZmlnLFxuICAgIHRhZ3M6IHN0cmluZ1tdXG4gICk6IFByb21pc2U8VGFnUm93W10+IHtcbiAgICBjb25zdCBwcmltYXJ5S2V5cyA9IHRhZ3MubWFwKHRhZyA9PiBbXG4gICAgICB7IG5hbWU6ICdhcHBfaWQnLCB2YWx1ZTogYCR7Y29uZmlnLmFsaXVpZH0vJHtjb25maWcucm91dGluZW5hbWV9YCB9LFxuICAgICAgeyBuYW1lOiAndGFnJywgdmFsdWU6IHRoaXMuYnVpbGRUYWdLZXkodGFnKSB9LFxuICAgIF0pO1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNvbmZpZywgJy90YWJsZS9iYXRjaC1nZXQtcm93Jywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcHJpbWFyeUtleXMgfSksXG4gICAgICB0aW1lb3V0TXM6IFFVRVJZX1RJTUVPVVQsXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlcy5vaykge1xuICAgICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSB8fCByZXMuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IHJlamVjdGVkICgke3Jlcy5zdGF0dXN9KWBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IGZhaWxlZDogc3RhdHVzPSR7cmVzLnN0YXR1c31gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIHtcbiAgICAgIHJvd3M/OiB7XG4gICAgICAgIHByaW1hcnlLZXk/OiBhbnlbXTtcbiAgICAgICAgY29sdW1ucz86IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogbnVtYmVyIH1bXTtcbiAgICAgIH1bXTtcbiAgICB9O1xuXG4gICAgaWYgKCFkYXRhLnJvd3MpIHJldHVybiBbXTtcblxuICAgIHJldHVybiBkYXRhLnJvd3MubWFwKHJvdyA9PiB7XG4gICAgICBjb25zdCByZXN1bHQ6IFRhZ1JvdyA9IHt9O1xuICAgICAgZm9yIChjb25zdCBjb2wgb2Ygcm93LmNvbHVtbnMgPz8gW10pIHtcbiAgICAgICAgaWYgKGNvbC5uYW1lID09PSAncmV2YWxpZGF0ZWRBdCcgJiYgdHlwZW9mIGNvbC52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXN1bHQucmV2YWxpZGF0ZWRBdCA9IGNvbC52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2wubmFtZSA9PT0gJ3N0YWxlJyAmJiB0eXBlb2YgY29sLnZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJlc3VsdC5zdGFsZSA9IGNvbC52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2wubmFtZSA9PT0gJ2V4cGlyZScgJiYgdHlwZW9mIGNvbC52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXN1bHQuZXhwaXJlID0gY29sLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBiYXRjaFdyaXRlKFxuICAgIGNvbmZpZzogR2F0ZXdheUF1dGhDb25maWcsXG4gICAgcm93czoge1xuICAgICAgcHJpbWFyeUtleTogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfVtdO1xuICAgICAgY29sdW1uczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfVtdO1xuICAgIH1bXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocm93cy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkgKz0gQkFUQ0hfU0laRSkge1xuICAgICAgY29uc3QgYmF0Y2ggPSByb3dzLnNsaWNlKGksIGkgKyBCQVRDSF9TSVpFKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNvbmZpZywgJy90YWJsZS9iYXRjaC13cml0ZScsIHtcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHJvd3M6IGJhdGNoIH0pLFxuICAgICAgICAgIHRpbWVvdXRNczogV1JJVEVfVElNRU9VVCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSB8fCByZXMuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgYFt0YWdDYWNoZV0gYmF0Y2gtd3JpdGUgcmVqZWN0ZWQgKCR7cmVzLnN0YXR1c30pYFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFyZXMub2spIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYFt0YWdDYWNoZV0gYmF0Y2gtd3JpdGUgZmFpbGVkOiBzdGF0dXM9JHtyZXMuc3RhdHVzfWApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBpZiAoZXJyLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBiYXRjaC13cml0ZSB0aW1lb3V0ICgke1dSSVRFX1RJTUVPVVR9bXMpYCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGJhdGNoLXdyaXRlIGVycm9yOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
236
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZXdheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9vdmVycmlkZXMvdGFnQ2FjaGUvZ2F0ZXdheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7O0dBS0c7O0FBRUgsNkRBSW9DO0FBQ3BDLHVEQUlpQztBQUVqQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFDM0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQztBQUV2QixTQUFTLGlCQUFpQixDQUFDLENBQVM7SUFDbEMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBZ0JELE1BQXFCLGVBQWU7SUFBcEM7UUFDRSxTQUFJLEdBQUcsbUJBQTRCLENBQUM7UUFDcEMsU0FBSSxHQUFHLFVBQW1CLENBQUM7UUFFbkIsV0FBTSxHQUE2QixJQUFJLENBQUM7UUFDeEMsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFFckIsZ0JBQVcsR0FBMEIsSUFBSSxDQUFDO1FBQzFDLHNCQUFpQixHQUFHLEtBQUssQ0FBQztJQWlQcEMsQ0FBQztJQS9PUyxTQUFTO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFBLG9DQUFxQixHQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDMUI7UUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztJQUVPLGNBQWM7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMzQixNQUFNLEdBQUcsR0FBRyxJQUFBLDhCQUFrQixHQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUEsZ0NBQW9CLEVBQUMsR0FBRyxDQUFDLENB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QUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFO29CQUNYLE9BQU8sQ0FBQyxJQUFJLENBQUMseUNBQXlDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO2lCQUNyRTthQUNGO1lBQUMsT0FBTyxHQUFRLEVBQUU7Z0JBQ2pCLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUU7b0JBQzdCLE9BQU8sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLGFBQWEsS0FBSyxDQUFDLENBQUM7aUJBQ3JFO3FCQUFNO29CQUNMLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2lCQUM5RDthQUNGO1NBQ0Y7SUFDSCxDQUFDO0NBQ0Y7QUF6UEQsa0NBeVBDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHYXRld2F5IFRhZyDnvJPlrZggT3ZlcnJpZGUgKG5leHRNb2RlKVxuICpcbiAqIOS9v+eUqCBPcGVuTmV4dCDnmoQgbmV4dE1vZGUg5o6l5Y+j77yM6YCa6L+HIEdhdGV3YXkg5Luj55CG6K+75YaZIFRhYmxlU3RvcmXjgIJcbiAqIOmJtOadg+e7n+S4gOi1sCBydW50aW1lL2dhdGV3YXktYXV0aO+8iEhNQUMg562+5ZCNICsgNCBoZWFkZXLvvInjgIJcbiAqL1xuXG5pbXBvcnQge1xuICBsb2FkR2F0ZXdheUF1dGhDb25maWcsXG4gIGdhdGV3YXlGZXRjaCxcbiAgR2F0ZXdheUF1dGhDb25maWcsXG59IGZyb20gJy4uLy4uL3J1bnRpbWUvZ2F0ZXdheS1hdXRoJztcbmltcG9ydCB7XG4gIGxvYWRDZG5QdXJnZUNvbmZpZyxcbiAgY3JlYXRlQ2RuUHVyZ2VDbGllbnQsXG4gIENkblB1cmdlQ2xpZW50LFxufSBmcm9tICcuLi8uLi9ydW50aW1lL2Nkbi1wdXJnZSc7XG5cbmNvbnN0IFFVRVJZX1RJTUVPVVQgPSAzMDAwO1xuY29uc3QgV1JJVEVfVElNRU9VVCA9IDUwMDA7XG5jb25zdCBCQVRDSF9TSVpFID0gMjAwO1xuXG5mdW5jdGlvbiBzdHJpcExlYWRpbmdTbGFzaChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKC9eXFwvKy8sICcnKTtcbn1cblxudHlwZSBOZXh0TW9kZVRhZ0NhY2hlV3JpdGVJbnB1dCA9XG4gIHwgc3RyaW5nXG4gIHwge1xuICAgICAgdGFnOiBzdHJpbmc7XG4gICAgICBzdGFsZT86IG51bWJlcjtcbiAgICAgIGV4cGlyZT86IG51bWJlcjtcbiAgICB9O1xuXG5pbnRlcmZhY2UgVGFnUm93IHtcbiAgcmV2YWxpZGF0ZWRBdD86IG51bWJlcjtcbiAgc3RhbGU/OiBudW1iZXI7XG4gIGV4cGlyZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR2F0ZXdheVRhZ0NhY2hlIHtcbiAgbmFtZSA9ICdnYXRld2F5LXRhZy1jYWNoZScgYXMgY29uc3Q7XG4gIG1vZGUgPSAnbmV4dE1vZGUnIGFzIGNvbnN0O1xuXG4gIHByaXZhdGUgY29uZmlnOiBHYXRld2F5QXV0aENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbmZpZ0xvYWRlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgcHVyZ2VDbGllbnQ6IENkblB1cmdlQ2xpZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcHVyZ2VDbGllbnRMb2FkZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIGdldENvbmZpZygpOiBHYXRld2F5QXV0aENvbmZpZyB8IG51bGwge1xuICAgIGlmICghdGhpcy5jb25maWdMb2FkZWQpIHtcbiAgICAgIHRoaXMuY29uZmlnID0gbG9hZEdhdGV3YXlBdXRoQ29uZmlnKCk7XG4gICAgICB0aGlzLmNvbmZpZ0xvYWRlZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbmZpZztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UHVyZ2VDbGllbnQoKTogQ2RuUHVyZ2VDbGllbnQgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMucHVyZ2VDbGllbnRMb2FkZWQpIHtcbiAgICAgIGNvbnN0IGNmZyA9IGxvYWRDZG5QdXJnZUNvbmZpZygpO1xuICAgICAgdGhpcy5wdXJnZUNsaWVudCA9IGNmZyA/IGNyZWF0ZUNkblB1cmdlQ2xpZW50KGNmZykgOiBudWxsO1xuICAgICAgdGhpcy5wdXJnZUNsaWVudExvYWRlZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnB1cmdlQ2xpZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFRhZ0tleSh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuIHRhZztcbiAgICByZXR1cm4gYCR7Y29uZmlnLnZlcnNpb259LyR7c3RyaXBMZWFkaW5nU2xhc2godGFnKX1gO1xuICB9XG5cbiAgYXN5bmMgZ2V0TGFzdFJldmFsaWRhdGVkKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gMDtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5iYXRjaEdldFRhZ3MoY29uZmlnLCB0YWdzKTtcbiAgICAgIGxldCBtYXhSZXZhbGlkYXRlZEF0ID0gMDtcbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5yZXZhbGlkYXRlZEF0ICYmIHJvdy5yZXZhbGlkYXRlZEF0ID4gbWF4UmV2YWxpZGF0ZWRBdCkge1xuICAgICAgICAgIG1heFJldmFsaWRhdGVkQXQgPSByb3cucmV2YWxpZGF0ZWRBdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1heFJldmFsaWRhdGVkQXQ7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBnZXRMYXN0UmV2YWxpZGF0ZWQgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYXNCZWVuUmV2YWxpZGF0ZWQoXG4gICAgdGFnczogc3RyaW5nW10sXG4gICAgbGFzdE1vZGlmaWVkPzogbnVtYmVyXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0YWdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLmJhdGNoR2V0VGFncyhjb25maWcsIHRhZ3MpO1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGxtID0gbGFzdE1vZGlmaWVkID8/IDA7XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5leHBpcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyb3cuZXhwaXJlIDw9IG5vdyAmJiByb3cuZXhwaXJlID4gbG0pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocm93LnJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCAmJiByb3cucmV2YWxpZGF0ZWRBdCA+IGxtKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGhhc0JlZW5SZXZhbGlkYXRlZCBlcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBpc1N0YWxlKHRhZ3M6IHN0cmluZ1tdLCBsYXN0TW9kaWZpZWQ/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5iYXRjaEdldFRhZ3MoY29uZmlnLCB0YWdzKTtcbiAgICAgIGNvbnN0IGxtID0gbGFzdE1vZGlmaWVkID8/IDA7XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5zdGFsZSA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgcmV2YWxpZGF0ZWRBdCA9IHJvdy5yZXZhbGlkYXRlZEF0ID8/IDA7XG4gICAgICAgIGlmIChyZXZhbGlkYXRlZEF0ID4gbG0gJiYgcm93LnN0YWxlID49IGxtKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGlzU3RhbGUgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgd3JpdGVUYWdzKHRhZ3M6IE5leHRNb2RlVGFnQ2FjaGVXcml0ZUlucHV0W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRhZ3MgfHwgdGFncy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybjtcblxuICAgIGNvbnN0IHdyaXRlVHMgPSBEYXRlLm5vdygpO1xuXG4gICAgY29uc3Qgcm93cyA9IHRhZ3MubWFwKGlucHV0ID0+IHtcbiAgICAgIGNvbnN0IHRhZ1N0ciA9IHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgPyBpbnB1dCA6IGlucHV0LnRhZztcbiAgICAgIGNvbnN0IHN0YWxlID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IGlucHV0LnN0YWxlO1xuICAgICAgY29uc3QgZXhwaXJlID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IGlucHV0LmV4cGlyZTtcbiAgICAgIGNvbnN0IHRhZ0tleSA9IHRoaXMuYnVpbGRUYWdLZXkodGFnU3RyKTtcblxuICAgICAgY29uc3QgY29sdW1uczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBudW1iZXIgfVtdID0gW1xuICAgICAgICB7IG5hbWU6ICdyZXZhbGlkYXRlZEF0JywgdmFsdWU6IHdyaXRlVHMgfSxcbiAgICAgIF07XG4gICAgICBpZiAoc3RhbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb2x1bW5zLnB1c2goeyBuYW1lOiAnc3RhbGUnLCB2YWx1ZTogc3RhbGUgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXhwaXJlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29sdW1ucy5wdXNoKHsgbmFtZTogJ2V4cGlyZScsIHZhbHVlOiBleHBpcmUgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByaW1hcnlLZXk6IFtcbiAgICAgICAgICB7IG5hbWU6ICdhcHBfaWQnLCB2YWx1ZTogYCR7Y29uZmlnLmFsaXVpZH0vJHtjb25maWcucm91dGluZW5hbWV9YCB9LFxuICAgICAgICAgIHsgbmFtZTogJ3RhZycsIHZhbHVlOiB0YWdLZXkgfSxcbiAgICAgICAgXSxcbiAgICAgICAgY29sdW1ucyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0aGlzLmJhdGNoV3JpdGUoY29uZmlnLCByb3dzKTtcblxuICAgIC8vIOWGmeW6k+aIkOWKn+WQjixmaXJlLWFuZC1mb3JnZXQg6Kem5Y+RIEVTQSDovrnnvJjnvJPlrZjlpLHmlYjjgIJcbiAgICAvLyDku7vkvZXlpLHotKXpg73kuI3lupTlm57ngYzliLDosIPnlKjmlrks5omA5LulIGNhdGNoIOebtOaOpSB3YXJuLOS4jSB0aHJvd+OAgeS4jSBhd2FpdOOAglxuICAgIGNvbnN0IHB1cmdlQ2xpZW50ID0gdGhpcy5nZXRQdXJnZUNsaWVudCgpO1xuICAgIGlmIChwdXJnZUNsaWVudCkge1xuICAgICAgY29uc3QgdGFnU3RycyA9IHRhZ3NcbiAgICAgICAgLm1hcCh0ID0+ICh0eXBlb2YgdCA9PT0gJ3N0cmluZycgPyB0IDogdC50YWcpKVxuICAgICAgICAuZmlsdGVyKChzKTogcyBpcyBzdHJpbmcgPT4gdHlwZW9mIHMgPT09ICdzdHJpbmcnICYmIHMubGVuZ3RoID4gMCk7XG4gICAgICBpZiAodGFnU3Rycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHB1cmdlQ2xpZW50LnB1cmdlQnlUYWdzKHRhZ1N0cnMpLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIHB1cmdlIGZhbi1vdXQgZmFpbGVkOiAke2Vycj8ubWVzc2FnZSA/PyBlcnJ9YCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0gcHJpdmF0ZSBtZXRob2RzIC0tLS1cblxuICBwcml2YXRlIGFzeW5jIGJhdGNoR2V0VGFncyhcbiAgICBjb25maWc6IEdhdGV3YXlBdXRoQ29uZmlnLFxuICAgIHRhZ3M6IHN0cmluZ1tdXG4gICk6IFByb21pc2U8VGFnUm93W10+IHtcbiAgICBjb25zdCBwcmltYXJ5S2V5cyA9IHRhZ3MubWFwKHRhZyA9PiBbXG4gICAgICB7IG5hbWU6ICdhcHBfaWQnLCB2YWx1ZTogYCR7Y29uZmlnLmFsaXVpZH0vJHtjb25maWcucm91dGluZW5hbWV9YCB9LFxuICAgICAgeyBuYW1lOiAndGFnJywgdmFsdWU6IHRoaXMuYnVpbGRUYWdLZXkodGFnKSB9LFxuICAgIF0pO1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNvbmZpZywgJy90YWJsZS9iYXRjaC1nZXQtcm93Jywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcHJpbWFyeUtleXMgfSksXG4gICAgICB0aW1lb3V0TXM6IFFVRVJZX1RJTUVPVVQsXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlcy5vaykge1xuICAgICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSB8fCByZXMuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IHJlamVjdGVkICgke3Jlcy5zdGF0dXN9KWBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IGZhaWxlZDogc3RhdHVzPSR7cmVzLnN0YXR1c31gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIHtcbiAgICAgIHJvd3M/OiB7XG4gICAgICAgIHByaW1hcnlLZXk/OiBhbnlbXTtcbiAgICAgICAgY29sdW1ucz86IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogbnVtYmVyIH1bXTtcbiAgICAgIH1bXTtcbiAgICB9O1xuXG4gICAgaWYgKCFkYXRhLnJvd3MpIHJldHVybiBbXTtcblxuICAgIHJldHVybiBkYXRhLnJvd3MubWFwKHJvdyA9PiB7XG4gICAgICBjb25zdCByZXN1bHQ6IFRhZ1JvdyA9IHt9O1xuICAgICAgZm9yIChjb25zdCBjb2wgb2Ygcm93LmNvbHVtbnMgPz8gW10pIHtcbiAgICAgICAgaWYgKGNvbC5uYW1lID09PSAncmV2YWxpZGF0ZWRBdCcgJiYgdHlwZW9mIGNvbC52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXN1bHQucmV2YWxpZGF0ZWRBdCA9IGNvbC52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2wubmFtZSA9PT0gJ3N0YWxlJyAmJiB0eXBlb2YgY29sLnZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJlc3VsdC5zdGFsZSA9IGNvbC52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2wubmFtZSA9PT0gJ2V4cGlyZScgJiYgdHlwZW9mIGNvbC52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXN1bHQuZXhwaXJlID0gY29sLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBiYXRjaFdyaXRlKFxuICAgIGNvbmZpZzogR2F0ZXdheUF1dGhDb25maWcsXG4gICAgcm93czoge1xuICAgICAgcHJpbWFyeUtleTogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfVtdO1xuICAgICAgY29sdW1uczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfVtdO1xuICAgIH1bXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocm93cy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkgKz0gQkFUQ0hfU0laRSkge1xuICAgICAgY29uc3QgYmF0Y2ggPSByb3dzLnNsaWNlKGksIGkgKyBCQVRDSF9TSVpFKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNvbmZpZywgJy90YWJsZS9iYXRjaC13cml0ZScsIHtcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHJvd3M6IGJhdGNoIH0pLFxuICAgICAgICAgIHRpbWVvdXRNczogV1JJVEVfVElNRU9VVCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSB8fCByZXMuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgYFt0YWdDYWNoZV0gYmF0Y2gtd3JpdGUgcmVqZWN0ZWQgKCR7cmVzLnN0YXR1c30pYFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFyZXMub2spIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYFt0YWdDYWNoZV0gYmF0Y2gtd3JpdGUgZmFpbGVkOiBzdGF0dXM9JHtyZXMuc3RhdHVzfWApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBpZiAoZXJyLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBiYXRjaC13cml0ZSB0aW1lb3V0ICgke1dSSVRFX1RJTUVPVVR9bXMpYCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGJhdGNoLXdyaXRlIGVycm9yOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDN Purge Runtime
|
|
3
|
+
*
|
|
4
|
+
* 在 revalidateTag / revalidatePath 后,fire-and-forget 触发 ESA 边缘缓存失效。
|
|
5
|
+
*
|
|
6
|
+
* 设计原则:
|
|
7
|
+
* - tag → paths 反查走 **本地** manifest(build 时由 pcg build 把
|
|
8
|
+
* .open-next/dynamodb-provider/dynamodb-cache.json 嵌入 FC bundle),
|
|
9
|
+
* 运行时第一次用到时 lazy 加载到内存 Map,后续 O(1) 查询,无网络往返
|
|
10
|
+
* - /cache/refresh 走 Gateway,沿用现有 HMAC 鉴权 + ESA 分流
|
|
11
|
+
* - 所有失败仅 warn,绝不抛错(purge 是优化,不是正确性)
|
|
12
|
+
* - hostname / siteId 缺失则 loadCdnPurgeConfig 返回 null,调用方降级 no-op
|
|
13
|
+
* - 跨 tag 反查结果去重,每 path 追加 /_next/data/{buildId}/{path}.json
|
|
14
|
+
* - 调 /cache/refresh 时按 100 URL/批、batch 内并发上限 4
|
|
15
|
+
*/
|
|
16
|
+
import { GatewayAuthConfig } from './gateway-auth';
|
|
17
|
+
export interface CdnPurgeConfig extends GatewayAuthConfig {
|
|
18
|
+
hostname: string;
|
|
19
|
+
siteId: string | number;
|
|
20
|
+
/**
|
|
21
|
+
* 覆盖默认 manifest 路径,主要给测试用。
|
|
22
|
+
* 默认 = path.join(__dirname, '__pcg_tag_manifest.json'),
|
|
23
|
+
* 即 FC bundle 内与 cache.cjs 同级。
|
|
24
|
+
*/
|
|
25
|
+
manifestPath?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface CdnPurgeClient {
|
|
28
|
+
/**
|
|
29
|
+
* 异步触发 ESA 缓存失效。不阻塞调用方,失败仅 warn。
|
|
30
|
+
* 内部完成 path 去重 + ISR 数据路径补全 + 限流。
|
|
31
|
+
*/
|
|
32
|
+
purgeByPaths(paths: string[]): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* tag → paths 反查 + purge。
|
|
35
|
+
* 反查走本地嵌入的 manifest 文件,无网络 IO。
|
|
36
|
+
*/
|
|
37
|
+
purgeByTags(tags: string[]): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 从环境变量加载 purge 配置。
|
|
41
|
+
*
|
|
42
|
+
* 沿用 loadGatewayAuthConfig 的 5 个 env,额外读取:
|
|
43
|
+
* - ESA_CACHE_GW_HOSTNAME — 拼 purge URL 用
|
|
44
|
+
* - ESA_CACHE_GW_SITE_ID — 透传给 /cache/refresh
|
|
45
|
+
*
|
|
46
|
+
* 缺一返回 null,调用方应跳过 purge(不影响 tag 写库)。
|
|
47
|
+
*/
|
|
48
|
+
export declare function loadCdnPurgeConfig(): CdnPurgeConfig | null;
|
|
49
|
+
export declare function createCdnPurgeClient(cfg: CdnPurgeConfig): CdnPurgeClient;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CDN Purge Runtime
|
|
4
|
+
*
|
|
5
|
+
* 在 revalidateTag / revalidatePath 后,fire-and-forget 触发 ESA 边缘缓存失效。
|
|
6
|
+
*
|
|
7
|
+
* 设计原则:
|
|
8
|
+
* - tag → paths 反查走 **本地** manifest(build 时由 pcg build 把
|
|
9
|
+
* .open-next/dynamodb-provider/dynamodb-cache.json 嵌入 FC bundle),
|
|
10
|
+
* 运行时第一次用到时 lazy 加载到内存 Map,后续 O(1) 查询,无网络往返
|
|
11
|
+
* - /cache/refresh 走 Gateway,沿用现有 HMAC 鉴权 + ESA 分流
|
|
12
|
+
* - 所有失败仅 warn,绝不抛错(purge 是优化,不是正确性)
|
|
13
|
+
* - hostname / siteId 缺失则 loadCdnPurgeConfig 返回 null,调用方降级 no-op
|
|
14
|
+
* - 跨 tag 反查结果去重,每 path 追加 /_next/data/{buildId}/{path}.json
|
|
15
|
+
* - 调 /cache/refresh 时按 100 URL/批、batch 内并发上限 4
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.createCdnPurgeClient = exports.loadCdnPurgeConfig = void 0;
|
|
19
|
+
const fs = require("fs");
|
|
20
|
+
const path = require("path");
|
|
21
|
+
const gateway_auth_1 = require("./gateway-auth");
|
|
22
|
+
const REFRESH_TIMEOUT_MS = 15000;
|
|
23
|
+
const URL_BATCH_SIZE = 100;
|
|
24
|
+
const REFRESH_CONCURRENCY = 4;
|
|
25
|
+
// 与 build.ts 中 TAG_MANIFEST_FILENAME 保持一致(对侧是写入,这侧是读取)
|
|
26
|
+
const TAG_MANIFEST_FILENAME = '__pcg_tag_manifest.json';
|
|
27
|
+
function stripLeadingSlash(s) {
|
|
28
|
+
return s.replace(/^\/+/, '');
|
|
29
|
+
}
|
|
30
|
+
function ensureLeadingSlash(s) {
|
|
31
|
+
return s.startsWith('/') ? s : `/${s}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 从环境变量加载 purge 配置。
|
|
35
|
+
*
|
|
36
|
+
* 沿用 loadGatewayAuthConfig 的 5 个 env,额外读取:
|
|
37
|
+
* - ESA_CACHE_GW_HOSTNAME — 拼 purge URL 用
|
|
38
|
+
* - ESA_CACHE_GW_SITE_ID — 透传给 /cache/refresh
|
|
39
|
+
*
|
|
40
|
+
* 缺一返回 null,调用方应跳过 purge(不影响 tag 写库)。
|
|
41
|
+
*/
|
|
42
|
+
function loadCdnPurgeConfig() {
|
|
43
|
+
const base = (0, gateway_auth_1.loadGatewayAuthConfig)();
|
|
44
|
+
if (!base)
|
|
45
|
+
return null;
|
|
46
|
+
const hostname = process.env.ESA_CACHE_GW_HOSTNAME;
|
|
47
|
+
const siteIdRaw = process.env.ESA_CACHE_GW_SITE_ID;
|
|
48
|
+
if (!hostname || !siteIdRaw) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const siteIdNum = Number(siteIdRaw);
|
|
52
|
+
const siteId = Number.isFinite(siteIdNum)
|
|
53
|
+
? siteIdNum
|
|
54
|
+
: siteIdRaw;
|
|
55
|
+
return {
|
|
56
|
+
...base,
|
|
57
|
+
hostname,
|
|
58
|
+
siteId,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
exports.loadCdnPurgeConfig = loadCdnPurgeConfig;
|
|
62
|
+
function createCdnPurgeClient(cfg) {
|
|
63
|
+
var _a;
|
|
64
|
+
const buildId = cfg.version;
|
|
65
|
+
const pathPrefix = `${buildId}/`;
|
|
66
|
+
const manifestPath = (_a = cfg.manifestPath) !== null && _a !== void 0 ? _a : path.join(__dirname, TAG_MANIFEST_FILENAME);
|
|
67
|
+
// lazy 加载;Promise 用于并发首次调用的合流
|
|
68
|
+
let manifestPromise = null;
|
|
69
|
+
async function loadManifest() {
|
|
70
|
+
if (manifestPromise)
|
|
71
|
+
return manifestPromise;
|
|
72
|
+
manifestPromise = (async () => {
|
|
73
|
+
var _a, _b, _c, _d;
|
|
74
|
+
const map = new Map();
|
|
75
|
+
let raw;
|
|
76
|
+
try {
|
|
77
|
+
raw = await fs.promises.readFile(manifestPath, 'utf-8');
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
// ENOENT 是常见情况(纯静态项目无 tag,或老版 CLI 未嵌入),静默降级
|
|
81
|
+
if ((err === null || err === void 0 ? void 0 : err.code) !== 'ENOENT') {
|
|
82
|
+
console.warn(`[cdn-purge] manifest read error ${manifestPath}: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
83
|
+
}
|
|
84
|
+
return new Map();
|
|
85
|
+
}
|
|
86
|
+
let rows;
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(raw);
|
|
89
|
+
rows = Array.isArray(parsed) ? parsed : [];
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
console.warn(`[cdn-purge] manifest parse error ${manifestPath}: ${(_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : err}`);
|
|
93
|
+
return new Map();
|
|
94
|
+
}
|
|
95
|
+
for (const row of rows) {
|
|
96
|
+
const tagPk = (_c = row === null || row === void 0 ? void 0 : row.tag) === null || _c === void 0 ? void 0 : _c.S;
|
|
97
|
+
const pathPk = (_d = row === null || row === void 0 ? void 0 : row.path) === null || _d === void 0 ? void 0 : _d.S;
|
|
98
|
+
if (typeof tagPk !== 'string' || typeof pathPk !== 'string')
|
|
99
|
+
continue;
|
|
100
|
+
// 只接受当前 buildId 的行;OpenNext 已保证 prefix,但万一混入旧行就跳过
|
|
101
|
+
if (!tagPk.startsWith(pathPrefix))
|
|
102
|
+
continue;
|
|
103
|
+
if (!pathPk.startsWith(pathPrefix))
|
|
104
|
+
continue;
|
|
105
|
+
const tag = tagPk.slice(pathPrefix.length);
|
|
106
|
+
const p = pathPk.slice(pathPrefix.length);
|
|
107
|
+
if (!tag || !p)
|
|
108
|
+
continue;
|
|
109
|
+
let bucket = map.get(tag);
|
|
110
|
+
if (!bucket) {
|
|
111
|
+
bucket = new Set();
|
|
112
|
+
map.set(tag, bucket);
|
|
113
|
+
}
|
|
114
|
+
bucket.add(p);
|
|
115
|
+
}
|
|
116
|
+
const result = new Map();
|
|
117
|
+
for (const [tag, set] of map) {
|
|
118
|
+
result.set(tag, Array.from(set));
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
})();
|
|
122
|
+
return manifestPromise;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 把若干 Next 路由 path 展开成需 purge 的 URL 列表:
|
|
126
|
+
* - 跳过空串、去重(基于规范化后的 leading "/")
|
|
127
|
+
* - 对每个 path 追加 /_next/data/{buildId}/{path}.json
|
|
128
|
+
* - 拼上 https://{hostname}
|
|
129
|
+
*/
|
|
130
|
+
function expandPathsToUrls(paths) {
|
|
131
|
+
const normalized = new Set();
|
|
132
|
+
for (const p of paths) {
|
|
133
|
+
if (!p)
|
|
134
|
+
continue;
|
|
135
|
+
normalized.add(ensureLeadingSlash(p));
|
|
136
|
+
}
|
|
137
|
+
if (normalized.size === 0)
|
|
138
|
+
return [];
|
|
139
|
+
const urls = new Set();
|
|
140
|
+
for (const p of normalized) {
|
|
141
|
+
urls.add(`https://${cfg.hostname}${p}`);
|
|
142
|
+
const rel = stripLeadingSlash(p);
|
|
143
|
+
// pages router ISR 必需;app router 多打一条无副作用
|
|
144
|
+
urls.add(`https://${cfg.hostname}/_next/data/${buildId}/${rel || 'index'}.json`);
|
|
145
|
+
}
|
|
146
|
+
return Array.from(urls);
|
|
147
|
+
}
|
|
148
|
+
async function refreshBatch(urls) {
|
|
149
|
+
var _a;
|
|
150
|
+
const body = {
|
|
151
|
+
hostname: cfg.hostname,
|
|
152
|
+
siteId: cfg.siteId,
|
|
153
|
+
urls,
|
|
154
|
+
};
|
|
155
|
+
let res;
|
|
156
|
+
try {
|
|
157
|
+
res = await (0, gateway_auth_1.gatewayFetch)(cfg, '/cache/refresh', {
|
|
158
|
+
method: 'POST',
|
|
159
|
+
headers: { 'Content-Type': 'application/json' },
|
|
160
|
+
body: JSON.stringify(body),
|
|
161
|
+
timeoutMs: REFRESH_TIMEOUT_MS,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
console.warn(`[cdn-purge] cache/refresh error (${urls.length} urls): ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (!res.ok) {
|
|
169
|
+
let detail = '';
|
|
170
|
+
try {
|
|
171
|
+
detail = (await res.text()).slice(0, 200);
|
|
172
|
+
}
|
|
173
|
+
catch (_b) {
|
|
174
|
+
/* ignore */
|
|
175
|
+
}
|
|
176
|
+
console.warn(`[cdn-purge] cache/refresh failed status=${res.status} urls=${urls.length} ${detail}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async function refreshUrls(allUrls) {
|
|
180
|
+
if (allUrls.length === 0)
|
|
181
|
+
return;
|
|
182
|
+
const batches = [];
|
|
183
|
+
for (let i = 0; i < allUrls.length; i += URL_BATCH_SIZE) {
|
|
184
|
+
batches.push(allUrls.slice(i, i + URL_BATCH_SIZE));
|
|
185
|
+
}
|
|
186
|
+
// 并发上限 REFRESH_CONCURRENCY 的滑动窗口
|
|
187
|
+
let cursor = 0;
|
|
188
|
+
async function worker() {
|
|
189
|
+
while (cursor < batches.length) {
|
|
190
|
+
const idx = cursor++;
|
|
191
|
+
await refreshBatch(batches[idx]);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const workers = Array.from({ length: Math.min(REFRESH_CONCURRENCY, batches.length) }, () => worker());
|
|
195
|
+
await Promise.all(workers);
|
|
196
|
+
}
|
|
197
|
+
async function purgeByPaths(paths) {
|
|
198
|
+
var _a;
|
|
199
|
+
try {
|
|
200
|
+
const urls = expandPathsToUrls(paths);
|
|
201
|
+
await refreshUrls(urls);
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
console.warn(`[cdn-purge] purgeByPaths error: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async function purgeByTags(tags) {
|
|
208
|
+
var _a;
|
|
209
|
+
try {
|
|
210
|
+
const uniqueTags = Array.from(new Set(tags
|
|
211
|
+
.map(t => (typeof t === 'string' ? t : ''))
|
|
212
|
+
.map(t => t.trim())
|
|
213
|
+
.filter(Boolean)));
|
|
214
|
+
if (uniqueTags.length === 0)
|
|
215
|
+
return;
|
|
216
|
+
const map = await loadManifest();
|
|
217
|
+
const merged = new Set();
|
|
218
|
+
for (const t of uniqueTags) {
|
|
219
|
+
const paths = map.get(t);
|
|
220
|
+
if (!paths)
|
|
221
|
+
continue;
|
|
222
|
+
for (const p of paths)
|
|
223
|
+
merged.add(p);
|
|
224
|
+
}
|
|
225
|
+
if (merged.size === 0)
|
|
226
|
+
return;
|
|
227
|
+
const urls = expandPathsToUrls(Array.from(merged));
|
|
228
|
+
await refreshUrls(urls);
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
console.warn(`[cdn-purge] purgeByTags error: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return { purgeByPaths, purgeByTags };
|
|
235
|
+
}
|
|
236
|
+
exports.createCdnPurgeClient = createCdnPurgeClient;
|
|
237
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RuLXB1cmdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvY2RuLXB1cmdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7R0FjRzs7O0FBRUgseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUU3QixpREFJd0I7QUFFeEIsTUFBTSxrQkFBa0IsR0FBRyxLQUFNLENBQUM7QUFFbEMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDO0FBQzNCLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBRTlCLHVEQUF1RDtBQUN2RCxNQUFNLHFCQUFxQixHQUFHLHlCQUF5QixDQUFDO0FBMkJ4RCxTQUFTLGlCQUFpQixDQUFDLENBQVM7SUFDbEMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxDQUFTO0lBQ25DLE9BQU8sQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO0FBQ3pDLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLGtCQUFrQjtJQUNoQyxNQUFNLElBQUksR0FBRyxJQUFBLG9DQUFxQixHQUFFLENBQUM7SUFDckMsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLElBQUksQ0FBQztJQUV2QixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDO0lBQ25ELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7SUFFbkQsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFNBQVMsRUFBRTtRQUMzQixPQUFPLElBQUksQ0FBQztLQUNiO0lBRUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3BD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LE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDdEM7WUFDRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQztnQkFBRSxPQUFPO1lBRTlCLE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNuRCxNQUFNLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN6QjtRQUFDLE9BQU8sR0FBUSxFQUFFO1lBQ2pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLE1BQUEsR0FBRyxhQUFILEdBQUcsdUJBQUgsR0FBRyxDQUFFLE9BQU8sbUNBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztTQUN2RTtJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxDQUFDO0FBQ3ZDLENBQUM7QUEzTEQsb0RBMkxDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDRE4gUHVyZ2UgUnVudGltZVxuICpcbiAqIOWcqCByZXZhbGlkYXRlVGFnIC8gcmV2YWxpZGF0ZVBhdGgg5ZCOLGZpcmUtYW5kLWZvcmdldCDop6blj5EgRVNBIOi+uee8mOe8k+WtmOWkseaViOOAglxuICpcbiAqIOiuvuiuoeWOn+WImTpcbiAqICAgLSB0YWcg4oaSIHBhdGhzIOWPjeafpei1sCAqKuacrOWcsCoqIG1hbmlmZXN0KGJ1aWxkIOaXtueUsSBwY2cgYnVpbGQg5oqKXG4gKiAgICAgLm9wZW4tbmV4dC9keW5hbW9kYi1wcm92aWRlci9keW5hbW9kYi1jYWNoZS5qc29uIOW1jOWFpSBGQyBidW5kbGUpLFxuICogICAgIOi/kOihjOaXtuesrOS4gOasoeeUqOWIsOaXtiBsYXp5IOWKoOi9veWIsOWGheWtmCBNYXAs5ZCO57utIE8oMSkg5p+l6K+iLOaXoOe9kee7nOW+gOi/lFxuICogICAtIC9jYWNoZS9yZWZyZXNoIOi1sCBHYXRld2F5LOayv+eUqOeOsOaciSBITUFDIOmJtOadgyArIEVTQSDliIbmtYFcbiAqICAgLSDmiYDmnInlpLHotKXku4Ugd2Fybiznu53kuI3mipvplJkocHVyZ2Ug5piv5LyY5YyWLOS4jeaYr+ato+ehruaApylcbiAqICAgLSBob3N0bmFtZSAvIHNpdGVJZCDnvLrlpLHliJkgbG9hZENkblB1cmdlQ29uZmlnIOi/lOWbniBudWxsLOiwg+eUqOaWuemZjee6pyBuby1vcFxuICogICAtIOi3qCB0YWcg5Y+N5p+l57uT5p6c5Y676YeNLOavjyBwYXRoIOi/veWKoCAvX25leHQvZGF0YS97YnVpbGRJZH0ve3BhdGh9Lmpzb25cbiAqICAgLSDosIMgL2NhY2hlL3JlZnJlc2gg5pe25oyJIDEwMCBVUkwv5om544CBYmF0Y2gg5YaF5bm25Y+R5LiK6ZmQIDRcbiAqL1xuXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ2FjaGVSZWZyZXNoUmVxdWVzdCB9IGZyb20gJ0BwY2cvcHJvdG9jb2wnO1xuaW1wb3J0IHtcbiAgbG9hZEdhdGV3YXlBdXRoQ29uZmlnLFxuICBnYXRld2F5RmV0Y2gsXG4gIEdhdGV3YXlBdXRoQ29uZmlnLFxufSBmcm9tICcuL2dhdGV3YXktYXV0aCc7XG5cbmNvbnN0IFJFRlJFU0hfVElNRU9VVF9NUyA9IDE1XzAwMDtcblxuY29uc3QgVVJMX0JBVENIX1NJWkUgPSAxMDA7XG5jb25zdCBSRUZSRVNIX0NPTkNVUlJFTkNZID0gNDtcblxuLy8g5LiOIGJ1aWxkLnRzIOS4rSBUQUdfTUFOSUZFU1RfRklMRU5BTUUg5L+d5oyB5LiA6Ie0KOWvueS+p+aYr+WGmeWFpSzov5nkvqfmmK/or7vlj5YpXG5jb25zdCBUQUdfTUFOSUZFU1RfRklMRU5BTUUgPSAnX19wY2dfdGFnX21hbmlmZXN0Lmpzb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIENkblB1cmdlQ29uZmlnIGV4dGVuZHMgR2F0ZXdheUF1dGhDb25maWcge1xuICBob3N0bmFtZTogc3RyaW5nO1xuICBzaXRlSWQ6IHN0cmluZyB8IG51bWJlcjtcbiAgLyoqXG4gICAqIOimhueblum7mOiupCBtYW5pZmVzdCDot6/lvoQs5Li76KaB57uZ5rWL6K+V55So44CCXG4gICAqIOm7mOiupCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdfX3BjZ190YWdfbWFuaWZlc3QuanNvbicpLFxuICAgKiDljbMgRkMgYnVuZGxlIOWGheS4jiBjYWNoZS5janMg5ZCM57qn44CCXG4gICAqL1xuICBtYW5pZmVzdFBhdGg/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2RuUHVyZ2VDbGllbnQge1xuICAvKipcbiAgICog5byC5q2l6Kem5Y+RIEVTQSDnvJPlrZjlpLHmlYjjgILkuI3pmLvloZ7osIPnlKjmlrks5aSx6LSl5LuFIHdhcm7jgIJcbiAgICog5YaF6YOo5a6M5oiQIHBhdGgg5Y676YeNICsgSVNSIOaVsOaNrui3r+W+hOihpeWFqCArIOmZkOa1geOAglxuICAgKi9cbiAgcHVyZ2VCeVBhdGhzKHBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD47XG5cbiAgLyoqXG4gICAqIHRhZyDihpIgcGF0aHMg5Y+N5p+lICsgcHVyZ2XjgIJcbiAgICog5Y+N5p+l6LWw5pys5Zyw5bWM5YWl55qEIG1hbmlmZXN0IOaWh+S7tizml6DnvZHnu5wgSU/jgIJcbiAgICovXG4gIHB1cmdlQnlUYWdzKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPjtcbn1cblxuZnVuY3Rpb24gc3RyaXBMZWFkaW5nU2xhc2goczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHMucmVwbGFjZSgvXlxcLysvLCAnJyk7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUxlYWRpbmdTbGFzaChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcy5zdGFydHNXaXRoKCcvJykgPyBzIDogYC8ke3N9YDtcbn1cblxuLyoqXG4gKiDku47njq/looPlj5jph4/liqDovb0gcHVyZ2Ug6YWN572u44CCXG4gKlxuICog5rK/55SoIGxvYWRHYXRld2F5QXV0aENvbmZpZyDnmoQgNSDkuKogZW52LOmineWkluivu+WPljpcbiAqICAgLSBFU0FfQ0FDSEVfR1dfSE9TVE5BTUUg4oCUIOaLvCBwdXJnZSBVUkwg55SoXG4gKiAgIC0gRVNBX0NBQ0hFX0dXX1NJVEVfSUQgIOKAlCDpgI/kvKDnu5kgL2NhY2hlL3JlZnJlc2hcbiAqXG4gKiDnvLrkuIDov5Tlm54gbnVsbCzosIPnlKjmlrnlupTot7Pov4cgcHVyZ2Uo5LiN5b2x5ZONIHRhZyDlhpnlupMp44CCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkQ2RuUHVyZ2VDb25maWcoKTogQ2RuUHVyZ2VDb25maWcgfCBudWxsIHtcbiAgY29uc3QgYmFzZSA9IGxvYWRHYXRld2F5QXV0aENvbmZpZygpO1xuICBpZiAoIWJhc2UpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IGhvc3RuYW1lID0gcHJvY2Vzcy5lbnYuRVNBX0NBQ0hFX0dXX0hPU1ROQU1FO1xuICBjb25zdCBzaXRlSWRSYXcgPSBwcm9jZXNzLmVudi5FU0FfQ0FDSEVfR1dfU0lURV9JRDtcblxuICBpZiAoIWhvc3RuYW1lIHx8ICFzaXRlSWRSYXcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHNpdGVJZE51bSA9IE51bWJlcihzaXRlSWRSYXcpO1xuICBjb25zdCBzaXRlSWQ6IHN0cmluZyB8IG51bWJlciA9IE51bWJlci5pc0Zpbml0ZShzaXRlSWROdW0pXG4gICAgPyBzaXRlSWROdW1cbiAgICA6IHNpdGVJZFJhdztcblxuICByZXR1cm4ge1xuICAgIC4uLmJhc2UsXG4gICAgaG9zdG5hbWUsXG4gICAgc2l0ZUlkLFxuICB9O1xufVxuXG4vKipcbiAqIGR5bmFtb2RiLXByb3ZpZGVyL2R5bmFtb2RiLWNhY2hlLmpzb24g55qE6KGM5qC85byPIOKAlOKAlFxuICog55SxIE9wZW5OZXh0IGJ1aWxkIOebtOaOpeS6p+WHuizlrZfmrrXlkI3lm7rlrprkuLogRHluYW1vREIg5bGe5oCn5pig5bCE5qC85byP44CCXG4gKi9cbmludGVyZmFjZSBEeW5hbW9UYWdSb3cge1xuICB0YWc6IHsgUzogc3RyaW5nIH07XG4gIHBhdGg6IHsgUzogc3RyaW5nIH07XG4gIHJldmFsaWRhdGVkQXQ/OiB7IE46IHN0cmluZyB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2RuUHVyZ2VDbGllbnQoY2ZnOiBDZG5QdXJnZUNvbmZpZyk6IENkblB1cmdlQ2xpZW50IHtcbiAgY29uc3QgYnVpbGRJZCA9IGNmZy52ZXJzaW9uO1xuICBjb25zdCBwYXRoUHJlZml4ID0gYCR7YnVpbGRJZH0vYDtcbiAgY29uc3QgbWFuaWZlc3RQYXRoID1cbiAgICBjZmcubWFuaWZlc3RQYXRoID8/IHBhdGguam9pbihfX2Rpcm5hbWUsIFRBR19NQU5JRkVTVF9GSUxFTkFNRSk7XG5cbiAgLy8gbGF6eSDliqDovb07UHJvbWlzZSDnlKjkuo7lubblj5HpppbmrKHosIPnlKjnmoTlkIjmtYFcbiAgbGV0IG1hbmlmZXN0UHJvbWlzZTogUHJvbWlzZTxNYXA8c3RyaW5nLCBzdHJpbmdbXT4+IHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZE1hbmlmZXN0KCk6IFByb21pc2U8TWFwPHN0cmluZywgc3RyaW5nW10+PiB7XG4gICAgaWYgKG1hbmlmZXN0UHJvbWlzZSkgcmV0dXJuIG1hbmlmZXN0UHJvbWlzZTtcbiAgICBtYW5pZmVzdFByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgbWFwID0gbmV3IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+PigpO1xuICAgICAgbGV0IHJhdzogc3RyaW5nO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmF3ID0gYXdhaXQgZnMucHJvbWlzZXMucmVhZEZpbGUobWFuaWZlc3RQYXRoLCAndXRmLTgnKTtcbiAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgIC8vIEVOT0VOVCDmmK/luLjop4Hmg4XlhrUo57qv6Z2Z5oCB6aG555uu5pegIHRhZyzmiJbogIHniYggQ0xJIOacquW1jOWFpSks6Z2Z6buY6ZmN57qnXG4gICAgICAgIGlmIChlcnI/LmNvZGUgIT09ICdFTk9FTlQnKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgYFtjZG4tcHVyZ2VdIG1hbmlmZXN0IHJlYWQgZXJyb3IgJHttYW5pZmVzdFBhdGh9OiAke2Vycj8ubWVzc2FnZSA/PyBlcnJ9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBNYXA8c3RyaW5nLCBzdHJpbmdbXT4oKTtcbiAgICAgIH1cbiAgICAgIGxldCByb3dzOiBEeW5hbW9UYWdSb3dbXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UocmF3KTtcbiAgICAgICAgcm93cyA9IEFycmF5LmlzQXJyYXkocGFyc2VkKSA/IHBhcnNlZCA6IFtdO1xuICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBbY2RuLXB1cmdlXSBtYW5pZmVzdCBwYXJzZSBlcnJvciAke21hbmlmZXN0UGF0aH06ICR7ZXJyPy5tZXNzYWdlID8/IGVycn1gXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KCk7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgY29uc3QgdGFnUGsgPSByb3c/LnRhZz8uUztcbiAgICAgICAgY29uc3QgcGF0aFBrID0gcm93Py5wYXRoPy5TO1xuICAgICAgICBpZiAodHlwZW9mIHRhZ1BrICE9PSAnc3RyaW5nJyB8fCB0eXBlb2YgcGF0aFBrICE9PSAnc3RyaW5nJykgY29udGludWU7XG4gICAgICAgIC8vIOWPquaOpeWPl+W9k+WJjSBidWlsZElkIOeahOihjDtPcGVuTmV4dCDlt7Lkv53or4EgcHJlZml4LOS9huS4h+S4gOa3t+WFpeaXp+ihjOWwsei3s+i/h1xuICAgICAgICBpZiAoIXRhZ1BrLnN0YXJ0c1dpdGgocGF0aFByZWZpeCkpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIXBhdGhQay5zdGFydHNXaXRoKHBhdGhQcmVmaXgpKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgdGFnID0gdGFnUGsuc2xpY2UocGF0aFByZWZpeC5sZW5ndGgpO1xuICAgICAgICBjb25zdCBwID0gcGF0aFBrLnNsaWNlKHBhdGhQcmVmaXgubGVuZ3RoKTtcbiAgICAgICAgaWYgKCF0YWcgfHwgIXApIGNvbnRpbnVlO1xuICAgICAgICBsZXQgYnVja2V0ID0gbWFwLmdldCh0YWcpO1xuICAgICAgICBpZiAoIWJ1Y2tldCkge1xuICAgICAgICAgIGJ1Y2tldCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICAgIG1hcC5zZXQodGFnLCBidWNrZXQpO1xuICAgICAgICB9XG4gICAgICAgIGJ1Y2tldC5hZGQocCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmdbXT4oKTtcbiAgICAgIGZvciAoY29uc3QgW3RhZywgc2V0XSBvZiBtYXApIHtcbiAgICAgICAgcmVzdWx0LnNldCh0YWcsIEFycmF5LmZyb20oc2V0KSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pKCk7XG4gICAgcmV0dXJuIG1hbmlmZXN0UHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmioroi6XlubIgTmV4dCDot6/nlLEgcGF0aCDlsZXlvIDmiJDpnIAgcHVyZ2Ug55qEIFVSTCDliJfooag6XG4gICAqICAgLSDot7Pov4fnqbrkuLLjgIHljrvph40o5Z+65LqO6KeE6IyD5YyW5ZCO55qEIGxlYWRpbmcgXCIvXCIpXG4gICAqICAgLSDlr7nmr4/kuKogcGF0aCDov73liqAgL19uZXh0L2RhdGEve2J1aWxkSWR9L3twYXRofS5qc29uXG4gICAqICAgLSDmi7zkuIogaHR0cHM6Ly97aG9zdG5hbWV9XG4gICAqL1xuICBmdW5jdGlvbiBleHBhbmRQYXRoc1RvVXJscyhwYXRoczogc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgcCBvZiBwYXRocykge1xuICAgICAgaWYgKCFwKSBjb250aW51ZTtcbiAgICAgIG5vcm1hbGl6ZWQuYWRkKGVuc3VyZUxlYWRpbmdTbGFzaChwKSk7XG4gICAgfVxuICAgIGlmIChub3JtYWxpemVkLnNpemUgPT09IDApIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHVybHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHAgb2Ygbm9ybWFsaXplZCkge1xuICAgICAgdXJscy5hZGQoYGh0dHBzOi8vJHtjZmcuaG9zdG5hbWV9JHtwfWApO1xuICAgICAgY29uc3QgcmVsID0gc3RyaXBMZWFkaW5nU2xhc2gocCk7XG4gICAgICAvLyBwYWdlcyByb3V0ZXIgSVNSIOW/hemcgDthcHAgcm91dGVyIOWkmuaJk+S4gOadoeaXoOWJr+S9nOeUqFxuICAgICAgdXJscy5hZGQoXG4gICAgICAgIGBodHRwczovLyR7Y2ZnLmhvc3RuYW1lfS9fbmV4dC9kYXRhLyR7YnVpbGRJZH0vJHtyZWwgfHwgJ2luZGV4J30uanNvbmBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKHVybHMpO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVmcmVzaEJhdGNoKHVybHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYm9keTogQ2FjaGVSZWZyZXNoUmVxdWVzdCA9IHtcbiAgICAgIGhvc3RuYW1lOiBjZmcuaG9zdG5hbWUsXG4gICAgICBzaXRlSWQ6IGNmZy5zaXRlSWQsXG4gICAgICB1cmxzLFxuICAgIH07XG5cbiAgICBsZXQgcmVzOiBSZXNwb25zZTtcbiAgICB0cnkge1xuICAgICAgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNmZywgJy9jYWNoZS9yZWZyZXNoJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuICAgICAgICB0aW1lb3V0TXM6IFJFRlJFU0hfVElNRU9VVF9NUyxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBbY2RuLXB1cmdlXSBjYWNoZS9yZWZyZXNoIGVycm9yICgke3VybHMubGVuZ3RofSB1cmxzKTogJHtlcnI/Lm1lc3NhZ2UgPz8gZXJyfWBcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFyZXMub2spIHtcbiAgICAgIGxldCBkZXRhaWwgPSAnJztcbiAgICAgIHRyeSB7XG4gICAgICAgIGRldGFpbCA9IChhd2FpdCByZXMudGV4dCgpKS5zbGljZSgwLCAyMDApO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGlnbm9yZSAqL1xuICAgICAgfVxuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgW2Nkbi1wdXJnZV0gY2FjaGUvcmVmcmVzaCBmYWlsZWQgc3RhdHVzPSR7cmVzLnN0YXR1c30gdXJscz0ke3VybHMubGVuZ3RofSAke2RldGFpbH1gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlZnJlc2hVcmxzKGFsbFVybHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKGFsbFVybHMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBjb25zdCBiYXRjaGVzOiBzdHJpbmdbXVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbGxVcmxzLmxlbmd0aDsgaSArPSBVUkxfQkFUQ0hfU0laRSkge1xuICAgICAgYmF0Y2hlcy5wdXNoKGFsbFVybHMuc2xpY2UoaSwgaSArIFVSTF9CQVRDSF9TSVpFKSk7XG4gICAgfVxuXG4gICAgLy8g5bm25Y+R5LiK6ZmQIFJFRlJFU0hfQ09OQ1VSUkVOQ1kg55qE5ruR5Yqo56qX5Y+jXG4gICAgbGV0IGN1cnNvciA9IDA7XG4gICAgYXN5bmMgZnVuY3Rpb24gd29ya2VyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgd2hpbGUgKGN1cnNvciA8IGJhdGNoZXMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGlkeCA9IGN1cnNvcisrO1xuICAgICAgICBhd2FpdCByZWZyZXNoQmF0Y2goYmF0Y2hlc1tpZHhdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB3b3JrZXJzID0gQXJyYXkuZnJvbShcbiAgICAgIHsgbGVuZ3RoOiBNYXRoLm1pbihSRUZSRVNIX0NPTkNVUlJFTkNZLCBiYXRjaGVzLmxlbmd0aCkgfSxcbiAgICAgICgpID0+IHdvcmtlcigpXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbCh3b3JrZXJzKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHB1cmdlQnlQYXRocyhwYXRoczogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXJscyA9IGV4cGFuZFBhdGhzVG9VcmxzKHBhdGhzKTtcbiAgICAgIGF3YWl0IHJlZnJlc2hVcmxzKHVybHMpO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLndhcm4oYFtjZG4tcHVyZ2VdIHB1cmdlQnlQYXRocyBlcnJvcjogJHtlcnI/Lm1lc3NhZ2UgPz8gZXJyfWApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHB1cmdlQnlUYWdzKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVuaXF1ZVRhZ3MgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFxuICAgICAgICAgIHRhZ3NcbiAgICAgICAgICAgIC5tYXAodCA9PiAodHlwZW9mIHQgPT09ICdzdHJpbmcnID8gdCA6ICcnKSlcbiAgICAgICAgICAgIC5tYXAodCA9PiB0LnRyaW0oKSlcbiAgICAgICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIGlmICh1bmlxdWVUYWdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICBjb25zdCBtYXAgPSBhd2FpdCBsb2FkTWFuaWZlc3QoKTtcblxuICAgICAgY29uc3QgbWVyZ2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBmb3IgKGNvbnN0IHQgb2YgdW5pcXVlVGFncykge1xuICAgICAgICBjb25zdCBwYXRocyA9IG1hcC5nZXQodCk7XG4gICAgICAgIGlmICghcGF0aHMpIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKGNvbnN0IHAgb2YgcGF0aHMpIG1lcmdlZC5hZGQocCk7XG4gICAgICB9XG4gICAgICBpZiAobWVyZ2VkLnNpemUgPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgdXJscyA9IGV4cGFuZFBhdGhzVG9VcmxzKEFycmF5LmZyb20obWVyZ2VkKSk7XG4gICAgICBhd2FpdCByZWZyZXNoVXJscyh1cmxzKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbY2RuLXB1cmdlXSBwdXJnZUJ5VGFncyBlcnJvcjogJHtlcnI/Lm1lc3NhZ2UgPz8gZXJyfWApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IHB1cmdlQnlQYXRocywgcHVyZ2VCeVRhZ3MgfTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 解析 next.config.images 并校验 /_next/image 的 url 参数。
|
|
3
|
+
*
|
|
4
|
+
* 配置来源:OpenNext build 完成后会把解析后的完整 next.config 写到
|
|
5
|
+
* <server-bundle>/.next/required-server-files.json,images 字段就是 Next 自己
|
|
6
|
+
* 在运行时用的最终形态。直接读这个文件可以避开 next.config 的 TS/ESM/JS 三种
|
|
7
|
+
* 形态解析,也无需在 build 阶段做额外抽取。
|
|
8
|
+
*
|
|
9
|
+
* 匹配算法:复用 Next 自己的 match-remote-pattern 模块——picomatch 的 glob
|
|
10
|
+
* 语义边界(`**` 跨段、`*` 单段、`?`、`{a,b}`)自己重写很容易跟 next dev
|
|
11
|
+
* 行为漂移。Next 必然在 server bundle 的 node_modules 里,运行时 require 即可。
|
|
12
|
+
*
|
|
13
|
+
* 边界行为(已与上层对齐):
|
|
14
|
+
* - 校验失败 → 上层 400(对齐 Next 默认行为)
|
|
15
|
+
* - required-server-files.json 缺失 → warn + 放行(兼容老产物,不阻断部署)
|
|
16
|
+
* - images.unoptimized=true → 跳过校验、照常代发(用户关了 Next 优化但仍走
|
|
17
|
+
* wrapper,白名单职责让位给上游)
|
|
18
|
+
*/
|
|
19
|
+
interface RemotePattern {
|
|
20
|
+
protocol?: 'http' | 'https';
|
|
21
|
+
hostname: string;
|
|
22
|
+
port?: string;
|
|
23
|
+
pathname?: string;
|
|
24
|
+
search?: string;
|
|
25
|
+
}
|
|
26
|
+
declare type MatcherImpl = (domains: string[], remotePatterns: RemotePattern[], url: URL) => boolean;
|
|
27
|
+
export interface ValidateResult {
|
|
28
|
+
ok: boolean;
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 校验 /_next/image 的 url 是否被允许。语义对齐 Next:
|
|
33
|
+
* - 同源(host header === url 的 host,含端口)始终放行
|
|
34
|
+
* - unoptimized:true 跳过校验
|
|
35
|
+
* - 否则必须命中 domains 或 remotePatterns 之一
|
|
36
|
+
*/
|
|
37
|
+
export declare function validateImageUrl(absoluteUrl: URL, hostHeader: string): ValidateResult;
|
|
38
|
+
/** 测试用:重置缓存。生产代码不调用。 */
|
|
39
|
+
export declare function _resetImageConfigCacheForTests(): void;
|
|
40
|
+
/**
|
|
41
|
+
* 测试用:注入 matcher,绕过对真实 next 模块的 require。
|
|
42
|
+
* 传 null 模拟"matcher 不可用"分支。
|
|
43
|
+
*/
|
|
44
|
+
export declare function _setMatcherForTests(impl: MatcherImpl | null): void;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 解析 next.config.images 并校验 /_next/image 的 url 参数。
|
|
4
|
+
*
|
|
5
|
+
* 配置来源:OpenNext build 完成后会把解析后的完整 next.config 写到
|
|
6
|
+
* <server-bundle>/.next/required-server-files.json,images 字段就是 Next 自己
|
|
7
|
+
* 在运行时用的最终形态。直接读这个文件可以避开 next.config 的 TS/ESM/JS 三种
|
|
8
|
+
* 形态解析,也无需在 build 阶段做额外抽取。
|
|
9
|
+
*
|
|
10
|
+
* 匹配算法:复用 Next 自己的 match-remote-pattern 模块——picomatch 的 glob
|
|
11
|
+
* 语义边界(`**` 跨段、`*` 单段、`?`、`{a,b}`)自己重写很容易跟 next dev
|
|
12
|
+
* 行为漂移。Next 必然在 server bundle 的 node_modules 里,运行时 require 即可。
|
|
13
|
+
*
|
|
14
|
+
* 边界行为(已与上层对齐):
|
|
15
|
+
* - 校验失败 → 上层 400(对齐 Next 默认行为)
|
|
16
|
+
* - required-server-files.json 缺失 → warn + 放行(兼容老产物,不阻断部署)
|
|
17
|
+
* - images.unoptimized=true → 跳过校验、照常代发(用户关了 Next 优化但仍走
|
|
18
|
+
* wrapper,白名单职责让位给上游)
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports._setMatcherForTests = exports._resetImageConfigCacheForTests = exports.validateImageUrl = void 0;
|
|
22
|
+
const fs = require("fs");
|
|
23
|
+
const path = require("path");
|
|
24
|
+
let cachedConfig;
|
|
25
|
+
let cachedMatcher;
|
|
26
|
+
let warnedMatcherMissing = false;
|
|
27
|
+
/**
|
|
28
|
+
* 路径解析与 node-server.ts 的 assets 解析同源:wrapper 启动时
|
|
29
|
+
* process.cwd() === server-functions/default/,所以 .next 就在 cwd 下。
|
|
30
|
+
*/
|
|
31
|
+
function configFilePath() {
|
|
32
|
+
return path.resolve(process.cwd(), '.next', 'required-server-files.json');
|
|
33
|
+
}
|
|
34
|
+
function loadImageConfig() {
|
|
35
|
+
var _a, _b, _c;
|
|
36
|
+
if (cachedConfig !== undefined)
|
|
37
|
+
return cachedConfig;
|
|
38
|
+
const filePath = configFilePath();
|
|
39
|
+
let raw;
|
|
40
|
+
try {
|
|
41
|
+
raw = fs.readFileSync(filePath, 'utf-8');
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
console.warn(`[image-config] required-server-files.json not found at ${filePath} — allowing all image URLs (${(_a = err.code) !== null && _a !== void 0 ? _a : err.message})`);
|
|
45
|
+
cachedConfig = { mode: 'config-missing' };
|
|
46
|
+
return cachedConfig;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(raw);
|
|
50
|
+
const images = (_c = (_b = parsed === null || parsed === void 0 ? void 0 : parsed.config) === null || _b === void 0 ? void 0 : _b.images) !== null && _c !== void 0 ? _c : {};
|
|
51
|
+
cachedConfig = {
|
|
52
|
+
mode: 'loaded',
|
|
53
|
+
images: {
|
|
54
|
+
remotePatterns: Array.isArray(images.remotePatterns)
|
|
55
|
+
? images.remotePatterns
|
|
56
|
+
: [],
|
|
57
|
+
domains: Array.isArray(images.domains) ? images.domains : [],
|
|
58
|
+
unoptimized: images.unoptimized === true,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
return cachedConfig;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
console.warn(`[image-config] failed to parse ${filePath}: ${err.message} — allowing all image URLs`);
|
|
65
|
+
cachedConfig = { mode: 'config-missing' };
|
|
66
|
+
return cachedConfig;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 拿 Next 自己的 hasRemoteMatch。失败一次后缓存 null,后续走严格 deny 分支。
|
|
71
|
+
* 用 eval('require') 让 esbuild 不去尝试解析 next 模块——wrapper bundle 由
|
|
72
|
+
* scripts/bundle-overrides.js 用 esbuild 打包,把 next 标了 external 是 belt-
|
|
73
|
+
* and-suspenders;eval 这一层确保即便 external 配错也打不进 bundle。
|
|
74
|
+
*/
|
|
75
|
+
function loadMatcher() {
|
|
76
|
+
if (cachedMatcher !== undefined)
|
|
77
|
+
return cachedMatcher;
|
|
78
|
+
try {
|
|
79
|
+
const dynamicRequire = eval('require');
|
|
80
|
+
const mod = dynamicRequire('next/dist/shared/lib/match-remote-pattern');
|
|
81
|
+
const hasRemoteMatch = mod === null || mod === void 0 ? void 0 : mod.hasRemoteMatch;
|
|
82
|
+
if (typeof hasRemoteMatch !== 'function') {
|
|
83
|
+
throw new Error('hasRemoteMatch not exported');
|
|
84
|
+
}
|
|
85
|
+
cachedMatcher = hasRemoteMatch;
|
|
86
|
+
return cachedMatcher;
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
if (!warnedMatcherMissing) {
|
|
90
|
+
warnedMatcherMissing = true;
|
|
91
|
+
console.warn(`[image-config] cannot load next/dist/shared/lib/match-remote-pattern (${err.message}) — falling back to deny-external-only mode`);
|
|
92
|
+
}
|
|
93
|
+
cachedMatcher = null;
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 校验 /_next/image 的 url 是否被允许。语义对齐 Next:
|
|
99
|
+
* - 同源(host header === url 的 host,含端口)始终放行
|
|
100
|
+
* - unoptimized:true 跳过校验
|
|
101
|
+
* - 否则必须命中 domains 或 remotePatterns 之一
|
|
102
|
+
*/
|
|
103
|
+
function validateImageUrl(absoluteUrl, hostHeader) {
|
|
104
|
+
const cfg = loadImageConfig();
|
|
105
|
+
if (cfg.mode === 'config-missing') {
|
|
106
|
+
return { ok: true, reason: 'config-missing' };
|
|
107
|
+
}
|
|
108
|
+
const { images } = cfg;
|
|
109
|
+
if (images.unoptimized) {
|
|
110
|
+
return { ok: true, reason: 'unoptimized' };
|
|
111
|
+
}
|
|
112
|
+
// host header 通常带端口,absoluteUrl.hostname 不带 —— 用 url.host(含端口)
|
|
113
|
+
// 比较;同时小写化避免大小写差异。
|
|
114
|
+
const reqHost = hostHeader.toLowerCase();
|
|
115
|
+
const urlHost = absoluteUrl.host.toLowerCase();
|
|
116
|
+
if (reqHost && reqHost === urlHost) {
|
|
117
|
+
return { ok: true, reason: 'same-origin' };
|
|
118
|
+
}
|
|
119
|
+
const matcher = loadMatcher();
|
|
120
|
+
if (matcher === null) {
|
|
121
|
+
return { ok: false, reason: 'matcher-unavailable' };
|
|
122
|
+
}
|
|
123
|
+
if (matcher(images.domains, images.remotePatterns, absoluteUrl)) {
|
|
124
|
+
return { ok: true, reason: 'pattern-match' };
|
|
125
|
+
}
|
|
126
|
+
return { ok: false, reason: 'remote-pattern-not-matched' };
|
|
127
|
+
}
|
|
128
|
+
exports.validateImageUrl = validateImageUrl;
|
|
129
|
+
/** 测试用:重置缓存。生产代码不调用。 */
|
|
130
|
+
function _resetImageConfigCacheForTests() {
|
|
131
|
+
cachedConfig = undefined;
|
|
132
|
+
cachedMatcher = undefined;
|
|
133
|
+
warnedMatcherMissing = false;
|
|
134
|
+
}
|
|
135
|
+
exports._resetImageConfigCacheForTests = _resetImageConfigCacheForTests;
|
|
136
|
+
/**
|
|
137
|
+
* 测试用:注入 matcher,绕过对真实 next 模块的 require。
|
|
138
|
+
* 传 null 模拟"matcher 不可用"分支。
|
|
139
|
+
*/
|
|
140
|
+
function _setMatcherForTests(impl) {
|
|
141
|
+
cachedMatcher = impl;
|
|
142
|
+
}
|
|
143
|
+
exports._setMatcherForTests = _setMatcherForTests;
|
|
144
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvaW1hZ2UtY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7OztBQUVILHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUEwQjdCLElBQUksWUFBc0MsQ0FBQztBQUMzQyxJQUFJLGFBQTZDLENBQUM7QUFDbEQsSUFBSSxvQkFBb0IsR0FBRyxLQUFLLENBQUM7QUFFakM7OztHQUdHO0FBQ0gsU0FBUyxjQUFjO0lBQ3JCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLDRCQUE0QixDQUFDLENBQUM7QUFDNUUsQ0FBQztBQUVELFNBQVMsZUFBZTs7SUFDdEIsSUFBSSxZQUFZLEtBQUssU0FBUztRQUFFLE9BQU8sWUFBWSxDQUFDO0lBRXBELE1BQU0sUUFBUSxHQUFHLGNBQWMsRUFBRSxDQUFDO0lBQ2xDLElBQUksR0FBVyxDQUFDO0lBQ2hCLElBQUk7UUFDRixHQUFHLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7S0FDMUM7SUFBQyxPQUFPLEdBQVEsRUFBRTtRQUNqQixPQUFPLENBQUMsSUFBSSxDQUNWLDBEQUEwRCxRQUFRLCtCQUErQixNQUFBLEdBQUcsQ0FBQyxJQUFJLG1DQUFJLEdBQUcsQ0FBQyxPQUFPLEdBQUcsQ0FDNUgsQ0FBQztRQUNGLFlBQVksR0FBRyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO1FBQzFDLE9BQU8sWUFBWSxDQUFDO0tBQ3JCO0lBRUQsSUFBSTtRQUNGLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsTUFBTSxNQUFNLEdBQUcsTUFBQSxNQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxN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QUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUscUJBQXFCLEVBQUUsQ0FBQztLQUNyRDtJQUNELElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLGNBQWMsRUFBRSxXQUFXLENBQUMsRUFBRTtRQUMvRCxPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLENBQUM7S0FDOUM7SUFDRCxPQUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsNEJBQTRCLEVBQUUsQ0FBQztBQUM3RCxDQUFDO0FBOUJELDRDQThCQztBQUVELHdCQUF3QjtBQUN4QixTQUFnQiw4QkFBOEI7SUFDNUMsWUFBWSxHQUFHLFNBQVMsQ0FBQztJQUN6QixhQUFhLEdBQUcsU0FBUyxDQUFDO0lBQzFCLG9CQUFvQixHQUFHLEtBQUssQ0FBQztBQUMvQixDQUFDO0FBSkQsd0VBSUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxJQUF3QjtJQUMxRCxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQ3ZCLENBQUM7QUFGRCxrREFFQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog6Kej5p6QIG5leHQuY29uZmlnLmltYWdlcyDlubbmoKHpqowgL19uZXh0L2ltYWdlIOeahCB1cmwg5Y+C5pWw44CCXG4gKlxuICog6YWN572u5p2l5rqQOk9wZW5OZXh0IGJ1aWxkIOWujOaIkOWQjuS8muaKiuino+aekOWQjueahOWujOaVtCBuZXh0LmNvbmZpZyDlhpnliLBcbiAqIDxzZXJ2ZXItYnVuZGxlPi8ubmV4dC9yZXF1aXJlZC1zZXJ2ZXItZmlsZXMuanNvbixpbWFnZXMg5a2X5q615bCx5pivIE5leHQg6Ieq5bexXG4gKiDlnKjov5DooYzml7bnlKjnmoTmnIDnu4jlvaLmgIHjgILnm7TmjqXor7vov5nkuKrmlofku7blj6/ku6Xpgb/lvIAgbmV4dC5jb25maWcg55qEIFRTL0VTTS9KUyDkuInnp41cbiAqIOW9ouaAgeino+aekCzkuZ/ml6DpnIDlnKggYnVpbGQg6Zi25q615YGa6aKd5aSW5oq95Y+W44CCXG4gKlxuICog5Yy56YWN566X5rOVOuWkjeeUqCBOZXh0IOiHquW3seeahCBtYXRjaC1yZW1vdGUtcGF0dGVybiDmqKHlnZfigJTigJRwaWNvbWF0Y2gg55qEIGdsb2JcbiAqIOivreS5iei+ueeVjChgKipgIOi3qOauteOAgWAqYCDljZXmrrXjgIFgP2DjgIFge2EsYn1gKeiHquW3semHjeWGmeW+iOWuueaYk+i3nyBuZXh0IGRldlxuICog6KGM5Li65ryC56e744CCTmV4dCDlv4XnhLblnKggc2VydmVyIGJ1bmRsZSDnmoQgbm9kZV9tb2R1bGVzIOmHjCzov5DooYzml7YgcmVxdWlyZSDljbPlj6/jgIJcbiAqXG4gKiDovrnnlYzooYzkuLoo5bey5LiO5LiK5bGC5a+56b2QKTpcbiAqIC0g5qCh6aqM5aSx6LSlIOKGkiDkuIrlsYIgNDAwKOWvuem9kCBOZXh0IOm7mOiupOihjOS4uilcbiAqIC0gcmVxdWlyZWQtc2VydmVyLWZpbGVzLmpzb24g57y65aSxIOKGkiB3YXJuICsg5pS+6KGMKOWFvOWuueiAgeS6p+eJqSzkuI3pmLvmlq3pg6jnvbIpXG4gKiAtIGltYWdlcy51bm9wdGltaXplZD10cnVlIOKGkiDot7Pov4fmoKHpqozjgIHnhafluLjku6Plj5Eo55So5oi35YWz5LqGIE5leHQg5LyY5YyW5L2G5LuN6LWwXG4gKiAgIHdyYXBwZXIs55m95ZCN5Y2V6IGM6LSj6K6p5L2N57uZ5LiK5ri4KVxuICovXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5cbmludGVyZmFjZSBSZW1vdGVQYXR0ZXJuIHtcbiAgcHJvdG9jb2w/OiAnaHR0cCcgfCAnaHR0cHMnO1xuICBob3N0bmFtZTogc3RyaW5nO1xuICBwb3J0Pzogc3RyaW5nO1xuICBwYXRobmFtZT86IHN0cmluZztcbiAgc2VhcmNoPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgSW1hZ2VzQ29uZmlnIHtcbiAgcmVtb3RlUGF0dGVybnM6IFJlbW90ZVBhdHRlcm5bXTtcbiAgZG9tYWluczogc3RyaW5nW107XG4gIHVub3B0aW1pemVkOiBib29sZWFuO1xufVxuXG50eXBlIExvYWRlZENvbmZpZyA9XG4gIHwgeyBtb2RlOiAnY29uZmlnLW1pc3NpbmcnIH1cbiAgfCB7IG1vZGU6ICdsb2FkZWQnOyBpbWFnZXM6IEltYWdlc0NvbmZpZyB9O1xuXG50eXBlIE1hdGNoZXJJbXBsID0gKFxuICBkb21haW5zOiBzdHJpbmdbXSxcbiAgcmVtb3RlUGF0dGVybnM6IFJlbW90ZVBhdHRlcm5bXSxcbiAgdXJsOiBVUkxcbikgPT4gYm9vbGVhbjtcblxubGV0IGNhY2hlZENvbmZpZzogTG9hZGVkQ29uZmlnIHwgdW5kZWZpbmVkO1xubGV0IGNhY2hlZE1hdGNoZXI6IE1hdGNoZXJJbXBsIHwgbnVsbCB8IHVuZGVmaW5lZDtcbmxldCB3YXJuZWRNYXRjaGVyTWlzc2luZyA9IGZhbHNlO1xuXG4vKipcbiAqIOi3r+W+hOino+aekOS4jiBub2RlLXNlcnZlci50cyDnmoQgYXNzZXRzIOino+aekOWQjOa6kDp3cmFwcGVyIOWQr+WKqOaXtlxuICogcHJvY2Vzcy5jd2QoKSA9PT0gc2VydmVyLWZ1bmN0aW9ucy9kZWZhdWx0LyzmiYDku6UgLm5leHQg5bCx5ZyoIGN3ZCDkuIvjgIJcbiAqL1xuZnVuY3Rpb24gY29uZmlnRmlsZVBhdGgoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnLm5leHQnLCAncmVxdWlyZWQtc2VydmVyLWZpbGVzLmpzb24nKTtcbn1cblxuZnVuY3Rpb24gbG9hZEltYWdlQ29uZmlnKCk6IExvYWRlZENvbmZpZyB7XG4gIGlmIChjYWNoZWRDb25maWcgIT09IHVuZGVmaW5lZCkgcmV0dXJuIGNhY2hlZENvbmZpZztcblxuICBjb25zdCBmaWxlUGF0aCA9IGNvbmZpZ0ZpbGVQYXRoKCk7XG4gIGxldCByYXc6IHN0cmluZztcbiAgdHJ5IHtcbiAgICByYXcgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsICd1dGYtOCcpO1xuICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIGBbaW1hZ2UtY29uZmlnXSByZXF1aXJlZC1zZXJ2ZXItZmlsZXMuanNvbiBub3QgZm91bmQgYXQgJHtmaWxlUGF0aH0g4oCUIGFsbG93aW5nIGFsbCBpbWFnZSBVUkxzICgke2Vyci5jb2RlID8/IGVyci5tZXNzYWdlfSlgXG4gICAgKTtcbiAgICBjYWNoZWRDb25maWcgPSB7IG1vZGU6ICdjb25maWctbWlzc2luZycgfTtcbiAgICByZXR1cm4gY2FjaGVkQ29uZmlnO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgY29uc3QgaW1hZ2VzID0gcGFyc2VkPy5jb25maWc/LmltYWdlcyA/PyB7fTtcbiAgICBjYWNoZWRDb25maWcgPSB7XG4gICAgICBtb2RlOiAnbG9hZGVkJyxcbiAgICAgIGltYWdlczoge1xuICAgICAgICByZW1vdGVQYXR0ZXJuczogQXJyYXkuaXNBcnJheShpbWFnZXMucmVtb3RlUGF0dGVybnMpXG4gICAgICAgICAgPyBpbWFnZXMucmVtb3RlUGF0dGVybnNcbiAgICAgICAgICA6IFtdLFxuICAgICAgICBkb21haW5zOiBBcnJheS5pc0FycmF5KGltYWdlcy5kb21haW5zKSA/IGltYWdlcy5kb21haW5zIDogW10sXG4gICAgICAgIHVub3B0aW1pemVkOiBpbWFnZXMudW5vcHRpbWl6ZWQgPT09IHRydWUsXG4gICAgICB9LFxuICAgIH07XG4gICAgcmV0dXJuIGNhY2hlZENvbmZpZztcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgW2ltYWdlLWNvbmZpZ10gZmFpbGVkIHRvIHBhcnNlICR7ZmlsZVBhdGh9OiAke2Vyci5tZXNzYWdlfSDigJQgYWxsb3dpbmcgYWxsIGltYWdlIFVSTHNgXG4gICAgKTtcbiAgICBjYWNoZWRDb25maWcgPSB7IG1vZGU6ICdjb25maWctbWlzc2luZycgfTtcbiAgICByZXR1cm4gY2FjaGVkQ29uZmlnO1xuICB9XG59XG5cbi8qKlxuICog5ou/IE5leHQg6Ieq5bex55qEIGhhc1JlbW90ZU1hdGNo44CC5aSx6LSl5LiA5qyh5ZCO57yT5a2YIG51bGws5ZCO57ut6LWw5Lil5qC8IGRlbnkg5YiG5pSv44CCXG4gKiDnlKggZXZhbCgncmVxdWlyZScpIOiuqSBlc2J1aWxkIOS4jeWOu+Wwneivleino+aekCBuZXh0IOaooeWdl+KAlOKAlHdyYXBwZXIgYnVuZGxlIOeUsVxuICogc2NyaXB0cy9idW5kbGUtb3ZlcnJpZGVzLmpzIOeUqCBlc2J1aWxkIOaJk+WMhSzmioogbmV4dCDmoIfkuoYgZXh0ZXJuYWwg5pivIGJlbHQtXG4gKiBhbmQtc3VzcGVuZGVycztldmFsIOi/meS4gOWxguehruS/neWNs+S+vyBleHRlcm5hbCDphY3plJnkuZ/miZPkuI3ov5sgYnVuZGxl44CCXG4gKi9cbmZ1bmN0aW9uIGxvYWRNYXRjaGVyKCk6IE1hdGNoZXJJbXBsIHwgbnVsbCB7XG4gIGlmIChjYWNoZWRNYXRjaGVyICE9PSB1bmRlZmluZWQpIHJldHVybiBjYWNoZWRNYXRjaGVyO1xuICB0cnkge1xuICAgIGNvbnN0IGR5bmFtaWNSZXF1aXJlID0gZXZhbCgncmVxdWlyZScpIGFzIE5vZGVSZXF1aXJlO1xuICAgIGNvbnN0IG1vZCA9IGR5bmFtaWNSZXF1aXJlKCduZXh0L2Rpc3Qvc2hhcmVkL2xpYi9tYXRjaC1yZW1vdGUtcGF0dGVybicpO1xuICAgIGNvbnN0IGhhc1JlbW90ZU1hdGNoID0gbW9kPy5oYXNSZW1vdGVNYXRjaDtcbiAgICBpZiAodHlwZW9mIGhhc1JlbW90ZU1hdGNoICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2hhc1JlbW90ZU1hdGNoIG5vdCBleHBvcnRlZCcpO1xuICAgIH1cbiAgICBjYWNoZWRNYXRjaGVyID0gaGFzUmVtb3RlTWF0Y2ggYXMgTWF0Y2hlckltcGw7XG4gICAgcmV0dXJuIGNhY2hlZE1hdGNoZXI7XG4gIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgaWYgKCF3YXJuZWRNYXRjaGVyTWlzc2luZykge1xuICAgICAgd2FybmVkTWF0Y2hlck1pc3NpbmcgPSB0cnVlO1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgW2ltYWdlLWNvbmZpZ10gY2Fubm90IGxvYWQgbmV4dC9kaXN0L3NoYXJlZC9saWIvbWF0Y2gtcmVtb3RlLXBhdHRlcm4gKCR7ZXJyLm1lc3NhZ2V9KSDigJQgZmFsbGluZyBiYWNrIHRvIGRlbnktZXh0ZXJuYWwtb25seSBtb2RlYFxuICAgICAgKTtcbiAgICB9XG4gICAgY2FjaGVkTWF0Y2hlciA9IG51bGw7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0ZVJlc3VsdCB7XG4gIG9rOiBib29sZWFuO1xuICByZWFzb24/OiBzdHJpbmc7XG59XG5cbi8qKlxuICog5qCh6aqMIC9fbmV4dC9pbWFnZSDnmoQgdXJsIOaYr+WQpuiiq+WFgeiuuOOAguivreS5ieWvuem9kCBOZXh0OlxuICogLSDlkIzmupAoaG9zdCBoZWFkZXIgPT09IHVybCDnmoQgaG9zdCzlkKvnq6/lj6Mp5aeL57uI5pS+6KGMXG4gKiAtIHVub3B0aW1pemVkOnRydWUg6Lez6L+H5qCh6aqMXG4gKiAtIOWQpuWImeW/hemhu+WRveS4rSBkb21haW5zIOaIliByZW1vdGVQYXR0ZXJucyDkuYvkuIBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlSW1hZ2VVcmwoXG4gIGFic29sdXRlVXJsOiBVUkwsXG4gIGhvc3RIZWFkZXI6IHN0cmluZ1xuKTogVmFsaWRhdGVSZXN1bHQge1xuICBjb25zdCBjZmcgPSBsb2FkSW1hZ2VDb25maWcoKTtcbiAgaWYgKGNmZy5tb2RlID09PSAnY29uZmlnLW1pc3NpbmcnKSB7XG4gICAgcmV0dXJuIHsgb2s6IHRydWUsIHJlYXNvbjogJ2NvbmZpZy1taXNzaW5nJyB9O1xuICB9XG5cbiAgY29uc3QgeyBpbWFnZXMgfSA9IGNmZztcbiAgaWYgKGltYWdlcy51bm9wdGltaXplZCkge1xuICAgIHJldHVybiB7IG9rOiB0cnVlLCByZWFzb246ICd1bm9wdGltaXplZCcgfTtcbiAgfVxuXG4gIC8vIGhvc3QgaGVhZGVyIOmAmuW4uOW4puerr+WPoyxhYnNvbHV0ZVVybC5ob3N0bmFtZSDkuI3luKYg4oCU4oCUIOeUqCB1cmwuaG9zdCjlkKvnq6/lj6MpXG4gIC8vIOavlOi+gzvlkIzml7blsI/lhpnljJbpgb/lhY3lpKflsI/lhpnlt67lvILjgIJcbiAgY29uc3QgcmVxSG9zdCA9IGhvc3RIZWFkZXIudG9Mb3dlckNhc2UoKTtcbiAgY29uc3QgdXJsSG9zdCA9IGFic29sdXRlVXJsLmhvc3QudG9Mb3dlckNhc2UoKTtcbiAgaWYgKHJlcUhvc3QgJiYgcmVxSG9zdCA9PT0gdXJsSG9zdCkge1xuICAgIHJldHVybiB7IG9rOiB0cnVlLCByZWFzb246ICdzYW1lLW9yaWdpbicgfTtcbiAgfVxuXG4gIGNvbnN0IG1hdGNoZXIgPSBsb2FkTWF0Y2hlcigpO1xuICBpZiAobWF0Y2hlciA9PT0gbnVsbCkge1xuICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnbWF0Y2hlci11bmF2YWlsYWJsZScgfTtcbiAgfVxuICBpZiAobWF0Y2hlcihpbWFnZXMuZG9tYWlucywgaW1hZ2VzLnJlbW90ZVBhdHRlcm5zLCBhYnNvbHV0ZVVybCkpIHtcbiAgICByZXR1cm4geyBvazogdHJ1ZSwgcmVhc29uOiAncGF0dGVybi1tYXRjaCcgfTtcbiAgfVxuICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ3JlbW90ZS1wYXR0ZXJuLW5vdC1tYXRjaGVkJyB9O1xufVxuXG4vKiog5rWL6K+V55SoOumHjee9rue8k+WtmOOAgueUn+S6p+S7o+eggeS4jeiwg+eUqOOAgiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9yZXNldEltYWdlQ29uZmlnQ2FjaGVGb3JUZXN0cygpOiB2b2lkIHtcbiAgY2FjaGVkQ29uZmlnID0gdW5kZWZpbmVkO1xuICBjYWNoZWRNYXRjaGVyID0gdW5kZWZpbmVkO1xuICB3YXJuZWRNYXRjaGVyTWlzc2luZyA9IGZhbHNlO1xufVxuXG4vKipcbiAqIOa1i+ivleeUqDrms6jlhaUgbWF0Y2hlciznu5Xov4flr7nnnJ/lrp4gbmV4dCDmqKHlnZfnmoQgcmVxdWlyZeOAglxuICog5LygIG51bGwg5qih5oufXCJtYXRjaGVyIOS4jeWPr+eUqFwi5YiG5pSv44CCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc2V0TWF0Y2hlckZvclRlc3RzKGltcGw6IE1hdGNoZXJJbXBsIHwgbnVsbCk6IHZvaWQge1xuICBjYWNoZWRNYXRjaGVyID0gaW1wbDtcbn1cbiJdfQ==
|
|
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
exports.handleImageProxy = void 0;
|
|
14
14
|
const stream_1 = require("stream");
|
|
15
15
|
const gateway_auth_1 = require("./gateway-auth");
|
|
16
|
+
const image_config_1 = require("./image-config");
|
|
16
17
|
const GATEWAY_TIMEOUT_MS = 10000;
|
|
17
18
|
/** 透传给浏览器的响应头白名单(避免泄露 Gateway 内部 header) */
|
|
18
19
|
const PASSTHROUGH_HEADERS = [
|
|
@@ -75,6 +76,19 @@ async function handleImageProxy(req, res) {
|
|
|
75
76
|
error: 'Cannot resolve absolute URL: missing Host header',
|
|
76
77
|
});
|
|
77
78
|
}
|
|
79
|
+
// 按 next.config.images.{remotePatterns,domains} 校验 —— 与 next dev 行为对齐
|
|
80
|
+
let parsedUrl;
|
|
81
|
+
try {
|
|
82
|
+
parsedUrl = new URL(absoluteUrl);
|
|
83
|
+
}
|
|
84
|
+
catch (_a) {
|
|
85
|
+
return writeJson(res, 400, { error: 'Invalid url parameter' });
|
|
86
|
+
}
|
|
87
|
+
const hostHeader = req.headers['host'] || '';
|
|
88
|
+
const verdict = (0, image_config_1.validateImageUrl)(parsedUrl, hostHeader);
|
|
89
|
+
if (!verdict.ok) {
|
|
90
|
+
return writeJson(res, 400, { error: 'url not allowed' });
|
|
91
|
+
}
|
|
78
92
|
// 加载签名配置
|
|
79
93
|
const cfg = (0, gateway_auth_1.loadGatewayAuthConfig)();
|
|
80
94
|
if (!cfg) {
|
|
@@ -147,4 +161,4 @@ async function handleImageProxy(req, res) {
|
|
|
147
161
|
}
|
|
148
162
|
}
|
|
149
163
|
exports.handleImageProxy = handleImageProxy;
|
|
150
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtcHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9pbWFnZS1wcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7OztHQVNHOzs7QUFHSCxtQ0FBa0M7QUFDbEMsaURBQXFFO0FBRXJFLE1BQU0sa0JBQWtCLEdBQUcsS0FBTSxDQUFDO0FBRWxDLDRDQUE0QztBQUM1QyxNQUFNLG1CQUFtQixHQUFHO0lBQzFCLGNBQWM7SUFDZCxnQkFBZ0I7SUFDaEIsZUFBZTtJQUNmLE1BQU07SUFDTixNQUFNO0lBQ04sZUFBZTtJQUNmLHlCQUF5QjtDQUMxQixDQUFDO0FBRUY7Ozs7R0FJRztBQUNILFNBQVMsa0JBQWtCLENBQ3pCLE1BQWMsRUFDZCxHQUF5QjtJQUV6QixJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRTtRQUNqRSxPQUFPLE1BQU0sQ0FBQztLQUNmO0lBQ0QsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNqQyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3ZCLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUNyRCxNQUFNLEtBQUssR0FDVCxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO1FBQzNELENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7UUFDM0QsT0FBTyxDQUFDO0lBQ1YsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFD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SUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUU7UUFDN0MsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ1YsT0FBTztLQUNSO0lBRUQsMkJBQTJCO0lBQzNCLElBQUk7UUFDRixNQUFNLFVBQVUsR0FBRyxpQkFBUSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBVyxDQUFDLENBQUM7UUFDMUQsVUFBVSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLEVBQUU7WUFDM0IsT0FBTyxDQUFDLElBQUksQ0FBQywrQkFBK0IsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDM0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhO2dCQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FBQztRQUNILFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDdEI7SUFBQyxPQUFPLEdBQVEsRUFBRTtRQUNqQixPQUFPLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRTtZQUNwQixTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSxxQkFBcUIsRUFBRSxDQUFDLENBQUM7U0FDdkQ7YUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRTtZQUM3QixHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7U0FDWDtLQUNGO0FBQ0gsQ0FBQztBQXhHRCw0Q0F3R0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIOWbvueJh+S8mOWMluS7o+eQhu+8iEZDIOWGheaJp+ihjO+8iVxuICpcbiAqIOa1j+iniOWZqCBHRVQgL19uZXh0L2ltYWdlP3VybD0uLi4mdz0uLi4mcT0uLi4g4oaSIEVTQSDihpIgRkPvvIjmnKzmqKHlnZfvvIlcbiAqIOKGkiDnlKggZ2F0ZXdheUZldGNoIOazqOWFpeetvuWQjSA0IGhlYWRlciDihpIgR2F0ZXdheSAvaW1hZ2Uvb3B0aW1pemVcbiAqIOKGkiDmtYHlvI8gcGlwZSDlk43lupTlm57mtY/op4jlmajvvIhDYWNoZS1Db250cm9sIC8gRVRhZyAvIFZhcnkg562J5aS06YCP5Lyg77yJXG4gKlxuICogYDxpbWc+YCDmoIfnrb7lj5HkuI3lh7roh6rlrprkuYkgaGVhZGVy77yM55SxIEZDIOWcqOi/memHjOS7o+WPkeetvuWQjeivt+axgiDigJTigJQg6L+Z5piv5pa55qGI5LiJ55qE5qC45b+D44CCXG4gKiDmi6bmiKogTmV4dCDlhoXnva7nmoQgL19uZXh0L2ltYWdlIOi3r+eUsSznlKjmiLcgbmV4dC5jb25maWcg5peg6ZyA6YWNIGN1c3RvbSBsb2FkZXLjgIJcbiAqL1xuXG5pbXBvcnQgKiBhcyBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0IHsgUmVhZGFibGUgfSBmcm9tICdzdHJlYW0nO1xuaW1wb3J0IHsgbG9hZEdhdGV3YXlBdXRoQ29uZmlnLCBnYXRld2F5RmV0Y2ggfSBmcm9tICcuL2dhdGV3YXktYXV0aCc7XG5cbmNvbnN0IEdBVEVXQVlfVElNRU9VVF9NUyA9IDEwXzAwMDtcblxuLyoqIOmAj+S8oOe7mea1j+iniOWZqOeahOWTjeW6lOWktOeZveWQjeWNle+8iOmBv+WFjeazhOmcsiBHYXRld2F5IOWGhemDqCBoZWFkZXLvvIkgKi9cbmNvbnN0IFBBU1NUSFJPVUdIX0hFQURFUlMgPSBbXG4gICdjb250ZW50LXR5cGUnLFxuICAnY29udGVudC1sZW5ndGgnLFxuICAnY2FjaGUtY29udHJvbCcsXG4gICdldGFnJyxcbiAgJ3ZhcnknLFxuICAnbGFzdC1tb2RpZmllZCcsXG4gICdjb250ZW50LXNlY3VyaXR5LXBvbGljeScsXG5dO1xuXG4vKipcbiAqIOaKiuivt+axgiBVUkwg5Lit55qEIGB1cmw9YCDlj4LmlbDmoIflh4bljJbmiJDnu53lr7kgVVJM44CCXG4gKiAtIOW3sue7j+aYryBodHRwKHMpOi8vIOKGkiDljp/moLdcbiAqIC0g5ZCm5YiZ55SoIGAke3Byb3RvfTovLyR7aG9zdH0ke3VybH1gIOaLvOaOpe+8jHByb3RvIOWPliB4LWZvcndhcmRlZC1wcm90b++8jOWQpuWImSBodHRwc1xuICovXG5mdW5jdGlvbiByZXNvbHZlQWJzb2x1dGVVcmwoXG4gIHJhd1VybDogc3RyaW5nLFxuICByZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlXG4pOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKHJhd1VybC5zdGFydHNXaXRoKCdodHRwOi8vJykgfHwgcmF3VXJsLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykpIHtcbiAgICByZXR1cm4gcmF3VXJsO1xuICB9XG4gIGNvbnN0IGhvc3QgPSByZXEuaGVhZGVyc1snaG9zdCddO1xuICBpZiAoIWhvc3QpIHJldHVybiBudWxsO1xuICBjb25zdCBwcm90b0hlYWRlciA9IHJlcS5oZWFkZXJzWyd4LWZvcndhcmRlZC1wcm90byddO1xuICBjb25zdCBwcm90byA9XG4gICAgKEFycmF5LmlzQXJyYXkocHJvdG9IZWFkZXIpID8gcHJvdG9IZWFkZXJbMF0gOiBwcm90b0hlYWRlcikgfHxcbiAgICAoQXJyYXkuaXNBcnJheShwcm90b0hlYWRlcikgPyBwcm90b0hlYWRlclswXSA6IHByb3RvSGVhZGVyKSB8fFxuICAgICdodHRwcyc7XG4gIGNvbnN0IHBhdGggPSByYXdVcmwuc3RhcnRzV2l0aCgnLycpID8gcmF3VXJsIDogYC8ke3Jhd1VybH1gO1xuICByZXR1cm4gYCR7cHJvdG99Oi8vJHtob3N0fSR7cGF0aH1gO1xufVxuXG5mdW5jdGlvbiB3cml0ZUpzb24ocmVzOiBodHRwLlNlcnZlclJlc3BvbnNlLCBzdGF0dXM6IG51bWJlciwgYm9keTogYW55KTogdm9pZCB7XG4gIHJlcy5zdGF0dXNDb2RlID0gc3RhdHVzO1xuICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOCcpO1xuICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbn1cblxuLyoqXG4gKiDlpITnkIbkuIDkuKogL19uZXh0L2ltYWdlIOivt+axguOAglxuICog55SxIG5vZGUtc2VydmVyIHdyYXBwZXIg5Zyo6Lev5b6E5Yy56YWN5ZCO6LCD55So44CCXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVJbWFnZVByb3h5KFxuICByZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLFxuICByZXM6IGh0dHAuU2VydmVyUmVzcG9uc2Vcbik6IFByb21pc2U8dm9pZD4ge1xuICAvLyDop6PmnpAgcXVlcnlcbiAgY29uc3QgcmVxVXJsID0gcmVxLnVybCB8fCAnJztcbiAgY29uc3QgcUlkeCA9IHJlcVVybC5pbmRleE9mKCc/Jyk7XG4gIGlmIChxSWR4ID09PSAtMSkge1xuICAgIHJldHVybiB3cml0ZUpzb24ocmVzLCA0MDAsIHsgZXJyb3I6ICdNaXNzaW5nIHF1ZXJ5IHBhcmFtZXRlcnMnIH0pO1xuICB9XG4gIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMocmVxVXJsLnNsaWNlKHFJZHggKyAxKSk7XG4gIGNvbnN0IHJhd1VybCA9IHBhcmFtcy5nZXQoJ3VybCcpO1xuICBjb25zdCB3ID0gcGFyYW1zLmdldCgndycpO1xuICBjb25zdCBxID0gcGFyYW1zLmdldCgncScpO1xuXG4gIGlmICghcmF3VXJsIHx8ICF3KSB7XG4gICAgcmV0dXJuIHdyaXRlSnNvbihyZXMsIDQwMCwge1xuICAgICAgZXJyb3I6ICdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcnM6IHVybCwgdycsXG4gICAgfSk7XG4gIH1cblxuICAvLyDmoIflh4bljJYgdXJsIOWPguaVsOS4uue7neWvuSBVUkxcbiAgY29uc3QgYWJzb2x1dGVVcmwgPSByZXNvbHZlQWJzb2x1dGVVcmwocmF3VXJsLCByZXEpO1xuICBpZiAoIWFic29sdXRlVXJsKSB7XG4gICAgcmV0dXJuIHdyaXRlSnNvbihyZXMsIDUwMCwge1xuICAgICAgZXJyb3I6ICdDYW5ub3QgcmVzb2x2ZSBhYnNvbHV0ZSBVUkw6IG1pc3NpbmcgSG9zdCBoZWFkZXInLFxuICAgIH0pO1xuICB9XG5cbiAgLy8g5Yqg6L29562+5ZCN6YWN572uXG4gIGNvbnN0IGNmZyA9IGxvYWRHYXRld2F5QXV0aENvbmZpZygpO1xuICBpZiAoIWNmZykge1xuICAgIHJldHVybiB3cml0ZUpzb24ocmVzLCA1MDAsIHtcbiAgICAgIGVycm9yOiAnR2F0ZXdheSBhdXRoIGNvbmZpZyBtaXNzaW5nJyxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIOaehOmAoCBHYXRld2F5IOivt+axgui3r+W+hFxuICBjb25zdCB1cHN0cmVhbVBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyB1cmw6IGFic29sdXRlVXJsLCB3IH0pO1xuICBpZiAocSkgdXBzdHJlYW1QYXJhbXMuc2V0KCdxJywgcSk7XG4gIGNvbnN0IHVwc3RyZWFtUGF0aCA9IGAvaW1hZ2Uvb3B0aW1pemU/JHt1cHN0cmVhbVBhcmFtc31gO1xuXG4gIC8vIOmAj+S8oCBJZi1Ob25lLU1hdGNoIOiuqSBHYXRld2F5IOi1sCAzMDRcbiAgY29uc3QgaWZOb25lTWF0Y2ggPSByZXEuaGVhZGVyc1snaWYtbm9uZS1tYXRjaCddO1xuICBjb25zdCB1cHN0cmVhbUhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgaWYgKHR5cGVvZiBpZk5vbmVNYXRjaCA9PT0gJ3N0cmluZycpIHtcbiAgICB1cHN0cmVhbUhlYWRlcnNbJ2lmLW5vbmUtbWF0Y2gnXSA9IGlmTm9uZU1hdGNoO1xuICB9XG4gIGNvbnN0IGFjY2VwdCA9IHJlcS5oZWFkZXJzWydhY2NlcHQnXTtcbiAgaWYgKHR5cGVvZiBhY2NlcHQgPT09ICdzdHJpbmcnKSB7XG4gICAgdXBzdHJlYW1IZWFkZXJzWydhY2NlcHQnXSA9IGFjY2VwdDtcbiAgfVxuXG4gIGxldCB1cHN0cmVhbTogUmVzcG9uc2U7XG4gIHRyeSB7XG4gICAgdXBzdHJlYW0gPSBhd2FpdCBnYXRld2F5RmV0Y2goY2ZnLCB1cHN0cmVhbVBhdGgsIHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB1cHN0cmVhbUhlYWRlcnMsXG4gICAgICB0aW1lb3V0TXM6IEdBVEVXQVlfVElNRU9VVF9NUyxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICBpZiAoZXJyLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgW2ltYWdlLXByb3h5XSBHYXRld2F5IHRpbWVvdXQgYWZ0ZXIgJHtHQVRFV0FZX1RJTUVPVVRfTVN9bXM6ICR7YWJzb2x1dGVVcmx9YFxuICAgICAgKTtcbiAgICAgIHJldHVybiB3cml0ZUpzb24ocmVzLCA1MDQsIHsgZXJyb3I6ICdVcHN0cmVhbSB0aW1lb3V0JyB9KTtcbiAgICB9XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYFtpbWFnZS1wcm94eV0gR2F0ZXdheSBmZXRjaCBlcnJvcjogJHtlcnIubWVzc2FnZX0gKHVybD0ke2Fic29sdXRlVXJsfSlgXG4gICAgKTtcbiAgICByZXR1cm4gd3JpdGVKc29uKHJlcywgNTAyLCB7IGVycm9yOiAnQmFkIGdhdGV3YXknIH0pO1xuICB9XG5cbiAgLy8g6YCP5Lyg54q25oCB56CBICsg55m95ZCN5Y2VIGhlYWRlclxuICByZXMuc3RhdHVzQ29kZSA9IHVwc3RyZWFtLnN0YXR1cztcbiAgZm9yIChjb25zdCBuYW1lIG9mIFBBU1NUSFJPVUdIX0hFQURFUlMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHVwc3RyZWFtLmhlYWRlcnMuZ2V0KG5hbWUpO1xuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgcmVzLnNldEhlYWRlcihuYW1lLCB2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gMzA0IC8g5pegIGJvZHkg55u05o6l57uT5p2fXG4gIGlmICh1cHN0cmVhbS5zdGF0dXMgPT09IDMwNCB8fCAhdXBzdHJlYW0uYm9keSkge1xuICAgIHJlcy5lbmQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyDmtYHlvI8gcGlwZe+8iOmBv+WFjeWkp+WbviBidWZmZXIg5Y2g5YaF5a2Y77yJXG4gIHRyeSB7XG4gICAgY29uc3Qgbm9kZVN0cmVhbSA9IFJlYWRhYmxlLmZyb21XZWIodXBzdHJlYW0uYm9keSBhcyBhbnkpO1xuICAgIG5vZGVTdHJlYW0ub24oJ2Vycm9yJywgZXJyID0+IHtcbiAgICAgIGNvbnNvbGUud2FybihgW2ltYWdlLXByb3h5XSBTdHJlYW0gZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICBpZiAoIXJlcy53cml0YWJsZUVuZGVkKSByZXMuZW5kKCk7XG4gICAgfSk7XG4gICAgbm9kZVN0cmVhbS5waXBlKHJlcyk7XG4gIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgY29uc29sZS53YXJuKGBbaW1hZ2UtcHJveHldIFBpcGUgc2V0dXAgZmFpbGVkOiAke2Vyci5tZXNzYWdlfWApO1xuICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICB3cml0ZUpzb24ocmVzLCA1MDIsIHsgZXJyb3I6ICdTdHJlYW0gc2V0dXAgZmFpbGVkJyB9KTtcbiAgICB9IGVsc2UgaWYgKCFyZXMud3JpdGFibGVFbmRlZCkge1xuICAgICAgcmVzLmVuZCgpO1xuICAgIH1cbiAgfVxufVxuIl19
|
|
164
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtcHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9pbWFnZS1wcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7OztHQVNHOzs7QUFHSCxtQ0FBa0M7QUFDbEMsaURBQXFFO0FBQ3JFLGlEQUFrRDtBQUVsRCxNQUFNLGtCQUFrQixHQUFHLEtBQU0sQ0FBQztBQUVsQyw0Q0FBNEM7QUFDNUMsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixjQUFjO0lBQ2QsZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZixNQUFNO0lBQ04sTUFBTTtJQUNOLGVBQWU7SUFDZix5QkFBeUI7Q0FDMUIsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxTQUFTLGtCQUFrQixDQUN6QixNQUFjLEVBQ2QsR0FBeUI7SUFFekIsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUU7UUFDakUsT0FBTyxNQUFNLENBQUM7S0FDZjtJQUNELE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakMsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN2QixNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDckQsTUFBTSxLQUFLLEdBQ1QsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztRQUMzRCxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO1FBQzNELE9BQU8sQ0FBQztJQUNWLE1BQU0sSUFBSSxH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LEVBQUU7UUFDakIsT0FBTyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUU7WUFDcEIsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUscUJBQXFCLEVBQUUsQ0FBQyxDQUFDO1NBQ3ZEO2FBQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUU7WUFDN0IsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1NBQ1g7S0FDRjtBQUNILENBQUM7QUFySEQsNENBcUhDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiDlm77niYfkvJjljJbku6PnkIbvvIhGQyDlhoXmiafooYzvvIlcbiAqXG4gKiDmtY/op4jlmaggR0VUIC9fbmV4dC9pbWFnZT91cmw9Li4uJnc9Li4uJnE9Li4uIOKGkiBFU0Eg4oaSIEZD77yI5pys5qih5Z2X77yJXG4gKiDihpIg55SoIGdhdGV3YXlGZXRjaCDms6jlhaXnrb7lkI0gNCBoZWFkZXIg4oaSIEdhdGV3YXkgL2ltYWdlL29wdGltaXplXG4gKiDihpIg5rWB5byPIHBpcGUg5ZON5bqU5Zue5rWP6KeI5Zmo77yIQ2FjaGUtQ29udHJvbCAvIEVUYWcgLyBWYXJ5IOetieWktOmAj+S8oO+8iVxuICpcbiAqIGA8aW1nPmAg5qCH562+5Y+R5LiN5Ye66Ieq5a6a5LmJIGhlYWRlcu+8jOeUsSBGQyDlnKjov5nph4zku6Plj5Hnrb7lkI3or7fmsYIg4oCU4oCUIOi/meaYr+aWueahiOS4ieeahOaguOW/g+OAglxuICog5oum5oiqIE5leHQg5YaF572u55qEIC9fbmV4dC9pbWFnZSDot6/nlLEs55So5oi3IG5leHQuY29uZmlnIOaXoOmcgOmFjSBjdXN0b20gbG9hZGVy44CCXG4gKi9cblxuaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJztcbmltcG9ydCB7IFJlYWRhYmxlIH0gZnJvbSAnc3RyZWFtJztcbmltcG9ydCB7IGxvYWRHYXRld2F5QXV0aENvbmZpZywgZ2F0ZXdheUZldGNoIH0gZnJvbSAnLi9nYXRld2F5LWF1dGgnO1xuaW1wb3J0IHsgdmFsaWRhdGVJbWFnZVVybCB9IGZyb20gJy4vaW1hZ2UtY29uZmlnJztcblxuY29uc3QgR0FURVdBWV9USU1FT1VUX01TID0gMTBfMDAwO1xuXG4vKiog6YCP5Lyg57uZ5rWP6KeI5Zmo55qE5ZON5bqU5aS055m95ZCN5Y2V77yI6YG/5YWN5rOE6ZyyIEdhdGV3YXkg5YaF6YOoIGhlYWRlcu+8iSAqL1xuY29uc3QgUEFTU1RIUk9VR0hfSEVBREVSUyA9IFtcbiAgJ2NvbnRlbnQtdHlwZScsXG4gICdjb250ZW50LWxlbmd0aCcsXG4gICdjYWNoZS1jb250cm9sJyxcbiAgJ2V0YWcnLFxuICAndmFyeScsXG4gICdsYXN0LW1vZGlmaWVkJyxcbiAgJ2NvbnRlbnQtc2VjdXJpdHktcG9saWN5Jyxcbl07XG5cbi8qKlxuICog5oqK6K+35rGCIFVSTCDkuK3nmoQgYHVybD1gIOWPguaVsOagh+WHhuWMluaIkOe7neWvuSBVUkzjgIJcbiAqIC0g5bey57uP5pivIGh0dHAocyk6Ly8g4oaSIOWOn+agt1xuICogLSDlkKbliJnnlKggYCR7cHJvdG99Oi8vJHtob3N0fSR7dXJsfWAg5ou85o6l77yMcHJvdG8g5Y+WIHgtZm9yd2FyZGVkLXByb3Rv77yM5ZCm5YiZIGh0dHBzXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVBYnNvbHV0ZVVybChcbiAgcmF3VXJsOiBzdHJpbmcsXG4gIHJlcTogaHR0cC5JbmNvbWluZ01lc3NhZ2Vcbik6IHN0cmluZyB8IG51bGwge1xuICBpZiAocmF3VXJsLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSB8fCByYXdVcmwuc3RhcnRzV2l0aCgnaHR0cHM6Ly8nKSkge1xuICAgIHJldHVybiByYXdVcmw7XG4gIH1cbiAgY29uc3QgaG9zdCA9IHJlcS5oZWFkZXJzWydob3N0J107XG4gIGlmICghaG9zdCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHByb3RvSGVhZGVyID0gcmVxLmhlYWRlcnNbJ3gtZm9yd2FyZGVkLXByb3RvJ107XG4gIGNvbnN0IHByb3RvID1cbiAgICAoQXJyYXkuaXNBcnJheShwcm90b0hlYWRlcikgPyBwcm90b0hlYWRlclswXSA6IHByb3RvSGVhZGVyKSB8fFxuICAgIChBcnJheS5pc0FycmF5KHByb3RvSGVhZGVyKSA/IHByb3RvSGVhZGVyWzBdIDogcHJvdG9IZWFkZXIpIHx8XG4gICAgJ2h0dHBzJztcbiAgY29uc3QgcGF0aCA9IHJhd1VybC5zdGFydHNXaXRoKCcvJykgPyByYXdVcmwgOiBgLyR7cmF3VXJsfWA7XG4gIHJldHVybiBgJHtwcm90b306Ly8ke2hvc3R9JHtwYXRofWA7XG59XG5cbmZ1bmN0aW9uIHdyaXRlSnNvbihyZXM6IGh0dHAuU2VydmVyUmVzcG9uc2UsIHN0YXR1czogbnVtYmVyLCBib2R5OiBhbnkpOiB2b2lkIHtcbiAgcmVzLnN0YXR1c0NvZGUgPSBzdGF0dXM7XG4gIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04Jyk7XG4gIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xufVxuXG4vKipcbiAqIOWkhOeQhuS4gOS4qiAvX25leHQvaW1hZ2Ug6K+35rGC44CCXG4gKiDnlLEgbm9kZS1zZXJ2ZXIgd3JhcHBlciDlnKjot6/lvoTljLnphY3lkI7osIPnlKjjgIJcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUltYWdlUHJveHkoXG4gIHJlcTogaHR0cC5JbmNvbWluZ01lc3NhZ2UsXG4gIHJlczogaHR0cC5TZXJ2ZXJSZXNwb25zZVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vIOino+aekCBxdWVyeVxuICBjb25zdCByZXFVcmwgPSByZXEudXJsIHx8ICcnO1xuICBjb25zdCBxSWR4ID0gcmVxVXJsLmluZGV4T2YoJz8nKTtcbiAgaWYgKHFJZHggPT09IC0xKSB7XG4gICAgcmV0dXJuIHdyaXRlSnNvbihyZXMsIDQwMCwgeyBlcnJvcjogJ01pc3NpbmcgcXVlcnkgcGFyYW1ldGVycycgfSk7XG4gIH1cbiAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhyZXFVcmwuc2xpY2UocUlkeCArIDEpKTtcbiAgY29uc3QgcmF3VXJsID0gcGFyYW1zLmdldCgndXJsJyk7XG4gIGNvbnN0IHcgPSBwYXJhbXMuZ2V0KCd3Jyk7XG4gIGNvbnN0IHEgPSBwYXJhbXMuZ2V0KCdxJyk7XG5cbiAgaWYgKCFyYXdVcmwgfHwgIXcpIHtcbiAgICByZXR1cm4gd3JpdGVKc29uKHJlcywgNDAwLCB7XG4gICAgICBlcnJvcjogJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyczogdXJsLCB3JyxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIOagh+WHhuWMliB1cmwg5Y+C5pWw5Li657ud5a+5IFVSTFxuICBjb25zdCBhYnNvbHV0ZVVybCA9IHJlc29sdmVBYnNvbHV0ZVVybChyYXdVcmwsIHJlcSk7XG4gIGlmICghYWJzb2x1dGVVcmwpIHtcbiAgICByZXR1cm4gd3JpdGVKc29uKHJlcywgNTAwLCB7XG4gICAgICBlcnJvcjogJ0Nhbm5vdCByZXNvbHZlIGFic29sdXRlIFVSTDogbWlzc2luZyBIb3N0IGhlYWRlcicsXG4gICAgfSk7XG4gIH1cblxuICAvLyDmjIkgbmV4dC5jb25maWcuaW1hZ2VzLntyZW1vdGVQYXR0ZXJucyxkb21haW5zfSDmoKHpqowg4oCU4oCUIOS4jiBuZXh0IGRldiDooYzkuLrlr7npvZBcbiAgbGV0IHBhcnNlZFVybDogVVJMO1xuICB0cnkge1xuICAgIHBhcnNlZFVybCA9IG5ldyBVUkwoYWJzb2x1dGVVcmwpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gd3JpdGVKc29uKHJlcywgNDAwLCB7IGVycm9yOiAnSW52YWxpZCB1cmwgcGFyYW1ldGVyJyB9KTtcbiAgfVxuICBjb25zdCBob3N0SGVhZGVyID0gKHJlcS5oZWFkZXJzWydob3N0J10gYXMgc3RyaW5nKSB8fCAnJztcbiAgY29uc3QgdmVyZGljdCA9IHZhbGlkYXRlSW1hZ2VVcmwocGFyc2VkVXJsLCBob3N0SGVhZGVyKTtcbiAgaWYgKCF2ZXJkaWN0Lm9rKSB7XG4gICAgcmV0dXJuIHdyaXRlSnNvbihyZXMsIDQwMCwgeyBlcnJvcjogJ3VybCBub3QgYWxsb3dlZCcgfSk7XG4gIH1cblxuICAvLyDliqDovb3nrb7lkI3phY3nva5cbiAgY29uc3QgY2ZnID0gbG9hZEdhdGV3YXlBdXRoQ29uZmlnKCk7XG4gIGlmICghY2ZnKSB7XG4gICAgcmV0dXJuIHdyaXRlSnNvbihyZXMsIDUwMCwge1xuICAgICAgZXJyb3I6ICdHYXRld2F5IGF1dGggY29uZmlnIG1pc3NpbmcnLFxuICAgIH0pO1xuICB9XG5cbiAgLy8g5p6E6YCgIEdhdGV3YXkg6K+35rGC6Lev5b6EXG4gIGNvbnN0IHVwc3RyZWFtUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7IHVybDogYWJzb2x1dGVVcmwsIHcgfSk7XG4gIGlmIChxKSB1cHN0cmVhbVBhcmFtcy5zZXQoJ3EnLCBxKTtcbiAgY29uc3QgdXBzdHJlYW1QYXRoID0gYC9pbWFnZS9vcHRpbWl6ZT8ke3Vwc3RyZWFtUGFyYW1zfWA7XG5cbiAgLy8g6YCP5LygIElmLU5vbmUtTWF0Y2gg6K6pIEdhdGV3YXkg6LWwIDMwNFxuICBjb25zdCBpZk5vbmVNYXRjaCA9IHJlcS5oZWFkZXJzWydpZi1ub25lLW1hdGNoJ107XG4gIGNvbnN0IHVwc3RyZWFtSGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBpZiAodHlwZW9mIGlmTm9uZU1hdGNoID09PSAnc3RyaW5nJykge1xuICAgIHVwc3RyZWFtSGVhZGVyc1snaWYtbm9uZS1tYXRjaCddID0gaWZOb25lTWF0Y2g7XG4gIH1cbiAgY29uc3QgYWNjZXB0ID0gcmVxLmhlYWRlcnNbJ2FjY2VwdCddO1xuICBpZiAodHlwZW9mIGFjY2VwdCA9PT0gJ3N0cmluZycpIHtcbiAgICB1cHN0cmVhbUhlYWRlcnNbJ2FjY2VwdCddID0gYWNjZXB0O1xuICB9XG5cbiAgbGV0IHVwc3RyZWFtOiBSZXNwb25zZTtcbiAgdHJ5IHtcbiAgICB1cHN0cmVhbSA9IGF3YWl0IGdhdGV3YXlGZXRjaChjZmcsIHVwc3RyZWFtUGF0aCwge1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhlYWRlcnM6IHVwc3RyZWFtSGVhZGVycyxcbiAgICAgIHRpbWVvdXRNczogR0FURVdBWV9USU1FT1VUX01TLFxuICAgIH0pO1xuICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgIGlmIChlcnIubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBbaW1hZ2UtcHJveHldIEdhdGV3YXkgdGltZW91dCBhZnRlciAke0dBVEVXQVlfVElNRU9VVF9NU31tczogJHthYnNvbHV0ZVVybH1gXG4gICAgICApO1xuICAgICAgcmV0dXJuIHdyaXRlSnNvbihyZXMsIDUwNCwgeyBlcnJvcjogJ1Vwc3RyZWFtIHRpbWVvdXQnIH0pO1xuICAgIH1cbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgW2ltYWdlLXByb3h5XSBHYXRld2F5IGZldGNoIGVycm9yOiAke2Vyci5tZXNzYWdlfSAodXJsPSR7YWJzb2x1dGVVcmx9KWBcbiAgICApO1xuICAgIHJldHVybiB3cml0ZUpzb24ocmVzLCA1MDIsIHsgZXJyb3I6ICdCYWQgZ2F0ZXdheScgfSk7XG4gIH1cblxuICAvLyDpgI/kvKDnirbmgIHnoIEgKyDnmb3lkI3ljZUgaGVhZGVyXG4gIHJlcy5zdGF0dXNDb2RlID0gdXBzdHJlYW0uc3RhdHVzO1xuICBmb3IgKGNvbnN0IG5hbWUgb2YgUEFTU1RIUk9VR0hfSEVBREVSUykge1xuICAgIGNvbnN0IHZhbHVlID0gdXBzdHJlYW0uaGVhZGVycy5nZXQobmFtZSk7XG4gICAgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICByZXMuc2V0SGVhZGVyKG5hbWUsIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvLyAzMDQgLyDml6AgYm9keSDnm7TmjqXnu5PmnZ9cbiAgaWYgKHVwc3RyZWFtLnN0YXR1cyA9PT0gMzA0IHx8ICF1cHN0cmVhbS5ib2R5KSB7XG4gICAgcmVzLmVuZCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIOa1geW8jyBwaXBl77yI6YG/5YWN5aSn5Zu+IGJ1ZmZlciDljaDlhoXlrZjvvIlcbiAgdHJ5IHtcbiAgICBjb25zdCBub2RlU3RyZWFtID0gUmVhZGFibGUuZnJvbVdlYih1cHN0cmVhbS5ib2R5IGFzIGFueSk7XG4gICAgbm9kZVN0cmVhbS5vbignZXJyb3InLCBlcnIgPT4ge1xuICAgICAgY29uc29sZS53YXJuKGBbaW1hZ2UtcHJveHldIFN0cmVhbSBlcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgIGlmICghcmVzLndyaXRhYmxlRW5kZWQpIHJlcy5lbmQoKTtcbiAgICB9KTtcbiAgICBub2RlU3RyZWFtLnBpcGUocmVzKTtcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICBjb25zb2xlLndhcm4oYFtpbWFnZS1wcm94eV0gUGlwZSBzZXR1cCBmYWlsZWQ6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgIHdyaXRlSnNvbihyZXMsIDUwMiwgeyBlcnJvcjogJ1N0cmVhbSBzZXR1cCBmYWlsZWQnIH0pO1xuICAgIH0gZWxzZSBpZiAoIXJlcy53cml0YWJsZUVuZGVkKSB7XG4gICAgICByZXMuZW5kKCk7XG4gICAgfVxuICB9XG59XG4iXX0=
|