@aphexcms/cms-core 2.0.8 → 2.0.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/dist/api/api-keys.d.ts +4 -7
- package/dist/api/api-keys.d.ts.map +1 -1
- package/dist/api/assets.d.ts +7 -22
- package/dist/api/assets.d.ts.map +1 -1
- package/dist/api/assets.js +1 -10
- package/dist/api/documents.d.ts +17 -16
- package/dist/api/documents.d.ts.map +1 -1
- package/dist/api/documents.js +2 -2
- package/dist/api/organizations.d.ts +15 -35
- package/dist/api/organizations.d.ts.map +1 -1
- package/dist/api/schemas/api-keys.d.ts +16 -0
- package/dist/api/schemas/api-keys.d.ts.map +1 -0
- package/dist/api/schemas/api-keys.js +9 -0
- package/dist/api/schemas/assets.d.ts +174 -0
- package/dist/api/schemas/assets.d.ts.map +1 -0
- package/dist/api/schemas/assets.js +99 -0
- package/dist/api/schemas/documents.d.ts +325 -0
- package/dist/api/schemas/documents.d.ts.map +1 -0
- package/dist/api/schemas/documents.js +161 -0
- package/dist/api/schemas/organizations.d.ts +59 -0
- package/dist/api/schemas/organizations.d.ts.map +1 -0
- package/dist/api/schemas/organizations.js +45 -0
- package/dist/api/schemas/user.d.ts +10 -0
- package/dist/api/schemas/user.d.ts.map +1 -0
- package/dist/api/schemas/user.js +11 -0
- package/dist/api/user.d.ts +4 -6
- package/dist/api/user.d.ts.map +1 -1
- package/dist/auth/provider.d.ts +5 -0
- package/dist/auth/provider.d.ts.map +1 -1
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -0
- package/dist/components/AdminApp.svelte +8 -4
- package/dist/components/AdminApp.svelte.d.ts.map +1 -1
- package/dist/components/admin/DocumentEditor.svelte +23 -18
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/DocumentVersionPanel.svelte +18 -31
- package/dist/components/admin/DocumentVersionPanel.svelte.d.ts.map +1 -1
- package/dist/components/admin/confirm-dialog/ConfirmDialogHost.svelte +37 -0
- package/dist/components/admin/confirm-dialog/ConfirmDialogHost.svelte.d.ts +19 -0
- package/dist/components/admin/confirm-dialog/ConfirmDialogHost.svelte.d.ts.map +1 -0
- package/dist/components/admin/confirm-dialog/confirm-dialog.svelte.d.ts +16 -0
- package/dist/components/admin/confirm-dialog/confirm-dialog.svelte.d.ts.map +1 -0
- package/dist/components/admin/confirm-dialog/confirm-dialog.svelte.js +29 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +4 -0
- package/dist/lib/api/api-keys.d.ts +4 -7
- package/dist/lib/api/api-keys.d.ts.map +1 -1
- package/dist/lib/api/api-keys.js.map +1 -1
- package/dist/lib/api/assets.d.ts +7 -22
- package/dist/lib/api/assets.d.ts.map +1 -1
- package/dist/lib/api/assets.js +1 -10
- package/dist/lib/api/assets.js.map +1 -1
- package/dist/lib/api/documents.d.ts +17 -16
- package/dist/lib/api/documents.d.ts.map +1 -1
- package/dist/lib/api/documents.js +2 -2
- package/dist/lib/api/documents.js.map +1 -1
- package/dist/lib/api/organizations.d.ts +15 -35
- package/dist/lib/api/organizations.d.ts.map +1 -1
- package/dist/lib/api/organizations.js.map +1 -1
- package/dist/lib/api/schemas/api-keys.d.ts +16 -0
- package/dist/lib/api/schemas/api-keys.d.ts.map +1 -0
- package/dist/lib/api/schemas/api-keys.js +10 -0
- package/dist/lib/api/schemas/api-keys.js.map +1 -0
- package/dist/lib/api/schemas/assets.d.ts +174 -0
- package/dist/lib/api/schemas/assets.d.ts.map +1 -0
- package/dist/lib/api/schemas/assets.js +100 -0
- package/dist/lib/api/schemas/assets.js.map +1 -0
- package/dist/lib/api/schemas/documents.d.ts +325 -0
- package/dist/lib/api/schemas/documents.d.ts.map +1 -0
- package/dist/lib/api/schemas/documents.js +162 -0
- package/dist/lib/api/schemas/documents.js.map +1 -0
- package/dist/lib/api/schemas/organizations.d.ts +59 -0
- package/dist/lib/api/schemas/organizations.d.ts.map +1 -0
- package/dist/lib/api/schemas/organizations.js +46 -0
- package/dist/lib/api/schemas/organizations.js.map +1 -0
- package/dist/lib/api/schemas/user.d.ts +10 -0
- package/dist/lib/api/schemas/user.d.ts.map +1 -0
- package/dist/lib/api/schemas/user.js +12 -0
- package/dist/lib/api/schemas/user.js.map +1 -0
- package/dist/lib/api/user.d.ts +4 -6
- package/dist/lib/api/user.d.ts.map +1 -1
- package/dist/lib/api/user.js.map +1 -1
- package/dist/lib/auth/provider.d.ts +5 -0
- package/dist/lib/auth/provider.d.ts.map +1 -1
- package/dist/lib/client/index.d.ts +2 -0
- package/dist/lib/client/index.d.ts.map +1 -1
- package/dist/lib/client/index.js +3 -0
- package/dist/lib/client/index.js.map +1 -1
- package/dist/lib/components/admin/confirm-dialog/confirm-dialog.svelte.d.ts +16 -0
- package/dist/lib/components/admin/confirm-dialog/confirm-dialog.svelte.d.ts.map +1 -0
- package/dist/lib/components/admin/confirm-dialog/confirm-dialog.svelte.js +30 -0
- package/dist/lib/components/admin/confirm-dialog/confirm-dialog.svelte.js.map +1 -0
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +4 -0
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/routes/assets-bulk.d.ts.map +1 -1
- package/dist/lib/routes/assets-bulk.js +10 -3
- package/dist/lib/routes/assets-bulk.js.map +1 -1
- package/dist/lib/routes/assets-by-id.d.ts.map +1 -1
- package/dist/lib/routes/assets-by-id.js +11 -1
- package/dist/lib/routes/assets-by-id.js.map +1 -1
- package/dist/lib/routes/assets-references-counts.d.ts.map +1 -1
- package/dist/lib/routes/assets-references-counts.js +12 -2
- package/dist/lib/routes/assets-references-counts.js.map +1 -1
- package/dist/lib/routes/assets.d.ts.map +1 -1
- package/dist/lib/routes/assets.js +14 -13
- package/dist/lib/routes/assets.js.map +1 -1
- package/dist/lib/routes/document-versions.d.ts.map +1 -1
- package/dist/lib/routes/document-versions.js +16 -2
- package/dist/lib/routes/document-versions.js.map +1 -1
- package/dist/lib/routes/documents-by-id.d.ts.map +1 -1
- package/dist/lib/routes/documents-by-id.js +15 -3
- package/dist/lib/routes/documents-by-id.js.map +1 -1
- package/dist/lib/routes/documents-query.d.ts.map +1 -1
- package/dist/lib/routes/documents-query.js +13 -10
- package/dist/lib/routes/documents-query.js.map +1 -1
- package/dist/lib/routes/documents.d.ts.map +1 -1
- package/dist/lib/routes/documents.js +29 -26
- package/dist/lib/routes/documents.js.map +1 -1
- package/dist/lib/routes/organizations-by-id.d.ts.map +1 -1
- package/dist/lib/routes/organizations-by-id.js +11 -1
- package/dist/lib/routes/organizations-by-id.js.map +1 -1
- package/dist/lib/routes/organizations-invitations.d.ts.map +1 -1
- package/dist/lib/routes/organizations-invitations.js +32 -12
- package/dist/lib/routes/organizations-invitations.js.map +1 -1
- package/dist/lib/routes/organizations-members.d.ts.map +1 -1
- package/dist/lib/routes/organizations-members.js +14 -16
- package/dist/lib/routes/organizations-members.js.map +1 -1
- package/dist/lib/routes/organizations-switch.d.ts.map +1 -1
- package/dist/lib/routes/organizations-switch.js +7 -3
- package/dist/lib/routes/organizations-switch.js.map +1 -1
- package/dist/lib/routes/organizations.d.ts.map +1 -1
- package/dist/lib/routes/organizations.js +8 -5
- package/dist/lib/routes/organizations.js.map +1 -1
- package/dist/lib/routes/user-preferences.d.ts.map +1 -1
- package/dist/lib/routes/user-preferences.js +7 -13
- package/dist/lib/routes/user-preferences.js.map +1 -1
- package/dist/routes/assets-bulk.d.ts.map +1 -1
- package/dist/routes/assets-bulk.js +10 -3
- package/dist/routes/assets-by-id.d.ts.map +1 -1
- package/dist/routes/assets-by-id.js +11 -1
- package/dist/routes/assets-references-counts.d.ts.map +1 -1
- package/dist/routes/assets-references-counts.js +12 -2
- package/dist/routes/assets.d.ts.map +1 -1
- package/dist/routes/assets.js +14 -13
- package/dist/routes/document-versions.d.ts.map +1 -1
- package/dist/routes/document-versions.js +16 -2
- package/dist/routes/documents-by-id.d.ts.map +1 -1
- package/dist/routes/documents-by-id.js +15 -3
- package/dist/routes/documents-query.d.ts.map +1 -1
- package/dist/routes/documents-query.js +13 -10
- package/dist/routes/documents.d.ts.map +1 -1
- package/dist/routes/documents.js +29 -26
- package/dist/routes/organizations-by-id.d.ts.map +1 -1
- package/dist/routes/organizations-by-id.js +11 -1
- package/dist/routes/organizations-invitations.d.ts.map +1 -1
- package/dist/routes/organizations-invitations.js +32 -12
- package/dist/routes/organizations-members.d.ts.map +1 -1
- package/dist/routes/organizations-members.js +14 -16
- package/dist/routes/organizations-switch.d.ts.map +1 -1
- package/dist/routes/organizations-switch.js +7 -3
- package/dist/routes/organizations.d.ts.map +1 -1
- package/dist/routes/organizations.js +8 -5
- package/dist/routes/user-preferences.d.ts.map +1 -1
- package/dist/routes/user-preferences.js +7 -13
- package/package.json +5 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Aphex CMS User Preferences API Handler
|
|
2
2
|
import { json } from '@sveltejs/kit';
|
|
3
3
|
import { cmsLogger } from '../utils/logger.js';
|
|
4
|
+
import { updateUserPreferencesRequest } from '../api/schemas/user.js';
|
|
4
5
|
// GET /api/user/preferences - Get user preferences
|
|
5
6
|
export const GET = async ({ locals }) => {
|
|
6
7
|
try {
|
|
@@ -40,24 +41,17 @@ export const PATCH = async ({ request, locals }) => {
|
|
|
40
41
|
message: 'Session authentication required'
|
|
41
42
|
}, { status: 401 });
|
|
42
43
|
}
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
if (
|
|
44
|
+
const rawBody = await request.json();
|
|
45
|
+
const parsed = updateUserPreferencesRequest.safeParse(rawBody);
|
|
46
|
+
if (!parsed.success) {
|
|
46
47
|
return json({
|
|
47
48
|
success: false,
|
|
48
49
|
error: 'Invalid request body',
|
|
49
|
-
message: '
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
// Validate individual preference types
|
|
53
|
-
if (body.includeChildOrganizations !== undefined &&
|
|
54
|
-
typeof body.includeChildOrganizations !== 'boolean') {
|
|
55
|
-
return json({
|
|
56
|
-
success: false,
|
|
57
|
-
error: 'Invalid preference value',
|
|
58
|
-
message: 'includeChildOrganizations must be a boolean'
|
|
50
|
+
message: 'Invalid preference values',
|
|
51
|
+
issues: parsed.error.issues
|
|
59
52
|
}, { status: 400 });
|
|
60
53
|
}
|
|
54
|
+
const body = parsed.data;
|
|
61
55
|
// Update preferences
|
|
62
56
|
await databaseAdapter.updateUserPreferences(auth.user.id, body);
|
|
63
57
|
// Get updated profile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-preferences.js","sourceRoot":"","sources":["../../../src/lib/routes/user-preferences.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"user-preferences.js","sourceRoot":"","sources":["../../../src/lib/routes/user-preferences.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets-bulk.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-bulk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"assets-bulk.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-bulk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,MAAM,EAAE,cAgEpB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { json } from '@sveltejs/kit';
|
|
2
2
|
import { cmsLogger } from '../utils/logger.js';
|
|
3
|
+
import { bulkDeleteAssetsRequest } from '../api/schemas/assets.js';
|
|
3
4
|
export const DELETE = async ({ request, locals }) => {
|
|
4
5
|
try {
|
|
5
6
|
const { assetService, databaseAdapter } = locals.aphexCMS;
|
|
@@ -7,10 +8,16 @@ export const DELETE = async ({ request, locals }) => {
|
|
|
7
8
|
if (!auth || auth.type === 'partial_session') {
|
|
8
9
|
return json({ success: false, error: 'Unauthorized' }, { status: 401 });
|
|
9
10
|
}
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const rawBody = await request.json();
|
|
12
|
+
const parsed = bulkDeleteAssetsRequest.safeParse(rawBody);
|
|
13
|
+
if (!parsed.success) {
|
|
14
|
+
return json({
|
|
15
|
+
success: false,
|
|
16
|
+
error: 'No asset IDs provided',
|
|
17
|
+
issues: parsed.error.issues
|
|
18
|
+
}, { status: 400 });
|
|
13
19
|
}
|
|
20
|
+
const { ids } = parsed.data;
|
|
14
21
|
// Check for references before deleting
|
|
15
22
|
let referencedIds = [];
|
|
16
23
|
if (databaseAdapter.countDocumentReferencesForAssets) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-by-id.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"assets-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-by-id.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,GAAG,EAAE,cA6BjB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,cA0CpB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,cA6DnB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { json } from '@sveltejs/kit';
|
|
2
2
|
import { cmsLogger } from '../utils/logger.js';
|
|
3
|
+
import { updateAssetRequest } from '../api/schemas/assets.js';
|
|
3
4
|
export const GET = async ({ params, locals }) => {
|
|
4
5
|
try {
|
|
5
6
|
const { assetService } = locals.aphexCMS;
|
|
@@ -69,7 +70,16 @@ export const PATCH = async ({ params, locals, request }) => {
|
|
|
69
70
|
if (!id) {
|
|
70
71
|
return json({ success: false, error: 'Asset ID is required' }, { status: 400 });
|
|
71
72
|
}
|
|
72
|
-
const
|
|
73
|
+
const rawBody = await request.json();
|
|
74
|
+
const parsed = updateAssetRequest.safeParse(rawBody);
|
|
75
|
+
if (!parsed.success) {
|
|
76
|
+
return json({
|
|
77
|
+
success: false,
|
|
78
|
+
error: 'Invalid request body',
|
|
79
|
+
issues: parsed.error.issues
|
|
80
|
+
}, { status: 400 });
|
|
81
|
+
}
|
|
82
|
+
const { title, description, alt, creditLine } = parsed.data;
|
|
73
83
|
let updatedAsset;
|
|
74
84
|
if (auth.type == 'session') {
|
|
75
85
|
updatedAsset = await assetService.updateAssetMetadata(auth.organizationId, id, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets-references-counts.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-references-counts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"assets-references-counts.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-references-counts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,cAwClB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { json } from '@sveltejs/kit';
|
|
2
2
|
import { cmsLogger } from '../utils/logger.js';
|
|
3
|
+
import { assetReferenceCountsRequest } from '../api/schemas/assets.js';
|
|
3
4
|
/**
|
|
4
5
|
* POST /api/assets/references/counts
|
|
5
6
|
* Get reference counts for multiple asset IDs in batch
|
|
@@ -11,8 +12,17 @@ export const POST = async ({ request, locals }) => {
|
|
|
11
12
|
if (!auth || auth.type === 'partial_session') {
|
|
12
13
|
return json({ success: false, error: 'Unauthorized' }, { status: 401 });
|
|
13
14
|
}
|
|
14
|
-
const
|
|
15
|
-
|
|
15
|
+
const rawBody = await request.json();
|
|
16
|
+
const parsed = assetReferenceCountsRequest.safeParse(rawBody);
|
|
17
|
+
if (!parsed.success) {
|
|
18
|
+
return json({
|
|
19
|
+
success: false,
|
|
20
|
+
error: 'Invalid request body',
|
|
21
|
+
issues: parsed.error.issues
|
|
22
|
+
}, { status: 400 });
|
|
23
|
+
}
|
|
24
|
+
const { ids } = parsed.data;
|
|
25
|
+
if (ids.length === 0) {
|
|
16
26
|
return json({ success: true, data: {} });
|
|
17
27
|
}
|
|
18
28
|
if (!databaseAdapter.countDocumentReferencesForAssets) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,IAAI,EAAE,cAuFlB,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,cAqEjB,CAAC"}
|
package/dist/routes/assets.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { json } from '@sveltejs/kit';
|
|
3
3
|
import { cmsLogger } from '../utils/logger.js';
|
|
4
4
|
import { validateFile } from '../utils/mime-detect.js';
|
|
5
|
+
import { listAssetsQuery } from '../api/schemas/assets.js';
|
|
5
6
|
export const POST = async ({ request, locals }) => {
|
|
6
7
|
try {
|
|
7
8
|
const { assetService } = locals.aphexCMS;
|
|
@@ -82,20 +83,20 @@ export const GET = async ({ url, locals }) => {
|
|
|
82
83
|
if (!auth || auth.type === 'partial_session') {
|
|
83
84
|
return json({ success: false, error: 'Unauthorized' }, { status: 401 });
|
|
84
85
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
const parsedQuery = listAssetsQuery.safeParse(Object.fromEntries(url.searchParams.entries()));
|
|
87
|
+
if (!parsedQuery.success) {
|
|
88
|
+
return json({
|
|
89
|
+
success: false,
|
|
90
|
+
error: 'Invalid query parameters',
|
|
91
|
+
issues: parsedQuery.error.issues
|
|
92
|
+
}, { status: 400 });
|
|
93
|
+
}
|
|
93
94
|
const filters = {
|
|
94
|
-
assetType,
|
|
95
|
-
mimeType,
|
|
96
|
-
search,
|
|
97
|
-
limit:
|
|
98
|
-
offset:
|
|
95
|
+
assetType: parsedQuery.data.assetType,
|
|
96
|
+
mimeType: parsedQuery.data.mimeType,
|
|
97
|
+
search: parsedQuery.data.search,
|
|
98
|
+
limit: parsedQuery.data.limit ?? 20,
|
|
99
|
+
offset: parsedQuery.data.offset ?? 0
|
|
99
100
|
};
|
|
100
101
|
// Fetch assets and total count in parallel
|
|
101
102
|
const [fetchedAssets, totalAssets] = await Promise.all([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-versions.d.ts","sourceRoot":"","sources":["../../src/lib/routes/document-versions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"document-versions.d.ts","sourceRoot":"","sources":["../../src/lib/routes/document-versions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,eAAO,MAAM,GAAG,EAAE,cAyEjB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,cAuCxB,CAAC;AAGF,eAAO,MAAM,cAAc,EAAE,cA4C5B,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { json } from '@sveltejs/kit';
|
|
3
3
|
import { authToContext } from '../local-api/auth-helpers.js';
|
|
4
4
|
import { cmsLogger } from '../utils/logger.js';
|
|
5
|
+
import { listVersionsQuery } from '../api/schemas/documents.js';
|
|
5
6
|
// GET /api/documents/[id]/versions - List version history
|
|
6
7
|
export const GET = async ({ params, url, locals }) => {
|
|
7
8
|
try {
|
|
@@ -11,14 +12,27 @@ export const GET = async ({ params, url, locals }) => {
|
|
|
11
12
|
if (!id) {
|
|
12
13
|
return json({ success: false, error: 'Document ID is required' }, { status: 400 });
|
|
13
14
|
}
|
|
14
|
-
const
|
|
15
|
-
|
|
15
|
+
const parsedQuery = listVersionsQuery.safeParse(Object.fromEntries(url.searchParams.entries()));
|
|
16
|
+
if (!parsedQuery.success) {
|
|
17
|
+
return json({
|
|
18
|
+
success: false,
|
|
19
|
+
error: 'Invalid query parameters',
|
|
20
|
+
issues: parsedQuery.error.issues
|
|
21
|
+
}, { status: 400 });
|
|
22
|
+
}
|
|
23
|
+
const limit = parsedQuery.data.limit ?? 25;
|
|
24
|
+
const offset = parsedQuery.data.offset ?? 0;
|
|
16
25
|
const result = await localAPI.versionService.listVersions(databaseAdapter, context.organizationId, id, { limit, offset });
|
|
17
26
|
// Resolve user names for createdBy IDs
|
|
18
27
|
const userIds = [...new Set(result.versions.map((v) => v.createdBy).filter(Boolean))];
|
|
19
28
|
const userMap = new Map();
|
|
20
29
|
if (userIds.length > 0 && locals.aphexCMS.auth) {
|
|
21
30
|
await Promise.all(userIds.map(async (userId) => {
|
|
31
|
+
// API key actions are stored as "apikey:<id>" — resolve to a friendly label
|
|
32
|
+
if (userId.startsWith('apikey:')) {
|
|
33
|
+
userMap.set(userId, 'API Key');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
22
36
|
try {
|
|
23
37
|
const user = await locals.aphexCMS.auth.getUserById(userId);
|
|
24
38
|
if (user) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAQpD,eAAO,MAAM,GAAG,EAAE,cAuEjB,CAAC;AAIF,eAAO,MAAM,GAAG,EAAE,cAiGjB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cA+DpB,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { json } from '@sveltejs/kit';
|
|
|
3
3
|
import { authToContext } from '../local-api/auth-helpers.js';
|
|
4
4
|
import { PermissionError } from '../local-api/permissions.js';
|
|
5
5
|
import { cmsLogger } from '../utils/logger.js';
|
|
6
|
+
import { updateDocumentRequest } from '../api/schemas/documents.js';
|
|
6
7
|
// GET /api/documents/[id] - Get document by ID
|
|
7
8
|
// TODO ENABLE CHILDREN ORG ACCESS BY DEFAULT - BECAUSE IF A PARENT ORG IS TRYING TO ACCESS A CHILD ORG. It should already have access to said id.
|
|
8
9
|
export const GET = async ({ params, url, locals }) => {
|
|
@@ -67,12 +68,23 @@ export const PUT = async ({ params, request, locals }) => {
|
|
|
67
68
|
const { localAPI } = locals.aphexCMS;
|
|
68
69
|
const context = authToContext(locals.auth);
|
|
69
70
|
const { id } = params;
|
|
70
|
-
const body = await request.json();
|
|
71
71
|
if (!id) {
|
|
72
72
|
return json({ success: false, error: 'Document ID is required' }, { status: 400 });
|
|
73
73
|
}
|
|
74
|
-
const
|
|
75
|
-
const
|
|
74
|
+
const rawBody = await request.json();
|
|
75
|
+
const parsed = updateDocumentRequest.safeParse(rawBody);
|
|
76
|
+
if (!parsed.success) {
|
|
77
|
+
return json({
|
|
78
|
+
success: false,
|
|
79
|
+
error: 'Invalid request body',
|
|
80
|
+
issues: parsed.error.issues
|
|
81
|
+
}, { status: 400 });
|
|
82
|
+
}
|
|
83
|
+
const documentData = parsed.data.draftData ?? parsed.data.data;
|
|
84
|
+
if (!documentData) {
|
|
85
|
+
return json({ success: false, error: 'Document data is required' }, { status: 400 });
|
|
86
|
+
}
|
|
87
|
+
const shouldPublish = parsed.data.publish ?? false;
|
|
76
88
|
// Fetch document to get its type (hierarchy-aware, no RLS transaction)
|
|
77
89
|
const found = await localAPI.findDocumentById(context, id);
|
|
78
90
|
if (!found) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents-query.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-query.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"documents-query.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-query.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAWpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,IAAI,EAAE,cAyFlB,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { json } from '@sveltejs/kit';
|
|
|
3
3
|
import { authToContext } from '../local-api/auth-helpers.js';
|
|
4
4
|
import { PermissionError } from '../local-api/permissions.js';
|
|
5
5
|
import { cmsLogger } from '../utils/logger.js';
|
|
6
|
+
import { queryDocumentsRequest } from '../api/schemas/documents.js';
|
|
6
7
|
// Default values
|
|
7
8
|
const DEFAULT_PAGE_SIZE = 20;
|
|
8
9
|
const DEFAULT_PAGE = 1;
|
|
@@ -33,16 +34,18 @@ export const POST = async ({ request, locals }) => {
|
|
|
33
34
|
try {
|
|
34
35
|
const { localAPI } = locals.aphexCMS;
|
|
35
36
|
const context = authToContext(locals.auth);
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (!documentType) {
|
|
37
|
+
const rawBody = await request.json();
|
|
38
|
+
const parsed = queryDocumentsRequest.safeParse(rawBody);
|
|
39
|
+
if (!parsed.success) {
|
|
40
40
|
return json({
|
|
41
41
|
success: false,
|
|
42
42
|
error: 'Bad Request',
|
|
43
|
-
message: 'Document type is required in request body'
|
|
43
|
+
message: 'Document type is required in request body',
|
|
44
|
+
issues: parsed.error.issues
|
|
44
45
|
}, { status: 400 });
|
|
45
46
|
}
|
|
47
|
+
const body = parsed.data;
|
|
48
|
+
const documentType = body.type;
|
|
46
49
|
// Check if collection exists
|
|
47
50
|
if (!localAPI.hasCollection(documentType)) {
|
|
48
51
|
return json({
|
|
@@ -52,18 +55,18 @@ export const POST = async ({ request, locals }) => {
|
|
|
52
55
|
}, { status: 400 });
|
|
53
56
|
}
|
|
54
57
|
// Parse pagination - support both page-based and offset-based
|
|
55
|
-
const page = body.page
|
|
56
|
-
const pageSize = body.pageSize
|
|
58
|
+
const page = body.page ?? DEFAULT_PAGE;
|
|
59
|
+
const pageSize = body.pageSize ?? body.limit ?? DEFAULT_PAGE_SIZE;
|
|
57
60
|
const offset = body.offset !== undefined ? body.offset : (page - 1) * pageSize;
|
|
58
61
|
// Build FindOptions from request body
|
|
59
62
|
const findOptions = {
|
|
60
63
|
where: body.where,
|
|
61
64
|
limit: pageSize,
|
|
62
|
-
offset
|
|
65
|
+
offset,
|
|
63
66
|
sort: body.sort,
|
|
64
|
-
depth: body.depth
|
|
67
|
+
depth: body.depth ?? 0,
|
|
65
68
|
select: body.select,
|
|
66
|
-
perspective: body.perspective
|
|
69
|
+
perspective: body.perspective ?? 'draft',
|
|
67
70
|
includeChildOrganizations: body.includeChildOrganizations,
|
|
68
71
|
filterOrganizationIds: body.filterOrganizationIds
|
|
69
72
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAWpD,eAAO,MAAM,GAAG,EAAE,cA6GjB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,cAkFlB,CAAC"}
|
package/dist/routes/documents.js
CHANGED
|
@@ -3,6 +3,7 @@ import { json } from '@sveltejs/kit';
|
|
|
3
3
|
import { authToContext } from '../local-api/auth-helpers.js';
|
|
4
4
|
import { PermissionError } from '../local-api/permissions.js';
|
|
5
5
|
import { cmsLogger } from '../utils/logger.js';
|
|
6
|
+
import { createDocumentRequest, listDocumentsQuery } from '../api/schemas/documents.js';
|
|
6
7
|
// Default values for API
|
|
7
8
|
const DEFAULT_PAGE_SIZE = 20;
|
|
8
9
|
const DEFAULT_PAGE = 1;
|
|
@@ -11,25 +12,27 @@ export const GET = async ({ url, locals }) => {
|
|
|
11
12
|
try {
|
|
12
13
|
const { localAPI } = locals.aphexCMS;
|
|
13
14
|
const context = authToContext(locals.auth);
|
|
14
|
-
// Parse query params
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
const
|
|
15
|
+
// Parse + validate query params with zod
|
|
16
|
+
const rawQuery = Object.fromEntries(url.searchParams.entries());
|
|
17
|
+
const parsedQuery = listDocumentsQuery.safeParse(rawQuery);
|
|
18
|
+
if (!parsedQuery.success) {
|
|
19
|
+
return json({
|
|
20
|
+
success: false,
|
|
21
|
+
error: 'Invalid query parameters',
|
|
22
|
+
issues: parsedQuery.error.issues
|
|
23
|
+
}, { status: 400 });
|
|
24
|
+
}
|
|
25
|
+
const q = parsedQuery.data;
|
|
26
|
+
const docType = q.type ?? q.docType;
|
|
27
|
+
const status = q.status;
|
|
28
|
+
const sortParam = Array.isArray(q.sort) ? q.sort.join(',') : q.sort;
|
|
29
|
+
const perspective = q.perspective ?? 'draft';
|
|
30
|
+
const includeChildOrganizations = q.includeChildOrganizations;
|
|
31
|
+
const filterOrganizationIds = q.filterOrganizationIds;
|
|
32
|
+
const page = q.page ?? DEFAULT_PAGE;
|
|
33
|
+
const pageSize = q.pageSize ?? q.limit ?? DEFAULT_PAGE_SIZE;
|
|
30
34
|
const offset = (page - 1) * pageSize;
|
|
31
|
-
|
|
32
|
-
const depth = depthParam ? Math.max(0, Math.min(parseInt(depthParam), 5)) : 0;
|
|
35
|
+
const depth = q.depth ?? 0;
|
|
33
36
|
if (!docType) {
|
|
34
37
|
return json({
|
|
35
38
|
success: false,
|
|
@@ -96,18 +99,18 @@ export const POST = async ({ request, locals }) => {
|
|
|
96
99
|
try {
|
|
97
100
|
const { localAPI } = locals.aphexCMS;
|
|
98
101
|
const context = authToContext(locals.auth);
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const documentData = body.draftData || body.data;
|
|
103
|
-
const shouldPublish = body.publish || false;
|
|
104
|
-
if (!documentType || !documentData) {
|
|
102
|
+
const rawBody = await request.json();
|
|
103
|
+
const parsed = createDocumentRequest.safeParse(rawBody);
|
|
104
|
+
if (!parsed.success) {
|
|
105
105
|
return json({
|
|
106
106
|
success: false,
|
|
107
|
-
error: '
|
|
108
|
-
|
|
107
|
+
error: 'Invalid request body',
|
|
108
|
+
issues: parsed.error.issues
|
|
109
109
|
}, { status: 400 });
|
|
110
110
|
}
|
|
111
|
+
const documentType = parsed.data.type;
|
|
112
|
+
const documentData = (parsed.data.draftData ?? parsed.data.data);
|
|
113
|
+
const shouldPublish = parsed.data.publish ?? false;
|
|
111
114
|
// Get collection API (TypeScript-safe)
|
|
112
115
|
const collection = localAPI.collections[documentType];
|
|
113
116
|
if (!collection) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"organizations-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,GAAG,EAAE,cAmEjB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cA4GnB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAmFpB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Aphex CMS Organization by ID API Handlers
|
|
2
2
|
import { json } from '@sveltejs/kit';
|
|
3
3
|
import { cmsLogger } from '../utils/logger.js';
|
|
4
|
+
import { updateOrganizationRequest } from '../api/schemas/organizations.js';
|
|
4
5
|
// GET /api/organizations/[id] - Get organization by ID
|
|
5
6
|
export const GET = async ({ params, locals }) => {
|
|
6
7
|
try {
|
|
@@ -80,7 +81,16 @@ export const PATCH = async ({ params, request, locals }) => {
|
|
|
80
81
|
message: 'Only owners and admins can update organization settings'
|
|
81
82
|
}, { status: 403 });
|
|
82
83
|
}
|
|
83
|
-
const
|
|
84
|
+
const rawBody = await request.json();
|
|
85
|
+
const parsed = updateOrganizationRequest.safeParse(rawBody);
|
|
86
|
+
if (!parsed.success) {
|
|
87
|
+
return json({
|
|
88
|
+
success: false,
|
|
89
|
+
error: 'Invalid request body',
|
|
90
|
+
issues: parsed.error.issues
|
|
91
|
+
}, { status: 400 });
|
|
92
|
+
}
|
|
93
|
+
const body = parsed.data;
|
|
84
94
|
// Validate: if slug is being changed, check it's not already taken
|
|
85
95
|
if (body.slug) {
|
|
86
96
|
const existingOrg = await databaseAdapter.findOrganizationBySlug(body.slug);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations-invitations.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-invitations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"organizations-invitations.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-invitations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,IAAI,EAAE,cA+HlB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAuEpB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Aphex CMS Organization Invitations API Handlers
|
|
2
2
|
import { json } from '@sveltejs/kit';
|
|
3
3
|
import { cmsLogger } from '../utils/logger.js';
|
|
4
|
+
import { inviteMemberRequest, cancelInvitationRequest } from '../api/schemas/organizations.js';
|
|
4
5
|
// POST /api/organizations/invitations - Create/send an invitation
|
|
5
6
|
export const POST = async ({ request, locals }) => {
|
|
6
7
|
try {
|
|
@@ -21,23 +22,39 @@ export const POST = async ({ request, locals }) => {
|
|
|
21
22
|
message: 'Only owners and admins can invite members'
|
|
22
23
|
}, { status: 403 });
|
|
23
24
|
}
|
|
24
|
-
const
|
|
25
|
-
|
|
25
|
+
const rawBody = await request.json();
|
|
26
|
+
const parsed = inviteMemberRequest.safeParse(rawBody);
|
|
27
|
+
if (!parsed.success) {
|
|
26
28
|
return json({
|
|
27
29
|
success: false,
|
|
28
|
-
error: '
|
|
29
|
-
message: 'email and role are required'
|
|
30
|
+
error: 'Invalid request body',
|
|
31
|
+
message: 'email and role (admin|editor|viewer) are required',
|
|
32
|
+
issues: parsed.error.issues
|
|
30
33
|
}, { status: 400 });
|
|
31
34
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (
|
|
35
|
+
const body = parsed.data;
|
|
36
|
+
// Reject self-invitation
|
|
37
|
+
if (body.email.toLowerCase() === auth.user.email.toLowerCase()) {
|
|
35
38
|
return json({
|
|
36
39
|
success: false,
|
|
37
|
-
error: 'Invalid
|
|
38
|
-
message: '
|
|
40
|
+
error: 'Invalid invitation',
|
|
41
|
+
message: 'You cannot invite yourself'
|
|
39
42
|
}, { status: 400 });
|
|
40
43
|
}
|
|
44
|
+
// Reject if the invitee is already a member of the organization
|
|
45
|
+
if (locals.aphexCMS.auth) {
|
|
46
|
+
const existingUser = await locals.aphexCMS.auth.getUserByEmail(body.email);
|
|
47
|
+
if (existingUser) {
|
|
48
|
+
const existingMembership = await databaseAdapter.findUserMembership(existingUser.id, auth.organizationId);
|
|
49
|
+
if (existingMembership) {
|
|
50
|
+
return json({
|
|
51
|
+
success: false,
|
|
52
|
+
error: 'Already a member',
|
|
53
|
+
message: 'This user is already a member of the organization'
|
|
54
|
+
}, { status: 400 });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
41
58
|
// Check if there's already a pending invitation for this email
|
|
42
59
|
const existingInvitations = await databaseAdapter.findOrganizationInvitations(auth.organizationId);
|
|
43
60
|
const pendingInvitation = existingInvitations.find((inv) => inv.email.toLowerCase() === body.email.toLowerCase() && inv.acceptedAt === null);
|
|
@@ -94,14 +111,17 @@ export const DELETE = async ({ request, locals }) => {
|
|
|
94
111
|
message: 'Only owners and admins can cancel invitations'
|
|
95
112
|
}, { status: 403 });
|
|
96
113
|
}
|
|
97
|
-
const
|
|
98
|
-
|
|
114
|
+
const rawBody = await request.json();
|
|
115
|
+
const parsed = cancelInvitationRequest.safeParse(rawBody);
|
|
116
|
+
if (!parsed.success) {
|
|
99
117
|
return json({
|
|
100
118
|
success: false,
|
|
101
119
|
error: 'Missing required field',
|
|
102
|
-
message: 'invitationId is required'
|
|
120
|
+
message: 'invitationId is required',
|
|
121
|
+
issues: parsed.error.issues
|
|
103
122
|
}, { status: 400 });
|
|
104
123
|
}
|
|
124
|
+
const body = parsed.data;
|
|
105
125
|
// Delete the invitation
|
|
106
126
|
const deleted = await databaseAdapter.deleteInvitation(body.invitationId);
|
|
107
127
|
if (!deleted) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations-members.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-members.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"organizations-members.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-members.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,GAAG,EAAE,cAkCjB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAqIpB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cAiHnB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Aphex CMS Organization Members API Handlers
|
|
2
2
|
import { json } from '@sveltejs/kit';
|
|
3
3
|
import { cmsLogger } from '../utils/logger.js';
|
|
4
|
+
import { removeMemberRequest, updateMemberRoleRequest } from '../api/schemas/organizations.js';
|
|
4
5
|
// GET /api/organizations/members - List organization members
|
|
5
6
|
export const GET = async ({ locals }) => {
|
|
6
7
|
try {
|
|
@@ -49,14 +50,17 @@ export const DELETE = async ({ request, locals }) => {
|
|
|
49
50
|
message: 'Only owners and admins can remove members'
|
|
50
51
|
}, { status: 403 });
|
|
51
52
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
53
|
+
const rawBody = await request.json();
|
|
54
|
+
const parsed = removeMemberRequest.safeParse(rawBody);
|
|
55
|
+
if (!parsed.success) {
|
|
54
56
|
return json({
|
|
55
57
|
success: false,
|
|
56
58
|
error: 'Missing required field',
|
|
57
|
-
message: 'userId is required'
|
|
59
|
+
message: 'userId is required',
|
|
60
|
+
issues: parsed.error.issues
|
|
58
61
|
}, { status: 400 });
|
|
59
62
|
}
|
|
63
|
+
const body = parsed.data;
|
|
60
64
|
// Prevent removing yourself
|
|
61
65
|
if (body.userId === auth.user.id) {
|
|
62
66
|
return json({
|
|
@@ -141,23 +145,17 @@ export const PATCH = async ({ request, locals }) => {
|
|
|
141
145
|
message: 'Only owners and admins can update member roles'
|
|
142
146
|
}, { status: 403 });
|
|
143
147
|
}
|
|
144
|
-
const
|
|
145
|
-
|
|
148
|
+
const rawBody = await request.json();
|
|
149
|
+
const parsed = updateMemberRoleRequest.safeParse(rawBody);
|
|
150
|
+
if (!parsed.success) {
|
|
146
151
|
return json({
|
|
147
152
|
success: false,
|
|
148
|
-
error: '
|
|
149
|
-
message: 'userId and role are required'
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
// Validate role
|
|
153
|
-
const validRoles = ['owner', 'admin', 'editor', 'viewer'];
|
|
154
|
-
if (!validRoles.includes(body.role)) {
|
|
155
|
-
return json({
|
|
156
|
-
success: false,
|
|
157
|
-
error: 'Invalid role',
|
|
158
|
-
message: 'Role must be one of: owner, admin, editor, viewer'
|
|
153
|
+
error: 'Invalid request body',
|
|
154
|
+
message: 'userId and role (owner|admin|editor|viewer) are required',
|
|
155
|
+
issues: parsed.error.issues
|
|
159
156
|
}, { status: 400 });
|
|
160
157
|
}
|
|
158
|
+
const body = parsed.data;
|
|
161
159
|
// Prevent changing your own role
|
|
162
160
|
if (body.userId === auth.user.id) {
|
|
163
161
|
return json({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations-switch.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-switch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"organizations-switch.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-switch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,IAAI,EAAE,cAsElB,CAAC"}
|