@sap/cds-dk
Version:
Command line client and development toolkit for the SAP Cloud Application Programming Model
123 lines (106 loc) • 3.52 kB
JavaScript
const cds = require ('../lib/cds.js')
const { Minifier } = cds.minify; if (!Minifier) throw new Error ('@sap/cds >= 9.4.0 required for this command')
const { Command } = require ('./util/cli.js')
const { inspect } = require ('node:util')
class Minify extends Command {
options = Minify.options // for IntelliSense
static options = {
cleanse: { _excluding: 'keep' },
keep: { _excluding: 'skip',
aspect: false,
entity: true,
event: true,
type: false,
action: true,
function: true,
},
skip: {},
dry: false,
debug: false,
inspect: false,
}
static shortcuts = { skip:'x', dry:'y' }
static filename = __filename
parseArgs (conf) {
let [sources,o] = super.parseArgs (conf)
this.sources = sources.length ? o.from = sources : sources = o.from || '*'
return [sources,o]
}
async exec ( args, options ) {
let [sources,o] = this.parseArgs ({ args, options })
try {
this.csn = await this.load (sources,o)
this.min = await this.minify (this.csn,o)
if (o.dry) return
if (o.inspect) return this.inspect (this.min,o)
else return this.output (this.min,o)
} catch (e) {
if (typeof e === 'string') return console.error (e)
if (e.code) return console.error (e.message)
else throw e
}
}
/**
* Subclasses override this method to provide custom loading behavior.
*/
async load (sources,o) { // eslint-disable-line no-unused-vars
return cds.load (sources)
}
/**
* Subclasses override this method to provide custom cleansing behavior.
*/
async cleanse (csn,o) { // eslint-disable-line no-unused-vars
return csn
}
/**
* Subclasses override this method to provide custom minification behavior.
*/
async minify (csn,o) {
let m = this.minifier ??= o.dry ? (new Dryifier).for(csn) : new Minifier
csn = await this.cleanse (csn,o)
return m.minify (csn,o)
}
/**
* Subclasses override this method to generate exported artifacts.
*/
export (csn,o) {} // eslint-disable-line no-unused-vars
/**
* Subclasses override this method to provide custom print behavior.
*/
output (csn,o) { // eslint-disable-line no-unused-vars
console.log (cds.compile.to.json (csn))
}
inspect (csn, {inspect:depth} = this.options) {
const colors = cds.utils.colors.enabled
console.log (inspect (cds.linked(csn), { depth, colors }))
}
}
/**
* Custom minifier to capture kept definitions in dry run mode
*/
class Dryifier extends Minifier {
for (csn) { this.all = Object.keys (csn.definitions); return this }
capture = {}
level = 0
keep (each,d) {
if (each in this.kept) return
if (each in this.defs) this.capture[each] = ++this.level
super.keep (each, d)
if (each in this.defs) this.level--
}
minify (csn,o) {
const { GREEN, GRAY, DIMMED, RESET } = cds.utils.colors
const min = super.minify (csn, o)
const kept = Object.keys(this.capture)
console.log (RESET+'\n', 'Kept:', kept.length, '\n')
for (let [ each, level ] of Object.entries(this.capture))
console.log (' '+GRAY,'•'.repeat(level)+GREEN, each, RESET)
console.log (RESET+'\n', 'Skipped:', this.all.length - kept.length, '\n')
for (let each of this.all)
each in this.capture || console.log (DIMMED, ' -', each, RESET)
console.log (RESET+'\n', 'Total:', this.all.length, '\n')
return min
}
}
module.exports = Object.assign (Minify._for_cds_dk(), { Minify })