@k2b/cloud 0.44.0 → 0.46.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 +9 -2
- package/src/_internal/app-queries.ts +73 -0
- package/src/_internal/capabilities.ts +137 -9
- package/src/_internal/define-app.ts +2 -0
- package/src/_internal/registry-validation.ts +17 -4
- package/src/_internal/registry.ts +32 -4
- package/src/_internal/resource-principals.ts +36 -0
- package/src/access/GroupCoverage.tsx +20 -5
- package/src/access/PermissionEditor.tsx +11 -2
- package/src/access/PrincipalAvatar.tsx +30 -21
- package/src/access/messages.ts +4 -4
- package/src/account/EntitySearch.tsx +12 -0
- package/src/ai/capabilities.ts +4 -2
- package/src/ai/chat/map-messages.ts +270 -0
- package/src/ai/chat/map-notebook.browser-harness.tsx +28 -0
- package/src/ai/chat/map-notebook.tsx +301 -0
- package/src/ai/chat/map-widget.browser-harness.tsx +71 -0
- package/src/ai/chat/map-widget.css +107 -0
- package/src/ai/chat/map-widget.tsx +1279 -0
- package/src/ai/chat/message-utils.ts +1 -0
- package/src/ai/chat/tool-names.ts +2 -0
- package/src/ai/chat/turn-layout.ts +2 -1
- package/src/ai/chat/turn-view.tsx +17 -1
- package/src/ai/default-tools.ts +3 -0
- package/src/ai/dictation-runtime.ts +6 -2
- package/src/ai/executor.ts +22 -4
- package/src/ai/index.ts +1 -0
- package/src/ai/map-contracts.ts +209 -0
- package/src/ai/map-execution.ts +14 -0
- package/src/ai/map-notebook-save.ts +276 -0
- package/src/ai/map-notebook.ts +32 -0
- package/src/ai/map-opening-hours.ts +40 -0
- package/src/ai/map-routes.ts +84 -0
- package/src/ai/map-service.ts +288 -0
- package/src/ai/map-store.ts +137 -0
- package/src/ai/map-tool.ts +73 -0
- package/src/ai/migrate.ts +3 -0
- package/src/ai/project-tool.ts +4 -4
- package/src/ai/projects-authorization.ts +53 -0
- package/src/ai/projects-routes.ts +56 -46
- package/src/ai/projects.ts +100 -79
- package/src/ai/protocol.ts +3 -1
- package/src/ai/recent-resources.ts +3 -3
- package/src/ai/routes.ts +32 -30
- 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 +19 -6
- package/src/ai/tools.ts +14 -0
- package/src/ai/types.ts +3 -0
- package/src/api/accounts-entities.ts +6 -3
- package/src/api/admin-ai-skills.ts +4 -1
- package/src/api/auth.ts +9 -2
- package/src/api/capabilities.ts +90 -12
- package/src/api/mcp.ts +4 -2
- package/src/browser/notifications.ts +25 -8
- 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/discussion-providers.ts +99 -0
- package/src/capabilities/executions.ts +2 -2
- package/src/capabilities/migrate.ts +10 -1
- package/src/capabilities/resource-readers.ts +58 -0
- package/src/capabilities/server-invoke.ts +23 -13
- package/src/capabilities/server.ts +17 -6
- package/src/capabilities/testing.ts +13 -0
- package/src/contracts/capabilities.ts +137 -4
- package/src/contracts/discussions.ts +91 -0
- package/src/contracts/geo-document.ts +60 -0
- package/src/contracts/geo-snapshot.ts +86 -0
- package/src/contracts/geo.ts +14 -0
- package/src/contracts/index.ts +2 -0
- package/src/contracts/outgoing-mail.ts +1 -1
- package/src/contracts/resource-types.ts +21 -0
- package/src/contracts/shared.ts +2 -1
- package/src/geo/AddressAutocomplete.tsx +213 -0
- package/src/geo/messages.ts +29 -0
- package/src/geo/navigation.ts +25 -0
- package/src/geo/ui.ts +2 -0
- package/src/server/api/respond.ts +10 -2
- package/src/server/index.ts +1 -0
- package/src/server/services/access.ts +23 -10
- package/src/server/services/index.ts +1 -0
- package/src/services/accounts/app.ts +56 -17
- package/src/services/accounts/entities.ts +36 -16
- package/src/services/accounts/group-sql.ts +23 -0
- package/src/services/accounts/groups.ts +26 -17
- package/src/services/accounts/identities.ts +8 -1
- package/src/services/accounts/identity-reconciliation.ts +3 -1
- package/src/services/accounts/local-groups.ts +141 -27
- package/src/services/accounts/machine-group-management.ts +94 -0
- package/src/services/accounts/users.ts +38 -8
- package/src/services/geo/cache.ts +2 -1
- package/src/services/geo/geoapify.ts +3 -0
- package/src/services/identity/invocation-token.ts +110 -0
- package/src/services/mandates/index.ts +2 -2
- package/src/services/mandates/policy.ts +1 -0
- package/src/services/pdf/geo-snapshot.ts +107 -0
- package/src/services/pdf/index.ts +2 -0
- package/src/services/session/index.ts +12 -3
- package/src/shared/email-html.ts +1 -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 +428 -77
- 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/types.ts +24 -5
- package/src/ssr/AdminArea.tsx +2 -2
- package/src/ssr/AdminLayout.tsx +1 -1
- package/src/ssr/AdminSidebar.tsx +1 -1
- package/src/ssr/AppLaunchpadPanel.tsx +1 -1
- package/src/ssr/CloudShell.island.tsx +19 -3
- package/src/ssr/Layout.tsx +1 -1
- package/src/ssr/MobileProfileActions.tsx +2 -2
- package/src/ssr/ProfilePreferences.tsx +2 -1
- package/src/ssr/__snapshots__/Layout.unchanged.render.test.tsx.snap +3 -3
- package/src/ssr/admin-navigation.ts +1 -11
- package/src/ssr/app-launchpad.tsx +6 -1
- package/src/ssr/platform-messages.ts +2 -0
- package/src/ssr/profile-actions.ts +3 -6
- package/src/ssr/shell-data.tsx +1 -1
- package/src/styles/global.css +2 -0
- package/src/workflows/language/expressions.ts +3 -2
- package/src/workflows/runtime/executor.ts +2 -1
|
@@ -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";
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
type AiProjectReference,
|
|
23
24
|
aiProjects,
|
|
24
25
|
} from "./projects";
|
|
26
|
+
import { AiResourceCredentialError } from "./projects-authorization";
|
|
25
27
|
|
|
26
28
|
const ProjectFieldsSchema = z.object({
|
|
27
29
|
name: z.string().trim().min(1).max(AI_PROJECT_NAME_MAX_CHARS),
|
|
@@ -31,7 +33,13 @@ const ProjectFieldsSchema = z.object({
|
|
|
31
33
|
defaultModel: AiModelRequestSchema.nullable().optional(),
|
|
32
34
|
});
|
|
33
35
|
|
|
34
|
-
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.");
|
|
35
43
|
const ProjectAccessSchema = z.object({ principal: AuthenticatedPrincipalSchema, permission: z.enum(["read", "write", "admin"]) });
|
|
36
44
|
const ProjectAccessUpdateSchema = z.object({ permission: z.enum(["read", "write", "admin"]) });
|
|
37
45
|
const KnowledgeSchema = z.object({
|
|
@@ -65,6 +73,11 @@ const publicReference = (reference: AiProjectReference, projectId: string): AiPr
|
|
|
65
73
|
projectId,
|
|
66
74
|
});
|
|
67
75
|
|
|
76
|
+
const resourceSubject = (c: Context<AuthContext>) => ({
|
|
77
|
+
actor: c.get("actor"),
|
|
78
|
+
accessSubject: c.get("accessSubject"),
|
|
79
|
+
});
|
|
80
|
+
|
|
68
81
|
type AiProjectsRouteDependencies = {
|
|
69
82
|
limit?: MiddlewareHandler<AuthContext>;
|
|
70
83
|
authenticate?: MiddlewareHandler<AuthContext>;
|
|
@@ -73,56 +86,54 @@ type AiProjectsRouteDependencies = {
|
|
|
73
86
|
|
|
74
87
|
const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =>
|
|
75
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
|
+
})
|
|
76
94
|
// The list combines projects from separate grants; the writer of one can rename it next to another project's instructions.
|
|
77
95
|
.use("*", noTransform())
|
|
78
96
|
.use(dependencies.limit ?? rateLimit())
|
|
79
97
|
.use("*", dependencies.authenticate ?? auth.requireRole("authenticated"))
|
|
80
|
-
.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) })))
|
|
81
99
|
.post("/", dependencies.authenticate ?? auth.requireRole("authenticated"), v("json", ProjectFieldsSchema), async (c) =>
|
|
82
100
|
respond(
|
|
83
101
|
c,
|
|
84
102
|
ok({
|
|
85
|
-
project: publicProject(await aiProjects.create({ subject: c
|
|
103
|
+
project: publicProject(await aiProjects.create({ subject: resourceSubject(c), ...c.req.valid("json") })),
|
|
86
104
|
}),
|
|
87
105
|
201,
|
|
88
106
|
),
|
|
89
107
|
)
|
|
90
108
|
.get("/:projectId", async (c) => {
|
|
91
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
109
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
92
110
|
return project ? respond(c, ok({ project: publicProject(project) })) : notFound(c);
|
|
93
111
|
})
|
|
94
112
|
.patch("/:projectId", v("json", UpdateProjectSchema), async (c) => {
|
|
95
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
113
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
96
114
|
if (!project) return notFound(c);
|
|
97
|
-
const updated = await aiProjects.update(project.id, c
|
|
115
|
+
const updated = await aiProjects.update(project.id, resourceSubject(c), c.req.valid("json"));
|
|
98
116
|
return updated ? respond(c, ok({ project: publicProject(updated) })) : notFound(c);
|
|
99
117
|
})
|
|
100
118
|
.delete("/:projectId", async (c) => {
|
|
101
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
102
|
-
return project && (await aiProjects.delete(project.id, c
|
|
103
|
-
? respond(c, ok({ deleted: true }))
|
|
104
|
-
: 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);
|
|
105
121
|
})
|
|
106
122
|
.get("/:projectId/access", async (c) => {
|
|
107
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
108
|
-
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;
|
|
109
125
|
return access ? respond(c, ok({ access })) : notFound(c);
|
|
110
126
|
})
|
|
111
127
|
.post("/:projectId/access", v("json", ProjectAccessSchema), async (c) => {
|
|
112
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
113
|
-
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;
|
|
114
130
|
return access ? respond(c, ok({ access }), 201) : notFound(c);
|
|
115
131
|
})
|
|
116
132
|
.patch("/:projectId/access/:accessId", v("json", ProjectAccessUpdateSchema), async (c) => {
|
|
117
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
133
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "admin");
|
|
118
134
|
try {
|
|
119
135
|
return project &&
|
|
120
|
-
(await aiProjects.updateAccess(
|
|
121
|
-
project.id,
|
|
122
|
-
c.req.param("accessId")!,
|
|
123
|
-
c.get("accessSubject") ?? null,
|
|
124
|
-
c.req.valid("json").permission,
|
|
125
|
-
))
|
|
136
|
+
(await aiProjects.updateAccess(project.id, c.req.param("accessId")!, resourceSubject(c), c.req.valid("json").permission))
|
|
126
137
|
? respond(c, ok({ updated: true }))
|
|
127
138
|
: notFound(c, "Access entry");
|
|
128
139
|
} catch (error) {
|
|
@@ -131,9 +142,9 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
131
142
|
}
|
|
132
143
|
})
|
|
133
144
|
.delete("/:projectId/access/:accessId", async (c) => {
|
|
134
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
145
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "admin");
|
|
135
146
|
try {
|
|
136
|
-
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)))
|
|
137
148
|
? respond(c, ok({ deleted: true }))
|
|
138
149
|
: notFound(c, "Access entry");
|
|
139
150
|
} catch (error) {
|
|
@@ -142,51 +153,50 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
142
153
|
}
|
|
143
154
|
})
|
|
144
155
|
.get("/:projectId/knowledge", v("query", KnowledgeQuerySchema), async (c) => {
|
|
145
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
156
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
146
157
|
if (!project) return notFound(c);
|
|
147
158
|
return respond(
|
|
148
159
|
c,
|
|
149
160
|
ok({
|
|
150
|
-
knowledge: (await aiProjects.listKnowledge(project.id, c
|
|
161
|
+
knowledge: (await aiProjects.listKnowledge(project.id, resourceSubject(c), c.req.valid("query").q)).map((item) =>
|
|
151
162
|
publicKnowledge(item, project.shortId),
|
|
152
163
|
),
|
|
153
164
|
}),
|
|
154
165
|
);
|
|
155
166
|
})
|
|
156
167
|
.post("/:projectId/knowledge", v("json", KnowledgeSchema), async (c) => {
|
|
157
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
158
|
-
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;
|
|
159
170
|
return knowledge ? respond(c, ok({ knowledge: publicKnowledge(knowledge, project!.shortId) }), 201) : notFound(c);
|
|
160
171
|
})
|
|
161
172
|
.patch("/:projectId/knowledge/:knowledgeId", v("json", UpdateKnowledgeSchema), async (c) => {
|
|
162
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
173
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
163
174
|
const knowledge =
|
|
164
|
-
project &&
|
|
165
|
-
(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")));
|
|
166
176
|
return knowledge ? respond(c, ok({ knowledge: publicKnowledge(knowledge, project!.shortId) })) : notFound(c, "Knowledge entry");
|
|
167
177
|
})
|
|
168
178
|
.delete("/:projectId/knowledge/:knowledgeId", async (c) => {
|
|
169
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
170
|
-
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)))
|
|
171
181
|
? respond(c, ok({ deleted: true }))
|
|
172
182
|
: notFound(c, "Knowledge entry");
|
|
173
183
|
})
|
|
174
184
|
.get("/:projectId/files", async (c) => {
|
|
175
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
185
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
176
186
|
if (!project) return notFound(c);
|
|
177
187
|
return respond(
|
|
178
188
|
c,
|
|
179
189
|
ok({
|
|
180
|
-
files: (await aiProjects.listFiles(project.id, c
|
|
190
|
+
files: (await aiProjects.listFiles(project.id, resourceSubject(c))).map((file) => publicFile(file, project.shortId)),
|
|
181
191
|
}),
|
|
182
192
|
);
|
|
183
193
|
})
|
|
184
194
|
.post("/:projectId/files", v("json", ProjectFileSchema), async (c) => {
|
|
185
195
|
const body = c.req.valid("json");
|
|
186
196
|
try {
|
|
187
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
197
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c), "write");
|
|
188
198
|
const file = project
|
|
189
|
-
? await aiProjects.writeFile(project.id, c
|
|
199
|
+
? await aiProjects.writeFile(project.id, resourceSubject(c), {
|
|
190
200
|
path: body.path,
|
|
191
201
|
mediaType: body.mediaType,
|
|
192
202
|
bytes: decodeAiFileContent(body.content, body.encoding),
|
|
@@ -200,8 +210,8 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
200
210
|
}
|
|
201
211
|
})
|
|
202
212
|
.get("/:projectId/files/:fileId", async (c) => {
|
|
203
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
204
|
-
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;
|
|
205
215
|
if (!file) return notFound(c, "Project file");
|
|
206
216
|
return respond(
|
|
207
217
|
c,
|
|
@@ -213,18 +223,18 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
213
223
|
);
|
|
214
224
|
})
|
|
215
225
|
.delete("/:projectId/files/:fileId", async (c) => {
|
|
216
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
217
|
-
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)))
|
|
218
228
|
? respond(c, ok({ deleted: true }))
|
|
219
229
|
: notFound(c, "Project file");
|
|
220
230
|
})
|
|
221
231
|
.get("/:projectId/references", async (c) => {
|
|
222
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
232
|
+
const project = await aiProjects.getByShortId(c.req.param("projectId")!, resourceSubject(c));
|
|
223
233
|
if (!project) return notFound(c);
|
|
224
234
|
return respond(
|
|
225
235
|
c,
|
|
226
236
|
ok({
|
|
227
|
-
references: (await aiProjects.listReferences(project.id, c
|
|
237
|
+
references: (await aiProjects.listReferences(project.id, resourceSubject(c))).map((reference) =>
|
|
228
238
|
publicReference(reference, project.shortId),
|
|
229
239
|
),
|
|
230
240
|
}),
|
|
@@ -232,7 +242,7 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
232
242
|
})
|
|
233
243
|
.post("/:projectId/references", v("json", ReferenceSchema), async (c) => {
|
|
234
244
|
const body = c.req.valid("json");
|
|
235
|
-
const subject = c
|
|
245
|
+
const subject = resourceSubject(c);
|
|
236
246
|
const project = await aiProjects.getByShortId(c.req.param("projectId")!, subject, "write");
|
|
237
247
|
if (!project) return notFound(c);
|
|
238
248
|
let entry: Awaited<ReturnType<typeof getCapability>>;
|
|
@@ -248,8 +258,8 @@ const buildAiProjectsRoutes = (dependencies: AiProjectsRouteDependencies = {}) =
|
|
|
248
258
|
return reference ? respond(c, ok({ reference: publicReference(reference, project.shortId) }), 201) : notFound(c);
|
|
249
259
|
})
|
|
250
260
|
.delete("/:projectId/references/:referenceId", async (c) => {
|
|
251
|
-
const project = await aiProjects.getByShortId(c.req.param("projectId")!, c
|
|
252
|
-
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)))
|
|
253
263
|
? respond(c, ok({ deleted: true }))
|
|
254
264
|
: notFound(c, "Project reference");
|
|
255
265
|
});
|