@lunora/vite 1.0.0-alpha.61 → 1.0.0-alpha.62

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/index.d.mts CHANGED
@@ -279,8 +279,8 @@ declare const frameworkComposePlugin: (options: ResolvedLunoraPluginOptions, con
279
279
  declare const LUNORA_API_UPDATED_EVENT = "lunora:api-updated";
280
280
  /**
281
281
  * Vite plugin (serve-only) that formats Lunora worker logs in the terminal.
282
- * Patches `process.stdout`/`process.stderr` once the dev server is configured
283
- * and restores them when it closes.
282
+ * Patches `process.stdout`/`process.stderr` fresh for each dev-server generation
283
+ * and restores them when that server closes.
284
284
  */
285
285
  declare const logStreamPlugin: () => Plugin;
286
286
  /** The decision a {@link planViteRemoteBindings} call returns. */
@@ -321,17 +321,34 @@ declare const planViteRemoteBindings: (options: PlanViteRemoteOptions) => ViteRe
321
321
  /**
322
322
  * Wrap the cloudflare-plugin options so the dev worker loads the materialized
323
323
  * remote temp config (via `configPath`) when — and only when — remote mode is
324
- * on AND it's a `vite` serve. A `configPath` the caller already set wins (their
325
- * explicit choice), and during a production build nothing is injected, so the
326
- * deployed worker is never affected.
324
+ * on and a temp config was materialized. A `configPath` the caller already set
325
+ * wins (their explicit choice).
327
326
  *
328
- * Returns the wrapped options plus the plan, so `index.ts` can register the
329
- * cleanup on a close hook. Materialization happens lazily inside the `configPath`
330
- * resolution path: it's only meaningful during serve, but computing it eagerly
331
- * is harmless (the materializer is a no-op when disabled) and keeps the wiring
332
- * simple — the plan is computed once here.
327
+ * Pure decision only the serve-vs-build gate lives in
328
+ * {@link remoteBindingsConfigPlugin}'s `config` hook, because the resolved Vite
329
+ * `command` is unknown at plugin-factory time (when this runs). An eager serve
330
+ * check here would always read `command` as undefined and strip `configPath`.
333
331
  */
334
- declare const withRemoteBindings: (options: CloudflarePluginOptions, isServe: () => boolean, plan: ViteRemotePlan) => CloudflarePluginOptions;
332
+ declare const withRemoteBindings: (options: CloudflarePluginOptions, plan: ViteRemotePlan) => CloudflarePluginOptions;
333
+ /**
334
+ * A `enforce: "pre"` plugin whose `config` hook injects the materialized remote
335
+ * temp config into the cloudflare plugin's `configPath` — but only on a `vite`
336
+ * serve, never a production build (so the deployed worker is never affected).
337
+ *
338
+ * The deferral is the whole point: at plugin-factory time Vite has not yet told
339
+ * us `serve` vs `build`, so the check must run in a `config` hook (where
340
+ * `env.command` is known). It mutates the SAME options object handed to
341
+ * `cloudflare()` in place — the cloudflare plugin reads `pluginConfig.configPath`
342
+ * lazily inside its own `config` hook, which runs after this `enforce: "pre"`
343
+ * one, so the injection takes effect. An eager factory-time serve check (the old
344
+ * behaviour) always saw `command` undefined and silently dropped the path, so
345
+ * remote bindings never activated on `vite dev`.
346
+ *
347
+ * When remote mode was requested but nothing materialized (no eligible binding,
348
+ * no wrangler file, …), the plan's `reason` is logged so the degradation isn't
349
+ * silent.
350
+ */
351
+ declare const remoteBindingsConfigPlugin: (options: CloudflarePluginOptions, plan: ViteRemotePlan) => Plugin;
335
352
  /**
336
353
  * A tiny Vite plugin that runs the remote temp-config disposer when the dev
337
354
  * server tears down (`buildEnd` fires on close in serve; `closeBundle` covers
@@ -467,5 +484,5 @@ declare const resolveOverlayOption: (overlay: LunoraPluginOptions["overlay"]) =>
467
484
  * than relying on whether they're installed.
468
485
  */
469
486
  declare const lunora: (options?: LunoraPluginOptions) => LunoraPlugins;
470
- declare const VERSION = "0.0.0";
471
- export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR, LUNORA_API_UPDATED_EVENT, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type OverlayPluginOptions, type PlanViteRemoteOptions, type ReconcileResult, type ResolvedLunoraPluginOptions, STUDIO_PATH, type Solution, type SolutionFinder, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, codegenPlugin, containerLogsPlugin, createCommandProbe, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, lunoraSolutionFinder, lunoraSolutionFinders, planViteRemoteBindings, reconcileWranglerCrons, remoteBindingsCleanupPlugin, resolveOverlayOption, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
487
+ declare const VERSION: string;
488
+ export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR, LUNORA_API_UPDATED_EVENT, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type OverlayPluginOptions, type PlanViteRemoteOptions, type ReconcileResult, type ResolvedLunoraPluginOptions, STUDIO_PATH, type Solution, type SolutionFinder, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, codegenPlugin, containerLogsPlugin, createCommandProbe, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, lunoraSolutionFinder, lunoraSolutionFinders, planViteRemoteBindings, reconcileWranglerCrons, remoteBindingsCleanupPlugin, remoteBindingsConfigPlugin, resolveOverlayOption, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
package/dist/index.d.ts CHANGED
@@ -279,8 +279,8 @@ declare const frameworkComposePlugin: (options: ResolvedLunoraPluginOptions, con
279
279
  declare const LUNORA_API_UPDATED_EVENT = "lunora:api-updated";
280
280
  /**
281
281
  * Vite plugin (serve-only) that formats Lunora worker logs in the terminal.
282
- * Patches `process.stdout`/`process.stderr` once the dev server is configured
283
- * and restores them when it closes.
282
+ * Patches `process.stdout`/`process.stderr` fresh for each dev-server generation
283
+ * and restores them when that server closes.
284
284
  */
285
285
  declare const logStreamPlugin: () => Plugin;
286
286
  /** The decision a {@link planViteRemoteBindings} call returns. */
@@ -321,17 +321,34 @@ declare const planViteRemoteBindings: (options: PlanViteRemoteOptions) => ViteRe
321
321
  /**
322
322
  * Wrap the cloudflare-plugin options so the dev worker loads the materialized
323
323
  * remote temp config (via `configPath`) when — and only when — remote mode is
324
- * on AND it's a `vite` serve. A `configPath` the caller already set wins (their
325
- * explicit choice), and during a production build nothing is injected, so the
326
- * deployed worker is never affected.
324
+ * on and a temp config was materialized. A `configPath` the caller already set
325
+ * wins (their explicit choice).
327
326
  *
328
- * Returns the wrapped options plus the plan, so `index.ts` can register the
329
- * cleanup on a close hook. Materialization happens lazily inside the `configPath`
330
- * resolution path: it's only meaningful during serve, but computing it eagerly
331
- * is harmless (the materializer is a no-op when disabled) and keeps the wiring
332
- * simple — the plan is computed once here.
327
+ * Pure decision only the serve-vs-build gate lives in
328
+ * {@link remoteBindingsConfigPlugin}'s `config` hook, because the resolved Vite
329
+ * `command` is unknown at plugin-factory time (when this runs). An eager serve
330
+ * check here would always read `command` as undefined and strip `configPath`.
333
331
  */
334
- declare const withRemoteBindings: (options: CloudflarePluginOptions, isServe: () => boolean, plan: ViteRemotePlan) => CloudflarePluginOptions;
332
+ declare const withRemoteBindings: (options: CloudflarePluginOptions, plan: ViteRemotePlan) => CloudflarePluginOptions;
333
+ /**
334
+ * A `enforce: "pre"` plugin whose `config` hook injects the materialized remote
335
+ * temp config into the cloudflare plugin's `configPath` — but only on a `vite`
336
+ * serve, never a production build (so the deployed worker is never affected).
337
+ *
338
+ * The deferral is the whole point: at plugin-factory time Vite has not yet told
339
+ * us `serve` vs `build`, so the check must run in a `config` hook (where
340
+ * `env.command` is known). It mutates the SAME options object handed to
341
+ * `cloudflare()` in place — the cloudflare plugin reads `pluginConfig.configPath`
342
+ * lazily inside its own `config` hook, which runs after this `enforce: "pre"`
343
+ * one, so the injection takes effect. An eager factory-time serve check (the old
344
+ * behaviour) always saw `command` undefined and silently dropped the path, so
345
+ * remote bindings never activated on `vite dev`.
346
+ *
347
+ * When remote mode was requested but nothing materialized (no eligible binding,
348
+ * no wrangler file, …), the plan's `reason` is logged so the degradation isn't
349
+ * silent.
350
+ */
351
+ declare const remoteBindingsConfigPlugin: (options: CloudflarePluginOptions, plan: ViteRemotePlan) => Plugin;
335
352
  /**
336
353
  * A tiny Vite plugin that runs the remote temp-config disposer when the dev
337
354
  * server tears down (`buildEnd` fires on close in serve; `closeBundle` covers
@@ -467,5 +484,5 @@ declare const resolveOverlayOption: (overlay: LunoraPluginOptions["overlay"]) =>
467
484
  * than relying on whether they're installed.
468
485
  */
469
486
  declare const lunora: (options?: LunoraPluginOptions) => LunoraPlugins;
470
- declare const VERSION = "0.0.0";
471
- export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR, LUNORA_API_UPDATED_EVENT, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type OverlayPluginOptions, type PlanViteRemoteOptions, type ReconcileResult, type ResolvedLunoraPluginOptions, STUDIO_PATH, type Solution, type SolutionFinder, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, codegenPlugin, containerLogsPlugin, createCommandProbe, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, lunoraSolutionFinder, lunoraSolutionFinders, planViteRemoteBindings, reconcileWranglerCrons, remoteBindingsCleanupPlugin, resolveOverlayOption, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
487
+ declare const VERSION: string;
488
+ export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR, LUNORA_API_UPDATED_EVENT, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type OverlayPluginOptions, type PlanViteRemoteOptions, type ReconcileResult, type ResolvedLunoraPluginOptions, STUDIO_PATH, type Solution, type SolutionFinder, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, codegenPlugin, containerLogsPlugin, createCommandProbe, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, lunoraSolutionFinder, lunoraSolutionFinders, planViteRemoteBindings, reconcileWranglerCrons, remoteBindingsCleanupPlugin, remoteBindingsConfigPlugin, resolveOverlayOption, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
package/dist/index.mjs CHANGED
@@ -1,22 +1,24 @@
1
+ import { createRequire } from 'node:module';
1
2
  import { cloudflare } from '@cloudflare/vite-plugin';
2
3
  import errorOverlayPlugin from '@visulima/vite-overlay';
3
4
  import { detectAgentRules, claimAgentRulesHint, AGENT_RULES_HINT, detectFramework } from '@lunora/config';
4
5
  export { detectFramework } from '@lunora/config';
5
6
  import { l as lunoraLine } from './packem_shared/log-BjO9EWah.mjs';
6
- import codegenPlugin from './packem_shared/codegenPlugin-DEfMflEi.mjs';
7
+ import codegenPlugin from './packem_shared/codegenPlugin-AvEbFKni.mjs';
7
8
  import containerLogsPlugin from './packem_shared/containerLogsPlugin-DMssU3wb.mjs';
8
9
  import devStatePlugin from './packem_shared/devStatePlugin-DdjfMrhx.mjs';
9
10
  import devVariablesPlugin from './packem_shared/devVariablesPlugin-CDNSnvOP.mjs';
10
11
  import { createCommandProbe, withDevWorkerEnv } from './packem_shared/DEV_WORKER_ENV_VALUE-Coo6bgVz.mjs';
11
12
  export { DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR } from './packem_shared/DEV_WORKER_ENV_VALUE-Coo6bgVz.mjs';
12
- import { frameworkComposePlugin } from './packem_shared/CLASS_A_WIRING-DEw5sPHs.mjs';
13
- export { CLASS_A_WIRING, LUNORA_WORKER_VIRTUAL_ID, buildWorkerEntrySource, isAutoComposable } from './packem_shared/CLASS_A_WIRING-DEw5sPHs.mjs';
14
- import logStreamPlugin from './packem_shared/logStreamPlugin-CVrcDAZ1.mjs';
15
- import { planViteRemoteBindings, remoteBindingsCleanupPlugin, withRemoteBindings } from './packem_shared/planViteRemoteBindings-QN5ncUS1.mjs';
13
+ import { frameworkComposePlugin } from './packem_shared/CLASS_A_WIRING-T1RohRZQ.mjs';
14
+ export { CLASS_A_WIRING, LUNORA_WORKER_VIRTUAL_ID, buildWorkerEntrySource, isAutoComposable } from './packem_shared/CLASS_A_WIRING-T1RohRZQ.mjs';
15
+ import logStreamPlugin from './packem_shared/logStreamPlugin-DeFzd_pC.mjs';
16
+ import { planViteRemoteBindings, remoteBindingsCleanupPlugin, remoteBindingsConfigPlugin } from './packem_shared/planViteRemoteBindings-CRU90Bip.mjs';
17
+ export { withRemoteBindings } from './packem_shared/planViteRemoteBindings-CRU90Bip.mjs';
16
18
  import { lunoraSolutionFinders } from './packem_shared/lunoraSolutionFinder-BKEAiUJP.mjs';
17
19
  export { lunoraSolutionFinder } from './packem_shared/lunoraSolutionFinder-BKEAiUJP.mjs';
18
- import { studioPlugin } from './packem_shared/STUDIO_PATH-DYspAN3z.mjs';
19
- export { STUDIO_PATH, buildStudioUrl } from './packem_shared/STUDIO_PATH-DYspAN3z.mjs';
20
+ import { studioPlugin } from './packem_shared/STUDIO_PATH-U0eIaW1t.mjs';
21
+ export { STUDIO_PATH, buildStudioUrl } from './packem_shared/STUDIO_PATH-U0eIaW1t.mjs';
20
22
  import { withWorkerStartupHint } from './packem_shared/WORKER_STARTUP_HINT-DhsXUW8k.mjs';
21
23
  export { WORKER_STARTUP_HINT, augmentWorkerStartupError, isWorkerEntryEvalError } from './packem_shared/WORKER_STARTUP_HINT-DhsXUW8k.mjs';
22
24
  import { wranglerValidatorPlugin } from './packem_shared/wranglerValidatorPlugin-C5VWOD7N.mjs';
@@ -156,14 +158,17 @@ const lunora = (options) => {
156
158
  if (resolved.cloudflare !== false) {
157
159
  plugins.push(containerLogsPlugin(resolved));
158
160
  const remotePlan = planViteRemoteBindings({ projectRoot: resolved.projectRoot });
159
- if (remotePlan.enabled && remotePlan.configPath !== void 0) {
160
- plugins.push(remoteBindingsCleanupPlugin(remotePlan.cleanup));
161
+ const cloudflareOptions = withDevWorkerEnv(resolved.cloudflare, isServe);
162
+ if (remotePlan.enabled) {
163
+ if (remotePlan.configPath !== void 0) {
164
+ plugins.push(remoteBindingsCleanupPlugin(remotePlan.cleanup));
165
+ }
166
+ plugins.push(remoteBindingsConfigPlugin(cloudflareOptions, remotePlan));
161
167
  }
162
- const cloudflareOptions = withRemoteBindings(withDevWorkerEnv(resolved.cloudflare, isServe), isServe, remotePlan);
163
168
  plugins.push(...withWorkerStartupHint(cloudflare(cloudflareOptions)));
164
169
  }
165
170
  return plugins;
166
171
  };
167
- const VERSION = "0.0.0";
172
+ const VERSION = createRequire(import.meta.url)("../package.json").version;
168
173
 
169
- export { VERSION, codegenPlugin, containerLogsPlugin, createCommandProbe, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, logStreamPlugin, lunora, lunoraSolutionFinders, planViteRemoteBindings, remoteBindingsCleanupPlugin, resolveOverlayOption, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
174
+ export { VERSION, codegenPlugin, containerLogsPlugin, createCommandProbe, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, logStreamPlugin, lunora, lunoraSolutionFinders, planViteRemoteBindings, remoteBindingsCleanupPlugin, remoteBindingsConfigPlugin, resolveOverlayOption, studioPlugin, withDevWorkerEnv, withWorkerStartupHint, wranglerValidatorPlugin };
@@ -53,18 +53,19 @@ const buildWorkerEntrySource = (framework, generatedImportBase, hasContainers =
53
53
  if (wiring === void 0) {
54
54
  throw new LunoraError("INTERNAL", `[lunora] no class-A worker wiring for framework "${framework}"`);
55
55
  }
56
+ const base = generatedImportBase.replaceAll("\\", "/");
56
57
  const runtimeModule = useUmbrella ? "lunorash/runtime" : "@lunora/runtime";
57
58
  const containersReexport = hasContainers ? `
58
- export * from "${generatedImportBase}/containers";
59
+ export * from "${base}/containers";
59
60
  ` : "";
60
61
  return `// Generated by @lunora/vite — class-A worker composition (PLAN4 M2).
61
62
  // Do not edit: emitted from the detected framework (${framework}). Point your
62
63
  // wrangler \`main\` here (or re-export it) instead of hand-wiring createWorker.
63
64
  import { composeWorker } from "${runtimeModule}";
64
65
  ${wiring.imports}
65
- import { LUNORA_FUNCTIONS } from "${generatedImportBase}/functions";
66
- import { openApiSpec } from "${generatedImportBase}/openapi";
67
- import { createShardDO } from "${generatedImportBase}/shard";
66
+ import { LUNORA_FUNCTIONS } from "${base}/functions";
67
+ import { openApiSpec } from "${base}/openapi";
68
+ import { createShardDO } from "${base}/shard";
68
69
 
69
70
  export const ShardDO = createShardDO();
70
71
  ${containersReexport}
@@ -47,6 +47,10 @@ const transportRejectionReason = (request) => {
47
47
  if (host !== void 0 && !LOOPBACK_HOSTS.has(host)) {
48
48
  return "Lunora studio rejects a non-localhost Host header in dev.";
49
49
  }
50
+ const FORWARDING_HEADERS = ["x-forwarded-for", "x-forwarded-host", "x-forwarded-proto", "forwarded"];
51
+ if (FORWARDING_HEADERS.some((name) => request.headers?.[name] !== void 0)) {
52
+ return "Lunora studio refuses a proxied (X-Forwarded-*) request in dev.";
53
+ }
50
54
  return void 0;
51
55
  };
52
56
  const originRejectionReason = (headers) => {
@@ -150,7 +150,6 @@ const notifyEnvironmentsAfterCodegen = (server, changedFile, clearErrorOverlay)
150
150
  const codegenPlugin = (options) => {
151
151
  const absoluteSchemaDirectory = resolve(options.projectRoot, options.schemaDir);
152
152
  let absoluteGeneratedDirectory = resolve(options.projectRoot, options.generatedDir);
153
- let debounceTimer;
154
153
  let devServer;
155
154
  const pendingMiddlewareTeardowns = /* @__PURE__ */ new Map();
156
155
  let configFingerprint;
@@ -219,6 +218,7 @@ const codegenPlugin = (options) => {
219
218
  };
220
219
  const isInside = (path, directory) => path === directory || path.startsWith(directory + sep);
221
220
  let closed = false;
221
+ let debounceTimer;
222
222
  let cachedProject;
223
223
  const invalidateGenerated = () => {
224
224
  for (const environment of Object.values(server.environments)) {
@@ -1,4 +1,5 @@
1
1
  import { detectAiAgent, LUNORA_EVENT_SOURCE, formatLunoraEvent } from '@lunora/config';
2
+ import { a as registerDevServerClose, r as runPendingClose } from './server-close-DKDp7YTU.mjs';
2
3
 
3
4
  const LUNORA_MARKER = `"source":"${LUNORA_EVENT_SOURCE}"`;
4
5
  const ANSI = {
@@ -30,9 +31,12 @@ const wrapWrite = (original, colour) => (...args) => {
30
31
  };
31
32
  const patchStream = (stream) => {
32
33
  const original = stream.write.bind(stream);
33
- stream.write = wrapWrite(original, stream.isTTY === true);
34
+ const wrapper = wrapWrite(original, stream.isTTY === true);
35
+ stream.write = wrapper;
34
36
  return () => {
35
- stream.write = original;
37
+ if (stream.write === wrapper) {
38
+ stream.write = original;
39
+ }
36
40
  };
37
41
  };
38
42
  const wantRawJsonLogs = () => {
@@ -46,26 +50,29 @@ const wantRawJsonLogs = () => {
46
50
  return detectAiAgent() !== void 0;
47
51
  };
48
52
  const logStreamPlugin = () => {
49
- let restore;
53
+ const pendingMiddlewareTeardowns = /* @__PURE__ */ new Map();
54
+ let activeRestore;
50
55
  return {
51
56
  apply: "serve",
57
+ buildEnd() {
58
+ runPendingClose(pendingMiddlewareTeardowns, this.environment);
59
+ },
52
60
  configureServer(server) {
53
- if (restore) {
54
- return;
55
- }
56
61
  if (wantRawJsonLogs()) {
57
62
  return;
58
63
  }
64
+ activeRestore?.();
59
65
  const restoreStdout = patchStream(process.stdout);
60
66
  const restoreStderr = patchStream(process.stderr);
61
- restore = () => {
67
+ const restore = () => {
62
68
  restoreStdout();
63
69
  restoreStderr();
64
- restore = void 0;
70
+ if (activeRestore === restore) {
71
+ activeRestore = void 0;
72
+ }
65
73
  };
66
- server.httpServer?.once("close", () => {
67
- restore?.();
68
- });
74
+ activeRestore = restore;
75
+ registerDevServerClose(server, pendingMiddlewareTeardowns, restore);
69
76
  },
70
77
  name: "lunora:log-stream"
71
78
  };
@@ -1,4 +1,5 @@
1
1
  import { resolveRemoteEnabled, readProjectRemotePreference, materializeRemoteWranglerConfig } from '@lunora/config';
2
+ import { l as lunoraLine } from './log-BjO9EWah.mjs';
2
3
 
3
4
  const noopCleanup = () => {
4
5
  };
@@ -21,7 +22,7 @@ const planViteRemoteBindings = (options) => {
21
22
  reason: result.reason
22
23
  };
23
24
  };
24
- const withRemoteBindings = (options, isServe, plan) => {
25
+ const withRemoteBindings = (options, plan) => {
25
26
  if (!plan.enabled || plan.configPath === void 0) {
26
27
  return options;
27
28
  }
@@ -29,11 +30,26 @@ const withRemoteBindings = (options, isServe, plan) => {
29
30
  if (typeof existing.configPath === "string") {
30
31
  return options;
31
32
  }
32
- if (!isServe()) {
33
- return options;
34
- }
35
33
  return { ...options, configPath: plan.configPath };
36
34
  };
35
+ const remoteBindingsConfigPlugin = (options, plan) => {
36
+ return {
37
+ config(_userConfig, env) {
38
+ if (env.command !== "serve") {
39
+ return;
40
+ }
41
+ const merged = withRemoteBindings(options, plan);
42
+ const target = options;
43
+ if (merged.configPath !== void 0 && target.configPath === void 0) {
44
+ target.configPath = merged.configPath;
45
+ } else if (plan.enabled && plan.configPath === void 0 && plan.reason !== void 0) {
46
+ console.info(lunoraLine(`remote bindings requested but not applied: ${plan.reason}`));
47
+ }
48
+ },
49
+ enforce: "pre",
50
+ name: "lunora:remote-bindings-config"
51
+ };
52
+ };
37
53
  const remoteBindingsCleanupPlugin = (cleanup) => {
38
54
  return {
39
55
  buildEnd() {
@@ -47,4 +63,4 @@ const remoteBindingsCleanupPlugin = (cleanup) => {
47
63
  };
48
64
  };
49
65
 
50
- export { planViteRemoteBindings, remoteBindingsCleanupPlugin, withRemoteBindings };
66
+ export { planViteRemoteBindings, remoteBindingsCleanupPlugin, remoteBindingsConfigPlugin, withRemoteBindings };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/vite",
3
- "version": "1.0.0-alpha.61",
3
+ "version": "1.0.0-alpha.62",
4
4
  "description": "The Lunora Vite plugin: codegen, type sync, wrangler validation, and an error overlay over @cloudflare/vite-plugin",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,15 +46,15 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@cloudflare/vite-plugin": "1.43.0",
49
- "@lunora/codegen": "1.0.0-alpha.39",
50
- "@lunora/config": "1.0.0-alpha.61",
51
- "@lunora/errors": "1.0.0-alpha.3",
49
+ "@lunora/codegen": "1.0.0-alpha.40",
50
+ "@lunora/config": "1.0.0-alpha.62",
51
+ "@lunora/errors": "1.0.0-alpha.4",
52
52
  "@visulima/vite-overlay": "2.0.0",
53
53
  "jsonc-parser": "^3.3.1",
54
54
  "ts-morph": "^28.0.0"
55
55
  },
56
56
  "peerDependencies": {
57
- "@lunora/studio": "1.0.0-alpha.46",
57
+ "@lunora/studio": "1.0.0-alpha.47",
58
58
  "vite": "^8.1.3"
59
59
  },
60
60
  "peerDependenciesMeta": {