node-csfd-api 5.0.0-next-2 → 5.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dto/movie.d.mts CHANGED
@@ -18,21 +18,6 @@ interface CSFDMovie extends CSFDScreening {
18
18
  premieres: CSFDPremiere[];
19
19
  related: CSFDMovieListItem[];
20
20
  similar: CSFDMovieListItem[];
21
- seasons: CSFDSeriesChild[] | null;
22
- episodes: CSFDSeriesChild[] | null;
23
- parent: CSFDParent | null;
24
- episodeCode: string | null;
25
- seasonName: string | null;
26
- }
27
- interface CSFDParent {
28
- season: {
29
- id: number;
30
- title: string;
31
- } | null;
32
- series: {
33
- id: number;
34
- title: string;
35
- } | null;
36
21
  }
37
22
  interface MovieJsonLd {
38
23
  dateCreated?: string;
@@ -88,12 +73,6 @@ interface CSFDPremiere {
88
73
  company: string;
89
74
  }
90
75
  type CSFDBoxContent = 'Související' | 'Podobné';
91
- interface CSFDSeriesChild {
92
- id: number;
93
- title: string;
94
- url: string;
95
- info: string | null;
96
- }
97
76
  //#endregion
98
- export { CSFDBoxContent, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreators, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDParent, CSFDPremiere, CSFDSeriesChild, CSFDTitlesOther, CSFDVod, CSFDVodService, MovieJsonLd };
77
+ export { CSFDBoxContent, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreators, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDPremiere, CSFDTitlesOther, CSFDVod, CSFDVodService, MovieJsonLd };
99
78
  //# sourceMappingURL=movie.d.mts.map
package/dto/movie.d.ts CHANGED
@@ -18,21 +18,6 @@ interface CSFDMovie extends CSFDScreening {
18
18
  premieres: CSFDPremiere[];
19
19
  related: CSFDMovieListItem[];
20
20
  similar: CSFDMovieListItem[];
21
- seasons: CSFDSeriesChild[] | null;
22
- episodes: CSFDSeriesChild[] | null;
23
- parent: CSFDParent | null;
24
- episodeCode: string | null;
25
- seasonName: string | null;
26
- }
27
- interface CSFDParent {
28
- season: {
29
- id: number;
30
- title: string;
31
- } | null;
32
- series: {
33
- id: number;
34
- title: string;
35
- } | null;
36
21
  }
37
22
  interface MovieJsonLd {
38
23
  dateCreated?: string;
@@ -88,12 +73,6 @@ interface CSFDPremiere {
88
73
  company: string;
89
74
  }
90
75
  type CSFDBoxContent = 'Související' | 'Podobné';
91
- interface CSFDSeriesChild {
92
- id: number;
93
- title: string;
94
- url: string;
95
- info: string | null;
96
- }
97
76
  //#endregion
98
- export { CSFDBoxContent, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreators, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDParent, CSFDPremiere, CSFDSeriesChild, CSFDTitlesOther, CSFDVod, CSFDVodService, MovieJsonLd };
77
+ export { CSFDBoxContent, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreators, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDPremiere, CSFDTitlesOther, CSFDVod, CSFDVodService, MovieJsonLd };
99
78
  //# sourceMappingURL=movie.d.ts.map
@@ -7,10 +7,6 @@ const parseIdFromUrl = (url) => {
7
7
  const parts = url.split("/");
8
8
  return +parts[LANG_PREFIX_REGEX.test(parts[1]) ? 3 : 2]?.split("-")[0] || null;
9
9
  };
10
- const parseLastIdFromUrl = (url) => {
11
- if (url) return +(url?.split("/")[3])?.split("-")[0] || null;
12
- else return null;
13
- };
14
10
  const getColor = (cls) => {
15
11
  switch (cls) {
16
12
  case "page-lightgrey": return "unknown";
@@ -103,6 +99,5 @@ exports.parseDate = parseDate;
103
99
  exports.parseFilmType = parseFilmType;
104
100
  exports.parseISO8601Duration = parseISO8601Duration;
105
101
  exports.parseIdFromUrl = parseIdFromUrl;
106
- exports.parseLastIdFromUrl = parseLastIdFromUrl;
107
102
  exports.sleep = sleep;
108
103
  //# sourceMappingURL=global.helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"global.helper.js","names":[],"sources":["../../src/helpers/global.helper.ts"],"sourcesContent":["import { CSFDColorRating, CSFDFilmTypes } from '../dto/global';\nimport { CSFDColors } from '../dto/user-ratings';\n\nconst LANG_PREFIX_REGEX = /^[a-z]{2,3}$/;\nconst ISO8601_DURATION_REGEX =\n /(-)?P(?:([.,\\d]+)Y)?(?:([.,\\d]+)M)?(?:([.,\\d]+)W)?(?:([.,\\d]+)D)?T(?:([.,\\d]+)H)?(?:([.,\\d]+)M)?(?:([.,\\d]+)S)?/;\n\nexport const parseIdFromUrl = (url: string): number => {\n if (!url) return null;\n\n const parts = url.split('/');\n // Detect language prefix like /en/ or /sk/\n const hasLangPrefix = LANG_PREFIX_REGEX.test(parts[1]);\n const idSlug = parts[hasLangPrefix ? 3 : 2];\n const id = idSlug?.split('-')[0];\n return +id || null;\n};\n\nexport const parseLastIdFromUrl = (url: string): number => {\n if (url) {\n const idSlug = url?.split('/')[3];\n const id = idSlug?.split('-')[0];\n return +id || null;\n } else {\n return null;\n }\n};\n\nexport const getColor = (cls: string): CSFDColorRating => {\n switch (cls) {\n case 'page-lightgrey':\n return 'unknown';\n case 'page-red':\n return 'good';\n case 'page-blue':\n return 'average';\n case 'page-grey':\n return 'bad';\n default:\n return 'unknown';\n }\n};\n\nexport const parseColor = (quality: CSFDColors): CSFDColorRating => {\n switch (quality) {\n case 'lightgrey':\n return 'unknown';\n case 'red':\n return 'good';\n case 'blue':\n return 'average';\n case 'grey':\n return 'bad';\n default:\n return 'unknown';\n }\n};\n\nconst filmTypeMap: Record<string, CSFDFilmTypes> = {\n 'TV film': 'tv-film',\n pořad: 'tv-show',\n seriál: 'series',\n 'divadelní záznam': 'theatrical',\n koncert: 'concert',\n série: 'season',\n 'studentský film': 'student-film',\n 'amatérský film': 'amateur-film',\n 'hudební videoklip': 'music-video',\n epizoda: 'episode',\n 'video kompilace': 'video-compilation',\n film: 'film'\n};\n\nexport const parseFilmType = (type: string): CSFDFilmTypes => {\n return filmTypeMap[type] || 'film';\n};\n\nexport const addProtocol = (url: string): string => {\n return url.startsWith('//') ? 'https:' + url : url;\n};\n\nexport const getDuration = (matches: RegExpMatchArray) => {\n return {\n sign: matches[1] === undefined ? '+' : '-',\n years: matches[2] === undefined ? 0 : matches[2],\n months: matches[3] === undefined ? 0 : matches[3],\n weeks: matches[4] === undefined ? 0 : matches[4],\n days: matches[5] === undefined ? 0 : matches[5],\n hours: matches[6] === undefined ? 0 : matches[6],\n minutes: matches[7] === undefined ? 0 : matches[7],\n seconds: matches[8] === undefined ? 0 : matches[8]\n };\n};\n\nexport const parseISO8601Duration = (iso: string): number => {\n const matches = iso.match(ISO8601_DURATION_REGEX);\n\n const duration = getDuration(matches);\n\n return +duration.hours * 60 + +duration.minutes;\n};\n\n/**\n * Parses a date string into a standardized YYYY-MM-DD format.\n * Supports:\n * - D.M.YYYY\n * - DD.MM.YYYY\n * - D. M. YYYY\n * - MM/DD/YYYY\n * - YYYY\n */\nexport const parseDate = (date: string): string | null => {\n if (!date) return null;\n\n // Clean the input\n const cleanDate = date.trim();\n\n // Try parsing DD.MM.YYYY or D.M.YYYY with optional spaces\n const dateMatch = cleanDate.match(/^(\\d{1,2})\\.\\s*(\\d{1,2})\\.\\s*(\\d{4})$/);\n if (dateMatch) {\n const day = dateMatch[1].padStart(2, '0');\n const month = dateMatch[2].padStart(2, '0');\n const year = dateMatch[3];\n return `${year}-${month}-${day}`;\n }\n\n // Try parsing MM/DD/YYYY\n const slashMatch = cleanDate.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\n if (slashMatch) {\n const month = slashMatch[1].padStart(2, '0');\n const day = slashMatch[2].padStart(2, '0');\n const year = slashMatch[3];\n return `${year}-${month}-${day}`;\n }\n\n // Try parsing YYYY\n const yearMatch = cleanDate.match(/^(\\d{4})$/);\n if (yearMatch) {\n return `${yearMatch[1]}-01-01`;\n }\n\n return null;\n};\n\n// Sleep in loop\nexport const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));\n"],"mappings":";;AAGA,MAAM,oBAAoB;AAC1B,MAAM,yBACJ;AAEF,MAAa,kBAAkB,QAAwB;AACrD,KAAI,CAAC,IAAK,QAAO;CAEjB,MAAM,QAAQ,IAAI,MAAM,IAAI;AAK5B,QAAO,CAFQ,MADO,kBAAkB,KAAK,MAAM,GAAG,GACjB,IAAI,IACtB,MAAM,IAAI,CAAC,MAChB;;AAGhB,MAAa,sBAAsB,QAAwB;AACzD,KAAI,IAGF,QAAO,EAFQ,KAAK,MAAM,IAAI,CAAC,KACZ,MAAM,IAAI,CAAC,MAChB;KAEd,QAAO;;AAIX,MAAa,YAAY,QAAiC;AACxD,SAAQ,KAAR;EACE,KAAK,iBACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAa,cAAc,YAAyC;AAClE,SAAQ,SAAR;EACE,KAAK,YACH,QAAO;EACT,KAAK,MACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAM,cAA6C;CACjD,WAAW;CACX,OAAO;CACP,QAAQ;CACR,oBAAoB;CACpB,SAAS;CACT,OAAO;CACP,mBAAmB;CACnB,kBAAkB;CAClB,qBAAqB;CACrB,SAAS;CACT,mBAAmB;CACnB,MAAM;CACP;AAED,MAAa,iBAAiB,SAAgC;AAC5D,QAAO,YAAY,SAAS;;AAG9B,MAAa,eAAe,QAAwB;AAClD,QAAO,IAAI,WAAW,KAAK,GAAG,WAAW,MAAM;;AAGjD,MAAa,eAAe,YAA8B;AACxD,QAAO;EACL,MAAM,QAAQ,OAAO,SAAY,MAAM;EACvC,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,QAAQ,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC/C,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,MAAM,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC7C,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,SAAS,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAChD,SAAS,QAAQ,OAAO,SAAY,IAAI,QAAQ;EACjD;;AAGH,MAAa,wBAAwB,QAAwB;CAG3D,MAAM,WAAW,YAFD,IAAI,MAAM,uBAAuB,CAEZ;AAErC,QAAO,CAAC,SAAS,QAAQ,KAAK,CAAC,SAAS;;;;;;;;;;;AAY1C,MAAa,aAAa,SAAgC;AACxD,KAAI,CAAC,KAAM,QAAO;CAGlB,MAAM,YAAY,KAAK,MAAM;CAG7B,MAAM,YAAY,UAAU,MAAM,wCAAwC;AAC1E,KAAI,WAAW;EACb,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI;EACzC,MAAM,QAAQ,UAAU,GAAG,SAAS,GAAG,IAAI;AAE3C,SAAO,GADM,UAAU,GACR,GAAG,MAAM,GAAG;;CAI7B,MAAM,aAAa,UAAU,MAAM,kCAAkC;AACrE,KAAI,YAAY;EACd,MAAM,QAAQ,WAAW,GAAG,SAAS,GAAG,IAAI;EAC5C,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,IAAI;AAE1C,SAAO,GADM,WAAW,GACT,GAAG,MAAM,GAAG;;CAI7B,MAAM,YAAY,UAAU,MAAM,YAAY;AAC9C,KAAI,UACF,QAAO,GAAG,UAAU,GAAG;AAGzB,QAAO;;AAIT,MAAa,SAAS,OAAe,IAAI,SAAS,QAAQ,WAAW,KAAK,GAAG,CAAC"}
1
+ {"version":3,"file":"global.helper.js","names":[],"sources":["../../src/helpers/global.helper.ts"],"sourcesContent":["import { CSFDColorRating, CSFDFilmTypes } from '../dto/global';\nimport { CSFDColors } from '../dto/user-ratings';\n\nconst LANG_PREFIX_REGEX = /^[a-z]{2,3}$/;\nconst ISO8601_DURATION_REGEX =\n /(-)?P(?:([.,\\d]+)Y)?(?:([.,\\d]+)M)?(?:([.,\\d]+)W)?(?:([.,\\d]+)D)?T(?:([.,\\d]+)H)?(?:([.,\\d]+)M)?(?:([.,\\d]+)S)?/;\n\nexport const parseIdFromUrl = (url: string): number => {\n if (!url) return null;\n\n const parts = url.split('/');\n // Detect language prefix like /en/ or /sk/\n const hasLangPrefix = LANG_PREFIX_REGEX.test(parts[1]);\n const idSlug = parts[hasLangPrefix ? 3 : 2];\n const id = idSlug?.split('-')[0];\n return +id || null;\n};\n\nexport const getColor = (cls: string): CSFDColorRating => {\n switch (cls) {\n case 'page-lightgrey':\n return 'unknown';\n case 'page-red':\n return 'good';\n case 'page-blue':\n return 'average';\n case 'page-grey':\n return 'bad';\n default:\n return 'unknown';\n }\n};\n\nexport const parseColor = (quality: CSFDColors): CSFDColorRating => {\n switch (quality) {\n case 'lightgrey':\n return 'unknown';\n case 'red':\n return 'good';\n case 'blue':\n return 'average';\n case 'grey':\n return 'bad';\n default:\n return 'unknown';\n }\n};\n\nconst filmTypeMap: Record<string, CSFDFilmTypes> = {\n 'TV film': 'tv-film',\n pořad: 'tv-show',\n seriál: 'series',\n 'divadelní záznam': 'theatrical',\n koncert: 'concert',\n série: 'season',\n 'studentský film': 'student-film',\n 'amatérský film': 'amateur-film',\n 'hudební videoklip': 'music-video',\n epizoda: 'episode',\n 'video kompilace': 'video-compilation',\n film: 'film'\n};\n\nexport const parseFilmType = (type: string): CSFDFilmTypes => {\n return filmTypeMap[type] || 'film';\n};\n\nexport const addProtocol = (url: string): string => {\n return url.startsWith('//') ? 'https:' + url : url;\n};\n\nexport const getDuration = (matches: RegExpMatchArray) => {\n return {\n sign: matches[1] === undefined ? '+' : '-',\n years: matches[2] === undefined ? 0 : matches[2],\n months: matches[3] === undefined ? 0 : matches[3],\n weeks: matches[4] === undefined ? 0 : matches[4],\n days: matches[5] === undefined ? 0 : matches[5],\n hours: matches[6] === undefined ? 0 : matches[6],\n minutes: matches[7] === undefined ? 0 : matches[7],\n seconds: matches[8] === undefined ? 0 : matches[8]\n };\n};\n\nexport const parseISO8601Duration = (iso: string): number => {\n const matches = iso.match(ISO8601_DURATION_REGEX);\n\n const duration = getDuration(matches);\n\n return +duration.hours * 60 + +duration.minutes;\n};\n\n/**\n * Parses a date string into a standardized YYYY-MM-DD format.\n * Supports:\n * - D.M.YYYY\n * - DD.MM.YYYY\n * - D. M. YYYY\n * - MM/DD/YYYY\n * - YYYY\n */\nexport const parseDate = (date: string): string | null => {\n if (!date) return null;\n\n // Clean the input\n const cleanDate = date.trim();\n\n // Try parsing DD.MM.YYYY or D.M.YYYY with optional spaces\n const dateMatch = cleanDate.match(/^(\\d{1,2})\\.\\s*(\\d{1,2})\\.\\s*(\\d{4})$/);\n if (dateMatch) {\n const day = dateMatch[1].padStart(2, '0');\n const month = dateMatch[2].padStart(2, '0');\n const year = dateMatch[3];\n return `${year}-${month}-${day}`;\n }\n\n // Try parsing MM/DD/YYYY\n const slashMatch = cleanDate.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\n if (slashMatch) {\n const month = slashMatch[1].padStart(2, '0');\n const day = slashMatch[2].padStart(2, '0');\n const year = slashMatch[3];\n return `${year}-${month}-${day}`;\n }\n\n // Try parsing YYYY\n const yearMatch = cleanDate.match(/^(\\d{4})$/);\n if (yearMatch) {\n return `${yearMatch[1]}-01-01`;\n }\n\n return null;\n};\n\n// Sleep in loop\nexport const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));\n"],"mappings":";;AAGA,MAAM,oBAAoB;AAC1B,MAAM,yBACJ;AAEF,MAAa,kBAAkB,QAAwB;AACrD,KAAI,CAAC,IAAK,QAAO;CAEjB,MAAM,QAAQ,IAAI,MAAM,IAAI;AAK5B,QAAO,CAFQ,MADO,kBAAkB,KAAK,MAAM,GAAG,GACjB,IAAI,IACtB,MAAM,IAAI,CAAC,MAChB;;AAGhB,MAAa,YAAY,QAAiC;AACxD,SAAQ,KAAR;EACE,KAAK,iBACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAa,cAAc,YAAyC;AAClE,SAAQ,SAAR;EACE,KAAK,YACH,QAAO;EACT,KAAK,MACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAM,cAA6C;CACjD,WAAW;CACX,OAAO;CACP,QAAQ;CACR,oBAAoB;CACpB,SAAS;CACT,OAAO;CACP,mBAAmB;CACnB,kBAAkB;CAClB,qBAAqB;CACrB,SAAS;CACT,mBAAmB;CACnB,MAAM;CACP;AAED,MAAa,iBAAiB,SAAgC;AAC5D,QAAO,YAAY,SAAS;;AAG9B,MAAa,eAAe,QAAwB;AAClD,QAAO,IAAI,WAAW,KAAK,GAAG,WAAW,MAAM;;AAGjD,MAAa,eAAe,YAA8B;AACxD,QAAO;EACL,MAAM,QAAQ,OAAO,SAAY,MAAM;EACvC,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,QAAQ,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC/C,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,MAAM,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC7C,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,SAAS,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAChD,SAAS,QAAQ,OAAO,SAAY,IAAI,QAAQ;EACjD;;AAGH,MAAa,wBAAwB,QAAwB;CAG3D,MAAM,WAAW,YAFD,IAAI,MAAM,uBAAuB,CAEZ;AAErC,QAAO,CAAC,SAAS,QAAQ,KAAK,CAAC,SAAS;;;;;;;;;;;AAY1C,MAAa,aAAa,SAAgC;AACxD,KAAI,CAAC,KAAM,QAAO;CAGlB,MAAM,YAAY,KAAK,MAAM;CAG7B,MAAM,YAAY,UAAU,MAAM,wCAAwC;AAC1E,KAAI,WAAW;EACb,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI;EACzC,MAAM,QAAQ,UAAU,GAAG,SAAS,GAAG,IAAI;AAE3C,SAAO,GADM,UAAU,GACR,GAAG,MAAM,GAAG;;CAI7B,MAAM,aAAa,UAAU,MAAM,kCAAkC;AACrE,KAAI,YAAY;EACd,MAAM,QAAQ,WAAW,GAAG,SAAS,GAAG,IAAI;EAC5C,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,IAAI;AAE1C,SAAO,GADM,WAAW,GACT,GAAG,MAAM,GAAG;;CAI7B,MAAM,YAAY,UAAU,MAAM,YAAY;AAC9C,KAAI,UACF,QAAO,GAAG,UAAU,GAAG;AAGzB,QAAO;;AAIT,MAAa,SAAS,OAAe,IAAI,SAAS,QAAQ,WAAW,KAAK,GAAG,CAAC"}
@@ -6,10 +6,6 @@ const parseIdFromUrl = (url) => {
6
6
  const parts = url.split("/");
7
7
  return +parts[LANG_PREFIX_REGEX.test(parts[1]) ? 3 : 2]?.split("-")[0] || null;
8
8
  };
9
- const parseLastIdFromUrl = (url) => {
10
- if (url) return +(url?.split("/")[3])?.split("-")[0] || null;
11
- else return null;
12
- };
13
9
  const getColor = (cls) => {
14
10
  switch (cls) {
15
11
  case "page-lightgrey": return "unknown";
@@ -95,5 +91,5 @@ const parseDate = (date) => {
95
91
  const sleep = (ms) => new Promise((res) => setTimeout(res, ms));
96
92
 
97
93
  //#endregion
98
- export { addProtocol, getColor, parseColor, parseDate, parseFilmType, parseISO8601Duration, parseIdFromUrl, parseLastIdFromUrl, sleep };
94
+ export { addProtocol, getColor, parseColor, parseDate, parseFilmType, parseISO8601Duration, parseIdFromUrl, sleep };
99
95
  //# sourceMappingURL=global.helper.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"global.helper.mjs","names":[],"sources":["../../src/helpers/global.helper.ts"],"sourcesContent":["import { CSFDColorRating, CSFDFilmTypes } from '../dto/global';\nimport { CSFDColors } from '../dto/user-ratings';\n\nconst LANG_PREFIX_REGEX = /^[a-z]{2,3}$/;\nconst ISO8601_DURATION_REGEX =\n /(-)?P(?:([.,\\d]+)Y)?(?:([.,\\d]+)M)?(?:([.,\\d]+)W)?(?:([.,\\d]+)D)?T(?:([.,\\d]+)H)?(?:([.,\\d]+)M)?(?:([.,\\d]+)S)?/;\n\nexport const parseIdFromUrl = (url: string): number => {\n if (!url) return null;\n\n const parts = url.split('/');\n // Detect language prefix like /en/ or /sk/\n const hasLangPrefix = LANG_PREFIX_REGEX.test(parts[1]);\n const idSlug = parts[hasLangPrefix ? 3 : 2];\n const id = idSlug?.split('-')[0];\n return +id || null;\n};\n\nexport const parseLastIdFromUrl = (url: string): number => {\n if (url) {\n const idSlug = url?.split('/')[3];\n const id = idSlug?.split('-')[0];\n return +id || null;\n } else {\n return null;\n }\n};\n\nexport const getColor = (cls: string): CSFDColorRating => {\n switch (cls) {\n case 'page-lightgrey':\n return 'unknown';\n case 'page-red':\n return 'good';\n case 'page-blue':\n return 'average';\n case 'page-grey':\n return 'bad';\n default:\n return 'unknown';\n }\n};\n\nexport const parseColor = (quality: CSFDColors): CSFDColorRating => {\n switch (quality) {\n case 'lightgrey':\n return 'unknown';\n case 'red':\n return 'good';\n case 'blue':\n return 'average';\n case 'grey':\n return 'bad';\n default:\n return 'unknown';\n }\n};\n\nconst filmTypeMap: Record<string, CSFDFilmTypes> = {\n 'TV film': 'tv-film',\n pořad: 'tv-show',\n seriál: 'series',\n 'divadelní záznam': 'theatrical',\n koncert: 'concert',\n série: 'season',\n 'studentský film': 'student-film',\n 'amatérský film': 'amateur-film',\n 'hudební videoklip': 'music-video',\n epizoda: 'episode',\n 'video kompilace': 'video-compilation',\n film: 'film'\n};\n\nexport const parseFilmType = (type: string): CSFDFilmTypes => {\n return filmTypeMap[type] || 'film';\n};\n\nexport const addProtocol = (url: string): string => {\n return url.startsWith('//') ? 'https:' + url : url;\n};\n\nexport const getDuration = (matches: RegExpMatchArray) => {\n return {\n sign: matches[1] === undefined ? '+' : '-',\n years: matches[2] === undefined ? 0 : matches[2],\n months: matches[3] === undefined ? 0 : matches[3],\n weeks: matches[4] === undefined ? 0 : matches[4],\n days: matches[5] === undefined ? 0 : matches[5],\n hours: matches[6] === undefined ? 0 : matches[6],\n minutes: matches[7] === undefined ? 0 : matches[7],\n seconds: matches[8] === undefined ? 0 : matches[8]\n };\n};\n\nexport const parseISO8601Duration = (iso: string): number => {\n const matches = iso.match(ISO8601_DURATION_REGEX);\n\n const duration = getDuration(matches);\n\n return +duration.hours * 60 + +duration.minutes;\n};\n\n/**\n * Parses a date string into a standardized YYYY-MM-DD format.\n * Supports:\n * - D.M.YYYY\n * - DD.MM.YYYY\n * - D. M. YYYY\n * - MM/DD/YYYY\n * - YYYY\n */\nexport const parseDate = (date: string): string | null => {\n if (!date) return null;\n\n // Clean the input\n const cleanDate = date.trim();\n\n // Try parsing DD.MM.YYYY or D.M.YYYY with optional spaces\n const dateMatch = cleanDate.match(/^(\\d{1,2})\\.\\s*(\\d{1,2})\\.\\s*(\\d{4})$/);\n if (dateMatch) {\n const day = dateMatch[1].padStart(2, '0');\n const month = dateMatch[2].padStart(2, '0');\n const year = dateMatch[3];\n return `${year}-${month}-${day}`;\n }\n\n // Try parsing MM/DD/YYYY\n const slashMatch = cleanDate.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\n if (slashMatch) {\n const month = slashMatch[1].padStart(2, '0');\n const day = slashMatch[2].padStart(2, '0');\n const year = slashMatch[3];\n return `${year}-${month}-${day}`;\n }\n\n // Try parsing YYYY\n const yearMatch = cleanDate.match(/^(\\d{4})$/);\n if (yearMatch) {\n return `${yearMatch[1]}-01-01`;\n }\n\n return null;\n};\n\n// Sleep in loop\nexport const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));\n"],"mappings":";AAGA,MAAM,oBAAoB;AAC1B,MAAM,yBACJ;AAEF,MAAa,kBAAkB,QAAwB;AACrD,KAAI,CAAC,IAAK,QAAO;CAEjB,MAAM,QAAQ,IAAI,MAAM,IAAI;AAK5B,QAAO,CAFQ,MADO,kBAAkB,KAAK,MAAM,GAAG,GACjB,IAAI,IACtB,MAAM,IAAI,CAAC,MAChB;;AAGhB,MAAa,sBAAsB,QAAwB;AACzD,KAAI,IAGF,QAAO,EAFQ,KAAK,MAAM,IAAI,CAAC,KACZ,MAAM,IAAI,CAAC,MAChB;KAEd,QAAO;;AAIX,MAAa,YAAY,QAAiC;AACxD,SAAQ,KAAR;EACE,KAAK,iBACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAa,cAAc,YAAyC;AAClE,SAAQ,SAAR;EACE,KAAK,YACH,QAAO;EACT,KAAK,MACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAM,cAA6C;CACjD,WAAW;CACX,OAAO;CACP,QAAQ;CACR,oBAAoB;CACpB,SAAS;CACT,OAAO;CACP,mBAAmB;CACnB,kBAAkB;CAClB,qBAAqB;CACrB,SAAS;CACT,mBAAmB;CACnB,MAAM;CACP;AAED,MAAa,iBAAiB,SAAgC;AAC5D,QAAO,YAAY,SAAS;;AAG9B,MAAa,eAAe,QAAwB;AAClD,QAAO,IAAI,WAAW,KAAK,GAAG,WAAW,MAAM;;AAGjD,MAAa,eAAe,YAA8B;AACxD,QAAO;EACL,MAAM,QAAQ,OAAO,SAAY,MAAM;EACvC,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,QAAQ,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC/C,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,MAAM,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC7C,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,SAAS,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAChD,SAAS,QAAQ,OAAO,SAAY,IAAI,QAAQ;EACjD;;AAGH,MAAa,wBAAwB,QAAwB;CAG3D,MAAM,WAAW,YAFD,IAAI,MAAM,uBAAuB,CAEZ;AAErC,QAAO,CAAC,SAAS,QAAQ,KAAK,CAAC,SAAS;;;;;;;;;;;AAY1C,MAAa,aAAa,SAAgC;AACxD,KAAI,CAAC,KAAM,QAAO;CAGlB,MAAM,YAAY,KAAK,MAAM;CAG7B,MAAM,YAAY,UAAU,MAAM,wCAAwC;AAC1E,KAAI,WAAW;EACb,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI;EACzC,MAAM,QAAQ,UAAU,GAAG,SAAS,GAAG,IAAI;AAE3C,SAAO,GADM,UAAU,GACR,GAAG,MAAM,GAAG;;CAI7B,MAAM,aAAa,UAAU,MAAM,kCAAkC;AACrE,KAAI,YAAY;EACd,MAAM,QAAQ,WAAW,GAAG,SAAS,GAAG,IAAI;EAC5C,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,IAAI;AAE1C,SAAO,GADM,WAAW,GACT,GAAG,MAAM,GAAG;;CAI7B,MAAM,YAAY,UAAU,MAAM,YAAY;AAC9C,KAAI,UACF,QAAO,GAAG,UAAU,GAAG;AAGzB,QAAO;;AAIT,MAAa,SAAS,OAAe,IAAI,SAAS,QAAQ,WAAW,KAAK,GAAG,CAAC"}
1
+ {"version":3,"file":"global.helper.mjs","names":[],"sources":["../../src/helpers/global.helper.ts"],"sourcesContent":["import { CSFDColorRating, CSFDFilmTypes } from '../dto/global';\nimport { CSFDColors } from '../dto/user-ratings';\n\nconst LANG_PREFIX_REGEX = /^[a-z]{2,3}$/;\nconst ISO8601_DURATION_REGEX =\n /(-)?P(?:([.,\\d]+)Y)?(?:([.,\\d]+)M)?(?:([.,\\d]+)W)?(?:([.,\\d]+)D)?T(?:([.,\\d]+)H)?(?:([.,\\d]+)M)?(?:([.,\\d]+)S)?/;\n\nexport const parseIdFromUrl = (url: string): number => {\n if (!url) return null;\n\n const parts = url.split('/');\n // Detect language prefix like /en/ or /sk/\n const hasLangPrefix = LANG_PREFIX_REGEX.test(parts[1]);\n const idSlug = parts[hasLangPrefix ? 3 : 2];\n const id = idSlug?.split('-')[0];\n return +id || null;\n};\n\nexport const getColor = (cls: string): CSFDColorRating => {\n switch (cls) {\n case 'page-lightgrey':\n return 'unknown';\n case 'page-red':\n return 'good';\n case 'page-blue':\n return 'average';\n case 'page-grey':\n return 'bad';\n default:\n return 'unknown';\n }\n};\n\nexport const parseColor = (quality: CSFDColors): CSFDColorRating => {\n switch (quality) {\n case 'lightgrey':\n return 'unknown';\n case 'red':\n return 'good';\n case 'blue':\n return 'average';\n case 'grey':\n return 'bad';\n default:\n return 'unknown';\n }\n};\n\nconst filmTypeMap: Record<string, CSFDFilmTypes> = {\n 'TV film': 'tv-film',\n pořad: 'tv-show',\n seriál: 'series',\n 'divadelní záznam': 'theatrical',\n koncert: 'concert',\n série: 'season',\n 'studentský film': 'student-film',\n 'amatérský film': 'amateur-film',\n 'hudební videoklip': 'music-video',\n epizoda: 'episode',\n 'video kompilace': 'video-compilation',\n film: 'film'\n};\n\nexport const parseFilmType = (type: string): CSFDFilmTypes => {\n return filmTypeMap[type] || 'film';\n};\n\nexport const addProtocol = (url: string): string => {\n return url.startsWith('//') ? 'https:' + url : url;\n};\n\nexport const getDuration = (matches: RegExpMatchArray) => {\n return {\n sign: matches[1] === undefined ? '+' : '-',\n years: matches[2] === undefined ? 0 : matches[2],\n months: matches[3] === undefined ? 0 : matches[3],\n weeks: matches[4] === undefined ? 0 : matches[4],\n days: matches[5] === undefined ? 0 : matches[5],\n hours: matches[6] === undefined ? 0 : matches[6],\n minutes: matches[7] === undefined ? 0 : matches[7],\n seconds: matches[8] === undefined ? 0 : matches[8]\n };\n};\n\nexport const parseISO8601Duration = (iso: string): number => {\n const matches = iso.match(ISO8601_DURATION_REGEX);\n\n const duration = getDuration(matches);\n\n return +duration.hours * 60 + +duration.minutes;\n};\n\n/**\n * Parses a date string into a standardized YYYY-MM-DD format.\n * Supports:\n * - D.M.YYYY\n * - DD.MM.YYYY\n * - D. M. YYYY\n * - MM/DD/YYYY\n * - YYYY\n */\nexport const parseDate = (date: string): string | null => {\n if (!date) return null;\n\n // Clean the input\n const cleanDate = date.trim();\n\n // Try parsing DD.MM.YYYY or D.M.YYYY with optional spaces\n const dateMatch = cleanDate.match(/^(\\d{1,2})\\.\\s*(\\d{1,2})\\.\\s*(\\d{4})$/);\n if (dateMatch) {\n const day = dateMatch[1].padStart(2, '0');\n const month = dateMatch[2].padStart(2, '0');\n const year = dateMatch[3];\n return `${year}-${month}-${day}`;\n }\n\n // Try parsing MM/DD/YYYY\n const slashMatch = cleanDate.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\n if (slashMatch) {\n const month = slashMatch[1].padStart(2, '0');\n const day = slashMatch[2].padStart(2, '0');\n const year = slashMatch[3];\n return `${year}-${month}-${day}`;\n }\n\n // Try parsing YYYY\n const yearMatch = cleanDate.match(/^(\\d{4})$/);\n if (yearMatch) {\n return `${yearMatch[1]}-01-01`;\n }\n\n return null;\n};\n\n// Sleep in loop\nexport const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));\n"],"mappings":";AAGA,MAAM,oBAAoB;AAC1B,MAAM,yBACJ;AAEF,MAAa,kBAAkB,QAAwB;AACrD,KAAI,CAAC,IAAK,QAAO;CAEjB,MAAM,QAAQ,IAAI,MAAM,IAAI;AAK5B,QAAO,CAFQ,MADO,kBAAkB,KAAK,MAAM,GAAG,GACjB,IAAI,IACtB,MAAM,IAAI,CAAC,MAChB;;AAGhB,MAAa,YAAY,QAAiC;AACxD,SAAQ,KAAR;EACE,KAAK,iBACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAa,cAAc,YAAyC;AAClE,SAAQ,SAAR;EACE,KAAK,YACH,QAAO;EACT,KAAK,MACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAM,cAA6C;CACjD,WAAW;CACX,OAAO;CACP,QAAQ;CACR,oBAAoB;CACpB,SAAS;CACT,OAAO;CACP,mBAAmB;CACnB,kBAAkB;CAClB,qBAAqB;CACrB,SAAS;CACT,mBAAmB;CACnB,MAAM;CACP;AAED,MAAa,iBAAiB,SAAgC;AAC5D,QAAO,YAAY,SAAS;;AAG9B,MAAa,eAAe,QAAwB;AAClD,QAAO,IAAI,WAAW,KAAK,GAAG,WAAW,MAAM;;AAGjD,MAAa,eAAe,YAA8B;AACxD,QAAO;EACL,MAAM,QAAQ,OAAO,SAAY,MAAM;EACvC,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,QAAQ,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC/C,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,MAAM,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC7C,OAAO,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAC9C,SAAS,QAAQ,OAAO,SAAY,IAAI,QAAQ;EAChD,SAAS,QAAQ,OAAO,SAAY,IAAI,QAAQ;EACjD;;AAGH,MAAa,wBAAwB,QAAwB;CAG3D,MAAM,WAAW,YAFD,IAAI,MAAM,uBAAuB,CAEZ;AAErC,QAAO,CAAC,SAAS,QAAQ,KAAK,CAAC,SAAS;;;;;;;;;;;AAY1C,MAAa,aAAa,SAAgC;AACxD,KAAI,CAAC,KAAM,QAAO;CAGlB,MAAM,YAAY,KAAK,MAAM;CAG7B,MAAM,YAAY,UAAU,MAAM,wCAAwC;AAC1E,KAAI,WAAW;EACb,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI;EACzC,MAAM,QAAQ,UAAU,GAAG,SAAS,GAAG,IAAI;AAE3C,SAAO,GADM,UAAU,GACR,GAAG,MAAM,GAAG;;CAI7B,MAAM,aAAa,UAAU,MAAM,kCAAkC;AACrE,KAAI,YAAY;EACd,MAAM,QAAQ,WAAW,GAAG,SAAS,GAAG,IAAI;EAC5C,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,IAAI;AAE1C,SAAO,GADM,WAAW,GACT,GAAG,MAAM,GAAG;;CAI7B,MAAM,YAAY,UAAU,MAAM,YAAY;AAC9C,KAAI,UACF,QAAO,GAAG,UAAU,GAAG;AAGzB,QAAO;;AAIT,MAAa,SAAS,OAAe,IAAI,SAAS,QAAQ,WAAW,KAAK,GAAG,CAAC"}
@@ -57,25 +57,6 @@ const CREATOR_LABELS = {
57
57
  const getLocalizedCreatorLabel = (language, key) => {
58
58
  return (CREATOR_LABELS[language || "cs"] || CREATOR_LABELS["cs"])[key];
59
59
  };
60
- const getSeriesAndSeasonTitle = (el) => {
61
- const titleElement = el.querySelector("h1");
62
- if (!titleElement) return {
63
- seriesName: null,
64
- seasonName: null
65
- };
66
- const fullText = titleElement.innerText.trim();
67
- if (fullText.includes(" - ")) {
68
- const [seriesName, seasonName] = fullText.split(" - ").map((part) => part.trim());
69
- return {
70
- seriesName,
71
- seasonName
72
- };
73
- }
74
- return {
75
- seriesName: fullText,
76
- seasonName: null
77
- };
78
- };
79
60
  const getMovieTitle = (el) => {
80
61
  return el.querySelector("h1").innerText.split(`(`)[0].trim();
81
62
  };
@@ -196,65 +177,6 @@ const getMovieCreators = (el, options) => {
196
177
  }
197
178
  return creators;
198
179
  };
199
- const getSeasonsOrEpisodes = (el, serie) => {
200
- const childrenList = el.querySelector(".film-episodes-list");
201
- if (!childrenList) return null;
202
- const childrenNodes = childrenList.querySelectorAll(".film-title");
203
- if (!childrenNodes?.length) return [];
204
- return childrenNodes.map((season) => {
205
- const nameContainer = season.querySelector(".film-title-name");
206
- const infoContainer = season.querySelector(".info");
207
- const href = nameContainer?.getAttribute("href");
208
- const url = href ? href.startsWith("/") ? `https://www.csfd.cz${href}` : href : null;
209
- return {
210
- id: require_global_helper.parseLastIdFromUrl(href || ""),
211
- title: nameContainer?.textContent?.trim() || null,
212
- url,
213
- info: infoContainer?.textContent?.replace(/[{()}]/g, "").trim() || null
214
- };
215
- });
216
- };
217
- const getEpisodeCode = (el) => {
218
- const filmHeaderName = el.querySelector(".film-header-name h1");
219
- if (!filmHeaderName) return null;
220
- const match = (filmHeaderName.textContent?.trim() || "").match(/\(([^)]+)\)/);
221
- return match ? match[1] : null;
222
- };
223
- const detectSeasonOrEpisodeListType = (el) => {
224
- const headerText = el.querySelector(".box-header h3")?.innerText.trim() ?? "";
225
- if (headerText.includes("Série")) return "seasons";
226
- if (headerText.startsWith("Epizody")) return "episodes";
227
- return null;
228
- };
229
- const getSeasonOrEpisodeParent = (el, serie) => {
230
- let parents = el.querySelectorAll(".film-header h2 a");
231
- if (parents.length === 0) parents = el.querySelectorAll(".film-header h1 a");
232
- if (parents.length === 0) {
233
- if (!serie) return null;
234
- return {
235
- series: serie,
236
- season: null
237
- };
238
- }
239
- const [parentSeries, parentSeason] = parents;
240
- const seriesId = require_global_helper.parseIdFromUrl(parentSeries?.getAttribute("href"));
241
- const seasonId = require_global_helper.parseLastIdFromUrl(parentSeason?.getAttribute("href") || "");
242
- const seriesTitle = parentSeries?.textContent?.trim() || null;
243
- const seasonTitle = parentSeason?.textContent?.trim() || null;
244
- const series = seriesId && seriesTitle ? {
245
- id: seriesId,
246
- title: seriesTitle
247
- } : null;
248
- const season = seasonId && seasonTitle ? {
249
- id: seasonId,
250
- title: seasonTitle
251
- } : null;
252
- if (!series && !season) return null;
253
- return {
254
- series,
255
- season
256
- };
257
- };
258
180
  const getMovieType = (el) => {
259
181
  return require_global_helper.parseFilmType(el.querySelector(".film-header-name .type")?.innerText?.replace(/[{()}]/g, "") || "film");
260
182
  };
@@ -304,8 +226,6 @@ const getMovieTags = (el) => {
304
226
  };
305
227
 
306
228
  //#endregion
307
- exports.detectSeasonOrEpisodeListType = detectSeasonOrEpisodeListType;
308
- exports.getEpisodeCode = getEpisodeCode;
309
229
  exports.getMovieBoxMovies = getMovieBoxMovies;
310
230
  exports.getMovieColorRating = getMovieColorRating;
311
231
  exports.getMovieCreators = getMovieCreators;
@@ -325,7 +245,4 @@ exports.getMovieTrivia = getMovieTrivia;
325
245
  exports.getMovieType = getMovieType;
326
246
  exports.getMovieVods = getMovieVods;
327
247
  exports.getMovieYear = getMovieYear;
328
- exports.getSeasonOrEpisodeParent = getSeasonOrEpisodeParent;
329
- exports.getSeasonsOrEpisodes = getSeasonsOrEpisodes;
330
- exports.getSeriesAndSeasonTitle = getSeriesAndSeasonTitle;
331
248
  //# sourceMappingURL=movie.helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"movie.helper.js","names":["getColor","parseISO8601Duration","addProtocol","parseIdFromUrl","parseLastIdFromUrl","parseFilmType","parseDate"],"sources":["../../src/helpers/movie.helper.ts"],"sourcesContent":["import { HTMLElement } from 'node-html-parser';\nimport { CSFDColorRating, CSFDFilmTypes } from '../dto/global';\nimport {\n CSFDBoxContent,\n CSFDCreatorGroups,\n CSFDCreatorGroupsEnglish,\n CSFDCreatorGroupsSlovak,\n CSFDCreators,\n CSFDGenres,\n CSFDMovieCreator,\n CSFDMovieListItem,\n CSFDParent,\n CSFDPremiere,\n CSFDSeriesChild,\n CSFDTitlesOther,\n CSFDVod,\n CSFDVodService,\n MovieJsonLd\n} from '../dto/movie';\nimport { CSFDOptions } from '../types';\nimport {\n addProtocol,\n getColor,\n parseDate,\n parseFilmType,\n parseISO8601Duration,\n parseIdFromUrl,\n parseLastIdFromUrl\n} from './global.helper';\n\nconst CREATOR_LABELS: Record<\n string,\n Record<string, CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak>\n> = {\n en: {\n directors: 'Directed by',\n writers: 'Screenplay',\n cinematography: 'Cinematography',\n music: 'Composer',\n actors: 'Cast',\n basedOn: 'Based on',\n producers: 'Produced by',\n filmEditing: 'Editing',\n costumeDesign: 'Costumes',\n productionDesign: 'Production design',\n casting: 'Casting',\n sound: 'Sound',\n makeup: 'Make-up'\n },\n cs: {\n directors: 'Režie',\n writers: 'Scénář',\n cinematography: 'Kamera',\n music: 'Hudba',\n actors: 'Hrají',\n basedOn: 'Předloha',\n producers: 'Produkce',\n filmEditing: 'Střih',\n costumeDesign: 'Kostýmy',\n productionDesign: 'Scénografie',\n casting: 'Casting',\n sound: 'Zvuk',\n makeup: 'Masky'\n },\n sk: {\n directors: 'Réžia',\n writers: 'Scenár',\n cinematography: 'Kamera',\n music: 'Hudba',\n actors: 'Hrajú',\n basedOn: 'Predloha',\n producers: 'Produkcia',\n filmEditing: 'Strih',\n costumeDesign: 'Kostýmy',\n productionDesign: 'Scénografia',\n casting: 'Casting',\n sound: 'Zvuk',\n makeup: 'Masky'\n }\n};\n\n/**\n * Maps language-specific movie creator group labels.\n * @param language - The language code (e.g., 'en', 'cs')\n * @param key - The key of the creator group (e.g., 'directors', 'writers')\n * @returns The localized label for the creator group\n */\nexport const getLocalizedCreatorLabel = (\n language: string | undefined,\n key:\n | 'directors'\n | 'writers'\n | 'cinematography'\n | 'music'\n | 'actors'\n | 'basedOn'\n | 'producers'\n | 'filmEditing'\n | 'costumeDesign'\n | 'productionDesign'\n | 'casting'\n | 'sound'\n | 'makeup'\n): CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak => {\n const lang = language || 'cs'; // Default to Czech\n return (CREATOR_LABELS[lang] || CREATOR_LABELS['cs'])[key];\n};\n\nexport const getMovieId = (el: HTMLElement): number => {\n const url = el.querySelector('.tabs .tab-nav-list a').attributes.href;\n return parseIdFromUrl(url);\n};\n\nexport const getSeriesAndSeasonTitle = (\n el: HTMLElement\n): { seriesName: string | null; seasonName: string | null } => {\n const titleElement = el.querySelector('h1');\n if (!titleElement) {\n return { seriesName: null, seasonName: null };\n }\n\n const fullText = titleElement.innerText.trim();\n\n // Check if there's a series part indicated by ' - '\n if (fullText.includes(' - ')) {\n const [seriesName, seasonName] = fullText.split(' - ').map((part) => part.trim());\n return { seriesName, seasonName };\n }\n\n // If no series part found, return just the name\n return { seriesName: fullText, seasonName: null };\n};\n\nexport const getMovieTitle = (el: HTMLElement): string => {\n return el.querySelector('h1').innerText.split(`(`)[0].trim();\n};\n\nexport const getMovieGenres = (el: HTMLElement): CSFDGenres[] => {\n const genresRaw = el.querySelector('.genres').textContent;\n return genresRaw.split(' / ') as CSFDGenres[];\n};\n\nexport const getMovieOrigins = (el: HTMLElement): string[] => {\n const originsRaw = el.querySelector('.origin').textContent;\n const origins = originsRaw.split(',')[0];\n return origins.split(' / ');\n};\n\nexport const getMovieColorRating = (bodyClasses: string[]): CSFDColorRating => {\n return getColor(bodyClasses[1]);\n};\n\nexport const getMovieRating = (el: HTMLElement): number => {\n const ratingRaw = el.querySelector('.film-rating-average').textContent;\n const rating = ratingRaw?.replace(/%/g, '').trim();\n const ratingInt = parseInt(rating);\n\n if (Number.isInteger(ratingInt)) {\n return ratingInt;\n } else {\n return null;\n }\n};\n\nexport const getMovieRatingCount = (el: HTMLElement): number => {\n const ratingCountRaw = el.querySelector('.box-rating-container .counter')?.textContent;\n const ratingCount = +ratingCountRaw?.replace(/[(\\s)]/g, '');\n if (Number.isInteger(ratingCount)) {\n return ratingCount;\n } else {\n return null;\n }\n};\n\nexport const getMovieYear = (jsonLd: MovieJsonLd | null): number => {\n if (jsonLd && jsonLd.dateCreated) {\n return +jsonLd.dateCreated;\n }\n return null;\n};\n\nexport const getMovieDuration = (jsonLd: MovieJsonLd | null, el: HTMLElement): number => {\n if (jsonLd && jsonLd.duration) {\n try {\n return parseISO8601Duration(jsonLd.duration);\n } catch (e) {\n // ignore\n }\n }\n\n try {\n const origin = el.querySelector('.origin').innerText;\n const timeString = origin.split(',');\n if (timeString.length > 2) {\n // Get last time elelment\n const timeString2 = timeString.pop().trim();\n // Clean it\n const timeRaw = timeString2.split('(')[0].trim();\n // Split by minutes and hours\n const hoursMinsRaw = timeRaw.split('min')[0];\n const hoursMins = hoursMinsRaw.split('h');\n // Resolve hours + minutes format\n const duration = hoursMins.length > 1 ? +hoursMins[0] * 60 + +hoursMins[1] : +hoursMins[0];\n return duration;\n } else {\n return null;\n }\n } catch (error) {\n return null;\n }\n};\n\nexport const getMovieTitlesOther = (el: HTMLElement): CSFDTitlesOther[] => {\n const namesNode = el.querySelectorAll('.film-names li');\n\n if (!namesNode.length) {\n return [];\n }\n\n const titlesOther = namesNode.map((el) => {\n const country = el.querySelector('img.flag').attributes.alt;\n const title = el.textContent.trim().split('\\n')[0];\n\n if (country && title) {\n return {\n country,\n title\n };\n } else {\n return null;\n }\n });\n\n return titlesOther.filter((x) => x);\n};\n\nexport const getMoviePoster = (el: HTMLElement | null): string => {\n const poster = el.querySelector('.film-posters img');\n // Resolve empty image\n if (poster) {\n if (poster.classNames?.includes('empty-image')) {\n return null;\n } else {\n // Full sized image (not thumb)\n const imageThumb = poster.attributes.src.split('?')[0];\n const image = imageThumb.replace(/\\/w140\\//, '/w1080/');\n return addProtocol(image);\n }\n } else {\n return null;\n }\n};\n\nexport const getMovieRandomPhoto = (el: HTMLElement | null): string => {\n const imageNode = el.querySelector('.gallery-item picture img');\n const image = imageNode?.attributes?.src;\n if (image) {\n return image.replace(/\\/w663\\//, '/w1326/');\n } else {\n return null;\n }\n};\n\nexport const getMovieTrivia = (el: HTMLElement | null): string[] => {\n const triviaNodes = el.querySelectorAll('.article-trivia ul li');\n if (triviaNodes?.length) {\n return triviaNodes.map((node) => node.textContent.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm, ''));\n } else {\n return null;\n }\n};\n\nexport const getMovieDescriptions = (el: HTMLElement): string[] => {\n return el\n .querySelectorAll('.body--plots .plot-full p, .body--plots .plots .plots-item p')\n .map((movie) => movie.textContent?.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm, ''));\n};\n\nconst parseMoviePeople = (el: HTMLElement): CSFDMovieCreator[] => {\n const people = el.querySelectorAll('a');\n return (\n people\n // Filter out \"more\" links\n .filter((x) => x.classNames.length === 0)\n .map((person) => {\n return {\n id: parseIdFromUrl(person.attributes.href),\n name: person.innerText.trim(),\n url: `https://www.csfd.cz${person.attributes.href}`\n };\n })\n );\n};\n\n// export const getMovieGroup = (el: HTMLElement, group: CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak): CSFDMovieCreator[] => {\n// const creators = el.querySelectorAll('.creators h4');\n// const element = creators.filter((elem) => elem.textContent.trim().includes(group))[0];\n// if (element?.parentNode) {\n// return parseMoviePeople(element.parentNode as HTMLElement);\n// } else {\n// return [];\n// }\n// };\n\nexport const getMovieCreators = (el: HTMLElement, options?: CSFDOptions): CSFDCreators => {\n const creators: CSFDCreators = {\n directors: [],\n writers: [],\n cinematography: [],\n music: [],\n actors: [],\n basedOn: [],\n producers: [],\n filmEditing: [],\n costumeDesign: [],\n productionDesign: []\n };\n\n const groups = el.querySelectorAll('.creators h4');\n\n const keys = [\n 'directors',\n 'writers',\n 'cinematography',\n 'music',\n 'actors',\n 'basedOn',\n 'producers',\n 'filmEditing',\n 'costumeDesign',\n 'productionDesign'\n ] as const;\n\n const localizedLabels = keys.map((key) => ({\n key,\n label: getLocalizedCreatorLabel(options?.language, key) as string\n }));\n\n for (const group of groups) {\n const text = group.textContent.trim();\n for (const { key, label } of localizedLabels) {\n if (text.includes(label)) {\n if (group.parentNode) {\n creators[key] = parseMoviePeople(group.parentNode as HTMLElement);\n }\n break;\n }\n }\n }\n\n return creators;\n};\n\nexport const getSeasonsOrEpisodes = (\n el: HTMLElement,\n serie?: { id: number; title: string }\n): CSFDSeriesChild[] | null => {\n const childrenList = el.querySelector('.film-episodes-list');\n if (!childrenList) return null;\n\n const childrenNodes = childrenList.querySelectorAll('.film-title');\n if (!childrenNodes?.length) return [];\n\n return childrenNodes.map((season) => {\n const nameContainer = season.querySelector('.film-title-name');\n const infoContainer = season.querySelector('.info');\n\n const href = nameContainer?.getAttribute('href');\n const url = href ? (href.startsWith('/') ? `https://www.csfd.cz${href}` : href) : null;\n\n return {\n id: parseLastIdFromUrl(href || ''),\n title: nameContainer?.textContent?.trim() || null,\n url,\n info: infoContainer?.textContent?.replace(/[{()}]/g, '').trim() || null\n };\n });\n};\n\nexport const getEpisodeCode = (el: HTMLElement): string | null => {\n const filmHeaderName = el.querySelector('.film-header-name h1');\n if (!filmHeaderName) return null;\n\n const text = filmHeaderName.textContent?.trim() || '';\n const match = text.match(/\\(([^)]+)\\)/);\n const code = match ? match[1] : null;\n\n return code;\n};\n\nexport const detectSeasonOrEpisodeListType = (el: HTMLElement) => {\n const headerText = el.querySelector('.box-header h3')?.innerText.trim() ?? '';\n\n if (headerText.includes('Série')) return 'seasons';\n if (headerText.startsWith('Epizody')) return 'episodes';\n return null;\n};\n\nexport const getSeasonOrEpisodeParent = (\n el: HTMLElement,\n serie?: { id: number; title: string }\n): CSFDParent | null => {\n // Try h2 first (for episodes), then h1 (for seasons)\n let parents = el.querySelectorAll('.film-header h2 a');\n if (parents.length === 0) {\n parents = el.querySelectorAll('.film-header h1 a');\n }\n\n if (parents.length === 0) {\n if (!serie) return null;\n return { series: serie, season: null };\n }\n\n const [parentSeries, parentSeason] = parents;\n\n const seriesId = parseIdFromUrl(parentSeries?.getAttribute('href'));\n const seasonId = parseLastIdFromUrl(parentSeason?.getAttribute('href') || '');\n const seriesTitle = parentSeries?.textContent?.trim() || null;\n const seasonTitle = parentSeason?.textContent?.trim() || null;\n\n const series = seriesId && seriesTitle ? { id: seriesId, title: seriesTitle } : null;\n const season = seasonId && seasonTitle ? { id: seasonId, title: seasonTitle } : null;\n\n if (!series && !season) return null;\n\n return { series, season };\n};\n\nexport const getMovieGroup = (\n el: HTMLElement,\n group: CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak\n): CSFDMovieCreator[] => {\n const creators = el.querySelectorAll('.creators h4');\n const element = creators.filter((elem) => elem.textContent.trim().includes(group))[0];\n if (element?.parentNode) {\n return parseMoviePeople(element.parentNode as HTMLElement);\n } else {\n return [];\n }\n};\n\nexport const getMovieType = (el: HTMLElement): CSFDFilmTypes => {\n const type = el.querySelector('.film-header-name .type');\n return parseFilmType(type?.innerText?.replace(/[{()}]/g, '') || 'film');\n};\n\nexport const getMovieVods = (el: HTMLElement | null): CSFDVod[] => {\n let vods: CSFDVod[] = [];\n if (el) {\n const buttonsVod = el.querySelectorAll('.box-buttons-vod .vod-badge a');\n vods = buttonsVod.map((btn) => {\n return {\n title: btn.textContent.trim() as CSFDVodService,\n url: btn.attributes.href\n };\n });\n }\n return vods.length ? vods : [];\n};\n\n// Get box content\nconst getBoxContent = (el: HTMLElement, box: string): HTMLElement => {\n const headers = el.querySelectorAll('section.box .box-header');\n return headers.find((header) => header.querySelector('h3')?.textContent.trim().includes(box))\n ?.parentNode;\n};\n\nexport const getMovieBoxMovies = (\n el: HTMLElement,\n boxName: CSFDBoxContent\n): CSFDMovieListItem[] => {\n const movieListItem: CSFDMovieListItem[] = [];\n const box = getBoxContent(el, boxName);\n const movieTitleNodes = box?.querySelectorAll('.article-header .film-title-name');\n if (movieTitleNodes?.length) {\n for (const item of movieTitleNodes) {\n movieListItem.push({\n id: parseIdFromUrl(item.attributes.href),\n title: item.textContent.trim(),\n url: `https://www.csfd.cz${item.attributes.href}`\n });\n }\n }\n return movieListItem;\n};\n\nexport const getMoviePremieres = (el: HTMLElement): CSFDPremiere[] => {\n const premiereNodes = el.querySelectorAll('.box-premieres li');\n const premiere: CSFDPremiere[] = [];\n for (const premiereNode of premiereNodes) {\n const title = premiereNode.querySelector('p + span').attributes.title;\n\n if (title) {\n const [dateRaw, ...company] = title?.split(' ');\n const date = parseDate(dateRaw);\n\n if (date) {\n premiere.push({\n country: premiereNode.querySelector('.flag')?.attributes.title || null,\n format: premiereNode.querySelector('p').textContent.trim()?.split(' od')[0],\n date,\n company: company.join(' ')\n });\n }\n }\n }\n return premiere;\n};\n\nexport const getMovieTags = (el: HTMLElement): string[] => {\n const tagsRaw = el.querySelectorAll('.box-content a[href*=\"/tag/\"]');\n return tagsRaw.map((tag) => tag.textContent);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"movie.helper.js","names":["getColor","parseISO8601Duration","addProtocol","parseIdFromUrl","parseFilmType","parseDate"],"sources":["../../src/helpers/movie.helper.ts"],"sourcesContent":["import { HTMLElement } from 'node-html-parser';\nimport { CSFDColorRating, CSFDFilmTypes } from '../dto/global';\nimport {\n CSFDBoxContent,\n CSFDCreatorGroups,\n CSFDCreatorGroupsEnglish,\n CSFDCreatorGroupsSlovak,\n CSFDCreators,\n CSFDGenres,\n CSFDMovieCreator,\n CSFDMovieListItem,\n CSFDPremiere,\n CSFDTitlesOther,\n CSFDVod,\n CSFDVodService,\n MovieJsonLd\n} from '../dto/movie';\nimport { CSFDOptions } from '../types';\nimport {\n addProtocol,\n getColor,\n parseDate,\n parseFilmType,\n parseISO8601Duration,\n parseIdFromUrl\n} from './global.helper';\n\nconst CREATOR_LABELS: Record<\n string,\n Record<string, CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak>\n> = {\n en: {\n directors: 'Directed by',\n writers: 'Screenplay',\n cinematography: 'Cinematography',\n music: 'Composer',\n actors: 'Cast',\n basedOn: 'Based on',\n producers: 'Produced by',\n filmEditing: 'Editing',\n costumeDesign: 'Costumes',\n productionDesign: 'Production design',\n casting: 'Casting',\n sound: 'Sound',\n makeup: 'Make-up'\n },\n cs: {\n directors: 'Režie',\n writers: 'Scénář',\n cinematography: 'Kamera',\n music: 'Hudba',\n actors: 'Hrají',\n basedOn: 'Předloha',\n producers: 'Produkce',\n filmEditing: 'Střih',\n costumeDesign: 'Kostýmy',\n productionDesign: 'Scénografie',\n casting: 'Casting',\n sound: 'Zvuk',\n makeup: 'Masky'\n },\n sk: {\n directors: 'Réžia',\n writers: 'Scenár',\n cinematography: 'Kamera',\n music: 'Hudba',\n actors: 'Hrajú',\n basedOn: 'Predloha',\n producers: 'Produkcia',\n filmEditing: 'Strih',\n costumeDesign: 'Kostýmy',\n productionDesign: 'Scénografia',\n casting: 'Casting',\n sound: 'Zvuk',\n makeup: 'Masky'\n }\n};\n\n/**\n * Maps language-specific movie creator group labels.\n * @param language - The language code (e.g., 'en', 'cs')\n * @param key - The key of the creator group (e.g., 'directors', 'writers')\n * @returns The localized label for the creator group\n */\nexport const getLocalizedCreatorLabel = (\n language: string | undefined,\n key:\n | 'directors'\n | 'writers'\n | 'cinematography'\n | 'music'\n | 'actors'\n | 'basedOn'\n | 'producers'\n | 'filmEditing'\n | 'costumeDesign'\n | 'productionDesign'\n | 'casting'\n | 'sound'\n | 'makeup'\n): CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak => {\n const lang = language || 'cs'; // Default to Czech\n return (CREATOR_LABELS[lang] || CREATOR_LABELS['cs'])[key];\n};\n\nexport const getMovieId = (el: HTMLElement): number => {\n const url = el.querySelector('.tabs .tab-nav-list a').attributes.href;\n return parseIdFromUrl(url);\n};\n\nexport const getMovieTitle = (el: HTMLElement): string => {\n return el.querySelector('h1').innerText.split(`(`)[0].trim();\n};\n\nexport const getMovieGenres = (el: HTMLElement): CSFDGenres[] => {\n const genresRaw = el.querySelector('.genres').textContent;\n return genresRaw.split(' / ') as CSFDGenres[];\n};\n\nexport const getMovieOrigins = (el: HTMLElement): string[] => {\n const originsRaw = el.querySelector('.origin').textContent;\n const origins = originsRaw.split(',')[0];\n return origins.split(' / ');\n};\n\nexport const getMovieColorRating = (bodyClasses: string[]): CSFDColorRating => {\n return getColor(bodyClasses[1]);\n};\n\nexport const getMovieRating = (el: HTMLElement): number => {\n const ratingRaw = el.querySelector('.film-rating-average').textContent;\n const rating = ratingRaw?.replace(/%/g, '').trim();\n const ratingInt = parseInt(rating);\n\n if (Number.isInteger(ratingInt)) {\n return ratingInt;\n } else {\n return null;\n }\n};\n\nexport const getMovieRatingCount = (el: HTMLElement): number => {\n const ratingCountRaw = el.querySelector('.box-rating-container .counter')?.textContent;\n const ratingCount = +ratingCountRaw?.replace(/[(\\s)]/g, '');\n if (Number.isInteger(ratingCount)) {\n return ratingCount;\n } else {\n return null;\n }\n};\n\nexport const getMovieYear = (jsonLd: MovieJsonLd | null): number => {\n if (jsonLd && jsonLd.dateCreated) {\n return +jsonLd.dateCreated;\n }\n return null;\n};\n\nexport const getMovieDuration = (jsonLd: MovieJsonLd | null, el: HTMLElement): number => {\n if (jsonLd && jsonLd.duration) {\n try {\n return parseISO8601Duration(jsonLd.duration);\n } catch (e) {\n // ignore\n }\n }\n\n try {\n const origin = el.querySelector('.origin').innerText;\n const timeString = origin.split(',');\n if (timeString.length > 2) {\n // Get last time elelment\n const timeString2 = timeString.pop().trim();\n // Clean it\n const timeRaw = timeString2.split('(')[0].trim();\n // Split by minutes and hours\n const hoursMinsRaw = timeRaw.split('min')[0];\n const hoursMins = hoursMinsRaw.split('h');\n // Resolve hours + minutes format\n const duration = hoursMins.length > 1 ? +hoursMins[0] * 60 + +hoursMins[1] : +hoursMins[0];\n return duration;\n } else {\n return null;\n }\n } catch (error) {\n return null;\n }\n};\n\nexport const getMovieTitlesOther = (el: HTMLElement): CSFDTitlesOther[] => {\n const namesNode = el.querySelectorAll('.film-names li');\n\n if (!namesNode.length) {\n return [];\n }\n\n const titlesOther = namesNode.map((el) => {\n const country = el.querySelector('img.flag').attributes.alt;\n const title = el.textContent.trim().split('\\n')[0];\n\n if (country && title) {\n return {\n country,\n title\n };\n } else {\n return null;\n }\n });\n\n return titlesOther.filter((x) => x);\n};\n\nexport const getMoviePoster = (el: HTMLElement | null): string => {\n const poster = el.querySelector('.film-posters img');\n // Resolve empty image\n if (poster) {\n if (poster.classNames?.includes('empty-image')) {\n return null;\n } else {\n // Full sized image (not thumb)\n const imageThumb = poster.attributes.src.split('?')[0];\n const image = imageThumb.replace(/\\/w140\\//, '/w1080/');\n return addProtocol(image);\n }\n } else {\n return null;\n }\n};\n\nexport const getMovieRandomPhoto = (el: HTMLElement | null): string => {\n const imageNode = el.querySelector('.gallery-item picture img');\n const image = imageNode?.attributes?.src;\n if (image) {\n return image.replace(/\\/w663\\//, '/w1326/');\n } else {\n return null;\n }\n};\n\nexport const getMovieTrivia = (el: HTMLElement | null): string[] => {\n const triviaNodes = el.querySelectorAll('.article-trivia ul li');\n if (triviaNodes?.length) {\n return triviaNodes.map((node) => node.textContent.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm, ''));\n } else {\n return null;\n }\n};\n\nexport const getMovieDescriptions = (el: HTMLElement): string[] => {\n return el\n .querySelectorAll('.body--plots .plot-full p, .body--plots .plots .plots-item p')\n .map((movie) => movie.textContent?.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm, ''));\n};\n\nconst parseMoviePeople = (el: HTMLElement): CSFDMovieCreator[] => {\n const people = el.querySelectorAll('a');\n return (\n people\n // Filter out \"more\" links\n .filter((x) => x.classNames.length === 0)\n .map((person) => {\n return {\n id: parseIdFromUrl(person.attributes.href),\n name: person.innerText.trim(),\n url: `https://www.csfd.cz${person.attributes.href}`\n };\n })\n );\n};\n\n// export const getMovieGroup = (el: HTMLElement, group: CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak): CSFDMovieCreator[] => {\n// const creators = el.querySelectorAll('.creators h4');\n// const element = creators.filter((elem) => elem.textContent.trim().includes(group))[0];\n// if (element?.parentNode) {\n// return parseMoviePeople(element.parentNode as HTMLElement);\n// } else {\n// return [];\n// }\n// };\n\nexport const getMovieCreators = (el: HTMLElement, options?: CSFDOptions): CSFDCreators => {\n const creators: CSFDCreators = {\n directors: [],\n writers: [],\n cinematography: [],\n music: [],\n actors: [],\n basedOn: [],\n producers: [],\n filmEditing: [],\n costumeDesign: [],\n productionDesign: []\n };\n\n const groups = el.querySelectorAll('.creators h4');\n\n const keys = [\n 'directors',\n 'writers',\n 'cinematography',\n 'music',\n 'actors',\n 'basedOn',\n 'producers',\n 'filmEditing',\n 'costumeDesign',\n 'productionDesign'\n ] as const;\n\n const localizedLabels = keys.map((key) => ({\n key,\n label: getLocalizedCreatorLabel(options?.language, key) as string\n }));\n\n for (const group of groups) {\n const text = group.textContent.trim();\n for (const { key, label } of localizedLabels) {\n if (text.includes(label)) {\n if (group.parentNode) {\n creators[key] = parseMoviePeople(group.parentNode as HTMLElement);\n }\n break;\n }\n }\n }\n\n return creators;\n};\n\nexport const getMovieType = (el: HTMLElement): CSFDFilmTypes => {\n const type = el.querySelector('.film-header-name .type');\n return parseFilmType(type?.innerText?.replace(/[{()}]/g, '') || 'film');\n};\n\nexport const getMovieVods = (el: HTMLElement | null): CSFDVod[] => {\n let vods: CSFDVod[] = [];\n if (el) {\n const buttonsVod = el.querySelectorAll('.box-buttons-vod .vod-badge a');\n vods = buttonsVod.map((btn) => {\n return {\n title: btn.textContent.trim() as CSFDVodService,\n url: btn.attributes.href\n };\n });\n }\n return vods.length ? vods : [];\n};\n\n// Get box content\nconst getBoxContent = (el: HTMLElement, box: string): HTMLElement => {\n const headers = el.querySelectorAll('section.box .box-header');\n return headers.find((header) => header.querySelector('h3')?.textContent.trim().includes(box))\n ?.parentNode;\n};\n\nexport const getMovieBoxMovies = (\n el: HTMLElement,\n boxName: CSFDBoxContent\n): CSFDMovieListItem[] => {\n const movieListItem: CSFDMovieListItem[] = [];\n const box = getBoxContent(el, boxName);\n const movieTitleNodes = box?.querySelectorAll('.article-header .film-title-name');\n if (movieTitleNodes?.length) {\n for (const item of movieTitleNodes) {\n movieListItem.push({\n id: parseIdFromUrl(item.attributes.href),\n title: item.textContent.trim(),\n url: `https://www.csfd.cz${item.attributes.href}`\n });\n }\n }\n return movieListItem;\n};\n\nexport const getMoviePremieres = (el: HTMLElement): CSFDPremiere[] => {\n const premiereNodes = el.querySelectorAll('.box-premieres li');\n const premiere: CSFDPremiere[] = [];\n for (const premiereNode of premiereNodes) {\n const title = premiereNode.querySelector('p + span').attributes.title;\n\n if (title) {\n const [dateRaw, ...company] = title?.split(' ');\n const date = parseDate(dateRaw);\n\n if (date) {\n premiere.push({\n country: premiereNode.querySelector('.flag')?.attributes.title || null,\n format: premiereNode.querySelector('p').textContent.trim()?.split(' od')[0],\n date,\n company: company.join(' ')\n });\n }\n }\n }\n return premiere;\n};\n\nexport const getMovieTags = (el: HTMLElement): string[] => {\n const tagsRaw = el.querySelectorAll('.box-content a[href*=\"/tag/\"]');\n return tagsRaw.map((tag) => tag.textContent);\n};\n"],"mappings":";;;AA2BA,MAAM,iBAGF;CACF,IAAI;EACF,WAAW;EACX,SAAS;EACT,gBAAgB;EAChB,OAAO;EACP,QAAQ;EACR,SAAS;EACT,WAAW;EACX,aAAa;EACb,eAAe;EACf,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,QAAQ;EACT;CACD,IAAI;EACF,WAAW;EACX,SAAS;EACT,gBAAgB;EAChB,OAAO;EACP,QAAQ;EACR,SAAS;EACT,WAAW;EACX,aAAa;EACb,eAAe;EACf,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,QAAQ;EACT;CACD,IAAI;EACF,WAAW;EACX,SAAS;EACT,gBAAgB;EAChB,OAAO;EACP,QAAQ;EACR,SAAS;EACT,WAAW;EACX,aAAa;EACb,eAAe;EACf,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,QAAQ;EACT;CACF;;;;;;;AAQD,MAAa,4BACX,UACA,QAc2E;AAE3E,SAAQ,eADK,YAAY,SACO,eAAe,OAAO;;AAQxD,MAAa,iBAAiB,OAA4B;AACxD,QAAO,GAAG,cAAc,KAAK,CAAC,UAAU,MAAM,IAAI,CAAC,GAAG,MAAM;;AAG9D,MAAa,kBAAkB,OAAkC;AAE/D,QADkB,GAAG,cAAc,UAAU,CAAC,YAC7B,MAAM,MAAM;;AAG/B,MAAa,mBAAmB,OAA8B;AAG5D,QAFmB,GAAG,cAAc,UAAU,CAAC,YACpB,MAAM,IAAI,CAAC,GACvB,MAAM,MAAM;;AAG7B,MAAa,uBAAuB,gBAA2C;AAC7E,QAAOA,+BAAS,YAAY,GAAG;;AAGjC,MAAa,kBAAkB,OAA4B;CAEzD,MAAM,SADY,GAAG,cAAc,uBAAuB,CAAC,aACjC,QAAQ,MAAM,GAAG,CAAC,MAAM;CAClD,MAAM,YAAY,SAAS,OAAO;AAElC,KAAI,OAAO,UAAU,UAAU,CAC7B,QAAO;KAEP,QAAO;;AAIX,MAAa,uBAAuB,OAA4B;CAE9D,MAAM,cAAc,EADG,GAAG,cAAc,iCAAiC,EAAE,cACtC,QAAQ,WAAW,GAAG;AAC3D,KAAI,OAAO,UAAU,YAAY,CAC/B,QAAO;KAEP,QAAO;;AAIX,MAAa,gBAAgB,WAAuC;AAClE,KAAI,UAAU,OAAO,YACnB,QAAO,CAAC,OAAO;AAEjB,QAAO;;AAGT,MAAa,oBAAoB,QAA4B,OAA4B;AACvF,KAAI,UAAU,OAAO,SACnB,KAAI;AACF,SAAOC,2CAAqB,OAAO,SAAS;UACrC,GAAG;AAKd,KAAI;EAEF,MAAM,aADS,GAAG,cAAc,UAAU,CAAC,UACjB,MAAM,IAAI;AACpC,MAAI,WAAW,SAAS,GAAG;GAOzB,MAAM,YALc,WAAW,KAAK,CAAC,MAAM,CAEf,MAAM,IAAI,CAAC,GAAG,MAAM,CAEnB,MAAM,MAAM,CAAC,GACX,MAAM,IAAI;AAGzC,UADiB,UAAU,SAAS,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,KAAK,CAAC,UAAU;QAGxF,QAAO;UAEF,OAAO;AACd,SAAO;;;AAIX,MAAa,uBAAuB,OAAuC;CACzE,MAAM,YAAY,GAAG,iBAAiB,iBAAiB;AAEvD,KAAI,CAAC,UAAU,OACb,QAAO,EAAE;AAiBX,QAdoB,UAAU,KAAK,OAAO;EACxC,MAAM,UAAU,GAAG,cAAc,WAAW,CAAC,WAAW;EACxD,MAAM,QAAQ,GAAG,YAAY,MAAM,CAAC,MAAM,KAAK,CAAC;AAEhD,MAAI,WAAW,MACb,QAAO;GACL;GACA;GACD;MAED,QAAO;GAET,CAEiB,QAAQ,MAAM,EAAE;;AAGrC,MAAa,kBAAkB,OAAmC;CAChE,MAAM,SAAS,GAAG,cAAc,oBAAoB;AAEpD,KAAI,OACF,KAAI,OAAO,YAAY,SAAS,cAAc,CAC5C,QAAO;KAKP,QAAOC,kCAFY,OAAO,WAAW,IAAI,MAAM,IAAI,CAAC,GAC3B,QAAQ,YAAY,UAAU,CAC9B;KAG3B,QAAO;;AAIX,MAAa,uBAAuB,OAAmC;CAErE,MAAM,QADY,GAAG,cAAc,4BAA4B,EACtC,YAAY;AACrC,KAAI,MACF,QAAO,MAAM,QAAQ,YAAY,UAAU;KAE3C,QAAO;;AAIX,MAAa,kBAAkB,OAAqC;CAClE,MAAM,cAAc,GAAG,iBAAiB,wBAAwB;AAChE,KAAI,aAAa,OACf,QAAO,YAAY,KAAK,SAAS,KAAK,YAAY,MAAM,CAAC,QAAQ,qBAAqB,GAAG,CAAC;KAE1F,QAAO;;AAIX,MAAa,wBAAwB,OAA8B;AACjE,QAAO,GACJ,iBAAiB,+DAA+D,CAChF,KAAK,UAAU,MAAM,aAAa,MAAM,CAAC,QAAQ,qBAAqB,GAAG,CAAC;;AAG/E,MAAM,oBAAoB,OAAwC;AAEhE,QADe,GAAG,iBAAiB,IAAI,CAIlC,QAAQ,MAAM,EAAE,WAAW,WAAW,EAAE,CACxC,KAAK,WAAW;AACf,SAAO;GACL,IAAIC,qCAAe,OAAO,WAAW,KAAK;GAC1C,MAAM,OAAO,UAAU,MAAM;GAC7B,KAAK,sBAAsB,OAAO,WAAW;GAC9C;GACD;;AAcR,MAAa,oBAAoB,IAAiB,YAAwC;CACxF,MAAM,WAAyB;EAC7B,WAAW,EAAE;EACb,SAAS,EAAE;EACX,gBAAgB,EAAE;EAClB,OAAO,EAAE;EACT,QAAQ,EAAE;EACV,SAAS,EAAE;EACX,WAAW,EAAE;EACb,aAAa,EAAE;EACf,eAAe,EAAE;EACjB,kBAAkB,EAAE;EACrB;CAED,MAAM,SAAS,GAAG,iBAAiB,eAAe;CAelD,MAAM,kBAbO;EACX;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAE4B,KAAK,SAAS;EACzC;EACA,OAAO,yBAAyB,SAAS,UAAU,IAAI;EACxD,EAAE;AAEH,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,OAAO,MAAM,YAAY,MAAM;AACrC,OAAK,MAAM,EAAE,KAAK,WAAW,gBAC3B,KAAI,KAAK,SAAS,MAAM,EAAE;AACxB,OAAI,MAAM,WACR,UAAS,OAAO,iBAAiB,MAAM,WAA0B;AAEnE;;;AAKN,QAAO;;AAGT,MAAa,gBAAgB,OAAmC;AAE9D,QAAOC,oCADM,GAAG,cAAc,0BAA0B,EAC7B,WAAW,QAAQ,WAAW,GAAG,IAAI,OAAO;;AAGzE,MAAa,gBAAgB,OAAsC;CACjE,IAAI,OAAkB,EAAE;AACxB,KAAI,GAEF,QADmB,GAAG,iBAAiB,gCAAgC,CACrD,KAAK,QAAQ;AAC7B,SAAO;GACL,OAAO,IAAI,YAAY,MAAM;GAC7B,KAAK,IAAI,WAAW;GACrB;GACD;AAEJ,QAAO,KAAK,SAAS,OAAO,EAAE;;AAIhC,MAAM,iBAAiB,IAAiB,QAA6B;AAEnE,QADgB,GAAG,iBAAiB,0BAA0B,CAC/C,MAAM,WAAW,OAAO,cAAc,KAAK,EAAE,YAAY,MAAM,CAAC,SAAS,IAAI,CAAC,EACzF;;AAGN,MAAa,qBACX,IACA,YACwB;CACxB,MAAM,gBAAqC,EAAE;CAE7C,MAAM,kBADM,cAAc,IAAI,QAAQ,EACT,iBAAiB,mCAAmC;AACjF,KAAI,iBAAiB,OACnB,MAAK,MAAM,QAAQ,gBACjB,eAAc,KAAK;EACjB,IAAID,qCAAe,KAAK,WAAW,KAAK;EACxC,OAAO,KAAK,YAAY,MAAM;EAC9B,KAAK,sBAAsB,KAAK,WAAW;EAC5C,CAAC;AAGN,QAAO;;AAGT,MAAa,qBAAqB,OAAoC;CACpE,MAAM,gBAAgB,GAAG,iBAAiB,oBAAoB;CAC9D,MAAM,WAA2B,EAAE;AACnC,MAAK,MAAM,gBAAgB,eAAe;EACxC,MAAM,QAAQ,aAAa,cAAc,WAAW,CAAC,WAAW;AAEhE,MAAI,OAAO;GACT,MAAM,CAAC,SAAS,GAAG,WAAW,OAAO,MAAM,IAAI;GAC/C,MAAM,OAAOE,gCAAU,QAAQ;AAE/B,OAAI,KACF,UAAS,KAAK;IACZ,SAAS,aAAa,cAAc,QAAQ,EAAE,WAAW,SAAS;IAClE,QAAQ,aAAa,cAAc,IAAI,CAAC,YAAY,MAAM,EAAE,MAAM,MAAM,CAAC;IACzE;IACA,SAAS,QAAQ,KAAK,IAAI;IAC3B,CAAC;;;AAIR,QAAO;;AAGT,MAAa,gBAAgB,OAA8B;AAEzD,QADgB,GAAG,iBAAiB,kCAAgC,CACrD,KAAK,QAAQ,IAAI,YAAY"}
@@ -1,4 +1,4 @@
1
- import { addProtocol, getColor, parseDate, parseFilmType, parseISO8601Duration, parseIdFromUrl, parseLastIdFromUrl } from "./global.helper.mjs";
1
+ import { addProtocol, getColor, parseDate, parseFilmType, parseISO8601Duration, parseIdFromUrl } from "./global.helper.mjs";
2
2
 
3
3
  //#region src/helpers/movie.helper.ts
4
4
  const CREATOR_LABELS = {
@@ -57,25 +57,6 @@ const CREATOR_LABELS = {
57
57
  const getLocalizedCreatorLabel = (language, key) => {
58
58
  return (CREATOR_LABELS[language || "cs"] || CREATOR_LABELS["cs"])[key];
59
59
  };
60
- const getSeriesAndSeasonTitle = (el) => {
61
- const titleElement = el.querySelector("h1");
62
- if (!titleElement) return {
63
- seriesName: null,
64
- seasonName: null
65
- };
66
- const fullText = titleElement.innerText.trim();
67
- if (fullText.includes(" - ")) {
68
- const [seriesName, seasonName] = fullText.split(" - ").map((part) => part.trim());
69
- return {
70
- seriesName,
71
- seasonName
72
- };
73
- }
74
- return {
75
- seriesName: fullText,
76
- seasonName: null
77
- };
78
- };
79
60
  const getMovieTitle = (el) => {
80
61
  return el.querySelector("h1").innerText.split(`(`)[0].trim();
81
62
  };
@@ -196,65 +177,6 @@ const getMovieCreators = (el, options) => {
196
177
  }
197
178
  return creators;
198
179
  };
199
- const getSeasonsOrEpisodes = (el, serie) => {
200
- const childrenList = el.querySelector(".film-episodes-list");
201
- if (!childrenList) return null;
202
- const childrenNodes = childrenList.querySelectorAll(".film-title");
203
- if (!childrenNodes?.length) return [];
204
- return childrenNodes.map((season) => {
205
- const nameContainer = season.querySelector(".film-title-name");
206
- const infoContainer = season.querySelector(".info");
207
- const href = nameContainer?.getAttribute("href");
208
- const url = href ? href.startsWith("/") ? `https://www.csfd.cz${href}` : href : null;
209
- return {
210
- id: parseLastIdFromUrl(href || ""),
211
- title: nameContainer?.textContent?.trim() || null,
212
- url,
213
- info: infoContainer?.textContent?.replace(/[{()}]/g, "").trim() || null
214
- };
215
- });
216
- };
217
- const getEpisodeCode = (el) => {
218
- const filmHeaderName = el.querySelector(".film-header-name h1");
219
- if (!filmHeaderName) return null;
220
- const match = (filmHeaderName.textContent?.trim() || "").match(/\(([^)]+)\)/);
221
- return match ? match[1] : null;
222
- };
223
- const detectSeasonOrEpisodeListType = (el) => {
224
- const headerText = el.querySelector(".box-header h3")?.innerText.trim() ?? "";
225
- if (headerText.includes("Série")) return "seasons";
226
- if (headerText.startsWith("Epizody")) return "episodes";
227
- return null;
228
- };
229
- const getSeasonOrEpisodeParent = (el, serie) => {
230
- let parents = el.querySelectorAll(".film-header h2 a");
231
- if (parents.length === 0) parents = el.querySelectorAll(".film-header h1 a");
232
- if (parents.length === 0) {
233
- if (!serie) return null;
234
- return {
235
- series: serie,
236
- season: null
237
- };
238
- }
239
- const [parentSeries, parentSeason] = parents;
240
- const seriesId = parseIdFromUrl(parentSeries?.getAttribute("href"));
241
- const seasonId = parseLastIdFromUrl(parentSeason?.getAttribute("href") || "");
242
- const seriesTitle = parentSeries?.textContent?.trim() || null;
243
- const seasonTitle = parentSeason?.textContent?.trim() || null;
244
- const series = seriesId && seriesTitle ? {
245
- id: seriesId,
246
- title: seriesTitle
247
- } : null;
248
- const season = seasonId && seasonTitle ? {
249
- id: seasonId,
250
- title: seasonTitle
251
- } : null;
252
- if (!series && !season) return null;
253
- return {
254
- series,
255
- season
256
- };
257
- };
258
180
  const getMovieType = (el) => {
259
181
  return parseFilmType(el.querySelector(".film-header-name .type")?.innerText?.replace(/[{()}]/g, "") || "film");
260
182
  };
@@ -304,5 +226,5 @@ const getMovieTags = (el) => {
304
226
  };
305
227
 
306
228
  //#endregion
307
- export { detectSeasonOrEpisodeListType, getEpisodeCode, getMovieBoxMovies, getMovieColorRating, getMovieCreators, getMovieDescriptions, getMovieDuration, getMovieGenres, getMovieOrigins, getMoviePoster, getMoviePremieres, getMovieRandomPhoto, getMovieRating, getMovieRatingCount, getMovieTags, getMovieTitle, getMovieTitlesOther, getMovieTrivia, getMovieType, getMovieVods, getMovieYear, getSeasonOrEpisodeParent, getSeasonsOrEpisodes, getSeriesAndSeasonTitle };
229
+ export { getMovieBoxMovies, getMovieColorRating, getMovieCreators, getMovieDescriptions, getMovieDuration, getMovieGenres, getMovieOrigins, getMoviePoster, getMoviePremieres, getMovieRandomPhoto, getMovieRating, getMovieRatingCount, getMovieTags, getMovieTitle, getMovieTitlesOther, getMovieTrivia, getMovieType, getMovieVods, getMovieYear };
308
230
  //# sourceMappingURL=movie.helper.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"movie.helper.mjs","names":[],"sources":["../../src/helpers/movie.helper.ts"],"sourcesContent":["import { HTMLElement } from 'node-html-parser';\nimport { CSFDColorRating, CSFDFilmTypes } from '../dto/global';\nimport {\n CSFDBoxContent,\n CSFDCreatorGroups,\n CSFDCreatorGroupsEnglish,\n CSFDCreatorGroupsSlovak,\n CSFDCreators,\n CSFDGenres,\n CSFDMovieCreator,\n CSFDMovieListItem,\n CSFDParent,\n CSFDPremiere,\n CSFDSeriesChild,\n CSFDTitlesOther,\n CSFDVod,\n CSFDVodService,\n MovieJsonLd\n} from '../dto/movie';\nimport { CSFDOptions } from '../types';\nimport {\n addProtocol,\n getColor,\n parseDate,\n parseFilmType,\n parseISO8601Duration,\n parseIdFromUrl,\n parseLastIdFromUrl\n} from './global.helper';\n\nconst CREATOR_LABELS: Record<\n string,\n Record<string, CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak>\n> = {\n en: {\n directors: 'Directed by',\n writers: 'Screenplay',\n cinematography: 'Cinematography',\n music: 'Composer',\n actors: 'Cast',\n basedOn: 'Based on',\n producers: 'Produced by',\n filmEditing: 'Editing',\n costumeDesign: 'Costumes',\n productionDesign: 'Production design',\n casting: 'Casting',\n sound: 'Sound',\n makeup: 'Make-up'\n },\n cs: {\n directors: 'Režie',\n writers: 'Scénář',\n cinematography: 'Kamera',\n music: 'Hudba',\n actors: 'Hrají',\n basedOn: 'Předloha',\n producers: 'Produkce',\n filmEditing: 'Střih',\n costumeDesign: 'Kostýmy',\n productionDesign: 'Scénografie',\n casting: 'Casting',\n sound: 'Zvuk',\n makeup: 'Masky'\n },\n sk: {\n directors: 'Réžia',\n writers: 'Scenár',\n cinematography: 'Kamera',\n music: 'Hudba',\n actors: 'Hrajú',\n basedOn: 'Predloha',\n producers: 'Produkcia',\n filmEditing: 'Strih',\n costumeDesign: 'Kostýmy',\n productionDesign: 'Scénografia',\n casting: 'Casting',\n sound: 'Zvuk',\n makeup: 'Masky'\n }\n};\n\n/**\n * Maps language-specific movie creator group labels.\n * @param language - The language code (e.g., 'en', 'cs')\n * @param key - The key of the creator group (e.g., 'directors', 'writers')\n * @returns The localized label for the creator group\n */\nexport const getLocalizedCreatorLabel = (\n language: string | undefined,\n key:\n | 'directors'\n | 'writers'\n | 'cinematography'\n | 'music'\n | 'actors'\n | 'basedOn'\n | 'producers'\n | 'filmEditing'\n | 'costumeDesign'\n | 'productionDesign'\n | 'casting'\n | 'sound'\n | 'makeup'\n): CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak => {\n const lang = language || 'cs'; // Default to Czech\n return (CREATOR_LABELS[lang] || CREATOR_LABELS['cs'])[key];\n};\n\nexport const getMovieId = (el: HTMLElement): number => {\n const url = el.querySelector('.tabs .tab-nav-list a').attributes.href;\n return parseIdFromUrl(url);\n};\n\nexport const getSeriesAndSeasonTitle = (\n el: HTMLElement\n): { seriesName: string | null; seasonName: string | null } => {\n const titleElement = el.querySelector('h1');\n if (!titleElement) {\n return { seriesName: null, seasonName: null };\n }\n\n const fullText = titleElement.innerText.trim();\n\n // Check if there's a series part indicated by ' - '\n if (fullText.includes(' - ')) {\n const [seriesName, seasonName] = fullText.split(' - ').map((part) => part.trim());\n return { seriesName, seasonName };\n }\n\n // If no series part found, return just the name\n return { seriesName: fullText, seasonName: null };\n};\n\nexport const getMovieTitle = (el: HTMLElement): string => {\n return el.querySelector('h1').innerText.split(`(`)[0].trim();\n};\n\nexport const getMovieGenres = (el: HTMLElement): CSFDGenres[] => {\n const genresRaw = el.querySelector('.genres').textContent;\n return genresRaw.split(' / ') as CSFDGenres[];\n};\n\nexport const getMovieOrigins = (el: HTMLElement): string[] => {\n const originsRaw = el.querySelector('.origin').textContent;\n const origins = originsRaw.split(',')[0];\n return origins.split(' / ');\n};\n\nexport const getMovieColorRating = (bodyClasses: string[]): CSFDColorRating => {\n return getColor(bodyClasses[1]);\n};\n\nexport const getMovieRating = (el: HTMLElement): number => {\n const ratingRaw = el.querySelector('.film-rating-average').textContent;\n const rating = ratingRaw?.replace(/%/g, '').trim();\n const ratingInt = parseInt(rating);\n\n if (Number.isInteger(ratingInt)) {\n return ratingInt;\n } else {\n return null;\n }\n};\n\nexport const getMovieRatingCount = (el: HTMLElement): number => {\n const ratingCountRaw = el.querySelector('.box-rating-container .counter')?.textContent;\n const ratingCount = +ratingCountRaw?.replace(/[(\\s)]/g, '');\n if (Number.isInteger(ratingCount)) {\n return ratingCount;\n } else {\n return null;\n }\n};\n\nexport const getMovieYear = (jsonLd: MovieJsonLd | null): number => {\n if (jsonLd && jsonLd.dateCreated) {\n return +jsonLd.dateCreated;\n }\n return null;\n};\n\nexport const getMovieDuration = (jsonLd: MovieJsonLd | null, el: HTMLElement): number => {\n if (jsonLd && jsonLd.duration) {\n try {\n return parseISO8601Duration(jsonLd.duration);\n } catch (e) {\n // ignore\n }\n }\n\n try {\n const origin = el.querySelector('.origin').innerText;\n const timeString = origin.split(',');\n if (timeString.length > 2) {\n // Get last time elelment\n const timeString2 = timeString.pop().trim();\n // Clean it\n const timeRaw = timeString2.split('(')[0].trim();\n // Split by minutes and hours\n const hoursMinsRaw = timeRaw.split('min')[0];\n const hoursMins = hoursMinsRaw.split('h');\n // Resolve hours + minutes format\n const duration = hoursMins.length > 1 ? +hoursMins[0] * 60 + +hoursMins[1] : +hoursMins[0];\n return duration;\n } else {\n return null;\n }\n } catch (error) {\n return null;\n }\n};\n\nexport const getMovieTitlesOther = (el: HTMLElement): CSFDTitlesOther[] => {\n const namesNode = el.querySelectorAll('.film-names li');\n\n if (!namesNode.length) {\n return [];\n }\n\n const titlesOther = namesNode.map((el) => {\n const country = el.querySelector('img.flag').attributes.alt;\n const title = el.textContent.trim().split('\\n')[0];\n\n if (country && title) {\n return {\n country,\n title\n };\n } else {\n return null;\n }\n });\n\n return titlesOther.filter((x) => x);\n};\n\nexport const getMoviePoster = (el: HTMLElement | null): string => {\n const poster = el.querySelector('.film-posters img');\n // Resolve empty image\n if (poster) {\n if (poster.classNames?.includes('empty-image')) {\n return null;\n } else {\n // Full sized image (not thumb)\n const imageThumb = poster.attributes.src.split('?')[0];\n const image = imageThumb.replace(/\\/w140\\//, '/w1080/');\n return addProtocol(image);\n }\n } else {\n return null;\n }\n};\n\nexport const getMovieRandomPhoto = (el: HTMLElement | null): string => {\n const imageNode = el.querySelector('.gallery-item picture img');\n const image = imageNode?.attributes?.src;\n if (image) {\n return image.replace(/\\/w663\\//, '/w1326/');\n } else {\n return null;\n }\n};\n\nexport const getMovieTrivia = (el: HTMLElement | null): string[] => {\n const triviaNodes = el.querySelectorAll('.article-trivia ul li');\n if (triviaNodes?.length) {\n return triviaNodes.map((node) => node.textContent.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm, ''));\n } else {\n return null;\n }\n};\n\nexport const getMovieDescriptions = (el: HTMLElement): string[] => {\n return el\n .querySelectorAll('.body--plots .plot-full p, .body--plots .plots .plots-item p')\n .map((movie) => movie.textContent?.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm, ''));\n};\n\nconst parseMoviePeople = (el: HTMLElement): CSFDMovieCreator[] => {\n const people = el.querySelectorAll('a');\n return (\n people\n // Filter out \"more\" links\n .filter((x) => x.classNames.length === 0)\n .map((person) => {\n return {\n id: parseIdFromUrl(person.attributes.href),\n name: person.innerText.trim(),\n url: `https://www.csfd.cz${person.attributes.href}`\n };\n })\n );\n};\n\n// export const getMovieGroup = (el: HTMLElement, group: CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak): CSFDMovieCreator[] => {\n// const creators = el.querySelectorAll('.creators h4');\n// const element = creators.filter((elem) => elem.textContent.trim().includes(group))[0];\n// if (element?.parentNode) {\n// return parseMoviePeople(element.parentNode as HTMLElement);\n// } else {\n// return [];\n// }\n// };\n\nexport const getMovieCreators = (el: HTMLElement, options?: CSFDOptions): CSFDCreators => {\n const creators: CSFDCreators = {\n directors: [],\n writers: [],\n cinematography: [],\n music: [],\n actors: [],\n basedOn: [],\n producers: [],\n filmEditing: [],\n costumeDesign: [],\n productionDesign: []\n };\n\n const groups = el.querySelectorAll('.creators h4');\n\n const keys = [\n 'directors',\n 'writers',\n 'cinematography',\n 'music',\n 'actors',\n 'basedOn',\n 'producers',\n 'filmEditing',\n 'costumeDesign',\n 'productionDesign'\n ] as const;\n\n const localizedLabels = keys.map((key) => ({\n key,\n label: getLocalizedCreatorLabel(options?.language, key) as string\n }));\n\n for (const group of groups) {\n const text = group.textContent.trim();\n for (const { key, label } of localizedLabels) {\n if (text.includes(label)) {\n if (group.parentNode) {\n creators[key] = parseMoviePeople(group.parentNode as HTMLElement);\n }\n break;\n }\n }\n }\n\n return creators;\n};\n\nexport const getSeasonsOrEpisodes = (\n el: HTMLElement,\n serie?: { id: number; title: string }\n): CSFDSeriesChild[] | null => {\n const childrenList = el.querySelector('.film-episodes-list');\n if (!childrenList) return null;\n\n const childrenNodes = childrenList.querySelectorAll('.film-title');\n if (!childrenNodes?.length) return [];\n\n return childrenNodes.map((season) => {\n const nameContainer = season.querySelector('.film-title-name');\n const infoContainer = season.querySelector('.info');\n\n const href = nameContainer?.getAttribute('href');\n const url = href ? (href.startsWith('/') ? `https://www.csfd.cz${href}` : href) : null;\n\n return {\n id: parseLastIdFromUrl(href || ''),\n title: nameContainer?.textContent?.trim() || null,\n url,\n info: infoContainer?.textContent?.replace(/[{()}]/g, '').trim() || null\n };\n });\n};\n\nexport const getEpisodeCode = (el: HTMLElement): string | null => {\n const filmHeaderName = el.querySelector('.film-header-name h1');\n if (!filmHeaderName) return null;\n\n const text = filmHeaderName.textContent?.trim() || '';\n const match = text.match(/\\(([^)]+)\\)/);\n const code = match ? match[1] : null;\n\n return code;\n};\n\nexport const detectSeasonOrEpisodeListType = (el: HTMLElement) => {\n const headerText = el.querySelector('.box-header h3')?.innerText.trim() ?? '';\n\n if (headerText.includes('Série')) return 'seasons';\n if (headerText.startsWith('Epizody')) return 'episodes';\n return null;\n};\n\nexport const getSeasonOrEpisodeParent = (\n el: HTMLElement,\n serie?: { id: number; title: string }\n): CSFDParent | null => {\n // Try h2 first (for episodes), then h1 (for seasons)\n let parents = el.querySelectorAll('.film-header h2 a');\n if (parents.length === 0) {\n parents = el.querySelectorAll('.film-header h1 a');\n }\n\n if (parents.length === 0) {\n if (!serie) return null;\n return { series: serie, season: null };\n }\n\n const [parentSeries, parentSeason] = parents;\n\n const seriesId = parseIdFromUrl(parentSeries?.getAttribute('href'));\n const seasonId = parseLastIdFromUrl(parentSeason?.getAttribute('href') || '');\n const seriesTitle = parentSeries?.textContent?.trim() || null;\n const seasonTitle = parentSeason?.textContent?.trim() || null;\n\n const series = seriesId && seriesTitle ? { id: seriesId, title: seriesTitle } : null;\n const season = seasonId && seasonTitle ? { id: seasonId, title: seasonTitle } : null;\n\n if (!series && !season) return null;\n\n return { series, season };\n};\n\nexport const getMovieGroup = (\n el: HTMLElement,\n group: CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak\n): CSFDMovieCreator[] => {\n const creators = el.querySelectorAll('.creators h4');\n const element = creators.filter((elem) => elem.textContent.trim().includes(group))[0];\n if (element?.parentNode) {\n return parseMoviePeople(element.parentNode as HTMLElement);\n } else {\n return [];\n }\n};\n\nexport const getMovieType = (el: HTMLElement): CSFDFilmTypes => {\n const type = el.querySelector('.film-header-name .type');\n return parseFilmType(type?.innerText?.replace(/[{()}]/g, '') || 'film');\n};\n\nexport const getMovieVods = (el: HTMLElement | null): CSFDVod[] => {\n let vods: CSFDVod[] = [];\n if (el) {\n const buttonsVod = el.querySelectorAll('.box-buttons-vod .vod-badge a');\n vods = buttonsVod.map((btn) => {\n return {\n title: btn.textContent.trim() as CSFDVodService,\n url: btn.attributes.href\n };\n });\n }\n return vods.length ? vods : [];\n};\n\n// Get box content\nconst getBoxContent = (el: HTMLElement, box: string): HTMLElement => {\n const headers = el.querySelectorAll('section.box .box-header');\n return headers.find((header) => header.querySelector('h3')?.textContent.trim().includes(box))\n ?.parentNode;\n};\n\nexport const getMovieBoxMovies = (\n el: HTMLElement,\n boxName: CSFDBoxContent\n): CSFDMovieListItem[] => {\n const movieListItem: CSFDMovieListItem[] = [];\n const box = getBoxContent(el, boxName);\n const movieTitleNodes = box?.querySelectorAll('.article-header .film-title-name');\n if (movieTitleNodes?.length) {\n for (const item of movieTitleNodes) {\n movieListItem.push({\n id: parseIdFromUrl(item.attributes.href),\n title: item.textContent.trim(),\n url: `https://www.csfd.cz${item.attributes.href}`\n });\n }\n }\n return movieListItem;\n};\n\nexport const getMoviePremieres = (el: HTMLElement): CSFDPremiere[] => {\n const premiereNodes = el.querySelectorAll('.box-premieres li');\n const premiere: CSFDPremiere[] = [];\n for (const premiereNode of premiereNodes) {\n const title = premiereNode.querySelector('p + span').attributes.title;\n\n if (title) {\n const [dateRaw, ...company] = title?.split(' ');\n const date = parseDate(dateRaw);\n\n if (date) {\n premiere.push({\n country: premiereNode.querySelector('.flag')?.attributes.title || null,\n format: premiereNode.querySelector('p').textContent.trim()?.split(' od')[0],\n date,\n company: company.join(' ')\n });\n }\n }\n }\n return premiere;\n};\n\nexport const getMovieTags = (el: HTMLElement): string[] => {\n const tagsRaw = el.querySelectorAll('.box-content a[href*=\"/tag/\"]');\n return tagsRaw.map((tag) => tag.textContent);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"movie.helper.mjs","names":[],"sources":["../../src/helpers/movie.helper.ts"],"sourcesContent":["import { HTMLElement } from 'node-html-parser';\nimport { CSFDColorRating, CSFDFilmTypes } from '../dto/global';\nimport {\n CSFDBoxContent,\n CSFDCreatorGroups,\n CSFDCreatorGroupsEnglish,\n CSFDCreatorGroupsSlovak,\n CSFDCreators,\n CSFDGenres,\n CSFDMovieCreator,\n CSFDMovieListItem,\n CSFDPremiere,\n CSFDTitlesOther,\n CSFDVod,\n CSFDVodService,\n MovieJsonLd\n} from '../dto/movie';\nimport { CSFDOptions } from '../types';\nimport {\n addProtocol,\n getColor,\n parseDate,\n parseFilmType,\n parseISO8601Duration,\n parseIdFromUrl\n} from './global.helper';\n\nconst CREATOR_LABELS: Record<\n string,\n Record<string, CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak>\n> = {\n en: {\n directors: 'Directed by',\n writers: 'Screenplay',\n cinematography: 'Cinematography',\n music: 'Composer',\n actors: 'Cast',\n basedOn: 'Based on',\n producers: 'Produced by',\n filmEditing: 'Editing',\n costumeDesign: 'Costumes',\n productionDesign: 'Production design',\n casting: 'Casting',\n sound: 'Sound',\n makeup: 'Make-up'\n },\n cs: {\n directors: 'Režie',\n writers: 'Scénář',\n cinematography: 'Kamera',\n music: 'Hudba',\n actors: 'Hrají',\n basedOn: 'Předloha',\n producers: 'Produkce',\n filmEditing: 'Střih',\n costumeDesign: 'Kostýmy',\n productionDesign: 'Scénografie',\n casting: 'Casting',\n sound: 'Zvuk',\n makeup: 'Masky'\n },\n sk: {\n directors: 'Réžia',\n writers: 'Scenár',\n cinematography: 'Kamera',\n music: 'Hudba',\n actors: 'Hrajú',\n basedOn: 'Predloha',\n producers: 'Produkcia',\n filmEditing: 'Strih',\n costumeDesign: 'Kostýmy',\n productionDesign: 'Scénografia',\n casting: 'Casting',\n sound: 'Zvuk',\n makeup: 'Masky'\n }\n};\n\n/**\n * Maps language-specific movie creator group labels.\n * @param language - The language code (e.g., 'en', 'cs')\n * @param key - The key of the creator group (e.g., 'directors', 'writers')\n * @returns The localized label for the creator group\n */\nexport const getLocalizedCreatorLabel = (\n language: string | undefined,\n key:\n | 'directors'\n | 'writers'\n | 'cinematography'\n | 'music'\n | 'actors'\n | 'basedOn'\n | 'producers'\n | 'filmEditing'\n | 'costumeDesign'\n | 'productionDesign'\n | 'casting'\n | 'sound'\n | 'makeup'\n): CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak => {\n const lang = language || 'cs'; // Default to Czech\n return (CREATOR_LABELS[lang] || CREATOR_LABELS['cs'])[key];\n};\n\nexport const getMovieId = (el: HTMLElement): number => {\n const url = el.querySelector('.tabs .tab-nav-list a').attributes.href;\n return parseIdFromUrl(url);\n};\n\nexport const getMovieTitle = (el: HTMLElement): string => {\n return el.querySelector('h1').innerText.split(`(`)[0].trim();\n};\n\nexport const getMovieGenres = (el: HTMLElement): CSFDGenres[] => {\n const genresRaw = el.querySelector('.genres').textContent;\n return genresRaw.split(' / ') as CSFDGenres[];\n};\n\nexport const getMovieOrigins = (el: HTMLElement): string[] => {\n const originsRaw = el.querySelector('.origin').textContent;\n const origins = originsRaw.split(',')[0];\n return origins.split(' / ');\n};\n\nexport const getMovieColorRating = (bodyClasses: string[]): CSFDColorRating => {\n return getColor(bodyClasses[1]);\n};\n\nexport const getMovieRating = (el: HTMLElement): number => {\n const ratingRaw = el.querySelector('.film-rating-average').textContent;\n const rating = ratingRaw?.replace(/%/g, '').trim();\n const ratingInt = parseInt(rating);\n\n if (Number.isInteger(ratingInt)) {\n return ratingInt;\n } else {\n return null;\n }\n};\n\nexport const getMovieRatingCount = (el: HTMLElement): number => {\n const ratingCountRaw = el.querySelector('.box-rating-container .counter')?.textContent;\n const ratingCount = +ratingCountRaw?.replace(/[(\\s)]/g, '');\n if (Number.isInteger(ratingCount)) {\n return ratingCount;\n } else {\n return null;\n }\n};\n\nexport const getMovieYear = (jsonLd: MovieJsonLd | null): number => {\n if (jsonLd && jsonLd.dateCreated) {\n return +jsonLd.dateCreated;\n }\n return null;\n};\n\nexport const getMovieDuration = (jsonLd: MovieJsonLd | null, el: HTMLElement): number => {\n if (jsonLd && jsonLd.duration) {\n try {\n return parseISO8601Duration(jsonLd.duration);\n } catch (e) {\n // ignore\n }\n }\n\n try {\n const origin = el.querySelector('.origin').innerText;\n const timeString = origin.split(',');\n if (timeString.length > 2) {\n // Get last time elelment\n const timeString2 = timeString.pop().trim();\n // Clean it\n const timeRaw = timeString2.split('(')[0].trim();\n // Split by minutes and hours\n const hoursMinsRaw = timeRaw.split('min')[0];\n const hoursMins = hoursMinsRaw.split('h');\n // Resolve hours + minutes format\n const duration = hoursMins.length > 1 ? +hoursMins[0] * 60 + +hoursMins[1] : +hoursMins[0];\n return duration;\n } else {\n return null;\n }\n } catch (error) {\n return null;\n }\n};\n\nexport const getMovieTitlesOther = (el: HTMLElement): CSFDTitlesOther[] => {\n const namesNode = el.querySelectorAll('.film-names li');\n\n if (!namesNode.length) {\n return [];\n }\n\n const titlesOther = namesNode.map((el) => {\n const country = el.querySelector('img.flag').attributes.alt;\n const title = el.textContent.trim().split('\\n')[0];\n\n if (country && title) {\n return {\n country,\n title\n };\n } else {\n return null;\n }\n });\n\n return titlesOther.filter((x) => x);\n};\n\nexport const getMoviePoster = (el: HTMLElement | null): string => {\n const poster = el.querySelector('.film-posters img');\n // Resolve empty image\n if (poster) {\n if (poster.classNames?.includes('empty-image')) {\n return null;\n } else {\n // Full sized image (not thumb)\n const imageThumb = poster.attributes.src.split('?')[0];\n const image = imageThumb.replace(/\\/w140\\//, '/w1080/');\n return addProtocol(image);\n }\n } else {\n return null;\n }\n};\n\nexport const getMovieRandomPhoto = (el: HTMLElement | null): string => {\n const imageNode = el.querySelector('.gallery-item picture img');\n const image = imageNode?.attributes?.src;\n if (image) {\n return image.replace(/\\/w663\\//, '/w1326/');\n } else {\n return null;\n }\n};\n\nexport const getMovieTrivia = (el: HTMLElement | null): string[] => {\n const triviaNodes = el.querySelectorAll('.article-trivia ul li');\n if (triviaNodes?.length) {\n return triviaNodes.map((node) => node.textContent.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm, ''));\n } else {\n return null;\n }\n};\n\nexport const getMovieDescriptions = (el: HTMLElement): string[] => {\n return el\n .querySelectorAll('.body--plots .plot-full p, .body--plots .plots .plots-item p')\n .map((movie) => movie.textContent?.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm, ''));\n};\n\nconst parseMoviePeople = (el: HTMLElement): CSFDMovieCreator[] => {\n const people = el.querySelectorAll('a');\n return (\n people\n // Filter out \"more\" links\n .filter((x) => x.classNames.length === 0)\n .map((person) => {\n return {\n id: parseIdFromUrl(person.attributes.href),\n name: person.innerText.trim(),\n url: `https://www.csfd.cz${person.attributes.href}`\n };\n })\n );\n};\n\n// export const getMovieGroup = (el: HTMLElement, group: CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak): CSFDMovieCreator[] => {\n// const creators = el.querySelectorAll('.creators h4');\n// const element = creators.filter((elem) => elem.textContent.trim().includes(group))[0];\n// if (element?.parentNode) {\n// return parseMoviePeople(element.parentNode as HTMLElement);\n// } else {\n// return [];\n// }\n// };\n\nexport const getMovieCreators = (el: HTMLElement, options?: CSFDOptions): CSFDCreators => {\n const creators: CSFDCreators = {\n directors: [],\n writers: [],\n cinematography: [],\n music: [],\n actors: [],\n basedOn: [],\n producers: [],\n filmEditing: [],\n costumeDesign: [],\n productionDesign: []\n };\n\n const groups = el.querySelectorAll('.creators h4');\n\n const keys = [\n 'directors',\n 'writers',\n 'cinematography',\n 'music',\n 'actors',\n 'basedOn',\n 'producers',\n 'filmEditing',\n 'costumeDesign',\n 'productionDesign'\n ] as const;\n\n const localizedLabels = keys.map((key) => ({\n key,\n label: getLocalizedCreatorLabel(options?.language, key) as string\n }));\n\n for (const group of groups) {\n const text = group.textContent.trim();\n for (const { key, label } of localizedLabels) {\n if (text.includes(label)) {\n if (group.parentNode) {\n creators[key] = parseMoviePeople(group.parentNode as HTMLElement);\n }\n break;\n }\n }\n }\n\n return creators;\n};\n\nexport const getMovieType = (el: HTMLElement): CSFDFilmTypes => {\n const type = el.querySelector('.film-header-name .type');\n return parseFilmType(type?.innerText?.replace(/[{()}]/g, '') || 'film');\n};\n\nexport const getMovieVods = (el: HTMLElement | null): CSFDVod[] => {\n let vods: CSFDVod[] = [];\n if (el) {\n const buttonsVod = el.querySelectorAll('.box-buttons-vod .vod-badge a');\n vods = buttonsVod.map((btn) => {\n return {\n title: btn.textContent.trim() as CSFDVodService,\n url: btn.attributes.href\n };\n });\n }\n return vods.length ? vods : [];\n};\n\n// Get box content\nconst getBoxContent = (el: HTMLElement, box: string): HTMLElement => {\n const headers = el.querySelectorAll('section.box .box-header');\n return headers.find((header) => header.querySelector('h3')?.textContent.trim().includes(box))\n ?.parentNode;\n};\n\nexport const getMovieBoxMovies = (\n el: HTMLElement,\n boxName: CSFDBoxContent\n): CSFDMovieListItem[] => {\n const movieListItem: CSFDMovieListItem[] = [];\n const box = getBoxContent(el, boxName);\n const movieTitleNodes = box?.querySelectorAll('.article-header .film-title-name');\n if (movieTitleNodes?.length) {\n for (const item of movieTitleNodes) {\n movieListItem.push({\n id: parseIdFromUrl(item.attributes.href),\n title: item.textContent.trim(),\n url: `https://www.csfd.cz${item.attributes.href}`\n });\n }\n }\n return movieListItem;\n};\n\nexport const getMoviePremieres = (el: HTMLElement): CSFDPremiere[] => {\n const premiereNodes = el.querySelectorAll('.box-premieres li');\n const premiere: CSFDPremiere[] = [];\n for (const premiereNode of premiereNodes) {\n const title = premiereNode.querySelector('p + span').attributes.title;\n\n if (title) {\n const [dateRaw, ...company] = title?.split(' ');\n const date = parseDate(dateRaw);\n\n if (date) {\n premiere.push({\n country: premiereNode.querySelector('.flag')?.attributes.title || null,\n format: premiereNode.querySelector('p').textContent.trim()?.split(' od')[0],\n date,\n company: company.join(' ')\n });\n }\n }\n }\n return premiere;\n};\n\nexport const getMovieTags = (el: HTMLElement): string[] => {\n const tagsRaw = el.querySelectorAll('.box-content a[href*=\"/tag/\"]');\n return tagsRaw.map((tag) => tag.textContent);\n};\n"],"mappings":"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"}
package/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CSFDColorRating, CSFDFilmTypes, CSFDScreening, CSFDStars } from "./dto/global.mjs";
2
- import { CSFDBoxContent, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreators, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDParent, CSFDPremiere, CSFDSeriesChild, CSFDTitlesOther, CSFDVod, CSFDVodService, MovieJsonLd } from "./dto/movie.mjs";
2
+ import { CSFDBoxContent, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreators, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDPremiere, CSFDTitlesOther, CSFDVod, CSFDVodService, MovieJsonLd } from "./dto/movie.mjs";
3
3
  import { CSFDCinema, CSFDCinemaGroupedFilmsByDate, CSFDCinemaMeta, CSFDCinemaMovie, CSFDCinemaPeriod } from "./dto/cinema.mjs";
4
4
  import { CSFDCreator, CSFDCreatorScreening } from "./dto/creator.mjs";
5
5
  import { CSFDSearch, CSFDSearchCreator, CSFDSearchCreators, CSFDSearchMovie, CSFDSearchUser } from "./dto/search.mjs";
@@ -36,5 +36,5 @@ declare class Csfd {
36
36
  }
37
37
  declare const csfd: Csfd;
38
38
  //#endregion
39
- export { CSFDBoxContent, CSFDCinema, CSFDCinemaGroupedFilmsByDate, CSFDCinemaMeta, CSFDCinemaMovie, CSFDCinemaPeriod, CSFDColorRating, CSFDColors, CSFDCreator, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreatorScreening, CSFDCreators, CSFDFilmTypes, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDParent, CSFDPremiere, CSFDScreening, CSFDSearch, CSFDSearchCreator, CSFDSearchCreators, CSFDSearchMovie, CSFDSearchUser, CSFDSeriesChild, CSFDStars, CSFDTitlesOther, CSFDUserRatingConfig, CSFDUserRatings, CSFDVod, CSFDVodService, Csfd, MovieJsonLd, csfd };
39
+ export { CSFDBoxContent, CSFDCinema, CSFDCinemaGroupedFilmsByDate, CSFDCinemaMeta, CSFDCinemaMovie, CSFDCinemaPeriod, CSFDColorRating, CSFDColors, CSFDCreator, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreatorScreening, CSFDCreators, CSFDFilmTypes, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDPremiere, CSFDScreening, CSFDSearch, CSFDSearchCreator, CSFDSearchCreators, CSFDSearchMovie, CSFDSearchUser, CSFDStars, CSFDTitlesOther, CSFDUserRatingConfig, CSFDUserRatings, CSFDVod, CSFDVodService, Csfd, MovieJsonLd, csfd };
40
40
  //# sourceMappingURL=index.d.mts.map
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CSFDColorRating, CSFDFilmTypes, CSFDScreening, CSFDStars } from "./dto/global.js";
2
- import { CSFDBoxContent, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreators, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDParent, CSFDPremiere, CSFDSeriesChild, CSFDTitlesOther, CSFDVod, CSFDVodService, MovieJsonLd } from "./dto/movie.js";
2
+ import { CSFDBoxContent, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreators, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDPremiere, CSFDTitlesOther, CSFDVod, CSFDVodService, MovieJsonLd } from "./dto/movie.js";
3
3
  import { CSFDCinema, CSFDCinemaGroupedFilmsByDate, CSFDCinemaMeta, CSFDCinemaMovie, CSFDCinemaPeriod } from "./dto/cinema.js";
4
4
  import { CSFDCreator, CSFDCreatorScreening } from "./dto/creator.js";
5
5
  import { CSFDSearch, CSFDSearchCreator, CSFDSearchCreators, CSFDSearchMovie, CSFDSearchUser } from "./dto/search.js";
@@ -36,5 +36,5 @@ declare class Csfd {
36
36
  }
37
37
  declare const csfd: Csfd;
38
38
  //#endregion
39
- export { CSFDBoxContent, CSFDCinema, CSFDCinemaGroupedFilmsByDate, CSFDCinemaMeta, CSFDCinemaMovie, CSFDCinemaPeriod, CSFDColorRating, CSFDColors, CSFDCreator, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreatorScreening, CSFDCreators, CSFDFilmTypes, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDParent, CSFDPremiere, CSFDScreening, CSFDSearch, CSFDSearchCreator, CSFDSearchCreators, CSFDSearchMovie, CSFDSearchUser, CSFDSeriesChild, CSFDStars, CSFDTitlesOther, CSFDUserRatingConfig, CSFDUserRatings, CSFDVod, CSFDVodService, Csfd, MovieJsonLd, csfd };
39
+ export { CSFDBoxContent, CSFDCinema, CSFDCinemaGroupedFilmsByDate, CSFDCinemaMeta, CSFDCinemaMovie, CSFDCinemaPeriod, CSFDColorRating, CSFDColors, CSFDCreator, CSFDCreatorGroups, CSFDCreatorGroupsEnglish, CSFDCreatorGroupsSlovak, CSFDCreatorScreening, CSFDCreators, CSFDFilmTypes, CSFDGenres, CSFDMovie, CSFDMovieCreator, CSFDMovieListItem, CSFDPremiere, CSFDScreening, CSFDSearch, CSFDSearchCreator, CSFDSearchCreators, CSFDSearchMovie, CSFDSearchUser, CSFDStars, CSFDTitlesOther, CSFDUserRatingConfig, CSFDUserRatings, CSFDVod, CSFDVodService, Csfd, MovieJsonLd, csfd };
40
40
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-csfd-api",
3
- "version": "5.0.0-next-2",
3
+ "version": "5.0.0-next.1",
4
4
  "description": "ČSFD API in JavaScript. Amazing NPM library for scrapping csfd.cz :)",
5
5
  "author": "BART! <bart@bartweb.cz>",
6
6
  "publishConfig": {
package/package.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  //#region package.json
3
3
  var name = "node-csfd-api";
4
- var version = "5.0.0-next-2";
4
+ var version = "5.0.0-next.1";
5
5
  var homepage = "https://github.com/bartholomej/node-csfd-api#readme";
6
6
 
7
7
  //#endregion
@@ -22,18 +22,14 @@ var MovieScraper = class {
22
22
  return this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd, options);
23
23
  }
24
24
  buildMovie(movieId, el, asideEl, pageClasses, jsonLd, options) {
25
- const type = require_movie_helper.getMovieType(el);
26
- const { seriesName = null, seasonName = null } = type === "season" ? require_movie_helper.getSeriesAndSeasonTitle(el) : {};
27
- const seasonOrEpisodeListType = require_movie_helper.detectSeasonOrEpisodeListType(el);
28
- const title = type === "season" && seriesName ? seriesName : require_movie_helper.getMovieTitle(el);
29
25
  return {
30
26
  id: movieId,
31
- title,
27
+ title: require_movie_helper.getMovieTitle(el),
32
28
  year: require_movie_helper.getMovieYear(jsonLd),
33
29
  duration: require_movie_helper.getMovieDuration(jsonLd, el),
34
30
  descriptions: require_movie_helper.getMovieDescriptions(el),
35
31
  genres: require_movie_helper.getMovieGenres(el),
36
- type,
32
+ type: require_movie_helper.getMovieType(el),
37
33
  url: require_vars.movieUrl(movieId, { language: options?.language }),
38
34
  origins: require_movie_helper.getMovieOrigins(el),
39
35
  colorRating: require_movie_helper.getMovieColorRating(pageClasses),
@@ -48,15 +44,7 @@ var MovieScraper = class {
48
44
  tags: require_movie_helper.getMovieTags(asideEl),
49
45
  premieres: require_movie_helper.getMoviePremieres(asideEl),
50
46
  related: require_movie_helper.getMovieBoxMovies(asideEl, "Související"),
51
- similar: require_movie_helper.getMovieBoxMovies(asideEl, "Podobné"),
52
- seasons: seasonOrEpisodeListType === "seasons" ? require_movie_helper.getSeasonsOrEpisodes(el) : null,
53
- episodes: seasonOrEpisodeListType === "episodes" ? require_movie_helper.getSeasonsOrEpisodes(el) : null,
54
- parent: type === "series" ? null : require_movie_helper.getSeasonOrEpisodeParent(el, {
55
- id: movieId,
56
- title
57
- }),
58
- episodeCode: type === "episode" ? require_movie_helper.getEpisodeCode(el) : null,
59
- seasonName
47
+ similar: require_movie_helper.getMovieBoxMovies(asideEl, "Podobné")
60
48
  };
61
49
  }
62
50
  };
@@ -1 +1 @@
1
- {"version":3,"file":"movie.service.js","names":["fetchPage","movieUrl","getMovieType","getSeriesAndSeasonTitle","detectSeasonOrEpisodeListType","getMovieTitle","getMovieYear","getMovieDuration","getMovieDescriptions","getMovieGenres","getMovieOrigins","getMovieColorRating","getMovieRating","getMovieRatingCount","getMovieTitlesOther","getMoviePoster","getMovieRandomPhoto","getMovieTrivia","getMovieCreators","getMovieVods","getMovieTags","getMoviePremieres","getMovieBoxMovies","getSeasonsOrEpisodes","getSeasonOrEpisodeParent","getEpisodeCode"],"sources":["../../src/services/movie.service.ts"],"sourcesContent":["import { HTMLElement, parse } from 'node-html-parser';\nimport { CSFDFilmTypes } from '../dto/global';\nimport { CSFDMovie, MovieJsonLd } from '../dto/movie';\nimport { fetchPage } from '../fetchers';\nimport {\n detectSeasonOrEpisodeListType,\n getEpisodeCode,\n getMovieBoxMovies,\n getMovieColorRating,\n getMovieCreators,\n getMovieDescriptions,\n getMovieDuration,\n getMovieGenres,\n getMovieOrigins,\n getMoviePoster,\n getMoviePremieres,\n getMovieRandomPhoto,\n getMovieRating,\n getMovieRatingCount,\n getMovieTags,\n getMovieTitle,\n getMovieTitlesOther,\n getMovieTrivia,\n getMovieType,\n getMovieVods,\n getMovieYear,\n getSeasonOrEpisodeParent,\n getSeasonsOrEpisodes,\n getSeriesAndSeasonTitle\n} from '../helpers/movie.helper';\nimport { CSFDOptions } from '../types';\nimport { movieUrl } from '../vars';\n\nexport class MovieScraper {\n public async movie(movieId: number, options?: CSFDOptions): Promise<CSFDMovie> {\n const id = Number(movieId);\n if (isNaN(id)) {\n throw new Error('node-csfd-api: movieId must be a valid number');\n }\n const url = movieUrl(id, { language: options?.language });\n const response = await fetchPage(url, { ...options?.request });\n\n const movieHtml = parse(response);\n\n const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');\n const asideNode = movieHtml.querySelector('.aside-movie-profile');\n const movieNode = movieHtml.querySelector('.main-movie-profile');\n const jsonLdString = movieHtml.querySelector('script[type=\"application/ld+json\"]').innerText;\n let jsonLd: MovieJsonLd | null = null;\n try {\n jsonLd = JSON.parse(jsonLdString);\n } catch (e) {\n console.error('node-csfd-api: Error parsing JSON-LD', e);\n }\n return this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd, options);\n }\n\n private buildMovie(\n movieId: number,\n el: HTMLElement,\n asideEl: HTMLElement,\n pageClasses: string[],\n jsonLd: MovieJsonLd | null,\n options: CSFDOptions\n ) {\n const type = getMovieType(el) as CSFDFilmTypes;\n const { seriesName = null, seasonName = null } =\n type === 'season' ? getSeriesAndSeasonTitle(el) : {};\n const seasonOrEpisodeListType = detectSeasonOrEpisodeListType(el);\n\n const title = type === 'season' && seriesName ? seriesName : getMovieTitle(el);\n return {\n id: movieId,\n title,\n year: getMovieYear(jsonLd),\n duration: getMovieDuration(jsonLd, el),\n descriptions: getMovieDescriptions(el),\n genres: getMovieGenres(el),\n type,\n url: movieUrl(movieId, { language: options?.language }),\n origins: getMovieOrigins(el),\n colorRating: getMovieColorRating(pageClasses),\n rating: getMovieRating(asideEl),\n ratingCount: getMovieRatingCount(asideEl),\n titlesOther: getMovieTitlesOther(el),\n poster: getMoviePoster(el),\n photo: getMovieRandomPhoto(el),\n trivia: getMovieTrivia(el),\n creators: getMovieCreators(el, options),\n vod: getMovieVods(asideEl),\n tags: getMovieTags(asideEl),\n premieres: getMoviePremieres(asideEl),\n related: getMovieBoxMovies(asideEl, 'Související'),\n similar: getMovieBoxMovies(asideEl, 'Podobné'),\n seasons: seasonOrEpisodeListType === 'seasons' ? getSeasonsOrEpisodes(el) : null,\n episodes: seasonOrEpisodeListType === 'episodes' ? getSeasonsOrEpisodes(el) : null,\n parent: type === 'series' ? null : getSeasonOrEpisodeParent(el, { id: movieId, title }),\n episodeCode: type === 'episode' ? getEpisodeCode(el) : null,\n seasonName\n };\n }\n}\n"],"mappings":";;;;;;AAiCA,IAAa,eAAb,MAA0B;CACxB,MAAa,MAAM,SAAiB,SAA2C;EAC7E,MAAM,KAAK,OAAO,QAAQ;AAC1B,MAAI,MAAM,GAAG,CACX,OAAM,IAAI,MAAM,gDAAgD;EAKlE,MAAM,wCAFW,MAAMA,wBADXC,sBAAS,IAAI,EAAE,UAAU,SAAS,UAAU,CAAC,EACnB,EAAE,GAAG,SAAS,SAAS,CAAC,CAE7B;EAEjC,MAAM,cAAc,UAAU,cAAc,gBAAgB,CAAC,WAAW,MAAM,IAAI;EAClF,MAAM,YAAY,UAAU,cAAc,uBAAuB;EACjE,MAAM,YAAY,UAAU,cAAc,sBAAsB;EAChE,MAAM,eAAe,UAAU,cAAc,uCAAqC,CAAC;EACnF,IAAI,SAA6B;AACjC,MAAI;AACF,YAAS,KAAK,MAAM,aAAa;WAC1B,GAAG;AACV,WAAQ,MAAM,wCAAwC,EAAE;;AAE1D,SAAO,KAAK,WAAW,CAAC,SAAS,WAAW,WAAW,aAAa,QAAQ,QAAQ;;CAGtF,AAAQ,WACN,SACA,IACA,SACA,aACA,QACA,SACA;EACA,MAAM,OAAOC,kCAAa,GAAG;EAC7B,MAAM,EAAE,aAAa,MAAM,aAAa,SACtC,SAAS,WAAWC,6CAAwB,GAAG,GAAG,EAAE;EACtD,MAAM,0BAA0BC,mDAA8B,GAAG;EAEjE,MAAM,QAAQ,SAAS,YAAY,aAAa,aAAaC,mCAAc,GAAG;AAC9E,SAAO;GACL,IAAI;GACJ;GACA,MAAMC,kCAAa,OAAO;GAC1B,UAAUC,sCAAiB,QAAQ,GAAG;GACtC,cAAcC,0CAAqB,GAAG;GACtC,QAAQC,oCAAe,GAAG;GAC1B;GACA,KAAKR,sBAAS,SAAS,EAAE,UAAU,SAAS,UAAU,CAAC;GACvD,SAASS,qCAAgB,GAAG;GAC5B,aAAaC,yCAAoB,YAAY;GAC7C,QAAQC,oCAAe,QAAQ;GAC/B,aAAaC,yCAAoB,QAAQ;GACzC,aAAaC,yCAAoB,GAAG;GACpC,QAAQC,oCAAe,GAAG;GAC1B,OAAOC,yCAAoB,GAAG;GAC9B,QAAQC,oCAAe,GAAG;GAC1B,UAAUC,sCAAiB,IAAI,QAAQ;GACvC,KAAKC,kCAAa,QAAQ;GAC1B,MAAMC,kCAAa,QAAQ;GAC3B,WAAWC,uCAAkB,QAAQ;GACrC,SAASC,uCAAkB,SAAS,cAAc;GAClD,SAASA,uCAAkB,SAAS,UAAU;GAC9C,SAAS,4BAA4B,YAAYC,0CAAqB,GAAG,GAAG;GAC5E,UAAU,4BAA4B,aAAaA,0CAAqB,GAAG,GAAG;GAC9E,QAAQ,SAAS,WAAW,OAAOC,8CAAyB,IAAI;IAAE,IAAI;IAAS;IAAO,CAAC;GACvF,aAAa,SAAS,YAAYC,oCAAe,GAAG,GAAG;GACvD;GACD"}
1
+ {"version":3,"file":"movie.service.js","names":["fetchPage","movieUrl","getMovieTitle","getMovieYear","getMovieDuration","getMovieDescriptions","getMovieGenres","getMovieType","getMovieOrigins","getMovieColorRating","getMovieRating","getMovieRatingCount","getMovieTitlesOther","getMoviePoster","getMovieRandomPhoto","getMovieTrivia","getMovieCreators","getMovieVods","getMovieTags","getMoviePremieres","getMovieBoxMovies"],"sources":["../../src/services/movie.service.ts"],"sourcesContent":["import { HTMLElement, parse } from 'node-html-parser';\nimport { CSFDFilmTypes } from '../dto/global';\nimport { CSFDMovie, MovieJsonLd } from '../dto/movie';\nimport { fetchPage } from '../fetchers';\nimport {\n getMovieBoxMovies,\n getMovieColorRating,\n getMovieCreators,\n getMovieDescriptions,\n getMovieDuration,\n getMovieGenres,\n getMovieOrigins,\n getMoviePoster,\n getMoviePremieres,\n getMovieRandomPhoto,\n getMovieRating,\n getMovieRatingCount,\n getMovieTags,\n getMovieTitle,\n getMovieTitlesOther,\n getMovieTrivia,\n getMovieType,\n getMovieVods,\n getMovieYear\n} from '../helpers/movie.helper';\nimport { CSFDOptions } from '../types';\nimport { movieUrl } from '../vars';\n\nexport class MovieScraper {\n public async movie(movieId: number, options?: CSFDOptions): Promise<CSFDMovie> {\n const id = Number(movieId);\n if (isNaN(id)) {\n throw new Error('node-csfd-api: movieId must be a valid number');\n }\n const url = movieUrl(id, { language: options?.language });\n const response = await fetchPage(url, { ...options?.request });\n\n const movieHtml = parse(response);\n\n const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');\n const asideNode = movieHtml.querySelector('.aside-movie-profile');\n const movieNode = movieHtml.querySelector('.main-movie-profile');\n const jsonLdString = movieHtml.querySelector('script[type=\"application/ld+json\"]').innerText;\n let jsonLd: MovieJsonLd | null = null;\n try {\n jsonLd = JSON.parse(jsonLdString);\n } catch (e) {\n console.error('node-csfd-api: Error parsing JSON-LD', e);\n }\n return this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd, options);\n }\n\n private buildMovie(\n movieId: number,\n el: HTMLElement,\n asideEl: HTMLElement,\n pageClasses: string[],\n jsonLd: MovieJsonLd | null,\n options: CSFDOptions\n ): CSFDMovie {\n return {\n id: movieId,\n title: getMovieTitle(el),\n year: getMovieYear(jsonLd),\n duration: getMovieDuration(jsonLd, el),\n descriptions: getMovieDescriptions(el),\n genres: getMovieGenres(el),\n type: getMovieType(el) as CSFDFilmTypes,\n url: movieUrl(movieId, { language: options?.language }),\n origins: getMovieOrigins(el),\n colorRating: getMovieColorRating(pageClasses),\n rating: getMovieRating(asideEl),\n ratingCount: getMovieRatingCount(asideEl),\n titlesOther: getMovieTitlesOther(el),\n poster: getMoviePoster(el),\n photo: getMovieRandomPhoto(el),\n trivia: getMovieTrivia(el),\n creators: getMovieCreators(el, options),\n vod: getMovieVods(asideEl),\n tags: getMovieTags(asideEl),\n premieres: getMoviePremieres(asideEl),\n related: getMovieBoxMovies(asideEl, 'Související'),\n similar: getMovieBoxMovies(asideEl, 'Podobné')\n };\n }\n}\n"],"mappings":";;;;;;AA4BA,IAAa,eAAb,MAA0B;CACxB,MAAa,MAAM,SAAiB,SAA2C;EAC7E,MAAM,KAAK,OAAO,QAAQ;AAC1B,MAAI,MAAM,GAAG,CACX,OAAM,IAAI,MAAM,gDAAgD;EAKlE,MAAM,wCAFW,MAAMA,wBADXC,sBAAS,IAAI,EAAE,UAAU,SAAS,UAAU,CAAC,EACnB,EAAE,GAAG,SAAS,SAAS,CAAC,CAE7B;EAEjC,MAAM,cAAc,UAAU,cAAc,gBAAgB,CAAC,WAAW,MAAM,IAAI;EAClF,MAAM,YAAY,UAAU,cAAc,uBAAuB;EACjE,MAAM,YAAY,UAAU,cAAc,sBAAsB;EAChE,MAAM,eAAe,UAAU,cAAc,uCAAqC,CAAC;EACnF,IAAI,SAA6B;AACjC,MAAI;AACF,YAAS,KAAK,MAAM,aAAa;WAC1B,GAAG;AACV,WAAQ,MAAM,wCAAwC,EAAE;;AAE1D,SAAO,KAAK,WAAW,CAAC,SAAS,WAAW,WAAW,aAAa,QAAQ,QAAQ;;CAGtF,AAAQ,WACN,SACA,IACA,SACA,aACA,QACA,SACW;AACX,SAAO;GACL,IAAI;GACJ,OAAOC,mCAAc,GAAG;GACxB,MAAMC,kCAAa,OAAO;GAC1B,UAAUC,sCAAiB,QAAQ,GAAG;GACtC,cAAcC,0CAAqB,GAAG;GACtC,QAAQC,oCAAe,GAAG;GAC1B,MAAMC,kCAAa,GAAG;GACtB,KAAKN,sBAAS,SAAS,EAAE,UAAU,SAAS,UAAU,CAAC;GACvD,SAASO,qCAAgB,GAAG;GAC5B,aAAaC,yCAAoB,YAAY;GAC7C,QAAQC,oCAAe,QAAQ;GAC/B,aAAaC,yCAAoB,QAAQ;GACzC,aAAaC,yCAAoB,GAAG;GACpC,QAAQC,oCAAe,GAAG;GAC1B,OAAOC,yCAAoB,GAAG;GAC9B,QAAQC,oCAAe,GAAG;GAC1B,UAAUC,sCAAiB,IAAI,QAAQ;GACvC,KAAKC,kCAAa,QAAQ;GAC1B,MAAMC,kCAAa,QAAQ;GAC3B,WAAWC,uCAAkB,QAAQ;GACrC,SAASC,uCAAkB,SAAS,cAAc;GAClD,SAASA,uCAAkB,SAAS,UAAU;GAC/C"}
@@ -1,6 +1,6 @@
1
1
  import { fetchPage } from "../fetchers/index.mjs";
2
2
  import { movieUrl } from "../vars.mjs";
3
- import { detectSeasonOrEpisodeListType, getEpisodeCode, getMovieBoxMovies, getMovieColorRating, getMovieCreators, getMovieDescriptions, getMovieDuration, getMovieGenres, getMovieOrigins, getMoviePoster, getMoviePremieres, getMovieRandomPhoto, getMovieRating, getMovieRatingCount, getMovieTags, getMovieTitle, getMovieTitlesOther, getMovieTrivia, getMovieType, getMovieVods, getMovieYear, getSeasonOrEpisodeParent, getSeasonsOrEpisodes, getSeriesAndSeasonTitle } from "../helpers/movie.helper.mjs";
3
+ import { getMovieBoxMovies, getMovieColorRating, getMovieCreators, getMovieDescriptions, getMovieDuration, getMovieGenres, getMovieOrigins, getMoviePoster, getMoviePremieres, getMovieRandomPhoto, getMovieRating, getMovieRatingCount, getMovieTags, getMovieTitle, getMovieTitlesOther, getMovieTrivia, getMovieType, getMovieVods, getMovieYear } from "../helpers/movie.helper.mjs";
4
4
  import { parse } from "node-html-parser";
5
5
 
6
6
  //#region src/services/movie.service.ts
@@ -22,18 +22,14 @@ var MovieScraper = class {
22
22
  return this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd, options);
23
23
  }
24
24
  buildMovie(movieId, el, asideEl, pageClasses, jsonLd, options) {
25
- const type = getMovieType(el);
26
- const { seriesName = null, seasonName = null } = type === "season" ? getSeriesAndSeasonTitle(el) : {};
27
- const seasonOrEpisodeListType = detectSeasonOrEpisodeListType(el);
28
- const title = type === "season" && seriesName ? seriesName : getMovieTitle(el);
29
25
  return {
30
26
  id: movieId,
31
- title,
27
+ title: getMovieTitle(el),
32
28
  year: getMovieYear(jsonLd),
33
29
  duration: getMovieDuration(jsonLd, el),
34
30
  descriptions: getMovieDescriptions(el),
35
31
  genres: getMovieGenres(el),
36
- type,
32
+ type: getMovieType(el),
37
33
  url: movieUrl(movieId, { language: options?.language }),
38
34
  origins: getMovieOrigins(el),
39
35
  colorRating: getMovieColorRating(pageClasses),
@@ -48,15 +44,7 @@ var MovieScraper = class {
48
44
  tags: getMovieTags(asideEl),
49
45
  premieres: getMoviePremieres(asideEl),
50
46
  related: getMovieBoxMovies(asideEl, "Související"),
51
- similar: getMovieBoxMovies(asideEl, "Podobné"),
52
- seasons: seasonOrEpisodeListType === "seasons" ? getSeasonsOrEpisodes(el) : null,
53
- episodes: seasonOrEpisodeListType === "episodes" ? getSeasonsOrEpisodes(el) : null,
54
- parent: type === "series" ? null : getSeasonOrEpisodeParent(el, {
55
- id: movieId,
56
- title
57
- }),
58
- episodeCode: type === "episode" ? getEpisodeCode(el) : null,
59
- seasonName
47
+ similar: getMovieBoxMovies(asideEl, "Podobné")
60
48
  };
61
49
  }
62
50
  };
@@ -1 +1 @@
1
- {"version":3,"file":"movie.service.mjs","names":[],"sources":["../../src/services/movie.service.ts"],"sourcesContent":["import { HTMLElement, parse } from 'node-html-parser';\nimport { CSFDFilmTypes } from '../dto/global';\nimport { CSFDMovie, MovieJsonLd } from '../dto/movie';\nimport { fetchPage } from '../fetchers';\nimport {\n detectSeasonOrEpisodeListType,\n getEpisodeCode,\n getMovieBoxMovies,\n getMovieColorRating,\n getMovieCreators,\n getMovieDescriptions,\n getMovieDuration,\n getMovieGenres,\n getMovieOrigins,\n getMoviePoster,\n getMoviePremieres,\n getMovieRandomPhoto,\n getMovieRating,\n getMovieRatingCount,\n getMovieTags,\n getMovieTitle,\n getMovieTitlesOther,\n getMovieTrivia,\n getMovieType,\n getMovieVods,\n getMovieYear,\n getSeasonOrEpisodeParent,\n getSeasonsOrEpisodes,\n getSeriesAndSeasonTitle\n} from '../helpers/movie.helper';\nimport { CSFDOptions } from '../types';\nimport { movieUrl } from '../vars';\n\nexport class MovieScraper {\n public async movie(movieId: number, options?: CSFDOptions): Promise<CSFDMovie> {\n const id = Number(movieId);\n if (isNaN(id)) {\n throw new Error('node-csfd-api: movieId must be a valid number');\n }\n const url = movieUrl(id, { language: options?.language });\n const response = await fetchPage(url, { ...options?.request });\n\n const movieHtml = parse(response);\n\n const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');\n const asideNode = movieHtml.querySelector('.aside-movie-profile');\n const movieNode = movieHtml.querySelector('.main-movie-profile');\n const jsonLdString = movieHtml.querySelector('script[type=\"application/ld+json\"]').innerText;\n let jsonLd: MovieJsonLd | null = null;\n try {\n jsonLd = JSON.parse(jsonLdString);\n } catch (e) {\n console.error('node-csfd-api: Error parsing JSON-LD', e);\n }\n return this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd, options);\n }\n\n private buildMovie(\n movieId: number,\n el: HTMLElement,\n asideEl: HTMLElement,\n pageClasses: string[],\n jsonLd: MovieJsonLd | null,\n options: CSFDOptions\n ) {\n const type = getMovieType(el) as CSFDFilmTypes;\n const { seriesName = null, seasonName = null } =\n type === 'season' ? getSeriesAndSeasonTitle(el) : {};\n const seasonOrEpisodeListType = detectSeasonOrEpisodeListType(el);\n\n const title = type === 'season' && seriesName ? seriesName : getMovieTitle(el);\n return {\n id: movieId,\n title,\n year: getMovieYear(jsonLd),\n duration: getMovieDuration(jsonLd, el),\n descriptions: getMovieDescriptions(el),\n genres: getMovieGenres(el),\n type,\n url: movieUrl(movieId, { language: options?.language }),\n origins: getMovieOrigins(el),\n colorRating: getMovieColorRating(pageClasses),\n rating: getMovieRating(asideEl),\n ratingCount: getMovieRatingCount(asideEl),\n titlesOther: getMovieTitlesOther(el),\n poster: getMoviePoster(el),\n photo: getMovieRandomPhoto(el),\n trivia: getMovieTrivia(el),\n creators: getMovieCreators(el, options),\n vod: getMovieVods(asideEl),\n tags: getMovieTags(asideEl),\n premieres: getMoviePremieres(asideEl),\n related: getMovieBoxMovies(asideEl, 'Související'),\n similar: getMovieBoxMovies(asideEl, 'Podobné'),\n seasons: seasonOrEpisodeListType === 'seasons' ? getSeasonsOrEpisodes(el) : null,\n episodes: seasonOrEpisodeListType === 'episodes' ? getSeasonsOrEpisodes(el) : null,\n parent: type === 'series' ? null : getSeasonOrEpisodeParent(el, { id: movieId, title }),\n episodeCode: type === 'episode' ? getEpisodeCode(el) : null,\n seasonName\n };\n }\n}\n"],"mappings":";;;;;;AAiCA,IAAa,eAAb,MAA0B;CACxB,MAAa,MAAM,SAAiB,SAA2C;EAC7E,MAAM,KAAK,OAAO,QAAQ;AAC1B,MAAI,MAAM,GAAG,CACX,OAAM,IAAI,MAAM,gDAAgD;EAKlE,MAAM,YAAY,MAFD,MAAM,UADX,SAAS,IAAI,EAAE,UAAU,SAAS,UAAU,CAAC,EACnB,EAAE,GAAG,SAAS,SAAS,CAAC,CAE7B;EAEjC,MAAM,cAAc,UAAU,cAAc,gBAAgB,CAAC,WAAW,MAAM,IAAI;EAClF,MAAM,YAAY,UAAU,cAAc,uBAAuB;EACjE,MAAM,YAAY,UAAU,cAAc,sBAAsB;EAChE,MAAM,eAAe,UAAU,cAAc,uCAAqC,CAAC;EACnF,IAAI,SAA6B;AACjC,MAAI;AACF,YAAS,KAAK,MAAM,aAAa;WAC1B,GAAG;AACV,WAAQ,MAAM,wCAAwC,EAAE;;AAE1D,SAAO,KAAK,WAAW,CAAC,SAAS,WAAW,WAAW,aAAa,QAAQ,QAAQ;;CAGtF,AAAQ,WACN,SACA,IACA,SACA,aACA,QACA,SACA;EACA,MAAM,OAAO,aAAa,GAAG;EAC7B,MAAM,EAAE,aAAa,MAAM,aAAa,SACtC,SAAS,WAAW,wBAAwB,GAAG,GAAG,EAAE;EACtD,MAAM,0BAA0B,8BAA8B,GAAG;EAEjE,MAAM,QAAQ,SAAS,YAAY,aAAa,aAAa,cAAc,GAAG;AAC9E,SAAO;GACL,IAAI;GACJ;GACA,MAAM,aAAa,OAAO;GAC1B,UAAU,iBAAiB,QAAQ,GAAG;GACtC,cAAc,qBAAqB,GAAG;GACtC,QAAQ,eAAe,GAAG;GAC1B;GACA,KAAK,SAAS,SAAS,EAAE,UAAU,SAAS,UAAU,CAAC;GACvD,SAAS,gBAAgB,GAAG;GAC5B,aAAa,oBAAoB,YAAY;GAC7C,QAAQ,eAAe,QAAQ;GAC/B,aAAa,oBAAoB,QAAQ;GACzC,aAAa,oBAAoB,GAAG;GACpC,QAAQ,eAAe,GAAG;GAC1B,OAAO,oBAAoB,GAAG;GAC9B,QAAQ,eAAe,GAAG;GAC1B,UAAU,iBAAiB,IAAI,QAAQ;GACvC,KAAK,aAAa,QAAQ;GAC1B,MAAM,aAAa,QAAQ;GAC3B,WAAW,kBAAkB,QAAQ;GACrC,SAAS,kBAAkB,SAAS,cAAc;GAClD,SAAS,kBAAkB,SAAS,UAAU;GAC9C,SAAS,4BAA4B,YAAY,qBAAqB,GAAG,GAAG;GAC5E,UAAU,4BAA4B,aAAa,qBAAqB,GAAG,GAAG;GAC9E,QAAQ,SAAS,WAAW,OAAO,yBAAyB,IAAI;IAAE,IAAI;IAAS;IAAO,CAAC;GACvF,aAAa,SAAS,YAAY,eAAe,GAAG,GAAG;GACvD;GACD"}
1
+ {"version":3,"file":"movie.service.mjs","names":[],"sources":["../../src/services/movie.service.ts"],"sourcesContent":["import { HTMLElement, parse } from 'node-html-parser';\nimport { CSFDFilmTypes } from '../dto/global';\nimport { CSFDMovie, MovieJsonLd } from '../dto/movie';\nimport { fetchPage } from '../fetchers';\nimport {\n getMovieBoxMovies,\n getMovieColorRating,\n getMovieCreators,\n getMovieDescriptions,\n getMovieDuration,\n getMovieGenres,\n getMovieOrigins,\n getMoviePoster,\n getMoviePremieres,\n getMovieRandomPhoto,\n getMovieRating,\n getMovieRatingCount,\n getMovieTags,\n getMovieTitle,\n getMovieTitlesOther,\n getMovieTrivia,\n getMovieType,\n getMovieVods,\n getMovieYear\n} from '../helpers/movie.helper';\nimport { CSFDOptions } from '../types';\nimport { movieUrl } from '../vars';\n\nexport class MovieScraper {\n public async movie(movieId: number, options?: CSFDOptions): Promise<CSFDMovie> {\n const id = Number(movieId);\n if (isNaN(id)) {\n throw new Error('node-csfd-api: movieId must be a valid number');\n }\n const url = movieUrl(id, { language: options?.language });\n const response = await fetchPage(url, { ...options?.request });\n\n const movieHtml = parse(response);\n\n const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');\n const asideNode = movieHtml.querySelector('.aside-movie-profile');\n const movieNode = movieHtml.querySelector('.main-movie-profile');\n const jsonLdString = movieHtml.querySelector('script[type=\"application/ld+json\"]').innerText;\n let jsonLd: MovieJsonLd | null = null;\n try {\n jsonLd = JSON.parse(jsonLdString);\n } catch (e) {\n console.error('node-csfd-api: Error parsing JSON-LD', e);\n }\n return this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd, options);\n }\n\n private buildMovie(\n movieId: number,\n el: HTMLElement,\n asideEl: HTMLElement,\n pageClasses: string[],\n jsonLd: MovieJsonLd | null,\n options: CSFDOptions\n ): CSFDMovie {\n return {\n id: movieId,\n title: getMovieTitle(el),\n year: getMovieYear(jsonLd),\n duration: getMovieDuration(jsonLd, el),\n descriptions: getMovieDescriptions(el),\n genres: getMovieGenres(el),\n type: getMovieType(el) as CSFDFilmTypes,\n url: movieUrl(movieId, { language: options?.language }),\n origins: getMovieOrigins(el),\n colorRating: getMovieColorRating(pageClasses),\n rating: getMovieRating(asideEl),\n ratingCount: getMovieRatingCount(asideEl),\n titlesOther: getMovieTitlesOther(el),\n poster: getMoviePoster(el),\n photo: getMovieRandomPhoto(el),\n trivia: getMovieTrivia(el),\n creators: getMovieCreators(el, options),\n vod: getMovieVods(asideEl),\n tags: getMovieTags(asideEl),\n premieres: getMoviePremieres(asideEl),\n related: getMovieBoxMovies(asideEl, 'Související'),\n similar: getMovieBoxMovies(asideEl, 'Podobné')\n };\n }\n}\n"],"mappings":";;;;;;AA4BA,IAAa,eAAb,MAA0B;CACxB,MAAa,MAAM,SAAiB,SAA2C;EAC7E,MAAM,KAAK,OAAO,QAAQ;AAC1B,MAAI,MAAM,GAAG,CACX,OAAM,IAAI,MAAM,gDAAgD;EAKlE,MAAM,YAAY,MAFD,MAAM,UADX,SAAS,IAAI,EAAE,UAAU,SAAS,UAAU,CAAC,EACnB,EAAE,GAAG,SAAS,SAAS,CAAC,CAE7B;EAEjC,MAAM,cAAc,UAAU,cAAc,gBAAgB,CAAC,WAAW,MAAM,IAAI;EAClF,MAAM,YAAY,UAAU,cAAc,uBAAuB;EACjE,MAAM,YAAY,UAAU,cAAc,sBAAsB;EAChE,MAAM,eAAe,UAAU,cAAc,uCAAqC,CAAC;EACnF,IAAI,SAA6B;AACjC,MAAI;AACF,YAAS,KAAK,MAAM,aAAa;WAC1B,GAAG;AACV,WAAQ,MAAM,wCAAwC,EAAE;;AAE1D,SAAO,KAAK,WAAW,CAAC,SAAS,WAAW,WAAW,aAAa,QAAQ,QAAQ;;CAGtF,AAAQ,WACN,SACA,IACA,SACA,aACA,QACA,SACW;AACX,SAAO;GACL,IAAI;GACJ,OAAO,cAAc,GAAG;GACxB,MAAM,aAAa,OAAO;GAC1B,UAAU,iBAAiB,QAAQ,GAAG;GACtC,cAAc,qBAAqB,GAAG;GACtC,QAAQ,eAAe,GAAG;GAC1B,MAAM,aAAa,GAAG;GACtB,KAAK,SAAS,SAAS,EAAE,UAAU,SAAS,UAAU,CAAC;GACvD,SAAS,gBAAgB,GAAG;GAC5B,aAAa,oBAAoB,YAAY;GAC7C,QAAQ,eAAe,QAAQ;GAC/B,aAAa,oBAAoB,QAAQ;GACzC,aAAa,oBAAoB,GAAG;GACpC,QAAQ,eAAe,GAAG;GAC1B,OAAO,oBAAoB,GAAG;GAC9B,QAAQ,eAAe,GAAG;GAC1B,UAAU,iBAAiB,IAAI,QAAQ;GACvC,KAAK,aAAa,QAAQ;GAC1B,MAAM,aAAa,QAAQ;GAC3B,WAAW,kBAAkB,QAAQ;GACrC,SAAS,kBAAkB,SAAS,cAAc;GAClD,SAAS,kBAAkB,SAAS,UAAU;GAC/C"}