@kky42/pievo-server 2.4.12 → 2.4.13
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/.output/nitro.json +1 -1
- package/.output/public/assets/SignIn-CDCdDD1a.js +1 -0
- package/.output/public/assets/{ui-s5IMg6RF.js → actionUi-D8m1FDHO.js} +1 -1
- package/.output/public/assets/app-PPhgN9iN.css +2 -0
- package/.output/public/assets/index-c0XPWXuz.js +10 -0
- package/.output/public/assets/loops._loopId-D7i_BGiE.js +67 -0
- package/.output/public/assets/loops._loopId_.runs._runId-CksSrEY7.js +3 -0
- package/.output/public/assets/{preload-helper-Bs7oCAsw.js → preload-helper-Zcmr31XG.js} +3 -3
- package/.output/public/assets/routes-79D939J4.js +1 -0
- package/.output/public/assets/routes-BYgl3Tmv.js +1 -0
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
- package/.output/server/_ssr/{MachinesModal-BhRw7oOx.mjs → MachinesModal-DBIP648Z.mjs} +18 -57
- package/.output/server/_ssr/{SignIn-BhoZIOUp.mjs → SignIn-Bp3uWaCQ.mjs} +3 -3
- package/.output/server/_ssr/{ui-DGz-q9MT.mjs → actionUi-C_WswNb1.mjs} +113 -2
- package/.output/server/_ssr/{artifactFiles-ChuJ4PzC.mjs → artifactFiles-BvVmixrs.mjs} +3 -3
- package/.output/server/_ssr/{artifactKind-DXumOv7c.mjs → artifactKind-DRCbYHZU.mjs} +6 -14
- package/.output/server/_ssr/artifacts-CzDJLaa6.mjs +2 -0
- package/.output/server/_ssr/{auth-LwPp_iim.mjs → auth-BV0MxVdo.mjs} +44 -124
- package/.output/server/_ssr/{SocialLinks-DVCLmql0.mjs → auth-client-RTpMpT4L.mjs} +143 -109
- package/.output/server/_ssr/boot-CsLXrLEa.mjs +2 -0
- package/.output/server/_ssr/{boot-BIxtZHU-.mjs → boot-U-CFI65B.mjs} +58 -331
- package/.output/server/_ssr/{bun-sqlite-dialect-BW9W1_Ps-CHMDkKqA.mjs → bun-sqlite-dialect-BW9W1_Ps-D9KUBJ-L.mjs} +2 -2
- package/.output/server/_ssr/{d1-sqlite-dialect-BLC8LXE6-DYum6qky.mjs → d1-sqlite-dialect-BLC8LXE6-CVHRzH1n.mjs} +2 -2
- package/.output/server/_ssr/db-BTX-xORB.mjs +2 -0
- package/.output/server/_ssr/{dist-bWqs5sTy.mjs → dist-D7UDVZ5G.mjs} +2 -2
- package/.output/server/_ssr/{factory-pBwrjVTI.mjs → factory-DYFx1fg-.mjs} +2 -2
- package/.output/server/_ssr/{kysely-adapter-DMf5pFTf.mjs → kysely-adapter-CwdB7yBh.mjs} +1 -1
- package/.output/server/_ssr/logger-CwiKSMp6.mjs +2 -0
- package/.output/server/_ssr/{loopApi-Im6JSK0p.mjs → loopApi-C4nN0msL.mjs} +29 -90
- package/.output/server/_ssr/{loopProjection-DIpGR6rp.mjs → loopProjection-DMSNHux6.mjs} +2 -2
- package/.output/server/_ssr/{loops._loopId-B5iPseDG.mjs → loops._loopId-Q4pRYPip.mjs} +19 -45
- package/.output/server/_ssr/{loops._loopId_.runs._runId-DVtG0xYb.mjs → loops._loopId_.runs._runId-DNXVmCt5.mjs} +6 -13
- package/.output/server/_ssr/{loops._loopId_.runs._runId-BA-P6sGA.mjs → loops._loopId_.runs._runId-ty3AhkOi.mjs} +31 -23
- package/.output/server/_ssr/{machineFns-Bb9KNXun.mjs → machineFns-CkNms3zA.mjs} +41 -108
- package/.output/server/_ssr/{node-sqlite-dialect-Dho9YjXb.mjs → node-sqlite-dialect-B_g92oFK.mjs} +2 -2
- package/.output/server/_ssr/{router-C8iotXtk.mjs → router-DCNZ2xLm.mjs} +26 -40
- package/.output/server/_ssr/routes-8JSF7bX_.mjs +27 -0
- package/.output/server/_ssr/{routes-FO0MFfYK.mjs → routes-B3fulW5I.mjs} +4 -9
- package/.output/server/_ssr/routes-BaanDO41.mjs +367 -0
- package/.output/server/_ssr/runDiff-D7CxAgYL.mjs +2 -0
- package/.output/server/_ssr/ssr.mjs +28 -88
- package/.output/server/_ssr/store-DSNbXxqz.mjs +2 -0
- package/.output/server/_ssr/tokens-DzUv7CCp.mjs +2 -0
- package/.output/server/_tanstack-start-manifest_v-DkmxsHDK.mjs +52 -0
- package/.output/server/drizzle/0002_remove_teams.sql +15 -0
- package/.output/server/drizzle/meta/_journal.json +7 -0
- package/.output/server/index.mjs +49 -98
- package/drizzle/0002_remove_teams.sql +15 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +2 -2
- package/.output/public/assets/MachinesModal-ByHejech.js +0 -1
- package/.output/public/assets/SignIn-Cf4HOpdF.js +0 -1
- package/.output/public/assets/actionUi-yYVvoOTn.js +0 -1
- package/.output/public/assets/app-D5Hy4BcS.css +0 -2
- package/.output/public/assets/index-D504r3X9.js +0 -10
- package/.output/public/assets/invite._token-B0EKVyrU.js +0 -1
- package/.output/public/assets/invite._token-BSnGRyUw.js +0 -1
- package/.output/public/assets/lifecycleUi-C0DaC6NM.js +0 -1
- package/.output/public/assets/loops._loopId-j5EB2PLW.js +0 -67
- package/.output/public/assets/loops._loopId_.runs._runId-BICo_pRz.js +0 -3
- package/.output/public/assets/routes-4N6mrQK_.js +0 -1
- package/.output/public/assets/routes-DZU0Tqka.js +0 -1
- package/.output/public/assets/t._teamId-CAUjvMZ6.js +0 -1
- package/.output/public/assets/t._teamId-Cqzd69sO.js +0 -1
- package/.output/server/_ssr/DashboardView-DrKNkmcX.mjs +0 -867
- package/.output/server/_ssr/actionUi-Cf6DuEC2.mjs +0 -119
- package/.output/server/_ssr/artifacts-DOLHJHcd.mjs +0 -2
- package/.output/server/_ssr/boot-D8cj4uZj.mjs +0 -2
- package/.output/server/_ssr/db-BphSJs66.mjs +0 -2
- package/.output/server/_ssr/invite._token-CPSvdDox.mjs +0 -27
- package/.output/server/_ssr/invite._token-CRBsTSTZ.mjs +0 -84
- package/.output/server/_ssr/invite._token-CaTLt92a.mjs +0 -20
- package/.output/server/_ssr/lifecycleUi-DauKavgx.mjs +0 -50
- package/.output/server/_ssr/logger-EinA2J6y.mjs +0 -2
- package/.output/server/_ssr/routes-CsV1weub.mjs +0 -26
- package/.output/server/_ssr/routes-fiMzFtcP.mjs +0 -39
- package/.output/server/_ssr/runDiff-BLdot9mi.mjs +0 -2
- package/.output/server/_ssr/store-CFCp_ggC.mjs +0 -2
- package/.output/server/_ssr/t._teamId-BYA4Dnjp.mjs +0 -43
- package/.output/server/_ssr/t._teamId-CKsrgN86.mjs +0 -32
- package/.output/server/_ssr/t._teamId-D1BTwhWf.mjs +0 -31
- package/.output/server/_ssr/teamCookie-B7hLOIie.mjs +0 -10
- package/.output/server/_ssr/teamFns-DfqtuBW2.mjs +0 -451
- package/.output/server/_ssr/teamFns-cI_tsiCv.mjs +0 -32
- package/.output/server/_ssr/tokens-CUz4LDLm.mjs +0 -2
- package/.output/server/_tanstack-start-manifest_v-xSxVtI1J.mjs +0 -86
|
@@ -1,64 +1,25 @@
|
|
|
1
1
|
import { o as __toESM } from "../_runtime.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { G as isOutdated, ct as machinePresence } from "./boot-U-CFI65B.mjs";
|
|
3
3
|
import { a as DialogClose, c as TooltipPopup, d as TooltipTrigger, f as TooltipRoot, g as require_react, h as require_jsx_runtime, i as DialogPopup, l as TooltipPositioner, n as DialogRoot, o as DialogBackdrop, r as DialogPortal, t as DialogTitle, u as TooltipPortal } from "../_libs/@base-ui/react+[...].mjs";
|
|
4
4
|
import { n as createServerFn } from "./ssr.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { C as
|
|
7
|
-
|
|
8
|
-
import { i as lifecyclePresentation, n as daemonStopSupport } from "./lifecycleUi-DauKavgx.mjs";
|
|
9
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/MachinesModal-BhRw7oOx.js
|
|
5
|
+
import { g as lifecyclePresentation, o as createSsrRpc, p as getConfig, s as daemonStopSupport } from "./auth-client-RTpMpT4L.mjs";
|
|
6
|
+
import { A as until, C as rel, D as sectionHeadCls, E as scheduleText, M as useHydrated, S as lastRunOf, _ as fmt, b as inputCls, c as btn, g as dur, h as dotOpacity, l as btnDanger, m as dotLabel, n as ErrorBanner, o as Pill, p as dotColor, t as ConfirmBar, u as btnPrimary, v as fnum, w as runPulseAnim, x as labelCls } from "./actionUi-C_WswNb1.mjs";
|
|
7
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/MachinesModal-DBIP648Z.js
|
|
10
8
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
11
9
|
var import_jsx_runtime = require_jsx_runtime();
|
|
12
10
|
/**
|
|
13
|
-
* Machine
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* 2. the daemon connects → poll records online + hostname/platform/arch. The
|
|
17
|
-
* UI polls machineStatus(id); once connected it shows the name field
|
|
18
|
-
* (prefilled with the hostname). finalizeMachine({id,name}) names it →
|
|
19
|
-
* it appears in the list. cancelMachine(id) drops a pending row.
|
|
20
|
-
*
|
|
21
|
-
* Scoping: when the auth gate is on, every fn requires a signed-in user, and a
|
|
22
|
-
* machine is visible/actionable only when the requester owns it, its owner is a
|
|
23
|
-
* member of the active team, or the scope is the admin "All teams" view (the
|
|
24
|
-
* same rule listMachines filters by). The PLAINTEXT device token is serialized
|
|
25
|
-
* ONLY to the machine's owner — it fully impersonates the machine (poll /
|
|
26
|
-
* create-loop / log), so a teammate who can see the row must never exfiltrate
|
|
27
|
-
* it. Open mode (gate off) keeps the shared workspace: everyone sees/manages
|
|
28
|
-
* all machines, tokens included. No workdir jail (fully open) for now.
|
|
11
|
+
* Machine-management server functions. In auth mode, the signed-in user is the
|
|
12
|
+
* sole human authorization boundary. Open mode intentionally shares all machine
|
|
13
|
+
* administration, including reconnect tokens.
|
|
29
14
|
*/
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* team-set thunk). */
|
|
34
|
-
/**
|
|
35
|
-
* Resolve a machine and authorize it against the request scope (the machine-fn
|
|
36
|
-
* twin of loopApi's `ownedLoop`). `machine` is undefined when it's missing OR
|
|
37
|
-
* out of scope — callers treat both as "not found" so existence never leaks.
|
|
38
|
-
* The scope rides along so callers don't re-run requestScope (a second session
|
|
39
|
-
* decrypt); the team-set thunk keeps the owner fast path query-free.
|
|
40
|
-
*/
|
|
41
|
-
/** Named machines only (pending/unnamed rows are mid-connect). Scoped to the
|
|
42
|
-
* given/active team when the gate is on; the full shared list in open mode. An
|
|
43
|
-
* explicit `teamId` (the `/t/<id>` route) scopes this request independent of the
|
|
44
|
-
* cookie, so a tab on /t/A and one on /t/B list different machines at once. */
|
|
45
|
-
var listMachines = createServerFn({ method: "GET" }).validator((teamId) => teamId).handler(createSsrRpc("aa46310016bb8a58b273a648ffd498c87f1f450d12827e30110a3b83ba6a27d9"));
|
|
46
|
-
/** Act 1 — create a pending machine + token, owned by the signed-in user's team.
|
|
47
|
-
* An explicit `teamId` (the `/t/<id>` route) binds the machine to that tab's team
|
|
48
|
-
* independent of the last-used cookie, mirroring `mintClaim`/`listMachines`. */
|
|
49
|
-
var createMachine = createServerFn({ method: "POST" }).validator((teamId) => teamId).handler(createSsrRpc("ed679b4e1e05e903a5d4ba4a70d9b9d883991ab22ed59b4d2d69078941818415"));
|
|
50
|
-
/** Poll while the connect dialog is open. Scoped like listMachines; the token
|
|
51
|
-
* rides along only for the machine's owner (the connect dialog's minter). */
|
|
15
|
+
/** Missing and out-of-scope machines both resolve to undefined. */
|
|
16
|
+
var listMachines = createServerFn({ method: "GET" }).handler(createSsrRpc("aa46310016bb8a58b273a648ffd498c87f1f450d12827e30110a3b83ba6a27d9"));
|
|
17
|
+
var createMachine = createServerFn({ method: "POST" }).handler(createSsrRpc("ed679b4e1e05e903a5d4ba4a70d9b9d883991ab22ed59b4d2d69078941818415"));
|
|
52
18
|
var machineStatus = createServerFn({ method: "GET" }).validator((id) => id).handler(createSsrRpc("169566e7637a22599b4eb32ee3775574e99677406922bbef7482a102036c33dd"));
|
|
53
|
-
var finalizeMachine = createServerFn({ method: "POST" }).validator((
|
|
19
|
+
var finalizeMachine = createServerFn({ method: "POST" }).validator((data) => data).handler(createSsrRpc("27d7eba0b6a2257949392fdd56057275a5c5366484ae01faf3b5897a225ecd83"));
|
|
54
20
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* history/artifact metadata is removed. Nothing reaches into the machine's cwd.
|
|
58
|
-
*
|
|
59
|
-
* A teammate may still remove an empty machine as before. Cascading loops is
|
|
60
|
-
* stronger: under the auth gate the caller must own every affected loop team,
|
|
61
|
-
* matching the authority required to force-retire those teams' run leases.
|
|
21
|
+
* Delete server-owned machine data without touching local project files. The
|
|
22
|
+
* store rechecks ownership under the deletion lock in auth mode.
|
|
62
23
|
*/
|
|
63
24
|
var deleteMachine = createServerFn({ method: "POST" }).validator((id) => id).handler(createSsrRpc("a6384dc7154d9930422d29396f5de64b3ac69c62ad3824bc4a22d745fc07b293"));
|
|
64
25
|
/** Merge two chronological (oldest-first) run lists, dedup by id (the first
|
|
@@ -403,7 +364,7 @@ function machineOrder(a, b) {
|
|
|
403
364
|
sensitivity: "base"
|
|
404
365
|
}) || a.id.localeCompare(b.id);
|
|
405
366
|
}
|
|
406
|
-
function MachinesModal({ open, onClose
|
|
367
|
+
function MachinesModal({ open, onClose }) {
|
|
407
368
|
const [machines, setMachines] = (0, import_react.useState)([]);
|
|
408
369
|
const [pending, setPending] = (0, import_react.useState)(null);
|
|
409
370
|
const [status, setStatus] = (0, import_react.useState)(null);
|
|
@@ -435,10 +396,10 @@ function MachinesModal({ open, onClose, teamId }) {
|
|
|
435
396
|
const load = (0, import_react.useCallback)(async () => {
|
|
436
397
|
const request = ++loadRequest.current;
|
|
437
398
|
try {
|
|
438
|
-
const next = await listMachines(
|
|
399
|
+
const next = await listMachines();
|
|
439
400
|
if (request === loadRequest.current) setMachines([...next].sort(machineOrder));
|
|
440
401
|
} catch {}
|
|
441
|
-
}, [
|
|
402
|
+
}, []);
|
|
442
403
|
const openRef = (0, import_react.useRef)(open);
|
|
443
404
|
openRef.current = open;
|
|
444
405
|
(0, import_react.useEffect)(() => {
|
|
@@ -474,7 +435,7 @@ function MachinesModal({ open, onClose, teamId }) {
|
|
|
474
435
|
setBusy(true);
|
|
475
436
|
setDelErr(null);
|
|
476
437
|
try {
|
|
477
|
-
const r = await createMachine(
|
|
438
|
+
const r = await createMachine();
|
|
478
439
|
if ("error" in r) {
|
|
479
440
|
setDelErr(r.error);
|
|
480
441
|
return;
|
|
@@ -756,4 +717,4 @@ function MachinesModal({ open, onClose, teamId }) {
|
|
|
756
717
|
});
|
|
757
718
|
}
|
|
758
719
|
//#endregion
|
|
759
|
-
export {
|
|
720
|
+
export { Timeline as a, mergeRuns as c, ModalHead as i, MachinesModal as n, daemonConnectCommand as o, Modal as r, listMachines as s, LoopOverview as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/SignIn-
|
|
2
|
+
import { C as signIn, a as PievoLogo, n as GITHUB_URL, r as GitHubIcon } from "./auth-client-RTpMpT4L.mjs";
|
|
3
|
+
import { u as btnPrimary } from "./actionUi-C_WswNb1.mjs";
|
|
4
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/SignIn-Bp3uWaCQ.js
|
|
5
5
|
var import_jsx_runtime = require_jsx_runtime();
|
|
6
6
|
/**
|
|
7
7
|
* Sign-in CTA — shown by the auth gate when a GitHub OAuth app is configured and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { o as __toESM } from "../_runtime.mjs";
|
|
2
2
|
import { g as require_react, h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
|
|
3
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/
|
|
3
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/actionUi-C_WswNb1.js
|
|
4
4
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
5
5
|
var import_jsx_runtime = require_jsx_runtime();
|
|
6
6
|
var fmt = (t) => t ? new Date(t).toLocaleString() : "—";
|
|
@@ -242,5 +242,116 @@ function StatusPill({ run, colorText }) {
|
|
|
242
242
|
}), dotLabel(run)]
|
|
243
243
|
});
|
|
244
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* First-load failure card — the calm "couldn't load X" + Retry the dashboard,
|
|
247
|
+
* loop page, and run page all show instead of a raw error dump. One shared
|
|
248
|
+
* markup so the three screens can't drift.
|
|
249
|
+
*/
|
|
250
|
+
function LoadErrorCard({ title, detail, onRetry }) {
|
|
251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
252
|
+
className: "rounded-card border border-hairline bg-surface px-6 py-8 shadow-card",
|
|
253
|
+
children: [
|
|
254
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
255
|
+
className: "text-[14px] text-accent",
|
|
256
|
+
children: title
|
|
257
|
+
}),
|
|
258
|
+
detail && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
259
|
+
className: "mt-1 text-meta text-secondary",
|
|
260
|
+
children: detail
|
|
261
|
+
}),
|
|
262
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
263
|
+
type: "button",
|
|
264
|
+
onClick: onRetry,
|
|
265
|
+
className: "mt-3 cursor-pointer border-none bg-transparent p-0 text-label font-medium text-interactive underline underline-offset-2 hover:text-display",
|
|
266
|
+
children: "Retry"
|
|
267
|
+
})
|
|
268
|
+
]
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* In-panel guard — the Nothing-styled stand-in for native confirm(). Owns its
|
|
273
|
+
* own a11y so the caller just renders it when armed: focus lands on the CTA,
|
|
274
|
+
* Esc cancels, Enter (CTA focused) confirms. Render with `key={kind}` so it
|
|
275
|
+
* remounts (and re-focuses) per guard.
|
|
276
|
+
*/
|
|
277
|
+
function ConfirmBar({ prompt, note, cta, danger, busy, onConfirm, onCancel }) {
|
|
278
|
+
const ctaRef = (0, import_react.useRef)(null);
|
|
279
|
+
(0, import_react.useEffect)(() => {
|
|
280
|
+
ctaRef.current?.focus();
|
|
281
|
+
}, []);
|
|
282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
283
|
+
role: "group",
|
|
284
|
+
"aria-label": prompt,
|
|
285
|
+
onKeyDown: (e) => {
|
|
286
|
+
if (e.key === "Escape" && !busy) onCancel();
|
|
287
|
+
},
|
|
288
|
+
className: "flex flex-wrap items-center gap-x-4 gap-y-2.5 rounded-control border border-hairline bg-raised px-4 py-3",
|
|
289
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
290
|
+
className: "min-w-0",
|
|
291
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
292
|
+
className: "text-body font-medium text-display",
|
|
293
|
+
children: prompt
|
|
294
|
+
}), note && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
295
|
+
className: "mt-0.5 text-meta text-secondary",
|
|
296
|
+
children: note
|
|
297
|
+
})]
|
|
298
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
299
|
+
className: "ml-auto flex items-center gap-2.5",
|
|
300
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
301
|
+
ref: ctaRef,
|
|
302
|
+
className: danger ? btnDanger : btnPrimary,
|
|
303
|
+
disabled: busy,
|
|
304
|
+
onClick: onConfirm,
|
|
305
|
+
children: busy ? "Working…" : cta
|
|
306
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
307
|
+
className: btn,
|
|
308
|
+
disabled: busy,
|
|
309
|
+
onClick: onCancel,
|
|
310
|
+
children: "Cancel"
|
|
311
|
+
})]
|
|
312
|
+
})]
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Transient peak-end acknowledgement (✓ done / ✕ gone), announced to AT via
|
|
317
|
+
* aria-live. Self-clearing is the caller's concern (see `useFlash`); this is
|
|
318
|
+
* pure presentation. No outer margin — wrap at the call site for spacing.
|
|
319
|
+
*/
|
|
320
|
+
function FlashLine({ label, tone = "ok", onUndo }) {
|
|
321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
322
|
+
role: "status",
|
|
323
|
+
"aria-live": "polite",
|
|
324
|
+
className: "inline-flex items-center gap-2 text-label font-medium text-secondary",
|
|
325
|
+
style: { animation: "fadeIn 0.2s ease-out" },
|
|
326
|
+
children: [
|
|
327
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
328
|
+
"aria-hidden": true,
|
|
329
|
+
className: tone === "gone" ? "text-accent" : "text-success",
|
|
330
|
+
children: tone === "gone" ? "✕" : "✓"
|
|
331
|
+
}),
|
|
332
|
+
label,
|
|
333
|
+
onUndo && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
334
|
+
type: "button",
|
|
335
|
+
onClick: onUndo,
|
|
336
|
+
className: "cursor-pointer border-none bg-transparent p-0 text-label font-medium text-interactive underline underline-offset-2 transition-colors hover:text-display",
|
|
337
|
+
children: "Undo"
|
|
338
|
+
})
|
|
339
|
+
]
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Flash state + its self-clear timer in one unit. `hold` wins; else an Undo
|
|
344
|
+
* flash lingers ~6s (reachable), a bare "done" fades after ~2.2s. Fade, don't
|
|
345
|
+
* slide.
|
|
346
|
+
*/
|
|
347
|
+
function useFlash() {
|
|
348
|
+
const [flash, setFlash] = (0, import_react.useState)(null);
|
|
349
|
+
(0, import_react.useEffect)(() => {
|
|
350
|
+
if (!flash) return;
|
|
351
|
+
const t = setTimeout(() => setFlash(null), flash.hold ?? (flash.undo ? 6e3 : 2200));
|
|
352
|
+
return () => clearTimeout(t);
|
|
353
|
+
}, [flash]);
|
|
354
|
+
return [flash, setFlash];
|
|
355
|
+
}
|
|
245
356
|
//#endregion
|
|
246
|
-
export {
|
|
357
|
+
export { until as A, rel as C, sectionHeadCls as D, scheduleText as E, useHydrated as M, selectCls as O, lastRunOf as S, runPulseStyle as T, fmt as _, Loading as a, inputCls as b, btn as c, btnQuiet as d, btnSm as f, dur as g, dotOpacity as h, LoadErrorCard as i, useFlash as j, tsShort as k, btnDanger as l, dotLabel as m, ErrorBanner as n, Pill as o, dotColor as p, FlashLine as r, StatusPill as s, ConfirmBar as t, btnPrimary as u, fnum as v, runPulseAnim as w, labelCls as x, humanBytes as y };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as toArtifactSummary } from "./loopProjection-
|
|
3
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/artifactFiles-
|
|
1
|
+
import { O as getArtifactFile, Z as listArtifacts, k as getArtifactSync, xt as safeRelPath } from "./boot-U-CFI65B.mjs";
|
|
2
|
+
import { n as toArtifactSummary } from "./loopProjection-DMSNHux6.mjs";
|
|
3
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/artifactFiles-BvVmixrs.js
|
|
4
4
|
/**
|
|
5
5
|
* Server-side reads over a loop's current exact artifacts. Pure helpers
|
|
6
6
|
* (no request/session context) so they're shared by the lazy server fns
|
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
import { c as createFileRoute, s as lazyRouteComponent } from "../_libs/@tanstack/react-router+[...].mjs";
|
|
2
|
-
import {
|
|
3
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/artifactKind-
|
|
4
|
-
var $$splitComponentImporter = () => import("./loops._loopId-
|
|
2
|
+
import { f as getAuthState } from "./auth-client-RTpMpT4L.mjs";
|
|
3
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/artifactKind-DRCbYHZU.js
|
|
4
|
+
var $$splitComponentImporter = () => import("./loops._loopId-Q4pRYPip.mjs");
|
|
5
5
|
/**
|
|
6
6
|
* Loop detail page — `/loops/$loopId`: a loop header and action toolbar, the
|
|
7
7
|
* exact artifact Files panel, and the runs timeline. The view owns its own
|
|
8
8
|
* data + self-poll (ssr:false so the session cookie rides along with its fetches,
|
|
9
9
|
* like the dashboard loader). Run rows link on to `/loops/$loopId/runs/$runId`.
|
|
10
10
|
*
|
|
11
|
-
* Auth-gated exactly like the dashboard (`/`):
|
|
12
|
-
*
|
|
13
|
-
* a raw `loop not found` error from the ownership-blocked data fetch.
|
|
11
|
+
* Auth-gated exactly like the dashboard (`/`): Better Auth's session hook keeps a
|
|
12
|
+
* logged-out or expired deep link from mounting the ownership-scoped data view.
|
|
14
13
|
*/
|
|
15
14
|
var Route = createFileRoute("/loops/$loopId")({
|
|
16
15
|
ssr: false,
|
|
17
|
-
loader: async () => {
|
|
18
|
-
const auth = await getAuthState();
|
|
19
|
-
if (auth.enabled) {
|
|
20
|
-
const { data: session } = await authClient.getSession();
|
|
21
|
-
if (!session) return { auth };
|
|
22
|
-
}
|
|
23
|
-
return { auth };
|
|
24
|
-
},
|
|
16
|
+
loader: async () => ({ auth: await getAuthState() }),
|
|
25
17
|
component: lazyRouteComponent($$splitComponentImporter, "component")
|
|
26
18
|
});
|
|
27
19
|
/** Extension → MIME for the image types we serve inline. This is an ALLOWLIST:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as notInArray, S as ne, _ as isNotNull, b as lt, d as and, f as eq, g as inArray, h as ilike, j as sql, l as asc, m as gte, p as gt, s as count, u as desc, v as isNull$1, w as or, x as lte, y as like } from "../_libs/drizzle-orm+postgres.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { C as withSpan, S as shouldPublishLog, _ as logger, a as __getBetterAuthGlobal, b as runWithTransaction, c as createRandomStringGenerator, d as getAuthTables, f as getBetterAuthVersion, g as initGetModelName, h as initGetFieldName, l as generateId$2, m as import_src, n as ATTR_HOOK_TYPE, o as createAdapterFactory, p as getCurrentAdapter, r as ATTR_OPERATION_ID, s as createLogger, t as ATTR_CONTEXT, u as getAsyncLocalStorage, v as queueAfterTransactionHook, x as safeJSONParse, y as runWithAdapter } from "./factory-
|
|
2
|
+
import { A as getBaseURL, C as defu, F as getHost, Ft as wildcardMatch, K as isProduction, N as getEnvVar, R as getOrigin, S as db, T as env, U as isDevelopment, W as isDynamicBaseURLConfig, X as kAPIErrorHeaderSymbol, Y as isTest, a as BetterAuthError, at as loginGateEnabled, bt as resolveBaseURL, c as ENV, h as capitalizeFirstLetter, j as getBooleanEnvVar, m as betterFetch, n as APIError$1, o as BetterCallError, p as ValidationError$1, q as isRequestLike, r as BASE_ERROR_CODES, t as APIError, ut as normalizePathname, v as createDefu, z as getProtocol } from "./boot-U-CFI65B.mjs";
|
|
3
|
+
import { C as withSpan, S as shouldPublishLog, _ as logger, a as __getBetterAuthGlobal, b as runWithTransaction, c as createRandomStringGenerator, d as getAuthTables, f as getBetterAuthVersion, g as initGetModelName, h as initGetFieldName, l as generateId$2, m as import_src, n as ATTR_HOOK_TYPE, o as createAdapterFactory, p as getCurrentAdapter, r as ATTR_OPERATION_ID, s as createLogger, t as ATTR_CONTEXT, u as getAsyncLocalStorage, v as queueAfterTransactionHook, x as safeJSONParse, y as runWithAdapter } from "./factory-DYFx1fg-.mjs";
|
|
4
4
|
import { randomBytes, scrypt } from "node:crypto";
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
@@ -1700,7 +1700,7 @@ var JOIN_TYPE_SQL = freeze({
|
|
|
1700
1700
|
Using: "using"
|
|
1701
1701
|
});
|
|
1702
1702
|
//#endregion
|
|
1703
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/auth-
|
|
1703
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/auth-BV0MxVdo.js
|
|
1704
1704
|
/**
|
|
1705
1705
|
* @internal
|
|
1706
1706
|
*/
|
|
@@ -15993,7 +15993,7 @@ var createKyselyAdapter = async (config) => {
|
|
|
15993
15993
|
if ("getConnection" in db) dialect = new MysqlDialect(db);
|
|
15994
15994
|
if ("connect" in db) dialect = new PostgresDialect({ pool: db });
|
|
15995
15995
|
if ("fileControl" in db) {
|
|
15996
|
-
const { BunSqliteDialect } = await import("./bun-sqlite-dialect-BW9W1_Ps-
|
|
15996
|
+
const { BunSqliteDialect } = await import("./bun-sqlite-dialect-BW9W1_Ps-D9KUBJ-L.mjs");
|
|
15997
15997
|
dialect = new BunSqliteDialect({ database: db });
|
|
15998
15998
|
}
|
|
15999
15999
|
if ("createSession" in db) {
|
|
@@ -16009,12 +16009,12 @@ var createKyselyAdapter = async (config) => {
|
|
|
16009
16009
|
if (error !== null && typeof error === "object" && "code" in error && error.code !== "ERR_UNKNOWN_BUILTIN_MODULE") throw error;
|
|
16010
16010
|
}
|
|
16011
16011
|
if (DatabaseSync && db instanceof DatabaseSync) {
|
|
16012
|
-
const { NodeSqliteDialect } = await import("./node-sqlite-dialect-
|
|
16012
|
+
const { NodeSqliteDialect } = await import("./node-sqlite-dialect-B_g92oFK.mjs");
|
|
16013
16013
|
dialect = new NodeSqliteDialect({ database: db });
|
|
16014
16014
|
}
|
|
16015
16015
|
}
|
|
16016
16016
|
if ("batch" in db && "exec" in db && "prepare" in db) {
|
|
16017
|
-
const { D1SqliteDialect } = await import("./d1-sqlite-dialect-BLC8LXE6-
|
|
16017
|
+
const { D1SqliteDialect } = await import("./d1-sqlite-dialect-BLC8LXE6-CVHRzH1n.mjs");
|
|
16018
16018
|
dialect = new D1SqliteDialect({ database: db });
|
|
16019
16019
|
}
|
|
16020
16020
|
return {
|
|
@@ -36526,7 +36526,7 @@ async function getBaseAdapter(options, handleDirectDatabase) {
|
|
|
36526
36526
|
acc[key] = [];
|
|
36527
36527
|
return acc;
|
|
36528
36528
|
}, {});
|
|
36529
|
-
const { memoryAdapter } = await import("./dist-
|
|
36529
|
+
const { memoryAdapter } = await import("./dist-D7UDVZ5G.mjs");
|
|
36530
36530
|
adapter = memoryAdapter(memoryDB)(options);
|
|
36531
36531
|
} else if (typeof options.database === "function") adapter = options.database(options);
|
|
36532
36532
|
else adapter = await handleDirectDatabase(options);
|
|
@@ -36540,10 +36540,10 @@ async function getBaseAdapter(options, handleDirectDatabase) {
|
|
|
36540
36540
|
}
|
|
36541
36541
|
async function getAdapter(options) {
|
|
36542
36542
|
return getBaseAdapter(options, async (opts) => {
|
|
36543
|
-
const { createKyselyAdapter } = await import("./kysely-adapter-
|
|
36543
|
+
const { createKyselyAdapter } = await import("./kysely-adapter-CwdB7yBh.mjs");
|
|
36544
36544
|
const { kysely, databaseType, transaction } = await createKyselyAdapter(opts);
|
|
36545
36545
|
if (!kysely) throw new BetterAuthError("Failed to initialize database adapter");
|
|
36546
|
-
const { kyselyAdapter } = await import("./kysely-adapter-
|
|
36546
|
+
const { kyselyAdapter } = await import("./kysely-adapter-CwdB7yBh.mjs");
|
|
36547
36547
|
return kyselyAdapter(kysely, {
|
|
36548
36548
|
type: databaseType || "sqlite",
|
|
36549
36549
|
debugLogs: opts.database && "debugLogs" in opts.database ? opts.database.debugLogs : false,
|
|
@@ -38278,40 +38278,23 @@ var drizzleAdapter = (db, config) => {
|
|
|
38278
38278
|
};
|
|
38279
38279
|
};
|
|
38280
38280
|
/**
|
|
38281
|
-
*
|
|
38282
|
-
* `
|
|
38283
|
-
*
|
|
38284
|
-
*
|
|
38285
|
-
* hot path. Leaf module — no imports, no side effects.
|
|
38286
|
-
*
|
|
38287
|
-
* The gate is ON exactly when a GitHub OAuth app is configured (both id + secret).
|
|
38288
|
-
* OFF ⇒ open/dev mode (single shared workspace, anonymous self-registration).
|
|
38289
|
-
*/
|
|
38290
|
-
function loginGateEnabled() {
|
|
38291
|
-
return !!(process.env.GITHUB_CLIENT_ID?.trim() && process.env.GITHUB_CLIENT_SECRET?.trim());
|
|
38292
|
-
}
|
|
38293
|
-
/**
|
|
38294
|
-
* Better Auth with GitHub social login. Supplying the GitHub OAuth credentials
|
|
38295
|
-
* enables authentication; `PIEVO_ALLOWED_LOGINS` optionally narrows who may sign
|
|
38296
|
-
* in. Authenticated data is team-scoped, while `userId` retains creator/owner
|
|
38297
|
-
* attribution. With no GitHub credentials the local server runs in open mode.
|
|
38281
|
+
* Better Auth with GitHub social login. Supplying GitHub OAuth credentials
|
|
38282
|
+
* enables authentication; `PIEVO_ALLOWED_LOGINS` optionally narrows who may
|
|
38283
|
+
* sign in. Auth mode isolates data by signed-in user. Without GitHub
|
|
38284
|
+
* credentials, the server is one shared open-mode workspace.
|
|
38298
38285
|
*/
|
|
38299
38286
|
var clientId = process.env.GITHUB_CLIENT_ID?.trim();
|
|
38300
38287
|
var clientSecret = process.env.GITHUB_CLIENT_SECRET?.trim();
|
|
38301
|
-
/**
|
|
38302
|
-
* the condition is `loginGateEnabled()` — the machine-enrollment guard reads it
|
|
38303
|
-
* live so the two can never drift. */
|
|
38288
|
+
/** Keep the web-session gate and machine-enrollment gate on one live condition. */
|
|
38304
38289
|
var authEnabled = loginGateEnabled();
|
|
38305
38290
|
var authSecret = process.env.PIEVO_AUTH_SECRET?.trim();
|
|
38306
38291
|
if (authEnabled && !authSecret) throw new Error("PIEVO_AUTH_SECRET must be set when the GitHub login gate is enabled (GITHUB_CLIENT_ID/SECRET present) — refusing to fall back to the public dev secret.");
|
|
38307
|
-
var allowlist = (process.env.PIEVO_ALLOWED_LOGINS || "").split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
38308
38292
|
/**
|
|
38309
|
-
*
|
|
38310
|
-
*
|
|
38311
|
-
* WILDCARD — `@example.com` or `*@example.com` — matching any address at that
|
|
38312
|
-
* domain (so `*@example.com` admits the whole team without listing each one).
|
|
38293
|
+
* An empty allowlist permits any GitHub-authenticated user. Entries may be full
|
|
38294
|
+
* email addresses or domain wildcards (`@example.com` or `*@example.com`).
|
|
38313
38295
|
*/
|
|
38314
38296
|
function emailAllowed(email) {
|
|
38297
|
+
const allowlist = (process.env.PIEVO_ALLOWED_LOGINS || "").split(",").map((entry) => entry.trim().toLowerCase()).filter(Boolean);
|
|
38315
38298
|
if (!allowlist.length) return true;
|
|
38316
38299
|
const e = (email || "").toLowerCase();
|
|
38317
38300
|
const at = e.indexOf("@");
|
|
@@ -38319,97 +38302,41 @@ function emailAllowed(email) {
|
|
|
38319
38302
|
const domain = e.slice(at);
|
|
38320
38303
|
return allowlist.some((entry) => entry === e || entry === domain || entry.startsWith("*@") && entry.slice(1) === domain);
|
|
38321
38304
|
}
|
|
38322
|
-
function
|
|
38323
|
-
|
|
38324
|
-
return local ? `${local}'s Team` : "Personal Team";
|
|
38305
|
+
function rejectDisallowedEmail(email) {
|
|
38306
|
+
throw new APIError("FORBIDDEN", { message: `${(email || "").trim().toLowerCase() || "this account"} is not on the Pievo allowlist` });
|
|
38325
38307
|
}
|
|
38326
|
-
|
|
38327
|
-
/**
|
|
38328
|
-
* The signed-in user (id + email) for the current server-fn request, or null when
|
|
38329
|
-
* no session. Reads the request via TanStack's async-local context, so it only
|
|
38330
|
-
* works inside a server fn / server route handler.
|
|
38331
|
-
*/
|
|
38308
|
+
/** The Better Auth user for the current server request, or null without a session. */
|
|
38332
38309
|
async function currentUser() {
|
|
38333
38310
|
const { getRequest } = await import("./ssr.mjs").then((n) => n.i).then((n) => n.t);
|
|
38334
|
-
const
|
|
38335
|
-
return
|
|
38336
|
-
id:
|
|
38337
|
-
email:
|
|
38311
|
+
const user = (await auth.api.getSession({ headers: getRequest().headers }))?.user;
|
|
38312
|
+
return user ? {
|
|
38313
|
+
id: user.id,
|
|
38314
|
+
email: user.email ?? null
|
|
38338
38315
|
} : null;
|
|
38339
38316
|
}
|
|
38340
38317
|
async function currentUserId() {
|
|
38341
38318
|
return (await currentUser())?.id ?? null;
|
|
38342
38319
|
}
|
|
38343
|
-
async function selectedTeam() {
|
|
38344
|
-
const { getRequest } = await import("./ssr.mjs").then((n) => n.i).then((n) => n.t);
|
|
38345
|
-
const raw = getRequest().headers.get("cookie") || "";
|
|
38346
|
-
const v = new RegExp(`(?:^|;\\s*)${TEAM_COOKIE}=([^;]+)`).exec(raw)?.[1];
|
|
38347
|
-
return v ? decodeURIComponent(v) : null;
|
|
38348
|
-
}
|
|
38349
38320
|
/**
|
|
38350
|
-
*
|
|
38351
|
-
*
|
|
38352
|
-
|
|
38353
|
-
|
|
38354
|
-
|
|
38355
|
-
|
|
38356
|
-
|
|
38357
|
-
|
|
38358
|
-
* value falls through to the personal team exactly like a stale cookie, so the
|
|
38359
|
-
* caller can detect rejection by comparing the returned `teamId` to what it asked
|
|
38360
|
-
* for (see `canViewTeam` in loopApi) without this ever leaking another team's data.
|
|
38361
|
-
*/
|
|
38362
|
-
async function requestScope(explicitTeam) {
|
|
38363
|
-
const enforce = authEnabled;
|
|
38364
|
-
if (!enforce) {
|
|
38365
|
-
const teamId = teamIdForUser(null);
|
|
38366
|
-
await ensureTeam(teamId, "Shared Workspace", null);
|
|
38367
|
-
return {
|
|
38368
|
-
enforce,
|
|
38369
|
-
userId: null,
|
|
38370
|
-
teamId
|
|
38371
|
-
};
|
|
38372
|
-
}
|
|
38373
|
-
const user = await currentUser();
|
|
38374
|
-
const userId = user?.id ?? null;
|
|
38375
|
-
const personalTeam = teamIdForUser(userId);
|
|
38376
|
-
await ensureTeam(personalTeam, userId ? teamNameForEmail(user?.email) : "Shared Workspace", userId);
|
|
38377
|
-
const sel = explicitTeam != null && explicitTeam !== "" ? explicitTeam : await selectedTeam();
|
|
38378
|
-
if (sel && sel !== personalTeam && userId) {
|
|
38379
|
-
if (await isTeamMember(sel, userId)) return {
|
|
38380
|
-
enforce,
|
|
38381
|
-
userId,
|
|
38382
|
-
teamId: sel
|
|
38383
|
-
};
|
|
38384
|
-
}
|
|
38321
|
+
* Auth mode uses the signed-in user as the sole tenant boundary. Open mode is
|
|
38322
|
+
* intentionally unscoped and does not perform a session lookup.
|
|
38323
|
+
*/
|
|
38324
|
+
async function requestScope() {
|
|
38325
|
+
if (!authEnabled) return {
|
|
38326
|
+
enforce: false,
|
|
38327
|
+
userId: null
|
|
38328
|
+
};
|
|
38385
38329
|
return {
|
|
38386
|
-
enforce,
|
|
38387
|
-
userId
|
|
38388
|
-
teamId: personalTeam
|
|
38330
|
+
enforce: true,
|
|
38331
|
+
userId: await currentUserId()
|
|
38389
38332
|
};
|
|
38390
38333
|
}
|
|
38391
38334
|
/**
|
|
38392
|
-
*
|
|
38393
|
-
*
|
|
38394
|
-
|
|
38395
|
-
|
|
38396
|
-
|
|
38397
|
-
* matching the caller's active team. A user who belongs to team B can open a
|
|
38398
|
-
* direct link to a team-B loop while their active team is A, instead of getting a
|
|
38399
|
-
* spurious "not found" (the cross-team-link bug). Rules:
|
|
38400
|
-
* - open mode ⇒ the single shared workspace, everything visible;
|
|
38401
|
-
* - the active team is a no-DB fast path (requestScope already membership-
|
|
38402
|
-
* validated the active-team cookie);
|
|
38403
|
-
* - otherwise the user must be a MEMBER of the loop's team.
|
|
38404
|
-
* Async because the membership fall-through is a store lookup. A non-member (and a
|
|
38405
|
-
* signed-out request) is denied, indistinguishable from a nonexistent loop.
|
|
38406
|
-
*/
|
|
38407
|
-
async function canAccessLoop(loopTeamId, scope) {
|
|
38408
|
-
const { enforce, teamId, userId } = scope;
|
|
38409
|
-
if (!enforce) return true;
|
|
38410
|
-
if (loopTeamId === teamId) return true;
|
|
38411
|
-
if (!loopTeamId || !userId) return false;
|
|
38412
|
-
return isTeamMember(loopTeamId, userId);
|
|
38335
|
+
* Shared loop authorization used by server functions and raw artifact serving.
|
|
38336
|
+
* A denied loop and an absent loop must remain externally indistinguishable.
|
|
38337
|
+
*/
|
|
38338
|
+
function canAccessLoop(loopUserId, scope) {
|
|
38339
|
+
return !scope.enforce || !!scope.userId && loopUserId === scope.userId;
|
|
38413
38340
|
}
|
|
38414
38341
|
var auth = betterAuth({
|
|
38415
38342
|
baseURL: process.env.PIEVO_BASE_URL || "http://127.0.0.1:3000",
|
|
@@ -38419,17 +38346,10 @@ var auth = betterAuth({
|
|
|
38419
38346
|
clientId,
|
|
38420
38347
|
clientSecret
|
|
38421
38348
|
} } : {},
|
|
38422
|
-
databaseHooks: { user: { create: {
|
|
38423
|
-
|
|
38424
|
-
|
|
38425
|
-
|
|
38426
|
-
},
|
|
38427
|
-
after: async (user) => {
|
|
38428
|
-
try {
|
|
38429
|
-
await ensureTeam(teamIdForUser(user.id), teamNameForEmail(user.email), user.id);
|
|
38430
|
-
} catch {}
|
|
38431
|
-
}
|
|
38432
|
-
} } }
|
|
38349
|
+
databaseHooks: { user: { create: { before: async (user) => {
|
|
38350
|
+
if (!emailAllowed(user.email)) rejectDisallowedEmail(user.email);
|
|
38351
|
+
return { data: user };
|
|
38352
|
+
} } } }
|
|
38433
38353
|
});
|
|
38434
38354
|
//#endregion
|
|
38435
|
-
export { SqliteQueryCompiler as a, auth, authEnabled, canAccessLoop,
|
|
38355
|
+
export { SqliteQueryCompiler as a, auth, authEnabled, canAccessLoop, SqliteAdapter as i, DefaultQueryCompiler as n, CompiledQuery as o, kyselyAdapter as r, requestScope, sql$1 as s, createKyselyAdapter as t };
|