launchpd 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Launchpd
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.
package/README.md ADDED
@@ -0,0 +1,183 @@
1
+ # Launchpd
2
+
3
+ Deploy static sites instantly to a live URL. No config, no complexity.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npm install -g launchpd
9
+ launchpd deploy ./my-site
10
+ # → https://abc123.launchpd.cloud
11
+ ```
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install -g launchpd
17
+ ```
18
+
19
+ Requires Node.js 20 or higher.
20
+
21
+ ## Usage
22
+
23
+ ### Deploy a folder
24
+
25
+ ```bash
26
+ launchpd deploy ./my-folder
27
+ ```
28
+
29
+ ### Use a custom subdomain
30
+
31
+ ```bash
32
+ launchpd deploy ./my-folder --name my-project
33
+ # → https://my-project.launchpd.cloud
34
+ ```
35
+
36
+ ### Set expiration time
37
+
38
+ ```bash
39
+ launchpd deploy ./my-folder --expires 2h
40
+ # Auto-deletes after 2 hours
41
+ ```
42
+
43
+ ### Dry run (preview without uploading)
44
+
45
+ ```bash
46
+ launchpd deploy ./my-folder --dry-run
47
+ ```
48
+
49
+ ### List your deployments
50
+
51
+ ```bash
52
+ launchpd list
53
+ ```
54
+
55
+ ### View version history
56
+
57
+ ```bash
58
+ launchpd versions my-subdomain
59
+ ```
60
+
61
+ ### Rollback to previous version
62
+
63
+ ```bash
64
+ launchpd rollback my-subdomain
65
+ launchpd rollback my-subdomain --to 2
66
+ ```
67
+
68
+ ## Authentication
69
+
70
+ ### Register for a free account
71
+
72
+ ```bash
73
+ launchpd register
74
+ ```
75
+
76
+ ### Login with your API key
77
+
78
+ ```bash
79
+ launchpd login
80
+ ```
81
+
82
+ ### Check current user and quota
83
+
84
+ ```bash
85
+ launchpd whoami
86
+ launchpd quota
87
+ ```
88
+
89
+ ### Logout
90
+
91
+ ```bash
92
+ launchpd logout
93
+ ```
94
+
95
+ ## Tier Limits
96
+
97
+ | Feature | Anonymous | Free (Registered) |
98
+ |---------|-----------|-------------------|
99
+ | Sites | 3 | 10 |
100
+ | Storage | 50MB | 100MB |
101
+ | Retention | 7 days | 30 days |
102
+ | Versions | 1 | 10 |
103
+
104
+ ## Development
105
+
106
+ ### Setup
107
+
108
+ ```bash
109
+ git clone https://github.com/your-username/launchpd.git
110
+ cd launchpd/cli
111
+ npm install
112
+ cp ../.env.example ../.env
113
+ # Edit ../.env with your Cloudflare R2 credentials
114
+ ```
115
+
116
+ ### Test locally
117
+
118
+ ```bash
119
+ # Dry run mode (no R2 upload)
120
+ npm run dev
121
+
122
+ # Or test with a real folder
123
+ node bin/cli.js deploy ../examples/test-site --dry-run
124
+ ```
125
+
126
+ ### Link for global testing
127
+
128
+ ```bash
129
+ npm link
130
+ launchpd deploy ./test-site --dry-run
131
+ ```
132
+
133
+ ### Run tests
134
+
135
+ ```bash
136
+ npm test
137
+ npm run test:watch
138
+ npm run test:coverage
139
+ ```
140
+
141
+ ### Lint code
142
+
143
+ ```bash
144
+ npm run lint
145
+ npm run lint:fix
146
+ ```
147
+
148
+ ## Configuration
149
+
150
+ The CLI loads configuration from environment variables. Create a `.env` file in the project root:
151
+
152
+ ```env
153
+ R2_ACCOUNT_ID=your_cloudflare_account_id
154
+ R2_ACCESS_KEY_ID=your_r2_access_key_id
155
+ R2_SECRET_ACCESS_KEY=your_r2_secret_access_key
156
+ R2_BUCKET_NAME=launchpd
157
+ LAUNCHPD_DOMAIN=launchpd.cloud
158
+ ```
159
+
160
+ ## Architecture
161
+
162
+ ```
163
+ CLI (Node.js + Commander.js)
164
+
165
+ Upload files to Cloudflare R2
166
+
167
+ Cloudflare Worker serves files
168
+
169
+ https://{subdomain}.launchpd.cloud
170
+ ```
171
+
172
+ ## Publishing to npm
173
+
174
+ ```bash
175
+ cd cli
176
+ npm run lint
177
+ npm test
178
+ npm publish --access public
179
+ ```
180
+
181
+ ## License
182
+
183
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import { deploy } from '../src/commands/deploy.js';
5
+ import { list } from '../src/commands/list.js';
6
+ import { rollback } from '../src/commands/rollback.js';
7
+ import { versions } from '../src/commands/versions.js';
8
+ import { login, logout, register, whoami, quota } from '../src/commands/auth.js';
9
+
10
+ const program = new Command();
11
+
12
+ program
13
+ .name('launchpd')
14
+ .description('Deploy static sites instantly to a live URL')
15
+ .version('0.1.0');
16
+
17
+ program
18
+ .command('deploy')
19
+ .description('Deploy a folder to a live URL')
20
+ .argument('<folder>', 'Path to the folder to deploy')
21
+ .option('--dry-run', 'Simulate deployment without uploading to R2')
22
+ .option('--name <subdomain>', 'Use a custom subdomain (optional)')
23
+ .option('--expires <time>', 'Auto-delete after time (e.g., 30m, 2h, 1d). Minimum: 30m')
24
+ .action(async (folder, options) => {
25
+ await deploy(folder, options);
26
+ });
27
+
28
+ program
29
+ .command('list')
30
+ .description('List your past deployments')
31
+ .option('--json', 'Output as JSON')
32
+ .action(async (options) => {
33
+ await list(options);
34
+ });
35
+
36
+ program
37
+ .command('versions')
38
+ .description('List all versions for a subdomain')
39
+ .argument('<subdomain>', 'The subdomain to list versions for')
40
+ .option('--json', 'Output as JSON')
41
+ .action(async (subdomain, options) => {
42
+ await versions(subdomain, options);
43
+ });
44
+
45
+ program
46
+ .command('rollback')
47
+ .description('Rollback a subdomain to a previous version')
48
+ .argument('<subdomain>', 'The subdomain to rollback')
49
+ .option('--to <n>', 'Specific version number to rollback to')
50
+ .action(async (subdomain, options) => {
51
+ await rollback(subdomain, options);
52
+ });
53
+
54
+ // Authentication commands
55
+ program
56
+ .command('login')
57
+ .description('Login with your API key')
58
+ .action(async () => {
59
+ await login();
60
+ });
61
+
62
+ program
63
+ .command('logout')
64
+ .description('Clear stored credentials')
65
+ .action(async () => {
66
+ await logout();
67
+ });
68
+
69
+ program
70
+ .command('register')
71
+ .description('Open browser to create a new account')
72
+ .action(async () => {
73
+ await register();
74
+ });
75
+
76
+ program
77
+ .command('whoami')
78
+ .description('Show current user info and quota status')
79
+ .action(async () => {
80
+ await whoami();
81
+ });
82
+
83
+ program
84
+ .command('quota')
85
+ .description('Check current quota and usage')
86
+ .action(async () => {
87
+ await quota();
88
+ });
89
+
90
+ program.parseAsync();
package/bin/setup.js ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { config, validateConfig } from '../src/config.js';
4
+ import { info, success, error } from '../src/utils/logger.js';
5
+ import chalk from 'chalk';
6
+
7
+ /**
8
+ * Setup script to validate and display configuration status
9
+ */
10
+ async function setup() {
11
+ console.log('\n' + chalk.bold.blue('═══════════════════════════════════════'));
12
+ console.log(chalk.bold.blue(' Launchpd Configuration Check'));
13
+ console.log(chalk.bold.blue('═══════════════════════════════════════\n'));
14
+
15
+ // Check environment variables
16
+ info('Checking configuration...\n');
17
+
18
+ const validation = validateConfig();
19
+
20
+ if (!validation.valid) {
21
+ error(`Missing required environment variables:`);
22
+ for (const missing of validation.missing) {
23
+ console.log(chalk.red(` ✗ ${missing}`));
24
+ }
25
+ console.log('\n' + chalk.yellow('Setup Instructions:'));
26
+ console.log(' 1. Copy .env.example to .env:');
27
+ console.log(chalk.gray(' cp .env.example .env'));
28
+ console.log(' 2. Edit .env and add your Cloudflare R2 credentials');
29
+ console.log(' 3. Get credentials from: https://dash.cloudflare.com → R2 → API Tokens\n');
30
+ process.exit(1);
31
+ }
32
+
33
+ // Display current configuration
34
+ console.log(chalk.green('✓ All required environment variables set\n'));
35
+
36
+ console.log(chalk.bold('Current Configuration:'));
37
+ console.log(chalk.gray('─'.repeat(50)));
38
+ console.log(chalk.cyan(' Domain: '), config.domain);
39
+ console.log(chalk.cyan(' R2 Bucket: '), config.r2.bucketName);
40
+ console.log(chalk.cyan(' Account ID: '), config.r2.accountId ? '✓ Set' : '✗ Missing');
41
+ console.log(chalk.cyan(' Access Key: '), config.r2.accessKeyId ? '✓ Set' : '✗ Missing');
42
+ console.log(chalk.cyan(' Secret Key: '), config.r2.secretAccessKey ? '✓ Set' : '✗ Missing');
43
+ console.log(chalk.gray('─'.repeat(50)) + '\n');
44
+
45
+ // Next steps
46
+ console.log(chalk.bold('Next Steps:'));
47
+ console.log(chalk.gray(' 1. Test dry-run deployment:'));
48
+ console.log(chalk.cyan(' npm run dev'));
49
+ console.log(chalk.gray(' 2. Deploy Worker:'));
50
+ console.log(chalk.cyan(' cd worker && wrangler deploy'));
51
+ console.log(chalk.gray(' 3. Verify DNS settings in Cloudflare Dashboard:'));
52
+ console.log(chalk.cyan(` DNS → Records → Add A record * → 192.0.2.1 (Proxied)`));
53
+ console.log(chalk.gray(' 4. Deploy your first site:'));
54
+ console.log(chalk.cyan(' launchpd deploy ./your-folder\n'));
55
+
56
+ success('Setup validation complete!');
57
+ }
58
+
59
+ setup().catch(err => {
60
+ error(`Setup failed: ${err.message}`);
61
+ process.exit(1);
62
+ });
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "launchpd",
3
+ "version": "0.1.0",
4
+ "description": "Deploy static sites instantly to a live URL",
5
+ "type": "module",
6
+ "bin": {
7
+ "launchpd": "./bin/cli.js"
8
+ },
9
+ "main": "./src/commands/index.js",
10
+ "exports": {
11
+ ".": "./src/commands/index.js",
12
+ "./utils": "./src/utils/index.js"
13
+ },
14
+ "files": [
15
+ "bin",
16
+ "src"
17
+ ],
18
+ "engines": {
19
+ "node": ">=20.0.0"
20
+ },
21
+ "scripts": {
22
+ "start": "node bin/cli.js",
23
+ "dev": "node bin/cli.js deploy ../examples/test-site --dry-run",
24
+ "setup": "node bin/setup.js",
25
+ "test": "vitest run",
26
+ "test:watch": "vitest",
27
+ "test:coverage": "vitest run --coverage",
28
+ "lint": "eslint src bin --ext .js",
29
+ "lint:fix": "eslint src bin --ext .js --fix",
30
+ "prepublishOnly": "npm run lint && npm run test"
31
+ },
32
+ "keywords": [
33
+ "static",
34
+ "hosting",
35
+ "deploy",
36
+ "cli",
37
+ "cloudflare",
38
+ "r2",
39
+ "cdn",
40
+ "website",
41
+ "publish"
42
+ ],
43
+ "author": "Kent John Edoloverio",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/kents00/launchpd.git",
48
+ "directory": "cli"
49
+ },
50
+ "bugs": {
51
+ "url": "https://github.com/kents00/launchpd/issues"
52
+ },
53
+ "homepage": "https://launchpd.cloud",
54
+ "dependencies": {
55
+ "@aws-sdk/client-s3": "^3.700.0",
56
+ "chalk": "^5.4.0",
57
+ "commander": "^14.0.0",
58
+ "dotenv": "^16.4.0",
59
+ "mime-types": "^2.1.35",
60
+ "nanoid": "^5.1.0"
61
+ },
62
+ "devDependencies": {
63
+ "@eslint/js": "^9.39.2",
64
+ "@vitest/coverage-v8": "^2.1.0",
65
+ "eslint": "^9.0.0",
66
+ "vitest": "^2.1.0"
67
+ }
68
+ }