@wssto2/vue-core 0.12.0 → 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.
- package/CHANGELOG.md +33 -0
- package/README.md +4 -2
- package/dist/{AccessGate.vue_vue_type_script_setup_true_lang-CzQbD2Pc.js → AccessGate.vue_vue_type_script_setup_true_lang-DEzXovsY.js} +1 -1
- package/dist/{Activity-CdkJW68R.js → Activity-ChfxdvXf.js} +24 -23
- package/dist/{AdaptivePageShell.vue_vue_type_script_setup_true_lang-D5i77H6S.js → AdaptivePageShell.vue_vue_type_script_setup_true_lang-lPj9hPqV.js} +33 -33
- package/dist/{Changes-DxK_QfiB.js → Changes-BCa43_mO.js} +18 -17
- package/dist/{CollectionPage.vue_vue_type_script_setup_true_lang-x0jyJ01f.js → CollectionPage.vue_vue_type_script_setup_true_lang-C1GCvyZx.js} +6 -6
- 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
- package/dist/{DateField.vue_vue_type_script_setup_true_lang-CeNwBbJT.js → DateField.vue_vue_type_script_setup_true_lang-B5UUY1OO.js} +2 -2
- package/dist/{DeadLetters-DnA7LP1w.js → DeadLetters-wFTqhISU.js} +5 -5
- package/dist/{General-2matxl2Y.js → General-jW7u4MjH.js} +16 -15
- package/dist/{IncidentRecord-Bt3G4HlX.js → IncidentRecord-CXzgLKqI.js} +6 -6
- package/dist/{IncidentsList-2iwgqp9J.js → IncidentsList-D1MySyXb.js} +6 -6
- package/dist/{NewRolePage-DhGFwvk3.js → NewRolePage-CQ5UVaHs.js} +3 -3
- package/dist/{NumberField.vue_vue_type_script_setup_true_lang-B3UrXNqH.js → NumberField.vue_vue_type_script_setup_true_lang-YVgf5CP6.js} +1 -1
- 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
- package/dist/{ProfilePage-CpuyDBAv.js → ProfilePage-Ca3x3UAH.js} +79 -77
- 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
- package/dist/{ResourcePage.vue_vue_type_script_setup_true_lang-DljhsTU4.js → ResourcePage.vue_vue_type_script_setup_true_lang-Coz91xht.js} +1 -1
- 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
- package/dist/{RolePage-DaNv049g.js → RolePage-BUj1w1m1.js} +5 -5
- package/dist/{RolesPage-6hlzJes_.js → RolesPage-NKzBUsrM.js} +3 -3
- package/dist/{SectionNavigator.vue_vue_type_script_setup_true_lang-Dh3sXUt_.js → SectionNavigator.vue_vue_type_script_setup_true_lang-DfKEhTFv.js} +2 -2
- package/dist/{ServiceAccountDialog.vue_vue_type_script_setup_true_lang-FJbWxME_.js → ServiceAccountDialog.vue_vue_type_script_setup_true_lang-4nbhEpv_.js} +10 -9
- package/dist/{ServiceAccountRecord-0-JF5lRx.js → ServiceAccountRecord-ClbyeLhL.js} +8 -8
- package/dist/{ServiceAccountsList-DcsnOcf-.js → ServiceAccountsList-B2VDnYxD.js} +5 -5
- package/dist/{Sessions-DgWhpk-i.js → Sessions-BjkciyHH.js} +23 -21
- package/dist/{SettingsPage-BXPWATYU.js → SettingsPage-Csb14qsx.js} +7 -7
- package/dist/{SignIn-DPoUwHZd.js → SignIn-DPFMv4C7.js} +14 -12
- package/dist/{SignInPage-OyrVemro.js → SignInPage-DukoFqkt.js} +2 -2
- package/dist/{SignIns-BMDrZVVp.js → SignIns-DvdpNkiS.js} +23 -22
- 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
- package/dist/{Timestamp.vue_vue_type_script_setup_true_lang-ClZAAUMd.js → Timestamp.vue_vue_type_script_setup_true_lang-DlEUKWra.js} +1 -1
- package/dist/{UserRecord-BW-gdCqi.js → UserRecord-B9SeSWQh.js} +57 -55
- package/dist/{UsersList-B3ZF_1Dj.js → UsersList-CREG8q3l.js} +4 -4
- package/dist/access/index.js +4 -4
- package/dist/app/application.d.ts +14 -6
- package/dist/app/current.d.ts +11 -0
- package/dist/app/environment.d.ts +8 -0
- package/dist/app/index.d.ts +1 -0
- package/dist/app/index.js +14 -12
- package/dist/application-DomS6sbx.js +435 -0
- package/dist/collection/http.d.ts +16 -1
- package/dist/collection/index.d.ts +1 -1
- package/dist/collection/index.js +34 -32
- package/dist/content/Money.vue.d.ts +1 -1
- package/dist/content/index.js +151 -158
- package/dist/{contributions-CeG4bszd.js → contributions-obnyn03x.js} +1 -1
- package/dist/current-B0lHKTWr.js +17 -0
- package/dist/form/DateField.vue.d.ts +2 -2
- package/dist/form/DateTimeField.vue.d.ts +2 -2
- package/dist/form/MoneyField.vue.d.ts +1 -1
- package/dist/form/NumberField.vue.d.ts +1 -1
- package/dist/form/date/MonthYearPanel.vue.d.ts +1 -1
- package/dist/form/date/days.d.ts +3 -3
- package/dist/form/index.d.ts +2 -0
- package/dist/form/index.js +1111 -1081
- package/dist/form/zodErrorMap.d.ts +35 -0
- package/dist/format/format.d.ts +51 -6
- package/dist/format/index.d.ts +1 -1
- package/dist/format/index.js +1 -1
- package/dist/format-DoKs29bZ.js +118 -0
- package/dist/{guards-Biv_SlGn.js → guards-DGcSfTEh.js} +1 -1
- package/dist/http-DOEfFCDA.js +107 -0
- package/dist/i18n/index.js +15 -15
- package/dist/identity/index.d.ts +2 -0
- package/dist/identity/index.js +43 -40
- package/dist/identity/usePreferences.d.ts +19 -0
- package/dist/incidents/clientErrorReporter.d.ts +2 -1
- package/dist/incidents/index.js +1 -1
- package/dist/{index-kEHY7hcG.js → index-CRxU_Wh2.js} +61 -61
- package/dist/{index-Cq9TuOqH.js → index-DZikGJ8L.js} +457 -511
- package/dist/{index-ClJeyW3F.js → index-D_yyd4C2.js} +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/intlLocale.d.ts +5 -2
- package/dist/modules/identity/entities.d.ts +7 -2
- package/dist/modules/identity/routes.d.ts +5 -2
- package/dist/modules/identity/schemas.d.ts +6 -2
- package/dist/{navigation-TnVFYRaX.js → navigation-CctcxT51.js} +1 -1
- package/dist/{neighbors-OyvGi233.js → neighbors-Csfan8Ho.js} +1 -1
- package/dist/notifications/index.js +1 -1
- package/dist/onboarding/Tip.vue.d.ts +41 -0
- package/dist/onboarding/index.d.ts +1 -0
- package/dist/onboarding/index.js +145 -0
- package/dist/onboarding/tips.d.ts +5 -0
- package/dist/page/index.js +3 -3
- package/dist/phone/index.js +74 -74
- package/dist/phone/phone.d.ts +3 -3
- package/dist/platform/httpSession.d.ts +1 -1
- package/dist/platform/index.d.ts +2 -0
- package/dist/platform/index.js +16 -13
- package/dist/platform/preferences.d.ts +35 -0
- package/dist/platform/session.d.ts +6 -1
- package/dist/platform-DtISOEt7.js +284 -0
- package/dist/playwright/session.d.ts +7 -11
- package/dist/preferences-hYhrw8Uy.js +91 -0
- package/dist/resource/index.d.ts +1 -0
- package/dist/resource/index.js +24 -8
- package/dist/resource/read.d.ts +16 -0
- package/dist/router/index.js +3 -3
- package/dist/{rowLayout-BsKEzEME.js → rowLayout-y1IB_h2r.js} +2 -2
- package/dist/{sections-CvUwZ-S1.js → sections-fkW_IJLc.js} +1 -1
- package/dist/{serverMessages-B6GHgi40.js → serverMessages-Ddghrewh.js} +1 -1
- package/dist/shell/darkMode.d.ts +13 -8
- package/dist/shell/index.js +396 -384
- package/dist/{state-6KSYsVw0.js → state-CXMexi0l.js} +1 -1
- package/dist/styles.css +1 -1
- package/dist/testing/app.d.ts +11 -0
- package/dist/testing/format.d.ts +4 -2
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +96 -89
- package/dist/testing/platform.d.ts +2 -0
- package/dist/usePreferences-B8LIZp_f.js +47 -0
- package/dist/{useTypedEntry-C_Bk4sI0.js → useTypedEntry-DKs8I1yP.js} +279 -280
- package/package.json +6 -2
- package/src/styles/components.css +17 -0
- package/dist/application-CuzT-0vW.js +0 -420
- package/dist/format-D8KUBmbS.js +0 -87
- package/dist/http-Dm0uXY9O.js +0 -95
- package/dist/intlLocale-CeRU44qJ.js +0 -4
- 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
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Page } from "@playwright/test";
|
|
2
2
|
import type { AccessQualifier } from "../platform";
|
|
3
|
-
import type { MyAccess, Node,
|
|
3
|
+
import type { MyAccess, Node, SessionResponse, User } from "../modules/identity/entities";
|
|
4
4
|
/** The signed-in person a spec starts with: only what go-core's identity returns. An app adds its own fields through `mockAuth`'s `user`. */
|
|
5
5
|
export declare const defaultUser: User;
|
|
6
6
|
export type MockAuthOptions = {
|
|
@@ -18,24 +18,20 @@ export type HeldAt = {
|
|
|
18
18
|
level: string;
|
|
19
19
|
id?: number;
|
|
20
20
|
};
|
|
21
|
-
type WireAccess = Omit<MyAccess, "permissions"> & {
|
|
22
|
-
permissions: Record<string, Omit<PermissionAccess, "qualifier"> & {
|
|
23
|
-
qualifier: AccessQualifier;
|
|
24
|
-
}>;
|
|
25
|
-
};
|
|
26
21
|
/** Fields of the session payload to set or replace (an `impersonator`, another `expires_at`), and any the application adds. */
|
|
27
22
|
export type SessionExtra = Partial<Omit<SessionResponse, "access">> & {
|
|
28
|
-
access?:
|
|
23
|
+
access?: MyAccess;
|
|
29
24
|
} & Record<string, unknown>;
|
|
30
25
|
/** The `/auth/me` `access` payload for the given permissions, every one at `scope` with its qualifier. The organization has no id: it is go-core's root scope, and `root` says a binding is there. */
|
|
31
|
-
export declare function accessOf(policies: string[], qualifiers?: Record<string, AccessQualifier>, scope?: HeldAt):
|
|
26
|
+
export declare function accessOf(policies: string[], qualifiers?: Record<string, AccessQualifier>, scope?: HeldAt): MyAccess;
|
|
32
27
|
/** The session payload of go-core's identity (`/auth/me`, `/auth/refresh`, `/auth/login-as`), without its envelope. */
|
|
33
28
|
export declare function authResponse(policies?: string[], extra?: SessionExtra): {
|
|
34
29
|
navigation: Node[];
|
|
35
30
|
user: unknown;
|
|
31
|
+
preferences?: unknown;
|
|
36
32
|
impersonator?: (import("../identity").Impersonator | null) | undefined;
|
|
37
33
|
expires_at: string;
|
|
38
|
-
access:
|
|
34
|
+
access: MyAccess;
|
|
39
35
|
};
|
|
40
36
|
/** The same, as the server sends it: inside go-core's `{ success, data }` envelope. */
|
|
41
37
|
export declare const authBody: (policies?: string[], extra?: SessionExtra) => {
|
|
@@ -44,11 +40,11 @@ export declare const authBody: (policies?: string[], extra?: SessionExtra) => {
|
|
|
44
40
|
data: {
|
|
45
41
|
navigation: Node[];
|
|
46
42
|
user: unknown;
|
|
43
|
+
preferences?: unknown;
|
|
47
44
|
impersonator?: (import("../identity").Impersonator | null) | undefined;
|
|
48
45
|
expires_at: string;
|
|
49
|
-
access:
|
|
46
|
+
access: MyAccess;
|
|
50
47
|
};
|
|
51
48
|
};
|
|
52
49
|
/** Signs the page in: answers go-core identity's `GET /api/v1/auth/me` with a session that holds `policies`. */
|
|
53
50
|
export declare function mockAuth(page: Page, policies?: string[], options?: MockAuthOptions): Promise<void>;
|
|
54
|
-
export {};
|
|
@@ -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
|
+
};
|
package/dist/resource/index.d.ts
CHANGED
|
@@ -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";
|
package/dist/resource/index.js
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
import { p as
|
|
2
|
-
import {
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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;
|
package/dist/router/index.js
CHANGED
|
@@ -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-
|
|
5
|
-
import { u as y } from "../sections-
|
|
6
|
-
import { b as v, c as N, n as H, u as b } from "../navigation-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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));
|
package/dist/shell/darkMode.d.ts
CHANGED
|
@@ -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
|
|
4
|
-
dark
|
|
5
|
-
/** Stores the choice. It handles its own failure (a toast): the switch only flips what `dark()` says next. */
|
|
6
|
-
set
|
|
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
|
-
*
|
|
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(
|
|
23
|
+
* darkMode()
|
|
23
24
|
*
|
|
24
|
-
*
|
|
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
|
|
31
|
+
export declare function darkMode(options?: DarkModeOptions): Feature;
|