@webiny/api-headless-cms 6.6.0-alpha.0 → 6.6.0-alpha.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.
Files changed (139) hide show
  1. package/HeadlessCmsFeature.js +4 -1
  2. package/HeadlessCmsFeature.js.map +1 -1
  3. package/createCmsRoute.d.ts +13 -8
  4. package/createCmsRoute.js +14 -4
  5. package/createCmsRoute.js.map +1 -1
  6. package/crud/contentEntry/entryDataValidation.js +27 -0
  7. package/crud/contentEntry/entryDataValidation.js.map +1 -1
  8. package/crud/contentModel/defaultFields.js +3 -2
  9. package/crud/contentModel/defaultFields.js.map +1 -1
  10. package/domain/contentModel/schemas.d.ts +8 -6
  11. package/domain/contentModel/schemas.js +5 -3
  12. package/domain/contentModel/schemas.js.map +1 -1
  13. package/exports/api/cms/model.d.ts +4 -1
  14. package/exports/api/cms/model.js +2 -0
  15. package/features/ai/DescribeContentModelTool.d.ts +55 -0
  16. package/features/ai/DescribeContentModelTool.js +60 -0
  17. package/features/ai/DescribeContentModelTool.js.map +1 -0
  18. package/features/ai/ListContentModelsTool.d.ts +41 -0
  19. package/features/ai/ListContentModelsTool.js +44 -0
  20. package/features/ai/ListContentModelsTool.js.map +1 -0
  21. package/features/ai/QueryEntriesTool.d.ts +75 -0
  22. package/features/ai/QueryEntriesTool.js +90 -0
  23. package/features/ai/QueryEntriesTool.js.map +1 -0
  24. package/features/ai/feature.d.ts +8 -0
  25. package/features/ai/feature.js +15 -0
  26. package/features/ai/feature.js.map +1 -0
  27. package/features/ai/index.d.ts +4 -0
  28. package/features/ai/index.js +4 -0
  29. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.d.ts +14 -0
  30. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.js +32 -0
  31. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.js.map +1 -0
  32. package/features/contentModel/ComponentMapGenerator/abstractions.d.ts +8 -0
  33. package/features/contentModel/ComponentMapGenerator/abstractions.js +5 -0
  34. package/features/contentModel/ComponentMapGenerator/abstractions.js.map +1 -0
  35. package/features/contentModel/ComponentMapGenerator/feature.d.ts +4 -0
  36. package/features/contentModel/ComponentMapGenerator/feature.js +11 -0
  37. package/features/contentModel/ComponentMapGenerator/feature.js.map +1 -0
  38. package/features/contentModel/ComponentMapGenerator/index.d.ts +2 -0
  39. package/features/contentModel/ComponentMapGenerator/index.js +2 -0
  40. package/features/contentModel/ContentModelFeature.js +4 -0
  41. package/features/contentModel/ContentModelFeature.js.map +1 -1
  42. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.d.ts +19 -0
  43. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.js +56 -0
  44. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.js.map +1 -0
  45. package/features/contentModel/RefModelsGenerator/abstractions.d.ts +11 -0
  46. package/features/contentModel/RefModelsGenerator/abstractions.js +5 -0
  47. package/features/contentModel/RefModelsGenerator/abstractions.js.map +1 -0
  48. package/features/contentModel/RefModelsGenerator/feature.d.ts +4 -0
  49. package/features/contentModel/RefModelsGenerator/feature.js +11 -0
  50. package/features/contentModel/RefModelsGenerator/feature.js.map +1 -0
  51. package/features/contentModel/RefModelsGenerator/index.d.ts +2 -0
  52. package/features/contentModel/RefModelsGenerator/index.js +2 -0
  53. package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js +2 -0
  54. package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js.map +1 -1
  55. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.d.ts +3 -1
  56. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js +6 -4
  57. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js.map +1 -1
  58. package/features/graphql/feature.js +2 -0
  59. package/features/graphql/feature.js.map +1 -1
  60. package/features/graphql/fields/base/AssetToGraphQL.d.ts +26 -0
  61. package/features/graphql/fields/base/AssetToGraphQL.js +148 -0
  62. package/features/graphql/fields/base/AssetToGraphQL.js.map +1 -0
  63. package/features/graphql/fields/base/DynamicZoneToGraphQL.js +5 -1
  64. package/features/graphql/fields/base/DynamicZoneToGraphQL.js.map +1 -1
  65. package/features/graphql/fields/base/ObjectToGraphQL.js +2 -2
  66. package/features/graphql/fields/base/ObjectToGraphQL.js.map +1 -1
  67. package/features/modelBuilder/abstractions.d.ts +10 -0
  68. package/features/modelBuilder/abstractions.js.map +1 -1
  69. package/features/modelBuilder/feature.js +2 -0
  70. package/features/modelBuilder/feature.js.map +1 -1
  71. package/features/modelBuilder/fields/AssetFieldType.d.ts +20 -0
  72. package/features/modelBuilder/fields/AssetFieldType.js +46 -0
  73. package/features/modelBuilder/fields/AssetFieldType.js.map +1 -0
  74. package/features/modelBuilder/fields/BaseFieldBuilder.d.ts +3 -1
  75. package/features/modelBuilder/fields/BaseFieldBuilder.js +4 -0
  76. package/features/modelBuilder/fields/BaseFieldBuilder.js.map +1 -1
  77. package/features/modelBuilder/fields/DataFieldBuilder.d.ts +42 -0
  78. package/features/modelBuilder/fields/DataFieldBuilder.js +5 -1
  79. package/features/modelBuilder/fields/DataFieldBuilder.js.map +1 -1
  80. package/features/modelBuilder/fields/DynamicZoneFieldType.d.ts +1 -0
  81. package/features/modelBuilder/fields/DynamicZoneFieldType.js +10 -9
  82. package/features/modelBuilder/fields/DynamicZoneFieldType.js.map +1 -1
  83. package/features/modelBuilder/fields/UiAlertFieldType.js +2 -1
  84. package/features/modelBuilder/fields/UiAlertFieldType.js.map +1 -1
  85. package/features/modelBuilder/fields/UiSeparatorFieldType.js +2 -1
  86. package/features/modelBuilder/fields/UiSeparatorFieldType.js.map +1 -1
  87. package/features/modelBuilder/fields/UiTabsFieldType.d.ts +2 -1
  88. package/features/modelBuilder/fields/UiTabsFieldType.js +6 -3
  89. package/features/modelBuilder/fields/UiTabsFieldType.js.map +1 -1
  90. package/features/modelBuilder/fields/resolveAssetUrl.d.ts +35 -0
  91. package/features/modelBuilder/fields/resolveAssetUrl.js +26 -0
  92. package/features/modelBuilder/fields/resolveAssetUrl.js.map +1 -0
  93. package/features/modelBuilder/index.d.ts +1 -1
  94. package/features/modelBuilder/models/BaseModelBuilder.d.ts +3 -1
  95. package/features/modelBuilder/models/BaseModelBuilder.js +7 -0
  96. package/features/modelBuilder/models/BaseModelBuilder.js.map +1 -1
  97. package/features/modelBuilder/models/PrivateModelBuilder.js +2 -1
  98. package/features/modelBuilder/models/PrivateModelBuilder.js.map +1 -1
  99. package/features/modelBuilder/models/PublicModelBuilder.js +2 -1
  100. package/features/modelBuilder/models/PublicModelBuilder.js.map +1 -1
  101. package/features/sortMapper/SortMapper.js +2 -5
  102. package/features/sortMapper/SortMapper.js.map +1 -1
  103. package/features/whereMapper/WhereMapper.js +7 -5
  104. package/features/whereMapper/WhereMapper.js.map +1 -1
  105. package/graphql/schema/cms/getEntryResolver.js +3 -2
  106. package/graphql/schema/cms/getEntryResolver.js.map +1 -1
  107. package/graphql/schema/cms/getModelResolver.d.ts +35 -0
  108. package/graphql/schema/cms/getModelResolver.js +49 -0
  109. package/graphql/schema/cms/getModelResolver.js.map +1 -0
  110. package/graphql/schema/cms/helpers/buildFieldsSelection.js +9 -2
  111. package/graphql/schema/cms/helpers/buildFieldsSelection.js.map +1 -1
  112. package/graphql/schema/cms/helpers/expandFieldWildcards.d.ts +2 -0
  113. package/graphql/schema/cms/helpers/expandFieldWildcards.js +13 -0
  114. package/graphql/schema/cms/helpers/expandFieldWildcards.js.map +1 -0
  115. package/graphql/schema/cms/helpers/index.d.ts +1 -0
  116. package/graphql/schema/cms/helpers/index.js +1 -0
  117. package/graphql/schema/cms/helpers/transformWhereToNested.js +39 -17
  118. package/graphql/schema/cms/helpers/transformWhereToNested.js.map +1 -1
  119. package/graphql/schema/cms/helpers.d.ts +1 -0
  120. package/graphql/schema/cms/helpers.js +1 -0
  121. package/graphql/schema/cms/listEntriesResolver.js +3 -2
  122. package/graphql/schema/cms/listEntriesResolver.js.map +1 -1
  123. package/graphql/schema/cms/resolvers/getModel.d.ts +8 -0
  124. package/graphql/schema/cms/resolvers/getModel.js +18 -0
  125. package/graphql/schema/cms/resolvers/getModel.js.map +1 -0
  126. package/graphql/schema/cms/resolvers/index.d.ts +1 -0
  127. package/graphql/schema/cms/resolvers/index.js +1 -0
  128. package/graphql/schema/cms/typeDefs/query.js +1 -0
  129. package/graphql/schema/cms/typeDefs/query.js.map +1 -1
  130. package/graphql/schema/cms/typeDefs/responses.js +5 -0
  131. package/graphql/schema/cms/typeDefs/responses.js.map +1 -1
  132. package/graphql/schema/contentModels.js +31 -0
  133. package/graphql/schema/contentModels.js.map +1 -1
  134. package/package.json +21 -22
  135. package/plugins/CmsModelPlugin.js +2 -1
  136. package/plugins/CmsModelPlugin.js.map +1 -1
  137. package/types/fields/dynamicZoneField.d.ts +3 -2
  138. package/types/model.d.ts +6 -0
  139. package/types/modelField.d.ts +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"features/modelBuilder/fields/UiAlertFieldType.js","sources":["../../../../src/features/modelBuilder/fields/UiAlertFieldType.ts"],"sourcesContent":["import { FieldType, type IFieldTypeFactory } from \"./abstractions.js\";\nimport { type LayoutFieldBuildResult } from \"./BaseFieldBuilder.js\";\nimport { LayoutFieldBuilder } from \"./LayoutFieldBuilder.js\";\n\ntype AlertType = \"info\" | \"success\" | \"warning\" | \"danger\";\n\nexport interface IUiAlertFieldBuilder extends LayoutFieldBuilder<\"uiAlert\"> {\n alertType(type: AlertType): this;\n}\n\nclass AlertFieldBuilder extends LayoutFieldBuilder<\"uiAlert\"> implements IUiAlertFieldBuilder {\n private _alertType: AlertType = \"warning\";\n\n public constructor() {\n super(\"uiAlert\");\n }\n\n public alertType(type: AlertType): this {\n this._alertType = type;\n return this;\n }\n\n public override build(): LayoutFieldBuildResult {\n return {\n type: \"layout\",\n layoutCell: {\n type: \"alert\",\n label: this.config.label,\n alertType: this._alertType\n }\n };\n }\n}\n\nclass UiAlertFieldTypeFactory implements IFieldTypeFactory {\n public readonly type = \"uiAlert\";\n\n public create(): IUiAlertFieldBuilder {\n return new AlertFieldBuilder();\n }\n}\n\nexport const UiAlertFieldType = FieldType.createImplementation({\n implementation: UiAlertFieldTypeFactory,\n dependencies: []\n});\n\n// Module augmentation for TypeScript autocomplete\ndeclare module \"../abstractions.js\" {\n interface IFieldBuilderRegistry {\n uiAlert(): IUiAlertFieldBuilder;\n }\n}\n"],"names":["AlertFieldBuilder","LayoutFieldBuilder","type","UiAlertFieldTypeFactory","UiAlertFieldType","FieldType"],"mappings":";;AAUA,MAAMA,0BAA0BC;IAG5B,aAAqB;QACjB,KAAK,CAAC,iBAHF,UAAU,GAAc;IAIhC;IAEO,UAAUC,IAAe,EAAQ;QACpC,IAAI,CAAC,UAAU,GAAGA;QAClB,OAAO,IAAI;IACf;IAEgB,QAAgC;QAC5C,OAAO;YACH,MAAM;YACN,YAAY;gBACR,MAAM;gBACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;gBACxB,WAAW,IAAI,CAAC,UAAU;YAC9B;QACJ;IACJ;AACJ;AAEA,MAAMC;IAGK,SAA+B;QAClC,OAAO,IAAIH;IACf;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMI,mBAAmBC,UAAU,oBAAoB,CAAC;IAC3D,gBAAgBF;IAChB,cAAc,EAAE;AACpB"}
1
+ {"version":3,"file":"features/modelBuilder/fields/UiAlertFieldType.js","sources":["../../../../src/features/modelBuilder/fields/UiAlertFieldType.ts"],"sourcesContent":["import { FieldType, type IFieldTypeFactory } from \"./abstractions.js\";\nimport { type LayoutFieldBuildResult } from \"./BaseFieldBuilder.js\";\nimport { LayoutFieldBuilder } from \"./LayoutFieldBuilder.js\";\n\ntype AlertType = \"info\" | \"success\" | \"warning\" | \"danger\";\n\nexport interface IUiAlertFieldBuilder extends LayoutFieldBuilder<\"uiAlert\"> {\n alertType(type: AlertType): this;\n}\n\nclass AlertFieldBuilder extends LayoutFieldBuilder<\"uiAlert\"> implements IUiAlertFieldBuilder {\n private _alertType: AlertType = \"warning\";\n\n public constructor() {\n super(\"uiAlert\");\n }\n\n public alertType(type: AlertType): this {\n this._alertType = type;\n return this;\n }\n\n public override build(): LayoutFieldBuildResult {\n return {\n type: \"layout\",\n layoutCell: {\n type: \"alert\",\n label: this.config.label,\n alertType: this._alertType,\n rules: this.config.rules\n }\n };\n }\n}\n\nclass UiAlertFieldTypeFactory implements IFieldTypeFactory {\n public readonly type = \"uiAlert\";\n\n public create(): IUiAlertFieldBuilder {\n return new AlertFieldBuilder();\n }\n}\n\nexport const UiAlertFieldType = FieldType.createImplementation({\n implementation: UiAlertFieldTypeFactory,\n dependencies: []\n});\n\n// Module augmentation for TypeScript autocomplete\ndeclare module \"../abstractions.js\" {\n interface IFieldBuilderRegistry {\n uiAlert(): IUiAlertFieldBuilder;\n }\n}\n"],"names":["AlertFieldBuilder","LayoutFieldBuilder","type","UiAlertFieldTypeFactory","UiAlertFieldType","FieldType"],"mappings":";;AAUA,MAAMA,0BAA0BC;IAG5B,aAAqB;QACjB,KAAK,CAAC,iBAHF,UAAU,GAAc;IAIhC;IAEO,UAAUC,IAAe,EAAQ;QACpC,IAAI,CAAC,UAAU,GAAGA;QAClB,OAAO,IAAI;IACf;IAEgB,QAAgC;QAC5C,OAAO;YACH,MAAM;YACN,YAAY;gBACR,MAAM;gBACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;gBACxB,WAAW,IAAI,CAAC,UAAU;gBAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;YAC5B;QACJ;IACJ;AACJ;AAEA,MAAMC;IAGK,SAA+B;QAClC,OAAO,IAAIH;IACf;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMI,mBAAmBC,UAAU,oBAAoB,CAAC;IAC3D,gBAAgBF;IAChB,cAAc,EAAE;AACpB"}
@@ -10,7 +10,8 @@ class SeparatorFieldBuilder extends LayoutFieldBuilder {
10
10
  layoutCell: {
11
11
  type: "separator",
12
12
  label: this.config.label,
13
- description: this.config.description
13
+ description: this.config.description,
14
+ rules: this.config.rules
14
15
  }
15
16
  };
16
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"features/modelBuilder/fields/UiSeparatorFieldType.js","sources":["../../../../src/features/modelBuilder/fields/UiSeparatorFieldType.ts"],"sourcesContent":["import { FieldType, type IFieldTypeFactory } from \"./abstractions.js\";\nimport { type LayoutFieldBuildResult } from \"./BaseFieldBuilder.js\";\nimport { LayoutFieldBuilder } from \"./LayoutFieldBuilder.js\";\n\nexport interface IUiSeparatorFieldBuilder extends LayoutFieldBuilder<\"uiSeparator\"> {}\n\nclass SeparatorFieldBuilder\n extends LayoutFieldBuilder<\"uiSeparator\">\n implements IUiSeparatorFieldBuilder\n{\n public constructor() {\n super(\"uiSeparator\");\n }\n\n public override build(): LayoutFieldBuildResult {\n return {\n type: \"layout\",\n layoutCell: {\n type: \"separator\",\n label: this.config.label,\n description: this.config.description\n }\n };\n }\n}\n\nclass UiSeparatorFieldTypeFactory implements IFieldTypeFactory {\n public readonly type = \"uiSeparator\";\n\n public create(): IUiSeparatorFieldBuilder {\n return new SeparatorFieldBuilder();\n }\n}\n\nexport const UiSeparatorFieldType = FieldType.createImplementation({\n implementation: UiSeparatorFieldTypeFactory,\n dependencies: []\n});\n\n// Module augmentation for TypeScript autocomplete\ndeclare module \"../abstractions.js\" {\n interface IFieldBuilderRegistry {\n uiSeparator(): IUiSeparatorFieldBuilder;\n }\n}\n"],"names":["SeparatorFieldBuilder","LayoutFieldBuilder","UiSeparatorFieldTypeFactory","UiSeparatorFieldType","FieldType"],"mappings":";;AAMA,MAAMA,8BACMC;IAGR,aAAqB;QACjB,KAAK,CAAC;IACV;IAEgB,QAAgC;QAC5C,OAAO;YACH,MAAM;YACN,YAAY;gBACR,MAAM;gBACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;gBACxB,aAAa,IAAI,CAAC,MAAM,CAAC,WAAW;YACxC;QACJ;IACJ;AACJ;AAEA,MAAMC;IAGK,SAAmC;QACtC,OAAO,IAAIF;IACf;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMG,uBAAuBC,UAAU,oBAAoB,CAAC;IAC/D,gBAAgBF;IAChB,cAAc,EAAE;AACpB"}
1
+ {"version":3,"file":"features/modelBuilder/fields/UiSeparatorFieldType.js","sources":["../../../../src/features/modelBuilder/fields/UiSeparatorFieldType.ts"],"sourcesContent":["import { FieldType, type IFieldTypeFactory } from \"./abstractions.js\";\nimport { type LayoutFieldBuildResult } from \"./BaseFieldBuilder.js\";\nimport { LayoutFieldBuilder } from \"./LayoutFieldBuilder.js\";\n\nexport interface IUiSeparatorFieldBuilder extends LayoutFieldBuilder<\"uiSeparator\"> {}\n\nclass SeparatorFieldBuilder\n extends LayoutFieldBuilder<\"uiSeparator\">\n implements IUiSeparatorFieldBuilder\n{\n public constructor() {\n super(\"uiSeparator\");\n }\n\n public override build(): LayoutFieldBuildResult {\n return {\n type: \"layout\",\n layoutCell: {\n type: \"separator\",\n label: this.config.label,\n description: this.config.description,\n rules: this.config.rules\n }\n };\n }\n}\n\nclass UiSeparatorFieldTypeFactory implements IFieldTypeFactory {\n public readonly type = \"uiSeparator\";\n\n public create(): IUiSeparatorFieldBuilder {\n return new SeparatorFieldBuilder();\n }\n}\n\nexport const UiSeparatorFieldType = FieldType.createImplementation({\n implementation: UiSeparatorFieldTypeFactory,\n dependencies: []\n});\n\n// Module augmentation for TypeScript autocomplete\ndeclare module \"../abstractions.js\" {\n interface IFieldBuilderRegistry {\n uiSeparator(): IUiSeparatorFieldBuilder;\n }\n}\n"],"names":["SeparatorFieldBuilder","LayoutFieldBuilder","UiSeparatorFieldTypeFactory","UiSeparatorFieldType","FieldType"],"mappings":";;AAMA,MAAMA,8BACMC;IAGR,aAAqB;QACjB,KAAK,CAAC;IACV;IAEgB,QAAgC;QAC5C,OAAO;YACH,MAAM;YACN,YAAY;gBACR,MAAM;gBACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;gBACxB,aAAa,IAAI,CAAC,MAAM,CAAC,WAAW;gBACpC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;YAC5B;QACJ;IACJ;AACJ;AAEA,MAAMC;IAGK,SAAmC;QACtC,OAAO,IAAIF;IACf;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMG,uBAAuBC,UAAU,oBAAoB,CAAC;IAC/D,gBAAgBF;IAChB,cAAc,EAAE;AACpB"}
@@ -2,13 +2,14 @@ import { type IFieldTypeFactory } from "./abstractions.js";
2
2
  import { BaseFieldBuilder } from "./BaseFieldBuilder.js";
3
3
  import { LayoutFieldBuilder } from "./LayoutFieldBuilder.js";
4
4
  import { type IFieldBuilderRegistry } from "../abstractions.js";
5
- import type { CmsIcon } from "../../../types/index.js";
5
+ import type { CmsIcon, FieldRule } from "../../../types/index.js";
6
6
  interface ITabConfig {
7
7
  label: string;
8
8
  icon?: CmsIcon;
9
9
  description?: string;
10
10
  fields: (registry: IFieldBuilderRegistry) => Record<string, BaseFieldBuilder<any>>;
11
11
  layout?: string[][];
12
+ rules?: FieldRule[];
12
13
  }
13
14
  export interface IUiTabsFieldBuilder extends LayoutFieldBuilder<"uiTabs"> {
14
15
  tab(id: string, config: ITabConfig): this;
@@ -24,7 +24,8 @@ class TabsFieldBuilder extends LayoutFieldBuilder {
24
24
  icon: config.icon,
25
25
  description: config.description || "",
26
26
  fields,
27
- layout
27
+ layout,
28
+ rules: config.rules
28
29
  });
29
30
  return this;
30
31
  }
@@ -37,7 +38,8 @@ class TabsFieldBuilder extends LayoutFieldBuilder {
37
38
  id: tab.id,
38
39
  label: tab.label,
39
40
  icon: tab.icon || null,
40
- layout: tab.layout
41
+ layout: tab.layout,
42
+ rules: tab.rules
41
43
  });
42
44
  }
43
45
  return {
@@ -47,7 +49,8 @@ class TabsFieldBuilder extends LayoutFieldBuilder {
47
49
  label: this.config.label,
48
50
  description: this.config.description || null,
49
51
  help: this.config.help || null,
50
- tabs: layoutTabs
52
+ tabs: layoutTabs,
53
+ rules: this.config.rules
51
54
  },
52
55
  fields: hoistedFields
53
56
  };
@@ -1 +1 @@
1
- {"version":3,"file":"features/modelBuilder/fields/UiTabsFieldType.js","sources":["../../../../src/features/modelBuilder/fields/UiTabsFieldType.ts"],"sourcesContent":["import { FieldType, type IFieldTypeFactory } from \"./abstractions.js\";\nimport {\n BaseFieldBuilder,\n type FieldBuildResult,\n type LayoutFieldBuildResult\n} from \"./BaseFieldBuilder.js\";\nimport { LayoutFieldBuilder } from \"./LayoutFieldBuilder.js\";\nimport { type IFieldBuilderRegistry } from \"../abstractions.js\";\nimport type { CmsIcon, CmsModelField, CmsModelLayout, CmsModelLayoutCell } from \"~/types/index.js\";\n\ninterface ITab {\n id: string;\n label: string;\n icon: CmsIcon | undefined;\n description: string;\n fields: CmsModelField[];\n layout: CmsModelLayout;\n}\n\ninterface ITabConfig {\n label: string;\n icon?: CmsIcon;\n description?: string;\n fields: (registry: IFieldBuilderRegistry) => Record<string, BaseFieldBuilder<any>>;\n layout?: string[][];\n}\n\nexport interface IUiTabsFieldBuilder extends LayoutFieldBuilder<\"uiTabs\"> {\n tab(id: string, config: ITabConfig): this;\n}\n\nclass TabsFieldBuilder extends LayoutFieldBuilder<\"uiTabs\"> implements IUiTabsFieldBuilder {\n private readonly tabs: ITab[] = [];\n\n public constructor(private registry: IFieldBuilderRegistry) {\n super(\"uiTabs\");\n }\n\n public tab(id: string, config: ITabConfig): this {\n const fieldBuilders = config.fields(this.registry);\n const fields: CmsModelField[] = [];\n const layoutReplacements = new Map<string, CmsModelLayoutCell>();\n\n for (const [key, fieldBuilder] of Object.entries(fieldBuilders)) {\n fieldBuilder.fieldId(key);\n const result: FieldBuildResult = (fieldBuilder as any).build();\n if (result.type === \"layout\") {\n layoutReplacements.set(key, result.layoutCell);\n if (result.fields) {\n fields.push(...result.fields);\n }\n } else {\n fields.push(result.field);\n }\n }\n\n const rawLayout: string[][] = config.layout || [];\n const layout: CmsModelLayout = rawLayout.map(row =>\n row.map(cell => layoutReplacements.get(cell) ?? cell)\n );\n\n this.tabs.push({\n id,\n label: config.label,\n icon: config.icon,\n description: config.description || \"\",\n fields,\n layout\n });\n\n return this;\n }\n\n public override build(): LayoutFieldBuildResult {\n const hoistedFields: CmsModelField[] = [];\n const layoutTabs = [];\n\n for (const tab of this.tabs) {\n hoistedFields.push(...tab.fields);\n layoutTabs.push({\n id: tab.id,\n label: tab.label,\n icon: tab.icon || null,\n layout: tab.layout\n });\n }\n\n return {\n type: \"layout\",\n layoutCell: {\n type: \"tabs\",\n label: this.config.label,\n description: this.config.description || null,\n help: this.config.help || null,\n tabs: layoutTabs\n },\n fields: hoistedFields\n };\n }\n}\n\nclass TabsFieldTypeFactory implements IFieldTypeFactory {\n public readonly type = \"uiTabs\";\n\n public create(registry: IFieldBuilderRegistry): IUiTabsFieldBuilder {\n return new TabsFieldBuilder(registry);\n }\n}\n\nexport const UiTabsFieldType = FieldType.createImplementation({\n implementation: TabsFieldTypeFactory,\n dependencies: []\n});\n\n// Module augmentation for TypeScript autocomplete\ndeclare module \"../abstractions.js\" {\n interface IFieldBuilderRegistry {\n uiTabs(): IUiTabsFieldBuilder;\n }\n}\n"],"names":["TabsFieldBuilder","LayoutFieldBuilder","registry","id","config","fieldBuilders","fields","layoutReplacements","Map","key","fieldBuilder","Object","result","rawLayout","layout","row","cell","hoistedFields","layoutTabs","tab","TabsFieldTypeFactory","UiTabsFieldType","FieldType"],"mappings":";;AA+BA,MAAMA,yBAAyBC;IAG3B,YAA2BC,QAA+B,CAAE;QACxD,KAAK,CAAC,gBADiBA,QAAQ,GAARA,UAAAA,IAAAA,CAFV,IAAI,GAAW,EAAE;IAIlC;IAEO,IAAIC,EAAU,EAAEC,MAAkB,EAAQ;QAC7C,MAAMC,gBAAgBD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ;QACjD,MAAME,SAA0B,EAAE;QAClC,MAAMC,qBAAqB,IAAIC;QAE/B,KAAK,MAAM,CAACC,KAAKC,aAAa,IAAIC,OAAO,OAAO,CAACN,eAAgB;YAC7DK,aAAa,OAAO,CAACD;YACrB,MAAMG,SAA4BF,aAAqB,KAAK;YAC5D,IAAIE,AAAgB,aAAhBA,OAAO,IAAI,EAAe;gBAC1BL,mBAAmB,GAAG,CAACE,KAAKG,OAAO,UAAU;gBAC7C,IAAIA,OAAO,MAAM,EACbN,OAAO,IAAI,IAAIM,OAAO,MAAM;YAEpC,OACIN,OAAO,IAAI,CAACM,OAAO,KAAK;QAEhC;QAEA,MAAMC,YAAwBT,OAAO,MAAM,IAAI,EAAE;QACjD,MAAMU,SAAyBD,UAAU,GAAG,CAACE,CAAAA,MACzCA,IAAI,GAAG,CAACC,CAAAA,OAAQT,mBAAmB,GAAG,CAACS,SAASA;QAGpD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACXb;YACA,OAAOC,OAAO,KAAK;YACnB,MAAMA,OAAO,IAAI;YACjB,aAAaA,OAAO,WAAW,IAAI;YACnCE;YACAQ;QACJ;QAEA,OAAO,IAAI;IACf;IAEgB,QAAgC;QAC5C,MAAMG,gBAAiC,EAAE;QACzC,MAAMC,aAAa,EAAE;QAErB,KAAK,MAAMC,OAAO,IAAI,CAAC,IAAI,CAAE;YACzBF,cAAc,IAAI,IAAIE,IAAI,MAAM;YAChCD,WAAW,IAAI,CAAC;gBACZ,IAAIC,IAAI,EAAE;gBACV,OAAOA,IAAI,KAAK;gBAChB,MAAMA,IAAI,IAAI,IAAI;gBAClB,QAAQA,IAAI,MAAM;YACtB;QACJ;QAEA,OAAO;YACH,MAAM;YACN,YAAY;gBACR,MAAM;gBACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;gBACxB,aAAa,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI;gBACxC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI;gBAC1B,MAAMD;YACV;YACA,QAAQD;QACZ;IACJ;AACJ;AAEA,MAAMG;IAGK,OAAOlB,QAA+B,EAAuB;QAChE,OAAO,IAAIF,iBAAiBE;IAChC;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMmB,kBAAkBC,UAAU,oBAAoB,CAAC;IAC1D,gBAAgBF;IAChB,cAAc,EAAE;AACpB"}
1
+ {"version":3,"file":"features/modelBuilder/fields/UiTabsFieldType.js","sources":["../../../../src/features/modelBuilder/fields/UiTabsFieldType.ts"],"sourcesContent":["import { FieldType, type IFieldTypeFactory } from \"./abstractions.js\";\nimport {\n BaseFieldBuilder,\n type FieldBuildResult,\n type LayoutFieldBuildResult\n} from \"./BaseFieldBuilder.js\";\nimport { LayoutFieldBuilder } from \"./LayoutFieldBuilder.js\";\nimport { type IFieldBuilderRegistry } from \"../abstractions.js\";\nimport type {\n CmsIcon,\n CmsModelField,\n CmsModelLayout,\n CmsModelLayoutCell,\n FieldRule\n} from \"~/types/index.js\";\n\ninterface ITab {\n id: string;\n label: string;\n icon: CmsIcon | undefined;\n description: string;\n fields: CmsModelField[];\n layout: CmsModelLayout;\n rules?: FieldRule[];\n}\n\ninterface ITabConfig {\n label: string;\n icon?: CmsIcon;\n description?: string;\n fields: (registry: IFieldBuilderRegistry) => Record<string, BaseFieldBuilder<any>>;\n layout?: string[][];\n rules?: FieldRule[];\n}\n\nexport interface IUiTabsFieldBuilder extends LayoutFieldBuilder<\"uiTabs\"> {\n tab(id: string, config: ITabConfig): this;\n}\n\nclass TabsFieldBuilder extends LayoutFieldBuilder<\"uiTabs\"> implements IUiTabsFieldBuilder {\n private readonly tabs: ITab[] = [];\n\n public constructor(private registry: IFieldBuilderRegistry) {\n super(\"uiTabs\");\n }\n\n public tab(id: string, config: ITabConfig): this {\n const fieldBuilders = config.fields(this.registry);\n const fields: CmsModelField[] = [];\n const layoutReplacements = new Map<string, CmsModelLayoutCell>();\n\n for (const [key, fieldBuilder] of Object.entries(fieldBuilders)) {\n fieldBuilder.fieldId(key);\n const result: FieldBuildResult = (fieldBuilder as any).build();\n if (result.type === \"layout\") {\n layoutReplacements.set(key, result.layoutCell);\n if (result.fields) {\n fields.push(...result.fields);\n }\n } else {\n fields.push(result.field);\n }\n }\n\n const rawLayout: string[][] = config.layout || [];\n const layout: CmsModelLayout = rawLayout.map(row =>\n row.map(cell => layoutReplacements.get(cell) ?? cell)\n );\n\n this.tabs.push({\n id,\n label: config.label,\n icon: config.icon,\n description: config.description || \"\",\n fields,\n layout,\n rules: config.rules\n });\n\n return this;\n }\n\n public override build(): LayoutFieldBuildResult {\n const hoistedFields: CmsModelField[] = [];\n const layoutTabs = [];\n\n for (const tab of this.tabs) {\n hoistedFields.push(...tab.fields);\n layoutTabs.push({\n id: tab.id,\n label: tab.label,\n icon: tab.icon || null,\n layout: tab.layout,\n rules: tab.rules\n });\n }\n\n return {\n type: \"layout\",\n layoutCell: {\n type: \"tabs\",\n label: this.config.label,\n description: this.config.description || null,\n help: this.config.help || null,\n tabs: layoutTabs,\n rules: this.config.rules\n },\n fields: hoistedFields\n };\n }\n}\n\nclass TabsFieldTypeFactory implements IFieldTypeFactory {\n public readonly type = \"uiTabs\";\n\n public create(registry: IFieldBuilderRegistry): IUiTabsFieldBuilder {\n return new TabsFieldBuilder(registry);\n }\n}\n\nexport const UiTabsFieldType = FieldType.createImplementation({\n implementation: TabsFieldTypeFactory,\n dependencies: []\n});\n\n// Module augmentation for TypeScript autocomplete\ndeclare module \"../abstractions.js\" {\n interface IFieldBuilderRegistry {\n uiTabs(): IUiTabsFieldBuilder;\n }\n}\n"],"names":["TabsFieldBuilder","LayoutFieldBuilder","registry","id","config","fieldBuilders","fields","layoutReplacements","Map","key","fieldBuilder","Object","result","rawLayout","layout","row","cell","hoistedFields","layoutTabs","tab","TabsFieldTypeFactory","UiTabsFieldType","FieldType"],"mappings":";;AAuCA,MAAMA,yBAAyBC;IAG3B,YAA2BC,QAA+B,CAAE;QACxD,KAAK,CAAC,gBADiBA,QAAQ,GAARA,UAAAA,IAAAA,CAFV,IAAI,GAAW,EAAE;IAIlC;IAEO,IAAIC,EAAU,EAAEC,MAAkB,EAAQ;QAC7C,MAAMC,gBAAgBD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ;QACjD,MAAME,SAA0B,EAAE;QAClC,MAAMC,qBAAqB,IAAIC;QAE/B,KAAK,MAAM,CAACC,KAAKC,aAAa,IAAIC,OAAO,OAAO,CAACN,eAAgB;YAC7DK,aAAa,OAAO,CAACD;YACrB,MAAMG,SAA4BF,aAAqB,KAAK;YAC5D,IAAIE,AAAgB,aAAhBA,OAAO,IAAI,EAAe;gBAC1BL,mBAAmB,GAAG,CAACE,KAAKG,OAAO,UAAU;gBAC7C,IAAIA,OAAO,MAAM,EACbN,OAAO,IAAI,IAAIM,OAAO,MAAM;YAEpC,OACIN,OAAO,IAAI,CAACM,OAAO,KAAK;QAEhC;QAEA,MAAMC,YAAwBT,OAAO,MAAM,IAAI,EAAE;QACjD,MAAMU,SAAyBD,UAAU,GAAG,CAACE,CAAAA,MACzCA,IAAI,GAAG,CAACC,CAAAA,OAAQT,mBAAmB,GAAG,CAACS,SAASA;QAGpD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACXb;YACA,OAAOC,OAAO,KAAK;YACnB,MAAMA,OAAO,IAAI;YACjB,aAAaA,OAAO,WAAW,IAAI;YACnCE;YACAQ;YACA,OAAOV,OAAO,KAAK;QACvB;QAEA,OAAO,IAAI;IACf;IAEgB,QAAgC;QAC5C,MAAMa,gBAAiC,EAAE;QACzC,MAAMC,aAAa,EAAE;QAErB,KAAK,MAAMC,OAAO,IAAI,CAAC,IAAI,CAAE;YACzBF,cAAc,IAAI,IAAIE,IAAI,MAAM;YAChCD,WAAW,IAAI,CAAC;gBACZ,IAAIC,IAAI,EAAE;gBACV,OAAOA,IAAI,KAAK;gBAChB,MAAMA,IAAI,IAAI,IAAI;gBAClB,QAAQA,IAAI,MAAM;gBAClB,OAAOA,IAAI,KAAK;YACpB;QACJ;QAEA,OAAO;YACH,MAAM;YACN,YAAY;gBACR,MAAM;gBACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;gBACxB,aAAa,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI;gBACxC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI;gBAC1B,MAAMD;gBACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;YAC5B;YACA,QAAQD;QACZ;IACJ;AACJ;AAEA,MAAMG;IAGK,OAAOlB,QAA+B,EAAuB;QAChE,OAAO,IAAIF,iBAAiBE;IAChC;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMmB,kBAAkBC,UAAU,oBAAoB,CAAC;IAC1D,gBAAgBF;IAChB,cAAc,EAAE;AACpB"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Build the turnkey delivery URL for a stored Asset field value.
3
+ *
4
+ * The Asset field stores `src` as the file's **base delivery URL** (the pristine
5
+ * original) with the per-usage crop kept beside it in `image.crop`. The delivery
6
+ * pipeline frames the image only when the URL carries a `?crop=` param, so a raw
7
+ * `src` never reflects the per-usage crop. This helper bakes that crop into the URL
8
+ * — it is what the generated `url` field on the Asset GraphQL type resolves to, so a
9
+ * headless consumer (any framework) gets a ready-to-use URL without having to know
10
+ * the delivery param contract.
11
+ *
12
+ * Note: only the per-usage crop is added here. Any **asset-level** crop (set in File
13
+ * Manager, stored on the file's metadata) is already baked in by the delivery on any
14
+ * GET of the base `src`, and a per-usage crop replaces — not composes with — it, so
15
+ * `src` + `?crop=<per-usage>` is the correct combined result.
16
+ */
17
+ interface AssetImageCrop {
18
+ top?: number | null;
19
+ left?: number | null;
20
+ bottom?: number | null;
21
+ right?: number | null;
22
+ }
23
+ interface AssetValue {
24
+ src?: string | null;
25
+ image?: {
26
+ crop?: AssetImageCrop | null;
27
+ } | null;
28
+ }
29
+ /**
30
+ * The stored `src` with the per-usage crop baked in as a `?crop=` delivery param.
31
+ * Returns `src` unchanged when there is no per-usage crop, and `null` when the value
32
+ * has no source.
33
+ */
34
+ export declare const resolveAssetUrl: (asset: AssetValue | null | undefined) => string | null;
35
+ export {};
@@ -0,0 +1,26 @@
1
+ const round = (n)=>Math.round(10000 * n) / 10000;
2
+ const cropParam = (crop)=>{
3
+ if (!crop) return;
4
+ const top = crop.top ?? 0;
5
+ const left = crop.left ?? 0;
6
+ const bottom = crop.bottom ?? 0;
7
+ const right = crop.right ?? 0;
8
+ if (0 === top && 0 === left && 0 === bottom && 0 === right) return;
9
+ return [
10
+ top,
11
+ left,
12
+ bottom,
13
+ right
14
+ ].map(round).join(",");
15
+ };
16
+ const resolveAssetUrl = (asset)=>{
17
+ const src = asset?.src;
18
+ if (!src) return null;
19
+ const param = cropParam(asset?.image?.crop);
20
+ if (!param) return src;
21
+ const separator = src.includes("?") ? "&" : "?";
22
+ return `${src}${separator}crop=${param}`;
23
+ };
24
+ export { resolveAssetUrl };
25
+
26
+ //# sourceMappingURL=resolveAssetUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/modelBuilder/fields/resolveAssetUrl.js","sources":["../../../../src/features/modelBuilder/fields/resolveAssetUrl.ts"],"sourcesContent":["/**\n * Build the turnkey delivery URL for a stored Asset field value.\n *\n * The Asset field stores `src` as the file's **base delivery URL** (the pristine\n * original) with the per-usage crop kept beside it in `image.crop`. The delivery\n * pipeline frames the image only when the URL carries a `?crop=` param, so a raw\n * `src` never reflects the per-usage crop. This helper bakes that crop into the URL\n * — it is what the generated `url` field on the Asset GraphQL type resolves to, so a\n * headless consumer (any framework) gets a ready-to-use URL without having to know\n * the delivery param contract.\n *\n * Note: only the per-usage crop is added here. Any **asset-level** crop (set in File\n * Manager, stored on the file's metadata) is already baked in by the delivery on any\n * GET of the base `src`, and a per-usage crop replaces — not composes with — it, so\n * `src` + `?crop=<per-usage>` is the correct combined result.\n */\n\ninterface AssetImageCrop {\n top?: number | null;\n left?: number | null;\n bottom?: number | null;\n right?: number | null;\n}\n\ninterface AssetValue {\n src?: string | null;\n image?: { crop?: AssetImageCrop | null } | null;\n}\n\nconst round = (n: number): number => Math.round(n * 10000) / 10000;\n\n/** `top,left,bottom,right` crop param, or `undefined` for a missing/full (no-op) crop. */\nconst cropParam = (crop: AssetImageCrop | null | undefined): string | undefined => {\n if (!crop) {\n return undefined;\n }\n const top = crop.top ?? 0;\n const left = crop.left ?? 0;\n const bottom = crop.bottom ?? 0;\n const right = crop.right ?? 0;\n if (top === 0 && left === 0 && bottom === 0 && right === 0) {\n return undefined;\n }\n return [top, left, bottom, right].map(round).join(\",\");\n};\n\n/**\n * The stored `src` with the per-usage crop baked in as a `?crop=` delivery param.\n * Returns `src` unchanged when there is no per-usage crop, and `null` when the value\n * has no source.\n */\nexport const resolveAssetUrl = (asset: AssetValue | null | undefined): string | null => {\n const src = asset?.src;\n if (!src) {\n return null;\n }\n const param = cropParam(asset?.image?.crop);\n if (!param) {\n return src;\n }\n const separator = src.includes(\"?\") ? \"&\" : \"?\";\n return `${src}${separator}crop=${param}`;\n};\n"],"names":["round","n","Math","cropParam","crop","top","left","bottom","right","resolveAssetUrl","asset","src","param","separator"],"mappings":"AA6BA,MAAMA,QAAQ,CAACC,IAAsBC,KAAK,KAAK,CAACD,AAAI,QAAJA,KAAa;AAG7D,MAAME,YAAY,CAACC;IACf,IAAI,CAACA,MACD;IAEJ,MAAMC,MAAMD,KAAK,GAAG,IAAI;IACxB,MAAME,OAAOF,KAAK,IAAI,IAAI;IAC1B,MAAMG,SAASH,KAAK,MAAM,IAAI;IAC9B,MAAMI,QAAQJ,KAAK,KAAK,IAAI;IAC5B,IAAIC,AAAQ,MAARA,OAAaC,AAAS,MAATA,QAAcC,AAAW,MAAXA,UAAgBC,AAAU,MAAVA,OAC3C;IAEJ,OAAO;QAACH;QAAKC;QAAMC;QAAQC;KAAM,CAAC,GAAG,CAACR,OAAO,IAAI,CAAC;AACtD;AAOO,MAAMS,kBAAkB,CAACC;IAC5B,MAAMC,MAAMD,OAAO;IACnB,IAAI,CAACC,KACD,OAAO;IAEX,MAAMC,QAAQT,UAAUO,OAAO,OAAO;IACtC,IAAI,CAACE,OACD,OAAOD;IAEX,MAAME,YAAYF,IAAI,QAAQ,CAAC,OAAO,MAAM;IAC5C,OAAO,GAAGA,MAAME,UAAU,KAAK,EAAED,OAAO;AAC5C"}
@@ -1,4 +1,4 @@
1
- export { ModelFactory } from "./abstractions.js";
1
+ export { ModelFactory, type IModelSettings } from "./abstractions.js";
2
2
  export * from "./models/BaseModelBuilder.js";
3
3
  export * from "./models/ModelBuilder.js";
4
4
  export * from "./models/PrivateModelBuilder.js";
@@ -1,6 +1,6 @@
1
1
  import { BaseFieldBuilder } from "../../../features/modelBuilder/index.js";
2
2
  import { CmsModelPlugin } from "../../../plugins/CmsModelPlugin.js";
3
- import { FieldBuilderRegistry } from "../abstractions.js";
3
+ import { FieldBuilderRegistry, type IModelSettings } from "../abstractions.js";
4
4
  import type { CmsModelField, CmsModelLayoutCell } from "../../../types/index.js";
5
5
  /**
6
6
  * Base class for all model builders, containing shared logic.
@@ -12,6 +12,7 @@ export declare abstract class BaseModelBuilder<TBuild = CmsModelPlugin> {
12
12
  modelId?: string;
13
13
  name?: string;
14
14
  tags?: string[];
15
+ settings?: IModelSettings;
15
16
  };
16
17
  protected isSingleEntry: boolean;
17
18
  protected fieldBuildersMap: Map<string, BaseFieldBuilder<any>>;
@@ -20,6 +21,7 @@ export declare abstract class BaseModelBuilder<TBuild = CmsModelPlugin> {
20
21
  name(name: string): this;
21
22
  singleEntry(): this;
22
23
  tags(tags: string[]): this;
24
+ settings(settings: Partial<IModelSettings>): this;
23
25
  fields(builder: (registry: FieldBuilderRegistry.Interface) => Record<string, BaseFieldBuilder<any>>): this;
24
26
  /**
25
27
  * Merge field operations from extension builder into existing builder.
@@ -21,6 +21,13 @@ class BaseModelBuilder {
21
21
  this.config.tags = tags;
22
22
  return this;
23
23
  }
24
+ settings(settings) {
25
+ this.config.settings = {
26
+ ...this.config.settings || {},
27
+ ...settings
28
+ };
29
+ return this;
30
+ }
24
31
  fields(builder) {
25
32
  this.registry.existingFields = this.fieldBuildersMap;
26
33
  const fieldBuilders = builder(this.registry);
@@ -1 +1 @@
1
- {"version":3,"file":"features/modelBuilder/models/BaseModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/BaseModelBuilder.ts"],"sourcesContent":["import { BaseFieldBuilder } from \"~/features/modelBuilder/index.js\";\nimport { CmsModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { FieldBuilderRegistry } from \"../abstractions.js\";\nimport type { CmsModelField, CmsModelLayoutCell } from \"~/types/index.js\";\n\n/**\n * Base class for all model builders, containing shared logic.\n * Concrete builders (PrivateModelBuilder, PublicModelBuilder) extend this.\n */\nexport abstract class BaseModelBuilder<TBuild = CmsModelPlugin> {\n protected config: {\n modelId?: string;\n name?: string;\n tags?: string[];\n } = {};\n\n protected isSingleEntry = false;\n protected fieldBuildersMap = new Map<string, BaseFieldBuilder<any>>();\n\n public constructor(protected registry: FieldBuilderRegistry.Interface) {}\n\n modelId(id: string): this {\n this.config.modelId = id;\n return this;\n }\n\n name(name: string): this {\n this.config.name = name;\n return this;\n }\n\n singleEntry(): this {\n this.isSingleEntry = true;\n return this;\n }\n\n tags(tags: string[]): this {\n this.config.tags = tags;\n return this;\n }\n\n fields(\n builder: (registry: FieldBuilderRegistry.Interface) => Record<string, BaseFieldBuilder<any>>\n ): this {\n // Pass existing fields to registry so it can return them when extending\n (this.registry as any).existingFields = this.fieldBuildersMap;\n\n const fieldBuilders = builder(this.registry);\n\n for (const [key, fieldBuilder] of Object.entries(fieldBuilders)) {\n // Set the fieldId from the object key\n fieldBuilder.fieldId(key);\n\n const existingBuilder = this.fieldBuildersMap.get(key);\n const isExtendMode = (fieldBuilder as any)._extendMode;\n\n if (isExtendMode && existingBuilder) {\n // Extension mode - validate type and merge operations\n if (existingBuilder.type !== fieldBuilder.type) {\n throw new Error(\n `Cannot extend field \"${key}\": type mismatch. Expected \"${existingBuilder.type}\", got \"${fieldBuilder.type}\".`\n );\n }\n // Merge operations from temporary new builder into existing builder\n this.mergeFieldOperations(key, existingBuilder, fieldBuilder);\n } else if (existingBuilder && !isExtendMode) {\n // Replacement mode - validate type\n if (existingBuilder.type !== fieldBuilder.type) {\n throw new Error(\n `Cannot redefine field \"${key}\": type mismatch. Expected \"${existingBuilder.type}\", got \"${fieldBuilder.type}\".`\n );\n }\n // Replace with new builder\n this.fieldBuildersMap.set(key, fieldBuilder);\n } else if (!existingBuilder && !isExtendMode) {\n // New field - store builder\n this.fieldBuildersMap.set(key, fieldBuilder);\n } else {\n // isExtendMode but no existingBuilder - this is an error\n throw new Error(\n `Cannot extend field \"${key}\": field does not exist. Use .extend() only for existing fields.`\n );\n }\n }\n\n return this;\n }\n\n /**\n * Merge field operations from extension builder into existing builder.\n * This handles the case where multiple fields of the same type exist,\n * and we need to transfer operations from the temporary new builder\n * to the existing builder.\n * @internal\n */\n private mergeFieldOperations(\n fieldId: string,\n existing: BaseFieldBuilder<any>,\n extension: BaseFieldBuilder<any>\n ): void {\n // For object fields, merge nested fields and layout operations\n if (existing.type === \"object\" && extension.type === \"object\") {\n const existingFieldMap = (existing as any).fieldBuildersMap;\n const extensionFieldMap = (extension as any).fieldBuildersMap;\n\n // Merge nested field builders\n if (extensionFieldMap) {\n for (const [nestedKey, nestedBuilder] of extensionFieldMap.entries()) {\n existingFieldMap.set(nestedKey, nestedBuilder);\n }\n }\n\n // Merge layout operations\n const existingLayoutBuilder = (existing as any).layoutBuilder;\n const extensionLayoutBuilder = (extension as any).layoutBuilder;\n\n if (extensionLayoutBuilder) {\n const snapshot = extensionLayoutBuilder.getSnapshot();\n\n // If extension called setLayout() with an array, apply it to existing\n // We detect this by checking if there's a layout but no modifiers\n if (snapshot.layout.length > 0 && snapshot.modifiers.length === 0) {\n existingLayoutBuilder.setLayout(snapshot.layout);\n }\n\n // Apply all modifiers from extension to existing\n for (const modifier of snapshot.modifiers) {\n existingLayoutBuilder.addModifier(modifier);\n }\n }\n }\n }\n\n protected buildFields(): {\n fields: CmsModelField[];\n layoutReplacements: Map<string, CmsModelLayoutCell>;\n } {\n const fields: CmsModelField[] = [];\n const layoutReplacements = new Map<string, CmsModelLayoutCell>();\n\n for (const [fieldId, builder] of this.fieldBuildersMap) {\n const result = builder.build();\n if (result.type === \"layout\") {\n layoutReplacements.set(fieldId, result.layoutCell);\n if (result.fields) {\n fields.push(...result.fields);\n }\n } else {\n fields.push(result.field);\n }\n }\n\n return { fields, layoutReplacements };\n }\n\n /**\n * Get tags with common defaults applied.\n * Always includes \"type:model\" and optionally \"singleEntry\".\n */\n protected getTags(): string[] {\n const tagsSet = new Set(this.config.tags || []);\n tagsSet.add(\"type:model\");\n if (this.isSingleEntry) {\n tagsSet.add(\"singleEntry\");\n }\n return Array.from(tagsSet);\n }\n\n /**\n * Build the final model configuration.\n * Must be implemented by concrete builders.\n */\n abstract build(): TBuild;\n}\n"],"names":["BaseModelBuilder","registry","Map","id","name","tags","builder","fieldBuilders","key","fieldBuilder","Object","existingBuilder","isExtendMode","Error","fieldId","existing","extension","existingFieldMap","extensionFieldMap","nestedKey","nestedBuilder","existingLayoutBuilder","extensionLayoutBuilder","snapshot","modifier","fields","layoutReplacements","result","tagsSet","Set","Array"],"mappings":"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"}
1
+ {"version":3,"file":"features/modelBuilder/models/BaseModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/BaseModelBuilder.ts"],"sourcesContent":["import { BaseFieldBuilder } from \"~/features/modelBuilder/index.js\";\nimport { CmsModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { FieldBuilderRegistry, type IModelSettings } from \"../abstractions.js\";\nimport type { CmsModelField, CmsModelLayoutCell } from \"~/types/index.js\";\n\n/**\n * Base class for all model builders, containing shared logic.\n * Concrete builders (PrivateModelBuilder, PublicModelBuilder) extend this.\n */\nexport abstract class BaseModelBuilder<TBuild = CmsModelPlugin> {\n protected config: {\n modelId?: string;\n name?: string;\n tags?: string[];\n settings?: IModelSettings;\n } = {};\n\n protected isSingleEntry = false;\n protected fieldBuildersMap = new Map<string, BaseFieldBuilder<any>>();\n\n public constructor(protected registry: FieldBuilderRegistry.Interface) {}\n\n modelId(id: string): this {\n this.config.modelId = id;\n return this;\n }\n\n name(name: string): this {\n this.config.name = name;\n return this;\n }\n\n singleEntry(): this {\n this.isSingleEntry = true;\n return this;\n }\n\n tags(tags: string[]): this {\n this.config.tags = tags;\n return this;\n }\n\n settings(settings: Partial<IModelSettings>): this {\n this.config.settings = { ...(this.config.settings || {}), ...settings };\n return this;\n }\n\n fields(\n builder: (registry: FieldBuilderRegistry.Interface) => Record<string, BaseFieldBuilder<any>>\n ): this {\n // Pass existing fields to registry so it can return them when extending\n (this.registry as any).existingFields = this.fieldBuildersMap;\n\n const fieldBuilders = builder(this.registry);\n\n for (const [key, fieldBuilder] of Object.entries(fieldBuilders)) {\n // Set the fieldId from the object key\n fieldBuilder.fieldId(key);\n\n const existingBuilder = this.fieldBuildersMap.get(key);\n const isExtendMode = (fieldBuilder as any)._extendMode;\n\n if (isExtendMode && existingBuilder) {\n // Extension mode - validate type and merge operations\n if (existingBuilder.type !== fieldBuilder.type) {\n throw new Error(\n `Cannot extend field \"${key}\": type mismatch. Expected \"${existingBuilder.type}\", got \"${fieldBuilder.type}\".`\n );\n }\n // Merge operations from temporary new builder into existing builder\n this.mergeFieldOperations(key, existingBuilder, fieldBuilder);\n } else if (existingBuilder && !isExtendMode) {\n // Replacement mode - validate type\n if (existingBuilder.type !== fieldBuilder.type) {\n throw new Error(\n `Cannot redefine field \"${key}\": type mismatch. Expected \"${existingBuilder.type}\", got \"${fieldBuilder.type}\".`\n );\n }\n // Replace with new builder\n this.fieldBuildersMap.set(key, fieldBuilder);\n } else if (!existingBuilder && !isExtendMode) {\n // New field - store builder\n this.fieldBuildersMap.set(key, fieldBuilder);\n } else {\n // isExtendMode but no existingBuilder - this is an error\n throw new Error(\n `Cannot extend field \"${key}\": field does not exist. Use .extend() only for existing fields.`\n );\n }\n }\n\n return this;\n }\n\n /**\n * Merge field operations from extension builder into existing builder.\n * This handles the case where multiple fields of the same type exist,\n * and we need to transfer operations from the temporary new builder\n * to the existing builder.\n * @internal\n */\n private mergeFieldOperations(\n fieldId: string,\n existing: BaseFieldBuilder<any>,\n extension: BaseFieldBuilder<any>\n ): void {\n // For object fields, merge nested fields and layout operations\n if (existing.type === \"object\" && extension.type === \"object\") {\n const existingFieldMap = (existing as any).fieldBuildersMap;\n const extensionFieldMap = (extension as any).fieldBuildersMap;\n\n // Merge nested field builders\n if (extensionFieldMap) {\n for (const [nestedKey, nestedBuilder] of extensionFieldMap.entries()) {\n existingFieldMap.set(nestedKey, nestedBuilder);\n }\n }\n\n // Merge layout operations\n const existingLayoutBuilder = (existing as any).layoutBuilder;\n const extensionLayoutBuilder = (extension as any).layoutBuilder;\n\n if (extensionLayoutBuilder) {\n const snapshot = extensionLayoutBuilder.getSnapshot();\n\n // If extension called setLayout() with an array, apply it to existing\n // We detect this by checking if there's a layout but no modifiers\n if (snapshot.layout.length > 0 && snapshot.modifiers.length === 0) {\n existingLayoutBuilder.setLayout(snapshot.layout);\n }\n\n // Apply all modifiers from extension to existing\n for (const modifier of snapshot.modifiers) {\n existingLayoutBuilder.addModifier(modifier);\n }\n }\n }\n }\n\n protected buildFields(): {\n fields: CmsModelField[];\n layoutReplacements: Map<string, CmsModelLayoutCell>;\n } {\n const fields: CmsModelField[] = [];\n const layoutReplacements = new Map<string, CmsModelLayoutCell>();\n\n for (const [fieldId, builder] of this.fieldBuildersMap) {\n const result = builder.build();\n if (result.type === \"layout\") {\n layoutReplacements.set(fieldId, result.layoutCell);\n if (result.fields) {\n fields.push(...result.fields);\n }\n } else {\n fields.push(result.field);\n }\n }\n\n return { fields, layoutReplacements };\n }\n\n /**\n * Get tags with common defaults applied.\n * Always includes \"type:model\" and optionally \"singleEntry\".\n */\n protected getTags(): string[] {\n const tagsSet = new Set(this.config.tags || []);\n tagsSet.add(\"type:model\");\n if (this.isSingleEntry) {\n tagsSet.add(\"singleEntry\");\n }\n return Array.from(tagsSet);\n }\n\n /**\n * Build the final model configuration.\n * Must be implemented by concrete builders.\n */\n abstract build(): TBuild;\n}\n"],"names":["BaseModelBuilder","registry","Map","id","name","tags","settings","builder","fieldBuilders","key","fieldBuilder","Object","existingBuilder","isExtendMode","Error","fieldId","existing","extension","existingFieldMap","extensionFieldMap","nestedKey","nestedBuilder","existingLayoutBuilder","extensionLayoutBuilder","snapshot","modifier","fields","layoutReplacements","result","tagsSet","Set","Array"],"mappings":"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"}
@@ -12,7 +12,8 @@ class PrivateModelBuilder extends BaseModelBuilder {
12
12
  fields,
13
13
  authorization: false,
14
14
  noValidate: true,
15
- tags: this.getTags()
15
+ tags: this.getTags(),
16
+ settings: this.config.settings || {}
16
17
  });
17
18
  }
18
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"features/modelBuilder/models/PrivateModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/PrivateModelBuilder.ts"],"sourcesContent":["import { createPrivateModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { BaseModelBuilder } from \"./BaseModelBuilder.js\";\n\nexport class PrivateModelBuilder extends BaseModelBuilder {\n public build() {\n if (!this.config.modelId) {\n throw new Error(\"modelId is required\");\n }\n if (!this.config.name) {\n throw new Error(\"name is required\");\n }\n if (this.fieldBuildersMap.size === 0) {\n throw new Error(\"fields are required\");\n }\n\n // Build all fields from field builders (layout replacements ignored for private models)\n const { fields } = this.buildFields();\n\n return createPrivateModelPlugin({\n modelId: this.config.modelId,\n name: this.config.name,\n fields,\n authorization: false,\n noValidate: true,\n tags: this.getTags()\n });\n }\n}\n"],"names":["PrivateModelBuilder","BaseModelBuilder","Error","fields","createPrivateModelPlugin"],"mappings":";;AAGO,MAAMA,4BAA4BC;IAC9B,QAAQ;QACX,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EACpB,MAAM,IAAIC,MAAM;QAEpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EACjB,MAAM,IAAIA,MAAM;QAEpB,IAAI,AAA+B,MAA/B,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAC1B,MAAM,IAAIA,MAAM;QAIpB,MAAM,EAAEC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW;QAEnC,OAAOC,yBAAyB;YAC5B,SAAS,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI;YACtBD;YACA,eAAe;YACf,YAAY;YACZ,MAAM,IAAI,CAAC,OAAO;QACtB;IACJ;AACJ"}
1
+ {"version":3,"file":"features/modelBuilder/models/PrivateModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/PrivateModelBuilder.ts"],"sourcesContent":["import { createPrivateModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { BaseModelBuilder } from \"./BaseModelBuilder.js\";\n\nexport class PrivateModelBuilder extends BaseModelBuilder {\n public build() {\n if (!this.config.modelId) {\n throw new Error(\"modelId is required\");\n }\n if (!this.config.name) {\n throw new Error(\"name is required\");\n }\n if (this.fieldBuildersMap.size === 0) {\n throw new Error(\"fields are required\");\n }\n\n // Build all fields from field builders (layout replacements ignored for private models)\n const { fields } = this.buildFields();\n\n return createPrivateModelPlugin({\n modelId: this.config.modelId,\n name: this.config.name,\n fields,\n authorization: false,\n noValidate: true,\n tags: this.getTags(),\n settings: this.config.settings || {}\n });\n }\n}\n"],"names":["PrivateModelBuilder","BaseModelBuilder","Error","fields","createPrivateModelPlugin"],"mappings":";;AAGO,MAAMA,4BAA4BC;IAC9B,QAAQ;QACX,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EACpB,MAAM,IAAIC,MAAM;QAEpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EACjB,MAAM,IAAIA,MAAM;QAEpB,IAAI,AAA+B,MAA/B,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAC1B,MAAM,IAAIA,MAAM;QAIpB,MAAM,EAAEC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW;QAEnC,OAAOC,yBAAyB;YAC5B,SAAS,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI;YACtBD;YACA,eAAe;YACf,YAAY;YACZ,MAAM,IAAI,CAAC,OAAO;YAClB,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC;QACvC;IACJ;AACJ"}
@@ -92,7 +92,8 @@ class PublicModelBuilder extends BaseModelBuilder {
92
92
  imageFieldId: this.publicConfig.imageFieldId,
93
93
  layout,
94
94
  fields,
95
- tags: this.getTags()
95
+ tags: this.getTags(),
96
+ settings: this.config.settings || {}
96
97
  }, {
97
98
  validateLayout: false
98
99
  });
@@ -1 +1 @@
1
- {"version":3,"file":"features/modelBuilder/models/PublicModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/PublicModelBuilder.ts"],"sourcesContent":["import upperFirst from \"lodash/upperFirst.js\";\nimport camelCase from \"lodash/camelCase.js\";\nimport pluralize from \"pluralize\";\nimport { createModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { BaseModelBuilder } from \"./BaseModelBuilder.js\";\nimport type { CmsIcon, CmsModelField } from \"~/types/index.js\";\nimport { LayoutBuilder } from \"../LayoutBuilder.js\";\n\nconst createApiName = (name: string) => {\n return upperFirst(camelCase(name));\n};\n\nconst createPluralApiName = (name: string) => {\n return pluralize(createApiName(name));\n};\n\nclass Icon {\n static from(icon: string | CmsIcon): CmsIcon {\n if (typeof icon === \"string\") {\n return {\n type: \"icon\",\n name: icon\n };\n }\n\n return icon;\n }\n}\n\nexport class PublicModelBuilder extends BaseModelBuilder {\n private publicConfig: {\n singularApiName?: string;\n pluralApiName?: string;\n group?: string;\n icon?: CmsIcon;\n description?: string;\n titleFieldId?: string;\n descriptionFieldId?: string;\n imageFieldId?: string;\n } = {};\n private layoutBuilder: LayoutBuilder;\n\n singularApiName(name: string): this {\n this.publicConfig.singularApiName = name;\n return this;\n }\n\n pluralApiName(name: string): this {\n this.publicConfig.pluralApiName = name;\n return this;\n }\n\n group(slug: string): this {\n this.publicConfig.group = slug;\n return this;\n }\n\n icon(icon: string | CmsIcon): this {\n this.publicConfig.icon = Icon.from(icon);\n return this;\n }\n\n description(description: string): this {\n this.publicConfig.description = description;\n return this;\n }\n\n titleFieldId(fieldId: string): this {\n this.publicConfig.titleFieldId = fieldId;\n return this;\n }\n\n descriptionFieldId(fieldId: string): this {\n this.publicConfig.descriptionFieldId = fieldId;\n return this;\n }\n\n imageFieldId(fieldId: string): this {\n this.publicConfig.imageFieldId = fieldId;\n return this;\n }\n /**\n * It just creates problems if we import the FieldBuilderRegistry.\n * TODO: figure out\n */\n constructor(registry: any) {\n super(registry);\n this.layoutBuilder = new LayoutBuilder();\n }\n\n layout(layoutOrBuilder: string[][] | ((builder: LayoutBuilder) => void)): this {\n if (Array.isArray(layoutOrBuilder)) {\n // Replace layout with array\n this.layoutBuilder.setLayout(layoutOrBuilder);\n } else {\n // Queue the modifier callback\n this.layoutBuilder.addModifier(layoutOrBuilder);\n }\n return this;\n }\n\n build() {\n if (!this.config.modelId) {\n throw new Error(\"modelId is required\");\n }\n if (!this.config.name) {\n throw new Error(\"name is required\");\n }\n if (this.fieldBuildersMap.size === 0) {\n this.fields(builder => ({\n alert: builder\n .uiAlert()\n .label(\n \"No fields defined in the code content model. Please ensure you have the fields property correctly defined.\"\n ),\n emptyPlaceholder: builder.text().label(\"Empty\").renderer(\"hidden\")\n }));\n this.titleFieldId(\"emptyPlaceholder\");\n this.layoutBuilder.setLayout([[\"alert\"], [\"emptyPlaceholder\"]]);\n }\n if (!this.publicConfig.group) {\n throw new Error(\"group is required\");\n }\n\n // Build all fields from field builders, separating data and layout results\n const { fields, layoutReplacements } = this.buildFields();\n\n // Build and apply layout replacements (tabs → rich descriptors)\n const rawLayout = this.layoutBuilder.build();\n const layout = rawLayout.map(row => row.map(cell => layoutReplacements.get(cell) ?? cell));\n\n return createModelPlugin(\n {\n modelId: this.config.modelId,\n name: this.config.name,\n singularApiName:\n this.publicConfig.singularApiName || createApiName(this.config.name),\n pluralApiName:\n this.publicConfig.pluralApiName || createPluralApiName(this.config.name),\n group: this.publicConfig.group,\n icon: this.publicConfig.icon ?? null,\n description: this.publicConfig.description || null,\n titleFieldId:\n this.publicConfig.titleFieldId ?? this.findFirstFieldId(fields, \"text\"),\n descriptionFieldId: this.publicConfig.descriptionFieldId,\n imageFieldId: this.publicConfig.imageFieldId,\n layout,\n fields,\n tags: this.getTags()\n },\n { validateLayout: false }\n );\n }\n\n private findFirstFieldId(fields: CmsModelField[], type: string): string {\n for (const field of fields) {\n if (field.type === type) {\n return field.fieldId;\n }\n }\n return fields.find(field => field.type === \"text\")?.fieldId || \"\";\n }\n}\n"],"names":["createApiName","name","upperFirst","camelCase","createPluralApiName","pluralize","Icon","icon","PublicModelBuilder","BaseModelBuilder","slug","description","fieldId","registry","LayoutBuilder","layoutOrBuilder","Array","Error","builder","fields","layoutReplacements","rawLayout","layout","row","cell","createModelPlugin","type","field"],"mappings":"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"}
1
+ {"version":3,"file":"features/modelBuilder/models/PublicModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/PublicModelBuilder.ts"],"sourcesContent":["import upperFirst from \"lodash/upperFirst.js\";\nimport camelCase from \"lodash/camelCase.js\";\nimport pluralize from \"pluralize\";\nimport { createModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { BaseModelBuilder } from \"./BaseModelBuilder.js\";\nimport type { CmsIcon, CmsModelField } from \"~/types/index.js\";\nimport { LayoutBuilder } from \"../LayoutBuilder.js\";\n\nconst createApiName = (name: string) => {\n return upperFirst(camelCase(name));\n};\n\nconst createPluralApiName = (name: string) => {\n return pluralize(createApiName(name));\n};\n\nclass Icon {\n static from(icon: string | CmsIcon): CmsIcon {\n if (typeof icon === \"string\") {\n return {\n type: \"icon\",\n name: icon\n };\n }\n\n return icon;\n }\n}\n\nexport class PublicModelBuilder extends BaseModelBuilder {\n private publicConfig: {\n singularApiName?: string;\n pluralApiName?: string;\n group?: string;\n icon?: CmsIcon;\n description?: string;\n titleFieldId?: string;\n descriptionFieldId?: string;\n imageFieldId?: string;\n } = {};\n private layoutBuilder: LayoutBuilder;\n\n singularApiName(name: string): this {\n this.publicConfig.singularApiName = name;\n return this;\n }\n\n pluralApiName(name: string): this {\n this.publicConfig.pluralApiName = name;\n return this;\n }\n\n group(slug: string): this {\n this.publicConfig.group = slug;\n return this;\n }\n\n icon(icon: string | CmsIcon): this {\n this.publicConfig.icon = Icon.from(icon);\n return this;\n }\n\n description(description: string): this {\n this.publicConfig.description = description;\n return this;\n }\n\n titleFieldId(fieldId: string): this {\n this.publicConfig.titleFieldId = fieldId;\n return this;\n }\n\n descriptionFieldId(fieldId: string): this {\n this.publicConfig.descriptionFieldId = fieldId;\n return this;\n }\n\n imageFieldId(fieldId: string): this {\n this.publicConfig.imageFieldId = fieldId;\n return this;\n }\n /**\n * It just creates problems if we import the FieldBuilderRegistry.\n * TODO: figure out\n */\n constructor(registry: any) {\n super(registry);\n this.layoutBuilder = new LayoutBuilder();\n }\n\n layout(layoutOrBuilder: string[][] | ((builder: LayoutBuilder) => void)): this {\n if (Array.isArray(layoutOrBuilder)) {\n // Replace layout with array\n this.layoutBuilder.setLayout(layoutOrBuilder);\n } else {\n // Queue the modifier callback\n this.layoutBuilder.addModifier(layoutOrBuilder);\n }\n return this;\n }\n\n build() {\n if (!this.config.modelId) {\n throw new Error(\"modelId is required\");\n }\n if (!this.config.name) {\n throw new Error(\"name is required\");\n }\n if (this.fieldBuildersMap.size === 0) {\n this.fields(builder => ({\n alert: builder\n .uiAlert()\n .label(\n \"No fields defined in the code content model. Please ensure you have the fields property correctly defined.\"\n ),\n emptyPlaceholder: builder.text().label(\"Empty\").renderer(\"hidden\")\n }));\n this.titleFieldId(\"emptyPlaceholder\");\n this.layoutBuilder.setLayout([[\"alert\"], [\"emptyPlaceholder\"]]);\n }\n if (!this.publicConfig.group) {\n throw new Error(\"group is required\");\n }\n\n // Build all fields from field builders, separating data and layout results\n const { fields, layoutReplacements } = this.buildFields();\n\n // Build and apply layout replacements (tabs → rich descriptors)\n const rawLayout = this.layoutBuilder.build();\n const layout = rawLayout.map(row => row.map(cell => layoutReplacements.get(cell) ?? cell));\n\n return createModelPlugin(\n {\n modelId: this.config.modelId,\n name: this.config.name,\n singularApiName:\n this.publicConfig.singularApiName || createApiName(this.config.name),\n pluralApiName:\n this.publicConfig.pluralApiName || createPluralApiName(this.config.name),\n group: this.publicConfig.group,\n icon: this.publicConfig.icon ?? null,\n description: this.publicConfig.description || null,\n titleFieldId:\n this.publicConfig.titleFieldId ?? this.findFirstFieldId(fields, \"text\"),\n descriptionFieldId: this.publicConfig.descriptionFieldId,\n imageFieldId: this.publicConfig.imageFieldId,\n layout,\n fields,\n tags: this.getTags(),\n settings: this.config.settings || {}\n },\n { validateLayout: false }\n );\n }\n\n private findFirstFieldId(fields: CmsModelField[], type: string): string {\n for (const field of fields) {\n if (field.type === type) {\n return field.fieldId;\n }\n }\n return fields.find(field => field.type === \"text\")?.fieldId || \"\";\n }\n}\n"],"names":["createApiName","name","upperFirst","camelCase","createPluralApiName","pluralize","Icon","icon","PublicModelBuilder","BaseModelBuilder","slug","description","fieldId","registry","LayoutBuilder","layoutOrBuilder","Array","Error","builder","fields","layoutReplacements","rawLayout","layout","row","cell","createModelPlugin","type","field"],"mappings":"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"}
@@ -4,10 +4,7 @@ class SortImpl {
4
4
  const { fields: modelFields, input } = params;
5
5
  if (!input) return;
6
6
  const fields = modelFields.map((field)=>field.fieldId);
7
- const isField = (key)=>{
8
- const field = key.split("_")[0];
9
- return fields.includes(field);
10
- };
7
+ const isField = (key)=>fields.includes(key);
11
8
  return this.mapSort({
12
9
  input,
13
10
  isField
@@ -16,7 +13,7 @@ class SortImpl {
16
13
  mapSort(params) {
17
14
  const { input, isField } = params;
18
15
  return input.map((sort)=>{
19
- const match = sort.match(/^(values_)?([a-zA-Z][a-zA-Z0-9]*)_(ASC|DESC)$/);
16
+ const match = sort.match(/^(values_)?([a-zA-Z][a-zA-Z0-9_]*)_(ASC|DESC)$/);
20
17
  if (!match) return null;
21
18
  const [, hasValues, field, direction] = match;
22
19
  if (hasValues) return sort;
@@ -1 +1 @@
1
- {"version":3,"file":"features/sortMapper/SortMapper.js","sources":["../../../src/features/sortMapper/SortMapper.ts"],"sourcesContent":["/**\n * Used to map sorting for custom CMS Models.\n */\nimport { type CmsEntryListSort } from \"~/types/types.js\";\nimport { CmsSortMapper, ICmsSortMapperParams } from \"./abstractions.js\";\n\ninterface IMapSortParams {\n input: CmsEntryListSort;\n isField: (key: string) => boolean;\n}\n\nclass SortImpl implements CmsSortMapper.Interface {\n map(params: ICmsSortMapperParams): CmsEntryListSort | undefined {\n const { fields: modelFields, input } = params;\n if (!input) {\n return undefined;\n }\n\n const fields = modelFields.map(field => {\n return field.fieldId;\n });\n\n const isField = (key: string): boolean => {\n const field = key.split(\"_\")[0];\n return fields.includes(field);\n };\n\n return this.mapSort({\n input,\n isField\n });\n }\n\n private mapSort(params: IMapSortParams): CmsEntryListSort {\n const { input, isField } = params;\n\n return input\n .map(sort => {\n const match = sort.match(/^(values_)?([a-zA-Z][a-zA-Z0-9]*)_(ASC|DESC)$/);\n if (!match) {\n return null;\n }\n\n const [, hasValues, field, direction] = match;\n\n if (hasValues) {\n return sort;\n }\n\n if (isField(field)) {\n return `values_${field}_${direction}` as unknown as CmsEntryListSort[0];\n }\n\n return sort;\n })\n .filter((item): item is CmsEntryListSort[0] => !!item);\n }\n}\n\nexport const SortMapper = CmsSortMapper.createImplementation({\n implementation: SortImpl,\n dependencies: []\n});\n"],"names":["SortImpl","params","modelFields","input","fields","field","isField","key","sort","match","hasValues","direction","item","SortMapper","CmsSortMapper"],"mappings":";AAWA,MAAMA;IACF,IAAIC,MAA4B,EAAgC;QAC5D,MAAM,EAAE,QAAQC,WAAW,EAAEC,KAAK,EAAE,GAAGF;QACvC,IAAI,CAACE,OACD;QAGJ,MAAMC,SAASF,YAAY,GAAG,CAACG,CAAAA,QACpBA,MAAM,OAAO;QAGxB,MAAMC,UAAU,CAACC;YACb,MAAMF,QAAQE,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;YAC/B,OAAOH,OAAO,QAAQ,CAACC;QAC3B;QAEA,OAAO,IAAI,CAAC,OAAO,CAAC;YAChBF;YACAG;QACJ;IACJ;IAEQ,QAAQL,MAAsB,EAAoB;QACtD,MAAM,EAAEE,KAAK,EAAEG,OAAO,EAAE,GAAGL;QAE3B,OAAOE,MACF,GAAG,CAACK,CAAAA;YACD,MAAMC,QAAQD,KAAK,KAAK,CAAC;YACzB,IAAI,CAACC,OACD,OAAO;YAGX,MAAM,GAAGC,WAAWL,OAAOM,UAAU,GAAGF;YAExC,IAAIC,WACA,OAAOF;YAGX,IAAIF,QAAQD,QACR,OAAO,CAAC,OAAO,EAAEA,MAAM,CAAC,EAAEM,WAAW;YAGzC,OAAOH;QACX,GACC,MAAM,CAAC,CAACI,OAAsC,CAAC,CAACA;IACzD;AACJ;AAEO,MAAMC,aAAaC,cAAc,oBAAoB,CAAC;IACzD,gBAAgBd;IAChB,cAAc,EAAE;AACpB"}
1
+ {"version":3,"file":"features/sortMapper/SortMapper.js","sources":["../../../src/features/sortMapper/SortMapper.ts"],"sourcesContent":["/**\n * Used to map sorting for custom CMS Models.\n */\nimport { type CmsEntryListSort } from \"~/types/types.js\";\nimport { CmsSortMapper, ICmsSortMapperParams } from \"./abstractions.js\";\n\ninterface IMapSortParams {\n input: CmsEntryListSort;\n isField: (key: string) => boolean;\n}\n\nclass SortImpl implements CmsSortMapper.Interface {\n map(params: ICmsSortMapperParams): CmsEntryListSort | undefined {\n const { fields: modelFields, input } = params;\n if (!input) {\n return undefined;\n }\n\n const fields = modelFields.map(field => {\n return field.fieldId;\n });\n\n /*\n * `mapSort` has already stripped the direction, so what arrives here is a bare fieldId and\n * is compared whole. Taking the segment before the first `_` would fail every fieldId that\n * contains one: `on_sale` would be looked up as `on`.\n */\n const isField = (key: string): boolean => {\n return fields.includes(key);\n };\n\n return this.mapSort({\n input,\n isField\n });\n }\n\n private mapSort(params: IMapSortParams): CmsEntryListSort {\n const { input, isField } = params;\n\n return input\n .map(sort => {\n // `_` is allowed inside the fieldId: excluding it made `on_sale_DESC` unmatchable,\n // and an unmatched directive is dropped from the sort entirely.\n const match = sort.match(/^(values_)?([a-zA-Z][a-zA-Z0-9_]*)_(ASC|DESC)$/);\n if (!match) {\n return null;\n }\n\n const [, hasValues, field, direction] = match;\n\n if (hasValues) {\n return sort;\n }\n\n if (isField(field)) {\n return `values_${field}_${direction}` as unknown as CmsEntryListSort[0];\n }\n\n return sort;\n })\n .filter((item): item is CmsEntryListSort[0] => !!item);\n }\n}\n\nexport const SortMapper = CmsSortMapper.createImplementation({\n implementation: SortImpl,\n dependencies: []\n});\n"],"names":["SortImpl","params","modelFields","input","fields","field","isField","key","sort","match","hasValues","direction","item","SortMapper","CmsSortMapper"],"mappings":";AAWA,MAAMA;IACF,IAAIC,MAA4B,EAAgC;QAC5D,MAAM,EAAE,QAAQC,WAAW,EAAEC,KAAK,EAAE,GAAGF;QACvC,IAAI,CAACE,OACD;QAGJ,MAAMC,SAASF,YAAY,GAAG,CAACG,CAAAA,QACpBA,MAAM,OAAO;QAQxB,MAAMC,UAAU,CAACC,MACNH,OAAO,QAAQ,CAACG;QAG3B,OAAO,IAAI,CAAC,OAAO,CAAC;YAChBJ;YACAG;QACJ;IACJ;IAEQ,QAAQL,MAAsB,EAAoB;QACtD,MAAM,EAAEE,KAAK,EAAEG,OAAO,EAAE,GAAGL;QAE3B,OAAOE,MACF,GAAG,CAACK,CAAAA;YAGD,MAAMC,QAAQD,KAAK,KAAK,CAAC;YACzB,IAAI,CAACC,OACD,OAAO;YAGX,MAAM,GAAGC,WAAWL,OAAOM,UAAU,GAAGF;YAExC,IAAIC,WACA,OAAOF;YAGX,IAAIF,QAAQD,QACR,OAAO,CAAC,OAAO,EAAEA,MAAM,CAAC,EAAEM,WAAW;YAGzC,OAAOH;QACX,GACC,MAAM,CAAC,CAACI,OAAsC,CAAC,CAACA;IACzD;AACJ;AAEO,MAAMC,aAAaC,cAAc,oBAAoB,CAAC;IACzD,gBAAgBd;IAChB,cAAc,EAAE;AACpB"}
@@ -9,11 +9,8 @@ class WhereMapperImpl {
9
9
  map(params) {
10
10
  const { fields: modelFields, input } = params;
11
11
  if (!input) return;
12
- const fields = modelFields.map((field)=>field.fieldId);
13
- const isField = (key)=>{
14
- const field = key.split("_")[0];
15
- return fields.includes(field);
16
- };
12
+ const fields = modelFields.map((field)=>field.fieldId).sort((a, b)=>b.length - a.length);
13
+ const isField = (key)=>fields.some((fieldId)=>key === fieldId || key.startsWith(`${fieldId}_`));
17
14
  return this.mapWhere({
18
15
  input,
19
16
  isField
@@ -33,6 +30,11 @@ class WhereMapperImpl {
33
30
  }));
34
31
  continue;
35
32
  }
33
+ if ("values" === key && isPlainObject(value)) {
34
+ if (!out.values) out.values = {};
35
+ Object.assign(out.values, value);
36
+ continue;
37
+ }
36
38
  if (isField(key)) {
37
39
  if (!out.values) out.values = {};
38
40
  out.values[key] = value;
@@ -1 +1 @@
1
- {"version":3,"file":"features/whereMapper/WhereMapper.js","sources":["../../../src/features/whereMapper/WhereMapper.ts"],"sourcesContent":["/**\n * Used to map a model with custom schema with fields in a root to values object.\n * eg. File Manager File model has \"title\" and \"tags\" fields in the root, but they should be\n * mapped to \"values.title\" and \"values.tags\" when creating the entry.\n */\nimport { GenericRecord } from \"@webiny/api/types.js\";\nimport { CmsEntryListWhere } from \"~/types/types.js\";\nimport { CmsWhereMapper, ICmsWhereMapperParams } from \"./abstractions.js\";\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (!value || typeof value !== \"object\") {\n return false;\n } else if (Array.isArray(value)) {\n return false;\n }\n return true;\n};\n\nconst isLogicalKey = (key: string): key is \"AND\" | \"OR\" => {\n return key === \"AND\" || key === \"OR\";\n};\n\ninterface IMapNodeWhereParams {\n input: GenericRecord;\n isField: (key: string) => boolean;\n}\n\nclass WhereMapperImpl implements CmsWhereMapper.Interface {\n map<T extends GenericRecord>(params: ICmsWhereMapperParams<T>): CmsEntryListWhere | undefined {\n const { fields: modelFields, input } = params;\n if (!input) {\n return undefined;\n }\n\n const fields = modelFields.map(field => {\n return field.fieldId;\n });\n\n const isField = (key: string): boolean => {\n const field = key.split(\"_\")[0];\n return fields.includes(field);\n };\n\n return this.mapWhere({\n input,\n isField\n });\n }\n\n private mapWhere(params: IMapNodeWhereParams) {\n const { input, isField } = params;\n const out: CmsEntryListWhere = {};\n\n const keys = Object.keys(input) as (keyof typeof out)[];\n if (keys.length === 0) {\n return out;\n }\n\n for (const key of keys) {\n const value = input[key];\n\n if (isLogicalKey(key)) {\n if (Array.isArray(value)) {\n out[key] = value.filter(isPlainObject).map(child => {\n return this.mapWhere({\n input: child,\n isField\n });\n });\n }\n continue;\n } else if (isField(key)) {\n if (!out.values) {\n out.values = {};\n }\n out.values[key] = value;\n continue;\n }\n\n out[key] = value;\n }\n\n return out;\n }\n}\n\nexport const WhereMapper = CmsWhereMapper.createImplementation({\n implementation: WhereMapperImpl,\n dependencies: []\n});\n"],"names":["isPlainObject","value","Array","isLogicalKey","key","WhereMapperImpl","params","modelFields","input","fields","field","isField","out","keys","Object","child","WhereMapper","CmsWhereMapper"],"mappings":";AASA,MAAMA,gBAAgB,CAACC;IACnB,IAAI,CAACA,SAAS,AAAiB,YAAjB,OAAOA,OACjB,OAAO;IACJ,IAAIC,MAAM,OAAO,CAACD,QACrB,OAAO;IAEX,OAAO;AACX;AAEA,MAAME,eAAe,CAACC,MACXA,AAAQ,UAARA,OAAiBA,AAAQ,SAARA;AAQ5B,MAAMC;IACF,IAA6BC,MAAgC,EAAiC;QAC1F,MAAM,EAAE,QAAQC,WAAW,EAAEC,KAAK,EAAE,GAAGF;QACvC,IAAI,CAACE,OACD;QAGJ,MAAMC,SAASF,YAAY,GAAG,CAACG,CAAAA,QACpBA,MAAM,OAAO;QAGxB,MAAMC,UAAU,CAACP;YACb,MAAMM,QAAQN,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;YAC/B,OAAOK,OAAO,QAAQ,CAACC;QAC3B;QAEA,OAAO,IAAI,CAAC,QAAQ,CAAC;YACjBF;YACAG;QACJ;IACJ;IAEQ,SAASL,MAA2B,EAAE;QAC1C,MAAM,EAAEE,KAAK,EAAEG,OAAO,EAAE,GAAGL;QAC3B,MAAMM,MAAyB,CAAC;QAEhC,MAAMC,OAAOC,OAAO,IAAI,CAACN;QACzB,IAAIK,AAAgB,MAAhBA,KAAK,MAAM,EACX,OAAOD;QAGX,KAAK,MAAMR,OAAOS,KAAM;YACpB,MAAMZ,QAAQO,KAAK,CAACJ,IAAI;YAExB,IAAID,aAAaC,MAAM;gBACnB,IAAIF,MAAM,OAAO,CAACD,QACdW,GAAG,CAACR,IAAI,GAAGH,MAAM,MAAM,CAACD,eAAe,GAAG,CAACe,CAAAA,QAChC,IAAI,CAAC,QAAQ,CAAC;wBACjB,OAAOA;wBACPJ;oBACJ;gBAGR;YACJ;YAAO,IAAIA,QAAQP,MAAM;gBACrB,IAAI,CAACQ,IAAI,MAAM,EACXA,IAAI,MAAM,GAAG,CAAC;gBAElBA,IAAI,MAAM,CAACR,IAAI,GAAGH;gBAClB;YACJ;YAEAW,GAAG,CAACR,IAAI,GAAGH;QACf;QAEA,OAAOW;IACX;AACJ;AAEO,MAAMI,cAAcC,eAAe,oBAAoB,CAAC;IAC3D,gBAAgBZ;IAChB,cAAc,EAAE;AACpB"}
1
+ {"version":3,"file":"features/whereMapper/WhereMapper.js","sources":["../../../src/features/whereMapper/WhereMapper.ts"],"sourcesContent":["/**\n * Used to map a model with custom schema with fields in a root to values object.\n * eg. File Manager File model has \"title\" and \"tags\" fields in the root, but they should be\n * mapped to \"values.title\" and \"values.tags\" when creating the entry.\n */\nimport { GenericRecord } from \"@webiny/api/types.js\";\nimport { CmsEntryListWhere } from \"~/types/types.js\";\nimport { CmsWhereMapper, ICmsWhereMapperParams } from \"./abstractions.js\";\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (!value || typeof value !== \"object\") {\n return false;\n } else if (Array.isArray(value)) {\n return false;\n }\n return true;\n};\n\nconst isLogicalKey = (key: string): key is \"AND\" | \"OR\" => {\n return key === \"AND\" || key === \"OR\";\n};\n\ninterface IMapNodeWhereParams {\n input: GenericRecord;\n isField: (key: string) => boolean;\n}\n\nclass WhereMapperImpl implements CmsWhereMapper.Interface {\n map<T extends GenericRecord>(params: ICmsWhereMapperParams<T>): CmsEntryListWhere | undefined {\n const { fields: modelFields, input } = params;\n if (!input) {\n return undefined;\n }\n\n /*\n * Longest fieldId first, so a key is attributed to the longest field it could belong to.\n * Taking the segment before the first `_` misreads any fieldId that contains one:\n * `on_sale_contains` resolves to a field named `on`, which does not exist, so the filter\n * silently stays at the top level and the CMS rejects it. Longest-first also keeps a model\n * with both `price` and `price_range` from being mis-routed.\n */\n const fields = modelFields.map(field => field.fieldId).sort((a, b) => b.length - a.length);\n\n const isField = (key: string): boolean => {\n return fields.some(fieldId => key === fieldId || key.startsWith(`${fieldId}_`));\n };\n\n return this.mapWhere({\n input,\n isField\n });\n }\n\n private mapWhere(params: IMapNodeWhereParams) {\n const { input, isField } = params;\n const out: CmsEntryListWhere = {};\n\n const keys = Object.keys(input) as (keyof typeof out)[];\n if (keys.length === 0) {\n return out;\n }\n\n for (const key of keys) {\n const value = input[key];\n\n if (isLogicalKey(key)) {\n if (Array.isArray(value)) {\n out[key] = value.filter(isPlainObject).map(child => {\n return this.mapWhere({\n input: child,\n isField\n });\n });\n }\n continue;\n } else if (key === \"values\" && isPlainObject(value)) {\n /*\n * A caller that already nested its model fields is taken at its word. Merged rather\n * than assigned, so an explicit `values` object and flat field keys can coexist:\n * assigning would drop whichever of the two arrived first.\n */\n if (!out.values) {\n out.values = {};\n }\n Object.assign(out.values, value);\n continue;\n } else if (isField(key)) {\n if (!out.values) {\n out.values = {};\n }\n out.values[key] = value;\n continue;\n }\n\n out[key] = value;\n }\n\n return out;\n }\n}\n\nexport const WhereMapper = CmsWhereMapper.createImplementation({\n implementation: WhereMapperImpl,\n dependencies: []\n});\n"],"names":["isPlainObject","value","Array","isLogicalKey","key","WhereMapperImpl","params","modelFields","input","fields","field","a","b","isField","fieldId","out","keys","Object","child","WhereMapper","CmsWhereMapper"],"mappings":";AASA,MAAMA,gBAAgB,CAACC;IACnB,IAAI,CAACA,SAAS,AAAiB,YAAjB,OAAOA,OACjB,OAAO;IACJ,IAAIC,MAAM,OAAO,CAACD,QACrB,OAAO;IAEX,OAAO;AACX;AAEA,MAAME,eAAe,CAACC,MACXA,AAAQ,UAARA,OAAiBA,AAAQ,SAARA;AAQ5B,MAAMC;IACF,IAA6BC,MAAgC,EAAiC;QAC1F,MAAM,EAAE,QAAQC,WAAW,EAAEC,KAAK,EAAE,GAAGF;QACvC,IAAI,CAACE,OACD;QAUJ,MAAMC,SAASF,YAAY,GAAG,CAACG,CAAAA,QAASA,MAAM,OAAO,EAAE,IAAI,CAAC,CAACC,GAAGC,IAAMA,EAAE,MAAM,GAAGD,EAAE,MAAM;QAEzF,MAAME,UAAU,CAACT,MACNK,OAAO,IAAI,CAACK,CAAAA,UAAWV,QAAQU,WAAWV,IAAI,UAAU,CAAC,GAAGU,QAAQ,CAAC,CAAC;QAGjF,OAAO,IAAI,CAAC,QAAQ,CAAC;YACjBN;YACAK;QACJ;IACJ;IAEQ,SAASP,MAA2B,EAAE;QAC1C,MAAM,EAAEE,KAAK,EAAEK,OAAO,EAAE,GAAGP;QAC3B,MAAMS,MAAyB,CAAC;QAEhC,MAAMC,OAAOC,OAAO,IAAI,CAACT;QACzB,IAAIQ,AAAgB,MAAhBA,KAAK,MAAM,EACX,OAAOD;QAGX,KAAK,MAAMX,OAAOY,KAAM;YACpB,MAAMf,QAAQO,KAAK,CAACJ,IAAI;YAExB,IAAID,aAAaC,MAAM;gBACnB,IAAIF,MAAM,OAAO,CAACD,QACdc,GAAG,CAACX,IAAI,GAAGH,MAAM,MAAM,CAACD,eAAe,GAAG,CAACkB,CAAAA,QAChC,IAAI,CAAC,QAAQ,CAAC;wBACjB,OAAOA;wBACPL;oBACJ;gBAGR;YACJ;YAAO,IAAIT,AAAQ,aAARA,OAAoBJ,cAAcC,QAAQ;gBAMjD,IAAI,CAACc,IAAI,MAAM,EACXA,IAAI,MAAM,GAAG,CAAC;gBAElBE,OAAO,MAAM,CAACF,IAAI,MAAM,EAAEd;gBAC1B;YACJ;YAAO,IAAIY,QAAQT,MAAM;gBACrB,IAAI,CAACW,IAAI,MAAM,EACXA,IAAI,MAAM,GAAG,CAAC;gBAElBA,IAAI,MAAM,CAACX,IAAI,GAAGH;gBAClB;YACJ;YAEAc,GAAG,CAACX,IAAI,GAAGH;QACf;QAEA,OAAOc;IACX;AACJ;AAEO,MAAMI,cAAcC,eAAe,oBAAoB,CAAC;IAC3D,gBAAgBf;IAChB,cAAc,EAAE;AACpB"}
@@ -1,11 +1,12 @@
1
- import { buildFieldsSelection, getErrorMessage, getModel } from "./helpers.js";
1
+ import { buildFieldsSelection, expandFieldWildcards, getErrorMessage, getModel } from "./helpers.js";
2
2
  import { CmsSchemaExecutor } from "../../CmsSchemaExecutor.js";
3
3
  const createGetEntryResolver = ()=>async ({ args, context })=>{
4
4
  const { modelId, where, fields, preview = false } = args;
5
5
  try {
6
6
  const model = await getModel(context, modelId);
7
7
  const apiType = preview ? "preview" : "read";
8
- const fieldsSelection = buildFieldsSelection(fields);
8
+ const expandedFields = expandFieldWildcards(fields, model, context);
9
+ const fieldsSelection = buildFieldsSelection(expandedFields);
9
10
  const query = `
10
11
  query Get${model.singularApiName}($where: ${model.singularApiName}GetWhereInput!) {
11
12
  get${model.singularApiName}(where: $where) {
@@ -1 +1 @@
1
- {"version":3,"file":"graphql/schema/cms/getEntryResolver.js","sources":["../../../../src/graphql/schema/cms/getEntryResolver.ts"],"sourcesContent":["import type { CmsContext, ApiEndpoint } from \"~/types/index.js\";\nimport type { ExecutionResult } from \"graphql\";\nimport { getModel, getErrorMessage, buildFieldsSelection } from \"./helpers.js\";\nimport { CmsSchemaExecutor } from \"~/graphql/CmsSchemaExecutor.js\";\n\nexport interface GetEntryArgs {\n modelId: string;\n where: Record<string, unknown>;\n fields: string[];\n preview?: boolean;\n}\n\nexport const createGetEntryResolver = () => {\n return async ({ args, context }: { args: GetEntryArgs; context: CmsContext }) => {\n const { modelId, where, fields, preview = false } = args;\n\n try {\n const model = await getModel(context, modelId);\n\n // Determine which API to use based on the preview flag.\n // preview=true -> preview API, preview=false -> read API\n const apiType: ApiEndpoint = preview ? \"preview\" : \"read\";\n\n const fieldsSelection = buildFieldsSelection(fields);\n\n const query = /* GraphQL */ `\n query Get${model.singularApiName}($where: ${model.singularApiName}GetWhereInput!) {\n get${model.singularApiName}(where: $where) {\n data {\n ${fieldsSelection}\n }\n error {\n message\n code\n data\n }\n }\n }\n `;\n\n const result = (await context.container\n .resolve(CmsSchemaExecutor)\n .execute(apiType, { query, variables: { where } })) as ExecutionResult;\n\n if (result.errors && result.errors.length > 0) {\n return {\n data: null,\n error: {\n message: result.errors.map(e => e.message).join(\"; \"),\n code: \"GET_ENTRY_ERROR\"\n }\n };\n }\n\n const operationName = `get${model.singularApiName}`;\n return result.data?.[operationName] || { data: null, error: null };\n } catch (error) {\n return {\n data: null,\n error: {\n message: getErrorMessage(error, \"Failed to get entry\"),\n code: \"GET_ENTRY_ERROR\"\n }\n };\n }\n };\n};\n"],"names":["createGetEntryResolver","args","context","modelId","where","fields","preview","model","getModel","apiType","fieldsSelection","buildFieldsSelection","query","result","CmsSchemaExecutor","e","operationName","error","getErrorMessage"],"mappings":";;AAYO,MAAMA,yBAAyB,IAC3B,OAAO,EAAEC,IAAI,EAAEC,OAAO,EAA+C;QACxE,MAAM,EAAEC,OAAO,EAAEC,KAAK,EAAEC,MAAM,EAAEC,UAAU,KAAK,EAAE,GAAGL;QAEpD,IAAI;YACA,MAAMM,QAAQ,MAAMC,SAASN,SAASC;YAItC,MAAMM,UAAuBH,UAAU,YAAY;YAEnD,MAAMI,kBAAkBC,qBAAqBN;YAE7C,MAAMO,QAAsB,CAAC;yBAChB,EAAEL,MAAM,eAAe,CAAC,SAAS,EAAEA,MAAM,eAAe,CAAC;uBAC3D,EAAEA,MAAM,eAAe,CAAC;;4BAEnB,EAAEG,gBAAgB;;;;;;;;;YASlC,CAAC;YAED,MAAMG,SAAU,MAAMX,QAAQ,SAAS,CAClC,OAAO,CAACY,mBACR,OAAO,CAACL,SAAS;gBAAEG;gBAAO,WAAW;oBAAER;gBAAM;YAAE;YAEpD,IAAIS,OAAO,MAAM,IAAIA,OAAO,MAAM,CAAC,MAAM,GAAG,GACxC,OAAO;gBACH,MAAM;gBACN,OAAO;oBACH,SAASA,OAAO,MAAM,CAAC,GAAG,CAACE,CAAAA,IAAKA,EAAE,OAAO,EAAE,IAAI,CAAC;oBAChD,MAAM;gBACV;YACJ;YAGJ,MAAMC,gBAAgB,CAAC,GAAG,EAAET,MAAM,eAAe,EAAE;YACnD,OAAOM,OAAO,IAAI,EAAE,CAACG,cAAc,IAAI;gBAAE,MAAM;gBAAM,OAAO;YAAK;QACrE,EAAE,OAAOC,OAAO;YACZ,OAAO;gBACH,MAAM;gBACN,OAAO;oBACH,SAASC,gBAAgBD,OAAO;oBAChC,MAAM;gBACV;YACJ;QACJ;IACJ"}
1
+ {"version":3,"file":"graphql/schema/cms/getEntryResolver.js","sources":["../../../../src/graphql/schema/cms/getEntryResolver.ts"],"sourcesContent":["import type { CmsContext, ApiEndpoint } from \"~/types/index.js\";\nimport type { ExecutionResult } from \"graphql\";\nimport {\n getModel,\n getErrorMessage,\n buildFieldsSelection,\n expandFieldWildcards\n} from \"./helpers.js\";\nimport { CmsSchemaExecutor } from \"~/graphql/CmsSchemaExecutor.js\";\n\nexport interface GetEntryArgs {\n modelId: string;\n where: Record<string, unknown>;\n fields: string[];\n preview?: boolean;\n}\n\nexport const createGetEntryResolver = () => {\n return async ({ args, context }: { args: GetEntryArgs; context: CmsContext }) => {\n const { modelId, where, fields, preview = false } = args;\n\n try {\n const model = await getModel(context, modelId);\n\n // Determine which API to use based on the preview flag.\n // preview=true -> preview API, preview=false -> read API\n const apiType: ApiEndpoint = preview ? \"preview\" : \"read\";\n\n const expandedFields = expandFieldWildcards(fields, model, context);\n const fieldsSelection = buildFieldsSelection(expandedFields);\n\n const query = /* GraphQL */ `\n query Get${model.singularApiName}($where: ${model.singularApiName}GetWhereInput!) {\n get${model.singularApiName}(where: $where) {\n data {\n ${fieldsSelection}\n }\n error {\n message\n code\n data\n }\n }\n }\n `;\n\n const result = (await context.container\n .resolve(CmsSchemaExecutor)\n .execute(apiType, { query, variables: { where } })) as ExecutionResult;\n\n if (result.errors && result.errors.length > 0) {\n return {\n data: null,\n error: {\n message: result.errors.map(e => e.message).join(\"; \"),\n code: \"GET_ENTRY_ERROR\"\n }\n };\n }\n\n const operationName = `get${model.singularApiName}`;\n return result.data?.[operationName] || { data: null, error: null };\n } catch (error) {\n return {\n data: null,\n error: {\n message: getErrorMessage(error, \"Failed to get entry\"),\n code: \"GET_ENTRY_ERROR\"\n }\n };\n }\n };\n};\n"],"names":["createGetEntryResolver","args","context","modelId","where","fields","preview","model","getModel","apiType","expandedFields","expandFieldWildcards","fieldsSelection","buildFieldsSelection","query","result","CmsSchemaExecutor","e","operationName","error","getErrorMessage"],"mappings":";;AAiBO,MAAMA,yBAAyB,IAC3B,OAAO,EAAEC,IAAI,EAAEC,OAAO,EAA+C;QACxE,MAAM,EAAEC,OAAO,EAAEC,KAAK,EAAEC,MAAM,EAAEC,UAAU,KAAK,EAAE,GAAGL;QAEpD,IAAI;YACA,MAAMM,QAAQ,MAAMC,SAASN,SAASC;YAItC,MAAMM,UAAuBH,UAAU,YAAY;YAEnD,MAAMI,iBAAiBC,qBAAqBN,QAAQE,OAAOL;YAC3D,MAAMU,kBAAkBC,qBAAqBH;YAE7C,MAAMI,QAAsB,CAAC;yBAChB,EAAEP,MAAM,eAAe,CAAC,SAAS,EAAEA,MAAM,eAAe,CAAC;uBAC3D,EAAEA,MAAM,eAAe,CAAC;;4BAEnB,EAAEK,gBAAgB;;;;;;;;;YASlC,CAAC;YAED,MAAMG,SAAU,MAAMb,QAAQ,SAAS,CAClC,OAAO,CAACc,mBACR,OAAO,CAACP,SAAS;gBAAEK;gBAAO,WAAW;oBAAEV;gBAAM;YAAE;YAEpD,IAAIW,OAAO,MAAM,IAAIA,OAAO,MAAM,CAAC,MAAM,GAAG,GACxC,OAAO;gBACH,MAAM;gBACN,OAAO;oBACH,SAASA,OAAO,MAAM,CAAC,GAAG,CAACE,CAAAA,IAAKA,EAAE,OAAO,EAAE,IAAI,CAAC;oBAChD,MAAM;gBACV;YACJ;YAGJ,MAAMC,gBAAgB,CAAC,GAAG,EAAEX,MAAM,eAAe,EAAE;YACnD,OAAOQ,OAAO,IAAI,EAAE,CAACG,cAAc,IAAI;gBAAE,MAAM;gBAAM,OAAO;YAAK;QACrE,EAAE,OAAOC,OAAO;YACZ,OAAO;gBACH,MAAM;gBACN,OAAO;oBACH,SAASC,gBAAgBD,OAAO;oBAChC,MAAM;gBACV;YACJ;QACJ;IACJ"}
@@ -0,0 +1,35 @@
1
+ import type { CmsContext } from "../../../types/index.js";
2
+ export interface GetModelArgs {
3
+ modelId: string;
4
+ }
5
+ export declare const createGetModelResolver: () => ({ args, context }: {
6
+ args: GetModelArgs;
7
+ context: CmsContext;
8
+ }) => Promise<{
9
+ data: {
10
+ name: string;
11
+ modelId: string;
12
+ singularApiName: string;
13
+ pluralApiName: string;
14
+ description: string | null;
15
+ titleFieldId: string;
16
+ descriptionFieldId: string | null | undefined;
17
+ imageFieldId: string | null | undefined;
18
+ fields: import("~/types/index.js").CmsModelField[];
19
+ layout: import("~/types/index.js").CmsModelLayout;
20
+ tags: string[] | undefined;
21
+ settings: import("../../../features/modelBuilder/abstractions.js").IModelSettings | null | undefined;
22
+ metadata: {
23
+ valuesSelection: string;
24
+ componentMap: Record<string, string>;
25
+ refModels: Record<string, import("~/features/contentModel/RefModelsGenerator/abstractions.js").RefModelMetadata>;
26
+ };
27
+ };
28
+ error: null;
29
+ } | {
30
+ data: null;
31
+ error: {
32
+ message: string;
33
+ code: string;
34
+ };
35
+ }>;
@@ -0,0 +1,49 @@
1
+ import { getErrorMessage, getModel } from "./helpers.js";
2
+ import { ComponentMapGenerator } from "../../../features/contentModel/ComponentMapGenerator/abstractions.js";
3
+ import { ValuesSelectionGenerator } from "../../../features/contentModel/ValuesSelectionGenerator/abstractions.js";
4
+ import { RefModelsGenerator } from "../../../features/contentModel/RefModelsGenerator/abstractions.js";
5
+ const createGetModelResolver = ()=>async ({ args, context })=>{
6
+ const { modelId } = args;
7
+ try {
8
+ const model = await getModel(context, modelId);
9
+ const componentMapGenerator = context.container.resolve(ComponentMapGenerator);
10
+ const valuesSelectionGenerator = context.container.resolve(ValuesSelectionGenerator);
11
+ const refModelsGenerator = context.container.resolve(RefModelsGenerator);
12
+ const componentMap = componentMapGenerator.generate(model);
13
+ const valuesSelection = valuesSelectionGenerator.generate(model);
14
+ const refModels = await refModelsGenerator.generate(model);
15
+ return {
16
+ data: {
17
+ name: model.name,
18
+ modelId: model.modelId,
19
+ singularApiName: model.singularApiName,
20
+ pluralApiName: model.pluralApiName,
21
+ description: model.description,
22
+ titleFieldId: model.titleFieldId,
23
+ descriptionFieldId: model.descriptionFieldId,
24
+ imageFieldId: model.imageFieldId,
25
+ fields: model.fields,
26
+ layout: model.layout,
27
+ tags: model.tags,
28
+ settings: model.settings,
29
+ metadata: {
30
+ valuesSelection,
31
+ componentMap,
32
+ refModels
33
+ }
34
+ },
35
+ error: null
36
+ };
37
+ } catch (error) {
38
+ return {
39
+ data: null,
40
+ error: {
41
+ message: getErrorMessage(error, "Failed to get model"),
42
+ code: "GET_MODEL_ERROR"
43
+ }
44
+ };
45
+ }
46
+ };
47
+ export { createGetModelResolver };
48
+
49
+ //# sourceMappingURL=getModelResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql/schema/cms/getModelResolver.js","sources":["../../../../src/graphql/schema/cms/getModelResolver.ts"],"sourcesContent":["import type { CmsContext } from \"~/types/index.js\";\nimport { getModel, getErrorMessage } from \"./helpers.js\";\nimport { ComponentMapGenerator } from \"~/features/contentModel/ComponentMapGenerator/abstractions.js\";\nimport { ValuesSelectionGenerator } from \"~/features/contentModel/ValuesSelectionGenerator/abstractions.js\";\nimport { RefModelsGenerator } from \"~/features/contentModel/RefModelsGenerator/abstractions.js\";\n\nexport interface GetModelArgs {\n modelId: string;\n}\n\nexport const createGetModelResolver = () => {\n return async ({ args, context }: { args: GetModelArgs; context: CmsContext }) => {\n const { modelId } = args;\n\n try {\n const model = await getModel(context, modelId);\n const componentMapGenerator = context.container.resolve(ComponentMapGenerator);\n const valuesSelectionGenerator = context.container.resolve(ValuesSelectionGenerator);\n const refModelsGenerator = context.container.resolve(RefModelsGenerator);\n\n const componentMap = componentMapGenerator.generate(model);\n const valuesSelection = valuesSelectionGenerator.generate(model);\n const refModels = await refModelsGenerator.generate(model);\n\n return {\n data: {\n name: model.name,\n modelId: model.modelId,\n singularApiName: model.singularApiName,\n pluralApiName: model.pluralApiName,\n description: model.description,\n titleFieldId: model.titleFieldId,\n descriptionFieldId: model.descriptionFieldId,\n imageFieldId: model.imageFieldId,\n fields: model.fields,\n layout: model.layout,\n tags: model.tags,\n settings: model.settings,\n metadata: {\n valuesSelection,\n componentMap,\n refModels\n }\n },\n error: null\n };\n } catch (error) {\n return {\n data: null,\n error: {\n message: getErrorMessage(error, \"Failed to get model\"),\n code: \"GET_MODEL_ERROR\"\n }\n };\n }\n };\n};\n"],"names":["createGetModelResolver","args","context","modelId","model","getModel","componentMapGenerator","ComponentMapGenerator","valuesSelectionGenerator","ValuesSelectionGenerator","refModelsGenerator","RefModelsGenerator","componentMap","valuesSelection","refModels","error","getErrorMessage"],"mappings":";;;;AAUO,MAAMA,yBAAyB,IAC3B,OAAO,EAAEC,IAAI,EAAEC,OAAO,EAA+C;QACxE,MAAM,EAAEC,OAAO,EAAE,GAAGF;QAEpB,IAAI;YACA,MAAMG,QAAQ,MAAMC,SAASH,SAASC;YACtC,MAAMG,wBAAwBJ,QAAQ,SAAS,CAAC,OAAO,CAACK;YACxD,MAAMC,2BAA2BN,QAAQ,SAAS,CAAC,OAAO,CAACO;YAC3D,MAAMC,qBAAqBR,QAAQ,SAAS,CAAC,OAAO,CAACS;YAErD,MAAMC,eAAeN,sBAAsB,QAAQ,CAACF;YACpD,MAAMS,kBAAkBL,yBAAyB,QAAQ,CAACJ;YAC1D,MAAMU,YAAY,MAAMJ,mBAAmB,QAAQ,CAACN;YAEpD,OAAO;gBACH,MAAM;oBACF,MAAMA,MAAM,IAAI;oBAChB,SAASA,MAAM,OAAO;oBACtB,iBAAiBA,MAAM,eAAe;oBACtC,eAAeA,MAAM,aAAa;oBAClC,aAAaA,MAAM,WAAW;oBAC9B,cAAcA,MAAM,YAAY;oBAChC,oBAAoBA,MAAM,kBAAkB;oBAC5C,cAAcA,MAAM,YAAY;oBAChC,QAAQA,MAAM,MAAM;oBACpB,QAAQA,MAAM,MAAM;oBACpB,MAAMA,MAAM,IAAI;oBAChB,UAAUA,MAAM,QAAQ;oBACxB,UAAU;wBACNS;wBACAD;wBACAE;oBACJ;gBACJ;gBACA,OAAO;YACX;QACJ,EAAE,OAAOC,OAAO;YACZ,OAAO;gBACH,MAAM;gBACN,OAAO;oBACH,SAASC,gBAAgBD,OAAO;oBAChC,MAAM;gBACV;YACJ;QACJ;IACJ"}