@ddysiodev/js-sdk 0.1.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/LICENSE +22 -0
- package/README.md +248 -0
- package/README.zh-CN.md +244 -0
- package/dist/index.cjs +552 -0
- package/dist/index.d.ts +465 -0
- package/dist/index.js +553 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DDYS
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# DDYS JavaScript SDK
|
|
2
|
+
|
|
3
|
+
[English](README.md) | [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
Official JavaScript SDK for the DDYS Open API.
|
|
6
|
+
|
|
7
|
+
Official website: [DDYS](https://ddys.io/)
|
|
8
|
+
|
|
9
|
+
This package is designed as the base layer for DDYS widgets, CMS plugins, static-site starters, bots, MCP servers, and custom integrations.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Covers every documented `/api/v1` endpoint.
|
|
14
|
+
- Works with public read endpoints without an API key.
|
|
15
|
+
- Supports authenticated endpoints with `Authorization: Bearer ddys_xxx`.
|
|
16
|
+
- Includes TypeScript declarations.
|
|
17
|
+
- Ships ESM and CommonJS builds.
|
|
18
|
+
- Uses standard `fetch`.
|
|
19
|
+
- Has zero runtime dependencies.
|
|
20
|
+
- Supports custom API base URLs for Cloudflare Worker proxy deployments.
|
|
21
|
+
- Provides consistent error classes, timeout handling, optional GET retry, and pagination helpers.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @ddysiodev/js-sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
CDN URLs:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
https://cdn.jsdelivr.net/npm/@ddysiodev/js-sdk/dist/index.js
|
|
33
|
+
https://unpkg.com/@ddysiodev/js-sdk/dist/index.js
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Public publishing:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm publish --access public
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import { createDdysClient } from '@ddysiodev/js-sdk';
|
|
46
|
+
|
|
47
|
+
const ddys = createDdysClient();
|
|
48
|
+
|
|
49
|
+
const latest = await ddys.latest({ limit: 12 });
|
|
50
|
+
const movie = await ddys.movies.detail('interstellar');
|
|
51
|
+
const sources = await ddys.movies.sources('interstellar');
|
|
52
|
+
|
|
53
|
+
console.log(latest, movie.title, sources.download);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Authenticated Usage
|
|
57
|
+
|
|
58
|
+
Authenticated endpoints require a user API key generated at:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
https://ddys.io/user/profile
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Use the key on the server side or inside your own Worker/API route:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
import { createDdysClient } from '@ddysiodev/js-sdk';
|
|
68
|
+
|
|
69
|
+
const ddys = createDdysClient({
|
|
70
|
+
apiKey: process.env.DDYS_API_KEY
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const request = await ddys.requests.create({
|
|
74
|
+
title: 'Dune 2',
|
|
75
|
+
year: 2024,
|
|
76
|
+
type: 'movie',
|
|
77
|
+
douban_id: '35652650'
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
console.log(request.url);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Do not bundle a site owner's API key into public browser JavaScript.
|
|
84
|
+
|
|
85
|
+
## Custom API Base URL
|
|
86
|
+
|
|
87
|
+
Use `baseUrl` when your site routes requests through a cache proxy:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
const ddys = createDdysClient({
|
|
91
|
+
baseUrl: 'https://example.com/ddys-api'
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## API Methods
|
|
96
|
+
|
|
97
|
+
### Movies
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
await ddys.movies.list({ type: 'movie', sort: 'rating', page: 1, per_page: 24 });
|
|
101
|
+
await ddys.movies.detail('interstellar');
|
|
102
|
+
await ddys.movies.sources('interstellar');
|
|
103
|
+
await ddys.movies.related('interstellar');
|
|
104
|
+
await ddys.movies.comments('interstellar', { page: 1, per_page: 20 });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Discovery
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
await ddys.search({ q: 'star', type: 'movie', per_page: 10 });
|
|
111
|
+
await ddys.suggest('star');
|
|
112
|
+
await ddys.hot();
|
|
113
|
+
await ddys.latest({ limit: 30 });
|
|
114
|
+
await ddys.calendar({ year: 2026, month: 7 });
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Dictionaries
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
await ddys.dictionaries.types();
|
|
121
|
+
await ddys.dictionaries.genres();
|
|
122
|
+
await ddys.dictionaries.regions();
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Collections, Shares, Requests, Activities
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
await ddys.collections.list();
|
|
129
|
+
await ddys.collections.detail('best-sci-fi');
|
|
130
|
+
await ddys.shares.list();
|
|
131
|
+
await ddys.shares.detail(1081);
|
|
132
|
+
await ddys.requests.list();
|
|
133
|
+
await ddys.activities.list({ type: 'share' });
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Users
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
await ddys.users.profile('diduan');
|
|
140
|
+
await ddys.me();
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Comments, Reports, Follow
|
|
144
|
+
|
|
145
|
+
```js
|
|
146
|
+
await ddys.comments.create({
|
|
147
|
+
target_type: 'movie',
|
|
148
|
+
target_id: 4786,
|
|
149
|
+
content: 'Great movie'
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
await ddys.comments.delete(12345);
|
|
153
|
+
|
|
154
|
+
await ddys.reports.invalidResource({
|
|
155
|
+
movie_id: 4786,
|
|
156
|
+
resource_id: 1002
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
await ddys.follow.follow('diduan');
|
|
160
|
+
await ddys.follow.unfollow('diduan');
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Pagination
|
|
164
|
+
|
|
165
|
+
Paginated methods return:
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
const result = await ddys.movies.list({ page: 1, per_page: 24 });
|
|
169
|
+
|
|
170
|
+
console.log(result.data);
|
|
171
|
+
console.log(result.meta.total);
|
|
172
|
+
console.log(result.meta.total_pages);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`perPage` is also accepted as an alias for `per_page`.
|
|
176
|
+
|
|
177
|
+
## Low-Level Request
|
|
178
|
+
|
|
179
|
+
Use `request()` for advanced cases. It returns the full API envelope.
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
const envelope = await ddys.request('/movies', {
|
|
183
|
+
query: { page: 1, per_page: 3 }
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
console.log(envelope.success, envelope.data, envelope.meta);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Error Handling
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
import { DdysApiError } from '@ddysiodev/js-sdk';
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
await ddys.movies.detail('missing');
|
|
196
|
+
} catch (error) {
|
|
197
|
+
if (error instanceof DdysApiError) {
|
|
198
|
+
console.error(error.status, error.message, error.endpoint);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Error classes:
|
|
204
|
+
|
|
205
|
+
- `DdysApiError`
|
|
206
|
+
- `DdysTimeoutError`
|
|
207
|
+
- `DdysNetworkError`
|
|
208
|
+
- `DdysParseError`
|
|
209
|
+
|
|
210
|
+
## Runtime Support
|
|
211
|
+
|
|
212
|
+
- Node.js `>=22`
|
|
213
|
+
- Modern browsers
|
|
214
|
+
- Cloudflare Workers
|
|
215
|
+
- Vercel Edge / Netlify Edge style runtimes
|
|
216
|
+
|
|
217
|
+
If a runtime does not provide global `fetch`, pass one:
|
|
218
|
+
|
|
219
|
+
```js
|
|
220
|
+
const ddys = createDdysClient({ fetch: customFetch });
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Development
|
|
224
|
+
|
|
225
|
+
This project intentionally has no runtime dependencies and can build/test with Node only.
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
node scripts/build.mjs
|
|
229
|
+
node --test test/*.test.mjs
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
When npm is available:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm test
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Live smoke tests are opt-in:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
DDYS_LIVE_TEST=1 node test/live-smoke.mjs
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Authenticated live smoke tests also need:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
DDYS_API_KEY=ddys_xxx
|
|
248
|
+
```
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# DDYS JavaScript SDK
|
|
2
|
+
|
|
3
|
+
[English](README.md) | [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
DDYS Open API 官方 JavaScript SDK。
|
|
6
|
+
|
|
7
|
+
官网:[低端影视](https://ddys.io/)
|
|
8
|
+
|
|
9
|
+
这个包是 DDYS 开放生态的基础库,后续官方 Widgets、CMS 插件、静态站模板、Bot、MCP Server 和第三方应用都可以基于它调用 API。
|
|
10
|
+
|
|
11
|
+
## 功能特点
|
|
12
|
+
|
|
13
|
+
- 覆盖当前文档中的全部 `/api/v1` 接口。
|
|
14
|
+
- 公开读取接口无需 API Key。
|
|
15
|
+
- 支持需要鉴权的接口:`Authorization: Bearer ddys_xxx`。
|
|
16
|
+
- 自带 TypeScript 类型声明。
|
|
17
|
+
- 同时提供 ESM 和 CommonJS 构建。
|
|
18
|
+
- 使用标准 `fetch`。
|
|
19
|
+
- 零运行时依赖。
|
|
20
|
+
- 支持自定义 API Base URL,方便配合 Cloudflare Worker 缓存代理。
|
|
21
|
+
- 统一错误类、超时处理、可选 GET 重试和分页返回结构。
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @ddysiodev/js-sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
CDN 地址:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
https://cdn.jsdelivr.net/npm/@ddysiodev/js-sdk/dist/index.js
|
|
33
|
+
https://unpkg.com/@ddysiodev/js-sdk/dist/index.js
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 快速开始
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
import { createDdysClient } from '@ddysiodev/js-sdk';
|
|
40
|
+
|
|
41
|
+
const ddys = createDdysClient();
|
|
42
|
+
|
|
43
|
+
const latest = await ddys.latest({ limit: 12 });
|
|
44
|
+
const movie = await ddys.movies.detail('interstellar');
|
|
45
|
+
const sources = await ddys.movies.sources('interstellar');
|
|
46
|
+
|
|
47
|
+
console.log(latest, movie.title, sources.download);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 鉴权接口
|
|
51
|
+
|
|
52
|
+
评论、求片、举报、关注、当前用户资料等接口需要用户 API Key。
|
|
53
|
+
|
|
54
|
+
API Key 在这里生成:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
https://ddys.io/user/profile
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
服务端使用示例:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { createDdysClient } from '@ddysiodev/js-sdk';
|
|
64
|
+
|
|
65
|
+
const ddys = createDdysClient({
|
|
66
|
+
apiKey: process.env.DDYS_API_KEY
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const request = await ddys.requests.create({
|
|
70
|
+
title: 'Dune 2',
|
|
71
|
+
year: 2024,
|
|
72
|
+
type: 'movie',
|
|
73
|
+
douban_id: '35652650'
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
console.log(request.url);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
不要把站长自己的 API Key 打包进公开浏览器 JavaScript。公开展示类功能不需要 API Key。
|
|
80
|
+
|
|
81
|
+
## 自定义 API 地址
|
|
82
|
+
|
|
83
|
+
如果你通过自己的 Worker 做缓存代理,可以这样配置:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
const ddys = createDdysClient({
|
|
87
|
+
baseUrl: 'https://example.com/ddys-api'
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 方法列表
|
|
92
|
+
|
|
93
|
+
### 影片
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
await ddys.movies.list({ type: 'movie', sort: 'rating', page: 1, per_page: 24 });
|
|
97
|
+
await ddys.movies.detail('interstellar');
|
|
98
|
+
await ddys.movies.sources('interstellar');
|
|
99
|
+
await ddys.movies.related('interstellar');
|
|
100
|
+
await ddys.movies.comments('interstellar', { page: 1, per_page: 20 });
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 搜索与发现
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
await ddys.search({ q: '星际', type: 'movie', per_page: 10 });
|
|
107
|
+
await ddys.suggest('星际');
|
|
108
|
+
await ddys.hot();
|
|
109
|
+
await ddys.latest({ limit: 30 });
|
|
110
|
+
await ddys.calendar({ year: 2026, month: 7 });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 字典
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
await ddys.dictionaries.types();
|
|
117
|
+
await ddys.dictionaries.genres();
|
|
118
|
+
await ddys.dictionaries.regions();
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 片单、分享、求片、动态
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
await ddys.collections.list();
|
|
125
|
+
await ddys.collections.detail('best-sci-fi');
|
|
126
|
+
await ddys.shares.list();
|
|
127
|
+
await ddys.shares.detail(1081);
|
|
128
|
+
await ddys.requests.list();
|
|
129
|
+
await ddys.activities.list({ type: 'share' });
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 用户
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
await ddys.users.profile('diduan');
|
|
136
|
+
await ddys.me();
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 评论、举报、关注
|
|
140
|
+
|
|
141
|
+
```js
|
|
142
|
+
await ddys.comments.create({
|
|
143
|
+
target_type: 'movie',
|
|
144
|
+
target_id: 4786,
|
|
145
|
+
content: '好片'
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
await ddys.comments.delete(12345);
|
|
149
|
+
|
|
150
|
+
await ddys.reports.invalidResource({
|
|
151
|
+
movie_id: 4786,
|
|
152
|
+
resource_id: 1002
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
await ddys.follow.follow('diduan');
|
|
156
|
+
await ddys.follow.unfollow('diduan');
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 分页
|
|
160
|
+
|
|
161
|
+
分页接口返回:
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
const result = await ddys.movies.list({ page: 1, per_page: 24 });
|
|
165
|
+
|
|
166
|
+
console.log(result.data);
|
|
167
|
+
console.log(result.meta.total);
|
|
168
|
+
console.log(result.meta.total_pages);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
SDK 同时支持 `perPage`,会自动转换为 API 使用的 `per_page`。
|
|
172
|
+
|
|
173
|
+
## 底层 request
|
|
174
|
+
|
|
175
|
+
高级开发者可以直接使用 `request()`,它返回完整 API envelope:
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
const envelope = await ddys.request('/movies', {
|
|
179
|
+
query: { page: 1, per_page: 3 }
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
console.log(envelope.success, envelope.data, envelope.meta);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## 错误处理
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
import { DdysApiError } from '@ddysiodev/js-sdk';
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
await ddys.movies.detail('missing');
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (error instanceof DdysApiError) {
|
|
194
|
+
console.error(error.status, error.message, error.endpoint);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
错误类:
|
|
200
|
+
|
|
201
|
+
- `DdysApiError`
|
|
202
|
+
- `DdysTimeoutError`
|
|
203
|
+
- `DdysNetworkError`
|
|
204
|
+
- `DdysParseError`
|
|
205
|
+
|
|
206
|
+
## 运行环境
|
|
207
|
+
|
|
208
|
+
- Node.js `>=22`
|
|
209
|
+
- 现代浏览器
|
|
210
|
+
- Cloudflare Workers
|
|
211
|
+
- Vercel Edge / Netlify Edge 等运行时
|
|
212
|
+
|
|
213
|
+
如果运行时没有全局 `fetch`,可以手动传入:
|
|
214
|
+
|
|
215
|
+
```js
|
|
216
|
+
const ddys = createDdysClient({ fetch: customFetch });
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## 开发
|
|
220
|
+
|
|
221
|
+
本项目零运行时依赖,可以只用 Node 构建和测试:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
node scripts/build.mjs
|
|
225
|
+
node --test test/*.test.mjs
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
如果 npm 可用:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npm test
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
线上 smoke test 默认不运行:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
DDYS_LIVE_TEST=1 node test/live-smoke.mjs
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
鉴权 smoke test 还需要:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
DDYS_API_KEY=ddys_xxx
|
|
244
|
+
```
|