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.
- package/LICENSE +21 -0
- package/README.md +65 -0
- package/dist/_inline-overrides.js +7 -0
- package/dist/_protocol/endpoints.d.ts +14 -0
- package/dist/_protocol/endpoints.js +24 -0
- package/dist/_protocol/index.d.ts +3 -0
- package/dist/_protocol/index.js +20 -0
- package/dist/_protocol/keys.d.ts +27 -0
- package/dist/_protocol/keys.js +36 -0
- package/dist/_protocol/types.d.ts +72 -0
- package/dist/_protocol/types.js +3 -0
- package/dist/adapters/adapter.interface.d.ts +8 -0
- package/dist/adapters/adapter.interface.js +3 -0
- package/dist/adapters/converters/passthrough.d.ts +16 -0
- package/dist/adapters/converters/passthrough.js +19 -0
- package/dist/adapters/index.d.ts +3 -0
- package/dist/adapters/index.js +8 -0
- package/dist/adapters/local-fs.adapter.d.ts +12 -0
- package/dist/adapters/local-fs.adapter.js +37 -0
- package/dist/adapters/oss.adapter.d.ts +13 -0
- package/dist/adapters/oss.adapter.js +26 -0
- package/dist/adapters/wrappers/node-server.d.ts +57 -0
- package/dist/adapters/wrappers/node-server.js +282 -0
- package/dist/bin/cli.d.ts +2 -0
- package/dist/bin/cli.js +21 -0
- package/dist/commands/build.d.ts +10 -0
- package/dist/commands/build.js +247 -0
- package/dist/commands/deploy.d.ts +11 -0
- package/dist/commands/deploy.js +116 -0
- package/dist/commands/purge.d.ts +15 -0
- package/dist/commands/purge.js +135 -0
- package/dist/commands/serve.d.ts +14 -0
- package/dist/commands/serve.js +162 -0
- package/dist/commands/upload-assets.d.ts +12 -0
- package/dist/commands/upload-assets.js +46 -0
- package/dist/commands/upload-cache.d.ts +13 -0
- package/dist/commands/upload-cache.js +70 -0
- package/dist/compile/compileCacheAssetsManifest.d.ts +1 -0
- package/dist/compile/compileCacheAssetsManifest.js +67 -0
- package/dist/config/default-open-next-config.d.ts +3 -0
- package/dist/config/default-open-next-config.js +30 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +36 -0
- package/dist/overrides/incrementalCache/gateway.d.ts +32 -0
- package/dist/overrides/incrementalCache/gateway.js +160 -0
- package/dist/overrides/tagCache/gateway.d.ts +26 -0
- package/dist/overrides/tagCache/gateway.js +211 -0
- package/dist/runtime/gateway-auth.d.ts +51 -0
- package/dist/runtime/gateway-auth.js +121 -0
- package/dist/runtime/image-proxy.d.ts +16 -0
- package/dist/runtime/image-proxy.js +149 -0
- package/dist/util/fs.d.ts +3 -0
- package/dist/util/fs.js +39 -0
- package/package.json +47 -0
- 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=
|
package/dist/bin/cli.js
ADDED
|
@@ -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;
|