@sevenfold/setto-client 0.2.9 → 0.3.3

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.
@@ -0,0 +1,20 @@
1
+ import { type ComponentType, type CSSProperties } from 'react';
2
+ export interface SettoIconProps {
3
+ /** i18n key storing the Lucide icon name, e.g. `problem.cards.complicated.icon`. */
4
+ k: string;
5
+ /** Map of icon name → Lucide component (provided by the host site). */
6
+ icons: Record<string, ComponentType<SettoIconRenderProps>>;
7
+ size?: number;
8
+ className?: string;
9
+ style?: CSSProperties;
10
+ }
11
+ export interface SettoIconRenderProps {
12
+ size?: number;
13
+ className?: string;
14
+ style?: CSSProperties;
15
+ }
16
+ /**
17
+ * Renders an icon whose identity is stored in i18n. In edit mode, click to open
18
+ * an icon browser and pick a replacement.
19
+ */
20
+ export declare function SettoIcon({ k, icons, size, className, style }: SettoIconProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,10 @@
1
+ import { type ImgHTMLAttributes } from 'react';
2
+ export interface SettoImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'src'> {
3
+ /** i18n key for the public URL path, e.g. `hero.illustrationSrc`. */
4
+ srcKey: string;
5
+ }
6
+ /**
7
+ * Renders an image whose src is stored in i18n. In edit mode, hover to upload
8
+ * a replacement — saved under `public/images/setto/` on publish.
9
+ */
10
+ export declare function SettoImage({ srcKey, alt, className, style, ...rest }: SettoImageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface SettoRepeaterProps {
3
+ /** List prefix in i18n, e.g. `faq.items`. */
4
+ itemsKey: string;
5
+ /** Default field values for a newly added item. */
6
+ defaultItem: Record<string, string>;
7
+ /** Label shown on add/remove controls. */
8
+ itemLabel?: string;
9
+ children: (itemKey: string, index: number) => ReactNode;
10
+ className?: string;
11
+ }
12
+ /**
13
+ * Renders a dynamic list from i18n. In edit mode, editors can add and remove items.
14
+ */
15
+ export declare function SettoRepeater({ itemsKey, defaultItem, itemLabel, children, className, }: SettoRepeaterProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,17 @@
1
+ import { type CSSProperties, type ReactNode } from 'react';
2
+ export interface PopoverPosition {
3
+ top: number;
4
+ left: number;
5
+ }
6
+ interface FloatingPopoverProps {
7
+ open: boolean;
8
+ anchorRef: React.RefObject<HTMLElement | null>;
9
+ onClose: () => void;
10
+ ariaLabel: string;
11
+ children: ReactNode;
12
+ style?: CSSProperties;
13
+ minWidth?: number;
14
+ }
15
+ /** Anchored popover portal used by icon picker and similar edit UI. */
16
+ export declare function FloatingPopover({ open, anchorRef, onClose, ariaLabel, children, style, minWidth, }: FloatingPopoverProps): import("react").ReactPortal | null;
17
+ export {};
package/dist/index.d.ts CHANGED
@@ -2,8 +2,14 @@ export { SettoProvider, useSetto } from './provider';
2
2
  export { T } from './T';
3
3
  export { SettoSection } from './SettoSection';
4
4
  export { SettoBlock } from './SettoBlock';
5
+ export { SettoIcon } from './SettoIcon';
6
+ export type { SettoIconProps, SettoIconRenderProps } from './SettoIcon';
7
+ export { SettoImage } from './SettoImage';
8
+ export type { SettoImageProps } from './SettoImage';
9
+ export { SettoRepeater } from './SettoRepeater';
10
+ export type { SettoRepeaterProps } from './SettoRepeater';
5
11
  export { useSectionTheme } from './use-section-theme';
6
12
  export { SettoAdminApp } from './admin/App';
7
13
  export { AuthGate } from './edit-mode/auth-gate';
8
- export type { SettoConfig, BrandColor, DeploymentRow, SiteRow, ContentFile, PublishResult, } from './types';
14
+ export type { SettoConfig, BrandColor, DeploymentRow, SiteRow, ContentFile, PublishFile, PublishResult, } from './types';
9
15
  export type { SectionSchema, SectionColorField } from './section-schema';
package/dist/lib/api.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { SupabaseClient } from '@supabase/supabase-js';
2
- import type { ContentFile, PublishResult } from '../types';
2
+ import type { ContentFile, PublishFile, PublishResult } from '../types';
3
+ import type { AssetDraft } from './asset-store';
3
4
  export declare function createApi(args: {
4
5
  apiUrl: string;
5
6
  supabase: SupabaseClient;
@@ -7,10 +8,10 @@ export declare function createApi(args: {
7
8
  getContent(siteId: string): Promise<{
8
9
  files: ContentFile[];
9
10
  }>;
10
- publish(siteId: string, files: Array<{
11
- path: string;
12
- content: string;
13
- }>, message?: string): Promise<PublishResult>;
11
+ publish(siteId: string, files: PublishFile[], options?: {
12
+ message?: string;
13
+ assets?: AssetDraft[];
14
+ }): Promise<PublishResult>;
14
15
  expireStaleDeployments(siteId: string): Promise<{
15
16
  expired: number;
16
17
  }>;
@@ -0,0 +1,45 @@
1
+ export interface AssetDraft {
2
+ /** i18n key for the image src, e.g. `hero.illustrationSrc`. */
3
+ srcKey: string;
4
+ /** GitHub repo path, e.g. `public/images/setto/hero-illustration-123.jpg`. */
5
+ repoPath: string;
6
+ /** Public URL path, e.g. `/images/setto/hero-illustration-123.jpg`. */
7
+ publicPath: string;
8
+ /** Src path before this upload (for revert). */
9
+ originalPublicPath: string;
10
+ /** Raw file bytes — published as binary via multipart, not base64 JSON. */
11
+ file: File;
12
+ /** Object URL for in-session preview. */
13
+ previewUrl: string;
14
+ }
15
+ export interface AssetStoreSnapshot {
16
+ drafts: Map<string, AssetDraft>;
17
+ version: number;
18
+ }
19
+ export declare const EMPTY_ASSET_STORE_SNAPSHOT: AssetStoreSnapshot;
20
+ type Listener = (snap: AssetStoreSnapshot) => void;
21
+ export declare class AssetStore {
22
+ private drafts;
23
+ private version;
24
+ private listeners;
25
+ private cachedSnapshot;
26
+ snapshot(): AssetStoreSnapshot;
27
+ subscribe(listener: Listener): () => void;
28
+ /** Returns a preview URL if a draft exists for this src key. */
29
+ getPreviewUrl(srcKey: string): string | null;
30
+ set(args: {
31
+ srcKey: string;
32
+ originalPublicPath: string;
33
+ repoPath: string;
34
+ publicPath: string;
35
+ file: File;
36
+ }): Promise<void>;
37
+ revert(srcKey: string): string | null;
38
+ revertAll(): void;
39
+ commit(): void;
40
+ size(): number;
41
+ pendingAssets(): AssetDraft[];
42
+ static isValidRepoPath(path: string): boolean;
43
+ private bump;
44
+ }
45
+ export {};
@@ -63,6 +63,17 @@ export declare class I18nStore {
63
63
  commit(): void;
64
64
  /** Number of pending draft entries across all languages. */
65
65
  size(): number;
66
+ /** Returns sorted item keys under a list prefix, e.g. `faq.items` → ['1','2',…]. */
67
+ getListKeys(prefix: string, lng: string): string[];
68
+ /**
69
+ * Adds a new list item under `prefix` with the given field defaults.
70
+ * Adds the same key across all loaded languages.
71
+ */
72
+ addListItem(prefix: string, _lng: string, template: Record<string, string>): string;
73
+ /** Removes a list item and all nested keys under `prefix.itemKey` in every language. */
74
+ removeListItem(prefix: string, itemKey: string, _lng: string): void;
75
+ /** Re-sorts list keys after removal (optional compaction — not used by default). */
76
+ sortListKeys(prefix: string, lng: string): string[];
66
77
  /**
67
78
  * Serialises the full resource bundle per language as it currently looks in
68
79
  * i18next (with drafts applied). Used as the payload for /publish.
@@ -0,0 +1,12 @@
1
+ /** GitHub repo directory for editor-uploaded images. */
2
+ export declare const SETTO_IMAGE_REPO_DIR = "public/images/setto";
3
+ /** Public URL prefix served by the host site. */
4
+ export declare const SETTO_IMAGE_URL_PREFIX = "/images/setto";
5
+ export declare function extensionFromMime(mime: string): string;
6
+ /** Builds repo + public paths for a newly uploaded Setto image. */
7
+ export declare function generateSettoImagePaths(srcKey: string, file: File): {
8
+ repoPath: string;
9
+ publicPath: string;
10
+ };
11
+ /** Returns true when `path` matches an exact entry or a directory prefix entry. */
12
+ export declare function isContentPathAllowed(path: string, allowed: string[]): boolean;
@@ -0,0 +1,9 @@
1
+ /** Reads a dotted key path from a nested object. */
2
+ export declare function getNested(obj: unknown, key: string): unknown;
3
+ /** Sets a dotted key path on a nested object (mutates in place). */
4
+ export declare function setNested(obj: Record<string, unknown>, key: string, value: unknown): void;
5
+ /** Deletes a dotted key path from a nested object (mutates in place). */
6
+ export declare function deleteNested(obj: Record<string, unknown>, key: string): void;
7
+ /** Collects all dotted keys under a prefix from a nested object. */
8
+ export declare function collectKeysUnder(obj: unknown, prefix: string): string[];
9
+ export declare function compareListKeys(a: string, b: string): number;
@@ -2,6 +2,7 @@ import { type ReactNode } from 'react';
2
2
  import type { SupabaseClient, Session } from '@supabase/supabase-js';
3
3
  import { type SettoApi } from './lib/api';
4
4
  import { I18nStore } from './lib/i18n-store';
5
+ import { AssetStore } from './lib/asset-store';
5
6
  import { ThemeStore } from './lib/theme-store';
6
7
  import type { SettoConfig } from './types';
7
8
  interface SettoContextValue {
@@ -19,6 +20,7 @@ interface SettoContextValue {
19
20
  */
20
21
  store: I18nStore | null;
21
22
  themeStore: ThemeStore | null;
23
+ assetStore: AssetStore | null;
22
24
  }
23
25
  export interface SettoProviderProps {
24
26
  config: SettoConfig;