@api-client/core 0.14.5 → 0.14.7

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.
Files changed (34) hide show
  1. package/build/src/amf/ApiSchemaValues.js.map +1 -1
  2. package/build/src/modeling/ApiModel.d.ts +27 -17
  3. package/build/src/modeling/ApiModel.d.ts.map +1 -1
  4. package/build/src/modeling/ApiModel.js +69 -20
  5. package/build/src/modeling/ApiModel.js.map +1 -1
  6. package/build/src/modeling/DataDomain.d.ts +5 -15
  7. package/build/src/modeling/DataDomain.d.ts.map +1 -1
  8. package/build/src/modeling/DataDomain.js +18 -14
  9. package/build/src/modeling/DataDomain.js.map +1 -1
  10. package/build/src/modeling/DependentModel.d.ts +26 -0
  11. package/build/src/modeling/DependentModel.d.ts.map +1 -0
  12. package/build/src/modeling/DependentModel.js +23 -0
  13. package/build/src/modeling/DependentModel.js.map +1 -0
  14. package/build/src/modeling/types.d.ts +2 -0
  15. package/build/src/modeling/types.d.ts.map +1 -1
  16. package/build/src/modeling/types.js.map +1 -1
  17. package/build/src/models/store/Backend.d.ts +0 -168
  18. package/build/src/models/store/Backend.d.ts.map +1 -1
  19. package/build/src/models/store/Backend.js +1 -12
  20. package/build/src/models/store/Backend.js.map +1 -1
  21. package/build/src/sdk/RouteBuilder.d.ts +1 -1
  22. package/build/src/sdk/RouteBuilder.d.ts.map +1 -1
  23. package/build/src/sdk/RouteBuilder.js.map +1 -1
  24. package/build/tsconfig.tsbuildinfo +1 -1
  25. package/data/models/example-generator-api.json +8 -8
  26. package/package.json +1 -1
  27. package/src/amf/ApiSchemaValues.ts +1 -1
  28. package/src/modeling/ApiModel.ts +74 -31
  29. package/src/modeling/DataDomain.ts +18 -25
  30. package/src/modeling/DependentModel.ts +36 -0
  31. package/src/modeling/types.ts +2 -0
  32. package/src/models/store/Backend.ts +0 -176
  33. package/src/sdk/RouteBuilder.ts +1 -1
  34. package/tests/unit/modeling/api_model.spec.ts +17 -15
@@ -42068,13 +42068,13 @@
42068
42068
  "@id": "#194"
42069
42069
  },
42070
42070
  {
42071
- "@id": "#197"
42071
+ "@id": "#203"
42072
42072
  },
42073
42073
  {
42074
- "@id": "#200"
42074
+ "@id": "#197"
42075
42075
  },
42076
42076
  {
42077
- "@id": "#203"
42077
+ "@id": "#200"
42078
42078
  },
42079
42079
  {
42080
42080
  "@id": "#206"
@@ -43478,7 +43478,7 @@
43478
43478
  "doc:ExternalDomainElement",
43479
43479
  "doc:DomainElement"
43480
43480
  ],
43481
- "doc:raw": "code: '5'\ndescription: 'Limited company'\n",
43481
+ "doc:raw": "class: '3'\ndescription: '150 - 300'\nnumberOfFte: 5500\nnumberOfEmployees: 5232\n",
43482
43482
  "core:mediaType": "application/yaml",
43483
43483
  "sourcemaps:sources": [
43484
43484
  {
@@ -43499,7 +43499,7 @@
43499
43499
  "doc:ExternalDomainElement",
43500
43500
  "doc:DomainElement"
43501
43501
  ],
43502
- "doc:raw": "class: '3'\ndescription: '150 - 300'\nnumberOfFte: 5500\nnumberOfEmployees: 5232\n",
43502
+ "doc:raw": "code: 'J'\ndescription: 'Information and communication'\n",
43503
43503
  "core:mediaType": "application/yaml",
43504
43504
  "sourcemaps:sources": [
43505
43505
  {
@@ -43520,7 +43520,7 @@
43520
43520
  "doc:ExternalDomainElement",
43521
43521
  "doc:DomainElement"
43522
43522
  ],
43523
- "doc:raw": "code: 'J'\ndescription: 'Information and communication'\n",
43523
+ "doc:raw": "code: '5'\ndescription: 'Limited company'\n",
43524
43524
  "core:mediaType": "application/yaml",
43525
43525
  "sourcemaps:sources": [
43526
43526
  {
@@ -44766,12 +44766,12 @@
44766
44766
  {
44767
44767
  "@id": "#199/source-map/lexical/element_0",
44768
44768
  "sourcemaps:element": "amf://id#199",
44769
- "sourcemaps:value": "[(1,0)-(3,0)]"
44769
+ "sourcemaps:value": "[(1,0)-(5,0)]"
44770
44770
  },
44771
44771
  {
44772
44772
  "@id": "#202/source-map/lexical/element_0",
44773
44773
  "sourcemaps:element": "amf://id#202",
44774
- "sourcemaps:value": "[(1,0)-(5,0)]"
44774
+ "sourcemaps:value": "[(1,0)-(3,0)]"
44775
44775
  },
44776
44776
  {
44777
44777
  "@id": "#205/source-map/lexical/element_0",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@api-client/core",
3
3
  "description": "The API Client's core client library. Works in NodeJS and in a ES enabled browser.",
4
- "version": "0.14.5",
4
+ "version": "0.14.7",
5
5
  "license": "Apache-2.0",
6
6
  "exports": {
7
7
  "./browser.js": {
@@ -15,7 +15,7 @@ import {
15
15
  IApiScalarShape,
16
16
  IShapeUnion,
17
17
  } from './definitions/Shapes.js'
18
- import { ILoremWordInit, ITypeHashInit, ITypeNumberInit } from '@pawel-up/data-mock/types.js'
18
+ import type { ILoremWordInit, ITypeHashInit, ITypeNumberInit } from '@pawel-up/data-mock/types.js'
19
19
 
20
20
  export interface IApiSchemaReadOptions {
21
21
  /**
@@ -1,18 +1,20 @@
1
1
  import { nanoid } from '../nanoid.js'
2
- import { ApiModelKind } from '../models/kinds.js'
2
+ import { ApiModelKind, DataDomainKind } from '../models/kinds.js'
3
3
  import { type IThing, Thing } from '../models/Thing.js'
4
4
  import type {
5
5
  AccessRule,
6
6
  AuthenticationConfiguration,
7
7
  AuthorizationConfiguration,
8
8
  ExposedEntity,
9
- ForeignDomainDependency,
10
9
  RateLimitingConfiguration,
10
+ RolesBasedAccessControl,
11
11
  SessionConfiguration,
12
+ UsernamePasswordConfiguration,
12
13
  } from './types.js'
13
- import { DataDomain, type DataDomainSchema } from './DataDomain.js'
14
+ import { DataDomain } from './DataDomain.js'
15
+ import { DependentModel, type DomainDependency, type DependentModelSchema } from './DependentModel.js'
14
16
 
15
- export interface ApiModelSchema {
17
+ export interface ApiModelSchema extends DependentModelSchema {
16
18
  /**
17
19
  * The data domain kind recognizable by the ecosystem.
18
20
  */
@@ -35,12 +37,6 @@ export interface ApiModelSchema {
35
37
  */
36
38
  userKey?: string
37
39
 
38
- /**
39
- * Reference to the stable, version-controlled data definition from the
40
- * Data Catalog. When not set, the model cannot be published.
41
- */
42
- domain?: ForeignDomainDependency
43
-
44
40
  /**
45
41
  * Configuration for how users prove their identity.
46
42
  * The API model is invalid if this is not set.
@@ -80,7 +76,7 @@ export interface ApiModelSchema {
80
76
  rateLimiting?: RateLimitingConfiguration
81
77
  }
82
78
 
83
- export class ApiModel extends EventTarget {
79
+ export class ApiModel extends DependentModel {
84
80
  /**
85
81
  * The data domain kind recognizable by the ecosystem.
86
82
  */
@@ -103,12 +99,6 @@ export class ApiModel extends EventTarget {
103
99
  */
104
100
  userKey?: string
105
101
 
106
- /**
107
- * Reference to the stable, version-controlled data definition from the
108
- * Data Catalog. When not set, the model cannot be published.
109
- */
110
- domain?: ForeignDomainDependency
111
-
112
102
  /**
113
103
  * Configuration for how users prove their identity.
114
104
  * The API model is invalid if this is not set.
@@ -161,9 +151,20 @@ export class ApiModel extends EventTarget {
161
151
  #notifying = false
162
152
 
163
153
  /**
164
- * A reference to the published data domain.
154
+ * A convenience getter that returns the DataDomain associated with this API model.
155
+ * Since the API model can have only one DataDomain,
156
+ * this getter returns the first dependency in the list.
157
+ *
158
+ * The parent interface `DependentModel` allows for multiple dependencies,
159
+ * to unify the dependency management across different models.
165
160
  */
166
- dataDomain?: DataDomain
161
+ get domain(): DataDomain | undefined {
162
+ if (this.dependencyList.length === 0) {
163
+ return undefined
164
+ }
165
+ const domain = this.dependencyList[0]
166
+ return this.dependencies.get(domain.key)
167
+ }
167
168
 
168
169
  static createSchema(input: Partial<ApiModelSchema> = {}): ApiModelSchema {
169
170
  const { key = nanoid(), exposes = [] } = input
@@ -177,8 +178,8 @@ export class ApiModel extends EventTarget {
177
178
  if (input.userKey) {
178
179
  result.userKey = input.userKey
179
180
  }
180
- if (input.domain) {
181
- result.domain = input.domain
181
+ if (input.dependencyList) {
182
+ result.dependencyList = structuredClone(input.dependencyList)
182
183
  }
183
184
  if (input.authentication) {
184
185
  result.authentication = input.authentication
@@ -198,16 +199,21 @@ export class ApiModel extends EventTarget {
198
199
  return result
199
200
  }
200
201
 
201
- constructor(state?: Partial<ApiModelSchema>, domain?: DataDomainSchema) {
202
- super()
202
+ constructor(state?: Partial<ApiModelSchema>, domain?: DomainDependency) {
203
203
  const init = ApiModel.createSchema(state)
204
+ const instances: DataDomain[] = []
205
+ if (domain instanceof DataDomain) {
206
+ instances.push(domain)
207
+ } else if (typeof domain === 'object' && domain.kind === DataDomainKind) {
208
+ instances.push(new DataDomain(domain))
209
+ } else if (domain) {
210
+ throw new Error(`Invalid domain provided. Expected a DataDomain instance or schema.`)
211
+ }
212
+ super(init.dependencyList, instances)
204
213
  this.kind = init.kind
205
214
  this.key = init.key
206
215
  this.info = new Thing(init.info)
207
216
  this.userKey = init.userKey
208
- if (init.domain) {
209
- this.domain = structuredClone(init.domain)
210
- }
211
217
  if (init.authentication) {
212
218
  this.authentication = structuredClone(init.authentication)
213
219
  }
@@ -228,9 +234,6 @@ export class ApiModel extends EventTarget {
228
234
  if (init.rateLimiting) {
229
235
  this.rateLimiting = structuredClone(init.rateLimiting)
230
236
  }
231
- if (domain) {
232
- this.dataDomain = new DataDomain(domain)
233
- }
234
237
  this.#initializing = false
235
238
  this.info.addEventListener('change', () => {
236
239
  this.notifyChange()
@@ -247,8 +250,8 @@ export class ApiModel extends EventTarget {
247
250
  if (this.userKey) {
248
251
  result.userKey = this.userKey
249
252
  }
250
- if (this.domain) {
251
- result.domain = structuredClone(this.domain)
253
+ if (this.dependencyList.length > 0) {
254
+ result.dependencyList = structuredClone(this.dependencyList)
252
255
  }
253
256
  if (this.authentication) {
254
257
  result.authentication = structuredClone(this.authentication)
@@ -324,4 +327,44 @@ export class ApiModel extends EventTarget {
324
327
  getExposedEntity(entityKey: string): ExposedEntity | undefined {
325
328
  return this.exposes.find((e) => e.key === entityKey)
326
329
  }
330
+
331
+ /**
332
+ * Clears the API model for a new entity change.
333
+ * This method resets the dependencies, exposes, userKey,
334
+ * authentication, authorization, and session properties.
335
+ */
336
+ cleanForEntityChange(): void {
337
+ this.dependencies.clear()
338
+ this.dependencyList = []
339
+ this.exposes = []
340
+ this.userKey = undefined
341
+ if (this.session) {
342
+ this.session.properties = []
343
+ }
344
+ if (this.authentication && this.authentication.strategy === 'UsernamePassword') {
345
+ const typed = this.authentication as UsernamePasswordConfiguration
346
+ typed.passwordKey = undefined
347
+ }
348
+ if (this.authorization && this.authorization.strategy == 'RBAC') {
349
+ const typed = this.authorization as RolesBasedAccessControl
350
+ typed.roleKey = ''
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Attaches a DataDomain to this API model.
356
+ * This method clears any existing dependencies and sets the new domain.
357
+ *
358
+ * @param domain The DataDomain to attach to this API model.
359
+ * @throws Error if the domain does not have a version set in its info.
360
+ */
361
+ attachDataDomain(domain: DataDomain): void {
362
+ if (!domain.info.version) {
363
+ throw new Error(`Cannot attach DataDomain without a version. Please set the version in the domain info.`)
364
+ }
365
+ this.cleanForEntityChange()
366
+ this.dependencies.set(domain.key, domain)
367
+ this.dependencyList = [{ key: domain.key, version: domain.info.version }]
368
+ this.notifyChange()
369
+ }
327
370
  }
@@ -8,13 +8,7 @@ import {
8
8
  DomainNamespaceKind,
9
9
  DomainPropertyKind,
10
10
  } from '../models/kinds.js'
11
- import type {
12
- AssociationAddOptions,
13
- DomainGraphEdge,
14
- DomainGraphNodeType,
15
- ForeignDomainDependency,
16
- SerializedGraph,
17
- } from './types.js'
11
+ import type { AssociationAddOptions, DomainGraphEdge, DomainGraphNodeType, SerializedGraph } from './types.js'
18
12
  import { type DomainNamespaceSchema, DomainNamespace, type NamespaceOrderedItem } from './DomainNamespace.js'
19
13
  import { type DomainModelSchema, DomainModel } from './DomainModel.js'
20
14
  import { type DomainEntitySchema, DomainEntity } from './DomainEntity.js'
@@ -23,13 +17,13 @@ import { DomainProperty, DomainPropertySchema } from './DomainProperty.js'
23
17
  import { type IThing, Thing } from '../models/Thing.js'
24
18
  import { removeGraphNode } from './GraphUtils.js'
25
19
  import { serialize, deserialize, mergeGraph, removeForeignGraph } from './DomainSerialization.js'
20
+ import { DependentModel, type DependentModelSchema, type DomainDependency } from './DependentModel.js'
26
21
 
27
- export interface DataDomainSchema {
22
+ export interface DataDomainSchema extends DependentModelSchema {
28
23
  info: IThing
29
24
  kind: typeof DataDomainKind
30
25
  key: string
31
26
  graph?: SerializedGraph
32
- dependencyList?: ForeignDomainDependency[]
33
27
  /**
34
28
  * The ordered list of fields (namespace and models) in the schema.
35
29
  * These only keep references to define the order of these properties
@@ -104,7 +98,7 @@ export interface DataDomainSchema {
104
98
  * @todo: Implement a mechanism to move an entity to a new
105
99
  * parent model.
106
100
  */
107
- export class DataDomain extends EventTarget {
101
+ export class DataDomain extends DependentModel {
108
102
  /**
109
103
  * The kind of the domain element.
110
104
  */
@@ -119,18 +113,6 @@ export class DataDomain extends EventTarget {
119
113
  */
120
114
  graph: Graph<unknown, DomainGraphNodeType, DomainGraphEdge>
121
115
 
122
- /**
123
- * A map of foreign data domains.
124
- * Key: The unique identifier of the foreign domain.
125
- * Value: The foreign DataDomain instance.
126
- */
127
- dependencies: Map<string, DataDomain> = new Map<string, DataDomain>()
128
-
129
- /**
130
- * The list of foreign domain dependencies.
131
- */
132
- dependencyList: ForeignDomainDependency[] = []
133
-
134
116
  /**
135
117
  * The description of the domain property.
136
118
  */
@@ -196,13 +178,24 @@ export class DataDomain extends EventTarget {
196
178
  * @param state The previously serialized state of the graph.
197
179
  * @param dependencies An array of foreign data domains to register with this domain.
198
180
  */
199
- constructor(state?: Partial<DataDomainSchema>, dependencies?: DataDomain[]) {
200
- super()
181
+ constructor(state?: Partial<DataDomainSchema>, dependencies: DomainDependency[] = []) {
201
182
  const init = DataDomain.createSchema(state)
183
+ const instances: DataDomain[] = []
184
+ for (const dep of dependencies) {
185
+ if (dep instanceof DataDomain) {
186
+ instances.push(dep)
187
+ } else if (typeof dep === 'object' && dep.kind === DataDomainKind && dep.key) {
188
+ const domain = new DataDomain(dep)
189
+ instances.push(domain)
190
+ } else {
191
+ throw new Error(`Invalid foreign domain dependency: ${dep}`)
192
+ }
193
+ }
194
+ super(init.dependencyList, instances)
202
195
  this.kind = init.kind
203
196
  this.key = init.key
204
197
  this.info = new Thing(init.info)
205
- this.graph = deserialize(this, init.graph, dependencies)
198
+ this.graph = deserialize(this, init.graph, instances)
206
199
  if (Array.isArray(init.fields)) {
207
200
  this.fields = [...init.fields]
208
201
  } else {
@@ -0,0 +1,36 @@
1
+ import type { DataDomain, DataDomainSchema } from './DataDomain.js'
2
+ import type { ForeignDomainDependency } from './types.js'
3
+
4
+ export type DomainDependency = DataDomain | DataDomainSchema
5
+
6
+ export interface DependentModelSchema {
7
+ /**
8
+ * A list of foreign domain dependencies.
9
+ */
10
+ dependencyList?: ForeignDomainDependency[]
11
+ }
12
+
13
+ /**
14
+ * A base model that has dependencies on foreign data domains.
15
+ */
16
+ export class DependentModel extends EventTarget {
17
+ /**
18
+ * A map of foreign data domains.
19
+ * Key: The unique identifier of the foreign domain.
20
+ * Value: The foreign DataDomain instance.
21
+ */
22
+ dependencies: Map<string, DataDomain> = new Map<string, DataDomain>()
23
+
24
+ /**
25
+ * The list of foreign domain dependencies.
26
+ */
27
+ dependencyList: ForeignDomainDependency[] = []
28
+
29
+ constructor(items: ForeignDomainDependency[] = [], instances: DataDomain[] = []) {
30
+ super()
31
+ this.dependencyList = [...items]
32
+ for (const dep of instances) {
33
+ this.dependencies.set(dep.key, dep)
34
+ }
35
+ }
36
+ }
@@ -337,6 +337,8 @@ export interface SessionConfiguration {
337
337
  /**
338
338
  * The properties from the `User` entity to be encoded into the session payload (JWT/cookie).
339
339
  * These properties become available in the `request.auth` object at runtime.
340
+ *
341
+ * In practice, these are the ids of the properties in the `User` entity.
340
342
  */
341
343
  properties: string[]
342
344
  /**
@@ -1,180 +1,4 @@
1
1
  import type { PatchInfo } from '../../patch/types.js'
2
- import { type IPatchRevision } from '../../events/BaseEvents.js'
3
- import { type IHttpHistory, Kind as HttpHistoryKind } from '../HttpHistory.js'
4
- import { Kind as ProjectExecutionKind } from '../ProjectExecution.js'
5
- import type { IFile } from './File.js'
6
- import type { IPermission } from './Permission.js'
7
- import type { IRevision } from './Revision.js'
8
- /**
9
- * @deprecated
10
- */
11
- export enum BackendCommandType {
12
- observe,
13
- unobserve,
14
- }
15
- /**
16
- * @deprecated
17
- */
18
- export const BackendCommandKind = 'Core#BackendCommand'
19
- /**
20
- * @deprecated
21
- */
22
- export interface IBackendCommand {
23
- kind: typeof BackendCommandKind
24
- cmd: BackendCommandType
25
- }
26
- /**
27
- * @deprecated
28
- */
29
- export interface IBackendObserveCommand extends IBackendCommand {
30
- path: string // includes query parameters
31
- }
32
- /**
33
- * @deprecated
34
- */
35
- export interface BroadcastEvent {
36
- type: 'event'
37
- operation: string
38
- kind: string
39
- key: string
40
- path: string
41
- organization: string // empty string for `/organizations`
42
- }
43
- /**
44
- * @deprecated
45
- */
46
- export interface BackendErrorEvent {
47
- type: 'error'
48
- cause: string
49
- time: number
50
- }
51
- /**
52
- * @deprecated
53
- */
54
- export interface ClearedBroadcastEvent {
55
- type: 'event'
56
- operation: 'cleared'
57
- name: string
58
- organization: string
59
- path: string
60
- }
61
- /**
62
- * @deprecated
63
- */
64
- export interface BroadcastFileData {
65
- parent?: string
66
- }
67
- /**
68
- * @deprecated
69
- */
70
- export interface BroadcastCreatedEvent extends BroadcastEvent {
71
- operation: 'created'
72
- data: unknown
73
- // path: string; -> /files, /certificates, /history, /project/executions, /organizations, /trash
74
- }
75
- /**
76
- * @deprecated
77
- */
78
- export interface FileCreatedBroadcastEvent extends BroadcastCreatedEvent, BroadcastFileData {}
79
- /**
80
- * @deprecated
81
- */
82
- export interface FileMetaCreatedBroadcastEvent extends FileCreatedBroadcastEvent {
83
- data: IFile
84
- alt: 'meta'
85
- }
86
- /**
87
- * @deprecated
88
- */
89
- export interface FileMediaCreatedBroadcastEvent extends FileCreatedBroadcastEvent {
90
- alt: 'media'
91
- }
92
- /**
93
- * @deprecated
94
- */
95
- export interface HistoryCreatedBroadcastEvent extends BroadcastCreatedEvent {
96
- project: string
97
- request: string
98
- app: string
99
- kind: typeof HttpHistoryKind
100
- data: IHttpHistory
101
- }
102
- /**
103
- * @deprecated
104
- */
105
- export interface FileRevisionCreatedBroadcastEvent extends BroadcastCreatedEvent, BroadcastFileData {
106
- parent: string
107
- data: IRevision
108
- }
109
- /**
110
- * @deprecated
111
- */
112
- export interface ProjectExecutionCreatedBroadcastEvent extends BroadcastCreatedEvent {
113
- project: string
114
- kind: typeof ProjectExecutionKind
115
- }
116
- /**
117
- * @deprecated
118
- */
119
- export interface BroadcastPatchEvent extends BroadcastEvent {
120
- operation: 'patch'
121
- data: IPatchRevision
122
- // path: string; -> /files, /organizations
123
- }
124
- /**
125
- * @deprecated
126
- */
127
- export interface FilePatchBroadcastEvent extends BroadcastPatchEvent, BroadcastFileData {}
128
-
129
- /**
130
- * @deprecated
131
- */
132
- export interface AccessBroadcastEvent extends BroadcastEvent {
133
- operation: 'access-granted' | 'access-removed'
134
- data?: IPermission
135
- // path: string; -> /files, /organizations, /organizations
136
- }
137
-
138
- /**
139
- * @deprecated
140
- */
141
- export interface FileAccessBroadcastEvent extends AccessBroadcastEvent {
142
- parent?: string
143
- }
144
-
145
- /**
146
- * @deprecated
147
- */
148
- export interface DeletedBroadcastEvent extends BroadcastEvent {
149
- operation: 'deleted'
150
- // path: string; -> /files, /certificates, /history, /project/executions, /organizations, /trash
151
- }
152
-
153
- /**
154
- * @deprecated
155
- */
156
- export interface FileDeletedBroadcastEvent extends DeletedBroadcastEvent, BroadcastFileData {
157
- /**
158
- * The key of the created trash entry for the deleted object.
159
- * This is **always** populated when the file alt is `meta`.
160
- */
161
- trash?: string
162
- }
163
-
164
- /**
165
- * @deprecated
166
- */
167
- export interface ProjectExecutionDeleteBroadcastEvent extends DeletedBroadcastEvent {
168
- project: string
169
- }
170
-
171
- /**
172
- * @deprecated
173
- */
174
- export interface HistoryDeletedBroadcastEvent extends DeletedBroadcastEvent {
175
- project: string
176
- request: string
177
- }
178
2
 
179
3
  export interface ServerEvent {
180
4
  kind: string
@@ -296,7 +296,7 @@ export class RouteBuilder {
296
296
  return `/v1/orgs/${oid}/groups/${gid}`
297
297
  }
298
298
 
299
- static groupUsers(oid: string, gid: string): string | undefined {
299
+ static groupUsers(oid: string, gid: string): string {
300
300
  return `/v1/orgs/${oid}/groups/${gid}/users`
301
301
  }
302
302
  }