Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions src/handlers/componentInstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import catchLater from '../util/catchLater';
*/
export default async function componentInstall(
name: string,
{ force, all }: InstallComponentHandlerOptions
{ force, all, componentSet }: InstallComponentHandlerOptions
): Promise<void> {
const emulsifyConfig = await getEmulsifyConfig();
if (!emulsifyConfig) {
Expand Down Expand Up @@ -89,10 +89,10 @@ export default async function componentInstall(
);
}

if (!name && !all) {
if (!name && !all && !componentSet) {
return log(
'error',
'Please specify a component to install, or pass --all to install all available components.'
'Please specify a component to install, or library name through option --component-set, or pass --all to install all available components.'
);
}

Expand All @@ -114,11 +114,34 @@ export default async function componentInstall(
])
);
}
// Pull library marked modules.
else if (componentSet) {
const parentComponents = variantConf.components
.filter((component) => component.componentSet?.includes(componentSet))
.map((component) => component.name);
const componentsWithDependencies = buildComponentDependencyList(
variantConf.components,
parentComponents
);
componentsWithDependencies.forEach((componentName) => {
components.push([
componentName,
catchLater(
installComponentFromCache(
systemConf,
variantConf,
componentName,
force
)
),
]);
});
}
// If there is only one component to install, add one single promise for the single component.
else {
const componentsWithDependencies = buildComponentDependencyList(
variantConf.components,
name
[name]
);
componentsWithDependencies.forEach((componentName) => {
components.push([
Expand Down
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ component
'-a --all',
'Use this to install all available components, rather than specifying a single component to install'
)
.option(
'-cs --component-set <setname>',
'Use this to Install a pre-defined set of related components from your component library'
)
.alias('i')
.description(
"Install a component from within the current project's system and variant"
Expand Down
7 changes: 7 additions & 0 deletions src/schemas/variant.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@
"items": {
"type": "string"
}
},
"componentSet": {
"type": "array",
"description": "List of all component library to which this component belonning to and should be installed as part of library",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
Expand Down
4 changes: 4 additions & 0 deletions src/types/_system.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ export interface EmulsifySystem {
* Array containing list of all components from which depends current conponent
*/
dependency?: string[];
/**
* List of all component library to which this component belonning to and should be installed as part of library
*/
componentSet?: string[];
}[];
/**
* Array containing objects that define general directories. These directories should contain files and assets that do not belong in a structure folder (such as font files)
Expand Down
4 changes: 4 additions & 0 deletions src/types/_variant.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export type Components = {
* Array containing list of all components from which depends current conponent
*/
dependency?: string[];
/**
* List of all component library to which this component belonning to and should be installed as part of library
*/
componentSet?: string[];
}[];
/**
* Array containing objects that define general directories. These directories should contain files and assets that do not belong in a structure folder (such as font files)
Expand Down
1 change: 1 addition & 0 deletions src/types/handlers.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ declare module '@emulsify-cli/handlers' {
export type InstallComponentHandlerOptions = {
force?: boolean;
all?: boolean;
componentSet: string;
};
}
14 changes: 10 additions & 4 deletions src/util/project/buildComponentDependencyList.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@ describe('buildComponentDependencyList', () => {
] as Components;

it('Build list of components without dependency', () => {
expect(buildComponentDependencyList(components, 'buttons')).toEqual([
expect(buildComponentDependencyList(components, ['buttons'])).toEqual([
'buttons',
]);
});

it('Build all components dependency for not existing component', () => {
expect(buildComponentDependencyList(components, 'test')).toEqual([]);
expect(buildComponentDependencyList(components, ['test'])).toEqual([]);
});

it('Build all components dependency tree returning flat list without duplicates', () => {
expect(buildComponentDependencyList(components, 'card')).toEqual([
expect(buildComponentDependencyList(components, ['card'])).toEqual([
'card',
'images',
'text',
Expand All @@ -56,11 +56,17 @@ describe('buildComponentDependencyList', () => {
});

it('Build all components dependency tree with hierarchical dependency', () => {
expect(buildComponentDependencyList(components, 'menus')).toEqual([
expect(buildComponentDependencyList(components, ['menus'])).toEqual([
'menus',
'images',
'text',
'links',
]);
});

it('Build all components dependency tree for 2 components', () => {
expect(buildComponentDependencyList(components, ['menus', 'card'])).toEqual(
['menus', 'card', 'images', 'text', 'links', 'buttons']
);
});
});
38 changes: 20 additions & 18 deletions src/util/project/buildComponentDependencyList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,28 @@ import type { Components } from '@emulsify-cli/config';

export default function buildComponentDependencyList(
components: Components,
name: string
componentsList: string[]
) {
const rootComponent = components.filter(
(component) => component.name == name
const rootComponents = components.filter((component) =>
componentsList.includes(component.name)
);
if (rootComponent.length == 0) return [];
let finalList = [name];
if (rootComponent.length > 0) {
const list = rootComponent[0].dependency as string[];
if (list && list.length > 0) {
list.forEach((componentName: string) => {
finalList = [
...new Set(
finalList.concat(
buildComponentDependencyList(components, componentName)
)
),
];
});
}
if (rootComponents.length == 0) return [];
let finalList = [...componentsList];
if (rootComponents.length > 0) {
rootComponents.forEach((rootComponent) => {
const list = rootComponent.dependency as string[];
if (list && list.length > 0) {
list.forEach((componentName: string) => {
finalList = [
...new Set(
finalList.concat(
buildComponentDependencyList(components, [componentName])
)
),
];
});
}
});
}
return finalList;
}