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.
- package/.env.local +2 -0
- package/.vercel/README.txt +11 -0
- package/.vercel/project.json +1 -0
- package/LICENSE +22 -0
- package/README.md +554 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +172 -0
- package/dist/cli.js.map +1 -0
- package/dist/generator/embedGenerator.d.ts +38 -0
- package/dist/generator/embedGenerator.d.ts.map +1 -0
- package/dist/generator/embedGenerator.js +92 -0
- package/dist/generator/embedGenerator.js.map +1 -0
- package/dist/generator/feedGenerator.d.ts +50 -0
- package/dist/generator/feedGenerator.d.ts.map +1 -0
- package/dist/generator/feedGenerator.js +167 -0
- package/dist/generator/feedGenerator.js.map +1 -0
- package/dist/generator/podcastFeedGenerator.d.ts +54 -0
- package/dist/generator/podcastFeedGenerator.d.ts.map +1 -0
- package/dist/generator/podcastFeedGenerator.js +173 -0
- package/dist/generator/podcastFeedGenerator.js.map +1 -0
- package/dist/generator/proceduralCoverGenerator.d.ts +51 -0
- package/dist/generator/proceduralCoverGenerator.d.ts.map +1 -0
- package/dist/generator/proceduralCoverGenerator.js +228 -0
- package/dist/generator/proceduralCoverGenerator.js.map +1 -0
- package/dist/generator/siteGenerator.d.ts +55 -0
- package/dist/generator/siteGenerator.d.ts.map +1 -0
- package/dist/generator/siteGenerator.js +539 -0
- package/dist/generator/siteGenerator.js.map +1 -0
- package/dist/generator/templateEngine.d.ts +13 -0
- package/dist/generator/templateEngine.d.ts.map +1 -0
- package/dist/generator/templateEngine.js +146 -0
- package/dist/generator/templateEngine.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/catalogParser.d.ts +13 -0
- package/dist/parser/catalogParser.d.ts.map +1 -0
- package/dist/parser/catalogParser.js +120 -0
- package/dist/parser/catalogParser.js.map +1 -0
- package/dist/tools/generate-codes.d.ts +14 -0
- package/dist/tools/generate-codes.d.ts.map +1 -0
- package/dist/tools/generate-codes.js +274 -0
- package/dist/tools/generate-codes.js.map +1 -0
- package/dist/tools/generate-sea-pair.d.ts +14 -0
- package/dist/tools/generate-sea-pair.d.ts.map +1 -0
- package/dist/tools/generate-sea-pair.js +111 -0
- package/dist/tools/generate-sea-pair.js.map +1 -0
- package/dist/types/index.d.ts +117 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/audioUtils.d.ts +9 -0
- package/dist/utils/audioUtils.d.ts.map +1 -0
- package/dist/utils/audioUtils.js +67 -0
- package/dist/utils/audioUtils.js.map +1 -0
- package/dist/utils/configUtils.d.ts +11 -0
- package/dist/utils/configUtils.d.ts.map +1 -0
- package/dist/utils/configUtils.js +50 -0
- package/dist/utils/configUtils.js.map +1 -0
- package/dist/utils/fileUtils.d.ts +14 -0
- package/dist/utils/fileUtils.d.ts.map +1 -0
- package/dist/utils/fileUtils.js +73 -0
- package/dist/utils/fileUtils.js.map +1 -0
- package/examples/artist-free/README.md +36 -0
- package/examples/artist-paycurtain/README.md +49 -0
- package/examples/label/README.md +33 -0
- package/gundb-keypair.json +8 -0
- package/logo.svg +30 -0
- package/package-lock.json +1176 -0
- package/package.json +42 -0
- package/public/assets/community-registry.js +291 -0
- package/public/assets/download-stats.js +263 -0
- package/public/assets/player.js +219 -0
- package/public/assets/style.css +1170 -0
- package/public/assets/theme-widget.js +353 -0
- package/public/assets/unlock-codes.js +225 -0
- package/public/atom.xml +22 -0
- package/public/catalog.m3u +3 -0
- package/public/feed.xml +22 -0
- package/public/image.png +0 -0
- package/public/index.html +249 -0
- package/public/logo.svg +30 -0
- package/public/releases/chirichetto/Homologo - Chirichetto.wav +0 -0
- package/public/releases/chirichetto/cover.png +0 -0
- package/public/releases/chirichetto/embed-code.txt +16 -0
- package/public/releases/chirichetto/embed-compact.txt +8 -0
- package/public/releases/chirichetto/embed.html +39 -0
- package/public/releases/chirichetto/index.html +389 -0
- package/public/releases/chirichetto/playlist.m3u +3 -0
- package/templates/dark/assets/community-registry.js +291 -0
- package/templates/dark/assets/download-stats.js +263 -0
- package/templates/dark/assets/player.js +219 -0
- package/templates/dark/assets/style.css +740 -0
- package/templates/dark/index.hbs +73 -0
- package/templates/dark/layout.hbs +84 -0
- package/templates/dark/release.hbs +212 -0
- package/templates/default/assets/community-registry.js +291 -0
- package/templates/default/assets/download-stats.js +263 -0
- package/templates/default/assets/player.js +219 -0
- package/templates/default/assets/style.css +1170 -0
- package/templates/default/assets/theme-widget.js +353 -0
- package/templates/default/assets/unlock-codes.js +225 -0
- package/templates/default/index.hbs +188 -0
- package/templates/default/layout.hbs +117 -0
- package/templates/default/release.hbs +553 -0
- package/templates/minimal/assets/community-registry.js +291 -0
- package/templates/minimal/assets/download-stats.js +263 -0
- package/templates/minimal/assets/player.js +219 -0
- package/templates/minimal/assets/style.css +796 -0
- package/templates/minimal/index.hbs +73 -0
- package/templates/minimal/layout.hbs +84 -0
- package/templates/minimal/release.hbs +212 -0
- package/templates/retro/assets/community-registry.js +291 -0
- package/templates/retro/assets/download-stats.js +263 -0
- package/templates/retro/assets/player.js +219 -0
- package/templates/retro/assets/style.css +872 -0
- package/templates/retro/index.hbs +73 -0
- package/templates/retro/layout.hbs +84 -0
- package/templates/retro/release.hbs +212 -0
- package/templates/translucent/assets/community-registry.js +291 -0
- package/templates/translucent/assets/download-stats.js +263 -0
- package/templates/translucent/assets/player.js +219 -0
- package/templates/translucent/assets/style.css +1352 -0
- package/templates/translucent/index.hbs +73 -0
- package/templates/translucent/layout.hbs +84 -0
- package/templates/translucent/release.hbs +212 -0
- package/website/community.html +492 -0
- package/website/index.html +195 -0
- package/website/styles.css +396 -0
- package/website/tunecamp.svg +30 -0
package/.env.local
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
# Created by Vercel CLI
|
|
2
|
+
VERCEL_OIDC_TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im1yay00MzAyZWMxYjY3MGY0OGE5OGFkNjFkYWRlNGEyM2JlNyJ9.eyJpc3MiOiJodHRwczovL29pZGMudmVyY2VsLmNvbS9zY29icnUtcy10ZWFtIiwic3ViIjoib3duZXI6c2NvYnJ1LXMtdGVhbTpwcm9qZWN0OmhvbW9sb2dvbXVzaWM6ZW52aXJvbm1lbnQ6ZGV2ZWxvcG1lbnQiLCJzY29wZSI6Im93bmVyOnNjb2JydS1zLXRlYW06cHJvamVjdDpob21vbG9nb211c2ljOmVudmlyb25tZW50OmRldmVsb3BtZW50IiwiYXVkIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3Njb2JydS1zLXRlYW0iLCJvd25lciI6InNjb2JydS1zLXRlYW0iLCJvd25lcl9pZCI6InRlYW1fUU1vUlcwTGY5OXpiQUZPdnlzaHdycE9HIiwicHJvamVjdCI6ImhvbW9sb2dvbXVzaWMiLCJwcm9qZWN0X2lkIjoicHJqX0JiNXVkV0NPUUI1ZUd6dHlyaXZ2bUFPU2V1aXIiLCJlbnZpcm9ubWVudCI6ImRldmVsb3BtZW50IiwicGxhbiI6ImhvYmJ5IiwidXNlcl9pZCI6IkpITk02UkMyN2lEMHMxQ1JSa3o2dEJQRSIsIm5iZiI6MTc2ODM5NzczOSwiaWF0IjoxNzY4Mzk3NzM5LCJleHAiOjE3Njg0NDA5Mzl9.hoIwo5r8MYxCSfq-jL0rZgFr1zaHI0qaks2JMBpjVQ3HbrdSJMitQ8dAdO0N9DwZVxRLF7j_tPozrf8BNje03Cg6rmEJMRZyfqvAIwUO3HBBIsxSs5hvh5L4L_jIZgz5pAHk_tgF7N8I4G0N8LCmpnEaRHRmdeaACxExGUQlkU9YkGYFWNcCyfo4YBY6_-Ej_HLBvv2Sfo0gg_AMpSv8mBkK701tAhwyCtDIhTTK9ORTUwnRU5CmYTVIARgWaW30W_52FrfimmNOBZz-qVbKp3rkCg6r1w0CVwGg3TUqI1T-IOkh98SRvvIRCjzEO-g-frIytT7T19Ab-pUy8Yv35A"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
> Why do I have a folder named ".vercel" in my project?
|
|
2
|
+
The ".vercel" folder is created when you link a directory to a Vercel project.
|
|
3
|
+
|
|
4
|
+
> What does the "project.json" file contain?
|
|
5
|
+
The "project.json" file contains:
|
|
6
|
+
- The ID of the Vercel project that you linked ("projectId")
|
|
7
|
+
- The ID of the user or team your Vercel project is owned by ("orgId")
|
|
8
|
+
|
|
9
|
+
> Should I commit the ".vercel" folder?
|
|
10
|
+
No, you should not share the ".vercel" folder with anyone.
|
|
11
|
+
Upon creation, it will be automatically added to your ".gitignore" file.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"projectId":"prj_Bb5udWCOQB5eGztyrivvmAOSeuir","orgId":"team_QMoRW0Lf99zbAFOvyshwrpOG","projectName":"homologomusic"}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Tunecamp Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
<img src="./logo.svg" alt="Tunecamp" width="200" height="200" style="display: block; margin-bottom: 20px; margin-top: 20px; align-items: center; justify-content: center; margin-left: auto; margin-right: auto;">
|
|
2
|
+
|
|
3
|
+
# Tunecamp
|
|
4
|
+
|
|
5
|
+
A modern static site generator for musicians and music labels, written in JavaScript/TypeScript.
|
|
6
|
+
|
|
7
|
+
Inspired by [Faircamp](https://simonrepp.com/faircamp/), this tool helps you create beautiful, fast static websites to showcase your music without the need for databases or complex hosting.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 🎵 **Audio-first**: Automatically reads metadata from your audio files
|
|
12
|
+
- 📦 **Zero database**: Pure static HTML generation
|
|
13
|
+
- 🎨 **Customizable**: Template-based theming system
|
|
14
|
+
- 🚀 **Fast**: Static sites that load instantly
|
|
15
|
+
- 📱 **Responsive**: Mobile-friendly out of the box
|
|
16
|
+
- 🔊 **Built-in player**: Modern HTML5 audio player
|
|
17
|
+
- 💿 **Multi-format**: Support for MP3, FLAC, OGG, WAV, and more
|
|
18
|
+
- 🏷️ **Flexible metadata**: YAML-based configuration files
|
|
19
|
+
- 📡 **RSS/Atom feeds**: Automatic feed generation for releases
|
|
20
|
+
- 🎙️ **Podcast support**: Generate podcast RSS feeds
|
|
21
|
+
- 📦 **Embed widgets**: Embeddable HTML widgets for releases
|
|
22
|
+
- 🎶 **M3U playlists**: Automatic playlist generation
|
|
23
|
+
- 🎨 **Procedural covers**: Auto-generate cover art if missing
|
|
24
|
+
- 🔐 **Unlock codes**: Decentralized download protection via GunDB
|
|
25
|
+
- 🏢 **Label mode**: Multi-artist catalog support
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
### Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install -g tunecamp
|
|
33
|
+
# or
|
|
34
|
+
yarn global add tunecamp
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Basic Usage
|
|
38
|
+
|
|
39
|
+
1. **Create your catalog structure:**
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
my-music/
|
|
43
|
+
├── catalog.yaml
|
|
44
|
+
├── artist.yaml
|
|
45
|
+
└── releases/
|
|
46
|
+
└── my-first-album/
|
|
47
|
+
├── release.yaml
|
|
48
|
+
├── cover.jpg
|
|
49
|
+
└── tracks/
|
|
50
|
+
├── 01-track-one.mp3
|
|
51
|
+
├── 02-track-two.mp3
|
|
52
|
+
└── track.yaml (optional)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
2. **Configure your catalog:**
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
# catalog.yaml
|
|
59
|
+
title: "My Music Catalog"
|
|
60
|
+
description: "Independent music releases"
|
|
61
|
+
url: "https://mymusic.com"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
# artist.yaml
|
|
66
|
+
name: "Artist Name"
|
|
67
|
+
bio: "Artist biography goes here"
|
|
68
|
+
links:
|
|
69
|
+
- bandcamp: "https://artistname.bandcamp.com"
|
|
70
|
+
- spotify: "https://open.spotify.com/artist/..."
|
|
71
|
+
donationLinks:
|
|
72
|
+
- platform: "PayPal"
|
|
73
|
+
url: "https://paypal.me/artistname"
|
|
74
|
+
description: "Support the artist"
|
|
75
|
+
- platform: "Ko-fi"
|
|
76
|
+
url: "https://ko-fi.com/artistname"
|
|
77
|
+
description: "Buy me a coffee"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
# releases/my-first-album/release.yaml
|
|
82
|
+
title: "My First Album"
|
|
83
|
+
date: "2024-01-15"
|
|
84
|
+
description: "An amazing debut album"
|
|
85
|
+
download: free # Options: free, paycurtain, codes, none
|
|
86
|
+
price: 10.00
|
|
87
|
+
paypalLink: "https://paypal.me/artistname/10"
|
|
88
|
+
stripeLink: "https://buy.stripe.com/..."
|
|
89
|
+
license: "cc-by" # Options: copyright, cc-by, cc-by-sa, cc-by-nc, cc-by-nc-sa, cc-by-nc-nd, cc-by-nd, public-domain
|
|
90
|
+
unlisted: false # Set to true to hide from index but keep accessible via direct link
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
3. **Generate your site:**
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
tunecamp build ./my-music --output ./public
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
4. **Deploy:**
|
|
100
|
+
|
|
101
|
+
Upload the `public` folder to any static hosting service (Netlify, Vercel, GitHub Pages, etc.)
|
|
102
|
+
|
|
103
|
+
## Deployment
|
|
104
|
+
|
|
105
|
+
### Deploying to Different Platforms
|
|
106
|
+
|
|
107
|
+
The `basePath` configuration is essential for correct asset loading when your site is deployed.
|
|
108
|
+
|
|
109
|
+
#### Root Domain Deployment
|
|
110
|
+
|
|
111
|
+
For deployments at the root of a domain (e.g., `mymusic.com`):
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
# catalog.yaml
|
|
115
|
+
basePath: "" # or omit the field
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Subdirectory Deployment
|
|
119
|
+
|
|
120
|
+
For deployments in a subdirectory (e.g., GitHub Pages at `username.github.io/my-music`):
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
# catalog.yaml
|
|
124
|
+
basePath: "/my-music"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### Platform-Specific Examples
|
|
128
|
+
|
|
129
|
+
**GitHub Pages (Project Site)**
|
|
130
|
+
```yaml
|
|
131
|
+
basePath: "/repository-name"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Netlify/Vercel (Custom Domain)**
|
|
135
|
+
```yaml
|
|
136
|
+
basePath: ""
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Netlify/Vercel (Subdirectory)**
|
|
140
|
+
```yaml
|
|
141
|
+
basePath: "/subfolder"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
You can also override the `basePath` at build time:
|
|
145
|
+
```bash
|
|
146
|
+
tunecamp build ./my-music --output ./public --basePath /my-music
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Configuration Files
|
|
150
|
+
|
|
151
|
+
### catalog.yaml
|
|
152
|
+
|
|
153
|
+
Global catalog configuration:
|
|
154
|
+
|
|
155
|
+
```yaml
|
|
156
|
+
title: "Catalog Title"
|
|
157
|
+
description: "Catalog description"
|
|
158
|
+
url: "https://yoursite.com"
|
|
159
|
+
basePath: "" # Base path for deployment (empty for root, "/repo-name" for subdirectory)
|
|
160
|
+
theme: "default" # or custom theme name
|
|
161
|
+
language: "en"
|
|
162
|
+
headerImage: "header.png" # Optional: Image to replace title in header (Bandcamp-style)
|
|
163
|
+
customFont: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" # Optional: Custom font URL (Google Fonts, etc.) or local file path
|
|
164
|
+
customCSS: "custom.css" # Optional: Custom CSS file path (relative to input directory) or external URL
|
|
165
|
+
labelMode: false # Set to true for multi-artist label catalogs
|
|
166
|
+
podcast: # Optional podcast feed configuration
|
|
167
|
+
enabled: true
|
|
168
|
+
title: "My Podcast"
|
|
169
|
+
description: "Podcast description"
|
|
170
|
+
author: "Artist Name"
|
|
171
|
+
email: "email@example.com"
|
|
172
|
+
category: "Music"
|
|
173
|
+
image: "podcast-cover.jpg"
|
|
174
|
+
explicit: false
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Important**: The `basePath` option is crucial when deploying to subdirectories (e.g., GitHub Pages). If your site will be at `username.github.io/my-music/`, set `basePath: "/my-music"`.
|
|
178
|
+
|
|
179
|
+
### artist.yaml
|
|
180
|
+
|
|
181
|
+
Artist information:
|
|
182
|
+
|
|
183
|
+
```yaml
|
|
184
|
+
name: "Artist Name"
|
|
185
|
+
bio: "Biography text"
|
|
186
|
+
photo: "artist.jpg"
|
|
187
|
+
links:
|
|
188
|
+
- website: "https://..."
|
|
189
|
+
- bandcamp: "https://..."
|
|
190
|
+
- spotify: "https://..."
|
|
191
|
+
- instagram: "https://..."
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### release.yaml
|
|
195
|
+
|
|
196
|
+
Individual release configuration:
|
|
197
|
+
|
|
198
|
+
```yaml
|
|
199
|
+
title: "Album Title"
|
|
200
|
+
date: "2024-01-15"
|
|
201
|
+
description: "Album description"
|
|
202
|
+
cover: "cover.jpg" # Optional, auto-detected (procedural cover generated if missing)
|
|
203
|
+
download: "free" # free, paycurtain, codes, none
|
|
204
|
+
price: 10.00 # For paycurtain mode
|
|
205
|
+
paypalLink: "https://paypal.me/artistname/10" # Optional PayPal link
|
|
206
|
+
stripeLink: "https://buy.stripe.com/..." # Optional Stripe link
|
|
207
|
+
license: "cc-by" # License type
|
|
208
|
+
genres:
|
|
209
|
+
- "Electronic"
|
|
210
|
+
- "Ambient"
|
|
211
|
+
credits:
|
|
212
|
+
- role: "Producer"
|
|
213
|
+
name: "Producer Name"
|
|
214
|
+
unlisted: false # Set to true to hide from index/feeds but keep accessible via direct link
|
|
215
|
+
artistSlug: "artist-name" # For label mode: associate release with an artist
|
|
216
|
+
unlockCodes: # For download: codes mode
|
|
217
|
+
enabled: true
|
|
218
|
+
namespace: tunecamp
|
|
219
|
+
peers: # Optional custom GunDB peers
|
|
220
|
+
- "https://your-relay.com/gun"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### track.yaml
|
|
224
|
+
|
|
225
|
+
Optional track-level metadata overrides:
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
tracks:
|
|
229
|
+
- file: "01-track.mp3"
|
|
230
|
+
title: "Custom Title"
|
|
231
|
+
description: "Track notes"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## CLI Commands
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Build a catalog
|
|
238
|
+
tunecamp build <input-dir> --output <output-dir>
|
|
239
|
+
|
|
240
|
+
# Build with custom base path (overrides catalog.yaml)
|
|
241
|
+
tunecamp build <input-dir> --output <output-dir> --basePath /my-music
|
|
242
|
+
|
|
243
|
+
# Build with custom theme (overrides catalog.yaml)
|
|
244
|
+
tunecamp build <input-dir> --output <output-dir> --theme dark
|
|
245
|
+
|
|
246
|
+
# Serve locally
|
|
247
|
+
tunecamp serve <output-dir> --port 3000
|
|
248
|
+
|
|
249
|
+
# Initialize a new catalog
|
|
250
|
+
tunecamp init <directory>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Development Modes
|
|
254
|
+
|
|
255
|
+
### Free Downloads
|
|
256
|
+
|
|
257
|
+
```yaml
|
|
258
|
+
download: free
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
All tracks available for immediate download.
|
|
262
|
+
|
|
263
|
+
### Soft Paycurtain (Honor System)
|
|
264
|
+
|
|
265
|
+
```yaml
|
|
266
|
+
download: paycurtain
|
|
267
|
+
price: 10.00
|
|
268
|
+
paypalLink: "https://paypal.me/artistname/10"
|
|
269
|
+
stripeLink: "https://buy.stripe.com/..."
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Pay-what-you-want with suggested price. Users can download for free, but are encouraged to support the artist.
|
|
273
|
+
|
|
274
|
+
**⚠️ Important**: This is an **honor system** - all files remain technically downloadable. PayPal and Stripe links are simply displayed as buttons; there is no payment verification or gating. If you need real download protection, use the `codes` mode instead.
|
|
275
|
+
|
|
276
|
+
### Unlock Codes (Decentralized Protection)
|
|
277
|
+
|
|
278
|
+
```yaml
|
|
279
|
+
download: codes
|
|
280
|
+
unlockCodes:
|
|
281
|
+
enabled: true
|
|
282
|
+
namespace: tunecamp # Optional, default: tunecamp
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Protect downloads with unlock codes validated via GunDB (decentralized, no backend required). See [Unlock Codes Guide](./docs/unlock-codes-guida.md) for details.
|
|
286
|
+
|
|
287
|
+
**⚠️ Important - Self-Hosting Required**: The code generation tool (`generate-codes.ts`) must be run locally on your machine where you have access to the Tunecamp source code. If you deploy only the static HTML output (e.g., to Vercel, Netlify, GitHub Pages), you won't be able to generate new codes from the deployed site - it's just static HTML.
|
|
288
|
+
|
|
289
|
+
**Workflow:**
|
|
290
|
+
1. Run `tunecamp build` locally
|
|
291
|
+
2. Generate codes locally: `npx ts-node src/tools/generate-codes.ts <release-slug> --count 20`
|
|
292
|
+
3. Deploy the static `public/` folder to your hosting
|
|
293
|
+
4. Distribute the generated codes to your customers
|
|
294
|
+
|
|
295
|
+
Generate codes using:
|
|
296
|
+
```bash
|
|
297
|
+
npx ts-node src/tools/generate-codes.ts <release-slug> --count 20
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Download Statistics (Public GunDB)
|
|
301
|
+
|
|
302
|
+
Tunecamp automatically tracks and displays download counts for your releases using a public GunDB space. This works out of the box with no configuration required:
|
|
303
|
+
|
|
304
|
+
- **Real-time counter**: Download counts update in real-time across all visitors
|
|
305
|
+
- **Decentralized**: No server required - data is stored on public GunDB peers
|
|
306
|
+
- **Anonymous**: No user tracking, just simple counters
|
|
307
|
+
- **Visible to all**: Download counts are shown on each release page
|
|
308
|
+
|
|
309
|
+
The download counter increments when users click "Download All" or individual track download buttons.
|
|
310
|
+
|
|
311
|
+
### Community Registry (Decentralized Directory)
|
|
312
|
+
|
|
313
|
+
Tunecamp includes an automatic community registry powered by GunDB. When someone visits your Tunecamp site, it gets automatically registered in a decentralized directory of Tunecamp sites.
|
|
314
|
+
|
|
315
|
+
**Features:**
|
|
316
|
+
- **Automatic registration**: No sign-up needed - your site is discovered when visited
|
|
317
|
+
- **Decentralized**: Data stored on public GunDB peers, no central server
|
|
318
|
+
- **Real-time**: New sites appear instantly in the community directory
|
|
319
|
+
- **Privacy-respecting**: Only public info is shared (URL, title, artist name)
|
|
320
|
+
|
|
321
|
+
**How it works:**
|
|
322
|
+
1. Build and deploy your Tunecamp site
|
|
323
|
+
2. When a visitor loads your site, it registers automatically
|
|
324
|
+
3. Your site appears in the [Tunecamp Community](https://tunecamp.dev/community.html) directory
|
|
325
|
+
4. Discover other independent artists using Tunecamp!
|
|
326
|
+
|
|
327
|
+
You can disable auto-registration by removing the `community-registry.js` script from your build output.
|
|
328
|
+
|
|
329
|
+
## Supported Audio Formats
|
|
330
|
+
|
|
331
|
+
- MP3
|
|
332
|
+
- FLAC
|
|
333
|
+
- OGG Vorbis
|
|
334
|
+
- WAV
|
|
335
|
+
- M4A/AAC
|
|
336
|
+
- OPUS
|
|
337
|
+
|
|
338
|
+
## Themes
|
|
339
|
+
|
|
340
|
+
tunecamp includes 5 ready-to-use themes:
|
|
341
|
+
|
|
342
|
+
### Available Themes
|
|
343
|
+
|
|
344
|
+
1. **default** - Modern dark theme with purple/blue gradients
|
|
345
|
+
2. **minimal** - Clean light theme with lots of white space
|
|
346
|
+
3. **dark** - Aggressive dark theme with red accents (perfect for rock/metal)
|
|
347
|
+
4. **retro** - 80s-inspired theme with neon colors (perfect for synthwave/vaporwave)
|
|
348
|
+
5. **translucent** - Glassmorphism theme with blur effects and transparency (perfect for ambient/electronic)
|
|
349
|
+
|
|
350
|
+
### Using a Theme
|
|
351
|
+
|
|
352
|
+
Specify the theme in your `catalog.yaml`:
|
|
353
|
+
|
|
354
|
+
```yaml
|
|
355
|
+
catalog:
|
|
356
|
+
title: "My Music"
|
|
357
|
+
theme: "translucent" # Change to: default, minimal, dark, retro, or translucent
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Or use the `--theme` option when building:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
tunecamp build ./my-music --output ./public --theme translucent
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Creating Custom Themes
|
|
367
|
+
|
|
368
|
+
Create your own theme by adding a folder in the `templates/` directory:
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
templates/my-theme/
|
|
372
|
+
├── layout.hbs
|
|
373
|
+
├── index.hbs
|
|
374
|
+
├── release.hbs
|
|
375
|
+
└── assets/
|
|
376
|
+
├── style.css
|
|
377
|
+
└── player.js
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
For detailed information about themes, see [Theme Documentation](./docs/THEMES.md).
|
|
381
|
+
|
|
382
|
+
## Generated Files
|
|
383
|
+
|
|
384
|
+
When you build a catalog, Tunecamp automatically generates:
|
|
385
|
+
|
|
386
|
+
- **HTML pages**: `index.html` and release pages
|
|
387
|
+
- **RSS/Atom feeds**: `feed.xml` (RSS 2.0) and `atom.xml`
|
|
388
|
+
- **Podcast feed**: `podcast.xml` (if enabled in config)
|
|
389
|
+
- **M3U playlists**: `playlist.m3u` for each release and `catalog.m3u` for the entire catalog
|
|
390
|
+
- **Embed widgets**: `embed.html`, `embed-code.txt`, and `embed-compact.txt` for each release
|
|
391
|
+
- **Procedural covers**: Auto-generated SVG covers if release has no cover art
|
|
392
|
+
|
|
393
|
+
### Embed Widgets
|
|
394
|
+
|
|
395
|
+
Each release gets embeddable HTML widgets that you can use on other websites:
|
|
396
|
+
|
|
397
|
+
- **Full embed**: Complete widget with cover, info, and audio player
|
|
398
|
+
- **Compact embed**: Smaller inline widget
|
|
399
|
+
- **Iframe embed**: Standalone embed page for iframe embedding
|
|
400
|
+
|
|
401
|
+
Access embed codes at: `releases/<release-slug>/embed-code.txt`
|
|
402
|
+
|
|
403
|
+
**Share & Embed Section**: Each release page includes a "Share & Embed" section at the top with:
|
|
404
|
+
- **Catalog link**: Quick navigation back to the main catalog
|
|
405
|
+
- **RSS/Atom feeds**: Direct links to `feed.xml` (RSS 2.0) and `atom.xml` for feed readers
|
|
406
|
+
- **Copy link**: One-click button to copy the release URL to clipboard
|
|
407
|
+
- **Embed code**: Modal viewer with tabs for full and compact embed codes, with copy functionality
|
|
408
|
+
- All embed codes are accessible directly from the page without needing to navigate to text files
|
|
409
|
+
|
|
410
|
+
### RSS/Atom Feeds
|
|
411
|
+
|
|
412
|
+
Automatic feed generation for:
|
|
413
|
+
- RSS 2.0 feed at `feed.xml`
|
|
414
|
+
- Atom feed at `atom.xml`
|
|
415
|
+
- Podcast RSS feed at `podcast.xml` (if enabled)
|
|
416
|
+
|
|
417
|
+
All feeds include proper metadata, cover images, and track information.
|
|
418
|
+
|
|
419
|
+
### M3U Playlists
|
|
420
|
+
|
|
421
|
+
Playlists are generated for:
|
|
422
|
+
- Each individual release: `releases/<release-slug>/playlist.m3u`
|
|
423
|
+
- Entire catalog: `catalog.m3u`
|
|
424
|
+
|
|
425
|
+
Playlists include track metadata (duration, artist, title) and can be opened in any music player.
|
|
426
|
+
|
|
427
|
+
## Examples
|
|
428
|
+
|
|
429
|
+
Check the `/examples` directory for complete catalog examples:
|
|
430
|
+
|
|
431
|
+
- **artist-free**: Simple artist catalog with free downloads
|
|
432
|
+
- **artist-paycurtain**: Artist with pay-what-you-want model
|
|
433
|
+
- **label**: Multi-artist label catalog
|
|
434
|
+
|
|
435
|
+
## API Usage
|
|
436
|
+
|
|
437
|
+
You can also use tunecamp programmatically:
|
|
438
|
+
|
|
439
|
+
```javascript
|
|
440
|
+
import { Tunecamp } from "tunecamp";
|
|
441
|
+
|
|
442
|
+
const generator = new Tunecamp({
|
|
443
|
+
inputDir: "./my-music",
|
|
444
|
+
outputDir: "./public",
|
|
445
|
+
theme: "default",
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
await generator.build();
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## Contributing
|
|
452
|
+
|
|
453
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
454
|
+
|
|
455
|
+
## License
|
|
456
|
+
|
|
457
|
+
MIT License - see LICENSE file for details
|
|
458
|
+
|
|
459
|
+
## Credits
|
|
460
|
+
|
|
461
|
+
Inspired by [Faircamp](https://simonrepp.com/faircamp/) by Simon Repp.
|
|
462
|
+
|
|
463
|
+
## Advanced Features
|
|
464
|
+
|
|
465
|
+
### Label Mode (Multi-Artist)
|
|
466
|
+
|
|
467
|
+
Enable label mode to create catalogs with multiple artists:
|
|
468
|
+
|
|
469
|
+
```yaml
|
|
470
|
+
# catalog.yaml
|
|
471
|
+
labelMode: true
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Create `artists/` directory with artist YAML files. Each release can be associated with an artist using `artistSlug` in `release.yaml`.
|
|
475
|
+
|
|
476
|
+
### Unlisted Releases
|
|
477
|
+
|
|
478
|
+
Hide releases from the main index and feeds while keeping them accessible via direct link:
|
|
479
|
+
|
|
480
|
+
```yaml
|
|
481
|
+
# release.yaml
|
|
482
|
+
unlisted: true
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Useful for:
|
|
486
|
+
- Work-in-progress releases
|
|
487
|
+
- Exclusive content
|
|
488
|
+
- Testing releases before public launch
|
|
489
|
+
|
|
490
|
+
### Procedural Cover Generation
|
|
491
|
+
|
|
492
|
+
If a release has no cover art, Tunecamp automatically generates a procedural SVG cover based on the release title and artist name. The cover uses deterministic algorithms (no AI) to create unique, consistent artwork.
|
|
493
|
+
|
|
494
|
+
### Header Image (Bandcamp-style)
|
|
495
|
+
|
|
496
|
+
Replace the text title in the header with a custom image, similar to Bandcamp:
|
|
497
|
+
|
|
498
|
+
```yaml
|
|
499
|
+
# catalog.yaml
|
|
500
|
+
headerImage: "header.png" # Path relative to catalog directory
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
The header image will be displayed prominently at the top of all pages. If `headerImage` is set, the text title and description are hidden to avoid redundancy.
|
|
504
|
+
|
|
505
|
+
### Custom Font
|
|
506
|
+
|
|
507
|
+
Add custom fonts from Google Fonts or other sources:
|
|
508
|
+
|
|
509
|
+
```yaml
|
|
510
|
+
# catalog.yaml
|
|
511
|
+
customFont: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
The font will be loaded before the theme CSS, allowing you to use it in your custom CSS.
|
|
515
|
+
|
|
516
|
+
### Custom CSS
|
|
517
|
+
|
|
518
|
+
Add custom CSS to override or extend theme styles. You can use either a local file or an external URL:
|
|
519
|
+
|
|
520
|
+
```yaml
|
|
521
|
+
# catalog.yaml
|
|
522
|
+
# Local file (copied to assets/ during build)
|
|
523
|
+
customCSS: "custom.css"
|
|
524
|
+
|
|
525
|
+
# Or external URL (CDN, etc.)
|
|
526
|
+
customCSS: "https://cdn.jsdelivr.net/npm/water.css@2/out/water.css"
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
Local CSS files are copied to the `assets/` directory during build. The custom CSS is loaded after the theme CSS, so your styles will override the default theme.
|
|
530
|
+
|
|
531
|
+
**Example custom.css:**
|
|
532
|
+
|
|
533
|
+
```css
|
|
534
|
+
/* Apply custom font to body */
|
|
535
|
+
body {
|
|
536
|
+
font-family: 'Inter', sans-serif;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/* Custom header image styling */
|
|
540
|
+
.header-image {
|
|
541
|
+
max-height: 300px;
|
|
542
|
+
border-radius: 8px;
|
|
543
|
+
}
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## Links
|
|
547
|
+
|
|
548
|
+
- [Documentation](./docs)
|
|
549
|
+
- [Deployment Guide](./docs/DEPLOYMENT.md)
|
|
550
|
+
- [API Documentation](./docs/API.md)
|
|
551
|
+
- [Theme Showcase](./docs/THEME_SHOWCASE.md)
|
|
552
|
+
- [Unlock Codes Guide](./docs/unlock-codes-guida.md)
|
|
553
|
+
- [Examples](./examples)
|
|
554
|
+
- [Changelog](./CHANGELOG.md)
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;GAEG"}
|