Compare commits
57 Commits
Author | SHA1 | Date | |
---|---|---|---|
4600749442 | |||
b0f8d1e4d0 | |||
902ca30529 | |||
5731150157 | |||
f39f8cd33c | |||
1d2e0974b2 | |||
801f86fede | |||
42feb09b4f | |||
d72bb28cf9 | |||
b9f0b798c9 | |||
9b5f42ef9b | |||
4e3355dc43 | |||
fc0a27f5b6 | |||
0248d52548 | |||
c3984819cc | |||
045b87a4a2 | |||
48ca9fdbb9 | |||
e466944c55 | |||
6d8deca9d4 | |||
a4518f3068 | |||
9e338354c6 | |||
9d8c14d187 | |||
5a0b12f6aa | |||
387f00078f | |||
fe2f45e3a9 | |||
90c9bfc906 | |||
4f9e81f612 | |||
a4e280f9f0 | |||
52bd80aebd | |||
15e3cdae83 | |||
c72147b469 | |||
d98c2f89c5 | |||
2b722816f6 | |||
91d58277dd | |||
2458da6754 | |||
d4379d19d3 | |||
b0fdd520f3 | |||
a746577945 | |||
bc4cae3333 | |||
e0614b5956 | |||
f568949085 | |||
bee256416f | |||
afa2679501 | |||
7838642fd5 | |||
7a992badf4 | |||
c65790e2f9 | |||
7ec0fe78fc | |||
12f4456ebd | |||
3e8cf73877 | |||
0032292714 | |||
ead87ceb63 | |||
04d70a4d12 | |||
8da43a79d3 | |||
3153021190 | |||
82701c19e7 | |||
d3a68b4fef | |||
c4c1367306 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -15,8 +15,6 @@ node_modules/
|
|||||||
|
|
||||||
# builds
|
# builds
|
||||||
dist/
|
dist/
|
||||||
dist_web/
|
dist_*/
|
||||||
dist_serve/
|
|
||||||
dist_ts_web/
|
|
||||||
|
|
||||||
# custom
|
# custom
|
117
.gitlab-ci.yml
117
.gitlab-ci.yml
@ -1,117 +0,0 @@
|
|||||||
# gitzone ci_default
|
|
||||||
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
|
||||||
|
|
||||||
cache:
|
|
||||||
paths:
|
|
||||||
- .npmci_cache/
|
|
||||||
key: "$CI_BUILD_STAGE"
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- security
|
|
||||||
- test
|
|
||||||
- release
|
|
||||||
- metadata
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# security stage
|
|
||||||
# ====================
|
|
||||||
mirror:
|
|
||||||
stage: security
|
|
||||||
script:
|
|
||||||
- npmci git mirror
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
snyk:
|
|
||||||
stage: security
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci command npm install -g snyk
|
|
||||||
- npmci command npm install --ignore-scripts
|
|
||||||
- npmci command snyk test
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# test stage
|
|
||||||
# ====================
|
|
||||||
|
|
||||||
testLTS:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci node install lts
|
|
||||||
- npmci npm install
|
|
||||||
- npmci npm test
|
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
testBuild:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci node install lts
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command npm run build
|
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
release:
|
|
||||||
stage: release
|
|
||||||
script:
|
|
||||||
- npmci node install lts
|
|
||||||
- npmci npm publish
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# metadata stage
|
|
||||||
# ====================
|
|
||||||
codequality:
|
|
||||||
stage: metadata
|
|
||||||
allow_failure: true
|
|
||||||
script:
|
|
||||||
- npmci command npm install -g tslint typescript
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- priv
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
stage: metadata
|
|
||||||
script:
|
|
||||||
- npmci trigger
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
pages:
|
|
||||||
image: hosttoday/ht-docker-node:npmci
|
|
||||||
stage: metadata
|
|
||||||
script:
|
|
||||||
- npmci command npm install -g @gitzone/tsdoc
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command tsdoc
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
paths:
|
|
||||||
- public
|
|
||||||
allow_failure: true
|
|
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"command": "npm test",
|
||||||
|
"name": "Run npm test",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "node-terminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
.vscode/settings.json
vendored
Normal file
26
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"json.schemas": [
|
||||||
|
{
|
||||||
|
"fileMatch": ["/npmextra.json"],
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"npmci": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for npmci"
|
||||||
|
},
|
||||||
|
"gitzone": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for gitzone",
|
||||||
|
"properties": {
|
||||||
|
"projectType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["website", "element", "service", "npm", "wcc"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
50
README.md
50
README.md
@ -1,50 +0,0 @@
|
|||||||
# @mojoio/cloudflare
|
|
||||||
easy cloudflare management
|
|
||||||
|
|
||||||
## Availabililty and Links
|
|
||||||
* [npmjs.org (npm package)](https://www.npmjs.com/package/@mojoio/cloudflare)
|
|
||||||
* [gitlab.com (source)](https://gitlab.com/mojoio/cloudflare)
|
|
||||||
* [github.com (source mirror)](https://github.com/mojoio/cloudflare)
|
|
||||||
* [docs (typedoc)](https://mojoio.gitlab.io/cloudflare/)
|
|
||||||
|
|
||||||
## Status for master
|
|
||||||
[](https://gitlab.com/mojoio/cloudflare/commits/master)
|
|
||||||
[](https://gitlab.com/mojoio/cloudflare/commits/master)
|
|
||||||
[](https://www.npmjs.com/package/@mojoio/cloudflare)
|
|
||||||
[](https://snyk.io/test/npm/@mojoio/cloudflare)
|
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
|
||||||
[](https://prettier.io/)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Use TypeScript for best in class instellisense.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import * as cflare from 'cflare'
|
|
||||||
|
|
||||||
let myCflareAccount = new cflare.CflareAccount()
|
|
||||||
testCflareAccount.auth({
|
|
||||||
email: 'someuser@example.com',
|
|
||||||
key: 'someLongApiKey'
|
|
||||||
})
|
|
||||||
|
|
||||||
let myAsyncCflareManagement = async () => {
|
|
||||||
// get things
|
|
||||||
let myZones = await myCflareAccount.listZones() // zones are fully typed
|
|
||||||
let myIdForADomain = await myCflareAccount.getZoneId('example.com') // type number
|
|
||||||
let myRecordsForADomain = await myCflareAccount.listRecords('example.com') // records are fully typed
|
|
||||||
|
|
||||||
// set things
|
|
||||||
myCflareAccount.updateRecord(...)
|
|
||||||
myCflareAccount.createRecord(...)
|
|
||||||
myCflareAccount.deleteRecord(...)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For further information read the linked docs at the top of this readme.
|
|
||||||
|
|
||||||
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
|
||||||
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
|
|
||||||
|
|
||||||
[](https://maintainedby.lossless.com)
|
|
@ -1,6 +1,4 @@
|
|||||||
The MIT License (MIT)
|
Copyright (c) 2014 Task Venture Capital GmbH (hello@task.vc)
|
||||||
|
|
||||||
Copyright (c) 2016 Lossless GmbH
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
@ -4,13 +4,26 @@
|
|||||||
"npmAccessLevel": "public"
|
"npmAccessLevel": "public"
|
||||||
},
|
},
|
||||||
"gitzone": {
|
"gitzone": {
|
||||||
|
"projectType": "npm",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "gitlab.com",
|
"githost": "gitlab.com",
|
||||||
"gitscope": "mojoio",
|
"gitscope": "mojoio",
|
||||||
"gitrepo": "cloudflare",
|
"gitrepo": "cloudflare",
|
||||||
"shortDescription": "easy cloudflare management",
|
"description": "A TypeScript client for managing Cloudflare accounts, zones, DNS records, and workers with ease.",
|
||||||
"npmPackagename": "@mojoio/cloudflare",
|
"npmPackagename": "@apiclient.xyz/cloudflare",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"Cloudflare",
|
||||||
|
"DNS management",
|
||||||
|
"zone management",
|
||||||
|
"worker management",
|
||||||
|
"TypeScript",
|
||||||
|
"API client",
|
||||||
|
"cloud infrastructure",
|
||||||
|
"automated DNS",
|
||||||
|
"CDN management",
|
||||||
|
"open source"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
1865
package-lock.json
generated
1865
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
71
package.json
71
package.json
@ -1,21 +1,32 @@
|
|||||||
{
|
{
|
||||||
"name": "@mojoio/cloudflare",
|
"name": "@apiclient.xyz/cloudflare",
|
||||||
"version": "3.0.3",
|
"version": "6.0.5",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "easy cloudflare management",
|
"description": "A TypeScript client for managing Cloudflare accounts, zones, DNS records, and workers with ease.",
|
||||||
"main": "dist/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(tstest test/)",
|
"test": "(tstest test/)",
|
||||||
"build": "(tsbuild)"
|
"build": "(tsbuild --web --allowimplicitany)",
|
||||||
|
"buildDocs": "tsdoc",
|
||||||
|
"updateOpenapi": "openapi-typescript https://raw.githubusercontent.com/cloudflare/api-schemas/main/openapi.yaml --output ts/openapi.spec.ts"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://gitlab.com/pushrocks/cflare.git"
|
"url": "git+https://gitlab.com/pushrocks/cflare.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Push.Rocks",
|
"Cloudflare",
|
||||||
"cloudflare"
|
"DNS management",
|
||||||
|
"zone management",
|
||||||
|
"worker management",
|
||||||
|
"TypeScript",
|
||||||
|
"API client",
|
||||||
|
"cloud infrastructure",
|
||||||
|
"automated DNS",
|
||||||
|
"CDN management",
|
||||||
|
"open source"
|
||||||
],
|
],
|
||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -24,32 +35,36 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/pushrocks/cflare#readme",
|
"homepage": "https://gitlab.com/pushrocks/cflare#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pushrocks/smartdelay": "^2.0.3",
|
"@push.rocks/smartdelay": "^3.0.1",
|
||||||
"@pushrocks/smartlog": "^2.0.19",
|
"@push.rocks/smartlog": "^3.0.2",
|
||||||
"@pushrocks/smartpromise": "^3.0.2",
|
"@push.rocks/smartpromise": "^4.0.2",
|
||||||
"@pushrocks/smartrequest": "^1.1.16",
|
"@push.rocks/smartrequest": "^2.0.15",
|
||||||
"@pushrocks/smartstring": "^3.0.10",
|
"@push.rocks/smartstring": "^4.0.5",
|
||||||
"@tsclass/tsclass": "^2.0.1"
|
"@tsclass/tsclass": "^4.0.58",
|
||||||
|
"cloudflare": "^3.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gitzone/tsbuild": "^2.1.11",
|
"@git.zone/tsbuild": "^2.1.66",
|
||||||
"@gitzone/tsrun": "^1.2.8",
|
"@git.zone/tsrun": "^1.2.42",
|
||||||
"@gitzone/tstest": "^1.0.24",
|
"@git.zone/tstest": "^1.0.74",
|
||||||
"@pushrocks/qenv": "^4.0.0",
|
"@push.rocks/qenv": "^6.0.5",
|
||||||
"@pushrocks/tapbundle": "^3.0.11",
|
"@push.rocks/tapbundle": "^5.0.4",
|
||||||
"@types/node": "^12.6.6",
|
"@types/node": "^20.3.1",
|
||||||
"tslint": "^5.18.0",
|
"openapi-typescript": "^6.7.6"
|
||||||
"tslint-config-prettier": "^1.18.0"
|
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/*",
|
"ts/**/*",
|
||||||
"ts_web/*",
|
"ts_web/**/*",
|
||||||
"dist/*",
|
"dist/**/*",
|
||||||
"dist_web/*",
|
"dist_*/**/*",
|
||||||
"dist_ts_web/*",
|
"dist_ts/**/*",
|
||||||
"assets/*",
|
"dist_ts_web/**/*",
|
||||||
|
"assets/**/*",
|
||||||
"cli.js",
|
"cli.js",
|
||||||
"npmextra.json",
|
"npmextra.json",
|
||||||
"readme.md"
|
"readme.md"
|
||||||
|
],
|
||||||
|
"browserslist": [
|
||||||
|
"last 1 chrome versions"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
6877
pnpm-lock.yaml
generated
Normal file
6877
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
1
readme.hints.md
Normal file
1
readme.hints.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
- unofficial TypeScript cloudflare api client coming with a lot of convenience.
|
250
readme.md
Normal file
250
readme.md
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
# @apiclient.xyz/cloudflare
|
||||||
|
easy cloudflare management
|
||||||
|
|
||||||
|
## Install
|
||||||
|
To install the `@apiclient.xyz/cloudflare` package, you can use npm. Simply run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @apiclient.xyz/cloudflare
|
||||||
|
```
|
||||||
|
|
||||||
|
Make sure to include it in your `dependencies` in `package.json`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Initial Setup
|
||||||
|
|
||||||
|
First, let's start by importing the required modules and setting up an instance of `CloudflareAccount` with your API token. This instance will be used to interact with the Cloudflare API.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import * as cflare from '@apiclient.xyz/cloudflare';
|
||||||
|
|
||||||
|
// Initialize Cloudflare Account
|
||||||
|
const myCflareAccount = new cflare.CloudflareAccount('mySuperAwesomeAccountToken');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Managing Zones
|
||||||
|
|
||||||
|
#### List All Zones
|
||||||
|
|
||||||
|
To list all zones in your Cloudflare account, you can use the `listZones` method:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const listAllZones = async () => {
|
||||||
|
const myZones = await myCflareAccount.convenience.listZones();
|
||||||
|
console.log(myZones);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Get Zone ID
|
||||||
|
|
||||||
|
To get the ID of a specific zone (domain), use the `getZoneId` method:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const getZoneId = async (domainName: string) => {
|
||||||
|
try {
|
||||||
|
const zoneId = await myCflareAccount.convenience.getZoneId(domainName);
|
||||||
|
console.log(`Zone ID for ${domainName}:`, zoneId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error getting zone ID:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Purge Cache for a Zone
|
||||||
|
|
||||||
|
To purge all cache for a specific zone:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const purgeZoneCache = async (domainName: string) => {
|
||||||
|
await myCflareAccount.convenience.purgeZone(domainName);
|
||||||
|
console.log(`Purged cache for ${domainName}`);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Managing DNS Records
|
||||||
|
|
||||||
|
#### List DNS Records
|
||||||
|
|
||||||
|
To list all DNS records for a specific zone:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const listDnsRecords = async (domainName: string) => {
|
||||||
|
try {
|
||||||
|
const records = await myCflareAccount.convenience.listRecords(domainName);
|
||||||
|
console.log(`DNS Records for ${domainName}:`, records);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error listing DNS records:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Get a Specific Record
|
||||||
|
|
||||||
|
To get a specific DNS record by type (e.g., A, AAAA, CNAME, etc.):
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const getDnsRecord = async (domainName: string, recordType: string) => {
|
||||||
|
try {
|
||||||
|
const record = await myCflareAccount.convenience.getRecord(domainName, recordType);
|
||||||
|
console.log(`DNS Record (${recordType}) for ${domainName}:`, record);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error getting DNS record:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Create a DNS Record
|
||||||
|
|
||||||
|
To create a new DNS record:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const createDnsRecord = async (domainName: string, recordType: string, content: string) => {
|
||||||
|
try {
|
||||||
|
const response = await myCflareAccount.convenience.createRecord(domainName, recordType, content, 120);
|
||||||
|
console.log(`Created DNS record (${recordType}) for ${domainName}:`, response);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating DNS record:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Remove a DNS Record
|
||||||
|
|
||||||
|
To remove a DNS record:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const removeDnsRecord = async (domainName: string, recordType: string) => {
|
||||||
|
try {
|
||||||
|
await myCflareAccount.convenience.removeRecord(domainName, recordType);
|
||||||
|
console.log(`Removed DNS record (${recordType}) for ${domainName}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error removing DNS record:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Clean a DNS Record
|
||||||
|
|
||||||
|
To clean (remove) all records of a specific type for a domain:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const cleanDnsRecord = async (domainName: string, recordType: string) => {
|
||||||
|
try {
|
||||||
|
await myCflareAccount.convenience.cleanRecord(domainName, recordType);
|
||||||
|
console.log(`Cleaned DNS records (${recordType}) for ${domainName}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error cleaning DNS record:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Managing Workers
|
||||||
|
|
||||||
|
#### Create a Worker
|
||||||
|
|
||||||
|
To create a new Cloudflare Worker:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const createWorker = async (workerName: string, workerScript: string) => {
|
||||||
|
try {
|
||||||
|
const worker = await myCflareAccount.workerManager.createWorker(workerName, workerScript);
|
||||||
|
console.log(`Created Worker (${workerName}):`, worker);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating Worker:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### List Workers
|
||||||
|
|
||||||
|
To list all workers in your Cloudflare account:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const listWorkers = async () => {
|
||||||
|
try {
|
||||||
|
const workers = await myCflareAccount.workerManager.listWorkers();
|
||||||
|
console.log('Workers:', workers);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error listing workers:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Set Worker Routes
|
||||||
|
|
||||||
|
To set routes for a Cloudflare Worker:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { CloudflareWorker } from '@apiclient.xyz/cloudflare';
|
||||||
|
|
||||||
|
const setWorkerRoutes = async (worker: CloudflareWorker, routes: Array<{ zoneName: string, pattern: string }>) => {
|
||||||
|
try {
|
||||||
|
await worker.setRoutes(routes);
|
||||||
|
console.log('Routes set successfully for Worker:', worker.id);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error setting routes for Worker:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sample Complete Workflow
|
||||||
|
|
||||||
|
Below is a sample workflow that includes all the above features:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import * as cflare from '@apiclient.xyz/cloudflare';
|
||||||
|
|
||||||
|
const myCflareAccount = new cflare.CloudflareAccount('mySuperAwesomeAccountToken');
|
||||||
|
|
||||||
|
const manageCloudflare = async () => {
|
||||||
|
try {
|
||||||
|
// List all zones
|
||||||
|
const myZones = await myCflareAccount.convenience.listZones();
|
||||||
|
console.log('Zones:', myZones);
|
||||||
|
|
||||||
|
// Get Zone ID for a specific domain
|
||||||
|
const myZoneId = await myCflareAccount.convenience.getZoneId('example.com');
|
||||||
|
console.log('Zone ID:', myZoneId);
|
||||||
|
|
||||||
|
// Purge cache for a zone
|
||||||
|
await myCflareAccount.convenience.purgeZone('example.com');
|
||||||
|
console.log('Cache purged for example.com');
|
||||||
|
|
||||||
|
// List DNS records for a domain
|
||||||
|
const myRecords = await myCflareAccount.convenience.listRecords('example.com');
|
||||||
|
console.log('DNS Records:', myRecords);
|
||||||
|
|
||||||
|
// Get a specific DNS record
|
||||||
|
const myRecord = await myCflareAccount.convenience.getRecord('sub.example.com', 'A');
|
||||||
|
console.log('Specific DNS Record:', myRecord);
|
||||||
|
|
||||||
|
// Create a DNS record
|
||||||
|
const createResponse = await myCflareAccount.convenience.createRecord('sub.example.com', 'A', '127.0.0.1');
|
||||||
|
console.log('Created DNS Record:', createResponse);
|
||||||
|
|
||||||
|
// Clean DNS records
|
||||||
|
await myCflareAccount.convenience.cleanRecord('sub.example.com', 'A');
|
||||||
|
console.log('Cleaned DNS Records for sub.example.com');
|
||||||
|
|
||||||
|
// Create a Cloudflare Worker
|
||||||
|
const myWorker = await myCflareAccount.workerManager.createWorker('myWorker', `addEventListener('fetch', event => { event.respondWith(fetch(event.request)) })`);
|
||||||
|
console.log('Created Worker:', myWorker);
|
||||||
|
|
||||||
|
// Set routes for the Worker
|
||||||
|
await myWorker.setRoutes([{ zoneName: 'example.com', pattern: 'https://*example.com/*' }]);
|
||||||
|
console.log('Routes set for Worker');
|
||||||
|
|
||||||
|
// List all Workers
|
||||||
|
const workers = await myCflareAccount.workerManager.listWorkers();
|
||||||
|
console.log('Workers:', workers);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error managing Cloudflare:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
manageCloudflare();
|
||||||
|
```
|
||||||
|
|
||||||
|
This complete guide covers initialization, managing Cloudflare zones, DNS records, and Cloudflare Workers comprehensively using TypeScript for enhanced type safety and intellisense. Always ensure to keep your API keys secure and avoid hardcoding them directly in your scripts.
|
||||||
|
undefined
|
70
test/test.ts
70
test/test.ts
@ -1,9 +1,9 @@
|
|||||||
// tslint:disable-next-line: no-implicit-dependencies
|
// tslint:disable-next-line: no-implicit-dependencies
|
||||||
import { expect, tap } from '@pushrocks/tapbundle';
|
import { expect, tap } from '@push.rocks/tapbundle';
|
||||||
// tslint:disable-next-line: no-implicit-dependencies
|
// tslint:disable-next-line: no-implicit-dependencies
|
||||||
import { Qenv } from '@pushrocks/qenv';
|
import { Qenv } from '@push.rocks/qenv';
|
||||||
|
|
||||||
import cloudflare = require('../ts/index');
|
import * as cloudflare from '../ts/index.js';
|
||||||
|
|
||||||
const testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit');
|
const testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit');
|
||||||
|
|
||||||
@ -11,77 +11,93 @@ const randomPrefix = Math.floor(Math.random() * 2000);
|
|||||||
let testCloudflareAccount: cloudflare.CloudflareAccount;
|
let testCloudflareAccount: cloudflare.CloudflareAccount;
|
||||||
|
|
||||||
tap.test('should create a valid instance of CloudflareAccount', async () => {
|
tap.test('should create a valid instance of CloudflareAccount', async () => {
|
||||||
testCloudflareAccount = new cloudflare.CloudflareAccount({
|
testCloudflareAccount = new cloudflare.CloudflareAccount(await testQenv.getEnvVarOnDemand('CF_KEY'));
|
||||||
email: testQenv.getEnvVarOnDemand('CF_EMAIL'),
|
|
||||||
key: testQenv.getEnvVarOnDemand('CF_KEY')
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('should preselect an account', async () => {
|
||||||
|
await testCloudflareAccount.preselectAccountByName('Sandbox Account');
|
||||||
|
})
|
||||||
|
|
||||||
|
tap.test('.listZones() -> should display an entire account', async (tools) => {
|
||||||
tap.skip.test('.listZones() -> should display an entire account', async tools => {
|
|
||||||
tools.timeout(600000);
|
tools.timeout(600000);
|
||||||
const result = await testCloudflareAccount.listZones();
|
const result = await testCloudflareAccount.convenience.listZones();
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
// await tools.delayFor(10000);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test(
|
tap.test(
|
||||||
'.getZoneId(domainName) -> should get an Cloudflare Id for a domain string',
|
'.getZoneId(domainName) -> should get an Cloudflare Id for a domain string',
|
||||||
async tools => {
|
async (tools) => {
|
||||||
tools.timeout(600000);
|
tools.timeout(600000);
|
||||||
await testCloudflareAccount.getZoneId('bleu.de');
|
const id = await testCloudflareAccount.convenience.getZoneId('bleu.de');
|
||||||
|
console.log(`The account id for bleu.de is: ${id}`);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
tap.test(
|
tap.test(
|
||||||
'.listRecords(domainName) -> should list all records for a specific Domain Name',
|
'.listRecords(domainName) -> should list all records for a specific Domain Name',
|
||||||
async tools => {
|
async (tools) => {
|
||||||
tools.timeout(600000);
|
tools.timeout(600000);
|
||||||
await testCloudflareAccount.listRecords('bleu.de').then(async responseArg => {
|
await testCloudflareAccount.convenience.listRecords('bleu.de').then(async (responseArg) => {
|
||||||
console.log(responseArg);
|
console.log(responseArg);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
tap.test('should create a valid record for a subdomain', async tools => {
|
tap.test('should create a valid record for a subdomain', async (tools) => {
|
||||||
tools.timeout(600000);
|
tools.timeout(600000);
|
||||||
await testCloudflareAccount.createRecord(`${randomPrefix}subdomain.bleu.de`, 'A', '127.0.0.1');
|
await testCloudflareAccount.convenience.createRecord(
|
||||||
|
`${randomPrefix}subdomain.bleu.de`,
|
||||||
|
'A',
|
||||||
|
'127.0.0.1',
|
||||||
|
120
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should get a record from Cloudflare', async tools => {
|
tap.test('should get a record from Cloudflare', async (tools) => {
|
||||||
tools.timeout(600000);
|
tools.timeout(600000);
|
||||||
await testCloudflareAccount.getRecord(`${randomPrefix}subdomain.bleu.de`, 'A').then(responseArg => {
|
await testCloudflareAccount.convenience
|
||||||
|
.getRecord(`${randomPrefix}subdomain.bleu.de`, 'A')
|
||||||
|
.then((responseArg) => {
|
||||||
console.log(responseArg);
|
console.log(responseArg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should remove a subdomain record from Cloudflare', async tools => {
|
tap.test('should remove a subdomain record from Cloudflare', async (tools) => {
|
||||||
tools.timeout(600000);
|
tools.timeout(600000);
|
||||||
await testCloudflareAccount
|
await testCloudflareAccount.convenience
|
||||||
.removeRecord(`${randomPrefix}subdomain.bleu.de`, 'A')
|
.removeRecord(`${randomPrefix}subdomain.bleu.de`, 'A')
|
||||||
.then(async responseArg => {
|
.then(async (responseArg) => {
|
||||||
console.log(responseArg);
|
console.log(responseArg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('.purge(some.domain) -> should purge everything', async () => {
|
tap.test('.purge(some.domain) -> should purge everything', async () => {
|
||||||
await testCloudflareAccount.purgeZone('bleu.de');
|
await testCloudflareAccount.convenience.purgeZone('bleu.de');
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should list workers', async () => {
|
||||||
|
const workerArray = await testCloudflareAccount.workerManager.listWorkerScripts();
|
||||||
|
console.log(workerArray);
|
||||||
});
|
});
|
||||||
|
|
||||||
// WORKERS
|
// WORKERS
|
||||||
tap.test('should create a worker', async () => {
|
tap.test('should create a worker', async () => {
|
||||||
const worker = await testCloudflareAccount.workerManager.createWorker('myawesomescript', `addEventListener('fetch', event => { event.respondWith(fetch(event.request)) })`);
|
const worker = await testCloudflareAccount.workerManager.createWorker(
|
||||||
|
'myawesomescript',
|
||||||
|
`addEventListener('fetch', event => { event.respondWith(fetch(event.request)) })`
|
||||||
|
);
|
||||||
await worker.setRoutes([
|
await worker.setRoutes([
|
||||||
{
|
{
|
||||||
zoneName: 'bleu.de',
|
zoneName: 'bleu.de',
|
||||||
pattern: 'https://*bleu.de/hello'
|
pattern: 'https://*bleu.de/hello',
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
console.log(worker);
|
console.log(worker);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should get workers', async () => {
|
tap.test('should get workers again', async () => {
|
||||||
const workerArray = await testCloudflareAccount.workerManager.listWorkers();
|
const workerArray = await testCloudflareAccount.workerManager.listWorkerScripts();
|
||||||
console.log(workerArray);
|
console.log(workerArray);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
8
ts/00_commitinfo_data.ts
Normal file
8
ts/00_commitinfo_data.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* autocreated commitinfo by @pushrocks/commitinfo
|
||||||
|
*/
|
||||||
|
export const commitinfo = {
|
||||||
|
name: '@apiclient.xyz/cloudflare',
|
||||||
|
version: '6.0.5',
|
||||||
|
description: 'A TypeScript client for managing Cloudflare accounts, zones, DNS records, and workers with ease.'
|
||||||
|
}
|
@ -1,111 +1,146 @@
|
|||||||
import plugins = require('./cloudflare.plugins');
|
import * as plugins from './cloudflare.plugins.js';
|
||||||
import * as interfaces from './interfaces';
|
import { logger } from './cloudflare.logger.js';
|
||||||
|
import * as interfaces from './interfaces/index.js';
|
||||||
|
|
||||||
// interfaces
|
// interfaces
|
||||||
import { TDnsRecord } from '@tsclass/tsclass';
|
import { WorkerManager } from './cloudflare.classes.workermanager.js';
|
||||||
import { WorkerManager } from './cloudflare.classes.workermanager';
|
import { ZoneManager } from './cloudflare.classes.zonemanager.js';
|
||||||
import { ZoneManager } from './cloudflare.classes.zonemanager';
|
|
||||||
|
|
||||||
export class CloudflareAccount {
|
export class CloudflareAccount {
|
||||||
private authEmail: string;
|
private authToken: string;
|
||||||
private authKey: string;
|
public preselectedAccountId: string;
|
||||||
private accountIdentifier: string;
|
|
||||||
|
|
||||||
public workerManager = new WorkerManager(this);
|
public workerManager = new WorkerManager(this);
|
||||||
public zoneManager = new ZoneManager(this);
|
public zoneManager = new ZoneManager(this);
|
||||||
|
|
||||||
|
public apiAccount: plugins.cloudflare.Cloudflare;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor sets auth information on the CloudflareAccountInstance
|
* constructor sets auth information on the CloudflareAccountInstance
|
||||||
* @param optionsArg
|
* @param optionsArg
|
||||||
*/
|
*/
|
||||||
constructor(optionsArg: { email: string; key: string }) {
|
constructor(authTokenArg: string) {
|
||||||
this.authEmail = optionsArg.email;
|
this.authToken = authTokenArg;
|
||||||
this.authKey = optionsArg.key;
|
this.apiAccount = new plugins.cloudflare.Cloudflare({
|
||||||
|
apiToken: this.authToken,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAccountIdentifier() {
|
public async preselectAccountByName(nameArg: string) {
|
||||||
if (!this.accountIdentifier) {
|
const accounts = await this.convenience.listAccounts();
|
||||||
const route = `/accounts?page=1&per_page=20&direction=desc`;
|
const account = accounts.find((accountArg) => {
|
||||||
const response: any = await this.request('GET', route);
|
return accountArg.name === nameArg;
|
||||||
this.accountIdentifier = response.result[0].id;
|
});
|
||||||
// console.log('Account identifier is: ' + this.accountIdentifier);
|
if (account) {
|
||||||
|
this.preselectedAccountId = account.id;
|
||||||
|
} else {
|
||||||
|
throw new Error(`account with name ${nameArg} not found`);
|
||||||
}
|
}
|
||||||
return this.accountIdentifier;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public convenience = {
|
||||||
|
/**
|
||||||
|
* listAccounts
|
||||||
|
*/
|
||||||
|
listAccounts: async () => {
|
||||||
|
const accounts: plugins.ICloudflareTypes['Account'][] = [];
|
||||||
|
for await (const account of this.apiAccount.accounts.list()) {
|
||||||
|
accounts.push(account as interfaces.ICloudflareApiAccountObject);
|
||||||
|
}
|
||||||
|
return accounts;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* gets a zone id of a domain from cloudflare
|
* gets a zone id of a domain from cloudflare
|
||||||
* @param domainName
|
* @param domainName
|
||||||
*/
|
*/
|
||||||
public async getZoneId(domainName: string) {
|
getZoneId: async (domainName: string) => {
|
||||||
const domain = new plugins.smartstring.Domain(domainName);
|
const domain = new plugins.smartstring.Domain(domainName);
|
||||||
const zoneArray = await this.listZones(domain.zoneName);
|
const zoneArray = await this.convenience.listZones(domain.zoneName);
|
||||||
const filteredResponse = zoneArray.filter(zoneArg => {
|
const filteredResponse = zoneArray.filter((zoneArg) => {
|
||||||
return zoneArg.name === domainName;
|
return zoneArg.name === domainName;
|
||||||
});
|
});
|
||||||
if (filteredResponse.length >= 1) {
|
if (filteredResponse.length >= 1) {
|
||||||
return filteredResponse[0].id;
|
return filteredResponse[0].id;
|
||||||
} else {
|
} else {
|
||||||
plugins.smartlog.defaultLogger.log(
|
logger.log('error', `the domain ${domainName} does not appear to be in this account!`);
|
||||||
'error',
|
|
||||||
`the domain ${domainName} does not appear to be in this account!`
|
|
||||||
);
|
|
||||||
throw new Error(`the domain ${domainName} does not appear to be in this account!`);
|
throw new Error(`the domain ${domainName} does not appear to be in this account!`);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets a record
|
* gets a record
|
||||||
* @param domainNameArg
|
* @param domainNameArg
|
||||||
* @param typeArg
|
* @param typeArg
|
||||||
*/
|
*/
|
||||||
public async getRecord(
|
getRecord: async (
|
||||||
domainNameArg: string,
|
domainNameArg: string,
|
||||||
typeArg: TDnsRecord
|
typeArg: plugins.tsclass.network.TDnsRecordType
|
||||||
): Promise<interfaces.ICflareRecord> {
|
): Promise<plugins.ICloudflareTypes['Record']> => {
|
||||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||||
const recordArrayArg = await this.listRecords(domain.zoneName);
|
const recordArrayArg = await this.convenience.listRecords(domain.zoneName);
|
||||||
const filteredResponse = recordArrayArg.filter(recordArg => {
|
const filteredResponse = recordArrayArg.filter((recordArg) => {
|
||||||
return recordArg.type === typeArg && recordArg.name === domainNameArg;
|
return recordArg.type === typeArg && recordArg.name === domainNameArg;
|
||||||
});
|
});
|
||||||
return filteredResponse[0];
|
return filteredResponse[0];
|
||||||
}
|
},
|
||||||
|
/**
|
||||||
public async createRecord(
|
* creates a record
|
||||||
|
*/
|
||||||
|
createRecord: async (
|
||||||
domainNameArg: string,
|
domainNameArg: string,
|
||||||
typeArg: TDnsRecord,
|
typeArg: plugins.tsclass.network.TDnsRecordType,
|
||||||
contentArg: string
|
contentArg: string,
|
||||||
): Promise<any> {
|
ttlArg = 1
|
||||||
|
): Promise<any> => {
|
||||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||||
const domainIdArg = await this.getZoneId(domain.zoneName);
|
const zoneId = await this.convenience.getZoneId(domain.zoneName);
|
||||||
const dataObject = {
|
const response = await this.apiAccount.dns.records.create({
|
||||||
|
zone_id: zoneId,
|
||||||
|
type: typeArg as any,
|
||||||
name: domain.fullName,
|
name: domain.fullName,
|
||||||
type: typeArg,
|
content: contentArg,
|
||||||
content: contentArg
|
ttl: ttlArg,
|
||||||
};
|
})
|
||||||
const response = await this.request(
|
|
||||||
'POST',
|
|
||||||
'/zones/' + domainIdArg + '/dns_records',
|
|
||||||
dataObject
|
|
||||||
);
|
|
||||||
return response;
|
return response;
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes a record from Cloudflare
|
* removes a record from Cloudflare
|
||||||
* @param domainNameArg
|
* @param domainNameArg
|
||||||
* @param typeArg
|
* @param typeArg
|
||||||
*/
|
*/
|
||||||
public async removeRecord(domainNameArg: string, typeArg: TDnsRecord): Promise<any> {
|
removeRecord: async (
|
||||||
|
domainNameArg: string,
|
||||||
|
typeArg: plugins.tsclass.network.TDnsRecordType
|
||||||
|
): Promise<any> => {
|
||||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||||
const cflareRecord = await this.getRecord(domain.fullName, typeArg);
|
const zoneId = await this.convenience.getZoneId(domain.zoneName);
|
||||||
if (cflareRecord) {
|
const records = await this.convenience.listRecords(domain.zoneName);
|
||||||
const requestRoute: string = `/zones/${cflareRecord.zone_id}/dns_records/${cflareRecord.id}`;
|
const recordToDelete = records.find((recordArg) => {
|
||||||
return await this.request('DELETE', requestRoute);
|
return recordArg.name === domainNameArg && recordArg.type === typeArg;
|
||||||
|
});
|
||||||
|
if (recordToDelete) {
|
||||||
|
await this.apiAccount.dns.records.delete(recordToDelete.id, {
|
||||||
|
zone_id: zoneId,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`could not remove record for ${domainNameArg} with type ${typeArg}`);
|
logger.log('warn', `record ${domainNameArg} of type ${typeArg} not found`);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cleanrecord allows the cleaning of any previous records to avoid unwanted sideeffects
|
||||||
|
*/
|
||||||
|
cleanRecord: async (domainNameArg: string, typeArg: plugins.tsclass.network.TDnsRecordType) => {
|
||||||
|
console.log(`cleaning record for ${domainNameArg}`);
|
||||||
|
const records = await this.convenience.listRecords(domainNameArg);
|
||||||
|
const recordsToDelete = records.filter((recordArg) => {
|
||||||
|
return recordArg.type === typeArg;
|
||||||
|
});
|
||||||
|
for (const recordToDelete of recordsToDelete) {
|
||||||
|
await this.apiAccount.dns.records.delete(recordToDelete.id, {
|
||||||
|
zone_id: recordToDelete.zone_id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates a record
|
* updates a record
|
||||||
@ -113,112 +148,64 @@ export class CloudflareAccount {
|
|||||||
* @param typeArg
|
* @param typeArg
|
||||||
* @param valueArg
|
* @param valueArg
|
||||||
*/
|
*/
|
||||||
public updateRecord(domainNameArg: string, typeArg: string, valueArg) {
|
updateRecord: async (
|
||||||
|
domainNameArg: string,
|
||||||
|
typeArg: plugins.tsclass.network.TDnsRecordType,
|
||||||
|
valueArg
|
||||||
|
) => {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
const done = plugins.smartpromise.defer();
|
|
||||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||||
return done.promise;
|
},
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list all records of a specified domain name
|
* list all records of a specified domain name
|
||||||
* @param domainNameArg - the domain name that you want to get the records from
|
* @param domainNameArg - the domain name that you want to get the records from
|
||||||
*/
|
*/
|
||||||
public async listRecords(domainNameArg: string): Promise<interfaces.ICflareRecord[]> {
|
listRecords: async (domainNameArg: string) => {
|
||||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||||
const domainId = await this.getZoneId(domain.zoneName);
|
const zoneId = await this.convenience.getZoneId(domain.zoneName);
|
||||||
const responseArg: any = await this.request(
|
const records: plugins.ICloudflareTypes['Record'][] = [];
|
||||||
'GET',
|
for await (const record of this.apiAccount.dns.records.list({
|
||||||
'/zones/' + domainId + '/dns_records?per_page=100'
|
zone_id: zoneId,
|
||||||
);
|
})) {
|
||||||
const result: interfaces.ICflareRecord[] = responseArg.result;
|
records.push(record);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
return records;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* list all zones in the associated authenticated account
|
* list all zones in the associated authenticated account
|
||||||
* @param domainName
|
* @param domainName
|
||||||
*/
|
*/
|
||||||
public async listZones(domainName?: string): Promise<interfaces.ICflareZone[]> {
|
listZones: async (domainName?: string) => {
|
||||||
// TODO: handle pagination
|
const zones: plugins.ICloudflareTypes['Zone'][] = [];
|
||||||
let requestRoute = `/zones?per_page=50`;
|
for await (const zone of this.apiAccount.zones.list()) {
|
||||||
|
zones.push(zone);
|
||||||
// may be optionally filtered by domain name
|
|
||||||
if (domainName) {
|
|
||||||
requestRoute = `${requestRoute}&name=${domainName}`;
|
|
||||||
}
|
}
|
||||||
|
return zones;
|
||||||
const response: any = await this.request('GET', requestRoute);
|
},
|
||||||
const result = response.result;
|
/**
|
||||||
return result;
|
* purges a zone
|
||||||
}
|
*/
|
||||||
|
purgeZone: async (domainName: string): Promise<void> => {
|
||||||
public async purgeZone(domainName: string) {
|
const domain = new plugins.smartstring.Domain(domainName);
|
||||||
const domain = new plugins.smartstring.Domain(domainName);
|
const zoneId = await this.convenience.getZoneId(domain.zoneName);
|
||||||
const domainId = await this.getZoneId(domain.zoneName);
|
await this.apiAccount.cache.purge({
|
||||||
const requestUrl = `/zones/${domainId}/purge_cache`;
|
zone_id: zoneId,
|
||||||
const payload = {
|
purge_everything: true,
|
||||||
purge_everything: true
|
});
|
||||||
};
|
|
||||||
const respone = await this.request('DELETE', requestUrl, payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public request(
|
|
||||||
methodArg: string,
|
|
||||||
routeArg: string,
|
|
||||||
dataArg: any = {},
|
|
||||||
requestHeadersArg = {}
|
|
||||||
): Promise<any> {
|
|
||||||
const done = plugins.smartpromise.defer();
|
|
||||||
const options: plugins.smartrequest.ISmartRequestOptions = {
|
|
||||||
method: methodArg,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-Auth-Email': this.authEmail,
|
|
||||||
'X-Auth-Key': this.authKey,
|
|
||||||
'Content-Length': Buffer.byteLength(JSON.stringify(dataArg)),
|
|
||||||
...requestHeadersArg
|
|
||||||
},
|
},
|
||||||
requestBody: dataArg
|
|
||||||
};
|
|
||||||
|
|
||||||
// console.log(options);
|
// acme convenience functions
|
||||||
|
acmeSetDnsChallenge: async (dnsChallenge: plugins.tsclass.network.IDnsChallenge) => {
|
||||||
let retryCount = 0; // count the amount of retries
|
await this.convenience.cleanRecord(dnsChallenge.hostName, 'TXT');
|
||||||
|
await this.convenience.createRecord(
|
||||||
const makeRequest = async () => {
|
dnsChallenge.hostName,
|
||||||
const response: any = await plugins.smartrequest.request(
|
'TXT',
|
||||||
`https://api.cloudflare.com/client/v4${routeArg}`,
|
dnsChallenge.challenge,
|
||||||
options
|
120
|
||||||
);
|
);
|
||||||
if (response.statusCode === 200) {
|
},
|
||||||
done.resolve(response.body);
|
acmeRemoveDnsChallenge: async (dnsChallenge: plugins.tsclass.network.IDnsChallenge) => {
|
||||||
} else if (response.statusCode === 429) {
|
await this.convenience.removeRecord(dnsChallenge.hostName, 'TXT');
|
||||||
console.log('rate limited! Waiting for retry!');
|
},
|
||||||
retryRequest();
|
|
||||||
} else if (response.statusCode === 400) {
|
|
||||||
console.log(`bad request for route ${routeArg}! Going to retry!`);
|
|
||||||
console.log(response.body);
|
|
||||||
} else {
|
|
||||||
console.log(response.statusCode);
|
|
||||||
done.reject(new Error('request failed'));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
const retryRequest = async (
|
|
||||||
delayTimeArg = Math.floor(Math.random() * (60000 - 8000) + 8000)
|
|
||||||
) => {
|
|
||||||
console.log(`retry started and waiting for ${delayTimeArg} ms`);
|
|
||||||
await plugins.smartdelay.delayFor(delayTimeArg);
|
|
||||||
if (retryCount < 10) {
|
|
||||||
retryCount++;
|
|
||||||
return await makeRequest();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
makeRequest();
|
|
||||||
return done.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
private authCheck() {
|
|
||||||
return this.authEmail && this.authKey; // check if auth is available
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
3
ts/cloudflare.classes.record.ts
Normal file
3
ts/cloudflare.classes.record.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import * as plugins from './cloudflare.plugins.js';
|
||||||
|
|
||||||
|
export class CloudflareRecord {}
|
@ -1,16 +1,20 @@
|
|||||||
import * as plugins from './cloudflare.plugins';
|
import * as plugins from './cloudflare.plugins.js';
|
||||||
import * as interfaces from './interfaces';
|
import * as interfaces from './interfaces/index.js';
|
||||||
import { WorkerManager } from './cloudflare.classes.workermanager';
|
import { WorkerManager } from './cloudflare.classes.workermanager.js';
|
||||||
|
import { logger } from './cloudflare.logger.js';
|
||||||
|
|
||||||
export interface IWorkerRoute extends interfaces.ICflareWorkerRoute {
|
export interface IWorkerRoute extends interfaces.ICflareWorkerRoute {
|
||||||
zoneName: string;
|
zoneName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Worker {
|
export class CloudflareWorker {
|
||||||
// STATIC
|
// STATIC
|
||||||
public static async fromApiObject(workerManager: WorkerManager, apiObject): Promise<Worker> {
|
public static async fromApiObject(
|
||||||
const newWorker = new Worker(workerManager);
|
workerManager: WorkerManager,
|
||||||
Object.assign(newWorker, apiObject.result);
|
apiObject
|
||||||
|
): Promise<CloudflareWorker> {
|
||||||
|
const newWorker = new CloudflareWorker(workerManager);
|
||||||
|
Object.assign(newWorker, apiObject);
|
||||||
await newWorker.getRoutes();
|
await newWorker.getRoutes();
|
||||||
return newWorker;
|
return newWorker;
|
||||||
}
|
}
|
||||||
@ -35,10 +39,12 @@ export class Worker {
|
|||||||
* gets all routes for a worker
|
* gets all routes for a worker
|
||||||
*/
|
*/
|
||||||
public async getRoutes() {
|
public async getRoutes() {
|
||||||
const zones = await this.workerManager.cfAccount.listZones();
|
const zones = await this.workerManager.cfAccount.convenience.listZones();
|
||||||
for (const zone of zones) {
|
for (const zone of zones) {
|
||||||
const requestRoute = `/zones/${zone.id}/workers/routes`;
|
const requestRoute = `/zones/${zone.id}/workers/routes`;
|
||||||
const response: {result: interfaces.ICflareWorkerRoute[]} = await this.workerManager.cfAccount.request('GET', requestRoute);
|
const response: {
|
||||||
|
result: interfaces.ICflareWorkerRoute[];
|
||||||
|
} = await this.workerManager.cfAccount.request('GET', requestRoute);
|
||||||
for (const route of response.result) {
|
for (const route of response.result) {
|
||||||
console.log('hey');
|
console.log('hey');
|
||||||
console.log(route);
|
console.log(route);
|
||||||
@ -50,7 +56,7 @@ export class Worker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setRoutes(routeArray: Array<{zoneName: string, pattern: string}>) {
|
public async setRoutes(routeArray: Array<{ zoneName: string; pattern: string }>) {
|
||||||
for (const newRoute of routeArray) {
|
for (const newRoute of routeArray) {
|
||||||
// lets determine wether a route is new, needs an update or already up to date.
|
// lets determine wether a route is new, needs an update or already up to date.
|
||||||
let routeStatus: 'new' | 'needsUpdate' | 'alreadyUpToDate' = 'new';
|
let routeStatus: 'new' | 'needsUpdate' | 'alreadyUpToDate' = 'new';
|
||||||
@ -61,25 +67,25 @@ export class Worker {
|
|||||||
routeIdForUpdate = existingRoute.id;
|
routeIdForUpdate = existingRoute.id;
|
||||||
if (existingRoute.script === this.id) {
|
if (existingRoute.script === this.id) {
|
||||||
routeStatus = 'alreadyUpToDate';
|
routeStatus = 'alreadyUpToDate';
|
||||||
plugins.smartlog.defaultLogger.log('info', `route already exists, no update needed`);
|
logger.log('info', `route already exists, no update needed`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// lets care about actually setting routes
|
// lets care about actually setting routes
|
||||||
if (routeStatus === 'new') {
|
if (routeStatus === 'new') {
|
||||||
const zoneId = await this.workerManager.cfAccount.getZoneId(newRoute.zoneName);
|
const zoneId = await this.workerManager.cfAccount.convenience.getZoneId(newRoute.zoneName);
|
||||||
const requestRoute = `/zones/${zoneId}/workers/routes`;
|
const requestRoute = `/zones/${zoneId}/workers/routes`;
|
||||||
await this.workerManager.cfAccount.request('POST', requestRoute, {
|
await this.workerManager.cfAccount.request('POST', requestRoute, {
|
||||||
pattern: newRoute.pattern,
|
pattern: newRoute.pattern,
|
||||||
script: this.id
|
script: this.id,
|
||||||
});
|
});
|
||||||
} else if (routeStatus === 'needsUpdate') {
|
} else if (routeStatus === 'needsUpdate') {
|
||||||
const zoneId = await this.workerManager.cfAccount.getZoneId(newRoute.zoneName);
|
const zoneId = await this.workerManager.cfAccount.convenience.getZoneId(newRoute.zoneName);
|
||||||
const requestRoute = `/zones/${zoneId}/workers/routes/${routeIdForUpdate}`;
|
const requestRoute = `/zones/${zoneId}/workers/routes/${routeIdForUpdate}`;
|
||||||
await this.workerManager.cfAccount.request('PUT', requestRoute, {
|
await this.workerManager.cfAccount.request('PUT', requestRoute, {
|
||||||
pattern: newRoute.pattern,
|
pattern: newRoute.pattern,
|
||||||
script: this.id
|
script: this.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as plugins from './cloudflare.plugins';
|
import * as plugins from './cloudflare.plugins.js';
|
||||||
import { CloudflareAccount } from './cloudflare.classes.account';
|
import { CloudflareAccount } from './cloudflare.classes.account.js';
|
||||||
import { Worker } from './cloudflare.classes.worker';
|
import { CloudflareWorker } from './cloudflare.classes.worker.js';
|
||||||
|
|
||||||
export class WorkerManager {
|
export class WorkerManager {
|
||||||
public cfAccount: CloudflareAccount;
|
public cfAccount: CloudflareAccount;
|
||||||
@ -9,23 +9,30 @@ export class WorkerManager {
|
|||||||
this.cfAccount = cfAccountArg;
|
this.cfAccount = cfAccountArg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createWorker(workerName: string, workerScript: string): Promise<Worker> {
|
public async createWorker(workerName: string, workerScript: string): Promise<plugins.ICloudflareTypes['Script']> {
|
||||||
const accountIdentifier = await this.cfAccount.getAccountIdentifier();
|
if (!this.cfAccount.preselectedAccountId) {
|
||||||
const route = `/accounts/${accountIdentifier}/workers/scripts/${workerName}`;
|
throw new Error('No account selected. Please select it first on the account.');
|
||||||
const responseBody = await this.cfAccount.request('PUT', route, workerScript, {
|
}
|
||||||
'Content-Type': 'application/javascript',
|
const worker = await this.cfAccount.apiAccount.workers.scripts.content.update(workerName, {
|
||||||
'Content-Length': Buffer.byteLength(workerScript)
|
account_id: this.cfAccount.preselectedAccountId,
|
||||||
|
"CF-WORKER-BODY-PART": workerScript,
|
||||||
});
|
});
|
||||||
return Worker.fromApiObject(this, responseBody);
|
return worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lists workers
|
* lists workers
|
||||||
*/
|
*/
|
||||||
public async listWorkers() {
|
public async listWorkerScripts() {
|
||||||
const accountIdentifier = await this.cfAccount.getAccountIdentifier();
|
if (!this.cfAccount.preselectedAccountId) {
|
||||||
const route = `/accounts/${accountIdentifier}/workers/scripts`;
|
throw new Error('No account selected. Please select it first on the account.');
|
||||||
const response = await this.cfAccount.request('GET', route);
|
}
|
||||||
console.log(response);
|
const workerScripts: plugins.ICloudflareTypes['Script'][] = [];
|
||||||
|
for await (const scriptArg of this.cfAccount.apiAccount.workers.scripts.list({
|
||||||
|
account_id: this.cfAccount.preselectedAccountId,
|
||||||
|
})) {
|
||||||
|
workerScripts.push(scriptArg);
|
||||||
|
}
|
||||||
|
return workerScripts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
ts/cloudflare.classes.zone.ts
Normal file
9
ts/cloudflare.classes.zone.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import * as plugins from './cloudflare.plugins.js';
|
||||||
|
|
||||||
|
export class CloudflareZone {
|
||||||
|
public static createFromApiObject(apiObject: plugins.ICloudflareTypes['Zone']) {
|
||||||
|
const cloudflareZone = new CloudflareZone();
|
||||||
|
Object.assign(cloudflareZone, apiObject);
|
||||||
|
return cloudflareZone;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
import * as plugins from './cloudflare.plugins';
|
import * as plugins from './cloudflare.plugins.js';
|
||||||
import { CloudflareAccount } from './cloudflare.classes.account';
|
import * as interfaces from './interfaces/index.js';
|
||||||
|
import { CloudflareAccount } from './cloudflare.classes.account.js';
|
||||||
|
import { CloudflareZone } from './cloudflare.classes.zone.js';
|
||||||
|
|
||||||
export class ZoneManager {
|
export class ZoneManager {
|
||||||
public cfAccount: CloudflareAccount;
|
public cfAccount: CloudflareAccount;
|
||||||
@ -8,4 +10,23 @@ export class ZoneManager {
|
|||||||
constructor(cfAccountArg: CloudflareAccount) {
|
constructor(cfAccountArg: CloudflareAccount) {
|
||||||
this.cfAccount = cfAccountArg;
|
this.cfAccount = cfAccountArg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getZones(zoneName: string) {
|
||||||
|
let requestRoute = `/zones?per_page=50`;
|
||||||
|
// may be optionally filtered by domain name
|
||||||
|
|
||||||
|
if (zoneName) {
|
||||||
|
requestRoute = `${requestRoute}&name=${zoneName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response: any = await this.cfAccount.request('GET', requestRoute);
|
||||||
|
const apiObjects: interfaces.ICflareZone[] = response.result;
|
||||||
|
|
||||||
|
const cloudflareZoneArray = [];
|
||||||
|
for (const apiObject of apiObjects) {
|
||||||
|
cloudflareZoneArray.push(CloudflareZone.createFromApiObject(apiObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
return cloudflareZoneArray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
3
ts/cloudflare.logger.ts
Normal file
3
ts/cloudflare.logger.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import * as plugins from './cloudflare.plugins.js';
|
||||||
|
|
||||||
|
export const logger = new plugins.smartlog.ConsoleLog();
|
@ -1,8 +1,24 @@
|
|||||||
import * as smartlog from '@pushrocks/smartlog';
|
import * as smartlog from '@push.rocks/smartlog';
|
||||||
import * as smartpromise from '@pushrocks/smartpromise';
|
import * as smartpromise from '@push.rocks/smartpromise';
|
||||||
import * as smartdelay from '@pushrocks/smartdelay';
|
import * as smartdelay from '@push.rocks/smartdelay';
|
||||||
import * as smartrequest from '@pushrocks/smartrequest';
|
import * as smartrequest from '@push.rocks/smartrequest';
|
||||||
import * as smartstring from '@pushrocks/smartstring';
|
import * as smartstring from '@push.rocks/smartstring';
|
||||||
import * as tsclass from '@tsclass/tsclass';
|
import * as tsclass from '@tsclass/tsclass';
|
||||||
|
|
||||||
export { smartlog, smartpromise, smartdelay, smartrequest, smartstring, tsclass };
|
export { smartlog, smartpromise, smartdelay, smartrequest, smartstring, tsclass };
|
||||||
|
|
||||||
|
// third party
|
||||||
|
import * as cloudflare from 'cloudflare';
|
||||||
|
import * as interfaces from './interfaces/index.js';
|
||||||
|
import type { Zone } from 'cloudflare/resources/zones/zones.js';
|
||||||
|
import type { Record } from 'cloudflare/resources/dns/records.js';
|
||||||
|
import type { Script } from 'cloudflare/resources/workers/scripts/index.js';
|
||||||
|
|
||||||
|
export interface ICloudflareTypes {
|
||||||
|
Account: interfaces.ICloudflareApiAccountObject;
|
||||||
|
Record: Record;
|
||||||
|
Zone: Zone;
|
||||||
|
Script: Script;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { cloudflare };
|
||||||
|
@ -1 +1,2 @@
|
|||||||
export { CloudflareAccount } from './cloudflare.classes.account';
|
export { CloudflareAccount } from './cloudflare.classes.account.js';
|
||||||
|
export { CloudflareWorker } from './cloudflare.classes.worker.js';
|
||||||
|
20
ts/interfaces/cloudflare.api.account.ts
Normal file
20
ts/interfaces/cloudflare.api.account.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export interface ICloudflareApiAccountObject {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
type: 'standard' | 'enterprise' | 'pro' | 'free'; // Assuming other possible types
|
||||||
|
settings: {
|
||||||
|
enforce_twofactor: boolean;
|
||||||
|
api_access_enabled: boolean | null;
|
||||||
|
access_approval_expiry: string | null; // Assuming ISO date string or null
|
||||||
|
use_account_custom_ns_by_default: boolean;
|
||||||
|
default_nameservers: string;
|
||||||
|
};
|
||||||
|
legacy_flags: {
|
||||||
|
enterprise_zone_quota: {
|
||||||
|
maximum: number;
|
||||||
|
current: number;
|
||||||
|
available: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
created_on: string; // Assuming ISO date string
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
export interface ICflareRecord {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
name: string;
|
|
||||||
content: string;
|
|
||||||
proxiable: boolean;
|
|
||||||
proxied: boolean;
|
|
||||||
ttl: number;
|
|
||||||
locked: boolean;
|
|
||||||
zone_id: string;
|
|
||||||
zone_name: string;
|
|
||||||
created_on: string;
|
|
||||||
modified_on: string;
|
|
||||||
data: any;
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
export interface ICflareZone {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
development_mode: number;
|
|
||||||
original_name_servers: string[];
|
|
||||||
original_registrar: string;
|
|
||||||
original_dnshost: string;
|
|
||||||
created_on: string;
|
|
||||||
modified_on: string;
|
|
||||||
name_servers: string[];
|
|
||||||
owner: {
|
|
||||||
id: string;
|
|
||||||
email: string;
|
|
||||||
owner_type: string;
|
|
||||||
};
|
|
||||||
permissions: string[];
|
|
||||||
plan: {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
price: number;
|
|
||||||
currency: string;
|
|
||||||
frequency: string;
|
|
||||||
legacy_id: string;
|
|
||||||
is_subscribed: boolean;
|
|
||||||
can_subscribe: boolean;
|
|
||||||
};
|
|
||||||
plan_pending: {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
price: number;
|
|
||||||
currency: string;
|
|
||||||
frequency: string;
|
|
||||||
legacy_id: string;
|
|
||||||
is_subscribed: string;
|
|
||||||
can_subscribe: string;
|
|
||||||
};
|
|
||||||
status: string;
|
|
||||||
paused: boolean;
|
|
||||||
type: string;
|
|
||||||
checked_on: string;
|
|
||||||
}
|
|
@ -1,3 +1,2 @@
|
|||||||
export * from './cloudflare.api.record';
|
export * from './cloudflare.api.account.js';
|
||||||
export * from './cloudflare.api.zone';
|
export * from './cloudflare.api.workerroute.js';
|
||||||
export * from './cloudflare.api.workerroute';
|
|
||||||
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"verbatimModuleSyntax": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"dist_*/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
18
tslint.json
18
tslint.json
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["tslint:latest", "tslint-config-prettier"],
|
|
||||||
"rules": {
|
|
||||||
"semicolon": [true, "always"],
|
|
||||||
"no-console": false,
|
|
||||||
"no-return-await": false,
|
|
||||||
"ordered-imports": false,
|
|
||||||
"object-literal-sort-keys": false,
|
|
||||||
"member-ordering": {
|
|
||||||
"options":{
|
|
||||||
"order": [
|
|
||||||
"static-method"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultSeverity": "warning"
|
|
||||||
}
|
|
Reference in New Issue
Block a user