Document Clips API routes

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-07-09 20:30:47 +00:00
1 parent 7a472023be
commit 13551db2f2
2 files changed
+135

No files matched your search

@@ -20,6 +20,7 @@ const apiPrefixes: Record<string, string> = {
"auth.ts": "/api/auth",
"board-chat.ts": "/api",
"cloud-upstreams.ts": "/api",
"clips.ts": "/api",
"companies.ts": "/api/companies",
"company-skills.ts": "/api",
"costs.ts": "/api",
+134
View File
@@ -151,6 +151,19 @@ import {
remoteSecretImportSchema,
workspaceFileListQuerySchema,
workspaceFileResourceQuerySchema,
// Clips
createClipCreatorProfileSchema,
clipSharePreviewSchema,
publishClipSchema,
clipImportPreviewSchema,
clipImportApplySchema,
createClipRevisionSchema,
updateClipSchema,
createClipVoteSchema,
createClipReportSchema,
createClipCommentSchema,
createClipShowcaseSchema,
createClipImportTelemetrySchema,
} from "@paperclipai/shared";
type JsonSchema = Record<string, unknown>;
@@ -640,6 +653,14 @@ const PUBLIC_OPERATIONS = new Set([
"GET /api/invites/{token}/test-resolution",
"POST /api/invites/{token}/accept",
"POST /api/join-requests/{requestId}/claim-api-key",
"GET /api/public/clips",
"GET /api/public/clips/{slug}",
"GET /api/public/clips/{slug}/revisions/{revisionNumber}",
"GET /api/public/clips/{slug}/manifest",
"GET /api/public/clips/{slug}/revisions/{revisionNumber}/manifest",
"GET /api/public/creators/{handle}",
"POST /api/public/clips/{slug}/report",
"POST /api/public/clips/{slug}/import-telemetry",
]);
const BOARD_ONLY_PREFIXES = [
@@ -760,6 +781,14 @@ const CREATED_OPERATIONS = new Set([
"POST /api/companies/{companyId}/me/user-secrets",
"POST /api/companies/{companyId}/skills",
"POST /api/companies/{companyId}/skills/import",
"POST /api/companies/{companyId}/clips/profiles",
"POST /api/companies/{companyId}/clips/publish",
"POST /api/clips/{clipId}/revisions",
"POST /api/public/clips/{slug}/votes",
"POST /api/public/clips/{slug}/report",
"POST /api/public/clips/{slug}/comments",
"POST /api/public/clips/{slug}/showcase",
"POST /api/public/clips/{slug}/import-telemetry",
"POST /api/join-requests/{requestId}/claim-api-key",
"POST /api/admin/users/{userId}/promote-instance-admin",
"POST /api/plugins/install",
@@ -5263,6 +5292,111 @@ registerCurrentRoute({
body: updateDocumentAnnotationThreadSchema,
});
// ─── Clips ──────────────────────────────────────────────────────────────────
const clipPublicBrowseQuerySchema = z.object({
q: z.string().optional(),
type: z.string().optional(),
tag: z.string().optional(),
limit: z.string().optional(),
offset: z.string().optional(),
});
registerCurrentRoute({
method: "get",
path: "/api/public/clips",
tags: ["clips"],
summary: "List public Clips",
query: clipPublicBrowseQuerySchema,
});
for (const route of [
["get", "/api/public/clips/{slug}", "Get a public Clip"],
["get", "/api/public/clips/{slug}/revisions/{revisionNumber}", "Get an approved public Clip revision"],
["get", "/api/public/clips/{slug}/manifest", "Get the approved public Clip manifest"],
["get", "/api/public/clips/{slug}/revisions/{revisionNumber}/manifest", "Get an approved public Clip revision manifest"],
["get", "/api/public/creators/{handle}", "Get a public Clip creator profile"],
] as const) {
registerCurrentRoute({
method: route[0],
path: route[1],
tags: ["clips"],
summary: route[2],
});
}
registerCurrentRoute({
method: "post",
path: "/api/companies/{companyId}/clips/profiles",
tags: ["clips"],
summary: "Create a Clip creator profile",
body: createClipCreatorProfileSchema,
});
registerCurrentRoute({
method: "post",
path: "/api/companies/{companyId}/clips/share-preview",
tags: ["clips"],
summary: "Preview a Clip share payload",
body: clipSharePreviewSchema,
});
registerCurrentRoute({
method: "post",
path: "/api/companies/{companyId}/clips/publish",
tags: ["clips"],
summary: "Publish a Clip",
body: publishClipSchema,
});
registerCurrentRoute({
method: "post",
path: "/api/companies/{companyId}/clips/import-preview",
tags: ["clips"],
summary: "Preview a Clip import",
body: clipImportPreviewSchema,
});
registerCurrentRoute({
method: "post",
path: "/api/companies/{companyId}/clips/import",
tags: ["clips"],
summary: "Import a Clip",
body: clipImportApplySchema,
});
registerCurrentRoute({
method: "post",
path: "/api/clips/{clipId}/revisions",
tags: ["clips"],
summary: "Create a Clip revision",
body: createClipRevisionSchema,
});
registerCurrentRoute({
method: "patch",
path: "/api/clips/{clipId}",
tags: ["clips"],
summary: "Update Clip metadata",
body: updateClipSchema,
});
for (const route of [
["/api/public/clips/{slug}/votes", "Vote on a public Clip", createClipVoteSchema],
["/api/public/clips/{slug}/report", "Report a public Clip", createClipReportSchema],
["/api/public/clips/{slug}/comments", "Comment on a public Clip", createClipCommentSchema],
["/api/public/clips/{slug}/showcase", "Add a public Clip showcase", createClipShowcaseSchema],
["/api/public/clips/{slug}/import-telemetry", "Record public Clip import telemetry", createClipImportTelemetrySchema],
] as const) {
registerCurrentRoute({
method: "post",
path: route[0],
tags: ["clips"],
summary: route[1],
body: route[2],
});
}
const pluginLocalFolderRequestSchema = z.object({
path: z.string().min(1),
access: z.enum(["read", "readWrite"]).optional(),