@cat-factory/server 0.170.0 → 0.171.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/dist/http/guards.d.ts +46 -0
- package/dist/http/guards.d.ts.map +1 -0
- package/dist/http/guards.js +57 -0
- package/dist/http/guards.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/accounts/AccountController.d.ts +0 -10
- package/dist/modules/accounts/AccountController.d.ts.map +1 -1
- package/dist/modules/accounts/AccountController.js +56 -101
- package/dist/modules/accounts/AccountController.js.map +1 -1
- package/dist/modules/agentRuns/AgentRunController.d.ts +0 -6
- package/dist/modules/agentRuns/AgentRunController.d.ts.map +1 -1
- package/dist/modules/agentRuns/AgentRunController.js +19 -16
- package/dist/modules/agentRuns/AgentRunController.js.map +1 -1
- package/dist/modules/artifacts/ArtifactController.d.ts.map +1 -1
- package/dist/modules/artifacts/ArtifactController.js +4 -15
- package/dist/modules/artifacts/ArtifactController.js.map +1 -1
- package/dist/modules/auth/AuthController.d.ts.map +1 -1
- package/dist/modules/auth/AuthController.js +14 -9
- package/dist/modules/auth/AuthController.js.map +1 -1
- package/dist/modules/bootstrap/BootstrapController.d.ts.map +1 -1
- package/dist/modules/bootstrap/BootstrapController.js +6 -20
- package/dist/modules/bootstrap/BootstrapController.js.map +1 -1
- package/dist/modules/brainstorm/BrainstormController.d.ts.map +1 -1
- package/dist/modules/brainstorm/BrainstormController.js +17 -27
- package/dist/modules/brainstorm/BrainstormController.js.map +1 -1
- package/dist/modules/bugHunt/BugHuntController.d.ts.map +1 -1
- package/dist/modules/bugHunt/BugHuntController.js +4 -12
- package/dist/modules/bugHunt/BugHuntController.js.map +1 -1
- package/dist/modules/clarity/ClarityReviewController.d.ts.map +1 -1
- package/dist/modules/clarity/ClarityReviewController.js +18 -27
- package/dist/modules/clarity/ClarityReviewController.js.map +1 -1
- package/dist/modules/docInterview/DocInterviewController.d.ts.map +1 -1
- package/dist/modules/docInterview/DocInterviewController.js +6 -17
- package/dist/modules/docInterview/DocInterviewController.js.map +1 -1
- package/dist/modules/documents/DocumentSourceController.d.ts.map +1 -1
- package/dist/modules/documents/DocumentSourceController.js +4 -32
- package/dist/modules/documents/DocumentSourceController.js.map +1 -1
- package/dist/modules/environments/EnvironmentController.d.ts.map +1 -1
- package/dist/modules/environments/EnvironmentController.js +10 -63
- package/dist/modules/environments/EnvironmentController.js.map +1 -1
- package/dist/modules/environments/EnvironmentUserHandlerController.d.ts.map +1 -1
- package/dist/modules/environments/EnvironmentUserHandlerController.js +16 -25
- package/dist/modules/environments/EnvironmentUserHandlerController.js.map +1 -1
- package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts.map +1 -1
- package/dist/modules/fragmentLibrary/FragmentLibraryController.js +26 -60
- package/dist/modules/fragmentLibrary/FragmentLibraryController.js.map +1 -1
- package/dist/modules/github/GitHubController.d.ts.map +1 -1
- package/dist/modules/github/GitHubController.js +14 -48
- package/dist/modules/github/GitHubController.js.map +1 -1
- package/dist/modules/gitlab/GitLabController.d.ts.map +1 -1
- package/dist/modules/gitlab/GitLabController.js +3 -12
- package/dist/modules/gitlab/GitLabController.js.map +1 -1
- package/dist/modules/incidentEnrichment/IncidentEnrichmentController.d.ts.map +1 -1
- package/dist/modules/incidentEnrichment/IncidentEnrichmentController.js +3 -12
- package/dist/modules/incidentEnrichment/IncidentEnrichmentController.js.map +1 -1
- package/dist/modules/initiatives/InitiativeController.d.ts.map +1 -1
- package/dist/modules/initiatives/InitiativeController.js +4 -39
- package/dist/modules/initiatives/InitiativeController.js.map +1 -1
- package/dist/modules/kaizen/KaizenController.d.ts.map +1 -1
- package/dist/modules/kaizen/KaizenController.js +3 -10
- package/dist/modules/kaizen/KaizenController.js.map +1 -1
- package/dist/modules/localModels/LocalModelEndpointController.d.ts.map +1 -1
- package/dist/modules/localModels/LocalModelEndpointController.js +21 -31
- package/dist/modules/localModels/LocalModelEndpointController.js.map +1 -1
- package/dist/modules/localSettings/LocalSettingsController.d.ts +0 -9
- package/dist/modules/localSettings/LocalSettingsController.d.ts.map +1 -1
- package/dist/modules/localSettings/LocalSettingsController.js +9 -12
- package/dist/modules/localSettings/LocalSettingsController.js.map +1 -1
- package/dist/modules/merge/MergeTrackRecordController.d.ts.map +1 -1
- package/dist/modules/merge/MergeTrackRecordController.js +3 -10
- package/dist/modules/merge/MergeTrackRecordController.js.map +1 -1
- package/dist/modules/merge/RiskPolicyController.d.ts.map +1 -1
- package/dist/modules/merge/RiskPolicyController.js +3 -16
- package/dist/modules/merge/RiskPolicyController.js.map +1 -1
- package/dist/modules/modelPresets/ModelPresetController.d.ts.map +1 -1
- package/dist/modules/modelPresets/ModelPresetController.js +3 -16
- package/dist/modules/modelPresets/ModelPresetController.js.map +1 -1
- package/dist/modules/notificationWebhook/NotificationWebhookController.d.ts.map +1 -1
- package/dist/modules/notificationWebhook/NotificationWebhookController.js +3 -12
- package/dist/modules/notificationWebhook/NotificationWebhookController.js.map +1 -1
- package/dist/modules/notifications/NotificationController.d.ts.map +1 -1
- package/dist/modules/notifications/NotificationController.js +3 -12
- package/dist/modules/notifications/NotificationController.js.map +1 -1
- package/dist/modules/observability/PlatformObservabilityController.d.ts.map +1 -1
- package/dist/modules/observability/PlatformObservabilityController.js +7 -11
- package/dist/modules/observability/PlatformObservabilityController.js.map +1 -1
- package/dist/modules/openrouter/OpenRouterCatalogController.d.ts.map +1 -1
- package/dist/modules/openrouter/OpenRouterCatalogController.js +19 -23
- package/dist/modules/openrouter/OpenRouterCatalogController.js.map +1 -1
- package/dist/modules/packageRegistries/PackageRegistriesController.d.ts.map +1 -1
- package/dist/modules/packageRegistries/PackageRegistriesController.js +3 -12
- package/dist/modules/packageRegistries/PackageRegistriesController.js.map +1 -1
- package/dist/modules/preflight/PreflightController.d.ts.map +1 -1
- package/dist/modules/preflight/PreflightController.js +3 -8
- package/dist/modules/preflight/PreflightController.js.map +1 -1
- package/dist/modules/preview/PreviewController.d.ts.map +1 -1
- package/dist/modules/preview/PreviewController.js +4 -14
- package/dist/modules/preview/PreviewController.js.map +1 -1
- package/dist/modules/providers/ApiKeyController.d.ts +0 -1
- package/dist/modules/providers/ApiKeyController.d.ts.map +1 -1
- package/dist/modules/providers/ApiKeyController.js +21 -43
- package/dist/modules/providers/ApiKeyController.js.map +1 -1
- package/dist/modules/providers/PersonalSubscriptionController.d.ts.map +1 -1
- package/dist/modules/providers/PersonalSubscriptionController.js +15 -25
- package/dist/modules/providers/PersonalSubscriptionController.js.map +1 -1
- package/dist/modules/providers/UserSecretController.d.ts.map +1 -1
- package/dist/modules/providers/UserSecretController.js +23 -37
- package/dist/modules/providers/UserSecretController.js.map +1 -1
- package/dist/modules/providers/VendorCredentialController.d.ts.map +1 -1
- package/dist/modules/providers/VendorCredentialController.js +9 -16
- package/dist/modules/providers/VendorCredentialController.js.map +1 -1
- package/dist/modules/provisioningLogs/ProvisioningLogController.d.ts.map +1 -1
- package/dist/modules/provisioningLogs/ProvisioningLogController.js +3 -8
- package/dist/modules/provisioningLogs/ProvisioningLogController.js.map +1 -1
- package/dist/modules/publicApi/PublicApiKeyController.d.ts +0 -1
- package/dist/modules/publicApi/PublicApiKeyController.d.ts.map +1 -1
- package/dist/modules/publicApi/PublicApiKeyController.js +8 -13
- package/dist/modules/publicApi/PublicApiKeyController.js.map +1 -1
- package/dist/modules/recurring/RecurringPipelineController.d.ts.map +1 -1
- package/dist/modules/recurring/RecurringPipelineController.js +3 -18
- package/dist/modules/recurring/RecurringPipelineController.js.map +1 -1
- package/dist/modules/recurring/TrackerSettingsController.d.ts.map +1 -1
- package/dist/modules/recurring/TrackerSettingsController.js +3 -10
- package/dist/modules/recurring/TrackerSettingsController.js.map +1 -1
- package/dist/modules/releaseHealth/ReleaseHealthController.d.ts.map +1 -1
- package/dist/modules/releaseHealth/ReleaseHealthController.js +3 -18
- package/dist/modules/releaseHealth/ReleaseHealthController.js.map +1 -1
- package/dist/modules/reports/ReportsController.d.ts.map +1 -1
- package/dist/modules/reports/ReportsController.js +7 -11
- package/dist/modules/reports/ReportsController.js.map +1 -1
- package/dist/modules/requirements/RequirementReviewController.d.ts.map +1 -1
- package/dist/modules/requirements/RequirementReviewController.js +18 -36
- package/dist/modules/requirements/RequirementReviewController.js.map +1 -1
- package/dist/modules/runners/RunnerPoolController.d.ts.map +1 -1
- package/dist/modules/runners/RunnerPoolController.js +3 -18
- package/dist/modules/runners/RunnerPoolController.js.map +1 -1
- package/dist/modules/sandbox/SandboxController.d.ts.map +1 -1
- package/dist/modules/sandbox/SandboxController.js +3 -32
- package/dist/modules/sandbox/SandboxController.js.map +1 -1
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts.map +1 -1
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js +3 -10
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js.map +1 -1
- package/dist/modules/services/ServiceMountController.d.ts.map +1 -1
- package/dist/modules/services/ServiceMountController.js +3 -16
- package/dist/modules/services/ServiceMountController.js.map +1 -1
- package/dist/modules/settings/WorkspaceSettingsController.d.ts.map +1 -1
- package/dist/modules/settings/WorkspaceSettingsController.js +3 -10
- package/dist/modules/settings/WorkspaceSettingsController.js.map +1 -1
- package/dist/modules/sharedStack/SharedStackController.d.ts.map +1 -1
- package/dist/modules/sharedStack/SharedStackController.js +3 -20
- package/dist/modules/sharedStack/SharedStackController.js.map +1 -1
- package/dist/modules/skillLibrary/SkillLibraryController.d.ts.map +1 -1
- package/dist/modules/skillLibrary/SkillLibraryController.js +21 -44
- package/dist/modules/skillLibrary/SkillLibraryController.js.map +1 -1
- package/dist/modules/slack/SlackController.d.ts.map +1 -1
- package/dist/modules/slack/SlackController.js +4 -26
- package/dist/modules/slack/SlackController.js.map +1 -1
- package/dist/modules/tasks/TaskSourceController.d.ts.map +1 -1
- package/dist/modules/tasks/TaskSourceController.js +5 -47
- package/dist/modules/tasks/TaskSourceController.js.map +1 -1
- package/dist/modules/testSecrets/TestSecretsController.d.ts.map +1 -1
- package/dist/modules/testSecrets/TestSecretsController.js +3 -12
- package/dist/modules/testSecrets/TestSecretsController.js.map +1 -1
- package/dist/modules/userSettings/UserSettingsController.d.ts.map +1 -1
- package/dist/modules/userSettings/UserSettingsController.js +13 -19
- package/dist/modules/userSettings/UserSettingsController.js.map +1 -1
- package/dist/modules/validation/ValidationConfigController.d.ts.map +1 -1
- package/dist/modules/validation/ValidationConfigController.js +3 -14
- package/dist/modules/validation/ValidationConfigController.js.map +1 -1
- package/dist/modules/workspaces/WorkspaceController.d.ts.map +1 -1
- package/dist/modules/workspaces/WorkspaceController.js +9 -4
- package/dist/modules/workspaces/WorkspaceController.js.map +1 -1
- package/dist/modules/workspaces/WorkspaceMemberController.d.ts.map +1 -1
- package/dist/modules/workspaces/WorkspaceMemberController.js +10 -19
- package/dist/modules/workspaces/WorkspaceMemberController.js.map +1 -1
- package/package.json +8 -8
- package/dist/agents/storeAgentContextGate.d.ts +0 -36
- package/dist/agents/storeAgentContextGate.d.ts.map +0 -1
- package/dist/agents/storeAgentContextGate.js +0 -36
- package/dist/agents/storeAgentContextGate.js.map +0 -1
|
@@ -1,48 +1,44 @@
|
|
|
1
1
|
import { getOpenRouterCatalogContract, refreshOpenRouterCatalogContract, upsertOpenRouterCatalogContract, } from '@cat-factory/contracts';
|
|
2
2
|
import { buildHonoRoute } from '@toad-contracts/hono';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
|
-
import {
|
|
4
|
+
import { requireCapability, requireUser } from '../../http/guards.js';
|
|
5
5
|
// Per-WORKSPACE OpenRouter dynamic catalog. OpenRouter is a single OpenAI-compatible
|
|
6
6
|
// gateway to 300+ models reached via the workspace's API-key pool; a workspace browses the
|
|
7
7
|
// live catalog (`/refresh`, leasing the pooled OpenRouter key server-side) and enables a
|
|
8
8
|
// subset (`PUT /catalog`). The enabled models surface in the per-workspace model picker and
|
|
9
9
|
// feed the spend budget. Mounted at `/` (workspaceId is a path param); requires a signed-in user.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
/** Resolve the OpenRouter catalog store, or refuse with a 503 naming what isn't wired. */
|
|
11
|
+
function requireCatalog(c) {
|
|
12
|
+
return requireCapability(c.get('container').openRouterCatalog, 'OpenRouter catalog storage is not configured');
|
|
13
|
+
}
|
|
14
|
+
/** The signed-in caller, or a 401 wording the prompt for what this controller manages. */
|
|
15
|
+
function requireSignedIn(c) {
|
|
16
|
+
return requireUser(c, 'Sign in to manage the OpenRouter catalog');
|
|
17
|
+
}
|
|
18
|
+
/** The same 401, for a route that needs a signed-in caller but reads nothing off them. */
|
|
19
|
+
function assertSignedIn(c) {
|
|
20
|
+
requireSignedIn(c);
|
|
21
|
+
}
|
|
16
22
|
export function openRouterCatalogController() {
|
|
17
23
|
const app = new Hono();
|
|
18
24
|
// The workspace's enabled OpenRouter models (empty when none configured yet).
|
|
19
25
|
buildHonoRoute(app, getOpenRouterCatalogContract, async (c) => {
|
|
20
|
-
const svc = c
|
|
21
|
-
|
|
22
|
-
return unavailable();
|
|
23
|
-
if (!c.get('user'))
|
|
24
|
-
return signInRequired();
|
|
26
|
+
const svc = requireCatalog(c);
|
|
27
|
+
assertSignedIn(c);
|
|
25
28
|
return c.json(await svc.get(c.req.valid('param').workspaceId), 200);
|
|
26
29
|
});
|
|
27
30
|
// Replace the workspace's enabled subset (the client sends each model's metadata it read
|
|
28
31
|
// from the browse list, so the server + spend table get accurate context + pricing).
|
|
29
32
|
buildHonoRoute(app, upsertOpenRouterCatalogContract, async (c) => {
|
|
30
|
-
const svc = c
|
|
31
|
-
|
|
32
|
-
return unavailable();
|
|
33
|
-
if (!c.get('user'))
|
|
34
|
-
return signInRequired();
|
|
33
|
+
const svc = requireCatalog(c);
|
|
34
|
+
assertSignedIn(c);
|
|
35
35
|
return c.json(await svc.upsert(c.req.valid('param').workspaceId, c.req.valid('json')), 200);
|
|
36
36
|
});
|
|
37
37
|
// Probe OpenRouter's live `/models` for the browse list (leases the workspace's pooled
|
|
38
38
|
// OpenRouter key server-side). Never throws — failures come back as { reachable: false }.
|
|
39
39
|
buildHonoRoute(app, refreshOpenRouterCatalogContract, async (c) => {
|
|
40
|
-
const svc = c
|
|
41
|
-
|
|
42
|
-
return unavailable();
|
|
43
|
-
const user = c.get('user');
|
|
44
|
-
if (!user)
|
|
45
|
-
return signInRequired();
|
|
40
|
+
const svc = requireCatalog(c);
|
|
41
|
+
const user = requireSignedIn(c);
|
|
46
42
|
return c.json(await svc.refresh(c.req.valid('param').workspaceId, { userId: user.id }), 200);
|
|
47
43
|
});
|
|
48
44
|
return app;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenRouterCatalogController.js","sourceRoot":"","sources":["../../../src/modules/openrouter/OpenRouterCatalogController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"OpenRouterCatalogController.js","sourceRoot":"","sources":["../../../src/modules/openrouter/OpenRouterCatalogController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAErE,qFAAqF;AACrF,2FAA2F;AAC3F,yFAAyF;AACzF,4FAA4F;AAC5F,kGAAkG;AAElG,0FAA0F;AAC1F,SAAS,cAAc,CAAmB,CAAa;IACrD,OAAO,iBAAiB,CACtB,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,iBAAiB,EACpC,8CAA8C,CAC/C,CAAA;AACH,CAAC;AAED,0FAA0F;AAC1F,SAAS,eAAe,CAAmB,CAAa;IACtD,OAAO,WAAW,CAAC,CAAC,EAAE,0CAA0C,CAAC,CAAA;AACnE,CAAC;AAED,0FAA0F;AAC1F,SAAS,cAAc,CAAmB,CAAa;IACrD,eAAe,CAAC,CAAC,CAAC,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,2BAA2B;IACzC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAE9B,8EAA8E;IAC9E,cAAc,CAAC,GAAG,EAAE,4BAA4B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5D,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QAC7B,cAAc,CAAC,CAAC,CAAC,CAAA;QACjB,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,CAAA;IACrE,CAAC,CAAC,CAAA;IAEF,yFAAyF;IACzF,qFAAqF;IACrF,cAAc,CAAC,GAAG,EAAE,+BAA+B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/D,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QAC7B,cAAc,CAAC,CAAC,CAAC,CAAA;QACjB,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC7F,CAAC,CAAC,CAAA;IAEF,uFAAuF;IACvF,0FAA0F;IAC1F,cAAc,CAAC,GAAG,EAAE,gCAAgC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAChE,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QAC7B,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;QAC/B,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;IAC9F,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageRegistriesController.d.ts","sourceRoot":"","sources":["../../../src/modules/packageRegistries/PackageRegistriesController.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"PackageRegistriesController.d.ts","sourceRoot":"","sources":["../../../src/modules/packageRegistries/PackageRegistriesController.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAa/C;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAAC,MAAM,CAAC,CAqB1D"}
|
|
@@ -3,14 +3,11 @@ import { buildHonoRoute } from '@toad-contracts/hono';
|
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
4
|
import { requireWorkspacePermission } from '../../http/workspaceAccess.js';
|
|
5
5
|
import { param } from '../../http/params.js';
|
|
6
|
-
import {
|
|
7
|
-
/** Resolve the package-registries module or
|
|
6
|
+
import { requireCapability } from '../../http/guards.js';
|
|
7
|
+
/** Resolve the package-registries module, or refuse with a 503 naming what isn't wired. */
|
|
8
8
|
function requirePackageRegistries(c) {
|
|
9
|
-
return c.get('container').packageRegistries
|
|
9
|
+
return requireCapability(c.get('container').packageRegistries, 'The package-registry integration is not configured');
|
|
10
10
|
}
|
|
11
|
-
const unavailable = () => {
|
|
12
|
-
throw new UnavailableError('The package-registry integration is not configured');
|
|
13
|
-
};
|
|
14
11
|
/**
|
|
15
12
|
* Per-workspace private package-registry entries (npm private orgs, GitHub Packages)
|
|
16
13
|
* that agent containers use to resolve private dependencies. Tokens are write-only —
|
|
@@ -22,20 +19,14 @@ export function packageRegistriesController() {
|
|
|
22
19
|
app.use('*', requireWorkspacePermission('integrations.manage'));
|
|
23
20
|
buildHonoRoute(app, listPackageRegistriesContract, async (c) => {
|
|
24
21
|
const registries = requirePackageRegistries(c);
|
|
25
|
-
if (!registries)
|
|
26
|
-
return unavailable();
|
|
27
22
|
return c.json(await registries.service.list(param(c, 'workspaceId')), 200);
|
|
28
23
|
});
|
|
29
24
|
buildHonoRoute(app, addPackageRegistryContract, async (c) => {
|
|
30
25
|
const registries = requirePackageRegistries(c);
|
|
31
|
-
if (!registries)
|
|
32
|
-
return unavailable();
|
|
33
26
|
return c.json(await registries.service.add(param(c, 'workspaceId'), c.req.valid('json')), 200);
|
|
34
27
|
});
|
|
35
28
|
buildHonoRoute(app, deletePackageRegistryContract, async (c) => {
|
|
36
29
|
const registries = requirePackageRegistries(c);
|
|
37
|
-
if (!registries)
|
|
38
|
-
return unavailable();
|
|
39
30
|
await registries.service.remove(param(c, 'workspaceId'), c.req.valid('param').entryId);
|
|
40
31
|
return c.body(null, 204);
|
|
41
32
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageRegistriesController.js","sourceRoot":"","sources":["../../../src/modules/packageRegistries/PackageRegistriesController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAI3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"PackageRegistriesController.js","sourceRoot":"","sources":["../../../src/modules/packageRegistries/PackageRegistriesController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAI3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExD,2FAA2F;AAC3F,SAAS,wBAAwB,CAAmB,CAAa;IAC/D,OAAO,iBAAiB,CACtB,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,iBAAiB,EACpC,oDAAoD,CACrD,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B;IACzC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,0BAA0B,CAAC,qBAAqB,CAAC,CAAC,CAAA;IAE/D,cAAc,CAAC,GAAG,EAAE,6BAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7D,MAAM,UAAU,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAA;QAC9C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IAEF,cAAc,CAAC,GAAG,EAAE,0BAA0B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1D,MAAM,UAAU,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAA;QAC9C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAChG,CAAC,CAAC,CAAA;IAEF,cAAc,CAAC,GAAG,EAAE,6BAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7D,MAAM,UAAU,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAA;QAC9C,MAAM,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAA;QACtF,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreflightController.d.ts","sourceRoot":"","sources":["../../../src/modules/preflight/PreflightController.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"PreflightController.d.ts","sourceRoot":"","sources":["../../../src/modules/preflight/PreflightController.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAW/C;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,CAUlD"}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { runPreflightsContract } from '@cat-factory/contracts';
|
|
2
2
|
import { buildHonoRoute } from '@toad-contracts/hono';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
|
-
import {
|
|
5
|
-
/** Resolve the preflight module, or
|
|
4
|
+
import { requireCapability } from '../../http/guards.js';
|
|
5
|
+
/** Resolve the preflight module, or 503 when the host-probe runtime isn't wired (non-local facade). */
|
|
6
6
|
function requirePreflight(c) {
|
|
7
|
-
return c.get('container').preflight
|
|
7
|
+
return requireCapability(c.get('container').preflight, 'Preflight checks are not available on this deployment');
|
|
8
8
|
}
|
|
9
|
-
const unavailable = () => {
|
|
10
|
-
throw new UnavailableError('Preflight checks are not available on this deployment');
|
|
11
|
-
};
|
|
12
9
|
/**
|
|
13
10
|
* Run a set of preflight checks (machine-prerequisite probes with guided remediation) and return
|
|
14
11
|
* one verdict per ref — the setup wizard's live re-check button (slice 7) + any ad-hoc "am I ready
|
|
@@ -19,8 +16,6 @@ export function preflightController() {
|
|
|
19
16
|
const app = new Hono();
|
|
20
17
|
buildHonoRoute(app, runPreflightsContract, async (c) => {
|
|
21
18
|
const preflight = requirePreflight(c);
|
|
22
|
-
if (!preflight)
|
|
23
|
-
return unavailable();
|
|
24
19
|
const { prerequisites } = c.req.valid('json');
|
|
25
20
|
return c.json(await preflight.service.run(prerequisites), 200);
|
|
26
21
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreflightController.js","sourceRoot":"","sources":["../../../src/modules/preflight/PreflightController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"PreflightController.js","sourceRoot":"","sources":["../../../src/modules/preflight/PreflightController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExD,uGAAuG;AACvG,SAAS,gBAAgB,CAAmB,CAAa;IACvD,OAAO,iBAAiB,CACtB,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,SAAS,EAC5B,uDAAuD,CACxD,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAE9B,cAAc,CAAC,GAAG,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrD,MAAM,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAA;QACrC,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAC7C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreviewController.d.ts","sourceRoot":"","sources":["../../../src/modules/preview/PreviewController.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"PreviewController.d.ts","sourceRoot":"","sources":["../../../src/modules/preview/PreviewController.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAoB/C;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,CAuBhD"}
|
|
@@ -3,22 +3,18 @@ import { buildHonoRoute } from '@toad-contracts/hono';
|
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
4
|
import { requireWorkspacePermission } from '../../http/workspaceAccess.js';
|
|
5
5
|
import { param } from '../../http/params.js';
|
|
6
|
-
import {
|
|
6
|
+
import { requireCapability } from '../../http/guards.js';
|
|
7
7
|
/**
|
|
8
8
|
* Resolve the preview module, gating on the runtime's `frontendPreview.supported` capability
|
|
9
9
|
* FIRST (defense-in-depth: slice 5a only gated the SPA toggle, so a direct API call on an
|
|
10
|
-
* unsupported runtime — e.g. the Worker — must still be refused here).
|
|
10
|
+
* unsupported runtime — e.g. the Worker — must still be refused here). Refuses with a 503
|
|
11
11
|
* when the runtime can't host a preview OR the module isn't wired.
|
|
12
12
|
*/
|
|
13
13
|
function requirePreview(c) {
|
|
14
14
|
const container = c.get('container');
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return container.preview ?? null;
|
|
15
|
+
const supported = container.config.infrastructure?.frontendPreview?.supported !== false;
|
|
16
|
+
return requireCapability(supported ? container.preview : null, 'Browsable frontend previews are not supported on this runtime');
|
|
18
17
|
}
|
|
19
|
-
const unavailable = () => {
|
|
20
|
-
throw new UnavailableError('Browsable frontend previews are not supported on this runtime');
|
|
21
|
-
};
|
|
22
18
|
/**
|
|
23
19
|
* Browsable frontend preview (slice 5c): start / poll / stop a long-lived build+serve container
|
|
24
20
|
* for a `frontend` frame, reachable on a host URL. A local/node differentiator — 503 on the
|
|
@@ -29,22 +25,16 @@ export function previewController() {
|
|
|
29
25
|
app.use('*', requireWorkspacePermission('integrations.manage'));
|
|
30
26
|
buildHonoRoute(app, getPreviewContract, async (c) => {
|
|
31
27
|
const preview = requirePreview(c);
|
|
32
|
-
if (!preview)
|
|
33
|
-
return unavailable();
|
|
34
28
|
const frameId = c.req.valid('param').frameId;
|
|
35
29
|
return c.json(await preview.service.get(param(c, 'workspaceId'), frameId), 200);
|
|
36
30
|
});
|
|
37
31
|
buildHonoRoute(app, startPreviewContract, async (c) => {
|
|
38
32
|
const preview = requirePreview(c);
|
|
39
|
-
if (!preview)
|
|
40
|
-
return unavailable();
|
|
41
33
|
const frameId = c.req.valid('param').frameId;
|
|
42
34
|
return c.json(await preview.service.start(param(c, 'workspaceId'), frameId), 201);
|
|
43
35
|
});
|
|
44
36
|
buildHonoRoute(app, stopPreviewContract, async (c) => {
|
|
45
37
|
const preview = requirePreview(c);
|
|
46
|
-
if (!preview)
|
|
47
|
-
return unavailable();
|
|
48
38
|
const frameId = c.req.valid('param').frameId;
|
|
49
39
|
return c.json(await preview.service.stop(param(c, 'workspaceId'), frameId), 200);
|
|
50
40
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreviewController.js","sourceRoot":"","sources":["../../../src/modules/preview/PreviewController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAI3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"PreviewController.js","sourceRoot":"","sources":["../../../src/modules/preview/PreviewController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAI3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExD;;;;;GAKG;AACH,SAAS,cAAc,CAAmB,CAAa;IACrD,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACpC,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,cAAc,EAAE,eAAe,EAAE,SAAS,KAAK,KAAK,CAAA;IACvF,OAAO,iBAAiB,CACtB,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EACpC,+DAA+D,CAChE,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,0BAA0B,CAAC,qBAAqB,CAAC,CAAC,CAAA;IAE/D,cAAc,CAAC,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QACjC,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAA;QAC5C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAA;IACjF,CAAC,CAAC,CAAA;IAEF,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACpD,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QACjC,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAA;QAC5C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAA;IACnF,CAAC,CAAC,CAAA;IAEF,cAAc,CAAC,GAAG,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACnD,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QACjC,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAA;QAC5C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAA;IAClF,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -2,7 +2,6 @@ import { type ApiKey } from '@cat-factory/contracts';
|
|
|
2
2
|
import type { ApiKeySummary } from '@cat-factory/integrations';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
4
|
import type { AppEnv } from '../../http/env.js';
|
|
5
|
-
/** Project the service summary onto the wire type (already secret-free). */
|
|
6
5
|
export declare function apiKeyToWire(summary: ApiKeySummary): ApiKey;
|
|
7
6
|
/** Workspace-scoped API-key routes, mounted under `/workspaces/:workspaceId`. */
|
|
8
7
|
export declare function workspaceApiKeyController(): Hono<AppEnv>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiKeyController.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/ApiKeyController.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,MAAM,EACZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAE9D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"ApiKeyController.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/ApiKeyController.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,MAAM,EACZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAE9D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAwB/C,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAe3D;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,IAAI,IAAI,CAAC,MAAM,CAAC,CAkCxD;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,MAAM,CAAC,CAqCnD"}
|
|
@@ -3,7 +3,7 @@ import { buildHonoRoute } from '@toad-contracts/hono';
|
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
4
|
import { requireWorkspacePermission } from '../../http/workspaceAccess.js';
|
|
5
5
|
import { param } from '../../http/params.js';
|
|
6
|
-
import {
|
|
6
|
+
import { requireCapability, requireUser } from '../../http/guards.js';
|
|
7
7
|
// Direct-provider API-key endpoints. Keys (OpenAI/Anthropic/Qwen/DeepSeek/Moonshot)
|
|
8
8
|
// are onboarded here and stored encrypted, replacing deployment-env onboarding. The
|
|
9
9
|
// raw key is write-only — only metadata + rolling-window usage is ever returned.
|
|
@@ -11,13 +11,15 @@ import { UnavailableError, UnauthorizedError } from '@cat-factory/kernel';
|
|
|
11
11
|
// This controller mounts the WORKSPACE-scoped routes (under `/workspaces/:workspaceId`)
|
|
12
12
|
// and the USER-scoped routes (`/me/api-keys`, the caller's own pool). ACCOUNT-scoped
|
|
13
13
|
// keys are managed by the AccountController, which admin-gates them.
|
|
14
|
-
const unavailable = () => {
|
|
15
|
-
throw new UnavailableError('API key storage is not configured');
|
|
16
|
-
};
|
|
17
|
-
const signInRequired = () => {
|
|
18
|
-
throw new UnauthorizedError('Sign in to manage your API keys');
|
|
19
|
-
};
|
|
20
14
|
/** Project the service summary onto the wire type (already secret-free). */
|
|
15
|
+
/** Resolve the API-key store, or refuse with a 503 naming what isn't wired. */
|
|
16
|
+
function requireApiKeys(c) {
|
|
17
|
+
return requireCapability(c.get('container').apiKeys, 'API key storage is not configured');
|
|
18
|
+
}
|
|
19
|
+
/** The signed-in caller, or a 401 wording the prompt for what this controller manages. */
|
|
20
|
+
function requireSignedIn(c) {
|
|
21
|
+
return requireUser(c, 'Sign in to manage your API keys');
|
|
22
|
+
}
|
|
21
23
|
export function apiKeyToWire(summary) {
|
|
22
24
|
return {
|
|
23
25
|
id: summary.id,
|
|
@@ -39,30 +41,22 @@ export function workspaceApiKeyController() {
|
|
|
39
41
|
const app = new Hono();
|
|
40
42
|
app.use('*', requireWorkspacePermission('secrets.manage'));
|
|
41
43
|
buildHonoRoute(app, listWorkspaceApiKeysContract, async (c) => {
|
|
42
|
-
const apiKeys = c
|
|
43
|
-
if (!apiKeys)
|
|
44
|
-
return unavailable();
|
|
44
|
+
const apiKeys = requireApiKeys(c);
|
|
45
45
|
const keys = await apiKeys.listKeys('workspace', param(c, 'workspaceId'));
|
|
46
46
|
return c.json({ keys: keys.map(apiKeyToWire) }, 200);
|
|
47
47
|
});
|
|
48
48
|
buildHonoRoute(app, addWorkspaceApiKeyContract, async (c) => {
|
|
49
|
-
const apiKeys = c
|
|
50
|
-
if (!apiKeys)
|
|
51
|
-
return unavailable();
|
|
49
|
+
const apiKeys = requireApiKeys(c);
|
|
52
50
|
const summary = await apiKeys.addKey('workspace', param(c, 'workspaceId'), c.req.valid('json'));
|
|
53
51
|
return c.json(apiKeyToWire(summary), 201);
|
|
54
52
|
});
|
|
55
53
|
buildHonoRoute(app, updateWorkspaceApiKeyContract, async (c) => {
|
|
56
|
-
const apiKeys = c
|
|
57
|
-
if (!apiKeys)
|
|
58
|
-
return unavailable();
|
|
54
|
+
const apiKeys = requireApiKeys(c);
|
|
59
55
|
const summary = await apiKeys.updateKey('workspace', param(c, 'workspaceId'), c.req.valid('param').id, c.req.valid('json'));
|
|
60
56
|
return c.json(apiKeyToWire(summary), 200);
|
|
61
57
|
});
|
|
62
58
|
buildHonoRoute(app, removeWorkspaceApiKeyContract, async (c) => {
|
|
63
|
-
const apiKeys = c
|
|
64
|
-
if (!apiKeys)
|
|
65
|
-
return unavailable();
|
|
59
|
+
const apiKeys = requireApiKeys(c);
|
|
66
60
|
await apiKeys.removeKey('workspace', param(c, 'workspaceId'), c.req.valid('param').id);
|
|
67
61
|
return c.body(null, 204);
|
|
68
62
|
});
|
|
@@ -72,42 +66,26 @@ export function workspaceApiKeyController() {
|
|
|
72
66
|
export function userApiKeyController() {
|
|
73
67
|
const app = new Hono();
|
|
74
68
|
buildHonoRoute(app, listUserApiKeysContract, async (c) => {
|
|
75
|
-
const apiKeys = c
|
|
76
|
-
|
|
77
|
-
return unavailable();
|
|
78
|
-
const user = c.get('user');
|
|
79
|
-
if (!user)
|
|
80
|
-
return signInRequired();
|
|
69
|
+
const apiKeys = requireApiKeys(c);
|
|
70
|
+
const user = requireSignedIn(c);
|
|
81
71
|
const keys = await apiKeys.listKeys('user', user.id);
|
|
82
72
|
return c.json({ keys: keys.map(apiKeyToWire) }, 200);
|
|
83
73
|
});
|
|
84
74
|
buildHonoRoute(app, addUserApiKeyContract, async (c) => {
|
|
85
|
-
const apiKeys = c
|
|
86
|
-
|
|
87
|
-
return unavailable();
|
|
88
|
-
const user = c.get('user');
|
|
89
|
-
if (!user)
|
|
90
|
-
return signInRequired();
|
|
75
|
+
const apiKeys = requireApiKeys(c);
|
|
76
|
+
const user = requireSignedIn(c);
|
|
91
77
|
const summary = await apiKeys.addKey('user', user.id, c.req.valid('json'));
|
|
92
78
|
return c.json(apiKeyToWire(summary), 201);
|
|
93
79
|
});
|
|
94
80
|
buildHonoRoute(app, updateUserApiKeyContract, async (c) => {
|
|
95
|
-
const apiKeys = c
|
|
96
|
-
|
|
97
|
-
return unavailable();
|
|
98
|
-
const user = c.get('user');
|
|
99
|
-
if (!user)
|
|
100
|
-
return signInRequired();
|
|
81
|
+
const apiKeys = requireApiKeys(c);
|
|
82
|
+
const user = requireSignedIn(c);
|
|
101
83
|
const summary = await apiKeys.updateKey('user', user.id, c.req.valid('param').id, c.req.valid('json'));
|
|
102
84
|
return c.json(apiKeyToWire(summary), 200);
|
|
103
85
|
});
|
|
104
86
|
buildHonoRoute(app, removeUserApiKeyContract, async (c) => {
|
|
105
|
-
const apiKeys = c
|
|
106
|
-
|
|
107
|
-
return unavailable();
|
|
108
|
-
const user = c.get('user');
|
|
109
|
-
if (!user)
|
|
110
|
-
return signInRequired();
|
|
87
|
+
const apiKeys = requireApiKeys(c);
|
|
88
|
+
const user = requireSignedIn(c);
|
|
111
89
|
await apiKeys.removeKey('user', user.id, c.req.valid('param').id);
|
|
112
90
|
return c.body(null, 204);
|
|
113
91
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiKeyController.js","sourceRoot":"","sources":["../../../src/modules/providers/ApiKeyController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,4BAA4B,EAC5B,wBAAwB,EACxB,6BAA6B,EAC7B,wBAAwB,EACxB,6BAA6B,GAE9B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"ApiKeyController.js","sourceRoot":"","sources":["../../../src/modules/providers/ApiKeyController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersonalSubscriptionController.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/PersonalSubscriptionController.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"PersonalSubscriptionController.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/PersonalSubscriptionController.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAuB/C,wBAAgB,8BAA8B,IAAI,IAAI,CAAC,MAAM,CAAC,CAyB7D"}
|
|
@@ -2,47 +2,37 @@ import { listPersonalSubscriptionsContract, removePersonalSubscriptionContract,
|
|
|
2
2
|
import * as v from 'valibot';
|
|
3
3
|
import { buildHonoRoute } from '@toad-contracts/hono';
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
|
-
import {
|
|
5
|
+
import { requireCapability, requireUser } from '../../http/guards.js';
|
|
6
6
|
// Per-USER individual-usage subscription endpoints (Claude). Unlike the workspace
|
|
7
7
|
// vendor-credential pool, these are scoped to the signed-in user: a personal
|
|
8
8
|
// subscription is licensed for that individual only, stored DOUBLE-encrypted (a
|
|
9
9
|
// personal-password layer inside the system layer), and never shared. Mounted at the
|
|
10
10
|
// root (not under a workspace) and require a signed-in user — with auth disabled there
|
|
11
11
|
// is no individual to own a personal credential.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
/** Resolve the personal-subscription store, or refuse with a 503 naming what isn't wired. */
|
|
13
|
+
function requirePersonalSubscriptions(c) {
|
|
14
|
+
return requireCapability(c.get('container').personalSubscriptions, 'Personal subscription storage is not configured');
|
|
15
|
+
}
|
|
16
|
+
/** The signed-in caller, or a 401 wording the prompt for what this controller manages. */
|
|
17
|
+
function requireSignedIn(c) {
|
|
18
|
+
return requireUser(c, 'Sign in to manage personal subscriptions');
|
|
19
|
+
}
|
|
18
20
|
export function personalSubscriptionController() {
|
|
19
21
|
const app = new Hono();
|
|
20
22
|
buildHonoRoute(app, listPersonalSubscriptionsContract, async (c) => {
|
|
21
|
-
const personal = c
|
|
22
|
-
|
|
23
|
-
return unavailable();
|
|
24
|
-
const user = c.get('user');
|
|
25
|
-
if (!user)
|
|
26
|
-
return signInRequired();
|
|
23
|
+
const personal = requirePersonalSubscriptions(c);
|
|
24
|
+
const user = requireSignedIn(c);
|
|
27
25
|
return c.json({ subscriptions: await personal.list(user.id) }, 200);
|
|
28
26
|
});
|
|
29
27
|
buildHonoRoute(app, storePersonalSubscriptionContract, async (c) => {
|
|
30
|
-
const personal = c
|
|
31
|
-
|
|
32
|
-
return unavailable();
|
|
33
|
-
const user = c.get('user');
|
|
34
|
-
if (!user)
|
|
35
|
-
return signInRequired();
|
|
28
|
+
const personal = requirePersonalSubscriptions(c);
|
|
29
|
+
const user = requireSignedIn(c);
|
|
36
30
|
const status = await personal.store(user.id, c.req.valid('json'));
|
|
37
31
|
return c.json(status, 201);
|
|
38
32
|
});
|
|
39
33
|
buildHonoRoute(app, removePersonalSubscriptionContract, async (c) => {
|
|
40
|
-
const personal = c
|
|
41
|
-
|
|
42
|
-
return unavailable();
|
|
43
|
-
const user = c.get('user');
|
|
44
|
-
if (!user)
|
|
45
|
-
return signInRequired();
|
|
34
|
+
const personal = requirePersonalSubscriptions(c);
|
|
35
|
+
const user = requireSignedIn(c);
|
|
46
36
|
const vendor = v.parse(subscriptionVendorSchema, c.req.valid('param').vendor);
|
|
47
37
|
await personal.remove(user.id, vendor);
|
|
48
38
|
return c.body(null, 204);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersonalSubscriptionController.js","sourceRoot":"","sources":["../../../src/modules/providers/PersonalSubscriptionController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,kCAAkC,EAClC,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"PersonalSubscriptionController.js","sourceRoot":"","sources":["../../../src/modules/providers/PersonalSubscriptionController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,kCAAkC,EAClC,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAErE,kFAAkF;AAClF,6EAA6E;AAC7E,gFAAgF;AAChF,qFAAqF;AACrF,uFAAuF;AACvF,iDAAiD;AAEjD,6FAA6F;AAC7F,SAAS,4BAA4B,CAAmB,CAAa;IACnE,OAAO,iBAAiB,CACtB,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,qBAAqB,EACxC,iDAAiD,CAClD,CAAA;AACH,CAAC;AAED,0FAA0F;AAC1F,SAAS,eAAe,CAAmB,CAAa;IACtD,OAAO,WAAW,CAAC,CAAC,EAAE,0CAA0C,CAAC,CAAA;AACnE,CAAC;AAED,MAAM,UAAU,8BAA8B;IAC5C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAE9B,cAAc,CAAC,GAAG,EAAE,iCAAiC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACjE,MAAM,QAAQ,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAA;QAChD,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;QAC/B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IACrE,CAAC,CAAC,CAAA;IAEF,cAAc,CAAC,GAAG,EAAE,iCAAiC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACjE,MAAM,QAAQ,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAA;QAChD,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;QAC/B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;QACjE,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,cAAc,CAAC,GAAG,EAAE,kCAAkC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAClE,MAAM,QAAQ,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAA;QAChD,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;QAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,wBAAwB,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;QAC7E,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;QACtC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserSecretController.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/UserSecretController.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"UserSecretController.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/UserSecretController.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAuB/C,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,MAAM,CAAC,CA8CnD"}
|
|
@@ -2,35 +2,33 @@ import { getUserSecretDescriptorContract, listUserSecretsContract, removeUserSec
|
|
|
2
2
|
import * as v from 'valibot';
|
|
3
3
|
import { buildHonoRoute } from '@toad-contracts/hono';
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
|
-
import {
|
|
5
|
+
import { requireCapability, requireUser } from '../../http/guards.js';
|
|
6
6
|
// Per-USER generic secrets (a GitHub PAT today; future repository/provider tokens as
|
|
7
7
|
// new kinds). Scoped to the signed-in user — mounted at the root (not under a
|
|
8
8
|
// workspace) and require a signed-in user, like personal subscriptions / local model
|
|
9
9
|
// runners. The secret is write-only; only status metadata is returned.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
/** Resolve the per-user secret store, or refuse with a 503 naming what isn't wired. */
|
|
11
|
+
function requireUserSecrets(c) {
|
|
12
|
+
return requireCapability(c.get('container').userSecrets, 'User secret storage is not configured');
|
|
13
|
+
}
|
|
14
|
+
/** The signed-in caller, or a 401 wording the prompt for what this controller manages. */
|
|
15
|
+
function requireSignedIn(c) {
|
|
16
|
+
return requireUser(c, 'Sign in to manage your secrets');
|
|
17
|
+
}
|
|
18
|
+
/** The same 401, for a route that needs a signed-in caller but reads nothing off them. */
|
|
19
|
+
function assertSignedIn(c) {
|
|
20
|
+
requireSignedIn(c);
|
|
21
|
+
}
|
|
16
22
|
export function userSecretController() {
|
|
17
23
|
const app = new Hono();
|
|
18
24
|
buildHonoRoute(app, listUserSecretsContract, async (c) => {
|
|
19
|
-
const store = c
|
|
20
|
-
|
|
21
|
-
return unavailable();
|
|
22
|
-
const user = c.get('user');
|
|
23
|
-
if (!user)
|
|
24
|
-
return signInRequired();
|
|
25
|
+
const store = requireUserSecrets(c);
|
|
26
|
+
const user = requireSignedIn(c);
|
|
25
27
|
return c.json({ secrets: await store.list(user.id), descriptors: store.describeAll() }, 200);
|
|
26
28
|
});
|
|
27
29
|
buildHonoRoute(app, getUserSecretDescriptorContract, async (c) => {
|
|
28
|
-
const store = c
|
|
29
|
-
|
|
30
|
-
return unavailable();
|
|
31
|
-
const user = c.get('user');
|
|
32
|
-
if (!user)
|
|
33
|
-
return signInRequired();
|
|
30
|
+
const store = requireUserSecrets(c);
|
|
31
|
+
assertSignedIn(c);
|
|
34
32
|
const kind = v.parse(userSecretKindSchema, c.req.valid('param').kind);
|
|
35
33
|
const descriptor = store.describe(kind);
|
|
36
34
|
if (!descriptor)
|
|
@@ -38,22 +36,14 @@ export function userSecretController() {
|
|
|
38
36
|
return c.json(descriptor, 200);
|
|
39
37
|
});
|
|
40
38
|
buildHonoRoute(app, storeUserSecretContract, async (c) => {
|
|
41
|
-
const store = c
|
|
42
|
-
|
|
43
|
-
return unavailable();
|
|
44
|
-
const user = c.get('user');
|
|
45
|
-
if (!user)
|
|
46
|
-
return signInRequired();
|
|
39
|
+
const store = requireUserSecrets(c);
|
|
40
|
+
const user = requireSignedIn(c);
|
|
47
41
|
const kind = v.parse(userSecretKindSchema, c.req.valid('param').kind);
|
|
48
42
|
return c.json(await store.store(user.id, kind, c.req.valid('json')), 201);
|
|
49
43
|
});
|
|
50
44
|
buildHonoRoute(app, removeUserSecretContract, async (c) => {
|
|
51
|
-
const store = c
|
|
52
|
-
|
|
53
|
-
return unavailable();
|
|
54
|
-
const user = c.get('user');
|
|
55
|
-
if (!user)
|
|
56
|
-
return signInRequired();
|
|
45
|
+
const store = requireUserSecrets(c);
|
|
46
|
+
const user = requireSignedIn(c);
|
|
57
47
|
const kind = v.parse(userSecretKindSchema, c.req.valid('param').kind);
|
|
58
48
|
await store.remove(user.id, kind);
|
|
59
49
|
// Revoke the fail-closed access cache too: without their PAT the user no longer has
|
|
@@ -64,12 +54,8 @@ export function userSecretController() {
|
|
|
64
54
|
});
|
|
65
55
|
// Probe a (not-yet-saved) secret server-side so the UI can validate before save.
|
|
66
56
|
buildHonoRoute(app, testUserSecretContract, async (c) => {
|
|
67
|
-
const store = c
|
|
68
|
-
|
|
69
|
-
return unavailable();
|
|
70
|
-
const user = c.get('user');
|
|
71
|
-
if (!user)
|
|
72
|
-
return signInRequired();
|
|
57
|
+
const store = requireUserSecrets(c);
|
|
58
|
+
assertSignedIn(c);
|
|
73
59
|
const kind = v.parse(userSecretKindSchema, c.req.valid('param').kind);
|
|
74
60
|
return c.json(await store.testConnection(kind, c.req.valid('json')), 200);
|
|
75
61
|
});
|