Skip to content

Commit

Permalink
Small fixes and setup API extractor (#6)
Browse files Browse the repository at this point in the history
* Fix missing type by alias
* Avoid `export {* as ql} from...` syntax
* Skip release tags for now
* Use type indirection for cds type
* Fix TSDoc comments
* Add missing param name
* Fix fluent type, add test
* Export more types

---------

Co-authored-by: Daniel O'Grady <[email protected]>
  • Loading branch information
chgeo and daogrady committed Dec 12, 2023
1 parent 2b85d38 commit 27bb0ef
Show file tree
Hide file tree
Showing 14 changed files with 561 additions and 65 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules/
gen/
out/

# API extractor

dist/
temp/
etc/
tsdoc-metadata.json
449 changes: 449 additions & 0 deletions api-extractor.json

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions apis/cds.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ 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'

// FIXME: sort out what needs to be exported from csn/linked and under which namespace
// export { Association, CSN, Definition, Extension, Element, EntityElements, FQN, kinds } from './csn'
// export { Definitions, LinkedCSN, LinkedDefinition, LinkedAssociation, LinkedEntity, Filter, Visitor } from './linked'

// API extractor cannot handle export * as ql from './ql', so split it into an import and an export statement
import * as ql from './ql'
export { ql }
export { QLExtensions } from './ql' // cds-ql.ts test tries to import this from top level? Correct? Or ql.QLExtensions?

// 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: ql.QL<any>['SELECT']
Expand Down
9 changes: 9 additions & 0 deletions apis/core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,13 @@ export const builtin: {
/**
* Add aspects to a given object, for example:
*
* @example
* ```js
* 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>
Expand All @@ -62,9 +65,12 @@ export function extend<T>(target: T): {
* Equip a given facade object with getters for lazy-loading modules instead
* of static requires. Example:
*
* @example
* ```js
* 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.
Expand All @@ -75,10 +81,13 @@ export function lazify <T>(target: T) : T
* Prepare a node module for lazy-loading submodules instead
* of static requires. Example:
*
* @example
* ```js
* 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.
Expand Down
4 changes: 2 additions & 2 deletions apis/csn.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export type Definition = context & service & type & struct & entity & Associatio
// NOTE: If we use & instead of | CSN.definitions values would be reduced to <never>

/**
* Extensions capture extend Foo with { ... } directives.
* Extensions capture `extend Foo with { ... }` directives.
*/
export type Extension = {
extend: FQN
Expand Down Expand Up @@ -103,7 +103,7 @@ export interface Association extends type {
type: 'cds.Association' | 'cds.Composition'
target: FQN
/**
* The specified cardinality. to-one = {max:1}, to-many = {max:'*'}
* The specified cardinality. to-one = `{max:1}`, to-many = `{max:'*'}`
*/
cardinality?: { src?: 1; min?: 1 | 0; max?: 1 | '*' }
/**
Expand Down
2 changes: 1 addition & 1 deletion apis/events.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class Request extends Event {
path: string
target: LinkedDefinition
/**
* Shortcut to {@link target.name}
* Shortcut to {@link Request.target | target (entity) name}
* @see https://cap.cloud.sap/docs/node.js/events#req-entity
*/
entity: string
Expand Down
26 changes: 16 additions & 10 deletions apis/linked.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ export interface LinkedCSN extends CSN {
/**
* Fetches definitions matching the given filter, returning an iterator on them.
* @example
* let m = cds.reflect (aParsedModel)
* for (let d of m.each('entity')) console.log (d.kind, d.name)
* let entities = [...m.each('entity')] //> capture all
* let entities = m.all('entity') //> equivalent shortcut
* ```js
* let m = cds.reflect (aParsedModel)
* for (let d of m.each('entity')) console.log (d.kind, d.name)
* let entities = [...m.each('entity')] //> capture all
* let entities = m.all('entity') //> equivalent shortcut
* ```
*/
each(x: Filter, defs?: Definitions): IterableIterator<any>

Expand All @@ -43,8 +45,8 @@ export interface LinkedCSN extends CSN {
* Fetches definitions matching the given filter, returning the first match, if any.
* @example
* let service = model.find('service')
* @param {Filter} [x] the filter
* @param {Definitions} [defs] the definitions to fetch in, default: `this.definitions`
* @param x - the filter
* @param defs - the definitions to fetch in, default: `this.definitions`
*/
find(x: Filter, defs?: Definitions): any

Expand All @@ -67,10 +69,12 @@ export interface LinkedCSN extends CSN {
* It fetches all definitions whose fully-qualified names start with the parent's name.
* Returns the found definitions as an object with the local names as keys.
* @example
* let service = model.find ('service')
* let entities = m.childrenOf (service)
* @param parent either the parent itself or its fully-qualified name
* @param filter an optional filter to apply before picking a child
* ```js
* let service = model.find ('service')
* let entities = m.childrenOf (service)
* ```
* @param parent - either the parent itself or its fully-qualified name
* @param filter - an optional filter to apply before picking a child
*/
childrenOf(parent: any | string, filter?: ((def: LinkedDefinition) => boolean)): Definitions

Expand All @@ -80,13 +84,15 @@ export interface LinkedCSN extends CSN {
* working with fully-qualified names as follows:
*
* @example
* ```js
* let model = cds.reflect (cds.parse(`
* namespace our.lovely.bookshop;
* entity Books {...}
* entity Authors {...}
* `))
* const {Books,Authors} = model.exports
* SELECT.from (Books) .where ({ID:11})
* ```
*/
exports: Definitions & ((namespace: string) => Definitions)
entities: Definitions & ((namespace: string) => Definitions)
Expand Down
33 changes: 17 additions & 16 deletions apis/log.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ export declare const log: LogFactory
/**
* Shortcut to `cds.log(...).debug`, returning `undefined` if `cds.log(...)._debug` is `false`.
* Use like this:
* ```
* @example
* ```js
* const dbg = cds.debug('foo')
* ...
* dbg && dbg('message')
* ```
*
* @param name logger name
* @param name - logger name
*/
export declare function debug(name: string): undefined | Log

Expand All @@ -26,41 +27,41 @@ declare type LogFactory = {
*
* By default this logger would prefix all output with `[sql] - `
* You can change this by specifying another prefix in the options:
*
* ```
* @example
* ```js
* const LOG = cds.log('sql|db', { prefix: 'cds.ql' })
* ```
*
* Call `cds.log()` for a given module again to dynamically change the log level
* of all formerly created loggers, for example:
*
* ```
* @example
* ```js
* const LOG = cds.log('sql')
* LOG.info ('this will show, as default level is info')
* cds.log('sql', 'warn')
* LOG.info('this will be suppressed now')
* ```
*
* @param name logger name
* @param options level, label and prefix
* @param name - logger name
* @param options - level, label and prefix
* @returns the logger
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-log)
*/
(name: string, options?: string | number | { level?: number, label?: string, prefix?: string }): Logger

/**
* Set a custom formatter function like that:
* ```
* ```js
* cds.log.format = (module, level, ...args) => [ '[', module, ']', ...args ]
* ```
*
* The formatter shall return an array of arguments, which are passed to the logger (for example, `console.log()`)
*/
format: Formatter

/**
* Set a custom logger.
* ```
* ```js
* cds.log.Logger = ...
* ```
*/
Expand Down Expand Up @@ -140,9 +141,9 @@ declare type Formatter = {
/**
* Custom format function
*
* @param module logger name
* @param level log level
* @param args additional arguments
* @param module - logger name
* @param level - log level
* @param args - additional arguments
* @returns an array of arguments, which are passed to the logger (for example, `console.log()`)
*/
(module: string, level: number, args: any[]): any[]
Expand All @@ -152,8 +153,8 @@ declare type Log = {
/**
* Logs a message
*
* @param message text to log
* @param optionalParams additional parameters, same as in `console.log(text, param1, ...)`
* @param message - text to log
* @param optionalParams - additional parameters, same as in `console.log(text, param1, ...)`
*/
(message?: any, ...optionalParams: any[]): void
}
Expand Down
4 changes: 2 additions & 2 deletions apis/models.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ export const parse : {
* Loads and parses models from the specified files.
* Uses `cds.resolve` to fetch the respective models.
* Essentially a shortcut for `cds.compile.to.csn(files)`
* @param {string} files - filenames of models or if folder containing models
* @param files - filenames of models or if folder containing models
*/
export function get (files: '*' | filename | filename[], o?:_options): Promise<CSN>

/**
* Shortcut for `cds.get(files, 'inferred')`
* @param {string} files - filenames of models or if folder containing models
* @param files - filenames of models or if folder containing models
*/
export function load (files: '*' | filename | filename[], o?:_options): Promise<CSN>

Expand Down
40 changes: 21 additions & 19 deletions apis/server.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import * as http from "http"
import * as cds from './cds'
import { Application } from "express"

type _cds = typeof cds

export const connect: {
/**
* Connects to a specific datasource.
Expand All @@ -21,7 +23,8 @@ import { Application } from "express"
* Connects the primary datasource.
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-connect)
*/
(options?: string | cds_connect_options): Promise<typeof cds> //> cds.connect(<options>)
// API extractor cannot handle the direct usages of the cds namespace in typeof cds, so add an indirection.
(options?: string | cds_connect_options): Promise<_cds> //> cds.connect(<options>)
}

/**
Expand All @@ -44,48 +47,47 @@ import { Application } from "express"
*/
// FIXME: this is actually supposed to be part of models.d.ts
// but had to be moved here so export * would not clash their definitions
export function on (event : 'loaded', listener : (model : CSN) => void): typeof cds
export function on (event : 'loaded', listener : (model : CSN) => void): _cds


/**
* Emitted whenever a specific service is connected for the first time.
*/
export function on(event: 'connect', listener: (srv: Service) => void): typeof cds
export function on(event: 'connect', listener: (srv: Service) => void): _cds


/**
* Emitted at the very beginning of the bootsrapping process, when the
* express application has been constructed but no middlewares or routes
* added yet.
*/
export function on (event : 'bootstrap', listener : (app : Application) => void) : typeof cds
export function once (event : 'bootstrap', listener : (app : Application) => void) : typeof cds
export function on (event : 'bootstrap', listener : (app : Application) => void) : _cds
export function once (event : 'bootstrap', listener : (app : Application) => void) : _cds

/**
* Emitted for each service served by cds.serve().
*/
export function on (event : 'serving', listener : (srv : Service) => void) : typeof cds
export function on (event : 'serving', listener : (srv : Service) => void) : _cds

/**
* Emitted by the default, built-in `server.js` when all services are
* constructed and mounted by cds.serve().
*/
export function on (event : 'served', listener : (all : cds_services) => void) : typeof cds
export function once (event : 'served', listener : (all : cds_services) => void) : typeof cds
export function on (event : 'served', listener : (all : cds_services) => void) : _cds
export function once (event : 'served', listener : (all : cds_services) => void) : _cds

/**
* Emitted by the default, built-in `server.js` when the http server
* is started and listening for incoming requests.
*/
export function on (event : 'listening', listener : (args : { server: http.Server, url:string }) => void) : typeof cds
export function once (event : 'listening', listener : (args : { server: http.Server, url:string }) => void) : typeof cds
export function on (event : 'listening', listener : (args : { server: http.Server, url:string }) => void) : _cds
export function once (event : 'listening', listener : (args : { server: http.Server, url:string }) => void) : _cds

/**
* Emitted by the default, built-in `server.js` when the http server
* is shutdown.
*/
export function on (event : 'shutdown', listener : () => void) : typeof cds
export function once (event : 'shutdown', listener : () => void) : typeof cds
export function on (event : 'shutdown', listener : () => void) : _cds
export function once (event : 'shutdown', listener : () => void) : _cds

/**
* Dictionary of all services constructed and/or connected.
Expand All @@ -112,7 +114,7 @@ export type service = {
* Use that in modules to get IntelliSense.
*/
impl (impl: ServiceImpl) : typeof impl
// impl <T> (srv:T, impl: ( typeof cds: T, srv: (T) ) => any) : typeof impl
// impl <T> (srv:T, impl: ( _cds: T, srv: (T) ) => any) : typeof impl

/**
* Array of all services constructed.
Expand All @@ -124,11 +126,11 @@ export type service = {
type cds_services = { [name:string]: Service }

interface cds_serve_fluent {
from (model : string | CSN) : typeof cds
to (protocol: string) : typeof cds
at (path: string) : typeof cds
in (app: Application) : typeof cds
with (impl: ServiceImpl | string) : typeof cds
from (model : string | CSN) : cds_serve_fluent
to (protocol: string) : cds_serve_fluent
at (path: string) : cds_serve_fluent
in (app: Application) : cds_serve_fluent
with (impl: ServiceImpl | string) : cds_serve_fluent
// (req,res) : void
}

Expand Down
3 changes: 2 additions & 1 deletion apis/services.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { SELECT, INSERT, UPDATE, DELETE, Query, ConstructedQuery, UPSERT } from './ql'
import { Awaitable } from './ql'
import { ArrayConstructable, Constructable } from './internal/inference'
import { LinkedCSN, LinkedDefinition, LinkedDefinitions, LinkedEntity } from './linked'
import { LinkedCSN, LinkedDefinition, Definitions as LinkedDefinitions, LinkedEntity } from './linked'
import { CSN } from './csn'
import { EventContext } from './events'
import { Request } from './events'
import { ReadableStream } from 'node:stream/web'


export class QueryAPI {
Expand Down
Loading

0 comments on commit 27bb0ef

Please sign in to comment.