@vatvaghool/create-ipl-dashboard 0.1.12 → 0.1.13

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/README.md CHANGED
@@ -6,7 +6,7 @@ Scaffold a full-featured IPL fantasy cricket dashboard in seconds.
6
6
  npx @vatvaghool/create-ipl-dashboard my-league
7
7
  ```
8
8
 
9
- Follow the prompts to enter your MongoDB URI, fantasy league URL, and team names — then get a ready-to-run Next.js dashboard with standings charts, performance trackers, AI roasts, and more.
9
+ Follow the prompts to enter your fantasy league URL, collection name, and team names — the database is pre-configured, so you don't need to provide a MongoDB URI. You get a ready-to-run Next.js dashboard with standings charts, performance trackers, AI roasts, and more.
10
10
 
11
11
  ## Usage
12
12
 
@@ -26,12 +26,14 @@ npx @vatvaghool/create-ipl-dashboard [project-name] [options]
26
26
 
27
27
  | Prompt | Description |
28
28
  |--------|-------------|
29
- | MongoDB URI | Your main app database connection string (or leave blank for file-based fallback) |
29
+ | Project name | Directory to scaffold into |
30
30
  | League URL | The fantasy.iplt20.com league page URL |
31
- | League DB URI | Separate database for league registry (optional — creates a collection per league) |
32
- | League name | Display name for your league (used as the collection name in the league DB) |
31
+ | Collection name | MongoDB collection to store this league's data (e.g. `ipl_2025_office_league`) |
32
+ | League name | Display name for your league |
33
33
  | Teams | Team names (and optional owners) in your league |
34
34
 
35
+ The database connection (`MONGODB_URI`) is hardcoded — you only need to specify which collection each league should use.
36
+
35
37
  If `--scrape` is provided, the CLI attempts to extract team names from the league page HTML. If that fails, it falls back to manual entry.
36
38
 
37
39
  ## Screenshots
@@ -71,7 +73,7 @@ A full Next.js 16 project with:
71
73
  - **AI roasting** — generated commentary in multiple languages
72
74
  - **Stock ticker** — fantasy stocks with sparklines
73
75
  - **Live updates** — bookmarklet or Playwright scraper for live sync
74
- - **MongoDB persistence** — optional, with file-based fallback for dev
76
+ - **MongoDB persistence** — auto-configured database connection
75
77
 
76
78
  ## Quick start after scaffold
77
79
 
@@ -95,11 +97,39 @@ Open http://localhost:3000 to see your dashboard.
95
97
  The CLI:
96
98
 
97
99
  1. Copies a pre-built Next.js app template
98
- 2. Writes your `.env` with MongoDB URI, league DB URI, league URL, and league name
100
+ 2. Writes your `.env` with the pre-configured `MONGODB_URI`, `COLLECTION_NAME`, league URL, and league name
99
101
  3. Generates `app/data/teams.ts` with your team roster
100
102
  4. Generates `app/data/league.ts` with league metadata
101
103
  5. Creates a placeholder `app/data/match-points.ts` (auto-populates as you sync)
102
104
  6. Installs dependencies
103
- 7. If a league DB URI was provided, runs `seed:league` to create a **collection named after your league** in that database, storing league metadata (name, URL, teams, timestamps)
105
+ 7. Runs `seed:league` to create a **document in your specified collection** in the pre-configured database, storing league metadata (name, URL, teams, timestamps)
106
+
107
+ Each league gets its own collection — run `create-ipl-dashboard` again with a different collection name to add another league.
104
108
 
105
109
  The template includes all dashboard components, API endpoints, scrapers, and tests from the [ipl-dashboard](https://github.com/anomalyco/ipl-dashboard) project.
110
+
111
+ ---
112
+
113
+ ## Next Steps
114
+
115
+ ### Adding more leagues
116
+
117
+ ```bash
118
+ npx @vatvaghool/create-ipl-dashboard another-league
119
+ ```
120
+
121
+ Provide a different collection name (e.g. `ipl_2025_friends_league`) and the new league will be stored in its own collection — data stays fully isolated.
122
+
123
+ ### Viewing seeded data
124
+
125
+ Connect to the MongoDB instance with any MongoDB client. Each league appears as a separate collection containing a document with `type: "league"` and all the metadata (name, URL, teams, timestamps).
126
+
127
+ ### Production deployment
128
+
129
+ ```bash
130
+ cd my-league
131
+ npm run build
132
+ npx vercel --prod
133
+ ```
134
+
135
+ Set `IPL_POST_SECRET` in your Vercel dashboard. The `MONGODB_URI` and `COLLECTION_NAME` are already configured in the scaffolded `.env`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vatvaghool/create-ipl-dashboard",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Scaffold an IPL fantasy cricket dashboard project",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.mjs CHANGED
@@ -3,10 +3,12 @@
3
3
  import { join } from "node:path";
4
4
  import { existsSync } from "node:fs";
5
5
  import { mkdir } from "node:fs/promises";
6
- import { getProjectName, getMongoUri, getLeagueUrl, getLeagueDbUri, getLeagueName, getTeams, close } from "./prompts.mjs";
6
+ import { getProjectName, getLeagueUrl, getCollectionName, getLeagueName, getTeams, close } from "./prompts.mjs";
7
7
  import { scaffoldProject } from "./scaffold.mjs";
8
8
  import { scrapeTeamsFromUrl } from "./scraper.mjs";
9
9
 
10
+ const MONGODB_URI = "mongodb+srv://admin:admin@cricket.ptjjrub.mongodb.net/?appName=cricket";
11
+
10
12
  function printHelp(exitCode) {
11
13
  console.log(`
12
14
  create-ipl-dashboard [project-name] [options]
@@ -59,9 +61,8 @@ async function main() {
59
61
 
60
62
  await mkdir(projectPath, { recursive: true });
61
63
 
62
- const mongoUri = await getMongoUri();
63
64
  const leagueUrl = await getLeagueUrl();
64
- const leagueDbUri = await getLeagueDbUri();
65
+ const collectionName = await getCollectionName();
65
66
  const leagueName = await getLeagueName();
66
67
  let teams;
67
68
 
@@ -80,7 +81,7 @@ async function main() {
80
81
 
81
82
  close();
82
83
 
83
- await scaffoldProject(projectPath, { mongoUri, leagueUrl, leagueDbUri, leagueName, teams, skipInstall: flags.skipInstall });
84
+ await scaffoldProject(projectPath, { mongoUri: MONGODB_URI, leagueUrl, collectionName, leagueName, teams, skipInstall: flags.skipInstall });
84
85
 
85
86
  console.log("");
86
87
  console.log(" Next steps:");
package/src/prompts.mjs CHANGED
@@ -33,14 +33,6 @@ export async function getProjectName(args) {
33
33
  return (await prompt("Project name: ")).trim() || "ipl-dashboard";
34
34
  }
35
35
 
36
- export async function getMongoUri() {
37
- if (!isTTY) {
38
- await consumeAllLines();
39
- return (pipedLines[promptIndex++] || "").trim();
40
- }
41
- return (await prompt("MongoDB URI (or press Enter to skip, can be set later): ")).trim();
42
- }
43
-
44
36
  export async function getLeagueUrl() {
45
37
  if (!isTTY) {
46
38
  await consumeAllLines();
@@ -49,12 +41,12 @@ export async function getLeagueUrl() {
49
41
  return (await prompt("IPL fantasy league URL (or press Enter to skip, can be set later): ")).trim();
50
42
  }
51
43
 
52
- export async function getLeagueDbUri() {
44
+ export async function getCollectionName() {
53
45
  if (!isTTY) {
54
46
  await consumeAllLines();
55
- return (pipedLines[promptIndex++] || "").trim();
47
+ return (pipedLines[promptIndex++] || "league_data").trim();
56
48
  }
57
- return (await prompt("League DB URI (separate database for league registry, press Enter to skip): ")).trim();
49
+ return (await prompt("MongoDB collection name for league data (e.g. ipl_2025_office_league): ")).trim() || "league_data";
58
50
  }
59
51
 
60
52
  export async function getLeagueName() {
package/src/scaffold.mjs CHANGED
@@ -8,7 +8,10 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
8
8
  const PACKAGE_ROOT = join(__dirname, "..");
9
9
  const TEMPLATE_DIR = join(PACKAGE_ROOT, "template");
10
10
 
11
- export async function scaffoldProject(projectPath, { mongoUri, leagueUrl, leagueDbUri, leagueName, teams, skipInstall = false }) {
11
+ export async function scaffoldProject(
12
+ projectPath,
13
+ { mongoUri, leagueUrl, collectionName, leagueName, teams, skipInstall = false },
14
+ ) {
12
15
  console.log(`\nCreating project at ${projectPath}...`);
13
16
 
14
17
  await mkdir(projectPath, { recursive: true });
@@ -19,44 +22,69 @@ export async function scaffoldProject(projectPath, { mongoUri, leagueUrl, league
19
22
  console.log(" (no template directory found, generating from scratch)");
20
23
  }
21
24
 
22
- for (const f of ["AGENTS.md", "tsconfig.tsbuildinfo", "tsconfig.buildinfo", "package-lock.json"]) {
23
- try { await rm(join(projectPath, f)); } catch {}
25
+ for (const f of [
26
+ "AGENTS.md",
27
+ "tsconfig.tsbuildinfo",
28
+ "tsconfig.buildinfo",
29
+ "package-lock.json",
30
+ ]) {
31
+ try {
32
+ await rm(join(projectPath, f));
33
+ } catch {}
24
34
  }
25
35
 
26
- await writeEnvFile(projectPath, { mongoUri, leagueUrl, leagueDbUri, leagueName });
36
+ await writeEnvFile(projectPath, {
37
+ mongoUri,
38
+ leagueUrl,
39
+ collectionName,
40
+ leagueName,
41
+ });
27
42
  await writeTeamData(projectPath, teams);
28
43
  await writeLeagueData(projectPath, { leagueName, leagueUrl, teams });
29
44
  await writeMatchPointsPlaceholder(projectPath);
30
45
  await updatePackageJson(projectPath);
31
46
 
32
- for (const f of ["app/api/ipl/live-snapshot.json", "app/api/ipl/transfers/live-snapshot.json"]) {
33
- try { await rm(join(projectPath, f)); } catch {}
47
+ for (const f of [
48
+ "app/api/ipl/live-snapshot.json",
49
+ "app/api/ipl/transfers/live-snapshot.json",
50
+ ]) {
51
+ try {
52
+ await rm(join(projectPath, f));
53
+ } catch {}
34
54
  }
35
55
 
36
56
  if (!skipInstall) {
37
57
  console.log(" Running npm install...");
38
58
  execSync("npm install", { cwd: projectPath, stdio: "inherit" });
39
59
 
40
- if (leagueDbUri && leagueName) {
60
+ if (mongoUri && leagueName) {
41
61
  console.log(" Seeding league metadata into MongoDB...");
42
62
  try {
43
- execSync(`npm run seed:league -- "${leagueName}"`, { cwd: projectPath, stdio: "inherit" });
63
+ execSync(`npm run seed:league -- "${leagueName}" "${collectionName}"`, {
64
+ cwd: projectPath,
65
+ stdio: "inherit",
66
+ });
44
67
  } catch {
45
68
  console.log(" League seed skipped (MongoDB may not be reachable yet)");
46
69
  }
47
70
  }
48
71
  } else {
49
- console.log(" Skipping npm install (run manually: cd <project> && npm install)");
72
+ console.log(
73
+ " Skipping npm install (run manually: cd <project> && npm install)",
74
+ );
50
75
  }
51
76
 
52
77
  console.log("\n Done! Your project is ready at:", projectPath);
53
78
  }
54
79
 
55
- async function writeEnvFile(projectPath, { mongoUri, leagueUrl, leagueDbUri, leagueName }) {
80
+ async function writeEnvFile(
81
+ projectPath,
82
+ { mongoUri, leagueUrl, collectionName, leagueName },
83
+ ) {
56
84
  const envPath = join(projectPath, ".env");
57
85
  const lines = [
58
86
  `MONGODB_URI=${mongoUri || ""}`,
59
- `LEAGUE_DB_URI=${leagueDbUri || ""}`,
87
+ `COLLECTION_NAME=${collectionName || "league_data"}`,
60
88
  `IPL_LEAGUE_URL=${leagueUrl || ""}`,
61
89
  `IPL_LEAGUE_NAME=${leagueName || ""}`,
62
90
  `IPL_POST_SECRET=`,
@@ -115,7 +143,7 @@ async function writeLeagueData(projectPath, { leagueName, leagueUrl, teams }) {
115
143
  await mkdir(dir, { recursive: true });
116
144
 
117
145
  const teamEntries = teams
118
- .map((t, i) => ` { id: ${t.id}, name: "${t.name}", owner: "${t.owner}" }`)
146
+ .map((t) => ` { id: ${t.id}, name: "${t.name}", owner: "${t.owner}" }`)
119
147
  .join(",\n");
120
148
 
121
149
  const content = `export type LeagueInfo = {
@@ -27,9 +27,11 @@ async function main() {
27
27
  process.exit(1);
28
28
  }
29
29
 
30
- const uri = process.env.LEAGUE_DB_URI;
30
+ const collectionName = process.argv[3] || process.env.COLLECTION_NAME?.trim() || sanitizeCollectionName(leagueName);
31
+
32
+ const uri = process.env.MONGODB_URI;
31
33
  if (!uri) {
32
- console.log("LEAGUE_DB_URI not set. Skipping league seed.");
34
+ console.log("MONGODB_URI not set. Skipping league seed.");
33
35
  return;
34
36
  }
35
37
 
@@ -54,8 +56,6 @@ async function main() {
54
56
  }
55
57
  }
56
58
 
57
- const collectionName = sanitizeCollectionName(leagueName);
58
-
59
59
  const { MongoClient } = await import("mongodb");
60
60
  const client = new MongoClient(uri);
61
61