@desplega.ai/agent-swarm 1.129.0 → 1.131.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/README.md +2 -2
- package/dist/{actions-kfv2dawe.js → actions-w53mbns9.js} +11 -11
- package/dist/{anthropic-messages-3xgme8my.js → anthropic-messages-rjmd2e7n.js} +5 -5
- package/dist/{app-q8vjk6e8.js → app-m9gwqsqv.js} +8 -8
- package/dist/{artifact-hg4t1nx7.js → artifact-jysj3wrg.js} +2 -2
- package/dist/{assistant-g037r345.js → assistant-bp65m6f3.js} +13 -13
- package/dist/{azure-openai-responses-xa4sh9f6.js → azure-openai-responses-c0yjmbfd.js} +8 -5
- package/dist/{boot-reembed-18pzsrxa.js → boot-reembed-62p0at2k.js} +6 -6
- package/dist/{boot-reembed-wpks2cj8.js → boot-reembed-xmfp6wdh.js} +7 -7
- package/dist/{boot-scrub-logs-n7szd57r.js → boot-scrub-logs-rr8q2dms.js} +5 -5
- package/dist/{claude-adapter-qz4r0ajt.js → claude-adapter-2y47mrkd.js} +9 -9
- package/dist/{cli-mhjnbgb6.js → cli-0rcyq6d9.js} +450 -186
- package/dist/{cli-ttkmehy0.js → cli-2q72qz2s.js} +274 -25
- package/dist/{cli-gztgc3hz.js → cli-2wadx7p2.js} +2 -2
- package/dist/cli-3fj60etf.js +153 -0
- package/dist/{cli-7ecgm5v0.js → cli-3kf51j15.js} +1 -1
- package/dist/{cli-vgexpfsr.js → cli-57khth04.js} +6 -3
- package/dist/{cli-2mbe7vk0.js → cli-5dsbcjjw.js} +1 -1
- package/dist/{cli-etr62zy6.js → cli-5kx36evn.js} +2 -2
- package/dist/{cli-v2tr6amf.js → cli-5n6e5yfn.js} +30 -8
- package/dist/{cli-hx02s9zq.js → cli-5v4rw6yd.js} +2 -2
- package/dist/{cli-v37yr6mf.js → cli-5ze9rv97.js} +4 -4
- package/dist/{cli-ch7t5v7n.js → cli-6map995v.js} +9 -4
- package/dist/{cli-h0457a67.js → cli-70xqj0z3.js} +3 -3
- package/dist/{cli-kk4f9r17.js → cli-72q8m8gk.js} +8 -6
- package/dist/{cli-7padk69a.js → cli-78xwvkhj.js} +2 -2
- package/dist/{cli-dxtxacy7.js → cli-9dr5qzc0.js} +45 -8
- package/dist/{cli-17zxdgsq.js → cli-a40rnf71.js} +6 -6
- package/dist/{cli-t53vnnxz.js → cli-a4jzdpa3.js} +2514 -1055
- package/dist/{cli-w10fkrf1.js → cli-akdvwc9v.js} +354 -115
- package/dist/{cli-1qkk5er0.js → cli-bmze986d.js} +1 -1
- package/dist/{cli-ga12dc1d.js → cli-bqw0mt1n.js} +3 -3
- package/dist/{cli-0sf92efp.js → cli-cdeg08wx.js} +1 -1
- package/dist/{cli-a8ynhkyj.js → cli-cvgjwnh1.js} +17 -15
- package/dist/{cli-9fxg3v5m.js → cli-d2tfkcga.js} +4 -4
- package/dist/{cli-nhcd7x43.js → cli-d3x3x1c9.js} +2 -2
- package/dist/{cli-6nh2qxvh.js → cli-darcwax3.js} +1 -1
- package/dist/{cli-yjbgmysx.js → cli-e7ckcg4v.js} +12 -12
- package/dist/{cli-4n2gcjpd.js → cli-efxfnq6q.js} +4 -3
- package/dist/{cli-z9xqqhfk.js → cli-er3a4bb0.js} +1 -1
- package/dist/{cli-xg2eezyv.js → cli-f1am9szv.js} +1 -1
- package/dist/{cli-xy4cwsm9.js → cli-fywms69x.js} +1 -1
- package/dist/{cli-33jj76y8.js → cli-g6b8x1h8.js} +1 -1
- package/dist/{cli-epsvdckx.js → cli-gm9cbhbq.js} +20 -10
- package/dist/{cli-rkndnn90.js → cli-k9qkf1hw.js} +6 -4
- package/dist/{cli-zejvt395.js → cli-kh3ba2zf.js} +1 -1
- package/dist/{cli-gb25p1h2.js → cli-nm5gtp1x.js} +2 -2
- package/dist/{cli-akxnpx17.js → cli-pm6xbh84.js} +1829 -1629
- package/dist/{cli-2k0ztbfp.js → cli-psh3c4va.js} +1 -1
- package/dist/{cli-39vgrsep.js → cli-qv61hp37.js} +2 -2
- package/dist/{cli-hv2fndhm.js → cli-r6kqqbj0.js} +6 -4
- package/dist/{cli-1y1cm570.js → cli-rzbpmxdr.js} +1 -1
- package/dist/{cli-mmrk00vp.js → cli-t1xze5qh.js} +1 -1
- package/dist/{cli-g252a9ky.js → cli-t55yw3a1.js} +2 -2
- package/dist/{cli-7bz8dzqa.js → cli-t76vw5db.js} +1184 -1522
- package/dist/{cli-4n4mdv21.js → cli-xpxde7rm.js} +7 -3
- package/dist/{cli-fpaa5k2q.js → cli-yw8vghx2.js} +54 -18
- package/dist/cli-zsspvvm2.js +490 -0
- package/dist/cli.js +27 -25
- package/dist/{codex-adapter-7v6t7ff6.js → codex-adapter-d24q75wk.js} +7 -7
- package/dist/{codex-hook-amndawyb.js → codex-hook-hq54t9ft.js} +2 -2
- package/dist/{codex-session-runner-e7j4khe2.js → codex-session-runner-g50vcsex.js} +7 -7
- package/dist/{commands-ex0k5tbf.js → commands-c3nrc5hg.js} +5 -5
- package/dist/{db-df7jatfc.js → db-nt7fg3tw.js} +5 -5
- package/dist/{google-generative-ai-y42hnw9p.js → google-generative-ai-hysrd8qx.js} +7 -5
- package/dist/{google-vertex-4sg66gb6.js → google-vertex-p5arrga0.js} +7 -5
- package/dist/{handlers-1j2cfqt2.js → handlers-fkr6swat.js} +13 -13
- package/dist/{hook-nx9a0mj3.js → hook-77wpvnjc.js} +7 -7
- package/dist/{hook-w6yaf6sy.js → hook-g019yehy.js} +8 -8
- package/dist/{http-4tz5h8wg.js → http-jewj0syk.js} +2993 -716
- package/dist/{index-0bpkzb09.js → index-070v4eyb.js} +3 -3
- package/dist/{index-0s67qv7h.js → index-6gm5he8h.js} +11 -11
- package/dist/{index-35gtv6gj.js → index-7n2xpbd4.js} +310 -40
- package/dist/{index-ker3gccb.js → index-9znhar3x.js} +4 -4
- package/dist/{index-5n2c8yay.js → index-hase6zbe.js} +2 -2
- package/dist/{index-kcf3tm9h.js → index-hfvggd0z.js} +12 -12
- package/dist/{index-7c0jqna0.js → index-hp1kdbjj.js} +13 -13
- package/dist/{keepalive-3j4a9168.js → keepalive-j0fjvqfd.js} +7 -7
- package/dist/{lead-6kpevymb.js → lead-1n8x30xe.js} +33 -33
- package/dist/{maintenance-m1k82ean.js → maintenance-gvev11sa.js} +7 -7
- package/dist/{mistral-conversations-bjkdfb6z.js → mistral-conversations-81fwav0j.js} +6 -6
- package/dist/{oauth-refresh-sweep-881k8e4q.js → oauth-refresh-sweep-s9ecsvh0.js} +6 -6
- package/dist/{onboard-c0ykffjn.js → onboard-pvm5b38w.js} +2 -2
- package/dist/{openai-codex-responses-xetseqvt.js → openai-codex-responses-5g27pd6f.js} +43 -23
- package/dist/{openai-completions-5r2g5axa.js → openai-completions-3vkmfz2a.js} +55 -11
- package/dist/{openai-responses-ce67hd23.js → openai-responses-dg4t7j7a.js} +8 -5
- package/dist/{openrouter-images-pzfp22jb.js → openrouter-images-g3gm8931.js} +1 -1
- package/dist/{otel-impl-sqagjerv.js → otel-impl-p6jvgd9c.js} +6 -4
- package/dist/{otel-3mp81ppd.js → otel-nqa12wf3.js} +2 -2
- package/dist/{pi-mono-adapter-k584k16g.js → pi-mono-adapter-t091s27g.js} +17117 -7517
- package/dist/{pricing-refresh-y82whbf9.js → pricing-refresh-k49rcyed.js} +7 -7
- package/dist/{rbac-roles-nvkqmzyd.js → rbac-roles-30pspvy7.js} +7 -7
- package/dist/{rbac-roles-4ht8gegc.js → rbac-roles-cr80g96t.js} +6 -6
- package/dist/{render-v2-wvqdgvvp.js → render-v2-xm457ng1.js} +8 -8
- package/dist/{seed-pricing-fy3rxhde.js → seed-pricing-yhpv35fr.js} +6 -6
- package/dist/{setup-ak5cnc6f.js → setup-nytnmwwr.js} +2 -2
- package/dist/{worker-d8769q8a.js → worker-msytr2cw.js} +33 -33
- package/openapi.json +34039 -11036
- package/package.json +8 -6
- package/src/apps/definition.ts +368 -26
- package/src/apps/row-store.ts +66 -10
- package/src/apps/schema-migrate.ts +95 -1
- package/src/apps/store.ts +13 -4
- package/src/apps/sync-run-as.ts +18 -0
- package/src/apps/sync.ts +934 -0
- package/src/apps/version.ts +16 -2
- package/src/assets/key.ts +8 -1
- package/src/be/asset-key-audit.ts +3 -1
- package/src/be/db-queries/mcp-oauth.ts +297 -24
- package/src/be/db.ts +42 -1
- package/src/be/migrations/129_asset_keys_apps_scripts.sql +161 -0
- package/src/be/scripts/db.ts +5 -2
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/seed-scripts/catalog/app-sync-run.ts +32 -0
- package/src/be/seed-scripts/catalog/github-issues-pull.ts +102 -0
- package/src/be/seed-scripts/index.ts +18 -0
- package/src/be/seed-skills/index.ts +7 -0
- package/src/http/active-sessions.ts +26 -18
- package/src/http/agents.ts +94 -27
- package/src/http/api-keys.ts +91 -17
- package/src/http/approval-requests.ts +87 -10
- package/src/http/apps.ts +361 -53
- package/src/http/assets.ts +165 -31
- package/src/http/budgets.ts +7 -5
- package/src/http/codex-oauth-keep-warm.ts +21 -3
- package/src/http/config.ts +46 -16
- package/src/http/context.ts +33 -6
- package/src/http/ecosystem.ts +20 -6
- package/src/http/events.ts +24 -9
- package/src/http/favorites.ts +20 -6
- package/src/http/fs.ts +60 -17
- package/src/http/heartbeat.ts +18 -4
- package/src/http/inbox-state.ts +12 -6
- package/src/http/integrations.ts +25 -5
- package/src/http/kv.ts +36 -15
- package/src/http/mcp-bridge.ts +5 -1
- package/src/http/mcp-oauth.ts +332 -17
- package/src/http/mcp-servers.ts +56 -18
- package/src/http/memory.ts +282 -29
- package/src/http/metrics.ts +80 -17
- package/src/http/oauth-callback.ts +10 -4
- package/src/http/oauth-generic.ts +5 -1
- package/src/http/oauth-locks.ts +6 -3
- package/src/http/openapi.ts +57 -9
- package/src/http/page-proxy.ts +25 -5
- package/src/http/pages-public.ts +37 -20
- package/src/http/pages.ts +93 -28
- package/src/http/poll.ts +89 -5
- package/src/http/pricing.ts +9 -6
- package/src/http/prompt-templates.ts +85 -21
- package/src/http/route-def.ts +67 -4
- package/src/http/schedules.ts +63 -14
- package/src/http/script-connection-proxy.ts +30 -4
- package/src/http/script-connections.ts +393 -43
- package/src/http/script-runs.ts +73 -19
- package/src/http/scripts.ts +257 -39
- package/src/http/session-data.ts +87 -14
- package/src/http/sessions.ts +80 -5
- package/src/http/skills.ts +115 -35
- package/src/http/stats.ts +94 -13
- package/src/http/task-templates.ts +6 -4
- package/src/http/tasks.ts +230 -61
- package/src/http/trackers/jira.ts +90 -30
- package/src/http/trackers/linear.ts +46 -12
- package/src/http/users.ts +162 -25
- package/src/http/utils.ts +12 -2
- package/src/http/webhooks.ts +30 -16
- package/src/http/workflow-events.ts +18 -5
- package/src/http/workflows.ts +128 -39
- package/src/http/x.ts +37 -6
- package/src/oauth/ensure-mcp-token.ts +16 -1
- package/src/oauth/mcp-wrapper.ts +281 -26
- package/src/providers/pi-mono-adapter.ts +1 -1
- package/src/scripts-runtime/credential-broker/README.md +1 -1
- package/src/scripts-runtime/credential-broker/fetch-patch.ts +12 -2
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/stdlib/fetch.ts +6 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/server.ts +2 -0
- package/src/tests/apps-rbac.test.ts +110 -0
- package/src/tests/apps-spike2.test.ts +4 -1
- package/src/tests/apps-sync-engine.test.ts +2540 -0
- package/src/tests/apps-sync.test.ts +1627 -0
- package/src/tests/asset-key-api.test.ts +48 -2
- package/src/tests/asset-key-invariants.test.ts +92 -0
- package/src/tests/asset-key-migration.test.ts +174 -8
- package/src/tests/asset-key-normalization.test.ts +2 -0
- package/src/tests/credential-broker.test.ts +27 -2
- package/src/tests/mcp-oauth-dcr-reuse.test.ts +743 -0
- package/src/tests/mcp-oauth-ensure-token.test.ts +45 -0
- package/src/tests/mcp-oauth-manual-client.test.ts +135 -2
- package/src/tests/mcp-oauth-queries.test.ts +153 -0
- package/src/tests/mcp-oauth-wrapper.test.ts +432 -0
- package/src/tests/memory-http-recall-gating.test.ts +2 -0
- package/src/tests/openapi-response-contract.test.ts +138 -0
- package/src/tests/rbac-admission-e2e.test.ts +68 -0
- package/src/tests/script-connections.test.ts +3 -0
- package/src/tests/scripts-runtime-fetch.test.ts +121 -0
- package/src/tests/scripts-runtime-secret-egress.test.ts +4 -2
- package/src/tests/seed-scripts.test.ts +2 -2
- package/src/tests/swarm-tool-result-gate.test.ts +32 -0
- package/src/tests/task-working-dir.test.ts +8 -4
- package/src/tests/whoami-route.test.ts +127 -0
- package/src/tests/workflow-engine-v2.test.ts +80 -7
- package/src/tests/workflow-swarm-script.test.ts +104 -0
- package/src/tools/app-get.ts +10 -2
- package/src/tools/app-rollback.ts +1 -0
- package/src/tools/app-sync.ts +112 -0
- package/src/tools/script-common.ts +20 -0
- package/src/tools/tool-config.ts +2 -1
- package/src/tools/utils.ts +11 -0
- package/src/tools/workflows/create-workflow.ts +4 -1
- package/src/types.ts +1394 -1206
- package/src/utils/template.ts +8 -1
- package/src/utils/zod-openapi.ts +11 -0
- package/src/workflows/engine.ts +27 -4
- package/src/workflows/executors/swarm-script.ts +28 -0
- package/src/workflows/retry-poller.ts +19 -2
- package/templates/skills/apps/content.md +94 -5
- package/templates/skills/asset-namespaces/content.md +2 -2
- package/templates/skills/scheduled-task-resilience/SKILL.md +102 -0
- package/templates/skills/scheduled-task-resilience/config.json +14 -0
- package/templates/skills/scheduled-task-resilience/content.md +97 -0
- package/dist/cli-7wmybrt5.js +0 -115
- package/dist/cli-d91pvmq1.js +0 -14
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
LlmRater,
|
|
8
8
|
REFERENCES_SOURCE_MAX_LENGTH,
|
|
9
9
|
sanitizeReferencesSource
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-2wadx7p2.js";
|
|
11
11
|
import {
|
|
12
12
|
createTrackerAgentMapping,
|
|
13
13
|
createTrackerSync,
|
|
@@ -22,32 +22,34 @@ import {
|
|
|
22
22
|
repointTrackerSyncBySwarmId,
|
|
23
23
|
updateTrackerSync,
|
|
24
24
|
updateTrackerSyncSwarmId
|
|
25
|
-
} from "./cli-
|
|
25
|
+
} from "./cli-nm5gtp1x.js";
|
|
26
26
|
import {
|
|
27
27
|
calculateNextRun,
|
|
28
28
|
ensure,
|
|
29
29
|
require_dist,
|
|
30
30
|
runScheduleNow
|
|
31
|
-
} from "./cli-
|
|
31
|
+
} from "./cli-5ze9rv97.js";
|
|
32
32
|
import {
|
|
33
33
|
startPricingRefreshLoop
|
|
34
|
-
} from "./cli-
|
|
34
|
+
} from "./cli-t55yw3a1.js";
|
|
35
35
|
import {
|
|
36
36
|
seedPricingFromModelsDev
|
|
37
|
-
} from "./cli-
|
|
37
|
+
} from "./cli-t1xze5qh.js";
|
|
38
38
|
import {
|
|
39
39
|
ensureRbacSeedsSynced,
|
|
40
40
|
getUserGrant
|
|
41
|
-
} from "./cli-
|
|
41
|
+
} from "./cli-5v4rw6yd.js";
|
|
42
42
|
import {
|
|
43
43
|
can,
|
|
44
44
|
decideAdmission,
|
|
45
45
|
isRbacEnabled
|
|
46
|
-
} from "./cli-
|
|
46
|
+
} from "./cli-bqw0mt1n.js";
|
|
47
47
|
import {
|
|
48
48
|
AppDefinitionSchema,
|
|
49
49
|
AppElementsSchema,
|
|
50
50
|
AppNameSchema,
|
|
51
|
+
ColumnKindSchema,
|
|
52
|
+
SORTABLE_SYSTEM_DATE_COLUMNS,
|
|
51
53
|
SYSTEM_COLUMN_KINDS,
|
|
52
54
|
appDefinitionNeedsRepair,
|
|
53
55
|
applyAppDefinitionPatch,
|
|
@@ -59,10 +61,11 @@ import {
|
|
|
59
61
|
isIso8601Date,
|
|
60
62
|
listApps,
|
|
61
63
|
parseAppDefinition,
|
|
64
|
+
resolveSyncRunAs,
|
|
62
65
|
runSavedScriptAsAgent,
|
|
63
66
|
updateApp,
|
|
64
67
|
upgradeAppDefinition
|
|
65
|
-
} from "./cli-
|
|
68
|
+
} from "./cli-2q72qz2s.js";
|
|
66
69
|
import {
|
|
67
70
|
TriggerSchemaError,
|
|
68
71
|
applyDefinitionPatch,
|
|
@@ -75,7 +78,7 @@ import {
|
|
|
75
78
|
startWorkflowExecution,
|
|
76
79
|
validateDefinition,
|
|
77
80
|
validateJsonSchema
|
|
78
|
-
} from "./cli-
|
|
81
|
+
} from "./cli-yw8vghx2.js";
|
|
79
82
|
import {
|
|
80
83
|
ConnectionAuthInputSchema,
|
|
81
84
|
SCRIPT_LONG_TIMEOUT_HINT_MS,
|
|
@@ -94,7 +97,7 @@ import {
|
|
|
94
97
|
setScriptConnectionEnabled,
|
|
95
98
|
upsertCredentialBinding,
|
|
96
99
|
upsertScriptConnection
|
|
97
|
-
} from "./cli-
|
|
100
|
+
} from "./cli-pm6xbh84.js";
|
|
98
101
|
import {
|
|
99
102
|
getApiKey
|
|
100
103
|
} from "./cli-f14fvzag.js";
|
|
@@ -109,7 +112,7 @@ import {
|
|
|
109
112
|
isGraphExpansionEnabled,
|
|
110
113
|
rerank,
|
|
111
114
|
rowToCandidate
|
|
112
|
-
} from "./cli-
|
|
115
|
+
} from "./cli-rzbpmxdr.js";
|
|
113
116
|
import {
|
|
114
117
|
buildAuthorizationUrl,
|
|
115
118
|
createOAuthApp,
|
|
@@ -124,7 +127,7 @@ import {
|
|
|
124
127
|
listAuthorizationsForApp,
|
|
125
128
|
onAuthorizationRefreshed,
|
|
126
129
|
upsertOAuthApp
|
|
127
|
-
} from "./cli-
|
|
130
|
+
} from "./cli-g6b8x1h8.js";
|
|
128
131
|
import {
|
|
129
132
|
ZodFirstPartyTypeKind,
|
|
130
133
|
objectType
|
|
@@ -133,7 +136,7 @@ import {
|
|
|
133
136
|
createAdditiveBuffer,
|
|
134
137
|
extractSlackMessageText,
|
|
135
138
|
parseSlackTs
|
|
136
|
-
} from "./cli-
|
|
139
|
+
} from "./cli-d3x3x1c9.js";
|
|
137
140
|
import {
|
|
138
141
|
findOrCreateUserByEmail,
|
|
139
142
|
findUserByExternalId,
|
|
@@ -149,10 +152,10 @@ import {
|
|
|
149
152
|
resolveIdentityByEmail,
|
|
150
153
|
resolveUserByToken,
|
|
151
154
|
unlinkIdentity
|
|
152
|
-
} from "./cli-
|
|
155
|
+
} from "./cli-psh3c4va.js";
|
|
153
156
|
import {
|
|
154
157
|
createTaskWithSiblingAwareness
|
|
155
|
-
} from "./cli-
|
|
158
|
+
} from "./cli-cdeg08wx.js";
|
|
156
159
|
import {
|
|
157
160
|
getAgentDisplayName,
|
|
158
161
|
getAgentEmoji,
|
|
@@ -161,8 +164,10 @@ import {
|
|
|
161
164
|
markdownToSlack,
|
|
162
165
|
startSlackApp,
|
|
163
166
|
stopSlackApp
|
|
164
|
-
} from "./cli-
|
|
167
|
+
} from "./cli-cvgjwnh1.js";
|
|
165
168
|
import {
|
|
169
|
+
$OpenAPIRegistry,
|
|
170
|
+
$OpenApiGeneratorV31,
|
|
166
171
|
AgentAvatarSchema,
|
|
167
172
|
AgentMemoryScopeSchema,
|
|
168
173
|
AgentMemorySourceSchema,
|
|
@@ -332,6 +337,7 @@ import {
|
|
|
332
337
|
init_credential_broker,
|
|
333
338
|
init_db,
|
|
334
339
|
init_defaults,
|
|
340
|
+
init_dist,
|
|
335
341
|
init_key,
|
|
336
342
|
init_request_auth_context,
|
|
337
343
|
init_slack_routing,
|
|
@@ -339,6 +345,7 @@ import {
|
|
|
339
345
|
init_swarm_config_guard,
|
|
340
346
|
init_task_lifecycle_events,
|
|
341
347
|
init_types,
|
|
348
|
+
init_zod_openapi,
|
|
342
349
|
insertTaskAttachment,
|
|
343
350
|
installMcpServer,
|
|
344
351
|
installSkill,
|
|
@@ -403,7 +410,7 @@ import {
|
|
|
403
410
|
upsertService,
|
|
404
411
|
upsertSwarmConfig,
|
|
405
412
|
validateConfigValue
|
|
406
|
-
} from "./cli-
|
|
413
|
+
} from "./cli-a4jzdpa3.js";
|
|
407
414
|
import {
|
|
408
415
|
getTemplateDefinition,
|
|
409
416
|
init_env_flag,
|
|
@@ -415,7 +422,7 @@ import {
|
|
|
415
422
|
parseEnvFlag,
|
|
416
423
|
registerTemplate,
|
|
417
424
|
resolveTemplate
|
|
418
|
-
} from "./cli-
|
|
425
|
+
} from "./cli-xpxde7rm.js";
|
|
419
426
|
import {
|
|
420
427
|
MAX_PROFILE_FILE_LENGTH,
|
|
421
428
|
getAppUrl,
|
|
@@ -424,8 +431,9 @@ import {
|
|
|
424
431
|
init_constants
|
|
425
432
|
} from "./cli-x23me2mg.js";
|
|
426
433
|
import {
|
|
434
|
+
exports_zod,
|
|
427
435
|
init_zod
|
|
428
|
-
} from "./cli-
|
|
436
|
+
} from "./cli-zsspvvm2.js";
|
|
429
437
|
import {
|
|
430
438
|
init_secret_scrubber,
|
|
431
439
|
refreshSecretScrubberCache,
|
|
@@ -436,7 +444,7 @@ import {
|
|
|
436
444
|
import {
|
|
437
445
|
init_package,
|
|
438
446
|
package_default
|
|
439
|
-
} from "./cli-
|
|
447
|
+
} from "./cli-72q8m8gk.js";
|
|
440
448
|
import {
|
|
441
449
|
$ZodObject,
|
|
442
450
|
$ZodType,
|
|
@@ -475,7 +483,7 @@ import {
|
|
|
475
483
|
union,
|
|
476
484
|
unknown,
|
|
477
485
|
uuid
|
|
478
|
-
} from "./cli-
|
|
486
|
+
} from "./cli-5dsbcjjw.js";
|
|
479
487
|
import {
|
|
480
488
|
init_event_bus,
|
|
481
489
|
workflowEventBus
|
|
@@ -22893,7 +22901,7 @@ async function notifySlack(text) {
|
|
|
22893
22901
|
return;
|
|
22894
22902
|
}
|
|
22895
22903
|
try {
|
|
22896
|
-
const { getSlackApp: getSlackApp2 } = await import("./app-
|
|
22904
|
+
const { getSlackApp: getSlackApp2 } = await import("./app-m9gwqsqv.js");
|
|
22897
22905
|
const app = getSlackApp2();
|
|
22898
22906
|
if (!app) {
|
|
22899
22907
|
console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
|
|
@@ -22964,7 +22972,7 @@ async function deleteJiraWebhook(webhookId) {
|
|
|
22964
22972
|
console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
|
|
22965
22973
|
}
|
|
22966
22974
|
async function overwriteWebhookIds(next) {
|
|
22967
|
-
const { getDb: getDb2 } = await import("./db-
|
|
22975
|
+
const { getDb: getDb2 } = await import("./db-nt7fg3tw.js");
|
|
22968
22976
|
const db = getDb2();
|
|
22969
22977
|
const txn = db.transaction(() => {
|
|
22970
22978
|
const row = db.query("SELECT metadata FROM oauth_apps WHERE provider = 'jira'").get();
|
|
@@ -95816,1431 +95824,10 @@ function isActiveUser(user) {
|
|
|
95816
95824
|
return !!user && user.status === "active";
|
|
95817
95825
|
}
|
|
95818
95826
|
|
|
95819
|
-
// node_modules/@asteasolutions/zod-to-openapi/dist/index.cjs
|
|
95820
|
-
function __rest(s, e) {
|
|
95821
|
-
var t = {};
|
|
95822
|
-
for (var p in s)
|
|
95823
|
-
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
95824
|
-
t[p] = s[p];
|
|
95825
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
95826
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s);i < p.length; i++) {
|
|
95827
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
95828
|
-
t[p[i]] = s[p[i]];
|
|
95829
|
-
}
|
|
95830
|
-
return t;
|
|
95831
|
-
}
|
|
95832
|
-
var ZodTypeKeys = {
|
|
95833
|
-
ZodAny: "any",
|
|
95834
|
-
ZodArray: "array",
|
|
95835
|
-
ZodBigInt: "bigint",
|
|
95836
|
-
ZodBoolean: "boolean",
|
|
95837
|
-
ZodDefault: "default",
|
|
95838
|
-
ZodPrefault: "prefault",
|
|
95839
|
-
ZodTransform: "transform",
|
|
95840
|
-
ZodEnum: "enum",
|
|
95841
|
-
ZodIntersection: "intersection",
|
|
95842
|
-
ZodLazy: "lazy",
|
|
95843
|
-
ZodLiteral: "literal",
|
|
95844
|
-
ZodNever: "never",
|
|
95845
|
-
ZodNull: "null",
|
|
95846
|
-
ZodNullable: "nullable",
|
|
95847
|
-
ZodNumber: "number",
|
|
95848
|
-
ZodNonOptional: "nonoptional",
|
|
95849
|
-
ZodObject: "object",
|
|
95850
|
-
ZodOptional: "optional",
|
|
95851
|
-
ZodPipe: "pipe",
|
|
95852
|
-
ZodReadonly: "readonly",
|
|
95853
|
-
ZodRecord: "record",
|
|
95854
|
-
ZodString: "string",
|
|
95855
|
-
ZodTuple: "tuple",
|
|
95856
|
-
ZodType: "type",
|
|
95857
|
-
ZodUnion: "union",
|
|
95858
|
-
ZodDiscriminatedUnion: "union",
|
|
95859
|
-
ZodUnknown: "unknown",
|
|
95860
|
-
ZodVoid: "void",
|
|
95861
|
-
ZodDate: "date",
|
|
95862
|
-
ZodTemplateLiteral: "template_literal"
|
|
95863
|
-
};
|
|
95864
|
-
function isZodType(schema, typeNames) {
|
|
95865
|
-
const typeNamesArray = Array.isArray(typeNames) ? typeNames : [typeNames];
|
|
95866
|
-
return typeNamesArray.some((typeName) => {
|
|
95867
|
-
var _a;
|
|
95868
|
-
const typeNameMatch = ((_a = schema === null || schema === undefined ? undefined : schema.def) === null || _a === undefined ? undefined : _a.type) === ZodTypeKeys[typeName];
|
|
95869
|
-
if (typeName === "ZodDiscriminatedUnion") {
|
|
95870
|
-
return typeNameMatch && "discriminator" in schema.def;
|
|
95871
|
-
}
|
|
95872
|
-
return typeNameMatch;
|
|
95873
|
-
});
|
|
95874
|
-
}
|
|
95875
|
-
function isAnyZodType(schema) {
|
|
95876
|
-
return schema && "def" in schema;
|
|
95877
|
-
}
|
|
95878
|
-
function isNullableSchema(schema) {
|
|
95879
|
-
return schema.safeParse(null).success;
|
|
95880
|
-
}
|
|
95881
|
-
function isOptionalSchema(schema) {
|
|
95882
|
-
return schema.safeParse(undefined).success;
|
|
95883
|
-
}
|
|
95884
|
-
|
|
95885
|
-
class $ZodRegistry {
|
|
95886
|
-
constructor() {
|
|
95887
|
-
this._map = new Map;
|
|
95888
|
-
this._idmap = new Map;
|
|
95889
|
-
}
|
|
95890
|
-
add(schema, ..._meta) {
|
|
95891
|
-
const meta2 = _meta[0];
|
|
95892
|
-
this._map.set(schema, meta2);
|
|
95893
|
-
if (meta2 && typeof meta2 === "object" && "id" in meta2) {
|
|
95894
|
-
if (this._idmap.has(meta2.id)) {
|
|
95895
|
-
throw new Error(`ID ${meta2.id} already exists in the registry`);
|
|
95896
|
-
}
|
|
95897
|
-
this._idmap.set(meta2.id, schema);
|
|
95898
|
-
}
|
|
95899
|
-
return this;
|
|
95900
|
-
}
|
|
95901
|
-
clear() {
|
|
95902
|
-
this._map = new Map;
|
|
95903
|
-
this._idmap = new Map;
|
|
95904
|
-
return this;
|
|
95905
|
-
}
|
|
95906
|
-
remove(schema) {
|
|
95907
|
-
const meta2 = this._map.get(schema);
|
|
95908
|
-
if (meta2 && typeof meta2 === "object" && "id" in meta2) {
|
|
95909
|
-
this._idmap.delete(meta2.id);
|
|
95910
|
-
}
|
|
95911
|
-
this._map.delete(schema);
|
|
95912
|
-
return this;
|
|
95913
|
-
}
|
|
95914
|
-
get(schema) {
|
|
95915
|
-
const p = schema._zod.parent;
|
|
95916
|
-
if (p) {
|
|
95917
|
-
const pm = { ...this.get(p) ?? {} };
|
|
95918
|
-
delete pm.id;
|
|
95919
|
-
return { ...pm, ...this._map.get(schema) };
|
|
95920
|
-
}
|
|
95921
|
-
return this._map.get(schema);
|
|
95922
|
-
}
|
|
95923
|
-
has(schema) {
|
|
95924
|
-
return this._map.has(schema);
|
|
95925
|
-
}
|
|
95926
|
-
}
|
|
95927
|
-
function registry() {
|
|
95928
|
-
return new $ZodRegistry;
|
|
95929
|
-
}
|
|
95930
|
-
function isEqual(x, y) {
|
|
95931
|
-
if (x === null || x === undefined || y === null || y === undefined) {
|
|
95932
|
-
return x === y;
|
|
95933
|
-
}
|
|
95934
|
-
if (x === y || x.valueOf() === y.valueOf()) {
|
|
95935
|
-
return true;
|
|
95936
|
-
}
|
|
95937
|
-
if (Array.isArray(x)) {
|
|
95938
|
-
if (!Array.isArray(y)) {
|
|
95939
|
-
return false;
|
|
95940
|
-
}
|
|
95941
|
-
if (x.length !== y.length) {
|
|
95942
|
-
return false;
|
|
95943
|
-
}
|
|
95944
|
-
}
|
|
95945
|
-
if (!(x instanceof Object) || !(y instanceof Object)) {
|
|
95946
|
-
return false;
|
|
95947
|
-
}
|
|
95948
|
-
const keysX = Object.keys(x);
|
|
95949
|
-
return Object.keys(y).every((keyY) => keysX.indexOf(keyY) !== -1) && keysX.every((key) => isEqual(x[key], y[key]));
|
|
95950
|
-
}
|
|
95951
|
-
|
|
95952
|
-
class ObjectSet {
|
|
95953
|
-
constructor() {
|
|
95954
|
-
this.buckets = new Map;
|
|
95955
|
-
}
|
|
95956
|
-
put(value) {
|
|
95957
|
-
const hashCode = this.hashCodeOf(value);
|
|
95958
|
-
const itemsByCode = this.buckets.get(hashCode);
|
|
95959
|
-
if (!itemsByCode) {
|
|
95960
|
-
this.buckets.set(hashCode, [value]);
|
|
95961
|
-
return;
|
|
95962
|
-
}
|
|
95963
|
-
const alreadyHasItem = itemsByCode.some((_) => isEqual(_, value));
|
|
95964
|
-
if (!alreadyHasItem) {
|
|
95965
|
-
itemsByCode.push(value);
|
|
95966
|
-
}
|
|
95967
|
-
}
|
|
95968
|
-
contains(value) {
|
|
95969
|
-
const hashCode = this.hashCodeOf(value);
|
|
95970
|
-
const itemsByCode = this.buckets.get(hashCode);
|
|
95971
|
-
if (!itemsByCode) {
|
|
95972
|
-
return false;
|
|
95973
|
-
}
|
|
95974
|
-
return itemsByCode.some((_) => isEqual(_, value));
|
|
95975
|
-
}
|
|
95976
|
-
values() {
|
|
95977
|
-
return [...this.buckets.values()].flat();
|
|
95978
|
-
}
|
|
95979
|
-
stats() {
|
|
95980
|
-
let totalBuckets = 0;
|
|
95981
|
-
let totalValues = 0;
|
|
95982
|
-
let collisions = 0;
|
|
95983
|
-
for (const bucket of this.buckets.values()) {
|
|
95984
|
-
totalBuckets += 1;
|
|
95985
|
-
totalValues += bucket.length;
|
|
95986
|
-
if (bucket.length > 1) {
|
|
95987
|
-
collisions += 1;
|
|
95988
|
-
}
|
|
95989
|
-
}
|
|
95990
|
-
const hashEffectiveness = totalBuckets / totalValues;
|
|
95991
|
-
return { totalBuckets, collisions, totalValues, hashEffectiveness };
|
|
95992
|
-
}
|
|
95993
|
-
hashCodeOf(object4) {
|
|
95994
|
-
let hashCode = 0;
|
|
95995
|
-
if (Array.isArray(object4)) {
|
|
95996
|
-
for (let i = 0;i < object4.length; i++) {
|
|
95997
|
-
hashCode ^= this.hashCodeOf(object4[i]) * i;
|
|
95998
|
-
}
|
|
95999
|
-
return hashCode;
|
|
96000
|
-
}
|
|
96001
|
-
if (typeof object4 === "string") {
|
|
96002
|
-
for (let i = 0;i < object4.length; i++) {
|
|
96003
|
-
hashCode ^= object4.charCodeAt(i) * i;
|
|
96004
|
-
}
|
|
96005
|
-
return hashCode;
|
|
96006
|
-
}
|
|
96007
|
-
if (typeof object4 === "number") {
|
|
96008
|
-
return object4;
|
|
96009
|
-
}
|
|
96010
|
-
if (typeof object4 === "object") {
|
|
96011
|
-
for (const [key, value] of Object.entries(object4)) {
|
|
96012
|
-
hashCode ^= this.hashCodeOf(key) + this.hashCodeOf(value !== null && value !== undefined ? value : "");
|
|
96013
|
-
}
|
|
96014
|
-
}
|
|
96015
|
-
return hashCode;
|
|
96016
|
-
}
|
|
96017
|
-
}
|
|
96018
|
-
function isUndefined(value) {
|
|
96019
|
-
return value === undefined;
|
|
96020
|
-
}
|
|
96021
|
-
function mapValues(object4, mapper) {
|
|
96022
|
-
const result = {};
|
|
96023
|
-
Object.entries(object4).forEach(([key, value]) => {
|
|
96024
|
-
result[key] = mapper(value);
|
|
96025
|
-
});
|
|
96026
|
-
return result;
|
|
96027
|
-
}
|
|
96028
|
-
function omit(object4, keys) {
|
|
96029
|
-
const result = {};
|
|
96030
|
-
Object.entries(object4).forEach(([key, value]) => {
|
|
96031
|
-
if (!keys.some((keyToOmit) => keyToOmit === key)) {
|
|
96032
|
-
result[key] = value;
|
|
96033
|
-
}
|
|
96034
|
-
});
|
|
96035
|
-
return result;
|
|
96036
|
-
}
|
|
96037
|
-
function omitBy(object4, predicate) {
|
|
96038
|
-
const result = {};
|
|
96039
|
-
Object.entries(object4).forEach(([key, value]) => {
|
|
96040
|
-
if (!predicate(value, key)) {
|
|
96041
|
-
result[key] = value;
|
|
96042
|
-
}
|
|
96043
|
-
});
|
|
96044
|
-
return result;
|
|
96045
|
-
}
|
|
96046
|
-
function compact(arr) {
|
|
96047
|
-
return arr.filter((elem) => !isUndefined(elem));
|
|
96048
|
-
}
|
|
96049
|
-
var objectEquals = isEqual;
|
|
96050
|
-
function uniq(values) {
|
|
96051
|
-
const set2 = new ObjectSet;
|
|
96052
|
-
values.forEach((value) => set2.put(value));
|
|
96053
|
-
return [...set2.values()];
|
|
96054
|
-
}
|
|
96055
|
-
function isString(val) {
|
|
96056
|
-
return typeof val === "string";
|
|
96057
|
-
}
|
|
96058
|
-
function sortObjectByKeys(obj) {
|
|
96059
|
-
return Object.fromEntries(Object.entries(obj).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)));
|
|
96060
|
-
}
|
|
96061
|
-
var zodToOpenAPIRegistry = registry();
|
|
96062
|
-
|
|
96063
|
-
class Metadata {
|
|
96064
|
-
static collectMetadata(schema, metadata) {
|
|
96065
|
-
const currentMetadata = this.getMetadataFromRegistry(schema);
|
|
96066
|
-
const _internal = Object.assign(Object.assign({}, currentMetadata === null || currentMetadata === undefined ? undefined : currentMetadata._internal), metadata === null || metadata === undefined ? undefined : metadata._internal);
|
|
96067
|
-
const param = Object.assign(Object.assign({}, currentMetadata === null || currentMetadata === undefined ? undefined : currentMetadata.param), metadata === null || metadata === undefined ? undefined : metadata.param);
|
|
96068
|
-
const totalMetadata = Object.assign(Object.assign(Object.assign(Object.assign({}, Object.keys(_internal).length > 0 ? { _internal } : {}), currentMetadata), metadata), Object.keys(param).length > 0 ? { param } : {});
|
|
96069
|
-
if (isZodType(schema, [
|
|
96070
|
-
"ZodOptional",
|
|
96071
|
-
"ZodNullable",
|
|
96072
|
-
"ZodDefault",
|
|
96073
|
-
"ZodPrefault",
|
|
96074
|
-
"ZodReadonly",
|
|
96075
|
-
"ZodNonOptional"
|
|
96076
|
-
]) && isAnyZodType(schema._zod.def.innerType)) {
|
|
96077
|
-
return this.collectMetadata(schema._zod.def.innerType, totalMetadata);
|
|
96078
|
-
}
|
|
96079
|
-
if (isZodType(schema, "ZodPipe")) {
|
|
96080
|
-
const inSchema = schema._zod.def.in;
|
|
96081
|
-
const outSchema = schema._zod.def.out;
|
|
96082
|
-
if (isZodType(inSchema, "ZodTransform") && isAnyZodType(outSchema)) {
|
|
96083
|
-
return this.collectMetadata(outSchema, totalMetadata);
|
|
96084
|
-
}
|
|
96085
|
-
if (isAnyZodType(inSchema)) {
|
|
96086
|
-
return this.collectMetadata(inSchema, totalMetadata);
|
|
96087
|
-
}
|
|
96088
|
-
}
|
|
96089
|
-
return totalMetadata;
|
|
96090
|
-
}
|
|
96091
|
-
static getMetadata(zodSchema) {
|
|
96092
|
-
return this.collectMetadata(zodSchema);
|
|
96093
|
-
}
|
|
96094
|
-
static getOpenApiMetadata(zodSchema) {
|
|
96095
|
-
const metadata = this.collectMetadata(zodSchema);
|
|
96096
|
-
const _a = metadata !== null && metadata !== undefined ? metadata : {}, { _internal } = _a, rest = __rest(_a, ["_internal"]);
|
|
96097
|
-
return rest;
|
|
96098
|
-
}
|
|
96099
|
-
static getInternalMetadata(zodSchema) {
|
|
96100
|
-
var _a;
|
|
96101
|
-
return (_a = this.collectMetadata(zodSchema)) === null || _a === undefined ? undefined : _a._internal;
|
|
96102
|
-
}
|
|
96103
|
-
static getParamMetadata(zodSchema) {
|
|
96104
|
-
const metadata = this.collectMetadata(zodSchema);
|
|
96105
|
-
return Object.assign(Object.assign({}, metadata), {
|
|
96106
|
-
param: Object.assign(Object.assign({}, (metadata === null || metadata === undefined ? undefined : metadata.description) ? { description: metadata.description } : {}), metadata === null || metadata === undefined ? undefined : metadata.param)
|
|
96107
|
-
});
|
|
96108
|
-
}
|
|
96109
|
-
static buildSchemaMetadata(metadata) {
|
|
96110
|
-
return omitBy(omit(metadata, ["param", "_internal"]), isUndefined);
|
|
96111
|
-
}
|
|
96112
|
-
static buildParameterMetadata(metadata) {
|
|
96113
|
-
return omitBy(metadata, isUndefined);
|
|
96114
|
-
}
|
|
96115
|
-
static applySchemaMetadata(initialData, metadata) {
|
|
96116
|
-
return omitBy(Object.assign(Object.assign({}, initialData), this.buildSchemaMetadata(metadata)), isUndefined);
|
|
96117
|
-
}
|
|
96118
|
-
static getRefId(zodSchema) {
|
|
96119
|
-
var _a;
|
|
96120
|
-
return (_a = this.getInternalMetadata(zodSchema)) === null || _a === undefined ? undefined : _a.refId;
|
|
96121
|
-
}
|
|
96122
|
-
static unwrapChained(schema) {
|
|
96123
|
-
return this.unwrapUntil(schema);
|
|
96124
|
-
}
|
|
96125
|
-
static getDefaultValue(zodSchema) {
|
|
96126
|
-
var _a;
|
|
96127
|
-
const unwrapped = (_a = this.unwrapUntil(zodSchema, "ZodDefault")) !== null && _a !== undefined ? _a : this.unwrapUntil(zodSchema, "ZodPrefault");
|
|
96128
|
-
return unwrapped === null || unwrapped === undefined ? undefined : unwrapped._zod.def.defaultValue;
|
|
96129
|
-
}
|
|
96130
|
-
static unwrapUntil(schema, typeName) {
|
|
96131
|
-
if (typeName && isZodType(schema, typeName)) {
|
|
96132
|
-
return schema;
|
|
96133
|
-
}
|
|
96134
|
-
if (isZodType(schema, [
|
|
96135
|
-
"ZodOptional",
|
|
96136
|
-
"ZodNullable",
|
|
96137
|
-
"ZodDefault",
|
|
96138
|
-
"ZodPrefault",
|
|
96139
|
-
"ZodReadonly",
|
|
96140
|
-
"ZodNonOptional"
|
|
96141
|
-
]) && isAnyZodType(schema._zod.def.innerType)) {
|
|
96142
|
-
return this.unwrapUntil(schema._zod.def.innerType, typeName);
|
|
96143
|
-
}
|
|
96144
|
-
if (isZodType(schema, "ZodPipe")) {
|
|
96145
|
-
const inSchema = schema._zod.def.in;
|
|
96146
|
-
const outSchema = schema._zod.def.out;
|
|
96147
|
-
if (isZodType(inSchema, "ZodTransform") && isAnyZodType(outSchema)) {
|
|
96148
|
-
return this.unwrapUntil(outSchema, typeName);
|
|
96149
|
-
}
|
|
96150
|
-
if (isAnyZodType(inSchema)) {
|
|
96151
|
-
return this.unwrapUntil(inSchema, typeName);
|
|
96152
|
-
}
|
|
96153
|
-
}
|
|
96154
|
-
return typeName ? undefined : schema;
|
|
96155
|
-
}
|
|
96156
|
-
static getMetadataFromInternalRegistry(zodSchema) {
|
|
96157
|
-
return zodToOpenAPIRegistry.get(zodSchema);
|
|
96158
|
-
}
|
|
96159
|
-
static getMetadataFromRegistry(zodSchema) {
|
|
96160
|
-
const internal = this.getMetadataFromInternalRegistry(zodSchema);
|
|
96161
|
-
const general = zodSchema.meta();
|
|
96162
|
-
if (!internal) {
|
|
96163
|
-
return general;
|
|
96164
|
-
}
|
|
96165
|
-
const { _internal } = internal, rest = __rest(internal, ["_internal"]);
|
|
96166
|
-
const _a = general !== null && general !== undefined ? general : {}, { id, title } = _a, restGeneral = __rest(_a, ["id", "title"]);
|
|
96167
|
-
return Object.assign(Object.assign(Object.assign({ _internal: Object.assign(Object.assign({}, id ? { refId: id } : {}), _internal) }, rest), title ? { description: title } : {}), restGeneral);
|
|
96168
|
-
}
|
|
96169
|
-
static setMetadataInRegistry(zodSchema, metadata) {
|
|
96170
|
-
zodToOpenAPIRegistry.add(zodSchema, metadata);
|
|
96171
|
-
}
|
|
96172
|
-
}
|
|
96173
|
-
function preserveMetadataFromModifier(zodSchema, modifier) {
|
|
96174
|
-
const zodModifier = zodSchema[modifier];
|
|
96175
|
-
if (typeof zodModifier !== "function") {
|
|
96176
|
-
return;
|
|
96177
|
-
}
|
|
96178
|
-
zodSchema[modifier] = function(...args) {
|
|
96179
|
-
const result = zodModifier.apply(this, args);
|
|
96180
|
-
const meta2 = Metadata.getMetadataFromRegistry(this);
|
|
96181
|
-
if (meta2) {
|
|
96182
|
-
Metadata.setMetadataInRegistry(result, meta2);
|
|
96183
|
-
}
|
|
96184
|
-
return result;
|
|
96185
|
-
};
|
|
96186
|
-
}
|
|
96187
|
-
function extendZodWithOpenApi(zod) {
|
|
96188
|
-
if (typeof zod.ZodType.prototype.openapi !== "undefined") {
|
|
96189
|
-
return;
|
|
96190
|
-
}
|
|
96191
|
-
zod.ZodType.prototype.openapi = function(...args) {
|
|
96192
|
-
const { refId, metadata, options } = getOpenApiConfiguration(...args);
|
|
96193
|
-
const _a = metadata !== null && metadata !== undefined ? metadata : {}, { param } = _a, restOfOpenApi = __rest(_a, ["param"]);
|
|
96194
|
-
const allMetadata = Metadata.getMetadataFromRegistry(this);
|
|
96195
|
-
const _b = allMetadata !== null && allMetadata !== undefined ? allMetadata : {}, { _internal: internalMetadata } = _b, currentMetadata = __rest(_b, ["_internal"]);
|
|
96196
|
-
const _internal = Object.assign(Object.assign(Object.assign({}, internalMetadata), options), refId ? { refId } : undefined);
|
|
96197
|
-
const resultMetadata = Object.assign(Object.assign(Object.assign({}, currentMetadata), restOfOpenApi), (currentMetadata === null || currentMetadata === undefined ? undefined : currentMetadata.param) || param ? {
|
|
96198
|
-
param: Object.assign(Object.assign({}, currentMetadata === null || currentMetadata === undefined ? undefined : currentMetadata.param), param)
|
|
96199
|
-
} : undefined);
|
|
96200
|
-
const result = new this.constructor(this._def);
|
|
96201
|
-
function setMetadata(schema) {
|
|
96202
|
-
Metadata.setMetadataInRegistry(schema, Object.assign(Object.assign({}, Object.keys(_internal).length > 0 ? { _internal } : undefined), resultMetadata));
|
|
96203
|
-
}
|
|
96204
|
-
setMetadata(result);
|
|
96205
|
-
if (isZodType(result, "ZodLazy")) {
|
|
96206
|
-
setMetadata(this);
|
|
96207
|
-
}
|
|
96208
|
-
if (isZodType(result, "ZodObject")) {
|
|
96209
|
-
const currentMetadata2 = Metadata.getMetadataFromRegistry(result);
|
|
96210
|
-
const originalExtend = result.extend;
|
|
96211
|
-
result.extend = function(...args2) {
|
|
96212
|
-
const extendedResult = originalExtend.apply(result, args2);
|
|
96213
|
-
const _a2 = currentMetadata2 !== null && currentMetadata2 !== undefined ? currentMetadata2 : {}, { _internal: _internal2 } = _a2, rest = __rest(_a2, ["_internal"]);
|
|
96214
|
-
Metadata.setMetadataInRegistry(extendedResult, {
|
|
96215
|
-
_internal: {
|
|
96216
|
-
extendedFrom: (_internal2 === null || _internal2 === undefined ? undefined : _internal2.refId) ? { refId: _internal2.refId, schema: result } : _internal2 === null || _internal2 === undefined ? undefined : _internal2.extendedFrom
|
|
96217
|
-
}
|
|
96218
|
-
});
|
|
96219
|
-
return extendedResult.openapi(rest);
|
|
96220
|
-
};
|
|
96221
|
-
preserveMetadataFromModifier(result, "catchall");
|
|
96222
|
-
}
|
|
96223
|
-
preserveMetadataFromModifier(result, "optional");
|
|
96224
|
-
preserveMetadataFromModifier(result, "nullable");
|
|
96225
|
-
preserveMetadataFromModifier(result, "default");
|
|
96226
|
-
preserveMetadataFromModifier(result, "transform");
|
|
96227
|
-
preserveMetadataFromModifier(result, "refine");
|
|
96228
|
-
preserveMetadataFromModifier(result, "length");
|
|
96229
|
-
preserveMetadataFromModifier(result, "min");
|
|
96230
|
-
preserveMetadataFromModifier(result, "max");
|
|
96231
|
-
const originalMeta = result.meta;
|
|
96232
|
-
result.meta = function(...args2) {
|
|
96233
|
-
const result2 = originalMeta.apply(this, args2);
|
|
96234
|
-
if (args2[0]) {
|
|
96235
|
-
const meta2 = Metadata.getMetadataFromInternalRegistry(this);
|
|
96236
|
-
if (meta2) {
|
|
96237
|
-
Metadata.setMetadataInRegistry(result2, Object.assign(Object.assign({}, meta2), args2[0]));
|
|
96238
|
-
}
|
|
96239
|
-
}
|
|
96240
|
-
return result2;
|
|
96241
|
-
};
|
|
96242
|
-
return result;
|
|
96243
|
-
};
|
|
96244
|
-
}
|
|
96245
|
-
function getOpenApiConfiguration(refOrOpenapi, metadataOrOptions, options) {
|
|
96246
|
-
if (typeof refOrOpenapi === "string") {
|
|
96247
|
-
return {
|
|
96248
|
-
refId: refOrOpenapi,
|
|
96249
|
-
metadata: metadataOrOptions,
|
|
96250
|
-
options
|
|
96251
|
-
};
|
|
96252
|
-
}
|
|
96253
|
-
return {
|
|
96254
|
-
refId: undefined,
|
|
96255
|
-
metadata: refOrOpenapi,
|
|
96256
|
-
options: metadataOrOptions
|
|
96257
|
-
};
|
|
96258
|
-
}
|
|
96259
|
-
class OpenAPIRegistry {
|
|
96260
|
-
constructor(parents) {
|
|
96261
|
-
this.parents = parents;
|
|
96262
|
-
this._definitions = [];
|
|
96263
|
-
}
|
|
96264
|
-
get definitions() {
|
|
96265
|
-
var _a, _b;
|
|
96266
|
-
const parentDefinitions = (_b = (_a = this.parents) === null || _a === undefined ? undefined : _a.flatMap((par) => par._definitions)) !== null && _b !== undefined ? _b : [];
|
|
96267
|
-
return [...parentDefinitions, ...this._definitions];
|
|
96268
|
-
}
|
|
96269
|
-
register(refId, zodSchema) {
|
|
96270
|
-
const schemaWithRefId = this.schemaWithRefId(refId, zodSchema);
|
|
96271
|
-
this._definitions.push({ type: "schema", schema: schemaWithRefId });
|
|
96272
|
-
return schemaWithRefId;
|
|
96273
|
-
}
|
|
96274
|
-
registerParameter(refId, zodSchema) {
|
|
96275
|
-
var _a, _b, _c;
|
|
96276
|
-
const schemaWithRefId = this.schemaWithRefId(refId, zodSchema);
|
|
96277
|
-
const currentMetadata = (_a = Metadata.getOpenApiMetadata(schemaWithRefId)) !== null && _a !== undefined ? _a : {};
|
|
96278
|
-
const schemaWithMetadata = schemaWithRefId.openapi(Object.assign(Object.assign({}, currentMetadata), { param: Object.assign(Object.assign({}, currentMetadata === null || currentMetadata === undefined ? undefined : currentMetadata.param), { name: (_c = (_b = currentMetadata === null || currentMetadata === undefined ? undefined : currentMetadata.param) === null || _b === undefined ? undefined : _b.name) !== null && _c !== undefined ? _c : refId }) }));
|
|
96279
|
-
this._definitions.push({
|
|
96280
|
-
type: "parameter",
|
|
96281
|
-
schema: schemaWithMetadata
|
|
96282
|
-
});
|
|
96283
|
-
return schemaWithMetadata;
|
|
96284
|
-
}
|
|
96285
|
-
registerPath(route) {
|
|
96286
|
-
this._definitions.push({
|
|
96287
|
-
type: "route",
|
|
96288
|
-
route
|
|
96289
|
-
});
|
|
96290
|
-
}
|
|
96291
|
-
registerWebhook(webhook) {
|
|
96292
|
-
this._definitions.push({
|
|
96293
|
-
type: "webhook",
|
|
96294
|
-
webhook
|
|
96295
|
-
});
|
|
96296
|
-
}
|
|
96297
|
-
registerComponent(type, name, component) {
|
|
96298
|
-
this._definitions.push({
|
|
96299
|
-
type: "component",
|
|
96300
|
-
componentType: type,
|
|
96301
|
-
name,
|
|
96302
|
-
component
|
|
96303
|
-
});
|
|
96304
|
-
return {
|
|
96305
|
-
name,
|
|
96306
|
-
ref: { $ref: `#/components/${type}/${name}` }
|
|
96307
|
-
};
|
|
96308
|
-
}
|
|
96309
|
-
schemaWithRefId(refId, zodSchema) {
|
|
96310
|
-
return zodSchema.openapi(refId);
|
|
96311
|
-
}
|
|
96312
|
-
}
|
|
96313
|
-
|
|
96314
|
-
class ZodToOpenAPIError {
|
|
96315
|
-
constructor(message) {
|
|
96316
|
-
this.message = message;
|
|
96317
|
-
}
|
|
96318
|
-
}
|
|
96319
|
-
|
|
96320
|
-
class ConflictError extends ZodToOpenAPIError {
|
|
96321
|
-
constructor(message, data) {
|
|
96322
|
-
super(message);
|
|
96323
|
-
this.data = data;
|
|
96324
|
-
}
|
|
96325
|
-
}
|
|
96326
|
-
|
|
96327
|
-
class MissingParameterDataError extends ZodToOpenAPIError {
|
|
96328
|
-
constructor(data) {
|
|
96329
|
-
super(`Missing parameter data, please specify \`${data.missingField}\` and other OpenAPI parameter props using the \`param\` field of \`schema.openapi\``);
|
|
96330
|
-
this.data = data;
|
|
96331
|
-
}
|
|
96332
|
-
}
|
|
96333
|
-
function enhanceMissingParametersError(action, paramsToAdd) {
|
|
96334
|
-
try {
|
|
96335
|
-
return action();
|
|
96336
|
-
} catch (error) {
|
|
96337
|
-
if (error instanceof MissingParameterDataError) {
|
|
96338
|
-
throw new MissingParameterDataError(Object.assign(Object.assign({}, error.data), paramsToAdd));
|
|
96339
|
-
}
|
|
96340
|
-
throw error;
|
|
96341
|
-
}
|
|
96342
|
-
}
|
|
96343
|
-
|
|
96344
|
-
class UnknownZodTypeError extends ZodToOpenAPIError {
|
|
96345
|
-
constructor(data) {
|
|
96346
|
-
super(`Unknown zod object type, please specify \`type\` and other OpenAPI props using \`schema.openapi\`.`);
|
|
96347
|
-
this.data = data;
|
|
96348
|
-
}
|
|
96349
|
-
}
|
|
96350
|
-
|
|
96351
|
-
class ArrayTransformer {
|
|
96352
|
-
transform(zodSchema, mapNullableType, mapItems) {
|
|
96353
|
-
var _a, _b, _c, _d;
|
|
96354
|
-
const itemType = zodSchema.def.element;
|
|
96355
|
-
const minItems = (_b = (_a = zodSchema.def.checks) === null || _a === undefined ? undefined : _a.find((check) => check._zod.def.check === "min_length")) === null || _b === undefined ? undefined : _b._zod.def.minimum;
|
|
96356
|
-
const maxItems = (_d = (_c = zodSchema.def.checks) === null || _c === undefined ? undefined : _c.find((check) => check._zod.def.check === "max_length")) === null || _d === undefined ? undefined : _d._zod.def.maximum;
|
|
96357
|
-
return Object.assign(Object.assign({}, mapNullableType("array")), {
|
|
96358
|
-
items: isAnyZodType(itemType) ? mapItems(itemType) : {},
|
|
96359
|
-
minItems,
|
|
96360
|
-
maxItems
|
|
96361
|
-
});
|
|
96362
|
-
}
|
|
96363
|
-
}
|
|
96364
|
-
|
|
96365
|
-
class BigIntTransformer {
|
|
96366
|
-
transform(mapNullableType) {
|
|
96367
|
-
return Object.assign(Object.assign({}, mapNullableType("string")), { pattern: `^d+$` });
|
|
96368
|
-
}
|
|
96369
|
-
}
|
|
96370
|
-
|
|
96371
|
-
class DiscriminatedUnionTransformer {
|
|
96372
|
-
transform(zodSchema, isNullable, mapNullableOfArray, mapItem, generateSchemaRef) {
|
|
96373
|
-
const options = [...zodSchema.def.options];
|
|
96374
|
-
const optionSchema = options.map(mapItem);
|
|
96375
|
-
if (isNullable) {
|
|
96376
|
-
return {
|
|
96377
|
-
oneOf: mapNullableOfArray(optionSchema, isNullable)
|
|
96378
|
-
};
|
|
96379
|
-
}
|
|
96380
|
-
const discriminator = zodSchema._zod.def.discriminator;
|
|
96381
|
-
if (!discriminator) {
|
|
96382
|
-
console.error("No discriminator found for discriminated union", zodSchema);
|
|
96383
|
-
return {
|
|
96384
|
-
oneOf: optionSchema
|
|
96385
|
-
};
|
|
96386
|
-
}
|
|
96387
|
-
return {
|
|
96388
|
-
oneOf: optionSchema,
|
|
96389
|
-
discriminator: this.mapDiscriminator(options, discriminator, generateSchemaRef)
|
|
96390
|
-
};
|
|
96391
|
-
}
|
|
96392
|
-
mapDiscriminator(zodObjects, discriminator, generateSchemaRef) {
|
|
96393
|
-
if (zodObjects.some((obj) => Metadata.getRefId(obj) === undefined)) {
|
|
96394
|
-
return;
|
|
96395
|
-
}
|
|
96396
|
-
const mapping = {};
|
|
96397
|
-
zodObjects.forEach((obj) => {
|
|
96398
|
-
var _a;
|
|
96399
|
-
const refId = Metadata.getRefId(obj);
|
|
96400
|
-
const value = (_a = obj.def.shape) === null || _a === undefined ? undefined : _a[discriminator];
|
|
96401
|
-
if (isZodType(value, "ZodEnum")) {
|
|
96402
|
-
const keys = Object.values(value._zod.def.entries).filter(isString);
|
|
96403
|
-
keys.forEach((enumValue) => {
|
|
96404
|
-
mapping[enumValue] = generateSchemaRef(refId);
|
|
96405
|
-
});
|
|
96406
|
-
return;
|
|
96407
|
-
}
|
|
96408
|
-
const literalValue = value === null || value === undefined ? undefined : value.def.values[0];
|
|
96409
|
-
if (typeof literalValue !== "string") {
|
|
96410
|
-
throw new Error(`Discriminator ${discriminator} could not be found in one of the values of a discriminated union`);
|
|
96411
|
-
}
|
|
96412
|
-
mapping[literalValue] = generateSchemaRef(refId);
|
|
96413
|
-
});
|
|
96414
|
-
return {
|
|
96415
|
-
propertyName: discriminator,
|
|
96416
|
-
mapping
|
|
96417
|
-
};
|
|
96418
|
-
}
|
|
96419
|
-
}
|
|
96420
|
-
function enumInfo(enumObject) {
|
|
96421
|
-
const keysExceptReverseMappings = Object.keys(enumObject).filter((key) => typeof enumObject[enumObject[key]] !== "number");
|
|
96422
|
-
const values = keysExceptReverseMappings.map((key) => enumObject[key]);
|
|
96423
|
-
const numericCount = values.filter((_) => typeof _ === "number").length;
|
|
96424
|
-
const type = numericCount === 0 ? "string" : numericCount === values.length ? "numeric" : "mixed";
|
|
96425
|
-
return { values, type };
|
|
96426
|
-
}
|
|
96427
|
-
|
|
96428
|
-
class EnumTransformer {
|
|
96429
|
-
transform(zodSchema, isNullable, mapNullableType) {
|
|
96430
|
-
const { type, values } = enumInfo(zodSchema._zod.def.entries);
|
|
96431
|
-
if (type === "mixed") {
|
|
96432
|
-
throw new ZodToOpenAPIError("Enum has mixed string and number values, please specify the OpenAPI type manually");
|
|
96433
|
-
}
|
|
96434
|
-
return Object.assign(Object.assign({}, mapNullableType(type === "numeric" ? "integer" : "string")), { enum: isNullable ? [...values, null] : values });
|
|
96435
|
-
}
|
|
96436
|
-
}
|
|
96437
|
-
|
|
96438
|
-
class IntersectionTransformer {
|
|
96439
|
-
transform(zodSchema, isNullable, mapNullableOfArray, mapItem) {
|
|
96440
|
-
const subtypes = this.flattenIntersectionTypes(zodSchema);
|
|
96441
|
-
const allOfSchema = {
|
|
96442
|
-
allOf: subtypes.map(mapItem)
|
|
96443
|
-
};
|
|
96444
|
-
if (isNullable) {
|
|
96445
|
-
return {
|
|
96446
|
-
anyOf: mapNullableOfArray([allOfSchema], isNullable)
|
|
96447
|
-
};
|
|
96448
|
-
}
|
|
96449
|
-
return allOfSchema;
|
|
96450
|
-
}
|
|
96451
|
-
flattenIntersectionTypes(schema) {
|
|
96452
|
-
if (!isZodType(schema, "ZodIntersection")) {
|
|
96453
|
-
return [schema];
|
|
96454
|
-
}
|
|
96455
|
-
const leftSubTypes = isAnyZodType(schema._zod.def.left) ? this.flattenIntersectionTypes(schema._zod.def.left) : [];
|
|
96456
|
-
const rightSubTypes = isAnyZodType(schema._zod.def.right) ? this.flattenIntersectionTypes(schema._zod.def.right) : [];
|
|
96457
|
-
return [...leftSubTypes, ...rightSubTypes];
|
|
96458
|
-
}
|
|
96459
|
-
}
|
|
96460
|
-
|
|
96461
|
-
class LiteralTransformer {
|
|
96462
|
-
constructor() {
|
|
96463
|
-
this.bigIntTransformer = new BigIntTransformer;
|
|
96464
|
-
}
|
|
96465
|
-
transform(zodSchema, mapNullableType) {
|
|
96466
|
-
const type = typeof zodSchema.def.values[0];
|
|
96467
|
-
if (type === "boolean" || type === "number" || type === "string" || type === "object") {
|
|
96468
|
-
return Object.assign(Object.assign({}, mapNullableType(type)), { enum: [zodSchema.def.values[0]] });
|
|
96469
|
-
}
|
|
96470
|
-
if (type === "bigint") {
|
|
96471
|
-
return this.bigIntTransformer.transform(mapNullableType);
|
|
96472
|
-
}
|
|
96473
|
-
return mapNullableType("null");
|
|
96474
|
-
}
|
|
96475
|
-
}
|
|
96476
|
-
|
|
96477
|
-
class NumberTransformer {
|
|
96478
|
-
transform(zodSchema, mapNullableType, getNumberChecks) {
|
|
96479
|
-
var _a;
|
|
96480
|
-
return Object.assign(Object.assign(Object.assign({}, mapNullableType("number")), mapNullableType(zodSchema.format === "safeint" ? "integer" : "number")), getNumberChecks((_a = zodSchema.def.checks) !== null && _a !== undefined ? _a : []));
|
|
96481
|
-
}
|
|
96482
|
-
}
|
|
96483
|
-
|
|
96484
|
-
class ObjectTransformer {
|
|
96485
|
-
transform(zodSchema, defaultValue, mapNullableType, mapItem) {
|
|
96486
|
-
var _a;
|
|
96487
|
-
const extendedFrom = (_a = Metadata.getInternalMetadata(zodSchema)) === null || _a === undefined ? undefined : _a.extendedFrom;
|
|
96488
|
-
const required = this.requiredKeysOf(zodSchema);
|
|
96489
|
-
const properties = mapValues(zodSchema.def.shape, mapItem);
|
|
96490
|
-
if (!extendedFrom) {
|
|
96491
|
-
return Object.assign(Object.assign(Object.assign(Object.assign({}, mapNullableType("object")), { properties, default: defaultValue }), required.length > 0 ? { required } : {}), this.generateAdditionalProperties(zodSchema, mapItem));
|
|
96492
|
-
}
|
|
96493
|
-
const parent = extendedFrom.schema;
|
|
96494
|
-
mapItem(parent);
|
|
96495
|
-
const keysRequiredByParent = this.requiredKeysOf(parent);
|
|
96496
|
-
const propsOfParent = mapValues(parent === null || parent === undefined ? undefined : parent.def.shape, mapItem);
|
|
96497
|
-
const propertiesToAdd = Object.fromEntries(Object.entries(properties).filter(([key, type]) => {
|
|
96498
|
-
return !objectEquals(propsOfParent[key], type);
|
|
96499
|
-
}));
|
|
96500
|
-
const additionallyRequired = required.filter((prop) => !keysRequiredByParent.includes(prop));
|
|
96501
|
-
const objectData = Object.assign(Object.assign(Object.assign(Object.assign({}, mapNullableType("object")), { default: defaultValue, properties: propertiesToAdd }), additionallyRequired.length > 0 ? { required: additionallyRequired } : {}), this.generateAdditionalProperties(zodSchema, mapItem));
|
|
96502
|
-
return {
|
|
96503
|
-
allOf: [
|
|
96504
|
-
{ $ref: `#/components/schemas/${extendedFrom.refId}` },
|
|
96505
|
-
objectData
|
|
96506
|
-
]
|
|
96507
|
-
};
|
|
96508
|
-
}
|
|
96509
|
-
generateAdditionalProperties(zodSchema, mapItem) {
|
|
96510
|
-
const catchallSchema = zodSchema.def.catchall;
|
|
96511
|
-
if (!catchallSchema) {
|
|
96512
|
-
return {};
|
|
96513
|
-
}
|
|
96514
|
-
if (isZodType(catchallSchema, "ZodNever")) {
|
|
96515
|
-
return { additionalProperties: false };
|
|
96516
|
-
}
|
|
96517
|
-
if (isAnyZodType(catchallSchema)) {
|
|
96518
|
-
return { additionalProperties: mapItem(catchallSchema) };
|
|
96519
|
-
}
|
|
96520
|
-
return {};
|
|
96521
|
-
}
|
|
96522
|
-
requiredKeysOf(objectSchema) {
|
|
96523
|
-
return Object.entries(objectSchema.def.shape).filter(([_key, type]) => !isOptionalSchema(type)).map(([key, _type]) => key);
|
|
96524
|
-
}
|
|
96525
|
-
}
|
|
96526
|
-
|
|
96527
|
-
class RecordTransformer {
|
|
96528
|
-
transform(zodSchema, mapNullableType, mapItem) {
|
|
96529
|
-
const propertiesType = zodSchema.valueType;
|
|
96530
|
-
const keyType = zodSchema.keyType;
|
|
96531
|
-
const propertiesSchema = isAnyZodType(propertiesType) ? mapItem(propertiesType) : {};
|
|
96532
|
-
if (isZodType(keyType, "ZodEnum")) {
|
|
96533
|
-
const keys = Object.values(keyType._zod.def.entries).filter(isString);
|
|
96534
|
-
const properties = keys.reduce((acc, curr) => Object.assign(Object.assign({}, acc), { [curr]: propertiesSchema }), {});
|
|
96535
|
-
return Object.assign(Object.assign({}, mapNullableType("object")), { properties });
|
|
96536
|
-
}
|
|
96537
|
-
return Object.assign(Object.assign({}, mapNullableType("object")), { additionalProperties: propertiesSchema });
|
|
96538
|
-
}
|
|
96539
|
-
}
|
|
96540
|
-
function isZodCheckLengthEquals(check) {
|
|
96541
|
-
return check._zod.def.check === "length_equals";
|
|
96542
|
-
}
|
|
96543
|
-
function isZodCheckRegex(check) {
|
|
96544
|
-
return check._zod.def.check === "string_format" && check._zod.def.format === "regex";
|
|
96545
|
-
}
|
|
96546
|
-
|
|
96547
|
-
class StringTransformer {
|
|
96548
|
-
transform(zodSchema, mapNullableType) {
|
|
96549
|
-
var _a, _b, _c, _d;
|
|
96550
|
-
const regexCheck = (_a = zodSchema.def.checks) === null || _a === undefined ? undefined : _a.find(isZodCheckRegex);
|
|
96551
|
-
const pattern = regexCheck === null || regexCheck === undefined ? undefined : regexCheck._zod.def.pattern.toString().replace(/^\/|\/$/g, "");
|
|
96552
|
-
const check = (_b = zodSchema.def.checks) === null || _b === undefined ? undefined : _b.find(isZodCheckLengthEquals);
|
|
96553
|
-
const length = check === null || check === undefined ? undefined : check._zod.def.length;
|
|
96554
|
-
const maxLength = Number.isFinite(zodSchema.minLength) ? (_c = zodSchema.minLength) !== null && _c !== undefined ? _c : undefined : undefined;
|
|
96555
|
-
const minLength = Number.isFinite(zodSchema.maxLength) ? (_d = zodSchema.maxLength) !== null && _d !== undefined ? _d : undefined : undefined;
|
|
96556
|
-
return Object.assign(Object.assign({}, mapNullableType("string")), {
|
|
96557
|
-
minLength: length !== null && length !== undefined ? length : maxLength,
|
|
96558
|
-
maxLength: length !== null && length !== undefined ? length : minLength,
|
|
96559
|
-
format: this.mapStringFormat(zodSchema),
|
|
96560
|
-
pattern
|
|
96561
|
-
});
|
|
96562
|
-
}
|
|
96563
|
-
mapStringFormat(zodString) {
|
|
96564
|
-
if (zodString.format === "uuid")
|
|
96565
|
-
return "uuid";
|
|
96566
|
-
if (zodString.format === "email")
|
|
96567
|
-
return "email";
|
|
96568
|
-
if (zodString.format === "url")
|
|
96569
|
-
return "uri";
|
|
96570
|
-
if (zodString.format === "date")
|
|
96571
|
-
return "date";
|
|
96572
|
-
if (zodString.format === "datetime")
|
|
96573
|
-
return "date-time";
|
|
96574
|
-
if (zodString.format === "cuid")
|
|
96575
|
-
return "cuid";
|
|
96576
|
-
if (zodString.format === "cuid2")
|
|
96577
|
-
return "cuid2";
|
|
96578
|
-
if (zodString.format === "ulid")
|
|
96579
|
-
return "ulid";
|
|
96580
|
-
if (zodString.format === "ipv4")
|
|
96581
|
-
return "ip";
|
|
96582
|
-
if (zodString.format === "ipv6")
|
|
96583
|
-
return "ip";
|
|
96584
|
-
if (zodString.format === "emoji")
|
|
96585
|
-
return "emoji";
|
|
96586
|
-
return;
|
|
96587
|
-
}
|
|
96588
|
-
}
|
|
96589
|
-
|
|
96590
|
-
class TupleTransformer {
|
|
96591
|
-
constructor(versionSpecifics) {
|
|
96592
|
-
this.versionSpecifics = versionSpecifics;
|
|
96593
|
-
}
|
|
96594
|
-
transform(zodSchema, mapNullableType, mapItem) {
|
|
96595
|
-
const items = zodSchema._zod.def.items;
|
|
96596
|
-
const schemas2 = items.map((item) => isAnyZodType(item) ? mapItem(item) : {});
|
|
96597
|
-
return Object.assign(Object.assign({}, mapNullableType("array")), this.versionSpecifics.mapTupleItems(schemas2));
|
|
96598
|
-
}
|
|
96599
|
-
}
|
|
96600
|
-
|
|
96601
|
-
class UnionTransformer {
|
|
96602
|
-
constructor(options) {
|
|
96603
|
-
this.options = options;
|
|
96604
|
-
}
|
|
96605
|
-
transform(zodSchema, mapNullableOfArray, mapItem) {
|
|
96606
|
-
var _a, _b, _c;
|
|
96607
|
-
const internalMetadata = Metadata.getInternalMetadata(zodSchema);
|
|
96608
|
-
const preferredType = (_c = (_a = internalMetadata === null || internalMetadata === undefined ? undefined : internalMetadata.unionPreferredType) !== null && _a !== undefined ? _a : (_b = this.options) === null || _b === undefined ? undefined : _b.unionPreferredType) !== null && _c !== undefined ? _c : "anyOf";
|
|
96609
|
-
const options = this.flattenUnionTypes(zodSchema);
|
|
96610
|
-
const schemas2 = options.map((schema) => {
|
|
96611
|
-
const optionToGenerate = this.unwrapNullable(schema);
|
|
96612
|
-
return mapItem(optionToGenerate);
|
|
96613
|
-
});
|
|
96614
|
-
return {
|
|
96615
|
-
[preferredType]: mapNullableOfArray(schemas2)
|
|
96616
|
-
};
|
|
96617
|
-
}
|
|
96618
|
-
flattenUnionTypes(schema) {
|
|
96619
|
-
if (!isZodType(schema, "ZodUnion")) {
|
|
96620
|
-
return [schema];
|
|
96621
|
-
}
|
|
96622
|
-
const options = schema.def.options;
|
|
96623
|
-
return options.flatMap((option) => isAnyZodType(option) ? this.flattenUnionTypes(option) : []);
|
|
96624
|
-
}
|
|
96625
|
-
unwrapNullable(schema) {
|
|
96626
|
-
if (isZodType(schema, "ZodNullable")) {
|
|
96627
|
-
const unwrapped = schema.unwrap();
|
|
96628
|
-
if (isAnyZodType(unwrapped)) {
|
|
96629
|
-
return this.unwrapNullable(unwrapped);
|
|
96630
|
-
}
|
|
96631
|
-
}
|
|
96632
|
-
return schema;
|
|
96633
|
-
}
|
|
96634
|
-
}
|
|
96635
|
-
|
|
96636
|
-
class DateTransformer {
|
|
96637
|
-
transform(mapNullableType) {
|
|
96638
|
-
return Object.assign(Object.assign({}, mapNullableType("string")), { format: "date-time" });
|
|
96639
|
-
}
|
|
96640
|
-
}
|
|
96641
|
-
|
|
96642
|
-
class LazyTransformer {
|
|
96643
|
-
transform(zodSchema, mapItem, mapNullableType, mapNullableRef) {
|
|
96644
|
-
const result = mapItem(zodSchema._zod.def.getter());
|
|
96645
|
-
return LazyTransformer.mapRecursive(result, mapNullableType, mapNullableRef);
|
|
96646
|
-
}
|
|
96647
|
-
static mapRecursive(schema, mapNullableType, mapNullableRef) {
|
|
96648
|
-
if ("$ref" in schema) {
|
|
96649
|
-
return mapNullableRef(schema);
|
|
96650
|
-
}
|
|
96651
|
-
if (schema.type) {
|
|
96652
|
-
return Object.assign(Object.assign({}, schema), mapNullableType(schema.type));
|
|
96653
|
-
}
|
|
96654
|
-
return schema;
|
|
96655
|
-
}
|
|
96656
|
-
}
|
|
96657
|
-
|
|
96658
|
-
class TemplateLiteralTransformer {
|
|
96659
|
-
transform(zodSchema, mapNullableType) {
|
|
96660
|
-
const parts = zodSchema.def.parts;
|
|
96661
|
-
const contentPattern = parts.map((part) => this.generatePattern(part)).join("");
|
|
96662
|
-
return Object.assign(Object.assign({}, mapNullableType("string")), { pattern: `^${contentPattern}$` });
|
|
96663
|
-
}
|
|
96664
|
-
generatePattern(part) {
|
|
96665
|
-
if (typeof part === "string" || typeof part === "number" || typeof part === "boolean" || typeof part === "bigint" || part === null || part === undefined) {
|
|
96666
|
-
return this.escapeRegex(String(part));
|
|
96667
|
-
}
|
|
96668
|
-
if (isZodType(part, "ZodLiteral")) {
|
|
96669
|
-
const value = part.def.values[0];
|
|
96670
|
-
return this.escapeRegex(String(value));
|
|
96671
|
-
}
|
|
96672
|
-
if (isZodType(part, "ZodNumber")) {
|
|
96673
|
-
return "[+-]?\\d+(\\.\\d+)?";
|
|
96674
|
-
}
|
|
96675
|
-
if (isZodType(part, "ZodBoolean")) {
|
|
96676
|
-
return "(true|false)";
|
|
96677
|
-
}
|
|
96678
|
-
if (isZodType(part, "ZodEnum")) {
|
|
96679
|
-
const { values } = enumInfo(part.def.entries);
|
|
96680
|
-
return `(${values.map((v) => this.escapeRegex(String(v))).join("|")})`;
|
|
96681
|
-
}
|
|
96682
|
-
return ".*";
|
|
96683
|
-
}
|
|
96684
|
-
escapeRegex(str) {
|
|
96685
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
96686
|
-
}
|
|
96687
|
-
}
|
|
96688
|
-
|
|
96689
|
-
class OpenApiTransformer {
|
|
96690
|
-
constructor(versionSpecifics, options) {
|
|
96691
|
-
this.versionSpecifics = versionSpecifics;
|
|
96692
|
-
this.objectTransformer = new ObjectTransformer;
|
|
96693
|
-
this.stringTransformer = new StringTransformer;
|
|
96694
|
-
this.numberTransformer = new NumberTransformer;
|
|
96695
|
-
this.bigIntTransformer = new BigIntTransformer;
|
|
96696
|
-
this.dateTransformer = new DateTransformer;
|
|
96697
|
-
this.lazyTransformer = new LazyTransformer;
|
|
96698
|
-
this.literalTransformer = new LiteralTransformer;
|
|
96699
|
-
this.templateLiteralTransformer = new TemplateLiteralTransformer;
|
|
96700
|
-
this.enumTransformer = new EnumTransformer;
|
|
96701
|
-
this.arrayTransformer = new ArrayTransformer;
|
|
96702
|
-
this.discriminatedUnionTransformer = new DiscriminatedUnionTransformer;
|
|
96703
|
-
this.intersectionTransformer = new IntersectionTransformer;
|
|
96704
|
-
this.recordTransformer = new RecordTransformer;
|
|
96705
|
-
this.tupleTransformer = new TupleTransformer(versionSpecifics);
|
|
96706
|
-
this.unionTransformer = new UnionTransformer(options);
|
|
96707
|
-
}
|
|
96708
|
-
transform(zodSchema, isNullable, mapItem, generateSchemaRef, defaultValue) {
|
|
96709
|
-
if (isZodType(zodSchema, "ZodNull")) {
|
|
96710
|
-
return this.versionSpecifics.nullType;
|
|
96711
|
-
}
|
|
96712
|
-
if (isZodType(zodSchema, "ZodUnknown") || isZodType(zodSchema, "ZodAny")) {
|
|
96713
|
-
return this.versionSpecifics.mapNullableType(undefined, isNullable);
|
|
96714
|
-
}
|
|
96715
|
-
if (isZodType(zodSchema, "ZodObject")) {
|
|
96716
|
-
return this.objectTransformer.transform(zodSchema, defaultValue, (_) => this.versionSpecifics.mapNullableType(_, isNullable), mapItem);
|
|
96717
|
-
}
|
|
96718
|
-
const schema = this.transformSchemaWithoutDefault(zodSchema, isNullable, mapItem, generateSchemaRef);
|
|
96719
|
-
return Object.assign(Object.assign({}, schema), { default: defaultValue });
|
|
96720
|
-
}
|
|
96721
|
-
transformSchemaWithoutDefault(zodSchema, isNullable, mapItem, generateSchemaRef) {
|
|
96722
|
-
if (isZodType(zodSchema, "ZodUnknown") || isZodType(zodSchema, "ZodAny")) {
|
|
96723
|
-
return this.versionSpecifics.mapNullableType(undefined, isNullable);
|
|
96724
|
-
}
|
|
96725
|
-
if (isZodType(zodSchema, "ZodString")) {
|
|
96726
|
-
return this.stringTransformer.transform(zodSchema, (schema) => this.versionSpecifics.mapNullableType(schema, isNullable));
|
|
96727
|
-
}
|
|
96728
|
-
if (isZodType(zodSchema, "ZodNumber")) {
|
|
96729
|
-
return this.numberTransformer.transform(zodSchema, (schema) => this.versionSpecifics.mapNullableType(schema, isNullable), (_) => this.versionSpecifics.getNumberChecks(_));
|
|
96730
|
-
}
|
|
96731
|
-
if (isZodType(zodSchema, "ZodBigInt")) {
|
|
96732
|
-
return this.bigIntTransformer.transform((schema) => this.versionSpecifics.mapNullableType(schema, isNullable));
|
|
96733
|
-
}
|
|
96734
|
-
if (isZodType(zodSchema, "ZodBoolean")) {
|
|
96735
|
-
return this.versionSpecifics.mapNullableType("boolean", isNullable);
|
|
96736
|
-
}
|
|
96737
|
-
if (isZodType(zodSchema, "ZodLazy")) {
|
|
96738
|
-
return this.lazyTransformer.transform(zodSchema, mapItem, (schema) => this.versionSpecifics.mapNullableType(schema, isNullable), (schema) => this.versionSpecifics.mapNullableOfRef(schema, isNullable));
|
|
96739
|
-
}
|
|
96740
|
-
if (isZodType(zodSchema, "ZodLiteral")) {
|
|
96741
|
-
return this.literalTransformer.transform(zodSchema, (schema) => this.versionSpecifics.mapNullableType(schema, isNullable));
|
|
96742
|
-
}
|
|
96743
|
-
if (isZodType(zodSchema, "ZodTemplateLiteral")) {
|
|
96744
|
-
return this.templateLiteralTransformer.transform(zodSchema, (schema) => this.versionSpecifics.mapNullableType(schema, isNullable));
|
|
96745
|
-
}
|
|
96746
|
-
if (isZodType(zodSchema, "ZodEnum")) {
|
|
96747
|
-
return this.enumTransformer.transform(zodSchema, isNullable, (schema) => this.versionSpecifics.mapNullableType(schema, isNullable));
|
|
96748
|
-
}
|
|
96749
|
-
if (isZodType(zodSchema, "ZodArray")) {
|
|
96750
|
-
return this.arrayTransformer.transform(zodSchema, (_) => this.versionSpecifics.mapNullableType(_, isNullable), mapItem);
|
|
96751
|
-
}
|
|
96752
|
-
if (isZodType(zodSchema, "ZodTuple")) {
|
|
96753
|
-
return this.tupleTransformer.transform(zodSchema, (_) => this.versionSpecifics.mapNullableType(_, isNullable), mapItem);
|
|
96754
|
-
}
|
|
96755
|
-
if (isZodType(zodSchema, "ZodDiscriminatedUnion")) {
|
|
96756
|
-
return this.discriminatedUnionTransformer.transform(zodSchema, isNullable, (_) => this.versionSpecifics.mapNullableOfArray(_, isNullable), mapItem, generateSchemaRef);
|
|
96757
|
-
}
|
|
96758
|
-
if (isZodType(zodSchema, "ZodUnion")) {
|
|
96759
|
-
return this.unionTransformer.transform(zodSchema, (_) => this.versionSpecifics.mapNullableOfArray(_, isNullable), mapItem);
|
|
96760
|
-
}
|
|
96761
|
-
if (isZodType(zodSchema, "ZodIntersection")) {
|
|
96762
|
-
return this.intersectionTransformer.transform(zodSchema, isNullable, (_) => this.versionSpecifics.mapNullableOfArray(_, isNullable), mapItem);
|
|
96763
|
-
}
|
|
96764
|
-
if (isZodType(zodSchema, "ZodRecord")) {
|
|
96765
|
-
return this.recordTransformer.transform(zodSchema, (_) => this.versionSpecifics.mapNullableType(_, isNullable), mapItem);
|
|
96766
|
-
}
|
|
96767
|
-
if (isZodType(zodSchema, "ZodDate")) {
|
|
96768
|
-
return this.dateTransformer.transform((_) => this.versionSpecifics.mapNullableType(_, isNullable));
|
|
96769
|
-
}
|
|
96770
|
-
const refId = Metadata.getRefId(zodSchema);
|
|
96771
|
-
throw new UnknownZodTypeError({
|
|
96772
|
-
currentSchema: zodSchema.def,
|
|
96773
|
-
schemaName: refId
|
|
96774
|
-
});
|
|
96775
|
-
}
|
|
96776
|
-
}
|
|
96777
|
-
|
|
96778
|
-
class OpenAPIGenerator {
|
|
96779
|
-
constructor(definitions, versionSpecifics, options) {
|
|
96780
|
-
this.definitions = definitions;
|
|
96781
|
-
this.versionSpecifics = versionSpecifics;
|
|
96782
|
-
this.options = options;
|
|
96783
|
-
this.schemaRefs = {};
|
|
96784
|
-
this.paramRefs = {};
|
|
96785
|
-
this.pathRefs = {};
|
|
96786
|
-
this.rawComponents = [];
|
|
96787
|
-
this.openApiTransformer = new OpenApiTransformer(versionSpecifics, options);
|
|
96788
|
-
this.sortDefinitions();
|
|
96789
|
-
}
|
|
96790
|
-
generateDocumentData() {
|
|
96791
|
-
this.definitions.forEach((definition) => this.generateSingle(definition));
|
|
96792
|
-
return {
|
|
96793
|
-
components: this.buildComponents(),
|
|
96794
|
-
paths: this.pathRefs
|
|
96795
|
-
};
|
|
96796
|
-
}
|
|
96797
|
-
generateComponents() {
|
|
96798
|
-
this.definitions.forEach((definition) => this.generateSingle(definition));
|
|
96799
|
-
return {
|
|
96800
|
-
components: this.buildComponents()
|
|
96801
|
-
};
|
|
96802
|
-
}
|
|
96803
|
-
buildComponents() {
|
|
96804
|
-
var _a, _b, _c, _d;
|
|
96805
|
-
const rawComponents = {};
|
|
96806
|
-
this.rawComponents.forEach(({ componentType, name, component }) => {
|
|
96807
|
-
var _a2;
|
|
96808
|
-
(_a2 = rawComponents[componentType]) !== null && _a2 !== undefined || (rawComponents[componentType] = {});
|
|
96809
|
-
rawComponents[componentType][name] = component;
|
|
96810
|
-
});
|
|
96811
|
-
const allSchemas = Object.assign(Object.assign({}, (_a = rawComponents.schemas) !== null && _a !== undefined ? _a : {}), this.filteredSchemaRefs);
|
|
96812
|
-
const schemas2 = ((_b = this.options) === null || _b === undefined ? undefined : _b.sortComponents) === "alphabetically" ? sortObjectByKeys(allSchemas) : allSchemas;
|
|
96813
|
-
const allParameters = Object.assign(Object.assign({}, (_c = rawComponents.parameters) !== null && _c !== undefined ? _c : {}), this.paramRefs);
|
|
96814
|
-
const parameters = ((_d = this.options) === null || _d === undefined ? undefined : _d.sortComponents) === "alphabetically" ? sortObjectByKeys(allParameters) : allParameters;
|
|
96815
|
-
return Object.assign(Object.assign({}, rawComponents), { schemas: schemas2, parameters });
|
|
96816
|
-
}
|
|
96817
|
-
isNotPendingRefEntry(entry) {
|
|
96818
|
-
return entry[1] !== "pending";
|
|
96819
|
-
}
|
|
96820
|
-
get filteredSchemaRefs() {
|
|
96821
|
-
const filtered = Object.entries(this.schemaRefs).filter(this.isNotPendingRefEntry);
|
|
96822
|
-
return Object.fromEntries(filtered);
|
|
96823
|
-
}
|
|
96824
|
-
sortDefinitions() {
|
|
96825
|
-
const generationOrder = [
|
|
96826
|
-
"schema",
|
|
96827
|
-
"parameter",
|
|
96828
|
-
"component",
|
|
96829
|
-
"route"
|
|
96830
|
-
];
|
|
96831
|
-
this.definitions.sort((left, right) => {
|
|
96832
|
-
if (!("type" in left)) {
|
|
96833
|
-
if (!("type" in right)) {
|
|
96834
|
-
return 0;
|
|
96835
|
-
}
|
|
96836
|
-
return -1;
|
|
96837
|
-
}
|
|
96838
|
-
if (!("type" in right)) {
|
|
96839
|
-
return 1;
|
|
96840
|
-
}
|
|
96841
|
-
const leftIndex = generationOrder.findIndex((type) => type === left.type);
|
|
96842
|
-
const rightIndex = generationOrder.findIndex((type) => type === right.type);
|
|
96843
|
-
return leftIndex - rightIndex;
|
|
96844
|
-
});
|
|
96845
|
-
}
|
|
96846
|
-
generateSingle(definition) {
|
|
96847
|
-
if (!("type" in definition)) {
|
|
96848
|
-
this.generateSchemaWithRef(definition);
|
|
96849
|
-
return;
|
|
96850
|
-
}
|
|
96851
|
-
switch (definition.type) {
|
|
96852
|
-
case "parameter":
|
|
96853
|
-
this.generateParameterDefinition(definition.schema);
|
|
96854
|
-
return;
|
|
96855
|
-
case "schema":
|
|
96856
|
-
this.generateSchemaWithRef(definition.schema);
|
|
96857
|
-
return;
|
|
96858
|
-
case "route":
|
|
96859
|
-
this.generateSingleRoute(definition.route);
|
|
96860
|
-
return;
|
|
96861
|
-
case "component":
|
|
96862
|
-
this.rawComponents.push(definition);
|
|
96863
|
-
return;
|
|
96864
|
-
}
|
|
96865
|
-
}
|
|
96866
|
-
generateParameterDefinition(zodSchema) {
|
|
96867
|
-
const refId = Metadata.getRefId(zodSchema);
|
|
96868
|
-
const result = this.generateParameter(zodSchema);
|
|
96869
|
-
if (refId) {
|
|
96870
|
-
this.paramRefs[refId] = result;
|
|
96871
|
-
}
|
|
96872
|
-
return result;
|
|
96873
|
-
}
|
|
96874
|
-
getParameterRef(schema, external) {
|
|
96875
|
-
const metadata = Metadata.getOpenApiMetadata(schema);
|
|
96876
|
-
const internalMetadata = Metadata.getInternalMetadata(schema);
|
|
96877
|
-
const parameterMetadata = metadata === null || metadata === undefined ? undefined : metadata.param;
|
|
96878
|
-
const existingRef = (internalMetadata === null || internalMetadata === undefined ? undefined : internalMetadata.refId) ? this.paramRefs[internalMetadata.refId] : undefined;
|
|
96879
|
-
if (!(internalMetadata === null || internalMetadata === undefined ? undefined : internalMetadata.refId) || !existingRef) {
|
|
96880
|
-
return;
|
|
96881
|
-
}
|
|
96882
|
-
if (parameterMetadata && existingRef.in !== parameterMetadata.in || (external === null || external === undefined ? undefined : external.in) && existingRef.in !== external.in) {
|
|
96883
|
-
throw new ConflictError(`Conflicting location for parameter ${existingRef.name}`, {
|
|
96884
|
-
key: "in",
|
|
96885
|
-
values: compact([
|
|
96886
|
-
existingRef.in,
|
|
96887
|
-
external === null || external === undefined ? undefined : external.in,
|
|
96888
|
-
parameterMetadata === null || parameterMetadata === undefined ? undefined : parameterMetadata.in
|
|
96889
|
-
])
|
|
96890
|
-
});
|
|
96891
|
-
}
|
|
96892
|
-
if (parameterMetadata && existingRef.name !== parameterMetadata.name || (external === null || external === undefined ? undefined : external.name) && existingRef.name !== (external === null || external === undefined ? undefined : external.name)) {
|
|
96893
|
-
throw new ConflictError(`Conflicting names for parameter`, {
|
|
96894
|
-
key: "name",
|
|
96895
|
-
values: compact([
|
|
96896
|
-
existingRef.name,
|
|
96897
|
-
external === null || external === undefined ? undefined : external.name,
|
|
96898
|
-
parameterMetadata === null || parameterMetadata === undefined ? undefined : parameterMetadata.name
|
|
96899
|
-
])
|
|
96900
|
-
});
|
|
96901
|
-
}
|
|
96902
|
-
return {
|
|
96903
|
-
$ref: `#/components/parameters/${internalMetadata.refId}`
|
|
96904
|
-
};
|
|
96905
|
-
}
|
|
96906
|
-
generateInlineParameters(zodSchema, location) {
|
|
96907
|
-
const metadata = Metadata.getOpenApiMetadata(zodSchema);
|
|
96908
|
-
const parameterMetadata = metadata === null || metadata === undefined ? undefined : metadata.param;
|
|
96909
|
-
const referencedSchema = this.getParameterRef(zodSchema, { in: location });
|
|
96910
|
-
if (referencedSchema) {
|
|
96911
|
-
return [referencedSchema];
|
|
96912
|
-
}
|
|
96913
|
-
if (isZodType(zodSchema, "ZodObject")) {
|
|
96914
|
-
const propTypes = zodSchema.def.shape;
|
|
96915
|
-
const parameters = Object.entries(propTypes).map(([key, schema]) => {
|
|
96916
|
-
var _a;
|
|
96917
|
-
const innerMetadata = Metadata.getOpenApiMetadata(schema);
|
|
96918
|
-
const referencedSchema2 = this.getParameterRef(schema, {
|
|
96919
|
-
in: location,
|
|
96920
|
-
name: key
|
|
96921
|
-
});
|
|
96922
|
-
if (referencedSchema2) {
|
|
96923
|
-
return referencedSchema2;
|
|
96924
|
-
}
|
|
96925
|
-
const innerParameterMetadata = innerMetadata === null || innerMetadata === undefined ? undefined : innerMetadata.param;
|
|
96926
|
-
if ((innerParameterMetadata === null || innerParameterMetadata === undefined ? undefined : innerParameterMetadata.name) && innerParameterMetadata.name !== key) {
|
|
96927
|
-
throw new ConflictError(`Conflicting names for parameter`, {
|
|
96928
|
-
key: "name",
|
|
96929
|
-
values: [key, innerParameterMetadata.name]
|
|
96930
|
-
});
|
|
96931
|
-
}
|
|
96932
|
-
if ((innerParameterMetadata === null || innerParameterMetadata === undefined ? undefined : innerParameterMetadata.in) && innerParameterMetadata.in !== location) {
|
|
96933
|
-
throw new ConflictError(`Conflicting location for parameter ${(_a = innerParameterMetadata.name) !== null && _a !== undefined ? _a : key}`, {
|
|
96934
|
-
key: "in",
|
|
96935
|
-
values: [location, innerParameterMetadata.in]
|
|
96936
|
-
});
|
|
96937
|
-
}
|
|
96938
|
-
return this.generateParameter(schema, { name: key, in: location });
|
|
96939
|
-
});
|
|
96940
|
-
return parameters;
|
|
96941
|
-
}
|
|
96942
|
-
if ((parameterMetadata === null || parameterMetadata === undefined ? undefined : parameterMetadata.in) && parameterMetadata.in !== location) {
|
|
96943
|
-
throw new ConflictError(`Conflicting location for parameter ${parameterMetadata.name}`, {
|
|
96944
|
-
key: "in",
|
|
96945
|
-
values: [location, parameterMetadata.in]
|
|
96946
|
-
});
|
|
96947
|
-
}
|
|
96948
|
-
return [this.generateParameter(zodSchema, { in: location })];
|
|
96949
|
-
}
|
|
96950
|
-
generateSimpleParameter(zodSchema, externalParamMetadata) {
|
|
96951
|
-
const metadata = Metadata.getParamMetadata(zodSchema);
|
|
96952
|
-
const paramMetadata = metadata === null || metadata === undefined ? undefined : metadata.param;
|
|
96953
|
-
const mergedParamMetadata = Object.assign(Object.assign({}, paramMetadata), externalParamMetadata);
|
|
96954
|
-
const required = !isOptionalSchema(zodSchema) && !isNullableSchema(zodSchema);
|
|
96955
|
-
const schema = this.generateSchemaWithRef(zodSchema);
|
|
96956
|
-
return Object.assign({
|
|
96957
|
-
schema,
|
|
96958
|
-
required
|
|
96959
|
-
}, Object.keys(mergedParamMetadata).length > 0 ? Metadata.buildParameterMetadata(mergedParamMetadata) : {});
|
|
96960
|
-
}
|
|
96961
|
-
generateParameter(zodSchema, externalParamMetadata) {
|
|
96962
|
-
var _a, _b;
|
|
96963
|
-
const metadata = Metadata.getOpenApiMetadata(zodSchema);
|
|
96964
|
-
const paramMetadata = metadata === null || metadata === undefined ? undefined : metadata.param;
|
|
96965
|
-
const paramName = (_a = externalParamMetadata === null || externalParamMetadata === undefined ? undefined : externalParamMetadata.name) !== null && _a !== undefined ? _a : paramMetadata === null || paramMetadata === undefined ? undefined : paramMetadata.name;
|
|
96966
|
-
const paramLocation = (_b = externalParamMetadata === null || externalParamMetadata === undefined ? undefined : externalParamMetadata.in) !== null && _b !== undefined ? _b : paramMetadata === null || paramMetadata === undefined ? undefined : paramMetadata.in;
|
|
96967
|
-
if (!paramName) {
|
|
96968
|
-
throw new MissingParameterDataError({ missingField: "name" });
|
|
96969
|
-
}
|
|
96970
|
-
if (!paramLocation) {
|
|
96971
|
-
throw new MissingParameterDataError({
|
|
96972
|
-
missingField: "in",
|
|
96973
|
-
paramName
|
|
96974
|
-
});
|
|
96975
|
-
}
|
|
96976
|
-
const baseParameter = this.generateSimpleParameter(zodSchema, externalParamMetadata);
|
|
96977
|
-
return Object.assign(Object.assign({}, baseParameter), { in: paramLocation, name: paramName });
|
|
96978
|
-
}
|
|
96979
|
-
generateSchemaWithMetadata(zodSchema) {
|
|
96980
|
-
const innerSchema = Metadata.unwrapChained(zodSchema);
|
|
96981
|
-
const metadata = Metadata.getOpenApiMetadata(zodSchema);
|
|
96982
|
-
const defaultValue = Metadata.getDefaultValue(zodSchema);
|
|
96983
|
-
const refId = Metadata.getRefId(zodSchema);
|
|
96984
|
-
if (refId && typeof this.schemaRefs[refId] === "object") {
|
|
96985
|
-
return this.schemaRefs[refId];
|
|
96986
|
-
}
|
|
96987
|
-
if (refId && this.schemaRefs[refId] === "pending") {
|
|
96988
|
-
const refSchema = { $ref: this.generateSchemaRef(refId) };
|
|
96989
|
-
return this.versionSpecifics.mapNullableOfRef(refSchema, isNullableSchema(zodSchema));
|
|
96990
|
-
}
|
|
96991
|
-
if (refId && !this.schemaRefs[refId]) {
|
|
96992
|
-
this.schemaRefs[refId] = "pending";
|
|
96993
|
-
}
|
|
96994
|
-
const result = (metadata === null || metadata === undefined ? undefined : metadata.type) ? { type: metadata.type } : this.toOpenAPISchema(innerSchema, isNullableSchema(zodSchema), defaultValue);
|
|
96995
|
-
return metadata ? Metadata.applySchemaMetadata(result, metadata) : omitBy(result, isUndefined);
|
|
96996
|
-
}
|
|
96997
|
-
constructReferencedOpenAPISchema(zodSchema) {
|
|
96998
|
-
const metadata = Metadata.getOpenApiMetadata(zodSchema);
|
|
96999
|
-
const innerSchema = Metadata.unwrapChained(zodSchema);
|
|
97000
|
-
const defaultValue = Metadata.getDefaultValue(zodSchema);
|
|
97001
|
-
const isNullable = isNullableSchema(zodSchema);
|
|
97002
|
-
if (metadata === null || metadata === undefined ? undefined : metadata.type) {
|
|
97003
|
-
return this.versionSpecifics.mapNullableType(metadata.type, isNullable);
|
|
97004
|
-
}
|
|
97005
|
-
const refId = Metadata.getRefId(zodSchema);
|
|
97006
|
-
if (refId && typeof this.schemaRefs[refId] === "object") {
|
|
97007
|
-
return LazyTransformer.mapRecursive(this.schemaRefs[refId], (schema) => this.versionSpecifics.mapNullableType(schema, isNullable), (schema) => this.versionSpecifics.mapNullableOfRef(schema, isNullable));
|
|
97008
|
-
}
|
|
97009
|
-
if (refId && this.schemaRefs[refId] === "pending") {
|
|
97010
|
-
const refSchema = { $ref: this.generateSchemaRef(refId) };
|
|
97011
|
-
return this.versionSpecifics.mapNullableOfRef(refSchema, isNullable);
|
|
97012
|
-
}
|
|
97013
|
-
if (refId && !this.schemaRefs[refId]) {
|
|
97014
|
-
this.schemaRefs[refId] = "pending";
|
|
97015
|
-
}
|
|
97016
|
-
return this.toOpenAPISchema(innerSchema, isNullable, defaultValue);
|
|
97017
|
-
}
|
|
97018
|
-
generateSimpleSchema(zodSchema) {
|
|
97019
|
-
const metadata = Metadata.getOpenApiMetadata(zodSchema);
|
|
97020
|
-
const refId = Metadata.getRefId(zodSchema);
|
|
97021
|
-
if (!refId || !this.schemaRefs[refId]) {
|
|
97022
|
-
return this.generateSchemaWithMetadata(zodSchema);
|
|
97023
|
-
}
|
|
97024
|
-
const schemaRef = this.schemaRefs[refId];
|
|
97025
|
-
const referenceObject = {
|
|
97026
|
-
$ref: this.generateSchemaRef(refId)
|
|
97027
|
-
};
|
|
97028
|
-
if (this.schemaRefs[refId] === "pending") {
|
|
97029
|
-
return this.versionSpecifics.mapNullableOfRef(referenceObject, isNullableSchema(zodSchema));
|
|
97030
|
-
}
|
|
97031
|
-
const newMetadata = omitBy(Metadata.buildSchemaMetadata(metadata !== null && metadata !== undefined ? metadata : {}), (value, key) => value === undefined || objectEquals(value, schemaRef[key]));
|
|
97032
|
-
if (newMetadata.type) {
|
|
97033
|
-
return {
|
|
97034
|
-
allOf: [referenceObject, newMetadata]
|
|
97035
|
-
};
|
|
97036
|
-
}
|
|
97037
|
-
const newSchemaMetadata = omitBy(this.constructReferencedOpenAPISchema(zodSchema), (value, key) => value === undefined || objectEquals(value, schemaRef[key]));
|
|
97038
|
-
const appliedMetadata = Metadata.applySchemaMetadata(newSchemaMetadata, newMetadata);
|
|
97039
|
-
if (Object.keys(appliedMetadata).length > 0) {
|
|
97040
|
-
return {
|
|
97041
|
-
allOf: [referenceObject, appliedMetadata]
|
|
97042
|
-
};
|
|
97043
|
-
}
|
|
97044
|
-
return referenceObject;
|
|
97045
|
-
}
|
|
97046
|
-
generateSchemaWithRef(zodSchema) {
|
|
97047
|
-
const refId = Metadata.getRefId(zodSchema);
|
|
97048
|
-
if (refId && !this.schemaRefs[refId]) {
|
|
97049
|
-
this.schemaRefs[refId] = this.generateSimpleSchema(zodSchema);
|
|
97050
|
-
return { $ref: this.generateSchemaRef(refId) };
|
|
97051
|
-
}
|
|
97052
|
-
return this.generateSimpleSchema(zodSchema);
|
|
97053
|
-
}
|
|
97054
|
-
generateSchemaRef(refId) {
|
|
97055
|
-
return `#/components/schemas/${refId}`;
|
|
97056
|
-
}
|
|
97057
|
-
getRequestBody(requestBody) {
|
|
97058
|
-
if (!requestBody) {
|
|
97059
|
-
return;
|
|
97060
|
-
}
|
|
97061
|
-
const { content } = requestBody, rest = __rest(requestBody, ["content"]);
|
|
97062
|
-
const requestBodyContent = this.getBodyContent(content);
|
|
97063
|
-
return Object.assign(Object.assign({}, rest), { content: requestBodyContent });
|
|
97064
|
-
}
|
|
97065
|
-
getParameters(request) {
|
|
97066
|
-
if (!request) {
|
|
97067
|
-
return [];
|
|
97068
|
-
}
|
|
97069
|
-
const { headers: headers2 } = request;
|
|
97070
|
-
const query = this.cleanParameter(request.query);
|
|
97071
|
-
const params = this.cleanParameter(request.params);
|
|
97072
|
-
const cookies = this.cleanParameter(request.cookies);
|
|
97073
|
-
const queryParameters = enhanceMissingParametersError(() => query ? this.generateInlineParameters(query, "query") : [], { location: "query" });
|
|
97074
|
-
const pathParameters = enhanceMissingParametersError(() => params ? this.generateInlineParameters(params, "path") : [], { location: "path" });
|
|
97075
|
-
const cookieParameters = enhanceMissingParametersError(() => cookies ? this.generateInlineParameters(cookies, "cookie") : [], { location: "cookie" });
|
|
97076
|
-
const headerParameters = enhanceMissingParametersError(() => {
|
|
97077
|
-
if (Array.isArray(headers2)) {
|
|
97078
|
-
return headers2.flatMap((header) => this.generateInlineParameters(header, "header"));
|
|
97079
|
-
}
|
|
97080
|
-
const cleanHeaders = this.cleanParameter(headers2);
|
|
97081
|
-
return cleanHeaders ? this.generateInlineParameters(cleanHeaders, "header") : [];
|
|
97082
|
-
}, { location: "header" });
|
|
97083
|
-
return [
|
|
97084
|
-
...pathParameters,
|
|
97085
|
-
...queryParameters,
|
|
97086
|
-
...headerParameters,
|
|
97087
|
-
...cookieParameters
|
|
97088
|
-
];
|
|
97089
|
-
}
|
|
97090
|
-
cleanParameter(schema) {
|
|
97091
|
-
if (!schema) {
|
|
97092
|
-
return;
|
|
97093
|
-
}
|
|
97094
|
-
if (isZodType(schema, "ZodPipe")) {
|
|
97095
|
-
const inSchema = schema._zod.def.in;
|
|
97096
|
-
const outSchema = schema._zod.def.out;
|
|
97097
|
-
if (isZodType(inSchema, "ZodObject")) {
|
|
97098
|
-
return this.cleanParameter(inSchema);
|
|
97099
|
-
}
|
|
97100
|
-
if (isZodType(outSchema, "ZodObject")) {
|
|
97101
|
-
return this.cleanParameter(outSchema);
|
|
97102
|
-
}
|
|
97103
|
-
return;
|
|
97104
|
-
}
|
|
97105
|
-
return schema;
|
|
97106
|
-
}
|
|
97107
|
-
generatePath(route) {
|
|
97108
|
-
const { method, path, request, responses } = route, pathItemConfig = __rest(route, ["method", "path", "request", "responses"]);
|
|
97109
|
-
const generatedResponses = mapValues(responses, (response) => {
|
|
97110
|
-
return this.getResponse(response);
|
|
97111
|
-
});
|
|
97112
|
-
const parameters = enhanceMissingParametersError(() => this.getParameters(request), { route: `${method} ${path}` });
|
|
97113
|
-
const requestBody = this.getRequestBody(request === null || request === undefined ? undefined : request.body);
|
|
97114
|
-
const routeDoc = {
|
|
97115
|
-
[method]: Object.assign(Object.assign(Object.assign(Object.assign({}, pathItemConfig), parameters.length > 0 ? {
|
|
97116
|
-
parameters: [...pathItemConfig.parameters || [], ...parameters]
|
|
97117
|
-
} : {}), requestBody ? { requestBody } : {}), { responses: generatedResponses })
|
|
97118
|
-
};
|
|
97119
|
-
return routeDoc;
|
|
97120
|
-
}
|
|
97121
|
-
generateSingleRoute(route) {
|
|
97122
|
-
const routeDoc = this.generatePath(route);
|
|
97123
|
-
this.pathRefs[route.path] = Object.assign(Object.assign({}, this.pathRefs[route.path]), routeDoc);
|
|
97124
|
-
return routeDoc;
|
|
97125
|
-
}
|
|
97126
|
-
getResponse(response) {
|
|
97127
|
-
if (this.isReferenceObject(response)) {
|
|
97128
|
-
return response;
|
|
97129
|
-
}
|
|
97130
|
-
const { content, headers: headers2 } = response, rest = __rest(response, ["content", "headers"]);
|
|
97131
|
-
const responseContent = content ? { content: this.getBodyContent(content) } : {};
|
|
97132
|
-
if (!headers2) {
|
|
97133
|
-
return Object.assign(Object.assign({}, rest), responseContent);
|
|
97134
|
-
}
|
|
97135
|
-
const responseHeaders = isZodType(headers2, "ZodObject") ? this.getResponseHeaders(headers2) : headers2;
|
|
97136
|
-
return Object.assign(Object.assign(Object.assign({}, rest), { headers: responseHeaders }), responseContent);
|
|
97137
|
-
}
|
|
97138
|
-
isReferenceObject(schema) {
|
|
97139
|
-
return "$ref" in schema;
|
|
97140
|
-
}
|
|
97141
|
-
getResponseHeaders(headers2) {
|
|
97142
|
-
const schemaShape = headers2.def.shape;
|
|
97143
|
-
const responseHeaders = mapValues(schemaShape, (_) => this.generateSimpleParameter(_));
|
|
97144
|
-
return responseHeaders;
|
|
97145
|
-
}
|
|
97146
|
-
getBodyContent(content) {
|
|
97147
|
-
return mapValues(content, (config) => {
|
|
97148
|
-
if (!config || !isAnyZodType(config.schema)) {
|
|
97149
|
-
return config;
|
|
97150
|
-
}
|
|
97151
|
-
const { schema: configSchema } = config, rest = __rest(config, ["schema"]);
|
|
97152
|
-
const schema = this.generateSchemaWithRef(configSchema);
|
|
97153
|
-
return Object.assign({ schema }, rest);
|
|
97154
|
-
});
|
|
97155
|
-
}
|
|
97156
|
-
toOpenAPISchema(zodSchema, isNullable, defaultValue) {
|
|
97157
|
-
const result = this.openApiTransformer.transform(zodSchema, isNullable, (_) => this.generateSchemaWithRef(_), (_) => this.generateSchemaRef(_), defaultValue);
|
|
97158
|
-
return result;
|
|
97159
|
-
}
|
|
97160
|
-
}
|
|
97161
|
-
class OpenApiGeneratorV31Specifics {
|
|
97162
|
-
get nullType() {
|
|
97163
|
-
return { type: "null" };
|
|
97164
|
-
}
|
|
97165
|
-
mapNullableOfArray(objects, isNullable) {
|
|
97166
|
-
if (isNullable && !objects.some((object4) => objectEquals(object4, this.nullType))) {
|
|
97167
|
-
return [...objects, this.nullType];
|
|
97168
|
-
}
|
|
97169
|
-
return objects;
|
|
97170
|
-
}
|
|
97171
|
-
mapNullableType(type, isNullable) {
|
|
97172
|
-
if (!type) {
|
|
97173
|
-
return {};
|
|
97174
|
-
}
|
|
97175
|
-
if (isNullable) {
|
|
97176
|
-
const typeArray = Array.isArray(type) ? type : [type];
|
|
97177
|
-
const nullableType = uniq([...typeArray, "null"]);
|
|
97178
|
-
return { type: nullableType };
|
|
97179
|
-
}
|
|
97180
|
-
return { type };
|
|
97181
|
-
}
|
|
97182
|
-
mapNullableOfRef(ref, isNullable) {
|
|
97183
|
-
if (isNullable) {
|
|
97184
|
-
return {
|
|
97185
|
-
oneOf: [ref, this.nullType]
|
|
97186
|
-
};
|
|
97187
|
-
}
|
|
97188
|
-
return ref;
|
|
97189
|
-
}
|
|
97190
|
-
mapTupleItems(schemas2) {
|
|
97191
|
-
return {
|
|
97192
|
-
prefixItems: schemas2
|
|
97193
|
-
};
|
|
97194
|
-
}
|
|
97195
|
-
getNumberChecks(checks2) {
|
|
97196
|
-
return Object.assign({}, ...checks2.map((check) => {
|
|
97197
|
-
switch (check._zod.def.check) {
|
|
97198
|
-
case "greater_than": {
|
|
97199
|
-
const greaterThanCheck = check;
|
|
97200
|
-
return greaterThanCheck._zod.def.inclusive ? { minimum: Number(greaterThanCheck._zod.def.value) } : { exclusiveMinimum: Number(greaterThanCheck._zod.def.value) };
|
|
97201
|
-
}
|
|
97202
|
-
case "less_than": {
|
|
97203
|
-
const lessThanCheck = check;
|
|
97204
|
-
return lessThanCheck._zod.def.inclusive ? { maximum: Number(lessThanCheck._zod.def.value) } : { exclusiveMaximum: Number(lessThanCheck._zod.def.value) };
|
|
97205
|
-
}
|
|
97206
|
-
default:
|
|
97207
|
-
return {};
|
|
97208
|
-
}
|
|
97209
|
-
}));
|
|
97210
|
-
}
|
|
97211
|
-
}
|
|
97212
|
-
function isWebhookDefinition(definition) {
|
|
97213
|
-
return "type" in definition && definition.type === "webhook";
|
|
97214
|
-
}
|
|
97215
|
-
|
|
97216
|
-
class OpenApiGeneratorV31 {
|
|
97217
|
-
constructor(definitions, options) {
|
|
97218
|
-
this.definitions = definitions;
|
|
97219
|
-
this.webhookRefs = {};
|
|
97220
|
-
const specifics = new OpenApiGeneratorV31Specifics;
|
|
97221
|
-
this.generator = new OpenAPIGenerator(this.definitions, specifics, options);
|
|
97222
|
-
}
|
|
97223
|
-
generateDocument(config) {
|
|
97224
|
-
const baseDocument = this.generator.generateDocumentData();
|
|
97225
|
-
this.definitions.filter(isWebhookDefinition).forEach((definition) => this.generateSingleWebhook(definition.webhook));
|
|
97226
|
-
return Object.assign(Object.assign(Object.assign({}, config), baseDocument), { webhooks: this.webhookRefs });
|
|
97227
|
-
}
|
|
97228
|
-
generateComponents() {
|
|
97229
|
-
return this.generator.generateComponents();
|
|
97230
|
-
}
|
|
97231
|
-
generateSingleWebhook(route) {
|
|
97232
|
-
const routeDoc = this.generator.generatePath(route);
|
|
97233
|
-
this.webhookRefs[route.path] = Object.assign(Object.assign({}, this.webhookRefs[route.path]), routeDoc);
|
|
97234
|
-
return routeDoc;
|
|
97235
|
-
}
|
|
97236
|
-
}
|
|
97237
|
-
var $OpenAPIRegistry = OpenAPIRegistry;
|
|
97238
|
-
var $OpenApiGeneratorV31 = OpenApiGeneratorV31;
|
|
97239
|
-
var $extendZodWithOpenApi = extendZodWithOpenApi;
|
|
97240
|
-
|
|
97241
95827
|
// src/http/openapi.ts
|
|
97242
|
-
|
|
95828
|
+
init_dist();
|
|
97243
95829
|
init_constants();
|
|
95830
|
+
init_zod_openapi();
|
|
97244
95831
|
|
|
97245
95832
|
// src/http/route-def.ts
|
|
97246
95833
|
init_zod();
|
|
@@ -97310,7 +95897,10 @@ async function parseBody(req) {
|
|
|
97310
95897
|
for await (const chunk of req) {
|
|
97311
95898
|
chunks.push(chunk);
|
|
97312
95899
|
}
|
|
97313
|
-
|
|
95900
|
+
const raw = Buffer.concat(chunks).toString();
|
|
95901
|
+
if (raw.trim() === "")
|
|
95902
|
+
return {};
|
|
95903
|
+
return JSON.parse(raw);
|
|
97314
95904
|
}
|
|
97315
95905
|
var BODY_TOO_LARGE = Symbol("body-too-large");
|
|
97316
95906
|
function enforceContentLengthCap(req, res, maxBytes) {
|
|
@@ -97415,10 +96005,24 @@ function describeRequestRoute(method, pathSegments) {
|
|
|
97415
96005
|
const first = pathSegments[0];
|
|
97416
96006
|
return { spanName: first ? `${m} /${first}` : m };
|
|
97417
96007
|
}
|
|
96008
|
+
var VALIDATE_RESPONSES = true;
|
|
97418
96009
|
function route(def) {
|
|
97419
96010
|
routeRegistry.push(def);
|
|
97420
96011
|
return {
|
|
97421
96012
|
def,
|
|
96013
|
+
respond(res, code, data) {
|
|
96014
|
+
if (VALIDATE_RESPONSES) {
|
|
96015
|
+
const schema = def.responses[code]?.schema;
|
|
96016
|
+
if (schema) {
|
|
96017
|
+
const result = schema.safeParse(data);
|
|
96018
|
+
if (!result.success) {
|
|
96019
|
+
throw new Error(`Response schema violation: ${def.method.toUpperCase()} ${def.path} ${code} — ` + result.error.issues.map((i) => `${i.path.join(".") || "<root>"}: ${i.message}`).join("; "));
|
|
96020
|
+
}
|
|
96021
|
+
}
|
|
96022
|
+
}
|
|
96023
|
+
res.writeHead(code, { "Content-Type": "application/json" });
|
|
96024
|
+
res.end(JSON.stringify(data));
|
|
96025
|
+
},
|
|
97422
96026
|
match(method, pathSegments) {
|
|
97423
96027
|
return matchRoute(method, pathSegments, def.method.toUpperCase(), def.pattern, def.exact ?? true);
|
|
97424
96028
|
},
|
|
@@ -97449,18 +96053,18 @@ function route(def) {
|
|
|
97449
96053
|
}
|
|
97450
96054
|
|
|
97451
96055
|
// src/http/openapi.ts
|
|
97452
|
-
|
|
96056
|
+
var ErrorResponseSchema = exports_zod.looseObject({ error: exports_zod.string() }).openapi("ErrorResponse", { description: "Standard error envelope" });
|
|
97453
96057
|
var cachedSpec = null;
|
|
97454
96058
|
function generateOpenApiSpec(opts) {
|
|
97455
96059
|
if (cachedSpec)
|
|
97456
96060
|
return cachedSpec;
|
|
97457
|
-
const
|
|
97458
|
-
|
|
96061
|
+
const registry = new $OpenAPIRegistry;
|
|
96062
|
+
registry.registerComponent("securitySchemes", "bearerAuth", {
|
|
97459
96063
|
type: "http",
|
|
97460
96064
|
scheme: "bearer",
|
|
97461
96065
|
description: "API key via Authorization: Bearer <API_KEY>"
|
|
97462
96066
|
});
|
|
97463
|
-
|
|
96067
|
+
registry.registerComponent("securitySchemes", "agentId", {
|
|
97464
96068
|
type: "apiKey",
|
|
97465
96069
|
in: "header",
|
|
97466
96070
|
name: "X-Agent-ID",
|
|
@@ -97469,11 +96073,12 @@ function generateOpenApiSpec(opts) {
|
|
|
97469
96073
|
for (const routeDef of routeRegistry) {
|
|
97470
96074
|
const responses = {};
|
|
97471
96075
|
for (const [code, resDef] of Object.entries(routeDef.responses)) {
|
|
96076
|
+
const schema = resDef.schema ?? (Number(code) >= 400 && !resDef.unstructured ? ErrorResponseSchema : undefined);
|
|
97472
96077
|
responses[code] = {
|
|
97473
96078
|
description: resDef.description,
|
|
97474
|
-
...
|
|
96079
|
+
...schema && {
|
|
97475
96080
|
content: {
|
|
97476
|
-
"application/json": { schema
|
|
96081
|
+
"application/json": { schema }
|
|
97477
96082
|
}
|
|
97478
96083
|
}
|
|
97479
96084
|
};
|
|
@@ -97488,7 +96093,7 @@ function generateOpenApiSpec(opts) {
|
|
|
97488
96093
|
content: { "application/json": { schema: routeDef.body } }
|
|
97489
96094
|
};
|
|
97490
96095
|
}
|
|
97491
|
-
|
|
96096
|
+
registry.registerPath({
|
|
97492
96097
|
method: routeDef.method,
|
|
97493
96098
|
path: routeDef.path,
|
|
97494
96099
|
operationId: routeDef.operationId,
|
|
@@ -97501,7 +96106,36 @@ function generateOpenApiSpec(opts) {
|
|
|
97501
96106
|
});
|
|
97502
96107
|
}
|
|
97503
96108
|
const serverUrl = opts.serverUrl || getPublicMcpBaseUrl();
|
|
97504
|
-
|
|
96109
|
+
function fixNullableAllOf(node) {
|
|
96110
|
+
if (!node || typeof node !== "object")
|
|
96111
|
+
return;
|
|
96112
|
+
if (Array.isArray(node)) {
|
|
96113
|
+
for (const item of node)
|
|
96114
|
+
fixNullableAllOf(item);
|
|
96115
|
+
return;
|
|
96116
|
+
}
|
|
96117
|
+
const obj = node;
|
|
96118
|
+
const allOf = obj.allOf;
|
|
96119
|
+
if (Array.isArray(allOf)) {
|
|
96120
|
+
let hadNull = false;
|
|
96121
|
+
for (const member of allOf) {
|
|
96122
|
+
if (member && Array.isArray(member.type) && member.type.includes("null")) {
|
|
96123
|
+
hadNull = true;
|
|
96124
|
+
const rest = member.type.filter((t) => t !== "null");
|
|
96125
|
+
member.type = rest.length === 1 ? rest[0] : rest;
|
|
96126
|
+
}
|
|
96127
|
+
}
|
|
96128
|
+
if (hadNull) {
|
|
96129
|
+
const members = allOf.filter((m) => !(Object.keys(m).length === 1 && m.type === "object"));
|
|
96130
|
+
const intersection3 = members.length === 1 ? members[0] : { allOf: members };
|
|
96131
|
+
delete obj.allOf;
|
|
96132
|
+
obj.anyOf = [intersection3, { type: "null" }];
|
|
96133
|
+
}
|
|
96134
|
+
}
|
|
96135
|
+
for (const value of Object.values(obj))
|
|
96136
|
+
fixNullableAllOf(value);
|
|
96137
|
+
}
|
|
96138
|
+
const generator = new $OpenApiGeneratorV31(registry.definitions);
|
|
97505
96139
|
const doc = generator.generateDocument({
|
|
97506
96140
|
openapi: "3.1.0",
|
|
97507
96141
|
info: {
|
|
@@ -97518,6 +96152,8 @@ function generateOpenApiSpec(opts) {
|
|
|
97518
96152
|
}
|
|
97519
96153
|
]
|
|
97520
96154
|
});
|
|
96155
|
+
fixNullableAllOf(doc.paths);
|
|
96156
|
+
fixNullableAllOf(doc.components);
|
|
97521
96157
|
cachedSpec = JSON.stringify(doc, null, 2);
|
|
97522
96158
|
return cachedSpec;
|
|
97523
96159
|
}
|
|
@@ -97880,7 +96516,7 @@ async function initOtel(serviceRole = process.env.AGENT_ROLE || "api") {
|
|
|
97880
96516
|
return;
|
|
97881
96517
|
initialized6 = true;
|
|
97882
96518
|
try {
|
|
97883
|
-
const impl = await import("./otel-impl-
|
|
96519
|
+
const impl = await import("./otel-impl-p6jvgd9c.js");
|
|
97884
96520
|
await impl.boot(serviceRole);
|
|
97885
96521
|
realWithSpan = impl.withSpan;
|
|
97886
96522
|
realStartSpan = impl.startSpan;
|
|
@@ -98069,6 +96705,14 @@ var NUDGES = {
|
|
|
98069
96705
|
const results = r.data?.results;
|
|
98070
96706
|
return Array.isArray(results) && results.some((entry) => Boolean(entry?.rateHint)) ? "Rate memories that help or mislead you with memory_rate." : undefined;
|
|
98071
96707
|
},
|
|
96708
|
+
"app-get": (r) => {
|
|
96709
|
+
if (!r.ok)
|
|
96710
|
+
return;
|
|
96711
|
+
const definition = r.data?.app?.definition;
|
|
96712
|
+
const hasQueries = Object.keys(definition?.queries ?? {}).length > 0;
|
|
96713
|
+
const hasActions = Object.keys(definition?.actions ?? {}).length > 0;
|
|
96714
|
+
return hasQueries || hasActions ? "This app's callable surface is `definition.queries` (run with `app-query`, passing any `$param` values) and `definition.actions` (invoke with `POST /api/apps/<id>/actions/<name>`; `sync` actions refresh sources)." : undefined;
|
|
96715
|
+
},
|
|
98072
96716
|
"kv-get": (r) => {
|
|
98073
96717
|
if (!r.ok)
|
|
98074
96718
|
return;
|
|
@@ -98560,13 +97204,41 @@ function validValue(column, value) {
|
|
|
98560
97204
|
return typeof value === "string" && isIso8601Date(value);
|
|
98561
97205
|
return typeof value === "string" && Boolean(column.enum?.includes(value));
|
|
98562
97206
|
}
|
|
98563
|
-
function
|
|
97207
|
+
function joinKeyColumnNames(definition) {
|
|
97208
|
+
const names = new Set;
|
|
97209
|
+
for (const source of Object.values(definition.sources ?? {}))
|
|
97210
|
+
names.add(source.joinKey);
|
|
97211
|
+
return names;
|
|
97212
|
+
}
|
|
97213
|
+
function sourceEnvelope(options) {
|
|
97214
|
+
return options.allowSourceManaged === true ? options.envelope : undefined;
|
|
97215
|
+
}
|
|
97216
|
+
function prepareValues(definition, values, mode, options = {}) {
|
|
98564
97217
|
const issues = [];
|
|
98565
97218
|
const prepared = { ...values };
|
|
97219
|
+
const sourceManaged = options.allowSourceManaged === true;
|
|
97220
|
+
if (sourceManaged && !options.envelope) {
|
|
97221
|
+
throw new Error("allowSourceManaged writes must carry an envelope");
|
|
97222
|
+
}
|
|
97223
|
+
const joinKeys = sourceManaged ? new Set : joinKeyColumnNames(definition);
|
|
98566
97224
|
for (const name of Object.keys(values)) {
|
|
98567
97225
|
const column = Object.hasOwn(definition.columns, name) ? definition.columns[name] : undefined;
|
|
98568
97226
|
if (!column || column.hidden === true) {
|
|
98569
97227
|
issues.push({ path: `values.${name}`, message: `unknown or hidden column "${name}"` });
|
|
97228
|
+
continue;
|
|
97229
|
+
}
|
|
97230
|
+
if (sourceManaged)
|
|
97231
|
+
continue;
|
|
97232
|
+
if (column.source) {
|
|
97233
|
+
issues.push({
|
|
97234
|
+
path: `values.${name}`,
|
|
97235
|
+
message: `column is a read-only projection from source "${column.source.of}"; mutate it via the source or a sync refresh`
|
|
97236
|
+
});
|
|
97237
|
+
} else if (joinKeys.has(name)) {
|
|
97238
|
+
issues.push({
|
|
97239
|
+
path: `values.${name}`,
|
|
97240
|
+
message: "column is the sync join key and is managed by the sync engine"
|
|
97241
|
+
});
|
|
98570
97242
|
}
|
|
98571
97243
|
}
|
|
98572
97244
|
if (mode === "create") {
|
|
@@ -98575,6 +97247,8 @@ function prepareValues(definition, values, mode) {
|
|
|
98575
97247
|
continue;
|
|
98576
97248
|
if (!Object.hasOwn(prepared, name) && column.default !== undefined)
|
|
98577
97249
|
prepared[name] = column.default;
|
|
97250
|
+
if (sourceManaged && column.source)
|
|
97251
|
+
continue;
|
|
98578
97252
|
if (column.required === true && (!Object.hasOwn(prepared, name) || prepared[name] === undefined || prepared[name] === null)) {
|
|
98579
97253
|
issues.push({ path: `values.${name}`, message: "required column is missing" });
|
|
98580
97254
|
}
|
|
@@ -98626,25 +97300,33 @@ function currentModelDefinition(appId2, model) {
|
|
|
98626
97300
|
return null;
|
|
98627
97301
|
}
|
|
98628
97302
|
}
|
|
98629
|
-
function createRowUnlocked(appId2, model, definition, prepared,
|
|
97303
|
+
function createRowUnlocked(appId2, model, definition, prepared, options) {
|
|
98630
97304
|
const issuedMs = Math.max(Date.now(), lastCreatedAtMs + 1);
|
|
98631
97305
|
lastCreatedAtMs = issuedMs;
|
|
98632
97306
|
const now = new Date(issuedMs).toISOString();
|
|
97307
|
+
const actor = options.actor;
|
|
98633
97308
|
return writeRow(appId2, model, definition, {
|
|
98634
97309
|
id: crypto.randomUUID(),
|
|
98635
97310
|
createdAt: now,
|
|
98636
97311
|
updatedAt: now,
|
|
98637
97312
|
...actor !== undefined ? { createdBy: actor, updatedBy: actor } : {},
|
|
98638
|
-
...prepared
|
|
97313
|
+
...prepared,
|
|
97314
|
+
...sourceEnvelope(options)
|
|
98639
97315
|
});
|
|
98640
97316
|
}
|
|
97317
|
+
function createAppRowUnlocked(appId2, model, definition, values, options = {}) {
|
|
97318
|
+
const prepared = prepareValues(definition, values, "create", options);
|
|
97319
|
+
if (!appExists(appId2))
|
|
97320
|
+
throw new AppRowAppNotFoundError(appId2);
|
|
97321
|
+
return createRowUnlocked(appId2, model, definition, prepared, options);
|
|
97322
|
+
}
|
|
98641
97323
|
function createAppRow(appId2, model, _definition, values, options = {}) {
|
|
98642
97324
|
return withMutationLock(appId2, model, () => {
|
|
98643
97325
|
const currentDefinition = currentModelDefinition(appId2, model);
|
|
98644
97326
|
if (!currentDefinition)
|
|
98645
97327
|
throw new AppRowAppNotFoundError(appId2);
|
|
98646
|
-
const prepared = prepareValues(currentDefinition, values, "create");
|
|
98647
|
-
return createRowUnlocked(appId2, model, currentDefinition, prepared, options
|
|
97328
|
+
const prepared = prepareValues(currentDefinition, values, "create", options);
|
|
97329
|
+
return createRowUnlocked(appId2, model, currentDefinition, prepared, options);
|
|
98648
97330
|
});
|
|
98649
97331
|
}
|
|
98650
97332
|
function createAppRows(appId2, model, _definition, rows, options = {}) {
|
|
@@ -98652,8 +97334,8 @@ function createAppRows(appId2, model, _definition, rows, options = {}) {
|
|
|
98652
97334
|
const currentDefinition = currentModelDefinition(appId2, model);
|
|
98653
97335
|
if (!currentDefinition)
|
|
98654
97336
|
throw new AppRowAppNotFoundError(appId2);
|
|
98655
|
-
const prepared = rows.map((values) => prepareValues(currentDefinition, values, "create"));
|
|
98656
|
-
return prepared.map((values) => createRowUnlocked(appId2, model, currentDefinition, values, options
|
|
97337
|
+
const prepared = rows.map((values) => prepareValues(currentDefinition, values, "create", options));
|
|
97338
|
+
return prepared.map((values) => createRowUnlocked(appId2, model, currentDefinition, values, options));
|
|
98657
97339
|
});
|
|
98658
97340
|
}
|
|
98659
97341
|
function getAppRow(appId2, model, rowId) {
|
|
@@ -98690,7 +97372,7 @@ function patchAppRow(appId2, model, _definition, rowId, values, options = {}) {
|
|
|
98690
97372
|
const currentDefinition = currentModelDefinition(appId2, model);
|
|
98691
97373
|
if (!currentDefinition)
|
|
98692
97374
|
throw new AppRowAppNotFoundError(appId2);
|
|
98693
|
-
const prepared = prepareValues(currentDefinition, values, "patch");
|
|
97375
|
+
const prepared = prepareValues(currentDefinition, values, "patch", options);
|
|
98694
97376
|
return patchPreparedRowUnlocked(appId2, model, currentDefinition, rowId, prepared, options);
|
|
98695
97377
|
});
|
|
98696
97378
|
}
|
|
@@ -98714,6 +97396,7 @@ function patchPreparedRowUnlocked(appId2, model, definition, rowId, prepared, op
|
|
|
98714
97396
|
updated[name] = value;
|
|
98715
97397
|
}
|
|
98716
97398
|
}
|
|
97399
|
+
Object.assign(updated, sourceEnvelope(options));
|
|
98717
97400
|
const newKeys = new Set(indexKeys(model, definition, updated));
|
|
98718
97401
|
const namespace = appsNamespace(appId2);
|
|
98719
97402
|
for (const key of oldKeys)
|
|
@@ -98726,6 +97409,10 @@ function patchPreparedRowUnlocked(appId2, model, definition, rowId, prepared, op
|
|
|
98726
97409
|
}
|
|
98727
97410
|
return updated;
|
|
98728
97411
|
}
|
|
97412
|
+
function patchAppRowUnlocked(appId2, model, definition, rowId, values, options = {}) {
|
|
97413
|
+
const prepared = prepareValues(definition, values, "patch", options);
|
|
97414
|
+
return patchPreparedRowUnlocked(appId2, model, definition, rowId, prepared, options);
|
|
97415
|
+
}
|
|
98729
97416
|
function writeAppRowForMigrationUnlocked(appId2, model, row) {
|
|
98730
97417
|
upsertKv({
|
|
98731
97418
|
namespace: appsNamespace(appId2),
|
|
@@ -98802,6 +97489,572 @@ function purgeAppRows(appId2, models, afterPurge) {
|
|
|
98802
97489
|
return acquire(0);
|
|
98803
97490
|
}
|
|
98804
97491
|
|
|
97492
|
+
// src/apps/sync.ts
|
|
97493
|
+
init_zod();
|
|
97494
|
+
init_db();
|
|
97495
|
+
init_types();
|
|
97496
|
+
init_secret_scrubber();
|
|
97497
|
+
var MAX_PULL_RECORDS = 500;
|
|
97498
|
+
var MAX_PASS_WARNINGS = 20;
|
|
97499
|
+
var MAX_TASK_LIMIT = 200;
|
|
97500
|
+
var DEFAULT_TASK_LIMIT = 100;
|
|
97501
|
+
var MAX_TASK_PROMPT_CHARS = 1000;
|
|
97502
|
+
var MAX_ERROR_DETAIL_CHARS = 500;
|
|
97503
|
+
|
|
97504
|
+
class SyncPassError extends Error {
|
|
97505
|
+
constructor(message) {
|
|
97506
|
+
super(message);
|
|
97507
|
+
this.name = "SyncPassError";
|
|
97508
|
+
}
|
|
97509
|
+
}
|
|
97510
|
+
|
|
97511
|
+
class TransformError extends Error {
|
|
97512
|
+
}
|
|
97513
|
+
function warn(warnings, message) {
|
|
97514
|
+
if (warnings.length < MAX_PASS_WARNINGS)
|
|
97515
|
+
warnings.push(message);
|
|
97516
|
+
}
|
|
97517
|
+
function syncStatusKey(model, source) {
|
|
97518
|
+
return `sync-status:${model}:${source}`;
|
|
97519
|
+
}
|
|
97520
|
+
function writeSyncStatus(appId2, pass, lastStartedAt) {
|
|
97521
|
+
if (!getApp(appId2))
|
|
97522
|
+
return;
|
|
97523
|
+
const status = {
|
|
97524
|
+
lastStartedAt,
|
|
97525
|
+
lastFinishedAt: new Date().toISOString(),
|
|
97526
|
+
ok: pass.error === undefined,
|
|
97527
|
+
created: pass.created,
|
|
97528
|
+
updated: pass.updated,
|
|
97529
|
+
refreshed: pass.refreshed,
|
|
97530
|
+
markedStale: pass.markedStale,
|
|
97531
|
+
...pass.error === undefined ? {} : { error: pass.error }
|
|
97532
|
+
};
|
|
97533
|
+
upsertKv({
|
|
97534
|
+
namespace: appsNamespace(appId2),
|
|
97535
|
+
key: syncStatusKey(pass.model, pass.source),
|
|
97536
|
+
value: status,
|
|
97537
|
+
valueType: "json"
|
|
97538
|
+
});
|
|
97539
|
+
}
|
|
97540
|
+
function getAppSyncStatus(appId2, model, source) {
|
|
97541
|
+
const entry = getKv(appsNamespace(appId2), syncStatusKey(model, source));
|
|
97542
|
+
const value = entry?.value;
|
|
97543
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
97544
|
+
return null;
|
|
97545
|
+
return value;
|
|
97546
|
+
}
|
|
97547
|
+
function collectAppSyncStatus(appId2) {
|
|
97548
|
+
const statuses = {};
|
|
97549
|
+
const app = getApp(appId2);
|
|
97550
|
+
if (!app || appDefinitionNeedsRepair(app))
|
|
97551
|
+
return statuses;
|
|
97552
|
+
for (const [modelName, model] of Object.entries(app.definition.models)) {
|
|
97553
|
+
for (const sourceName of Object.keys(model.sources ?? {})) {
|
|
97554
|
+
const status = getAppSyncStatus(appId2, modelName, sourceName);
|
|
97555
|
+
if (status)
|
|
97556
|
+
statuses[`${modelName}:${sourceName}`] = status;
|
|
97557
|
+
}
|
|
97558
|
+
}
|
|
97559
|
+
return statuses;
|
|
97560
|
+
}
|
|
97561
|
+
function invalidateChangedSyncStatus(appId2, previous, next) {
|
|
97562
|
+
if (!previous)
|
|
97563
|
+
return;
|
|
97564
|
+
for (const [modelName, oldModel] of Object.entries(previous.models)) {
|
|
97565
|
+
for (const [sourceName, oldSource] of Object.entries(oldModel.sources ?? {})) {
|
|
97566
|
+
const nextModel = next.models[modelName];
|
|
97567
|
+
const nextSource = nextModel?.sources?.[sourceName];
|
|
97568
|
+
const unchanged = nextModel !== undefined && nextSource !== undefined && pairFingerprint(nextModel, sourceName, nextSource) === pairFingerprint(oldModel, sourceName, oldSource);
|
|
97569
|
+
if (!unchanged)
|
|
97570
|
+
deleteKv(appsNamespace(appId2), syncStatusKey(modelName, sourceName));
|
|
97571
|
+
}
|
|
97572
|
+
}
|
|
97573
|
+
}
|
|
97574
|
+
var SourceRecordSchema = object({
|
|
97575
|
+
key: union([string().min(1), number()]).transform(String),
|
|
97576
|
+
fields: record(string(), unknown())
|
|
97577
|
+
});
|
|
97578
|
+
var PullPayloadSchema = union([
|
|
97579
|
+
array(SourceRecordSchema),
|
|
97580
|
+
object({ records: array(SourceRecordSchema), complete: boolean().optional() })
|
|
97581
|
+
]);
|
|
97582
|
+
function scriptFailure(output) {
|
|
97583
|
+
if (output.exitCode === 0 && !output.error && !output.runtimeError)
|
|
97584
|
+
return;
|
|
97585
|
+
const base = output.runtimeError ? `${output.runtimeError.name}: ${output.runtimeError.message}` : output.error ?? `script exited with code ${output.exitCode}`;
|
|
97586
|
+
const stderr = scrubSecrets(output.stderr).trim().slice(0, MAX_ERROR_DETAIL_CHARS);
|
|
97587
|
+
return stderr.length > 0 ? `${base} — ${stderr}` : base;
|
|
97588
|
+
}
|
|
97589
|
+
function parsePullPayload(payload, warnings) {
|
|
97590
|
+
const parsed = PullPayloadSchema.safeParse(payload);
|
|
97591
|
+
if (!parsed.success) {
|
|
97592
|
+
const detail = parsed.error.issues.slice(0, 3).map((issue) => `${issue.path.join(".") || "<root>"}: ${issue.message}`).join("; ");
|
|
97593
|
+
throw new SyncPassError(`source script returned an invalid payload — expected Array<{key, fields}> or {records, complete?} (${detail})`);
|
|
97594
|
+
}
|
|
97595
|
+
let records = Array.isArray(parsed.data) ? parsed.data : parsed.data.records;
|
|
97596
|
+
let complete = Array.isArray(parsed.data) ? true : parsed.data.complete ?? true;
|
|
97597
|
+
if (records.length > MAX_PULL_RECORDS) {
|
|
97598
|
+
warn(warnings, `source returned ${records.length} records; truncated to the ${MAX_PULL_RECORDS}-record cap and the stale sweep is skipped`);
|
|
97599
|
+
records = records.slice(0, MAX_PULL_RECORDS);
|
|
97600
|
+
complete = false;
|
|
97601
|
+
}
|
|
97602
|
+
return { records, complete, warnings };
|
|
97603
|
+
}
|
|
97604
|
+
async function pullFromScript(args) {
|
|
97605
|
+
const warnings = [];
|
|
97606
|
+
const { source } = args;
|
|
97607
|
+
const script = getScriptById(source.scriptId);
|
|
97608
|
+
if (!script)
|
|
97609
|
+
throw new SyncPassError(`script "${source.scriptId}" not found`);
|
|
97610
|
+
const agentId = resolveSyncRunAs(script);
|
|
97611
|
+
if (source.connection !== undefined) {
|
|
97612
|
+
const reachable = listScriptConnections({ agentId });
|
|
97613
|
+
if (!reachable.some((connection) => connection.slug === source.connection)) {
|
|
97614
|
+
throw new SyncPassError(`connection "${source.connection}" not found or disabled for the sync run-as identity`);
|
|
97615
|
+
}
|
|
97616
|
+
}
|
|
97617
|
+
const output = await runSavedScriptAsAgent({
|
|
97618
|
+
script,
|
|
97619
|
+
agentId,
|
|
97620
|
+
input: {
|
|
97621
|
+
...source.args,
|
|
97622
|
+
app: { id: args.appId },
|
|
97623
|
+
model: args.model,
|
|
97624
|
+
source: args.sourceName,
|
|
97625
|
+
...source.connection ? { connection: source.connection } : {}
|
|
97626
|
+
}
|
|
97627
|
+
});
|
|
97628
|
+
const failure = scriptFailure(output);
|
|
97629
|
+
if (failure)
|
|
97630
|
+
throw new SyncPassError(failure);
|
|
97631
|
+
return parsePullPayload(output.result, warnings);
|
|
97632
|
+
}
|
|
97633
|
+
var TASK_CONFIG_KEYS = new Set([
|
|
97634
|
+
"status",
|
|
97635
|
+
"agentId",
|
|
97636
|
+
"tags",
|
|
97637
|
+
"assetKey",
|
|
97638
|
+
"limit",
|
|
97639
|
+
"includeHeartbeat"
|
|
97640
|
+
]);
|
|
97641
|
+
function commaList(value) {
|
|
97642
|
+
return String(value).split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
97643
|
+
}
|
|
97644
|
+
function taskLimit(raw, warnings) {
|
|
97645
|
+
if (raw === undefined)
|
|
97646
|
+
return DEFAULT_TASK_LIMIT;
|
|
97647
|
+
const parsed = Math.trunc(Number(raw));
|
|
97648
|
+
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
97649
|
+
warn(warnings, `config.limit "${String(raw)}" is not a positive integer; using ${DEFAULT_TASK_LIMIT}`);
|
|
97650
|
+
return DEFAULT_TASK_LIMIT;
|
|
97651
|
+
}
|
|
97652
|
+
if (parsed > MAX_TASK_LIMIT) {
|
|
97653
|
+
warn(warnings, `config.limit ${parsed} exceeds the ${MAX_TASK_LIMIT} cap; using ${MAX_TASK_LIMIT}`);
|
|
97654
|
+
return MAX_TASK_LIMIT;
|
|
97655
|
+
}
|
|
97656
|
+
return parsed;
|
|
97657
|
+
}
|
|
97658
|
+
function taskRecord(task) {
|
|
97659
|
+
return {
|
|
97660
|
+
key: task.id,
|
|
97661
|
+
fields: {
|
|
97662
|
+
id: task.id,
|
|
97663
|
+
status: task.status,
|
|
97664
|
+
prompt: scrubSecrets(task.task).slice(0, MAX_TASK_PROMPT_CHARS),
|
|
97665
|
+
source: task.source,
|
|
97666
|
+
agentId: task.agentId,
|
|
97667
|
+
tags: task.tags,
|
|
97668
|
+
priority: task.priority,
|
|
97669
|
+
createdAt: task.createdAt,
|
|
97670
|
+
updatedAt: task.lastUpdatedAt,
|
|
97671
|
+
vcsProvider: task.vcsProvider,
|
|
97672
|
+
vcsNumber: task.vcsNumber,
|
|
97673
|
+
vcsUrl: task.vcsUrl,
|
|
97674
|
+
vcsAuthor: task.vcsAuthor
|
|
97675
|
+
}
|
|
97676
|
+
};
|
|
97677
|
+
}
|
|
97678
|
+
function pullFromSwarmTasks(source, invokedBy) {
|
|
97679
|
+
const warnings = [];
|
|
97680
|
+
const config = source.config ?? {};
|
|
97681
|
+
for (const key of Object.keys(config)) {
|
|
97682
|
+
if (!TASK_CONFIG_KEYS.has(key)) {
|
|
97683
|
+
warn(warnings, `config key "${key}" is not supported by the swarm-tasks connector and was ignored`);
|
|
97684
|
+
}
|
|
97685
|
+
}
|
|
97686
|
+
const limit = taskLimit(config.limit, warnings);
|
|
97687
|
+
const filters = {
|
|
97688
|
+
limit,
|
|
97689
|
+
includeHeartbeat: config.includeHeartbeat === true || config.includeHeartbeat === "true"
|
|
97690
|
+
};
|
|
97691
|
+
if (config.status !== undefined) {
|
|
97692
|
+
const statuses = commaList(config.status).map((token) => {
|
|
97693
|
+
const parsed = AgentTaskStatusSchema.safeParse(token);
|
|
97694
|
+
if (!parsed.success)
|
|
97695
|
+
throw new SyncPassError(`config.status: unknown task status "${token}"`);
|
|
97696
|
+
return parsed.data;
|
|
97697
|
+
});
|
|
97698
|
+
if (statuses.length === 0) {
|
|
97699
|
+
throw new SyncPassError(`config.status must name at least one task status, got ${JSON.stringify(config.status)}`);
|
|
97700
|
+
}
|
|
97701
|
+
filters.status = statuses;
|
|
97702
|
+
}
|
|
97703
|
+
if (config.agentId !== undefined) {
|
|
97704
|
+
if (typeof config.agentId !== "string" || config.agentId.trim().length === 0) {
|
|
97705
|
+
throw new SyncPassError(`config.agentId must be a non-empty string, got ${JSON.stringify(config.agentId)}`);
|
|
97706
|
+
}
|
|
97707
|
+
filters.agentId = config.agentId.trim();
|
|
97708
|
+
}
|
|
97709
|
+
if (config.tags !== undefined) {
|
|
97710
|
+
const tags = commaList(config.tags);
|
|
97711
|
+
if (tags.length === 0) {
|
|
97712
|
+
throw new SyncPassError(`config.tags must name at least one tag, got ${JSON.stringify(config.tags)}`);
|
|
97713
|
+
}
|
|
97714
|
+
filters.tags = tags;
|
|
97715
|
+
}
|
|
97716
|
+
if (config.assetKey !== undefined) {
|
|
97717
|
+
if (typeof config.assetKey !== "string" || config.assetKey.trim().length === 0) {
|
|
97718
|
+
throw new SyncPassError(`config.assetKey must be a non-empty string, got ${JSON.stringify(config.assetKey)}`);
|
|
97719
|
+
}
|
|
97720
|
+
filters.keyPrefix = config.assetKey.trim();
|
|
97721
|
+
}
|
|
97722
|
+
const scopedUserId = invokedBy?.startsWith("user:") ? invokedBy.slice("user:".length) : undefined;
|
|
97723
|
+
if (scopedUserId !== undefined) {
|
|
97724
|
+
filters.requestedByUserId = scopedUserId;
|
|
97725
|
+
warn(warnings, "pull scoped to tasks requested by the invoking user");
|
|
97726
|
+
}
|
|
97727
|
+
const records = getAllTasks(filters).map(taskRecord);
|
|
97728
|
+
return { records, complete: scopedUserId === undefined && records.length < limit, warnings };
|
|
97729
|
+
}
|
|
97730
|
+
function getByDottedPath(fields, path) {
|
|
97731
|
+
let value = fields;
|
|
97732
|
+
for (const segment of path.split(".")) {
|
|
97733
|
+
if (value === null || typeof value !== "object")
|
|
97734
|
+
return;
|
|
97735
|
+
value = value[segment];
|
|
97736
|
+
}
|
|
97737
|
+
return value;
|
|
97738
|
+
}
|
|
97739
|
+
function slugify(value) {
|
|
97740
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
97741
|
+
}
|
|
97742
|
+
function applyTransform(value, transform) {
|
|
97743
|
+
if (value === undefined || value === null)
|
|
97744
|
+
return null;
|
|
97745
|
+
switch (transform) {
|
|
97746
|
+
case undefined:
|
|
97747
|
+
return value;
|
|
97748
|
+
case "lower":
|
|
97749
|
+
return String(value).toLowerCase();
|
|
97750
|
+
case "upper":
|
|
97751
|
+
return String(value).toUpperCase();
|
|
97752
|
+
case "slug":
|
|
97753
|
+
return slugify(String(value));
|
|
97754
|
+
case "cents": {
|
|
97755
|
+
const numeric = Number(value);
|
|
97756
|
+
if (!Number.isFinite(numeric))
|
|
97757
|
+
throw new TransformError(`"${String(value)}" is not a number`);
|
|
97758
|
+
return Math.round(numeric * 100);
|
|
97759
|
+
}
|
|
97760
|
+
case "date-parse": {
|
|
97761
|
+
const date2 = new Date(typeof value === "number" ? value : String(value));
|
|
97762
|
+
if (Number.isNaN(date2.getTime()))
|
|
97763
|
+
throw new TransformError(`"${String(value)}" is not a date`);
|
|
97764
|
+
return date2.toISOString();
|
|
97765
|
+
}
|
|
97766
|
+
}
|
|
97767
|
+
}
|
|
97768
|
+
function validForKind(column, value) {
|
|
97769
|
+
if (column.kind === "string")
|
|
97770
|
+
return typeof value === "string";
|
|
97771
|
+
if (column.kind === "number")
|
|
97772
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
97773
|
+
if (column.kind === "boolean")
|
|
97774
|
+
return typeof value === "boolean";
|
|
97775
|
+
if (column.kind === "date")
|
|
97776
|
+
return typeof value === "string" && isIso8601Date(value);
|
|
97777
|
+
return typeof value === "string" && Boolean(column.enum?.includes(value));
|
|
97778
|
+
}
|
|
97779
|
+
function projectRecord(args) {
|
|
97780
|
+
const values = { [args.joinKey]: args.record.key };
|
|
97781
|
+
for (const [name, column] of args.bindings) {
|
|
97782
|
+
const binding = column.source;
|
|
97783
|
+
if (!binding)
|
|
97784
|
+
continue;
|
|
97785
|
+
const raw = getByDottedPath(args.record.fields, binding.field);
|
|
97786
|
+
let value;
|
|
97787
|
+
try {
|
|
97788
|
+
value = applyTransform(raw, binding.transform);
|
|
97789
|
+
} catch (error) {
|
|
97790
|
+
warn(args.warnings, `column "${name}": transform "${binding.transform}" failed — ${error instanceof Error ? error.message : String(error)}`);
|
|
97791
|
+
value = null;
|
|
97792
|
+
}
|
|
97793
|
+
if (value !== null && !validForKind(column, value)) {
|
|
97794
|
+
warn(args.warnings, `column "${name}": field "${binding.field}" produced a value that is not a valid ${column.kind}`);
|
|
97795
|
+
value = null;
|
|
97796
|
+
}
|
|
97797
|
+
values[name] = value;
|
|
97798
|
+
}
|
|
97799
|
+
return values;
|
|
97800
|
+
}
|
|
97801
|
+
function sameValue(existing, projected) {
|
|
97802
|
+
return Object.is(existing ?? null, projected ?? null);
|
|
97803
|
+
}
|
|
97804
|
+
function resolvePair(appId2, model, source) {
|
|
97805
|
+
const app = getApp(appId2);
|
|
97806
|
+
if (!app || appDefinitionNeedsRepair(app))
|
|
97807
|
+
return null;
|
|
97808
|
+
const modelDef = app.definition.models[model];
|
|
97809
|
+
const sourceDef = modelDef?.sources?.[source];
|
|
97810
|
+
return modelDef && sourceDef ? { model: modelDef, source: sourceDef } : null;
|
|
97811
|
+
}
|
|
97812
|
+
function pairFingerprint(model, sourceName, source) {
|
|
97813
|
+
const bindings = Object.entries(model.columns).filter(([, column]) => column.source?.of === sourceName).map(([name, column]) => ({
|
|
97814
|
+
name,
|
|
97815
|
+
kind: column.kind,
|
|
97816
|
+
enum: column.enum ?? null,
|
|
97817
|
+
required: column.required === true,
|
|
97818
|
+
hidden: column.hidden === true,
|
|
97819
|
+
field: column.source?.field,
|
|
97820
|
+
transform: column.source?.transform ?? null
|
|
97821
|
+
}));
|
|
97822
|
+
return JSON.stringify({ source, bindings });
|
|
97823
|
+
}
|
|
97824
|
+
function reconcile(args) {
|
|
97825
|
+
const { appId: appId2, model, sourceName, joinKey, pull, warnings, counts } = args;
|
|
97826
|
+
return withMutationLock(appId2, model, () => {
|
|
97827
|
+
const fresh = resolvePair(appId2, model, sourceName);
|
|
97828
|
+
if (!fresh) {
|
|
97829
|
+
throw new SyncPassError(`model "${model}" no longer declares source "${sourceName}"; pass aborted with no writes`);
|
|
97830
|
+
}
|
|
97831
|
+
if (pairFingerprint(fresh.model, sourceName, fresh.source) !== args.fingerprint) {
|
|
97832
|
+
throw new SyncPassError(`source "${sourceName}" changed while the pull was running; pass aborted with no writes`);
|
|
97833
|
+
}
|
|
97834
|
+
const modelDef = fresh.model;
|
|
97835
|
+
const bindings = Object.entries(modelDef.columns).filter(([, column]) => column.source?.of === sourceName && column.hidden !== true);
|
|
97836
|
+
const mine = new Map;
|
|
97837
|
+
const unkeyed = [];
|
|
97838
|
+
for (const row of listAllAppRowsForMigrationUnlocked(appId2, model)) {
|
|
97839
|
+
if (row.source !== sourceName)
|
|
97840
|
+
continue;
|
|
97841
|
+
const key = row[joinKey];
|
|
97842
|
+
if (typeof key === "string")
|
|
97843
|
+
mine.set(key, row);
|
|
97844
|
+
else
|
|
97845
|
+
unkeyed.push(row);
|
|
97846
|
+
}
|
|
97847
|
+
const now = new Date().toISOString();
|
|
97848
|
+
const actor = `sync:${sourceName}`;
|
|
97849
|
+
const seen = new Set;
|
|
97850
|
+
for (const record3 of pull.records) {
|
|
97851
|
+
if (seen.has(record3.key)) {
|
|
97852
|
+
warn(warnings, `source returned duplicate key "${record3.key}"; the last record wins`);
|
|
97853
|
+
}
|
|
97854
|
+
seen.add(record3.key);
|
|
97855
|
+
const values = projectRecord({ record: record3, bindings, joinKey, warnings });
|
|
97856
|
+
const envelope = { source: sourceName, syncedAt: now, stale: false };
|
|
97857
|
+
const existing = mine.get(record3.key);
|
|
97858
|
+
if (!existing) {
|
|
97859
|
+
const created = createAppRowUnlocked(appId2, model, modelDef, values, {
|
|
97860
|
+
allowSourceManaged: true,
|
|
97861
|
+
envelope,
|
|
97862
|
+
actor
|
|
97863
|
+
});
|
|
97864
|
+
mine.set(record3.key, created);
|
|
97865
|
+
counts.created += 1;
|
|
97866
|
+
continue;
|
|
97867
|
+
}
|
|
97868
|
+
const differs = Object.entries(values).some(([name, value]) => !sameValue(existing[name], value));
|
|
97869
|
+
const updated = patchAppRowUnlocked(appId2, model, modelDef, existing.id, values, {
|
|
97870
|
+
allowSourceManaged: true,
|
|
97871
|
+
envelope,
|
|
97872
|
+
actor,
|
|
97873
|
+
...differs ? {} : { skipUpdatedAt: true }
|
|
97874
|
+
});
|
|
97875
|
+
if (!updated) {
|
|
97876
|
+
warn(warnings, `row "${existing.id}" vanished before it could be updated`);
|
|
97877
|
+
continue;
|
|
97878
|
+
}
|
|
97879
|
+
mine.set(record3.key, updated);
|
|
97880
|
+
if (differs)
|
|
97881
|
+
counts.updated += 1;
|
|
97882
|
+
else
|
|
97883
|
+
counts.refreshed += 1;
|
|
97884
|
+
}
|
|
97885
|
+
const unseen = [...mine.entries()].filter(([key]) => !seen.has(key)).map(([, row]) => row).concat(unkeyed);
|
|
97886
|
+
if (!pull.complete) {
|
|
97887
|
+
counts.staleSweepSkipped = true;
|
|
97888
|
+
counts.unchanged += unseen.length;
|
|
97889
|
+
warn(warnings, "pull reported an incomplete window; stale sweep skipped");
|
|
97890
|
+
return;
|
|
97891
|
+
}
|
|
97892
|
+
for (const row of unseen) {
|
|
97893
|
+
if (row.stale === true) {
|
|
97894
|
+
counts.unchanged += 1;
|
|
97895
|
+
continue;
|
|
97896
|
+
}
|
|
97897
|
+
patchAppRowUnlocked(appId2, model, modelDef, row.id, {}, {
|
|
97898
|
+
allowSourceManaged: true,
|
|
97899
|
+
skipUpdatedAt: true,
|
|
97900
|
+
envelope: {
|
|
97901
|
+
source: sourceName,
|
|
97902
|
+
syncedAt: typeof row.syncedAt === "string" ? row.syncedAt : now,
|
|
97903
|
+
stale: true
|
|
97904
|
+
}
|
|
97905
|
+
});
|
|
97906
|
+
counts.markedStale += 1;
|
|
97907
|
+
}
|
|
97908
|
+
});
|
|
97909
|
+
}
|
|
97910
|
+
var inFlight = new Map;
|
|
97911
|
+
function passBase(args) {
|
|
97912
|
+
return {
|
|
97913
|
+
model: args.model,
|
|
97914
|
+
source: args.source,
|
|
97915
|
+
connector: args.connector,
|
|
97916
|
+
pulled: 0,
|
|
97917
|
+
created: 0,
|
|
97918
|
+
updated: 0,
|
|
97919
|
+
refreshed: 0,
|
|
97920
|
+
unchanged: 0,
|
|
97921
|
+
markedStale: 0,
|
|
97922
|
+
warnings: [],
|
|
97923
|
+
durationMs: 0,
|
|
97924
|
+
...args.invokedBy === undefined ? {} : { invokedBy: args.invokedBy }
|
|
97925
|
+
};
|
|
97926
|
+
}
|
|
97927
|
+
async function executePass(args) {
|
|
97928
|
+
const startedMs = Date.now();
|
|
97929
|
+
const lastStartedAt = new Date(startedMs).toISOString();
|
|
97930
|
+
const warnings = [];
|
|
97931
|
+
const base = passBase({
|
|
97932
|
+
model: args.model,
|
|
97933
|
+
source: args.sourceName,
|
|
97934
|
+
connector: args.source.connector,
|
|
97935
|
+
invokedBy: args.invokedBy
|
|
97936
|
+
});
|
|
97937
|
+
let plannedFingerprint = null;
|
|
97938
|
+
const finish = (result) => {
|
|
97939
|
+
const scrubbed = scrubObject({ ...result, warnings, durationMs: Date.now() - startedMs });
|
|
97940
|
+
const current = resolvePair(args.appId, args.model, args.sourceName);
|
|
97941
|
+
const stillCurrent = plannedFingerprint !== null && current !== null && pairFingerprint(current.model, args.sourceName, current.source) === plannedFingerprint;
|
|
97942
|
+
if (stillCurrent)
|
|
97943
|
+
writeSyncStatus(args.appId, scrubbed, lastStartedAt);
|
|
97944
|
+
return scrubbed;
|
|
97945
|
+
};
|
|
97946
|
+
const counts = {
|
|
97947
|
+
created: 0,
|
|
97948
|
+
updated: 0,
|
|
97949
|
+
refreshed: 0,
|
|
97950
|
+
unchanged: 0,
|
|
97951
|
+
markedStale: 0
|
|
97952
|
+
};
|
|
97953
|
+
let pulled = 0;
|
|
97954
|
+
try {
|
|
97955
|
+
const planned = resolvePair(args.appId, args.model, args.sourceName);
|
|
97956
|
+
if (!planned) {
|
|
97957
|
+
throw new SyncPassError(`model "${args.model}" no longer declares source "${args.sourceName}"; pass aborted with no writes`);
|
|
97958
|
+
}
|
|
97959
|
+
const source = planned.source;
|
|
97960
|
+
const fingerprint = pairFingerprint(planned.model, args.sourceName, source);
|
|
97961
|
+
plannedFingerprint = fingerprint;
|
|
97962
|
+
const pull = scrubObject(source.connector === "script" ? await pullFromScript({
|
|
97963
|
+
appId: args.appId,
|
|
97964
|
+
model: args.model,
|
|
97965
|
+
sourceName: args.sourceName,
|
|
97966
|
+
source
|
|
97967
|
+
}) : pullFromSwarmTasks(source, args.invokedBy));
|
|
97968
|
+
pulled = pull.records.length;
|
|
97969
|
+
for (const warning of pull.warnings)
|
|
97970
|
+
warn(warnings, warning);
|
|
97971
|
+
await reconcile({
|
|
97972
|
+
appId: args.appId,
|
|
97973
|
+
model: args.model,
|
|
97974
|
+
sourceName: args.sourceName,
|
|
97975
|
+
fingerprint,
|
|
97976
|
+
joinKey: source.joinKey,
|
|
97977
|
+
pull,
|
|
97978
|
+
warnings,
|
|
97979
|
+
counts
|
|
97980
|
+
});
|
|
97981
|
+
return finish({ ...base, ...counts, pulled });
|
|
97982
|
+
} catch (error) {
|
|
97983
|
+
const message = error instanceof SyncPassError ? error.message : error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
97984
|
+
return finish({ ...base, ...counts, pulled, error: message });
|
|
97985
|
+
}
|
|
97986
|
+
}
|
|
97987
|
+
async function runPass(args) {
|
|
97988
|
+
const key = `${args.appId}:${args.model}:${args.sourceName}`;
|
|
97989
|
+
if (inFlight.has(key)) {
|
|
97990
|
+
return scrubObject({
|
|
97991
|
+
...passBase({
|
|
97992
|
+
model: args.model,
|
|
97993
|
+
source: args.sourceName,
|
|
97994
|
+
connector: args.source.connector,
|
|
97995
|
+
invokedBy: args.invokedBy
|
|
97996
|
+
}),
|
|
97997
|
+
warnings: ["a sync pass for this pair is already running; this trigger did not pull"],
|
|
97998
|
+
skipped: true,
|
|
97999
|
+
alreadyRunning: true
|
|
98000
|
+
});
|
|
98001
|
+
}
|
|
98002
|
+
const pass = executePass(args);
|
|
98003
|
+
inFlight.set(key, pass);
|
|
98004
|
+
try {
|
|
98005
|
+
return await pass;
|
|
98006
|
+
} finally {
|
|
98007
|
+
if (inFlight.get(key) === pass)
|
|
98008
|
+
inFlight.delete(key);
|
|
98009
|
+
}
|
|
98010
|
+
}
|
|
98011
|
+
function noPairIssue(input) {
|
|
98012
|
+
if (input.source !== undefined) {
|
|
98013
|
+
return {
|
|
98014
|
+
path: "source",
|
|
98015
|
+
message: input.model !== undefined ? `unknown source "${input.source}" on model "${input.model}"` : `unknown source "${input.source}" — no model declares it`
|
|
98016
|
+
};
|
|
98017
|
+
}
|
|
98018
|
+
if (input.model !== undefined) {
|
|
98019
|
+
return { path: "model", message: `model "${input.model}" declares no sources` };
|
|
98020
|
+
}
|
|
98021
|
+
return { path: "appId", message: "no model declares a source to sync" };
|
|
98022
|
+
}
|
|
98023
|
+
async function runAppSync(input) {
|
|
98024
|
+
const app = getApp(input.appId);
|
|
98025
|
+
if (!app) {
|
|
98026
|
+
return {
|
|
98027
|
+
ok: false,
|
|
98028
|
+
passes: [],
|
|
98029
|
+
issues: [{ path: "appId", message: `app "${input.appId}" not found` }]
|
|
98030
|
+
};
|
|
98031
|
+
}
|
|
98032
|
+
if (appDefinitionNeedsRepair(app)) {
|
|
98033
|
+
return {
|
|
98034
|
+
ok: false,
|
|
98035
|
+
passes: [],
|
|
98036
|
+
issues: [{ path: "definition", message: "app definition needs repair before it can sync" }]
|
|
98037
|
+
};
|
|
98038
|
+
}
|
|
98039
|
+
const models = app.definition.models;
|
|
98040
|
+
if (input.model !== undefined && !Object.hasOwn(models, input.model)) {
|
|
98041
|
+
return {
|
|
98042
|
+
ok: false,
|
|
98043
|
+
passes: [],
|
|
98044
|
+
issues: [{ path: "model", message: `unknown model "${input.model}"` }]
|
|
98045
|
+
};
|
|
98046
|
+
}
|
|
98047
|
+
const pairs = (input.model !== undefined ? [input.model] : Object.keys(models)).flatMap((model) => Object.entries(models[model]?.sources ?? {}).filter(([sourceName]) => input.source === undefined || sourceName === input.source).map(([sourceName, source]) => ({ model, sourceName, source })));
|
|
98048
|
+
if (pairs.length === 0) {
|
|
98049
|
+
return { ok: false, passes: [], issues: [noPairIssue(input)] };
|
|
98050
|
+
}
|
|
98051
|
+
const passes = [];
|
|
98052
|
+
for (const pair of pairs) {
|
|
98053
|
+
passes.push(await runPass({ appId: app.id, ...pair, invokedBy: input.invokedBy }));
|
|
98054
|
+
}
|
|
98055
|
+
return { ok: passes.every((pass) => pass.error === undefined), passes };
|
|
98056
|
+
}
|
|
98057
|
+
|
|
98805
98058
|
// src/apps/schema-migrate.ts
|
|
98806
98059
|
var MigrationValueSchema = union([string(), number(), boolean()]);
|
|
98807
98060
|
var AppMigrationDirectiveSchema = union([
|
|
@@ -98824,6 +98077,7 @@ var AppMigrationReportSchema = object({
|
|
|
98824
98077
|
elsed: number().int().nonnegative(),
|
|
98825
98078
|
purgedValues: number().int().nonnegative(),
|
|
98826
98079
|
idxRebuilt: number().int().nonnegative(),
|
|
98080
|
+
detachedRows: number().int().nonnegative(),
|
|
98827
98081
|
orphanFields: array(string()),
|
|
98828
98082
|
userConfigChanged: array(string())
|
|
98829
98083
|
});
|
|
@@ -98835,6 +98089,7 @@ var AppMigrationReportOutputSchema = looseObject({
|
|
|
98835
98089
|
elsed: number().optional(),
|
|
98836
98090
|
purgedValues: number().optional(),
|
|
98837
98091
|
idxRebuilt: number().optional(),
|
|
98092
|
+
detachedRows: number().optional(),
|
|
98838
98093
|
orphanFields: array(string()).optional(),
|
|
98839
98094
|
userConfigChanged: array(string()).optional()
|
|
98840
98095
|
});
|
|
@@ -98862,6 +98117,7 @@ var EMPTY_REPORT = {
|
|
|
98862
98117
|
elsed: 0,
|
|
98863
98118
|
purgedValues: 0,
|
|
98864
98119
|
idxRebuilt: 0,
|
|
98120
|
+
detachedRows: 0,
|
|
98865
98121
|
orphanFields: [],
|
|
98866
98122
|
userConfigChanged: []
|
|
98867
98123
|
};
|
|
@@ -99243,6 +98499,45 @@ function applyDirective(rows, modelName, columnName, directive, oldColumn, nextC
|
|
|
99243
98499
|
});
|
|
99244
98500
|
}
|
|
99245
98501
|
}
|
|
98502
|
+
function ownSource(model, sourceName) {
|
|
98503
|
+
const sources = model?.sources;
|
|
98504
|
+
return sources && Object.hasOwn(sources, sourceName) ? sources[sourceName] : undefined;
|
|
98505
|
+
}
|
|
98506
|
+
function planSources(modelName, oldModel, nextModel, rows, report, issues) {
|
|
98507
|
+
const sourceNames = new Set([
|
|
98508
|
+
...Object.keys(oldModel?.sources ?? {}),
|
|
98509
|
+
...Object.keys(nextModel?.sources ?? {})
|
|
98510
|
+
]);
|
|
98511
|
+
for (const sourceName of [...sourceNames].sort()) {
|
|
98512
|
+
const oldSource = ownSource(oldModel, sourceName);
|
|
98513
|
+
if (!oldSource)
|
|
98514
|
+
continue;
|
|
98515
|
+
const nextSource = ownSource(nextModel, sourceName);
|
|
98516
|
+
const path = `models.${modelName}.sources.${sourceName}`;
|
|
98517
|
+
const owned = rows.filter((row) => row.source === sourceName);
|
|
98518
|
+
if (!nextSource) {
|
|
98519
|
+
for (const row of owned) {
|
|
98520
|
+
delete row.source;
|
|
98521
|
+
delete row.syncedAt;
|
|
98522
|
+
delete row.stale;
|
|
98523
|
+
report.detachedRows += 1;
|
|
98524
|
+
}
|
|
98525
|
+
continue;
|
|
98526
|
+
}
|
|
98527
|
+
if (nextSource.joinKey !== oldSource.joinKey) {
|
|
98528
|
+
issues.push({
|
|
98529
|
+
path: `${path}.joinKey`,
|
|
98530
|
+
message: "join key is immutable; remove the source and add it again"
|
|
98531
|
+
});
|
|
98532
|
+
}
|
|
98533
|
+
if (nextSource.connector !== oldSource.connector && owned.length > 0) {
|
|
98534
|
+
issues.push({
|
|
98535
|
+
path: `${path}.connector`,
|
|
98536
|
+
message: `connector change would orphan ${owned.length} row(s) this source owns; remove the source and add it again`
|
|
98537
|
+
});
|
|
98538
|
+
}
|
|
98539
|
+
}
|
|
98540
|
+
}
|
|
99246
98541
|
function planModel(appId2, modelName, oldModel, nextModel, migration, oldSideUnparseable, report, orphanFields, appliedDirectives) {
|
|
99247
98542
|
const persistedRows = listAllAppRowsForMigrationUnlocked(appId2, modelName);
|
|
99248
98543
|
const rows = persistedRows.map((row) => structuredClone(row));
|
|
@@ -99256,6 +98551,7 @@ function planModel(appId2, modelName, oldModel, nextModel, migration, oldSideUnp
|
|
|
99256
98551
|
message: `model holds ${rows.length} ${rows.length === 1 ? "row" : "rows"} — delete its rows before removing the model`
|
|
99257
98552
|
});
|
|
99258
98553
|
}
|
|
98554
|
+
planSources(modelName, oldModel, nextModel, rows, report, issues);
|
|
99259
98555
|
for (const columnName of changedColumns) {
|
|
99260
98556
|
const oldColumn = ownColumn(oldModel, columnName);
|
|
99261
98557
|
const nextColumn = ownColumn(nextModel, columnName);
|
|
@@ -99279,6 +98575,16 @@ function planModel(appId2, modelName, oldModel, nextModel, migration, oldSideUnp
|
|
|
99279
98575
|
}
|
|
99280
98576
|
continue;
|
|
99281
98577
|
}
|
|
98578
|
+
if (nextColumn.source !== undefined && (oldColumn?.source === undefined || oldColumn.source.of !== nextColumn.source.of)) {
|
|
98579
|
+
const populated = rows.filter((row) => Object.hasOwn(row, columnName) && row[columnName] !== null).length;
|
|
98580
|
+
if (populated > 0) {
|
|
98581
|
+
issues.push({
|
|
98582
|
+
path: `${path}.source`,
|
|
98583
|
+
message: `binding an existing column would let the next pass overwrite ${populated} row(s) of existing data; hide or purge the column and add it bound instead`
|
|
98584
|
+
});
|
|
98585
|
+
continue;
|
|
98586
|
+
}
|
|
98587
|
+
}
|
|
99282
98588
|
if (exactUnhide && nextColumn.required === true && (!directive || !("set" in directive))) {
|
|
99283
98589
|
const missing = rows.filter((row) => !Object.hasOwn(row, columnName) || row[columnName] === null).length;
|
|
99284
98590
|
if (missing > 0) {
|
|
@@ -99434,7 +98740,9 @@ async function migrateAppSchema(input) {
|
|
|
99434
98740
|
rebuildAppColumnIndexUnlocked(input.appId, modelPlan.modelName, columnName, ownColumn(nextModel, columnName), modelPlan.rows);
|
|
99435
98741
|
}
|
|
99436
98742
|
}
|
|
99437
|
-
|
|
98743
|
+
const written = input.writeDefinition();
|
|
98744
|
+
invalidateChangedSyncStatus(input.appId, input.previousDefinition, input.nextDefinition);
|
|
98745
|
+
return written;
|
|
99438
98746
|
});
|
|
99439
98747
|
return { result: transaction(), migration: plan.report };
|
|
99440
98748
|
});
|
|
@@ -99500,7 +98808,7 @@ function decodeAppVersion(appVersion) {
|
|
|
99500
98808
|
}
|
|
99501
98809
|
};
|
|
99502
98810
|
}
|
|
99503
|
-
function rollbackSnapshot(version) {
|
|
98811
|
+
function rollbackSnapshot(version, writer, existingDefinition) {
|
|
99504
98812
|
if (typeof version.snapshot !== "object" || version.snapshot === null || Array.isArray(version.snapshot)) {
|
|
99505
98813
|
throw new AppRollbackDefinitionError(version.version, [
|
|
99506
98814
|
{ path: "snapshot", message: "app version snapshot must be an object" }
|
|
@@ -99519,7 +98827,10 @@ function rollbackSnapshot(version) {
|
|
|
99519
98827
|
}
|
|
99520
98828
|
const parsed = parseAppDefinition(upgradeAppDefinition(snapshot.definition), {
|
|
99521
98829
|
currentAppId: version.appId,
|
|
99522
|
-
resolveApp: getApp
|
|
98830
|
+
resolveApp: getApp,
|
|
98831
|
+
writerAgentId: writer.writerAgentId ?? null,
|
|
98832
|
+
...writer.writerIsUser === undefined ? {} : { writerIsUser: writer.writerIsUser },
|
|
98833
|
+
existingDefinition
|
|
99523
98834
|
});
|
|
99524
98835
|
if (!parsed.success)
|
|
99525
98836
|
throw new AppRollbackDefinitionError(version.version, parsed.issues);
|
|
@@ -99537,7 +98848,7 @@ async function rollbackApp(input) {
|
|
|
99537
98848
|
const version = getAppVersions(input.appId).find((candidate) => candidate.version === input.version);
|
|
99538
98849
|
if (!version)
|
|
99539
98850
|
throw new AppRollbackVersionNotFoundError(input.version);
|
|
99540
|
-
const snapshot = rollbackSnapshot(version);
|
|
98851
|
+
const snapshot = rollbackSnapshot(version, input, existing.definition);
|
|
99541
98852
|
const migrated = await migrateAppSchema({
|
|
99542
98853
|
appId: input.appId,
|
|
99543
98854
|
previousDefinition: appDefinitionNeedsRepair(existing) ? undefined : existing.definition,
|
|
@@ -99822,8 +99133,10 @@ function upsertAppUserConfigValues(appId2, scope, values) {
|
|
|
99822
99133
|
}
|
|
99823
99134
|
|
|
99824
99135
|
// src/http/apps.ts
|
|
99136
|
+
init_key();
|
|
99825
99137
|
init_db();
|
|
99826
99138
|
init_resolver();
|
|
99139
|
+
init_types();
|
|
99827
99140
|
init_request_auth_context();
|
|
99828
99141
|
init_secret_scrubber();
|
|
99829
99142
|
|
|
@@ -99901,8 +99214,84 @@ var rowParamsSchema = object({
|
|
|
99901
99214
|
rowId: string().min(1)
|
|
99902
99215
|
});
|
|
99903
99216
|
var valuesSchema = record(string(), unknown());
|
|
99217
|
+
var AppValidationIssueSchema = object({ path: string(), message: string() });
|
|
99218
|
+
var JsonValueSchema = union([
|
|
99219
|
+
record(string(), unknown()),
|
|
99220
|
+
array(unknown()),
|
|
99221
|
+
string(),
|
|
99222
|
+
number(),
|
|
99223
|
+
boolean(),
|
|
99224
|
+
_null()
|
|
99225
|
+
]);
|
|
99226
|
+
var AppRecordSchema = object({
|
|
99227
|
+
id: string(),
|
|
99228
|
+
name: string(),
|
|
99229
|
+
description: string().optional(),
|
|
99230
|
+
definition: JsonValueSchema,
|
|
99231
|
+
definitionError: array(AppValidationIssueSchema).optional(),
|
|
99232
|
+
createdAt: string(),
|
|
99233
|
+
updatedAt: string()
|
|
99234
|
+
});
|
|
99235
|
+
var AppSummarySchema = object({
|
|
99236
|
+
id: string(),
|
|
99237
|
+
name: string(),
|
|
99238
|
+
description: string().optional(),
|
|
99239
|
+
createdAt: string(),
|
|
99240
|
+
updatedAt: string()
|
|
99241
|
+
});
|
|
99242
|
+
var AppVersionSchema = object({
|
|
99243
|
+
id: string(),
|
|
99244
|
+
appId: string(),
|
|
99245
|
+
version: number(),
|
|
99246
|
+
snapshot: unknown(),
|
|
99247
|
+
changedByAgentId: string().optional(),
|
|
99248
|
+
createdAt: string()
|
|
99249
|
+
});
|
|
99250
|
+
var AppRowSchema = looseObject({
|
|
99251
|
+
id: string(),
|
|
99252
|
+
createdAt: string(),
|
|
99253
|
+
updatedAt: string(),
|
|
99254
|
+
createdBy: string().optional(),
|
|
99255
|
+
updatedBy: string().optional()
|
|
99256
|
+
});
|
|
99257
|
+
var SyncPassResultSchema = object({
|
|
99258
|
+
model: string(),
|
|
99259
|
+
source: string(),
|
|
99260
|
+
connector: _enum(["script", "swarm-tasks"]),
|
|
99261
|
+
pulled: number(),
|
|
99262
|
+
created: number(),
|
|
99263
|
+
updated: number(),
|
|
99264
|
+
refreshed: number(),
|
|
99265
|
+
unchanged: number(),
|
|
99266
|
+
markedStale: number(),
|
|
99267
|
+
staleSweepSkipped: boolean().optional(),
|
|
99268
|
+
warnings: array(string()),
|
|
99269
|
+
durationMs: number(),
|
|
99270
|
+
invokedBy: string().optional(),
|
|
99271
|
+
error: string().optional(),
|
|
99272
|
+
skipped: literal(true).optional(),
|
|
99273
|
+
alreadyRunning: literal(true).optional()
|
|
99274
|
+
});
|
|
99275
|
+
var AppSyncStatusSchema = object({
|
|
99276
|
+
lastStartedAt: string(),
|
|
99277
|
+
lastFinishedAt: string(),
|
|
99278
|
+
ok: boolean(),
|
|
99279
|
+
created: number(),
|
|
99280
|
+
updated: number(),
|
|
99281
|
+
refreshed: number(),
|
|
99282
|
+
markedStale: number(),
|
|
99283
|
+
error: string().optional()
|
|
99284
|
+
});
|
|
99285
|
+
var UserConfigValuesSchema = record(string(), union([string(), number(), boolean(), _null()]));
|
|
99286
|
+
var AppUserConfigFieldSchema = object({
|
|
99287
|
+
kind: ColumnKindSchema,
|
|
99288
|
+
default: union([string(), number(), boolean()]).optional(),
|
|
99289
|
+
enum: array(string()).optional(),
|
|
99290
|
+
label: string().optional()
|
|
99291
|
+
});
|
|
99292
|
+
var AppUserConfigSchema = record(AppNameSchema, AppUserConfigFieldSchema);
|
|
99904
99293
|
var appWriteResponseSchema = object({
|
|
99905
|
-
app:
|
|
99294
|
+
app: AppRecordSchema,
|
|
99906
99295
|
migration: AppMigrationReportSchema
|
|
99907
99296
|
});
|
|
99908
99297
|
var userConfigBodySchema = object({ values: record(string(), unknown()) }).strict();
|
|
@@ -99915,7 +99304,10 @@ var getUserConfigRoute = route({
|
|
|
99915
99304
|
tags: ["Apps"],
|
|
99916
99305
|
params: appParamsSchema,
|
|
99917
99306
|
responses: {
|
|
99918
|
-
200: {
|
|
99307
|
+
200: {
|
|
99308
|
+
description: "Merged user configuration",
|
|
99309
|
+
schema: object({ values: UserConfigValuesSchema, schema: AppUserConfigSchema })
|
|
99310
|
+
},
|
|
99919
99311
|
403: { description: "Permission denied" },
|
|
99920
99312
|
404: { description: "App not found" },
|
|
99921
99313
|
409: { description: "App definition needs repair" }
|
|
@@ -99932,7 +99324,10 @@ var putUserConfigRoute = route({
|
|
|
99932
99324
|
params: appParamsSchema,
|
|
99933
99325
|
body: userConfigBodySchema,
|
|
99934
99326
|
responses: {
|
|
99935
|
-
200: {
|
|
99327
|
+
200: {
|
|
99328
|
+
description: "Stored user configuration",
|
|
99329
|
+
schema: object({ values: UserConfigValuesSchema, schema: AppUserConfigSchema })
|
|
99330
|
+
},
|
|
99936
99331
|
400: { description: "Invalid user configuration" },
|
|
99937
99332
|
403: { description: "Permission denied" },
|
|
99938
99333
|
413: { description: "Request exceeds 64 KB or serialized values exceed 16 KB" },
|
|
@@ -99947,7 +99342,12 @@ var listAppsRoute = route({
|
|
|
99947
99342
|
pattern: ["api", "apps"],
|
|
99948
99343
|
summary: "List apps",
|
|
99949
99344
|
tags: ["Apps"],
|
|
99950
|
-
responses: {
|
|
99345
|
+
responses: {
|
|
99346
|
+
200: {
|
|
99347
|
+
description: "App summaries without definitions",
|
|
99348
|
+
schema: object({ apps: array(AppSummarySchema) })
|
|
99349
|
+
}
|
|
99350
|
+
},
|
|
99951
99351
|
rbac: { ungated: "app summaries are list-level; per-app filtering is future work" }
|
|
99952
99352
|
});
|
|
99953
99353
|
var createAppRoute = route({
|
|
@@ -99963,7 +99363,7 @@ var createAppRoute = route({
|
|
|
99963
99363
|
forceElementBreak: ForceElementBreakSchema.optional()
|
|
99964
99364
|
}),
|
|
99965
99365
|
responses: {
|
|
99966
|
-
201: { description: "Created app" },
|
|
99366
|
+
201: { description: "Created app", schema: object({ app: AppRecordSchema }) },
|
|
99967
99367
|
400: { description: "Invalid app definition" },
|
|
99968
99368
|
403: { description: "Permission denied" }
|
|
99969
99369
|
},
|
|
@@ -99977,7 +99377,10 @@ var listAppVersionsRoute = route({
|
|
|
99977
99377
|
tags: ["Apps"],
|
|
99978
99378
|
params: appParamsSchema,
|
|
99979
99379
|
responses: {
|
|
99980
|
-
200: {
|
|
99380
|
+
200: {
|
|
99381
|
+
description: "App definition versions",
|
|
99382
|
+
schema: object({ versions: array(AppVersionSchema) })
|
|
99383
|
+
},
|
|
99981
99384
|
404: { description: "App not found" }
|
|
99982
99385
|
},
|
|
99983
99386
|
rbac: { permission: "app.manage" }
|
|
@@ -99990,7 +99393,7 @@ var getAppVersionRoute = route({
|
|
|
99990
99393
|
tags: ["Apps"],
|
|
99991
99394
|
params: appVersionParamsSchema,
|
|
99992
99395
|
responses: {
|
|
99993
|
-
200: { description: "App definition version" },
|
|
99396
|
+
200: { description: "App definition version", schema: object({ version: AppVersionSchema }) },
|
|
99994
99397
|
404: { description: "App or version not found" }
|
|
99995
99398
|
},
|
|
99996
99399
|
rbac: { permission: "app.manage" }
|
|
@@ -100024,7 +99427,13 @@ var getAppRoute = route({
|
|
|
100024
99427
|
tags: ["Apps"],
|
|
100025
99428
|
params: appParamsSchema,
|
|
100026
99429
|
responses: {
|
|
100027
|
-
200: {
|
|
99430
|
+
200: {
|
|
99431
|
+
description: "App including its definition",
|
|
99432
|
+
schema: object({
|
|
99433
|
+
app: AppRecordSchema,
|
|
99434
|
+
syncStatus: record(string(), AppSyncStatusSchema).optional()
|
|
99435
|
+
})
|
|
99436
|
+
},
|
|
100028
99437
|
403: { description: "Permission denied" },
|
|
100029
99438
|
404: { description: "App not found" }
|
|
100030
99439
|
},
|
|
@@ -100083,7 +99492,7 @@ var deleteAppRoute = route({
|
|
|
100083
99492
|
tags: ["Apps"],
|
|
100084
99493
|
params: appParamsSchema,
|
|
100085
99494
|
responses: {
|
|
100086
|
-
200: { description: "App deleted" },
|
|
99495
|
+
200: { description: "App deleted", schema: object({ ok: literal(true) }) },
|
|
100087
99496
|
403: { description: "Permission denied" },
|
|
100088
99497
|
404: { description: "App not found" }
|
|
100089
99498
|
},
|
|
@@ -100098,7 +99507,7 @@ var createRowRoute = route({
|
|
|
100098
99507
|
params: modelParamsSchema,
|
|
100099
99508
|
body: object({ values: valuesSchema }),
|
|
100100
99509
|
responses: {
|
|
100101
|
-
201: { description: "Created row" },
|
|
99510
|
+
201: { description: "Created row", schema: object({ row: AppRowSchema }) },
|
|
100102
99511
|
400: { description: "Invalid row values" },
|
|
100103
99512
|
403: { description: "Permission denied" },
|
|
100104
99513
|
404: { description: "App or model not found" }
|
|
@@ -100114,7 +99523,7 @@ var bulkCreateRowsRoute = route({
|
|
|
100114
99523
|
params: modelParamsSchema,
|
|
100115
99524
|
body: object({ rows: array(object({ values: valuesSchema })).max(500) }),
|
|
100116
99525
|
responses: {
|
|
100117
|
-
200: { description: "Created rows" },
|
|
99526
|
+
200: { description: "Created rows", schema: object({ rows: array(AppRowSchema) }) },
|
|
100118
99527
|
400: { description: "Invalid row values" },
|
|
100119
99528
|
403: { description: "Permission denied" },
|
|
100120
99529
|
404: { description: "App or model not found" }
|
|
@@ -100133,7 +99542,10 @@ var listRowsRoute = route({
|
|
|
100133
99542
|
limit: exports_coerce.number().int().positive().max(1000).optional()
|
|
100134
99543
|
}),
|
|
100135
99544
|
responses: {
|
|
100136
|
-
200: {
|
|
99545
|
+
200: {
|
|
99546
|
+
description: "Filtered app model rows",
|
|
99547
|
+
schema: object({ rows: array(AppRowSchema), total: number() })
|
|
99548
|
+
},
|
|
100137
99549
|
400: { description: "Invalid filter or sort" },
|
|
100138
99550
|
403: { description: "Permission denied" },
|
|
100139
99551
|
404: { description: "App or model not found" }
|
|
@@ -100148,7 +99560,7 @@ var getRowRoute = route({
|
|
|
100148
99560
|
tags: ["Apps"],
|
|
100149
99561
|
params: rowParamsSchema,
|
|
100150
99562
|
responses: {
|
|
100151
|
-
200: { description: "App model row" },
|
|
99563
|
+
200: { description: "App model row", schema: object({ row: AppRowSchema }) },
|
|
100152
99564
|
403: { description: "Permission denied" },
|
|
100153
99565
|
404: { description: "App, model, or row not found" }
|
|
100154
99566
|
},
|
|
@@ -100163,7 +99575,7 @@ var patchRowRoute = route({
|
|
|
100163
99575
|
params: rowParamsSchema,
|
|
100164
99576
|
body: object({ values: valuesSchema }),
|
|
100165
99577
|
responses: {
|
|
100166
|
-
200: { description: "Updated row" },
|
|
99578
|
+
200: { description: "Updated row", schema: object({ row: AppRowSchema }) },
|
|
100167
99579
|
400: { description: "Invalid row values" },
|
|
100168
99580
|
403: { description: "Permission denied" },
|
|
100169
99581
|
404: { description: "App, model, or row not found" }
|
|
@@ -100178,7 +99590,7 @@ var deleteRowRoute = route({
|
|
|
100178
99590
|
tags: ["Apps"],
|
|
100179
99591
|
params: rowParamsSchema,
|
|
100180
99592
|
responses: {
|
|
100181
|
-
200: { description: "Row deleted" },
|
|
99593
|
+
200: { description: "Row deleted", schema: object({ ok: literal(true) }) },
|
|
100182
99594
|
403: { description: "Permission denied" },
|
|
100183
99595
|
404: { description: "App, model, or row not found" }
|
|
100184
99596
|
},
|
|
@@ -100192,7 +99604,7 @@ var runNamedQueryRoute = route({
|
|
|
100192
99604
|
tags: ["Apps"],
|
|
100193
99605
|
params: object({ id: string().min(1), name: AppNameSchema }),
|
|
100194
99606
|
responses: {
|
|
100195
|
-
200: { description: "Named query rows" },
|
|
99607
|
+
200: { description: "Named query rows", schema: object({ rows: array(AppRowSchema) }) },
|
|
100196
99608
|
400: { description: "Missing or invalid named query parameters" },
|
|
100197
99609
|
403: { description: "Permission denied" },
|
|
100198
99610
|
409: { description: "App definition needs repair" },
|
|
@@ -100200,6 +99612,29 @@ var runNamedQueryRoute = route({
|
|
|
100200
99612
|
},
|
|
100201
99613
|
rbac: { permission: "app.use" }
|
|
100202
99614
|
});
|
|
99615
|
+
var runActionScriptResultSchema = object({
|
|
99616
|
+
ok: boolean(),
|
|
99617
|
+
result: unknown(),
|
|
99618
|
+
stdout: string(),
|
|
99619
|
+
error: string().optional(),
|
|
99620
|
+
durationMs: number()
|
|
99621
|
+
});
|
|
99622
|
+
var runActionTaskResultSchema = object({
|
|
99623
|
+
ok: literal(true),
|
|
99624
|
+
taskId: string(),
|
|
99625
|
+
status: AgentTaskStatusSchema
|
|
99626
|
+
});
|
|
99627
|
+
var runActionSyncResultSchema = object({
|
|
99628
|
+
ok: boolean(),
|
|
99629
|
+
result: object({ passes: array(SyncPassResultSchema) }),
|
|
99630
|
+
error: string().optional(),
|
|
99631
|
+
durationMs: number()
|
|
99632
|
+
});
|
|
99633
|
+
var runActionResultSchema = union([
|
|
99634
|
+
runActionScriptResultSchema,
|
|
99635
|
+
runActionTaskResultSchema,
|
|
99636
|
+
runActionSyncResultSchema
|
|
99637
|
+
]);
|
|
100203
99638
|
var runActionRoute = route({
|
|
100204
99639
|
method: "post",
|
|
100205
99640
|
path: "/api/apps/{id}/actions/{name}",
|
|
@@ -100210,7 +99645,7 @@ var runActionRoute = route({
|
|
|
100210
99645
|
params: object({ id: string().min(1), name: AppNameSchema }),
|
|
100211
99646
|
body: object({ input: record(string(), unknown()).optional() }),
|
|
100212
99647
|
responses: {
|
|
100213
|
-
200: { description: "Action invoked" },
|
|
99648
|
+
200: { description: "Action invoked", schema: runActionResultSchema },
|
|
100214
99649
|
400: { description: "Invalid action input or stale script reference" },
|
|
100215
99650
|
403: { description: "Permission denied" },
|
|
100216
99651
|
409: { description: "App definition needs repair" },
|
|
@@ -100218,6 +99653,27 @@ var runActionRoute = route({
|
|
|
100218
99653
|
},
|
|
100219
99654
|
rbac: { permission: "app.use" }
|
|
100220
99655
|
});
|
|
99656
|
+
var syncAppRoute = route({
|
|
99657
|
+
method: "post",
|
|
99658
|
+
path: "/api/apps/{id}/sync",
|
|
99659
|
+
pattern: ["api", "apps", null, "sync"],
|
|
99660
|
+
summary: "Sync an app's declared sources",
|
|
99661
|
+
description: "Runs every (model x source) pair the body selects. Each pass pulls outside the row mutation lock and reconciles inside it.",
|
|
99662
|
+
tags: ["Apps"],
|
|
99663
|
+
params: appParamsSchema,
|
|
99664
|
+
body: object({ model: AppNameSchema.optional(), source: AppNameSchema.optional() }),
|
|
99665
|
+
responses: {
|
|
99666
|
+
200: {
|
|
99667
|
+
description: "Sync passes",
|
|
99668
|
+
schema: object({ ok: boolean(), passes: array(SyncPassResultSchema) })
|
|
99669
|
+
},
|
|
99670
|
+
400: { description: "Unknown model or source, or no model declares a source" },
|
|
99671
|
+
403: { description: "Permission denied" },
|
|
99672
|
+
409: { description: "App definition needs repair" },
|
|
99673
|
+
404: { description: "App not found" }
|
|
99674
|
+
},
|
|
99675
|
+
rbac: { permission: "app.use" }
|
|
99676
|
+
});
|
|
100221
99677
|
function authorizeApp(req, res, myAgentId, verb, resource) {
|
|
100222
99678
|
const auth = getRequestAuth(req);
|
|
100223
99679
|
let principal;
|
|
@@ -100259,6 +99715,12 @@ function definitionNeedsRepair(res, app) {
|
|
|
100259
99715
|
json(res, { error: "definition needs repair", issues: app.definitionError }, 409);
|
|
100260
99716
|
return true;
|
|
100261
99717
|
}
|
|
99718
|
+
function syncPassError(sync) {
|
|
99719
|
+
const failed = sync.passes.filter((pass) => pass.error !== undefined);
|
|
99720
|
+
if (failed.length === 0)
|
|
99721
|
+
return;
|
|
99722
|
+
return failed.map((pass) => `${pass.model}.${pass.source}: ${pass.error}`).join("; ");
|
|
99723
|
+
}
|
|
100262
99724
|
function snapshotFailure(res) {
|
|
100263
99725
|
jsonError(res, "failed to snapshot app", 500);
|
|
100264
99726
|
}
|
|
@@ -100435,7 +99897,7 @@ function applyQuery(rows, query, model, params = {}, queryName = "<unnamed>") {
|
|
|
100435
99897
|
const sort = query.sort;
|
|
100436
99898
|
if (sort) {
|
|
100437
99899
|
selected = [...selected].sort((a, b) => {
|
|
100438
|
-
const result = compareValues(rowValue(a, sort.column), rowValue(b, sort.column), sort.dir,
|
|
99900
|
+
const result = compareValues(rowValue(a, sort.column), rowValue(b, sort.column), sort.dir, SORTABLE_SYSTEM_DATE_COLUMNS.has(sort.column) || Object.hasOwn(model.columns, sort.column) && model.columns[sort.column].kind === "date");
|
|
100439
99901
|
return result;
|
|
100440
99902
|
});
|
|
100441
99903
|
}
|
|
@@ -100456,23 +99918,24 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100456
99918
|
}
|
|
100457
99919
|
const definition = parseAppDefinition(parsed.body.definition, {
|
|
100458
99920
|
resolveApp: getApp,
|
|
100459
|
-
writerAgentId: myAgentId ?? null
|
|
99921
|
+
writerAgentId: myAgentId ?? null,
|
|
99922
|
+
writerIsUser: getRequestAuth(req)?.kind === "user"
|
|
100460
99923
|
});
|
|
100461
99924
|
if (!definition.success) {
|
|
100462
99925
|
invalidDefinition(res, definition.issues);
|
|
100463
99926
|
return true;
|
|
100464
99927
|
}
|
|
100465
|
-
|
|
99928
|
+
createAppRoute.respond(res, 201, {
|
|
100466
99929
|
app: createApp({
|
|
100467
99930
|
name: parsed.body.name,
|
|
100468
99931
|
description: parsed.body.description,
|
|
100469
99932
|
definition: definition.definition
|
|
100470
99933
|
})
|
|
100471
|
-
}
|
|
99934
|
+
});
|
|
100472
99935
|
return true;
|
|
100473
99936
|
}
|
|
100474
99937
|
if (listAppsRoute.match(req.method, pathSegments)) {
|
|
100475
|
-
|
|
99938
|
+
listAppsRoute.respond(res, 200, { apps: listApps() });
|
|
100476
99939
|
return true;
|
|
100477
99940
|
}
|
|
100478
99941
|
if (listAppVersionsRoute.match(req.method, pathSegments)) {
|
|
@@ -100485,7 +99948,9 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100485
99948
|
jsonError(res, "app not found", 404);
|
|
100486
99949
|
return true;
|
|
100487
99950
|
}
|
|
100488
|
-
|
|
99951
|
+
listAppVersionsRoute.respond(res, 200, {
|
|
99952
|
+
versions: getAppVersions(parsed.params.id).map(decodeAppVersion)
|
|
99953
|
+
});
|
|
100489
99954
|
return true;
|
|
100490
99955
|
}
|
|
100491
99956
|
if (getAppVersionRoute.match(req.method, pathSegments)) {
|
|
@@ -100503,7 +99968,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100503
99968
|
jsonError(res, "app version not found", 404);
|
|
100504
99969
|
return true;
|
|
100505
99970
|
}
|
|
100506
|
-
|
|
99971
|
+
getAppVersionRoute.respond(res, 200, { version: decodeAppVersion(version) });
|
|
100507
99972
|
return true;
|
|
100508
99973
|
}
|
|
100509
99974
|
if (rollbackAppRoute.match(req.method, pathSegments)) {
|
|
@@ -100520,9 +99985,11 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100520
99985
|
version: parsed.body.version,
|
|
100521
99986
|
migration: parsed.body.migration,
|
|
100522
99987
|
forceElementBreak: parsed.body.forceElementBreak,
|
|
100523
|
-
changedByAgentId: myAgentId
|
|
99988
|
+
changedByAgentId: myAgentId,
|
|
99989
|
+
writerAgentId: myAgentId ?? null,
|
|
99990
|
+
writerIsUser: getRequestAuth(req)?.kind === "user"
|
|
100524
99991
|
});
|
|
100525
|
-
|
|
99992
|
+
rollbackAppRoute.respond(res, 200, { app: rolledBack.app, migration: rolledBack.migration });
|
|
100526
99993
|
} catch (error) {
|
|
100527
99994
|
if (error instanceof AppRollbackAppNotFoundError) {
|
|
100528
99995
|
jsonError(res, "app not found", 404);
|
|
@@ -100554,7 +100021,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100554
100021
|
return true;
|
|
100555
100022
|
try {
|
|
100556
100023
|
const rows = await createAppRows(parsed.params.id, parsed.params.model, resolved.model, parsed.body.rows.map((row) => row.values), { actor });
|
|
100557
|
-
|
|
100024
|
+
bulkCreateRowsRoute.respond(res, 200, { rows });
|
|
100558
100025
|
} catch (error) {
|
|
100559
100026
|
if (!invalidRows(res, error))
|
|
100560
100027
|
throw error;
|
|
@@ -100575,7 +100042,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100575
100042
|
return true;
|
|
100576
100043
|
try {
|
|
100577
100044
|
const row = await createAppRow(parsed.params.id, parsed.params.model, resolved.model, parsed.body.values, { actor });
|
|
100578
|
-
|
|
100045
|
+
createRowRoute.respond(res, 201, { row });
|
|
100579
100046
|
} catch (error) {
|
|
100580
100047
|
if (!invalidRows(res, error))
|
|
100581
100048
|
throw error;
|
|
@@ -100600,7 +100067,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100600
100067
|
const sortRaw = parsed.query.sort;
|
|
100601
100068
|
if (sortRaw) {
|
|
100602
100069
|
const [column, dir, extra] = sortRaw.split(":");
|
|
100603
|
-
if (extra !== undefined || !column || dir !== "asc" && dir !== "desc" || column
|
|
100070
|
+
if (extra !== undefined || !column || dir !== "asc" && dir !== "desc" || !SORTABLE_SYSTEM_DATE_COLUMNS.has(column) && (!Object.hasOwn(resolved.model.columns, column) || resolved.model.columns[column].hidden === true)) {
|
|
100604
100071
|
json(res, {
|
|
100605
100072
|
error: "invalid sort",
|
|
100606
100073
|
issues: [{ path: "sort", message: "must be <column>:<asc|desc> for a known column" }]
|
|
@@ -100608,12 +100075,12 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100608
100075
|
return true;
|
|
100609
100076
|
}
|
|
100610
100077
|
rows.sort((a, b) => {
|
|
100611
|
-
const result = compareValues(rowValue(a, column), rowValue(b, column), dir, column
|
|
100078
|
+
const result = compareValues(rowValue(a, column), rowValue(b, column), dir, SORTABLE_SYSTEM_DATE_COLUMNS.has(column) || Object.hasOwn(resolved.model.columns, column) && resolved.model.columns[column].kind === "date");
|
|
100612
100079
|
return result;
|
|
100613
100080
|
});
|
|
100614
100081
|
}
|
|
100615
100082
|
const total = rows.length;
|
|
100616
|
-
|
|
100083
|
+
listRowsRoute.respond(res, 200, { rows: rows.slice(0, parsed.query.limit ?? 200), total });
|
|
100617
100084
|
return true;
|
|
100618
100085
|
}
|
|
100619
100086
|
if (getRowRoute.match(req.method, pathSegments)) {
|
|
@@ -100629,7 +100096,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100629
100096
|
jsonError(res, "row not found", 404);
|
|
100630
100097
|
return true;
|
|
100631
100098
|
}
|
|
100632
|
-
|
|
100099
|
+
getRowRoute.respond(res, 200, { row });
|
|
100633
100100
|
return true;
|
|
100634
100101
|
}
|
|
100635
100102
|
if (patchRowRoute.match(req.method, pathSegments)) {
|
|
@@ -100650,7 +100117,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100650
100117
|
jsonError(res, "row not found", 404);
|
|
100651
100118
|
return true;
|
|
100652
100119
|
}
|
|
100653
|
-
|
|
100120
|
+
patchRowRoute.respond(res, 200, { row });
|
|
100654
100121
|
} catch (error) {
|
|
100655
100122
|
if (!invalidRows(res, error))
|
|
100656
100123
|
throw error;
|
|
@@ -100670,7 +100137,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100670
100137
|
jsonError(res, "row not found", 404);
|
|
100671
100138
|
return true;
|
|
100672
100139
|
}
|
|
100673
|
-
|
|
100140
|
+
deleteRowRoute.respond(res, 200, { ok: true });
|
|
100674
100141
|
return true;
|
|
100675
100142
|
}
|
|
100676
100143
|
if (runNamedQueryRoute.match(req.method, pathSegments)) {
|
|
@@ -100694,7 +100161,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100694
100161
|
}
|
|
100695
100162
|
const model = app.definition.models[query.model];
|
|
100696
100163
|
try {
|
|
100697
|
-
|
|
100164
|
+
runNamedQueryRoute.respond(res, 200, {
|
|
100698
100165
|
rows: applyQuery(listAppRows(app.id, query.model), query, model, appQueryParamsFromRequest(queryParams), parsed.params.name)
|
|
100699
100166
|
});
|
|
100700
100167
|
} catch (error) {
|
|
@@ -100753,7 +100220,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100753
100220
|
});
|
|
100754
100221
|
const ok = output.exitCode === 0 && !output.error && !output.runtimeError;
|
|
100755
100222
|
const error = ok ? undefined : output.runtimeError ? `${output.runtimeError.name}: ${output.runtimeError.message}` : output.error ?? `Script exited with code ${output.exitCode}`;
|
|
100756
|
-
|
|
100223
|
+
runActionRoute.respond(res, 200, scrubObject({
|
|
100757
100224
|
ok,
|
|
100758
100225
|
result: output.result,
|
|
100759
100226
|
stdout: output.stdout,
|
|
@@ -100762,6 +100229,28 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100762
100229
|
}));
|
|
100763
100230
|
return true;
|
|
100764
100231
|
}
|
|
100232
|
+
if (action.kind === "sync") {
|
|
100233
|
+
const startedAt = Date.now();
|
|
100234
|
+
const sync = await runAppSync({
|
|
100235
|
+
appId: app.id,
|
|
100236
|
+
...action.model === undefined ? {} : { model: action.model },
|
|
100237
|
+
...action.source === undefined ? {} : { source: action.source },
|
|
100238
|
+
invokedBy: actor
|
|
100239
|
+
});
|
|
100240
|
+
const durationMs = Date.now() - startedAt;
|
|
100241
|
+
if (sync.issues && sync.issues.length > 0) {
|
|
100242
|
+
json(res, { error: "invalid sync action", issues: sync.issues }, 400);
|
|
100243
|
+
return true;
|
|
100244
|
+
}
|
|
100245
|
+
const error = syncPassError(sync);
|
|
100246
|
+
runActionRoute.respond(res, 200, scrubObject({
|
|
100247
|
+
ok: sync.ok,
|
|
100248
|
+
result: { passes: sync.passes },
|
|
100249
|
+
...error === undefined ? {} : { error },
|
|
100250
|
+
durationMs
|
|
100251
|
+
}));
|
|
100252
|
+
return true;
|
|
100253
|
+
}
|
|
100765
100254
|
const lead = action.agentId ? null : getLeadAgent();
|
|
100766
100255
|
const taskPrompt = resolveTemplate("task.app.action", {
|
|
100767
100256
|
prompt: action.prompt,
|
|
@@ -100772,9 +100261,39 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100772
100261
|
const task = createTaskWithSiblingAwareness(taskPrompt.text, {
|
|
100773
100262
|
source: "api",
|
|
100774
100263
|
agentId: action.agentId ?? lead?.id,
|
|
100264
|
+
key: normalizeAssetKey(`shared/app:${app.id}/action:${parsed.params.name}/`),
|
|
100775
100265
|
...actor.startsWith("user:") ? { requestedByUserId: actor.slice("user:".length) } : {}
|
|
100776
100266
|
});
|
|
100777
|
-
|
|
100267
|
+
runActionRoute.respond(res, 200, { ok: true, taskId: task.id, status: task.status });
|
|
100268
|
+
return true;
|
|
100269
|
+
}
|
|
100270
|
+
if (syncAppRoute.match(req.method, pathSegments)) {
|
|
100271
|
+
if (enforceContentLengthCap(req, res, MAX_APP_ROW_BODY_BYTES) === BODY_TOO_LARGE)
|
|
100272
|
+
return true;
|
|
100273
|
+
const parsed = await syncAppRoute.parse(req, res, pathSegments, queryParams);
|
|
100274
|
+
if (!parsed)
|
|
100275
|
+
return true;
|
|
100276
|
+
const actor = authorizeAppUse(req, res, myAgentId, parsed.params.id);
|
|
100277
|
+
if (!actor)
|
|
100278
|
+
return true;
|
|
100279
|
+
const app = getApp(parsed.params.id);
|
|
100280
|
+
if (!app) {
|
|
100281
|
+
jsonError(res, "app not found", 404);
|
|
100282
|
+
return true;
|
|
100283
|
+
}
|
|
100284
|
+
if (definitionNeedsRepair(res, app))
|
|
100285
|
+
return true;
|
|
100286
|
+
const sync = await runAppSync({
|
|
100287
|
+
appId: app.id,
|
|
100288
|
+
...parsed.body.model === undefined ? {} : { model: parsed.body.model },
|
|
100289
|
+
...parsed.body.source === undefined ? {} : { source: parsed.body.source },
|
|
100290
|
+
invokedBy: actor
|
|
100291
|
+
});
|
|
100292
|
+
if (sync.issues && sync.issues.length > 0) {
|
|
100293
|
+
json(res, { error: "nothing to sync", issues: sync.issues }, 400);
|
|
100294
|
+
return true;
|
|
100295
|
+
}
|
|
100296
|
+
syncAppRoute.respond(res, 200, scrubObject({ ok: sync.ok, passes: sync.passes }));
|
|
100778
100297
|
return true;
|
|
100779
100298
|
}
|
|
100780
100299
|
if (patchAppRoute.match(req.method, pathSegments)) {
|
|
@@ -100814,6 +100333,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100814
100333
|
currentAppId: parsed.params.id,
|
|
100815
100334
|
resolveApp: getApp,
|
|
100816
100335
|
writerAgentId: myAgentId ?? null,
|
|
100336
|
+
writerIsUser: getRequestAuth(req)?.kind === "user",
|
|
100817
100337
|
existingDefinition: existing.definition
|
|
100818
100338
|
});
|
|
100819
100339
|
if (!definition.success) {
|
|
@@ -100861,7 +100381,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100861
100381
|
jsonError(res, "app not found", 404);
|
|
100862
100382
|
return true;
|
|
100863
100383
|
}
|
|
100864
|
-
|
|
100384
|
+
patchAppRoute.respond(res, 200, { app, migration });
|
|
100865
100385
|
return true;
|
|
100866
100386
|
}
|
|
100867
100387
|
if (updateAppRoute.match(req.method, pathSegments)) {
|
|
@@ -100893,6 +100413,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100893
100413
|
currentAppId: parsed.params.id,
|
|
100894
100414
|
resolveApp: getApp,
|
|
100895
100415
|
writerAgentId: myAgentId ?? null,
|
|
100416
|
+
writerIsUser: getRequestAuth(req)?.kind === "user",
|
|
100896
100417
|
existingDefinition: existing.definition
|
|
100897
100418
|
});
|
|
100898
100419
|
if (!parsedDefinition.success) {
|
|
@@ -100946,7 +100467,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100946
100467
|
jsonError(res, "app not found", 404);
|
|
100947
100468
|
return true;
|
|
100948
100469
|
}
|
|
100949
|
-
|
|
100470
|
+
updateAppRoute.respond(res, 200, { app, migration });
|
|
100950
100471
|
return true;
|
|
100951
100472
|
}
|
|
100952
100473
|
if (deleteAppRoute.match(req.method, pathSegments)) {
|
|
@@ -100969,7 +100490,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100969
100490
|
jsonError(res, "app not found", 404);
|
|
100970
100491
|
return true;
|
|
100971
100492
|
}
|
|
100972
|
-
|
|
100493
|
+
deleteAppRoute.respond(res, 200, { ok: true });
|
|
100973
100494
|
return true;
|
|
100974
100495
|
}
|
|
100975
100496
|
if (getAppRoute.match(req.method, pathSegments)) {
|
|
@@ -100983,7 +100504,11 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
100983
100504
|
jsonError(res, "app not found", 404);
|
|
100984
100505
|
return true;
|
|
100985
100506
|
}
|
|
100986
|
-
|
|
100507
|
+
const syncStatus = collectAppSyncStatus(app.id);
|
|
100508
|
+
getAppRoute.respond(res, 200, {
|
|
100509
|
+
app,
|
|
100510
|
+
...Object.keys(syncStatus).length > 0 ? { syncStatus } : {}
|
|
100511
|
+
});
|
|
100987
100512
|
return true;
|
|
100988
100513
|
}
|
|
100989
100514
|
if (getUserConfigRoute.match(req.method, pathSegments)) {
|
|
@@ -101002,7 +100527,7 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
101002
100527
|
const schema = app.definition.userConfig ?? {};
|
|
101003
100528
|
const owner = resolveHttpFavoriteOwner(req, myAgentId);
|
|
101004
100529
|
const stored = owner ? getAppUserConfigValues(app.id, owner.scope) : {};
|
|
101005
|
-
|
|
100530
|
+
getUserConfigRoute.respond(res, 200, { values: mergeUserConfigValues(schema, stored), schema });
|
|
101006
100531
|
return true;
|
|
101007
100532
|
}
|
|
101008
100533
|
if (putUserConfigRoute.match(req.method, pathSegments)) {
|
|
@@ -101042,7 +100567,10 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
101042
100567
|
return true;
|
|
101043
100568
|
}
|
|
101044
100569
|
upsertAppUserConfigValues(app.id, owner.scope, parsed.body.values);
|
|
101045
|
-
|
|
100570
|
+
putUserConfigRoute.respond(res, 200, {
|
|
100571
|
+
values: mergeUserConfigValues(schema, parsed.body.values),
|
|
100572
|
+
schema
|
|
100573
|
+
});
|
|
101046
100574
|
return true;
|
|
101047
100575
|
}
|
|
101048
100576
|
return false;
|
|
@@ -101090,9 +100618,15 @@ var registerAppGetTool = (server) => {
|
|
|
101090
100618
|
const app = getApp(appId2);
|
|
101091
100619
|
if (!app)
|
|
101092
100620
|
return toolErr(`App ${appId2} not found.`);
|
|
100621
|
+
const syncStatus = collectAppSyncStatus(app.id);
|
|
100622
|
+
const hasSyncStatus = Object.keys(syncStatus).length > 0;
|
|
100623
|
+
const details = hasSyncStatus ? `${JSON.stringify(app, null, 2)}
|
|
100624
|
+
|
|
100625
|
+
Sync status (model:source):
|
|
100626
|
+
${JSON.stringify(syncStatus, null, 2)}` : JSON.stringify(app, null, 2);
|
|
101093
100627
|
return toolOk(`App "${app.name}" (${app.id}).`, {
|
|
101094
|
-
details
|
|
101095
|
-
data: { app }
|
|
100628
|
+
details,
|
|
100629
|
+
data: { app, ...hasSyncStatus ? { syncStatus } : {} }
|
|
101096
100630
|
});
|
|
101097
100631
|
});
|
|
101098
100632
|
};
|
|
@@ -101415,7 +100949,8 @@ var registerAppRollbackTool = (server) => {
|
|
|
101415
100949
|
version,
|
|
101416
100950
|
migration,
|
|
101417
100951
|
forceElementBreak,
|
|
101418
|
-
changedByAgentId: requestInfo.agentId
|
|
100952
|
+
changedByAgentId: requestInfo.agentId,
|
|
100953
|
+
writerAgentId: requestInfo.agentId
|
|
101419
100954
|
});
|
|
101420
100955
|
const url = `/apps/${rolledBack.app.id}`;
|
|
101421
100956
|
return toolOk(`App "${rolledBack.app.name}" rolled back to v${version}.`, {
|
|
@@ -101453,6 +100988,92 @@ var registerAppRollbackTool = (server) => {
|
|
|
101453
100988
|
});
|
|
101454
100989
|
};
|
|
101455
100990
|
|
|
100991
|
+
// src/tools/app-sync.ts
|
|
100992
|
+
init_zod();
|
|
100993
|
+
init_db();
|
|
100994
|
+
function cell(value) {
|
|
100995
|
+
return String(value ?? "—").replaceAll("\\", "\\\\").replaceAll("|", "\\|").replace(/\r\n|\r|\n/g, "<br>");
|
|
100996
|
+
}
|
|
100997
|
+
function renderPasses(passes) {
|
|
100998
|
+
if (passes.length === 0)
|
|
100999
|
+
return "No sync passes ran.";
|
|
101000
|
+
const header = "| model | source | created | updated | refreshed | stale | error |";
|
|
101001
|
+
const separator = "| --- | --- | --- | --- | --- | --- | --- |";
|
|
101002
|
+
const body = passes.map((pass) => [
|
|
101003
|
+
cell(pass.model),
|
|
101004
|
+
cell(pass.source),
|
|
101005
|
+
cell(pass.created),
|
|
101006
|
+
cell(pass.updated),
|
|
101007
|
+
cell(pass.refreshed),
|
|
101008
|
+
cell(pass.markedStale),
|
|
101009
|
+
cell(pass.error ?? (pass.skipped ? "skipped: already running" : undefined))
|
|
101010
|
+
].map((value) => ` ${value} `).join("|"));
|
|
101011
|
+
const warnings = passes.flatMap((pass) => pass.warnings.map((warning) => `- ${pass.model}.${pass.source}: ${warning}`));
|
|
101012
|
+
return [header, separator, ...body.map((row) => `|${row}|`), ...warnings].join(`
|
|
101013
|
+
`);
|
|
101014
|
+
}
|
|
101015
|
+
var registerAppSyncTool = (server) => {
|
|
101016
|
+
createToolRegistrar(server)("app-sync", {
|
|
101017
|
+
title: "Sync an app's sources",
|
|
101018
|
+
description: "Refresh an app's declared sources: pull each selected (model x source) pair and reconcile its rows.",
|
|
101019
|
+
annotations: { destructiveHint: false },
|
|
101020
|
+
rbac: { permission: "app.use" },
|
|
101021
|
+
inputSchema: object({
|
|
101022
|
+
appId: string().min(1).describe("App ID whose sources should sync."),
|
|
101023
|
+
model: AppNameSchema.optional().describe("Limit the sync to one model."),
|
|
101024
|
+
source: AppNameSchema.optional().describe("Limit the sync to one declared source name.")
|
|
101025
|
+
}),
|
|
101026
|
+
outputSchema: swarmToolOutputSchema({
|
|
101027
|
+
passes: array(looseObject({})).optional(),
|
|
101028
|
+
ok: boolean().optional()
|
|
101029
|
+
})
|
|
101030
|
+
}, async ({ appId: appId2, model, source }, requestInfo) => {
|
|
101031
|
+
if (!requestInfo.agentId)
|
|
101032
|
+
return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
|
|
101033
|
+
const agent = getAgentById(requestInfo.agentId);
|
|
101034
|
+
const decision = can({
|
|
101035
|
+
principal: { kind: "agent", agentId: requestInfo.agentId, isLead: agent?.isLead ?? false },
|
|
101036
|
+
verb: "app.use",
|
|
101037
|
+
resource: { kind: "app", appId: appId2 },
|
|
101038
|
+
source: "mcp"
|
|
101039
|
+
});
|
|
101040
|
+
if (!decision.allow)
|
|
101041
|
+
return toolErr(decision.reason);
|
|
101042
|
+
const app = getApp(appId2);
|
|
101043
|
+
if (!app)
|
|
101044
|
+
return toolErr(`App ${appId2} not found.`);
|
|
101045
|
+
const result = await runAppSync({
|
|
101046
|
+
appId: appId2,
|
|
101047
|
+
...model === undefined ? {} : { model },
|
|
101048
|
+
...source === undefined ? {} : { source },
|
|
101049
|
+
invokedBy: `agent:${requestInfo.agentId}`
|
|
101050
|
+
});
|
|
101051
|
+
if (result.issues && result.issues.length > 0) {
|
|
101052
|
+
return toolErr(`Cannot sync app "${app.name}" (${app.id}).`, {
|
|
101053
|
+
details: result.issues.map((issue) => `${issue.path}: ${issue.message}`).join(`
|
|
101054
|
+
`),
|
|
101055
|
+
data: { ok: false }
|
|
101056
|
+
});
|
|
101057
|
+
}
|
|
101058
|
+
const totals = result.passes.reduce((sum, pass) => ({
|
|
101059
|
+
created: sum.created + pass.created,
|
|
101060
|
+
updated: sum.updated + pass.updated,
|
|
101061
|
+
refreshed: sum.refreshed + pass.refreshed,
|
|
101062
|
+
markedStale: sum.markedStale + pass.markedStale
|
|
101063
|
+
}), { created: 0, updated: 0, refreshed: 0, markedStale: 0 });
|
|
101064
|
+
const summary = `${result.passes.length} pass(es): ${totals.created} created, ${totals.updated} updated, ` + `${totals.refreshed} refreshed, ${totals.markedStale} marked stale.`;
|
|
101065
|
+
const details = renderPasses(result.passes);
|
|
101066
|
+
const data = { ok: result.ok, passes: result.passes };
|
|
101067
|
+
if (!result.ok) {
|
|
101068
|
+
return toolErr(`Sync failed for app "${app.name}" (${app.id}) — ${summary}`, {
|
|
101069
|
+
details,
|
|
101070
|
+
data
|
|
101071
|
+
});
|
|
101072
|
+
}
|
|
101073
|
+
return toolOk(`Synced app "${app.name}" (${app.id}) — ${summary}`, { details, data });
|
|
101074
|
+
});
|
|
101075
|
+
};
|
|
101076
|
+
|
|
101456
101077
|
// src/tools/app-upsert.ts
|
|
101457
101078
|
init_zod();
|
|
101458
101079
|
init_db();
|
|
@@ -102122,7 +101743,7 @@ function snapshotMetric(metricId, changedByAgentId) {
|
|
|
102122
101743
|
// src/tools/create-metric.ts
|
|
102123
101744
|
init_types();
|
|
102124
101745
|
init_constants();
|
|
102125
|
-
function
|
|
101746
|
+
function slugify2(input) {
|
|
102126
101747
|
const slug = input.toLowerCase().normalize("NFKD").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
102127
101748
|
return slug || "metric";
|
|
102128
101749
|
}
|
|
@@ -102165,7 +101786,7 @@ var registerCreateMetricTool = (server) => {
|
|
|
102165
101786
|
data: { yourAgentId: requestInfo.agentId, id: "" }
|
|
102166
101787
|
});
|
|
102167
101788
|
}
|
|
102168
|
-
const slug = input.slug ??
|
|
101789
|
+
const slug = input.slug ?? slugify2(input.title);
|
|
102169
101790
|
const existing = getMetricBySlug(requestInfo.agentId, slug);
|
|
102170
101791
|
let id;
|
|
102171
101792
|
if (existing) {
|
|
@@ -102279,7 +101900,7 @@ function snapshotPage(pageId, changedByAgentId) {
|
|
|
102279
101900
|
// src/tools/create-page.ts
|
|
102280
101901
|
init_types();
|
|
102281
101902
|
init_constants();
|
|
102282
|
-
function
|
|
101903
|
+
function slugify3(input) {
|
|
102283
101904
|
const slug = input.toLowerCase().normalize("NFKD").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
102284
101905
|
return slug;
|
|
102285
101906
|
}
|
|
@@ -102322,7 +101943,7 @@ var registerCreatePageTool = (server) => {
|
|
|
102322
101943
|
const msg = "Agent ID required. Set the X-Agent-ID header on the MCP request.";
|
|
102323
101944
|
return toolErr(msg);
|
|
102324
101945
|
}
|
|
102325
|
-
const slug = input.slug ??
|
|
101946
|
+
const slug = input.slug ?? slugify3(input.title);
|
|
102326
101947
|
const finalSlug = slug || "page";
|
|
102327
101948
|
let passwordHash;
|
|
102328
101949
|
if (input.password) {
|
|
@@ -103263,8 +102884,8 @@ var getTasksOutputSchema = swarmToolOutputSchema({
|
|
|
103263
102884
|
var TASK_DETAILS_CELL_CAP = 180;
|
|
103264
102885
|
function escapeMarkdownCell(value) {
|
|
103265
102886
|
const text = String(value ?? "—");
|
|
103266
|
-
const
|
|
103267
|
-
return
|
|
102887
|
+
const compact = text.length > TASK_DETAILS_CELL_CAP ? `${text.slice(0, TASK_DETAILS_CELL_CAP - 1)}…` : text;
|
|
102888
|
+
return compact.replaceAll("\\", "\\\\").replaceAll("|", "\\|").replace(/\r\n|\r|\n/g, "<br>");
|
|
103268
102889
|
}
|
|
103269
102890
|
function renderTaskSummaries(tasks) {
|
|
103270
102891
|
if (tasks.length === 0)
|
|
@@ -108194,6 +107815,14 @@ function isRecord(value) {
|
|
|
108194
107815
|
function apiBaseUrl() {
|
|
108195
107816
|
return getMcpBaseUrl();
|
|
108196
107817
|
}
|
|
107818
|
+
function renderIssue(issue) {
|
|
107819
|
+
if (typeof issue === "string")
|
|
107820
|
+
return issue;
|
|
107821
|
+
if (isRecord(issue) && typeof issue.message === "string") {
|
|
107822
|
+
return typeof issue.path === "string" ? `${issue.path}: ${issue.message}` : issue.message;
|
|
107823
|
+
}
|
|
107824
|
+
return JSON.stringify(issue);
|
|
107825
|
+
}
|
|
108197
107826
|
function describeScriptFailure(resOk, status, data) {
|
|
108198
107827
|
const body = isRecord(data) ? data : undefined;
|
|
108199
107828
|
if (!resOk) {
|
|
@@ -108215,6 +107844,14 @@ function describeScriptFailure(resOk, status, data) {
|
|
|
108215
107844
|
return {
|
|
108216
107845
|
message: `${error ?? `Scripts API request failed with ${status}`} — ${violations.length} violation(s)`,
|
|
108217
107846
|
details: capDetails(violations.map((v) => typeof v === "string" ? v : JSON.stringify(v)).join(`
|
|
107847
|
+
`))
|
|
107848
|
+
};
|
|
107849
|
+
}
|
|
107850
|
+
const issues = body && Array.isArray(body.issues) ? body.issues : undefined;
|
|
107851
|
+
if (issues && issues.length > 0) {
|
|
107852
|
+
return {
|
|
107853
|
+
message: `${error ?? `Scripts API request failed with ${status}`} — ${issues.length} issue(s)`,
|
|
107854
|
+
details: capDetails(issues.map(renderIssue).join(`
|
|
108218
107855
|
`))
|
|
108219
107856
|
};
|
|
108220
107857
|
}
|
|
@@ -113594,7 +113231,7 @@ var registerCreateWorkflowTool = (server) => {
|
|
|
113594
113231
|
annotations: { destructiveHint: false },
|
|
113595
113232
|
description: `Create a new automation workflow. Key concepts:
|
|
113596
113233
|
` + `- Nodes are linked via 'next' (string or port-based record).
|
|
113597
|
-
` + "- CROSS-NODE DATA: To use output from an upstream node, you MUST declare an 'inputs' mapping on the downstream node. " + 'Example: inputs: { "cityData": "generate-city" } → then use {{cityData.taskOutput.field}} in config templates. ' +
|
|
113234
|
+
` + "- CROSS-NODE DATA: To use output from an upstream node, you MUST declare an 'inputs' mapping on the downstream node. " + 'Example: inputs: { "cityData": "generate-city" } → then use {{cityData.taskOutput.field}} in config templates. ' + "Without 'inputs', built-in trigger/input/workflow/swarm/run context remains available, but upstream outputs do not. " + "Agent-task templates may interpolate trigger and declared upstream aliases. SECURITY: executable source for script/swarm-script nodes does not: " + "inline script source allows only input/workflow/swarm/run values, while named swarm-script source is not workflow-interpolated. " + `Pass dynamic trigger or upstream values through config.args (argv for inline scripts; the args object for swarm-script).
|
|
113598
113235
|
` + "- STRUCTURED OUTPUT: For agent-task nodes, put outputSchema inside 'config' to validate the agent's raw JSON output. " + `Node-level outputSchema validates the executor's return ({taskId, taskOutput}), which is different.
|
|
113599
113236
|
` + `- Agent-task config: { template, outputSchema?, agentId?, tags?, priority?, dir?, vcsRepo?, model? }.
|
|
113600
113237
|
` + "- FOREACH NODE: type 'foreach' fans out one agent-task per item. Config: " + "{ over: <array or exact {{input}} token>, itemKey: <property name>, body: { type: 'agent-task', config: {...} } }. " + "The body config is interpolated once per item with {{item.*}} and {{index}}. Child steps use synthetic IDs " + "'<foreachNodeId>#<itemKey>'; the parent waits for every child and exposes one aggregate result to successors. " + `concurrency is not supported in v1; use definition-level onNodeFailure: 'continue' to aggregate failed children.
|
|
@@ -114240,6 +113877,30 @@ function resolveScriptsOnlyMode(opts) {
|
|
|
114240
113877
|
}
|
|
114241
113878
|
|
|
114242
113879
|
// src/server.ts
|
|
113880
|
+
var ALL_CAPABILITIES = [
|
|
113881
|
+
"core",
|
|
113882
|
+
"task-pool",
|
|
113883
|
+
"scripts",
|
|
113884
|
+
"config",
|
|
113885
|
+
"prompt-templates",
|
|
113886
|
+
"mcp",
|
|
113887
|
+
"profiles",
|
|
113888
|
+
"services",
|
|
113889
|
+
"scheduling",
|
|
113890
|
+
"memory",
|
|
113891
|
+
"workflows",
|
|
113892
|
+
"pages",
|
|
113893
|
+
"metrics",
|
|
113894
|
+
"kv",
|
|
113895
|
+
"slack",
|
|
113896
|
+
"tracker",
|
|
113897
|
+
"skills",
|
|
113898
|
+
"messaging",
|
|
113899
|
+
"repo",
|
|
113900
|
+
"agentmail",
|
|
113901
|
+
"kapso",
|
|
113902
|
+
"swarm-x"
|
|
113903
|
+
];
|
|
114243
113904
|
var DEFAULT_CAPABILITIES = [
|
|
114244
113905
|
"core",
|
|
114245
113906
|
"task-pool",
|
|
@@ -114418,6 +114079,7 @@ function createServer(opts = {}) {
|
|
|
114418
114079
|
registerAppPatchTool(server);
|
|
114419
114080
|
registerAppQueryTool(server);
|
|
114420
114081
|
registerAppRollbackTool(server);
|
|
114082
|
+
registerAppSyncTool(server);
|
|
114421
114083
|
registerAppUpsertTool(server);
|
|
114422
114084
|
registerCreatePageTool(server);
|
|
114423
114085
|
registerDeletePageTool(server);
|
|
@@ -114617,4 +114279,4 @@ function writeSkillsToFilesystem(entries, harnessType = "all", home) {
|
|
|
114617
114279
|
return { synced, removed, errors };
|
|
114618
114280
|
}
|
|
114619
114281
|
|
|
114620
|
-
export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, isInboxAllowed, isSenderAllowed, handleMessageReceived, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2 as handleIssue1, handleNote, handlePipeline, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, setCorsHeaders, parseQueryParams, getPathSegments, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, describeRequestRoute, route, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, mcpOverflowAuthError, isPollTracingEnabled, initOtel, withSpan, startSpan, withSpanContext, withRemoteContext, injectTraceContext, recordSessionCost, markScriptSdkRequestOrigin, toolErr, createToolRegistrar, userCtx, resolveTaskAuditUserId, resolveHttpAuditUserId, resolveHttpFavoriteOwner, handleApps, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, assertSelectOnlyQuery, executeReadOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, storeLinks, refreshLinks, canReadMemory, getLinksForMemory, recordRetrievals, expandCandidatesWithGraph, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, sendTaskOutputSchema, sendTaskHandler, parseSkillContent, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, guardTerminalTaskResultWrite, canClaim, emitBudgetRefusalSideEffects, taskActionInputSchema, taskActionOutputSchema, taskActionHandler, resolveScriptsOnlyMode, hasCapability, getEnabledCapabilities, createServer, writeSkillsToFilesystem };
|
|
114282
|
+
export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, isInboxAllowed, isSenderAllowed, handleMessageReceived, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2 as handleIssue1, handleNote, handlePipeline, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, setCorsHeaders, parseQueryParams, getPathSegments, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, describeRequestRoute, route, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, mcpOverflowAuthError, isPollTracingEnabled, initOtel, withSpan, startSpan, withSpanContext, withRemoteContext, injectTraceContext, recordSessionCost, markScriptSdkRequestOrigin, toolErr, createToolRegistrar, userCtx, resolveTaskAuditUserId, resolveHttpAuditUserId, resolveHttpFavoriteOwner, handleApps, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, assertSelectOnlyQuery, executeReadOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, storeLinks, refreshLinks, canReadMemory, getLinksForMemory, recordRetrievals, expandCandidatesWithGraph, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, sendTaskOutputSchema, sendTaskHandler, parseSkillContent, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, guardTerminalTaskResultWrite, canClaim, emitBudgetRefusalSideEffects, taskActionInputSchema, taskActionOutputSchema, taskActionHandler, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer, writeSkillsToFilesystem };
|