patreon-dl 3.2.0 → 3.3.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.
Files changed (109) hide show
  1. package/README.md +15 -0
  2. package/dist/browse/api/CampaignAPIMixin.d.ts +4 -4
  3. package/dist/browse/api/CampaignAPIMixin.js +4 -4
  4. package/dist/browse/api/CampaignAPIMixin.js.map +1 -1
  5. package/dist/browse/api/ContentAPIMixin.d.ts +6 -5
  6. package/dist/browse/api/ContentAPIMixin.js +64 -29
  7. package/dist/browse/api/ContentAPIMixin.js.map +1 -1
  8. package/dist/browse/api/FilterAPIMixin.d.ts +3 -3
  9. package/dist/browse/api/FilterAPIMixin.js +13 -13
  10. package/dist/browse/api/FilterAPIMixin.js.map +1 -1
  11. package/dist/browse/api/MediaAPIMixin.d.ts +1 -1
  12. package/dist/browse/api/MediaAPIMixin.js.map +1 -1
  13. package/dist/browse/api/SettingsAPIMixin.d.ts +3 -3
  14. package/dist/browse/api/SettingsAPIMixin.js +2 -2
  15. package/dist/browse/api/SettingsAPIMixin.js.map +1 -1
  16. package/dist/browse/api/index.d.ts +30 -28
  17. package/dist/browse/db/CampaignDBMixin.d.ts +28 -27
  18. package/dist/browse/db/CampaignDBMixin.js +29 -29
  19. package/dist/browse/db/CampaignDBMixin.js.map +1 -1
  20. package/dist/browse/db/ContentDBMixin.d.ts +55 -50
  21. package/dist/browse/db/ContentDBMixin.js +158 -58
  22. package/dist/browse/db/ContentDBMixin.js.map +1 -1
  23. package/dist/browse/db/EnvDBMixin.d.ts +10 -9
  24. package/dist/browse/db/EnvDBMixin.js +9 -8
  25. package/dist/browse/db/EnvDBMixin.js.map +1 -1
  26. package/dist/browse/db/Init.d.ts +2 -3
  27. package/dist/browse/db/Init.js +71 -18
  28. package/dist/browse/db/Init.js.map +1 -1
  29. package/dist/browse/db/MediaDBMixin.d.ts +18 -17
  30. package/dist/browse/db/MediaDBMixin.js +19 -19
  31. package/dist/browse/db/MediaDBMixin.js.map +1 -1
  32. package/dist/browse/db/Update.d.ts +7 -0
  33. package/dist/browse/db/Update.js +46 -0
  34. package/dist/browse/db/Update.js.map +1 -0
  35. package/dist/browse/db/UserDBMixin.d.ts +21 -20
  36. package/dist/browse/db/UserDBMixin.js +10 -10
  37. package/dist/browse/db/UserDBMixin.js.map +1 -1
  38. package/dist/browse/db/index.d.ts +378 -142
  39. package/dist/browse/db/index.js +27 -47
  40. package/dist/browse/db/index.js.map +1 -1
  41. package/dist/browse/db/updaters/DBUpdater_1_1_0.d.ts +2 -0
  42. package/dist/browse/db/updaters/DBUpdater_1_1_0.js +11 -0
  43. package/dist/browse/db/updaters/DBUpdater_1_1_0.js.map +1 -0
  44. package/dist/browse/server/handler/CampaignAPIRequesthandler.d.ts +2 -2
  45. package/dist/browse/server/handler/CampaignAPIRequesthandler.js +4 -4
  46. package/dist/browse/server/handler/CampaignAPIRequesthandler.js.map +1 -1
  47. package/dist/browse/server/handler/ContentAPIRequestHandler.d.ts +3 -3
  48. package/dist/browse/server/handler/ContentAPIRequestHandler.js +50 -30
  49. package/dist/browse/server/handler/ContentAPIRequestHandler.js.map +1 -1
  50. package/dist/browse/server/handler/MediaAPIRequestHandler.d.ts +2 -2
  51. package/dist/browse/server/handler/MediaAPIRequestHandler.js +8 -8
  52. package/dist/browse/server/handler/MediaAPIRequestHandler.js.map +1 -1
  53. package/dist/browse/server/handler/MediaRequestHandler.d.ts +1 -1
  54. package/dist/browse/server/handler/MediaRequestHandler.js +11 -2
  55. package/dist/browse/server/handler/MediaRequestHandler.js.map +1 -1
  56. package/dist/browse/server/handler/SettingsAPIRequestHandler.d.ts +2 -2
  57. package/dist/browse/server/handler/SettingsAPIRequestHandler.js +4 -4
  58. package/dist/browse/server/handler/SettingsAPIRequestHandler.js.map +1 -1
  59. package/dist/browse/types/Content.d.ts +8 -0
  60. package/dist/browse/types/Content.js.map +1 -1
  61. package/dist/browse/web/assets/index-C5gLqRAU.js +209 -0
  62. package/dist/browse/web/assets/{index-USVypdWT.css → index-b301OTnD.css} +1 -1
  63. package/dist/browse/web/index.html +2 -2
  64. package/dist/cli/CLIOptions.d.ts +2 -1
  65. package/dist/cli/CLIOptions.js +20 -13
  66. package/dist/cli/CLIOptions.js.map +1 -1
  67. package/dist/cli/index.js +7 -4
  68. package/dist/cli/index.js.map +1 -1
  69. package/dist/downloaders/Downloader.d.ts +2 -2
  70. package/dist/downloaders/Downloader.js +6 -5
  71. package/dist/downloaders/Downloader.js.map +1 -1
  72. package/dist/downloaders/PostDownloader.js +72 -7
  73. package/dist/downloaders/PostDownloader.js.map +1 -1
  74. package/dist/downloaders/ProductDownloader.js +2 -2
  75. package/dist/downloaders/ProductDownloader.js.map +1 -1
  76. package/dist/downloaders/task/DownloadTaskFactory.js +1 -0
  77. package/dist/downloaders/task/DownloadTaskFactory.js.map +1 -1
  78. package/dist/downloaders/task/FFmpegDownloadTaskBase.d.ts +1 -1
  79. package/dist/downloaders/task/FFmpegDownloadTaskBase.js +27 -13
  80. package/dist/downloaders/task/FFmpegDownloadTaskBase.js.map +1 -1
  81. package/dist/downloaders/task/M3U8DownloadTask.js +3 -1
  82. package/dist/downloaders/task/M3U8DownloadTask.js.map +1 -1
  83. package/dist/downloaders/task/YouTubeDownloadTask.d.ts +4 -2
  84. package/dist/downloaders/task/YouTubeDownloadTask.js +63 -6
  85. package/dist/downloaders/task/YouTubeDownloadTask.js.map +1 -1
  86. package/dist/entities/Post.d.ts +13 -0
  87. package/dist/entities/Post.js.map +1 -1
  88. package/dist/parsers/Parser.d.ts +2 -0
  89. package/dist/parsers/Parser.js +17 -1
  90. package/dist/parsers/Parser.js.map +1 -1
  91. package/dist/parsers/PostParser.js +4 -1
  92. package/dist/parsers/PostParser.js.map +1 -1
  93. package/dist/utils/FSHelper.d.ts +0 -1
  94. package/dist/utils/FSHelper.js +0 -10
  95. package/dist/utils/FSHelper.js.map +1 -1
  96. package/dist/utils/Fetcher.d.ts +2 -0
  97. package/dist/utils/Fetcher.js +3 -0
  98. package/dist/utils/Fetcher.js.map +1 -1
  99. package/dist/utils/Misc.d.ts +1 -1
  100. package/dist/utils/Misc.js.map +1 -1
  101. package/dist/utils/URLHelper.d.ts +9 -0
  102. package/dist/utils/URLHelper.js +25 -0
  103. package/dist/utils/URLHelper.js.map +1 -1
  104. package/dist/utils/logging/FileLogger.js +3 -3
  105. package/dist/utils/logging/FileLogger.js.map +1 -1
  106. package/dist/utils/yt/InnertubeLoader.js +1 -0
  107. package/dist/utils/yt/InnertubeLoader.js.map +1 -1
  108. package/package.json +5 -5
  109. package/dist/browse/web/assets/index-BqQSEIOs.js +0 -209
package/README.md CHANGED
@@ -267,6 +267,21 @@ 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.0
271
+ - Fix:
272
+ - YouTube stream fetching error ([patreon-dl-gui#28](https://github.com/patrickkfkan/patreon-dl-gui/issues/28))
273
+ - Unsupported option error with FFmpeg v7.1.0 ([#97](https://github.com/patrickkfkan/patreon-dl/issues/97))
274
+ - Browse:
275
+ - Add next / previous links to post page ([#93](https://github.com/patrickkfkan/patreon-dl/issues/93))
276
+ - Fix media filter error when tier selected but not "Post"
277
+ - Process linked attachments in body of posts ([patreon-dl-gui#27](https://github.com/patrickkfkan/patreon-dl-gui/issues/27))
278
+ - Some DB optimizations (contrib by @[piperswe](https://github.com/piperswe) - PR #[95](https://github.com/patrickkfkan/patreon-dl/pull/95))
279
+
280
+ v3.2.1
281
+ - Fix log file path sometimes not sanitized properly on Windows
282
+ - API: add support for passing request options to `getCampaign()`
283
+ - CLI: add support for using request options from conf file when running with `--list-tiers` / `--list-tiers-uid`
284
+
270
285
  v3.2.0
271
286
  - Fix:
272
287
  - "Initial data not found" error in `patreon.com/cw` pages ([#85](https://github.com/patrickkfkan/patreon-dl/issues/85)) and custom-domain pages
@@ -3,14 +3,14 @@ import { type Campaign } from "../../entities/index.js";
3
3
  import { type CampaignList, type CampaignWithCounts, type GetCampaignListParams, type GetCampaignParams } from "../types/Campaign.js";
4
4
  export declare function CampaignAPIMixin<TBase extends APIConstructor>(Base: TBase): {
5
5
  new (...args: any[]): {
6
- getCampaignList(params: GetCampaignListParams): Promise<CampaignList>;
6
+ getCampaignList(params: GetCampaignListParams): CampaignList;
7
7
  getCampaign(params: GetCampaignParams & {
8
8
  withCounts: true;
9
- }): Promise<CampaignWithCounts | null>;
9
+ }): CampaignWithCounts | null;
10
10
  getCampaign(params: GetCampaignParams & {
11
11
  withCounts?: false;
12
- }): Promise<Campaign | null>;
13
- getCampaign(params: GetCampaignParams): Promise<Campaign | CampaignWithCounts | null>;
12
+ }): Campaign | null;
13
+ getCampaign(params: GetCampaignParams): Campaign | CampaignWithCounts | null;
14
14
  "__#132@#sanitizeCampaign"(campaign: Campaign): void;
15
15
  name: string;
16
16
  db: import("../db").DBInstance;
@@ -12,9 +12,9 @@ export function CampaignAPIMixin(Base) {
12
12
  super(...arguments);
13
13
  _CampaignAPI_instances.add(this);
14
14
  }
15
- async getCampaignList(params) {
15
+ getCampaignList(params) {
16
16
  const { sortBy = DEFAULT_CAMPAIGN_LIST_SORT_BY, limit = DEFAULT_CAMPAIGN_LIST_SIZE, offset = 0 } = params;
17
- const list = await this.db.getCampaignList({
17
+ const list = this.db.getCampaignList({
18
18
  sortBy,
19
19
  limit,
20
20
  offset
@@ -24,8 +24,8 @@ export function CampaignAPIMixin(Base) {
24
24
  }
25
25
  return list;
26
26
  }
27
- async getCampaign(params) {
28
- const campaign = await this.db.getCampaign(params);
27
+ getCampaign(params) {
28
+ const campaign = this.db.getCampaign(params);
29
29
  if (campaign) {
30
30
  __classPrivateFieldGet(this, _CampaignAPI_instances, "m", _CampaignAPI_sanitizeCampaign).call(this, campaign);
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CampaignAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/CampaignAPIMixin.ts"],"names":[],"mappings":";;;;;AAKA,MAAM,0BAA0B,GAAG,EAAE,CAAC;AACtC,MAAM,6BAA6B,GAAuB,KAAK,CAAC;AAGhE,MAAM,UAAU,gBAAgB,CAA+B,IAAW;;IACxE,YAAO,MAAM,WAAY,SAAQ,IAAI;YAA9B;;;YAmCP,CAAC;YAlCC,KAAK,CAAC,eAAe,CAAC,MAA6B;gBACjD,MAAM,EAAE,MAAM,GAAG,6BAA6B,EAAE,KAAK,GAAG,0BAA0B,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC;gBAC1G,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC;oBACzC,MAAM;oBACN,KAAK;oBACL,MAAM;iBACP,CAAC,CAAC;gBACH,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACtC,uBAAA,IAAI,6DAAkB,MAAtB,IAAI,EAAmB,QAAQ,CAAC,CAAC;gBACnC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YAKD,KAAK,CAAC,WAAW,CAAC,MAAyB;gBACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBACnD,IAAI,QAAQ,EAAE,CAAC;oBACb,uBAAA,IAAI,6DAAkB,MAAtB,IAAI,EAAmB,QAAQ,CAAC,CAAC;gBACnC,CAAC;gBACD,OAAO,QAAQ,CAAC;YAClB,CAAC;SAYF;;+EAVmB,QAAkB;YAClC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACzD,CAAC;YACD,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBACvB,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC;QACH,CAAC;WACF;AACH,CAAC","sourcesContent":["import { type APIConstructor } from \".\";\nimport { type Campaign } from \"../../entities/index.js\";\nimport { type CampaignList, type CampaignListSortBy, type CampaignWithCounts, type GetCampaignListParams, type GetCampaignParams } from \"../types/Campaign.js\";\n\n\nconst DEFAULT_CAMPAIGN_LIST_SIZE = 10;\nconst DEFAULT_CAMPAIGN_LIST_SORT_BY: CampaignListSortBy = 'a-z';\n\n\nexport function CampaignAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class CampaignAPI extends Base {\n async getCampaignList(params: GetCampaignListParams): Promise<CampaignList> {\n const { sortBy = DEFAULT_CAMPAIGN_LIST_SORT_BY, limit = DEFAULT_CAMPAIGN_LIST_SIZE, offset = 0 } = params;\n const list = await this.db.getCampaignList({\n sortBy,\n limit,\n offset\n });\n for (const campaign of list.campaigns) {\n this.#sanitizeCampaign(campaign);\n }\n return list;\n }\n\n async getCampaign(params: GetCampaignParams & { withCounts: true }): Promise<CampaignWithCounts | null>;\n async getCampaign(params: GetCampaignParams & { withCounts?: false }): Promise<Campaign | null>;\n async getCampaign(params: GetCampaignParams): Promise<Campaign | CampaignWithCounts | null>;\n async getCampaign(params: GetCampaignParams) {\n const campaign = await this.db.getCampaign(params);\n if (campaign) {\n this.#sanitizeCampaign(campaign);\n }\n return campaign;\n }\n\n #sanitizeCampaign(campaign: Campaign) {\n if (campaign.summary) {\n campaign.summary = this.sanitizeHTML(campaign.summary);\n }\n for (const reward of campaign.rewards) {\n if (reward.description) {\n reward.description = this.sanitizeHTML(reward.description);\n }\n }\n }\n }\n}"]}
1
+ {"version":3,"file":"CampaignAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/CampaignAPIMixin.ts"],"names":[],"mappings":";;;;;AAKA,MAAM,0BAA0B,GAAG,EAAE,CAAC;AACtC,MAAM,6BAA6B,GAAuB,KAAK,CAAC;AAGhE,MAAM,UAAU,gBAAgB,CAA+B,IAAW;;IACxE,YAAO,MAAM,WAAY,SAAQ,IAAI;YAA9B;;;YAmCP,CAAC;YAlCC,eAAe,CAAC,MAA6B;gBAC3C,MAAM,EAAE,MAAM,GAAG,6BAA6B,EAAE,KAAK,GAAG,0BAA0B,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC;gBAC1G,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC;oBACnC,MAAM;oBACN,KAAK;oBACL,MAAM;iBACP,CAAC,CAAC;gBACH,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACtC,uBAAA,IAAI,6DAAkB,MAAtB,IAAI,EAAmB,QAAQ,CAAC,CAAC;gBACnC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YAKD,WAAW,CAAC,MAAyB;gBACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAC7C,IAAI,QAAQ,EAAE,CAAC;oBACb,uBAAA,IAAI,6DAAkB,MAAtB,IAAI,EAAmB,QAAQ,CAAC,CAAC;gBACnC,CAAC;gBACD,OAAO,QAAQ,CAAC;YAClB,CAAC;SAYF;;+EAVmB,QAAkB;YAClC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACzD,CAAC;YACD,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBACvB,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC;QACH,CAAC;WACF;AACH,CAAC","sourcesContent":["import { type APIConstructor } from \".\";\nimport { type Campaign } from \"../../entities/index.js\";\nimport { type CampaignList, type CampaignListSortBy, type CampaignWithCounts, type GetCampaignListParams, type GetCampaignParams } from \"../types/Campaign.js\";\n\n\nconst DEFAULT_CAMPAIGN_LIST_SIZE = 10;\nconst DEFAULT_CAMPAIGN_LIST_SORT_BY: CampaignListSortBy = 'a-z';\n\n\nexport function CampaignAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class CampaignAPI extends Base {\n getCampaignList(params: GetCampaignListParams): CampaignList {\n const { sortBy = DEFAULT_CAMPAIGN_LIST_SORT_BY, limit = DEFAULT_CAMPAIGN_LIST_SIZE, offset = 0 } = params;\n const list = this.db.getCampaignList({\n sortBy,\n limit,\n offset\n });\n for (const campaign of list.campaigns) {\n this.#sanitizeCampaign(campaign);\n }\n return list;\n }\n\n getCampaign(params: GetCampaignParams & { withCounts: true }): CampaignWithCounts | null;\n getCampaign(params: GetCampaignParams & { withCounts?: false }): Campaign | null;\n getCampaign(params: GetCampaignParams): Campaign | CampaignWithCounts | null;\n getCampaign(params: GetCampaignParams) {\n const campaign = this.db.getCampaign(params);\n if (campaign) {\n this.#sanitizeCampaign(campaign);\n }\n return campaign;\n }\n\n #sanitizeCampaign(campaign: Campaign) {\n if (campaign.summary) {\n campaign.summary = this.sanitizeHTML(campaign.summary);\n }\n for (const reward of campaign.rewards) {\n if (reward.description) {\n reward.description = this.sanitizeHTML(reward.description);\n }\n }\n }\n }\n}"]}
@@ -1,11 +1,12 @@
1
1
  import { type APIConstructor } from ".";
2
- import { type Post } from "../../entities";
3
- import { type ContentType, type GetContentListParams } from "../types/Content.js";
2
+ import { type Product, type Post } from "../../entities";
3
+ import { type GetContentContext, type ContentType, type GetContentListParams } from "../types/Content.js";
4
4
  export declare function ContentAPIMixin<TBase extends APIConstructor>(Base: TBase): {
5
5
  new (...args: any[]): {
6
- getContentList<T extends ContentType>(params: GetContentListParams<T>): Promise<import("../types/Content.js").ContentList<T>>;
7
- getPost(id: string): Promise<import("../types/Content.js").PostWithComments | null>;
8
- getProduct(id: string): Promise<import("../../entities").Product | null>;
6
+ getContentList<T extends ContentType>(params: GetContentListParams<T>): import("../types/Content.js").ContentList<T>;
7
+ getPost(id: string): import("../types/Content.js").PostWithComments | null;
8
+ getProduct(id: string): Product | null;
9
+ getPreviousNextContent<T extends ContentType>(content: Post | Product, context: GetContentContext<T>): import("../types/Content.js").GetPreviousNextContentResult<T>;
9
10
  "__#133@#processPostContentInlineMedia"(post: Post): void;
10
11
  name: string;
11
12
  db: import("../db").DBInstance;
@@ -5,6 +5,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
5
5
  };
6
6
  import { load as cheerioLoad } from 'cheerio';
7
7
  import RawDataExtractor from '../web/utils/RawDataExtractor.js';
8
+ import { URLHelper } from '../../utils/index.js';
8
9
  const DEFAULT_CONTENT_LIST_SIZE = 10;
9
10
  const DEFAULT_CONTENT_LIST_SORT_BY = 'a-z';
10
11
  export function ContentAPIMixin(Base) {
@@ -14,9 +15,9 @@ export function ContentAPIMixin(Base) {
14
15
  super(...arguments);
15
16
  _ContentAPI_instances.add(this);
16
17
  }
17
- async getContentList(params) {
18
+ getContentList(params) {
18
19
  const { sortBy = DEFAULT_CONTENT_LIST_SORT_BY, limit = DEFAULT_CONTENT_LIST_SIZE, offset = 0 } = params;
19
- const list = await this.db.getContentList({
20
+ const list = this.db.getContentList({
20
21
  ...params,
21
22
  sortBy,
22
23
  limit,
@@ -37,8 +38,8 @@ export function ContentAPIMixin(Base) {
37
38
  }
38
39
  return list;
39
40
  }
40
- async getPost(id) {
41
- const post = await this.db.getContent(id, 'post');
41
+ getPost(id) {
42
+ const post = this.db.getContent(id, 'post');
42
43
  if (post) {
43
44
  __classPrivateFieldGet(this, _ContentAPI_instances, "m", _ContentAPI_processPostContentInlineMedia).call(this, post);
44
45
  post.content = this.sanitizeHTML(post.content || '');
@@ -48,41 +49,75 @@ export function ContentAPIMixin(Base) {
48
49
  getProduct(id) {
49
50
  return this.db.getContent(id, 'product');
50
51
  }
52
+ getPreviousNextContent(content, context) {
53
+ return this.db.getPreviousNextContent(content, context);
54
+ }
51
55
  },
52
56
  _ContentAPI_instances = new WeakSet(),
53
57
  _ContentAPI_processPostContentInlineMedia = function _ContentAPI_processPostContentInlineMedia(post) {
54
58
  const html = post.content || '';
55
- if (!html || post.images.length === 0) {
59
+ const hasImages = post.images.length > 0;
60
+ const hasLinkedAttachments = post.linkedAttachments && post.linkedAttachments.length > 0;
61
+ if (!html || (!hasImages && !hasLinkedAttachments)) {
56
62
  return;
57
63
  }
58
64
  const $ = cheerioLoad(html);
59
65
  const replacedMediaIds = [];
60
- $('img').each((_, _el) => {
61
- const el = $(_el);
62
- const id = el.attr('data-media-id');
63
- const matched = id ? post.images.find(img => img.id === id && img.downloaded) : null;
64
- const src = matched ? `/media/${matched.id}` : el.attr('src');
65
- const imgEl = $('<img>').attr('src', src);
66
- const aEl = $('<a>')
67
- .attr('href', src)
68
- .attr('class', 'lightgallery-item')
69
- .append(imgEl);
70
- const wrapperEl = $('<div>')
71
- .attr('class', 'post-card__inline-media-wrapper')
72
- .append(aEl);
73
- if (!matched) {
74
- const caption = "(Externally hosted - not stored locally)";
75
- wrapperEl.append($('<span>').attr('class', 'post-card__inline-media-caption').append(caption));
76
- }
77
- el.replaceWith(wrapperEl);
78
- if (id && matched) {
79
- replacedMediaIds.push(id);
66
+ let hasModified = false;
67
+ if (hasImages) {
68
+ $('img').each((_, _el) => {
69
+ const el = $(_el);
70
+ const id = el.attr('data-media-id');
71
+ const matched = id ? post.images.find(img => img.id === id && img.downloaded) : null;
72
+ const src = matched ? `/media/${matched.id}` : el.attr('src');
73
+ const imgEl = $('<img>').attr('src', src);
74
+ const aEl = $('<a>')
75
+ .attr('href', src)
76
+ .attr('class', 'lightgallery-item')
77
+ .append(imgEl);
78
+ const wrapperEl = $('<div>')
79
+ .attr('class', 'post-card__inline-media-wrapper')
80
+ .append(aEl);
81
+ if (!matched) {
82
+ const caption = "(Externally hosted - not stored locally)";
83
+ wrapperEl.append($('<span>').attr('class', 'post-card__inline-media-caption').append(caption));
84
+ }
85
+ el.replaceWith(wrapperEl);
86
+ if (id && matched) {
87
+ replacedMediaIds.push(id);
88
+ }
89
+ });
90
+ if (replacedMediaIds.length > 0) {
91
+ hasModified = true;
92
+ // Remove images that have been inlined
93
+ post.images = post.images.filter((img) => !replacedMediaIds.includes(img.id));
80
94
  }
81
- });
82
- if (replacedMediaIds.length > 0) {
95
+ }
96
+ // Linked attachments
97
+ if (hasLinkedAttachments) {
98
+ $('a').each((_, _el) => {
99
+ const aEl = $(_el);
100
+ const href = aEl.attr('href') || '';
101
+ const { validated, ownerId, mediaId } = URLHelper.isAttachmentLink(href);
102
+ if (validated) {
103
+ let modifiedPath;
104
+ if (post.id !== ownerId) {
105
+ const isDownloaded = post.linkedAttachments?.find((att) => att.postId === ownerId && att.mediaId === mediaId)?.downloadable?.downloaded;
106
+ modifiedPath = isDownloaded && `/media/${mediaId}?lapid=${post.id}`;
107
+ }
108
+ else {
109
+ const isDownloaded = post.attachments.find((att) => att.id === mediaId)?.downloaded;
110
+ modifiedPath = isDownloaded && `/media/${mediaId}`;
111
+ }
112
+ if (modifiedPath) {
113
+ aEl.attr('href', modifiedPath);
114
+ hasModified = true;
115
+ }
116
+ }
117
+ });
118
+ }
119
+ if (hasModified) {
83
120
  post.content = $.html();
84
- // Remove images that have been inlined
85
- post.images = post.images.filter((img) => !replacedMediaIds.includes(img.id));
86
121
  }
87
122
  },
88
123
  _a;
@@ -1 +1 @@
1
- {"version":3,"file":"ContentAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/ContentAPIMixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { load as cheerioLoad } from 'cheerio';\nimport { type APIConstructor } from \".\";\nimport { type Post } from \"../../entities\";\nimport { type ContentListSortBy, type ContentType, type GetContentListParams } from \"../types/Content.js\";\nimport RawDataExtractor from '../web/utils/RawDataExtractor.js';\n\nconst DEFAULT_CONTENT_LIST_SIZE = 10;\nconst DEFAULT_CONTENT_LIST_SORT_BY: ContentListSortBy = 'a-z';\n\nexport function ContentAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class ContentAPI extends Base {\n async getContentList<T extends ContentType>(params: GetContentListParams<T>) {\n const { sortBy = DEFAULT_CONTENT_LIST_SORT_BY, limit = DEFAULT_CONTENT_LIST_SIZE, offset = 0 } = params;\n const list = await this.db.getContentList({\n ...params,\n sortBy,\n limit,\n offset,\n });\n for (const item of list.items) {\n switch (item.type) {\n case 'post':\n this.#processPostContentInlineMedia(item);\n item.content = this.sanitizeHTML(item.content || '');\n break;\n case 'product': {\n const description = RawDataExtractor.getProductRichTextDescription(item);\n item.description = description ? this.sanitizeHTML(description) : null;\n break;\n }\n }\n }\n return list;\n }\n\n async getPost(id: string) {\n const post = await this.db.getContent(id, 'post');\n if (post) {\n this.#processPostContentInlineMedia(post);\n post.content = this.sanitizeHTML(post.content || '');\n }\n return post;\n }\n\n getProduct(id: string) {\n return this.db.getContent(id, 'product');\n }\n\n #processPostContentInlineMedia(post: Post) {\n const html = post.content || '';\n if (!html || post.images.length === 0) {\n return;\n }\n const $ = cheerioLoad(html);\n const replacedMediaIds: string[] = [];\n $('img').each((_, _el) => {\n const el = $(_el);\n const id = el.attr('data-media-id');\n const matched = id ? post.images.find(img => img.id === id && img.downloaded) : null;\n const src = matched ? `/media/${matched.id}` : el.attr('src');\n const imgEl = $('<img>').attr('src', src);\n const aEl = $('<a>')\n .attr('href', src)\n .attr('class', 'lightgallery-item')\n .append(imgEl);\n const wrapperEl = $('<div>')\n .attr('class', 'post-card__inline-media-wrapper')\n .append(aEl);\n if (!matched) {\n const caption = \"(Externally hosted - not stored locally)\";\n wrapperEl.append(\n $('<span>').attr('class', 'post-card__inline-media-caption').append(caption)\n );\n }\n el.replaceWith(wrapperEl);\n if (id && matched) {\n replacedMediaIds.push(id);\n }\n });\n if (replacedMediaIds.length > 0) {\n post.content = $.html();\n // Remove images that have been inlined\n post.images = post.images.filter((img) => !replacedMediaIds.includes(img.id));\n }\n }\n }\n}"]}
1
+ {"version":3,"file":"ContentAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/ContentAPIMixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { load as cheerioLoad } from 'cheerio';\nimport { type APIConstructor } from \".\";\nimport { type Product, type Post } from \"../../entities\";\nimport { type GetContentContext, type ContentListSortBy, type ContentType, type GetContentListParams } from \"../types/Content.js\";\nimport RawDataExtractor from '../web/utils/RawDataExtractor.js';\nimport { URLHelper } from '../../utils/index.js';\n\nconst DEFAULT_CONTENT_LIST_SIZE = 10;\nconst DEFAULT_CONTENT_LIST_SORT_BY: ContentListSortBy = 'a-z';\n\nexport function ContentAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class ContentAPI extends Base {\n getContentList<T extends ContentType>(params: GetContentListParams<T>) {\n const { sortBy = DEFAULT_CONTENT_LIST_SORT_BY, limit = DEFAULT_CONTENT_LIST_SIZE, offset = 0 } = params;\n const list = this.db.getContentList({\n ...params,\n sortBy,\n limit,\n offset,\n });\n for (const item of list.items) {\n switch (item.type) {\n case 'post':\n this.#processPostContentInlineMedia(item);\n item.content = this.sanitizeHTML(item.content || '');\n break;\n case 'product': {\n const description = RawDataExtractor.getProductRichTextDescription(item);\n item.description = description ? this.sanitizeHTML(description) : null;\n break;\n }\n }\n }\n return list;\n }\n\n getPost(id: string) {\n const post = this.db.getContent(id, 'post');\n if (post) {\n this.#processPostContentInlineMedia(post);\n post.content = this.sanitizeHTML(post.content || '');\n }\n return post;\n }\n\n getProduct(id: string) {\n return this.db.getContent(id, 'product');\n }\n\n getPreviousNextContent<T extends ContentType>(content: Post | Product, context: GetContentContext<T>) {\n return this.db.getPreviousNextContent(content, context);\n }\n\n #processPostContentInlineMedia(post: Post) {\n const html = post.content || '';\n const hasImages = post.images.length > 0;\n const hasLinkedAttachments = post.linkedAttachments && post.linkedAttachments.length > 0;\n if (!html || (!hasImages && !hasLinkedAttachments)) {\n return;\n }\n\n const $ = cheerioLoad(html);\n const replacedMediaIds: string[] = [];\n let hasModified = false;\n\n if (hasImages) {\n $('img').each((_, _el) => {\n const el = $(_el);\n const id = el.attr('data-media-id');\n const matched = id ? post.images.find(img => img.id === id && img.downloaded) : null;\n const src = matched ? `/media/${matched.id}` : el.attr('src');\n const imgEl = $('<img>').attr('src', src);\n const aEl = $('<a>')\n .attr('href', src)\n .attr('class', 'lightgallery-item')\n .append(imgEl);\n const wrapperEl = $('<div>')\n .attr('class', 'post-card__inline-media-wrapper')\n .append(aEl);\n if (!matched) {\n const caption = \"(Externally hosted - not stored locally)\";\n wrapperEl.append(\n $('<span>').attr('class', 'post-card__inline-media-caption').append(caption)\n );\n }\n el.replaceWith(wrapperEl);\n if (id && matched) {\n replacedMediaIds.push(id);\n }\n });\n if (replacedMediaIds.length > 0) {\n hasModified = true;\n // Remove images that have been inlined\n post.images = post.images.filter((img) => !replacedMediaIds.includes(img.id));\n }\n }\n\n // Linked attachments\n if (hasLinkedAttachments) {\n $('a').each((_, _el) => {\n const aEl = $(_el);\n const href = aEl.attr('href') || '';\n const { validated, ownerId, mediaId } = URLHelper.isAttachmentLink(href);\n if (validated) {\n let modifiedPath: string | undefined;\n if (post.id !== ownerId) {\n const isDownloaded = post.linkedAttachments?.find((att) => att.postId === ownerId && att.mediaId === mediaId)?.downloadable?.downloaded;\n modifiedPath = isDownloaded && `/media/${mediaId}?lapid=${post.id}`;\n }\n else {\n const isDownloaded = post.attachments.find((att) => att.id === mediaId)?.downloaded;\n modifiedPath = isDownloaded && `/media/${mediaId}`;\n }\n if (modifiedPath) {\n aEl.attr('href', modifiedPath);\n hasModified = true;\n }\n }\n });\n }\n\n if (hasModified) {\n post.content = $.html();\n }\n }\n }\n}"]}
@@ -2,10 +2,10 @@ import { type APIConstructor } from ".";
2
2
  import { type FilterData, type MediaFilterSearchParams, type PostFilterSearchParams, type ProductFilterSearchParams } from "../types/Filter.js";
3
3
  export declare function FilterAPIMixin<TBase extends APIConstructor>(Base: TBase): {
4
4
  new (...args: any[]): {
5
- getPostFilterData(campaignId: string): Promise<FilterData<PostFilterSearchParams>>;
5
+ getPostFilterData(campaignId: string): FilterData<PostFilterSearchParams>;
6
6
  "__#134@#getPostTypeTitle"(postType: string): "Link" | "Audio" | "Image" | "Video" | "Other" | "Text" | "Podcast" | "Poll";
7
- getProductFilterData(campaignId: string): Promise<FilterData<ProductFilterSearchParams>>;
8
- getMediaFilterData(campaignId: string): Promise<FilterData<MediaFilterSearchParams>>;
7
+ getProductFilterData(campaignId: string): FilterData<ProductFilterSearchParams>;
8
+ getMediaFilterData(campaignId: string): FilterData<MediaFilterSearchParams>;
9
9
  name: string;
10
10
  db: import("../db").DBInstance;
11
11
  logger?: import("../..").Logger | null;
@@ -11,13 +11,13 @@ export function FilterAPIMixin(Base) {
11
11
  super(...arguments);
12
12
  _FilterAPI_instances.add(this);
13
13
  }
14
- async getPostFilterData(campaignId) {
15
- const postCountByTier = await this.db.getPostCountByTier(campaignId);
16
- const postCountByType = await this.db.getPostCountByType(campaignId);
17
- const postCountByYear = await this.db.getContentCountByDate('post', 'year', {
14
+ getPostFilterData(campaignId) {
15
+ const postCountByTier = this.db.getPostCountByTier(campaignId);
16
+ const postCountByType = this.db.getPostCountByType(campaignId);
17
+ const postCountByYear = this.db.getContentCountByDate('post', 'year', {
18
18
  campaign: campaignId
19
19
  });
20
- const postCountThisMonth = (await this.db.getContentCountByDate('post', 'month', {
20
+ const postCountThisMonth = (this.db.getContentCountByDate('post', 'month', {
21
21
  campaign: campaignId,
22
22
  date: new Date()
23
23
  }))[0];
@@ -136,11 +136,11 @@ export function FilterAPIMixin(Base) {
136
136
  });
137
137
  return { sections };
138
138
  }
139
- async getProductFilterData(campaignId) {
140
- const productCountByYear = await this.db.getContentCountByDate('product', 'year', {
139
+ getProductFilterData(campaignId) {
140
+ const productCountByYear = this.db.getContentCountByDate('product', 'year', {
141
141
  campaign: campaignId
142
142
  });
143
- const productCountThisMonth = (await this.db.getContentCountByDate('product', 'month', {
143
+ const productCountThisMonth = (this.db.getContentCountByDate('product', 'month', {
144
144
  campaign: campaignId,
145
145
  date: new Date()
146
146
  }))[0];
@@ -210,13 +210,13 @@ export function FilterAPIMixin(Base) {
210
210
  });
211
211
  return { sections };
212
212
  }
213
- async getMediaFilterData(campaignId) {
214
- const mediaCountByTier = await this.db.getMediaCountByTier(campaignId);
215
- const mediaCountByType = await this.db.getMediaCountByContentType(campaignId);
216
- const mediaCountByYear = await this.db.getMediaCountByDate('year', {
213
+ getMediaFilterData(campaignId) {
214
+ const mediaCountByTier = this.db.getMediaCountByTier(campaignId);
215
+ const mediaCountByType = this.db.getMediaCountByContentType(campaignId);
216
+ const mediaCountByYear = this.db.getMediaCountByDate('year', {
217
217
  campaign: campaignId
218
218
  });
219
- const postCountThisMonth = (await this.db.getMediaCountByDate('month', {
219
+ const postCountThisMonth = (this.db.getMediaCountByDate('month', {
220
220
  campaign: campaignId,
221
221
  date: new Date()
222
222
  }))[0];
@@ -1 +1 @@
1
- {"version":3,"file":"FilterAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/FilterAPIMixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { type APIConstructor } from \".\";\nimport { PostType } from \"../../entities/Post.js\";\nimport { type FilterData, type FilterOption, type FilterSection, type MediaFilterSearchParams, type PostFilterSearchParams, type ProductFilterSearchParams } from \"../types/Filter.js\";\nimport { type ContentListSortBy } from \"../types/Content.js\";\nimport { type MediaListSortBy } from \"../types/Media.js\";\n\nexport function FilterAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class FilterAPI extends Base {\n async getPostFilterData(\n campaignId: string\n ): Promise<FilterData<PostFilterSearchParams>> {\n const postCountByTier = await this.db.getPostCountByTier(campaignId);\n const postCountByType = await this.db.getPostCountByType(campaignId);\n const postCountByYear = await this.db.getContentCountByDate('post', 'year', {\n campaign: campaignId\n });\n const postCountThisMonth = (await this.db.getContentCountByDate('post', 'month', {\n campaign: campaignId,\n date: new Date()\n }))[0];\n\n const sections: FilterSection<PostFilterSearchParams>[] = [];\n\n const postTypeRecords = postCountByType.map<FilterOption & { count: number; }>(({ postType, count }) => ({\n title: this.#getPostTypeTitle(postType),\n count,\n value: postType\n }))\n .reduce<Record<string, { count: number, value: string; }>>((result, option) => {\n if (option.value) {\n if (result[option.title]) {\n result[option.title].count += option.count;\n result[option.title].value += `,${option.value}`;\n }\n else {\n result[option.title] = { \n count: option.count,\n value: option.value\n };\n }\n }\n return result;\n }, {});\n const postTypeOptions: FilterOption[] = [];\n for (const [title, { count, value }] of Object.entries(postTypeRecords)) {\n postTypeOptions.push({\n title: `${title} (${count})`,\n value\n });\n }\n if (postTypeOptions.length > 0) {\n sections.push({\n title: 'Post type',\n displayHint: 'pill',\n searchParam: 'post_types',\n options: postTypeOptions\n });\n }\n\n const postAccessOptions: FilterOption[] = [\n {\n title: 'Posts you have access to',\n value: 'true',\n },\n {\n title: 'All posts',\n value: null,\n isDefault: true,\n }\n ];\n sections.push({\n title: 'Post access',\n displayHint: 'list',\n searchParam: 'is_viewable',\n options: postAccessOptions\n });\n\n const tierOptions = postCountByTier.map<FilterOption>(({tierId, title, count}) => ({\n title: `${title || (tierId === '-1' ? 'Public' : title)} (${count})`,\n value: tierId,\n }));\n tierOptions.unshift({\n title: 'Any tier',\n value: null,\n isDefault: true\n });\n sections.push({\n displayHint: 'list',\n searchParam: 'tier_ids',\n options: tierOptions\n });\n\n const sortByOptions: FilterOption[] = [\n {\n title: 'Latest',\n value: 'latest' satisfies ContentListSortBy,\n isDefault: true\n },\n {\n title: 'Oldest',\n value: 'oldest' satisfies ContentListSortBy,\n },\n {\n title: 'A-Z',\n value: 'a-z' satisfies ContentListSortBy,\n },\n {\n title: 'Z-A',\n value: 'z-a' satisfies ContentListSortBy,\n }\n ];\n sections.push({\n title: 'Sort by',\n displayHint: 'list',\n searchParam: 'sort_by',\n options: sortByOptions\n });\n\n const datePublishedOptions = postCountByYear.map<FilterOption>(({dt, count}) => ({\n title: `${dt} (${count})`,\n value: dt,\n }));\n if (postCountThisMonth?.count > 0) {\n datePublishedOptions.unshift({\n title: `This month (${postCountThisMonth.count})`,\n value: 'this_month',\n });\n }\n datePublishedOptions.unshift({\n title: 'Any date',\n value: null,\n isDefault: true\n });\n sections.push({\n title: 'Date published',\n displayHint: 'list',\n searchParam: 'date_published',\n options: datePublishedOptions\n });\n\n return { sections };\n }\n\n #getPostTypeTitle(postType: string) {\n switch (postType) {\n case PostType.Audio:\n return 'Audio';\n case PostType.Image:\n return 'Image';\n case PostType.Link:\n return 'Link';\n case PostType.Podcast:\n return 'Podcast';\n case PostType.Poll:\n return 'Poll';\n case PostType.Text:\n return 'Text';\n case PostType.Video:\n case PostType.VideoEmbed:\n return 'Video';\n default:\n return 'Other';\n }\n }\n\n async getProductFilterData(\n campaignId: string\n ): Promise<FilterData<ProductFilterSearchParams>> {\n const productCountByYear = await this.db.getContentCountByDate('product', 'year', {\n campaign: campaignId\n });\n const productCountThisMonth = (await this.db.getContentCountByDate('product', 'month', {\n campaign: campaignId,\n date: new Date()\n }))[0];\n\n const sections: FilterSection<ProductFilterSearchParams>[] = [];\n \n const productAccessOptions: FilterOption[] = [\n {\n title: 'Products you have access to',\n value: 'true',\n },\n {\n title: 'All products',\n value: null,\n isDefault: true,\n }\n ];\n sections.push({\n title: 'Product access',\n displayHint: 'list',\n searchParam: 'is_viewable',\n options: productAccessOptions\n });\n\n const sortByOptions: FilterOption[] = [\n {\n title: 'Latest',\n value: 'latest' satisfies ContentListSortBy,\n isDefault: true\n },\n {\n title: 'Oldest',\n value: 'oldest' satisfies ContentListSortBy,\n },\n {\n title: 'A-Z',\n value: 'a-z' satisfies ContentListSortBy,\n },\n {\n title: 'Z-A',\n value: 'z-a' satisfies ContentListSortBy,\n }\n ];\n sections.push({\n title: 'Sort by',\n displayHint: 'list',\n searchParam: 'sort_by',\n options: sortByOptions\n });\n\n const datePublishedOptions = productCountByYear.map<FilterOption>(({dt, count}) => ({\n title: `${dt} (${count})`,\n value: dt,\n }));\n if (productCountThisMonth?.count > 0) {\n datePublishedOptions.unshift({\n title: `This month ${productCountThisMonth.count}`,\n value: 'this_month',\n });\n }\n datePublishedOptions.unshift({\n title: 'Any date',\n value: null,\n isDefault: true\n });\n sections.push({\n title: 'Date published',\n displayHint: 'list',\n searchParam: 'date_published',\n options: datePublishedOptions\n });\n\n return { sections };\n }\n\n async getMediaFilterData(\n campaignId: string\n ): Promise<FilterData<MediaFilterSearchParams>> {\n const mediaCountByTier = await this.db.getMediaCountByTier(campaignId);\n const mediaCountByType = await this.db.getMediaCountByContentType(campaignId);\n const mediaCountByYear = await this.db.getMediaCountByDate('year', {\n campaign: campaignId\n });\n const postCountThisMonth = (await this.db.getMediaCountByDate('month', {\n campaign: campaignId,\n date: new Date()\n }))[0];\n\n const sections: FilterSection<MediaFilterSearchParams>[] = [];\n\n const sourceTypeRecords = mediaCountByType.map<FilterOption & { count: number; }>(({ contentType, count }) => ({\n title: contentType === 'post' ? 'Posts' : 'Products',\n count,\n value: contentType\n }))\n .reduce<Record<string, { count: number, value: string; }>>((result, option) => {\n if (option.value) {\n if (result[option.title]) {\n result[option.title].count += option.count;\n result[option.title].value += `,${option.value}`;\n }\n else {\n result[option.title] = { \n count: option.count,\n value: option.value\n };\n }\n }\n return result;\n }, {});\n const sourceTypeOptions: FilterOption[] = [];\n for (const [title, { count, value }] of Object.entries(sourceTypeRecords)) {\n sourceTypeOptions.push({\n title: `${title} (${count})`,\n value\n });\n }\n if (sourceTypeOptions.length > 0) {\n sections.push({\n title: 'Show media from',\n displayHint: 'pill',\n searchParam: 'source_type',\n options: sourceTypeOptions\n });\n }\n\n const mediaAccessOptions: FilterOption[] = [\n {\n title: 'Media you have access to',\n value: 'true',\n },\n {\n title: 'All media',\n value: null,\n isDefault: true,\n }\n ];\n sections.push({\n title: 'Media access',\n displayHint: 'list',\n searchParam: 'is_viewable',\n options: mediaAccessOptions\n });\n\n if (sourceTypeOptions.find((o) => o.value === 'post')) {\n const tierOptions = mediaCountByTier.map<FilterOption>(({tierId, title, count}) => ({\n title: `${title || (tierId === '-1' ? 'Public' : title)} (${count})`,\n value: tierId,\n }));\n tierOptions.unshift({\n title: 'Any tier',\n value: null,\n isDefault: true\n });\n const tierSection: FilterSection<MediaFilterSearchParams> = {\n displayHint: 'list',\n searchParam: 'tier_ids',\n options: tierOptions\n };\n const hasProductSourceType = sourceTypeOptions.find((o) => o.value === 'product');\n if (hasProductSourceType) {\n tierSection.enableCondition = {\n searchParam: 'source_type',\n condition: 'not',\n value: 'post'\n };\n }\n sections.push(tierSection);\n }\n\n const sortByOptions: FilterOption[] = [\n {\n title: 'Latest',\n value: 'latest' satisfies MediaListSortBy,\n isDefault: true\n },\n {\n title: 'Oldest',\n value: 'oldest' satisfies MediaListSortBy,\n }\n ];\n sections.push({\n title: 'Sort by',\n displayHint: 'list',\n searchParam: 'sort_by',\n options: sortByOptions\n });\n\n const datePublishedOptions = mediaCountByYear.map<FilterOption>(({dt, count}) => ({\n title: `${dt} (${count})`,\n value: dt,\n }));\n if (postCountThisMonth?.count > 0) {\n datePublishedOptions.unshift({\n title: `This month (${postCountThisMonth.count})`,\n value: 'this_month',\n });\n }\n datePublishedOptions.unshift({\n title: 'Any date',\n value: null,\n isDefault: true\n });\n sections.push({\n title: 'Date published',\n displayHint: 'list',\n searchParam: 'date_published',\n options: datePublishedOptions\n });\n\n return { sections };\n }\n }\n}"]}
1
+ {"version":3,"file":"FilterAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/FilterAPIMixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { type APIConstructor } from \".\";\nimport { PostType } from \"../../entities/Post.js\";\nimport { type FilterData, type FilterOption, type FilterSection, type MediaFilterSearchParams, type PostFilterSearchParams, type ProductFilterSearchParams } from \"../types/Filter.js\";\nimport { type ContentListSortBy } from \"../types/Content.js\";\nimport { type MediaListSortBy } from \"../types/Media.js\";\n\nexport function FilterAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class FilterAPI extends Base {\n getPostFilterData(\n campaignId: string\n ): FilterData<PostFilterSearchParams> {\n const postCountByTier = this.db.getPostCountByTier(campaignId);\n const postCountByType = this.db.getPostCountByType(campaignId);\n const postCountByYear = this.db.getContentCountByDate('post', 'year', {\n campaign: campaignId\n });\n const postCountThisMonth = (this.db.getContentCountByDate('post', 'month', {\n campaign: campaignId,\n date: new Date()\n }))[0];\n\n const sections: FilterSection<PostFilterSearchParams>[] = [];\n\n const postTypeRecords = postCountByType.map<FilterOption & { count: number; }>(({ postType, count }) => ({\n title: this.#getPostTypeTitle(postType),\n count,\n value: postType\n }))\n .reduce<Record<string, { count: number, value: string; }>>((result, option) => {\n if (option.value) {\n if (result[option.title]) {\n result[option.title].count += option.count;\n result[option.title].value += `,${option.value}`;\n }\n else {\n result[option.title] = { \n count: option.count,\n value: option.value\n };\n }\n }\n return result;\n }, {});\n const postTypeOptions: FilterOption[] = [];\n for (const [title, { count, value }] of Object.entries(postTypeRecords)) {\n postTypeOptions.push({\n title: `${title} (${count})`,\n value\n });\n }\n if (postTypeOptions.length > 0) {\n sections.push({\n title: 'Post type',\n displayHint: 'pill',\n searchParam: 'post_types',\n options: postTypeOptions\n });\n }\n\n const postAccessOptions: FilterOption[] = [\n {\n title: 'Posts you have access to',\n value: 'true',\n },\n {\n title: 'All posts',\n value: null,\n isDefault: true,\n }\n ];\n sections.push({\n title: 'Post access',\n displayHint: 'list',\n searchParam: 'is_viewable',\n options: postAccessOptions\n });\n\n const tierOptions = postCountByTier.map<FilterOption>(({tierId, title, count}) => ({\n title: `${title || (tierId === '-1' ? 'Public' : title)} (${count})`,\n value: tierId,\n }));\n tierOptions.unshift({\n title: 'Any tier',\n value: null,\n isDefault: true\n });\n sections.push({\n displayHint: 'list',\n searchParam: 'tier_ids',\n options: tierOptions\n });\n\n const sortByOptions: FilterOption[] = [\n {\n title: 'Latest',\n value: 'latest' satisfies ContentListSortBy,\n isDefault: true\n },\n {\n title: 'Oldest',\n value: 'oldest' satisfies ContentListSortBy,\n },\n {\n title: 'A-Z',\n value: 'a-z' satisfies ContentListSortBy,\n },\n {\n title: 'Z-A',\n value: 'z-a' satisfies ContentListSortBy,\n }\n ];\n sections.push({\n title: 'Sort by',\n displayHint: 'list',\n searchParam: 'sort_by',\n options: sortByOptions\n });\n\n const datePublishedOptions = postCountByYear.map<FilterOption>(({dt, count}) => ({\n title: `${dt} (${count})`,\n value: dt,\n }));\n if (postCountThisMonth?.count > 0) {\n datePublishedOptions.unshift({\n title: `This month (${postCountThisMonth.count})`,\n value: 'this_month',\n });\n }\n datePublishedOptions.unshift({\n title: 'Any date',\n value: null,\n isDefault: true\n });\n sections.push({\n title: 'Date published',\n displayHint: 'list',\n searchParam: 'date_published',\n options: datePublishedOptions\n });\n\n return { sections };\n }\n\n #getPostTypeTitle(postType: string) {\n switch (postType) {\n case PostType.Audio:\n return 'Audio';\n case PostType.Image:\n return 'Image';\n case PostType.Link:\n return 'Link';\n case PostType.Podcast:\n return 'Podcast';\n case PostType.Poll:\n return 'Poll';\n case PostType.Text:\n return 'Text';\n case PostType.Video:\n case PostType.VideoEmbed:\n return 'Video';\n default:\n return 'Other';\n }\n }\n\n getProductFilterData(\n campaignId: string\n ): FilterData<ProductFilterSearchParams> {\n const productCountByYear = this.db.getContentCountByDate('product', 'year', {\n campaign: campaignId\n });\n const productCountThisMonth = (this.db.getContentCountByDate('product', 'month', {\n campaign: campaignId,\n date: new Date()\n }))[0];\n\n const sections: FilterSection<ProductFilterSearchParams>[] = [];\n \n const productAccessOptions: FilterOption[] = [\n {\n title: 'Products you have access to',\n value: 'true',\n },\n {\n title: 'All products',\n value: null,\n isDefault: true,\n }\n ];\n sections.push({\n title: 'Product access',\n displayHint: 'list',\n searchParam: 'is_viewable',\n options: productAccessOptions\n });\n\n const sortByOptions: FilterOption[] = [\n {\n title: 'Latest',\n value: 'latest' satisfies ContentListSortBy,\n isDefault: true\n },\n {\n title: 'Oldest',\n value: 'oldest' satisfies ContentListSortBy,\n },\n {\n title: 'A-Z',\n value: 'a-z' satisfies ContentListSortBy,\n },\n {\n title: 'Z-A',\n value: 'z-a' satisfies ContentListSortBy,\n }\n ];\n sections.push({\n title: 'Sort by',\n displayHint: 'list',\n searchParam: 'sort_by',\n options: sortByOptions\n });\n\n const datePublishedOptions = productCountByYear.map<FilterOption>(({dt, count}) => ({\n title: `${dt} (${count})`,\n value: dt,\n }));\n if (productCountThisMonth?.count > 0) {\n datePublishedOptions.unshift({\n title: `This month ${productCountThisMonth.count}`,\n value: 'this_month',\n });\n }\n datePublishedOptions.unshift({\n title: 'Any date',\n value: null,\n isDefault: true\n });\n sections.push({\n title: 'Date published',\n displayHint: 'list',\n searchParam: 'date_published',\n options: datePublishedOptions\n });\n\n return { sections };\n }\n\n getMediaFilterData(\n campaignId: string\n ): FilterData<MediaFilterSearchParams> {\n const mediaCountByTier = this.db.getMediaCountByTier(campaignId);\n const mediaCountByType = this.db.getMediaCountByContentType(campaignId);\n const mediaCountByYear = this.db.getMediaCountByDate('year', {\n campaign: campaignId\n });\n const postCountThisMonth = (this.db.getMediaCountByDate('month', {\n campaign: campaignId,\n date: new Date()\n }))[0];\n\n const sections: FilterSection<MediaFilterSearchParams>[] = [];\n\n const sourceTypeRecords = mediaCountByType.map<FilterOption & { count: number; }>(({ contentType, count }) => ({\n title: contentType === 'post' ? 'Posts' : 'Products',\n count,\n value: contentType\n }))\n .reduce<Record<string, { count: number, value: string; }>>((result, option) => {\n if (option.value) {\n if (result[option.title]) {\n result[option.title].count += option.count;\n result[option.title].value += `,${option.value}`;\n }\n else {\n result[option.title] = { \n count: option.count,\n value: option.value\n };\n }\n }\n return result;\n }, {});\n const sourceTypeOptions: FilterOption[] = [];\n for (const [title, { count, value }] of Object.entries(sourceTypeRecords)) {\n sourceTypeOptions.push({\n title: `${title} (${count})`,\n value\n });\n }\n if (sourceTypeOptions.length > 0) {\n sections.push({\n title: 'Show media from',\n displayHint: 'pill',\n searchParam: 'source_type',\n options: sourceTypeOptions\n });\n }\n\n const mediaAccessOptions: FilterOption[] = [\n {\n title: 'Media you have access to',\n value: 'true',\n },\n {\n title: 'All media',\n value: null,\n isDefault: true,\n }\n ];\n sections.push({\n title: 'Media access',\n displayHint: 'list',\n searchParam: 'is_viewable',\n options: mediaAccessOptions\n });\n\n if (sourceTypeOptions.find((o) => o.value === 'post')) {\n const tierOptions = mediaCountByTier.map<FilterOption>(({tierId, title, count}) => ({\n title: `${title || (tierId === '-1' ? 'Public' : title)} (${count})`,\n value: tierId,\n }));\n tierOptions.unshift({\n title: 'Any tier',\n value: null,\n isDefault: true\n });\n const tierSection: FilterSection<MediaFilterSearchParams> = {\n displayHint: 'list',\n searchParam: 'tier_ids',\n options: tierOptions\n };\n const hasProductSourceType = sourceTypeOptions.find((o) => o.value === 'product');\n if (hasProductSourceType) {\n tierSection.enableCondition = {\n searchParam: 'source_type',\n condition: 'not',\n value: 'post'\n };\n }\n sections.push(tierSection);\n }\n\n const sortByOptions: FilterOption[] = [\n {\n title: 'Latest',\n value: 'latest' satisfies MediaListSortBy,\n isDefault: true\n },\n {\n title: 'Oldest',\n value: 'oldest' satisfies MediaListSortBy,\n }\n ];\n sections.push({\n title: 'Sort by',\n displayHint: 'list',\n searchParam: 'sort_by',\n options: sortByOptions\n });\n\n const datePublishedOptions = mediaCountByYear.map<FilterOption>(({dt, count}) => ({\n title: `${dt} (${count})`,\n value: dt,\n }));\n if (postCountThisMonth?.count > 0) {\n datePublishedOptions.unshift({\n title: `This month (${postCountThisMonth.count})`,\n value: 'this_month',\n });\n }\n datePublishedOptions.unshift({\n title: 'Any date',\n value: null,\n isDefault: true\n });\n sections.push({\n title: 'Date published',\n displayHint: 'list',\n searchParam: 'date_published',\n options: datePublishedOptions\n });\n\n return { sections };\n }\n }\n}"]}
@@ -3,7 +3,7 @@ import { type GetMediaListParams, type MediaList } from "../types/Media.js";
3
3
  import { type ContentType } from "../types/Content.js";
4
4
  export declare function MediaAPIMixin<TBase extends APIConstructor>(Base: TBase): {
5
5
  new (...args: any[]): {
6
- getMediaList<T extends ContentType>(params: GetMediaListParams<T>): Promise<MediaList<T>>;
6
+ getMediaList<T extends ContentType>(params: GetMediaListParams<T>): MediaList<T>;
7
7
  name: string;
8
8
  db: import("../db").DBInstance;
9
9
  logger?: import("../..").Logger | null;
@@ -1 +1 @@
1
- {"version":3,"file":"MediaAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/MediaAPIMixin.ts"],"names":[],"mappings":"AAIA,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,0BAA0B,GAAoB,QAAQ,CAAC;AAE7D,MAAM,UAAU,aAAa,CAA+B,IAAW;IACrE,OAAO,MAAM,QAAS,SAAQ,IAAI;QAChC,YAAY,CAAwB,MAA6B;YAC/D,MAAM,EAAE,MAAM,GAAG,0BAA0B,EAAE,KAAK,GAAG,uBAAuB,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC;YACpG,OAAO,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;gBAC1B,GAAG,MAAM;gBACT,MAAM;gBACN,KAAK;gBACL,MAAM;aACP,CAAC,CAAC;QACL,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import { type APIConstructor } from \".\";\nimport { type GetMediaListParams, type MediaList, type MediaListSortBy } from \"../types/Media.js\";\nimport { type ContentType } from \"../types/Content.js\";\n\nconst DEFAULT_MEDIA_LIST_SIZE = 10;\nconst DEFAULT_MEDIA_LIST_SORT_BY: MediaListSortBy = 'latest';\n\nexport function MediaAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class MediaAPI extends Base {\n getMediaList<T extends ContentType>(params: GetMediaListParams<T>): Promise<MediaList<T>> {\n const { sortBy = DEFAULT_MEDIA_LIST_SORT_BY, limit = DEFAULT_MEDIA_LIST_SIZE, offset = 0 } = params;\n return this.db.getMediaList({\n ...params,\n sortBy,\n limit,\n offset,\n });\n }\n }\n}"]}
1
+ {"version":3,"file":"MediaAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/MediaAPIMixin.ts"],"names":[],"mappings":"AAIA,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,0BAA0B,GAAoB,QAAQ,CAAC;AAE7D,MAAM,UAAU,aAAa,CAA+B,IAAW;IACrE,OAAO,MAAM,QAAS,SAAQ,IAAI;QAChC,YAAY,CAAwB,MAA6B;YAC/D,MAAM,EAAE,MAAM,GAAG,0BAA0B,EAAE,KAAK,GAAG,uBAAuB,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC;YACpG,OAAO,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;gBAC1B,GAAG,MAAM;gBACT,MAAM;gBACN,KAAK;gBACL,MAAM;aACP,CAAC,CAAC;QACL,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import { type APIConstructor } from \".\";\nimport { type GetMediaListParams, type MediaList, type MediaListSortBy } from \"../types/Media.js\";\nimport { type ContentType } from \"../types/Content.js\";\n\nconst DEFAULT_MEDIA_LIST_SIZE = 10;\nconst DEFAULT_MEDIA_LIST_SORT_BY: MediaListSortBy = 'latest';\n\nexport function MediaAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class MediaAPI extends Base {\n getMediaList<T extends ContentType>(params: GetMediaListParams<T>): MediaList<T> {\n const { sortBy = DEFAULT_MEDIA_LIST_SORT_BY, limit = DEFAULT_MEDIA_LIST_SIZE, offset = 0 } = params;\n return this.db.getMediaList({\n ...params,\n sortBy,\n limit,\n offset,\n });\n }\n }\n}"]}
@@ -2,12 +2,12 @@ import { type APIConstructor } from ".";
2
2
  import { type BrowseSettingOptions, type BrowseSettings } from "../types/Settings.js";
3
3
  export declare function SettingsAPIMixin<TBase extends APIConstructor>(Base: TBase): {
4
4
  new (...args: any[]): {
5
- getBrowseSettings(): Promise<{
5
+ getBrowseSettings(): {
6
6
  theme: string;
7
7
  listItemsPerPage: number;
8
8
  galleryItemsPerPage: number;
9
- }>;
10
- saveBrowseSettings(settings: BrowseSettings): Promise<void>;
9
+ };
10
+ saveBrowseSettings(settings: BrowseSettings): void;
11
11
  getBrowseSettingOptions(): BrowseSettingOptions;
12
12
  name: string;
13
13
  db: import("../db").DBInstance;
@@ -45,8 +45,8 @@ const DEFAULT_BROWSE_SETTINGS = {
45
45
  };
46
46
  export function SettingsAPIMixin(Base) {
47
47
  return class SettingsAPI extends Base {
48
- async getBrowseSettings() {
49
- const settings = await this.db.getEnvValue(BROWSE_SETTINGS_ENV_KEY);
48
+ getBrowseSettings() {
49
+ const settings = this.db.getEnvValue(BROWSE_SETTINGS_ENV_KEY);
50
50
  if (settings) {
51
51
  return {
52
52
  ...DEFAULT_BROWSE_SETTINGS,
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/SettingsAPIMixin.ts"],"names":[],"mappings":"AAGA,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAElD,MAAM,MAAM,GAAkB;IAC5B;QACE,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,CAAC,iDAAiD,CAAC;KACjE;IACD,GAAG;QACD,OAAO;QACP,UAAU;QACV,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,OAAO;QACP,KAAK;QACL,SAAS;QACT,OAAO;QACP,OAAO;QACP,OAAO;QACP,QAAQ;QACR,WAAW;QACX,SAAS;QACT,SAAS;QACT,OAAO;QACP,OAAO;QACP,UAAU;QACV,WAAW;QACX,QAAQ;QACR,OAAO;QACP,MAAM;QACN,QAAQ;KACT,CAAC,GAAG,CAAC,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;QAChF,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,CAAC,sBAAsB,mBAAmB,oBAAoB,CAAC;KAC7E,CAAC,CAAC;CACJ,CAAA;AAED,MAAM,uBAAuB,GAAmB;IAC9C,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;IACtB,gBAAgB,EAAE,EAAE;IACpB,mBAAmB,EAAE,GAAG;CACzB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAA+B,IAAW;IACxE,OAAO,MAAM,WAAY,SAAQ,IAAI;QACnC,KAAK,CAAC,iBAAiB;YACrB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAiB,uBAAuB,CAAC,CAAC;YACpF,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;oBACL,GAAG,uBAAuB;oBAC1B,GAAG,QAAQ;iBACZ,CAAC;YACJ,CAAC;YACD,OAAO,EAAC,GAAG,uBAAuB,EAAC,CAAC;QACtC,CAAC;QAED,kBAAkB,CAAC,QAAwB;YACzC,OAAO,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;QACjE,CAAC;QAED,uBAAuB;YACrB,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,gBAAgB,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;gBAClC,mBAAmB,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;aACzC,CAAC;QACJ,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import { type APIConstructor } from \".\";\nimport { type BrowseSettingOptions, type BrowseSettings, type BrowseTheme } from \"../types/Settings.js\";\n\nconst BROWSE_SETTINGS_ENV_KEY = 'browse_settings';\n\nconst THEMES: BrowseTheme[] = [\n {\n name: 'Default',\n value: 'default',\n stylesheets: ['/themes/bootstrap/default/css/bootstrap.min.css']\n },\n ...[\n 'brite',\n 'cerulean',\n 'cosmo',\n 'cyborg',\n 'darkly',\n 'flatly',\n 'journal',\n 'litera',\n 'lumen',\n 'lux',\n 'materia',\n 'minty',\n 'morph',\n 'pulse',\n 'quartz',\n 'sandstone',\n 'simplex',\n 'sketchy',\n 'slate',\n 'solar',\n 'spacelab',\n 'superhero',\n 'united',\n 'vapor',\n 'yeti',\n 'zephyr'\n ].map((bootswatchThemeName) => ({\n name: bootswatchThemeName.charAt(0).toUpperCase() + bootswatchThemeName.slice(1),\n value: bootswatchThemeName,\n stylesheets: [`/themes/bootswatch/${bootswatchThemeName}/bootstrap.min.css`]\n }))\n]\n\nconst DEFAULT_BROWSE_SETTINGS: BrowseSettings = {\n theme: THEMES[0].value,\n listItemsPerPage: 20,\n galleryItemsPerPage: 100\n};\n\nexport function SettingsAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class SettingsAPI extends Base {\n async getBrowseSettings() {\n const settings = await this.db.getEnvValue<BrowseSettings>(BROWSE_SETTINGS_ENV_KEY);\n if (settings) {\n return {\n ...DEFAULT_BROWSE_SETTINGS,\n ...settings\n };\n }\n return {...DEFAULT_BROWSE_SETTINGS};\n }\n\n saveBrowseSettings(settings: BrowseSettings) {\n return this.db.saveEnvValue(BROWSE_SETTINGS_ENV_KEY, settings);\n }\n\n getBrowseSettingOptions(): BrowseSettingOptions {\n return {\n themes: THEMES,\n listItemsPerPage: [10, 20, 30, 50],\n galleryItemsPerPage: [50, 100, 150, 200]\n };\n }\n }\n}"]}
1
+ {"version":3,"file":"SettingsAPIMixin.js","sourceRoot":"","sources":["../../../src/browse/api/SettingsAPIMixin.ts"],"names":[],"mappings":"AAGA,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAElD,MAAM,MAAM,GAAkB;IAC5B;QACE,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,CAAC,iDAAiD,CAAC;KACjE;IACD,GAAG;QACD,OAAO;QACP,UAAU;QACV,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,OAAO;QACP,KAAK;QACL,SAAS;QACT,OAAO;QACP,OAAO;QACP,OAAO;QACP,QAAQ;QACR,WAAW;QACX,SAAS;QACT,SAAS;QACT,OAAO;QACP,OAAO;QACP,UAAU;QACV,WAAW;QACX,QAAQ;QACR,OAAO;QACP,MAAM;QACN,QAAQ;KACT,CAAC,GAAG,CAAC,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;QAChF,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,CAAC,sBAAsB,mBAAmB,oBAAoB,CAAC;KAC7E,CAAC,CAAC;CACJ,CAAA;AAED,MAAM,uBAAuB,GAAmB;IAC9C,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;IACtB,gBAAgB,EAAE,EAAE;IACpB,mBAAmB,EAAE,GAAG;CACzB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAA+B,IAAW;IACxE,OAAO,MAAM,WAAY,SAAQ,IAAI;QACnC,iBAAiB;YACf,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAiB,uBAAuB,CAAC,CAAC;YAC9E,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;oBACL,GAAG,uBAAuB;oBAC1B,GAAG,QAAQ;iBACZ,CAAC;YACJ,CAAC;YACD,OAAO,EAAC,GAAG,uBAAuB,EAAC,CAAC;QACtC,CAAC;QAED,kBAAkB,CAAC,QAAwB;YACzC,OAAO,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;QACjE,CAAC;QAED,uBAAuB;YACrB,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,gBAAgB,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;gBAClC,mBAAmB,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;aACzC,CAAC;QACJ,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import { type APIConstructor } from \".\";\nimport { type BrowseSettingOptions, type BrowseSettings, type BrowseTheme } from \"../types/Settings.js\";\n\nconst BROWSE_SETTINGS_ENV_KEY = 'browse_settings';\n\nconst THEMES: BrowseTheme[] = [\n {\n name: 'Default',\n value: 'default',\n stylesheets: ['/themes/bootstrap/default/css/bootstrap.min.css']\n },\n ...[\n 'brite',\n 'cerulean',\n 'cosmo',\n 'cyborg',\n 'darkly',\n 'flatly',\n 'journal',\n 'litera',\n 'lumen',\n 'lux',\n 'materia',\n 'minty',\n 'morph',\n 'pulse',\n 'quartz',\n 'sandstone',\n 'simplex',\n 'sketchy',\n 'slate',\n 'solar',\n 'spacelab',\n 'superhero',\n 'united',\n 'vapor',\n 'yeti',\n 'zephyr'\n ].map((bootswatchThemeName) => ({\n name: bootswatchThemeName.charAt(0).toUpperCase() + bootswatchThemeName.slice(1),\n value: bootswatchThemeName,\n stylesheets: [`/themes/bootswatch/${bootswatchThemeName}/bootstrap.min.css`]\n }))\n]\n\nconst DEFAULT_BROWSE_SETTINGS: BrowseSettings = {\n theme: THEMES[0].value,\n listItemsPerPage: 20,\n galleryItemsPerPage: 100\n};\n\nexport function SettingsAPIMixin<TBase extends APIConstructor>(Base: TBase) {\n return class SettingsAPI extends Base {\n getBrowseSettings() {\n const settings = this.db.getEnvValue<BrowseSettings>(BROWSE_SETTINGS_ENV_KEY);\n if (settings) {\n return {\n ...DEFAULT_BROWSE_SETTINGS,\n ...settings\n };\n }\n return {...DEFAULT_BROWSE_SETTINGS};\n }\n\n saveBrowseSettings(settings: BrowseSettings) {\n return this.db.saveEnvValue(BROWSE_SETTINGS_ENV_KEY, settings);\n }\n\n getBrowseSettingOptions(): BrowseSettingOptions {\n return {\n themes: THEMES,\n listItemsPerPage: [10, 20, 30, 50],\n galleryItemsPerPage: [50, 100, 150, 200]\n };\n }\n }\n}"]}