cfdns 2.1.2 → 2.1.3
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 +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +25 -0
- package/package.json +20 -22
- package/cfdns.js +0 -148
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# cfdns
|
|
2
|
-
[](https://www.npmjs.org/package/cfdns) [](https://www.npmjs.org/package/cfdns) [](https://travis-ci.org/silverwind/cfdns)
|
|
2
|
+
[](https://www.npmjs.org/package/cfdns) [](https://www.npmjs.org/package/cfdns) [](https://packagephobia.com/result?p=cfdns) [](https://travis-ci.org/silverwind/cfdns)
|
|
3
3
|
|
|
4
4
|
> CLI to modify DNS records hosted on Cloudflare
|
|
5
5
|
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import e,{argv as t,exit as n}from"node:process";import r,{homedir as i}from"node:os";import a from"node:tty";import{join as o}from"node:path";import{chmod as s,readFile as c,unlink as l,writeFile as ee}from"node:fs/promises";var u=Object.create,d=Object.defineProperty,f=Object.getOwnPropertyDescriptor,p=Object.getOwnPropertyNames,m=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty,g=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),_=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=p(t),a=0,o=i.length,s;a<o;a++)s=i[a],!h.call(e,s)&&s!==n&&d(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=f(t,s))||r.enumerable});return e},v=((e,t,n)=>(n=e==null?{}:u(m(e)),_(t||!e||!e.__esModule?d(n,`default`,{value:e,enumerable:!0}):n,e)))(g(((e,t)=>{function n(e,t){var n=e;return t.slice(0,-1).forEach(function(e){n=n[e]||{}}),t[t.length-1]in n}function r(e){return typeof e==`number`||/^0x[0-9a-f]+$/i.test(e)?!0:/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(e)}function i(e,t){return t===`constructor`&&typeof e[t]==`function`||t===`__proto__`}t.exports=function(e,t){t||={};var a={bools:{},strings:{},unknownFn:null};typeof t.unknown==`function`&&(a.unknownFn=t.unknown),typeof t.boolean==`boolean`&&t.boolean?a.allBools=!0:[].concat(t.boolean).filter(Boolean).forEach(function(e){a.bools[e]=!0});var o={};function s(e){return o[e].some(function(e){return a.bools[e]})}Object.keys(t.alias||{}).forEach(function(e){o[e]=[].concat(t.alias[e]),o[e].forEach(function(t){o[t]=[e].concat(o[e].filter(function(e){return t!==e}))})}),[].concat(t.string).filter(Boolean).forEach(function(e){a.strings[e]=!0,o[e]&&[].concat(o[e]).forEach(function(e){a.strings[e]=!0})});var c=t.default||{},l={_:[]};function ee(e,t){return a.allBools&&/^--[^=]+$/.test(t)||a.strings[e]||a.bools[e]||o[e]}function u(e,t,n){for(var r=e,o=0;o<t.length-1;o++){var s=t[o];if(i(r,s))return;r[s]===void 0&&(r[s]={}),(r[s]===Object.prototype||r[s]===Number.prototype||r[s]===String.prototype)&&(r[s]={}),r[s]===Array.prototype&&(r[s]=[]),r=r[s]}var c=t[t.length-1];i(r,c)||((r===Object.prototype||r===Number.prototype||r===String.prototype)&&(r={}),r===Array.prototype&&(r=[]),r[c]===void 0||a.bools[c]||typeof r[c]==`boolean`?r[c]=n:Array.isArray(r[c])?r[c].push(n):r[c]=[r[c],n])}function d(e,t,n){if(!(n&&a.unknownFn&&!ee(e,n)&&a.unknownFn(n)===!1)){var i=!a.strings[e]&&r(t)?Number(t):t;u(l,e.split(`.`),i),(o[e]||[]).forEach(function(e){u(l,e.split(`.`),i)})}}Object.keys(a.bools).forEach(function(e){d(e,c[e]===void 0?!1:c[e])});var f=[];e.indexOf(`--`)!==-1&&(f=e.slice(e.indexOf(`--`)+1),e=e.slice(0,e.indexOf(`--`)));for(var p=0;p<e.length;p++){var m=e[p],h,g;if(/^--.+=/.test(m)){var _=m.match(/^--([^=]+)=([\s\S]*)$/);h=_[1];var v=_[2];a.bools[h]&&(v=v!==`false`),d(h,v,m)}else if(/^--no-.+/.test(m))h=m.match(/^--no-(.+)/)[1],d(h,!1,m);else if(/^--.+/.test(m))h=m.match(/^--(.+)/)[1],g=e[p+1],g!==void 0&&!/^(-|--)[^-]/.test(g)&&!a.bools[h]&&!a.allBools&&(!o[h]||!s(h))?(d(h,g,m),p+=1):/^(true|false)$/.test(g)?(d(h,g===`true`,m),p+=1):d(h,a.strings[h]?``:!0,m);else if(/^-[^-]+/.test(m)){for(var y=m.slice(1,-1).split(``),b=!1,x=0;x<y.length;x++){if(g=m.slice(x+2),g===`-`){d(y[x],g,m);continue}if(/[A-Za-z]/.test(y[x])&&g[0]===`=`){d(y[x],g.slice(1),m),b=!0;break}if(/[A-Za-z]/.test(y[x])&&/-?\d+(\.\d*)?(e-?\d+)?$/.test(g)){d(y[x],g,m),b=!0;break}if(y[x+1]&&y[x+1].match(/\W/)){d(y[x],m.slice(x+2),m),b=!0;break}else d(y[x],a.strings[y[x]]?``:!0,m)}h=m.slice(-1)[0],!b&&h!==`-`&&(e[p+1]&&!/^(-|--)[^-]/.test(e[p+1])&&!a.bools[h]&&(!o[h]||!s(h))?(d(h,e[p+1],m),p+=1):e[p+1]&&/^(true|false)$/.test(e[p+1])?(d(h,e[p+1]===`true`,m),p+=1):d(h,a.strings[h]?``:!0,m))}else if((!a.unknownFn||a.unknownFn(m)!==!1)&&l._.push(a.strings._||!r(m)?m:Number(m)),t.stopEarly){l._.push.apply(l._,e.slice(p+1));break}}return Object.keys(c).forEach(function(e){n(l,e.split(`.`))||(u(l,e.split(`.`),c[e]),(o[e]||[]).forEach(function(t){u(l,t.split(`.`),c[e])}))}),t[`--`]?l[`--`]=f.slice():f.forEach(function(e){l._.push(e)}),l}}))(),1);const y=(e=0)=>t=>`\u001B[${t+e}m`,b=(e=0)=>t=>`\u001B[${38+e};5;${t}m`,x=(e=0)=>(t,n,r)=>`\u001B[${38+e};2;${t};${n};${r}m`,S={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};Object.keys(S.modifier);const te=Object.keys(S.color),ne=Object.keys(S.bgColor);[...te,...ne];function re(){let e=new Map;for(let[t,n]of Object.entries(S)){for(let[t,r]of Object.entries(n))S[t]={open:`\u001B[${r[0]}m`,close:`\u001B[${r[1]}m`},n[t]=S[t],e.set(r[0],r[1]);Object.defineProperty(S,t,{value:n,enumerable:!1})}return Object.defineProperty(S,"codes",{value:e,enumerable:!1}),S.color.close=`\x1B[39m`,S.bgColor.close=`\x1B[49m`,S.color.ansi=y(),S.color.ansi256=b(),S.color.ansi16m=x(),S.bgColor.ansi=y(10),S.bgColor.ansi256=b(10),S.bgColor.ansi16m=x(10),Object.defineProperties(S,{rgbToAnsi256:{value(e,t,n){return e===t&&t===n?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(t/255*5)+Math.round(n/255*5)},enumerable:!1},hexToRgb:{value(e){let t=/[a-f\d]{6}|[a-f\d]{3}/i.exec(e.toString(16));if(!t)return[0,0,0];let[n]=t;n.length===3&&(n=[...n].map(e=>e+e).join(``));let r=Number.parseInt(n,16);return[r>>16&255,r>>8&255,r&255]},enumerable:!1},hexToAnsi256:{value:e=>S.rgbToAnsi256(...S.hexToRgb(e)),enumerable:!1},ansi256ToAnsi:{value(e){if(e<8)return 30+e;if(e<16)return 90+(e-8);let t,n,r;if(e>=232)t=((e-232)*10+8)/255,n=t,r=t;else{e-=16;let i=e%36;t=Math.floor(e/36)/5,n=Math.floor(i/6)/5,r=i%6/5}let i=Math.max(t,n,r)*2;if(i===0)return 30;let a=30+(Math.round(r)<<2|Math.round(n)<<1|Math.round(t));return i===2&&(a+=60),a},enumerable:!1},rgbToAnsi:{value:(e,t,n)=>S.ansi256ToAnsi(S.rgbToAnsi256(e,t,n)),enumerable:!1},hexToAnsi:{value:e=>S.ansi256ToAnsi(S.hexToAnsi256(e)),enumerable:!1}}),S}const C=re();function w(t,n=globalThis.Deno?globalThis.Deno.args:e.argv){let r=t.startsWith(`-`)?``:t.length===1?`-`:`--`,i=n.indexOf(r+t),a=n.indexOf(`--`);return i!==-1&&(a===-1||i<a)}const{env:T}=e;let E;w(`no-color`)||w(`no-colors`)||w(`color=false`)||w(`color=never`)?E=0:(w(`color`)||w(`colors`)||w(`color=true`)||w(`color=always`))&&(E=1);function ie(){if(`FORCE_COLOR`in T)return T.FORCE_COLOR===`true`?1:T.FORCE_COLOR===`false`?0:T.FORCE_COLOR.length===0?1:Math.min(Number.parseInt(T.FORCE_COLOR,10),3)}function ae(e){return e===0?!1:{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function oe(t,{streamIsTTY:n,sniffFlags:i=!0}={}){let a=ie();a!==void 0&&(E=a);let o=i?E:a;if(o===0)return 0;if(i){if(w(`color=16m`)||w(`color=full`)||w(`color=truecolor`))return 3;if(w(`color=256`))return 2}if(`TF_BUILD`in T&&`AGENT_NAME`in T)return 1;if(t&&!n&&o===void 0)return 0;let s=o||0;if(T.TERM===`dumb`)return s;if(e.platform===`win32`){let e=r.release().split(`.`);return Number(e[0])>=10&&Number(e[2])>=10586?Number(e[2])>=14931?3:2:1}if(`CI`in T)return[`GITHUB_ACTIONS`,`GITEA_ACTIONS`,`CIRCLECI`].some(e=>e in T)?3:[`TRAVIS`,`APPVEYOR`,`GITLAB_CI`,`BUILDKITE`,`DRONE`].some(e=>e in T)||T.CI_NAME===`codeship`?1:s;if(`TEAMCITY_VERSION`in T)return+!!/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(T.TEAMCITY_VERSION);if(T.COLORTERM===`truecolor`||T.TERM===`xterm-kitty`||T.TERM===`xterm-ghostty`||T.TERM===`wezterm`)return 3;if(`TERM_PROGRAM`in T){let e=Number.parseInt((T.TERM_PROGRAM_VERSION||``).split(`.`)[0],10);switch(T.TERM_PROGRAM){case`iTerm.app`:return e>=3?3:2;case`Apple_Terminal`:return 2}}return/-256(color)?$/i.test(T.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(T.TERM)||`COLORTERM`in T?1:s}function D(e,t={}){return ae(oe(e,{streamIsTTY:e&&e.isTTY,...t}))}const se={stdout:D({isTTY:a.isatty(1)}),stderr:D({isTTY:a.isatty(2)})};function ce(e,t,n){let r=e.indexOf(t);if(r===-1)return e;let i=t.length,a=0,o=``;do o+=e.slice(a,r)+t+n,a=r+i,r=e.indexOf(t,a);while(r!==-1);return o+=e.slice(a),o}function le(e,t,n,r){let i=0,a=``;do{let o=e[r-1]===`\r`;a+=e.slice(i,o?r-1:r)+t+(o?`\r
|
|
3
|
+
`:`
|
|
4
|
+
`)+n,i=r+1,r=e.indexOf(`
|
|
5
|
+
`,i)}while(r!==-1);return a+=e.slice(i),a}const{stdout:O,stderr:k}=se,A=Symbol(`GENERATOR`),j=Symbol(`STYLER`),M=Symbol(`IS_EMPTY`),ue=[`ansi`,`ansi`,`ansi256`,`ansi16m`],N=Object.create(null),de=(e,t={})=>{if(t.level&&!(Number.isInteger(t.level)&&t.level>=0&&t.level<=3))throw Error("The `level` option should be an integer from 0 to 3");let n=O?O.level:0;e.level=t.level===void 0?n:t.level},fe=e=>{let t=(...e)=>e.join(` `);return de(t,e),Object.setPrototypeOf(t,P.prototype),t};function P(e){return fe(e)}Object.setPrototypeOf(P.prototype,Function.prototype);for(let[e,t]of Object.entries(C))N[e]={get(){let n=L(this,I(t.open,t.close,this[j]),this[M]);return Object.defineProperty(this,e,{value:n}),n}};N.visible={get(){let e=L(this,this[j],!0);return Object.defineProperty(this,"visible",{value:e}),e}};const F=(e,t,n,...r)=>e===`rgb`?t===`ansi16m`?C[n].ansi16m(...r):t===`ansi256`?C[n].ansi256(C.rgbToAnsi256(...r)):C[n].ansi(C.rgbToAnsi(...r)):e===`hex`?F(`rgb`,t,n,...C.hexToRgb(...r)):C[n][e](...r);for(let e of[`rgb`,`hex`,`ansi256`]){N[e]={get(){let{level:t}=this;return function(...n){let r=I(F(e,ue[t],`color`,...n),C.color.close,this[j]);return L(this,r,this[M])}}};let t=`bg`+e[0].toUpperCase()+e.slice(1);N[t]={get(){let{level:t}=this;return function(...n){let r=I(F(e,ue[t],`bgColor`,...n),C.bgColor.close,this[j]);return L(this,r,this[M])}}}}const pe=Object.defineProperties(()=>{},{...N,level:{enumerable:!0,get(){return this[A].level},set(e){this[A].level=e}}}),I=(e,t,n)=>{let r,i;return n===void 0?(r=e,i=t):(r=n.openAll+e,i=t+n.closeAll),{open:e,close:t,openAll:r,closeAll:i,parent:n}},L=(e,t,n)=>{let r=(...e)=>me(r,e.length===1?``+e[0]:e.join(` `));return Object.setPrototypeOf(r,pe),r[A]=e,r[j]=t,r[M]=n,r},me=(e,t)=>{if(e.level<=0||!t)return e[M]?``:t;let n=e[j];if(n===void 0)return t;let{openAll:r,closeAll:i}=n;if(t.includes(`\x1B`))for(;n!==void 0;)t=ce(t,n.close,n.open),n=n.parent;let a=t.indexOf(`
|
|
6
|
+
`);return a!==-1&&(t=le(t,i,r,a)),r+t+i};Object.defineProperties(P.prototype,N);const R=P();P({level:k?k.level:0});var he=`2.1.3`;const z=(0,v.default)(t.slice(2),{boolean:[`c`,`color`,`h`,`help`,`n`,`no-color`,`v`,`version`],string:[`_`],alias:{c:`color`,h:`help`,n:`no-color`,v:`version`}});function B(e){e&&console.info(`Error: ${e}`),n(+!!e)}z.version&&(console.info(he),B());const V={login:[2,2],logout:[0,0],get:[2,2],set:[3,4],add:[3,4],del:[2,2]},[H,...U]=z._,ge=H&&V[H]&&U.length>=V[H][0]&&U.length<=V[H][1];(!H||z.help||!Object.keys(V).includes(H)||!ge)&&(console.info(`usage: cfdns [options] command [args]
|
|
7
|
+
|
|
8
|
+
Commands:
|
|
9
|
+
login <email> <key> Log in to the API
|
|
10
|
+
get <name> <type> Retrieve a DNS record
|
|
11
|
+
set <name> <type> <value> [<ttl>] Create or update a DNS record
|
|
12
|
+
del <name> <type> Delete a DNS record
|
|
13
|
+
logout Log out from the API
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
-c, --color Force-enable color output
|
|
17
|
+
-n, --no-color Disable color output
|
|
18
|
+
-v, --version Print the version
|
|
19
|
+
-h, --help Print this help
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
$ cfdns login user@example.com 4c689aa3462a44a121c1f199c1081240b9be4
|
|
23
|
+
$ cfdns set example.com a 1.2.3.4 120
|
|
24
|
+
$ cfdns get example.com a
|
|
25
|
+
$ cfdns del example.com a`),B());let W,G;async function K(e,t,n){let r=await fetch(`https://api.cloudflare.com/client/v4/${t}`,{method:e.toUpperCase(),headers:{"Content-Type":`application/json`,"X-Auth-Email":W,"X-Auth-Key":G},body:n===void 0?void 0:JSON.stringify(n)}),i=await r.json();if(!r.ok)throw Error(`${r.status} ${r.statusText}: ${JSON.stringify(i)}`);return i.result}const q=o(i(),`.cfdnsrc`);if(H===`login`||H===`logout`){if(H===`login`)[W,G]=U,await ee(q,JSON.stringify({email:W,key:G})),await s(q,384),console.info(`login data saved`);else try{await l(q),console.info(`login data deleted`)}catch{console.info(`no login data found`)}B()}else try{({email:W,key:G}=JSON.parse(await c(q,`utf8`)))}catch{B(`login data not found, please log in first.`)}U[1]&&=U[1].toUpperCase();let[J,Y,X,Z]=U;Z||=120,typeof Z==`string`&&(Z=Number(Z));const Q=(await K(`get`,`zones`)).find(e=>J.endsWith(e.name));Q||B(`no matching zone found`);const $=(await K(`get`,`zones/${Q.id}/dns_records?name=${J}&type=${Y}`))[0];H===`get`?console.info($):H===`set`||H===`add`?$?X!==$.content||Z!==$.ttl?(await K(`put`,`zones/${Q.id}/dns_records/${$.id}`,{name:J,type:Y,content:X,ttl:Z,proxied:$.proxied}),console.info(`updated ${R.magenta(J)} ${Z} IN ${Y} ${R.green(X)}`)):console.info(`${R.magenta(J)} is up to date`):(await K(`post`,`zones/${Q.id}/dns_records`,{name:J,type:Y,content:X,ttl:Z,proxied:!1}),console.info(`created ${R.magenta(J)} ${Z} IN ${Y} ${R.green(X)}`)):H===`del`&&$&&(await K(`delete`,`zones/${Q.id}/dns_records/${$.id}`),console.info(`deleted ${R.magenta(J)} ${$.ttl} IN ${Y} ${R.green($.content)}`)),B();export{};
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cfdns",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"description": "CLI to modify DNS records hosted on Cloudflare",
|
|
5
5
|
"author": "silverwind <me@silverwind.io>",
|
|
6
6
|
"repository": "silverwind/cfdns",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"sideEffects": false,
|
|
8
9
|
"license": "BSD-2-Clause",
|
|
10
|
+
"bin": "./dist/index.js",
|
|
9
11
|
"engines": {
|
|
10
|
-
"node": ">=
|
|
11
|
-
|
|
12
|
-
"bin": {
|
|
13
|
-
"cfdns": "cfdns.js"
|
|
12
|
+
"node": ">=22",
|
|
13
|
+
"bun": "*"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
|
-
"
|
|
16
|
+
"dist"
|
|
17
17
|
],
|
|
18
18
|
"keywords": [
|
|
19
19
|
"cloudflare",
|
|
@@ -23,22 +23,20 @@
|
|
|
23
23
|
"record",
|
|
24
24
|
"ddns"
|
|
25
25
|
],
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"chalk": "5.6.2",
|
|
28
|
-
"fs-extra": "^11.3.3",
|
|
29
|
-
"minimist": "^1.2.8",
|
|
30
|
-
"request": "^2.88.2",
|
|
31
|
-
"request-promise-native": "^1.0.9",
|
|
32
|
-
"ver": "6.0.2"
|
|
33
|
-
},
|
|
34
26
|
"devDependencies": {
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"typescript-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
27
|
+
"@types/minimist": "1.2.5",
|
|
28
|
+
"@types/node": "25.8.0",
|
|
29
|
+
"@typescript/native-preview": "7.0.0-dev.20260515.1",
|
|
30
|
+
"chalk": "5.6.2",
|
|
31
|
+
"eslint": "10.4.0",
|
|
32
|
+
"eslint-config-silverwind": "133.0.2",
|
|
33
|
+
"minimist": "1.2.8",
|
|
34
|
+
"tsdown": "0.22.0",
|
|
35
|
+
"tsdown-config-silverwind": "3.0.1",
|
|
36
|
+
"typescript": "6.0.3",
|
|
37
|
+
"typescript-config-silverwind": "18.0.0",
|
|
38
|
+
"updates": "17.16.12",
|
|
39
|
+
"updates-config-silverwind": "3.0.2",
|
|
40
|
+
"versions": "15.0.4"
|
|
43
41
|
}
|
|
44
42
|
}
|
package/cfdns.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import minimist from "minimist";
|
|
3
|
-
import request from "request-promise-native";
|
|
4
|
-
import chalk from "chalk";
|
|
5
|
-
import fs from "fs-extra";
|
|
6
|
-
import {join} from "node:path";
|
|
7
|
-
import {homedir} from "node:os";
|
|
8
|
-
import {readFileSync} from "node:fs";
|
|
9
|
-
|
|
10
|
-
const pkg = JSON.parse(readFileSync(new URL("package.json", import.meta.url)));
|
|
11
|
-
|
|
12
|
-
const args = minimist(process.argv.slice(2), {
|
|
13
|
-
boolean: [
|
|
14
|
-
"c", "color",
|
|
15
|
-
"h", "help",
|
|
16
|
-
"n", "no-color",
|
|
17
|
-
"v", "version",
|
|
18
|
-
],
|
|
19
|
-
string: [
|
|
20
|
-
"_",
|
|
21
|
-
],
|
|
22
|
-
alias: {
|
|
23
|
-
c: "color",
|
|
24
|
-
h: "help",
|
|
25
|
-
n: "no-color",
|
|
26
|
-
v: "version",
|
|
27
|
-
},
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
function exit(err) {
|
|
31
|
-
if (err) console.info(`Error: ${err}`);
|
|
32
|
-
process.exit(err ? 1 : 0);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (args.version) {
|
|
36
|
-
console.info(pkg.version);
|
|
37
|
-
exit();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const cmds = {
|
|
41
|
-
login: [2, 2],
|
|
42
|
-
logout: [0, 0],
|
|
43
|
-
get: [2, 2],
|
|
44
|
-
set: [3, 4],
|
|
45
|
-
add: [3, 4],
|
|
46
|
-
del: [2, 2],
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const [cmd, ...params] = args._;
|
|
50
|
-
const paramLengthOkay = cmd && cmds[cmd] && (params.length >= cmds[cmd][0] && params.length <= cmds[cmd][1]);
|
|
51
|
-
if (!cmd || args.help || !Object.keys(cmds).includes(cmd) || !paramLengthOkay) {
|
|
52
|
-
console.info(`usage: cfdns [options] command [args]
|
|
53
|
-
|
|
54
|
-
Commands:
|
|
55
|
-
login <email> <key> Log in to the API
|
|
56
|
-
get <name> <type> Retrieve a DNS record
|
|
57
|
-
set <name> <type> <value> [<ttl>] Create or update a DNS record
|
|
58
|
-
del <name> <type> Delete a DNS record
|
|
59
|
-
logout Log out from the API
|
|
60
|
-
|
|
61
|
-
Options:
|
|
62
|
-
-c, --color Force-enable color output
|
|
63
|
-
-n, --no-color Disable color output
|
|
64
|
-
-v, --version Print the version
|
|
65
|
-
-h, --help Print this help
|
|
66
|
-
|
|
67
|
-
Example:
|
|
68
|
-
$ cfdns login user@example.com 4c689aa3462a44a121c1f199c1081240b9be4
|
|
69
|
-
$ cfdns set example.com a 1.2.3.4 120
|
|
70
|
-
$ cfdns get example.com a
|
|
71
|
-
$ cfdns del example.com a`);
|
|
72
|
-
exit();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
let email, key;
|
|
76
|
-
|
|
77
|
-
async function req(method, path, body) {
|
|
78
|
-
return (await request({
|
|
79
|
-
method: method.toUpperCase(),
|
|
80
|
-
json: true,
|
|
81
|
-
uri: `https://api.cloudflare.com/client/v4/${path}`,
|
|
82
|
-
headers: {
|
|
83
|
-
"X-Auth-Email": email,
|
|
84
|
-
"X-Auth-Key": key,
|
|
85
|
-
},
|
|
86
|
-
body,
|
|
87
|
-
})).result;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
(async () => {
|
|
91
|
-
const rcfile = join(homedir(), ".cfdnsrc");
|
|
92
|
-
|
|
93
|
-
if (cmd === "login" || cmd === "logout") {
|
|
94
|
-
if (cmd === "login") {
|
|
95
|
-
[email, key] = params;
|
|
96
|
-
await fs.writeFile(rcfile, JSON.stringify({email, key}));
|
|
97
|
-
await fs.chmod(rcfile, 0o600);
|
|
98
|
-
console.info("login data saved");
|
|
99
|
-
} else {
|
|
100
|
-
try {
|
|
101
|
-
await fs.unlink(rcfile);
|
|
102
|
-
console.info("login data deleted");
|
|
103
|
-
} catch {
|
|
104
|
-
console.info("no login data found");
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
exit();
|
|
108
|
-
} else {
|
|
109
|
-
try {
|
|
110
|
-
({email, key} = JSON.parse(await fs.readFile(rcfile)));
|
|
111
|
-
} catch {
|
|
112
|
-
exit("login data not found, please log in first.");
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (params[1]) params[1] = params[1].toUpperCase();
|
|
117
|
-
let [name, type, content, ttl] = params;
|
|
118
|
-
if (!ttl) ttl = 120;
|
|
119
|
-
if (typeof ttl === "string") ttl = Number(ttl);
|
|
120
|
-
const zones = await req("get", "zones");
|
|
121
|
-
const zone = zones.find(zone => name.endsWith(zone.name));
|
|
122
|
-
if (!zone) exit("no matching zone found");
|
|
123
|
-
|
|
124
|
-
const record = (await req("get", `zones/${zone.id}/dns_records?name=${name}&type=${type}`))[0];
|
|
125
|
-
if (cmd === "get") {
|
|
126
|
-
console.info(record);
|
|
127
|
-
} else if (cmd === "set" || cmd === "add") {
|
|
128
|
-
if (record) {
|
|
129
|
-
if (content !== record.content || ttl !== record.ttl) {
|
|
130
|
-
await req("put", `zones/${zone.id}/dns_records/${record.id}`, {
|
|
131
|
-
name, type, content, ttl, proxied: record.proxied
|
|
132
|
-
});
|
|
133
|
-
console.info(`updated ${chalk.magenta(name)} ${ttl} IN ${type} ${chalk.green(content)}`);
|
|
134
|
-
} else {
|
|
135
|
-
console.info(`${chalk.magenta(name)} is up to date`);
|
|
136
|
-
}
|
|
137
|
-
} else {
|
|
138
|
-
await req("post", `zones/${zone.id}/dns_records`, {
|
|
139
|
-
name, type, content, ttl, proxied: false
|
|
140
|
-
});
|
|
141
|
-
console.info(`created ${chalk.magenta(name)} ${ttl} IN ${type} ${chalk.green(content)}`);
|
|
142
|
-
}
|
|
143
|
-
} else if (cmd === "del" && record) {
|
|
144
|
-
await req("delete", `zones/${zone.id}/dns_records/${record.id}`);
|
|
145
|
-
console.info(`deleted ${chalk.magenta(name)} ${record.ttl} IN ${type} ${chalk.green(record.content)}`);
|
|
146
|
-
}
|
|
147
|
-
exit();
|
|
148
|
-
})();
|