orez 0.0.9 → 0.0.10
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/dist/bunny-local.d.ts +11 -0
- package/dist/bunny-local.d.ts.map +1 -0
- package/dist/bunny-local.js +175 -0
- package/dist/bunny-local.js.map +1 -0
- package/dist/cli.js +56 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +1 -0
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +1 -0
- package/dist/log.js.map +1 -1
- package/dist/vite-plugin.d.ts +2 -0
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +10 -1
- package/dist/vite-plugin.js.map +1 -1
- package/package.json +7 -2
- package/src/bunny-local.ts +224 -0
- package/src/cli.ts +59 -1
- package/src/index.ts +28 -4
- package/src/log.ts +1 -0
- package/src/sqlite-shim.cjs +67 -0
- package/src/vite-plugin.ts +13 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* minimal local bunny cdn storage-compatible server.
|
|
3
|
+
* handles GET/PUT/DELETE/HEAD and directory listing.
|
|
4
|
+
*/
|
|
5
|
+
import { type Server } from 'node:http';
|
|
6
|
+
export interface BunnyLocalConfig {
|
|
7
|
+
port: number;
|
|
8
|
+
dataDir: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function startBunnyLocal(config: BunnyLocalConfig): Promise<Server>;
|
|
11
|
+
//# sourceMappingURL=bunny-local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bunny-local.d.ts","sourceRoot":"","sources":["../src/bunny-local.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EAEL,KAAK,MAAM,EAGZ,MAAM,WAAW,CAAA;AAKlB,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAqED,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+HzE"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* minimal local bunny cdn storage-compatible server.
|
|
3
|
+
* handles GET/PUT/DELETE/HEAD and directory listing.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, statSync, readdirSync, } from 'node:fs';
|
|
6
|
+
import { createServer, } from 'node:http';
|
|
7
|
+
import { join, dirname, extname, relative } from 'node:path';
|
|
8
|
+
import { log } from './log.js';
|
|
9
|
+
const MIME_TYPES = {
|
|
10
|
+
'.jpg': 'image/jpeg',
|
|
11
|
+
'.jpeg': 'image/jpeg',
|
|
12
|
+
'.png': 'image/png',
|
|
13
|
+
'.gif': 'image/gif',
|
|
14
|
+
'.webp': 'image/webp',
|
|
15
|
+
'.svg': 'image/svg+xml',
|
|
16
|
+
'.json': 'application/json',
|
|
17
|
+
'.txt': 'text/plain',
|
|
18
|
+
'.pdf': 'application/pdf',
|
|
19
|
+
'.mp4': 'video/mp4',
|
|
20
|
+
'.mp3': 'audio/mpeg',
|
|
21
|
+
'.css': 'text/css',
|
|
22
|
+
'.js': 'application/javascript',
|
|
23
|
+
'.html': 'text/html',
|
|
24
|
+
'.woff': 'font/woff',
|
|
25
|
+
'.woff2': 'font/woff2',
|
|
26
|
+
'.ttf': 'font/ttf',
|
|
27
|
+
'.otf': 'font/otf',
|
|
28
|
+
};
|
|
29
|
+
function corsHeaders() {
|
|
30
|
+
return {
|
|
31
|
+
'Access-Control-Allow-Origin': '*',
|
|
32
|
+
'Access-Control-Allow-Methods': 'GET, PUT, DELETE, HEAD, OPTIONS',
|
|
33
|
+
'Access-Control-Allow-Headers': '*',
|
|
34
|
+
'Access-Control-Expose-Headers': 'Content-Length',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// recursively collect files for directory listing
|
|
38
|
+
function listFiles(dir, baseDir) {
|
|
39
|
+
if (!existsSync(dir) || !statSync(dir).isDirectory()) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
43
|
+
return entries.map((entry) => {
|
|
44
|
+
const fullPath = join(dir, entry.name);
|
|
45
|
+
const stat = statSync(fullPath);
|
|
46
|
+
const relativePath = '/' + relative(baseDir, dir) + '/';
|
|
47
|
+
return {
|
|
48
|
+
Guid: '00000000-0000-0000-0000-000000000000',
|
|
49
|
+
StorageZoneName: '',
|
|
50
|
+
Path: relativePath,
|
|
51
|
+
ObjectName: entry.name,
|
|
52
|
+
Length: entry.isDirectory() ? 0 : stat.size,
|
|
53
|
+
LastChanged: stat.mtime.toISOString(),
|
|
54
|
+
IsDirectory: entry.isDirectory(),
|
|
55
|
+
DateCreated: stat.birthtime.toISOString(),
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export function startBunnyLocal(config) {
|
|
60
|
+
const storageDir = join(config.dataDir, 'bunny');
|
|
61
|
+
mkdirSync(storageDir, { recursive: true });
|
|
62
|
+
const server = createServer((req, res) => {
|
|
63
|
+
const headers = corsHeaders();
|
|
64
|
+
if (req.method === 'OPTIONS') {
|
|
65
|
+
res.writeHead(200, headers);
|
|
66
|
+
res.end();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const url = new URL(req.url || '/', `http://localhost:${config.port}`);
|
|
70
|
+
// sanitize path to prevent traversal
|
|
71
|
+
const normalized = url.pathname
|
|
72
|
+
.split('/')
|
|
73
|
+
.filter((s) => s && s !== '..' && s !== '.')
|
|
74
|
+
.join('/');
|
|
75
|
+
const filePath = join(storageDir, normalized);
|
|
76
|
+
if (!filePath.startsWith(storageDir)) {
|
|
77
|
+
res.writeHead(403, headers);
|
|
78
|
+
res.end();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
switch (req.method) {
|
|
83
|
+
case 'GET': {
|
|
84
|
+
// directory listing if path ends with / or is a directory
|
|
85
|
+
if (url.pathname.endsWith('/') ||
|
|
86
|
+
(existsSync(filePath) && statSync(filePath).isDirectory())) {
|
|
87
|
+
const items = listFiles(filePath, storageDir);
|
|
88
|
+
const body = JSON.stringify(items);
|
|
89
|
+
res.writeHead(200, {
|
|
90
|
+
...headers,
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
});
|
|
93
|
+
res.end(body);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!existsSync(filePath)) {
|
|
97
|
+
res.writeHead(404, { ...headers, 'Content-Type': 'application/json' });
|
|
98
|
+
res.end(JSON.stringify({ HttpCode: 404, Message: 'Object Not Found' }));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const data = readFileSync(filePath);
|
|
102
|
+
const ext = extname(filePath);
|
|
103
|
+
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
104
|
+
res.writeHead(200, {
|
|
105
|
+
...headers,
|
|
106
|
+
'Content-Type': contentType,
|
|
107
|
+
'Content-Length': data.length.toString(),
|
|
108
|
+
});
|
|
109
|
+
res.end(data);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case 'PUT': {
|
|
113
|
+
const chunks = [];
|
|
114
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
115
|
+
req.on('end', () => {
|
|
116
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
117
|
+
const body = Buffer.concat(chunks);
|
|
118
|
+
writeFileSync(filePath, body);
|
|
119
|
+
res.writeHead(201, {
|
|
120
|
+
...headers,
|
|
121
|
+
'Content-Type': 'application/json',
|
|
122
|
+
});
|
|
123
|
+
res.end(JSON.stringify({ HttpCode: 201, Message: 'File uploaded.' }));
|
|
124
|
+
});
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case 'DELETE': {
|
|
128
|
+
if (existsSync(filePath)) {
|
|
129
|
+
unlinkSync(filePath);
|
|
130
|
+
}
|
|
131
|
+
res.writeHead(200, {
|
|
132
|
+
...headers,
|
|
133
|
+
'Content-Type': 'application/json',
|
|
134
|
+
});
|
|
135
|
+
res.end(JSON.stringify({ HttpCode: 200, Message: 'File deleted successfuly.' }));
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case 'HEAD': {
|
|
139
|
+
if (!existsSync(filePath) || statSync(filePath).isDirectory()) {
|
|
140
|
+
res.writeHead(404, headers);
|
|
141
|
+
res.end();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const stat = statSync(filePath);
|
|
145
|
+
const ext2 = extname(filePath);
|
|
146
|
+
res.writeHead(200, {
|
|
147
|
+
...headers,
|
|
148
|
+
'Content-Type': MIME_TYPES[ext2] || 'application/octet-stream',
|
|
149
|
+
'Content-Length': stat.size.toString(),
|
|
150
|
+
});
|
|
151
|
+
res.end();
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
default:
|
|
155
|
+
res.writeHead(405, headers);
|
|
156
|
+
res.end();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
res.writeHead(500, {
|
|
161
|
+
...headers,
|
|
162
|
+
'Content-Type': 'application/json',
|
|
163
|
+
});
|
|
164
|
+
res.end(JSON.stringify({ HttpCode: 500, Message: 'Internal Server Error' }));
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
return new Promise((resolve, reject) => {
|
|
168
|
+
server.listen(config.port, '127.0.0.1', () => {
|
|
169
|
+
log.bunny(`listening on port ${config.port}`);
|
|
170
|
+
resolve(server);
|
|
171
|
+
});
|
|
172
|
+
server.on('error', reject);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=bunny-local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bunny-local.js","sourceRoot":"","sources":["../src/bunny-local.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { defineCommand, runMain } from 'citty';
|
|
3
3
|
import { startZeroLite } from './index.js';
|
|
4
4
|
import { log } from './log.js';
|
|
5
|
-
import { startS3Local } from './s3-local.js';
|
|
6
5
|
const s3Command = defineCommand({
|
|
7
6
|
meta: {
|
|
8
7
|
name: 's3',
|
|
@@ -21,6 +20,7 @@ const s3Command = defineCommand({
|
|
|
21
20
|
},
|
|
22
21
|
},
|
|
23
22
|
async run({ args }) {
|
|
23
|
+
const { startS3Local } = await import('./s3-local.js');
|
|
24
24
|
const server = await startS3Local({
|
|
25
25
|
port: Number(args.port),
|
|
26
26
|
dataDir: args['data-dir'],
|
|
@@ -35,6 +35,39 @@ const s3Command = defineCommand({
|
|
|
35
35
|
});
|
|
36
36
|
},
|
|
37
37
|
});
|
|
38
|
+
const bunnyCommand = defineCommand({
|
|
39
|
+
meta: {
|
|
40
|
+
name: 'bunny',
|
|
41
|
+
description: 'start a local bunny cdn storage-compatible server',
|
|
42
|
+
},
|
|
43
|
+
args: {
|
|
44
|
+
port: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
description: 'port to listen on',
|
|
47
|
+
default: '3533',
|
|
48
|
+
},
|
|
49
|
+
'data-dir': {
|
|
50
|
+
type: 'string',
|
|
51
|
+
description: 'data directory for stored files',
|
|
52
|
+
default: '.orez',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
async run({ args }) {
|
|
56
|
+
const { startBunnyLocal } = await import('./bunny-local.js');
|
|
57
|
+
const server = await startBunnyLocal({
|
|
58
|
+
port: Number(args.port),
|
|
59
|
+
dataDir: args['data-dir'],
|
|
60
|
+
});
|
|
61
|
+
process.on('SIGINT', () => {
|
|
62
|
+
server.close();
|
|
63
|
+
process.exit(0);
|
|
64
|
+
});
|
|
65
|
+
process.on('SIGTERM', () => {
|
|
66
|
+
server.close();
|
|
67
|
+
process.exit(0);
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
});
|
|
38
71
|
const main = defineCommand({
|
|
39
72
|
meta: {
|
|
40
73
|
name: 'orez',
|
|
@@ -96,9 +129,20 @@ const main = defineCommand({
|
|
|
96
129
|
description: 's3 server port',
|
|
97
130
|
default: '9200',
|
|
98
131
|
},
|
|
132
|
+
bunny: {
|
|
133
|
+
type: 'boolean',
|
|
134
|
+
description: 'also start a local bunny cdn storage-compatible server',
|
|
135
|
+
default: false,
|
|
136
|
+
},
|
|
137
|
+
'bunny-port': {
|
|
138
|
+
type: 'string',
|
|
139
|
+
description: 'bunny storage server port',
|
|
140
|
+
default: '3533',
|
|
141
|
+
},
|
|
99
142
|
},
|
|
100
143
|
subCommands: {
|
|
101
144
|
s3: s3Command,
|
|
145
|
+
bunny: bunnyCommand,
|
|
102
146
|
},
|
|
103
147
|
async run({ args }) {
|
|
104
148
|
const { config, stop } = await startZeroLite({
|
|
@@ -114,22 +158,33 @@ const main = defineCommand({
|
|
|
114
158
|
});
|
|
115
159
|
let s3Server = null;
|
|
116
160
|
if (args.s3) {
|
|
161
|
+
const { startS3Local } = await import('./s3-local.js');
|
|
117
162
|
s3Server = await startS3Local({
|
|
118
163
|
port: Number(args['s3-port']),
|
|
119
164
|
dataDir: args['data-dir'],
|
|
120
165
|
});
|
|
121
166
|
}
|
|
167
|
+
let bunnyServer = null;
|
|
168
|
+
if (args.bunny) {
|
|
169
|
+
const { startBunnyLocal } = await import('./bunny-local.js');
|
|
170
|
+
bunnyServer = await startBunnyLocal({
|
|
171
|
+
port: Number(args['bunny-port']),
|
|
172
|
+
dataDir: args['data-dir'],
|
|
173
|
+
});
|
|
174
|
+
}
|
|
122
175
|
log.orez('ready');
|
|
123
176
|
log.orez(`pg: postgresql://${config.pgUser}:${config.pgPassword}@127.0.0.1:${config.pgPort}/postgres`);
|
|
124
177
|
if (!config.skipZeroCache) {
|
|
125
178
|
log.zero(`http://localhost:${config.zeroPort}`);
|
|
126
179
|
}
|
|
127
180
|
process.on('SIGINT', async () => {
|
|
181
|
+
bunnyServer?.close();
|
|
128
182
|
s3Server?.close();
|
|
129
183
|
await stop();
|
|
130
184
|
process.exit(0);
|
|
131
185
|
});
|
|
132
186
|
process.on('SIGTERM', async () => {
|
|
187
|
+
bunnyServer?.close();
|
|
133
188
|
s3Server?.close();
|
|
134
189
|
await stop();
|
|
135
190
|
process.exit(0);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* `bun run` command.
|
|
7
7
|
*/
|
|
8
8
|
import type { ZeroLiteConfig } from './config.js';
|
|
9
|
-
export type { ZeroLiteConfig, LogLevel } from './config.js';
|
|
10
9
|
export { getConfig, getConnectionString } from './config.js';
|
|
10
|
+
export type { LogLevel, ZeroLiteConfig } from './config.js';
|
|
11
11
|
export declare function startZeroLite(overrides?: Partial<ZeroLiteConfig>): Promise<{
|
|
12
12
|
config: ZeroLiteConfig;
|
|
13
13
|
stop: () => Promise<void>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC5D,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE3D,wBAAsB,aAAa,CAAC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM;;;GA4D1E"}
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* `bun run` command.
|
|
7
7
|
*/
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
|
-
import { existsSync, readFileSync,
|
|
10
|
-
import { resolve
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { resolve } from 'node:path';
|
|
11
11
|
import { getConfig, getConnectionString } from './config.js';
|
|
12
12
|
import { log } from './log.js';
|
|
13
13
|
import { startPgProxy } from './pg-proxy.js';
|
|
@@ -124,6 +124,28 @@ async function seedIfNeeded(db, config) {
|
|
|
124
124
|
}
|
|
125
125
|
log.orez('seeded demo data');
|
|
126
126
|
}
|
|
127
|
+
function patchSqliteForWasm() {
|
|
128
|
+
// replace @rocicorp/zero-sqlite3 with bedrock-sqlite (wasm) shim
|
|
129
|
+
// so zero-cache uses wasm instead of native bindings
|
|
130
|
+
try {
|
|
131
|
+
const sqlitePkg = import.meta.resolve('@rocicorp/zero-sqlite3').replace('file://', '');
|
|
132
|
+
const indexPath = resolve(sqlitePkg, '..', 'index.js');
|
|
133
|
+
if (!existsSync(indexPath))
|
|
134
|
+
return;
|
|
135
|
+
const current = readFileSync(indexPath, 'utf-8');
|
|
136
|
+
if (current.includes('bedrock-sqlite'))
|
|
137
|
+
return; // already patched
|
|
138
|
+
const shimPath = resolve(import.meta.dirname, 'sqlite-shim.cjs');
|
|
139
|
+
if (!existsSync(shimPath))
|
|
140
|
+
return;
|
|
141
|
+
const shim = `'use strict';\nmodule.exports = require('${shimPath}');\n`;
|
|
142
|
+
writeFileSync(indexPath, shim);
|
|
143
|
+
log.orez('patched @rocicorp/zero-sqlite3 -> bedrock-sqlite (wasm)');
|
|
144
|
+
}
|
|
145
|
+
catch (e) {
|
|
146
|
+
log.orez(`sqlite wasm patch skipped: ${e}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
127
149
|
async function startZeroCache(config) {
|
|
128
150
|
// resolve @rocicorp/zero entry, cli.js is right next to it
|
|
129
151
|
let zeroCacheBin = '';
|
|
@@ -139,6 +161,8 @@ async function startZeroCache(config) {
|
|
|
139
161
|
if (!zeroCacheBin) {
|
|
140
162
|
throw new Error('zero-cache binary not found. install @rocicorp/zero');
|
|
141
163
|
}
|
|
164
|
+
// patch sqlite to use wasm before spawning zero-cache
|
|
165
|
+
patchSqliteForWasm();
|
|
142
166
|
const upstreamUrl = getConnectionString(config, 'postgres');
|
|
143
167
|
const cvrUrl = getConnectionString(config, 'zero_cvr');
|
|
144
168
|
const cdbUrl = getConnectionString(config, 'zero_cdb');
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAKvE,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAG5D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,YAAqC,EAAE;IACzE,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;IAEnC,uBAAuB;IACvB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa;QACnC,CAAC,CAAC,MAAM,CAAC,QAAQ;QACjB,CAAC,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACnC,IAAI,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,MAAM,kBAAkB,MAAM,EAAE,CAAC,CAAA;IACvF,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,QAAQ,KAAK,MAAM,CAAC,QAAQ;QACvD,GAAG,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,QAAQ,kBAAkB,QAAQ,EAAE,CAAC,CAAA;IAC/D,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAE1B,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IACvB,GAAG,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAEhD,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE9C,eAAe;IACf,MAAM,EAAE,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAA;IAE7C,iBAAiB;IACjB,MAAM,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAE/B,0BAA0B;IAC1B,GAAG,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;IACtC,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAA;IAE/B,kBAAkB;IAClB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAE/C,sBAAsB;IACtB,MAAM,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAE9B,uDAAuD;IACvD,aAAa,CAAC,MAAM,CAAC,CAAA;IAErB,mBAAmB;IACnB,IAAI,gBAAgB,GAAwB,IAAI,CAAA;IAChD,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1B,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;QAClC,gBAAgB,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAA;QAC/C,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAChC,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAA;IACtD,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;QACtB,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;QAC5B,IAAI,gBAAgB,EAAE,CAAC;YACrB,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAClC,CAAC;QACD,QAAQ,CAAC,KAAK,EAAE,CAAA;QAChB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAA;QAChB,eAAe,EAAE,CAAA;QACjB,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACrB,CAAC,CAAA;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;AACzB,CAAC;AAED,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;AAC5C,MAAM,gBAAgB,GAAG,0BAA0B,CAAA;AAEnD,SAAS,aAAa,CAAC,MAAsB;IAC3C,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC3D,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACtD,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAEtD,MAAM,OAAO,GAAG,GAAG,gBAAgB;qBAChB,MAAM,CAAC,MAAM;iBACjB,MAAM,CAAC,QAAQ;4CACY,MAAM,CAAC,QAAQ;oBACvC,WAAW;eAChB,MAAM;kBACH,MAAM;CACvB,CAAA;IACC,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;IACtC,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAA;AAC7C,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;YACrD,IAAI,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACzC,UAAU,CAAC,cAAc,CAAC,CAAA;gBAC1B,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,EAAU,EAAE,MAAsB;IAC5D,gCAAgC;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,CAC3B,6CAA6C,CAC9C,CAAA;QACD,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,OAAM;QACR,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;IAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACzC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,GAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;QACxC,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAG,GAAG;SACnB,KAAK,CAAC,0BAA0B,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAA;IAElB,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACrB,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;AAC9B,CAAC;AAED,SAAS,kBAAkB;IACzB,iEAAiE;IACjE,qDAAqD;IACrD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QACtF,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;QACtD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAM;QAElC,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAChD,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YAAE,OAAM,CAAC,kBAAkB;QAEjE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAA;QAChE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAM;QAEjC,MAAM,IAAI,GAAG,4CAA4C,QAAQ,OAAO,CAAA;QACxE,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QAC9B,GAAG,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAA;IACrE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAA;IAC7C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,MAAsB;IAClD,2DAA2D;IAC3D,IAAI,YAAY,GAAG,EAAE,CAAA;IACrB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QAC1E,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC1C,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,YAAY,GAAG,GAAG,CAAA;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;IACxE,CAAC;IAED,sDAAsD;IACtD,kBAAkB,EAAE,CAAA;IAEpB,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC3D,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACtD,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAEtD,8CAA8C;IAC9C,MAAM,QAAQ,GAA2B;QACvC,QAAQ,EAAE,aAAa;QACvB,cAAc,EAAE,MAAM,CAAC,QAAQ;QAC/B,qBAAqB,EAAE,GAAG;KAC3B,CAAA;IAED,MAAM,GAAG,GAA2B;QAClC,GAAG,QAAQ;QACX,GAAI,OAAO,CAAC,GAA8B;QAC1C,4BAA4B;QAC5B,gBAAgB,EAAE,WAAW;QAC7B,WAAW,EAAE,MAAM;QACnB,cAAc,EAAE,MAAM;QACtB,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,iBAAiB,CAAC;QAC7D,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;KACnC,CAAA;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,EAAE,EAAE,EAAE;QACpC,GAAG;QACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAA;IAEF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAChD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAChD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChC,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAA;QACtC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,KAAK,CAAA;AACd,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,MAAsB,EACtB,SAAS,GAAG,KAAK;IAEjB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,MAAM,GAAG,GAAG,oBAAoB,MAAM,CAAC,QAAQ,GAAG,CAAA;IAElD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;YAC5B,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;gBACX,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACjB,OAAM;YACR,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;IAC9C,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;AACvD,CAAC"}
|
package/dist/log.d.ts
CHANGED
package/dist/log.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,GAAG;oBALG,OAAO,EAAE;sBAAT,OAAO,EAAE;qBAAT,OAAO,EAAE;oBAAT,OAAO,EAAE;kBAAT,OAAO,EAAE;
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,GAAG;oBALG,OAAO,EAAE;sBAAT,OAAO,EAAE;qBAAT,OAAO,EAAE;oBAAT,OAAO,EAAE;kBAAT,OAAO,EAAE;qBAAT,OAAO,EAAE;CAY3B,CAAA"}
|
package/dist/log.js
CHANGED
package/dist/log.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,SAAS,CAAA;AACvB,MAAM,IAAI,GAAG,SAAS,CAAA;AACtB,MAAM,GAAG,GAAG,SAAS,CAAA;AAErB,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,UAAU;CACR,CAAA;AAEV,SAAS,MAAM,CAAC,KAAa,EAAE,KAAa;IAC1C,OAAO,GAAG,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,CAAA;AAC5C,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,KAAa;IAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC9B,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAA;IAC1B,CAAC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC;IACrC,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC;IAC1C,KAAK,EAAE,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC;IAC9C,EAAE,EAAE,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,SAAS,CAAA;AACvB,MAAM,IAAI,GAAG,SAAS,CAAA;AACtB,MAAM,GAAG,GAAG,SAAS,CAAA;AAErB,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,UAAU;CACR,CAAA;AAEV,SAAS,MAAM,CAAC,KAAa,EAAE,KAAa;IAC1C,OAAO,GAAG,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,CAAA;AAC5C,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,KAAa;IAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC9B,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAA;IAC1B,CAAC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC;IACrC,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC;IAC1C,KAAK,EAAE,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC;IAC9C,EAAE,EAAE,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC;IACtC,KAAK,EAAE,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC;CAC7C,CAAA"}
|
package/dist/vite-plugin.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import type { Plugin } from 'vite';
|
|
|
3
3
|
export interface OrezPluginOptions extends Partial<ZeroLiteConfig> {
|
|
4
4
|
s3?: boolean;
|
|
5
5
|
s3Port?: number;
|
|
6
|
+
bunny?: boolean;
|
|
7
|
+
bunnyPort?: number;
|
|
6
8
|
}
|
|
7
9
|
export default function orez(options?: OrezPluginOptions): Plugin;
|
|
8
10
|
//# sourceMappingURL=vite-plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,cAAc,CAAC;IAChE,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAsChE"}
|
package/dist/vite-plugin.js
CHANGED
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
import { startZeroLite } from './index.js';
|
|
2
|
-
import { startS3Local } from './s3-local.js';
|
|
3
2
|
export default function orez(options) {
|
|
4
3
|
let stop = null;
|
|
5
4
|
let s3Server = null;
|
|
5
|
+
let bunnyServer = null;
|
|
6
6
|
return {
|
|
7
7
|
name: 'orez',
|
|
8
8
|
async configureServer(server) {
|
|
9
9
|
const result = await startZeroLite(options);
|
|
10
10
|
stop = result.stop;
|
|
11
11
|
if (options?.s3) {
|
|
12
|
+
const { startS3Local } = await import('./s3-local.js');
|
|
12
13
|
s3Server = await startS3Local({
|
|
13
14
|
port: options.s3Port || 9200,
|
|
14
15
|
dataDir: result.config.dataDir,
|
|
15
16
|
});
|
|
16
17
|
}
|
|
18
|
+
if (options?.bunny) {
|
|
19
|
+
const { startBunnyLocal } = await import('./bunny-local.js');
|
|
20
|
+
bunnyServer = await startBunnyLocal({
|
|
21
|
+
port: options.bunnyPort || 3533,
|
|
22
|
+
dataDir: result.config.dataDir,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
17
25
|
server.httpServer?.on('close', async () => {
|
|
26
|
+
bunnyServer?.close();
|
|
18
27
|
s3Server?.close();
|
|
19
28
|
if (stop) {
|
|
20
29
|
await stop();
|
package/dist/vite-plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin.js","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"vite-plugin.js","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAa1C,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAA2B;IACtD,IAAI,IAAI,GAAiC,IAAI,CAAA;IAC7C,IAAI,QAAQ,GAAkB,IAAI,CAAA;IAClC,IAAI,WAAW,GAAkB,IAAI,CAAA;IAErC,OAAO;QACL,IAAI,EAAE,MAAM;QAEZ,KAAK,CAAC,eAAe,CAAC,MAAM;YAC1B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAA;YAC3C,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;YAElB,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC;gBAChB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;gBACtD,QAAQ,GAAG,MAAM,YAAY,CAAC;oBAC5B,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;oBAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;iBAC/B,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;gBACnB,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;gBAC5D,WAAW,GAAG,MAAM,eAAe,CAAC;oBAClC,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;oBAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;iBAC/B,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBACxC,WAAW,EAAE,KAAK,EAAE,CAAA;gBACpB,QAAQ,EAAE,KAAK,EAAE,CAAA;gBACjB,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,IAAI,EAAE,CAAA;oBACZ,IAAI,GAAG,IAAI,CAAA;gBACb,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orez",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "PGlite-powered zero-sync development backend. No Docker required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
"types": "./dist/s3-local.d.ts",
|
|
16
16
|
"import": "./dist/s3-local.js"
|
|
17
17
|
},
|
|
18
|
+
"./bunny": {
|
|
19
|
+
"types": "./dist/bunny-local.d.ts",
|
|
20
|
+
"import": "./dist/bunny-local.js"
|
|
21
|
+
},
|
|
18
22
|
"./vite": {
|
|
19
23
|
"types": "./dist/vite-plugin.d.ts",
|
|
20
24
|
"import": "./dist/vite-plugin.js"
|
|
@@ -43,6 +47,7 @@
|
|
|
43
47
|
"dependencies": {
|
|
44
48
|
"@electric-sql/pglite": "^0.2.17",
|
|
45
49
|
"@rocicorp/zero": ">=0.1.0",
|
|
50
|
+
"bedrock-sqlite": "0.0.2",
|
|
46
51
|
"citty": "^0.2.0",
|
|
47
52
|
"pg-gateway": "^0.3.0-beta.4"
|
|
48
53
|
},
|
|
@@ -54,7 +59,7 @@
|
|
|
54
59
|
"optional": true
|
|
55
60
|
}
|
|
56
61
|
},
|
|
57
|
-
"devDependencies": {
|
|
62
|
+
"devDependencies": {
|
|
58
63
|
"oxlint": "latest",
|
|
59
64
|
"oxfmt": "latest",
|
|
60
65
|
"typescript": "^5.7.0",
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* minimal local bunny cdn storage-compatible server.
|
|
3
|
+
* handles GET/PUT/DELETE/HEAD and directory listing.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
existsSync,
|
|
8
|
+
mkdirSync,
|
|
9
|
+
readFileSync,
|
|
10
|
+
writeFileSync,
|
|
11
|
+
unlinkSync,
|
|
12
|
+
statSync,
|
|
13
|
+
readdirSync,
|
|
14
|
+
} from 'node:fs'
|
|
15
|
+
import {
|
|
16
|
+
createServer,
|
|
17
|
+
type Server,
|
|
18
|
+
type IncomingMessage,
|
|
19
|
+
type ServerResponse,
|
|
20
|
+
} from 'node:http'
|
|
21
|
+
import { join, dirname, extname, relative } from 'node:path'
|
|
22
|
+
|
|
23
|
+
import { log } from './log.js'
|
|
24
|
+
|
|
25
|
+
export interface BunnyLocalConfig {
|
|
26
|
+
port: number
|
|
27
|
+
dataDir: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const MIME_TYPES: Record<string, string> = {
|
|
31
|
+
'.jpg': 'image/jpeg',
|
|
32
|
+
'.jpeg': 'image/jpeg',
|
|
33
|
+
'.png': 'image/png',
|
|
34
|
+
'.gif': 'image/gif',
|
|
35
|
+
'.webp': 'image/webp',
|
|
36
|
+
'.svg': 'image/svg+xml',
|
|
37
|
+
'.json': 'application/json',
|
|
38
|
+
'.txt': 'text/plain',
|
|
39
|
+
'.pdf': 'application/pdf',
|
|
40
|
+
'.mp4': 'video/mp4',
|
|
41
|
+
'.mp3': 'audio/mpeg',
|
|
42
|
+
'.css': 'text/css',
|
|
43
|
+
'.js': 'application/javascript',
|
|
44
|
+
'.html': 'text/html',
|
|
45
|
+
'.woff': 'font/woff',
|
|
46
|
+
'.woff2': 'font/woff2',
|
|
47
|
+
'.ttf': 'font/ttf',
|
|
48
|
+
'.otf': 'font/otf',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function corsHeaders(): Record<string, string> {
|
|
52
|
+
return {
|
|
53
|
+
'Access-Control-Allow-Origin': '*',
|
|
54
|
+
'Access-Control-Allow-Methods': 'GET, PUT, DELETE, HEAD, OPTIONS',
|
|
55
|
+
'Access-Control-Allow-Headers': '*',
|
|
56
|
+
'Access-Control-Expose-Headers': 'Content-Length',
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// recursively collect files for directory listing
|
|
61
|
+
function listFiles(
|
|
62
|
+
dir: string,
|
|
63
|
+
baseDir: string
|
|
64
|
+
): Array<{
|
|
65
|
+
Guid: string
|
|
66
|
+
StorageZoneName: string
|
|
67
|
+
Path: string
|
|
68
|
+
ObjectName: string
|
|
69
|
+
Length: number
|
|
70
|
+
LastChanged: string
|
|
71
|
+
IsDirectory: boolean
|
|
72
|
+
DateCreated: string
|
|
73
|
+
}> {
|
|
74
|
+
if (!existsSync(dir) || !statSync(dir).isDirectory()) {
|
|
75
|
+
return []
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const entries = readdirSync(dir, { withFileTypes: true })
|
|
79
|
+
return entries.map((entry) => {
|
|
80
|
+
const fullPath = join(dir, entry.name)
|
|
81
|
+
const stat = statSync(fullPath)
|
|
82
|
+
const relativePath = '/' + relative(baseDir, dir) + '/'
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
Guid: '00000000-0000-0000-0000-000000000000',
|
|
86
|
+
StorageZoneName: '',
|
|
87
|
+
Path: relativePath,
|
|
88
|
+
ObjectName: entry.name,
|
|
89
|
+
Length: entry.isDirectory() ? 0 : stat.size,
|
|
90
|
+
LastChanged: stat.mtime.toISOString(),
|
|
91
|
+
IsDirectory: entry.isDirectory(),
|
|
92
|
+
DateCreated: stat.birthtime.toISOString(),
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function startBunnyLocal(config: BunnyLocalConfig): Promise<Server> {
|
|
98
|
+
const storageDir = join(config.dataDir, 'bunny')
|
|
99
|
+
mkdirSync(storageDir, { recursive: true })
|
|
100
|
+
|
|
101
|
+
const server = createServer((req: IncomingMessage, res: ServerResponse) => {
|
|
102
|
+
const headers = corsHeaders()
|
|
103
|
+
|
|
104
|
+
if (req.method === 'OPTIONS') {
|
|
105
|
+
res.writeHead(200, headers)
|
|
106
|
+
res.end()
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const url = new URL(req.url || '/', `http://localhost:${config.port}`)
|
|
111
|
+
|
|
112
|
+
// sanitize path to prevent traversal
|
|
113
|
+
const normalized = url.pathname
|
|
114
|
+
.split('/')
|
|
115
|
+
.filter((s) => s && s !== '..' && s !== '.')
|
|
116
|
+
.join('/')
|
|
117
|
+
const filePath = join(storageDir, normalized)
|
|
118
|
+
if (!filePath.startsWith(storageDir)) {
|
|
119
|
+
res.writeHead(403, headers)
|
|
120
|
+
res.end()
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
switch (req.method) {
|
|
126
|
+
case 'GET': {
|
|
127
|
+
// directory listing if path ends with / or is a directory
|
|
128
|
+
if (
|
|
129
|
+
url.pathname.endsWith('/') ||
|
|
130
|
+
(existsSync(filePath) && statSync(filePath).isDirectory())
|
|
131
|
+
) {
|
|
132
|
+
const items = listFiles(filePath, storageDir)
|
|
133
|
+
const body = JSON.stringify(items)
|
|
134
|
+
res.writeHead(200, {
|
|
135
|
+
...headers,
|
|
136
|
+
'Content-Type': 'application/json',
|
|
137
|
+
})
|
|
138
|
+
res.end(body)
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!existsSync(filePath)) {
|
|
143
|
+
res.writeHead(404, { ...headers, 'Content-Type': 'application/json' })
|
|
144
|
+
res.end(JSON.stringify({ HttpCode: 404, Message: 'Object Not Found' }))
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
const data = readFileSync(filePath)
|
|
148
|
+
const ext = extname(filePath)
|
|
149
|
+
const contentType = MIME_TYPES[ext] || 'application/octet-stream'
|
|
150
|
+
res.writeHead(200, {
|
|
151
|
+
...headers,
|
|
152
|
+
'Content-Type': contentType,
|
|
153
|
+
'Content-Length': data.length.toString(),
|
|
154
|
+
})
|
|
155
|
+
res.end(data)
|
|
156
|
+
break
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
case 'PUT': {
|
|
160
|
+
const chunks: Buffer[] = []
|
|
161
|
+
req.on('data', (chunk: Buffer) => chunks.push(chunk))
|
|
162
|
+
req.on('end', () => {
|
|
163
|
+
mkdirSync(dirname(filePath), { recursive: true })
|
|
164
|
+
const body = Buffer.concat(chunks)
|
|
165
|
+
writeFileSync(filePath, body)
|
|
166
|
+
res.writeHead(201, {
|
|
167
|
+
...headers,
|
|
168
|
+
'Content-Type': 'application/json',
|
|
169
|
+
})
|
|
170
|
+
res.end(JSON.stringify({ HttpCode: 201, Message: 'File uploaded.' }))
|
|
171
|
+
})
|
|
172
|
+
break
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
case 'DELETE': {
|
|
176
|
+
if (existsSync(filePath)) {
|
|
177
|
+
unlinkSync(filePath)
|
|
178
|
+
}
|
|
179
|
+
res.writeHead(200, {
|
|
180
|
+
...headers,
|
|
181
|
+
'Content-Type': 'application/json',
|
|
182
|
+
})
|
|
183
|
+
res.end(JSON.stringify({ HttpCode: 200, Message: 'File deleted successfuly.' }))
|
|
184
|
+
break
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
case 'HEAD': {
|
|
188
|
+
if (!existsSync(filePath) || statSync(filePath).isDirectory()) {
|
|
189
|
+
res.writeHead(404, headers)
|
|
190
|
+
res.end()
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
const stat = statSync(filePath)
|
|
194
|
+
const ext2 = extname(filePath)
|
|
195
|
+
res.writeHead(200, {
|
|
196
|
+
...headers,
|
|
197
|
+
'Content-Type': MIME_TYPES[ext2] || 'application/octet-stream',
|
|
198
|
+
'Content-Length': stat.size.toString(),
|
|
199
|
+
})
|
|
200
|
+
res.end()
|
|
201
|
+
break
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
default:
|
|
205
|
+
res.writeHead(405, headers)
|
|
206
|
+
res.end()
|
|
207
|
+
}
|
|
208
|
+
} catch {
|
|
209
|
+
res.writeHead(500, {
|
|
210
|
+
...headers,
|
|
211
|
+
'Content-Type': 'application/json',
|
|
212
|
+
})
|
|
213
|
+
res.end(JSON.stringify({ HttpCode: 500, Message: 'Internal Server Error' }))
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
return new Promise((resolve, reject) => {
|
|
218
|
+
server.listen(config.port, '127.0.0.1', () => {
|
|
219
|
+
log.bunny(`listening on port ${config.port}`)
|
|
220
|
+
resolve(server)
|
|
221
|
+
})
|
|
222
|
+
server.on('error', reject)
|
|
223
|
+
})
|
|
224
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { defineCommand, runMain } from 'citty'
|
|
|
3
3
|
|
|
4
4
|
import { startZeroLite } from './index.js'
|
|
5
5
|
import { log } from './log.js'
|
|
6
|
-
import { startS3Local } from './s3-local.js'
|
|
7
6
|
|
|
8
7
|
const s3Command = defineCommand({
|
|
9
8
|
meta: {
|
|
@@ -23,6 +22,7 @@ const s3Command = defineCommand({
|
|
|
23
22
|
},
|
|
24
23
|
},
|
|
25
24
|
async run({ args }) {
|
|
25
|
+
const { startS3Local } = await import('./s3-local.js')
|
|
26
26
|
const server = await startS3Local({
|
|
27
27
|
port: Number(args.port),
|
|
28
28
|
dataDir: args['data-dir'],
|
|
@@ -39,6 +39,41 @@ const s3Command = defineCommand({
|
|
|
39
39
|
},
|
|
40
40
|
})
|
|
41
41
|
|
|
42
|
+
const bunnyCommand = defineCommand({
|
|
43
|
+
meta: {
|
|
44
|
+
name: 'bunny',
|
|
45
|
+
description: 'start a local bunny cdn storage-compatible server',
|
|
46
|
+
},
|
|
47
|
+
args: {
|
|
48
|
+
port: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
description: 'port to listen on',
|
|
51
|
+
default: '3533',
|
|
52
|
+
},
|
|
53
|
+
'data-dir': {
|
|
54
|
+
type: 'string',
|
|
55
|
+
description: 'data directory for stored files',
|
|
56
|
+
default: '.orez',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
async run({ args }) {
|
|
60
|
+
const { startBunnyLocal } = await import('./bunny-local.js')
|
|
61
|
+
const server = await startBunnyLocal({
|
|
62
|
+
port: Number(args.port),
|
|
63
|
+
dataDir: args['data-dir'],
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
process.on('SIGINT', () => {
|
|
67
|
+
server.close()
|
|
68
|
+
process.exit(0)
|
|
69
|
+
})
|
|
70
|
+
process.on('SIGTERM', () => {
|
|
71
|
+
server.close()
|
|
72
|
+
process.exit(0)
|
|
73
|
+
})
|
|
74
|
+
},
|
|
75
|
+
})
|
|
76
|
+
|
|
42
77
|
const main = defineCommand({
|
|
43
78
|
meta: {
|
|
44
79
|
name: 'orez',
|
|
@@ -100,9 +135,20 @@ const main = defineCommand({
|
|
|
100
135
|
description: 's3 server port',
|
|
101
136
|
default: '9200',
|
|
102
137
|
},
|
|
138
|
+
bunny: {
|
|
139
|
+
type: 'boolean',
|
|
140
|
+
description: 'also start a local bunny cdn storage-compatible server',
|
|
141
|
+
default: false,
|
|
142
|
+
},
|
|
143
|
+
'bunny-port': {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'bunny storage server port',
|
|
146
|
+
default: '3533',
|
|
147
|
+
},
|
|
103
148
|
},
|
|
104
149
|
subCommands: {
|
|
105
150
|
s3: s3Command,
|
|
151
|
+
bunny: bunnyCommand,
|
|
106
152
|
},
|
|
107
153
|
async run({ args }) {
|
|
108
154
|
const { config, stop } = await startZeroLite({
|
|
@@ -119,12 +165,22 @@ const main = defineCommand({
|
|
|
119
165
|
|
|
120
166
|
let s3Server: import('node:http').Server | null = null
|
|
121
167
|
if (args.s3) {
|
|
168
|
+
const { startS3Local } = await import('./s3-local.js')
|
|
122
169
|
s3Server = await startS3Local({
|
|
123
170
|
port: Number(args['s3-port']),
|
|
124
171
|
dataDir: args['data-dir'],
|
|
125
172
|
})
|
|
126
173
|
}
|
|
127
174
|
|
|
175
|
+
let bunnyServer: import('node:http').Server | null = null
|
|
176
|
+
if (args.bunny) {
|
|
177
|
+
const { startBunnyLocal } = await import('./bunny-local.js')
|
|
178
|
+
bunnyServer = await startBunnyLocal({
|
|
179
|
+
port: Number(args['bunny-port']),
|
|
180
|
+
dataDir: args['data-dir'],
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
|
|
128
184
|
log.orez('ready')
|
|
129
185
|
log.orez(
|
|
130
186
|
`pg: postgresql://${config.pgUser}:${config.pgPassword}@127.0.0.1:${config.pgPort}/postgres`
|
|
@@ -134,11 +190,13 @@ const main = defineCommand({
|
|
|
134
190
|
}
|
|
135
191
|
|
|
136
192
|
process.on('SIGINT', async () => {
|
|
193
|
+
bunnyServer?.close()
|
|
137
194
|
s3Server?.close()
|
|
138
195
|
await stop()
|
|
139
196
|
process.exit(0)
|
|
140
197
|
})
|
|
141
198
|
process.on('SIGTERM', async () => {
|
|
199
|
+
bunnyServer?.close()
|
|
142
200
|
s3Server?.close()
|
|
143
201
|
await stop()
|
|
144
202
|
process.exit(0)
|
package/src/index.ts
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { spawn, type ChildProcess } from 'node:child_process'
|
|
10
|
-
import { existsSync, readFileSync,
|
|
11
|
-
import { resolve
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
|
|
11
|
+
import { resolve } from 'node:path'
|
|
12
12
|
|
|
13
13
|
import { getConfig, getConnectionString } from './config.js'
|
|
14
14
|
import { log } from './log.js'
|
|
@@ -19,10 +19,9 @@ import { installChangeTracking } from './replication/change-tracker.js'
|
|
|
19
19
|
|
|
20
20
|
import type { ZeroLiteConfig } from './config.js'
|
|
21
21
|
import type { PGlite } from '@electric-sql/pglite'
|
|
22
|
-
import type { Server } from 'node:net'
|
|
23
22
|
|
|
24
|
-
export type { ZeroLiteConfig, LogLevel } from './config.js'
|
|
25
23
|
export { getConfig, getConnectionString } from './config.js'
|
|
24
|
+
export type { LogLevel, ZeroLiteConfig } from './config.js'
|
|
26
25
|
|
|
27
26
|
export async function startZeroLite(overrides: Partial<ZeroLiteConfig> = {}) {
|
|
28
27
|
const config = getConfig(overrides)
|
|
@@ -152,6 +151,28 @@ async function seedIfNeeded(db: PGlite, config: ZeroLiteConfig): Promise<void> {
|
|
|
152
151
|
log.orez('seeded demo data')
|
|
153
152
|
}
|
|
154
153
|
|
|
154
|
+
function patchSqliteForWasm(): void {
|
|
155
|
+
// replace @rocicorp/zero-sqlite3 with bedrock-sqlite (wasm) shim
|
|
156
|
+
// so zero-cache uses wasm instead of native bindings
|
|
157
|
+
try {
|
|
158
|
+
const sqlitePkg = import.meta.resolve('@rocicorp/zero-sqlite3').replace('file://', '')
|
|
159
|
+
const indexPath = resolve(sqlitePkg, '..', 'index.js')
|
|
160
|
+
if (!existsSync(indexPath)) return
|
|
161
|
+
|
|
162
|
+
const current = readFileSync(indexPath, 'utf-8')
|
|
163
|
+
if (current.includes('bedrock-sqlite')) return // already patched
|
|
164
|
+
|
|
165
|
+
const shimPath = resolve(import.meta.dirname, 'sqlite-shim.cjs')
|
|
166
|
+
if (!existsSync(shimPath)) return
|
|
167
|
+
|
|
168
|
+
const shim = `'use strict';\nmodule.exports = require('${shimPath}');\n`
|
|
169
|
+
writeFileSync(indexPath, shim)
|
|
170
|
+
log.orez('patched @rocicorp/zero-sqlite3 -> bedrock-sqlite (wasm)')
|
|
171
|
+
} catch (e) {
|
|
172
|
+
log.orez(`sqlite wasm patch skipped: ${e}`)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
155
176
|
async function startZeroCache(config: ZeroLiteConfig): Promise<ChildProcess> {
|
|
156
177
|
// resolve @rocicorp/zero entry, cli.js is right next to it
|
|
157
178
|
let zeroCacheBin = ''
|
|
@@ -167,6 +188,9 @@ async function startZeroCache(config: ZeroLiteConfig): Promise<ChildProcess> {
|
|
|
167
188
|
throw new Error('zero-cache binary not found. install @rocicorp/zero')
|
|
168
189
|
}
|
|
169
190
|
|
|
191
|
+
// patch sqlite to use wasm before spawning zero-cache
|
|
192
|
+
patchSqliteForWasm()
|
|
193
|
+
|
|
170
194
|
const upstreamUrl = getConnectionString(config, 'postgres')
|
|
171
195
|
const cvrUrl = getConnectionString(config, 'zero_cvr')
|
|
172
196
|
const cdbUrl = getConnectionString(config, 'zero_cdb')
|
package/src/log.ts
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// shim that makes bedrock-sqlite (wasm) compatible with @rocicorp/zero-sqlite3 (native)
|
|
2
|
+
// patches missing methods that zero-cache expects
|
|
3
|
+
'use strict'
|
|
4
|
+
|
|
5
|
+
const mod = require('bedrock-sqlite')
|
|
6
|
+
const Database = mod.Database
|
|
7
|
+
const SqliteError = mod.SqliteError
|
|
8
|
+
|
|
9
|
+
// patch Database.prototype with methods zero-cache uses but bedrock-sqlite doesn't have
|
|
10
|
+
if (!Database.prototype.unsafeMode) {
|
|
11
|
+
Database.prototype.unsafeMode = function () {
|
|
12
|
+
return this
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (!Database.prototype.defaultSafeIntegers) {
|
|
16
|
+
Database.prototype.defaultSafeIntegers = function () {
|
|
17
|
+
return this
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (!Database.prototype.serialize) {
|
|
21
|
+
Database.prototype.serialize = function () {
|
|
22
|
+
throw new Error('serialize() not supported in wasm build')
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (!Database.prototype.backup) {
|
|
26
|
+
Database.prototype.backup = function () {
|
|
27
|
+
throw new Error('backup() not supported in wasm build')
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// patch Statement prototype - find it from a temp db instance
|
|
32
|
+
const tmpDb = new Database(':memory:')
|
|
33
|
+
const tmpStmt = tmpDb.prepare('SELECT 1')
|
|
34
|
+
const StmtProto = Object.getPrototypeOf(tmpStmt)
|
|
35
|
+
|
|
36
|
+
if (!StmtProto.safeIntegers) {
|
|
37
|
+
StmtProto.safeIntegers = function () {
|
|
38
|
+
return this
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (!StmtProto.scanStatusV2) {
|
|
42
|
+
// returns empty stats - zero-cache uses this for query performance tracking
|
|
43
|
+
StmtProto.scanStatusV2 = function () {
|
|
44
|
+
return []
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!StmtProto.scanStatusReset) {
|
|
48
|
+
StmtProto.scanStatusReset = function () {}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
tmpDb.close()
|
|
52
|
+
|
|
53
|
+
// scanstat constants (zero-cache references these as static properties)
|
|
54
|
+
Database.SQLITE_SCANSTAT_NLOOP = 0
|
|
55
|
+
Database.SQLITE_SCANSTAT_NVISIT = 1
|
|
56
|
+
Database.SQLITE_SCANSTAT_EST = 2
|
|
57
|
+
Database.SQLITE_SCANSTAT_NAME = 3
|
|
58
|
+
Database.SQLITE_SCANSTAT_EXPLAIN = 4
|
|
59
|
+
Database.SQLITE_SCANSTAT_SELECTID = 5
|
|
60
|
+
Database.SQLITE_SCANSTAT_PARENTID = 6
|
|
61
|
+
Database.SQLITE_SCANSTAT_NCYCLE = 7
|
|
62
|
+
Database.SQLITE_SCANSTAT_COMPLEX = 8
|
|
63
|
+
|
|
64
|
+
// export in the same shape as @rocicorp/zero-sqlite3:
|
|
65
|
+
// default export is the Database constructor, SqliteError is a named export
|
|
66
|
+
module.exports = Database
|
|
67
|
+
module.exports.SqliteError = SqliteError
|
package/src/vite-plugin.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { startZeroLite } from './index.js'
|
|
2
|
-
import { startS3Local } from './s3-local.js'
|
|
3
2
|
|
|
4
3
|
import type { ZeroLiteConfig } from './config.js'
|
|
5
4
|
import type { Server } from 'node:http'
|
|
@@ -8,11 +7,14 @@ import type { Plugin } from 'vite'
|
|
|
8
7
|
export interface OrezPluginOptions extends Partial<ZeroLiteConfig> {
|
|
9
8
|
s3?: boolean
|
|
10
9
|
s3Port?: number
|
|
10
|
+
bunny?: boolean
|
|
11
|
+
bunnyPort?: number
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export default function orez(options?: OrezPluginOptions): Plugin {
|
|
14
15
|
let stop: (() => Promise<void>) | null = null
|
|
15
16
|
let s3Server: Server | null = null
|
|
17
|
+
let bunnyServer: Server | null = null
|
|
16
18
|
|
|
17
19
|
return {
|
|
18
20
|
name: 'orez',
|
|
@@ -22,13 +24,23 @@ export default function orez(options?: OrezPluginOptions): Plugin {
|
|
|
22
24
|
stop = result.stop
|
|
23
25
|
|
|
24
26
|
if (options?.s3) {
|
|
27
|
+
const { startS3Local } = await import('./s3-local.js')
|
|
25
28
|
s3Server = await startS3Local({
|
|
26
29
|
port: options.s3Port || 9200,
|
|
27
30
|
dataDir: result.config.dataDir,
|
|
28
31
|
})
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
if (options?.bunny) {
|
|
35
|
+
const { startBunnyLocal } = await import('./bunny-local.js')
|
|
36
|
+
bunnyServer = await startBunnyLocal({
|
|
37
|
+
port: options.bunnyPort || 3533,
|
|
38
|
+
dataDir: result.config.dataDir,
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
server.httpServer?.on('close', async () => {
|
|
43
|
+
bunnyServer?.close()
|
|
32
44
|
s3Server?.close()
|
|
33
45
|
if (stop) {
|
|
34
46
|
await stop()
|