@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 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
+ ```
@@ -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
+ ```