Skip to content

Commit 1beedb9

Browse files
committed
feat: Migrate project to TypeScript, update build and linting configurations, and add new test suites for various resources.
1 parent f98b2fd commit 1beedb9

216 files changed

Lines changed: 12003 additions & 5493 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.yml

Lines changed: 0 additions & 23 deletions
This file was deleted.

.idea/copilot.data.migration.ask2agent.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.prettierrc.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ useTabs: false
44
semi: true
55
singleQuote: true
66
trailingComma: es5
7-
bracketSpacing: false
8-
parser: babylon
7+
bracketSpacing: false
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import AccessApplications from '../lib/resources/AccessApplications';
2+
import {
3+
describe,
4+
test,
5+
beforeEach,
6+
expect,
7+
afterEach,
8+
jest
9+
} from '@jest/globals';
10+
11+
const mockApiClient = {
12+
request: jest.fn<any>(),
13+
};
14+
15+
describe('AccessApplications Unit Tests', () => {
16+
let instance: AccessApplications;
17+
18+
beforeEach(() => {
19+
instance = new AccessApplications(mockApiClient as any);
20+
});
21+
22+
test('browse should call request', async () => {
23+
mockApiClient.request.mockResolvedValueOnce({ success: true });
24+
await instance.browse('test-id');
25+
expect(mockApiClient.request).toHaveBeenCalled();
26+
});
27+
28+
test('read should call request', async () => {
29+
mockApiClient.request.mockResolvedValueOnce({ success: true });
30+
await instance.read('test-id', 'test-id');
31+
expect(mockApiClient.request).toHaveBeenCalled();
32+
});
33+
34+
test('edit should call request', async () => {
35+
mockApiClient.request.mockResolvedValueOnce({ success: true });
36+
await instance.edit('test-id', 'test-id', {});
37+
expect(mockApiClient.request).toHaveBeenCalled();
38+
});
39+
40+
test('add should call request', async () => {
41+
mockApiClient.request.mockResolvedValueOnce({ success: true });
42+
await instance.add('test-id', {});
43+
expect(mockApiClient.request).toHaveBeenCalled();
44+
});
45+
46+
test('del should call request', async () => {
47+
mockApiClient.request.mockResolvedValueOnce({ success: true });
48+
await instance.del('test-id', 'test-id');
49+
expect(mockApiClient.request).toHaveBeenCalled();
50+
});
51+
52+
afterEach(() => {
53+
mockApiClient.request.mockClear();
54+
});
55+
});

__tests__/ArgoTunnels.spec.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import ArgoTunnels from '../lib/resources/ArgoTunnels';
2+
import {
3+
describe,
4+
test,
5+
beforeEach,
6+
expect,
7+
afterEach,
8+
jest
9+
} from '@jest/globals';
10+
11+
const mockApiClient = {
12+
request: jest.fn<any>(),
13+
};
14+
15+
describe('ArgoTunnels Unit Tests', () => {
16+
let instance: ArgoTunnels;
17+
18+
beforeEach(() => {
19+
instance = new ArgoTunnels(mockApiClient as any);
20+
});
21+
22+
test('browse should call request', async () => {
23+
mockApiClient.request.mockResolvedValueOnce({ success: true });
24+
await instance.browse('test-id');
25+
expect(mockApiClient.request).toHaveBeenCalled();
26+
});
27+
28+
test('clean should call request', async () => {
29+
mockApiClient.request.mockResolvedValueOnce({ success: true });
30+
await instance.clean('test-id', 'test-id');
31+
expect(mockApiClient.request).toHaveBeenCalled();
32+
});
33+
34+
test('read should call request', async () => {
35+
mockApiClient.request.mockResolvedValueOnce({ success: true });
36+
await instance.read('test-id', 'test-id');
37+
expect(mockApiClient.request).toHaveBeenCalled();
38+
});
39+
40+
test('add should call request', async () => {
41+
mockApiClient.request.mockResolvedValueOnce({ success: true });
42+
await instance.add('test-id', 'test-id');
43+
expect(mockApiClient.request).toHaveBeenCalled();
44+
});
45+
46+
test('del should call request', async () => {
47+
mockApiClient.request.mockResolvedValueOnce({ success: true });
48+
await instance.del('test-id', 'test-id');
49+
expect(mockApiClient.request).toHaveBeenCalled();
50+
});
51+
52+
afterEach(() => {
53+
mockApiClient.request.mockClear();
54+
});
55+
});

__tests__/CFIPs.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import CFIPs from '../lib/resources/CFIPs';
2+
import {
3+
describe,
4+
test,
5+
beforeEach,
6+
expect,
7+
afterEach,
8+
jest
9+
} from '@jest/globals';
10+
11+
const mockApiClient = {
12+
request: jest.fn<any>(),
13+
};
14+
15+
describe('CFIPs Unit Tests', () => {
16+
let instance: CFIPs;
17+
18+
beforeEach(() => {
19+
instance = new CFIPs(mockApiClient as any);
20+
});
21+
22+
test('browse should call request', async () => {
23+
mockApiClient.request.mockResolvedValueOnce({ success: true });
24+
await instance.browse();
25+
expect(mockApiClient.request).toHaveBeenCalled();
26+
});
27+
28+
afterEach(() => {
29+
mockApiClient.request.mockClear();
30+
});
31+
});
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
const CFIPs = require('../lib/resources/CFIPs');
2-
const {
1+
import CFIPs from '../lib/resources/CFIPs';
2+
import {
33
describe,
44
test,
55
beforeEach,
66
expect,
77
afterEach,
8-
} = require('@jest/globals');
9-
const impJest = require('@jest/globals');
8+
} from '@jest/globals';
9+
import impJest from '@jest/globals';
1010
// Mock API client for testing
1111
const mockApiClient = {
12-
request: impJest.jest.fn(),
12+
request: impJest.jest.fn<any>(),
1313
};
1414

1515
describe('CFIPs API Tests', () => {
16-
let cfIPs;
16+
let cfIPs: any;
1717

1818
beforeEach(() => {
1919
// Create an instance of CFIPs with the mock API client
20-
cfIPs = new CFIPs(mockApiClient);
20+
cfIPs = new CFIPs(mockApiClient as any);
2121
});
2222

2323
test('Should successfully browse IP addresses', async () => {

__tests__/Client.unit.test.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import axios from 'axios';
2+
import { CloudflareApiClient } from '../lib/Client';
3+
import { describe, test, expect, jest, beforeEach } from '@jest/globals';
4+
5+
jest.mock('axios');
6+
const mockedAxios = axios as jest.MockedFunction<typeof axios>;
7+
8+
describe('CloudflareApiClient Unit Tests', () => {
9+
let client: CloudflareApiClient;
10+
11+
beforeEach(() => {
12+
client = new CloudflareApiClient({ token: 'test-token' });
13+
jest.clearAllMocks();
14+
});
15+
16+
test('isPlainObject should work correctly for various inputs', () => {
17+
expect(client.isPlainObject({})).toBe(true);
18+
expect(client.isPlainObject([])).toBe(false);
19+
expect(client.isPlainObject(null)).toBe(false);
20+
expect(client.isPlainObject(undefined)).toBe(false);
21+
expect(client.isPlainObject('string')).toBe(false);
22+
expect(client.isPlainObject(42)).toBe(false);
23+
});
24+
25+
test('isUserServiceKey should identify service keys', () => {
26+
expect(client.isUserServiceKey('v1.0-key')).toBe(true);
27+
expect(client.isUserServiceKey('not-a-service-key')).toBe(false);
28+
expect(client.isUserServiceKey(undefined)).toBe(false);
29+
});
30+
31+
test('request should handle 40-char keys as tokens', async () => {
32+
const tokenClient = new CloudflareApiClient({ key: 'a'.repeat(40) });
33+
mockedAxios.mockResolvedValueOnce({ data: { success: true } });
34+
35+
await tokenClient.request({ method: 'GET', uriPath: 'test' });
36+
37+
expect(mockedAxios).toHaveBeenCalledWith(
38+
expect.any(String),
39+
expect.objectContaining({
40+
headers: expect.objectContaining({
41+
Authorization: expect.stringContaining('Bearer')
42+
})
43+
})
44+
);
45+
});
46+
47+
test('request should handle service keys', async () => {
48+
const serviceClient = new CloudflareApiClient({ key: 'v1.0-service-key' });
49+
mockedAxios.mockResolvedValueOnce({ data: { success: true } });
50+
51+
await serviceClient.request({ method: 'GET', uriPath: 'test' });
52+
53+
expect(mockedAxios).toHaveBeenCalledWith(
54+
expect.any(String),
55+
expect.objectContaining({
56+
headers: expect.objectContaining({
57+
'X-Auth-User-Service-Key': 'v1.0-service-key'
58+
})
59+
})
60+
);
61+
});
62+
63+
test('request should handle normal keys with email', async () => {
64+
const keyClient = new CloudflareApiClient({ key: 'abc', email: 'test@example.com' });
65+
mockedAxios.mockResolvedValueOnce({ data: { success: true } });
66+
67+
await keyClient.request({ method: 'GET', uriPath: 'test' });
68+
69+
expect(mockedAxios).toHaveBeenCalledWith(
70+
expect.any(String),
71+
expect.objectContaining({
72+
headers: expect.objectContaining({
73+
'X-Auth-Key': 'abc',
74+
'X-Auth-Email': 'test@example.com'
75+
})
76+
})
77+
);
78+
});
79+
80+
test('request should handle absolute URLs', async () => {
81+
mockedAxios.mockResolvedValueOnce({ data: { success: true } });
82+
const absUrl = 'https://example.com/api';
83+
await client.request({ method: 'GET', uriPath: absUrl });
84+
expect(mockedAxios).toHaveBeenCalledWith(absUrl, expect.any(Object));
85+
});
86+
87+
test('request should handle paths starting with /', async () => {
88+
mockedAxios.mockResolvedValueOnce({ data: { success: true } });
89+
await client.request({ method: 'GET', uriPath: '/my/path' });
90+
expect(mockedAxios).toHaveBeenCalledWith(expect.stringMatching(/v4\/my\/path$/), expect.any(Object));
91+
});
92+
93+
test('request should handle empty path', async () => {
94+
mockedAxios.mockResolvedValueOnce({ data: { success: true } });
95+
await client.request({ method: 'GET' });
96+
expect(mockedAxios).toHaveBeenCalledWith(expect.stringMatching(/v4\/$/), expect.any(Object));
97+
});
98+
99+
test('request should handle POST data', async () => {
100+
mockedAxios.mockResolvedValueOnce({ data: { success: true } });
101+
const testData = { foo: 'bar' };
102+
await client.request({ method: 'POST', uriPath: 'test', data: testData });
103+
expect(mockedAxios).toHaveBeenCalledWith(
104+
expect.any(String),
105+
expect.objectContaining({
106+
data: JSON.stringify(testData)
107+
})
108+
);
109+
});
110+
111+
test('request should handle path substitution', async () => {
112+
mockedAxios.mockResolvedValueOnce({ data: { success: true } });
113+
await client.request({
114+
method: 'GET',
115+
uriPath: 'zones/:zoneId/test',
116+
params: { zoneId: '123', missing: null }
117+
});
118+
expect(mockedAxios).toHaveBeenCalledWith(
119+
expect.stringContaining('/zones/123/test'),
120+
expect.any(Object)
121+
);
122+
});
123+
124+
test('request should throw on axios error', async () => {
125+
const error = new Error('Axios failed');
126+
mockedAxios.mockRejectedValueOnce(error);
127+
await expect(client.request({ method: 'GET', uriPath: 'test' })).rejects.toThrow('Axios failed');
128+
});
129+
});
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
const Cloudflare = require('../index');
2-
require('dotenv').config({path: './.env'});
1+
import Cloudflare from '../index';
2+
import 'dotenv/config';
33

44
// Importy dla funkcji testowych Jest
5-
const {describe, test, beforeAll, afterAll, expect} = require('@jest/globals');
5+
import {describe, test, beforeAll, afterAll, expect} from '@jest/globals';
66

77
// Funkcja pomocnicza do oczekiwania na asynchroniczne zdarzenie
8-
const waitFor = milliseconds =>
8+
const waitFor = (milliseconds: number) =>
99
new Promise(resolve => setTimeout(resolve, milliseconds));
1010

1111
describe('Cloudflare API Tests - DNS Records', () => {
12-
let cloudflareInstance;
13-
let zoneId;
12+
let cloudflareInstance: Cloudflare;
13+
let zoneId: string;
1414

1515
beforeAll(async () => {
1616
cloudflareInstance = new Cloudflare({

0 commit comments

Comments
 (0)