cloudns-cloudformation-sync 1.3.0 → 1.5.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ClouDNS CloudFormation Sync
2
2
 
3
- Copyright (C) Clouden Oy 2020-2023, author Kenneth Falck <kennu@clouden.net>.
3
+ Copyright (C) Clouden Oy 2020-2024, author Kenneth Falck <kennu@clouden.net>.
4
4
 
5
5
  Released under the MIT license.
6
6
 
@@ -30,7 +30,7 @@ Other resource types are also allowed (A, AAAA, ALIAS, etc).
30
30
 
31
31
  Use the cloudns-cloudformation-sync command to synchronize ClouDNS records.
32
32
 
33
- AWS_PROFILE=xxx cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackname]]
33
+ AWS_PROFILE=xxx cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackname...]]
34
34
 
35
35
  Options:
36
36
 
@@ -38,6 +38,6 @@ Options:
38
38
  <cloudns-username> - ClouDNS API sub-auth-user
39
39
  <cloudns-password-parameter-name> - SSM Parameter with the encrypted ClouDNS API password
40
40
  [ttl] - Optional TTL for generated records (defaults to 300)
41
- [stackName] - Optional CloudFormation stack name to limit the exports to scan (defaults to all stacks)
41
+ [stackName...] - Optional CloudFormation stack name(s) to limit the exports to scan (defaults to all stacks)
42
42
 
43
43
  You can create your ClouDNS API credentials in the ClouDNS management console.
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.main = void 0;
3
+ exports.main = main;
4
4
  /**
5
5
  * Read AWS CloudFormation Exports and autogenerate ClouDNS records based on their names and values.
6
- * Kenneth Falck <kennu@clouden.net> (C) Clouden Oy 2020-2023
6
+ * Kenneth Falck <kennu@clouden.net> (C) Clouden Oy 2020-2024
7
7
  *
8
8
  * This tool can be used to autogenerate ClouDNS records for CloudFormation resources like
9
9
  * CloudFront distributions and API Gateway domains.
@@ -19,17 +19,16 @@ exports.main = void 0;
19
19
  *
20
20
  * Other resource types are also allowed (A, AAAA, ALIAS, etc).
21
21
  *
22
- * Command line usage: AWS_PROFILE=xxx ts-node cloudns-cloudformation-sync.ts <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName]]
22
+ * Command line usage: AWS_PROFILE=xxx ts-node cloudns-cloudformation-sync.ts <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName...]]
23
23
  *
24
24
  * AWS_PROFILE=xxx - Specify your AWS profile in ~/.aws/credentials as an environment variable
25
25
  * <cloudns-username> - ClouDNS API sub-auth-user
26
26
  * <cloudns-password-parameter-name> - SSM Parameter with the encrypted ClouDNS API password
27
27
  * [ttl] - Optional TTL for generated records (defaults to 300)
28
- * [stackName] - Optional CloudFormation stack name to limit the exports to scan (defaults to all stacks)
28
+ * [stackName...] - Optional CloudFormation stack name(s) to limit the exports to scan (defaults to all stacks)
29
29
  */
30
30
  const client_ssm_1 = require("@aws-sdk/client-ssm");
31
31
  const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
32
- const node_fetch_1 = require("node-fetch");
33
32
  const querystring = require("querystring");
34
33
  // Load ~/.aws/config
35
34
  process.env.AWS_SDK_LOAD_CONFIG = '1';
@@ -42,7 +41,7 @@ async function cloudnsRestCall(cloudnsUsername, cloudnsPassword, method, relativ
42
41
  'auth-password': cloudnsPassword,
43
42
  }, queryOptions || {}));
44
43
  // console.log('Note: Calling', fullUrl)
45
- const response = await (0, node_fetch_1.default)(fullUrl, {
44
+ const response = await fetch(fullUrl, {
46
45
  method: method,
47
46
  headers: {
48
47
  'Content-Type': 'application/json',
@@ -54,7 +53,8 @@ async function cloudnsRestCall(cloudnsUsername, cloudnsPassword, method, relativ
54
53
  console.error('HTTP Error', response.status, response.statusText, errorText);
55
54
  throw new Error(errorText);
56
55
  }
57
- return response.json();
56
+ const parsedResponse = await response.json();
57
+ return parsedResponse;
58
58
  }
59
59
  async function autoDetectCloudnsHostAndZone(cloudnsUsername, cloudnsPassword, name, zoneCache) {
60
60
  const nameParts = name.split('.');
@@ -133,17 +133,17 @@ async function createOrUpdateCloudnsResource(cloudnsUsername, cloudnsPassword, n
133
133
  }
134
134
  async function main() {
135
135
  var _a, _b, _c;
136
- console.log('ClouDNS CloudFormation Sync by Kenneth Falck <kennu@clouden.net> (C) Clouden Oy 2020-2023');
136
+ console.log('ClouDNS CloudFormation Sync by Kenneth Falck <kennu@clouden.net> (C) Clouden Oy 2020-2024');
137
137
  const cloudnsUsername = process.argv[2];
138
138
  const cloudnsPasswordParameter = process.argv[3];
139
139
  const ttlValue = process.argv[4] || '300';
140
- const stackName = process.argv[5] || '';
140
+ const stackNames = process.argv.slice(5);
141
141
  if (!cloudnsUsername) {
142
- console.error('Usage: cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName]]');
142
+ console.error('Usage: cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName...]]');
143
143
  process.exit(1);
144
144
  }
145
145
  if (!cloudnsPasswordParameter) {
146
- console.error('Usage: cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName]]');
146
+ console.error('Usage: cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName...]]');
147
147
  process.exit(1);
148
148
  }
149
149
  const ssm = new client_ssm_1.SSMClient({});
@@ -160,10 +160,10 @@ async function main() {
160
160
  NextToken: nextToken,
161
161
  }));
162
162
  for (const exportObj of response.Exports || []) {
163
- if (stackName && exportObj.ExportingStackId !== stackName) {
163
+ if (stackNames.length && !stackNames.includes(exportObj.ExportingStackId || '')) {
164
164
  // Check if the name part of the ID matches arn:aws:cloudformation:eu-west-1:<xxx>:stack/<name>/<xxx>
165
165
  const m = (_b = exportObj.ExportingStackId) === null || _b === void 0 ? void 0 : _b.match(/^arn:[^:]+:cloudformation:[^:]+:[^:]+:stack\/([^\/]+)\//);
166
- if (!m || m[1] !== stackName) {
166
+ if (!m || !stackNames.includes(m[1])) {
167
167
  // Stack ID name part didn't match given stackName, so skip it
168
168
  continue;
169
169
  }
@@ -179,5 +179,4 @@ async function main() {
179
179
  nextToken = response.NextToken;
180
180
  } while (nextToken);
181
181
  }
182
- exports.main = main;
183
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWRucy1jbG91ZGZvcm1hdGlvbi1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Nsb3VkbnMtY2xvdWRmb3JtYXRpb24tc3luYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUNILG9EQUFvRTtBQUNwRSwwRUFBNEc7QUFDNUcsMkNBQThCO0FBQzlCLDJDQUEwQztBQUUxQyxxQkFBcUI7QUFDckIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsR0FBRyxHQUFHLENBQUE7QUFFckMsS0FBSyxVQUFVLGVBQWUsQ0FBQyxlQUF1QixFQUFFLGVBQXVCLEVBQUUsTUFBYyxFQUFFLFdBQW1CLEVBQUUsWUFBaUI7SUFDckksSUFBSSxPQUFPLEdBQ1QseUJBQXlCO1FBQ3pCLFdBQVc7UUFDWCxHQUFHO1FBQ0gsV0FBVyxDQUFDLFNBQVMsQ0FDbkIsTUFBTSxDQUFDLE1BQU0sQ0FDWDtZQUNFLGVBQWUsRUFBRSxlQUFlO1lBQ2hDLGVBQWUsRUFBRSxlQUFlO1NBQ2pDLEVBQ0QsWUFBWSxJQUFJLEVBQUUsQ0FDbkIsQ0FDRixDQUFBO0lBRUgsd0NBQXdDO0lBRXhDLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBQSxvQkFBSyxFQUFDLE9BQU8sRUFBRTtRQUNwQyxNQUFNLEVBQUUsTUFBTTtRQUNkLE9BQU8sRUFBRTtZQUNQLGNBQWMsRUFBRSxrQkFBa0I7WUFDbEMsTUFBTSxFQUFFLGtCQUFrQjtTQUMzQjtLQUNGLENBQUMsQ0FBQTtJQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDakIsTUFBTSxTQUFTLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUE7UUFDdkMsT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFBO1FBQzVF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UmVhZCBBV1MgQ2xvdWRGb3JtYXRpb24gRXhwb3J0cyBhbmQgYXV0b2dlbmVyYXRlIENsb3VETlMgcmVjb3JkcyBiYXNlZCBvbiB0aGVpciBuYW1lcyBhbmQgdmFsdWVzLlxuICogS2VubmV0aCBGYWxjayA8a2VubnVAY2xvdWRlbi5uZXQ+IChDKSBDbG91ZGVuIE95IDIwMjAtMjAyM1xuICpcbiAqIFRoaXMgdG9vbCBjYW4gYmUgdXNlZCB0byBhdXRvZ2VuZXJhdGUgQ2xvdUROUyByZWNvcmRzIGZvciBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZXMgbGlrZVxuICogQ2xvdWRGcm9udCBkaXN0cmlidXRpb25zIGFuZCBBUEkgR2F0ZXdheSBkb21haW5zLlxuICpcbiAqIENsb3VkRm9ybWF0aW9uIGV4cG9ydCBuYW1lIG11c3Qgc3BlY2lmeSB0aGUgcmVzb3VyY2UgdHlwZSBhbmQgcmVjb3JkIGhvc3RuYW1lIGFzIGZvbGxvd3M6XG4gKiBDbG91RE5TOkNOQU1FOm15aG9zdDpleGFtcGxlOm9yZ1xuICpcbiAqIENsb3VkRm9ybWF0aW9uIGV4cG9ydCB2YWx1ZSBtdXN0IHNwZWNpZnkgdGhlIHJlY29yZCB2YWx1ZSBhcy1pcyAoZm9yIGluc3RhbmNlLCBhIGRpc3RyaWJ1dGlvbiBkb21haW4gbmFtZSk6XG4gKiB4eHh4eHh4eHh4eHh4eC5jbG91ZGZyb250Lm5ldFxuICpcbiAqIFRoZSBhYm92ZSBleGFtcGxlIHdpbGwgZ2VuZXJhdGUgdGhlIGZvbGxvd2luZyByZWNvcmQgaW4gdGhlIENsb3VETlMgem9uZSBleGFtcGxlLm9yZzpcbiAqIG15aG9zdC5leGFtcGxlLm9yZyBDTkFNRSB4eHh4eHh4eHh4eHh4eC5jbG91ZGZyb250Lm5ldFxuICpcbiAqIE90aGVyIHJlc291cmNlIHR5cGVzIGFyZSBhbHNvIGFsbG93ZWQgKEEsIEFBQUEsIEFMSUFTLCBldGMpLlxuICpcbiAqIENvbW1hbmQgbGluZSB1c2FnZTogQVdTX1BST0ZJTEU9eHh4IHRzLW5vZGUgY2xvdWRucy1jbG91ZGZvcm1hdGlvbi1zeW5jLnRzIDxjbG91ZG5zLXVzZXJuYW1lPiA8Y2xvdWRucy1wYXNzd29yZC1wYXJhbWV0ZXItbmFtZT4gW3R0bCBbc3RhY2tOYW1lXV1cbiAqXG4gKiBBV1NfUFJPRklMRT14eHggLSBTcGVjaWZ5IHlvdXIgQVdTIHByb2ZpbGUgaW4gfi8uYXdzL2NyZWRlbnRpYWxzIGFzIGFuIGVudmlyb25tZW50IHZhcmlhYmxlXG4gKiA8Y2xvdWRucy11c2VybmFtZT4gLSBDbG91RE5TIEFQSSBzdWItYXV0aC11c2VyXG4gKiA8Y2xvdWRucy1wYXNzd29yZC1wYXJhbWV0ZXItbmFtZT4gLSBTU00gUGFyYW1ldGVyIHdpdGggdGhlIGVuY3J5cHRlZCBDbG91RE5TIEFQSSBwYXNzd29yZFxuICogW3R0bF0gLSBPcHRpb25hbCBUVEwgZm9yIGdlbmVyYXRlZCByZWNvcmRzIChkZWZhdWx0cyB0byAzMDApXG4gKiBbc3RhY2tOYW1lXSAtIE9wdGlvbmFsIENsb3VkRm9ybWF0aW9uIHN0YWNrIG5hbWUgdG8gbGltaXQgdGhlIGV4cG9ydHMgdG8gc2NhbiAoZGVmYXVsdHMgdG8gYWxsIHN0YWNrcylcbiAqL1xuaW1wb3J0IHsgU1NNQ2xpZW50LCBHZXRQYXJhbWV0ZXJDb21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNzbSdcbmltcG9ydCB7IENsb3VkRm9ybWF0aW9uQ2xpZW50LCBMaXN0RXhwb3J0c0NvbW1hbmQsIExpc3RFeHBvcnRzT3V0cHV0IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNsb3VkZm9ybWF0aW9uJ1xuaW1wb3J0IGZldGNoIGZyb20gJ25vZGUtZmV0Y2gnXG5pbXBvcnQgKiBhcyBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZydcblxuLy8gTG9hZCB+Ly5hd3MvY29uZmlnXG5wcm9jZXNzLmVudi5BV1NfU0RLX0xPQURfQ09ORklHID0gJzEnXG5cbmFzeW5jIGZ1bmN0aW9uIGNsb3VkbnNSZXN0Q2FsbChjbG91ZG5zVXNlcm5hbWU6IHN0cmluZywgY2xvdWRuc1Bhc3N3b3JkOiBzdHJpbmcsIG1ldGhvZDogc3RyaW5nLCByZWxhdGl2ZVVybDogc3RyaW5nLCBxdWVyeU9wdGlvbnM6IGFueSkge1xuICBsZXQgZnVsbFVybCA9XG4gICAgJ2h0dHBzOi8vYXBpLmNsb3VkbnMubmV0JyArXG4gICAgcmVsYXRpdmVVcmwgK1xuICAgICc/JyArXG4gICAgcXVlcnlzdHJpbmcuc3RyaW5naWZ5KFxuICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAge1xuICAgICAgICAgICdzdWItYXV0aC11c2VyJzogY2xvdWRuc1VzZXJuYW1lLFxuICAgICAgICAgICdhdXRoLXBhc3N3b3JkJzogY2xvdWRuc1Bhc3N3b3JkLFxuICAgICAgICB9LFxuICAgICAgICBxdWVyeU9wdGlvbnMgfHwge31cbiAgICAgIClcbiAgICApXG5cbiAgLy8gY29uc29sZS5sb2coJ05vdGU6IENhbGxpbmcnLCBmdWxsVXJsKVxuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goZnVsbFVybCwge1xuICAgIG1ldGhvZDogbWV0aG9kLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICB9LFxuICB9KVxuICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgY29uc3QgZXJyb3JUZXh0ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpXG4gICAgY29uc29sZS5lcnJvcignSFRUUCBFcnJvcicsIHJlc3BvbnNlLnN0YXR1cywgcmVzcG9uc2Uuc3RhdHVzVGV4dCwgZXJyb3JUZXh0KVxuICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRleHQpXG4gIH1cbiAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKVxufVxuXG5hc3luYyBmdW5jdGlvbiBhdXRvRGV0ZWN0Q2xvdWRuc0hvc3RBbmRab25lKGNsb3VkbnNVc2VybmFtZTogc3RyaW5nLCBjbG91ZG5zUGFzc3dvcmQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCB6b25lQ2FjaGU6IGFueSkge1xuICBjb25zdCBuYW1lUGFydHMgPSBuYW1lLnNwbGl0KCcuJylcblxuICAvLyBab25lIGFuZCBob3N0IG5hbWUgZm9yIHh4eC50bGRcbiAgY29uc3QgaG9zdE5hbWUxID0gbmFtZVBhcnRzLnNsaWNlKDAsIG5hbWVQYXJ0cy5sZW5ndGggLSAyKS5qb2luKCcuJylcbiAgY29uc3Qgem9uZU5hbWUxID0gbmFtZVBhcnRzLnNsaWNlKG5hbWVQYXJ0cy5sZW5ndGggLSAyKS5qb2luKCcuJylcblxuICAvLyBab25lIGFuZCBob3N0IG5hbWUgZm9yIHh4eC5zdWJ0bGQudGxkXG4gIGNvbnN0IGhvc3ROYW1lMiA9IG5hbWVQYXJ0cy5zbGljZSgwLCBuYW1lUGFydHMubGVuZ3RoIC0gMykuam9pbignLicpXG4gIGNvbnN0IHpvbmVOYW1lMiA9IG5hbWVQYXJ0cy5zbGljZShuYW1lUGFydHMubGVuZ3RoIC0gMykuam9pbignLicpXG5cbiAgLy8gQ2hlY2sgd2hpY2ggem9uZSBleGlzdHNcbiAgY29uc3Qgem9uZVJlc3BvbnNlMSA9XG4gICAgem9uZUNhY2hlW3pvbmVOYW1lMV0gfHxcbiAgICAoYXdhaXQgY2xvdWRuc1Jlc3RDYWxsKGNsb3VkbnNVc2VybmFtZSwgY2xvdWRuc1Bhc3N3b3JkLCAnR0VUJywgJy9kbnMvZ2V0LXpvbmUtaW5mby5qc29uJywge1xuICAgICAgJ2RvbWFpbi1uYW1lJzogem9uZU5hbWUxLFxuICAgIH0pKVxuICB6b25lQ2FjaGVbem9uZU5hbWUxXSA9IHpvbmVSZXNwb25zZTFcbiAgY29uc3Qgem9uZVJlc3BvbnNlMiA9XG4gICAgem9uZUNhY2hlW3pvbmVOYW1lMl0gfHxcbiAgICAoYXdhaXQgY2xvdWRuc1Jlc3RDYWxsKGNsb3VkbnNVc2VybmFtZSwgY2xvdWRuc1Bhc3N3b3JkLCAnR0VUJywgJy9kbnMvZ2V0LXpvbmUtaW5mby5qc29uJywge1xuICAgICAgJ2RvbWFpbi1uYW1lJzogem9uZU5hbWUyLFxuICAgIH0pKVxuICB6b25lQ2FjaGVbem9uZU5hbWUyXSA9IHpvbmVSZXNwb25zZTJcblxuICAvLyBjb25zb2xlLmxvZygnTm90ZTogUmVzcG9uc2UgZm9yIGhvc3QnLCBob3N0TmFtZTEsICdpbiB6b25lJywgem9uZU5hbWUxLCAnOicsIHpvbmVSZXNwb25zZTEpXG4gIC8vIGNvbnNvbGUubG9nKCdOb3RlOiBSZXNwb25zZSBmb3IgaG9zdCcsIGhvc3ROYW1lMiwgJ2luIHpvbmUnLCB6b25lTmFtZTIsICc6Jywgem9uZVJlc3BvbnNlMilcblxuICBjb25zdCB6b25lTmFtZSA9IHpvbmVSZXNwb25zZTEuc3RhdHVzID09PSAnMScgPyB6b25lTmFtZTEgOiB6b25lUmVzcG9uc2UyLnN0YXR1cyA9PT0gJzEnID8gem9uZU5hbWUyIDogJydcbiAgY29uc3QgaG9zdE5hbWUgPSB6b25lUmVzcG9uc2UxLnN0YXR1cyA9PT0gJzEnID8gaG9zdE5hbWUxIDogem9uZVJlc3BvbnNlMi5zdGF0dXMgPT09ICcxJyA/IGhvc3ROYW1lMiA6ICcnXG4gIGlmICghem9uZU5hbWUpIHtcbiAgICAvLyBOZWl0aGVyIHpvbmUgZXhpc3RzXG4gICAgdGhyb3cgbmV3IEVycm9yKCdab25lIE5vdCBGb3VuZDogJyArIG5hbWUpXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBob3N0TmFtZTogaG9zdE5hbWUsXG4gICAgem9uZU5hbWU6IHpvbmVOYW1lLFxuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlQ2xvdWRuc1Jlc291cmNlKFxuICBjbG91ZG5zVXNlcm5hbWU6IHN0cmluZyxcbiAgY2xvdWRuc1Bhc3N3b3JkOiBzdHJpbmcsXG4gIG5hbWU6IHN0cmluZyxcbiAgdHlwZTogc3RyaW5nLFxuICB2YWx1ZTogc3RyaW5nLFxuICB0dGxWYWx1ZTogc3RyaW5nLFxuICB6b25lQ2FjaGU6IGFueVxuKSB7XG4gIGNvbnN0IHsgem9uZU5hbWUsIGhvc3ROYW1lIH0gPSBhd2FpdCBhdXRvRGV0ZWN0Q2xvdWRuc0hvc3RBbmRab25lKGNsb3VkbnNVc2VybmFtZSwgY2xvdWRuc1Bhc3N3b3JkLCBuYW1lLCB6b25lQ2FjaGUpXG4gIC8vIERvZXMgdGhlIHJlY29yZCBleGlzdD9cbiAgY29uc3QgcmVjb3Jkc1Jlc3BvbnNlID0gYXdhaXQgY2xvdWRuc1Jlc3RDYWxsKGNsb3VkbnNVc2VybmFtZSwgY2xvdWRuc1Bhc3N3b3JkLCAnR0VUJywgJy9kbnMvcmVjb3Jkcy5qc29uJywge1xuICAgICdkb21haW4tbmFtZSc6IHpvbmVOYW1lLFxuICAgIGhvc3Q6IGhvc3ROYW1lLFxuICAgIHR5cGU6IHR5cGUsXG4gIH0pXG4gIGNvbnN0IGV4aXN0aW5nUmVjb3JkOiBhbnkgPSBPYmplY3QudmFsdWVzKHJlY29yZHNSZXNwb25zZSlbMF1cbiAgaWYgKGV4aXN0aW5nUmVjb3JkPy5ob3N0ID09PSBob3N0TmFtZSAmJiBleGlzdGluZ1JlY29yZD8udHlwZSA9PT0gdHlwZSAmJiBleGlzdGluZ1JlY29yZD8udHRsID09PSB0dGxWYWx1ZSAmJiBleGlzdGluZ1JlY29yZD8ucmVjb3JkID09PSB2YWx1ZSkge1xuICAgIC8vIFJlY29yZCBleGlzdHMgYWxyZWFkeSAtIG5vIGNoYW5nZVxuICAgIGNvbnNvbGUubG9nKCdPSycsIG5hbWUsIHR5cGUsIHR0bFZhbHVlLCB2YWx1ZSwgJ1pPTkUnLCB6b25lTmFtZSwgJ0hPU1QnLCBob3N0TmFtZSlcbiAgfSBlbHNlIGlmIChleGlzdGluZ1JlY29yZD8uaWQpIHtcbiAgICAvLyBVcGRhdGUgcmVjb3JkXG4gICAgY29uc29sZS5sb2coJ1VQREFURScsIG5hbWUsIHR5cGUsIHR0bFZhbHVlLCB2YWx1ZSwgJ1pPTkUnLCB6b25lTmFtZSwgJ0hPU1QnLCBob3N0TmFtZSlcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjbG91ZG5zUmVzdENhbGwoY2xvdWRuc1VzZXJuYW1lLCBjbG91ZG5zUGFzc3dvcmQsICdQT1NUJywgJy9kbnMvbW9kLXJlY29yZC5qc29uJywge1xuICAgICAgJ2RvbWFpbi1uYW1lJzogem9uZU5hbWUsXG4gICAgICAncmVjb3JkLWlkJzogZXhpc3RpbmdSZWNvcmQ/LmlkLFxuICAgICAgaG9zdDogaG9zdE5hbWUsXG4gICAgICAncmVjb3JkLXR5cGUnOiB0eXBlLFxuICAgICAgcmVjb3JkOiB2YWx1ZSxcbiAgICAgIHR0bDogdHRsVmFsdWUsXG4gICAgfSlcbiAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gJ0ZhaWxlZCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTW9kaWZ5IHJlY29yZCBmYWlsZWQ6ICcgKyAocmVzdWx0LnN0YXR1c01lc3NhZ2UgfHwgcmVzdWx0LnN0YXR1c0Rlc2NyaXB0aW9uKSlcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gQ3JlYXRlIHJlY29yZFxuICAgIGNvbnNvbGUubG9nKCdDUkVBVEUnLCBuYW1lLCB0eXBlLCB0dGxWYWx1ZSwgdmFsdWUsICdaT05FJywgem9uZU5hbWUsICdIT1NUJywgaG9zdE5hbWUpXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY2xvdWRuc1Jlc3RDYWxsKGNsb3VkbnNVc2VybmFtZSwgY2xvdWRuc1Bhc3N3b3JkLCAnUE9TVCcsICcvZG5zL2FkZC1yZWNvcmQuanNvbicsIHtcbiAgICAgICdkb21haW4tbmFtZSc6IHpvbmVOYW1lLFxuICAgICAgaG9zdDogaG9zdE5hbWUsXG4gICAgICAncmVjb3JkLXR5cGUnOiB0eXBlLFxuICAgICAgcmVjb3JkOiB2YWx1ZSxcbiAgICAgIHR0bDogdHRsVmFsdWUsXG4gICAgfSlcbiAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gJ0ZhaWxlZCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWRkIHJlY29yZCBmYWlsZWQ6ICcgKyAocmVzdWx0LnN0YXR1c01lc3NhZ2UgfHwgcmVzdWx0LnN0YXR1c0Rlc2NyaXB0aW9uKSlcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gIGNvbnNvbGUubG9nKCdDbG91RE5TIENsb3VkRm9ybWF0aW9uIFN5bmMgYnkgS2VubmV0aCBGYWxjayA8a2VubnVAY2xvdWRlbi5uZXQ+IChDKSBDbG91ZGVuIE95IDIwMjAtMjAyMycpXG4gIGNvbnN0IGNsb3VkbnNVc2VybmFtZSA9IHByb2Nlc3MuYXJndlsyXVxuICBjb25zdCBjbG91ZG5zUGFzc3dvcmRQYXJhbWV0ZXIgPSBwcm9jZXNzLmFyZ3ZbM11cbiAgY29uc3QgdHRsVmFsdWUgPSBwcm9jZXNzLmFyZ3ZbNF0gfHwgJzMwMCdcbiAgY29uc3Qgc3RhY2tOYW1lID0gcHJvY2Vzcy5hcmd2WzVdIHx8ICcnXG4gIGlmICghY2xvdWRuc1VzZXJuYW1lKSB7XG4gICAgY29uc29sZS5lcnJvcignVXNhZ2U6IGNsb3VkbnMtY2xvdWRmb3JtYXRpb24tc3luYyA8Y2xvdWRucy11c2VybmFtZT4gPGNsb3VkbnMtcGFzc3dvcmQtcGFyYW1ldGVyLW5hbWU+IFt0dGwgW3N0YWNrTmFtZV1dJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBpZiAoIWNsb3VkbnNQYXNzd29yZFBhcmFtZXRlcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1VzYWdlOiBjbG91ZG5zLWNsb3VkZm9ybWF0aW9uLXN5bmMgPGNsb3VkbnMtdXNlcm5hbWU+IDxjbG91ZG5zLXBhc3N3b3JkLXBhcmFtZXRlci1uYW1lPiBbdHRsIFtzdGFja05hbWVdXScpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cblxuICBjb25zdCBzc20gPSBuZXcgU1NNQ2xpZW50KHt9KVxuICBjb25zdCB6b25lQ2FjaGUgPSB7fVxuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc3NtLnNlbmQoXG4gICAgbmV3IEdldFBhcmFtZXRlckNvbW1hbmQoe1xuICAgICAgTmFtZTogY2xvdWRuc1Bhc3N3b3JkUGFyYW1ldGVyLFxuICAgICAgV2l0aERlY3J5cHRpb246IHRydWUsXG4gICAgfSlcbiAgKVxuICBjb25zdCBjbG91ZG5zUGFzc3dvcmQgPSByZXNwb25zZS5QYXJhbWV0ZXI/LlZhbHVlIHx8ICcnXG5cbiAgY29uc3QgY2xvdWRGb3JtYXRpb24gPSBuZXcgQ2xvdWRGb3JtYXRpb25DbGllbnQoe30pXG4gIGxldCBuZXh0VG9rZW5cbiAgZG8ge1xuICAgIGNvbnN0IHJlc3BvbnNlOiBMaXN0RXhwb3J0c091dHB1dCA9IGF3YWl0IGNsb3VkRm9ybWF0aW9uLnNlbmQoXG4gICAgICBuZXcgTGlzdEV4cG9ydHNDb21tYW5kKHtcbiAgICAgICAgTmV4dFRva2VuOiBuZXh0VG9rZW4sXG4gICAgICB9KVxuICAgIClcbiAgICBmb3IgKGNvbnN0IGV4cG9ydE9iaiBvZiByZXNwb25zZS5FeHBvcnRzIHx8IFtdKSB7XG4gICAgICBpZiAoc3RhY2tOYW1lICYmIGV4cG9ydE9iai5FeHBvcnRpbmdTdGFja0lkICE9PSBzdGFja05hbWUpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG5hbWUgcGFydCBvZiB0aGUgSUQgbWF0Y2hlcyBhcm46YXdzOmNsb3VkZm9ybWF0aW9uOmV1LXdlc3QtMTo8eHh4PjpzdGFjay88bmFtZT4vPHh4eD5cbiAgICAgICAgY29uc3QgbSA9IGV4cG9ydE9iai5FeHBvcnRpbmdTdGFja0lkPy5tYXRjaCgvXmFybjpbXjpdKzpjbG91ZGZvcm1hdGlvbjpbXjpdKzpbXjpdKzpzdGFja1xcLyhbXlxcL10rKVxcLy8pXG4gICAgICAgIGlmICghbSB8fCBtWzFdICE9PSBzdGFja05hbWUpIHtcbiAgICAgICAgICAvLyBTdGFjayBJRCBuYW1lIHBhcnQgZGlkbid0IG1hdGNoIGdpdmVuIHN0YWNrTmFtZSwgc28gc2tpcCBpdFxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChleHBvcnRPYmouTmFtZT8ubWF0Y2goL15DbG91RE5TOi8pKSB7XG4gICAgICAgIGNvbnN0IG5hbWVQYXJ0cyA9IGV4cG9ydE9iai5OYW1lLnNwbGl0KCc6JylcbiAgICAgICAgY29uc3QgcmVzb3VyY2VUeXBlID0gbmFtZVBhcnRzWzFdXG4gICAgICAgIGNvbnN0IHJlc291cmNlTmFtZSA9IG5hbWVQYXJ0cy5zbGljZSgyKS5qb2luKCcuJylcbiAgICAgICAgY29uc3QgcmVzb3VyY2VWYWx1ZSA9IGV4cG9ydE9iai5WYWx1ZSFcbiAgICAgICAgYXdhaXQgY3JlYXRlT3JVcGRhdGVDbG91ZG5zUmVzb3VyY2UoY2xvdWRuc1VzZXJuYW1lLCBjbG91ZG5zUGFzc3dvcmQsIHJlc291cmNlTmFtZSwgcmVzb3VyY2VUeXBlLCByZXNvdXJjZVZhbHVlLCB0dGxWYWx1ZSwgem9uZUNhY2hlKVxuICAgICAgfVxuICAgIH1cbiAgICBuZXh0VG9rZW4gPSByZXNwb25zZS5OZXh0VG9rZW5cbiAgfSB3aGlsZSAobmV4dFRva2VuKVxufVxuIl19
182
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWRucy1jbG91ZGZvcm1hdGlvbi1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Nsb3VkbnMtY2xvdWRmb3JtYXRpb24tc3luYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQThKQSxvQkFxREM7QUFuTkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5Qkc7QUFDSCxvREFBb0U7QUFDcEUsMEVBQTRHO0FBQzVHLDJDQUEwQztBQUUxQyxxQkFBcUI7QUFDckIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsR0FBRyxHQUFHLENBQUE7QUFJckMsS0FBSyxVQUFVLGVBQWUsQ0FBQyxlQUF1QixFQUFFLGVBQXVCLEVBQUUsTUFBYyxFQUFFLFdBQW1CLEVBQUUsWUFBaUI7SUFDckksSUFBSSxPQUFPLEdBQ1QseUJBQXlCO1FBQ3pCLFdBQVc7UUFDWCxHQUFHO1FBQ0gsV0FBVyxDQUFDLFNBQVMsQ0FDbkIsTUFBTSxDQUFDLE1BQU0sQ0FDWDtZQUNFLGVBQWUsRUFBRSxlQUFlO1lBQ2hDLGVBQWUsRUFBRSxlQUFlO1NBQ2pDLEVBQ0QsWUFBWSxJQUFJLEVBQUUsQ0FDbkIsQ0FDRixDQUFBO0lBRUgsd0NBQXdDO0lBRXhDLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sRUFBRTtRQUNwQyxNQUFNLEVBQUUsTUFBTTtRQUNkLE9BQU8sRUFBRTtZQUNQLGNBQWMsRUFBRSxrQkFBa0I7WUFDbEMsTUFBTSxFQUFFLGtCQUFrQjtTQUMzQjtLQUNGLENBQUMsQ0FBQTtJQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDakIsTUFBTSxTQUFTLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUE7UUFDdkMsT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFBO1FBQzVFLE1BQU0s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QUMsU0FBUyxDQUFBO0lBQ2hDLENBQUMsUUFBUSxTQUFTLEVBQUM7QUFDckIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmVhZCBBV1MgQ2xvdWRGb3JtYXRpb24gRXhwb3J0cyBhbmQgYXV0b2dlbmVyYXRlIENsb3VETlMgcmVjb3JkcyBiYXNlZCBvbiB0aGVpciBuYW1lcyBhbmQgdmFsdWVzLlxuICogS2VubmV0aCBGYWxjayA8a2VubnVAY2xvdWRlbi5uZXQ+IChDKSBDbG91ZGVuIE95IDIwMjAtMjAyNFxuICpcbiAqIFRoaXMgdG9vbCBjYW4gYmUgdXNlZCB0byBhdXRvZ2VuZXJhdGUgQ2xvdUROUyByZWNvcmRzIGZvciBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZXMgbGlrZVxuICogQ2xvdWRGcm9udCBkaXN0cmlidXRpb25zIGFuZCBBUEkgR2F0ZXdheSBkb21haW5zLlxuICpcbiAqIENsb3VkRm9ybWF0aW9uIGV4cG9ydCBuYW1lIG11c3Qgc3BlY2lmeSB0aGUgcmVzb3VyY2UgdHlwZSBhbmQgcmVjb3JkIGhvc3RuYW1lIGFzIGZvbGxvd3M6XG4gKiBDbG91RE5TOkNOQU1FOm15aG9zdDpleGFtcGxlOm9yZ1xuICpcbiAqIENsb3VkRm9ybWF0aW9uIGV4cG9ydCB2YWx1ZSBtdXN0IHNwZWNpZnkgdGhlIHJlY29yZCB2YWx1ZSBhcy1pcyAoZm9yIGluc3RhbmNlLCBhIGRpc3RyaWJ1dGlvbiBkb21haW4gbmFtZSk6XG4gKiB4eHh4eHh4eHh4eHh4eC5jbG91ZGZyb250Lm5ldFxuICpcbiAqIFRoZSBhYm92ZSBleGFtcGxlIHdpbGwgZ2VuZXJhdGUgdGhlIGZvbGxvd2luZyByZWNvcmQgaW4gdGhlIENsb3VETlMgem9uZSBleGFtcGxlLm9yZzpcbiAqIG15aG9zdC5leGFtcGxlLm9yZyBDTkFNRSB4eHh4eHh4eHh4eHh4eC5jbG91ZGZyb250Lm5ldFxuICpcbiAqIE90aGVyIHJlc291cmNlIHR5cGVzIGFyZSBhbHNvIGFsbG93ZWQgKEEsIEFBQUEsIEFMSUFTLCBldGMpLlxuICpcbiAqIENvbW1hbmQgbGluZSB1c2FnZTogQVdTX1BST0ZJTEU9eHh4IHRzLW5vZGUgY2xvdWRucy1jbG91ZGZvcm1hdGlvbi1zeW5jLnRzIDxjbG91ZG5zLXVzZXJuYW1lPiA8Y2xvdWRucy1wYXNzd29yZC1wYXJhbWV0ZXItbmFtZT4gW3R0bCBbc3RhY2tOYW1lLi4uXV1cbiAqXG4gKiBBV1NfUFJPRklMRT14eHggLSBTcGVjaWZ5IHlvdXIgQVdTIHByb2ZpbGUgaW4gfi8uYXdzL2NyZWRlbnRpYWxzIGFzIGFuIGVudmlyb25tZW50IHZhcmlhYmxlXG4gKiA8Y2xvdWRucy11c2VybmFtZT4gLSBDbG91RE5TIEFQSSBzdWItYXV0aC11c2VyXG4gKiA8Y2xvdWRucy1wYXNzd29yZC1wYXJhbWV0ZXItbmFtZT4gLSBTU00gUGFyYW1ldGVyIHdpdGggdGhlIGVuY3J5cHRlZCBDbG91RE5TIEFQSSBwYXNzd29yZFxuICogW3R0bF0gLSBPcHRpb25hbCBUVEwgZm9yIGdlbmVyYXRlZCByZWNvcmRzIChkZWZhdWx0cyB0byAzMDApXG4gKiBbc3RhY2tOYW1lLi4uXSAtIE9wdGlvbmFsIENsb3VkRm9ybWF0aW9uIHN0YWNrIG5hbWUocykgdG8gbGltaXQgdGhlIGV4cG9ydHMgdG8gc2NhbiAoZGVmYXVsdHMgdG8gYWxsIHN0YWNrcylcbiAqL1xuaW1wb3J0IHsgU1NNQ2xpZW50LCBHZXRQYXJhbWV0ZXJDb21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNzbSdcbmltcG9ydCB7IENsb3VkRm9ybWF0aW9uQ2xpZW50LCBMaXN0RXhwb3J0c0NvbW1hbmQsIExpc3RFeHBvcnRzT3V0cHV0IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNsb3VkZm9ybWF0aW9uJ1xuaW1wb3J0ICogYXMgcXVlcnlzdHJpbmcgZnJvbSAncXVlcnlzdHJpbmcnXG5cbi8vIExvYWQgfi8uYXdzL2NvbmZpZ1xucHJvY2Vzcy5lbnYuQVdTX1NES19MT0FEX0NPTkZJRyA9ICcxJ1xuXG50eXBlIENsb3VkbnNSZXN0Q2FsbFJlc3BvbnNlID0gYW55XG5cbmFzeW5jIGZ1bmN0aW9uIGNsb3VkbnNSZXN0Q2FsbChjbG91ZG5zVXNlcm5hbWU6IHN0cmluZywgY2xvdWRuc1Bhc3N3b3JkOiBzdHJpbmcsIG1ldGhvZDogc3RyaW5nLCByZWxhdGl2ZVVybDogc3RyaW5nLCBxdWVyeU9wdGlvbnM6IGFueSk6IFByb21pc2U8Q2xvdWRuc1Jlc3RDYWxsUmVzcG9uc2U+IHtcbiAgbGV0IGZ1bGxVcmwgPVxuICAgICdodHRwczovL2FwaS5jbG91ZG5zLm5ldCcgK1xuICAgIHJlbGF0aXZlVXJsICtcbiAgICAnPycgK1xuICAgIHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShcbiAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgIHtcbiAgICAgICAgICAnc3ViLWF1dGgtdXNlcic6IGNsb3VkbnNVc2VybmFtZSxcbiAgICAgICAgICAnYXV0aC1wYXNzd29yZCc6IGNsb3VkbnNQYXNzd29yZCxcbiAgICAgICAgfSxcbiAgICAgICAgcXVlcnlPcHRpb25zIHx8IHt9XG4gICAgICApXG4gICAgKVxuXG4gIC8vIGNvbnNvbGUubG9nKCdOb3RlOiBDYWxsaW5nJywgZnVsbFVybClcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGZ1bGxVcmwsIHtcbiAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICBoZWFkZXJzOiB7XG4gICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgQWNjZXB0OiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgfSxcbiAgfSlcbiAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgIGNvbnN0IGVycm9yVGV4dCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKVxuICAgIGNvbnNvbGUuZXJyb3IoJ0hUVFAgRXJyb3InLCByZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlLnN0YXR1c1RleHQsIGVycm9yVGV4dClcbiAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUZXh0KVxuICB9XG4gIGNvbnN0IHBhcnNlZFJlc3BvbnNlOiBDbG91ZG5zUmVzdENhbGxSZXNwb25zZSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKVxuICByZXR1cm4gcGFyc2VkUmVzcG9uc2Vcbn1cblxuYXN5bmMgZnVuY3Rpb24gYXV0b0RldGVjdENsb3VkbnNIb3N0QW5kWm9uZShjbG91ZG5zVXNlcm5hbWU6IHN0cmluZywgY2xvdWRuc1Bhc3N3b3JkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgem9uZUNhY2hlOiBhbnkpIHtcbiAgY29uc3QgbmFtZVBhcnRzID0gbmFtZS5zcGxpdCgnLicpXG5cbiAgLy8gWm9uZSBhbmQgaG9zdCBuYW1lIGZvciB4eHgudGxkXG4gIGNvbnN0IGhvc3ROYW1lMSA9IG5hbWVQYXJ0cy5zbGljZSgwLCBuYW1lUGFydHMubGVuZ3RoIC0gMikuam9pbignLicpXG4gIGNvbnN0IHpvbmVOYW1lMSA9IG5hbWVQYXJ0cy5zbGljZShuYW1lUGFydHMubGVuZ3RoIC0gMikuam9pbignLicpXG5cbiAgLy8gWm9uZSBhbmQgaG9zdCBuYW1lIGZvciB4eHguc3VidGxkLnRsZFxuICBjb25zdCBob3N0TmFtZTIgPSBuYW1lUGFydHMuc2xpY2UoMCwgbmFtZVBhcnRzLmxlbmd0aCAtIDMpLmpvaW4oJy4nKVxuICBjb25zdCB6b25lTmFtZTIgPSBuYW1lUGFydHMuc2xpY2UobmFtZVBhcnRzLmxlbmd0aCAtIDMpLmpvaW4oJy4nKVxuXG4gIC8vIENoZWNrIHdoaWNoIHpvbmUgZXhpc3RzXG4gIGNvbnN0IHpvbmVSZXNwb25zZTEgPVxuICAgIHpvbmVDYWNoZVt6b25lTmFtZTFdIHx8XG4gICAgKGF3YWl0IGNsb3VkbnNSZXN0Q2FsbChjbG91ZG5zVXNlcm5hbWUsIGNsb3VkbnNQYXNzd29yZCwgJ0dFVCcsICcvZG5zL2dldC16b25lLWluZm8uanNvbicsIHtcbiAgICAgICdkb21haW4tbmFtZSc6IHpvbmVOYW1lMSxcbiAgICB9KSlcbiAgem9uZUNhY2hlW3pvbmVOYW1lMV0gPSB6b25lUmVzcG9uc2UxXG4gIGNvbnN0IHpvbmVSZXNwb25zZTIgPVxuICAgIHpvbmVDYWNoZVt6b25lTmFtZTJdIHx8XG4gICAgKGF3YWl0IGNsb3VkbnNSZXN0Q2FsbChjbG91ZG5zVXNlcm5hbWUsIGNsb3VkbnNQYXNzd29yZCwgJ0dFVCcsICcvZG5zL2dldC16b25lLWluZm8uanNvbicsIHtcbiAgICAgICdkb21haW4tbmFtZSc6IHpvbmVOYW1lMixcbiAgICB9KSlcbiAgem9uZUNhY2hlW3pvbmVOYW1lMl0gPSB6b25lUmVzcG9uc2UyXG5cbiAgLy8gY29uc29sZS5sb2coJ05vdGU6IFJlc3BvbnNlIGZvciBob3N0JywgaG9zdE5hbWUxLCAnaW4gem9uZScsIHpvbmVOYW1lMSwgJzonLCB6b25lUmVzcG9uc2UxKVxuICAvLyBjb25zb2xlLmxvZygnTm90ZTogUmVzcG9uc2UgZm9yIGhvc3QnLCBob3N0TmFtZTIsICdpbiB6b25lJywgem9uZU5hbWUyLCAnOicsIHpvbmVSZXNwb25zZTIpXG5cbiAgY29uc3Qgem9uZU5hbWUgPSB6b25lUmVzcG9uc2UxLnN0YXR1cyA9PT0gJzEnID8gem9uZU5hbWUxIDogem9uZVJlc3BvbnNlMi5zdGF0dXMgPT09ICcxJyA/IHpvbmVOYW1lMiA6ICcnXG4gIGNvbnN0IGhvc3ROYW1lID0gem9uZVJlc3BvbnNlMS5zdGF0dXMgPT09ICcxJyA/IGhvc3ROYW1lMSA6IHpvbmVSZXNwb25zZTIuc3RhdHVzID09PSAnMScgPyBob3N0TmFtZTIgOiAnJ1xuICBpZiAoIXpvbmVOYW1lKSB7XG4gICAgLy8gTmVpdGhlciB6b25lIGV4aXN0c1xuICAgIHRocm93IG5ldyBFcnJvcignWm9uZSBOb3QgRm91bmQ6ICcgKyBuYW1lKVxuICB9XG4gIHJldHVybiB7XG4gICAgaG9zdE5hbWU6IGhvc3ROYW1lLFxuICAgIHpvbmVOYW1lOiB6b25lTmFtZSxcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVPclVwZGF0ZUNsb3VkbnNSZXNvdXJjZShcbiAgY2xvdWRuc1VzZXJuYW1lOiBzdHJpbmcsXG4gIGNsb3VkbnNQYXNzd29yZDogc3RyaW5nLFxuICBuYW1lOiBzdHJpbmcsXG4gIHR5cGU6IHN0cmluZyxcbiAgdmFsdWU6IHN0cmluZyxcbiAgdHRsVmFsdWU6IHN0cmluZyxcbiAgem9uZUNhY2hlOiBhbnlcbikge1xuICBjb25zdCB7IHpvbmVOYW1lLCBob3N0TmFtZSB9ID0gYXdhaXQgYXV0b0RldGVjdENsb3VkbnNIb3N0QW5kWm9uZShjbG91ZG5zVXNlcm5hbWUsIGNsb3VkbnNQYXNzd29yZCwgbmFtZSwgem9uZUNhY2hlKVxuICAvLyBEb2VzIHRoZSByZWNvcmQgZXhpc3Q/XG4gIGNvbnN0IHJlY29yZHNSZXNwb25zZSA9IGF3YWl0IGNsb3VkbnNSZXN0Q2FsbChjbG91ZG5zVXNlcm5hbWUsIGNsb3VkbnNQYXNzd29yZCwgJ0dFVCcsICcvZG5zL3JlY29yZHMuanNvbicsIHtcbiAgICAnZG9tYWluLW5hbWUnOiB6b25lTmFtZSxcbiAgICBob3N0OiBob3N0TmFtZSxcbiAgICB0eXBlOiB0eXBlLFxuICB9KVxuICBjb25zdCBleGlzdGluZ1JlY29yZDogYW55ID0gT2JqZWN0LnZhbHVlcyhyZWNvcmRzUmVzcG9uc2UpWzBdXG4gIGlmIChleGlzdGluZ1JlY29yZD8uaG9zdCA9PT0gaG9zdE5hbWUgJiYgZXhpc3RpbmdSZWNvcmQ/LnR5cGUgPT09IHR5cGUgJiYgZXhpc3RpbmdSZWNvcmQ/LnR0bCA9PT0gdHRsVmFsdWUgJiYgZXhpc3RpbmdSZWNvcmQ/LnJlY29yZCA9PT0gdmFsdWUpIHtcbiAgICAvLyBSZWNvcmQgZXhpc3RzIGFscmVhZHkgLSBubyBjaGFuZ2VcbiAgICBjb25zb2xlLmxvZygnT0snLCBuYW1lLCB0eXBlLCB0dGxWYWx1ZSwgdmFsdWUsICdaT05FJywgem9uZU5hbWUsICdIT1NUJywgaG9zdE5hbWUpXG4gIH0gZWxzZSBpZiAoZXhpc3RpbmdSZWNvcmQ/LmlkKSB7XG4gICAgLy8gVXBkYXRlIHJlY29yZFxuICAgIGNvbnNvbGUubG9nKCdVUERBVEUnLCBuYW1lLCB0eXBlLCB0dGxWYWx1ZSwgdmFsdWUsICdaT05FJywgem9uZU5hbWUsICdIT1NUJywgaG9zdE5hbWUpXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY2xvdWRuc1Jlc3RDYWxsKGNsb3VkbnNVc2VybmFtZSwgY2xvdWRuc1Bhc3N3b3JkLCAnUE9TVCcsICcvZG5zL21vZC1yZWNvcmQuanNvbicsIHtcbiAgICAgICdkb21haW4tbmFtZSc6IHpvbmVOYW1lLFxuICAgICAgJ3JlY29yZC1pZCc6IGV4aXN0aW5nUmVjb3JkPy5pZCxcbiAgICAgIGhvc3Q6IGhvc3ROYW1lLFxuICAgICAgJ3JlY29yZC10eXBlJzogdHlwZSxcbiAgICAgIHJlY29yZDogdmFsdWUsXG4gICAgICB0dGw6IHR0bFZhbHVlLFxuICAgIH0pXG4gICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICdGYWlsZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vZGlmeSByZWNvcmQgZmFpbGVkOiAnICsgKHJlc3VsdC5zdGF0dXNNZXNzYWdlIHx8IHJlc3VsdC5zdGF0dXNEZXNjcmlwdGlvbikpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIENyZWF0ZSByZWNvcmRcbiAgICBjb25zb2xlLmxvZygnQ1JFQVRFJywgbmFtZSwgdHlwZSwgdHRsVmFsdWUsIHZhbHVlLCAnWk9ORScsIHpvbmVOYW1lLCAnSE9TVCcsIGhvc3ROYW1lKVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNsb3VkbnNSZXN0Q2FsbChjbG91ZG5zVXNlcm5hbWUsIGNsb3VkbnNQYXNzd29yZCwgJ1BPU1QnLCAnL2Rucy9hZGQtcmVjb3JkLmpzb24nLCB7XG4gICAgICAnZG9tYWluLW5hbWUnOiB6b25lTmFtZSxcbiAgICAgIGhvc3Q6IGhvc3ROYW1lLFxuICAgICAgJ3JlY29yZC10eXBlJzogdHlwZSxcbiAgICAgIHJlY29yZDogdmFsdWUsXG4gICAgICB0dGw6IHR0bFZhbHVlLFxuICAgIH0pXG4gICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICdGYWlsZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FkZCByZWNvcmQgZmFpbGVkOiAnICsgKHJlc3VsdC5zdGF0dXNNZXNzYWdlIHx8IHJlc3VsdC5zdGF0dXNEZXNjcmlwdGlvbikpXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtYWluKCkge1xuICBjb25zb2xlLmxvZygnQ2xvdUROUyBDbG91ZEZvcm1hdGlvbiBTeW5jIGJ5IEtlbm5ldGggRmFsY2sgPGtlbm51QGNsb3VkZW4ubmV0PiAoQykgQ2xvdWRlbiBPeSAyMDIwLTIwMjQnKVxuICBjb25zdCBjbG91ZG5zVXNlcm5hbWUgPSBwcm9jZXNzLmFyZ3ZbMl1cbiAgY29uc3QgY2xvdWRuc1Bhc3N3b3JkUGFyYW1ldGVyID0gcHJvY2Vzcy5hcmd2WzNdXG4gIGNvbnN0IHR0bFZhbHVlID0gcHJvY2Vzcy5hcmd2WzRdIHx8ICczMDAnXG4gIGNvbnN0IHN0YWNrTmFtZXMgPSBwcm9jZXNzLmFyZ3Yuc2xpY2UoNSlcbiAgaWYgKCFjbG91ZG5zVXNlcm5hbWUpIHtcbiAgICBjb25zb2xlLmVycm9yKCdVc2FnZTogY2xvdWRucy1jbG91ZGZvcm1hdGlvbi1zeW5jIDxjbG91ZG5zLXVzZXJuYW1lPiA8Y2xvdWRucy1wYXNzd29yZC1wYXJhbWV0ZXItbmFtZT4gW3R0bCBbc3RhY2tOYW1lLi4uXV0nKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIGlmICghY2xvdWRuc1Bhc3N3b3JkUGFyYW1ldGVyKSB7XG4gICAgY29uc29sZS5lcnJvcignVXNhZ2U6IGNsb3VkbnMtY2xvdWRmb3JtYXRpb24tc3luYyA8Y2xvdWRucy11c2VybmFtZT4gPGNsb3VkbnMtcGFzc3dvcmQtcGFyYW1ldGVyLW5hbWU+IFt0dGwgW3N0YWNrTmFtZS4uLl1dJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuXG4gIGNvbnN0IHNzbSA9IG5ldyBTU01DbGllbnQoe30pXG4gIGNvbnN0IHpvbmVDYWNoZSA9IHt9XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzc20uc2VuZChcbiAgICBuZXcgR2V0UGFyYW1ldGVyQ29tbWFuZCh7XG4gICAgICBOYW1lOiBjbG91ZG5zUGFzc3dvcmRQYXJhbWV0ZXIsXG4gICAgICBXaXRoRGVjcnlwdGlvbjogdHJ1ZSxcbiAgICB9KVxuICApXG4gIGNvbnN0IGNsb3VkbnNQYXNzd29yZCA9IHJlc3BvbnNlLlBhcmFtZXRlcj8uVmFsdWUgfHwgJydcblxuICBjb25zdCBjbG91ZEZvcm1hdGlvbiA9IG5ldyBDbG91ZEZvcm1hdGlvbkNsaWVudCh7fSlcbiAgbGV0IG5leHRUb2tlblxuICBkbyB7XG4gICAgY29uc3QgcmVzcG9uc2U6IExpc3RFeHBvcnRzT3V0cHV0ID0gYXdhaXQgY2xvdWRGb3JtYXRpb24uc2VuZChcbiAgICAgIG5ldyBMaXN0RXhwb3J0c0NvbW1hbmQoe1xuICAgICAgICBOZXh0VG9rZW46IG5leHRUb2tlbixcbiAgICAgIH0pXG4gICAgKVxuICAgIGZvciAoY29uc3QgZXhwb3J0T2JqIG9mIHJlc3BvbnNlLkV4cG9ydHMgfHwgW10pIHtcbiAgICAgIGlmIChzdGFja05hbWVzLmxlbmd0aCAmJiAhc3RhY2tOYW1lcy5pbmNsdWRlcyhleHBvcnRPYmouRXhwb3J0aW5nU3RhY2tJZCB8fCAnJykpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG5hbWUgcGFydCBvZiB0aGUgSUQgbWF0Y2hlcyBhcm46YXdzOmNsb3VkZm9ybWF0aW9uOmV1LXdlc3QtMTo8eHh4PjpzdGFjay88bmFtZT4vPHh4eD5cbiAgICAgICAgY29uc3QgbSA9IGV4cG9ydE9iai5FeHBvcnRpbmdTdGFja0lkPy5tYXRjaCgvXmFybjpbXjpdKzpjbG91ZGZvcm1hdGlvbjpbXjpdKzpbXjpdKzpzdGFja1xcLyhbXlxcL10rKVxcLy8pXG4gICAgICAgIGlmICghbSB8fCAhc3RhY2tOYW1lcy5pbmNsdWRlcyhtWzFdKSkge1xuICAgICAgICAgIC8vIFN0YWNrIElEIG5hbWUgcGFydCBkaWRuJ3QgbWF0Y2ggZ2l2ZW4gc3RhY2tOYW1lLCBzbyBza2lwIGl0XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGV4cG9ydE9iai5OYW1lPy5tYXRjaCgvXkNsb3VETlM6LykpIHtcbiAgICAgICAgY29uc3QgbmFtZVBhcnRzID0gZXhwb3J0T2JqLk5hbWUuc3BsaXQoJzonKVxuICAgICAgICBjb25zdCByZXNvdXJjZVR5cGUgPSBuYW1lUGFydHNbMV1cbiAgICAgICAgY29uc3QgcmVzb3VyY2VOYW1lID0gbmFtZVBhcnRzLnNsaWNlKDIpLmpvaW4oJy4nKVxuICAgICAgICBjb25zdCByZXNvdXJjZVZhbHVlID0gZXhwb3J0T2JqLlZhbHVlIVxuICAgICAgICBhd2FpdCBjcmVhdGVPclVwZGF0ZUNsb3VkbnNSZXNvdXJjZShjbG91ZG5zVXNlcm5hbWUsIGNsb3VkbnNQYXNzd29yZCwgcmVzb3VyY2VOYW1lLCByZXNvdXJjZVR5cGUsIHJlc291cmNlVmFsdWUsIHR0bFZhbHVlLCB6b25lQ2FjaGUpXG4gICAgICB9XG4gICAgfVxuICAgIG5leHRUb2tlbiA9IHJlc3BvbnNlLk5leHRUb2tlblxuICB9IHdoaWxlIChuZXh0VG9rZW4pXG59XG4iXX0=
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cloudns-cloudformation-sync",
3
- "version": "1.3.0",
4
- "description": "Copyright (C) Clouden Oy 2023",
3
+ "version": "1.5.0",
4
+ "description": "Copyright (C) Clouden Oy 2020-2026",
5
5
  "main": "lib/cloudns-cloudformation-sync.js",
6
6
  "bin": {
7
7
  "cloudns-cloudformation-sync": "bin/cloudns-cloudformation-sync"
@@ -13,8 +13,8 @@
13
13
  "test": "echo \"Error: no test specified\" && exit 1",
14
14
  "build": "tsc",
15
15
  "prepare": "tsc",
16
- "ncu": "ncu -u -x 'node-fetch @types/node-fetch' && npm install",
17
- "ncucheck": "ncu -x 'node-fetch @types/node-fetch'"
16
+ "ncu": "ncu -u && npm install",
17
+ "ncucheck": "ncu"
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",
@@ -28,13 +28,11 @@
28
28
  },
29
29
  "homepage": "https://github.com/cloudeninc/cloudns-cloudformation-sync#readme",
30
30
  "dependencies": {
31
- "@aws-sdk/client-cloudformation": "^3.454.0",
32
- "@aws-sdk/client-ssm": "^3.454.0",
33
- "node-fetch": "^2.6.0"
31
+ "@aws-sdk/client-cloudformation": "^3.999.0",
32
+ "@aws-sdk/client-ssm": "^3.999.0"
34
33
  },
35
34
  "devDependencies": {
36
- "@types/node": "^20.10.0",
37
- "@types/node-fetch": "^2.5.7",
38
- "typescript": "^5.3.2"
35
+ "@types/node": "^25.3.2",
36
+ "typescript": "^5.9.3"
39
37
  }
40
38
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Read AWS CloudFormation Exports and autogenerate ClouDNS records based on their names and values.
3
- * Kenneth Falck <kennu@clouden.net> (C) Clouden Oy 2020-2023
3
+ * Kenneth Falck <kennu@clouden.net> (C) Clouden Oy 2020-2024
4
4
  *
5
5
  * This tool can be used to autogenerate ClouDNS records for CloudFormation resources like
6
6
  * CloudFront distributions and API Gateway domains.
@@ -16,23 +16,24 @@
16
16
  *
17
17
  * Other resource types are also allowed (A, AAAA, ALIAS, etc).
18
18
  *
19
- * Command line usage: AWS_PROFILE=xxx ts-node cloudns-cloudformation-sync.ts <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName]]
19
+ * Command line usage: AWS_PROFILE=xxx ts-node cloudns-cloudformation-sync.ts <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName...]]
20
20
  *
21
21
  * AWS_PROFILE=xxx - Specify your AWS profile in ~/.aws/credentials as an environment variable
22
22
  * <cloudns-username> - ClouDNS API sub-auth-user
23
23
  * <cloudns-password-parameter-name> - SSM Parameter with the encrypted ClouDNS API password
24
24
  * [ttl] - Optional TTL for generated records (defaults to 300)
25
- * [stackName] - Optional CloudFormation stack name to limit the exports to scan (defaults to all stacks)
25
+ * [stackName...] - Optional CloudFormation stack name(s) to limit the exports to scan (defaults to all stacks)
26
26
  */
27
27
  import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm'
28
28
  import { CloudFormationClient, ListExportsCommand, ListExportsOutput } from '@aws-sdk/client-cloudformation'
29
- import fetch from 'node-fetch'
30
29
  import * as querystring from 'querystring'
31
30
 
32
31
  // Load ~/.aws/config
33
32
  process.env.AWS_SDK_LOAD_CONFIG = '1'
34
33
 
35
- async function cloudnsRestCall(cloudnsUsername: string, cloudnsPassword: string, method: string, relativeUrl: string, queryOptions: any) {
34
+ type CloudnsRestCallResponse = any
35
+
36
+ async function cloudnsRestCall(cloudnsUsername: string, cloudnsPassword: string, method: string, relativeUrl: string, queryOptions: any): Promise<CloudnsRestCallResponse> {
36
37
  let fullUrl =
37
38
  'https://api.cloudns.net' +
38
39
  relativeUrl +
@@ -61,7 +62,8 @@ async function cloudnsRestCall(cloudnsUsername: string, cloudnsPassword: string,
61
62
  console.error('HTTP Error', response.status, response.statusText, errorText)
62
63
  throw new Error(errorText)
63
64
  }
64
- return response.json()
65
+ const parsedResponse: CloudnsRestCallResponse = await response.json()
66
+ return parsedResponse
65
67
  }
66
68
 
67
69
  async function autoDetectCloudnsHostAndZone(cloudnsUsername: string, cloudnsPassword: string, name: string, zoneCache: any) {
@@ -155,17 +157,17 @@ async function createOrUpdateCloudnsResource(
155
157
  }
156
158
 
157
159
  export async function main() {
158
- console.log('ClouDNS CloudFormation Sync by Kenneth Falck <kennu@clouden.net> (C) Clouden Oy 2020-2023')
160
+ console.log('ClouDNS CloudFormation Sync by Kenneth Falck <kennu@clouden.net> (C) Clouden Oy 2020-2024')
159
161
  const cloudnsUsername = process.argv[2]
160
162
  const cloudnsPasswordParameter = process.argv[3]
161
163
  const ttlValue = process.argv[4] || '300'
162
- const stackName = process.argv[5] || ''
164
+ const stackNames = process.argv.slice(5)
163
165
  if (!cloudnsUsername) {
164
- console.error('Usage: cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName]]')
166
+ console.error('Usage: cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName...]]')
165
167
  process.exit(1)
166
168
  }
167
169
  if (!cloudnsPasswordParameter) {
168
- console.error('Usage: cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName]]')
170
+ console.error('Usage: cloudns-cloudformation-sync <cloudns-username> <cloudns-password-parameter-name> [ttl [stackName...]]')
169
171
  process.exit(1)
170
172
  }
171
173
 
@@ -189,10 +191,10 @@ export async function main() {
189
191
  })
190
192
  )
191
193
  for (const exportObj of response.Exports || []) {
192
- if (stackName && exportObj.ExportingStackId !== stackName) {
194
+ if (stackNames.length && !stackNames.includes(exportObj.ExportingStackId || '')) {
193
195
  // Check if the name part of the ID matches arn:aws:cloudformation:eu-west-1:<xxx>:stack/<name>/<xxx>
194
196
  const m = exportObj.ExportingStackId?.match(/^arn:[^:]+:cloudformation:[^:]+:[^:]+:stack\/([^\/]+)\//)
195
- if (!m || m[1] !== stackName) {
197
+ if (!m || !stackNames.includes(m[1])) {
196
198
  // Stack ID name part didn't match given stackName, so skip it
197
199
  continue
198
200
  }