Skip to content

Commit 2b5a1f9

Browse files
authored
Merge pull request #414 from objectstack-ai/copilot/develop-object-stack-protocol
2 parents 5a4fc01 + dd78129 commit 2b5a1f9

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

packages/plugins/plugin-msw/src/msw-plugin.ts

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,100 @@ export class MSWPlugin implements Plugin {
362362
}
363363
}),
364364

365+
// Batch Operations
366+
http.post(`${baseUrl}/data/:object/batch`, async ({ params, request }) => {
367+
try {
368+
const body = await request.json();
369+
const result = await protocol.batchData({ object: params.object as string, request: body as any });
370+
return HttpResponse.json(result);
371+
} catch (error) {
372+
const message = error instanceof Error ? error.message : 'Unknown error';
373+
return HttpResponse.json({ error: message }, { status: 400 });
374+
}
375+
}),
376+
377+
http.post(`${baseUrl}/data/:object/createMany`, async ({ params, request }) => {
378+
try {
379+
const body = await request.json();
380+
const records = Array.isArray(body) ? body : [];
381+
const result = await protocol.createManyData({ object: params.object as string, records });
382+
return HttpResponse.json(result, { status: 201 });
383+
} catch (error) {
384+
const message = error instanceof Error ? error.message : 'Unknown error';
385+
return HttpResponse.json({ error: message }, { status: 400 });
386+
}
387+
}),
388+
389+
http.post(`${baseUrl}/data/:object/updateMany`, async ({ params, request }) => {
390+
try {
391+
const body = await request.json() as any;
392+
const result = await protocol.updateManyData({
393+
object: params.object as string,
394+
records: body?.records || [],
395+
options: body?.options
396+
});
397+
return HttpResponse.json(result);
398+
} catch (error) {
399+
const message = error instanceof Error ? error.message : 'Unknown error';
400+
return HttpResponse.json({ error: message }, { status: 400 });
401+
}
402+
}),
403+
404+
http.post(`${baseUrl}/data/:object/deleteMany`, async ({ params, request }) => {
405+
try {
406+
const body = await request.json() as any;
407+
const result = await protocol.deleteManyData({
408+
object: params.object as string,
409+
ids: body?.ids || [],
410+
options: body?.options
411+
});
412+
return HttpResponse.json(result);
413+
} catch (error) {
414+
const message = error instanceof Error ? error.message : 'Unknown error';
415+
return HttpResponse.json({ error: message }, { status: 400 });
416+
}
417+
}),
418+
419+
// Enhanced Metadata with Cache Support
420+
http.get(`${baseUrl}/meta/:type/:name`, async ({ params, request }) => {
421+
try {
422+
const cacheRequest = {
423+
ifNoneMatch: request.headers.get('if-none-match') || undefined,
424+
ifModifiedSince: request.headers.get('if-modified-since') || undefined,
425+
};
426+
427+
const result = await protocol.getMetaItemCached({
428+
type: params.type as string,
429+
name: params.name as string,
430+
cacheRequest
431+
});
432+
433+
if (result.notModified) {
434+
return new HttpResponse(null, { status: 304 });
435+
}
436+
437+
// Build response headers
438+
const headers: Record<string, string> = {};
439+
if (result.etag) {
440+
const etagValue = result.etag.weak ? `W/"${result.etag.value}"` : `"${result.etag.value}"`;
441+
headers['ETag'] = etagValue;
442+
}
443+
if (result.lastModified) {
444+
headers['Last-Modified'] = new Date(result.lastModified).toUTCString();
445+
}
446+
if (result.cacheControl) {
447+
const directives = result.cacheControl.directives.join(', ');
448+
const maxAge = result.cacheControl.maxAge ? `, max-age=${result.cacheControl.maxAge}` : '';
449+
headers['Cache-Control'] = directives + maxAge;
450+
}
451+
452+
return HttpResponse.json(result.data, { headers });
453+
} catch (error) {
454+
const message = error instanceof Error ? error.message : 'Unknown error';
455+
return HttpResponse.json({ error: message }, { status: 404 });
456+
}
457+
}),
458+
365459
// UI Protocol endpoint
366460
http.get(`${baseUrl}/ui/view/:object`, async ({ params, request }) => {
367461
try {
@@ -375,6 +469,101 @@ export class MSWPlugin implements Plugin {
375469
}
376470
}),
377471

472+
// View Storage Operations
473+
http.post(`${baseUrl}/ui/views`, async ({ request }) => {
474+
try {
475+
const body = await request.json();
476+
const result = await protocol.createView(body as any);
477+
if (result.success) {
478+
return HttpResponse.json(result, { status: 201 });
479+
} else {
480+
return HttpResponse.json(result, { status: 400 });
481+
}
482+
} catch (error) {
483+
const message = error instanceof Error ? error.message : 'Unknown error';
484+
return HttpResponse.json({ success: false, error: { code: 'internal_error', message } }, { status: 500 });
485+
}
486+
}),
487+
488+
http.get(`${baseUrl}/ui/views/:id`, async ({ params }) => {
489+
try {
490+
const result = await protocol.getView({ id: params.id as string });
491+
if (result.success) {
492+
return HttpResponse.json(result);
493+
} else {
494+
return HttpResponse.json(result, { status: 404 });
495+
}
496+
} catch (error) {
497+
const message = error instanceof Error ? error.message : 'Unknown error';
498+
return HttpResponse.json({ success: false, error: { code: 'internal_error', message } }, { status: 500 });
499+
}
500+
}),
501+
502+
http.get(`${baseUrl}/ui/views`, async ({ request }) => {
503+
try {
504+
const url = new URL(request.url);
505+
const queryRequest: any = {};
506+
if (url.searchParams.get('object')) queryRequest.object = url.searchParams.get('object');
507+
if (url.searchParams.get('type')) queryRequest.type = url.searchParams.get('type');
508+
if (url.searchParams.get('visibility')) queryRequest.visibility = url.searchParams.get('visibility');
509+
if (url.searchParams.get('createdBy')) queryRequest.createdBy = url.searchParams.get('createdBy');
510+
if (url.searchParams.get('isDefault')) queryRequest.isDefault = url.searchParams.get('isDefault') === 'true';
511+
512+
// Parse numeric parameters with validation
513+
const limitParam = url.searchParams.get('limit');
514+
const offsetParam = url.searchParams.get('offset');
515+
if (limitParam) {
516+
const limit = parseInt(limitParam, 10);
517+
if (!isNaN(limit) && limit > 0) queryRequest.limit = limit;
518+
}
519+
if (offsetParam) {
520+
const offset = parseInt(offsetParam, 10);
521+
if (!isNaN(offset) && offset >= 0) queryRequest.offset = offset;
522+
}
523+
524+
const result = await protocol.listViews(queryRequest);
525+
return HttpResponse.json(result);
526+
} catch (error) {
527+
const message = error instanceof Error ? error.message : 'Unknown error';
528+
return HttpResponse.json({ success: false, error: { code: 'internal_error', message } }, { status: 500 });
529+
}
530+
}),
531+
532+
http.patch(`${baseUrl}/ui/views/:id`, async ({ params, request }) => {
533+
try {
534+
const body = await request.json() as any;
535+
// Merge body with id parameter, ensuring body is an object
536+
const updateData = (typeof body === 'object' && body !== null)
537+
? { ...body, id: params.id as string }
538+
: { id: params.id as string };
539+
540+
const result = await protocol.updateView(updateData as any);
541+
if (result.success) {
542+
return HttpResponse.json(result);
543+
} else {
544+
const statusCode = result.error?.code === 'resource_not_found' ? 404 : 400;
545+
return HttpResponse.json(result, { status: statusCode });
546+
}
547+
} catch (error) {
548+
const message = error instanceof Error ? error.message : 'Unknown error';
549+
return HttpResponse.json({ success: false, error: { code: 'internal_error', message } }, { status: 500 });
550+
}
551+
}),
552+
553+
http.delete(`${baseUrl}/ui/views/:id`, async ({ params }) => {
554+
try {
555+
const result = await protocol.deleteView({ id: params.id as string });
556+
if (result.success) {
557+
return HttpResponse.json(result);
558+
} else {
559+
return HttpResponse.json(result, { status: 404 });
560+
}
561+
} catch (error) {
562+
const message = error instanceof Error ? error.message : 'Unknown error';
563+
return HttpResponse.json({ success: false, error: { code: 'internal_error', message } }, { status: 500 });
564+
}
565+
}),
566+
378567
// Add custom handlers
379568
...(this.options.customHandlers || [])
380569
];

0 commit comments

Comments
 (0)