node-csfd-api 5.8.0 → 5.8.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/cli.js CHANGED
@@ -141,7 +141,7 @@ async function main() {
141
141
  }
142
142
  case "--version":
143
143
  case "-v":
144
- console.log(c.bold("5.8.0"));
144
+ console.log(c.bold("5.8.1"));
145
145
  break;
146
146
  case "update":
147
147
  await runUpdate();
@@ -234,15 +234,15 @@ async function checkForUpdateInBackground() {
234
234
  } catch {}
235
235
  }
236
236
  } catch {}
237
- if (!latestVersion || compareSemver("5.8.0", latestVersion) >= 0) return;
237
+ if (!latestVersion || compareSemver("5.8.1", latestVersion) >= 0) return;
238
238
  console.log("");
239
239
  console.log(c.dim(" " + "─".repeat(44)));
240
- console.log(` ${c.yellow(c.bold("↑ Update available:"))} ${c.dim("5.8.0")} → ${c.bold(c.green(latestVersion))}`);
240
+ console.log(` ${c.yellow(c.bold("↑ Update available:"))} ${c.dim("5.8.1")} → ${c.bold(c.green(latestVersion))}`);
241
241
  console.log(` ${c.dim("Run")} ${c.cyan(getCommandName() + " update")} ${c.dim("for upgrade instructions.")}`);
242
242
  } catch {}
243
243
  }
244
244
  async function runUpdate() {
245
- console.log(c.dim("Current version: ") + c.bold("5.8.0"));
245
+ console.log(c.dim("Current version: ") + c.bold("5.8.1"));
246
246
  console.log(c.dim("Checking for updates..."));
247
247
  let latest;
248
248
  try {
@@ -255,7 +255,7 @@ async function runUpdate() {
255
255
  console.error(err("Could not determine latest version."));
256
256
  process.exit(1);
257
257
  }
258
- const cmp = compareSemver("5.8.0", latest);
258
+ const cmp = compareSemver("5.8.1", latest);
259
259
  if (cmp === 0) {
260
260
  console.log(c.green("✔ Already up to date."));
261
261
  return;
@@ -268,7 +268,7 @@ async function runUpdate() {
268
268
  }
269
269
  function printUsage() {
270
270
  const cmd = getCommandName();
271
- const header = c.bold(c.cyan("csfd")) + " " + c.dim(`v5.8.0`);
271
+ const header = c.bold(c.cyan("csfd")) + " " + c.dim(`v5.8.1`);
272
272
  const usage = c.bold("Usage:") + ` ${c.cyan(cmd)} ${c.dim("<command> [options]")}`;
273
273
  const section = (title) => c.bold(title);
274
274
  const cmd_ = (name) => " " + c.cyan(name);
@@ -4,8 +4,10 @@ const ISO8601_DURATION_REGEX = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W
4
4
  const parseIdFromUrl = (url) => {
5
5
  if (!url) return null;
6
6
  const parts = url.split("/");
7
- const idParts = parts.filter((p) => /^\d+-/.test(p));
8
- if (idParts.length > 0) return +idParts[idParts.length - 1].split("-")[0] || null;
7
+ for (let i = parts.length - 1; i >= 0; i--) {
8
+ const p = parts[i];
9
+ if (/^\d+-/.test(p)) return +p.split("-")[0] || null;
10
+ }
9
11
  return +parts[LANG_PREFIX_REGEX.test(parts[1]) ? 3 : 2]?.split("-")[0] || null;
10
12
  };
11
13
  const parseLastIdFromUrl = (url) => {
@@ -1 +1 @@
1
- {"version":3,"file":"global.helper.cjs","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 const idParts = parts.filter((p) => /^\\d+-/.test(p));\n if (idParts.length > 0) {\n const idSlug = idParts[idParts.length - 1];\n return +idSlug.split('-')[0] || null;\n }\n\n // Fallback\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\nconst PAGE_COLORS: Record<string, CSFDColorRating> = {\n 'page-lightgrey': 'unknown',\n 'page-red': 'good',\n 'page-blue': 'average',\n 'page-grey': 'bad'\n};\n\nexport const getColor = (cls: string): CSFDColorRating => {\n return PAGE_COLORS[cls] || 'unknown';\n};\n\nconst RATING_COLORS: Record<CSFDColors, CSFDColorRating> = {\n lightgrey: 'unknown',\n red: 'good',\n blue: 'average',\n grey: 'bad'\n};\n\nexport const parseColor = (quality: CSFDColors): CSFDColorRating => {\n return RATING_COLORS[quality] || 'unknown';\n};\n\nconst FILM_TYPES: 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 FILM_TYPES[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;CAC5B,MAAM,UAAU,MAAM,QAAQ,MAAM,QAAQ,KAAK,EAAE,CAAC;AACpD,KAAI,QAAQ,SAAS,EAEnB,QAAO,CADQ,QAAQ,QAAQ,SAAS,GACzB,MAAM,IAAI,CAAC,MAAM;AAOlC,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,MAAM,cAA+C;CACnD,kBAAkB;CAClB,YAAY;CACZ,aAAa;CACb,aAAa;CACd;AAED,MAAa,YAAY,QAAiC;AACxD,QAAO,YAAY,QAAQ;;AAG7B,MAAM,gBAAqD;CACzD,WAAW;CACX,KAAK;CACL,MAAM;CACN,MAAM;CACP;AAED,MAAa,cAAc,YAAyC;AAClE,QAAO,cAAc,YAAY;;AAGnC,MAAM,aAA4C;CAChD,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,WAAW,SAAS;;AAG7B,MAAa,eAAe,QAAwB;AAClD,QAAO,IAAI,WAAW,KAAK,GAAG,WAAW,MAAM;;AAGjD,MAAa,eAAe,YAA8B;AACxD,QAAO;EACL,MAAM,QAAQ,OAAO,KAAA,IAAY,MAAM;EACvC,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,QAAQ,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC/C,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,MAAM,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC7C,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,SAAS,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAChD,SAAS,QAAQ,OAAO,KAAA,IAAY,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.cjs","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\n // Reverse loop to find the ID slug efficiently without allocating intermediate arrays\n for (let i = parts.length - 1; i >= 0; i--) {\n const p = parts[i];\n if (/^\\d+-/.test(p)) {\n return +p.split('-')[0] || null;\n }\n }\n\n // Fallback\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\nconst PAGE_COLORS: Record<string, CSFDColorRating> = {\n 'page-lightgrey': 'unknown',\n 'page-red': 'good',\n 'page-blue': 'average',\n 'page-grey': 'bad'\n};\n\nexport const getColor = (cls: string): CSFDColorRating => {\n return PAGE_COLORS[cls] || 'unknown';\n};\n\nconst RATING_COLORS: Record<CSFDColors, CSFDColorRating> = {\n lightgrey: 'unknown',\n red: 'good',\n blue: 'average',\n grey: 'bad'\n};\n\nexport const parseColor = (quality: CSFDColors): CSFDColorRating => {\n return RATING_COLORS[quality] || 'unknown';\n};\n\nconst FILM_TYPES: 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 FILM_TYPES[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;AAG5B,MAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;EAC1C,MAAM,IAAI,MAAM;AAChB,MAAI,QAAQ,KAAK,EAAE,CACjB,QAAO,CAAC,EAAE,MAAM,IAAI,CAAC,MAAM;;AAQ/B,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,MAAM,cAA+C;CACnD,kBAAkB;CAClB,YAAY;CACZ,aAAa;CACb,aAAa;CACd;AAED,MAAa,YAAY,QAAiC;AACxD,QAAO,YAAY,QAAQ;;AAG7B,MAAM,gBAAqD;CACzD,WAAW;CACX,KAAK;CACL,MAAM;CACN,MAAM;CACP;AAED,MAAa,cAAc,YAAyC;AAClE,QAAO,cAAc,YAAY;;AAGnC,MAAM,aAA4C;CAChD,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,WAAW,SAAS;;AAG7B,MAAa,eAAe,QAAwB;AAClD,QAAO,IAAI,WAAW,KAAK,GAAG,WAAW,MAAM;;AAGjD,MAAa,eAAe,YAA8B;AACxD,QAAO;EACL,MAAM,QAAQ,OAAO,KAAA,IAAY,MAAM;EACvC,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,QAAQ,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC/C,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,MAAM,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC7C,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,SAAS,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAChD,SAAS,QAAQ,OAAO,KAAA,IAAY,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"}
@@ -4,8 +4,10 @@ const ISO8601_DURATION_REGEX = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W
4
4
  const parseIdFromUrl = (url) => {
5
5
  if (!url) return null;
6
6
  const parts = url.split("/");
7
- const idParts = parts.filter((p) => /^\d+-/.test(p));
8
- if (idParts.length > 0) return +idParts[idParts.length - 1].split("-")[0] || null;
7
+ for (let i = parts.length - 1; i >= 0; i--) {
8
+ const p = parts[i];
9
+ if (/^\d+-/.test(p)) return +p.split("-")[0] || null;
10
+ }
9
11
  return +parts[LANG_PREFIX_REGEX.test(parts[1]) ? 3 : 2]?.split("-")[0] || null;
10
12
  };
11
13
  const parseLastIdFromUrl = (url) => {
@@ -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 const idParts = parts.filter((p) => /^\\d+-/.test(p));\n if (idParts.length > 0) {\n const idSlug = idParts[idParts.length - 1];\n return +idSlug.split('-')[0] || null;\n }\n\n // Fallback\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\nconst PAGE_COLORS: Record<string, CSFDColorRating> = {\n 'page-lightgrey': 'unknown',\n 'page-red': 'good',\n 'page-blue': 'average',\n 'page-grey': 'bad'\n};\n\nexport const getColor = (cls: string): CSFDColorRating => {\n return PAGE_COLORS[cls] || 'unknown';\n};\n\nconst RATING_COLORS: Record<CSFDColors, CSFDColorRating> = {\n lightgrey: 'unknown',\n red: 'good',\n blue: 'average',\n grey: 'bad'\n};\n\nexport const parseColor = (quality: CSFDColors): CSFDColorRating => {\n return RATING_COLORS[quality] || 'unknown';\n};\n\nconst FILM_TYPES: 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 FILM_TYPES[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;CAC5B,MAAM,UAAU,MAAM,QAAQ,MAAM,QAAQ,KAAK,EAAE,CAAC;AACpD,KAAI,QAAQ,SAAS,EAEnB,QAAO,CADQ,QAAQ,QAAQ,SAAS,GACzB,MAAM,IAAI,CAAC,MAAM;AAOlC,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,MAAM,cAA+C;CACnD,kBAAkB;CAClB,YAAY;CACZ,aAAa;CACb,aAAa;CACd;AAED,MAAa,YAAY,QAAiC;AACxD,QAAO,YAAY,QAAQ;;AAG7B,MAAM,gBAAqD;CACzD,WAAW;CACX,KAAK;CACL,MAAM;CACN,MAAM;CACP;AAED,MAAa,cAAc,YAAyC;AAClE,QAAO,cAAc,YAAY;;AAGnC,MAAM,aAA4C;CAChD,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,WAAW,SAAS;;AAG7B,MAAa,eAAe,QAAwB;AAClD,QAAO,IAAI,WAAW,KAAK,GAAG,WAAW,MAAM;;AAGjD,MAAa,eAAe,YAA8B;AACxD,QAAO;EACL,MAAM,QAAQ,OAAO,KAAA,IAAY,MAAM;EACvC,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,QAAQ,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC/C,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,MAAM,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC7C,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,SAAS,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAChD,SAAS,QAAQ,OAAO,KAAA,IAAY,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\n // Reverse loop to find the ID slug efficiently without allocating intermediate arrays\n for (let i = parts.length - 1; i >= 0; i--) {\n const p = parts[i];\n if (/^\\d+-/.test(p)) {\n return +p.split('-')[0] || null;\n }\n }\n\n // Fallback\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\nconst PAGE_COLORS: Record<string, CSFDColorRating> = {\n 'page-lightgrey': 'unknown',\n 'page-red': 'good',\n 'page-blue': 'average',\n 'page-grey': 'bad'\n};\n\nexport const getColor = (cls: string): CSFDColorRating => {\n return PAGE_COLORS[cls] || 'unknown';\n};\n\nconst RATING_COLORS: Record<CSFDColors, CSFDColorRating> = {\n lightgrey: 'unknown',\n red: 'good',\n blue: 'average',\n grey: 'bad'\n};\n\nexport const parseColor = (quality: CSFDColors): CSFDColorRating => {\n return RATING_COLORS[quality] || 'unknown';\n};\n\nconst FILM_TYPES: 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 FILM_TYPES[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;AAG5B,MAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;EAC1C,MAAM,IAAI,MAAM;AAChB,MAAI,QAAQ,KAAK,EAAE,CACjB,QAAO,CAAC,EAAE,MAAM,IAAI,CAAC,MAAM;;AAQ/B,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,MAAM,cAA+C;CACnD,kBAAkB;CAClB,YAAY;CACZ,aAAa;CACb,aAAa;CACd;AAED,MAAa,YAAY,QAAiC;AACxD,QAAO,YAAY,QAAQ;;AAG7B,MAAM,gBAAqD;CACzD,WAAW;CACX,KAAK;CACL,MAAM;CACN,MAAM;CACP;AAED,MAAa,cAAc,YAAyC;AAClE,QAAO,cAAc,YAAY;;AAGnC,MAAM,aAA4C;CAChD,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,WAAW,SAAS;;AAG7B,MAAa,eAAe,QAAwB;AAClD,QAAO,IAAI,WAAW,KAAK,GAAG,WAAW,MAAM;;AAGjD,MAAa,eAAe,YAA8B;AACxD,QAAO;EACL,MAAM,QAAQ,OAAO,KAAA,IAAY,MAAM;EACvC,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,QAAQ,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC/C,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,MAAM,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC7C,OAAO,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAC9C,SAAS,QAAQ,OAAO,KAAA,IAAY,IAAI,QAAQ;EAChD,SAAS,QAAQ,OAAO,KAAA,IAAY,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"}
package/package.js 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.8.0";
4
+ var version = "5.8.1";
5
5
  var homepage = "https://github.com/bartholomej/node-csfd-api#readme";
6
6
 
7
7
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-csfd-api",
3
- "version": "5.8.0",
3
+ "version": "5.8.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": {
@@ -8,8 +8,8 @@
8
8
  "registry": "https://registry.npmjs.org"
9
9
  },
10
10
  "dependencies": {
11
- "@modelcontextprotocol/sdk": "^1.28.0",
12
- "dotenv": "^17.3.1",
11
+ "@modelcontextprotocol/sdk": "^1.29.0",
12
+ "dotenv": "^17.4.1",
13
13
  "express": "^5.2.1",
14
14
  "node-html-parser": "^7.1.0",
15
15
  "zod": "^4.3.6"