@konomi-app/k2 2.1.5 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,123 +1,47 @@
1
1
  #!/usr/bin/env node
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
2
8
 
3
9
  // src/index.ts
4
10
  import { program as program6 } from "commander";
5
11
 
6
12
  // src/commands/build.ts
7
13
  import { program } from "commander";
8
- import fs2 from "fs-extra";
14
+ import fs3 from "fs-extra";
9
15
  import path6 from "path";
16
+ import chalk2 from "chalk";
10
17
 
11
18
  // src/lib/constants.ts
12
19
  import path from "path";
13
20
  var WORKSPACE_DIRECTORY = ".k2";
14
21
  var DEVELOPMENT_DIRECTORY = path.join(WORKSPACE_DIRECTORY, "dev");
22
+ var PRODUCTION_DIRECTORY = path.join(WORKSPACE_DIRECTORY, "prod");
15
23
  var CONFIG_FILE_NAME = "k2.config.mjs";
16
24
  var PLUGIN_WORKSPACE_DIRECTORY = ".plugin";
17
25
  var PLUGIN_CONTENTS_DIRECTORY = path.join(PLUGIN_WORKSPACE_DIRECTORY, "contents");
18
26
  var PLUGIN_DEVELOPMENT_DIRECTORY = path.join(PLUGIN_WORKSPACE_DIRECTORY, "dev");
27
+ var PLUGIN_PRODUCTION_DIRECTORY = path.join(PLUGIN_WORKSPACE_DIRECTORY, "prod");
19
28
  var DEFAULT_PORT = 32767;
20
29
 
21
- // src/commands/build-base.ts
22
- import "webpack";
23
-
24
- // src/lib/webpack.ts
25
- import MiniCssExtractPlugin from "mini-css-extract-plugin";
26
- import path2 from "path";
27
- import { cwd } from "process";
28
- import TerserPlugin from "terser-webpack-plugin";
29
- import webpack from "webpack";
30
- import chalk from "chalk";
31
- import { TsconfigPathsPlugin } from "tsconfig-paths-webpack-plugin";
32
- var buildWithWebpack = async (props) => {
33
- const { entries, outDir } = props;
34
- const exclude = /node_modules/;
35
- const styleLoader = MiniCssExtractPlugin.loader;
36
- const tsConfigPath = path2.join(cwd(), "tsconfig.json");
37
- console.group(chalk.blue("\u{1F680} Building with Webpack..."));
38
- console.log("\u{1F527} tsconfig.json path:", tsConfigPath);
39
- console.groupEnd();
40
- return new Promise((resolve, reject) => {
41
- webpack(
42
- {
43
- mode: "production",
44
- target: ["web", "es2023"],
45
- entry: entries,
46
- resolve: {
47
- extensions: [".ts", ".tsx", ".js", ".json"],
48
- fallback: {
49
- path: false
50
- },
51
- plugins: [new TsconfigPathsPlugin({ configFile: tsConfigPath })]
52
- },
53
- cache: { type: "filesystem" },
54
- output: { filename: "[name].js", path: path2.resolve(outDir) },
55
- module: {
56
- rules: [
57
- { test: /\.tsx?$/, exclude, loader: "ts-loader" },
58
- { test: /\.css$/, use: [styleLoader, "css-loader"] },
59
- {
60
- test: /\.scss$/,
61
- use: [
62
- styleLoader,
63
- "css-loader",
64
- { loader: "sass-loader", options: { sassOptions: { outputStyle: "expanded" } } }
65
- ]
66
- }
67
- ]
68
- },
69
- plugins: [new MiniCssExtractPlugin()],
70
- optimization: {
71
- minimize: true,
72
- minimizer: [
73
- new TerserPlugin({
74
- terserOptions: { format: { comments: false } },
75
- extractComments: false
76
- })
77
- ]
78
- }
79
- },
80
- (err, stats) => {
81
- if (err) {
82
- reject(err);
83
- } else {
84
- if (stats?.compilation.errors.length) {
85
- reject(
86
- [
87
- chalk.red("\u26A0 Build failed."),
88
- ...stats.compilation.errors.map((error) => error.message)
89
- ].join("\n")
90
- );
91
- } else {
92
- resolve();
93
- }
94
- }
95
- }
96
- );
97
- });
98
- };
99
-
100
- // src/commands/build-base.ts
101
- async function action(params) {
102
- const { entries, outDir } = params;
103
- return buildWithWebpack({ entries, outDir });
104
- }
105
-
106
30
  // src/commands/build-tailwind.ts
107
- import path5 from "path";
31
+ import path4 from "path";
108
32
 
109
33
  // src/lib/import.ts
110
34
  import { pathToFileURL } from "url";
111
- import path3 from "path";
112
- var esmImport = (path12) => {
35
+ import path2 from "path";
36
+ var esmImport = (path11) => {
113
37
  if (process.platform === "win32") {
114
- return import(pathToFileURL(path12).toString());
38
+ return import(pathToFileURL(path11).toString());
115
39
  } else {
116
- return import(path12);
40
+ return import(path11);
117
41
  }
118
42
  };
119
43
  var importK2Config = async (configFileName) => {
120
- return (await esmImport(path3.resolve(configFileName ?? CONFIG_FILE_NAME))).default;
44
+ return (await esmImport(path2.resolve(configFileName ?? CONFIG_FILE_NAME))).default;
121
45
  };
122
46
 
123
47
  // src/lib/tailwind.ts
@@ -125,14 +49,14 @@ import chokidar from "chokidar";
125
49
  import cssnanoPlugin from "cssnano";
126
50
  import fs from "fs-extra";
127
51
  import { glob } from "glob";
128
- import path4 from "path";
52
+ import path3 from "path";
129
53
  import postcss from "postcss";
130
54
  import { debounce } from "remeda";
131
55
  import tailwindcss from "tailwindcss";
132
56
  import invariant from "tiny-invariant";
133
57
  var getTailwindConfigFromK2Config = async (k2Config) => {
134
58
  invariant(k2Config?.config, "tailwind.config is required");
135
- const config = (await esmImport(path4.resolve(k2Config?.config))).default;
59
+ const config = (await esmImport(path3.resolve(k2Config?.config))).default;
136
60
  return config;
137
61
  };
138
62
  var outputCss = async (params) => {
@@ -177,16 +101,16 @@ var watchTailwindCSS = async (params) => {
177
101
  watcher.on("error", (error) => {
178
102
  console.error("Error watching Tailwind CSS:", error);
179
103
  });
180
- watcher.on("add", (path12) => {
104
+ watcher.on("add", (path11) => {
181
105
  debouncedProcessChanges.call("add");
182
106
  });
183
- watcher.on("change", (path12) => {
107
+ watcher.on("change", (path11) => {
184
108
  debouncedProcessChanges.call("change");
185
109
  });
186
- watcher.on("unlink", (path12) => {
110
+ watcher.on("unlink", (path11) => {
187
111
  debouncedProcessChanges.call("unlink");
188
112
  });
189
- watcher.on("unlinkDir", (path12) => {
113
+ watcher.on("unlinkDir", (path11) => {
190
114
  debouncedProcessChanges.call("unlink");
191
115
  });
192
116
  return watcher;
@@ -197,12 +121,12 @@ var buildTailwind = async (config) => {
197
121
  if (!config.tailwind?.css || !config.tailwind?.config) {
198
122
  return;
199
123
  }
200
- const tailwindConfig = (await esmImport(path5.resolve(config.tailwind.config))).default;
201
- const inputPath = path5.resolve(config.tailwind.css);
124
+ const tailwindConfig = (await esmImport(path4.resolve(config.tailwind.config))).default;
125
+ const inputPath = path4.resolve(config.tailwind.css);
202
126
  const fileName = config.tailwind.fileName ?? "tailwind.css";
203
127
  await outputCss({
204
128
  inputPath,
205
- outputPath: path5.join(config.outDir, fileName),
129
+ outputPath: path4.join(config.outDir, fileName),
206
130
  config: tailwindConfig,
207
131
  minify: true
208
132
  });
@@ -219,28 +143,131 @@ var getDefaultK2Config = () => {
219
143
  };
220
144
  };
221
145
 
146
+ // src/lib/vite.ts
147
+ import path5 from "path";
148
+ import fs2 from "fs-extra";
149
+ import { build as viteBuild } from "vite";
150
+ import chalk from "chalk";
151
+ var createViteConfig = (config = {}) => {
152
+ const plugins = [...config.plugins ?? []];
153
+ try {
154
+ const tsconfigPaths = __require("vite-tsconfig-paths");
155
+ plugins.push(tsconfigPaths.default ? tsconfigPaths.default() : tsconfigPaths());
156
+ } catch {
157
+ }
158
+ return {
159
+ ...config,
160
+ configFile: false,
161
+ build: {
162
+ ...config.build,
163
+ cssCodeSplit: false,
164
+ rollupOptions: {
165
+ ...config.build?.rollupOptions,
166
+ onwarn: (warning, warn) => {
167
+ if (["MODULE_LEVEL_DIRECTIVE"].includes(warning.code ?? "")) {
168
+ return;
169
+ }
170
+ warn(warning);
171
+ }
172
+ }
173
+ },
174
+ plugins,
175
+ resolve: {
176
+ ...config.resolve,
177
+ alias: {
178
+ "@": path5.resolve(process.cwd(), "src"),
179
+ ...config.resolve?.alias
180
+ }
181
+ }
182
+ };
183
+ };
184
+ async function buildEntriesWithVite(params) {
185
+ const {
186
+ entries,
187
+ outDir,
188
+ mode = "production",
189
+ sourcemap = false,
190
+ minify = true,
191
+ viteConfig = {}
192
+ } = params;
193
+ for (const name of Object.keys(entries)) {
194
+ const entryPath = entries[name];
195
+ const config = createViteConfig({
196
+ ...viteConfig,
197
+ mode,
198
+ build: {
199
+ ...viteConfig.build,
200
+ lib: {
201
+ entry: entryPath,
202
+ name,
203
+ fileName: () => `${name}.js`,
204
+ formats: ["iife"]
205
+ },
206
+ rollupOptions: {
207
+ ...viteConfig.build?.rollupOptions,
208
+ output: {
209
+ assetFileNames: `${name}.[ext]`,
210
+ ...viteConfig.build?.rollupOptions?.output
211
+ }
212
+ },
213
+ outDir,
214
+ emptyOutDir: false,
215
+ sourcemap,
216
+ minify,
217
+ cssCodeSplit: false
218
+ }
219
+ });
220
+ await viteBuild(config);
221
+ }
222
+ }
223
+ var ENTRY_FILE_NAMES = ["index.ts", "index.tsx", "index.js", "index.jsx", "index.mjs"];
224
+ function getEntryPointsFromDir(inputDir) {
225
+ const entries = {};
226
+ if (!fs2.existsSync(inputDir)) {
227
+ throw new Error(`Input directory not found: ${inputDir}`);
228
+ }
229
+ const dirs = fs2.readdirSync(inputDir, { withFileTypes: true });
230
+ for (const dirent of dirs) {
231
+ if (!dirent.isDirectory()) continue;
232
+ const dirName = dirent.name;
233
+ const dirPath = path5.join(inputDir, dirName);
234
+ for (const filename of ENTRY_FILE_NAMES) {
235
+ const entryPath = path5.join(dirPath, filename);
236
+ if (fs2.existsSync(entryPath)) {
237
+ entries[dirName] = entryPath;
238
+ break;
239
+ }
240
+ }
241
+ }
242
+ return entries;
243
+ }
244
+
222
245
  // src/commands/build.ts
223
246
  function command() {
224
- program.command("build").option("-o, --outdir <outdir>", "Output directory.", path6.join(WORKSPACE_DIRECTORY, "prod")).option("-i, --input <input>", "Input directory.", path6.join("src", "apps")).option("--config <config>", "k2 config file path").description("Build the project for production. (It's a wrapper of webpack build command.)").action(action2);
247
+ program.command("build").option("-o, --outdir <outdir>", "Output directory.", path6.join(WORKSPACE_DIRECTORY, "prod")).option("-i, --input <input>", "Input directory.", path6.join("src", "apps")).option("--config <config>", "k2 config file path").description("Build the project for production with Vite.").action(action);
225
248
  }
226
- async function action2(options) {
249
+ async function action(options) {
227
250
  console.group("\u{1F373} Build the project for production");
228
251
  try {
229
252
  const { outdir, input, config } = options;
230
253
  const outDir = path6.resolve(outdir);
231
- const allProjects = fs2.readdirSync(path6.resolve(input));
232
- const entries = allProjects.reduce((acc, dir) => {
233
- for (const filename of ["index.ts", "index.js", "index.mjs"]) {
234
- if (fs2.existsSync(path6.join(input, dir, filename))) {
235
- return { ...acc, [dir]: path6.join(input, dir, filename) };
236
- }
237
- }
238
- return acc;
239
- }, {});
254
+ const entries = getEntryPointsFromDir(path6.resolve(input));
255
+ const entryNames = Object.keys(entries);
256
+ if (entryNames.length === 0) {
257
+ throw new Error(`No entry points found in ${input}`);
258
+ }
259
+ console.log(chalk2.gray(` Entry points: ${entryNames.join(", ")}`));
240
260
  const k2Config = config ? await importK2Config(config) : getDefaultK2Config();
241
261
  const fullConfig = { ...k2Config, outDir };
262
+ await fs3.emptyDir(outDir);
242
263
  const results = await Promise.allSettled([
243
- action({ entries, outDir }),
264
+ buildEntriesWithVite({
265
+ entries,
266
+ outDir,
267
+ mode: "production",
268
+ sourcemap: false,
269
+ minify: true
270
+ }),
244
271
  buildTailwind(fullConfig)
245
272
  ]);
246
273
  for (const result of results) {
@@ -258,75 +285,15 @@ async function action2(options) {
258
285
 
259
286
  // src/commands/dev/index.ts
260
287
  import { program as program2 } from "commander";
261
- import "esbuild";
262
- import fs4 from "fs-extra";
288
+ import { createServer } from "vite";
289
+ import fs6 from "fs-extra";
263
290
  import path9 from "path";
264
-
265
- // src/commands/dev-base-esbuild.ts
266
- import "esbuild";
267
- import path7 from "path";
268
-
269
- // src/lib/esbuild.ts
270
- import chalk2 from "chalk";
271
- import esbuild from "esbuild";
272
- var completeBuildOptions = (params) => {
273
- return {
274
- bundle: true,
275
- platform: "browser",
276
- ...params,
277
- plugins: [...params.plugins ?? []]
278
- };
279
- };
280
- var completeDevBuildOptions = (params) => {
281
- return completeBuildOptions({
282
- ...params,
283
- plugins: [
284
- ...params.plugins ?? [],
285
- {
286
- name: "on-end",
287
- setup: ({ onEnd }) => onEnd(
288
- () => console.log(
289
- chalk2.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk2.cyan(`[js] `) + `rebuilt`
290
- )
291
- )
292
- }
293
- ]
294
- });
295
- };
296
- var getEsbuildContext = async (params) => {
297
- return esbuild.context(completeDevBuildOptions(params));
298
- };
299
- var buildWithEsbuild = async (params) => {
300
- const { watch = false, ...rest } = params;
301
- if (watch) {
302
- const context = await getEsbuildContext(rest);
303
- context.watch();
304
- } else {
305
- const options = completeBuildOptions(rest);
306
- await esbuild.build(options);
307
- }
308
- };
309
-
310
- // src/commands/dev-base-esbuild.ts
311
- async function action3(params) {
312
- const { entryPoints, staticDir: outdir, certDir, port } = params;
313
- const context = await getEsbuildContext({ sourcemap: "inline", entryPoints, outdir });
314
- const [_, serveResult] = await Promise.all([
315
- context.watch(),
316
- context.serve({
317
- port,
318
- keyfile: path7.join(certDir, "localhost-key.pem"),
319
- certfile: path7.join(certDir, "localhost-cert.pem"),
320
- servedir: outdir
321
- })
322
- ]);
323
- console.log(`\u{1F680} Start development server at https://localhost:${serveResult.port}`);
324
- }
291
+ import chalk4 from "chalk";
325
292
 
326
293
  // src/commands/dev/tailwind.ts
327
- import path8 from "path";
294
+ import path7 from "path";
328
295
  import chalk3 from "chalk";
329
- import fs3 from "fs-extra";
296
+ import fs4 from "fs-extra";
330
297
  var watchCss = async (params) => {
331
298
  const { k2Config, outdir } = params;
332
299
  if (!k2Config.tailwind?.css || !k2Config.tailwind?.config) {
@@ -334,17 +301,17 @@ var watchCss = async (params) => {
334
301
  return;
335
302
  }
336
303
  const tailwindConfig = await getTailwindConfigFromK2Config(k2Config.tailwind);
337
- const input = path8.resolve(k2Config.tailwind.css);
338
- const output = path8.join(outdir, "tailwind.css");
339
- if (!await fs3.pathExists(output)) {
340
- await fs3.outputFile(output, "");
304
+ const input = path7.resolve(k2Config.tailwind.css);
305
+ const output = path7.join(outdir, "tailwind.css");
306
+ if (!await fs4.pathExists(output)) {
307
+ await fs4.outputFile(output, "");
341
308
  }
342
309
  return watchTailwindCSS({
343
310
  input,
344
- output: path8.join(outdir, "tailwind.css"),
311
+ output: path7.join(outdir, "tailwind.css"),
345
312
  config: tailwindConfig,
346
313
  onChanges: ({ output: output2, type }) => {
347
- const outputFileName = path8.basename(output2);
314
+ const outputFileName = path7.basename(output2);
348
315
  console.log(
349
316
  chalk3.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk3.cyan(`[css] `) + outputFileName + (type === "init" ? " init" : ` rebuilt(${type})`)
350
317
  );
@@ -352,11 +319,46 @@ var watchCss = async (params) => {
352
319
  });
353
320
  };
354
321
 
322
+ // src/lib/exec.ts
323
+ import { exec as defaultExec } from "child_process";
324
+ import { promisify } from "util";
325
+ var exec = promisify(defaultExec);
326
+
327
+ // src/lib/cert.ts
328
+ import fs5 from "fs-extra";
329
+ import path8 from "path";
330
+ var CERT_KEY_FILENAME = "localhost-key.pem";
331
+ var CERT_FILENAME = "localhost-cert.pem";
332
+ var generateCert = async (outDir) => {
333
+ await fs5.ensureDir(outDir);
334
+ const { stdout } = await exec(`mkcert localhost 127.0.0.1 ::1`);
335
+ [
336
+ { input: "localhost+2.pem", output: CERT_FILENAME },
337
+ { input: "localhost+2-key.pem", output: CERT_KEY_FILENAME }
338
+ ].forEach(({ input, output }) => {
339
+ if (fs5.existsSync(input)) {
340
+ fs5.moveSync(`./${input}`, path8.join(outDir, output), {
341
+ overwrite: true
342
+ });
343
+ }
344
+ });
345
+ return { stdout };
346
+ };
347
+ function hasCertificates(certDir) {
348
+ return fs5.existsSync(path8.join(certDir, CERT_KEY_FILENAME)) && fs5.existsSync(path8.join(certDir, CERT_FILENAME));
349
+ }
350
+ function loadCertificates(certDir) {
351
+ return {
352
+ key: fs5.readFileSync(path8.join(certDir, CERT_KEY_FILENAME)),
353
+ cert: fs5.readFileSync(path8.join(certDir, CERT_FILENAME))
354
+ };
355
+ }
356
+
355
357
  // src/commands/dev/index.ts
356
358
  function command2() {
357
- program2.command("dev").description("Start development server.").option("-i, --input <input>", "Input directory", "src/apps").option("-o, --outdir <outdir>", "Output directory.", DEVELOPMENT_DIRECTORY).option("-c, --certdir <certdir>", "Certificate directory", WORKSPACE_DIRECTORY).option("--config <config>", "k2 config file path").option("-p, --port <port>", "Port number").action(action4);
359
+ program2.command("dev").description("Start development server with Vite.").option("-i, --input <input>", "Input directory", "src/apps").option("-o, --outdir <outdir>", "Output directory.", DEVELOPMENT_DIRECTORY).option("-c, --certdir <certdir>", "Certificate directory", WORKSPACE_DIRECTORY).option("--config <config>", "k2 config file path").option("-p, --port <port>", "Port number").action(action2);
358
360
  }
359
- async function action4(options) {
361
+ async function action2(options) {
360
362
  const { certdir, outdir, config, port: specifiedPort, input } = options;
361
363
  console.group("\u{1F373} Start development server");
362
364
  try {
@@ -369,60 +371,85 @@ async function action4(options) {
369
371
  console.log(`\u2699 ${CONFIG_FILE_NAME} not found. use default settings.`);
370
372
  }
371
373
  const port = Number(specifiedPort ?? k2Config?.server?.port ?? DEFAULT_PORT);
372
- await Promise.all([
373
- build({ certdir, outdir, port, input }),
374
- watchCss({ k2Config: k2Config ?? {}, outdir })
375
- ]);
374
+ const certDirPath = path9.resolve(certdir);
375
+ const outputDir = path9.resolve(outdir);
376
+ const inputDir = path9.resolve(input);
377
+ if (!hasCertificates(certDirPath)) {
378
+ console.log(chalk4.yellow("\u{1F4DC} SSL certificates not found. Generating..."));
379
+ try {
380
+ await generateCert(certDirPath);
381
+ console.log(chalk4.green("\u2705 SSL certificates generated successfully"));
382
+ } catch (error) {
383
+ console.log(
384
+ chalk4.red("\u274C Failed to generate SSL certificates. Make sure mkcert is installed.")
385
+ );
386
+ console.log(chalk4.gray(" Install mkcert: https://github.com/FiloSottile/mkcert"));
387
+ throw error;
388
+ }
389
+ }
390
+ const entries = getEntryPointsFromDir(inputDir);
391
+ const entryNames = Object.keys(entries);
392
+ if (entryNames.length === 0) {
393
+ throw new Error(`No entry points found in ${input}`);
394
+ }
395
+ console.log(chalk4.gray(` Entry points: ${entryNames.join(", ")}`));
396
+ await fs6.emptyDir(outputDir);
397
+ const { key, cert } = loadCertificates(certDirPath);
398
+ console.log(chalk4.gray(" Building..."));
399
+ await buildEntriesWithVite({
400
+ entries,
401
+ outDir: outputDir,
402
+ mode: "development",
403
+ sourcemap: "inline",
404
+ minify: false
405
+ });
406
+ const serverConfig = createViteConfig({
407
+ root: outputDir,
408
+ server: {
409
+ port,
410
+ https: { key, cert }
411
+ }
412
+ });
413
+ const server = await createServer(serverConfig);
414
+ await server.listen();
415
+ console.log(chalk4.green(`
416
+ \u2728 Development server ready!`));
417
+ console.log(chalk4.cyan(` Local: https://localhost:${port}`));
418
+ console.log(chalk4.gray(` Output: ${outputDir}`));
419
+ console.log(chalk4.gray("\n Watching for changes...\n"));
420
+ const chokidar2 = await import("chokidar");
421
+ const watcher = chokidar2.watch([`${input}/**/*.{ts,tsx,js,jsx,css,scss}`], {
422
+ ignored: /node_modules/,
423
+ persistent: true
424
+ });
425
+ const rebuild = async () => {
426
+ console.log(chalk4.gray(" Rebuilding..."));
427
+ await buildEntriesWithVite({
428
+ entries,
429
+ outDir: outputDir,
430
+ mode: "development",
431
+ sourcemap: "inline",
432
+ minify: false
433
+ });
434
+ };
435
+ watcher.on("change", rebuild);
436
+ watcher.on("add", rebuild);
437
+ watcher.on("unlink", rebuild);
438
+ if (k2Config) {
439
+ await watchCss({ k2Config, outdir });
440
+ }
376
441
  } catch (error) {
377
442
  throw error;
378
443
  } finally {
379
444
  console.groupEnd();
380
445
  }
381
446
  }
382
- var build = async (params) => {
383
- const { outdir, certdir, port, input } = params;
384
- const srcDir = path9.resolve(input);
385
- const dirs = fs4.readdirSync(srcDir);
386
- const entryPoints = dirs.reduce(
387
- (acc, dir) => {
388
- for (const filename of ["index.ts", "index.js", "index.mjs"]) {
389
- if (fs4.existsSync(path9.join(srcDir, dir, filename))) {
390
- return [...acc, { in: path9.join(srcDir, dir, filename), out: dir }];
391
- }
392
- }
393
- return acc;
394
- },
395
- []
396
- );
397
- return action3({ port, entryPoints, certDir: certdir, staticDir: outdir });
398
- };
399
447
 
400
448
  // src/commands/genkey.ts
401
449
  import { program as program3 } from "commander";
402
450
 
403
- // src/lib/exec.ts
404
- import { exec as defaultExec } from "child_process";
405
- import { promisify } from "util";
406
- var exec = promisify(defaultExec);
407
-
408
- // src/lib/cert.ts
409
- import fs5 from "fs-extra";
410
- import path10 from "path";
411
- var generateCert = async (outDir) => {
412
- const { stdout } = await exec(`mkcert localhost 127.0.0.1 ::1`);
413
- [
414
- { input: "localhost+2.pem", output: "localhost-cert.pem" },
415
- { input: "localhost+2-key.pem", output: "localhost-key.pem" }
416
- ].forEach(({ input, output }) => {
417
- fs5.moveSync(`./${input}`, path10.join(outDir, output), {
418
- overwrite: true
419
- });
420
- });
421
- return { stdout };
422
- };
423
-
424
451
  // src/commands/genkey-base.ts
425
- async function action5(options) {
452
+ async function action3(options) {
426
453
  const { output } = options;
427
454
  console.group("\u{1F373} Generate SSL key for localhost");
428
455
  try {
@@ -440,47 +467,41 @@ async function action5(options) {
440
467
 
441
468
  // src/commands/genkey.ts
442
469
  function command3() {
443
- program3.command("genkey").description("Generate SSL key for localhost. (Require mkcert)").option("-o, --output <output>", "Output directory.", WORKSPACE_DIRECTORY).action(action6);
470
+ program3.command("genkey").description("Generate SSL key for localhost. (Require mkcert)").option("-o, --output <output>", "Output directory.", WORKSPACE_DIRECTORY).action(action4);
444
471
  }
445
- async function action6(options) {
446
- await action5(options);
472
+ async function action4(options) {
473
+ await action3(options);
447
474
  }
448
475
 
449
476
  // src/commands/build-esbuild.ts
450
477
  import { program as program4 } from "commander";
451
- import fs6 from "fs-extra";
452
- import path11 from "path";
453
- import "esbuild";
478
+ import fs7 from "fs-extra";
479
+ import path10 from "path";
480
+ import chalk5 from "chalk";
454
481
  function command4() {
455
- program4.command("esbuild-build").option("-o, --outdir <outdir>", "Output directory.", path11.join(WORKSPACE_DIRECTORY, "prod")).option("-i, --input <input>", "Input directory.", path11.join("src", "apps")).option("--config <config>", "k2 config file path").description("Build the project for production. (It's a wrapper of webpack build command.)").action(action7);
482
+ program4.command("esbuild-build").option("-o, --outdir <outdir>", "Output directory.", path10.join(WORKSPACE_DIRECTORY, "prod")).option("-i, --input <input>", "Input directory.", path10.join("src", "apps")).option("--config <config>", "k2 config file path").description("Build the project for production with Vite. (Legacy command name, now uses Vite)").action(action5);
456
483
  }
457
- async function action7(options) {
484
+ async function action5(options) {
458
485
  console.group("\u{1F373} Build the project for production");
459
486
  try {
460
487
  const { outdir, input, config } = options;
461
- const outDir = path11.resolve(outdir);
462
- if (!fs6.existsSync(outDir)) {
463
- fs6.mkdirSync(outDir, { recursive: true });
488
+ const outDir = path10.resolve(outdir);
489
+ const entries = getEntryPointsFromDir(path10.resolve(input));
490
+ const entryNames = Object.keys(entries);
491
+ if (entryNames.length === 0) {
492
+ throw new Error(`No entry points found in ${input}`);
464
493
  }
465
- const allProjects = fs6.readdirSync(path11.resolve(input));
466
- const entryPoints = allProjects.reduce((acc, dir) => {
467
- for (const filename of ["index.ts", "index.js", "index.mjs"]) {
468
- if (fs6.existsSync(path11.join(input, dir, filename))) {
469
- return { ...acc, [dir]: path11.join(input, dir, filename) };
470
- }
471
- }
472
- return acc;
473
- }, {});
474
- console.log(`\u{1F4C1} ${Object.keys(entryPoints).length} entry points`);
494
+ console.log(chalk5.gray(` Entry points: ${entryNames.join(", ")}`));
495
+ await fs7.emptyDir(outDir);
475
496
  const k2Config = config ? await importK2Config(config) : getDefaultK2Config();
476
497
  const fullConfig = { ...k2Config, outDir };
477
498
  const results = await Promise.allSettled([
478
- buildWithEsbuild({
479
- entryPoints,
480
- outdir,
499
+ buildEntriesWithVite({
500
+ entries,
501
+ outDir,
502
+ mode: "production",
481
503
  sourcemap: false,
482
- minify: true,
483
- legalComments: "none"
504
+ minify: true
484
505
  }),
485
506
  buildTailwind(fullConfig)
486
507
  ]);
@@ -531,9 +552,9 @@ async function lint() {
531
552
 
532
553
  // src/commands/lint.ts
533
554
  function command5() {
534
- program5.command("lint").description("Lint source files").option("-c, --config <config>", "Config file path").action(action8);
555
+ program5.command("lint").description("Lint source files").option("-c, --config <config>", "Config file path").action(action6);
535
556
  }
536
- async function action8(options) {
557
+ async function action6(options) {
537
558
  try {
538
559
  lint();
539
560
  } catch (error) {