@aphexcms/cms-core 5.0.3 → 5.1.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.
- package/dist/components/AdminApp.svelte +3 -9
- package/dist/components/AdminApp.svelte.d.ts.map +1 -1
- package/dist/components/admin/DocumentEditor.svelte +7 -3
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/ObjectModal.svelte +1 -1
- package/dist/components/admin/fields/ArrayField.svelte +23 -14
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/FileField.svelte +15 -4
- package/dist/components/admin/fields/FileField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ImageField.svelte +19 -4
- package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ReferenceField.svelte +26 -9
- package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +1 -1
- package/dist/hooks.d.ts +11 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +39 -22
- package/dist/lib/hooks.d.ts +11 -0
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +39 -22
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/schema-utils/validator.d.ts.map +1 -1
- package/dist/lib/schema-utils/validator.js +10 -7
- package/dist/lib/schema-utils/validator.js.map +1 -1
- package/dist/lib/server/api/routes/organizations-members.d.ts.map +1 -1
- package/dist/lib/server/api/routes/organizations-members.js +11 -0
- package/dist/lib/server/api/routes/organizations-members.js.map +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +1 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/types/schemas.d.ts +2 -0
- package/dist/lib/types/schemas.d.ts.map +1 -1
- package/dist/lib/utils/preview.d.ts +20 -0
- package/dist/lib/utils/preview.d.ts.map +1 -0
- package/dist/lib/utils/preview.js +68 -0
- package/dist/lib/utils/preview.js.map +1 -0
- package/dist/lib/vite/index.d.ts +86 -0
- package/dist/lib/vite/index.d.ts.map +1 -0
- package/dist/lib/vite/index.js +270 -0
- package/dist/lib/vite/index.js.map +1 -0
- package/dist/schema-utils/validator.d.ts.map +1 -1
- package/dist/schema-utils/validator.js +10 -7
- package/dist/server/api/routes/organizations-members.d.ts.map +1 -1
- package/dist/server/api/routes/organizations-members.js +11 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/types/schemas.d.ts +2 -0
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/utils/preview.d.ts +20 -0
- package/dist/utils/preview.d.ts.map +1 -0
- package/dist/utils/preview.js +67 -0
- package/dist/vite/index.d.ts +86 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +269 -0
- package/package.json +5 -1
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { SvelteURLSearchParams } from 'svelte/reactivity';
|
|
14
14
|
import type { SchemaType } from '../types/index';
|
|
15
15
|
import type { UserSessionPreferences } from '../types/organization';
|
|
16
|
+
import { resolvePreviewTitle, resolvePreviewSubtitle } from '../utils/preview';
|
|
16
17
|
import DocumentEditor from './admin/DocumentEditor.svelte';
|
|
17
18
|
import DocumentVersionPanel from './admin/DocumentVersionPanel.svelte';
|
|
18
19
|
import DocumentsSkeleton from './admin/DocumentsSkeleton.svelte';
|
|
@@ -912,20 +913,13 @@
|
|
|
912
913
|
}
|
|
913
914
|
// Find schema for preview config
|
|
914
915
|
const schema = schemas.find((s) => s.name === docType);
|
|
915
|
-
const previewConfig = schema?.preview;
|
|
916
916
|
|
|
917
917
|
documentsList = result.data.map((doc: any) => {
|
|
918
918
|
// With LocalAPI, data is already flattened at top level (not in draftData)
|
|
919
919
|
// The document itself IS the data, with _meta containing metadata
|
|
920
920
|
|
|
921
|
-
|
|
922
|
-
const
|
|
923
|
-
? doc[previewConfig.select.title] || `Untitled`
|
|
924
|
-
: doc.title || `Untitled`;
|
|
925
|
-
|
|
926
|
-
const subtitle = previewConfig?.select?.subtitle
|
|
927
|
-
? doc[previewConfig.select.subtitle]
|
|
928
|
-
: undefined;
|
|
921
|
+
const title = resolvePreviewTitle(doc, schema);
|
|
922
|
+
const subtitle = resolvePreviewSubtitle(doc, schema) ?? undefined;
|
|
929
923
|
|
|
930
924
|
// Metadata is in _meta field (from LocalAPI transformation)
|
|
931
925
|
const meta = doc._meta || {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminApp.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/AdminApp.svelte.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"AdminApp.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/AdminApp.svelte.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AA4BnE,UAAU,KAAK;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5E,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAA;KAAE,CAAC;IACxD,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,eAAe,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;CAChD;AA0/CF,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -293,12 +293,16 @@
|
|
|
293
293
|
(hasUnpublishedContent || isUnpublished) && !saving && documentId && !hasValidationErrors
|
|
294
294
|
);
|
|
295
295
|
|
|
296
|
-
// Get preview title based on schema config
|
|
296
|
+
// Get preview title based on schema config. When viewing in published
|
|
297
|
+
// perspective, read from the loaded published snapshot — otherwise the
|
|
298
|
+
// header shows the draft's title even though the body shows published
|
|
299
|
+
// fields, which is confusing.
|
|
297
300
|
function getPreviewTitle(): string {
|
|
301
|
+
const source = perspective === 'published' && publishedData ? publishedData : documentData;
|
|
298
302
|
if (!schema?.preview?.select?.title) {
|
|
299
|
-
return
|
|
303
|
+
return source.title || `Untitled`;
|
|
300
304
|
}
|
|
301
|
-
return
|
|
305
|
+
return source[schema.preview.select.title] || `Untitled`;
|
|
302
306
|
}
|
|
303
307
|
|
|
304
308
|
// CRITICAL: Clear state IMMEDIATELY when switching documents to prevent cross-contamination
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentEditor.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/DocumentEditor.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAaxD,UAAU,KAAK;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,CAAC,EAAE;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;IACT,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;
|
|
1
|
+
{"version":3,"file":"DocumentEditor.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/DocumentEditor.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAaxD,UAAU,KAAK;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,CAAC,EAAE;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;IACT,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAm+CF,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
backdrops cover the full screen, but for now keeping it inside the
|
|
85
85
|
editor is the design we want. -->
|
|
86
86
|
<div
|
|
87
|
-
class="bg-background/80 absolute inset-0
|
|
87
|
+
class="bg-background/80 absolute inset-0"
|
|
88
88
|
style="z-index: {backdropZ}"
|
|
89
89
|
onclick={handleBackdropClick}
|
|
90
90
|
onkeydown={handleKeydown}
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
import type { ImageValue } from '../../../types/asset';
|
|
29
29
|
import { toast } from 'svelte-sonner';
|
|
30
30
|
import AssetBrowserModal from '../AssetBrowserModal.svelte';
|
|
31
|
+
import { resolvePreviewTitle, resolvePreviewSubtitle } from '../../../utils/preview';
|
|
31
32
|
|
|
32
33
|
interface Props {
|
|
33
34
|
field: ArrayFieldType;
|
|
@@ -59,7 +60,9 @@
|
|
|
59
60
|
type: 'object',
|
|
60
61
|
name: inlineDef.name || typeName,
|
|
61
62
|
title: inlineDef.title || typeName,
|
|
62
|
-
fields: inlineDef.fields
|
|
63
|
+
fields: inlineDef.fields,
|
|
64
|
+
icon: inlineDef.icon,
|
|
65
|
+
preview: inlineDef.preview
|
|
63
66
|
};
|
|
64
67
|
}
|
|
65
68
|
|
|
@@ -401,21 +404,19 @@
|
|
|
401
404
|
|
|
402
405
|
function getItemTitle(item: any): string {
|
|
403
406
|
if (!item._type) return 'Unknown Item';
|
|
404
|
-
|
|
405
407
|
const schema = getSchemaForType(item._type);
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const titleField = item.title || item.heading || item.name || item.label;
|
|
409
|
-
if (titleField && typeof titleField === 'string' && titleField.trim()) {
|
|
410
|
-
return titleField;
|
|
411
|
-
}
|
|
408
|
+
return resolvePreviewTitle(item, schema, item._type);
|
|
409
|
+
}
|
|
412
410
|
|
|
413
|
-
|
|
411
|
+
function getItemSubtitle(item: any): string | null {
|
|
412
|
+
if (!item._type) return null;
|
|
413
|
+
const schema = getSchemaForType(item._type);
|
|
414
|
+
return resolvePreviewSubtitle(item, schema);
|
|
414
415
|
}
|
|
415
416
|
|
|
416
417
|
function getItemIcon(item: any): any {
|
|
417
418
|
if (!item._type) return null;
|
|
418
|
-
const schema =
|
|
419
|
+
const schema = getSchemaForType(item._type);
|
|
419
420
|
return schema?.icon || null;
|
|
420
421
|
}
|
|
421
422
|
</script>
|
|
@@ -771,7 +772,8 @@
|
|
|
771
772
|
|
|
772
773
|
<!-- Title (clickable to edit) — wraps the type icon so the whole
|
|
773
774
|
row body is a generous click target instead of just the
|
|
774
|
-
truncated title text.
|
|
775
|
+
truncated title text. When the schema's preview config
|
|
776
|
+
supplies a `subtitle` field, render it on a second line. -->
|
|
775
777
|
<button
|
|
776
778
|
class="flex flex-1 cursor-pointer items-center gap-2 self-stretch truncate px-1 py-2 text-left text-sm"
|
|
777
779
|
onclick={() => handleEditItem(index)}
|
|
@@ -784,7 +786,14 @@
|
|
|
784
786
|
<FileText class="h-4 w-4" />
|
|
785
787
|
{/if}
|
|
786
788
|
</span>
|
|
787
|
-
<span class="
|
|
789
|
+
<span class="flex min-w-0 flex-1 flex-col">
|
|
790
|
+
<span class="truncate">{getItemTitle(item)}</span>
|
|
791
|
+
{#if getItemSubtitle(item)}
|
|
792
|
+
<span class="text-muted-foreground truncate text-xs"
|
|
793
|
+
>{getItemSubtitle(item)}</span
|
|
794
|
+
>
|
|
795
|
+
{/if}
|
|
796
|
+
</span>
|
|
788
797
|
</button>
|
|
789
798
|
|
|
790
799
|
<!-- Context menu -->
|
|
@@ -875,7 +884,7 @@
|
|
|
875
884
|
<!-- Image upload modal -->
|
|
876
885
|
{#if imageModalOpen}
|
|
877
886
|
<div
|
|
878
|
-
class="bg-background/80 fixed top-12 right-0 bottom-0 left-0 z-40 flex items-center justify-center p-6
|
|
887
|
+
class="bg-background/80 fixed top-12 right-0 bottom-0 left-0 z-40 flex items-center justify-center p-6 sm:absolute sm:top-0 sm:p-4"
|
|
879
888
|
onclick={(e) => {
|
|
880
889
|
if (e.target === e.currentTarget) handleImageModalClose();
|
|
881
890
|
}}
|
|
@@ -931,7 +940,7 @@
|
|
|
931
940
|
<!-- Text editing modal -->
|
|
932
941
|
{#if textModalOpen}
|
|
933
942
|
<div
|
|
934
|
-
class="bg-background/80 fixed top-12 right-0 bottom-0 left-0 z-[100] flex items-center justify-center p-6
|
|
943
|
+
class="bg-background/80 fixed top-12 right-0 bottom-0 left-0 z-[100] flex items-center justify-center p-6 sm:absolute sm:top-0 sm:p-4"
|
|
935
944
|
onclick={(e) => {
|
|
936
945
|
if (e.target === e.currentTarget) handleTextModalClose();
|
|
937
946
|
}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ArrayField.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAc,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"ArrayField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ArrayField.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAc,MAAM,wBAAwB,CAAC;AA0BtF,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AA8xBF,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -52,6 +52,8 @@
|
|
|
52
52
|
const isReadOnly = $derived(readonly || !perms.can('asset.upload'));
|
|
53
53
|
|
|
54
54
|
let isDragging = $state(false);
|
|
55
|
+
// Drag-counter to defeat the dragleave/dragenter flicker — see ImageField for rationale.
|
|
56
|
+
let dragDepth = 0;
|
|
55
57
|
let isUploading = $state(false);
|
|
56
58
|
let uploadError = $state<string | null>(null);
|
|
57
59
|
let fileInputRef: HTMLInputElement;
|
|
@@ -121,21 +123,29 @@
|
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
125
|
|
|
124
|
-
function
|
|
126
|
+
function handleDragEnter(event: DragEvent) {
|
|
125
127
|
if (isReadOnly) return;
|
|
126
128
|
event.preventDefault();
|
|
129
|
+
dragDepth++;
|
|
127
130
|
isDragging = true;
|
|
128
131
|
}
|
|
129
132
|
|
|
133
|
+
function handleDragOver(event: DragEvent) {
|
|
134
|
+
if (isReadOnly) return;
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
}
|
|
137
|
+
|
|
130
138
|
function handleDragLeave(event: DragEvent) {
|
|
131
139
|
if (isReadOnly) return;
|
|
132
140
|
event.preventDefault();
|
|
133
|
-
|
|
141
|
+
dragDepth = Math.max(0, dragDepth - 1);
|
|
142
|
+
if (dragDepth === 0) isDragging = false;
|
|
134
143
|
}
|
|
135
144
|
|
|
136
145
|
function handleDrop(event: DragEvent) {
|
|
137
146
|
if (isReadOnly) return;
|
|
138
147
|
event.preventDefault();
|
|
148
|
+
dragDepth = 0;
|
|
139
149
|
isDragging = false;
|
|
140
150
|
handleFileSelect(event.dataTransfer?.files || null);
|
|
141
151
|
}
|
|
@@ -409,13 +419,14 @@
|
|
|
409
419
|
{:else}
|
|
410
420
|
<!-- Upload bar -->
|
|
411
421
|
<div
|
|
412
|
-
class="border-border flex h-
|
|
422
|
+
class="border-border flex h-12 items-center overflow-hidden rounded-md border transition-colors {validationClasses} {isReadOnly
|
|
413
423
|
? ''
|
|
414
424
|
: isDragging
|
|
415
|
-
? 'bg-primary/5'
|
|
425
|
+
? 'border-primary bg-primary/5'
|
|
416
426
|
: ''}"
|
|
417
427
|
use:elementEvents={{
|
|
418
428
|
events: [
|
|
429
|
+
{ name: 'dragenter', handler: handleDragEnter },
|
|
419
430
|
{ name: 'dragover', handler: handleDragOver },
|
|
420
431
|
{ name: 'drop', handler: handleDrop },
|
|
421
432
|
{ name: 'dragleave', handler: handleDragLeave }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/FileField.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAkBxE,UAAU,KAAK;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"FileField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/FileField.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAkBxE,UAAU,KAAK;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAkbF,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -53,6 +53,12 @@
|
|
|
53
53
|
|
|
54
54
|
// Component state
|
|
55
55
|
let isDragging = $state(false);
|
|
56
|
+
// Drag-counter to defeat the dragleave/dragenter flicker: every child
|
|
57
|
+
// element the cursor crosses fires `dragleave` on the parent immediately
|
|
58
|
+
// followed by `dragenter`, so a naive `dragover → true / dragleave → false`
|
|
59
|
+
// flickers `isDragging` rapidly. Counting enters/leaves and only resetting
|
|
60
|
+
// at zero gives stable highlight state.
|
|
61
|
+
let dragDepth = 0;
|
|
56
62
|
let isUploading = $state(false);
|
|
57
63
|
let uploadError = $state<string | null>(null);
|
|
58
64
|
let fileInputRef: HTMLInputElement;
|
|
@@ -112,21 +118,29 @@
|
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
// Drag and drop handlers
|
|
115
|
-
function
|
|
121
|
+
function handleDragEnter(event: DragEvent) {
|
|
116
122
|
if (isReadOnly) return;
|
|
117
123
|
event.preventDefault();
|
|
124
|
+
dragDepth++;
|
|
118
125
|
isDragging = true;
|
|
119
126
|
}
|
|
120
127
|
|
|
128
|
+
function handleDragOver(event: DragEvent) {
|
|
129
|
+
if (isReadOnly) return;
|
|
130
|
+
event.preventDefault(); // required to allow `drop` to fire
|
|
131
|
+
}
|
|
132
|
+
|
|
121
133
|
function handleDragLeave(event: DragEvent) {
|
|
122
134
|
if (isReadOnly) return;
|
|
123
135
|
event.preventDefault();
|
|
124
|
-
|
|
136
|
+
dragDepth = Math.max(0, dragDepth - 1);
|
|
137
|
+
if (dragDepth === 0) isDragging = false;
|
|
125
138
|
}
|
|
126
139
|
|
|
127
140
|
function handleDrop(event: DragEvent) {
|
|
128
141
|
if (isReadOnly) return;
|
|
129
142
|
event.preventDefault();
|
|
143
|
+
dragDepth = 0;
|
|
130
144
|
isDragging = false;
|
|
131
145
|
handleFileSelect(event.dataTransfer?.files || null);
|
|
132
146
|
}
|
|
@@ -456,13 +470,14 @@
|
|
|
456
470
|
{:else}
|
|
457
471
|
<!-- Sanity-style upload bar -->
|
|
458
472
|
<div
|
|
459
|
-
class="border-border flex h-
|
|
473
|
+
class="border-border flex h-12 items-center overflow-hidden rounded-md border transition-colors {validationClasses} {isReadOnly
|
|
460
474
|
? ''
|
|
461
475
|
: isDragging
|
|
462
|
-
? 'bg-primary/5'
|
|
476
|
+
? 'border-primary bg-primary/5'
|
|
463
477
|
: ''}"
|
|
464
478
|
use:elementEvents={{
|
|
465
479
|
events: [
|
|
480
|
+
{ name: 'dragenter', handler: handleDragEnter },
|
|
466
481
|
{ name: 'dragover', handler: handleDragOver },
|
|
467
482
|
{ name: 'drop', handler: handleDrop },
|
|
468
483
|
{ name: 'dragleave', handler: handleDragLeave }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ImageField.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAmB1E,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"ImageField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ImageField.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAmB1E,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AA4cF,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import { toast } from 'svelte-sonner';
|
|
16
16
|
import { cmsLogger } from '../../../utils/logger';
|
|
17
17
|
import { pluralize } from '../../../utils/pluralize';
|
|
18
|
+
import { resolvePreviewTitle, resolvePreviewSubtitle } from '../../../utils/preview';
|
|
18
19
|
|
|
19
20
|
interface Props {
|
|
20
21
|
field: Field;
|
|
@@ -141,17 +142,19 @@
|
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
function getDocumentTitle(doc: any): string {
|
|
144
|
-
|
|
145
|
-
return doc.title || doc.name || doc.heading || 'Untitled';
|
|
145
|
+
return resolvePreviewTitle(doc, targetSchema);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
function getDocumentSubtitle(doc: any): string | null {
|
|
149
|
+
return resolvePreviewSubtitle(doc, targetSchema);
|
|
150
|
+
}
|
|
149
151
|
</script>
|
|
150
152
|
|
|
151
153
|
{#if selectedDocument}
|
|
152
|
-
<!-- Selected document — row styled like an ArrayField item
|
|
154
|
+
<!-- Selected document — row styled like an ArrayField item. Grows to two
|
|
155
|
+
lines when the target schema's preview config exposes a subtitle. -->
|
|
153
156
|
<div
|
|
154
|
-
class="border-border/50 bg-background hover:bg-muted/50 flex h-10 items-center gap-1 rounded border px-1 transition-colors"
|
|
157
|
+
class="border-border/50 bg-background hover:bg-muted/50 flex min-h-10 items-center gap-1 rounded border px-1 transition-colors"
|
|
155
158
|
>
|
|
156
159
|
<!-- Type icon -->
|
|
157
160
|
<div class="text-muted-foreground flex h-8 w-8 shrink-0 items-center justify-center">
|
|
@@ -162,13 +165,20 @@
|
|
|
162
165
|
{/if}
|
|
163
166
|
</div>
|
|
164
167
|
|
|
165
|
-
<!-- Title + status dot (clickable to open referenced document) -->
|
|
168
|
+
<!-- Title (+ subtitle) + status dot (clickable to open referenced document) -->
|
|
166
169
|
<button
|
|
167
|
-
class="flex min-w-0 flex-1 cursor-pointer items-center gap-2 text-left"
|
|
170
|
+
class="flex min-w-0 flex-1 cursor-pointer items-center gap-2 py-1 text-left"
|
|
168
171
|
onclick={openReference}
|
|
169
172
|
title="Open referenced document"
|
|
170
173
|
>
|
|
171
|
-
<span class="
|
|
174
|
+
<span class="flex min-w-0 flex-1 flex-col">
|
|
175
|
+
<span class="truncate text-sm">{getDocumentTitle(selectedDocument)}</span>
|
|
176
|
+
{#if getDocumentSubtitle(selectedDocument)}
|
|
177
|
+
<span class="text-muted-foreground truncate text-xs"
|
|
178
|
+
>{getDocumentSubtitle(selectedDocument)}</span
|
|
179
|
+
>
|
|
180
|
+
{/if}
|
|
181
|
+
</span>
|
|
172
182
|
{#if selectedDocument.status === 'published'}
|
|
173
183
|
<span class="h-1.5 w-1.5 shrink-0 rounded-full bg-green-500" title="Published"></span>
|
|
174
184
|
{:else if selectedDocument.status === 'unpublished'}
|
|
@@ -261,7 +271,14 @@
|
|
|
261
271
|
<CheckIcon
|
|
262
272
|
class={cn('h-4 w-4 shrink-0', value !== doc.id && 'text-transparent')}
|
|
263
273
|
/>
|
|
264
|
-
<span class="
|
|
274
|
+
<span class="flex min-w-0 flex-1 flex-col">
|
|
275
|
+
<span class="truncate text-sm">{getDocumentTitle(doc)}</span>
|
|
276
|
+
{#if getDocumentSubtitle(doc)}
|
|
277
|
+
<span class="text-muted-foreground truncate text-xs"
|
|
278
|
+
>{getDocumentSubtitle(doc)}</span
|
|
279
|
+
>
|
|
280
|
+
{/if}
|
|
281
|
+
</span>
|
|
265
282
|
</div>
|
|
266
283
|
{#if doc.status === 'published'}
|
|
267
284
|
<span class="h-1.5 w-1.5 shrink-0 rounded-full bg-green-500" title="Published"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReferenceField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ReferenceField.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,KAAK,EAAwC,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"ReferenceField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ReferenceField.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,KAAK,EAAwC,MAAM,wBAAwB,CAAC;AAUzF,UAAU,KAAK;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAiRF,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -24,5 +24,16 @@ export interface CMSInstances {
|
|
|
24
24
|
graphqlSettings?: GraphQLSettings | null;
|
|
25
25
|
apiApp: Hono<AphexEnv>;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Called by the Vite HMR plugin (`@aphexcms/cms-core/vite`) when schema
|
|
29
|
+
* files or `aphex.config.ts` change. Replaces the captured config with the
|
|
30
|
+
* freshly re-evaluated module and marks instances for re-initialization on
|
|
31
|
+
* the next request — no Vite dev-server restart required.
|
|
32
|
+
*
|
|
33
|
+
* Module-level state means the Vite plugin and the running SvelteKit hook
|
|
34
|
+
* share the same cms-core instance through Vite's module graph, so this
|
|
35
|
+
* setter mutates the same `activeConfig` the hook reads on each request.
|
|
36
|
+
*/
|
|
37
|
+
export declare function __notifyAphexConfigChanged(newConfig: CMSConfig): void;
|
|
27
38
|
export declare function createCMSHook(config: CMSConfig): Handle;
|
|
28
39
|
//# sourceMappingURL=hooks.d.ts.map
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAa,SAAS,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAIN,KAAK,QAAQ,EACb,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAa,SAAS,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAIN,KAAK,QAAQ,EACb,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;CACvB;AAQD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAGrE;AAgBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAwJvD"}
|
package/dist/hooks.js
CHANGED
|
@@ -9,16 +9,27 @@ import { createAphexApi, mountAphexBuiltins, toHonoHandler } from './server/api/
|
|
|
9
9
|
let cmsInstances = null;
|
|
10
10
|
let schemaError = null;
|
|
11
11
|
let initPromise = null;
|
|
12
|
+
let activeConfig = null;
|
|
13
|
+
let configDirty = false;
|
|
12
14
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
+
* Called by the Vite HMR plugin (`@aphexcms/cms-core/vite`) when schema
|
|
16
|
+
* files or `aphex.config.ts` change. Replaces the captured config with the
|
|
17
|
+
* freshly re-evaluated module and marks instances for re-initialization on
|
|
18
|
+
* the next request — no Vite dev-server restart required.
|
|
19
|
+
*
|
|
20
|
+
* Module-level state means the Vite plugin and the running SvelteKit hook
|
|
21
|
+
* share the same cms-core instance through Vite's module graph, so this
|
|
22
|
+
* setter mutates the same `activeConfig` the hook reads on each request.
|
|
15
23
|
*/
|
|
24
|
+
export function __notifyAphexConfigChanged(newConfig) {
|
|
25
|
+
activeConfig = newConfig;
|
|
26
|
+
configDirty = true;
|
|
27
|
+
}
|
|
16
28
|
function checkSchemasDirty() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return dirty;
|
|
29
|
+
if (!configDirty)
|
|
30
|
+
return false;
|
|
31
|
+
configDirty = false;
|
|
32
|
+
return true;
|
|
22
33
|
}
|
|
23
34
|
// Factory function to create the default local storage adapter
|
|
24
35
|
function createDefaultStorageAdapter() {
|
|
@@ -35,7 +46,13 @@ export function createCMSHook(config) {
|
|
|
35
46
|
// Apply log level from config (if provided)
|
|
36
47
|
if (config.logLevel)
|
|
37
48
|
setLogLevel(config.logLevel);
|
|
49
|
+
// Stash the config in module scope so the HMR plugin can replace it via
|
|
50
|
+
// __notifyAphexConfigChanged() without going through this factory again.
|
|
51
|
+
activeConfig = config;
|
|
38
52
|
return async ({ event, resolve }) => {
|
|
53
|
+
// Use the latest config that the HMR plugin handed us; falls back to
|
|
54
|
+
// the one captured at hook construction time.
|
|
55
|
+
const currentConfig = activeConfig ?? config;
|
|
39
56
|
// Note: In dev mode, /storage/ might be accessible via Vite dev server
|
|
40
57
|
// In production, only /static/ folder is served - /storage/ is private
|
|
41
58
|
// Initialize CMS instances once at application startup
|
|
@@ -59,20 +76,20 @@ export function createCMSHook(config) {
|
|
|
59
76
|
let resolveInit;
|
|
60
77
|
initPromise = new Promise((r) => (resolveInit = r));
|
|
61
78
|
cmsLogger.info('[CMS]', 'Initializing...');
|
|
62
|
-
const databaseAdapter =
|
|
79
|
+
const databaseAdapter = currentConfig.database;
|
|
63
80
|
// Use the storage adapter from config, or create the default local one.
|
|
64
|
-
const storageAdapter =
|
|
65
|
-
const emailAdapter =
|
|
81
|
+
const storageAdapter = currentConfig.storage ?? createDefaultStorageAdapter();
|
|
82
|
+
const emailAdapter = currentConfig.email ?? null;
|
|
66
83
|
const assetService = new AssetServiceClass(storageAdapter, databaseAdapter);
|
|
67
|
-
const cmsEngine = createCMS(
|
|
68
|
-
const rolesService = new RolesService(databaseAdapter,
|
|
84
|
+
const cmsEngine = createCMS(currentConfig, databaseAdapter);
|
|
85
|
+
const rolesService = new RolesService(databaseAdapter, currentConfig.cache ?? null);
|
|
69
86
|
// Initialize Local API (unified operations layer)
|
|
70
|
-
const localAPI = createLocalAPI(
|
|
87
|
+
const localAPI = createLocalAPI(currentConfig, databaseAdapter);
|
|
71
88
|
// Build the Hono API app shell. User middleware/overrides register
|
|
72
89
|
// FIRST (so they sit ahead of built-ins in the chain), then we mount
|
|
73
90
|
// the built-in routes, then GraphQL.
|
|
74
91
|
const apiApp = createAphexApi();
|
|
75
|
-
|
|
92
|
+
currentConfig.api?.(apiApp);
|
|
76
93
|
mountAphexBuiltins(apiApp);
|
|
77
94
|
// Initialize schemas with validation
|
|
78
95
|
try {
|
|
@@ -84,12 +101,12 @@ export function createCMSHook(config) {
|
|
|
84
101
|
}
|
|
85
102
|
// Initialize built-in GraphQL (enabled by default, opt-out with graphql: false)
|
|
86
103
|
let graphqlSettings = null;
|
|
87
|
-
if (
|
|
104
|
+
if (currentConfig.graphql !== false) {
|
|
88
105
|
try {
|
|
89
106
|
const { createGraphQLHandler } = await import('./graphql/index.js');
|
|
90
|
-
const graphqlConfig = typeof
|
|
107
|
+
const graphqlConfig = typeof currentConfig.graphql === 'object' ? currentConfig.graphql : {};
|
|
91
108
|
const result = await createGraphQLHandler({
|
|
92
|
-
config,
|
|
109
|
+
config: currentConfig,
|
|
93
110
|
databaseAdapter,
|
|
94
111
|
assetService,
|
|
95
112
|
storageAdapter,
|
|
@@ -97,9 +114,9 @@ export function createCMSHook(config) {
|
|
|
97
114
|
cmsEngine,
|
|
98
115
|
localAPI,
|
|
99
116
|
rolesService,
|
|
100
|
-
auth:
|
|
117
|
+
auth: currentConfig.auth?.provider,
|
|
101
118
|
apiApp
|
|
102
|
-
},
|
|
119
|
+
}, currentConfig.schemaTypes, graphqlConfig);
|
|
103
120
|
// Register GraphQL directly on the Hono app. The Yoga handler
|
|
104
121
|
// internally distinguishes GET (GraphiQL UI) from POST (queries),
|
|
105
122
|
// so we mount with `app.all()` and let it route by method.
|
|
@@ -120,7 +137,7 @@ export function createCMSHook(config) {
|
|
|
120
137
|
}
|
|
121
138
|
}
|
|
122
139
|
cmsInstances = {
|
|
123
|
-
config,
|
|
140
|
+
config: currentConfig,
|
|
124
141
|
databaseAdapter: databaseAdapter,
|
|
125
142
|
assetService: assetService,
|
|
126
143
|
storageAdapter: storageAdapter,
|
|
@@ -128,7 +145,7 @@ export function createCMSHook(config) {
|
|
|
128
145
|
cmsEngine: cmsEngine,
|
|
129
146
|
localAPI: localAPI,
|
|
130
147
|
rolesService,
|
|
131
|
-
auth:
|
|
148
|
+
auth: currentConfig.auth?.provider,
|
|
132
149
|
graphqlSettings,
|
|
133
150
|
apiApp
|
|
134
151
|
};
|
|
@@ -142,7 +159,7 @@ export function createCMSHook(config) {
|
|
|
142
159
|
event.locals.aphexCMS = cmsInstances;
|
|
143
160
|
// Auth protection if configured
|
|
144
161
|
if (cmsInstances.auth) {
|
|
145
|
-
const authResponse = await handleAuthHook(event,
|
|
162
|
+
const authResponse = await handleAuthHook(event, currentConfig, cmsInstances.auth, cmsInstances.databaseAdapter, cmsInstances.rolesService);
|
|
146
163
|
if (authResponse)
|
|
147
164
|
return authResponse;
|
|
148
165
|
}
|
package/dist/lib/hooks.d.ts
CHANGED
|
@@ -24,5 +24,16 @@ export interface CMSInstances {
|
|
|
24
24
|
graphqlSettings?: GraphQLSettings | null;
|
|
25
25
|
apiApp: Hono<AphexEnv>;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Called by the Vite HMR plugin (`@aphexcms/cms-core/vite`) when schema
|
|
29
|
+
* files or `aphex.config.ts` change. Replaces the captured config with the
|
|
30
|
+
* freshly re-evaluated module and marks instances for re-initialization on
|
|
31
|
+
* the next request — no Vite dev-server restart required.
|
|
32
|
+
*
|
|
33
|
+
* Module-level state means the Vite plugin and the running SvelteKit hook
|
|
34
|
+
* share the same cms-core instance through Vite's module graph, so this
|
|
35
|
+
* setter mutates the same `activeConfig` the hook reads on each request.
|
|
36
|
+
*/
|
|
37
|
+
export declare function __notifyAphexConfigChanged(newConfig: CMSConfig): void;
|
|
27
38
|
export declare function createCMSHook(config: CMSConfig): Handle;
|
|
28
39
|
//# sourceMappingURL=hooks.d.ts.map
|
package/dist/lib/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAa,SAAS,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAIN,KAAK,QAAQ,EACb,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAa,SAAS,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAIN,KAAK,QAAQ,EACb,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;CACvB;AAQD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAGrE;AAgBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAwJvD"}
|