@moontaiworks/fanbox-dl 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/LICENSE +21 -0
- package/README.md +148 -0
- package/dist/bundle/index.cjs +2 -0
- package/dist/bundle/index.cjs.map +1 -0
- package/dist/bundle/index.d.cts +296 -0
- package/dist/bundle/index.d.ts +296 -0
- package/dist/bundle/index.js +2 -0
- package/dist/bundle/index.js.map +1 -0
- package/dist/cjs/client-options.d.ts +8 -0
- package/dist/cjs/client-options.d.ts.map +1 -0
- package/dist/cjs/client-options.js +3 -0
- package/dist/cjs/client-options.js.map +1 -0
- package/dist/cjs/client.d.ts +31 -0
- package/dist/cjs/client.d.ts.map +1 -0
- package/dist/cjs/client.js +107 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/downloader/asset.d.ts +30 -0
- package/dist/cjs/downloader/asset.d.ts.map +1 -0
- package/dist/cjs/downloader/asset.js +99 -0
- package/dist/cjs/downloader/asset.js.map +1 -0
- package/dist/cjs/downloader/cli.d.ts +8 -0
- package/dist/cjs/downloader/cli.d.ts.map +1 -0
- package/dist/cjs/downloader/cli.js +168 -0
- package/dist/cjs/downloader/cli.js.map +1 -0
- package/dist/cjs/downloader/discovery.d.ts +12 -0
- package/dist/cjs/downloader/discovery.d.ts.map +1 -0
- package/dist/cjs/downloader/discovery.js +87 -0
- package/dist/cjs/downloader/discovery.js.map +1 -0
- package/dist/cjs/downloader/errors.d.ts +5 -0
- package/dist/cjs/downloader/errors.d.ts.map +1 -0
- package/dist/cjs/downloader/errors.js +40 -0
- package/dist/cjs/downloader/errors.js.map +1 -0
- package/dist/cjs/downloader/index.d.ts +3 -0
- package/dist/cjs/downloader/index.d.ts.map +1 -0
- package/dist/cjs/downloader/index.js +8 -0
- package/dist/cjs/downloader/index.js.map +1 -0
- package/dist/cjs/downloader/logger.d.ts +16 -0
- package/dist/cjs/downloader/logger.d.ts.map +1 -0
- package/dist/cjs/downloader/logger.js +51 -0
- package/dist/cjs/downloader/logger.js.map +1 -0
- package/dist/cjs/downloader/manifest.d.ts +31 -0
- package/dist/cjs/downloader/manifest.d.ts.map +1 -0
- package/dist/cjs/downloader/manifest.js +53 -0
- package/dist/cjs/downloader/manifest.js.map +1 -0
- package/dist/cjs/downloader/markdown.d.ts +4 -0
- package/dist/cjs/downloader/markdown.d.ts.map +1 -0
- package/dist/cjs/downloader/markdown.js +62 -0
- package/dist/cjs/downloader/markdown.js.map +1 -0
- package/dist/cjs/downloader/options.d.ts +24 -0
- package/dist/cjs/downloader/options.d.ts.map +1 -0
- package/dist/cjs/downloader/options.js +135 -0
- package/dist/cjs/downloader/options.js.map +1 -0
- package/dist/cjs/downloader/path.d.ts +15 -0
- package/dist/cjs/downloader/path.d.ts.map +1 -0
- package/dist/cjs/downloader/path.js +79 -0
- package/dist/cjs/downloader/path.js.map +1 -0
- package/dist/cjs/downloader/resolver.d.ts +16 -0
- package/dist/cjs/downloader/resolver.d.ts.map +1 -0
- package/dist/cjs/downloader/resolver.js +21 -0
- package/dist/cjs/downloader/resolver.js.map +1 -0
- package/dist/cjs/downloader/scheduler.d.ts +19 -0
- package/dist/cjs/downloader/scheduler.d.ts.map +1 -0
- package/dist/cjs/downloader/scheduler.js +124 -0
- package/dist/cjs/downloader/scheduler.js.map +1 -0
- package/dist/cjs/downloader/sync.d.ts +21 -0
- package/dist/cjs/downloader/sync.d.ts.map +1 -0
- package/dist/cjs/downloader/sync.js +317 -0
- package/dist/cjs/downloader/sync.js.map +1 -0
- package/dist/cjs/endpoints/creator-get.d.ts +7 -0
- package/dist/cjs/endpoints/creator-get.d.ts.map +1 -0
- package/dist/cjs/endpoints/creator-get.js +5 -0
- package/dist/cjs/endpoints/creator-get.js.map +1 -0
- package/dist/cjs/endpoints/creator-list-following.d.ts +4 -0
- package/dist/cjs/endpoints/creator-list-following.d.ts.map +1 -0
- package/dist/cjs/endpoints/creator-list-following.js +5 -0
- package/dist/cjs/endpoints/creator-list-following.js.map +1 -0
- package/dist/cjs/endpoints/fanbox-envelope.d.ts +4 -0
- package/dist/cjs/endpoints/fanbox-envelope.d.ts.map +1 -0
- package/dist/cjs/endpoints/fanbox-envelope.js +3 -0
- package/dist/cjs/endpoints/fanbox-envelope.js.map +1 -0
- package/dist/cjs/endpoints/models/creator.d.ts +40 -0
- package/dist/cjs/endpoints/models/creator.d.ts.map +1 -0
- package/dist/cjs/endpoints/models/creator.js +3 -0
- package/dist/cjs/endpoints/models/creator.js.map +1 -0
- package/dist/cjs/endpoints/models/plan.d.ts +17 -0
- package/dist/cjs/endpoints/models/plan.d.ts.map +1 -0
- package/dist/cjs/endpoints/models/plan.js +3 -0
- package/dist/cjs/endpoints/models/plan.js.map +1 -0
- package/dist/cjs/endpoints/models/post.d.ts +134 -0
- package/dist/cjs/endpoints/models/post.d.ts.map +1 -0
- package/dist/cjs/endpoints/models/post.js +3 -0
- package/dist/cjs/endpoints/models/post.js.map +1 -0
- package/dist/cjs/endpoints/models/user.d.ts +6 -0
- package/dist/cjs/endpoints/models/user.d.ts.map +1 -0
- package/dist/cjs/endpoints/models/user.js +3 -0
- package/dist/cjs/endpoints/models/user.js.map +1 -0
- package/dist/cjs/endpoints/plan-list-creator.d.ts +7 -0
- package/dist/cjs/endpoints/plan-list-creator.d.ts.map +1 -0
- package/dist/cjs/endpoints/plan-list-creator.js +5 -0
- package/dist/cjs/endpoints/plan-list-creator.js.map +1 -0
- package/dist/cjs/endpoints/plan-list-supporting.d.ts +4 -0
- package/dist/cjs/endpoints/plan-list-supporting.d.ts.map +1 -0
- package/dist/cjs/endpoints/plan-list-supporting.js +5 -0
- package/dist/cjs/endpoints/plan-list-supporting.js.map +1 -0
- package/dist/cjs/endpoints/post-info.d.ts +7 -0
- package/dist/cjs/endpoints/post-info.d.ts.map +1 -0
- package/dist/cjs/endpoints/post-info.js +5 -0
- package/dist/cjs/endpoints/post-info.js.map +1 -0
- package/dist/cjs/endpoints/post-list-creator.d.ts +10 -0
- package/dist/cjs/endpoints/post-list-creator.d.ts.map +1 -0
- package/dist/cjs/endpoints/post-list-creator.js +5 -0
- package/dist/cjs/endpoints/post-list-creator.js.map +1 -0
- package/dist/cjs/endpoints/post-list-home.d.ts +5 -0
- package/dist/cjs/endpoints/post-list-home.d.ts.map +1 -0
- package/dist/cjs/endpoints/post-list-home.js +5 -0
- package/dist/cjs/endpoints/post-list-home.js.map +1 -0
- package/dist/cjs/endpoints/post-list-supporting.d.ts +5 -0
- package/dist/cjs/endpoints/post-list-supporting.d.ts.map +1 -0
- package/dist/cjs/endpoints/post-list-supporting.js +5 -0
- package/dist/cjs/endpoints/post-list-supporting.js.map +1 -0
- package/dist/cjs/endpoints/post-paginate-creator.d.ts +8 -0
- package/dist/cjs/endpoints/post-paginate-creator.d.ts.map +1 -0
- package/dist/cjs/endpoints/post-paginate-creator.js +5 -0
- package/dist/cjs/endpoints/post-paginate-creator.js.map +1 -0
- package/dist/cjs/fanbox-headers.d.ts +7 -0
- package/dist/cjs/fanbox-headers.d.ts.map +1 -0
- package/dist/cjs/fanbox-headers.js +23 -0
- package/dist/cjs/fanbox-headers.js.map +1 -0
- package/dist/cjs/http.d.ts +31 -0
- package/dist/cjs/http.d.ts.map +1 -0
- package/dist/cjs/http.js +200 -0
- package/dist/cjs/http.js.map +1 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/types.d.ts +16 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/client-options.d.ts +8 -0
- package/dist/esm/client-options.d.ts.map +1 -0
- package/dist/esm/client-options.js +2 -0
- package/dist/esm/client-options.js.map +1 -0
- package/dist/esm/client.d.ts +31 -0
- package/dist/esm/client.d.ts.map +1 -0
- package/dist/esm/client.js +102 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/downloader/asset.d.ts +30 -0
- package/dist/esm/downloader/asset.d.ts.map +1 -0
- package/dist/esm/downloader/asset.js +91 -0
- package/dist/esm/downloader/asset.js.map +1 -0
- package/dist/esm/downloader/cli.d.ts +8 -0
- package/dist/esm/downloader/cli.d.ts.map +1 -0
- package/dist/esm/downloader/cli.js +164 -0
- package/dist/esm/downloader/cli.js.map +1 -0
- package/dist/esm/downloader/discovery.d.ts +12 -0
- package/dist/esm/downloader/discovery.d.ts.map +1 -0
- package/dist/esm/downloader/discovery.js +84 -0
- package/dist/esm/downloader/discovery.js.map +1 -0
- package/dist/esm/downloader/errors.d.ts +5 -0
- package/dist/esm/downloader/errors.d.ts.map +1 -0
- package/dist/esm/downloader/errors.js +36 -0
- package/dist/esm/downloader/errors.js.map +1 -0
- package/dist/esm/downloader/index.d.ts +3 -0
- package/dist/esm/downloader/index.d.ts.map +1 -0
- package/dist/esm/downloader/index.js +6 -0
- package/dist/esm/downloader/index.js.map +1 -0
- package/dist/esm/downloader/logger.d.ts +16 -0
- package/dist/esm/downloader/logger.d.ts.map +1 -0
- package/dist/esm/downloader/logger.js +47 -0
- package/dist/esm/downloader/logger.js.map +1 -0
- package/dist/esm/downloader/manifest.d.ts +31 -0
- package/dist/esm/downloader/manifest.d.ts.map +1 -0
- package/dist/esm/downloader/manifest.js +46 -0
- package/dist/esm/downloader/manifest.js.map +1 -0
- package/dist/esm/downloader/markdown.d.ts +4 -0
- package/dist/esm/downloader/markdown.d.ts.map +1 -0
- package/dist/esm/downloader/markdown.js +59 -0
- package/dist/esm/downloader/markdown.js.map +1 -0
- package/dist/esm/downloader/options.d.ts +24 -0
- package/dist/esm/downloader/options.d.ts.map +1 -0
- package/dist/esm/downloader/options.js +130 -0
- package/dist/esm/downloader/options.js.map +1 -0
- package/dist/esm/downloader/path.d.ts +15 -0
- package/dist/esm/downloader/path.d.ts.map +1 -0
- package/dist/esm/downloader/path.js +69 -0
- package/dist/esm/downloader/path.js.map +1 -0
- package/dist/esm/downloader/resolver.d.ts +16 -0
- package/dist/esm/downloader/resolver.d.ts.map +1 -0
- package/dist/esm/downloader/resolver.js +18 -0
- package/dist/esm/downloader/resolver.js.map +1 -0
- package/dist/esm/downloader/scheduler.d.ts +19 -0
- package/dist/esm/downloader/scheduler.d.ts.map +1 -0
- package/dist/esm/downloader/scheduler.js +120 -0
- package/dist/esm/downloader/scheduler.js.map +1 -0
- package/dist/esm/downloader/sync.d.ts +21 -0
- package/dist/esm/downloader/sync.d.ts.map +1 -0
- package/dist/esm/downloader/sync.js +311 -0
- package/dist/esm/downloader/sync.js.map +1 -0
- package/dist/esm/endpoints/creator-get.d.ts +7 -0
- package/dist/esm/endpoints/creator-get.d.ts.map +1 -0
- package/dist/esm/endpoints/creator-get.js +2 -0
- package/dist/esm/endpoints/creator-get.js.map +1 -0
- package/dist/esm/endpoints/creator-list-following.d.ts +4 -0
- package/dist/esm/endpoints/creator-list-following.d.ts.map +1 -0
- package/dist/esm/endpoints/creator-list-following.js +2 -0
- package/dist/esm/endpoints/creator-list-following.js.map +1 -0
- package/dist/esm/endpoints/fanbox-envelope.d.ts +4 -0
- package/dist/esm/endpoints/fanbox-envelope.d.ts.map +1 -0
- package/dist/esm/endpoints/fanbox-envelope.js +2 -0
- package/dist/esm/endpoints/fanbox-envelope.js.map +1 -0
- package/dist/esm/endpoints/models/creator.d.ts +40 -0
- package/dist/esm/endpoints/models/creator.d.ts.map +1 -0
- package/dist/esm/endpoints/models/creator.js +2 -0
- package/dist/esm/endpoints/models/creator.js.map +1 -0
- package/dist/esm/endpoints/models/plan.d.ts +17 -0
- package/dist/esm/endpoints/models/plan.d.ts.map +1 -0
- package/dist/esm/endpoints/models/plan.js +2 -0
- package/dist/esm/endpoints/models/plan.js.map +1 -0
- package/dist/esm/endpoints/models/post.d.ts +134 -0
- package/dist/esm/endpoints/models/post.d.ts.map +1 -0
- package/dist/esm/endpoints/models/post.js +2 -0
- package/dist/esm/endpoints/models/post.js.map +1 -0
- package/dist/esm/endpoints/models/user.d.ts +6 -0
- package/dist/esm/endpoints/models/user.d.ts.map +1 -0
- package/dist/esm/endpoints/models/user.js +2 -0
- package/dist/esm/endpoints/models/user.js.map +1 -0
- package/dist/esm/endpoints/plan-list-creator.d.ts +7 -0
- package/dist/esm/endpoints/plan-list-creator.d.ts.map +1 -0
- package/dist/esm/endpoints/plan-list-creator.js +2 -0
- package/dist/esm/endpoints/plan-list-creator.js.map +1 -0
- package/dist/esm/endpoints/plan-list-supporting.d.ts +4 -0
- package/dist/esm/endpoints/plan-list-supporting.d.ts.map +1 -0
- package/dist/esm/endpoints/plan-list-supporting.js +2 -0
- package/dist/esm/endpoints/plan-list-supporting.js.map +1 -0
- package/dist/esm/endpoints/post-info.d.ts +7 -0
- package/dist/esm/endpoints/post-info.d.ts.map +1 -0
- package/dist/esm/endpoints/post-info.js +2 -0
- package/dist/esm/endpoints/post-info.js.map +1 -0
- package/dist/esm/endpoints/post-list-creator.d.ts +10 -0
- package/dist/esm/endpoints/post-list-creator.d.ts.map +1 -0
- package/dist/esm/endpoints/post-list-creator.js +2 -0
- package/dist/esm/endpoints/post-list-creator.js.map +1 -0
- package/dist/esm/endpoints/post-list-home.d.ts +5 -0
- package/dist/esm/endpoints/post-list-home.d.ts.map +1 -0
- package/dist/esm/endpoints/post-list-home.js +2 -0
- package/dist/esm/endpoints/post-list-home.js.map +1 -0
- package/dist/esm/endpoints/post-list-supporting.d.ts +5 -0
- package/dist/esm/endpoints/post-list-supporting.d.ts.map +1 -0
- package/dist/esm/endpoints/post-list-supporting.js +2 -0
- package/dist/esm/endpoints/post-list-supporting.js.map +1 -0
- package/dist/esm/endpoints/post-paginate-creator.d.ts +8 -0
- package/dist/esm/endpoints/post-paginate-creator.d.ts.map +1 -0
- package/dist/esm/endpoints/post-paginate-creator.js +2 -0
- package/dist/esm/endpoints/post-paginate-creator.js.map +1 -0
- package/dist/esm/fanbox-headers.d.ts +7 -0
- package/dist/esm/fanbox-headers.d.ts.map +1 -0
- package/dist/esm/fanbox-headers.js +19 -0
- package/dist/esm/fanbox-headers.js.map +1 -0
- package/dist/esm/http.d.ts +31 -0
- package/dist/esm/http.d.ts.map +1 -0
- package/dist/esm/http.js +195 -0
- package/dist/esm/http.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/types.d.ts +16 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +98 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _FanboxClient_instances, _FanboxClient_baseUrl, _FanboxClient_headers, _FanboxClient_transport, _FanboxClient_get;
|
|
13
|
+
import { CREATOR_GET_PATH, } from "./endpoints/creator-get.js";
|
|
14
|
+
import { CREATOR_LIST_FOLLOWING_PATH, } from "./endpoints/creator-list-following.js";
|
|
15
|
+
import { PLAN_LIST_CREATOR_PATH, } from "./endpoints/plan-list-creator.js";
|
|
16
|
+
import { PLAN_LIST_SUPPORTING_PATH, } from "./endpoints/plan-list-supporting.js";
|
|
17
|
+
import { POST_INFO_PATH, } from "./endpoints/post-info.js";
|
|
18
|
+
import { POST_LIST_CREATOR_PATH, } from "./endpoints/post-list-creator.js";
|
|
19
|
+
import { POST_LIST_HOME_PATH, } from "./endpoints/post-list-home.js";
|
|
20
|
+
import { POST_LIST_SUPPORTING_PATH, } from "./endpoints/post-list-supporting.js";
|
|
21
|
+
import { POST_PAGINATE_CREATOR_PATH, } from "./endpoints/post-paginate-creator.js";
|
|
22
|
+
import { createFanboxRequestHeaders } from "./fanbox-headers.js";
|
|
23
|
+
import { Http2Transport, } from "./http.js";
|
|
24
|
+
const DEFAULT_BASE_URL = "https://api.fanbox.cc";
|
|
25
|
+
export class FanboxApiError extends Error {
|
|
26
|
+
constructor(response, body) {
|
|
27
|
+
super(`FANBOX API request failed: ${response.status} ${response.statusText}`);
|
|
28
|
+
this.name = "FanboxApiError";
|
|
29
|
+
this.body = body;
|
|
30
|
+
this.status = response.status;
|
|
31
|
+
this.statusText = response.statusText;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class FanboxClient {
|
|
35
|
+
constructor(options = {}) {
|
|
36
|
+
_FanboxClient_instances.add(this);
|
|
37
|
+
_FanboxClient_baseUrl.set(this, void 0);
|
|
38
|
+
_FanboxClient_headers.set(this, void 0);
|
|
39
|
+
_FanboxClient_transport.set(this, void 0);
|
|
40
|
+
__classPrivateFieldSet(this, _FanboxClient_baseUrl, options.baseUrl ?? DEFAULT_BASE_URL, "f");
|
|
41
|
+
__classPrivateFieldSet(this, _FanboxClient_headers, createFanboxRequestHeaders({
|
|
42
|
+
cookie: options.cookie,
|
|
43
|
+
userAgent: options.userAgent,
|
|
44
|
+
}), "f");
|
|
45
|
+
__classPrivateFieldSet(this, _FanboxClient_transport, options.transport ?? new Http2Transport(), "f");
|
|
46
|
+
}
|
|
47
|
+
getCreator(params) {
|
|
48
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, CREATOR_GET_PATH, params);
|
|
49
|
+
}
|
|
50
|
+
getPost(params) {
|
|
51
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, POST_INFO_PATH, params);
|
|
52
|
+
}
|
|
53
|
+
listCreatorPlans(params) {
|
|
54
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, PLAN_LIST_CREATOR_PATH, params);
|
|
55
|
+
}
|
|
56
|
+
listCreatorPosts(params) {
|
|
57
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, POST_LIST_CREATOR_PATH, params);
|
|
58
|
+
}
|
|
59
|
+
listFollowingCreators() {
|
|
60
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, CREATOR_LIST_FOLLOWING_PATH);
|
|
61
|
+
}
|
|
62
|
+
listHomePosts(params = {}) {
|
|
63
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, POST_LIST_HOME_PATH, params);
|
|
64
|
+
}
|
|
65
|
+
listSupportingPlans() {
|
|
66
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, PLAN_LIST_SUPPORTING_PATH);
|
|
67
|
+
}
|
|
68
|
+
listSupportingPosts(params = {}) {
|
|
69
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, POST_LIST_SUPPORTING_PATH, params);
|
|
70
|
+
}
|
|
71
|
+
paginateCreatorPosts(params) {
|
|
72
|
+
return __classPrivateFieldGet(this, _FanboxClient_instances, "m", _FanboxClient_get).call(this, POST_PAGINATE_CREATOR_PATH, params);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
_FanboxClient_baseUrl = new WeakMap(), _FanboxClient_headers = new WeakMap(), _FanboxClient_transport = new WeakMap(), _FanboxClient_instances = new WeakSet(), _FanboxClient_get = async function _FanboxClient_get(path, query = {}) {
|
|
76
|
+
const url = new URL(path, __classPrivateFieldGet(this, _FanboxClient_baseUrl, "f").endsWith("/") ? __classPrivateFieldGet(this, _FanboxClient_baseUrl, "f") : `${__classPrivateFieldGet(this, _FanboxClient_baseUrl, "f")}/`);
|
|
77
|
+
for (const [key, value] of Object.entries(query)) {
|
|
78
|
+
if (value !== undefined) {
|
|
79
|
+
url.searchParams.set(key, String(value));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const response = await __classPrivateFieldGet(this, _FanboxClient_transport, "f").request({
|
|
83
|
+
headers: __classPrivateFieldGet(this, _FanboxClient_headers, "f"),
|
|
84
|
+
method: "GET",
|
|
85
|
+
url,
|
|
86
|
+
});
|
|
87
|
+
const body = await readResponseBody(response);
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
throw new FanboxApiError(response, body);
|
|
90
|
+
}
|
|
91
|
+
return body.body;
|
|
92
|
+
};
|
|
93
|
+
async function readResponseBody(response) {
|
|
94
|
+
const text = await response.text();
|
|
95
|
+
try {
|
|
96
|
+
return JSON.parse(text);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return text;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type HttpResponse, type HttpTransport } from "../http.js";
|
|
2
|
+
import type { RequestScheduler } from "./scheduler.js";
|
|
3
|
+
export interface AssetDownloaderOptions {
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
scheduler: RequestScheduler;
|
|
6
|
+
transport?: HttpTransport;
|
|
7
|
+
}
|
|
8
|
+
export interface AssetDownloadOptions {
|
|
9
|
+
publishedDatetime: string;
|
|
10
|
+
relativePath: string;
|
|
11
|
+
rootDirectory: string;
|
|
12
|
+
url: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AssetDownloadResult {
|
|
15
|
+
bytes: number;
|
|
16
|
+
sha256: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class AssetDownloader {
|
|
19
|
+
#private;
|
|
20
|
+
constructor(options: AssetDownloaderOptions);
|
|
21
|
+
download(options: AssetDownloadOptions): Promise<AssetDownloadResult>;
|
|
22
|
+
}
|
|
23
|
+
export declare class AssetDownloadError extends Error {
|
|
24
|
+
readonly body: unknown;
|
|
25
|
+
readonly status: number;
|
|
26
|
+
readonly statusText: string;
|
|
27
|
+
readonly url: string;
|
|
28
|
+
constructor(response: HttpResponse, url: string, body: unknown);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=asset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../../src/downloader/asset.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,eAAe;;gBAKP,OAAO,EAAE,sBAAsB;IAMrC,QAAQ,CACnB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC;CA8ChC;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAgB,IAAI,EAAE,OAAO,CAAC;IAC9B,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,GAAG,EAAE,MAAM,CAAC;gBAET,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;CAQtE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _AssetDownloader_headers, _AssetDownloader_scheduler, _AssetDownloader_transport;
|
|
13
|
+
import { createHash } from "node:crypto";
|
|
14
|
+
import { createReadStream, createWriteStream } from "node:fs";
|
|
15
|
+
import { mkdir, rename, stat, utimes } from "node:fs/promises";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { pipeline } from "node:stream/promises";
|
|
18
|
+
import { Http2Transport, } from "../http.js";
|
|
19
|
+
import { assertPathBudget } from "./path.js";
|
|
20
|
+
export class AssetDownloader {
|
|
21
|
+
constructor(options) {
|
|
22
|
+
_AssetDownloader_headers.set(this, void 0);
|
|
23
|
+
_AssetDownloader_scheduler.set(this, void 0);
|
|
24
|
+
_AssetDownloader_transport.set(this, void 0);
|
|
25
|
+
__classPrivateFieldSet(this, _AssetDownloader_headers, options.headers ?? {}, "f");
|
|
26
|
+
__classPrivateFieldSet(this, _AssetDownloader_scheduler, options.scheduler, "f");
|
|
27
|
+
__classPrivateFieldSet(this, _AssetDownloader_transport, options.transport ?? new Http2Transport(), "f");
|
|
28
|
+
}
|
|
29
|
+
async download(options) {
|
|
30
|
+
const destination = path.join(options.rootDirectory, options.relativePath);
|
|
31
|
+
const temporaryPath = `${destination}.part`;
|
|
32
|
+
assertPathBudget(temporaryPath);
|
|
33
|
+
await mkdir(path.dirname(destination), { recursive: true });
|
|
34
|
+
const partialBytes = await stat(temporaryPath)
|
|
35
|
+
.then((result) => result.size)
|
|
36
|
+
.catch(() => 0);
|
|
37
|
+
const headers = { ...__classPrivateFieldGet(this, _AssetDownloader_headers, "f") };
|
|
38
|
+
if (partialBytes > 0) {
|
|
39
|
+
headers.Range = `bytes=${partialBytes}-`;
|
|
40
|
+
}
|
|
41
|
+
const response = await __classPrivateFieldGet(this, _AssetDownloader_scheduler, "f").request(() => __classPrivateFieldGet(this, _AssetDownloader_transport, "f").request({
|
|
42
|
+
headers,
|
|
43
|
+
method: "GET",
|
|
44
|
+
url: options.url,
|
|
45
|
+
}));
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new AssetDownloadError(response, options.url, await readResponseBody(response));
|
|
48
|
+
}
|
|
49
|
+
await pipeline(response.body, createWriteStream(temporaryPath, {
|
|
50
|
+
flags: response.status === 206 && partialBytes > 0 ? "a" : "w",
|
|
51
|
+
}));
|
|
52
|
+
await rename(temporaryPath, destination);
|
|
53
|
+
const modified = response.headers.get("Last-Modified");
|
|
54
|
+
const timestamp = modified
|
|
55
|
+
? new Date(modified)
|
|
56
|
+
: new Date(options.publishedDatetime);
|
|
57
|
+
await utimes(destination, timestamp, timestamp);
|
|
58
|
+
return {
|
|
59
|
+
bytes: (await stat(destination)).size,
|
|
60
|
+
sha256: await hashFile(destination),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
_AssetDownloader_headers = new WeakMap(), _AssetDownloader_scheduler = new WeakMap(), _AssetDownloader_transport = new WeakMap();
|
|
65
|
+
export class AssetDownloadError extends Error {
|
|
66
|
+
constructor(response, url, body) {
|
|
67
|
+
super(`Asset download failed: ${response.status} ${url}`);
|
|
68
|
+
this.name = "AssetDownloadError";
|
|
69
|
+
this.body = body;
|
|
70
|
+
this.status = response.status;
|
|
71
|
+
this.statusText = response.statusText;
|
|
72
|
+
this.url = url;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function hashFile(filePath) {
|
|
76
|
+
const hash = createHash("sha256");
|
|
77
|
+
for await (const chunk of createReadStream(filePath)) {
|
|
78
|
+
hash.update(chunk);
|
|
79
|
+
}
|
|
80
|
+
return hash.digest("hex");
|
|
81
|
+
}
|
|
82
|
+
async function readResponseBody(response) {
|
|
83
|
+
const text = await response.text();
|
|
84
|
+
try {
|
|
85
|
+
return JSON.parse(text);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return text;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=asset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset.js","sourceRoot":"","sources":["../../../src/downloader/asset.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type HttpTransport } from "../http.js";
|
|
2
|
+
export interface RunCliDependencies {
|
|
3
|
+
transport?: HttpTransport;
|
|
4
|
+
write?: (line: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare const DOWNLOAD_HELP = "Usage: fanbox-dl download [options]\n\nDownload FANBOX posts for selected creators.\n\nSelectors:\n --creator <id> Add a creator ID. Can be repeated.\n --following Add all followed creators.\n --supporting Add all supporting creators.\n --ignore-creator <id> Exclude a creator ID. Can be repeated.\n\nAuth:\n --cookie <value> Raw session ID or FANBOXSESSID=... cookie.\n --cookie-file <path> Read raw cookie or Netscape cookies.txt.\n --user-agent <value> Send the User-Agent from your logged-in browser.\n FANBOX_SESSION_ID Environment fallback.\n FANBOX_USER_AGENT User-Agent environment fallback.\n\nDownload:\n --output <path> Output directory. Default: fanbox-downloads.\n --dry-run List creators/posts without downloading or writing.\n --flat-posts Store post files directly under each creator.\n --verify-assets Verify existing asset size and SHA-256 locally.\n\nRequests:\n --concurrency <n> Concurrent requests. Default: 3.\n --request-interval-ms <n> Delay between request starts. Default: 0.\n --rate-limit-pause-ms <n> Pause after 429 without Retry-After. Default: 60000.\n --max-retries <n> Retry attempts. Default: 5.\n\nOutput:\n --log-format json|pretty Default: json.\n --log-level <level> debug|info|warn|error. Default: info.\n --help Show this help.\n";
|
|
7
|
+
export declare function runCli(args: string[], env?: NodeJS.ProcessEnv, dependencies?: RunCliDependencies): Promise<number>;
|
|
8
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/downloader/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAWhE,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,eAAO,MAAM,aAAa,w7CAiCzB,CAAC;AAEF,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,YAAY,GAAE,kBAAuB,GACpC,OAAO,CAAC,MAAM,CAAC,CAqHjB"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { FanboxClient } from "../client.js";
|
|
2
|
+
import { createFanboxRequestHeaders } from "../fanbox-headers.js";
|
|
3
|
+
import { Http2Transport } from "../http.js";
|
|
4
|
+
import { AssetDownloader } from "./asset.js";
|
|
5
|
+
import { discoverCreatorPosts } from "./discovery.js";
|
|
6
|
+
import { logDebugErrorResponse } from "./errors.js";
|
|
7
|
+
import { createLogger } from "./logger.js";
|
|
8
|
+
import { CliUsageError, parseDownloadOptions } from "./options.js";
|
|
9
|
+
import { assertPathBudget } from "./path.js";
|
|
10
|
+
import { resolveCreatorIds } from "./resolver.js";
|
|
11
|
+
import { RequestScheduler } from "./scheduler.js";
|
|
12
|
+
import { syncCreator } from "./sync.js";
|
|
13
|
+
export const DOWNLOAD_HELP = `Usage: fanbox-dl download [options]
|
|
14
|
+
|
|
15
|
+
Download FANBOX posts for selected creators.
|
|
16
|
+
|
|
17
|
+
Selectors:
|
|
18
|
+
--creator <id> Add a creator ID. Can be repeated.
|
|
19
|
+
--following Add all followed creators.
|
|
20
|
+
--supporting Add all supporting creators.
|
|
21
|
+
--ignore-creator <id> Exclude a creator ID. Can be repeated.
|
|
22
|
+
|
|
23
|
+
Auth:
|
|
24
|
+
--cookie <value> Raw session ID or FANBOXSESSID=... cookie.
|
|
25
|
+
--cookie-file <path> Read raw cookie or Netscape cookies.txt.
|
|
26
|
+
--user-agent <value> Send the User-Agent from your logged-in browser.
|
|
27
|
+
FANBOX_SESSION_ID Environment fallback.
|
|
28
|
+
FANBOX_USER_AGENT User-Agent environment fallback.
|
|
29
|
+
|
|
30
|
+
Download:
|
|
31
|
+
--output <path> Output directory. Default: fanbox-downloads.
|
|
32
|
+
--dry-run List creators/posts without downloading or writing.
|
|
33
|
+
--flat-posts Store post files directly under each creator.
|
|
34
|
+
--verify-assets Verify existing asset size and SHA-256 locally.
|
|
35
|
+
|
|
36
|
+
Requests:
|
|
37
|
+
--concurrency <n> Concurrent requests. Default: 3.
|
|
38
|
+
--request-interval-ms <n> Delay between request starts. Default: 0.
|
|
39
|
+
--rate-limit-pause-ms <n> Pause after 429 without Retry-After. Default: 60000.
|
|
40
|
+
--max-retries <n> Retry attempts. Default: 5.
|
|
41
|
+
|
|
42
|
+
Output:
|
|
43
|
+
--log-format json|pretty Default: json.
|
|
44
|
+
--log-level <level> debug|info|warn|error. Default: info.
|
|
45
|
+
--help Show this help.
|
|
46
|
+
`;
|
|
47
|
+
export async function runCli(args, env = process.env, dependencies = {}) {
|
|
48
|
+
const write = dependencies.write ?? ((line) => process.stderr.write(`${line}\n`));
|
|
49
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
50
|
+
write(DOWNLOAD_HELP);
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
let logger;
|
|
54
|
+
let transportToClose;
|
|
55
|
+
try {
|
|
56
|
+
const options = parseDownloadOptions(args, env);
|
|
57
|
+
assertPathBudget(options.output);
|
|
58
|
+
logger = createLogger({
|
|
59
|
+
format: options.logFormat,
|
|
60
|
+
level: options.logLevel,
|
|
61
|
+
write: dependencies.write,
|
|
62
|
+
});
|
|
63
|
+
const transport = dependencies.transport ?? new Http2Transport();
|
|
64
|
+
transportToClose = dependencies.transport ? undefined : transport;
|
|
65
|
+
const requestHeaders = createFanboxRequestHeaders({
|
|
66
|
+
cookie: options.cookie,
|
|
67
|
+
userAgent: options.userAgent,
|
|
68
|
+
});
|
|
69
|
+
const scheduler = new RequestScheduler({
|
|
70
|
+
concurrency: options.concurrency,
|
|
71
|
+
logger,
|
|
72
|
+
maxRetries: options.maxRetries,
|
|
73
|
+
rateLimitPauseMs: options.rateLimitPauseMs,
|
|
74
|
+
requestIntervalMs: options.requestIntervalMs,
|
|
75
|
+
});
|
|
76
|
+
const client = new FanboxClient({
|
|
77
|
+
cookie: requestHeaders.Cookie,
|
|
78
|
+
transport: {
|
|
79
|
+
close: () => transport.close(),
|
|
80
|
+
request: (request) => scheduler.request(() => transport.request(request)),
|
|
81
|
+
},
|
|
82
|
+
userAgent: requestHeaders["User-Agent"],
|
|
83
|
+
});
|
|
84
|
+
const creatorIds = await resolveCreatorIds(client, options);
|
|
85
|
+
if (options.dryRun) {
|
|
86
|
+
for (const creatorId of creatorIds) {
|
|
87
|
+
logger.info("dry-run.creator", "Dry-run creator selected", {
|
|
88
|
+
creatorId,
|
|
89
|
+
});
|
|
90
|
+
for (const post of await discoverCreatorPosts(client, creatorId, {
|
|
91
|
+
logger,
|
|
92
|
+
})) {
|
|
93
|
+
logger.info("dry-run.post", "Dry-run post discovered", {
|
|
94
|
+
creatorId,
|
|
95
|
+
postId: post.id,
|
|
96
|
+
restricted: post.isRestricted,
|
|
97
|
+
title: post.title,
|
|
98
|
+
updatedDatetime: post.updatedDatetime,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
const assetDownloader = new AssetDownloader({
|
|
105
|
+
headers: requestHeaders,
|
|
106
|
+
scheduler,
|
|
107
|
+
transport,
|
|
108
|
+
});
|
|
109
|
+
let failed = false;
|
|
110
|
+
for (const creatorId of creatorIds) {
|
|
111
|
+
logger.info("creator.sync.start", "Creator sync started", { creatorId });
|
|
112
|
+
try {
|
|
113
|
+
const manifest = await syncCreator({
|
|
114
|
+
assetDownloader,
|
|
115
|
+
client,
|
|
116
|
+
creatorId,
|
|
117
|
+
flatPosts: options.flatPosts,
|
|
118
|
+
logger,
|
|
119
|
+
outputDirectory: options.output,
|
|
120
|
+
verifyAssets: options.verifyAssets,
|
|
121
|
+
});
|
|
122
|
+
failed || (failed = hasFailures(manifest));
|
|
123
|
+
logger.info("creator.sync.complete", "Creator sync completed", {
|
|
124
|
+
creatorId,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
failed = true;
|
|
129
|
+
logDebugErrorResponse(logger, error);
|
|
130
|
+
logger.error("creator.sync.failed", "Creator sync failed", {
|
|
131
|
+
creatorId,
|
|
132
|
+
error: String(error),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return failed ? 1 : 0;
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const usage = error instanceof CliUsageError;
|
|
140
|
+
const message = String(error);
|
|
141
|
+
if (usage) {
|
|
142
|
+
write(`${message}\n\n${DOWNLOAD_HELP}`);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
if (logger) {
|
|
146
|
+
logDebugErrorResponse(logger, error);
|
|
147
|
+
}
|
|
148
|
+
write(JSON.stringify({
|
|
149
|
+
event: "cli.failed",
|
|
150
|
+
level: "error",
|
|
151
|
+
msg: message,
|
|
152
|
+
time: new Date().toISOString(),
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
return usage ? 2 : 1;
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
await transportToClose?.close();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function hasFailures(manifest) {
|
|
162
|
+
return Object.values(manifest.posts).some((post) => post?.status === "failed");
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/downloader/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ListCreatorPostsParams, PaginateCreatorPostsParams, PostSummary } from "../types.js";
|
|
2
|
+
import type { Logger } from "./logger.js";
|
|
3
|
+
export interface CreatorPostClient {
|
|
4
|
+
listCreatorPosts(params: ListCreatorPostsParams): Promise<PostSummary[]>;
|
|
5
|
+
paginateCreatorPosts(params: PaginateCreatorPostsParams): Promise<string[]>;
|
|
6
|
+
}
|
|
7
|
+
export interface DiscoverCreatorPostsOptions {
|
|
8
|
+
logger?: Logger;
|
|
9
|
+
pageSize?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function discoverCreatorPosts(client: CreatorPostClient, creatorId: string, options?: DiscoverCreatorPostsOptions): Promise<PostSummary[]>;
|
|
12
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/downloader/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAK1C,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACzE,oBAAoB,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC7E;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,WAAW,EAAE,CAAC,CAqDxB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { logDebugErrorResponse } from "./errors.js";
|
|
2
|
+
import { silentLogger } from "./logger.js";
|
|
3
|
+
const DEFAULT_PAGE_SIZE = 300;
|
|
4
|
+
export async function discoverCreatorPosts(client, creatorId, options = {}) {
|
|
5
|
+
const logger = options.logger ?? silentLogger;
|
|
6
|
+
const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE;
|
|
7
|
+
const found = new Map();
|
|
8
|
+
let cursor = {
|
|
9
|
+
creatorId,
|
|
10
|
+
limit: pageSize,
|
|
11
|
+
sort: "newest",
|
|
12
|
+
};
|
|
13
|
+
for (;;) {
|
|
14
|
+
let page;
|
|
15
|
+
try {
|
|
16
|
+
page = await client.listCreatorPosts(cursor);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
logDebugErrorResponse(logger, error, { creatorId });
|
|
20
|
+
logger.warn("post.discovery.fallback", "Direct cursor failed; using paginateCreator", {
|
|
21
|
+
creatorId,
|
|
22
|
+
error: String(error),
|
|
23
|
+
});
|
|
24
|
+
await fallbackPaginate(client, creatorId, found);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
const added = addPosts(page, found);
|
|
28
|
+
if (page.length < pageSize) {
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
if (added === 0) {
|
|
32
|
+
logger.warn("post.discovery.fallback", "Direct cursor made no progress; using paginateCreator", {
|
|
33
|
+
creatorId,
|
|
34
|
+
});
|
|
35
|
+
await fallbackPaginate(client, creatorId, found);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
const last = page.at(-1);
|
|
39
|
+
cursor = {
|
|
40
|
+
creatorId,
|
|
41
|
+
firstId: last.id,
|
|
42
|
+
firstPublishedDatetime: last.publishedDatetime,
|
|
43
|
+
limit: pageSize,
|
|
44
|
+
sort: "newest",
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return [...found.values()];
|
|
48
|
+
}
|
|
49
|
+
function addPosts(posts, found) {
|
|
50
|
+
let added = 0;
|
|
51
|
+
for (const post of posts) {
|
|
52
|
+
if (!found.has(post.id)) {
|
|
53
|
+
added += 1;
|
|
54
|
+
found.set(post.id, post);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return added;
|
|
58
|
+
}
|
|
59
|
+
function cursorFromUrl(url) {
|
|
60
|
+
const parsed = new URL(url);
|
|
61
|
+
const creatorId = parsed.searchParams.get("creatorId");
|
|
62
|
+
if (!creatorId) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
creatorId,
|
|
67
|
+
firstId: parsed.searchParams.get("firstId") ?? undefined,
|
|
68
|
+
firstPublishedDatetime: parsed.searchParams.get("firstPublishedDatetime") ?? undefined,
|
|
69
|
+
limit: Number(parsed.searchParams.get("limit") ?? DEFAULT_PAGE_SIZE),
|
|
70
|
+
sort: "newest",
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async function fallbackPaginate(client, creatorId, found) {
|
|
74
|
+
for (const url of await client.paginateCreatorPosts({
|
|
75
|
+
creatorId,
|
|
76
|
+
sort: "newest",
|
|
77
|
+
})) {
|
|
78
|
+
const cursor = cursorFromUrl(url);
|
|
79
|
+
if (cursor) {
|
|
80
|
+
addPosts(await client.listCreatorPosts(cursor), found);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/downloader/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { HttpResponse } from "../http.js";
|
|
2
|
+
import type { LogFields, Logger } from "./logger.js";
|
|
3
|
+
export declare function logDebugErrorResponse(logger: Logger, error: unknown, fields?: LogFields): void;
|
|
4
|
+
export declare function logDebugResponse(logger: Logger, response: HttpResponse, fields?: LogFields): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/downloader/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,MAAM,GAAE,SAAc,GACrB,IAAI,CAWN;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,YAAY,EACtB,MAAM,GAAE,SAAc,GACrB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function logDebugErrorResponse(logger, error, fields = {}) {
|
|
2
|
+
if (!isResponseLikeError(error)) {
|
|
3
|
+
return;
|
|
4
|
+
}
|
|
5
|
+
logger.debug("api.response.error", "HTTP error response", {
|
|
6
|
+
...fields,
|
|
7
|
+
body: error.body,
|
|
8
|
+
status: error.status,
|
|
9
|
+
statusText: error.statusText,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export async function logDebugResponse(logger, response, fields = {}) {
|
|
13
|
+
logger.debug("api.response.error", "HTTP error response", {
|
|
14
|
+
...fields,
|
|
15
|
+
body: await readResponseBody(response),
|
|
16
|
+
status: response.status,
|
|
17
|
+
statusText: response.statusText,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function isResponseLikeError(error) {
|
|
21
|
+
return (typeof error === "object" &&
|
|
22
|
+
error !== null &&
|
|
23
|
+
"body" in error &&
|
|
24
|
+
"status" in error &&
|
|
25
|
+
typeof error.status === "number");
|
|
26
|
+
}
|
|
27
|
+
async function readResponseBody(response) {
|
|
28
|
+
const text = await response.text();
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(text);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return text;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/downloader/errors.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,qBAAqB,CACnC,MAAc,EACd,KAAc,EACd,SAAoB,EAAE;IAEtB,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO;IACT,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,qBAAqB,EAAE;QACxD,GAAG,MAAM;QACT,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,QAAsB,EACtB,SAAoB,EAAE;IAEtB,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,qBAAqB,EAAE;QACxD,GAAG,MAAM;QACT,IAAI,EAAE,MAAM,gBAAgB,CAAC,QAAQ,CAAC;QACtC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;KAChC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IACzC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,QAAQ,IAAI,KAAK;QACjB,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CACjC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAsB;IACpD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/downloader/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/downloader/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,KAAK,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;IACnD,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;AAC9B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface CreateLoggerOptions {
|
|
2
|
+
format?: "json" | "pretty";
|
|
3
|
+
level?: LogLevel;
|
|
4
|
+
write?: (line: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export type LogFields = Record<string, unknown>;
|
|
7
|
+
export interface Logger {
|
|
8
|
+
debug(event: string, message: string, fields?: LogFields): void;
|
|
9
|
+
error(event: string, message: string, fields?: LogFields): void;
|
|
10
|
+
info(event: string, message: string, fields?: LogFields): void;
|
|
11
|
+
warn(event: string, message: string, fields?: LogFields): void;
|
|
12
|
+
}
|
|
13
|
+
export type LogLevel = "debug" | "error" | "info" | "warn";
|
|
14
|
+
export declare function createLogger(options?: CreateLoggerOptions): Logger;
|
|
15
|
+
export declare const silentLogger: Logger;
|
|
16
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/downloader/logger.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAChE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CAChE;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAS3D,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,CA0CtE;AAED,eAAO,MAAM,YAAY,EAAE,MAK1B,CAAC"}
|