kirbyup 4.0.0-alpha.6 → 4.0.0-alpha.8

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 CHANGED
@@ -2,23 +2,31 @@
2
2
 
3
3
  # kirbyup
4
4
 
5
- The official bundler for Kirby Panel plugins with zero-config usage and built-in HMR.
5
+ The official bundler for Kirby Panel plugins. Zero-config, built-in HMR.
6
6
 
7
7
  - [✨  Release Notes](https://github.com/johannschopplich/kirbyup/releases)
8
8
  - [📖  Read the documentation](https://kirbyup.getkirby.com)
9
9
 
10
10
  ## Key Features
11
11
 
12
- - 🔄 [Hot module replacement](https://kirbyup.getkirby.com/guide/getting-started.html#development)
13
- - 🎒 PostCSS support
14
- - 🧭 Add custom path aliases
15
- - 🔌 Run actions based on environment variables
16
- - 🦔 [Extends Vite with `kirbyup.config.js`](https://kirbyup.getkirby.com/guide/config-file)
12
+ - 🔄 [Hot Module Replacement](https://kirbyup.getkirby.com/guide/getting-started.html#development)
13
+ - 🎒 [PostCSS & Sass](https://kirbyup.getkirby.com/guide/postcss)
14
+ - 🧩 [kirbyuse Integration](https://kirbyup.getkirby.com/guide/kirbyuse)
15
+ - 🔌 [Environment Variables](https://kirbyup.getkirby.com/guide/environment-variables)
16
+ - 🦔 [Configuration File](https://kirbyup.getkirby.com/guide/config-file)
17
+ - 🧭 [Path Aliases](https://kirbyup.getkirby.com/guide/path-aliases)
18
+
19
+ ## Requirements
20
+
21
+ - **Node.js 24+**: paired with a package manager (pnpm, npm, or yarn).
22
+ - **Kirby 6 or newer**: kirbyup 4.x targets the Vue 3-based Panel runtime introduced in Kirby 6. For Kirby 4 or 5 plugins, use kirbyup 3.x.
17
23
 
18
24
  ## Setup
19
25
 
20
26
  > [!TIP]
21
- > [📖 Read the documentation](https://kirbyup.getkirby.com)
27
+ > Skip starting from scratch and pick one of the following starters:
28
+ > - [`eslint`](./examples/eslint)
29
+ > - [`unocss`](./examples/unocss)
22
30
 
23
31
  ```bash
24
32
  # pnpm
@@ -26,16 +34,12 @@ pnpm add -D kirbyup
26
34
 
27
35
  # npm
28
36
  npm i -D kirbyup
29
- ```
30
37
 
31
- ## Basic Usage
32
-
33
- > [!TIP]
34
- > [📖 Read the documentation](https://kirbyup.getkirby.com) or skip starting from scratch and pick one of the following starters:
35
- > - [`eslint`](./examples/eslint)
36
- > - [`unocss`](./examples/unocss)
38
+ # yarn
39
+ yarn add -D kirbyup
40
+ ```
37
41
 
38
- Having installed kirbyup, you can add the following scripts as shortcuts to the commands you will use most often:
42
+ After installation, add these scripts to your `package.json`:
39
43
 
40
44
  ```json
41
45
  {
@@ -44,18 +48,18 @@ Having installed kirbyup, you can add the following scripts as shortcuts to the
44
48
  "build": "kirbyup src/index.js"
45
49
  },
46
50
  "devDependencies": {
47
- "kirbyup": "^3.4.0"
51
+ "kirbyup": "^4.0.0-alpha.6"
48
52
  }
49
53
  }
50
54
  ```
51
55
 
52
- ## 💻 Development
56
+ ## Development
53
57
 
54
58
  1. Clone this repository
55
59
  2. Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
56
60
  3. Install dependencies using `pnpm install`
57
- 4. Run `pnpm run dev:prepare`
58
- 5. Start development server using `pnpm run dev`
61
+ 4. Build with `pnpm run build`
62
+ 5. Run tests with `pnpm test`
59
63
 
60
64
  ## License
61
65
 
@@ -1,4 +1,4 @@
1
- import { r as UserConfig } from "../types-0NUTyTUQ.mjs";
1
+ import { r as UserConfig } from "../types-3hN383nZ.mjs";
2
2
 
3
3
  //#region src/client/config.d.ts
4
4
  declare function defineConfig(config: UserConfig): UserConfig;
@@ -8,6 +8,7 @@ const kirbyup = Object.freeze({
8
8
  * kirbyup.import('./components/blocks/*.vue')
9
9
  */
10
10
  import(glob) {
11
+ if (typeof glob === "string") throw new TypeError("[kirbyup] kirbyup.import() requires the kirbyup build pipeline. The call must be transformed at build time by the kirbyup:glob-import plugin.");
11
12
  return Object.entries(glob).reduce((accumulator, [path, component]) => {
12
13
  accumulator[getComponentName(path)] = component.default;
13
14
  return accumulator;
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-Do_IAs2E.mjs";
1
+ import { a as version, i as name, n as serve, r as handleError, t as build } from "../node-DFNV7EsB.mjs";
2
2
  import { cac } from "cac";
3
3
  //#region src/node/cli-start.ts
4
4
  async function startCli(cwd = process.cwd(), argv = process.argv) {
@@ -1,4 +1,4 @@
1
- import { n as ServeOptions, t as BuildOptions } from "../types-0NUTyTUQ.mjs";
1
+ import { n as ServeOptions, t as BuildOptions } from "../types-3hN383nZ.mjs";
2
2
  import { ViteDevServer } from "vite";
3
3
 
4
4
  //#region src/node/index.d.ts
@@ -1,2 +1,2 @@
1
- import { n as serve, t as build } from "../node-Do_IAs2E.mjs";
1
+ import { n as serve, t as build } from "../node-DFNV7EsB.mjs";
2
2
  export { build, serve };
@@ -1,25 +1,21 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as fsp from "node:fs/promises";
3
+ import { basename, dirname, relative, resolve } from "node:path";
3
4
  import vuePlugin from "@vitejs/plugin-vue";
4
5
  import vueJsxPlugin from "@vitejs/plugin-vue-jsx";
5
6
  import { consola } from "consola";
6
7
  import { colors } from "consola/utils";
7
- import { basename, dirname, normalize, relative, resolve } from "pathe";
8
8
  import { debounce } from "perfect-debounce";
9
- import { build, createLogger, createServer, mergeConfig, normalizePath } from "vite";
10
- import fullReloadPlugin from "vite-plugin-full-reload";
11
- import * as vueCompilerSfc from "vue/compiler-sfc";
9
+ import { build, createFilter, createLogger, createServer, mergeConfig, normalizePath } from "vite";
12
10
  import { loadConfig } from "c12";
13
- import postcssrc from "postcss-load-config";
14
- import { fileURLToPath, pathToFileURL } from "node:url";
15
- import { detectPackageManager } from "nypm";
11
+ import postcssrcLoad from "postcss-load-config";
12
+ import { gzipSync } from "node:zlib";
13
+ import MagicString from "magic-string";
14
+ import { stripLiteral } from "strip-literal";
16
15
  import { isIP } from "node:net";
17
- import { Buffer } from "node:buffer";
18
- import { promisify } from "node:util";
19
- import { gzip } from "node:zlib";
20
16
  //#region package.json
21
17
  var name = "kirbyup";
22
- var version = "4.0.0-alpha.6";
18
+ var version = "4.0.0-alpha.8";
23
19
  //#endregion
24
20
  //#region src/node/config.ts
25
21
  function loadConfig$1(cwd = process.cwd()) {
@@ -32,7 +28,7 @@ function loadConfig$1(cwd = process.cwd()) {
32
28
  }
33
29
  async function resolvePostCSSConfig(cwd) {
34
30
  try {
35
- return await postcssrc(void 0, void 0, { stopDir: cwd });
31
+ return await postcssrcLoad(void 0, void 0, { stopDir: cwd });
36
32
  } catch (error) {
37
33
  if (!error.message.includes("No PostCSS Config found")) throw error;
38
34
  }
@@ -43,8 +39,7 @@ var PrettyError = class extends Error {
43
39
  constructor(message) {
44
40
  super(message);
45
41
  this.name = this.constructor.name;
46
- if (typeof Error.captureStackTrace === "function") Error.captureStackTrace(this, this.constructor);
47
- else this.stack = new Error(message).stack;
42
+ Error.captureStackTrace(this, this.constructor);
48
43
  }
49
44
  };
50
45
  function handleError(error) {
@@ -69,14 +64,93 @@ function kirbyupBuildCleanupPlugin(options) {
69
64
  };
70
65
  }
71
66
  //#endregion
67
+ //#region src/node/utils.ts
68
+ function toArray(array) {
69
+ array ??= [];
70
+ return Array.isArray(array) ? array : [array];
71
+ }
72
+ async function printFileInfo({ root, outDir, filePath, content, type, maxLength }) {
73
+ const prettyOutDir = `${normalizePath(relative(root, outDir))}/`;
74
+ const kibs = content.length / 1024;
75
+ const compressedKibs = gzipSync(content).length / 1024;
76
+ const writeColor = type === "chunk" ? colors.cyan : colors.magenta;
77
+ consola.log(colors.white(colors.dim(prettyOutDir)) + writeColor(filePath.padEnd(maxLength + 2)) + colors.dim(`${kibs.toFixed(2)} kB / gzip: ${compressedKibs.toFixed(2)} KiB`));
78
+ }
79
+ //#endregion
80
+ //#region src/node/plugins/full-reload.ts
81
+ /**
82
+ * Triggers a full browser reload when files matching the given globs change.
83
+ * Vite forces chokidar's `disableGlobbing: true` by default; this plugin
84
+ * resets it so glob strings passed to `watcher.add` are expanded by chokidar.
85
+ */
86
+ function kirbyupFullReloadPlugin(paths) {
87
+ return {
88
+ name: "kirbyup:full-reload",
89
+ apply: "serve",
90
+ config() {
91
+ return { server: { watch: { disableGlobbing: false } } };
92
+ },
93
+ configureServer({ watcher, ws, config: { root, logger } }) {
94
+ const files = toArray(paths).map((p) => resolve(root, p));
95
+ const matches = createFilter(files);
96
+ watcher.add(files);
97
+ const reload = (path) => {
98
+ if (!matches(path)) return;
99
+ setTimeout(() => ws.send({
100
+ type: "full-reload",
101
+ path: "*"
102
+ }), 0);
103
+ logger.info(`${colors.green("full reload")} ${colors.dim(normalizePath(relative(root, path)))}`, {
104
+ clear: true,
105
+ timestamp: true
106
+ });
107
+ };
108
+ watcher.on("add", reload);
109
+ watcher.on("change", reload);
110
+ }
111
+ };
112
+ }
113
+ //#endregion
114
+ //#region src/node/plugins/glob-import.ts
115
+ /**
116
+ * Transforms `kirbyup.import(<path>)` to `kirbyup.import(import.meta.glob(<path>, { eager: true }))`.
117
+ *
118
+ * Must run before Vite's own `import.meta.glob` plugin (also `enforce: 'pre'`),
119
+ * otherwise the emitted call is never expanded.
120
+ */
121
+ function kirbyupGlobImportPlugin() {
122
+ let config;
123
+ return {
124
+ name: "kirbyup:glob-import",
125
+ enforce: "pre",
126
+ configResolved(resolvedConfig) {
127
+ config = resolvedConfig;
128
+ },
129
+ transform(code) {
130
+ if (!code.includes("kirbyup.import")) return;
131
+ const kirbyupImportRE = /\bkirbyup\.import\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*\)/dg;
132
+ const cleanCode = stripLiteral(code);
133
+ let s;
134
+ for (const match of cleanCode.matchAll(kirbyupImportRE)) {
135
+ const { 0: exp, index } = match;
136
+ const [argStart, argEnd] = match.indices[1];
137
+ const rawPath = code.slice(argStart, argEnd);
138
+ if (!s) s = new MagicString(code);
139
+ s.overwrite(index, index + exp.length, `kirbyup.import(import.meta.glob(${rawPath}, { eager: true }))`);
140
+ }
141
+ if (s) return {
142
+ code: s.toString(),
143
+ map: config.build.sourcemap ? s.generateMap({ hires: true }) : void 0
144
+ };
145
+ }
146
+ };
147
+ }
148
+ //#endregion
72
149
  //#region src/node/utils/server.ts
73
150
  function resolveOriginFromServerOptions(serverOptions, port, fallbackHostname) {
74
151
  const protocol = serverOptions?.https && (typeof serverOptions.https === "boolean" || Object.keys(serverOptions.https).length > 0) ? "https" : "http";
75
152
  const configuredHost = normalizeHost(serverOptions?.host);
76
- return `${protocol}://${formatHostname(configuredHost || fallbackHostname || "localhost")}${(configuredHost ? hostIncludesPort(configuredHost) : false) || !needsExplicitPort(protocol, port) ? "" : `:${port}`}`;
77
- }
78
- function ensureTrailingSlash(url) {
79
- return url.endsWith("/") ? url : `${url}/`;
153
+ return `${protocol}://${formatHostname(configuredHost || fallbackHostname || "localhost")}${(configuredHost ? hostIncludesPort(configuredHost) : false) || protocol === "http" && port === 80 || protocol === "https" && port === 443 ? "" : `:${port}`}`;
80
154
  }
81
155
  function normalizeHost(host) {
82
156
  if (host === false || host === void 0) return;
@@ -96,13 +170,9 @@ function hostIncludesPort(host) {
96
170
  if (isIP(host) === 6) return false;
97
171
  return host.includes(":");
98
172
  }
99
- function needsExplicitPort(protocol, port) {
100
- if (protocol === "http") return port !== 80;
101
- return port !== 443;
102
- }
103
173
  //#endregion
104
174
  //#region src/node/plugins/runtime/hmr-shim.js?raw
105
- var hmr_shim_default = "/* eslint-disable no-undef */\nimport 'vue'\n\nif (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {\n const originalReload = __VUE_HMR_RUNTIME__.reload\n\n __VUE_HMR_RUNTIME__.reload = function (id, newComp) {\n const plugins = window.panel && window.panel.plugins\n const app = window.panel && window.panel.app\n\n if (\n plugins\n && app\n && plugins.components\n && typeof plugins.resolveComponentExtension === 'function'\n && typeof plugins.resolveComponentRender === 'function'\n && typeof plugins.resolveComponentMixins === 'function'\n ) {\n for (const name in plugins.components) {\n const pluginComp = plugins.components[name]\n if (\n pluginComp.__hmrId === id\n || (newComp.__file && pluginComp.__file === newComp.__file)\n ) {\n plugins.resolveComponentExtension(app, name, newComp)\n plugins.resolveComponentRender(newComp)\n plugins.resolveComponentMixins(newComp)\n break\n }\n }\n }\n\n return originalReload.call(this, id, newComp)\n }\n}\nelse {\n console.warn(\n '[kirbyup] Vue HMR runtime not detected; component changes will fall back to full page reload. The Kirby Panel may be loading a production build of Vue.',\n )\n}\n";
175
+ var hmr_shim_default = "/* eslint-disable no-undef */\nimport 'vue'\n\nif (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {\n const originalReload = __VUE_HMR_RUNTIME__.reload\n\n __VUE_HMR_RUNTIME__.reload = function (id, newComp) {\n const { plugins, app } = window.panel ?? {}\n\n if (plugins?.components) {\n for (const [name, pluginComp] of Object.entries(plugins.components)) {\n if (\n pluginComp.__hmrId === id\n || (newComp.__file && pluginComp.__file === newComp.__file)\n ) {\n plugins.resolveComponentExtension(app, name, newComp)\n plugins.resolveComponentRender(newComp)\n plugins.resolveComponentMixins(newComp)\n break\n }\n }\n }\n\n return originalReload(id, newComp)\n }\n}\nelse {\n console.warn(\n '[kirbyup] Vue HMR runtime not detected; component changes will fall back to full page reload. The Kirby Panel may be loading a production build of Vue.',\n )\n}\n";
106
176
  //#endregion
107
177
  //#region src/node/plugins/runtime/vue-stub.js?raw
108
178
  var vue_stub_default = "const __kirbyupVueImportMapEl = typeof document !== 'undefined'\n ? document.querySelector('script[type=\"importmap\"]')\n : null\nconst __kirbyupVueImports = __kirbyupVueImportMapEl\n ? (() => {\n try {\n return JSON.parse(__kirbyupVueImportMapEl.textContent || '{}').imports || {}\n }\n // eslint-disable-next-line unused-imports/no-unused-vars\n catch (_) {\n return {}\n }\n })()\n : {}\nconst __kirbyupVueUrl = __kirbyupVueImports.vue\nif (!__kirbyupVueUrl) {\n throw new Error(\n '[kirbyup] No \"vue\" entry found in the page <script type=\"importmap\">. Ensure Kirby\\'s Panel is loaded with v6 import maps enabled.',\n )\n}\n// eslint-disable-next-line no-unused-vars, antfu/no-top-level-await\nconst __kirbyupVueModule = await import(/* @vite-ignore */ __kirbyupVueUrl)\n";
@@ -118,21 +188,6 @@ var vue_stub_default = "const __kirbyupVueImportMapEl = typeof document !== 'und
118
188
  */
119
189
  const __HMR_SHIM_CODE__ = hmr_shim_default;
120
190
  /**
121
- * Extract public named exports from a Rollup-style ESM bundle. Vue's
122
- * `dist/vue.esm-browser.js` ships a single trailing `export { ... }` block
123
- * with a few `internalName as publicName` aliases.
124
- *
125
- * Only the last block is read; `as`-aliased entries yield the public name.
126
- */
127
- function extractEsmNamedExports(source) {
128
- const blockMatches = [...source.matchAll(/export\s*\{([^}]*)\}/g)];
129
- if (blockMatches.length === 0) return [];
130
- return blockMatches.at(-1)[1].split(",").map((entry) => entry.trim()).filter(Boolean).map((entry) => {
131
- const aliasMatch = entry.match(/^\S+\s+as\s+(\S+)$/);
132
- return aliasMatch ? aliasMatch[1] : entry;
133
- });
134
- }
135
- /**
136
191
  * Reads Kirby's panel-vue URL at runtime from the page's
137
192
  * `<script type="importmap">` and dynamic-imports it; the browser's module
138
193
  * map dedups by URL, so plugin SFCs share Kirby's Vue instance (and
@@ -141,7 +196,11 @@ function extractEsmNamedExports(source) {
141
196
  */
142
197
  function buildVueStubCode(namedExports) {
143
198
  if (namedExports.length === 0) return vue_stub_default;
144
- return vue_stub_default + `\nexport const {\n${namedExports.map((name) => ` ${name},`).join("\n")}\n} = __kirbyupVueModule\n`;
199
+ return [vue_stub_default, `
200
+ export const {
201
+ ${namedExports.map((name) => ` ${name},`).join("\n")}
202
+ } = __kirbyupVueModule
203
+ `.trimStart()].join("\n");
145
204
  }
146
205
  //#endregion
147
206
  //#region src/node/plugins/hmr.ts
@@ -149,7 +208,7 @@ const SHIM_ID = "\0kirbyup:hmr-shim";
149
208
  const SHIM_PUBLIC_ID = SHIM_ID.slice(1);
150
209
  const VUE_STUB_ID = "\0kirbyup:vue-stub";
151
210
  const VUE_STUB_PUBLIC_ID = VUE_STUB_ID.slice(1);
152
- const VUE_NOT_FOUND_STUB = `throw new Error('[kirbyup] Cannot resolve "vue/dist/vue.esm-browser.js" from the plugin project. Make sure "vue" is installed as a dependency.')\n`;
211
+ const VUE_NOT_FOUND_STUB = `throw new Error('[kirbyup] Cannot resolve "vue" from the plugin project. Make sure "vue" is installed as a dependency.')\n`;
153
212
  function kirbyupHmrPlugin(options) {
154
213
  let config;
155
214
  let entry;
@@ -169,14 +228,14 @@ function kirbyupHmrPlugin(options) {
169
228
  }] }
170
229
  };
171
230
  },
172
- configResolved(resolvedConfig) {
231
+ async configResolved(resolvedConfig) {
173
232
  config = resolvedConfig;
174
233
  entry = resolve(config.root, options.entry);
175
234
  entryId = normalizePath(entry);
176
235
  devIndexPath = resolve(config.root, options.outDir ?? "", "index.dev.js");
177
236
  try {
178
- const vueUrl = import.meta.resolve("vue/dist/vue.esm-browser.js", pathToFileURL(`${config.root}/_`).href);
179
- const namedExports = extractEsmNamedExports(fs.readFileSync(fileURLToPath(vueUrl), "utf8"));
237
+ const vueModule = await import("vue");
238
+ const namedExports = Object.keys(vueModule).filter((name) => name !== "default" && /^[A-Z_$][\w$]*$/i.test(name));
180
239
  vueStubCode = namedExports.length > 0 ? buildVueStubCode(namedExports) : void 0;
181
240
  } catch {
182
241
  vueStubCode = void 0;
@@ -212,7 +271,7 @@ function kirbyupHmrPlugin(options) {
212
271
  const entryPath = entry.replace(`${config.root}/`, "");
213
272
  const baseUrl = getDevBaseUrl(server, config);
214
273
  const entryUrl = new URL(entryPath, baseUrl).href;
215
- const pm = await detectPackageManager(config.root);
274
+ const pm = detectPackageManager(config.root);
216
275
  await fsp.writeFile(devIndexPath, getViteProxyModule(entryUrl, pm));
217
276
  });
218
277
  },
@@ -222,13 +281,12 @@ function kirbyupHmrPlugin(options) {
222
281
  };
223
282
  }
224
283
  function getViteProxyModule(entryUrl, packageManager) {
225
- const pm = packageManager?.name || "npm";
226
284
  return `
227
285
  try {
228
286
  await import("${entryUrl}");
229
287
  } catch (error) {
230
288
  console.error(
231
- "[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."
289
+ "[kirbyup] Couldn't connect to the development server at ${entryUrl}. Run \`${packageManager} run serve\` to start Vite or build the plugin with \`${packageManager} run build\` so Kirby uses the production version."
232
290
  );
233
291
  throw error;
234
292
  }
@@ -236,42 +294,25 @@ try {
236
294
  }
237
295
  function getDevBaseUrl(server, config) {
238
296
  const { address, port } = server.httpServer.address();
239
- const normalizedOrigin = ensureTrailingSlash(config.server?.origin ?? server.resolvedUrls?.local?.[0] ?? server.resolvedUrls?.network?.[0] ?? resolveOriginFromServerOptions(config.server, port, address));
297
+ const origin = config.server?.origin ?? server.resolvedUrls?.local?.[0] ?? server.resolvedUrls?.network?.[0] ?? resolveOriginFromServerOptions(config.server, port, address);
240
298
  const base = config.base ?? "/";
241
- return new URL(base, normalizedOrigin).href;
242
- }
243
- //#endregion
244
- //#region src/node/utils.ts
245
- const compress = promisify(gzip);
246
- function toArray(array) {
247
- array ??= [];
248
- return Array.isArray(array) ? array : [array];
299
+ return new URL(base, origin).href;
249
300
  }
250
- async function getCompressedSize(code) {
251
- return ` / gzip: ${((await compress(typeof code === "string" ? code : Buffer.from(code))).length / 1024).toFixed(2)} KiB`;
252
- }
253
- async function printFileInfo({ root, outDir, filePath, content, type, maxLength }) {
254
- const prettyOutDir = `${normalize(relative(root, resolve(root, outDir)))}/`;
255
- const kibs = content.length / 1024;
256
- const compressedSize = await getCompressedSize(content);
257
- const writeColor = type === "chunk" ? colors.cyan : colors.magenta;
258
- consola.log(colors.white(colors.dim(prettyOutDir)) + writeColor(filePath.padEnd(maxLength + 2)) + colors.dim(`${kibs.toFixed(2)} kB${compressedSize}`));
301
+ function detectPackageManager(cwd) {
302
+ if (fs.existsSync(resolve(cwd, "pnpm-lock.yaml"))) return "pnpm";
303
+ if (fs.existsSync(resolve(cwd, "bun.lock")) || fs.existsSync(resolve(cwd, "bun.lockb"))) return "bun";
304
+ if (fs.existsSync(resolve(cwd, "yarn.lock"))) return "yarn";
305
+ if (fs.existsSync(resolve(cwd, "deno.lock"))) return "deno";
306
+ return "npm";
259
307
  }
260
308
  //#endregion
261
309
  //#region src/node/index.ts
262
310
  const DEV_OUTPUT_FILENAME = "index.dev.js";
263
- let resolvedKirbyupConfig;
264
- let resolvedPostCssConfig;
311
+ const SUPPRESSED_WARNING_PREFIX = "\n(!) build.outDir";
265
312
  const logLevel = "warn";
266
- const logger = createLogger(logLevel);
267
- const loggerWarn = logger.warn;
268
- logger.warn = (msg, options) => {
269
- if (msg.includes("(!) build.outDir")) return;
270
- loggerWarn(msg, options);
271
- };
272
- function getViteConfig(command, options) {
313
+ function getViteConfig(command, options, { kirbyupConfig, postCssConfig, logger }) {
273
314
  const aliasDir = resolve(options.cwd, dirname(options.entry));
274
- const { alias = {}, vite } = resolvedKirbyupConfig;
315
+ const { alias = {}, vite } = kirbyupConfig;
275
316
  const userConfig = vite ?? {};
276
317
  const sharedConfig = {
277
318
  resolve: { alias: {
@@ -279,9 +320,16 @@ function getViteConfig(command, options) {
279
320
  "@/": `${aliasDir}/`,
280
321
  ...alias
281
322
  } },
282
- plugins: [vuePlugin({ compiler: vueCompilerSfc }), vueJsxPlugin()],
323
+ plugins: [
324
+ vuePlugin(),
325
+ vueJsxPlugin(),
326
+ kirbyupGlobImportPlugin()
327
+ ],
283
328
  build: { copyPublicDir: false },
284
- ...resolvedPostCssConfig && { css: { postcss: resolvedPostCssConfig } },
329
+ ...postCssConfig && { css: { postcss: {
330
+ ...postCssConfig.options,
331
+ plugins: postCssConfig.plugins
332
+ } } },
285
333
  envDir: options.cwd,
286
334
  envPrefix: ["VITE_", "KIRBYUP_"],
287
335
  customLogger: logger,
@@ -291,7 +339,7 @@ function getViteConfig(command, options) {
291
339
  const { port, watch } = options;
292
340
  const inferredOrigin = userConfig.server?.origin ?? resolveOriginFromServerOptions(userConfig.server, port, "localhost");
293
341
  return mergeConfig(mergeConfig(sharedConfig, {
294
- plugins: [kirbyupHmrPlugin(options), watch && fullReloadPlugin(watch)].filter(Boolean),
342
+ plugins: [kirbyupHmrPlugin(options), watch && kirbyupFullReloadPlugin(watch)].filter(Boolean),
295
343
  build: { rollupOptions: { input: resolve(options.cwd, options.entry) } },
296
344
  server: {
297
345
  port,
@@ -321,58 +369,55 @@ function getViteConfig(command, options) {
321
369
  }
322
370
  }), userConfig);
323
371
  }
324
- async function generate(options) {
325
- const config = getViteConfig("build", options);
372
+ async function generate(options, context) {
373
+ const config = getViteConfig("build", options, context);
326
374
  let result;
327
375
  try {
328
376
  result = await build(config);
329
377
  } catch (error) {
330
- if (config.mode === "production") throw error;
331
- else consola.error(error);
378
+ if (!options.watch) throw error;
379
+ consola.error(error);
332
380
  }
333
- if (result && !options.watch) {
334
- const { output } = toArray(result)[0];
335
- let maxLength = 0;
336
- for (const chunkFile in output) {
337
- const fileNameLength = output[chunkFile].fileName.length;
338
- if (fileNameLength > maxLength) maxLength = fileNameLength;
339
- }
340
- for (const { fileName, type, code } of output) {
341
- const content = code || await fsp.readFile(resolve(options.outDir, fileName), "utf8");
342
- await printFileInfo({
343
- root: options.cwd,
344
- outDir: options.outDir,
345
- filePath: fileName,
346
- content,
347
- type,
348
- maxLength
349
- });
350
- }
381
+ if (!result || options.watch) return;
382
+ const { output } = toArray(result)[0];
383
+ const maxLength = Math.max(0, ...output.map((item) => item.fileName.length));
384
+ for (const item of output) {
385
+ const content = item.type === "chunk" ? item.code : await fsp.readFile(resolve(options.outDir, item.fileName), "utf8");
386
+ await printFileInfo({
387
+ root: options.cwd,
388
+ outDir: options.outDir,
389
+ filePath: item.fileName,
390
+ content,
391
+ type: item.type,
392
+ maxLength
393
+ });
351
394
  }
352
- return result;
353
395
  }
354
396
  async function build$1(options) {
355
397
  assertEntryExists(options);
356
398
  const { cwd } = options;
357
399
  const { config, configFile } = await loadConfig$1(cwd);
358
- resolvedKirbyupConfig = config ?? {};
359
- resolvedPostCssConfig = await resolvePostCSSConfig(cwd);
400
+ const postCssConfig = await resolvePostCSSConfig(cwd);
401
+ const context = {
402
+ kirbyupConfig: config ?? {},
403
+ postCssConfig,
404
+ logger: createKirbyupLogger()
405
+ };
360
406
  consola.log(colors.green(`${name} v${version}`));
361
407
  consola.start(`Building ${colors.cyan(options.entry)}`);
362
- if (options.watch) consola.info("Running in watch mode");
363
- await generate(options);
408
+ await generate(options, context);
364
409
  consola.success("Build successful");
365
410
  if (!options.watch) return;
366
411
  const { watch } = await import("chokidar");
367
- const debouncedBuild = debounce(async () => {
368
- generate(options).catch(handleError);
412
+ const debouncedBuild = debounce(() => {
413
+ generate(options, context).catch(handleError);
369
414
  }, 100);
370
415
  const ignored = [
371
416
  "**/{.git,node_modules}/**",
372
417
  "index.{css,js}",
373
418
  DEV_OUTPUT_FILENAME
374
419
  ];
375
- const watchPaths = typeof options.watch === "boolean" ? dirname(options.entry) : Array.isArray(options.watch) ? options.watch.filter((path) => typeof path === "string") : options.watch;
420
+ const watchPaths = options.watch === true ? dirname(options.entry) : toArray(options.watch);
376
421
  consola.info(`Watching for changes in ${toArray(watchPaths).map((i) => colors.cyan(i)).join(", ")}`);
377
422
  const watcher = watch(watchPaths, {
378
423
  ignoreInitial: true,
@@ -390,13 +435,15 @@ async function build$1(options) {
390
435
  fs.rmSync(devOutputPath, { force: true });
391
436
  } catch {}
392
437
  });
393
- const onShutdown = () => void cleanup().finally(() => process.exit(0));
438
+ const onShutdown = () => {
439
+ cleanup().finally(() => process.exit(0));
440
+ };
394
441
  process.once("SIGINT", onShutdown);
395
442
  process.once("SIGTERM", onShutdown);
396
443
  if (configFile) watcher.add(configFile);
397
444
  watcher.on("all", async (type, file) => {
398
445
  if (configFile === resolve(cwd, file)) {
399
- resolvedKirbyupConfig = (await loadConfig$1(cwd)).config ?? {};
446
+ context.kirbyupConfig = (await loadConfig$1(cwd)).config ?? {};
400
447
  consola.info(`${colors.cyan(basename(file))} changed, setting new config`);
401
448
  } else consola.log(`${colors.green(type)} ${colors.white(colors.dim(file))}`);
402
449
  debouncedBuild();
@@ -406,15 +453,29 @@ async function serve(options) {
406
453
  assertEntryExists(options);
407
454
  const { cwd } = options;
408
455
  const { config } = await loadConfig$1(cwd);
409
- resolvedKirbyupConfig = config ?? {};
410
- resolvedPostCssConfig = await resolvePostCSSConfig(cwd);
456
+ const postCssConfig = await resolvePostCSSConfig(cwd);
457
+ const context = {
458
+ kirbyupConfig: config ?? {},
459
+ postCssConfig,
460
+ logger: createKirbyupLogger()
461
+ };
411
462
  consola.log(colors.green(`${name} v${version}`));
412
463
  consola.info("Starting development server…");
413
- const server = await createServer(getViteConfig("serve", options));
464
+ const server = await createServer(getViteConfig("serve", options, context));
414
465
  await server.listen();
415
466
  consola.success(`Server is listening on :${server.config.server.port}`);
416
467
  return server;
417
468
  }
469
+ function createKirbyupLogger() {
470
+ const baseLogger = createLogger(logLevel);
471
+ return {
472
+ ...baseLogger,
473
+ warn(msg, options) {
474
+ if (msg.startsWith(SUPPRESSED_WARNING_PREFIX)) return;
475
+ baseLogger.warn(msg, options);
476
+ }
477
+ };
478
+ }
418
479
  function assertEntryExists(options) {
419
480
  if (!fs.existsSync(resolve(options.cwd, options.entry))) throw new PrettyError(`Cannot find "${options.entry}"`);
420
481
  }
@@ -1,4 +1,5 @@
1
1
  import { AliasOptions, InlineConfig } from "vite";
2
+
2
3
  //#region src/node/types.d.ts
3
4
  interface BaseOptions {
4
5
  cwd: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kirbyup",
3
3
  "type": "module",
4
- "version": "4.0.0-alpha.6",
4
+ "version": "4.0.0-alpha.8",
5
5
  "packageManager": "pnpm@10.33.3",
6
6
  "description": "Zero-config bundler for Kirby Panel plugins",
7
7
  "author": {
@@ -39,16 +39,6 @@
39
39
  }
40
40
  },
41
41
  "types": "./dist/node/index.d.mts",
42
- "typesVersions": {
43
- "*": {
44
- "config": [
45
- "./dist/client/config.d.mts"
46
- ],
47
- "plugin": [
48
- "./dist/client/plugin.d.mts"
49
- ]
50
- }
51
- },
52
42
  "bin": {
53
43
  "kirbyup": "bin/kirbyup.mjs"
54
44
  },
@@ -73,20 +63,17 @@
73
63
  "dependencies": {
74
64
  "@vitejs/plugin-vue": "^6.0.6",
75
65
  "@vitejs/plugin-vue-jsx": "^5.1.5",
76
- "@vue/compiler-sfc": "^3.5.34",
77
66
  "c12": "^4.0.0-beta.4",
78
67
  "cac": "^7.0.0",
79
68
  "chokidar": "^5.0.0",
80
69
  "consola": "^3.4.2",
81
70
  "magic-string": "^0.30.21",
82
- "nypm": "^0.6.6",
83
- "pathe": "^2.0.3",
84
71
  "perfect-debounce": "^2.1.0",
85
72
  "postcss": "^8.5.14",
86
73
  "postcss-load-config": "^6.0.1",
87
74
  "sass": "^1.99.0",
75
+ "strip-literal": "^3.1.0",
88
76
  "vite": "^8.0.10",
89
- "vite-plugin-full-reload": "^1.2.0",
90
77
  "vue": "^3.5.34"
91
78
  },
92
79
  "devDependencies": {
@@ -95,7 +82,6 @@
95
82
  "bumpp": "^11.0.1",
96
83
  "eslint": "^10.3.0",
97
84
  "eslint-flat-config-utils": "^3.2.0",
98
- "tinyglobby": "^0.2.16",
99
85
  "tsdown": "^0.21.10",
100
86
  "typescript": "^6.0.3",
101
87
  "unplugin-raw": "^0.7.0",