@brainfish-ai/devdoc 0.1.50 → 0.1.51

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.
@@ -131,7 +131,7 @@ async function domainAdd(customDomain, options) {
131
131
  }
132
132
  console.log(' Next, add these DNS records to your domain provider:');
133
133
  console.log('');
134
- // Handle new Vercel verification format (array of records)
134
+ // Display verification records from Vercel
135
135
  if (result.verification && Array.isArray(result.verification)) {
136
136
  result.verification.forEach((record, index) => {
137
137
  console.log(` ${index + 1}. ${record.type} Record:`);
@@ -140,21 +140,6 @@ async function domainAdd(customDomain, options) {
140
140
  console.log('');
141
141
  });
142
142
  }
143
- // Show any additional instructions from the API
144
- if (result.instructions && result.instructions.length > 0) {
145
- // Filter out redundant lines that we've already shown
146
- const additionalInstructions = result.instructions.filter(line => !line.includes('Add the following') &&
147
- line.trim() !== '' &&
148
- !line.match(/^\d+\.\s+(CNAME|TXT|A)\s+Record/));
149
- if (additionalInstructions.length > 0) {
150
- additionalInstructions.forEach(line => {
151
- if (line.trim()) {
152
- console.log(` ${line}`);
153
- }
154
- });
155
- console.log('');
156
- }
157
- }
158
143
  logger_1.logger.info('After adding DNS records, run:');
159
144
  console.log(' devdoc domain verify');
160
145
  console.log('');
@@ -229,7 +214,6 @@ async function domainStatus(options) {
229
214
  console.log(` ${result.projectUrl}`);
230
215
  }
231
216
  else if (result.status === 'pending') {
232
- // Handle new Vercel verification format
233
217
  if (result.verification && result.verification.length > 0) {
234
218
  console.log(' Add these DNS records to your domain:');
235
219
  console.log('');
@@ -241,20 +225,6 @@ async function domainStatus(options) {
241
225
  });
242
226
  logger_1.logger.info('After adding DNS records, run: devdoc domain verify');
243
227
  }
244
- // Handle legacy DNS records format
245
- else if (result.dnsRecords) {
246
- console.log(' Add these DNS records to your domain:');
247
- console.log('');
248
- console.log(' CNAME Record:');
249
- console.log(` Name: ${result.dnsRecords.cname.name}`);
250
- console.log(` Value: ${result.dnsRecords.cname.value}`);
251
- console.log('');
252
- console.log(' TXT Record:');
253
- console.log(` Name: ${result.dnsRecords.txt.name}`);
254
- console.log(` Value: ${result.dnsRecords.txt.value}`);
255
- console.log('');
256
- logger_1.logger.info('After adding DNS records, run: devdoc domain verify');
257
- }
258
228
  }
259
229
  else if (result.message) {
260
230
  console.log(` ${result.message}`);
@@ -277,11 +247,7 @@ async function domainStatus(options) {
277
247
  function getStatusDisplay(status) {
278
248
  switch (status) {
279
249
  case 'pending':
280
- return logger_1.logger.yellow('⏳ Pending DNS configuration');
281
- case 'dns_verified':
282
- return logger_1.logger.cyan('✓ DNS verified, SSL provisioning...');
283
- case 'ssl_provisioning':
284
- return logger_1.logger.cyan('🔒 SSL certificate provisioning...');
250
+ return logger_1.logger.yellow('⏳ Pending DNS verification');
285
251
  case 'active':
286
252
  return logger_1.logger.green('✓ Active');
287
253
  case 'error':
@@ -336,82 +302,34 @@ async function domainVerify(options) {
336
302
  console.log('');
337
303
  console.log(` Domain: ${result.domain}`);
338
304
  console.log('');
339
- // Handle Vercel verification (new format)
340
- if (result.verified !== undefined) {
341
- if (result.verified) {
342
- console.log(` Status: ${logger_1.logger.green('✓ Verified')}`);
343
- console.log('');
344
- logger_1.logger.success('Domain verified!');
345
- console.log('');
346
- console.log(` ${result.message}`);
347
- console.log('');
348
- console.log(' Your docs will be available at:');
349
- console.log(` ${logger_1.logger.cyan(`https://${result.domain}`)}`);
350
- }
351
- else {
352
- console.log(` Status: ${logger_1.logger.yellow('⏳ Pending verification')}`);
353
- console.log('');
354
- // Show what DNS records are needed
355
- if (result.verification && result.verification.length > 0) {
356
- console.log(' Required DNS records:');
357
- console.log('');
358
- result.verification.forEach((record, index) => {
359
- console.log(` ${index + 1}. ${record.type} Record:`);
360
- console.log(` Name: ${record.name}`);
361
- console.log(` Value: ${record.value}`);
362
- console.log('');
363
- });
364
- }
365
- console.log(` ${result.message}`);
366
- console.log('');
367
- logger_1.logger.info('DNS changes can take up to 48 hours to propagate.');
368
- logger_1.logger.info('Run "devdoc domain verify" again later.');
369
- }
370
- }
371
- // Handle legacy verification format (for backward compatibility)
372
- else if (result.checks) {
373
- // CNAME check
374
- console.log(' CNAME Record:');
375
- if (result.checks.cname.valid) {
376
- console.log(` ${logger_1.logger.green('✓')} Found: ${result.checks.cname.value}`);
377
- }
378
- else if (result.checks.cname.found) {
379
- console.log(` ${logger_1.logger.yellow('!')} Found but incorrect: ${result.checks.cname.value}`);
380
- console.log(` Expected: ${result.checks.cname.expected}`);
381
- }
382
- else {
383
- console.log(` ${logger_1.logger.red('✗')} Not found`);
384
- console.log(` Expected: ${result.checks.cname.expected}`);
385
- }
386
- // TXT check
305
+ if (result.verified) {
306
+ console.log(` Status: ${logger_1.logger.green('✓ Verified')}`);
387
307
  console.log('');
388
- console.log(' TXT Verification Record:');
389
- if (result.checks.txt.verified) {
390
- console.log(` ${logger_1.logger.green('✓')} Verified`);
391
- }
392
- else if (result.checks.txt.found) {
393
- console.log(` ${logger_1.logger.yellow('!')} Found but value doesn't match`);
394
- }
395
- else {
396
- console.log(` ${logger_1.logger.red('✗')} Not found`);
397
- console.log(` Expected: ${result.checks.txt.expected}`);
398
- }
308
+ logger_1.logger.success('Domain verified!');
399
309
  console.log('');
400
- if (result.success) {
401
- logger_1.logger.success('DNS verified!');
402
- console.log('');
403
- console.log(` ${result.message}`);
404
- console.log('');
405
- logger_1.logger.info('Run "devdoc domain status" to check SSL provisioning progress.');
406
- }
407
- else {
408
- logger_1.logger.warn('DNS verification incomplete');
409
- console.log('');
410
- console.log(` ${result.message}`);
310
+ console.log(` ${result.message}`);
311
+ console.log('');
312
+ console.log(' Your docs will be available at:');
313
+ console.log(` ${logger_1.logger.cyan(`https://${result.domain}`)}`);
314
+ }
315
+ else {
316
+ console.log(` Status: ${logger_1.logger.yellow('⏳ Pending verification')}`);
317
+ console.log('');
318
+ // Show what DNS records are needed
319
+ if (result.verification && result.verification.length > 0) {
320
+ console.log(' Required DNS records:');
411
321
  console.log('');
412
- logger_1.logger.info('DNS changes can take 1-24 hours to propagate.');
413
- logger_1.logger.info('Run "devdoc domain verify" again later.');
322
+ result.verification.forEach((record, index) => {
323
+ console.log(` ${index + 1}. ${record.type} Record:`);
324
+ console.log(` Name: ${record.name}`);
325
+ console.log(` Value: ${record.value}`);
326
+ console.log('');
327
+ });
414
328
  }
329
+ console.log(` ${result.message}`);
330
+ console.log('');
331
+ logger_1.logger.info('DNS changes can take up to 48 hours to propagate.');
332
+ logger_1.logger.info('Run "devdoc domain verify" again later.');
415
333
  }
416
334
  console.log('');
417
335
  }
@@ -479,4 +397,4 @@ async function domainRemove(customDomain, options) {
479
397
  process.exit(1);
480
398
  }
481
399
  }
482
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tYWluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jb21tYW5kcy9kb21haW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUF5SkEsOEJBOEdDO0FBU0Qsb0NBNEdDO0FBNkJELG9DQW9JQztBQVNELG9DQTJEQztBQWptQkQsZ0RBQXVCO0FBQ3ZCLHdEQUF5QjtBQUN6QiwrQ0FBMkM7QUFDM0MsK0NBQWlEO0FBbUZqRDs7R0FFRztBQUNILFNBQVMsZ0JBQWdCLENBQUMsV0FBbUI7SUFDM0MsTUFBTSxVQUFVLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsY0FBYyxDQUFDLENBQUE7SUFDekQsSUFBSSxDQUFDLGtCQUFFLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDL0IsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBQ0QsSUFBSSxDQUFDO1FBQ0gsT0FBTyxrQkFBRSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQWlCLENBQUE7SUFDcEQsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztBQUNILENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsU0FBUyxDQUFDLE9BQXNCLEVBQUUsTUFBMkI7SUFDcEUsT0FBTyxPQUFPLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLE1BQU0sRUFBRSxNQUFNLElBQUksSUFBSSxDQUFBO0FBQy9FLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBYztJQUN6QyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQTtJQUN0RCxDQUFDO0lBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3RCLE9BQU8s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Q0FBQyxLQUFLLENBQUMsQ0FBQTtRQUN0RSxlQUFNLENBQUMsS0FBSyxDQUFDLDRCQUE0QixPQUFPLEVBQUUsQ0FBQyxDQUFBO1FBQ25ELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDakIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJ1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vdXRpbHMvbG9nZ2VyJ1xuaW1wb3J0IHsgREVGQVVMVF9BUElfVVJMIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzJ1xuXG5pbnRlcmZhY2UgRG9tYWluT3B0aW9ucyB7XG4gIHVybD86IHN0cmluZ1xuICBhcGlLZXk/OiBzdHJpbmdcbn1cblxuaW50ZXJmYWNlIERldkRvY0NvbmZpZyB7XG4gIHByb2plY3RJZD86IHN0cmluZ1xuICBuYW1lPzogc3RyaW5nXG4gIHNsdWc/OiBzdHJpbmdcbiAgc3ViZG9tYWluPzogc3RyaW5nXG4gIGFwaUtleT86IHN0cmluZ1xuICB1cmw/OiBzdHJpbmdcbiAgbGFzdERlcGxveWVkPzogc3RyaW5nXG4gIGNyZWF0ZWRBdD86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgVmVyaWZpY2F0aW9uUmVjb3JkIHtcbiAgdHlwZTogc3RyaW5nXG4gIG5hbWU6IHN0cmluZ1xuICB2YWx1ZTogc3RyaW5nXG59XG5cbmludGVyZmFjZSBEb21haW5BZGRSZXNwb25zZSB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW5cbiAgZG9tYWluOiBzdHJpbmdcbiAgcHJvamVjdFNsdWc6IHN0cmluZ1xuICBzdGF0dXM6IHN0cmluZ1xuICB2ZXJpZmllZD86IGJvb2xlYW5cbiAgbWVzc2FnZT86IHN0cmluZ1xuICAvLyBOZXcgVmVyY2VsIGZvcm1hdCAtIGFycmF5IG9mIHZlcmlmaWNhdGlvbiByZWNvcmRzXG4gIHZlcmlmaWNhdGlvbj86IFZlcmlmaWNhdGlvblJlY29yZFtdXG4gIGluc3RydWN0aW9ucz86IHN0cmluZ1tdXG4gIC8vIExlZ2FjeSBmb3JtYXQgKGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5KVxuICBsZWdhY3lWZXJpZmljYXRpb24/OiB7XG4gICAgY25hbWU6IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogc3RyaW5nIH1cbiAgICB0eHQ6IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogc3RyaW5nIH1cbiAgfVxuICBlcnJvcj86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgRG9tYWluU3RhdHVzUmVzcG9uc2Uge1xuICBoYXNDdXN0b21Eb21haW46IGJvb2xlYW5cbiAgZG9tYWluPzogc3RyaW5nXG4gIHN0YXR1cz86IHN0cmluZ1xuICBwcm9qZWN0U2x1Zzogc3RyaW5nXG4gIHByb2plY3RVcmw6IHN0cmluZ1xuICBjdXN0b21Vcmw/OiBzdHJpbmdcbiAgbWVzc2FnZT86IHN0cmluZ1xuICB2ZXJpZmljYXRpb24/OiBWZXJpZmljYXRpb25SZWNvcmRbXVxuICBkbnNSZWNvcmRzPzoge1xuICAgIGNuYW1lOiB7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9XG4gICAgdHh0OiB7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9XG4gIH1cbiAgbmV4dFN0ZXA/OiBzdHJpbmdcbiAgZXJyb3I/OiBzdHJpbmdcbn1cblxuaW50ZXJmYWNlIERvbWFpblZlcmlmeVJlc3BvbnNlIHtcbiAgc3VjY2VzczogYm9vbGVhblxuICBkb21haW46IHN0cmluZ1xuICBzdGF0dXM6IHN0cmluZ1xuICBtZXNzYWdlOiBzdHJpbmdcbiAgdmVyaWZpZWQ/OiBib29sZWFuXG4gIC8vIE5ldyBWZXJjZWwgZm9ybWF0XG4gIHZlcmlmaWNhdGlvbj86IFZlcmlmaWNhdGlvblJlY29yZFtdXG4gIGluc3RydWN0aW9ucz86IHN0cmluZ1tdXG4gIC8vIExlZ2FjeSBmb3JtYXQgKGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5KVxuICBjaGVja3M/OiB7XG4gICAgY25hbWU6IHsgZm91bmQ6IGJvb2xlYW47IHZhbHVlOiBzdHJpbmcgfCBudWxsOyB2YWxpZDogYm9vbGVhbjsgZXhwZWN0ZWQ6IHN0cmluZyB9XG4gICAgdHh0OiB7IGZvdW5kOiBib29sZWFuOyB2ZXJpZmllZDogYm9vbGVhbjsgZXhwZWN0ZWQ6IHN0cmluZyB9XG4gIH1cbiAgZXJyb3I/OiBzdHJpbmdcbn1cblxuaW50ZXJmYWNlIERvbWFpblJlbW92ZVJlc3BvbnNlIHtcbiAgc3VjY2VzczogYm9vbGVhblxuICBtZXNzYWdlOiBzdHJpbmdcbiAgZG9tYWluOiBzdHJpbmdcbiAgZXJyb3I/OiBzdHJpbmdcbn1cblxuLyoqXG4gKiBMb2FkIC5kZXZkb2MuanNvbiBhbmQgZ2V0IEFQSSBrZXlcbiAqL1xuZnVuY3Rpb24gbG9hZERldkRvY0NvbmZpZyhwcm9qZWN0Um9vdDogc3RyaW5nKTogRGV2RG9jQ29uZmlnIHwgbnVsbCB7XG4gIGNvbnN0IGNvbmZpZ1BhdGggPSBwYXRoLmpvaW4ocHJvamVjdFJvb3QsICcuZGV2ZG9jLmpzb24nKVxuICBpZiAoIWZzLmV4aXN0c1N5bmMoY29uZmlnUGF0aCkpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG4gIHRyeSB7XG4gICAgcmV0dXJuIGZzLnJlYWRKc29uU3luYyhjb25maWdQYXRoKSBhcyBEZXZEb2NDb25maWdcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxufVxuXG4vKipcbiAqIEdldCBBUEkga2V5IGZyb20gb3B0aW9ucywgZW52LCBvciBjb25maWdcbiAqL1xuZnVuY3Rpb24gZ2V0QXBpS2V5KG9wdGlvbnM6IERvbWFpbk9wdGlvbnMsIGNvbmZpZzogRGV2RG9jQ29uZmlnIHwgbnVsbCk6IHN0cmluZyB8IG51bGwge1xuICByZXR1cm4gb3B0aW9ucy5hcGlLZXkgfHwgcHJvY2Vzcy5lbnYuREVWRE9DX0FQSV9LRVkgfHwgY29uZmlnPy5hcGlLZXkgfHwgbnVsbFxufVxuXG4vKipcbiAqIFZhbGlkYXRlIGRvbWFpbiBmb3JtYXRcbiAqL1xuZnVuY3Rpb24gaXNWYWxpZERvbWFpbkZvcm1hdChkb21haW46IHN0cmluZyk6IHsgdmFsaWQ6IGJvb2xlYW47IGVycm9yPzogc3RyaW5nIH0ge1xuICBpZiAoIWRvbWFpbikge1xuICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgZXJyb3I6ICdEb21haW4gaXMgcmVxdWlyZWQnIH1cbiAgfVxuICBcbiAgaWYgKGRvbWFpbi5sZW5ndGggPCA0KSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcjogJ0RvbWFpbiBtdXN0IGJlIGF0IGxlYXN0IDQgY2hhcmFjdGVycycgfVxuICB9XG4gIFxuICAvLyBCYXNpYyBkb21haW4gZm9ybWF0IGNoZWNrXG4gIGNvbnN0IGRvbWFpblJlZ2V4ID0gL14oPyEtKVthLXpBLVowLTktXSsoPzpcXC5bYS16QS1aMC05LV0rKSpcXC5bYS16QS1aXXsyLH0kL1xuICBpZiAoIWRvbWFpblJlZ2V4LnRlc3QoZG9tYWluKSkge1xuICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgZXJyb3I6ICdJbnZhbGlkIGRvbWFpbiBmb3JtYXQuIEV4YW1wbGU6IGRvY3MuZXhhbXBsZS5jb20nIH1cbiAgfVxuICBcbiAgLy8gQ2hlY2sgZm9yIHJlc2VydmVkIGRvbWFpbnNcbiAgY29uc3QgcmVzZXJ2ZWQgPSBbJ2RldmRvYy5zaCcsICdkZXZkb2MuaW8nLCAnZGV2ZG9jLmNvbSddXG4gIGlmIChyZXNlcnZlZC5zb21lKHIgPT4gZG9tYWluID09PSByIHx8IGRvbWFpbi5lbmRzV2l0aChgLiR7cn1gKSkpIHtcbiAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIGVycm9yOiAnQ2Fubm90IHVzZSBhIHJlc2VydmVkIERldkRvYyBkb21haW4nIH1cbiAgfVxuICBcbiAgcmV0dXJuIHsgdmFsaWQ6IHRydWUgfVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBkb21haW4gKGxvd2VyY2FzZSwgcmVtb3ZlIHByb3RvY29sL3BhdGgpXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZURvbWFpbihkb21haW46IHN0cmluZyk6IHN0cmluZyB7XG4gIGxldCBub3JtYWxpemVkID0gZG9tYWluLnRvTG93ZXJDYXNlKCkudHJpbSgpXG4gIG5vcm1hbGl6ZWQgPSBub3JtYWxpemVkLnJlcGxhY2UoL15odHRwcz86XFwvXFwvLywgJycpXG4gIG5vcm1hbGl6ZWQgPSBub3JtYWxpemVkLnNwbGl0KCcvJylbMF1cbiAgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZWQuc3BsaXQoJzonKVswXVxuICByZXR1cm4gbm9ybWFsaXplZFxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRG9tYWluIEFkZCBDb21tYW5kXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEFkZCBhIGN1c3RvbSBkb21haW4gdG8gdGhlIHByb2plY3RcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvbWFpbkFkZChjdXN0b21Eb21haW46IHN0cmluZywgb3B0aW9uczogRG9tYWluT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IHByb2Nlc3MuY3dkKClcbiAgY29uc3QgYXBpVXJsID0gb3B0aW9ucy51cmwgfHwgcHJvY2Vzcy5lbnYuREVWRE9DX0FQSV9VUkwgfHwgREVGQVVMVF9BUElfVVJMXG4gIFxuICBsb2dnZXIuaW5mbygnQWRkaW5nIGN1c3RvbSBkb21haW4uLi5cXG4nKVxuICBcbiAgLy8gTG9hZCBjb25maWdcbiAgY29uc3QgY29uZmlnID0gbG9hZERldkRvY0NvbmZpZyhwcm9qZWN0Um9vdClcbiAgaWYgKCFjb25maWcpIHtcbiAgICBsb2dnZXIuZXJyb3IoJ1Byb2plY3Qgbm90IGluaXRpYWxpemVkLicpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgbG9nZ2VyLmluZm8oJ1J1biBcImRldmRvYyBpbml0XCIgdG8gaW5pdGlhbGl6ZSwgdGhlbiBcImRldmRvYyBkZXBsb3lcIiB0byBkZXBsb3kuJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgLy8gR2V0IEFQSSBrZXkgLSByZXF1aXJlZCBiZWNhdXNlIGN1c3RvbSBkb21haW5zIG5lZWQgYSBkZXBsb3llZCBwcm9qZWN0XG4gIGNvbnN0IGFwaUtleSA9IGdldEFwaUtleShvcHRpb25zLCBjb25maWcpXG4gIGlmICghYXBpS2V5KSB7XG4gICAgbG9nZ2VyLmVycm9yKCdQcm9qZWN0IG5vdCBkZXBsb3llZCB5ZXQuJylcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBjb25zb2xlLmxvZygnICBDdXN0b20gZG9tYWlucyByZXF1aXJlIGEgZGVwbG95ZWQgcHJvamVjdC4nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGNvbnNvbGUubG9nKCcgIFRvIHNldCB1cCBhIGN1c3RvbSBkb21haW46JylcbiAgICBjb25zb2xlLmxvZygnICAgIDEuIERlcGxveSB5b3VyIHByb2plY3QgZmlyc3Q6ICBkZXZkb2MgZGVwbG95JylcbiAgICBjb25zb2xlLmxvZygnICAgIDIuIFRoZW4gYWRkIHlvdXIgZG9tYWluOiAgICAgICBkZXZkb2MgZG9tYWluIGFkZCAnICsgY3VzdG9tRG9tYWluKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIFxuICAvLyBOb3JtYWxpemUgYW5kIHZhbGlkYXRlIGRvbWFpblxuICBjb25zdCBkb21haW4gPSBub3JtYWxpemVEb21haW4oY3VzdG9tRG9tYWluKVxuICBjb25zdCB2YWxpZGF0aW9uID0gaXNWYWxpZERvbWFpbkZvcm1hdChkb21haW4pXG4gIGlmICghdmFsaWRhdGlvbi52YWxpZCkge1xuICAgIGxvZ2dlci5lcnJvcih2YWxpZGF0aW9uLmVycm9yISlcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgbG9nZ2VyLmluZm8oYERvbWFpbjogJHtkb21haW59YClcbiAgY29uc29sZS5sb2coJycpXG4gIFxuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7YXBpVXJsfS9hcGkvZG9tYWlucy9hZGRgLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBjdXN0b21Eb21haW46IGRvbWFpbiB9KSxcbiAgICB9KVxuICAgIFxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyBEb21haW5BZGRSZXNwb25zZVxuICAgIFxuICAgIGlmICghcmVzcG9uc2Uub2sgfHwgIXJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICBsb2dnZXIuZXJyb3IocmVzdWx0LmVycm9yIHx8ICdGYWlsZWQgdG8gYWRkIGRvbWFpbicpXG4gICAgICBwcm9jZXNzLmV4aXQoMSlcbiAgICB9XG4gICAgXG4gICAgbG9nZ2VyLnN1Y2Nlc3MoYOKckyBEb21haW4gJHtkb21haW59IGFkZGVkIWApXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgXG4gICAgLy8gQ2hlY2sgaWYgZG9tYWluIGlzIGFscmVhZHkgdmVyaWZpZWQgKFZlcmNlbCBtYXkgYXV0by12ZXJpZnkgaWYgRE5TIGlzIGFscmVhZHkgY29uZmlndXJlZClcbiAgICBpZiAocmVzdWx0LnZlcmlmaWVkKSB7XG4gICAgICBjb25zb2xlLmxvZygnICAnICsgbG9nZ2VyLmdyZWVuKCdEb21haW4gaXMgYWxyZWFkeSB2ZXJpZmllZCBhbmQgYWN0aXZlIScpKVxuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICBjb25zb2xlLmxvZygnICBZb3VyIGRvY3Mgd2lsbCBiZSBhdmFpbGFibGUgYXQ6JylcbiAgICAgIGNvbnNvbGUubG9nKGAgICR7bG9nZ2VyLmN5YW4oYGh0dHBzOi8vJHtkb21haW59YCl9YClcbiAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIFxuICAgIGNvbnNvbGUubG9nKCcgIE5leHQsIGFkZCB0aGVzZSBETlMgcmVjb3JkcyB0byB5b3VyIGRvbWFpbiBwcm92aWRlcjonKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIFxuICAgIC8vIEhhbmRsZSBuZXcgVmVyY2VsIHZlcmlmaWNhdGlvbiBmb3JtYXQgKGFycmF5IG9mIHJlY29yZHMpXG4gICAgaWYgKHJlc3VsdC52ZXJpZmljYXRpb24gJiYgQXJyYXkuaXNBcnJheShyZXN1bHQudmVyaWZpY2F0aW9uKSkge1xuICAgICAgcmVzdWx0LnZlcmlmaWNhdGlvbi5mb3JFYWNoKChyZWNvcmQsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAgICR7aW5kZXggKyAxfS4gJHtyZWNvcmQudHlwZX0gUmVjb3JkOmApXG4gICAgICAgIGNvbnNvbGUubG9nKGAgICAgIE5hbWU6ICAke3JlY29yZC5uYW1lfWApXG4gICAgICAgIGNvbnNvbGUubG9nKGAgICAgIFZhbHVlOiAke3JlY29yZC52YWx1ZX1gKVxuICAgICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgIH0pXG4gICAgfVxuICAgIFxuICAgIC8vIFNob3cgYW55IGFkZGl0aW9uYWwgaW5zdHJ1Y3Rpb25zIGZyb20gdGhlIEFQSVxuICAgIGlmIChyZXN1bHQuaW5zdHJ1Y3Rpb25zICYmIHJlc3VsdC5pbnN0cnVjdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gRmlsdGVyIG91dCByZWR1bmRhbnQgbGluZXMgdGhhdCB3ZSd2ZSBhbHJlYWR5IHNob3duXG4gICAgICBjb25zdCBhZGRpdGlvbmFsSW5zdHJ1Y3Rpb25zID0gcmVzdWx0Lmluc3RydWN0aW9ucy5maWx0ZXIobGluZSA9PiBcbiAgICAgICAgIWxpbmUuaW5jbHVkZXMoJ0FkZCB0aGUgZm9sbG93aW5nJykgJiYgXG4gICAgICAgIGxpbmUudHJpbSgpICE9PSAnJyAmJlxuICAgICAgICAhbGluZS5tYXRjaCgvXlxcZCtcXC5cXHMrKENOQU1FfFRYVHxBKVxccytSZWNvcmQvKVxuICAgICAgKVxuICAgICAgaWYgKGFkZGl0aW9uYWxJbnN0cnVjdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICBhZGRpdGlvbmFsSW5zdHJ1Y3Rpb25zLmZvckVhY2gobGluZSA9PiB7XG4gICAgICAgICAgaWYgKGxpbmUudHJpbSgpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgICAke2xpbmV9YClcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICBsb2dnZXIuaW5mbygnQWZ0ZXIgYWRkaW5nIEROUyByZWNvcmRzLCBydW46JylcbiAgICBjb25zb2xlLmxvZygnICBkZXZkb2MgZG9tYWluIHZlcmlmeScpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKVxuICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGFkZCBkb21haW46ICR7bWVzc2FnZX1gKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEb21haW4gU3RhdHVzIENvbW1hbmRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ2hlY2sgc3RhdHVzIG9mIGN1c3RvbSBkb21haW5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvbWFpblN0YXR1cyhvcHRpb25zOiBEb21haW5PcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvY2Vzcy5jd2QoKVxuICBjb25zdCBhcGlVcmwgPSBvcHRpb25zLnVybCB8fCBwcm9jZXNzLmVudi5ERVZET0NfQVBJX1VSTCB8fCBERUZBVUxUX0FQSV9VUkxcbiAgXG4gIC8vIExvYWQgY29uZmlnXG4gIGNvbnN0IGNvbmZpZyA9IGxvYWREZXZEb2NDb25maWcocHJvamVjdFJvb3QpXG4gIGlmICghY29uZmlnKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdQcm9qZWN0IG5vdCBpbml0aWFsaXplZC4nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGxvZ2dlci5pbmZvKCdSdW4gXCJkZXZkb2MgaW5pdFwiIHRvIGluaXRpYWxpemUsIHRoZW4gXCJkZXZkb2MgZGVwbG95XCIgdG8gZGVwbG95LicpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbiAgXG4gIC8vIEdldCBBUEkga2V5XG4gIGNvbnN0IGFwaUtleSA9IGdldEFwaUtleShvcHRpb25zLCBjb25maWcpXG4gIGlmICghYXBpS2V5KSB7XG4gICAgbG9nZ2VyLmVycm9yKCdQcm9qZWN0IG5vdCBkZXBsb3llZCB5ZXQuJylcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBsb2dnZXIuaW5mbygnRGVwbG95IHlvdXIgcHJvamVjdCBmaXJzdCB3aXRoIFwiZGV2ZG9jIGRlcGxveVwiJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2FwaVVybH0vYXBpL2RvbWFpbnMvc3RhdHVzYCwge1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICB9LFxuICAgIH0pXG4gICAgXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIERvbWFpblN0YXR1c1Jlc3BvbnNlXG4gICAgXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgbG9nZ2VyLmVycm9yKHJlc3VsdC5lcnJvciB8fCAnRmFpbGVkIHRvIGdldCBkb21haW4gc3RhdHVzJylcbiAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBjb25zb2xlLmxvZygnICBDdXN0b20gRG9tYWluIFN0YXR1cycpXG4gICAgY29uc29sZS5sb2coJyAgLS0tLS0tLS0tLS0tLS0tLS0tLS0nKVxuICAgIFxuICAgIGlmICghcmVzdWx0Lmhhc0N1c3RvbURvbWFpbikge1xuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICBjb25zb2xlLmxvZygnICBObyBjdXN0b20gZG9tYWluIGNvbmZpZ3VyZWQuJylcbiAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgY29uc29sZS5sb2coJyAgWW91ciBkb2NzIGFyZSBhdmFpbGFibGUgYXQ6JylcbiAgICAgIGNvbnNvbGUubG9nKGAgICR7bG9nZ2VyLmN5YW4ocmVzdWx0LnByb2plY3RVcmwpfWApXG4gICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgIGxvZ2dlci5pbmZvKCdUbyBhZGQgYSBjdXN0b20gZG9tYWluLCBydW46JylcbiAgICAgIGNvbnNvbGUubG9nKCcgIGRldmRvYyBkb21haW4gYWRkIGRvY3MueW91cmRvbWFpbi5jb20nKVxuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgY29uc29sZS5sb2coYCAgRG9tYWluOiAgJHtyZXN1bHQuZG9tYWlufWApXG4gICAgY29uc29sZS5sb2coYCAgU3RhdHVzOiAgJHtnZXRTdGF0dXNEaXNwbGF5KHJlc3VsdC5zdGF0dXMgfHwgJ3Vua25vd24nKX1gKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIFxuICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSAnYWN0aXZlJykge1xuICAgICAgY29uc29sZS5sb2coJyAgWW91ciBkb2NzIGFyZSBhdmFpbGFibGUgYXQ6JylcbiAgICAgIGNvbnNvbGUubG9nKGAgICR7bG9nZ2VyLmN5YW4ocmVzdWx0LmN1c3RvbVVybCB8fCBgaHR0cHM6Ly8ke3Jlc3VsdC5kb21haW59YCl9YClcbiAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgY29uc29sZS5sb2coJyAgQWxzbyBhY2Nlc3NpYmxlIGF0OicpXG4gICAgICBjb25zb2xlLmxvZyhgICAke3Jlc3VsdC5wcm9qZWN0VXJsfWApXG4gICAgfSBlbHNlIGlmIChyZXN1bHQuc3RhdHVzID09PSAncGVuZGluZycpIHtcbiAgICAgIC8vIEhhbmRsZSBuZXcgVmVyY2VsIHZlcmlmaWNhdGlvbiBmb3JtYXRcbiAgICAgIGlmIChyZXN1bHQudmVyaWZpY2F0aW9uICYmIHJlc3VsdC52ZXJpZmljYXRpb24ubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zb2xlLmxvZygnICBBZGQgdGhlc2UgRE5TIHJlY29yZHMgdG8geW91ciBkb21haW46JylcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIHJlc3VsdC52ZXJpZmljYXRpb24uZm9yRWFjaCgocmVjb3JkLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICR7aW5kZXggKyAxfS4gJHtyZWNvcmQudHlwZX0gUmVjb3JkOmApXG4gICAgICAgICAgY29uc29sZS5sb2coYCAgICAgTmFtZTogICR7cmVjb3JkLm5hbWV9YClcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICAgICBWYWx1ZTogJHtyZWNvcmQudmFsdWV9YClcbiAgICAgICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgICAgfSlcbiAgICAgICAgbG9nZ2VyLmluZm8oJ0FmdGVyIGFkZGluZyBETlMgcmVjb3JkcywgcnVuOiBkZXZkb2MgZG9tYWluIHZlcmlmeScpXG4gICAgICB9XG4gICAgICAvLyBIYW5kbGUgbGVnYWN5IEROUyByZWNvcmRzIGZvcm1hdFxuICAgICAgZWxzZSBpZiAocmVzdWx0LmRuc1JlY29yZHMpIHtcbiAgICAgICAgY29uc29sZS5sb2coJyAgQWRkIHRoZXNlIEROUyByZWNvcmRzIHRvIHlvdXIgZG9tYWluOicpXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgICBjb25zb2xlLmxvZygnICBDTkFNRSBSZWNvcmQ6JylcbiAgICAgICAgY29uc29sZS5sb2coYCAgICBOYW1lOiAgJHtyZXN1bHQuZG5zUmVjb3Jkcy5jbmFtZS5uYW1lfWApXG4gICAgICAgIGNvbnNvbGUubG9nKGAgICAgVmFsdWU6ICR7cmVzdWx0LmRuc1JlY29yZHMuY25hbWUudmFsdWV9YClcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIGNvbnNvbGUubG9nKCcgIFRYVCBSZWNvcmQ6JylcbiAgICAgICAgY29uc29sZS5sb2coYCAgICBOYW1lOiAgJHtyZXN1bHQuZG5zUmVjb3Jkcy50eHQubmFtZX1gKVxuICAgICAgICBjb25zb2xlLmxvZyhgICAgIFZhbHVlOiAke3Jlc3VsdC5kbnNSZWNvcmRzLnR4dC52YWx1ZX1gKVxuICAgICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgICAgbG9nZ2VyLmluZm8oJ0FmdGVyIGFkZGluZyBETlMgcmVjb3JkcywgcnVuOiBkZXZkb2MgZG9tYWluIHZlcmlmeScpXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZXN1bHQubWVzc2FnZSkge1xuICAgICAgY29uc29sZS5sb2coYCAgJHtyZXN1bHQubWVzc2FnZX1gKVxuICAgIH1cbiAgICBcbiAgICBpZiAocmVzdWx0Lm5leHRTdGVwKSB7XG4gICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgIGxvZ2dlci5pbmZvKGBOZXh0OiAke3Jlc3VsdC5uZXh0U3RlcH1gKVxuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IGRvbWFpbiBzdGF0dXM6ICR7bWVzc2FnZX1gKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG59XG5cbi8qKlxuICogR2V0IGRpc3BsYXkgc3RyaW5nIGZvciBzdGF0dXNcbiAqL1xuZnVuY3Rpb24gZ2V0U3RhdHVzRGlzcGxheShzdGF0dXM6IHN0cmluZyk6IHN0cmluZyB7XG4gIHN3aXRjaCAoc3RhdHVzKSB7XG4gICAgY2FzZSAncGVuZGluZyc6XG4gICAgICByZXR1cm4gbG9nZ2VyLnllbGxvdygn4o+zIFBlbmRpbmcgRE5TIGNvbmZpZ3VyYXRpb24nKVxuICAgIGNhc2UgJ2Ruc192ZXJpZmllZCc6XG4gICAgICByZXR1cm4gbG9nZ2VyLmN5YW4oJ+KckyBETlMgdmVyaWZpZWQsIFNTTCBwcm92aXNpb25pbmcuLi4nKVxuICAgIGNhc2UgJ3NzbF9wcm92aXNpb25pbmcnOlxuICAgICAgcmV0dXJuIGxvZ2dlci5jeWFuKCfwn5SSIFNTTCBjZXJ0aWZpY2F0ZSBwcm92aXNpb25pbmcuLi4nKVxuICAgIGNhc2UgJ2FjdGl2ZSc6XG4gICAgICByZXR1cm4gbG9nZ2VyLmdyZWVuKCfinJMgQWN0aXZlJylcbiAgICBjYXNlICdlcnJvcic6XG4gICAgICByZXR1cm4gbG9nZ2VyLnJlZCgn4pyXIEVycm9yJylcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHN0YXR1c1xuICB9XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEb21haW4gVmVyaWZ5IENvbW1hbmRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogVmVyaWZ5IEROUyBjb25maWd1cmF0aW9uIGZvciBjdXN0b20gZG9tYWluXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb21haW5WZXJpZnkob3B0aW9uczogRG9tYWluT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IHByb2Nlc3MuY3dkKClcbiAgY29uc3QgYXBpVXJsID0gb3B0aW9ucy51cmwgfHwgcHJvY2Vzcy5lbnYuREVWRE9DX0FQSV9VUkwgfHwgREVGQVVMVF9BUElfVVJMXG4gIFxuICBsb2dnZXIuaW5mbygnVmVyaWZ5aW5nIEROUyBjb25maWd1cmF0aW9uLi4uXFxuJylcbiAgXG4gIC8vIExvYWQgY29uZmlnXG4gIGNvbnN0IGNvbmZpZyA9IGxvYWREZXZEb2NDb25maWcocHJvamVjdFJvb3QpXG4gIGlmICghY29uZmlnKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdQcm9qZWN0IG5vdCBpbml0aWFsaXplZC4nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGxvZ2dlci5pbmZvKCdSdW4gXCJkZXZkb2MgaW5pdFwiIHRvIGluaXRpYWxpemUsIHRoZW4gXCJkZXZkb2MgZGVwbG95XCIgdG8gZGVwbG95LicpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbiAgXG4gIC8vIEdldCBBUEkga2V5XG4gIGNvbnN0IGFwaUtleSA9IGdldEFwaUtleShvcHRpb25zLCBjb25maWcpXG4gIGlmICghYXBpS2V5KSB7XG4gICAgbG9nZ2VyLmVycm9yKCdQcm9qZWN0IG5vdCBkZXBsb3llZCB5ZXQuJylcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBsb2dnZXIuaW5mbygnRGVwbG95IHlvdXIgcHJvamVjdCBmaXJzdCB3aXRoIFwiZGV2ZG9jIGRlcGxveVwiJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2FwaVVybH0vYXBpL2RvbWFpbnMvdmVyaWZ5YCwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICdBdXRob3JpemF0aW9uJzogYEJlYXJlciAke2FwaUtleX1gLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHt9KSxcbiAgICB9KVxuICAgIFxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyBEb21haW5WZXJpZnlSZXNwb25zZVxuICAgIFxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIGxvZ2dlci5lcnJvcihyZXN1bHQuZXJyb3IgfHwgJ0ZhaWxlZCB0byB2ZXJpZnkgZG9tYWluJylcbiAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBjb25zb2xlLmxvZygnICBETlMgVmVyaWZpY2F0aW9uIFJlc3VsdHMnKVxuICAgIGNvbnNvbGUubG9nKCcgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgY29uc29sZS5sb2coYCAgRG9tYWluOiAke3Jlc3VsdC5kb21haW59YClcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBcbiAgICAvLyBIYW5kbGUgVmVyY2VsIHZlcmlmaWNhdGlvbiAobmV3IGZvcm1hdClcbiAgICBpZiAocmVzdWx0LnZlcmlmaWVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChyZXN1bHQudmVyaWZpZWQpIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgU3RhdHVzOiAke2xvZ2dlci5ncmVlbign4pyTIFZlcmlmaWVkJyl9YClcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIGxvZ2dlci5zdWNjZXNzKCdEb21haW4gdmVyaWZpZWQhJylcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIGNvbnNvbGUubG9nKGAgICR7cmVzdWx0Lm1lc3NhZ2V9YClcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIGNvbnNvbGUubG9nKCcgIFlvdXIgZG9jcyB3aWxsIGJlIGF2YWlsYWJsZSBhdDonKVxuICAgICAgICBjb25zb2xlLmxvZyhgICAke2xvZ2dlci5jeWFuKGBodHRwczovLyR7cmVzdWx0LmRvbWFpbn1gKX1gKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgU3RhdHVzOiAke2xvZ2dlci55ZWxsb3coJ+KPsyBQZW5kaW5nIHZlcmlmaWNhdGlvbicpfWApXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgICBcbiAgICAgICAgLy8gU2hvdyB3aGF0IEROUyByZWNvcmRzIGFyZSBuZWVkZWRcbiAgICAgICAgaWYgKHJlc3VsdC52ZXJpZmljYXRpb24gJiYgcmVzdWx0LnZlcmlmaWNhdGlvbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJyAgUmVxdWlyZWQgRE5TIHJlY29yZHM6JylcbiAgICAgICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgICAgICByZXN1bHQudmVyaWZpY2F0aW9uLmZvckVhY2goKHJlY29yZCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAgICR7aW5kZXggKyAxfS4gJHtyZWNvcmQudHlwZX0gUmVjb3JkOmApXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgICAgICBOYW1lOiAgJHtyZWNvcmQubmFtZX1gKVxuICAgICAgICAgICAgY29uc29sZS5sb2coYCAgICAgVmFsdWU6ICR7cmVjb3JkLnZhbHVlfWApXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBjb25zb2xlLmxvZyhgICAke3Jlc3VsdC5tZXNzYWdlfWApXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgICBsb2dnZXIuaW5mbygnRE5TIGNoYW5nZXMgY2FuIHRha2UgdXAgdG8gNDggaG91cnMgdG8gcHJvcGFnYXRlLicpXG4gICAgICAgIGxvZ2dlci5pbmZvKCdSdW4gXCJkZXZkb2MgZG9tYWluIHZlcmlmeVwiIGFnYWluIGxhdGVyLicpXG4gICAgICB9XG4gICAgfVxuICAgIC8vIEhhbmRsZSBsZWdhY3kgdmVyaWZpY2F0aW9uIGZvcm1hdCAoZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkpXG4gICAgZWxzZSBpZiAocmVzdWx0LmNoZWNrcykge1xuICAgICAgLy8gQ05BTUUgY2hlY2tcbiAgICAgIGNvbnNvbGUubG9nKCcgIENOQU1FIFJlY29yZDonKVxuICAgICAgaWYgKHJlc3VsdC5jaGVja3MuY25hbWUudmFsaWQpIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgICAke2xvZ2dlci5ncmVlbign4pyTJyl9IEZvdW5kOiAke3Jlc3VsdC5jaGVja3MuY25hbWUudmFsdWV9YClcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0LmNoZWNrcy5jbmFtZS5mb3VuZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgICAgICR7bG9nZ2VyLnllbGxvdygnIScpfSBGb3VuZCBidXQgaW5jb3JyZWN0OiAke3Jlc3VsdC5jaGVja3MuY25hbWUudmFsdWV9YClcbiAgICAgICAgY29uc29sZS5sb2coYCAgICAgIEV4cGVjdGVkOiAke3Jlc3VsdC5jaGVja3MuY25hbWUuZXhwZWN0ZWR9YClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAgICAgJHtsb2dnZXIucmVkKCfinJcnKX0gTm90IGZvdW5kYClcbiAgICAgICAgY29uc29sZS5sb2coYCAgICAgIEV4cGVjdGVkOiAke3Jlc3VsdC5jaGVja3MuY25hbWUuZXhwZWN0ZWR9YClcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gVFhUIGNoZWNrXG4gICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgIGNvbnNvbGUubG9nKCcgIFRYVCBWZXJpZmljYXRpb24gUmVjb3JkOicpXG4gICAgICBpZiAocmVzdWx0LmNoZWNrcy50eHQudmVyaWZpZWQpIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgICAke2xvZ2dlci5ncmVlbign4pyTJyl9IFZlcmlmaWVkYClcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0LmNoZWNrcy50eHQuZm91bmQpIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgICAke2xvZ2dlci55ZWxsb3coJyEnKX0gRm91bmQgYnV0IHZhbHVlIGRvZXNuJ3QgbWF0Y2hgKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgICAke2xvZ2dlci5yZWQoJ+KclycpfSBOb3QgZm91bmRgKVxuICAgICAgICBjb25zb2xlLmxvZyhgICAgICAgRXhwZWN0ZWQ6ICR7cmVzdWx0LmNoZWNrcy50eHQuZXhwZWN0ZWR9YClcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICBcbiAgICAgIGlmIChyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICBsb2dnZXIuc3VjY2VzcygnRE5TIHZlcmlmaWVkIScpXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgICBjb25zb2xlLmxvZyhgICAke3Jlc3VsdC5tZXNzYWdlfWApXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgICBsb2dnZXIuaW5mbygnUnVuIFwiZGV2ZG9jIGRvbWFpbiBzdGF0dXNcIiB0byBjaGVjayBTU0wgcHJvdmlzaW9uaW5nIHByb2dyZXNzLicpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIud2FybignRE5TIHZlcmlmaWNhdGlvbiBpbmNvbXBsZXRlJylcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIGNvbnNvbGUubG9nKGAgICR7cmVzdWx0Lm1lc3NhZ2V9YClcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIGxvZ2dlci5pbmZvKCdETlMgY2hhbmdlcyBjYW4gdGFrZSAxLTI0IGhvdXJzIHRvIHByb3BhZ2F0ZS4nKVxuICAgICAgICBsb2dnZXIuaW5mbygnUnVuIFwiZGV2ZG9jIGRvbWFpbiB2ZXJpZnlcIiBhZ2FpbiBsYXRlci4nKVxuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gdmVyaWZ5IGRvbWFpbjogJHttZXNzYWdlfWApXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERvbWFpbiBSZW1vdmUgQ29tbWFuZFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBSZW1vdmUgY3VzdG9tIGRvbWFpbiBmcm9tIHByb2plY3RcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvbWFpblJlbW92ZShjdXN0b21Eb21haW46IHN0cmluZyB8IHVuZGVmaW5lZCwgb3B0aW9uczogRG9tYWluT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IHByb2Nlc3MuY3dkKClcbiAgY29uc3QgYXBpVXJsID0gb3B0aW9ucy51cmwgfHwgcHJvY2Vzcy5lbnYuREVWRE9DX0FQSV9VUkwgfHwgREVGQVVMVF9BUElfVVJMXG4gIFxuICBsb2dnZXIuaW5mbygnUmVtb3ZpbmcgY3VzdG9tIGRvbWFpbi4uLlxcbicpXG4gIFxuICAvLyBMb2FkIGNvbmZpZ1xuICBjb25zdCBjb25maWcgPSBsb2FkRGV2RG9jQ29uZmlnKHByb2plY3RSb290KVxuICBpZiAoIWNvbmZpZykge1xuICAgIGxvZ2dlci5lcnJvcignUHJvamVjdCBub3QgaW5pdGlhbGl6ZWQuJylcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBsb2dnZXIuaW5mbygnUnVuIFwiZGV2ZG9jIGluaXRcIiB0byBpbml0aWFsaXplLCB0aGVuIFwiZGV2ZG9jIGRlcGxveVwiIHRvIGRlcGxveS4nKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIFxuICAvLyBHZXQgQVBJIGtleVxuICBjb25zdCBhcGlLZXkgPSBnZXRBcGlLZXkob3B0aW9ucywgY29uZmlnKVxuICBpZiAoIWFwaUtleSkge1xuICAgIGxvZ2dlci5lcnJvcignUHJvamVjdCBub3QgZGVwbG95ZWQgeWV0LicpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgbG9nZ2VyLmluZm8oJ0RlcGxveSB5b3VyIHByb2plY3QgZmlyc3Qgd2l0aCBcImRldmRvYyBkZXBsb3lcIicpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbiAgXG4gIHRyeSB7XG4gICAgY29uc3QgYm9keTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9XG4gICAgaWYgKGN1c3RvbURvbWFpbikge1xuICAgICAgYm9keS5jdXN0b21Eb21haW4gPSBub3JtYWxpemVEb21haW4oY3VzdG9tRG9tYWluKVxuICAgIH1cbiAgICBcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2FwaVVybH0vYXBpL2RvbWFpbnMvcmVtb3ZlYCwge1xuICAgICAgbWV0aG9kOiAnREVMRVRFJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgfSlcbiAgICBcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCkgYXMgRG9tYWluUmVtb3ZlUmVzcG9uc2VcbiAgICBcbiAgICBpZiAoIXJlc3BvbnNlLm9rIHx8ICFyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgbG9nZ2VyLmVycm9yKHJlc3VsdC5lcnJvciB8fCAnRmFpbGVkIHRvIHJlbW92ZSBkb21haW4nKVxuICAgICAgcHJvY2Vzcy5leGl0KDEpXG4gICAgfVxuICAgIFxuICAgIGxvZ2dlci5zdWNjZXNzKGDinJMgRG9tYWluICR7cmVzdWx0LmRvbWFpbn0gcmVtb3ZlZGApXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgY29uc29sZS5sb2coJyAgWW91ciBkb2NzIHJlbWFpbiBhY2Nlc3NpYmxlIGF0IHRoZSBkZWZhdWx0IHN1YmRvbWFpbi4nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGxvZ2dlci5pbmZvKCdZb3UgY2FuIGFkZCBhIG5ldyBjdXN0b20gZG9tYWluIGFueXRpbWUgd2l0aDonKVxuICAgIGNvbnNvbGUubG9nKCcgIGRldmRvYyBkb21haW4gYWRkIGRvY3MueW91cmRvbWFpbi5jb20nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIFxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byByZW1vdmUgZG9tYWluOiAke21lc3NhZ2V9YClcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxufVxuIl19
400
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tYWluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jb21tYW5kcy9kb21haW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUF5SUEsOEJBNEZDO0FBU0Qsb0NBNkZDO0FBeUJELG9DQXNGQztBQVNELG9DQTJEQztBQTlmRCxnREFBdUI7QUFDdkIsd0RBQXlCO0FBQ3pCLCtDQUEyQztBQUMzQywrQ0FBaUQ7QUFtRWpEOztHQUVHO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FBQyxXQUFtQjtJQUMzQyxNQUFNLFVBQVUsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxjQUFjLENBQUMsQ0FBQTtJQUN6RCxJQUFJLENBQUMsa0JBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUMvQixPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDSCxPQUFPLGtCQUFFLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBaUIsQ0FBQTtJQUNwRCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxTQUFTLENBQUMsT0FBc0IsRUFBRSxNQUEyQjtJQUNwRSxPQUFPLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLElBQUksTUFBTSxFQUFFLE1BQU0sSUFBSSxJQUFJLENBQUE7QUFDL0UsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxNQUFjO0lBQ3pDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRSxDQUFBO0lBQ3RELENBQUM7SUFFRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDdEIsT0FBTyxF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QXlDLENBQUMsQ0FBQTtRQUN0RCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRWpCLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsTUFBTSxPQUFPLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3RFLGVBQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLE9BQU8sRUFBRSxDQUFDLENBQUE7UUFDbkQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnXG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi91dGlscy9sb2dnZXInXG5pbXBvcnQgeyBERUZBVUxUX0FQSV9VUkwgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnXG5cbmludGVyZmFjZSBEb21haW5PcHRpb25zIHtcbiAgdXJsPzogc3RyaW5nXG4gIGFwaUtleT86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgRGV2RG9jQ29uZmlnIHtcbiAgcHJvamVjdElkPzogc3RyaW5nXG4gIG5hbWU/OiBzdHJpbmdcbiAgc2x1Zz86IHN0cmluZ1xuICBzdWJkb21haW4/OiBzdHJpbmdcbiAgYXBpS2V5Pzogc3RyaW5nXG4gIHVybD86IHN0cmluZ1xuICBsYXN0RGVwbG95ZWQ/OiBzdHJpbmdcbiAgY3JlYXRlZEF0Pzogc3RyaW5nXG59XG5cbmludGVyZmFjZSBWZXJpZmljYXRpb25SZWNvcmQge1xuICB0eXBlOiBzdHJpbmdcbiAgbmFtZTogc3RyaW5nXG4gIHZhbHVlOiBzdHJpbmdcbn1cblxuaW50ZXJmYWNlIERvbWFpbkFkZFJlc3BvbnNlIHtcbiAgc3VjY2VzczogYm9vbGVhblxuICBkb21haW46IHN0cmluZ1xuICBwcm9qZWN0U2x1Zzogc3RyaW5nXG4gIHN0YXR1czogc3RyaW5nXG4gIHZlcmlmaWVkPzogYm9vbGVhblxuICBtZXNzYWdlPzogc3RyaW5nXG4gIHZlcmlmaWNhdGlvbj86IFZlcmlmaWNhdGlvblJlY29yZFtdXG4gIGluc3RydWN0aW9ucz86IHN0cmluZ1tdXG4gIGVycm9yPzogc3RyaW5nXG59XG5cbmludGVyZmFjZSBEb21haW5TdGF0dXNSZXNwb25zZSB7XG4gIGhhc0N1c3RvbURvbWFpbjogYm9vbGVhblxuICBkb21haW4/OiBzdHJpbmdcbiAgc3RhdHVzPzogc3RyaW5nXG4gIHByb2plY3RTbHVnOiBzdHJpbmdcbiAgcHJvamVjdFVybDogc3RyaW5nXG4gIGN1c3RvbVVybD86IHN0cmluZ1xuICBtZXNzYWdlPzogc3RyaW5nXG4gIHZlcmlmaWNhdGlvbj86IFZlcmlmaWNhdGlvblJlY29yZFtdXG4gIG5leHRTdGVwPzogc3RyaW5nXG4gIGVycm9yPzogc3RyaW5nXG59XG5cbmludGVyZmFjZSBEb21haW5WZXJpZnlSZXNwb25zZSB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW5cbiAgZG9tYWluOiBzdHJpbmdcbiAgc3RhdHVzOiBzdHJpbmdcbiAgbWVzc2FnZTogc3RyaW5nXG4gIHZlcmlmaWVkPzogYm9vbGVhblxuICB2ZXJpZmljYXRpb24/OiBWZXJpZmljYXRpb25SZWNvcmRbXVxuICBpbnN0cnVjdGlvbnM/OiBzdHJpbmdbXVxuICBlcnJvcj86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgRG9tYWluUmVtb3ZlUmVzcG9uc2Uge1xuICBzdWNjZXNzOiBib29sZWFuXG4gIG1lc3NhZ2U6IHN0cmluZ1xuICBkb21haW46IHN0cmluZ1xuICBlcnJvcj86IHN0cmluZ1xufVxuXG4vKipcbiAqIExvYWQgLmRldmRvYy5qc29uIGFuZCBnZXQgQVBJIGtleVxuICovXG5mdW5jdGlvbiBsb2FkRGV2RG9jQ29uZmlnKHByb2plY3RSb290OiBzdHJpbmcpOiBEZXZEb2NDb25maWcgfCBudWxsIHtcbiAgY29uc3QgY29uZmlnUGF0aCA9IHBhdGguam9pbihwcm9qZWN0Um9vdCwgJy5kZXZkb2MuanNvbicpXG4gIGlmICghZnMuZXhpc3RzU3luYyhjb25maWdQYXRoKSkge1xuICAgIHJldHVybiBudWxsXG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gZnMucmVhZEpzb25TeW5jKGNvbmZpZ1BhdGgpIGFzIERldkRvY0NvbmZpZ1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbi8qKlxuICogR2V0IEFQSSBrZXkgZnJvbSBvcHRpb25zLCBlbnYsIG9yIGNvbmZpZ1xuICovXG5mdW5jdGlvbiBnZXRBcGlLZXkob3B0aW9uczogRG9tYWluT3B0aW9ucywgY29uZmlnOiBEZXZEb2NDb25maWcgfCBudWxsKTogc3RyaW5nIHwgbnVsbCB7XG4gIHJldHVybiBvcHRpb25zLmFwaUtleSB8fCBwcm9jZXNzLmVudi5ERVZET0NfQVBJX0tFWSB8fCBjb25maWc/LmFwaUtleSB8fCBudWxsXG59XG5cbi8qKlxuICogVmFsaWRhdGUgZG9tYWluIGZvcm1hdFxuICovXG5mdW5jdGlvbiBpc1ZhbGlkRG9tYWluRm9ybWF0KGRvbWFpbjogc3RyaW5nKTogeyB2YWxpZDogYm9vbGVhbjsgZXJyb3I/OiBzdHJpbmcgfSB7XG4gIGlmICghZG9tYWluKSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcjogJ0RvbWFpbiBpcyByZXF1aXJlZCcgfVxuICB9XG4gIFxuICBpZiAoZG9tYWluLmxlbmd0aCA8IDQpIHtcbiAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIGVycm9yOiAnRG9tYWluIG11c3QgYmUgYXQgbGVhc3QgNCBjaGFyYWN0ZXJzJyB9XG4gIH1cbiAgXG4gIC8vIEJhc2ljIGRvbWFpbiBmb3JtYXQgY2hlY2tcbiAgY29uc3QgZG9tYWluUmVnZXggPSAvXig/IS0pW2EtekEtWjAtOS1dKyg/OlxcLlthLXpBLVowLTktXSspKlxcLlthLXpBLVpdezIsfSQvXG4gIGlmICghZG9tYWluUmVnZXgudGVzdChkb21haW4pKSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcjogJ0ludmFsaWQgZG9tYWluIGZvcm1hdC4gRXhhbXBsZTogZG9jcy5leGFtcGxlLmNvbScgfVxuICB9XG4gIFxuICAvLyBDaGVjayBmb3IgcmVzZXJ2ZWQgZG9tYWluc1xuICBjb25zdCByZXNlcnZlZCA9IFsnZGV2ZG9jLnNoJywgJ2RldmRvYy5pbycsICdkZXZkb2MuY29tJ11cbiAgaWYgKHJlc2VydmVkLnNvbWUociA9PiBkb21haW4gPT09IHIgfHwgZG9tYWluLmVuZHNXaXRoKGAuJHtyfWApKSkge1xuICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgZXJyb3I6ICdDYW5ub3QgdXNlIGEgcmVzZXJ2ZWQgRGV2RG9jIGRvbWFpbicgfVxuICB9XG4gIFxuICByZXR1cm4geyB2YWxpZDogdHJ1ZSB9XG59XG5cbi8qKlxuICogTm9ybWFsaXplIGRvbWFpbiAobG93ZXJjYXNlLCByZW1vdmUgcHJvdG9jb2wvcGF0aClcbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRG9tYWluKGRvbWFpbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgbGV0IG5vcm1hbGl6ZWQgPSBkb21haW4udG9Mb3dlckNhc2UoKS50cmltKClcbiAgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZWQucmVwbGFjZSgvXmh0dHBzPzpcXC9cXC8vLCAnJylcbiAgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZWQuc3BsaXQoJy8nKVswXVxuICBub3JtYWxpemVkID0gbm9ybWFsaXplZC5zcGxpdCgnOicpWzBdXG4gIHJldHVybiBub3JtYWxpemVkXG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEb21haW4gQWRkIENvbW1hbmRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQWRkIGEgY3VzdG9tIGRvbWFpbiB0byB0aGUgcHJvamVjdFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9tYWluQWRkKGN1c3RvbURvbWFpbjogc3RyaW5nLCBvcHRpb25zOiBEb21haW5PcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvY2Vzcy5jd2QoKVxuICBjb25zdCBhcGlVcmwgPSBvcHRpb25zLnVybCB8fCBwcm9jZXNzLmVudi5ERVZET0NfQVBJX1VSTCB8fCBERUZBVUxUX0FQSV9VUkxcbiAgXG4gIGxvZ2dlci5pbmZvKCdBZGRpbmcgY3VzdG9tIGRvbWFpbi4uLlxcbicpXG4gIFxuICAvLyBMb2FkIGNvbmZpZ1xuICBjb25zdCBjb25maWcgPSBsb2FkRGV2RG9jQ29uZmlnKHByb2plY3RSb290KVxuICBpZiAoIWNvbmZpZykge1xuICAgIGxvZ2dlci5lcnJvcignUHJvamVjdCBub3QgaW5pdGlhbGl6ZWQuJylcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBsb2dnZXIuaW5mbygnUnVuIFwiZGV2ZG9jIGluaXRcIiB0byBpbml0aWFsaXplLCB0aGVuIFwiZGV2ZG9jIGRlcGxveVwiIHRvIGRlcGxveS4nKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIFxuICAvLyBHZXQgQVBJIGtleSAtIHJlcXVpcmVkIGJlY2F1c2UgY3VzdG9tIGRvbWFpbnMgbmVlZCBhIGRlcGxveWVkIHByb2plY3RcbiAgY29uc3QgYXBpS2V5ID0gZ2V0QXBpS2V5KG9wdGlvbnMsIGNvbmZpZylcbiAgaWYgKCFhcGlLZXkpIHtcbiAgICBsb2dnZXIuZXJyb3IoJ1Byb2plY3Qgbm90IGRlcGxveWVkIHlldC4nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGNvbnNvbGUubG9nKCcgIEN1c3RvbSBkb21haW5zIHJlcXVpcmUgYSBkZXBsb3llZCBwcm9qZWN0LicpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgY29uc29sZS5sb2coJyAgVG8gc2V0IHVwIGEgY3VzdG9tIGRvbWFpbjonKVxuICAgIGNvbnNvbGUubG9nKCcgICAgMS4gRGVwbG95IHlvdXIgcHJvamVjdCBmaXJzdDogIGRldmRvYyBkZXBsb3knKVxuICAgIGNvbnNvbGUubG9nKCcgICAgMi4gVGhlbiBhZGQgeW91ciBkb21haW46ICAgICAgIGRldmRvYyBkb21haW4gYWRkICcgKyBjdXN0b21Eb21haW4pXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbiAgXG4gIC8vIE5vcm1hbGl6ZSBhbmQgdmFsaWRhdGUgZG9tYWluXG4gIGNvbnN0IGRvbWFpbiA9IG5vcm1hbGl6ZURvbWFpbihjdXN0b21Eb21haW4pXG4gIGNvbnN0IHZhbGlkYXRpb24gPSBpc1ZhbGlkRG9tYWluRm9ybWF0KGRvbWFpbilcbiAgaWYgKCF2YWxpZGF0aW9uLnZhbGlkKSB7XG4gICAgbG9nZ2VyLmVycm9yKHZhbGlkYXRpb24uZXJyb3IhKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIFxuICBsb2dnZXIuaW5mbyhgRG9tYWluOiAke2RvbWFpbn1gKVxuICBjb25zb2xlLmxvZygnJylcbiAgXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHthcGlVcmx9L2FwaS9kb21haW5zL2FkZGAsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHthcGlLZXl9YCxcbiAgICAgIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IGN1c3RvbURvbWFpbjogZG9tYWluIH0pLFxuICAgIH0pXG4gICAgXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIERvbWFpbkFkZFJlc3BvbnNlXG4gICAgXG4gICAgaWYgKCFyZXNwb25zZS5vayB8fCAhcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihyZXN1bHQuZXJyb3IgfHwgJ0ZhaWxlZCB0byBhZGQgZG9tYWluJylcbiAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgIH1cbiAgICBcbiAgICBsb2dnZXIuc3VjY2Vzcyhg4pyTIERvbWFpbiAke2RvbWFpbn0gYWRkZWQhYClcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBcbiAgICAvLyBDaGVjayBpZiBkb21haW4gaXMgYWxyZWFkeSB2ZXJpZmllZCAoVmVyY2VsIG1heSBhdXRvLXZlcmlmeSBpZiBETlMgaXMgYWxyZWFkeSBjb25maWd1cmVkKVxuICAgIGlmIChyZXN1bHQudmVyaWZpZWQpIHtcbiAgICAgIGNvbnNvbGUubG9nKCcgICcgKyBsb2dnZXIuZ3JlZW4oJ0RvbWFpbiBpcyBhbHJlYWR5IHZlcmlmaWVkIGFuZCBhY3RpdmUhJykpXG4gICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgIGNvbnNvbGUubG9nKCcgIFlvdXIgZG9jcyB3aWxsIGJlIGF2YWlsYWJsZSBhdDonKVxuICAgICAgY29uc29sZS5sb2coYCAgJHtsb2dnZXIuY3lhbihgaHR0cHM6Ly8ke2RvbWFpbn1gKX1gKVxuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgXG4gICAgY29uc29sZS5sb2coJyAgTmV4dCwgYWRkIHRoZXNlIEROUyByZWNvcmRzIHRvIHlvdXIgZG9tYWluIHByb3ZpZGVyOicpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgXG4gICAgLy8gRGlzcGxheSB2ZXJpZmljYXRpb24gcmVjb3JkcyBmcm9tIFZlcmNlbFxuICAgIGlmIChyZXN1bHQudmVyaWZpY2F0aW9uICYmIEFycmF5LmlzQXJyYXkocmVzdWx0LnZlcmlmaWNhdGlvbikpIHtcbiAgICAgIHJlc3VsdC52ZXJpZmljYXRpb24uZm9yRWFjaCgocmVjb3JkLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhgICAke2luZGV4ICsgMX0uICR7cmVjb3JkLnR5cGV9IFJlY29yZDpgKVxuICAgICAgICBjb25zb2xlLmxvZyhgICAgICBOYW1lOiAgJHtyZWNvcmQubmFtZX1gKVxuICAgICAgICBjb25zb2xlLmxvZyhgICAgICBWYWx1ZTogJHtyZWNvcmQudmFsdWV9YClcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICB9KVxuICAgIH1cbiAgICBcbiAgICBsb2dnZXIuaW5mbygnQWZ0ZXIgYWRkaW5nIEROUyByZWNvcmRzLCBydW46JylcbiAgICBjb25zb2xlLmxvZygnICBkZXZkb2MgZG9tYWluIHZlcmlmeScpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKVxuICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGFkZCBkb21haW46ICR7bWVzc2FnZX1gKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEb21haW4gU3RhdHVzIENvbW1hbmRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ2hlY2sgc3RhdHVzIG9mIGN1c3RvbSBkb21haW5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvbWFpblN0YXR1cyhvcHRpb25zOiBEb21haW5PcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvY2Vzcy5jd2QoKVxuICBjb25zdCBhcGlVcmwgPSBvcHRpb25zLnVybCB8fCBwcm9jZXNzLmVudi5ERVZET0NfQVBJX1VSTCB8fCBERUZBVUxUX0FQSV9VUkxcbiAgXG4gIC8vIExvYWQgY29uZmlnXG4gIGNvbnN0IGNvbmZpZyA9IGxvYWREZXZEb2NDb25maWcocHJvamVjdFJvb3QpXG4gIGlmICghY29uZmlnKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdQcm9qZWN0IG5vdCBpbml0aWFsaXplZC4nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGxvZ2dlci5pbmZvKCdSdW4gXCJkZXZkb2MgaW5pdFwiIHRvIGluaXRpYWxpemUsIHRoZW4gXCJkZXZkb2MgZGVwbG95XCIgdG8gZGVwbG95LicpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbiAgXG4gIC8vIEdldCBBUEkga2V5XG4gIGNvbnN0IGFwaUtleSA9IGdldEFwaUtleShvcHRpb25zLCBjb25maWcpXG4gIGlmICghYXBpS2V5KSB7XG4gICAgbG9nZ2VyLmVycm9yKCdQcm9qZWN0IG5vdCBkZXBsb3llZCB5ZXQuJylcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBsb2dnZXIuaW5mbygnRGVwbG95IHlvdXIgcHJvamVjdCBmaXJzdCB3aXRoIFwiZGV2ZG9jIGRlcGxveVwiJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2FwaVVybH0vYXBpL2RvbWFpbnMvc3RhdHVzYCwge1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICB9LFxuICAgIH0pXG4gICAgXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIERvbWFpblN0YXR1c1Jlc3BvbnNlXG4gICAgXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgbG9nZ2VyLmVycm9yKHJlc3VsdC5lcnJvciB8fCAnRmFpbGVkIHRvIGdldCBkb21haW4gc3RhdHVzJylcbiAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBjb25zb2xlLmxvZygnICBDdXN0b20gRG9tYWluIFN0YXR1cycpXG4gICAgY29uc29sZS5sb2coJyAgLS0tLS0tLS0tLS0tLS0tLS0tLS0nKVxuICAgIFxuICAgIGlmICghcmVzdWx0Lmhhc0N1c3RvbURvbWFpbikge1xuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICBjb25zb2xlLmxvZygnICBObyBjdXN0b20gZG9tYWluIGNvbmZpZ3VyZWQuJylcbiAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgY29uc29sZS5sb2coJyAgWW91ciBkb2NzIGFyZSBhdmFpbGFibGUgYXQ6JylcbiAgICAgIGNvbnNvbGUubG9nKGAgICR7bG9nZ2VyLmN5YW4ocmVzdWx0LnByb2plY3RVcmwpfWApXG4gICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgIGxvZ2dlci5pbmZvKCdUbyBhZGQgYSBjdXN0b20gZG9tYWluLCBydW46JylcbiAgICAgIGNvbnNvbGUubG9nKCcgIGRldmRvYyBkb21haW4gYWRkIGRvY3MueW91cmRvbWFpbi5jb20nKVxuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgY29uc29sZS5sb2coYCAgRG9tYWluOiAgJHtyZXN1bHQuZG9tYWlufWApXG4gICAgY29uc29sZS5sb2coYCAgU3RhdHVzOiAgJHtnZXRTdGF0dXNEaXNwbGF5KHJlc3VsdC5zdGF0dXMgfHwgJ3Vua25vd24nKX1gKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIFxuICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSAnYWN0aXZlJykge1xuICAgICAgY29uc29sZS5sb2coJyAgWW91ciBkb2NzIGFyZSBhdmFpbGFibGUgYXQ6JylcbiAgICAgIGNvbnNvbGUubG9nKGAgICR7bG9nZ2VyLmN5YW4ocmVzdWx0LmN1c3RvbVVybCB8fCBgaHR0cHM6Ly8ke3Jlc3VsdC5kb21haW59YCl9YClcbiAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgY29uc29sZS5sb2coJyAgQWxzbyBhY2Nlc3NpYmxlIGF0OicpXG4gICAgICBjb25zb2xlLmxvZyhgICAke3Jlc3VsdC5wcm9qZWN0VXJsfWApXG4gICAgfSBlbHNlIGlmIChyZXN1bHQuc3RhdHVzID09PSAncGVuZGluZycpIHtcbiAgICAgIGlmIChyZXN1bHQudmVyaWZpY2F0aW9uICYmIHJlc3VsdC52ZXJpZmljYXRpb24ubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zb2xlLmxvZygnICBBZGQgdGhlc2UgRE5TIHJlY29yZHMgdG8geW91ciBkb21haW46JylcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIHJlc3VsdC52ZXJpZmljYXRpb24uZm9yRWFjaCgocmVjb3JkLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICR7aW5kZXggKyAxfS4gJHtyZWNvcmQudHlwZX0gUmVjb3JkOmApXG4gICAgICAgICAgY29uc29sZS5sb2coYCAgICAgTmFtZTogICR7cmVjb3JkLm5hbWV9YClcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICAgICBWYWx1ZTogJHtyZWNvcmQudmFsdWV9YClcbiAgICAgICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgICAgfSlcbiAgICAgICAgbG9nZ2VyLmluZm8oJ0FmdGVyIGFkZGluZyBETlMgcmVjb3JkcywgcnVuOiBkZXZkb2MgZG9tYWluIHZlcmlmeScpXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZXN1bHQubWVzc2FnZSkge1xuICAgICAgY29uc29sZS5sb2coYCAgJHtyZXN1bHQubWVzc2FnZX1gKVxuICAgIH1cbiAgICBcbiAgICBpZiAocmVzdWx0Lm5leHRTdGVwKSB7XG4gICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgIGxvZ2dlci5pbmZvKGBOZXh0OiAke3Jlc3VsdC5uZXh0U3RlcH1gKVxuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IGRvbWFpbiBzdGF0dXM6ICR7bWVzc2FnZX1gKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG59XG5cbi8qKlxuICogR2V0IGRpc3BsYXkgc3RyaW5nIGZvciBzdGF0dXNcbiAqL1xuZnVuY3Rpb24gZ2V0U3RhdHVzRGlzcGxheShzdGF0dXM6IHN0cmluZyk6IHN0cmluZyB7XG4gIHN3aXRjaCAoc3RhdHVzKSB7XG4gICAgY2FzZSAncGVuZGluZyc6XG4gICAgICByZXR1cm4gbG9nZ2VyLnllbGxvdygn4o+zIFBlbmRpbmcgRE5TIHZlcmlmaWNhdGlvbicpXG4gICAgY2FzZSAnYWN0aXZlJzpcbiAgICAgIHJldHVybiBsb2dnZXIuZ3JlZW4oJ+KckyBBY3RpdmUnKVxuICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgIHJldHVybiBsb2dnZXIucmVkKCfinJcgRXJyb3InKVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc3RhdHVzXG4gIH1cbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERvbWFpbiBWZXJpZnkgQ29tbWFuZFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBWZXJpZnkgRE5TIGNvbmZpZ3VyYXRpb24gZm9yIGN1c3RvbSBkb21haW5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvbWFpblZlcmlmeShvcHRpb25zOiBEb21haW5PcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvY2Vzcy5jd2QoKVxuICBjb25zdCBhcGlVcmwgPSBvcHRpb25zLnVybCB8fCBwcm9jZXNzLmVudi5ERVZET0NfQVBJX1VSTCB8fCBERUZBVUxUX0FQSV9VUkxcbiAgXG4gIGxvZ2dlci5pbmZvKCdWZXJpZnlpbmcgRE5TIGNvbmZpZ3VyYXRpb24uLi5cXG4nKVxuICBcbiAgLy8gTG9hZCBjb25maWdcbiAgY29uc3QgY29uZmlnID0gbG9hZERldkRvY0NvbmZpZyhwcm9qZWN0Um9vdClcbiAgaWYgKCFjb25maWcpIHtcbiAgICBsb2dnZXIuZXJyb3IoJ1Byb2plY3Qgbm90IGluaXRpYWxpemVkLicpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgbG9nZ2VyLmluZm8oJ1J1biBcImRldmRvYyBpbml0XCIgdG8gaW5pdGlhbGl6ZSwgdGhlbiBcImRldmRvYyBkZXBsb3lcIiB0byBkZXBsb3kuJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgLy8gR2V0IEFQSSBrZXlcbiAgY29uc3QgYXBpS2V5ID0gZ2V0QXBpS2V5KG9wdGlvbnMsIGNvbmZpZylcbiAgaWYgKCFhcGlLZXkpIHtcbiAgICBsb2dnZXIuZXJyb3IoJ1Byb2plY3Qgbm90IGRlcGxveWVkIHlldC4nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGxvZ2dlci5pbmZvKCdEZXBsb3kgeW91ciBwcm9qZWN0IGZpcnN0IHdpdGggXCJkZXZkb2MgZGVwbG95XCInKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIFxuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7YXBpVXJsfS9hcGkvZG9tYWlucy92ZXJpZnlgLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe30pLFxuICAgIH0pXG4gICAgXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIERvbWFpblZlcmlmeVJlc3BvbnNlXG4gICAgXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgbG9nZ2VyLmVycm9yKHJlc3VsdC5lcnJvciB8fCAnRmFpbGVkIHRvIHZlcmlmeSBkb21haW4nKVxuICAgICAgcHJvY2Vzcy5leGl0KDEpXG4gICAgfVxuICAgIFxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGNvbnNvbGUubG9nKCcgIEROUyBWZXJpZmljYXRpb24gUmVzdWx0cycpXG4gICAgY29uc29sZS5sb2coJyAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJylcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBjb25zb2xlLmxvZyhgICBEb21haW46ICR7cmVzdWx0LmRvbWFpbn1gKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIFxuICAgIGlmIChyZXN1bHQudmVyaWZpZWQpIHtcbiAgICAgIGNvbnNvbGUubG9nKGAgIFN0YXR1czogJHtsb2dnZXIuZ3JlZW4oJ+KckyBWZXJpZmllZCcpfWApXG4gICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgIGxvZ2dlci5zdWNjZXNzKCdEb21haW4gdmVyaWZpZWQhJylcbiAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgY29uc29sZS5sb2coYCAgJHtyZXN1bHQubWVzc2FnZX1gKVxuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICBjb25zb2xlLmxvZygnICBZb3VyIGRvY3Mgd2lsbCBiZSBhdmFpbGFibGUgYXQ6JylcbiAgICAgIGNvbnNvbGUubG9nKGAgICR7bG9nZ2VyLmN5YW4oYGh0dHBzOi8vJHtyZXN1bHQuZG9tYWlufWApfWApXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKGAgIFN0YXR1czogJHtsb2dnZXIueWVsbG93KCfij7MgUGVuZGluZyB2ZXJpZmljYXRpb24nKX1gKVxuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICBcbiAgICAgIC8vIFNob3cgd2hhdCBETlMgcmVjb3JkcyBhcmUgbmVlZGVkXG4gICAgICBpZiAocmVzdWx0LnZlcmlmaWNhdGlvbiAmJiByZXN1bHQudmVyaWZpY2F0aW9uLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc29sZS5sb2coJyAgUmVxdWlyZWQgRE5TIHJlY29yZHM6JylcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIHJlc3VsdC52ZXJpZmljYXRpb24uZm9yRWFjaCgocmVjb3JkLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICR7aW5kZXggKyAxfS4gJHtyZWNvcmQudHlwZX0gUmVjb3JkOmApXG4gICAgICAgICAgY29uc29sZS5sb2coYCAgICAgTmFtZTogICR7cmVjb3JkLm5hbWV9YClcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICAgICBWYWx1ZTogJHtyZWNvcmQudmFsdWV9YClcbiAgICAgICAgICBjb25zb2xlLmxvZygnJylcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc29sZS5sb2coYCAgJHtyZXN1bHQubWVzc2FnZX1gKVxuICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICBsb2dnZXIuaW5mbygnRE5TIGNoYW5nZXMgY2FuIHRha2UgdXAgdG8gNDggaG91cnMgdG8gcHJvcGFnYXRlLicpXG4gICAgICBsb2dnZXIuaW5mbygnUnVuIFwiZGV2ZG9jIGRvbWFpbiB2ZXJpZnlcIiBhZ2FpbiBsYXRlci4nKVxuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gdmVyaWZ5IGRvbWFpbjogJHttZXNzYWdlfWApXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERvbWFpbiBSZW1vdmUgQ29tbWFuZFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBSZW1vdmUgY3VzdG9tIGRvbWFpbiBmcm9tIHByb2plY3RcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvbWFpblJlbW92ZShjdXN0b21Eb21haW46IHN0cmluZyB8IHVuZGVmaW5lZCwgb3B0aW9uczogRG9tYWluT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IHByb2Nlc3MuY3dkKClcbiAgY29uc3QgYXBpVXJsID0gb3B0aW9ucy51cmwgfHwgcHJvY2Vzcy5lbnYuREVWRE9DX0FQSV9VUkwgfHwgREVGQVVMVF9BUElfVVJMXG4gIFxuICBsb2dnZXIuaW5mbygnUmVtb3ZpbmcgY3VzdG9tIGRvbWFpbi4uLlxcbicpXG4gIFxuICAvLyBMb2FkIGNvbmZpZ1xuICBjb25zdCBjb25maWcgPSBsb2FkRGV2RG9jQ29uZmlnKHByb2plY3RSb290KVxuICBpZiAoIWNvbmZpZykge1xuICAgIGxvZ2dlci5lcnJvcignUHJvamVjdCBub3QgaW5pdGlhbGl6ZWQuJylcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBsb2dnZXIuaW5mbygnUnVuIFwiZGV2ZG9jIGluaXRcIiB0byBpbml0aWFsaXplLCB0aGVuIFwiZGV2ZG9jIGRlcGxveVwiIHRvIGRlcGxveS4nKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIFxuICAvLyBHZXQgQVBJIGtleVxuICBjb25zdCBhcGlLZXkgPSBnZXRBcGlLZXkob3B0aW9ucywgY29uZmlnKVxuICBpZiAoIWFwaUtleSkge1xuICAgIGxvZ2dlci5lcnJvcignUHJvamVjdCBub3QgZGVwbG95ZWQgeWV0LicpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgbG9nZ2VyLmluZm8oJ0RlcGxveSB5b3VyIHByb2plY3QgZmlyc3Qgd2l0aCBcImRldmRvYyBkZXBsb3lcIicpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbiAgXG4gIHRyeSB7XG4gICAgY29uc3QgYm9keTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9XG4gICAgaWYgKGN1c3RvbURvbWFpbikge1xuICAgICAgYm9keS5jdXN0b21Eb21haW4gPSBub3JtYWxpemVEb21haW4oY3VzdG9tRG9tYWluKVxuICAgIH1cbiAgICBcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2FwaVVybH0vYXBpL2RvbWFpbnMvcmVtb3ZlYCwge1xuICAgICAgbWV0aG9kOiAnREVMRVRFJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgfSlcbiAgICBcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCkgYXMgRG9tYWluUmVtb3ZlUmVzcG9uc2VcbiAgICBcbiAgICBpZiAoIXJlc3BvbnNlLm9rIHx8ICFyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgbG9nZ2VyLmVycm9yKHJlc3VsdC5lcnJvciB8fCAnRmFpbGVkIHRvIHJlbW92ZSBkb21haW4nKVxuICAgICAgcHJvY2Vzcy5leGl0KDEpXG4gICAgfVxuICAgIFxuICAgIGxvZ2dlci5zdWNjZXNzKGDinJMgRG9tYWluICR7cmVzdWx0LmRvbWFpbn0gcmVtb3ZlZGApXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgY29uc29sZS5sb2coJyAgWW91ciBkb2NzIHJlbWFpbiBhY2Nlc3NpYmxlIGF0IHRoZSBkZWZhdWx0IHN1YmRvbWFpbi4nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGxvZ2dlci5pbmZvKCdZb3UgY2FuIGFkZCBhIG5ldyBjdXN0b20gZG9tYWluIGFueXRpbWUgd2l0aDonKVxuICAgIGNvbnNvbGUubG9nKCcgIGRldmRvYyBkb21haW4gYWRkIGRvY3MueW91cmRvbWFpbi5jb20nKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIFxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byByZW1vdmUgZG9tYWluOiAke21lc3NhZ2V9YClcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxufVxuIl19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainfish-ai/devdoc",
3
- "version": "0.1.50",
3
+ "version": "0.1.51",
4
4
  "description": "Documentation framework for developers. Write docs in MDX, preview locally, deploy to Brainfish.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,17 +1,17 @@
1
1
  import { NextResponse } from 'next/server';
2
2
  import { validateApiKey, addCustomDomain, isCustomDomainRegistered, updateCustomDomainStatus } from '@/lib/storage/blob';
3
3
  import { isValidDomain, normalizeDomain } from '@/lib/docs/config';
4
- import { addDomainToProject, isVercelIntegrationEnabled, formatVerificationInstructions, getDomainType } from '@/lib/vercel/domains';
4
+ import { addDomainToProject, isVercelIntegrationEnabled, formatVerificationInstructions } from '@/lib/vercel/domains';
5
5
  /**
6
6
  * POST /api/domains/add
7
7
  *
8
- * Add a custom domain to a project.
8
+ * Add a custom domain to a project via Vercel Domains API.
9
9
  * Each project can have ONE custom domain (free).
10
10
  *
11
- * When Vercel integration is enabled (VERCEL_API_TOKEN + VERCEL_PROJECT_ID):
12
- * - Domain is added to Vercel project
13
- * - Real DNS verification instructions from Vercel are returned
14
- * - SSL is provisioned automatically by Vercel after verification
11
+ * Requires environment variables:
12
+ * - VERCEL_API_TOKEN (or VERCEL_TOKEN)
13
+ * - VERCEL_PROJECT_ID
14
+ * - VERCEL_TEAM_ID (optional)
15
15
  *
16
16
  * Headers:
17
17
  * Authorization: Bearer <api_key>
@@ -25,7 +25,7 @@ import { addDomainToProject, isVercelIntegrationEnabled, formatVerificationInstr
25
25
  * domain: "docs.example.com",
26
26
  * status: "pending",
27
27
  * verification: [
28
- * { type: "TXT", domain: "_vercel.docs.example.com", value: "vc-domain-verify=..." }
28
+ * { type: "TXT", name: "_vercel.example.com", value: "vc-domain-verify=..." }
29
29
  * ]
30
30
  * }
31
31
  */ export async function POST(request) {
@@ -77,115 +77,79 @@ import { addDomainToProject, isVercelIntegrationEnabled, formatVerificationInstr
77
77
  status: 409
78
78
  });
79
79
  }
80
- // Check if Vercel integration is enabled
81
- if (isVercelIntegrationEnabled()) {
82
- // Add domain to Vercel project
83
- const vercelResult = await addDomainToProject(customDomain);
84
- if (!vercelResult.success) {
85
- return NextResponse.json({
86
- error: vercelResult.error,
87
- vercelError: vercelResult.vercelError
88
- }, {
89
- status: 400
90
- });
91
- }
92
- const vercelDomain = vercelResult.domain;
93
- // Add to our internal registry with Vercel data
94
- const result = await addCustomDomain(projectSlug, customDomain);
95
- if (!result.success) {
96
- // Rollback: Try to remove from Vercel if we couldn't add to registry
97
- console.error('[Domains API] Failed to add to registry, domain added to Vercel:', customDomain);
98
- return NextResponse.json({
99
- error: result.error
100
- }, {
101
- status: 400
102
- });
103
- }
104
- // Update with Vercel domain ID
105
- await updateCustomDomainStatus(customDomain, vercelDomain.verified ? 'active' : 'pending', {
106
- vercelDomainId: vercelDomain.projectId
80
+ // Require Vercel integration
81
+ if (!isVercelIntegrationEnabled()) {
82
+ return NextResponse.json({
83
+ error: 'Vercel integration not configured. Set VERCEL_API_TOKEN and VERCEL_PROJECT_ID environment variables.'
84
+ }, {
85
+ status: 503
107
86
  });
108
- // If Vercel already verified the domain (e.g., previously configured DNS)
109
- if (vercelDomain.verified) {
110
- return NextResponse.json({
111
- success: true,
112
- domain: customDomain,
113
- projectSlug,
114
- status: 'active',
115
- verified: true,
116
- message: 'Domain is already verified and active!'
117
- });
118
- }
119
- // Format Vercel's verification instructions
120
- const verification = vercelDomain.verification || [];
121
- const { records, instructions } = formatVerificationInstructions(verification);
122
- // Add CNAME instruction for subdomains (Vercel may not always include it)
123
- const domainType = getDomainType(customDomain);
124
- const parts = customDomain.split('.');
125
- const subdomain = parts.length > 2 ? parts[0] : '@';
126
- const cnameInstruction = domainType === 'subdomain' ? `\nAlso add a CNAME record:\n Name: ${subdomain}\n Value: cname.vercel-dns.com` : `\nFor apex domains, add an A record:\n Name: @\n Value: 76.76.21.21`;
87
+ }
88
+ // Add domain to Vercel project
89
+ const vercelResult = await addDomainToProject(customDomain);
90
+ if (!vercelResult.success) {
127
91
  return NextResponse.json({
128
- success: true,
129
- domain: customDomain,
130
- projectSlug,
131
- status: 'pending',
132
- verified: false,
133
- verification: records,
134
- instructions: [
135
- ...instructions,
136
- cnameInstruction
137
- ],
138
- vercelVerification: verification
92
+ error: vercelResult.error,
93
+ vercelError: vercelResult.vercelError
94
+ }, {
95
+ status: 400
139
96
  });
140
- } else {
141
- // Fallback: No Vercel integration, use legacy behavior
142
- console.warn('[Domains API] Vercel integration not configured, using legacy mode');
143
- const result = await addCustomDomain(projectSlug, customDomain);
144
- if (!result.success) {
145
- return NextResponse.json({
146
- error: result.error
147
- }, {
148
- status: 400
149
- });
150
- }
151
- // Legacy hardcoded DNS instructions
152
- const parts = customDomain.split('.');
153
- const subdomain = parts.length > 2 ? parts[0] : '@';
97
+ }
98
+ const vercelDomain = vercelResult.domain;
99
+ // Add to our internal registry with Vercel data
100
+ const result = await addCustomDomain(projectSlug, customDomain);
101
+ if (!result.success) {
102
+ // Rollback: Try to remove from Vercel if we couldn't add to registry
103
+ console.error('[Domains API] Failed to add to registry, domain added to Vercel:', customDomain);
104
+ return NextResponse.json({
105
+ error: result.error
106
+ }, {
107
+ status: 400
108
+ });
109
+ }
110
+ // Update with Vercel domain ID
111
+ await updateCustomDomainStatus(customDomain, vercelDomain.verified ? 'active' : 'pending', {
112
+ vercelDomainId: vercelDomain.projectId
113
+ });
114
+ // If Vercel already verified the domain (e.g., previously configured DNS)
115
+ if (vercelDomain.verified) {
154
116
  return NextResponse.json({
155
117
  success: true,
156
118
  domain: customDomain,
157
119
  projectSlug,
158
- status: result.entry.status,
159
- verified: false,
160
- verification: [
161
- {
162
- type: 'CNAME',
163
- name: subdomain,
164
- value: 'cname.vercel-dns.com'
165
- },
166
- {
167
- type: 'TXT',
168
- name: `_devdoc-verify.${customDomain}`,
169
- value: result.entry.verificationToken || ''
170
- }
171
- ],
172
- instructions: [
173
- 'Add the following DNS records to your domain:',
174
- '',
175
- '1. CNAME Record:',
176
- ` Name: ${subdomain}`,
177
- ' Value: cname.vercel-dns.com',
178
- '',
179
- '2. TXT Record (for verification):',
180
- ` Name: _devdoc-verify.${customDomain}`,
181
- ` Value: ${result.entry.verificationToken || ''}`,
182
- '',
183
- 'After adding DNS records, run "devdoc domain verify" to verify.',
184
- '',
185
- 'Note: Vercel integration not configured. Set VERCEL_API_TOKEN and VERCEL_PROJECT_ID for automatic SSL.'
186
- ]
120
+ status: 'active',
121
+ verified: true,
122
+ message: 'Domain is already verified and active!'
187
123
  });
188
124
  }
125
+ // Format Vercel's verification instructions
126
+ const verification = vercelDomain.verification || [];
127
+ const { records } = formatVerificationInstructions(verification);
128
+ // Add CNAME/A record for routing (Vercel only returns TXT for verification)
129
+ const parts = customDomain.split('.');
130
+ const isApexDomain = parts.length <= 2;
131
+ const subdomain = parts.length > 2 ? parts[0] : '@';
132
+ // Add routing record first, then verification records
133
+ const allRecords = [
134
+ isApexDomain ? {
135
+ type: 'A',
136
+ name: '@',
137
+ value: '76.76.21.21'
138
+ } : {
139
+ type: 'CNAME',
140
+ name: subdomain,
141
+ value: 'cname.vercel-dns.com'
142
+ },
143
+ ...records
144
+ ];
145
+ return NextResponse.json({
146
+ success: true,
147
+ domain: customDomain,
148
+ projectSlug,
149
+ status: 'pending',
150
+ verified: false,
151
+ verification: allRecords
152
+ });
189
153
  } catch (error) {
190
154
  console.error('[Domains API] Error adding domain:', error);
191
155
  const message = error instanceof Error ? error.message : String(error);
@@ -5,11 +5,13 @@ import { removeDomain as vercelRemoveDomain, isVercelIntegrationEnabled } from '
5
5
  /**
6
6
  * DELETE /api/domains/remove
7
7
  *
8
- * Remove a custom domain from a project.
8
+ * Remove a custom domain from a project via Vercel API.
9
+ * Removes from both Vercel and internal registry.
9
10
  *
10
- * When Vercel integration is enabled:
11
- * - Removes domain from Vercel project
12
- * - Removes from internal registry
11
+ * Requires environment variables:
12
+ * - VERCEL_API_TOKEN (or VERCEL_TOKEN)
13
+ * - VERCEL_PROJECT_ID
14
+ * - VERCEL_TEAM_ID (optional)
13
15
  *
14
16
  * Headers:
15
17
  * Authorization: Bearer <api_key>
@@ -57,15 +59,21 @@ import { removeDomain as vercelRemoveDomain, isVercelIntegrationEnabled } from '
57
59
  }
58
60
  customDomain = projectDomain.customDomain;
59
61
  }
60
- // Remove from Vercel if integration is enabled
61
- if (isVercelIntegrationEnabled()) {
62
- const vercelResult = await vercelRemoveDomain(customDomain);
63
- if (!vercelResult.success) {
64
- // Log warning but continue - domain might not exist in Vercel
65
- console.warn('[Domains API] Failed to remove from Vercel:', vercelResult.error);
66
- } else {
67
- console.log('[Domains API] Domain removed from Vercel:', customDomain);
68
- }
62
+ // Require Vercel integration
63
+ if (!isVercelIntegrationEnabled()) {
64
+ return NextResponse.json({
65
+ error: 'Vercel integration not configured. Set VERCEL_API_TOKEN and VERCEL_PROJECT_ID environment variables.'
66
+ }, {
67
+ status: 503
68
+ });
69
+ }
70
+ // Remove from Vercel
71
+ const vercelResult = await vercelRemoveDomain(customDomain);
72
+ if (!vercelResult.success) {
73
+ // Log warning but continue - domain might not exist in Vercel
74
+ console.warn('[Domains API] Failed to remove from Vercel:', vercelResult.error);
75
+ } else {
76
+ console.log('[Domains API] Domain removed from Vercel:', customDomain);
69
77
  }
70
78
  // Remove from internal registry
71
79
  const result = await removeCustomDomain(customDomain, projectSlug);
@@ -1,11 +1,17 @@
1
1
  import { NextResponse } from 'next/server';
2
2
  import { validateApiKey, getProjectCustomDomain, getCustomDomainEntry } from '@/lib/storage/blob';
3
- import { normalizeDomain, getDnsInstructions } from '@/lib/docs/config';
3
+ import { normalizeDomain } from '@/lib/docs/config';
4
4
  import { getProjectUrl } from '@/lib/multi-tenant/context';
5
+ import { getDomainConfig, isVercelIntegrationEnabled, formatVerificationInstructions } from '@/lib/vercel/domains';
5
6
  /**
6
7
  * GET /api/domains/status
7
8
  *
8
- * Get the status of a custom domain.
9
+ * Get the status of a custom domain via Vercel API.
10
+ *
11
+ * Requires environment variables:
12
+ * - VERCEL_API_TOKEN (or VERCEL_TOKEN)
13
+ * - VERCEL_PROJECT_ID
14
+ * - VERCEL_TEAM_ID (optional)
9
15
  *
10
16
  * Headers:
11
17
  * Authorization: Bearer <api_key>
@@ -94,26 +100,18 @@ import { getProjectUrl } from '@/lib/multi-tenant/context';
94
100
  switch(domainEntry.status){
95
101
  case 'pending':
96
102
  {
97
- const dnsInstructions = getDnsInstructions(domainEntry.customDomain);
98
- dnsInstructions.txt.value = domainEntry.verificationToken || '';
99
103
  response.message = 'Waiting for DNS configuration';
100
- response.dnsRecords = {
101
- cname: dnsInstructions.cname,
102
- txt: dnsInstructions.txt
103
- };
104
- response.nextStep = 'Add the DNS records above, then run "devdoc domain verify"';
104
+ response.nextStep = 'Add the DNS records below, then run "devdoc domain verify"';
105
+ // Get verification instructions from Vercel if available
106
+ if (isVercelIntegrationEnabled()) {
107
+ const configResult = await getDomainConfig(domainEntry.customDomain);
108
+ if (configResult.success && configResult.domain?.verification) {
109
+ const { records } = formatVerificationInstructions(configResult.domain.verification);
110
+ response.verification = records;
111
+ }
112
+ }
105
113
  break;
106
114
  }
107
- case 'dns_verified':
108
- response.message = 'DNS verified, SSL certificate provisioning in progress';
109
- response.verifiedAt = domainEntry.verifiedAt;
110
- response.nextStep = 'SSL certificate should be ready within 1-24 hours';
111
- break;
112
- case 'ssl_provisioning':
113
- response.message = 'SSL certificate being provisioned';
114
- response.verifiedAt = domainEntry.verifiedAt;
115
- response.nextStep = 'Almost ready! Check back in a few minutes';
116
- break;
117
115
  case 'active':
118
116
  response.message = 'Domain is active and working';
119
117
  response.customUrl = `https://${domainEntry.customDomain}`;
@@ -2,21 +2,16 @@ import { NextResponse } from 'next/server';
2
2
  import { validateApiKey, getProjectCustomDomain, getCustomDomainEntry, updateCustomDomainStatus } from '@/lib/storage/blob';
3
3
  import { normalizeDomain } from '@/lib/docs/config';
4
4
  import { verifyDomain as vercelVerifyDomain, getDomainConfig, isVercelIntegrationEnabled, formatVerificationInstructions } from '@/lib/vercel/domains';
5
- import dns from 'dns';
6
- import { promisify } from 'util';
7
- const resolveCname = promisify(dns.resolveCname);
8
- const resolveTxt = promisify(dns.resolveTxt);
9
5
  /**
10
6
  * POST /api/domains/verify
11
7
  *
12
- * Verify DNS configuration for a custom domain.
8
+ * Verify DNS configuration for a custom domain via Vercel API.
9
+ * Vercel handles DNS verification and automatic SSL provisioning.
13
10
  *
14
- * When Vercel integration is enabled:
15
- * - Calls Vercel's verify endpoint directly
16
- * - Vercel handles DNS verification and SSL provisioning
17
- *
18
- * Legacy mode (no Vercel integration):
19
- * - Checks CNAME and TXT records manually
11
+ * Requires environment variables:
12
+ * - VERCEL_API_TOKEN (or VERCEL_TOKEN)
13
+ * - VERCEL_PROJECT_ID
14
+ * - VERCEL_TEAM_ID (optional)
20
15
  *
21
16
  * Headers:
22
17
  * Authorization: Bearer <api_key>
@@ -84,142 +79,71 @@ const resolveTxt = promisify(dns.resolveTxt);
84
79
  status: 403
85
80
  });
86
81
  }
87
- // Use Vercel integration if available
88
- if (isVercelIntegrationEnabled()) {
89
- // Call Vercel's verify endpoint
90
- const verifyResult = await vercelVerifyDomain(customDomain);
91
- if (!verifyResult.success) {
92
- // Get current domain config to show what's needed
93
- const configResult = await getDomainConfig(customDomain);
94
- const verification = configResult.domain?.verification || [];
95
- let instructions = [];
96
- if (verification.length > 0) {
97
- const formatted = formatVerificationInstructions(verification);
98
- instructions = formatted.instructions;
99
- }
100
- return NextResponse.json({
101
- success: false,
102
- domain: customDomain,
103
- projectSlug,
104
- status: domainEntry.status,
105
- verified: false,
106
- message: verifyResult.error || 'DNS verification failed. Please check your DNS records.',
107
- verification: verification.map((v)=>({
108
- type: v.type,
109
- name: v.domain,
110
- value: v.value
111
- })),
112
- instructions
113
- });
114
- }
115
- // Domain verified successfully
116
- if (verifyResult.verified) {
117
- // Update our registry to mark as active
118
- await updateCustomDomainStatus(customDomain, 'active');
119
- return NextResponse.json({
120
- success: true,
121
- domain: customDomain,
122
- projectSlug,
123
- status: 'active',
124
- verified: true,
125
- message: 'Domain verified! SSL certificate will be provisioned automatically by Vercel.'
126
- });
127
- } else {
128
- // Vercel didn't verify yet, return what's needed
129
- const verification = verifyResult.domain?.verification || [];
130
- const { instructions } = formatVerificationInstructions(verification);
131
- return NextResponse.json({
132
- success: false,
133
- domain: customDomain,
134
- projectSlug,
135
- status: 'pending',
136
- verified: false,
137
- message: 'DNS records not yet propagated. This can take up to 48 hours.',
138
- verification: verification.map((v)=>({
139
- type: v.type,
140
- name: v.domain,
141
- value: v.value
142
- })),
143
- instructions
144
- });
145
- }
146
- }
147
- // Legacy verification (no Vercel integration)
148
- console.warn('[Domains API] Vercel integration not configured, using legacy DNS verification');
149
- // Check DNS records manually
150
- const checks = {
151
- cname: {
152
- found: false,
153
- value: null,
154
- expected: 'cname.vercel-dns.com'
155
- },
156
- txt: {
157
- found: false,
158
- verified: false,
159
- expected: domainEntry.verificationToken
160
- }
161
- };
162
- // Check CNAME record
163
- try {
164
- const cnameRecords = await resolveCname(customDomain);
165
- if (cnameRecords && cnameRecords.length > 0) {
166
- checks.cname.found = true;
167
- checks.cname.value = cnameRecords[0];
168
- }
169
- } catch {
170
- // CNAME not found or DNS error
82
+ // Require Vercel integration
83
+ if (!isVercelIntegrationEnabled()) {
84
+ return NextResponse.json({
85
+ error: 'Vercel integration not configured. Set VERCEL_API_TOKEN and VERCEL_PROJECT_ID environment variables.'
86
+ }, {
87
+ status: 503
88
+ });
171
89
  }
172
- // Check TXT record for verification
173
- const txtRecordName = `_devdoc-verify.${customDomain}`;
174
- try {
175
- const txtRecords = await resolveTxt(txtRecordName);
176
- if (txtRecords && txtRecords.length > 0) {
177
- checks.txt.found = true;
178
- // TXT records can be arrays, flatten and check
179
- const allTxtValues = txtRecords.flat();
180
- checks.txt.verified = allTxtValues.some((val)=>val === domainEntry.verificationToken);
90
+ // Call Vercel's verify endpoint
91
+ const verifyResult = await vercelVerifyDomain(customDomain);
92
+ if (!verifyResult.success) {
93
+ // Get current domain config to show what's needed
94
+ const configResult = await getDomainConfig(customDomain);
95
+ const verification = configResult.domain?.verification || [];
96
+ let instructions = [];
97
+ if (verification.length > 0) {
98
+ const formatted = formatVerificationInstructions(verification);
99
+ instructions = formatted.instructions;
181
100
  }
182
- } catch {
183
- // TXT not found or DNS error
101
+ return NextResponse.json({
102
+ success: false,
103
+ domain: customDomain,
104
+ projectSlug,
105
+ status: domainEntry.status,
106
+ verified: false,
107
+ message: verifyResult.error || 'DNS verification failed. Please check your DNS records.',
108
+ verification: verification.map((v)=>({
109
+ type: v.type,
110
+ name: v.domain,
111
+ value: v.value
112
+ })),
113
+ instructions
114
+ });
184
115
  }
185
- // Determine overall status
186
- const cnameValid = checks.cname.found && checks.cname.value?.toLowerCase().includes('vercel');
187
- const txtValid = checks.txt.found && checks.txt.verified;
188
- let newStatus = domainEntry.status;
189
- let message = '';
190
- if (cnameValid && txtValid) {
191
- // DNS is verified
192
- newStatus = 'active';
193
- message = 'DNS verified! Domain is now active.';
116
+ // Domain verified successfully
117
+ if (verifyResult.verified) {
118
+ // Update our registry to mark as active
194
119
  await updateCustomDomainStatus(customDomain, 'active');
195
- } else if (cnameValid && !txtValid) {
196
- message = 'CNAME record found, but TXT verification record is missing or incorrect.';
197
- } else if (!cnameValid && txtValid) {
198
- message = 'TXT verification found, but CNAME record is missing or incorrect.';
120
+ return NextResponse.json({
121
+ success: true,
122
+ domain: customDomain,
123
+ projectSlug,
124
+ status: 'active',
125
+ verified: true,
126
+ message: 'Domain verified! SSL certificate will be provisioned automatically by Vercel.'
127
+ });
199
128
  } else {
200
- message = 'DNS records not found. Please add the required CNAME and TXT records.';
129
+ // Vercel didn't verify yet, return what's needed
130
+ const verification = verifyResult.domain?.verification || [];
131
+ const { instructions } = formatVerificationInstructions(verification);
132
+ return NextResponse.json({
133
+ success: false,
134
+ domain: customDomain,
135
+ projectSlug,
136
+ status: 'pending',
137
+ verified: false,
138
+ message: 'DNS records not yet propagated. This can take up to 48 hours.',
139
+ verification: verification.map((v)=>({
140
+ type: v.type,
141
+ name: v.domain,
142
+ value: v.value
143
+ })),
144
+ instructions
145
+ });
201
146
  }
202
- return NextResponse.json({
203
- success: cnameValid && txtValid,
204
- domain: customDomain,
205
- projectSlug,
206
- status: newStatus,
207
- verified: cnameValid && txtValid,
208
- message,
209
- checks: {
210
- cname: {
211
- found: checks.cname.found,
212
- value: checks.cname.value,
213
- valid: cnameValid,
214
- expected: checks.cname.expected
215
- },
216
- txt: {
217
- found: checks.txt.found,
218
- verified: checks.txt.verified,
219
- expected: checks.txt.expected
220
- }
221
- }
222
- });
223
147
  } catch (error) {
224
148
  console.error('[Domains API] Error verifying domain:', error);
225
149
  const message = error instanceof Error ? error.message : String(error);
@@ -143,41 +143,3 @@ export const domainConfigSchema = z.object({
143
143
  normalized = normalized.split(':')[0];
144
144
  return normalized;
145
145
  }
146
- /**
147
- * Get DNS instructions for a custom domain
148
- *
149
- * NOTE: When Vercel integration is enabled (VERCEL_API_TOKEN + VERCEL_PROJECT_ID),
150
- * the actual DNS instructions come from Vercel's API response.
151
- * This function is used as a fallback for legacy/local development mode.
152
- *
153
- * For Vercel-hosted projects:
154
- * - Subdomains: CNAME to cname.vercel-dns.com
155
- * - Apex domains: A record to 76.76.21.21
156
- *
157
- * @param customDomain - The custom domain (e.g., "docs.example.com")
158
- * @returns DNS instructions for CNAME and TXT records
159
- */ export function getDnsInstructions(customDomain) {
160
- const parts = customDomain.split('.');
161
- const subdomain = parts.length > 2 ? parts[0] : '@';
162
- const isApexDomain = parts.length <= 2;
163
- return {
164
- cname: {
165
- name: subdomain === '@' ? customDomain : subdomain,
166
- // Use Vercel's actual DNS target
167
- value: isApexDomain ? '76.76.21.21' : 'cname.vercel-dns.com'
168
- },
169
- txt: {
170
- name: `_devdoc-verify.${customDomain}`,
171
- value: ''
172
- }
173
- };
174
- }
175
- /**
176
- * Get human-readable DNS type based on domain
177
- *
178
- * @param customDomain - The custom domain
179
- * @returns 'A' for apex domains, 'CNAME' for subdomains
180
- */ export function getDnsRecordType(customDomain) {
181
- const parts = customDomain.split('.');
182
- return parts.length <= 2 ? 'A' : 'CNAME';
183
- }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Configuration Module Exports
3
3
  */ export { docsConfigSchema, parseDocsConfig, safeParseDocsConfig, getDefaultDocsConfig } from './schema';
4
- export { domainConfigSchema, parseDomainConfig, safeParseDomainConfig, isValidDomain, normalizeDomain, getDnsInstructions, getDnsRecordType } from './domain-schema';
4
+ export { domainConfigSchema, parseDomainConfig, safeParseDomainConfig, isValidDomain, normalizeDomain } from './domain-schema';
5
5
  export { loadDocsConfig, safeLoadDocsConfig, clearConfigCache, hasDocsConfig, getContentDir, resolvePagePath, loadPageContent, listMdxFiles } from './loader';
6
6
  export { isDevMode, isProductionMode, shouldShowItem } from './environment';