@cap-js/cds-types 0.0.1

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/apis/ql.d.ts ADDED
@@ -0,0 +1,330 @@
1
+ import { CSN, Definition, EntityElements } from "./csn"
2
+ import * as CQN from "./cqn"
3
+ import { Constructable, ArrayConstructable, SingularType } from "./internal/inference"
4
+ import { LinkedEntity } from "./linked"
5
+ import { ref, column_expr } from './cqn'
6
+
7
+ export type Query = CQN.Query
8
+
9
+ export class ConstructedQuery {
10
+ then(_resolved:(x:any)=>any, _rejected:(e:Error)=>any) : any
11
+ }
12
+
13
+ export class cds_ql {
14
+ ql:QL<any> & ((context:object) => QL<any>)
15
+ }
16
+
17
+ export type PK = number | string | object
18
+
19
+
20
+ type Primitive = string | number | boolean | Date
21
+
22
+ // don't wrap QLExtensions in more QLExtensions (indirection to work around recursive definition)
23
+ type QLExtensions<T> = T extends QLExtensions_<any> ? T : QLExtensions_<T>
24
+
25
+ /**
26
+ * QLExtensions are properties that are attached to entities in CQL contexts.
27
+ * They are passed down to all properties recursively.
28
+ */
29
+ type QLExtensions_<T> = {
30
+ [Key in keyof T]: QLExtensions<T[Key]>
31
+ } & {
32
+ /**
33
+ * Alias for this attribute.
34
+ */
35
+ as: (alias: string) => void
36
+
37
+ /**
38
+ * Accesses any nested attribute based on a [path](https://cap.cloud.sap/cap/docs/java/query-api#path-expressions):
39
+ * `X.get('a.b.c.d')`. Note that you will not receive
40
+ * proper typing after this call.
41
+ * To still have access to typed results, use
42
+ * `X.a().b().c().d()` instead.
43
+ */
44
+ get: (path: string) => any
45
+
46
+ // have to exclude undefined from the type, or we'd end up with a distribution of Subqueryable
47
+ // over T and undefined, which gives us zero code completion within the callable.
48
+ } & Subqueryable<Exclude<T, undefined>>
49
+
50
+ /**
51
+ * Adds the ability for subqueries to structured properties.
52
+ * The final result of each subquery will be the property itself:
53
+ * `Book.title` == `Subqueryable<Book>.title()`
54
+ */
55
+ type Subqueryable<T> =
56
+ T extends Primitive ? {}
57
+ // composition of many/ association to many
58
+ : T extends readonly unknown[] ? {
59
+ /**
60
+ * @example
61
+ * ```js
62
+ * SELECT.from(Books, b => b.author)
63
+ * ```
64
+ * means: "select all books and project each book's author"
65
+ *
66
+ * whereas
67
+ * ```js
68
+ * SELECT.from(Books, b => b.author(a => a.ID))
69
+ * ```
70
+ * means: "select all books, subselect each book's author's ID
71
+ *
72
+ * Note that you do not need to return anything from these subqueries.
73
+ */
74
+ (fn: ((a:QLExtensions<T[number]>) => any) | '*'): T[number]
75
+ }
76
+ // composition of one/ association to one
77
+ : {
78
+ /**
79
+ * @example
80
+ * ```js
81
+ * SELECT.from(Books, b => b.author)
82
+ * ```
83
+ * means: "select all books and project each book's author"
84
+ *
85
+ * whereas
86
+ * ```js
87
+ * SELECT.from(Books, b => b.author(a => a.ID))
88
+ * ```
89
+ * means: "select all books, subselect each book's author's ID
90
+ *
91
+ * Note that you do not need to return anything from these subqueries.
92
+ */
93
+ (fn: ((a:QLExtensions<T>) => any) | '*'): T
94
+ }
95
+ ;
96
+
97
+
98
+ // Alias for projections
99
+ // https://cap.cloud.sap/docs/node.js/cds-ql?q=projection#projection-functions
100
+ //export type Projection<T> = (e:T)=>void
101
+ export type Projection<T> = (e:QLExtensions<T extends ArrayConstructable ? SingularType<T> : T>)=>void
102
+ // Type for query pieces that can either be chained to build more complex queries or
103
+ // awaited to materialise the result:
104
+ // `Awaitable<SELECT<Book>, Book> = SELECT<Book> & Promise<Book>`
105
+ //
106
+ // While the benefit is probably not immediately obvious as we don't exactly
107
+ // save a lot of typing over explicitly writing `SELECT<Book> & Promise<Book>`,
108
+ // it makes the semantics more explicit. Also sets us up for when TypeScript ever
109
+ // improves their generics to support:
110
+ //
111
+ // `Awaitable<T> = T extends unknown<infer I> ? (T & Promise<I>) : never`
112
+ // (at the time of writing, infering the first generic parameter of ANY type
113
+ // does not seem to be possible.)
114
+ export type Awaitable<T, I> = T & Promise<I>
115
+
116
+ // all the functionality of an instance of SELECT, but directly callable:
117
+ // new SELECT(...).(...) == SELECT(...)
118
+ export type StaticSELECT<T> = typeof SELECT
119
+ & ((...columns: (T extends ArrayConstructable<any> ? keyof SingularType<T> : keyof T)[]) => SELECT<T>)
120
+ & ((...columns:string[]) => SELECT<T>)
121
+ & ((columns:string[]) => SELECT<T>)
122
+ & (TaggedTemplateQueryPart<SELECT<T>>)
123
+ & SELECT_one // as it is not directly quantified, ...
124
+ & SELECT_from // ...we should expect both a scalar and a list
125
+
126
+ declare class QL<T> {
127
+ SELECT : StaticSELECT<T>
128
+ INSERT : typeof INSERT
129
+ & ((...entries:object[]) => INSERT<any>) & ((entries:object[]) => INSERT<any>)
130
+ UPSERT: typeof UPSERT
131
+ & ((...entries:object[]) => UPSERT<any>) & ((entries:object[]) => UPSERT<any>)
132
+ UPDATE : typeof UPDATE
133
+ & typeof UPDATE.entity
134
+ DELETE : typeof DELETE
135
+ & ((...entries:object[]) => DELETE<any>) & ((entries:object[]) => DELETE<any>)
136
+ CREATE : typeof CREATE
137
+ DROP : typeof DROP
138
+ }
139
+
140
+ // used as a catch-all type for using tagged template strings: SELECT `foo`. from `bar` etc.
141
+ // the resulting signatures are actually not very strongly typed, but they at least accept template strings
142
+ // when run in strict mode.
143
+ // This signature has to be added to a method as intersection type.
144
+ // Defining overloads with it will override preceding signatures and the other way around.
145
+ type TaggedTemplateQueryPart<T> = (strings: TemplateStringsArray, ...params: unknown[]) => T
146
+
147
+ export class SELECT<T> extends ConstructedQuery {
148
+ static one : SELECT_one & { from: SELECT_one }
149
+ static distinct : typeof SELECT
150
+ static from : SELECT_from
151
+ from: SELECT_from & TaggedTemplateQueryPart<this>
152
+ & ((entity: Definition | string, primaryKey? : PK, projection? : Projection<unknown>) => this)
153
+ byKey (primaryKey? : PK) : this
154
+ columns: TaggedTemplateQueryPart<this>
155
+ & ((projection: Projection<T>) => this)
156
+ & ((...col: (T extends ArrayConstructable<any> ? keyof SingularType<T> : keyof T)[]) => this)
157
+ & ((...col:(string | column_expr)[]) => this)
158
+ & ((col:(string | column_expr)[]) => this)
159
+ where: TaggedTemplateQueryPart<this>
160
+ & ((predicate:object) => this)
161
+ & ((...expr : any[]) => this)
162
+ and: TaggedTemplateQueryPart<this>
163
+ & ((predicate:object) => this)
164
+ & ((...expr : any[]) => this)
165
+ having: TaggedTemplateQueryPart<this>
166
+ & ((...expr : string[]) => this)
167
+ & ((predicate:object) => this)
168
+ groupBy: TaggedTemplateQueryPart<this>
169
+ & ((...expr : string[]) => this)
170
+ orderBy: TaggedTemplateQueryPart<this>
171
+ & ((...expr : string[]) => this)
172
+ limit: TaggedTemplateQueryPart<this>
173
+ & ((rows : number, offset? : number) => this)
174
+ forShareLock () : this
175
+ forUpdate ({wait}? : {wait?: number}) : this
176
+ alias (as: string) : this
177
+
178
+ elements: EntityElements
179
+
180
+
181
+ // Not yet public
182
+ // fullJoin (other: string, as: string) : this
183
+ // leftJoin (other: string, as: string) : this
184
+ // rightJoin (other: string, as: string) : this
185
+ // innerJoin (other: string, as: string) : this
186
+ // join (other: string, as: string, kind?: string) : this
187
+ // on : TaggedTemplateQueryPart<this>
188
+ // & ((...expr : string[]) => this)
189
+ // & ((predicate:object) => this)
190
+
191
+ SELECT : CQN.SELECT["SELECT"] & {
192
+ forUpdate?: { wait: number }
193
+ forShareLock?: { wait: number }
194
+ search?: CQN.predicate
195
+ count?: boolean
196
+ }
197
+ }
198
+
199
+
200
+ type SELECT_one =
201
+ TaggedTemplateQueryPart<Awaitable<SELECT<unknown>, InstanceType<any>>>
202
+ &
203
+ // calling with class
204
+ (<T extends ArrayConstructable<any>>
205
+ (entityType: T, projection?: Projection<QLExtensions<SingularType<T>>>)
206
+ => Awaitable<SELECT<SingularType<T>>, SingularType<T>>)
207
+ &
208
+ (<T extends ArrayConstructable<any>>
209
+ (entityType: T, primaryKey : PK, projection?: Projection<QLExtensions<SingularType<T>>>)
210
+ => Awaitable<SELECT<SingularType<T>>, SingularType<T>>)
211
+
212
+ & ((entity: Definition | string, primaryKey? : PK, projection? : Projection<unknown>) => SELECT<any>)
213
+ & ((entity: LinkedEntity | string, primaryKey? : PK, projection? : Projection<unknown>) => SELECT<any>)
214
+ & (<T> (entity: T[], projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
215
+ & (<T> (entity: T[], primaryKey : PK, projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
216
+ & (<T> (entity: {new():T}, projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
217
+ & (<T> (entity: {new():T}, primaryKey : PK, projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
218
+ & ((subject: ref) => SELECT<any>)
219
+
220
+ type SELECT_from =
221
+ // tagged template
222
+ TaggedTemplateQueryPart<Awaitable<SELECT<unknown>, InstanceType<any>>>
223
+ &
224
+ // calling with class
225
+ (<T extends ArrayConstructable<any>>
226
+ (entityType: T, projection?: Projection<QLExtensions<SingularType<T>>>)
227
+ => Awaitable<SELECT<T>, InstanceType<T>>)
228
+ &
229
+ (<T extends ArrayConstructable<any>>
230
+ (entityType: T, primaryKey : PK, projection?: Projection<SingularType<T>>)
231
+ => Awaitable<SELECT<SingularType<T>>, InstanceType<SingularType<T>>>) // when specifying a key, we expect a single element as result
232
+ // calling with definition
233
+ & ((entity: Definition | string, primaryKey? : PK, projection? : Projection<unknown>) => SELECT<any>)
234
+ & ((entity: LinkedEntity | string, primaryKey? : PK, projection? : Projection<unknown>) => SELECT<any>)
235
+ // calling with concrete list
236
+ & (<T> (entity: T[], projection? : Projection<T>) => SELECT<T> & Promise<T[]>)
237
+ & (<T> (entity: T[], primaryKey : PK, projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
238
+ & ((subject: ref) => SELECT<any>)
239
+
240
+ export class INSERT<T> extends ConstructedQuery {
241
+ static into : (<T extends ArrayConstructable<any>> (entity:T, entries? : object | object[]) => INSERT<SingularType<T>>)
242
+ & (TaggedTemplateQueryPart<INSERT<unknown>>)
243
+ & ((entity : Definition | string, entries? : object | object[]) => INSERT<any>)
244
+ & ((entity : LinkedEntity | string, entries? : object | object[]) => INSERT<any>)
245
+ & (<T> (entity:Constructable<T>, entries? : object | object[]) => INSERT<T>)
246
+ & (<T> (entity:T, entries? : T | object | object[]) => INSERT<T>)
247
+
248
+ into: (<T extends ArrayConstructable> (entity:T) => this)
249
+ & TaggedTemplateQueryPart<this>
250
+ & ((entity : Definition | string) => this)
251
+ data (block : (e:T)=>void) : this
252
+ entries (...entries : object[]) : this
253
+ columns (...col: (T extends ArrayConstructable<any> ? keyof SingularType<T> : keyof T)[]) : this
254
+ columns (...col: string[]) : this
255
+ values (... val: any[]) : this
256
+ rows (... row: any[]) : this
257
+ as (select: SELECT<T>): this
258
+ INSERT : CQN.INSERT["INSERT"]
259
+ }
260
+
261
+
262
+ export class UPSERT<T> extends ConstructedQuery {
263
+ static into : (<T extends ArrayConstructable<any>> (entity:T, entries? : object | object[]) => UPSERT<SingularType<T>>)
264
+ & (TaggedTemplateQueryPart<UPSERT<unknown>>)
265
+ & ((entity : Definition | string, entries? : object | object[]) => UPSERT<any>)
266
+ & ((entity : LinkedEntity | string, entries? : object | object[]) => UPSERT<any>)
267
+ & (<T> (entity:Constructable<T>, entries? : object | object[]) => UPSERT<T>)
268
+ & (<T> (entity:T, entries? : T | object | object[]) => UPSERT<T>)
269
+
270
+ into: (<T extends ArrayConstructable> (entity:T) => this)
271
+ & TaggedTemplateQueryPart<this>
272
+ & ((entity : Definition | string) => this)
273
+ data (block : (e:T)=>void) : this
274
+ entries (...entries : object[]) : this
275
+ columns (...col: (T extends ArrayConstructable<any> ? keyof SingularType<T> : keyof T)[]) : this
276
+ columns (...col: string[]) : this
277
+ values (... val: any[]) : this
278
+ rows (... row: any[]) : this
279
+ UPSERT : CQN.UPSERT["UPSERT"]
280
+ }
281
+
282
+
283
+
284
+ export class DELETE<T> extends ConstructedQuery {
285
+ static from:
286
+ TaggedTemplateQueryPart<Awaitable<SELECT<unknown>, InstanceType<any>>>
287
+ & ((entity : Definition | string | ArrayConstructable, primaryKey? : PK) => DELETE<any>)
288
+ & ((entity : LinkedEntity | string | ArrayConstructable, primaryKey? : PK) => DELETE<any>)
289
+ & ((subject: ref) => DELETE<any>)
290
+ byKey (primaryKey? : PK) : this
291
+ where (predicate:object) : this
292
+ where (...expr : any[]) : this
293
+ and (predicate:object) : this
294
+ and (...expr : any[]) : this
295
+ DELETE : CQN.DELETE["DELETE"]
296
+ }
297
+
298
+ export class UPDATE<T> extends ConstructedQuery {
299
+ // cds-typer plural
300
+ static entity <T extends ArrayConstructable<any>> (entity:T, primaryKey? : PK) : UPDATE<SingularType<T>>
301
+
302
+ static entity (entity : Definition | string, primaryKey? : PK) : UPDATE<any>
303
+ static entity (entity : LinkedEntity | string, primaryKey? : PK) : UPDATE<any>
304
+ static entity <T> (entity:Constructable<T>, primaryKey? : PK) : UPDATE<T>
305
+ static entity <T> (entity:T, primaryKey? : PK) : UPDATE<T>
306
+ byKey (primaryKey? : PK) : this
307
+ // with (block: (e:T)=>void) : this
308
+ // set (block: (e:T)=>void) : this
309
+ set: TaggedTemplateQueryPart<this>
310
+ & ((data:object) => this)
311
+ with: TaggedTemplateQueryPart<this>
312
+ & ((data:object) => this)
313
+ where (predicate:object) : this
314
+ where (...expr : any[]) : this
315
+ and (predicate:object) : this
316
+ and (...expr : any[]) : this
317
+ UPDATE : CQN.UPDATE["UPDATE"]
318
+ }
319
+
320
+ export class CREATE<T> extends ConstructedQuery {
321
+ static entity (entity : Definition | string) : CREATE<any>
322
+ static entity (entity : LinkedEntity | string) : CREATE<any>
323
+ CREATE : CQN.CREATE["CREATE"]
324
+ }
325
+
326
+ export class DROP<T> extends ConstructedQuery {
327
+ static entity (entity : Definition | string) : DROP<any>
328
+ static entity (entity : LinkedEntity | string) : DROP<any>
329
+ DROP : CQN.DROP["DROP"]
330
+ }
@@ -0,0 +1,135 @@
1
+ import { Service, ServiceImpl } from "./services"
2
+ import { CSN } from "./csn"
3
+ import * as http from "http"
4
+ import { Application } from "express"
5
+
6
+ export default class cds {
7
+
8
+ connect: {
9
+ /**
10
+ * Connects to a specific datasource.
11
+ * @see [capire](https://cap.cloud.sap/docs/node.js/cds-connect#cds-connect-to)
12
+ */
13
+ to(datasource: string, options?: cds_connect_options): Promise<Service>
14
+
15
+ /**
16
+ * Connects to a specific datasource via options.
17
+ * @see [capire](https://cap.cloud.sap/docs/node.js/cds-connect#cds-connect-to)
18
+ */
19
+ to(options: cds_connect_options): Promise<Service>
20
+
21
+ /**
22
+ * Connects the primary datasource.
23
+ * @see [capire](https://cap.cloud.sap/docs/node.js/cds-connect)
24
+ */
25
+ (options?: string | cds_connect_options): Promise<typeof cds> //> cds.connect(<options>)
26
+ }
27
+
28
+ /**
29
+ * The default bootstrap function as loaded from server.js
30
+ */
31
+ server: Function
32
+
33
+ /**
34
+ * Constructs service providers from respective service definitions
35
+ * @see [capire](https://cap.cloud.sap/docs/node.js/cds-serve)
36
+ */
37
+ serve (service : string, options?: {
38
+ service?: string,
39
+ from?: '*' | 'all' | string,
40
+ [key: string]: unknown
41
+ }) : Promise<cds_services> & cds_serve_fluent
42
+
43
+
44
+ /**
45
+ * Emitted whenever a specific service is connected for the first time.
46
+ */
47
+ on(event: 'connect', listener: (srv: Service) => void): this
48
+
49
+
50
+ /**
51
+ * Emitted at the very beginning of the bootsrapping process, when the
52
+ * express application has been constructed but no middlewares or routes
53
+ * added yet.
54
+ */
55
+ on (event : 'bootstrap', listener : (app : Application) => void) : this
56
+ once (event : 'bootstrap', listener : (app : Application) => void) : this
57
+
58
+ /**
59
+ * Emitted for each service served by cds.serve().
60
+ */
61
+ on (event : 'serving', listener : (srv : Service) => void) : this
62
+
63
+ /**
64
+ * Emitted by the default, built-in `server.js` when all services are
65
+ * constructed and mounted by cds.serve().
66
+ */
67
+ on (event : 'served', listener : (all : cds_services) => void) : this
68
+ once (event : 'served', listener : (all : cds_services) => void) : this
69
+
70
+ /**
71
+ * Emitted by the default, built-in `server.js` when the http server
72
+ * is started and listening for incoming requests.
73
+ */
74
+ on (event : 'listening', listener : (args : { server: http.Server, url:string }) => void) : this
75
+ once (event : 'listening', listener : (args : { server: http.Server, url:string }) => void) : this
76
+
77
+ /**
78
+ * Emitted by the default, built-in `server.js` when the http server
79
+ * is shutdown.
80
+ */
81
+ on (event : 'shutdown', listener : () => void) : this
82
+ once (event : 'shutdown', listener : () => void) : this
83
+
84
+ /**
85
+ * Dictionary of all services constructed and/or connected.
86
+ */
87
+ services : cds_services
88
+
89
+ /**
90
+ * Shortcut to base class for all service definitions from linked models.
91
+ * Plus accessors to impl functions and constructed providers.
92
+ */
93
+ service : service
94
+
95
+ /**
96
+ * Provides a graceful shutdown for running servers, by first emitting `cds.emit('shutdown')`.
97
+ * @see [capire](https://cap.cloud.sap/docs/node.js/cds-facade#cds-exit)
98
+ */
99
+ exit(): void
100
+
101
+ }
102
+
103
+ export type service = {
104
+ /**
105
+ * Dummy wrapper for service implementation functions.
106
+ * Use that in modules to get IntelliSense.
107
+ */
108
+ impl (impl: ServiceImpl) : typeof impl
109
+ // impl <T> (srv:T, impl: ( this: T, srv: (T) ) => any) : typeof impl
110
+
111
+ /**
112
+ * Array of all services constructed.
113
+ */
114
+ providers : Service[]
115
+ }
116
+
117
+
118
+ type cds_services = { [name:string]: Service }
119
+
120
+ interface cds_serve_fluent {
121
+ from (model : string | CSN) : this
122
+ to (protocol: string) : this
123
+ at (path: string) : this
124
+ in (app: Application) : this
125
+ with (impl: ServiceImpl | string) : this
126
+ // (req,res) : void
127
+ }
128
+
129
+ interface cds_connect_options {
130
+ impl?: string,
131
+ service?: string,
132
+ kind?: string,
133
+ model?: string,
134
+ credentials?: object
135
+ }