@voltro/cli 0.57.0 → 0.58.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 +201 -0
- package/dist/apiBuild-CDE4NXNi.js +2 -0
- package/dist/{apiBuild-DDr2aNFd.js → apiBuild-CkpsCqIu.js} +2 -2
- package/dist/bin.js +1 -1
- package/dist/build-51qBWfYY.js +981 -0
- package/dist/{checkCommand-BISqx1OJ.js → checkCommand-C1EbNmwl.js} +1 -1
- package/dist/{checkCommand-DUtMWjcR.js → checkCommand-C30J2F18.js} +3 -3
- package/dist/{codegenCommand-DnVuDxwT.js → codegenCommand-kS3Twuc9.js} +7 -7
- package/dist/{codemodRunner-BlQPfjzA.js → codemodRunner-BKjCwGiN.js} +1127 -895
- package/dist/{commands-CRbxgxv0.js → commands-DowWkYtd.js} +21 -21
- package/dist/{dashboardCommand-Bf_-Ne3P.js → dashboardCommand-gG1y4PFG.js} +5 -5
- package/dist/{dataCommand-BoBJJ-Gb.js → dataCommand-hNOGKz4K.js} +6 -6
- package/dist/{dev-DOEJXicj.js → dev-Ce2gEziv.js} +2422 -2419
- package/dist/dev-Dff_pdik.js +3 -0
- package/dist/{doctorCommand-BrWu67JZ.js → doctorCommand-5ULMpL10.js} +505 -284
- package/dist/doctorCommand-B8H2MYCE.js +2 -0
- package/dist/{dormancyCommand-xn2y-pJm.js → dormancyCommand-DYgI0Kf-.js} +3 -3
- package/dist/{embeddingsCommand-Cn5MbRDM.js → embeddingsCommand-yJivQSrI.js} +2 -2
- package/dist/{envCommand-UJmJIbs9.js → envCommand-ORJUf8r_.js} +8 -8
- package/dist/{evolveCommand-Db30twUy.js → evolveCommand-DTawtTxf.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{infoCommand-BjVXpMlP.js → infoCommand-BFksHunl.js} +1 -1
- package/dist/inspect-CZvsmp8t.js +2 -0
- package/dist/{inspect-DZnan87F.js → inspect-PcC5J-Dl.js} +6 -7
- package/dist/manifestBuild-AUh31bFU.js +2 -0
- package/dist/{manifestBuild-DnbFKF6w.js → manifestBuild-BwiS4iYm.js} +1 -1
- package/dist/{probeCommand-C5fuN6Z2.js → probeCommand-BUYzc0CT.js} +1 -1
- package/dist/{runtimeTrace-BQL_lfz6.js → runtimeTrace-BUk5zMXY.js} +1 -1
- package/dist/{sdkgen-CMUPrDjH.js → sdkgen-CAhmmbjx.js} +1 -1
- package/dist/serveCommand-BUXUtSF5.js +2 -0
- package/dist/{serveCommand-B_w-Mpb_.js → serveCommand-DhtC7WBq.js} +726 -725
- package/dist/serveEntry.js +1 -1
- package/dist/{start-s25GAIgn.js → start-C75w6ftA.js} +1 -1
- package/dist/{start-YaUehtDV.js → start-DNtIlBcn.js} +641 -609
- package/dist/startEntry.js +1 -1
- package/dist/{updateCommand-C9n_Z_oG.js → updateCommand-CtuD5r1t.js} +1 -1
- package/dist/updateCommand-eVKVHj3N.js +2 -0
- package/dist/webDev-Bzb8ZFus.js +2 -0
- package/dist/{webDev-BgdkyjP6.js → webDev-CBN9KkyQ.js} +154 -146
- package/dist/{webhooksCommand-CYXTNvXq.js → webhooksCommand-BPJQOGTe.js} +1 -1
- package/package.json +61 -19
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/_manifest.json +1 -1
- package/templates/agent-docs/ai.md +174 -0
- package/templates/agent-docs/authentication.md +34 -0
- package/templates/agent-docs/data.md +30 -0
- package/templates/agent-docs/database/transactions.md +48 -0
- package/templates/agent-docs/observability.md +13 -2
- package/templates/agent-docs/plugins/auth-supabase.md +21 -0
- package/templates/agent-docs/plugins/sentry.md +91 -8
- package/templates/agent-docs/schema-driven-ui.md +29 -0
- package/templates/agent-docs/whats-new.md +112 -105
- package/templates/apps/api-ai/package.json +6 -6
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-sqlite/package.json +8 -8
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-cms/package.json +9 -9
- package/templates/apps/api-collab/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-row-history/package.json +8 -8
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-saas-starter/package.json +10 -10
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-status/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +7 -7
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +7 -7
- package/templates/apps/frontend-app/package.json +8 -8
- package/templates/apps/frontend-auth/package.json +7 -7
- package/templates/apps/frontend-blank/package.json +6 -6
- package/templates/apps/frontend-cms/package.json +8 -8
- package/templates/apps/frontend-collab/package.json +9 -9
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +6 -6
- package/templates/apps/frontend-docs/package.json +8 -8
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-portal/package.json +7 -7
- package/templates/apps/frontend-saas/package.json +7 -7
- package/templates/apps/frontend-spa/package.json +6 -6
- package/templates/apps/frontend-ssr/package.json +6 -6
- package/templates/apps/frontend-ssr-api/package.json +7 -7
- package/templates/apps/frontend-static-blog/package.json +8 -8
- package/templates/apps/frontend-status/package.json +7 -7
- package/templates/apps/mobile-app/package.json +4 -4
- package/dist/apiBuild-B83Cb2Rv.js +0 -2
- package/dist/build-QKP6Bm0J.js +0 -872
- package/dist/dev-Bl9HqtV7.js +0 -3
- package/dist/doctorCommand-DrQv9SL3.js +0 -2
- package/dist/inspect-B0hL41s0.js +0 -2
- package/dist/manifestBuild-UXrnUcXP.js +0 -2
- package/dist/serveCommand-Dtb48ffg.js +0 -2
- package/dist/updateCommand-DsXEAHbd.js +0 -2
- package/dist/webDev-B6ZMX42w.js +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Bt as r,
|
|
3
|
-
import { r as d, u as f } from "./apiBuild-
|
|
1
|
+
import { Xt as e, Yt as t, Zt as n } from "./dev-Ce2gEziv.js";
|
|
2
|
+
import { Bt as r, Ht as i, T as a, Ut as o, V as s, Vt as c, t as l, u } from "./webDev-CBN9KkyQ.js";
|
|
3
|
+
import { r as d, u as f } from "./apiBuild-CkpsCqIu.js";
|
|
4
4
|
import { S as p } from "./frameworkTableAssembly-vfkzuzEo.js";
|
|
5
5
|
import { n as m } from "./pageConvention-CMpfDN6r.js";
|
|
6
6
|
import { n as h, r as g, t as ee } from "./cliOutput-D1tSBoRM.js";
|
|
@@ -11,8 +11,227 @@ import { existsSync as S, readFileSync as C, readdirSync as w, statSync as T, wr
|
|
|
11
11
|
import { pathToFileURL as se } from "node:url";
|
|
12
12
|
import { createLogger as ce } from "@voltro/logger";
|
|
13
13
|
import { Node as E, Project as D, SyntaxKind as O } from "ts-morph";
|
|
14
|
-
//#region src/
|
|
15
|
-
var le =
|
|
14
|
+
//#region src/frameworkTableNullability.generated.ts
|
|
15
|
+
var le = {
|
|
16
|
+
_voltro_ai_flow_runs: [
|
|
17
|
+
"cancelledAt",
|
|
18
|
+
"chainPending",
|
|
19
|
+
"chainRefusal",
|
|
20
|
+
"completedAt",
|
|
21
|
+
"durationMs",
|
|
22
|
+
"error",
|
|
23
|
+
"errorMessage",
|
|
24
|
+
"flowName",
|
|
25
|
+
"humanResponse",
|
|
26
|
+
"input",
|
|
27
|
+
"metadata",
|
|
28
|
+
"output",
|
|
29
|
+
"ownerId",
|
|
30
|
+
"sessionId",
|
|
31
|
+
"sessionName",
|
|
32
|
+
"source",
|
|
33
|
+
"startedAt",
|
|
34
|
+
"steps"
|
|
35
|
+
],
|
|
36
|
+
_voltro_ai_flows: [
|
|
37
|
+
"avatarUrl",
|
|
38
|
+
"cadence",
|
|
39
|
+
"chainTo",
|
|
40
|
+
"color",
|
|
41
|
+
"description",
|
|
42
|
+
"humanTimeoutMs",
|
|
43
|
+
"icon",
|
|
44
|
+
"inputSchema",
|
|
45
|
+
"metadata",
|
|
46
|
+
"orchestratorInstructions",
|
|
47
|
+
"orchestratorModel",
|
|
48
|
+
"ownerId",
|
|
49
|
+
"steps"
|
|
50
|
+
],
|
|
51
|
+
_voltro_api_keys: [
|
|
52
|
+
"createdBy",
|
|
53
|
+
"expiresAt",
|
|
54
|
+
"lastUsedAt",
|
|
55
|
+
"metadata",
|
|
56
|
+
"onBehalfOf",
|
|
57
|
+
"revokedAt",
|
|
58
|
+
"scopes",
|
|
59
|
+
"tenantId"
|
|
60
|
+
],
|
|
61
|
+
_voltro_change_claims: [],
|
|
62
|
+
_voltro_comment_reactions: [],
|
|
63
|
+
_voltro_comment_reads: [],
|
|
64
|
+
_voltro_comment_threads: ["tenantId"],
|
|
65
|
+
_voltro_comments: ["editedAt", "tenantId"],
|
|
66
|
+
_voltro_events: ["subjectId", "tenantId"],
|
|
67
|
+
_voltro_idempotency: ["response"],
|
|
68
|
+
_voltro_kv: ["expiresAt", "value"],
|
|
69
|
+
_voltro_migration_plans: [
|
|
70
|
+
"liveFingerprint",
|
|
71
|
+
"notes",
|
|
72
|
+
"onlineStrategy",
|
|
73
|
+
"rollbackPlan",
|
|
74
|
+
"squashedAt"
|
|
75
|
+
],
|
|
76
|
+
_voltro_migrations: [
|
|
77
|
+
"appliedAt",
|
|
78
|
+
"durationMs",
|
|
79
|
+
"errorMessage",
|
|
80
|
+
"errorStack",
|
|
81
|
+
"workflowRunId"
|
|
82
|
+
],
|
|
83
|
+
_voltro_notification_deliveries: [
|
|
84
|
+
"clickToken",
|
|
85
|
+
"clickedAt",
|
|
86
|
+
"endpoint",
|
|
87
|
+
"error"
|
|
88
|
+
],
|
|
89
|
+
_voltro_notification_held: [],
|
|
90
|
+
_voltro_notification_inbox: [
|
|
91
|
+
"archivedAt",
|
|
92
|
+
"readAt",
|
|
93
|
+
"tenantId"
|
|
94
|
+
],
|
|
95
|
+
_voltro_notification_preferences: [],
|
|
96
|
+
_voltro_notification_push_subscriptions: ["tenantId", "ua"],
|
|
97
|
+
_voltro_notification_quiet_hours: [],
|
|
98
|
+
_voltro_notification_topic_subscriptions: ["tenantId"],
|
|
99
|
+
_voltro_rebac_tuples: ["tenantId"],
|
|
100
|
+
_voltro_replica_observations: [
|
|
101
|
+
"payload",
|
|
102
|
+
"reachableAt",
|
|
103
|
+
"version"
|
|
104
|
+
],
|
|
105
|
+
_voltro_schedule_claims: [],
|
|
106
|
+
_voltro_schedule_runs: [
|
|
107
|
+
"completedAt",
|
|
108
|
+
"coordinationOutcome",
|
|
109
|
+
"durationMs",
|
|
110
|
+
"errorMessage",
|
|
111
|
+
"errorTag",
|
|
112
|
+
"firedAt",
|
|
113
|
+
"heartbeatAt",
|
|
114
|
+
"replicaId",
|
|
115
|
+
"result"
|
|
116
|
+
],
|
|
117
|
+
_voltro_scim_groups: ["externalId", "members"],
|
|
118
|
+
_voltro_scim_users: [
|
|
119
|
+
"email",
|
|
120
|
+
"externalId",
|
|
121
|
+
"familyName",
|
|
122
|
+
"givenName"
|
|
123
|
+
],
|
|
124
|
+
_voltro_seeds: [
|
|
125
|
+
"cronSchedule",
|
|
126
|
+
"lastError",
|
|
127
|
+
"lastRunAt",
|
|
128
|
+
"lastRunDurationMs",
|
|
129
|
+
"lastRunRowsTouched",
|
|
130
|
+
"lastRunStatus",
|
|
131
|
+
"nextRunAt",
|
|
132
|
+
"watchedTables",
|
|
133
|
+
"workflowRunId"
|
|
134
|
+
],
|
|
135
|
+
_voltro_traces: [
|
|
136
|
+
"attributes",
|
|
137
|
+
"events",
|
|
138
|
+
"parentSpanId",
|
|
139
|
+
"statusMessage"
|
|
140
|
+
],
|
|
141
|
+
_voltro_undo_log: [
|
|
142
|
+
"label",
|
|
143
|
+
"subjectId",
|
|
144
|
+
"tenantId",
|
|
145
|
+
"traceId"
|
|
146
|
+
],
|
|
147
|
+
_voltro_wakeups: [],
|
|
148
|
+
_voltro_webhook_deliveries: [
|
|
149
|
+
"errorMessage",
|
|
150
|
+
"eventId",
|
|
151
|
+
"latencyMs",
|
|
152
|
+
"nextAttemptAt",
|
|
153
|
+
"responseBody",
|
|
154
|
+
"responseStatus"
|
|
155
|
+
],
|
|
156
|
+
_voltro_webhook_event_stats: [],
|
|
157
|
+
_voltro_webhook_rate_windows: [],
|
|
158
|
+
_voltro_webhook_targets: [
|
|
159
|
+
"autoDisableAfter",
|
|
160
|
+
"autoDisableReason",
|
|
161
|
+
"autoDisabledAt",
|
|
162
|
+
"description",
|
|
163
|
+
"filter",
|
|
164
|
+
"headers",
|
|
165
|
+
"rateLimitPerMinute",
|
|
166
|
+
"scope"
|
|
167
|
+
],
|
|
168
|
+
_voltro_workflow_admissions: [
|
|
169
|
+
"concurrencyKey",
|
|
170
|
+
"executionId",
|
|
171
|
+
"expiresAt",
|
|
172
|
+
"mode",
|
|
173
|
+
"rateKey",
|
|
174
|
+
"reason",
|
|
175
|
+
"releasedAt",
|
|
176
|
+
"runId",
|
|
177
|
+
"singletonKey",
|
|
178
|
+
"tenantId",
|
|
179
|
+
"waitedMs"
|
|
180
|
+
],
|
|
181
|
+
_voltro_workflow_event_deliveries: [
|
|
182
|
+
"completedAt",
|
|
183
|
+
"errorMessage",
|
|
184
|
+
"executionId"
|
|
185
|
+
],
|
|
186
|
+
_voltro_workflow_events: ["subject", "traceId"],
|
|
187
|
+
_voltro_workflow_pauses: ["pausedBy", "reason"],
|
|
188
|
+
_voltro_workflow_pending: [
|
|
189
|
+
"callerContext",
|
|
190
|
+
"deadlineAt",
|
|
191
|
+
"lastError",
|
|
192
|
+
"tenantId"
|
|
193
|
+
],
|
|
194
|
+
_voltro_workflow_run_events: [
|
|
195
|
+
"attempt",
|
|
196
|
+
"payload",
|
|
197
|
+
"stepName"
|
|
198
|
+
],
|
|
199
|
+
_voltro_workflow_run_steps: [
|
|
200
|
+
"completedAt",
|
|
201
|
+
"durationMs",
|
|
202
|
+
"errorCause",
|
|
203
|
+
"errorMessage",
|
|
204
|
+
"errorTag",
|
|
205
|
+
"input",
|
|
206
|
+
"output",
|
|
207
|
+
"retryPolicy"
|
|
208
|
+
],
|
|
209
|
+
_voltro_workflow_runs: [
|
|
210
|
+
"completedAt",
|
|
211
|
+
"discardedAt",
|
|
212
|
+
"discardedBy",
|
|
213
|
+
"durationMs",
|
|
214
|
+
"errorMessage",
|
|
215
|
+
"errorTag",
|
|
216
|
+
"output",
|
|
217
|
+
"parentClosePolicy",
|
|
218
|
+
"parentExecutionId",
|
|
219
|
+
"runnerEnteredAt",
|
|
220
|
+
"source",
|
|
221
|
+
"subject",
|
|
222
|
+
"traceId",
|
|
223
|
+
"workflowPatches",
|
|
224
|
+
"workflowVersion"
|
|
225
|
+
],
|
|
226
|
+
_voltro_workflow_start_contexts: [
|
|
227
|
+
"parentClosePolicy",
|
|
228
|
+
"parentExecutionId",
|
|
229
|
+
"source",
|
|
230
|
+
"subject",
|
|
231
|
+
"traceId"
|
|
232
|
+
],
|
|
233
|
+
_voltro_workflow_watermarks: []
|
|
234
|
+
}, ue = /* @__PURE__ */ new Set([
|
|
16
235
|
"eq",
|
|
17
236
|
"ne",
|
|
18
237
|
"gt",
|
|
@@ -30,10 +249,10 @@ var le = /* @__PURE__ */ new Set([
|
|
|
30
249
|
"endsWith",
|
|
31
250
|
"between",
|
|
32
251
|
"jsonField"
|
|
33
|
-
]),
|
|
252
|
+
]), de = (e) => {
|
|
34
253
|
if (E.isPropertyAccessExpression(e)) return e.getName();
|
|
35
254
|
if (E.isIdentifier(e)) return e.getText();
|
|
36
|
-
},
|
|
255
|
+
}, fe = (e) => {
|
|
37
256
|
let t = e;
|
|
38
257
|
for (; E.isCallExpression(t);) {
|
|
39
258
|
let e = t.getExpression();
|
|
@@ -41,7 +260,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
41
260
|
t = e.getExpression();
|
|
42
261
|
}
|
|
43
262
|
return t;
|
|
44
|
-
},
|
|
263
|
+
}, pe = (e, t, n) => {
|
|
45
264
|
let r = new Map(t.map((e) => [e.name, new Set(e.columns)])), i = new Map(t.map((e) => [e.name, e.columns])), a = [], o = 0, s = new D({
|
|
46
265
|
useInMemoryFileSystem: !0,
|
|
47
266
|
skipAddingFilesFromTsConfig: !0
|
|
@@ -59,7 +278,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
59
278
|
for (let t of e.getDescendantsOfKind(O.CallExpression)) {
|
|
60
279
|
let e = t.getExpression();
|
|
61
280
|
if (!E.isPropertyAccessExpression(e) || e.getName() !== "where") continue;
|
|
62
|
-
let n =
|
|
281
|
+
let n = de(fe(e.getExpression()));
|
|
63
282
|
if (n === void 0 || !r.has(n)) {
|
|
64
283
|
let t = e.getExpression();
|
|
65
284
|
if (E.isCallExpression(t)) {
|
|
@@ -82,7 +301,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
82
301
|
else for (let e of [u, ...u.getDescendantsOfKind(O.CallExpression)]) {
|
|
83
302
|
if (!E.isCallExpression(e)) continue;
|
|
84
303
|
let t = e.getExpression(), n = E.isIdentifier(t) ? t.getText() : E.isPropertyAccessExpression(t) ? t.getName() : void 0;
|
|
85
|
-
if (n === void 0 || !
|
|
304
|
+
if (n === void 0 || !ue.has(n)) continue;
|
|
86
305
|
let r = e.getArguments()[0];
|
|
87
306
|
r !== void 0 && E.isStringLiteral(r) && l.push({
|
|
88
307
|
column: r.getLiteralValue(),
|
|
@@ -103,7 +322,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
103
322
|
issues: a,
|
|
104
323
|
checked: o
|
|
105
324
|
};
|
|
106
|
-
}, k = 12,
|
|
325
|
+
}, k = 12, me = (e) => {
|
|
107
326
|
if (e.checked === 0) return null;
|
|
108
327
|
if (e.issues.length === 0) return `predicate columns: ${e.checked} checked — every filtered column exists on its table`;
|
|
109
328
|
let t = [`predicate columns: ${e.issues.length} filter${e.issues.length, "s"} on a column that does not exist (${e.checked} checked)`];
|
|
@@ -112,7 +331,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
112
331
|
t.push(` ${n.file}:${n.line} '${n.table}' has no column '${n.column}'`), t.push(` columns: ${e}${r}`);
|
|
113
332
|
}
|
|
114
333
|
return t.push(" This type-checks today and fails at runtime as a bare SQL error."), t.join("\n");
|
|
115
|
-
},
|
|
334
|
+
}, he = /* @__PURE__ */ new Set([
|
|
116
335
|
"id",
|
|
117
336
|
"tenantId",
|
|
118
337
|
"tenant_id",
|
|
@@ -132,7 +351,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
132
351
|
"idempotency_id",
|
|
133
352
|
"idempotencyKey",
|
|
134
353
|
"idempotency_key"
|
|
135
|
-
]),
|
|
354
|
+
]), ge = /* @__PURE__ */ new Set([
|
|
136
355
|
"id",
|
|
137
356
|
"createdAt",
|
|
138
357
|
"created_at",
|
|
@@ -142,10 +361,10 @@ var le = /* @__PURE__ */ new Set([
|
|
|
142
361
|
"deleted_at",
|
|
143
362
|
"tenantId",
|
|
144
363
|
"tenant_id"
|
|
145
|
-
]),
|
|
364
|
+
]), _e = (e) => he.has(e) ? !1 : /[a-z0-9]Id$/.test(e) || /_id$/.test(e), ve = (e) => e.type === "reference", ye = (e) => {
|
|
146
365
|
let t = [];
|
|
147
366
|
for (let n of e) {
|
|
148
|
-
let e = n.columns.filter((e) =>
|
|
367
|
+
let e = n.columns.filter((e) => _e(e.name)), r = e.filter((e) => !ve(e)).map((e) => e.name);
|
|
149
368
|
if (r.length === 0) continue;
|
|
150
369
|
let i = new Set(n.primaryKey), a = r.filter((e) => i.has(e));
|
|
151
370
|
if (n.primaryKey.length >= 2 && a.length > 0) {
|
|
@@ -156,7 +375,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
156
375
|
});
|
|
157
376
|
continue;
|
|
158
377
|
}
|
|
159
|
-
if (e.some(
|
|
378
|
+
if (e.some(ve) && e.length >= 2) {
|
|
160
379
|
t.push({
|
|
161
380
|
table: n.name,
|
|
162
381
|
columns: r,
|
|
@@ -164,7 +383,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
164
383
|
});
|
|
165
384
|
continue;
|
|
166
385
|
}
|
|
167
|
-
e.length >= 2 && n.columns.filter((e) => !
|
|
386
|
+
e.length >= 2 && n.columns.filter((e) => !_e(e.name) && !ge.has(e.name)).length === 0 && t.push({
|
|
168
387
|
table: n.name,
|
|
169
388
|
columns: r,
|
|
170
389
|
signal: "link-only"
|
|
@@ -174,20 +393,20 @@ var le = /* @__PURE__ */ new Set([
|
|
|
174
393
|
issues: t,
|
|
175
394
|
tablesChecked: e.length
|
|
176
395
|
};
|
|
177
|
-
},
|
|
396
|
+
}, be = {
|
|
178
397
|
"composite-pk": "part of a composite primary key",
|
|
179
398
|
"reference-sibling": "sits beside a wired reference() on this table",
|
|
180
399
|
"link-only": "this table is nothing but link columns"
|
|
181
|
-
},
|
|
400
|
+
}, xe = (e) => {
|
|
182
401
|
if (e.tablesChecked === 0) return null;
|
|
183
402
|
if (e.issues.length === 0) return `junction FKs: ${e.tablesChecked} table${e.tablesChecked === 1 ? "" : "s"} checked — every link column is a wired reference()`;
|
|
184
403
|
let t = e.issues.length, n = [`junction FKs: ${t} junction table${t === 1 ? "" : "s"} with an id column that is a plain text() and not a reference()`];
|
|
185
404
|
for (let t of e.issues) {
|
|
186
405
|
let e = t.columns.map((e) => `'${e}'`).join(", ");
|
|
187
|
-
n.push(` '${t.table}': ${e} (${
|
|
406
|
+
n.push(` '${t.table}': ${e} (${be[t.signal]})`);
|
|
188
407
|
}
|
|
189
408
|
return n.push(" Declare each as reference(() => <table>): the FK is enforced, the column is auto-indexed,"), n.push(" and the relationship becomes walkable (a plain text() id column is an invisible edge)."), n.join("\n");
|
|
190
|
-
},
|
|
409
|
+
}, Se = /* @__PURE__ */ new Set(/* @__PURE__ */ "position.positions.move.moved.moving.cursor.pointer.mouse.drag.dragging.hover.frame.frames.tick.ticks.ping.heartbeat.typing.scroll.scrolling.zoom.pan.coord.coords.coordinate.coordinates.telemetry.sensor.sample.samples.viewport".split(".")), Ce = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter((e) => e.length > 0).map((e) => e.toLowerCase()), we = (e) => Ce(e).some((e) => Se.has(e)), Te = (e) => {
|
|
191
410
|
let t = [], n = [];
|
|
192
411
|
for (let r of e) t.push({
|
|
193
412
|
event: r.name,
|
|
@@ -196,7 +415,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
196
415
|
event: r.name,
|
|
197
416
|
kind: "wide-key",
|
|
198
417
|
keyFieldCount: r.keyFieldCount
|
|
199
|
-
}), r.hasWebhook &&
|
|
418
|
+
}), r.hasWebhook && we(r.name) && n.push({
|
|
200
419
|
event: r.name,
|
|
201
420
|
kind: "webhook-high-rate"
|
|
202
421
|
});
|
|
@@ -205,26 +424,26 @@ var le = /* @__PURE__ */ new Set([
|
|
|
205
424
|
modes: t,
|
|
206
425
|
warnings: n
|
|
207
426
|
};
|
|
208
|
-
},
|
|
427
|
+
}, Ee = (e) => {
|
|
209
428
|
if (e.eventsChecked === 0) return null;
|
|
210
429
|
let t = e.eventsChecked, n = [`event delivery: ${t} declared event${t === 1 ? "" : "s"} — the mode decides what a MISSING message means`];
|
|
211
430
|
for (let t of e.modes) n.push(` '${t.event}': ${t.delivery}`);
|
|
212
431
|
return n.push(" each — every delivery matters; a slow subscriber loses the oldest and is TOLD how many (the default)."), n.push(" latest — a newer delivery supersedes a pending one; a slow subscriber gets the current value, told nothing."), n.push(" Two events with identical route/subscriber/buffer numbers mean OPPOSITE things about a drop — the mode is the difference."), n.join("\n");
|
|
213
|
-
},
|
|
432
|
+
}, De = (e) => {
|
|
214
433
|
if (e.warnings.length === 0) return null;
|
|
215
434
|
let t = e.warnings.length, n = [`events that may not scale as declared: ${t} finding${t === 1 ? "" : "s"}`];
|
|
216
435
|
for (let t of e.warnings) t.kind === "wide-key" ? (n.push(` '${t.event}': routing key has ${t.keyFieldCount ?? 0} fields — every field FRAGMENTS the subscriber set (distinct routes are the PRODUCT of the fields’ value spaces).`), n.push(" Check each is an ADDRESS the delivery is decided by (arenaId), not a discriminator the handler reads (gameType) — the latter is payload, not key.")) : (n.push(` '${t.event}': a webhook block on a per-frame-looking event — every publish is N HTTP deliveries per second per subscribed target.`), n.push(" The webhook rate limit DEFERS the excess as pending rows rather than failing, so the symptom is a growing table. Publish a coarser event (a summary / state change) for the outside world."));
|
|
217
436
|
return n.push(" WARNING, not a fault — a producer may intend the fan-out. `voltro doctor --json` prints every finding."), n.join("\n");
|
|
218
|
-
},
|
|
437
|
+
}, Oe = /* @__PURE__ */ new Set([
|
|
219
438
|
"start",
|
|
220
439
|
"run",
|
|
221
440
|
"child"
|
|
222
|
-
]),
|
|
441
|
+
]), ke = (e) => E.isCallExpression(e) && (() => {
|
|
223
442
|
let t = e.getExpression();
|
|
224
|
-
if (!E.isPropertyAccessExpression(t) || !
|
|
443
|
+
if (!E.isPropertyAccessExpression(t) || !Oe.has(t.getName())) return !1;
|
|
225
444
|
let n = t.getExpression();
|
|
226
445
|
return E.isPropertyAccessExpression(n) ? n.getName() === "workflows" : E.isIdentifier(n) && n.getText() === "workflows";
|
|
227
|
-
})(),
|
|
446
|
+
})(), Ae = (e, t, n) => {
|
|
228
447
|
let r = new Map(t.map((e) => [e.name, e])), i = [...r.keys()].sort(), a = [], o = [], s = 0, c = 0, l = new D({
|
|
229
448
|
useInMemoryFileSystem: !0,
|
|
230
449
|
skipAddingFilesFromTsConfig: !0
|
|
@@ -240,7 +459,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
240
459
|
}
|
|
241
460
|
let u = y(n, t);
|
|
242
461
|
for (let t of e.getDescendantsOfKind(O.CallExpression)) {
|
|
243
|
-
if (!
|
|
462
|
+
if (!ke(t)) continue;
|
|
244
463
|
c++;
|
|
245
464
|
let e = t.getStartLineNumber(), [n, l] = t.getArguments();
|
|
246
465
|
if (n === void 0 || !E.isStringLiteral(n)) {
|
|
@@ -324,7 +543,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
324
543
|
checked: s,
|
|
325
544
|
callSites: c
|
|
326
545
|
};
|
|
327
|
-
},
|
|
546
|
+
}, je = (e) => {
|
|
328
547
|
if (e.callSites === 0) return null;
|
|
329
548
|
let t = [];
|
|
330
549
|
t.push(`workflow starts: ${e.checked}/${e.callSites} call sites checked`);
|
|
@@ -337,7 +556,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
337
556
|
for (let n of e.unchecked) t.push(` ${n.file}:${n.line} — ${n.reason}`);
|
|
338
557
|
}
|
|
339
558
|
return e.issues.length === 0 && e.unchecked.length === 0 && t.push(" every call site matches its workflow"), t.join("\n");
|
|
340
|
-
},
|
|
559
|
+
}, Me = /(^|[/\\])(\.env(\.[\w.-]+)?|.*\.ya?ml|Dockerfile|.*\.tf|.*\.toml|Procfile)$/i, A = "VOLTRO_FIELD_ENCRYPTION_KEY", Ne = (e) => {
|
|
341
560
|
let t;
|
|
342
561
|
for (let [n, r] of e.sources) if (t === void 0 && /\bfieldEncryption\b/.test(r) && (t = {
|
|
343
562
|
reason: "fieldEncryption",
|
|
@@ -350,7 +569,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
350
569
|
for (let [, t] of e.envFiles) if (t.includes(A)) return;
|
|
351
570
|
return t;
|
|
352
571
|
}
|
|
353
|
-
},
|
|
572
|
+
}, Pe = (e) => [
|
|
354
573
|
`✗ ${A} is named nowhere under this app root, and the app encrypts columns at rest`,
|
|
355
574
|
e.reason === "fieldEncryption" ? ` (\`fieldEncryption\` in ${e.file})` : ` (an \`.encrypted()\` column in ${e.file})`,
|
|
356
575
|
"",
|
|
@@ -367,15 +586,15 @@ var le = /* @__PURE__ */ new Set([
|
|
|
367
586
|
" reaches your deploy target is not knowable from here — a secret manager",
|
|
368
587
|
" or a CI variable is not a file. Naming it nowhere is conclusive; naming",
|
|
369
588
|
" it somewhere is not a guarantee."
|
|
370
|
-
].join("\n"),
|
|
589
|
+
].join("\n"), Fe = {
|
|
371
590
|
"@voltro/cli": "provides the `voltro` binary; consumed by scripts, never imported",
|
|
372
591
|
"@voltro/devtools": "mounted by `voltro dev` itself",
|
|
373
592
|
"@voltro/sql-postgres": "dialect driver, loaded by the framework from config",
|
|
374
593
|
"@voltro/sql-mysql": "dialect driver, loaded by the framework from config",
|
|
375
594
|
"@voltro/sql-sqlite": "dialect driver, loaded by the framework from config",
|
|
376
595
|
"@voltro/sql-mssql": "dialect driver, loaded by the framework from config"
|
|
377
|
-
},
|
|
378
|
-
if (n > 12 ||
|
|
596
|
+
}, Ie = /* @__PURE__ */ new Set(["@voltro/client", "@voltro/web"]), Le = /(^|\/)(node_modules|dist|build|\.framework|\.next|\.turbo|\.git|coverage|\.publish)(\/|$)/, Re = /\.([cm]?[jt]sx?)$/, ze = /\.generated\.[cm]?[jt]sx?$/, Be = (e, t = [], n = 0) => {
|
|
597
|
+
if (n > 12 || Le.test(e)) return t;
|
|
379
598
|
let r;
|
|
380
599
|
try {
|
|
381
600
|
r = w(e);
|
|
@@ -389,10 +608,10 @@ var le = /* @__PURE__ */ new Set([
|
|
|
389
608
|
} catch {
|
|
390
609
|
continue;
|
|
391
610
|
}
|
|
392
|
-
a.isDirectory() ?
|
|
611
|
+
a.isDirectory() ? Be(r, t, n + 1) : Re.test(i) && t.push(r);
|
|
393
612
|
}
|
|
394
613
|
return t;
|
|
395
|
-
},
|
|
614
|
+
}, Ve = /(?:\bfrom\s*|\bimport\s+|\bimport\s*\(\s*|\brequire\s*\(\s*)['"](@voltro\/[a-z0-9-]+)(?:\/[^'"]*)?['"]/g, He = (e) => e.split("\n").filter((e) => !/^\s*(\/\/|\*|\/\*)/.test(e)).join("\n"), Ue = (e) => {
|
|
396
615
|
let t;
|
|
397
616
|
try {
|
|
398
617
|
t = JSON.parse(C(v(e, "package.json"), "utf8"));
|
|
@@ -402,7 +621,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
402
621
|
let n = (e) => Object.keys(t[e] ?? {}).filter((e) => e.startsWith("@voltro/")).map((t) => ({
|
|
403
622
|
pkg: t,
|
|
404
623
|
declaredIn: e
|
|
405
|
-
})), r = /* @__PURE__ */ new Set(), i = [...n("dependencies"), ...n("devDependencies")].filter((e) => !r.has(e.pkg) && (r.add(e.pkg), !0)), a =
|
|
624
|
+
})), r = /* @__PURE__ */ new Set(), i = [...n("dependencies"), ...n("devDependencies")].filter((e) => !r.has(e.pkg) && (r.add(e.pkg), !0)), a = Be(e), o = a.some((e) => ze.test(e)), s = /* @__PURE__ */ new Set();
|
|
406
625
|
for (let e of a) {
|
|
407
626
|
let t;
|
|
408
627
|
try {
|
|
@@ -410,17 +629,17 @@ var le = /* @__PURE__ */ new Set([
|
|
|
410
629
|
} catch {
|
|
411
630
|
continue;
|
|
412
631
|
}
|
|
413
|
-
for (let e of
|
|
632
|
+
for (let e of He(t).matchAll(Ve)) s.add(e[1]);
|
|
414
633
|
}
|
|
415
|
-
let c = i.filter((e) => !(e.pkg in
|
|
634
|
+
let c = i.filter((e) => !(e.pkg in Fe) && !s.has(e.pkg));
|
|
416
635
|
return {
|
|
417
636
|
declared: i.map((e) => e.pkg).sort(),
|
|
418
|
-
unimported: c.filter((e) => o || !
|
|
419
|
-
pendingCodegen: o ? [] : c.map((e) => e.pkg).filter((e) =>
|
|
420
|
-
exempt: i.map((e) => e.pkg).filter((e) => e in
|
|
637
|
+
unimported: c.filter((e) => o || !Ie.has(e.pkg)).sort((e, t) => e.pkg.localeCompare(t.pkg)),
|
|
638
|
+
pendingCodegen: o ? [] : c.map((e) => e.pkg).filter((e) => Ie.has(e)).sort(),
|
|
639
|
+
exempt: i.map((e) => e.pkg).filter((e) => e in Fe).sort(),
|
|
421
640
|
scannedFiles: a.length
|
|
422
641
|
};
|
|
423
|
-
},
|
|
642
|
+
}, We = (e) => {
|
|
424
643
|
if (e === null) return ["unimported deps · no package.json here — could not check"];
|
|
425
644
|
let t = `unimported deps · ${e.declared.length} @voltro/* package(s) declared, ${e.scannedFiles} file(s) scanned`;
|
|
426
645
|
if (e.declared.length === 0) return [t, " no @voltro/* dependencies declared — nothing to check"];
|
|
@@ -437,14 +656,14 @@ var le = /* @__PURE__ */ new Set([
|
|
|
437
656
|
let i = [t];
|
|
438
657
|
for (let t of e.unimported) i.push(` ⚠ ${t.pkg} — declared in ${t.declaredIn}, imported nowhere`);
|
|
439
658
|
return i.push(" a dependency nobody imports still gets installed, updated, and read as"), i.push(" evidence the package is in use — its breaking-change notes included."), i.push(" Remove it, or if it IS imported through an assembled specifier the scan"), i.push(" cannot see, keep it and ignore this line — the rule is advisory."), i.push(...r), n !== "" && i.push(` ·${n.slice(1)}`), i;
|
|
440
|
-
},
|
|
659
|
+
}, Ge = (e) => {
|
|
441
660
|
if (e.catalogCodes.length === 0) return;
|
|
442
661
|
let t = new Set(e.declaredLocales), n = e.catalogCodes.filter((e) => !t.has(e)).sort();
|
|
443
662
|
if (n.length !== 0) return {
|
|
444
663
|
orphaned: n,
|
|
445
664
|
noneDeclared: t.size === 0
|
|
446
665
|
};
|
|
447
|
-
},
|
|
666
|
+
}, Ke = (e, t) => {
|
|
448
667
|
let n = e.orphaned.join(", ");
|
|
449
668
|
return e.noneDeclared ? [
|
|
450
669
|
`⚠ ${t} has ${e.orphaned.length} catalog(s) — ${n} — and the app declares no \`locales:\`.`,
|
|
@@ -456,7 +675,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
456
675
|
" …or delete the files. A catalog that is never loaded looks from the inside",
|
|
457
676
|
" exactly like one that works, which is why this is worth a line."
|
|
458
677
|
] : [`⚠ ${t} has catalog(s) not in \`locales:\` — ${n} — so they are never imported.`, " Add the code(s) to `locales:` in your app config, or delete the file(s)."];
|
|
459
|
-
},
|
|
678
|
+
}, qe = (e) => {
|
|
460
679
|
let t = e.getProperty("match");
|
|
461
680
|
if (t === void 0) return null;
|
|
462
681
|
let n = (t.asKind(O.PropertyAssignment)?.getInitializer())?.asKind(O.ObjectLiteralExpression);
|
|
@@ -493,7 +712,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
493
712
|
else return;
|
|
494
713
|
}
|
|
495
714
|
return r;
|
|
496
|
-
},
|
|
715
|
+
}, Je = (e, t) => {
|
|
497
716
|
let n = ["middleware.ts", "middleware.tsx"].find((t) => S(v(e, t)));
|
|
498
717
|
if (n === void 0) return;
|
|
499
718
|
let r = new D({
|
|
@@ -510,22 +729,22 @@ var le = /* @__PURE__ */ new Set([
|
|
|
510
729
|
file: n
|
|
511
730
|
};
|
|
512
731
|
}
|
|
513
|
-
let
|
|
732
|
+
let a = [], o = [], c = 0;
|
|
514
733
|
for (let e of i.getVariableDeclarations()) {
|
|
515
734
|
let t = e.getInitializerIfKind(O.CallExpression);
|
|
516
735
|
if (t?.getExpression().getText() !== "defineMiddleware") continue;
|
|
517
736
|
c += 1;
|
|
518
737
|
let n = e.getName(), r = t.getArguments()[0]?.asKind(O.ObjectLiteralExpression);
|
|
519
738
|
if (r === void 0) {
|
|
520
|
-
|
|
739
|
+
o.push(n);
|
|
521
740
|
continue;
|
|
522
741
|
}
|
|
523
|
-
let i =
|
|
742
|
+
let i = qe(r);
|
|
524
743
|
if (i === void 0) {
|
|
525
|
-
|
|
744
|
+
o.push(n);
|
|
526
745
|
continue;
|
|
527
746
|
}
|
|
528
|
-
|
|
747
|
+
a.push({
|
|
529
748
|
exportName: n,
|
|
530
749
|
middleware: {
|
|
531
750
|
_tag: "VoltroMiddleware",
|
|
@@ -535,45 +754,45 @@ var le = /* @__PURE__ */ new Set([
|
|
|
535
754
|
});
|
|
536
755
|
}
|
|
537
756
|
return {
|
|
538
|
-
problems: a
|
|
539
|
-
unreadable:
|
|
757
|
+
problems: s(a, t).map((e) => e.message),
|
|
758
|
+
unreadable: o,
|
|
540
759
|
seen: c,
|
|
541
760
|
file: n
|
|
542
761
|
};
|
|
543
|
-
},
|
|
762
|
+
}, Ye = (e) => {
|
|
544
763
|
let t = [];
|
|
545
764
|
if (e.problems.length > 0) {
|
|
546
765
|
t.push(`✗ ${e.file}: ${e.problems.length} matcher problem(s) — this REFUSES the boot`);
|
|
547
766
|
for (let n of e.problems) t.push(` • ${n}`);
|
|
548
767
|
}
|
|
549
768
|
return e.unreadable.length > 0 && t.push(`… ${e.file}: ${e.unreadable.length} matcher(s) not statically readable (${e.unreadable.join(", ")}) — doctor did NOT check them. The boot still does.`), e.seen === 0 && t.push(`… ${e.file}: no \`defineMiddleware(...)\` found — doctor checked nothing here. A middleware assigned through a variable or re-exported from another module is invisible to this rule.`), t.length === 0 && e.seen > 0 && t.push(`✓ ${e.file}: ${e.seen} middleware(s), matchers resolve and do not overlap`), t;
|
|
550
|
-
},
|
|
769
|
+
}, Xe = (e) => e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/[^\n]*/g, "$1"), Ze = /* @__PURE__ */ new Set([
|
|
551
770
|
"requireScope",
|
|
552
771
|
"requireAnyScope",
|
|
553
772
|
"requireAuth",
|
|
554
773
|
"assertScope",
|
|
555
774
|
"assertCan",
|
|
556
775
|
"can"
|
|
557
|
-
]),
|
|
776
|
+
]), Qe = (e) => {
|
|
558
777
|
let t = /* @__PURE__ */ new Set();
|
|
559
|
-
for (let n of e) for (let e of
|
|
778
|
+
for (let n of e) for (let e of Xe(n).matchAll(/\bexport\s+(?:const|function|async\s+function)\s+((?:require|assert)[A-Z]\w*)/g)) t.add(e[1]);
|
|
560
779
|
return t;
|
|
561
|
-
},
|
|
780
|
+
}, $e = (e, t) => {
|
|
562
781
|
for (let n of t) if (RegExp(`\\b${n}\\s*\\(`).test(e)) return n;
|
|
563
|
-
},
|
|
782
|
+
}, et = (e) => {
|
|
564
783
|
let t = /\bsubject\s*\.\s*id\b[^\n]*?(?:!==|===|!=|==)|(?:!==|===|!=|==)[^\n]*?\bsubject\s*\.\s*id\b/.test(e), n = /(?:Error|Denied|Forbidden|Unauthorized)\b|\b(?:fail|die|throw)\b/.test(e);
|
|
565
784
|
return t && n;
|
|
566
|
-
},
|
|
785
|
+
}, tt = (e, t, n) => {
|
|
567
786
|
if (e.hasDeclaredGuards) return { kind: "declared-guard" };
|
|
568
|
-
let r =
|
|
569
|
-
return i === void 0 ?
|
|
787
|
+
let r = Xe(e.src), i = $e(r, t);
|
|
788
|
+
return i === void 0 ? et(r) ? { kind: "inline-ownership" } : n.has(e.tag) ? { kind: "allowlisted" } : { kind: "unchecked" } : {
|
|
570
789
|
kind: "vocabulary-guard",
|
|
571
790
|
name: i
|
|
572
791
|
};
|
|
573
|
-
},
|
|
792
|
+
}, nt = (e, t, n) => {
|
|
574
793
|
let r = e.op === "delete" ? 3 : e.op === "update" ? 2 : 1;
|
|
575
794
|
return e.table !== void 0 && (t.has(e.table) && (r += 2), n.has(e.table) && e.op === "delete" && (r += 2)), r;
|
|
576
|
-
},
|
|
795
|
+
}, rt = (e, t, n) => {
|
|
577
796
|
switch (t.kind) {
|
|
578
797
|
case "declared-guard": return "guards: on the descriptor";
|
|
579
798
|
case "vocabulary-guard": return `calls ${t.name}()`;
|
|
@@ -581,15 +800,15 @@ var le = /* @__PURE__ */ new Set([
|
|
|
581
800
|
case "allowlisted": return "accepted by a previous run";
|
|
582
801
|
case "unchecked": return n ? e.op === "read" ? "no check in this file — this app registers a row filter; VERIFY it covers this table, then record it as reviewed= rather than debt" : `${e.op}s${e.table ? ` ${e.table}` : ""} with no check in this file — this app registers a row filter; VERIFY it covers this table, then record it as reviewed= rather than debt` : e.op === "read" ? "returns a row the client selected, with nothing compared to the caller" : `${e.op}s${e.table ? ` ${e.table}` : ""} with nothing constraining WHICH row`;
|
|
583
802
|
}
|
|
584
|
-
},
|
|
803
|
+
}, it = (e) => {
|
|
585
804
|
let t = e.executors.map((t) => {
|
|
586
|
-
let n =
|
|
805
|
+
let n = tt(t, e.guardVocabulary, e.allowlist);
|
|
587
806
|
return {
|
|
588
807
|
tag: t.tag,
|
|
589
808
|
path: t.path,
|
|
590
809
|
verdict: n,
|
|
591
|
-
severity:
|
|
592
|
-
why:
|
|
810
|
+
severity: nt(t, e.tenantScopedTables, e.referencedTables),
|
|
811
|
+
why: rt(t, n, e.rowFilterRegistered === !0)
|
|
593
812
|
};
|
|
594
813
|
}), n = (e) => t.filter((t) => t.verdict.kind === e).length;
|
|
595
814
|
return {
|
|
@@ -603,7 +822,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
603
822
|
},
|
|
604
823
|
unchecked: t.filter((e) => e.verdict.kind === "unchecked").sort((e, t) => t.severity - e.severity || e.tag.localeCompare(t.tag))
|
|
605
824
|
};
|
|
606
|
-
},
|
|
825
|
+
}, at = [
|
|
607
826
|
"# voltro doctor — authz allowlist",
|
|
608
827
|
"#",
|
|
609
828
|
"# Two KINDS of line, and the difference is the point:",
|
|
@@ -628,18 +847,18 @@ var le = /* @__PURE__ */ new Set([
|
|
|
628
847
|
"# `--write-authz-allowlist` PRESERVES reviewed= lines. It only ever adds debt",
|
|
629
848
|
"# lines for executors that are newly unchecked.",
|
|
630
849
|
""
|
|
631
|
-
],
|
|
850
|
+
], ot = (e) => {
|
|
632
851
|
let t = [...e].map((e) => typeof e == "string" ? { tag: e } : e), n = t.filter((e) => e.reviewed === void 0).map((e) => e.tag).sort(), r = t.filter((e) => e.reviewed !== void 0).sort((e, t) => e.tag.localeCompare(t.tag));
|
|
633
852
|
return [
|
|
634
|
-
...
|
|
853
|
+
...at,
|
|
635
854
|
...n,
|
|
636
855
|
...r.length > 0 ? ["", "# reviewed — read by a human, open on purpose"] : [],
|
|
637
856
|
...r.map((e) => `${e.tag} reviewed=${e.reviewed}`),
|
|
638
857
|
""
|
|
639
858
|
].join("\n");
|
|
640
|
-
},
|
|
859
|
+
}, st = (e, t) => {
|
|
641
860
|
let n = [...new Set(t)].sort();
|
|
642
|
-
if (e === void 0) return
|
|
861
|
+
if (e === void 0) return ot(n.map((e) => ({ tag: e })));
|
|
643
862
|
let r = j(e).tags, i = n.filter((e) => !r.has(e));
|
|
644
863
|
return i.length === 0 ? e : [
|
|
645
864
|
e.replace(/\n+$/, ""),
|
|
@@ -649,7 +868,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
649
868
|
...i,
|
|
650
869
|
""
|
|
651
870
|
].join("\n");
|
|
652
|
-
},
|
|
871
|
+
}, ct = (e, t) => {
|
|
653
872
|
let n = [...new Set(t)];
|
|
654
873
|
if (e === void 0) return {
|
|
655
874
|
added: n.length,
|
|
@@ -662,7 +881,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
662
881
|
kept: r.size,
|
|
663
882
|
removed: 0
|
|
664
883
|
};
|
|
665
|
-
},
|
|
884
|
+
}, lt = class extends Error {
|
|
666
885
|
tag;
|
|
667
886
|
constructor(e) {
|
|
668
887
|
super(`authz allowlist: '${e}' is marked reviewed with no reason. Write \`${e} reviewed=<why it is genuinely open>\`. A bare tag is the other, honest option — it records the executor as DEBT, which is what an unexplained exemption is.`), this.tag = e, this.name = "AllowlistReasonMissingError";
|
|
@@ -680,7 +899,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
680
899
|
continue;
|
|
681
900
|
}
|
|
682
901
|
let a = r[2].trim();
|
|
683
|
-
if (a.length === 0) throw new
|
|
902
|
+
if (a.length === 0) throw new lt(i);
|
|
684
903
|
t.push({
|
|
685
904
|
tag: i,
|
|
686
905
|
reviewed: a
|
|
@@ -690,13 +909,13 @@ var le = /* @__PURE__ */ new Set([
|
|
|
690
909
|
tags: new Set(t.map((e) => e.tag)),
|
|
691
910
|
entries: t
|
|
692
911
|
};
|
|
693
|
-
},
|
|
912
|
+
}, ut = (e) => {
|
|
694
913
|
let t = e.indexOf(".");
|
|
695
914
|
return t <= 0 ? void 0 : e.slice(0, t);
|
|
696
|
-
},
|
|
915
|
+
}, dt = (e, t) => {
|
|
697
916
|
let n = new Set(t.tables), r = new Set(t.rpcTags), i = /* @__PURE__ */ new Map();
|
|
698
917
|
for (let e of t.rpcTags) {
|
|
699
|
-
let t =
|
|
918
|
+
let t = ut(e);
|
|
700
919
|
if (t === void 0) continue;
|
|
701
920
|
let n = i.get(t);
|
|
702
921
|
n ? n.push(e) : i.set(t, [e]);
|
|
@@ -725,7 +944,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
725
944
|
});
|
|
726
945
|
continue;
|
|
727
946
|
}
|
|
728
|
-
let s = new Set(o.rpcTags.map(
|
|
947
|
+
let s = new Set(o.rpcTags.map(ut).filter((e) => e !== void 0));
|
|
729
948
|
for (let e of s) {
|
|
730
949
|
let t = i.get(e);
|
|
731
950
|
t !== void 0 && a.push({
|
|
@@ -738,12 +957,12 @@ var le = /* @__PURE__ */ new Set([
|
|
|
738
957
|
}
|
|
739
958
|
}
|
|
740
959
|
return a;
|
|
741
|
-
},
|
|
960
|
+
}, ft = (e, t) => {
|
|
742
961
|
let n = e.reduce((e, t) => e + t.tables.length, 0), r = [`plugin surface · ${e.length} plugin(s) contribute ${n} table(s)`];
|
|
743
962
|
if (t.length === 0) return r.push(" ✓ no overlap with your own tables or rpc namespaces"), r;
|
|
744
963
|
for (let e of t) r.push(` ${e.fatal ? "✗" : "⚠"} ${e.plugin} — ${e.detail}`), r.push(` ${e.fix}`);
|
|
745
964
|
return r;
|
|
746
|
-
},
|
|
965
|
+
}, pt = async (e) => {
|
|
747
966
|
if (!await e.hasWorkflows().catch(() => !1)) return { kind: "not-applicable" };
|
|
748
967
|
let t;
|
|
749
968
|
try {
|
|
@@ -767,12 +986,12 @@ var le = /* @__PURE__ */ new Set([
|
|
|
767
986
|
} finally {
|
|
768
987
|
await t.close().catch(() => {});
|
|
769
988
|
}
|
|
770
|
-
},
|
|
989
|
+
}, mt = (e) => {
|
|
771
990
|
let t = Math.round(e / 6e4);
|
|
772
991
|
if (t < 90) return `${t}m`;
|
|
773
992
|
let n = Math.round(t / 60);
|
|
774
993
|
return n < 48 ? `${n}h` : `${Math.round(n / 24)}d`;
|
|
775
|
-
},
|
|
994
|
+
}, ht = (e) => {
|
|
776
995
|
if (e.kind === "not-applicable") return null;
|
|
777
996
|
if (e.kind === "skipped") return `• stuck runs: NOT CHECKED — ${e.reason}\n This is the one doctor rule that reads the database rather than your source.
|
|
778
997
|
Run it where the app's DB env vars are set, or ignore this line locally.`;
|
|
@@ -780,21 +999,21 @@ var le = /* @__PURE__ */ new Set([
|
|
|
780
999
|
if (t.stalled.length === 0) n.push(`✓ stuck runs: none (${t.examined} live run(s) old enough to examine${t.waitingOnTimer > 0 ? `, ${t.waitingOnTimer} waiting on a durable timer` : ""}${t.alreadyReported > 0 ? `, ${t.alreadyReported} already reported` : ""})`);
|
|
781
1000
|
else {
|
|
782
1001
|
n.push(`✗ stuck runs: ${t.stalled.length} run(s) have made no progress`);
|
|
783
|
-
for (let e of t.stalled.slice(0, 20)) n.push(` ${e.tag} ${e.runId} idle ${
|
|
1002
|
+
for (let e of t.stalled.slice(0, 20)) n.push(` ${e.tag} ${e.runId} idle ${mt(e.idleMs)} ${e.reason}`);
|
|
784
1003
|
t.stalled.length > 20 && n.push(` … and ${t.stalled.length - 20} more`), n.push(" Nothing was changed — this is a SUSPICION, not a verdict. `awaiting-signal` usually means the sender never came.");
|
|
785
1004
|
}
|
|
786
1005
|
t.sawFullRunPage && n.push(" (the examined page filled up — more old runs exist than were read this pass)");
|
|
787
1006
|
for (let e of t.failures) n.push(` ! could not examine ${e.subject}: ${e.detail}`);
|
|
788
1007
|
return n.join("\n");
|
|
789
|
-
},
|
|
1008
|
+
}, gt = /(?:^|\n)\s*import\s+(?!type\s)[^;'"]*?from\s+['"]@voltro\/ui-shadcn(?:\/(?!tokens\.css)[^'"]+)?['"]/, _t = /@import\s+["']@voltro\/ui-shadcn\/tokens\.css["']|@import\s+["']tailwindcss["']|from\s+['"]@voltro\/ui-shadcn\/tokens\.css['"]|import\s+['"][^'"]*@voltro\/ui-shadcn\/tokens\.css['"]/, vt = (e) => {
|
|
790
1009
|
let t = [], n = [];
|
|
791
|
-
for (let r of e)
|
|
1010
|
+
for (let r of e) _t.test(r.source) ? n.push(r.path) : !r.path.endsWith(".css") && gt.test(r.source) && t.push(r.path);
|
|
792
1011
|
return {
|
|
793
1012
|
kitImporters: t,
|
|
794
1013
|
styleEntries: n
|
|
795
1014
|
};
|
|
796
|
-
},
|
|
797
|
-
if (!
|
|
1015
|
+
}, yt = (e) => e.kitImporters.length > 0 && e.styleEntries.length === 0, bt = (e) => {
|
|
1016
|
+
if (!yt(e)) return [];
|
|
798
1017
|
let t = e.kitImporters.slice(0, 5);
|
|
799
1018
|
return [
|
|
800
1019
|
`⚠ ui-shadcn: ${e.kitImporters.length} file(s) render kit components, and no CSS entry imports the kit's stylesheet.`,
|
|
@@ -813,7 +1032,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
813
1032
|
" Or, if this app is not a kit app, import the unstyled control instead:",
|
|
814
1033
|
" import { LocaleSwitcher } from '@voltro/i18n'"
|
|
815
1034
|
];
|
|
816
|
-
},
|
|
1035
|
+
}, xt = (e) => S(b(e, "app.config.ts")) || S(b(e, "app.config.js")), St = (e) => {
|
|
817
1036
|
let t = f(e), n = d(e);
|
|
818
1037
|
return {
|
|
819
1038
|
root: e,
|
|
@@ -822,22 +1041,22 @@ var le = /* @__PURE__ */ new Set([
|
|
|
822
1041
|
apiBundle: n,
|
|
823
1042
|
apiBundlePresent: S(n)
|
|
824
1043
|
};
|
|
825
|
-
},
|
|
1044
|
+
}, Ct = [
|
|
826
1045
|
"Production `voltro serve` requires a precompiled serve bundle and never transpiles on demand.",
|
|
827
1046
|
"Add a `voltro build .` step BEFORE `voltro serve .` in your Dockerfile / start script.",
|
|
828
1047
|
"(Generated Dockerfiles from `voltro create-project` already do this.)"
|
|
829
|
-
].join("\n "),
|
|
830
|
-
let n =
|
|
831
|
-
if (console.log(`voltro doctor — serve preflight for ${n.root}`), !
|
|
1048
|
+
].join("\n "), wt = (e, t = !1) => {
|
|
1049
|
+
let n = St(e);
|
|
1050
|
+
if (console.log(`voltro doctor — serve preflight for ${n.root}`), !xt(e)) return console.log("• no app.config found here — nothing to check (run against an app root)."), 0;
|
|
832
1051
|
console.log(`${n.serveBundlePresent ? "✓" : "✗"} serve bundle: ${n.serveBundlePresent ? "present" : "MISSING"} (${n.serveBundle})`), console.log(`${n.apiBundlePresent ? "✓" : "•"} api bundle: ${n.apiBundlePresent ? "present" : "absent"} (${n.apiBundle})`);
|
|
833
1052
|
let r = process.env.NODE_ENV === "production";
|
|
834
1053
|
if (n.serveBundlePresent) return console.log("✓ serve preflight: ready for `voltro serve`."), 0;
|
|
835
1054
|
let i = t || r;
|
|
836
|
-
return console.error(`${i ? "✗" : "•"} serve bundle missing — ${i ? "production `voltro serve` will FAIL." : "a non-production `voltro serve` still runs via tsx."}`), console.error(` ${
|
|
837
|
-
},
|
|
1055
|
+
return console.error(`${i ? "✗" : "•"} serve bundle missing — ${i ? "production `voltro serve` will FAIL." : "a non-production `voltro serve` still runs via tsx."}`), console.error(` ${Ct}`), +!!i;
|
|
1056
|
+
}, Tt = (e) => {
|
|
838
1057
|
let t = e.absPath.replace(/\.server\.(tsx?)$/, ".$1");
|
|
839
1058
|
if (t !== e.absPath) return e.sources.get(t) ?? e.sources.get(t.replace(/\.ts$/, ".tsx"));
|
|
840
|
-
},
|
|
1059
|
+
}, Et = (e, t, n) => {
|
|
841
1060
|
let r = new Set(e), i = _(n), a = (e) => (/\.(tsx?|jsx?)$/.test(e) ? [e] : [
|
|
842
1061
|
`${e}.ts`,
|
|
843
1062
|
`${e}.tsx`,
|
|
@@ -863,7 +1082,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
863
1082
|
r !== void 0 && o.push(r);
|
|
864
1083
|
}
|
|
865
1084
|
return o;
|
|
866
|
-
}, s = /* @__PURE__ */ new Set(), c = e.filter((e) =>
|
|
1085
|
+
}, s = /* @__PURE__ */ new Set(), c = e.filter((e) => Bt.test(y(n, e))), l = new Set(c);
|
|
867
1086
|
for (; c.length > 0;) {
|
|
868
1087
|
let e = c.shift();
|
|
869
1088
|
if (!s.has(e)) {
|
|
@@ -876,11 +1095,11 @@ var le = /* @__PURE__ */ new Set([
|
|
|
876
1095
|
let d = /* @__PURE__ */ new Set();
|
|
877
1096
|
for (let e of s) l.has(e) || u.has(e) || d.add(e);
|
|
878
1097
|
return d;
|
|
879
|
-
}, M = (e) => e.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/[^\n]*/g, "$1").replace(/'(?:[^'\\\n]|\\.)*'/g, "''").replace(/"(?:[^"\\\n]|\\.)*"/g, "\"\""),
|
|
1098
|
+
}, M = (e) => e.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/[^\n]*/g, "$1").replace(/'(?:[^'\\\n]|\\.)*'/g, "''").replace(/"(?:[^"\\\n]|\\.)*"/g, "\"\""), Dt = (e, t) => (e.match(t) ?? []).length, N = (e, t) => e.getDescendantsOfKind(O.CallExpression).filter((e) => t.test(e.getExpression().getText())).length, Ot = (e, t) => {
|
|
880
1099
|
if (e.src.includes(t)) return !0;
|
|
881
1100
|
let n = t.replace(/^@voltro\/plugin-/, "");
|
|
882
1101
|
return n !== t && N(e.file, RegExp(`^${n}Plugin$`)) > 0;
|
|
883
|
-
},
|
|
1102
|
+
}, kt = (e, t) => {
|
|
884
1103
|
let n = [], r = RegExp(`\\b${t}\\s*(?:<[^()]*>)?\\s*\\(`, "g"), i;
|
|
885
1104
|
for (; (i = r.exec(e)) !== null;) {
|
|
886
1105
|
let t = i.index + i[0].length, r = 1, a = t;
|
|
@@ -888,10 +1107,10 @@ var le = /* @__PURE__ */ new Set([
|
|
|
888
1107
|
n.push(e.slice(t, a - 1));
|
|
889
1108
|
}
|
|
890
1109
|
return n;
|
|
891
|
-
},
|
|
1110
|
+
}, At = (e, t) => {
|
|
892
1111
|
let n = t.getSymbol()?.getDeclarations()?.[0];
|
|
893
1112
|
return n === void 0 ? [] : e.getDescendantsOfKind(O.Identifier).filter((e) => e.getSymbol()?.getDeclarations()?.[0] === n);
|
|
894
|
-
},
|
|
1113
|
+
}, jt = /^(insert|insertMany|insertIgnore|update|updateMany|upsert|delete|deleteMany|hardDelete|patchJson)$/, Mt = /^(notify|sendNotification|sendWebhook|dispatchWebhook|sendMail|trigger)\w*$/, Nt = (e, t) => {
|
|
895
1114
|
if (!E.isObjectLiteralExpression(e)) return;
|
|
896
1115
|
let n = e.getProperty("handler");
|
|
897
1116
|
if (n === void 0 || !E.isPropertyAssignment(n)) return;
|
|
@@ -903,17 +1122,17 @@ var le = /* @__PURE__ */ new Set([
|
|
|
903
1122
|
if (i !== void 0) return i;
|
|
904
1123
|
let a = t.getVariableDeclaration(r.getText())?.getInitializer();
|
|
905
1124
|
if (a !== void 0 && (E.isArrowFunction(a) || E.isFunctionExpression(a))) return a;
|
|
906
|
-
},
|
|
907
|
-
let t = [
|
|
1125
|
+
}, Pt = (e) => {
|
|
1126
|
+
let t = [Mt], n = (E.isArrowFunction(e) || E.isFunctionExpression(e) || E.isFunctionDeclaration(e) ? e.getParameters() : [])[1];
|
|
908
1127
|
if (n === void 0) return t;
|
|
909
1128
|
let r = n.getNameNode();
|
|
910
|
-
if (E.isIdentifier(r)) return t.push(RegExp(`^${r.getText()}\\.publish$`)), t.push(RegExp(`^${r.getText()}\\.store\\.${
|
|
1129
|
+
if (E.isIdentifier(r)) return t.push(RegExp(`^${r.getText()}\\.publish$`)), t.push(RegExp(`^${r.getText()}\\.store\\.${jt.source.replace(/^\^|\$$/g, "")}$`)), t;
|
|
911
1130
|
if (E.isObjectBindingPattern(r)) for (let e of r.getElements()) {
|
|
912
1131
|
let n = e.getPropertyNameNode()?.getText() ?? e.getName(), r = e.getName();
|
|
913
|
-
n === "publish" && t.push(RegExp(`^${r}$`)), n === "store" && t.push(RegExp(`^${r}\\.${
|
|
1132
|
+
n === "publish" && t.push(RegExp(`^${r}$`)), n === "store" && t.push(RegExp(`^${r}\\.${jt.source.replace(/^\^|\$$/g, "")}$`));
|
|
914
1133
|
}
|
|
915
1134
|
return t;
|
|
916
|
-
},
|
|
1135
|
+
}, Ft = (e, t, n, r = 0, i = /* @__PURE__ */ new Set()) => {
|
|
917
1136
|
let a = e.getDescendantsOfKind(O.CallExpression);
|
|
918
1137
|
for (let e of a) {
|
|
919
1138
|
let t = e.getExpression().getText();
|
|
@@ -928,10 +1147,10 @@ var le = /* @__PURE__ */ new Set([
|
|
|
928
1147
|
let e = t.getVariableDeclaration(a)?.getInitializer();
|
|
929
1148
|
return e !== void 0 && (E.isArrowFunction(e) || E.isFunctionExpression(e)) ? e : void 0;
|
|
930
1149
|
})();
|
|
931
|
-
if (o !== void 0 &&
|
|
1150
|
+
if (o !== void 0 && Ft(o, t, [...n, ...Pt(o)], r + 1, i)) return !0;
|
|
932
1151
|
}
|
|
933
1152
|
return !1;
|
|
934
|
-
},
|
|
1153
|
+
}, It = (e) => {
|
|
935
1154
|
let t = /* @__PURE__ */ new Set();
|
|
936
1155
|
for (let n of e.values()) {
|
|
937
1156
|
if (!/\bsetRowFilter\s*[<(]/.test(n)) continue;
|
|
@@ -939,19 +1158,19 @@ var le = /* @__PURE__ */ new Set([
|
|
|
939
1158
|
if (e !== null) for (let n of e[1].matchAll(/['"`]([A-Za-z_][\w]*)['"`]/g)) t.add(n[1]);
|
|
940
1159
|
}
|
|
941
1160
|
return t;
|
|
942
|
-
},
|
|
1161
|
+
}, Lt = (e) => {
|
|
943
1162
|
if (!/\.(query|stream|mutation|action)\.server\.tsx?$/.test(e.path)) return !1;
|
|
944
|
-
let t =
|
|
1163
|
+
let t = It(e.sources);
|
|
945
1164
|
return t.size === 0 || ['"`]/g)].map((e) => e[1]).some((e) => t.has(e)) ? !1 : /\b(eq|and|inSet)\s*\(/.test(e.src) || /\bwhere\s*:/.test(e.src);
|
|
946
|
-
},
|
|
1165
|
+
}, Rt = (e) => e.getDescendantsOfKind(O.CallExpression).filter((e) => e.getExpression().getText() === "defineSubscriber").some((t) => {
|
|
947
1166
|
let n = t.getArguments()[0];
|
|
948
1167
|
if (n === void 0 || !E.isObjectLiteralExpression(n) || n.getProperty("once") !== void 0) return !1;
|
|
949
|
-
let r =
|
|
950
|
-
return r !== void 0 &&
|
|
951
|
-
}),
|
|
1168
|
+
let r = Nt(n, e);
|
|
1169
|
+
return r !== void 0 && Ft(r, e, Pt(r));
|
|
1170
|
+
}), zt = (e) => e.getDescendantsOfKind(O.CallExpression).filter((e) => e.getExpression().getText() === "defineSubscriber").filter((e) => {
|
|
952
1171
|
let t = e.getArguments()[0];
|
|
953
1172
|
return t !== void 0 && E.isObjectLiteralExpression(t) && t.getProperty("once") === void 0;
|
|
954
|
-
}).length,
|
|
1173
|
+
}).length, Bt = /\.(server|cron|workflow\.server|subscribe|reaction|outbox|startup|trigger|webhook|migration|seed)\.tsx?$/, Vt = (e, t) => {
|
|
955
1174
|
let n;
|
|
956
1175
|
try {
|
|
957
1176
|
n = t.createSourceFile("/descriptor-scan.ts", e, { overwrite: !0 });
|
|
@@ -969,7 +1188,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
969
1188
|
else if (E.isSpreadAssignment(t)) return;
|
|
970
1189
|
return r;
|
|
971
1190
|
}
|
|
972
|
-
},
|
|
1191
|
+
}, Ht = (e, t) => {
|
|
973
1192
|
let n = [], r = (e) => {
|
|
974
1193
|
e !== void 0 && (E.isObjectLiteralExpression(e) ? n.push(e) : E.isParenthesizedExpression(e) && r(e.getExpression()));
|
|
975
1194
|
};
|
|
@@ -983,7 +1202,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
983
1202
|
if (n.some((e) => t.has(e))) for (let e of n) i.add(e);
|
|
984
1203
|
}
|
|
985
1204
|
return [...i];
|
|
986
|
-
},
|
|
1205
|
+
}, Ut = (e, t, n) => {
|
|
987
1206
|
let r = RegExp(`\\btable\\(\\s*['"\`]${e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}['"\`]`);
|
|
988
1207
|
for (let [, i] of t) {
|
|
989
1208
|
if (!r.test(i)) continue;
|
|
@@ -1003,7 +1222,9 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1003
1222
|
return i;
|
|
1004
1223
|
}
|
|
1005
1224
|
}
|
|
1006
|
-
|
|
1225
|
+
let i = le[e];
|
|
1226
|
+
return i === void 0 ? void 0 : new Set(i);
|
|
1227
|
+
}, Wt = (e) => /\bNullOr\b|\bSchema\.Null\b|\bnullable\s*\(/.test(e), P = /\.(query|mutation|action|stream)\.server\.tsx?$/, Gt = [
|
|
1007
1228
|
"Id",
|
|
1008
1229
|
"ID",
|
|
1009
1230
|
"Hash",
|
|
@@ -1029,7 +1250,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1029
1250
|
"Comment",
|
|
1030
1251
|
"Provider",
|
|
1031
1252
|
"Format"
|
|
1032
|
-
],
|
|
1253
|
+
], Kt = RegExp(`(?:${Gt.join("|")})$|_(?:${Gt.map((e) => e.toLowerCase()).join("|")})$`), qt = [
|
|
1033
1254
|
{
|
|
1034
1255
|
id: "hardcoded-framework-cookie",
|
|
1035
1256
|
scope: "client",
|
|
@@ -1054,7 +1275,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1054
1275
|
if (!P.test(n)) return !1;
|
|
1055
1276
|
let r = M(t);
|
|
1056
1277
|
if (!(/\bsubject\s*\.\s*id\b/.test(r) && /\b(?:insert|update|upsert|insertMany|updateMany|insertRow|upsertRow|updateManyRow)\s*\(/.test(r)) || /\b(?:guard|guards|requireScope|requireAnyScope|assertCan|assertScope|requireAuth|Unauthenticated)\b/.test(r) || /[=!]==?\s*[^;\n]*\bsubject\s*\.\s*id\b|\bsubject\s*\.\s*id\b\s*[=!]==/.test(r)) return !1;
|
|
1057
|
-
let i =
|
|
1278
|
+
let i = Tt(e);
|
|
1058
1279
|
if (i === void 0) return !1;
|
|
1059
1280
|
let a = M(i);
|
|
1060
1281
|
return /\binternal\s*:\s*true\b/.test(a) || /\bguards\s*:\s*\[/.test(a) || /\.guard\s*\(/.test(a) ? !1 : /\bopenAccess\s*:/.test(a);
|
|
@@ -1065,7 +1286,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1065
1286
|
scope: "server",
|
|
1066
1287
|
smell: "raw fetch() for outbound HTTP on the server (no traceparent, no retry, and no SSRF guard where the URL is not a constant)",
|
|
1067
1288
|
use: "yield* HttpClient — the framework client. It injects traceparent, retries, and honours `http.allowHosts`. Where the URL is built from anything a caller supplied it ALSO blocks loopback / RFC-1918 / link-local targets (incl. 169.254.169.254) on the initial request AND every redirect hop — for a hard-coded host that half is redundant, and the first three are still the reason to switch",
|
|
1068
|
-
match: ({ file: e, path: t, serverOnly: n }) => (
|
|
1289
|
+
match: ({ file: e, path: t, serverOnly: n }) => (Bt.test(t) || n) && N(e, /^(?:globalThis\.|window\.|self\.)?fetch$/) > 0
|
|
1069
1290
|
},
|
|
1070
1291
|
{
|
|
1071
1292
|
id: "form",
|
|
@@ -1100,7 +1321,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1100
1321
|
scope: "client",
|
|
1101
1322
|
smell: "useMemo fanning in multiple subscriptions (hand-maintained dep array)",
|
|
1102
1323
|
use: "useDerived — dependency-tracked, referentially stable",
|
|
1103
|
-
match: ({ src: e }) =>
|
|
1324
|
+
match: ({ src: e }) => Dt(e, /\buseSubscription\s*[(<]/g) >= 3 && Dt(e, /\buseMemo\s*\(/g) >= 3
|
|
1104
1325
|
},
|
|
1105
1326
|
{
|
|
1106
1327
|
id: "next-shim",
|
|
@@ -1132,7 +1353,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1132
1353
|
match: ({ file: e }) => e.getDescendantsOfKind(O.CallExpression).filter((e) => /(^|\.)useSubscription$/.test(e.getExpression().getText())).flatMap((e) => {
|
|
1133
1354
|
let t = e.getFirstAncestorByKind(O.VariableDeclaration)?.getNameNode();
|
|
1134
1355
|
return t === void 0 ? [] : E.isObjectBindingPattern(t) ? t.getElements().filter((e) => (e.getPropertyNameNode() ?? e.getNameNode()).getText() === "data").map((e) => e.getNameNode()) : [];
|
|
1135
|
-
}).some((t) =>
|
|
1356
|
+
}).some((t) => At(e, t).some((e) => {
|
|
1136
1357
|
let t = e.getParent();
|
|
1137
1358
|
if (E.isBinaryExpression(t)) {
|
|
1138
1359
|
let n = t.getOperatorToken().getText(), r = t.getLeft() === e ? t.getRight() : t.getLeft();
|
|
@@ -1183,7 +1404,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1183
1404
|
use: ".encrypted() on the column — boot fails loudly if no cipher is configured, so it can never silently persist plaintext (a *Hash column and a vault* handle are NOT plaintext secrets: the hash IS the protection — often a unique lookup key — and the handle only names a secret held elsewhere, so both are skipped)",
|
|
1184
1405
|
match: ({ src: e }) => e.split("\n").some((e) => [...e.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*(?:text|varchar|string|longtext)\s*\(/g)].some((t) => {
|
|
1185
1406
|
let n = t[1];
|
|
1186
|
-
return !/token|secret|credential|password|apikey|accesskey/i.test(n) ||
|
|
1407
|
+
return !/token|secret|credential|password|apikey|accesskey/i.test(n) || Kt.test(n) || /^vault/i.test(n) || /\.unique\s*\(/.test(e) ? !1 : !/\.encrypted\s*\(/.test(e);
|
|
1187
1408
|
}))
|
|
1188
1409
|
},
|
|
1189
1410
|
{
|
|
@@ -1193,7 +1414,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1193
1414
|
use: "you cannot look a value up by equality AND encrypt it non-deterministically — `.encrypted()` would make this column unfindable. Store the HASH as the unique lookup key and keep the secret itself either `.encrypted()` in a second column or nowhere (the framework's own `_voltro_api_keys.hashedKey` is the shape: the presented value is hashed and compared, never read back). A deterministic cipher is the other option and buys equality lookup at the cost of leaking which rows share a value",
|
|
1194
1415
|
match: ({ src: e }) => e.split("\n").some((e) => [...e.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*(?:text|varchar|string|longtext)\s*\(/g)].some((t) => {
|
|
1195
1416
|
let n = t[1];
|
|
1196
|
-
return !/token|secret|credential|password|apikey|accesskey/i.test(n) ||
|
|
1417
|
+
return !/token|secret|credential|password|apikey|accesskey/i.test(n) || Kt.test(n) || /^vault/i.test(n) ? !1 : /\.unique\s*\(/.test(e) && !/\.encrypted\s*\(/.test(e);
|
|
1197
1418
|
}))
|
|
1198
1419
|
},
|
|
1199
1420
|
{
|
|
@@ -1205,7 +1426,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1205
1426
|
if (!/\.mutation\.tsx?$/.test(e.path)) return !1;
|
|
1206
1427
|
let t = /target\s*:\s*\{[^}]*\btable\s*:\s*['"`]([^'"`]+)['"`]/.exec(e.src)?.[1];
|
|
1207
1428
|
if (t === void 0) return !1;
|
|
1208
|
-
let n =
|
|
1429
|
+
let n = Ut(t, e.sources, e.file.getProject());
|
|
1209
1430
|
if (n === void 0 || n.size === 0) return !1;
|
|
1210
1431
|
for (let t of e.file.getDescendantsOfKind(O.PropertyAssignment)) {
|
|
1211
1432
|
if (t.getName() !== "input") continue;
|
|
@@ -1213,7 +1434,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1213
1434
|
if (e === void 0 || !E.isCallExpression(e) || !/\.Struct$/.test(e.getExpression().getText())) continue;
|
|
1214
1435
|
let r = e.getArguments()[0];
|
|
1215
1436
|
if (!(r === void 0 || !E.isObjectLiteralExpression(r))) {
|
|
1216
|
-
for (let e of r.getProperties()) if (E.isPropertyAssignment(e) && n.has(e.getName()) && !
|
|
1437
|
+
for (let e of r.getProperties()) if (E.isPropertyAssignment(e) && n.has(e.getName()) && !Wt(e.getText())) return !0;
|
|
1217
1438
|
}
|
|
1218
1439
|
}
|
|
1219
1440
|
return !1;
|
|
@@ -1226,11 +1447,11 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1226
1447
|
use: "add the field to the descriptor's `output` struct, or stop building it — `output` IS the serializer, so an undeclared key never reaches the caller",
|
|
1227
1448
|
match: (e) => {
|
|
1228
1449
|
if (!P.test(e.path)) return !1;
|
|
1229
|
-
let t =
|
|
1450
|
+
let t = Tt(e);
|
|
1230
1451
|
if (t === void 0) return !1;
|
|
1231
|
-
let n =
|
|
1452
|
+
let n = Vt(t, e.file.getProject());
|
|
1232
1453
|
if (n === void 0 || n.length === 0) return !1;
|
|
1233
|
-
let r =
|
|
1454
|
+
let r = Ht(e.file, new Set(n));
|
|
1234
1455
|
return r === void 0 || r.length === 0 ? !1 : r.some((e) => !n.includes(e));
|
|
1235
1456
|
}
|
|
1236
1457
|
},
|
|
@@ -1239,14 +1460,14 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1239
1460
|
scope: "server",
|
|
1240
1461
|
smell: "a *.subscribe.ts handler that WRITES or publishes with no `once:` (it runs on every replica, so the effect repeats once per replica)",
|
|
1241
1462
|
use: "once: true on defineSubscriber — one INSERT-wins claim per change, fleet-wide (or `once: (event) => key` for a coarser key). A hand-rolled `insertIgnore` dedupe is this, written out.",
|
|
1242
|
-
match: ({ file: e }) =>
|
|
1463
|
+
match: ({ file: e }) => Rt(e)
|
|
1243
1464
|
},
|
|
1244
1465
|
{
|
|
1245
1466
|
id: "row-filter-duplicated-by-hand",
|
|
1246
1467
|
scope: "server",
|
|
1247
1468
|
smell: "a handler that constrains a table your registered `setRowFilter` already constrains",
|
|
1248
1469
|
use: "drop the hand-written predicate — the filter covers the query, the mutation, the stream AND the subscription delivery. Keep it only if this handler must be NARROWER than the filter, and say so in a comment (two identical predicates ANDed are as tight as one, so this is maintenance, not a leak)",
|
|
1249
|
-
match: (e) =>
|
|
1470
|
+
match: (e) => Lt(e)
|
|
1250
1471
|
},
|
|
1251
1472
|
{
|
|
1252
1473
|
id: "mutation-tail-effect",
|
|
@@ -1311,7 +1532,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1311
1532
|
use: "wire the filter into at least one test (`makeTestContext({ subject, store, rowFilter })`) and sabotage the predicate once to watch it go red — an untested row filter is a visibility rule nothing verifies",
|
|
1312
1533
|
match: ({ file: e, testSources: t }) => N(e, /^setRowFilter$/) > 0 && ![...t.values()].some((e) => {
|
|
1313
1534
|
let t = M(e);
|
|
1314
|
-
return
|
|
1535
|
+
return kt(t, "makeTestContext").length > 0 && /\browFilter\b/.test(t);
|
|
1315
1536
|
})
|
|
1316
1537
|
},
|
|
1317
1538
|
{
|
|
@@ -1321,14 +1542,14 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1321
1542
|
use: "timestampMs / timestampMsOrNull from @voltro/database/wire in the descriptor's output struct — `output` IS the serializer (it is the rpc success schema), so a Date field declared as timestampMs crosses as epoch ms on its own; declaring Schema.Number describes the WIRE type and leaves nothing to convert",
|
|
1322
1543
|
match: ({ src: e }) => /\.(getTime|toISOString)\s*\(\s*\)/.test(e) && /\.map\s*\(|=>\s*\(\{/.test(e) && /\bexport\s+default\b/.test(e)
|
|
1323
1544
|
}
|
|
1324
|
-
], F = (e) => L(e),
|
|
1545
|
+
], F = (e) => L(e), Jt = (e, t) => {
|
|
1325
1546
|
let n = /* @__PURE__ */ new Set();
|
|
1326
1547
|
for (let r of t) {
|
|
1327
1548
|
let t = y(e, r), i = t.split(/[\\/]/)[0];
|
|
1328
1549
|
n.add(i !== void 0 && i !== t ? i : ".");
|
|
1329
1550
|
}
|
|
1330
1551
|
return [...n].sort();
|
|
1331
|
-
},
|
|
1552
|
+
}, Yt = /\.(tsx?|jsx?)$/, I = /(^|\/)(node_modules|dist|build|\.framework|\.next|coverage)(\/|$)/, Xt = /(^|[\\/])[^\\/]*\.generated\.[cm]?[jt]sx?$|\.d\.[cm]?ts$/, Zt = (e, t = [], n = 0) => {
|
|
1332
1553
|
if (n > 12 || I.test(e)) return t;
|
|
1333
1554
|
let r;
|
|
1334
1555
|
try {
|
|
@@ -1340,8 +1561,8 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1340
1561
|
let r = v(e, i.name);
|
|
1341
1562
|
if (i.isDirectory()) {
|
|
1342
1563
|
if (i.name.startsWith(".")) continue;
|
|
1343
|
-
|
|
1344
|
-
} else
|
|
1564
|
+
Zt(r, t, n + 1);
|
|
1565
|
+
} else Me.test(i.name) && t.push(r);
|
|
1345
1566
|
}
|
|
1346
1567
|
return t;
|
|
1347
1568
|
}, L = (e, t = [], n = 0) => {
|
|
@@ -1359,10 +1580,10 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1359
1580
|
} catch {
|
|
1360
1581
|
continue;
|
|
1361
1582
|
}
|
|
1362
|
-
a.isDirectory() ? L(r, t, n + 1) :
|
|
1583
|
+
a.isDirectory() ? L(r, t, n + 1) : Yt.test(i) && !/\.(test|spec)\./.test(i) && !Xt.test(i) && t.push(r);
|
|
1363
1584
|
}
|
|
1364
1585
|
return t;
|
|
1365
|
-
},
|
|
1586
|
+
}, Qt = (e, t = [], n = 0) => {
|
|
1366
1587
|
if (n > 12 || I.test(e)) return t;
|
|
1367
1588
|
let r;
|
|
1368
1589
|
try {
|
|
@@ -1377,16 +1598,16 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1377
1598
|
} catch {
|
|
1378
1599
|
continue;
|
|
1379
1600
|
}
|
|
1380
|
-
a.isDirectory() ?
|
|
1601
|
+
a.isDirectory() ? Qt(r, t, n + 1) : Yt.test(i) && /\.(test|spec)\./.test(i) && t.push(r);
|
|
1381
1602
|
}
|
|
1382
1603
|
return t;
|
|
1383
|
-
},
|
|
1604
|
+
}, $t = (e) => {
|
|
1384
1605
|
let t = F(e);
|
|
1385
1606
|
return {
|
|
1386
|
-
dirs:
|
|
1607
|
+
dirs: Jt(e, t),
|
|
1387
1608
|
fileCount: t.length
|
|
1388
1609
|
};
|
|
1389
|
-
},
|
|
1610
|
+
}, en = (e) => {
|
|
1390
1611
|
let t = F(e);
|
|
1391
1612
|
if (t.length === 0) return [];
|
|
1392
1613
|
let n = new D({
|
|
@@ -1396,8 +1617,8 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1396
1617
|
for (let e of t) try {
|
|
1397
1618
|
i.set(e, C(e, "utf8"));
|
|
1398
1619
|
} catch {}
|
|
1399
|
-
let a =
|
|
1400
|
-
for (let t of
|
|
1620
|
+
let a = Et([...i.keys()], i, e), o = /* @__PURE__ */ new Map();
|
|
1621
|
+
for (let t of Qt(e)) try {
|
|
1401
1622
|
o.set(t, C(t, "utf8"));
|
|
1402
1623
|
} catch {}
|
|
1403
1624
|
for (let s of t) {
|
|
@@ -1417,34 +1638,34 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1417
1638
|
} catch {
|
|
1418
1639
|
continue;
|
|
1419
1640
|
}
|
|
1420
|
-
for (let t of
|
|
1421
|
-
if (t.plugin !== void 0 &&
|
|
1641
|
+
for (let t of qt) {
|
|
1642
|
+
if (t.plugin !== void 0 && Ot(c, t.plugin) || !t.match(c)) continue;
|
|
1422
1643
|
let n = r.get(t.id) ?? [];
|
|
1423
1644
|
n.push(y(e, s)), r.set(t.id, n);
|
|
1424
1645
|
}
|
|
1425
1646
|
}
|
|
1426
|
-
return
|
|
1647
|
+
return qt.filter((e) => r.has(e.id)).map((e) => ({
|
|
1427
1648
|
rule: e,
|
|
1428
1649
|
files: r.get(e.id)
|
|
1429
1650
|
})).sort((e, t) => t.files.length - e.files.length || e.rule.id.localeCompare(t.rule.id));
|
|
1430
|
-
},
|
|
1651
|
+
}, tn = (e) => {
|
|
1431
1652
|
let t = new D({
|
|
1432
1653
|
useInMemoryFileSystem: !0,
|
|
1433
1654
|
skipAddingFilesFromTsConfig: !0
|
|
1434
1655
|
}), n = 0;
|
|
1435
1656
|
for (let r of F(e)) if (/\.subscribe\.tsx?$/.test(r)) try {
|
|
1436
1657
|
let e = t.createSourceFile(`/count${r.endsWith("x") ? ".tsx" : ".ts"}`, C(r, "utf8"), { overwrite: !0 });
|
|
1437
|
-
n +=
|
|
1658
|
+
n += zt(e);
|
|
1438
1659
|
} catch {}
|
|
1439
1660
|
return n;
|
|
1440
1661
|
}, R = (e) => {
|
|
1441
|
-
let t =
|
|
1662
|
+
let t = $t(e);
|
|
1442
1663
|
return {
|
|
1443
1664
|
root: e,
|
|
1444
1665
|
scannedFiles: t.fileCount,
|
|
1445
1666
|
scannedDirs: t.dirs,
|
|
1446
|
-
subscribersWithoutOnce:
|
|
1447
|
-
findings:
|
|
1667
|
+
subscribersWithoutOnce: tn(e),
|
|
1668
|
+
findings: en(e).map(({ rule: e, files: t }) => ({
|
|
1448
1669
|
id: e.id,
|
|
1449
1670
|
scope: e.scope,
|
|
1450
1671
|
smell: e.smell,
|
|
@@ -1452,21 +1673,21 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1452
1673
|
files: t
|
|
1453
1674
|
}))
|
|
1454
1675
|
};
|
|
1455
|
-
},
|
|
1676
|
+
}, nn = 3, rn = .2, an = 50, on = (e, t) => e >= an && t > 0 && e / t >= rn, sn = (e) => {
|
|
1456
1677
|
let t = /* @__PURE__ */ new Map();
|
|
1457
1678
|
for (let n of L(e)) try {
|
|
1458
1679
|
t.set(y(e, n), C(n, "utf8"));
|
|
1459
1680
|
} catch {}
|
|
1460
1681
|
let n = /* @__PURE__ */ new Map();
|
|
1461
|
-
for (let t of
|
|
1682
|
+
for (let t of Zt(e)) try {
|
|
1462
1683
|
n.set(y(e, t), C(t, "utf8"));
|
|
1463
1684
|
} catch {}
|
|
1464
|
-
let r =
|
|
1685
|
+
let r = Ne({
|
|
1465
1686
|
sources: t,
|
|
1466
1687
|
envFiles: n
|
|
1467
1688
|
});
|
|
1468
|
-
r !== void 0 && (console.log(""), console.log(
|
|
1469
|
-
},
|
|
1689
|
+
r !== void 0 && (console.log(""), console.log(Pe(r)));
|
|
1690
|
+
}, cn = (e) => {
|
|
1470
1691
|
let t = R(e);
|
|
1471
1692
|
if (console.log(""), t.scannedFiles === 0) return console.log(`\u2022 hand-roll scan: no source directories found under ${e}.`), console.log(" Walked the app root recursively (node_modules / dist / .framework pruned). Run `voltro doctor <app>` against an app root."), 0;
|
|
1472
1693
|
if (t.findings.length === 0) return console.log(`\u2713 hand-roll scan: ${t.scannedFiles} file${t.scannedFiles === 1 ? "" : "s"} across ${t.scannedDirs.join(", ")} \u2014 no hand-rolled primitives found.`), 0;
|
|
@@ -1478,12 +1699,12 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1478
1699
|
console.log(` [${e}]`);
|
|
1479
1700
|
let i = [...r].sort((e, t) => e.files.length - t.files.length);
|
|
1480
1701
|
for (let e of i) {
|
|
1481
|
-
if (
|
|
1702
|
+
if (on(e.files.length, t.scannedFiles)) {
|
|
1482
1703
|
let n = Math.round(e.files.length / t.scannedFiles * 100);
|
|
1483
1704
|
console.log(` ${e.smell} \u2014 ${e.files.length} file(s), ${n}% of those scanned: a codebase-wide pattern rather than a work list`), console.log(` \u2192 ${e.use}`), console.log(" (paths omitted on purpose at this scale — `voltro doctor --json` has every one.)");
|
|
1484
1705
|
continue;
|
|
1485
1706
|
}
|
|
1486
|
-
let r = e.files.slice(0,
|
|
1707
|
+
let r = e.files.slice(0, nn).join(", "), i = e.files.length - nn;
|
|
1487
1708
|
i > 0 && (n += i);
|
|
1488
1709
|
let a = i > 0 ? `, +${i} more` : "";
|
|
1489
1710
|
console.log(` ${e.smell} \u2014 ${e.files.length} file(s): ${r}${a}`), console.log(` \u2192 ${e.use}`);
|
|
@@ -1496,25 +1717,25 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1496
1717
|
console.log(` \u24d8 ${t.subscribersWithoutOnce} subscriber(s) declare no \`once:\`; an effect was found in ${e}. The rule reads each subscriber's OWN file (its handler and the functions that file declares) and does not resolve imports — a write in another module is unexamined, not absent.`);
|
|
1497
1718
|
}
|
|
1498
1719
|
return console.log(" (See the \"Pick the SERVER primitive\" / \"Pick the CLIENT primitive\" rubrics in AGENTS.md / CLAUDE.md.)"), t.findings.length;
|
|
1499
|
-
},
|
|
1500
|
-
let t =
|
|
1720
|
+
}, ln = "renderMode:'spa' skips this page's SSR compile while its layout shell still renders server-side — adopt it if the page BODY does not need SSR (internal/authenticated pages); keep 'ssr' if the page content needs SEO or server first-paint.", un = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, dn = /export\s+const\s+dynamic\s*=\s*['"]force-(dynamic|static)['"]/, fn = (e) => {
|
|
1721
|
+
let t = un.exec(e)?.[1];
|
|
1501
1722
|
if (t !== void 0) return t === "ssr" ? "ssr" : null;
|
|
1502
|
-
let n =
|
|
1723
|
+
let n = dn.exec(e)?.[1];
|
|
1503
1724
|
return n === "dynamic" ? "ssr" : n === "static" ? null : "default";
|
|
1504
1725
|
}, z = async (e) => {
|
|
1505
1726
|
let t = v(e, "src", "pages");
|
|
1506
1727
|
if (!S(t)) return [];
|
|
1507
|
-
let { pages: n, dirs: r } = await
|
|
1728
|
+
let { pages: n, dirs: r } = await a(t), i = [];
|
|
1508
1729
|
for (let a of n) {
|
|
1509
|
-
if (!
|
|
1730
|
+
if (!u(r, a.dirChain).some((e) => e.hasLayout)) continue;
|
|
1510
1731
|
let n;
|
|
1511
1732
|
try {
|
|
1512
1733
|
n = C(v(t, a.file), "utf8");
|
|
1513
1734
|
} catch {
|
|
1514
1735
|
continue;
|
|
1515
1736
|
}
|
|
1516
|
-
if (
|
|
1517
|
-
let o =
|
|
1737
|
+
if (l.test(n)) continue;
|
|
1738
|
+
let o = fn(n);
|
|
1518
1739
|
o !== null && i.push({
|
|
1519
1740
|
file: y(e, v(t, a.file)),
|
|
1520
1741
|
pattern: a.pattern,
|
|
@@ -1522,19 +1743,19 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1522
1743
|
});
|
|
1523
1744
|
}
|
|
1524
1745
|
return i;
|
|
1525
|
-
},
|
|
1746
|
+
}, pn = 10, B = async (e) => {
|
|
1526
1747
|
console.log("");
|
|
1527
1748
|
let t = v(e, "src", "pages");
|
|
1528
1749
|
if (!S(t)) return console.log("• spa-candidate scan: no src/pages here — nothing to check (web apps only)."), 0;
|
|
1529
1750
|
let n = await z(e);
|
|
1530
1751
|
if (n.length === 0) return console.log("✓ spa-candidate scan: no loader-free, layout-backed pages to flag."), 0;
|
|
1531
1752
|
console.log(`• renderMode:'spa' candidates (${n.length} page${n.length === 1 ? "" : "s"} — loader-free, under a layout, currently ssr/default):`);
|
|
1532
|
-
for (let e of n.slice(0,
|
|
1753
|
+
for (let e of n.slice(0, pn)) {
|
|
1533
1754
|
let t = e.currentMode === "ssr" ? "renderMode:'ssr'" : "default renderMode";
|
|
1534
1755
|
console.log(` ${e.file} (${e.pattern}) — ${t}`);
|
|
1535
1756
|
}
|
|
1536
|
-
let r = n.length -
|
|
1537
|
-
return r > 0 && console.log(` (+${r} more page${r === 1 ? "" : "s"} not shown — \`voltro doctor --json\` prints every one.)`), console.log(` → ${
|
|
1757
|
+
let r = n.length - pn;
|
|
1758
|
+
return r > 0 && console.log(` (+${r} more page${r === 1 ? "" : "s"} not shown — \`voltro doctor --json\` prints every one.)`), console.log(` → ${ln}`), n.length;
|
|
1538
1759
|
}, mn = /* @__PURE__ */ new Set([
|
|
1539
1760
|
"node_modules",
|
|
1540
1761
|
"dist",
|
|
@@ -1583,7 +1804,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1583
1804
|
}, _n = (e, t) => {
|
|
1584
1805
|
let n = e.slice(t.length).split(x).slice(0, -1)[0];
|
|
1585
1806
|
return n !== void 0 && n.startsWith("[");
|
|
1586
|
-
},
|
|
1807
|
+
}, V = (e) => {
|
|
1587
1808
|
let t = [], n = v(e, "src", "pages"), r = v(e, "src");
|
|
1588
1809
|
if (!S(r)) return t;
|
|
1589
1810
|
let i = [];
|
|
@@ -1617,7 +1838,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1617
1838
|
});
|
|
1618
1839
|
}
|
|
1619
1840
|
return t;
|
|
1620
|
-
}, vn = 10,
|
|
1841
|
+
}, vn = 10, H = (e, t, n) => {
|
|
1621
1842
|
if (t.length === 0) return;
|
|
1622
1843
|
console.log(`• ${e} (${t.length}):`);
|
|
1623
1844
|
for (let e of t.slice(0, vn)) console.log(` ${e}`);
|
|
@@ -1627,15 +1848,15 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1627
1848
|
console.log("");
|
|
1628
1849
|
let t = v(e, "src", "pages");
|
|
1629
1850
|
if (!S(t)) return console.log("• page-convention scan: no src/pages here — nothing to check (web apps only)."), 0;
|
|
1630
|
-
let n =
|
|
1851
|
+
let n = V(e);
|
|
1631
1852
|
if (n.length === 0) return console.log("✓ page-convention scan: every route is a page.tsx in its own directory, with a test beside it."), 0;
|
|
1632
1853
|
let r = (e) => n.filter((t) => t.kind === e).map((e) => e.file);
|
|
1633
|
-
return
|
|
1634
|
-
}, bn = "voltro doctor [app] [flags]\n\nPreflight an app root: verify it can boot under production `voltro serve`,\nreport shipped primitives the source looks to be hand-rolling, and flag pages\nthat are safe `renderMode:'spa'` candidates.\n\nArguments:\n [app] App directory to check (default: the current directory).\n\nFlags:\n --strict Treat a missing serve bundle as blocking regardless of NODE_ENV\n (the `voltro serve --preflight` behavior). Without it, a missing\n bundle only fails when NODE_ENV=production.\n --json Print the complete scan as JSON — hand-roll findings AND spa\n candidates, every file path, nothing elided. Skips the preflight output.\n --write-authz-allowlist\n Record today's executors that reference NO access check into\n voltro-authz-allowlist.txt, so every later run fails only on\n ADDITIONS. The list is DEBT, not approval — an entry stops\n mattering as soon as its executor gains a guard.\n -h, --help Print this help.", xn = /* @__PURE__ */ new Map(),
|
|
1854
|
+
return H("will NEVER route — page.tsx outside src/pages/", r("suffixed-outside-pages"), "the name says \"route\", the location says otherwise, and the location wins: the URL comes from the directory chain under src/pages/. Move it into the directory whose route it serves, or rename it."), H("pages with no test beside them", r("page-without-test"), "a page and its test belong together — `users/[id].page.tsx` → `users/[id].page.test.tsx`. Advisory only; a missing test is a gap, not a defect."), H("routes whose FIRST segment is dynamic — they claim every URL of that depth", r("top-level-dynamic-route"), "a route like `[id]/[code]` answers `/api/health`, `/internal/readiness` and anything else with that many segments on this origin. That is what the pattern means, so it is not a bug — but it is invisible until something requests such a URL, and then the page renders, its loader runs, and the failure reads as an application error rather than as a route claiming a path nobody meant it to. Give the route a literal first segment (`scan/[id]/[code]`) if you did not intend to own the whole origin at that depth. Advisory."), H("pages with no `meta` export — they serve the APP name as their title", r("page-without-meta"), "a page with no `meta` sets no title, so the response carries `<title>{your app.config name}</title>` — the same string on every such page, to every reader that does not run JavaScript: link previews, crawlers, a bookmark taken before hydration, a screen reader announcing the document. The client router fixes the tab after hydration, which is exactly why this is easy to miss. Add `export const meta = { title: \"…\" }` (or a function of params/loaderData). If such a page also has no real body — it redirects from an effect, say — the missing title is the symptom rather than the bug: on an `ssr` route the server answers 200 with an empty document and the redirect happens only once JavaScript runs. Move it into the loader (`redirect(...)`, a real 303). Advisory."), n.length;
|
|
1855
|
+
}, bn = "voltro doctor [app] [flags]\n\nPreflight an app root: verify it can boot under production `voltro serve`,\nreport shipped primitives the source looks to be hand-rolling, and flag pages\nthat are safe `renderMode:'spa'` candidates.\n\nArguments:\n [app] App directory to check (default: the current directory).\n\nFlags:\n --strict Treat a missing serve bundle as blocking regardless of NODE_ENV\n (the `voltro serve --preflight` behavior). Without it, a missing\n bundle only fails when NODE_ENV=production.\n --json Print the complete scan as JSON — hand-roll findings AND spa\n candidates, every file path, nothing elided. Skips the preflight output.\n --write-authz-allowlist\n Record today's executors that reference NO access check into\n voltro-authz-allowlist.txt, so every later run fails only on\n ADDITIONS. The list is DEBT, not approval — an entry stops\n mattering as soon as its executor gains a guard.\n -h, --help Print this help.", xn = /* @__PURE__ */ new Map(), U = (e) => {
|
|
1635
1856
|
let t = xn.get(e);
|
|
1636
1857
|
if (t !== void 0) return t;
|
|
1637
1858
|
let n = (async () => {
|
|
1638
|
-
let { walk: t, loadDiscovered: n } = await import("./dev-
|
|
1859
|
+
let { walk: t, loadDiscovered: n } = await import("./dev-Dff_pdik.js"), r = await t(e);
|
|
1639
1860
|
return {
|
|
1640
1861
|
files: r,
|
|
1641
1862
|
discovered: await n(r, { root: e })
|
|
@@ -1645,7 +1866,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1645
1866
|
}, Sn = async (e) => {
|
|
1646
1867
|
let t;
|
|
1647
1868
|
try {
|
|
1648
|
-
let { files: n, discovered: r } = await
|
|
1869
|
+
let { files: n, discovered: r } = await U(e), i = r.tables.map((e) => {
|
|
1649
1870
|
let t = e;
|
|
1650
1871
|
return {
|
|
1651
1872
|
name: t.tableName,
|
|
@@ -1653,7 +1874,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1653
1874
|
};
|
|
1654
1875
|
});
|
|
1655
1876
|
if (i.length === 0) return;
|
|
1656
|
-
t = pe(
|
|
1877
|
+
t = me(pe(n, i, e));
|
|
1657
1878
|
} catch {
|
|
1658
1879
|
return;
|
|
1659
1880
|
}
|
|
@@ -1670,7 +1891,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1670
1891
|
};
|
|
1671
1892
|
}), wn = async (e) => {
|
|
1672
1893
|
try {
|
|
1673
|
-
let { missingRelationSources: t } = await import("./doctorSourceRelations-c5mlN5HI.js"), { sourceKeys: n } = await import("@voltro/protocol"), { readFile: r } = await import("node:fs/promises"), { discovered: i } = await
|
|
1894
|
+
let { missingRelationSources: t } = await import("./doctorSourceRelations-c5mlN5HI.js"), { sourceKeys: n } = await import("@voltro/protocol"), { readFile: r } = await import("node:fs/promises"), { discovered: i } = await U(e), a = [], o = [];
|
|
1674
1895
|
for (let e of i.queries) {
|
|
1675
1896
|
let i = n(e.descriptor.source);
|
|
1676
1897
|
if (i.length === 0) continue;
|
|
@@ -1705,22 +1926,22 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1705
1926
|
for (let e of t.unresolved) console.log(` ${e.procedure}: ${e.relations.map((e) => `\`${e}\``).join(", ")} resolved against no table`);
|
|
1706
1927
|
console.log(" declare the base table in `source:` and re-run — relations under it are unchecked until then.");
|
|
1707
1928
|
}
|
|
1708
|
-
},
|
|
1929
|
+
}, W = async (e) => {
|
|
1709
1930
|
try {
|
|
1710
|
-
let { discovered: t } = await
|
|
1711
|
-
return
|
|
1931
|
+
let { discovered: t } = await U(e);
|
|
1932
|
+
return ye(Cn(t.tables));
|
|
1712
1933
|
} catch {
|
|
1713
1934
|
return null;
|
|
1714
1935
|
}
|
|
1715
1936
|
}, Dn = async (e) => {
|
|
1716
|
-
let t = await
|
|
1937
|
+
let t = await W(e);
|
|
1717
1938
|
if (t === null || t.tablesChecked === 0) return;
|
|
1718
|
-
let n =
|
|
1939
|
+
let n = xe(t);
|
|
1719
1940
|
n !== null && (console.log(""), console.log(`${t.issues.length > 0 ? "✗" : "✓"} ${n}`));
|
|
1720
|
-
},
|
|
1941
|
+
}, G = async (e) => {
|
|
1721
1942
|
try {
|
|
1722
|
-
let { payloadPropertyNames: t } = await import("@voltro/runtime"), { discovered: n } = await
|
|
1723
|
-
return
|
|
1943
|
+
let { payloadPropertyNames: t } = await import("@voltro/runtime"), { discovered: n } = await U(e);
|
|
1944
|
+
return Te(n.events.map((e) => {
|
|
1724
1945
|
let n = e.descriptor, r = t(n.key);
|
|
1725
1946
|
return {
|
|
1726
1947
|
name: n.name,
|
|
@@ -1733,18 +1954,18 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1733
1954
|
return null;
|
|
1734
1955
|
}
|
|
1735
1956
|
}, On = async (e) => {
|
|
1736
|
-
let t = await
|
|
1957
|
+
let t = await G(e);
|
|
1737
1958
|
if (t === null || t.eventsChecked === 0) return;
|
|
1738
|
-
let n =
|
|
1959
|
+
let n = Ee(t);
|
|
1739
1960
|
n !== null && (console.log(""), console.log(`• ${n}`));
|
|
1740
|
-
let r =
|
|
1961
|
+
let r = De(t);
|
|
1741
1962
|
r !== null && (console.log(""), console.log(`⚠️ ${r}`));
|
|
1742
|
-
},
|
|
1963
|
+
}, K = (e) => {
|
|
1743
1964
|
let t = e, n = typeof t?.message == "string" && t.message !== "" ? t.message : String(e), r = typeof t?.code == "string" ? t.code : void 0;
|
|
1744
1965
|
return r === void 0 ? n : `${r}: ${n}`;
|
|
1745
|
-
},
|
|
1966
|
+
}, q = async (e) => {
|
|
1746
1967
|
try {
|
|
1747
|
-
let { formatServerOnlyLeaks: t } = await import("@voltro/runtime"), n = (await
|
|
1968
|
+
let { formatServerOnlyLeaks: t } = await import("@voltro/runtime"), n = (await U(e)).discovered.serverOnlyLeaks, r = t(n);
|
|
1748
1969
|
return {
|
|
1749
1970
|
status: {
|
|
1750
1971
|
checked: !0,
|
|
@@ -1755,12 +1976,12 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1755
1976
|
} catch (e) {
|
|
1756
1977
|
return { status: {
|
|
1757
1978
|
checked: !1,
|
|
1758
|
-
reason:
|
|
1979
|
+
reason: K(e)
|
|
1759
1980
|
} };
|
|
1760
1981
|
}
|
|
1761
|
-
},
|
|
1982
|
+
}, J = async (r) => {
|
|
1762
1983
|
try {
|
|
1763
|
-
let { loadApiConfig: i } = await import("./dev-
|
|
1984
|
+
let { loadApiConfig: i } = await import("./dev-Dff_pdik.js"), { discovered: a } = await U(r), o = e(await i(r)), s = {
|
|
1764
1985
|
queries: a.queries,
|
|
1765
1986
|
mutations: a.mutations,
|
|
1766
1987
|
actions: a.actions,
|
|
@@ -1770,20 +1991,20 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1770
1991
|
return {
|
|
1771
1992
|
checked: !0,
|
|
1772
1993
|
defaultDeny: o,
|
|
1773
|
-
undecided:
|
|
1774
|
-
openAccess:
|
|
1994
|
+
undecided: n(s),
|
|
1995
|
+
openAccess: t(s)
|
|
1775
1996
|
};
|
|
1776
1997
|
} catch (e) {
|
|
1777
1998
|
return {
|
|
1778
1999
|
checked: !1,
|
|
1779
|
-
reason:
|
|
2000
|
+
reason: K(e),
|
|
1780
2001
|
defaultDeny: !0,
|
|
1781
2002
|
undecided: [],
|
|
1782
2003
|
openAccess: []
|
|
1783
2004
|
};
|
|
1784
2005
|
}
|
|
1785
2006
|
}, kn = async (e) => {
|
|
1786
|
-
let t = await
|
|
2007
|
+
let t = await J(e);
|
|
1787
2008
|
if (!t.checked) return console.log(""), console.log("• access decisions: NOT CHECKED — the app's descriptors could not be loaded (not a pass)"), console.log(` reason: ${t.reason ?? "unknown"}`), !1;
|
|
1788
2009
|
console.log(""), console.log(`access decisions · security.defaultDeny ${t.defaultDeny ? "ON" : "OFF"}`), console.log(` ✗ no access decision ${String(t.undecided.length).padStart(4)}`), console.log(` ✓ openAccess, declared on purpose ${String(t.openAccess.length).padStart(4)}`);
|
|
1789
2010
|
for (let e of t.openAccess) console.log(` ${e.tag} — ${e.openAccess ?? ""}`);
|
|
@@ -1793,9 +2014,9 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1793
2014
|
return console.log(""), t.defaultDeny ? (console.log(" `voltro dev` and `voltro serve` REFUSE to boot on these. Give each a decision:"), An(), !0) : (console.log(" This app sets `security: { defaultDeny: false }`, so these BOOT — and each one is"), console.log(" callable by any authenticated session. Advisory here for that reason only."), An(), !1);
|
|
1794
2015
|
}, An = () => {
|
|
1795
2016
|
console.log(" `guards: [{ scope: '…' }]` authority the SUBJECT holds globally"), console.log(" `guards: [{ action, resourceType, resource }]` authority per ROW / per resource"), console.log(" — backed by `defineResourcePolicy` + a tuple source you register. If your"), console.log(" relationships already live in your own tables (a `teamMembers` row), register"), console.log(" a tuple source over them; nothing is copied. Fail-closed without a resolver."), console.log(" Docs: Authentication → Authorization."), console.log(" `openAccess: '<why anyone may call it>'` deliberately unauthenticated");
|
|
1796
|
-
},
|
|
2017
|
+
}, Y = async (e) => {
|
|
1797
2018
|
try {
|
|
1798
|
-
let { files: t } = await
|
|
2019
|
+
let { files: t } = await U(e), { WEBHOOK_PATTERN: n, loadWebhookFiles: r } = await import("./webhookDiscovery-il9ti-HE.js"), { incomingWebhookVerification: i } = await import("@voltro/plugin-webhooks"), a = t.filter((e) => n.test(ie(e)));
|
|
1799
2020
|
if (a.length === 0) return {
|
|
1800
2021
|
checked: !0,
|
|
1801
2022
|
unverified: [],
|
|
@@ -1822,14 +2043,14 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1822
2043
|
} catch (e) {
|
|
1823
2044
|
return {
|
|
1824
2045
|
checked: !1,
|
|
1825
|
-
reason:
|
|
2046
|
+
reason: K(e),
|
|
1826
2047
|
unverified: [],
|
|
1827
2048
|
open: [],
|
|
1828
2049
|
verified: 0
|
|
1829
2050
|
};
|
|
1830
2051
|
}
|
|
1831
2052
|
}, jn = async (e) => {
|
|
1832
|
-
let t = await
|
|
2053
|
+
let t = await Y(e);
|
|
1833
2054
|
if (!t.checked) return console.log(""), console.log("• webhook verification: NOT CHECKED — the app's webhooks could not be loaded (not a pass)"), console.log(` reason: ${t.reason ?? "unknown"}`), !1;
|
|
1834
2055
|
if (t.verified + t.open.length + t.unverified.length === 0) return !1;
|
|
1835
2056
|
console.log(""), console.log("incoming webhook verification"), console.log(` ✓ signature / provider verified ${String(t.verified).padStart(4)}`), console.log(` ! deliberately public (none) ${String(t.open.length).padStart(4)}`), console.log(` ✗ nothing verifies the caller ${String(t.unverified.length).padStart(4)}`);
|
|
@@ -1839,12 +2060,12 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1839
2060
|
for (let e of t.unverified) console.log(` ✗ ${e.id}\n ${e.file}`);
|
|
1840
2061
|
return console.log(""), console.log(" These are public POSTs that run your application code, and `voltro dev` /"), console.log(" `voltro serve` REFUSE to mount them. Declare one of: `provider:` (a preset),"), console.log(" `signature:` (your own HMAC scheme), `verification: 'provider'` (your handler"), console.log(" verifies), or `verification: 'none'` (deliberately public)."), !0;
|
|
1841
2062
|
}, Mn = async (e) => {
|
|
1842
|
-
let { status: t, message: n } = await
|
|
2063
|
+
let { status: t, message: n } = await q(e);
|
|
1843
2064
|
return t.checked ? n !== void 0 && (console.log(""), console.log(`✗ [serverOnly] ${n}`), !0) : (console.log(""), console.log("• serverOnly: NOT CHECKED — the app's descriptors could not be loaded (not a pass)"), console.log(` reason: ${t.reason ?? "unknown"}`), console.log(" This audit is the automated check that a hash or a token cannot reach the wire, so"), console.log(" an app that leans on `.serverOnly()` should treat a persistent skip as a failure."), console.log(" `voltro doctor --json` reports it as `serverOnly.checked: false` for a CI gate."), !1);
|
|
1844
|
-
}, Nn = async (e) =>
|
|
1845
|
-
hasWorkflows: async () => (await
|
|
2065
|
+
}, Nn = async (e) => pt({
|
|
2066
|
+
hasWorkflows: async () => (await U(e)).discovered.workflows.length > 0,
|
|
1846
2067
|
openStore: async () => {
|
|
1847
|
-
let { loadApiConfig: t, buildStore: n } = await import("./dev-
|
|
2068
|
+
let { loadApiConfig: t, buildStore: n } = await import("./dev-Dff_pdik.js"), r = await t(e);
|
|
1848
2069
|
if (r === null) throw Error("no app.config.ts in this directory");
|
|
1849
2070
|
let i = await n(r, void 0);
|
|
1850
2071
|
return {
|
|
@@ -1859,13 +2080,13 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1859
2080
|
return t({ store: e });
|
|
1860
2081
|
}
|
|
1861
2082
|
}), Pn = async (e) => {
|
|
1862
|
-
let t =
|
|
2083
|
+
let t = ht(await Nn(e));
|
|
1863
2084
|
t !== null && (console.log(""), console.log(t));
|
|
1864
2085
|
}, Fn = async (e) => {
|
|
1865
2086
|
let t;
|
|
1866
2087
|
try {
|
|
1867
|
-
let { payloadPropertyNames: n } = await import("@voltro/runtime"), { files: r, discovered: i } = await
|
|
1868
|
-
t =
|
|
2088
|
+
let { payloadPropertyNames: n } = await import("@voltro/runtime"), { files: r, discovered: i } = await U(e);
|
|
2089
|
+
t = Ae(r, i.workflows.map((e) => {
|
|
1869
2090
|
let t = e.definition, r = t.payloadSchema === void 0 ? {
|
|
1870
2091
|
required: [],
|
|
1871
2092
|
optional: []
|
|
@@ -1879,23 +2100,23 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1879
2100
|
} catch {
|
|
1880
2101
|
return;
|
|
1881
2102
|
}
|
|
1882
|
-
let n =
|
|
2103
|
+
let n = je(t);
|
|
1883
2104
|
if (n === null) return;
|
|
1884
2105
|
console.log("");
|
|
1885
2106
|
let r = t.issues.length > 0 ? "✗" : t.unchecked.length > 0 ? "•" : "✓";
|
|
1886
2107
|
console.log(`${r} ${n}`);
|
|
1887
|
-
},
|
|
2108
|
+
}, X = "voltro-authz-allowlist.txt", In = (e, t = (e) => {
|
|
1888
2109
|
try {
|
|
1889
2110
|
return C(e, "utf8");
|
|
1890
2111
|
} catch {
|
|
1891
2112
|
return "";
|
|
1892
2113
|
}
|
|
1893
|
-
}) => /* @__PURE__ */ new Set([...
|
|
2114
|
+
}) => /* @__PURE__ */ new Set([...Ze, ...Qe(L(e).map(t))]), Ln = (e, t) => {
|
|
1894
2115
|
let n = t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1895
2116
|
return new RegExp(String.raw`(?:export\s+)?const\s+([A-Za-z_$][\w$]*)\s*=\s*define[A-Za-z]*Event\s*\(\s*\{[^}]*?name\s*:\s*['"\`]${n}['"\`]`, "s").exec(e)?.[1];
|
|
1896
2117
|
}, Z = async (e) => {
|
|
1897
2118
|
try {
|
|
1898
|
-
let { discovered: t } = await
|
|
2119
|
+
let { discovered: t } = await U(e), n = t.events.map((e) => ({
|
|
1899
2120
|
name: e.descriptor.name,
|
|
1900
2121
|
file: e.file
|
|
1901
2122
|
})).filter((e) => typeof e.name == "string");
|
|
@@ -1909,22 +2130,22 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1909
2130
|
}, a = L(e).filter((e) => !r.has(e)).map(i).join("\n");
|
|
1910
2131
|
return n.filter(({ name: e, file: t }) => {
|
|
1911
2132
|
if (a.includes(e)) return !1;
|
|
1912
|
-
let n =
|
|
2133
|
+
let n = Ln(i(t), e);
|
|
1913
2134
|
return n === void 0 || !new RegExp(String.raw`\b${n}\b`).test(a);
|
|
1914
2135
|
}).map((e) => e.name).sort();
|
|
1915
2136
|
} catch {
|
|
1916
2137
|
return [];
|
|
1917
2138
|
}
|
|
1918
|
-
},
|
|
2139
|
+
}, Rn = async (e) => {
|
|
1919
2140
|
let t = await Z(e);
|
|
1920
2141
|
if (t.length !== 0) {
|
|
1921
2142
|
console.log(""), console.log(`• ${t.length} declared event(s) with no emit call site found:`);
|
|
1922
2143
|
for (let e of t) console.log(` ${e}`);
|
|
1923
2144
|
console.log(""), console.log(" An event you declare is an event partners can subscribe to. One that"), console.log(" never fires is indistinguishable, from their side, from a broken"), console.log(" endpoint of their own — so they debug your contract instead of"), console.log(" reading it."), console.log(" ADVISORY: this looks for the event name AND the identifier its"), console.log(" declaration binds it to, so `emit(ctx, apiKeyCreated, …)` counts. An"), console.log(" emit through an ASSEMBLED name still reads as missing here.");
|
|
1924
2145
|
}
|
|
1925
|
-
},
|
|
2146
|
+
}, zn = async (e) => {
|
|
1926
2147
|
try {
|
|
1927
|
-
let { loadApiConfig: t } = await import("./dev-
|
|
2148
|
+
let { loadApiConfig: t } = await import("./dev-Dff_pdik.js"), n = (await t(e))?.doctor?.scopeVocabulary;
|
|
1928
2149
|
if (typeof n != "string") return [];
|
|
1929
2150
|
let [r, i] = n.split("#");
|
|
1930
2151
|
if (r === void 0 || i === void 0) return [];
|
|
@@ -1941,7 +2162,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1941
2162
|
findings: []
|
|
1942
2163
|
});
|
|
1943
2164
|
try {
|
|
1944
|
-
let { offlineManifest: n, toInput: r } = await import("./checkCommand-
|
|
2165
|
+
let { offlineManifest: n, toInput: r } = await import("./checkCommand-C1EbNmwl.js"), { buildAppGraph: i, checkAppGraph: a } = await import("./appGraph-CFmFKHb2.js"), o = await n(e), s = r(o.manifest, o.tables), c = await zn(e), l = [.../* @__PURE__ */ new Set([...s.scopes ?? [], ...c])];
|
|
1945
2166
|
if (l.length === 0) {
|
|
1946
2167
|
try {
|
|
1947
2168
|
let { loadAppSchemaInputs: t } = await import("./frameworkTableAssembly-B96WCNJA.js");
|
|
@@ -1968,7 +2189,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1968
2189
|
} catch {
|
|
1969
2190
|
return t("app-not-importable");
|
|
1970
2191
|
}
|
|
1971
|
-
},
|
|
2192
|
+
}, Bn = async (e) => {
|
|
1972
2193
|
let { findings: t, evaluated: n, notEvaluated: r } = await Q(e);
|
|
1973
2194
|
if (!n) {
|
|
1974
2195
|
if (console.log(""), r === "app-not-importable") {
|
|
@@ -1983,7 +2204,7 @@ var le = /* @__PURE__ */ new Set([
|
|
|
1983
2204
|
for (let e of t) console.log(` ${e.node}${e.file === void 0 ? "" : ` ${e.file}`}`), console.log(` ${e.detail}`);
|
|
1984
2205
|
console.log(""), console.log(" Each of these is uncallable by every user in every role — not"), console.log(" misconfigured, DEAD — and nothing fails at boot to say so. The"), console.log(" usual cause is a typo or a rename that moved one side only."), console.log(` ${t[0].fix}`);
|
|
1985
2206
|
}
|
|
1986
|
-
},
|
|
2207
|
+
}, Vn = (e) => {
|
|
1987
2208
|
let t = v(e, "src");
|
|
1988
2209
|
if (!S(t)) return;
|
|
1989
2210
|
let n = [], r = (t, i = 0) => {
|
|
@@ -2014,12 +2235,12 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2014
2235
|
}
|
|
2015
2236
|
};
|
|
2016
2237
|
r(t);
|
|
2017
|
-
let i =
|
|
2238
|
+
let i = bt(vt(n));
|
|
2018
2239
|
if (i.length !== 0) {
|
|
2019
2240
|
console.log("");
|
|
2020
2241
|
for (let e of i) console.log(e);
|
|
2021
2242
|
}
|
|
2022
|
-
},
|
|
2243
|
+
}, Hn = async (e) => {
|
|
2023
2244
|
let t = ["src/locales", "locales"], n, r = [];
|
|
2024
2245
|
for (let i of t) {
|
|
2025
2246
|
let t = v(e, i);
|
|
@@ -2031,20 +2252,20 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2031
2252
|
if (n === void 0 || r.length === 0) return;
|
|
2032
2253
|
let i = [];
|
|
2033
2254
|
try {
|
|
2034
|
-
let { loadApiConfig: t } = await import("./dev-
|
|
2255
|
+
let { loadApiConfig: t } = await import("./dev-Dff_pdik.js");
|
|
2035
2256
|
i = (await t(e))?.locales ?? [];
|
|
2036
2257
|
} catch {
|
|
2037
2258
|
return;
|
|
2038
2259
|
}
|
|
2039
|
-
let a =
|
|
2260
|
+
let a = Ge({
|
|
2040
2261
|
catalogCodes: r,
|
|
2041
2262
|
declaredLocales: i
|
|
2042
2263
|
});
|
|
2043
2264
|
if (a !== void 0) {
|
|
2044
2265
|
console.log("");
|
|
2045
|
-
for (let e of
|
|
2266
|
+
for (let e of Ke(a, n)) console.log(e);
|
|
2046
2267
|
}
|
|
2047
|
-
},
|
|
2268
|
+
}, Un = async (e) => {
|
|
2048
2269
|
let t = v(e, "src");
|
|
2049
2270
|
if (!S(t)) return;
|
|
2050
2271
|
let n = !1, r = (e) => {
|
|
@@ -2063,9 +2284,9 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2063
2284
|
return;
|
|
2064
2285
|
}
|
|
2065
2286
|
a()?.reason === "binary-missing" ? (console.log("image pipeline: sharp is INSTALLED but its platform binary is missing —"), console.log(" an install that omitted optional dependencies drops the @img/* prebuilds."), console.log(" Fix: reinstall without omitting optional deps, or `pnpm add -D sharp` in this app.")) : (console.log("image pipeline: sharp is NOT installed — ?image imports serve originals (no srcSet, no blur)."), console.log(" Fix: `pnpm add -D sharp` in this app (it is an optional dependency of @voltro/cli;"), console.log(" your installer skipped optional dependencies)."));
|
|
2066
|
-
},
|
|
2287
|
+
}, Wn = async (e) => {
|
|
2067
2288
|
try {
|
|
2068
|
-
let { loadConfig: t } = await import("./webDev-
|
|
2289
|
+
let { loadConfig: t } = await import("./webDev-Bzb8ZFus.js"), n = (await t(e, { preferSource: !0 }))?.fonts;
|
|
2069
2290
|
if (n === void 0 || n.length === 0) return;
|
|
2070
2291
|
let { loadFontkit: r, loadSubsetFont: i } = await import("./fontPipeline-LxIHa1vo.js"), a = [];
|
|
2071
2292
|
if (await r() === null && a.push("fontkit (size-adjust fallback metrics — the CLS guard — are skipped)"), await i() === null && a.push("subset-font (declared `subsets:` ship the full files)"), console.log(""), a.length === 0) {
|
|
@@ -2075,25 +2296,25 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2075
2296
|
for (let e of a) console.log(`font pipeline: ${e}`);
|
|
2076
2297
|
console.log(" Fix: reinstall without omitting optional deps, or `pnpm add -D fontkit subset-font` in this app.");
|
|
2077
2298
|
} catch {}
|
|
2078
|
-
},
|
|
2299
|
+
}, Gn = async (e) => {
|
|
2079
2300
|
let t = v(e, "src", "pages");
|
|
2080
2301
|
if (!S(t)) return !1;
|
|
2081
2302
|
let n = [];
|
|
2082
2303
|
try {
|
|
2083
|
-
let { walkPagesTree: e } = await import("./webDev-
|
|
2304
|
+
let { walkPagesTree: e } = await import("./webDev-Bzb8ZFus.js");
|
|
2084
2305
|
n = (await e(t)).pages.map((e) => e.pattern);
|
|
2085
2306
|
} catch {
|
|
2086
2307
|
return !1;
|
|
2087
2308
|
}
|
|
2088
|
-
let r =
|
|
2309
|
+
let r = Je(e, n);
|
|
2089
2310
|
if (r === void 0) return !1;
|
|
2090
2311
|
console.log("");
|
|
2091
|
-
for (let e of
|
|
2312
|
+
for (let e of Ye(r)) console.log(e);
|
|
2092
2313
|
return r.problems.length > 0;
|
|
2093
|
-
},
|
|
2094
|
-
let { discovered: t } = await
|
|
2314
|
+
}, Kn = async (e) => {
|
|
2315
|
+
let { discovered: t } = await U(e), n = [];
|
|
2095
2316
|
try {
|
|
2096
|
-
let { loadApiConfig: t } = await import("./dev-
|
|
2317
|
+
let { loadApiConfig: t } = await import("./dev-Dff_pdik.js");
|
|
2097
2318
|
n = ((await t(e))?.plugins ?? []).map((e) => {
|
|
2098
2319
|
let t = (e.extendSchema?.tables ?? []).map((e) => {
|
|
2099
2320
|
let t = e;
|
|
@@ -2106,8 +2327,8 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2106
2327
|
plugin: e.name,
|
|
2107
2328
|
tables: t,
|
|
2108
2329
|
rpcTags: n,
|
|
2109
|
-
canDisableTables:
|
|
2110
|
-
canAlias:
|
|
2330
|
+
canDisableTables: qn.has(r),
|
|
2331
|
+
canAlias: Jn.has(r)
|
|
2111
2332
|
};
|
|
2112
2333
|
});
|
|
2113
2334
|
} catch {
|
|
@@ -2119,18 +2340,18 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2119
2340
|
...t.mutations,
|
|
2120
2341
|
...t.actions,
|
|
2121
2342
|
...t.streams ?? []
|
|
2122
|
-
].map((e) => String(e.descriptor.name)), i =
|
|
2343
|
+
].map((e) => String(e.descriptor.name)), i = dt(n, {
|
|
2123
2344
|
tables: t.tables.map((e) => e.tableName),
|
|
2124
2345
|
rpcTags: r
|
|
2125
2346
|
});
|
|
2126
2347
|
console.log();
|
|
2127
|
-
for (let e of
|
|
2128
|
-
},
|
|
2348
|
+
for (let e of ft(n, i)) console.log(e);
|
|
2349
|
+
}, qn = /* @__PURE__ */ new Set([
|
|
2129
2350
|
"@voltro/plugin-rbac",
|
|
2130
2351
|
"@voltro/plugin-audit",
|
|
2131
2352
|
"@voltro/plugin-notifications",
|
|
2132
2353
|
"aiFlows"
|
|
2133
|
-
]),
|
|
2354
|
+
]), Jn = /* @__PURE__ */ new Set([
|
|
2134
2355
|
"aiFlows",
|
|
2135
2356
|
"@voltro/plugin-audit",
|
|
2136
2357
|
"@voltro/plugin-billing",
|
|
@@ -2148,8 +2369,8 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2148
2369
|
"@voltro/plugin-sso-saml",
|
|
2149
2370
|
"@voltro/plugin-storage",
|
|
2150
2371
|
"@voltro/plugin-row-history"
|
|
2151
|
-
]), $ = 20,
|
|
2152
|
-
let t = await
|
|
2372
|
+
]), $ = 20, Yn = async (e) => {
|
|
2373
|
+
let t = await Xn(e), n = new Set(t.reviewed.map((e) => e.tag)), r = t.result.findings.filter((e) => e.verdict.kind === "allowlisted" && !n.has(e.tag)).length;
|
|
2153
2374
|
return {
|
|
2154
2375
|
executors: t.executorCount,
|
|
2155
2376
|
guardVocabulary: [...t.vocabulary].sort(),
|
|
@@ -2161,8 +2382,8 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2161
2382
|
},
|
|
2162
2383
|
unchecked: t.result.unchecked
|
|
2163
2384
|
};
|
|
2164
|
-
},
|
|
2165
|
-
let { discovered: t } = await
|
|
2385
|
+
}, Xn = async (e) => {
|
|
2386
|
+
let { discovered: t } = await U(e), n = /* @__PURE__ */ new Map(), r = (e) => {
|
|
2166
2387
|
if (!n.has(e)) try {
|
|
2167
2388
|
n.set(e, C(e, "utf8"));
|
|
2168
2389
|
} catch {
|
|
@@ -2201,12 +2422,12 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2201
2422
|
op: a?.op === "delete" || a?.op === "insert" ? a.op : t,
|
|
2202
2423
|
...a?.table === void 0 ? {} : { table: a.table }
|
|
2203
2424
|
};
|
|
2204
|
-
})), s = v(e,
|
|
2425
|
+
})), s = v(e, X), c = S(s) ? j(C(s, "utf8")) : void 0, l = !1;
|
|
2205
2426
|
for (let t of L(e)) if (/\bsetRowFilter\s*[<(]/.test(r(t))) {
|
|
2206
2427
|
l = !0;
|
|
2207
2428
|
break;
|
|
2208
2429
|
}
|
|
2209
|
-
let u =
|
|
2430
|
+
let u = it({
|
|
2210
2431
|
executors: o,
|
|
2211
2432
|
guardVocabulary: i,
|
|
2212
2433
|
tenantScopedTables: t.tenantScopedTables,
|
|
@@ -2223,23 +2444,23 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2223
2444
|
executorCount: o.length,
|
|
2224
2445
|
allowPath: s
|
|
2225
2446
|
};
|
|
2226
|
-
},
|
|
2227
|
-
let { result: n, vocabulary: r, existing: i, reviewed: a, executorCount: o, allowPath: s, rowFilterRegistered: c } = await
|
|
2447
|
+
}, Zn = async (e, t) => {
|
|
2448
|
+
let { result: n, vocabulary: r, existing: i, reviewed: a, executorCount: o, allowPath: s, rowFilterRegistered: c } = await Xn(e), l = n.counts;
|
|
2228
2449
|
console.log(`\nauthz scan · ${o} executor(s)`);
|
|
2229
|
-
let u = [...r].filter((e) => !
|
|
2450
|
+
let u = [...r].filter((e) => !Ze.has(e)).sort();
|
|
2230
2451
|
console.log(u.length === 0 ? " guard vocabulary: framework names only — no exported require*/assert* found in this app" : ` guard vocabulary: ${u.length} from your source (${u.slice(0, 6).join(", ")}${u.length > 6 ? ", …" : ""})`), console.log(` ✗ no access check ${String(l.unchecked).padStart(4)}`), console.log(` ⚠ inline ownership check, no named guard${String(l.inlineOwnership).padStart(4)} (informational)`), console.log(` ✓ guards: on the descriptor ${String(l.declaredGuard).padStart(4)}`), console.log(` ✓ calls a guard from the vocabulary ${String(l.vocabularyGuard).padStart(4)}`);
|
|
2231
2452
|
let d = new Set(a.map((e) => e.tag)), f = n.findings.filter((e) => e.verdict.kind === "allowlisted" && !d.has(e.tag)).length, p = l.allowlisted - f;
|
|
2232
|
-
if (console.log(` – accepted as recorded debt ${String(f).padStart(4)} (${
|
|
2233
|
-
let e = S(s) ? C(s, "utf8") : void 0, t = n.unchecked.map((e) => e.tag), r =
|
|
2234
|
-
return oe(s,
|
|
2453
|
+
if (console.log(` – accepted as recorded debt ${String(f).padStart(4)} (${X})`), console.log(` ✓ reviewed, open on purpose ${String(p).padStart(4)} (\`reviewed=<why>\` in that file)`), c && console.log(" ⓘ this app registers setRowFilter — the scan CANNOT see through it. A finding below may\n already be constrained; verify the filter covers that table and record it as `reviewed=`."), t) {
|
|
2454
|
+
let e = S(s) ? C(s, "utf8") : void 0, t = n.unchecked.map((e) => e.tag), r = ct(e, t);
|
|
2455
|
+
return oe(s, st(e, t), "utf8"), console.log(`\n${X}: +${r.added} new, ${r.kept} kept, ${r.removed} removed. Doctor now fails on ADDITIONS only.`), r.added === 0 && console.log(" (nothing new was unchecked — the file is unchanged.)"), !1;
|
|
2235
2456
|
}
|
|
2236
2457
|
if (n.unchecked.length === 0) return !1;
|
|
2237
2458
|
console.log("");
|
|
2238
2459
|
for (let e of n.unchecked.slice(0, $)) console.log(` ✗ ${e.tag} — ${e.why}\n ${e.path}`);
|
|
2239
|
-
return n.unchecked.length > $ && console.log(` … and ${n.unchecked.length - $} more — \`voltro doctor --json\` prints every one (\`authz.unchecked\`).`), i === void 0 ? (console.log(`\nNo ${
|
|
2240
|
-
},
|
|
2460
|
+
return n.unchecked.length > $ && console.log(` … and ${n.unchecked.length - $} more — \`voltro doctor --json\` prints every one (\`authz.unchecked\`).`), i === void 0 ? (console.log(`\nNo ${X} yet, so this run is advisory. To start the ratchet:`), console.log("\n voltro doctor --write-authz-allowlist\n"), console.log("That records today's unchecked handlers as DEBT and fails every run after on"), console.log("anything NEW. Fix a handler and its line stops mattering — the scan reports it as"), console.log("guarded whether or not the line is still there."), !1) : (console.log(`\n${n.unchecked.length} executor(s) with no access check are not in ${X}.`), console.log("Add a guard, or add the tag to that file if it is genuinely open."), console.log("\nBefore hand-rolling another check: `guards: [{ action, resourceType, resource }]`"), console.log("answers \"may this subject act on THIS row\" declaratively, and an app whose"), console.log("relationships live in its own tables registers its own tuple source rather than"), console.log("copying data into a framework table. See the authorization docs."), !0);
|
|
2461
|
+
}, Qn = async (e) => {
|
|
2241
2462
|
try {
|
|
2242
|
-
let { loadApiConfig: t } = await import("./dev-
|
|
2463
|
+
let { loadApiConfig: t } = await import("./dev-Dff_pdik.js"), { decidedSchemaReport: n } = await import("./doctorDecidedSchema-BlbWgCD_.js"), r = await t(e);
|
|
2243
2464
|
return r == null ? null : n({
|
|
2244
2465
|
...r.schema ? { declared: r.schema } : {},
|
|
2245
2466
|
...r.store === void 0 ? {} : { store: r.store },
|
|
@@ -2248,42 +2469,42 @@ var le = /* @__PURE__ */ new Set([
|
|
|
2248
2469
|
} catch {
|
|
2249
2470
|
return null;
|
|
2250
2471
|
}
|
|
2251
|
-
},
|
|
2252
|
-
let t = await
|
|
2472
|
+
}, $n = async (e) => {
|
|
2473
|
+
let t = await Qn(e);
|
|
2253
2474
|
if (t !== null) {
|
|
2254
2475
|
console.log(""), console.log("• framework tables whose presence is DECIDED rather than implied by your source tree:");
|
|
2255
2476
|
for (let e of t.text.split("\n")) console.log(` ${e}`);
|
|
2256
2477
|
}
|
|
2257
|
-
},
|
|
2478
|
+
}, er = async (e) => {
|
|
2258
2479
|
if (e.includes("--help") || e.includes("-h")) return console.log(bn), 0;
|
|
2259
2480
|
let t = e.includes("--strict"), n = e.find((e) => !e.startsWith("-")), a = b(n ?? process.cwd());
|
|
2260
2481
|
if (g(e)) return ee(), h({
|
|
2261
2482
|
...R(a),
|
|
2262
2483
|
spaCandidates: await z(a),
|
|
2263
|
-
pageConvention:
|
|
2484
|
+
pageConvention: V(a),
|
|
2264
2485
|
fileTaxonomy: re(a).findings,
|
|
2265
|
-
junctionFks: (await
|
|
2266
|
-
eventDelivery: await
|
|
2267
|
-
duplicateInstances:
|
|
2268
|
-
versionSkew:
|
|
2269
|
-
serverOnly: (await
|
|
2270
|
-
accessDecisions: await
|
|
2271
|
-
webhookVerification: await
|
|
2272
|
-
authz: await
|
|
2486
|
+
junctionFks: (await W(a))?.issues ?? [],
|
|
2487
|
+
eventDelivery: await G(a),
|
|
2488
|
+
duplicateInstances: r(a),
|
|
2489
|
+
versionSkew: c(a) ?? null,
|
|
2490
|
+
serverOnly: (await q(a)).status,
|
|
2491
|
+
accessDecisions: await J(a),
|
|
2492
|
+
webhookVerification: await Y(a),
|
|
2493
|
+
authz: await Yn(a),
|
|
2273
2494
|
ungrantedScopes: await Q(a),
|
|
2274
2495
|
neverEmittedEvents: await Z(a),
|
|
2275
|
-
unimportedDeps:
|
|
2496
|
+
unimportedDeps: Ue(a),
|
|
2276
2497
|
stalledRuns: await Nn(a),
|
|
2277
|
-
decidedSchema: await
|
|
2498
|
+
decidedSchema: await Qn(a)
|
|
2278
2499
|
}), 0;
|
|
2279
|
-
let s =
|
|
2280
|
-
|
|
2281
|
-
for (let e of Ue(
|
|
2282
|
-
await
|
|
2283
|
-
let
|
|
2500
|
+
let s = wt(a, t);
|
|
2501
|
+
cn(a), sn(a), yn(a), ne(a), await B(a), await Fn(a), await Pn(a), await Sn(a), await Dn(a), await En(a), await $n(a), await On(a), await Kn(a), await Bn(a), await Rn(a), console.log("");
|
|
2502
|
+
for (let e of We(Ue(a))) console.log(e);
|
|
2503
|
+
await Hn(a), Vn(a), await Un(a), await Wn(a);
|
|
2504
|
+
let l = await Mn(a), u = await Zn(a, e.includes("--write-authz-allowlist")), d = await kn(a), f = await jn(a), p = await Gn(a), m = o(c(a));
|
|
2284
2505
|
m !== void 0 && (console.log(""), console.log(m));
|
|
2285
|
-
let _ =
|
|
2286
|
-
return _ !== void 0 && console.log(`\n${_}`),
|
|
2506
|
+
let _ = i(r(a));
|
|
2507
|
+
return _ !== void 0 && console.log(`\n${_}`), l || u || d || p || f ? Math.max(s, 1) : s;
|
|
2287
2508
|
};
|
|
2288
2509
|
//#endregion
|
|
2289
|
-
export { z as C,
|
|
2510
|
+
export { z as C, Y as D, Q as E, V as S, zt as T, yn as _, Yn as a, wt as b, G as c, $t as d, St as f, cn as g, sn as h, J as i, In as l, wn as m, Ct as n, Z as o, W as p, ln as r, Ln as s, bn as t, R as u, B as v, q as w, en as x, er as y };
|