fimo 0.12.0-staging.1 → 0.12.0-staging.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.
- package/assets/skills/fimo/SKILL.md +7 -5
- package/assets/skills/fimo-cli/SKILL.md +8 -16
- package/assets/skills/fimo-cli/references/agent-setup.md +13 -13
- package/assets/skills/fimo-cli/references/assets.md +2 -2
- package/assets/skills/fimo-cli/references/content.md +10 -10
- package/assets/skills/fimo-cli/references/forms.md +6 -6
- package/assets/skills/fimo-cli/references/init.md +1 -1
- package/assets/skills/fimo-cli/references/labels.md +3 -3
- package/assets/skills/fimo-cli/references/locales.md +1 -1
- package/assets/skills/fimo-code/SKILL.md +2 -2
- package/assets/skills/fimo-studio/SKILL.md +3 -1
- package/assets/skills/fimo-studio/references/ai-chat.md +1 -1
- package/assets/skills/fimo-studio/references/command-palette.md +31 -0
- package/dist/build/vite/plugins/content-sync.js +1 -1
- package/dist/cli/bundle.json +1 -1
- package/dist/cli/index.js +167 -58
- package/dist/runtime/labels/core.d.ts +18 -0
- package/dist/runtime/labels/core.js +15 -0
- package/dist/runtime/labels/fetch.d.ts +7 -0
- package/dist/runtime/labels/fetch.js +41 -0
- package/dist/runtime/next/client.d.ts +11 -3
- package/dist/runtime/next/client.js +9 -2
- package/dist/runtime/next/facade.d.ts +8 -0
- package/dist/runtime/next/facade.js +34 -0
- package/dist/runtime/next/labels.d.ts +7 -0
- package/dist/runtime/next/labels.js +9 -0
- package/dist/runtime/next/{Text.d.ts → primitives/Text.d.ts} +1 -1
- package/dist/runtime/next/{Text.js → primitives/Text.js} +1 -1
- package/dist/runtime/next/primitives/server.d.ts +9 -0
- package/dist/runtime/next/primitives/server.js +46 -0
- package/dist/runtime/next/provider.d.ts +5 -2
- package/dist/runtime/next/provider.js +18 -5
- package/dist/runtime/next/server.d.ts +8 -1
- package/dist/runtime/next/server.js +5 -1
- package/dist/runtime/primitives/index.d.ts +10 -10
- package/dist/runtime/primitives/index.js +10 -10
- package/dist/runtime/primitives/lib/image-optimization.d.ts +10 -1
- package/dist/runtime/primitives/lib/image-optimization.js +12 -12
- package/dist/runtime/primitives/lib/index.d.ts +0 -1
- package/dist/runtime/primitives/lib/index.js +0 -1
- package/dist/runtime/react/primitives/contracts.d.ts +56 -0
- package/dist/runtime/react/primitives/contracts.js +1 -0
- package/dist/runtime/react/primitives/editable/Boolean.d.ts +5 -0
- package/dist/runtime/react/primitives/editable/Boolean.js +11 -0
- package/dist/runtime/react/primitives/editable/Date.d.ts +4 -0
- package/dist/runtime/react/primitives/editable/Date.js +12 -0
- package/dist/runtime/react/primitives/editable/Image.d.ts +4 -0
- package/dist/runtime/react/primitives/editable/Image.js +10 -0
- package/dist/runtime/react/primitives/editable/Json.d.ts +5 -0
- package/dist/runtime/react/primitives/editable/Json.js +11 -0
- package/dist/runtime/react/primitives/editable/RichText.d.ts +4 -0
- package/dist/runtime/react/primitives/editable/RichText.js +11 -0
- package/dist/runtime/{primitives/components → react/primitives/editable}/Text.d.ts +3 -6
- package/dist/runtime/{primitives/components → react/primitives/editable}/Text.js +2 -1
- package/dist/runtime/react/primitives/editable/Video.d.ts +4 -0
- package/dist/runtime/react/primitives/editable/Video.js +10 -0
- package/dist/runtime/react/primitives/renderers/DateRenderer.d.ts +11 -0
- package/dist/runtime/react/primitives/renderers/DateRenderer.js +14 -0
- package/dist/runtime/react/primitives/renderers/ImageRenderer.d.ts +8 -0
- package/dist/runtime/react/primitives/renderers/ImageRenderer.js +50 -0
- package/dist/runtime/react/primitives/renderers/RichTextRenderer.d.ts +11 -0
- package/dist/runtime/{primitives/components/RichText.js → react/primitives/renderers/RichTextRenderer.js} +4 -6
- package/dist/runtime/{primitives/components → react/primitives/renderers}/StaticImage.d.ts +2 -11
- package/dist/runtime/{primitives/components → react/primitives/renderers}/StaticImage.js +5 -3
- package/dist/runtime/react/primitives/renderers/VideoRenderer.d.ts +8 -0
- package/dist/runtime/react/primitives/renderers/VideoRenderer.js +10 -0
- package/dist/runtime/{primitives/lib → react}/useFimoLiveValue.d.ts +3 -3
- package/dist/runtime/{primitives/lib → react}/useFimoLiveValue.js +3 -3
- package/dist/runtime/vite/primitives/Images.d.ts +4 -0
- package/dist/runtime/vite/primitives/Images.js +12 -0
- package/dist/runtime/{primitives → vite}/translations.d.ts +1 -1
- package/dist/runtime/{primitives → vite}/translations.js +1 -1
- package/dist/scripts/sync-schemas.d.ts +2 -1
- package/dist/scripts/sync-schemas.js +119 -67
- package/package.json +2 -1
- package/templates/react-router/AGENTS.md +4 -2
- package/templates/react-router/package.json +1 -1
- package/dist/runtime/primitives/components/Boolean.d.ts +0 -29
- package/dist/runtime/primitives/components/Boolean.js +0 -33
- package/dist/runtime/primitives/components/Date.d.ts +0 -30
- package/dist/runtime/primitives/components/Date.js +0 -43
- package/dist/runtime/primitives/components/Image.d.ts +0 -72
- package/dist/runtime/primitives/components/Image.js +0 -108
- package/dist/runtime/primitives/components/Json.d.ts +0 -25
- package/dist/runtime/primitives/components/Json.js +0 -29
- package/dist/runtime/primitives/components/RichText.d.ts +0 -9
- package/dist/runtime/primitives/components/Video.d.ts +0 -31
- package/dist/runtime/primitives/components/Video.js +0 -34
- package/dist/runtime/primitives/components/index.d.ts +0 -6
- package/dist/runtime/primitives/components/index.js +0 -5
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FimoString } from '../primitives/lib/index.js';
|
|
2
|
+
export interface LabelsSnapshot {
|
|
3
|
+
locale: string;
|
|
4
|
+
labels: Record<string, string>;
|
|
5
|
+
updatedAt: string | null;
|
|
6
|
+
}
|
|
7
|
+
export interface Labels {
|
|
8
|
+
locale: string;
|
|
9
|
+
snapshot: LabelsSnapshot;
|
|
10
|
+
t(key: string): FimoString;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build the shared label reader used by server `getLabels()` and client
|
|
14
|
+
* `useLabels()`. Missing keys stay editable but render as an empty string;
|
|
15
|
+
* snapshots never fall back across locales implicitly.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createLabels(snapshot: LabelsSnapshot): Labels;
|
|
18
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FimoString } from '../primitives/lib/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build the shared label reader used by server `getLabels()` and client
|
|
4
|
+
* `useLabels()`. Missing keys stay editable but render as an empty string;
|
|
5
|
+
* snapshots never fall back across locales implicitly.
|
|
6
|
+
*/
|
|
7
|
+
export function createLabels(snapshot) {
|
|
8
|
+
return {
|
|
9
|
+
locale: snapshot.locale,
|
|
10
|
+
snapshot,
|
|
11
|
+
t(key) {
|
|
12
|
+
return new FimoString(snapshot.labels[key] ?? '', `__labels.${snapshot.locale}.${key}.value`);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ContentRuntime } from '../content/client/runtime.js';
|
|
2
|
+
import { type Labels } from './core.js';
|
|
3
|
+
export interface GetLabelsOptions {
|
|
4
|
+
locale?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function fetchLabels(runtime: ContentRuntime, { locale: requestedLocale }?: GetLabelsOptions): Promise<Labels>;
|
|
7
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createLabels } from './core.js';
|
|
2
|
+
function dictionaryFrom(value) {
|
|
3
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
4
|
+
return {};
|
|
5
|
+
}
|
|
6
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === 'string'));
|
|
7
|
+
}
|
|
8
|
+
function snapshotFrom(body, requestedLocale) {
|
|
9
|
+
if (Array.isArray(body.data)) {
|
|
10
|
+
return {
|
|
11
|
+
locale: requestedLocale,
|
|
12
|
+
labels: Object.fromEntries(body.data.flatMap((row) => {
|
|
13
|
+
if (typeof row.key !== 'string') {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const value = typeof row.value === 'string' ? row.value : row.defaultValue;
|
|
17
|
+
return [[row.key, typeof value === 'string' ? value : '']];
|
|
18
|
+
})),
|
|
19
|
+
updatedAt: null,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const data = body.data;
|
|
23
|
+
return {
|
|
24
|
+
locale: typeof data?.locale === 'string' && data.locale.trim() ? data.locale : requestedLocale,
|
|
25
|
+
labels: dictionaryFrom(data?.labels),
|
|
26
|
+
updatedAt: typeof data?.updatedAt === 'string' ? data.updatedAt : null,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export async function fetchLabels(runtime, { locale: requestedLocale } = {}) {
|
|
30
|
+
const locale = requestedLocale?.trim() || runtime.defaultLocale();
|
|
31
|
+
const url = new URL('/labels', runtime.apiBase());
|
|
32
|
+
url.searchParams.set('locale', locale);
|
|
33
|
+
const response = await runtime.fetch(url, {
|
|
34
|
+
headers: runtime.headers({ Accept: 'application/json' }),
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new Error(`Failed to read Fimo labels (${response.status}).`);
|
|
38
|
+
}
|
|
39
|
+
const body = (await response.json());
|
|
40
|
+
return createLabels(snapshotFrom(body, locale));
|
|
41
|
+
}
|
|
@@ -9,8 +9,16 @@ export type { CollectionContentClient, InfiniteListResult, SingletonContentClien
|
|
|
9
9
|
export { createContentCore, createSingletonCore } from '../content/index.js';
|
|
10
10
|
export type { CollectionContentCore, CollectionPage, CollectionPageInfo, ContentClientConfig, ContentClientHandle, ContentModuleMeta, ContentModuleRef, ContentReadOptions, ContentResult, ContentRuntime, ContentSchema, ContentSchemaField, SingletonContentCore, } from '../content/index.js';
|
|
11
11
|
export { FIMO_PARTS, FIMO_SOURCE, FimoBoolean, FimoDate, FimoMedia, FimoRichText, FimoString, getFimoParts, getFimoSource, hasFimoSource, isFimoDate, isFimoString, } from '../content/index.js';
|
|
12
|
-
export {
|
|
12
|
+
export { Boolean } from '../react/primitives/editable/Boolean.js';
|
|
13
|
+
export { Date } from '../react/primitives/editable/Date.js';
|
|
14
|
+
export { Image } from '../react/primitives/editable/Image.js';
|
|
15
|
+
export { Json } from '../react/primitives/editable/Json.js';
|
|
16
|
+
export { RichText } from '../react/primitives/editable/RichText.js';
|
|
17
|
+
export { StaticImage } from '../react/primitives/renderers/StaticImage.js';
|
|
18
|
+
export { Text } from '../react/primitives/editable/Text.js';
|
|
19
|
+
export { Video } from '../react/primitives/editable/Video.js';
|
|
13
20
|
export type { BoolOps, DateOps, Field, Fields, FilterFor, FimoPart, FimoPolymorphicReference, FimoReference, FimoRichTextComponents, FimoRichTextContent, FimoRichTextMarkProps, FimoRichTextNodeProps, FimoSource, NullOnlyOps, NumberOps, Populate, Populated, PopulatedResult, Projected, ProjectedWithPopulate, Query, ReferenceField, ReferenceMap, ScalarOps, Sort, SortField, StringOps, Where, WithReferences, } from '../content/index.js';
|
|
14
|
-
export {
|
|
15
|
-
export type {
|
|
21
|
+
export { FimoProvider, useLabels } from './provider.js';
|
|
22
|
+
export type { FimoProviderProps } from './provider.js';
|
|
23
|
+
export type { Labels, LabelsSnapshot } from '../labels/core.js';
|
|
16
24
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -11,5 +11,12 @@ export function createSingletonClient(config) {
|
|
|
11
11
|
}
|
|
12
12
|
export { createContentCore, createSingletonCore } from '../content/index.js';
|
|
13
13
|
export { FIMO_PARTS, FIMO_SOURCE, FimoBoolean, FimoDate, FimoMedia, FimoRichText, FimoString, getFimoParts, getFimoSource, hasFimoSource, isFimoDate, isFimoString, } from '../content/index.js';
|
|
14
|
-
export {
|
|
15
|
-
export {
|
|
14
|
+
export { Boolean } from '../react/primitives/editable/Boolean.js';
|
|
15
|
+
export { Date } from '../react/primitives/editable/Date.js';
|
|
16
|
+
export { Image } from '../react/primitives/editable/Image.js';
|
|
17
|
+
export { Json } from '../react/primitives/editable/Json.js';
|
|
18
|
+
export { RichText } from '../react/primitives/editable/RichText.js';
|
|
19
|
+
export { StaticImage } from '../react/primitives/renderers/StaticImage.js';
|
|
20
|
+
export { Text } from '../react/primitives/editable/Text.js';
|
|
21
|
+
export { Video } from '../react/primitives/editable/Video.js';
|
|
22
|
+
export { FimoProvider, useLabels } from './provider.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContentClientHandle } from '../content/client/types.js';
|
|
2
|
+
export type NextContentRegistry = Readonly<Record<string, ContentClientHandle>>;
|
|
3
|
+
export interface CreateFimoOptions<TContent extends NextContentRegistry> {
|
|
4
|
+
content: TContent;
|
|
5
|
+
locale?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function createFimo<const TContent extends NextContentRegistry>({ content, locale, }: CreateFimoOptions<TContent>): TContent;
|
|
8
|
+
//# sourceMappingURL=facade.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function withLocale(options, locale) {
|
|
2
|
+
return { ...options, locale: options?.locale ?? locale };
|
|
3
|
+
}
|
|
4
|
+
function isCollectionClient(client) {
|
|
5
|
+
return 'list' in client && typeof client.list === 'function';
|
|
6
|
+
}
|
|
7
|
+
function isSingletonClient(client) {
|
|
8
|
+
return 'get' in client && typeof client.get === 'function';
|
|
9
|
+
}
|
|
10
|
+
function bindLocale(client, locale) {
|
|
11
|
+
if (isCollectionClient(client)) {
|
|
12
|
+
return {
|
|
13
|
+
...client,
|
|
14
|
+
getById: (id, options) => client.getById(id, withLocale(options, locale)),
|
|
15
|
+
getBySlug: (slug, options) => client.getBySlug(slug, withLocale(options, locale)),
|
|
16
|
+
getByField: (fieldName, value, options) => client.getByField(fieldName, value, withLocale(options, locale)),
|
|
17
|
+
list: (params) => client.list(withLocale(params, locale)),
|
|
18
|
+
get: (params) => client.get(withLocale(params, locale)),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (isSingletonClient(client)) {
|
|
22
|
+
return {
|
|
23
|
+
...client,
|
|
24
|
+
get: (options) => client.get(withLocale(options, locale)),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return client;
|
|
28
|
+
}
|
|
29
|
+
export function createFimo({ content, locale, }) {
|
|
30
|
+
if (locale === undefined) {
|
|
31
|
+
return content;
|
|
32
|
+
}
|
|
33
|
+
return Object.fromEntries(Object.entries(content).map(([key, client]) => [key, bindLocale(client, locale)]));
|
|
34
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type GetLabelsOptions } from '../labels/fetch.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read the labels for an application-resolved locale. When omitted, locale
|
|
4
|
+
* comes from FIMO_DEFAULT_LOCALE / NEXT_PUBLIC_FIMO_DEFAULT_LOCALE.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getLabels(options?: GetLabelsOptions): Promise<import("./client.js").Labels>;
|
|
7
|
+
//# sourceMappingURL=labels.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { fetchLabels } from '../labels/fetch.js';
|
|
2
|
+
import { nextServerContentRuntime } from './server-runtime.js';
|
|
3
|
+
/**
|
|
4
|
+
* Read the labels for an application-resolved locale. When omitted, locale
|
|
5
|
+
* comes from FIMO_DEFAULT_LOCALE / NEXT_PUBLIC_FIMO_DEFAULT_LOCALE.
|
|
6
|
+
*/
|
|
7
|
+
export function getLabels(options) {
|
|
8
|
+
return fetchLabels(nextServerContentRuntime, options);
|
|
9
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
|
-
import { getFimoParts, getFimoSource } from '
|
|
3
|
+
import { getFimoParts, getFimoSource } from '../../content/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Server-safe text primitive for Next.js Server Components.
|
|
6
6
|
*
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ElementType } from 'react';
|
|
2
|
+
import type { BooleanProps, DateProps, ImageProps, JsonProps, RichTextProps, VideoProps } from '../../react/primitives/contracts.js';
|
|
3
|
+
export declare function Boolean<T extends ElementType = 'span'>({ value, as, children, ...props }: BooleanProps<T>): import("react/jsx-runtime").JSX.Element | null;
|
|
4
|
+
export declare function Date({ value, ...props }: DateProps): import("react/jsx-runtime").JSX.Element | null;
|
|
5
|
+
export declare function Image(props: ImageProps): import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
export declare function Json<T extends ElementType = 'span'>({ value, as, children, ...props }: JsonProps<T>): import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
export declare function RichText({ value, components, ...props }: RichTextProps): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export declare function Video(props: VideoProps): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FIMO_SOURCE, getFimoSource } from '../../content/index.js';
|
|
3
|
+
import { DateRenderer } from '../../react/primitives/renderers/DateRenderer.js';
|
|
4
|
+
import { ImageRenderer } from '../../react/primitives/renderers/ImageRenderer.js';
|
|
5
|
+
import { RichTextRenderer } from '../../react/primitives/renderers/RichTextRenderer.js';
|
|
6
|
+
import { VideoRenderer } from '../../react/primitives/renderers/VideoRenderer.js';
|
|
7
|
+
export function Boolean({ value, as, children, ...props }) {
|
|
8
|
+
if (!value) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const Component = as || 'span';
|
|
12
|
+
const booleanValue = value.valueOf();
|
|
13
|
+
return (_jsx(Component, { ...props, "data-fimo-source": value[FIMO_SOURCE], children: children ? children(booleanValue) : String(booleanValue) }));
|
|
14
|
+
}
|
|
15
|
+
export function Date({ value, ...props }) {
|
|
16
|
+
if (!value) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const source = typeof value === 'object' && FIMO_SOURCE in value ? (value[FIMO_SOURCE] ?? undefined) : undefined;
|
|
20
|
+
return _jsx(DateRenderer, { ...props, value: value, source: source });
|
|
21
|
+
}
|
|
22
|
+
export function Image(props) {
|
|
23
|
+
if (!props.value) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return _jsx(ImageRenderer, { ...props });
|
|
27
|
+
}
|
|
28
|
+
export function Json({ value, as, children, ...props }) {
|
|
29
|
+
if (value === null || value === undefined) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const Component = as || 'span';
|
|
33
|
+
return (_jsx(Component, { ...props, "data-fimo-source": getFimoSource(value), children: children ? children(value) : JSON.stringify(value) }));
|
|
34
|
+
}
|
|
35
|
+
export function RichText({ value, components, ...props }) {
|
|
36
|
+
if (!value) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return _jsx(RichTextRenderer, { ...props, document: value.content, source: value[FIMO_SOURCE], components: components });
|
|
40
|
+
}
|
|
41
|
+
export function Video(props) {
|
|
42
|
+
if (!props.value) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return _jsx(VideoRenderer, { ...props });
|
|
46
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { QueryClient } from '@tanstack/react-query';
|
|
2
2
|
import { type ReactNode } from 'react';
|
|
3
|
-
|
|
3
|
+
import { type Labels, type LabelsSnapshot } from '../labels/core.js';
|
|
4
|
+
export interface FimoProviderProps {
|
|
4
5
|
children: ReactNode;
|
|
6
|
+
labels?: LabelsSnapshot;
|
|
5
7
|
locale?: string;
|
|
6
8
|
queryClient?: QueryClient;
|
|
7
9
|
}
|
|
8
|
-
export declare function
|
|
10
|
+
export declare function FimoProvider({ children, labels, locale, queryClient }: FimoProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
9
11
|
export declare function useNextContentLocale(requestedLocale: string | undefined, defaultLocale: string): string;
|
|
12
|
+
export declare function useLabels(): Labels;
|
|
10
13
|
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
4
|
-
import { createContext, useContext, useState } from 'react';
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import { createContext, useContext, useMemo, useState } from 'react';
|
|
5
|
+
import { createLabels } from '../labels/core.js';
|
|
6
|
+
import { nextClientContentRuntime } from './client-runtime.js';
|
|
7
|
+
const FimoNextContext = createContext({});
|
|
8
|
+
export function FimoProvider({ children, labels, locale, queryClient }) {
|
|
7
9
|
const [client] = useState(() => queryClient ?? new QueryClient());
|
|
8
|
-
|
|
10
|
+
const activeLocale = locale?.trim() || labels?.locale;
|
|
11
|
+
const value = useMemo(() => ({ labels, locale: activeLocale }), [activeLocale, labels]);
|
|
12
|
+
return (_jsx(FimoNextContext.Provider, { value: value, children: _jsx(QueryClientProvider, { client: client, children: children }) }));
|
|
9
13
|
}
|
|
10
14
|
export function useNextContentLocale(requestedLocale, defaultLocale) {
|
|
11
|
-
|
|
15
|
+
const context = useContext(FimoNextContext);
|
|
16
|
+
return requestedLocale ?? context.locale ?? defaultLocale;
|
|
17
|
+
}
|
|
18
|
+
export function useLabels() {
|
|
19
|
+
const context = useContext(FimoNextContext);
|
|
20
|
+
const locale = context.locale ?? nextClientContentRuntime.defaultLocale();
|
|
21
|
+
const snapshot = context.labels?.locale === locale
|
|
22
|
+
? context.labels
|
|
23
|
+
: { locale, labels: {}, updatedAt: null };
|
|
24
|
+
return useMemo(() => createLabels(snapshot), [snapshot]);
|
|
12
25
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { CollectionContentClient, ContentClientConfig, SingletonContentClient } from '../content/client/types.js';
|
|
2
|
-
export {
|
|
2
|
+
export { StaticImage } from '../react/primitives/renderers/StaticImage.js';
|
|
3
|
+
export { Text } from './primitives/Text.js';
|
|
4
|
+
export { Boolean, Date, Image, Json, RichText, Video } from './primitives/server.js';
|
|
5
|
+
export { createFimo } from './facade.js';
|
|
6
|
+
export type { CreateFimoOptions, NextContentRegistry } from './facade.js';
|
|
7
|
+
export { getLabels } from './labels.js';
|
|
8
|
+
export type { GetLabelsOptions } from '../labels/fetch.js';
|
|
9
|
+
export type { Labels, LabelsSnapshot } from '../labels/core.js';
|
|
3
10
|
export declare function createContentClient<T extends {
|
|
4
11
|
id: string;
|
|
5
12
|
}, TInput extends object>(config: ContentClientConfig): CollectionContentClient<T, TInput>;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createServerContentClient, createServerSingletonClient } from '../content/client/server-content-client.js';
|
|
2
2
|
import { nextServerContentRuntime } from './server-runtime.js';
|
|
3
|
-
export {
|
|
3
|
+
export { StaticImage } from '../react/primitives/renderers/StaticImage.js';
|
|
4
|
+
export { Text } from './primitives/Text.js';
|
|
5
|
+
export { Boolean, Date, Image, Json, RichText, Video } from './primitives/server.js';
|
|
6
|
+
export { createFimo } from './facade.js';
|
|
7
|
+
export { getLabels } from './labels.js';
|
|
4
8
|
export function createContentClient(config) {
|
|
5
9
|
return createServerContentClient(config, nextServerContentRuntime);
|
|
6
10
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export { Text } from '
|
|
2
|
-
export { Image } from '
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
1
|
+
export { Text } from '../react/primitives/editable/Text.js';
|
|
2
|
+
export { Image, StaticImage } from '../vite/primitives/Images.js';
|
|
3
|
+
export { Video } from '../react/primitives/editable/Video.js';
|
|
4
|
+
export { Date } from '../react/primitives/editable/Date.js';
|
|
5
|
+
export { Boolean } from '../react/primitives/editable/Boolean.js';
|
|
6
|
+
export { Json } from '../react/primitives/editable/Json.js';
|
|
7
|
+
export { RichText } from '../react/primitives/editable/RichText.js';
|
|
8
|
+
export { useLabels, useTranslations } from '../vite/translations.js';
|
|
9
|
+
export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, type FimoPolymorphicReference, type FimoReference, type FimoSource, type FimoPart, type FimoRichTextContent, type FimoRichTextNodeProps, type FimoRichTextMarkProps, type FimoRichTextComponents, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, fimo, } from './lib/index.js';
|
|
10
|
+
export { useFimoLiveValue } from '../react/useFimoLiveValue.js';
|
|
11
11
|
export type { BoolOps, DateOps, Field, Fields, FilterFor, NullOnlyOps, NumberOps, Populate, Populated, PopulatedResult, Projected, ProjectedWithPopulate, Query, ReferenceField, ReferenceMap, ScalarOps, Sort, SortField, StringOps, WithReferences, Where, } from './lib/index.js';
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// Fimo UI — components and primitives for source-tracked inline editing
|
|
2
2
|
// This module is auto-synced and should not be modified by agents or users.
|
|
3
3
|
// Components
|
|
4
|
-
export { Text } from '
|
|
5
|
-
export { Image } from '
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export { RichText } from './components/RichText.js';
|
|
4
|
+
export { Text } from '../react/primitives/editable/Text.js';
|
|
5
|
+
export { Image, StaticImage } from '../vite/primitives/Images.js';
|
|
6
|
+
export { Video } from '../react/primitives/editable/Video.js';
|
|
7
|
+
export { Date } from '../react/primitives/editable/Date.js';
|
|
8
|
+
export { Boolean } from '../react/primitives/editable/Boolean.js';
|
|
9
|
+
export { Json } from '../react/primitives/editable/Json.js';
|
|
10
|
+
export { RichText } from '../react/primitives/editable/RichText.js';
|
|
12
11
|
// Labels
|
|
13
|
-
export { useLabels, useTranslations } from '
|
|
12
|
+
export { useLabels, useTranslations } from '../vite/translations.js';
|
|
14
13
|
// Primitives & utilities
|
|
15
|
-
export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, fimo,
|
|
14
|
+
export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, fimo, } from './lib/index.js';
|
|
15
|
+
export { useFimoLiveValue } from '../react/useFimoLiveValue.js';
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
/** Default host suffixes eligible for Cloudflare Image Resizing optimization. */
|
|
3
|
+
export declare const DEFAULT_IMAGE_HOST_SUFFIXES: readonly [".fimo.team", ".fimo.ai", ".fimo.site"];
|
|
4
|
+
/**
|
|
5
|
+
* Get allowed host suffixes from env or use defaults.
|
|
6
|
+
* Env format: comma-separated suffixes, e.g. ".fimo.team,.fimo.ai,.fimo.site"
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseImageHostSuffixes(value: string | undefined): readonly string[];
|
|
2
9
|
export declare const DEFAULT_IMAGE_QUALITY = 85;
|
|
3
10
|
export declare const DEFAULT_IMAGE_FIT: "scale-down";
|
|
4
11
|
export declare const DEFAULT_IMAGE_DPRS: readonly [1, 2];
|
|
@@ -21,7 +28,7 @@ export declare function toObjectFit(fit: ImageFit): NonNullable<ComponentPropsWi
|
|
|
21
28
|
/** Parse value to positive integer, or undefined if invalid. */
|
|
22
29
|
export declare function toPositiveInt(value: string | number | undefined): number | undefined;
|
|
23
30
|
/** Check if URL can be optimized (valid http(s) URL on allowed host). */
|
|
24
|
-
export declare function isOptimizableFimoUrl(value: string): value is string;
|
|
31
|
+
export declare function isOptimizableFimoUrl(value: string, hostSuffixes?: readonly string[]): value is string;
|
|
25
32
|
/**
|
|
26
33
|
* Build optimized URL with Cloudflare Image Resizing query params.
|
|
27
34
|
* Adds: w (width), q (quality), fit, f (format=auto), dpr.
|
|
@@ -31,6 +38,7 @@ export declare function buildOptimizedUrl(src: string, options: {
|
|
|
31
38
|
quality: number;
|
|
32
39
|
fit: ImageFit;
|
|
33
40
|
dpr?: number;
|
|
41
|
+
hostSuffixes?: readonly string[];
|
|
34
42
|
}): string;
|
|
35
43
|
export type ImageOptimizationConfig = {
|
|
36
44
|
generatedSrcSet?: string;
|
|
@@ -46,5 +54,6 @@ export declare function computeImageOptimizationConfig(options: {
|
|
|
46
54
|
renderWidth: number | undefined;
|
|
47
55
|
quality: number;
|
|
48
56
|
fit: ImageFit;
|
|
57
|
+
hostSuffixes?: readonly string[];
|
|
49
58
|
}): ImageOptimizationConfig;
|
|
50
59
|
//# sourceMappingURL=image-optimization.d.ts.map
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/** Default host suffixes eligible for Cloudflare Image Resizing optimization. */
|
|
2
|
-
const DEFAULT_IMAGE_HOST_SUFFIXES = ['.fimo.team', '.fimo.ai', '.fimo.site'];
|
|
2
|
+
export const DEFAULT_IMAGE_HOST_SUFFIXES = ['.fimo.team', '.fimo.ai', '.fimo.site'];
|
|
3
3
|
/**
|
|
4
4
|
* Get allowed host suffixes from env or use defaults.
|
|
5
5
|
* Env format: comma-separated suffixes, e.g. ".fimo.team,.fimo.ai,.fimo.site"
|
|
6
6
|
*/
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (typeof envHosts === 'string' && envHosts.trim().length > 0) {
|
|
11
|
-
return envHosts.split(',').map((s) => s.trim());
|
|
7
|
+
export function parseImageHostSuffixes(value) {
|
|
8
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
9
|
+
return value.split(',').map((suffix) => suffix.trim());
|
|
12
10
|
}
|
|
13
11
|
return DEFAULT_IMAGE_HOST_SUFFIXES;
|
|
14
12
|
}
|
|
@@ -91,14 +89,14 @@ function parseHttpUrl(value) {
|
|
|
91
89
|
}
|
|
92
90
|
}
|
|
93
91
|
/** Check if hostname is eligible for Cloudflare optimization. */
|
|
94
|
-
function isAllowedHost(hostname) {
|
|
92
|
+
function isAllowedHost(hostname, hostSuffixes) {
|
|
95
93
|
const host = hostname.toLowerCase();
|
|
96
|
-
return
|
|
94
|
+
return hostSuffixes.some((suffix) => host.endsWith(suffix.toLowerCase()));
|
|
97
95
|
}
|
|
98
96
|
/** Check if URL can be optimized (valid http(s) URL on allowed host). */
|
|
99
|
-
export function isOptimizableFimoUrl(value) {
|
|
97
|
+
export function isOptimizableFimoUrl(value, hostSuffixes = DEFAULT_IMAGE_HOST_SUFFIXES) {
|
|
100
98
|
const url = parseHttpUrl(value);
|
|
101
|
-
return Boolean(url && isAllowedHost(url.hostname));
|
|
99
|
+
return Boolean(url && isAllowedHost(url.hostname, hostSuffixes));
|
|
102
100
|
}
|
|
103
101
|
/**
|
|
104
102
|
* Build optimized URL with Cloudflare Image Resizing query params.
|
|
@@ -106,7 +104,7 @@ export function isOptimizableFimoUrl(value) {
|
|
|
106
104
|
*/
|
|
107
105
|
export function buildOptimizedUrl(src, options) {
|
|
108
106
|
const parsed = parseHttpUrl(src);
|
|
109
|
-
if (!parsed || !isAllowedHost(parsed.hostname)) {
|
|
107
|
+
if (!parsed || !isAllowedHost(parsed.hostname, options.hostSuffixes ?? DEFAULT_IMAGE_HOST_SUFFIXES)) {
|
|
110
108
|
return src;
|
|
111
109
|
}
|
|
112
110
|
const transformed = new URL(parsed.toString());
|
|
@@ -152,7 +150,7 @@ function buildWidthSrcSet(src, options, widths) {
|
|
|
152
150
|
.join(', ');
|
|
153
151
|
}
|
|
154
152
|
export function computeImageOptimizationConfig(options) {
|
|
155
|
-
const { shouldOptimize, hasSizesAttr, srcSetOverride, originalSrc, mediaWidth, renderWidth, quality, fit } = options;
|
|
153
|
+
const { shouldOptimize, hasSizesAttr, srcSetOverride, originalSrc, mediaWidth, renderWidth, quality, fit, hostSuffixes, } = options;
|
|
156
154
|
if (!shouldOptimize || srcSetOverride != null) {
|
|
157
155
|
return {
|
|
158
156
|
generatedSrcSet: undefined,
|
|
@@ -166,6 +164,7 @@ export function computeImageOptimizationConfig(options) {
|
|
|
166
164
|
generatedSrcSet: buildWidthSrcSet(originalSrc, {
|
|
167
165
|
quality,
|
|
168
166
|
fit,
|
|
167
|
+
hostSuffixes,
|
|
169
168
|
}, responsiveWidths),
|
|
170
169
|
transformWidth: responsiveWidths[responsiveWidths.length - 1] ?? renderWidth,
|
|
171
170
|
transformDpr: undefined,
|
|
@@ -176,6 +175,7 @@ export function computeImageOptimizationConfig(options) {
|
|
|
176
175
|
width: renderWidth,
|
|
177
176
|
quality,
|
|
178
177
|
fit,
|
|
178
|
+
hostSuffixes,
|
|
179
179
|
}),
|
|
180
180
|
transformWidth: renderWidth,
|
|
181
181
|
transformDpr: renderWidth ? DEFAULT_IMAGE_DPRS[DEFAULT_IMAGE_DPRS.length - 1] : undefined,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, type FimoPolymorphicReference, type FimoReference, type FimoSource, type FimoPart, type FimoRichTextContent, type FimoRichTextNodeProps, type FimoRichTextMarkProps, type FimoRichTextComponents, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, } from './primitives.js';
|
|
2
2
|
export { fimo } from './template.js';
|
|
3
|
-
export { useFimoLiveValue } from './useFimoLiveValue.js';
|
|
4
3
|
export type { BoolOps, DateOps, Field, Fields, FilterFor, NullOnlyOps, NumberOps, Populate, Populated, PopulatedResult, ProjectedWithPopulate, Projected, Query, ReferenceField, ReferenceMap, ScalarOps, Sort, SortField, StringOps, Where, WithReferences, } from './query.js';
|
|
5
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
// Fimo - Source tracking for inline editing
|
|
2
2
|
export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, } from './primitives.js';
|
|
3
3
|
export { fimo } from './template.js';
|
|
4
|
-
export { useFimoLiveValue } from './useFimoLiveValue.js';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';
|
|
2
|
+
import type { ImageFit } from '../../primitives/lib/image-optimization.js';
|
|
3
|
+
import type { FimoBoolean, FimoDate, FimoMedia, FimoRichText, FimoRichTextComponents, FimoString } from '../../primitives/lib/index.js';
|
|
4
|
+
export type BooleanProps<T extends ElementType = 'span'> = {
|
|
5
|
+
value: FimoBoolean;
|
|
6
|
+
as?: T;
|
|
7
|
+
children?: (value: boolean) => ReactNode;
|
|
8
|
+
} & Omit<ComponentPropsWithoutRef<T>, 'value' | 'as' | 'children'>;
|
|
9
|
+
export interface DateProps {
|
|
10
|
+
value: FimoDate | FimoString | Date | string;
|
|
11
|
+
children?: (date: Date) => ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface BaseImageProps extends Omit<ComponentPropsWithoutRef<'img'>, 'src' | 'alt' | 'children'> {
|
|
15
|
+
quality?: number;
|
|
16
|
+
fit?: ImageFit;
|
|
17
|
+
unoptimized?: boolean;
|
|
18
|
+
overrideSrc?: string;
|
|
19
|
+
hostSuffixes?: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
export interface ImageProps extends BaseImageProps {
|
|
22
|
+
value: FimoMedia;
|
|
23
|
+
alt?: string;
|
|
24
|
+
children?: (media: FimoMedia) => ReactNode;
|
|
25
|
+
}
|
|
26
|
+
export type JsonProps<T extends ElementType = 'span'> = {
|
|
27
|
+
value: unknown;
|
|
28
|
+
as?: T;
|
|
29
|
+
children?: (value: unknown) => ReactNode;
|
|
30
|
+
} & Omit<ComponentPropsWithoutRef<T>, 'value' | 'as' | 'children'>;
|
|
31
|
+
export interface RichTextProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {
|
|
32
|
+
value: FimoRichText | null | undefined;
|
|
33
|
+
components?: FimoRichTextComponents;
|
|
34
|
+
}
|
|
35
|
+
export type StaticImageProps = Omit<ComponentPropsWithoutRef<'img'>, 'children'> & {
|
|
36
|
+
/** Image quality (1-100). Defaults to 85. */
|
|
37
|
+
quality?: number;
|
|
38
|
+
/** Resize fit mode. Also maps to CSS object-fit. Defaults to 'scale-down'. */
|
|
39
|
+
fit?: ImageFit;
|
|
40
|
+
/** Skip optimization and use the original URL. */
|
|
41
|
+
unoptimized?: boolean;
|
|
42
|
+
hostSuffixes?: readonly string[];
|
|
43
|
+
};
|
|
44
|
+
export type TextProps<T extends ElementType = 'span'> = {
|
|
45
|
+
value: unknown;
|
|
46
|
+
as?: T;
|
|
47
|
+
children?: (value: string) => ReactNode;
|
|
48
|
+
} & Omit<ComponentPropsWithoutRef<T>, 'value' | 'as' | 'children'>;
|
|
49
|
+
export interface BaseVideoProps extends Omit<ComponentPropsWithoutRef<'video'>, 'src' | 'children'> {
|
|
50
|
+
overrideSrc?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface VideoProps extends BaseVideoProps {
|
|
53
|
+
value: FimoMedia;
|
|
54
|
+
children?: (media: FimoMedia) => ReactNode;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ElementType } from 'react';
|
|
2
|
+
import type { BooleanProps } from '../contracts.js';
|
|
3
|
+
export type { BooleanProps } from '../contracts.js';
|
|
4
|
+
export declare function Boolean<T extends ElementType = 'span'>({ value, as, children, ...props }: BooleanProps<T>): import("react/jsx-runtime").JSX.Element | null;
|
|
5
|
+
//# sourceMappingURL=Boolean.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FIMO_SOURCE } from '../../../primitives/lib/index.js';
|
|
3
|
+
import { useFimoLiveValue } from '../../useFimoLiveValue.js';
|
|
4
|
+
export function Boolean({ value, as, children, ...props }) {
|
|
5
|
+
const Component = as || 'span';
|
|
6
|
+
const { value: liveValue, ref } = useFimoLiveValue(value ? value.valueOf() : false);
|
|
7
|
+
if (!value) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return (_jsx(Component, { ref: ref, ...props, "data-fimo-source": value[FIMO_SOURCE], children: children ? children(liveValue) : String(liveValue) }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FIMO_SOURCE } from '../../../primitives/lib/index.js';
|
|
3
|
+
import { useFimoLiveValue } from '../../useFimoLiveValue.js';
|
|
4
|
+
import { DateRenderer } from '../renderers/DateRenderer.js';
|
|
5
|
+
export function Date({ value, ...props }) {
|
|
6
|
+
const { value: liveValue, ref } = useFimoLiveValue(value ?? null);
|
|
7
|
+
if (!liveValue) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const source = typeof value === 'object' && FIMO_SOURCE in value ? (value[FIMO_SOURCE] ?? undefined) : undefined;
|
|
11
|
+
return _jsx(DateRenderer, { ...props, value: liveValue, source: source, elementRef: ref });
|
|
12
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ImageProps } from '../contracts.js';
|
|
2
|
+
export type { BaseImageProps, ImageProps } from '../contracts.js';
|
|
3
|
+
export declare function Image({ value: media, ...props }: ImageProps): import("react/jsx-runtime").JSX.Element | null;
|
|
4
|
+
//# sourceMappingURL=Image.d.ts.map
|