localflare-core 0.0.1 → 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/README.md +76 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +56 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# localflare-core
|
|
2
|
+
|
|
3
|
+
Core Miniflare wrapper and configuration parser for [LocalFlare](https://www.npmjs.com/package/localflare).
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/localflare-core)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
This package provides the core functionality for LocalFlare:
|
|
11
|
+
|
|
12
|
+
- **Miniflare Integration** - Wraps Miniflare to provide a consistent API for running Cloudflare Workers locally
|
|
13
|
+
- **Config Parser** - Reads and parses `wrangler.toml` configuration files
|
|
14
|
+
- **Bindings Support** - Full support for D1, KV, R2, Durable Objects, Queues, and more
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install localflare-core
|
|
20
|
+
# or
|
|
21
|
+
pnpm add localflare-core
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { LocalFlareCore } from 'localflare-core';
|
|
28
|
+
|
|
29
|
+
const core = new LocalFlareCore({
|
|
30
|
+
configPath: './wrangler.toml',
|
|
31
|
+
port: 8787,
|
|
32
|
+
persist: '.localflare'
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Start the worker
|
|
36
|
+
await core.start();
|
|
37
|
+
|
|
38
|
+
// Access bindings programmatically
|
|
39
|
+
const bindings = core.getBindings();
|
|
40
|
+
|
|
41
|
+
// Get D1 databases
|
|
42
|
+
const d1Databases = bindings.d1;
|
|
43
|
+
|
|
44
|
+
// Get KV namespaces
|
|
45
|
+
const kvNamespaces = bindings.kv;
|
|
46
|
+
|
|
47
|
+
// Stop when done
|
|
48
|
+
await core.stop();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Supported Bindings
|
|
52
|
+
|
|
53
|
+
| Binding | Support |
|
|
54
|
+
|---------|---------|
|
|
55
|
+
| D1 | ✅ Full |
|
|
56
|
+
| KV | ✅ Full |
|
|
57
|
+
| R2 | ✅ Full |
|
|
58
|
+
| Durable Objects | ✅ Full |
|
|
59
|
+
| Queues | ✅ Full |
|
|
60
|
+
| Service Bindings | ✅ Full |
|
|
61
|
+
| Cache API | ✅ Full |
|
|
62
|
+
| Hyperdrive | ✅ Full |
|
|
63
|
+
| Vectorize | ⚠️ Limited |
|
|
64
|
+
| Workers AI | ⚠️ Mock |
|
|
65
|
+
|
|
66
|
+
## Related Packages
|
|
67
|
+
|
|
68
|
+
| Package | Description |
|
|
69
|
+
|---------|-------------|
|
|
70
|
+
| [`localflare`](https://www.npmjs.com/package/localflare) | CLI tool (main package) |
|
|
71
|
+
| [`localflare-server`](https://www.npmjs.com/package/localflare-server) | Dashboard API server |
|
|
72
|
+
| [`localflare-dashboard`](https://www.npmjs.com/package/localflare-dashboard) | React dashboard UI |
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -62,12 +62,18 @@ interface DiscoveredBindings {
|
|
|
62
62
|
};
|
|
63
63
|
vars: Record<string, string>;
|
|
64
64
|
}
|
|
65
|
+
interface WorkerLogEntry {
|
|
66
|
+
level: 'log' | 'info' | 'warn' | 'error' | 'debug';
|
|
67
|
+
message: string;
|
|
68
|
+
}
|
|
69
|
+
type WorkerLogCallback = (entry: WorkerLogEntry) => void;
|
|
65
70
|
interface LocalFlareOptions {
|
|
66
71
|
configPath?: string;
|
|
67
72
|
port?: number;
|
|
68
73
|
dashboardPort?: number;
|
|
69
74
|
persistPath?: string;
|
|
70
75
|
verbose?: boolean;
|
|
76
|
+
onWorkerLog?: WorkerLogCallback;
|
|
71
77
|
}
|
|
72
78
|
interface BindingInfo {
|
|
73
79
|
type: 'D1' | 'KV' | 'R2' | 'DO' | 'Queue' | 'Var';
|
|
@@ -94,6 +100,7 @@ declare class LocalFlare {
|
|
|
94
100
|
getOptions(): Required<LocalFlareOptions>;
|
|
95
101
|
getMiniflare(): Miniflare | null;
|
|
96
102
|
isRunning(): boolean;
|
|
103
|
+
setLogCallback(callback: WorkerLogCallback): void;
|
|
97
104
|
private ensureRunning;
|
|
98
105
|
}
|
|
99
106
|
|
|
@@ -101,4 +108,4 @@ declare function parseWranglerConfig(configPath: string): WranglerConfig;
|
|
|
101
108
|
declare function discoverBindings(config: WranglerConfig): DiscoveredBindings;
|
|
102
109
|
declare function getBindingSummary(bindings: DiscoveredBindings): string[];
|
|
103
110
|
|
|
104
|
-
export { type BindingInfo, type D1DatabaseConfig, type DiscoveredBindings, type DurableObjectBinding, type KVNamespaceConfig, LocalFlare, type LocalFlareOptions, type QueueConsumerConfig, type QueueProducerConfig, type R2BucketConfig, type WranglerConfig, discoverBindings, getBindingSummary, parseWranglerConfig };
|
|
111
|
+
export { type BindingInfo, type D1DatabaseConfig, type DiscoveredBindings, type DurableObjectBinding, type KVNamespaceConfig, LocalFlare, type LocalFlareOptions, type QueueConsumerConfig, type QueueProducerConfig, type R2BucketConfig, type WorkerLogCallback, type WorkerLogEntry, type WranglerConfig, discoverBindings, getBindingSummary, parseWranglerConfig };
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Miniflare } from "miniflare";
|
|
3
3
|
import { resolve as resolve2, dirname } from "path";
|
|
4
4
|
import * as esbuild from "esbuild";
|
|
5
|
+
import * as readline from "readline";
|
|
5
6
|
|
|
6
7
|
// src/config.ts
|
|
7
8
|
import { readFileSync, existsSync } from "fs";
|
|
@@ -45,6 +46,9 @@ function getBindingSummary(bindings) {
|
|
|
45
46
|
if (bindings.queues.producers.length > 0) {
|
|
46
47
|
summary.push(`Queue Producers: ${bindings.queues.producers.map((q) => q.binding).join(", ")}`);
|
|
47
48
|
}
|
|
49
|
+
if (bindings.queues.consumers.length > 0) {
|
|
50
|
+
summary.push(`Queue Consumers: ${bindings.queues.consumers.map((q) => q.queue).join(", ")}`);
|
|
51
|
+
}
|
|
48
52
|
if (Object.keys(bindings.vars).length > 0) {
|
|
49
53
|
summary.push(`Environment Variables: ${Object.keys(bindings.vars).join(", ")}`);
|
|
50
54
|
}
|
|
@@ -63,7 +67,9 @@ var LocalFlare = class {
|
|
|
63
67
|
port: options.port ?? 8787,
|
|
64
68
|
dashboardPort: options.dashboardPort ?? 8788,
|
|
65
69
|
persistPath: options.persistPath ?? ".localflare",
|
|
66
|
-
verbose: options.verbose ?? false
|
|
70
|
+
verbose: options.verbose ?? false,
|
|
71
|
+
onWorkerLog: options.onWorkerLog ?? (() => {
|
|
72
|
+
})
|
|
67
73
|
};
|
|
68
74
|
}
|
|
69
75
|
async start() {
|
|
@@ -88,7 +94,8 @@ var LocalFlare = class {
|
|
|
88
94
|
write: false,
|
|
89
95
|
minify: false,
|
|
90
96
|
sourcemap: false,
|
|
91
|
-
conditions: ["workerd", "worker", "browser"]
|
|
97
|
+
conditions: ["workerd", "worker", "browser"],
|
|
98
|
+
external: ["cloudflare:*", "node:*"]
|
|
92
99
|
});
|
|
93
100
|
const scriptContent = buildResult.outputFiles?.[0]?.text;
|
|
94
101
|
if (!scriptContent) {
|
|
@@ -106,9 +113,44 @@ var LocalFlare = class {
|
|
|
106
113
|
const queueProducers = Object.fromEntries(
|
|
107
114
|
this.bindings.queues.producers.map((q) => [q.binding, q.queue])
|
|
108
115
|
);
|
|
116
|
+
const queueConsumers = Object.fromEntries(
|
|
117
|
+
this.bindings.queues.consumers.map((c) => [
|
|
118
|
+
c.queue,
|
|
119
|
+
{
|
|
120
|
+
maxBatchSize: c.max_batch_size ?? 10,
|
|
121
|
+
maxBatchTimeout: c.max_batch_timeout ?? 5,
|
|
122
|
+
maxRetries: c.max_retries ?? 3,
|
|
123
|
+
deadLetterQueue: c.dead_letter_queue
|
|
124
|
+
}
|
|
125
|
+
])
|
|
126
|
+
);
|
|
109
127
|
const durableObjects = Object.fromEntries(
|
|
110
128
|
this.bindings.durableObjects.map((d) => [d.name, d.class_name])
|
|
111
129
|
);
|
|
130
|
+
const handleRuntimeStdio = (stdout, stderr) => {
|
|
131
|
+
if (this.options.verbose) {
|
|
132
|
+
console.log("[LocalFlare] Runtime stdio handler connected");
|
|
133
|
+
}
|
|
134
|
+
const processStream = (stream, level) => {
|
|
135
|
+
const rl = readline.createInterface({ input: stream });
|
|
136
|
+
rl.on("line", (line) => {
|
|
137
|
+
if (!line.trim()) return;
|
|
138
|
+
let logLevel = level === "error" ? "error" : "log";
|
|
139
|
+
if (line.includes("[warn]") || line.includes("WARNING")) {
|
|
140
|
+
logLevel = "warn";
|
|
141
|
+
} else if (line.includes("[info]") || line.includes("INFO")) {
|
|
142
|
+
logLevel = "info";
|
|
143
|
+
} else if (line.includes("[debug]") || line.includes("DEBUG")) {
|
|
144
|
+
logLevel = "debug";
|
|
145
|
+
} else if (line.includes("[error]") || line.includes("ERROR")) {
|
|
146
|
+
logLevel = "error";
|
|
147
|
+
}
|
|
148
|
+
this.options.onWorkerLog({ level: logLevel, message: line });
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
processStream(stdout, "log");
|
|
152
|
+
processStream(stderr, "error");
|
|
153
|
+
};
|
|
112
154
|
const miniflareOptions = {
|
|
113
155
|
modules: [
|
|
114
156
|
{
|
|
@@ -125,7 +167,11 @@ var LocalFlare = class {
|
|
|
125
167
|
durableObjectsPersist: `${persistRoot}/do`,
|
|
126
168
|
cachePersist: `${persistRoot}/cache`,
|
|
127
169
|
// Explicit binding configurations
|
|
128
|
-
bindings: this.bindings.vars
|
|
170
|
+
bindings: this.bindings.vars,
|
|
171
|
+
// Capture worker stdout/stderr for logging
|
|
172
|
+
handleRuntimeStdio,
|
|
173
|
+
// Use plain text logs instead of structured JSON for easier parsing
|
|
174
|
+
structuredWorkerdLogs: false
|
|
129
175
|
};
|
|
130
176
|
if (Object.keys(d1Databases).length > 0) {
|
|
131
177
|
miniflareOptions.d1Databases = d1Databases;
|
|
@@ -139,6 +185,9 @@ var LocalFlare = class {
|
|
|
139
185
|
if (Object.keys(queueProducers).length > 0) {
|
|
140
186
|
miniflareOptions.queueProducers = queueProducers;
|
|
141
187
|
}
|
|
188
|
+
if (Object.keys(queueConsumers).length > 0) {
|
|
189
|
+
miniflareOptions.queueConsumers = queueConsumers;
|
|
190
|
+
}
|
|
142
191
|
if (Object.keys(durableObjects).length > 0) {
|
|
143
192
|
miniflareOptions.durableObjects = durableObjects;
|
|
144
193
|
}
|
|
@@ -199,6 +248,10 @@ var LocalFlare = class {
|
|
|
199
248
|
isRunning() {
|
|
200
249
|
return this.mf !== null;
|
|
201
250
|
}
|
|
251
|
+
// Set the worker log callback (must be called before start())
|
|
252
|
+
setLogCallback(callback) {
|
|
253
|
+
this.options.onWorkerLog = callback;
|
|
254
|
+
}
|
|
202
255
|
ensureRunning() {
|
|
203
256
|
if (!this.mf) {
|
|
204
257
|
throw new Error("LocalFlare is not running. Call start() first.");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/localflare.ts","../src/config.ts"],"sourcesContent":["import { Miniflare } from 'miniflare'\nimport { resolve, dirname } from 'node:path'\nimport * as esbuild from 'esbuild'\nimport { parseWranglerConfig, discoverBindings, getBindingSummary } from './config.js'\nimport type { LocalFlareOptions, DiscoveredBindings, WranglerConfig } from './types.js'\n\nexport class LocalFlare {\n private mf: Miniflare | null = null\n private config: WranglerConfig | null = null\n private bindings: DiscoveredBindings | null = null\n private options: Required<LocalFlareOptions>\n\n constructor(options: LocalFlareOptions = {}) {\n this.options = {\n configPath: options.configPath ?? './wrangler.toml',\n port: options.port ?? 8787,\n dashboardPort: options.dashboardPort ?? 8788,\n persistPath: options.persistPath ?? '.localflare',\n verbose: options.verbose ?? false,\n }\n }\n\n async start(): Promise<void> {\n const configPath = resolve(this.options.configPath)\n const rootDir = dirname(configPath)\n\n // Parse wrangler.toml\n this.config = parseWranglerConfig(configPath)\n this.bindings = discoverBindings(this.config)\n\n // Log discovered bindings\n if (this.options.verbose) {\n console.log('\\n📦 Discovered bindings:')\n getBindingSummary(this.bindings).forEach(line => {\n console.log(` ${line}`)\n })\n console.log('')\n }\n\n // Build Miniflare options\n const persistRoot = resolve(rootDir, this.options.persistPath)\n\n // Compile the worker entry point with esbuild\n const entryPoint = resolve(rootDir, this.config.main || 'src/index.ts')\n const buildResult = await esbuild.build({\n entryPoints: [entryPoint],\n bundle: true,\n format: 'esm',\n target: 'es2022',\n write: false,\n minify: false,\n sourcemap: false,\n conditions: ['workerd', 'worker', 'browser'],\n })\n\n const scriptContent = buildResult.outputFiles?.[0]?.text\n if (!scriptContent) {\n throw new Error('Failed to compile worker script')\n }\n\n // Build explicit binding configurations from parsed config\n // Miniflare v3 expects bindings as objects keyed by binding name\n const d1Databases = Object.fromEntries(\n this.bindings.d1.map(d => [d.binding, d.database_id])\n )\n\n const kvNamespaces = Object.fromEntries(\n this.bindings.kv.map(k => [k.binding, k.id])\n )\n\n const r2Buckets = Object.fromEntries(\n this.bindings.r2.map(r => [r.binding, r.bucket_name])\n )\n\n const queueProducers = Object.fromEntries(\n this.bindings.queues.producers.map(q => [q.binding, q.queue])\n )\n\n const durableObjects = Object.fromEntries(\n this.bindings.durableObjects.map(d => [d.name, d.class_name])\n )\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const miniflareOptions: any = {\n modules: [\n {\n type: 'ESModule',\n path: entryPoint,\n contents: scriptContent,\n },\n ],\n port: this.options.port,\n verbose: this.options.verbose,\n kvPersist: `${persistRoot}/kv`,\n d1Persist: `${persistRoot}/d1`,\n r2Persist: `${persistRoot}/r2`,\n durableObjectsPersist: `${persistRoot}/do`,\n cachePersist: `${persistRoot}/cache`,\n // Explicit binding configurations\n bindings: this.bindings.vars,\n }\n\n // Only add bindings if they exist\n if (Object.keys(d1Databases).length > 0) {\n miniflareOptions.d1Databases = d1Databases\n }\n if (Object.keys(kvNamespaces).length > 0) {\n miniflareOptions.kvNamespaces = kvNamespaces\n }\n if (Object.keys(r2Buckets).length > 0) {\n miniflareOptions.r2Buckets = r2Buckets\n }\n if (Object.keys(queueProducers).length > 0) {\n miniflareOptions.queueProducers = queueProducers\n }\n if (Object.keys(durableObjects).length > 0) {\n miniflareOptions.durableObjects = durableObjects\n }\n\n this.mf = new Miniflare(miniflareOptions)\n\n // Wait for Miniflare to be ready\n const url = await this.mf.ready\n console.log(`⚡ Worker running at ${url}`)\n }\n\n async stop(): Promise<void> {\n if (this.mf) {\n await this.mf.dispose()\n this.mf = null\n }\n }\n\n // Binding accessors - use generic types for portability\n // Consumers can cast to @cloudflare/workers-types if needed\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getD1Database(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getD1Database(bindingName)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getKVNamespace(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getKVNamespace(bindingName)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getR2Bucket(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getR2Bucket(bindingName)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getDurableObjectNamespace(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getDurableObjectNamespace(bindingName)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getQueueProducer<T = unknown>(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getQueueProducer<T>(bindingName)\n }\n\n async getAllBindings<T = Record<string, unknown>>(): Promise<T> {\n this.ensureRunning()\n return this.mf!.getBindings() as Promise<T>\n }\n\n // Getters\n getDiscoveredBindings(): DiscoveredBindings | null {\n return this.bindings\n }\n\n getConfig(): WranglerConfig | null {\n return this.config\n }\n\n getOptions(): Required<LocalFlareOptions> {\n return this.options\n }\n\n getMiniflare(): Miniflare | null {\n return this.mf\n }\n\n isRunning(): boolean {\n return this.mf !== null\n }\n\n private ensureRunning(): void {\n if (!this.mf) {\n throw new Error('LocalFlare is not running. Call start() first.')\n }\n }\n}\n","import { readFileSync, existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { parse as parseToml } from 'toml'\nimport type { WranglerConfig, DiscoveredBindings } from './types.js'\n\nexport function parseWranglerConfig(configPath: string): WranglerConfig {\n const fullPath = resolve(configPath)\n\n if (!existsSync(fullPath)) {\n throw new Error(`Wrangler config not found at: ${fullPath}`)\n }\n\n const content = readFileSync(fullPath, 'utf-8')\n return parseToml(content) as WranglerConfig\n}\n\nexport function discoverBindings(config: WranglerConfig): DiscoveredBindings {\n return {\n d1: config.d1_databases ?? [],\n kv: config.kv_namespaces ?? [],\n r2: config.r2_buckets ?? [],\n durableObjects: config.durable_objects?.bindings ?? [],\n queues: {\n producers: config.queues?.producers ?? [],\n consumers: config.queues?.consumers ?? [],\n },\n vars: config.vars ?? {},\n }\n}\n\nexport function getBindingSummary(bindings: DiscoveredBindings): string[] {\n const summary: string[] = []\n\n if (bindings.d1.length > 0) {\n summary.push(`D1 Databases: ${bindings.d1.map(d => d.binding).join(', ')}`)\n }\n if (bindings.kv.length > 0) {\n summary.push(`KV Namespaces: ${bindings.kv.map(k => k.binding).join(', ')}`)\n }\n if (bindings.r2.length > 0) {\n summary.push(`R2 Buckets: ${bindings.r2.map(r => r.binding).join(', ')}`)\n }\n if (bindings.durableObjects.length > 0) {\n summary.push(`Durable Objects: ${bindings.durableObjects.map(d => d.name).join(', ')}`)\n }\n if (bindings.queues.producers.length > 0) {\n summary.push(`Queue Producers: ${bindings.queues.producers.map(q => q.binding).join(', ')}`)\n }\n if (Object.keys(bindings.vars).length > 0) {\n summary.push(`Environment Variables: ${Object.keys(bindings.vars).join(', ')}`)\n }\n\n return summary\n}\n"],"mappings":"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","names":["resolve","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/localflare.ts","../src/config.ts"],"sourcesContent":["import { Miniflare } from 'miniflare'\nimport { resolve, dirname } from 'node:path'\nimport * as esbuild from 'esbuild'\nimport { Readable } from 'node:stream'\nimport * as readline from 'node:readline'\nimport { parseWranglerConfig, discoverBindings, getBindingSummary } from './config.js'\nimport type { LocalFlareOptions, DiscoveredBindings, WranglerConfig, WorkerLogCallback } from './types.js'\n\nexport class LocalFlare {\n private mf: Miniflare | null = null\n private config: WranglerConfig | null = null\n private bindings: DiscoveredBindings | null = null\n private options: Required<LocalFlareOptions>\n\n constructor(options: LocalFlareOptions = {}) {\n this.options = {\n configPath: options.configPath ?? './wrangler.toml',\n port: options.port ?? 8787,\n dashboardPort: options.dashboardPort ?? 8788,\n persistPath: options.persistPath ?? '.localflare',\n verbose: options.verbose ?? false,\n onWorkerLog: options.onWorkerLog ?? (() => {}),\n }\n }\n\n async start(): Promise<void> {\n const configPath = resolve(this.options.configPath)\n const rootDir = dirname(configPath)\n\n // Parse wrangler.toml\n this.config = parseWranglerConfig(configPath)\n this.bindings = discoverBindings(this.config)\n\n // Log discovered bindings\n if (this.options.verbose) {\n console.log('\\n📦 Discovered bindings:')\n getBindingSummary(this.bindings).forEach(line => {\n console.log(` ${line}`)\n })\n console.log('')\n }\n\n // Build Miniflare options\n const persistRoot = resolve(rootDir, this.options.persistPath)\n\n // Compile the worker entry point with esbuild\n const entryPoint = resolve(rootDir, this.config.main || 'src/index.ts')\n const buildResult = await esbuild.build({\n entryPoints: [entryPoint],\n bundle: true,\n format: 'esm',\n target: 'es2022',\n write: false,\n minify: false,\n sourcemap: false,\n conditions: ['workerd', 'worker', 'browser'],\n external: ['cloudflare:*', 'node:*'],\n })\n\n const scriptContent = buildResult.outputFiles?.[0]?.text\n if (!scriptContent) {\n throw new Error('Failed to compile worker script')\n }\n\n // Build explicit binding configurations from parsed config\n // Miniflare v3 expects bindings as objects keyed by binding name\n const d1Databases = Object.fromEntries(\n this.bindings.d1.map(d => [d.binding, d.database_id])\n )\n\n const kvNamespaces = Object.fromEntries(\n this.bindings.kv.map(k => [k.binding, k.id])\n )\n\n const r2Buckets = Object.fromEntries(\n this.bindings.r2.map(r => [r.binding, r.bucket_name])\n )\n\n const queueProducers = Object.fromEntries(\n this.bindings.queues.producers.map(q => [q.binding, q.queue])\n )\n\n // Queue consumers configuration for Miniflare\n // Maps queue name to consumer options\n const queueConsumers = Object.fromEntries(\n this.bindings.queues.consumers.map(c => [\n c.queue,\n {\n maxBatchSize: c.max_batch_size ?? 10,\n maxBatchTimeout: c.max_batch_timeout ?? 5,\n maxRetries: c.max_retries ?? 3,\n deadLetterQueue: c.dead_letter_queue,\n },\n ])\n )\n\n const durableObjects = Object.fromEntries(\n this.bindings.durableObjects.map(d => [d.name, d.class_name])\n )\n\n // Create a handler for worker stdout/stderr to capture logs\n // Use arrow function to capture 'this' and access current callback\n const handleRuntimeStdio = (stdout: Readable, stderr: Readable) => {\n if (this.options.verbose) {\n console.log('[LocalFlare] Runtime stdio handler connected')\n }\n\n const processStream = (stream: Readable, level: 'log' | 'error') => {\n const rl = readline.createInterface({ input: stream })\n rl.on('line', (line) => {\n // Skip empty lines\n if (!line.trim()) return\n\n // Determine log level from content\n let logLevel: 'log' | 'info' | 'warn' | 'error' | 'debug' = level === 'error' ? 'error' : 'log'\n if (line.includes('[warn]') || line.includes('WARNING')) {\n logLevel = 'warn'\n } else if (line.includes('[info]') || line.includes('INFO')) {\n logLevel = 'info'\n } else if (line.includes('[debug]') || line.includes('DEBUG')) {\n logLevel = 'debug'\n } else if (line.includes('[error]') || line.includes('ERROR')) {\n logLevel = 'error'\n }\n\n // Access callback via this.options to allow setting it after start()\n this.options.onWorkerLog({ level: logLevel, message: line })\n })\n }\n\n processStream(stdout, 'log')\n processStream(stderr, 'error')\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const miniflareOptions: any = {\n modules: [\n {\n type: 'ESModule',\n path: entryPoint,\n contents: scriptContent,\n },\n ],\n port: this.options.port,\n verbose: this.options.verbose,\n kvPersist: `${persistRoot}/kv`,\n d1Persist: `${persistRoot}/d1`,\n r2Persist: `${persistRoot}/r2`,\n durableObjectsPersist: `${persistRoot}/do`,\n cachePersist: `${persistRoot}/cache`,\n // Explicit binding configurations\n bindings: this.bindings.vars,\n // Capture worker stdout/stderr for logging\n handleRuntimeStdio,\n // Use plain text logs instead of structured JSON for easier parsing\n structuredWorkerdLogs: false,\n }\n\n // Only add bindings if they exist\n if (Object.keys(d1Databases).length > 0) {\n miniflareOptions.d1Databases = d1Databases\n }\n if (Object.keys(kvNamespaces).length > 0) {\n miniflareOptions.kvNamespaces = kvNamespaces\n }\n if (Object.keys(r2Buckets).length > 0) {\n miniflareOptions.r2Buckets = r2Buckets\n }\n if (Object.keys(queueProducers).length > 0) {\n miniflareOptions.queueProducers = queueProducers\n }\n if (Object.keys(queueConsumers).length > 0) {\n miniflareOptions.queueConsumers = queueConsumers\n }\n if (Object.keys(durableObjects).length > 0) {\n miniflareOptions.durableObjects = durableObjects\n }\n\n this.mf = new Miniflare(miniflareOptions)\n\n // Wait for Miniflare to be ready\n const url = await this.mf.ready\n console.log(`⚡ Worker running at ${url}`)\n }\n\n async stop(): Promise<void> {\n if (this.mf) {\n await this.mf.dispose()\n this.mf = null\n }\n }\n\n // Binding accessors - use generic types for portability\n // Consumers can cast to @cloudflare/workers-types if needed\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getD1Database(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getD1Database(bindingName)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getKVNamespace(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getKVNamespace(bindingName)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getR2Bucket(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getR2Bucket(bindingName)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getDurableObjectNamespace(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getDurableObjectNamespace(bindingName)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getQueueProducer<T = unknown>(bindingName: string): Promise<any> {\n this.ensureRunning()\n return this.mf!.getQueueProducer<T>(bindingName)\n }\n\n async getAllBindings<T = Record<string, unknown>>(): Promise<T> {\n this.ensureRunning()\n return this.mf!.getBindings() as Promise<T>\n }\n\n // Getters\n getDiscoveredBindings(): DiscoveredBindings | null {\n return this.bindings\n }\n\n getConfig(): WranglerConfig | null {\n return this.config\n }\n\n getOptions(): Required<LocalFlareOptions> {\n return this.options\n }\n\n getMiniflare(): Miniflare | null {\n return this.mf\n }\n\n isRunning(): boolean {\n return this.mf !== null\n }\n\n // Set the worker log callback (must be called before start())\n setLogCallback(callback: WorkerLogCallback): void {\n this.options.onWorkerLog = callback\n }\n\n private ensureRunning(): void {\n if (!this.mf) {\n throw new Error('LocalFlare is not running. Call start() first.')\n }\n }\n}\n","import { readFileSync, existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { parse as parseToml } from 'toml'\nimport type { WranglerConfig, DiscoveredBindings } from './types.js'\n\nexport function parseWranglerConfig(configPath: string): WranglerConfig {\n const fullPath = resolve(configPath)\n\n if (!existsSync(fullPath)) {\n throw new Error(`Wrangler config not found at: ${fullPath}`)\n }\n\n const content = readFileSync(fullPath, 'utf-8')\n return parseToml(content) as WranglerConfig\n}\n\nexport function discoverBindings(config: WranglerConfig): DiscoveredBindings {\n return {\n d1: config.d1_databases ?? [],\n kv: config.kv_namespaces ?? [],\n r2: config.r2_buckets ?? [],\n durableObjects: config.durable_objects?.bindings ?? [],\n queues: {\n producers: config.queues?.producers ?? [],\n consumers: config.queues?.consumers ?? [],\n },\n vars: config.vars ?? {},\n }\n}\n\nexport function getBindingSummary(bindings: DiscoveredBindings): string[] {\n const summary: string[] = []\n\n if (bindings.d1.length > 0) {\n summary.push(`D1 Databases: ${bindings.d1.map(d => d.binding).join(', ')}`)\n }\n if (bindings.kv.length > 0) {\n summary.push(`KV Namespaces: ${bindings.kv.map(k => k.binding).join(', ')}`)\n }\n if (bindings.r2.length > 0) {\n summary.push(`R2 Buckets: ${bindings.r2.map(r => r.binding).join(', ')}`)\n }\n if (bindings.durableObjects.length > 0) {\n summary.push(`Durable Objects: ${bindings.durableObjects.map(d => d.name).join(', ')}`)\n }\n if (bindings.queues.producers.length > 0) {\n summary.push(`Queue Producers: ${bindings.queues.producers.map(q => q.binding).join(', ')}`)\n }\n if (bindings.queues.consumers.length > 0) {\n summary.push(`Queue Consumers: ${bindings.queues.consumers.map(q => q.queue).join(', ')}`)\n }\n if (Object.keys(bindings.vars).length > 0) {\n summary.push(`Environment Variables: ${Object.keys(bindings.vars).join(', ')}`)\n }\n\n return summary\n}\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B,SAAS,WAAAA,UAAS,eAAe;AACjC,YAAY,aAAa;AAEzB,YAAY,cAAc;;;ACJ1B,SAAS,cAAc,kBAAkB;AACzC,SAAS,eAAe;AACxB,SAAS,SAAS,iBAAiB;AAG5B,SAAS,oBAAoB,YAAoC;AACtE,QAAM,WAAW,QAAQ,UAAU;AAEnC,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,UAAM,IAAI,MAAM,iCAAiC,QAAQ,EAAE;AAAA,EAC7D;AAEA,QAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,SAAO,UAAU,OAAO;AAC1B;AAEO,SAAS,iBAAiB,QAA4C;AAC3E,SAAO;AAAA,IACL,IAAI,OAAO,gBAAgB,CAAC;AAAA,IAC5B,IAAI,OAAO,iBAAiB,CAAC;AAAA,IAC7B,IAAI,OAAO,cAAc,CAAC;AAAA,IAC1B,gBAAgB,OAAO,iBAAiB,YAAY,CAAC;AAAA,IACrD,QAAQ;AAAA,MACN,WAAW,OAAO,QAAQ,aAAa,CAAC;AAAA,MACxC,WAAW,OAAO,QAAQ,aAAa,CAAC;AAAA,IAC1C;AAAA,IACA,MAAM,OAAO,QAAQ,CAAC;AAAA,EACxB;AACF;AAEO,SAAS,kBAAkB,UAAwC;AACxE,QAAM,UAAoB,CAAC;AAE3B,MAAI,SAAS,GAAG,SAAS,GAAG;AAC1B,YAAQ,KAAK,iBAAiB,SAAS,GAAG,IAAI,OAAK,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC5E;AACA,MAAI,SAAS,GAAG,SAAS,GAAG;AAC1B,YAAQ,KAAK,kBAAkB,SAAS,GAAG,IAAI,OAAK,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7E;AACA,MAAI,SAAS,GAAG,SAAS,GAAG;AAC1B,YAAQ,KAAK,eAAe,SAAS,GAAG,IAAI,OAAK,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC1E;AACA,MAAI,SAAS,eAAe,SAAS,GAAG;AACtC,YAAQ,KAAK,oBAAoB,SAAS,eAAe,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACxF;AACA,MAAI,SAAS,OAAO,UAAU,SAAS,GAAG;AACxC,YAAQ,KAAK,oBAAoB,SAAS,OAAO,UAAU,IAAI,OAAK,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7F;AACA,MAAI,SAAS,OAAO,UAAU,SAAS,GAAG;AACxC,YAAQ,KAAK,oBAAoB,SAAS,OAAO,UAAU,IAAI,OAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC3F;AACA,MAAI,OAAO,KAAK,SAAS,IAAI,EAAE,SAAS,GAAG;AACzC,YAAQ,KAAK,0BAA0B,OAAO,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAChF;AAEA,SAAO;AACT;;;ADhDO,IAAM,aAAN,MAAiB;AAAA,EACd,KAAuB;AAAA,EACvB,SAAgC;AAAA,EAChC,WAAsC;AAAA,EACtC;AAAA,EAER,YAAY,UAA6B,CAAC,GAAG;AAC3C,SAAK,UAAU;AAAA,MACb,YAAY,QAAQ,cAAc;AAAA,MAClC,MAAM,QAAQ,QAAQ;AAAA,MACtB,eAAe,QAAQ,iBAAiB;AAAA,MACxC,aAAa,QAAQ,eAAe;AAAA,MACpC,SAAS,QAAQ,WAAW;AAAA,MAC5B,aAAa,QAAQ,gBAAgB,MAAM;AAAA,MAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,aAAaC,SAAQ,KAAK,QAAQ,UAAU;AAClD,UAAM,UAAU,QAAQ,UAAU;AAGlC,SAAK,SAAS,oBAAoB,UAAU;AAC5C,SAAK,WAAW,iBAAiB,KAAK,MAAM;AAG5C,QAAI,KAAK,QAAQ,SAAS;AACxB,cAAQ,IAAI,kCAA2B;AACvC,wBAAkB,KAAK,QAAQ,EAAE,QAAQ,UAAQ;AAC/C,gBAAQ,IAAI,MAAM,IAAI,EAAE;AAAA,MAC1B,CAAC;AACD,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,UAAM,cAAcA,SAAQ,SAAS,KAAK,QAAQ,WAAW;AAG7D,UAAM,aAAaA,SAAQ,SAAS,KAAK,OAAO,QAAQ,cAAc;AACtE,UAAM,cAAc,MAAc,cAAM;AAAA,MACtC,aAAa,CAAC,UAAU;AAAA,MACxB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,YAAY,CAAC,WAAW,UAAU,SAAS;AAAA,MAC3C,UAAU,CAAC,gBAAgB,QAAQ;AAAA,IACrC,CAAC;AAED,UAAM,gBAAgB,YAAY,cAAc,CAAC,GAAG;AACpD,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAIA,UAAM,cAAc,OAAO;AAAA,MACzB,KAAK,SAAS,GAAG,IAAI,OAAK,CAAC,EAAE,SAAS,EAAE,WAAW,CAAC;AAAA,IACtD;AAEA,UAAM,eAAe,OAAO;AAAA,MAC1B,KAAK,SAAS,GAAG,IAAI,OAAK,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC;AAAA,IAC7C;AAEA,UAAM,YAAY,OAAO;AAAA,MACvB,KAAK,SAAS,GAAG,IAAI,OAAK,CAAC,EAAE,SAAS,EAAE,WAAW,CAAC;AAAA,IACtD;AAEA,UAAM,iBAAiB,OAAO;AAAA,MAC5B,KAAK,SAAS,OAAO,UAAU,IAAI,OAAK,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC;AAAA,IAC9D;AAIA,UAAM,iBAAiB,OAAO;AAAA,MAC5B,KAAK,SAAS,OAAO,UAAU,IAAI,OAAK;AAAA,QACtC,EAAE;AAAA,QACF;AAAA,UACE,cAAc,EAAE,kBAAkB;AAAA,UAClC,iBAAiB,EAAE,qBAAqB;AAAA,UACxC,YAAY,EAAE,eAAe;AAAA,UAC7B,iBAAiB,EAAE;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,iBAAiB,OAAO;AAAA,MAC5B,KAAK,SAAS,eAAe,IAAI,OAAK,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC;AAAA,IAC9D;AAIA,UAAM,qBAAqB,CAAC,QAAkB,WAAqB;AACjE,UAAI,KAAK,QAAQ,SAAS;AACxB,gBAAQ,IAAI,8CAA8C;AAAA,MAC5D;AAEA,YAAM,gBAAgB,CAAC,QAAkB,UAA2B;AAClE,cAAM,KAAc,yBAAgB,EAAE,OAAO,OAAO,CAAC;AACrD,WAAG,GAAG,QAAQ,CAAC,SAAS;AAEtB,cAAI,CAAC,KAAK,KAAK,EAAG;AAGlB,cAAI,WAAwD,UAAU,UAAU,UAAU;AAC1F,cAAI,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,SAAS,GAAG;AACvD,uBAAW;AAAA,UACb,WAAW,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,MAAM,GAAG;AAC3D,uBAAW;AAAA,UACb,WAAW,KAAK,SAAS,SAAS,KAAK,KAAK,SAAS,OAAO,GAAG;AAC7D,uBAAW;AAAA,UACb,WAAW,KAAK,SAAS,SAAS,KAAK,KAAK,SAAS,OAAO,GAAG;AAC7D,uBAAW;AAAA,UACb;AAGA,eAAK,QAAQ,YAAY,EAAE,OAAO,UAAU,SAAS,KAAK,CAAC;AAAA,QAC7D,CAAC;AAAA,MACH;AAEA,oBAAc,QAAQ,KAAK;AAC3B,oBAAc,QAAQ,OAAO;AAAA,IAC/B;AAGA,UAAM,mBAAwB;AAAA,MAC5B,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,MACA,MAAM,KAAK,QAAQ;AAAA,MACnB,SAAS,KAAK,QAAQ;AAAA,MACtB,WAAW,GAAG,WAAW;AAAA,MACzB,WAAW,GAAG,WAAW;AAAA,MACzB,WAAW,GAAG,WAAW;AAAA,MACzB,uBAAuB,GAAG,WAAW;AAAA,MACrC,cAAc,GAAG,WAAW;AAAA;AAAA,MAE5B,UAAU,KAAK,SAAS;AAAA;AAAA,MAExB;AAAA;AAAA,MAEA,uBAAuB;AAAA,IACzB;AAGA,QAAI,OAAO,KAAK,WAAW,EAAE,SAAS,GAAG;AACvC,uBAAiB,cAAc;AAAA,IACjC;AACA,QAAI,OAAO,KAAK,YAAY,EAAE,SAAS,GAAG;AACxC,uBAAiB,eAAe;AAAA,IAClC;AACA,QAAI,OAAO,KAAK,SAAS,EAAE,SAAS,GAAG;AACrC,uBAAiB,YAAY;AAAA,IAC/B;AACA,QAAI,OAAO,KAAK,cAAc,EAAE,SAAS,GAAG;AAC1C,uBAAiB,iBAAiB;AAAA,IACpC;AACA,QAAI,OAAO,KAAK,cAAc,EAAE,SAAS,GAAG;AAC1C,uBAAiB,iBAAiB;AAAA,IACpC;AACA,QAAI,OAAO,KAAK,cAAc,EAAE,SAAS,GAAG;AAC1C,uBAAiB,iBAAiB;AAAA,IACpC;AAEA,SAAK,KAAK,IAAI,UAAU,gBAAgB;AAGxC,UAAM,MAAM,MAAM,KAAK,GAAG;AAC1B,YAAQ,IAAI,4BAAuB,GAAG,EAAE;AAAA,EAC1C;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,KAAK,IAAI;AACX,YAAM,KAAK,GAAG,QAAQ;AACtB,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,aAAmC;AACrD,SAAK,cAAc;AACnB,WAAO,KAAK,GAAI,cAAc,WAAW;AAAA,EAC3C;AAAA;AAAA,EAGA,MAAM,eAAe,aAAmC;AACtD,SAAK,cAAc;AACnB,WAAO,KAAK,GAAI,eAAe,WAAW;AAAA,EAC5C;AAAA;AAAA,EAGA,MAAM,YAAY,aAAmC;AACnD,SAAK,cAAc;AACnB,WAAO,KAAK,GAAI,YAAY,WAAW;AAAA,EACzC;AAAA;AAAA,EAGA,MAAM,0BAA0B,aAAmC;AACjE,SAAK,cAAc;AACnB,WAAO,KAAK,GAAI,0BAA0B,WAAW;AAAA,EACvD;AAAA;AAAA,EAGA,MAAM,iBAA8B,aAAmC;AACrE,SAAK,cAAc;AACnB,WAAO,KAAK,GAAI,iBAAoB,WAAW;AAAA,EACjD;AAAA,EAEA,MAAM,iBAA0D;AAC9D,SAAK,cAAc;AACnB,WAAO,KAAK,GAAI,YAAY;AAAA,EAC9B;AAAA;AAAA,EAGA,wBAAmD;AACjD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAmC;AACjC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAA0C;AACxC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,eAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA,EAGA,eAAe,UAAmC;AAChD,SAAK,QAAQ,cAAc;AAAA,EAC7B;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,CAAC,KAAK,IAAI;AACZ,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAAA,EACF;AACF;","names":["resolve","resolve"]}
|