esa-pcg-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/dist/_inline-overrides.js +7 -0
  4. package/dist/_protocol/endpoints.d.ts +14 -0
  5. package/dist/_protocol/endpoints.js +24 -0
  6. package/dist/_protocol/index.d.ts +3 -0
  7. package/dist/_protocol/index.js +20 -0
  8. package/dist/_protocol/keys.d.ts +27 -0
  9. package/dist/_protocol/keys.js +36 -0
  10. package/dist/_protocol/types.d.ts +72 -0
  11. package/dist/_protocol/types.js +3 -0
  12. package/dist/adapters/adapter.interface.d.ts +8 -0
  13. package/dist/adapters/adapter.interface.js +3 -0
  14. package/dist/adapters/converters/passthrough.d.ts +16 -0
  15. package/dist/adapters/converters/passthrough.js +19 -0
  16. package/dist/adapters/index.d.ts +3 -0
  17. package/dist/adapters/index.js +8 -0
  18. package/dist/adapters/local-fs.adapter.d.ts +12 -0
  19. package/dist/adapters/local-fs.adapter.js +37 -0
  20. package/dist/adapters/oss.adapter.d.ts +13 -0
  21. package/dist/adapters/oss.adapter.js +26 -0
  22. package/dist/adapters/wrappers/node-server.d.ts +57 -0
  23. package/dist/adapters/wrappers/node-server.js +282 -0
  24. package/dist/bin/cli.d.ts +2 -0
  25. package/dist/bin/cli.js +21 -0
  26. package/dist/commands/build.d.ts +10 -0
  27. package/dist/commands/build.js +247 -0
  28. package/dist/commands/deploy.d.ts +11 -0
  29. package/dist/commands/deploy.js +116 -0
  30. package/dist/commands/purge.d.ts +15 -0
  31. package/dist/commands/purge.js +135 -0
  32. package/dist/commands/serve.d.ts +14 -0
  33. package/dist/commands/serve.js +162 -0
  34. package/dist/commands/upload-assets.d.ts +12 -0
  35. package/dist/commands/upload-assets.js +46 -0
  36. package/dist/commands/upload-cache.d.ts +13 -0
  37. package/dist/commands/upload-cache.js +70 -0
  38. package/dist/compile/compileCacheAssetsManifest.d.ts +1 -0
  39. package/dist/compile/compileCacheAssetsManifest.js +67 -0
  40. package/dist/config/default-open-next-config.d.ts +3 -0
  41. package/dist/config/default-open-next-config.js +30 -0
  42. package/dist/index.d.ts +13 -0
  43. package/dist/index.js +36 -0
  44. package/dist/overrides/incrementalCache/gateway.d.ts +32 -0
  45. package/dist/overrides/incrementalCache/gateway.js +160 -0
  46. package/dist/overrides/tagCache/gateway.d.ts +26 -0
  47. package/dist/overrides/tagCache/gateway.js +211 -0
  48. package/dist/runtime/gateway-auth.d.ts +51 -0
  49. package/dist/runtime/gateway-auth.js +121 -0
  50. package/dist/runtime/image-proxy.d.ts +16 -0
  51. package/dist/runtime/image-proxy.js +149 -0
  52. package/dist/util/fs.d.ts +3 -0
  53. package/dist/util/fs.js +39 -0
  54. package/package.json +47 -0
  55. package/runtime/pcg-image-loader.js +13 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PCG Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # esa-pcg-cli
2
+
3
+ CLI for building and deploying Next.js apps onto **pages-cache-gateway (PCG)** — an OpenNext-based deployment target that proxies incremental cache, tag cache, and `<Image>` optimization through a single self-hosted gateway.
4
+
5
+ `esa-pcg-cli` wraps `@opennextjs/aws` and injects PCG's wrapper / converter / incrementalCache / tagCache overrides automatically, so most projects don't need a hand-written `open-next.config.ts`.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install --save-dev esa-pcg-cli
11
+ # or
12
+ pnpm add -D esa-pcg-cli
13
+ ```
14
+
15
+ `@opennextjs/aws` is declared as a peer dependency and ships bundled inside the CLI; you don't need to add it yourself.
16
+
17
+ ## Quick start
18
+
19
+ 1. Wire the custom image loader in `next.config.{js,mjs,ts}`:
20
+
21
+ ```js
22
+ // next.config.mjs
23
+ const nextConfig = {
24
+ output: 'standalone',
25
+ images: {
26
+ loader: 'custom',
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
+ ```
41
+
42
+ ## Commands
43
+
44
+ | Command | What it does |
45
+ |---|---|
46
+ | `pcg build` | Runs OpenNext build with PCG overrides auto-injected. Generates `.open-next/` and materializes the image loader into `node_modules/.pcg/`. |
47
+ | `pcg deploy` | Uploads cache artifacts to OSS (via gateway-issued STS or local mode). |
48
+ | `pcg serve` | Local dev server backed by the built `.open-next/` (assets + spawned server function). |
49
+ | `pcg upload-cache` / `upload-assets` | Lower-level upload primitives. |
50
+ | `pcg purge` | Invalidates cached entries by tag / path. |
51
+
52
+ Run `pcg <cmd> --help` for full option lists.
53
+
54
+ ## How it integrates with Next.js
55
+
56
+ | Concern | Handled by |
57
+ |---|---|
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
+ | ISR / on-demand revalidation | PCG `incrementalCache` override talks to the gateway, which proxies OSS. |
60
+ | `revalidateTag` | PCG `tagCache` override (Next.js `nextMode`) talks to the gateway's TableStore-backed tag store. |
61
+ | `<Image>` optimization | Loader emits `/_pcg/image/optimize?...` URLs; the wrapper inside the server function forwards them to the gateway's signed `/image/*` endpoint. |
62
+
63
+ ## License
64
+
65
+ MIT. See [LICENSE](./LICENSE).
@@ -0,0 +1,7 @@
1
+ "use strict";
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",
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
+ "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",
7
+ };
@@ -0,0 +1,14 @@
1
+ export interface CentralCacheEndpoints {
2
+ base: string;
3
+ cache: string;
4
+ cacheRefresh: string;
5
+ revalidateTag: string;
6
+ revalidatePath: string;
7
+ tagByTag: string;
8
+ tagByPath: string;
9
+ tagLastModified: string;
10
+ tagWrite: string;
11
+ deploySts: string;
12
+ deployTags: string;
13
+ }
14
+ export declare function buildCentralEndpoints(base: string): CentralCacheEndpoints;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildCentralEndpoints = void 0;
4
+ function stripTrailingSlashes(s) {
5
+ return s.replace(/\/+$/, '');
6
+ }
7
+ function buildCentralEndpoints(base) {
8
+ const b = stripTrailingSlashes(base);
9
+ return {
10
+ base: b,
11
+ cache: `${b}/cache`,
12
+ cacheRefresh: `${b}/cache/refresh`,
13
+ revalidateTag: `${b}/revalidate/tag`,
14
+ revalidatePath: `${b}/revalidate/path`,
15
+ tagByTag: `${b}/tag/by-tag`,
16
+ tagByPath: `${b}/tag/by-path`,
17
+ tagLastModified: `${b}/tag/last-modified`,
18
+ tagWrite: `${b}/tag/write`,
19
+ deploySts: `${b}/deploy/sts-token`,
20
+ deployTags: `${b}/deploy/tags`,
21
+ };
22
+ }
23
+ exports.buildCentralEndpoints = buildCentralEndpoints;
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5kcG9pbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2VuZHBvaW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFjQSxTQUFTLG9CQUFvQixDQUFDLENBQVM7SUFDckMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBRUQsU0FBZ0IscUJBQXFCLENBQUMsSUFBWTtJQUNoRCxNQUFNLENBQUMsR0FBRyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNyQyxPQUFPO1FBQ0wsSUFBSSxFQUFFLENBQUM7UUFDUCxLQUFLLEVBQUUsR0FBRyxDQUFDLFFBQVE7UUFDbkIsWUFBWSxFQUFFLEdBQUcsQ0FBQyxnQkFBZ0I7UUFDbEMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxpQkFBaUI7UUFDcEMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxrQkFBa0I7UUFDdEMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxhQUFhO1FBQzNCLFNBQVMsRUFBRSxHQUFHLENBQUMsY0FBYztRQUM3QixlQUFlLEVBQUUsR0FBRyxDQUFDLG9CQUFvQjtRQUN6QyxRQUFRLEVBQUUsR0FBRyxDQUFDLFlBQVk7UUFDMUIsU0FBUyxFQUFFLEdBQUcsQ0FBQyxtQkFBbUI7UUFDbEMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxjQUFjO0tBQy9CLENBQUM7QUFDSixDQUFDO0FBZkQsc0RBZUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgaW50ZXJmYWNlIENlbnRyYWxDYWNoZUVuZHBvaW50cyB7XG4gIGJhc2U6IHN0cmluZztcbiAgY2FjaGU6IHN0cmluZztcbiAgY2FjaGVSZWZyZXNoOiBzdHJpbmc7XG4gIHJldmFsaWRhdGVUYWc6IHN0cmluZztcbiAgcmV2YWxpZGF0ZVBhdGg6IHN0cmluZztcbiAgdGFnQnlUYWc6IHN0cmluZztcbiAgdGFnQnlQYXRoOiBzdHJpbmc7XG4gIHRhZ0xhc3RNb2RpZmllZDogc3RyaW5nO1xuICB0YWdXcml0ZTogc3RyaW5nO1xuICBkZXBsb3lTdHM6IHN0cmluZztcbiAgZGVwbG95VGFnczogc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBzdHJpcFRyYWlsaW5nU2xhc2hlcyhzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKC9cXC8rJC8sICcnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ2VudHJhbEVuZHBvaW50cyhiYXNlOiBzdHJpbmcpOiBDZW50cmFsQ2FjaGVFbmRwb2ludHMge1xuICBjb25zdCBiID0gc3RyaXBUcmFpbGluZ1NsYXNoZXMoYmFzZSk7XG4gIHJldHVybiB7XG4gICAgYmFzZTogYixcbiAgICBjYWNoZTogYCR7Yn0vY2FjaGVgLFxuICAgIGNhY2hlUmVmcmVzaDogYCR7Yn0vY2FjaGUvcmVmcmVzaGAsXG4gICAgcmV2YWxpZGF0ZVRhZzogYCR7Yn0vcmV2YWxpZGF0ZS90YWdgLFxuICAgIHJldmFsaWRhdGVQYXRoOiBgJHtifS9yZXZhbGlkYXRlL3BhdGhgLFxuICAgIHRhZ0J5VGFnOiBgJHtifS90YWcvYnktdGFnYCxcbiAgICB0YWdCeVBhdGg6IGAke2J9L3RhZy9ieS1wYXRoYCxcbiAgICB0YWdMYXN0TW9kaWZpZWQ6IGAke2J9L3RhZy9sYXN0LW1vZGlmaWVkYCxcbiAgICB0YWdXcml0ZTogYCR7Yn0vdGFnL3dyaXRlYCxcbiAgICBkZXBsb3lTdHM6IGAke2J9L2RlcGxveS9zdHMtdG9rZW5gLFxuICAgIGRlcGxveVRhZ3M6IGAke2J9L2RlcGxveS90YWdzYCxcbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,3 @@
1
+ export * from './types';
2
+ export * from './keys';
3
+ export * from './endpoints';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./keys"), exports);
19
+ __exportStar(require("./endpoints"), exports);
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDBDQUF3QjtBQUN4Qix5Q0FBdUI7QUFDdkIsOENBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL2tleXMnO1xuZXhwb3J0ICogZnJvbSAnLi9lbmRwb2ludHMnO1xuIl19
@@ -0,0 +1,27 @@
1
+ export declare function buildOssKey(params: {
2
+ appId: string;
3
+ buildId: string;
4
+ key: string;
5
+ cacheType?: string;
6
+ }): string;
7
+ export declare function buildStaticAssetKey(params: {
8
+ appId: string;
9
+ path: string;
10
+ }): string;
11
+ export declare function buildTagKey(params: {
12
+ appId: string;
13
+ buildId: string;
14
+ tag: string;
15
+ path: string;
16
+ }): {
17
+ app_id: string;
18
+ tag: string;
19
+ path: string;
20
+ };
21
+ export declare function buildPageMetadataKey(params: {
22
+ appId: string;
23
+ url: string;
24
+ }): {
25
+ app_id: string;
26
+ url: string;
27
+ };
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildPageMetadataKey = exports.buildTagKey = exports.buildStaticAssetKey = exports.buildOssKey = void 0;
4
+ function stripLeadingSlash(s) {
5
+ return s.replace(/^\/+/, '');
6
+ }
7
+ function buildOssKey(params) {
8
+ const { appId, buildId, cacheType = 'cache' } = params;
9
+ const key = stripLeadingSlash(params.key);
10
+ if (cacheType === 'fetch') {
11
+ return `${appId}/__fetch/${buildId}/${key}`;
12
+ }
13
+ return `${appId}/${buildId}/${key}.cache`;
14
+ }
15
+ exports.buildOssKey = buildOssKey;
16
+ function buildStaticAssetKey(params) {
17
+ const p = stripLeadingSlash(params.path);
18
+ return `${params.appId}/_next/static/${p}`;
19
+ }
20
+ exports.buildStaticAssetKey = buildStaticAssetKey;
21
+ function buildTagKey(params) {
22
+ return {
23
+ app_id: params.appId,
24
+ tag: `${params.buildId}/${params.tag}`,
25
+ path: `${params.buildId}/${params.path}`,
26
+ };
27
+ }
28
+ exports.buildTagKey = buildTagKey;
29
+ function buildPageMetadataKey(params) {
30
+ return {
31
+ app_id: params.appId,
32
+ url: params.url,
33
+ };
34
+ }
35
+ exports.buildPageMetadataKey = buildPageMetadataKey;
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9rZXlzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLFNBQVMsaUJBQWlCLENBQUMsQ0FBUztJQUNsQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQy9CLENBQUM7QUFFRCxTQUFnQixXQUFXLENBQUMsTUFLM0I7SUFDQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEdBQUcsT0FBTyxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBQ3ZELE1BQU0sR0FBRyxHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUxQyxJQUFJLFNBQVMsS0FBSyxPQUFPLEVBQUU7UUFDekIsT0FBTyxHQUFHLEtBQUssWUFBWSxPQUFPLElBQUksR0FBRyxFQUFFLENBQUM7S0FDN0M7SUFDRCxPQUFPLEdBQUcsS0FBSyxJQUFJLE9BQU8sSUFBSSxHQUFHLFFBQVEsQ0FBQztBQUM1QyxDQUFDO0FBYkQsa0NBYUM7QUFFRCxTQUFnQixtQkFBbUIsQ0FBQyxNQUduQztJQUNDLE1BQU0sQ0FBQyxHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QyxPQUFPLEdBQUcsTUFBTSxDQUFDLEtBQUssaUJBQWlCLENBQUMsRUFBRSxDQUFDO0FBQzdDLENBQUM7QUFORCxrREFNQztBQUVELFNBQWdCLFdBQVcsQ0FBQyxNQUszQjtJQUNDLE9BQU87UUFDTCxNQUFNLEVBQUUsTUFBTSxDQUFDLEtBQUs7UUFDcEIsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsR0FBRyxFQUFFO1FBQ3RDLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLElBQUksRUFBRTtLQUN6QyxDQUFDO0FBQ0osQ0FBQztBQVhELGtDQVdDO0FBRUQsU0FBZ0Isb0JBQW9CLENBQUMsTUFHcEM7SUFDQyxPQUFPO1FBQ0wsTUFBTSxFQUFFLE1BQU0sQ0FBQyxLQUFLO1FBQ3BCLEdBQUcsRUFBRSxNQUFNLENBQUMsR0FBRztLQUNoQixDQUFDO0FBQ0osQ0FBQztBQVJELG9EQVFDIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gc3RyaXBMZWFkaW5nU2xhc2goczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHMucmVwbGFjZSgvXlxcLysvLCAnJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZE9zc0tleShwYXJhbXM6IHtcbiAgYXBwSWQ6IHN0cmluZztcbiAgYnVpbGRJZDogc3RyaW5nO1xuICBrZXk6IHN0cmluZztcbiAgY2FjaGVUeXBlPzogc3RyaW5nO1xufSk6IHN0cmluZyB7XG4gIGNvbnN0IHsgYXBwSWQsIGJ1aWxkSWQsIGNhY2hlVHlwZSA9ICdjYWNoZScgfSA9IHBhcmFtcztcbiAgY29uc3Qga2V5ID0gc3RyaXBMZWFkaW5nU2xhc2gocGFyYW1zLmtleSk7XG5cbiAgaWYgKGNhY2hlVHlwZSA9PT0gJ2ZldGNoJykge1xuICAgIHJldHVybiBgJHthcHBJZH0vX19mZXRjaC8ke2J1aWxkSWR9LyR7a2V5fWA7XG4gIH1cbiAgcmV0dXJuIGAke2FwcElkfS8ke2J1aWxkSWR9LyR7a2V5fS5jYWNoZWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFN0YXRpY0Fzc2V0S2V5KHBhcmFtczoge1xuICBhcHBJZDogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG59KTogc3RyaW5nIHtcbiAgY29uc3QgcCA9IHN0cmlwTGVhZGluZ1NsYXNoKHBhcmFtcy5wYXRoKTtcbiAgcmV0dXJuIGAke3BhcmFtcy5hcHBJZH0vX25leHQvc3RhdGljLyR7cH1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRUYWdLZXkocGFyYW1zOiB7XG4gIGFwcElkOiBzdHJpbmc7XG4gIGJ1aWxkSWQ6IHN0cmluZztcbiAgdGFnOiBzdHJpbmc7XG4gIHBhdGg6IHN0cmluZztcbn0pOiB7IGFwcF9pZDogc3RyaW5nOyB0YWc6IHN0cmluZzsgcGF0aDogc3RyaW5nIH0ge1xuICByZXR1cm4ge1xuICAgIGFwcF9pZDogcGFyYW1zLmFwcElkLFxuICAgIHRhZzogYCR7cGFyYW1zLmJ1aWxkSWR9LyR7cGFyYW1zLnRhZ31gLFxuICAgIHBhdGg6IGAke3BhcmFtcy5idWlsZElkfS8ke3BhcmFtcy5wYXRofWAsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBhZ2VNZXRhZGF0YUtleShwYXJhbXM6IHtcbiAgYXBwSWQ6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG59KTogeyBhcHBfaWQ6IHN0cmluZzsgdXJsOiBzdHJpbmcgfSB7XG4gIHJldHVybiB7XG4gICAgYXBwX2lkOiBwYXJhbXMuYXBwSWQsXG4gICAgdXJsOiBwYXJhbXMudXJsLFxuICB9O1xufVxuIl19
@@ -0,0 +1,72 @@
1
+ /// <reference types="node" />
2
+ export declare type CacheMode = 'local' | 'central';
3
+ export interface JWTPayload {
4
+ uid: string;
5
+ app: string;
6
+ buildId: string;
7
+ iat?: number;
8
+ exp?: number;
9
+ }
10
+ export interface TenantContext {
11
+ uid: string;
12
+ app: string;
13
+ buildId: string;
14
+ /** `${uid}/${app}` */
15
+ appId: string;
16
+ }
17
+ export interface STSTokenResponse {
18
+ accessKeyId: string;
19
+ accessKeySecret: string;
20
+ securityToken: string;
21
+ expiration: string;
22
+ bucket: string;
23
+ /** "{uid}/{app}/" */
24
+ prefix: string;
25
+ region: string;
26
+ }
27
+ export interface TableStorePrimaryKey {
28
+ name: string;
29
+ value: string | number;
30
+ }
31
+ export interface TableStoreColumn {
32
+ name: string;
33
+ value: string | number | Buffer;
34
+ timestamp?: number;
35
+ }
36
+ export interface TableStoreRow {
37
+ primaryKey: TableStorePrimaryKey[];
38
+ columns?: TableStoreColumn[];
39
+ }
40
+ export interface GetRowRequest {
41
+ primaryKey: TableStorePrimaryKey[];
42
+ }
43
+ export interface PutRowRequest {
44
+ primaryKey: TableStorePrimaryKey[];
45
+ columns: TableStoreColumn[];
46
+ }
47
+ export interface DeleteRowRequest {
48
+ primaryKey: TableStorePrimaryKey[];
49
+ }
50
+ export interface GetRangeRequest {
51
+ startPrimaryKey: TableStorePrimaryKey[];
52
+ endPrimaryKey: TableStorePrimaryKey[];
53
+ limit?: number;
54
+ }
55
+ export interface BatchWriteRequest {
56
+ rows: PutRowRequest[];
57
+ }
58
+ export interface CacheRefreshRequest {
59
+ hostname: string;
60
+ siteId: string | number;
61
+ urls: string[];
62
+ }
63
+ export interface CacheRefreshResponse {
64
+ success: boolean;
65
+ hostname: string;
66
+ siteId?: string | number;
67
+ taskId?: string;
68
+ purgedUrlCount: number;
69
+ backend: 'inner-api' | 'internal-api';
70
+ apiRequestId?: string;
71
+ note?: string;
72
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIENhY2hlTW9kZSA9ICdsb2NhbCcgfCAnY2VudHJhbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSldUUGF5bG9hZCB7XG4gIHVpZDogc3RyaW5nO1xuICBhcHA6IHN0cmluZztcbiAgYnVpbGRJZDogc3RyaW5nO1xuICBpYXQ/OiBudW1iZXI7XG4gIGV4cD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5hbnRDb250ZXh0IHtcbiAgdWlkOiBzdHJpbmc7XG4gIGFwcDogc3RyaW5nO1xuICBidWlsZElkOiBzdHJpbmc7XG4gIC8qKiBgJHt1aWR9LyR7YXBwfWAgKi9cbiAgYXBwSWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTVFNUb2tlblJlc3BvbnNlIHtcbiAgYWNjZXNzS2V5SWQ6IHN0cmluZztcbiAgYWNjZXNzS2V5U2VjcmV0OiBzdHJpbmc7XG4gIHNlY3VyaXR5VG9rZW46IHN0cmluZztcbiAgZXhwaXJhdGlvbjogc3RyaW5nO1xuICBidWNrZXQ6IHN0cmluZztcbiAgLyoqIFwie3VpZH0ve2FwcH0vXCIgKi9cbiAgcHJlZml4OiBzdHJpbmc7XG4gIHJlZ2lvbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlU3RvcmVQcmltYXJ5S2V5IHtcbiAgbmFtZTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlU3RvcmVDb2x1bW4ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBCdWZmZXI7XG4gIHRpbWVzdGFtcD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYWJsZVN0b3JlUm93IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgY29sdW1ucz86IFRhYmxlU3RvcmVDb2x1bW5bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHZXRSb3dSZXF1ZXN0IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQdXRSb3dSZXF1ZXN0IHtcbiAgcHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgY29sdW1uczogVGFibGVTdG9yZUNvbHVtbltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlbGV0ZVJvd1JlcXVlc3Qge1xuICBwcmltYXJ5S2V5OiBUYWJsZVN0b3JlUHJpbWFyeUtleVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdldFJhbmdlUmVxdWVzdCB7XG4gIHN0YXJ0UHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgZW5kUHJpbWFyeUtleTogVGFibGVTdG9yZVByaW1hcnlLZXlbXTtcbiAgbGltaXQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmF0Y2hXcml0ZVJlcXVlc3Qge1xuICByb3dzOiBQdXRSb3dSZXF1ZXN0W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FjaGVSZWZyZXNoUmVxdWVzdCB7XG4gIGhvc3RuYW1lOiBzdHJpbmc7XG4gIHNpdGVJZDogc3RyaW5nIHwgbnVtYmVyO1xuICB1cmxzOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYWNoZVJlZnJlc2hSZXNwb25zZSB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIGhvc3RuYW1lOiBzdHJpbmc7XG4gIHNpdGVJZD86IHN0cmluZyB8IG51bWJlcjtcbiAgdGFza0lkPzogc3RyaW5nO1xuICBwdXJnZWRVcmxDb3VudDogbnVtYmVyO1xuICBiYWNrZW5kOiAnaW5uZXItYXBpJyB8ICdpbnRlcm5hbC1hcGknO1xuICBhcGlSZXF1ZXN0SWQ/OiBzdHJpbmc7XG4gIG5vdGU/OiBzdHJpbmc7XG59XG4iXX0=
@@ -0,0 +1,8 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ import { Readable } from 'stream';
5
+ export interface IUploadAdapter {
6
+ upload(key: string, content: Buffer | Readable): Promise<void>;
7
+ uploadFile(key: string, filePath: string): Promise<void>;
8
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhcHRlci5pbnRlcmZhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlcnMvYWRhcHRlci5pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlYWRhYmxlIH0gZnJvbSAnc3RyZWFtJztcblxuZXhwb3J0IGludGVyZmFjZSBJVXBsb2FkQWRhcHRlciB7XG4gIHVwbG9hZChrZXk6IHN0cmluZywgY29udGVudDogQnVmZmVyIHwgUmVhZGFibGUpOiBQcm9taXNlPHZvaWQ+O1xuICB1cGxvYWRGaWxlKGtleTogc3RyaW5nLCBmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcbn1cbiJdfQ==
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 直通 Converter
3
+ *
4
+ * 无操作的 converter,适用于平台直接使用原生 HTTP 请求/响应的场景。
5
+ * 不需要任何格式转换。
6
+ *
7
+ * 在 OpenNext 架构中,converter 负责将平台特定的请求/响应格式与 InternalEvent 互转。
8
+ * 由于目标平台使用标准 HTTP(Node.js http.IncomingMessage / http.ServerResponse),
9
+ * 此 converter 直接透传,不做任何转换。
10
+ */
11
+ declare const converter: {
12
+ convertFrom: (event: any) => Promise<any>;
13
+ convertTo: (result: any) => Promise<any>;
14
+ name: string;
15
+ };
16
+ export default converter;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * 直通 Converter
4
+ *
5
+ * 无操作的 converter,适用于平台直接使用原生 HTTP 请求/响应的场景。
6
+ * 不需要任何格式转换。
7
+ *
8
+ * 在 OpenNext 架构中,converter 负责将平台特定的请求/响应格式与 InternalEvent 互转。
9
+ * 由于目标平台使用标准 HTTP(Node.js http.IncomingMessage / http.ServerResponse),
10
+ * 此 converter 直接透传,不做任何转换。
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const converter = {
14
+ convertFrom: async (event) => event,
15
+ convertTo: async (result) => result,
16
+ name: 'passthrough',
17
+ };
18
+ exports.default = converter;
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFzc3Rocm91Z2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYWRhcHRlcnMvY29udmVydGVycy9wYXNzdGhyb3VnaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7OztHQVNHOztBQUVILE1BQU0sU0FBUyxHQUFHO0lBQ2hCLFdBQVcsRUFBRSxLQUFLLEVBQUUsS0FBVSxFQUFFLEVBQUUsQ0FBQyxLQUFLO0lBQ3hDLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBVyxFQUFFLEVBQUUsQ0FBQyxNQUFNO0lBQ3hDLElBQUksRUFBRSxhQUFhO0NBQ3BCLENBQUM7QUFFRixrQkFBZSxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIOebtOmAmiBDb252ZXJ0ZXJcbiAqXG4gKiDml6Dmk43kvZznmoQgY29udmVydGVy77yM6YCC55So5LqO5bmz5Y+w55u05o6l5L2/55So5Y6f55SfIEhUVFAg6K+35rGCL+WTjeW6lOeahOWcuuaZr+OAglxuICog5LiN6ZyA6KaB5Lu75L2V5qC85byP6L2s5o2i44CCXG4gKlxuICog5ZyoIE9wZW5OZXh0IOaetuaehOS4re+8jGNvbnZlcnRlciDotJ/otKPlsIblubPlj7DnibnlrprnmoTor7fmsYIv5ZON5bqU5qC85byP5LiOIEludGVybmFsRXZlbnQg5LqS6L2s44CCXG4gKiDnlLHkuo7nm67moIflubPlj7Dkvb/nlKjmoIflh4YgSFRUUO+8iE5vZGUuanMgaHR0cC5JbmNvbWluZ01lc3NhZ2UgLyBodHRwLlNlcnZlclJlc3BvbnNl77yJ77yMXG4gKiDmraQgY29udmVydGVyIOebtOaOpemAj+S8oO+8jOS4jeWBmuS7u+S9lei9rOaNouOAglxuICovXG5cbmNvbnN0IGNvbnZlcnRlciA9IHtcbiAgY29udmVydEZyb206IGFzeW5jIChldmVudDogYW55KSA9PiBldmVudCxcbiAgY29udmVydFRvOiBhc3luYyAocmVzdWx0OiBhbnkpID0+IHJlc3VsdCxcbiAgbmFtZTogJ3Bhc3N0aHJvdWdoJyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbnZlcnRlcjtcbiJdfQ==
@@ -0,0 +1,3 @@
1
+ export { IUploadAdapter } from './adapter.interface';
2
+ export { LocalFSUploadAdapter } from './local-fs.adapter';
3
+ export { OSSUploadAdapter } from './oss.adapter';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OSSUploadAdapter = exports.LocalFSUploadAdapter = void 0;
4
+ var local_fs_adapter_1 = require("./local-fs.adapter");
5
+ Object.defineProperty(exports, "LocalFSUploadAdapter", { enumerable: true, get: function () { return local_fs_adapter_1.LocalFSUploadAdapter; } });
6
+ var oss_adapter_1 = require("./oss.adapter");
7
+ Object.defineProperty(exports, "OSSUploadAdapter", { enumerable: true, get: function () { return oss_adapter_1.OSSUploadAdapter; } });
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlcnMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsdURBQTBEO0FBQWpELHdIQUFBLG9CQUFvQixPQUFBO0FBQzdCLDZDQUFpRDtBQUF4QywrR0FBQSxnQkFBZ0IsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IElVcGxvYWRBZGFwdGVyIH0gZnJvbSAnLi9hZGFwdGVyLmludGVyZmFjZSc7XG5leHBvcnQgeyBMb2NhbEZTVXBsb2FkQWRhcHRlciB9IGZyb20gJy4vbG9jYWwtZnMuYWRhcHRlcic7XG5leHBvcnQgeyBPU1NVcGxvYWRBZGFwdGVyIH0gZnJvbSAnLi9vc3MuYWRhcHRlcic7XG4iXX0=
@@ -0,0 +1,12 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ import { Readable } from 'stream';
5
+ import { IUploadAdapter } from './adapter.interface';
6
+ export declare class LocalFSUploadAdapter implements IUploadAdapter {
7
+ private readonly targetDir;
8
+ constructor(targetDir: string);
9
+ init(): Promise<void>;
10
+ upload(key: string, content: Buffer | Readable): Promise<void>;
11
+ uploadFile(key: string, filePath: string): Promise<void>;
12
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalFSUploadAdapter = void 0;
4
+ const fs = require("fs/promises");
5
+ const path = require("path");
6
+ const fs_1 = require("fs");
7
+ class LocalFSUploadAdapter {
8
+ constructor(targetDir) {
9
+ this.targetDir = targetDir;
10
+ }
11
+ async init() {
12
+ await fs.mkdir(this.targetDir, { recursive: true });
13
+ }
14
+ async upload(key, content) {
15
+ const fullPath = path.join(this.targetDir, key);
16
+ await fs.mkdir(path.dirname(fullPath), { recursive: true });
17
+ if (Buffer.isBuffer(content)) {
18
+ await fs.writeFile(fullPath, content);
19
+ }
20
+ else {
21
+ await new Promise((resolve, reject) => {
22
+ const ws = (0, fs_1.createWriteStream)(fullPath);
23
+ content.pipe(ws);
24
+ ws.on('finish', resolve);
25
+ ws.on('error', reject);
26
+ content.on('error', reject);
27
+ });
28
+ }
29
+ }
30
+ async uploadFile(key, filePath) {
31
+ const fullPath = path.join(this.targetDir, key);
32
+ await fs.mkdir(path.dirname(fullPath), { recursive: true });
33
+ await fs.copyFile(filePath, fullPath);
34
+ }
35
+ }
36
+ exports.LocalFSUploadAdapter = LocalFSUploadAdapter;
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtZnMuYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9sb2NhbC1mcy5hZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGtDQUFrQztBQUNsQyw2QkFBNkI7QUFFN0IsMkJBQXVDO0FBR3ZDLE1BQWEsb0JBQW9CO0lBQy9CLFlBQTZCLFNBQWlCO1FBQWpCLGNBQVMsR0FBVCxTQUFTLENBQVE7SUFBRyxDQUFDO0lBRWxELEtBQUssQ0FBQyxJQUFJO1FBQ1IsTUFBTSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFXLEVBQUUsT0FBMEI7UUFDbEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFFNUQsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzVCLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDdkM7YUFBTTtZQUNMLE1BQU0sSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQzFDLE1BQU0sRUFBRSxHQUFHLElBQUEsc0JBQWlCLEVBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2pCLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUN6QixFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdkIsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDOUIsQ0FBQyxDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQVcsRUFBRSxRQUFnQjtRQUM1QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDaEQsTUFBTSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM1RCxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7Q0FDRjtBQTdCRCxvREE2QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcy9wcm9taXNlcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgUmVhZGFibGUgfSBmcm9tICdzdHJlYW0nO1xuaW1wb3J0IHsgY3JlYXRlV3JpdGVTdHJlYW0gfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBJVXBsb2FkQWRhcHRlciB9IGZyb20gJy4vYWRhcHRlci5pbnRlcmZhY2UnO1xuXG5leHBvcnQgY2xhc3MgTG9jYWxGU1VwbG9hZEFkYXB0ZXIgaW1wbGVtZW50cyBJVXBsb2FkQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgdGFyZ2V0RGlyOiBzdHJpbmcpIHt9XG5cbiAgYXN5bmMgaW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBmcy5ta2Rpcih0aGlzLnRhcmdldERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH1cblxuICBhc3luYyB1cGxvYWQoa2V5OiBzdHJpbmcsIGNvbnRlbnQ6IEJ1ZmZlciB8IFJlYWRhYmxlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4odGhpcy50YXJnZXREaXIsIGtleSk7XG4gICAgYXdhaXQgZnMubWtkaXIocGF0aC5kaXJuYW1lKGZ1bGxQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNvbnRlbnQpKSB7XG4gICAgICBhd2FpdCBmcy53cml0ZUZpbGUoZnVsbFBhdGgsIGNvbnRlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHdzID0gY3JlYXRlV3JpdGVTdHJlYW0oZnVsbFBhdGgpO1xuICAgICAgICBjb250ZW50LnBpcGUod3MpO1xuICAgICAgICB3cy5vbignZmluaXNoJywgcmVzb2x2ZSk7XG4gICAgICAgIHdzLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgICAgIGNvbnRlbnQub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHVwbG9hZEZpbGUoa2V5OiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbih0aGlzLnRhcmdldERpciwga2V5KTtcbiAgICBhd2FpdCBmcy5ta2RpcihwYXRoLmRpcm5hbWUoZnVsbFBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBhd2FpdCBmcy5jb3B5RmlsZShmaWxlUGF0aCwgZnVsbFBhdGgpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,13 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ import { Readable } from 'stream';
5
+ import { STSTokenResponse } from '../_protocol';
6
+ import { IUploadAdapter } from './adapter.interface';
7
+ export declare class OSSUploadAdapter implements IUploadAdapter {
8
+ private client;
9
+ private prefix;
10
+ constructor(stsCredentials: STSTokenResponse);
11
+ upload(key: string, content: Buffer | Readable): Promise<void>;
12
+ uploadFile(key: string, filePath: string): Promise<void>;
13
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OSSUploadAdapter = void 0;
4
+ class OSSUploadAdapter {
5
+ constructor(stsCredentials) {
6
+ this.prefix = stsCredentials.prefix;
7
+ const OSS = require('ali-oss');
8
+ this.client = new OSS({
9
+ region: `oss-${stsCredentials.region}`,
10
+ bucket: stsCredentials.bucket,
11
+ accessKeyId: stsCredentials.accessKeyId,
12
+ accessKeySecret: stsCredentials.accessKeySecret,
13
+ stsToken: stsCredentials.securityToken,
14
+ });
15
+ }
16
+ async upload(key, content) {
17
+ const ossKey = this.prefix + key;
18
+ await this.client.put(ossKey, content);
19
+ }
20
+ async uploadFile(key, filePath) {
21
+ const ossKey = this.prefix + key;
22
+ await this.client.put(ossKey, filePath);
23
+ }
24
+ }
25
+ exports.OSSUploadAdapter = OSSUploadAdapter;
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3NzLmFkYXB0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlcnMvb3NzLmFkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsTUFBYSxnQkFBZ0I7SUFJM0IsWUFBWSxjQUFnQztRQUMxQyxJQUFJLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUM7UUFDcEMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUM7WUFDcEIsTUFBTSxFQUFFLE9BQU8sY0FBYyxDQUFDLE1BQU0sRUFBRTtZQUN0QyxNQUFNLEVBQUUsY0FBYyxDQUFDLE1BQU07WUFDN0IsV0FBVyxFQUFFLGNBQWMsQ0FBQyxXQUFXO1lBQ3ZDLGVBQWUsRUFBRSxjQUFjLENBQUMsZUFBZTtZQUMvQyxRQUFRLEVBQUUsY0FBYyxDQUFDLGFBQWE7U0FDdkMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBVyxFQUFFLE9BQTBCO1FBQ2xELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDO1FBQ2pDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE9BQWMsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQVcsRUFBRSxRQUFnQjtRQUM1QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztRQUNqQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0Y7QUF6QkQsNENBeUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUmVhZGFibGUgfSBmcm9tICdzdHJlYW0nO1xuaW1wb3J0IHsgU1RTVG9rZW5SZXNwb25zZSB9IGZyb20gJ0BwY2cvcHJvdG9jb2wnO1xuaW1wb3J0IHsgSVVwbG9hZEFkYXB0ZXIgfSBmcm9tICcuL2FkYXB0ZXIuaW50ZXJmYWNlJztcblxuZXhwb3J0IGNsYXNzIE9TU1VwbG9hZEFkYXB0ZXIgaW1wbGVtZW50cyBJVXBsb2FkQWRhcHRlciB7XG4gIHByaXZhdGUgY2xpZW50OiBhbnk7XG4gIHByaXZhdGUgcHJlZml4OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc3RzQ3JlZGVudGlhbHM6IFNUU1Rva2VuUmVzcG9uc2UpIHtcbiAgICB0aGlzLnByZWZpeCA9IHN0c0NyZWRlbnRpYWxzLnByZWZpeDtcbiAgICBjb25zdCBPU1MgPSByZXF1aXJlKCdhbGktb3NzJyk7XG4gICAgdGhpcy5jbGllbnQgPSBuZXcgT1NTKHtcbiAgICAgIHJlZ2lvbjogYG9zcy0ke3N0c0NyZWRlbnRpYWxzLnJlZ2lvbn1gLFxuICAgICAgYnVja2V0OiBzdHNDcmVkZW50aWFscy5idWNrZXQsXG4gICAgICBhY2Nlc3NLZXlJZDogc3RzQ3JlZGVudGlhbHMuYWNjZXNzS2V5SWQsXG4gICAgICBhY2Nlc3NLZXlTZWNyZXQ6IHN0c0NyZWRlbnRpYWxzLmFjY2Vzc0tleVNlY3JldCxcbiAgICAgIHN0c1Rva2VuOiBzdHNDcmVkZW50aWFscy5zZWN1cml0eVRva2VuLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgdXBsb2FkKGtleTogc3RyaW5nLCBjb250ZW50OiBCdWZmZXIgfCBSZWFkYWJsZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG9zc0tleSA9IHRoaXMucHJlZml4ICsga2V5O1xuICAgIGF3YWl0IHRoaXMuY2xpZW50LnB1dChvc3NLZXksIGNvbnRlbnQgYXMgYW55KTtcbiAgfVxuXG4gIGFzeW5jIHVwbG9hZEZpbGUoa2V5OiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBvc3NLZXkgPSB0aGlzLnByZWZpeCArIGtleTtcbiAgICBhd2FpdCB0aGlzLmNsaWVudC5wdXQob3NzS2V5LCBmaWxlUGF0aCk7XG4gIH1cbn1cbiJdfQ==