@velastack/cms 0.5.0 → 0.6.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/README.md +104 -47
- package/dist/backend/index.d.ts +7 -5
- package/dist/backend/index.js +7 -5
- package/dist/backend/types.d.ts +1 -1
- package/dist/components/admin-bar/admin-bar-internal.svelte +54 -59
- package/dist/components/admin-bar/admin-bar.css +1 -1
- package/dist/components/admin-bar/admin-bar.svelte +11 -7
- package/dist/components/admin-bar/field-input.svelte +20 -1
- package/dist/components/admin-bar/field-input.svelte.d.ts +2 -1
- package/dist/components/admin-bar/fields-form.svelte +218 -0
- package/dist/components/admin-bar/fields-form.svelte.d.ts +16 -0
- package/dist/components/admin-bar/history-panel.svelte +4 -4
- package/dist/components/admin-bar/link-input.svelte +102 -0
- package/dist/components/admin-bar/link-input.svelte.d.ts +9 -0
- package/dist/components/admin-bar/list-field.svelte +93 -0
- package/dist/components/admin-bar/list-field.svelte.d.ts +20 -0
- package/dist/components/admin-bar/locales-panel.svelte +1 -1
- package/dist/components/admin-bar/page-options.d.ts +24 -0
- package/dist/components/admin-bar/page-options.js +53 -0
- package/dist/components/admin-bar/pages-panel.svelte +1 -1
- package/dist/components/admin-bar/rich-text-input.svelte +92 -0
- package/dist/components/admin-bar/rich-text-input.svelte.d.ts +9 -0
- package/dist/components/admin-bar/structured-editor-popover.svelte +15 -6
- package/dist/components/admin-bar/theme.svelte.js +1 -1
- package/dist/components/cms/cms-collection.svelte +46 -0
- package/dist/components/cms/cms-collection.svelte.d.ts +25 -0
- package/dist/components/cms/cms-contact.svelte +26 -0
- package/dist/components/cms/cms-contact.svelte.d.ts +14 -0
- package/dist/components/cms/cms-faq.svelte +22 -0
- package/dist/components/cms/cms-faq.svelte.d.ts +15 -0
- package/dist/components/cms/cms-gallery.svelte +31 -0
- package/dist/components/cms/cms-gallery.svelte.d.ts +16 -0
- package/dist/components/cms/cms-hours-editable.svelte +160 -0
- package/dist/components/cms/cms-hours-editable.svelte.d.ts +17 -0
- package/dist/components/cms/cms-hours.svelte +42 -0
- package/dist/components/cms/cms-hours.svelte.d.ts +19 -0
- package/dist/components/cms/cms-image.svelte +3 -25
- package/dist/components/cms/cms-image.svelte.d.ts +3 -11
- package/dist/components/cms/cms-link-editable.svelte +4 -60
- package/dist/components/cms/cms-link.svelte +3 -23
- package/dist/components/cms/cms-link.svelte.d.ts +3 -10
- package/dist/components/cms/cms-logos.svelte +29 -0
- package/dist/components/cms/cms-logos.svelte.d.ts +16 -0
- package/dist/components/cms/cms-nav.svelte +22 -0
- package/dist/components/cms/cms-nav.svelte.d.ts +15 -0
- package/dist/components/cms/cms-pricing.svelte +36 -0
- package/dist/components/cms/cms-pricing.svelte.d.ts +14 -0
- package/dist/components/cms/cms-schedule.svelte +35 -0
- package/dist/components/cms/cms-schedule.svelte.d.ts +16 -0
- package/dist/components/cms/cms-social-links.svelte +35 -0
- package/dist/components/cms/cms-social-links.svelte.d.ts +15 -0
- package/dist/components/cms/cms-stats.svelte +31 -0
- package/dist/components/cms/cms-stats.svelte.d.ts +16 -0
- package/dist/components/cms/cms-steps.svelte +31 -0
- package/dist/components/cms/cms-steps.svelte.d.ts +16 -0
- package/dist/components/cms/cms-store.svelte.js +8 -5
- package/dist/components/cms/cms-structured-editable.svelte +29 -0
- package/dist/components/cms/{cms-repeater-editable.svelte.d.ts → cms-structured-editable.svelte.d.ts} +12 -8
- package/dist/components/cms/cms-structured.svelte +50 -0
- package/dist/components/cms/cms-structured.svelte.d.ts +49 -0
- package/dist/components/cms/cms-team.svelte +22 -0
- package/dist/components/cms/cms-team.svelte.d.ts +15 -0
- package/dist/components/cms/cms-testimonials.svelte +36 -0
- package/dist/components/cms/cms-testimonials.svelte.d.ts +15 -0
- package/dist/components/cms/cms-timeline.svelte +35 -0
- package/dist/components/cms/cms-timeline.svelte.d.ts +16 -0
- package/dist/components/cms/index.d.ts +15 -1
- package/dist/components/cms/index.js +15 -1
- package/dist/core/cms-fetch.d.ts +16 -0
- package/dist/core/cms-fetch.js +24 -0
- package/dist/core/shapes/collection.d.ts +60 -0
- package/dist/core/shapes/collection.js +194 -0
- package/dist/core/shapes/contact.d.ts +70 -0
- package/dist/core/shapes/contact.js +214 -0
- package/dist/core/shapes/faq.d.ts +12 -0
- package/dist/core/shapes/faq.js +48 -0
- package/dist/core/shapes/form.d.ts +46 -0
- package/dist/core/shapes/form.js +7 -0
- package/dist/core/shapes/hours.d.ts +91 -0
- package/dist/core/shapes/hours.js +325 -0
- package/dist/core/shapes/image.d.ts +15 -0
- package/dist/core/shapes/image.js +27 -0
- package/dist/core/shapes/index.d.ts +31 -0
- package/dist/core/shapes/index.js +13 -0
- package/dist/core/shapes/link.d.ts +15 -0
- package/dist/core/shapes/link.js +42 -0
- package/dist/core/shapes/nav.d.ts +21 -0
- package/dist/core/shapes/nav.js +71 -0
- package/dist/core/shapes/presets.d.ts +65 -0
- package/dist/core/shapes/presets.js +152 -0
- package/dist/core/shapes/pricing.d.ts +40 -0
- package/dist/core/shapes/pricing.js +115 -0
- package/dist/core/shapes/social-links.d.ts +19 -0
- package/dist/core/shapes/social-links.js +83 -0
- package/dist/core/shapes/team.d.ts +22 -0
- package/dist/core/shapes/team.js +70 -0
- package/dist/core/shapes/testimonials.d.ts +24 -0
- package/dist/core/shapes/testimonials.js +86 -0
- package/dist/{components/cms → core}/structured-registry.d.ts +2 -2
- package/dist/core/structured.d.ts +33 -10
- package/dist/core/structured.js +98 -47
- package/dist/editor.d.ts +4 -0
- package/dist/editor.js +4 -0
- package/dist/index.d.ts +22 -8
- package/dist/index.js +24 -5
- package/dist/server/README.md +1 -1
- package/dist/server/api-adapter.js +1 -1
- package/dist/server/cms.d.ts +1 -1
- package/dist/server/cms.js +1 -1
- package/dist/server/load-cms.js +1 -1
- package/package.json +15 -11
- package/plugin/README.md +34 -4
- package/plugin/dist/adapter.d.ts +5 -5
- package/plugin/dist/adapter.js +21 -7
- package/plugin/dist/adapter.js.map +1 -1
- package/plugin/dist/build-state.d.ts +1 -0
- package/plugin/dist/build-state.js +10 -1
- package/plugin/dist/build-state.js.map +1 -1
- package/plugin/dist/build.d.ts +2 -2
- package/plugin/dist/build.js +8 -7
- package/plugin/dist/build.js.map +1 -1
- package/plugin/dist/index.js +5 -1
- package/plugin/dist/index.js.map +1 -1
- package/plugin/dist/manifest.d.ts +18 -0
- package/plugin/dist/manifest.js +78 -10
- package/plugin/dist/manifest.js.map +1 -1
- package/plugin/dist/transforms.d.ts +4 -4
- package/plugin/dist/transforms.js +4 -4
- package/dist/cms.d.ts +0 -6
- package/dist/cms.js +0 -27
- package/dist/components/cms/cms-repeater-editable.svelte +0 -137
- package/dist/components/cms/cms-repeater.svelte +0 -52
- package/dist/components/cms/cms-repeater.svelte.d.ts +0 -31
- /package/dist/{components/cms → core}/structured-registry.js +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** `CmsSocialLinks`: profile links; the template supplies the icons. */
|
|
3
|
+
export * from '../../core/shapes/social-links.js';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
import Structured from './cms-structured.svelte';
|
|
9
|
+
import {
|
|
10
|
+
cmsSocialLinks,
|
|
11
|
+
socialLinksView,
|
|
12
|
+
type CmsSocialLinksValue,
|
|
13
|
+
type SocialLinkView
|
|
14
|
+
} from '../../core/shapes/social-links.js';
|
|
15
|
+
|
|
16
|
+
type Props = {
|
|
17
|
+
name: string;
|
|
18
|
+
scope?: string;
|
|
19
|
+
/** The full value, or a bare item list. */
|
|
20
|
+
fallback?: Partial<CmsSocialLinksValue> | Array<Partial<CmsSocialLinksValue['items'][number]>>;
|
|
21
|
+
value?: unknown;
|
|
22
|
+
children: Snippet<[SocialLinkView[]]>;
|
|
23
|
+
};
|
|
24
|
+
let { name, scope, fallback, value, children }: Props = $props();
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<Structured
|
|
28
|
+
schema={cmsSocialLinks}
|
|
29
|
+
{name}
|
|
30
|
+
{scope}
|
|
31
|
+
{fallback}
|
|
32
|
+
{value}
|
|
33
|
+
view={socialLinksView}
|
|
34
|
+
{children}
|
|
35
|
+
/>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** `CmsSocialLinks`: profile links; the template supplies the icons. */
|
|
2
|
+
export * from '../../core/shapes/social-links.js';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import { type CmsSocialLinksValue, type SocialLinkView } from '../../core/shapes/social-links.js';
|
|
5
|
+
type Props = {
|
|
6
|
+
name: string;
|
|
7
|
+
scope?: string;
|
|
8
|
+
/** The full value, or a bare item list. */
|
|
9
|
+
fallback?: Partial<CmsSocialLinksValue> | Array<Partial<CmsSocialLinksValue['items'][number]>>;
|
|
10
|
+
value?: unknown;
|
|
11
|
+
children: Snippet<[SocialLinkView[]]>;
|
|
12
|
+
};
|
|
13
|
+
declare const CmsSocialLinks: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type CmsSocialLinks = ReturnType<typeof CmsSocialLinks>;
|
|
15
|
+
export default CmsSocialLinks;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** `CmsStats` preset: value, label, note. */
|
|
3
|
+
export type { CmsStatsValue, StatItem } from '../../core/shapes/presets.js';
|
|
4
|
+
export { cmsStats } from '../../core/shapes/presets.js';
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import type { Snippet } from 'svelte';
|
|
9
|
+
import Structured from './cms-structured.svelte';
|
|
10
|
+
import { cmsStats, type CmsStatsValue, type StatItem } from '../../core/shapes/presets.js';
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
name: string;
|
|
14
|
+
scope?: string;
|
|
15
|
+
/** The full value, or a bare item list. */
|
|
16
|
+
fallback?: Partial<CmsStatsValue> | Partial<StatItem>[];
|
|
17
|
+
value?: unknown;
|
|
18
|
+
children: Snippet<[StatItem[]]>;
|
|
19
|
+
};
|
|
20
|
+
let { name, scope, fallback, value, children }: Props = $props();
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<Structured
|
|
24
|
+
schema={cmsStats}
|
|
25
|
+
{name}
|
|
26
|
+
{scope}
|
|
27
|
+
{fallback}
|
|
28
|
+
{value}
|
|
29
|
+
view={(v: CmsStatsValue) => v.items}
|
|
30
|
+
{children}
|
|
31
|
+
/>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** `CmsStats` preset: value, label, note. */
|
|
2
|
+
export type { CmsStatsValue, StatItem } from '../../core/shapes/presets.js';
|
|
3
|
+
export { cmsStats } from '../../core/shapes/presets.js';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import { type CmsStatsValue, type StatItem } from '../../core/shapes/presets.js';
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
scope?: string;
|
|
9
|
+
/** The full value, or a bare item list. */
|
|
10
|
+
fallback?: Partial<CmsStatsValue> | Partial<StatItem>[];
|
|
11
|
+
value?: unknown;
|
|
12
|
+
children: Snippet<[StatItem[]]>;
|
|
13
|
+
};
|
|
14
|
+
declare const CmsStats: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type CmsStats = ReturnType<typeof CmsStats>;
|
|
16
|
+
export default CmsStats;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** `CmsSteps` preset: title, body, image. */
|
|
3
|
+
export type { CmsStepsValue, StepItem } from '../../core/shapes/presets.js';
|
|
4
|
+
export { cmsSteps } from '../../core/shapes/presets.js';
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import type { Snippet } from 'svelte';
|
|
9
|
+
import Structured from './cms-structured.svelte';
|
|
10
|
+
import { cmsSteps, type CmsStepsValue, type StepItem } from '../../core/shapes/presets.js';
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
name: string;
|
|
14
|
+
scope?: string;
|
|
15
|
+
/** The full value, or a bare item list. */
|
|
16
|
+
fallback?: Partial<CmsStepsValue> | Partial<StepItem>[];
|
|
17
|
+
value?: unknown;
|
|
18
|
+
children: Snippet<[StepItem[]]>;
|
|
19
|
+
};
|
|
20
|
+
let { name, scope, fallback, value, children }: Props = $props();
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<Structured
|
|
24
|
+
schema={cmsSteps}
|
|
25
|
+
{name}
|
|
26
|
+
{scope}
|
|
27
|
+
{fallback}
|
|
28
|
+
{value}
|
|
29
|
+
view={(v: CmsStepsValue) => v.items}
|
|
30
|
+
{children}
|
|
31
|
+
/>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** `CmsSteps` preset: title, body, image. */
|
|
2
|
+
export type { CmsStepsValue, StepItem } from '../../core/shapes/presets.js';
|
|
3
|
+
export { cmsSteps } from '../../core/shapes/presets.js';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import { type CmsStepsValue, type StepItem } from '../../core/shapes/presets.js';
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
scope?: string;
|
|
9
|
+
/** The full value, or a bare item list. */
|
|
10
|
+
fallback?: Partial<CmsStepsValue> | Partial<StepItem>[];
|
|
11
|
+
value?: unknown;
|
|
12
|
+
children: Snippet<[StepItem[]]>;
|
|
13
|
+
};
|
|
14
|
+
declare const CmsSteps: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type CmsSteps = ReturnType<typeof CmsSteps>;
|
|
16
|
+
export default CmsSteps;
|
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
* Locales panel passes an explicit locale to inspect other locales'
|
|
28
28
|
* working-copy state without switching the page.
|
|
29
29
|
*/
|
|
30
|
-
import { browser } from '$app/
|
|
30
|
+
import { browser } from '$app/env';
|
|
31
31
|
import { page } from '$app/state';
|
|
32
|
+
import { cmsFetch } from '../../core/cms-fetch.js';
|
|
32
33
|
import { mergeLocaleDocs, mergeLocaleEntries } from './locale-merge.js';
|
|
33
34
|
import { composeKey } from './overlay-sync.js';
|
|
34
35
|
import { get, has, mergeTree, set } from '../../core/path.js';
|
|
@@ -543,12 +544,14 @@ class CmsStore {
|
|
|
543
544
|
if (!res.ok)
|
|
544
545
|
throw new Error(`List failed (${res.status})`);
|
|
545
546
|
const data = (await res.json());
|
|
546
|
-
return {
|
|
547
|
+
return {
|
|
548
|
+
...data,
|
|
549
|
+
items: data.items.map((i) => resolveMediaItem(i, endpoint))
|
|
550
|
+
};
|
|
547
551
|
}
|
|
548
552
|
async deleteMedia(endpoint, id) {
|
|
549
|
-
const res = await
|
|
550
|
-
method: 'DELETE'
|
|
551
|
-
credentials: 'include'
|
|
553
|
+
const res = await cmsFetch(`${endpoint}/media/${id}`, {
|
|
554
|
+
method: 'DELETE'
|
|
552
555
|
});
|
|
553
556
|
if (!res.ok)
|
|
554
557
|
throw new Error(`Delete failed (${res.status})`);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends Record<string, unknown>">
|
|
2
|
+
/**
|
|
3
|
+
* The generic editable sibling of a structured component: the popover
|
|
4
|
+
* over the shape's declared fields. Loaded lazily, only in edit mode.
|
|
5
|
+
*/
|
|
6
|
+
import type { Snippet } from 'svelte';
|
|
7
|
+
import type { FormShape } from '../../core/shapes/form.js';
|
|
8
|
+
import type { Tree } from '../../core/path.js';
|
|
9
|
+
import type { CmsField } from './use-cms-field.svelte.js';
|
|
10
|
+
import StructuredEditorPopover from '../admin-bar/structured-editor-popover.svelte';
|
|
11
|
+
import FieldsForm from '../admin-bar/fields-form.svelte';
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
field: CmsField<T>;
|
|
15
|
+
schema: FormShape<T>;
|
|
16
|
+
preview: Snippet;
|
|
17
|
+
};
|
|
18
|
+
let { field, schema, preview }: Props = $props();
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<StructuredEditorPopover {field} {schema} label={schema.label} {preview}>
|
|
22
|
+
{#snippet editor(draft: T, update: (next: T) => void)}
|
|
23
|
+
<FieldsForm
|
|
24
|
+
fields={schema.fields}
|
|
25
|
+
value={draft as Tree}
|
|
26
|
+
onChange={(next) => update(next as T)}
|
|
27
|
+
/>
|
|
28
|
+
{/snippet}
|
|
29
|
+
</StructuredEditorPopover>
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The generic editable sibling of a structured component: the popover
|
|
3
|
+
* over the shape's declared fields. Loaded lazily, only in edit mode.
|
|
4
|
+
*/
|
|
1
5
|
import type { Snippet } from 'svelte';
|
|
2
|
-
import {
|
|
6
|
+
import type { FormShape } from '../../core/shapes/form.js';
|
|
7
|
+
import type { CmsField } from './use-cms-field.svelte.js';
|
|
3
8
|
declare function $$render<T extends Record<string, unknown>>(): {
|
|
4
9
|
props: {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
children: Snippet<[T, number]>;
|
|
10
|
+
field: CmsField<T>;
|
|
11
|
+
schema: FormShape<T>;
|
|
12
|
+
preview: Snippet;
|
|
9
13
|
};
|
|
10
14
|
exports: {};
|
|
11
15
|
bindings: "";
|
|
@@ -26,6 +30,6 @@ interface $$IsomorphicComponent {
|
|
|
26
30
|
<T extends Record<string, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
27
31
|
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
28
32
|
}
|
|
29
|
-
declare const
|
|
30
|
-
type
|
|
31
|
-
export default
|
|
33
|
+
declare const CmsStructuredEditable: $$IsomorphicComponent;
|
|
34
|
+
type CmsStructuredEditable<T extends Record<string, unknown>> = InstanceType<typeof CmsStructuredEditable<T>>;
|
|
35
|
+
export default CmsStructuredEditable;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends Record<string, unknown>, V">
|
|
2
|
+
/**
|
|
3
|
+
* The one display component behind every structured editor component.
|
|
4
|
+
* It reads the value through the shape, derives the template's view of
|
|
5
|
+
* it and renders `children(view)`; in edit mode it swaps in the lazily
|
|
6
|
+
* loaded editable sibling (the generic form, or a bespoke one).
|
|
7
|
+
*/
|
|
8
|
+
import type { Component, Snippet } from 'svelte';
|
|
9
|
+
import type { FormShape } from '../../core/shapes/form.js';
|
|
10
|
+
import { useCmsField, type CmsField } from './use-cms-field.svelte.js';
|
|
11
|
+
|
|
12
|
+
type EditableProps = { field: CmsField<T>; schema: FormShape<T>; preview: Snippet };
|
|
13
|
+
type Props = {
|
|
14
|
+
schema: FormShape<T>;
|
|
15
|
+
name: string;
|
|
16
|
+
scope?: string;
|
|
17
|
+
fallback?: unknown;
|
|
18
|
+
value?: unknown;
|
|
19
|
+
view: (value: T) => V;
|
|
20
|
+
children: Snippet<[V]>;
|
|
21
|
+
/** Loader for a bespoke editable sibling; defaults to the generic form. */
|
|
22
|
+
editable?: () => Promise<{ default: Component<EditableProps> }>;
|
|
23
|
+
};
|
|
24
|
+
let { schema, name, scope, fallback, value, view, children, editable }: Props = $props();
|
|
25
|
+
|
|
26
|
+
const field = useCmsField(
|
|
27
|
+
() => ({ name, scope, value }),
|
|
28
|
+
(raw) => schema.read(raw, fallback as T | undefined)
|
|
29
|
+
);
|
|
30
|
+
const current = $derived(view(field.current));
|
|
31
|
+
const load = $derived(
|
|
32
|
+
editable ??
|
|
33
|
+
(() =>
|
|
34
|
+
import('./cms-structured-editable.svelte') as unknown as Promise<{
|
|
35
|
+
default: Component<EditableProps>;
|
|
36
|
+
}>)
|
|
37
|
+
);
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
{#snippet preview()}
|
|
41
|
+
{@render children(current)}
|
|
42
|
+
{/snippet}
|
|
43
|
+
|
|
44
|
+
{#if field.editable}
|
|
45
|
+
{#await load() then { default: Editable }}
|
|
46
|
+
<Editable {field} {schema} {preview} />
|
|
47
|
+
{/await}
|
|
48
|
+
{:else}
|
|
49
|
+
{@render children(current)}
|
|
50
|
+
{/if}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one display component behind every structured editor component.
|
|
3
|
+
* It reads the value through the shape, derives the template's view of
|
|
4
|
+
* it and renders `children(view)`; in edit mode it swaps in the lazily
|
|
5
|
+
* loaded editable sibling (the generic form, or a bespoke one).
|
|
6
|
+
*/
|
|
7
|
+
import type { Component, Snippet } from 'svelte';
|
|
8
|
+
import type { FormShape } from '../../core/shapes/form.js';
|
|
9
|
+
import { type CmsField } from './use-cms-field.svelte.js';
|
|
10
|
+
declare function $$render<T extends Record<string, unknown>, V>(): {
|
|
11
|
+
props: {
|
|
12
|
+
schema: FormShape<T>;
|
|
13
|
+
name: string;
|
|
14
|
+
scope?: string;
|
|
15
|
+
fallback?: unknown;
|
|
16
|
+
value?: unknown;
|
|
17
|
+
view: (value: T) => V;
|
|
18
|
+
children: Snippet<[V]>;
|
|
19
|
+
/** Loader for a bespoke editable sibling; defaults to the generic form. */
|
|
20
|
+
editable?: () => Promise<{
|
|
21
|
+
default: Component<{
|
|
22
|
+
field: CmsField<T>;
|
|
23
|
+
schema: FormShape<T>;
|
|
24
|
+
preview: Snippet;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
28
|
+
exports: {};
|
|
29
|
+
bindings: "";
|
|
30
|
+
slots: {};
|
|
31
|
+
events: {};
|
|
32
|
+
};
|
|
33
|
+
declare class __sveltets_Render<T extends Record<string, unknown>, V> {
|
|
34
|
+
props(): ReturnType<typeof $$render<T, V>>['props'];
|
|
35
|
+
events(): ReturnType<typeof $$render<T, V>>['events'];
|
|
36
|
+
slots(): ReturnType<typeof $$render<T, V>>['slots'];
|
|
37
|
+
bindings(): "";
|
|
38
|
+
exports(): {};
|
|
39
|
+
}
|
|
40
|
+
interface $$IsomorphicComponent {
|
|
41
|
+
new <T extends Record<string, unknown>, V>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T, V>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T, V>['props']>, ReturnType<__sveltets_Render<T, V>['events']>, ReturnType<__sveltets_Render<T, V>['slots']>> & {
|
|
42
|
+
$$bindings?: ReturnType<__sveltets_Render<T, V>['bindings']>;
|
|
43
|
+
} & ReturnType<__sveltets_Render<T, V>['exports']>;
|
|
44
|
+
<T extends Record<string, unknown>, V>(internal: unknown, props: ReturnType<__sveltets_Render<T, V>['props']> & {}): ReturnType<__sveltets_Render<T, V>['exports']>;
|
|
45
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
46
|
+
}
|
|
47
|
+
declare const CmsStructured: $$IsomorphicComponent;
|
|
48
|
+
type CmsStructured<T extends Record<string, unknown>, V> = InstanceType<typeof CmsStructured<T, V>>;
|
|
49
|
+
export default CmsStructured;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** `CmsTeam`: people with a portrait, role and bio. */
|
|
3
|
+
export * from '../../core/shapes/team.js';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
import Structured from './cms-structured.svelte';
|
|
9
|
+
import { cmsTeam, teamView, type CmsTeamValue, type TeamMember } from '../../core/shapes/team.js';
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
name: string;
|
|
13
|
+
scope?: string;
|
|
14
|
+
/** The full value, or a bare item list. */
|
|
15
|
+
fallback?: Partial<CmsTeamValue> | Array<Partial<CmsTeamValue['items'][number]>>;
|
|
16
|
+
value?: unknown;
|
|
17
|
+
children: Snippet<[TeamMember[]]>;
|
|
18
|
+
};
|
|
19
|
+
let { name, scope, fallback, value, children }: Props = $props();
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<Structured schema={cmsTeam} {name} {scope} {fallback} {value} view={teamView} {children} />
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** `CmsTeam`: people with a portrait, role and bio. */
|
|
2
|
+
export * from '../../core/shapes/team.js';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import { type CmsTeamValue, type TeamMember } from '../../core/shapes/team.js';
|
|
5
|
+
type Props = {
|
|
6
|
+
name: string;
|
|
7
|
+
scope?: string;
|
|
8
|
+
/** The full value, or a bare item list. */
|
|
9
|
+
fallback?: Partial<CmsTeamValue> | Array<Partial<CmsTeamValue['items'][number]>>;
|
|
10
|
+
value?: unknown;
|
|
11
|
+
children: Snippet<[TeamMember[]]>;
|
|
12
|
+
};
|
|
13
|
+
declare const CmsTeam: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type CmsTeam = ReturnType<typeof CmsTeam>;
|
|
15
|
+
export default CmsTeam;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** `CmsTestimonials`: quotes with author, rating and source. */
|
|
3
|
+
export * from '../../core/shapes/testimonials.js';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
import Structured from './cms-structured.svelte';
|
|
9
|
+
import {
|
|
10
|
+
cmsTestimonials,
|
|
11
|
+
testimonialsView,
|
|
12
|
+
type CmsTestimonialsValue,
|
|
13
|
+
type Testimonial
|
|
14
|
+
} from '../../core/shapes/testimonials.js';
|
|
15
|
+
|
|
16
|
+
type Props = {
|
|
17
|
+
name: string;
|
|
18
|
+
scope?: string;
|
|
19
|
+
/** The full value, or a bare item list. */
|
|
20
|
+
fallback?:
|
|
21
|
+
Partial<CmsTestimonialsValue> | Array<Partial<CmsTestimonialsValue['items'][number]>>;
|
|
22
|
+
value?: unknown;
|
|
23
|
+
children: Snippet<[Testimonial[]]>;
|
|
24
|
+
};
|
|
25
|
+
let { name, scope, fallback, value, children }: Props = $props();
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<Structured
|
|
29
|
+
schema={cmsTestimonials}
|
|
30
|
+
{name}
|
|
31
|
+
{scope}
|
|
32
|
+
{fallback}
|
|
33
|
+
{value}
|
|
34
|
+
view={testimonialsView}
|
|
35
|
+
{children}
|
|
36
|
+
/>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** `CmsTestimonials`: quotes with author, rating and source. */
|
|
2
|
+
export * from '../../core/shapes/testimonials.js';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import { type CmsTestimonialsValue, type Testimonial } from '../../core/shapes/testimonials.js';
|
|
5
|
+
type Props = {
|
|
6
|
+
name: string;
|
|
7
|
+
scope?: string;
|
|
8
|
+
/** The full value, or a bare item list. */
|
|
9
|
+
fallback?: Partial<CmsTestimonialsValue> | Array<Partial<CmsTestimonialsValue['items'][number]>>;
|
|
10
|
+
value?: unknown;
|
|
11
|
+
children: Snippet<[Testimonial[]]>;
|
|
12
|
+
};
|
|
13
|
+
declare const CmsTestimonials: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type CmsTestimonials = ReturnType<typeof CmsTestimonials>;
|
|
15
|
+
export default CmsTestimonials;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** `CmsTimeline` preset: date, title, body, image. */
|
|
3
|
+
export type { CmsTimelineValue, TimelineItem } from '../../core/shapes/presets.js';
|
|
4
|
+
export { cmsTimeline } from '../../core/shapes/presets.js';
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import type { Snippet } from 'svelte';
|
|
9
|
+
import Structured from './cms-structured.svelte';
|
|
10
|
+
import {
|
|
11
|
+
cmsTimeline,
|
|
12
|
+
type CmsTimelineValue,
|
|
13
|
+
type TimelineItem
|
|
14
|
+
} from '../../core/shapes/presets.js';
|
|
15
|
+
|
|
16
|
+
type Props = {
|
|
17
|
+
name: string;
|
|
18
|
+
scope?: string;
|
|
19
|
+
/** The full value, or a bare item list. */
|
|
20
|
+
fallback?: Partial<CmsTimelineValue> | Partial<TimelineItem>[];
|
|
21
|
+
value?: unknown;
|
|
22
|
+
children: Snippet<[TimelineItem[]]>;
|
|
23
|
+
};
|
|
24
|
+
let { name, scope, fallback, value, children }: Props = $props();
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<Structured
|
|
28
|
+
schema={cmsTimeline}
|
|
29
|
+
{name}
|
|
30
|
+
{scope}
|
|
31
|
+
{fallback}
|
|
32
|
+
{value}
|
|
33
|
+
view={(v: CmsTimelineValue) => v.items}
|
|
34
|
+
{children}
|
|
35
|
+
/>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** `CmsTimeline` preset: date, title, body, image. */
|
|
2
|
+
export type { CmsTimelineValue, TimelineItem } from '../../core/shapes/presets.js';
|
|
3
|
+
export { cmsTimeline } from '../../core/shapes/presets.js';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import { type CmsTimelineValue, type TimelineItem } from '../../core/shapes/presets.js';
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
scope?: string;
|
|
9
|
+
/** The full value, or a bare item list. */
|
|
10
|
+
fallback?: Partial<CmsTimelineValue> | Partial<TimelineItem>[];
|
|
11
|
+
value?: unknown;
|
|
12
|
+
children: Snippet<[TimelineItem[]]>;
|
|
13
|
+
};
|
|
14
|
+
declare const CmsTimeline: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type CmsTimeline = ReturnType<typeof CmsTimeline>;
|
|
16
|
+
export default CmsTimeline;
|
|
@@ -7,7 +7,21 @@ export { default as CmsNumber } from './cms-number.svelte';
|
|
|
7
7
|
export { default as CmsDateTime } from './cms-date-time.svelte';
|
|
8
8
|
export { default as CmsLink } from './cms-link.svelte';
|
|
9
9
|
export type { CmsLinkValue, CmsLinkRenderProps } from './cms-link.svelte';
|
|
10
|
-
export { default as
|
|
10
|
+
export { default as CmsNav } from './cms-nav.svelte';
|
|
11
|
+
export { default as CmsHours } from './cms-hours.svelte';
|
|
12
|
+
export { default as CmsContact } from './cms-contact.svelte';
|
|
13
|
+
export { default as CmsSocialLinks } from './cms-social-links.svelte';
|
|
14
|
+
export { default as CmsCollection } from './cms-collection.svelte';
|
|
15
|
+
export { default as CmsTeam } from './cms-team.svelte';
|
|
16
|
+
export { default as CmsTestimonials } from './cms-testimonials.svelte';
|
|
17
|
+
export { default as CmsPricing } from './cms-pricing.svelte';
|
|
18
|
+
export { default as CmsFaq } from './cms-faq.svelte';
|
|
19
|
+
export { default as CmsStats } from './cms-stats.svelte';
|
|
20
|
+
export { default as CmsSteps } from './cms-steps.svelte';
|
|
21
|
+
export { default as CmsTimeline } from './cms-timeline.svelte';
|
|
22
|
+
export { default as CmsGallery } from './cms-gallery.svelte';
|
|
23
|
+
export { default as CmsLogos } from './cms-logos.svelte';
|
|
24
|
+
export { default as CmsSchedule } from './cms-schedule.svelte';
|
|
11
25
|
export { default as CmsEntries } from './cms-entries.svelte';
|
|
12
26
|
export { CMS_SCOPE, getCmsScope, getCmsValue } from './scope.js';
|
|
13
27
|
export type { CmsScope, CmsPayload, CmsEntry } from './scope.js';
|
|
@@ -6,6 +6,20 @@ export { default as CmsBoolean } from './cms-boolean.svelte';
|
|
|
6
6
|
export { default as CmsNumber } from './cms-number.svelte';
|
|
7
7
|
export { default as CmsDateTime } from './cms-date-time.svelte';
|
|
8
8
|
export { default as CmsLink } from './cms-link.svelte';
|
|
9
|
-
export { default as
|
|
9
|
+
export { default as CmsNav } from './cms-nav.svelte';
|
|
10
|
+
export { default as CmsHours } from './cms-hours.svelte';
|
|
11
|
+
export { default as CmsContact } from './cms-contact.svelte';
|
|
12
|
+
export { default as CmsSocialLinks } from './cms-social-links.svelte';
|
|
13
|
+
export { default as CmsCollection } from './cms-collection.svelte';
|
|
14
|
+
export { default as CmsTeam } from './cms-team.svelte';
|
|
15
|
+
export { default as CmsTestimonials } from './cms-testimonials.svelte';
|
|
16
|
+
export { default as CmsPricing } from './cms-pricing.svelte';
|
|
17
|
+
export { default as CmsFaq } from './cms-faq.svelte';
|
|
18
|
+
export { default as CmsStats } from './cms-stats.svelte';
|
|
19
|
+
export { default as CmsSteps } from './cms-steps.svelte';
|
|
20
|
+
export { default as CmsTimeline } from './cms-timeline.svelte';
|
|
21
|
+
export { default as CmsGallery } from './cms-gallery.svelte';
|
|
22
|
+
export { default as CmsLogos } from './cms-logos.svelte';
|
|
23
|
+
export { default as CmsSchedule } from './cms-schedule.svelte';
|
|
10
24
|
export { default as CmsEntries } from './cms-entries.svelte';
|
|
11
25
|
export { CMS_SCOPE, getCmsScope, getCmsValue } from './scope.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fetch` for the CMS endpoint's mutating routes, with the editor's session
|
|
3
|
+
* cookie (`credentials: 'include'`) unless the caller overrides it.
|
|
4
|
+
*
|
|
5
|
+
* SvelteKit 3 treats a cross-origin `POST`/`PUT`/`PATCH`/`DELETE` that has no
|
|
6
|
+
* `content-type` like a form submission, and rejects it with a 403 unless the
|
|
7
|
+
* site's origin is in the backend's `csrf.trustedOrigins`. The admin bar talks
|
|
8
|
+
* to a cross-origin endpoint whenever the CMS is hosted (velastack.dev), so a
|
|
9
|
+
* bodiless mutation gets `content-type: application/json`. That turns it into a
|
|
10
|
+
* CORS-preflighted request, which the backend's `cors` option already answers.
|
|
11
|
+
*
|
|
12
|
+
* A caller-set `content-type` is kept, and so is the browser's own for a
|
|
13
|
+
* `FormData`, `Blob` or `URLSearchParams` body: multipart uploads keep their
|
|
14
|
+
* boundary.
|
|
15
|
+
*/
|
|
16
|
+
export declare const cmsFetch: (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fetch` for the CMS endpoint's mutating routes, with the editor's session
|
|
3
|
+
* cookie (`credentials: 'include'`) unless the caller overrides it.
|
|
4
|
+
*
|
|
5
|
+
* SvelteKit 3 treats a cross-origin `POST`/`PUT`/`PATCH`/`DELETE` that has no
|
|
6
|
+
* `content-type` like a form submission, and rejects it with a 403 unless the
|
|
7
|
+
* site's origin is in the backend's `csrf.trustedOrigins`. The admin bar talks
|
|
8
|
+
* to a cross-origin endpoint whenever the CMS is hosted (velastack.dev), so a
|
|
9
|
+
* bodiless mutation gets `content-type: application/json`. That turns it into a
|
|
10
|
+
* CORS-preflighted request, which the backend's `cors` option already answers.
|
|
11
|
+
*
|
|
12
|
+
* A caller-set `content-type` is kept, and so is the browser's own for a
|
|
13
|
+
* `FormData`, `Blob` or `URLSearchParams` body: multipart uploads keep their
|
|
14
|
+
* boundary.
|
|
15
|
+
*/
|
|
16
|
+
export const cmsFetch = (input, init = {}) => {
|
|
17
|
+
const method = (init.method ?? 'GET').toUpperCase();
|
|
18
|
+
const headers = new Headers(init.headers);
|
|
19
|
+
const bodyHasOwnType = init.body != null && typeof init.body !== 'string';
|
|
20
|
+
if (method !== 'GET' && method !== 'HEAD' && !headers.has('content-type') && !bodyHasOwnType) {
|
|
21
|
+
headers.set('content-type', 'application/json');
|
|
22
|
+
}
|
|
23
|
+
return fetch(input, { credentials: 'include', ...init, headers });
|
|
24
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `CmsCollection`: services, rooms, programmes, tours, projects, case
|
|
3
|
+
* studies. One fixed core plus a `details` key-value list for kind-specific
|
|
4
|
+
* facts. Lists only: an item's `link` covers "read more".
|
|
5
|
+
*/
|
|
6
|
+
import type { Tree } from '../path.js';
|
|
7
|
+
import { type ListValue } from './form.js';
|
|
8
|
+
import { type CmsImageValue } from './image.js';
|
|
9
|
+
import { type CmsLinkValue } from './link.js';
|
|
10
|
+
export type CollectionDetail = {
|
|
11
|
+
id: string;
|
|
12
|
+
label: string;
|
|
13
|
+
value: string;
|
|
14
|
+
};
|
|
15
|
+
export type CollectionPrice = {
|
|
16
|
+
amount: number | null;
|
|
17
|
+
/** ISO 4217, e.g. `EUR`. */
|
|
18
|
+
currency: string;
|
|
19
|
+
/** `night`, `person`, `hour`… shown after the amount. */
|
|
20
|
+
period: string;
|
|
21
|
+
/** `from`, shown before the amount. */
|
|
22
|
+
prefix: string;
|
|
23
|
+
};
|
|
24
|
+
export type CollectionItem = {
|
|
25
|
+
id: string;
|
|
26
|
+
title: string;
|
|
27
|
+
summary: string;
|
|
28
|
+
body: string;
|
|
29
|
+
image: CmsImageValue | null;
|
|
30
|
+
gallery: CmsImageValue[];
|
|
31
|
+
price: CollectionPrice;
|
|
32
|
+
duration: string;
|
|
33
|
+
link: CmsLinkValue | null;
|
|
34
|
+
tags: string[];
|
|
35
|
+
features: string[];
|
|
36
|
+
featured: boolean;
|
|
37
|
+
hidden: boolean;
|
|
38
|
+
details: CollectionDetail[];
|
|
39
|
+
};
|
|
40
|
+
export type CmsCollectionValue = ListValue<CollectionItem>;
|
|
41
|
+
export type CollectionItemView = CollectionItem & {
|
|
42
|
+
href: string | null;
|
|
43
|
+
};
|
|
44
|
+
export declare const cmsCollection: import("./form.js").FormShape<CmsCollectionValue>;
|
|
45
|
+
export type CollectionSlice = {
|
|
46
|
+
/** At most this many items. */
|
|
47
|
+
limit?: number;
|
|
48
|
+
/** Only featured items. */
|
|
49
|
+
featured?: boolean;
|
|
50
|
+
/** Only items carrying this tag. */
|
|
51
|
+
tag?: string;
|
|
52
|
+
};
|
|
53
|
+
/** Visible items (not hidden, with a title), optionally sliced. */
|
|
54
|
+
export declare const collectionView: (value: CmsCollectionValue, slice?: CollectionSlice) => CollectionItemView[];
|
|
55
|
+
/** Every tag in use, in first-seen order. */
|
|
56
|
+
export declare const collectionTags: (value: CmsCollectionValue) => string[];
|
|
57
|
+
/** `from €120 / night`, or empty when there is no amount. */
|
|
58
|
+
export declare const formatCollectionPrice: (price: CollectionPrice, locale: string) => string;
|
|
59
|
+
/** A schema.org `ItemList` of the visible items. */
|
|
60
|
+
export declare const toItemList: (value: CmsCollectionValue, baseUrl?: string) => Tree;
|