@bernierllc/content-management-nextjs 0.0.1 → 0.2.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.
@@ -0,0 +1,363 @@
1
+ /**
2
+ * Local type stubs matching the content management suite's interface contracts.
3
+ * These will be replaced by imports from @bernierllc/content-management-suite at merge time.
4
+ */
5
+ interface ContentItem {
6
+ id: string;
7
+ type: string;
8
+ createdAt: string;
9
+ title?: string;
10
+ body?: string;
11
+ data?: Record<string, unknown>;
12
+ status?: string;
13
+ channels?: string[];
14
+ metadata?: Record<string, unknown>;
15
+ updatedAt?: string;
16
+ publishedAt?: string;
17
+ scheduledFor?: Date;
18
+ workflowId?: string;
19
+ workflowStage?: string;
20
+ sourceType?: string | null;
21
+ sourceId?: string | null;
22
+ }
23
+ interface CreateContentInput {
24
+ type: string;
25
+ title?: string;
26
+ body?: string;
27
+ data?: Record<string, unknown>;
28
+ channels?: string[];
29
+ metadata?: Record<string, unknown>;
30
+ }
31
+ interface UpdateContentInput {
32
+ title?: string;
33
+ body?: string;
34
+ data?: Record<string, unknown>;
35
+ channels?: string[];
36
+ metadata?: Record<string, unknown>;
37
+ status?: string;
38
+ }
39
+ interface ContentFilters {
40
+ type?: string;
41
+ status?: string;
42
+ page?: number;
43
+ limit?: number;
44
+ }
45
+ interface PaginatedResult<T> {
46
+ items: T[];
47
+ total: number;
48
+ page: number;
49
+ limit: number;
50
+ totalPages: number;
51
+ }
52
+ interface AIReview {
53
+ id: string;
54
+ contentId: string;
55
+ score: number;
56
+ suggestions: AIReviewSuggestion[];
57
+ passesThreshold: boolean;
58
+ rawResult: Record<string, unknown>;
59
+ createdAt: string;
60
+ }
61
+ interface AIReviewSuggestion {
62
+ category: string;
63
+ severity: 'info' | 'warning' | 'error';
64
+ message: string;
65
+ originalText?: string;
66
+ suggestedFix?: string;
67
+ }
68
+ interface SocialPost {
69
+ id: string;
70
+ contentId: string;
71
+ platform: string;
72
+ body: string;
73
+ status: 'draft' | 'published' | 'failed';
74
+ platformPostId?: string | null;
75
+ publishedAt?: string | null;
76
+ workflowId?: string;
77
+ workflowStage?: string;
78
+ createdAt: string;
79
+ }
80
+ interface Workflow {
81
+ id: string;
82
+ name: string;
83
+ stages: WorkflowStage[];
84
+ contentType?: string;
85
+ description?: string;
86
+ createdAt?: string;
87
+ updatedAt?: string;
88
+ }
89
+ interface WorkflowStage {
90
+ id: string;
91
+ name: string;
92
+ order: number;
93
+ isPublishStage?: boolean;
94
+ allowsScheduling?: boolean;
95
+ description?: string;
96
+ permissions?: string[];
97
+ conditions?: StageConditions;
98
+ }
99
+ interface StageConditions {
100
+ autoAdvance?: boolean;
101
+ minScore?: number;
102
+ requiresHumanReview?: boolean;
103
+ }
104
+ interface User {
105
+ id: string;
106
+ name: string;
107
+ email: string;
108
+ role?: string;
109
+ permissions?: string[];
110
+ createdAt?: string;
111
+ updatedAt?: string;
112
+ }
113
+ interface ContentTypeDefinition {
114
+ id: string;
115
+ name: string;
116
+ schema?: unknown;
117
+ defaults?: Record<string, unknown>;
118
+ description?: string;
119
+ }
120
+ interface PublishResult {
121
+ channelId: string;
122
+ success: boolean;
123
+ url?: string;
124
+ error?: string;
125
+ }
126
+ interface ContentPublishResult {
127
+ item: ContentItem;
128
+ results: PublishResult[];
129
+ }
130
+ interface IngestResult {
131
+ created: boolean;
132
+ content: ContentItem;
133
+ }
134
+ interface PlatformPublishResult {
135
+ platform: string;
136
+ success: boolean;
137
+ platformPostId?: string;
138
+ url?: string;
139
+ error?: string;
140
+ }
141
+ interface ContentSource {
142
+ id: string;
143
+ name: string;
144
+ outputTypes: string[];
145
+ }
146
+ interface ContentPublisher {
147
+ id: string;
148
+ name: string;
149
+ acceptedTypes: string[];
150
+ }
151
+ interface EnhancedContent {
152
+ original: string;
153
+ enhanced: string;
154
+ changes: Array<{
155
+ type: string;
156
+ description: string;
157
+ }>;
158
+ }
159
+ interface Suggestion {
160
+ category: string;
161
+ severity: 'info' | 'warning' | 'error';
162
+ message: string;
163
+ suggestedFix?: string;
164
+ }
165
+ interface EnhanceOptions {
166
+ tone?: string;
167
+ style?: string;
168
+ instructions?: string;
169
+ }
170
+ interface PlatformInfo {
171
+ id: string;
172
+ name: string;
173
+ acceptedTypes: string[];
174
+ hasPreview: boolean;
175
+ hasMetrics: boolean;
176
+ }
177
+ interface PreviewResult {
178
+ html?: string;
179
+ url?: string;
180
+ text?: string;
181
+ }
182
+ interface SocialMetrics {
183
+ platform: string;
184
+ platformPostId: string;
185
+ impressions?: number;
186
+ engagement?: number;
187
+ clicks?: number;
188
+ shares?: number;
189
+ raw?: Record<string, unknown>;
190
+ }
191
+ interface ContentNamespace {
192
+ list(filters?: ContentFilters): Promise<PaginatedResult<ContentItem>>;
193
+ get(id: string): Promise<ContentItem | null>;
194
+ create(input: CreateContentInput): Promise<ContentItem>;
195
+ update(id: string, input: UpdateContentInput): Promise<ContentItem>;
196
+ delete(id: string): Promise<void>;
197
+ publish(id: string, options?: {
198
+ channels?: string[];
199
+ }): Promise<ContentPublishResult>;
200
+ }
201
+ interface ContentTypesNamespace {
202
+ register(definition: ContentTypeDefinition): void;
203
+ unregister(id: string): void;
204
+ list(): ContentTypeDefinition[];
205
+ get(id: string): ContentTypeDefinition | undefined;
206
+ }
207
+ interface WorkflowsNamespace {
208
+ list(): Promise<Workflow[]>;
209
+ get(id: string): Promise<Workflow>;
210
+ create(input: Partial<Workflow>): Promise<Workflow>;
211
+ update(id: string, input: Partial<Workflow>): Promise<Workflow>;
212
+ delete(id: string): Promise<void>;
213
+ }
214
+ interface PublishersNamespace {
215
+ register(publisher: ContentPublisher): void;
216
+ unregister(id: string): void;
217
+ list(): ContentPublisher[];
218
+ get(id: string): ContentPublisher | undefined;
219
+ }
220
+ interface SourcesNamespace {
221
+ register(source: ContentSource): void;
222
+ unregister(id: string): void;
223
+ list(): ContentSource[];
224
+ get(id: string): ContentSource | undefined;
225
+ ingest(sourceId: string, rawPayload: unknown): Promise<IngestResult>;
226
+ }
227
+ interface AINamespace {
228
+ review(contentId: string): Promise<AIReview>;
229
+ generateSocialPosts(contentId: string, platforms: string[]): Promise<SocialPost[]>;
230
+ enhance(contentId: string, opts?: EnhanceOptions): Promise<EnhancedContent>;
231
+ suggest(contentId: string): Promise<Suggestion[]>;
232
+ }
233
+ interface SocialNamespace {
234
+ registerPlatform(adapter: unknown): void;
235
+ unregisterPlatform(id: string): void;
236
+ listPlatforms(): PlatformInfo[];
237
+ publish(contentId: string, platforms: string[]): Promise<PlatformPublishResult[]>;
238
+ preview(contentId: string, platform: string): Promise<PreviewResult>;
239
+ getMetrics(contentId: string, platform: string): Promise<SocialMetrics>;
240
+ }
241
+ interface UsersNamespace {
242
+ list(): Promise<User[]>;
243
+ get(id: string): Promise<User | null>;
244
+ create(input: Partial<User>): Promise<User>;
245
+ update(id: string, input: Partial<User>): Promise<User>;
246
+ delete(id: string): Promise<void>;
247
+ }
248
+ interface PermissionsNamespace {
249
+ check(userId: string, permission: string): Promise<boolean>;
250
+ grant(userId: string, permission: string): Promise<void>;
251
+ revoke(userId: string, permission: string): Promise<void>;
252
+ list(userId: string): Promise<string[]>;
253
+ }
254
+ interface ConfigNamespace {
255
+ get<T = unknown>(key: string): T | undefined;
256
+ set<T = unknown>(key: string, value: T): void;
257
+ getAll(): Record<string, unknown>;
258
+ }
259
+ interface PluginsNamespace {
260
+ register(plugin: unknown): void;
261
+ unregister(id: string): void;
262
+ list(): unknown[];
263
+ get(id: string): unknown | undefined;
264
+ }
265
+ interface ContentManagementSuite {
266
+ readonly content: ContentNamespace;
267
+ readonly contentTypes: ContentTypesNamespace;
268
+ readonly workflows: WorkflowsNamespace;
269
+ readonly publishers: PublishersNamespace;
270
+ readonly sources: SourcesNamespace;
271
+ readonly ai: AINamespace;
272
+ readonly social: SocialNamespace;
273
+ readonly users: UsersNamespace;
274
+ readonly permissions: PermissionsNamespace;
275
+ readonly config: ConfigNamespace;
276
+ readonly plugins: PluginsNamespace;
277
+ initialize(): Promise<void>;
278
+ dispose(): Promise<void>;
279
+ }
280
+ declare class ContentManagementError extends Error {
281
+ readonly code: string;
282
+ readonly context: Record<string, unknown> | undefined;
283
+ constructor(message: string, options?: {
284
+ cause?: Error;
285
+ code?: string;
286
+ context?: Record<string, unknown>;
287
+ });
288
+ }
289
+ declare class ValidationError extends ContentManagementError {
290
+ constructor(message: string, options?: {
291
+ cause?: Error;
292
+ code?: string;
293
+ context?: Record<string, unknown>;
294
+ });
295
+ }
296
+ declare class NotFoundError extends ContentManagementError {
297
+ constructor(message: string, options?: {
298
+ cause?: Error;
299
+ code?: string;
300
+ context?: Record<string, unknown>;
301
+ });
302
+ }
303
+ declare class UnauthorizedError extends ContentManagementError {
304
+ constructor(message: string, options?: {
305
+ cause?: Error;
306
+ code?: string;
307
+ context?: Record<string, unknown>;
308
+ });
309
+ }
310
+ declare class ForbiddenError extends ContentManagementError {
311
+ constructor(message: string, options?: {
312
+ cause?: Error;
313
+ code?: string;
314
+ context?: Record<string, unknown>;
315
+ });
316
+ }
317
+ declare class ConflictError extends ContentManagementError {
318
+ constructor(message: string, options?: {
319
+ cause?: Error;
320
+ code?: string;
321
+ context?: Record<string, unknown>;
322
+ });
323
+ }
324
+ declare class InternalError extends ContentManagementError {
325
+ constructor(message: string, options?: {
326
+ cause?: Error;
327
+ code?: string;
328
+ context?: Record<string, unknown>;
329
+ });
330
+ }
331
+ interface RouteHandlerOptions {
332
+ auth: (request: Request) => Promise<{
333
+ userId: string;
334
+ } | null>;
335
+ basePath?: string;
336
+ }
337
+ interface AuthUser {
338
+ userId: string;
339
+ }
340
+
341
+ interface RouteHandlers {
342
+ GET: (request: Request) => Promise<Response>;
343
+ POST: (request: Request) => Promise<Response>;
344
+ PUT: (request: Request) => Promise<Response>;
345
+ DELETE: (request: Request) => Promise<Response>;
346
+ }
347
+ /**
348
+ * Create Next.js App Router route handlers for the content management suite.
349
+ *
350
+ * Returns GET, POST, PUT, DELETE functions that internally route based on the URL path.
351
+ */
352
+ declare function createContentRouteHandlers(suite: ContentManagementSuite, options: RouteHandlerOptions): RouteHandlers;
353
+
354
+ /**
355
+ * Map error instances to HTTP status codes.
356
+ */
357
+ declare function errorToStatusCode(error: unknown): number;
358
+ /**
359
+ * Extract an error message suitable for HTTP responses.
360
+ */
361
+ declare function errorToMessage(error: unknown): string;
362
+
363
+ export { type AIReview, type AIReviewSuggestion, type AuthUser, ConflictError, type ContentFilters, type ContentItem, ContentManagementError, type ContentManagementSuite, type ContentPublishResult, type ContentPublisher, type ContentSource, type ContentTypeDefinition, type CreateContentInput, ForbiddenError, type IngestResult, InternalError, NotFoundError, type PaginatedResult, type PlatformPublishResult, type PublishResult, type RouteHandlerOptions, type RouteHandlers, type SocialPost, type StageConditions, UnauthorizedError, type UpdateContentInput, type User, ValidationError, type Workflow, type WorkflowStage, createContentRouteHandlers, errorToMessage, errorToStatusCode };
package/dist/index.js ADDED
@@ -0,0 +1,352 @@
1
+ // src/types.ts
2
+ var ContentManagementError = class extends Error {
3
+ constructor(message, options) {
4
+ super(message, { cause: options?.cause });
5
+ this.name = "ContentManagementError";
6
+ this.code = options?.code ?? "CONTENT_MANAGEMENT_ERROR";
7
+ this.context = options?.context;
8
+ }
9
+ };
10
+ var ValidationError = class extends ContentManagementError {
11
+ constructor(message, options) {
12
+ super(message, { ...options, code: options?.code ?? "VALIDATION_ERROR" });
13
+ this.name = "ValidationError";
14
+ }
15
+ };
16
+ var NotFoundError = class extends ContentManagementError {
17
+ constructor(message, options) {
18
+ super(message, { ...options, code: options?.code ?? "NOT_FOUND" });
19
+ this.name = "NotFoundError";
20
+ }
21
+ };
22
+ var UnauthorizedError = class extends ContentManagementError {
23
+ constructor(message, options) {
24
+ super(message, { ...options, code: options?.code ?? "UNAUTHORIZED" });
25
+ this.name = "UnauthorizedError";
26
+ }
27
+ };
28
+ var ForbiddenError = class extends ContentManagementError {
29
+ constructor(message, options) {
30
+ super(message, { ...options, code: options?.code ?? "FORBIDDEN" });
31
+ this.name = "ForbiddenError";
32
+ }
33
+ };
34
+ var ConflictError = class extends ContentManagementError {
35
+ constructor(message, options) {
36
+ super(message, { ...options, code: options?.code ?? "CONFLICT" });
37
+ this.name = "ConflictError";
38
+ }
39
+ };
40
+ var InternalError = class extends ContentManagementError {
41
+ constructor(message, options) {
42
+ super(message, { ...options, code: options?.code ?? "INTERNAL_ERROR" });
43
+ this.name = "InternalError";
44
+ }
45
+ };
46
+
47
+ // src/error-mapper.ts
48
+ function errorToStatusCode(error) {
49
+ if (error instanceof ValidationError)
50
+ return 400;
51
+ if (error instanceof UnauthorizedError)
52
+ return 401;
53
+ if (error instanceof ForbiddenError)
54
+ return 403;
55
+ if (error instanceof NotFoundError)
56
+ return 404;
57
+ if (error instanceof ConflictError)
58
+ return 409;
59
+ if (error instanceof InternalError)
60
+ return 500;
61
+ return 500;
62
+ }
63
+ function errorToMessage(error) {
64
+ if (error instanceof Error) {
65
+ return error.message;
66
+ }
67
+ return "Internal server error";
68
+ }
69
+
70
+ // src/handlers/content.ts
71
+ async function handleContentGet(suite, _user, segments, request) {
72
+ if (segments.length === 1) {
73
+ const id = segments[0];
74
+ const item = await suite.content.get(id);
75
+ if (!item) {
76
+ return Response.json({ error: "Content not found" }, { status: 404 });
77
+ }
78
+ return Response.json(item);
79
+ }
80
+ const url = new URL(request.url);
81
+ const filters = {};
82
+ const type = url.searchParams.get("type");
83
+ const status = url.searchParams.get("status");
84
+ const page = url.searchParams.get("page");
85
+ const limit = url.searchParams.get("limit");
86
+ if (type)
87
+ filters.type = type;
88
+ if (status)
89
+ filters.status = status;
90
+ if (page)
91
+ filters.page = parseInt(page, 10);
92
+ if (limit)
93
+ filters.limit = parseInt(limit, 10);
94
+ const result = await suite.content.list(filters);
95
+ return Response.json(result);
96
+ }
97
+ async function handleContentPost(suite, _user, segments, request) {
98
+ if (segments.length === 2 && segments[1] === "publish") {
99
+ const id = segments[0];
100
+ let body2 = {};
101
+ try {
102
+ body2 = await request.json();
103
+ } catch {
104
+ }
105
+ const channels = body2.channels;
106
+ const result = await suite.content.publish(id, channels ? { channels } : {});
107
+ return Response.json(result);
108
+ }
109
+ if (segments.length === 2 && segments[1] === "review") {
110
+ const id = segments[0];
111
+ const review = await suite.ai.review(id);
112
+ return Response.json(review);
113
+ }
114
+ const body = await request.json();
115
+ const item = await suite.content.create(body);
116
+ return Response.json(item, { status: 201 });
117
+ }
118
+ async function handleContentPut(suite, _user, segments, request) {
119
+ if (segments.length !== 1) {
120
+ return Response.json({ error: "Invalid path" }, { status: 400 });
121
+ }
122
+ const id = segments[0];
123
+ const body = await request.json();
124
+ const item = await suite.content.update(id, body);
125
+ return Response.json(item);
126
+ }
127
+ async function handleContentDelete(suite, _user, segments) {
128
+ if (segments.length !== 1) {
129
+ return Response.json({ error: "Invalid path" }, { status: 400 });
130
+ }
131
+ const id = segments[0];
132
+ await suite.content.delete(id);
133
+ return Response.json({ success: true }, { status: 200 });
134
+ }
135
+
136
+ // src/handlers/workflows.ts
137
+ async function handleWorkflowsGet(suite, _user, segments) {
138
+ if (segments.length === 1) {
139
+ const id = segments[0];
140
+ const workflow = await suite.workflows.get(id);
141
+ return Response.json(workflow);
142
+ }
143
+ const workflows = await suite.workflows.list();
144
+ return Response.json(workflows);
145
+ }
146
+ async function handleWorkflowsPost(suite, _user, _segments, request) {
147
+ const body = await request.json();
148
+ const workflow = await suite.workflows.create(body);
149
+ return Response.json(workflow, { status: 201 });
150
+ }
151
+ async function handleWorkflowsPut(suite, _user, segments, request) {
152
+ if (segments.length !== 1) {
153
+ return Response.json({ error: "Invalid path" }, { status: 400 });
154
+ }
155
+ const id = segments[0];
156
+ const body = await request.json();
157
+ const workflow = await suite.workflows.update(id, body);
158
+ return Response.json(workflow);
159
+ }
160
+ async function handleWorkflowsDelete(suite, _user, segments) {
161
+ if (segments.length !== 1) {
162
+ return Response.json({ error: "Invalid path" }, { status: 400 });
163
+ }
164
+ const id = segments[0];
165
+ await suite.workflows.delete(id);
166
+ return Response.json({ success: true }, { status: 200 });
167
+ }
168
+
169
+ // src/handlers/sources.ts
170
+ async function handleSourcesGet(suite, _user) {
171
+ const sources = suite.sources.list();
172
+ const result = sources.map((s) => ({
173
+ id: s.id,
174
+ name: s.name,
175
+ outputTypes: s.outputTypes
176
+ }));
177
+ return Response.json(result);
178
+ }
179
+ async function handleSourcesIngest(suite, _user, sourceId, request) {
180
+ const body = await request.json();
181
+ const result = await suite.sources.ingest(sourceId, body);
182
+ return Response.json(result, { status: result.created ? 201 : 200 });
183
+ }
184
+
185
+ // src/handlers/publishers.ts
186
+ async function handlePublishersGet(suite, _user) {
187
+ const publishers = suite.publishers.list();
188
+ const result = publishers.map((p) => ({
189
+ id: p.id,
190
+ name: p.name,
191
+ acceptedTypes: p.acceptedTypes
192
+ }));
193
+ return Response.json(result);
194
+ }
195
+
196
+ // src/handlers/content-types.ts
197
+ async function handleContentTypesGet(suite, _user) {
198
+ const types = suite.contentTypes.list();
199
+ const result = types.map((t) => ({
200
+ id: t.id,
201
+ name: t.name,
202
+ description: t.description,
203
+ defaults: t.defaults
204
+ }));
205
+ return Response.json(result);
206
+ }
207
+
208
+ // src/handlers/social.ts
209
+ async function handleSocialPublish(suite, _user, contentId, request) {
210
+ const body = await request.json();
211
+ const platforms = body.platforms;
212
+ if (!platforms || !Array.isArray(platforms)) {
213
+ return Response.json(
214
+ { error: "platforms array is required" },
215
+ { status: 400 }
216
+ );
217
+ }
218
+ const results = await suite.social.publish(contentId, platforms);
219
+ return Response.json(results);
220
+ }
221
+
222
+ // src/route-handler-factory.ts
223
+ function createContentRouteHandlers(suite, options) {
224
+ if (!options.auth) {
225
+ throw new Error(
226
+ "auth callback is required - content management routes must not be publicly accessible"
227
+ );
228
+ }
229
+ const basePath = options.basePath ?? "/api/content";
230
+ const normalizedBase = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
231
+ const lastSlash = normalizedBase.lastIndexOf("/");
232
+ const apiPrefix = lastSlash > 0 ? normalizedBase.slice(0, lastSlash) : "";
233
+ async function withAuth(request, handler) {
234
+ try {
235
+ const user = await options.auth(request);
236
+ if (!user) {
237
+ return Response.json({ error: "Unauthorized" }, { status: 401 });
238
+ }
239
+ return await handler(user);
240
+ } catch (error) {
241
+ const status = errorToStatusCode(error);
242
+ const message = errorToMessage(error);
243
+ return Response.json({ error: message }, { status });
244
+ }
245
+ }
246
+ function routeSegments(url) {
247
+ const parsed = new URL(url);
248
+ const pathname = parsed.pathname;
249
+ if (pathname === normalizedBase || pathname.startsWith(normalizedBase + "/")) {
250
+ const rest = pathname.slice(normalizedBase.length);
251
+ const segments = rest.split("/").filter(Boolean);
252
+ return { resource: "content", segments };
253
+ }
254
+ if (apiPrefix) {
255
+ const afterPrefix = pathname.slice(apiPrefix.length);
256
+ const parts = afterPrefix.split("/").filter(Boolean);
257
+ if (parts.length >= 1 && parts[0]) {
258
+ const resource = parts[0];
259
+ const segments = parts.slice(1);
260
+ return { resource, segments };
261
+ }
262
+ }
263
+ return null;
264
+ }
265
+ const GET = async (request) => {
266
+ return withAuth(request, async (user) => {
267
+ const route = routeSegments(request.url);
268
+ if (!route) {
269
+ return Response.json({ error: "Not found" }, { status: 404 });
270
+ }
271
+ switch (route.resource) {
272
+ case "content":
273
+ return handleContentGet(suite, user, route.segments, request);
274
+ case "workflows":
275
+ return handleWorkflowsGet(suite, user, route.segments);
276
+ case "sources":
277
+ return handleSourcesGet(suite, user);
278
+ case "publishers":
279
+ return handlePublishersGet(suite, user);
280
+ case "content-types":
281
+ return handleContentTypesGet(suite, user);
282
+ default:
283
+ return Response.json({ error: "Not found" }, { status: 404 });
284
+ }
285
+ });
286
+ };
287
+ const POST = async (request) => {
288
+ return withAuth(request, async (user) => {
289
+ const route = routeSegments(request.url);
290
+ if (!route) {
291
+ return Response.json({ error: "Not found" }, { status: 404 });
292
+ }
293
+ switch (route.resource) {
294
+ case "content":
295
+ return handleContentPost(suite, user, route.segments, request);
296
+ case "workflows":
297
+ return handleWorkflowsPost(suite, user, route.segments, request);
298
+ case "sources":
299
+ if (route.segments.length === 2 && route.segments[0] === "ingest" && route.segments[1]) {
300
+ return handleSourcesIngest(suite, user, route.segments[1], request);
301
+ }
302
+ return Response.json({ error: "Not found" }, { status: 404 });
303
+ case "social":
304
+ if (route.segments.length === 2 && route.segments[0] && route.segments[1] === "publish") {
305
+ return handleSocialPublish(suite, user, route.segments[0], request);
306
+ }
307
+ return Response.json({ error: "Not found" }, { status: 404 });
308
+ default:
309
+ return Response.json({ error: "Not found" }, { status: 404 });
310
+ }
311
+ });
312
+ };
313
+ const PUT = async (request) => {
314
+ return withAuth(request, async (user) => {
315
+ const route = routeSegments(request.url);
316
+ if (!route) {
317
+ return Response.json({ error: "Not found" }, { status: 404 });
318
+ }
319
+ switch (route.resource) {
320
+ case "content":
321
+ return handleContentPut(suite, user, route.segments, request);
322
+ case "workflows":
323
+ return handleWorkflowsPut(suite, user, route.segments, request);
324
+ default:
325
+ return Response.json({ error: "Not found" }, { status: 404 });
326
+ }
327
+ });
328
+ };
329
+ const DELETE = async (request) => {
330
+ return withAuth(request, async (user) => {
331
+ const route = routeSegments(request.url);
332
+ if (!route) {
333
+ return Response.json({ error: "Not found" }, { status: 404 });
334
+ }
335
+ switch (route.resource) {
336
+ case "content":
337
+ return handleContentDelete(suite, user, route.segments);
338
+ case "workflows":
339
+ return handleWorkflowsDelete(suite, user, route.segments);
340
+ default:
341
+ return Response.json({ error: "Not found" }, { status: 404 });
342
+ }
343
+ });
344
+ };
345
+ return { GET, POST, PUT, DELETE };
346
+ }
347
+ export {
348
+ createContentRouteHandlers,
349
+ errorToMessage,
350
+ errorToStatusCode
351
+ };
352
+ //# sourceMappingURL=index.js.map