@lcem/declarative-ui-generator
Advanced tools
Comparing version 0.6.6 to 0.6.7
@@ -6,10 +6,13 @@ # Change Log | ||
## [0.6.6](https://github.com/salesforce/low-code-experience-model/compare/v0.6.5...v0.6.6) (2021-05-19) | ||
## [0.6.7](https://github.com/salesforce/low-code-experience-model/compare/v0.6.6...v0.6.7) (2021-05-20) | ||
**Note:** Version bump only for package @lcem/declarative-ui-generator | ||
### Features | ||
* configure editor with data provider @W-9185978 ([#22](https://github.com/salesforce/low-code-experience-model/issues/22)) ([14c392c](https://github.com/salesforce/low-code-experience-model/commit/14c392c06cc26d0cc29c20a358758f0c047551bc)) | ||
# [0.6.0](https://git.soma.salesforce.com/BuilderFramework/canonical-ui-metadata/compare/v0.5.6...v0.6.0) (2021-03-29) | ||
@@ -16,0 +19,0 @@ |
@@ -1,91 +0,1 @@ | ||
export type ViewMetadataSchema = | ||
| ComponentWithNoRegion | ||
| ComponentWithRegionMap | ||
| ComponentWithComponentArray; | ||
export type ComponentWithNoRegion = Component & { | ||
[k: string]: any; | ||
}; | ||
export type JSONSchemaMetaSchema = CoreSchemaMetaSchema | boolean; | ||
export type ComponentWithRegionMap = Component & { | ||
regions: RegionMap; | ||
[k: string]: any; | ||
}; | ||
export type ComponentArray = [ViewMetadataSchema, ...ViewMetadataSchema[]]; | ||
export type ComponentWithComponentArray = Component & { | ||
components: ComponentArray; | ||
[k: string]: any; | ||
}; | ||
export interface Component { | ||
label?: string; | ||
description?: string; | ||
name?: string; | ||
definition?: string; | ||
schema?: JSONSchemaMetaSchema; | ||
properties?: { | ||
[k: string]: any; | ||
}; | ||
[k: string]: any; | ||
} | ||
export interface CoreSchemaMetaSchema { | ||
$id?: string; | ||
$schema?: string; | ||
$ref?: string; | ||
title?: string; | ||
description?: string; | ||
default?: any; | ||
examples?: any[]; | ||
multipleOf?: number; | ||
maximum?: number; | ||
exclusiveMaximum?: number; | ||
minimum?: number; | ||
exclusiveMinimum?: number; | ||
maxLength?: number; | ||
minLength?: number; | ||
pattern?: string; | ||
additionalItems?: JSONSchemaMetaSchema; | ||
items?: JSONSchemaMetaSchema | JSONSchemaMetaSchema[]; | ||
maxItems?: number; | ||
minItems?: number; | ||
uniqueItems?: boolean; | ||
contains?: JSONSchemaMetaSchema; | ||
maxProperties?: number; | ||
minProperties?: number; | ||
required?: string[]; | ||
additionalProperties?: JSONSchemaMetaSchema; | ||
definitions?: { | ||
[k: string]: JSONSchemaMetaSchema; | ||
}; | ||
properties?: { | ||
[k: string]: JSONSchemaMetaSchema; | ||
}; | ||
patternProperties?: { | ||
[k: string]: JSONSchemaMetaSchema; | ||
}; | ||
dependencies?: { | ||
[k: string]: JSONSchemaMetaSchema | string[]; | ||
}; | ||
propertyNames?: JSONSchemaMetaSchema; | ||
const?: any; | ||
enum?: [any, ...any[]]; | ||
type?: | ||
| ('array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string') | ||
| ('array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string')[]; | ||
format?: string; | ||
allOf?: JSONSchemaMetaSchema[]; | ||
anyOf?: JSONSchemaMetaSchema[]; | ||
oneOf?: JSONSchemaMetaSchema[]; | ||
not?: JSONSchemaMetaSchema; | ||
[k: string]: any; | ||
} | ||
export interface RegionMap { | ||
[k: string]: Region; | ||
} | ||
/** | ||
* This interface was referenced by `RegionMap`'s JSON-Schema definition | ||
* via the `patternProperty` "^.+$". | ||
*/ | ||
export interface Region { | ||
components?: ComponentArray; | ||
[k: string]: any; | ||
} | ||
export interface Slots<C> { | ||
@@ -103,27 +13,2 @@ [name: string]: C[]; | ||
} | ||
export interface LWCPropertyDefinition { | ||
type?: string; | ||
access: 'global'; | ||
required?: boolean; | ||
default?: boolean; | ||
description?: string; | ||
} | ||
export interface LWCComponentDefinition { | ||
descriptor: string; | ||
properties: LWCComponentProperties; | ||
slots: string[]; | ||
} | ||
export interface LWCComponentProperties { | ||
[name: string]: LWCPropertyDefinition; | ||
} | ||
export declare function createLWCComponentDefinitionBuilder(descriptor: string): LWCComponentDefinitionBuilder; | ||
declare class LWCComponentDefinitionBuilder { | ||
private readonly descriptor; | ||
private properties; | ||
private slots; | ||
constructor(descriptor: string); | ||
property(name: string): this; | ||
slot(name: string): this; | ||
build(): LWCComponentDefinition; | ||
} | ||
export declare type ComponentInstances = Slots<LWCComponentInstance>; | ||
@@ -136,3 +21,3 @@ export interface LWCComponentInstance extends MayContainOtherComponents<LWCComponentInstance> { | ||
export interface ComponentResolver<C extends MayContainOtherComponents<C>> { | ||
resolve(component: ViewMetadataSchema): ComponentDefinition<C> | null; | ||
resolve(component: any): ComponentDefinition<C> | null; | ||
} | ||
@@ -142,4 +27,29 @@ export declare class ComponentResolverChain<C> implements ComponentResolver<C> { | ||
constructor(resolvers: ComponentResolver<C>[]); | ||
resolve(component: ViewMetadataSchema): ComponentDefinition<C> | null; | ||
resolve(component: any): ComponentDefinition<C> | null; | ||
} | ||
export declare type Expression = string; | ||
export declare type JsonValue = null | undefined | string | boolean | number | JsonValue[] | { | ||
[key: string]: JsonValue; | ||
}; | ||
export interface DataProvider { | ||
type: string; | ||
properties: Record<string, JsonValue | Expression>; | ||
} | ||
export interface Region { | ||
components: Component[]; | ||
} | ||
export interface Component { | ||
definition: string; | ||
properties?: Record<string, JsonValue | Expression>; | ||
dataProviders?: Record<string, DataProvider>; | ||
regions?: Record<string, Region>; | ||
components?: Component[]; | ||
} | ||
export declare type View = Component; | ||
export interface DataProviderInstance { | ||
getData(): JsonValue; | ||
} | ||
export interface DataProviderInstanceProvider { | ||
getDataProviderInstance(definition: string, properties: Record<string, JsonValue>): Promise<DataProviderInstance>; | ||
} | ||
export interface UiGenerationResult<C extends MayContainOtherComponents<C>> { | ||
@@ -149,13 +59,4 @@ component?: C; | ||
} | ||
export declare function generateLWC(document: ViewMetadataSchema, resolver?: ComponentResolver<LWCComponentInstance>): UiGenerationResult<LWCComponentInstance>; | ||
export declare function generateUi<Ui extends MayContainOtherComponents<Ui>>(document: ViewMetadataSchema, resolver?: ComponentResolver<Ui>): UiGenerationResult<Ui>; | ||
export interface LWCDefinitionLookup { | ||
[definition: string]: LWCComponentDefinition; | ||
} | ||
export declare class LWCComponentDefinitionBasedResolver implements ComponentResolver<LWCComponentInstance> { | ||
private readonly definitions; | ||
constructor(definitions: LWCDefinitionLookup); | ||
resolve({ definition }: ViewMetadataSchema): ComponentDefinition<LWCComponentInstance> | null; | ||
} | ||
export declare function generateLWCAsync(view: View, dataProviderInstanceProvider: DataProviderInstanceProvider, resolver?: ComponentResolver<LWCComponentInstance>): Promise<UiGenerationResult<LWCComponentInstance>>; | ||
export {}; |
@@ -1,82 +0,12 @@ | ||
function createLWCComponentDefinitionBuilder(descriptor) { | ||
return new LWCComponentDefinitionBuilder(descriptor); | ||
} | ||
class LWCComponentDefinitionBuilder { | ||
constructor(descriptor) { | ||
this.properties = {}; | ||
this.slots = []; | ||
this.descriptor = descriptor; | ||
} | ||
property(name) { | ||
this.properties[name] = { access: 'global' }; | ||
return this; | ||
} | ||
slot(name) { | ||
this.slots.push(name); | ||
return this; | ||
} | ||
build() { | ||
return { descriptor: this.descriptor, properties: this.properties, slots: this.slots }; | ||
} | ||
} | ||
import { ViewReducer, isExpression, extract } from '@lcem/unified-experience-model'; | ||
const AccordionDef = createLWCComponentDefinitionBuilder('lightning-accordion') | ||
.property('active-section-name') | ||
.property('allow-multiple-sections-open') | ||
.property('title') | ||
.slot('default') | ||
.build(); | ||
const AccordionSectionDef = createLWCComponentDefinitionBuilder('lightning-accordion-section') | ||
.property('label') | ||
.property('name') | ||
.property('title') | ||
.slot('actions') | ||
.slot('default') | ||
.build(); | ||
const TabsetDef = createLWCComponentDefinitionBuilder('lightning-tabset') | ||
.property('active-tab-value') | ||
.property('title') | ||
.property('variant') | ||
.slot('default') | ||
.build(); | ||
const TabDef = createLWCComponentDefinitionBuilder('lightning-tab') | ||
.property('label') | ||
.slot('default') | ||
.build(); | ||
const DivDef = createLWCComponentDefinitionBuilder('div').build(); | ||
function create({ descriptor }, properties, slots) { | ||
// check properties against attributes | ||
return { | ||
descriptor, | ||
properties, | ||
slots | ||
}; | ||
} | ||
const resolution = { | ||
'lightning/accordion': AccordionDef, | ||
'lightning/accordionSection': AccordionSectionDef, | ||
'lightning/tabset': TabsetDef, | ||
'lightning/tab': TabDef, | ||
'lightning/verticalLayout': DivDef | ||
}; | ||
class LWCComponentDefinitionBasedResolver { | ||
constructor(definitions) { | ||
this.definitions = definitions; | ||
} | ||
class LWCComponentResolver { | ||
resolve({ definition }) { | ||
const def = definition && this.definitions[definition]; | ||
return def ? new LWCDefinition(def) : null; | ||
return { | ||
create: (properties, slots) => { | ||
return { descriptor: definition, properties, slots }; | ||
} | ||
}; | ||
} | ||
} | ||
const LWCDefaultResolver = new LWCComponentDefinitionBasedResolver(resolution); | ||
class LWCDefinition { | ||
constructor(definition) { | ||
this.definition = definition; | ||
} | ||
create(properties, slots) { | ||
return create(this.definition, properties, slots); | ||
} | ||
} | ||
@@ -103,38 +33,79 @@ class ComponentResolverChain { | ||
function generateLWC(document, resolver = new NoopResolver()) { | ||
return generateUi(document, new ComponentResolverChain([resolver, LWCDefaultResolver])); | ||
/** | ||
* This transforms a view in UEM to an LWC component instance. | ||
* Please see ViewReducer for traversal of the component tree. | ||
* */ | ||
class LwcViewReducer extends ViewReducer { | ||
constructor(resolver, dataProviderInstanceProvider) { | ||
super(new LwcComponentPropertyReducer(), new LwcRegionReducer(), new LwcComponentReducer(resolver), new LwcDataProviderReducer(dataProviderInstanceProvider)); | ||
} | ||
} | ||
function generateUi(document, resolver = new NoopResolver()) { | ||
// const ajv = new Ajv(); | ||
// if (!ajv.validate(SCHEMA, document)) { | ||
// return { errors: ajv.errors }; | ||
// } | ||
try { | ||
return { component: traverse(document, resolver) }; | ||
/** | ||
* This component reducer transforms a component of Unified View Model into an LWC component instance. | ||
* */ | ||
class LwcComponentReducer { | ||
constructor(resolver) { | ||
this.resolver = resolver; | ||
} | ||
catch (e) { | ||
return { errors: [e] }; | ||
getChildrenReducer() { | ||
return undefined; | ||
} | ||
reduce(context, definition, properties, regions) { | ||
const componentDefinition = this.resolver.resolve({ definition, properties }); | ||
if (componentDefinition) { | ||
const instance = componentDefinition.create(properties, regions); | ||
return Promise.resolve(instance); | ||
} | ||
throw new Error(`Unresolved component: ${definition}`); | ||
} | ||
} | ||
function traverse(component, resolver) { | ||
const { regions: regionMap, components, properties, ...rest } = component; | ||
const definition = resolver.resolve(component); | ||
if (!definition) { | ||
throw new Error(`Fail to resolve component ${JSON.stringify(rest)}`); | ||
/** | ||
* It gets the data provider instance and calls to get the data. | ||
* */ | ||
class LwcDataProviderReducer { | ||
constructor(dataProviderInstanceProvider) { | ||
this.dataProviderInstanceProvider = dataProviderInstanceProvider; | ||
} | ||
// normalization | ||
const regions = regionMap | ||
? regionMap | ||
: components | ||
? { default: { components } } | ||
: {}; | ||
const slots = Object.keys(regions).reduce((slots, name) => { | ||
const { components } = regions[name]; | ||
// components always there due to normalization | ||
slots[name] = components.map((component) => traverse(component, resolver)); | ||
return slots; | ||
async reduce(context, name, type, properties) { | ||
const dataProviderInstance = await this.dataProviderInstanceProvider.getDataProviderInstance(type, resolveExpressions(properties, context)); | ||
return Promise.resolve(dataProviderInstance.getData()); | ||
} | ||
} | ||
class LwcRegionReducer { | ||
reduce(context, name, components) { | ||
return components; | ||
} | ||
} | ||
/** | ||
* It resolves the value of a property down to a json value if it is an expression. | ||
* */ | ||
class LwcComponentPropertyReducer { | ||
reduce(context, name, value) { | ||
return resolveExpression(value, context.flatten()); | ||
} | ||
} | ||
function resolveExpressions(properties, context) { | ||
return Object.keys(properties).reduce((resolved, key) => { | ||
resolved[key] = resolveExpression(properties[key], context.flatten()); | ||
return resolved; | ||
}, {}); | ||
return definition.create(properties || {}, slots); | ||
} | ||
function resolveExpression(value, context) { | ||
if (isExpression(value)) { | ||
return extract(context, value); | ||
} | ||
return value; | ||
} | ||
export { ComponentResolverChain, LWCComponentDefinitionBasedResolver, createLWCComponentDefinitionBuilder, generateLWC, generateUi }; | ||
async function generateLWCAsync(view, dataProviderInstanceProvider, resolver = new NoopResolver()) { | ||
const viewReducer = new LwcViewReducer(new ComponentResolverChain([resolver, new LWCComponentResolver()]), dataProviderInstanceProvider); | ||
try { | ||
const component = await viewReducer.reduce(view); | ||
return { component }; | ||
} | ||
catch (e) { | ||
return Promise.resolve({ errors: [e] }); | ||
} | ||
} | ||
export { ComponentResolverChain, generateLWCAsync }; |
@@ -5,5 +5,6 @@ { | ||
"license": "MIT", | ||
"version": "0.6.6", | ||
"version": "0.6.7", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"type": "module", | ||
"publishConfig": { | ||
@@ -27,5 +28,5 @@ "access": "public" | ||
"dependencies": { | ||
"@lcem/canonical-ui-metadata-schema": "0.6.6", | ||
"@lcem/unified-experience-model": "0.6.7", | ||
"ajv": "^6.12.0" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Yes
9635
162
1
+ Added@lcem/unified-experience-model@0.6.7(transitive)
- Removed@lcem/canonical-ui-metadata-schema@0.6.6(transitive)