@spartacus/schematics
Version:
Spartacus schematics
219 lines • 12.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.addCmsComponent = void 0;
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
const change_1 = require("@schematics/angular/utility/change");
const constants_1 = require("../shared/constants");
const file_utils_1 = require("../shared/utils/file-utils");
const module_file_utils_1 = require("../shared/utils/module-file-utils");
const workspace_utils_1 = require("../shared/utils/workspace-utils");
function buildComponentModule(options) {
const moduleName = options.module || '';
return Boolean(options.declareCmsModule)
? options.declareCmsModule
: moduleName;
}
function buildDeclaringCmsModule(options) {
return Boolean(options.declareCmsModule)
? options.declareCmsModule
: options.name;
}
function updateModule(options) {
return (tree, context) => {
const rawComponentModule = buildDeclaringCmsModule(options);
const componentModule = `${core_1.strings.dasherize(rawComponentModule)}.module.ts`;
const modulePath = file_utils_1.getPathResultsForFile(tree, componentModule, '/src')[0];
if (!modulePath) {
context.logger.error(`Could not find the ${modulePath}`);
return;
}
const changes = [];
const moduleTs = file_utils_1.getTsSourceFile(tree, modulePath);
if (!ast_utils_1.isImported(moduleTs, constants_1.CONFIG_MODULE_CLASS, constants_1.SPARTACUS_CORE)) {
const insertImportChange = ast_utils_1.insertImport(moduleTs, modulePath, `${constants_1.CONFIG_MODULE_CLASS}`, constants_1.SPARTACUS_CORE, false);
changes.push(insertImportChange);
}
if (!ast_utils_1.isImported(moduleTs, constants_1.CMS_CONFIG, constants_1.SPARTACUS_CORE)) {
const insertImportChange = ast_utils_1.insertImport(moduleTs, modulePath, `${constants_1.CMS_CONFIG}`, constants_1.SPARTACUS_CORE, false);
changes.push(insertImportChange);
}
const componentName = `${core_1.strings.classify(options.name)}${core_1.strings.classify(options.type)}`;
/*** updating the module's metadata start ***/
const addToModuleImportsChanges = module_file_utils_1.addToModuleImports(tree, modulePath, `${constants_1.CONFIG_MODULE_CLASS}.withConfig(<${constants_1.CMS_CONFIG}>{
cmsComponents: {
${componentName}: {
component: ${componentName},
},
},
})`, moduleTs);
changes.push(...addToModuleImportsChanges);
const addToModuleDeclarationsChanges = module_file_utils_1.addToModuleDeclarations(tree, modulePath, componentName, moduleTs);
changes.push(...addToModuleDeclarationsChanges);
const addToModuleExportsChanges = module_file_utils_1.addToModuleExports(tree, modulePath, componentName, moduleTs);
changes.push(...addToModuleExportsChanges);
/*** updating the module's metadata end ***/
const componentImportSkipped = !Boolean(options.declareCmsModule);
if (componentImportSkipped) {
const componentFileName = `${core_1.strings.dasherize(options.name)}.${core_1.strings.dasherize(options.type)}.ts`;
const componentPath = file_utils_1.getPathResultsForFile(tree, componentFileName, '/src')[0];
const componentRelativeImportPath = module_file_utils_1.buildRelativePath(modulePath, componentPath);
const componentImport = ast_utils_1.insertImport(moduleTs, modulePath, componentName, module_file_utils_1.stripTsFromImport(componentRelativeImportPath), false);
changes.push(componentImport);
}
file_utils_1.commitChanges(tree, modulePath, changes, file_utils_1.InsertDirection.RIGHT);
context.logger.info(`Updated ${modulePath}`);
};
}
function updateComponent(options) {
return (tree, _context) => {
if (!options.cmsComponentData) {
return;
}
if (!options.cmsComponentDataModel) {
throw new schematics_1.SchematicsException(`"cmsComponentDataModel" can't be falsy`);
}
const cmsComponentData = `${constants_1.CMS_COMPONENT_DATA_CLASS}<${core_1.strings.classify(options.cmsComponentDataModel)}>`;
const componentFileName = `${core_1.strings.dasherize(options.name)}.${core_1.strings.dasherize(options.type)}.ts`;
const project = workspace_utils_1.getProjectFromWorkspace(tree, options);
const componentPath = file_utils_1.getPathResultsForFile(tree, componentFileName, project.sourceRoot)[0];
const changes = [];
const componentTs = file_utils_1.getTsSourceFile(tree, componentPath);
const nodes = ast_utils_1.getSourceNodes(componentTs);
const constructorNode = file_utils_1.findConstructor(nodes);
const injectionChange = file_utils_1.injectService({
constructorNode,
path: componentPath,
serviceName: cmsComponentData,
modifier: 'private',
propertyName: constants_1.CMS_COMPONENT_DATA_PROPERTY_NAME,
});
changes.push(injectionChange);
const componentDataProperty = ` ${constants_1.CMS_COMPONENT_DATA_PROPERTY_NAME}$: Observable<${core_1.strings.classify(options.cmsComponentDataModel)}> = this.${constants_1.CMS_COMPONENT_DATA_PROPERTY_NAME}.data$;`;
const componentDataPropertyChange = file_utils_1.defineProperty(nodes, componentPath, componentDataProperty);
changes.push(componentDataPropertyChange);
const cmsComponentImport = ast_utils_1.insertImport(componentTs, componentPath, core_1.strings.classify(options.cmsComponentDataModel), module_file_utils_1.stripTsFromImport(options.cmsComponentDataModelPath), false);
changes.push(cmsComponentImport);
const cmsComponentDataImport = ast_utils_1.insertImport(componentTs, componentPath, constants_1.CMS_COMPONENT_DATA_CLASS, constants_1.SPARTACUS_STOREFRONTLIB, false);
changes.push(cmsComponentDataImport);
const observableImport = ast_utils_1.insertImport(componentTs, componentPath, constants_1.OBSERVABLE_CLASS, constants_1.RXJS, false);
changes.push(observableImport);
file_utils_1.commitChanges(tree, componentPath, changes, file_utils_1.InsertDirection.LEFT);
};
}
function updateTemplate(options) {
return (tree, _context) => {
const componentFileName = `${core_1.strings.dasherize(options.name)}.${core_1.strings.dasherize(options.type)}.ts`;
const project = workspace_utils_1.getProjectFromWorkspace(tree, options);
const componentPath = file_utils_1.getPathResultsForFile(tree, componentFileName, project.sourceRoot)[0];
const componentTs = file_utils_1.getTsSourceFile(tree, componentPath);
let templatePath = '';
let templateContent = '';
let startIndex;
if (options.inlineTemplate) {
templatePath = componentPath;
const decorator = ast_utils_1.getDecoratorMetadata(componentTs, 'Component', constants_1.ANGULAR_CORE)[0];
const inlineTemplate = file_utils_1.getMetadataProperty(decorator, 'template');
templateContent = inlineTemplate.getText();
startIndex = inlineTemplate.name.parent.end - 1;
}
else {
const componentTemplateFileName = `${core_1.strings.dasherize(options.name)}.${core_1.strings.dasherize(options.type)}.html`;
templatePath = file_utils_1.getPathResultsForFile(tree, componentTemplateFileName, project.sourceRoot)[0];
const buffer = tree.read(templatePath);
templateContent = buffer ? buffer.toString(constants_1.UTF_8) : '';
startIndex = templateContent.length;
}
if (Boolean(templateContent)) {
const insertion = new change_1.InsertChange(templatePath, startIndex, `<ng-container *ngIf="${constants_1.CMS_COMPONENT_DATA_PROPERTY_NAME}$ | async as data">{{data | json}}</ng-container>`);
file_utils_1.commitChanges(tree, templatePath, [insertion], file_utils_1.InsertDirection.RIGHT);
}
};
}
function declareInModule(options) {
return (tree, context) => {
if (!(options.declareCmsModule && options.module)) {
return;
}
const sourceCmsModule = core_1.basename(options.declareCmsModule);
const sourceCmsModuleFileName = `${core_1.strings.dasherize(sourceCmsModule)}.module.ts`;
const sourceCmsModulePath = file_utils_1.getPathResultsForFile(tree, sourceCmsModuleFileName, '/src')[0];
if (!sourceCmsModulePath) {
context.logger.error(`Could not find the ${sourceCmsModulePath}`);
return;
}
const destinationModuleName = core_1.basename(options.module);
const destinationFileName = `${core_1.strings.dasherize(destinationModuleName)}.module.ts`;
const destinationModulePath = file_utils_1.getPathResultsForFile(tree, destinationFileName, '/src')[0];
if (!destinationModulePath) {
context.logger.error(`Could not find the ${destinationModulePath}`);
return;
}
const sourceCmsModuleRelativeImportPath = module_file_utils_1.buildRelativePath(destinationModulePath, sourceCmsModulePath);
const destinationModuleTs = file_utils_1.getTsSourceFile(tree, destinationModulePath);
const sourceCmsModuleClassified = core_1.strings.classify(sourceCmsModule);
const moduleFileImport = ast_utils_1.insertImport(destinationModuleTs, destinationModulePath, sourceCmsModuleClassified, module_file_utils_1.stripTsFromImport(sourceCmsModuleRelativeImportPath), false);
const moduleImport = module_file_utils_1.addToModuleImports(tree, destinationModulePath, sourceCmsModuleClassified, destinationModuleTs);
const changes = [moduleFileImport, ...moduleImport];
file_utils_1.commitChanges(tree, destinationModulePath, changes, file_utils_1.InsertDirection.LEFT);
};
}
function validateArguments(options) {
if (options.cmsComponentData && !Boolean(options.cmsComponentDataModel)) {
throw new schematics_1.SchematicsException('You have to specify the "cmsComponentDataModel" option.');
}
}
function addCmsComponent(options) {
return (tree, context) => {
validateArguments(options);
// angular's component CLI flags
const { declareCmsModule, export: exportOption, name: componentName, changeDetection, flat, inlineStyle, inlineTemplate, lintFix, prefix, project, selector, skipSelector, type, skipTests, style, viewEncapsulation, } = options;
const componentModule = buildComponentModule(options);
// angular's module CLI flags
const { path, routing, routingScope, route, commonModule, module: declaringModule, } = options;
const createCmsModule = !Boolean(declareCmsModule);
const skipImport = createCmsModule;
return schematics_1.chain([
// we are creating a new module if the declared module is not provided
createCmsModule
? schematics_1.externalSchematic(constants_1.ANGULAR_SCHEMATICS, 'module', {
project,
name: componentName,
path,
routing,
routingScope,
route,
commonModule,
lintFix,
module: declaringModule,
})
: schematics_1.noop(),
schematics_1.externalSchematic(constants_1.ANGULAR_SCHEMATICS, 'component', {
changeDetection,
export: exportOption,
flat,
inlineStyle,
inlineTemplate,
lintFix,
module: componentModule,
name: componentName,
prefix,
project,
selector,
skipSelector,
type,
skipTests,
style,
viewEncapsulation,
skipImport,
}),
updateModule(options),
updateComponent(options),
updateTemplate(options),
!createCmsModule && declaringModule ? declareInModule(options) : schematics_1.noop(),
])(tree, context);
};
}
exports.addCmsComponent = addCmsComponent;
//# sourceMappingURL=index.js.map