@roottale/cms-core 0.58.0 → 0.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.cjs +11 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -12
- package/dist/index.d.ts +17 -12
- package/dist/index.js +11 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -475,15 +475,16 @@ declare function injectStableIdsTree(blocks: readonly (Omit<Block, "_id"> & {
|
|
|
475
475
|
* 공통 블록(Site Patterns) — 여러 글에 같은 자리로 붙는 재사용 블록의 순수 규칙.
|
|
476
476
|
*
|
|
477
477
|
* 블록 본문은 ROOT-ADMIN 이 `site_patterns` 에 저장하고, "어느 자리(slot)에 어느
|
|
478
|
-
*
|
|
479
|
-
* 으로 정한다.
|
|
478
|
+
* 콘텐츠 모델(`model_key`)의 글이면 어떤 블록"인지는 배치 규칙
|
|
479
|
+
* (`settings.site_pattern_placements`)으로 정한다. 유형의 단위는 콘텐츠 모델이다 —
|
|
480
|
+
* 컬렉션 설정(ADR-0060)은 ADR-0105 로 폐기 중이라 규칙 키로 쓰지 않는다. 공개 API 는 글마다 `pattern_slots`(자리 → 블록 key | null) 를 계산해
|
|
480
481
|
* 내려주므로 FRONT 는 규칙을 몰라도 된다. 이 파일은 api-core(계산)·tenant-admin(편집)·
|
|
481
482
|
* cms-renderer-next(렌더)가 같은 판정을 공유하기 위한 프레임워크 비의존 모듈이다.
|
|
482
483
|
*
|
|
483
484
|
* 규칙 판정:
|
|
484
485
|
* - 자리는 `SITE_PATTERN_SLOTS` 에 선언된 것만 계산한다(미선언 자리는 무시).
|
|
485
|
-
* - 글의 `
|
|
486
|
-
* - 없으면 `
|
|
486
|
+
* - 글의 `modelKey` 와 같은 규칙이 있으면 그 규칙(블록 없음 = null 도 명시적 결정).
|
|
487
|
+
* - 없으면 `modelKey: null`(모든 글 기본) 규칙.
|
|
487
488
|
* - 가리키는 블록이 발행 상태가 아니면 null(FRONT 가 미발행 블록을 그리지 않게).
|
|
488
489
|
*/
|
|
489
490
|
/** 블록을 놓을 수 있는 자리. key 는 공개 API `pattern_slots` 의 키와 같다. */
|
|
@@ -501,12 +502,12 @@ declare const SITE_PATTERN_KEY_PATTERN: RegExp;
|
|
|
501
502
|
declare function isValidSitePatternKey(key: string): boolean;
|
|
502
503
|
declare function isSitePatternSlotKey(value: string): value is SitePatternSlotKey;
|
|
503
504
|
/**
|
|
504
|
-
* 배치 규칙 1건. `
|
|
505
|
+
* 배치 규칙 1건. `modelKey: null` = 모든 글의 기본값, 문자열 = 그 콘텐츠 모델의 글만.
|
|
505
506
|
* `patternKey: null` = 이 자리에 블록을 놓지 않는다(유형 규칙이면 기본값 덮어쓰기).
|
|
506
507
|
*/
|
|
507
508
|
interface SitePatternPlacementRule {
|
|
508
509
|
readonly slot: SitePatternSlotKey;
|
|
509
|
-
readonly
|
|
510
|
+
readonly modelKey: string | null;
|
|
510
511
|
readonly patternKey: string | null;
|
|
511
512
|
}
|
|
512
513
|
interface SitePatternPlacements {
|
|
@@ -517,26 +518,30 @@ declare const EMPTY_SITE_PATTERN_PLACEMENTS: SitePatternPlacements;
|
|
|
517
518
|
type PatternSlots = Record<string, string | null>;
|
|
518
519
|
/**
|
|
519
520
|
* 저장된 값(unknown) → 정규화된 배치 규칙. 형식이 틀린 항목·미선언 자리는 버리고,
|
|
520
|
-
* 같은 (slot,
|
|
521
|
+
* 같은 (slot, modelKey) 는 마지막 항목이 이긴다. 이중 인코딩된 JSON 문자열도 받는다.
|
|
522
|
+
* 2026-08-19 이전에 저장된 규칙은 `collectionKey` 필드를 썼다 — `modelKey` 가 없으면 그
|
|
523
|
+
* 값을 읽는다(실측상 남은 규칙은 기본값 `null` 뿐이라 의미가 같다). 다시 저장하면
|
|
524
|
+
* `modelKey` 로 쓰인다.
|
|
521
525
|
*/
|
|
522
526
|
declare function readSitePatternPlacements(raw: unknown): SitePatternPlacements;
|
|
523
|
-
/** (slot,
|
|
524
|
-
declare function findSitePatternPlacementRule(placements: SitePatternPlacements, slot: SitePatternSlotKey,
|
|
527
|
+
/** (slot, modelKey) 에 해당하는 규칙. 없으면 undefined(= 기본값으로 위임). */
|
|
528
|
+
declare function findSitePatternPlacementRule(placements: SitePatternPlacements, slot: SitePatternSlotKey, modelKey: string | null): SitePatternPlacementRule | undefined;
|
|
525
529
|
/**
|
|
526
530
|
* 규칙 1건을 갈아 끼운 새 배치 규칙을 돌려준다(불변). `patternKey: undefined` 는
|
|
527
531
|
* "규칙 삭제 = 기본값으로 위임"이다 — 유형 규칙에서 "표시 안 함"(null)과 구분된다.
|
|
528
532
|
*/
|
|
529
533
|
declare function setSitePatternPlacementRule(placements: SitePatternPlacements, target: {
|
|
530
534
|
slot: SitePatternSlotKey;
|
|
531
|
-
|
|
535
|
+
modelKey: string | null;
|
|
532
536
|
}, patternKey: string | null | undefined): SitePatternPlacements;
|
|
533
537
|
/** 선언된 자리마다 null 인 빈 결과 — 규칙이나 발행 블록이 없을 때의 기본 응답. */
|
|
534
538
|
declare function emptyPatternSlots(): PatternSlots;
|
|
535
539
|
/**
|
|
536
|
-
* 글 1건의 자리별 블록 key 를 계산한다. `
|
|
540
|
+
* 글 1건의 자리별 블록 key 를 계산한다. 글의 콘텐츠 모델(`modelKey`) 규칙 > 모든 글 기본
|
|
541
|
+
* 규칙. `publishedKeys` 에 없는 블록(미발행·삭제)은 null.
|
|
537
542
|
*/
|
|
538
543
|
declare function resolvePatternSlots(post: {
|
|
539
|
-
readonly
|
|
544
|
+
readonly modelKey: string | null;
|
|
540
545
|
}, placements: SitePatternPlacements, publishedKeys: ReadonlySet<string>): PatternSlots;
|
|
541
546
|
/**
|
|
542
547
|
* 규칙에서 참조하는 블록 key 집합 — 어드민이 "이 블록은 어디에 쓰이는가"를 표시하거나
|
package/dist/index.d.ts
CHANGED
|
@@ -475,15 +475,16 @@ declare function injectStableIdsTree(blocks: readonly (Omit<Block, "_id"> & {
|
|
|
475
475
|
* 공통 블록(Site Patterns) — 여러 글에 같은 자리로 붙는 재사용 블록의 순수 규칙.
|
|
476
476
|
*
|
|
477
477
|
* 블록 본문은 ROOT-ADMIN 이 `site_patterns` 에 저장하고, "어느 자리(slot)에 어느
|
|
478
|
-
*
|
|
479
|
-
* 으로 정한다.
|
|
478
|
+
* 콘텐츠 모델(`model_key`)의 글이면 어떤 블록"인지는 배치 규칙
|
|
479
|
+
* (`settings.site_pattern_placements`)으로 정한다. 유형의 단위는 콘텐츠 모델이다 —
|
|
480
|
+
* 컬렉션 설정(ADR-0060)은 ADR-0105 로 폐기 중이라 규칙 키로 쓰지 않는다. 공개 API 는 글마다 `pattern_slots`(자리 → 블록 key | null) 를 계산해
|
|
480
481
|
* 내려주므로 FRONT 는 규칙을 몰라도 된다. 이 파일은 api-core(계산)·tenant-admin(편집)·
|
|
481
482
|
* cms-renderer-next(렌더)가 같은 판정을 공유하기 위한 프레임워크 비의존 모듈이다.
|
|
482
483
|
*
|
|
483
484
|
* 규칙 판정:
|
|
484
485
|
* - 자리는 `SITE_PATTERN_SLOTS` 에 선언된 것만 계산한다(미선언 자리는 무시).
|
|
485
|
-
* - 글의 `
|
|
486
|
-
* - 없으면 `
|
|
486
|
+
* - 글의 `modelKey` 와 같은 규칙이 있으면 그 규칙(블록 없음 = null 도 명시적 결정).
|
|
487
|
+
* - 없으면 `modelKey: null`(모든 글 기본) 규칙.
|
|
487
488
|
* - 가리키는 블록이 발행 상태가 아니면 null(FRONT 가 미발행 블록을 그리지 않게).
|
|
488
489
|
*/
|
|
489
490
|
/** 블록을 놓을 수 있는 자리. key 는 공개 API `pattern_slots` 의 키와 같다. */
|
|
@@ -501,12 +502,12 @@ declare const SITE_PATTERN_KEY_PATTERN: RegExp;
|
|
|
501
502
|
declare function isValidSitePatternKey(key: string): boolean;
|
|
502
503
|
declare function isSitePatternSlotKey(value: string): value is SitePatternSlotKey;
|
|
503
504
|
/**
|
|
504
|
-
* 배치 규칙 1건. `
|
|
505
|
+
* 배치 규칙 1건. `modelKey: null` = 모든 글의 기본값, 문자열 = 그 콘텐츠 모델의 글만.
|
|
505
506
|
* `patternKey: null` = 이 자리에 블록을 놓지 않는다(유형 규칙이면 기본값 덮어쓰기).
|
|
506
507
|
*/
|
|
507
508
|
interface SitePatternPlacementRule {
|
|
508
509
|
readonly slot: SitePatternSlotKey;
|
|
509
|
-
readonly
|
|
510
|
+
readonly modelKey: string | null;
|
|
510
511
|
readonly patternKey: string | null;
|
|
511
512
|
}
|
|
512
513
|
interface SitePatternPlacements {
|
|
@@ -517,26 +518,30 @@ declare const EMPTY_SITE_PATTERN_PLACEMENTS: SitePatternPlacements;
|
|
|
517
518
|
type PatternSlots = Record<string, string | null>;
|
|
518
519
|
/**
|
|
519
520
|
* 저장된 값(unknown) → 정규화된 배치 규칙. 형식이 틀린 항목·미선언 자리는 버리고,
|
|
520
|
-
* 같은 (slot,
|
|
521
|
+
* 같은 (slot, modelKey) 는 마지막 항목이 이긴다. 이중 인코딩된 JSON 문자열도 받는다.
|
|
522
|
+
* 2026-08-19 이전에 저장된 규칙은 `collectionKey` 필드를 썼다 — `modelKey` 가 없으면 그
|
|
523
|
+
* 값을 읽는다(실측상 남은 규칙은 기본값 `null` 뿐이라 의미가 같다). 다시 저장하면
|
|
524
|
+
* `modelKey` 로 쓰인다.
|
|
521
525
|
*/
|
|
522
526
|
declare function readSitePatternPlacements(raw: unknown): SitePatternPlacements;
|
|
523
|
-
/** (slot,
|
|
524
|
-
declare function findSitePatternPlacementRule(placements: SitePatternPlacements, slot: SitePatternSlotKey,
|
|
527
|
+
/** (slot, modelKey) 에 해당하는 규칙. 없으면 undefined(= 기본값으로 위임). */
|
|
528
|
+
declare function findSitePatternPlacementRule(placements: SitePatternPlacements, slot: SitePatternSlotKey, modelKey: string | null): SitePatternPlacementRule | undefined;
|
|
525
529
|
/**
|
|
526
530
|
* 규칙 1건을 갈아 끼운 새 배치 규칙을 돌려준다(불변). `patternKey: undefined` 는
|
|
527
531
|
* "규칙 삭제 = 기본값으로 위임"이다 — 유형 규칙에서 "표시 안 함"(null)과 구분된다.
|
|
528
532
|
*/
|
|
529
533
|
declare function setSitePatternPlacementRule(placements: SitePatternPlacements, target: {
|
|
530
534
|
slot: SitePatternSlotKey;
|
|
531
|
-
|
|
535
|
+
modelKey: string | null;
|
|
532
536
|
}, patternKey: string | null | undefined): SitePatternPlacements;
|
|
533
537
|
/** 선언된 자리마다 null 인 빈 결과 — 규칙이나 발행 블록이 없을 때의 기본 응답. */
|
|
534
538
|
declare function emptyPatternSlots(): PatternSlots;
|
|
535
539
|
/**
|
|
536
|
-
* 글 1건의 자리별 블록 key 를 계산한다. `
|
|
540
|
+
* 글 1건의 자리별 블록 key 를 계산한다. 글의 콘텐츠 모델(`modelKey`) 규칙 > 모든 글 기본
|
|
541
|
+
* 규칙. `publishedKeys` 에 없는 블록(미발행·삭제)은 null.
|
|
537
542
|
*/
|
|
538
543
|
declare function resolvePatternSlots(post: {
|
|
539
|
-
readonly
|
|
544
|
+
readonly modelKey: string | null;
|
|
540
545
|
}, placements: SitePatternPlacements, publishedKeys: ReadonlySet<string>): PatternSlots;
|
|
541
546
|
/**
|
|
542
547
|
* 규칙에서 참조하는 블록 key 집합 — 어드민이 "이 블록은 어디에 쓰이는가"를 표시하거나
|
package/dist/index.js
CHANGED
|
@@ -1455,34 +1455,31 @@ function readSitePatternPlacements(raw) {
|
|
|
1455
1455
|
if (!isRecord(item)) continue;
|
|
1456
1456
|
const slot = typeof item.slot === "string" ? item.slot : "";
|
|
1457
1457
|
if (!isSitePatternSlotKey(slot)) continue;
|
|
1458
|
-
const
|
|
1459
|
-
|
|
1458
|
+
const modelKey = readNullableKey(
|
|
1459
|
+
item.modelKey === void 0 ? item.collectionKey : item.modelKey
|
|
1460
|
+
);
|
|
1461
|
+
if (modelKey === void 0) continue;
|
|
1460
1462
|
const patternKey = readNullableKey(item.patternKey);
|
|
1461
1463
|
if (patternKey === void 0) continue;
|
|
1462
1464
|
if (patternKey !== null && !isValidSitePatternKey(patternKey)) continue;
|
|
1463
|
-
byTarget.set(`${slot}\0${
|
|
1465
|
+
byTarget.set(`${slot}\0${modelKey ?? ""}`, {
|
|
1464
1466
|
slot,
|
|
1465
|
-
|
|
1467
|
+
modelKey,
|
|
1466
1468
|
patternKey
|
|
1467
1469
|
});
|
|
1468
1470
|
}
|
|
1469
1471
|
return { rules: [...byTarget.values()] };
|
|
1470
1472
|
}
|
|
1471
|
-
function findSitePatternPlacementRule(placements, slot,
|
|
1472
|
-
return placements.rules.find(
|
|
1473
|
-
(rule) => rule.slot === slot && rule.collectionKey === collectionKey
|
|
1474
|
-
);
|
|
1473
|
+
function findSitePatternPlacementRule(placements, slot, modelKey) {
|
|
1474
|
+
return placements.rules.find((rule) => rule.slot === slot && rule.modelKey === modelKey);
|
|
1475
1475
|
}
|
|
1476
1476
|
function setSitePatternPlacementRule(placements, target, patternKey) {
|
|
1477
1477
|
const rest = placements.rules.filter(
|
|
1478
|
-
(rule) => !(rule.slot === target.slot && rule.
|
|
1478
|
+
(rule) => !(rule.slot === target.slot && rule.modelKey === target.modelKey)
|
|
1479
1479
|
);
|
|
1480
1480
|
if (patternKey === void 0) return { rules: rest };
|
|
1481
1481
|
return {
|
|
1482
|
-
rules: [
|
|
1483
|
-
...rest,
|
|
1484
|
-
{ slot: target.slot, collectionKey: target.collectionKey, patternKey }
|
|
1485
|
-
]
|
|
1482
|
+
rules: [...rest, { slot: target.slot, modelKey: target.modelKey, patternKey }]
|
|
1486
1483
|
};
|
|
1487
1484
|
}
|
|
1488
1485
|
function emptyPatternSlots() {
|
|
@@ -1491,7 +1488,7 @@ function emptyPatternSlots() {
|
|
|
1491
1488
|
function resolvePatternSlots(post, placements, publishedKeys) {
|
|
1492
1489
|
const slots = emptyPatternSlots();
|
|
1493
1490
|
for (const slot of SITE_PATTERN_SLOTS) {
|
|
1494
|
-
const specific = post.
|
|
1491
|
+
const specific = post.modelKey !== null ? findSitePatternPlacementRule(placements, slot.key, post.modelKey) : void 0;
|
|
1495
1492
|
const rule = specific ?? findSitePatternPlacementRule(placements, slot.key, null);
|
|
1496
1493
|
const key = rule?.patternKey ?? null;
|
|
1497
1494
|
slots[slot.key] = key !== null && publishedKeys.has(key) ? key : null;
|