@cap-js/cds-typer 0.6.0 → 0.7.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 +18 -1
- package/lib/cli.js +1 -1
- package/lib/components/resolver.js +5 -1
- package/lib/visitor.js +27 -18
- package/package.json +1 -1
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
|
+
## Version 0.7.1 - TBD
|
|
8
8
|
|
|
9
9
|
### Changed
|
|
10
10
|
|
|
@@ -12,6 +12,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
|
12
12
|
|
|
13
13
|
### Fixed
|
|
14
14
|
|
|
15
|
+
## Version 0.7.0 - 2023-08-22
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- Support for `[many] $self` syntax in bound action parameters
|
|
21
|
+
- Foreign keys are now present in the generated types in addition to the resolved property
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
## Version 0.6.1 - 2023-08-10
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- Removed a warning about circular imports
|
|
15
32
|
|
|
16
33
|
## Version 0.6.0 - 2023-08-07
|
|
17
34
|
|
package/lib/cli.js
CHANGED
|
@@ -44,7 +44,7 @@ const flags = {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const hint = () =>
|
|
47
|
+
const hint = () => 'Missing or invalid parameter(s). Call with --help for more details.'
|
|
48
48
|
const indent = (s, indentation) => s.split(EOL).map(line => `${indentation}${line}`).join(EOL)
|
|
49
49
|
|
|
50
50
|
const help = () => `SYNOPSIS${EOL2}` +
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
const util = require('../util')
|
|
4
4
|
const { Buffer, SourceFile, Path, Library, baseDefinitions } = require("../file")
|
|
5
5
|
const { deepRequire, createToManyAssociation, createToOneAssociation, createArrayOf, createCompositionOfMany, createCompositionOfOne } = require('./wrappers')
|
|
6
|
-
const { Visitor } = require("../visitor")
|
|
7
6
|
const { StructuredInlineDeclarationResolver } = require("./inline")
|
|
8
7
|
|
|
9
8
|
/** @typedef {{ cardinality?: { max?: '*' | number } }} EntityCSN */
|
|
10
9
|
/** @typedef {{ definitions?: Object<string, EntityCSN> }} CSN */
|
|
10
|
+
/** @typedef {import('../visitor').Visitor} Visitor */
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* When nested inline types require additional imports. E.g.:
|
|
@@ -445,6 +445,10 @@ class Resolver {
|
|
|
445
445
|
result.path = new Path(path) // FIXME: relative to current file
|
|
446
446
|
result.csn = this.csn.definitions[t]
|
|
447
447
|
result.plainName = this.trimNamespace(t)
|
|
448
|
+
} else if (t === '$self') {
|
|
449
|
+
result.type = 'this'
|
|
450
|
+
result.isBuiltin = true
|
|
451
|
+
result.plainName = 'this'
|
|
448
452
|
} else {
|
|
449
453
|
// type offered by some library
|
|
450
454
|
const lib = this.libraries.find((lib) => lib.offers(t))
|
package/lib/visitor.js
CHANGED
|
@@ -59,7 +59,6 @@ class Visitor {
|
|
|
59
59
|
* @param {VisitorOptions} options
|
|
60
60
|
*/
|
|
61
61
|
constructor(csn, options = {}, logger = new Logger()) {
|
|
62
|
-
util.fixCSN(csn)
|
|
63
62
|
this.options = { ...defaults, ...options }
|
|
64
63
|
this.logger = logger
|
|
65
64
|
this.csn = csn
|
|
@@ -130,16 +129,16 @@ class Visitor {
|
|
|
130
129
|
buffer.indent()
|
|
131
130
|
for (const [ename, element] of Object.entries(entity.elements ?? {})) {
|
|
132
131
|
this.visitElement(ename, element, file, buffer)
|
|
132
|
+
// make foreign keys explicit
|
|
133
|
+
for (const [fkname, fkelement] of Object.entries(element.foreignKeys ?? {})) {
|
|
134
|
+
this.visitElement(`${ename}_${fkname}`, fkelement, file, buffer)
|
|
135
|
+
}
|
|
133
136
|
}
|
|
134
137
|
for (const [aname, action] of Object.entries(entity.actions ?? {})) {
|
|
135
|
-
const lambdaString =
|
|
136
138
|
buffer.add(
|
|
137
139
|
SourceFile.stringifyLambda({
|
|
138
140
|
name: aname,
|
|
139
|
-
parameters:
|
|
140
|
-
n,
|
|
141
|
-
this.resolver.resolveAndRequire(t, file).typeName,
|
|
142
|
-
]),
|
|
141
|
+
parameters: this.#stringifyFunctionParams(action.params, file),
|
|
143
142
|
returns: action.returns ? this.resolver.resolveAndRequire(action.returns, file).typeName : 'any',
|
|
144
143
|
initialiser: `undefined as unknown as this['${aname}']`
|
|
145
144
|
})
|
|
@@ -226,17 +225,32 @@ class Visitor {
|
|
|
226
225
|
buffer.add('')
|
|
227
226
|
}
|
|
228
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Stringifies function parameters in preparation of passing them to {@link SourceFile.stringifyLambda}.
|
|
230
|
+
* Resolves all parameters to a pair of parameter name and name of the resolved type.
|
|
231
|
+
* Also filters out parameters that indicate a binding parameter ({@link https://cap.cloud.sap/docs/releases/jan23#simplified-syntax-for-binding-parameters}).
|
|
232
|
+
* @param {[string, object][]} params - parameter list as found in CSN.
|
|
233
|
+
* @param {File} file - source file relative to which the parameter types should be resolved.
|
|
234
|
+
* @returns {[string, string][]} pair of names and types.
|
|
235
|
+
*/
|
|
236
|
+
#stringifyFunctionParams(params, file) {
|
|
237
|
+
return params
|
|
238
|
+
? Object.entries(params)
|
|
239
|
+
// filter params of type '[many] $self', as they are not to be part of the implementation
|
|
240
|
+
.filter(([, type]) => type?.type !== '$self' && !(type.items?.type === '$self'))
|
|
241
|
+
.map(([name, type]) => [
|
|
242
|
+
name,
|
|
243
|
+
this.resolver.resolveAndRequire(type, file).typeName,
|
|
244
|
+
])
|
|
245
|
+
: []
|
|
246
|
+
}
|
|
247
|
+
|
|
229
248
|
#printFunction(name, func) {
|
|
230
249
|
// FIXME: mostly duplicate of printAction -> reuse
|
|
231
250
|
this.logger.debug(`Printing function ${name}:\n${JSON.stringify(func, null, 2)}`)
|
|
232
251
|
const ns = this.resolver.resolveNamespace(name.split('.'))
|
|
233
252
|
const file = this.getNamespaceFile(ns)
|
|
234
|
-
const params = func.params
|
|
235
|
-
? Object.entries(func.params).map(([pname, ptype]) => [
|
|
236
|
-
pname,
|
|
237
|
-
this.resolver.resolveAndRequire(ptype, file).typeName,
|
|
238
|
-
])
|
|
239
|
-
: []
|
|
253
|
+
const params = this.#stringifyFunctionParams(func.params, file)
|
|
240
254
|
const returns = this.resolver.resolveAndRequire(func.returns, file).typeName
|
|
241
255
|
file.addFunction(name.split('.').at(-1), params, returns)
|
|
242
256
|
}
|
|
@@ -245,12 +259,7 @@ class Visitor {
|
|
|
245
259
|
this.logger.debug(`Printing action ${name}:\n${JSON.stringify(action, null, 2)}`)
|
|
246
260
|
const ns = this.resolver.resolveNamespace(name.split('.'))
|
|
247
261
|
const file = this.getNamespaceFile(ns)
|
|
248
|
-
const params = action.params
|
|
249
|
-
? Object.entries(action.params).map(([pname, ptype]) => [
|
|
250
|
-
pname,
|
|
251
|
-
this.resolver.resolveAndRequire(ptype, file).typeName,
|
|
252
|
-
])
|
|
253
|
-
: []
|
|
262
|
+
const params = this.#stringifyFunctionParams(action.params, file)
|
|
254
263
|
const returns = this.resolver.resolveAndRequire(action.returns, file).typeName
|
|
255
264
|
file.addAction(name.split('.').at(-1), params, returns)
|
|
256
265
|
}
|