@cap-js/cds-typer 0.7.0 → 0.8.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 CHANGED
@@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/).
6
6
 
7
- ## Version 0.7.1 - TBD
7
+ ## Version 0.8.1 - TBD
8
8
 
9
9
  ### Changed
10
10
 
@@ -12,6 +12,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
12
12
 
13
13
  ### Fixed
14
14
 
15
+
16
+ ## Version 0.8.0 - 2023-09-05
17
+
18
+ ### Changed
19
+
20
+ ### Added
21
+
22
+ ### Fixed
23
+ - Foreign keys that are inherited via aspects are now also generated in addition to the resolved property (see 0.7.0)
24
+ - Explicitly annotated `@singular` and `@plural` names are now properly used in generated _index.js_ files
25
+
26
+
15
27
  ## Version 0.7.0 - 2023-08-22
16
28
 
17
29
  ### Changed
package/lib/file.js CHANGED
@@ -335,6 +335,9 @@ class SourceFile extends File {
335
335
  .flatMap(([singular, plural, original]) => Array.from(new Set([
336
336
  `module.exports.${singular} = csn.${original}`,
337
337
  `module.exports.${plural} = csn.${original}`,
338
+ // FIXME: we currently produce at most 3 entries.
339
+ // This could be an issue when the user re-used the original name in a @singular/@plural annotation.
340
+ // Seems unlikely, but we have to eliminate the original entry if users start running into this.
338
341
  `module.exports.${original} = csn.${original}`
339
342
  ])))
340
343
  ) // singular -> plural aliases
package/lib/util.js CHANGED
@@ -201,6 +201,24 @@ const parseCommandlineArgs = (argv, validFlags) => {
201
201
  * when removing an annotation which we also check.
202
202
  */
203
203
  function fixCSN(csn) {
204
+ for (const element of Object.values(csn.definitions)) {
205
+ Object.defineProperty(element, 'keys', {
206
+ get: function () {
207
+ // cached access to all immediately defined _and_ inherited keys.
208
+ // They need to be explicitly accessible in subclasses to generate
209
+ // foreign key fields from Associations/ Compositions.
210
+ if (!Object.hasOwn(this, '__keys')) {
211
+ const ownKeys = Object.fromEntries(Object.entries(this.elements ?? {}).filter(([,el]) => el.key === true))
212
+ const inheritedKeys = this.includes?.flatMap(parent => csn.definitions[parent].keys) ?? []
213
+ this.__keys = inheritedKeys.reduce((ks, ps) => ({...ps, ...ks}), ownKeys)
214
+ }
215
+ return this.__keys
216
+ }
217
+ })
218
+ }
219
+
220
+ // FIXME: delete after merge with draft-enablement PR
221
+ return
204
222
  const erase = (entity, parent, attr) => {
205
223
  if (attr in entity) {
206
224
  const ea = entity[attr]
package/lib/visitor.js CHANGED
@@ -59,6 +59,7 @@ class Visitor {
59
59
  * @param {VisitorOptions} options
60
60
  */
61
61
  constructor(csn, options = {}, logger = new Logger()) {
62
+ util.fixCSN(csn)
62
63
  this.options = { ...defaults, ...options }
63
64
  this.logger = logger
64
65
  this.csn = csn
@@ -130,8 +131,13 @@ class Visitor {
130
131
  for (const [ename, element] of Object.entries(entity.elements ?? {})) {
131
132
  this.visitElement(ename, element, file, buffer)
132
133
  // make foreign keys explicit
133
- for (const [fkname, fkelement] of Object.entries(element.foreignKeys ?? {})) {
134
- this.visitElement(`${ename}_${fkname}`, fkelement, file, buffer)
134
+ if ('target' in element) {
135
+ // lookup in cds.definitions can fail for inline structs.
136
+ // We don't really have to care for this case, as keys from such structs are _not_ propagated to
137
+ // the containing entity.
138
+ for (const [kname, kelement] of Object.entries(this.csn.definitions[element.target]?.keys ?? {})) {
139
+ this.visitElement(`${ename}_${kname}`, kelement, file, buffer)
140
+ }
135
141
  }
136
142
  }
137
143
  for (const [aname, action] of Object.entries(entity.actions ?? {})) {
@@ -207,7 +213,8 @@ class Visitor {
207
213
  // to have Books.texts = Books.text, so we derive the singular once more without cutting off the ns.
208
214
  // Directly deriving it from the plural makes sure we retain any parent namespaces of kind "entity",
209
215
  // which would not be possible while already in singular form, as "Book.text" could not be resolved in CSN.
210
- file.addInflection(util.singular4(plural), plural, clean)
216
+ // edge case: @singular annotation present. singular4 will take care of that.
217
+ file.addInflection(util.singular4(entity, true), plural, clean)
211
218
  if ('doc' in entity) {
212
219
  docify(entity.doc).forEach((d) => buffer.add(d))
213
220
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cap-js/cds-typer",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Generates .ts files for a CDS model to receive code completion in VS Code",
5
5
  "main": "index.js",
6
6
  "repository": "github:cap-js/cds-typer",
@@ -43,6 +43,7 @@
43
43
  "@sap/cds": ">=6"
44
44
  },
45
45
  "devDependencies": {
46
+ "acorn": "^8.10.0",
46
47
  "eslint": "^8.15.0",
47
48
  "eslint-config-prettier": "^8.5.0",
48
49
  "eslint-plugin-prettier": "^4.0.0",