esa-pcg-cli 0.1.1 → 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 +11 -26
- package/dist/_inline-overrides.js +2 -2
- package/dist/_protocol/types.d.ts +3 -0
- package/dist/_protocol/types.js +1 -1
- package/dist/adapters/wrappers/node-server.d.ts +1 -1
- package/dist/adapters/wrappers/node-server.js +8 -6
- package/dist/commands/build.js +20 -60
- package/dist/commands/serve.js +2 -2
- 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.d.ts +3 -2
- package/dist/runtime/image-proxy.js +18 -3
- package/package.json +2 -3
- package/runtime/pcg-image-loader.js +0 -13
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. |
|
|
@@ -55,10 +41,9 @@ Run `pcg <cmd> --help` for full option lists.
|
|
|
55
41
|
|
|
56
42
|
| Concern | Handled by |
|
|
57
43
|
|---|---|
|
|
58
|
-
| Custom image loader | `pcg build` copies `pcg-image-loader.js` into `<projectDir>/node_modules/.pcg/`; your `next.config` references it via a normal relative path. |
|
|
59
44
|
| ISR / on-demand revalidation | PCG `incrementalCache` override talks to the gateway, which proxies OSS. |
|
|
60
45
|
| `revalidateTag` | PCG `tagCache` override (Next.js `nextMode`) talks to the gateway's TableStore-backed tag store. |
|
|
61
|
-
| `<Image>` optimization |
|
|
46
|
+
| `<Image>` optimization | The wrapper intercepts Next's built-in `/_next/image?...` route and forwards it to the gateway's signed `/image/*` endpoint. No `next.config` changes required. |
|
|
62
47
|
|
|
63
48
|
## License
|
|
64
49
|
|
|
@@ -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, _c;\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 ((_c = req.url) === null || _c === void 0 ? void 0 : _c.startsWith(\"/_pcg/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, /_pcg/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==
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* 单个请求会按以下顺序分发:
|
|
8
8
|
* 1. `/__health` → 200 OK(供 pcg serve / 容器就绪探针)
|
|
9
|
-
* 2. `/
|
|
9
|
+
* 2. `/_next/image` → image-proxy(签名 client 调 Gateway)
|
|
10
10
|
* 3. `.open-next/assets/<urlPath>` 命中 → 直接 pipe 文件流
|
|
11
11
|
* 4. 其他 → OpenNext handler(Next SSR/API/RSC)
|
|
12
12
|
*
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* 单个请求会按以下顺序分发:
|
|
9
9
|
* 1. `/__health` → 200 OK(供 pcg serve / 容器就绪探针)
|
|
10
|
-
* 2. `/
|
|
10
|
+
* 2. `/_next/image` → image-proxy(签名 client 调 Gateway)
|
|
11
11
|
* 3. `.open-next/assets/<urlPath>` 命中 → 直接 pipe 文件流
|
|
12
12
|
* 4. 其他 → OpenNext handler(Next SSR/API/RSC)
|
|
13
13
|
*
|
|
@@ -218,7 +218,7 @@ async function wrapper(handler) {
|
|
|
218
218
|
}
|
|
219
219
|
const dispatchToNext = bridgeOpenNextHandler(handler);
|
|
220
220
|
const server = http.createServer(async (req, res) => {
|
|
221
|
-
var _a, _b
|
|
221
|
+
var _a, _b;
|
|
222
222
|
const urlPath = (_b = (_a = req.url) === null || _a === void 0 ? void 0 : _a.split('?')[0]) !== null && _b !== void 0 ? _b : '/';
|
|
223
223
|
// 1. health check
|
|
224
224
|
if (urlPath === '/__health') {
|
|
@@ -226,8 +226,10 @@ async function wrapper(handler) {
|
|
|
226
226
|
res.end('OK');
|
|
227
227
|
return;
|
|
228
228
|
}
|
|
229
|
-
// 2. 图片优化代理 ——
|
|
230
|
-
|
|
229
|
+
// 2. 图片优化代理 —— 拦截 Next 默认的 /_next/image?url=...,server 侧代发
|
|
230
|
+
// 签名请求到 Gateway。这样用户 next.config 不需要配 custom loader,
|
|
231
|
+
// <Image> 走 Next 内置 URL 生成逻辑即可。
|
|
232
|
+
if (urlPath === '/_next/image') {
|
|
231
233
|
try {
|
|
232
234
|
await (0, image_proxy_1.handleImageProxy)(req, res);
|
|
233
235
|
}
|
|
@@ -265,7 +267,7 @@ async function wrapper(handler) {
|
|
|
265
267
|
server.listen(port, () => {
|
|
266
268
|
console.log(`[pcg-node] Listening on port ${port}`);
|
|
267
269
|
console.log(`[pcg-node] assets: ${assetsDir}`);
|
|
268
|
-
console.log(`[pcg-node] routes: /__health, /
|
|
270
|
+
console.log(`[pcg-node] routes: /__health, /_next/image, /_next/static/*, <next>`);
|
|
269
271
|
resolve();
|
|
270
272
|
});
|
|
271
273
|
});
|
|
@@ -279,4 +281,4 @@ const wrapperDef = {
|
|
|
279
281
|
supportStreaming: true,
|
|
280
282
|
};
|
|
281
283
|
exports.default = wrapperDef;
|
|
282
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1zZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYWRhcHRlcnMvd3JhcHBlcnMvbm9kZS1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRzs7QUFFSCw2QkFBNkI7QUFDN0IseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QiwyREFBNkQ7QUErQjdELDRDQUE0QztBQUU1QyxNQUFNLFVBQVUsR0FBMkI7SUFDekMsS0FBSyxFQUFFLHdCQUF3QjtJQUMvQixNQUFNLEVBQUUsd0JBQXdCO0lBQ2hDLE1BQU0sRUFBRSxVQUFVO0lBQ2xCLE9BQU8sRUFBRSxXQUFXO0lBQ3BCLE9BQU8sRUFBRSxrQkFBa0I7SUFDM0IsTUFBTSxFQUFFLFdBQVc7SUFDbkIsTUFBTSxFQUFFLFlBQVk7SUFDcEIsT0FBTyxFQUFFLFlBQVk7SUFDckIsTUFBTSxFQUFFLFdBQVc7SUFDbkIsTUFBTSxFQUFFLGVBQWU7SUFDdkIsTUFBTSxFQUFFLGNBQWM7SUFDdEIsT0FBTyxFQUFFLFdBQVc7SUFDcEIsUUFBUSxFQUFFLFlBQVk7SUFDdEIsTUFBTSxFQUFFLFVBQVU7SUFDbEIsTUFBTSxFQUFFLGtCQUFrQjtJQUMxQixNQUFNLEVBQUUsWUFBWTtJQUNwQixPQUFPLEVBQUUsWUFBWTtDQUN0QixDQUFDO0FBRUYsa0NBQWtDO0FBRWxDLFNBQVMsVUFBVSxDQUFDLEdBQVc7SUFDN0IsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUMxQixNQUFNLE1BQU0sR0FBc0MsRUFBRSxDQUFDO0lBQ3JELE1BQU0sWUFBWSxHQUFHLElBQUksZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0QsS0FBSyxN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QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxHQUFHO0lBQ2pCLE9BQU87SUFDUCxJQUFJLEVBQUUsVUFBVTtJQUNoQixnQkFBZ0IsRUFBRSxJQUFJO0NBQ3ZCLENBQUM7QUFFRixrQkFBZSxVQUFVLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHBjZyBOb2RlIFNlcnZlciBXcmFwcGVyXG4gKlxuICogT3Blbk5leHQgd3JhcHBlciDnmoTplb/ov5vnqIvlvaLmgIE65LiN5L6d6LWWIEZhYVMgcnVudGltZSzoh6rluKYgSFRUUCBzZXJ2ZXIg55u05o6l55uR5ZCsXG4gKiBgcHJvY2Vzcy5lbnYuUE9SVGAo6buY6K6kIDMwMDApLGBub2RlIGluZGV4Lm1qc2Ag5Y2z5Y+v54us56uL6L+Q6KGM44CCXG4gKlxuICog5Y2V5Liq6K+35rGC5Lya5oyJ5Lul5LiL6aG65bqP5YiG5Y+ROlxuICogICAxLiBgL19faGVhbHRoYCAgICAgICAgICAgICAgICAgIOKGkiAyMDAgT0so5L6bIHBjZyBzZXJ2ZSAvIOWuueWZqOWwsee7quaOoumSiClcbiAqICAgMi4gYC9fcGNnL2ltYWdlLypgICAgICAgICAgICAgIOKGkiBpbWFnZS1wcm94eSjnrb7lkI0gY2xpZW50IOiwgyBHYXRld2F5KVxuICogICAzLiBgLm9wZW4tbmV4dC9hc3NldHMvPHVybFBhdGg+YCDlkb3kuK0g4oaSIOebtOaOpSBwaXBlIOaWh+S7tua1gVxuICogICA0LiDlhbbku5YgICAgICAgICAgICAgICAgICAgICAgICAgIOKGkiBPcGVuTmV4dCBoYW5kbGVyKE5leHQgU1NSL0FQSS9SU0MpXG4gKlxuICog5LiJ5q616YC76L6R5q2k5YmN5YiG5pWj5ZyoIHBsYXRmb3JtLWZ1bmN0aW9uIHdyYXBwZXIoaW1hZ2UgcHJveHkgKyByZXHihpJldmVudCDmoaXmjqUpXG4gKiDkuI4gYHBjZyBzZXJ2ZWAg54i26L+b56iLKOmdmeaAgei1hOa6kCArIHJldmVyc2UgcHJveHkp5LitO+atpOasoee7n+S4gOi/myB3cmFwcGVyLFxuICog6K6pIGBwY2cgc2VydmVgIOmAgOWMluS4uue6r+WtkOi/m+eoi+euoeeQhuWZqOOAglxuICovXG5cbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgaGFuZGxlSW1hZ2VQcm94eSB9IGZyb20gJy4uLy4uL3J1bnRpbWUvaW1hZ2UtcHJveHknO1xuXG4vLyA9PT0gT3Blbk5leHQg5o6l5Y+j57G75Z6LKOWGheiBlOmBv+WFjeehrOS+nei1liBAb3Blbm5leHRqcy9hd3MpID09PVxuXG5pbnRlcmZhY2UgSW50ZXJuYWxFdmVudCB7XG4gIHR5cGU6ICdjb3JlJztcbiAgbWV0aG9kOiBzdHJpbmc7XG4gIHJhd1BhdGg6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG4gIGJvZHk/OiBzdHJpbmc7XG4gIGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXT47XG4gIGNvb2tpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIHJlbW90ZUFkZHJlc3M6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFN0cmVhbUNyZWF0b3Ige1xuICB3cml0ZUhlYWRlcnMocHJlbHVkZToge1xuICAgIHN0YXR1c0NvZGU6IG51bWJlcjtcbiAgICBjb29raWVzOiBzdHJpbmdbXTtcbiAgICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICB9KTogaW1wb3J0KCdzdHJlYW0nKS5Xcml0YWJsZTtcbiAgYWJvcnRTaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgb25GaW5pc2g/OiAoKSA9PiB2b2lkO1xufVxuXG50eXBlIE9wZW5OZXh0SGFuZGxlciA9IChcbiAgZXZlbnQ6IEludGVybmFsRXZlbnQsXG4gIGN0eDogeyBzdHJlYW1DcmVhdG9yOiBTdHJlYW1DcmVhdG9yIH1cbikgPT4gUHJvbWlzZTx2b2lkPjtcblxuLy8gPT09IOmdmeaAgei1hOa6kCBNSU1FKOS4juWOnyBwY2cgc2VydmUg54i26L+b56iL5a6e546w5L+d5oyB5LiA6Ie0KSA9PT1cblxuY29uc3QgTUlNRV9UWVBFUzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgJy5qcyc6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0JyxcbiAgJy5tanMnOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdCcsXG4gICcuY3NzJzogJ3RleHQvY3NzJyxcbiAgJy5odG1sJzogJ3RleHQvaHRtbCcsXG4gICcuanNvbic6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgJy5wbmcnOiAnaW1hZ2UvcG5nJyxcbiAgJy5qcGcnOiAnaW1hZ2UvanBlZycsXG4gICcuanBlZyc6ICdpbWFnZS9qcGVnJyxcbiAgJy5naWYnOiAnaW1hZ2UvZ2lmJyxcbiAgJy5zdmcnOiAnaW1hZ2Uvc3ZnK3htbCcsXG4gICcuaWNvJzogJ2ltYWdlL3gtaWNvbicsXG4gICcud29mZic6ICdmb250L3dvZmYnLFxuICAnLndvZmYyJzogJ2ZvbnQvd29mZjInLFxuICAnLnR0Zic6ICdmb250L3R0ZicsXG4gICcubWFwJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAnLnR4dCc6ICd0ZXh0L3BsYWluJyxcbiAgJy53ZWJwJzogJ2ltYWdlL3dlYnAnLFxufTtcblxuLy8gPT09IOivt+axgiDihpIgSW50ZXJuYWxFdmVudCDmoaXmjqXlt6XlhbcgPT09XG5cbmZ1bmN0aW9uIHBhcnNlUXVlcnkodXJsOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXT4ge1xuICBjb25zdCBpZHggPSB1cmwuaW5kZXhPZignPycpO1xuICBpZiAoaWR4ID09PSAtMSkgcmV0dXJuIHt9O1xuICBjb25zdCBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHN0cmluZ1tdPiA9IHt9O1xuICBjb25zdCBzZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHVybC5zbGljZShpZHggKyAxKSk7XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHNlYXJjaFBhcmFtcykge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gcGFyYW1zW2tleV07XG4gICAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhcmFtc1trZXldID0gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGV4aXN0aW5nKSkge1xuICAgICAgZXhpc3RpbmcucHVzaCh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcmFtc1trZXldID0gW2V4aXN0aW5nLCB2YWx1ZV07XG4gICAgfVxuICB9XG4gIHJldHVybiBwYXJhbXM7XG59XG5cbmZ1bmN0aW9uIHBhcnNlQ29va2llcyhcbiAgY29va2llSGVhZGVyOiBzdHJpbmcgfCB1bmRlZmluZWRcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBpZiAoIWNvb2tpZUhlYWRlcikgcmV0dXJuIHt9O1xuICBjb25zdCBjb29raWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGZvciAoY29uc3QgcGFpciBvZiBjb29raWVIZWFkZXIuc3BsaXQoJzsnKSkge1xuICAgIGNvbnN0IGVxSWR4ID0gcGFpci5pbmRleE9mKCc9Jyk7XG4gICAgaWYgKGVxSWR4ID09PSAtMSkgY29udGludWU7XG4gICAgY29uc3QgbmFtZSA9IHBhaXIuc2xpY2UoMCwgZXFJZHgpLnRyaW0oKTtcbiAgICBjb25zdCB2YWx1ZSA9IHBhaXIuc2xpY2UoZXFJZHggKyAxKS50cmltKCk7XG4gICAgaWYgKG5hbWUpIGNvb2tpZXNbbmFtZV0gPSB2YWx1ZTtcbiAgfVxuICByZXR1cm4gY29va2llcztcbn1cblxuZnVuY3Rpb24gZmxhdHRlbkhlYWRlcnMoXG4gIHJhd0hlYWRlcnM6IGh0dHAuSW5jb21pbmdIdHRwSGVhZGVyc1xuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocmF3SGVhZGVycykpIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG4gICAgaGVhZGVyc1trZXkudG9Mb3dlckNhc2UoKV0gPSBBcnJheS5pc0FycmF5KHZhbHVlKVxuICAgICAgPyB2YWx1ZS5qb2luKCcsICcpXG4gICAgICA6IHZhbHVlO1xuICB9XG4gIHJldHVybiBoZWFkZXJzO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZWFkQm9keShcbiAgcmVxOiBodHRwLkluY29taW5nTWVzc2FnZVxuKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgaWYgKHJlcS5tZXRob2QgPT09ICdHRVQnIHx8IHJlcS5tZXRob2QgPT09ICdIRUFEJykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBjaHVua3M6IEJ1ZmZlcltdID0gW107XG4gICAgcmVxLm9uKCdkYXRhJywgKGNodW5rOiBCdWZmZXIpID0+IGNodW5rcy5wdXNoKGNodW5rKSk7XG4gICAgcmVxLm9uKCdlbmQnLCAoKSA9PiByZXNvbHZlKEJ1ZmZlci5jb25jYXQoY2h1bmtzKS50b1N0cmluZygndXRmLTgnKSkpO1xuICAgIHJlcS5vbignZXJyb3InLCByZWplY3QpO1xuICB9KTtcbn1cblxuLy8gPT09IOmdmeaAgei1hOa6kCA9PT1cblxuLyoqXG4gKiDmnI3liqEgLm9wZW4tbmV4dC9hc3NldHMvIOS4i+eahOmdmeaAgeaWh+S7tuOAglxuICpcbiAqIOWMuemFjeS4pOexuzpcbiAqICAgMS4gYC9fbmV4dC9zdGF0aWMvKmAg4oCU4oCUIE5leHQuanMg55Sf5oiQ55qE5bimIGhhc2gg6LWE5rqQLOmVv+e8k+WtmCBpbW11dGFibGVcbiAqICAgMi4gYC88cHVibGljLWZpbGU+YCDigJTigJQgYHB1YmxpYy9gIOaPkOWPluWHuuadpeeahOaguee6p+mdmeaAgeaWh+S7tiznn63nvJPlrZhcbiAqXG4gKiDkuI3lrZjlnKjnmoTot6/lvoTov5Tlm54gZmFsc2Ug6K6p5LiK5bGCIGZhbGxiYWNrIOWIsCBPcGVuTmV4dCBoYW5kbGVyKEFQSSAvIFNTUiAvXG4gKiBgX3BjZy8qYCDnrYkp44CCXG4gKi9cbmZ1bmN0aW9uIHNlcnZlU3RhdGljRmlsZShcbiAgYXNzZXRzRGlyOiBzdHJpbmcsXG4gIHJlcTogaHR0cC5JbmNvbWluZ01lc3NhZ2UsXG4gIHJlczogaHR0cC5TZXJ2ZXJSZXNwb25zZVxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IHVybFBhdGggPSByZXEudXJsPy5zcGxpdCgnPycpWzBdID8/ICcvJztcbiAgaWYgKHVybFBhdGggPT09ICcvJyB8fCAhdXJsUGF0aC5zdGFydHNXaXRoKCcvJykpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihhc3NldHNEaXIsIHVybFBhdGgpO1xuICBjb25zdCBub3JtYWxpemVkUGF0aCA9IHBhdGgubm9ybWFsaXplKGZpbGVQYXRoKTtcbiAgaWYgKCFub3JtYWxpemVkUGF0aC5zdGFydHNXaXRoKGFzc2V0c0RpcikpIHtcbiAgICByZXMud3JpdGVIZWFkKDQwMyk7XG4gICAgcmVzLmVuZCgpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgbGV0IHN0YXQ6IGZzLlN0YXRzO1xuICB0cnkge1xuICAgIHN0YXQgPSBmcy5zdGF0U3luYyhub3JtYWxpemVkUGF0aCk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoIXN0YXQuaXNGaWxlKCkpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBleHQgPSBwYXRoLmV4dG5hbWUobm9ybWFsaXplZFBhdGgpO1xuICBjb25zdCBjb250ZW50VHlwZSA9IE1JTUVfVFlQRVNbZXh0XSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJztcbiAgY29uc3QgaXNIYXNoZWRBc3NldCA9IHVybFBhdGguc3RhcnRzV2l0aCgnL19uZXh0L3N0YXRpYy8nKTtcblxuICByZXMud3JpdGVIZWFkKDIwMCwge1xuICAgICdDb250ZW50LVR5cGUnOiBjb250ZW50VHlwZSxcbiAgICAnQ29udGVudC1MZW5ndGgnOiBzdGF0LnNpemUsXG4gICAgJ0NhY2hlLUNvbnRyb2wnOiBpc0hhc2hlZEFzc2V0XG4gICAgICA/ICdwdWJsaWMsIG1heC1hZ2U9MzE1MzYwMDAsIGltbXV0YWJsZSdcbiAgICAgIDogJ3B1YmxpYywgbWF4LWFnZT02MCcsXG4gIH0pO1xuICBmcy5jcmVhdGVSZWFkU3RyZWFtKG5vcm1hbGl6ZWRQYXRoKS5waXBlKHJlcyk7XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIOaKiiBPcGVuTmV4dCDmj5DkvpvnmoQgaGFuZGxlciDljIXmiJAgaHR0cCAocmVxLCByZXMpIOWkhOeQhuWHveaVsOOAglxuICog6LSf6LSjOiBib2R5IOivu+WPluOAgWV2ZW50IOe7hOijheOAgea1geW8j+WTjeW6lOOAgTUwMCDlhZzlupXjgIJcbiAqL1xuZnVuY3Rpb24gYnJpZGdlT3Blbk5leHRIYW5kbGVyKGhhbmRsZXI6IE9wZW5OZXh0SGFuZGxlcikge1xuICByZXR1cm4gYXN5bmMgKFxuICAgIHJlcTogaHR0cC5JbmNvbWluZ01lc3NhZ2UsXG4gICAgcmVzOiBodHRwLlNlcnZlclJlc3BvbnNlXG4gICk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByYXdVcmwgPSByZXEudXJsIHx8ICcvJztcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSBmbGF0dGVuSGVhZGVycyhyZXEuaGVhZGVycyk7XG4gICAgICBjb25zdCBib2R5ID0gYXdhaXQgcmVhZEJvZHkocmVxKTtcblxuICAgICAgLy8gT3Blbk5leHQg5YaF6YOo5a+5IGV2ZW50LnVybCDmiafooYwgYG5ldyBVUkwoLi4uKWAs5b+F6aG75piv57ud5a+5IFVSTCDigJTigJQg55SoXG4gICAgICAvLyBob3N0IGhlYWRlciArIHgtZm9yd2FyZGVkLXByb3RvIOi/mOWOnyzooYzkuLrkuI4gT3Blbk5leHQg5YaF572uIG5vZGVcbiAgICAgIC8vIGNvbnZlcnRlciDkuIDoh7QgKEBvcGVubmV4dGpzL2F3cy9kaXN0L292ZXJyaWRlcy9jb252ZXJ0ZXJzL25vZGUuanMp44CCXG4gICAgICBjb25zdCBob3N0ID0gaGVhZGVyc1snaG9zdCddIHx8IGBsb2NhbGhvc3Q6JHtwcm9jZXNzLmVudi5QT1JUID8/ICczMDAwJ31gO1xuICAgICAgY29uc3QgcHJvdG8gPSBoZWFkZXJzWyd4LWZvcndhcmRlZC1wcm90byddPy5zcGxpdCgnLCcpWzBdPy50cmltKCkgfHwgJ2h0dHAnO1xuICAgICAgY29uc3QgYWJzb2x1dGVVcmwgPSBuZXcgVVJMKGAke3Byb3RvfTovLyR7aG9zdH0ke3Jhd1VybH1gKTtcblxuICAgICAgY29uc3QgZXZlbnQ6IEludGVybmFsRXZlbnQgPSB7XG4gICAgICAgIHR5cGU6ICdjb3JlJyxcbiAgICAgICAgbWV0aG9kOiByZXEubWV0aG9kIHx8ICdHRVQnLFxuICAgICAgICByYXdQYXRoOiBhYnNvbHV0ZVVybC5wYXRobmFtZSxcbiAgICAgICAgdXJsOiBhYnNvbHV0ZVVybC5ocmVmLFxuICAgICAgICBib2R5LFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBxdWVyeTogcGFyc2VRdWVyeShyYXdVcmwpLFxuICAgICAgICBjb29raWVzOiBwYXJzZUNvb2tpZXMoaGVhZGVyc1snY29va2llJ10pLFxuICAgICAgICByZW1vdGVBZGRyZXNzOlxuICAgICAgICAgIGhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvciddPy5zcGxpdCgnLCcpWzBdPy50cmltKCkgfHxcbiAgICAgICAgICBoZWFkZXJzWyd4LXJlYWwtaXAnXSB8fFxuICAgICAgICAgIHJlcS5zb2NrZXQ/LnJlbW90ZUFkZHJlc3MgfHxcbiAgICAgICAgICAnMTI3LjAuMC4xJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICAgIHJlcy5vbignY2xvc2UnLCAoKSA9PiBhYm9ydENvbnRyb2xsZXIuYWJvcnQoKSk7XG5cbiAgICAgIGNvbnN0IHN0cmVhbUNyZWF0b3I6IFN0cmVhbUNyZWF0b3IgPSB7XG4gICAgICAgIHdyaXRlSGVhZGVycyhwcmVsdWRlKSB7XG4gICAgICAgICAgcmVzLnNldEhlYWRlcignU2V0LUNvb2tpZScsIHByZWx1ZGUuY29va2llcyk7XG4gICAgICAgICAgcmVzLndyaXRlSGVhZChwcmVsdWRlLnN0YXR1c0NvZGUsIHByZWx1ZGUuaGVhZGVycyk7XG4gICAgICAgICAgcmVzLmZsdXNoSGVhZGVycygpO1xuICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0sXG4gICAgICAgIGFib3J0U2lnbmFsOiBhYm9ydENvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgaGFuZGxlcihldmVudCwgeyBzdHJlYW1DcmVhdG9yIH0pO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICBjb25zdCBpc0RldiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbic7XG4gICAgICAgIHJlcy53cml0ZUhlYWQoNTAwLCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgIHJlcy5lbmQoXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgZXJyb3I6ICdJbnRlcm5hbCBTZXJ2ZXIgRXJyb3InLFxuICAgICAgICAgICAgLi4uKGlzRGV2ICYmIHsgbWVzc2FnZTogZXJyLm1lc3NhZ2UsIHN0YWNrOiBlcnIuc3RhY2sgfSksXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoIXJlcy53cml0YWJsZUVuZGVkKSB7XG4gICAgICAgIHJlcy5lbmQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogT3Blbk5leHQg5Zyo5Yqg6L295a6MIHNlcnZlciBidW5kbGUg5ZCO6LCD55So5q2k5Ye95pWwLOaIkeS7rOWcqOatpOWQr+WKqCBIVFRQIHNlcnZlcuOAglxuICpcbiAqIGFzc2V0cyDnm67lvZXop6PmnpDkuLogYDxjd2Q+Ly4uLy4uL2Fzc2V0c2A6T3Blbk5leHQg6buY6K6k5Lqn54mp57uT5p6E5pivXG4gKiBgLm9wZW4tbmV4dC9zZXJ2ZXItZnVuY3Rpb25zL2RlZmF1bHQvaW5kZXgubWpzYCzov5DooYzml7bml6DorrrmmK/nlKjmiLfmiYvliqhcbiAqIGBjZGAg5ZCOIGBub2RlIGluZGV4Lm1qc2Ag6L+Y5pivIGBwY2cgc2VydmVgIHNwYXduKGBjd2Q6IHNlcnZlckRpcmApLFxuICogYHByb2Nlc3MuY3dkKClgIOmDveetieS6jiBgc2VydmVyLWZ1bmN0aW9ucy9kZWZhdWx0L2AsYXNzZXRzIOW/heWcqCBgLi4vLi4vYXNzZXRzL2DjgIJcbiAqL1xuYXN5bmMgZnVuY3Rpb24gd3JhcHBlcihoYW5kbGVyOiBPcGVuTmV4dEhhbmRsZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcG9ydCA9IHBhcnNlSW50KHByb2Nlc3MuZW52LlBPUlQgPz8gJzMwMDAnLCAxMCk7XG4gIGNvbnN0IGFzc2V0c0RpciA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnLi4nLCAnLi4nLCAnYXNzZXRzJyk7XG4gIGlmICghZnMuZXhpc3RzU3luYyhhc3NldHNEaXIpKSB7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYFtwY2ctbm9kZV0gYXNzZXRzIGRpcmVjdG9yeSBub3QgZm91bmQgYXQgJHthc3NldHNEaXJ9IOKAlCBzdGF0aWMgZmlsZSByZXF1ZXN0cyB3aWxsIGZhbGwgdGhyb3VnaCB0byBOZXh0IGhhbmRsZXJgXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGRpc3BhdGNoVG9OZXh0ID0gYnJpZGdlT3Blbk5leHRIYW5kbGVyKGhhbmRsZXIpO1xuXG4gIGNvbnN0IHNlcnZlciA9IGh0dHAuY3JlYXRlU2VydmVyKGFzeW5jIChyZXEsIHJlcykgPT4ge1xuICAgIGNvbnN0IHVybFBhdGggPSByZXEudXJsPy5zcGxpdCgnPycpWzBdID8/ICcvJztcblxuICAgIC8vIDEuIGhlYWx0aCBjaGVja1xuICAgIGlmICh1cmxQYXRoID09PSAnL19faGVhbHRoJykge1xuICAgICAgcmVzLndyaXRlSGVhZCgyMDAsIHsgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L3BsYWluJyB9KTtcbiAgICAgIHJlcy5lbmQoJ09LJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gMi4g5Zu+54mH5LyY5YyW5Luj55CGIOKAlOKAlCBgPGltZz5gIOWPkeS4jeWHuuiHquWumuS5ieetvuWQjSBoZWFkZXIsd3JhcHBlciDlnKjmraTku6Plj5FcbiAgICBpZiAocmVxLnVybD8uc3RhcnRzV2l0aCgnL19wY2cvaW1hZ2UvJykpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGhhbmRsZUltYWdlUHJveHkocmVxLCByZXMpO1xuICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignW3BjZy1ub2RlXSBpbWFnZS1wcm94eSBlcnJvcjonLCBlcnIpO1xuICAgICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQoNTAwLCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAnSW1hZ2UgcHJveHkgZmFpbGVkJyB9KSk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXJlcy53cml0YWJsZUVuZGVkKSB7XG4gICAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gMy4g6Z2Z5oCB6LWE5rqQKC5vcGVuLW5leHQvYXNzZXRzLylcbiAgICBpZiAoc2VydmVTdGF0aWNGaWxlKGFzc2V0c0RpciwgcmVxLCByZXMpKSByZXR1cm47XG5cbiAgICAvLyA0LiBmYWxsYmFjayDigJTigJQgT3Blbk5leHQgTmV4dC5qcyBoYW5kbGVyXG4gICAgYXdhaXQgZGlzcGF0Y2hUb05leHQocmVxLCByZXMpO1xuICB9KTtcblxuICAvLyDkvJjpm4XlhbPpl6065YGc5q2i5o6l5pS25paw6L+e5o6lLOetiSBpbi1mbGlnaHQg6K+35rGC6Ieq54S257uT5p2fLDVzIOWFnOW6leW8uuWItumAgOWHulxuICBsZXQgc2h1dHRpbmdEb3duID0gZmFsc2U7XG4gIGNvbnN0IHNodXRkb3duID0gKHNpZ25hbDogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgaWYgKHNodXR0aW5nRG93bikgcmV0dXJuO1xuICAgIHNodXR0aW5nRG93biA9IHRydWU7XG4gICAgY29uc29sZS5sb2coYFtwY2ctbm9kZV0gJHtzaWduYWx9IHJlY2VpdmVkLCBzaHV0dGluZyBkb3duLi4uYCk7XG4gICAgc2VydmVyLmNsb3NlKCgpID0+IHByb2Nlc3MuZXhpdCgwKSk7XG4gICAgc2V0VGltZW91dCgoKSA9PiBwcm9jZXNzLmV4aXQoMCksIDUwMDApLnVucmVmKCk7XG4gIH07XG4gIHByb2Nlc3Mub24oJ1NJR0lOVCcsICgpID0+IHNodXRkb3duKCdTSUdJTlQnKSk7XG4gIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCAoKSA9PiBzaHV0ZG93bignU0lHVEVSTScpKTtcblxuICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPihyZXNvbHZlID0+IHtcbiAgICBzZXJ2ZXIubGlzdGVuKHBvcnQsICgpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGBbcGNnLW5vZGVdIExpc3RlbmluZyBvbiBwb3J0ICR7cG9ydH1gKTtcbiAgICAgIGNvbnNvbGUubG9nKGBbcGNnLW5vZGVdICAgYXNzZXRzOiAgJHthc3NldHNEaXJ9YCk7XG4gICAgICBjb25zb2xlLmxvZyhgW3BjZy1ub2RlXSAgIHJvdXRlczogIC9fX2hlYWx0aCwgL19wY2cvaW1hZ2UvKiwgL19uZXh0L3N0YXRpYy8qLCA8bmV4dD5gKTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogT3Blbk5leHQg6buY6K6k5a+85Ye65aWR57qmOmB7IHdyYXBwZXIsIG5hbWUsIHN1cHBvcnRTdHJlYW1pbmcgfWDjgIJcbiAqL1xuY29uc3Qgd3JhcHBlckRlZiA9IHtcbiAgd3JhcHBlcixcbiAgbmFtZTogJ3BjZy1ub2RlJyxcbiAgc3VwcG9ydFN0cmVhbWluZzogdHJ1ZSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHdyYXBwZXJEZWY7XG4iXX0=
|
|
284
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1zZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYWRhcHRlcnMvd3JhcHBlcnMvbm9kZS1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRzs7QUFFSCw2QkFBNkI7QUFDN0IseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QiwyREFBNkQ7QUErQjdELDRDQUE0QztBQUU1QyxNQUFNLFVBQVUsR0FBMkI7SUFDekMsS0FBSyxFQUFFLHdCQUF3QjtJQUMvQixNQUFNLEVBQUUsd0JBQXdCO0lBQ2hDLE1BQU0sRUFBRSxVQUFVO0lBQ2xCLE9BQU8sRUFBRSxXQUFXO0lBQ3BCLE9BQU8sRUFBRSxrQkFBa0I7SUFDM0IsTUFBTSxFQUFFLFdBQVc7SUFDbkIsTUFBTSxFQUFFLFlBQVk7SUFDcEIsT0FBTyxFQUFFLFlBQVk7SUFDckIsTUFBTSxFQUFFLFdBQVc7SUFDbkIsTUFBTSxFQUFFLGVBQWU7SUFDdkIsTUFBTSxFQUFFLGNBQWM7SUFDdEIsT0FBTyxFQUFFLFdBQVc7SUFDcEIsUUFBUSxFQUFFLFlBQVk7SUFDdEIsTUFBTSxFQUFFLFVBQVU7SUFDbEIsTUFBTSxFQUFFLGtCQUFrQjtJQUMxQixNQUFNLEVBQUUsWUFBWTtJQUNwQixPQUFPLEVBQUUsWUFBWTtDQUN0QixDQUFDO0FBRUYsa0NBQWtDO0FBRWxDLFNBQVMsVUFBVSxDQUFDLEdBQVc7SUFDN0IsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUMxQixNQUFNLE1BQU0sR0FBc0MsRUFBRSxDQUFDO0lBQ3JELE1BQU0sWUFBWSxHQUFHLElBQUksZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0QsS0FBSyxN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O0dBRUc7QUFDSCxNQUFNLFVBQVUsR0FBRztJQUNqQixPQUFPO0lBQ1AsSUFBSSxFQUFFLFVBQVU7SUFDaEIsZ0JBQWdCLEVBQUUsSUFBSTtDQUN2QixDQUFDO0FBRUYsa0JBQWUsVUFBVSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBwY2cgTm9kZSBTZXJ2ZXIgV3JhcHBlclxuICpcbiAqIE9wZW5OZXh0IHdyYXBwZXIg55qE6ZW/6L+b56iL5b2i5oCBOuS4jeS+nei1liBGYWFTIHJ1bnRpbWUs6Ieq5bimIEhUVFAgc2VydmVyIOebtOaOpeebkeWQrFxuICogYHByb2Nlc3MuZW52LlBPUlRgKOm7mOiupCAzMDAwKSxgbm9kZSBpbmRleC5tanNgIOWNs+WPr+eLrOeri+i/kOihjOOAglxuICpcbiAqIOWNleS4quivt+axguS8muaMieS7peS4i+mhuuW6j+WIhuWPkTpcbiAqICAgMS4gYC9fX2hlYWx0aGAgICAgICAgICAgICAgICAgICDihpIgMjAwIE9LKOS+myBwY2cgc2VydmUgLyDlrrnlmajlsLHnu6rmjqLpkogpXG4gKiAgIDIuIGAvX25leHQvaW1hZ2VgICAgICAgICAgICAgICDihpIgaW1hZ2UtcHJveHko562+5ZCNIGNsaWVudCDosIMgR2F0ZXdheSlcbiAqICAgMy4gYC5vcGVuLW5leHQvYXNzZXRzLzx1cmxQYXRoPmAg5ZG95LitIOKGkiDnm7TmjqUgcGlwZSDmlofku7bmtYFcbiAqICAgNC4g5YW25LuWICAgICAgICAgICAgICAgICAgICAgICAgICDihpIgT3Blbk5leHQgaGFuZGxlcihOZXh0IFNTUi9BUEkvUlNDKVxuICpcbiAqIOS4ieautemAu+i+keatpOWJjeWIhuaVo+WcqCBwbGF0Zm9ybS1mdW5jdGlvbiB3cmFwcGVyKGltYWdlIHByb3h5ICsgcmVx4oaSZXZlbnQg5qGl5o6lKVxuICog5LiOIGBwY2cgc2VydmVgIOeItui/m+eoiyjpnZnmgIHotYTmupAgKyByZXZlcnNlIHByb3h5KeS4rTvmraTmrKHnu5/kuIDov5sgd3JhcHBlcixcbiAqIOiuqSBgcGNnIHNlcnZlYCDpgIDljJbkuLrnuq/lrZDov5vnqIvnrqHnkIblmajjgIJcbiAqL1xuXG5pbXBvcnQgKiBhcyBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGhhbmRsZUltYWdlUHJveHkgfSBmcm9tICcuLi8uLi9ydW50aW1lL2ltYWdlLXByb3h5JztcblxuLy8gPT09IE9wZW5OZXh0IOaOpeWPo+exu+WeiyjlhoXogZTpgb/lhY3noazkvp3otZYgQG9wZW5uZXh0anMvYXdzKSA9PT1cblxuaW50ZXJmYWNlIEludGVybmFsRXZlbnQge1xuICB0eXBlOiAnY29yZSc7XG4gIG1ldGhvZDogc3RyaW5nO1xuICByYXdQYXRoOiBzdHJpbmc7XG4gIHVybDogc3RyaW5nO1xuICBib2R5Pzogc3RyaW5nO1xuICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBxdWVyeTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgc3RyaW5nW10+O1xuICBjb29raWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICByZW1vdGVBZGRyZXNzOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBTdHJlYW1DcmVhdG9yIHtcbiAgd3JpdGVIZWFkZXJzKHByZWx1ZGU6IHtcbiAgICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gICAgY29va2llczogc3RyaW5nW107XG4gICAgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgfSk6IGltcG9ydCgnc3RyZWFtJykuV3JpdGFibGU7XG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIG9uRmluaXNoPzogKCkgPT4gdm9pZDtcbn1cblxudHlwZSBPcGVuTmV4dEhhbmRsZXIgPSAoXG4gIGV2ZW50OiBJbnRlcm5hbEV2ZW50LFxuICBjdHg6IHsgc3RyZWFtQ3JlYXRvcjogU3RyZWFtQ3JlYXRvciB9XG4pID0+IFByb21pc2U8dm9pZD47XG5cbi8vID09PSDpnZnmgIHotYTmupAgTUlNRSjkuI7ljp8gcGNnIHNlcnZlIOeItui/m+eoi+WunueOsOS/neaMgeS4gOiHtCkgPT09XG5cbmNvbnN0IE1JTUVfVFlQRVM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICcuanMnOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdCcsXG4gICcubWpzJzogJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnLFxuICAnLmNzcyc6ICd0ZXh0L2NzcycsXG4gICcuaHRtbCc6ICd0ZXh0L2h0bWwnLFxuICAnLmpzb24nOiAnYXBwbGljYXRpb24vanNvbicsXG4gICcucG5nJzogJ2ltYWdlL3BuZycsXG4gICcuanBnJzogJ2ltYWdlL2pwZWcnLFxuICAnLmpwZWcnOiAnaW1hZ2UvanBlZycsXG4gICcuZ2lmJzogJ2ltYWdlL2dpZicsXG4gICcuc3ZnJzogJ2ltYWdlL3N2Zyt4bWwnLFxuICAnLmljbyc6ICdpbWFnZS94LWljb24nLFxuICAnLndvZmYnOiAnZm9udC93b2ZmJyxcbiAgJy53b2ZmMic6ICdmb250L3dvZmYyJyxcbiAgJy50dGYnOiAnZm9udC90dGYnLFxuICAnLm1hcCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgJy50eHQnOiAndGV4dC9wbGFpbicsXG4gICcud2VicCc6ICdpbWFnZS93ZWJwJyxcbn07XG5cbi8vID09PSDor7fmsYIg4oaSIEludGVybmFsRXZlbnQg5qGl5o6l5bel5YW3ID09PVxuXG5mdW5jdGlvbiBwYXJzZVF1ZXJ5KHVybDogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgc3RyaW5nW10+IHtcbiAgY29uc3QgaWR4ID0gdXJsLmluZGV4T2YoJz8nKTtcbiAgaWYgKGlkeCA9PT0gLTEpIHJldHVybiB7fTtcbiAgY29uc3QgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXT4gPSB7fTtcbiAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh1cmwuc2xpY2UoaWR4ICsgMSkpO1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBzZWFyY2hQYXJhbXMpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHBhcmFtc1trZXldO1xuICAgIGlmIChleGlzdGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXJhbXNba2V5XSA9IHZhbHVlO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShleGlzdGluZykpIHtcbiAgICAgIGV4aXN0aW5nLnB1c2godmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJhbXNba2V5XSA9IFtleGlzdGluZywgdmFsdWVdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcGFyYW1zO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNvb2tpZXMoXG4gIGNvb2tpZUhlYWRlcjogc3RyaW5nIHwgdW5kZWZpbmVkXG4pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgaWYgKCFjb29raWVIZWFkZXIpIHJldHVybiB7fTtcbiAgY29uc3QgY29va2llczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IHBhaXIgb2YgY29va2llSGVhZGVyLnNwbGl0KCc7JykpIHtcbiAgICBjb25zdCBlcUlkeCA9IHBhaXIuaW5kZXhPZignPScpO1xuICAgIGlmIChlcUlkeCA9PT0gLTEpIGNvbnRpbnVlO1xuICAgIGNvbnN0IG5hbWUgPSBwYWlyLnNsaWNlKDAsIGVxSWR4KS50cmltKCk7XG4gICAgY29uc3QgdmFsdWUgPSBwYWlyLnNsaWNlKGVxSWR4ICsgMSkudHJpbSgpO1xuICAgIGlmIChuYW1lKSBjb29raWVzW25hbWVdID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGNvb2tpZXM7XG59XG5cbmZ1bmN0aW9uIGZsYXR0ZW5IZWFkZXJzKFxuICByYXdIZWFkZXJzOiBodHRwLkluY29taW5nSHR0cEhlYWRlcnNcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJhd0hlYWRlcnMpKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgIGhlYWRlcnNba2V5LnRvTG93ZXJDYXNlKCldID0gQXJyYXkuaXNBcnJheSh2YWx1ZSlcbiAgICAgID8gdmFsdWUuam9pbignLCAnKVxuICAgICAgOiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gaGVhZGVycztcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZEJvZHkoXG4gIHJlcTogaHR0cC5JbmNvbWluZ01lc3NhZ2Vcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGlmIChyZXEubWV0aG9kID09PSAnR0VUJyB8fCByZXEubWV0aG9kID09PSAnSEVBRCcpIHJldHVybiB1bmRlZmluZWQ7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2h1bmtzOiBCdWZmZXJbXSA9IFtdO1xuICAgIHJlcS5vbignZGF0YScsIChjaHVuazogQnVmZmVyKSA9PiBjaHVua3MucHVzaChjaHVuaykpO1xuICAgIHJlcS5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoJ3V0Zi04JykpKTtcbiAgICByZXEub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfSk7XG59XG5cbi8vID09PSDpnZnmgIHotYTmupAgPT09XG5cbi8qKlxuICog5pyN5YqhIC5vcGVuLW5leHQvYXNzZXRzLyDkuIvnmoTpnZnmgIHmlofku7bjgIJcbiAqXG4gKiDljLnphY3kuKTnsbs6XG4gKiAgIDEuIGAvX25leHQvc3RhdGljLypgIOKAlOKAlCBOZXh0LmpzIOeUn+aIkOeahOW4piBoYXNoIOi1hOa6kCzplb/nvJPlrZggaW1tdXRhYmxlXG4gKiAgIDIuIGAvPHB1YmxpYy1maWxlPmAg4oCU4oCUIGBwdWJsaWMvYCDmj5Dlj5blh7rmnaXnmoTmoLnnuqfpnZnmgIHmlofku7Ys55+t57yT5a2YXG4gKlxuICog5LiN5a2Y5Zyo55qE6Lev5b6E6L+U5ZueIGZhbHNlIOiuqeS4iuWxgiBmYWxsYmFjayDliLAgT3Blbk5leHQgaGFuZGxlcihBUEkgLyBTU1IgL1xuICogYF9wY2cvKmAg562JKeOAglxuICovXG5mdW5jdGlvbiBzZXJ2ZVN0YXRpY0ZpbGUoXG4gIGFzc2V0c0Rpcjogc3RyaW5nLFxuICByZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLFxuICByZXM6IGh0dHAuU2VydmVyUmVzcG9uc2Vcbik6IGJvb2xlYW4ge1xuICBjb25zdCB1cmxQYXRoID0gcmVxLnVybD8uc3BsaXQoJz8nKVswXSA/PyAnLyc7XG4gIGlmICh1cmxQYXRoID09PSAnLycgfHwgIXVybFBhdGguc3RhcnRzV2l0aCgnLycpKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oYXNzZXRzRGlyLCB1cmxQYXRoKTtcbiAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBwYXRoLm5vcm1hbGl6ZShmaWxlUGF0aCk7XG4gIGlmICghbm9ybWFsaXplZFBhdGguc3RhcnRzV2l0aChhc3NldHNEaXIpKSB7XG4gICAgcmVzLndyaXRlSGVhZCg0MDMpO1xuICAgIHJlcy5lbmQoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGxldCBzdGF0OiBmcy5TdGF0cztcbiAgdHJ5IHtcbiAgICBzdGF0ID0gZnMuc3RhdFN5bmMobm9ybWFsaXplZFBhdGgpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKCFzdGF0LmlzRmlsZSgpKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgZXh0ID0gcGF0aC5leHRuYW1lKG5vcm1hbGl6ZWRQYXRoKTtcbiAgY29uc3QgY29udGVudFR5cGUgPSBNSU1FX1RZUEVTW2V4dF0gfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7XG4gIGNvbnN0IGlzSGFzaGVkQXNzZXQgPSB1cmxQYXRoLnN0YXJ0c1dpdGgoJy9fbmV4dC9zdGF0aWMvJyk7XG5cbiAgcmVzLndyaXRlSGVhZCgyMDAsIHtcbiAgICAnQ29udGVudC1UeXBlJzogY29udGVudFR5cGUsXG4gICAgJ0NvbnRlbnQtTGVuZ3RoJzogc3RhdC5zaXplLFxuICAgICdDYWNoZS1Db250cm9sJzogaXNIYXNoZWRBc3NldFxuICAgICAgPyAncHVibGljLCBtYXgtYWdlPTMxNTM2MDAwLCBpbW11dGFibGUnXG4gICAgICA6ICdwdWJsaWMsIG1heC1hZ2U9NjAnLFxuICB9KTtcbiAgZnMuY3JlYXRlUmVhZFN0cmVhbShub3JtYWxpemVkUGF0aCkucGlwZShyZXMpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiDmioogT3Blbk5leHQg5o+Q5L6b55qEIGhhbmRsZXIg5YyF5oiQIGh0dHAgKHJlcSwgcmVzKSDlpITnkIblh73mlbDjgIJcbiAqIOi0n+i0ozogYm9keSDor7vlj5bjgIFldmVudCDnu4Too4XjgIHmtYHlvI/lk43lupTjgIE1MDAg5YWc5bqV44CCXG4gKi9cbmZ1bmN0aW9uIGJyaWRnZU9wZW5OZXh0SGFuZGxlcihoYW5kbGVyOiBPcGVuTmV4dEhhbmRsZXIpIHtcbiAgcmV0dXJuIGFzeW5jIChcbiAgICByZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLFxuICAgIHJlczogaHR0cC5TZXJ2ZXJSZXNwb25zZVxuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3VXJsID0gcmVxLnVybCB8fCAnLyc7XG4gICAgICBjb25zdCBoZWFkZXJzID0gZmxhdHRlbkhlYWRlcnMocmVxLmhlYWRlcnMpO1xuICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlYWRCb2R5KHJlcSk7XG5cbiAgICAgIC8vIE9wZW5OZXh0IOWGhemDqOWvuSBldmVudC51cmwg5omn6KGMIGBuZXcgVVJMKC4uLilgLOW/hemhu+aYr+e7neWvuSBVUkwg4oCU4oCUIOeUqFxuICAgICAgLy8gaG9zdCBoZWFkZXIgKyB4LWZvcndhcmRlZC1wcm90byDov5jljp8s6KGM5Li65LiOIE9wZW5OZXh0IOWGhee9riBub2RlXG4gICAgICAvLyBjb252ZXJ0ZXIg5LiA6Ie0IChAb3Blbm5leHRqcy9hd3MvZGlzdC9vdmVycmlkZXMvY29udmVydGVycy9ub2RlLmpzKeOAglxuICAgICAgY29uc3QgaG9zdCA9IGhlYWRlcnNbJ2hvc3QnXSB8fCBgbG9jYWxob3N0OiR7cHJvY2Vzcy5lbnYuUE9SVCA/PyAnMzAwMCd9YDtcbiAgICAgIGNvbnN0IHByb3RvID0gaGVhZGVyc1sneC1mb3J3YXJkZWQtcHJvdG8nXT8uc3BsaXQoJywnKVswXT8udHJpbSgpIHx8ICdodHRwJztcbiAgICAgIGNvbnN0IGFic29sdXRlVXJsID0gbmV3IFVSTChgJHtwcm90b306Ly8ke2hvc3R9JHtyYXdVcmx9YCk7XG5cbiAgICAgIGNvbnN0IGV2ZW50OiBJbnRlcm5hbEV2ZW50ID0ge1xuICAgICAgICB0eXBlOiAnY29yZScsXG4gICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCB8fCAnR0VUJyxcbiAgICAgICAgcmF3UGF0aDogYWJzb2x1dGVVcmwucGF0aG5hbWUsXG4gICAgICAgIHVybDogYWJzb2x1dGVVcmwuaHJlZixcbiAgICAgICAgYm9keSxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgcXVlcnk6IHBhcnNlUXVlcnkocmF3VXJsKSxcbiAgICAgICAgY29va2llczogcGFyc2VDb29raWVzKGhlYWRlcnNbJ2Nvb2tpZSddKSxcbiAgICAgICAgcmVtb3RlQWRkcmVzczpcbiAgICAgICAgICBoZWFkZXJzWyd4LWZvcndhcmRlZC1mb3InXT8uc3BsaXQoJywnKVswXT8udHJpbSgpIHx8XG4gICAgICAgICAgaGVhZGVyc1sneC1yZWFsLWlwJ10gfHxcbiAgICAgICAgICByZXEuc29ja2V0Py5yZW1vdGVBZGRyZXNzIHx8XG4gICAgICAgICAgJzEyNy4wLjAuMScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICByZXMub24oJ2Nsb3NlJywgKCkgPT4gYWJvcnRDb250cm9sbGVyLmFib3J0KCkpO1xuXG4gICAgICBjb25zdCBzdHJlYW1DcmVhdG9yOiBTdHJlYW1DcmVhdG9yID0ge1xuICAgICAgICB3cml0ZUhlYWRlcnMocHJlbHVkZSkge1xuICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ1NldC1Db29raWUnLCBwcmVsdWRlLmNvb2tpZXMpO1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQocHJlbHVkZS5zdGF0dXNDb2RlLCBwcmVsdWRlLmhlYWRlcnMpO1xuICAgICAgICAgIHJlcy5mbHVzaEhlYWRlcnMoKTtcbiAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9LFxuICAgICAgICBhYm9ydFNpZ25hbDogYWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGhhbmRsZXIoZXZlbnQsIHsgc3RyZWFtQ3JlYXRvciB9KTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgY29uc3QgaXNEZXYgPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nO1xuICAgICAgICByZXMud3JpdGVIZWFkKDUwMCwgeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICByZXMuZW5kKFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIGVycm9yOiAnSW50ZXJuYWwgU2VydmVyIEVycm9yJyxcbiAgICAgICAgICAgIC4uLihpc0RldiAmJiB7IG1lc3NhZ2U6IGVyci5tZXNzYWdlLCBzdGFjazogZXJyLnN0YWNrIH0pLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKCFyZXMud3JpdGFibGVFbmRlZCkge1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIE9wZW5OZXh0IOWcqOWKoOi9veWujCBzZXJ2ZXIgYnVuZGxlIOWQjuiwg+eUqOatpOWHveaVsCzmiJHku6zlnKjmraTlkK/liqggSFRUUCBzZXJ2ZXLjgIJcbiAqXG4gKiBhc3NldHMg55uu5b2V6Kej5p6Q5Li6IGA8Y3dkPi8uLi8uLi9hc3NldHNgOk9wZW5OZXh0IOm7mOiupOS6p+eJqee7k+aehOaYr1xuICogYC5vcGVuLW5leHQvc2VydmVyLWZ1bmN0aW9ucy9kZWZhdWx0L2luZGV4Lm1qc2As6L+Q6KGM5pe25peg6K665piv55So5oi35omL5YqoXG4gKiBgY2RgIOWQjiBgbm9kZSBpbmRleC5tanNgIOi/mOaYryBgcGNnIHNlcnZlYCBzcGF3bihgY3dkOiBzZXJ2ZXJEaXJgKSxcbiAqIGBwcm9jZXNzLmN3ZCgpYCDpg73nrYnkuo4gYHNlcnZlci1mdW5jdGlvbnMvZGVmYXVsdC9gLGFzc2V0cyDlv4XlnKggYC4uLy4uL2Fzc2V0cy9g44CCXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHdyYXBwZXIoaGFuZGxlcjogT3Blbk5leHRIYW5kbGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHBvcnQgPSBwYXJzZUludChwcm9jZXNzLmVudi5QT1JUID8/ICczMDAwJywgMTApO1xuICBjb25zdCBhc3NldHNEaXIgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJy4uJywgJy4uJywgJ2Fzc2V0cycpO1xuICBpZiAoIWZzLmV4aXN0c1N5bmMoYXNzZXRzRGlyKSkge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIGBbcGNnLW5vZGVdIGFzc2V0cyBkaXJlY3Rvcnkgbm90IGZvdW5kIGF0ICR7YXNzZXRzRGlyfSDigJQgc3RhdGljIGZpbGUgcmVxdWVzdHMgd2lsbCBmYWxsIHRocm91Z2ggdG8gTmV4dCBoYW5kbGVyYFxuICAgICk7XG4gIH1cblxuICBjb25zdCBkaXNwYXRjaFRvTmV4dCA9IGJyaWRnZU9wZW5OZXh0SGFuZGxlcihoYW5kbGVyKTtcblxuICBjb25zdCBzZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcihhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICBjb25zdCB1cmxQYXRoID0gcmVxLnVybD8uc3BsaXQoJz8nKVswXSA/PyAnLyc7XG5cbiAgICAvLyAxLiBoZWFsdGggY2hlY2tcbiAgICBpZiAodXJsUGF0aCA9PT0gJy9fX2hlYWx0aCcpIHtcbiAgICAgIHJlcy53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9wbGFpbicgfSk7XG4gICAgICByZXMuZW5kKCdPSycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIDIuIOWbvueJh+S8mOWMluS7o+eQhiDigJTigJQg5oum5oiqIE5leHQg6buY6K6k55qEIC9fbmV4dC9pbWFnZT91cmw9Li4uLHNlcnZlciDkvqfku6Plj5FcbiAgICAvLyAgICDnrb7lkI3or7fmsYLliLAgR2F0ZXdheeOAgui/meagt+eUqOaItyBuZXh0LmNvbmZpZyDkuI3pnIDopoHphY0gY3VzdG9tIGxvYWRlcixcbiAgICAvLyAgICA8SW1hZ2U+IOi1sCBOZXh0IOWGhee9riBVUkwg55Sf5oiQ6YC76L6R5Y2z5Y+v44CCXG4gICAgaWYgKHVybFBhdGggPT09ICcvX25leHQvaW1hZ2UnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBoYW5kbGVJbWFnZVByb3h5KHJlcSwgcmVzKTtcbiAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1twY2ctbm9kZV0gaW1hZ2UtcHJveHkgZXJyb3I6JywgZXJyKTtcbiAgICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDUwMCwgeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogJ0ltYWdlIHByb3h5IGZhaWxlZCcgfSkpO1xuICAgICAgICB9IGVsc2UgaWYgKCFyZXMud3JpdGFibGVFbmRlZCkge1xuICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIDMuIOmdmeaAgei1hOa6kCgub3Blbi1uZXh0L2Fzc2V0cy8pXG4gICAgaWYgKHNlcnZlU3RhdGljRmlsZShhc3NldHNEaXIsIHJlcSwgcmVzKSkgcmV0dXJuO1xuXG4gICAgLy8gNC4gZmFsbGJhY2sg4oCU4oCUIE9wZW5OZXh0IE5leHQuanMgaGFuZGxlclxuICAgIGF3YWl0IGRpc3BhdGNoVG9OZXh0KHJlcSwgcmVzKTtcbiAgfSk7XG5cbiAgLy8g5LyY6ZuF5YWz6ZetOuWBnOatouaOpeaUtuaWsOi/nuaOpSznrYkgaW4tZmxpZ2h0IOivt+axguiHqueEtue7k+adnyw1cyDlhZzlupXlvLrliLbpgIDlh7pcbiAgbGV0IHNodXR0aW5nRG93biA9IGZhbHNlO1xuICBjb25zdCBzaHV0ZG93biA9IChzaWduYWw6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIGlmIChzaHV0dGluZ0Rvd24pIHJldHVybjtcbiAgICBzaHV0dGluZ0Rvd24gPSB0cnVlO1xuICAgIGNvbnNvbGUubG9nKGBbcGNnLW5vZGVdICR7c2lnbmFsfSByZWNlaXZlZCwgc2h1dHRpbmcgZG93bi4uLmApO1xuICAgIHNlcnZlci5jbG9zZSgoKSA9PiBwcm9jZXNzLmV4aXQoMCkpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KDApLCA1MDAwKS51bnJlZigpO1xuICB9O1xuICBwcm9jZXNzLm9uKCdTSUdJTlQnLCAoKSA9PiBzaHV0ZG93bignU0lHSU5UJykpO1xuICBwcm9jZXNzLm9uKCdTSUdURVJNJywgKCkgPT4gc2h1dGRvd24oJ1NJR1RFUk0nKSk7XG5cbiAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4ocmVzb2x2ZSA9PiB7XG4gICAgc2VydmVyLmxpc3Rlbihwb3J0LCAoKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhgW3BjZy1ub2RlXSBMaXN0ZW5pbmcgb24gcG9ydCAke3BvcnR9YCk7XG4gICAgICBjb25zb2xlLmxvZyhgW3BjZy1ub2RlXSAgIGFzc2V0czogICR7YXNzZXRzRGlyfWApO1xuICAgICAgY29uc29sZS5sb2coYFtwY2ctbm9kZV0gICByb3V0ZXM6ICAvX19oZWFsdGgsIC9fbmV4dC9pbWFnZSwgL19uZXh0L3N0YXRpYy8qLCA8bmV4dD5gKTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogT3Blbk5leHQg6buY6K6k5a+85Ye65aWR57qmOmB7IHdyYXBwZXIsIG5hbWUsIHN1cHBvcnRTdHJlYW1pbmcgfWDjgIJcbiAqL1xuY29uc3Qgd3JhcHBlckRlZiA9IHtcbiAgd3JhcHBlcixcbiAgbmFtZTogJ3BjZy1ub2RlJyxcbiAgc3VwcG9ydFN0cmVhbWluZzogdHJ1ZSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHdyYXBwZXJEZWY7XG4iXX0=
|