Skip to content

Commit

Permalink
Fix Missing exports & failing tests (#4)
Browse files Browse the repository at this point in the history
* Add proxy methods to this.db
* Work around "delete" keyword restrictions
* Remove duplicate declaration of tx
* headers are optional
* .entities, etc. return linked definitions
* Add commented-out disconnection signature
* Remove leftover dev-comments
* compat coding moved to cds
* Expose Test class
* Remove Test class from top level export again
* Make event context optional
* Reintroduced missing Application import
* Remove leftover comment
* Remove generic default "any"
* Add LinkedDefinitions alias and fix test-test

---------

Co-authored-by: Johannes Vogel <johannes.vogel@sap.com>
  • Loading branch information
daogrady and johannes-vogel authored Dec 11, 2023
1 parent 8352a9e commit 2b85d38
Show file tree
Hide file tree
Showing 16 changed files with 472 additions and 483 deletions.
54 changes: 27 additions & 27 deletions apis/cds.d.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import * as ql from './ql'

declare global {
const cds : cds_facade
}
export * from './core'
export * from './server'
export * from './env'
export * from './models'
export * from './services'
export * from './events'
export * from './utils'
export { log, debug } from './log'
// FIXME: rename clashes to Linked.*
// export * from './csn'
export { test } from './test'
export * from './cqn'
export * as ql from './ql'
export { QLExtensions } from './ql' // cds-ql.ts test tries to import this from top level? Correct? Or ql.QLExtensions?

export = cds

type cds_facade = {}
& import('./core').default
& import('./env').default
& import('./models').default
& import('./server').default
& import('./services').QueryAPI
& import('./services').default
& import('./events').default
& import('./ql').cds_ql
& import('./log')
& import('./utils')
& import('./test')
// trick to work around "delete" as reserved identifier
import { Service } from './services'
declare const delete_: Service['delete']
export { delete_ as delete }

import * as ql from './ql'
declare global {
// these provide the functionality from SELECT, INSERT, etc in the global facade
const SELECT: typeof cds.ql.SELECT
const INSERT: typeof cds.ql.INSERT
const UPSERT: typeof cds.ql.UPSERT
const UPDATE: typeof cds.ql.UPDATE
const DELETE: typeof cds.ql.DELETE
const CREATE: typeof cds.ql.CREATE
const DROP: typeof cds.ql.DROP
const SELECT: ql.QL<any>['SELECT']
const INSERT: ql.QL<any>['INSERT']
const UPSERT: ql.QL<any>['UPSERT']
const UPDATE: ql.QL<any>['UPDATE']
const DELETE: ql.QL<any>['DELETE']
const CREATE: ql.QL<any>['CREATE']
const DROP: ql.QL<any>['DROP']

// and these allow us to use them as type too, i.e. `const q: SELECT<Book> = ...`
type SELECT<T> = ql.SELECT<T>
Expand All @@ -37,4 +37,4 @@ declare global {
type DELETE<T> = ql.DELETE<T>
type CREATE<T> = ql.CREATE<T>
type DROP<T> = ql.DROP<T>
}
}
149 changes: 67 additions & 82 deletions apis/core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,85 @@ import { LinkedAssociation, LinkedEntity, linked } from './linked'
import * as csn from './csn'
import { service } from './server'

type Intersect<T extends readonly unknown[]> = T extends [infer Head, ...infer Tail]
? Head & Intersect<Tail>
: unknown

// These are classes actually -> using the new() => interface trick
/**
* Base class for linked Associations from reflected models.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#cds-Association)
*/
export type Association = new(_?:object) => LinkedAssociation
/**
* Base class for linked Compositions from reflected models.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#cds-Association)
*/
export type Composition = new(_?:object) => LinkedAssociation
/**
* Base class for linked entities from reflected models.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#cds-entity)
*/
export type entity = new(_?:object) => LinkedEntity
export type event = new(_?:object) => linked & csn.struct
export type type = new(_?:object) => linked & csn.type
export type array = new(_?:object) => linked & csn.type
export type struct = new(_?:object) => linked & csn.struct

export default class cds {
// infer (query : cqn, model : csn) : LinkedDefinition

builtin: {
/**
* Base classes of linked definitions from reflected models.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#cds-builtin-classes)
*/
classes: {
Association: Association
Composition: Composition
entity: entity
event: event
type: type
array: array
struct: struct
service: service
}
types: {}
}

/**
* Base class for linked Associations from reflected models.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#cds-Association)
*/
Association: Association

/**
* Base class for linked Compositions from reflected models.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#cds-Association)
*/
Composition: Composition

/**
* Base class for linked entities from reflected models.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#cds-entity)
*/
entity: entity

event: event
type: type
array: array
struct: struct

// infer (query : cqn, model : csn) : LinkedDefinition
export const builtin: {
/**
* Add aspects to a given object, for example:
*
* extend (Object.prototype) .with (class {
* get foo() { return ... }
* bar() {...}
* }.prototype)
* Base classes of linked definitions from reflected models.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-reflect#cds-builtin-classes)
*/
extend<T>(target: T): {
with<E extends readonly unknown[]>(...ext: E): T & Intersect<E>
classes: {
Association: Association
Composition: Composition
entity: entity
event: event
type: type
array: array
struct: struct
service: service
}
types: {}
}

/**
* Equip a given facade object with getters for lazy-loading modules instead
* of static requires. Example:
*
* const facade = lazify ({
* sub: lazy => require ('./sub-module')
* })
*
* The first usage of `facade.sub` will load the sub module
* using standard Node.js's `module.require` functions.
*/
lazify <T>(target: T) : T

/**
* Prepare a node module for lazy-loading submodules instead
* of static requires. Example:
*
* require = lazify (module) //> turns require into a lazy one
* const facade = module.exports = {
* sub: require ('./sub-module')
* })
*
* The first usage of `facade.sub` will load the sub module
* using standard Node.js's `module.require` functions.
*/
lazified <T>(target: T) : T

/**
* Add aspects to a given object, for example:
*
* extend (Object.prototype) .with (class {
* get foo() { return ... }
* bar() {...}
* }.prototype)
*/
export function extend<T>(target: T): {
with<E extends readonly unknown[]>(...ext: E): T & Intersect<E>
}

type Intersect<T extends readonly unknown[]> = T extends [infer Head, ...infer Tail]
? Head & Intersect<Tail>
: unknown
/**
* Equip a given facade object with getters for lazy-loading modules instead
* of static requires. Example:
*
* const facade = lazify ({
* sub: lazy => require ('./sub-module')
* })
*
* The first usage of `facade.sub` will load the sub module
* using standard Node.js's `module.require` functions.
*/
export function lazify <T>(target: T) : T

/**
* Prepare a node module for lazy-loading submodules instead
* of static requires. Example:
*
* require = lazify (module) //> turns require into a lazy one
* const facade = module.exports = {
* sub: require ('./sub-module')
* })
*
* The first usage of `facade.sub` will load the sub module
* using standard Node.js's `module.require` functions.
*/
export function lazified <T>(target: T) : T
11 changes: 11 additions & 0 deletions apis/cqn.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,31 @@ export type DROP = {DROP:{
view: ref
}}

/** @private */
type scalar = number | string | boolean | null
/** @private */
type data = Record<string,any>
/** @private */
type name = string
/** @private */
type source = ( ref | SELECT ) & { as?: name, join?:name, on?:xpr }
export type column_expr = expr & { as?: name, cast?:any, expand?: column_expr[], inline?: column_expr[] }
export type predicate = _xpr
/** @private */
type ordering_term = expr & { sort?: "asc"|"desc", nulls?: "first"|"last" }

export type expr = ref | val | xpr | function_call | SELECT
/** @private */
type ref = {ref:( name & { id?:string, where?:expr, args?:expr[] } )[]}
/** @private */
type val = {val:any}
/** @private */
type xpr = {xpr:_xpr}
/** @private */
type _xpr = ( expr | operator ) []
/** @private */
type operator = string
/** @private */
type function_call = {func: string, args: {[key: string]: unknown}[]}

export type enum_literal = {"#": string}
Expand Down
27 changes: 12 additions & 15 deletions apis/env.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
export default class {
/**
* Access to the configuration for Node.js runtime and tools.
* The object is the effective result of configuration merged from various sources,
* filtered through the currently active profiles, thus highly dependent on the current working
* directory and process environment.
*/
env : {
/**
* Access to the configuration for Node.js runtime and tools.
* The object is the effective result of configuration merged from various sources,
* filtered through the currently active profiles, thus highly dependent on the current working
* directory and process environment.
*/
export const env : {
build: any,
hana: any,
i18n: any,
Expand All @@ -15,11 +14,9 @@ export default class {
odata: any,
query: any,
sql: any
}
} & { [key: string]: any } // to allow additional values we have not yet captured

requires: any
version: string
home: string
root: string

}
export const requires: any
export const version: string
export const home: string
export const root: string
33 changes: 6 additions & 27 deletions apis/events.d.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,15 @@
import { LinkedDefinition } from './linked'
import { Query } from './cqn'
import { ref } from './cqn'
import * as express from "express"


export default class cds {

/**
* @see [capire docs](https://cap.cloud.sap/docs/node.js/events)
*/
EventContext: typeof EventContext

/**
* @see [capire docs](https://cap.cloud.sap/docs/node.js/events)
*/
Event: typeof Event

/**
* @see [capire docs](https://cap.cloud.sap/docs/node.js/events)
*/
Request: typeof Request

/**
* Represents the user in a given context.
* @see [capire docs](https://cap.cloud.sap/docs/node.js/authentication#cds-user)
*/
User: typeof User
}
import * as express from 'express'


/**
* Represents the invocation context of incoming request and event messages.
* @see [capire docs](https://cap.cloud.sap/docs/node.js/events)
*/
export class EventContext {
constructor(properties:{event:string, data?:object, query?:object, headers:object});
constructor(properties:{event:string, data?:object, query?:object, headers?:object});
http?: {req: express.Request, res: express.Response}
tenant: string
user: User
Expand Down Expand Up @@ -97,6 +72,10 @@ export class Request extends Event {
}


/**
* Represents the user in a given context.
* @see [capire docs](https://cap.cloud.sap/docs/node.js/authentication#cds-user)
*/
export class User {
constructor(obj?: string | { id: string; attr: Record<string, string>; roles: Record<string, string> } | User)
id: string
Expand Down
4 changes: 3 additions & 1 deletion apis/linked.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { CSN, FQN, Association, Definition, entity, kinds } from "./csn"

export type LinkedDefinition = linked & Definition & LinkedEntity & LinkedAssociation
export type Definitions = { [name: string]: LinkedDefinition }

// FIXME: this is only a temporary alias. Definitions is actually correct,
// but the name may be misleading, as it is indeed a mapping of strings to LinkedDefinition objects.
export type LinkedDefinitions = Definitions
export interface linked {
is(kind: kinds | 'Association' | 'Composition'): boolean
name: FQN
Expand Down
Loading

0 comments on commit 2b85d38

Please sign in to comment.