@aifabrix/builder 2.11.0 → 2.21.0

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 (36) hide show
  1. package/.cursor/rules/project-rules.mdc +194 -0
  2. package/README.md +12 -0
  3. package/lib/api/applications.api.js +164 -0
  4. package/lib/api/auth.api.js +303 -0
  5. package/lib/api/datasources-core.api.js +87 -0
  6. package/lib/api/datasources-extended.api.js +117 -0
  7. package/lib/api/datasources.api.js +13 -0
  8. package/lib/api/deployments.api.js +126 -0
  9. package/lib/api/environments.api.js +245 -0
  10. package/lib/api/external-systems.api.js +251 -0
  11. package/lib/api/index.js +236 -0
  12. package/lib/api/pipeline.api.js +234 -0
  13. package/lib/api/types/applications.types.js +136 -0
  14. package/lib/api/types/auth.types.js +218 -0
  15. package/lib/api/types/datasources.types.js +272 -0
  16. package/lib/api/types/deployments.types.js +184 -0
  17. package/lib/api/types/environments.types.js +197 -0
  18. package/lib/api/types/external-systems.types.js +244 -0
  19. package/lib/api/types/pipeline.types.js +125 -0
  20. package/lib/app-list.js +5 -7
  21. package/lib/app-rotate-secret.js +4 -10
  22. package/lib/cli.js +30 -0
  23. package/lib/commands/login.js +41 -12
  24. package/lib/datasource-deploy.js +7 -30
  25. package/lib/datasource-list.js +9 -6
  26. package/lib/deployer.js +103 -135
  27. package/lib/environment-deploy.js +15 -26
  28. package/lib/external-system-deploy.js +12 -39
  29. package/lib/external-system-download.js +5 -13
  30. package/lib/external-system-test.js +9 -12
  31. package/lib/generator-split.js +342 -0
  32. package/lib/generator.js +94 -5
  33. package/lib/utils/app-register-api.js +5 -10
  34. package/lib/utils/deployment-errors.js +88 -6
  35. package/package.json +1 -1
  36. package/tatus +0 -181
@@ -0,0 +1,236 @@
1
+ /**
2
+ * @fileoverview Centralized API client for AI Fabrix Builder
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const { makeApiCall, authenticatedApiCall } = require('../utils/api');
8
+
9
+ /**
10
+ * API Client class for making typed API calls
11
+ * Wraps existing makeApiCall and authenticatedApiCall utilities
12
+ * @class ApiClient
13
+ */
14
+ class ApiClient {
15
+ /**
16
+ * Create an API client instance
17
+ * @param {string} baseUrl - Base URL for the API (controller URL)
18
+ * @param {Object} [authConfig] - Authentication configuration
19
+ * @param {string} [authConfig.type] - Auth type ('bearer' | 'client-credentials' | 'client-token')
20
+ * @param {string} [authConfig.token] - Bearer token
21
+ * @param {string} [authConfig.clientId] - Client ID
22
+ * @param {string} [authConfig.clientSecret] - Client secret
23
+ */
24
+ constructor(baseUrl, authConfig = {}) {
25
+ if (!baseUrl || typeof baseUrl !== 'string') {
26
+ throw new Error('baseUrl is required and must be a string');
27
+ }
28
+ this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
29
+ this.authConfig = authConfig;
30
+ }
31
+
32
+ /**
33
+ * Build full URL from endpoint path
34
+ * @private
35
+ * @param {string} endpoint - API endpoint path (e.g., '/api/v1/auth/token')
36
+ * @returns {string} Full URL
37
+ */
38
+ _buildUrl(endpoint) {
39
+ const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
40
+ return `${this.baseUrl}${path}`;
41
+ }
42
+
43
+ /**
44
+ * Build request headers with authentication
45
+ * @private
46
+ * @param {Object} [additionalHeaders] - Additional headers to include
47
+ * @returns {Object} Request headers
48
+ */
49
+ _buildHeaders(additionalHeaders = {}) {
50
+ const headers = {
51
+ 'Content-Type': 'application/json',
52
+ ...additionalHeaders
53
+ };
54
+
55
+ // Add authentication headers based on authConfig
56
+ if (this.authConfig.type === 'bearer' || this.authConfig.type === 'client-token') {
57
+ if (this.authConfig.token) {
58
+ headers['Authorization'] = `Bearer ${this.authConfig.token}`;
59
+ }
60
+ } else if (this.authConfig.type === 'client-credentials') {
61
+ if (this.authConfig.clientId) {
62
+ headers['x-client-id'] = this.authConfig.clientId;
63
+ }
64
+ if (this.authConfig.clientSecret) {
65
+ headers['x-client-secret'] = this.authConfig.clientSecret;
66
+ }
67
+ }
68
+
69
+ return headers;
70
+ }
71
+
72
+ /**
73
+ * Make a GET request
74
+ * @async
75
+ * @param {string} endpoint - API endpoint path
76
+ * @param {Object} [options] - Request options
77
+ * @param {Object} [options.headers] - Additional headers
78
+ * @param {Object} [options.params] - Query parameters (will be converted to query string)
79
+ * @returns {Promise<Object>} API response
80
+ */
81
+ async get(endpoint, options = {}) {
82
+ let url = this._buildUrl(endpoint);
83
+ const headers = this._buildHeaders(options.headers);
84
+
85
+ // Add query parameters if provided
86
+ if (options.params) {
87
+ const params = new URLSearchParams();
88
+ Object.entries(options.params).forEach(([key, value]) => {
89
+ if (value !== undefined && value !== null) {
90
+ params.append(key, String(value));
91
+ }
92
+ });
93
+ const queryString = params.toString();
94
+ if (queryString) {
95
+ url += `?${queryString}`;
96
+ }
97
+ }
98
+
99
+ if (this.authConfig.type === 'bearer' || this.authConfig.type === 'client-token') {
100
+ return await authenticatedApiCall(url, { method: 'GET', headers }, this.authConfig.token);
101
+ }
102
+
103
+ return await makeApiCall(url, { method: 'GET', headers });
104
+ }
105
+
106
+ /**
107
+ * Make a POST request
108
+ * @async
109
+ * @param {string} endpoint - API endpoint path
110
+ * @param {Object} [options] - Request options
111
+ * @param {Object} [options.body] - Request body (will be JSON stringified)
112
+ * @param {Object} [options.headers] - Additional headers
113
+ * @param {Object} [options.params] - Query parameters (will be converted to query string)
114
+ * @returns {Promise<Object>} API response
115
+ */
116
+ async post(endpoint, options = {}) {
117
+ let url = this._buildUrl(endpoint);
118
+ const headers = this._buildHeaders(options.headers);
119
+
120
+ // Add query parameters if provided
121
+ if (options.params) {
122
+ const params = new URLSearchParams();
123
+ Object.entries(options.params).forEach(([key, value]) => {
124
+ if (value !== undefined && value !== null) {
125
+ params.append(key, String(value));
126
+ }
127
+ });
128
+ const queryString = params.toString();
129
+ if (queryString) {
130
+ url += `?${queryString}`;
131
+ }
132
+ }
133
+
134
+ const requestOptions = {
135
+ method: 'POST',
136
+ headers
137
+ };
138
+
139
+ if (options.body) {
140
+ requestOptions.body = JSON.stringify(options.body);
141
+ }
142
+
143
+ if (this.authConfig.type === 'bearer' || this.authConfig.type === 'client-token') {
144
+ return await authenticatedApiCall(url, requestOptions, this.authConfig.token);
145
+ }
146
+
147
+ return await makeApiCall(url, requestOptions);
148
+ }
149
+
150
+ /**
151
+ * Make a PATCH request
152
+ * @async
153
+ * @param {string} endpoint - API endpoint path
154
+ * @param {Object} [options] - Request options
155
+ * @param {Object} [options.body] - Request body (will be JSON stringified)
156
+ * @param {Object} [options.headers] - Additional headers
157
+ * @returns {Promise<Object>} API response
158
+ */
159
+ async patch(endpoint, options = {}) {
160
+ const url = this._buildUrl(endpoint);
161
+ const headers = this._buildHeaders(options.headers);
162
+
163
+ const requestOptions = {
164
+ method: 'PATCH',
165
+ headers
166
+ };
167
+
168
+ if (options.body) {
169
+ requestOptions.body = JSON.stringify(options.body);
170
+ }
171
+
172
+ if (this.authConfig.type === 'bearer' || this.authConfig.type === 'client-token') {
173
+ return await authenticatedApiCall(url, requestOptions, this.authConfig.token);
174
+ }
175
+
176
+ return await makeApiCall(url, requestOptions);
177
+ }
178
+
179
+ /**
180
+ * Make a PUT request
181
+ * @async
182
+ * @param {string} endpoint - API endpoint path
183
+ * @param {Object} [options] - Request options
184
+ * @param {Object} [options.body] - Request body (will be JSON stringified)
185
+ * @param {Object} [options.headers] - Additional headers
186
+ * @returns {Promise<Object>} API response
187
+ */
188
+ async put(endpoint, options = {}) {
189
+ const url = this._buildUrl(endpoint);
190
+ const headers = this._buildHeaders(options.headers);
191
+
192
+ const requestOptions = {
193
+ method: 'PUT',
194
+ headers
195
+ };
196
+
197
+ if (options.body) {
198
+ requestOptions.body = JSON.stringify(options.body);
199
+ }
200
+
201
+ if (this.authConfig.type === 'bearer' || this.authConfig.type === 'client-token') {
202
+ return await authenticatedApiCall(url, requestOptions, this.authConfig.token);
203
+ }
204
+
205
+ return await makeApiCall(url, requestOptions);
206
+ }
207
+
208
+ /**
209
+ * Make a DELETE request
210
+ * @async
211
+ * @param {string} endpoint - API endpoint path
212
+ * @param {Object} [options] - Request options
213
+ * @param {Object} [options.headers] - Additional headers
214
+ * @returns {Promise<Object>} API response
215
+ */
216
+ async delete(endpoint, options = {}) {
217
+ const url = this._buildUrl(endpoint);
218
+ const headers = this._buildHeaders(options.headers);
219
+
220
+ const requestOptions = {
221
+ method: 'DELETE',
222
+ headers
223
+ };
224
+
225
+ if (this.authConfig.type === 'bearer' || this.authConfig.type === 'client-token') {
226
+ return await authenticatedApiCall(url, requestOptions, this.authConfig.token);
227
+ }
228
+
229
+ return await makeApiCall(url, requestOptions);
230
+ }
231
+ }
232
+
233
+ module.exports = {
234
+ ApiClient
235
+ };
236
+
@@ -0,0 +1,234 @@
1
+ /**
2
+ * @fileoverview Pipeline API functions
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const { ApiClient } = require('./index');
8
+
9
+ /**
10
+ * Validate deployment configuration
11
+ * POST /api/v1/pipeline/{envKey}/validate
12
+ * @async
13
+ * @function validatePipeline
14
+ * @param {string} controllerUrl - Controller base URL
15
+ * @param {string} envKey - Environment key
16
+ * @param {Object} authConfig - Authentication configuration (supports client credentials)
17
+ * @param {Object} validationData - Validation data
18
+ * @param {string} validationData.clientId - Client ID for application authentication
19
+ * @param {string} validationData.repositoryUrl - Repository URL for validation
20
+ * @param {Object} validationData.applicationConfig - Application configuration
21
+ * @returns {Promise<Object>} Validation response with validateToken and ACR credentials
22
+ * @throws {Error} If validation fails
23
+ */
24
+ async function validatePipeline(controllerUrl, envKey, authConfig, validationData) {
25
+ const client = new ApiClient(controllerUrl, authConfig);
26
+ return await client.post(`/api/v1/pipeline/${envKey}/validate`, {
27
+ body: validationData
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Deploy application using validateToken
33
+ * POST /api/v1/pipeline/{envKey}/deploy
34
+ * @async
35
+ * @function deployPipeline
36
+ * @param {string} controllerUrl - Controller base URL
37
+ * @param {string} envKey - Environment key
38
+ * @param {Object} authConfig - Authentication configuration (supports client credentials)
39
+ * @param {Object} deployData - Deployment data
40
+ * @param {string} deployData.validateToken - One-time deployment token from /validate endpoint
41
+ * @param {string} deployData.imageTag - Container image tag to deploy
42
+ * @returns {Promise<Object>} Deployment response
43
+ * @throws {Error} If deployment fails
44
+ */
45
+ async function deployPipeline(controllerUrl, envKey, authConfig, deployData) {
46
+ const client = new ApiClient(controllerUrl, authConfig);
47
+ return await client.post(`/api/v1/pipeline/${envKey}/deploy`, {
48
+ body: deployData
49
+ });
50
+ }
51
+
52
+ /**
53
+ * Get deployment status for CI/CD
54
+ * GET /api/v1/pipeline/{envKey}/deployments/{deploymentId}
55
+ * @async
56
+ * @function getPipelineDeployment
57
+ * @param {string} controllerUrl - Controller base URL
58
+ * @param {string} envKey - Environment key
59
+ * @param {string} deploymentId - Deployment ID
60
+ * @param {Object} authConfig - Authentication configuration (supports client credentials)
61
+ * @returns {Promise<Object>} Minimal deployment status response
62
+ * @throws {Error} If request fails
63
+ */
64
+ async function getPipelineDeployment(controllerUrl, envKey, deploymentId, authConfig) {
65
+ const client = new ApiClient(controllerUrl, authConfig);
66
+ return await client.get(`/api/v1/pipeline/${envKey}/deployments/${deploymentId}`);
67
+ }
68
+
69
+ /**
70
+ * Pipeline health check
71
+ * GET /api/v1/pipeline/{envKey}/health
72
+ * @async
73
+ * @function getPipelineHealth
74
+ * @param {string} controllerUrl - Controller base URL
75
+ * @param {string} envKey - Environment key
76
+ * @returns {Promise<Object>} Health check response (public endpoint, no auth required)
77
+ * @throws {Error} If request fails
78
+ */
79
+ async function getPipelineHealth(controllerUrl, envKey) {
80
+ const client = new ApiClient(controllerUrl);
81
+ return await client.get(`/api/v1/pipeline/${envKey}/health`);
82
+ }
83
+
84
+ /**
85
+ * Publish datasource via dataplane pipeline endpoint
86
+ * POST /api/v1/pipeline/{systemKey}/publish
87
+ * @async
88
+ * @function publishDatasourceViaPipeline
89
+ * @param {string} dataplaneUrl - Dataplane base URL
90
+ * @param {string} systemKey - System key
91
+ * @param {Object} authConfig - Authentication configuration
92
+ * @param {Object} datasourceConfig - Datasource configuration to publish
93
+ * @returns {Promise<Object>} Publish response
94
+ * @throws {Error} If publish fails
95
+ */
96
+ async function publishDatasourceViaPipeline(dataplaneUrl, systemKey, authConfig, datasourceConfig) {
97
+ const client = new ApiClient(dataplaneUrl, authConfig);
98
+ return await client.post(`/api/v1/pipeline/${systemKey}/publish`, {
99
+ body: datasourceConfig
100
+ });
101
+ }
102
+
103
+ /**
104
+ * Test datasource via dataplane pipeline endpoint
105
+ * POST /api/v1/pipeline/{systemKey}/{datasourceKey}/test
106
+ * @async
107
+ * @function testDatasourceViaPipeline
108
+ * @param {string} dataplaneUrl - Dataplane base URL
109
+ * @param {string} systemKey - System key
110
+ * @param {string} datasourceKey - Datasource key
111
+ * @param {Object} authConfig - Authentication configuration
112
+ * @param {Object} testData - Test data
113
+ * @param {Object} testData.payloadTemplate - Test payload template
114
+ * @param {Object} [options] - Request options
115
+ * @param {number} [options.timeout] - Request timeout in milliseconds
116
+ * @returns {Promise<Object>} Test response
117
+ * @throws {Error} If test fails
118
+ */
119
+ async function testDatasourceViaPipeline(dataplaneUrl, systemKey, datasourceKey, authConfig, testData, options = {}) {
120
+ const client = new ApiClient(dataplaneUrl, authConfig);
121
+ const requestOptions = {
122
+ body: testData
123
+ };
124
+ // Pass through timeout if provided (will be handled by underlying fetch implementation)
125
+ if (options.timeout) {
126
+ requestOptions.timeout = options.timeout;
127
+ }
128
+ return await client.post(`/api/v1/pipeline/${systemKey}/${datasourceKey}/test`, requestOptions);
129
+ }
130
+
131
+ /**
132
+ * Deploy external system via dataplane pipeline endpoint
133
+ * POST /api/v1/pipeline/deploy
134
+ * @async
135
+ * @function deployExternalSystemViaPipeline
136
+ * @param {string} dataplaneUrl - Dataplane base URL
137
+ * @param {Object} authConfig - Authentication configuration
138
+ * @param {Object} systemConfig - External system configuration to deploy
139
+ * @returns {Promise<Object>} Deployment response
140
+ * @throws {Error} If deployment fails
141
+ */
142
+ async function deployExternalSystemViaPipeline(dataplaneUrl, authConfig, systemConfig) {
143
+ const client = new ApiClient(dataplaneUrl, authConfig);
144
+ return await client.post('/api/v1/pipeline/deploy', {
145
+ body: systemConfig
146
+ });
147
+ }
148
+
149
+ /**
150
+ * Deploy datasource via dataplane pipeline endpoint
151
+ * POST /api/v1/pipeline/{systemKey}/deploy
152
+ * @async
153
+ * @function deployDatasourceViaPipeline
154
+ * @param {string} dataplaneUrl - Dataplane base URL
155
+ * @param {string} systemKey - System key
156
+ * @param {Object} authConfig - Authentication configuration
157
+ * @param {Object} datasourceConfig - Datasource configuration to deploy
158
+ * @returns {Promise<Object>} Deployment response
159
+ * @throws {Error} If deployment fails
160
+ */
161
+ async function deployDatasourceViaPipeline(dataplaneUrl, systemKey, authConfig, datasourceConfig) {
162
+ const client = new ApiClient(dataplaneUrl, authConfig);
163
+ return await client.post(`/api/v1/pipeline/${systemKey}/deploy`, {
164
+ body: datasourceConfig
165
+ });
166
+ }
167
+
168
+ /**
169
+ * Upload application configuration via dataplane pipeline endpoint
170
+ * POST /api/v1/pipeline/upload
171
+ * @async
172
+ * @function uploadApplicationViaPipeline
173
+ * @param {string} dataplaneUrl - Dataplane base URL
174
+ * @param {Object} authConfig - Authentication configuration
175
+ * @param {Object} applicationSchema - Application schema configuration
176
+ * @returns {Promise<Object>} Upload response with uploadId
177
+ * @throws {Error} If upload fails
178
+ */
179
+ async function uploadApplicationViaPipeline(dataplaneUrl, authConfig, applicationSchema) {
180
+ const client = new ApiClient(dataplaneUrl, authConfig);
181
+ return await client.post('/api/v1/pipeline/upload', {
182
+ body: applicationSchema
183
+ });
184
+ }
185
+
186
+ /**
187
+ * Validate upload via dataplane pipeline endpoint
188
+ * POST /api/v1/pipeline/upload/{uploadId}/validate
189
+ * @async
190
+ * @function validateUploadViaPipeline
191
+ * @param {string} dataplaneUrl - Dataplane base URL
192
+ * @param {string} uploadId - Upload ID
193
+ * @param {Object} authConfig - Authentication configuration
194
+ * @returns {Promise<Object>} Validation response with changes and summary
195
+ * @throws {Error} If validation fails
196
+ */
197
+ async function validateUploadViaPipeline(dataplaneUrl, uploadId, authConfig) {
198
+ const client = new ApiClient(dataplaneUrl, authConfig);
199
+ return await client.post(`/api/v1/pipeline/upload/${uploadId}/validate`);
200
+ }
201
+
202
+ /**
203
+ * Publish upload via dataplane pipeline endpoint
204
+ * POST /api/v1/pipeline/upload/{uploadId}/publish
205
+ * @async
206
+ * @function publishUploadViaPipeline
207
+ * @param {string} dataplaneUrl - Dataplane base URL
208
+ * @param {string} uploadId - Upload ID
209
+ * @param {Object} authConfig - Authentication configuration
210
+ * @param {Object} [options] - Publish options
211
+ * @param {boolean} [options.generateMcpContract] - Generate MCP contract (default: true)
212
+ * @returns {Promise<Object>} Publish response
213
+ * @throws {Error} If publish fails
214
+ */
215
+ async function publishUploadViaPipeline(dataplaneUrl, uploadId, authConfig, options = {}) {
216
+ const client = new ApiClient(dataplaneUrl, authConfig);
217
+ const generateMcpContract = options.generateMcpContract !== false; // Default to true
218
+ return await client.post(`/api/v1/pipeline/upload/${uploadId}/publish?generateMcpContract=${generateMcpContract}`);
219
+ }
220
+
221
+ module.exports = {
222
+ validatePipeline,
223
+ deployPipeline,
224
+ getPipelineDeployment,
225
+ getPipelineHealth,
226
+ publishDatasourceViaPipeline,
227
+ testDatasourceViaPipeline,
228
+ deployExternalSystemViaPipeline,
229
+ deployDatasourceViaPipeline,
230
+ uploadApplicationViaPipeline,
231
+ validateUploadViaPipeline,
232
+ publishUploadViaPipeline
233
+ };
234
+
@@ -0,0 +1,136 @@
1
+ /**
2
+ * @fileoverview Applications API type definitions
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ /**
8
+ * Pagination metadata
9
+ * @typedef {Object} PaginationMeta
10
+ * @property {number} page - Current page number
11
+ * @property {number} pageSize - Number of items per page
12
+ * @property {number} total - Total number of items
13
+ * @property {number} totalPages - Total number of pages
14
+ */
15
+
16
+ /**
17
+ * Pagination links
18
+ * @typedef {Object} PaginationLinks
19
+ * @property {string} self - Current page URL
20
+ * @property {string} first - First page URL
21
+ * @property {string} last - Last page URL
22
+ * @property {string|null} prev - Previous page URL (null if on first page)
23
+ * @property {string|null} next - Next page URL (null if on last page)
24
+ */
25
+
26
+ /**
27
+ * Application configuration (references application-config.schema.yaml)
28
+ * @typedef {Object} ApplicationConfig
29
+ * @property {string} key - Unique application identifier
30
+ * @property {string} displayName - Human-readable application name
31
+ * @property {string} description - Application description
32
+ * @property {string} type - Azure application type ('webapp' | 'functionapp' | 'api' | 'service' | 'external')
33
+ * @property {string} deploymentKey - SHA256 hash of deployment manifest
34
+ * @property {string} [image] - Container image reference
35
+ * @property {string} [registryMode] - Registry mode ('acr' | 'external' | 'public')
36
+ * @property {number} [port] - Application port number
37
+ * @property {Object} [externalIntegration] - External systems & data sources configuration
38
+ * @property {Object} [system] - Inline external system configuration
39
+ * @property {Object[]} [dataSources] - Inline external data source configurations
40
+ * @property {boolean} [requiresDatabase] - Whether application requires database
41
+ * @property {Object[]} [databases] - Database configurations
42
+ * @property {boolean} [requiresRedis] - Whether application requires Redis
43
+ * @property {boolean} [requiresStorage] - Whether application requires storage
44
+ * @property {Object[]} [configuration] - Core application configuration
45
+ * @property {Object[]} [conditionalConfiguration] - Conditional configuration
46
+ * @property {Object} [healthCheck] - Health check configuration
47
+ * @property {Object} [frontDoorRouting] - Front Door routing configuration
48
+ * @property {Object} [authentication] - Authentication configuration
49
+ * @property {Object[]} [roles] - Application roles
50
+ * @property {Object[]} [permissions] - Application permissions
51
+ * @property {Object} [repository] - Repository deployment configuration
52
+ * @property {string} [startupCommand] - Application startup command
53
+ * @property {Object} [runtimeVersion] - Runtime version configuration
54
+ * @property {Object} [scaling] - Application scaling configuration
55
+ * @property {Object} [build] - Build and local development configuration
56
+ * @property {Object} [deployment] - Deployment configuration for pipeline API
57
+ */
58
+
59
+ /**
60
+ * Application entity
61
+ * @typedef {Object} Application
62
+ * @property {string} id - Application ID
63
+ * @property {string} key - Application key (unique identifier)
64
+ * @property {string} displayName - Display name
65
+ * @property {string|null} description - Application description
66
+ * @property {string|null} url - Application URL
67
+ * @property {ApplicationConfig} configuration - Application configuration
68
+ * @property {string} status - Application status ('healthy' | 'degraded' | 'deploying' | 'error' | 'maintenance')
69
+ * @property {string} createdAt - Creation timestamp (ISO 8601)
70
+ * @property {string} updatedAt - Update timestamp (ISO 8601)
71
+ */
72
+
73
+ /**
74
+ * List applications request options
75
+ * @typedef {Object} ListApplicationsRequest
76
+ * @property {number} [page] - Page number (default: 1)
77
+ * @property {number} [pageSize] - Items per page (default: 10)
78
+ * @property {string} [sort] - Sort parameter
79
+ * @property {string} [filter] - Filter parameter
80
+ * @property {string} [search] - Search term to match across key, displayName, name, and description fields
81
+ */
82
+
83
+ /**
84
+ * List applications response
85
+ * @typedef {Object} ListApplicationsResponse
86
+ * @property {Application[]} data - Array of template applications
87
+ * @property {PaginationMeta} meta - Pagination metadata
88
+ * @property {PaginationLinks} links - Pagination links
89
+ */
90
+
91
+ /**
92
+ * Create application request
93
+ * @typedef {Object} CreateApplicationRequest
94
+ * @property {string} key - Application key (lowercase, numbers, hyphens only)
95
+ * @property {string} displayName - Display name
96
+ * @property {string} [description] - Application description
97
+ * @property {string} [url] - Application URL
98
+ * @property {ApplicationConfig} configuration - Application configuration
99
+ */
100
+
101
+ /**
102
+ * Create application response
103
+ * @typedef {Object} CreateApplicationResponse
104
+ * @property {Application} data - Created template application
105
+ */
106
+
107
+ /**
108
+ * Get application response
109
+ * @typedef {Object} GetApplicationResponse
110
+ * @property {Application} data - Template application details
111
+ */
112
+
113
+ /**
114
+ * Update application request
115
+ * @typedef {Object} UpdateApplicationRequest
116
+ * @property {string} [displayName] - Display name
117
+ * @property {string} [description] - Application description
118
+ * @property {string} [url] - Application URL
119
+ * @property {ApplicationConfig} [configuration] - Application configuration
120
+ * @property {string} [status] - Application status ('healthy' | 'degraded' | 'deploying' | 'error' | 'maintenance')
121
+ */
122
+
123
+ /**
124
+ * Update application response
125
+ * @typedef {Object} UpdateApplicationResponse
126
+ * @property {Application} data - Updated template application
127
+ */
128
+
129
+ /**
130
+ * Delete application response
131
+ * @typedef {Object} DeleteApplicationResponse
132
+ * @property {null} data - Always null for DELETE operations
133
+ */
134
+
135
+ module.exports = {};
136
+