@sap/cds 5.6.1 → 5.7.1
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 +136 -0
- package/_i18n/i18n_fr.properties +4 -4
- package/apis/cds.d.ts +7 -10
- package/apis/connect.d.ts +3 -3
- package/apis/core.d.ts +2 -4
- package/apis/models.d.ts +2 -3
- package/apis/ql.d.ts +0 -1
- package/apis/services.d.ts +7 -3
- package/bin/build/buildTaskFactory.js +16 -10
- package/bin/build/buildTaskProviderFactory.js +3 -3
- package/bin/build/constants.js +2 -1
- package/bin/build/provider/buildTaskProviderInternal.js +14 -14
- package/bin/build/provider/hana/2migration.js +2 -3
- package/bin/build/provider/hana/index.js +34 -0
- package/bin/build/provider/hana/migrationtable.js +90 -22
- package/bin/build/provider/hana/template/undeploy.json +5 -0
- package/bin/build/provider/node-cf/index.js +9 -2
- package/bin/serve.js +16 -18
- package/lib/compile/cdsc.js +15 -5
- package/lib/compile/etc/_localized.js +4 -4
- package/lib/compile/extend.js +8 -0
- package/lib/compile/index.js +3 -1
- package/lib/compile/minify.js +61 -0
- package/lib/compile/resolve.js +4 -1
- package/lib/compile/to/gql.js +9 -0
- package/lib/compile/to/sql.js +26 -30
- package/lib/connect/index.js +1 -1
- package/lib/core/entities.js +0 -3
- package/lib/core/infer.js +1 -0
- package/lib/core/reflect.js +1 -34
- package/lib/deploy.js +25 -17
- package/lib/env/defaults.js +3 -1
- package/lib/env/index.js +13 -4
- package/lib/env/presets.js +38 -0
- package/lib/env/requires.js +16 -11
- package/lib/index.js +13 -11
- package/lib/log/format/kibana.js +4 -2
- package/lib/log/index.js +2 -2
- package/lib/ql/Whereable.js +1 -0
- package/lib/req/cds-context.js +79 -0
- package/lib/req/context.js +5 -77
- package/lib/req/request.js +1 -1
- package/lib/serve/Service-api.js +8 -4
- package/lib/serve/Service-dispatch.js +0 -7
- package/lib/serve/Service-methods.js +6 -8
- package/lib/serve/Transaction.js +35 -30
- package/lib/serve/adapters.js +1 -4
- package/lib/utils/axios.js +1 -1
- package/libx/_runtime/audit/Service.js +44 -20
- package/libx/_runtime/audit/generic/personal/access.js +16 -11
- package/libx/_runtime/audit/generic/personal/modification.js +5 -5
- package/libx/_runtime/audit/generic/personal/utils.js +46 -37
- package/libx/_runtime/{common/auth → auth}/index.js +21 -7
- package/libx/_runtime/{common/auth → auth}/strategies/JWT.js +2 -2
- package/libx/_runtime/{common/auth → auth}/strategies/basic.js +2 -2
- package/libx/_runtime/{common/auth → auth}/strategies/dummy.js +1 -1
- package/libx/_runtime/{common/auth → auth}/strategies/mock.js +2 -2
- package/libx/_runtime/{common/auth → auth}/strategies/utils/uaa.js +1 -1
- package/libx/_runtime/{common/auth → auth}/strategies/utils/xssec.js +0 -0
- package/libx/_runtime/{common/auth → auth}/strategies/xsuaa.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +7 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +0 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +3 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +6 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +3 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +2 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +16 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +26 -65
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +3 -66
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +26 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +13 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/ConditionalRequestControlCommand.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/ConditionalRequestValidator.js +0 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +18 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +54 -76
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -7
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +2 -2
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +8 -4
- package/libx/_runtime/cds-services/services/Service.js +0 -6
- package/libx/_runtime/cds-services/services/utils/columns.js +10 -3
- package/libx/_runtime/cds-services/services/utils/compareJson.js +4 -7
- package/libx/_runtime/cds-services/services/utils/differ.js +4 -1
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +1 -41
- package/libx/_runtime/cds-services/util/assert.js +1 -262
- package/libx/_runtime/cds.js +6 -9
- package/libx/_runtime/common/aspects/entity.js +1 -1
- package/libx/_runtime/common/composition/delete.js +4 -2
- package/libx/_runtime/common/composition/update.js +27 -35
- package/libx/_runtime/common/composition/utils.js +3 -7
- package/libx/_runtime/common/error/standardError.js +11 -0
- package/libx/_runtime/common/generic/auth.js +61 -30
- package/libx/_runtime/common/generic/crud.js +11 -23
- package/libx/_runtime/common/generic/input.js +20 -0
- package/libx/_runtime/common/generic/paging.js +2 -2
- package/libx/_runtime/common/generic/put.js +4 -10
- package/libx/_runtime/common/generic/sorting.js +12 -30
- package/libx/_runtime/common/perf/index.js +24 -0
- package/libx/_runtime/common/utils/cqn.js +58 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +289 -114
- package/libx/_runtime/common/utils/csn.js +38 -56
- package/libx/_runtime/common/utils/entityFromCqn.js +6 -6
- package/libx/_runtime/common/utils/resolveView.js +4 -5
- package/libx/_runtime/common/utils/rewriteAsterisks.js +46 -5
- package/libx/_runtime/common/utils/search2cqn4sql.js +21 -9
- package/libx/_runtime/common/utils/structured.js +35 -25
- package/libx/_runtime/db/Service.js +0 -6
- package/libx/_runtime/db/expand/expand-v2.js +130 -0
- package/libx/_runtime/db/expand/expandCQNToJoin.js +82 -61
- package/libx/_runtime/db/expand/index.js +3 -1
- package/libx/_runtime/db/generic/arrayed.js +14 -27
- package/libx/_runtime/db/generic/input.js +52 -10
- package/libx/_runtime/db/generic/integrity.js +367 -26
- package/libx/_runtime/db/generic/virtual.js +51 -13
- package/libx/_runtime/db/query/update.js +9 -3
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +8 -9
- package/libx/_runtime/{common → db}/utils/propagateForeignKeys.js +11 -14
- package/libx/_runtime/fiori/generic/activate.js +1 -0
- package/libx/_runtime/fiori/generic/before.js +2 -1
- package/libx/_runtime/fiori/generic/edit.js +2 -1
- package/libx/_runtime/fiori/generic/patch.js +1 -1
- package/libx/_runtime/fiori/generic/read.js +151 -57
- package/libx/_runtime/fiori/uiflex/handler/transformRESULT.js +0 -4
- package/libx/_runtime/fiori/uiflex/index.js +1 -1
- package/libx/_runtime/fiori/uiflex/{extensibility/index.js → service.js} +6 -4
- package/libx/_runtime/fiori/utils/delete.js +7 -1
- package/libx/_runtime/hana/Service.js +1 -8
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +5 -14
- package/libx/_runtime/hana/execute.js +10 -4
- package/libx/_runtime/hana/pool.js +55 -45
- package/libx/_runtime/hana/search.js +7 -6
- package/libx/_runtime/hana/search2cqn4sql.js +8 -5
- package/libx/_runtime/hana/searchToContains.js +3 -1
- package/libx/_runtime/index.js +5 -5
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +3 -3
- package/libx/_runtime/messaging/Outbox.js +53 -0
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +17 -10
- package/libx/_runtime/messaging/common-utils/connections.js +14 -9
- package/libx/_runtime/messaging/common-utils/waitingTime.js +2 -0
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -3
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging.js +21 -15
- package/libx/_runtime/messaging/file-based.js +5 -5
- package/libx/_runtime/messaging/message-queuing.js +2 -3
- package/libx/_runtime/messaging/outbox/OutboxRunner.js +75 -0
- package/libx/_runtime/messaging/outbox/utils.js +192 -0
- package/libx/_runtime/messaging/service.js +16 -30
- package/libx/_runtime/remote/Service.js +21 -2
- package/libx/_runtime/remote/utils/client.js +15 -3
- package/libx/_runtime/remote/utils/{dataConversion.js → data.js} +12 -2
- package/libx/_runtime/sqlite/Service.js +7 -10
- package/libx/_runtime/sqlite/customBuilder/CustomExpressionBuilder.js +19 -0
- package/libx/_runtime/sqlite/execute.js +18 -12
- package/libx/_runtime/types/api.js +2 -1
- package/libx/odata/{odata2cqn/afterburner.js → afterburner.js} +28 -16
- package/libx/odata/{cqn2odata/index.js → cqn2odata.js} +1 -1
- package/libx/odata/{odata2cqn/grammar.pegjs → grammar.pegjs} +182 -118
- package/libx/odata/index.js +18 -15
- package/libx/odata/parser.js +1 -0
- package/libx/odata/utils.js +57 -0
- package/libx/rest/RestAdapter.js +2 -6
- package/libx/rest/utils/data.js +1 -6
- package/package.json +4 -3
- package/server.js +13 -10
- package/srv/audit-log.cds +87 -0
- package/{libx/_runtime/fiori/uiflex/extensibility/index.cds → srv/flex.cds} +0 -0
- package/srv/flex.js +1 -0
- package/srv/outbox.cds +11 -0
- package/srv/outbox.js +0 -0
- package/libx/_runtime/cds-services/adapter/perf/performance.js +0 -104
- package/libx/_runtime/cds-services/adapter/perf/performanceMeasurement.js +0 -33
- package/libx/odata/odata2cqn/index.js +0 -3
- package/libx/odata/odata2cqn/parser.js +0 -1
- package/libx/odata/readme.md +0 -1
- package/libx/odata/utils/index.js +0 -64
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const { fs } = require('@sap/cds-foss')
|
|
2
|
-
|
|
3
2
|
class MigrationTableParser {
|
|
4
3
|
constructor() {
|
|
5
4
|
}
|
|
@@ -212,17 +211,17 @@ class MigrationTableModel {
|
|
|
212
211
|
* into the current branch representing the extension.
|
|
213
212
|
* <code>extension.merge(base, targetTable)</code>
|
|
214
213
|
*
|
|
215
|
-
* A---B---E---F extension
|
|
216
|
-
* /
|
|
217
|
-
* A---B---C base
|
|
214
|
+
* A---B---E---F extension X---Y extension
|
|
215
|
+
* / /
|
|
216
|
+
* A---B---C base A---B base
|
|
218
217
|
*
|
|
219
218
|
* || upgrade extension with base - migration version C is inserted into extension, its version number is updated,
|
|
220
219
|
* || its version number is rebased on the version number of the extension
|
|
221
220
|
* \/
|
|
222
221
|
*
|
|
223
|
-
* A---B---E---F---C extension
|
|
224
|
-
* /
|
|
225
|
-
* A---B---C base
|
|
222
|
+
* A---B---E---F---C extension A---B---X---Y extension
|
|
223
|
+
* / /
|
|
224
|
+
* A---B---C base A---B base
|
|
226
225
|
*
|
|
227
226
|
* @param {MigrationTableModel} base The new base migration table version from which all missing migration versions
|
|
228
227
|
* will be taken and merged into the new migration table result.
|
|
@@ -230,17 +229,18 @@ class MigrationTableModel {
|
|
|
230
229
|
* retrieved from the migration table file created by cds build based on the final CDS model version.
|
|
231
230
|
* @returns {MigrationTableModel} The merge result containg missing migrations from base.
|
|
232
231
|
*/
|
|
233
|
-
merge(base, targetTable) {
|
|
234
|
-
let
|
|
235
|
-
return this.migrations.entries.some(extensionMigration => this._compareMigrations(extensionMigration, baseMigration))
|
|
236
|
-
})
|
|
232
|
+
merge(base, targetTable, addBaseVersionAnnotation) {
|
|
233
|
+
let idxBase = this._findCommonBaseMigrationIdx(base)
|
|
237
234
|
const mergeResult = new MigrationTableModel(targetTable, this.migrations.clone())
|
|
238
|
-
|
|
239
|
-
|
|
235
|
+
|
|
236
|
+
// insert all migration versions since the histories diverged
|
|
237
|
+
for (let idx = idxBase >= 0 ? idxBase - 1 : base.migrations.entries.length - 1, versionNumber = this.versionNumber + 1; idx >= 0; idx--, versionNumber++) {
|
|
240
238
|
const migration = base.migrations.entries[idx].clone();
|
|
239
|
+
if (addBaseVersionAnnotation) {
|
|
240
|
+
migration._addBaseMigrationVersion(migration.versionNumber)
|
|
241
|
+
}
|
|
241
242
|
// update migration version number and insert at beginning
|
|
242
|
-
migration.versionNumber =
|
|
243
|
-
mergeResult.table.versionNumber = this.versionNumber + 1
|
|
243
|
+
migration.versionNumber = mergeResult.table.versionNumber = versionNumber
|
|
244
244
|
mergeResult.migrations.entries.splice(0, 0, migration)
|
|
245
245
|
}
|
|
246
246
|
return mergeResult
|
|
@@ -250,13 +250,63 @@ class MigrationTableModel {
|
|
|
250
250
|
return new MigrationTableModel(this.table.clone(), this.migrations.clone())
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
/**
|
|
254
|
+
* Returns the index of the common base migration version (since the time their histories diverged)
|
|
255
|
+
* or -1 if there is no common base. The index points to the base migration table model.
|
|
256
|
+
* @param {MigrationTableModel} base The new base migration table version.
|
|
257
|
+
* @returns The index of the common base migration, -1 if there is no common base.
|
|
258
|
+
*/
|
|
259
|
+
_findCommonBaseMigrationIdx(base) {
|
|
260
|
+
// get the index based on the annotation '-- migration-base=<version number>'
|
|
261
|
+
const extMigration = this.migrations.entries.find(extMigration => extMigration._getBaseMigrationVersion() !== -1)
|
|
262
|
+
// get the index based on DDL equality
|
|
263
|
+
const idxBase = base.migrations.entries.findIndex(baseMigration => {
|
|
264
|
+
return this.migrations.entries.some(extMigration => this._compareMigrations(baseMigration, extMigration))
|
|
265
|
+
})
|
|
266
|
+
if (!extMigration && idxBase === -1) {
|
|
267
|
+
// no common base version - all good
|
|
268
|
+
return -1
|
|
269
|
+
}
|
|
270
|
+
if (extMigration && idxBase !== -1 && extMigration._getBaseMigrationVersion() === base.migrations.entries[idxBase].versionNumber) {
|
|
271
|
+
// both indices refer to the same base version - all good
|
|
272
|
+
return idxBase
|
|
273
|
+
}
|
|
274
|
+
// differences encountered, cause might be:
|
|
275
|
+
// 1. older versions may not add 'migration-base' annotations
|
|
276
|
+
// 2. the same DDL statements might exist in different migrations
|
|
277
|
+
if (!extMigration && idxBase !== -1) {
|
|
278
|
+
// if migration-base annotations do not exist use equality of DDL statements
|
|
279
|
+
// older versions did not add 'migration-base' annotations - most probably all good
|
|
280
|
+
return idxBase
|
|
281
|
+
}
|
|
282
|
+
if (extMigration) {
|
|
283
|
+
// favor 'migration-base' annotation over DDL statement equality
|
|
284
|
+
const baseVersion = extMigration._getBaseMigrationVersion()
|
|
285
|
+
const idxBase = base.migrations.entries.findIndex(baseMigration => baseMigration.versionNumber === baseVersion)
|
|
286
|
+
if (idxBase > -1) {
|
|
287
|
+
return idxBase
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return idxBase
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Migrations are identical if the corresponding DDL statements are identical,
|
|
295
|
+
* ignoring order and ignoring comments.
|
|
296
|
+
*/
|
|
297
|
+
_compareMigrations(m1, m2) {
|
|
298
|
+
if (m1.ddl.length !== m2.ddl.length) {
|
|
299
|
+
return false
|
|
300
|
+
}
|
|
301
|
+
const mDdl2 = m2.ddl.map(entry => this._compactLine(entry))
|
|
302
|
+
return m1.ddl.some(entry => mDdl2.includes(this._compactLine(entry)))
|
|
256
303
|
}
|
|
257
304
|
|
|
258
|
-
|
|
259
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Delete comments and return only those lines representing DDL statements.
|
|
307
|
+
*/
|
|
308
|
+
_compactLine(line) {
|
|
309
|
+
return line.replace(/ /g, '')
|
|
260
310
|
}
|
|
261
311
|
}
|
|
262
312
|
|
|
@@ -349,7 +399,6 @@ class Migration {
|
|
|
349
399
|
this._lines = lines
|
|
350
400
|
}
|
|
351
401
|
this._versionNumber = MigrationTableParser._parseVersionNumber(this.lines[0])
|
|
352
|
-
this._changeset = this._lines.filter(line => !MigrationTableParser._isMigrationMarker(line))
|
|
353
402
|
}
|
|
354
403
|
|
|
355
404
|
/**
|
|
@@ -378,7 +427,7 @@ class Migration {
|
|
|
378
427
|
* Returns the changeset containing the DDL statements of this migration.
|
|
379
428
|
*/
|
|
380
429
|
get changeset() {
|
|
381
|
-
return this.
|
|
430
|
+
return this._lines.filter(line => !MigrationTableParser._isMigrationMarker(line))
|
|
382
431
|
}
|
|
383
432
|
|
|
384
433
|
/**
|
|
@@ -389,6 +438,25 @@ class Migration {
|
|
|
389
438
|
return this.changeset.filter(line => MigrationTableParser._isDDL(line))
|
|
390
439
|
}
|
|
391
440
|
|
|
441
|
+
_addBaseMigrationVersion(versionNumber) {
|
|
442
|
+
this._addComment(1, `-- migration-base=${versionNumber}`)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
_getBaseMigrationVersion() {
|
|
446
|
+
let versionNumber = -1
|
|
447
|
+
if (this._lines.length > 1) {
|
|
448
|
+
const match = this._lines[1].match(/(^\s*-- migration-base=)(\d+)\s*$/)
|
|
449
|
+
if (match && match.length === 3) {
|
|
450
|
+
versionNumber = parseInt(match[2])
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return versionNumber
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
_addComment(start, comment) {
|
|
457
|
+
this._lines.splice(start, 0, comment)
|
|
458
|
+
}
|
|
459
|
+
|
|
392
460
|
/**
|
|
393
461
|
* Returns the string representation of this migration.
|
|
394
462
|
*/
|
|
@@ -4,7 +4,10 @@ const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
|
|
|
4
4
|
const { getHanaDbModuleDescriptor, getServiceModuleDescriptor } = require('../../mtaUtil')
|
|
5
5
|
const { BuildError } = require('../../util')
|
|
6
6
|
const { BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY, ODATA_VERSION, ODATA_VERSION_V2,
|
|
7
|
-
BUILD_TASK_HANA, FOLDER_GEN, BUILD_NODEJS_EDMX_GENERAION, EDMX_GENERATION,
|
|
7
|
+
BUILD_TASK_HANA, FOLDER_GEN, BUILD_NODEJS_EDMX_GENERAION, EDMX_GENERATION,
|
|
8
|
+
SKIP_PACKAGE_JSON_GENERATION, SKIP_MANIFEST_GENERATION,
|
|
9
|
+
CONTENT_EDMX, CONTENT_MANIFEST, CONTENT_PACKAGE_JSON, CONTENT_PACKAGELOCK_JSON }
|
|
10
|
+
= require('../../constants')
|
|
8
11
|
const { WARNING } = require('../../buildTaskHandler')
|
|
9
12
|
|
|
10
13
|
const FILE_NAME_MANIFEST_YML = "manifest.yml"
|
|
@@ -16,6 +19,7 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
16
19
|
this.task.options[CONTENT_EDMX] = this.hasBuildOption(CONTENT_EDMX, true) || this.hasCdsEnvOption(BUILD_NODEJS_EDMX_GENERAION, true) || this.hasBuildOption(EDMX_GENERATION, true) ? true : false
|
|
17
20
|
this.task.options[CONTENT_MANIFEST] = !this.hasBuildOption(CONTENT_MANIFEST, false) && !this.hasBuildOption(SKIP_MANIFEST_GENERATION, true) ? true : false
|
|
18
21
|
this.task.options[CONTENT_PACKAGE_JSON] = !this.hasBuildOption(CONTENT_PACKAGE_JSON, false) && !this.hasBuildOption(SKIP_PACKAGE_JSON_GENERATION, true) ? true : false
|
|
22
|
+
this.task.options[CONTENT_PACKAGELOCK_JSON] = !this.hasBuildOption(CONTENT_PACKAGELOCK_JSON, false) ? true : false
|
|
19
23
|
|
|
20
24
|
if (this.task.options.compileDest) {
|
|
21
25
|
throw new BuildError("Option not supported - compileDest")
|
|
@@ -66,7 +70,7 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
async _copyNativeContent(src, dest) {
|
|
69
|
-
const regex = RegExp('\\.cds$|package\\.json|manifest\\.y.?ml')
|
|
73
|
+
const regex = RegExp('\\.cds$|package\\.json|package-lock\\.json|manifest\\.y.?ml')
|
|
70
74
|
|
|
71
75
|
await super.copyNativeContent(src, dest, (entry) => {
|
|
72
76
|
if (fs.statSync(entry).isDirectory()) {
|
|
@@ -92,6 +96,9 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
92
96
|
packageJsonCopy = true
|
|
93
97
|
return true
|
|
94
98
|
}
|
|
99
|
+
if (/package-lock\.json$/.test(entry) && this.hasBuildOption(CONTENT_PACKAGELOCK_JSON, true)) {
|
|
100
|
+
return true
|
|
101
|
+
}
|
|
95
102
|
return false
|
|
96
103
|
})
|
|
97
104
|
|
package/bin/serve.js
CHANGED
|
@@ -124,7 +124,7 @@ module.exports = Object.assign ( serve, {
|
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
const cds = require('../lib'), { exists, isfile, local, path } = cds.utils
|
|
127
|
-
let log = console.log // provisional logger, see
|
|
127
|
+
let log = console.log // provisional logger, see _prepare_logging
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
130
|
* The main function which dispatches into the respective usage variants.
|
|
@@ -139,7 +139,7 @@ async function serve (all=[], o={}) { // NOSONAR
|
|
|
139
139
|
else if (o.service) { o.from = pms ? pms.split(',') : '*'}
|
|
140
140
|
else if (o.from) { o.service = pms }
|
|
141
141
|
else if (exists(pms)) { o.service ='all', o.from = all }
|
|
142
|
-
else { o.service = pms, o.from = '*' }
|
|
142
|
+
else { o.service = pms||'all', o.from = '*' }
|
|
143
143
|
|
|
144
144
|
// IMPORTANT: never load any @sap/cds modules before the chdir above happened!
|
|
145
145
|
// handle --watch and --project
|
|
@@ -151,16 +151,16 @@ async function serve (all=[], o={}) { // NOSONAR
|
|
|
151
151
|
const {features} = cds.env
|
|
152
152
|
{
|
|
153
153
|
// handle --with-mocks resp. --mocked
|
|
154
|
-
if (
|
|
154
|
+
if (features.with_mocks) o.mocked = _with_mocks(o)
|
|
155
155
|
|
|
156
156
|
// handle --in-memory resp. --in-memory?
|
|
157
|
-
if (features.in_memory_db) o.in_memory = _in_memory
|
|
157
|
+
if (features.in_memory_db) o.in_memory = _in_memory(o)
|
|
158
158
|
|
|
159
159
|
// load service bindings when mocking or asked to
|
|
160
160
|
if (features.mocked_bindings && o.mocked || o['with-bindings']) await cds.service.bindings
|
|
161
161
|
|
|
162
162
|
// live reload, in cooperation with cds watch
|
|
163
|
-
if (features.live_reload)
|
|
163
|
+
if (features.live_reload) require('../app/etc/livereload')
|
|
164
164
|
|
|
165
165
|
// add dev helper for Fiori URLs
|
|
166
166
|
if (features.fiori_routes) require('../app/fiori/routes')
|
|
@@ -203,38 +203,37 @@ function _prepare_logging () { // NOSONAR
|
|
|
203
203
|
// change `log` function to cds.log
|
|
204
204
|
const LOG = cds.log('serve', { prefix:'cds' })
|
|
205
205
|
log = LOG._info && LOG.info
|
|
206
|
+
if (!log) return
|
|
206
207
|
|
|
207
|
-
const _timer =
|
|
208
|
-
|
|
208
|
+
const _timer = `[cds] - launched at ${new Date().toLocaleString()}, in`
|
|
209
|
+
console.time (_timer)
|
|
209
210
|
|
|
210
211
|
// print information when model is loaded
|
|
211
212
|
cds.on ('loaded', (model)=>{
|
|
212
|
-
log
|
|
213
|
-
for (let each of model.$sources)
|
|
214
|
-
|
|
213
|
+
log (`model loaded from ${model.$sources.length} file(s):\n\x1b[2m`)
|
|
214
|
+
for (let each of model.$sources) console.log (' ', local(each))
|
|
215
|
+
console.log ('\x1b[0m')
|
|
215
216
|
})
|
|
216
217
|
|
|
217
218
|
// print information about each connected service
|
|
218
219
|
cds.on ('connect', ({name,kind,options:{use,credentials}})=>{
|
|
219
|
-
log
|
|
220
|
+
log (`connect to ${name} > ${use||kind}`, credentials ? _redacted(credentials) : '')
|
|
220
221
|
})
|
|
221
222
|
|
|
222
223
|
// print information about each provided service
|
|
223
224
|
cds.on ('serving', (srv) => {
|
|
224
225
|
const details = { at: srv.path }
|
|
225
226
|
if (srv._source) details.impl = local(srv._source)
|
|
226
|
-
log
|
|
227
|
+
log (`${srv.mocked ? 'mocking' : 'serving'} ${srv.name}`, details)
|
|
227
228
|
})
|
|
228
229
|
|
|
229
230
|
// print info when we are finally on air
|
|
230
231
|
cds.once ('listening', ({url})=>{
|
|
231
|
-
|
|
232
|
-
log
|
|
232
|
+
console.log ()
|
|
233
|
+
log ('server listening on',{url})
|
|
233
234
|
_timer && console.timeEnd (_timer)
|
|
234
|
-
if (process.stdin.isTTY) log
|
|
235
|
+
if (process.stdin.isTTY) log (`[ terminate with ^C ]\n`)
|
|
235
236
|
})
|
|
236
|
-
|
|
237
|
-
return cds
|
|
238
237
|
}
|
|
239
238
|
|
|
240
239
|
|
|
@@ -275,7 +274,6 @@ function _in_memory (o) {
|
|
|
275
274
|
|
|
276
275
|
/** handles --with-mocks option */
|
|
277
276
|
function _with_mocks (o) {
|
|
278
|
-
if (process.env.NODE_ENV === 'production') return
|
|
279
277
|
if (o.mocked || (o.mocked = o['with-mocks'])) {
|
|
280
278
|
cds.on ('loaded', model => cds.deploy.include_external_entities_in(model))
|
|
281
279
|
const mocks = cds.env.features.test_mocks && isfile ('test/mocked.js')
|
package/lib/compile/cdsc.js
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
const {cdsc,odata,sql,hana} = require ('../index').env
|
|
1
|
+
const {cdsc,odata,sql,hana,features} = require ('../index').env
|
|
2
|
+
const constraints = {
|
|
3
|
+
assertIntegrity: features.assert_integrity,
|
|
4
|
+
assertIntegrityType: features.assert_integrity_type
|
|
5
|
+
}
|
|
6
|
+
// REVISIT: remove with compiler ^2.11
|
|
7
|
+
const { assertIntegrity: ai, assertIntegrityType: ait } = constraints
|
|
8
|
+
if ((typeof ai === 'string' && ai.match(/individual/i)) || (ait && ait.match(/db/i))) {
|
|
9
|
+
cdsc.beta = cdsc.beta || {}
|
|
10
|
+
cdsc.beta.foreignKeyConstraints = true
|
|
11
|
+
}
|
|
2
12
|
const compile = require ('@sap/cds-compiler')
|
|
3
13
|
const _4cdsc = Symbol('_4cdsc')
|
|
4
14
|
|
|
5
15
|
/**
|
|
6
|
-
* Returns a copy of the given options object,
|
|
16
|
+
* Returns a copy of the given options object, with all mappings applied and
|
|
7
17
|
* finally overridden with entries from cds.env.cdsc. That is, the equivalent
|
|
8
18
|
* of {...o, ...[...mappings], ...cds.env.cdsc }.
|
|
9
19
|
* @type <T> (src:T,...mappings:{}[]) => T
|
|
@@ -11,7 +21,7 @@ const _4cdsc = Symbol('_4cdsc')
|
|
|
11
21
|
function _options4 (src, ...mappings) {
|
|
12
22
|
if (src[_4cdsc]) return src //> already prepared for cdsc
|
|
13
23
|
// Create a derivate of given src options object
|
|
14
|
-
const dst = Object.defineProperty({__proto__:src},_4cdsc,{value:true}) // NOTE: {__proto__:src}
|
|
24
|
+
const dst = Object.defineProperty({__proto__:src, ...src}, _4cdsc,{value:true}) // NOTE: {__proto__:src} alone doesn't suffice, due to compiler obviously cloning options; {...src} doesn't suffice as non-enumerables from .effective.odata would get lost
|
|
15
25
|
// Apply mappings in order of appearance -> latter ones override formers
|
|
16
26
|
for (let map of mappings) for (let k in map) {
|
|
17
27
|
let v = dst[k]; if (v === undefined) continue
|
|
@@ -61,10 +71,10 @@ const _options = {for: Object.assign (_options4, {
|
|
|
61
71
|
},
|
|
62
72
|
|
|
63
73
|
sql(o,_env) {
|
|
64
|
-
return _options4 ({ ..._env||sql, ...o }, {
|
|
74
|
+
return _options4 ({ ...constraints, ..._env||sql, ...o }, {
|
|
65
75
|
sql_mapping : 'names', //> legacy
|
|
66
76
|
sqlDialect : 'dialect', //> legacy
|
|
67
|
-
sqlMapping
|
|
77
|
+
sqlMapping : 'names',
|
|
68
78
|
dialect : 'sqlDialect',
|
|
69
79
|
names : (o,v) => v !== 'plain' ? o.sqlMapping = v : undefined,
|
|
70
80
|
})
|
|
@@ -42,13 +42,13 @@ function unfold_csn (m) { // NOSONAR
|
|
|
42
42
|
// only do that once per model
|
|
43
43
|
if (!m || m[_been_here]) return m
|
|
44
44
|
// eslint-disable-next-line no-console
|
|
45
|
-
DEBUG &&
|
|
45
|
+
DEBUG && DEBUG ('unfolding csn...')
|
|
46
46
|
const pass2 = []
|
|
47
47
|
|
|
48
48
|
const _locales = _on_sqlite && _locales_4sql.sqlite
|
|
49
49
|
|
|
50
50
|
// Pass 1 - add localized.<locale> entities and views
|
|
51
|
-
for (let each in m.definitions) {
|
|
51
|
+
for (let each in cds.linked(m).definitions) {
|
|
52
52
|
const d = m.definitions [each]
|
|
53
53
|
// Add <entry>_texts proxies for all <entry>.texts entities
|
|
54
54
|
if (_texts_entries !== false && each.endsWith('.texts')) {
|
|
@@ -99,5 +99,5 @@ function unfold_csn (m) { // NOSONAR
|
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
// feature-toggled exports
|
|
102
|
-
module.exports =
|
|
103
|
-
if (!env.features.localized) module.exports
|
|
102
|
+
module.exports = { unfold_csn, unfold_ddl }
|
|
103
|
+
if (!env.features.localized) Object.assign (module.exports, { unfold_csn: x=>x, unfold_ddl: x=>x })
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const { extend } = require ('../lazy')
|
|
2
|
+
const compile = require ('./index')
|
|
3
|
+
|
|
4
|
+
module.exports = o => o.definitions ? { with(...exts) {
|
|
5
|
+
const all = { 'base.csn': JSON.stringify(o) }
|
|
6
|
+
exts.forEach ((x,i)=> all[i+'.csn'] = JSON.stringify(x))
|
|
7
|
+
return compile (all)
|
|
8
|
+
}} : extend(o)
|
package/lib/compile/index.js
CHANGED
|
@@ -16,6 +16,7 @@ const compile = module.exports = Object.assign (cds_compile, {
|
|
|
16
16
|
to: lazified ({
|
|
17
17
|
csn: cds_compile,
|
|
18
18
|
cdl: require('./to/cdl'),
|
|
19
|
+
gql: require('./to/gql'),
|
|
19
20
|
yml: require('./to/yaml'),
|
|
20
21
|
yaml: require('./to/yaml'),
|
|
21
22
|
json: require('./to/json'),
|
|
@@ -26,6 +27,7 @@ const compile = module.exports = Object.assign (cds_compile, {
|
|
|
26
27
|
serviceinfo: require('./to/srvinfo'), //> REVISIT: move to CLI
|
|
27
28
|
}),
|
|
28
29
|
|
|
30
|
+
_localized: require('./etc/_localized'),
|
|
29
31
|
})
|
|
30
32
|
|
|
31
33
|
|
|
@@ -53,7 +55,7 @@ function cds_compile (model, options, _flavor) {
|
|
|
53
55
|
}
|
|
54
56
|
else return _fluent (_finalize (cdsc.compileSources(model,o))) //> compile CDL sources
|
|
55
57
|
function _finalize (csn) {
|
|
56
|
-
if (o.min) csn = cds.
|
|
58
|
+
if (o.min) csn = cds.minify(csn)
|
|
57
59
|
// REVISIT: experimental implementation to detect external APIs
|
|
58
60
|
for (let each in csn.definitions) {
|
|
59
61
|
const d = csn.definitions[each]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module.exports = function cds_minify (csn, _roots = global.cds.env.features.skip_unused) {
|
|
2
|
+
if (_roots === false) return csn
|
|
3
|
+
if (csn[_minified]) return csn; else Object.defineProperty (csn,_minified,{value:true})
|
|
4
|
+
const all = csn.definitions, reached = new Set
|
|
5
|
+
if (_roots === 'services') {
|
|
6
|
+
for (let n in all) if (all[n].kind === 'service') _visit_service(n)
|
|
7
|
+
} else if (typeof _roots === 'string') {
|
|
8
|
+
_visit_service(_roots)
|
|
9
|
+
} else for (let n in all) {
|
|
10
|
+
let d = all[n]
|
|
11
|
+
if (d.kind === 'service') _visit_service(n)
|
|
12
|
+
else if (d.kind === 'entity') {
|
|
13
|
+
if (d['@cds.persistence.skip'] === 'if-unused') continue
|
|
14
|
+
if (n.endsWith('.texts')) {
|
|
15
|
+
let e = all[n.slice(0,-6)]
|
|
16
|
+
if (e && e['@cds.persistence.skip'] === 'if-unused') continue
|
|
17
|
+
}
|
|
18
|
+
_visit(d)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function _visit_service (service) {
|
|
22
|
+
reached.add (all[service])
|
|
23
|
+
for (let e in all) if (e.startsWith(service+'.')) _visit(all[e])
|
|
24
|
+
}
|
|
25
|
+
function _visit_query (q) {
|
|
26
|
+
if (q.SELECT) return _visit_query (q.SELECT)
|
|
27
|
+
if (q.SET) return q.SET.args.forEach (_visit_query)
|
|
28
|
+
if (q.from) {
|
|
29
|
+
if (q.from.join) return q.from.args.forEach (_visit)
|
|
30
|
+
else return _visit (q.from)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function _visit (d) {
|
|
34
|
+
if (typeof d === 'string') {
|
|
35
|
+
if (d.startsWith('cds.')) return
|
|
36
|
+
else d = all[d]
|
|
37
|
+
} else if (d.ref) return d.ref.reduce((p,n) => {
|
|
38
|
+
let d = p.elements[n.id || n] // > n.id -> view with parameters
|
|
39
|
+
_visit(d)
|
|
40
|
+
return d
|
|
41
|
+
},{elements:all})
|
|
42
|
+
if (reached.has(d)) return; else reached.add(d)
|
|
43
|
+
if (d.includes) d.includes.forEach(i => _visit(all[i])) // Note: with delete d.includes, redirects in AFC broke
|
|
44
|
+
if (d.projection) _visit_query (d.projection)
|
|
45
|
+
if (d.query) _visit_query (d.query)
|
|
46
|
+
if (d.type) _visit (d.type)
|
|
47
|
+
if (d.target) _visit (d.target)
|
|
48
|
+
if (d.targetAspect) _visit (d.targetAspect)
|
|
49
|
+
if (d.items) _visit (d.items)
|
|
50
|
+
if (d.returns) _visit (d.returns)
|
|
51
|
+
for (let e in d.elements) _visit (d.elements[e])
|
|
52
|
+
for (let a in d.actions) _visit (d.actions[a])
|
|
53
|
+
for (let p in d.params) _visit (d.params[p])
|
|
54
|
+
}
|
|
55
|
+
const minified = Object.create (csn.__proto__, Object.getOwnPropertyDescriptors(csn))
|
|
56
|
+
const less = minified.definitions = {}
|
|
57
|
+
for (let n in all) if (reached.has(all[n])) less[n] = all[n]
|
|
58
|
+
return minified
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const _minified = Symbol('minified')
|
package/lib/compile/resolve.js
CHANGED
|
@@ -23,9 +23,12 @@ module.exports = exports = function cds_resolve (model, o={}) { // NOSONAR
|
|
|
23
23
|
|
|
24
24
|
const cwd = o.root || global.cds && global.cds.root, local = resolve (cwd,model)
|
|
25
25
|
const context = _paths(cwd), {cached} = context
|
|
26
|
-
|
|
26
|
+
let id = model.startsWith('.') ? local : model
|
|
27
27
|
if (id in cached && !o.skipModelCache) return cached[id]
|
|
28
28
|
|
|
29
|
+
// expand @sap/cds by cds.home
|
|
30
|
+
if (id.startsWith('@sap/cds')) id = global.cds.home +'/'+ id.slice(8)
|
|
31
|
+
|
|
29
32
|
// fetch file with .cds/.csn suffix as is
|
|
30
33
|
if (/\.(csn|cds)$/.test(id)) try {
|
|
31
34
|
return cached[id] = _resolved ([ _resolve (id,context) ])
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const { generate } = require ('../../../libx/gql/schema')
|
|
2
|
+
const cds = require ('../..')
|
|
3
|
+
|
|
4
|
+
function cds_compile_to_gql (csn) {
|
|
5
|
+
const m = cds.linked(csn)
|
|
6
|
+
return generate (m.services.map(s => ({ name:s.name, model:m })))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
module.exports = cds_compile_to_gql
|
package/lib/compile/to/sql.js
CHANGED
|
@@ -1,47 +1,25 @@
|
|
|
1
|
-
const cds = require ('../..'),
|
|
1
|
+
const cds = require ('../..'), { unfold_ddl: cds_localized } = cds.compile._localized
|
|
2
2
|
const cdsc = require ('../cdsc')
|
|
3
|
-
const {unfold_ddl} = cds.alpha_localized
|
|
4
|
-
const EXT_BACK_PACK = 'extensions__'
|
|
5
3
|
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
function cds_compile_to_sql (csn,_o) {
|
|
6
|
+
csn = _extended(cds.minify(csn))
|
|
7
7
|
const o = cdsc._options.for.sql(_o) //> used twice below...
|
|
8
|
-
const all = cdsc.to.sql
|
|
9
|
-
const sql =
|
|
10
|
-
.replace(/^-- .+\n/,'') //> strip comments
|
|
11
|
-
), csn, o)
|
|
8
|
+
const all = cdsc.to.sql(csn,o) .map (each => each.replace(/^-- .+\n/,'')) //> strip comments
|
|
9
|
+
const sql = cds_localized(all, csn, o)
|
|
12
10
|
if (o.as === 'str') return `\n${sql.join('\n\n')}\n`
|
|
13
11
|
return sql
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
function cds_compile_to_sql (csn,_o) {
|
|
17
|
-
const defs = cds.linked(csn).definitions
|
|
18
|
-
for (let each in defs) {
|
|
19
|
-
const d = defs[each], q = d.query
|
|
20
|
-
// q may have SET instead of SELECT
|
|
21
|
-
if (q && q.SELECT && q.SELECT.columns && _is_extensible(d)) _add_extensions2 (q.SELECT.columns)
|
|
22
|
-
}
|
|
23
|
-
function _is_extensible (d) {
|
|
24
|
-
if(!d || !d.elements) return false
|
|
25
|
-
if (EXT_BACK_PACK in d.elements) return true
|
|
26
|
-
else return _is_extensible (d.__proto__)
|
|
27
|
-
}
|
|
28
|
-
function _add_extensions2 (cols) {
|
|
29
|
-
if (cols.some(({ref}) => ref && ref[0] === EXT_BACK_PACK)) return
|
|
30
|
-
cols.push({ref:[EXT_BACK_PACK]})
|
|
31
|
-
}
|
|
32
|
-
const ddl = cds_compile_to_sql_ (csn,_o)
|
|
33
|
-
return ddl
|
|
34
|
-
}
|
|
35
|
-
|
|
36
14
|
|
|
37
15
|
function cds_compile_to_hdbtable (csn,o) {
|
|
38
|
-
const all = cdsc.to.hdi (
|
|
16
|
+
const all = cdsc.to.hdi (cds.minify(csn),o)
|
|
39
17
|
return _2many(all)
|
|
40
18
|
}
|
|
41
19
|
|
|
42
20
|
|
|
43
21
|
function cds_compile_to_hdbcds (csn,o) {
|
|
44
|
-
const all = cdsc.to.hdbcds (
|
|
22
|
+
const all = cdsc.to.hdbcds (cds.minify(csn),o)
|
|
45
23
|
const constructFileName = (fileName) => {
|
|
46
24
|
const identifier = fileName.split('.');
|
|
47
25
|
const suffix = identifier.pop();
|
|
@@ -61,3 +39,21 @@ module.exports = Object.assign (cds_compile_to_sql, {
|
|
|
61
39
|
hdbcds: cds_compile_to_hdbcds,
|
|
62
40
|
hdbtable: cds_compile_to_hdbtable,
|
|
63
41
|
})
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
46
|
+
// UI Flex - read extensions__ to views, when ext fields are read
|
|
47
|
+
const _extended = (csn) => {
|
|
48
|
+
const defs = cds.linked(csn).definitions
|
|
49
|
+
for (let each in defs) {
|
|
50
|
+
const d = defs[each], q = d.query // TODO: q may have SET instead of SELECT
|
|
51
|
+
if (q && q.SELECT && q.SELECT.columns && _is_extensible(d)) {
|
|
52
|
+
if (!q.SELECT.columns.some(({ref}) => ref && ref[0] === _extensions)) q.SELECT.columns.push({ref:[_extensions]})
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return csn
|
|
56
|
+
}
|
|
57
|
+
const _is_extensible = d => _extensions in d.elements || d.__proto__.elements && _is_extensible (d.__proto__)
|
|
58
|
+
const _extensions = 'extensions__'
|
|
59
|
+
/////////////////////////////////////////////////////////////////////////////
|
package/lib/connect/index.js
CHANGED
|
@@ -38,7 +38,7 @@ connect.to = async (datasource, options) => {
|
|
|
38
38
|
// check if required service definition exists
|
|
39
39
|
const required = cds.requires[datasource]
|
|
40
40
|
if (required && required.model && datasource !== 'db' && !m.definitions[required.service||datasource]) {
|
|
41
|
-
LOG.error
|
|
41
|
+
LOG._error && LOG.error(`No service definition found for '${required.service || datasource}', as required by 'cds.requires.${datasource}':`, required)
|
|
42
42
|
throw new Error (`No service definition found for '${required.service || datasource}'`)
|
|
43
43
|
}
|
|
44
44
|
// construct new service instance
|
package/lib/core/entities.js
CHANGED
|
@@ -11,9 +11,6 @@ class entity extends struct {
|
|
|
11
11
|
get compositions() {
|
|
12
12
|
return this.own('_compositions') || this.set('_compositions', this._elements (e => e instanceof Composition))
|
|
13
13
|
}
|
|
14
|
-
get texts() {
|
|
15
|
-
return this.own('_texts') || this.set('_texts', {__proto__:this, name: this.name + '.texts' })
|
|
16
|
-
}
|
|
17
14
|
get drafts() {
|
|
18
15
|
return this.own('_drafts') || this.set('_drafts',
|
|
19
16
|
this.elements.HasDraftEntity && { name: this.name + '_drafts', keys: this.keys }
|
package/lib/core/infer.js
CHANGED