mirror of
https://github.com/cupcakearmy/docker-ddns-cloudflare.git
synced 2025-09-09 14:30:41 +00:00
Compare commits
9 Commits
v1.3.1
...
e0af9cd82e
Author | SHA1 | Date | |
---|---|---|---|
e0af9cd82e | |||
3ca15c532f | |||
500d7b2423 | |||
144d5abeb6 | |||
0b6e6e07dd | |||
|
43bc492c49 | ||
|
b9f77f24ca | ||
18a5a40b43 | |||
37cdc12439 |
@@ -1,5 +1,4 @@
|
||||
*
|
||||
!src
|
||||
!tsconfig.json
|
||||
!package.json
|
||||
!pnpm-lock.yaml
|
||||
!bun.lockb
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
.env
|
||||
ip.log
|
||||
dist
|
||||
node_modules
|
||||
.vscode
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# Required
|
||||
TOKEn=myapitoken
|
||||
TOKEN=myapitoken
|
||||
ZONE=example.org
|
||||
DNS_RECORD=some.example.org
|
||||
|
||||
|
31
CHANGELOG.md
31
CHANGELOG.md
@@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.4.1] - 2024-02-27
|
||||
|
||||
### Changed
|
||||
|
||||
- Use the alpine `bun` image to half the image size.
|
||||
|
||||
## [1.4.0] - 2024-02-27
|
||||
|
||||
### Changed
|
||||
|
||||
- Moved to bun.
|
||||
- Removed some dependencies.
|
||||
|
||||
## [1.3.4] - 2024-02-27
|
||||
|
||||
### Security
|
||||
|
||||
- Updated dependencies.
|
||||
|
||||
## [1.3.3] - 2023-08-20
|
||||
|
||||
### Security
|
||||
|
||||
- Updated dependencies.
|
||||
|
||||
## [1.3.2] - 2023-06-24
|
||||
|
||||
### Security
|
||||
|
||||
- Updated dependencies.
|
||||
|
||||
## [1.3.1] - 2022-11-28
|
||||
|
||||
### Added
|
||||
|
21
Dockerfile
21
Dockerfile
@@ -1,19 +1,10 @@
|
||||
FROM node:18-alpine as base
|
||||
FROM oven/bun:1-alpine as base
|
||||
|
||||
WORKDIR /app
|
||||
RUN npm -g i pnpm
|
||||
COPY package.json bun.lockb /app/
|
||||
RUN bun install --production --frozen-lockfile
|
||||
|
||||
|
||||
FROM base as builder
|
||||
ADD ./package.json ./pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
ADD . .
|
||||
RUN pnpm run build
|
||||
|
||||
FROM base
|
||||
ADD ./package.json ./pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile --prod
|
||||
COPY --from=builder /app/dist/ /app/dist/
|
||||
COPY . .
|
||||
|
||||
STOPSIGNAL SIGTERM
|
||||
|
||||
CMD ["pnpm", "start"]
|
||||
CMD ["bun", "."]
|
||||
|
@@ -51,7 +51,7 @@ docker-compose up -d
|
||||
| `ZONE` | | Cloudflare zone where your domain is. |
|
||||
| `DNS_RECORD` | | The actual DNS record that should be updated. |
|
||||
| `PROXIED` | `true` | Whether the record is proxied by CloudFlare or not. |
|
||||
| `CRON` | `*/5 * * * *` | Frequency of updates. |
|
||||
| `CRON` | `*/5 * * * *` | Frequency of updates. The [following syntax](https://croner.56k.guru/usage/pattern/) is supported |
|
||||
| `RESOLVER` | `https://api.ipify.org/` | The endpoint used to determine your public ip. |
|
||||
| `LOG_LEVEL` | `info` | Log level to run at. See [winston](https://github.com/winstonjs/winston#logging-levels) for possible values |
|
||||
|
||||
|
22
package.json
22
package.json
@@ -1,22 +1,20 @@
|
||||
{
|
||||
"version": "1.3.1",
|
||||
"version": "1.4.1",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "dist",
|
||||
"main": "./src/index.ts",
|
||||
"scripts": {
|
||||
"dev": "tsc -w",
|
||||
"build": "tsc",
|
||||
"start": "node ."
|
||||
"check": "tsc --noEmit",
|
||||
"dev": "bun --watch ./src/index.ts",
|
||||
"start": "bun ./src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.2.0",
|
||||
"dotenv": "^16.0.3",
|
||||
"node-cron": "^3.0.2",
|
||||
"winston": "^3.8.2"
|
||||
"axios": "^1.6.7",
|
||||
"croner": "^8.0.1",
|
||||
"winston": "^3.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/node-cron": "^3.0.6",
|
||||
"typescript": "^4.9.3"
|
||||
"@types/bun": "^1.0.7",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
288
pnpm-lock.yaml
generated
288
pnpm-lock.yaml
generated
@@ -1,288 +0,0 @@
|
||||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@types/node': ^18.11.9
|
||||
'@types/node-cron': ^3.0.6
|
||||
axios: ^1.2.0
|
||||
dotenv: ^16.0.3
|
||||
node-cron: ^3.0.2
|
||||
typescript: ^4.9.3
|
||||
winston: ^3.8.2
|
||||
|
||||
dependencies:
|
||||
axios: 1.2.0
|
||||
dotenv: 16.0.3
|
||||
node-cron: 3.0.2
|
||||
winston: 3.8.2
|
||||
|
||||
devDependencies:
|
||||
'@types/node': 18.11.9
|
||||
'@types/node-cron': 3.0.6
|
||||
typescript: 4.9.3
|
||||
|
||||
packages:
|
||||
|
||||
/@colors/colors/1.5.0:
|
||||
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
||||
engines: {node: '>=0.1.90'}
|
||||
dev: false
|
||||
|
||||
/@dabh/diagnostics/2.0.3:
|
||||
resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
|
||||
dependencies:
|
||||
colorspace: 1.1.4
|
||||
enabled: 2.0.0
|
||||
kuler: 2.0.0
|
||||
dev: false
|
||||
|
||||
/@types/node-cron/3.0.6:
|
||||
resolution: {integrity: sha512-Qu9dpjkgj2JmzRmDMVzpt2dFKuJ7wma0mxEvbbgomwkhAdHKT2LpSLYHawzd9OeeP4HsyhmcV9o/xLgJyPNcgw==}
|
||||
dev: true
|
||||
|
||||
/@types/node/18.11.9:
|
||||
resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==}
|
||||
dev: true
|
||||
|
||||
/async/3.2.4:
|
||||
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
|
||||
dev: false
|
||||
|
||||
/asynckit/0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
dev: false
|
||||
|
||||
/axios/1.2.0:
|
||||
resolution: {integrity: sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.2
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/color-convert/1.9.3:
|
||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||
dependencies:
|
||||
color-name: 1.1.3
|
||||
dev: false
|
||||
|
||||
/color-name/1.1.3:
|
||||
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
|
||||
dev: false
|
||||
|
||||
/color-name/1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
dev: false
|
||||
|
||||
/color-string/1.9.1:
|
||||
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
simple-swizzle: 0.2.2
|
||||
dev: false
|
||||
|
||||
/color/3.2.1:
|
||||
resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
|
||||
dependencies:
|
||||
color-convert: 1.9.3
|
||||
color-string: 1.9.1
|
||||
dev: false
|
||||
|
||||
/colorspace/1.1.4:
|
||||
resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==}
|
||||
dependencies:
|
||||
color: 3.2.1
|
||||
text-hex: 1.0.0
|
||||
dev: false
|
||||
|
||||
/combined-stream/1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
dev: false
|
||||
|
||||
/delayed-stream/1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/dotenv/16.0.3:
|
||||
resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/enabled/2.0.0:
|
||||
resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==}
|
||||
dev: false
|
||||
|
||||
/fecha/4.2.3:
|
||||
resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==}
|
||||
dev: false
|
||||
|
||||
/fn.name/1.1.0:
|
||||
resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==}
|
||||
dev: false
|
||||
|
||||
/follow-redirects/1.15.2:
|
||||
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
dev: false
|
||||
|
||||
/form-data/4.0.0:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: false
|
||||
|
||||
/inherits/2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
dev: false
|
||||
|
||||
/is-arrayish/0.3.2:
|
||||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
||||
dev: false
|
||||
|
||||
/is-stream/2.0.1:
|
||||
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/kuler/2.0.0:
|
||||
resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==}
|
||||
dev: false
|
||||
|
||||
/logform/2.4.2:
|
||||
resolution: {integrity: sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==}
|
||||
dependencies:
|
||||
'@colors/colors': 1.5.0
|
||||
fecha: 4.2.3
|
||||
ms: 2.1.3
|
||||
safe-stable-stringify: 2.4.1
|
||||
triple-beam: 1.3.0
|
||||
dev: false
|
||||
|
||||
/mime-db/1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/mime-types/2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
dev: false
|
||||
|
||||
/ms/2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
dev: false
|
||||
|
||||
/node-cron/3.0.2:
|
||||
resolution: {integrity: sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dependencies:
|
||||
uuid: 8.3.2
|
||||
dev: false
|
||||
|
||||
/one-time/1.0.0:
|
||||
resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==}
|
||||
dependencies:
|
||||
fn.name: 1.1.0
|
||||
dev: false
|
||||
|
||||
/proxy-from-env/1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
dev: false
|
||||
|
||||
/readable-stream/3.6.0:
|
||||
resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
string_decoder: 1.3.0
|
||||
util-deprecate: 1.0.2
|
||||
dev: false
|
||||
|
||||
/safe-buffer/5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
dev: false
|
||||
|
||||
/safe-stable-stringify/2.4.1:
|
||||
resolution: {integrity: sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/simple-swizzle/0.2.2:
|
||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||
dependencies:
|
||||
is-arrayish: 0.3.2
|
||||
dev: false
|
||||
|
||||
/stack-trace/0.0.10:
|
||||
resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
|
||||
dev: false
|
||||
|
||||
/string_decoder/1.3.0:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
dev: false
|
||||
|
||||
/text-hex/1.0.0:
|
||||
resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==}
|
||||
dev: false
|
||||
|
||||
/triple-beam/1.3.0:
|
||||
resolution: {integrity: sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==}
|
||||
dev: false
|
||||
|
||||
/typescript/4.9.3:
|
||||
resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/util-deprecate/1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
dev: false
|
||||
|
||||
/uuid/8.3.2:
|
||||
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/winston-transport/4.5.0:
|
||||
resolution: {integrity: sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==}
|
||||
engines: {node: '>= 6.4.0'}
|
||||
dependencies:
|
||||
logform: 2.4.2
|
||||
readable-stream: 3.6.0
|
||||
triple-beam: 1.3.0
|
||||
dev: false
|
||||
|
||||
/winston/3.8.2:
|
||||
resolution: {integrity: sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
dependencies:
|
||||
'@colors/colors': 1.5.0
|
||||
'@dabh/diagnostics': 2.0.3
|
||||
async: 3.2.4
|
||||
is-stream: 2.0.1
|
||||
logform: 2.4.2
|
||||
one-time: 1.0.0
|
||||
readable-stream: 3.6.0
|
||||
safe-stable-stringify: 2.4.1
|
||||
stack-trace: 0.0.10
|
||||
triple-beam: 1.3.0
|
||||
winston-transport: 4.5.0
|
||||
dev: false
|
@@ -20,6 +20,8 @@ type DNSRecord = {
|
||||
type DNSRecordCreate = Pick<DNSRecord, 'name' | 'type' | 'ttl' | 'proxied' | 'content'>
|
||||
type DNSRecordPatch = Partial<DNSRecordCreate>
|
||||
|
||||
const l = logger.child({ context: 'cloudflare' })
|
||||
|
||||
const Base = axios.create({
|
||||
baseURL: 'https://api.cloudflare.com/client/v4',
|
||||
headers: {
|
||||
@@ -80,27 +82,27 @@ export const API = {
|
||||
export async function update(ip: string) {
|
||||
// Find zone
|
||||
if (!Cache.has('zone')) {
|
||||
logger.debug('Fetching zone')
|
||||
l.debug('Fetching zone')
|
||||
const zone = await API.zones.findByName(Config.dns.zone)
|
||||
if (!zone) {
|
||||
logger.error(`Zone "${Config.dns.zone}"" not found`)
|
||||
l.error(`Zone "${Config.dns.zone}" not found`)
|
||||
process.exit(1)
|
||||
}
|
||||
Cache.set('zone', zone)
|
||||
}
|
||||
|
||||
const zoneId = Cache.get('zone')!
|
||||
logger.debug(`Zone ID: ${zoneId}`)
|
||||
l.debug(`Zone ID: ${zoneId}`)
|
||||
|
||||
// Set record
|
||||
const records = await API.records.find(zoneId)
|
||||
|
||||
logger.debug('Updating record', ip)
|
||||
l.debug('Updating record', ip)
|
||||
|
||||
switch (records.length) {
|
||||
case 0:
|
||||
// Create DNS Record
|
||||
logger.debug('Creating DNS record')
|
||||
l.debug('Creating DNS record')
|
||||
await API.records.create(zoneId, {
|
||||
content: ip,
|
||||
name: Config.dns.record,
|
||||
@@ -114,7 +116,7 @@ export async function update(ip: string) {
|
||||
break
|
||||
default:
|
||||
// More than one record, delete all but the first
|
||||
logger.debug('Deleting other DNS records')
|
||||
l.debug('Deleting other DNS records')
|
||||
for (const record of records.slice(1)) {
|
||||
await API.records.remove(zoneId, record.id)
|
||||
}
|
||||
|
@@ -1,7 +1,5 @@
|
||||
import { config } from 'dotenv'
|
||||
import { validate } from 'node-cron'
|
||||
|
||||
config()
|
||||
import { Cron } from 'croner'
|
||||
import pkg from '../package.json'
|
||||
|
||||
function getEnv(key: string, fallback: string, parse?: undefined, validator?: (s: string) => boolean): string
|
||||
function getEnv<T>(key: string, fallback: T, parse: (value: string) => T, validator?: (T: string) => boolean): T
|
||||
@@ -31,7 +29,7 @@ function isPresent(s: string): boolean {
|
||||
}
|
||||
|
||||
export const Config = {
|
||||
version: getEnv('npm_package_version', 'unknown'),
|
||||
version: pkg.version,
|
||||
logging: {
|
||||
level: getEnv('LOG_LEVEL', 'info'),
|
||||
},
|
||||
@@ -44,7 +42,14 @@ export const Config = {
|
||||
proxied: getEnv('PROXIED', false, parseBoolean),
|
||||
},
|
||||
runner: {
|
||||
cron: getEnv('CRON', '*/5 * * * *', undefined, (s) => validate(s)),
|
||||
cron: getEnv('CRON', '*/5 * * * *', undefined, (s) => {
|
||||
try {
|
||||
new Cron(s)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}),
|
||||
resolver: getEnv('RESOLVER', 'https://api.ipify.org'),
|
||||
},
|
||||
}
|
||||
|
16
src/index.ts
16
src/index.ts
@@ -1,14 +1,20 @@
|
||||
import { schedule } from 'node-cron'
|
||||
import process from 'process'
|
||||
import { Cron } from 'croner'
|
||||
import process from 'node:process'
|
||||
|
||||
import { Config } from './config.js'
|
||||
import { logger } from './logger.js'
|
||||
import { loop } from './runner.js'
|
||||
|
||||
async function main() {
|
||||
const cron = schedule(Config.runner.cron, loop)
|
||||
logger.info('Started service.', { version: Config.version })
|
||||
logger.debug('Config', Config)
|
||||
const cron = new Cron(Config.runner.cron, { protect: true }, loop)
|
||||
logger.info('started service', { version: Config.version })
|
||||
logger.debug('config', Config)
|
||||
|
||||
const nextRun = cron.nextRun()
|
||||
if (nextRun) {
|
||||
const pretty = new Intl.DateTimeFormat(undefined, { dateStyle: 'long', timeStyle: 'long' }).format(nextRun)
|
||||
logger.info(`next run scheduled for ${pretty}`, { nextRunAt: nextRun })
|
||||
}
|
||||
|
||||
function terminate() {
|
||||
logger.info('Stopping service.')
|
||||
|
@@ -2,17 +2,19 @@ import { update } from './cloudflare.js'
|
||||
import { checkIfUpdateIsRequired, getCurrentIp } from './ip.js'
|
||||
import { logger } from './logger.js'
|
||||
|
||||
const l = logger.child({ context: 'runner' })
|
||||
|
||||
export async function loop() {
|
||||
const ip = await getCurrentIp()
|
||||
const changed = checkIfUpdateIsRequired(ip)
|
||||
logger.info(`Running. Update required: ${!!changed}`)
|
||||
l.info(`Running. Update required: ${!!changed}`)
|
||||
if (changed) {
|
||||
try {
|
||||
await update(ip)
|
||||
logger.info('Successfully updated DNS record')
|
||||
l.info('Successfully updated DNS record')
|
||||
} catch (e) {
|
||||
logger.error(e)
|
||||
logger.error('Failed to update DNS record')
|
||||
l.error(e)
|
||||
l.error('Failed to update DNS record')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
107
tsconfig.json
107
tsconfig.json
@@ -1,103 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "ES2022" /* Specify what module code is generated. */,
|
||||
"rootDir": "./src" /* Specify the root folder within your source files. */,
|
||||
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
"noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */,
|
||||
"strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */,
|
||||
"strictFunctionTypes": true /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */,
|
||||
"strictBindCallApply": true /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */,
|
||||
"strictPropertyInitialization": true /* Check for class properties that are declared but not set in the constructor. */,
|
||||
"noImplicitThis": true /* Enable error reporting when 'this' is given the type 'any'. */,
|
||||
"useUnknownInCatchVariables": true /* Default catch clause variables as 'unknown' instead of 'any'. */,
|
||||
"alwaysStrict": true /* Ensure 'use strict' is always emitted. */,
|
||||
"noUnusedLocals": true /* Enable error reporting when local variables aren't read. */,
|
||||
"noUnusedParameters": true /* Raise an error when a function parameter isn't read. */,
|
||||
"exactOptionalPropertyTypes": true /* Interpret optional property types as written, rather than adding 'undefined'. */,
|
||||
"noImplicitReturns": true /* Enable error reporting for codepaths that do not explicitly return in a function. */,
|
||||
"noFallthroughCasesInSwitch": true /* Enable error reporting for fallthrough cases in switch statements. */,
|
||||
"noUncheckedIndexedAccess": true /* Add 'undefined' to a type when accessed using an index. */,
|
||||
"noImplicitOverride": true /* Ensure overriding members in derived classes are marked with an override modifier. */,
|
||||
"noPropertyAccessFromIndexSignature": true /* Enforces using indexed accessors for keys declared using an indexed type. */,
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"rootDir": "./src",
|
||||
"moduleResolution": "Bundler",
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user