@decocms/blocks 7.20.5 → 7.20.7
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/package.json +1 -1
- package/src/cms/schema.test.ts +21 -0
- package/src/cms/schema.ts +14 -0
package/package.json
CHANGED
package/src/cms/schema.test.ts
CHANGED
|
@@ -237,3 +237,24 @@ describe("composeMeta framework option", () => {
|
|
|
237
237
|
expect(meta.manifest.blocks.pages).toHaveProperty("website/pages/Page.tsx");
|
|
238
238
|
});
|
|
239
239
|
});
|
|
240
|
+
|
|
241
|
+
describe("composeMeta idempotency", () => {
|
|
242
|
+
it("returns an already-composed meta unchanged (no double-compose)", () => {
|
|
243
|
+
const once = composeMeta(emptySiteMeta());
|
|
244
|
+
const twice = composeMeta(once);
|
|
245
|
+
// The sentinel is the top-level `framework` field, which only composeMeta
|
|
246
|
+
// sets — re-composing must be a no-op, returning the same object.
|
|
247
|
+
expect(twice).toBe(once);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it("does not duplicate framework section refs when re-composed", () => {
|
|
251
|
+
// Simulate the tanstack runtime path: a self-contained meta.gen.json (baked
|
|
252
|
+
// at gen time) is loaded from disk and composeMeta runs again on top of it.
|
|
253
|
+
const composed = composeMeta(emptySiteMeta());
|
|
254
|
+
const sectionsAnyOf = composed.schema.root.sections.anyOf;
|
|
255
|
+
const recomposed = composeMeta(composed);
|
|
256
|
+
// Without the guard, framework section refs (Lazy/Seo/…) would be appended
|
|
257
|
+
// to root.sections.anyOf a second time.
|
|
258
|
+
expect(recomposed.schema.root.sections.anyOf).toHaveLength(sectionsAnyOf.length);
|
|
259
|
+
});
|
|
260
|
+
});
|
package/src/cms/schema.ts
CHANGED
|
@@ -1007,6 +1007,20 @@ export function composeMeta(
|
|
|
1007
1007
|
siteMeta: MetaResponse,
|
|
1008
1008
|
options?: ComposeMetaOptions,
|
|
1009
1009
|
): MetaResponse {
|
|
1010
|
+
// Idempotency guard. composeMeta is NOT structurally idempotent — it appends
|
|
1011
|
+
// the framework section refs to `root.sections.anyOf` (and `__SECTION_REF__`),
|
|
1012
|
+
// so composing an already-composed meta a second time duplicates those refs.
|
|
1013
|
+
// Since self-contained meta.gen.json is now baked at generation time (via the
|
|
1014
|
+
// CLI's --compose), the tanstack runtime re-runs composeMeta on the file it
|
|
1015
|
+
// loads from disk. A composed meta always carries a top-level `framework`
|
|
1016
|
+
// field, which raw generateMeta() output never sets — use it as the sentinel
|
|
1017
|
+
// and return the already-composed meta unchanged. Raw metas (framework unset,
|
|
1018
|
+
// e.g. sites generated by an older CLI) still compose normally, so this stays
|
|
1019
|
+
// backward compatible.
|
|
1020
|
+
if (siteMeta.framework) {
|
|
1021
|
+
return siteMeta;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1010
1024
|
const siteAnyOf = siteMeta.schema?.root?.sections?.anyOf || [];
|
|
1011
1025
|
|
|
1012
1026
|
// Build all framework components
|