@naisys/erp 3.0.0-beta.20 → 3.0.0-beta.22

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.
@@ -1,5 +1,5 @@
1
1
  import { r as __toESM } from "./rolldown-runtime-CvHMtSRF.js";
2
- import { $ as Link, $t as MantineProvider, A as IconListDetails, At as FileButton, B as IconAlertTriangle, Bt as Checkbox, C as IconX, Ct as PasswordInput, D as IconPlus, Dt as Menu, E as IconTrash, Et as Modal, F as IconEye$1, Ft as Center, G as boolean, Gt as Accordion, H as ZodIssueCode, Ht as Anchor, I as IconChevronDown, It as Card, J as record, Jt as Loader, K as number, Kt as Group, L as IconCheck, Lt as Button, M as IconLayoutSidebarLeftCollapse, Mt as Divider, N as IconInfoCircle, Nt as Container, O as IconNote, Ot as Textarea, P as IconFile, Pt as Code, Q as BrowserRouter, Qt as Box, R as IconArrowBackUp, Rt as Badge, S as useForm, St as Tooltip, T as IconUpload, Tt as NumberInput, U as _enum, Ut as Text, V as IconAlertCircle, Vt as AppShell, W as array, Wt as Alert, X as union, Xt as UnstyledButton, Y as string, Yt as Popover, Z as unknown, Zt as ScrollArea, _ as IconRefresh, _t as Table, a as _undefined, at as useNavigate, b as IconDownload, bt as Select, c as boolean$1, ct as useSearchParams, d as object$1, dt as DateTimePicker, en as useDisclosure, et as Navigate, f as string$1, ft as DateInput, g as Markdown, gt as Tabs, h as remarkGfm, ht as TextInput, i as _null, in as require_react, it as useLocation, j as IconLayoutSidebarLeftExpand, jt as Drawer, k as IconLogout, kt as Image, l as literal, lt as Notifications, m as datetime, mt as Title, n as string$2, nn as require_jsx_runtime, nt as Route, o as any, ot as useOutletContext, p as union$1, pt as DatesProvider, q as object, qt as ActionIcon, r as _enum$1, rn as require_client, rt as Routes, s as array$1, st as useParams, t as number$2, tn as useDebouncedValue, tt as Outlet, u as number$1, ut as notifications, v as IconEye, vt as Switch, w as IconUser, wt as Pagination, x as IconCopy, xt as SegmentedControl, y as IconEyeOff, yt as Stack, z as IconApi, zt as Autocomplete } from "./vendor-DdMxejie.js";
2
+ import { $ as BrowserRouter, $t as Box, A as IconLogout, At as Image, B as IconApi, Bt as Autocomplete, C as useForm, Ct as Tooltip, D as IconTrash, Dt as Modal, E as IconUpload, Et as NumberInput, F as IconFile, Ft as Code, G as array, Gt as Alert, H as IconAlertCircle, Ht as AppShell, I as IconEye$1, It as Center, J as object, Jt as ActionIcon, K as boolean, Kt as Accordion, L as IconChevronDown, Lt as Card, M as IconLayoutSidebarLeftExpand, Mt as Drawer, N as IconLayoutSidebarLeftCollapse, Nt as Divider, O as IconPlus, Ot as Menu, P as IconInfoCircle, Pt as Container, Q as unknown, Qt as ScrollArea, R as IconCheck, Rt as Button, S as IconCopy, St as SegmentedControl, T as IconUser, Tt as Pagination, U as ZodIssueCode, Ut as Anchor, V as IconAlertTriangle, Vt as Checkbox, W as _enum, Wt as Text, X as string, Xt as Popover, Y as record, Yt as Loader, Z as union, Zt as UnstyledButton, _ as IconRefresh, _t as Tabs, a as _undefined, an as require_react, at as useLocation, b as IconEyeOff, bt as Stack, c as boolean$1, ct as useParams, d as object$1, dt as notifications, en as MantineProvider, et as Link, f as string$1, ft as DateTimePicker, g as Markdown, gt as TextInput, h as remarkGfm, ht as Title, i as _null, in as require_client, it as Routes, j as IconListDetails, jt as FileButton, k as IconNote, kt as Textarea, l as literal, lt as useSearchParams, m as datetime, mt as DatesProvider, n as string$2, nn as useDebouncedValue, nt as Outlet, o as any, ot as useNavigate, p as union$1, pt as DateInput, q as number, qt as Group, r as _enum$1, rn as require_jsx_runtime, rt as Route, s as array$1, st as useOutletContext, t as number$2, tn as useDisclosure, tt as Navigate, u as number$1, ut as Notifications, v as IconPhoto, vt as Table, w as IconX, wt as PasswordInput, x as IconDownload, xt as Select, y as IconEye, yt as Switch, z as IconArrowBackUp, zt as Badge } from "./vendor-DlmcA82d.js";
3
3
  //#region \0vite/modulepreload-polyfill.js
4
4
  (function polyfill() {
5
5
  const relList = document.createElement("link").relList;
@@ -262,6 +262,32 @@ object({
262
262
  _actions: array(HateoasActionSchema).optional()
263
263
  });
264
264
  //#endregion
265
+ //#region ../../../packages/common/dist/mimeTypes.js
266
+ var MIME_TYPES = {
267
+ ".jpg": "image/jpeg",
268
+ ".jpeg": "image/jpeg",
269
+ ".png": "image/png",
270
+ ".gif": "image/gif",
271
+ ".webp": "image/webp",
272
+ ".svg": "image/svg+xml",
273
+ ".bmp": "image/bmp",
274
+ ".wav": "audio/wav",
275
+ ".mp3": "audio/mpeg",
276
+ ".m4a": "audio/mp4",
277
+ ".flac": "audio/flac",
278
+ ".ogg": "audio/ogg",
279
+ ".webm": "audio/webm",
280
+ ".pdf": "application/pdf",
281
+ ".txt": "text/plain",
282
+ ".json": "application/json"
283
+ };
284
+ function mimeFromFilename(filename) {
285
+ return MIME_TYPES[filename.slice(filename.lastIndexOf(".")).toLowerCase()] ?? "application/octet-stream";
286
+ }
287
+ function isImageFilename(filename) {
288
+ return mimeFromFilename(filename).startsWith("image/");
289
+ }
290
+ //#endregion
265
291
  //#region ../../../packages/common/assets/naisys-logo.webp
266
292
  var naisys_logo_default = "/erp/assets/naisys-logo-CzoPnn5I.webp";
267
293
  //#endregion
@@ -461,6 +487,62 @@ function useAuth() {
461
487
  return ctx;
462
488
  }
463
489
  //#endregion
490
+ //#region src/components/RouteErrorPage.tsx
491
+ var RouteErrorPage = ({ error }) => {
492
+ const navigate = useNavigate();
493
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, {
494
+ size: "sm",
495
+ py: "xl",
496
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Stack, {
497
+ align: "center",
498
+ children: [
499
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Title, {
500
+ order: 2,
501
+ children: "Something went wrong"
502
+ }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
504
+ c: "dimmed",
505
+ ta: "center",
506
+ children: error.message || "An unexpected error occurred on this page."
507
+ }),
508
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Group, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
509
+ variant: "default",
510
+ onClick: () => navigate(-1),
511
+ children: "Go back"
512
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
513
+ onClick: () => window.location.reload(),
514
+ children: "Reload"
515
+ })] })
516
+ ]
517
+ })
518
+ });
519
+ };
520
+ //#endregion
521
+ //#region src/components/ErrorBoundary.tsx
522
+ var ErrorBoundary = class extends import_react.Component {
523
+ state = { error: null };
524
+ static getDerivedStateFromError(error) {
525
+ return { error };
526
+ }
527
+ componentDidUpdate(prevProps) {
528
+ if (this.state.error && prevProps.resetKey !== this.props.resetKey) this.setState({ error: null });
529
+ }
530
+ componentDidCatch(error, info) {
531
+ console.error("ErrorBoundary caught:", error, info);
532
+ }
533
+ render() {
534
+ if (this.state.error) return this.props.fallback(this.state.error);
535
+ return this.props.children;
536
+ }
537
+ };
538
+ var RouteErrorBoundary = ({ children }) => {
539
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBoundary, {
540
+ resetKey: useLocation().pathname,
541
+ fallback: (error) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RouteErrorPage, { error }),
542
+ children
543
+ });
544
+ };
545
+ //#endregion
464
546
  //#region ../../../packages/common-browser/dist/ActionButton.js
465
547
  /**
466
548
  * A button that is automatically shown/hidden and enabled/disabled
@@ -508,9 +590,14 @@ var AttachmentList = ({ fetchAttachments: fetchAttachmentsFn, getDownloadUrl, ex
508
590
  (0, import_react.useEffect)(() => {
509
591
  fetchAttachments();
510
592
  }, [fetchAttachments]);
511
- const handleDownload = (id, filename) => {
593
+ const handleOpen = (id, filename) => {
594
+ const url = getDownloadUrl(id);
595
+ if (isImageFilename(filename)) {
596
+ window.open(url, "_blank", "noopener,noreferrer");
597
+ return;
598
+ }
512
599
  const link = document.createElement("a");
513
- link.href = getDownloadUrl(id);
600
+ link.href = url;
514
601
  link.download = filename;
515
602
  link.click();
516
603
  };
@@ -553,14 +640,14 @@ var AttachmentList = ({ fetchAttachments: fetchAttachmentsFn, getDownloadUrl, ex
553
640
  (0, import_jsx_runtime.jsx)(Table.Th, {})
554
641
  ] }) }), (0, import_jsx_runtime.jsx)(Table.Tbody, { children: data.attachments.map((att) => (0, import_jsx_runtime.jsxs)(Table.Tr, {
555
642
  style: { cursor: "pointer" },
556
- onClick: () => handleDownload(att.id, att.filename),
643
+ onClick: () => handleOpen(att.id, att.filename),
557
644
  children: [
558
645
  (0, import_jsx_runtime.jsx)(Table.Td, { children: att.filename }),
559
646
  (0, import_jsx_runtime.jsx)(Table.Td, { children: formatFileSize(att.fileSize) }),
560
647
  extraColumns?.map((col) => (0, import_jsx_runtime.jsx)(Table.Td, { children: col.render(att) }, col.header)),
561
648
  (0, import_jsx_runtime.jsx)(Table.Td, { children: att.uploadedBy }),
562
649
  (0, import_jsx_runtime.jsx)(Table.Td, { children: new Date(att.createdAt).toLocaleString() }),
563
- (0, import_jsx_runtime.jsx)(Table.Td, { children: (0, import_jsx_runtime.jsx)(IconDownload, { size: 16 }) })
650
+ (0, import_jsx_runtime.jsx)(Table.Td, { children: isImageFilename(att.filename) ? (0, import_jsx_runtime.jsx)(IconPhoto, { size: 16 }) : (0, import_jsx_runtime.jsx)(IconDownload, { size: 16 }) })
564
651
  ]
565
652
  }, att.id)) })]
566
653
  }), totalPages > 1 && (0, import_jsx_runtime.jsx)(Group, {
@@ -2193,7 +2280,7 @@ var AppLayout = ({ supervisorAuth }) => {
2193
2280
  size: "xs",
2194
2281
  children: "Public read-only mode — login for full access"
2195
2282
  })
2196
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Outlet, { context: { supervisorAuth } })] }),
2283
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RouteErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Outlet, { context: { supervisorAuth } }) })] }),
2197
2284
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoginModal, {
2198
2285
  opened: loginOpen,
2199
2286
  onClose: closeLogin
@@ -2202,6 +2289,39 @@ var AppLayout = ({ supervisorAuth }) => {
2202
2289
  });
2203
2290
  };
2204
2291
  //#endregion
2292
+ //#region src/components/RootErrorPage.tsx
2293
+ var RootErrorPage = ({ error }) => {
2294
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, {
2295
+ size: "sm",
2296
+ py: "xl",
2297
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Stack, {
2298
+ align: "center",
2299
+ children: [
2300
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Title, {
2301
+ order: 1,
2302
+ children: "Something went wrong"
2303
+ }),
2304
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
2305
+ size: "lg",
2306
+ c: "dimmed",
2307
+ ta: "center",
2308
+ children: error.message || "An unexpected error occurred."
2309
+ }),
2310
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2311
+ onClick: () => window.location.reload(),
2312
+ children: "Reload"
2313
+ })
2314
+ ]
2315
+ })
2316
+ });
2317
+ };
2318
+ //#endregion
2319
+ //#region src/lib/useBoomGuard.ts
2320
+ var useBoomGuard = (scope) => {
2321
+ const [searchParams] = useSearchParams();
2322
+ if (searchParams.get("boom") === scope) throw new Error(`Boom guard triggered: ${scope}`);
2323
+ };
2324
+ //#endregion
2205
2325
  //#region src/pages/admin/AdminPage.tsx
2206
2326
  var AdminPage = () => {
2207
2327
  const [data, setData] = (0, import_react.useState)(null);
@@ -3364,19 +3484,6 @@ function formatDate$1(d) {
3364
3484
  function formatDateTime$1(d) {
3365
3485
  return `${formatDate$1(d)}T${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
3366
3486
  }
3367
- var IMAGE_EXTENSIONS = new Set([
3368
- ".jpg",
3369
- ".jpeg",
3370
- ".png",
3371
- ".gif",
3372
- ".webp",
3373
- ".svg",
3374
- ".bmp"
3375
- ]);
3376
- function isImageFilename(filename) {
3377
- const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase();
3378
- return IMAGE_EXTENSIONS.has(ext);
3379
- }
3380
3487
  /** Check if a field type represents an array (e.g. "string[]") */
3381
3488
  function isArrayType(type) {
3382
3489
  return type.endsWith("[]");
@@ -5040,6 +5147,7 @@ var OrderDetail = () => {
5040
5147
  //#endregion
5041
5148
  //#region src/pages/orders/OrderList.tsx
5042
5149
  var OrderList = () => {
5150
+ useBoomGuard("orders");
5043
5151
  const navigate = useNavigate();
5044
5152
  const [searchParams, setSearchParams] = useSearchParams();
5045
5153
  const page = Number(searchParams.get("page")) || 1;
@@ -10295,6 +10403,7 @@ var WorkCenterList = () => {
10295
10403
  //#endregion
10296
10404
  //#region src/App.tsx
10297
10405
  var AppContent = () => {
10406
+ useBoomGuard("root");
10298
10407
  const [publicRead, setPublicRead] = import_react.useState(false);
10299
10408
  const [supervisorAuth, setSupervisorAuth] = import_react.useState(false);
10300
10409
  const [clientConfigLoaded, setClientConfigLoaded] = import_react.useState(false);
@@ -10445,7 +10554,10 @@ var App = () => {
10445
10554
  settings: { consistentWeeks: true },
10446
10555
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Notifications, { position: "top-right" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BrowserRouter, {
10447
10556
  basename: "/erp",
10448
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppContent, {}) })
10557
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBoundary, {
10558
+ fallback: (error) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootErrorPage, { error }),
10559
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppContent, {})
10560
+ }) })
10449
10561
  })]
10450
10562
  })
10451
10563
  });
@@ -39588,6 +39588,24 @@ var IconEye = createReactComponent("outline", "eye", "Eye", [["path", {
39588
39588
  "d": "M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6",
39589
39589
  "key": "svg-1"
39590
39590
  }]]);
39591
+ var IconPhoto = createReactComponent("outline", "photo", "Photo", [
39592
+ ["path", {
39593
+ "d": "M15 8h.01",
39594
+ "key": "svg-0"
39595
+ }],
39596
+ ["path", {
39597
+ "d": "M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12",
39598
+ "key": "svg-1"
39599
+ }],
39600
+ ["path", {
39601
+ "d": "M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5",
39602
+ "key": "svg-2"
39603
+ }],
39604
+ ["path", {
39605
+ "d": "M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3",
39606
+ "key": "svg-3"
39607
+ }]
39608
+ ]);
39591
39609
  var IconRefresh = createReactComponent("outline", "refresh", "Refresh", [["path", {
39592
39610
  "d": "M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4",
39593
39611
  "key": "svg-0"
@@ -64782,4 +64800,4 @@ function number(params) {
64782
64800
  return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
64783
64801
  }
64784
64802
  //#endregion
64785
- export { Link as $, MantineProvider as $t, IconListDetails as A, FileButton as At, IconAlertTriangle as B, Checkbox as Bt, IconX as C, PasswordInput as Ct, IconPlus as D, Menu as Dt, IconTrash as E, Modal as Et, IconEye$1 as F, Center as Ft, boolean$3 as G, Accordion as Gt, ZodIssueCode as H, Anchor as Ht, IconChevronDown as I, Card as It, record as J, Loader as Jt, number$4 as K, Group as Kt, IconCheck as L, Button as Lt, IconLayoutSidebarLeftCollapse as M, Divider as Mt, IconInfoCircle as N, Container as Nt, IconNote as O, Textarea as Ot, IconFile as P, Code as Pt, BrowserRouter as Q, Box as Qt, IconArrowBackUp as R, Badge as Rt, useForm as S, Tooltip as St, IconUpload as T, NumberInput as Tt, _enum$1 as U, Text as Ut, IconAlertCircle as V, AppShell as Vt, array$1 as W, Alert as Wt, union$1 as X, UnstyledButton as Xt, string$5 as Y, Popover as Yt, unknown$1 as Z, ScrollArea as Zt, IconRefresh as _, Table as _t, _undefined as a, useNavigate as at, IconDownload as b, Select as bt, boolean as c, useSearchParams as ct, object as d, DateTimePicker as dt, useDisclosure as en, Navigate as et, string$1 as f, DateInput as ft, Markdown as g, Tabs as gt, remarkGfm as h, TextInput as ht, _null as i, require_react as in, useLocation as it, IconLayoutSidebarLeftExpand as j, Drawer as jt, IconLogout as k, Image as kt, literal as l, Notifications as lt, datetime as m, Title as mt, string as n, require_jsx_runtime as nn, Route as nt, any as o, useOutletContext as ot, union as p, DatesProvider as pt, object$1 as q, ActionIcon as qt, _enum as r, require_client as rn, Routes as rt, array as s, useParams as st, number as t, useDebouncedValue as tn, Outlet as tt, number$1 as u, notifications as ut, IconEye as v, Switch as vt, IconUser as w, Pagination as wt, IconCopy as x, SegmentedControl as xt, IconEyeOff as y, Stack as yt, IconApi as z, Autocomplete as zt };
64803
+ export { BrowserRouter as $, Box as $t, IconLogout as A, Image as At, IconApi as B, Autocomplete as Bt, useForm as C, Tooltip as Ct, IconTrash as D, Modal as Dt, IconUpload as E, NumberInput as Et, IconFile as F, Code as Ft, array$1 as G, Alert as Gt, IconAlertCircle as H, AppShell as Ht, IconEye$1 as I, Center as It, object$1 as J, ActionIcon as Jt, boolean$3 as K, Accordion as Kt, IconChevronDown as L, Card as Lt, IconLayoutSidebarLeftExpand as M, Drawer as Mt, IconLayoutSidebarLeftCollapse as N, Divider as Nt, IconPlus as O, Menu as Ot, IconInfoCircle as P, Container as Pt, unknown$1 as Q, ScrollArea as Qt, IconCheck as R, Button as Rt, IconCopy as S, SegmentedControl as St, IconUser as T, Pagination as Tt, ZodIssueCode as U, Anchor as Ut, IconAlertTriangle as V, Checkbox as Vt, _enum$1 as W, Text as Wt, string$5 as X, Popover as Xt, record as Y, Loader as Yt, union$1 as Z, UnstyledButton as Zt, IconRefresh as _, Tabs as _t, _undefined as a, require_react as an, useLocation as at, IconEyeOff as b, Stack as bt, boolean as c, useParams as ct, object as d, notifications as dt, MantineProvider as en, Link as et, string$1 as f, DateTimePicker as ft, Markdown as g, TextInput as gt, remarkGfm as h, Title as ht, _null as i, require_client as in, Routes as it, IconListDetails as j, FileButton as jt, IconNote as k, Textarea as kt, literal as l, useSearchParams as lt, datetime as m, DatesProvider as mt, string as n, useDebouncedValue as nn, Outlet as nt, any as o, useNavigate as ot, union as p, DateInput as pt, number$4 as q, Group as qt, _enum as r, require_jsx_runtime as rn, Route as rt, array as s, useOutletContext as st, number as t, useDisclosure as tn, Navigate as tt, number$1 as u, Notifications as ut, IconPhoto as v, Table as vt, IconX as w, PasswordInput as wt, IconDownload as x, Select as xt, IconEye as y, Switch as yt, IconArrowBackUp as z, Badge as zt };
@@ -33,9 +33,9 @@
33
33
  <meta name="format-detection" content="telephone=no" />
34
34
 
35
35
  <title>NAISYS ERP</title>
36
- <script type="module" crossorigin src="/erp/assets/index-CZhFlAkg.js"></script>
36
+ <script type="module" crossorigin src="/erp/assets/index-BJzK1WXg.js"></script>
37
37
  <link rel="modulepreload" crossorigin href="/erp/assets/rolldown-runtime-CvHMtSRF.js">
38
- <link rel="modulepreload" crossorigin href="/erp/assets/vendor-DdMxejie.js">
38
+ <link rel="modulepreload" crossorigin href="/erp/assets/vendor-DlmcA82d.js">
39
39
  <link rel="stylesheet" crossorigin href="/erp/assets/vendor-CLUPjUnv.css">
40
40
  <link rel="stylesheet" crossorigin href="/erp/assets/index-CSiMTJfw.css">
41
41
  </head>
package/dist/erpServer.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "dotenv/config";
2
2
  import "./schema-registry.js";
3
- import { ensureDotEnv, expandNaisysFolder, runSetupWizard, } from "@naisys/common-node";
3
+ import { cwdWithTilde, ensureDotEnv, expandNaisysFolder, runSetupWizard, } from "@naisys/common-node";
4
4
  expandNaisysFolder();
5
5
  // Important to load dotenv before any other imports, to ensure environment variables are available
6
6
  import cookie from "@fastify/cookie";
@@ -182,7 +182,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
182
182
  type: "fields",
183
183
  comment: "ERP configuration",
184
184
  fields: [
185
- { key: "NAISYS_FOLDER", label: "NAISYS Data Folder" },
185
+ { key: "NAISYS_FOLDER", label: "NAISYS Data Folder", defaultValue: cwdWithTilde() },
186
186
  { key: "SERVER_PORT", label: "Server Port" },
187
187
  { key: "SUPERVISOR_AUTH", label: "Use Supervisor for Auth" },
188
188
  { key: "PUBLIC_READ", label: "Public Read Access" },
@@ -191,11 +191,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
191
191
  ],
192
192
  };
193
193
  const erpExampleUrl = new URL("../.env.example", import.meta.url);
194
- if (process.argv.includes("--setup")) {
195
- await runSetupWizard(path.resolve(".env"), erpExampleUrl, erpWizardConfig);
196
- process.exit(0);
197
- }
198
- else if (process.argv.includes("--reset-password")) {
194
+ if (process.argv.includes("--reset-password")) {
199
195
  const usernameIdx = process.argv.indexOf("--username");
200
196
  const passwordIdx = process.argv.indexOf("--password");
201
197
  const username = usernameIdx !== -1 ? process.argv[usernameIdx + 1] : undefined;
@@ -226,6 +222,10 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
226
222
  }
227
223
  }
228
224
  else {
225
+ if (process.argv.includes("--setup")) {
226
+ await runSetupWizard(path.resolve(".env"), erpExampleUrl, erpWizardConfig);
227
+ expandNaisysFolder();
228
+ }
229
229
  await ensureDotEnv(erpExampleUrl, erpWizardConfig);
230
230
  void startServer();
231
231
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naisys/erp",
3
- "version": "3.0.0-beta.20",
3
+ "version": "3.0.0-beta.22",
4
4
  "description": "NAISYS ERP - Web UI for AI-driven order and work management",
5
5
  "type": "module",
6
6
  "main": "dist/erpServer.js",
@@ -46,11 +46,11 @@
46
46
  "@fastify/rate-limit": "^10.3.0",
47
47
  "@fastify/static": "^9.0.0",
48
48
  "@fastify/swagger": "^9.7.0",
49
- "@naisys/erp-shared": "3.0.0-beta.20",
50
- "@naisys/common": "3.0.0-beta.20",
51
- "@naisys/common-node": "3.0.0-beta.20",
52
- "@naisys/hub-database": "3.0.0-beta.20",
53
- "@naisys/supervisor-database": "3.0.0-beta.20",
49
+ "@naisys/erp-shared": "3.0.0-beta.22",
50
+ "@naisys/common": "3.0.0-beta.22",
51
+ "@naisys/common-node": "3.0.0-beta.22",
52
+ "@naisys/hub-database": "3.0.0-beta.22",
53
+ "@naisys/supervisor-database": "3.0.0-beta.22",
54
54
  "@prisma/adapter-better-sqlite3": "^7.5.0",
55
55
  "@prisma/client": "^7.5.0",
56
56
  "@scalar/fastify-api-reference": "^1.48.7",