@incajs/cli 0.0.1 → 0.0.3

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/cli.js CHANGED
@@ -1,20 +1,79 @@
1
- import e from "node:path";
2
- import { build as t } from "vite";
3
- import n from "@vitejs/plugin-vue";
4
- import { existsSync as r } from "node:fs";
5
- import { chmod as i, cp as a, mkdir as o, readFile as s, readdir as c, rm as l, writeFile as u } from "node:fs/promises";
6
- import { createRequire as d } from "node:module";
7
- import { spawn as f } from "node:child_process";
8
- import { once as p } from "node:events";
9
- import m from "node:readline";
10
- import { setTimeout as h } from "node:timers/promises";
1
+ import { i as e, n as t, o as n, r, t as i } from "./chunks/defaults-D_1rymg4.js";
2
+ import a from "node:path";
3
+ import { existsSync as o } from "node:fs";
4
+ import { chmod as s, cp as c, mkdir as l, readFile as u, readdir as d, rm as f, writeFile as p } from "node:fs/promises";
5
+ import { styleText as m } from "node:util";
6
+ import { build as h } from "vite";
7
+ import g from "@vitejs/plugin-vue";
8
+ import { createRequire as _ } from "node:module";
9
+ import { spawn as v } from "node:child_process";
10
+ import { once as y } from "node:events";
11
+ import b from "node:readline";
12
+ import { setTimeout as x } from "node:timers/promises";
13
+ //#region src/error.mts
14
+ var S = class extends Error {
15
+ code;
16
+ name = "IncaError";
17
+ constructor(e, t) {
18
+ super(t), this.code = e;
19
+ }
20
+ };
21
+ //#endregion
22
+ //#region src/config/loader.mts
23
+ async function C(e) {
24
+ let { config: t } = await n({
25
+ cwd: e,
26
+ name: "inca",
27
+ packageJson: "inca",
28
+ rcFile: !1,
29
+ globalRc: !1,
30
+ giget: !1,
31
+ extend: !1
32
+ });
33
+ return {
34
+ entry: t.entry ? a.resolve(e, t.entry) : void 0,
35
+ outDir: a.resolve(e, t.outDir ?? i.outDir)
36
+ };
37
+ }
38
+ async function ee(e) {
39
+ let s = a.join(e, "package.json"), c;
40
+ try {
41
+ c = await u(s, "utf8");
42
+ } catch {
43
+ throw new S("ERR_INCA_PACKAGE_JSON_NOT_FOUND", `no package.json found at ${s}`);
44
+ }
45
+ let l = JSON.parse(c), { config: d, layers: f } = await n({
46
+ cwd: e,
47
+ name: "inca",
48
+ packageJson: "inca",
49
+ rcFile: !1,
50
+ globalRc: !1,
51
+ giget: !1,
52
+ extend: !1
53
+ }), p = f?.find((e) => e.configFile === "package.json"), m = Object.keys(p?.config ?? {}).length > 0, h = d.productName ?? r(l.name);
54
+ if (!h) throw new S("ERR_INCA_PRODUCT_NAME_MISSING", `${s} needs a "name", or "productName" in inca.config.ts`);
55
+ let g = d.version ?? l.version ?? i.version, _ = d.identifier ?? t(h), v;
56
+ if (d.icon && (v = a.resolve(e, d.icon), !o(v))) throw new S("ERR_INCA_ICON_NOT_FOUND", `"icon" points to ${v}, which doesn't exist`);
57
+ let y = d.entry ? a.resolve(e, d.entry) : void 0, b = a.resolve(e, d.outDir ?? i.outDir);
58
+ return {
59
+ productName: h,
60
+ identifier: _,
61
+ identifierIsDefault: d.identifier === void 0,
62
+ version: g,
63
+ icon: v,
64
+ entry: y,
65
+ outDir: b,
66
+ usedPackageJsonKey: m
67
+ };
68
+ }
69
+ //#endregion
11
70
  //#region src/adapter/vite/captureOutput.mts
12
- function g(e) {
71
+ function te(e) {
13
72
  return {
14
73
  name: "inca:capture-output",
15
74
  writeBundle(t, n) {
16
75
  let r = Object.keys(n), i = Object.values(n).find((e) => e.type === "chunk" && e.isEntry);
17
- if (!i) throw Error("inca: build produced no entry chunk");
76
+ if (!i) throw new S("ERR_INCA_BUILD_NO_ENTRY_CHUNK", "build produced no entry chunk");
18
77
  e({
19
78
  entryFile: i.fileName,
20
79
  files: r
@@ -23,27 +82,82 @@ function g(e) {
23
82
  };
24
83
  }
25
84
  //#endregion
85
+ //#region src/adapter/vite/logger.mts
86
+ var ne = "Build failed with ";
87
+ function re(e, t) {
88
+ let n = /* @__PURE__ */ new WeakSet(), r = /* @__PURE__ */ new Set(), i = {
89
+ hasWarned: !1,
90
+ info(t) {
91
+ e.write(`${t}\n`);
92
+ },
93
+ warn(e) {
94
+ i.hasWarned = !0, t.write(`${e}\n`);
95
+ },
96
+ warnOnce(e) {
97
+ r.has(e) || (r.add(e), i.warn(e));
98
+ },
99
+ error(e, r) {
100
+ i.hasWarned = !0, r?.error && n.add(r.error), !e.includes(ne) && t.write(`${e.replace(/\n\s+at .*/g, "")}\n`);
101
+ },
102
+ clearScreen() {},
103
+ hasErrorLogged(e) {
104
+ return n.has(e);
105
+ }
106
+ };
107
+ return i;
108
+ }
109
+ //#endregion
110
+ //#region src/adapter/vite/unsupported.mts
111
+ var w = /\.(?:css|pcss|postcss|sass|scss|less|styl|stylus)(?:\?|$)/, T = [{
112
+ code: "ERR_INCA_UNSUPPORTED_STYLE",
113
+ name: "a <style> block",
114
+ matches: (e) => e.includes("vue&type=style"),
115
+ hint: "the renderer applies no stylesheet — use a :style binding instead"
116
+ }, {
117
+ code: "ERR_INCA_UNSUPPORTED_STYLESHEET",
118
+ name: "a stylesheet import",
119
+ matches: (e) => w.test(e),
120
+ hint: "the renderer applies no stylesheet — use a :style binding instead"
121
+ }];
122
+ function E(e = T) {
123
+ return {
124
+ name: "inca:reject-unsupported",
125
+ enforce: "pre",
126
+ transform(t, n) {
127
+ let r = e.find((e) => e.matches(n));
128
+ if (!r) return null;
129
+ let i = a.relative(process.cwd(), n.split("?")[0] ?? n);
130
+ throw new S(r.code, `${r.code}: ${i} uses ${r.name}, unsupported for now: ${r.hint}`);
131
+ }
132
+ };
133
+ }
134
+ //#endregion
26
135
  //#region src/adapter/vite/config.mts
27
- var _ = "bundle.js";
28
- function v({ entry: t, outDir: r, mode: i, watch: a, onOutput: o }) {
136
+ var D = "bundle.js";
137
+ function O({ entry: e, outDir: t, mode: n, watch: r, onOutput: i, stdout: o, stderr: s, quiet: c }) {
29
138
  return {
30
139
  configFile: !1,
31
- root: e.dirname(t),
32
- mode: i,
140
+ root: a.dirname(e),
141
+ mode: n,
33
142
  clearScreen: !1,
34
- logLevel: "silent",
35
- define: { "process.env.NODE_ENV": JSON.stringify(i) },
36
- plugins: [n({ template: { compilerOptions: { runtimeModuleName: "@vue/runtime-core" } } }), g(o)],
143
+ logLevel: c ? "silent" : "info",
144
+ customLogger: re(o, s),
145
+ define: { "process.env.NODE_ENV": JSON.stringify(n) },
146
+ plugins: [
147
+ g({ template: { compilerOptions: { runtimeModuleName: "@vue/runtime-core" } } }),
148
+ E(),
149
+ te(i)
150
+ ],
37
151
  build: {
38
152
  lib: {
39
- entry: t,
153
+ entry: e,
40
154
  formats: ["es"],
41
- fileName: () => _
155
+ fileName: () => D
42
156
  },
43
- outDir: r,
44
- emptyOutDir: i === "production",
45
- minify: i === "production",
46
- watch: a ? {} : void 0,
157
+ outDir: t,
158
+ emptyOutDir: n === "production",
159
+ minify: n === "production",
160
+ watch: r ? {} : void 0,
47
161
  rolldownOptions: { output: {
48
162
  chunkFileNames: "chunks/[name]-[hash].js",
49
163
  assetFileNames: "assets/[name]-[hash][extname]"
@@ -53,138 +167,93 @@ function v({ entry: t, outDir: r, mode: i, watch: a, onOutput: o }) {
53
167
  }
54
168
  //#endregion
55
169
  //#region src/adapter/vite/build.mts
56
- async function y({ entry: n, outDir: r }) {
57
- let i;
58
- if (await t(v({
59
- entry: n,
60
- outDir: r,
170
+ async function k({ entry: e, outDir: t, stdout: n = process.stdout, stderr: r = process.stderr, quiet: i = !1 }) {
171
+ let o;
172
+ if (await h(O({
173
+ entry: e,
174
+ outDir: t,
61
175
  mode: "production",
62
176
  watch: !1,
63
- onOutput: (t) => {
64
- i = {
65
- outDir: r,
66
- entryFile: e.join(r, t.entryFile),
67
- files: t.files
177
+ stdout: n,
178
+ stderr: r,
179
+ quiet: i,
180
+ onOutput: (e) => {
181
+ o = {
182
+ outDir: t,
183
+ entryFile: a.join(t, e.entryFile),
184
+ files: e.files
68
185
  };
69
186
  }
70
- })), !i) throw Error("inca: build produced no output");
71
- return i;
72
- }
73
- //#endregion
74
- //#region src/adapter/vite/watch.mts
75
- async function b({ onBuild: n, onError: r, ...i }) {
76
- let { outDir: a } = i, o = await t(v({
77
- ...i,
78
- watch: !0,
79
- onOutput: (t) => {
80
- n({
81
- outDir: a,
82
- entryFile: e.join(a, t.entryFile),
83
- files: t.files
84
- });
85
- }
86
- }));
87
- return o.on("event", (e) => {
88
- e.code === "ERROR" && r({
89
- message: e.error.message,
90
- stack: e.error.stack ?? null
91
- });
92
- }), { close: () => o.close() };
93
- }
94
- //#endregion
95
- //#region src/defaultBundler.mts
96
- var x = {
97
- watch: b,
98
- build: y
99
- };
100
- //#endregion
101
- //#region src/entry.mts
102
- async function S(t) {
103
- let n = e.join(t, "src/main.mts");
104
- if (r(n)) return n;
105
- let i = e.join(t, "src/App.vue");
106
- if (r(i)) return C(i, t);
107
- throw Error(`no app entry found — expected ${n} or ${i}`);
108
- }
109
- async function C(t, n) {
110
- let r = e.join(n, "node_modules/.inca");
111
- await o(r, { recursive: !0 });
112
- let i = e.join(r, "entry.mts"), a = JSON.stringify(t.split(e.sep).join("/"));
113
- return await u(i, `import { createIncaApp } from "incajs/vue";\nimport App from ${a};\ncreateIncaApp(App).mount();\n`), i;
114
- }
115
- //#endregion
116
- //#region src/build.mts
117
- async function w(t = {}) {
118
- let n = t.cwd ?? process.cwd(), r = e.join(n, "dist"), i = t.bundler ?? x, a = t.entry ?? await S(n);
119
- return i.build({
120
- entry: a,
121
- outDir: r
122
- });
187
+ })), !o) throw new S("ERR_INCA_BUILD_NO_OUTPUT", "build produced no output");
188
+ return o;
123
189
  }
124
190
  //#endregion
125
191
  //#region src/dev-client/hostBin.mts
126
- var T = "INCA_HOST_BIN";
127
- function E() {
192
+ var A = "INCA_HOST_BIN";
193
+ function j() {
128
194
  let e = process.platform === "darwin" || process.platform === "linux" ? process.platform : void 0, t = process.arch === "arm64" || process.arch === "x64" ? process.arch : void 0;
129
195
  return e && t ? `@incajs/host-${e}-${t}` : void 0;
130
196
  }
131
- function D() {
132
- let e = E();
197
+ function M() {
198
+ let e = j();
133
199
  if (e) try {
134
- return d(import.meta.url).resolve(`${e}/bin/inca-host`);
200
+ return _(import.meta.url).resolve(`${e}/bin/inca-host`);
135
201
  } catch {
136
202
  return;
137
203
  }
138
204
  }
139
- function O() {
140
- let e = process.env[T];
205
+ function N() {
206
+ let e = process.env[A];
141
207
  if (e) return e;
142
- let t = D();
208
+ let t = M();
143
209
  if (t) return t;
144
- let n = E(), r = n ? `no ${n} package is installed for it` : `this platform (${process.platform}/${process.arch}) has no published package`;
145
- throw Error(`no inca-host binary found — ${r}, and ${T} isn't set to one`);
210
+ let n = j();
211
+ throw new S("ERR_INCA_HOST_BIN_UNRESOLVED", `no inca-host binary found — ${n ? `no ${n} package is installed for it` : `this platform (${process.platform}/${process.arch}) has no published package`}, and ${A} isn't set to one`);
146
212
  }
147
213
  //#endregion
148
214
  //#region src/dev-client/hostError.mts
149
- var k = class extends Error {
215
+ var P = class extends Error {
150
216
  code;
151
217
  hostStack;
152
218
  constructor(e, t, n = null) {
153
219
  super(e), this.code = t, this.hostStack = n, this.name = "HostError";
154
220
  }
155
221
  };
156
- function A(e) {
222
+ function ie(e) {
157
223
  return typeof e == "object" && !!e && e.jsonrpc === "2.0";
158
224
  }
159
225
  //#endregion
160
226
  //#region src/dev-client/hostClient.mts
161
- var j = (e) => {
227
+ var ae = (e) => {
162
228
  process.stderr.write(e.endsWith("\n") ? e : `${e}\n`);
163
- }, M = class {
229
+ }, oe = class {
164
230
  #e;
165
231
  #t;
166
232
  #n = 1;
167
233
  #r = /* @__PURE__ */ new Map();
234
+ #i = !1;
168
235
  constructor(e) {
169
236
  this.#e = e;
170
237
  }
171
238
  async start() {
172
- let e = this.#e.hostBin ?? O(), t = f(e, ["--dev", this.#e.entryFile], { stdio: [
239
+ let e = this.#e.hostBin ?? N(), t = v(e, ["--dev", this.#e.entryFile], { stdio: [
173
240
  "pipe",
174
241
  "pipe",
175
242
  "pipe"
176
243
  ] });
177
244
  this.#t = t;
178
- let n = this.#e.onStderr ?? j;
179
- t.stderr.setEncoding("utf8"), t.stderr.on("data", (e) => n(e)), m.createInterface({ input: t.stdout }).on("line", (e) => {
180
- this.#i(e, n);
245
+ let n = this.#e.onStderr ?? ae;
246
+ t.stderr.setEncoding("utf8"), t.stderr.on("data", (e) => n(e)), t.stdin.on("error", (e) => {
247
+ e.code !== "EPIPE" && n(`inca-host stdin: ${e.message}\n`);
248
+ }), b.createInterface({ input: t.stdout }).on("line", (e) => {
249
+ this.#a(e, n);
181
250
  }), t.on("exit", (e, t) => {
182
251
  let n = /* @__PURE__ */ Error(`inca-host exited (code=${String(e)}, signal=${String(t)}) before answering`);
183
252
  for (let { reject: e } of this.#r.values()) e(n);
184
- this.#r.clear();
185
- }), await p(t, "spawn");
253
+ this.#r.clear(), this.#i || this.#e.onExit?.(e, t);
254
+ }), await y(t, "spawn");
186
255
  }
187
- #i(e, t) {
256
+ #a(e, t) {
188
257
  let n;
189
258
  try {
190
259
  n = JSON.parse(e);
@@ -192,23 +261,23 @@ var j = (e) => {
192
261
  t(`[stray stdout] ${e}`);
193
262
  return;
194
263
  }
195
- if (!A(n)) {
264
+ if (!ie(n)) {
196
265
  t(`[stray stdout] ${e}`);
197
266
  return;
198
267
  }
199
268
  if ("method" in n) {
200
- this.#a(n.method, n.params, t);
269
+ this.#o(n.method, n.params, t);
201
270
  return;
202
271
  }
203
272
  let r = this.#r.get(n.id);
204
- r && (this.#r.delete(n.id), "error" in n ? r.reject(new k(n.error.message, n.error.code, n.error.data?.stack ?? null)) : r.resolve(n.result));
273
+ r && (this.#r.delete(n.id), "error" in n ? r.reject(new P(n.error.message, n.error.code, n.error.data?.stack ?? null)) : r.resolve(n.result));
205
274
  }
206
- #a(e, t, n) {
275
+ #o(e, t, n) {
207
276
  switch (e) {
208
277
  case "ready": {
209
278
  let { protocol: e } = t;
210
279
  if (e !== 0) {
211
- n(`inca-host speaks protocol ${String(e)}, this package was built for 0 — stopping it rather than carrying on`), this.#t && this.#o(this.#t);
280
+ n(`inca-host speaks protocol ${String(e)}, this package was built for 0 — stopping it rather than carrying on`), this.#t && this.#s(this.#t);
212
281
  return;
213
282
  }
214
283
  this.#e.onReady?.();
@@ -223,8 +292,9 @@ var j = (e) => {
223
292
  }
224
293
  }
225
294
  }
226
- async #o(e) {
227
- let t = p(e, "exit");
295
+ async #s(e) {
296
+ this.#i = !0;
297
+ let t = y(e, "exit");
228
298
  e.kill(), await t;
229
299
  }
230
300
  async call(e, t) {
@@ -240,242 +310,350 @@ var j = (e) => {
240
310
  this.#r.set(r, {
241
311
  resolve: e,
242
312
  reject: t
243
- }), n.stdin.write(`${i}\n`);
313
+ }), n.stdin.write(`${i}\n`, (e) => {
314
+ e && (this.#r.delete(r), t(e));
315
+ });
244
316
  });
245
317
  }
246
318
  async stop(e = 2e3) {
247
319
  let t = this.#t;
248
320
  if (!t || t.exitCode !== null || t.signalCode !== null) return;
249
- let n = p(t, "exit");
250
- this.call("shutdown").catch(() => {}), await Promise.race([n.then(() => "exited"), h(e).then(() => "timeout")]) === "timeout" && (t.kill(), await n);
321
+ this.#i = !0;
322
+ let n = y(t, "exit");
323
+ this.call("shutdown").catch(() => {}), await Promise.race([n.then(() => "exited"), x(e).then(() => "timeout")]) === "timeout" && (t.kill(), await n);
251
324
  }
252
- };
253
- //#endregion
254
- //#region src/fault.mts
255
- function N(e) {
256
- return e instanceof k ? {
325
+ }, F = "[inca]", I = new Intl.DateTimeFormat(void 0, {
326
+ hour: "numeric",
327
+ minute: "numeric",
328
+ second: "numeric"
329
+ });
330
+ function L(e, t, n) {
331
+ let r = m(["bold", n], F, { stream: e });
332
+ return t.timestamp ? `${m("dim", I.format(/* @__PURE__ */ new Date()), { stream: e })} ${r}` : r;
333
+ }
334
+ function R(e, t, n = {}) {
335
+ e.write(`${L(e, n, "cyan")} ${t}\n`);
336
+ }
337
+ function z(e) {
338
+ let t = e.code;
339
+ return typeof t == "string" ? t : null;
340
+ }
341
+ function B(e) {
342
+ return /\bERR_INCA_[A-Z0-9_]+/.exec(e)?.[0] ?? null;
343
+ }
344
+ function V(e) {
345
+ let t = e.stack;
346
+ if (!t) return null;
347
+ for (let n of [`${e.name}: ${e.message}`, e.message]) if (t.startsWith(n)) return t.slice(n.length).replace(/^\r?\n/, "") || null;
348
+ return t;
349
+ }
350
+ function H(e) {
351
+ let t = /^(?:\w*Error: )?(ERR_INCA_[A-Z0-9_]+): /.exec(e);
352
+ return t ? {
353
+ message: e.slice(t[0].length),
354
+ stack: null,
355
+ code: t[1]
356
+ } : {
357
+ message: e.replace(/^\w*Error: /, ""),
358
+ stack: null,
359
+ code: null
360
+ };
361
+ }
362
+ function U(e) {
363
+ return e instanceof P ? {
257
364
  message: e.message,
258
- stack: e.hostStack
365
+ stack: e.hostStack,
366
+ code: z(e)
259
367
  } : e instanceof Error ? {
260
368
  message: e.message,
261
- stack: e.stack ?? null
369
+ stack: V(e),
370
+ code: z(e) ?? B(e.message)
262
371
  } : {
263
372
  message: String(e),
264
- stack: null
373
+ stack: null,
374
+ code: null
265
375
  };
266
376
  }
267
- function P(e, t, n) {
268
- e.write(`[inca] ${t}: ${n.message}\n`), n.stack && e.write(`${n.stack}\n`);
377
+ function W(e, t, n, r = {}) {
378
+ let i = n.code ? ` (${m("bold", n.code, { stream: e })})` : "";
379
+ e.write(`${L(e, r, "red")} ${t}${i}: ${n.message}\n`), n.stack && e.write(`${n.stack}\n`);
380
+ }
381
+ //#endregion
382
+ //#region src/adapter/vite/watch.mts
383
+ async function G({ onBuild: e, onError: t, stdout: n = process.stdout, stderr: r = process.stderr, quiet: i = !1, ...o }) {
384
+ let { outDir: s } = o, c, l = await h(O({
385
+ ...o,
386
+ watch: !0,
387
+ stdout: n,
388
+ stderr: r,
389
+ quiet: i,
390
+ onOutput: (t) => {
391
+ e({
392
+ outDir: s,
393
+ entryFile: a.join(s, t.entryFile),
394
+ files: t.files,
395
+ changed: c
396
+ }), c = void 0;
397
+ }
398
+ }));
399
+ return l.on("change", (e) => {
400
+ c ??= {
401
+ file: e,
402
+ at: Date.now()
403
+ };
404
+ }), l.on("event", (e) => {
405
+ if (e.code !== "ERROR") return;
406
+ c = void 0;
407
+ let { errors: n } = e.error;
408
+ t(H(n?.[0]?.message ?? e.error.message));
409
+ }), { close: () => l.close() };
410
+ }
411
+ //#endregion
412
+ //#region src/defaultBundler.mts
413
+ var K = {
414
+ watch: G,
415
+ build: k
416
+ };
417
+ //#endregion
418
+ //#region src/entry.mts
419
+ async function q(e) {
420
+ let t = a.join(e, "src/main.mts");
421
+ if (o(t)) return t;
422
+ let n = a.join(e, "src/App.vue");
423
+ if (o(n)) return se(n, e);
424
+ throw new S("ERR_INCA_ENTRY_NOT_FOUND", `no app entry found — expected ${t} or ${n}`);
425
+ }
426
+ async function se(e, t) {
427
+ let n = a.join(t, "node_modules/.inca");
428
+ await l(n, { recursive: !0 });
429
+ let r = a.join(n, "entry.mts"), i = JSON.stringify(e.split(a.sep).join("/"));
430
+ return await p(r, `import { createIncaApp } from "incajs/vue";\nimport App from ${i};\ncreateIncaApp(App).mount();\n`), r;
431
+ }
432
+ //#endregion
433
+ //#region src/build.mts
434
+ async function J(e = {}) {
435
+ let t = e.cwd ?? process.cwd(), n = e.config ?? await C(t), r = n.outDir, i = e.bundler ?? K, a = e.entry ?? n.entry ?? await q(t);
436
+ return i.build({
437
+ entry: a,
438
+ outDir: r,
439
+ stdout: e.stdout,
440
+ stderr: e.stderr
441
+ });
442
+ }
443
+ //#endregion
444
+ //#region src/dev-lock.mts
445
+ function ce(e) {
446
+ return a.join(e, "node_modules/.inca/dev.pid");
447
+ }
448
+ function le(e) {
449
+ try {
450
+ return process.kill(e, 0), !0;
451
+ } catch (e) {
452
+ return e.code === "EPERM";
453
+ }
454
+ }
455
+ async function ue(e) {
456
+ let t = ce(e), n = Number.parseInt(await u(t, "utf8").catch(() => ""), 10);
457
+ if (Number.isInteger(n) && le(n)) throw new S("ERR_INCA_DEV_RUNNING", `inca dev is already running for this app (pid ${String(n)})`);
458
+ return await l(a.dirname(t), { recursive: !0 }), await p(t, String(process.pid)), () => f(t, { force: !0 });
269
459
  }
270
460
  //#endregion
271
461
  //#region src/dev.mts
272
- async function F(t, n) {
273
- let r = new Set(n), i;
462
+ var Y = { timestamp: !0 };
463
+ async function de(e, t) {
464
+ let n = new Set(t), r;
274
465
  try {
275
- i = await c(t, {
466
+ r = await d(e, {
276
467
  recursive: !0,
277
468
  withFileTypes: !0
278
469
  });
279
470
  } catch {
280
471
  return;
281
472
  }
282
- await Promise.all(i.filter((e) => e.isFile()).map((n) => e.relative(t, e.join(n.parentPath, n.name))).filter((e) => !r.has(e)).map((n) => l(e.join(t, n), { force: !0 })));
473
+ await Promise.all(r.filter((e) => e.isFile()).map((t) => a.relative(e, a.join(t.parentPath, t.name))).filter((e) => !n.has(e)).map((t) => f(a.join(e, t), { force: !0 })));
283
474
  }
284
- async function I(t) {
285
- let n = t.cwd ?? process.cwd(), r = e.join(n, "dist"), i = t.bundler ?? x, a = t.stdout ?? process.stdout, o = t.stderr ?? process.stderr, s = t.entry ?? await S(n), c, l = !1, u = !1, d = Promise.resolve();
286
- async function f() {
475
+ async function fe(e) {
476
+ let t = e.cwd ?? process.cwd(), n = await C(t), r = await ue(t), i = n.outDir, o = e.bundler ?? K, s = e.stdout ?? process.stdout, c = e.stderr ?? process.stderr, l = e.entry ?? n.entry ?? await q(t), u, d = !1, f = !1, p = Promise.resolve(), h = () => {}, g = new Promise((e) => {
477
+ h = e;
478
+ });
479
+ async function _() {
287
480
  try {
288
- await c?.call("reload");
481
+ return await u?.call("reload"), !0;
289
482
  } catch (e) {
290
- P(o, "reload failed", N(e));
483
+ return W(c, "reload failed", U(e), Y), !1;
291
484
  }
292
485
  }
293
- async function p(e) {
294
- if (await F(e.outDir, e.files), !c) {
295
- let n = new M({
296
- entryFile: e.entryFile,
297
- hostBin: t.hostBin,
298
- onStderr: (e) => o.write(e),
486
+ async function v(n) {
487
+ if (await de(n.outDir, n.files), !u) {
488
+ let t = new oe({
489
+ entryFile: n.entryFile,
490
+ hostBin: e.hostBin,
491
+ onStderr: (e) => c.write(e),
299
492
  onReady: () => {
300
- l = !0, a.write("[inca] ready\n"), u && (u = !1, f());
493
+ d = !0, R(s, "ready", Y), f && (f = !1, _());
301
494
  },
302
- onAppError: (e) => P(o, "app error", e)
495
+ onAppError: (e) => W(c, "app error", e, Y),
496
+ onExit: () => {
497
+ R(s, "host exited — stopping", Y), h();
498
+ }
303
499
  });
304
500
  try {
305
- await n.start();
501
+ await t.start();
306
502
  } catch (e) {
307
- P(o, "failed to start inca-host", N(e));
503
+ W(c, "failed to start inca-host", U(e), Y);
308
504
  return;
309
505
  }
310
- c = n;
506
+ u = t;
311
507
  return;
312
508
  }
313
- if (!l) {
314
- u = !0;
509
+ if (!d) {
510
+ f = !0;
315
511
  return;
316
512
  }
317
- await f();
513
+ if (await _() && n.changed) {
514
+ let e = m("dim", a.relative(t, n.changed.file), { stream: s }), r = Date.now() - n.changed.at;
515
+ R(s, `${m("green", "reload")} ${e} (${r}ms)`, Y);
516
+ }
318
517
  }
319
- let m = await i.watch({
320
- entry: s,
321
- outDir: r,
518
+ let y = await o.watch({
519
+ entry: l,
520
+ outDir: i,
322
521
  mode: "development",
522
+ stdout: s,
523
+ stderr: c,
323
524
  onBuild: (e) => {
324
- d = d.then(() => p(e));
525
+ p = p.then(() => v(e));
325
526
  },
326
527
  onError: (e) => {
327
- P(o, "build failed", e);
528
+ W(c, "build failed", e, Y);
328
529
  }
329
530
  });
330
- await new Promise((e) => {
331
- if (t.signal.aborted) {
332
- e();
333
- return;
334
- }
335
- t.signal.addEventListener("abort", () => e(), { once: !0 });
336
- }), await d, await c?.stop(), await m.close();
337
- }
338
- //#endregion
339
- //#region src/metadata.mts
340
- function L(e) {
341
- let t = e.indexOf("/");
342
- return e.startsWith("@") && t !== -1 ? e.slice(t + 1) : e;
343
- }
344
- function R(e) {
345
- return e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
346
- }
347
- async function z(t) {
348
- let n = e.join(t, "package.json"), i;
349
- try {
350
- i = await s(n, "utf8");
351
- } catch {
352
- throw Error(`no package.json found at ${n}`);
353
- }
354
- let a = JSON.parse(i), o = a.inca ?? {}, c = o.productName ?? (a.name ? L(a.name) : void 0);
355
- if (!c) throw Error(`${n} needs a "name", or "inca": { "productName" }`);
356
- let l = a.version ?? "0.0.0", u = o.identifier ?? `org.inca.${R(c)}`, d;
357
- if (o.icon && (d = e.resolve(t, o.icon), !r(d))) throw Error(`"inca.icon" points to ${d}, which doesn't exist`);
358
- return {
359
- productName: c,
360
- identifier: u,
361
- identifierIsDefault: o.identifier === void 0,
362
- version: l,
363
- icon: d
364
- };
531
+ e.signal.aborted ? h() : e.signal.addEventListener("abort", () => h(), { once: !0 }), await g, await p, await u?.stop(), await y.close(), await r();
365
532
  }
366
533
  //#endregion
367
534
  //#region src/plist.mts
368
- function B(e) {
535
+ function X(e) {
369
536
  return e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
370
537
  }
371
- function V(e) {
372
- return typeof e == "boolean" ? e ? "<true/>" : "<false/>" : `<string>${B(e)}</string>`;
538
+ function pe(e) {
539
+ return typeof e == "boolean" ? e ? "<true/>" : "<false/>" : `<string>${X(e)}</string>`;
373
540
  }
374
- function H(e) {
541
+ function me(e) {
375
542
  return `<?xml version="1.0" encoding="UTF-8"?>
376
543
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
377
544
  <plist version="1.0">
378
545
  <dict>
379
- ${Object.entries(e).map(([e, t]) => `\t<key>${B(e)}</key>\n\t${V(t)}`).join("\n")}\n</dict>
546
+ ${Object.entries(e).map(([e, t]) => `\t<key>${X(e)}</key>\n\t${pe(t)}`).join("\n")}\n</dict>
380
547
  </plist>
381
548
  `;
382
549
  }
383
550
  //#endregion
384
551
  //#region src/package.mts
385
- function U() {
552
+ function he() {
386
553
  if (process.platform === "darwin") return "macos";
387
554
  if (process.platform === "linux") return "linux";
388
- throw Error(`inca package doesn't support ${process.platform} yet`);
555
+ throw new S("ERR_INCA_PLATFORM_UNSUPPORTED", `inca package doesn't support ${process.platform} yet`);
389
556
  }
390
- async function W(t, n) {
391
- await Promise.all(t.files.map(async (r) => {
392
- let i = e.join(n, r);
393
- await o(e.dirname(i), { recursive: !0 }), await a(e.join(t.outDir, r), i);
557
+ async function Z(e, t) {
558
+ await Promise.all(e.files.map(async (n) => {
559
+ let r = a.join(t, n);
560
+ await l(a.dirname(r), { recursive: !0 }), await c(a.join(e.outDir, n), r);
394
561
  }));
395
562
  }
396
- async function G({ metadata: t, output: n, hostBin: r }) {
397
- let s = e.join(n.outDir, `${t.productName}.app`);
398
- await l(s, {
563
+ async function Q({ metadata: e, output: t, hostBin: n }) {
564
+ let r = a.join(t.outDir, `${e.productName}.app`);
565
+ await f(r, {
399
566
  recursive: !0,
400
567
  force: !0
401
568
  });
402
- let c = e.join(s, "Contents"), d = e.join(c, "MacOS"), f = e.join(c, "Resources");
403
- await o(d, { recursive: !0 }), await o(f, { recursive: !0 });
404
- let p = e.join(d, t.productName);
405
- await a(r, p), await i(p, 493), await W(n, f);
569
+ let i = a.join(r, "Contents"), o = a.join(i, "MacOS"), u = a.join(i, "Resources");
570
+ await l(o, { recursive: !0 }), await l(u, { recursive: !0 });
571
+ let d = a.join(o, e.productName);
572
+ await c(n, d), await s(d, 493), await Z(t, u);
406
573
  let m = {
407
- CFBundleName: t.productName,
408
- CFBundleDisplayName: t.productName,
409
- CFBundleExecutable: t.productName,
410
- CFBundleIdentifier: t.identifier,
411
- CFBundleVersion: t.version,
412
- CFBundleShortVersionString: t.version,
574
+ CFBundleName: e.productName,
575
+ CFBundleDisplayName: e.productName,
576
+ CFBundleExecutable: e.productName,
577
+ CFBundleIdentifier: e.identifier,
578
+ CFBundleVersion: e.version,
579
+ CFBundleShortVersionString: e.version,
413
580
  CFBundlePackageType: "APPL",
414
581
  CFBundleInfoDictionaryVersion: "6.0",
415
582
  NSHighResolutionCapable: !0
416
583
  };
417
- if (t.icon) {
418
- let n = e.basename(t.icon);
419
- await a(t.icon, e.join(f, n)), m.CFBundleIconFile = n;
584
+ if (e.icon) {
585
+ let t = a.basename(e.icon);
586
+ await c(e.icon, a.join(u, t)), m.CFBundleIconFile = t;
420
587
  }
421
- return await u(e.join(c, "Info.plist"), H(m)), await u(e.join(c, "PkgInfo"), "APPL????"), s;
588
+ return await p(a.join(i, "Info.plist"), me(m)), await p(a.join(i, "PkgInfo"), "APPL????"), r;
422
589
  }
423
- async function K({ metadata: t, output: n, hostBin: r }) {
424
- let s = R(t.productName), c = e.join(n.outDir, s);
425
- await l(c, {
590
+ async function ge({ metadata: t, output: n, hostBin: r }) {
591
+ let i = e(t.productName), o = a.join(n.outDir, i);
592
+ await f(o, {
426
593
  recursive: !0,
427
594
  force: !0
428
- }), await o(c, { recursive: !0 });
429
- let u = e.join(c, s);
430
- return await a(r, u), await i(u, 493), await W(n, c), c;
431
- }
432
- async function q(e = {}) {
433
- let t = e.cwd ?? process.cwd(), n = e.stdout ?? process.stdout, i = e.target ?? U(), a = await z(t);
434
- a.identifierIsDefault && n.write(`[inca] no "inca.identifier" set in package.json — using generated identifier ${a.identifier}\n`);
435
- let o = await w({
595
+ }), await l(o, { recursive: !0 });
596
+ let u = a.join(o, i);
597
+ return await c(r, u), await s(u, 493), await Z(n, o), o;
598
+ }
599
+ async function _e(e = {}) {
600
+ let t = e.cwd ?? process.cwd(), n = e.stdout ?? process.stdout, r = e.target ?? he(), i = await ee(t);
601
+ i.usedPackageJsonKey && R(n, "the \"inca\" key in package.json is deprecated — move these settings to inca.config.ts"), i.identifierIsDefault && R(n, `no "identifier" set in inca.config.ts — using generated identifier ${i.identifier}`);
602
+ let a = await J({
436
603
  cwd: t,
437
604
  entry: e.entry,
438
- bundler: e.bundler
439
- }), s = e.hostBin ?? O();
440
- if (!r(s)) throw Error(`no host binary at ${s} — check that it was built and is executable`);
605
+ config: i,
606
+ bundler: e.bundler,
607
+ stdout: n,
608
+ stderr: e.stderr
609
+ }), s = e.hostBin ?? N();
610
+ if (!o(s)) throw new S("ERR_INCA_HOST_BIN_NOT_FOUND", `no host binary at ${s} — check that it was built and is executable`);
441
611
  let c = {
442
- metadata: a,
443
- output: o,
612
+ metadata: i,
613
+ output: a,
444
614
  hostBin: s
445
615
  };
446
- return { appPath: i === "macos" ? await G(c) : await K(c) };
616
+ return { appPath: r === "macos" ? await Q(c) : await ge(c) };
447
617
  }
448
618
  //#endregion
449
619
  //#region src/cli.mts
450
- var J = "Usage: inca <dev|build|package>";
451
- async function Y(e = process.argv) {
620
+ var ve = "Usage: inca <dev|build|package>";
621
+ function $(e) {
622
+ return a.relative(process.cwd(), e);
623
+ }
624
+ async function ye(e = process.argv) {
452
625
  let t = e[2];
453
626
  if (t === "build") {
454
627
  try {
455
- let e = await w();
456
- process.stdout.write(`[inca] built ${e.entryFile}\n`);
628
+ let e = await J();
629
+ R(process.stdout, `built ${$(e.entryFile)}`);
457
630
  } catch (e) {
458
- P(process.stderr, "build failed", N(e)), process.exitCode = 1;
631
+ W(process.stderr, "build failed", U(e)), process.exitCode = 1;
459
632
  }
460
633
  return;
461
634
  }
462
635
  if (t === "package") {
463
636
  try {
464
- let { appPath: e } = await q();
465
- process.stdout.write(`[inca] packaged ${e}\n`);
637
+ let { appPath: e } = await _e();
638
+ R(process.stdout, `packaged ${$(e)}`);
466
639
  } catch (e) {
467
- P(process.stderr, "package failed", N(e)), process.exitCode = 1;
640
+ W(process.stderr, "package failed", U(e)), process.exitCode = 1;
468
641
  }
469
642
  return;
470
643
  }
471
644
  if (t !== "dev") {
472
- process.stderr.write(`${J}\n`), process.exitCode = 1;
645
+ process.stderr.write(`${ve}\n`), process.exitCode = 1;
473
646
  return;
474
647
  }
475
648
  let n = new AbortController(), r = () => {
476
- process.stderr.write("[inca] shutting down\n"), n.abort();
649
+ n.signal.aborted || (R(process.stderr, "shutting down", { timestamp: !0 }), n.abort());
477
650
  };
478
- process.on("SIGINT", r), process.on("SIGTERM", r), await I({ signal: n.signal });
651
+ process.on("SIGINT", r), process.on("SIGTERM", r);
652
+ try {
653
+ await fe({ signal: n.signal });
654
+ } catch (e) {
655
+ W(process.stderr, "dev failed", U(e), { timestamp: !0 }), process.exitCode = 1;
656
+ }
479
657
  }
480
658
  //#endregion
481
- export { Y as run };
659
+ export { ye as run };