@sap/cds 6.8.3 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -2
- package/README.md +0 -1
- package/bin/cds-serve.js +50 -3
- package/bin/deploy/to-hana.js +1 -0
- package/bin/serve.js +16 -20
- package/lib/auth/basic-auth.js +6 -4
- package/lib/auth/index.js +4 -3
- package/lib/auth/jwt-auth.js +2 -5
- package/lib/compile/cds-compile.js +34 -89
- package/lib/compile/cdsc.js +11 -0
- package/lib/compile/etc/properties.js +2 -2
- package/lib/compile/for/lean_drafts.js +36 -69
- package/lib/compile/for/nodejs.js +2 -1
- package/lib/compile/load.js +1 -1
- package/lib/compile/minify.js +2 -0
- package/lib/compile/to/csn.js +74 -0
- package/{bin/build/provider/hana/2tabledata.js → lib/compile/to/hdbtabledata.js} +4 -6
- package/lib/compile/to/json.js +1 -1
- package/lib/compile/to/sql.js +8 -6
- package/lib/dbs/cds-deploy.js +174 -114
- package/lib/env/cds-env.js +64 -79
- package/lib/env/cds-requires.js +11 -28
- package/lib/env/defaults.js +13 -3
- package/lib/env/plugins.js +1 -12
- package/lib/env/presets.js +25 -21
- package/lib/index.js +121 -147
- package/lib/{core/reflect.js → linked/models.js} +2 -2
- package/lib/{core/infer.js → linked/queries.js} +2 -0
- package/lib/{core/index.js → linked/types.js} +2 -1
- package/lib/log/cds-error.js +13 -7
- package/lib/log/format/cf.js +1 -1
- package/lib/plugins.js +49 -0
- package/lib/ql/Query.js +0 -9
- package/lib/ql/STREAM.js +0 -1
- package/lib/req/context.js +2 -7
- package/lib/req/request.js +6 -2
- package/lib/req/response.js +23 -10
- package/lib/srv/middlewares/ctx-model.js +1 -1
- package/lib/srv/middlewares/errors.js +1 -1
- package/lib/srv/protocols/_legacy.js +1 -0
- package/lib/srv/protocols/graphql.js +7 -16
- package/lib/srv/protocols/index.js +59 -45
- package/lib/srv/protocols/odata-v2-proxy.js +2 -70
- package/lib/srv/srv-api.js +9 -3
- package/lib/srv/srv-dispatch.js +12 -9
- package/lib/srv/srv-models.js +4 -21
- package/lib/srv/srv-tx.js +15 -12
- package/lib/utils/cds-test.js +14 -9
- package/lib/utils/cds-utils.js +2 -12
- package/lib/utils/check-version.js +17 -0
- package/{bin/build → lib/utils}/csv-reader.js +23 -24
- package/libx/_runtime/auth/index.js +27 -23
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +15 -72
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +0 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +33 -63
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +14 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +5 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +37 -40
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +7 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +101 -38
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/errors/AbstractError.js +5 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +2 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/ResourceJsonDeserializer.js +9 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +15 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +4 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +5 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +1 -123
- package/libx/_runtime/cds-services/services/Service.js +79 -107
- package/libx/_runtime/cds-services/services/utils/columns.js +23 -19
- package/libx/_runtime/cds-services/services/utils/compareJson.js +11 -1
- package/libx/_runtime/cds-services/services/utils/differ.js +7 -2
- package/libx/_runtime/cds-services/util/assert.js +65 -2
- package/libx/_runtime/common/composition/data.js +1 -0
- package/libx/_runtime/common/generic/auth/expand.js +1 -1
- package/libx/_runtime/common/generic/auth/restrict.js +5 -10
- package/libx/_runtime/common/generic/auth/restrictions.js +40 -0
- package/libx/_runtime/common/generic/auth/utils.js +1 -2
- package/libx/_runtime/common/generic/crud.js +32 -16
- package/libx/_runtime/common/generic/etag.js +133 -104
- package/libx/_runtime/common/generic/input.js +6 -21
- package/libx/_runtime/common/generic/put.js +1 -1
- package/libx/_runtime/common/generic/stream.js +52 -0
- package/libx/_runtime/common/generic/temporal.js +25 -8
- package/libx/_runtime/common/i18n/messages.properties +0 -2
- package/libx/_runtime/common/utils/cqn.js +1 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +5 -2
- package/libx/_runtime/common/utils/csn.js +0 -51
- package/libx/_runtime/common/utils/etag.js +30 -0
- package/libx/_runtime/common/utils/keys.js +1 -1
- package/libx/_runtime/common/utils/normalizeTimestamp.js +25 -0
- package/libx/_runtime/common/utils/path.js +1 -1
- package/libx/_runtime/common/utils/resolveView.js +2 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +6 -4
- package/libx/_runtime/common/utils/search2cqn4sql.js +12 -16
- package/libx/_runtime/common/utils/stream.js +140 -0
- package/libx/_runtime/common/utils/streamProp.js +29 -12
- package/libx/_runtime/common/utils/templateProcessorPathSerializer.js +0 -2
- package/libx/_runtime/db/generic/index.js +0 -2
- package/libx/_runtime/db/query/delete.js +2 -2
- package/libx/_runtime/db/query/insert.js +2 -2
- package/libx/_runtime/db/query/read.js +2 -2
- package/libx/_runtime/db/query/run.js +2 -2
- package/libx/_runtime/db/query/update.js +2 -2
- package/libx/_runtime/db/sql-builder/BaseBuilder.js +0 -6
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +23 -12
- package/libx/_runtime/db/sql-builder/FunctionBuilder.js +18 -6
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -0
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +3 -7
- package/libx/_runtime/db/sql-builder/UpsertBuilder.js +1 -0
- package/libx/_runtime/db/utils/normalizeTimeData.js +7 -3
- package/libx/_runtime/fiori/draft.js +2 -0
- package/libx/_runtime/fiori/generic/activate.js +8 -9
- package/libx/_runtime/fiori/generic/before.js +30 -20
- package/libx/_runtime/fiori/generic/cancel.js +5 -3
- package/libx/_runtime/fiori/generic/delete.js +5 -3
- package/libx/_runtime/fiori/generic/edit.js +7 -7
- package/libx/_runtime/fiori/generic/index.js +10 -16
- package/libx/_runtime/fiori/generic/new.js +5 -3
- package/libx/_runtime/fiori/generic/patch.js +11 -8
- package/libx/_runtime/fiori/generic/prepare.js +13 -6
- package/libx/_runtime/fiori/generic/read.js +12 -6
- package/libx/_runtime/fiori/lean-draft.js +207 -152
- package/libx/_runtime/fiori/utils/delete.js +10 -5
- package/libx/_runtime/fiori/utils/req.js +17 -5
- package/libx/_runtime/fiori/utils/stream.js +36 -0
- package/libx/_runtime/hana/Service.js +12 -9
- package/libx/_runtime/hana/conversion.js +10 -15
- package/libx/_runtime/hana/driver.js +2 -0
- package/libx/_runtime/hana/execute.js +28 -6
- package/libx/_runtime/hana/pool.js +36 -122
- package/libx/_runtime/hana/search2cqn4sql.js +34 -36
- package/libx/_runtime/messaging/enterprise-messaging-utils/getTenantInfo.js +2 -6
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +3 -1
- package/libx/_runtime/messaging/enterprise-messaging.js +10 -58
- package/libx/_runtime/messaging/outbox/utils.js +1 -1
- package/libx/_runtime/remote/Service.js +20 -1
- package/libx/_runtime/remote/utils/client.js +3 -5
- package/libx/_runtime/sqlite/Service.js +4 -6
- package/libx/_runtime/sqlite/conversion.js +3 -13
- package/libx/_runtime/sqlite/customBuilder/CustomFunctionBuilder.js +9 -6
- package/libx/_runtime/sqlite/customBuilder/CustomUpsertBuilder.js +6 -1
- package/libx/_runtime/sqlite/execute.js +5 -16
- package/libx/odata/afterburner.js +22 -6
- package/libx/odata/grammar.pegjs +6 -1
- package/libx/odata/parser.js +1 -1
- package/libx/rest/RestAdapter.js +16 -9
- package/libx/rest/RestRequest.js +1 -1
- package/libx/rest/middleware/input.js +2 -1
- package/libx/rest/middleware/operation.js +1 -0
- package/libx/rest/middleware/parse.js +3 -2
- package/libx/rest/middleware/payload.js +9 -8
- package/libx/rest/middleware/read.js +1 -0
- package/package.json +9 -16
- package/app/fiori/preview.js +0 -270
- package/app/fiori/routes.js +0 -59
- package/bin/build/buildTaskEngine.js +0 -360
- package/bin/build/buildTaskFactory.js +0 -283
- package/bin/build/buildTaskHandler.js +0 -241
- package/bin/build/buildTaskProvider.js +0 -22
- package/bin/build/buildTaskProviderFactory.js +0 -175
- package/bin/build/cds.js +0 -5
- package/bin/build/constants.js +0 -66
- package/bin/build/index.js +0 -58
- package/bin/build/provider/buildTaskHandlerEdmx.js +0 -82
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +0 -131
- package/bin/build/provider/buildTaskHandlerInternal.js +0 -254
- package/bin/build/provider/buildTaskProviderInternal.js +0 -383
- package/bin/build/provider/fiori/index.js +0 -171
- package/bin/build/provider/hana/2migration.js +0 -179
- package/bin/build/provider/hana/index.js +0 -505
- package/bin/build/provider/hana/migrationtable.js +0 -472
- package/bin/build/provider/hana/template/.hdiconfig-haas +0 -163
- package/bin/build/provider/hana/template/.hdiconfig-hanacloud +0 -137
- package/bin/build/provider/hana/template/.hdinamespace +0 -4
- package/bin/build/provider/hana/template/package.json +0 -12
- package/bin/build/provider/hana/template/undeploy.json +0 -5
- package/bin/build/provider/java/index.js +0 -111
- package/bin/build/provider/java-cf/index.js +0 -1
- package/bin/build/provider/mtx/index.js +0 -268
- package/bin/build/provider/mtx/resourcesTarBuilder.js +0 -95
- package/bin/build/provider/mtx-extension/index.js +0 -131
- package/bin/build/provider/mtx-sidecar/index.js +0 -137
- package/bin/build/provider/node-cf/index.js +0 -1
- package/bin/build/provider/nodejs/index.js +0 -192
- package/bin/build/util.js +0 -299
- package/bin/cds.js +0 -125
- package/bin/deploy/to-hana/cfUtil.js +0 -355
- package/bin/deploy/to-hana/gitUtil.js +0 -57
- package/bin/deploy/to-hana/hana.js +0 -306
- package/bin/deploy/to-hana/hdiDeployUtil.js +0 -153
- package/bin/deploy/to-hana/index.js +0 -16
- package/bin/deploy/to-hana/mtaUtil.js +0 -170
- package/bin/mtx/in-cds.js +0 -17
- package/bin/plugins.js +0 -32
- package/bin/run.js +0 -24
- package/bin/utils/log.js +0 -24
- package/bin/version.js +0 -178
- package/libx/_runtime/audit/Service.js +0 -222
- package/libx/_runtime/audit/generic/personal/access.js +0 -61
- package/libx/_runtime/audit/generic/personal/index.js +0 -56
- package/libx/_runtime/audit/generic/personal/modification.js +0 -132
- package/libx/_runtime/audit/generic/personal/utils.js +0 -186
- package/libx/_runtime/audit/utils/log.js +0 -23
- package/libx/_runtime/audit/utils/v2.js +0 -176
- package/libx/_runtime/db/data-conversion/timestamp.js +0 -9
- package/libx/_runtime/db/generic/integrity.js +0 -455
- package/srv/audit-log.cds +0 -87
- package/srv/mtx.cds +0 -2
- package/srv/mtx.js +0 -8
- /package/lib/{core → linked}/classes.js +0 -0
- /package/lib/{core → linked}/entities.js +0 -0
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
const cp = require('child_process');
|
|
2
|
-
const os = require('os');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const util = require('util');
|
|
5
|
-
|
|
6
|
-
const fs = require('fs').promises;
|
|
7
|
-
|
|
8
|
-
const { BuildTaskEngine, BuildTaskFactory } = require('../../build');
|
|
9
|
-
const buildConstants = require('../../build/constants');
|
|
10
|
-
|
|
11
|
-
const cfUtil = require('./cfUtil');
|
|
12
|
-
const hdiDeployUtil = require('./hdiDeployUtil');
|
|
13
|
-
const gitUtil = require('./gitUtil');
|
|
14
|
-
const mtaUtil = require('./mtaUtil');
|
|
15
|
-
|
|
16
|
-
const { bold, info } = require('../../utils/term');
|
|
17
|
-
|
|
18
|
-
const IS_WIN = (os.platform() === 'win32');
|
|
19
|
-
const UTF_8 = 'utf-8';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class HanaDeployer {
|
|
23
|
-
|
|
24
|
-
constructor() {
|
|
25
|
-
this.execAsync = util.promisify(cp.exec);
|
|
26
|
-
this.spawnSync = cp.spawnSync;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
getFromEnv(...varNames) {
|
|
30
|
-
const result = {}
|
|
31
|
-
for (const varName of varNames) {
|
|
32
|
-
if (process.env[varName]) {
|
|
33
|
-
try {
|
|
34
|
-
result[varName] = JSON.parse(process.env[varName]);
|
|
35
|
-
} catch (err) {
|
|
36
|
-
throw new Error(`Error parsing environment variable ${varName}`);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return result;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async deploy(model, serviceName, noSave, tunnelAddress, buildTaskOptions, vcapFile, undeployWhitelist, hdiOptions, bindCallback) { // NOSONAR
|
|
44
|
-
hdiOptions = hdiOptions || {}
|
|
45
|
-
|
|
46
|
-
console.log(`${bold('Starting deploy to SAP HANA ...')}`);
|
|
47
|
-
if (vcapFile) {
|
|
48
|
-
console.log(`Using VCAP_SERVICES from file ${vcapFile} (beta feature).`);
|
|
49
|
-
bindCallback = null // credentials are given - no cds bind then
|
|
50
|
-
} else if (bindCallback) {
|
|
51
|
-
console.log('Using cds bind');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const projectPath = path.resolve(process.env._TEST_CWD || process.cwd());
|
|
55
|
-
|
|
56
|
-
const { buildResults } = await this._build(model, buildTaskOptions);
|
|
57
|
-
|
|
58
|
-
let globalVcapEnv = vcapFile ? await this._loadEnvFile(vcapFile) : {};
|
|
59
|
-
globalVcapEnv = { ...globalVcapEnv, ...this.getFromEnv('VCAP_SERVICES', 'SERVICE_REPLACEMENTS') };
|
|
60
|
-
if (process.env.TARGET_CONTAINER) {
|
|
61
|
-
globalVcapEnv.TARGET_CONTAINER = process.env.TARGET_CONTAINER;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
for (const buildResult of buildResults) {
|
|
65
|
-
let vcapEnv = globalVcapEnv;
|
|
66
|
-
let serviceKeyName;
|
|
67
|
-
const currentModelFolder = buildResult.result.dest;
|
|
68
|
-
|
|
69
|
-
if (undeployWhitelist) {
|
|
70
|
-
console.log('Writing undeploy.json');
|
|
71
|
-
await fs.write(path.join(currentModelFolder, 'undeploy.json'), JSON.stringify(undeployWhitelist, null, 2));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const hasVCAPEnv = Object.keys(vcapEnv).length > 0;
|
|
75
|
-
if (!serviceName && hasVCAPEnv) {
|
|
76
|
-
await fs.mkdir(currentModelFolder, { recursive: true });
|
|
77
|
-
} else {
|
|
78
|
-
const { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey } =
|
|
79
|
-
await this._getOrCreateCFService(projectPath, currentModelFolder, serviceName, tunnelAddress);
|
|
80
|
-
serviceKeyName = cfServiceInstanceKeyName;
|
|
81
|
-
serviceName = serviceName || cfServiceInstanceName;
|
|
82
|
-
|
|
83
|
-
vcapEnv = this._getVCAPServicesEntry(cfServiceInstanceName, serviceKey);
|
|
84
|
-
|
|
85
|
-
if (!noSave && !bindCallback) {
|
|
86
|
-
await this._addInstanceToDefaultEnvJson([currentModelFolder, projectPath], cfServiceInstanceName, serviceKey);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Check if deployer is already installed, otherwise only install this one, not the rest of dependencies.
|
|
91
|
-
if (!await hdiDeployUtil.findHdiDeployLib(currentModelFolder)) {
|
|
92
|
-
const { deployerName, deployerVersionSpec } = hdiDeployUtil;
|
|
93
|
-
console.log(`Installing ${deployerName}`);
|
|
94
|
-
|
|
95
|
-
// spawn has not callback and cannot be promisified, using sync instead
|
|
96
|
-
this.spawnSync(`npm`, [`install`, `${deployerName}@${deployerVersionSpec}`, (noSave ? '--no-save' : '--save-dev')], {
|
|
97
|
-
cwd: currentModelFolder,
|
|
98
|
-
shell: IS_WIN,
|
|
99
|
-
stdio: 'inherit',
|
|
100
|
-
env: {
|
|
101
|
-
...process.env,
|
|
102
|
-
NODE_ENV: 'development' // for 'install --save-dev' to work, there must be no 'production' set
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
await hdiDeployUtil.deploy(currentModelFolder, vcapEnv, hdiOptions);
|
|
108
|
-
|
|
109
|
-
// let isLoggedInToCF;
|
|
110
|
-
// try {
|
|
111
|
-
// isLoggedInToCF = !!(await cfUtil.getCfTarget());
|
|
112
|
-
// } catch (err) {
|
|
113
|
-
// // valid state: not logged in
|
|
114
|
-
// }
|
|
115
|
-
// if (bindCallback && isLoggedInToCF) {
|
|
116
|
-
if (!hasVCAPEnv && bindCallback) {
|
|
117
|
-
const args = [path.relative(projectPath, buildResult.task.src)];
|
|
118
|
-
const options = { to: `${serviceName}:${serviceKeyName}`, kind: buildResult.task.for }
|
|
119
|
-
await bindCallback(args, options);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (!bindCallback) {
|
|
124
|
-
await gitUtil.ensureFileIsGitignored('default-env.json', projectPath);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
console.log(`If not already done, use ${info('cds add hana')} to configure the project for SAP HANA.\n`);
|
|
128
|
-
console.log(`Done.`);
|
|
129
|
-
|
|
130
|
-
return { buildResults };
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
async _getOrCreateCFService(projectPath, currentModelFolder, serviceName, tunnelAddress) {
|
|
135
|
-
const modelName = path.basename(currentModelFolder);
|
|
136
|
-
|
|
137
|
-
// get from param
|
|
138
|
-
let cfServiceInstanceMta;
|
|
139
|
-
let cfServiceInstanceName;
|
|
140
|
-
if (serviceName) {
|
|
141
|
-
cfServiceInstanceName = serviceName;
|
|
142
|
-
} else {
|
|
143
|
-
const cfServiceDescriptor = await mtaUtil.getHanaDbModuleDescriptor(projectPath, modelName);
|
|
144
|
-
cfServiceInstanceName = cfServiceDescriptor.hdiServiceName;
|
|
145
|
-
cfServiceInstanceMta = cfServiceDescriptor.hdiService
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
console.log();
|
|
149
|
-
this._validateServiceInstanceName(cfServiceInstanceName);
|
|
150
|
-
console.log(`Using container ${bold(cfServiceInstanceName)}`);
|
|
151
|
-
|
|
152
|
-
let cfConfig = cfServiceInstanceMta && cfServiceInstanceMta.parameters && cfServiceInstanceMta.parameters.config;
|
|
153
|
-
const serviceInstance = await this.createHanaService(cfServiceInstanceName, cfConfig);
|
|
154
|
-
|
|
155
|
-
const cfServiceInstanceKeyName = `${cfServiceInstanceName}-key`;
|
|
156
|
-
let serviceKey = await cfUtil.getOrCreateServiceKey(serviceInstance, cfServiceInstanceKeyName);
|
|
157
|
-
this._validateServiceKey(serviceKey, cfServiceInstanceKeyName);
|
|
158
|
-
|
|
159
|
-
if (tunnelAddress) {
|
|
160
|
-
console.log(`Using tunnel address ${bold(tunnelAddress)} (beta feature)`);
|
|
161
|
-
serviceKey = this._injectTunnelAddress(serviceKey, tunnelAddress)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey, serviceInstance }
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
async createHanaService(instanceName, cfConfig) {
|
|
169
|
-
// hana or hanatrial, error if neither found
|
|
170
|
-
try {
|
|
171
|
-
return await cfUtil.getOrCreateService('hana', 'hdi-shared', instanceName, cfConfig);
|
|
172
|
-
} catch (error) {
|
|
173
|
-
if (error.command && /offering .* not found/i.test(error.command.stderr)) {
|
|
174
|
-
console.log(`Falling back to 'hanatrial'`);
|
|
175
|
-
return await cfUtil.getOrCreateService('hanatrial', 'hdi-shared', instanceName, cfConfig);
|
|
176
|
-
}
|
|
177
|
-
else if (error.command && /no database/i.test(error.command.stderr)) {
|
|
178
|
-
console.log(`No database connected to 'hana' service. Falling back to 'hanatrial'`);
|
|
179
|
-
return await cfUtil.getOrCreateService('hanatrial', 'hdi-shared', instanceName, cfConfig);
|
|
180
|
-
}
|
|
181
|
-
throw error;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
_validateServiceKey(serviceKey, cfServiceInstanceKey) {
|
|
187
|
-
if (!serviceKey) {
|
|
188
|
-
throw new Error(`Could not create service key ${bold(cfServiceInstanceKey)}.`);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const fields = ['schema', 'user', 'password', 'url'];
|
|
192
|
-
for (const field of fields) {
|
|
193
|
-
if (!serviceKey[field]) {
|
|
194
|
-
throw new Error(`Service key is missing mandatory field '${field}'. Make sure you are ${bold('not')} using a managed service.`);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
async _build(model, buildTaskOptions) {
|
|
201
|
-
buildTaskOptions = buildTaskOptions || {
|
|
202
|
-
root: process.env._TEST_CWD || process.cwd(),
|
|
203
|
-
cli: true,
|
|
204
|
-
cmdOptions: {
|
|
205
|
-
for: buildConstants.BUILD_TASK_HANA
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
if (typeof model === 'string') {
|
|
210
|
-
model = [model];
|
|
211
|
-
}
|
|
212
|
-
console.log(`Creating build tasks`);
|
|
213
|
-
const buildTaskFactory = new BuildTaskFactory();
|
|
214
|
-
const hanaTasks = await buildTaskFactory.getTasks(buildTaskOptions);
|
|
215
|
-
console.log(`Running build`);
|
|
216
|
-
|
|
217
|
-
const buildResults = await new BuildTaskEngine().processTasks(hanaTasks, buildTaskOptions);
|
|
218
|
-
return { buildResults, hanaTasks }
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
async _loadEnvFile(defaultEnvFile) {
|
|
222
|
-
try {
|
|
223
|
-
const content = await fs.readFile(defaultEnvFile);
|
|
224
|
-
return JSON.parse(content);
|
|
225
|
-
} catch (err) {
|
|
226
|
-
throw new Error(`Error reading default env file: ${err.message}`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
async _addInstanceToDefaultEnvJson(currentFolders, serviceInstanceName, serviceKey) {
|
|
232
|
-
for (const currentFolder of currentFolders) {
|
|
233
|
-
let defaultEnvJson = {};
|
|
234
|
-
const defaultEnvJsonPath = path.join(currentFolder, 'default-env.json');
|
|
235
|
-
|
|
236
|
-
try {
|
|
237
|
-
defaultEnvJson = JSON.parse(await fs.readFile(defaultEnvJsonPath, UTF_8));
|
|
238
|
-
} catch (err) {
|
|
239
|
-
// ignore any errors
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
defaultEnvJson.VCAP_SERVICES = defaultEnvJson.VCAP_SERVICES || {};
|
|
243
|
-
for (const serviceKey of Object.keys(defaultEnvJson.VCAP_SERVICES)) {
|
|
244
|
-
defaultEnvJson.VCAP_SERVICES[serviceKey] = defaultEnvJson.VCAP_SERVICES[serviceKey].filter((service) => {
|
|
245
|
-
return (service.name !== serviceInstanceName);
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const hanaEntry = this._getVCAPServicesEntry(serviceInstanceName, serviceKey)
|
|
250
|
-
Object.assign(defaultEnvJson, hanaEntry);
|
|
251
|
-
|
|
252
|
-
console.log(`Writing ${defaultEnvJsonPath}`);
|
|
253
|
-
await fs.mkdir(path.dirname(defaultEnvJsonPath), { recursive: true })
|
|
254
|
-
await fs.writeFile(defaultEnvJsonPath, JSON.stringify(defaultEnvJson, null, 2));
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
_getVCAPServicesEntry(serviceInstanceName, serviceKey) {
|
|
260
|
-
return {
|
|
261
|
-
VCAP_SERVICES: {
|
|
262
|
-
hana: [
|
|
263
|
-
{
|
|
264
|
-
name: serviceInstanceName,
|
|
265
|
-
tags: ['hana'],
|
|
266
|
-
credentials: serviceKey
|
|
267
|
-
}
|
|
268
|
-
]
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
_validateServiceInstanceName(serviceInstanceName) {
|
|
275
|
-
// valid service name chars: alpha-numeric, hyphens, and underscores
|
|
276
|
-
if (/[^\w-_]+/g.exec(serviceInstanceName)) {
|
|
277
|
-
throw new Error(`Service name ${serviceInstanceName} must only contain alpha-numeric, hyphens, and underscores.`);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
_injectTunnelAddress(serviceKey, tunnelAddress) {
|
|
283
|
-
if (!/\w+:\d+/.test(tunnelAddress)) {
|
|
284
|
-
throw new Error(`Invalid tunnel address '${tunnelAddress}' - must be in form 'host:port'`)
|
|
285
|
-
}
|
|
286
|
-
const [tunnelHost, tunnelPort] = tunnelAddress.split(':')
|
|
287
|
-
const { host, port } = serviceKey
|
|
288
|
-
serviceKey.host = tunnelHost
|
|
289
|
-
serviceKey.port = tunnelPort
|
|
290
|
-
serviceKey.url = serviceKey.url.replace(`${host}:${port}`, tunnelAddress)
|
|
291
|
-
serviceKey.hostname_in_certificate = host // make cert. verification happy, see xs2/hdideploy.js#527
|
|
292
|
-
serviceKey.url = serviceKey.url + (serviceKey.url.includes('?') ? '&' : '?') + 'hostNameInCertificate=' + host
|
|
293
|
-
return serviceKey
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
async readFileSafely(file) {
|
|
298
|
-
try {
|
|
299
|
-
return await fs.readFile(file, 'utf8');
|
|
300
|
-
} catch (err) {
|
|
301
|
-
return '';
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
module.exports = new HanaDeployer();
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
const cp = require('child_process');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const util = require('util');
|
|
4
|
-
|
|
5
|
-
const execAsync = util.promisify(cp.exec);
|
|
6
|
-
|
|
7
|
-
const cds = require('../../../lib');
|
|
8
|
-
const LOG = cds.log ? cds.log('deploy') : console;
|
|
9
|
-
const DEBUG = cds.debug('deploy');
|
|
10
|
-
const { SILENT } = cds.log.levels;
|
|
11
|
-
|
|
12
|
-
class HdiDeployUtil {
|
|
13
|
-
|
|
14
|
-
constructor() {
|
|
15
|
-
this.hdiDeployLibs = new Map();
|
|
16
|
-
this.deployerName = '@sap/hdi-deploy'
|
|
17
|
-
this.deployerVersionSpec = '^4'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async deployTenant(dbDir, env) {
|
|
21
|
-
await this._executeDeploy(dbDir, env, true);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async deploy(dbDir, vcapEnv, options) {
|
|
25
|
-
vcapEnv = vcapEnv || {}; // handles null and undefined
|
|
26
|
-
options = options || {};
|
|
27
|
-
|
|
28
|
-
console.log(`Deploying to HANA from ${dbDir}`);
|
|
29
|
-
|
|
30
|
-
const hdiDeployLib = await this._getHdiDeployLib(dbDir);
|
|
31
|
-
|
|
32
|
-
let deployerEnv = JSON.parse(JSON.stringify(process.env));
|
|
33
|
-
const hdiDeployOptions = deployerEnv.HDI_DEPLOY_OPTIONS ? JSON.parse(deployerEnv.HDI_DEPLOY_OPTIONS) : {};
|
|
34
|
-
delete hdiDeployOptions.root;
|
|
35
|
-
|
|
36
|
-
if (typeof hdiDeployLib.clean_env === 'function') {
|
|
37
|
-
deployerEnv = hdiDeployLib.clean_env(deployerEnv);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (vcapEnv.VCAP_SERVICES) {
|
|
41
|
-
deployerEnv.VCAP_SERVICES = JSON.stringify(vcapEnv.VCAP_SERVICES);
|
|
42
|
-
}
|
|
43
|
-
if (vcapEnv.SERVICE_REPLACEMENTS) {
|
|
44
|
-
deployerEnv.SERVICE_REPLACEMENTS = JSON.stringify(vcapEnv.SERVICE_REPLACEMENTS);
|
|
45
|
-
}
|
|
46
|
-
if (vcapEnv.TARGET_CONTAINER) {
|
|
47
|
-
deployerEnv.TARGET_CONTAINER = vcapEnv.TARGET_CONTAINER;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (options.autoUndeploy) {
|
|
51
|
-
console.log(`Hdi deployer automatically undeploys deleted resources using --auto-undeploy.`);
|
|
52
|
-
hdiDeployOptions.auto_undeploy = true;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (Object.entries(hdiDeployOptions).length > 0) {
|
|
56
|
-
deployerEnv.HDI_DEPLOY_OPTIONS = JSON.stringify(hdiDeployOptions);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
await this._executeDeploy(dbDir, deployerEnv);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
async findHdiDeployLib(cwd) {
|
|
64
|
-
const searchPaths = await this._npmSearchPaths(cwd)
|
|
65
|
-
try {
|
|
66
|
-
return require.resolve(path.join(this.deployerName, 'library'), { paths: searchPaths });
|
|
67
|
-
} catch (err) {
|
|
68
|
-
// no luck
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
async _getHdiDeployLib(dbDir) {
|
|
74
|
-
let hdiDeployLib = this.hdiDeployLibs.get(dbDir)
|
|
75
|
-
if (!hdiDeployLib) {
|
|
76
|
-
hdiDeployLib = await this._loadHdiDeployLib(dbDir);
|
|
77
|
-
this.hdiDeployLibs.set(dbDir, hdiDeployLib);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return hdiDeployLib;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
async _loadHdiDeployLib(cwd) {
|
|
85
|
-
const libPath = await this.findHdiDeployLib(cwd)
|
|
86
|
-
if (!libPath) {
|
|
87
|
-
const searchPaths = await this._npmSearchPaths(cwd)
|
|
88
|
-
throw new Error(`Required library '${this.deployerName}' not found in
|
|
89
|
-
${searchPaths.join('\n ')}
|
|
90
|
-
Add it either as a devDependency using 'npm install -D ${this.deployerName}' or install it globally using 'npm install -g ${this.deployerName}'.`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
LOG.info(`Using HDI deployer from ${libPath}`)
|
|
94
|
-
|
|
95
|
-
// let any error go through and abort deploy
|
|
96
|
-
return require(libPath);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
async _npmSearchPaths(cwd) {
|
|
101
|
-
// REVISIT: we shouldn't have to rely on `npm` on the server
|
|
102
|
-
try {
|
|
103
|
-
const npmRootCall = await execAsync('npm root -g');
|
|
104
|
-
const globalNodeModules = npmRootCall.stdout.toString().trim();
|
|
105
|
-
return [cwd, globalNodeModules, '@sap/hdi-deploy']
|
|
106
|
-
} catch (error) {
|
|
107
|
-
if (/Command failed: npm.*not found/s.test(error.message)) return [cwd, '@sap/hdi-deploy']
|
|
108
|
-
else throw error
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
async _executeDeploy(dbDir, env, fromMtx) {
|
|
114
|
-
const hdiDeployLib = await this._getHdiDeployLib(dbDir);
|
|
115
|
-
let writeStream
|
|
116
|
-
if (fromMtx) {
|
|
117
|
-
await cds.utils.mkdirp('logs')
|
|
118
|
-
writeStream = require('fs').createWriteStream(path.join(cds.root, 'logs', `${cds.context.tenant}.log`))
|
|
119
|
-
}
|
|
120
|
-
return new Promise((resolve, reject) => {
|
|
121
|
-
const callbacks = {
|
|
122
|
-
stderrCB: buffer => {
|
|
123
|
-
LOG.error(buffer.toString())
|
|
124
|
-
writeStream?.write(buffer)
|
|
125
|
-
},
|
|
126
|
-
}
|
|
127
|
-
if (fromMtx) {
|
|
128
|
-
callbacks.stdoutCB = buffer => {
|
|
129
|
-
DEBUG?.(buffer.toString())
|
|
130
|
-
writeStream.write(buffer)
|
|
131
|
-
}
|
|
132
|
-
} else if (LOG.level !== SILENT) {
|
|
133
|
-
callbacks.stdoutCB = buffer => LOG.info(buffer.toString())
|
|
134
|
-
}
|
|
135
|
-
hdiDeployLib.deploy(dbDir, env, (error, response) => {
|
|
136
|
-
if (error) {
|
|
137
|
-
return reject(error);
|
|
138
|
-
}
|
|
139
|
-
if (response?.exitCode) {
|
|
140
|
-
let message = `HDI deployment failed with exit code ${response.exitCode}`
|
|
141
|
-
if (response.signal) message += `. ${response.signal}`
|
|
142
|
-
return reject(new Error(message));
|
|
143
|
-
}
|
|
144
|
-
return resolve();
|
|
145
|
-
}, callbacks);
|
|
146
|
-
}).finally(() => writeStream?.end());
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
module.exports = new HdiDeployUtil();
|
|
152
|
-
|
|
153
|
-
/* eslint no-console: off */
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
exports.deploy = (_model, _dbSpecificParameter, {
|
|
2
|
-
'no-save': no_save,
|
|
3
|
-
'auto-undeploy': autoUndeploy = false,
|
|
4
|
-
'tunnel-address': tunnelAddress,
|
|
5
|
-
'vcap-file': vcapFile,
|
|
6
|
-
}, bindCallback) => {
|
|
7
|
-
const hanaDeployer = require('./hana');
|
|
8
|
-
|
|
9
|
-
return hanaDeployer.deploy(
|
|
10
|
-
_model, _dbSpecificParameter,
|
|
11
|
-
no_save, tunnelAddress,
|
|
12
|
-
null, vcapFile, null,
|
|
13
|
-
{ autoUndeploy },
|
|
14
|
-
bindCallback
|
|
15
|
-
)
|
|
16
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
const cds = require('../../../lib')
|
|
2
|
-
const fs = require('fs').promises
|
|
3
|
-
const {existsSync} = require('fs')
|
|
4
|
-
const path = require('path')
|
|
5
|
-
|
|
6
|
-
const HDI_CONTAINER_TYPES = ['com.sap.xs.hdi-container']
|
|
7
|
-
const UTF_8 = 'utf-8'
|
|
8
|
-
const MTA_YAML = 'mta.yaml'
|
|
9
|
-
const LOG = cds.log ? cds.log('deploy') : console;
|
|
10
|
-
|
|
11
|
-
async function getHanaDbModuleDescriptor(projectPath, moduleName) {
|
|
12
|
-
// mta might be null if mta.yaml does not exist
|
|
13
|
-
const mta = await _getMta(projectPath)
|
|
14
|
-
const projectInfo = await _getProjectInfo(projectPath, mta)
|
|
15
|
-
const hdiService = _findHdiResource(mta, moduleName)
|
|
16
|
-
const appName = _getApplicationName(mta, moduleName, 'hdb')
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
project: projectInfo,
|
|
20
|
-
appName: appName ? appName : `${projectInfo.name}-${moduleName}-deployer`,
|
|
21
|
-
hdiServiceName: hdiService ? hdiService.name : `${projectInfo.name}-${moduleName}`,
|
|
22
|
-
hdiService: hdiService
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async function getServiceModuleDescriptor(projectPath, moduleName, moduleType) {
|
|
27
|
-
// mta might be null if mta.yaml does not exist
|
|
28
|
-
const mta = await _getMta(projectPath)
|
|
29
|
-
const projectInfo = await _getProjectInfo(projectPath, mta)
|
|
30
|
-
const appName = _getApplicationName(mta, moduleName, moduleType)
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
project: projectInfo,
|
|
34
|
-
appName: appName ? appName : `${projectInfo.name}-${moduleName}`
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function _getProjectInfo(projectPath, mta) {
|
|
39
|
-
const details = {
|
|
40
|
-
}
|
|
41
|
-
// 1. use mta data
|
|
42
|
-
if (mta) {
|
|
43
|
-
details.id = mta.ID
|
|
44
|
-
details.description = mta.description
|
|
45
|
-
details.version = mta.version
|
|
46
|
-
if (mta.ID) {
|
|
47
|
-
details.name = mta.ID.replace(/\./g, '-')
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
// 2. use package.json data
|
|
51
|
-
const packageJsonPath = path.join(projectPath, 'package.json')
|
|
52
|
-
if (existsSync(packageJsonPath)) {
|
|
53
|
-
try {
|
|
54
|
-
const packageJson = JSON.parse((await fs.readFile(packageJsonPath, 'utf-8')).toString())
|
|
55
|
-
if (!details.description && packageJson.description) {
|
|
56
|
-
details.description = packageJson.description
|
|
57
|
-
}
|
|
58
|
-
if (!details.version && packageJson.version) {
|
|
59
|
-
details.version = packageJson.version
|
|
60
|
-
}
|
|
61
|
-
if (packageJson.name) {
|
|
62
|
-
let segments = packageJson.name.trim().split('/')
|
|
63
|
-
// scope as namespace
|
|
64
|
-
if (segments[0].startsWith('@')) {
|
|
65
|
-
segments[0] = segments[0].replace('@', '')
|
|
66
|
-
}
|
|
67
|
-
segments = segments.map(segment => segment.startsWith('@') ? encodeURIComponent(segment.replace('@', '')) : encodeURIComponent(segment))
|
|
68
|
-
if (!details.name) {
|
|
69
|
-
details.name = segments[segments.length - 1]
|
|
70
|
-
}
|
|
71
|
-
if (!details.id) {
|
|
72
|
-
details.id = segments.join('.')
|
|
73
|
-
}
|
|
74
|
-
if (!details.description) {
|
|
75
|
-
details.description = segments[segments.length - 1]
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
} catch (e) {
|
|
79
|
-
console.error(`Failed to load ${packageJsonPath} - skip application data`, e)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
// 3. use project name and static default values
|
|
83
|
-
const projectName = path.basename(projectPath)
|
|
84
|
-
if (!details.name) {
|
|
85
|
-
details.name = projectName
|
|
86
|
-
}
|
|
87
|
-
if (!details.description) {
|
|
88
|
-
details.description = projectName
|
|
89
|
-
}
|
|
90
|
-
if (!details.id) {
|
|
91
|
-
details.id = projectName
|
|
92
|
-
}
|
|
93
|
-
if (!details.version) {
|
|
94
|
-
details.version = '1.0.0'
|
|
95
|
-
}
|
|
96
|
-
return details
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async function _getMta(projectPath) {
|
|
100
|
-
// yaml.parse oesn't like null
|
|
101
|
-
const mtaFilePath = path.join(projectPath, MTA_YAML)
|
|
102
|
-
|
|
103
|
-
const existsMtaYaml = existsSync(mtaFilePath)
|
|
104
|
-
if (!existsMtaYaml) {
|
|
105
|
-
LOG.debug('mta.yaml not existing')
|
|
106
|
-
return null
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const yamlStr = await fs.readFile(mtaFilePath, UTF_8)
|
|
110
|
-
|
|
111
|
-
// yaml returns null if string couldn't be parsed, e.g. empty string
|
|
112
|
-
return cds.parse.yaml(yamlStr)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function _getApplicationName(mta, moduleName, moduleType) {
|
|
116
|
-
const module = _findModule(mta, moduleName, moduleType)
|
|
117
|
-
if (module) {
|
|
118
|
-
const appName = module.parameters && module.parameters['app-name']
|
|
119
|
-
return appName ? appName : module.name
|
|
120
|
-
}
|
|
121
|
-
return null
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function _findModules(mta, moduleType) {
|
|
125
|
-
let modules = []
|
|
126
|
-
if (mta && Array.isArray(mta.modules)) {
|
|
127
|
-
modules = mta.modules.filter(module => module.type === moduleType)
|
|
128
|
-
}
|
|
129
|
-
return modules
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function _findModule(mta, moduleName, moduleType) {
|
|
133
|
-
const modules = _findModules(mta, moduleType)
|
|
134
|
-
if (modules.length === 1) {
|
|
135
|
-
return modules[0]
|
|
136
|
-
} else if (modules.length > 1) {
|
|
137
|
-
return modules.find(module => typeof module.path === 'string' && module.path.includes(moduleName))
|
|
138
|
-
}
|
|
139
|
-
return null
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function _findHdiResource(mta, moduleName) {
|
|
143
|
-
if (mta && Array.isArray(mta.resources)) {
|
|
144
|
-
const hdiResources = mta.resources.filter(resource => HDI_CONTAINER_TYPES.includes(resource.type))
|
|
145
|
-
|
|
146
|
-
if (hdiResources.length > 0) {
|
|
147
|
-
if (Array.isArray(mta.modules)) {
|
|
148
|
-
const module = _findModule(mta, moduleName, 'hdb')
|
|
149
|
-
if (module && Array.isArray(module.requires)) {
|
|
150
|
-
return hdiResources.find(hdiResource =>
|
|
151
|
-
module.requires.find(req =>
|
|
152
|
-
hdiResource.name === req.name
|
|
153
|
-
)
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
console.warn(`No matching hdi resource found for ${moduleName}. Using ${hdiResources[0].name}.`)
|
|
159
|
-
return hdiResources[0]
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return null
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
module.exports = {
|
|
167
|
-
getHanaDbModuleDescriptor,
|
|
168
|
-
getServiceModuleDescriptor,
|
|
169
|
-
MTA_YAML
|
|
170
|
-
}
|
package/bin/mtx/in-cds.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const cds = require('../build/cds')
|
|
2
|
-
|
|
3
|
-
if (cds.requires.multitenancy && cds.utils._oldMtx()) try {
|
|
4
|
-
// eslint-disable-next-line cds/no-missing-dependencies
|
|
5
|
-
const mtx = module.exports = require ('@sap/cds-mtx')()
|
|
6
|
-
mtx.inject (cds)
|
|
7
|
-
cds.on('served', () => cds.emit('mtx'))
|
|
8
|
-
} catch(e) {
|
|
9
|
-
if (e.code === 'MODULE_NOT_FOUND') throw new Error('Error serving MTX APIs: @sap/cds-mtx is not installed')
|
|
10
|
-
else throw e
|
|
11
|
-
}
|
|
12
|
-
else module.exports = undefined
|
|
13
|
-
|
|
14
|
-
/*
|
|
15
|
-
cds.requires.multitenancy -- use this to check whether mt is enabled (old or new)
|
|
16
|
-
cds.mtx -- use this to check whether old(!) mtx is enabled
|
|
17
|
-
*/
|
package/bin/plugins.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
const cds = require('../lib')
|
|
2
|
-
const DEBUG = cds.debug('plugins')
|
|
3
|
-
|
|
4
|
-
module.exports = async function load_plugins (log = console.log) {
|
|
5
|
-
|
|
6
|
-
if (DEBUG) console.time('[cds] - loaded plugins in')
|
|
7
|
-
const plugins = []
|
|
8
|
-
if (cds.env.plugins) {
|
|
9
|
-
for (let each of cds.env.plugins) {
|
|
10
|
-
let impl = typeof each === 'string' ? each : each.impl
|
|
11
|
-
if (impl.startsWith('.'))
|
|
12
|
-
impl = require.resolve(cds.root + '/' + impl)
|
|
13
|
-
plugins.push(_load_plugin(impl, each))
|
|
14
|
-
}
|
|
15
|
-
} else
|
|
16
|
-
try {
|
|
17
|
-
const pkg = require(cds.root + '/package.json')
|
|
18
|
-
const dependencies = { ...pkg.dependencies, ...(process.env.NODE_ENV !== 'production' && pkg.devDependencies) }
|
|
19
|
-
for (let each in dependencies) {
|
|
20
|
-
plugins.push(_load_plugin(each + '/cds-plugin'))
|
|
21
|
-
}
|
|
22
|
-
} catch { /* ignored */ }
|
|
23
|
-
try { await Promise.all(plugins); } catch { /* ignored */ }
|
|
24
|
-
if (DEBUG) console.timeEnd('[cds] - loaded plugins in')
|
|
25
|
-
|
|
26
|
-
async function _load_plugin (impl, conf) {
|
|
27
|
-
// TODO support ESM plugins. But see cap/cds/pull/1838#issuecomment-1177200 !
|
|
28
|
-
const plugin = require(impl)
|
|
29
|
-
log('loaded plugin:', { impl })
|
|
30
|
-
if (plugin.activate) await plugin.activate(conf)
|
|
31
|
-
}
|
|
32
|
-
}
|