@webiny/website-builder-sdk 0.0.0-unstable.e6f0dc8ca7 → 0.0.0-unstable.eb81deee7e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BindingsApi.js +29 -36
- package/BindingsApi.js.map +1 -1
- package/BindingsProcessor.js +34 -43
- package/BindingsProcessor.js.map +1 -1
- package/BindingsProcessor.test.js +82 -78
- package/BindingsProcessor.test.js.map +1 -1
- package/BindingsResolver.d.ts +4 -1
- package/BindingsResolver.js +99 -119
- package/BindingsResolver.js.map +1 -1
- package/BindingsResolver.test.js +399 -363
- package/BindingsResolver.test.js.map +1 -1
- package/ComponentInputTraverser.js +32 -49
- package/ComponentInputTraverser.js.map +1 -1
- package/ComponentManifestToAstConverter.js +20 -21
- package/ComponentManifestToAstConverter.js.map +1 -1
- package/ComponentRegistry.d.ts +9 -0
- package/ComponentRegistry.js +30 -44
- package/ComponentRegistry.js.map +1 -1
- package/ComponentResolver.d.ts +3 -2
- package/ComponentResolver.js +39 -29
- package/ComponentResolver.js.map +1 -1
- package/ComponentResolver.test.d.ts +1 -0
- package/ComponentResolver.test.js +81 -0
- package/ComponentResolver.test.js.map +1 -0
- package/ConstraintEvaluator.js +246 -353
- package/ConstraintEvaluator.js.map +1 -1
- package/ConstraintEvaluator.test.js +1616 -1438
- package/ConstraintEvaluator.test.js.map +1 -1
- package/ContentSdk.d.ts +14 -0
- package/ContentSdk.js +113 -90
- package/ContentSdk.js.map +1 -1
- package/DocumentStore.js +47 -59
- package/DocumentStore.js.map +1 -1
- package/DocumentStoreManager.js +17 -16
- package/DocumentStoreManager.js.map +1 -1
- package/EditingSdk.js +92 -121
- package/EditingSdk.js.map +1 -1
- package/ElementFactory.js +164 -172
- package/ElementFactory.js.map +1 -1
- package/ElementFactory.objectListDefaults.test.d.ts +1 -0
- package/ElementFactory.objectListDefaults.test.js +423 -0
- package/ElementFactory.objectListDefaults.test.js.map +1 -0
- package/ElementFactory.test.js +335 -262
- package/ElementFactory.test.js.map +1 -1
- package/Environment.js +18 -19
- package/Environment.js.map +1 -1
- package/FunctionConverter.js +8 -7
- package/FunctionConverter.js.map +1 -1
- package/HashObject.js +11 -26
- package/HashObject.js.map +1 -1
- package/HotkeyManager.js +40 -47
- package/HotkeyManager.js.map +1 -1
- package/IBindingsUpdater.js +0 -3
- package/IRedirects.js +0 -3
- package/InheritanceProcessor.js +99 -139
- package/InheritanceProcessor.js.map +1 -1
- package/InheritanceProcessor.test.js +178 -179
- package/InheritanceProcessor.test.js.map +1 -1
- package/InheritedValueResolver.d.ts +18 -1
- package/InheritedValueResolver.js +18 -20
- package/InheritedValueResolver.js.map +1 -1
- package/InputBindingsProcessor.d.ts +23 -2
- package/InputBindingsProcessor.js +200 -307
- package/InputBindingsProcessor.js.map +1 -1
- package/InputBindingsProcessorTokens.test.d.ts +1 -0
- package/InputBindingsProcessorTokens.test.js +400 -0
- package/InputBindingsProcessorTokens.test.js.map +1 -0
- package/InputsBindingsProcessor.test.js +334 -315
- package/InputsBindingsProcessor.test.js.map +1 -1
- package/InputsUpdater.js +23 -26
- package/InputsUpdater.js.map +1 -1
- package/LiveSdk.js +12 -13
- package/LiveSdk.js.map +1 -1
- package/Logger.js +9 -8
- package/Logger.js.map +1 -1
- package/MouseTracker.js +77 -83
- package/MouseTracker.js.map +1 -1
- package/NullSdk.js +22 -21
- package/NullSdk.js.map +1 -1
- package/PreviewDocument.d.ts +1 -0
- package/PreviewDocument.js +30 -30
- package/PreviewDocument.js.map +1 -1
- package/PreviewSdk.d.ts +2 -1
- package/PreviewSdk.js +19 -17
- package/PreviewSdk.js.map +1 -1
- package/PreviewViewport.js +51 -63
- package/PreviewViewport.js.map +1 -1
- package/ResizeObserver.js +24 -31
- package/ResizeObserver.js.map +1 -1
- package/StylesBindingsProcessor.d.ts +12 -2
- package/StylesBindingsProcessor.js +62 -79
- package/StylesBindingsProcessor.js.map +1 -1
- package/StylesUpdater.js +20 -25
- package/StylesUpdater.js.map +1 -1
- package/Theme.js +30 -25
- package/Theme.js.map +1 -1
- package/ViewportManager.js +89 -101
- package/ViewportManager.js.map +1 -1
- package/assertBindingShapes.d.ts +31 -0
- package/assertBindingShapes.js +64 -0
- package/assertBindingShapes.js.map +1 -0
- package/assertBindingShapes.test.d.ts +1 -0
- package/assertBindingShapes.test.js +131 -0
- package/assertBindingShapes.test.js.map +1 -0
- package/asset/deliveryUrl.d.ts +41 -0
- package/asset/deliveryUrl.js +34 -0
- package/asset/deliveryUrl.js.map +1 -0
- package/asset/deliveryUrl.test.d.ts +1 -0
- package/asset/deliveryUrl.test.js +127 -0
- package/asset/deliveryUrl.test.js.map +1 -0
- package/asset/geometry.d.ts +7 -0
- package/asset/geometry.js +10 -0
- package/asset/geometry.js.map +1 -0
- package/asset/imageSrcSet.d.ts +63 -0
- package/asset/imageSrcSet.js +98 -0
- package/asset/imageSrcSet.js.map +1 -0
- package/asset/imageSrcSet.test.d.ts +1 -0
- package/asset/imageSrcSet.test.js +103 -0
- package/asset/imageSrcSet.test.js.map +1 -0
- package/asset/index.d.ts +5 -0
- package/asset/index.js +5 -0
- package/asset/normalize.d.ts +24 -0
- package/asset/normalize.js +106 -0
- package/asset/normalize.js.map +1 -0
- package/asset/normalize.test.d.ts +1 -0
- package/asset/normalize.test.js +263 -0
- package/asset/normalize.test.js.map +1 -0
- package/asset/types.d.ts +2 -0
- package/asset/types.js +0 -0
- package/constants.js +7 -6
- package/constants.js.map +1 -1
- package/contentEntry/ContentEntryBindingsResolver.d.ts +30 -0
- package/contentEntry/ContentEntryBindingsResolver.js +45 -0
- package/contentEntry/ContentEntryBindingsResolver.js.map +1 -0
- package/contentEntry/ContentEntryCache.d.ts +46 -0
- package/contentEntry/ContentEntryCache.js +50 -0
- package/contentEntry/ContentEntryCache.js.map +1 -0
- package/contentEntry/resolveContentEntry.d.ts +74 -0
- package/contentEntry/resolveContentEntry.js +53 -0
- package/contentEntry/resolveContentEntry.js.map +1 -0
- package/contentEntry/resolveContentEntry.test.d.ts +1 -0
- package/contentEntry/resolveContentEntry.test.js +213 -0
- package/contentEntry/resolveContentEntry.test.js.map +1 -0
- package/createComponent.d.ts +5 -0
- package/createComponent.js +32 -0
- package/createComponent.js.map +1 -0
- package/createElement.js +5 -6
- package/createElement.js.map +1 -1
- package/createInput.d.ts +10 -2
- package/createInput.js +92 -143
- package/createInput.js.map +1 -1
- package/createTheme.js +2 -3
- package/createTheme.js.map +1 -1
- package/dataProviders/ApiClient.d.ts +10 -5
- package/dataProviders/ApiClient.js +40 -49
- package/dataProviders/ApiClient.js.map +1 -1
- package/dataProviders/DefaultDataProvider.d.ts +4 -0
- package/dataProviders/DefaultDataProvider.js +91 -58
- package/dataProviders/DefaultDataProvider.js.map +1 -1
- package/dataProviders/GET_EXPERIMENT_PAUSED.d.ts +1 -0
- package/dataProviders/GET_EXPERIMENT_PAUSED.js +17 -0
- package/dataProviders/GET_EXPERIMENT_PAUSED.js.map +1 -0
- package/dataProviders/GET_PAGE_BY_ID.js +2 -1
- package/dataProviders/GET_PAGE_BY_ID.js.map +1 -1
- package/dataProviders/GET_PAGE_BY_PATH.js +2 -1
- package/dataProviders/GET_PAGE_BY_PATH.js.map +1 -1
- package/dataProviders/GET_PAGE_EXPERIMENT.d.ts +1 -0
- package/dataProviders/GET_PAGE_EXPERIMENT.js +32 -0
- package/dataProviders/GET_PAGE_EXPERIMENT.js.map +1 -0
- package/dataProviders/GET_VARIANT_CONTENT.d.ts +1 -0
- package/dataProviders/GET_VARIANT_CONTENT.js +24 -0
- package/dataProviders/GET_VARIANT_CONTENT.js.map +1 -0
- package/dataProviders/LIST_PUBLISHED_PAGES.js +2 -1
- package/dataProviders/LIST_PUBLISHED_PAGES.js.map +1 -1
- package/dataProviders/NullDataProvider.d.ts +4 -0
- package/dataProviders/NullDataProvider.js +30 -20
- package/dataProviders/NullDataProvider.js.map +1 -1
- package/dataProviders/RedirectsProvider.js +24 -27
- package/dataProviders/RedirectsProvider.js.map +1 -1
- package/defaultBreakpoints.js +43 -22
- package/defaultBreakpoints.js.map +1 -1
- package/documentOperations/$addElementReferenceToParent.js +29 -32
- package/documentOperations/$addElementReferenceToParent.js.map +1 -1
- package/documentOperations/AddElement.js +8 -7
- package/documentOperations/AddElement.js.map +1 -1
- package/documentOperations/AddToParent.js +14 -13
- package/documentOperations/AddToParent.js.map +1 -1
- package/documentOperations/IDocumentOperation.js +0 -3
- package/documentOperations/RemoveElement.js +9 -15
- package/documentOperations/RemoveElement.js.map +1 -1
- package/documentOperations/SetGlobalInputBinding.js +23 -22
- package/documentOperations/SetGlobalInputBinding.js.map +1 -1
- package/documentOperations/SetGlobalStyleBinding.js +23 -23
- package/documentOperations/SetGlobalStyleBinding.js.map +1 -1
- package/documentOperations/SetInputBindingOverride.js +30 -29
- package/documentOperations/SetInputBindingOverride.js.map +1 -1
- package/documentOperations/SetStyleBindingOverride.js +30 -31
- package/documentOperations/SetStyleBindingOverride.js.map +1 -1
- package/documentOperations/index.js +9 -8
- package/documentOperations/index.js.map +1 -1
- package/experiments/PostHogAnalyticsProvider.d.ts +31 -0
- package/experiments/PostHogAnalyticsProvider.js +28 -0
- package/experiments/PostHogAnalyticsProvider.js.map +1 -0
- package/experiments/analyticsProvider.d.ts +4 -0
- package/experiments/analyticsProvider.js +11 -0
- package/experiments/analyticsProvider.js.map +1 -0
- package/experiments/bucketing.d.ts +27 -0
- package/experiments/bucketing.js +91 -0
- package/experiments/bucketing.js.map +1 -0
- package/experiments/bucketing.test.d.ts +1 -0
- package/experiments/bucketing.test.js +183 -0
- package/experiments/bucketing.test.js.map +1 -0
- package/experiments/index.d.ts +5 -0
- package/experiments/index.js +5 -0
- package/experiments/render.d.ts +79 -0
- package/experiments/render.js +149 -0
- package/experiments/render.js.map +1 -0
- package/experiments/types.d.ts +108 -0
- package/experiments/types.js +4 -0
- package/experiments/types.js.map +1 -0
- package/findMatchingAstNode.js +11 -13
- package/findMatchingAstNode.js.map +1 -1
- package/generateElementId.js +2 -1
- package/generateElementId.js.map +1 -1
- package/headersProvider.js +4 -3
- package/headersProvider.js.map +1 -1
- package/image/geometry.d.ts +54 -0
- package/image/geometry.js +112 -0
- package/image/geometry.js.map +1 -0
- package/image/geometry.test.d.ts +1 -0
- package/image/geometry.test.js +190 -0
- package/image/geometry.test.js.map +1 -0
- package/image/index.d.ts +3 -0
- package/image/index.js +3 -0
- package/image/presets.d.ts +6 -0
- package/image/presets.js +20 -0
- package/image/presets.js.map +1 -0
- package/image/types.d.ts +10 -0
- package/image/types.js +0 -0
- package/index.d.ts +10 -0
- package/index.js +10 -2
- package/jsonPatch.js +5 -9
- package/jsonPatch.js.map +1 -1
- package/messages.js +12 -11
- package/messages.js.map +1 -1
- package/messenger/MessageOrigin.js +12 -11
- package/messenger/MessageOrigin.js.map +1 -1
- package/messenger/Messenger.js +58 -69
- package/messenger/Messenger.js.map +1 -1
- package/messenger/index.js +0 -2
- package/package.json +12 -9
- package/registerComponentGroup.js +5 -6
- package/registerComponentGroup.js.map +1 -1
- package/tokenBinding.d.ts +26 -0
- package/tokenBinding.js +15 -0
- package/tokenBinding.js.map +1 -0
- package/tokenBinding.test.d.ts +1 -0
- package/tokenBinding.test.js +165 -0
- package/tokenBinding.test.js.map +1 -0
- package/types/ShorthandCssProperties.js +0 -3
- package/types/WebsiteBuilderTheme.d.ts +12 -0
- package/types/WebsiteBuilderTheme.js +0 -3
- package/types.d.ts +96 -1
- package/types.js +0 -3
- package/IBindingsUpdater.js.map +0 -1
- package/IRedirects.js.map +0 -1
- package/documentOperations/IDocumentOperation.js.map +0 -1
- package/index.js.map +0 -1
- package/messenger/index.js.map +0 -1
- package/types/ShorthandCssProperties.js.map +0 -1
- package/types/WebsiteBuilderTheme.js.map +0 -1
- package/types.js.map +0 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ContentEntryReference, ContentEntryQueryValue } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal CMS data loader the content-entry resolver depends on. Injected by the
|
|
4
|
+
* caller (the render layer passes the CMS `contentSdk`) so this module stays
|
|
5
|
+
* decoupled from `@webiny/cms-sdk`.
|
|
6
|
+
*/
|
|
7
|
+
export interface ContentEntryLoader {
|
|
8
|
+
getEntry(params: {
|
|
9
|
+
modelId: string;
|
|
10
|
+
entryId: string;
|
|
11
|
+
}): Promise<unknown | null>;
|
|
12
|
+
listEntries(params: {
|
|
13
|
+
modelId: string;
|
|
14
|
+
sort?: Record<string, "asc" | "desc">;
|
|
15
|
+
limit?: number;
|
|
16
|
+
search?: string;
|
|
17
|
+
after?: string;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
data: unknown[];
|
|
20
|
+
meta: {
|
|
21
|
+
cursor: string | null;
|
|
22
|
+
hasMoreItems: boolean;
|
|
23
|
+
totalCount: number;
|
|
24
|
+
};
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The query params used to produce a page. Embedded in the query result so the
|
|
29
|
+
* client can fetch further pages (loadMore) from `pageInfo.cursor`.
|
|
30
|
+
*/
|
|
31
|
+
export interface ContentEntryQuerySpec {
|
|
32
|
+
modelId: string;
|
|
33
|
+
sort?: Record<string, "asc" | "desc">;
|
|
34
|
+
limit?: number;
|
|
35
|
+
search?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface ResolvedContentEntryQuery<T = unknown> {
|
|
38
|
+
items: T[];
|
|
39
|
+
pageInfo: {
|
|
40
|
+
cursor: string | null;
|
|
41
|
+
hasMore: boolean;
|
|
42
|
+
totalCount: number;
|
|
43
|
+
};
|
|
44
|
+
/** Continuation params for loadMore. */
|
|
45
|
+
query?: ContentEntryQuerySpec;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The shape passed to a component for a content-entry input:
|
|
49
|
+
* - manual, single -> the resolved entry (or null)
|
|
50
|
+
* - manual, list -> an array of resolved entries
|
|
51
|
+
* - query -> `{ items, pageInfo, query? }`
|
|
52
|
+
*/
|
|
53
|
+
export type ResolvedContentEntry = unknown | unknown[] | ResolvedContentEntryQuery | null;
|
|
54
|
+
/**
|
|
55
|
+
* Detect whether a raw binding value is a `ContentEntryQueryValue` (query mode)
|
|
56
|
+
* rather than a manual `ContentEntryReference`.
|
|
57
|
+
*
|
|
58
|
+
* Query values carry `modelId` but NOT `id`; manual references carry both.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isQueryValue(value: unknown): value is ContentEntryQueryValue;
|
|
61
|
+
/**
|
|
62
|
+
* Detect whether a content-entry input's value is already a resolved CMS entry
|
|
63
|
+
* rather than a bare reference that needs fetching.
|
|
64
|
+
*/
|
|
65
|
+
export declare function isAlreadyResolved(value: unknown, list: boolean): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Resolve a content-entry binding value into CMS entries. Works entirely from
|
|
68
|
+
* the value shape — no component manifest needed.
|
|
69
|
+
*
|
|
70
|
+
* - `{ id, modelId }` → fetch single entry
|
|
71
|
+
* - `[{ id, modelId }, ...]` → fetch multiple entries
|
|
72
|
+
* - `{ modelId, sort?, limit?, search? }` → list query
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveContentEntryValue(value: ContentEntryReference | ContentEntryReference[] | ContentEntryQueryValue | null | undefined, list: boolean, loader: ContentEntryLoader): Promise<ResolvedContentEntry>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
function isQueryValue(value) {
|
|
2
|
+
return "object" == typeof value && null !== value && "modelId" in value && !("id" in value) && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
function isAlreadyResolved(value, list) {
|
|
5
|
+
if (null == value) return false;
|
|
6
|
+
if ("object" == typeof value && "items" in value) return true;
|
|
7
|
+
if (list && Array.isArray(value) && value.length > 0) {
|
|
8
|
+
const first = value[0];
|
|
9
|
+
return "object" == typeof first && null !== first && "values" in first;
|
|
10
|
+
}
|
|
11
|
+
if (!list && "object" == typeof value && "values" in value) return true;
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
async function resolveContentEntryValue(value, list, loader) {
|
|
15
|
+
if (null == value) return list ? [] : null;
|
|
16
|
+
if (isQueryValue(value)) {
|
|
17
|
+
const query = value;
|
|
18
|
+
const listParams = {
|
|
19
|
+
modelId: query.modelId,
|
|
20
|
+
sort: query.sort ? {
|
|
21
|
+
[query.sort.field]: query.sort.order
|
|
22
|
+
} : void 0,
|
|
23
|
+
limit: query.limit,
|
|
24
|
+
search: query.search
|
|
25
|
+
};
|
|
26
|
+
const result = await loader.listEntries(listParams);
|
|
27
|
+
return {
|
|
28
|
+
items: result.data,
|
|
29
|
+
pageInfo: {
|
|
30
|
+
cursor: result.meta.cursor,
|
|
31
|
+
hasMore: result.meta.hasMoreItems,
|
|
32
|
+
totalCount: result.meta.totalCount
|
|
33
|
+
},
|
|
34
|
+
query: listParams
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
const refs = value;
|
|
39
|
+
const entries = await Promise.all(refs.map((ref)=>loader.getEntry({
|
|
40
|
+
modelId: ref.modelId,
|
|
41
|
+
entryId: ref.id
|
|
42
|
+
})));
|
|
43
|
+
return entries.filter((entry)=>null !== entry);
|
|
44
|
+
}
|
|
45
|
+
const ref = value;
|
|
46
|
+
return loader.getEntry({
|
|
47
|
+
modelId: ref.modelId,
|
|
48
|
+
entryId: ref.id
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export { isAlreadyResolved, isQueryValue, resolveContentEntryValue };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=resolveContentEntry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentEntry/resolveContentEntry.js","sources":["../../src/contentEntry/resolveContentEntry.ts"],"sourcesContent":["import type { ContentEntryReference, ContentEntryQueryValue } from \"~/types.js\";\n\n/**\n * Minimal CMS data loader the content-entry resolver depends on. Injected by the\n * caller (the render layer passes the CMS `contentSdk`) so this module stays\n * decoupled from `@webiny/cms-sdk`.\n */\nexport interface ContentEntryLoader {\n getEntry(params: { modelId: string; entryId: string }): Promise<unknown | null>;\n listEntries(params: {\n modelId: string;\n sort?: Record<string, \"asc\" | \"desc\">;\n limit?: number;\n search?: string;\n after?: string;\n }): Promise<{\n data: unknown[];\n meta: { cursor: string | null; hasMoreItems: boolean; totalCount: number };\n }>;\n}\n\n/**\n * The query params used to produce a page. Embedded in the query result so the\n * client can fetch further pages (loadMore) from `pageInfo.cursor`.\n */\nexport interface ContentEntryQuerySpec {\n modelId: string;\n sort?: Record<string, \"asc\" | \"desc\">;\n limit?: number;\n search?: string;\n}\n\nexport interface ResolvedContentEntryQuery<T = unknown> {\n items: T[];\n pageInfo: { cursor: string | null; hasMore: boolean; totalCount: number };\n /** Continuation params for loadMore. */\n query?: ContentEntryQuerySpec;\n}\n\n/**\n * The shape passed to a component for a content-entry input:\n * - manual, single -> the resolved entry (or null)\n * - manual, list -> an array of resolved entries\n * - query -> `{ items, pageInfo, query? }`\n */\nexport type ResolvedContentEntry = unknown | unknown[] | ResolvedContentEntryQuery | null;\n\n/**\n * Detect whether a raw binding value is a `ContentEntryQueryValue` (query mode)\n * rather than a manual `ContentEntryReference`.\n *\n * Query values carry `modelId` but NOT `id`; manual references carry both.\n */\nexport function isQueryValue(value: unknown): value is ContentEntryQueryValue {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"modelId\" in value &&\n !(\"id\" in value) &&\n !Array.isArray(value)\n );\n}\n\n/**\n * Detect whether a content-entry input's value is already a resolved CMS entry\n * rather than a bare reference that needs fetching.\n */\nexport function isAlreadyResolved(value: unknown, list: boolean): boolean {\n if (value == null) {\n return false;\n }\n // Query result — already resolved if it has `items`.\n if (typeof value === \"object\" && \"items\" in (value as any)) {\n return true;\n }\n // List of resolved entries — each has `values` (CMS entry shape).\n if (list && Array.isArray(value) && value.length > 0) {\n const first = value[0];\n return typeof first === \"object\" && first !== null && \"values\" in first;\n }\n // Single resolved entry.\n if (!list && typeof value === \"object\" && \"values\" in (value as any)) {\n return true;\n }\n return false;\n}\n\n/**\n * Resolve a content-entry binding value into CMS entries. Works entirely from\n * the value shape — no component manifest needed.\n *\n * - `{ id, modelId }` → fetch single entry\n * - `[{ id, modelId }, ...]` → fetch multiple entries\n * - `{ modelId, sort?, limit?, search? }` → list query\n */\nexport async function resolveContentEntryValue(\n value:\n | ContentEntryReference\n | ContentEntryReference[]\n | ContentEntryQueryValue\n | null\n | undefined,\n list: boolean,\n loader: ContentEntryLoader\n): Promise<ResolvedContentEntry> {\n if (value == null) {\n return list ? [] : null;\n }\n\n // Query mode: value is `{ modelId, sort?, limit?, search? }`.\n if (isQueryValue(value)) {\n const query = value;\n const listParams: ContentEntryQuerySpec = {\n modelId: query.modelId,\n sort: query.sort ? { [query.sort.field]: query.sort.order } : undefined,\n limit: query.limit,\n search: query.search\n };\n const result = await loader.listEntries(listParams);\n return {\n items: result.data,\n pageInfo: {\n cursor: result.meta.cursor,\n hasMore: result.meta.hasMoreItems,\n totalCount: result.meta.totalCount\n },\n query: listParams\n };\n }\n\n // Manual list: value is `[{ id, modelId }, ...]`.\n if (Array.isArray(value)) {\n const refs = value as ContentEntryReference[];\n const entries = await Promise.all(\n refs.map(ref => loader.getEntry({ modelId: ref.modelId, entryId: ref.id }))\n );\n return entries.filter(entry => entry !== null);\n }\n\n // Manual single: value is `{ id, modelId }`.\n const ref = value as ContentEntryReference;\n return loader.getEntry({ modelId: ref.modelId, entryId: ref.id });\n}\n"],"names":["isQueryValue","value","Array","isAlreadyResolved","list","first","resolveContentEntryValue","loader","query","listParams","undefined","result","refs","entries","Promise","ref","entry"],"mappings":"AAqDO,SAASA,aAAaC,KAAc;IACvC,OACI,AAAiB,YAAjB,OAAOA,SACPA,AAAU,SAAVA,SACA,aAAaA,SACb,CAAE,SAAQA,KAAI,KACd,CAACC,MAAM,OAAO,CAACD;AAEvB;AAMO,SAASE,kBAAkBF,KAAc,EAAEG,IAAa;IAC3D,IAAIH,AAAS,QAATA,OACA,OAAO;IAGX,IAAI,AAAiB,YAAjB,OAAOA,SAAsB,WAAYA,OACzC,OAAO;IAGX,IAAIG,QAAQF,MAAM,OAAO,CAACD,UAAUA,MAAM,MAAM,GAAG,GAAG;QAClD,MAAMI,QAAQJ,KAAK,CAAC,EAAE;QACtB,OAAO,AAAiB,YAAjB,OAAOI,SAAsBA,AAAU,SAAVA,SAAkB,YAAYA;IACtE;IAEA,IAAI,CAACD,QAAQ,AAAiB,YAAjB,OAAOH,SAAsB,YAAaA,OACnD,OAAO;IAEX,OAAO;AACX;AAUO,eAAeK,yBAClBL,KAKe,EACfG,IAAa,EACbG,MAA0B;IAE1B,IAAIN,AAAS,QAATA,OACA,OAAOG,OAAO,EAAE,GAAG;IAIvB,IAAIJ,aAAaC,QAAQ;QACrB,MAAMO,QAAQP;QACd,MAAMQ,aAAoC;YACtC,SAASD,MAAM,OAAO;YACtB,MAAMA,MAAM,IAAI,GAAG;gBAAE,CAACA,MAAM,IAAI,CAAC,KAAK,CAAC,EAAEA,MAAM,IAAI,CAAC,KAAK;YAAC,IAAIE;YAC9D,OAAOF,MAAM,KAAK;YAClB,QAAQA,MAAM,MAAM;QACxB;QACA,MAAMG,SAAS,MAAMJ,OAAO,WAAW,CAACE;QACxC,OAAO;YACH,OAAOE,OAAO,IAAI;YAClB,UAAU;gBACN,QAAQA,OAAO,IAAI,CAAC,MAAM;gBAC1B,SAASA,OAAO,IAAI,CAAC,YAAY;gBACjC,YAAYA,OAAO,IAAI,CAAC,UAAU;YACtC;YACA,OAAOF;QACX;IACJ;IAGA,IAAIP,MAAM,OAAO,CAACD,QAAQ;QACtB,MAAMW,OAAOX;QACb,MAAMY,UAAU,MAAMC,QAAQ,GAAG,CAC7BF,KAAK,GAAG,CAACG,CAAAA,MAAOR,OAAO,QAAQ,CAAC;gBAAE,SAASQ,IAAI,OAAO;gBAAE,SAASA,IAAI,EAAE;YAAC;QAE5E,OAAOF,QAAQ,MAAM,CAACG,CAAAA,QAASA,AAAU,SAAVA;IACnC;IAGA,MAAMD,MAAMd;IACZ,OAAOM,OAAO,QAAQ,CAAC;QAAE,SAASQ,IAAI,OAAO;QAAE,SAASA,IAAI,EAAE;IAAC;AACnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { isAlreadyResolved, isQueryValue, resolveContentEntryValue } from "./resolveContentEntry.js";
|
|
3
|
+
const entry = (id)=>({
|
|
4
|
+
id,
|
|
5
|
+
entryId: id,
|
|
6
|
+
values: {
|
|
7
|
+
title: `T${id}`
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
function makeLoader(over = {}) {
|
|
11
|
+
return {
|
|
12
|
+
getEntry: vi.fn(async ({ entryId })=>entry(entryId)),
|
|
13
|
+
listEntries: vi.fn(async ()=>({
|
|
14
|
+
data: [
|
|
15
|
+
entry("1"),
|
|
16
|
+
entry("2")
|
|
17
|
+
],
|
|
18
|
+
meta: {
|
|
19
|
+
cursor: "c1",
|
|
20
|
+
hasMoreItems: true,
|
|
21
|
+
totalCount: 5
|
|
22
|
+
}
|
|
23
|
+
})),
|
|
24
|
+
...over
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
describe("resolveContentEntryValue — manual mode", ()=>{
|
|
28
|
+
it("resolves a single reference", async ()=>{
|
|
29
|
+
const loader = makeLoader();
|
|
30
|
+
const result = await resolveContentEntryValue({
|
|
31
|
+
id: "42",
|
|
32
|
+
modelId: "blog"
|
|
33
|
+
}, false, loader);
|
|
34
|
+
expect(loader.getEntry).toHaveBeenCalledWith({
|
|
35
|
+
modelId: "blog",
|
|
36
|
+
entryId: "42"
|
|
37
|
+
});
|
|
38
|
+
expect(result).toEqual(entry("42"));
|
|
39
|
+
});
|
|
40
|
+
it("returns null for a null single value", async ()=>{
|
|
41
|
+
const loader = makeLoader();
|
|
42
|
+
const result = await resolveContentEntryValue(null, false, loader);
|
|
43
|
+
expect(result).toBeNull();
|
|
44
|
+
expect(loader.getEntry).not.toHaveBeenCalled();
|
|
45
|
+
});
|
|
46
|
+
it("resolves a list of references, preserving order", async ()=>{
|
|
47
|
+
const loader = makeLoader();
|
|
48
|
+
const result = await resolveContentEntryValue([
|
|
49
|
+
{
|
|
50
|
+
id: "1",
|
|
51
|
+
modelId: "blog"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "2",
|
|
55
|
+
modelId: "blog"
|
|
56
|
+
}
|
|
57
|
+
], true, loader);
|
|
58
|
+
expect(loader.getEntry).toHaveBeenCalledTimes(2);
|
|
59
|
+
expect(result).toEqual([
|
|
60
|
+
entry("1"),
|
|
61
|
+
entry("2")
|
|
62
|
+
]);
|
|
63
|
+
});
|
|
64
|
+
it("filters out unresolved (deleted) references in a list", async ()=>{
|
|
65
|
+
const loader = makeLoader({
|
|
66
|
+
getEntry: vi.fn(async ({ entryId })=>"2" === entryId ? null : entry(entryId))
|
|
67
|
+
});
|
|
68
|
+
const result = await resolveContentEntryValue([
|
|
69
|
+
{
|
|
70
|
+
id: "1",
|
|
71
|
+
modelId: "blog"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "2",
|
|
75
|
+
modelId: "blog"
|
|
76
|
+
}
|
|
77
|
+
], true, loader);
|
|
78
|
+
expect(result).toEqual([
|
|
79
|
+
entry("1")
|
|
80
|
+
]);
|
|
81
|
+
});
|
|
82
|
+
it("returns an empty array for a null list value", async ()=>{
|
|
83
|
+
const loader = makeLoader();
|
|
84
|
+
const result = await resolveContentEntryValue(null, true, loader);
|
|
85
|
+
expect(result).toEqual([]);
|
|
86
|
+
expect(loader.getEntry).not.toHaveBeenCalled();
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe("resolveContentEntryValue — query mode", ()=>{
|
|
90
|
+
it("runs the query and returns items + pageInfo", async ()=>{
|
|
91
|
+
const loader = makeLoader();
|
|
92
|
+
const result = await resolveContentEntryValue({
|
|
93
|
+
modelId: "blog",
|
|
94
|
+
sort: {
|
|
95
|
+
field: "values_title",
|
|
96
|
+
order: "asc"
|
|
97
|
+
},
|
|
98
|
+
limit: 5,
|
|
99
|
+
search: "cat"
|
|
100
|
+
}, false, loader);
|
|
101
|
+
expect(loader.listEntries).toHaveBeenCalledWith({
|
|
102
|
+
modelId: "blog",
|
|
103
|
+
sort: {
|
|
104
|
+
values_title: "asc"
|
|
105
|
+
},
|
|
106
|
+
limit: 5,
|
|
107
|
+
search: "cat"
|
|
108
|
+
});
|
|
109
|
+
expect(result).toMatchObject({
|
|
110
|
+
items: [
|
|
111
|
+
entry("1"),
|
|
112
|
+
entry("2")
|
|
113
|
+
],
|
|
114
|
+
pageInfo: {
|
|
115
|
+
cursor: "c1",
|
|
116
|
+
hasMore: true,
|
|
117
|
+
totalCount: 5
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
it("always embeds the continuation query", async ()=>{
|
|
122
|
+
const loader = makeLoader();
|
|
123
|
+
const result = await resolveContentEntryValue({
|
|
124
|
+
modelId: "blog",
|
|
125
|
+
limit: 4
|
|
126
|
+
}, false, loader);
|
|
127
|
+
expect(result.query).toEqual({
|
|
128
|
+
modelId: "blog",
|
|
129
|
+
sort: void 0,
|
|
130
|
+
limit: 4,
|
|
131
|
+
search: void 0
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
it("runs a minimal query (modelId only)", async ()=>{
|
|
135
|
+
const loader = makeLoader();
|
|
136
|
+
await resolveContentEntryValue({
|
|
137
|
+
modelId: "blog"
|
|
138
|
+
}, false, loader);
|
|
139
|
+
expect(loader.listEntries).toHaveBeenCalledWith({
|
|
140
|
+
modelId: "blog",
|
|
141
|
+
sort: void 0,
|
|
142
|
+
limit: void 0,
|
|
143
|
+
search: void 0
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
describe("isQueryValue", ()=>{
|
|
148
|
+
it("returns true for { modelId } without id", ()=>{
|
|
149
|
+
expect(isQueryValue({
|
|
150
|
+
modelId: "blog"
|
|
151
|
+
})).toBe(true);
|
|
152
|
+
expect(isQueryValue({
|
|
153
|
+
modelId: "blog",
|
|
154
|
+
sort: {
|
|
155
|
+
field: "a",
|
|
156
|
+
order: "asc"
|
|
157
|
+
}
|
|
158
|
+
})).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
it("returns false for a manual reference { id, modelId }", ()=>{
|
|
161
|
+
expect(isQueryValue({
|
|
162
|
+
id: "42",
|
|
163
|
+
modelId: "blog"
|
|
164
|
+
})).toBe(false);
|
|
165
|
+
});
|
|
166
|
+
it("returns false for arrays and non-objects", ()=>{
|
|
167
|
+
expect(isQueryValue([
|
|
168
|
+
{
|
|
169
|
+
modelId: "blog"
|
|
170
|
+
}
|
|
171
|
+
])).toBe(false);
|
|
172
|
+
expect(isQueryValue(null)).toBe(false);
|
|
173
|
+
expect(isQueryValue("string")).toBe(false);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
describe("isAlreadyResolved", ()=>{
|
|
177
|
+
it("returns true for a query result with items", ()=>{
|
|
178
|
+
expect(isAlreadyResolved({
|
|
179
|
+
items: [],
|
|
180
|
+
pageInfo: {}
|
|
181
|
+
}, false)).toBe(true);
|
|
182
|
+
});
|
|
183
|
+
it("returns true for a list of resolved entries", ()=>{
|
|
184
|
+
expect(isAlreadyResolved([
|
|
185
|
+
{
|
|
186
|
+
values: {
|
|
187
|
+
title: "x"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
], true)).toBe(true);
|
|
191
|
+
});
|
|
192
|
+
it("returns false for a list of bare references", ()=>{
|
|
193
|
+
expect(isAlreadyResolved([
|
|
194
|
+
{
|
|
195
|
+
id: "1",
|
|
196
|
+
modelId: "blog"
|
|
197
|
+
}
|
|
198
|
+
], true)).toBe(false);
|
|
199
|
+
});
|
|
200
|
+
it("returns true for a single resolved entry", ()=>{
|
|
201
|
+
expect(isAlreadyResolved({
|
|
202
|
+
values: {
|
|
203
|
+
title: "x"
|
|
204
|
+
}
|
|
205
|
+
}, false)).toBe(true);
|
|
206
|
+
});
|
|
207
|
+
it("returns false for null", ()=>{
|
|
208
|
+
expect(isAlreadyResolved(null, false)).toBe(false);
|
|
209
|
+
expect(isAlreadyResolved(null, true)).toBe(false);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
//# sourceMappingURL=resolveContentEntry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentEntry/resolveContentEntry.test.js","sources":["../../src/contentEntry/resolveContentEntry.test.ts"],"sourcesContent":["import { describe, it, expect, vi } from \"vitest\";\nimport {\n resolveContentEntryValue,\n isQueryValue,\n isAlreadyResolved,\n type ContentEntryLoader\n} from \"./resolveContentEntry.js\";\n\nconst entry = (id: string) => ({ id, entryId: id, values: { title: `T${id}` } });\n\nfunction makeLoader(over: Partial<ContentEntryLoader> = {}): ContentEntryLoader {\n return {\n getEntry: vi.fn(async ({ entryId }: { entryId: string }) => entry(entryId)),\n listEntries: vi.fn(async () => ({\n data: [entry(\"1\"), entry(\"2\")],\n meta: { cursor: \"c1\", hasMoreItems: true, totalCount: 5 }\n })),\n ...over\n };\n}\n\ndescribe(\"resolveContentEntryValue — manual mode\", () => {\n it(\"resolves a single reference\", async () => {\n const loader = makeLoader();\n const result = await resolveContentEntryValue({ id: \"42\", modelId: \"blog\" }, false, loader);\n expect(loader.getEntry).toHaveBeenCalledWith({ modelId: \"blog\", entryId: \"42\" });\n expect(result).toEqual(entry(\"42\"));\n });\n\n it(\"returns null for a null single value\", async () => {\n const loader = makeLoader();\n const result = await resolveContentEntryValue(null, false, loader);\n expect(result).toBeNull();\n expect(loader.getEntry).not.toHaveBeenCalled();\n });\n\n it(\"resolves a list of references, preserving order\", async () => {\n const loader = makeLoader();\n const result = await resolveContentEntryValue(\n [\n { id: \"1\", modelId: \"blog\" },\n { id: \"2\", modelId: \"blog\" }\n ],\n true,\n loader\n );\n expect(loader.getEntry).toHaveBeenCalledTimes(2);\n expect(result).toEqual([entry(\"1\"), entry(\"2\")]);\n });\n\n it(\"filters out unresolved (deleted) references in a list\", async () => {\n const loader = makeLoader({\n getEntry: vi.fn(async ({ entryId }: { entryId: string }) =>\n entryId === \"2\" ? null : entry(entryId)\n )\n });\n const result = await resolveContentEntryValue(\n [\n { id: \"1\", modelId: \"blog\" },\n { id: \"2\", modelId: \"blog\" }\n ],\n true,\n loader\n );\n expect(result).toEqual([entry(\"1\")]);\n });\n\n it(\"returns an empty array for a null list value\", async () => {\n const loader = makeLoader();\n const result = await resolveContentEntryValue(null, true, loader);\n expect(result).toEqual([]);\n expect(loader.getEntry).not.toHaveBeenCalled();\n });\n});\n\ndescribe(\"resolveContentEntryValue — query mode\", () => {\n it(\"runs the query and returns items + pageInfo\", async () => {\n const loader = makeLoader();\n const result = await resolveContentEntryValue(\n {\n modelId: \"blog\",\n sort: { field: \"values_title\", order: \"asc\" },\n limit: 5,\n search: \"cat\"\n },\n false,\n loader\n );\n expect(loader.listEntries).toHaveBeenCalledWith({\n modelId: \"blog\",\n sort: { values_title: \"asc\" },\n limit: 5,\n search: \"cat\"\n });\n expect(result).toMatchObject({\n items: [entry(\"1\"), entry(\"2\")],\n pageInfo: { cursor: \"c1\", hasMore: true, totalCount: 5 }\n });\n });\n\n it(\"always embeds the continuation query\", async () => {\n const loader = makeLoader();\n const result = (await resolveContentEntryValue(\n { modelId: \"blog\", limit: 4 },\n false,\n loader\n )) as Record<string, unknown>;\n expect(result.query).toEqual({\n modelId: \"blog\",\n sort: undefined,\n limit: 4,\n search: undefined\n });\n });\n\n it(\"runs a minimal query (modelId only)\", async () => {\n const loader = makeLoader();\n await resolveContentEntryValue({ modelId: \"blog\" }, false, loader);\n expect(loader.listEntries).toHaveBeenCalledWith({\n modelId: \"blog\",\n sort: undefined,\n limit: undefined,\n search: undefined\n });\n });\n});\n\ndescribe(\"isQueryValue\", () => {\n it(\"returns true for { modelId } without id\", () => {\n expect(isQueryValue({ modelId: \"blog\" })).toBe(true);\n expect(isQueryValue({ modelId: \"blog\", sort: { field: \"a\", order: \"asc\" } })).toBe(true);\n });\n\n it(\"returns false for a manual reference { id, modelId }\", () => {\n expect(isQueryValue({ id: \"42\", modelId: \"blog\" })).toBe(false);\n });\n\n it(\"returns false for arrays and non-objects\", () => {\n expect(isQueryValue([{ modelId: \"blog\" }])).toBe(false);\n expect(isQueryValue(null)).toBe(false);\n expect(isQueryValue(\"string\")).toBe(false);\n });\n});\n\ndescribe(\"isAlreadyResolved\", () => {\n it(\"returns true for a query result with items\", () => {\n expect(isAlreadyResolved({ items: [], pageInfo: {} }, false)).toBe(true);\n });\n\n it(\"returns true for a list of resolved entries\", () => {\n expect(isAlreadyResolved([{ values: { title: \"x\" } }], true)).toBe(true);\n });\n\n it(\"returns false for a list of bare references\", () => {\n expect(isAlreadyResolved([{ id: \"1\", modelId: \"blog\" }], true)).toBe(false);\n });\n\n it(\"returns true for a single resolved entry\", () => {\n expect(isAlreadyResolved({ values: { title: \"x\" } }, false)).toBe(true);\n });\n\n it(\"returns false for null\", () => {\n expect(isAlreadyResolved(null, false)).toBe(false);\n expect(isAlreadyResolved(null, true)).toBe(false);\n });\n});\n"],"names":["entry","id","makeLoader","over","vi","entryId","describe","it","loader","result","resolveContentEntryValue","expect","undefined","isQueryValue","isAlreadyResolved"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Component, ComponentManifestInput } from "./types.js";
|
|
2
|
+
export type ExtractInputs<T> = T extends {
|
|
3
|
+
inputs: infer I;
|
|
4
|
+
} ? I : never;
|
|
5
|
+
export declare function createComponent<TComponent extends (props: any) => any, TInputs extends ExtractInputs<Parameters<TComponent>[0]>>(component: TComponent, manifest: ComponentManifestInput<TInputs>): Component;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createSlotInput } from "./createInput.js";
|
|
2
|
+
function createComponent(component, manifest) {
|
|
3
|
+
const inputs = [];
|
|
4
|
+
if (Array.isArray(manifest.inputs)) inputs.push(...manifest.inputs);
|
|
5
|
+
else {
|
|
6
|
+
const inputsObject = manifest.inputs ?? {};
|
|
7
|
+
Object.keys(inputsObject).forEach((name)=>{
|
|
8
|
+
inputs.push({
|
|
9
|
+
...inputsObject[name],
|
|
10
|
+
name
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const acceptsChildren = manifest.acceptsChildren;
|
|
15
|
+
if (acceptsChildren) {
|
|
16
|
+
const hasChildren = inputs.some((input)=>"children" === input.name);
|
|
17
|
+
if (!hasChildren) inputs.push(createSlotInput({
|
|
18
|
+
name: "children"
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
component,
|
|
23
|
+
manifest: {
|
|
24
|
+
...manifest,
|
|
25
|
+
tags: manifest.tags ?? [],
|
|
26
|
+
inputs
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export { createComponent };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=createComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createComponent.js","sources":["../src/createComponent.ts"],"sourcesContent":["import type {\n Component,\n ComponentInput,\n ComponentManifest,\n ComponentManifestInput\n} from \"./types.js\";\nimport type { InputFactory } from \"./createInput.js\";\nimport { createSlotInput } from \"./createInput.js\";\n\nexport type ExtractInputs<T> = T extends { inputs: infer I } ? I : never;\n\nexport function createComponent<\n TComponent extends (props: any) => any,\n TInputs extends ExtractInputs<Parameters<TComponent>[0]>\n>(component: TComponent, manifest: ComponentManifestInput<TInputs>): Component {\n const inputs: ComponentInput[] = [];\n\n if (Array.isArray(manifest.inputs)) {\n inputs.push(...manifest.inputs);\n } else {\n const inputsObject: Record<string, InputFactory<any>> = manifest.inputs ?? {};\n Object.keys(inputsObject).forEach((name: string) => {\n inputs.push({ ...inputsObject[name], name });\n });\n }\n\n const acceptsChildren = manifest.acceptsChildren;\n\n if (acceptsChildren) {\n const hasChildren = inputs.some(input => input.name === \"children\");\n if (!hasChildren) {\n inputs.push(createSlotInput({ name: \"children\" }));\n }\n }\n\n return {\n component,\n manifest: { ...manifest, tags: manifest.tags ?? [], inputs } as ComponentManifest\n };\n}\n"],"names":["createComponent","component","manifest","inputs","Array","inputsObject","Object","name","acceptsChildren","hasChildren","input","createSlotInput"],"mappings":";AAWO,SAASA,gBAGdC,SAAqB,EAAEC,QAAyC;IAC9D,MAAMC,SAA2B,EAAE;IAEnC,IAAIC,MAAM,OAAO,CAACF,SAAS,MAAM,GAC7BC,OAAO,IAAI,IAAID,SAAS,MAAM;SAC3B;QACH,MAAMG,eAAkDH,SAAS,MAAM,IAAI,CAAC;QAC5EI,OAAO,IAAI,CAACD,cAAc,OAAO,CAAC,CAACE;YAC/BJ,OAAO,IAAI,CAAC;gBAAE,GAAGE,YAAY,CAACE,KAAK;gBAAEA;YAAK;QAC9C;IACJ;IAEA,MAAMC,kBAAkBN,SAAS,eAAe;IAEhD,IAAIM,iBAAiB;QACjB,MAAMC,cAAcN,OAAO,IAAI,CAACO,CAAAA,QAASA,AAAe,eAAfA,MAAM,IAAI;QACnD,IAAI,CAACD,aACDN,OAAO,IAAI,CAACQ,gBAAgB;YAAE,MAAM;QAAW;IAEvD;IAEA,OAAO;QACHV;QACA,UAAU;YAAE,GAAGC,QAAQ;YAAE,MAAMA,SAAS,IAAI,IAAI,EAAE;YAAEC;QAAO;IAC/D;AACJ"}
|
package/createElement.js
CHANGED
package/createElement.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"createElement.js","sources":["../src/createElement.ts"],"sourcesContent":["import type { ResponsiveStyles } from \"~/types.js\";\n\nexport interface CreateElementParams {\n component: string;\n inputs?: Record<string, any>;\n styles?: ResponsiveStyles;\n}\n\nexport const createElement = (params: CreateElementParams) => {\n return {\n action: \"CreateElement\",\n params\n };\n};\n"],"names":["createElement","params"],"mappings":"AAQO,MAAMA,gBAAgB,CAACC,SACnB;QACH,QAAQ;QACRA;IACJ"}
|
package/createInput.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TextInput, LongTextInput, NumberInput, BooleanInput, ColorInput, FileInput, LexicalInput, SelectInput, RadioInput, ObjectInput, DateTimeInput, ComponentInput, TagsInput, SlotInput } from "./types.js";
|
|
2
|
-
export type InputFactory<Name extends string> = ReturnType<typeof createTextInput<Name>> | ReturnType<typeof createLongTextInput<Name>> | ReturnType<typeof createNumberInput<Name>> | ReturnType<typeof createBooleanInput<Name>> | ReturnType<typeof createColorInput<Name>> | ReturnType<typeof createFileInput<Name>> | ReturnType<typeof createDateInput<Name>> | ReturnType<typeof createLexicalInput<Name>> | ReturnType<typeof createSelectInput<Name>> | ReturnType<typeof createRadioInput<Name>> | ReturnType<typeof createObjectInput<Name>> | ReturnType<typeof createTagsInput<Name>> | ReturnType<typeof createSlotInput<Name>>;
|
|
1
|
+
import type { TextInput, LongTextInput, NumberInput, BooleanInput, ColorInput, FileInput, LexicalInput, SelectInput, RadioInput, ObjectInput, DateTimeInput, ComponentInput, TagsInput, SlotInput, ContentEntryInput } from "./types.js";
|
|
2
|
+
export type InputFactory<Name extends string> = ReturnType<typeof createTextInput<Name>> | ReturnType<typeof createLongTextInput<Name>> | ReturnType<typeof createNumberInput<Name>> | ReturnType<typeof createBooleanInput<Name>> | ReturnType<typeof createColorInput<Name>> | ReturnType<typeof createFileInput<Name>> | ReturnType<typeof createDateInput<Name>> | ReturnType<typeof createLexicalInput<Name>> | ReturnType<typeof createSelectInput<Name>> | ReturnType<typeof createRadioInput<Name>> | ReturnType<typeof createObjectInput<Name>> | ReturnType<typeof createTagsInput<Name>> | ReturnType<typeof createSlotInput<Name>> | ReturnType<typeof createContentEntryInput<Name>>;
|
|
3
3
|
/**
|
|
4
4
|
* TypeScript Overload Resolution and Input Factory Design
|
|
5
5
|
*
|
|
@@ -122,4 +122,12 @@ export declare function createSlotInput<TName extends string>(input: {
|
|
|
122
122
|
export declare function createSlotInput<TName extends string>(input: Omit<SlotInput, "type" | "name">): SlotInput & {
|
|
123
123
|
name: TName;
|
|
124
124
|
};
|
|
125
|
+
export declare function createContentEntryInput<TName extends string>(input: {
|
|
126
|
+
name: TName;
|
|
127
|
+
} & Omit<ContentEntryInput, "type" | "name">): ContentEntryInput & {
|
|
128
|
+
name: TName;
|
|
129
|
+
};
|
|
130
|
+
export declare function createContentEntryInput<TName extends string>(input: Omit<ContentEntryInput, "type" | "name">): ContentEntryInput & {
|
|
131
|
+
name: TName;
|
|
132
|
+
};
|
|
125
133
|
export declare function createInput(input: ComponentInput): ComponentInput;
|