@morphika/andami 0.2.8 → 0.2.10
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/README.md +8 -3
- package/admin/backups.ts +7 -0
- package/app/(site)/layout.tsx +0 -2
- package/app/admin/backups/page.tsx +1 -0
- package/app/admin/layout.tsx +327 -274
- package/app/api/admin/backups/export/route.ts +76 -0
- package/app/api/admin/backups/prepare-export/route.ts +56 -0
- package/app/api/admin/backups/restore/route.ts +131 -0
- package/app/api/admin/backups/restore-data/route.ts +424 -0
- package/app/api/admin/backups/status/route.ts +35 -0
- package/app/api/custom-sections/[id]/route.ts +9 -5
- package/components/admin/backups/BackupsPage.tsx +1581 -0
- package/components/builder/CustomSectionInstanceCard.tsx +7 -3
- package/components/builder/ReadOnlyFrame.tsx +4 -2
- package/components/builder/settings-panel/CustomSectionSettings.tsx +5 -3
- package/lib/backup/export.ts +377 -0
- package/lib/backup/manifest.ts +121 -0
- package/lib/backup/r2-helpers.ts +294 -0
- package/lib/backup/restore.ts +266 -0
- package/lib/backup/sanity-ops.ts +194 -0
- package/lib/builder/serializer/normalizers.ts +1 -0
- package/lib/builder/store-canvas.ts +4 -0
- package/lib/builder/store.ts +1 -0
- package/lib/builder/types.ts +4 -0
- package/lib/security.ts +30 -0
- package/lib/security.ts.new +27 -0
- package/lib/storage/types.ts +33 -1
- package/lib/version.ts +7 -4
- package/package.json +17 -1
- package/components/ui/PortfolioTracker.tsx +0 -87
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { isAdminAuthenticated } from "../../../../../lib/auth";
|
|
3
|
+
import { jsonError } from "../../../../../lib/security";
|
|
4
|
+
import { getBackupStatus } from "../../../../../lib/backup/export";
|
|
5
|
+
import { logger } from "../../../../../lib/logger";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* GET /api/admin/backups/status — Backup readiness check.
|
|
9
|
+
*
|
|
10
|
+
* Returns:
|
|
11
|
+
* - R2 connection status
|
|
12
|
+
* - Asset count and total size
|
|
13
|
+
* - Sanity document counts by type
|
|
14
|
+
*
|
|
15
|
+
* Used by the admin Backups page to show what will be included
|
|
16
|
+
* in the backup before the user clicks "Create Backup".
|
|
17
|
+
*
|
|
18
|
+
* Auth required. No CSRF (GET request).
|
|
19
|
+
*/
|
|
20
|
+
export async function GET() {
|
|
21
|
+
if (!(await isAdminAuthenticated())) {
|
|
22
|
+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const status = await getBackupStatus();
|
|
27
|
+
return NextResponse.json(status);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
logger.error("[Admin:Backup]", "Status check failed", err);
|
|
30
|
+
return jsonError(
|
|
31
|
+
err instanceof Error ? err.message : "Status check failed",
|
|
32
|
+
500
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { adminClient } from "../../../../lib/sanity/client";
|
|
3
3
|
import { customSectionByIdQuery } from "../../../../lib/sanity/queries";
|
|
4
4
|
import { logger } from "../../../../lib/logger";
|
|
5
5
|
|
|
6
6
|
type RouteContext = { params: Promise<{ id: string }> };
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* GET /api/custom-sections/[id] — Public: section data only
|
|
9
|
+
* GET /api/custom-sections/[id] — Public: section data only
|
|
10
10
|
*
|
|
11
11
|
* Returns only the `section` field (PageSectionV2 data) for rendering
|
|
12
12
|
* custom section instances on the public site.
|
|
13
|
+
*
|
|
14
|
+
* Uses adminClient (useCdn: false) so data is always fresh after
|
|
15
|
+
* revalidatePath() is called from the admin PATCH endpoint.
|
|
16
|
+
* Cache is controlled via ISR revalidation on-demand, not via
|
|
17
|
+
* Cache-Control headers — this avoids stale CDN responses after edits.
|
|
13
18
|
*/
|
|
14
19
|
export async function GET(_request: NextRequest, context: RouteContext) {
|
|
15
20
|
try {
|
|
@@ -19,7 +24,7 @@ export async function GET(_request: NextRequest, context: RouteContext) {
|
|
|
19
24
|
return NextResponse.json({ error: "Missing section ID" }, { status: 400 });
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
const result = await
|
|
27
|
+
const result = await adminClient.fetch(customSectionByIdQuery, { id });
|
|
23
28
|
if (!result?.section) {
|
|
24
29
|
return NextResponse.json({ error: "Custom section not found" }, { status: 404 });
|
|
25
30
|
}
|
|
@@ -28,8 +33,7 @@ export async function GET(_request: NextRequest, context: RouteContext) {
|
|
|
28
33
|
{ section: result.section },
|
|
29
34
|
{
|
|
30
35
|
headers: {
|
|
31
|
-
"Cache-Control": "public, s-maxage=
|
|
32
|
-
"CDN-Cache-Control": "public, s-maxage=3600",
|
|
36
|
+
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=30",
|
|
33
37
|
},
|
|
34
38
|
}
|
|
35
39
|
);
|