@k2b/cloud 0.43.0 → 0.45.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/package.json +11 -2
- package/src/_internal/app-access-request.ts +13 -0
- package/src/_internal/app-access-resources.ts +141 -0
- package/src/_internal/app-event-catalog.ts +40 -0
- package/src/_internal/app-event-schemas.ts +127 -0
- package/src/_internal/application-package.ts +40 -0
- package/src/_internal/built-in-app-ids.json +27 -0
- package/src/_internal/capabilities.ts +158 -12
- package/src/_internal/capability-origin.ts +4 -0
- package/src/_internal/capability-streams.ts +7 -5
- package/src/_internal/define-app.ts +57 -6
- package/src/_internal/object-store-area.ts +9 -0
- package/src/_internal/object-store-config.ts +101 -0
- package/src/_internal/object-store-key.ts +14 -0
- package/src/_internal/process-identity.ts +7 -2
- package/src/_internal/registry-validation.ts +11 -1
- package/src/_internal/registry.ts +8 -1
- package/src/_internal/runtime-context.ts +8 -1
- package/src/access/AppAccessEditor.tsx +2 -0
- package/src/access/GroupCoverage.tsx +20 -5
- package/src/access/PermissionEditor.tsx +20 -5
- package/src/access/PrincipalAvatar.tsx +30 -21
- package/src/access/PrincipalPicker.tsx +14 -4
- package/src/access/ResourceApiKeys.tsx +3 -4
- package/src/access/app-access-messages.ts +6 -0
- package/src/access/messages.ts +4 -4
- package/src/account/EntitySearch.tsx +12 -0
- package/src/account/ProfilePictureDialog.tsx +699 -0
- package/src/account/profile-picture-messages.ts +269 -0
- package/src/account/ui.ts +7 -0
- package/src/ai/admin.ts +3 -0
- package/src/ai/app-frame.ts +12 -0
- package/src/ai/application-tasks.ts +101 -0
- package/src/ai/assistant-models.ts +126 -64
- package/src/ai/capabilities.ts +19 -4
- package/src/ai/chart-block.ts +63 -30
- package/src/ai/chat/chart-block.tsx +12 -3
- package/src/ai/chat/composer-adapter.ts +8 -7
- package/src/ai/chat/message-actions.tsx +1 -1
- package/src/ai/chat/message-utils.ts +2 -2
- package/src/ai/chat/presentation.tsx +22 -1
- package/src/ai/chat-quotas.ts +5 -4
- package/src/ai/chat-tasks.ts +2 -2
- package/src/ai/client/controller.ts +11 -10
- package/src/ai/client/projection.ts +3 -3
- package/src/ai/compaction.ts +3 -3
- package/src/ai/credentials.ts +13 -114
- package/src/ai/default-tool-contracts.ts +4 -3
- package/src/ai/dictation-runtime.ts +10 -6
- package/src/ai/enrich.ts +2 -2
- package/src/ai/executor.ts +40 -25
- package/src/ai/http.ts +17 -29
- package/src/ai/index.ts +12 -5
- package/src/ai/inference-calls.ts +5 -4
- package/src/ai/maintenance.ts +1 -1
- package/src/ai/memory-learning-runs.ts +5 -5
- package/src/ai/memory-learning.ts +3 -3
- package/src/ai/message-queue.ts +1 -2
- package/src/ai/migrate.ts +75 -42
- package/src/ai/model-access-migrate.ts +3 -17
- package/src/ai/model-access.ts +44 -85
- package/src/ai/model-card.tsx +134 -0
- package/src/ai/model-catalog.ts +359 -0
- package/src/ai/model-chooser-messages.ts +88 -0
- package/src/ai/model-chooser.tsx +577 -0
- package/src/ai/model-delete.ts +234 -0
- package/src/ai/model-fixture.ts +39 -0
- package/src/ai/model-icon.tsx +36 -0
- package/src/ai/model-overview.ts +53 -0
- package/src/ai/model-usage.ts +45 -0
- package/src/ai/openai-api-messages.ts +0 -4
- package/src/ai/openai-api.ts +26 -9
- package/src/ai/personal-agent.ts +1 -1
- package/src/ai/prefs.ts +12 -10
- package/src/ai/project-tool.ts +4 -4
- package/src/ai/projects-authorization.ts +53 -0
- package/src/ai/projects-routes.ts +58 -47
- package/src/ai/projects.ts +110 -88
- package/src/ai/protocol.ts +2 -2
- package/src/ai/provider-connections.ts +161 -0
- package/src/ai/provider-errors.ts +55 -6
- package/src/ai/provider-fetch.ts +4 -0
- package/src/ai/provider.ts +1 -1
- package/src/ai/quota-limits.ts +36 -0
- package/src/ai/quota-provider.ts +4 -2
- package/src/ai/quota-report.ts +7 -4
- package/src/ai/quotas.ts +19 -8
- package/src/ai/recent-resources.ts +9 -3
- package/src/ai/request-headers.ts +14 -87
- package/src/ai/resource-refs.ts +6 -2
- package/src/ai/routes.ts +47 -48
- package/src/ai/runtime.ts +50 -22
- package/src/ai/settings.ts +93 -580
- package/src/ai/skill-tool.ts +4 -4
- package/src/ai/skills-routes.ts +27 -26
- package/src/ai/skills.ts +120 -81
- package/src/ai/store.ts +45 -23
- package/src/ai/stream.ts +1 -1
- package/src/ai/structured-runs.ts +2 -2
- package/src/ai/structured.ts +21 -44
- package/src/ai/task-contracts.ts +25 -5
- package/src/ai/task-execution.ts +15 -6
- package/src/ai/task-model.ts +9 -0
- package/src/ai/transcription.ts +27 -22
- package/src/ai/types.ts +50 -62
- package/src/ai/ui.tsx +13 -0
- package/src/ai/usage.ts +8 -8
- package/src/ai/validate.ts +8 -7
- package/src/ai/view-block.ts +2 -2
- package/src/api/accounts-entities.ts +22 -3
- package/src/api/admin-ai-quotas.ts +34 -56
- package/src/api/admin-ai-skills.ts +4 -1
- package/src/api/admin-ai-usage.ts +1 -1
- package/src/api/admin-ai.ts +173 -0
- package/src/api/admin-core-settings.ts +68 -244
- package/src/api/app-approval.ts +3 -1
- package/src/api/app-event-delivery.ts +51 -0
- package/src/api/app-events.ts +123 -0
- package/src/api/app-resource-access.ts +48 -0
- package/src/api/auth/account-mismatch.ts +24 -0
- package/src/api/auth.ts +35 -5
- package/src/api/capabilities.ts +28 -4
- package/src/api/index.ts +7 -1
- package/src/api/mcp.ts +175 -2
- package/src/api/me.ts +6 -4
- package/src/api/pwa-phone.ts +75 -26
- package/src/api/pwa.ts +34 -8
- package/src/api/resource-links.ts +83 -6
- package/src/api/resource-resolve.ts +50 -0
- package/src/api/search/schemas.ts +3 -1
- package/src/api/search.ts +9 -7
- package/src/app-pwa/contracts.ts +4 -0
- package/src/app-pwa/core-query-error.ts +20 -0
- package/src/app-pwa/index.ts +1 -0
- package/src/app-pwa/service.ts +91 -0
- package/src/app-pwa/transport.ts +22 -0
- package/src/approvals/messages.ts +2 -2
- package/src/browser/cloud-id.ts +86 -0
- package/src/browser/resource-clipboard.ts +4 -0
- package/src/browser/resource-links.ts +52 -0
- package/src/browser/session.ts +39 -0
- package/src/browser/shared-text-history-validation.ts +151 -0
- package/src/browser/shared-text-history.ts +464 -0
- package/src/browser/shared-text-offline-authorized.ts +29 -0
- package/src/browser/shared-text-offline.ts +351 -0
- package/src/browser/shared-text-provider.ts +714 -0
- package/src/browser/shared-text-table-contract.ts +150 -0
- package/src/browser/shared-text.ts +19 -0
- package/src/capabilities/server-invoke.ts +2 -11
- package/src/capabilities/testing.ts +5 -2
- package/src/cli/access.ts +6 -5
- package/src/cli/admin/ai-models.ts +199 -0
- package/src/cli/admin/ai-quotas.ts +6 -102
- package/src/cli/admin/ai-usage.ts +4 -4
- package/src/cli/admin/app-credentials.ts +5 -3
- package/src/cli/admin/index.ts +5 -2
- package/src/cli/apps.ts +89 -26
- package/src/cli/capabilities.ts +22 -1
- package/src/cli/events.ts +320 -0
- package/src/config/env.ts +40 -0
- package/src/contracts/app-access.ts +26 -2
- package/src/contracts/app-details.ts +89 -0
- package/src/contracts/app-events.ts +51 -0
- package/src/contracts/app.ts +21 -5
- package/src/contracts/capabilities.ts +143 -3
- package/src/contracts/index.ts +2 -0
- package/src/contracts/notification-types.ts +36 -9
- package/src/contracts/pwa.ts +17 -1
- package/src/contracts/registry.ts +6 -0
- package/src/contracts/resource-clipboard.ts +35 -0
- package/src/contracts/resource-pages.ts +140 -0
- package/src/contracts/resource-resolution.ts +13 -0
- package/src/contracts/shared.ts +6 -1
- package/src/contracts/user-notifications.ts +2 -0
- package/src/events/app-event-delivery.ts +100 -0
- package/src/events/app-events.testing.ts +65 -0
- package/src/events/app-events.ts +134 -0
- package/src/events/core-user-created.ts +24 -0
- package/src/events/index.ts +9 -0
- package/src/events/testing.ts +2 -0
- package/src/index.ts +1 -1
- package/src/server/api/respond.ts +17 -4
- package/src/server/index.ts +2 -0
- package/src/server/middleware/app-access.ts +1 -1
- package/src/server/middleware/auth.ts +21 -7
- package/src/server/middleware/index.ts +1 -0
- package/src/server/middleware/invocation.ts +2 -0
- package/src/server/public-storage.ts +106 -0
- package/src/server/services/access.ts +31 -10
- package/src/server/services/index.ts +1 -0
- package/src/services/accounts/app.ts +36 -13
- package/src/services/accounts/entities.ts +43 -19
- package/src/services/accounts/group-sql.ts +23 -0
- package/src/services/accounts/groups.ts +19 -14
- package/src/services/accounts/identities.ts +70 -11
- package/src/services/accounts/identity-reconciliation.ts +3 -1
- package/src/services/accounts/local-groups.ts +69 -4
- package/src/services/accounts/users.ts +45 -14
- package/src/services/app-access.ts +25 -7
- package/src/services/app-details.ts +224 -0
- package/src/services/app-discovery.ts +2 -1
- package/src/services/app-event-shapes.ts +139 -0
- package/src/services/app-events/accept.ts +116 -0
- package/src/services/app-events/admin.ts +250 -0
- package/src/services/app-events/declarations.ts +187 -0
- package/src/services/app-events/deliver.ts +218 -0
- package/src/services/app-events.ts +92 -0
- package/src/services/config-conflict.ts +11 -0
- package/src/services/core-user-events.ts +1 -0
- package/src/services/freeipa-config.ts +9 -0
- package/src/services/geo/ledger.ts +28 -10
- package/src/services/geo/service.ts +43 -24
- package/src/services/identity/core-origin.ts +12 -0
- package/src/services/identity/invocation-actor.ts +20 -2
- package/src/services/identity/invocation-authority.ts +4 -0
- package/src/services/identity/invocation-token.ts +238 -56
- package/src/services/identity/issue-invocation.ts +6 -1
- package/src/services/image-metadata.ts +65 -1
- package/src/services/index.ts +13 -1
- package/src/services/ipa/sync.ts +6 -2
- package/src/services/ipa/users.ts +4 -1
- package/src/services/mandates/index.ts +2 -2
- package/src/services/mandates/policy.ts +20 -12
- package/src/services/notifications/browser.ts +4 -0
- package/src/services/notifications/catalog.ts +5 -2
- package/src/services/notifications/platform.ts +7 -2
- package/src/services/notifications/user.ts +18 -7
- package/src/services/oauth-tokens.ts +28 -2
- package/src/services/object-store.ts +217 -0
- package/src/services/providers/local/users.ts +5 -0
- package/src/services/pwa-devices.ts +147 -37
- package/src/services/session/index.ts +26 -3
- package/src/services/settings/core-settings.ts +71 -43
- package/src/services/settings/index.ts +8 -0
- package/src/services/settings/versions.ts +26 -0
- package/src/shared/ai-models.ts +274 -0
- package/src/shared/ai-quotas.ts +2 -2
- package/src/shared/ai-usage.ts +2 -2
- package/src/shared/email-html.ts +1 -0
- package/src/shared/index.ts +2 -0
- package/src/shared/markdown/extensions/katex.ts +8 -1
- package/src/shared/markdown/extensions/tables.ts +14 -1
- package/src/shared/markdown/index.ts +22 -11
- package/src/shared-text/anchors.ts +29 -0
- package/src/shared-text/awareness.ts +87 -0
- package/src/shared-text/changes.ts +27 -0
- package/src/shared-text/documents.ts +433 -65
- package/src/shared-text/events.ts +12 -2
- package/src/shared-text/index.ts +16 -1
- package/src/shared-text/log.ts +24 -5
- package/src/shared-text/snapshots.ts +69 -23
- package/src/shared-text/structural-history.ts +377 -0
- package/src/shared-text/table-actions.ts +432 -0
- package/src/shared-text/text-diff.ts +75 -0
- package/src/shared-text/types.ts +24 -5
- package/src/ssr/AdminArea.tsx +131 -0
- package/src/ssr/AdminLayout.tsx +9 -3
- package/src/ssr/AdminSidebar.tsx +7 -7
- package/src/ssr/AppAccessDenied.tsx +2 -0
- package/src/ssr/AppBadge.tsx +14 -0
- package/src/ssr/AppLaunchpadPanel.tsx +2 -2
- package/src/ssr/CloudShell.island.tsx +44 -7
- package/src/ssr/Layout.tsx +9 -7
- package/src/ssr/MobileProfileActions.tsx +2 -2
- package/src/ssr/ProfilePreferences.tsx +2 -1
- package/src/ssr/PwaLayout.tsx +16 -1
- package/src/ssr/PwaPartCount.island.tsx +23 -0
- package/src/ssr/SettingsSaveOutcome.tsx +58 -0
- package/src/ssr/SettingsSaveStatus.island.tsx +16 -0
- package/src/ssr/__snapshots__/Layout.unchanged.render.test.tsx.snap +3 -3
- package/src/ssr/admin-active-link.ts +16 -0
- package/src/ssr/admin-navigation.ts +26 -31
- package/src/ssr/app-badges.ts +31 -7
- package/src/ssr/app-launchpad.tsx +6 -1
- package/src/ssr/index.ts +8 -0
- package/src/ssr/page-trail-runtime.ts +3 -1
- package/src/ssr/platform-messages.ts +11 -1
- package/src/ssr/profile-actions.ts +3 -6
- package/src/ssr/pwa-messages.ts +2 -2
- package/src/ssr/rail-navigation.ts +5 -1
- package/src/ssr/settings-draft.ts +153 -0
- package/src/ssr/shell-data.tsx +3 -1
- package/src/styles/global.css +1 -0
- package/src/styles/profile-picture.css +270 -0
- package/src/styles/utilities-navigation.css +6 -0
- package/src/workflows/ai/policy.ts +49 -0
- package/src/workflows/ai/runtime.ts +131 -21
- package/src/workflows/ai/store.ts +283 -35
- package/src/workflows/ai/types.ts +8 -2
- package/src/workflows/ai-actions.ts +148 -120
- package/src/workflows/authoring.ts +31 -0
- package/src/workflows/contracts.ts +1 -0
- package/src/workflows/definition.ts +2 -0
- package/src/workflows/editor.ts +15 -0
- package/src/workflows/index.ts +2 -1
- package/src/workflows/language/compiler.ts +34 -3
- package/src/workflows/language/expressions.ts +3 -2
- package/src/workflows/runtime/executor.ts +134 -34
- package/src/workflows/runtime/index.ts +2 -0
- package/src/workflows/runtime/ports.ts +5 -1
- package/src/workflows/store/actions.ts +1 -1
- package/src/workflows/store/definitions.ts +5 -0
- package/src/workflows/store/runs.ts +5 -3
- package/src/workflows/store/worker.ts +7 -2
- package/src/ai/model-pricing.ts +0 -43
- package/src/ai/model-request-settings.ts +0 -98
- package/src/ai/settings-messages.ts +0 -129
- package/src/shared/ai-model-request-settings.ts +0 -21
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { AccessSubject, RequestActor } from "../server";
|
|
2
|
+
import { hasPermission, type PermissionLevel } from "../server/services/access";
|
|
3
|
+
|
|
4
|
+
/** Resource operations retain the actor's credential alongside the grant subject. */
|
|
5
|
+
export type AiResourceContext = { actor: RequestActor; accessSubject: AccessSubject };
|
|
6
|
+
|
|
7
|
+
export const aiResourceAccessSubject = (subject: AiResourceContext | null): AccessSubject | null => subject?.accessSubject ?? null;
|
|
8
|
+
|
|
9
|
+
/** Projects and Skills have no supported resource-bound credential contract. */
|
|
10
|
+
export const aiResourcePermissionCap = (subject: AiResourceContext | null): PermissionLevel => {
|
|
11
|
+
if (!subject?.actor || !subject.accessSubject) return "none";
|
|
12
|
+
const { actor, accessSubject } = subject;
|
|
13
|
+
if (actor.kind === "user") {
|
|
14
|
+
return accessSubject.type === "user" && accessSubject.userId === actor.user.id ? "admin" : "none";
|
|
15
|
+
}
|
|
16
|
+
if (actor.serviceAccount.kind === "resource_bound") return "none";
|
|
17
|
+
if (actor.delegatedUser) {
|
|
18
|
+
return actor.serviceAccount.kind === "user_delegated" &&
|
|
19
|
+
accessSubject.type === "user" &&
|
|
20
|
+
accessSubject.userId === actor.delegatedUser.id
|
|
21
|
+
? "admin"
|
|
22
|
+
: "none";
|
|
23
|
+
}
|
|
24
|
+
if (
|
|
25
|
+
(actor.serviceAccount.kind !== "standalone" && actor.serviceAccount.kind !== "agent") ||
|
|
26
|
+
accessSubject.type !== "service_account" ||
|
|
27
|
+
accessSubject.serviceAccountId !== actor.serviceAccount.id
|
|
28
|
+
)
|
|
29
|
+
return "none";
|
|
30
|
+
return actor.scopes.includes("admin")
|
|
31
|
+
? "admin"
|
|
32
|
+
: actor.scopes.includes("write")
|
|
33
|
+
? "write"
|
|
34
|
+
: actor.scopes.includes("read")
|
|
35
|
+
? "read"
|
|
36
|
+
: "none";
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const capAiResourcePermission = (granted: PermissionLevel, subject: AiResourceContext | null): PermissionLevel => {
|
|
40
|
+
const cap = aiResourcePermissionCap(subject);
|
|
41
|
+
return hasPermission(granted, cap) ? cap : granted;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export class AiResourceCredentialError extends Error {
|
|
45
|
+
constructor() {
|
|
46
|
+
super("The credential does not permit creating Projects or Skills.");
|
|
47
|
+
this.name = "AiResourceCredentialError";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const requireAiResourceCreation = (subject: AiResourceContext): void => {
|
|
52
|
+
if (!hasPermission(aiResourcePermissionCap(subject), "write")) throw new AiResourceCredentialError();
|
|
53
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Hono, type MiddlewareHandler } from "hono";
|
|
1
|
+
import { type Context, Hono, type MiddlewareHandler } from "hono";
|
|
2
|
+
import { HTTPException } from "hono/http-exception";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
import { getCapability } from "../_internal/registry";
|
|
4
5
|
import { CloudResourceRefSchema, cloudResourceRefAppId, resolveCapabilityResourceReader } from "../contracts/capabilities";
|
|
@@ -6,6 +7,7 @@ import { AuthenticatedPrincipalSchema } from "../contracts/shared";
|
|
|
6
7
|
import { type AuthContext, auth, err, fail, getLocale, ok, rateLimit, respond, v } from "../server";
|
|
7
8
|
import { noTransform } from "../server/middleware/no-transform";
|
|
8
9
|
import { ImageMetadataError } from "../services/image-metadata";
|
|
10
|
+
import { AiModelRequestSchema } from "../shared/ai-models";
|
|
9
11
|
import { aiChatMessages } from "./chat/messages";
|
|
10
12
|
import { decodeAiFileContent } from "./files-store";
|
|
11
13
|
import {
|
|
@@ -21,16 +23,23 @@ import {
|
|
|
21
23
|
type AiProjectReference,
|
|
22
24
|
aiProjects,
|
|
23
25
|
} from "./projects";
|
|
26
|
+
import { AiResourceCredentialError } from "./projects-authorization";
|
|
24
27
|
|
|
25
28
|
const ProjectFieldsSchema = z.object({
|
|
26
29
|
name: z.string().trim().min(1).max(AI_PROJECT_NAME_MAX_CHARS),
|
|
27
30
|
description: z.string().trim().max(AI_PROJECT_DESCRIPTION_MAX_CHARS).default(""),
|
|
28
31
|
icon: z.string().trim().min(1).max(80).default("ti ti-folders"),
|
|
29
32
|
instructions: z.string().trim().max(AI_PROJECT_INSTRUCTIONS_MAX_CHARS).default(""),
|
|
30
|
-
|
|
33
|
+
defaultModel: AiModelRequestSchema.nullable().optional(),
|
|
31
34
|
});
|
|
32
35
|
|
|
33
|
-
const UpdateProjectSchema = ProjectFieldsSchema.
|
|
36
|
+
const UpdateProjectSchema = ProjectFieldsSchema.extend({
|
|
37
|
+
description: ProjectFieldsSchema.shape.description.removeDefault(),
|
|
38
|
+
icon: ProjectFieldsSchema.shape.icon.removeDefault(),
|
|
39
|
+
instructions: ProjectFieldsSchema.shape.instructions.removeDefault(),
|
|
40
|
+
})
|
|
41
|
+
.partial()
|
|
42
|
+
.refine((input) => Object.keys(input).length > 0, "No changes supplied.");
|
|
34
43
|
const ProjectAccessSchema = z.object({ principal: AuthenticatedPrincipalSchema, permission: z.enum(["read", "write", "admin"]) });
|
|
35
44
|
const ProjectAccessUpdateSchema = z.object({ permission: z.enum(["read", "write", "admin"]) });
|
|
36
45
|
const KnowledgeSchema = z.object({
|
|
@@ -64,6 +73,11 @@ const publicReference = (reference: AiProjectReference, projectId: string): AiPr
|
|
|
64
73
|
projectId,
|
|
65
74
|
});
|
|
66
75
|
|
|
76
|
+
const resourceSubject = (c: Context<AuthContext>) => ({
|
|
77
|
+
actor: c.get("actor"),
|
|
78
|
+
accessSubject: c.get("accessSubject"),
|
|
79
|
+
});
|
|
80
|
+
|
|
67
81
|
type AiProjectsRouteDependencies = {
|
|
68
82
|
limit?: MiddlewareHandler<AuthContext>;
|
|
69
83
|
authenticate?: MiddlewareHandler<AuthContext>;
|
|
@@ -72,56 +86,54 @@ type AiProjectsRouteDependencies = {
|
|
|
72
86
|
|
|
73
87
|
const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =>
|
|
74
88
|
new Hono<AuthContext>()
|
|
89
|
+
.onError((error, c) => {
|
|
90
|
+
if (error instanceof AiResourceCredentialError) return respond(c, fail(err.forbidden(error.message)));
|
|
91
|
+
if (error instanceof HTTPException) return error.getResponse();
|
|
92
|
+
throw error;
|
|
93
|
+
})
|
|
75
94
|
// The list combines projects from separate grants; the writer of one can rename it next to another project's instructions.
|
|
76
95
|
.use("*", noTransform())
|
|
77
96
|
.use(dependencies.limit ?? rateLimit())
|
|
78
97
|
.use("*", dependencies.authenticate ?? auth.requireRole("authenticated"))
|
|
79
|
-
.get("/", async (c) => respond(c, ok({ projects: (await aiProjects.list(c
|
|
98
|
+
.get("/", async (c) => respond(c, ok({ projects: (await aiProjects.list(resourceSubject(c))).map(publicProject) })))
|
|
80
99
|
.post("/", dependencies.authenticate ?? auth.requireRole("authenticated"), v("json", ProjectFieldsSchema), async (c) =>
|
|
81
100
|
respond(
|
|
82
101
|
c,
|
|
83
102
|
ok({
|
|
84
|
-
project: publicProject(await aiProjects.create({ subject: c
|
|
103
|
+
project: publicProject(await aiProjects.create({ subject: resourceSubject(c), ...c.req.valid("json") })),
|
|
85
104
|
}),
|
|
86
105
|
201,
|
|
87
106
|
),
|
|
88
107
|
)
|
|
89
108
|
.get("/:projectId", async (c) => {
|
|
90
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
109
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
91
110
|
return project ? respond(c, ok({ project: publicProject(project) })) : notFound(c);
|
|
92
111
|
})
|
|
93
112
|
.patch("/:projectId", v("json", UpdateProjectSchema), async (c) => {
|
|
94
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
113
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
95
114
|
if (!project) return notFound(c);
|
|
96
|
-
const updated = await aiProjects.update(project.id, c
|
|
115
|
+
const updated = await aiProjects.update(project.id, resourceSubject(c), c.req.valid("json"));
|
|
97
116
|
return updated ? respond(c, ok({ project: publicProject(updated) })) : notFound(c);
|
|
98
117
|
})
|
|
99
118
|
.delete("/:projectId", async (c) => {
|
|
100
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
101
|
-
return project && (await aiProjects.delete(project.id, c
|
|
102
|
-
? respond(c, ok({ deleted: true }))
|
|
103
|
-
: notFound(c);
|
|
119
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "admin");
|
|
120
|
+
return project && (await aiProjects.delete(project.id, resourceSubject(c))) ? respond(c, ok({ deleted: true })) : notFound(c);
|
|
104
121
|
})
|
|
105
122
|
.get("/:projectId/access", async (c) => {
|
|
106
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
107
|
-
const access = project ? await aiProjects.listAccess(project.id, c
|
|
123
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "admin");
|
|
124
|
+
const access = project ? await aiProjects.listAccess(project.id, resourceSubject(c)) : null;
|
|
108
125
|
return access ? respond(c, ok({ access })) : notFound(c);
|
|
109
126
|
})
|
|
110
127
|
.post("/:projectId/access", v("json", ProjectAccessSchema), async (c) => {
|
|
111
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
112
|
-
const access = project ? await aiProjects.grantAccess(project.id, c
|
|
128
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "admin");
|
|
129
|
+
const access = project ? await aiProjects.grantAccess(project.id, resourceSubject(c), c.req.valid("json")) : null;
|
|
113
130
|
return access ? respond(c, ok({ access }), 201) : notFound(c);
|
|
114
131
|
})
|
|
115
132
|
.patch("/:projectId/access/:accessId", v("json", ProjectAccessUpdateSchema), async (c) => {
|
|
116
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
133
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "admin");
|
|
117
134
|
try {
|
|
118
135
|
return project &&
|
|
119
|
-
(await aiProjects.updateAccess(
|
|
120
|
-
project.id,
|
|
121
|
-
c.req.param("accessId")!,
|
|
122
|
-
c.get("accessSubject") ?? null,
|
|
123
|
-
c.req.valid("json").permission,
|
|
124
|
-
))
|
|
136
|
+
(await aiProjects.updateAccess(project.id, c.req.param("accessId")!, resourceSubject(c), c.req.valid("json").permission))
|
|
125
137
|
? respond(c, ok({ updated: true }))
|
|
126
138
|
: notFound(c, "Access entry");
|
|
127
139
|
} catch (error) {
|
|
@@ -130,9 +142,9 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
130
142
|
}
|
|
131
143
|
})
|
|
132
144
|
.delete("/:projectId/access/:accessId", async (c) => {
|
|
133
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
145
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "admin");
|
|
134
146
|
try {
|
|
135
|
-
return project && (await aiProjects.revokeAccess(project.id, c.req.param("accessId")!, c
|
|
147
|
+
return project && (await aiProjects.revokeAccess(project.id, c.req.param("accessId")!, resourceSubject(c)))
|
|
136
148
|
? respond(c, ok({ deleted: true }))
|
|
137
149
|
: notFound(c, "Access entry");
|
|
138
150
|
} catch (error) {
|
|
@@ -141,51 +153,50 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
141
153
|
}
|
|
142
154
|
})
|
|
143
155
|
.get("/:projectId/knowledge", v("query", KnowledgeQuerySchema), async (c) => {
|
|
144
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
156
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
145
157
|
if (!project) return notFound(c);
|
|
146
158
|
return respond(
|
|
147
159
|
c,
|
|
148
160
|
ok({
|
|
149
|
-
knowledge: (await aiProjects.listKnowledge(project.id, c
|
|
161
|
+
knowledge: (await aiProjects.listKnowledge(project.id, resourceSubject(c), c.req.valid("query").q)).map((item) =>
|
|
150
162
|
publicKnowledge(item, project.shortId),
|
|
151
163
|
),
|
|
152
164
|
}),
|
|
153
165
|
);
|
|
154
166
|
})
|
|
155
167
|
.post("/:projectId/knowledge", v("json", KnowledgeSchema), async (c) => {
|
|
156
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
157
|
-
const knowledge = project ? await aiProjects.createKnowledge(project.id, c
|
|
168
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
169
|
+
const knowledge = project ? await aiProjects.createKnowledge(project.id, resourceSubject(c), c.req.valid("json")) : null;
|
|
158
170
|
return knowledge ? respond(c, ok({ knowledge: publicKnowledge(knowledge, project!.shortId) }), 201) : notFound(c);
|
|
159
171
|
})
|
|
160
172
|
.patch("/:projectId/knowledge/:knowledgeId", v("json", UpdateKnowledgeSchema), async (c) => {
|
|
161
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
173
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
162
174
|
const knowledge =
|
|
163
|
-
project &&
|
|
164
|
-
(await aiProjects.updateKnowledge(project.id, c.req.param("knowledgeId")!, c.get("accessSubject") ?? null, c.req.valid("json")));
|
|
175
|
+
project && (await aiProjects.updateKnowledge(project.id, c.req.param("knowledgeId")!, resourceSubject(c), c.req.valid("json")));
|
|
165
176
|
return knowledge ? respond(c, ok({ knowledge: publicKnowledge(knowledge, project!.shortId) })) : notFound(c, "Knowledge entry");
|
|
166
177
|
})
|
|
167
178
|
.delete("/:projectId/knowledge/:knowledgeId", async (c) => {
|
|
168
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
169
|
-
return project && (await aiProjects.deleteKnowledge(project.id, c.req.param("knowledgeId")!, c
|
|
179
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
180
|
+
return project && (await aiProjects.deleteKnowledge(project.id, c.req.param("knowledgeId")!, resourceSubject(c)))
|
|
170
181
|
? respond(c, ok({ deleted: true }))
|
|
171
182
|
: notFound(c, "Knowledge entry");
|
|
172
183
|
})
|
|
173
184
|
.get("/:projectId/files", async (c) => {
|
|
174
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
185
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
175
186
|
if (!project) return notFound(c);
|
|
176
187
|
return respond(
|
|
177
188
|
c,
|
|
178
189
|
ok({
|
|
179
|
-
files: (await aiProjects.listFiles(project.id, c
|
|
190
|
+
files: (await aiProjects.listFiles(project.id, resourceSubject(c))).map((file) => publicFile(file, project.shortId)),
|
|
180
191
|
}),
|
|
181
192
|
);
|
|
182
193
|
})
|
|
183
194
|
.post("/:projectId/files", v("json", ProjectFileSchema), async (c) => {
|
|
184
195
|
const body = c.req.valid("json");
|
|
185
196
|
try {
|
|
186
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
197
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
187
198
|
const file = project
|
|
188
|
-
? await aiProjects.writeFile(project.id, c
|
|
199
|
+
? await aiProjects.writeFile(project.id, resourceSubject(c), {
|
|
189
200
|
path: body.path,
|
|
190
201
|
mediaType: body.mediaType,
|
|
191
202
|
bytes: decodeAiFileContent(body.content, body.encoding),
|
|
@@ -199,8 +210,8 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
199
210
|
}
|
|
200
211
|
})
|
|
201
212
|
.get("/:projectId/files/:fileId", async (c) => {
|
|
202
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
203
|
-
const file = project ? await aiProjects.readFile(project.id, c.req.param("fileId")!, c
|
|
213
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
214
|
+
const file = project ? await aiProjects.readFile(project.id, c.req.param("fileId")!, resourceSubject(c)) : null;
|
|
204
215
|
if (!file) return notFound(c, "Project file");
|
|
205
216
|
return respond(
|
|
206
217
|
c,
|
|
@@ -212,18 +223,18 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
212
223
|
);
|
|
213
224
|
})
|
|
214
225
|
.delete("/:projectId/files/:fileId", async (c) => {
|
|
215
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
216
|
-
return project && (await aiProjects.deleteFile(project.id, c.req.param("fileId")!, c
|
|
226
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
227
|
+
return project && (await aiProjects.deleteFile(project.id, c.req.param("fileId")!, resourceSubject(c)))
|
|
217
228
|
? respond(c, ok({ deleted: true }))
|
|
218
229
|
: notFound(c, "Project file");
|
|
219
230
|
})
|
|
220
231
|
.get("/:projectId/references", async (c) => {
|
|
221
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
232
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
222
233
|
if (!project) return notFound(c);
|
|
223
234
|
return respond(
|
|
224
235
|
c,
|
|
225
236
|
ok({
|
|
226
|
-
references: (await aiProjects.listReferences(project.id, c
|
|
237
|
+
references: (await aiProjects.listReferences(project.id, resourceSubject(c))).map((reference) =>
|
|
227
238
|
publicReference(reference, project.shortId),
|
|
228
239
|
),
|
|
229
240
|
}),
|
|
@@ -231,7 +242,7 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
231
242
|
})
|
|
232
243
|
.post("/:projectId/references", v("json", ReferenceSchema), async (c) => {
|
|
233
244
|
const body = c.req.valid("json");
|
|
234
|
-
const subject = c
|
|
245
|
+
const subject = resourceSubject(c);
|
|
235
246
|
const project = await aiProjects.getByShortId(c.req.param("projectId")!, subject, "write");
|
|
236
247
|
if (!project) return notFound(c);
|
|
237
248
|
let entry: Awaited<ReturnType<typeof getCapability>>;
|
|
@@ -247,8 +258,8 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
247
258
|
return reference ? respond(c, ok({ reference: publicReference(reference, project.shortId) }), 201) : notFound(c);
|
|
248
259
|
})
|
|
249
260
|
.delete("/:projectId/references/:referenceId", async (c) => {
|
|
250
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
251
|
-
return project && (await aiProjects.deleteReference(project.id, c.req.param("referenceId")!, c
|
|
261
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
262
|
+
return project && (await aiProjects.deleteReference(project.id, c.req.param("referenceId")!, resourceSubject(c)))
|
|
252
263
|
? respond(c, ok({ deleted: true }))
|
|
253
264
|
: notFound(c, "Project reference");
|
|
254
265
|
});
|