Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed LinkedDefinitions in @sap/cds #204

Merged
merged 4 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
### Fixed
- The `@types/sap__cds` link created by the `postinstall` script now also works in monorepo setups where the target `@cap-js/cds-types` might already be preinstalled (often hoisted some levels up).

### Removed
- Removed array-like methods from model parts (`.map`, `.find`, etc.). To still use them, apply spreading to object in question first.

## Version 0.6.4 - 2024-08-05
### Added
- `Service.emit(...)` can now also be called with custom events
Expand Down
17 changes: 1 addition & 16 deletions apis/internal/util.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,8 @@ type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
/** @internal */
export type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U

// "ArrayLike" is taken since es5, so the underscore is both for @internal and to avoid clashes
/**
* A subset of array-like methods, but not `ArrayLike`, as it does not expose `.length`.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#iterable)
* @internal
* @since cds 7.9
*/
export type _ArrayLike<T> = Iterable<T> & {
forEach: (handler: (element: T) => any) => void,
filter: (predicate: (element: T) => boolean) => Array<T>,
map: <R>(converter: (element: T) => R) => Array<R>,
some: (predicate: (element: T) => boolean) => boolean,
find: (predicate: (element: T) => boolean) => T | undefined,
}

/**
* Object structure that exposes both array-like and object-like behaviour.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#iterable)
*/
export type IterableMap<T> = { [name: string]: T } & _ArrayLike<T>
export type IterableMap<T> = { [name: string]: T } & Iterable<T>
daogrady marked this conversation as resolved.
Show resolved Hide resolved
27 changes: 8 additions & 19 deletions test/typescript/apis/project/cds-linked.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { LinkedCSN } from '../../../../apis/linked';
import { _ArrayLike } from '../../../../apis/internal/util';
import cds from '@sap/cds';
import { csn } from '../../../..';
import { as } from './dummy';
Expand Down Expand Up @@ -30,8 +29,8 @@ csnStruct.is_struct
linkedCsn.exports[0].name
linkedCsn.exports['foo'].name
// @ts-expect-error only for entities and services
linkedCsn.exports('foo').bar
linkedCsn.exports.map(e => e.kind)
linkedCsn.exports('foo').bar;
[...linkedCsn.exports].map(e => e.kind)
linkedCsn.entities('foo')
const es: cds.linked.classes.entity[] = linkedCsn.all(x => Boolean(x.name), linkedCsn.entities)
// @ts-expect-error
Expand All @@ -40,15 +39,15 @@ const one: cds.linked.classes.entity | undefined = linkedCsn.find(x => Boolean(x
for (const each of linkedCsn.each(e => true, linkedCsn.entities)) each.keys

new entity().kind === 'entity'
new entity().keys.find
new entity().associations.find(Boolean)
new entity().compositions.find(Boolean)
new entity().actions.find(Boolean)
new entity().keys.find;
[...new entity().associations].find(Boolean);
[...new entity().compositions].find(Boolean);
[...new entity().actions].find(Boolean)
new entity().texts?.kind === 'entity'
new entity().drafts?.kind === 'entity'
new entity().is_entity === true
new entity().is_struct === true
new entity().elements.find(x => x.items.kind === 'type')
new entity().is_struct === true;
[...new entity().elements].find(x => x.items.kind === 'type')
new entity().items?.kind
new entity().name
// @ts-expect-error
Expand Down Expand Up @@ -88,16 +87,6 @@ mixin(class {}, class {})
// @ts-expect-error
mixin(42)

const arr: _ArrayLike<number> = as<_ArrayLike<number>>()
// @ts-expect-error
arr.length
const v: void = arr.forEach(x => x + 1)
const s: string[] = arr.map(x => ''+x)
const xs: number[] = arr.filter(x => x > 0)
const x: number | undefined = arr.find(x => x > 0)
const b: boolean = arr.some(x => x > 0)
for (const n of arr) n + 1

// spot check to make sure linked classes are properly exposed cds.linked.classes...
cds.linked.classes.entity === entity
// @ts-expect-error
Expand Down
8 changes: 4 additions & 4 deletions test/typescript/apis/project/cds-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,11 @@ const outboxedService = cds.outboxed(srv)
await outboxedService.send({ event: 'feeEstimation', entity: networkGroups, data: {name:'Volta'}})
await cds.unboxed(outboxedService).send({ event: 'feeEstimation', entity: networkGroups, data: {name:'Volta'}})

srv.entities('namespace')
srv.entities('namespace').map(e => e.keys) // .keys only available on entities
srv.entities('namespace');
[...srv.entities('namespace')].map(e => e.keys); // .keys only available on entities
// @ts-expect-error
srv.events('namespace').map(e => e.keys)
srv.events('namespace').map(e => e.elements)
[...srv.events('namespace')].map(e => e.keys);
[...srv.events('namespace')].map(e => e.elements)

// @ts-expect-error
srv.entities('namespace')('and again')