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
@@ -0,0 +1,57 @@
1
+ /**
2
+ * pcg Node Server Wrapper
3
+ *
4
+ * OpenNext wrapper 的长进程形态:不依赖 FaaS runtime,自带 HTTP server 直接监听
5
+ * `process.env.PORT`(默认 3000),`node index.mjs` 即可独立运行。
6
+ *
7
+ * 单个请求会按以下顺序分发:
8
+ * 1. `/__health` → 200 OK(供 pcg serve / 容器就绪探针)
9
+ * 2. `/_pcg/image/*` → image-proxy(签名 client 调 Gateway)
10
+ * 3. `.open-next/assets/<urlPath>` 命中 → 直接 pipe 文件流
11
+ * 4. 其他 → OpenNext handler(Next SSR/API/RSC)
12
+ *
13
+ * 三段逻辑此前分散在 platform-function wrapper(image proxy + req→event 桥接)
14
+ * 与 `pcg serve` 父进程(静态资源 + reverse proxy)中;此次统一进 wrapper,
15
+ * 让 `pcg serve` 退化为纯子进程管理器。
16
+ */
17
+ interface InternalEvent {
18
+ type: 'core';
19
+ method: string;
20
+ rawPath: string;
21
+ url: string;
22
+ body?: string;
23
+ headers: Record<string, string>;
24
+ query: Record<string, string | string[]>;
25
+ cookies: Record<string, string>;
26
+ remoteAddress: string;
27
+ }
28
+ interface StreamCreator {
29
+ writeHeaders(prelude: {
30
+ statusCode: number;
31
+ cookies: string[];
32
+ headers: Record<string, string>;
33
+ }): import('stream').Writable;
34
+ abortSignal?: AbortSignal;
35
+ onFinish?: () => void;
36
+ }
37
+ declare type OpenNextHandler = (event: InternalEvent, ctx: {
38
+ streamCreator: StreamCreator;
39
+ }) => Promise<void>;
40
+ /**
41
+ * OpenNext 在加载完 server bundle 后调用此函数,我们在此启动 HTTP server。
42
+ *
43
+ * assets 目录解析为 `<cwd>/../../assets`:OpenNext 默认产物结构是
44
+ * `.open-next/server-functions/default/index.mjs`,运行时无论是用户手动
45
+ * `cd` 后 `node index.mjs` 还是 `pcg serve` spawn(`cwd: serverDir`),
46
+ * `process.cwd()` 都等于 `server-functions/default/`,assets 必在 `../../assets/`。
47
+ */
48
+ declare function wrapper(handler: OpenNextHandler): Promise<void>;
49
+ /**
50
+ * OpenNext 默认导出契约:`{ wrapper, name, supportStreaming }`。
51
+ */
52
+ declare const wrapperDef: {
53
+ wrapper: typeof wrapper;
54
+ name: string;
55
+ supportStreaming: boolean;
56
+ };
57
+ export default wrapperDef;
@@ -0,0 +1,282 @@
1
+ "use strict";
2
+ /**
3
+ * pcg Node Server Wrapper
4
+ *
5
+ * OpenNext wrapper 的长进程形态:不依赖 FaaS runtime,自带 HTTP server 直接监听
6
+ * `process.env.PORT`(默认 3000),`node index.mjs` 即可独立运行。
7
+ *
8
+ * 单个请求会按以下顺序分发:
9
+ * 1. `/__health` → 200 OK(供 pcg serve / 容器就绪探针)
10
+ * 2. `/_pcg/image/*` → image-proxy(签名 client 调 Gateway)
11
+ * 3. `.open-next/assets/<urlPath>` 命中 → 直接 pipe 文件流
12
+ * 4. 其他 → OpenNext handler(Next SSR/API/RSC)
13
+ *
14
+ * 三段逻辑此前分散在 platform-function wrapper(image proxy + req→event 桥接)
15
+ * 与 `pcg serve` 父进程(静态资源 + reverse proxy)中;此次统一进 wrapper,
16
+ * 让 `pcg serve` 退化为纯子进程管理器。
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ const http = require("http");
20
+ const fs = require("fs");
21
+ const path = require("path");
22
+ const image_proxy_1 = require("../../runtime/image-proxy");
23
+ // === 静态资源 MIME(与原 pcg serve 父进程实现保持一致) ===
24
+ const MIME_TYPES = {
25
+ '.js': 'application/javascript',
26
+ '.mjs': 'application/javascript',
27
+ '.css': 'text/css',
28
+ '.html': 'text/html',
29
+ '.json': 'application/json',
30
+ '.png': 'image/png',
31
+ '.jpg': 'image/jpeg',
32
+ '.jpeg': 'image/jpeg',
33
+ '.gif': 'image/gif',
34
+ '.svg': 'image/svg+xml',
35
+ '.ico': 'image/x-icon',
36
+ '.woff': 'font/woff',
37
+ '.woff2': 'font/woff2',
38
+ '.ttf': 'font/ttf',
39
+ '.map': 'application/json',
40
+ '.txt': 'text/plain',
41
+ '.webp': 'image/webp',
42
+ };
43
+ // === 请求 → InternalEvent 桥接工具 ===
44
+ function parseQuery(url) {
45
+ const idx = url.indexOf('?');
46
+ if (idx === -1)
47
+ return {};
48
+ const params = {};
49
+ const searchParams = new URLSearchParams(url.slice(idx + 1));
50
+ for (const [key, value] of searchParams) {
51
+ const existing = params[key];
52
+ if (existing === undefined) {
53
+ params[key] = value;
54
+ }
55
+ else if (Array.isArray(existing)) {
56
+ existing.push(value);
57
+ }
58
+ else {
59
+ params[key] = [existing, value];
60
+ }
61
+ }
62
+ return params;
63
+ }
64
+ function parseCookies(cookieHeader) {
65
+ if (!cookieHeader)
66
+ return {};
67
+ const cookies = {};
68
+ for (const pair of cookieHeader.split(';')) {
69
+ const eqIdx = pair.indexOf('=');
70
+ if (eqIdx === -1)
71
+ continue;
72
+ const name = pair.slice(0, eqIdx).trim();
73
+ const value = pair.slice(eqIdx + 1).trim();
74
+ if (name)
75
+ cookies[name] = value;
76
+ }
77
+ return cookies;
78
+ }
79
+ function flattenHeaders(rawHeaders) {
80
+ const headers = {};
81
+ for (const [key, value] of Object.entries(rawHeaders)) {
82
+ if (value === undefined)
83
+ continue;
84
+ headers[key.toLowerCase()] = Array.isArray(value)
85
+ ? value.join(', ')
86
+ : value;
87
+ }
88
+ return headers;
89
+ }
90
+ async function readBody(req) {
91
+ if (req.method === 'GET' || req.method === 'HEAD')
92
+ return undefined;
93
+ return new Promise((resolve, reject) => {
94
+ const chunks = [];
95
+ req.on('data', (chunk) => chunks.push(chunk));
96
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
97
+ req.on('error', reject);
98
+ });
99
+ }
100
+ // === 静态资源 ===
101
+ /**
102
+ * 服务 .open-next/assets/ 下的静态文件。
103
+ *
104
+ * 匹配两类:
105
+ * 1. `/_next/static/*` —— Next.js 生成的带 hash 资源,长缓存 immutable
106
+ * 2. `/<public-file>` —— `public/` 提取出来的根级静态文件,短缓存
107
+ *
108
+ * 不存在的路径返回 false 让上层 fallback 到 OpenNext handler(API / SSR /
109
+ * `_pcg/*` 等)。
110
+ */
111
+ function serveStaticFile(assetsDir, req, res) {
112
+ var _a, _b;
113
+ const urlPath = (_b = (_a = req.url) === null || _a === void 0 ? void 0 : _a.split('?')[0]) !== null && _b !== void 0 ? _b : '/';
114
+ if (urlPath === '/' || !urlPath.startsWith('/'))
115
+ return false;
116
+ const filePath = path.join(assetsDir, urlPath);
117
+ const normalizedPath = path.normalize(filePath);
118
+ if (!normalizedPath.startsWith(assetsDir)) {
119
+ res.writeHead(403);
120
+ res.end();
121
+ return true;
122
+ }
123
+ let stat;
124
+ try {
125
+ stat = fs.statSync(normalizedPath);
126
+ }
127
+ catch (_c) {
128
+ return false;
129
+ }
130
+ if (!stat.isFile())
131
+ return false;
132
+ const ext = path.extname(normalizedPath);
133
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
134
+ const isHashedAsset = urlPath.startsWith('/_next/static/');
135
+ res.writeHead(200, {
136
+ 'Content-Type': contentType,
137
+ 'Content-Length': stat.size,
138
+ 'Cache-Control': isHashedAsset
139
+ ? 'public, max-age=31536000, immutable'
140
+ : 'public, max-age=60',
141
+ });
142
+ fs.createReadStream(normalizedPath).pipe(res);
143
+ return true;
144
+ }
145
+ /**
146
+ * 把 OpenNext 提供的 handler 包成 http (req, res) 处理函数。
147
+ * 负责: body 读取、event 组装、流式响应、500 兜底。
148
+ */
149
+ function bridgeOpenNextHandler(handler) {
150
+ return async (req, res) => {
151
+ var _a, _b, _c, _d, _e, _f;
152
+ try {
153
+ const rawUrl = req.url || '/';
154
+ const headers = flattenHeaders(req.headers);
155
+ const body = await readBody(req);
156
+ // OpenNext 内部对 event.url 执行 `new URL(...)`,必须是绝对 URL —— 用
157
+ // host header + x-forwarded-proto 还原,行为与 OpenNext 内置 node
158
+ // converter 一致 (@opennextjs/aws/dist/overrides/converters/node.js)。
159
+ const host = headers['host'] || `localhost:${(_a = process.env.PORT) !== null && _a !== void 0 ? _a : '3000'}`;
160
+ 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';
161
+ const absoluteUrl = new URL(`${proto}://${host}${rawUrl}`);
162
+ const event = {
163
+ type: 'core',
164
+ method: req.method || 'GET',
165
+ rawPath: absoluteUrl.pathname,
166
+ url: absoluteUrl.href,
167
+ body,
168
+ headers,
169
+ query: parseQuery(rawUrl),
170
+ cookies: parseCookies(headers['cookie']),
171
+ remoteAddress: ((_e = (_d = headers['x-forwarded-for']) === null || _d === void 0 ? void 0 : _d.split(',')[0]) === null || _e === void 0 ? void 0 : _e.trim()) ||
172
+ headers['x-real-ip'] ||
173
+ ((_f = req.socket) === null || _f === void 0 ? void 0 : _f.remoteAddress) ||
174
+ '127.0.0.1',
175
+ };
176
+ const abortController = new AbortController();
177
+ res.on('close', () => abortController.abort());
178
+ const streamCreator = {
179
+ writeHeaders(prelude) {
180
+ res.setHeader('Set-Cookie', prelude.cookies);
181
+ res.writeHead(prelude.statusCode, prelude.headers);
182
+ res.flushHeaders();
183
+ return res;
184
+ },
185
+ abortSignal: abortController.signal,
186
+ };
187
+ await handler(event, { streamCreator });
188
+ }
189
+ catch (err) {
190
+ if (!res.headersSent) {
191
+ const isDev = process.env.NODE_ENV !== 'production';
192
+ res.writeHead(500, { 'Content-Type': 'application/json' });
193
+ res.end(JSON.stringify({
194
+ error: 'Internal Server Error',
195
+ ...(isDev && { message: err.message, stack: err.stack }),
196
+ }));
197
+ }
198
+ else if (!res.writableEnded) {
199
+ res.end();
200
+ }
201
+ }
202
+ };
203
+ }
204
+ /**
205
+ * OpenNext 在加载完 server bundle 后调用此函数,我们在此启动 HTTP server。
206
+ *
207
+ * assets 目录解析为 `<cwd>/../../assets`:OpenNext 默认产物结构是
208
+ * `.open-next/server-functions/default/index.mjs`,运行时无论是用户手动
209
+ * `cd` 后 `node index.mjs` 还是 `pcg serve` spawn(`cwd: serverDir`),
210
+ * `process.cwd()` 都等于 `server-functions/default/`,assets 必在 `../../assets/`。
211
+ */
212
+ async function wrapper(handler) {
213
+ var _a;
214
+ const port = parseInt((_a = process.env.PORT) !== null && _a !== void 0 ? _a : '3000', 10);
215
+ const assetsDir = path.resolve(process.cwd(), '..', '..', 'assets');
216
+ if (!fs.existsSync(assetsDir)) {
217
+ console.warn(`[pcg-node] assets directory not found at ${assetsDir} — static file requests will fall through to Next handler`);
218
+ }
219
+ const dispatchToNext = bridgeOpenNextHandler(handler);
220
+ const server = http.createServer(async (req, res) => {
221
+ var _a, _b, _c;
222
+ const urlPath = (_b = (_a = req.url) === null || _a === void 0 ? void 0 : _a.split('?')[0]) !== null && _b !== void 0 ? _b : '/';
223
+ // 1. health check
224
+ if (urlPath === '/__health') {
225
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
226
+ res.end('OK');
227
+ return;
228
+ }
229
+ // 2. 图片优化代理 —— `<img>` 发不出自定义签名 header,wrapper 在此代发
230
+ if ((_c = req.url) === null || _c === void 0 ? void 0 : _c.startsWith('/_pcg/image/')) {
231
+ try {
232
+ await (0, image_proxy_1.handleImageProxy)(req, res);
233
+ }
234
+ catch (err) {
235
+ console.error('[pcg-node] image-proxy error:', err);
236
+ if (!res.headersSent) {
237
+ res.writeHead(500, { 'Content-Type': 'application/json' });
238
+ res.end(JSON.stringify({ error: 'Image proxy failed' }));
239
+ }
240
+ else if (!res.writableEnded) {
241
+ res.end();
242
+ }
243
+ }
244
+ return;
245
+ }
246
+ // 3. 静态资源(.open-next/assets/)
247
+ if (serveStaticFile(assetsDir, req, res))
248
+ return;
249
+ // 4. fallback —— OpenNext Next.js handler
250
+ await dispatchToNext(req, res);
251
+ });
252
+ // 优雅关闭:停止接收新连接,等 in-flight 请求自然结束,5s 兜底强制退出
253
+ let shuttingDown = false;
254
+ const shutdown = (signal) => {
255
+ if (shuttingDown)
256
+ return;
257
+ shuttingDown = true;
258
+ console.log(`[pcg-node] ${signal} received, shutting down...`);
259
+ server.close(() => process.exit(0));
260
+ setTimeout(() => process.exit(0), 5000).unref();
261
+ };
262
+ process.on('SIGINT', () => shutdown('SIGINT'));
263
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
264
+ await new Promise(resolve => {
265
+ server.listen(port, () => {
266
+ console.log(`[pcg-node] Listening on port ${port}`);
267
+ console.log(`[pcg-node] assets: ${assetsDir}`);
268
+ console.log(`[pcg-node] routes: /__health, /_pcg/image/*, /_next/static/*, <next>`);
269
+ resolve();
270
+ });
271
+ });
272
+ }
273
+ /**
274
+ * OpenNext 默认导出契约:`{ wrapper, name, supportStreaming }`。
275
+ */
276
+ const wrapperDef = {
277
+ wrapper,
278
+ name: 'pcg-node',
279
+ supportStreaming: true,
280
+ };
281
+ 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=
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const build_1 = require("../commands/build");
6
+ const deploy_1 = require("../commands/deploy");
7
+ const upload_cache_1 = require("../commands/upload-cache");
8
+ const serve_1 = require("../commands/serve");
9
+ const purge_1 = require("../commands/purge");
10
+ const program = new commander_1.Command();
11
+ program
12
+ .name('pcg')
13
+ .description('CLI tool for building and deploying Next.js apps to pages-cache-gateway')
14
+ .version('0.1.0');
15
+ program.addCommand((0, build_1.createBuildCommand)());
16
+ program.addCommand((0, deploy_1.createDeployCommand)());
17
+ program.addCommand((0, upload_cache_1.createUploadCacheCommand)());
18
+ program.addCommand((0, serve_1.createServeCommand)());
19
+ program.addCommand((0, purge_1.createPurgeCommand)());
20
+ program.parse(process.argv);
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jpbi9jbGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEseUNBQW9DO0FBQ3BDLDZDQUF1RDtBQUN2RCwrQ0FBeUQ7QUFDekQsMkRBQW9FO0FBQ3BFLDZDQUF1RDtBQUN2RCw2Q0FBdUQ7QUFFdkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxtQkFBTyxFQUFFLENBQUM7QUFFOUIsT0FBTztLQUNKLElBQUksQ0FBQyxLQUFLLENBQUM7S0FDWCxXQUFXLENBQUMseUVBQXlFLENBQUM7S0FDdEYsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRXBCLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBQSwwQkFBa0IsR0FBRSxDQUFDLENBQUM7QUFDekMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFBLDRCQUFtQixHQUFFLENBQUMsQ0FBQztBQUMxQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUEsdUNBQXdCLEdBQUUsQ0FBQyxDQUFDO0FBQy9DLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBQSwwQkFBa0IsR0FBRSxDQUFDLENBQUM7QUFDekMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFBLDBCQUFrQixHQUFFLENBQUMsQ0FBQztBQUV6QyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBjcmVhdGVCdWlsZENvbW1hbmQgfSBmcm9tICcuLi9jb21tYW5kcy9idWlsZCc7XG5pbXBvcnQgeyBjcmVhdGVEZXBsb3lDb21tYW5kIH0gZnJvbSAnLi4vY29tbWFuZHMvZGVwbG95JztcbmltcG9ydCB7IGNyZWF0ZVVwbG9hZENhY2hlQ29tbWFuZCB9IGZyb20gJy4uL2NvbW1hbmRzL3VwbG9hZC1jYWNoZSc7XG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZUNvbW1hbmQgfSBmcm9tICcuLi9jb21tYW5kcy9zZXJ2ZSc7XG5pbXBvcnQgeyBjcmVhdGVQdXJnZUNvbW1hbmQgfSBmcm9tICcuLi9jb21tYW5kcy9wdXJnZSc7XG5cbmNvbnN0IHByb2dyYW0gPSBuZXcgQ29tbWFuZCgpO1xuXG5wcm9ncmFtXG4gIC5uYW1lKCdwY2cnKVxuICAuZGVzY3JpcHRpb24oJ0NMSSB0b29sIGZvciBidWlsZGluZyBhbmQgZGVwbG95aW5nIE5leHQuanMgYXBwcyB0byBwYWdlcy1jYWNoZS1nYXRld2F5JylcbiAgLnZlcnNpb24oJzAuMS4wJyk7XG5cbnByb2dyYW0uYWRkQ29tbWFuZChjcmVhdGVCdWlsZENvbW1hbmQoKSk7XG5wcm9ncmFtLmFkZENvbW1hbmQoY3JlYXRlRGVwbG95Q29tbWFuZCgpKTtcbnByb2dyYW0uYWRkQ29tbWFuZChjcmVhdGVVcGxvYWRDYWNoZUNvbW1hbmQoKSk7XG5wcm9ncmFtLmFkZENvbW1hbmQoY3JlYXRlU2VydmVDb21tYW5kKCkpO1xucHJvZ3JhbS5hZGRDb21tYW5kKGNyZWF0ZVB1cmdlQ29tbWFuZCgpKTtcblxucHJvZ3JhbS5wYXJzZShwcm9jZXNzLmFyZ3YpO1xuIl19
@@ -0,0 +1,10 @@
1
+ import { Command } from 'commander';
2
+ export interface BuildOptions {
3
+ dir: string;
4
+ config?: string;
5
+ debug?: boolean;
6
+ dryRun?: boolean;
7
+ forceUnsupportedNext?: boolean;
8
+ }
9
+ export declare function runBuild(opts: BuildOptions): Promise<void>;
10
+ export declare function createBuildCommand(): Command;