From 0b2c475b6c671f7034415e1f4a78ef27ffda5339 Mon Sep 17 00:00:00 2001 From: 4gray Date: Sun, 26 Jul 2026 04:05:03 +0200 Subject: [PATCH] feat(mock-data): share poster catalog across mocks --- apps/stalker-mock-server/README.md | 8 +- apps/stalker-mock-server/project.json | 4 +- .../src/app/data-generator.ts | 103 +++++++-- .../app/handlers/get-ordered-list.handler.ts | 8 +- apps/stalker-mock-server/src/app/scenarios.ts | 14 ++ apps/stalker-mock-server/src/main.ts | 15 ++ apps/xtream-mock-server/README.md | 9 +- apps/xtream-mock-server/project.json | 4 +- .../src/app/generators/marketing.generator.ts | 212 +++--------------- docs/architecture/stalker-mock-server.md | 14 ++ docs/architecture/xtream-mock-server.md | 9 +- package.json | 8 +- tools/release/capture-v020-screenshots.ts | 10 +- 13 files changed, 201 insertions(+), 217 deletions(-) diff --git a/apps/stalker-mock-server/README.md b/apps/stalker-mock-server/README.md index 8a299a823..42abe86d2 100644 --- a/apps/stalker-mock-server/README.md +++ b/apps/stalker-mock-server/README.md @@ -39,6 +39,7 @@ Then in IPTVnator, add a new Stalker portal: | `00:1A:79:00:00:04` | **is-series** | 60% of VOD items have `is_series=1` — tests the Ministra lazy-season flow | | `00:1A:79:00:00:05` | **embedded-series** | 50% of VOD items have embedded `series[]` arrays — tests the embedded series flow | | `00:1A:79:00:00:06` | **legacy-pagination** | No `get_all_channels` support — tests the paginated `get_ordered_list` crawl fallback for the full ITV channel list | +| `00:1A:79:00:00:07` | **marketing-demo** | 35 original poster movies with the newest 20 first — safe for screenshots and marketing | | `` | **auto** | MAC bytes used as seed → deterministic unique dataset | ## Configuration @@ -74,7 +75,12 @@ All endpoints are served at `GET /portal.php?action=&...` matching the r ## Cover Images -Cover images and logos use [Picsum Photos](https://picsum.photos) (e.g. `https://picsum.photos/seed/{id}/300/200`). These are real images served from a CDN — no local setup required, but an internet connection is needed for images to display. +Generated scenarios use [Picsum Photos](https://picsum.photos) for cover images +and logos, so they need an internet connection to display artwork. The +`marketing-demo` scenario instead uses the committed, screenshot-safe poster +catalog shared with the Xtream mock. Stalker serves those PNGs itself from +`/assets/marketing/poster/.png`, so screenshots remain deterministic and +offline once the repository is checked out. ## Stream URLs diff --git a/apps/stalker-mock-server/project.json b/apps/stalker-mock-server/project.json index d826d0656..137477115 100644 --- a/apps/stalker-mock-server/project.json +++ b/apps/stalker-mock-server/project.json @@ -9,7 +9,7 @@ "continuous": true, "executor": "nx:run-commands", "options": { - "command": "pnpm tsx apps/stalker-mock-server/src/main.ts", + "command": "pnpm tsx --tsconfig tsconfig.base.json apps/stalker-mock-server/src/main.ts", "cwd": "{workspaceRoot}", "color": true, "env": { @@ -22,7 +22,7 @@ "continuous": true, "executor": "nx:run-commands", "options": { - "command": "pnpm tsx watch apps/stalker-mock-server/src/main.ts", + "command": "pnpm tsx watch --tsconfig tsconfig.base.json apps/stalker-mock-server/src/main.ts", "cwd": "{workspaceRoot}", "color": true, "env": { diff --git a/apps/stalker-mock-server/src/app/data-generator.ts b/apps/stalker-mock-server/src/app/data-generator.ts index cd46f306b..72efdd1b4 100644 --- a/apps/stalker-mock-server/src/app/data-generator.ts +++ b/apps/stalker-mock-server/src/app/data-generator.ts @@ -1,4 +1,8 @@ import { faker } from '@faker-js/faker'; +import { + MarketingMovieCategoryKey, + POSTER_SHOWCASE_MOVIES, +} from '@iptvnator/shared/marketing-fixtures'; import { ScenarioConfig } from './scenarios.js'; // --------------------------------------------------------------------------- @@ -115,6 +119,8 @@ export interface GeneratedPortalData { channels: Map; // categoryId -> channels radio: Map; // categoryId -> radio stations vod: Map; // categoryId -> items + /** Preserves the provider-neutral fixture order for the "*" VOD listing. */ + vodOrder?: RawVodItem[]; series: Map; // categoryId -> items seasons: Map; // seriesItemId -> seasons epg: Map; // channelId -> programs @@ -146,6 +152,58 @@ function logoUrl(seed: string): string { return `https://picsum.photos/seed/logo-${seed}/100/100`; } +const STALKER_MARKETING_VOD_CATEGORIES: RawCategory[] = [ + { id: '2901', title: 'Action & Mystery', alias: 'action_mystery' }, + { id: '2902', title: 'Cosmic & Future Worlds', alias: 'future_worlds' }, + { id: '2903', title: 'Family & Comedy', alias: 'family_comedy' }, + { + id: '2904', + title: 'Documentary & Drama', + alias: 'documentary_drama', + }, +]; + +const STALKER_MARKETING_VOD_CATEGORY_IDS: Record< + MarketingMovieCategoryKey, + string +> = { + 'action-mystery': '2901', + 'future-fantasy': '2902', + 'family-comedy': '2903', + 'drama-documentary': '2904', +}; + +function generateMarketingVodItems(): RawVodItem[] { + const assetBaseUrl = `http://localhost:${process.env['PORT'] ?? '3210'}/assets/marketing/poster`; + + return POSTER_SHOWCASE_MOVIES.map((movie, index) => { + const id = String(29_000 + index); + const posterUrl = `${assetBaseUrl}/${movie.slug}.png`; + const rating = movie.rating.toFixed(1); + + return { + id, + name: movie.name, + o_name: movie.name, + title: movie.name, + cmd: `ffrt4://vod/${id}/index.m3u8`, + screenshot_uri: posterUrl, + cover: posterUrl, + description: `${movie.tagline} ${movie.description}`, + actors: movie.actors, + director: movie.director, + year: String(movie.year), + genre: movie.genre, + genres_str: movie.genre, + rating_imdb: rating, + rating_kinopoisk: rating, + category_id: STALKER_MARKETING_VOD_CATEGORY_IDS[movie.categoryKey], + is_series: 0, + has_files: 1, + }; + }); +} + // --------------------------------------------------------------------------- // Generator // --------------------------------------------------------------------------- @@ -205,20 +263,39 @@ export function generatePortalData(config: ScenarioConfig): GeneratedPortalData } // ------ VOD categories + items ------ - data.vodCategories = generateCategories('vod', config.categoryCount.vod); - let vodIndex = 0; - for (const cat of data.vodCategories) { - const items = generateVodItems( - cat.id, - config.itemsPerCategory, - vodIndex, - config.isSeriesFraction, - config.embeddedSeriesFraction, - config.seasonsPerSeries, - config.episodesPerSeason + if (config.marketingFixture) { + data.vodCategories = STALKER_MARKETING_VOD_CATEGORIES.map( + (category) => ({ ...category }) ); - data.vod.set(cat.id, items); - vodIndex += config.itemsPerCategory; + const marketingVodItems = generateMarketingVodItems(); + data.vodOrder = marketingVodItems; + for (const category of data.vodCategories) { + data.vod.set( + category.id, + marketingVodItems.filter( + (item) => item.category_id === category.id + ) + ); + } + } else { + data.vodCategories = generateCategories( + 'vod', + config.categoryCount.vod + ); + let vodIndex = 0; + for (const cat of data.vodCategories) { + const items = generateVodItems( + cat.id, + config.itemsPerCategory, + vodIndex, + config.isSeriesFraction, + config.embeddedSeriesFraction, + config.seasonsPerSeries, + config.episodesPerSeason + ); + data.vod.set(cat.id, items); + vodIndex += config.itemsPerCategory; + } } // ------ Series categories + items ------ diff --git a/apps/stalker-mock-server/src/app/handlers/get-ordered-list.handler.ts b/apps/stalker-mock-server/src/app/handlers/get-ordered-list.handler.ts index 0a60127bd..ea6c7bb26 100644 --- a/apps/stalker-mock-server/src/app/handlers/get-ordered-list.handler.ts +++ b/apps/stalker-mock-server/src/app/handlers/get-ordered-list.handler.ts @@ -68,8 +68,12 @@ export function handleGetOrderedList(req: Request, res: Response): void { } else { // vod (default) if (categoryId === '*') { - for (const items of data.vod.values()) { - allItems.push(...items); + if (data.vodOrder) { + allItems.push(...data.vodOrder); + } else { + for (const items of data.vod.values()) { + allItems.push(...items); + } } } else { allItems = data.vod.get(categoryId) ?? []; diff --git a/apps/stalker-mock-server/src/app/scenarios.ts b/apps/stalker-mock-server/src/app/scenarios.ts index 74c271dd6..ec1c4b6b8 100644 --- a/apps/stalker-mock-server/src/app/scenarios.ts +++ b/apps/stalker-mock-server/src/app/scenarios.ts @@ -21,6 +21,8 @@ export interface ScenarioConfig { * `get_ordered_list` crawling (legacy portals). */ supportsGetAllChannels?: boolean; + /** Replace generated VOD with the shared screenshot-safe poster catalog. */ + marketingFixture?: true; } /** @@ -107,6 +109,18 @@ export const SCENARIOS: Record = { embeddedSeriesFraction: 0, supportsGetAllChannels: false, }, + '00:1a:79:00:00:07': { + name: 'marketing-demo', + description: 'Screenshot-safe portal with 35 original poster movies', + seed: 7007, + categoryCount: { itv: 4, radio: 4, vod: 4, series: 4 }, + itemsPerCategory: 6, + seasonsPerSeries: 2, + episodesPerSeason: 5, + isSeriesFraction: 0, + embeddedSeriesFraction: 0, + marketingFixture: true, + }, }; /** diff --git a/apps/stalker-mock-server/src/main.ts b/apps/stalker-mock-server/src/main.ts index 2e8eed602..6d84d369f 100644 --- a/apps/stalker-mock-server/src/main.ts +++ b/apps/stalker-mock-server/src/main.ts @@ -1,4 +1,5 @@ import http from 'http'; +import { join } from 'node:path'; import express, { Request, Response } from 'express'; import cors from 'cors'; import portalRouter from './app/routes/portal.route.js'; @@ -8,6 +9,10 @@ import { SCENARIOS } from './app/scenarios.js'; const PORT = parseInt(process.env['PORT'] ?? '3210', 10); const app = express(); +const MARKETING_POSTER_DIRECTORY = join( + process.cwd(), + 'apps/xtream-mock-server/public/marketing/poster' +); // --------------------------------------------------------------------------- // Middleware @@ -35,6 +40,16 @@ app.use((req, _res, next) => { // Routes // --------------------------------------------------------------------------- +// Serve the shared screenshot-safe poster catalog directly from this process. +app.use( + '/assets/marketing/poster', + express.static(MARKETING_POSTER_DIRECTORY, { + fallthrough: false, + immutable: true, + maxAge: '1y', + }) +); + // Stalker portal.php endpoint (direct portal protocol, Electron mode) app.use('/portal.php', portalRouter); diff --git a/apps/xtream-mock-server/README.md b/apps/xtream-mock-server/README.md index 69e700d9e..d0d7096b1 100644 --- a/apps/xtream-mock-server/README.md +++ b/apps/xtream-mock-server/README.md @@ -153,11 +153,12 @@ application code. ## Release Demo Artwork -The `marketing:marketing` fixture uses 45 original fictional titles for release +The `marketing:marketing` fixture uses 65 original fictional titles for release screenshots. Its core 30-title artwork pack includes matched posters and -backdrops; 15 additional movie-poster showcase titles use approved local poster -PNGs and the deterministic SVG fallback for missing backdrops. Assets are served -from: +backdrops; 35 additional movie-poster showcase titles use approved local poster +PNGs and the deterministic SVG fallback for missing backdrops. The newest 20 +showcase movies are ordered first so they appear immediately in screenshot +catalog grids. Assets are served from: ```text apps/xtream-mock-server/public/marketing/{poster,backdrop}/ diff --git a/apps/xtream-mock-server/project.json b/apps/xtream-mock-server/project.json index 7a8056516..f43ed7394 100644 --- a/apps/xtream-mock-server/project.json +++ b/apps/xtream-mock-server/project.json @@ -9,7 +9,7 @@ "continuous": true, "executor": "nx:run-commands", "options": { - "command": "pnpm tsx apps/xtream-mock-server/src/main.ts", + "command": "pnpm tsx --tsconfig tsconfig.base.json apps/xtream-mock-server/src/main.ts", "cwd": "{workspaceRoot}", "color": true, "env": { @@ -22,7 +22,7 @@ "continuous": true, "executor": "nx:run-commands", "options": { - "command": "pnpm tsx watch apps/xtream-mock-server/src/main.ts", + "command": "pnpm tsx watch --tsconfig tsconfig.base.json apps/xtream-mock-server/src/main.ts", "cwd": "{workspaceRoot}", "color": true, "env": { diff --git a/apps/xtream-mock-server/src/app/generators/marketing.generator.ts b/apps/xtream-mock-server/src/app/generators/marketing.generator.ts index 2d0392cf6..855983dc1 100644 --- a/apps/xtream-mock-server/src/app/generators/marketing.generator.ts +++ b/apps/xtream-mock-server/src/app/generators/marketing.generator.ts @@ -1,3 +1,8 @@ +import { + MarketingMovieCategoryKey, + MarketingMovieFixture, + POSTER_SHOWCASE_MOVIES as SHARED_POSTER_SHOWCASE_MOVIES, +} from '@iptvnator/shared/marketing-fixtures'; import { RawCategory } from './categories.generator.js'; import { buildEpgListing, @@ -83,6 +88,27 @@ const VOD_CATEGORIES: RawCategory[] = [ { category_id: '5204', category_name: 'Documentary & Drama', parent_id: 0 }, ]; +const XTREAM_VOD_CATEGORY_IDS: Record = { + 'action-mystery': '5201', + 'future-fantasy': '5202', + 'family-comedy': '5203', + 'drama-documentary': '5204', +}; + +function toMarketingMovie(movie: MarketingMovieFixture): MarketingMovie { + return { + actors: movie.actors, + categoryId: XTREAM_VOD_CATEGORY_IDS[movie.categoryKey], + description: movie.description, + director: movie.director, + genre: movie.genre, + name: movie.name, + rating: movie.rating, + tagline: movie.tagline, + year: movie.year, + }; +} + const SERIES_CATEGORIES: RawCategory[] = [ { category_id: '5301', category_name: 'Urban Drama', parent_id: 0 }, { category_id: '5302', category_name: 'Speculative Series', parent_id: 0 }, @@ -352,192 +378,12 @@ const GENERATED_ARTWORK_MOVIES: MarketingMovie[] = [ }, ]; -const POSTER_SHOWCASE_MOVIES: MarketingMovie[] = [ - { - categoryId: '5204', - name: 'Orchard Walls', - description: - 'A quiet prison gardener and a new volunteer rebuild an abandoned orchard while both reconsider the lives waiting beyond its walls.', - director: 'Elena March', - actors: 'Darius Cole, Mina Hart, Ruth Bell, Owen Pike', - genre: 'Human Drama', - rating: 8.4, - tagline: 'Some walls are grown, not built.', - year: 2025, - }, - { - categoryId: '5203', - name: 'Blue Current', - description: - 'A young reef fish and an anxious lantern companion cross a changing ocean current to guide their family home.', - director: 'Talia North', - actors: 'Lumi Vale, Finn Reed, Orla Moss, Kit Arden', - genre: 'Animated Family Adventure', - rating: 8.6, - tagline: 'The smallest light can find the way.', - year: 2026, - }, - { - categoryId: '5201', - name: 'Signal Nine', - description: - 'A transit reporter and a railway investigator trace a repeating emergency signal through a city that insists nothing happened.', - director: 'Mara Venn', - actors: 'Nadia Cross, Elias Rowe, June Mercer, Tomas Vale', - genre: 'Urban Conspiracy Thriller', - rating: 8.1, - tagline: 'The ninth signal was never sent.', - year: 2026, - }, - { - categoryId: '5204', - name: 'Checkout at Noon', - description: - 'An exhausted hotel manager has one morning to settle a cheerful traveler and a formidable guest into the same impossible room.', - director: 'Milo Hart', - actors: 'Adrian Moss, Clara Wynn, Evelyn Shore, Ben Vale', - genre: 'Ensemble Comedy', - rating: 7.7, - tagline: 'Every guest has a different plan.', - year: 2025, - }, - { - categoryId: '5202', - name: 'Vesper Crown', - description: - 'A royal archivist crosses a silent salt kingdom to recover a broken crown before its seven pieces choose a new ruler.', - director: 'Iris March', - actors: 'Selah Quinn, Rowan Pike, Mira Holt, Theo Arden', - genre: 'Fantasy Adventure', - rating: 8.3, - tagline: 'Seven pieces remember the throne.', - year: 2026, - }, - { - categoryId: '5201', - name: 'Last Detour', - description: - 'A veteran mechanic and a bicycle courier take one mountain road too far and discover why every map avoids it.', - director: 'Noah Rook', - actors: 'Tessa Marr, Leo Venn, Omar Pike, Nina Cross', - genre: 'Road Action Thriller', - rating: 7.9, - tagline: 'The long way back is the only way out.', - year: 2025, - }, - { - categoryId: '5204', - name: 'Borrowed Summer', - description: - 'Two former friends meet beside a lakeside bus route and spend one final season deciding which memories still belong to them.', - director: 'Lina Shore', - actors: 'Mara Wynn, Julian Hart, Elise Rowe, Finn Cole', - genre: 'Romantic Drama', - rating: 8.0, - tagline: 'Some seasons are only passing through.', - year: 2024, - }, - { - categoryId: '5201', - name: 'Under the Floor', - description: - 'A tenant renovating an empty family home follows a red thread beneath the floorboards and into a history no room remembers.', - director: 'Oren Vale', - actors: 'Rhea Moss, Daniel Cross, Mina Shore, Asa Bell', - genre: 'Supernatural Horror', - rating: 7.8, - tagline: 'The house kept one thing hidden.', - year: 2025, - }, - { - categoryId: '5202', - name: 'Red Winter', - description: - 'A planetary botanist crosses a frozen red plain with the last living samples after her remote habitat falls silent.', - director: 'Vera Holt', - actors: 'Nora Venn, Kai March, Elias Moss, Ruth Arden', - genre: 'Science Fiction Survival', - rating: 8.5, - tagline: 'Life travels light.', - year: 2026, - }, - { - categoryId: '5203', - name: 'Saturday Champions', - description: - 'Six neighborhood footballers with mismatched kits train for the one match their muddy community field has been waiting for.', - director: 'Tomas Hart', - actors: 'Milo Quinn, Ari Bell, Leni Moss, Kit Rowe', - genre: 'Family Sports Comedy', - rating: 7.9, - tagline: 'The score is not the whole story.', - year: 2025, - }, - { - categoryId: '5204', - name: 'The Silent Verdict', - description: - 'A public defender receives one sealed envelope after an empty courtroom closes and must decide whether justice can survive the truth.', - director: 'June Marr', - actors: 'Amara Voss, Theo Reed, Elias Hart, Cora Wynn', - genre: 'Courtroom Drama', - rating: 8.2, - tagline: 'The final evidence said nothing.', - year: 2026, - }, - { - categoryId: '5201', - name: 'Low Tide Letters', - description: - 'An aging postal worker crosses the tidal flats to deliver a final bundle of letters to a village missing from every new map.', - director: 'Owen Shore', - actors: 'Bram North, Iris Cole, Lena March, Rafi Bell', - genre: 'Coastal Mystery', - rating: 8.1, - tagline: 'The sea returns every address.', - year: 2024, - }, - { - categoryId: '5204', - name: 'Salt & Cedar', - description: - 'Two estranged siblings reopen their family restaurant and discover that the old recipes settle fewer arguments than they start.', - director: 'Cora Vale', - actors: 'Mina Wynn, Adrian Rowe, Ruth Moss, Nico Hart', - genre: 'Culinary Dramedy', - rating: 7.8, - tagline: 'Every table remembers.', - year: 2025, - }, - { - categoryId: '5201', - name: 'Brass Horizon', - description: - 'A desert aircraft engineer races an experimental survey plane ahead of a dust front that has erased every route home.', - director: 'Ren Arden', - actors: 'Talia Cross, Owen Pike, Mara Bell, Jules North', - genre: 'Retro Aviation Adventure', - rating: 8.0, - tagline: 'Build what the horizon cannot stop.', - year: 2023, - }, - { - categoryId: '5203', - name: 'Moonlight Delivery', - description: - 'A young night courier climbs a winding miniature city to deliver three glowing parcels before the moon disappears.', - director: 'Lumi Hart', - actors: 'Kit Vale, Orla Reed, Finn Moss, Ari Shore', - genre: 'Animated Family Adventure', - rating: 8.4, - tagline: 'Every doorstep needs a little light.', - year: 2026, - }, -]; +const POSTER_SHOWCASE_MOVIES: MarketingMovie[] = + SHARED_POSTER_SHOWCASE_MOVIES.map(toMarketingMovie); const MOVIES: MarketingMovie[] = [ - ...GENERATED_ARTWORK_MOVIES, ...POSTER_SHOWCASE_MOVIES, + ...GENERATED_ARTWORK_MOVIES, ]; const SERIES: MarketingSeries[] = [ diff --git a/docs/architecture/stalker-mock-server.md b/docs/architecture/stalker-mock-server.md index a15bb061a..652e6eef6 100644 --- a/docs/architecture/stalker-mock-server.md +++ b/docs/architecture/stalker-mock-server.md @@ -14,6 +14,7 @@ The mock server enables: 1. **Local development** without access to a real Stalker portal 2. **Playwright E2E testing** with predictable, deterministic data 3. **Scenario-based testing** via predefined MAC addresses that map to specific data shapes +4. **Screenshot-safe marketing capture** with committed fictional posters shared with the Xtream mock ## Key Design Decisions @@ -56,6 +57,11 @@ faker.seed(config.seed) // scenario seed; unknown MACs: macToSeed(mac) │ ├── is_series=1 items (fraction, Ministra flow) │ └── embedded series[] items (fraction) │ +├── marketingFixture? → shared curated VOD catalog +│ ├── @iptvnator/shared/marketing-fixtures +│ ├── vod Map +│ └── vodOrder[] preserves screenshot catalog order +│ └── generateCategories('series', N) → seriesCategories[] └── generateSeriesItems() → series Map └── generateSeasons() → seasons Map @@ -219,6 +225,7 @@ interface ScenarioConfig { embeddedSeriesFraction: number; // 0–1: fraction of VOD with embedded series[] supportsGetAllChannels?: boolean; // default true; false mimics legacy portals // without the ITV get_all_channels action + marketingFixture?: true; // replace generated VOD with shared posters } ``` @@ -230,6 +237,13 @@ supporting scenarios, `get_all_channels` (`get-all-channels.handler.ts`, `{ js: { data, total_items } }` response, excluding channels from censored (adult) genres. +The `marketing-demo` scenario (`00:1A:79:00:00:07`) replaces faker-generated +VOD with the 35-movie provider-neutral showcase catalog from +`@iptvnator/shared/marketing-fixtures`. Its newest 20 movies are returned first +for the wildcard VOD listing. Poster URLs point back to the Stalker process at +`/assets/marketing/poster/.png`; `main.ts` serves the committed PNG +directory directly, so the Xtream server does not need to be running. + ### Adding a New Scenario 1. Add an entry to the `SCENARIOS` map in `src/app/scenarios.ts`. diff --git a/docs/architecture/xtream-mock-server.md b/docs/architecture/xtream-mock-server.md index 1d8bf8169..49519db85 100644 --- a/docs/architecture/xtream-mock-server.md +++ b/docs/architecture/xtream-mock-server.md @@ -273,11 +273,14 @@ labels instead of trusting provider-local strings. This scenario is reserved for release screenshots and marketing materials: -- VOD and series data use 45 curated fictional titles instead of faker-generated +- VOD and series data use 65 curated fictional titles instead of faker-generated titles or real media metadata - the core 30-title generated artwork pack keeps matched posters and backdrops; - 15 additional movie-poster showcase titles use approved local poster PNGs and - the deterministic SVG fallback for their missing backdrops + 35 additional movie-poster showcase titles use approved local poster PNGs and + the deterministic SVG fallback for their missing backdrops; the newest 20 + appear first in the VOD catalog +- showcase metadata comes from the provider-neutral + `@iptvnator/shared/marketing-fixtures` catalog shared with the Stalker mock - posters and backdrops are served from committed PNG files in `apps/xtream-mock-server/public/marketing/{poster,backdrop}/` - `tools/release/generate-marketing-artwork.ts` generates the PNGs with diff --git a/package.json b/package.json index 872879829..972020302 100644 --- a/package.json +++ b/package.json @@ -57,10 +57,10 @@ "serve:website": "nx serve website", "build:website": "nx build website", "i18n:check": "node tools/i18n/check-drift.mjs", - "release:artwork:dry-run": "tsx tools/release/generate-marketing-artwork.ts --dry-run", - "release:artwork:manifest": "tsx tools/release/generate-marketing-artwork.ts --manifest", - "release:artwork:generate": "tsx tools/release/generate-marketing-artwork.ts --generate", - "release:artwork:validate": "tsx tools/release/generate-marketing-artwork.ts --validate", + "release:artwork:dry-run": "tsx --tsconfig tsconfig.base.json tools/release/generate-marketing-artwork.ts --dry-run", + "release:artwork:manifest": "tsx --tsconfig tsconfig.base.json tools/release/generate-marketing-artwork.ts --manifest", + "release:artwork:generate": "tsx --tsconfig tsconfig.base.json tools/release/generate-marketing-artwork.ts --generate", + "release:artwork:validate": "tsx --tsconfig tsconfig.base.json tools/release/generate-marketing-artwork.ts --validate", "release:notes:validate": "node tools/release/build-release-notes.mjs --validate", "release:notes:github": "node tools/release/build-release-notes.mjs --format github", "release:notes:changelog": "node tools/release/build-release-notes.mjs --format changelog", diff --git a/tools/release/capture-v020-screenshots.ts b/tools/release/capture-v020-screenshots.ts index eb09fce16..8d19387ef 100644 --- a/tools/release/capture-v020-screenshots.ts +++ b/tools/release/capture-v020-screenshots.ts @@ -126,7 +126,11 @@ async function ensureXtreamMockServer(): Promise { const child = spawn( path.join(workspaceRoot, 'node_modules/.bin/tsx'), - ['apps/xtream-mock-server/src/main.ts'], + [ + '--tsconfig', + 'tsconfig.base.json', + 'apps/xtream-mock-server/src/main.ts', + ], { cwd: workspaceRoot, env: { @@ -515,7 +519,7 @@ async function openXtreamVodDetails(page: Page): Promise { const xtreamId = requireCapturedPlaylistId('xtreams'); await clickHrefSuffix(page, `/workspace/xtreams/${xtreamId}/vod`); - await clickCategoryByName(page, 'Hero Premieres'); + await clickCategoryByName(page, 'Action & Mystery'); await clickFirstGridCard(page); await page.waitForURL(/\/workspace\/xtreams\/[^/]+\/vod\/[^/]+\/[^/]+/, { timeout: 30_000, @@ -531,7 +535,7 @@ async function openXtreamSeriesSeason(page: Page): Promise { const xtreamId = requireCapturedPlaylistId('xtreams'); await clickHrefSuffix(page, `/workspace/xtreams/${xtreamId}/series`); - await clickCategoryByName(page, 'Hero Teams'); + await clickCategoryByName(page, 'Urban Drama'); await clickFirstGridCard(page); await page.waitForURL(/\/workspace\/xtreams\/[^/]+\/series\/[^/]+\/[^/]+/, { timeout: 30_000,