UNPKG

@sap/cds-dk

Version:

Command line client and development toolkit for the SAP Cloud Application Programming Model

76 lines (65 loc) 3.6 kB
const path = require('path') const cds = require('../../cds') const { DEFAULT_CSN_FILE_NAME } = require('../constants') const { getI18nDefaultFolder, filterFeaturePaths } = require('../util') module.exports = class FeatureTogglesBuildPlugin extends require('./internal') { async compileAll(csn, destBase, destFts) { const sources = filterFeaturePaths(csn, this.task.options.model || this.task.src) const dictionary = { base: null, features: null } if (sources.features) { // create base model as the given CSN is containing all features dictionary.base = await cds.load(sources.base, this.options()) } else { // CSN already represents the base model as no features exist dictionary.base = csn } // preserve @location as @source properties const csnStr = await this.compileToJson(dictionary.base, path.join(destBase, DEFAULT_CSN_FILE_NAME)) const csnModel = JSON.parse(csnStr) csnModel.meta = csn.meta if (sources.features) { dictionary.features = await this._compileFeatures(sources.features, destBase, destFts, dictionary.base) } return { dictionary, sources } } async collectAllLanguageBundles(dictionary, paths, destBase, destFts) { const i18nFolder = getI18nDefaultFolder() const ftsName = path.dirname(cds.env.features.folders || 'fts/*') // create language bundle for base model await this.collectLanguageBundles(dictionary.base, path.join(destBase, i18nFolder)) if (dictionary.features) { // create language bundles for all features const featureBundleTasks = Object.keys(dictionary.features).map(async ftName => { // attach the sources information for i18n location reference dictionary.features[ftName]['$sources'] = paths.features[ftName] await this.collectLanguageBundles(dictionary.features[ftName], path.join(destFts, ftsName, ftName, i18nFolder)) }) await Promise.all(featureBundleTasks) } } async _compileFeatures(ftsPaths, destBase, destFts, baseCsn) { if (!ftsPaths) { return } const features = {} const options = { ...this.options(), flavor: 'parsed' } const ftsName = path.dirname(cds.env.features.folders || 'fts/*') // create feature models await Promise.all(Object.keys(ftsPaths).map(async ftName => { const ftCsn = await cds.load(ftsPaths[ftName], options) const ftPath = path.join(destFts, ftsName, ftName) // replace require paths by base model path to ensure precedence of feature annotations // see https://pages.github.tools.sap/cap/docs/cds/compiler-messages#anno-duplicate-unrelated-layer ftCsn.requires = [path.join(path.relative(ftPath, destBase), DEFAULT_CSN_FILE_NAME).replace(/\\/g, '/')] await this.compileToJson(ftCsn, path.join(ftPath, DEFAULT_CSN_FILE_NAME)) this._validateFeature(ftCsn, baseCsn) features[ftName] = ftCsn })) return features } _validateFeature(ftCsn, baseCsn) { // features must not have other dependencies than base model dependencies - cross feature dependencies are not supported // assuming only core compiler options are relevant for validation scenario cds.compiler.compileSources({ [ftCsn.requires[0]]: baseCsn, 'feature.csn': ftCsn }, { ...super.options(), ...cds.env.cdsc ?? {} }) } }