@konomi-app/k2 3.4.1 → 4.1.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/plugin.js CHANGED
@@ -1,19 +1,13 @@
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
- });
8
2
 
9
3
  // src/plugin.ts
10
- import { program as program10 } from "commander";
4
+ import { program as program9 } from "commander";
11
5
 
12
6
  // src/commands/plugin-build.ts
13
7
  import { program } from "commander";
14
8
  import fs3 from "fs-extra";
15
9
  import path5 from "path";
16
- import chalk2 from "chalk";
10
+ import chalk from "chalk";
17
11
 
18
12
  // src/lib/constants.ts
19
13
  import path from "path";
@@ -30,11 +24,11 @@ var DEFAULT_PORT = 32767;
30
24
  // src/lib/import.ts
31
25
  import { pathToFileURL } from "url";
32
26
  import path2 from "path";
33
- var esmImport = (path16) => {
27
+ var esmImport = (path17) => {
34
28
  if (process.platform === "win32") {
35
- return import(pathToFileURL(path16).toString());
29
+ return import(pathToFileURL(path17).toString());
36
30
  } else {
37
- return import(path16);
31
+ return import(path17);
38
32
  }
39
33
  };
40
34
  var importK2PluginConfig = async (configFileName) => {
@@ -114,16 +108,16 @@ var watchTailwindCSS = async (params) => {
114
108
  watcher.on("error", (error) => {
115
109
  console.error("Error watching Tailwind CSS:", error);
116
110
  });
117
- watcher.on("add", (path16) => {
111
+ watcher.on("add", (path17) => {
118
112
  debouncedProcessChanges.call("add");
119
113
  });
120
- watcher.on("change", (path16) => {
114
+ watcher.on("change", (path17) => {
121
115
  debouncedProcessChanges.call("change");
122
116
  });
123
- watcher.on("unlink", (path16) => {
117
+ watcher.on("unlink", (path17) => {
124
118
  debouncedProcessChanges.call("unlink");
125
119
  });
126
- watcher.on("unlinkDir", (path16) => {
120
+ watcher.on("unlinkDir", (path17) => {
127
121
  debouncedProcessChanges.call("unlink");
128
122
  });
129
123
  return watcher;
@@ -158,188 +152,127 @@ async function lint() {
158
152
  }
159
153
  }
160
154
 
161
- // src/lib/vite.ts
162
- import chalk from "chalk";
163
- import fs2 from "fs-extra";
164
- import os from "os";
155
+ // src/lib/rsbuild.ts
156
+ import { createRsbuild } from "@rsbuild/core";
157
+ import { pluginReact as pluginReact2 } from "@rsbuild/plugin-react";
165
158
  import path4 from "path";
166
- import { build as viteBuild } from "vite";
167
- var DEFAULT_CONCURRENCY = Math.max(1, os.cpus().length - 1);
168
- async function parallelLimit(items, concurrency, fn) {
169
- const results = [];
170
- const executing = [];
171
- for (const item of items) {
172
- const promise = fn(item).then((result) => {
173
- results.push(result);
174
- });
175
- const e = promise.then(() => {
176
- executing.splice(executing.indexOf(e), 1);
177
- });
178
- executing.push(e);
179
- if (executing.length >= concurrency) {
180
- await Promise.race(executing);
181
- }
182
- }
183
- await Promise.all(executing);
184
- return results;
185
- }
186
- var createViteConfig = (config2 = {}) => {
187
- const plugins = [...config2.plugins ?? []];
188
- try {
189
- const tsconfigPaths = __require("vite-tsconfig-paths");
190
- plugins.push(tsconfigPaths.default ? tsconfigPaths.default() : tsconfigPaths());
191
- } catch {
192
- }
193
- const mode = config2.mode ?? "production";
194
- return {
195
- ...config2,
196
- configFile: false,
197
- // ソースマップ関連のエラーメッセージを抑制
198
- logLevel: config2.logLevel ?? "warn",
199
- // ブラウザ向けにNode.js固有のオブジェクトをビルド時に解決
200
- define: {
201
- "process.env.NODE_ENV": JSON.stringify(mode),
202
- "process.env": JSON.stringify({}),
203
- ...config2.define
204
- },
205
- build: {
206
- ...config2.build,
207
- // ブラウザ向けターゲット
208
- target: config2.build?.target ?? "es2020",
209
- cssCodeSplit: false,
210
- rollupOptions: {
211
- ...config2.build?.rollupOptions,
212
- onwarn: (warning, warn) => {
213
- if (["MODULE_LEVEL_DIRECTIVE"].includes(warning.code ?? "")) {
214
- return;
215
- }
216
- if (warning.message?.includes("sourcemap") || warning.code === "SOURCEMAP_ERROR") {
217
- return;
218
- }
219
- warn(warning);
220
- }
221
- }
222
- },
223
- plugins,
224
- resolve: {
225
- ...config2.resolve,
226
- alias: {
227
- "@": path4.resolve(process.cwd(), "src"),
228
- ...config2.resolve?.alias
159
+ import fs2 from "fs-extra";
160
+ function getRsbuildPlugins() {
161
+ return [
162
+ pluginReact2({
163
+ swcReactOptions: {
164
+ runtime: "automatic"
229
165
  }
230
- }
231
- };
232
- };
233
- async function buildEntriesWithVite(params) {
234
- const {
235
- entries,
236
- outDir,
237
- mode = "production",
238
- sourcemap = false,
239
- minify = true,
240
- viteConfig = {},
241
- concurrency = DEFAULT_CONCURRENCY
242
- } = params;
243
- const entryNames = Object.keys(entries);
244
- if (entryNames.length === 1) {
245
- const name = entryNames[0];
246
- await buildSingleEntry({
247
- name,
248
- entryPath: entries[name],
249
- outDir,
250
- mode,
251
- sourcemap,
252
- minify,
253
- viteConfig
254
- });
255
- return;
256
- }
257
- await parallelLimit(entryNames, concurrency, async (name) => {
258
- await buildSingleEntry({
259
- name,
260
- entryPath: entries[name],
261
- outDir,
262
- mode,
263
- sourcemap,
264
- minify,
265
- viteConfig
266
- });
267
- });
166
+ })
167
+ ];
268
168
  }
269
- async function buildSingleEntry(params) {
270
- const { name, entryPath, outDir, mode, sourcemap, minify, viteConfig } = params;
271
- const config2 = createViteConfig({
272
- ...viteConfig,
273
- mode,
274
- build: {
275
- ...viteConfig.build,
276
- rollupOptions: {
277
- ...viteConfig.build?.rollupOptions,
278
- input: entryPath,
279
- output: {
280
- entryFileNames: `${name}.js`,
281
- assetFileNames: `${name}.[ext]`,
282
- format: "iife",
283
- // 外部ライブラリのソースマップを無視して警告を抑制
284
- sourcemapIgnoreList: (relativeSourcePath) => {
285
- return relativeSourcePath.includes("node_modules");
286
- },
287
- ...viteConfig.build?.rollupOptions?.output
288
- }
169
+ async function buildWithRsbuild(params) {
170
+ const { entries, outDir, minify = true, sourcemap = false, injectStyles = true } = params;
171
+ const sourceMapConfig = sourcemap === "inline" ? "cheap-module-source-map" : sourcemap ? "source-map" : false;
172
+ const rsbuild = await createRsbuild({
173
+ rsbuildConfig: {
174
+ plugins: getRsbuildPlugins(),
175
+ source: { entry: entries },
176
+ output: {
177
+ target: "web",
178
+ distPath: { root: outDir, js: "" },
179
+ filename: { js: "[name].js" },
180
+ filenameHash: false,
181
+ cleanDistPath: true,
182
+ injectStyles,
183
+ sourceMap: { js: sourceMapConfig },
184
+ minify
289
185
  },
290
- outDir,
291
- emptyOutDir: false,
292
- sourcemap,
293
- minify,
294
- cssCodeSplit: false
186
+ performance: {
187
+ chunkSplit: { strategy: "all-in-one" }
188
+ },
189
+ tools: {
190
+ htmlPlugin: false
191
+ }
295
192
  }
296
193
  });
297
- await viteBuild(config2);
298
- const outputPath = path4.join(outDir, `${name}.js`);
299
- if (fs2.existsSync(outputPath)) {
300
- const content = await fs2.readFile(outputPath, "utf-8");
301
- const wrapped = `(function(){
302
- ${content}
303
- })();`;
304
- await fs2.writeFile(outputPath, wrapped);
305
- }
194
+ await rsbuild.build();
306
195
  }
307
- var ENTRY_FILE_NAMES = ["index.ts", "index.tsx", "index.js", "index.jsx", "index.mjs"];
308
- function findEntryPoint(basePath) {
309
- for (const filename of ENTRY_FILE_NAMES) {
310
- const entryPath = path4.join(basePath, filename);
311
- if (fs2.existsSync(entryPath)) {
312
- return entryPath;
196
+ async function startRsbuildDevServer(params) {
197
+ const { entries, outDir, port, https, publicDir, onFirstCompile, onRecompile } = params;
198
+ const rsbuildConfig = {
199
+ plugins: getRsbuildPlugins(),
200
+ source: { entry: entries },
201
+ output: {
202
+ target: "web",
203
+ distPath: { root: outDir, js: "" },
204
+ filename: { js: "[name].js" },
205
+ filenameHash: false,
206
+ cleanDistPath: false,
207
+ injectStyles: true,
208
+ sourceMap: { js: "cheap-module-source-map" },
209
+ minify: false
210
+ },
211
+ performance: {
212
+ chunkSplit: { strategy: "all-in-one" }
213
+ },
214
+ tools: {
215
+ htmlPlugin: false
216
+ },
217
+ server: {
218
+ port,
219
+ host: "0.0.0.0",
220
+ ...https ? { https } : {},
221
+ ...publicDir && fs2.existsSync(publicDir) ? { publicDir: { name: publicDir } } : {}
222
+ },
223
+ dev: {
224
+ writeToDisk: true
313
225
  }
226
+ };
227
+ const rsbuild = await createRsbuild({ rsbuildConfig });
228
+ if (onFirstCompile || onRecompile) {
229
+ rsbuild.addPlugins([
230
+ {
231
+ name: "k2-dev-hooks",
232
+ setup(api) {
233
+ api.onDevCompileDone(async ({ isFirstCompile }) => {
234
+ if (isFirstCompile && onFirstCompile) {
235
+ await onFirstCompile();
236
+ } else if (!isFirstCompile && onRecompile) {
237
+ await onRecompile();
238
+ }
239
+ });
240
+ }
241
+ }
242
+ ]);
314
243
  }
315
- if (fs2.existsSync(basePath) && fs2.statSync(basePath).isFile()) {
316
- return basePath;
317
- }
318
- return null;
244
+ const result = await rsbuild.startDevServer();
245
+ return {
246
+ port: result.port,
247
+ close: result.server.close
248
+ };
319
249
  }
320
- function getPluginEntryPoints(options) {
250
+ function getPluginEntryPoints(params) {
251
+ const { configEntry, desktopEntry } = params;
321
252
  const entries = {};
322
- const configPath = findEntryPoint(options.configEntry);
323
- if (configPath) {
324
- entries["config"] = configPath;
325
- } else {
326
- console.log(chalk.yellow(` \u26A0 Config entry not found: ${options.configEntry}`));
253
+ for (const ext of ["index.ts", "index.tsx", "index.js", "index.jsx"]) {
254
+ const configPath = path4.join(configEntry, ext);
255
+ if (fs2.existsSync(configPath)) {
256
+ entries.config = configPath;
257
+ break;
258
+ }
327
259
  }
328
- const desktopPath = findEntryPoint(options.desktopEntry);
329
- if (desktopPath) {
330
- entries["desktop"] = desktopPath;
331
- } else {
332
- console.log(chalk.yellow(` \u26A0 Desktop entry not found: ${options.desktopEntry}`));
260
+ for (const ext of ["index.ts", "index.tsx", "index.js", "index.jsx"]) {
261
+ const desktopPath = path4.join(desktopEntry, ext);
262
+ if (fs2.existsSync(desktopPath)) {
263
+ entries.desktop = desktopPath;
264
+ break;
265
+ }
333
266
  }
334
267
  return entries;
335
268
  }
336
269
 
337
270
  // src/commands/plugin-build.ts
338
271
  function command() {
339
- program.command("build").description("Build the project for production with Vite.").action(action);
272
+ program.command("build").description("Build the plugin for production with rsbuild.").action(action);
340
273
  }
341
274
  async function action() {
342
- console.group("\u{1F373} Build the project for production");
275
+ console.group("\u{1F373} Build the plugin for production");
343
276
  try {
344
277
  const config2 = await importK2PluginConfig();
345
278
  if (config2?.lint?.build) {
@@ -349,6 +282,24 @@ async function action() {
349
282
  if (!fs3.existsSync(PLUGIN_CONTENTS_DIRECTORY)) {
350
283
  await fs3.mkdir(PLUGIN_CONTENTS_DIRECTORY, { recursive: true });
351
284
  }
285
+ if (config2.tailwind?.css && config2.tailwind?.config) {
286
+ const tailwindConfig = await getTailwindConfig(config2.tailwind);
287
+ const inputFile = getTailwindInputCss(config2.tailwind);
288
+ await outputCss({
289
+ inputPath: inputFile.config,
290
+ outputPath: path5.join(PLUGIN_CONTENTS_DIRECTORY, "config.css"),
291
+ config: tailwindConfig.config,
292
+ minify: true
293
+ });
294
+ console.log("\u2728 Built config.css");
295
+ await outputCss({
296
+ inputPath: inputFile.desktop,
297
+ outputPath: path5.join(PLUGIN_CONTENTS_DIRECTORY, "desktop.css"),
298
+ config: tailwindConfig.desktop,
299
+ minify: true
300
+ });
301
+ console.log("\u2728 Built desktop.css");
302
+ }
352
303
  const entries = getPluginEntryPoints({
353
304
  configEntry: path5.resolve("src", "config"),
354
305
  desktopEntry: path5.resolve("src", "desktop")
@@ -357,36 +308,15 @@ async function action() {
357
308
  if (entryNames.length === 0) {
358
309
  throw new Error("No entry points found for plugin. Check src/config and src/desktop paths.");
359
310
  }
360
- console.log(chalk2.gray(` Entry points: ${entryNames.join(", ")}`));
361
- const buildTasks = [];
362
- if (config2.tailwind?.css && config2.tailwind?.config) {
363
- const tailwindConfig = await getTailwindConfig(config2.tailwind);
364
- const inputFile = getTailwindInputCss(config2.tailwind);
365
- buildTasks.push(
366
- outputCss({
367
- inputPath: inputFile.config,
368
- outputPath: path5.join(PLUGIN_CONTENTS_DIRECTORY, "config.css"),
369
- config: tailwindConfig.config,
370
- minify: true
371
- }).then(() => console.log("\u2728 Built config.css")),
372
- outputCss({
373
- inputPath: inputFile.desktop,
374
- outputPath: path5.join(PLUGIN_CONTENTS_DIRECTORY, "desktop.css"),
375
- config: tailwindConfig.desktop,
376
- minify: true
377
- }).then(() => console.log("\u2728 Built desktop.css"))
378
- );
379
- }
380
- buildTasks.push(
381
- buildEntriesWithVite({
382
- entries,
383
- outDir: PLUGIN_CONTENTS_DIRECTORY,
384
- mode: "production",
385
- sourcemap: false,
386
- minify: true
387
- }).then(() => console.log("\u2728 Built desktop.js and config.js"))
388
- );
389
- await Promise.all(buildTasks);
311
+ console.log(chalk.gray(` Entry points: ${entryNames.join(", ")}`));
312
+ await buildWithRsbuild({
313
+ entries,
314
+ outDir: PLUGIN_CONTENTS_DIRECTORY,
315
+ minify: true,
316
+ sourcemap: false,
317
+ injectStyles: true
318
+ });
319
+ console.log("\u2728 Built desktop.js and config.js");
390
320
  console.log("\u2728 Build success.");
391
321
  } catch (error) {
392
322
  throw error;
@@ -395,65 +325,245 @@ async function action() {
395
325
  }
396
326
  }
397
327
 
398
- // src/commands/plugin-esbuild.ts
399
- import { program as program2 } from "commander";
400
- function command2() {
401
- program2.command("esbuild").description(
402
- "[DEPRECATED] Build the project for production with esbuild. (Use `plugin build` instead.)"
403
- ).action(action);
404
- }
405
-
406
328
  // src/commands/plugin-dev/index.ts
407
- import { program as program3 } from "commander";
408
- import { createServer } from "vite";
329
+ import { program as program2 } from "commander";
409
330
  import fs10 from "fs-extra";
410
331
  import path13 from "path";
411
- import chalk5 from "chalk";
412
-
413
- // src/lib/exec.ts
414
- import { exec as defaultExec } from "child_process";
415
- import { promisify } from "util";
416
- var exec = promisify(defaultExec);
332
+ import chalk4 from "chalk";
417
333
 
418
- // src/lib/cert.ts
334
+ // src/lib/cert/index.ts
419
335
  import fs4 from "fs-extra";
336
+ import path7 from "path";
337
+
338
+ // src/lib/cert/cert.ts
339
+ import forge from "node-forge";
340
+ import net from "net";
341
+ var { md, pki } = forge;
342
+ function createCertificate(serial, publicKey, subject, issuer, extensions, validity, signWith) {
343
+ const cert = pki.createCertificate();
344
+ cert.serialNumber = Buffer.from(serial).toString("hex");
345
+ cert.publicKey = publicKey;
346
+ cert.setSubject(subject);
347
+ cert.setIssuer(issuer);
348
+ cert.setExtensions(extensions);
349
+ cert.validity.notBefore = /* @__PURE__ */ new Date();
350
+ cert.validity.notAfter = /* @__PURE__ */ new Date();
351
+ cert.validity.notAfter.setDate(cert.validity.notAfter.getDate() + validity);
352
+ cert.sign(signWith, md.sha256.create());
353
+ return cert;
354
+ }
355
+ function generateCertInternal(params) {
356
+ const { subject, issuer, extensions, validity, signWith } = params;
357
+ const serial = Math.floor(Math.random() * 95e3 + 5e4).toString();
358
+ const keyPair = pki.rsa.generateKeyPair(2048);
359
+ const privateKey = signWith ? pki.privateKeyFromPem(signWith) : keyPair.privateKey;
360
+ const cert = createCertificate(
361
+ serial,
362
+ keyPair.publicKey,
363
+ subject,
364
+ issuer,
365
+ extensions,
366
+ validity,
367
+ privateKey
368
+ );
369
+ return {
370
+ key: pki.privateKeyToPem(keyPair.privateKey),
371
+ cert: pki.certificateToPem(cert)
372
+ };
373
+ }
374
+ function createCA(params = {}) {
375
+ const {
376
+ organization = "K2 Development CA",
377
+ countryCode = "JP",
378
+ state = "Tokyo",
379
+ locality = "Tokyo",
380
+ validity = 7300
381
+ } = params;
382
+ const attributes = [
383
+ { name: "commonName", value: organization },
384
+ { name: "countryName", value: countryCode },
385
+ { name: "stateOrProvinceName", value: state },
386
+ { name: "localityName", value: locality },
387
+ { name: "organizationName", value: organization }
388
+ ];
389
+ const extensions = [
390
+ { name: "basicConstraints", cA: true, critical: true },
391
+ { name: "keyUsage", keyCertSign: true, critical: true }
392
+ ];
393
+ return generateCertInternal({
394
+ subject: attributes,
395
+ issuer: attributes,
396
+ extensions,
397
+ validity
398
+ });
399
+ }
400
+ function createCert(params) {
401
+ const { ca, domains, validity = 7300 } = params;
402
+ const attributes = [{ name: "commonName", value: domains[0] }];
403
+ const extensions = [
404
+ { name: "basicConstraints", cA: false, critical: true },
405
+ {
406
+ name: "keyUsage",
407
+ digitalSignature: true,
408
+ keyEncipherment: true,
409
+ critical: true
410
+ },
411
+ { name: "extKeyUsage", serverAuth: true, clientAuth: true },
412
+ {
413
+ name: "subjectAltName",
414
+ altNames: domains.map((domain) => {
415
+ const TYPE_DOMAIN = 2;
416
+ const TYPE_IP = 7;
417
+ return net.isIP(domain) ? { type: TYPE_IP, ip: domain } : { type: TYPE_DOMAIN, value: domain };
418
+ })
419
+ }
420
+ ];
421
+ const caCert = pki.certificateFromPem(ca.cert.toString());
422
+ return generateCertInternal({
423
+ subject: attributes,
424
+ issuer: caCert.subject.attributes,
425
+ extensions,
426
+ validity,
427
+ signWith: ca.key.toString()
428
+ });
429
+ }
430
+
431
+ // src/lib/cert/constants.ts
420
432
  import path6 from "path";
433
+ var PKG_NAME = "k2";
434
+ var isSupported = process.platform === "darwin" || process.platform === "linux" || process.platform === "win32";
435
+ function getApplicationConfigPath(name) {
436
+ if (process.platform === "darwin") {
437
+ return path6.join(process.env.HOME, "Library", "Application Support", name);
438
+ }
439
+ if (process.platform === "win32") {
440
+ return process.env.LOCALAPPDATA ? path6.join(process.env.LOCALAPPDATA, name) : path6.join(process.env.USERPROFILE, "Local Settings", "Application Data", name);
441
+ }
442
+ return process.env.XDG_CONFIG_HOME ? path6.join(process.env.XDG_CONFIG_HOME, name) : path6.join(process.env.HOME, ".config", name);
443
+ }
444
+ var pkgDir = getApplicationConfigPath(PKG_NAME);
445
+ var rootCAPath = path6.resolve(pkgDir, "rootCA.pem");
446
+ var rootCAKeyPath = path6.resolve(pkgDir, "rootCA-key.pem");
447
+
448
+ // src/lib/cert/platforms.ts
449
+ import { spawnSync } from "child_process";
450
+
451
+ // src/lib/logger.ts
452
+ var PKG_NAME2 = "@konomi-app/k2";
453
+ function createLogger(prefix = PKG_NAME2) {
454
+ return {
455
+ log: (...args) => console.log(`[${prefix}]`, ...args),
456
+ info: (...args) => console.info(`[${prefix}]`, ...args),
457
+ warn: (...args) => console.warn(`[${prefix}]`, ...args),
458
+ error: (...args) => console.error(`[${prefix}]`, ...args)
459
+ };
460
+ }
461
+ var logger_default = createLogger();
462
+
463
+ // src/lib/cert/platforms.ts
464
+ function addToTrustStoresDarwin(certPath) {
465
+ logger_default.log("Adding certificate to trusted store. Admin rights may be required.");
466
+ spawnSync(
467
+ "sudo",
468
+ [
469
+ "security",
470
+ "add-trusted-cert",
471
+ "-d",
472
+ "-r",
473
+ "trustRoot",
474
+ "-k",
475
+ "/Library/Keychains/System.keychain",
476
+ "-p",
477
+ "ssl",
478
+ "-p",
479
+ "basic",
480
+ certPath
481
+ ],
482
+ { stdio: "inherit" }
483
+ );
484
+ }
485
+ var targetCA = `/usr/local/share/ca-certificates/${PKG_NAME}.crt`;
486
+ function addToTrustStoresLinux(certPath) {
487
+ logger_default.log("Adding certificate to trusted store. Admin rights may be required.");
488
+ spawnSync("sudo", ["cp", certPath, targetCA]);
489
+ spawnSync("sudo", ["update-ca-certificates"]);
490
+ }
491
+ function addToTrustStoresWin32(certPath) {
492
+ spawnSync("certutil", ["-addstore", "-user", "root", certPath], {
493
+ stdio: "inherit"
494
+ });
495
+ }
496
+ function addToTrustStores(certPath) {
497
+ switch (process.platform) {
498
+ case "darwin":
499
+ return addToTrustStoresDarwin(certPath);
500
+ case "linux":
501
+ return addToTrustStoresLinux(certPath);
502
+ case "win32":
503
+ return addToTrustStoresWin32(certPath);
504
+ }
505
+ }
506
+
507
+ // src/lib/cert/index.ts
421
508
  var CERT_KEY_FILENAME = "localhost-key.pem";
422
509
  var CERT_FILENAME = "localhost-cert.pem";
423
- var generateCert = async (outDir) => {
424
- await fs4.ensureDir(outDir);
425
- const { stdout } = await exec(`mkcert localhost 127.0.0.1 ::1`);
426
- [
427
- { input: "localhost+2.pem", output: CERT_FILENAME },
428
- { input: "localhost+2-key.pem", output: CERT_KEY_FILENAME }
429
- ].forEach(({ input, output }) => {
430
- if (fs4.existsSync(input)) {
431
- fs4.moveSync(`./${input}`, path6.join(outDir, output), {
432
- overwrite: true
433
- });
510
+ function install(options = {}) {
511
+ const { validity = 7300 } = options;
512
+ if (!isSupported) {
513
+ throw new Error(`Platform not supported: "${process.platform}"`);
514
+ }
515
+ if (!fs4.existsSync(rootCAPath) && !fs4.existsSync(rootCAKeyPath)) {
516
+ const ca = createCA({ validity });
517
+ fs4.outputFileSync(rootCAPath, ca.cert);
518
+ fs4.outputFileSync(rootCAKeyPath, ca.key);
519
+ try {
520
+ addToTrustStores(rootCAPath);
521
+ } catch {
522
+ console.warn(
523
+ "\u26A0 Failed to add CA to system trust store. You may need to trust the certificate manually."
524
+ );
434
525
  }
435
- });
436
- return { stdout };
437
- };
526
+ }
527
+ }
528
+ function certificateFor(requestedDomains = []) {
529
+ const validity = 7300;
530
+ install({ validity });
531
+ const requests = Array.isArray(requestedDomains) ? requestedDomains : [requestedDomains];
532
+ const domains = [
533
+ .../* @__PURE__ */ new Set(["localhost", "localhost.localdomain", "127.0.0.1", "0.0.0.0", "::1", ...requests])
534
+ ];
535
+ const ca = {
536
+ cert: fs4.readFileSync(rootCAPath),
537
+ key: fs4.readFileSync(rootCAKeyPath)
538
+ };
539
+ return createCert({ ca, domains, validity });
540
+ }
541
+ function generateCert(outDir) {
542
+ fs4.ensureDirSync(outDir);
543
+ const result = certificateFor();
544
+ fs4.outputFileSync(path7.join(outDir, CERT_FILENAME), result.cert);
545
+ fs4.outputFileSync(path7.join(outDir, CERT_KEY_FILENAME), result.key);
546
+ return result;
547
+ }
438
548
  function hasCertificates(certDir) {
439
- return fs4.existsSync(path6.join(certDir, CERT_KEY_FILENAME)) && fs4.existsSync(path6.join(certDir, CERT_FILENAME));
549
+ return fs4.existsSync(path7.join(certDir, CERT_KEY_FILENAME)) && fs4.existsSync(path7.join(certDir, CERT_FILENAME));
440
550
  }
441
551
  function loadCertificates(certDir) {
442
552
  return {
443
- key: fs4.readFileSync(path6.join(certDir, CERT_KEY_FILENAME)),
444
- cert: fs4.readFileSync(path6.join(certDir, CERT_FILENAME))
553
+ key: fs4.readFileSync(path7.join(certDir, CERT_KEY_FILENAME)),
554
+ cert: fs4.readFileSync(path7.join(certDir, CERT_FILENAME))
445
555
  };
446
556
  }
447
557
 
448
558
  // src/lib/plugin-manifest.ts
449
559
  import fs5 from "fs-extra";
450
- import path7 from "path";
560
+ import path8 from "path";
451
561
  import merge from "deepmerge";
452
562
  var outputManifest = async (env, options) => {
453
563
  const config2 = options?.config || await importK2PluginConfig();
454
564
  const merged = merge(config2.manifest.base, config2.manifest[env] || {});
455
565
  await fs5.mkdirs(PLUGIN_CONTENTS_DIRECTORY);
456
- await fs5.writeJson(path7.join(PLUGIN_CONTENTS_DIRECTORY, "manifest.json"), merged);
566
+ await fs5.writeJson(path8.join(PLUGIN_CONTENTS_DIRECTORY, "manifest.json"), merged);
457
567
  return merged;
458
568
  };
459
569
 
@@ -488,21 +598,21 @@ var getManifest = async (params) => {
488
598
  };
489
599
 
490
600
  // src/commands/plugin-dev/tailwind.ts
491
- import path8 from "path";
601
+ import path9 from "path";
492
602
  import "tailwindcss";
493
- import chalk3 from "chalk";
603
+ import chalk2 from "chalk";
494
604
  async function buildTailwindCSS(params) {
495
605
  const { inputFile, outputFileName, config: config2 } = params;
496
- const inputPath = path8.resolve(inputFile);
497
- const outputPath = path8.join(PLUGIN_DEVELOPMENT_DIRECTORY, outputFileName);
606
+ const inputPath = path9.resolve(inputFile);
607
+ const outputPath = path9.join(PLUGIN_DEVELOPMENT_DIRECTORY, outputFileName);
498
608
  return watchTailwindCSS({
499
609
  input: inputPath,
500
610
  output: outputPath,
501
611
  config: config2,
502
612
  onChanges: ({ output, type }) => {
503
- const outputFileName2 = path8.basename(output);
613
+ const outputFileName2 = path9.basename(output);
504
614
  console.log(
505
- chalk3.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk3.cyan(`[css] `) + outputFileName2 + (type === "init" ? " init" : ` rebuilt`)
615
+ chalk2.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk2.cyan(`[css] `) + outputFileName2 + (type === "init" ? " init" : ` rebuilt`)
506
616
  );
507
617
  }
508
618
  });
@@ -527,20 +637,17 @@ var watchCss = async (pluginConfig) => {
527
637
  ]);
528
638
  };
529
639
 
530
- // src/commands/plugin-dev/upload.ts
531
- import packer from "@kintone/plugin-packer";
532
-
533
640
  // src/lib/plugin-contents.ts
534
641
  import fs6 from "fs-extra";
535
- import path9 from "path";
642
+ import path10 from "path";
536
643
  import htmlMinifier from "html-minifier";
537
644
  var copyPluginContents = async (params = {}) => {
538
- const { inputDir = path9.join("src", "contents"), outputDir = PLUGIN_CONTENTS_DIRECTORY } = params;
645
+ const { inputDir = path10.join("src", "contents"), outputDir = PLUGIN_CONTENTS_DIRECTORY } = params;
539
646
  if (!fs6.existsSync(inputDir)) {
540
647
  await fs6.mkdir(inputDir, { recursive: true });
541
648
  }
542
649
  await fs6.copy(inputDir, outputDir, { overwrite: true });
543
- const configHtmlPath = path9.join(outputDir, "config.html");
650
+ const configHtmlPath = path10.join(outputDir, "config.html");
544
651
  if (!fs6.existsSync(configHtmlPath)) {
545
652
  throw new Error(`Plugin HTML file not found. Create "config.html" in ${inputDir}.`);
546
653
  }
@@ -559,208 +666,165 @@ var copyPluginContents = async (params = {}) => {
559
666
  };
560
667
 
561
668
  // src/lib/zip.ts
562
- import archiver from "archiver";
669
+ import fs8 from "fs-extra";
670
+ import path11 from "path";
671
+ import { zipSync } from "fflate";
672
+
673
+ // src/lib/rsa.ts
674
+ import forge2 from "node-forge";
563
675
  import fs7 from "fs-extra";
564
- import path10 from "path";
565
- import invariant2 from "tiny-invariant";
566
- var outputContentsZip = async (manifest) => {
567
- const archive = archiver("zip", { zlib: { level: 9 } });
568
- archive.on("warning", (error) => {
569
- if (error.code === "ENOENT") {
570
- console.warn(error);
676
+ function sign(contents, privateKeyPem) {
677
+ const key = forge2.pki.privateKeyFromPem(privateKeyPem);
678
+ const md2 = forge2.md.sha1.create();
679
+ md2.update(contents.toString("binary"));
680
+ const signature = key.sign(md2);
681
+ return Buffer.from(signature, "binary");
682
+ }
683
+ function getPublicKeyDer(privateKeyPem) {
684
+ const privateKey = forge2.pki.privateKeyFromPem(privateKeyPem);
685
+ const publicKey = forge2.pki.rsa.setPublicKey(privateKey.n, privateKey.e);
686
+ const publicKeyAsn1 = forge2.pki.publicKeyToAsn1(publicKey);
687
+ const publicKeyDerBytes = forge2.asn1.toDer(publicKeyAsn1).getBytes();
688
+ return Buffer.from(publicKeyDerBytes, "binary");
689
+ }
690
+ function generatePPK(ppkPath) {
691
+ const keypair = forge2.pki.rsa.generateKeyPair(1024);
692
+ const privateKey = forge2.pki.privateKeyToPem(keypair.privateKey);
693
+ fs7.outputFileSync(ppkPath, privateKey);
694
+ return privateKey;
695
+ }
696
+ function generatePluginId(publicKeyDer) {
697
+ const md2 = forge2.md.sha256.create();
698
+ md2.update(publicKeyDer.toString("binary"));
699
+ const hash = Buffer.from(md2.digest().bytes(), "binary");
700
+ const hexDigest = hash.subarray(0, 16).toString("hex");
701
+ return hexDigest.replace(/[0-9a-f]/g, (c) => "abcdefghijklmnop"["0123456789abcdef".indexOf(c)]);
702
+ }
703
+
704
+ // src/lib/zip.ts
705
+ function sourceList(manifest) {
706
+ const sourceTypes = [
707
+ ["desktop", "js"],
708
+ ["desktop", "css"],
709
+ ["mobile", "js"],
710
+ ["mobile", "css"],
711
+ ["config", "js"],
712
+ ["config", "css"]
713
+ ];
714
+ const list = sourceTypes.map(([type, ext]) => manifest[type]?.[ext]).filter(Boolean).reduce((a, b) => a.concat(b), []).filter((file) => !/^https?:\/\//.test(file));
715
+ if (manifest.config?.html) list.push(manifest.config.html);
716
+ list.push(manifest.icon);
717
+ return Array.from(new Set(list));
718
+ }
719
+ function zipFiles(files) {
720
+ const zipObj = {};
721
+ for (const [fileName, fileContent] of Object.entries(files)) {
722
+ let content;
723
+ if (Buffer.isBuffer(fileContent)) {
724
+ content = new Uint8Array(fileContent);
725
+ } else if (typeof fileContent === "string") {
726
+ const fileData = fs8.readFileSync(fileContent);
727
+ content = new Uint8Array(fileData);
571
728
  } else {
572
- throw error;
729
+ throw new Error(`Unsupported file content type for file: ${fileName}`);
573
730
  }
574
- });
575
- const outputZipPath = path10.join(PLUGIN_WORKSPACE_DIRECTORY, "contents.zip");
576
- const outputZipStream = fs7.createWriteStream(outputZipPath);
577
- outputZipStream.on("close", () => {
578
- console.log(`\u{1F4E6} ${archive.pointer()} total bytes`);
579
- });
580
- outputZipStream.on("end", function() {
581
- console.log("\u{1F4E6} Data has been drained");
582
- });
583
- const filterLocalContent = (file) => {
584
- return !/^https?:\/\//.test(file);
585
- };
586
- invariant2(manifest.config?.html, "manifest.config.html is required");
587
- const targetFiles = [
588
- "manifest.json",
589
- .../* @__PURE__ */ new Set([
590
- manifest.icon,
591
- manifest.config.html,
592
- ...(manifest.desktop?.js || []).filter(filterLocalContent),
593
- ...(manifest.desktop?.css || []).filter(filterLocalContent),
594
- ...(manifest.mobile?.js || []).filter(filterLocalContent),
595
- ...(manifest.mobile?.css || []).filter(filterLocalContent),
596
- ...(manifest.config.js || []).filter(filterLocalContent),
597
- ...(manifest.config.css || []).filter(filterLocalContent)
598
- ])
599
- ];
731
+ zipObj[fileName] = content;
732
+ }
733
+ const zipped = zipSync(zipObj);
734
+ return Buffer.from(zipped);
735
+ }
736
+ function createContentsZip(contentsDir, manifest, fileContents = {}) {
737
+ const files = sourceList(manifest).reduce((acc, file) => {
738
+ acc[file] = fileContents[file] || path11.join(contentsDir, file);
739
+ return acc;
740
+ }, {});
741
+ files["manifest.json"] = Buffer.from(JSON.stringify(manifest, null, 2));
742
+ const targetFiles = Object.keys(files);
600
743
  console.group("\u{1F4C1} Target files");
601
744
  targetFiles.forEach((file, i) => {
602
745
  const prefix = i === targetFiles.length - 1 ? "\u2514\u2500" : "\u251C\u2500";
603
746
  console.log(`${prefix} \u{1F4C4} ${file}`);
604
747
  });
605
748
  console.groupEnd();
606
- for (const file of targetFiles) {
607
- const filePath = path10.join(PLUGIN_CONTENTS_DIRECTORY, file);
608
- if (!fs7.existsSync(filePath)) {
609
- throw new Error(`${filePath} does not exist`);
610
- }
611
- archive.file(filePath, { name: file });
749
+ return zipFiles(files);
750
+ }
751
+ function createContentsZipFromDir(manifest) {
752
+ return createContentsZip(PLUGIN_CONTENTS_DIRECTORY, manifest);
753
+ }
754
+ function createPluginZip(params) {
755
+ const { ppkPath, contentsZip } = params;
756
+ let ppkContent;
757
+ if (fs8.existsSync(ppkPath)) {
758
+ ppkContent = fs8.readFileSync(ppkPath, "utf-8");
759
+ } else {
760
+ ppkContent = generatePPK(ppkPath);
612
761
  }
613
- archive.pipe(outputZipStream);
614
- await archive.finalize();
615
- await new Promise((resolve) => outputZipStream.on("close", resolve));
616
- };
617
- var getContentsZipBuffer = async () => {
618
- const outputZipPath = path10.join(PLUGIN_WORKSPACE_DIRECTORY, "contents.zip");
619
- return fs7.readFile(outputZipPath);
620
- };
762
+ const signature = sign(contentsZip, ppkContent);
763
+ const publicKeyDer = getPublicKeyDer(ppkContent);
764
+ const pluginId = generatePluginId(publicKeyDer);
765
+ const pluginZip = zipFiles({
766
+ "contents.zip": contentsZip,
767
+ PUBKEY: publicKeyDer,
768
+ SIGNATURE: signature
769
+ });
770
+ return { zip: pluginZip, id: pluginId, privateKey: ppkContent };
771
+ }
621
772
  var getZipFileNameSuffix = (env) => {
622
773
  return env === "prod" ? "" : `-${env}`;
623
774
  };
624
775
 
625
- // src/commands/plugin-dev/upload.ts
626
- import fs9 from "fs-extra";
627
- import path12 from "path";
628
-
629
776
  // src/lib/kintone-api-client.ts
630
777
  import { config } from "dotenv";
631
- var KintoneApiClient = class {
632
- #baseUrl;
633
- #authHeader;
634
- constructor() {
635
- config();
636
- const {
637
- KINTONE_BASE_URL,
638
- KINTONE_USERNAME,
639
- KINTONE_PASSWORD,
640
- KINTONE_BASIC_AUTH_USERNAME = "",
641
- KINTONE_BASIC_AUTH_PASSWORD = ""
642
- } = process.env;
643
- if (!KINTONE_BASE_URL || !KINTONE_USERNAME || !KINTONE_PASSWORD) {
644
- throw new Error(`.env\u306E\u8A2D\u5B9A\u304C\u4E0D\u5341\u5206\u3067\u3059\u3002\u4EE5\u4E0B\u306E\u30D1\u30E9\u30E1\u30FC\u30BF\u306F\u5FC5\u9808\u3067\u3059
778
+ import { KintoneRestAPIClient } from "@kintone/rest-api-client";
779
+ function createKintoneClient() {
780
+ config();
781
+ const {
782
+ KINTONE_BASE_URL,
783
+ KINTONE_USERNAME,
784
+ KINTONE_PASSWORD,
785
+ KINTONE_BASIC_AUTH_USERNAME,
786
+ KINTONE_BASIC_AUTH_PASSWORD
787
+ } = process.env;
788
+ if (!KINTONE_BASE_URL || !KINTONE_USERNAME || !KINTONE_PASSWORD) {
789
+ throw new Error(`.env\u306E\u8A2D\u5B9A\u304C\u4E0D\u5341\u5206\u3067\u3059\u3002\u4EE5\u4E0B\u306E\u30D1\u30E9\u30E1\u30FC\u30BF\u306F\u5FC5\u9808\u3067\u3059
645
790
  KINTONE_BASE_URL
646
791
  KINTONE_USERNAME
647
792
  KINTONE_PASSWORD`);
648
- }
649
- const authHeader = {
650
- "X-Cybozu-Authorization": Buffer.from(`${KINTONE_USERNAME}:${KINTONE_PASSWORD}`).toString(
651
- "base64"
652
- ),
653
- ...KINTONE_BASIC_AUTH_USERNAME && KINTONE_BASIC_AUTH_PASSWORD && {
654
- Authorization: `Basic ${Buffer.from(
655
- `${KINTONE_BASIC_AUTH_USERNAME}:${KINTONE_BASIC_AUTH_PASSWORD}`
656
- ).toString("base64")}`
657
- }
658
- };
659
- this.#baseUrl = KINTONE_BASE_URL;
660
- this.#authHeader = authHeader;
661
- }
662
- getEndpointUrl(path16) {
663
- return `${this.#baseUrl}${path16}`;
664
- }
665
- async upload(params) {
666
- const { blob, fileName } = params;
667
- const form = new FormData();
668
- form.append("file", blob, fileName);
669
- const uploadResult = await fetch(this.getEndpointUrl("/k/v1/file.json"), {
670
- method: "POST",
671
- headers: this.#authHeader,
672
- body: form
673
- });
674
- const { fileKey } = await uploadResult.json();
675
- return fileKey;
676
- }
677
- async getPlugins(params = {}) {
678
- const url = new URL(this.getEndpointUrl("/k/v1/plugins.json"));
679
- if (params.offset) {
680
- url.searchParams.set("offset", String(params.offset));
681
- }
682
- if (params.limit) {
683
- url.searchParams.set("limit", String(params.limit));
684
- }
685
- const pluginResponse = await fetch(url.toString(), {
686
- headers: this.#authHeader
687
- });
688
- return pluginResponse.json();
689
793
  }
690
- async getAllPlugins() {
691
- const plugins = [];
692
- let offset = 0;
693
- let limit = 100;
694
- let hasMore = true;
695
- while (hasMore) {
696
- const { plugins: currentPlugins } = await this.getPlugins({ offset, limit });
697
- plugins.push(...currentPlugins);
698
- if (currentPlugins.length < limit) {
699
- hasMore = false;
700
- } else {
701
- offset += limit;
794
+ return new KintoneRestAPIClient({
795
+ baseUrl: KINTONE_BASE_URL,
796
+ auth: {
797
+ username: KINTONE_USERNAME,
798
+ password: KINTONE_PASSWORD
799
+ },
800
+ ...KINTONE_BASIC_AUTH_USERNAME && KINTONE_BASIC_AUTH_PASSWORD ? {
801
+ basicAuth: {
802
+ username: KINTONE_BASIC_AUTH_USERNAME,
803
+ password: KINTONE_BASIC_AUTH_PASSWORD
702
804
  }
703
- }
704
- return plugins;
705
- }
706
- async addPlugin(params) {
707
- const { fileKey } = params;
708
- const pluginResponse = await fetch(this.getEndpointUrl("/k/v1/plugin.json"), {
709
- method: "POST",
710
- headers: {
711
- "Content-Type": "application/json",
712
- ...this.#authHeader
713
- },
714
- body: JSON.stringify({
715
- fileKey
716
- })
717
- });
718
- return pluginResponse.json();
719
- }
720
- async updatePlugin(params) {
721
- const pluginResponse = await fetch(this.getEndpointUrl("/k/v1/plugin.json"), {
722
- method: "PUT",
723
- headers: {
724
- "Content-Type": "application/json",
725
- ...this.#authHeader
726
- },
727
- body: JSON.stringify(params)
728
- });
729
- return pluginResponse.json();
730
- }
731
- };
732
-
733
- // src/lib/utils.ts
734
- import fs8 from "fs-extra";
735
- import path11 from "path";
736
- var isEnv = (env) => {
737
- return ["prod", "dev", "standalone"].includes(env);
738
- };
739
- var apiUploadZip = async (params) => {
740
- const { env, pluginId } = params;
741
- const kc = new KintoneApiClient();
742
- const zipFileName = `plugin${getZipFileNameSuffix(env)}.zip`;
743
- const zipFile = new Blob([await fs8.readFile(path11.join(PLUGIN_WORKSPACE_DIRECTORY, zipFileName))]);
744
- const fileKey = await kc.upload({ blob: zipFile, fileName: zipFileName });
745
- const plugins = await kc.getAllPlugins();
746
- const plugin = plugins.find((p) => p.id === pluginId);
747
- if (plugin) {
748
- const json = await kc.updatePlugin({ id: pluginId, fileKey });
749
- if ("errors" in json && json.errors) {
750
- console.error((json.errors.id?.messages ?? []).map((m) => `Error: ${m}`).join("\n"));
751
- }
805
+ } : {}
806
+ });
807
+ }
808
+ async function uploadPlugin(params) {
809
+ const client = createKintoneClient();
810
+ const { fileKey } = await client.file.uploadFile({
811
+ file: { name: params.file.name, data: new Uint8Array(params.file.data) }
812
+ });
813
+ const { plugins } = await client.plugin.getPlugins({ offset: 0, limit: 100 });
814
+ const isUpdate = plugins.some(({ id }) => id === params.pluginId);
815
+ if (isUpdate) {
816
+ await client.plugin.updatePlugin({ id: params.pluginId, fileKey });
752
817
  return { method: "PUT" };
753
818
  }
754
- const result = await kc.addPlugin({ fileKey });
755
- if ("code" in result) {
756
- console.error(`Error: ${result.message}`);
757
- }
819
+ await client.plugin.installPlugin({ fileKey });
758
820
  return { method: "POST" };
759
- };
821
+ }
760
822
 
761
823
  // src/commands/plugin-dev/upload.ts
762
- import chokider from "chokidar";
763
- import chalk4 from "chalk";
824
+ import fs9 from "fs-extra";
825
+ import path12 from "path";
826
+ import chokidar2 from "chokidar";
827
+ import chalk3 from "chalk";
764
828
  var watchContentsAndUploadZip = async (params) => {
765
829
  const { manifest, ppkPath } = params;
766
830
  let initialScanComplete = false;
@@ -771,30 +835,34 @@ var watchContentsAndUploadZip = async (params) => {
771
835
  }
772
836
  await copyPluginContents();
773
837
  console.log(
774
- chalk4.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk4.cyan(`[contents] `) + `updated`
838
+ chalk3.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk3.cyan(`[contents] `) + `updated`
775
839
  );
776
840
  } catch (error) {
777
841
  console.error("Error copying plugin contents:", error);
778
842
  return;
779
843
  }
780
844
  try {
781
- await outputContentsZip(manifest);
782
- const buffer = await getContentsZipBuffer();
783
- const pluginPrivateKey = await fs9.readFile(path12.resolve(ppkPath), "utf8");
784
- const output = await packer(buffer, pluginPrivateKey);
845
+ const contentsZip = createContentsZipFromDir(manifest);
846
+ const { zip, id: pluginId } = createPluginZip({
847
+ ppkPath: path12.resolve(ppkPath),
848
+ contentsZip
849
+ });
785
850
  const zipFileName = `plugin${getZipFileNameSuffix("dev")}.zip`;
786
- await fs9.writeFile(path12.join(PLUGIN_WORKSPACE_DIRECTORY, zipFileName), output.plugin);
787
- const { method } = await apiUploadZip({ env: "dev", pluginId: output.id });
851
+ await fs9.writeFile(path12.join(PLUGIN_WORKSPACE_DIRECTORY, zipFileName), zip);
852
+ const { method } = await uploadPlugin({
853
+ pluginId,
854
+ file: { name: zipFileName, data: zip }
855
+ });
788
856
  console.log(
789
- chalk4.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk4.cyan(`[upload] `) + `uploaded ${method === "POST" ? "(new)" : "(update)"}`
857
+ chalk3.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk3.cyan(`[upload] `) + `uploaded ${method === "POST" ? "(new)" : "(update)"}`
790
858
  );
791
859
  } catch (error) {
792
860
  console.log(
793
- chalk4.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk4.cyan(`[upload] `) + chalk4.red(`failed`) + chalk4.hex("#e5e7eb")(`: ${error?.message ?? "Unknown error"}`)
861
+ chalk3.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk3.cyan(`[upload] `) + chalk3.red(`failed`) + chalk3.hex("#e5e7eb")(`: ${error?.message ?? "Unknown error"}`)
794
862
  );
795
863
  }
796
864
  };
797
- const contentsWatcher = chokider.watch(["src/contents/**/*"], {
865
+ const contentsWatcher = chokidar2.watch(["src/contents/**/*"], {
798
866
  ignored: /node_modules/,
799
867
  persistent: true
800
868
  });
@@ -808,12 +876,12 @@ var watchContentsAndUploadZip = async (params) => {
808
876
  };
809
877
 
810
878
  // src/commands/plugin-dev/index.ts
811
- function command3() {
812
- program3.command("dev").option(
879
+ function command2() {
880
+ program2.command("dev").option(
813
881
  "-p, --ppk <ppk>",
814
882
  ".ppk file path",
815
883
  path13.join(PLUGIN_WORKSPACE_DIRECTORY, "private.ppk")
816
- ).option("-c, --cert-dir <certDir>", "Certificate directory", PLUGIN_WORKSPACE_DIRECTORY).description("Start development server with Vite.").action(action2);
884
+ ).option("-c, --cert-dir <certDir>", "Certificate directory", PLUGIN_WORKSPACE_DIRECTORY).description("Start development server with rsbuild.").action(action2);
817
885
  }
818
886
  async function action2(options) {
819
887
  console.group("\u{1F373} Start development server");
@@ -827,15 +895,12 @@ async function action2(options) {
827
895
  }
828
896
  const port = config2.server?.port ?? DEFAULT_PORT;
829
897
  if (!hasCertificates(certDirPath)) {
830
- console.log(chalk5.yellow("\u{1F4DC} SSL certificates not found. Generating..."));
898
+ console.log(chalk4.yellow("\u{1F4DC} SSL certificates not found. Generating with node-forge..."));
831
899
  try {
832
- await generateCert(certDirPath);
833
- console.log(chalk5.green("\u2705 SSL certificates generated successfully"));
900
+ generateCert(certDirPath);
901
+ console.log(chalk4.green("\u2705 SSL certificates generated successfully"));
834
902
  } catch (error) {
835
- console.log(
836
- chalk5.red("\u274C Failed to generate SSL certificates. Make sure mkcert is installed.")
837
- );
838
- console.log(chalk5.gray(" Install mkcert: https://github.com/FiloSottile/mkcert"));
903
+ console.log(chalk4.red("\u274C Failed to generate SSL certificates."));
839
904
  throw error;
840
905
  }
841
906
  }
@@ -849,83 +914,28 @@ async function action2(options) {
849
914
  if (entryNames.length === 0) {
850
915
  throw new Error("No entry points found for plugin. Check src/config and src/desktop paths.");
851
916
  }
852
- console.log(chalk5.gray(` Entry points: ${entryNames.join(", ")}`));
917
+ console.log(chalk4.gray(` Entry points: ${entryNames.join(", ")}`));
853
918
  const { key, cert } = loadCertificates(certDirPath);
854
- console.log(chalk5.gray(" Building..."));
855
- await buildEntriesWithVite({
919
+ const { port: actualPort } = await startRsbuildDevServer({
856
920
  entries,
857
921
  outDir: outputDir,
858
- mode: "development",
859
- sourcemap: "inline",
860
- minify: false
861
- });
862
- const serverConfig = createViteConfig({
863
- root: outputDir,
864
- server: {
865
- port,
866
- https: { key, cert }
867
- }
868
- });
869
- const server = await createServer(serverConfig);
870
- await server.listen();
871
- console.log(chalk5.green(`
922
+ port,
923
+ https: { key, cert },
924
+ publicDir: outputDir,
925
+ onFirstCompile: () => {
926
+ console.log(chalk4.green(`
872
927
  \u2728 Plugin development server ready!`));
873
- console.log(chalk5.cyan(` Local: https://localhost:${port}`));
874
- console.log(chalk5.gray(` Output: ${outputDir}`));
875
- console.log(chalk5.gray(` Files: config.js, desktop.js`));
876
- console.log(chalk5.gray("\n Watching for changes...\n"));
877
- const chokidar2 = await import("chokidar");
878
- const watchDirs = [
879
- path13.resolve("src", "config"),
880
- path13.resolve("src", "desktop"),
881
- path13.resolve("src", "lib")
882
- ].filter((dir) => fs10.existsSync(dir));
883
- console.log(chalk5.gray(` Watching directories: ${watchDirs.join(", ")}`));
884
- const watcher = chokidar2.watch(watchDirs, {
885
- ignored: /node_modules/,
886
- persistent: true,
887
- ignoreInitial: true
888
- });
889
- const watchExtensions = [".ts", ".tsx", ".js", ".jsx", ".css", ".scss"];
890
- const shouldRebuild = (filePath) => {
891
- const ext = path13.extname(filePath).toLowerCase();
892
- return watchExtensions.includes(ext);
893
- };
894
- const rebuild = async () => {
895
- console.log(chalk5.gray(` ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} Rebuilding...`));
896
- await buildEntriesWithVite({
897
- entries,
898
- outDir: outputDir,
899
- mode: "development",
900
- sourcemap: "inline",
901
- minify: false
902
- });
903
- console.log(chalk5.gray(` ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} Rebuild complete`));
904
- };
905
- watcher.on("ready", () => {
906
- console.log(chalk5.green(" \u2713 File watcher ready"));
907
- });
908
- watcher.on("change", (filePath) => {
909
- if (shouldRebuild(filePath)) {
910
- console.log(chalk5.cyan(` [change] ${filePath}`));
911
- rebuild();
912
- }
913
- });
914
- watcher.on("add", (filePath) => {
915
- if (shouldRebuild(filePath)) {
916
- console.log(chalk5.cyan(` [add] ${filePath}`));
917
- rebuild();
918
- }
919
- });
920
- watcher.on("unlink", (filePath) => {
921
- if (shouldRebuild(filePath)) {
922
- console.log(chalk5.cyan(` [unlink] ${filePath}`));
923
- rebuild();
928
+ console.log(chalk4.cyan(` Local: https://localhost:${actualPort}`));
929
+ console.log(chalk4.gray(` Output: ${outputDir}`));
930
+ console.log(chalk4.gray(` Files: config.js, desktop.js`));
931
+ console.log(chalk4.gray("\n Watching for changes...\n"));
932
+ },
933
+ onRecompile: () => {
934
+ console.log(
935
+ chalk4.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk4.cyan(`[rsbuild] `) + `rebuild complete`
936
+ );
924
937
  }
925
938
  });
926
- watcher.on("error", (error) => {
927
- console.error(chalk5.red(` Watcher error: ${error}`));
928
- });
929
939
  Promise.all([watchContentsAndUploadZip({ manifest, ppkPath }), watchCss(config2)]);
930
940
  } catch (error) {
931
941
  throw error;
@@ -935,18 +945,15 @@ async function action2(options) {
935
945
  }
936
946
 
937
947
  // src/commands/plugin-genkey.ts
938
- import { program as program4 } from "commander";
939
-
940
- // src/commands/genkey-base.ts
941
- async function action3(options) {
942
- const { output } = options;
943
- console.group("\u{1F373} Generate SSL key for localhost");
948
+ import { program as program3 } from "commander";
949
+ function command3() {
950
+ program3.command("genkey").description("Generate SSL certificate for localhost using node-forge.").action(action3);
951
+ }
952
+ async function action3() {
953
+ console.group("\u{1F373} Generate SSL certificate for localhost");
944
954
  try {
945
- const { stdout } = await generateCert(output);
946
- if (stdout) {
947
- console.log(stdout);
948
- }
949
- console.log(`\u{1F511} key generation success. Output to ./${output}`);
955
+ generateCert(PLUGIN_WORKSPACE_DIRECTORY);
956
+ console.log(`\u{1F511} Certificate generated. Output to ./${PLUGIN_WORKSPACE_DIRECTORY}`);
950
957
  } catch (error) {
951
958
  throw error;
952
959
  } finally {
@@ -954,44 +961,29 @@ async function action3(options) {
954
961
  }
955
962
  }
956
963
 
957
- // src/commands/plugin-genkey.ts
958
- function command4() {
959
- program4.command("genkey").description("Generate SSL key for localhost. (Require mkcert)").action(action4);
960
- }
961
- async function action4() {
962
- await action3({ output: PLUGIN_WORKSPACE_DIRECTORY });
963
- }
964
-
965
964
  // src/commands/plugin-init.ts
966
- import { program as program5 } from "commander";
965
+ import { program as program4 } from "commander";
967
966
  import fs11 from "fs-extra";
968
967
  import path14 from "path";
969
- import packer2 from "@kintone/plugin-packer";
970
- function command5() {
971
- program5.command("init").description("generate private.ppk and kitting config").action(action5);
968
+ function command4() {
969
+ program4.command("init").description("generate private.ppk and kitting config").action(action4);
972
970
  }
973
- async function action5() {
971
+ async function action4() {
974
972
  console.group("\u{1F373} Executing plugin initialization setup");
975
973
  try {
976
974
  const manifest = await outputManifest("dev");
977
975
  console.log("\u{1F4DD} manifest.json generated");
978
976
  await copyPluginContents();
979
977
  console.log("\u{1F4C1} contents copied");
980
- let privateKey;
981
- const keyPath = path14.join(PLUGIN_WORKSPACE_DIRECTORY, "private.ppk");
982
- if (fs11.existsSync(keyPath)) {
983
- privateKey = await fs11.readFile(keyPath, "utf8");
984
- }
985
- await outputContentsZip(manifest);
986
- const buffer = await getContentsZipBuffer();
987
- const output = await packer2(buffer, privateKey);
988
- if (!privateKey) {
989
- await fs11.writeFile(path14.join(PLUGIN_WORKSPACE_DIRECTORY, "private.ppk"), output.privateKey);
978
+ const ppkPath = path14.join(PLUGIN_WORKSPACE_DIRECTORY, "private.ppk");
979
+ const contentsZip = createContentsZipFromDir(manifest);
980
+ const { zip, privateKey } = createPluginZip({ ppkPath, contentsZip });
981
+ if (!fs11.existsSync(ppkPath)) {
990
982
  console.log("\u{1F511} private.ppk generated");
991
983
  } else {
992
984
  console.log("\u{1F511} private.ppk already exists. The existing private.ppk will be used.");
993
985
  }
994
- await fs11.writeFile(path14.join(PLUGIN_WORKSPACE_DIRECTORY, "plugin.zip"), output.plugin);
986
+ await fs11.writeFile(path14.join(PLUGIN_WORKSPACE_DIRECTORY, "plugin.zip"), zip);
995
987
  console.log("\u{1F4E6} plugin.zip generated");
996
988
  console.log("\u2728 Plugin initialization setup completed! zip file path is ./.plugin/plugin.zip");
997
989
  } catch (error) {
@@ -1002,11 +994,11 @@ async function action5() {
1002
994
  }
1003
995
 
1004
996
  // src/commands/manifest/index.ts
1005
- import { program as program6 } from "commander";
1006
- function command6() {
1007
- program6.command("manifest").option("-e, --env <env>", "create manifest", "prod").action(action6);
997
+ import { program as program5 } from "commander";
998
+ function command5() {
999
+ program5.command("manifest").option("-e, --env <env>", "create manifest", "prod").action(action5);
1008
1000
  }
1009
- async function action6(options) {
1001
+ async function action5(options) {
1010
1002
  console.group("\u{1F680} Executing manifest generation");
1011
1003
  try {
1012
1004
  const { env } = options;
@@ -1025,12 +1017,12 @@ async function action6(options) {
1025
1017
  }
1026
1018
 
1027
1019
  // src/commands/test/index.ts
1028
- import { program as program7 } from "commander";
1020
+ import { program as program6 } from "commander";
1029
1021
  import fs12 from "fs-extra";
1030
- function command7() {
1031
- program7.command("test").description("test").action(action7);
1022
+ function command6() {
1023
+ program6.command("test").description("test").action(action6);
1032
1024
  }
1033
- async function action7() {
1025
+ async function action6() {
1034
1026
  console.group("package.json");
1035
1027
  const packageJson = fs12.readJSONSync("package.json");
1036
1028
  console.log("package.json detected");
@@ -1042,18 +1034,26 @@ async function action7() {
1042
1034
  }
1043
1035
 
1044
1036
  // src/commands/plugin-zip.ts
1045
- import { program as program8 } from "commander";
1037
+ import { program as program7 } from "commander";
1038
+ import fs14 from "fs-extra";
1039
+ import path16 from "path";
1040
+
1041
+ // src/lib/utils.ts
1046
1042
  import fs13 from "fs-extra";
1047
1043
  import path15 from "path";
1048
- import packer3 from "@kintone/plugin-packer";
1049
- function command8() {
1050
- program8.command("zip").description("generate plugin zip").option("-e, --env <env>", "plugin environment (dev, prod, standalone)", "prod").option(
1044
+ var isEnv = (env) => {
1045
+ return ["prod", "dev", "standalone"].includes(env);
1046
+ };
1047
+
1048
+ // src/commands/plugin-zip.ts
1049
+ function command7() {
1050
+ program7.command("zip").description("generate plugin zip").option("-e, --env <env>", "plugin environment (dev, prod, standalone)", "prod").option(
1051
1051
  "-p, --ppk <ppk>",
1052
1052
  ".ppk file path",
1053
- path15.join(PLUGIN_WORKSPACE_DIRECTORY, "private.ppk")
1054
- ).action(action8);
1053
+ path16.join(PLUGIN_WORKSPACE_DIRECTORY, "private.ppk")
1054
+ ).action(action7);
1055
1055
  }
1056
- async function action8(options) {
1056
+ async function action7(options) {
1057
1057
  console.group("\u{1F373} Executing plugin zip generation");
1058
1058
  try {
1059
1059
  const { env, ppk: ppkPath } = options;
@@ -1064,18 +1064,17 @@ async function action8(options) {
1064
1064
  console.log("\u{1F4C1} contents copied");
1065
1065
  const manifest = await outputManifest(env);
1066
1066
  console.log(`\u{1F4DD} manifest.json generated (${env})`);
1067
- await outputContentsZip(manifest);
1067
+ const contentsZip = createContentsZipFromDir(manifest);
1068
1068
  console.log("\u{1F4E6} contents.zip generated");
1069
- const buffer = await getContentsZipBuffer();
1070
- const privateKey = await fs13.readFile(path15.resolve(ppkPath), "utf8");
1071
- const output = await packer3(buffer, privateKey);
1069
+ const { zip, id } = createPluginZip({ ppkPath: path16.resolve(ppkPath), contentsZip });
1072
1070
  const zipFileName = `plugin${getZipFileNameSuffix(env)}.zip`;
1073
- await fs13.writeFile(path15.join(PLUGIN_WORKSPACE_DIRECTORY, zipFileName), output.plugin);
1071
+ await fs14.writeFile(path16.join(PLUGIN_WORKSPACE_DIRECTORY, zipFileName), zip);
1074
1072
  console.log("\u{1F4E6} plugin.zip generated");
1075
1073
  const version = String(manifest.version);
1076
- await fs13.writeFile(path15.join(PLUGIN_WORKSPACE_DIRECTORY, "version"), version);
1074
+ await fs14.writeFile(path16.join(PLUGIN_WORKSPACE_DIRECTORY, "version"), version);
1077
1075
  console.log(`\u{1F4DD} version file generated (${version})`);
1078
1076
  console.log(`\u2728 Plugin zip generation completed! zip file path is ./.plugin/${zipFileName}`);
1077
+ console.log(` Plugin ID: ${id}`);
1079
1078
  } catch (error) {
1080
1079
  throw error;
1081
1080
  } finally {
@@ -1084,11 +1083,11 @@ async function action8(options) {
1084
1083
  }
1085
1084
 
1086
1085
  // src/commands/lint.ts
1087
- import { program as program9 } from "commander";
1088
- function command9() {
1089
- program9.command("lint").description("Lint source files").option("-c, --config <config>", "Config file path").action(action9);
1086
+ import { program as program8 } from "commander";
1087
+ function command8() {
1088
+ program8.command("lint").description("Lint source files").option("-c, --config <config>", "Config file path").action(action8);
1090
1089
  }
1091
- async function action9(options) {
1090
+ async function action8(options) {
1092
1091
  try {
1093
1092
  lint();
1094
1093
  } catch (error) {
@@ -1098,7 +1097,7 @@ async function action9(options) {
1098
1097
  }
1099
1098
 
1100
1099
  // src/plugin.ts
1101
- program10.name("plugin").version("1.12.0").description("\u{1F373} kintone kitchen \u{1F373} for kintone plugin");
1100
+ program9.name("plugin").version("4.0.0").description("\u{1F373} kintone kitchen \u{1F373} for kintone plugin");
1102
1101
  command();
1103
1102
  command2();
1104
1103
  command3();
@@ -1107,6 +1106,5 @@ command5();
1107
1106
  command6();
1108
1107
  command7();
1109
1108
  command8();
1110
- command9();
1111
- program10.parse(process.argv);
1109
+ program9.parse(process.argv);
1112
1110
  //# sourceMappingURL=plugin.js.map