enigmatic 0.34.0 → 0.35.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.
@@ -1,9 +0,0 @@
1
- // Mock window.components if not defined
2
- if (typeof window !== 'undefined' && !window.components) {
3
- window.components = {}
4
- }
5
-
6
- // Add fetch polyfill for jsdom
7
- if (typeof global.fetch === 'undefined') {
8
- global.fetch = require('whatwg-fetch').fetch
9
- }
package/beemap.js DELETED
@@ -1,47 +0,0 @@
1
- class BeeMap extends Map {
2
- constructor(jsonlFile, timems) {
3
- super();
4
- this.jsonlFile = jsonlFile;
5
- this.timems = timems;
6
- this.intervalId = null;
7
-
8
- // Load existing data
9
- this.load();
10
-
11
- // Set up interval to save
12
- if (!timems) return;
13
- this.intervalId = setInterval(() => {
14
- this.save();
15
- }, timems);
16
- }
17
-
18
- async load() {
19
- const file = Bun.file(this.jsonlFile);
20
- if (!(await file.exists())) return;
21
-
22
- const text = await file.text();
23
- const lines = text.trim().split('\n').filter(line => line.length > 0);
24
-
25
- for (const line of lines) {
26
- const [key, value] = JSON.parse(line);
27
- super.set(key, value);
28
- }
29
- }
30
-
31
- async save() {
32
- const lines = [];
33
- for (const [key, value] of this) {
34
- lines.push(JSON.stringify([key, value]));
35
- }
36
- await Bun.write(this.jsonlFile, lines.join('\n') + '\n');
37
- }
38
-
39
- destroy() {
40
- if (this.intervalId) {
41
- clearInterval(this.intervalId);
42
- this.intervalId = null;
43
- }
44
- }
45
- }
46
-
47
- export { BeeMap };
package/bun-server.js DELETED
@@ -1,122 +0,0 @@
1
- import { S3Client } from "bun";
2
- import { BeeMap } from "./beemap.js";
3
-
4
- const sessions = new BeeMap("sessions.jsonl", 20000), beeMaps = {};
5
- const s3 = new S3Client({
6
- accessKeyId: Bun.env.CLOUDFLARE_ACCESS_KEY_ID,
7
- secretAccessKey: Bun.env.CLOUDFLARE_SECRET_ACCESS_KEY,
8
- bucket: Bun.env.CLOUDFLARE_BUCKET_NAME,
9
- endpoint: Bun.env.CLOUDFLARE_PUBLIC_URL
10
- });
11
-
12
- const json = (data, status = 200, extraHeaders = {}) => new Response(JSON.stringify(data), {
13
- status, headers: {
14
- "Access-Control-Allow-Origin": "*",
15
- "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PURGE, PROPFIND, DOWNLOAD, OPTIONS",
16
- "Access-Control-Allow-Headers": "Content-Type, Authorization, Cookie, X-HTTP-Method-Override",
17
- "Access-Control-Allow-Credentials": "true",
18
- "Content-Type": "application/json",
19
- ...extraHeaders
20
- }
21
- });
22
-
23
- const redirect = (url, cookie = null) => new Response(null, {
24
- status: 302,
25
- headers: { Location: url, ...(cookie && { "Set-Cookie": cookie }) }
26
- });
27
-
28
- export default {
29
- async fetch(req) {
30
- const url = new URL(req.url), key = url.pathname.slice(1);
31
- const token = req.headers.get("Cookie")?.match(/token=([^;]+)/)?.[1];
32
- const user = token ? sessions.get(token) : null;
33
-
34
- if (req.method === "OPTIONS") return json(null, 204);
35
-
36
- // Serve static files from public folder
37
- if (req.method === 'GET') {
38
- const file = Bun.file(`./public${url.pathname === '/' ? '/index.html' : url.pathname}`);
39
- if (await file.exists()) return new Response(file);
40
- }
41
-
42
- if (url.pathname === '/login') {
43
- return Response.redirect(`https://${Bun.env.AUTH0_DOMAIN}/authorize?${new URLSearchParams({
44
- response_type: "code", client_id: Bun.env.AUTH0_CLIENT_ID, redirect_uri: cb, scope: "openid email profile"
45
- })}`);
46
- }
47
-
48
- if (url.pathname === '/callback') {
49
- const code = url.searchParams.get("code");
50
- if (!code) return json({ error: 'No code' }, 400);
51
- const tRes = await fetch(`https://${Bun.env.AUTH0_DOMAIN}/oauth/token`, {
52
- method: "POST", headers: { "content-type": "application/json" },
53
- body: JSON.stringify({
54
- grant_type: "authorization_code", client_id: Bun.env.AUTH0_CLIENT_ID,
55
- client_secret: Bun.env.AUTH0_CLIENT_SECRET, code, redirect_uri: `${url.origin}/callback`
56
- })
57
- });
58
- if (!tRes.ok) return json({ error: 'Auth error' }, 401);
59
- const tokens = await tRes.json();
60
- const userInfo = await (await fetch(`https://${Bun.env.AUTH0_DOMAIN}/userinfo`, {
61
- headers: { Authorization: `Bearer ${tokens.access_token}` }
62
- })).json();
63
- const session = crypto.randomUUID();
64
- sessions.set(session, {
65
- ...userInfo,
66
- login_time: new Date().toISOString(),
67
- access_token_expires_at: tokens.expires_in ? new Date(Date.now() + tokens.expires_in * 1000).toISOString() : null
68
- });
69
- return redirect(url.origin, `token=${session}; HttpOnly; Path=/; Secure; SameSite=Lax; Max-Age=86400`);
70
- }
71
-
72
- if (!token || !user) return json({ error: 'Unauthorized' }, 401);
73
-
74
- if (url.pathname === '/logout') {
75
- sessions.delete(token);
76
- return redirect(url.origin, "token=; Max-Age=0; Path=/");
77
- }
78
-
79
- // Initialize user's beeMap if needed
80
- if (!beeMaps[user.sub]) beeMaps[user.sub] = new BeeMap(`kv_${user.sub}.jsonl`, 20000);
81
-
82
- switch (req.method) {
83
- case 'GET': return json(beeMaps[user.sub].get(key) || null);
84
- case 'POST':
85
- const value = await req.text();
86
- beeMaps[user.sub].set(key, (() => { try { return JSON.parse(value); } catch { return value; } })());
87
- return json({ key, value });
88
- case 'DELETE':
89
- beeMaps[user.sub].delete(key);
90
- return json({ status: "Deleted" });
91
- case 'PUT':
92
- await s3.write(`${user.sub}/${key}`, req.body);
93
- return json({ status: "Saved to R2" });
94
- case 'PURGE':
95
- await s3.delete(`${user.sub}/${key}`);
96
- return json({ status: "Deleted from R2" });
97
- case 'PROPFIND':
98
- const list = await s3.list({ prefix: `${user.sub}/` });
99
- const items = Array.isArray(list) ? list : (list?.contents || []);
100
- return json(items.map(item => ({
101
- name: item.key?.split('/').pop() || item.name || item.Key,
102
- lastModified: item.lastModified || item.LastModified,
103
- size: item.size || item.Size || 0
104
- })));
105
- case 'PATCH':
106
- try {
107
- const exists = await s3.exists(`${user.sub}/${key}`);
108
- if (!exists) return json({ error: 'File not found' }, 404);
109
- const file = await s3.file(`${user.sub}/${key}`);
110
- if (!file) return json({ error: 'File not found' }, 404);
111
- return new Response(file.stream(), { headers: file.headers });
112
- } catch (err) {
113
- console.error('Download error:', err);
114
- return json({ error: 'File not found', details: err.message }, 404);
115
- }
116
- default: return json({ error: 'Method not allowed' }, 405);
117
- }
118
- },
119
-
120
- port: 3000,
121
- tls: { cert: Bun.file("cert.pem"), key: Bun.file("key.pem") }
122
- };
package/public/index.html DELETED
@@ -1,48 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>API Test</title>
7
- <script>
8
- window.api_url = 'https://localhost:3000';
9
- </script>
10
- <script src="custom.js"></script>
11
- <script src="client.js"></script>
12
- <style>
13
- body { font-family: sans-serif; max-width: 800px; margin: 20px auto; padding: 20px; }
14
- .section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
15
- input, button { margin: 5px; padding: 8px; }
16
- input { width: 200px; }
17
- button { cursor: pointer; }
18
- #result { margin-top: 10px; padding: 10px; background: #f5f5f5; border-radius: 3px; white-space: pre-wrap; }
19
- .error { color: red; }
20
- .success { color: green; }
21
- </style>
22
- </head>
23
- <body>
24
- <h1>Server API Test</h1>
25
-
26
- <div class="section">
27
- <h2>KV Storage</h2>
28
- <input type="text" id="kv-key" placeholder="Key" value="test-key">
29
- <input type="text" id="kv-value" placeholder="Value" value="test-value">
30
- <button onclick="window.set(document.querySelector('#kv-key').value, document.querySelector('#kv-value').value).then(r => window.$('#result').textContent = JSON.stringify(r)).catch(err => window.$('#result').textContent = 'Error: ' + err.message)">POST</button>
31
- <button onclick="window.get(document.querySelector('#kv-key').value).then(r => window.$('#result').textContent = JSON.stringify(r)).catch(err => window.$('#result').textContent = 'Error: ' + err.message)">GET</button>
32
- <button onclick="window.delete(document.querySelector('#kv-key').value).then(r => window.$('#result').textContent = JSON.stringify(r)).catch(err => window.$('#result').textContent = 'Error: ' + err.message)">DELETE</button>
33
- </div>
34
-
35
- <div class="section">
36
- <h2>R2 Storage</h2>
37
- <file-widget></file-widget>
38
- </div>
39
-
40
- <div class="section">
41
- <h2>Auth</h2>
42
- <button onclick="window.login()">Login</button>
43
- <button onclick="window.logout()">Logout</button>
44
- </div>
45
-
46
- <pre id="result"></pre>
47
- </body>
48
- </html>
@@ -1,10 +0,0 @@
1
- <script src='https://unpkg.com/enigmatic'></script>
2
- <script src='custom.js'></script>
3
-
4
- <script>
5
- window.api_url = 'http://localhost:3000';
6
- custom.hw = (data) => `Hello ${data}`;
7
- state.message = "World";
8
- </script>
9
-
10
- <file-widget></file-widget>
File without changes