localflare-core 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # localflare-core
2
+
3
+ Core Miniflare wrapper and configuration parser for [LocalFlare](https://www.npmjs.com/package/localflare).
4
+
5
+ [![npm version](https://img.shields.io/npm/v/localflare-core.svg)](https://www.npmjs.com/package/localflare-core)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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,11 +100,18 @@ 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
 
107
+ declare const WRANGLER_CONFIG_FILES: string[];
108
+ /**
109
+ * Find wrangler config file in a directory
110
+ * Returns the path to the first found config file, or null if none found
111
+ */
112
+ declare function findWranglerConfig(directory: string): string | null;
100
113
  declare function parseWranglerConfig(configPath: string): WranglerConfig;
101
114
  declare function discoverBindings(config: WranglerConfig): DiscoveredBindings;
102
115
  declare function getBindingSummary(bindings: DiscoveredBindings): string[];
103
116
 
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 };
117
+ export { type BindingInfo, type D1DatabaseConfig, type DiscoveredBindings, type DurableObjectBinding, type KVNamespaceConfig, LocalFlare, type LocalFlareOptions, type QueueConsumerConfig, type QueueProducerConfig, type R2BucketConfig, WRANGLER_CONFIG_FILES, type WorkerLogCallback, type WorkerLogEntry, type WranglerConfig, discoverBindings, findWranglerConfig, getBindingSummary, parseWranglerConfig };
package/dist/index.js CHANGED
@@ -2,18 +2,107 @@
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";
8
- import { resolve } from "path";
9
+ import { resolve, extname } from "path";
9
10
  import { parse as parseToml } from "toml";
11
+ var WRANGLER_CONFIG_FILES = [
12
+ "wrangler.toml",
13
+ "wrangler.json",
14
+ "wrangler.jsonc"
15
+ ];
16
+ function stripJsonComments(content) {
17
+ let result = "";
18
+ let inString = false;
19
+ let inSingleLineComment = false;
20
+ let inMultiLineComment = false;
21
+ let i = 0;
22
+ while (i < content.length) {
23
+ const char = content[i];
24
+ const nextChar = content[i + 1];
25
+ if (inSingleLineComment) {
26
+ if (char === "\n") {
27
+ inSingleLineComment = false;
28
+ result += char;
29
+ }
30
+ i++;
31
+ continue;
32
+ }
33
+ if (inMultiLineComment) {
34
+ if (char === "*" && nextChar === "/") {
35
+ inMultiLineComment = false;
36
+ i += 2;
37
+ continue;
38
+ }
39
+ i++;
40
+ continue;
41
+ }
42
+ if (inString) {
43
+ result += char;
44
+ if (char === "\\" && i + 1 < content.length) {
45
+ result += nextChar;
46
+ i += 2;
47
+ continue;
48
+ }
49
+ if (char === '"') {
50
+ inString = false;
51
+ }
52
+ i++;
53
+ continue;
54
+ }
55
+ if (char === '"') {
56
+ inString = true;
57
+ result += char;
58
+ i++;
59
+ continue;
60
+ }
61
+ if (char === "/" && nextChar === "/") {
62
+ inSingleLineComment = true;
63
+ i += 2;
64
+ continue;
65
+ }
66
+ if (char === "/" && nextChar === "*") {
67
+ inMultiLineComment = true;
68
+ i += 2;
69
+ continue;
70
+ }
71
+ result += char;
72
+ i++;
73
+ }
74
+ return result;
75
+ }
76
+ function findWranglerConfig(directory) {
77
+ for (const filename of WRANGLER_CONFIG_FILES) {
78
+ const configPath = resolve(directory, filename);
79
+ if (existsSync(configPath)) {
80
+ return configPath;
81
+ }
82
+ }
83
+ return null;
84
+ }
10
85
  function parseWranglerConfig(configPath) {
11
86
  const fullPath = resolve(configPath);
12
87
  if (!existsSync(fullPath)) {
13
88
  throw new Error(`Wrangler config not found at: ${fullPath}`);
14
89
  }
15
90
  const content = readFileSync(fullPath, "utf-8");
16
- return parseToml(content);
91
+ const ext = extname(fullPath).toLowerCase();
92
+ switch (ext) {
93
+ case ".toml":
94
+ return parseToml(content);
95
+ case ".json":
96
+ return JSON.parse(content);
97
+ case ".jsonc":
98
+ return JSON.parse(stripJsonComments(content));
99
+ default:
100
+ const trimmed = content.trim();
101
+ if (trimmed.startsWith("{")) {
102
+ return JSON.parse(stripJsonComments(content));
103
+ }
104
+ return parseToml(content);
105
+ }
17
106
  }
18
107
  function discoverBindings(config) {
19
108
  return {
@@ -45,6 +134,9 @@ function getBindingSummary(bindings) {
45
134
  if (bindings.queues.producers.length > 0) {
46
135
  summary.push(`Queue Producers: ${bindings.queues.producers.map((q) => q.binding).join(", ")}`);
47
136
  }
137
+ if (bindings.queues.consumers.length > 0) {
138
+ summary.push(`Queue Consumers: ${bindings.queues.consumers.map((q) => q.queue).join(", ")}`);
139
+ }
48
140
  if (Object.keys(bindings.vars).length > 0) {
49
141
  summary.push(`Environment Variables: ${Object.keys(bindings.vars).join(", ")}`);
50
142
  }
@@ -58,12 +150,19 @@ var LocalFlare = class {
58
150
  bindings = null;
59
151
  options;
60
152
  constructor(options = {}) {
153
+ let configPath = options.configPath;
154
+ if (!configPath) {
155
+ const detected = findWranglerConfig(process.cwd());
156
+ configPath = detected ?? "./wrangler.toml";
157
+ }
61
158
  this.options = {
62
- configPath: options.configPath ?? "./wrangler.toml",
159
+ configPath,
63
160
  port: options.port ?? 8787,
64
161
  dashboardPort: options.dashboardPort ?? 8788,
65
162
  persistPath: options.persistPath ?? ".localflare",
66
- verbose: options.verbose ?? false
163
+ verbose: options.verbose ?? false,
164
+ onWorkerLog: options.onWorkerLog ?? (() => {
165
+ })
67
166
  };
68
167
  }
69
168
  async start() {
@@ -88,7 +187,8 @@ var LocalFlare = class {
88
187
  write: false,
89
188
  minify: false,
90
189
  sourcemap: false,
91
- conditions: ["workerd", "worker", "browser"]
190
+ conditions: ["workerd", "worker", "browser"],
191
+ external: ["cloudflare:*", "node:*"]
92
192
  });
93
193
  const scriptContent = buildResult.outputFiles?.[0]?.text;
94
194
  if (!scriptContent) {
@@ -106,9 +206,44 @@ var LocalFlare = class {
106
206
  const queueProducers = Object.fromEntries(
107
207
  this.bindings.queues.producers.map((q) => [q.binding, q.queue])
108
208
  );
209
+ const queueConsumers = Object.fromEntries(
210
+ this.bindings.queues.consumers.map((c) => [
211
+ c.queue,
212
+ {
213
+ maxBatchSize: c.max_batch_size ?? 10,
214
+ maxBatchTimeout: c.max_batch_timeout ?? 5,
215
+ maxRetries: c.max_retries ?? 3,
216
+ deadLetterQueue: c.dead_letter_queue
217
+ }
218
+ ])
219
+ );
109
220
  const durableObjects = Object.fromEntries(
110
221
  this.bindings.durableObjects.map((d) => [d.name, d.class_name])
111
222
  );
223
+ const handleRuntimeStdio = (stdout, stderr) => {
224
+ if (this.options.verbose) {
225
+ console.log("[LocalFlare] Runtime stdio handler connected");
226
+ }
227
+ const processStream = (stream, level) => {
228
+ const rl = readline.createInterface({ input: stream });
229
+ rl.on("line", (line) => {
230
+ if (!line.trim()) return;
231
+ let logLevel = level === "error" ? "error" : "log";
232
+ if (line.includes("[warn]") || line.includes("WARNING")) {
233
+ logLevel = "warn";
234
+ } else if (line.includes("[info]") || line.includes("INFO")) {
235
+ logLevel = "info";
236
+ } else if (line.includes("[debug]") || line.includes("DEBUG")) {
237
+ logLevel = "debug";
238
+ } else if (line.includes("[error]") || line.includes("ERROR")) {
239
+ logLevel = "error";
240
+ }
241
+ this.options.onWorkerLog({ level: logLevel, message: line });
242
+ });
243
+ };
244
+ processStream(stdout, "log");
245
+ processStream(stderr, "error");
246
+ };
112
247
  const miniflareOptions = {
113
248
  modules: [
114
249
  {
@@ -125,7 +260,11 @@ var LocalFlare = class {
125
260
  durableObjectsPersist: `${persistRoot}/do`,
126
261
  cachePersist: `${persistRoot}/cache`,
127
262
  // Explicit binding configurations
128
- bindings: this.bindings.vars
263
+ bindings: this.bindings.vars,
264
+ // Capture worker stdout/stderr for logging
265
+ handleRuntimeStdio,
266
+ // Use plain text logs instead of structured JSON for easier parsing
267
+ structuredWorkerdLogs: false
129
268
  };
130
269
  if (Object.keys(d1Databases).length > 0) {
131
270
  miniflareOptions.d1Databases = d1Databases;
@@ -139,6 +278,9 @@ var LocalFlare = class {
139
278
  if (Object.keys(queueProducers).length > 0) {
140
279
  miniflareOptions.queueProducers = queueProducers;
141
280
  }
281
+ if (Object.keys(queueConsumers).length > 0) {
282
+ miniflareOptions.queueConsumers = queueConsumers;
283
+ }
142
284
  if (Object.keys(durableObjects).length > 0) {
143
285
  miniflareOptions.durableObjects = durableObjects;
144
286
  }
@@ -199,6 +341,10 @@ var LocalFlare = class {
199
341
  isRunning() {
200
342
  return this.mf !== null;
201
343
  }
344
+ // Set the worker log callback (must be called before start())
345
+ setLogCallback(callback) {
346
+ this.options.onWorkerLog = callback;
347
+ }
202
348
  ensureRunning() {
203
349
  if (!this.mf) {
204
350
  throw new Error("LocalFlare is not running. Call start() first.");
@@ -207,7 +353,9 @@ var LocalFlare = class {
207
353
  };
208
354
  export {
209
355
  LocalFlare,
356
+ WRANGLER_CONFIG_FILES,
210
357
  discoverBindings,
358
+ findWranglerConfig,
211
359
  getBindingSummary,
212
360
  parseWranglerConfig
213
361
  };
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, findWranglerConfig } 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 // Auto-detect config if not provided\n let configPath = options.configPath\n if (!configPath) {\n const detected = findWranglerConfig(process.cwd())\n configPath = detected ?? './wrangler.toml' // Fallback for error messaging\n }\n\n this.options = {\n configPath,\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, extname } from 'node:path'\nimport { parse as parseToml } from 'toml'\nimport type { WranglerConfig, DiscoveredBindings } from './types.js'\n\n// Supported wrangler config file names in order of priority\nexport const WRANGLER_CONFIG_FILES = [\n 'wrangler.toml',\n 'wrangler.json',\n 'wrangler.jsonc',\n]\n\n/**\n * Strip JSON comments (both // and /* *\\/) for JSONC parsing\n */\nfunction stripJsonComments(content: string): string {\n let result = ''\n let inString = false\n let inSingleLineComment = false\n let inMultiLineComment = false\n let i = 0\n\n while (i < content.length) {\n const char = content[i]\n const nextChar = content[i + 1]\n\n if (inSingleLineComment) {\n if (char === '\\n') {\n inSingleLineComment = false\n result += char\n }\n i++\n continue\n }\n\n if (inMultiLineComment) {\n if (char === '*' && nextChar === '/') {\n inMultiLineComment = false\n i += 2\n continue\n }\n i++\n continue\n }\n\n if (inString) {\n result += char\n if (char === '\\\\' && i + 1 < content.length) {\n result += nextChar\n i += 2\n continue\n }\n if (char === '\"') {\n inString = false\n }\n i++\n continue\n }\n\n if (char === '\"') {\n inString = true\n result += char\n i++\n continue\n }\n\n if (char === '/' && nextChar === '/') {\n inSingleLineComment = true\n i += 2\n continue\n }\n\n if (char === '/' && nextChar === '*') {\n inMultiLineComment = true\n i += 2\n continue\n }\n\n result += char\n i++\n }\n\n return result\n}\n\n/**\n * Find wrangler config file in a directory\n * Returns the path to the first found config file, or null if none found\n */\nexport function findWranglerConfig(directory: string): string | null {\n for (const filename of WRANGLER_CONFIG_FILES) {\n const configPath = resolve(directory, filename)\n if (existsSync(configPath)) {\n return configPath\n }\n }\n return null\n}\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 const ext = extname(fullPath).toLowerCase()\n\n switch (ext) {\n case '.toml':\n return parseToml(content) as WranglerConfig\n case '.json':\n return JSON.parse(content) as WranglerConfig\n case '.jsonc':\n return JSON.parse(stripJsonComments(content)) as WranglerConfig\n default:\n // Try to detect format from content\n const trimmed = content.trim()\n if (trimmed.startsWith('{')) {\n // Looks like JSON/JSONC\n return JSON.parse(stripJsonComments(content)) as WranglerConfig\n }\n // Default to TOML\n return parseToml(content) as WranglerConfig\n }\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":"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","names":["resolve","resolve"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "localflare-core",
3
- "version": "0.0.1",
3
+ "version": "0.1.1",
4
4
  "description": "Core Miniflare wrapper for LocalFlare",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",