feat(core): Update dependencies, enhance documentation, and improve error handling with clearer API usage examples
This commit is contained in:
@@ -17,7 +17,7 @@ export class CloudflareAccount {
|
||||
|
||||
/**
|
||||
* constructor sets auth information on the CloudflareAccountInstance
|
||||
* @param optionsArg
|
||||
* @param authTokenArg Cloudflare API token
|
||||
*/
|
||||
constructor(authTokenArg: string) {
|
||||
this.authToken = authTokenArg;
|
||||
@@ -27,21 +27,21 @@ export class CloudflareAccount {
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a request to the Cloudflare API
|
||||
* Make a request to the Cloudflare API for endpoints not directly supported by the official client
|
||||
* Only use this for endpoints that don't have a direct method in the official client
|
||||
* @param method HTTP method (GET, POST, PUT, DELETE)
|
||||
* @param endpoint API endpoint path
|
||||
* @param data Optional request body data
|
||||
* @returns API response
|
||||
*/
|
||||
public async request<T = any>(
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',
|
||||
endpoint: string,
|
||||
data?: any
|
||||
): Promise<T> {
|
||||
try {
|
||||
const options: plugins.smartrequest.ISmartRequestOptions = {
|
||||
method,
|
||||
url: `https://api.cloudflare.com/client/v4${endpoint}`,
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.authToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
@@ -49,10 +49,10 @@ export class CloudflareAccount {
|
||||
};
|
||||
|
||||
if (data) {
|
||||
options.json = data;
|
||||
options.requestBody = JSON.stringify(data);
|
||||
}
|
||||
|
||||
const response = await plugins.smartrequest.request(options);
|
||||
const response = await plugins.smartrequest.request(`https://api.cloudflare.com/client/v4${endpoint}`, options);
|
||||
return JSON.parse(response.body);
|
||||
} catch (error) {
|
||||
logger.log('error', `Cloudflare API request failed: ${error.message}`);
|
||||
@@ -108,13 +108,25 @@ export class CloudflareAccount {
|
||||
getRecord: async (
|
||||
domainNameArg: string,
|
||||
typeArg: plugins.tsclass.network.TDnsRecordType
|
||||
): Promise<plugins.ICloudflareTypes['Record']> => {
|
||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||
const recordArrayArg = await this.convenience.listRecords(domain.zoneName);
|
||||
const filteredResponse = recordArrayArg.filter((recordArg) => {
|
||||
return recordArg.type === typeArg && recordArg.name === domainNameArg;
|
||||
});
|
||||
return filteredResponse[0];
|
||||
): Promise<plugins.ICloudflareTypes['Record'] | undefined> => {
|
||||
try {
|
||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||
const recordArrayArg = await this.convenience.listRecords(domain.zoneName);
|
||||
|
||||
if (!Array.isArray(recordArrayArg)) {
|
||||
logger.log('warn', `Expected records array for ${domainNameArg} but got ${typeof recordArrayArg}`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const filteredResponse = recordArrayArg.filter((recordArg) => {
|
||||
return recordArg.type === typeArg && recordArg.name === domainNameArg;
|
||||
});
|
||||
|
||||
return filteredResponse.length > 0 ? filteredResponse[0] : undefined;
|
||||
} catch (error) {
|
||||
logger.log('error', `Error getting record for ${domainNameArg}: ${error.message}`);
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* creates a record
|
||||
@@ -152,7 +164,10 @@ export class CloudflareAccount {
|
||||
return recordArg.name === domainNameArg && recordArg.type === typeArg;
|
||||
});
|
||||
if (recordToDelete) {
|
||||
await this.apiAccount.dns.records.delete(recordToDelete.id, {
|
||||
// The official client might have the id in a different location
|
||||
// Casting to any to access the id property
|
||||
const recordId = (recordToDelete as any).id;
|
||||
await this.apiAccount.dns.records.delete(recordId, {
|
||||
zone_id: zoneId,
|
||||
});
|
||||
} else {
|
||||
@@ -164,15 +179,44 @@ export class CloudflareAccount {
|
||||
* cleanrecord allows the cleaning of any previous records to avoid unwanted sideeffects
|
||||
*/
|
||||
cleanRecord: async (domainNameArg: string, typeArg: plugins.tsclass.network.TDnsRecordType) => {
|
||||
logger.log('info', `Cleaning ${typeArg} records 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,
|
||||
try {
|
||||
logger.log('info', `Cleaning ${typeArg} records for ${domainNameArg}`);
|
||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||
const zoneId = await this.convenience.getZoneId(domain.zoneName);
|
||||
|
||||
const records = await this.convenience.listRecords(domainNameArg);
|
||||
|
||||
if (!Array.isArray(records)) {
|
||||
logger.log('warn', `Expected records array for ${domainNameArg} but got ${typeof records}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const recordsToDelete = records.filter((recordArg) => {
|
||||
return recordArg.type === typeArg;
|
||||
});
|
||||
|
||||
logger.log('info', `Found ${recordsToDelete.length} ${typeArg} records to delete for ${domainNameArg}`);
|
||||
|
||||
for (const recordToDelete of recordsToDelete) {
|
||||
try {
|
||||
// The official client might have different property locations
|
||||
// Casting to any to access properties safely
|
||||
const recordId = (recordToDelete as any).id;
|
||||
if (!recordId) {
|
||||
logger.log('warn', `Record ID not found for ${domainNameArg} record`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.apiAccount.dns.records.delete(recordId, {
|
||||
zone_id: zoneId,
|
||||
});
|
||||
logger.log('info', `Deleted ${typeArg} record ${recordId} for ${domainNameArg}`);
|
||||
} catch (deleteError) {
|
||||
logger.log('error', `Failed to delete record: ${deleteError.message}`);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.log('error', `Error cleaning ${typeArg} records for ${domainNameArg}: ${error.message}`);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -201,8 +245,9 @@ export class CloudflareAccount {
|
||||
return this.convenience.createRecord(domainNameArg, typeArg, contentArg, ttlArg);
|
||||
}
|
||||
|
||||
// Update the record
|
||||
const updatedRecord = await this.apiAccount.dns.records.edit(record.id, {
|
||||
// Update the record - cast to any to access the id property
|
||||
const recordId = (record as any).id;
|
||||
const updatedRecord = await this.apiAccount.dns.records.edit(recordId, {
|
||||
zone_id: zoneId,
|
||||
type: typeArg as any,
|
||||
name: domain.fullName,
|
||||
@@ -220,23 +265,60 @@ export class CloudflareAccount {
|
||||
const domain = new plugins.smartstring.Domain(domainNameArg);
|
||||
const zoneId = await this.convenience.getZoneId(domain.zoneName);
|
||||
const records: plugins.ICloudflareTypes['Record'][] = [];
|
||||
for await (const record of this.apiAccount.dns.records.list({
|
||||
zone_id: zoneId,
|
||||
})) {
|
||||
records.push(record);
|
||||
|
||||
try {
|
||||
const result = await this.apiAccount.dns.records.list({
|
||||
zone_id: zoneId,
|
||||
});
|
||||
|
||||
// Check if the result has a 'result' property (API response format)
|
||||
if (result && result.result && Array.isArray(result.result)) {
|
||||
return result.result;
|
||||
}
|
||||
|
||||
// Otherwise iterate through async iterator (new client format)
|
||||
for await (const record of this.apiAccount.dns.records.list({
|
||||
zone_id: zoneId,
|
||||
})) {
|
||||
records.push(record);
|
||||
}
|
||||
|
||||
return records;
|
||||
} catch (error) {
|
||||
logger.log('error', `Failed to list records for ${domainNameArg}: ${error.message}`);
|
||||
return [];
|
||||
}
|
||||
return records;
|
||||
},
|
||||
/**
|
||||
* list all zones in the associated authenticated account
|
||||
* @param domainName
|
||||
*/
|
||||
listZones: async (domainName?: string) => {
|
||||
const zones: plugins.ICloudflareTypes['Zone'][] = [];
|
||||
for await (const zone of this.apiAccount.zones.list()) {
|
||||
zones.push(zone);
|
||||
const options: any = {};
|
||||
if (domainName) {
|
||||
options.name = domainName;
|
||||
}
|
||||
|
||||
const zones: plugins.ICloudflareTypes['Zone'][] = [];
|
||||
|
||||
try {
|
||||
const result = await this.apiAccount.zones.list(options);
|
||||
|
||||
// Check if the result has a 'result' property (API response format)
|
||||
if (result && result.result && Array.isArray(result.result)) {
|
||||
return result.result;
|
||||
}
|
||||
|
||||
// Otherwise iterate through async iterator (new client format)
|
||||
for await (const zone of this.apiAccount.zones.list(options)) {
|
||||
zones.push(zone);
|
||||
}
|
||||
|
||||
return zones;
|
||||
} catch (error) {
|
||||
logger.log('error', `Failed to list zones: ${error.message}`);
|
||||
return [];
|
||||
}
|
||||
return zones;
|
||||
},
|
||||
/**
|
||||
* purges a zone
|
||||
|
||||
Reference in New Issue
Block a user