movie-agent 1.0.0 → 1.1.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.
Files changed (48) hide show
  1. package/README.md +319 -39
  2. package/bin/movie-agent +33 -8
  3. package/dist/agent.d.ts +31 -4
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +109 -16
  6. package/dist/agent.js.map +1 -1
  7. package/dist/cache.d.ts +40 -5
  8. package/dist/cache.d.ts.map +1 -1
  9. package/dist/cache.js +95 -11
  10. package/dist/cache.js.map +1 -1
  11. package/dist/factory.d.ts.map +1 -1
  12. package/dist/factory.js +23 -1
  13. package/dist/factory.js.map +1 -1
  14. package/dist/format.d.ts +14 -1
  15. package/dist/format.d.ts.map +1 -1
  16. package/dist/format.js +22 -1
  17. package/dist/format.js.map +1 -1
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +9 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/llm.d.ts +33 -0
  23. package/dist/llm.d.ts.map +1 -0
  24. package/dist/llm.js +221 -0
  25. package/dist/llm.js.map +1 -0
  26. package/dist/providers.d.ts +9 -1
  27. package/dist/providers.d.ts.map +1 -1
  28. package/dist/providers.js +27 -0
  29. package/dist/providers.js.map +1 -1
  30. package/dist/rateLimiter.d.ts +59 -0
  31. package/dist/rateLimiter.d.ts.map +1 -0
  32. package/dist/rateLimiter.js +99 -0
  33. package/dist/rateLimiter.js.map +1 -0
  34. package/dist/sanitize.d.ts +24 -0
  35. package/dist/sanitize.d.ts.map +1 -0
  36. package/dist/sanitize.js +137 -0
  37. package/dist/sanitize.js.map +1 -0
  38. package/dist/tmdbApi.d.ts +37 -1
  39. package/dist/tmdbApi.d.ts.map +1 -1
  40. package/dist/tmdbApi.js +70 -22
  41. package/dist/tmdbApi.js.map +1 -1
  42. package/dist/types.d.ts +2 -0
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/validate.d.ts +5 -0
  45. package/dist/validate.d.ts.map +1 -1
  46. package/dist/validate.js +38 -1
  47. package/dist/validate.js.map +1 -1
  48. package/package.json +9 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AA4BA;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG,CA+BpD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA4ClD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CA6BzD"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ // Sanitization utilities for LLM prompt injection prevention
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.sanitizeForLLMPrompt = sanitizeForLLMPrompt;
5
+ exports.sanitizeString = sanitizeString;
6
+ exports.detectPromptInjection = detectPromptInjection;
7
+ /**
8
+ * Common prompt injection patterns to detect and mitigate
9
+ * Using consolidated patterns for better performance and maintainability
10
+ */
11
+ const PROMPT_INJECTION_PATTERNS = [
12
+ // Action-based injections: "ignore/disregard/forget/override [all] [previous/the] instructions/prompts/commands"
13
+ /(?:ignore|disregard|forget|override)\s+(?:all\s+)?(?:previous|the)\s+(?:instructions?|prompts?|commands?)/gi,
14
+ /(?:ignore|disregard|forget|override)\s+(?:previous|all|the)\s+(?:instructions?|prompts?|commands?)/gi,
15
+ // New instruction attempts
16
+ /new\s+(?:instructions?|prompts?|commands?)[\s:]/gi,
17
+ // Role-based injections
18
+ /(?:system|assistant|user)\s*:/gi,
19
+ // Model-specific control tokens
20
+ /\[INST\]|\[\/INST\]/gi,
21
+ /<\|im_start\|>|<\|im_end\|>/gi,
22
+ // Code blocks (limited to reasonable size to prevent ReDoS)
23
+ /```[^`]{0,1000}```/g,
24
+ // Role injection in JSON format
25
+ /\{[^}]{0,500}"role"\s*:\s*"(?:system|assistant)"[^}]{0,500}\}/gi,
26
+ ];
27
+ /**
28
+ * Maximum lengths for different input types (defense in depth with existing validation)
29
+ */
30
+ const MAX_SANITIZED_LENGTH = 500;
31
+ /**
32
+ * Sanitizes user input to prevent prompt injection attacks
33
+ * This is specifically for content that will be passed to LLM prompts
34
+ *
35
+ * @param input - Raw user input object
36
+ * @returns Sanitized version safe for LLM prompts
37
+ */
38
+ function sanitizeForLLMPrompt(input) {
39
+ if (input === null || input === undefined) {
40
+ return input;
41
+ }
42
+ // Handle primitive types
43
+ if (typeof input === 'string') {
44
+ return sanitizeString(input);
45
+ }
46
+ if (typeof input === 'number' || typeof input === 'boolean') {
47
+ return input;
48
+ }
49
+ // Handle arrays
50
+ if (Array.isArray(input)) {
51
+ return input.map(item => sanitizeForLLMPrompt(item));
52
+ }
53
+ // Handle objects recursively
54
+ if (typeof input === 'object') {
55
+ const sanitized = {};
56
+ for (const [key, value] of Object.entries(input)) {
57
+ // Sanitize both key and value
58
+ const sanitizedKey = sanitizeString(String(key));
59
+ sanitized[sanitizedKey] = sanitizeForLLMPrompt(value);
60
+ }
61
+ return sanitized;
62
+ }
63
+ return input;
64
+ }
65
+ /**
66
+ * Sanitizes a string to remove potential prompt injection attacks
67
+ *
68
+ * @param str - Input string to sanitize
69
+ * @returns Sanitized string
70
+ */
71
+ function sanitizeString(str) {
72
+ if (!str || typeof str !== 'string') {
73
+ return '';
74
+ }
75
+ let sanitized = str;
76
+ // Truncate to maximum length early to prevent expensive operations on large strings
77
+ if (sanitized.length > MAX_SANITIZED_LENGTH) {
78
+ sanitized = sanitized.substring(0, MAX_SANITIZED_LENGTH);
79
+ }
80
+ // Remove common prompt injection patterns - replace with safe placeholder
81
+ // Use a marker that won't be affected by later cleanup
82
+ const FILTERED_MARKER = '___FILTERED___';
83
+ for (const pattern of PROMPT_INJECTION_PATTERNS) {
84
+ // Reset regex state to ensure consistent behavior with global flag
85
+ pattern.lastIndex = 0;
86
+ sanitized = sanitized.replace(pattern, FILTERED_MARKER);
87
+ }
88
+ // Remove control characters except common whitespace (space, tab, newline)
89
+ // eslint-disable-next-line no-control-regex
90
+ sanitized = sanitized.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
91
+ // Limit consecutive special characters (more than 3 in a row) - more efficient than nested quantifiers
92
+ // Only process if the string contains special characters
93
+ if (/[^\w\s]/.test(sanitized)) {
94
+ sanitized = sanitized.replace(/([^\w\s])\1{3,}/g, '$1$1$1');
95
+ }
96
+ // Remove any remaining potential instruction delimiters (but preserve our marker)
97
+ sanitized = sanitized.replace(/[<>{}[\]]/g, ' ');
98
+ // Clean up multiple spaces created by replacements
99
+ sanitized = sanitized.replace(/\s+/g, ' ');
100
+ // Replace marker with user-friendly text
101
+ sanitized = sanitized.replace(new RegExp(FILTERED_MARKER, 'g'), '[filtered]');
102
+ // Trim whitespace
103
+ sanitized = sanitized.trim();
104
+ return sanitized;
105
+ }
106
+ /**
107
+ * Detects if input contains potential prompt injection attempts
108
+ * This is for logging/monitoring purposes
109
+ *
110
+ * @param input - Input to check
111
+ * @returns True if potential injection detected
112
+ */
113
+ function detectPromptInjection(input) {
114
+ if (!input) {
115
+ return false;
116
+ }
117
+ const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
118
+ // Early termination for very large inputs to prevent performance issues
119
+ const CHECK_LENGTH_LIMIT = 10000;
120
+ const truncatedInput = inputStr.length > CHECK_LENGTH_LIMIT
121
+ ? inputStr.substring(0, CHECK_LENGTH_LIMIT)
122
+ : inputStr;
123
+ // Reuse sanitization patterns for consistency
124
+ for (const pattern of PROMPT_INJECTION_PATTERNS) {
125
+ // Reset regex state for reuse
126
+ pattern.lastIndex = 0;
127
+ if (pattern.test(truncatedInput)) {
128
+ return true;
129
+ }
130
+ }
131
+ // Additional checks for suspicious character sequences
132
+ if (/[<>{}[\]]{3,}/.test(truncatedInput)) {
133
+ return true;
134
+ }
135
+ return false;
136
+ }
137
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"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"}
package/dist/tmdbApi.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { RateLimiterConfig } from './rateLimiter';
1
2
  export interface MovieSummary {
2
3
  id: number;
3
4
  title: string;
@@ -6,6 +7,8 @@ export interface MovieSummary {
6
7
  genre_ids?: number[];
7
8
  vote_average?: number;
8
9
  popularity?: number;
10
+ /** Path to poster image (e.g., "/abc123.jpg") */
11
+ poster_path?: string | null;
9
12
  }
10
13
  export interface DiscoverMoviesParams {
11
14
  sort_by?: string;
@@ -33,6 +36,12 @@ export interface MovieDetails extends MovieSummary {
33
36
  tagline?: string;
34
37
  homepage?: string;
35
38
  }
39
+ /**
40
+ * Movie details with embedded watch providers (from append_to_response)
41
+ */
42
+ export interface MovieDetailsWithProviders extends MovieDetails {
43
+ 'watch/providers'?: WatchProvidersResponse;
44
+ }
36
45
  export interface SearchMoviesResponse extends DiscoverMoviesResponse {
37
46
  }
38
47
  export interface Genre {
@@ -62,15 +71,42 @@ export interface WatchProvidersResponse {
62
71
  };
63
72
  };
64
73
  }
74
+ /**
75
+ * Configuration options for TmdbApiClient
76
+ */
77
+ export interface TmdbApiClientConfig {
78
+ baseUrl?: string;
79
+ apiKey?: string;
80
+ region?: string;
81
+ /** Rate limiter configuration for throttling requests */
82
+ rateLimiterConfig?: Partial<RateLimiterConfig>;
83
+ /** Request timeout in milliseconds (default: 10000) */
84
+ timeoutMs?: number;
85
+ }
65
86
  export declare class TmdbApiClient {
66
87
  private readonly baseUrl;
67
88
  private readonly apiKey;
68
89
  private readonly region;
69
- constructor(baseUrl?: string, apiKey?: string, region?: string);
90
+ private readonly rateLimiter;
91
+ private readonly rateLimiterConfig;
92
+ private readonly timeoutMs;
93
+ constructor(baseUrl?: string, apiKey?: string, region?: string, rateLimiterConfig?: Partial<RateLimiterConfig>, timeoutMs?: number);
70
94
  private buildUrl;
95
+ /**
96
+ * Internal fetch method with rate limiting and exponential backoff retry
97
+ * @param url - The URL to fetch
98
+ * @returns Promise resolving to the parsed JSON response
99
+ */
71
100
  private doFetch;
72
101
  discoverMovies(params?: DiscoverMoviesParams): Promise<DiscoverMoviesResponse>;
73
102
  getMovieDetails(movieId: number): Promise<MovieDetails>;
103
+ /**
104
+ * Fetches movie details with watch providers in a single API call
105
+ * Uses append_to_response to reduce API calls
106
+ * @param movieId - TMDb movie ID
107
+ * @returns Movie details with embedded watch providers
108
+ */
109
+ getMovieDetailsWithProviders(movieId: number): Promise<MovieDetailsWithProviders>;
74
110
  searchMovies(query: string, page?: number): Promise<SearchMoviesResponse>;
75
111
  getGenres(): Promise<GenresResponse>;
76
112
  getWatchProviders(movieId: number): Promise<WatchProvidersResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"tmdbApi.d.ts","sourceRoot":"","sources":["../src/tmdbApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tmdbApi.d.ts","sourceRoot":"","sources":["../src/tmdbApi.ts"],"names":[],"mappings":"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"}
package/dist/tmdbApi.js CHANGED
@@ -5,19 +5,33 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TmdbApiClient = void 0;
7
7
  const config_1 = __importDefault(require("./config"));
8
+ const rateLimiter_1 = require("./rateLimiter");
9
+ /**
10
+ * Default timeout for API requests in milliseconds (10 seconds)
11
+ */
12
+ const DEFAULT_TIMEOUT_MS = 10000;
8
13
  class TmdbApiClient {
9
- constructor(baseUrl, apiKey, region) {
14
+ constructor(baseUrl, apiKey, region, rateLimiterConfig, timeoutMs) {
10
15
  this.baseUrl = baseUrl ?? config_1.default.TMDB_BASE_URL;
11
16
  this.apiKey = apiKey ?? config_1.default.TMDB_API_KEY;
12
17
  this.region = region ?? config_1.default.TMDB_REGION;
18
+ this.timeoutMs = timeoutMs ?? DEFAULT_TIMEOUT_MS;
19
+ // Enforce HTTPS-only for security
20
+ if (!this.baseUrl.toLowerCase().startsWith('https://')) {
21
+ throw new Error('Base URL must use HTTPS protocol for secure API communication');
22
+ }
23
+ this.rateLimiterConfig = {
24
+ ...rateLimiter_1.DEFAULT_RATE_LIMITER_CONFIG,
25
+ ...rateLimiterConfig,
26
+ };
27
+ this.rateLimiter = (0, rateLimiter_1.createRateLimiter)(this.rateLimiterConfig.concurrency);
13
28
  }
14
29
  buildUrl(path, params) {
15
30
  const normalizedBase = this.baseUrl.endsWith('/')
16
31
  ? this.baseUrl
17
32
  : this.baseUrl + '/';
18
33
  const url = new URL(path, normalizedBase);
19
- // TMDb v3 supports API key via query string
20
- url.searchParams.set('api_key', this.apiKey);
34
+ // TMDb v3 API key is now passed via Authorization header for security
21
35
  if (params) {
22
36
  for (const [k, v] of Object.entries(params)) {
23
37
  if (v !== undefined && v !== null) {
@@ -27,26 +41,47 @@ class TmdbApiClient {
27
41
  }
28
42
  return url.toString();
29
43
  }
44
+ /**
45
+ * Internal fetch method with rate limiting and exponential backoff retry
46
+ * @param url - The URL to fetch
47
+ * @returns Promise resolving to the parsed JSON response
48
+ */
30
49
  async doFetch(url) {
31
- let resp;
32
- try {
33
- resp = await fetch(url, {
34
- headers: { Accept: 'application/json' },
35
- });
36
- }
37
- catch (err) {
38
- throw new Error(`Network error calling TMDb API: ${err?.message ?? String(err)}`);
39
- }
40
- if (!resp.ok) {
41
- const text = await resp.text().catch(() => '');
42
- throw new Error(`TMDb API error ${resp.status}: ${text || resp.statusText}`);
43
- }
44
- try {
45
- return (await resp.json());
46
- }
47
- catch (err) {
48
- throw new Error(`Invalid JSON from TMDb API: ${err?.message ?? String(err)}`);
49
- }
50
+ return this.rateLimiter(() => (0, rateLimiter_1.withRetry)(async () => {
51
+ let resp;
52
+ const abortController = new AbortController();
53
+ const timeoutId = setTimeout(() => {
54
+ abortController.abort();
55
+ }, this.timeoutMs);
56
+ try {
57
+ resp = await fetch(url, {
58
+ headers: {
59
+ Accept: 'application/json',
60
+ Authorization: `Bearer ${this.apiKey}`,
61
+ },
62
+ signal: abortController.signal,
63
+ });
64
+ clearTimeout(timeoutId);
65
+ }
66
+ catch (err) {
67
+ clearTimeout(timeoutId);
68
+ // Check if the error is due to abort (timeout)
69
+ if (err.name === 'AbortError') {
70
+ throw new Error(`Network error calling TMDb API: Request timeout after ${this.timeoutMs}ms`);
71
+ }
72
+ throw new Error(`Network error calling TMDb API: ${err?.message ?? String(err)}`);
73
+ }
74
+ if (!resp.ok) {
75
+ const text = await resp.text().catch(() => '');
76
+ throw new Error(`TMDb API error ${resp.status}: ${text || resp.statusText}`);
77
+ }
78
+ try {
79
+ return (await resp.json());
80
+ }
81
+ catch (err) {
82
+ throw new Error(`Invalid JSON from TMDb API: ${err?.message ?? String(err)}`);
83
+ }
84
+ }, this.rateLimiterConfig));
50
85
  }
51
86
  async discoverMovies(params = {}) {
52
87
  const url = this.buildUrl('discover/movie', {
@@ -66,6 +101,19 @@ class TmdbApiClient {
66
101
  const url = this.buildUrl(`movie/${movieId}`, { region: this.region });
67
102
  return this.doFetch(url);
68
103
  }
104
+ /**
105
+ * Fetches movie details with watch providers in a single API call
106
+ * Uses append_to_response to reduce API calls
107
+ * @param movieId - TMDb movie ID
108
+ * @returns Movie details with embedded watch providers
109
+ */
110
+ async getMovieDetailsWithProviders(movieId) {
111
+ const url = this.buildUrl(`movie/${movieId}`, {
112
+ region: this.region,
113
+ append_to_response: 'watch/providers',
114
+ });
115
+ return this.doFetch(url);
116
+ }
69
117
  async searchMovies(query, page) {
70
118
  const url = this.buildUrl('search/movie', {
71
119
  query,
@@ -1 +1 @@
1
- {"version":3,"file":"tmdbApi.js","sourceRoot":"","sources":["../src/tmdbApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tmdbApi.js","sourceRoot":"","sources":["../src/tmdbApi.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -60,6 +60,8 @@ export interface MovieRecommendation {
60
60
  streamingPlatforms: StreamingPlatform[];
61
61
  /** Explanation of why this movie was recommended */
62
62
  matchReason: string;
63
+ /** URL to movie poster image (w500 size) */
64
+ posterUrl: string | null;
63
65
  }
64
66
  /**
65
67
  * Metadata about the recommendation request
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,qCAAqC;IACrC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oCAAoC;IACpC,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,gBAAgB,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,eAAe,EAAE,SAAS,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,eAAe,EAAE,mBAAmB,EAAE,CAAC;IACvC,uBAAuB;IACvB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,KAAK,EAAE,IAAI,CAAC;IACZ,0BAA0B;IAC1B,SAAS,EACL,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,GACrB,kBAAkB,GAClB,YAAY,GACZ,eAAe,CAAC;IACpB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,qCAAqC;IACrC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oCAAoC;IACpC,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,gBAAgB,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,eAAe,EAAE,SAAS,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,eAAe,EAAE,mBAAmB,EAAE,CAAC;IACvC,uBAAuB;IACvB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,KAAK,EAAE,IAAI,CAAC;IACZ,0BAA0B;IAC1B,SAAS,EACL,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,GACrB,kBAAkB,GAClB,YAAY,GACZ,eAAe,CAAC;IACpB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -1,3 +1,6 @@
1
+ export declare const MAX_MOOD_LENGTH = 100;
2
+ export declare const MAX_GENRE_LENGTH = 50;
3
+ export declare const MAX_ARRAY_LENGTH = 10;
1
4
  export declare const ALLOWED_PLATFORMS: string[];
2
5
  export declare function isValidPlatform(name: string): boolean;
3
6
  export declare function validatePlatforms(platforms: string[]): void;
@@ -10,4 +13,6 @@ export declare function validateYearRange({ from, to, }: {
10
13
  from: number;
11
14
  to: number;
12
15
  }): void;
16
+ export declare function validateMood(mood: string): void;
17
+ export declare function validateGenre(genre: string | string[]): void;
13
18
  //# sourceMappingURL=validate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,UAU7B,CAAC;AAEF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAK3D;AAED,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,GAAG,GACJ,EAAE;IACD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAMP;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,EAAE,GACH,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,IAAI,CAMP"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,eAAO,MAAM,iBAAiB,UAU7B,CAAC;AAEF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAU3D;AAED,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,GAAG,GACJ,EAAE;IACD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAMP;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,EAAE,GACH,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,IAAI,CAMP;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAY/C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAsB5D"}
package/dist/validate.js CHANGED
@@ -1,12 +1,18 @@
1
1
  "use strict";
2
2
  // Input validation utilities for movie-agent
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.ALLOWED_PLATFORMS = void 0;
4
+ exports.ALLOWED_PLATFORMS = exports.MAX_ARRAY_LENGTH = exports.MAX_GENRE_LENGTH = exports.MAX_MOOD_LENGTH = void 0;
5
5
  exports.isValidPlatform = isValidPlatform;
6
6
  exports.validatePlatforms = validatePlatforms;
7
7
  exports.validateRuntime = validateRuntime;
8
8
  exports.validateYear = validateYear;
9
9
  exports.validateYearRange = validateYearRange;
10
+ exports.validateMood = validateMood;
11
+ exports.validateGenre = validateGenre;
12
+ // Maximum length constants to prevent DoS attacks
13
+ exports.MAX_MOOD_LENGTH = 100;
14
+ exports.MAX_GENRE_LENGTH = 50;
15
+ exports.MAX_ARRAY_LENGTH = 10;
10
16
  exports.ALLOWED_PLATFORMS = [
11
17
  'Netflix',
12
18
  'Prime Video',
@@ -22,6 +28,9 @@ function isValidPlatform(name) {
22
28
  return exports.ALLOWED_PLATFORMS.includes(name);
23
29
  }
24
30
  function validatePlatforms(platforms) {
31
+ if (platforms.length > exports.MAX_ARRAY_LENGTH) {
32
+ throw new Error(`Too many platforms: maximum ${exports.MAX_ARRAY_LENGTH} allowed, got ${platforms.length}`);
33
+ }
25
34
  const invalid = platforms.filter(p => !isValidPlatform(p));
26
35
  if (invalid.length > 0) {
27
36
  throw new Error(`Invalid platform(s): ${invalid.join(', ')}`);
@@ -44,4 +53,32 @@ function validateYearRange({ from, to, }) {
44
53
  throw new Error(`Year range invalid: from (${from}) > to (${to})`);
45
54
  }
46
55
  }
56
+ function validateMood(mood) {
57
+ if (typeof mood !== 'string') {
58
+ throw new Error('Mood must be a string');
59
+ }
60
+ if (mood.trim().length === 0) {
61
+ throw new Error('Mood cannot be empty');
62
+ }
63
+ if (mood.length > exports.MAX_MOOD_LENGTH) {
64
+ throw new Error(`Mood must be ${exports.MAX_MOOD_LENGTH} characters or less, got ${mood.length}`);
65
+ }
66
+ }
67
+ function validateGenre(genre) {
68
+ const genres = Array.isArray(genre) ? genre : [genre];
69
+ if (genres.length > exports.MAX_ARRAY_LENGTH) {
70
+ throw new Error(`Too many genres: maximum ${exports.MAX_ARRAY_LENGTH} allowed, got ${genres.length}`);
71
+ }
72
+ for (const g of genres) {
73
+ if (typeof g !== 'string') {
74
+ throw new Error('Genre must be a string');
75
+ }
76
+ if (g.trim().length === 0) {
77
+ throw new Error('Genre cannot be empty');
78
+ }
79
+ if (g.length > exports.MAX_GENRE_LENGTH) {
80
+ throw new Error(`Genre must be ${exports.MAX_GENRE_LENGTH} characters or less, got ${g.length}`);
81
+ }
82
+ }
83
+ }
47
84
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":";AAAA,6CAA6C;;;AAc7C,0CAEC;AAED,8CAKC;AAED,0CAYC;AAED,oCAIC;AAED,8CAYC;AAvDY,QAAA,iBAAiB,GAAG;IAC/B,SAAS;IACT,aAAa;IACb,OAAO;IACP,SAAS;IACT,WAAW;IACX,YAAY;IACZ,MAAM;IACN,MAAM;IACN,UAAU;CACX,CAAC;AAEF,SAAgB,eAAe,CAAC,IAAY;IAC1C,OAAO,yBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,SAAgB,iBAAiB,CAAC,SAAmB;IACnD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,SAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,GAAG,GAIJ;IACC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CACb,gBAAgB,GAAG,yCAAyC,GAAG,GAAG,CACnE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,SAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,EAAE,GAIH;IACC,YAAY,CAAC,IAAI,CAAC,CAAC;IACnB,YAAY,CAAC,EAAE,CAAC,CAAC;IACjB,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,WAAW,EAAE,GAAG,CAAC,CAAC;IACrE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "movie-agent",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Movie Agent - A TypeScript-based movie recommendation agent",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,8 +30,9 @@
30
30
  "format": "prettier --write \"src/**/*.ts\"",
31
31
  "format:check": "prettier --check \"src/**/*.ts\"",
32
32
  "type-check": "tsc --noEmit",
33
+ "audit": "npm audit --audit-level=moderate",
33
34
  "validate": "npm run type-check && npm run lint && npm run test:coverage",
34
- "validate:ci": "npm run type-check && npm run lint && npm run format:check && npm run test:ci && npm run build",
35
+ "validate:ci": "npm run type-check && npm run audit && npm run lint && npm run format:check && npm run test:ci && npm run build",
35
36
  "clean": "rm -rf dist coverage",
36
37
  "prebuild": "npm run clean",
37
38
  "prepublishOnly": "npm run validate:ci",
@@ -55,6 +56,7 @@
55
56
  "devDependencies": {
56
57
  "@types/jest": "^29.5.11",
57
58
  "@types/node": "^20.10.6",
59
+ "@types/p-limit": "^2.1.0",
58
60
  "@typescript-eslint/eslint-plugin": "^6.17.0",
59
61
  "@typescript-eslint/parser": "^6.17.0",
60
62
  "dotenv-cli": "^7.1.0",
@@ -67,6 +69,10 @@
67
69
  "typescript": "^5.3.3"
68
70
  },
69
71
  "dependencies": {
70
- "dotenv": "^16.4.5"
72
+ "@langchain/core": "^1.1.7",
73
+ "@langchain/google-genai": "^2.1.2",
74
+ "@langchain/openai": "^1.2.0",
75
+ "dotenv": "^16.4.5",
76
+ "p-limit": "^3.1.0"
71
77
  }
72
78
  }