patreon-dl 3.3.0 → 3.3.1
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 +6 -0
- package/dist/browse/api/index.d.ts +0 -1
- package/dist/browse/api/index.js +1 -5
- package/dist/browse/api/index.js.map +1 -1
- package/dist/browse/db/CampaignDBMixin.d.ts +1 -0
- package/dist/browse/db/ContentDBMixin.d.ts +1 -0
- package/dist/browse/db/EnvDBMixin.d.ts +1 -0
- package/dist/browse/db/MediaDBMixin.d.ts +1 -0
- package/dist/browse/db/UserDBMixin.d.ts +1 -0
- package/dist/browse/db/index.d.ts +15 -236
- package/dist/browse/db/index.js +44 -7
- package/dist/browse/db/index.js.map +1 -1
- package/dist/browse/server/WebServer.js +15 -4
- package/dist/browse/server/WebServer.js.map +1 -1
- package/dist/downloaders/Downloader.d.ts +1 -0
- package/dist/downloaders/Downloader.js +6 -0
- package/dist/downloaders/Downloader.js.map +1 -1
- package/dist/downloaders/PostDownloader.js +1 -0
- package/dist/downloaders/PostDownloader.js.map +1 -1
- package/dist/downloaders/ProductDownloader.js +1 -0
- package/dist/downloaders/ProductDownloader.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -267,6 +267,12 @@ Note the URL shown in the output. Open this URL in a web browser to begin viewin
|
|
|
267
267
|
|
|
268
268
|
## Changelog
|
|
269
269
|
|
|
270
|
+
v3.3.1
|
|
271
|
+
- Fix bugs affecting library usage:
|
|
272
|
+
- `DB.getInstance()` returning same instance despite different DB path
|
|
273
|
+
- `API.getInstance()` returning same instance despite different DB instance
|
|
274
|
+
- DB not closed when downloader ends or web server stops
|
|
275
|
+
|
|
270
276
|
v3.3.0
|
|
271
277
|
- Fix:
|
|
272
278
|
- YouTube stream fetching error ([patreon-dl-gui#28](https://github.com/patrickkfkan/patreon-dl-gui/issues/28))
|
|
@@ -5,7 +5,6 @@ export type APIConstructor = new (...args: any[]) => APIBase;
|
|
|
5
5
|
export type APIInstance = InstanceType<typeof API>;
|
|
6
6
|
export declare class APIBase {
|
|
7
7
|
name: string;
|
|
8
|
-
protected static instance: APIInstance | null;
|
|
9
8
|
db: DBInstance;
|
|
10
9
|
logger?: Logger | null;
|
|
11
10
|
constructor(db: DBInstance, logger?: Logger | null);
|
package/dist/browse/api/index.js
CHANGED
|
@@ -19,10 +19,7 @@ export class APIBase {
|
|
|
19
19
|
this.logger = logger;
|
|
20
20
|
}
|
|
21
21
|
static getInstance(db, logger) {
|
|
22
|
-
|
|
23
|
-
this.instance = new API(db, logger);
|
|
24
|
-
}
|
|
25
|
-
return this.instance;
|
|
22
|
+
return new API(db, logger);
|
|
26
23
|
}
|
|
27
24
|
sanitizeHTML(html) {
|
|
28
25
|
return _sanitizeHTML(html, SANITIZE_HTML_OPTIONS);
|
|
@@ -35,7 +32,6 @@ export class APIBase {
|
|
|
35
32
|
commonLog(this.logger, level, this.name, ...msg);
|
|
36
33
|
}
|
|
37
34
|
}
|
|
38
|
-
APIBase.instance = null;
|
|
39
35
|
const API = FilterAPIMixin(MediaAPIMixin(SettingsAPIMixin(ContentAPIMixin(CampaignAPIMixin(APIBase)))));
|
|
40
36
|
export default API;
|
|
41
37
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/browse/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAiB,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD,MAAM,qBAAqB,GAAG;IAC5B,WAAW,EAAE,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;IAC/D,iBAAiB,EAAE;QACjB,GAAG,aAAa,CAAC,QAAQ,CAAC,iBAAiB;QAC3C,GAAG,EAAE,CAAC,OAAO,CAAC;KACf;CACF,CAAC;AAEF,MAAM,OAAO,OAAO;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/browse/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAiB,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD,MAAM,qBAAqB,GAAG;IAC5B,WAAW,EAAE,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;IAC/D,iBAAiB,EAAE;QACjB,GAAG,aAAa,CAAC,QAAQ,CAAC,iBAAiB;QAC3C,GAAG,EAAE,CAAC,OAAO,CAAC;KACf;CACF,CAAC;AAEF,MAAM,OAAO,OAAO;IAMlB,YAAY,EAAc,EAAE,MAAsB;QALlD,SAAI,GAAG,KAAK,CAAC;QAMX,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,EAAc,EAAE,MAAsB;QACvD,OAAO,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY,CAAC,IAAY;QACvB,OAAO,aAAa,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IACpD,CAAC;IAED,GAAG,CAAC,KAAe,EAAE,GAAG,GAAU;QAChC,MAAM,kBAAkB,GAAG,GAAG,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,oBAAoB,CAChE,CAAC;QACF,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC;IACnD,CAAC;CACF;AAED,MAAM,GAAG,GAAG,cAAc,CAAC,aAAa,CAAC,gBAAgB,CAAC,eAAe,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAExG,eAAe,GAAG,CAAC","sourcesContent":["import _sanitizeHTML from 'sanitize-html';\nimport type Logger from '../../utils/logging/Logger.js';\nimport { commonLog, type LogLevel } from '../../utils/logging/Logger.js';\nimport { CampaignAPIMixin } from './CampaignAPIMixin.js';\nimport { type DBInstance } from '../db';\nimport { ContentAPIMixin } from './ContentAPIMixin.js';\nimport { SettingsAPIMixin } from './SettingsAPIMixin.js';\nimport { MediaAPIMixin } from './MediaAPIMixin.js';\nimport { FilterAPIMixin } from './FilterAPIMixin.js';\n\nexport type APIConstructor = new (...args: any[]) => APIBase;\nexport type APIInstance = InstanceType<typeof API>;\n\nconst SANITIZE_HTML_OPTIONS = {\n allowedTags: _sanitizeHTML.defaults.allowedTags.concat(['img']),\n allowedAttributes: {\n ..._sanitizeHTML.defaults.allowedAttributes,\n '*': ['class']\n }\n};\n\nexport class APIBase {\n name = 'API';\n\n db: DBInstance;\n logger?: Logger | null;\n\n constructor(db: DBInstance, logger?: Logger | null) {\n this.db = db;\n this.logger = logger;\n }\n\n static getInstance(db: DBInstance, logger?: Logger | null) {\n return new API(db, logger);\n }\n\n sanitizeHTML(html: string) {\n return _sanitizeHTML(html, SANITIZE_HTML_OPTIONS);\n }\n\n log(level: LogLevel, ...msg: any[]) {\n const limiterStopOnError = msg.find(\n (m) => m instanceof Error && m.message === 'LimiterStopOnError'\n );\n if (limiterStopOnError) {\n return;\n }\n commonLog(this.logger, level, this.name, ...msg);\n }\n}\n\nconst API = FilterAPIMixin(MediaAPIMixin(SettingsAPIMixin(ContentAPIMixin(CampaignAPIMixin(APIBase)))));\n\nexport default API;\n"]}
|
|
@@ -45,6 +45,7 @@ export declare function CampaignDBMixin<TBase extends UserDBConstructor>(Base: T
|
|
|
45
45
|
limitOffset?: string;
|
|
46
46
|
}): string;
|
|
47
47
|
name: string;
|
|
48
|
+
dbPath: string | null;
|
|
48
49
|
db: import("better-sqlite3").Database;
|
|
49
50
|
logger?: import("../../index.js").Logger | null;
|
|
50
51
|
exec(sql: string): void;
|
|
@@ -84,6 +84,7 @@ export declare function ContentDBMixin<TBase extends CampaignDBConstructor>(Base
|
|
|
84
84
|
limitOffset?: string;
|
|
85
85
|
}): string;
|
|
86
86
|
name: string;
|
|
87
|
+
dbPath: string | null;
|
|
87
88
|
db: import("better-sqlite3").Database;
|
|
88
89
|
logger?: import("../..").Logger | null;
|
|
89
90
|
exec(sql: string): void;
|
|
@@ -6,6 +6,7 @@ export declare function EnvDBMixin<TBase extends DBConstructor>(Base: TBase): {
|
|
|
6
6
|
getEnvValue<T = any>(key: string): T | null;
|
|
7
7
|
checkEnvExists(key: string): boolean;
|
|
8
8
|
name: string;
|
|
9
|
+
dbPath: string | null;
|
|
9
10
|
db: import("better-sqlite3").Database;
|
|
10
11
|
logger?: import("../..").Logger | null;
|
|
11
12
|
exec(sql: string): void;
|
|
@@ -35,6 +35,7 @@ export declare function MediaDBMixin<TBase extends DBConstructor>(Base: TBase):
|
|
|
35
35
|
limitOffset?: string;
|
|
36
36
|
}): string;
|
|
37
37
|
name: string;
|
|
38
|
+
dbPath: string | null;
|
|
38
39
|
db: import("better-sqlite3").Database;
|
|
39
40
|
logger?: import("../..").Logger | null;
|
|
40
41
|
exec(sql: string): void;
|
|
@@ -36,6 +36,7 @@ export declare function UserDBMixin<TBase extends MediaDBConstructor>(Base: TBas
|
|
|
36
36
|
limitOffset?: string;
|
|
37
37
|
}): string;
|
|
38
38
|
name: string;
|
|
39
|
+
dbPath: string | null;
|
|
39
40
|
db: import("better-sqlite3").Database;
|
|
40
41
|
logger?: import("../..").Logger | null;
|
|
41
42
|
exec(sql: string): void;
|
|
@@ -3,246 +3,20 @@ import type Logger from '../../utils/logging/Logger.js';
|
|
|
3
3
|
import { type LogLevel } from '../../utils/logging/Logger.js';
|
|
4
4
|
export type DBConstructor = new (...args: any[]) => DBBase;
|
|
5
5
|
export type DBInstance = InstanceType<typeof DB>;
|
|
6
|
+
interface DBPool {
|
|
7
|
+
[dbPath: string]: {
|
|
8
|
+
db: Database.Database;
|
|
9
|
+
count: number;
|
|
10
|
+
} | undefined;
|
|
11
|
+
}
|
|
6
12
|
export declare class DBBase {
|
|
7
13
|
name: string;
|
|
8
|
-
|
|
14
|
+
dbPath: string | null;
|
|
15
|
+
static dbPool: DBPool;
|
|
9
16
|
db: Database.Database;
|
|
10
17
|
logger?: Logger | null;
|
|
11
|
-
constructor(db: Database.Database, logger?: Logger | null);
|
|
12
|
-
static getInstance(file: string, dryRun?: boolean, logger?: Logger | null): Promise<
|
|
13
|
-
saveEnvValue(key: string, value: any): void;
|
|
14
|
-
getEnvValue<T = any>(key: string): T | null;
|
|
15
|
-
checkEnvExists(key: string): boolean;
|
|
16
|
-
name: string;
|
|
17
|
-
db: Database.Database;
|
|
18
|
-
logger?: Logger | null;
|
|
19
|
-
exec(sql: string): void;
|
|
20
|
-
run(sql: string, params?: any[]): Database.RunResult;
|
|
21
|
-
get<T = any>(sql: string, params?: any[]): T | undefined;
|
|
22
|
-
all<T = any>(sql: string, params?: any[]): T[];
|
|
23
|
-
close(): void;
|
|
24
|
-
transaction(fn: (...args: any[]) => any): (...args: any[]) => any;
|
|
25
|
-
log(level: LogLevel, ...msg: any[]): void;
|
|
26
|
-
} & {
|
|
27
|
-
saveContent(content: import("../../index.js").Post | import("../../index.js").Product): void;
|
|
28
|
-
"__#120@#saveContentMedia"(content: import("../../index.js").Post | import("../../index.js").Product): void;
|
|
29
|
-
"__#120@#savepostMedia"(post: import("../../index.js").Post): void;
|
|
30
|
-
"__#120@#saveProductMedia"(product: import("../../index.js").Product): void;
|
|
31
|
-
"__#120@#doSaveContentMedia"(content: import("../../index.js").Post | import("../../index.js").Product, media: import("../../index.js").Downloadable, mediaIndex: number, isPreview: boolean): void;
|
|
32
|
-
"__#120@#publishedAtToTime"(publishedAt: string | null): number | null;
|
|
33
|
-
"__#120@#savePostTiers"(post: import("../../index.js").Post): void;
|
|
34
|
-
"__#120@#doSaveTier"(post: import("../../index.js").Post, tier: import("../../index.js").Tier): void;
|
|
35
|
-
savePostComments(post: import("../../index.js").Post, comments: import("../../index.js").Comment[]): void;
|
|
36
|
-
checkPostCommentsExist(post: import("../../index.js").Post): boolean;
|
|
37
|
-
getContent(id: string, contentType: "post"): import("../types/Content.js").PostWithComments | null;
|
|
38
|
-
getContent(id: string, contentType: "product"): import("../../index.js").Product | null;
|
|
39
|
-
getPreviousNextContent<T extends import("../types/Content.js").ContentType>(content: import("../../index.js").Post | import("../../index.js").Product, context: import("../types/Content.js").GetContentContext<T>): import("../types/Content.js").GetPreviousNextContentResult<T>;
|
|
40
|
-
getContentList<T extends import("../types/Content.js").ContentType>(params: import("../types/Content.js").GetContentListParams<T>, db?: {
|
|
41
|
-
whereClauses: string[];
|
|
42
|
-
whereValues: any[];
|
|
43
|
-
} | undefined, includeTotal?: boolean): import("../types/Content.js").ContentList<T>;
|
|
44
|
-
"__#120@#parseContentRowJoinedComments"(row: any): any;
|
|
45
|
-
getContentCountByDate(contentType: import("../types/Content.js").ContentType, groupBy: "year" | "month", filter?: {
|
|
46
|
-
campaign?: import("../../index.js").Campaign | string | null;
|
|
47
|
-
date?: Date | null;
|
|
48
|
-
} | undefined): {
|
|
49
|
-
dt: string;
|
|
50
|
-
count: number;
|
|
51
|
-
}[];
|
|
52
|
-
getPostCountByType(campaign: import("../../index.js").Campaign | string): {
|
|
53
|
-
postType: string;
|
|
54
|
-
count: number;
|
|
55
|
-
}[];
|
|
56
|
-
getPostCountByTier(campaign: import("../../index.js").Campaign | string): {
|
|
57
|
-
tierId: string;
|
|
58
|
-
title: string;
|
|
59
|
-
count: number;
|
|
60
|
-
}[];
|
|
61
|
-
checkContentExists(id: string, contentType: import("../types/Content.js").ContentType, campaign: import("../../index.js").Campaign | null): boolean;
|
|
62
|
-
getPostComments(post: import("../../index.js").Post | string): import("../../index.js").Comment[] | null;
|
|
63
|
-
saveCampaign(campaign: import("../../index.js").Campaign | null, downloadDate: Date, overwriteIfExists?: boolean): void;
|
|
64
|
-
getCampaign(params: import("../types/Campaign.js").GetCampaignParams): import("../../index.js").Campaign | null;
|
|
65
|
-
"__#119@#saveRewards"(campaign: import("../../index.js").Campaign): void;
|
|
66
|
-
"__#119@#doSaveReward"(campaign: import("../../index.js").Campaign, reward: import("../../index.js").Reward): void;
|
|
67
|
-
getCampaignList(params: import("../types/Campaign.js").GetCampaignListParams): import("../types/Campaign.js").CampaignList;
|
|
68
|
-
"__#119@#getCampaignWithCounts"(params: import("../types/Campaign.js").GetCampaignParams): import("../types/Campaign.js").CampaignWithCounts | null;
|
|
69
|
-
checkCampaignExists(id: string): boolean;
|
|
70
|
-
saveUser(user: import("../../index.js").User | null): void;
|
|
71
|
-
getUserByID(id: string): import("../../index.js").User | null;
|
|
72
|
-
checkUserExists(id: string): boolean;
|
|
73
|
-
saveMedia(media: import("../../index.js").Downloadable): void;
|
|
74
|
-
checkMediaExists(media: import("../../index.js").Downloadable): boolean;
|
|
75
|
-
checkContentMediaExists(content: import("../../index.js").Post | import("../../index.js").Product, media: import("../../index.js").Downloadable): boolean;
|
|
76
|
-
getMediaByID(id: string): import("../../index.js").Downloaded | null;
|
|
77
|
-
getMediaList<T extends import("../types/Content.js").ContentType>(params: import("../types/Media.js").GetMediaListParams<T>): import("../types/Media.js").MediaList<T>;
|
|
78
|
-
getMediaCountByDate(groupBy: "year" | "month", filter?: {
|
|
79
|
-
campaign?: import("../../index.js").Campaign | string | null;
|
|
80
|
-
date?: Date | null;
|
|
81
|
-
} | undefined): {
|
|
82
|
-
dt: string;
|
|
83
|
-
count: number;
|
|
84
|
-
}[];
|
|
85
|
-
getMediaCountByContentType(campaign?: import("../../index.js").Campaign | string | null): {
|
|
86
|
-
contentType: "post" | "product";
|
|
87
|
-
count: number;
|
|
88
|
-
}[];
|
|
89
|
-
getMediaCountByTier(campaign: import("../../index.js").Campaign | string): {
|
|
90
|
-
tierId: string;
|
|
91
|
-
title: string;
|
|
92
|
-
count: number;
|
|
93
|
-
}[];
|
|
94
|
-
getMediaListSQL(params: {
|
|
95
|
-
select: string;
|
|
96
|
-
join?: string;
|
|
97
|
-
where?: string;
|
|
98
|
-
groupBy?: string;
|
|
99
|
-
orderBy?: string;
|
|
100
|
-
limitOffset?: string;
|
|
101
|
-
}): string;
|
|
102
|
-
name: string;
|
|
103
|
-
db: Database.Database;
|
|
104
|
-
logger?: Logger | null;
|
|
105
|
-
exec(sql: string): void;
|
|
106
|
-
run(sql: string, params?: any[]): Database.RunResult;
|
|
107
|
-
get<T = any>(sql: string, params?: any[]): T | undefined;
|
|
108
|
-
all<T = any>(sql: string, params?: any[]): T[];
|
|
109
|
-
close(): void;
|
|
110
|
-
transaction(fn: (...args: any[]) => any): (...args: any[]) => any;
|
|
111
|
-
log(level: LogLevel, ...msg: any[]): void;
|
|
112
|
-
} & {
|
|
113
|
-
saveCampaign(campaign: import("../../index.js").Campaign | null, downloadDate: Date, overwriteIfExists?: boolean): void;
|
|
114
|
-
getCampaign(params: import("../types/Campaign.js").GetCampaignParams): import("../../index.js").Campaign | null;
|
|
115
|
-
"__#119@#saveRewards"(campaign: import("../../index.js").Campaign): void;
|
|
116
|
-
"__#119@#doSaveReward"(campaign: import("../../index.js").Campaign, reward: import("../../index.js").Reward): void;
|
|
117
|
-
getCampaignList(params: import("../types/Campaign.js").GetCampaignListParams): import("../types/Campaign.js").CampaignList;
|
|
118
|
-
"__#119@#getCampaignWithCounts"(params: import("../types/Campaign.js").GetCampaignParams): import("../types/Campaign.js").CampaignWithCounts | null;
|
|
119
|
-
checkCampaignExists(id: string): boolean;
|
|
120
|
-
saveUser(user: import("../../index.js").User | null): void;
|
|
121
|
-
getUserByID(id: string): import("../../index.js").User | null;
|
|
122
|
-
checkUserExists(id: string): boolean;
|
|
123
|
-
saveMedia(media: import("../../index.js").Downloadable): void;
|
|
124
|
-
checkMediaExists(media: import("../../index.js").Downloadable): boolean;
|
|
125
|
-
checkContentMediaExists(content: import("../../index.js").Post | import("../../index.js").Product, media: import("../../index.js").Downloadable): boolean;
|
|
126
|
-
getMediaByID(id: string): import("../../index.js").Downloaded | null;
|
|
127
|
-
getMediaList<T extends import("../types/Content.js").ContentType>(params: import("../types/Media.js").GetMediaListParams<T>): import("../types/Media.js").MediaList<T>;
|
|
128
|
-
getMediaCountByDate(groupBy: "year" | "month", filter?: {
|
|
129
|
-
campaign?: import("../../index.js").Campaign | string | null;
|
|
130
|
-
date?: Date | null;
|
|
131
|
-
} | undefined): {
|
|
132
|
-
dt: string;
|
|
133
|
-
count: number;
|
|
134
|
-
}[];
|
|
135
|
-
getMediaCountByContentType(campaign?: import("../../index.js").Campaign | string | null): {
|
|
136
|
-
contentType: "post" | "product";
|
|
137
|
-
count: number;
|
|
138
|
-
}[];
|
|
139
|
-
getMediaCountByTier(campaign: import("../../index.js").Campaign | string): {
|
|
140
|
-
tierId: string;
|
|
141
|
-
title: string;
|
|
142
|
-
count: number;
|
|
143
|
-
}[];
|
|
144
|
-
getMediaListSQL(params: {
|
|
145
|
-
select: string;
|
|
146
|
-
join?: string;
|
|
147
|
-
where?: string;
|
|
148
|
-
groupBy?: string;
|
|
149
|
-
orderBy?: string;
|
|
150
|
-
limitOffset?: string;
|
|
151
|
-
}): string;
|
|
152
|
-
name: string;
|
|
153
|
-
db: Database.Database;
|
|
154
|
-
logger?: Logger | null;
|
|
155
|
-
exec(sql: string): void;
|
|
156
|
-
run(sql: string, params?: any[]): Database.RunResult;
|
|
157
|
-
get<T = any>(sql: string, params?: any[]): T | undefined;
|
|
158
|
-
all<T = any>(sql: string, params?: any[]): T[];
|
|
159
|
-
close(): void;
|
|
160
|
-
transaction(fn: (...args: any[]) => any): (...args: any[]) => any;
|
|
161
|
-
log(level: LogLevel, ...msg: any[]): void;
|
|
162
|
-
} & {
|
|
163
|
-
saveUser(user: import("../../index.js").User | null): void;
|
|
164
|
-
getUserByID(id: string): import("../../index.js").User | null;
|
|
165
|
-
checkUserExists(id: string): boolean;
|
|
166
|
-
saveMedia(media: import("../../index.js").Downloadable): void;
|
|
167
|
-
checkMediaExists(media: import("../../index.js").Downloadable): boolean;
|
|
168
|
-
checkContentMediaExists(content: import("../../index.js").Post | import("../../index.js").Product, media: import("../../index.js").Downloadable): boolean;
|
|
169
|
-
getMediaByID(id: string): import("../../index.js").Downloaded | null;
|
|
170
|
-
getMediaList<T extends import("../types/Content.js").ContentType>(params: import("../types/Media.js").GetMediaListParams<T>): import("../types/Media.js").MediaList<T>;
|
|
171
|
-
getMediaCountByDate(groupBy: "year" | "month", filter?: {
|
|
172
|
-
campaign?: import("../../index.js").Campaign | string | null;
|
|
173
|
-
date?: Date | null;
|
|
174
|
-
} | undefined): {
|
|
175
|
-
dt: string;
|
|
176
|
-
count: number;
|
|
177
|
-
}[];
|
|
178
|
-
getMediaCountByContentType(campaign?: import("../../index.js").Campaign | string | null): {
|
|
179
|
-
contentType: "post" | "product";
|
|
180
|
-
count: number;
|
|
181
|
-
}[];
|
|
182
|
-
getMediaCountByTier(campaign: import("../../index.js").Campaign | string): {
|
|
183
|
-
tierId: string;
|
|
184
|
-
title: string;
|
|
185
|
-
count: number;
|
|
186
|
-
}[];
|
|
187
|
-
getMediaListSQL(params: {
|
|
188
|
-
select: string;
|
|
189
|
-
join?: string;
|
|
190
|
-
where?: string;
|
|
191
|
-
groupBy?: string;
|
|
192
|
-
orderBy?: string;
|
|
193
|
-
limitOffset?: string;
|
|
194
|
-
}): string;
|
|
195
|
-
name: string;
|
|
196
|
-
db: Database.Database;
|
|
197
|
-
logger?: Logger | null;
|
|
198
|
-
exec(sql: string): void;
|
|
199
|
-
run(sql: string, params?: any[]): Database.RunResult;
|
|
200
|
-
get<T = any>(sql: string, params?: any[]): T | undefined;
|
|
201
|
-
all<T = any>(sql: string, params?: any[]): T[];
|
|
202
|
-
close(): void;
|
|
203
|
-
transaction(fn: (...args: any[]) => any): (...args: any[]) => any;
|
|
204
|
-
log(level: LogLevel, ...msg: any[]): void;
|
|
205
|
-
} & {
|
|
206
|
-
saveMedia(media: import("../../index.js").Downloadable): void;
|
|
207
|
-
checkMediaExists(media: import("../../index.js").Downloadable): boolean;
|
|
208
|
-
checkContentMediaExists(content: import("../../index.js").Post | import("../../index.js").Product, media: import("../../index.js").Downloadable): boolean;
|
|
209
|
-
getMediaByID(id: string): import("../../index.js").Downloaded | null;
|
|
210
|
-
getMediaList<T extends import("../types/Content.js").ContentType>(params: import("../types/Media.js").GetMediaListParams<T>): import("../types/Media.js").MediaList<T>;
|
|
211
|
-
getMediaCountByDate(groupBy: "year" | "month", filter?: {
|
|
212
|
-
campaign?: import("../../index.js").Campaign | string | null;
|
|
213
|
-
date?: Date | null;
|
|
214
|
-
} | undefined): {
|
|
215
|
-
dt: string;
|
|
216
|
-
count: number;
|
|
217
|
-
}[];
|
|
218
|
-
getMediaCountByContentType(campaign?: import("../../index.js").Campaign | string | null): {
|
|
219
|
-
contentType: "post" | "product";
|
|
220
|
-
count: number;
|
|
221
|
-
}[];
|
|
222
|
-
getMediaCountByTier(campaign: import("../../index.js").Campaign | string): {
|
|
223
|
-
tierId: string;
|
|
224
|
-
title: string;
|
|
225
|
-
count: number;
|
|
226
|
-
}[];
|
|
227
|
-
getMediaListSQL(params: {
|
|
228
|
-
select: string;
|
|
229
|
-
join?: string;
|
|
230
|
-
where?: string;
|
|
231
|
-
groupBy?: string;
|
|
232
|
-
orderBy?: string;
|
|
233
|
-
limitOffset?: string;
|
|
234
|
-
}): string;
|
|
235
|
-
name: string;
|
|
236
|
-
db: Database.Database;
|
|
237
|
-
logger?: Logger | null;
|
|
238
|
-
exec(sql: string): void;
|
|
239
|
-
run(sql: string, params?: any[]): Database.RunResult;
|
|
240
|
-
get<T = any>(sql: string, params?: any[]): T | undefined;
|
|
241
|
-
all<T = any>(sql: string, params?: any[]): T[];
|
|
242
|
-
close(): void;
|
|
243
|
-
transaction(fn: (...args: any[]) => any): (...args: any[]) => any;
|
|
244
|
-
log(level: LogLevel, ...msg: any[]): void;
|
|
245
|
-
} & DBBase>;
|
|
18
|
+
constructor(dbPath: string | null, db: Database.Database, logger?: Logger | null);
|
|
19
|
+
static getInstance(file: string, dryRun?: boolean, logger?: Logger | null): Promise<DBInstance>;
|
|
246
20
|
exec(sql: string): void;
|
|
247
21
|
run(sql: string, params?: any[]): Database.RunResult;
|
|
248
22
|
get<T = any>(sql: string, params?: any[]): T | undefined;
|
|
@@ -257,6 +31,7 @@ declare const DB: {
|
|
|
257
31
|
getEnvValue<T = any>(key: string): T | null;
|
|
258
32
|
checkEnvExists(key: string): boolean;
|
|
259
33
|
name: string;
|
|
34
|
+
dbPath: string | null;
|
|
260
35
|
db: Database.Database;
|
|
261
36
|
logger?: Logger | null;
|
|
262
37
|
exec(sql: string): void;
|
|
@@ -345,6 +120,7 @@ declare const DB: {
|
|
|
345
120
|
limitOffset?: string;
|
|
346
121
|
}): string;
|
|
347
122
|
name: string;
|
|
123
|
+
dbPath: string | null;
|
|
348
124
|
db: Database.Database;
|
|
349
125
|
logger?: Logger | null;
|
|
350
126
|
exec(sql: string): void;
|
|
@@ -397,6 +173,7 @@ declare const DB: {
|
|
|
397
173
|
limitOffset?: string;
|
|
398
174
|
}): string;
|
|
399
175
|
name: string;
|
|
176
|
+
dbPath: string | null;
|
|
400
177
|
db: Database.Database;
|
|
401
178
|
logger?: Logger | null;
|
|
402
179
|
exec(sql: string): void;
|
|
@@ -442,6 +219,7 @@ declare const DB: {
|
|
|
442
219
|
limitOffset?: string;
|
|
443
220
|
}): string;
|
|
444
221
|
name: string;
|
|
222
|
+
dbPath: string | null;
|
|
445
223
|
db: Database.Database;
|
|
446
224
|
logger?: Logger | null;
|
|
447
225
|
exec(sql: string): void;
|
|
@@ -484,6 +262,7 @@ declare const DB: {
|
|
|
484
262
|
limitOffset?: string;
|
|
485
263
|
}): string;
|
|
486
264
|
name: string;
|
|
265
|
+
dbPath: string | null;
|
|
487
266
|
db: Database.Database;
|
|
488
267
|
logger?: Logger | null;
|
|
489
268
|
exec(sql: string): void;
|
package/dist/browse/db/index.js
CHANGED
|
@@ -5,18 +5,39 @@ import { UserDBMixin } from './UserDBMixin.js';
|
|
|
5
5
|
import { CampaignDBMixin } from './CampaignDBMixin.js';
|
|
6
6
|
import { ContentDBMixin } from './ContentDBMixin.js';
|
|
7
7
|
import { EnvDBMixin } from './EnvDBMixin.js';
|
|
8
|
+
import path from 'path';
|
|
8
9
|
export class DBBase {
|
|
9
|
-
constructor(db, logger) {
|
|
10
|
+
constructor(dbPath, db, logger) {
|
|
10
11
|
this.name = 'DB';
|
|
12
|
+
this.dbPath = dbPath;
|
|
11
13
|
this.db = db;
|
|
12
14
|
this.logger = logger;
|
|
13
15
|
}
|
|
14
16
|
static async getInstance(file, dryRun = false, logger) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
let db;
|
|
18
|
+
let dbPath;
|
|
19
|
+
if (dryRun) {
|
|
20
|
+
dbPath = null;
|
|
21
|
+
db = await openDB(file, dryRun, logger);
|
|
18
22
|
}
|
|
19
|
-
|
|
23
|
+
else {
|
|
24
|
+
dbPath = path.resolve(file);
|
|
25
|
+
const poolEntry = this.dbPool[dbPath];
|
|
26
|
+
if (poolEntry) {
|
|
27
|
+
db = poolEntry.db;
|
|
28
|
+
poolEntry.count++;
|
|
29
|
+
commonLog(logger, 'debug', 'DB', `Obtained DB from pool (shares: ${poolEntry.count})`);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
db = await openDB(file, dryRun, logger);
|
|
33
|
+
this.dbPool[dbPath] = {
|
|
34
|
+
db,
|
|
35
|
+
count: 1
|
|
36
|
+
};
|
|
37
|
+
commonLog(logger, 'debug', 'DB', `Added DB to pool`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return new DB(dbPath, db, logger);
|
|
20
41
|
}
|
|
21
42
|
exec(sql) {
|
|
22
43
|
this.db.exec(sql);
|
|
@@ -35,7 +56,23 @@ export class DBBase {
|
|
|
35
56
|
return (params ? stmt.all(...params) : stmt.all());
|
|
36
57
|
}
|
|
37
58
|
close() {
|
|
38
|
-
this.
|
|
59
|
+
if (!this.dbPath) {
|
|
60
|
+
this.log('debug', '(dry-run) Close in-memory DB');
|
|
61
|
+
this.db.close();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const poolEntry = DBBase.dbPool[this.dbPath];
|
|
65
|
+
if (poolEntry && poolEntry.count > 0) {
|
|
66
|
+
poolEntry.count--;
|
|
67
|
+
if (poolEntry.count === 0) {
|
|
68
|
+
this.log('debug', 'Close DB (no shares remaining)');
|
|
69
|
+
delete DBBase.dbPool[this.dbPath];
|
|
70
|
+
this.db.close();
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this.log('debug', `Close DB skipped - ${poolEntry.count} shares remaining`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
39
76
|
}
|
|
40
77
|
transaction(fn) {
|
|
41
78
|
return this.db.transaction(fn);
|
|
@@ -48,7 +85,7 @@ export class DBBase {
|
|
|
48
85
|
commonLog(this.logger, level, this.name, ...msg);
|
|
49
86
|
}
|
|
50
87
|
}
|
|
51
|
-
DBBase.
|
|
88
|
+
DBBase.dbPool = {};
|
|
52
89
|
const DB = EnvDBMixin(ContentDBMixin(CampaignDBMixin(UserDBMixin(MediaDBMixin(DBBase)))));
|
|
53
90
|
export default DB;
|
|
54
91
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/browse/db/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAiB,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/browse/db/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type Database from 'better-sqlite3';\nimport type Logger from '../../utils/logging/Logger.js';\nimport { commonLog, type LogLevel } from '../../utils/logging/Logger.js';\nimport { openDB } from './Init.js';\nimport { MediaDBMixin } from './MediaDBMixin.js';\nimport { UserDBMixin } from './UserDBMixin.js';\nimport { CampaignDBMixin } from './CampaignDBMixin.js';\nimport { ContentDBMixin } from './ContentDBMixin.js';\nimport { EnvDBMixin } from './EnvDBMixin.js';\nimport path from 'path';\n\nexport type DBConstructor = new (...args: any[]) => DBBase;\nexport type DBInstance = InstanceType<typeof DB>;\n\ninterface DBPool {\n [dbPath: string]: { db: Database.Database; count: number; } | undefined;\n}\n\nexport class DBBase {\n name = 'DB';\n\n dbPath: string | null;\n static dbPool: DBPool = {};\n db: Database.Database;\n logger?: Logger | null;\n\n constructor(dbPath: string | null, db: Database.Database, logger?: Logger | null) {\n this.dbPath = dbPath;\n this.db = db;\n this.logger = logger;\n }\n\n static async getInstance(file: string, dryRun = false, logger?: Logger | null): Promise<DBInstance> {\n let db: Database.Database;\n let dbPath: string | null;\n if (dryRun) {\n dbPath = null;\n db = await openDB(file, dryRun, logger);\n }\n else {\n dbPath = path.resolve(file);\n const poolEntry = this.dbPool[dbPath];\n if (poolEntry) {\n db = poolEntry.db;\n poolEntry.count++;\n commonLog(\n logger,\n 'debug',\n 'DB',\n `Obtained DB from pool (shares: ${poolEntry.count})`\n );\n }\n else {\n db = await openDB(file, dryRun, logger);\n this.dbPool[dbPath] = {\n db,\n count: 1\n };\n commonLog(\n logger,\n 'debug',\n 'DB',\n `Added DB to pool`\n );\n }\n }\n return new DB(dbPath, db, logger);\n }\n\n exec(sql: string): void {\n this.db.exec(sql);\n }\n\n run(sql: string, params?: any[]): Database.RunResult {\n const stmt = this.db.prepare(sql);\n return params ? stmt.run(...params) : stmt.run();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters\n get<T = any>(sql: string, params?: any[]): T | undefined {\n const stmt = this.db.prepare(sql);\n return (params ? stmt.get(...params) : stmt.get()) as T | undefined;\n }\n\n all<T = any>(sql: string, params?: any[]): T[] {\n const stmt = this.db.prepare(sql);\n return (params ? stmt.all(...params) : stmt.all()) as T[];\n }\n\n close(): void {\n if (!this.dbPath) {\n this.log('debug', '(dry-run) Close in-memory DB');\n this.db.close();\n return;\n }\n const poolEntry = DBBase.dbPool[this.dbPath];\n if (poolEntry && poolEntry.count > 0) {\n poolEntry.count--;\n if (poolEntry.count === 0) {\n this.log('debug', 'Close DB (no shares remaining)');\n delete DBBase.dbPool[this.dbPath];\n this.db.close();\n }\n else {\n this.log('debug', `Close DB skipped - ${poolEntry.count} shares remaining`)\n }\n }\n }\n\n transaction(fn: (...args: any[]) => any): (...args: any[]) => any {\n return this.db.transaction(fn);\n }\n\n log(level: LogLevel, ...msg: any[]) {\n const limiterStopOnError = msg.find(\n (m) => m instanceof Error && m.message === 'LimiterStopOnError'\n );\n if (limiterStopOnError) {\n return;\n }\n commonLog(this.logger, level, this.name, ...msg);\n }\n}\n\nconst DB = EnvDBMixin(\n ContentDBMixin(\n CampaignDBMixin(\n UserDBMixin(\n MediaDBMixin(DBBase)\n )\n )\n )\n);\n\nexport default DB;"]}
|
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
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
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _WebServer_instances, _WebServer_config, _WebServer_app, _WebServer_server, _WebServer_status, _WebServer_port, _WebServer_getPort;
|
|
12
|
+
var _WebServer_instances, _WebServer_config, _WebServer_app, _WebServer_server, _WebServer_status, _WebServer_port, _WebServer_db, _WebServer_getPort;
|
|
13
13
|
import express from 'express';
|
|
14
14
|
import path from 'path';
|
|
15
15
|
import fs from 'fs';
|
|
@@ -27,11 +27,13 @@ export class WebServer {
|
|
|
27
27
|
_WebServer_server.set(this, void 0);
|
|
28
28
|
_WebServer_status.set(this, void 0);
|
|
29
29
|
_WebServer_port.set(this, void 0);
|
|
30
|
+
_WebServer_db.set(this, void 0);
|
|
30
31
|
__classPrivateFieldSet(this, _WebServer_config, config, "f");
|
|
31
32
|
__classPrivateFieldSet(this, _WebServer_app, express(), "f");
|
|
32
33
|
__classPrivateFieldSet(this, _WebServer_server, null, "f");
|
|
33
34
|
__classPrivateFieldSet(this, _WebServer_status, 'stopped', "f");
|
|
34
35
|
__classPrivateFieldSet(this, _WebServer_port, config.port || null, "f");
|
|
36
|
+
__classPrivateFieldSet(this, _WebServer_db, null, "f");
|
|
35
37
|
}
|
|
36
38
|
async start() {
|
|
37
39
|
if (__classPrivateFieldGet(this, _WebServer_status, "f") === 'started') {
|
|
@@ -57,6 +59,7 @@ export class WebServer {
|
|
|
57
59
|
__classPrivateFieldGet(this, _WebServer_app, "f").use('/themes', express.static(path.resolve(import.meta.dirname, '../web/themes')));
|
|
58
60
|
__classPrivateFieldGet(this, _WebServer_app, "f").use('/images', express.static(path.resolve(import.meta.dirname, '../web/images')));
|
|
59
61
|
__classPrivateFieldGet(this, _WebServer_app, "f").use(router);
|
|
62
|
+
__classPrivateFieldSet(this, _WebServer_db, db, "f");
|
|
60
63
|
__classPrivateFieldSet(this, _WebServer_port, await __classPrivateFieldGet(this, _WebServer_instances, "m", _WebServer_getPort).call(this), "f");
|
|
61
64
|
return new Promise((resolve, reject) => {
|
|
62
65
|
__classPrivateFieldSet(this, _WebServer_server, __classPrivateFieldGet(this, _WebServer_app, "f").listen(__classPrivateFieldGet(this, _WebServer_port, "f"), (error) => {
|
|
@@ -77,12 +80,20 @@ export class WebServer {
|
|
|
77
80
|
if (__classPrivateFieldGet(this, _WebServer_server, "f")) {
|
|
78
81
|
__classPrivateFieldGet(this, _WebServer_server, "f").close((error) => {
|
|
79
82
|
if (error) {
|
|
80
|
-
reject(error);
|
|
81
|
-
|
|
83
|
+
return reject(error);
|
|
84
|
+
;
|
|
82
85
|
}
|
|
83
86
|
__classPrivateFieldSet(this, _WebServer_server, null, "f");
|
|
84
87
|
__classPrivateFieldSet(this, _WebServer_port, null, "f");
|
|
85
88
|
__classPrivateFieldSet(this, _WebServer_status, 'stopped', "f");
|
|
89
|
+
if (__classPrivateFieldGet(this, _WebServer_db, "f")) {
|
|
90
|
+
try {
|
|
91
|
+
__classPrivateFieldGet(this, _WebServer_db, "f").close();
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return reject(error instanceof Error ? error : Error(String(error)));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
86
97
|
resolve();
|
|
87
98
|
});
|
|
88
99
|
}
|
|
@@ -98,7 +109,7 @@ export class WebServer {
|
|
|
98
109
|
};
|
|
99
110
|
}
|
|
100
111
|
}
|
|
101
|
-
_WebServer_config = new WeakMap(), _WebServer_app = new WeakMap(), _WebServer_server = new WeakMap(), _WebServer_status = new WeakMap(), _WebServer_port = new WeakMap(), _WebServer_instances = new WeakSet(), _WebServer_getPort = function _WebServer_getPort() {
|
|
112
|
+
_WebServer_config = new WeakMap(), _WebServer_app = new WeakMap(), _WebServer_server = new WeakMap(), _WebServer_status = new WeakMap(), _WebServer_port = new WeakMap(), _WebServer_db = new WeakMap(), _WebServer_instances = new WeakSet(), _WebServer_getPort = function _WebServer_getPort() {
|
|
102
113
|
if (typeof __classPrivateFieldGet(this, _WebServer_config, "f").port === 'number') {
|
|
103
114
|
return __classPrivateFieldGet(this, _WebServer_config, "f").port;
|
|
104
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebServer.js","sourceRoot":"","sources":["../../../src/browse/server/WebServer.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,
|
|
1
|
+
{"version":3,"file":"WebServer.js","sourceRoot":"","sources":["../../../src/browse/server/WebServer.ts"],"names":[],"mappings":"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","sourcesContent":["import express from 'express';\nimport path from 'path';\nimport fs from 'fs';\nimport DB, { type DBInstance } from '../db/index.js';\nimport { type Server } from 'http';\nimport getPort from 'get-port';\nimport { type Logger } from '../../utils/logging/index.js';\nimport { getRouter } from './Router.js';\nimport API from '../api/index.js';\n\nexport const DEFAULT_WEB_SERVER_PORT = 3000;\n\nexport interface WebServerConfig {\n dataDir?: string;\n port?: number | null;\n logger?: Logger | null;\n}\n\nexport class WebServer {\n name = 'WebServer';\n\n #config: WebServerConfig;\n #app: express.Express;\n #server: Server | null;\n #status: 'stopped' | 'started';\n #port: number | null;\n\n #db: DBInstance | null;\n\n constructor(config: WebServerConfig) {\n this.#config = config;\n this.#app = express();\n this.#server = null;\n this.#status = 'stopped';\n this.#port = config.port || null;\n this.#db = null;\n }\n\n async start() {\n if (this.#status === 'started') {\n return;\n }\n\n const dataDir = this.#config.dataDir || process.cwd();\n if (!fs.existsSync(dataDir)) {\n throw Error(`Data directory \"${this.#config.dataDir}\" does not exist`);\n }\n if (!fs.statSync(dataDir).isDirectory()) {\n throw Error(`\"${this.#config.dataDir}\" is not a directory`);\n }\n\n const dbFile = path.resolve(dataDir, '.patreon-dl', 'db.sqlite');\n if (!fs.existsSync(dbFile)) {\n throw Error(`DB file \"${dbFile}\" does not exist`);\n }\n const db = await DB.getInstance(dbFile, false, this.#config.logger);\n const api = API.getInstance(db, this.#config.logger);\n const router = getRouter(db, api, dataDir, this.#config.logger);\n\n this.#app.use(express.json());\n this.#app.use(express.urlencoded({ extended: true }));\n this.#app.use('/assets', express.static(path.resolve(import.meta.dirname, '../web/assets')));\n this.#app.use('/themes', express.static(path.resolve(import.meta.dirname, '../web/themes')));\n this.#app.use('/images', express.static(path.resolve(import.meta.dirname, '../web/images')));\n this.#app.use(router);\n\n this.#db = db;\n this.#port = await this.#getPort();\n\n return new Promise<void>((resolve, reject) => {\n this.#server = this.#app.listen(this.#port, (error) => {\n if (error) {\n reject(error);\n return;\n }\n this.#status = 'started';\n resolve();\n });\n });\n }\n\n stop() {\n if (this.#status === 'stopped') {\n return;\n }\n return new Promise<void>((resolve, reject) => {\n if (this.#server) {\n this.#server.close((error) => {\n if (error) {\n return reject(error);;\n }\n this.#server = null;\n this.#port = null;\n this.#status = 'stopped';\n if (this.#db) {\n try {\n this.#db.close();\n }\n catch (error) {\n return reject(error instanceof Error ? error : Error(String(error)));\n }\n }\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n #getPort() {\n if (typeof this.#config.port === 'number') {\n return this.#config.port;\n }\n return getPort({ port: DEFAULT_WEB_SERVER_PORT });\n }\n\n getConfig(): WebServerConfig {\n return {\n ...this.#config,\n port: this.#port\n };\n }\n}\n"]}
|
|
@@ -78,6 +78,7 @@ export default abstract class Downloader<T extends DownloaderType> extends Event
|
|
|
78
78
|
json: any;
|
|
79
79
|
error: any;
|
|
80
80
|
}>;
|
|
81
|
+
protected closeDB(): Promise<void>;
|
|
81
82
|
on<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;
|
|
82
83
|
once<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;
|
|
83
84
|
off<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;
|
|
@@ -410,6 +410,12 @@ class Downloader extends EventEmitter {
|
|
|
410
410
|
this.log('debug', `Fetch user data from API URL "${url}"`);
|
|
411
411
|
return this.commonFetchAPI(url, signal);
|
|
412
412
|
}
|
|
413
|
+
async closeDB() {
|
|
414
|
+
if (__classPrivateFieldGet(this, _Downloader_dbPromise, "f")) {
|
|
415
|
+
(await __classPrivateFieldGet(this, _Downloader_dbPromise, "f")).close();
|
|
416
|
+
__classPrivateFieldSet(this, _Downloader_dbPromise, null, "f");
|
|
417
|
+
}
|
|
418
|
+
}
|
|
413
419
|
on(event, listener) {
|
|
414
420
|
return super.on(event, listener);
|
|
415
421
|
}
|