tunecamp 1.0.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.
Files changed (132) hide show
  1. package/.env.local +2 -0
  2. package/.vercel/README.txt +11 -0
  3. package/.vercel/project.json +1 -0
  4. package/LICENSE +22 -0
  5. package/README.md +554 -0
  6. package/dist/cli.d.ts +6 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +172 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/generator/embedGenerator.d.ts +38 -0
  11. package/dist/generator/embedGenerator.d.ts.map +1 -0
  12. package/dist/generator/embedGenerator.js +92 -0
  13. package/dist/generator/embedGenerator.js.map +1 -0
  14. package/dist/generator/feedGenerator.d.ts +50 -0
  15. package/dist/generator/feedGenerator.d.ts.map +1 -0
  16. package/dist/generator/feedGenerator.js +167 -0
  17. package/dist/generator/feedGenerator.js.map +1 -0
  18. package/dist/generator/podcastFeedGenerator.d.ts +54 -0
  19. package/dist/generator/podcastFeedGenerator.d.ts.map +1 -0
  20. package/dist/generator/podcastFeedGenerator.js +173 -0
  21. package/dist/generator/podcastFeedGenerator.js.map +1 -0
  22. package/dist/generator/proceduralCoverGenerator.d.ts +51 -0
  23. package/dist/generator/proceduralCoverGenerator.d.ts.map +1 -0
  24. package/dist/generator/proceduralCoverGenerator.js +228 -0
  25. package/dist/generator/proceduralCoverGenerator.js.map +1 -0
  26. package/dist/generator/siteGenerator.d.ts +55 -0
  27. package/dist/generator/siteGenerator.d.ts.map +1 -0
  28. package/dist/generator/siteGenerator.js +539 -0
  29. package/dist/generator/siteGenerator.js.map +1 -0
  30. package/dist/generator/templateEngine.d.ts +13 -0
  31. package/dist/generator/templateEngine.d.ts.map +1 -0
  32. package/dist/generator/templateEngine.js +146 -0
  33. package/dist/generator/templateEngine.js.map +1 -0
  34. package/dist/index.d.ts +12 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +32 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/parser/catalogParser.d.ts +13 -0
  39. package/dist/parser/catalogParser.d.ts.map +1 -0
  40. package/dist/parser/catalogParser.js +120 -0
  41. package/dist/parser/catalogParser.js.map +1 -0
  42. package/dist/tools/generate-codes.d.ts +14 -0
  43. package/dist/tools/generate-codes.d.ts.map +1 -0
  44. package/dist/tools/generate-codes.js +274 -0
  45. package/dist/tools/generate-codes.js.map +1 -0
  46. package/dist/tools/generate-sea-pair.d.ts +14 -0
  47. package/dist/tools/generate-sea-pair.d.ts.map +1 -0
  48. package/dist/tools/generate-sea-pair.js +111 -0
  49. package/dist/tools/generate-sea-pair.js.map +1 -0
  50. package/dist/types/index.d.ts +117 -0
  51. package/dist/types/index.d.ts.map +1 -0
  52. package/dist/types/index.js +5 -0
  53. package/dist/types/index.js.map +1 -0
  54. package/dist/utils/audioUtils.d.ts +9 -0
  55. package/dist/utils/audioUtils.d.ts.map +1 -0
  56. package/dist/utils/audioUtils.js +67 -0
  57. package/dist/utils/audioUtils.js.map +1 -0
  58. package/dist/utils/configUtils.d.ts +11 -0
  59. package/dist/utils/configUtils.d.ts.map +1 -0
  60. package/dist/utils/configUtils.js +50 -0
  61. package/dist/utils/configUtils.js.map +1 -0
  62. package/dist/utils/fileUtils.d.ts +14 -0
  63. package/dist/utils/fileUtils.d.ts.map +1 -0
  64. package/dist/utils/fileUtils.js +73 -0
  65. package/dist/utils/fileUtils.js.map +1 -0
  66. package/examples/artist-free/README.md +36 -0
  67. package/examples/artist-paycurtain/README.md +49 -0
  68. package/examples/label/README.md +33 -0
  69. package/gundb-keypair.json +8 -0
  70. package/logo.svg +30 -0
  71. package/package-lock.json +1176 -0
  72. package/package.json +42 -0
  73. package/public/assets/community-registry.js +291 -0
  74. package/public/assets/download-stats.js +263 -0
  75. package/public/assets/player.js +219 -0
  76. package/public/assets/style.css +1170 -0
  77. package/public/assets/theme-widget.js +353 -0
  78. package/public/assets/unlock-codes.js +225 -0
  79. package/public/atom.xml +22 -0
  80. package/public/catalog.m3u +3 -0
  81. package/public/feed.xml +22 -0
  82. package/public/image.png +0 -0
  83. package/public/index.html +249 -0
  84. package/public/logo.svg +30 -0
  85. package/public/releases/chirichetto/Homologo - Chirichetto.wav +0 -0
  86. package/public/releases/chirichetto/cover.png +0 -0
  87. package/public/releases/chirichetto/embed-code.txt +16 -0
  88. package/public/releases/chirichetto/embed-compact.txt +8 -0
  89. package/public/releases/chirichetto/embed.html +39 -0
  90. package/public/releases/chirichetto/index.html +389 -0
  91. package/public/releases/chirichetto/playlist.m3u +3 -0
  92. package/templates/dark/assets/community-registry.js +291 -0
  93. package/templates/dark/assets/download-stats.js +263 -0
  94. package/templates/dark/assets/player.js +219 -0
  95. package/templates/dark/assets/style.css +740 -0
  96. package/templates/dark/index.hbs +73 -0
  97. package/templates/dark/layout.hbs +84 -0
  98. package/templates/dark/release.hbs +212 -0
  99. package/templates/default/assets/community-registry.js +291 -0
  100. package/templates/default/assets/download-stats.js +263 -0
  101. package/templates/default/assets/player.js +219 -0
  102. package/templates/default/assets/style.css +1170 -0
  103. package/templates/default/assets/theme-widget.js +353 -0
  104. package/templates/default/assets/unlock-codes.js +225 -0
  105. package/templates/default/index.hbs +188 -0
  106. package/templates/default/layout.hbs +117 -0
  107. package/templates/default/release.hbs +553 -0
  108. package/templates/minimal/assets/community-registry.js +291 -0
  109. package/templates/minimal/assets/download-stats.js +263 -0
  110. package/templates/minimal/assets/player.js +219 -0
  111. package/templates/minimal/assets/style.css +796 -0
  112. package/templates/minimal/index.hbs +73 -0
  113. package/templates/minimal/layout.hbs +84 -0
  114. package/templates/minimal/release.hbs +212 -0
  115. package/templates/retro/assets/community-registry.js +291 -0
  116. package/templates/retro/assets/download-stats.js +263 -0
  117. package/templates/retro/assets/player.js +219 -0
  118. package/templates/retro/assets/style.css +872 -0
  119. package/templates/retro/index.hbs +73 -0
  120. package/templates/retro/layout.hbs +84 -0
  121. package/templates/retro/release.hbs +212 -0
  122. package/templates/translucent/assets/community-registry.js +291 -0
  123. package/templates/translucent/assets/download-stats.js +263 -0
  124. package/templates/translucent/assets/player.js +219 -0
  125. package/templates/translucent/assets/style.css +1352 -0
  126. package/templates/translucent/index.hbs +73 -0
  127. package/templates/translucent/layout.hbs +84 -0
  128. package/templates/translucent/release.hbs +212 -0
  129. package/website/community.html +492 -0
  130. package/website/index.html +195 -0
  131. package/website/styles.css +396 -0
  132. package/website/tunecamp.svg +30 -0
@@ -0,0 +1,539 @@
1
+ import path from "path";
2
+ import fs from "fs-extra";
3
+ import { fileURLToPath } from "url";
4
+ import { TemplateEngine } from "./templateEngine.js";
5
+ import { FeedGenerator } from "./feedGenerator.js";
6
+ import { EmbedGenerator } from "./embedGenerator.js";
7
+ import { PodcastFeedGenerator } from "./podcastFeedGenerator.js";
8
+ import { ProceduralCoverGenerator } from "./proceduralCoverGenerator.js";
9
+ import { copyFile, ensureDir, writeFile, } from "../utils/fileUtils.js";
10
+ /**
11
+ * Generates static HTML site from catalog
12
+ */
13
+ export class SiteGenerator {
14
+ catalog;
15
+ options;
16
+ templateEngine;
17
+ templateDir;
18
+ constructor(catalog, options) {
19
+ this.catalog = catalog;
20
+ this.options = options;
21
+ this.templateEngine = new TemplateEngine();
22
+ // Use custom theme or default
23
+ const themeName = options.theme || this.catalog.config.theme || "default";
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = path.dirname(__filename);
26
+ this.templateDir = path.join(__dirname, "../../templates", themeName);
27
+ }
28
+ async generate() {
29
+ console.log("🏗️ Generating site...");
30
+ // Clean output directory
31
+ await fs.emptyDir(this.options.outputDir);
32
+ // Load templates
33
+ await this.loadTemplates();
34
+ // Copy static assets
35
+ await this.copyAssets();
36
+ // Generate pages
37
+ await this.generateIndexPage();
38
+ await this.generateReleasesPages();
39
+ // Generate artist pages if label mode
40
+ if (this.catalog.config.labelMode && this.catalog.artists) {
41
+ await this.generateArtistPages();
42
+ }
43
+ // Generate embed pages for each release
44
+ await this.generateEmbedPages();
45
+ // Generate feeds (RSS/Atom)
46
+ await this.generateFeeds();
47
+ // Generate podcast feed if enabled
48
+ if (this.catalog.config.podcast?.enabled) {
49
+ await this.generatePodcastFeed();
50
+ }
51
+ // Generate M3U playlists
52
+ await this.generateM3uPlaylists();
53
+ // Generate procedural covers for releases without cover art
54
+ await this.generateProceduralCovers();
55
+ // Copy media files
56
+ await this.copyMediaFiles();
57
+ console.log("✅ Site generated successfully!");
58
+ console.log(`📂 Output: ${this.options.outputDir}`);
59
+ }
60
+ async loadTemplates() {
61
+ const templates = ["layout", "index", "release"];
62
+ for (const templateName of templates) {
63
+ const templatePath = path.join(this.templateDir, `${templateName}.hbs`);
64
+ if (await fs.pathExists(templatePath)) {
65
+ await this.templateEngine.loadTemplate(templatePath, templateName);
66
+ }
67
+ else {
68
+ console.warn(`⚠️ Template ${templateName}.hbs not found, using default`);
69
+ }
70
+ }
71
+ }
72
+ async copyAssets() {
73
+ const assetsDir = path.join(this.templateDir, "assets");
74
+ if (await fs.pathExists(assetsDir)) {
75
+ const destAssetsDir = path.join(this.options.outputDir, "assets");
76
+ await fs.copy(assetsDir, destAssetsDir);
77
+ console.log(" 📁 Copied assets");
78
+ }
79
+ }
80
+ async generateIndexPage() {
81
+ const basePath = this.options.basePath || this.catalog.config.basePath || "";
82
+ // Prepare custom font URL
83
+ // Note: customFont should be an external URL (e.g., Google Fonts)
84
+ // For local fonts, use @font-face in customCSS instead
85
+ let customFontUrl = null;
86
+ let customFontFamily = null;
87
+ if (this.catalog.config.customFont) {
88
+ if (this.catalog.config.customFont.startsWith('http://') || this.catalog.config.customFont.startsWith('https://')) {
89
+ // External URL (e.g., Google Fonts) - extract font family from URL if possible
90
+ customFontUrl = this.catalog.config.customFont;
91
+ // Try to extract font family from Google Fonts URL
92
+ const fontMatch = this.catalog.config.customFont.match(/family=([^:&]+)/);
93
+ if (fontMatch) {
94
+ customFontFamily = fontMatch[1].replace(/\+/g, ' ');
95
+ }
96
+ }
97
+ // For local files, users should use @font-face in customCSS
98
+ }
99
+ // Prepare custom CSS URL
100
+ let customCSSUrl = null;
101
+ if (this.catalog.config.customCSS) {
102
+ if (this.catalog.config.customCSS.startsWith('http://') || this.catalog.config.customCSS.startsWith('https://')) {
103
+ // External URL
104
+ customCSSUrl = this.catalog.config.customCSS;
105
+ }
106
+ else {
107
+ // Local file - already copied to assets/
108
+ customCSSUrl = `assets/${path.basename(this.catalog.config.customCSS)}`;
109
+ }
110
+ }
111
+ const data = {
112
+ basePath,
113
+ catalog: {
114
+ ...this.catalog.config,
115
+ headerImageUrl: this.catalog.config.headerImage
116
+ ? path.basename(this.catalog.config.headerImage)
117
+ : null,
118
+ customFontUrl,
119
+ customFontFamily,
120
+ customCSSUrl,
121
+ },
122
+ artist: this.catalog.artist,
123
+ releases: this.catalog.releases
124
+ .filter((release) => !release.config.unlisted) // Filter out unlisted releases
125
+ .map((release) => ({
126
+ ...release,
127
+ url: `releases/${release.slug}/index.html`,
128
+ coverUrl: release.coverPath
129
+ ? `releases/${release.slug}/${path.basename(release.coverPath)}`
130
+ : null,
131
+ })),
132
+ };
133
+ const html = this.templateEngine.renderWithLayout("index", data);
134
+ const outputPath = path.join(this.options.outputDir, "index.html");
135
+ await writeFile(outputPath, html);
136
+ console.log(" 📄 Generated index.html");
137
+ }
138
+ async generateReleasesPages() {
139
+ for (const release of this.catalog.releases) {
140
+ await this.generateReleasePage(release);
141
+ }
142
+ }
143
+ async generateReleasePage(release) {
144
+ const releaseOutputDir = path.join(this.options.outputDir, "releases", release.slug);
145
+ await ensureDir(releaseOutputDir);
146
+ const basePath = this.options.basePath || this.catalog.config.basePath || "";
147
+ // Prepare custom font URL
148
+ let customFontUrl = null;
149
+ let customFontFamily = null;
150
+ if (this.catalog.config.customFont) {
151
+ if (this.catalog.config.customFont.startsWith('http://') || this.catalog.config.customFont.startsWith('https://')) {
152
+ customFontUrl = this.catalog.config.customFont;
153
+ // Try to extract font family from Google Fonts URL
154
+ const fontMatch = this.catalog.config.customFont.match(/family=([^:&]+)/);
155
+ if (fontMatch) {
156
+ customFontFamily = fontMatch[1].replace(/\+/g, ' ');
157
+ }
158
+ }
159
+ }
160
+ // Prepare custom CSS URL
161
+ let customCSSUrl = null;
162
+ if (this.catalog.config.customCSS) {
163
+ if (this.catalog.config.customCSS.startsWith('http://') || this.catalog.config.customCSS.startsWith('https://')) {
164
+ customCSSUrl = this.catalog.config.customCSS;
165
+ }
166
+ else {
167
+ customCSSUrl = `../../assets/${path.basename(this.catalog.config.customCSS)}`;
168
+ }
169
+ }
170
+ const siteUrl = this.catalog.config.url || "";
171
+ const releaseUrl = siteUrl
172
+ ? `${siteUrl}${basePath ? basePath : ''}releases/${release.slug}/index.html`
173
+ : `../../index.html`;
174
+ const data = {
175
+ basePath,
176
+ catalog: {
177
+ ...this.catalog.config,
178
+ headerImageUrl: this.catalog.config.headerImage
179
+ ? `../../${path.basename(this.catalog.config.headerImage)}`
180
+ : null,
181
+ customFontUrl,
182
+ customFontFamily,
183
+ customCSSUrl,
184
+ url: siteUrl,
185
+ },
186
+ artist: this.catalog.artist,
187
+ release: {
188
+ ...release,
189
+ coverUrl: release.coverPath ? path.basename(release.coverPath) : null,
190
+ tracks: release.tracks.map((track) => ({
191
+ ...track,
192
+ url: path.basename(track.file),
193
+ })),
194
+ slug: release.slug,
195
+ },
196
+ backUrl: "../../index.html",
197
+ releaseUrl,
198
+ embedCodePath: "embed-code.txt",
199
+ embedCompactPath: "embed-compact.txt",
200
+ };
201
+ const html = this.templateEngine.renderWithLayout("release", data, release.config.title);
202
+ const outputPath = path.join(releaseOutputDir, "index.html");
203
+ await writeFile(outputPath, html);
204
+ console.log(` 📄 Generated ${release.slug}/index.html`);
205
+ }
206
+ async copyMediaFiles() {
207
+ // Copy logo.svg from project root if exists
208
+ const __filename = fileURLToPath(import.meta.url);
209
+ const __dirname = path.dirname(__filename);
210
+ const projectRoot = path.join(__dirname, "../../");
211
+ const logoPath = path.join(projectRoot, "logo.svg");
212
+ if (await fs.pathExists(logoPath)) {
213
+ const logoDest = path.join(this.options.outputDir, "logo.svg");
214
+ await copyFile(logoPath, logoDest);
215
+ console.log(` 🎨 Copied logo.svg`);
216
+ }
217
+ // Copy header image if exists
218
+ if (this.catalog.config.headerImage) {
219
+ const headerImageSrc = path.join(this.options.inputDir, this.catalog.config.headerImage);
220
+ if (await fs.pathExists(headerImageSrc)) {
221
+ const headerImageDest = path.join(this.options.outputDir, path.basename(this.catalog.config.headerImage));
222
+ await copyFile(headerImageSrc, headerImageDest);
223
+ console.log(` 🖼️ Copied header image: ${this.catalog.config.headerImage}`);
224
+ }
225
+ else {
226
+ console.warn(` ⚠️ Header image not found: ${headerImageSrc}`);
227
+ }
228
+ }
229
+ else {
230
+ // Debug: check if headerImage is in config but not being read
231
+ if (this.catalog.config.headerImage) {
232
+ console.warn(` ⚠️ Header image found in config but not processed: ${this.catalog.config.headerImage}`);
233
+ }
234
+ }
235
+ // Copy custom font file if exists (only if it's a local file, not a URL)
236
+ // Note: For local fonts, users should use @font-face in custom CSS instead
237
+ if (this.catalog.config.customFont && !this.catalog.config.customFont.startsWith('http://') && !this.catalog.config.customFont.startsWith('https://')) {
238
+ const customFontSrc = path.join(this.options.inputDir, this.catalog.config.customFont);
239
+ if (await fs.pathExists(customFontSrc)) {
240
+ const customFontDest = path.join(this.options.outputDir, "assets", "fonts", path.basename(this.catalog.config.customFont));
241
+ await ensureDir(path.dirname(customFontDest));
242
+ await copyFile(customFontSrc, customFontDest);
243
+ console.log(` 🔤 Copied custom font: ${this.catalog.config.customFont}`);
244
+ }
245
+ else {
246
+ console.warn(` ⚠️ Custom font not found: ${customFontSrc}`);
247
+ }
248
+ }
249
+ // Copy custom CSS if exists (only if it's a local file, not a URL)
250
+ if (this.catalog.config.customCSS && !this.catalog.config.customCSS.startsWith('http://') && !this.catalog.config.customCSS.startsWith('https://')) {
251
+ const customCSSSrc = path.join(this.options.inputDir, this.catalog.config.customCSS);
252
+ if (await fs.pathExists(customCSSSrc)) {
253
+ const customCSSDest = path.join(this.options.outputDir, "assets", path.basename(this.catalog.config.customCSS));
254
+ await ensureDir(path.dirname(customCSSDest));
255
+ await copyFile(customCSSSrc, customCSSDest);
256
+ console.log(` 🎨 Copied custom CSS: ${this.catalog.config.customCSS}`);
257
+ }
258
+ else {
259
+ console.warn(` ⚠️ Custom CSS not found: ${customCSSSrc}`);
260
+ }
261
+ }
262
+ // Copy artist photo if exists
263
+ if (this.catalog.artist?.photo) {
264
+ const artistPhotoSrc = path.join(this.options.inputDir, this.catalog.artist.photo);
265
+ const artistPhotoDest = path.join(this.options.outputDir, path.basename(this.catalog.artist.photo));
266
+ await copyFile(artistPhotoSrc, artistPhotoDest);
267
+ console.log(` 📸 Copied artist photo: ${this.catalog.artist.photo}`);
268
+ }
269
+ for (const release of this.catalog.releases) {
270
+ const releaseOutputDir = path.join(this.options.outputDir, "releases", release.slug);
271
+ // Copy cover
272
+ if (release.coverPath) {
273
+ const coverSrc = path.join(release.path, release.coverPath);
274
+ const coverDest = path.join(releaseOutputDir, path.basename(release.coverPath));
275
+ await copyFile(coverSrc, coverDest);
276
+ }
277
+ // Copy tracks
278
+ for (const track of release.tracks) {
279
+ const trackSrc = track.file;
280
+ const trackDest = path.join(releaseOutputDir, path.basename(track.file));
281
+ await copyFile(trackSrc, trackDest);
282
+ }
283
+ }
284
+ console.log(" 🎵 Copied media files");
285
+ }
286
+ /**
287
+ * Generate RSS and Atom feeds
288
+ */
289
+ async generateFeeds() {
290
+ const siteUrl = this.catalog.config.url || "https://example.com";
291
+ const basePath = this.options.basePath || this.catalog.config.basePath || "";
292
+ const feedGenerator = new FeedGenerator(this.catalog, {
293
+ siteUrl,
294
+ basePath,
295
+ });
296
+ // Generate RSS feed
297
+ const rssFeed = feedGenerator.generateRssFeed();
298
+ await writeFile(path.join(this.options.outputDir, "feed.xml"), rssFeed);
299
+ console.log(" 📡 Generated feed.xml (RSS)");
300
+ // Generate Atom feed
301
+ const atomFeed = feedGenerator.generateAtomFeed();
302
+ await writeFile(path.join(this.options.outputDir, "atom.xml"), atomFeed);
303
+ console.log(" 📡 Generated atom.xml (Atom)");
304
+ }
305
+ /**
306
+ * Generate M3U playlists for releases and catalog
307
+ */
308
+ async generateM3uPlaylists() {
309
+ const siteUrl = this.catalog.config.url || "";
310
+ const basePath = this.options.basePath || this.catalog.config.basePath || "";
311
+ // Generate playlist for each release
312
+ for (const release of this.catalog.releases) {
313
+ const m3u = this.generateReleaseM3u(release, siteUrl, basePath);
314
+ const releaseDir = path.join(this.options.outputDir, "releases", release.slug);
315
+ await writeFile(path.join(releaseDir, "playlist.m3u"), m3u);
316
+ }
317
+ console.log(" 🎶 Generated release playlists (M3U)");
318
+ // Generate catalog-wide playlist
319
+ const catalogM3u = this.generateCatalogM3u(siteUrl, basePath);
320
+ await writeFile(path.join(this.options.outputDir, "catalog.m3u"), catalogM3u);
321
+ console.log(" 🎶 Generated catalog.m3u");
322
+ }
323
+ /**
324
+ * Generate M3U playlist for a single release
325
+ */
326
+ generateReleaseM3u(release, siteUrl, basePath) {
327
+ const lines = ["#EXTM3U"];
328
+ const artistName = this.catalog.artist?.name || "Unknown Artist";
329
+ for (const track of release.tracks) {
330
+ const duration = track.duration ? Math.round(track.duration) : -1;
331
+ const trackUrl = siteUrl
332
+ ? `${siteUrl.replace(/\/$/, "")}${basePath}/releases/${release.slug}/${path.basename(track.file)}`
333
+ : path.basename(track.file);
334
+ lines.push(`#EXTINF:${duration},${artistName} - ${track.title}`);
335
+ lines.push(trackUrl);
336
+ }
337
+ return lines.join("\n");
338
+ }
339
+ /**
340
+ * Generate M3U playlist for entire catalog
341
+ */
342
+ generateCatalogM3u(siteUrl, basePath) {
343
+ const lines = ["#EXTM3U"];
344
+ const artistName = this.catalog.artist?.name || "Unknown Artist";
345
+ // Sort releases by date (newest first)
346
+ const sortedReleases = [...this.catalog.releases].sort((a, b) => new Date(b.config.date).getTime() - new Date(a.config.date).getTime());
347
+ for (const release of sortedReleases) {
348
+ // Skip unlisted releases from catalog playlist
349
+ if (release.config.unlisted)
350
+ continue;
351
+ for (const track of release.tracks) {
352
+ const duration = track.duration ? Math.round(track.duration) : -1;
353
+ const trackUrl = siteUrl
354
+ ? `${siteUrl.replace(/\/$/, "")}${basePath}/releases/${release.slug}/${path.basename(track.file)}`
355
+ : `releases/${release.slug}/${path.basename(track.file)}`;
356
+ lines.push(`#EXTINF:${duration},${artistName} - ${track.title}`);
357
+ lines.push(trackUrl);
358
+ }
359
+ }
360
+ return lines.join("\n");
361
+ }
362
+ /**
363
+ * Generate artist pages for label mode
364
+ */
365
+ async generateArtistPages() {
366
+ if (!this.catalog.artists)
367
+ return;
368
+ const basePath = this.options.basePath || this.catalog.config.basePath || "";
369
+ for (const artist of this.catalog.artists) {
370
+ const artistSlug = artist.slug || artist.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
371
+ const artistDir = path.join(this.options.outputDir, "artists", artistSlug);
372
+ await ensureDir(artistDir);
373
+ // Get releases for this artist
374
+ const artistReleases = this.catalog.releases.filter((release) => release.config.artistSlug === artistSlug && !release.config.unlisted);
375
+ // Prepare custom font URL
376
+ let customFontUrl = null;
377
+ let customFontFamily = null;
378
+ if (this.catalog.config.customFont) {
379
+ if (this.catalog.config.customFont.startsWith('http://') || this.catalog.config.customFont.startsWith('https://')) {
380
+ customFontUrl = this.catalog.config.customFont;
381
+ // Try to extract font family from Google Fonts URL
382
+ const fontMatch = this.catalog.config.customFont.match(/family=([^:&]+)/);
383
+ if (fontMatch) {
384
+ customFontFamily = fontMatch[1].replace(/\+/g, ' ');
385
+ }
386
+ }
387
+ }
388
+ // Prepare custom CSS URL
389
+ let customCSSUrl = null;
390
+ if (this.catalog.config.customCSS) {
391
+ if (this.catalog.config.customCSS.startsWith('http://') || this.catalog.config.customCSS.startsWith('https://')) {
392
+ customCSSUrl = this.catalog.config.customCSS;
393
+ }
394
+ else {
395
+ customCSSUrl = `../../assets/${path.basename(this.catalog.config.customCSS)}`;
396
+ }
397
+ }
398
+ const data = {
399
+ basePath,
400
+ catalog: {
401
+ ...this.catalog.config,
402
+ customFontUrl,
403
+ customFontFamily,
404
+ customCSSUrl,
405
+ },
406
+ artist,
407
+ releases: artistReleases.map((release) => ({
408
+ ...release,
409
+ url: `../../releases/${release.slug}/index.html`,
410
+ coverUrl: release.coverPath
411
+ ? `../../releases/${release.slug}/${path.basename(release.coverPath)}`
412
+ : null,
413
+ })),
414
+ backUrl: "../../index.html",
415
+ };
416
+ // Try to use artist template, fall back to index
417
+ const templateName = this.templateEngine.hasTemplate("artist") ? "artist" : "index";
418
+ const html = this.templateEngine.renderWithLayout(templateName, data, artist.name);
419
+ await writeFile(path.join(artistDir, "index.html"), html);
420
+ console.log(` 👤 Generated artists/${artistSlug}/index.html`);
421
+ }
422
+ }
423
+ /**
424
+ * Generate embed pages for each release
425
+ */
426
+ async generateEmbedPages() {
427
+ const siteUrl = this.catalog.config.url || "";
428
+ const basePath = this.options.basePath || this.catalog.config.basePath || "";
429
+ const embedGenerator = new EmbedGenerator(this.catalog, { siteUrl, basePath });
430
+ for (const release of this.catalog.releases) {
431
+ const releaseDir = path.join(this.options.outputDir, "releases", release.slug);
432
+ // Generate embed.html (standalone embed page)
433
+ const embedHtml = this.generateEmbedHtmlPage(release, embedGenerator);
434
+ await writeFile(path.join(releaseDir, "embed.html"), embedHtml);
435
+ // Generate embed-code.txt (copyable embed code)
436
+ const embedCode = embedGenerator.generateReleaseEmbed(release);
437
+ await writeFile(path.join(releaseDir, "embed-code.txt"), embedCode);
438
+ // Generate compact embed code
439
+ const compactEmbed = embedGenerator.generateCompactEmbed(release);
440
+ await writeFile(path.join(releaseDir, "embed-compact.txt"), compactEmbed);
441
+ }
442
+ console.log(" 📦 Generated embed pages");
443
+ }
444
+ /**
445
+ * Generate standalone embed HTML page
446
+ */
447
+ generateEmbedHtmlPage(release, embedGenerator) {
448
+ const siteUrl = this.catalog.config.url || "";
449
+ const basePath = this.options.basePath || this.catalog.config.basePath || "";
450
+ const coverUrl = release.coverPath ? path.basename(release.coverPath) : null;
451
+ const artistName = this.catalog.artist?.name || "Unknown Artist";
452
+ const firstTrackUrl = release.tracks.length > 0 ? path.basename(release.tracks[0].file) : null;
453
+ return `<!DOCTYPE html>
454
+ <html>
455
+ <head>
456
+ <meta charset="UTF-8">
457
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
458
+ <title>${release.config.title} - Embed</title>
459
+ <style>
460
+ * { margin: 0; padding: 0; box-sizing: border-box; }
461
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1e293b; }
462
+ .embed-container { max-width: 400px; margin: 0 auto; }
463
+ .cover { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
464
+ .cover-placeholder { width: 100%; aspect-ratio: 1; background: linear-gradient(135deg, #6366f1, #8b5cf6); display: flex; align-items: center; justify-content: center; font-size: 4rem; color: rgba(255,255,255,0.3); }
465
+ .info { padding: 1rem; }
466
+ .title { font-size: 1.1rem; font-weight: 600; color: #f1f5f9; margin-bottom: 0.25rem; }
467
+ .artist { font-size: 0.9rem; color: #94a3b8; }
468
+ .tracks { font-size: 0.8rem; color: #64748b; margin-top: 0.5rem; }
469
+ audio { width: 100%; height: 40px; }
470
+ .footer { padding: 0.5rem 1rem; background: #0f172a; font-size: 0.7rem; color: #64748b; text-align: right; }
471
+ .footer a { color: #6366f1; text-decoration: none; }
472
+ .link { display: block; text-decoration: none; color: inherit; }
473
+ </style>
474
+ </head>
475
+ <body>
476
+ <div class="embed-container">
477
+ <a href="index.html" class="link" target="_top">
478
+ ${coverUrl ? `<img src="${coverUrl}" alt="${release.config.title}" class="cover">` : '<div class="cover-placeholder">♪</div>'}
479
+ <div class="info">
480
+ <div class="title">${release.config.title}</div>
481
+ <div class="artist">${artistName}</div>
482
+ <div class="tracks">${release.tracks.length} track${release.tracks.length !== 1 ? 's' : ''}</div>
483
+ </div>
484
+ </a>
485
+ ${firstTrackUrl ? `<audio controls preload="none"><source src="${firstTrackUrl}" type="audio/mpeg">Your browser does not support audio.</audio>` : ''}
486
+ <div class="footer">
487
+ Powered by <a href="https://github.com/scobru/tunecamp" target="_blank">Tunecamp</a>
488
+ </div>
489
+ </div>
490
+ </body>
491
+ </html>`;
492
+ }
493
+ /**
494
+ * Generate podcast RSS feed
495
+ */
496
+ async generatePodcastFeed() {
497
+ const siteUrl = this.catalog.config.url || "https://example.com";
498
+ const basePath = this.options.basePath || this.catalog.config.basePath || "";
499
+ const podcastConfig = this.catalog.config.podcast || {};
500
+ const podcastGenerator = new PodcastFeedGenerator(this.catalog, {
501
+ siteUrl,
502
+ basePath,
503
+ podcastTitle: podcastConfig.title,
504
+ podcastDescription: podcastConfig.description,
505
+ podcastAuthor: podcastConfig.author || this.catalog.artist?.name,
506
+ podcastEmail: podcastConfig.email,
507
+ podcastCategory: podcastConfig.category,
508
+ podcastImage: podcastConfig.image,
509
+ explicit: podcastConfig.explicit,
510
+ });
511
+ const podcastFeed = podcastGenerator.generatePodcastFeed();
512
+ await writeFile(path.join(this.options.outputDir, "podcast.xml"), podcastFeed);
513
+ console.log(" 🎙️ Generated podcast.xml");
514
+ }
515
+ /**
516
+ * Generate procedural SVG covers for releases without cover art
517
+ */
518
+ async generateProceduralCovers() {
519
+ const coverGenerator = new ProceduralCoverGenerator();
520
+ const artistName = this.catalog.artist?.name || "Unknown Artist";
521
+ let generatedCount = 0;
522
+ for (const release of this.catalog.releases) {
523
+ // Only generate if no cover exists
524
+ if (!release.coverPath) {
525
+ const releaseDir = path.join(this.options.outputDir, "releases", release.slug);
526
+ // Generate procedural cover
527
+ const svg = coverGenerator.generateCover(release.config.title, artistName, release.config.date, release.config.genres);
528
+ // Save as SVG
529
+ const coverPath = path.join(releaseDir, "cover-procedural.svg");
530
+ await writeFile(coverPath, svg);
531
+ generatedCount++;
532
+ }
533
+ }
534
+ if (generatedCount > 0) {
535
+ console.log(` 🎨 Generated ${generatedCount} procedural cover(s)`);
536
+ }
537
+ }
538
+ }
539
+ //# sourceMappingURL=siteGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"siteGenerator.js","sourceRoot":"","sources":["../../src/generator/siteGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Handlebars template engine with helpers
3
+ */
4
+ export declare class TemplateEngine {
5
+ private templates;
6
+ constructor();
7
+ private registerHelpers;
8
+ loadTemplate(templatePath: string, name: string): Promise<void>;
9
+ render(templateName: string, data: any): string;
10
+ renderWithLayout(templateName: string, data: any, pageTitle?: string): string;
11
+ hasTemplate(templateName: string): boolean;
12
+ }
13
+ //# sourceMappingURL=templateEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateEngine.d.ts","sourceRoot":"","sources":["../../src/generator/templateEngine.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAsD;;IAMvE,OAAO,CAAC,eAAe;IA2HjB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM;IAU/C,gBAAgB,CACd,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,GAAG,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM;IAiBT,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;CAG3C"}