fimo 0.6.0-experimental.2 → 0.6.0-staging.1
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/content-templates/hooks-template.eta +38 -83
- package/assets/content-templates/types-template.eta +2 -6
- package/assets/skills/fimo/references/content.md +14 -13
- package/assets/skills/fimo-cli/references/content.md +6 -6
- package/dist/cli/bundle.json +1 -1
- package/dist/cli/index.js +29 -49
- package/dist/runtime/app/prefetch.js +1 -1
- package/dist/runtime/content/utils/retrieve-data-sources.d.ts +0 -1
- package/dist/runtime/content/utils/retrieve-data-sources.d.ts.map +1 -1
- package/dist/runtime/content/utils/retrieve-data-sources.js +4 -27
- package/dist/runtime/paths/get-fimo-paths.js +1 -1
- package/dist/runtime/primitives/lib/query.d.ts +9 -11
- package/dist/runtime/primitives/lib/query.d.ts.map +1 -1
- package/dist/runtime/primitives/public-surface.test.js +3 -3
- package/dist/scripts/sync-schemas.test.js +3 -14
- package/package.json +1 -1
- package/templates/react-router/package.json +1 -1
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// AUTO-GENERATED ⚠️ – do not edit by hand
|
|
12
12
|
import { <% if (!model.isSingleton) { %>useInfiniteQuery, <% } %>useSuspenseQuery, useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
13
13
|
<% if (!model.isSingleton) { -%>
|
|
14
|
-
import type { InfiniteData, UseInfiniteQueryResult, UseQueryResult
|
|
14
|
+
import type { InfiniteData, UseInfiniteQueryResult, UseQueryResult } from "@tanstack/react-query";
|
|
15
15
|
<% } -%>
|
|
16
16
|
import { FimoString, FimoMedia, FimoBoolean, FimoRichText, useLocale<% if (!model.isSingleton) { %>, parseCollectionResponse<% } %> } from "fimo/ui";
|
|
17
17
|
// @ts-ignore - virtual module provided by Fimo's Vite plugin
|
|
@@ -36,35 +36,16 @@ export type { <%= model.pascal %>, <%= model.pascal %>Fields, <%= model.pascal %
|
|
|
36
36
|
* Wraps raw API data with Fimo types for source tracking
|
|
37
37
|
*/
|
|
38
38
|
export function wrapWithSource(entry: Record<string, any>): <%= model.pascal %> {
|
|
39
|
-
<% if (!model.isSingleton) { -%>
|
|
40
|
-
const documentId = entry.documentId;
|
|
41
|
-
const locale = entry.locale;
|
|
42
|
-
const sourcePrefix = `<%= model.pascal %>.v2:${documentId}:${encodeURIComponent(locale)}`;
|
|
43
|
-
<% } else { -%>
|
|
44
39
|
const id = entry.id;
|
|
45
|
-
const
|
|
46
|
-
const locale = entry.locale ?? defaultLocale();
|
|
47
|
-
const usesV2Identity = typeof id !== "string";
|
|
48
|
-
const sourcePrefix = usesV2Identity
|
|
49
|
-
? `<%= model.pascal %>.v2:${documentId}:${encodeURIComponent(locale)}`
|
|
50
|
-
: `<%= model.pascal %>.${id}`;
|
|
51
|
-
<% } -%>
|
|
40
|
+
const sourcePrefix = `<%= model.pascal %>.${id}`;
|
|
52
41
|
const entryFimo = entry.__fimo && typeof entry.__fimo === "object" ? entry.__fimo : {};
|
|
53
42
|
|
|
54
43
|
return {
|
|
55
|
-
|
|
56
|
-
documentId,
|
|
57
|
-
<% } else { -%>
|
|
58
|
-
...(typeof id === "string" ? { id } : {}),
|
|
59
|
-
documentId,
|
|
60
|
-
<% } -%>
|
|
44
|
+
id,
|
|
45
|
+
documentId: entry.documentId,
|
|
61
46
|
slug: entry.slug != null ? new FimoString(entry.slug, `${sourcePrefix}.slug`) : entry.slug,
|
|
62
|
-
<% if (
|
|
63
|
-
locale,
|
|
64
|
-
<% } else if (model.localized) { -%>
|
|
65
|
-
locale,
|
|
66
|
-
<% } else { -%>
|
|
67
|
-
...(usesV2Identity ? { locale } : {}),
|
|
47
|
+
<% if (model.localized) { -%>
|
|
48
|
+
locale: entry.locale,
|
|
68
49
|
<% } -%>
|
|
69
50
|
createdAt: entry.createdAt,
|
|
70
51
|
updatedAt: entry.updatedAt,
|
|
@@ -120,11 +101,11 @@ if (model.fields) {
|
|
|
120
101
|
const wrapper = field.target === model.uid ? 'wrapWithSource' : `wrap${field.targetPascal}WithSource`;
|
|
121
102
|
if (field.many) {
|
|
122
103
|
-%>
|
|
123
|
-
<%= key %>: Array.isArray(entry.<%= key %>) ? entry.<%= key %>.map((value: any) =>
|
|
104
|
+
<%= key %>: Array.isArray(entry.<%= key %>) ? entry.<%= key %>.map((value: any) => value != null && typeof value === "object" && typeof value.id === "string" ? <%= wrapper %>(value) : value) : entry.<%= key %>,
|
|
124
105
|
<%
|
|
125
106
|
} else {
|
|
126
107
|
-%>
|
|
127
|
-
<%= key %>:
|
|
108
|
+
<%= key %>: entry.<%= key %> != null && typeof entry.<%= key %> === "object" && typeof entry.<%= key %>.id === "string" ? <%= wrapper %>(entry.<%= key %>) : entry.<%= key %>,
|
|
128
109
|
<%
|
|
129
110
|
}
|
|
130
111
|
break;
|
|
@@ -140,23 +121,6 @@ if (model.fields) {
|
|
|
140
121
|
} as <%= model.pascal %>;
|
|
141
122
|
}
|
|
142
123
|
|
|
143
|
-
interface PopulatedEntryRecord extends Record<string, unknown> {
|
|
144
|
-
documentId: string;
|
|
145
|
-
__fimo: { contentType: string };
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function isPopulatedEntry(value: unknown): value is PopulatedEntryRecord {
|
|
149
|
-
if (value == null || typeof value !== "object") {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
const entry = value as Record<string, unknown>;
|
|
153
|
-
const fimo = entry.__fimo;
|
|
154
|
-
return typeof entry.documentId === "string"
|
|
155
|
-
&& fimo != null
|
|
156
|
-
&& typeof fimo === "object"
|
|
157
|
-
&& typeof (fimo as Record<string, unknown>).contentType === "string";
|
|
158
|
-
}
|
|
159
|
-
|
|
160
124
|
<%
|
|
161
125
|
const hasPolymorphicReferences = model.fields && Object.values(model.fields).some((field) => field.type === 'reference' && Array.isArray(field.targetRefs) && field.targetRefs.length > 0);
|
|
162
126
|
if (hasPolymorphicReferences) {
|
|
@@ -168,9 +132,7 @@ if (hasPolymorphicReferences) {
|
|
|
168
132
|
* (unpopulated) values pass through untouched.
|
|
169
133
|
*/
|
|
170
134
|
function wrapPolymorphic(value: any, wrappers: Record<string, (entry: Record<string, any>) => any>): any {
|
|
171
|
-
if (
|
|
172
|
-
return value;
|
|
173
|
-
}
|
|
135
|
+
if (value == null || typeof value !== "object" || typeof value.id !== "string") return value;
|
|
174
136
|
const contentType = value.__fimo && typeof value.__fimo.contentType === "string" ? value.__fimo.contentType : null;
|
|
175
137
|
const wrapper = contentType ? wrappers[contentType] : undefined;
|
|
176
138
|
if (!wrapper) return value;
|
|
@@ -210,12 +172,8 @@ function readLocale(
|
|
|
210
172
|
ownerUsesLocale: boolean,
|
|
211
173
|
fallbackLocale = defaultLocale()
|
|
212
174
|
): string | undefined {
|
|
213
|
-
<% if (!model.isSingleton) { -%>
|
|
214
|
-
return options.locale ?? fallbackLocale;
|
|
215
|
-
<% } else { -%>
|
|
216
175
|
const populatesLocalizedTarget = populateFields(options.populate).some((field) => LOCALIZED_REFERENCE_FIELDS.has(field));
|
|
217
176
|
return ownerUsesLocale || populatesLocalizedTarget ? options.locale ?? fallbackLocale : undefined;
|
|
218
|
-
<% } -%>
|
|
219
177
|
}
|
|
220
178
|
|
|
221
179
|
function fimoHeaders(extra?: Record<string, string>): Record<string, string> {
|
|
@@ -291,11 +249,11 @@ export type InfiniteListResult<TItem> = UseInfiniteQueryResult<
|
|
|
291
249
|
readonly isLoadingMore: boolean;
|
|
292
250
|
};
|
|
293
251
|
|
|
294
|
-
export async function
|
|
295
|
-
|
|
252
|
+
export async function getById<TPopulate extends <%= model.pascal %>Populate | undefined = undefined>(
|
|
253
|
+
id: string,
|
|
296
254
|
options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}
|
|
297
255
|
): Promise<<%= model.pascal %>Result<undefined, TPopulate>> {
|
|
298
|
-
const res = await fetch(`${base}${withReadOptions(`/
|
|
256
|
+
const res = await fetch(`${base}${withReadOptions(`/entries/<%= model.uid %>/${id}`, options, false)}`, { headers: fimoHeaders() });
|
|
299
257
|
if (!res.ok) throw new Error(await res.text());
|
|
300
258
|
const data = await res.json();
|
|
301
259
|
return wrapWithSource(data.data) as <%= model.pascal %>Result<undefined, TPopulate>;
|
|
@@ -305,7 +263,7 @@ export async function getBySlug<TPopulate extends <%= model.pascal %>Populate |
|
|
|
305
263
|
slug: string,
|
|
306
264
|
options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}
|
|
307
265
|
): Promise<<%= model.pascal %>Result<undefined, TPopulate> | null> {
|
|
308
|
-
const res = await fetch(`${base}${withReadOptions(`/
|
|
266
|
+
const res = await fetch(`${base}${withReadOptions(`/entries/<%= model.uid %>/slug/${encodeURIComponent(slug)}`, options)}`, { headers: fimoHeaders() });
|
|
309
267
|
if (res.status === 404) return null;
|
|
310
268
|
if (!res.ok) throw new Error(await res.text());
|
|
311
269
|
const data = await res.json();
|
|
@@ -317,7 +275,7 @@ export async function getByField<TPopulate extends <%= model.pascal %>Populate |
|
|
|
317
275
|
value: string,
|
|
318
276
|
options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}
|
|
319
277
|
): Promise<<%= model.pascal %>Result<undefined, TPopulate> | null> {
|
|
320
|
-
const res = await fetch(`${base}${withReadOptions(`/
|
|
278
|
+
const res = await fetch(`${base}${withReadOptions(`/entries/<%= model.uid %>/field/${encodeURIComponent(fieldName)}/${encodeURIComponent(value)}`, options)}`, { headers: fimoHeaders() });
|
|
321
279
|
if (res.status === 404) return null;
|
|
322
280
|
if (!res.ok) throw new Error(await res.text());
|
|
323
281
|
const data = await res.json();
|
|
@@ -363,7 +321,7 @@ export async function list<
|
|
|
363
321
|
TPopulate extends <%= model.pascal %>Populate | undefined = undefined,
|
|
364
322
|
>(params: <%= model.pascal %>Query<TFields, TPopulate> = {} as <%= model.pascal %>Query<TFields, TPopulate>): Promise<CollectionPage<<%= model.pascal %>Result<TFields, TPopulate>>> {
|
|
365
323
|
const qs = toQueryString(params);
|
|
366
|
-
const res = await fetch(`${base}/
|
|
324
|
+
const res = await fetch(`${base}/entries/<%= model.uid %>${qs ? "?" + qs : ""}`, { headers: fimoHeaders() });
|
|
367
325
|
if (!res.ok) throw new Error(await res.text());
|
|
368
326
|
const data = parseCollectionResponse(await res.json());
|
|
369
327
|
const items = data.data.map(wrapWithSource) as <%= model.pascal %>Result<TFields, TPopulate>[];
|
|
@@ -385,7 +343,7 @@ export async function get<
|
|
|
385
343
|
}
|
|
386
344
|
|
|
387
345
|
export async function create(payload: <%= model.pascal %>Input): Promise<<%= model.pascal %>> {
|
|
388
|
-
const res = await fetch(`${base}/
|
|
346
|
+
const res = await fetch(`${base}/entries/<%= model.uid %>`, {
|
|
389
347
|
method: "POST",
|
|
390
348
|
headers: fimoHeaders({ "Content-Type": "application/json" }),
|
|
391
349
|
body: JSON.stringify(splitWritePayload(payload))
|
|
@@ -395,22 +353,19 @@ export async function create(payload: <%= model.pascal %>Input): Promise<<%= mod
|
|
|
395
353
|
return wrapWithSource(data.data);
|
|
396
354
|
}
|
|
397
355
|
|
|
398
|
-
export async function update(
|
|
399
|
-
const
|
|
400
|
-
const url = withReadOptions(`/v2/entries/<%= model.uid %>/${documentId}`, { locale: write.locale });
|
|
401
|
-
const res = await fetch(`${base}${url}`, {
|
|
356
|
+
export async function update(id: string, payload: Partial<<%= model.pascal %>Input>): Promise<<%= model.pascal %>> {
|
|
357
|
+
const res = await fetch(`${base}/entries/<%= model.uid %>/${id}`, {
|
|
402
358
|
method: "PUT",
|
|
403
359
|
headers: fimoHeaders({ "Content-Type": "application/json" }),
|
|
404
|
-
body: JSON.stringify(
|
|
360
|
+
body: JSON.stringify(splitWritePayload(payload))
|
|
405
361
|
});
|
|
406
362
|
if (!res.ok) throw new Error(await res.text());
|
|
407
363
|
const data = await res.json();
|
|
408
364
|
return wrapWithSource(data.data);
|
|
409
365
|
}
|
|
410
366
|
|
|
411
|
-
export async function remove(
|
|
412
|
-
const
|
|
413
|
-
const res = await fetch(`${base}${url}`, { method: "DELETE", headers: fimoHeaders() });
|
|
367
|
+
export async function remove(id: string): Promise<void> {
|
|
368
|
+
const res = await fetch(`${base}/entries/<%= model.uid %>/${id}`, { method: "DELETE", headers: fimoHeaders() });
|
|
414
369
|
if (!res.ok) throw new Error(await res.text());
|
|
415
370
|
}
|
|
416
371
|
<% } else { -%>
|
|
@@ -444,7 +399,7 @@ export async function update(payload: Partial<<%= model.pascal %>Input>): Promis
|
|
|
444
399
|
<% if (!model.isSingleton) { -%>
|
|
445
400
|
const qk = {
|
|
446
401
|
root : ["<%= model.pascal %>"] as const,
|
|
447
|
-
|
|
402
|
+
byId : <TPopulate extends <%= model.pascal %>Populate | undefined = undefined>(id: string, options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}) => ["<%= model.pascal %>", id, options.locale, options.populate] as const,
|
|
448
403
|
bySlug : <TPopulate extends <%= model.pascal %>Populate | undefined = undefined>(slug: string, options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}) => ["<%= model.pascal %>", "slug", slug, options.locale, options.populate] as const,
|
|
449
404
|
byField : <TPopulate extends <%= model.pascal %>Populate | undefined = undefined>(field: string, value: string, options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}) => ["<%= model.pascal %>", field, value, options.locale, options.populate] as const,
|
|
450
405
|
list : (params: <%= model.pascal %>Query) => ["<%= model.pascal %>", params] as const,
|
|
@@ -454,10 +409,10 @@ const qk = {
|
|
|
454
409
|
>(params: InfiniteListQuery<TFields, TPopulate>) => ["<%= model.pascal %>", "infinite", params] as const
|
|
455
410
|
};
|
|
456
411
|
|
|
457
|
-
export function
|
|
458
|
-
const locale = useQueryLocale(options.locale);
|
|
412
|
+
export function useGetById<TPopulate extends <%= model.pascal %>Populate | undefined = undefined>(id: string, options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}) {
|
|
413
|
+
const locale = readLocale(options, false, useQueryLocale(options.locale));
|
|
459
414
|
const localizedOptions = { ...options, locale };
|
|
460
|
-
return useQuery<<%= model.pascal %>Result<undefined, TPopulate>, Error>({ queryKey: qk.
|
|
415
|
+
return useQuery<<%= model.pascal %>Result<undefined, TPopulate>, Error>({ queryKey: qk.byId(id, localizedOptions), queryFn: () => getById(id, localizedOptions) });
|
|
461
416
|
}
|
|
462
417
|
|
|
463
418
|
export function useGetBySlug<TPopulate extends <%= model.pascal %>Populate | undefined = undefined>(slug: string, options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}) {
|
|
@@ -520,10 +475,10 @@ export function useInfiniteList<
|
|
|
520
475
|
};
|
|
521
476
|
}
|
|
522
477
|
|
|
523
|
-
export function
|
|
524
|
-
const locale = useQueryLocale(options.locale);
|
|
478
|
+
export function useSuspenseGetById<TPopulate extends <%= model.pascal %>Populate | undefined = undefined>(id: string, options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}) {
|
|
479
|
+
const locale = readLocale(options, false, useQueryLocale(options.locale));
|
|
525
480
|
const localizedOptions = { ...options, locale };
|
|
526
|
-
return useSuspenseQuery<<%= model.pascal %>Result<undefined, TPopulate>, Error>({ queryKey: qk.
|
|
481
|
+
return useSuspenseQuery<<%= model.pascal %>Result<undefined, TPopulate>, Error>({ queryKey: qk.byId(id, localizedOptions), queryFn: () => getById(id, localizedOptions) });
|
|
527
482
|
}
|
|
528
483
|
|
|
529
484
|
export function useSuspenseGetBySlug<TPopulate extends <%= model.pascal %>Populate | undefined = undefined>(slug: string, options: { locale?: string; populate?: TPopulate; localeFallbacks?: boolean } = {}) {
|
|
@@ -561,22 +516,22 @@ export function useCreate() {
|
|
|
561
516
|
|
|
562
517
|
export function useUpdate() {
|
|
563
518
|
const qc = useQueryClient();
|
|
564
|
-
return useMutation<<%= model.pascal %>, Error, {
|
|
565
|
-
mutationFn : ({
|
|
519
|
+
return useMutation<<%= model.pascal %>, Error, { id: string } & Partial<<%= model.pascal %>Input>>({
|
|
520
|
+
mutationFn : ({ id, ...patch }) => update(id, patch),
|
|
566
521
|
onSuccess : (_data, vars) => {
|
|
567
522
|
qc.invalidateQueries({ queryKey: qk.root });
|
|
568
|
-
qc.invalidateQueries({ queryKey: qk.
|
|
523
|
+
qc.invalidateQueries({ queryKey: qk.byId(vars.id) });
|
|
569
524
|
}
|
|
570
525
|
});
|
|
571
526
|
}
|
|
572
527
|
|
|
573
528
|
export function useRemove() {
|
|
574
529
|
const qc = useQueryClient();
|
|
575
|
-
return useMutation<void, Error,
|
|
576
|
-
mutationFn :
|
|
577
|
-
onSuccess : (_data,
|
|
530
|
+
return useMutation<void, Error, string>({
|
|
531
|
+
mutationFn : remove,
|
|
532
|
+
onSuccess : (_data, id) => {
|
|
578
533
|
qc.invalidateQueries({ queryKey: qk.root });
|
|
579
|
-
qc.removeQueries({ queryKey:
|
|
534
|
+
qc.removeQueries({ queryKey: ["<%= model.pascal %>", id], exact: false });
|
|
580
535
|
}
|
|
581
536
|
});
|
|
582
537
|
}
|
|
@@ -614,7 +569,7 @@ export function useUpdate() {
|
|
|
614
569
|
export default {
|
|
615
570
|
<% if (!model.isSingleton) { -%>
|
|
616
571
|
/* async helpers */
|
|
617
|
-
|
|
572
|
+
getById,
|
|
618
573
|
getBySlug,
|
|
619
574
|
getByField,
|
|
620
575
|
list,
|
|
@@ -624,13 +579,13 @@ export default {
|
|
|
624
579
|
remove,
|
|
625
580
|
|
|
626
581
|
/* hooks */
|
|
627
|
-
|
|
582
|
+
useGetById,
|
|
628
583
|
useGetBySlug,
|
|
629
584
|
useGetByField,
|
|
630
585
|
useList,
|
|
631
586
|
useInfiniteList,
|
|
632
587
|
useGet,
|
|
633
|
-
|
|
588
|
+
useSuspenseGetById,
|
|
634
589
|
useSuspenseGet,
|
|
635
590
|
useSuspenseGetByField,
|
|
636
591
|
useSuspenseGetBySlug,
|
|
@@ -32,15 +32,11 @@ export interface <%= model.pascal %>FimoMeta {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export interface <%= model.pascal %> extends WithReferences<<%= model.pascal %>References> {
|
|
35
|
-
|
|
36
|
-
id?: string;
|
|
37
|
-
<% } -%>
|
|
35
|
+
id: string;
|
|
38
36
|
documentId: string;
|
|
39
37
|
slug: FimoString;
|
|
40
|
-
<% if (
|
|
38
|
+
<% if (model.localized) { -%>
|
|
41
39
|
locale: string;
|
|
42
|
-
<% } else { -%>
|
|
43
|
-
locale?: string;
|
|
44
40
|
<% } -%>
|
|
45
41
|
createdAt: string;
|
|
46
42
|
updatedAt: string;
|
|
@@ -191,9 +191,10 @@ Import from the public schema module, e.g. `import BlogPost from '@/schemas/Blog
|
|
|
191
191
|
|
|
192
192
|
```ts
|
|
193
193
|
interface BlogPost {
|
|
194
|
+
id: string;
|
|
194
195
|
documentId: string;
|
|
195
196
|
slug: FimoString;
|
|
196
|
-
locale: string;
|
|
197
|
+
locale: string; // localized schemas only; omitted when i18n.enabled is false
|
|
197
198
|
createdAt: string;
|
|
198
199
|
updatedAt: string;
|
|
199
200
|
__fimo: {
|
|
@@ -218,7 +219,7 @@ When a project has multiple configured locales, create and update each localized
|
|
|
218
219
|
|
|
219
220
|
For shared content, set `i18n: { "enabled": false }` on the schema and create each entry once. Shared entries:
|
|
220
221
|
|
|
221
|
-
-
|
|
222
|
+
- have no public `locale` property;
|
|
222
223
|
- are returned in every locale context without duplication;
|
|
223
224
|
- ignore locale on owner reads and writes;
|
|
224
225
|
- still use the active/requested locale when a populated reference targets a localized schema.
|
|
@@ -246,17 +247,17 @@ Filtering on polymorphic fields is not supported yet.
|
|
|
246
247
|
|
|
247
248
|
```ts
|
|
248
249
|
// low-level fetch helpers
|
|
249
|
-
|
|
250
|
+
getById<TPopulate extends BlogPostPopulate | undefined>(id: string, options?: { populate?: TPopulate }): Promise<BlogPostResult<undefined, TPopulate>>
|
|
250
251
|
getBySlug<TPopulate extends BlogPostPopulate | undefined>(slug: string, options?: { populate?: TPopulate }): Promise<BlogPostResult<undefined, TPopulate> | null>
|
|
251
252
|
getByField<TPopulate extends BlogPostPopulate | undefined>(fieldName: string, value: string, options?: { populate?: TPopulate }): Promise<BlogPostResult<undefined, TPopulate> | null>
|
|
252
253
|
list<TFields extends BlogPostFields | undefined, TPopulate extends BlogPostPopulate | undefined>(params?: BlogPostQuery<TFields, TPopulate>): Promise<CollectionPage<BlogPostResult<TFields, TPopulate>>>
|
|
253
254
|
get<TFields extends BlogPostFields | undefined, TPopulate extends BlogPostPopulate | undefined>(params?: BlogPostQuery<TFields, TPopulate>): Promise<BlogPostResult<TFields, TPopulate>[]>
|
|
254
255
|
create(payload: BlogPostInput): Promise<BlogPost>
|
|
255
|
-
update(
|
|
256
|
-
remove(
|
|
256
|
+
update(id: string, payload: Partial<BlogPostInput>): Promise<BlogPost>
|
|
257
|
+
remove(id: string): Promise<void>
|
|
257
258
|
|
|
258
259
|
// react-query hooks
|
|
259
|
-
|
|
260
|
+
useGetById(id, { populate? }) // → { data: BlogPostResult<undefined, TPopulate> | undefined, isLoading, ... }
|
|
260
261
|
useGetBySlug(slug, { populate? }) // → { data: BlogPostResult<undefined, TPopulate> | null | undefined, ... } — ideal for /:slug detail routes
|
|
261
262
|
useGetByField(fieldName, value, { populate? })
|
|
262
263
|
useList<TFields, TPopulate>(params?) // → { data: CollectionPage<BlogPostResult<TFields, TPopulate>> | undefined, ... }
|
|
@@ -265,7 +266,7 @@ useGet<TFields, TPopulate>(params?) // → legacy array-shaped { data:
|
|
|
265
266
|
useCreate() / useUpdate() / useRemove()
|
|
266
267
|
|
|
267
268
|
// Suspense variants (same signatures, throw to a <Suspense> boundary instead of returning isLoading)
|
|
268
|
-
|
|
269
|
+
useSuspenseGetById(id) / useSuspenseGetBySlug(slug) / useSuspenseGetByField(fieldName, value) / useSuspenseGet(params?)
|
|
269
270
|
```
|
|
270
271
|
|
|
271
272
|
Write inputs contain plain JSON values. Read models contain Fimo wrapper values for source tracking, so use `BlogPostInput` rather than sending a `BlogPost` back to `create` or `update`.
|
|
@@ -278,7 +279,7 @@ update(payload: Partial<SettingsInput>): Promise<Settings>
|
|
|
278
279
|
useGet(options?) / useSuspenseGet(options?) / useUpdate()
|
|
279
280
|
```
|
|
280
281
|
|
|
281
|
-
Singleton clients do not expose `create`, `remove`, `
|
|
282
|
+
Singleton clients do not expose `create`, `remove`, `getById`, or list queries. Localized singletons have one variant per locale; non-localized singletons have one locale-free row.
|
|
282
283
|
|
|
283
284
|
Choose the collection interface from the UI behavior. Use `useList` when the UI controls a page, and read pagination state from `pageInfo`:
|
|
284
285
|
|
|
@@ -337,7 +338,7 @@ Operators: scalar equality, `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `
|
|
|
337
338
|
Reference field values are reference objects, but reference filters use the target `documentId` string, for example `where: { author: "750e..." }`; for to-many references that means "contains this target document".
|
|
338
339
|
For to-many references, `$eq` and `$contains` mean membership, `$in` means any listed document is present, `$ne` and `$nin` mean none are present, and `$null: true` means empty or missing. Reference fields cannot be sorted.
|
|
339
340
|
|
|
340
|
-
Use `fields` to keep list payloads small. The
|
|
341
|
+
Use `fields` to keep list payloads small. The API always keeps `id`, and returns only the requested fields beyond that:
|
|
341
342
|
|
|
342
343
|
```tsx
|
|
343
344
|
const { data: summaries = [] } = BlogPost.useGet({
|
|
@@ -345,7 +346,7 @@ const { data: summaries = [] } = BlogPost.useGet({
|
|
|
345
346
|
sort: '-publishedAt',
|
|
346
347
|
limit: 12,
|
|
347
348
|
});
|
|
348
|
-
// summaries: Array<Pick<BlogPost, '
|
|
349
|
+
// summaries: Array<Pick<BlogPost, 'id' | 'slug' | 'title' | 'excerpt' | 'coverImage'>>
|
|
349
350
|
```
|
|
350
351
|
|
|
351
352
|
Use `populate` to embed reference targets in read results:
|
|
@@ -433,7 +434,7 @@ export function BlogList() {
|
|
|
433
434
|
return (
|
|
434
435
|
<ul>
|
|
435
436
|
{page.items.map((post) => (
|
|
436
|
-
<li key={
|
|
437
|
+
<li key={post.id}>
|
|
437
438
|
<Text value={post.title} as="h2" />
|
|
438
439
|
<Image value={post.coverImage} width={800} height={400} fit="cover" />
|
|
439
440
|
<RichText value={post.body} className="prose" />
|
|
@@ -450,9 +451,9 @@ For the `<Text>` / `<RichText>` / `<Image>` / `<Date>` components and the rules
|
|
|
450
451
|
## Read path (published app, no auth)
|
|
451
452
|
|
|
452
453
|
```ts
|
|
453
|
-
const res = await fetch(`${import.meta.env.VITE_API_URL}/
|
|
454
|
+
const res = await fetch(`${import.meta.env.VITE_API_URL}/entries/<typeName>?fields=slug,title&limit=12`);
|
|
454
455
|
const { data, meta } = await res.json();
|
|
455
|
-
// data: Entry[] — fields flattened at top level (
|
|
456
|
+
// data: Entry[] — fields flattened at top level (id, slug, title, ...)
|
|
456
457
|
// meta: { limit, offset, total, hasMore }
|
|
457
458
|
```
|
|
458
459
|
|
|
@@ -43,9 +43,9 @@ fimo entries create <TypeName> --body '<json>'
|
|
|
43
43
|
fimo entries create <TypeName> --locale es --document-id <documentId> --body '<json>'
|
|
44
44
|
fimo entries list <TypeName> [--limit N] [--offset N] [--search Q] [--where JSON] [--sort F] [--fields FIELDS] [--populate FIELDS]
|
|
45
45
|
fimo entries list <TypeName> --locale es
|
|
46
|
-
fimo entries get <TypeName> <
|
|
47
|
-
fimo entries update <TypeName> <
|
|
48
|
-
fimo entries delete <TypeName> <
|
|
46
|
+
fimo entries get <TypeName> <id>
|
|
47
|
+
fimo entries update <TypeName> <id> --locale es --body '<json>'
|
|
48
|
+
fimo entries delete <TypeName> <id>
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
`--body` is a **required** option on `create` and `update`. Its JSON shape (where `slug` goes, how `media` fields look, Tiptap richtext format) lives in `fimo/references/content.md`. **Always read that first before constructing an entry payload — slug must be inside `data`, media has a specific shape, richtext must be Tiptap JSONContent.**
|
|
@@ -66,7 +66,7 @@ Use the canonical read query flags: `--search`, `--sort`, `--where`, `--limit`,
|
|
|
66
66
|
`--where` is a JSON object keyed by schema field name. Simple values mean equality and stay typed inside the JSON (`{"featured":true}`, `{"category":"react"}`, `{"rank":{"$gte":3}}`); operator objects support `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$contains`, `$startsWith`, and `$null`, subject to the field type. Public Fimo-owned metadata lives under `__fimo`; currently `__fimo.contentType` is filterable.
|
|
67
67
|
|
|
68
68
|
Reference filters take the target `documentId` string even though stored values are objects (`{"author":"750e..."}`). On a to-many field, `$eq` and `$contains` mean membership, `$in` means any listed document is present, `$ne` and `$nin` mean none are present, and `$null: true` means empty or missing. Reference fields cannot be sorted; use `--sort field` / `--sort -field` on scalar fields.
|
|
69
|
-
`--fields` is a comma-separated projection for list payloads. The
|
|
69
|
+
`--fields` is a comma-separated projection for list payloads. The API always keeps `id`; pass only the fields your view needs, such as `slug,title,excerpt,coverImage`.
|
|
70
70
|
|
|
71
71
|
`--populate` is a comma-separated list of reference fields to embed. Without it, reference fields return reference objects like `{ "documentId": "..." }`; with `--populate author,contributors`, those fields return the target entry objects for the requested locale. Only reference fields can be populated (scalar fields 400), and populate never selects which target fields come back. A populated target missing in the requested locale resolves to null unless you pass `localeFallbacks=true`, which falls back to the best available locale variant, marked by its `locale` field. Limits: 200 references per to-many write, 500 distinct populated documents per field per request (400 past either).
|
|
72
72
|
|
|
@@ -95,11 +95,11 @@ Do not add `localized` or field-level `i18n` to reference fields. The reference
|
|
|
95
95
|
|
|
96
96
|
## Localized and shared content
|
|
97
97
|
|
|
98
|
-
Schemas are localized by default. Omit `--locale` for default-locale
|
|
98
|
+
Schemas are localized by default. Omit `--locale` for default-locale entries. Pass `--locale <locale>` when creating, listing, reading, or updating a specific non-default locale.
|
|
99
99
|
|
|
100
100
|
When creating a localized variant of an existing entry, pass the source entry's `documentId` with `--document-id`. Keep projects single-locale unless the user asks for multilingual or localized output; when multiple locales are configured, create and update every locale explicitly.
|
|
101
101
|
|
|
102
|
-
For content shared across locales, define `"i18n": { "enabled": false }` at the schema root and create each entry once. Do not pass `--document-id` to manufacture locale variants.
|
|
102
|
+
For content shared across locales, define `"i18n": { "enabled": false }` at the schema root and create each entry once. Do not pass `--document-id` to manufacture locale variants. Shared entry responses omit `locale`; a read locale is only used to resolve populated references that target localized schemas. No other `i18n` options and no field-level localization settings are supported.
|
|
103
103
|
|
|
104
104
|
Use `"isSingleton": true` for a type with exactly one logical document. Generated singleton clients expose `get`/`update` and their React Query hooks, not collection create/remove APIs.
|
|
105
105
|
|
package/dist/cli/bundle.json
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -20634,39 +20634,33 @@ var init_api = __esm({
|
|
|
20634
20634
|
// ── Tenant API: Entries ──
|
|
20635
20635
|
async listEntries(projectId, typeName, params) {
|
|
20636
20636
|
const query = params ? `?${new URLSearchParams(params).toString()}` : "";
|
|
20637
|
-
return this.request(this.tenantPath(projectId, `/
|
|
20637
|
+
return this.request(this.tenantPath(projectId, `/entries/${typeName}${query}`));
|
|
20638
20638
|
}
|
|
20639
|
-
async getEntry(projectId, typeName,
|
|
20640
|
-
const query = new URLSearchParams(
|
|
20639
|
+
async getEntry(projectId, typeName, id, params) {
|
|
20640
|
+
const query = params ? `?${new URLSearchParams(params).toString()}` : "";
|
|
20641
20641
|
const body = await this.request(
|
|
20642
|
-
this.tenantPath(projectId, `/
|
|
20642
|
+
this.tenantPath(projectId, `/entries/${typeName}/${id}${query}`)
|
|
20643
20643
|
);
|
|
20644
20644
|
return body.data;
|
|
20645
20645
|
}
|
|
20646
20646
|
async createEntry(projectId, typeName, data2) {
|
|
20647
|
-
const body = await this.request(this.tenantPath(projectId, `/
|
|
20647
|
+
const body = await this.request(this.tenantPath(projectId, `/entries/${typeName}`), {
|
|
20648
20648
|
method: "POST",
|
|
20649
20649
|
body: JSON.stringify(data2)
|
|
20650
20650
|
});
|
|
20651
20651
|
return body.data;
|
|
20652
20652
|
}
|
|
20653
|
-
async updateEntry(projectId, typeName,
|
|
20654
|
-
const
|
|
20655
|
-
|
|
20656
|
-
|
|
20657
|
-
|
|
20658
|
-
method: "PUT",
|
|
20659
|
-
body: JSON.stringify(data2)
|
|
20660
|
-
}
|
|
20661
|
-
);
|
|
20653
|
+
async updateEntry(projectId, typeName, id, data2) {
|
|
20654
|
+
const body = await this.request(this.tenantPath(projectId, `/entries/${typeName}/${id}`), {
|
|
20655
|
+
method: "PUT",
|
|
20656
|
+
body: JSON.stringify(data2)
|
|
20657
|
+
});
|
|
20662
20658
|
return body.data;
|
|
20663
20659
|
}
|
|
20664
|
-
async deleteEntry(projectId, typeName,
|
|
20665
|
-
const
|
|
20666
|
-
|
|
20667
|
-
|
|
20668
|
-
{ method: "DELETE" }
|
|
20669
|
-
);
|
|
20660
|
+
async deleteEntry(projectId, typeName, id) {
|
|
20661
|
+
const body = await this.request(this.tenantPath(projectId, `/entries/${typeName}/${id}`), {
|
|
20662
|
+
method: "DELETE"
|
|
20663
|
+
});
|
|
20670
20664
|
return body.data;
|
|
20671
20665
|
}
|
|
20672
20666
|
// ── Tenant API: Assets ──
|
|
@@ -44413,7 +44407,7 @@ var init_payment_method_dto = __esm({
|
|
|
44413
44407
|
});
|
|
44414
44408
|
|
|
44415
44409
|
// ../../packages/api-contracts/dist/esm/dtos/content.dto.js
|
|
44416
|
-
var FieldDefinitionSchema, ContentTypeI18nSchema, ContentTypeDTOSchema, ContentTypeDTO, SchemaDTOSchema, SchemaDTO, EntryDTOSchema, EntryDTO,
|
|
44410
|
+
var FieldDefinitionSchema, ContentTypeI18nSchema, ContentTypeDTOSchema, ContentTypeDTO, SchemaDTOSchema, SchemaDTO, EntryDTOSchema, EntryDTO, PaginatedEntriesDTOSchema, PaginatedEntriesDTO, EntryCountDTOSchema, EntryCountDTO, EntryCountsDTOSchema, EntryCountsDTO, ContentTypeResponseSchema, ContentTypeListResponseSchema, SchemaResponseSchema, EntryResponseSchema, EntryListResponseSchema;
|
|
44417
44411
|
var init_content_dto = __esm({
|
|
44418
44412
|
"../../packages/api-contracts/dist/esm/dtos/content.dto.js"() {
|
|
44419
44413
|
"use strict";
|
|
@@ -44455,18 +44449,6 @@ var init_content_dto = __esm({
|
|
|
44455
44449
|
})
|
|
44456
44450
|
}).passthrough();
|
|
44457
44451
|
EntryDTO = createDTO(EntryDTOSchema);
|
|
44458
|
-
EntryV2DTOSchema = external_exports.object({
|
|
44459
|
-
id: external_exports.never().optional(),
|
|
44460
|
-
documentId: external_exports.string(),
|
|
44461
|
-
slug: external_exports.string(),
|
|
44462
|
-
locale: external_exports.string(),
|
|
44463
|
-
createdAt: external_exports.string(),
|
|
44464
|
-
updatedAt: external_exports.string(),
|
|
44465
|
-
__fimo: external_exports.object({
|
|
44466
|
-
contentType: external_exports.string()
|
|
44467
|
-
})
|
|
44468
|
-
}).passthrough();
|
|
44469
|
-
EntryV2DTO = createDTO(EntryV2DTOSchema);
|
|
44470
44452
|
PaginatedEntriesDTOSchema = external_exports.object({
|
|
44471
44453
|
data: external_exports.array(EntryDTOSchema),
|
|
44472
44454
|
meta: external_exports.object({
|
|
@@ -44477,10 +44459,6 @@ var init_content_dto = __esm({
|
|
|
44477
44459
|
})
|
|
44478
44460
|
});
|
|
44479
44461
|
PaginatedEntriesDTO = createDTO(PaginatedEntriesDTOSchema);
|
|
44480
|
-
PaginatedEntriesV2DTOSchema = PaginatedEntriesDTOSchema.extend({
|
|
44481
|
-
data: external_exports.array(EntryV2DTOSchema)
|
|
44482
|
-
});
|
|
44483
|
-
PaginatedEntriesV2DTO = createDTO(PaginatedEntriesV2DTOSchema);
|
|
44484
44462
|
EntryCountDTOSchema = external_exports.object({
|
|
44485
44463
|
contentType: external_exports.string(),
|
|
44486
44464
|
count: external_exports.number()
|
|
@@ -44494,9 +44472,7 @@ var init_content_dto = __esm({
|
|
|
44494
44472
|
ContentTypeListResponseSchema = createResponseSchema(external_exports.array(ContentTypeDTOSchema));
|
|
44495
44473
|
SchemaResponseSchema = createResponseSchema(SchemaDTOSchema);
|
|
44496
44474
|
EntryResponseSchema = createResponseSchema(EntryDTOSchema);
|
|
44497
|
-
EntryV2ResponseSchema = createResponseSchema(EntryV2DTOSchema);
|
|
44498
44475
|
EntryListResponseSchema = createResponseSchema(external_exports.array(EntryDTOSchema));
|
|
44499
|
-
EntryV2ListResponseSchema = createResponseSchema(external_exports.array(EntryV2DTOSchema));
|
|
44500
44476
|
}
|
|
44501
44477
|
});
|
|
44502
44478
|
|
|
@@ -106376,10 +106352,11 @@ async function entriesListCommand(typeName, options, cmd) {
|
|
|
106376
106352
|
ui.result({ command: "entries list", data: result, render: /* @__PURE__ */ __name(() => renderPrettyJson5(result), "render") });
|
|
106377
106353
|
}
|
|
106378
106354
|
__name(entriesListCommand, "entriesListCommand");
|
|
106379
|
-
async function entriesGetCommand(typeName,
|
|
106355
|
+
async function entriesGetCommand(typeName, id, options, cmd) {
|
|
106380
106356
|
const { ctx, api } = await bootstrapProjectCommand(options, cmd);
|
|
106381
106357
|
await requireOperation("cms.get", { projectId: ctx.projectId, env: ctx.env });
|
|
106382
|
-
const
|
|
106358
|
+
const params = options.locale ? { locale: options.locale } : void 0;
|
|
106359
|
+
const result = await api.getEntry(ctx.projectId, typeName, id, params);
|
|
106383
106360
|
ui.result({ command: "entries get", data: result, render: /* @__PURE__ */ __name(() => renderPrettyJson5(result), "render") });
|
|
106384
106361
|
}
|
|
106385
106362
|
__name(entriesGetCommand, "entriesGetCommand");
|
|
@@ -106394,18 +106371,21 @@ async function entriesCreateCommand(typeName, options, cmd) {
|
|
|
106394
106371
|
ui.result({ command: "entries create", data: result, render: /* @__PURE__ */ __name(() => renderPrettyJson5(result), "render") });
|
|
106395
106372
|
}
|
|
106396
106373
|
__name(entriesCreateCommand, "entriesCreateCommand");
|
|
106397
|
-
async function entriesUpdateCommand(typeName,
|
|
106374
|
+
async function entriesUpdateCommand(typeName, id, options, cmd) {
|
|
106398
106375
|
const { ctx, api } = await bootstrapProjectCommand(options, cmd, { refuseReadOnly: true });
|
|
106399
106376
|
await requireOperation("cms.update", { projectId: ctx.projectId, env: ctx.env });
|
|
106400
|
-
const data2 = parseJsonObject(options.body)
|
|
106401
|
-
|
|
106377
|
+
const data2 = addDefinedMetadata(parseJsonObject(options.body), {
|
|
106378
|
+
locale: options.locale,
|
|
106379
|
+
documentId: options.documentId
|
|
106380
|
+
});
|
|
106381
|
+
const result = await api.updateEntry(ctx.projectId, typeName, id, data2);
|
|
106402
106382
|
ui.result({ command: "entries update", data: result, render: /* @__PURE__ */ __name(() => renderPrettyJson5(result), "render") });
|
|
106403
106383
|
}
|
|
106404
106384
|
__name(entriesUpdateCommand, "entriesUpdateCommand");
|
|
106405
|
-
async function entriesDeleteCommand(typeName,
|
|
106385
|
+
async function entriesDeleteCommand(typeName, id, options, cmd) {
|
|
106406
106386
|
const { ctx, api } = await bootstrapProjectCommand(options, cmd, { refuseReadOnly: true });
|
|
106407
106387
|
await requireOperation("cms.delete", { projectId: ctx.projectId, env: ctx.env });
|
|
106408
|
-
const result = await api.deleteEntry(ctx.projectId, typeName,
|
|
106388
|
+
const result = await api.deleteEntry(ctx.projectId, typeName, id);
|
|
106409
106389
|
ui.result({ command: "entries delete", data: result, render: /* @__PURE__ */ __name(() => renderPrettyJson5(result), "render") });
|
|
106410
106390
|
}
|
|
106411
106391
|
__name(entriesDeleteCommand, "entriesDeleteCommand");
|
|
@@ -110358,10 +110338,10 @@ schemas2.command("push").description("Push schema JSON files to the API (create
|
|
|
110358
110338
|
schemas2.command("delete").description("Delete a schema by type name").argument("<typeName>", "Content type name").option("-C, --cwd <dir>", "Project directory").action(schemaDeleteCommand);
|
|
110359
110339
|
var entries = program.command("entries").description("Manage content entries");
|
|
110360
110340
|
entries.command("list").description("List entries of a content type").argument("<typeName>", "Content type name").option("-C, --cwd <dir>", "Project directory").option("--limit <n>", "Max entries to return").option("--offset <n>", "Offset for pagination").option("--search <query>", "Search query").option("--where <json>", `JSON filter object, e.g. '{"featured":true}'`).option("--sort <field>", "Sort field, prefix with - for descending").option("--fields <fields>", "Comma-separated fields to return, e.g. slug,title,excerpt").option("--populate <fields>", "Comma-separated reference fields to populate, e.g. author,contributors").option("--locale <locale>", "Locale to list (default en)").option("--sort-by <field>", "Sort field").option("--sort-direction <dir>", "Sort direction (asc|desc)").action(entriesListCommand);
|
|
110361
|
-
entries.command("get").description("Get a single entry").argument("<typeName>", "Content type name").argument("<
|
|
110341
|
+
entries.command("get").description("Get a single entry").argument("<typeName>", "Content type name").argument("<id>", "Entry ID").option("-C, --cwd <dir>", "Project directory").option("--locale <locale>", "Locale to read (default en)").action(entriesGetCommand);
|
|
110362
110342
|
entries.command("create").description("Create a new entry").argument("<typeName>", "Content type name").option("-C, --cwd <dir>", "Project directory").requiredOption("--body <json>", "Entry JSON body (slug + data)").option("--locale <locale>", "Entry locale (default en)").option("--document-id <id>", "Document ID shared by localized variants").action(entriesCreateCommand);
|
|
110363
|
-
entries.command("update").description("Update an existing entry").argument("<typeName>", "Content type name").argument("<
|
|
110364
|
-
entries.command("delete").description("Delete an entry").argument("<typeName>", "Content type name").argument("<
|
|
110343
|
+
entries.command("update").description("Update an existing entry").argument("<typeName>", "Content type name").argument("<id>", "Entry ID").option("-C, --cwd <dir>", "Project directory").requiredOption("--body <json>", "Updated entry JSON body").option("--locale <locale>", "Entry locale").option("--document-id <id>", "Document ID shared by localized variants").action(entriesUpdateCommand);
|
|
110344
|
+
entries.command("delete").description("Delete an entry").argument("<typeName>", "Content type name").argument("<id>", "Entry ID").option("-C, --cwd <dir>", "Project directory").action(entriesDeleteCommand);
|
|
110365
110345
|
var assets2 = program.command("assets").description("Manage media assets");
|
|
110366
110346
|
assets2.command("list").description("List assets").option("-C, --cwd <dir>", "Project directory").option("--parent-id <id>", "Filter by parent folder").option(
|
|
110367
110347
|
"--search <query>",
|
|
@@ -71,7 +71,7 @@ export async function resolveMetaEntries(url) {
|
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
73
|
const { schema, queryField } = paramInfo;
|
|
74
|
-
const entryUrl = new URL(`${base}/
|
|
74
|
+
const entryUrl = new URL(`${base}/entries/${schema}/field/${encodeURIComponent(queryField)}/${encodeURIComponent(value)}`);
|
|
75
75
|
entryUrl.searchParams.set('locale', localeResolution.locale);
|
|
76
76
|
const res = await fetch(entryUrl);
|
|
77
77
|
if (res.ok) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retrieve-data-sources.d.ts","sourceRoot":"","sources":["../../../../src/runtime/content/utils/retrieve-data-sources.ts"],"names":[],"mappings":"AACA,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExC,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,
|
|
1
|
+
{"version":3,"file":"retrieve-data-sources.d.ts","sourceRoot":"","sources":["../../../../src/runtime/content/utils/retrieve-data-sources.ts"],"names":[],"mappings":"AACA,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExC,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AA8B9D;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,kBAAkB,CAiD/D"}
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
function parseRecordIdentity(token) {
|
|
2
|
-
if (!token.startsWith('v2:')) {
|
|
3
|
-
return { id: token };
|
|
4
|
-
}
|
|
5
|
-
const [version, documentId, encodedLocale, ...rest] = token.split(':');
|
|
6
|
-
if (version !== 'v2' || !documentId || !encodedLocale || rest.length > 0) {
|
|
7
|
-
return null;
|
|
8
|
-
}
|
|
9
|
-
try {
|
|
10
|
-
const locale = decodeURIComponent(encodedLocale);
|
|
11
|
-
return locale ? { id: documentId, locale } : null;
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
1
|
/**
|
|
18
2
|
* Checks if an element is genuinely visible to the user within the viewport.
|
|
19
3
|
* @param el The element to check.
|
|
@@ -54,13 +38,7 @@ export function retrieveVisibleDataSources() {
|
|
|
54
38
|
const parts = source.split('.');
|
|
55
39
|
// Expects the format "SchemaName.id.fieldName"
|
|
56
40
|
if (parts.length === 3) {
|
|
57
|
-
const [schemaName,
|
|
58
|
-
const identity = parseRecordIdentity(identityToken);
|
|
59
|
-
if (!identity) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const { id, locale } = identity;
|
|
63
|
-
const recordKey = JSON.stringify([id, locale ?? null]);
|
|
41
|
+
const [schemaName, id, fieldName] = parts;
|
|
64
42
|
// Skip __translations
|
|
65
43
|
if (schemaName === '__translations') {
|
|
66
44
|
return;
|
|
@@ -70,17 +48,16 @@ export function retrieveVisibleDataSources() {
|
|
|
70
48
|
tempGroupedData[schemaName] = {};
|
|
71
49
|
}
|
|
72
50
|
// Ensure the record (by ID) exists for this schema
|
|
73
|
-
if (!tempGroupedData[schemaName][
|
|
74
|
-
tempGroupedData[schemaName][
|
|
51
|
+
if (!tempGroupedData[schemaName][id]) {
|
|
52
|
+
tempGroupedData[schemaName][id] = {
|
|
75
53
|
id: id,
|
|
76
|
-
...(locale ? { locale } : {}),
|
|
77
54
|
data: {},
|
|
78
55
|
visible: isElementVisible(el),
|
|
79
56
|
};
|
|
80
57
|
}
|
|
81
58
|
// Add the field and its text content to the record
|
|
82
59
|
if (el.textContent) {
|
|
83
|
-
tempGroupedData[schemaName][
|
|
60
|
+
tempGroupedData[schemaName][id].data[fieldName] = el.textContent.trim();
|
|
84
61
|
}
|
|
85
62
|
}
|
|
86
63
|
});
|
|
@@ -35,7 +35,7 @@ function resolveApiBaseUrl(rootDir) {
|
|
|
35
35
|
return readEnvValue(rootDir, 'VITE_API_URL') ?? readEnvValue(rootDir, 'VITE_API_URL_DEV');
|
|
36
36
|
}
|
|
37
37
|
async function fetchEntries(baseUrl, schema, rootDir, locale) {
|
|
38
|
-
const url = new URL(`${baseUrl.replace(/\/$/, '')}/
|
|
38
|
+
const url = new URL(`${baseUrl.replace(/\/$/, '')}/entries/${schema}`);
|
|
39
39
|
url.searchParams.set('locale', locale);
|
|
40
40
|
if (isValidationBuild) {
|
|
41
41
|
url.searchParams.set('limit', '1');
|
|
@@ -42,6 +42,7 @@ export type ManyReferenceOps = {
|
|
|
42
42
|
};
|
|
43
43
|
export type FilterFor<T> = [T] extends [FimoString | string] ? string | StringOps : [T] extends [FimoBoolean | boolean] ? boolean | BoolOps : [T] extends [FimoDate | Date] ? string | DateOps : [T] extends [number] ? number | NumberOps : [T] extends [FimoPolymorphicReference | null] ? never : [T] extends [FimoPolymorphicReference[]] ? never : [T] extends [FimoReference | null] ? string | null | ReferenceOps : [T] extends [FimoReference[]] ? string | ManyReferenceOps : [T] extends [FimoMedia | FimoMedia[]] ? NullOnlyOps : [T] extends [FimoRichText] ? string | StringOps : NullOnlyOps;
|
|
44
44
|
type BaseTopLevelWhere = {
|
|
45
|
+
id?: string | StringOps;
|
|
45
46
|
documentId?: string | StringOps;
|
|
46
47
|
slug?: string | StringOps;
|
|
47
48
|
createdAt?: string | DateOps;
|
|
@@ -65,12 +66,9 @@ export type Fields<T> = Field<T> | readonly Field<T>[];
|
|
|
65
66
|
type SelectedField<TField> = TField extends `__fimo.${string}` ? '__fimo' : TField;
|
|
66
67
|
type SelectedFields<TFields> = TFields extends readonly (infer K)[] ? SelectedField<K> : SelectedField<TFields>;
|
|
67
68
|
type ListItem<TValue> = TValue extends readonly (infer K)[] ? K : TValue;
|
|
68
|
-
type EntryIdentityField<T> = Extract<'documentId' | 'locale', keyof T>;
|
|
69
69
|
export type Projected<T extends {
|
|
70
|
-
|
|
71
|
-
}, TFields extends Fields<T> | undefined> = [TFields] extends [
|
|
72
|
-
undefined
|
|
73
|
-
] ? T : Pick<T, EntryIdentityField<T> | Extract<SelectedFields<TFields>, keyof T>>;
|
|
70
|
+
id: string;
|
|
71
|
+
}, TFields extends Fields<T> | undefined> = [TFields] extends [undefined] ? T : Pick<T, Extract<'id' | SelectedFields<TFields>, keyof T>>;
|
|
74
72
|
export declare const FIMO_REFERENCES: unique symbol;
|
|
75
73
|
export interface WithReferences<TReferences> {
|
|
76
74
|
readonly [FIMO_REFERENCES]?: TReferences;
|
|
@@ -80,20 +78,20 @@ export type ReferenceField<TEntry> = Extract<keyof ReferenceMap<TEntry>, string>
|
|
|
80
78
|
export type Populate<TEntry> = ReferenceField<TEntry> | readonly ReferenceField<TEntry>[];
|
|
81
79
|
type PopulatedKeys<TEntry, TPopulate> = Extract<ListItem<TPopulate>, keyof ReferenceMap<TEntry> & keyof TEntry>;
|
|
82
80
|
export type Populated<TEntry extends {
|
|
83
|
-
|
|
84
|
-
}, TPopulate extends Populate<TEntry>> = Pick<TEntry,
|
|
81
|
+
id: string;
|
|
82
|
+
}, TPopulate extends Populate<TEntry>> = Pick<TEntry, 'id'> & Omit<TEntry, PopulatedKeys<TEntry, TPopulate>> & {
|
|
85
83
|
[K in PopulatedKeys<TEntry, TPopulate>]: ReferenceMap<TEntry>[K];
|
|
86
84
|
};
|
|
87
85
|
export type PopulatedResult<TEntry extends {
|
|
88
|
-
|
|
86
|
+
id: string;
|
|
89
87
|
}, TPopulate extends Populate<TEntry> | undefined> = [
|
|
90
88
|
TPopulate
|
|
91
89
|
] extends [undefined] ? TEntry : Populated<TEntry, NonNullable<TPopulate>>;
|
|
92
90
|
export type ProjectedWithPopulate<T extends {
|
|
93
|
-
|
|
94
|
-
}, TFields extends string | readonly string[] | undefined, TPopulate extends string | readonly string[] | undefined> = [TFields] extends [undefined] ? T : Pick<T,
|
|
91
|
+
id: string;
|
|
92
|
+
}, TFields extends string | readonly string[] | undefined, TPopulate extends string | readonly string[] | undefined> = [TFields] extends [undefined] ? T : Pick<T, Extract<'id' | SelectedFields<TFields> | ListItem<NonNullable<TPopulate>>, keyof T>>;
|
|
95
93
|
export type Query<T extends {
|
|
96
|
-
|
|
94
|
+
id: string;
|
|
97
95
|
}, TFields extends Fields<T> | undefined = Fields<T> | undefined, TPopulate extends string | readonly string[] | undefined = string | readonly string[] | undefined> = {
|
|
98
96
|
where?: Where<T>;
|
|
99
97
|
locale?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../src/runtime/primitives/lib/query.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../src/runtime/primitives/lib/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,9 +12,9 @@ describe('fimo/ui public type surface', () => {
|
|
|
12
12
|
expectTypeOf().toEqualTypeOf();
|
|
13
13
|
const localizedWhere = { locale: 'en' };
|
|
14
14
|
expectTypeOf(localizedWhere).toEqualTypeOf();
|
|
15
|
-
// @ts-expect-error
|
|
16
|
-
const
|
|
17
|
-
expectTypeOf(
|
|
15
|
+
// @ts-expect-error locale is not a filter on non-localized generated entry types.
|
|
16
|
+
const sharedWhere = { locale: 'en' };
|
|
17
|
+
expectTypeOf(sharedWhere).toEqualTypeOf();
|
|
18
18
|
});
|
|
19
19
|
it('supports the reference populate pattern emitted into generated schemas', () => {
|
|
20
20
|
const query = {
|
|
@@ -37,8 +37,6 @@ describe('syncSchemas', () => {
|
|
|
37
37
|
const post = readFileSync(join(scratch, 'src/schemas/Post.ts'), 'utf-8');
|
|
38
38
|
const postTypes = readFileSync(join(scratch, 'src/schemas/Post.types.ts'), 'utf-8');
|
|
39
39
|
expect(post).toContain('import { wrapWithSource as wrapAuthorWithSource } from "./Author";');
|
|
40
|
-
expect(post).toContain('isPopulatedEntry(value) ? wrapAuthorWithSource(value) : value');
|
|
41
|
-
expect(post).toContain('function isPopulatedEntry(value: unknown): value is PopulatedEntryRecord');
|
|
42
40
|
expect(post).toContain('import type { Post, PostInput, PostPopulate, PostResult, PostFields, PostQuery } from "./Post.types";');
|
|
43
41
|
expect(post).toContain('from "./Post.types";');
|
|
44
42
|
expect(post).not.toContain('import type { Author } from "./Author";');
|
|
@@ -49,14 +47,9 @@ describe('syncSchemas', () => {
|
|
|
49
47
|
expect(post).toContain('wrapAuthorWithSource(value)');
|
|
50
48
|
expect(post).toContain('wrapWithSource(value)');
|
|
51
49
|
expect(post).toContain('export async function create(payload: PostInput): Promise<Post>');
|
|
52
|
-
expect(post).toContain('export async function getByDocumentId');
|
|
53
|
-
expect(post).toContain('/v2/entries/Post/');
|
|
54
50
|
expect(post).toContain('return wrapWithSource(data.data);');
|
|
55
51
|
expect(postTypes).toContain('import type { Author } from "./Author.types";');
|
|
56
52
|
expect(postTypes).toContain('export interface Post extends WithReferences<PostReferences>');
|
|
57
|
-
expect(postTypes).not.toContain(' id: string;');
|
|
58
|
-
expect(postTypes).toContain(' documentId: string;');
|
|
59
|
-
expect(postTypes).toContain(' locale: string;');
|
|
60
53
|
expect(postTypes).toContain('type FimoReference');
|
|
61
54
|
expect(postTypes).toContain('author: FimoReference | null;');
|
|
62
55
|
expect(postTypes).toContain('contributors: FimoReference[];');
|
|
@@ -95,15 +88,15 @@ describe('syncSchemas', () => {
|
|
|
95
88
|
const settings = readFileSync(join(scratch, 'src/schemas/Settings.ts'), 'utf-8');
|
|
96
89
|
const settingsTypes = readFileSync(join(scratch, 'src/schemas/Settings.types.ts'), 'utf-8');
|
|
97
90
|
const homepageTypes = readFileSync(join(scratch, 'src/schemas/Homepage.types.ts'), 'utf-8');
|
|
98
|
-
expect(settingsTypes).toContain('locale: string;');
|
|
91
|
+
expect(settingsTypes).not.toContain('locale: string;');
|
|
99
92
|
expect(settingsTypes).not.toContain('locale?: string;');
|
|
100
93
|
expect(homepageTypes).toContain('locale: string;');
|
|
101
94
|
expect(settings).toContain('const LOCALIZED_CONTENT = false;');
|
|
102
95
|
expect(settings).toContain('const LOCALIZED_REFERENCE_FIELDS = new Set<string>(["homepage"]);');
|
|
103
|
-
expect(settings).toContain(' locale,');
|
|
96
|
+
expect(settings).not.toContain(' locale: entry.locale,');
|
|
104
97
|
expect(settings).toContain('readLocale(params, LOCALIZED_CONTENT, useQueryLocale(params.locale))');
|
|
105
98
|
expect(settings.match(/readLocale\(params, LOCALIZED_CONTENT, useQueryLocale\(params\.locale\)\)/g)?.length).toBe(4);
|
|
106
|
-
expect(settings.match(/
|
|
99
|
+
expect(settings.match(/readLocale\(options, false, useQueryLocale\(options\.locale\)\)/g)?.length).toBe(2);
|
|
107
100
|
});
|
|
108
101
|
it('generates singleton document APIs without collection mutations', () => {
|
|
109
102
|
writeSchema('Settings', {
|
|
@@ -117,10 +110,6 @@ describe('syncSchemas', () => {
|
|
|
117
110
|
const settings = readFileSync(join(scratch, 'src/schemas/Settings.ts'), 'utf-8');
|
|
118
111
|
const settingsTypes = readFileSync(join(scratch, 'src/schemas/Settings.types.ts'), 'utf-8');
|
|
119
112
|
expect(settings).toContain('fetch(`${base}${withReadOptions(`/documents/Settings`, options)}`');
|
|
120
|
-
expect(settings).toContain('const usesV2Identity = typeof id !== "string";');
|
|
121
|
-
expect(settings).toContain('`Settings.v2:${documentId}:${encodeURIComponent(locale)}`');
|
|
122
|
-
expect(settingsTypes).toContain('id?: string;');
|
|
123
|
-
expect(settingsTypes).toContain('locale?: string;');
|
|
124
113
|
expect(settings).toContain('export async function update(payload: Partial<SettingsInput>)');
|
|
125
114
|
expect(settings).toContain('export function useSuspenseGet');
|
|
126
115
|
expect(settings).not.toContain('export async function create(');
|
package/package.json
CHANGED