@remkoj/optimizely-cms-react 6.0.0-pre8 → 6.0.0-rc.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 (56) hide show
  1. package/LICENSE +12 -12
  2. package/README.md +3 -4
  3. package/dist/components/cms-content/get-content-type.js +8 -17
  4. package/dist/components/cms-content/get-content-type.js.map +1 -1
  5. package/dist/components/cms-content/get-content.js +46 -50
  6. package/dist/components/cms-content/get-content.js.map +1 -1
  7. package/dist/components/cms-content/resolve-component.js +8 -9
  8. package/dist/components/cms-content/resolve-component.js.map +1 -1
  9. package/dist/components/cms-content/rsc.d.ts +1 -1
  10. package/dist/components/cms-content/rsc.js +9 -7
  11. package/dist/components/cms-content/rsc.js.map +1 -1
  12. package/dist/components/cms-content/types.d.ts +46 -2
  13. package/dist/components/cms-content-area/index.js +3 -3
  14. package/dist/components/cms-content-area/index.js.map +1 -1
  15. package/dist/components/cms-content-area/types.d.ts +51 -10
  16. package/dist/components/cms-editable/index.d.ts +86 -17
  17. package/dist/components/cms-editable/index.js +20 -10
  18. package/dist/components/cms-editable/index.js.map +1 -1
  19. package/dist/components/rich-text/index.d.ts +2 -1
  20. package/dist/components/rich-text/index.js +6 -3
  21. package/dist/components/rich-text/index.js.map +1 -1
  22. package/dist/components/rsc-components.d.ts +154 -5
  23. package/dist/components/rsc-components.js +153 -5
  24. package/dist/components/rsc-components.js.map +1 -1
  25. package/dist/components/rsc.d.ts +2 -0
  26. package/dist/components/rsc.js +1 -0
  27. package/dist/components/rsc.js.map +1 -1
  28. package/dist/components/visual-builder/functions.js +10 -17
  29. package/dist/components/visual-builder/functions.js.map +1 -1
  30. package/dist/components/visual-builder/index.d.ts +3 -1
  31. package/dist/components/visual-builder/index.js +19 -16
  32. package/dist/components/visual-builder/index.js.map +1 -1
  33. package/dist/components/visual-builder/types.d.ts +8 -2
  34. package/dist/context/client.js +5 -2
  35. package/dist/context/client.js.map +1 -1
  36. package/dist/context/rsc.d.ts +1 -1
  37. package/dist/context/rsc.js +11 -42
  38. package/dist/context/rsc.js.map +1 -1
  39. package/dist/context/shared.js +2 -1
  40. package/dist/context/shared.js.map +1 -1
  41. package/dist/context/types.d.ts +3 -11
  42. package/dist/factory/default.d.ts +20 -3
  43. package/dist/factory/default.js +41 -27
  44. package/dist/factory/default.js.map +1 -1
  45. package/dist/factory/types.d.ts +24 -4
  46. package/dist/factory/undef.d.ts +7 -5
  47. package/dist/factory/undef.js +10 -4
  48. package/dist/factory/undef.js.map +1 -1
  49. package/dist/rsc.d.ts +24 -0
  50. package/dist/rsc.js +24 -0
  51. package/dist/rsc.js.map +1 -1
  52. package/dist/types.d.ts +37 -6
  53. package/dist/utilities.d.ts +56 -6
  54. package/dist/utilities.js +112 -14
  55. package/dist/utilities.js.map +1 -1
  56. package/package.json +19 -15
@@ -15,6 +15,15 @@ export class DefaultComponentFactory {
15
15
  */
16
16
  constructor(initialComponents) {
17
17
  this.registry = new Map();
18
+ /**
19
+ * A list of interfaces to ignore when resolving components. Adjust this
20
+ * list if you're experiencing issues with resolving components due to
21
+ * contracts. Values **must be** provided lowercase and without leading
22
+ * underscore. For example `_Item` must be provided as `item`.
23
+ *
24
+ * The default value includes the common ones for SaaS CMS.
25
+ */
26
+ this.ignoredContracts = ['item', 'assetitem', 'imageitem', 'content'];
18
27
  // Resolve debug mode
19
28
  try {
20
29
  this.dbg = process.env.OPTIMIZELY_DEBUG == '1';
@@ -26,31 +35,27 @@ export class DefaultComponentFactory {
26
35
  if (initialComponents)
27
36
  this.registerAll(initialComponents);
28
37
  }
29
- register(type, component, useSuspense = false, loader) {
30
- const registryKey = processComponentTypeHandle(type);
38
+ register(type, component, useSuspense = false, loader, variant = 'default') {
39
+ const registryKey = this.processComponentTypeHandle(type, variant);
31
40
  if (this.dbg)
32
41
  console.log(`➕ [DefaultComponentFactory] Registering ${registryKey}`);
33
- this.registry.set(registryKey, { type, component, useSuspense, loader });
42
+ this.registry.set(registryKey, { type: registryKey, component, useSuspense, loader, variant });
34
43
  }
35
44
  registerAll(components) {
36
- components.forEach((c) => {
37
- const registryKey = processComponentTypeHandle(c.type);
38
- if (this.dbg)
39
- console.log(`➕ [DefaultComponentFactory] Registering ${registryKey}`);
40
- this.registry.set(registryKey, c);
41
- });
45
+ components.forEach(c => this.register(c.type, c.component, c.useSuspense, c.loader, c.variant));
42
46
  }
43
- has(type) {
44
- const registryKey = processComponentTypeHandle(type);
45
- //if (this.dbg) console.log(`🔎 [DefaultComponentFactory] Checking for ${ registryKey }`)
47
+ has(type, variant = 'default') {
48
+ const registryKey = this.processComponentTypeHandle(type, variant);
49
+ if (this.dbg)
50
+ console.log(`🔎 [DefaultComponentFactory] Checking for ${registryKey} - ${this.registry.has(registryKey) ? 'YES' : 'NO'}`);
46
51
  return this.registry.has(registryKey);
47
52
  }
48
- resolve(type) {
49
- const registryKey = processComponentTypeHandle(type);
53
+ resolve(type, variant = 'default') {
54
+ const registryKey = this.processComponentTypeHandle(type, variant);
50
55
  const entry = this.registry.get(registryKey);
51
56
  if (!entry) {
52
57
  if (this.dbg)
53
- console.warn(`⚡ [DefaultComponentFactory] Unable to resolve ${registryKey}`);
58
+ console.warn(`❌ [DefaultComponentFactory] Unable to resolve ${registryKey}, this will prevent the item from rendering`);
54
59
  return undefined; // The key is not registered in the factory
55
60
  }
56
61
  if (entry.useSuspense != true)
@@ -69,23 +74,32 @@ export class DefaultComponentFactory {
69
74
  });
70
75
  }
71
76
  remove(type) {
72
- const registryKey = processComponentTypeHandle(type);
77
+ const registryKey = this.processComponentTypeHandle(type);
73
78
  if (this.dbg)
74
79
  console.log(`🔎 [DefaultComponentFactory] Removing ${registryKey}`);
75
80
  if (!this.registry.has(registryKey))
76
81
  return true;
77
82
  return this.registry.delete(registryKey);
78
83
  }
79
- }
80
- function processComponentTypeHandle(handle) {
81
- if (typeof handle == 'string')
82
- return handle == '' ? EmptyComponentHandle : handle;
83
- if (Array.isArray(handle) && handle.every((s) => typeof s == 'string'))
84
- return handle
85
- .map((s) => (s.startsWith('_') ? s.substring(1) : s)) // Remove all leading underscores
86
- .filter((s) => s.toLowerCase() != 'content') // Remove the "Content" base type
87
- .map((s) => (s == '' ? EmptyComponentHandle : s)) // Fall back to a fragment
88
- .join(MERGE_SYMBOL); // Types are processed as a string
89
- throw new Error(`Invalid component type handle: ${typeof handle}`);
84
+ /**
85
+ * Process the component variant handle into
86
+ *
87
+ * @param handle
88
+ * @param variant
89
+ * @returns
90
+ */
91
+ processComponentTypeHandle(handle, variant) {
92
+ let handleToProcess = typeof handle === 'string' ? handle.split(MERGE_SYMBOL) : [...handle];
93
+ if (Array.isArray(handleToProcess) && handleToProcess.every((s) => typeof s === 'string')) {
94
+ const offset = (['component', 'page', 'experience'].includes(handleToProcess.at(handleToProcess.length - 3)?.toLowerCase() ?? '') &&
95
+ !['row', 'column', 'section', 'experience', 'media'].includes(handleToProcess.at(handleToProcess.length - 2)?.toLowerCase() ?? '')) ? 1 : 0;
96
+ const typeName = handleToProcess.at(handleToProcess.length - (1 + offset));
97
+ const prefix = handleToProcess.at(handleToProcess.length - (2 + offset)) === 'RichText' ? 'RichText/' : '';
98
+ const actualVariant = offset > 0 ? handleToProcess.at(handleToProcess.length - 1) ?? variant ?? 'default' : variant ?? 'default';
99
+ const newHandle = prefix + typeName + '/' + actualVariant;
100
+ return newHandle;
101
+ }
102
+ throw new Error(`Invalid component type handle: ${typeof handle}`);
103
+ }
90
104
  }
91
105
  //# sourceMappingURL=default.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/factory/default.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/factory/default.tsx"],"names":[],"mappings":"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"}
@@ -25,18 +25,36 @@ export type ComponentTypeDictionaryEntry = {
25
25
  * The component to use as "loading" state by the <Suspense />
26
26
  */
27
27
  loader?: ComponentType;
28
+ /**
29
+ * Used for the loading of a specific variant of the component (for example 'header', 'footer', 'menu')
30
+ */
31
+ variant?: string;
32
+ /**
33
+ * Optional marker to indicate that the component is a Client Side component, which
34
+ * may add attribute filtering in the future.
35
+ */
36
+ isClient?: boolean;
28
37
  };
29
38
  /**
30
39
  * Component Factory
31
40
  */
32
41
  export interface ComponentFactory {
42
+ /**
43
+ * A list of interfaces to ignore when resolving components. Adjust this
44
+ * list if you're experiencing issues with resolving components due to
45
+ * contracts. Values **must be** provided lowercase and without leading
46
+ * underscore. For example `_Item` must be provided as `item`.
47
+ *
48
+ * The default value includes the common ones for SaaS CMS.
49
+ */
50
+ ignoredContracts: string[];
33
51
  /**
34
52
  * Check if the component type has been registered within the factory
35
53
  *
36
54
  * @param type The component type to check for
37
55
  * @returns Whether or not the type exists within the factory
38
56
  */
39
- has(type: ComponentTypeHandle): boolean;
57
+ has(type: ComponentTypeHandle, variant?: string): boolean;
40
58
  /**
41
59
  * Register an individual component. When the component type has already
42
60
  * been registered it will be updated.
@@ -45,8 +63,9 @@ export interface ComponentFactory {
45
63
  * @param component The component to bind to the type
46
64
  * @param useSuspense If set to 'true' the registered component will be wrapped in <Suspense />
47
65
  * @param loader The component to use as "loading" state by the <Suspense />
66
+ * @param variant The specific variant of the component (for example 'header', 'footer', 'menu')
48
67
  */
49
- register(type: ComponentTypeHandle, component: ComponentType, useSuspense?: boolean, loader?: ComponentType): void;
68
+ register(type: ComponentTypeHandle, component: ComponentType, useSuspense?: boolean, loader?: ComponentType, variant?: string): void;
50
69
  /**
51
70
  * Register all components provided through the dictionary. When the
52
71
  * component type has already been registered it will be updated.
@@ -59,17 +78,18 @@ export interface ComponentFactory {
59
78
  * the implemenation supports it.
60
79
  *
61
80
  * @param type The component type to remove
81
+ * @param variant The variant of the component type, will remove all if not specified
62
82
  * @returns `true` If the component was not found or removed, `false`
63
83
  * otherwise
64
84
  */
65
- remove?: (type: ComponentTypeHandle) => boolean;
85
+ remove?: (type: ComponentTypeHandle, variant?: string) => boolean;
66
86
  /**
67
87
  * Resolve a component type
68
88
  *
69
89
  * @param type The type to search the component for
70
90
  * @returns The component that was resolved for the provided type
71
91
  */
72
- resolve(type: ComponentTypeHandle): ComponentType | undefined;
92
+ resolve(type: ComponentTypeHandle, variant?: string): ComponentType | undefined;
73
93
  /**
74
94
  * Retrieve the registered components as a dictionary that can be used to
75
95
  * be imported in a new instance.
@@ -1,9 +1,11 @@
1
- import { ComponentType, ComponentTypeDictionary, ComponentTypeHandle, type ComponentFactory } from "./types.js";
1
+ import { ComponentType, ComponentTypeDictionary, type ComponentFactory } from "./types.js";
2
2
  export declare class UndefinedComponentFactory implements ComponentFactory {
3
- has(type: ComponentTypeHandle): boolean;
4
- register(type: ComponentTypeHandle, componentType: ComponentType): void;
5
- registerAll(components: ComponentTypeDictionary): void;
6
- resolve(type: ComponentTypeHandle): ComponentType | undefined;
3
+ get ignoredContracts(): string[];
4
+ set ignoredContracts(newList: string[]);
5
+ has(): boolean;
6
+ register(): void;
7
+ registerAll(): void;
8
+ resolve(): ComponentType | undefined;
7
9
  extract(): ComponentTypeDictionary;
8
10
  }
9
11
  export default UndefinedComponentFactory;
@@ -1,14 +1,20 @@
1
1
  export class UndefinedComponentFactory {
2
- has(type) {
2
+ get ignoredContracts() {
3
3
  throw new Error("Factory not specified, please specify a factory.");
4
4
  }
5
- register(type, componentType) {
5
+ set ignoredContracts(newList) {
6
6
  throw new Error("Factory not specified, please specify a factory.");
7
7
  }
8
- registerAll(components) {
8
+ has() {
9
9
  throw new Error("Factory not specified, please specify a factory.");
10
10
  }
11
- resolve(type) {
11
+ register() {
12
+ throw new Error("Factory not specified, please specify a factory.");
13
+ }
14
+ registerAll() {
15
+ throw new Error("Factory not specified, please specify a factory.");
16
+ }
17
+ resolve() {
12
18
  throw new Error("Factory not specified, please specify a factory.");
13
19
  }
14
20
  extract() {
@@ -1 +1 @@
1
- {"version":3,"file":"undef.js","sourceRoot":"","sources":["../../src/factory/undef.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,yBAAyB;IAClC,GAAG,CAAC,IAAyB;QACzB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACxE,CAAC;IACD,QAAQ,CAAC,IAAyB,EAAE,aAA4B;QAC5D,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACxE,CAAC;IACD,WAAW,CAAC,UAAmC;QAC3C,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,CAAC,IAAyB;QAC7B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO;QACH,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACxE,CAAC;CACJ;AAED,eAAe,yBAAyB,CAAA"}
1
+ {"version":3,"file":"undef.js","sourceRoot":"","sources":["../../src/factory/undef.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,yBAAyB;IACpC,IAAI,gBAAgB;QAClB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,gBAAgB,CAAC,OAAiB;QACpC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,GAAG;QACD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,QAAQ;QACN,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,WAAW;QACT,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO;QACL,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO;QACL,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;CACF;AAED,eAAe,yBAAyB,CAAA"}
package/dist/rsc.d.ts CHANGED
@@ -6,5 +6,29 @@ export * from './factory/index.js';
6
6
  export * from './context/types.js';
7
7
  export * from './context/rsc.js';
8
8
  export * from './components/rsc.js';
9
+ /**
10
+ * RSC component exports, including `CmsEditable`, `CmsContent`,
11
+ * `CmsContentArea` and their prop types.
12
+ *
13
+ * `CmsContent` usage:
14
+ *
15
+ * ```tsx
16
+ * import { CmsContent } from '@remkoj/optimizely-cms-react/rsc'
17
+ *
18
+ * <CmsContent contentLink={{ key: content._metadata.key, locale: 'en' }} />
19
+ * ```
20
+ *
21
+ * `CmsContentArea` usage:
22
+ *
23
+ * ```tsx
24
+ * import { CmsContentArea } from '@remkoj/optimizely-cms-react/rsc'
25
+ *
26
+ * <CmsContentArea
27
+ * items={content.MainContentArea}
28
+ * fieldName="MainContentArea"
29
+ * as="section"
30
+ * />
31
+ * ```
32
+ */
9
33
  export * from './components/rsc-components.js';
10
34
  export * from './rsc-utilities.js';
package/dist/rsc.js CHANGED
@@ -12,6 +12,30 @@ export * from './context/types.js';
12
12
  // Export React Server Components
13
13
  export * from './context/rsc.js';
14
14
  export * from './components/rsc.js';
15
+ /**
16
+ * RSC component exports, including `CmsEditable`, `CmsContent`,
17
+ * `CmsContentArea` and their prop types.
18
+ *
19
+ * `CmsContent` usage:
20
+ *
21
+ * ```tsx
22
+ * import { CmsContent } from '@remkoj/optimizely-cms-react/rsc'
23
+ *
24
+ * <CmsContent contentLink={{ key: content._metadata.key, locale: 'en' }} />
25
+ * ```
26
+ *
27
+ * `CmsContentArea` usage:
28
+ *
29
+ * ```tsx
30
+ * import { CmsContentArea } from '@remkoj/optimizely-cms-react/rsc'
31
+ *
32
+ * <CmsContentArea
33
+ * items={content.MainContentArea}
34
+ * fieldName="MainContentArea"
35
+ * as="section"
36
+ * />
37
+ * ```
38
+ */
15
39
  export * from './components/rsc-components.js';
16
40
  export * from './rsc-utilities.js';
17
41
  //# sourceMappingURL=rsc.js.map
package/dist/rsc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rsc.js","sourceRoot":"","sources":["../src/rsc.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,SAAS,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAC5D,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAA;AAExC,iBAAiB;AACjB,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AACvC,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAElC,iCAAiC;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oBAAoB,CAAA"}
1
+ {"version":3,"file":"rsc.js","sourceRoot":"","sources":["../src/rsc.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,SAAS,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAC5D,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAA;AAExC,iBAAiB;AACjB,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AACvC,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAElC,iCAAiC;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oBAAoB,CAAA"}
package/dist/types.d.ts CHANGED
@@ -3,6 +3,9 @@ import type { DocumentNode } from "graphql";
3
3
  import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
4
4
  import type { ContentLinkWithLocale, ContentLink, InlineContentLinkWithLocale } from "@remkoj/optimizely-graph-client";
5
5
  import type { GenericContext } from "./context/types.js";
6
+ import type { CmsEditableProps } from "./components/cms-editable/index.js";
7
+ import type { VariationInput } from "@remkoj/optimizely-graph-client/router";
8
+ export type { VariationInput } from "@remkoj/optimizely-graph-client/router";
6
9
  export type ContentType = string[];
7
10
  export type {
8
11
  /**
@@ -13,9 +16,10 @@ ContentLink,
13
16
  * @deprecated Use the export from `@remkoj/optimizely-graph-client` directly
14
17
  */
15
18
  ContentLinkWithLocale } from "@remkoj/optimizely-graph-client";
19
+ export type ComponentCmsEditableProps = Pick<CmsEditableProps<'div'>, 'cmsId' | 'ctx' | 'currentContent'>;
16
20
  export type CmsComponentProps<T, L extends Record<string, any> = Record<string, any>> = PropsWithChildren<{
17
21
  /**
18
- * The identifier of the content item
22
+ * The identifier of the content item.
19
23
  */
20
24
  contentLink: ContentLinkWithLocale | InlineContentLinkWithLocale;
21
25
  /**
@@ -24,22 +28,30 @@ export type CmsComponentProps<T, L extends Record<string, any> = Record<string,
24
28
  data: T;
25
29
  /**
26
30
  * Use the Server/Client context instead if you need this information
31
+ *
32
+ * @deprecated
27
33
  */
28
34
  inEditMode?: boolean;
29
35
  /**
30
- * Contextual layout data, if any
36
+ * Contextual layout data from an Experience. This will be `undefined` if
37
+ * there's no layout data attached.
31
38
  */
32
39
  layoutProps?: L;
40
+ /**
41
+ * The minimal properties needed to render a CmsEditable inside the
42
+ * component.
43
+ */
44
+ editProps?: ComponentCmsEditableProps;
33
45
  /**
34
46
  * The context in which this component will be rendered
35
47
  */
36
48
  ctx?: GenericContext;
37
49
  }>;
38
- export type ContentQueryProps<LocaleType = string> = ContentLink & {
50
+ export type ContentQueryProps<LocaleType = string> = Omit<ContentLink, 'isInline' | 'variation'> & {
39
51
  locale?: Array<LocaleType> | LocaleType | null;
40
52
  path?: string | null;
41
53
  domain?: string | null;
42
- changeset?: string | null;
54
+ variation?: VariationInput | null;
43
55
  };
44
56
  /**
45
57
  * Extract the data type from a GraphQL Query
@@ -47,7 +59,22 @@ export type ContentQueryProps<LocaleType = string> = ContentLink & {
47
59
  export type ResponseDataType<T extends DocumentNode> = T extends TypedDocumentNode<infer DataType> ? DataType : {
48
60
  [key: string]: any;
49
61
  };
50
- export type GetDataQuery<T> = () => TypedDocumentNode<T, ContentQueryProps> | DocumentNode;
62
+ export type GetDataQueryResponseTemplate = {
63
+ __typename?: 'Query' | null;
64
+ data?: {
65
+ __typename?: string | null;
66
+ item?: {
67
+ __typename?: string | null;
68
+ _metadata?: {
69
+ key?: string | null;
70
+ locale?: any | null;
71
+ } | null;
72
+ [key: string]: any;
73
+ } | null;
74
+ } | null;
75
+ };
76
+ export type ProcessQueryResponse<T> = T extends GetDataQueryResponseTemplate ? NonNullable<NonNullable<Required<T>['data']>['item']> : T;
77
+ export type GetDataQuery<T> = () => TypedDocumentNode<T, Omit<ContentQueryProps, 'path' | 'domain'>> | DocumentNode;
51
78
  export type GetDataFragment<T> = () => [string, TypedDocumentNode<T, never> | DocumentNode | string];
52
79
  export type WithGqlFragment<BaseComponent, DataType> = BaseComponent & {
53
80
  getDataFragment: GetDataFragment<DataType>;
@@ -56,7 +83,7 @@ export type WithGqlFragment<BaseComponent, DataType> = BaseComponent & {
56
83
  export type WithGqlQuery<B, T> = B & {
57
84
  getDataQuery: GetDataQuery<T>;
58
85
  };
59
- export type BaseCmsComponent<T = {}, L extends Record<string, any> = Record<string, any>> = T extends never | TypedDocumentNode | DocumentNode ? DynamicCmsComponent<T> : ReactComponentType<CmsComponentProps<T, L>>;
86
+ export type BaseCmsComponent<T = {}, L extends Record<string, any> = Record<string, any>> = T extends never | TypedDocumentNode | DocumentNode ? DynamicCmsComponent<ProcessQueryResponse<T>> : ReactComponentType<CmsComponentProps<ProcessQueryResponse<T>, L>>;
60
87
  export type DynamicCmsComponent<T extends TypedDocumentNode | DocumentNode = DocumentNode, L extends Record<string, any> = Record<string, any>> = ReactComponentType<CmsComponentProps<ResponseDataType<T>, L>>;
61
88
  export type GraphQLFragmentBase = {
62
89
  ' $fragmentName'?: string;
@@ -79,4 +106,8 @@ export type CmsComponentWithOptionalQuery<T = DocumentNode, L extends Record<str
79
106
  export type CmsComponent<T = DocumentNode, L extends Record<string, any> = Record<string, any>> = T extends TypedDocumentNode<infer R, any> ? CmsComponentWithQuery<R, L> : T extends DocumentNode ? CmsComponentWithQuery<{
80
107
  [key: string]: any;
81
108
  }, L> : T extends GraphQLFragmentBase ? CmsComponentWithFragment<T, L> : T extends GraphQLQueryBase ? CmsComponentWithQuery<T, L> : CmsComponentWithOptionalQuery<T, L>;
109
+ /**
110
+ * A generic Optimizely CMS Component used to render a layout node from an experience, which cannot
111
+ * be loaded directly as independent Content Item from Optimizely Graph
112
+ */
82
113
  export type CmsLayoutComponent<L extends Record<string, any> = Record<string, any>, T = never> = ReactComponentType<CmsComponentProps<T, L>>;
@@ -1,9 +1,24 @@
1
1
  import type { ComponentType } from 'react';
2
2
  import type { DocumentNode } from 'graphql';
3
- import type { ContentLinkWithLocale, ContentLink } from '@remkoj/optimizely-graph-client';
4
- import type { ContentType, BaseCmsComponent, CmsComponentWithQuery, CmsComponentWithFragment, WithGqlFragment, ContentQueryProps } from './types.js';
5
- import type { ComponentFactory, ComponentTypeHandle } from './factory/types.js';
3
+ import type { ContentLinkWithLocale, ContentLink, IOptiGraphClient, InlineContentLink } from '@remkoj/optimizely-graph-client';
4
+ import type { ContentType, BaseCmsComponent, CmsComponentWithQuery, CmsComponentWithFragment, WithGqlFragment, ContentQueryProps, CmsComponentProps } from './types.js';
5
+ import type { ComponentFactory } from './factory/types.js';
6
6
  export * from './components/rich-text/utils.js';
7
+ /**
8
+ * Safeguard filter to remove default properties from the CmsComponent, intended
9
+ * to prevent these properties to be passed to client components. It will also
10
+ * remove all properties where the name starts with a `_`.
11
+ *
12
+ * @param toFilter The object to filter the
13
+ * @returns W
14
+ */
15
+ export declare function filterCmsComponentProps<T extends object>(toFilter: T): Omit<T, keyof CmsComponentProps<any>>;
16
+ /**
17
+ *
18
+ *
19
+ * @param toTest
20
+ * @returns
21
+ */
7
22
  export declare function isNonEmptyString(toTest: any): toTest is string;
8
23
  export declare function isNotNullOrUndefined<T>(toTest?: T | null): toTest is T;
9
24
  export declare function isContentType(toTest: any): toTest is ContentType;
@@ -40,14 +55,40 @@ export declare function normalizeAndPrefixContentType(contentType: Array<string
40
55
  * @param variants The variants to test
41
56
  * @returns The resolved Component or undefined if not found
42
57
  */
43
- export declare function resolveComponentType(factory: ComponentFactory, type: ComponentTypeHandle, variants?: Array<string>): ReturnType<ComponentFactory['resolve']>;
58
+ export declare function resolveComponentType(factory: ComponentFactory, type: ContentType, variants?: Array<string>): ReturnType<ComponentFactory['resolve']>;
44
59
  export declare function isCmsComponentWithDataQuery<T = DocumentNode>(toTest?: BaseCmsComponent<T>): toTest is CmsComponentWithQuery<T>;
45
60
  export declare function isCmsComponentWithFragment<T = DocumentNode>(toTest?: BaseCmsComponent<T>): toTest is CmsComponentWithFragment<T>;
46
61
  export declare function validatesFragment<T extends ComponentType<any>>(toTest?: T): toTest is T & Pick<Required<WithGqlFragment<T, any>>, "validateFragment">;
47
- export declare function contentLinkToRequestVariables(contentLink: ContentLinkWithLocale): ContentQueryProps;
62
+ /**
63
+ * Take a ContentLink and transform it into the normalized set of request variables used query for content across
64
+ * multiple components.
65
+ *
66
+ * @param contentLink The contentlink to transform
67
+ * @param client If provided, the the configuration of the client is applied to the variables
68
+ * @returns The request variables to use for querying Optimizely Graph
69
+ */
70
+ export declare function contentLinkToRequestVariables(contentLink: ContentLinkWithLocale, client: IOptiGraphClient): ContentQueryProps;
71
+ /**
72
+ * Normalizes a string|null|undefined input to a non-empty string or undefined. This ensures that a
73
+ * non-empty string is considered insignificant and will not yield an empty result. When provided,
74
+ * the transformer function is applied *after* the non-empty check and the outcome of the transformer
75
+ * is returned.
76
+ *
77
+ * @param inputValue The current value to check
78
+ * @param transformer The transformer to apply to a non-empty string value
79
+ * @returns The output of the transformer when the input is a non-empty string, `undefined` otherwise
80
+ */
81
+ export declare function ifNonEmptyString<T = string>(inputValue?: string | null, transformer?: (iv: string) => T): T | undefined;
48
82
  export declare function toUniqueValues<R extends any>(value: R, index: number, array: Array<R>): value is R;
49
83
  export declare function trim<T extends string | null | undefined>(valueToTrim: T): T;
50
- export declare function getContentEditId(contentLink: ContentLink): string;
84
+ /**
85
+ * Extract the identifier needed for the edit HTML properties from the contentLink. This will ensure
86
+ * that inline content links don't output an identifier.
87
+ *
88
+ * @param contentLink
89
+ * @returns
90
+ */
91
+ export declare function getContentEditId(contentLink?: ContentLink | InlineContentLink | null): string | undefined;
51
92
  /**
52
93
  * Generate a pseudo-random identifier usable to satisfy the unique key
53
94
  * requirement for children within a React node. However this effectively will
@@ -61,3 +102,12 @@ export declare function getContentEditId(contentLink: ContentLink): string;
61
102
  * @returns The unique key
62
103
  */
63
104
  export declare function getRandomKey(prefix?: string): string;
105
+ /**
106
+ * Parse the provided string to determine if it's a valid positive (i.e. larger then 0) number,
107
+ * return the number if it is, `undefined` or the `defaultValue` otherwise.
108
+ *
109
+ * @param value
110
+ * @param defaultValue
111
+ * @returns
112
+ */
113
+ export declare function tryParsePositiveInt(value: string | undefined | null, defaultValue?: number): number | undefined;