patreon-dl 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +23 -0
- package/README.md +16 -5
- package/bin/EmbedlyDownloader.js +1 -1
- package/bin/patreon-dl-vimeo.js +7 -4
- package/dist/browse/api/CampaignAPIMixin.d.ts +1 -1
- package/dist/browse/api/ContentAPIMixin.d.ts +4 -1
- package/dist/browse/api/ContentAPIMixin.js +44 -11
- package/dist/browse/api/ContentAPIMixin.js.map +1 -1
- package/dist/browse/api/FilterAPIMixin.d.ts +1 -1
- package/dist/browse/api/SettingsAPIMixin.d.ts +1 -0
- package/dist/browse/api/SettingsAPIMixin.js +4 -2
- package/dist/browse/api/SettingsAPIMixin.js.map +1 -1
- package/dist/browse/api/index.d.ts +12 -6
- package/dist/browse/db/CampaignDBMixin.d.ts +3 -3
- package/dist/browse/db/ContentDBMixin.d.ts +14 -14
- package/dist/browse/db/ContentDBMixin.js +12 -5
- package/dist/browse/db/ContentDBMixin.js.map +1 -1
- package/dist/browse/db/index.d.ts +17 -17
- package/dist/browse/server/handler/SettingsAPIRequestHandler.js +2 -1
- package/dist/browse/server/handler/SettingsAPIRequestHandler.js.map +1 -1
- package/dist/browse/types/Settings.d.ts +3 -0
- package/dist/browse/types/Settings.js.map +1 -1
- package/dist/browse/web/assets/index-CW4CUoWl.css +1 -0
- package/dist/browse/web/assets/{index-Dw_64hkR.js → index-CziUWlSw.js} +31 -31
- package/dist/browse/web/index.html +2 -2
- package/dist/cli/CLIOptions.js +10 -1
- package/dist/cli/CLIOptions.js.map +1 -1
- package/dist/cli/CommandLineParser.d.ts +1 -0
- package/dist/cli/CommandLineParser.js +11 -3
- package/dist/cli/CommandLineParser.js.map +1 -1
- package/dist/downloaders/Bootstrap.d.ts +6 -0
- package/dist/downloaders/Bootstrap.js +26 -0
- package/dist/downloaders/Bootstrap.js.map +1 -1
- package/dist/downloaders/Downloader.d.ts +5 -4
- package/dist/downloaders/Downloader.js +3 -1
- package/dist/downloaders/Downloader.js.map +1 -1
- package/dist/downloaders/InitialData.js +1 -0
- package/dist/downloaders/InitialData.js.map +1 -1
- package/dist/downloaders/PostDownloader.js +16 -0
- package/dist/downloaders/PostDownloader.js.map +1 -1
- package/dist/downloaders/PostsFetcher.js +29 -12
- package/dist/downloaders/PostsFetcher.js.map +1 -1
- package/dist/downloaders/ProductDownloader.js +8 -0
- package/dist/downloaders/ProductDownloader.js.map +1 -1
- package/dist/downloaders/ProductsFetcher.js +32 -15
- package/dist/downloaders/ProductsFetcher.js.map +1 -1
- package/dist/downloaders/task/DownloadTaskFactory.d.ts +4 -0
- package/dist/downloaders/task/DownloadTaskFactory.js +3 -2
- package/dist/downloaders/task/DownloadTaskFactory.js.map +1 -1
- package/dist/downloaders/task/YouTubeDownloadTask.js +7 -2
- package/dist/downloaders/task/YouTubeDownloadTask.js.map +1 -1
- package/dist/entities/Post.d.ts +1 -1
- package/dist/entities/Post.js.map +1 -1
- package/dist/entities/Product.d.ts +1 -1
- package/dist/entities/Product.js.map +1 -1
- package/dist/parsers/PostParser.d.ts +1 -1
- package/dist/parsers/PostParser.js +69 -13
- package/dist/parsers/PostParser.js.map +1 -1
- package/dist/parsers/ProductParser.d.ts +1 -1
- package/dist/parsers/ProductParser.js +5 -6
- package/dist/parsers/ProductParser.js.map +1 -1
- package/dist/utils/FilenameFormatHelper.d.ts +2 -2
- package/dist/utils/FilenameFormatHelper.js +45 -2
- package/dist/utils/FilenameFormatHelper.js.map +1 -1
- package/dist/utils/MediaFilenameResolver.d.ts +4 -1
- package/dist/utils/MediaFilenameResolver.js +6 -4
- package/dist/utils/MediaFilenameResolver.js.map +1 -1
- package/dist/utils/URLHelper.js +8 -8
- package/dist/utils/URLHelper.js.map +1 -1
- package/dist/utils/YouTubeCredentialsCapturer.js +1 -1
- package/dist/utils/YouTubeCredentialsCapturer.js.map +1 -1
- package/dist/utils/yt/InnertubeLoader.d.ts +19 -1
- package/dist/utils/yt/InnertubeLoader.js +55 -15
- package/dist/utils/yt/InnertubeLoader.js.map +1 -1
- package/package.json +2 -1
- package/dist/browse/web/assets/index-DjOKbT1U.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostParser.js","sourceRoot":"","sources":["../../src/parsers/PostParser.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripHtml } from 'string-strip-html';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport { type AttachmentMediaItem, type AudioMediaItem, type DefaultImageMediaItem, type MediaItem, type PostCoverImageMediaItem, type PostThumbnailMediaItem, type VideoMediaItem } from '../entities/MediaItem.js';\nimport { type LinkedAttachment, PostType, type Post, type PostList as PostList, type PostEmbed, type Collection, type PostTag } from '../entities/Post.js';\nimport { type Tier } from '../entities/Reward.js';\nimport { pickDefined } from '../utils/Misc.js';\nimport ObjectHelper from '../utils/ObjectHelper.js';\nimport Parser from './Parser.js';\n\nexport default class PostParser extends Parser {\n\n protected name = 'PostParser';\n\n parsePostsAPIResponse(json: any, _url: string): PostList {\n\n this.log('debug', `Parse API response of \"${_url}\"`);\n\n /*If (json.errors) {\n this.log('error', `API response error:`, json.errors);\n return null;\n }*/\n\n const includedJSON = json.included;\n const dataJSON = json.data;\n let postsJSONArray: any[];\n // Check if API data consists of just a single post (not an array).\n // If so, place the post data in an array.\n if (dataJSON && !Array.isArray(dataJSON) && dataJSON.type === 'post') {\n postsJSONArray = [ dataJSON ];\n }\n // If API data is an array, filter out those matching 'post' type.\n else if (dataJSON && Array.isArray(dataJSON)) {\n postsJSONArray = dataJSON.filter((data) => data.type === 'post');\n }\n else {\n // No posts found\n postsJSONArray = [];\n }\n const collection: PostList = {\n url: _url,\n items: [],\n total: ObjectHelper.getProperty(json, 'meta.pagination.total') || null,\n nextURL: this.parseCollectionNextURL(json, _url)\n };\n\n let hasIncludedJSON = true;\n if (!includedJSON || !Array.isArray(includedJSON)) {\n this.log('warn', `'included' field missing in API response of \"${_url}\" or has incorrect type - no media items and campaign info will be returned`);\n hasIncludedJSON = false;\n }\n\n if (postsJSONArray.length === 0) {\n this.log('warn', `No posts found in API response of \"${_url}\"`);\n return collection;\n }\n if (postsJSONArray.length > 1) {\n this.log('debug', `${postsJSONArray.length} posts found - iterate and parse`);\n }\n else {\n this.log('debug', '1 post found - parse');\n }\n\n let campaign: Campaign | null | undefined;\n\n for (const postJSON of postsJSONArray) {\n if (!postJSON || typeof postJSON !== 'object') {\n this.log('error', 'Parse error: API data of post has incorrect type');\n continue;\n }\n\n const { id, attributes, relationships = {} } = postJSON;\n\n if (!id) {\n this.log('error', 'Parse error: \\'id\\' field missing in API data of post');\n continue;\n }\n\n this.log('debug', `Parse post #${id}`);\n\n if (!attributes || typeof attributes !== 'object') {\n this.log('error', `Parse error: 'attributes' field missing in API data of post #${id} or has incorrect type`);\n continue;\n }\n\n // Campaign info\n if (campaign === undefined) {\n const campaignId = ObjectHelper.getProperty(postJSON, 'relationships.campaign.data.id') || null;\n if (!campaignId || typeof campaignId !== 'string') {\n this.log('warn', `Campaign ID missing in API data of post #${id} or has incorrect type` +\n ' - no campaign info will be available until campaign ID is obtained');\n }\n else if (hasIncludedJSON) {\n campaign = this.findInAPIResponseIncludedArray(includedJSON, campaignId, 'campaign');\n }\n }\n\n // Viewability\n const isViewable = pickDefined(attributes.current_user_can_view, true);\n if (attributes.current_user_can_view === undefined) {\n this.log('warn', `'current_user_can_view' attribute missing in API data of post #${id} - assuming post is viewable`);\n }\n\n // Get downloadables from relationships\n let audio: Downloadable<AudioMediaItem> | null = null;\n let audioPreview: Downloadable<AudioMediaItem> | null = null;\n let images: Downloadable<DefaultImageMediaItem>[] = [];\n let attachments: Downloadable<AttachmentMediaItem>[] = [];\n if (hasIncludedJSON) {\n const downloadables = this.fetchDownloadablesFromRelationships(\n relationships,\n {\n 'audio': 'audio items',\n 'audio_preview': 'audio preview items',\n 'images': 'images',\n 'attachments_media': 'attachments'\n },\n includedJSON,\n `post #${id}`,\n false\n );\n audio = downloadables.audio?.[0] as Downloadable<AudioMediaItem> || null;\n audioPreview = downloadables.audio_preview?.[0] as Downloadable<AudioMediaItem> || null;\n images = downloadables.images as Downloadable<DefaultImageMediaItem>[] || [];\n attachments = downloadables.attachments_media as Downloadable<AttachmentMediaItem>[] || [];\n }\n\n // Get inline media from content (currently only images and linked attachments supported)\n const linkedAttachments: LinkedAttachment[] = [];\n if (hasIncludedJSON && attributes.content) {\n const inlineMedia = this.parseInlineMedia(id, attributes.content, includedJSON);\n images.push(...inlineMedia.images);\n linkedAttachments.push(...inlineMedia.linkedAttachments);\n }\n\n // Video preview\n let videoPreview: Downloadable<VideoMediaItem> | null = null;\n const vidPreviewJSON = attributes.video_preview;\n if (vidPreviewJSON && typeof vidPreviewJSON === 'object') {\n videoPreview = this.#getVideoMediaItemFromAttr(vidPreviewJSON, includedJSON, id);\n if (!videoPreview.downloadURL && !videoPreview.displayURL) {\n this.log('warn', `Video preview for post #${id} is missing URLs`);\n }\n }\n\n // Video - `postType` is 'video_external_file' and has `postFile`\n let video: Downloadable<VideoMediaItem> | null = null;\n const postFileJSON = attributes.post_file;\n const hasPostFile = postFileJSON && typeof postFileJSON === 'object';\n if (attributes.post_type === PostType.Video && hasPostFile) {\n video = this.#getVideoMediaItemFromAttr(postFileJSON, includedJSON, id);\n if (!video.downloadURL && !video.displayURL) {\n this.log('warn', `Video for post #${id} is missing URLs`);\n }\n }\n // Repeat for 'podcast' type - but note that `postFile` here can be audio or video.\n // We are only interested in video. For audio, info should have already been obtained\n // through relationships above.\n if (attributes.post_type === PostType.Podcast && hasPostFile) {\n video = this.#getVideoMediaItemFromAttr(postFileJSON, includedJSON, id, true);\n }\n\n if (attributes.post_type === PostType.Podcast && isViewable && !video && !audio) {\n this.log('warn', `Post #${id} is podcast type and is viewable, but no video or audio was found`);\n }\n\n // Cover image\n let coverImage: PostCoverImageMediaItem | null = null;\n if (attributes.image) {\n coverImage = {\n type: 'image',\n id: `post:${id}:cover`,\n filename: isViewable ? 'cover-image' : 'cover-image-preview',\n mimeType: null,\n imageType: 'postCoverImage',\n imageURLs: {\n large: ObjectHelper.getProperty(attributes, 'image.large_url') || null,\n thumbSquareLarge: ObjectHelper.getProperty(attributes, 'image.thumb_square_large_url') || null,\n thumbSquare: ObjectHelper.getProperty(attributes, 'image.thumb_square_url') || null,\n thumb: ObjectHelper.getProperty(attributes, 'image.thumb_url') || null,\n default: ObjectHelper.getProperty(attributes, 'image.url') || null\n }\n };\n }\n\n // Thumbnail\n let thumbnail: PostThumbnailMediaItem | null = null;\n if (attributes.thumbnail) {\n thumbnail = {\n type: 'image',\n id: `post:${id}:thumbnail`,\n filename: isViewable ? 'thumbnail' : 'thumbnail-preview',\n mimeType: null,\n imageType: 'postThumbnail',\n imageURLs: {\n large: ObjectHelper.getProperty(attributes, 'thumbnail.large') || null,\n large2: ObjectHelper.getProperty(attributes, 'thumbnail.large_2') || null,\n square: ObjectHelper.getProperty(attributes, 'thumbnail.square') || null,\n default: ObjectHelper.getProperty(attributes, 'thumbnail.url') || null\n }\n };\n }\n\n // Audio items doesn't have thumbnail - use first image or thumbnail\n if (audio) {\n audio.thumbnailURL =\n images[0]?.imageURLs.default ||\n thumbnail?.imageURLs.default || null;\n }\n if (audioPreview) {\n audioPreview.thumbnailURL =\n images[0]?.imageURLs.default ||\n thumbnail?.imageURLs.default || null;\n }\n\n // Embed\n const embedJSON = attributes.embed;\n let embed: PostEmbed | null = null;\n if (embedJSON && typeof embedJSON === 'object') {\n let embedType: PostEmbed['type'];\n switch (attributes.post_type) {\n case 'video_embed':\n embedType = 'videoEmbed';\n break;\n case 'link':\n embedType = 'linkEmbed';\n break;\n default:\n embedType = 'unknownEmbed';\n }\n embed = {\n id: `${id}-embed`,\n postId: id,\n postURL: attributes.url || null,\n type: embedType,\n description: embedJSON.descripton || null,\n html: embedJSON.html || null,\n provider: embedJSON.provider || null,\n providerURL: embedJSON.provider_url || null,\n subject: embedJSON.subject || null,\n url: embedJSON.url || null,\n thumbnailURL: ObjectHelper.getProperty(attributes, 'image.large_url') || null // Use cover image\n };\n }\n\n // Tiers\n let tiers: Tier[] = [];\n const tierData = ObjectHelper.getProperty(postJSON, 'relationships.access_rules.data');\n if (Array.isArray(tierData) && campaign) {\n const c = campaign;\n tiers = tierData.reduce<Tier[]>((result, t) => {\n const id = ObjectHelper.getProperty(t, 'id');\n if (id) {\n const tier = this.findInAPIResponseIncludedArray(includedJSON, id, 'tier', c);\n if (tier) {\n result.push(tier);\n }\n }\n return result;\n }, []);\n }\n if (tiers.length === 0) {\n this.log('warn', `Could not obtain tier info for post #${id}`);\n }\n\n // Collections\n let collections: Collection[] = [];\n const collectionsData = ObjectHelper.getProperty(postJSON, 'relationships.collections.data');\n if (Array.isArray(collectionsData)) {\n collections = collectionsData.reduce<Collection[]>((result, c) => {\n const id = ObjectHelper.getProperty(c, 'id');\n if (id) {\n const collection = this.findInAPIResponseIncludedArray(includedJSON, id, 'collection');\n if (collection) {\n result.push(collection);\n }\n }\n return result;\n }, []);\n }\n\n // Tags\n let tags: PostTag[] = [];\n const tagsData = ObjectHelper.getProperty(postJSON, 'relationships.user_defined_tags.data');\n if (Array.isArray(tagsData)) {\n tags = tagsData.reduce<PostTag[]>((result, t) => {\n const id = ObjectHelper.getProperty(t, 'id');\n if (id) {\n const tag = this.findInAPIResponseIncludedArray(includedJSON, id, 'post_tag');\n if (tag) {\n result.push(tag);\n }\n }\n return result;\n }, []);\n }\n\n const post: Post = {\n id,\n type: 'post',\n postType: attributes.post_type || null,\n isViewable,\n url: attributes.url || null,\n title: attributes.title || null,\n content: attributes.content || null,\n contentText: stripHtml(attributes.content || '').result,\n teaserText: attributes.teaser_text || null,\n publishedAt: attributes.published_at || null,\n editedAt: attributes.edited_at || null,\n commentCount: attributes.comment_count || 0,\n coverImage,\n thumbnail,\n tiers,\n collections,\n tags,\n embed,\n attachments,\n linkedAttachments,\n audio,\n audioPreview,\n images,\n videoPreview,\n video,\n campaign: null,\n raw: json\n };\n\n this.log('debug', `Done parsing post #${id}`);\n\n collection.items.push(post);\n }\n\n if (campaign) {\n this.log('debug', `Campaign #${campaign.id} found while parsing posts`);\n for (const post of collection.items) {\n post.campaign = campaign;\n }\n }\n else {\n this.log('warn', 'No campaign info found while parsing posts');\n }\n\n this.log('debug', 'Done parsing posts');\n\n return collection;\n }\n\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict: true): VideoMediaItem | null;\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict?: false): VideoMediaItem;\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict = false) {\n let miFromIncluded: MediaItem | null = null;\n const _mediaId = attrJSON.media_id !== undefined ? attrJSON.media_id.toString() : null;\n const hasIncludedJSON = includedJSON && Array.isArray(includedJSON)\n if (_mediaId && hasIncludedJSON) {\n // Fetch item from 'included' array, matching `media_id`\n miFromIncluded = this.findInAPIResponseIncludedArray(includedJSON, _mediaId, 'media', 'video');\n }\n const vidInc = miFromIncluded && miFromIncluded.type === 'video' ? miFromIncluded : null;\n if (strict && !miFromIncluded) {\n return null;\n }\n const mediaId = _mediaId || postId; // Fallback to post ID\n\n const { download_url: downloadURL = null, url: displayURL = null } = attrJSON;\n\n // Convert `attrJSON` to Downloadable (VideoMediaItem)\n return {\n type: 'video',\n id: mediaId,\n filename: vidInc?.filename || null,\n mimeType: vidInc?.mimeType || null,\n createdAt: vidInc?.createdAt || null,\n size: {\n width: attrJSON.width || vidInc?.size.width,\n height: attrJSON.height || vidInc?.size.height\n },\n duration: attrJSON.duration || vidInc?.duration,\n downloadURL: downloadURL || vidInc?.downloadURL,\n displayURL: displayURL || vidInc?.downloadURL,\n thumbnailURL: vidInc?.thumbnailURL || null\n };\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PostParser.js","sourceRoot":"","sources":["../../src/parsers/PostParser.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripHtml } from 'string-strip-html';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport { type AttachmentMediaItem, type AudioMediaItem, type DefaultImageMediaItem, type MediaItem, type PostCoverImageMediaItem, type PostThumbnailMediaItem, type VideoMediaItem } from '../entities/MediaItem.js';\nimport { type LinkedAttachment, PostType, type Post, type PostList as PostList, type PostEmbed, type Collection, type PostTag } from '../entities/Post.js';\nimport { type Tier } from '../entities/Reward.js';\nimport { pickDefined } from '../utils/Misc.js';\nimport ObjectHelper from '../utils/ObjectHelper.js';\nimport Parser from './Parser.js';\nimport URLHelper from '../utils/URLHelper.js';\n\nexport default class PostParser extends Parser {\n\n protected name = 'PostParser';\n\n parsePostsAPIResponse(json: any, src: string): PostList {\n\n this.log('debug', `Parse API data obtained from \"${src}\"`);\n\n /*If (json.errors) {\n this.log('error', `API response error:`, json.errors);\n return null;\n }*/\n\n const includedJSON = json.included;\n const dataJSON = json.data;\n let postsJSONArray: any[];\n // Check if API data consists of just a single post (not an array).\n // If so, place the post data in an array.\n if (dataJSON && !Array.isArray(dataJSON) && dataJSON.type === 'post') {\n postsJSONArray = [ dataJSON ];\n }\n // If API data is an array, filter out those matching 'post' type.\n else if (dataJSON && Array.isArray(dataJSON)) {\n postsJSONArray = dataJSON.filter((data) => data.type === 'post');\n }\n else {\n // No posts found\n postsJSONArray = [];\n }\n const collection: PostList = {\n items: [],\n total: ObjectHelper.getProperty(json, 'meta.pagination.total') || null,\n // src could be a file, in which case there'll be no nextURL.\n nextURL: URLHelper.validateURL(src) ? this.parseCollectionNextURL(json, src) : null\n };\n\n let hasIncludedJSON = true;\n if (!includedJSON || !Array.isArray(includedJSON)) {\n this.log('warn', `'included' field missing in API data obtained from \"${src}\" or has incorrect type - no media items and campaign info will be returned`);\n hasIncludedJSON = false;\n }\n\n if (postsJSONArray.length === 0) {\n this.log('warn', `No posts found in API data obtained from \"${src}\"`);\n return collection;\n }\n if (postsJSONArray.length > 1) {\n this.log('debug', `${postsJSONArray.length} posts found - iterate and parse`);\n }\n else {\n this.log('debug', '1 post found - parse');\n }\n\n let campaign: Campaign | null | undefined;\n\n for (const postJSON of postsJSONArray) {\n if (!postJSON || typeof postJSON !== 'object') {\n this.log('error', 'Parse error: API data of post has incorrect type');\n continue;\n }\n\n const { id, attributes, relationships = {} } = postJSON;\n\n if (!id) {\n this.log('error', 'Parse error: \\'id\\' field missing in API data of post');\n continue;\n }\n\n this.log('debug', `Parse post #${id}`);\n\n if (!attributes || typeof attributes !== 'object') {\n this.log('error', `Parse error: 'attributes' field missing in API data of post #${id} or has incorrect type`);\n continue;\n }\n\n // Campaign info\n if (campaign === undefined) {\n const campaignId = ObjectHelper.getProperty(postJSON, 'relationships.campaign.data.id') || null;\n if (!campaignId || typeof campaignId !== 'string') {\n this.log('warn', `Campaign ID missing in API data of post #${id} or has incorrect type` +\n ' - no campaign info will be available until campaign ID is obtained');\n }\n else if (hasIncludedJSON) {\n campaign = this.findInAPIResponseIncludedArray(includedJSON, campaignId, 'campaign');\n }\n }\n\n // Viewability\n const isViewable = pickDefined(attributes.current_user_can_view, true);\n if (attributes.current_user_can_view === undefined) {\n this.log('warn', `'current_user_can_view' attribute missing in API data of post #${id} - assuming post is viewable`);\n }\n\n // Get downloadables from relationships\n let audio: Downloadable<AudioMediaItem> | null = null;\n let audioPreview: Downloadable<AudioMediaItem> | null = null;\n let images: Downloadable<DefaultImageMediaItem>[] = [];\n let attachments: Downloadable<AttachmentMediaItem>[] = [];\n if (hasIncludedJSON) {\n const downloadables = this.fetchDownloadablesFromRelationships(\n relationships,\n {\n 'audio': 'audio items',\n 'audio_preview': 'audio preview items',\n 'images': 'images',\n 'attachments_media': 'attachments'\n },\n includedJSON,\n `post #${id}`,\n false\n );\n audio = downloadables.audio?.[0] as Downloadable<AudioMediaItem> || null;\n audioPreview = downloadables.audio_preview?.[0] as Downloadable<AudioMediaItem> || null;\n images = downloadables.images as Downloadable<DefaultImageMediaItem>[] || [];\n attachments = downloadables.attachments_media as Downloadable<AttachmentMediaItem>[] || [];\n }\n\n // Post content and teaser\n const content = this.#parseContent(attributes);\n const teaserText = this.#parseContent({\n content: attributes.teaser_text,\n content_json_string: attributes.teaser_text_json_string\n });\n\n // Get inline media from content (currently only images and linked attachments supported)\n const linkedAttachments: LinkedAttachment[] = [];\n const inlineMediaBody = content || teaserText;\n if (hasIncludedJSON && inlineMediaBody) {\n const inlineMedia = this.parseInlineMedia(id, inlineMediaBody, includedJSON);\n images.push(...inlineMedia.images);\n linkedAttachments.push(...inlineMedia.linkedAttachments);\n }\n\n // Video preview\n let videoPreview: Downloadable<VideoMediaItem> | null = null;\n const vidPreviewJSON = attributes.video_preview;\n if (vidPreviewJSON && typeof vidPreviewJSON === 'object') {\n videoPreview = this.#getVideoMediaItemFromAttr(vidPreviewJSON, includedJSON, id);\n if (!videoPreview.downloadURL && !videoPreview.displayURL) {\n this.log('warn', `Video preview for post #${id} is missing URLs`);\n }\n }\n\n // Video - `postType` is 'video_external_file' and has `postFile`\n let video: Downloadable<VideoMediaItem> | null = null;\n const postFileJSON = attributes.post_file;\n const hasPostFile = postFileJSON && typeof postFileJSON === 'object';\n if (attributes.post_type === PostType.Video && hasPostFile) {\n video = this.#getVideoMediaItemFromAttr(postFileJSON, includedJSON, id);\n if (!video.downloadURL && !video.displayURL) {\n this.log('warn', `Video for post #${id} is missing URLs`);\n }\n }\n // Repeat for 'podcast' type - but note that `postFile` here can be audio or video.\n // We are only interested in video. For audio, info should have already been obtained\n // through relationships above.\n if (attributes.post_type === PostType.Podcast && hasPostFile) {\n video = this.#getVideoMediaItemFromAttr(postFileJSON, includedJSON, id, true);\n }\n\n if (attributes.post_type === PostType.Podcast && isViewable && !video && !audio) {\n this.log('warn', `Post #${id} is podcast type and is viewable, but no video or audio was found`);\n }\n\n // Cover image\n let coverImage: PostCoverImageMediaItem | null = null;\n if (attributes.image) {\n coverImage = {\n type: 'image',\n id: `post:${id}:cover`,\n filename: isViewable ? 'cover-image' : 'cover-image-preview',\n mimeType: null,\n imageType: 'postCoverImage',\n imageURLs: {\n large: ObjectHelper.getProperty(attributes, 'image.large_url') || null,\n thumbSquareLarge: ObjectHelper.getProperty(attributes, 'image.thumb_square_large_url') || null,\n thumbSquare: ObjectHelper.getProperty(attributes, 'image.thumb_square_url') || null,\n thumb: ObjectHelper.getProperty(attributes, 'image.thumb_url') || null,\n default: ObjectHelper.getProperty(attributes, 'image.url') || null\n }\n };\n }\n\n // Thumbnail\n let thumbnail: PostThumbnailMediaItem | null = null;\n if (attributes.thumbnail) {\n thumbnail = {\n type: 'image',\n id: `post:${id}:thumbnail`,\n filename: isViewable ? 'thumbnail' : 'thumbnail-preview',\n mimeType: null,\n imageType: 'postThumbnail',\n imageURLs: {\n large: ObjectHelper.getProperty(attributes, 'thumbnail.large') || null,\n large2: ObjectHelper.getProperty(attributes, 'thumbnail.large_2') || null,\n square: ObjectHelper.getProperty(attributes, 'thumbnail.square') || null,\n default: ObjectHelper.getProperty(attributes, 'thumbnail.url') || null\n }\n };\n }\n\n // Audio items doesn't have thumbnail - use first image or thumbnail\n if (audio) {\n audio.thumbnailURL =\n images[0]?.imageURLs.default ||\n thumbnail?.imageURLs.default || null;\n }\n if (audioPreview) {\n audioPreview.thumbnailURL =\n images[0]?.imageURLs.default ||\n thumbnail?.imageURLs.default || null;\n }\n\n // Embed\n const embedJSON = attributes.embed;\n let embed: PostEmbed | null = null;\n if (embedJSON && typeof embedJSON === 'object') {\n let embedType: PostEmbed['type'];\n switch (attributes.post_type) {\n case 'video_embed':\n embedType = 'videoEmbed';\n break;\n case 'link':\n embedType = 'linkEmbed';\n break;\n default:\n embedType = 'unknownEmbed';\n }\n embed = {\n id: `${id}-embed`,\n postId: id,\n postURL: attributes.url || null,\n type: embedType,\n description: embedJSON.descripton || null,\n html: embedJSON.html || null,\n provider: embedJSON.provider || null,\n providerURL: embedJSON.provider_url || null,\n subject: embedJSON.subject || null,\n url: embedJSON.url || null,\n thumbnailURL: ObjectHelper.getProperty(attributes, 'image.large_url') || null // Use cover image\n };\n }\n\n // Tiers\n let tiers: Tier[] = [];\n const tierData = ObjectHelper.getProperty(postJSON, 'relationships.access_rules.data');\n if (Array.isArray(tierData) && campaign) {\n const c = campaign;\n tiers = tierData.reduce<Tier[]>((result, t) => {\n const id = ObjectHelper.getProperty(t, 'id');\n if (id) {\n const tier = this.findInAPIResponseIncludedArray(includedJSON, id, 'tier', c);\n if (tier) {\n result.push(tier);\n }\n }\n return result;\n }, []);\n }\n if (tiers.length === 0) {\n this.log('warn', `Could not obtain tier info for post #${id}`);\n }\n\n // Collections\n let collections: Collection[] = [];\n const collectionsData = ObjectHelper.getProperty(postJSON, 'relationships.collections.data');\n if (Array.isArray(collectionsData)) {\n collections = collectionsData.reduce<Collection[]>((result, c) => {\n const id = ObjectHelper.getProperty(c, 'id');\n if (id) {\n const collection = this.findInAPIResponseIncludedArray(includedJSON, id, 'collection');\n if (collection) {\n result.push(collection);\n }\n }\n return result;\n }, []);\n }\n\n // Tags\n let tags: PostTag[] = [];\n const tagsData = ObjectHelper.getProperty(postJSON, 'relationships.user_defined_tags.data');\n if (Array.isArray(tagsData)) {\n tags = tagsData.reduce<PostTag[]>((result, t) => {\n const id = ObjectHelper.getProperty(t, 'id');\n if (id) {\n const tag = this.findInAPIResponseIncludedArray(includedJSON, id, 'post_tag');\n if (tag) {\n result.push(tag);\n }\n }\n return result;\n }, []);\n }\n\n const post: Post = {\n id,\n type: 'post',\n postType: attributes.post_type || null,\n isViewable,\n url: attributes.url || null,\n title: attributes.title || null,\n content,\n contentText: stripHtml(content || '').result,\n teaserText,\n publishedAt: attributes.published_at || null,\n editedAt: attributes.edited_at || null,\n commentCount: attributes.comment_count || 0,\n coverImage,\n thumbnail,\n tiers,\n collections,\n tags,\n embed,\n attachments,\n linkedAttachments,\n audio,\n audioPreview,\n images,\n videoPreview,\n video,\n campaign: null,\n raw: json\n };\n\n this.log('debug', `Done parsing post #${id}`);\n\n collection.items.push(post);\n }\n\n if (campaign) {\n this.log('debug', `Campaign #${campaign.id} found while parsing posts`);\n for (const post of collection.items) {\n post.campaign = campaign;\n }\n }\n else {\n this.log('warn', 'No campaign info found while parsing posts');\n }\n\n this.log('debug', 'Done parsing posts');\n\n return collection;\n }\n\n /**\n * Returns `content` if value is not empty.\n * Otherwise, returns HTML assembled from `content_json_string`.\n * \n * Contributed by: Fabelwesen (https://github.com/Fabelwesen)\n * Origin: https://github.com/patrickkfkan/patreon-dl/issues/119\n * \n * @param data \n * @returns HTML or null\n */\n #parseContent(data: { content?: string | null; content_json_string?: string | null }) {\n const { content, content_json_string } = data;\n if (typeof content === 'string' && content.trim()) {\n return content;\n }\n if (!content_json_string) {\n return null;\n }\n try {\n const doc = JSON.parse(content_json_string);\n let parsedHTML = '';\n\n function extractHTML(node: any) {\n if (!node) return;\n\n if (node.type === 'text') {\n if (node.marks && node.marks.find((m: any) => m.type === 'link')) {\n const linkMark = node.marks.find((m: any) => m.type === 'link');\n parsedHTML += `<a href=\"${linkMark.attrs.href}\" target=\"_blank\">${node.text || ''}</a>`;\n } else {\n // You can expand this to handle bold, italic, etc.\n parsedHTML += (String(node.text) || '');\n }\n } else if (node.type === 'paragraph' || node.type === 'heading' || node.type === 'listItem') {\n parsedHTML += '<p>';\n if (node.content && Array.isArray(node.content)) {\n node.content.forEach(extractHTML);\n }\n parsedHTML += '</p>';\n } else if (node.type === 'image') {\n // Ensure media_id is passed so the local web server can link downloaded assets\n const mediaIdAttr = (node.attrs && node.attrs.media_id) ? `data-media-id=\"${node.attrs.media_id}\" ` : '';\n const srcAttr = (node.attrs && node.attrs.src) ? node.attrs.src : '';\n parsedHTML += `<img ${mediaIdAttr}src=\"${srcAttr}\" />`;\n } else if (node.content && Array.isArray(node.content)) {\n node.content.forEach(extractHTML);\n }\n }\n\n extractHTML(doc);\n return parsedHTML;\n } catch (e) {\n this.log('warn', 'Failed to parse content_json_string:', e);\n }\n return null;\n }\n\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict: true): VideoMediaItem | null;\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict?: false): VideoMediaItem;\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict = false) {\n let miFromIncluded: MediaItem | null = null;\n const _mediaId = attrJSON.media_id !== undefined ? attrJSON.media_id.toString() : null;\n const hasIncludedJSON = includedJSON && Array.isArray(includedJSON)\n if (_mediaId && hasIncludedJSON) {\n // Fetch item from 'included' array, matching `media_id`\n miFromIncluded = this.findInAPIResponseIncludedArray(includedJSON, _mediaId, 'media', 'video');\n }\n const vidInc = miFromIncluded && miFromIncluded.type === 'video' ? miFromIncluded : null;\n if (strict && !miFromIncluded) {\n return null;\n }\n const mediaId = _mediaId || postId; // Fallback to post ID\n\n const { download_url: downloadURL = null, url: displayURL = null } = attrJSON;\n\n // Convert `attrJSON` to Downloadable (VideoMediaItem)\n return {\n type: 'video',\n id: mediaId,\n filename: vidInc?.filename || null,\n mimeType: vidInc?.mimeType || null,\n createdAt: vidInc?.createdAt || null,\n size: {\n width: attrJSON.width || vidInc?.size.width,\n height: attrJSON.height || vidInc?.size.height\n },\n duration: attrJSON.duration || vidInc?.duration,\n downloadURL: downloadURL || vidInc?.downloadURL,\n displayURL: displayURL || vidInc?.downloadURL,\n thumbnailURL: vidInc?.thumbnailURL || null\n };\n };\n}\n"]}
|
|
@@ -3,5 +3,5 @@ import { type ProductList } from '../entities/Product.js';
|
|
|
3
3
|
import Parser from './Parser.js';
|
|
4
4
|
export default class ProductParser extends Parser {
|
|
5
5
|
protected name: string;
|
|
6
|
-
parseProductsAPIResponse(json: any,
|
|
6
|
+
parseProductsAPIResponse(json: any, src: string, _campaign?: Campaign | null): ProductList;
|
|
7
7
|
}
|
|
@@ -6,8 +6,8 @@ export default class ProductParser extends Parser {
|
|
|
6
6
|
super(...arguments);
|
|
7
7
|
this.name = 'ProductParser';
|
|
8
8
|
}
|
|
9
|
-
parseProductsAPIResponse(json,
|
|
10
|
-
this.log('debug', `Parse API
|
|
9
|
+
parseProductsAPIResponse(json, src, _campaign) {
|
|
10
|
+
this.log('debug', `Parse API data obtained from "${src}"`);
|
|
11
11
|
/*If (json.errors) {
|
|
12
12
|
this.log('error', `API response error:`, json.errors);
|
|
13
13
|
return null;
|
|
@@ -29,18 +29,17 @@ export default class ProductParser extends Parser {
|
|
|
29
29
|
productsJSONArray = [];
|
|
30
30
|
}
|
|
31
31
|
const collection = {
|
|
32
|
-
url: _url,
|
|
33
32
|
items: [],
|
|
34
33
|
total: ObjectHelper.getProperty(json, 'meta.count') || null,
|
|
35
34
|
nextURL: ObjectHelper.getProperty(json, 'links.next') || null
|
|
36
35
|
};
|
|
37
36
|
let hasIncludedJSON = true;
|
|
38
37
|
if (!includedJSON || !Array.isArray(includedJSON)) {
|
|
39
|
-
this.log('warn', `'included' field missing in API
|
|
38
|
+
this.log('warn', `'included' field missing in API data obtained from "${src}" or has incorrect type - no media items and campaign info will be returned`);
|
|
40
39
|
hasIncludedJSON = false;
|
|
41
40
|
}
|
|
42
41
|
if (productsJSONArray.length === 0) {
|
|
43
|
-
this.log('warn', `No products found in API
|
|
42
|
+
this.log('warn', `No products found in API data obtained from "${src}"`);
|
|
44
43
|
return collection;
|
|
45
44
|
}
|
|
46
45
|
if (productsJSONArray.length > 1) {
|
|
@@ -96,7 +95,7 @@ export default class ProductParser extends Parser {
|
|
|
96
95
|
previewMedia = [];
|
|
97
96
|
contentMedia = [];
|
|
98
97
|
}
|
|
99
|
-
const { name = null, description = null, published_at_datetime: publishedAt = null, url =
|
|
98
|
+
const { name = null, description = null, published_at_datetime: publishedAt = null, url = src } = attributes;
|
|
100
99
|
let price = null;
|
|
101
100
|
if (attributes.price_cents !== undefined && !isNaN(Number(attributes.price_cents))) {
|
|
102
101
|
const currency = campaign?.currency ? ` ${campaign?.currency}` : '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductParser.js","sourceRoot":"","sources":["../../src/parsers/ProductParser.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripHtml } from 'string-strip-html';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport { type ProductList } from '../entities/Product.js';\nimport ObjectHelper from '../utils/ObjectHelper.js';\nimport Parser from './Parser.js';\n\nexport default class ProductParser extends Parser {\n\n protected name = 'ProductParser';\n\n parseProductsAPIResponse(json: any, _url: string, _campaign?: Campaign | null): ProductList {\n\n this.log('debug', `Parse API response of \"${_url}\"`);\n\n /*If (json.errors) {\n this.log('error', `API response error:`, json.errors);\n return null;\n }*/\n\n const includedJSON = json.included;\n const dataJSON = json.data;\n let productsJSONArray: any[];\n // Check if API data consists of just a single product (not an array).\n // If so, place the product data in an array.\n if (dataJSON && !Array.isArray(dataJSON) && dataJSON.type === 'product-variant') {\n productsJSONArray = [dataJSON];\n }\n // If API data is an array, filter out those matching 'product-variant' type (they should all be).\n else if (dataJSON && Array.isArray(dataJSON)) {\n productsJSONArray = dataJSON.filter((data) => data.type === 'product-variant');\n }\n else {\n // No products found\n productsJSONArray = [];\n }\n const collection: ProductList = {\n url: _url,\n items: [],\n total: ObjectHelper.getProperty(json, 'meta.count') || null,\n nextURL: ObjectHelper.getProperty(json, 'links.next') || null\n };\n\n let hasIncludedJSON = true;\n if (!includedJSON || !Array.isArray(includedJSON)) {\n this.log('warn', `'included' field missing in API response of \"${_url}\" or has incorrect type - no media items and campaign info will be returned`);\n hasIncludedJSON = false;\n }\n\n if (productsJSONArray.length === 0) {\n this.log('warn', `No products found in API response of \"${_url}\"`);\n return collection;\n }\n if (productsJSONArray.length > 1) {\n this.log('debug', `${productsJSONArray.length} products found - iterate and parse`);\n }\n else {\n this.log('debug', '1 product found - parse');\n }\n\n let campaign: Campaign | null | undefined = _campaign;\n\n for (const productJSON of productsJSONArray) {\n if (!productJSON || typeof productJSON !== 'object') {\n this.log('error', 'Parse error: API data of product has incorrect type');\n continue;\n }\n\n const { id, attributes, relationships = {} } = productJSON;\n\n if (!id) {\n this.log('error', 'Parse error: \\'id\\' field missing in API data of product');\n continue;\n }\n\n this.log('debug', `Parse product #${id}`);\n\n if (!attributes || typeof attributes !== 'object') {\n this.log('error', `Parse error: 'attributes' field missing in API data of product #${id} or has incorrect type`);\n continue;\n }\n\n // Campaign info\n if (campaign === undefined) {\n const campaignId = ObjectHelper.getProperty(productJSON, 'relationships.campaign.data.id') || null;\n if (!campaignId || typeof campaignId !== 'string') {\n this.log('warn', `Campaign ID missing in API data of product #${id} or has incorrect type` +\n ' - no campaign info will be available until campaign ID is obtained');\n }\n else if (hasIncludedJSON) {\n campaign = this.findInAPIResponseIncludedArray(includedJSON, campaignId, 'campaign');\n }\n }\n\n // Is accessible?\n let isAccessible = false;\n const accessMetadata = attributes.access_metadata;\n if (accessMetadata && Array.isArray(accessMetadata)) {\n isAccessible = accessMetadata.some((acc) => acc.access_created_at);\n }\n\n let previewMedia: Downloadable[];\n let contentMedia: Downloadable[];\n if (hasIncludedJSON) {\n const downloadables = this.fetchDownloadablesFromRelationships(\n relationships,\n {\n 'preview_media': 'preview media',\n 'content_media': 'content media'\n },\n includedJSON,\n `product #${id}`,\n isAccessible\n );\n previewMedia = downloadables['preview_media'] || [];\n contentMedia = downloadables['content_media'] || [];\n }\n else {\n previewMedia = [];\n contentMedia = [];\n }\n\n const {\n name = null,\n description = null,\n published_at_datetime: publishedAt = null,\n url = _url\n } = attributes;\n\n let price: string | null = null;\n if (attributes.price_cents !== undefined && !isNaN(Number(attributes.price_cents))) {\n const currency = campaign?.currency ? ` ${campaign?.currency}` : '';\n price = `${Number(attributes.price_cents) / 100}${currency}`;\n }\n\n this.log('debug', `Done parsing product #${id}`);\n\n collection.items.push({\n id,\n type: 'product',\n productType: ObjectHelper.getProperty(attributes, 'content_type'),\n isAccessible,\n name,\n description,\n descriptionText: stripHtml(description || '').result,\n price,\n publishedAt,\n url,\n campaign: null,\n previewMedia,\n contentMedia,\n raw: json\n });\n }\n\n if (campaign) {\n this.log('debug', `Campaign #${campaign.id} found while parsing products`);\n for (const product of collection.items) {\n product.campaign = campaign;\n }\n }\n else {\n this.log('warn', 'No campaign info found while parsing products');\n }\n\n this.log('debug', 'Done parsing products');\n\n return collection;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ProductParser.js","sourceRoot":"","sources":["../../src/parsers/ProductParser.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripHtml } from 'string-strip-html';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport { type ProductList } from '../entities/Product.js';\nimport ObjectHelper from '../utils/ObjectHelper.js';\nimport Parser from './Parser.js';\n\nexport default class ProductParser extends Parser {\n\n protected name = 'ProductParser';\n\n parseProductsAPIResponse(json: any, src: string, _campaign?: Campaign | null): ProductList {\n\n this.log('debug', `Parse API data obtained from \"${src}\"`);\n\n /*If (json.errors) {\n this.log('error', `API response error:`, json.errors);\n return null;\n }*/\n\n const includedJSON = json.included;\n const dataJSON = json.data;\n let productsJSONArray: any[];\n // Check if API data consists of just a single product (not an array).\n // If so, place the product data in an array.\n if (dataJSON && !Array.isArray(dataJSON) && dataJSON.type === 'product-variant') {\n productsJSONArray = [dataJSON];\n }\n // If API data is an array, filter out those matching 'product-variant' type (they should all be).\n else if (dataJSON && Array.isArray(dataJSON)) {\n productsJSONArray = dataJSON.filter((data) => data.type === 'product-variant');\n }\n else {\n // No products found\n productsJSONArray = [];\n }\n const collection: ProductList = {\n items: [],\n total: ObjectHelper.getProperty(json, 'meta.count') || null,\n nextURL: ObjectHelper.getProperty(json, 'links.next') || null\n };\n\n let hasIncludedJSON = true;\n if (!includedJSON || !Array.isArray(includedJSON)) {\n this.log('warn', `'included' field missing in API data obtained from \"${src}\" or has incorrect type - no media items and campaign info will be returned`);\n hasIncludedJSON = false;\n }\n\n if (productsJSONArray.length === 0) {\n this.log('warn', `No products found in API data obtained from \"${src}\"`);\n return collection;\n }\n if (productsJSONArray.length > 1) {\n this.log('debug', `${productsJSONArray.length} products found - iterate and parse`);\n }\n else {\n this.log('debug', '1 product found - parse');\n }\n\n let campaign: Campaign | null | undefined = _campaign;\n\n for (const productJSON of productsJSONArray) {\n if (!productJSON || typeof productJSON !== 'object') {\n this.log('error', 'Parse error: API data of product has incorrect type');\n continue;\n }\n\n const { id, attributes, relationships = {} } = productJSON;\n\n if (!id) {\n this.log('error', 'Parse error: \\'id\\' field missing in API data of product');\n continue;\n }\n\n this.log('debug', `Parse product #${id}`);\n\n if (!attributes || typeof attributes !== 'object') {\n this.log('error', `Parse error: 'attributes' field missing in API data of product #${id} or has incorrect type`);\n continue;\n }\n\n // Campaign info\n if (campaign === undefined) {\n const campaignId = ObjectHelper.getProperty(productJSON, 'relationships.campaign.data.id') || null;\n if (!campaignId || typeof campaignId !== 'string') {\n this.log('warn', `Campaign ID missing in API data of product #${id} or has incorrect type` +\n ' - no campaign info will be available until campaign ID is obtained');\n }\n else if (hasIncludedJSON) {\n campaign = this.findInAPIResponseIncludedArray(includedJSON, campaignId, 'campaign');\n }\n }\n\n // Is accessible?\n let isAccessible = false;\n const accessMetadata = attributes.access_metadata;\n if (accessMetadata && Array.isArray(accessMetadata)) {\n isAccessible = accessMetadata.some((acc) => acc.access_created_at);\n }\n\n let previewMedia: Downloadable[];\n let contentMedia: Downloadable[];\n if (hasIncludedJSON) {\n const downloadables = this.fetchDownloadablesFromRelationships(\n relationships,\n {\n 'preview_media': 'preview media',\n 'content_media': 'content media'\n },\n includedJSON,\n `product #${id}`,\n isAccessible\n );\n previewMedia = downloadables['preview_media'] || [];\n contentMedia = downloadables['content_media'] || [];\n }\n else {\n previewMedia = [];\n contentMedia = [];\n }\n\n const {\n name = null,\n description = null,\n published_at_datetime: publishedAt = null,\n url = src\n } = attributes;\n\n let price: string | null = null;\n if (attributes.price_cents !== undefined && !isNaN(Number(attributes.price_cents))) {\n const currency = campaign?.currency ? ` ${campaign?.currency}` : '';\n price = `${Number(attributes.price_cents) / 100}${currency}`;\n }\n\n this.log('debug', `Done parsing product #${id}`);\n\n collection.items.push({\n id,\n type: 'product',\n productType: ObjectHelper.getProperty(attributes, 'content_type'),\n isAccessible,\n name,\n description,\n descriptionText: stripHtml(description || '').result,\n price,\n publishedAt,\n url,\n campaign: null,\n previewMedia,\n contentMedia,\n raw: json\n });\n }\n\n if (campaign) {\n this.log('debug', `Campaign #${campaign.id} found while parsing products`);\n for (const product of collection.items) {\n product.campaign = campaign;\n }\n }\n else {\n this.log('warn', 'No campaign info found while parsing products');\n }\n\n this.log('debug', 'Done parsing products');\n\n return collection;\n }\n}\n"]}
|
|
@@ -7,7 +7,7 @@ type CampaignDirNameFormatFieldName = 'creator.vanity' | 'creator.name' | 'creat
|
|
|
7
7
|
export declare const CAMPAIGN_DIR_NAME_VALIDATION_SCHEMA: FormatFieldRules<CampaignDirNameFormatFieldName>;
|
|
8
8
|
type ContentDirNameFormatFieldName = 'content.id' | 'content.type' | 'content.slug' | 'content.name' | 'content.publishDate';
|
|
9
9
|
export declare const CONTENT_DIR_NAME_VALIDATION_SCHEMA: FormatFieldRules<ContentDirNameFormatFieldName>;
|
|
10
|
-
type MediaFilenameFormatFieldName = 'media.id' | 'media.type' | 'media.filename' | 'media.variant';
|
|
10
|
+
type MediaFilenameFormatFieldName = 'media.id' | 'media.type' | 'media.filename' | 'media.variant' | 'src.id' | 'src.type' | 'src.title' | 'src.date';
|
|
11
11
|
export declare const MEDIA_FILENAME_VALIDATION_SCHEMA: FormatFieldRules<MediaFilenameFormatFieldName>;
|
|
12
12
|
export default class FilenameFormatHelper {
|
|
13
13
|
#private;
|
|
@@ -16,7 +16,7 @@ export default class FilenameFormatHelper {
|
|
|
16
16
|
static getCollectionDirName(collection: Collection, format: string): string;
|
|
17
17
|
static getMediaFilename(media: MediaLike & {
|
|
18
18
|
variant: string | null;
|
|
19
|
-
}, format: string, ext: string): string;
|
|
19
|
+
}, src: Post | Product | Campaign | Collection, format: string, ext: string): string;
|
|
20
20
|
static validateCampaignDirNameFormat(format: string): {
|
|
21
21
|
validateOK: boolean;
|
|
22
22
|
regex?: undefined;
|
|
@@ -4,6 +4,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
6
|
var _a, _FilenameFormatHelper_getFilename;
|
|
7
|
+
import dateFormat from 'dateformat';
|
|
7
8
|
import Formatter from './Formatter.js';
|
|
8
9
|
import URLHelper from './URLHelper.js';
|
|
9
10
|
import { createSafeSlug, toISODate } from './Misc.js';
|
|
@@ -75,12 +76,54 @@ class FilenameFormatHelper {
|
|
|
75
76
|
};
|
|
76
77
|
return __classPrivateFieldGet(this, _a, "m", _FilenameFormatHelper_getFilename).call(this, format, dict, CONTENT_DIR_NAME_VALIDATION_SCHEMA, CONTENT_DIR_NAME_FALLBACK_FORMAT);
|
|
77
78
|
}
|
|
78
|
-
static getMediaFilename(media, format, ext) {
|
|
79
|
+
static getMediaFilename(media, src, format, ext) {
|
|
80
|
+
let srcFields;
|
|
81
|
+
switch (src.type) {
|
|
82
|
+
case 'post':
|
|
83
|
+
srcFields = {
|
|
84
|
+
'src.id': src.id,
|
|
85
|
+
'src.type': src.type,
|
|
86
|
+
'src.date': src.publishedAt,
|
|
87
|
+
'src.title': src.title
|
|
88
|
+
};
|
|
89
|
+
break;
|
|
90
|
+
case 'product':
|
|
91
|
+
srcFields = {
|
|
92
|
+
'src.id': src.id,
|
|
93
|
+
'src.type': src.type,
|
|
94
|
+
'src.date': src.publishedAt,
|
|
95
|
+
'src.title': src.name
|
|
96
|
+
};
|
|
97
|
+
break;
|
|
98
|
+
case 'campaign':
|
|
99
|
+
srcFields = {
|
|
100
|
+
'src.id': src.id,
|
|
101
|
+
'src.type': src.type,
|
|
102
|
+
'src.date': src.createdAt,
|
|
103
|
+
'src.title': src.name
|
|
104
|
+
};
|
|
105
|
+
break;
|
|
106
|
+
case 'collection':
|
|
107
|
+
srcFields = {
|
|
108
|
+
'src.id': src.id,
|
|
109
|
+
'src.type': src.type,
|
|
110
|
+
'src.date': src.createdAt,
|
|
111
|
+
'src.title': src.title
|
|
112
|
+
};
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
srcFields['src.date'] = dateFormat(new Date(srcFields['src.date']), 'yyyy-mm-dd_HH-MM');
|
|
117
|
+
}
|
|
118
|
+
catch (_) {
|
|
119
|
+
// Do nothing
|
|
120
|
+
}
|
|
79
121
|
const dict = {
|
|
80
122
|
'media.id': media.id,
|
|
81
123
|
'media.type': media.type,
|
|
82
124
|
'media.filename': media.filename,
|
|
83
|
-
'media.variant': media.variant
|
|
125
|
+
'media.variant': media.variant,
|
|
126
|
+
...srcFields
|
|
84
127
|
};
|
|
85
128
|
return __classPrivateFieldGet(this, _a, "m", _FilenameFormatHelper_getFilename).call(this, format, dict, MEDIA_FILENAME_VALIDATION_SCHEMA, MEDIA_FILENAME_FALLBACK_FORMAT, ext);
|
|
86
129
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilenameFormatHelper.js","sourceRoot":"","sources":["../../src/utils/FilenameFormatHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Campaign } from '../entities/Campaign.js';\nimport { type MediaLike } from '../entities/MediaItem.js';\nimport { type Product } from '../entities/Product.js';\nimport Formatter, { type FormatFieldName, type FormatFieldRules, type FormatFieldValues } from './Formatter.js';\nimport URLHelper from './URLHelper.js';\nimport { type Collection, type Post } from '../entities/Post.js';\nimport { createSafeSlug, toISODate } from './Misc.js';\nimport FSHelper from './FSHelper.js';\n\ntype CampaignDirNameFormatFieldName =\n 'creator.vanity' |\n 'creator.name' |\n 'creator.id' |\n 'campaign.name' |\n 'campaign.id';\n\nexport const CAMPAIGN_DIR_NAME_VALIDATION_SCHEMA: FormatFieldRules<CampaignDirNameFormatFieldName> = [\n { name: 'creator.vanity', atLeastOneOf: true },\n { name: 'creator.name', atLeastOneOf: true },\n { name: 'creator.id', atLeastOneOf: true },\n { name: 'campaign.name', atLeastOneOf: true },\n { name: 'campaign.id', atLeastOneOf: true }\n];\n\ntype ContentDirNameFormatFieldName =\n 'content.id' |\n 'content.type' |\n 'content.slug' |\n 'content.name' |\n 'content.publishDate';\n\nexport const CONTENT_DIR_NAME_VALIDATION_SCHEMA: FormatFieldRules<ContentDirNameFormatFieldName> = [\n { name: 'content.id', atLeastOneOf: true },\n { name: 'content.type', atLeastOneOf: false },\n { name: 'content.slug', atLeastOneOf: true },\n { name: 'content.name', atLeastOneOf: false },\n { name: 'content.publishDate', atLeastOneOf: false }\n];\n\ntype MediaFilenameFormatFieldName =\n 'media.id' |\n 'media.type' |\n 'media.filename' |\n 'media.variant';\n\nexport const MEDIA_FILENAME_VALIDATION_SCHEMA: FormatFieldRules<MediaFilenameFormatFieldName> = [\n { name: 'media.id', atLeastOneOf: true },\n { name: 'media.type', atLeastOneOf: false },\n { name: 'media.filename', atLeastOneOf: true },\n { name: 'media.variant', atLeastOneOf: false }\n];\n\nconst CAMPAIGN_DIR_NAME_FALLBACK_FORMAT = 'campaign-{campaign.id}';\nconst CONTENT_DIR_NAME_FALLBACK_FORMAT = '{content.type}-{content.id}';\nconst MEDIA_FILENAME_FALLBACK_FORMAT = '{media.type}-{media.id}';\n\nexport default class FilenameFormatHelper {\n\n static getCampaignDirName(campaign: Campaign, format: string): string {\n const dict: FormatFieldValues<CampaignDirNameFormatFieldName> = {\n 'creator.vanity': campaign.creator?.vanity,\n 'creator.name': campaign.creator?.fullName,\n 'creator.id': campaign.creator?.id,\n 'campaign.name': campaign.name,\n 'campaign.id': campaign.id\n };\n\n return this.#getFilename(format, dict, CAMPAIGN_DIR_NAME_VALIDATION_SCHEMA, CAMPAIGN_DIR_NAME_FALLBACK_FORMAT);\n }\n\n static getContentDirName(content: Product | Post, format: string): string {\n const dict: FormatFieldValues<ContentDirNameFormatFieldName> = {\n 'content.id': content.id,\n 'content.type': content.type,\n 'content.slug': null,\n 'content.name': null,\n 'content.publishDate': content.publishedAt ? toISODate(content.publishedAt) : null\n };\n if (content.type === 'post') {\n const urlAnalysis = content.url ? URLHelper.analyzeURL(content.url) : null;\n dict['content.slug'] = urlAnalysis && urlAnalysis.type === 'post' ? urlAnalysis.slug : null;\n dict['content.name'] = content.title;\n }\n else if (content.type === 'product') {\n const urlAnalysis = URLHelper.analyzeURL(content.url);\n dict['content.slug'] = urlAnalysis && urlAnalysis.type === 'product' ? urlAnalysis.slug : null;\n dict['content.name'] = content.name;\n }\n\n return this.#getFilename(format, dict, CONTENT_DIR_NAME_VALIDATION_SCHEMA, CONTENT_DIR_NAME_FALLBACK_FORMAT);\n }\n\n static getCollectionDirName(collection: Collection, format: string): string {\n const slug = collection.title ?\n `${createSafeSlug(collection.title)}-${collection.id}`\n : `collection-${collection.id}`;\n const dict: FormatFieldValues<ContentDirNameFormatFieldName> = {\n 'content.id': collection.id,\n 'content.type': collection.type,\n 'content.slug': slug,\n 'content.name': collection.title,\n 'content.publishDate': collection.createdAt ? toISODate(collection.createdAt) : null\n };\n return this.#getFilename(format, dict, CONTENT_DIR_NAME_VALIDATION_SCHEMA, CONTENT_DIR_NAME_FALLBACK_FORMAT);\n }\n\n static getMediaFilename(media: MediaLike & { variant: string | null }, format: string, ext: string): string {\n const dict: FormatFieldValues<MediaFilenameFormatFieldName> = {\n 'media.id': media.id,\n 'media.type': media.type,\n 'media.filename': media.filename,\n 'media.variant': media.variant\n };\n\n return this.#getFilename(format, dict, MEDIA_FILENAME_VALIDATION_SCHEMA, MEDIA_FILENAME_FALLBACK_FORMAT, ext);\n }\n\n static #getFilename<T extends FormatFieldName>(\n format: string,\n dict: FormatFieldValues<T>,\n rules: FormatFieldRules<T>,\n fallbackFormat: string,\n ext?: string\n ) {\n const { validateOK, result } = Formatter.format(format, dict, rules);\n let base = result;\n\n if (validateOK === false) {\n base = Formatter.format(fallbackFormat, dict).result;\n }\n\n return FSHelper.createFilename({ name: base, ext });\n }\n\n static validateCampaignDirNameFormat(format: string) {\n return Formatter.validate(format, CAMPAIGN_DIR_NAME_VALIDATION_SCHEMA);\n }\n\n static validateContentDirNameFormat(format: string) {\n return Formatter.validate(format, CONTENT_DIR_NAME_VALIDATION_SCHEMA);\n }\n\n static validateMediaFilenameFormat(format: string) {\n return Formatter.validate(format, MEDIA_FILENAME_VALIDATION_SCHEMA);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FilenameFormatHelper.js","sourceRoot":"","sources":["../../src/utils/FilenameFormatHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import dateFormat from 'dateformat';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type MediaLike } from '../entities/MediaItem.js';\nimport { type Product } from '../entities/Product.js';\nimport Formatter, { type FormatFieldName, type FormatFieldRules, type FormatFieldValues } from './Formatter.js';\nimport URLHelper from './URLHelper.js';\nimport { type Collection, type Post } from '../entities/Post.js';\nimport { createSafeSlug, toISODate } from './Misc.js';\nimport FSHelper from './FSHelper.js';\n\ntype CampaignDirNameFormatFieldName =\n 'creator.vanity' |\n 'creator.name' |\n 'creator.id' |\n 'campaign.name' |\n 'campaign.id';\n\nexport const CAMPAIGN_DIR_NAME_VALIDATION_SCHEMA: FormatFieldRules<CampaignDirNameFormatFieldName> = [\n { name: 'creator.vanity', atLeastOneOf: true },\n { name: 'creator.name', atLeastOneOf: true },\n { name: 'creator.id', atLeastOneOf: true },\n { name: 'campaign.name', atLeastOneOf: true },\n { name: 'campaign.id', atLeastOneOf: true }\n];\n\ntype ContentDirNameFormatFieldName =\n 'content.id' |\n 'content.type' |\n 'content.slug' |\n 'content.name' |\n 'content.publishDate';\n\nexport const CONTENT_DIR_NAME_VALIDATION_SCHEMA: FormatFieldRules<ContentDirNameFormatFieldName> = [\n { name: 'content.id', atLeastOneOf: true },\n { name: 'content.type', atLeastOneOf: false },\n { name: 'content.slug', atLeastOneOf: true },\n { name: 'content.name', atLeastOneOf: false },\n { name: 'content.publishDate', atLeastOneOf: false }\n];\n\ntype MediaFilenameFormatFieldName =\n 'media.id' |\n 'media.type' |\n 'media.filename' |\n 'media.variant' |\n 'src.id' |\n 'src.type' |\n 'src.title' |\n 'src.date';\n\nexport const MEDIA_FILENAME_VALIDATION_SCHEMA: FormatFieldRules<MediaFilenameFormatFieldName> = [\n { name: 'media.id', atLeastOneOf: true },\n { name: 'media.type', atLeastOneOf: false },\n { name: 'media.filename', atLeastOneOf: true },\n { name: 'media.variant', atLeastOneOf: false }\n];\n\nconst CAMPAIGN_DIR_NAME_FALLBACK_FORMAT = 'campaign-{campaign.id}';\nconst CONTENT_DIR_NAME_FALLBACK_FORMAT = '{content.type}-{content.id}';\nconst MEDIA_FILENAME_FALLBACK_FORMAT = '{media.type}-{media.id}';\n\nexport default class FilenameFormatHelper {\n\n static getCampaignDirName(campaign: Campaign, format: string): string {\n const dict: FormatFieldValues<CampaignDirNameFormatFieldName> = {\n 'creator.vanity': campaign.creator?.vanity,\n 'creator.name': campaign.creator?.fullName,\n 'creator.id': campaign.creator?.id,\n 'campaign.name': campaign.name,\n 'campaign.id': campaign.id\n };\n\n return this.#getFilename(format, dict, CAMPAIGN_DIR_NAME_VALIDATION_SCHEMA, CAMPAIGN_DIR_NAME_FALLBACK_FORMAT);\n }\n\n static getContentDirName(content: Product | Post, format: string): string {\n const dict: FormatFieldValues<ContentDirNameFormatFieldName> = {\n 'content.id': content.id,\n 'content.type': content.type,\n 'content.slug': null,\n 'content.name': null,\n 'content.publishDate': content.publishedAt ? toISODate(content.publishedAt) : null\n };\n if (content.type === 'post') {\n const urlAnalysis = content.url ? URLHelper.analyzeURL(content.url) : null;\n dict['content.slug'] = urlAnalysis && urlAnalysis.type === 'post' ? urlAnalysis.slug : null;\n dict['content.name'] = content.title;\n }\n else if (content.type === 'product') {\n const urlAnalysis = URLHelper.analyzeURL(content.url);\n dict['content.slug'] = urlAnalysis && urlAnalysis.type === 'product' ? urlAnalysis.slug : null;\n dict['content.name'] = content.name;\n }\n\n return this.#getFilename(format, dict, CONTENT_DIR_NAME_VALIDATION_SCHEMA, CONTENT_DIR_NAME_FALLBACK_FORMAT);\n }\n\n static getCollectionDirName(collection: Collection, format: string): string {\n const slug = collection.title ?\n `${createSafeSlug(collection.title)}-${collection.id}`\n : `collection-${collection.id}`;\n const dict: FormatFieldValues<ContentDirNameFormatFieldName> = {\n 'content.id': collection.id,\n 'content.type': collection.type,\n 'content.slug': slug,\n 'content.name': collection.title,\n 'content.publishDate': collection.createdAt ? toISODate(collection.createdAt) : null\n };\n return this.#getFilename(format, dict, CONTENT_DIR_NAME_VALIDATION_SCHEMA, CONTENT_DIR_NAME_FALLBACK_FORMAT);\n }\n\n static getMediaFilename(\n media: MediaLike & { variant: string | null },\n src: Post | Product | Campaign | Collection,\n format: string,\n ext: string\n ): string {\n let srcFields: Pick<FormatFieldValues<MediaFilenameFormatFieldName>, 'src.id' | 'src.type' | 'src.title' | 'src.date'>;\n switch (src.type) {\n case 'post':\n srcFields = {\n 'src.id': src.id,\n 'src.type': src.type,\n 'src.date': src.publishedAt,\n 'src.title': src.title\n };\n break;\n case 'product':\n srcFields = {\n 'src.id': src.id,\n 'src.type': src.type,\n 'src.date': src.publishedAt,\n 'src.title': src.name\n };\n break;\n case 'campaign':\n srcFields = {\n 'src.id': src.id,\n 'src.type': src.type,\n 'src.date': src.createdAt,\n 'src.title': src.name\n };\n break;\n case 'collection':\n srcFields = {\n 'src.id': src.id,\n 'src.type': src.type,\n 'src.date': src.createdAt,\n 'src.title': src.title\n };\n break;\n }\n try {\n srcFields['src.date'] = dateFormat(new Date(srcFields['src.date']), 'yyyy-mm-dd_HH-MM');\n }\n catch (_) {\n // Do nothing\n }\n const dict: FormatFieldValues<MediaFilenameFormatFieldName> = {\n 'media.id': media.id,\n 'media.type': media.type,\n 'media.filename': media.filename,\n 'media.variant': media.variant,\n ...srcFields\n };\n\n return this.#getFilename(format, dict, MEDIA_FILENAME_VALIDATION_SCHEMA, MEDIA_FILENAME_FALLBACK_FORMAT, ext);\n }\n\n static #getFilename<T extends FormatFieldName>(\n format: string,\n dict: FormatFieldValues<T>,\n rules: FormatFieldRules<T>,\n fallbackFormat: string,\n ext?: string\n ) {\n const { validateOK, result } = Formatter.format(format, dict, rules);\n let base = result;\n\n if (validateOK === false) {\n base = Formatter.format(fallbackFormat, dict).result;\n }\n\n return FSHelper.createFilename({ name: base, ext });\n }\n\n static validateCampaignDirNameFormat(format: string) {\n return Formatter.validate(format, CAMPAIGN_DIR_NAME_VALIDATION_SCHEMA);\n }\n\n static validateContentDirNameFormat(format: string) {\n return Formatter.validate(format, CONTENT_DIR_NAME_VALIDATION_SCHEMA);\n }\n\n static validateMediaFilenameFormat(format: string) {\n return Formatter.validate(format, MEDIA_FILENAME_VALIDATION_SCHEMA);\n }\n}\n"]}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { type Response } from 'undici';
|
|
2
2
|
import { type MediaLike } from '../entities/MediaItem.js';
|
|
3
3
|
import FilenameResolver from './FllenameResolver.js';
|
|
4
|
+
import { type Collection, type Post } from '../entities/Post.js';
|
|
5
|
+
import { type Campaign } from '../entities/Campaign.js';
|
|
6
|
+
import { type Product } from '../entities/Product.js';
|
|
4
7
|
export default class MediaFilenameResolver<T extends MediaLike> extends FilenameResolver<T> {
|
|
5
8
|
#private;
|
|
6
|
-
constructor(target: T, srcURL: string, format: string, variant: string | null, ensureVariant: boolean);
|
|
9
|
+
constructor(target: T, srcURL: string, src: Post | Product | Campaign | Collection, format: string, variant: string | null, ensureVariant: boolean);
|
|
7
10
|
resolve(response: Response): string;
|
|
8
11
|
}
|
|
@@ -9,16 +9,18 @@ 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 _MediaFilenameResolver_format, _MediaFilenameResolver_variant;
|
|
12
|
+
var _MediaFilenameResolver_format, _MediaFilenameResolver_variant, _MediaFilenameResolver_src;
|
|
13
13
|
import path from 'path';
|
|
14
14
|
import FilenameResolver from './FllenameResolver.js';
|
|
15
15
|
import URLHelper from './URLHelper.js';
|
|
16
16
|
import FilenameFormatHelper from './FilenameFormatHelper.js';
|
|
17
17
|
class MediaFilenameResolver extends FilenameResolver {
|
|
18
|
-
constructor(target, srcURL, format, variant, ensureVariant) {
|
|
18
|
+
constructor(target, srcURL, src, format, variant, ensureVariant) {
|
|
19
19
|
super(target, srcURL);
|
|
20
20
|
_MediaFilenameResolver_format.set(this, void 0);
|
|
21
21
|
_MediaFilenameResolver_variant.set(this, void 0);
|
|
22
|
+
_MediaFilenameResolver_src.set(this, void 0);
|
|
23
|
+
__classPrivateFieldSet(this, _MediaFilenameResolver_src, src, "f");
|
|
22
24
|
__classPrivateFieldSet(this, _MediaFilenameResolver_format, format, "f");
|
|
23
25
|
__classPrivateFieldSet(this, _MediaFilenameResolver_variant, variant, "f");
|
|
24
26
|
if (ensureVariant && !__classPrivateFieldGet(this, _MediaFilenameResolver_format, "f").includes('{media.variant}')) {
|
|
@@ -82,9 +84,9 @@ class MediaFilenameResolver extends FilenameResolver {
|
|
|
82
84
|
filename: filenameParts.name,
|
|
83
85
|
variant: __classPrivateFieldGet(this, _MediaFilenameResolver_variant, "f")
|
|
84
86
|
};
|
|
85
|
-
return FilenameFormatHelper.getMediaFilename(tmpMI, __classPrivateFieldGet(this, _MediaFilenameResolver_format, "f"), filenameParts.ext);
|
|
87
|
+
return FilenameFormatHelper.getMediaFilename(tmpMI, __classPrivateFieldGet(this, _MediaFilenameResolver_src, "f"), __classPrivateFieldGet(this, _MediaFilenameResolver_format, "f"), filenameParts.ext);
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
|
-
_MediaFilenameResolver_format = new WeakMap(), _MediaFilenameResolver_variant = new WeakMap();
|
|
90
|
+
_MediaFilenameResolver_format = new WeakMap(), _MediaFilenameResolver_variant = new WeakMap(), _MediaFilenameResolver_src = new WeakMap();
|
|
89
91
|
export default MediaFilenameResolver;
|
|
90
92
|
//# sourceMappingURL=MediaFilenameResolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaFilenameResolver.js","sourceRoot":"","sources":["../../src/utils/MediaFilenameResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,gBAAgB,MAAM,uBAAuB,CAAC;AACrD,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"MediaFilenameResolver.js","sourceRoot":"","sources":["../../src/utils/MediaFilenameResolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Response } from 'undici';\nimport path from 'path';\nimport { type MediaLike } from '../entities/MediaItem.js';\nimport FilenameResolver from './FllenameResolver.js';\nimport URLHelper from './URLHelper.js';\nimport FilenameFormatHelper from './FilenameFormatHelper.js';\nimport { type Collection, type Post } from '../entities/Post.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type Product } from '../entities/Product.js';\n\nexport default class MediaFilenameResolver<T extends MediaLike> extends FilenameResolver<T> {\n\n #format: string;\n #variant: string | null;\n #src: Post | Product | Campaign | Collection;\n\n constructor(target: T, srcURL: string, src: Post | Product | Campaign | Collection, format: string, variant: string | null, ensureVariant: boolean) {\n super(target, srcURL);\n this.#src = src;\n this.#format = format;\n this.#variant = variant;\n\n if (ensureVariant && !this.#format.includes('{media.variant}')) {\n this.#format = `${format}[-]?{media.variant}`;\n }\n }\n\n resolve(response: Response) {\n const mi = this.target;\n const miFilenameParts = mi.filename ? path.parse(mi.filename) : null;\n const resFilenameParts = this.getFilenamePartsFromResponse(response, mi.type !== 'attachment');\n\n const filenameParts = {\n name: '',\n ext: ''\n };\n\n /**\n * Obtain `name` part from (in order of priority):\n * 1. Media filename\n * 2. Filename from response headers\n * 3. If none of the above is available, fallback to using the media ID\n */\n if (miFilenameParts?.name) {\n filenameParts.name = miFilenameParts.name;\n }\n else if (resFilenameParts.name) {\n filenameParts.name = resFilenameParts.name;\n }\n else if (!this.#format.includes('{media.id}')) {\n filenameParts.name = mi.id;\n }\n\n /**\n * Obtain `extension` from (in order of priority):\n * 1. Response headers (unless target is attachment, in which case (2) takes precedence)\n * 2. Media filename\n * 3. Media mimetype\n * 4. Src URL\n */\n if (mi.type === 'attachment' && miFilenameParts?.ext) {\n filenameParts.ext = miFilenameParts.ext;\n }\n else if (resFilenameParts.ext) {\n // Use media item filename if the same (preserves case)\n if (miFilenameParts?.ext?.toLowerCase() === resFilenameParts.ext.toLowerCase() &&\n filenameParts.name === miFilenameParts.name && this.#format.includes('{media.filename}')) {\n\n filenameParts.ext = miFilenameParts.ext;\n }\n else {\n filenameParts.ext = resFilenameParts.ext;\n }\n }\n else if (miFilenameParts?.ext) {\n filenameParts.ext = miFilenameParts.ext;\n }\n else if (mi.mimeType) {\n filenameParts.ext = this.getExtensionByContentType(mi.mimeType);\n }\n else {\n filenameParts.ext = URLHelper.getExtensionFromURL(this.srcURL);\n }\n\n const tmpMI = {\n ...mi,\n filename: filenameParts.name,\n variant: this.#variant\n };\n\n return FilenameFormatHelper.getMediaFilename(tmpMI, this.#src, this.#format, filenameParts.ext);\n }\n}\n"]}
|
package/dist/utils/URLHelper.js
CHANGED
|
@@ -10,14 +10,14 @@ const CAMPAIGN_API_URL = `${SITE_URL}/api/campaigns`;
|
|
|
10
10
|
const POST_COMMENTS_API_URL = `${SITE_URL}/api/posts/{POST_ID}/comments2`;
|
|
11
11
|
const POST_COMMENT_REPLIES_API_URL = `${SITE_URL}/api/comments/{COMMENT_ID}/replies2`;
|
|
12
12
|
const SHOP_API_URL = `${SITE_URL}/api/campaigns/{CAMPAIGN_ID}/products`;
|
|
13
|
-
const PRODUCT_URL_REGEX = /https:\/\/www\.patreon\.com\/([^/]+?)\/shop\/(([^/]+)-(\d+))$/;
|
|
14
|
-
const POSTS_BY_USER_URL_REGEX = /https:\/\/www\.patreon\.com\/([^/]+?)\/posts$/;
|
|
15
|
-
const POSTS_BY_USER_URL_REGEX_2 = /https:\/\/www\.patreon\.com\/(?:c|cw)\/([^/]+?)\/posts$/;
|
|
16
|
-
const COLLECTION_URL_REGEX = /https:\/\/www\.patreon\.com\/collection\/(\d+)$/;
|
|
17
|
-
const POST_URL_REGEX = /https:\/\/www\.patreon\.com\/posts\/(([^/]+)-(\d+))$/;
|
|
18
|
-
const POST_URL_REGEX_2 = /https:\/\/www\.patreon\.com\/posts\/(\d+)$/; // No slug
|
|
19
|
-
const SHOP_URL_REGEX = /https:\/\/www\.patreon\.com\/([^/]+?)\/shop$/;
|
|
20
|
-
const SHOP_URL_REGEX_2 = /https:\/\/www\.patreon\.com\/(?:c|cw)\/([^/]+?)\/shop$/;
|
|
13
|
+
const PRODUCT_URL_REGEX = /https:\/\/(?:www\.)?patreon\.com\/([^/]+?)\/shop\/(([^/]+)-(\d+))$/;
|
|
14
|
+
const POSTS_BY_USER_URL_REGEX = /https:\/\/(?:www\.)?patreon\.com\/([^/]+?)\/posts$/;
|
|
15
|
+
const POSTS_BY_USER_URL_REGEX_2 = /https:\/\/(?:www\.)?patreon\.com\/(?:c|cw)\/([^/]+?)\/posts$/;
|
|
16
|
+
const COLLECTION_URL_REGEX = /https:\/\/(?:www\.)?patreon\.com\/collection\/(\d+)$/;
|
|
17
|
+
const POST_URL_REGEX = /https:\/\/(?:www\.)?patreon\.com\/posts\/(([^/]+)-(\d+))$/;
|
|
18
|
+
const POST_URL_REGEX_2 = /https:\/\/(?:www\.)?patreon\.com\/posts\/(\d+)$/; // No slug
|
|
19
|
+
const SHOP_URL_REGEX = /https:\/\/(?:www\.)?patreon\.com\/([^/]+?)\/shop$/;
|
|
20
|
+
const SHOP_URL_REGEX_2 = /https:\/\/(?:www\.)?patreon\.com\/(?:c|cw)\/([^/]+?)\/shop$/;
|
|
21
21
|
const PRODUCT_API_URL_SEARCH_PARAMS = {
|
|
22
22
|
PRODUCT_VARIANT: [
|
|
23
23
|
'name',
|