@sap/cds
Version:
SAP Cloud Application Programming Model - CDS for Node.js
154 lines (137 loc) • 9.04 kB
JavaScript
if (process.env.CDS_STRICT_NODE_VERSION !== 'false') require('./utils/version').check()
! (global.__cds_loaded_from ??= new Set).add(__filename.toLowerCase()) // track from where we loaded cds, lowercase to avoid path duplicates on Windows
const { AsyncLocalStorage } = require ('async_hooks')
const context = new AsyncLocalStorage
const { EventEmitter } = require('node:events')
const cds = exports = module.exports = global.cds = new class cds extends EventEmitter {
/** Contexts and Transactions @type {import('./req/context.js')} */
get context() { return context.getStore() }
set context(x) { this._with(x) }
_with (x,fn,...args) {
const ctx = typeof x !== 'object' || x instanceof exports.EventContext ? x : x.context || exports.EventContext.for(x)
return fn ? context.run (ctx,fn,...args) : context.enterWith (ctx)
}
get spawn() { return super.spawn = require('./req/spawn.js') }
/** @import {LinkedCSN} from './core/linked-csn.js' */
/** @import {Service} from './srv/cds.Service.js' */
/** @type LinkedCSN */ model = undefined
/** @type Service */ db = undefined
/** CLI args */ cli = { command:'', options:{}, argv:[] }
/** Working dir */ root = process.cwd()
emit (eve, ...args) {
if (eve === 'served') return this.listeners(eve) .reduce (
(p,each) => p.then(()=> each.call(this,...args)),
Promise.resolve()
)
else return super.emit (eve, ...args)
}
// Configuration & Information
get requires() { return super.requires = this.env.requires._resolved() }
get plugins() { return super.plugins = require('./plugins.js').activate() }
get version() { return super.version = require('../package.json').version }
get env() { return super.env = require('./env/cds-env.js').for(this) }
get home() { return super.home = __dirname.slice(0,-4) }
get schema() { return super.schema = require('./env/schemas/index.js') } // REVISIT: Better move that to cds-dk?
// Loading and Compiling Models
get compiler() { return super.compiler = require('./compile/cdsc.js') }
get compile() { return super.compile = require('./compile/cds-compile.js') }
get resolve() { return super.resolve = require('./compile/resolve.js') }
get load() { return super.load = require('./compile/load.js') }
get get() { return super.get = this.load.parsed }
get parse() { return super.parse = require('./compile/parse.js') }
get minify() { return super.minify = require('./compile/minify.js') }
get extend() { return super.extend = require('./compile/extend.js') }
get deploy() { return super.deploy = require('./dbs/cds-deploy.js') }
get localize() { return super.localize = require('./i18n/localize.js') }
get i18n() { return super.i18n = require('./i18n/index.js') }
// Model Reflection, Builtin types and classes
get entities() { return this.db?.entities || this.model?.entities }
get reflect() { return super.reflect = this.linked }
get linked() { return super.linked = require('./core/linked-csn.js') }
get builtin() { return super.builtin = require('./core/types.js') }
get Association() { return super.Association = this.builtin.classes.Association }
get Composition() { return super.Composition = this.builtin.classes.Composition }
get entity() { return super.entity = this.builtin.classes.entity }
get event() { return super.event = this.builtin.classes.event }
get type() { return super.type = this.builtin.classes.type }
get array() { return super.array = this.builtin.classes.array }
get struct() { return super.struct = this.builtin.classes.struct }
get service() { return super.service = Object.assign (this.builtin.classes.service, {
/** @param {( this:Service, srv:Service )} fn */ impl: fn => fn,
/** @type Service[] */ providers: []
})}
// Providing and Consuming Services
/** @type { Record<string,Service> } */ services = new class {
*[Symbol.iterator](){ for (let e in this) yield this[e] }
}
get server() { return super.server = require('../server.js') }
get serve() { return super.serve = require('./srv/cds-serve.js') }
get connect() { return super.connect = require('./srv/cds-connect.js') }
get outboxed() { return this.queued }
get unboxed() { return this.unqueued }
get queued() { return super.queued = require('../libx/queue/index.js').queued }
get unqueued() { return super.unqueued = require('../libx/queue/index.js').unqueued }
get middlewares() { return super.middlewares = require('./srv/middlewares/index.js') }
get odata() { return super.odata = require('../libx/odata/index.js') }
get auth() { return super.auth = require('./auth.js') }
shutdown() { this.app?.server && process.exit() } // is overridden in bin/serve.js
// Core Services API
get Service() { return super.Service = require('./srv/cds.Service.js') }
get EventContext() { return super.EventContext = require('./req/context.js') }
get Request() { return super.Request = require('./req/request.js') }
get Event() { return super.Event = require('./req/event.js') }
get User() { return super.User = require('./req/user.js') }
get validate() { return super.validate = require('./req/validate.js') }
// Services, Protocols and Periphery
get ApplicationService() { return super.ApplicationService = require('../srv/app-service.js') }
get MessagingService() { return super.MessagingService = require('../srv/msg-service.js') }
get DatabaseService() { return super.DatabaseService = require('../srv/db-service.js') }
get RemoteService() { return super.RemoteService = require('../srv/remote-service.js') }
// Helpers
get utils() { return super.utils = require('./utils/cds-utils.js') }
get error() { return super.error = require('./log/cds-error.js') }
get exec() { return super.exec = require('../bin/serve.js').exec }
get test() { return super.test = require('./test/cds-test.js') }
get log() { return super.log = require('./log/cds-log.js') }
get debug() { return super.debug = this.log.debug }
clone(x) { return structuredClone(x) }
// Querying and Databases
get infer(){ return super.infer = require('./ql/cds.ql-infer.js') }
get txs() { return super.txs = new this.Service('cds.tx') }
get ql() { return super.ql = require('./ql/cds-ql.js') }
// get tx() { return super.tx = this.Service.prototype.tx.bind (new this.Service) } // Note: this would break too much of existing code/tests
tx (..._) { return (this.db || this.txs).tx(..._) }
run (..._) { return (this.db || typeof _[0] === 'function' && this.txs || this.error._no_primary_db).run(..._) }
foreach (..._) { return (this.db || this.error._no_primary_db).foreach(..._) }
read (..._) { return (this.db || this.error._no_primary_db).read(..._) }
create (..._) { return (this.db || this.error._no_primary_db).create(..._) }
insert (..._) { return (this.db || this.error._no_primary_db).insert(..._) }
update (..._) { return (this.db || this.error._no_primary_db).update(..._) }
upsert (..._) { return (this.db || this.error._no_primary_db).upsert(..._) }
delete (..._) { return (this.db || this.error._no_primary_db).delete(..._) }
disconnect (..._) { return (this.db || this.error._no_primary_db).disconnect(..._) }
// Deprecated stuff to be removed in upcomming releases...
/** @deprecated */ get lazified() { return this.lazify }
/** @deprecated */ get lazify() { return super.lazify = require('./utils/lazify.js') }
/** @deprecated */ get in() { return super.in = cwd => !cwd ? this : {__proto__:this, cwd, env: this.env.for('cds',cwd) } }
/** @deprecated */ exit(code){ return this.app?.server ? this.shutdown() : process.exit(code) }
/** @deprecated */ transaction (..._) { return (this.db||this.error._no_primary_db).transaction(..._) }
}
// Add global convenience shortcuts for cds.ql and cds.parse commands
cds.extend (global) .with ( class globals {
get SELECT() { return Q('SELECT') }
get INSERT() { return Q('INSERT') }
get UPSERT() { return Q('UPSERT') }
get UPDATE() { return Q('UPDATE') }
get DELETE() { return Q('DELETE') }
/** @deprecated */ get CREATE() { return D('CREATE', '{CREATE} = cds.ql', cds.ql.CREATE) }
/** @deprecated */ get DROP() { return D('DROP', '{DROP} = cds.ql', cds.ql.DROP) }
/** @deprecated */ get CDL() { return D('CDL', 'cds.parse.cdl', cds.parse.cdl) }
/** @deprecated */ get CQL() { return D('CQL', 'cds.parse.cql', cds.parse.cql) }
/** @deprecated */ get CXL() { return D('CXL', 'cds.parse.expr', cds.parse.expr) }
} .prototype )
function Q (p) { return G (p, cds.ql[p]) }
function D (old,use,fn) { return G (old, cds.utils.deprecated (fn,{kind:'Global constant',old,use})) }
function G (p,v) { Object.defineProperty (global, p, { value:v, enumerable:1,configurable:1}); return v }
// Allow for `import cds from '@sap/cds'` without `esModuleInterop` in tsconfig.json
Object.defineProperties (exports, { default: {value:cds}, __esModule: {value:true} })