@cap-js/cds-typer 0.26.0 → 0.28.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 +26 -1
- package/cds-plugin.js +11 -4
- package/lib/cli.js +172 -40
- package/lib/compile.js +10 -16
- package/lib/components/basedefs.js +20 -0
- package/lib/components/class.js +35 -0
- package/lib/components/enum.js +2 -2
- package/lib/components/inline.js +15 -9
- package/lib/components/javascript.js +2 -2
- package/lib/components/wrappers.js +49 -1
- package/lib/config.js +118 -0
- package/lib/csn.js +110 -147
- package/lib/file.js +37 -24
- package/lib/resolution/entity.js +1 -0
- package/lib/resolution/resolver.js +23 -14
- package/lib/typedefs.d.ts +82 -38
- package/lib/util.js +17 -64
- package/lib/visitor.js +119 -66
- package/library/cds.hana.ts +2 -2
- package/package.json +70 -2
package/lib/visitor.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
const util = require('./util')
|
|
4
4
|
|
|
5
|
-
const {
|
|
5
|
+
const { isView, isUnresolved, propagateForeignKeys, collectDraftEnabledEntities, isDraftEnabled, isType, isProjection, getMaxCardinality, isViewOrProjection, isEnum, isEntity } = require('./csn')
|
|
6
6
|
// eslint-disable-next-line no-unused-vars
|
|
7
7
|
const { SourceFile, FileRepository, Buffer, Path } = require('./file')
|
|
8
8
|
const { FlatInlineDeclarationResolver, StructuredInlineDeclarationResolver } = require('./components/inline')
|
|
9
9
|
const { Resolver } = require('./resolution/resolver')
|
|
10
10
|
const { LOG } = require('./logging')
|
|
11
|
-
const { docify, createPromiseOf, createUnionOf } = require('./components/wrappers')
|
|
11
|
+
const { docify, createPromiseOf, createUnionOf, createKeysOf, createElementsOf, stringIdent, createDraftsOf, createDraftOf } = require('./components/wrappers')
|
|
12
12
|
const { csnToEnumPairs, propertyToInlineEnumName, isInlineEnumType, stringifyEnumType } = require('./components/enum')
|
|
13
13
|
const { isReferenceType } = require('./components/reference')
|
|
14
14
|
const { empty } = require('./components/typescript')
|
|
@@ -16,23 +16,17 @@ const { baseDefinitions } = require('./components/basedefs')
|
|
|
16
16
|
const { EntityRepository, asIdentifier } = require('./resolution/entity')
|
|
17
17
|
const { last } = require('./components/identifier')
|
|
18
18
|
const { getPropertyModifiers } = require('./components/property')
|
|
19
|
+
const { configuration } = require('./config')
|
|
20
|
+
const { createMember } = require('./components/class')
|
|
19
21
|
|
|
20
22
|
/** @typedef {import('./file').File} File */
|
|
21
23
|
/** @typedef {import('./typedefs').visitor.Context} Context */
|
|
22
|
-
/** @typedef {import('./typedefs').visitor.CompileParameters} CompileParameters */
|
|
23
|
-
/** @typedef {import('./typedefs').visitor.VisitorOptions} VisitorOptions */
|
|
24
24
|
/** @typedef {import('./typedefs').visitor.Inflection} Inflection */
|
|
25
25
|
/** @typedef {import('./typedefs').resolver.CSN} CSN */
|
|
26
|
+
/** @typedef {import('./typedefs').resolver.TypeResolveOptions} TypeResolveOptions */
|
|
26
27
|
/** @typedef {import('./typedefs').resolver.EntityCSN} EntityCSN */
|
|
27
28
|
/** @typedef {import('./typedefs').resolver.EnumCSN} EnumCSN */
|
|
28
29
|
|
|
29
|
-
const defaults = {
|
|
30
|
-
// FIXME: add defaults for remaining parameters
|
|
31
|
-
propertiesOptional: true,
|
|
32
|
-
useEntitiesProxy: false,
|
|
33
|
-
inlineDeclarations: 'flat'
|
|
34
|
-
}
|
|
35
|
-
|
|
36
30
|
class Visitor {
|
|
37
31
|
/**
|
|
38
32
|
* Gathers all files that are supposed to be written to
|
|
@@ -46,12 +40,12 @@ class Visitor {
|
|
|
46
40
|
|
|
47
41
|
/**
|
|
48
42
|
* @param {{xtended: CSN, inferred: CSN}} csn - root CSN
|
|
49
|
-
* @param {VisitorOptions | {}} options - the options
|
|
50
43
|
*/
|
|
51
|
-
constructor(csn
|
|
52
|
-
|
|
44
|
+
constructor(csn) {
|
|
45
|
+
propagateForeignKeys(csn.xtended)
|
|
53
46
|
propagateForeignKeys(csn.inferred)
|
|
54
|
-
|
|
47
|
+
// has to be executed on the inferred model as autoexposed entities are not included in the xtended csn
|
|
48
|
+
collectDraftEnabledEntities(csn.inferred)
|
|
55
49
|
this.csn = csn
|
|
56
50
|
|
|
57
51
|
/** @type {Context[]} **/
|
|
@@ -64,12 +58,10 @@ class Visitor {
|
|
|
64
58
|
this.entityRepository = new EntityRepository(this.resolver)
|
|
65
59
|
|
|
66
60
|
/** @type {FileRepository} */
|
|
67
|
-
this.fileRepository = new FileRepository(
|
|
68
|
-
// REVISIT: better way to pass options to base source file ???
|
|
69
|
-
baseDefinitions.options = this.options
|
|
61
|
+
this.fileRepository = new FileRepository()
|
|
70
62
|
this.fileRepository.add(baseDefinitions.path.asNamespace(), baseDefinitions)
|
|
71
63
|
this.inlineDeclarationResolver =
|
|
72
|
-
|
|
64
|
+
configuration.inlineDeclarations === 'structured'
|
|
73
65
|
? new StructuredInlineDeclarationResolver(this)
|
|
74
66
|
: new FlatInlineDeclarationResolver(this)
|
|
75
67
|
|
|
@@ -105,7 +97,13 @@ class Visitor {
|
|
|
105
97
|
// FIXME: references to types of entity properties may be missing from xtendend flavour (see #103)
|
|
106
98
|
// this should be revisted once we settle on a single flavour.
|
|
107
99
|
const target = this.csn.xtended.definitions[targetName] ?? this.csn.inferred.definitions[targetName]
|
|
108
|
-
|
|
100
|
+
if (target.kind !== 'type') {
|
|
101
|
+
// skip if the target is a property, like in:
|
|
102
|
+
// books: Association to many Author.books ...
|
|
103
|
+
// as this would result in a type definition that
|
|
104
|
+
// name-clashes with the actual declaration of Author
|
|
105
|
+
this.visitEntity(name, target)
|
|
106
|
+
}
|
|
109
107
|
} else {
|
|
110
108
|
LOG.error(`Expecting an autoexposed projection within a service. Skipping ${name}`)
|
|
111
109
|
}
|
|
@@ -145,21 +143,58 @@ class Visitor {
|
|
|
145
143
|
: ''
|
|
146
144
|
if (actions.length) {
|
|
147
145
|
buffer.addIndentedBlock(`declare static readonly actions: ${inherited}{`,
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
146
|
+
() => {
|
|
147
|
+
for (const [aname, action] of actions) {
|
|
148
|
+
const [opener, content, closer] = SourceFile.stringifyLambda({
|
|
149
|
+
name: aname,
|
|
150
|
+
parameters: this.#stringifyFunctionParams(action.params, file),
|
|
151
|
+
returns: action.returns
|
|
152
|
+
? this.resolver.resolveAndRequire(action.returns, file).typeName
|
|
153
|
+
: 'any',
|
|
154
|
+
kind: action.kind,
|
|
155
|
+
doc: docify(action.doc)})
|
|
156
|
+
buffer.addIndentedBlock(opener, content, closer)
|
|
157
|
+
}
|
|
158
|
+
}, '}'
|
|
157
159
|
) // end of actions
|
|
158
160
|
} else {
|
|
159
|
-
buffer.add(
|
|
161
|
+
buffer.add(createMember({
|
|
162
|
+
name: 'actions',
|
|
163
|
+
type: `${inherited}${empty}`,
|
|
164
|
+
isStatic: true,
|
|
165
|
+
isReadonly: true
|
|
166
|
+
}))
|
|
160
167
|
}
|
|
161
168
|
}
|
|
162
169
|
|
|
170
|
+
/**
|
|
171
|
+
* @param {Buffer} buffer - the buffer to write the keys into
|
|
172
|
+
* @param {string} clean - the clean name of the entity
|
|
173
|
+
*/
|
|
174
|
+
#printStaticKeys(buffer, clean) {
|
|
175
|
+
buffer.add(createMember({
|
|
176
|
+
name: 'keys',
|
|
177
|
+
type: createKeysOf(clean),
|
|
178
|
+
isDeclare: true,
|
|
179
|
+
isStatic: true,
|
|
180
|
+
isReadonly: true,
|
|
181
|
+
}))
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @param {Buffer} buffer - the buffer to write the elements into
|
|
186
|
+
* @param {string} clean - the clean name of the entity
|
|
187
|
+
*/
|
|
188
|
+
#printStaticElements(buffer, clean) {
|
|
189
|
+
buffer.add(createMember({
|
|
190
|
+
name: 'elements',
|
|
191
|
+
type: createElementsOf(clean),
|
|
192
|
+
isDeclare: true,
|
|
193
|
+
isStatic: true,
|
|
194
|
+
isReadonly: true
|
|
195
|
+
}))
|
|
196
|
+
}
|
|
197
|
+
|
|
163
198
|
/**
|
|
164
199
|
* Transforms an entity or CDS aspect into a JS aspect (aka mixin).
|
|
165
200
|
* That is, for an element A we get:
|
|
@@ -227,12 +262,15 @@ class Visitor {
|
|
|
227
262
|
buffer.addIndentedBlock(`return class ${clean} extends ${ancestorsAspects} {`, () => {
|
|
228
263
|
/** @type {import('./typedefs').resolver.EnumCSN[]} */
|
|
229
264
|
const enums = []
|
|
230
|
-
|
|
265
|
+
/** @type {TypeResolveOptions} */
|
|
266
|
+
const resolverOptions = { forceInlineStructs: isEntity(entity) && configuration.inlineDeclarations === 'flat'}
|
|
267
|
+
|
|
268
|
+
for (let [ename, element] of Object.entries(entity.elements ?? [])) {
|
|
231
269
|
if (element.target && /\.texts?/.test(element.target)) {
|
|
232
270
|
LOG.warn(`referring to .texts property in ${fq}. This is currently not supported and will be ignored.`)
|
|
233
271
|
continue
|
|
234
272
|
}
|
|
235
|
-
this.visitElement(ename, element, file, buffer)
|
|
273
|
+
this.visitElement({name: ename, element, file, buffer, resolverOptions})
|
|
236
274
|
|
|
237
275
|
// make foreign keys explicit
|
|
238
276
|
if (element.target) {
|
|
@@ -248,7 +286,7 @@ class Visitor {
|
|
|
248
286
|
const kelement = Object.assign(Object.create(originalKeyElement), {
|
|
249
287
|
isRefNotNull: !!element.notNull || !!element.key
|
|
250
288
|
})
|
|
251
|
-
this.visitElement(foreignKey, kelement, file, buffer)
|
|
289
|
+
this.visitElement({name: foreignKey, element: kelement, file, buffer, resolverOptions})
|
|
252
290
|
}
|
|
253
291
|
}
|
|
254
292
|
}
|
|
@@ -260,35 +298,49 @@ class Visitor {
|
|
|
260
298
|
}
|
|
261
299
|
}
|
|
262
300
|
|
|
263
|
-
|
|
264
|
-
|
|
301
|
+
for (const e of enums) {
|
|
302
|
+
const eDoc = docify(e.doc)
|
|
303
|
+
buffer.add(eDoc)
|
|
304
|
+
buffer.add(createMember({
|
|
305
|
+
name: e.name,
|
|
306
|
+
initialiser: propertyToInlineEnumName(clean, e.name),
|
|
307
|
+
isStatic: true,
|
|
308
|
+
}))
|
|
309
|
+
file.addInlineEnum(clean, fq, e.name, csnToEnumPairs(e, {unwrapVals: true}), eDoc)
|
|
265
310
|
}
|
|
266
311
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
312
|
+
if ('kind' in entity) {
|
|
313
|
+
buffer.add(createMember({
|
|
314
|
+
name: 'kind',
|
|
315
|
+
type: '"entity" | "type" | "aspect"',
|
|
316
|
+
isStatic: true,
|
|
317
|
+
isReadonly: true,
|
|
318
|
+
isDeclare: false,
|
|
319
|
+
isOverride: ancestorInfos.some(ancestor => ancestor.csn.kind),
|
|
320
|
+
initialiser: stringIdent(entity.kind)
|
|
321
|
+
}))
|
|
322
|
+
}
|
|
323
|
+
this.#printStaticKeys(buffer, clean)
|
|
324
|
+
this.#printStaticElements(buffer, clean)
|
|
325
|
+
this.#printStaticActions(entity, buffer, ancestorInfos, file)
|
|
276
326
|
}, '};') // end of generated class
|
|
277
327
|
}, '}') // end of aspect
|
|
278
328
|
|
|
279
329
|
// CLASS WITH ADDED ASPECTS
|
|
280
330
|
file.addImport(baseDefinitions.path)
|
|
281
331
|
docify(entity.doc).forEach(d => { buffer.add(d) })
|
|
282
|
-
buffer.add(`export class ${identSingular(clean)} extends ${identAspect(toLocalIdent({clean, fq}))}(${baseDefinitions.path.asIdentifier()}.Entity) {${this.#staticClassContents(
|
|
332
|
+
buffer.add(`export class ${identSingular(clean)} extends ${identAspect(toLocalIdent({clean, fq}))}(${baseDefinitions.path.asIdentifier()}.Entity) {${this.#staticClassContents(fq, clean).join('\n')}}`)
|
|
283
333
|
this.contexts.pop()
|
|
284
334
|
}
|
|
285
335
|
|
|
286
336
|
/**
|
|
337
|
+
* @param {string} fq - fully qualified name of the entity
|
|
287
338
|
* @param {string} clean - the clean name of the entity
|
|
288
|
-
* @param {
|
|
339
|
+
* @param {boolean} [isPlural] - `true` if passed entity is plural
|
|
289
340
|
*/
|
|
290
|
-
#staticClassContents(clean,
|
|
291
|
-
|
|
341
|
+
#staticClassContents(fq, clean, isPlural = false) {
|
|
342
|
+
if (!isDraftEnabled(fq)) return []
|
|
343
|
+
return [`static drafts: ${isPlural ? createDraftsOf(clean) : createDraftOf(clean)}`]
|
|
292
344
|
}
|
|
293
345
|
|
|
294
346
|
/**
|
|
@@ -344,9 +396,6 @@ class Visitor {
|
|
|
344
396
|
? this.csn.inferred.definitions[fq]
|
|
345
397
|
: entity
|
|
346
398
|
|
|
347
|
-
// draft enablement is stored in csn.xtended. Iff we took the entity from csn.inferred, we have to carry the draft-enablement over at this point
|
|
348
|
-
target['@odata.draft.enabled'] = isDraftEnabled(entity)
|
|
349
|
-
|
|
350
399
|
this.#aspectify(fq, target, buffer, { cleanName: singular })
|
|
351
400
|
|
|
352
401
|
buffer.add(overrideNameProperty(singular, entity.name))
|
|
@@ -362,13 +411,13 @@ class Visitor {
|
|
|
362
411
|
}
|
|
363
412
|
// plural can not be a type alias to $singular[] but needs to be a proper class instead,
|
|
364
413
|
// so it can get passed as value to CQL functions.
|
|
365
|
-
const additionalProperties = this.#staticClassContents(singular,
|
|
414
|
+
const additionalProperties = this.#staticClassContents(fq, singular, true)
|
|
366
415
|
additionalProperties.push('$count?: number')
|
|
367
|
-
docify(entity.doc)
|
|
416
|
+
buffer.add(docify(entity.doc))
|
|
368
417
|
buffer.add(`export class ${plural} extends Array<${singular}> {${additionalProperties.join('\n')}}`)
|
|
369
418
|
buffer.add(overrideNameProperty(plural, entity.name))
|
|
370
419
|
}
|
|
371
|
-
buffer.
|
|
420
|
+
buffer.blankLine()
|
|
372
421
|
}
|
|
373
422
|
|
|
374
423
|
/**
|
|
@@ -488,12 +537,13 @@ class Visitor {
|
|
|
488
537
|
buffer.add('// event')
|
|
489
538
|
// only declare classes, as their properties are not optional, so we don't have to do awkward initialisation thereof.
|
|
490
539
|
buffer.addIndentedBlock(`export declare class ${entityName} {`, () => {
|
|
491
|
-
const propOpt =
|
|
492
|
-
|
|
540
|
+
const propOpt = configuration.propertiesOptional
|
|
541
|
+
// FIXME: shouldn't need to change config here! Idea: init Visitor with .options fed from config, then manipulate that
|
|
542
|
+
configuration.propertiesOptional = false
|
|
493
543
|
for (const [ename, element] of Object.entries(event.elements ?? {})) {
|
|
494
|
-
this.visitElement(ename, element, file, buffer)
|
|
544
|
+
this.visitElement({name: ename, element, file, buffer})
|
|
495
545
|
}
|
|
496
|
-
|
|
546
|
+
configuration.propertiesOptional = propOpt
|
|
497
547
|
}, '}')
|
|
498
548
|
}
|
|
499
549
|
|
|
@@ -512,12 +562,12 @@ class Visitor {
|
|
|
512
562
|
// file.addImport(new Path(['cds'], '')) TODO make sap/cds import work
|
|
513
563
|
buffer.addIndentedBlock(`export class ${serviceNameSimple} extends cds.Service {`, () => {
|
|
514
564
|
Object.entries(service.operations ?? {}).forEach(([name, {doc}]) => {
|
|
515
|
-
|
|
565
|
+
buffer.add(docify(doc))
|
|
516
566
|
buffer.add(`declare ${name}: typeof ${name}`)
|
|
517
567
|
})
|
|
518
568
|
}, '}')
|
|
519
569
|
buffer.add(`export default ${serviceNameSimple}`)
|
|
520
|
-
buffer.
|
|
570
|
+
buffer.blankLine()
|
|
521
571
|
file.addService(service.name)
|
|
522
572
|
}
|
|
523
573
|
|
|
@@ -580,13 +630,15 @@ class Visitor {
|
|
|
580
630
|
|
|
581
631
|
/**
|
|
582
632
|
* Visits a single element in an entity.
|
|
583
|
-
* @param {
|
|
584
|
-
* @param {
|
|
585
|
-
* @param {
|
|
586
|
-
* @param {
|
|
633
|
+
* @param {object} options - options
|
|
634
|
+
* @param {string} options.name - name of the element
|
|
635
|
+
* @param {EntityCSN} options.element - CSN data belonging to the the element.
|
|
636
|
+
* @param {SourceFile} options.file - the namespace file the surrounding entity is being printed into.
|
|
637
|
+
* @param {Buffer} [options.buffer] - buffer to add the definition to. If no buffer is passed, the passed file's class buffer is used instead.
|
|
638
|
+
* @param {TypeResolveOptions} [options.resolverOptions] - custom type resolver options
|
|
587
639
|
* @returns @see InlineDeclarationResolver.visitElement
|
|
588
640
|
*/
|
|
589
|
-
visitElement(name, element, file, buffer = file.classes) {
|
|
641
|
+
visitElement({name, element, file, buffer = file.classes, resolverOptions}) {
|
|
590
642
|
return this.inlineDeclarationResolver.visitElement({
|
|
591
643
|
name,
|
|
592
644
|
element,
|
|
@@ -594,7 +646,8 @@ class Visitor {
|
|
|
594
646
|
buffer,
|
|
595
647
|
// we explicitly pass the "declare" modifier here to avoid problems with noImplicitOverride and useDefineForClassFields in strict tsconfigs
|
|
596
648
|
// but not inside type defs (e.g. parameter types) where this would be a syntax error
|
|
597
|
-
modifiers: getPropertyModifiers(element)
|
|
649
|
+
modifiers: getPropertyModifiers(element),
|
|
650
|
+
resolverOptions
|
|
598
651
|
})
|
|
599
652
|
}
|
|
600
653
|
}
|
package/library/cds.hana.ts
CHANGED
|
@@ -9,7 +9,7 @@ export class VARCHAR extends String {};
|
|
|
9
9
|
export class CLOB extends String {};
|
|
10
10
|
export class BINARY extends String {}
|
|
11
11
|
export class ST_POINT {
|
|
12
|
-
public x: number;
|
|
13
|
-
public y: number;
|
|
12
|
+
declare public x: number;
|
|
13
|
+
declare public y: number;
|
|
14
14
|
}
|
|
15
15
|
export class ST_GEOMETRY { /* FIXME */ }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js/cds-typer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.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",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"doc:prepare": "npm run doc:clean && mkdir -p doc/types",
|
|
26
26
|
"doc:typegen": "./node_modules/.bin/tsc ./lib/*.js --skipLibCheck --declaration --allowJs --emitDeclarationOnly --outDir doc/types && cd doc/types && tsc --init",
|
|
27
27
|
"doc:cli": "npm run cli -- --help > ./doc/cli.txt",
|
|
28
|
-
"jsdoc:check": "tsc --noEmit --project jsconfig.json"
|
|
28
|
+
"jsdoc:check": "tsc --noEmit --project jsconfig.json",
|
|
29
|
+
"write:cds-typer-shema": "node scripts/write-cds-typer-schema.js"
|
|
29
30
|
},
|
|
30
31
|
"files": [
|
|
31
32
|
"lib/",
|
|
@@ -60,5 +61,72 @@
|
|
|
60
61
|
"test/smoke.jest.config.js",
|
|
61
62
|
"test/unit.jest.config.js"
|
|
62
63
|
]
|
|
64
|
+
},
|
|
65
|
+
"cds": {
|
|
66
|
+
"schema": {
|
|
67
|
+
"buildTaskType": {
|
|
68
|
+
"name": "typescript",
|
|
69
|
+
"description": "TypeScript build plugin. For use after the nodejs build task."
|
|
70
|
+
},
|
|
71
|
+
"cds": {
|
|
72
|
+
"typer": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"description": "Configuration for CDS Typer",
|
|
75
|
+
"properties": {
|
|
76
|
+
"output_directory": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"description": "Root directory to write the generated files to.",
|
|
79
|
+
"default": "@cds-models"
|
|
80
|
+
},
|
|
81
|
+
"log_level": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"description": "Minimum log level that is printed.\nThe default is only used if no explicit value is passed\nand there is no configuration passed via cds.env either.",
|
|
84
|
+
"enum": [
|
|
85
|
+
"SILENT",
|
|
86
|
+
"ERROR",
|
|
87
|
+
"WARN",
|
|
88
|
+
"INFO",
|
|
89
|
+
"DEBUG",
|
|
90
|
+
"TRACE",
|
|
91
|
+
"SILLY",
|
|
92
|
+
"VERBOSE",
|
|
93
|
+
"WARNING",
|
|
94
|
+
"CRITICAL",
|
|
95
|
+
"NONE"
|
|
96
|
+
],
|
|
97
|
+
"default": "ERROR"
|
|
98
|
+
},
|
|
99
|
+
"js_config_path": {
|
|
100
|
+
"type": "string",
|
|
101
|
+
"description": "Path to where the jsconfig.json should be written.\nIf specified, cds-typer will create a jsconfig.json file and\nset it up to restrict property usage in types entities to\nexisting properties only."
|
|
102
|
+
},
|
|
103
|
+
"use_entities_proxy": {
|
|
104
|
+
"type": "boolean",
|
|
105
|
+
"description": "If set to true the 'cds.entities' exports in the generated 'index.js'\nfiles will be wrapped in 'Proxy' objects\nso static import/require calls can be used everywhere.\n\nWARNING: entity properties can still only be accessed after\n'cds.entities' has been loaded",
|
|
106
|
+
"default": false
|
|
107
|
+
},
|
|
108
|
+
"inline_declarations": {
|
|
109
|
+
"type": "string",
|
|
110
|
+
"description": "Whether to resolve inline type declarations\nflat: (x_a, x_b, ...)\nor structured: (x: {a, b}).",
|
|
111
|
+
"enum": [
|
|
112
|
+
"flat",
|
|
113
|
+
"structured"
|
|
114
|
+
],
|
|
115
|
+
"default": "structured"
|
|
116
|
+
},
|
|
117
|
+
"properties_optional": {
|
|
118
|
+
"type": "boolean",
|
|
119
|
+
"description": "If set to true, properties in entities are\nalways generated as optional (a?: T).",
|
|
120
|
+
"default": true
|
|
121
|
+
},
|
|
122
|
+
"ieee754compatible": {
|
|
123
|
+
"type": "boolean",
|
|
124
|
+
"description": "If set to true, floating point properties are generated\nas IEEE754 compatible '(number | string)' instead of 'number'.",
|
|
125
|
+
"default": false
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
63
131
|
}
|
|
64
132
|
}
|