instaserve 1.0.20 → 1.1.1

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 ADDED
@@ -0,0 +1,145 @@
1
+ <div align="center">
2
+ <h1 style="color: #3b82f6; margin: 10px 0 5px;">Instaserve</h1>
3
+ <p style="color: #6b7280; margin: 0;">Instant web stack for Node.js</p>
4
+ </div>
5
+
6
+ ## Usage
7
+
8
+ <div style="background: white; padding: 15px; border-radius: 6px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); margin: 15px 0;">
9
+ <pre style="margin: 0;"><code>npx instaserve [options]</code></pre>
10
+ </div>
11
+
12
+ ## Options
13
+
14
+ <div style="display: flex; gap: 8px; margin: 8px 0;">
15
+ <code style="background: #f3f4f6; padding: 2px 4px; border-radius: 4px; color: #2563eb;">-port &lt;number&gt;</code>
16
+ <span>Port to listen on (default: 3000)</span>
17
+ </div>
18
+
19
+ <div style="display: flex; gap: 8px; margin: 8px 0;">
20
+ <code style="background: #f3f4f6; padding: 2px 4px; border-radius: 4px; color: #2563eb;">-ip &lt;address&gt;</code>
21
+ <span>IP address to bind to (default: 127.0.0.1)</span>
22
+ </div>
23
+
24
+ <div style="display: flex; gap: 8px; margin: 8px 0;">
25
+ <code style="background: #f3f4f6; padding: 2px 4px; border-radius: 4px; color: #2563eb;">-public &lt;path&gt;</code>
26
+ <span>Public directory path (default: ./public)</span>
27
+ </div>
28
+
29
+ <div style="display: flex; gap: 8px; margin: 8px 0;">
30
+ <code style="background: #f3f4f6; padding: 2px 4px; border-radius: 4px; color: #2563eb;">-api &lt;file&gt;</code>
31
+ <span>Path to routes file (default: ./routes.js)</span>
32
+ </div>
33
+
34
+ <div style="display: flex; gap: 8px; margin: 8px 0;">
35
+ <code style="background: #f3f4f6; padding: 2px 4px; border-radius: 4px; color: #2563eb;">-secure</code>
36
+ <span>Enable HTTPS (requires cert.pem and key.pem - run ./generate-certs.sh)</span>
37
+ </div>
38
+
39
+ <div style="display: flex; gap: 8px; margin: 8px 0;">
40
+ <code style="background: #f3f4f6; padding: 2px 4px; border-radius: 4px; color: #2563eb;">-help</code>
41
+ <span>Show help message</span>
42
+ </div>
43
+
44
+ ## HTTPS Support
45
+
46
+ Instaserve supports HTTPS with self-signed certificates. To enable HTTPS:
47
+
48
+ 1. **Generate certificates:**
49
+ ```bash
50
+ ./generate-certs.sh
51
+ ```
52
+ This creates `cert.pem` and `key.pem` files and adds them to your system's trust store.
53
+
54
+ 2. **Run with HTTPS:**
55
+ ```bash
56
+ npx instaserve -secure
57
+ ```
58
+
59
+ The certificate generation script:
60
+ - Creates a self-signed certificate valid for 365 days
61
+ - Automatically adds the certificate to your system trust store (macOS/Linux)
62
+ - Prevents browser security warnings
63
+
64
+ ## Routes
65
+
66
+ The routes file (`routes.js` by default) defines your API endpoints. Each route is a function that handles requests to a specific URL path.
67
+
68
+ ### Basic Route Example
69
+
70
+ ```javascript
71
+ export default {
72
+ // Handle GET /hello
73
+ hello: (req, res, data) => {
74
+ return { message: 'Hello World' }
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### Special Routes (Middleware)
80
+
81
+ Routes starting with `_` are middleware functions that run on **every request** before the main route handler. They are useful for:
82
+
83
+ - Logging requests
84
+ - Authentication
85
+ - Request modification
86
+ - Response headers
87
+
88
+ Middleware functions can:
89
+ - Return `false` to continue to the next middleware or main route
90
+ - Return a truthy value to stop processing and use that as the response
91
+ - Modify the request or response objects
92
+
93
+ #### Middleware Example
94
+
95
+ ```javascript
96
+ export default {
97
+ // Log every request
98
+ _log: (req, res, data) => {
99
+ console.log(`${req.method} ${req.url}`)
100
+ return false // Continue processing
101
+ },
102
+
103
+ // Block unauthorized requests
104
+ _auth: (req, res, data) => {
105
+ if (!data.token) {
106
+ res.writeHead(401)
107
+ return 'Unauthorized'
108
+ }
109
+ return false // Continue if authorized
110
+ }
111
+ }
112
+ ```
113
+
114
+ ### Route Parameters
115
+
116
+ Each route function receives:
117
+ - `req` - The HTTP request object
118
+ - `res` - The HTTP response object
119
+ - `data` - Combined data from:
120
+ - POST body (if JSON)
121
+ - URL query parameters
122
+ - Form data
123
+
124
+ ### Example Routes File
125
+
126
+ ```javascript
127
+ // routes.js
128
+ export default {
129
+ // Middleware example
130
+ _debug: (req, res, data) => {
131
+ console.log('Request:', req.url)
132
+ return false // Continue to next route
133
+ },
134
+
135
+ // API endpoint
136
+ api: (req, res, data) => {
137
+ return { status: 'ok', data }
138
+ },
139
+
140
+ // Error handling
141
+ testerror: () => {
142
+ throw new Error('Test error')
143
+ }
144
+ }
145
+ ```
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+
3
+ echo "Generating self-signed certificates for Instaserve..."
4
+
5
+ # Create openssl config file
6
+ cat > openssl.conf << EOF
7
+ [req]
8
+ distinguished_name = req_distinguished_name
9
+ req_extensions = v3_req
10
+ prompt = no
11
+
12
+ [req_distinguished_name]
13
+ C = US
14
+ ST = State
15
+ L = City
16
+ O = Instaserve
17
+ OU = Development
18
+ CN = localhost
19
+
20
+ [v3_req]
21
+ basicConstraints = CA:FALSE
22
+ keyUsage = nonRepudiation, digitalSignature, keyEncipherment
23
+ extendedKeyUsage = serverAuth, clientAuth
24
+ subjectAltName = @alt_names
25
+
26
+ [alt_names]
27
+ DNS.1 = localhost
28
+ DNS.2 = *.localhost
29
+ IP.1 = 127.0.0.1
30
+ IP.2 = ::1
31
+ EOF
32
+
33
+ # Generate private key
34
+ openssl genrsa -out key.pem 2048
35
+
36
+ # Generate certificate with config
37
+ openssl req -new -x509 -key key.pem -out cert.pem -days 365 -config openssl.conf -extensions v3_req
38
+
39
+ # Clean up config
40
+ rm openssl.conf
41
+
42
+ echo "Certificates generated: cert.pem and key.pem"
43
+
44
+ # Add to system trust store (macOS)
45
+ if [[ "$OSTYPE" == "darwin"* ]]; then
46
+ echo "Adding certificate to macOS trust store..."
47
+ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain cert.pem
48
+ echo "Certificate added to macOS trust store"
49
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
50
+ echo "Adding certificate to Linux trust store..."
51
+ sudo cp cert.pem /usr/local/share/ca-certificates/instaserve.crt
52
+ sudo update-ca-certificates
53
+ echo "Certificate added to Linux trust store"
54
+ else
55
+ echo "Please manually add cert.pem to your system's trust store"
56
+ fi
57
+
58
+ echo "HTTPS certificates ready! Use 'npx instaserve -secure' to enable HTTPS"
59
+ echo "Note: You may still see browser warnings for self-signed certificates"
package/instaserve ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+
3
+ import chalk from 'chalk'
4
+ import fs from 'node:fs'
5
+
6
+ console.log(chalk.cyan('\nInstaserve - Instant Web Stack\n'))
7
+ console.log(chalk.yellow('Usage:'))
8
+ console.log(chalk.green(' npx instaserve [options]\n'))
9
+ console.log(chalk.yellow('Options:'))
10
+ console.log(chalk.green(' -port <number>') + ' Port to listen on (default: 3000)')
11
+ console.log(chalk.green(' -ip <address>') + ' IP address to bind to (default: 127.0.0.1)')
12
+ console.log(chalk.green(' -public <path>') + ' Public directory path (default: ./public)')
13
+ console.log(chalk.green(' -api <file>') + ' Path to routes file (default: ./routes.js)')
14
+ console.log(chalk.green(' -secure') + ' Enable HTTPS (requires cert.pem and key.pem: run generate-certs.sh)')
15
+ console.log(chalk.green(' -help') + ' Show this help message\n')
16
+
17
+ if (process.argv.includes('-help')) {
18
+ process.exit(0)
19
+ }
20
+
21
+ import server from './module.mjs'
22
+
23
+ const args = process.argv.slice(2)
24
+ const params = {}
25
+ for (let i = 0; i < args.length; i++) {
26
+ const arg = args[i]
27
+ if (arg.startsWith('-')) {
28
+ const key = arg.slice(1)
29
+ const nextArg = args[i + 1]
30
+ if (nextArg && !nextArg.startsWith('-')) {
31
+ params[key] = nextArg
32
+ i++ // Skip the next argument since we used it
33
+ } else {
34
+ params[key] = true // Boolean flag
35
+ }
36
+ }
37
+ }
38
+
39
+ // Load routes file
40
+ let routes = {}
41
+ const routesFile = params.api || './routes.js'
42
+ if (fs.existsSync(routesFile)) {
43
+ try {
44
+ const imported = await import(routesFile)
45
+ routes = imported.default || imported
46
+ } catch (e) {
47
+ console.log(chalk.yellow(`Warning: Could not load routes file ${routesFile}: ${e.message}`))
48
+ }
49
+ }
50
+
51
+ server(routes)
package/module.mjs ADDED
@@ -0,0 +1,136 @@
1
+ import http from 'node:http'
2
+ import https from 'node:https'
3
+ import fs from 'node:fs'
4
+
5
+ const args = process.argv.slice(2)
6
+ const params = {}
7
+ for (let i = 0; i < args.length; i++) {
8
+ const arg = args[i]
9
+ if (arg.startsWith('-')) {
10
+ const key = arg.slice(1)
11
+ const nextArg = args[i + 1]
12
+ if (nextArg && !nextArg.startsWith('-')) {
13
+ params[key] = nextArg
14
+ i++ // Skip the next argument since we used it
15
+ } else {
16
+ params[key] = true // Boolean flag
17
+ }
18
+ }
19
+ }
20
+
21
+ function public_file(r, s) {
22
+ if (r.url == '/') r.url = '/index.html'
23
+ const fn = `${params.public || './public'}${r.url.replace(/\.\./g, '')}`
24
+ if (fs.existsSync(fn)) {
25
+ const content = fs.readFileSync(fn, 'utf-8')
26
+ if (fn.match(/.js$/)) {
27
+ s.writeHead(200, { 'Content-Type': 'application/javascript' })
28
+ } else {
29
+ s.writeHead(200)
30
+ }
31
+ s.end(content)
32
+ return true // Indicate file was served
33
+ }
34
+ return false // Indicate no file was served
35
+ }
36
+
37
+ export default async function (routes, port = params.port || 3000, ip = params.ip || '127.0.0.1') {
38
+ const publicDir = params.public || './public'
39
+ if (publicDir.includes('..')) {
40
+ throw new Error('Public directory path cannot contain ".."')
41
+ }
42
+ if (!fs.existsSync(publicDir)) {
43
+ throw new Error(`Public directory "${publicDir}" does not exist`)
44
+ }
45
+
46
+ const requestHandler = async (r, s) => {
47
+ let sdata = '', rrurl = r.url || ''
48
+ let responseSent = false
49
+
50
+ r.on('data', (s) => sdata += s.toString().trim())
51
+ r.on('end', (x) => {
52
+ try {
53
+ // Compose data object
54
+ const data = sdata ? JSON.parse(sdata) : {}
55
+ const qs = rrurl.split('?')
56
+ if(qs && qs[1]) {
57
+ const o = JSON.parse('{"' + decodeURI(qs[1].replace(/&/g, "\",\"").replace(/=/g, "\":\"")) + '"}')
58
+ Object.assign(data, o)
59
+ }
60
+
61
+ const midware = Object.keys(routes)
62
+ .filter((k) => k.startsWith('_'))
63
+ .find((k) => {
64
+ const result = routes[k](r, s, data)
65
+ if (result && !responseSent) {
66
+ responseSent = true
67
+ s.end(typeof result === 'string' ? result : JSON.stringify(result))
68
+ }
69
+ return result
70
+ })
71
+
72
+ // Response closed by middleware
73
+ if(responseSent || s.writableEnded) return
74
+
75
+ // Try to serve public file
76
+ if(public_file(r, s)) {
77
+ responseSent = true
78
+ return
79
+ }
80
+
81
+ const url = rrurl.split('/')[1].split('?')[0]
82
+ if (routes[url]) {
83
+ const resp = routes[url](r, s, data)
84
+ if (!responseSent && !s.writableEnded) {
85
+ responseSent = true
86
+ s.end(typeof resp === 'string' ? resp:JSON.stringify(resp))
87
+ }
88
+ return
89
+ }
90
+
91
+ if (!responseSent && !s.writableEnded) {
92
+ responseSent = true
93
+ s.writeHead(404);
94
+ s.end();
95
+ }
96
+ } catch (e) {
97
+ console.error(e.stack)
98
+ if (!responseSent && !s.writableEnded) {
99
+ responseSent = true
100
+ s.writeHead(500).end()
101
+ }
102
+ }
103
+ })
104
+ }
105
+
106
+ let server
107
+ if (params.secure) {
108
+ const certPath = './cert.pem'
109
+ const keyPath = './key.pem'
110
+
111
+ if (!fs.existsSync(certPath) || !fs.existsSync(keyPath)) {
112
+ throw new Error('Certificate files not found. Run ./generate-certs.sh first.')
113
+ }
114
+
115
+ const options = {
116
+ cert: fs.readFileSync(certPath),
117
+ key: fs.readFileSync(keyPath)
118
+ }
119
+
120
+ server = https.createServer(options, requestHandler)
121
+ } else {
122
+ server = http.createServer(requestHandler)
123
+ }
124
+
125
+ server.listen(port || 3000, ip || '')
126
+
127
+ const protocol = params.secure ? 'https' : 'http'
128
+ console.log(`started on: ${protocol}://${(process.env.ip || ip)}:${(process.env.port || port)}, public: ${publicDir}, ${Object.keys(routes).length > 0 ? `using routes: ${Object.keys(routes)}` : 'not using routes'}`)
129
+
130
+ return {
131
+ routes: routes,
132
+ port: port,
133
+ server: server,
134
+ stop: () => { server.close(); return true }
135
+ }
136
+ }
package/package.json CHANGED
@@ -1,5 +1,14 @@
1
- {
2
- "name": "instaserve",
3
- "version": "1.0.20",
4
- "bin": "./index.mjs"
5
- }
1
+ {
2
+ "name": "instaserve",
3
+ "version": "1.1.1",
4
+ "description": "Instant web stack",
5
+ "main": "module.mjs",
6
+ "bin": "./instaserve",
7
+ "scripts": {
8
+ "start": "node instaserve"
9
+ },
10
+ "type": "module",
11
+ "dependencies": {
12
+ "chalk": "^5.4.1"
13
+ }
14
+ }
@@ -0,0 +1,209 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Instaserve</title>
5
+ <style>
6
+ :root {
7
+ --primary: #3b82f6;
8
+ --primary-dark: #2563eb;
9
+ --text: #1f2937;
10
+ --text-light: #6b7280;
11
+ --bg: #f9fafb;
12
+ }
13
+ body {
14
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
15
+ line-height: 1.5;
16
+ max-width: 800px;
17
+ margin: 0 auto;
18
+ padding: 20px 15px;
19
+ color: var(--text);
20
+ background: var(--bg);
21
+ }
22
+ .header {
23
+ text-align: center;
24
+ margin-bottom: 20px;
25
+ }
26
+ .orb {
27
+ width: 60px;
28
+ height: 60px;
29
+ background: radial-gradient(circle at 30% 30%, #60a5fa, var(--primary));
30
+ border-radius: 50%;
31
+ margin: 0 auto 10px;
32
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
33
+ }
34
+ h1 {
35
+ color: var(--primary);
36
+ font-size: 2rem;
37
+ margin: 0;
38
+ }
39
+ .subtitle {
40
+ color: var(--text-light);
41
+ font-size: 1rem;
42
+ margin: 5px 0;
43
+ }
44
+ h2 {
45
+ color: var(--text);
46
+ font-size: 1.3rem;
47
+ margin: 20px 0 10px;
48
+ padding-bottom: 5px;
49
+ border-bottom: 2px solid var(--primary);
50
+ }
51
+ h3 {
52
+ color: var(--text);
53
+ font-size: 1.1rem;
54
+ margin: 15px 0 8px;
55
+ }
56
+ code {
57
+ background: #f3f4f6;
58
+ padding: 2px 4px;
59
+ border-radius: 4px;
60
+ font-family: 'SF Mono', Menlo, monospace;
61
+ color: var(--primary-dark);
62
+ }
63
+ pre {
64
+ background: #f3f4f6;
65
+ padding: 10px;
66
+ border-radius: 6px;
67
+ overflow-x: auto;
68
+ border: 1px solid #e5e7eb;
69
+ margin: 10px 0;
70
+ font-size: 0.9rem;
71
+ }
72
+ .option {
73
+ margin: 8px 0;
74
+ padding-left: 0;
75
+ position: relative;
76
+ display: flex;
77
+ gap: 8px;
78
+ }
79
+ .option:before {
80
+ display: none;
81
+ }
82
+ .option code {
83
+ flex-shrink: 0;
84
+ }
85
+ ul {
86
+ padding-left: 15px;
87
+ margin: 8px 0;
88
+ }
89
+ li {
90
+ margin: 5px 0;
91
+ }
92
+ .usage {
93
+ background: white;
94
+ padding: 15px;
95
+ border-radius: 6px;
96
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
97
+ margin: 15px 0;
98
+ }
99
+ p {
100
+ margin: 8px 0;
101
+ }
102
+ </style>
103
+ </head>
104
+ <body>
105
+ <div class="header">
106
+ <div class="orb"></div>
107
+ <h1>Instaserve</h1>
108
+ <p class="subtitle">Instant web stack for Node.js</p>
109
+ </div>
110
+
111
+ <div class="usage">
112
+ <h2>Usage</h2>
113
+ <pre><code>npx instaserve [options]</code></pre>
114
+ </div>
115
+
116
+ <h2>Options</h2>
117
+ <div class="option"><code>-port &lt;number&gt;</code> - Port to listen on (default: 3000)</div>
118
+ <div class="option"><code>-ip &lt;address&gt;</code> - IP address to bind to (default: 127.0.0.1)</div>
119
+ <div class="option"><code>-public &lt;path&gt;</code> - Public directory path (default: ./public)</div>
120
+ <div class="option"><code>-api &lt;file&gt;</code> - Path to routes file (default: ./routes.js)</div>
121
+ <div class="option"><code>-secure</code> - Enable HTTPS (requires cert.pem and key.pem - run ./generate-certs.sh)</div>
122
+ <div class="option"><code>-help</code> - Show help message</div>
123
+
124
+ <h2>HTTPS Support</h2>
125
+ <p>Instaserve supports HTTPS with self-signed certificates. To enable HTTPS:</p>
126
+ <ol>
127
+ <li><strong>Generate certificates:</strong> <code>./generate-certs.sh</code></li>
128
+ <li><strong>Run with HTTPS:</strong> <code>npx instaserve -secure</code></li>
129
+ </ol>
130
+ <p>The certificate generation script creates trusted certificates that won't show browser warnings.</p>
131
+
132
+ <h2>Routes</h2>
133
+ <p>The routes file (<code>routes.js</code> by default) defines your API endpoints. Each route is a function that handles requests to a specific URL path.</p>
134
+
135
+ <h3>Basic Route Example</h3>
136
+ <pre><code>export default {
137
+ // Handle GET /hello
138
+ hello: (req, res, data) => {
139
+ return { message: 'Hello World' }
140
+ }
141
+ }</code></pre>
142
+
143
+ <h3>Special Routes (Middleware)</h3>
144
+ <p>Routes starting with <code>_</code> are middleware functions that run on <strong>every request</strong> before the main route handler. They are useful for:</p>
145
+ <ul>
146
+ <li>Logging requests</li>
147
+ <li>Authentication</li>
148
+ <li>Request modification</li>
149
+ <li>Response headers</li>
150
+ </ul>
151
+ <p>Middleware functions can:</p>
152
+ <ul>
153
+ <li>Return <code>false</code> to continue to the next middleware or main route</li>
154
+ <li>Return a truthy value to stop processing and use that as the response</li>
155
+ <li>Modify the request or response objects</li>
156
+ </ul>
157
+
158
+ <h4>Middleware Example</h4>
159
+ <pre><code>export default {
160
+ // Log every request
161
+ _log: (req, res, data) => {
162
+ console.log(`${req.method} ${req.url}`)
163
+ return false // Continue processing
164
+ },
165
+
166
+ // Block unauthorized requests
167
+ _auth: (req, res, data) => {
168
+ if (!data.token) {
169
+ res.writeHead(401)
170
+ return 'Unauthorized'
171
+ }
172
+ return false // Continue if authorized
173
+ }
174
+ }</code></pre>
175
+
176
+ <h3>Route Parameters</h3>
177
+ <p>Each route function receives:</p>
178
+ <ul>
179
+ <li><code>req</code> - The HTTP request object</li>
180
+ <li><code>res</code> - The HTTP response object</li>
181
+ <li><code>data</code> - Combined data from:
182
+ <ul>
183
+ <li>POST body (if JSON)</li>
184
+ <li>URL query parameters</li>
185
+ <li>Form data</li>
186
+ </ul>
187
+ </li>
188
+ </ul>
189
+
190
+ <h3>Example Routes File</h3>
191
+ <pre><code>export default {
192
+ // Middleware example
193
+ _debug: (req, res, data) => {
194
+ console.log('Request:', req.url)
195
+ return false // Continue to next route
196
+ },
197
+
198
+ // API endpoint
199
+ api: (req, res, data) => {
200
+ return { status: 'ok', data }
201
+ },
202
+
203
+ // Error handling
204
+ testerror: () => {
205
+ throw new Error('Test error')
206
+ }
207
+ }</code></pre>
208
+ </body>
209
+ </html>
package/routes.js ADDED
@@ -0,0 +1,54 @@
1
+ /*
2
+ * This file defines the API routes and middleware for the Instaserve web server.
3
+ *
4
+ * The file exports a default object containing route handlers and middleware functions.
5
+ *
6
+ * Middleware functions (prefixed with _):
7
+ * - _debug: Logs request method, URL and data to console
8
+ * - _returnfalsy: Example middleware that returns true to stop request processing
9
+ * - _example: Demonstrates middleware behavior with console log
10
+ * - _end: Example of early response termination (commented out)
11
+ *
12
+ * Route handlers:
13
+ * - api: Returns a string response with the request data
14
+ * - testerror: Throws an error for testing error handling
15
+ * - testdata: Example route that returns the context parameter
16
+ *
17
+ * Each route handler receives:
18
+ * - req: HTTP request object
19
+ * - s: HTTP response object
20
+ * - data: Combined request data (POST body, query params, form data)
21
+ */
22
+
23
+ export default {
24
+ // Middleware functions (prefixed with _) run on every request
25
+ // Return false to continue processing, or a value to use as response
26
+
27
+ // Example: Log all requests
28
+ _log: (req, res, data) => {
29
+ console.log(`${req.method} ${req.url}`)
30
+ return false // Continue to next middleware or route
31
+ },
32
+
33
+ /**** Example: Basic authentication
34
+ _auth: (req, res, data) => {
35
+ if (!data.token) {
36
+ res.writeHead(401)
37
+ return 'Unauthorized'
38
+ }
39
+ return false // Continue if authorized
40
+ }, */
41
+
42
+ // Regular route handlers
43
+ hello: (req, res, data) => {
44
+ return { message: 'Hello World' }
45
+ },
46
+
47
+ _debug: ({method, url}, s, data) => { console.log(method, url, data) },
48
+ _example: (r, s) => console.log('in routes.mjs, returning a truthy value (above) will stop the chain'),
49
+ // _returnfalsy: (r, s) => { return true }, // Commented out - interferes with static file serving
50
+
51
+ api: (r, s, data) => 'an example api response, data:' + JSON.stringify(data),
52
+ testerror: () => { throw new Error('this from testerror') },
53
+ testdata: (r, s, c, d) => c
54
+ }
package/index.mjs DELETED
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env node
2
- import http from 'node:http'
3
- import fs from 'node:fs'
4
- import { pathToFileURL } from 'node:url'
5
- import { resolve } from 'node:path'
6
-
7
- const routesfile = resolve('routes.mjs')
8
- const routesurl = pathToFileURL(routesfile).href
9
- console.log(routesfile, routesurl)
10
-
11
- if (!fs.existsSync(routesfile)) {
12
- fs.writeFileSync(routesfile, `export default {
13
- _debug: ({ r, s, db }) => console.log(r.url, r.method),
14
- '/': ({ s }) => s.endJSON({ message: 'hello index' }),
15
- 'tables': name => ([k, v]) => k.match(name + ':')
16
- }`)
17
- }
18
- const routes = (await import(routesurl)).default
19
- routes['/sw.js'] = e => {
20
- e.s.writeHead(201, { 'Content-Type': 'application/javascript' })
21
- e.s.end('self.addEventListener("fetch",e=>{e.respondWith(caches.open("e").then(function(t){return t.match(e.request).then(function(n){return n||fetch(e.request).then(function(n){return e.request.url.match(/\.js$|\.css$/)&&t.put(e.request,n.clone()),n})})}))});')
22
- }
23
- const VastDB = (await import(`./vastdb.mjs`)).default
24
- const db = new VastDB(routes)
25
- console.log(db.filename, routes)
26
-
27
- http
28
- .createServer(async (r, s) => {
29
- try {
30
- let data = '';
31
- r.on('data', (s) => (data += s.toString()));
32
- r.on('end', (x) => {
33
- try {
34
- data = JSON.parse(data);
35
- } catch { }
36
- });
37
- s.endJSON = o => s.end(JSON.stringify(o))
38
- const midware = Object.keys(routes)
39
- .filter((k) => k.startsWith('_'))
40
- .map((k) => routes[k]({ r, s, data, db }));
41
- if (midware.includes(true)) return;
42
- if (routes[r.url]) return routes[r.url]({ r, s, data, db });
43
- else s.writeHead(404).end()
44
- } catch (e) {
45
- console.log(e);
46
- s.writeHead(404).end();
47
- }
48
- })
49
- .listen(3000, (x) => console.log('listening on 3000'));