cloudflare-ddns-sync 2.0.5 → 3.0.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/CHANGELOG.md CHANGED
@@ -1,7 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## v3
4
+
5
+ ### v3.0.0
6
+
7
+ **This package will now be released as native ECMAScript module.**
8
+
9
+ - ✨ **Add possibility to use Cloudflare API Token**
10
+ - ♻️ Reduce request if many DNS Records exist for one Zone
11
+ - ⬆️ Update dependencies
12
+
3
13
  ## v2
4
14
 
15
+ ### v2.0.6
16
+
17
+ - ⬆️ Update dependencies
18
+
5
19
  ### v2.0.5
6
20
 
7
21
  - 🚨 Replace tslint with eslint
package/README.md CHANGED
@@ -5,12 +5,11 @@
5
5
  [![NPM](https://nodei.co/npm/cloudflare-ddns-sync.png)](https://www.npmjs.com/package/cloudflare-ddns-sync)
6
6
  [![NPM](https://nodei.co/npm/cloudflare-ddns-sync-cli.png)](https://www.npmjs.com/package/cloudflare-ddns-sync-cli)
7
7
 
8
-
9
8
  ## Overview
10
9
 
11
10
  Cloudflare-DDNS-Sync is a simple module that updates Cloudflare DNS records.
12
11
 
13
- For a more detailed overview, have a look at the [Documentation](https://cddnss.knaup.dev/)
12
+ For a more detailed overview, have a look at the [Documentation](https://cddnss.knaup.pw/)
14
13
 
15
14
  You may also have a look at the **official** [CLI version](https://www.npmjs.com/package/cloudflare-ddns-sync-cli) of Cloudflare-DDNS-Sync.
16
15
 
@@ -18,7 +17,7 @@ You may also have a look at the **official** [CLI version](https://www.npmjs.com
18
17
 
19
18
  ### Prerequisites
20
19
 
21
- - Node
20
+ - Node (16, 18)
22
21
  - Cloudflare Account
23
22
 
24
23
  ### Installation
@@ -34,27 +33,27 @@ in your project folder.
34
33
  ## Usage
35
34
 
36
35
  > Hint: If a record is not existing, CDS will automatically create it when
37
- syncing.
36
+ > syncing.
38
37
 
39
38
  ### Javascript Example
40
39
 
41
40
  ```javascript
42
- const Cddnss = require('cloudflare-ddns-sync').default;
41
+ const Cddnss = require("cloudflare-ddns-sync").default;
43
42
 
44
- const cddnss = new Cddnss('your@email.com', '<your-cloudflare-api-key>');
43
+ const cddnss = new Cddnss("your@email.com", "<your-cloudflare-api-key>");
45
44
 
46
45
  const records = [
47
46
  {
48
- name: 'test-1.domain.com',
49
- type: 'A', // optional
50
- proxied: true, // optional
51
- ttl: 1, // optional
52
- priority: 0, // optional
53
- content: '1.2.3.4', // optional
47
+ name: "test-1.domain.com",
48
+ type: "A", // optional
49
+ proxied: true, // optional
50
+ ttl: 1, // optional
51
+ priority: 0, // optional
52
+ content: "1.2.3.4", // optional
54
53
  },
55
54
  {
56
- name: "test-2.domain.com"
57
- }
55
+ name: "test-2.domain.com",
56
+ },
58
57
  ];
59
58
 
60
59
  cddnss.syncRecords(records).then((result) => {
@@ -65,21 +64,24 @@ cddnss.syncRecords(records).then((result) => {
65
64
  ### Typescript Example
66
65
 
67
66
  ```typescript
68
- import Cddnss, {Record, RecordData} from 'cloudflare-ddns-sync';
67
+ import Cddnss, { Record, RecordData } from "cloudflare-ddns-sync";
69
68
 
70
- const cddnss: Cddnss = new Cddnss('your@email.com', '<your-cloudflare-api-key>');
69
+ const cddnss: Cddnss = new Cddnss(
70
+ "your@email.com",
71
+ "<your-cloudflare-api-key>"
72
+ );
71
73
 
72
74
  const records: Array<Record> = [
73
75
  {
74
- name: 'test-1.yourdomain.com',
75
- type: 'A', // optional
76
- proxied: true, // optional
77
- ttl: 1, // optional
78
- priority: 0, // optional
79
- content: '1.2.3.4', // optional
76
+ name: "test-1.yourdomain.com",
77
+ type: "A", // optional
78
+ proxied: true, // optional
79
+ ttl: 1, // optional
80
+ priority: 0, // optional
81
+ content: "1.2.3.4", // optional
80
82
  },
81
83
  {
82
- name: "test-2.yourdomain.com"
84
+ name: "test-2.yourdomain.com",
83
85
  },
84
86
  ];
85
87
 
@@ -108,18 +110,18 @@ Cron expressions have the following syntax:
108
110
 
109
111
  - getIp(): Promise\<string\>
110
112
  - getIpv6(): Promise\<string\>
111
- - getRecordDataForDomain(domain: string): Promise\<Array\<[RecordData](https://cddnss.knaup.dev/types/recorddata)\>\>
112
- - getRecordDataForDomains(domains: Array\<string\>): Promise\<[DomainRecordList](https://cddnss.knaup.dev/types/domainrecordlist)\>
113
- - getRecordDataForRecord(record: [Record](https://cddnss.knaup.dev/types/record)): Promise\<[RecordData](https://cddnss.knaup.dev/types/recorddata)\>
114
- - getRecordDataForRecords(records: Array\<[Record](https://cddnss.knaup.dev/types/record)\>): Promise\<Array\<[RecordData](https://cddnss.knaup.dev/types/recorddata)\>\>
113
+ - getRecordDataForDomain(domain: string): Promise\<Array\<[RecordData](https://cddnss.knaup.pw/types/recorddata)\>\>
114
+ - getRecordDataForDomains(domains: Array\<string\>): Promise\<[DomainRecordList](https://cddnss.knaup.pw/types/domainrecordlist)\>
115
+ - getRecordDataForRecord(record: [Record](https://cddnss.knaup.pw/types/record)): Promise\<[RecordData](https://cddnss.knaup.pw/types/recorddata)\>
116
+ - getRecordDataForRecords(records: Array\<[Record](https://cddnss.knaup.pw/types/record)\>): Promise\<Array\<[RecordData](https://cddnss.knaup.pw/types/recorddata)\>\>
115
117
  - removeRecord(recordName: string, recordType?: string): Promise\<void\>
116
118
  - stopSyncOnIpChange(changeListenerId: string): void
117
- - syncByCronTime(cronExpression: string, records: Array\<[Record](https://cddnss.knaup.dev/types/recorddata)\>, callback: [MultiSyncCallback](https://cddnss.knaup.dev/types/multisynccallback), ip?: string): [ScheduledTask](https://www.npmjs.com/package/node-cron#scheduledtask-methods)
118
- - syncOnIpChange(records: Array\<[Record](https://cddnss.knaup.dev/types/record)\>, callback: multisynccallback): Promise\<string\>
119
- - syncRecord(record: [Record](https://cddnss.knaup.dev/types/record), ip?: string): Promise\<[RecordData](https://cddnss.knaup.dev/types/recorddata)\>
120
- - syncRecords(records: Array\<[Record](https://cddnss.knaup.dev/types/record)\>, ip?: string): Promise\<Array\<[RecordData](https://cddnss.knaup.dev/types/recorddata)\>\>
119
+ - syncByCronTime(cronExpression: string, records: Array\<[Record](https://cddnss.knaup.pw/types/recorddata)\>, callback: [MultiSyncCallback](https://cddnss.knaup.pw/types/multisynccallback), ip?: string): [ScheduledTask](https://www.npmjs.com/package/node-cron#scheduledtask-methods)
120
+ - syncOnIpChange(records: Array\<[Record](https://cddnss.knaup.pw/types/record)\>, callback: multisynccallback): Promise\<string\>
121
+ - syncRecord(record: [Record](https://cddnss.knaup.pw/types/record), ip?: string): Promise\<[RecordData](https://cddnss.knaup.pw/types/recorddata)\>
122
+ - syncRecords(records: Array\<[Record](https://cddnss.knaup.pw/types/record)\>, ip?: string): Promise\<Array\<[RecordData](https://cddnss.knaup.pw/types/recorddata)\>\>
121
123
 
122
- For a more detailed view, have a look at the [Documentation](https://cddnss.knaup.dev/)
124
+ For a more detailed view, have a look at the [Documentation](https://cddnss.knaup.pw/)
123
125
 
124
126
  ## Get Your Cloudflare API Key
125
127
 
@@ -0,0 +1,5 @@
1
+ export type Auth = {
2
+ email?: string;
3
+ key?: string;
4
+ token?: string;
5
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,3 @@
1
- import { RecordData } from './index';
2
- export declare type SingleSyncCallback = (syncResult: RecordData) => void;
3
- export declare type MultiSyncCallback = (syncResult: Array<RecordData>) => void;
1
+ import { RecordData } from './index.js';
2
+ export type SingleSyncCallback = (syncResult: RecordData) => void;
3
+ export type MultiSyncCallback = (syncResult: Array<RecordData>) => void;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { RecordData } from './index';
2
- export declare type DomainRecordList = {
1
+ import { RecordData } from './index.js';
2
+ export type DomainRecordList = {
3
3
  [domain: string]: Array<RecordData>;
4
4
  };
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,6 +1,8 @@
1
- export declare type Record = {
1
+ import { RecordTypes as CloudflareRecordTypes } from 'cloudflare';
2
+ export type RecordTypes = Exclude<CloudflareRecordTypes, 'MX' | 'SRV' | 'URI'>;
3
+ export type Record = {
2
4
  name: string;
3
- type?: string;
5
+ type?: RecordTypes;
4
6
  proxied?: boolean;
5
7
  ttl?: number;
6
8
  priority?: number;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1 +1 @@
1
- export declare type ZoneMap = Map<string, string>;
1
+ export type ZoneMap = Map<string, string>;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,6 +1,7 @@
1
- export declare type RecordData = {
1
+ import { RecordTypes } from '../index.js';
2
+ export type RecordData = {
2
3
  id: string;
3
- type: string;
4
+ type: RecordTypes;
4
5
  name: string;
5
6
  content: string;
6
7
  proxiable: boolean;
@@ -13,7 +14,7 @@ export declare type RecordData = {
13
14
  created_on: string;
14
15
  meta: RecordMetaData;
15
16
  };
16
- export declare type RecordMetaData = {
17
+ export type RecordMetaData = {
17
18
  auto_added: boolean;
18
19
  managed_by_apps: boolean;
19
20
  managed_by_argo_tunnel: boolean;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,4 +1,4 @@
1
- export declare type ZoneData = {
1
+ export type ZoneData = {
2
2
  id: string;
3
3
  name: string;
4
4
  status: string;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1,2 @@
1
- export * from './RecordData';
2
- export * from './ZoneData';
1
+ export * from './RecordData.js';
2
+ export * from './ZoneData.js';
@@ -1,14 +1,2 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- __exportStar(require("./RecordData"), exports);
14
- __exportStar(require("./ZoneData"), exports);
1
+ export * from './RecordData.js';
2
+ export * from './ZoneData.js';
@@ -1,5 +1,6 @@
1
- export * from './cloudflare/index';
2
- export * from './Callbacks';
3
- export * from './DomainRecordList';
4
- export * from './Record';
5
- export * from './ZoneMap';
1
+ export * from './cloudflare/index.js';
2
+ export * from './Auth.js';
3
+ export * from './Callbacks.js';
4
+ export * from './DomainRecordList.js';
5
+ export * from './Record.js';
6
+ export * from './ZoneMap.js';
@@ -1,17 +1,6 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- __exportStar(require("./cloudflare/index"), exports);
14
- __exportStar(require("./Callbacks"), exports);
15
- __exportStar(require("./DomainRecordList"), exports);
16
- __exportStar(require("./Record"), exports);
17
- __exportStar(require("./ZoneMap"), exports);
1
+ export * from './cloudflare/index.js';
2
+ export * from './Auth.js';
3
+ export * from './Callbacks.js';
4
+ export * from './DomainRecordList.js';
5
+ export * from './Record.js';
6
+ export * from './ZoneMap.js';
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { ScheduledTask } from 'node-cron';
2
- import { DomainRecordList, MultiSyncCallback, Record, RecordData } from './contracts/index';
2
+ import { Auth, DomainRecordList, MultiSyncCallback, Record, RecordData } from './contracts/index.js';
3
3
  export default class CloudflareDDNSSync {
4
4
  private cloudflareClient;
5
- constructor(email: string, authKey: string);
5
+ constructor(auth: Auth);
6
6
  getIp(): Promise<string>;
7
7
  getIpv6(): Promise<string>;
8
8
  getRecordDataForDomain(domain: string): Promise<Array<RecordData>>;
@@ -16,4 +16,4 @@ export default class CloudflareDDNSSync {
16
16
  syncRecord(record: Record, ip?: string): Promise<RecordData>;
17
17
  syncRecords(records: Array<Record>, ip?: string): Promise<Array<RecordData>>;
18
18
  }
19
- export * from './contracts/index';
19
+ export * from './contracts/index.js';
package/dist/index.js CHANGED
@@ -1,31 +1,16 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
- };
12
- var __importDefault = (this && this.__importDefault) || function (mod) {
13
- return (mod && mod.__esModule) ? mod : { "default": mod };
14
- };
15
- Object.defineProperty(exports, "__esModule", { value: true });
16
- const cloudflare_client_1 = __importDefault(require("./lib/cloudflare-client"));
17
- const cron_1 = __importDefault(require("./lib/cron"));
18
- const ip_utils_1 = __importDefault(require("./lib/ip-utils"));
19
- class CloudflareDDNSSync {
1
+ import CloudflareClient from './lib/cloudflare-client.js';
2
+ import Cron from './lib/cron.js';
3
+ import ipUtils from './lib/ip-utils.js';
4
+ export default class CloudflareDDNSSync {
20
5
  cloudflareClient;
21
- constructor(email, authKey) {
22
- this.cloudflareClient = new cloudflare_client_1.default(email, authKey);
6
+ constructor(auth) {
7
+ this.cloudflareClient = new CloudflareClient(auth);
23
8
  }
24
9
  getIp() {
25
- return ip_utils_1.default.getIpv4();
10
+ return ipUtils.getIpv4();
26
11
  }
27
12
  getIpv6() {
28
- return ip_utils_1.default.getIpv6();
13
+ return ipUtils.getIpv6();
29
14
  }
30
15
  getRecordDataForDomain(domain) {
31
16
  return this.cloudflareClient.getRecordDataForDomain(domain);
@@ -43,21 +28,21 @@ class CloudflareDDNSSync {
43
28
  return this.cloudflareClient.removeRecordByNameAndType(recordName, recordType);
44
29
  }
45
30
  stopSyncOnIpChange(changeListenerId) {
46
- ip_utils_1.default.removeIpChangeListener(changeListenerId);
31
+ ipUtils.removeIpChangeListener(changeListenerId);
47
32
  }
48
33
  syncByCronTime(cronExpression, records, callback, ip) {
49
- return cron_1.default.createCronJob(cronExpression, async () => {
34
+ return Cron.createCronJob(cronExpression, async () => {
50
35
  const result = await this.syncRecords(records, ip);
51
36
  callback(result);
52
37
  });
53
38
  }
54
39
  async syncOnIpChange(records, callback) {
55
- const changeListenerId = await ip_utils_1.default.addIpChangeListener(async (ip) => {
40
+ const changeListenerId = await ipUtils.addIpChangeListener(async (ip) => {
56
41
  const result = await this.syncRecords(records, ip);
57
42
  callback(result);
58
43
  });
59
44
  // Sync records to make sure the current ip is already set.
60
- const currentIp = await ip_utils_1.default.getIpv4();
45
+ const currentIp = await ipUtils.getIpv4();
61
46
  this.syncRecords(records, currentIp).then((syncedRecords) => {
62
47
  callback(syncedRecords);
63
48
  });
@@ -70,5 +55,4 @@ class CloudflareDDNSSync {
70
55
  return this.cloudflareClient.syncRecords(records, ip);
71
56
  }
72
57
  }
73
- exports.default = CloudflareDDNSSync;
74
- __exportStar(require("./contracts/index"), exports);
58
+ export * from './contracts/index.js';
@@ -1,8 +1,8 @@
1
- import { DomainRecordList, Record, RecordData } from '../contracts';
1
+ import { Auth, DomainRecordList, Record, RecordData } from '../contracts/index.js';
2
2
  export default class CloudflareClient {
3
3
  private cloudflare;
4
4
  private zoneMap;
5
- constructor(email: string, authKey: string);
5
+ constructor(auth: Auth);
6
6
  syncRecord(record: Record, ip?: string): Promise<RecordData>;
7
7
  syncRecords(records: Array<Record>, ip?: string): Promise<Array<RecordData>>;
8
8
  removeRecordByNameAndType(recordName: string, recordType?: string): Promise<void>;
@@ -1,27 +1,19 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const parse_domain_1 = require("parse-domain");
7
- const cloudflare_1 = __importDefault(require("cloudflare"));
8
- const ip_utils_1 = __importDefault(require("./ip-utils"));
1
+ import { ParseResultType, fromUrl, parseDomain, } from 'parse-domain';
2
+ import Cloudflare from 'cloudflare';
3
+ import IPUtils from './ip-utils.js';
9
4
  const ipv4Regex = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/u;
10
5
  // eslint-disable-next-line max-len
11
6
  const ipv6Regex = /^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$/u;
12
- class CloudflareClient {
7
+ export default class CloudflareClient {
13
8
  cloudflare;
14
9
  zoneMap = new Map();
15
- constructor(email, authKey) {
16
- this.cloudflare = new cloudflare_1.default({
17
- email: email,
18
- key: authKey,
19
- });
10
+ constructor(auth) {
11
+ this.cloudflare = new Cloudflare(auth);
20
12
  this.updateZoneMap();
21
13
  }
22
14
  async syncRecord(record, ip) {
23
15
  const recordIds = await this.getRecordIdsForRecords([record]);
24
- const ipToUse = ip ? ip : await ip_utils_1.default.getIpv4();
16
+ const ipToUse = ip ? ip : await IPUtils.getIpv4();
25
17
  const zoneId = await this.getZoneIdByRecordName(record.name);
26
18
  const recordId = recordIds.get(this.getRecordIdMapKey(record));
27
19
  const recordExists = recordId !== undefined;
@@ -34,7 +26,7 @@ class CloudflareClient {
34
26
  }
35
27
  async syncRecords(records, ip) {
36
28
  const recordIds = await this.getRecordIdsForRecords(records);
37
- const ipToUse = ip ? ip : await ip_utils_1.default.getIpv4();
29
+ const ipToUse = ip ? ip : await IPUtils.getIpv4();
38
30
  const resultPromises = records.map(async (record) => {
39
31
  const zoneId = await this.getZoneIdByRecordName(record.name);
40
32
  const recordId = recordIds.get(this.getRecordIdMapKey(record));
@@ -53,7 +45,7 @@ class CloudflareClient {
53
45
  const recordTypeToUse = recordType ? recordType : 'A';
54
46
  const zoneId = await this.getZoneIdByRecordName(recordName);
55
47
  const recordId = await this.getRecordIdByNameAndType(recordName, recordTypeToUse);
56
- return this.cloudflare.dnsRecords.del(zoneId, recordId);
48
+ await this.cloudflare.dnsRecords.del(zoneId, recordId);
57
49
  }
58
50
  async getRecordDataForRecord(record) {
59
51
  const domain = this.getDomainByRecordName(record.name);
@@ -88,57 +80,63 @@ class CloudflareClient {
88
80
  return recordData;
89
81
  }
90
82
  async createRecord(zoneId, record, ip) {
91
- const copyOfRecord = { ...record };
92
- copyOfRecord.name = record.name.toLowerCase();
93
- copyOfRecord.content = copyOfRecord.content ? copyOfRecord.content : ip;
94
- copyOfRecord.type = copyOfRecord.type ? copyOfRecord.type : 'A';
95
- if (!copyOfRecord.content) {
96
- throw Error(`Could not create Record "${copyOfRecord.name}": Content is missing!`);
97
- }
98
- if (copyOfRecord.type === 'A') {
99
- if (!copyOfRecord.content.match(ipv4Regex)) {
100
- throw Error(`Could not create Record "${copyOfRecord.name}": '${copyOfRecord.content}' is not a valid ipv4!`);
83
+ const dnsRecord = {
84
+ ...record,
85
+ name: record.name.toLowerCase(),
86
+ content: record.content ? record.content : ip,
87
+ type: record.type ? record.type : 'A',
88
+ ttl: record.ttl ? record.ttl : 1,
89
+ };
90
+ if (!dnsRecord.content) {
91
+ throw Error(`Could not create Record "${dnsRecord.name}": Content is missing!`);
92
+ }
93
+ if (dnsRecord.type === 'A') {
94
+ if (!dnsRecord.content.match(ipv4Regex)) {
95
+ throw Error(`Could not create Record "${dnsRecord.name}": '${dnsRecord.content}' is not a valid ipv4!`);
101
96
  }
102
97
  }
103
- else if (copyOfRecord.type === 'AAAA') {
104
- if (!copyOfRecord.content.match(ipv6Regex)) {
105
- throw Error(`Could not create Record "${copyOfRecord.name}": '${copyOfRecord.content}' is not a valid ipv6!`);
98
+ else if (dnsRecord.type === 'AAAA') {
99
+ if (!dnsRecord.content.match(ipv6Regex)) {
100
+ throw Error(`Could not create Record "${dnsRecord.name}": '${dnsRecord.content}' is not a valid ipv6!`);
106
101
  }
107
102
  }
108
- else if (copyOfRecord.type === 'CNAME') {
109
- const parsedDomain = (0, parse_domain_1.parseDomain)((0, parse_domain_1.fromUrl)(copyOfRecord.content));
110
- if (parsedDomain.type !== parse_domain_1.ParseResultType.Listed || !parsedDomain.domain) {
111
- throw Error(`Could not create Record "${copyOfRecord.name}": '${copyOfRecord.content}' is not a valid domain name!`);
103
+ else if (dnsRecord.type === 'CNAME') {
104
+ const parsedDomain = parseDomain(fromUrl(dnsRecord.content));
105
+ if (parsedDomain.type !== ParseResultType.Listed || !parsedDomain.domain) {
106
+ throw Error(`Could not create Record "${dnsRecord.name}": '${dnsRecord.content}' is not a valid domain name!`);
112
107
  }
113
108
  }
114
- const response = await this.cloudflare.dnsRecords.add(zoneId, copyOfRecord);
109
+ const response = await this.cloudflare.dnsRecords.add(zoneId, dnsRecord);
115
110
  return response.result;
116
111
  }
117
112
  async updateRecord(zoneId, recordId, record, ip) {
118
- const copyOfRecord = { ...record };
119
- copyOfRecord.name = record.name.toLowerCase();
120
- copyOfRecord.content = copyOfRecord.content ? copyOfRecord.content : ip;
121
- copyOfRecord.type = copyOfRecord.type ? copyOfRecord.type : 'A';
122
- if (!copyOfRecord.content) {
123
- throw Error(`Could not update Record "${copyOfRecord.name}": Content is missing!`);
124
- }
125
- if (copyOfRecord.type === 'A') {
126
- if (!copyOfRecord.content.match(ipv4Regex)) {
127
- throw Error(`Could not update Record "${copyOfRecord.name}": '${copyOfRecord.content}' is not a valid ipv4!`);
113
+ const dnsRecord = {
114
+ ...record,
115
+ name: record.name.toLowerCase(),
116
+ content: record.content ? record.content : ip,
117
+ type: record.type ? record.type : 'A',
118
+ ttl: record.ttl ? record.ttl : 1,
119
+ };
120
+ if (!dnsRecord.content) {
121
+ throw Error(`Could not update Record "${dnsRecord.name}": Content is missing!`);
122
+ }
123
+ if (dnsRecord.type === 'A') {
124
+ if (!dnsRecord.content.match(ipv4Regex)) {
125
+ throw Error(`Could not update Record "${dnsRecord.name}": '${dnsRecord.content}' is not a valid ipv4!`);
128
126
  }
129
127
  }
130
- else if (copyOfRecord.type === 'AAAA') {
131
- if (!copyOfRecord.content.match(ipv6Regex)) {
132
- throw Error(`Could not update Record "${copyOfRecord.name}": '${copyOfRecord.content}' is not a valid ipv6!`);
128
+ else if (dnsRecord.type === 'AAAA') {
129
+ if (!dnsRecord.content.match(ipv6Regex)) {
130
+ throw Error(`Could not update Record "${dnsRecord.name}": '${dnsRecord.content}' is not a valid ipv6!`);
133
131
  }
134
132
  }
135
- else if (copyOfRecord.type === 'CNAME') {
136
- const parsedDomain = (0, parse_domain_1.parseDomain)((0, parse_domain_1.fromUrl)(copyOfRecord.content));
137
- if (parsedDomain.type !== parse_domain_1.ParseResultType.Listed || !parsedDomain.domain) {
138
- throw Error(`Could not update Record "${copyOfRecord.name}": '${copyOfRecord.content}' is not a valid domain name!`);
133
+ else if (dnsRecord.type === 'CNAME') {
134
+ const parsedDomain = parseDomain(fromUrl(dnsRecord.content));
135
+ if (parsedDomain.type !== ParseResultType.Listed || !parsedDomain.domain) {
136
+ throw Error(`Could not update Record "${dnsRecord.name}": '${dnsRecord.content}' is not a valid domain name!`);
139
137
  }
140
138
  }
141
- const response = await this.cloudflare.dnsRecords.edit(zoneId, recordId, copyOfRecord);
139
+ const response = await this.cloudflare.dnsRecords.edit(zoneId, recordId, dnsRecord);
142
140
  return response.result;
143
141
  }
144
142
  async updateZoneMap() {
@@ -186,13 +184,16 @@ class CloudflareClient {
186
184
  const records = [];
187
185
  let pageIndex = 1;
188
186
  let allRecordsFound = false;
187
+ const recordsPerPage = 5000;
189
188
  while (!allRecordsFound) {
189
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
190
190
  const response = await this.cloudflare.dnsRecords.browse(zoneId, {
191
191
  page: pageIndex,
192
- per_page: 100,
192
+ // eslint-disable-next-line camelcase
193
+ per_page: recordsPerPage,
193
194
  });
194
195
  records.push(...response.result);
195
- allRecordsFound = response.result.length < 100;
196
+ allRecordsFound = response.result.length < recordsPerPage;
196
197
  pageIndex++;
197
198
  }
198
199
  return records;
@@ -216,8 +217,8 @@ class CloudflareClient {
216
217
  return domains;
217
218
  }
218
219
  getDomainByRecordName(recordName) {
219
- const parsedDomain = (0, parse_domain_1.parseDomain)((0, parse_domain_1.fromUrl)(recordName));
220
- if (parsedDomain.type !== parse_domain_1.ParseResultType.Listed || !parsedDomain.domain) {
220
+ const parsedDomain = parseDomain(fromUrl(recordName));
221
+ if (parsedDomain.type !== ParseResultType.Listed || !parsedDomain.domain) {
221
222
  throw new Error(`Could not parse domain. '${JSON.stringify(recordName)}' is not a valid record name.`);
222
223
  }
223
224
  let domain = '';
@@ -228,4 +229,3 @@ class CloudflareClient {
228
229
  return domain.toLowerCase();
229
230
  }
230
231
  }
231
- exports.default = CloudflareClient;
package/dist/lib/cron.js CHANGED
@@ -1,22 +1,16 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const node_cron_1 = __importDefault(require("node-cron"));
7
- class Cron {
1
+ import cron from 'node-cron';
2
+ export default class Cron {
8
3
  static createCronJob(cronExpression, callback) {
9
4
  const cronExpressionIsInvalid = !this.isValid(cronExpression);
10
5
  if (cronExpressionIsInvalid) {
11
6
  // eslint-disable-next-line max-len
12
- throw new Error(`'${cronExpression}' is not a valid cron expression.\nHere you can see how cron expressions work: https://cddnss.knaup.dev/cron-expression-syntax`);
7
+ throw new Error(`'${cronExpression}' is not a valid cron expression.\nHere you can see how cron expressions work: https://cddnss.knaup.pw/cron-expression-syntax`);
13
8
  }
14
- return node_cron_1.default.schedule(cronExpression, () => {
9
+ return cron.schedule(cronExpression, () => {
15
10
  callback();
16
11
  }, undefined);
17
12
  }
18
13
  static isValid(cronExpression) {
19
- return node_cron_1.default.validate(cronExpression);
14
+ return cron.validate(cronExpression);
20
15
  }
21
16
  }
22
- exports.default = Cron;
@@ -5,5 +5,5 @@ export default class IPUtils {
5
5
  static getIpv6(): Promise<string>;
6
6
  static addIpChangeListener(callback: Function): Promise<string>;
7
7
  static removeIpChangeListener(eventListenerId: string): void;
8
- private static getRandomId;
8
+ private static getId;
9
9
  }
@@ -1,36 +1,12 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
21
- var __importDefault = (this && this.__importDefault) || function (mod) {
22
- return (mod && mod.__esModule) ? mod : { "default": mod };
23
- };
24
- Object.defineProperty(exports, "__esModule", { value: true });
25
- const wimIp = __importStar(require("what-is-my-ip-address"));
26
- const public_ip_1 = __importDefault(require("public-ip"));
27
- class IPUtils {
1
+ import * as wimIp from 'what-is-my-ip-address';
2
+ import { publicIpv4, publicIpv6 } from 'public-ip';
3
+ export default class IPUtils {
28
4
  static ipPollingDelay = 10 * 1000;
29
5
  static ipChangeEventListeners = new Map();
30
6
  static async getIpv4() {
31
7
  /* c8 ignore start*/
32
8
  try {
33
- return await public_ip_1.default.v4();
9
+ return await publicIpv4();
34
10
  }
35
11
  catch (error) {
36
12
  return wimIp.v4();
@@ -40,7 +16,7 @@ class IPUtils {
40
16
  static async getIpv6() {
41
17
  /* c8 ignore start */
42
18
  try {
43
- return await public_ip_1.default.v6();
19
+ return await publicIpv6();
44
20
  }
45
21
  catch (error) {
46
22
  return wimIp.v6();
@@ -48,7 +24,7 @@ class IPUtils {
48
24
  /* c8 ignore stop*/
49
25
  }
50
26
  static async addIpChangeListener(callback) {
51
- const eventListenerId = this.getRandomId();
27
+ const eventListenerId = this.getId();
52
28
  let previousIp = await this.getIpv4();
53
29
  /* c8 ignore start */
54
30
  const intervalId = setInterval(async () => {
@@ -68,15 +44,9 @@ class IPUtils {
68
44
  clearInterval(eventListenerIntervalId);
69
45
  IPUtils.ipChangeEventListeners.delete(eventListenerId);
70
46
  }
71
- static getRandomId() {
72
- const beginningRandomString = Math.random().toString(36)
73
- .substr(2);
74
- const currentDateAsString = new Date().valueOf()
75
- .toString(36);
76
- const endingRandomString = Math.random().toString(36)
77
- .substr(2);
78
- const randomString = beginningRandomString + currentDateAsString + endingRandomString;
79
- return randomString;
47
+ static getId() {
48
+ return Math.random().toString(36)
49
+ .substring(2, 15) + Math.random().toString(36)
50
+ .substring(2, 15);
80
51
  }
81
52
  }
82
- exports.default = IPUtils;
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "cloudflare-ddns-sync",
3
- "version": "2.0.5",
3
+ "version": "3.0.0",
4
4
  "description": "A simple module to update DNS records on Cloudflare whenever you want",
5
5
  "main": "dist/index.js",
6
6
  "author": "Steffen Knaup <SteffenKnaup@hotmail.de>",
7
7
  "license": "ISC",
8
+ "type": "module",
8
9
  "keywords": [
9
10
  "cloudflare",
10
11
  "cddnss",
@@ -13,7 +14,7 @@
13
14
  "dyndns",
14
15
  "sync"
15
16
  ],
16
- "homepage": "https://cddnss.knaup.dev/",
17
+ "homepage": "https://cddnss.knaup.pw/",
17
18
  "repository": {
18
19
  "type": "git",
19
20
  "url": "git://github.com:Steffen982/cloudflare-ddns-sync.git"
@@ -29,25 +30,25 @@
29
30
  },
30
31
  "dependencies": {
31
32
  "cloudflare": "2.9.1",
32
- "node-cron": "3.0.0",
33
- "parse-domain": "4.1.0",
34
- "public-ip": "4.0.4",
33
+ "node-cron": "3.0.2",
34
+ "parse-domain": "7.0.1",
35
+ "public-ip": "6.0.1",
35
36
  "what-is-my-ip-address": "1.0.3"
36
37
  },
37
38
  "devDependencies": {
38
- "@types/chai": "4.3.0",
39
+ "@types/chai": "4.3.4",
40
+ "@types/cloudflare": "^2.7.9",
39
41
  "@types/minimist": "1.2.2",
40
- "@types/mocha": "9.0.0",
41
- "@types/node": "16.11.20",
42
- "@types/node-cron": "3.0.1",
43
- "@typescript-eslint/eslint-plugin": "5.10.0",
44
- "@typescript-eslint/parser": "5.10.0",
45
- "c8": "7.11.0",
46
- "chai": "4.3.4",
47
- "eslint": "8.7.0",
48
- "minimist": "1.2.5",
49
- "mocha": "9.1.4",
50
- "tslint": "6.1.3",
51
- "typescript": "4.5.4"
42
+ "@types/mocha": "10.0.1",
43
+ "@types/node": "18.11.17",
44
+ "@types/node-cron": "3.0.6",
45
+ "@typescript-eslint/eslint-plugin": "5.46.1",
46
+ "@typescript-eslint/parser": "5.46.1",
47
+ "c8": "7.12.0",
48
+ "chai": "4.3.7",
49
+ "eslint": "8.30.0",
50
+ "minimist": "1.2.7",
51
+ "mocha": "10.2.0",
52
+ "typescript": "4.9.4"
52
53
  }
53
54
  }