run402 2.13.0 → 2.15.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/cli.mjs CHANGED
@@ -240,6 +240,16 @@ switch (cmd) {
240
240
  await run(sub, rest);
241
241
  break;
242
242
  }
243
+ case "notifications": {
244
+ const { run } = await import("./lib/notifications.mjs");
245
+ await run(sub, rest);
246
+ break;
247
+ }
248
+ case "webhook-secret": {
249
+ const { runWebhookSecret } = await import("./lib/notifications.mjs");
250
+ await runWebhookSecret(sub, rest);
251
+ break;
252
+ }
243
253
  case "logs": {
244
254
  const { run } = await import("./lib/logs.mjs");
245
255
  await run(sub, rest);
package/lib/doctor.mjs CHANGED
@@ -165,7 +165,51 @@ export async function run(sub, args = []) {
165
165
  });
166
166
  }
167
167
 
168
- const allOk = checks.every((c) => c.status === "ok");
168
+ // 6. Operator health snapshot (v1.55).
169
+ try {
170
+ const sdk = getSdk();
171
+ const status = await sdk.admin.getOperatorStatus();
172
+ const gaps = [];
173
+ if (status.operator_contact.email_status !== "verified") {
174
+ gaps.push(`operator email not verified (${status.operator_contact.email_status}) — run 'run402 agent contact --email ...' then reply to the challenge`);
175
+ }
176
+ if (status.operator_contact.passkey_status !== "verified") {
177
+ gaps.push("operator passkey not bound — run 'run402 agent passkey enroll' after email verification");
178
+ }
179
+ if (Array.isArray(status.skipped_notifications) && status.skipped_notifications.length > 0) {
180
+ gaps.push(`${status.skipped_notifications.length} notification(s) skipped due to missing verified recipient`);
181
+ }
182
+ if (Array.isArray(status.critical_items) && status.critical_items.length > 0) {
183
+ for (const item of status.critical_items) {
184
+ gaps.push(`${item.kind}: ${item.detail}`);
185
+ }
186
+ }
187
+ if (gaps.length > 0) {
188
+ checks.push({
189
+ name: "operator_health",
190
+ status: "warning",
191
+ value: { gaps },
192
+ hint: "Address the above gaps; they're what 'run402 notifications' is designed to surface.",
193
+ });
194
+ } else {
195
+ checks.push({ name: "operator_health", status: "ok" });
196
+ }
197
+ } catch (err) {
198
+ // Operator status endpoint may not be reachable if the operator-binding
199
+ // substrate isn't deployed yet on the target API. Don't fail the whole
200
+ // doctor over it — emit as a soft warning.
201
+ checks.push({
202
+ name: "operator_health",
203
+ status: "skipped",
204
+ message: err instanceof Error ? err.message : String(err),
205
+ ...(verbose && { hint: "GET /agent/v1/operator/status not reachable; requires v1.55+ gateway." }),
206
+ });
207
+ }
208
+
209
+ // 'warning' counts as ok for exit-code purposes — gaps are surfaced in
210
+ // output but don't fail the doctor. Only hard 'error' / 'missing' /
211
+ // 'empty' fail.
212
+ const allOk = checks.every((c) => c.status === "ok" || c.status === "warning" || c.status === "skipped");
169
213
 
170
214
  if (json) {
171
215
  console.log(JSON.stringify({ ok: allOk, checks }, null, 2));
@@ -175,12 +219,17 @@ export async function run(sub, args = []) {
175
219
  for (const c of checks) {
176
220
  const icon =
177
221
  c.status === "ok" ? "✓"
222
+ : c.status === "warning" ? "⚠"
223
+ : c.status === "skipped" ? "·"
178
224
  : c.status === "missing" || c.status === "empty" ? "⚠"
179
225
  : "✗";
180
226
  const status = c.status === "ok" ? "ok" : c.status;
181
227
  console.log(` ${icon} ${c.name.padEnd(16)} ${status}`);
182
228
  if (c.hint) console.log(` → ${c.hint}`);
183
229
  if (c.message) console.log(` ${c.message}`);
230
+ if (c.value && c.value.gaps && Array.isArray(c.value.gaps)) {
231
+ for (const gap of c.value.gaps) console.log(` • ${gap}`);
232
+ }
184
233
  }
185
234
  }
186
235
 
@@ -0,0 +1,174 @@
1
+ /**
2
+ * run402 notifications — Operator health notifications.
3
+ *
4
+ * Wraps the v1.55 `add-operator-health-notifications` API surface:
5
+ *
6
+ * - run402 notifications list [--type ...] [--since ...] [--limit N] [--offset N]
7
+ * - run402 notifications get <id>
8
+ * - run402 notifications preferences [get|set ...]
9
+ * - run402 notifications test
10
+ * - run402 webhook-secret rotate
11
+ *
12
+ * All commands use the allowance-wallet auth path (SIWX). The assurance
13
+ * ladder is enforced server-side; CLI surfaces 403 errors with the
14
+ * required-assurance hint.
15
+ */
16
+
17
+ import { allowanceAuthHeaders } from "./config.mjs";
18
+ import { getSdk } from "./sdk.mjs";
19
+ import { reportSdkError, fail } from "./sdk-errors.mjs";
20
+ import { assertKnownFlags, flagValue, normalizeArgv, positionalArgs } from "./argparse.mjs";
21
+
22
+ const HELP = `run402 notifications — Operator health notifications
23
+
24
+ Usage:
25
+ run402 notifications list [--type <event_type>] [--since <iso>] [--limit N] [--offset N]
26
+ run402 notifications get <id>
27
+ run402 notifications preferences
28
+ run402 notifications preferences set <key>=<value> [<key>=<value> ...]
29
+ run402 notifications test
30
+
31
+ Examples:
32
+ run402 notifications list --limit 10
33
+ run402 notifications list --type project_past_due --since 2026-05-01T00:00:00Z
34
+ run402 notifications get 9b21fa0a-...
35
+ run402 notifications preferences
36
+ run402 notifications preferences set digest_cadence=weekly digest_day_of_week=1
37
+ run402 notifications preferences set webhook_url=https://my-receiver.example.com/hook
38
+ run402 notifications test
39
+
40
+ Auth ladder (enforced server-side):
41
+ - SIWX wallet: read own notifications + preferences
42
+ - email_verified: cross-wallet rollup reads + multi-wallet preference updates
43
+ - operator_passkey: webhook URL changes, webhook secret rotation
44
+ `;
45
+
46
+ async function list(args) {
47
+ const parsedArgs = normalizeArgv(args);
48
+ const valueFlags = ["--type", "--since", "--limit", "--offset"];
49
+ assertKnownFlags(parsedArgs, [...valueFlags, "--help", "-h"], valueFlags);
50
+ const extra = positionalArgs(parsedArgs, valueFlags);
51
+ if (extra.length > 0) {
52
+ fail({ code: "BAD_USAGE", message: `Unexpected argument for notifications list: ${extra[0]}` });
53
+ }
54
+ allowanceAuthHeaders("/agent/v1/notifications");
55
+ const opts = {};
56
+ const type = flagValue(parsedArgs, "--type");
57
+ const since = flagValue(parsedArgs, "--since");
58
+ const limit = flagValue(parsedArgs, "--limit");
59
+ const offset = flagValue(parsedArgs, "--offset");
60
+ if (type) opts.type = type;
61
+ if (since) opts.since = since;
62
+ if (limit != null) opts.limit = Number(limit);
63
+ if (offset != null) opts.offset = Number(offset);
64
+ try {
65
+ const data = await getSdk().admin.listNotifications(opts);
66
+ console.log(JSON.stringify(data, null, 2));
67
+ } catch (err) {
68
+ reportSdkError(err);
69
+ }
70
+ }
71
+
72
+ async function get(args) {
73
+ const parsedArgs = normalizeArgv(args);
74
+ assertKnownFlags(parsedArgs, ["--help", "-h"]);
75
+ const positionals = positionalArgs(parsedArgs);
76
+ if (positionals.length !== 1) {
77
+ fail({ code: "BAD_USAGE", message: "Usage: run402 notifications get <id>" });
78
+ }
79
+ allowanceAuthHeaders("/agent/v1/notifications");
80
+ try {
81
+ const data = await getSdk().admin.getNotification(positionals[0]);
82
+ console.log(JSON.stringify(data, null, 2));
83
+ } catch (err) {
84
+ reportSdkError(err);
85
+ }
86
+ }
87
+
88
+ async function preferences(args) {
89
+ const parsedArgs = normalizeArgv(args);
90
+ assertKnownFlags(parsedArgs, ["--help", "-h"]);
91
+ const positionals = positionalArgs(parsedArgs);
92
+ allowanceAuthHeaders("/agent/v1/notifications/preferences");
93
+
94
+ if (positionals.length === 0) {
95
+ // GET preferences
96
+ try {
97
+ const data = await getSdk().admin.getNotificationPreferences();
98
+ console.log(JSON.stringify(data, null, 2));
99
+ } catch (err) {
100
+ reportSdkError(err);
101
+ }
102
+ return;
103
+ }
104
+
105
+ if (positionals[0] !== "set") {
106
+ fail({ code: "BAD_USAGE", message: "Usage: run402 notifications preferences [set <key>=<value> ...]" });
107
+ }
108
+
109
+ // SET — parse remaining positional args as key=value
110
+ const patch = {};
111
+ for (const kv of positionals.slice(1)) {
112
+ const eq = kv.indexOf("=");
113
+ if (eq <= 0) {
114
+ fail({ code: "BAD_USAGE", message: `Expected key=value, got: ${kv}` });
115
+ }
116
+ const key = kv.slice(0, eq);
117
+ const rawValue = kv.slice(eq + 1);
118
+ if (key === "digest_day_of_week" || key === "digest_hour_utc") {
119
+ patch[key] = Number(rawValue);
120
+ } else if (key === "webhook_url" && (rawValue === "null" || rawValue === "")) {
121
+ patch[key] = null;
122
+ } else {
123
+ patch[key] = rawValue;
124
+ }
125
+ }
126
+ try {
127
+ const data = await getSdk().admin.setNotificationPreferences(patch);
128
+ console.log(JSON.stringify(data, null, 2));
129
+ } catch (err) {
130
+ reportSdkError(err);
131
+ }
132
+ }
133
+
134
+ async function test(args) {
135
+ const parsedArgs = normalizeArgv(args);
136
+ assertKnownFlags(parsedArgs, ["--help", "-h"]);
137
+ const extra = positionalArgs(parsedArgs);
138
+ if (extra.length > 0) {
139
+ fail({ code: "BAD_USAGE", message: `Unexpected argument for notifications test: ${extra[0]}` });
140
+ }
141
+ allowanceAuthHeaders("/agent/v1/notifications/test");
142
+ try {
143
+ const data = await getSdk().admin.testNotification();
144
+ console.log(JSON.stringify(data, null, 2));
145
+ } catch (err) {
146
+ reportSdkError(err);
147
+ }
148
+ }
149
+
150
+ export async function run(sub, args) {
151
+ if (!sub || sub === "--help" || sub === "-h") {
152
+ console.log(HELP);
153
+ process.exit(0);
154
+ }
155
+ switch (sub) {
156
+ case "list":
157
+ await list(args);
158
+ return;
159
+ case "get":
160
+ await get(args);
161
+ return;
162
+ case "preferences":
163
+ await preferences(args);
164
+ return;
165
+ case "test":
166
+ await test(args);
167
+ return;
168
+ default:
169
+ fail({ code: "BAD_USAGE", message: `Unknown notifications subcommand: ${sub}\n\n${HELP}` });
170
+ }
171
+ }
172
+
173
+ // `run402 webhook-secret rotate` lives in cli/lib/webhook-secret.mjs as
174
+ // its own top-level command, separate from this notifications module.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * run402 webhook-secret — Manage the operator webhook signing secret.
3
+ *
4
+ * Split out from notifications.mjs so the SURFACE inventory parser sees
5
+ * `webhook-secret:rotate` as its own command, separate from the
6
+ * `notifications:*` group.
7
+ */
8
+
9
+ import { allowanceAuthHeaders } from "./config.mjs";
10
+ import { getSdk } from "./sdk.mjs";
11
+ import { reportSdkError, fail } from "./sdk-errors.mjs";
12
+ import { assertKnownFlags, normalizeArgv } from "./argparse.mjs";
13
+
14
+ const HELP = `run402 webhook-secret — Manage the operator webhook signing secret
15
+
16
+ Usage:
17
+ run402 webhook-secret rotate
18
+
19
+ Notes:
20
+ - Returns the new plaintext secret EXACTLY once. Store it immediately.
21
+ - Previous secret remains valid for 24 hours after rotation.
22
+ - Requires operator_passkey assurance level.
23
+ `;
24
+
25
+ export async function run(sub, args = []) {
26
+ if (!sub || sub === "--help" || sub === "-h") {
27
+ console.log(HELP);
28
+ process.exit(0);
29
+ }
30
+ if (sub !== "rotate") {
31
+ fail({ code: "BAD_USAGE", message: "Usage: run402 webhook-secret rotate" });
32
+ }
33
+ const parsedArgs = normalizeArgv(args);
34
+ assertKnownFlags(parsedArgs, ["--help", "-h"]);
35
+ allowanceAuthHeaders("/agent/v1/webhook-secret/rotate");
36
+ try {
37
+ const data = await getSdk().admin.rotateWebhookSecret();
38
+ console.log(JSON.stringify(data, null, 2));
39
+ console.error(""); // separator
40
+ console.error("⚠ Store this secret NOW — it will not be shown again.");
41
+ console.error("⚠ Your previous secret remains valid for the next 24 hours.");
42
+ } catch (err) {
43
+ reportSdkError(err);
44
+ }
45
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "2.13.0",
3
+ "version": "2.15.0",
4
4
  "description": "CLI for Run402 — provision Postgres databases, deploy static sites, generate images, and manage wallets via x402 and MPP micropayments.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -65,6 +65,108 @@ export interface AdminProjectFinanceResult {
65
65
  }>;
66
66
  notes: string;
67
67
  }
68
+ export type NotificationKind = "digest" | "lifecycle_event" | "threshold_alert" | "missing_verified_recipient";
69
+ export type NotificationChannel = "email" | "webhook" | "skipped";
70
+ export type NotificationDeliveryStatus = "delivered" | "failed_transient" | "failed_permanent" | "skipped_no_recipient" | "skipped_disabled";
71
+ export interface NotificationRow {
72
+ id: string;
73
+ recipient_email: string | null;
74
+ kind: NotificationKind;
75
+ event_type: string | null;
76
+ channel: NotificationChannel;
77
+ delivery_status: NotificationDeliveryStatus;
78
+ delivery_error: string | null;
79
+ attempt_count: number;
80
+ is_test: boolean;
81
+ related_project_id: string | null;
82
+ related_billing_account_id: string | null;
83
+ related_wallet_address: string | null;
84
+ created_at: string;
85
+ redacted_at: string | null;
86
+ /** Payload JSON, or null when the row has been redacted. */
87
+ payload: Record<string, unknown> | null;
88
+ }
89
+ export interface ListNotificationsOptions {
90
+ type?: string;
91
+ /** ISO timestamp; only notifications created at or after this time. */
92
+ since?: string;
93
+ /** Default 50, max 200. */
94
+ limit?: number;
95
+ offset?: number;
96
+ }
97
+ export interface ListNotificationsResult {
98
+ notifications: NotificationRow[];
99
+ pagination: {
100
+ limit: number;
101
+ offset: number;
102
+ returned: number;
103
+ };
104
+ }
105
+ export interface NotificationPreferences {
106
+ channels: {
107
+ email: boolean;
108
+ webhook: boolean;
109
+ };
110
+ webhook_url: string | null;
111
+ webhook_signing_secret_configured: boolean;
112
+ digest_cadence: "off" | "daily" | "weekly" | "monthly";
113
+ /** 1=Monday..7=Sunday. */
114
+ digest_day_of_week: number;
115
+ /** 0..23 UTC. */
116
+ digest_hour_utc: number;
117
+ threshold_alerts: "off" | "digest_only" | "immediate";
118
+ lifecycle_events: "off" | "critical_only" | "all";
119
+ /** Schema-enforced; always "always". */
120
+ security_events: "always";
121
+ /** BCP-47 (e.g. "en-US"). */
122
+ locale: string;
123
+ /** IANA timezone (e.g. "UTC"). */
124
+ timezone: string;
125
+ }
126
+ export type NotificationPreferencesPatch = Partial<Omit<NotificationPreferences, "webhook_signing_secret_configured" | "security_events">> & {
127
+ /** Cannot be changed away from "always" — server returns 400. */
128
+ security_events?: "always";
129
+ };
130
+ export interface TestNotificationResult {
131
+ status: "queued";
132
+ source_event_id: string;
133
+ note: string;
134
+ }
135
+ export interface RotateWebhookSecretResult {
136
+ webhook_signing_secret: string;
137
+ rotated_at: string;
138
+ grace_window_hours: number;
139
+ note: string;
140
+ }
141
+ export interface OperatorStatusResult {
142
+ operator_contact: {
143
+ email_status: "none" | "pending" | "verified" | "bouncing";
144
+ passkey_status: "none" | "pending" | "verified";
145
+ recovery_gap: boolean;
146
+ };
147
+ critical_items: Array<{
148
+ kind: string;
149
+ detail: string;
150
+ }>;
151
+ skipped_notifications: Array<{
152
+ id: string;
153
+ event_type: string;
154
+ related_project_id: string | null;
155
+ related_billing_account_id: string | null;
156
+ related_wallet_address: string | null;
157
+ created_at: string;
158
+ }>;
159
+ billing_accounts: Array<Record<string, unknown>>;
160
+ projects: Array<Record<string, unknown>>;
161
+ active_thresholds: Array<{
162
+ resource: string;
163
+ level: "warn" | "critical";
164
+ scope_kind: string;
165
+ scope_id: string;
166
+ crossed_at: string;
167
+ last_observed_value: number | null;
168
+ }>;
169
+ }
68
170
  export declare class Admin {
69
171
  private readonly client;
70
172
  constructor(client: Client);
@@ -78,6 +180,28 @@ export declare class Admin {
78
180
  verifyAgentContactEmail(): Promise<AgentContactResult>;
79
181
  /** Email a passkey enrollment link to the verified operator email. */
80
182
  startOperatorPasskeyEnrollment(): Promise<AgentContactResult>;
183
+ /** List operator notification audit rows (paginated, filterable). */
184
+ listNotifications(opts?: ListNotificationsOptions): Promise<ListNotificationsResult>;
185
+ /** Retrieve a single notification audit row by id. */
186
+ getNotification(id: string): Promise<NotificationRow>;
187
+ /** Read the current operator notification preferences. */
188
+ getNotificationPreferences(): Promise<NotificationPreferences>;
189
+ /** Patch operator notification preferences (assurance ladder applies). */
190
+ setNotificationPreferences(patch: NotificationPreferencesPatch): Promise<NotificationPreferences>;
191
+ /**
192
+ * Trigger a real test notification. Sends a sample `project_past_due`
193
+ * event through the normal worker pipeline; the audit row is marked
194
+ * `is_test: true`. Rate-limited per wallet at 1/min.
195
+ */
196
+ testNotification(): Promise<TestNotificationResult>;
197
+ /**
198
+ * Rotate the operator's webhook signing secret. The new plaintext secret
199
+ * is returned EXACTLY once. The previous secret remains valid for 24
200
+ * hours (dual-secret grace window). Requires `operator_passkey` assurance.
201
+ */
202
+ rotateWebhookSecret(): Promise<RotateWebhookSecretResult>;
203
+ /** Compact operator-health snapshot for the authenticated wallet. */
204
+ getOperatorStatus(): Promise<OperatorStatusResult>;
81
205
  /**
82
206
  * Fetch per-project finance for platform operators.
83
207
  *
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/namespaces/admin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/namespaces/admin.ts"],"names":[],"mappings":"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"}
@@ -54,6 +54,64 @@ export class Admin {
54
54
  context: "starting operator passkey enrollment",
55
55
  });
56
56
  }
57
+ // ---------------------------------------------------------------------------
58
+ // Operator notifications (v1.55, add-operator-health-notifications).
59
+ // ---------------------------------------------------------------------------
60
+ /** List operator notification audit rows (paginated, filterable). */
61
+ async listNotifications(opts = {}) {
62
+ const q = [];
63
+ if (opts.type)
64
+ q.push(`type=${encodeURIComponent(opts.type)}`);
65
+ if (opts.since)
66
+ q.push(`since=${encodeURIComponent(opts.since)}`);
67
+ if (opts.limit != null)
68
+ q.push(`limit=${opts.limit}`);
69
+ if (opts.offset != null)
70
+ q.push(`offset=${opts.offset}`);
71
+ const url = q.length > 0
72
+ ? `/agent/v1/notifications?${q.join("&")}`
73
+ : "/agent/v1/notifications";
74
+ return this.client.request(url, {
75
+ method: "GET",
76
+ context: "listing notifications",
77
+ });
78
+ }
79
+ /** Retrieve a single notification audit row by id. */
80
+ async getNotification(id) {
81
+ return this.client.request(`/agent/v1/notifications/${encodeURIComponent(id)}`, { method: "GET", context: "fetching notification" });
82
+ }
83
+ /** Read the current operator notification preferences. */
84
+ async getNotificationPreferences() {
85
+ return this.client.request("/agent/v1/notifications/preferences", { method: "GET", context: "fetching notification preferences" });
86
+ }
87
+ /** Patch operator notification preferences (assurance ladder applies). */
88
+ async setNotificationPreferences(patch) {
89
+ return this.client.request("/agent/v1/notifications/preferences", {
90
+ method: "PATCH",
91
+ body: patch,
92
+ context: "updating notification preferences",
93
+ });
94
+ }
95
+ /**
96
+ * Trigger a real test notification. Sends a sample `project_past_due`
97
+ * event through the normal worker pipeline; the audit row is marked
98
+ * `is_test: true`. Rate-limited per wallet at 1/min.
99
+ */
100
+ async testNotification() {
101
+ return this.client.request("/agent/v1/notifications/test", { method: "POST", context: "triggering test notification" });
102
+ }
103
+ /**
104
+ * Rotate the operator's webhook signing secret. The new plaintext secret
105
+ * is returned EXACTLY once. The previous secret remains valid for 24
106
+ * hours (dual-secret grace window). Requires `operator_passkey` assurance.
107
+ */
108
+ async rotateWebhookSecret() {
109
+ return this.client.request("/agent/v1/webhook-secret/rotate", { method: "POST", context: "rotating webhook signing secret" });
110
+ }
111
+ /** Compact operator-health snapshot for the authenticated wallet. */
112
+ async getOperatorStatus() {
113
+ return this.client.request("/agent/v1/operator/status", { method: "GET", context: "fetching operator status" });
114
+ }
57
115
  /**
58
116
  * Fetch per-project finance for platform operators.
59
117
  *
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/namespaces/admin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAsE1C,MAAM,eAAe,GAAG,IAAI,GAAG,CAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEjF,MAAM,OAAO,KAAK;IACa;IAA7B,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAE/C,wEAAwE;IACxE,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAoB,aAAa,EAAE;YAC3D,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,OAAO,EAAE;YACjB,OAAO,EAAE,iBAAiB;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,KAAK,CAAC,eAAe,CAAC,OAAqB;QACzC,MAAM,IAAI,GAA2B,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5D,IAAI,OAAO,CAAC,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC9C,IAAI,OAAO,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAEpD,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAqB,mBAAmB,EAAE;YAClE,MAAM,EAAE,MAAM;YACd,IAAI;YACJ,OAAO,EAAE,uBAAuB;SACjC,CAAC,CAAC;IACL,CAAC;IAED,+EAA+E;IAC/E,KAAK,CAAC,qBAAqB;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAqB,0BAA0B,EAAE;YACzE,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,+BAA+B;SACzC,CAAC,CAAC;IACL,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,uBAAuB;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAqB,gCAAgC,EAAE;YAC/E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,2CAA2C;SACrD,CAAC,CAAC;IACL,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,8BAA8B;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAqB,kCAAkC,EAAE;YACjF,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,sCAAsC;SAChD,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,iBAAiB,CACrB,SAAiB,EACjB,OAAmC,EAAE;QAErC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC;QACpC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,UAAU,CAClB,2BAA2B,MAAM,CAAC,MAAM,CAAC,uCAAuC,EAChF,0BAA0B,CAC3B,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC;QAChE,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,8BAA8B,kBAAkB,CAAC,SAAS,CAAC,WAAW,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAClG;YACE,OAAO;YACP,OAAO,EAAE,0BAA0B;SACpC,CACF,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/namespaces/admin.ts"],"names":[],"mappings":"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"}