Skip to content

Commit

Permalink
feat: add static property elements to entity classes (#345)
Browse files Browse the repository at this point in the history
  • Loading branch information
stockbal authored Oct 16, 2024
1 parent 852afea commit bfed040
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
## Version 0.28.0 - TBD
### Added
- Schema definition for `cds.typer` options in `package.json` and `.cdsrc-*.json` files
- Added a static `elements` property to all entities, which allows access to the `LinkedDefinitions` instance of an entity's elements
- Schema definition for `typescript` cds build task.

### Fixed
Expand Down
4 changes: 4 additions & 0 deletions lib/components/basedefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const timeRegex = '`${number}${number}:${number}${number}:${number}${number}`'
const baseDefinitions = new SourceFile('_')
// FIXME: this should be a library someday
baseDefinitions.addPreamble(`
import { type } from '@sap/cds'
export type ElementsOf<T> = {[name in keyof Required<T>]: type }
export namespace Association {
export type to <T> = T;
export namespace to {
Expand Down
8 changes: 8 additions & 0 deletions lib/components/wrappers.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ const createKey = t => `${base}.Key<${t}>`
*/
const createKeysOf = t => `${base}.KeysOf<${t}>`

/**
* Wraps type into ElementsOf type.
* @param {string} t - the type name.
* @returns {string}
*/
const createElementsOf = t => `${base}.ElementsOf<${t}>`

/**
* Wraps type into association to scalar.
* @param {string} t - the singular type name.
Expand Down Expand Up @@ -102,6 +109,7 @@ module.exports = {
createArrayOf,
createKey,
createKeysOf,
createElementsOf,
createObjectOf,
createPromiseOf,
createUnionOf,
Expand Down
11 changes: 10 additions & 1 deletion lib/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const { SourceFile, FileRepository, Buffer, Path } = require('./file')
const { FlatInlineDeclarationResolver, StructuredInlineDeclarationResolver } = require('./components/inline')
const { Resolver } = require('./resolution/resolver')
const { LOG } = require('./logging')
const { docify, createPromiseOf, createUnionOf, createKeysOf } = require('./components/wrappers')
const { docify, createPromiseOf, createUnionOf, createKeysOf, createElementsOf } = require('./components/wrappers')
const { csnToEnumPairs, propertyToInlineEnumName, isInlineEnumType, stringifyEnumType } = require('./components/enum')
const { isReferenceType } = require('./components/reference')
const { empty } = require('./components/typescript')
Expand Down Expand Up @@ -167,6 +167,14 @@ class Visitor {
buffer.add(`declare static readonly keys: ${createKeysOf(clean)}`)
}

/**
* @param {Buffer} buffer - the buffer to write the elements into
* @param {string} clean - the clean name of the entity
*/
#printStaticElements(buffer, clean) {
buffer.add(`declare static readonly elements: ${createElementsOf(clean)}`)
}

/**
* Transforms an entity or CDS aspect into a JS aspect (aka mixin).
* That is, for an element A we get:
Expand Down Expand Up @@ -281,6 +289,7 @@ class Visitor {
buffer.add(`static readonly kind: 'entity' | 'type' | 'aspect' = '${entity.kind}';`)
}
this.#printStaticKeys(buffer, clean)
this.#printStaticElements(buffer, clean)
this.#printStaticActions(entity, buffer, ancestorInfos, file)
}, '};') // end of generated class
}, '}') // end of aspect
Expand Down
19 changes: 19 additions & 0 deletions test/unit/files/elements/model.cds
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace elements_test;

aspect A1 {
A_f1 : String;
A_f2 : String;
}

entity E1 {
key ID: Integer;
a : String;
b : Integer;
}

entity E2 : A1 {
key ID: String;
d: Integer;
}

entity P1 as projection on E2;
26 changes: 26 additions & 0 deletions test/unit/files/elements/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import cds from '@sap/cds'
import { E1, E2, P1 } from '#cds-models/elements_test'

E1.elements
E1.elements.ID
E1.elements.a
E1.elements.b
// @ts-expect-error
E1.elements.nonExistent

E2.elements
E2.elements.d // from entity E1
E2.elements.A_f1 // from aspect A1

// check projection
P1.elements
P1.elements.ID
P1.elements.d
P1.elements.A_f1
P1.elements.A_f2

// check LinkedDefinitions types
E1.elements.a.type
E1.elements.a.kind
E1.elements.a.items
E1.elements.a instanceof cds.builtin.classes.String

0 comments on commit bfed040

Please sign in to comment.