@wssto2/vue-core 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +4 -2
  3. package/dist/{AccessGate.vue_vue_type_script_setup_true_lang-CzQbD2Pc.js → AccessGate.vue_vue_type_script_setup_true_lang-DEzXovsY.js} +1 -1
  4. package/dist/{Activity-CdkJW68R.js → Activity-ChfxdvXf.js} +24 -23
  5. package/dist/{AdaptivePageShell.vue_vue_type_script_setup_true_lang-D5i77H6S.js → AdaptivePageShell.vue_vue_type_script_setup_true_lang-lPj9hPqV.js} +33 -33
  6. package/dist/{Changes-DxK_QfiB.js → Changes-BCa43_mO.js} +18 -17
  7. package/dist/{CollectionPage.vue_vue_type_script_setup_true_lang-x0jyJ01f.js → CollectionPage.vue_vue_type_script_setup_true_lang-C1GCvyZx.js} +6 -6
  8. package/dist/{DataTable.vue_vue_type_script_setup_true_lang-C_ZytnW-.js → DataTable.vue_vue_type_script_setup_true_lang-B9r9M5Gt.js} +1 -1
  9. package/dist/{DateField.vue_vue_type_script_setup_true_lang-CeNwBbJT.js → DateField.vue_vue_type_script_setup_true_lang-B5UUY1OO.js} +2 -2
  10. package/dist/{DeadLetters-DnA7LP1w.js → DeadLetters-wFTqhISU.js} +5 -5
  11. package/dist/{General-2matxl2Y.js → General-jW7u4MjH.js} +16 -15
  12. package/dist/{IncidentRecord-Bt3G4HlX.js → IncidentRecord-CXzgLKqI.js} +6 -6
  13. package/dist/{IncidentsList-2iwgqp9J.js → IncidentsList-D1MySyXb.js} +6 -6
  14. package/dist/{NewRolePage-DhGFwvk3.js → NewRolePage-CQ5UVaHs.js} +3 -3
  15. package/dist/{NumberField.vue_vue_type_script_setup_true_lang-B3UrXNqH.js → NumberField.vue_vue_type_script_setup_true_lang-YVgf5CP6.js} +1 -1
  16. package/dist/{PersonAccess.vue_vue_type_script_setup_true_lang-DbGZSNQc.js → PersonAccess.vue_vue_type_script_setup_true_lang-CWCt9_dM.js} +2 -2
  17. package/dist/{ProfilePage-CpuyDBAv.js → ProfilePage-Ca3x3UAH.js} +79 -77
  18. package/dist/{RecordHeader.vue_vue_type_script_setup_true_lang-DqGc3Jyo.js → RecordHeader.vue_vue_type_script_setup_true_lang-Do_ATJwT.js} +1 -1
  19. package/dist/{ResourcePage.vue_vue_type_script_setup_true_lang-DljhsTU4.js → ResourcePage.vue_vue_type_script_setup_true_lang-Coz91xht.js} +1 -1
  20. package/dist/{RoleEditor.vue_vue_type_script_setup_true_lang-C0FIotFA.js → RoleEditor.vue_vue_type_script_setup_true_lang-d_aaeXTT.js} +2 -2
  21. package/dist/{RolePage-DaNv049g.js → RolePage-BUj1w1m1.js} +5 -5
  22. package/dist/{RolesPage-6hlzJes_.js → RolesPage-NKzBUsrM.js} +3 -3
  23. package/dist/{SectionNavigator.vue_vue_type_script_setup_true_lang-Dh3sXUt_.js → SectionNavigator.vue_vue_type_script_setup_true_lang-DfKEhTFv.js} +2 -2
  24. package/dist/{ServiceAccountDialog.vue_vue_type_script_setup_true_lang-FJbWxME_.js → ServiceAccountDialog.vue_vue_type_script_setup_true_lang-4nbhEpv_.js} +10 -9
  25. package/dist/{ServiceAccountRecord-0-JF5lRx.js → ServiceAccountRecord-ClbyeLhL.js} +8 -8
  26. package/dist/{ServiceAccountsList-DcsnOcf-.js → ServiceAccountsList-B2VDnYxD.js} +5 -5
  27. package/dist/{Sessions-DgWhpk-i.js → Sessions-BjkciyHH.js} +23 -21
  28. package/dist/{SettingsPage-BXPWATYU.js → SettingsPage-Csb14qsx.js} +7 -7
  29. package/dist/{SignIn-DPoUwHZd.js → SignIn-DPFMv4C7.js} +14 -12
  30. package/dist/{SignInPage-OyrVemro.js → SignInPage-DukoFqkt.js} +2 -2
  31. package/dist/{SignIns-BMDrZVVp.js → SignIns-DvdpNkiS.js} +23 -22
  32. package/dist/{TimeField.vue_vue_type_script_setup_true_lang-D-Em4glH.js → TimeField.vue_vue_type_script_setup_true_lang-DpDXHH7u.js} +2 -2
  33. package/dist/{Timestamp.vue_vue_type_script_setup_true_lang-ClZAAUMd.js → Timestamp.vue_vue_type_script_setup_true_lang-DlEUKWra.js} +1 -1
  34. package/dist/{UserRecord-BW-gdCqi.js → UserRecord-B9SeSWQh.js} +57 -55
  35. package/dist/{UsersList-B3ZF_1Dj.js → UsersList-CREG8q3l.js} +4 -4
  36. package/dist/access/index.js +4 -4
  37. package/dist/app/application.d.ts +14 -6
  38. package/dist/app/current.d.ts +11 -0
  39. package/dist/app/environment.d.ts +8 -0
  40. package/dist/app/index.d.ts +1 -0
  41. package/dist/app/index.js +14 -12
  42. package/dist/application-DomS6sbx.js +435 -0
  43. package/dist/collection/http.d.ts +16 -1
  44. package/dist/collection/index.d.ts +1 -1
  45. package/dist/collection/index.js +34 -32
  46. package/dist/content/Money.vue.d.ts +1 -1
  47. package/dist/content/index.js +151 -158
  48. package/dist/{contributions-CeG4bszd.js → contributions-obnyn03x.js} +1 -1
  49. package/dist/current-B0lHKTWr.js +17 -0
  50. package/dist/form/DateField.vue.d.ts +2 -2
  51. package/dist/form/DateTimeField.vue.d.ts +2 -2
  52. package/dist/form/MoneyField.vue.d.ts +1 -1
  53. package/dist/form/NumberField.vue.d.ts +1 -1
  54. package/dist/form/date/MonthYearPanel.vue.d.ts +1 -1
  55. package/dist/form/date/days.d.ts +3 -3
  56. package/dist/form/index.d.ts +2 -0
  57. package/dist/form/index.js +1111 -1081
  58. package/dist/form/zodErrorMap.d.ts +35 -0
  59. package/dist/format/format.d.ts +51 -6
  60. package/dist/format/index.d.ts +1 -1
  61. package/dist/format/index.js +1 -1
  62. package/dist/format-DoKs29bZ.js +118 -0
  63. package/dist/{guards-Biv_SlGn.js → guards-DGcSfTEh.js} +1 -1
  64. package/dist/http-DOEfFCDA.js +107 -0
  65. package/dist/i18n/index.js +15 -15
  66. package/dist/identity/index.d.ts +2 -0
  67. package/dist/identity/index.js +43 -40
  68. package/dist/identity/usePreferences.d.ts +19 -0
  69. package/dist/incidents/clientErrorReporter.d.ts +2 -1
  70. package/dist/incidents/index.js +1 -1
  71. package/dist/{index-kEHY7hcG.js → index-CRxU_Wh2.js} +61 -61
  72. package/dist/{index-Cq9TuOqH.js → index-DZikGJ8L.js} +457 -511
  73. package/dist/{index-ClJeyW3F.js → index-D_yyd4C2.js} +4 -4
  74. package/dist/index.d.ts +1 -1
  75. package/dist/index.js +1 -1
  76. package/dist/internal/intlLocale.d.ts +5 -2
  77. package/dist/modules/identity/entities.d.ts +4 -0
  78. package/dist/modules/identity/routes.d.ts +5 -2
  79. package/dist/modules/identity/schemas.d.ts +6 -2
  80. package/dist/{navigation-TnVFYRaX.js → navigation-CctcxT51.js} +1 -1
  81. package/dist/{neighbors-OyvGi233.js → neighbors-Csfan8Ho.js} +1 -1
  82. package/dist/notifications/index.js +1 -1
  83. package/dist/onboarding/Tip.vue.d.ts +41 -0
  84. package/dist/onboarding/index.d.ts +1 -0
  85. package/dist/onboarding/index.js +145 -0
  86. package/dist/onboarding/tips.d.ts +5 -0
  87. package/dist/page/index.js +3 -3
  88. package/dist/phone/index.js +74 -74
  89. package/dist/phone/phone.d.ts +3 -3
  90. package/dist/platform/httpSession.d.ts +1 -1
  91. package/dist/platform/index.d.ts +2 -0
  92. package/dist/platform/index.js +16 -13
  93. package/dist/platform/preferences.d.ts +35 -0
  94. package/dist/platform/session.d.ts +6 -1
  95. package/dist/platform-DtISOEt7.js +284 -0
  96. package/dist/playwright/session.d.ts +2 -0
  97. package/dist/preferences-hYhrw8Uy.js +91 -0
  98. package/dist/resource/index.d.ts +1 -0
  99. package/dist/resource/index.js +24 -8
  100. package/dist/resource/read.d.ts +16 -0
  101. package/dist/router/index.js +3 -3
  102. package/dist/{rowLayout-BsKEzEME.js → rowLayout-y1IB_h2r.js} +2 -2
  103. package/dist/{sections-CvUwZ-S1.js → sections-fkW_IJLc.js} +1 -1
  104. package/dist/{serverMessages-B6GHgi40.js → serverMessages-Ddghrewh.js} +1 -1
  105. package/dist/shell/darkMode.d.ts +13 -8
  106. package/dist/shell/index.js +396 -384
  107. package/dist/{state-6KSYsVw0.js → state-CXMexi0l.js} +1 -1
  108. package/dist/styles.css +1 -1
  109. package/dist/testing/app.d.ts +11 -0
  110. package/dist/testing/format.d.ts +4 -2
  111. package/dist/testing/index.d.ts +1 -1
  112. package/dist/testing/index.js +96 -89
  113. package/dist/testing/platform.d.ts +2 -0
  114. package/dist/usePreferences-B8LIZp_f.js +47 -0
  115. package/dist/{useTypedEntry-C_Bk4sI0.js → useTypedEntry-DKs8I1yP.js} +279 -280
  116. package/package.json +6 -2
  117. package/src/styles/components.css +17 -0
  118. package/dist/application-CuzT-0vW.js +0 -420
  119. package/dist/format-D8KUBmbS.js +0 -87
  120. package/dist/http-Dm0uXY9O.js +0 -95
  121. package/dist/intlLocale-CeRU44qJ.js +0 -4
  122. package/dist/platform-BQOX_Ntw.js +0 -283
@@ -0,0 +1,284 @@
1
+ import { c as U } from "./client-Dg303Pmc.js";
2
+ import { d as _ } from "./context-Ch1r4fdN.js";
3
+ import { a as A, A as z } from "./error-CD7x0Jrz.js";
4
+ import { shallowRef as C } from "vue";
5
+ const I = (e, r) => e.level === r.level && e.id === r.id, T = (e, r) => Object.prototype.hasOwnProperty.call(e, r);
6
+ function N(e, r = {}) {
7
+ const n = r.covers ?? I;
8
+ function o(s) {
9
+ const t = e();
10
+ return !t || !T(t.permissions, s) || t.unavailable.includes(s) ? null : t.permissions[s] ?? null;
11
+ }
12
+ function u(s, t) {
13
+ const c = o(s);
14
+ return c ? t ? (c.clauses.length > 0 ? c.clauses.map((i) => i.scope) : [c.scope]).some((i) => n(i, t)) : !0 : !1;
15
+ }
16
+ return {
17
+ get root() {
18
+ return e()?.root ?? !1;
19
+ },
20
+ can: u,
21
+ canAny: (s) => s.some((t) => u(t)),
22
+ canAll: (s) => s.every((t) => u(t)),
23
+ held: o
24
+ };
25
+ }
26
+ const $ = ["own", "own_location", "all"], y = (e) => typeof e == "object" && e !== null && !Array.isArray(e);
27
+ function S(e, r, n) {
28
+ return !y(e) || typeof e.level != "string" ? (n.push(`${r}: expected { level: string, id?: number }`), { level: "" }) : (e.id !== void 0 && typeof e.id != "number" && n.push(`${r}.id: expected number`), typeof e.id == "number" ? { level: e.level, id: e.id } : { level: e.level });
29
+ }
30
+ function O(e, r, n) {
31
+ return typeof e == "string" && $.includes(e) ? e : (n.push(`${r}: expected one of ${$.join(", ")}`), "own");
32
+ }
33
+ function B(e) {
34
+ const r = [], n = {}, o = { root: !1, permissions: {}, unavailable: [] };
35
+ if (!y(e)) return { snapshot: o, issues: ["access: expected an object"] };
36
+ if (!y(e.permissions)) r.push("access.permissions: expected an object");
37
+ else
38
+ for (const [s, t] of Object.entries(e.permissions)) {
39
+ const c = `access.permissions.${s}`;
40
+ if (!y(t)) {
41
+ r.push(`${c}: expected an object`);
42
+ continue;
43
+ }
44
+ const f = (Array.isArray(t.clauses) ? t.clauses : []).map((i, x) => {
45
+ const m = `${c}.clauses[${x}]`;
46
+ if (!y(i))
47
+ return r.push(`${m}: expected an object`), { scope: { level: "" }, qualifier: "own" };
48
+ const d = { scope: S(i.scope, `${m}.scope`, r), qualifier: O(i.qualifier, `${m}.qualifier`, r) };
49
+ return typeof i.role == "string" ? { ...d, role: i.role } : d;
50
+ });
51
+ n[s] = {
52
+ scope: S(t.scope, `${c}.scope`, r),
53
+ qualifier: O(t.qualifier, `${c}.qualifier`, r),
54
+ clauses: f
55
+ };
56
+ }
57
+ const u = e.unavailable ?? [];
58
+ return (!Array.isArray(u) || !u.every((s) => typeof s == "string")) && r.push("access.unavailable: expected an array of strings"), {
59
+ snapshot: {
60
+ root: e.root === !0,
61
+ permissions: n,
62
+ unavailable: Array.isArray(u) ? u.filter((s) => typeof s == "string") : []
63
+ },
64
+ issues: r
65
+ };
66
+ }
67
+ const F = (e) => typeof e == "object" && e !== null && !Array.isArray(e);
68
+ function P(e, r, n = "navigation") {
69
+ return Array.isArray(e) ? e.flatMap((o, u) => {
70
+ const s = `${n}[${u}]`;
71
+ if (!F(o) || typeof o.i18n != "string")
72
+ return r.push(`${s}: expected an object with an i18n key`), [];
73
+ for (const c of ["icon", "route"])
74
+ o[c] != null && typeof o[c] != "string" && r.push(`${s}.${c}: expected a string`);
75
+ const t = o.children == null ? void 0 : P(o.children, r, `${s}.children`);
76
+ return [
77
+ {
78
+ i18n: o.i18n,
79
+ ...typeof o.icon == "string" && { icon: o.icon },
80
+ ...typeof o.route == "string" && { route: o.route },
81
+ ...t && { children: t }
82
+ }
83
+ ];
84
+ }) : (r.push(`${n}: expected an array`), []);
85
+ }
86
+ const b = (e) => typeof e == "object" && e !== null && !Array.isArray(e), H = (e) => {
87
+ if (b(e) && (typeof e.id == "number" || typeof e.id == "string")) return { id: e.id };
88
+ throw new TypeError("expected an object with a numeric or string id");
89
+ };
90
+ function Q(e, r = H) {
91
+ const n = [];
92
+ if (!b(e)) throw j(["expected an object"]);
93
+ let o = null;
94
+ try {
95
+ o = r(e.user);
96
+ } catch (i) {
97
+ n.push(`user: ${i instanceof Error ? i.message : "invalid"}`);
98
+ }
99
+ let u = null;
100
+ if (e.expires_at !== void 0 && e.expires_at !== null) {
101
+ const i = typeof e.expires_at == "string" ? new Date(e.expires_at) : null;
102
+ i === null || Number.isNaN(i.getTime()) ? n.push("expires_at: expected an ISO date-time string") : u = i;
103
+ }
104
+ let s;
105
+ if (e.impersonator !== void 0 && e.impersonator !== null) {
106
+ const i = e.impersonator;
107
+ b(i) && (typeof i.id == "number" || typeof i.id == "string") && typeof i.name == "string" ? s = { id: i.id, name: i.name } : n.push("impersonator: expected { id, name }");
108
+ }
109
+ const t = B(e.access);
110
+ n.push(...t.issues);
111
+ const c = e.navigation === void 0 || e.navigation === null ? void 0 : P(e.navigation, n), f = b(e.preferences) ? e.preferences : {};
112
+ if (o === null || n.length > 0) throw j(n);
113
+ return { user: o, expiresAt: u, access: t.snapshot, preferences: f, ...s && { impersonator: s }, ...c && { navigation: c } };
114
+ }
115
+ const j = (e) => new z({ kind: "malformed", message: `Unreadable session payload: ${e.join("; ")}` });
116
+ function R(e, r = {}) {
117
+ const { mePath: n = "/auth/me", signOutPath: o = "/auth/logout", parseUser: u } = r;
118
+ return {
119
+ async load(s) {
120
+ try {
121
+ const { data: t } = await e.get(n, { signal: s, handleUnauthorized: !1 });
122
+ return Q(t, u);
123
+ } catch (t) {
124
+ if (A(t) && t.kind === "unauthorized") return null;
125
+ throw t;
126
+ }
127
+ },
128
+ async signOut() {
129
+ try {
130
+ await e.post(o, void 0, { handleUnauthorized: !1 });
131
+ } catch (s) {
132
+ if (!(A(s) && s.kind === "unauthorized")) throw s;
133
+ }
134
+ }
135
+ };
136
+ }
137
+ function k(e) {
138
+ return e.status === "authenticated" ? e : e.status === "anonymous" && e.reason === "expired" ? e.previous ?? null : null;
139
+ }
140
+ const E = 3e3;
141
+ function D(e, r = {}) {
142
+ const n = C({ status: "unknown" });
143
+ let o = 0;
144
+ const u = new Set(r.beforeSignOut ? [r.beforeSignOut] : []);
145
+ let s = !1, t = null, c = null, f = null;
146
+ function i() {
147
+ o++, f?.controller.abort(), f = null;
148
+ }
149
+ async function x(a) {
150
+ const l = new AbortController();
151
+ let g;
152
+ const v = new Promise((h) => {
153
+ g = setTimeout(() => {
154
+ l.abort(), r.onError?.(new Error(`A before-sign-out hook did not finish within ${E} ms; signing out without it.`)), h();
155
+ }, E);
156
+ }), w = Promise.all(
157
+ [...u].map(async (h) => {
158
+ try {
159
+ await h(a, l.signal);
160
+ } catch (p) {
161
+ r.onError?.(p);
162
+ }
163
+ })
164
+ ).then(() => {
165
+ });
166
+ await Promise.race([w, v]), clearTimeout(g);
167
+ }
168
+ function m() {
169
+ if (f) return f.promise;
170
+ const a = o, l = new AbortController(), g = n.value, v = k(g) !== null;
171
+ v || (n.value = { status: "loading" });
172
+ const w = async () => {
173
+ try {
174
+ const p = await e.load(l.signal);
175
+ if (o !== a) return n.value;
176
+ n.value = p ? { status: "authenticated", ...p } : { status: "anonymous", reason: "none" };
177
+ } catch (p) {
178
+ if (o !== a) return n.value;
179
+ r.onError?.(p), n.value = v ? g : { status: "failed", error: p };
180
+ } finally {
181
+ o === a && (f = null);
182
+ }
183
+ return n.value;
184
+ }, h = Promise.resolve().then(w);
185
+ return f = { controller: l, promise: h }, h;
186
+ }
187
+ const d = {
188
+ state: n,
189
+ restore: () => n.value.status === "unknown" || n.value.status === "failed" ? m() : f?.promise ?? Promise.resolve(n.value),
190
+ refresh: m,
191
+ establish(a) {
192
+ i(), n.value = { status: "authenticated", ...a };
193
+ },
194
+ update(a) {
195
+ const l = n.value;
196
+ if (l.status === "authenticated") {
197
+ if (a.user && a.user.id !== l.user.id)
198
+ throw new Error(`session.update cannot change who is signed in (user ${String(l.user.id)} to ${String(a.user.id)}); use session.establish for a different person.`);
199
+ n.value = {
200
+ ...l,
201
+ user: a.user ?? l.user,
202
+ access: a.access ?? l.access,
203
+ ...(a.navigation ?? l.navigation) && { navigation: a.navigation ?? l.navigation },
204
+ ...(a.preferences ?? l.preferences) && { preferences: a.preferences ?? l.preferences }
205
+ };
206
+ }
207
+ },
208
+ expire() {
209
+ if (n.value.status !== "authenticated") return;
210
+ const { status: a, ...l } = n.value;
211
+ i(), n.value = s && !n.value.impersonator ? { status: "anonymous", reason: "expired", previous: l } : { status: "anonymous", reason: "expired" }, r.onExpired?.();
212
+ },
213
+ signOut() {
214
+ return t ?? (t = (async () => {
215
+ try {
216
+ const a = n.value;
217
+ a.status === "authenticated" && u.size > 0 && await x(a.user), i(), n.value = { status: "anonymous", reason: "signedOut" }, await e.signOut();
218
+ } finally {
219
+ t = null;
220
+ }
221
+ })()), t;
222
+ },
223
+ get renewable() {
224
+ return r.renew !== void 0 && (r.renewable?.() ?? !0);
225
+ },
226
+ renew() {
227
+ return n.value.status !== "authenticated" ? Promise.resolve(!1) : (c ?? (c = (async () => {
228
+ try {
229
+ if (d.renewable && await r.renew(d)) return !0;
230
+ } catch {
231
+ }
232
+ return d.expire(), !1;
233
+ })().finally(() => {
234
+ c = null;
235
+ })), c);
236
+ },
237
+ holdExpired(a) {
238
+ s = a;
239
+ },
240
+ onBeforeSignOut(a) {
241
+ return u.add(a), () => void u.delete(a);
242
+ }
243
+ };
244
+ return d;
245
+ }
246
+ function V(e) {
247
+ const r = U({
248
+ baseUrl: e.config.apiBase,
249
+ transport: e.transport,
250
+ headers: e.headers,
251
+ credentials: e.credentials,
252
+ requestId: e.requestId,
253
+ async onUnauthorized() {
254
+ return await u.renew() ? "retry" : "fail";
255
+ }
256
+ }), n = e.session ?? ((t) => R(t)), o = typeof n == "function" ? n(r) : n, u = D(o, {
257
+ onError: e.onSessionError,
258
+ onExpired: e.onSessionExpired,
259
+ beforeSignOut: e.beforeSignOut,
260
+ renew: e.renewSession && ((t) => e.renewSession(t, r)),
261
+ renewable: e.renewable
262
+ }), s = N(
263
+ () => k(u.state.value)?.access ?? null,
264
+ { covers: e.covers }
265
+ );
266
+ return { config: e.config, http: r, session: u, access: s };
267
+ }
268
+ const q = _("platform"), K = q[0], W = q[1];
269
+ function X(e, r) {
270
+ e.provide(K, r);
271
+ }
272
+ export {
273
+ V as a,
274
+ E as b,
275
+ N as c,
276
+ D as d,
277
+ R as e,
278
+ Q as f,
279
+ K as g,
280
+ k as h,
281
+ X as i,
282
+ P as p,
283
+ W as u
284
+ };
@@ -28,6 +28,7 @@ export declare function accessOf(policies: string[], qualifiers?: Record<string,
28
28
  export declare function authResponse(policies?: string[], extra?: SessionExtra): {
29
29
  navigation: Node[];
30
30
  user: unknown;
31
+ preferences?: unknown;
31
32
  impersonator?: (import("../identity").Impersonator | null) | undefined;
32
33
  expires_at: string;
33
34
  access: MyAccess;
@@ -39,6 +40,7 @@ export declare const authBody: (policies?: string[], extra?: SessionExtra) => {
39
40
  data: {
40
41
  navigation: Node[];
41
42
  user: unknown;
43
+ preferences?: unknown;
42
44
  impersonator?: (import("../identity").Impersonator | null) | undefined;
43
45
  expires_at: string;
44
46
  access: MyAccess;
@@ -0,0 +1,91 @@
1
+ import { computed as P } from "vue";
2
+ import { A as S } from "./error-CD7x0Jrz.js";
3
+ import { r as e } from "./route-goWMxDUN.js";
4
+ const w = {
5
+ login: e("POST", "/v1/auth/login", { public: !0 }),
6
+ refresh: e("POST", "/v1/auth/refresh", { public: !0 }),
7
+ logout: e("POST", "/v1/auth/logout"),
8
+ me: e("GET", "/v1/auth/me"),
9
+ changeLocale: e("POST", "/v1/auth/change-locale"),
10
+ loginAs: e("POST", "/v1/auth/login-as"),
11
+ loginAsReturn: e("POST", "/v1/auth/login-as/return"),
12
+ usersList: e("GET", "/v1/iam/users", { permission: "iam.user:view" }),
13
+ usersShow: e("GET", "/v1/iam/users/:id", { permission: "iam.user:view" }),
14
+ usersCreate: e("POST", "/v1/iam/users", { permission: "iam.user:manage" }),
15
+ usersUpdate: e("PUT", "/v1/iam/users/:id", { permission: "iam.user:manage" }),
16
+ usersSetPassword: e("PUT", "/v1/iam/users/:id/password", { permission: "iam.user:manage" }),
17
+ usersDeactivate: e("POST", "/v1/iam/users/:id/deactivate", { permission: "iam.user:manage" }),
18
+ usersActivate: e("POST", "/v1/iam/users/:id/activate", { permission: "iam.user:manage" }),
19
+ usersUnlock: e("POST", "/v1/iam/users/:id/unlock", { permission: "iam.user:manage" }),
20
+ usersSignins: e("GET", "/v1/iam/users/:id/signins", { permission: "iam.user:view" }),
21
+ usersChanges: e("GET", "/v1/iam/users/:id/changes", { permission: "iam.user:view" }),
22
+ usersActivity: e("GET", "/v1/iam/users/:id/activity", { permission: "iam.user.activity:view" }),
23
+ usersSessions: e("GET", "/v1/iam/users/:id/sessions", { permission: "iam.user:view" }),
24
+ usersRevokeSession: e("DELETE", "/v1/iam/users/:id/sessions/:session_id", { permission: "iam.user:manage" }),
25
+ usersRevokeSessions: e("DELETE", "/v1/iam/users/:id/sessions", { permission: "iam.user:manage" }),
26
+ profileShow: e("GET", "/v1/iam/profile"),
27
+ profileUpdate: e("PUT", "/v1/iam/profile"),
28
+ profileChangePassword: e("PUT", "/v1/iam/profile/password"),
29
+ profileRequestEmail: e("POST", "/v1/iam/profile/email"),
30
+ profileResendEmail: e("POST", "/v1/iam/profile/email/resend"),
31
+ profileConfirmEmail: e("POST", "/v1/iam/profile/email/confirm"),
32
+ profileCancelEmail: e("DELETE", "/v1/iam/profile/email"),
33
+ profileSignins: e("GET", "/v1/iam/profile/signins"),
34
+ profileSessions: e("GET", "/v1/iam/profile/sessions"),
35
+ profileRevokeSession: e("DELETE", "/v1/iam/profile/sessions/:session_id"),
36
+ preferencesUpdate: e("PUT", "/v1/auth/preferences")
37
+ }, f = (s) => typeof s == "object" && s !== null && !Array.isArray(s);
38
+ function E(s, a) {
39
+ if (!f(a)) return a;
40
+ const o = f(s) ? { ...s } : {};
41
+ for (const [n, t] of Object.entries(a))
42
+ n !== "__proto__" && (t === null ? delete o[n] : t !== void 0 && (o[n] = E(o[n], t)));
43
+ return o;
44
+ }
45
+ const T = /* @__PURE__ */ new WeakMap();
46
+ function k(s) {
47
+ let a = T.get(s);
48
+ return a || (a = O(s), T.set(s, a)), a;
49
+ }
50
+ function O({ session: s, http: a }) {
51
+ const o = () => {
52
+ const r = s.state.value;
53
+ return r.status === "authenticated" ? { ...r.preferences } : {};
54
+ }, n = () => {
55
+ const r = s.state.value;
56
+ return r.status === "authenticated" ? r.user.id : null;
57
+ };
58
+ let t = {}, m = null;
59
+ const u = [];
60
+ let v = Promise.resolve();
61
+ const c = () => s.update({ preferences: u.reduce((r, { patch: i }) => E(r, i), t) }), d = (r) => {
62
+ const i = u.indexOf(r);
63
+ i >= 0 && u.splice(i, 1);
64
+ };
65
+ return {
66
+ value: P(() => o()),
67
+ save(r) {
68
+ const i = n();
69
+ if (i === null) return Promise.resolve();
70
+ (u.length === 0 || m !== i) && (t = o(), m = i, u.length = 0);
71
+ const p = { patch: r };
72
+ u.push(p), c();
73
+ const h = async () => {
74
+ try {
75
+ const { data: l } = await a.request(w.preferencesUpdate, { preferences: r });
76
+ if (!f(l?.preferences)) throw new S({ kind: "malformed", message: "Unreadable preferences answer: expected { preferences: {} }" });
77
+ m === i && (t = l.preferences), d(p), m === i && n() === i && c();
78
+ } catch (l) {
79
+ throw d(p), m === i && n() === i && c(), l;
80
+ }
81
+ }, g = v.then(h);
82
+ return v = g.catch(() => {
83
+ }), g;
84
+ }
85
+ };
86
+ }
87
+ export {
88
+ w as i,
89
+ E as m,
90
+ k as p
91
+ };
@@ -1,5 +1,6 @@
1
1
  export { positiveInteger, useResource } from "./resource";
2
2
  export type { Resource, ResourceContext, ResourceId, ResourceOptions, ResourceState } from "./resource";
3
+ export { found, readRecord, readRecordWithMeta } from "./read";
3
4
  export { useRouteResource, useRouteResourceContext } from "./routeResource";
4
5
  export type { RouteResource, RouteResourceOptions } from "./routeResource";
5
6
  export type { RecordListContext, RecordNeighbors } from "./listContext";
@@ -1,10 +1,26 @@
1
- import { p as o, u as r, a, b as u } from "../routeResource-DlTsGTg_.js";
2
- import { _ as R, a as c } from "../ResourcePage.vue_vue_type_script_setup_true_lang-DljhsTU4.js";
1
+ import { p as g, u as m, a as l, b as R } from "../routeResource-DlTsGTg_.js";
2
+ import { c as a } from "../current-B0lHKTWr.js";
3
+ import { A as n } from "../error-CD7x0Jrz.js";
4
+ import { _ as w, a as x } from "../ResourcePage.vue_vue_type_script_setup_true_lang-Coz91xht.js";
5
+ async function i(t, e) {
6
+ return (await a().platform.http.get(t, { signal: e.signal })).data;
7
+ }
8
+ async function c(t, e) {
9
+ const { data: o, meta: r } = await a().platform.http.get(t, { signal: e.signal });
10
+ return { data: o, meta: r };
11
+ }
12
+ function p(t) {
13
+ if (t === null) throw new n({ kind: "notFound", message: "Not found", status: 404 });
14
+ return t;
15
+ }
3
16
  export {
4
- R as RecordPager,
5
- c as ResourcePage,
6
- o as positiveInteger,
7
- r as useResource,
8
- a as useRouteResource,
9
- u as useRouteResourceContext
17
+ w as RecordPager,
18
+ x as ResourcePage,
19
+ p as found,
20
+ g as positiveInteger,
21
+ i as readRecord,
22
+ c as readRecordWithMeta,
23
+ m as useResource,
24
+ l as useRouteResource,
25
+ R as useRouteResourceContext
10
26
  };
@@ -0,0 +1,16 @@
1
+ import type { ResourceContext } from "./resource";
2
+ /**
3
+ * The `load` of a record page on `useRouteResource` / `useResource`: one GET through the current application's client, which answers
4
+ * with `ApiError` (so a 404 reads as "not found" and a page that was left aborts its read). The client is read on each call, so a feature's
5
+ * api declares its reads at module level, before the application exists.
6
+ *
7
+ * const dealerRecord = (id: number, context: ResourceContext) => readRecord<DealerRecord>(`/v1/dealers/${id}`, context);
8
+ */
9
+ export declare function readRecord<T>(path: string, context: Pick<ResourceContext, "signal">): Promise<T>;
10
+ /** `readRecord` for an answer that carries `meta` beside the record (the authors, the comments); `meta` is the caller's word, not checked. */
11
+ export declare function readRecordWithMeta<T, M>(path: string, context: Pick<ResourceContext, "signal">): Promise<{
12
+ data: T;
13
+ meta: M | null;
14
+ }>;
15
+ /** The record a read found: the server answers `null` only where there is none, which a page reads as "not found" (404), never as a record. */
16
+ export declare function found<T>(record: T | null): T;
@@ -1,9 +1,9 @@
1
1
  import { _ as a, c as o, a as r, i as t } from "../NoAccess.vue_vue_type_script_setup_true_lang-BHzZtZ50.js";
2
2
  import { d as c } from "../defineRoutes-BGAdiIrt.js";
3
3
  import { A as u, f as p, i as f, r as A, u as m } from "../access-DmAceEo5.js";
4
- import { i as l, r as x } from "../guards-Biv_SlGn.js";
5
- import { u as y } from "../sections-CvUwZ-S1.js";
6
- import { b as v, c as N, n as H, u as b } from "../navigation-TnVFYRaX.js";
4
+ import { i as l, r as x } from "../guards-DGcSfTEh.js";
5
+ import { u as y } from "../sections-fkW_IJLc.js";
6
+ import { b as v, c as N, n as H, u as b } from "../navigation-CctcxT51.js";
7
7
  export {
8
8
  u as AppRouterView,
9
9
  a as NoAccess,
@@ -6,9 +6,9 @@ import { _ as J } from "./Icon.vue_vue_type_script_lang-BhhsFYwp.js";
6
6
  import { _ as Ne } from "./Menu.vue_vue_type_script_setup_true_lang-wKc9gdCn.js";
7
7
  import { _ as ze } from "./Tooltip.vue_vue_type_script_setup_true_lang-Dtg5Y6pf.js";
8
8
  import { _ as he } from "./EmptyState.vue_vue_type_script_setup_true_lang-DbZiO2RF.js";
9
- import { u as Fe } from "./format-D8KUBmbS.js";
9
+ import { u as Fe } from "./format-DoKs29bZ.js";
10
10
  import { _ as Ve } from "./Badge.vue_vue_type_script_setup_true_lang-DJyZc0C7.js";
11
- import { _ as Oe } from "./Timestamp.vue_vue_type_script_setup_true_lang-ClZAAUMd.js";
11
+ import { _ as Oe } from "./Timestamp.vue_vue_type_script_setup_true_lang-DlEUKWra.js";
12
12
  import { _ as me } from "./Highlight.vue_vue_type_script_setup_true_lang-DZGBmwcX.js";
13
13
  import { a as je } from "./mediaQuery-CygcXmFW.js";
14
14
  const Ue = ["data-row-click-ignore"], be = "col-start-1 row-start-1", Ye = "col-span-full row-start-2 max-w-full", ke = /* @__PURE__ */ oe({
@@ -1,7 +1,7 @@
1
1
  import { computed as n, watch as h } from "vue";
2
2
  import { useI18n as b } from "vue-i18n";
3
3
  import { useRoute as g, useRouter as p } from "vue-router";
4
- import { u as y } from "./platform-BQOX_Ntw.js";
4
+ import { u as y } from "./platform-DtISOEt7.js";
5
5
  import { i as w } from "./access-DmAceEo5.js";
6
6
  function j() {
7
7
  const t = g(), u = p(), { access: c } = y(), { t: r } = b(), i = n(() => {
@@ -1,6 +1,6 @@
1
1
  import { useI18n as f } from "vue-i18n";
2
2
  import { a as c } from "./error-CD7x0Jrz.js";
3
- import { u as m } from "./format-D8KUBmbS.js";
3
+ import { u as m } from "./format-DoKs29bZ.js";
4
4
  import { u as l } from "./describeError-B-NMa--w.js";
5
5
  function E() {
6
6
  const { t: i, te: u } = f(), a = m(), d = l(), s = (e) => [`errors.${e}`, `core.errors.${e}`].find((t) => u(t));
@@ -1,9 +1,9 @@
1
1
  import { type Feature } from "../app/feature";
2
2
  export interface DarkModeOptions {
3
- /** Whether this person wants dark mode now: read in a reactive context (their session user's preference, a store). */
4
- dark: () => boolean;
5
- /** Stores the choice. It handles its own failure (a toast): the switch only flips what `dark()` says next. */
6
- set: (dark: boolean) => void | Promise<void>;
3
+ /** Whether this person wants dark mode now: read in a reactive context. Default: `dark_mode` of their stored preferences. */
4
+ dark?: () => boolean;
5
+ /** Stores the choice. It handles its own failure (a toast): the switch only flips what `dark()` says next. Default: saves `dark_mode` in their stored preferences. */
6
+ set?: (dark: boolean) => void | Promise<void>;
7
7
  /** The colour of an installed app's status bar, which follows the mode. Default white and `#18181B`. */
8
8
  themeColor?: {
9
9
  light: string;
@@ -17,10 +17,15 @@ export declare function applyDarkMode(dark: boolean, themeColor?: {
17
17
  }): void;
18
18
  /**
19
19
  * The person's dark-mode preference, as an opt-in feature: a switch in the account menu and the mode on the page.
20
- * Where the preference lives is the app's (usually a field of the session user, saved on the server):
20
+ * The preference is `dark_mode` of the preferences go-core's identity module keeps for the person (`usePreferences`): the
21
+ * switch shows at once and is saved with `PUT /v1/auth/preferences`; a refusal is a toast and the mode goes back.
21
22
  *
22
- * darkMode({ dark: () => session.user.value?.preferences.dark_mode ?? false, set: (dark) => savePreferences({ dark_mode: dark }) })
23
+ * darkMode()
23
24
  *
24
- * The page follows `dark()` from the moment the application mounts, signed in or not.
25
+ * A preference kept elsewhere (a store, a cookie) is `dark` and `set`:
26
+ *
27
+ * darkMode({ dark: () => store.dark, set: (dark) => store.save(dark) })
28
+ *
29
+ * The page follows `dark()` from the moment the application mounts, signed in or not (light while nobody is).
25
30
  */
26
- export declare function darkMode(options: DarkModeOptions): Feature;
31
+ export declare function darkMode(options?: DarkModeOptions): Feature;