@zfadhli/tokrec 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/config.mjs +1 -1
- package/dist/lib/config.mjs.map +1 -1
- package/dist/package.mjs +1 -1
- package/package.json +1 -1
package/dist/lib/config.mjs
CHANGED
package/dist/lib/config.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../../src/lib/config.ts"],"sourcesContent":["/**\n * Config — types, defaults, and normalization for the recorder.\n * The single source of truth for every user-facing option.\n */\n\n/**\n * TikTok cookie key-value pairs extracted from Firefox or cookies.json.\n * Includes session cookies (sessionid_ss, tt-target-idc) and any WAF\n * bypass cookies needed to avoid Slardar challenges on www.tiktok.com.\n */\nexport type CookieAuth = Record<string, string>\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\"\n\nexport interface RecorderConfig {\n /** TikTok username (required) */\n user: string\n /** Output directory for recordings (default: ./recordings) */\n outputDir?: string\n /** Polling interval in minutes (default: 3) */\n interval?: number\n /** Max recording duration in seconds (default: 0 — unlimited). CLI accepts minutes, converted internally. */\n duration?: number\n /** HTTP proxy URL (e.g. http://127.0.0.1:8080) */\n proxy?: string\n /** Path to cookies.json (default: ./cookies.json) */\n cookiesPath?: string\n /** Cookie auth loaded from cookies.json */\n cookies?: CookieAuth\n /** Log level (default: info) */\n logLevel?: LogLevel\n /** Whether to print logs to console (default: true). Set false when using Display-based UI. */\n logConsole?: boolean\n /** Segment duration in minutes (default: 0 — disabled). When >= 1, the recording is split into segments of this length. */\n segmentMinutes?: number\n /** Normalize audio loudness via EBU R128 (default: false). */\n normalizeAudio?: boolean\n /** Target loudness in LUFS (default: -14). */\n normalizeLoudness?: number\n /** Audio codec for normalized output (default: peaknorm's default, \"libopus\"). */\n normalizeCodec?: string\n /** Audio bitrate for normalized output (default: peaknorm's default, \"96k\"). */\n normalizeBitrate?: string\n /**\n * Max API requests per second (default: 5).\n * Prevents TikTok WAF triggering on rapid polling or URL refresh loops.\n * Set to 0 for unlimited (not recommended).\n */\n ratePerSecond?: number\n /** Show API debug logging on stderr (default: false). */\n debug?: boolean\n}\n\nexport interface RecorderController {\n /** Start the polling loop */\n start(): Promise<void>\n /** Gracefully stop (joins active recording, then exits) */\n stop(): Promise<void>\n /** Snapshot of current state */\n getStatus(): RecorderStatus\n /** Subscribe to events */\n on<E extends keyof RecorderEventHandler>(event: E, handler: RecorderEventHandler[E]): void\n /** Unsubscribe a previously registered event handler */\n off<E extends keyof RecorderEventHandler>(event: E, handler: RecorderEventHandler[E]): void\n}\n\nexport interface RecorderStatus {\n state: \"idle\" | \"polling\" | \"recording\" | \"converting\" | \"stopped\"\n user: string\n currentFile?: string\n sessionDuration?: number\n lastPollTime?: string\n lastError?: string\n}\n\nexport type RecorderEvent = keyof RecorderEventHandler\n\nexport interface RecorderEventHandler {\n checking: (info: { user: string }) => void\n tick: (info: { user: string; isLive: boolean; roomId?: string }) => void\n \"recording:start\": (info: { user: string; file: string }) => void\n \"download:progress\": (info: { bytes: number; elapsed: number; speed: number }) => void\n \"download:end\": (info: { file: string; duration: number; size: number }) => void\n \"recording:end\": (info: { file: string; duration: number; size: number }) => void\n \"segmenting:start\": (info: { input: string; outputPattern: string }) => void\n \"segmenting:end\": (info: { segments: number }) => void\n \"converting:start\": (info: { input: string }) => void\n converted: (info: { input: string; output: string }) => void\n \"normalize:start\": (info: { file: string }) => void\n \"normalize:progress\": (info: {\n file: string\n percent: number\n phase: \"analyzing\" | \"normalizing\"\n }) => void\n \"normalize:end\": (info: { input: string; output: string }) => void\n \"normalize:error\": (info: { input: string; error: string }) => void\n error: (err: TikTokError) => void\n}\n\nexport type AppErrorKind =\n | \"user-not-live\"\n | \"room-not-found\"\n | \"stream-url-not-found\"\n | \"waf-blocked\"\n | \"country-blocked\"\n | \"network-error\"\n | \"ffmpeg-not-found\"\n | \"ffmpeg-error\"\n | \"aborted\"\n | \"config-error\"\n | \"unknown\"\n\nexport class TikTokError extends Error {\n constructor(\n public readonly kind: AppErrorKind,\n message: string,\n public override readonly cause?: unknown,\n ) {\n super(message)\n this.name = \"TikTokError\"\n }\n}\n\nconst DEFAULTS = {\n outputDir: \".\",\n interval: 3,\n duration: 0,\n logLevel: \"info\" as LogLevel,\n logConsole: true,\n segmentMinutes: 0,\n normalizeAudio:
|
|
1
|
+
{"version":3,"file":"config.mjs","names":[],"sources":["../../src/lib/config.ts"],"sourcesContent":["/**\n * Config — types, defaults, and normalization for the recorder.\n * The single source of truth for every user-facing option.\n */\n\n/**\n * TikTok cookie key-value pairs extracted from Firefox or cookies.json.\n * Includes session cookies (sessionid_ss, tt-target-idc) and any WAF\n * bypass cookies needed to avoid Slardar challenges on www.tiktok.com.\n */\nexport type CookieAuth = Record<string, string>\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\"\n\nexport interface RecorderConfig {\n /** TikTok username (required) */\n user: string\n /** Output directory for recordings (default: ./recordings) */\n outputDir?: string\n /** Polling interval in minutes (default: 3) */\n interval?: number\n /** Max recording duration in seconds (default: 0 — unlimited). CLI accepts minutes, converted internally. */\n duration?: number\n /** HTTP proxy URL (e.g. http://127.0.0.1:8080) */\n proxy?: string\n /** Path to cookies.json (default: ./cookies.json) */\n cookiesPath?: string\n /** Cookie auth loaded from cookies.json */\n cookies?: CookieAuth\n /** Log level (default: info) */\n logLevel?: LogLevel\n /** Whether to print logs to console (default: true). Set false when using Display-based UI. */\n logConsole?: boolean\n /** Segment duration in minutes (default: 0 — disabled). When >= 1, the recording is split into segments of this length. */\n segmentMinutes?: number\n /** Normalize audio loudness via EBU R128 (default: false). */\n normalizeAudio?: boolean\n /** Target loudness in LUFS (default: -14). */\n normalizeLoudness?: number\n /** Audio codec for normalized output (default: peaknorm's default, \"libopus\"). */\n normalizeCodec?: string\n /** Audio bitrate for normalized output (default: peaknorm's default, \"96k\"). */\n normalizeBitrate?: string\n /**\n * Max API requests per second (default: 5).\n * Prevents TikTok WAF triggering on rapid polling or URL refresh loops.\n * Set to 0 for unlimited (not recommended).\n */\n ratePerSecond?: number\n /** Show API debug logging on stderr (default: false). */\n debug?: boolean\n}\n\nexport interface RecorderController {\n /** Start the polling loop */\n start(): Promise<void>\n /** Gracefully stop (joins active recording, then exits) */\n stop(): Promise<void>\n /** Snapshot of current state */\n getStatus(): RecorderStatus\n /** Subscribe to events */\n on<E extends keyof RecorderEventHandler>(event: E, handler: RecorderEventHandler[E]): void\n /** Unsubscribe a previously registered event handler */\n off<E extends keyof RecorderEventHandler>(event: E, handler: RecorderEventHandler[E]): void\n}\n\nexport interface RecorderStatus {\n state: \"idle\" | \"polling\" | \"recording\" | \"converting\" | \"stopped\"\n user: string\n currentFile?: string\n sessionDuration?: number\n lastPollTime?: string\n lastError?: string\n}\n\nexport type RecorderEvent = keyof RecorderEventHandler\n\nexport interface RecorderEventHandler {\n checking: (info: { user: string }) => void\n tick: (info: { user: string; isLive: boolean; roomId?: string }) => void\n \"recording:start\": (info: { user: string; file: string }) => void\n \"download:progress\": (info: { bytes: number; elapsed: number; speed: number }) => void\n \"download:end\": (info: { file: string; duration: number; size: number }) => void\n \"recording:end\": (info: { file: string; duration: number; size: number }) => void\n \"segmenting:start\": (info: { input: string; outputPattern: string }) => void\n \"segmenting:end\": (info: { segments: number }) => void\n \"converting:start\": (info: { input: string }) => void\n converted: (info: { input: string; output: string }) => void\n \"normalize:start\": (info: { file: string }) => void\n \"normalize:progress\": (info: {\n file: string\n percent: number\n phase: \"analyzing\" | \"normalizing\"\n }) => void\n \"normalize:end\": (info: { input: string; output: string }) => void\n \"normalize:error\": (info: { input: string; error: string }) => void\n error: (err: TikTokError) => void\n}\n\nexport type AppErrorKind =\n | \"user-not-live\"\n | \"room-not-found\"\n | \"stream-url-not-found\"\n | \"waf-blocked\"\n | \"country-blocked\"\n | \"network-error\"\n | \"ffmpeg-not-found\"\n | \"ffmpeg-error\"\n | \"aborted\"\n | \"config-error\"\n | \"unknown\"\n\nexport class TikTokError extends Error {\n constructor(\n public readonly kind: AppErrorKind,\n message: string,\n public override readonly cause?: unknown,\n ) {\n super(message)\n this.name = \"TikTokError\"\n }\n}\n\nconst DEFAULTS = {\n outputDir: \".\",\n interval: 3,\n duration: 0,\n logLevel: \"info\" as LogLevel,\n logConsole: true,\n segmentMinutes: 0,\n normalizeAudio: false,\n normalizeLoudness: -14,\n ratePerSecond: 5,\n debug: false,\n}\n\nexport function normalizeConfig(\n config: RecorderConfig,\n): Required<\n Omit<RecorderConfig, \"cookies\" | \"cookiesPath\" | \"proxy\" | \"normalizeCodec\" | \"normalizeBitrate\">\n> &\n Pick<\n RecorderConfig,\n \"cookies\" | \"cookiesPath\" | \"proxy\" | \"normalizeCodec\" | \"normalizeBitrate\"\n > {\n return {\n user: config.user,\n outputDir: config.outputDir ?? DEFAULTS.outputDir,\n interval: config.interval ?? DEFAULTS.interval,\n duration: config.duration ?? DEFAULTS.duration,\n logLevel: config.logLevel ?? DEFAULTS.logLevel,\n logConsole: config.logConsole ?? DEFAULTS.logConsole,\n proxy: config.proxy,\n cookies: config.cookies,\n cookiesPath: config.cookiesPath,\n segmentMinutes: config.segmentMinutes ?? DEFAULTS.segmentMinutes,\n normalizeAudio: config.normalizeAudio ?? DEFAULTS.normalizeAudio,\n normalizeLoudness: config.normalizeLoudness ?? DEFAULTS.normalizeLoudness,\n normalizeCodec: config.normalizeCodec,\n normalizeBitrate: config.normalizeBitrate,\n ratePerSecond: config.ratePerSecond ?? DEFAULTS.ratePerSecond,\n debug: config.debug ?? DEFAULTS.debug,\n }\n}\n\nexport function validateConfig(config: RecorderConfig): void {\n if (!config.user || config.user.trim().length === 0) {\n throw new TikTokError(\"config-error\", \"--user is required\")\n }\n if (config.interval !== undefined && config.interval < 1) {\n throw new TikTokError(\"config-error\", \"--interval must be >= 1 minute\")\n }\n if (config.duration !== undefined && config.duration < 0) {\n throw new TikTokError(\"config-error\", \"--duration must be >= 0 seconds\")\n }\n}\n"],"mappings":";AAgHA,IAAa,cAAb,cAAiC,MAAM;CAEnB;CAES;CAH3B,YACE,MACA,SACA,OACA;EACA,MAAM,OAAO;EAJG,KAAA,OAAA;EAES,KAAA,QAAA;EAGzB,KAAK,OAAO;CACd;AACF;AAEA,MAAM,WAAW;CACf,WAAW;CACX,UAAU;CACV,UAAU;CACV,UAAU;CACV,YAAY;CACZ,gBAAgB;CAChB,gBAAgB;CAChB,mBAAmB;CACnB,eAAe;CACf,OAAO;AACT;AAEA,SAAgB,gBACd,QAOE;CACF,OAAO;EACL,MAAM,OAAO;EACb,WAAW,OAAO,aAAa,SAAS;EACxC,UAAU,OAAO,YAAY,SAAS;EACtC,UAAU,OAAO,YAAY,SAAS;EACtC,UAAU,OAAO,YAAY,SAAS;EACtC,YAAY,OAAO,cAAc,SAAS;EAC1C,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,aAAa,OAAO;EACpB,gBAAgB,OAAO,kBAAkB,SAAS;EAClD,gBAAgB,OAAO,kBAAkB,SAAS;EAClD,mBAAmB,OAAO,qBAAqB,SAAS;EACxD,gBAAgB,OAAO;EACvB,kBAAkB,OAAO;EACzB,eAAe,OAAO,iBAAiB,SAAS;EAChD,OAAO,OAAO,SAAS,SAAS;CAClC;AACF"}
|
package/dist/package.mjs
CHANGED