@zalkera/client 0.14.0 → 0.15.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/dist/index.d.cts CHANGED
@@ -949,7 +949,7 @@ declare class ZalkeraError extends Error {
949
949
  * 이 패키지는 그 방언을 읽는 헬퍼([asHandle]·[asHandleArray]·[assetPath]·[readConfig])를 실어 나른다.
950
950
  * 그래서 아래 `SECTION_CONTRACT` 리터럴은 rev 3 과 **바이트 동일**하다(동기 스크립트가 확인한다).
951
951
  */
952
- declare const SECTION_CONTRACT_REV = 4;
952
+ declare const SECTION_CONTRACT_REV = 5;
953
953
  /** 업종 분류 — 콘솔 섹션 픽커의 그룹핑에 쓴다(테넌트 업종 필드는 아직 없다·memo102 §5). */
954
954
  type SectionVertical = "BEAUTY" | "GENERAL";
955
955
  interface SectionSpec {
@@ -972,6 +972,17 @@ interface SectionSpec {
972
972
  * **필수성의 집행 지점은 팩/시드뿐이다** — 런타임은 그대로 관용이다(렌더러 스킵·콘솔 raw 편집 허용).
973
973
  */
974
974
  readonly requiredRefs: readonly string[];
975
+ /**
976
+ * **참조 그룹**(rev 5) — 각 그룹에서 **하나 이상**이 채워져야 한다.
977
+ *
978
+ * rev 3 은 필수성을 키 하나(`productIds`)에 걸었는데, rev 5 에서 갈래 참조(`categorySlug`)가 같은
979
+ * 역할을 하게 되면서 필수의 단위가 **"참조 존재"**로 옮겨갔다. 막으려는 것은 그대로다 — 아무것도
980
+ * 안 가리킨 채 시드에 들어와 개시 직후 조용히 사라지는 섹션.
981
+ *
982
+ * `requiredRefs`(무조건 필수)와 **함께** 쓴다: 그룹으로 표현되는 섹션은 `requiredRefs` 가 빈 배열이고,
983
+ * 종전처럼 단일 키가 무조건 필수인 섹션은 이 필드가 빈 배열이다. 둘 다 빈 배열이면 참조 요구가 없다.
984
+ */
985
+ readonly requiredRefsAnyOf: readonly (readonly string[])[];
975
986
  }
976
987
  /**
977
988
  * 아는 섹션 전량. **순서는 콘솔 픽커의 노출 순서**(관행 아크: 주목→가치→신뢰→행동).
@@ -985,62 +996,74 @@ declare const SECTION_CONTRACT: readonly [{
985
996
  readonly type: "SERVICE_MENU";
986
997
  readonly vertical: "BEAUTY";
987
998
  readonly jsonLd: "ItemList";
988
- readonly requiredRefs: readonly ["productIds"];
999
+ readonly requiredRefs: readonly [];
1000
+ readonly requiredRefsAnyOf: readonly [readonly ["productIds", "categorySlug"]];
989
1001
  }, {
990
1002
  readonly type: "BEFORE_AFTER_GALLERY";
991
1003
  readonly vertical: "BEAUTY";
992
1004
  readonly jsonLd: null;
993
1005
  readonly requiredRefs: readonly [];
1006
+ readonly requiredRefsAnyOf: readonly [];
994
1007
  }, {
995
1008
  readonly type: "BOOKING_CTA";
996
1009
  readonly vertical: "BEAUTY";
997
1010
  readonly jsonLd: null;
998
- readonly requiredRefs: readonly ["productId"];
1011
+ readonly requiredRefs: readonly [];
1012
+ readonly requiredRefsAnyOf: readonly [readonly ["productId", "categorySlug"]];
999
1013
  }, {
1000
1014
  readonly type: "DOCTOR_INTRO";
1001
1015
  readonly vertical: "BEAUTY";
1002
1016
  readonly jsonLd: null;
1003
1017
  readonly requiredRefs: readonly [];
1018
+ readonly requiredRefsAnyOf: readonly [];
1004
1019
  }, {
1005
1020
  readonly type: "HERO";
1006
1021
  readonly vertical: "GENERAL";
1007
1022
  readonly jsonLd: null;
1008
1023
  readonly requiredRefs: readonly [];
1024
+ readonly requiredRefsAnyOf: readonly [];
1009
1025
  }, {
1010
1026
  readonly type: "FEATURE_GRID";
1011
1027
  readonly vertical: "GENERAL";
1012
1028
  readonly jsonLd: null;
1013
1029
  readonly requiredRefs: readonly [];
1030
+ readonly requiredRefsAnyOf: readonly [];
1014
1031
  }, {
1015
1032
  readonly type: "TEXT_MEDIA";
1016
1033
  readonly vertical: "GENERAL";
1017
1034
  readonly jsonLd: null;
1018
1035
  readonly requiredRefs: readonly [];
1036
+ readonly requiredRefsAnyOf: readonly [];
1019
1037
  }, {
1020
1038
  readonly type: "LOGO_WALL";
1021
1039
  readonly vertical: "GENERAL";
1022
1040
  readonly jsonLd: null;
1023
1041
  readonly requiredRefs: readonly [];
1042
+ readonly requiredRefsAnyOf: readonly [];
1024
1043
  }, {
1025
1044
  readonly type: "STATS_BAND";
1026
1045
  readonly vertical: "GENERAL";
1027
1046
  readonly jsonLd: null;
1028
1047
  readonly requiredRefs: readonly [];
1048
+ readonly requiredRefsAnyOf: readonly [];
1029
1049
  }, {
1030
1050
  readonly type: "TESTIMONIALS";
1031
1051
  readonly vertical: "GENERAL";
1032
1052
  readonly jsonLd: null;
1033
1053
  readonly requiredRefs: readonly [];
1054
+ readonly requiredRefsAnyOf: readonly [];
1034
1055
  }, {
1035
1056
  readonly type: "FAQ_LIST";
1036
1057
  readonly vertical: "GENERAL";
1037
1058
  readonly jsonLd: "FAQPage";
1038
1059
  readonly requiredRefs: readonly [];
1060
+ readonly requiredRefsAnyOf: readonly [];
1039
1061
  }, {
1040
1062
  readonly type: "LEAD_CTA";
1041
1063
  readonly vertical: "GENERAL";
1042
1064
  readonly jsonLd: null;
1043
1065
  readonly requiredRefs: readonly [];
1066
+ readonly requiredRefsAnyOf: readonly [];
1044
1067
  }];
1045
1068
  /** 지금 렌더러가 아는 섹션 타입. 이 밖의 값이 와도 정상이다(스킵). */
1046
1069
  type KnownSectionType = (typeof SECTION_CONTRACT)[number]["type"];
package/dist/index.d.ts CHANGED
@@ -949,7 +949,7 @@ declare class ZalkeraError extends Error {
949
949
  * 이 패키지는 그 방언을 읽는 헬퍼([asHandle]·[asHandleArray]·[assetPath]·[readConfig])를 실어 나른다.
950
950
  * 그래서 아래 `SECTION_CONTRACT` 리터럴은 rev 3 과 **바이트 동일**하다(동기 스크립트가 확인한다).
951
951
  */
952
- declare const SECTION_CONTRACT_REV = 4;
952
+ declare const SECTION_CONTRACT_REV = 5;
953
953
  /** 업종 분류 — 콘솔 섹션 픽커의 그룹핑에 쓴다(테넌트 업종 필드는 아직 없다·memo102 §5). */
954
954
  type SectionVertical = "BEAUTY" | "GENERAL";
955
955
  interface SectionSpec {
@@ -972,6 +972,17 @@ interface SectionSpec {
972
972
  * **필수성의 집행 지점은 팩/시드뿐이다** — 런타임은 그대로 관용이다(렌더러 스킵·콘솔 raw 편집 허용).
973
973
  */
974
974
  readonly requiredRefs: readonly string[];
975
+ /**
976
+ * **참조 그룹**(rev 5) — 각 그룹에서 **하나 이상**이 채워져야 한다.
977
+ *
978
+ * rev 3 은 필수성을 키 하나(`productIds`)에 걸었는데, rev 5 에서 갈래 참조(`categorySlug`)가 같은
979
+ * 역할을 하게 되면서 필수의 단위가 **"참조 존재"**로 옮겨갔다. 막으려는 것은 그대로다 — 아무것도
980
+ * 안 가리킨 채 시드에 들어와 개시 직후 조용히 사라지는 섹션.
981
+ *
982
+ * `requiredRefs`(무조건 필수)와 **함께** 쓴다: 그룹으로 표현되는 섹션은 `requiredRefs` 가 빈 배열이고,
983
+ * 종전처럼 단일 키가 무조건 필수인 섹션은 이 필드가 빈 배열이다. 둘 다 빈 배열이면 참조 요구가 없다.
984
+ */
985
+ readonly requiredRefsAnyOf: readonly (readonly string[])[];
975
986
  }
976
987
  /**
977
988
  * 아는 섹션 전량. **순서는 콘솔 픽커의 노출 순서**(관행 아크: 주목→가치→신뢰→행동).
@@ -985,62 +996,74 @@ declare const SECTION_CONTRACT: readonly [{
985
996
  readonly type: "SERVICE_MENU";
986
997
  readonly vertical: "BEAUTY";
987
998
  readonly jsonLd: "ItemList";
988
- readonly requiredRefs: readonly ["productIds"];
999
+ readonly requiredRefs: readonly [];
1000
+ readonly requiredRefsAnyOf: readonly [readonly ["productIds", "categorySlug"]];
989
1001
  }, {
990
1002
  readonly type: "BEFORE_AFTER_GALLERY";
991
1003
  readonly vertical: "BEAUTY";
992
1004
  readonly jsonLd: null;
993
1005
  readonly requiredRefs: readonly [];
1006
+ readonly requiredRefsAnyOf: readonly [];
994
1007
  }, {
995
1008
  readonly type: "BOOKING_CTA";
996
1009
  readonly vertical: "BEAUTY";
997
1010
  readonly jsonLd: null;
998
- readonly requiredRefs: readonly ["productId"];
1011
+ readonly requiredRefs: readonly [];
1012
+ readonly requiredRefsAnyOf: readonly [readonly ["productId", "categorySlug"]];
999
1013
  }, {
1000
1014
  readonly type: "DOCTOR_INTRO";
1001
1015
  readonly vertical: "BEAUTY";
1002
1016
  readonly jsonLd: null;
1003
1017
  readonly requiredRefs: readonly [];
1018
+ readonly requiredRefsAnyOf: readonly [];
1004
1019
  }, {
1005
1020
  readonly type: "HERO";
1006
1021
  readonly vertical: "GENERAL";
1007
1022
  readonly jsonLd: null;
1008
1023
  readonly requiredRefs: readonly [];
1024
+ readonly requiredRefsAnyOf: readonly [];
1009
1025
  }, {
1010
1026
  readonly type: "FEATURE_GRID";
1011
1027
  readonly vertical: "GENERAL";
1012
1028
  readonly jsonLd: null;
1013
1029
  readonly requiredRefs: readonly [];
1030
+ readonly requiredRefsAnyOf: readonly [];
1014
1031
  }, {
1015
1032
  readonly type: "TEXT_MEDIA";
1016
1033
  readonly vertical: "GENERAL";
1017
1034
  readonly jsonLd: null;
1018
1035
  readonly requiredRefs: readonly [];
1036
+ readonly requiredRefsAnyOf: readonly [];
1019
1037
  }, {
1020
1038
  readonly type: "LOGO_WALL";
1021
1039
  readonly vertical: "GENERAL";
1022
1040
  readonly jsonLd: null;
1023
1041
  readonly requiredRefs: readonly [];
1042
+ readonly requiredRefsAnyOf: readonly [];
1024
1043
  }, {
1025
1044
  readonly type: "STATS_BAND";
1026
1045
  readonly vertical: "GENERAL";
1027
1046
  readonly jsonLd: null;
1028
1047
  readonly requiredRefs: readonly [];
1048
+ readonly requiredRefsAnyOf: readonly [];
1029
1049
  }, {
1030
1050
  readonly type: "TESTIMONIALS";
1031
1051
  readonly vertical: "GENERAL";
1032
1052
  readonly jsonLd: null;
1033
1053
  readonly requiredRefs: readonly [];
1054
+ readonly requiredRefsAnyOf: readonly [];
1034
1055
  }, {
1035
1056
  readonly type: "FAQ_LIST";
1036
1057
  readonly vertical: "GENERAL";
1037
1058
  readonly jsonLd: "FAQPage";
1038
1059
  readonly requiredRefs: readonly [];
1060
+ readonly requiredRefsAnyOf: readonly [];
1039
1061
  }, {
1040
1062
  readonly type: "LEAD_CTA";
1041
1063
  readonly vertical: "GENERAL";
1042
1064
  readonly jsonLd: null;
1043
1065
  readonly requiredRefs: readonly [];
1066
+ readonly requiredRefsAnyOf: readonly [];
1044
1067
  }];
1045
1068
  /** 지금 렌더러가 아는 섹션 타입. 이 밖의 값이 와도 정상이다(스킵). */
1046
1069
  type KnownSectionType = (typeof SECTION_CONTRACT)[number]["type"];
package/dist/index.js CHANGED
@@ -290,7 +290,7 @@ function safeJsonParse(text) {
290
290
  }
291
291
 
292
292
  // src/sections.ts
293
- var SECTION_CONTRACT_REV = 4;
293
+ var SECTION_CONTRACT_REV = 5;
294
294
  var SECTION_CONTRACT = [
295
295
  // 뷰티(memo47) — append-only 계약상 불변
296
296
  // SERVICE_MENU 의 ItemList 는 rev 2 에서 올라왔다(memo119 T6-ⓒ): 쇼핑몰 유형엔 상품 목록 표면을
@@ -298,19 +298,19 @@ var SECTION_CONTRACT = [
298
298
  // 정위치는 별도 라우트가 아니라 홈의 이 섹션이라, FAQ_LIST→FAQPage 와 같은 형태로 섹션이 직접 낸다.
299
299
  // rev 3 에서 productIds 의 `?` 가 떨어졌다 — 목록을 내겠다고 선언한 섹션이 목록을 안 가리키는 상태가
300
300
  // 계약상 성립하지 않게 됐다(BOOKING_CTA.productId 는 rev 1 부터 필수였다·비대칭 해소).
301
- { type: "SERVICE_MENU", vertical: "BEAUTY", jsonLd: "ItemList", requiredRefs: ["productIds"] },
302
- { type: "BEFORE_AFTER_GALLERY", vertical: "BEAUTY", jsonLd: null, requiredRefs: [] },
303
- { type: "BOOKING_CTA", vertical: "BEAUTY", jsonLd: null, requiredRefs: ["productId"] },
304
- { type: "DOCTOR_INTRO", vertical: "BEAUTY", jsonLd: null, requiredRefs: [] },
301
+ { type: "SERVICE_MENU", vertical: "BEAUTY", jsonLd: "ItemList", requiredRefs: [], requiredRefsAnyOf: [["productIds", "categorySlug"]] },
302
+ { type: "BEFORE_AFTER_GALLERY", vertical: "BEAUTY", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
303
+ { type: "BOOKING_CTA", vertical: "BEAUTY", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [["productId", "categorySlug"]] },
304
+ { type: "DOCTOR_INTRO", vertical: "BEAUTY", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
305
305
  // 기업 마케팅(memo102 §2)
306
- { type: "HERO", vertical: "GENERAL", jsonLd: null, requiredRefs: [] },
307
- { type: "FEATURE_GRID", vertical: "GENERAL", jsonLd: null, requiredRefs: [] },
308
- { type: "TEXT_MEDIA", vertical: "GENERAL", jsonLd: null, requiredRefs: [] },
309
- { type: "LOGO_WALL", vertical: "GENERAL", jsonLd: null, requiredRefs: [] },
310
- { type: "STATS_BAND", vertical: "GENERAL", jsonLd: null, requiredRefs: [] },
311
- { type: "TESTIMONIALS", vertical: "GENERAL", jsonLd: null, requiredRefs: [] },
312
- { type: "FAQ_LIST", vertical: "GENERAL", jsonLd: "FAQPage", requiredRefs: [] },
313
- { type: "LEAD_CTA", vertical: "GENERAL", jsonLd: null, requiredRefs: [] }
306
+ { type: "HERO", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
307
+ { type: "FEATURE_GRID", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
308
+ { type: "TEXT_MEDIA", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
309
+ { type: "LOGO_WALL", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
310
+ { type: "STATS_BAND", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
311
+ { type: "TESTIMONIALS", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
312
+ { type: "FAQ_LIST", vertical: "GENERAL", jsonLd: "FAQPage", requiredRefs: [], requiredRefsAnyOf: [] },
313
+ { type: "LEAD_CTA", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] }
314
314
  ];
315
315
  function sectionsOfVertical(vertical) {
316
316
  return SECTION_CONTRACT.filter((s) => s.vertical === vertical);