@api-client/core 0.19.24 → 0.19.25

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 (102) hide show
  1. package/build/src/index.d.ts +3 -1
  2. package/build/src/index.d.ts.map +1 -1
  3. package/build/src/index.js +3 -1
  4. package/build/src/index.js.map +1 -1
  5. package/build/src/mocking/ModelingMock.d.ts +2 -0
  6. package/build/src/mocking/ModelingMock.d.ts.map +1 -1
  7. package/build/src/mocking/ModelingMock.js +2 -0
  8. package/build/src/mocking/ModelingMock.js.map +1 -1
  9. package/build/src/mocking/lib/Deployment.d.ts +16 -0
  10. package/build/src/mocking/lib/Deployment.d.ts.map +1 -0
  11. package/build/src/mocking/lib/Deployment.js +76 -0
  12. package/build/src/mocking/lib/Deployment.js.map +1 -0
  13. package/build/src/modeling/Bindings.d.ts +4 -0
  14. package/build/src/modeling/Bindings.d.ts.map +1 -1
  15. package/build/src/modeling/Bindings.js.map +1 -1
  16. package/build/src/modeling/DataFormat.d.ts +1 -1
  17. package/build/src/modeling/DataFormat.d.ts.map +1 -1
  18. package/build/src/modeling/DataFormat.js +2 -0
  19. package/build/src/modeling/DataFormat.js.map +1 -1
  20. package/build/src/modeling/DomainAssociation.d.ts +7 -0
  21. package/build/src/modeling/DomainAssociation.d.ts.map +1 -1
  22. package/build/src/modeling/DomainAssociation.js +10 -0
  23. package/build/src/modeling/DomainAssociation.js.map +1 -1
  24. package/build/src/modeling/DomainEntity.d.ts +9 -1
  25. package/build/src/modeling/DomainEntity.d.ts.map +1 -1
  26. package/build/src/modeling/DomainEntity.js +26 -1
  27. package/build/src/modeling/DomainEntity.js.map +1 -1
  28. package/build/src/modeling/ExposedEntity.d.ts +12 -1
  29. package/build/src/modeling/ExposedEntity.d.ts.map +1 -1
  30. package/build/src/modeling/ExposedEntity.js +24 -1
  31. package/build/src/modeling/ExposedEntity.js.map +1 -1
  32. package/build/src/modeling/RuntimeApiModel.d.ts +52 -0
  33. package/build/src/modeling/RuntimeApiModel.d.ts.map +1 -0
  34. package/build/src/modeling/RuntimeApiModel.js +85 -0
  35. package/build/src/modeling/RuntimeApiModel.js.map +1 -0
  36. package/build/src/modeling/actions/index.d.ts +10 -0
  37. package/build/src/modeling/actions/index.d.ts.map +1 -1
  38. package/build/src/modeling/actions/index.js +30 -0
  39. package/build/src/modeling/actions/index.js.map +1 -1
  40. package/build/src/modeling/index.d.ts.map +1 -1
  41. package/build/src/modeling/index.js +1 -0
  42. package/build/src/modeling/index.js.map +1 -1
  43. package/build/src/modeling/types.d.ts +25 -1
  44. package/build/src/modeling/types.d.ts.map +1 -1
  45. package/build/src/modeling/types.js.map +1 -1
  46. package/build/src/models/kinds.d.ts +1 -0
  47. package/build/src/models/kinds.d.ts.map +1 -1
  48. package/build/src/models/kinds.js +1 -0
  49. package/build/src/models/kinds.js.map +1 -1
  50. package/build/src/models/store/Deployment.d.ts +53 -16
  51. package/build/src/models/store/Deployment.d.ts.map +1 -1
  52. package/build/src/models/store/Deployment.js +92 -34
  53. package/build/src/models/store/Deployment.js.map +1 -1
  54. package/build/src/sdk/DataCatalogSdk.d.ts.map +1 -1
  55. package/build/src/sdk/DataCatalogSdk.js +22 -179
  56. package/build/src/sdk/DataCatalogSdk.js.map +1 -1
  57. package/build/src/sdk/DeploymentsSdk.d.ts +48 -0
  58. package/build/src/sdk/DeploymentsSdk.d.ts.map +1 -0
  59. package/build/src/sdk/DeploymentsSdk.js +94 -0
  60. package/build/src/sdk/DeploymentsSdk.js.map +1 -0
  61. package/build/src/sdk/RouteBuilder.d.ts +2 -0
  62. package/build/src/sdk/RouteBuilder.d.ts.map +1 -1
  63. package/build/src/sdk/RouteBuilder.js +6 -0
  64. package/build/src/sdk/RouteBuilder.js.map +1 -1
  65. package/build/src/sdk/Sdk.d.ts +2 -0
  66. package/build/src/sdk/Sdk.d.ts.map +1 -1
  67. package/build/src/sdk/Sdk.js +2 -0
  68. package/build/src/sdk/Sdk.js.map +1 -1
  69. package/build/src/sdk/SdkBase.d.ts +19 -1
  70. package/build/src/sdk/SdkBase.d.ts.map +1 -1
  71. package/build/src/sdk/SdkBase.js +31 -1
  72. package/build/src/sdk/SdkBase.js.map +1 -1
  73. package/build/src/sdk/SdkMock.d.ts +9 -0
  74. package/build/src/sdk/SdkMock.d.ts.map +1 -1
  75. package/build/src/sdk/SdkMock.js +73 -0
  76. package/build/src/sdk/SdkMock.js.map +1 -1
  77. package/build/tsconfig.tsbuildinfo +1 -1
  78. package/package.json +2 -1
  79. package/src/matchit.d.ts +19 -0
  80. package/src/mocking/ModelingMock.ts +2 -0
  81. package/src/mocking/lib/Deployment.ts +88 -0
  82. package/src/modeling/Bindings.ts +4 -0
  83. package/src/modeling/DataFormat.ts +4 -0
  84. package/src/modeling/DomainAssociation.ts +11 -0
  85. package/src/modeling/DomainEntity.ts +30 -1
  86. package/src/modeling/ExposedEntity.ts +26 -1
  87. package/src/modeling/RuntimeApiModel.ts +137 -0
  88. package/src/modeling/types.ts +26 -1
  89. package/src/models/kinds.ts +1 -0
  90. package/src/models/store/Deployment.ts +122 -45
  91. package/src/sdk/DataCatalogSdk.ts +22 -176
  92. package/src/sdk/DeploymentsSdk.ts +123 -0
  93. package/src/sdk/RouteBuilder.ts +8 -0
  94. package/src/sdk/Sdk.ts +3 -0
  95. package/src/sdk/SdkBase.ts +35 -3
  96. package/src/sdk/SdkMock.ts +103 -0
  97. package/tests/unit/modeling/RuntimeApiModel.spec.ts +122 -0
  98. package/tests/unit/modeling/actions/index.spec.ts +113 -0
  99. package/tests/unit/modeling/domain_asociation.spec.ts +28 -0
  100. package/tests/unit/modeling/domain_entity_parents.spec.ts +49 -0
  101. package/tests/unit/modeling/exposed_entity_actions.spec.ts +47 -0
  102. package/tests/unit/models/store/Deployment.spec.ts +108 -44
@@ -1,5 +1,8 @@
1
1
  import type { FieldValidationMessage } from '../../exceptions/validation_error.js'
2
2
  import { nanoid } from '../../nanoid.js'
3
+ import { DeploymentKind } from '../kinds.js'
4
+
5
+ export { DeploymentKind }
3
6
 
4
7
  /**
5
8
  * Status of the deployment
@@ -23,11 +26,21 @@ export enum DeploymentStatus {
23
26
  Failed = 3,
24
27
  }
25
28
 
29
+ /**
30
+ * Environment tag for logical deployment grouping
31
+ */
32
+ export enum DeploymentEnvironment {
33
+ PROD = 'prod',
34
+ STAGING = 'staging',
35
+ DEV = 'dev',
36
+ }
37
+
26
38
  export interface DeploymentSchema {
39
+ kind: typeof DeploymentKind
27
40
  /**
28
41
  * Primary key (nanoid)
29
42
  */
30
- id: string
43
+ key: string
31
44
  /**
32
45
  * ID of the organization
33
46
  */
@@ -37,25 +50,31 @@ export interface DeploymentSchema {
37
50
  */
38
51
  apiId: string
39
52
  /**
40
- * The version of the deployment (e.g., 'v1', 'v2')
53
+ * Denormalized organization slug
41
54
  */
42
- deploymentVersion: string
55
+ orgSlug: string
43
56
  /**
44
- * The semantic version of the deployed API model (e.g., '1.0.1')
57
+ * Denormalized API slug
45
58
  */
46
- apiModelVersion: string
59
+ apiSlug: string
47
60
  /**
48
- * Status of the deployment
61
+ * Environment tag
49
62
  */
50
- status: DeploymentStatus
63
+ env: DeploymentEnvironment
51
64
  /**
52
- * Optional custom path for staging (e.g., '/dev')
65
+ * The version of the deployment (e.g., 'v1', 'v2')
66
+ * It must be set for production environments.
67
+ * It cannot be set for non-production environments (e.g. 'dev').
53
68
  */
54
- stagingPath?: string
69
+ version?: string
55
70
  /**
56
- * Reference to the optimized model in MongoDB
71
+ * The semantic version of the deployed API model (e.g., '1.0.1').
57
72
  */
58
- mongoModelId?: string
73
+ modelVersion: string
74
+ /**
75
+ * Status of the deployment
76
+ */
77
+ status: DeploymentStatus
59
78
  /**
60
79
  * Timestamp of creation
61
80
  */
@@ -64,79 +83,110 @@ export interface DeploymentSchema {
64
83
  * Timestamp of last update
65
84
  */
66
85
  updatedAt: number
86
+ /**
87
+ * The base URI to the API.
88
+ * Note: This field is computed at runtime when the deployment status is active.
89
+ * Note: This field is ignored when creating or updating a deployment.
90
+ */
91
+ baseUri?: string
92
+ /**
93
+ * The URI to the API portal.
94
+ * Note: This field is computed at runtime when the deployment status is active.
95
+ * Note: This field is ignored when creating or updating a deployment.
96
+ */
97
+ portalUri?: string
67
98
  }
68
99
 
69
100
  export class Deployment implements DeploymentSchema {
70
- id: string
101
+ readonly kind: typeof DeploymentKind = DeploymentKind
102
+ key: string
71
103
  orgId: string
72
104
  apiId: string
73
- deploymentVersion: string
74
- apiModelVersion: string
105
+ orgSlug: string
106
+ apiSlug: string
107
+ env: DeploymentEnvironment
108
+ version?: string
109
+ modelVersion: string
75
110
  status: DeploymentStatus
76
- stagingPath?: string
77
- mongoModelId?: string
78
111
  createdAt: number
79
112
  updatedAt: number
113
+ baseUri?: string
114
+ portalUri?: string
80
115
 
81
116
  static createSchema(input: Partial<DeploymentSchema> = {}): DeploymentSchema {
82
- const id = input.id ?? nanoid()
117
+ const key = input.key ?? nanoid()
83
118
  const result: DeploymentSchema = {
84
- id,
119
+ kind: DeploymentKind,
120
+ key,
85
121
  orgId: input.orgId || '',
86
122
  apiId: input.apiId || '',
87
- deploymentVersion: input.deploymentVersion || 'v0',
88
- apiModelVersion: input.apiModelVersion || '0.0.0',
123
+ orgSlug: input.orgSlug || '',
124
+ apiSlug: input.apiSlug || '',
125
+ env: input.env ?? DeploymentEnvironment.DEV,
126
+ modelVersion: input.modelVersion || '0.0.0',
89
127
  status: input.status ?? DeploymentStatus.Pending,
90
128
  createdAt: input.createdAt ?? Date.now(),
91
129
  updatedAt: input.updatedAt ?? Date.now(),
92
130
  }
93
- if (input.stagingPath) {
94
- result.stagingPath = input.stagingPath
131
+ if (input.baseUri) {
132
+ result.baseUri = input.baseUri
95
133
  }
96
- if (input.mongoModelId) {
97
- result.mongoModelId = input.mongoModelId
134
+ if (input.portalUri) {
135
+ result.portalUri = input.portalUri
136
+ }
137
+ if (input.version) {
138
+ result.version = input.version
98
139
  }
99
140
  return result
100
141
  }
101
142
 
102
143
  constructor(state?: Partial<DeploymentSchema>) {
103
144
  const init = Deployment.createSchema(state)
104
- this.id = init.id
145
+ this.key = init.key
105
146
  this.orgId = init.orgId
106
147
  this.apiId = init.apiId
107
- this.deploymentVersion = init.deploymentVersion
108
- this.apiModelVersion = init.apiModelVersion
148
+ this.orgSlug = init.orgSlug
149
+ this.apiSlug = init.apiSlug
150
+ this.env = init.env
151
+ this.version = init.version
109
152
  this.status = init.status
110
- if (init.stagingPath) {
111
- this.stagingPath = init.stagingPath
112
- }
113
- if (init.mongoModelId) {
114
- this.mongoModelId = init.mongoModelId
115
- }
116
153
  this.createdAt = init.createdAt
117
154
  this.updatedAt = init.updatedAt
155
+ this.modelVersion = init.modelVersion
156
+ this.baseUri = init.baseUri
157
+ this.portalUri = init.portalUri
118
158
  }
119
159
 
120
160
  toJSON(): DeploymentSchema {
121
161
  const result: DeploymentSchema = {
122
- id: this.id,
162
+ kind: DeploymentKind,
163
+ key: this.key,
123
164
  orgId: this.orgId,
124
165
  apiId: this.apiId,
125
- deploymentVersion: this.deploymentVersion,
126
- apiModelVersion: this.apiModelVersion,
166
+ orgSlug: this.orgSlug,
167
+ apiSlug: this.apiSlug,
168
+ env: this.env,
169
+ modelVersion: this.modelVersion,
127
170
  status: this.status,
128
171
  createdAt: this.createdAt,
129
172
  updatedAt: this.updatedAt,
130
173
  }
131
- if (this.stagingPath) {
132
- result.stagingPath = this.stagingPath
174
+ if (this.version) {
175
+ result.version = this.version
176
+ }
177
+ if (this.baseUri) {
178
+ result.baseUri = this.baseUri
133
179
  }
134
- if (this.mongoModelId) {
135
- result.mongoModelId = this.mongoModelId
180
+ if (this.portalUri) {
181
+ result.portalUri = this.portalUri
136
182
  }
137
183
  return result
138
184
  }
139
185
 
186
+ /**
187
+ * Validates the deployment.
188
+ * @returns An array of validation messages.
189
+ */
140
190
  validate(): FieldValidationMessage[] {
141
191
  const result: FieldValidationMessage[] = []
142
192
 
@@ -154,20 +204,47 @@ export class Deployment implements DeploymentSchema {
154
204
  rule: 'notEmpty',
155
205
  })
156
206
  }
157
- if (this.deploymentVersion === '') {
207
+ if (this.orgSlug === '') {
208
+ result.push({
209
+ field: 'orgSlug',
210
+ message: 'Org slug must not be empty',
211
+ rule: 'notEmpty',
212
+ })
213
+ }
214
+ if (this.apiSlug === '') {
158
215
  result.push({
159
- field: 'deploymentVersion',
160
- message: 'Deployment version must not be empty',
216
+ field: 'apiSlug',
217
+ message: 'API slug must not be empty',
161
218
  rule: 'notEmpty',
162
219
  })
163
220
  }
164
- if (this.apiModelVersion === '') {
221
+ if (!this.env) {
165
222
  result.push({
166
- field: 'apiModelVersion',
223
+ field: 'env',
224
+ message: 'Environment tag must not be empty',
225
+ rule: 'notEmpty',
226
+ })
227
+ }
228
+ if (this.modelVersion === '') {
229
+ result.push({
230
+ field: 'modelVersion',
167
231
  message: 'API model version must not be empty',
168
232
  rule: 'notEmpty',
169
233
  })
170
234
  }
235
+ if (this.env === DeploymentEnvironment.PROD && !this.version) {
236
+ result.push({
237
+ field: 'version',
238
+ message: 'Version must not be empty for production environment',
239
+ rule: 'notEmpty',
240
+ })
241
+ } else if (this.env !== DeploymentEnvironment.PROD && this.version) {
242
+ result.push({
243
+ field: 'version',
244
+ message: 'Version must not be present for non-production environment',
245
+ rule: 'notEmpty',
246
+ })
247
+ }
171
248
  return result
172
249
  }
173
250
  }
@@ -1,11 +1,4 @@
1
- import {
2
- SdkBase,
3
- E_RESPONSE_STATUS,
4
- E_RESPONSE_NO_VALUE,
5
- E_INVALID_JSON,
6
- E_RESPONSE_UNKNOWN,
7
- SdkOptions,
8
- } from './SdkBase.js'
1
+ import { SdkBase, E_RESPONSE_STATUS, SdkOptions } from './SdkBase.js'
9
2
  import { ContextListResult, ContextListOptions, ContextChangeRecord } from '../events/BaseEvents.js'
10
3
  import type {
11
4
  DataCatalogSchema,
@@ -19,7 +12,6 @@ import { DataCatalogKind, DataCatalogVersionKind } from '../models/kinds.js'
19
12
  import type { DataCatalogVersionSchema } from '../models/DataCatalogVersion.js'
20
13
  import type { ForeignDomainDependency } from '../modeling/types.js'
21
14
  import type { DataDomainSchema } from '../modeling/DataDomain.js'
22
- import { Exception } from '../exceptions/exception.js'
23
15
 
24
16
  export interface DataCatalogListOptions extends ContextListOptions {
25
17
  scope?: DataCatalogScope
@@ -38,26 +30,7 @@ export class DataCatalogSdk extends SdkBase {
38
30
  url.searchParams.set('scope', opts.scope)
39
31
  }
40
32
  const result = await this.sdk.http.get(url.toString(), { token })
41
- this.inspectCommonStatusCodes(result)
42
- const E_PREFIX = 'Unable to list data domains. '
43
- if (result.status !== 200) {
44
- this.logInvalidResponse(result)
45
- throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
46
- }
47
- if (!result.body) {
48
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
49
- }
50
-
51
- let data: ContextListResult<DataCatalogSchemaWithVersion>
52
- try {
53
- data = JSON.parse(result.body)
54
- } catch {
55
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
56
- }
57
- if (!Array.isArray(data.items)) {
58
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
59
- }
60
- return data
33
+ return this.processListResponse<DataCatalogSchemaWithVersion>(result, 'Unable to list data domains. ')
61
34
  }
62
35
 
63
36
  /**
@@ -68,25 +41,7 @@ export class DataCatalogSdk extends SdkBase {
68
41
  const { token } = request
69
42
  const url = this.sdk.getUrl(RouteBuilder.dataCatalogEntryVersions(key))
70
43
  const result = await this.sdk.http.get(url.toString(), { token })
71
- this.inspectCommonStatusCodes(result)
72
- const E_PREFIX = 'Unable to list data domain versions. '
73
- if (result.status !== 200) {
74
- this.logInvalidResponse(result)
75
- throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
76
- }
77
- if (!result.body) {
78
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
79
- }
80
- let data: ContextListResult<DataCatalogVersionInfo>
81
- try {
82
- data = JSON.parse(result.body)
83
- } catch {
84
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
85
- }
86
- if (!Array.isArray(data.items)) {
87
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
88
- }
89
- return data
44
+ return this.processListResponse<DataCatalogVersionInfo>(result, 'Unable to list data domain versions. ')
90
45
  }
91
46
 
92
47
  /**
@@ -112,19 +67,8 @@ export class DataCatalogSdk extends SdkBase {
112
67
  this.logInvalidResponse(result)
113
68
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
114
69
  }
115
-
116
- if (!result.body) {
117
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
118
- }
119
- let data: ContextChangeRecord<DataCatalogSchema>
120
- try {
121
- data = JSON.parse(result.body)
122
- } catch {
123
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
124
- }
125
- if (!data.key) {
126
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
127
- }
70
+ const data = this.readResponseJSON<DataCatalogSchema>(result, E_PREFIX)
71
+ this.assertObjectKind(E_PREFIX, DataCatalogKind, data.kind)
128
72
  return data
129
73
  }
130
74
 
@@ -138,18 +82,8 @@ export class DataCatalogSdk extends SdkBase {
138
82
  this.logInvalidResponse(result)
139
83
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
140
84
  }
141
- if (!result.body) {
142
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
143
- }
144
- let data: DataCatalogSchema
145
- try {
146
- data = JSON.parse(result.body)
147
- } catch {
148
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
149
- }
150
- if (data.kind !== DataCatalogKind) {
151
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
152
- }
85
+ const data = this.readResponseJSON<DataCatalogSchema>(result, E_PREFIX)
86
+ this.assertObjectKind(E_PREFIX, DataCatalogKind, data.kind)
153
87
  return data
154
88
  }
155
89
 
@@ -180,18 +114,8 @@ export class DataCatalogSdk extends SdkBase {
180
114
  this.logInvalidResponse(result)
181
115
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
182
116
  }
183
- if (!result.body) {
184
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
185
- }
186
- let data: ContextChangeRecord<DataCatalogSchema>
187
- try {
188
- data = JSON.parse(result.body)
189
- } catch {
190
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
191
- }
192
- if (data.kind !== DataCatalogKind) {
193
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
194
- }
117
+ const data = this.readResponseJSON<DataCatalogSchema>(result, E_PREFIX)
118
+ this.assertObjectKind(E_PREFIX, DataCatalogKind, data.kind)
195
119
  return data
196
120
  }
197
121
 
@@ -211,18 +135,8 @@ export class DataCatalogSdk extends SdkBase {
211
135
  this.logInvalidResponse(result)
212
136
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
213
137
  }
214
- if (!result.body) {
215
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
216
- }
217
- let data: ContextChangeRecord<DataCatalogSchema>
218
- try {
219
- data = JSON.parse(result.body)
220
- } catch {
221
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
222
- }
223
- if (data.kind !== DataCatalogKind) {
224
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
225
- }
138
+ const data = this.readResponseJSON<DataCatalogSchema>(result, E_PREFIX)
139
+ this.assertObjectKind(E_PREFIX, DataCatalogKind, data.kind)
226
140
  return data
227
141
  }
228
142
 
@@ -247,18 +161,8 @@ export class DataCatalogSdk extends SdkBase {
247
161
  this.logInvalidResponse(result)
248
162
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
249
163
  }
250
- if (!result.body) {
251
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
252
- }
253
- let data: ContextChangeRecord<DataCatalogVersionSchema>
254
- try {
255
- data = JSON.parse(result.body)
256
- } catch {
257
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
258
- }
259
- if (data.kind !== DataCatalogVersionKind) {
260
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
261
- }
164
+ const data = this.readResponseJSON<DataCatalogVersionSchema>(result, E_PREFIX)
165
+ this.assertObjectKind(E_PREFIX, DataCatalogVersionKind, data.kind)
262
166
  return data
263
167
  }
264
168
 
@@ -272,18 +176,8 @@ export class DataCatalogSdk extends SdkBase {
272
176
  this.logInvalidResponse(result)
273
177
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
274
178
  }
275
- if (!result.body) {
276
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
277
- }
278
- let data: DataCatalogVersionSchema
279
- try {
280
- data = JSON.parse(result.body)
281
- } catch {
282
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
283
- }
284
- if (data.kind !== DataCatalogVersionKind) {
285
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
286
- }
179
+ const data = this.readResponseJSON<DataCatalogVersionSchema>(result, E_PREFIX)
180
+ this.assertObjectKind(E_PREFIX, DataCatalogVersionKind, data.kind)
287
181
  return data
288
182
  }
289
183
 
@@ -301,25 +195,7 @@ export class DataCatalogSdk extends SdkBase {
301
195
  'content-type': 'application/json',
302
196
  },
303
197
  })
304
- this.inspectCommonStatusCodes(result)
305
- const E_PREFIX = 'Unable to list data domain dependencies. '
306
- if (result.status !== 200) {
307
- this.logInvalidResponse(result)
308
- throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
309
- }
310
- if (!result.body) {
311
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
312
- }
313
- let data: ContextListResult<DataDomainSchema>
314
- try {
315
- data = JSON.parse(result.body)
316
- } catch {
317
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
318
- }
319
- if (!Array.isArray(data.items)) {
320
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
321
- }
322
- return data
198
+ return this.processListResponse<DataDomainSchema>(result, 'Unable to list data domain dependencies. ')
323
199
  }
324
200
 
325
201
  async deprecateVersion(
@@ -344,18 +220,8 @@ export class DataCatalogSdk extends SdkBase {
344
220
  this.logInvalidResponse(result)
345
221
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
346
222
  }
347
- if (!result.body) {
348
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
349
- }
350
- let data: ContextChangeRecord<DataCatalogVersionSchema>
351
- try {
352
- data = JSON.parse(result.body)
353
- } catch {
354
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
355
- }
356
- if (data.kind !== DataCatalogVersionKind) {
357
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
358
- }
223
+ const data = this.readResponseJSON<DataCatalogVersionSchema>(result, E_PREFIX)
224
+ this.assertObjectKind(E_PREFIX, DataCatalogVersionKind, data.kind)
359
225
  return data
360
226
  }
361
227
 
@@ -373,18 +239,8 @@ export class DataCatalogSdk extends SdkBase {
373
239
  this.logInvalidResponse(result)
374
240
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
375
241
  }
376
- if (!result.body) {
377
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
378
- }
379
- let data: ContextChangeRecord<DataCatalogVersionSchema>
380
- try {
381
- data = JSON.parse(result.body)
382
- } catch {
383
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
384
- }
385
- if (data.kind !== DataCatalogVersionKind) {
386
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
387
- }
242
+ const data = this.readResponseJSON<DataCatalogVersionSchema>(result, E_PREFIX)
243
+ this.assertObjectKind(E_PREFIX, DataCatalogVersionKind, data.kind)
388
244
  return data
389
245
  }
390
246
 
@@ -408,18 +264,8 @@ export class DataCatalogSdk extends SdkBase {
408
264
  this.logInvalidResponse(result)
409
265
  throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
410
266
  }
411
- if (!result.body) {
412
- throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
413
- }
414
- let data: DataCatalogStatus
415
- try {
416
- data = JSON.parse(result.body)
417
- } catch {
418
- throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
419
- }
420
- if (data.kind !== DataCatalogKind) {
421
- throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
422
- }
267
+ const data = this.readResponseJSON<DataCatalogStatus>(result, E_PREFIX)
268
+ this.assertObjectKind(E_PREFIX, DataCatalogKind, data.kind)
423
269
  return data
424
270
  }
425
271
  }
@@ -0,0 +1,123 @@
1
+ import { SdkBase, type SdkOptions, E_RESPONSE_STATUS } from './SdkBase.js'
2
+ import { RouteBuilder } from './RouteBuilder.js'
3
+ import { DeploymentEnvironment, DeploymentKind, DeploymentSchema } from '../models/store/Deployment.js'
4
+ import { Exception } from '../exceptions/exception.js'
5
+ import type { ContextListOptions, ContextListResult } from '../events/BaseEvents.js'
6
+
7
+ export interface CreateDeploymentPayload {
8
+ /**
9
+ * API file ID
10
+ */
11
+ fid: string
12
+ /**
13
+ * API deployment version (e.g. "v1", "v2")
14
+ * It is optional for non production environments (e.g. 'dev').
15
+ */
16
+ version?: string
17
+ /**
18
+ * API model version (e.g. "3.1.2", "4.0.0")
19
+ */
20
+ modelVersion: string
21
+ /**
22
+ * Target environment tag (e.g. "prod", "staging", "dev")
23
+ */
24
+ env: DeploymentEnvironment
25
+ }
26
+
27
+ export class DeploymentsSdk extends SdkBase {
28
+ async list(
29
+ oid: string,
30
+ options: ContextListOptions = {},
31
+ request: SdkOptions = {}
32
+ ): Promise<ContextListResult<DeploymentSchema>> {
33
+ const { token = this.sdk.token } = request
34
+ const url = this.sdk.getUrl(RouteBuilder.deployments(oid))
35
+ this.sdk.appendListOptions(url, options)
36
+ const result = await this.sdk.http.get(url.toString(), { token })
37
+ return this.processListResponse<DeploymentSchema>(result, 'Unable to list deployments. ')
38
+ }
39
+
40
+ /**
41
+ * Triggers the creation of a new deployment.
42
+ *
43
+ * @param oid The parent organization key
44
+ * @param payload The deployment payload
45
+ * @param request Optional SDK options
46
+ */
47
+ async create(oid: string, payload: CreateDeploymentPayload, request: SdkOptions = {}): Promise<DeploymentSchema> {
48
+ // Let's do some basic validation before hitting the API endpoint.
49
+ if (payload.env === DeploymentEnvironment.PROD && !payload.version) {
50
+ throw new Exception(`Version must not be empty for production environment: ${payload.env}`, {
51
+ code: 'INVALID_DEPLOYMENT_VERSION',
52
+ help: 'Please provide a version for production environment',
53
+ status: 400,
54
+ })
55
+ } else if (payload.env !== DeploymentEnvironment.PROD && payload.version) {
56
+ throw new Exception(`Version must not be present for non-production environment: ${payload.env}`, {
57
+ code: 'INVALID_DEPLOYMENT_VERSION',
58
+ help: 'Please remove the version for non-production environment',
59
+ status: 400,
60
+ })
61
+ }
62
+ const url = this.sdk.getUrl(RouteBuilder.deployments(oid))
63
+ const { token = this.sdk.token } = request
64
+ const result = await this.sdk.http.post(url.toString(), {
65
+ token,
66
+ body: JSON.stringify(payload),
67
+ headers: {
68
+ 'content-type': 'application/json',
69
+ },
70
+ })
71
+
72
+ this.inspectCommonStatusCodes(result)
73
+ const E_PREFIX = 'Unable to create a deployment. '
74
+ // It is accepted for async processing.
75
+ if (result.status !== 202) {
76
+ this.logInvalidResponse(result)
77
+ throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
78
+ }
79
+ const data = this.readResponseJSON<DeploymentSchema>(result, E_PREFIX)
80
+ this.assertObjectKind(E_PREFIX, DeploymentKind, data.kind)
81
+ return data
82
+ }
83
+
84
+ /**
85
+ * Reads the status of an API deployment.
86
+ *
87
+ * @param oid The parent organization key
88
+ * @param did The deployment ID
89
+ * @param request Optional SDK options
90
+ */
91
+ async read(oid: string, did: string, request: SdkOptions = {}): Promise<DeploymentSchema> {
92
+ const url = this.sdk.getUrl(RouteBuilder.deployment(oid, did))
93
+ const { token = this.sdk.token } = request
94
+ const result = await this.sdk.http.get(url.toString(), { token })
95
+
96
+ this.inspectCommonStatusCodes(result)
97
+ const E_PREFIX = 'Unable to read a deployment. '
98
+ if (result.status !== 200) {
99
+ this.logInvalidResponse(result)
100
+ throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
101
+ }
102
+ const data = this.readResponseJSON<DeploymentSchema>(result, E_PREFIX)
103
+ this.assertObjectKind(E_PREFIX, DeploymentKind, data.kind)
104
+ return data
105
+ }
106
+
107
+ /**
108
+ * Deactivates a deployment. Essentially it disables the version of an API.
109
+ * @param oid The organization ID
110
+ * @param did The deployment ID
111
+ */
112
+ async deactivate(oid: string, did: string, request: SdkOptions = {}): Promise<void> {
113
+ const url = this.sdk.getUrl(RouteBuilder.deployment(oid, did))
114
+ const { token = this.sdk.token } = request
115
+ const result = await this.sdk.http.delete(url.toString(), { token })
116
+ this.inspectCommonStatusCodes(result)
117
+ const E_PREFIX = 'Unable to deactivate a deployment. '
118
+ if (result.status !== 204) {
119
+ this.logInvalidResponse(result)
120
+ throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
121
+ }
122
+ }
123
+ }
@@ -334,4 +334,12 @@ export class RouteBuilder {
334
334
  static orgSlugValidate(): string {
335
335
  return `/v1/orgs/slugs/validate`
336
336
  }
337
+
338
+ static deployments(oid: string): string {
339
+ return `/v1/orgs/${oid}/deployments`
340
+ }
341
+
342
+ static deployment(oid: string, deploymentId: string): string {
343
+ return `${RouteBuilder.deployments(oid)}/${deploymentId}`
344
+ }
337
345
  }