UNPKG

@spartacus/schematics

Version:
219 lines 12.5 kB
"use strict"; 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