ichime-ts-api-client 1.0.0
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 +105 -0
- package/biome.json +52 -0
- package/package.json +49 -0
- package/src/api/api-client.ts +173 -0
- package/src/api/date-decoder.ts +57 -0
- package/src/api/errors.ts +43 -0
- package/src/api/index.ts +4 -0
- package/src/api/types/episode.ts +16 -0
- package/src/api/types/index.ts +15 -0
- package/src/api/types/series-type.ts +10 -0
- package/src/api/types/series.ts +44 -0
- package/src/api/types/translation.ts +30 -0
- package/src/http-session.ts +99 -0
- package/src/index.ts +53 -0
- package/src/web/errors.ts +43 -0
- package/src/web/helpers.ts +70 -0
- package/src/web/index.ts +4 -0
- package/src/web/types/anime-list-status.ts +70 -0
- package/src/web/types/anime-list.ts +23 -0
- package/src/web/types/index.ts +21 -0
- package/src/web/types/moment.ts +25 -0
- package/src/web/types/personal-episode.ts +19 -0
- package/src/web/types/profile.ts +5 -0
- package/src/web/web-client.ts +810 -0
- package/tests/auth.test.ts +92 -0
- package/tsconfig.json +24 -0
- package/tsdown.config.ts +11 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { HttpSession, WebClient } from "../src/index.js";
|
|
3
|
+
|
|
4
|
+
const BASE_URL = process.env.ANIME365_BASE_URL || "https://smotret-anime.com";
|
|
5
|
+
const USERNAME = process.env.ANIME365_USERNAME as string | undefined;
|
|
6
|
+
const PASSWORD = process.env.ANIME365_PASSWORD as string | undefined;
|
|
7
|
+
|
|
8
|
+
function getCredentials(): { username: string; password: string } {
|
|
9
|
+
if (!USERNAME || !PASSWORD) {
|
|
10
|
+
throw new Error("Credentials not set");
|
|
11
|
+
}
|
|
12
|
+
return { username: USERNAME, password: PASSWORD };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe("WebClient Authentication", () => {
|
|
16
|
+
it("should fail login with invalid credentials", async () => {
|
|
17
|
+
const session = new HttpSession(BASE_URL);
|
|
18
|
+
const webClient = new WebClient(session);
|
|
19
|
+
|
|
20
|
+
await expect(webClient.login("invalid@example.com", "wrongpassword")).rejects.toThrow(
|
|
21
|
+
"Invalid credentials"
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it.skipIf(!USERNAME || !PASSWORD)(
|
|
26
|
+
"should successfully login with valid credentials",
|
|
27
|
+
async () => {
|
|
28
|
+
const { username, password } = getCredentials();
|
|
29
|
+
const session = new HttpSession(BASE_URL);
|
|
30
|
+
const webClient = new WebClient(session);
|
|
31
|
+
|
|
32
|
+
// Login should not throw
|
|
33
|
+
await expect(webClient.login(username, password)).resolves.toBeUndefined();
|
|
34
|
+
|
|
35
|
+
// After login, getProfile should work
|
|
36
|
+
const profile = await webClient.getProfile();
|
|
37
|
+
|
|
38
|
+
expect(profile).toBeDefined();
|
|
39
|
+
expect(profile.id).toBeGreaterThan(0);
|
|
40
|
+
expect(profile.name).toBeTruthy();
|
|
41
|
+
expect(profile.avatarUrl).toBeTruthy();
|
|
42
|
+
|
|
43
|
+
console.log("Logged in as:", profile.name, `(ID: ${profile.id})`);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
it.skipIf(!USERNAME || !PASSWORD)(
|
|
48
|
+
"should persist cookies across requests after login",
|
|
49
|
+
async () => {
|
|
50
|
+
const { username, password } = getCredentials();
|
|
51
|
+
const session = new HttpSession(BASE_URL);
|
|
52
|
+
const webClient = new WebClient(session);
|
|
53
|
+
|
|
54
|
+
// Login
|
|
55
|
+
await webClient.login(username, password);
|
|
56
|
+
|
|
57
|
+
// Multiple requests should work with the same session
|
|
58
|
+
const profile1 = await webClient.getProfile();
|
|
59
|
+
const profile2 = await webClient.getProfile();
|
|
60
|
+
|
|
61
|
+
expect(profile1.id).toBe(profile2.id);
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
it("should throw authenticationRequired when accessing profile without login", async () => {
|
|
66
|
+
const session = new HttpSession(BASE_URL);
|
|
67
|
+
const webClient = new WebClient(session);
|
|
68
|
+
|
|
69
|
+
await expect(webClient.getProfile()).rejects.toThrow("Authentication required");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it.skipIf(!USERNAME || !PASSWORD)("should get personal episodes after login", async () => {
|
|
73
|
+
const { username, password } = getCredentials();
|
|
74
|
+
const session = new HttpSession(BASE_URL);
|
|
75
|
+
const webClient = new WebClient(session);
|
|
76
|
+
|
|
77
|
+
await webClient.login(username, password);
|
|
78
|
+
|
|
79
|
+
const episodes = await webClient.getPersonalEpisodes(1);
|
|
80
|
+
|
|
81
|
+
// Episodes array should exist (may be empty if user has no episodes)
|
|
82
|
+
expect(Array.isArray(episodes)).toBe(true);
|
|
83
|
+
|
|
84
|
+
if (episodes.length > 0) {
|
|
85
|
+
const episode = episodes[0];
|
|
86
|
+
expect(episode.seriesId).toBeGreaterThan(0);
|
|
87
|
+
expect(episode.episodeId).toBeGreaterThan(0);
|
|
88
|
+
expect(episode.seriesTitleRu).toBeTruthy();
|
|
89
|
+
console.log(`Found ${episodes.length} personal episodes`);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true,
|
|
17
|
+
"noUnusedLocals": true,
|
|
18
|
+
"noUnusedParameters": true,
|
|
19
|
+
"noImplicitReturns": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true
|
|
21
|
+
},
|
|
22
|
+
"include": ["src/**/*"],
|
|
23
|
+
"exclude": ["node_modules", "dist", "tests", ".build"]
|
|
24
|
+
}
|
package/tsdown.config.ts
ADDED
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: "node",
|
|
7
|
+
coverage: {
|
|
8
|
+
provider: "v8",
|
|
9
|
+
reporter: ["text", "json", "html"],
|
|
10
|
+
exclude: ["node_modules/", "dist/", "tests/", "*.config.ts", "*.config.js"],
|
|
11
|
+
},
|
|
12
|
+
setupFiles: ["dotenv/config"],
|
|
13
|
+
},
|
|
14
|
+
});
|