kirbyup 4.0.0-alpha.4 → 4.0.0-alpha.5

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/node/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as version, i as name, n as serve, r as handleError, t as build } from "../node-GoJ-fFA1.mjs";
1
+ import { a as version, i as name, n as serve, r as handleError, t as build } from "../node-B8aLFfzt.mjs";
2
2
  import { cac } from "cac";
3
3
 
4
4
  //#region src/node/cli-start.ts
@@ -1,3 +1,3 @@
1
- import { n as serve, t as build } from "../node-GoJ-fFA1.mjs";
1
+ import { n as serve, t as build } from "../node-B8aLFfzt.mjs";
2
2
 
3
3
  export { build, serve };
@@ -12,13 +12,14 @@ import * as vueCompilerSfc from "vue/compiler-sfc";
12
12
  import { loadConfig } from "c12";
13
13
  import postcssrc from "postcss-load-config";
14
14
  import { detectPackageManager } from "nypm";
15
+ import { isIP } from "node:net";
15
16
  import { Buffer } from "node:buffer";
16
17
  import { promisify } from "node:util";
17
18
  import { gzip } from "node:zlib";
18
19
 
19
20
  //#region package.json
20
21
  var name = "kirbyup";
21
- var version = "4.0.0-alpha.4";
22
+ var version = "4.0.0-alpha.5";
22
23
 
23
24
  //#endregion
24
25
  //#region src/node/config.ts
@@ -70,6 +71,39 @@ function kirbyupBuildCleanupPlugin(options) {
70
71
  };
71
72
  }
72
73
 
74
+ //#endregion
75
+ //#region src/node/utils/server.ts
76
+ function resolveOriginFromServerOptions(serverOptions, port, fallbackHostname) {
77
+ const protocol = serverOptions?.https && (typeof serverOptions.https === "boolean" || Object.keys(serverOptions.https).length > 0) ? "https" : "http";
78
+ const configuredHost = normalizeHost(serverOptions?.host);
79
+ return `${protocol}://${formatHostname(configuredHost || fallbackHostname || "localhost")}${(configuredHost ? hostIncludesPort(configuredHost) : false) || !needsExplicitPort(protocol, port) ? "" : `:${port}`}`;
80
+ }
81
+ function ensureTrailingSlash(url) {
82
+ return url.endsWith("/") ? url : `${url}/`;
83
+ }
84
+ function normalizeHost(host) {
85
+ if (host === false || host === void 0) return;
86
+ if (host === true) return "0.0.0.0";
87
+ return host;
88
+ }
89
+ function formatHostname(host) {
90
+ if (!host) return "localhost";
91
+ if (host.startsWith("[") && host.endsWith("]")) return host;
92
+ return isIP(host) === 6 ? `[${host}]` : host;
93
+ }
94
+ function hostIncludesPort(host) {
95
+ if (host.startsWith("[")) {
96
+ const closingIndex = host.indexOf("]");
97
+ return closingIndex > -1 && host.slice(closingIndex + 1).startsWith(":");
98
+ }
99
+ if (isIP(host) === 6) return false;
100
+ return host.includes(":");
101
+ }
102
+ function needsExplicitPort(protocol, port) {
103
+ if (protocol === "http") return port !== 80;
104
+ return port !== 443;
105
+ }
106
+
73
107
  //#endregion
74
108
  //#region src/node/plugins/utils.ts
75
109
  /**
@@ -232,7 +266,7 @@ function kirbyupHmrPlugin(options) {
232
266
  configResolved(resolvedConfig) {
233
267
  config = resolvedConfig;
234
268
  entry = resolve(config.root, options.entry);
235
- devIndexPath = resolve(config.root, options.outDir || "", "index.dev.mjs");
269
+ devIndexPath = resolve(config.root, options.outDir ?? "", "index.dev.mjs");
236
270
  },
237
271
  transform(code, id) {
238
272
  if (!id.endsWith(".vue")) return;
@@ -248,15 +282,14 @@ function kirbyupHmrPlugin(options) {
248
282
  if (!server.httpServer) return;
249
283
  server.httpServer.once("listening", async () => {
250
284
  const entryPath = entry.replace(`${config.root}/`, "");
251
- const { address, family, port } = server.httpServer.address();
252
- const baseUrl = `http://${family === "IPv6" ? `[${address}]` : address}:${port}${config.base}`;
285
+ const baseUrl = getDevBaseUrl(server, config);
253
286
  const entryUrl = new URL(entryPath, baseUrl).href;
254
287
  const pm = await detectPackageManager(config.root);
255
288
  await fsp.writeFile(devIndexPath, getViteProxyModule(entryUrl, pm));
256
289
  });
257
290
  },
258
- closeBundle() {
259
- if (fs.existsSync(devIndexPath)) fs.unlinkSync(devIndexPath);
291
+ async closeBundle() {
292
+ await fsp.rm(devIndexPath, { force: true });
260
293
  }
261
294
  };
262
295
  }
@@ -268,106 +301,19 @@ function getViteProxyModule(entryUrl, packageManager) {
268
301
  return `
269
302
  try {
270
303
  await import("${entryUrl}");
271
- } catch (err) {
304
+ } catch (error) {
272
305
  console.error(
273
- "[kirbyup] Couldn't connect to the development server. Run \`${pm} run serve\` to start Vite or build the plugin with \`${pm} run build\` so Kirby uses the production version."
306
+ "[kirbyup] Couldn't connect to the development server at ${entryUrl}. Run \`${pm} run serve\` to start Vite or build the plugin with \`${pm} run build\` so Kirby uses the production version."
274
307
  );
275
- throw err;
308
+ throw error;
276
309
  }
277
310
  `.trimStart();
278
311
  }
279
-
280
- //#endregion
281
- //#region src/node/plugins/vite-running.ts
282
- const VITE_RUNNING_FILENAME = ".vite-running";
283
- function kirbyupRunningMarkerPlugin(options = {}) {
284
- let config;
285
- let pluginDir;
286
- let markerPath;
287
- let exitCleanupRegistered = false;
288
- const ensureMarker = async () => {
289
- if (markerPath) return;
290
- try {
291
- const resolvedPath = await ensureViteRunningMarker(pluginDir);
292
- if (resolvedPath) markerPath = resolvedPath;
293
- } catch (error) {
294
- config.logger.warn(`[kirbyup] Failed to write ${VITE_RUNNING_FILENAME}: ${error.message}`);
295
- }
296
- };
297
- const cleanupMarker = async () => {
298
- if (!markerPath) return;
299
- try {
300
- await removeViteRunningMarker(markerPath);
301
- } catch (error) {
302
- config.logger.warn(`[kirbyup] Failed to remove ${VITE_RUNNING_FILENAME}: ${error.message}`);
303
- } finally {
304
- markerPath = void 0;
305
- }
306
- };
307
- const registerProcessCleanup = () => {
308
- if (exitCleanupRegistered) return;
309
- exitCleanupRegistered = true;
310
- process.once("exit", () => {
311
- if (markerPath && fs.existsSync(markerPath)) try {
312
- fs.rmSync(markerPath, { force: true });
313
- } catch {}
314
- });
315
- };
316
- return {
317
- name: "kirbyup:vite-running",
318
- configResolved(resolved) {
319
- config = resolved;
320
- pluginDir = resolve(resolved.root, options.outDir || "");
321
- registerProcessCleanup();
322
- },
323
- configureServer(server) {
324
- server.httpServer?.once("listening", () => ensureMarker());
325
- server.httpServer?.once("close", () => cleanupMarker());
326
- },
327
- buildStart() {
328
- if (config.command !== "build" || !config.build.watch) return;
329
- ensureMarker();
330
- }
331
- };
332
- }
333
- /**
334
- * Creates the `.vite-running` marker file if the directory is inside `site/plugins/`.
335
- * Returns `undefined` if the directory is not a Kirby plugin directory.
336
- */
337
- async function ensureViteRunningMarker(targetDir) {
338
- if (!isInsideKirbyPlugins(targetDir)) return;
339
- const markerPath = resolve(targetDir, VITE_RUNNING_FILENAME);
340
- await fsp.writeFile(markerPath, "", "utf8");
341
- return markerPath;
342
- }
343
- /**
344
- * Removes the `.vite-running` marker file.
345
- */
346
- async function removeViteRunningMarker(markerPath) {
347
- if (!markerPath) return;
348
- await fsp.rm(markerPath, { force: true });
349
- }
350
- /**
351
- * Checks if a directory is inside a Kirby plugin directory (`site/plugins/*`).
352
- * This is used to determine whether to create the `.vite-running` marker file,
353
- * which Kirby 6+ uses to detect development mode and load the development
354
- * build of Vue instead of the production build.
355
- */
356
- function isInsideKirbyPlugins(targetDir) {
357
- const initialDir = normalize(targetDir);
358
- let currentDir = initialDir;
359
- while (true) {
360
- const parentDir = dirname(currentDir);
361
- if (currentDir !== initialDir && isPathSegmentEqual(basename(currentDir), "plugins") && isPathSegmentEqual(basename(parentDir), "site")) return true;
362
- if (currentDir === parentDir) return false;
363
- currentDir = parentDir;
364
- }
365
- }
366
- /**
367
- * Performs case-insensitive comparison of path segments.
368
- */
369
- function isPathSegmentEqual(segment, expected) {
370
- return segment.toLowerCase() === expected;
312
+ function getDevBaseUrl(server, config) {
313
+ const { address, port } = server.httpServer.address();
314
+ const normalizedOrigin = ensureTrailingSlash(config.server?.origin ?? server.resolvedUrls?.local?.[0] ?? server.resolvedUrls?.network?.[0] ?? resolveOriginFromServerOptions(config.server, port, address));
315
+ const base = config.base ?? "/";
316
+ return new URL(base, normalizedOrigin).href;
371
317
  }
372
318
 
373
319
  //#endregion
@@ -390,6 +336,7 @@ async function printFileInfo({ root, outDir, filePath, content, type, maxLength
390
336
 
391
337
  //#endregion
392
338
  //#region src/node/index.ts
339
+ const DEV_OUTPUT_FILENAME = "index.dev.js";
393
340
  let resolvedKirbyupConfig;
394
341
  let resolvedPostCssConfig;
395
342
  const logLevel = "warn";
@@ -419,29 +366,26 @@ function getViteConfig(command, options) {
419
366
  };
420
367
  if (command === "serve") {
421
368
  const { port, watch } = options;
369
+ const inferredOrigin = userConfig.server?.origin ?? resolveOriginFromServerOptions(userConfig.server, port, "localhost");
422
370
  return mergeConfig(mergeConfig(sharedConfig, {
423
- plugins: [
424
- kirbyupHmrPlugin(options),
425
- kirbyupRunningMarkerPlugin({ outDir: options.outDir }),
426
- watch && fullReloadPlugin(watch)
427
- ].filter(Boolean),
371
+ plugins: [kirbyupHmrPlugin(options), watch && fullReloadPlugin(watch)].filter(Boolean),
428
372
  build: { rollupOptions: { input: resolve(options.cwd, options.entry) } },
429
373
  server: {
430
374
  port,
431
375
  strictPort: true,
432
- origin: `http://localhost:${port}`
376
+ origin: inferredOrigin
433
377
  }
434
378
  }), userConfig);
435
379
  }
436
380
  const mode = options.watch ? "development" : "production";
437
381
  return mergeConfig(mergeConfig(sharedConfig, {
438
382
  mode,
439
- plugins: [kirbyupBuildCleanupPlugin(options), options.watch && kirbyupRunningMarkerPlugin({ outDir: options.outDir })].filter(Boolean),
383
+ plugins: [kirbyupBuildCleanupPlugin(options)],
440
384
  build: {
441
385
  lib: {
442
386
  entry: resolve(options.cwd, options.entry),
443
387
  formats: ["es"],
444
- fileName: () => "index.js"
388
+ fileName: () => options.watch ? DEV_OUTPUT_FILENAME : "index.js"
445
389
  },
446
390
  minify: mode === "production",
447
391
  outDir: options.outDir,
@@ -492,33 +436,47 @@ async function build$1(options) {
492
436
  consola.log(colors.green(`${name} v${version}`));
493
437
  consola.start(`Building ${colors.cyan(options.entry)}`);
494
438
  if (options.watch) consola.info("Running in watch mode");
439
+ await generate(options);
440
+ consola.success("Build successful");
441
+ if (!options.watch) return;
442
+ const { watch } = await import("chokidar");
495
443
  const debouncedBuild = debounce(async () => {
496
444
  generate(options).catch(handleError);
497
445
  }, 100);
498
- const startWatcher = async () => {
499
- if (!options.watch) return;
500
- const { watch } = await import("chokidar");
501
- const ignored = ["**/{.git,node_modules}/**", "index.{css,js,mjs}"];
502
- const watchPaths = typeof options.watch === "boolean" ? dirname(options.entry) : Array.isArray(options.watch) ? options.watch.filter((path) => typeof path === "string") : options.watch;
503
- consola.info(`Watching for changes in ${toArray(watchPaths).map((i) => colors.cyan(i)).join(", ")}`);
504
- const watcher = watch(watchPaths, {
505
- ignoreInitial: true,
506
- ignorePermissionErrors: true,
507
- ignored,
508
- cwd
509
- });
510
- if (configFile) watcher.add(configFile);
511
- watcher.on("all", async (type, file) => {
512
- if (configFile === resolve(cwd, file)) {
513
- resolvedKirbyupConfig = (await loadConfig$1(cwd)).config ?? {};
514
- consola.info(`${colors.cyan(basename(file))} changed, setting new config`);
515
- } else consola.log(`${colors.green(type)} ${colors.white(colors.dim(file))}`);
516
- debouncedBuild();
517
- });
446
+ const ignored = [
447
+ "**/{.git,node_modules}/**",
448
+ "index.{css,js}",
449
+ DEV_OUTPUT_FILENAME
450
+ ];
451
+ const watchPaths = typeof options.watch === "boolean" ? dirname(options.entry) : Array.isArray(options.watch) ? options.watch.filter((path) => typeof path === "string") : options.watch;
452
+ consola.info(`Watching for changes in ${toArray(watchPaths).map((i) => colors.cyan(i)).join(", ")}`);
453
+ const watcher = watch(watchPaths, {
454
+ ignoreInitial: true,
455
+ ignorePermissionErrors: true,
456
+ ignored,
457
+ cwd
458
+ });
459
+ const devOutputPath = resolve(options.outDir, DEV_OUTPUT_FILENAME);
460
+ const cleanup = async () => {
461
+ await watcher.close().catch(() => {});
462
+ await fsp.rm(devOutputPath, { force: true }).catch(() => {});
518
463
  };
519
- await generate(options);
520
- consola.success("Build successful");
521
- startWatcher();
464
+ process.once("exit", () => {
465
+ try {
466
+ fs.rmSync(devOutputPath, { force: true });
467
+ } catch {}
468
+ });
469
+ const onShutdown = () => void cleanup().finally(() => process.exit(0));
470
+ process.once("SIGINT", onShutdown);
471
+ process.once("SIGTERM", onShutdown);
472
+ if (configFile) watcher.add(configFile);
473
+ watcher.on("all", async (type, file) => {
474
+ if (configFile === resolve(cwd, file)) {
475
+ resolvedKirbyupConfig = (await loadConfig$1(cwd)).config ?? {};
476
+ consola.info(`${colors.cyan(basename(file))} changed, setting new config`);
477
+ } else consola.log(`${colors.green(type)} ${colors.white(colors.dim(file))}`);
478
+ debouncedBuild();
479
+ });
522
480
  }
523
481
  async function serve(options) {
524
482
  assertEntryExists(options);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kirbyup",
3
3
  "type": "module",
4
- "version": "4.0.0-alpha.4",
4
+ "version": "4.0.0-alpha.5",
5
5
  "packageManager": "pnpm@10.25.0",
6
6
  "description": "Zero-config bundler for Kirby Panel plugins",
7
7
  "author": {