@stackgenhq/backstage-plugin-stackgen-backend 0.3.6-beta.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.
Files changed (66) hide show
  1. package/README.md +485 -0
  2. package/config.d.ts +39 -0
  3. package/dist/actions/core/assign_project_members_action.cjs.js +227 -0
  4. package/dist/actions/core/assign_project_members_action.cjs.js.map +1 -0
  5. package/dist/actions/core/create_appstack_action.cjs.js +953 -0
  6. package/dist/actions/core/create_appstack_action.cjs.js.map +1 -0
  7. package/dist/actions/core/create_project_action.cjs.js +243 -0
  8. package/dist/actions/core/create_project_action.cjs.js.map +1 -0
  9. package/dist/actions/core/download_iac_action.cjs.js +133 -0
  10. package/dist/actions/core/download_iac_action.cjs.js.map +1 -0
  11. package/dist/actions/core/set_environment_variable_values_action.cjs.js +121 -0
  12. package/dist/actions/core/set_environment_variable_values_action.cjs.js.map +1 -0
  13. package/dist/actions/core/set_state_backend_action.cjs.js +174 -0
  14. package/dist/actions/core/set_state_backend_action.cjs.js.map +1 -0
  15. package/dist/actions/exporter/export_iac_to_git_action.cjs.js +290 -0
  16. package/dist/actions/exporter/export_iac_to_git_action.cjs.js.map +1 -0
  17. package/dist/actions/exporter/list_vault_secrets_action.cjs.js +39 -0
  18. package/dist/actions/exporter/list_vault_secrets_action.cjs.js.map +1 -0
  19. package/dist/config/constants.cjs.js +23 -0
  20. package/dist/config/constants.cjs.js.map +1 -0
  21. package/dist/exporter/exportOverrides.cjs.js +27 -0
  22. package/dist/exporter/exportOverrides.cjs.js.map +1 -0
  23. package/dist/exporter/gitExporterConfigHttp.cjs.js +105 -0
  24. package/dist/exporter/gitExporterConfigHttp.cjs.js.map +1 -0
  25. package/dist/exporter/http.cjs.js +14 -0
  26. package/dist/exporter/http.cjs.js.map +1 -0
  27. package/dist/exporter/paths.cjs.js +25 -0
  28. package/dist/exporter/paths.cjs.js.map +1 -0
  29. package/dist/exporter/projectGitExporterTemplate.cjs.js +62 -0
  30. package/dist/exporter/projectGitExporterTemplate.cjs.js.map +1 -0
  31. package/dist/exporter/topologyResolve.cjs.js +71 -0
  32. package/dist/exporter/topologyResolve.cjs.js.map +1 -0
  33. package/dist/index.cjs.js +31 -0
  34. package/dist/index.cjs.js.map +1 -0
  35. package/dist/index.d.ts +224 -0
  36. package/dist/lib/extractArchive.cjs.js +62 -0
  37. package/dist/lib/extractArchive.cjs.js.map +1 -0
  38. package/dist/modules/stackgenExporterScaffolderModule.cjs.js +29 -0
  39. package/dist/modules/stackgenExporterScaffolderModule.cjs.js.map +1 -0
  40. package/dist/modules/stackgenUiProxiesModule.cjs.js +366 -0
  41. package/dist/modules/stackgenUiProxiesModule.cjs.js.map +1 -0
  42. package/dist/plugin/plugin.cjs.js +136 -0
  43. package/dist/plugin/plugin.cjs.js.map +1 -0
  44. package/dist/plugin/router.cjs.js +341 -0
  45. package/dist/plugin/router.cjs.js.map +1 -0
  46. package/dist/services/MappingsService/mappingsService.cjs.js +149 -0
  47. package/dist/services/MappingsService/mappingsService.cjs.js.map +1 -0
  48. package/dist/services/StackgenService/stackgenService.cjs.js +267 -0
  49. package/dist/services/StackgenService/stackgenService.cjs.js.map +1 -0
  50. package/dist/utils/api-objects.cjs.js +205 -0
  51. package/dist/utils/api-objects.cjs.js.map +1 -0
  52. package/dist/vendor/stackgen-api-client/index.cjs.js +47681 -0
  53. package/dist/vendor/stackgen-api-client/index.cjs.js.map +1 -0
  54. package/migrations/20250131055302_init.js +24 -0
  55. package/migrations/20250305123456_alter_type_associations.js +23 -0
  56. package/package.json +86 -0
  57. package/templates/appstack-configure-environment.yaml +81 -0
  58. package/templates/appstack-from-template.yaml +76 -0
  59. package/templates/appstack-with-modules.yaml +69 -0
  60. package/templates/appstack-with-resources.yaml +81 -0
  61. package/templates/export-iac.yaml +97 -0
  62. package/templates/full-infra-setup.yaml +156 -0
  63. package/templates/git_export_exporter_multi_scm.yaml +123 -0
  64. package/templates/project-advanced.yaml +77 -0
  65. package/templates/project-basic.yaml +39 -0
  66. package/templates/project-with-members.yaml +86 -0
@@ -0,0 +1,366 @@
1
+ 'use strict';
2
+
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
4
+ var express = require('express');
5
+ var gitExporterConfigHttp = require('../exporter/gitExporterConfigHttp.cjs.js');
6
+ var topologyResolve = require('../exporter/topologyResolve.cjs.js');
7
+ var apiObjects = require('../utils/api-objects.cjs.js');
8
+
9
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
10
+
11
+ var express__default = /*#__PURE__*/_interopDefaultCompat(express);
12
+
13
+ async function proxyStackgenClientCall(res, logger, operation, call) {
14
+ try {
15
+ const body = await call();
16
+ res.status(200).json(body);
17
+ } catch (error) {
18
+ const parsedError = await apiObjects.readClientError(error);
19
+ if (parsedError.status === 500 && parsedError.text === String(error)) {
20
+ logger.error(
21
+ `${operation} failed: ${apiObjects.formatApiFailure(
22
+ parsedError.status,
23
+ parsedError.body,
24
+ parsedError.text,
25
+ parsedError.requestId
26
+ )}`
27
+ );
28
+ res.status(502).json({ message: `${operation} failed` });
29
+ return;
30
+ }
31
+ if (parsedError.requestId) {
32
+ res.setHeader("x-request-id", parsedError.requestId);
33
+ }
34
+ const payload = parsedError.body && typeof parsedError.body === "object" ? parsedError.body : { message: parsedError.text || `${operation} failed` };
35
+ res.status(parsedError.status).json(payload);
36
+ }
37
+ }
38
+ const stackgenUiProxiesModule = backendPluginApi.createBackendModule({
39
+ pluginId: "stackgen",
40
+ moduleId: "stackgen-ui-proxies",
41
+ register(env) {
42
+ env.registerInit({
43
+ deps: {
44
+ httpRouter: backendPluginApi.coreServices.httpRouter,
45
+ config: backendPluginApi.coreServices.rootConfig,
46
+ logger: backendPluginApi.coreServices.logger,
47
+ httpAuth: backendPluginApi.coreServices.httpAuth
48
+ },
49
+ async init({ httpRouter, config, logger, httpAuth }) {
50
+ const router = express__default.default.Router();
51
+ router.use(express__default.default.json());
52
+ router.get("/vault-secrets", async (req, res) => {
53
+ try {
54
+ await httpAuth.credentials(req, { allow: ["user"] });
55
+ } catch {
56
+ res.status(401).json({ message: "Unauthorized" });
57
+ return;
58
+ }
59
+ const orgId = typeof req.query.orgId === "string" ? req.query.orgId.trim() : "";
60
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
61
+ logger.info("Vault secrets proxy via generated client");
62
+ await proxyStackgenClientCall(
63
+ res,
64
+ logger,
65
+ "Vault secrets proxy",
66
+ () => stackgenApis.vaultSecretApiObj.getSecrets({
67
+ orgId: orgId || void 0,
68
+ category: typeof req.query.category === "string" ? req.query.category : void 0,
69
+ subcategory: typeof req.query.subcategory === "string" ? req.query.subcategory : void 0,
70
+ name: typeof req.query.name === "string" ? req.query.name : void 0
71
+ })
72
+ );
73
+ });
74
+ router.get(
75
+ "/exporter-git-configs/:id",
76
+ async (req, res) => {
77
+ try {
78
+ await httpAuth.credentials(req, { allow: ["user"] });
79
+ } catch {
80
+ res.status(401).json({ message: "Unauthorized" });
81
+ return;
82
+ }
83
+ const orgId = typeof req.query.orgId === "string" ? req.query.orgId.trim() : "";
84
+ if (!orgId) {
85
+ res.status(400).json({ message: "orgId query parameter is required" });
86
+ return;
87
+ }
88
+ const configId = typeof req.params.id === "string" ? req.params.id.trim() : "";
89
+ if (!configId) {
90
+ res.status(400).json({ message: "config id is required" });
91
+ return;
92
+ }
93
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
94
+ await proxyStackgenClientCall(
95
+ res,
96
+ logger,
97
+ "Exporter config detail proxy",
98
+ async () => {
99
+ const body = await stackgenApis.exporterConfigApiObj.getConfig({
100
+ id: configId,
101
+ orgId
102
+ });
103
+ const parameters = body?.parameters && typeof body.parameters === "object" ? body.parameters : {};
104
+ return {
105
+ id: body?.id ?? configId,
106
+ name: body?.name,
107
+ parameters
108
+ };
109
+ }
110
+ );
111
+ }
112
+ );
113
+ router.get(
114
+ "/exporter-git-configs",
115
+ async (req, res) => {
116
+ try {
117
+ await httpAuth.credentials(req, { allow: ["user"] });
118
+ } catch {
119
+ res.status(401).json({ message: "Unauthorized" });
120
+ return;
121
+ }
122
+ const orgId = typeof req.query.orgId === "string" ? req.query.orgId : "";
123
+ if (!orgId.trim()) {
124
+ res.status(400).json({ message: "orgId query parameter is required" });
125
+ return;
126
+ }
127
+ const appstackId = typeof req.query.appstackId === "string" ? req.query.appstackId.trim() : "";
128
+ const appstackName = typeof req.query.appstackName === "string" ? req.query.appstackName.trim() : "";
129
+ await proxyStackgenClientCall(
130
+ res,
131
+ logger,
132
+ "Exporter configs proxy",
133
+ async () => {
134
+ let filterAppstackId = appstackId || void 0;
135
+ if (appstackName || appstackId) {
136
+ try {
137
+ filterAppstackId = await topologyResolve.resolveExporterAppstackId({
138
+ config,
139
+ teamId: orgId.trim(),
140
+ appstackId: appstackId || void 0,
141
+ appstackName: appstackName || void 0,
142
+ logger
143
+ });
144
+ } catch (error) {
145
+ logger.warn(
146
+ `Could not resolve exporter appstackId: ${await apiObjects.formatClientErrorMessage(error)}`
147
+ );
148
+ filterAppstackId = void 0;
149
+ }
150
+ }
151
+ return gitExporterConfigHttp.listGitExporterConfigs(
152
+ config,
153
+ {
154
+ orgId: orgId.trim(),
155
+ type: "git",
156
+ appstackId: filterAppstackId
157
+ },
158
+ logger
159
+ );
160
+ }
161
+ );
162
+ }
163
+ );
164
+ router.get("/export-history", async (req, res) => {
165
+ try {
166
+ await httpAuth.credentials(req, { allow: ["user"] });
167
+ } catch {
168
+ res.status(401).json({ message: "Unauthorized" });
169
+ return;
170
+ }
171
+ const orgId = typeof req.query.orgId === "string" ? req.query.orgId.trim() : "";
172
+ const appstackName = typeof req.query.appstackName === "string" ? req.query.appstackName.trim() : "";
173
+ if (!orgId) {
174
+ res.status(400).json({ message: "orgId query parameter is required" });
175
+ return;
176
+ }
177
+ if (!appstackName) {
178
+ res.status(400).json({ message: "appstackName query parameter is required" });
179
+ return;
180
+ }
181
+ const limitRaw = typeof req.query.limit === "string" ? Number(req.query.limit) : 1;
182
+ const limit = Number.isFinite(limitRaw) && limitRaw > 0 ? Math.min(Math.floor(limitRaw), 50) : 1;
183
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
184
+ await proxyStackgenClientCall(
185
+ res,
186
+ logger,
187
+ "Export history proxy",
188
+ async () => {
189
+ const topologyId = await topologyResolve.resolveTopologyId({
190
+ config,
191
+ teamId: orgId,
192
+ appstackName,
193
+ logger
194
+ });
195
+ const history = await stackgenApis.exporterApiObj.getExportHistory({
196
+ orgId,
197
+ topologyIds: [topologyId],
198
+ limit
199
+ });
200
+ const first = Array.isArray(history?.records) ? history.records[0] : void 0;
201
+ const head = typeof first?.metadata?.head === "string" ? first.metadata.head.trim() : "";
202
+ return {
203
+ topologyId,
204
+ ...head ? { head } : {}
205
+ };
206
+ }
207
+ );
208
+ });
209
+ router.get(
210
+ "/environment-profiles",
211
+ async (req, res) => {
212
+ try {
213
+ await httpAuth.credentials(req, { allow: ["user"] });
214
+ } catch {
215
+ res.status(401).json({ message: "Unauthorized" });
216
+ return;
217
+ }
218
+ const orgId = typeof req.query.orgId === "string" ? req.query.orgId.trim() : "";
219
+ let topologyId = typeof req.query.topologyId === "string" ? req.query.topologyId.trim() : "";
220
+ const appstackName = typeof req.query.appstackName === "string" ? req.query.appstackName.trim() : "";
221
+ await proxyStackgenClientCall(
222
+ res,
223
+ logger,
224
+ "Environment profiles proxy",
225
+ async () => {
226
+ if (!topologyId && orgId && appstackName) {
227
+ topologyId = await topologyResolve.resolveTopologyId({
228
+ config,
229
+ teamId: orgId,
230
+ appstackName,
231
+ logger
232
+ });
233
+ }
234
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
235
+ return stackgenApis.v1EnvironmentProfileApiObj.getAllEnvProfiles(
236
+ {
237
+ orgId: orgId || void 0,
238
+ topologyID: topologyId || void 0
239
+ }
240
+ );
241
+ }
242
+ );
243
+ }
244
+ );
245
+ router.get("/users", async (req, res) => {
246
+ try {
247
+ await httpAuth.credentials(req, { allow: ["user"] });
248
+ } catch {
249
+ res.status(401).json({ message: "Unauthorized" });
250
+ return;
251
+ }
252
+ const orgId = typeof req.query.orgId === "string" ? req.query.orgId.trim() : "";
253
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
254
+ await proxyStackgenClientCall(
255
+ res,
256
+ logger,
257
+ "Users proxy",
258
+ () => stackgenApis.usersApiObj.listUsers({
259
+ orgID: orgId || void 0
260
+ })
261
+ );
262
+ });
263
+ router.get("/me", async (req, res) => {
264
+ try {
265
+ await httpAuth.credentials(req, { allow: ["user"] });
266
+ } catch {
267
+ res.status(401).json({ message: "Unauthorized" });
268
+ return;
269
+ }
270
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
271
+ await proxyStackgenClientCall(
272
+ res,
273
+ logger,
274
+ "Current user proxy",
275
+ () => stackgenApis.authenticationApiObject.getMe()
276
+ );
277
+ });
278
+ router.get("/user-groups", async (req, res) => {
279
+ try {
280
+ await httpAuth.credentials(req, { allow: ["user"] });
281
+ } catch {
282
+ res.status(401).json({ message: "Unauthorized" });
283
+ return;
284
+ }
285
+ const includeMembers = typeof req.query.includeMembers === "string" ? req.query.includeMembers === "true" : true;
286
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
287
+ await proxyStackgenClientCall(
288
+ res,
289
+ logger,
290
+ "User groups proxy",
291
+ () => stackgenApis.userGroupApiObj.listUserGroups({
292
+ includeMembers
293
+ })
294
+ );
295
+ });
296
+ router.get("/modules", async (req, res) => {
297
+ try {
298
+ await httpAuth.credentials(req, { allow: ["user"] });
299
+ } catch {
300
+ res.status(401).json({ message: "Unauthorized" });
301
+ return;
302
+ }
303
+ const orgId = typeof req.query.orgId === "string" ? req.query.orgId.trim() : "";
304
+ const pageRaw = typeof req.query.page === "string" ? Number(req.query.page) : 1;
305
+ const perPageRaw = typeof req.query.perPage === "string" ? Number(req.query.perPage) : 100;
306
+ const page = Number.isFinite(pageRaw) && pageRaw > 0 ? Math.floor(pageRaw) : 1;
307
+ const perPage = Number.isFinite(perPageRaw) && perPageRaw > 0 ? Math.min(Math.floor(perPageRaw), 100) : 100;
308
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
309
+ await proxyStackgenClientCall(
310
+ res,
311
+ logger,
312
+ "Modules proxy",
313
+ () => stackgenApis.v1CustomResourceTemplateApiObj.getAccessibleCustomResourceTemplates(
314
+ {
315
+ orgId: orgId || void 0,
316
+ page,
317
+ perPage
318
+ }
319
+ )
320
+ );
321
+ });
322
+ router.get("/variables", async (req, res) => {
323
+ try {
324
+ await httpAuth.credentials(req, { allow: ["user"] });
325
+ } catch {
326
+ res.status(401).json({ message: "Unauthorized" });
327
+ return;
328
+ }
329
+ let topologyId = typeof req.query.topologyId === "string" ? req.query.topologyId.trim() : "";
330
+ const orgId = typeof req.query.orgId === "string" ? req.query.orgId.trim() : "";
331
+ const appstackName = typeof req.query.appstackName === "string" ? req.query.appstackName.trim() : "";
332
+ if (!topologyId && (!orgId || !appstackName)) {
333
+ res.status(400).json({
334
+ message: "topologyId or both orgId and appstackName query parameters are required"
335
+ });
336
+ return;
337
+ }
338
+ await proxyStackgenClientCall(
339
+ res,
340
+ logger,
341
+ "Variables proxy",
342
+ async () => {
343
+ if (!topologyId) {
344
+ topologyId = await topologyResolve.resolveTopologyId({
345
+ config,
346
+ teamId: orgId,
347
+ appstackName,
348
+ logger
349
+ });
350
+ }
351
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
352
+ return stackgenApis.v1TfBlocksApiObj.getTFVariables({
353
+ topologyId,
354
+ orgId: orgId || void 0
355
+ });
356
+ }
357
+ );
358
+ });
359
+ httpRouter.use(router);
360
+ }
361
+ });
362
+ }
363
+ });
364
+
365
+ exports.stackgenUiProxiesModule = stackgenUiProxiesModule;
366
+ //# sourceMappingURL=stackgenUiProxiesModule.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stackgenUiProxiesModule.cjs.js","sources":["../../src/modules/stackgenUiProxiesModule.ts"],"sourcesContent":["import {\n coreServices,\n createBackendModule,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport express, { Request, Response } from 'express';\nimport { listGitExporterConfigs } from '../exporter/gitExporterConfigHttp';\nimport {\n resolveExporterAppstackId,\n resolveTopologyId,\n} from '../exporter/topologyResolve';\nimport {\n formatApiFailure,\n formatClientErrorMessage,\n getStackgenApiObjects,\n readClientError,\n} from '../utils/api-objects';\n\nasync function proxyStackgenClientCall(\n res: Response,\n logger: LoggerService,\n operation: string,\n call: () => Promise<unknown>,\n): Promise<void> {\n try {\n const body = await call();\n res.status(200).json(body);\n } catch (error) {\n const parsedError = await readClientError(error);\n if (parsedError.status === 500 && parsedError.text === String(error)) {\n logger.error(\n `${operation} failed: ${formatApiFailure(\n parsedError.status,\n parsedError.body,\n parsedError.text,\n parsedError.requestId,\n )}`,\n );\n res.status(502).json({ message: `${operation} failed` });\n return;\n }\n\n if (parsedError.requestId) {\n res.setHeader('x-request-id', parsedError.requestId);\n }\n\n const payload =\n parsedError.body && typeof parsedError.body === 'object'\n ? parsedError.body\n : { message: parsedError.text || `${operation} failed` };\n res.status(parsedError.status).json(payload);\n }\n}\n\n/**\n * Proxies StackGen HTTP APIs used by scaffolder custom fields\n * (`/vault-secrets`, `/environment-profiles`, `/users`, `/user-groups`,\n * `/modules`, `/variables`, `/exporter-git-configs`, `/export-history`).\n * Mounted on the stackgen backend plugin HTTP router.\n */\nexport const stackgenUiProxiesModule = createBackendModule({\n pluginId: 'stackgen',\n moduleId: 'stackgen-ui-proxies',\n register(env) {\n env.registerInit({\n deps: {\n httpRouter: coreServices.httpRouter,\n config: coreServices.rootConfig,\n logger: coreServices.logger,\n httpAuth: coreServices.httpAuth,\n },\n async init({ httpRouter, config, logger, httpAuth }) {\n const router = express.Router();\n router.use(express.json());\n\n router.get('/vault-secrets', async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const orgId =\n typeof req.query.orgId === 'string' ? req.query.orgId.trim() : '';\n\n const stackgenApis = getStackgenApiObjects(config);\n logger.info('Vault secrets proxy via generated client');\n await proxyStackgenClientCall(res, logger, 'Vault secrets proxy', () =>\n stackgenApis.vaultSecretApiObj.getSecrets({\n orgId: orgId || undefined,\n category:\n typeof req.query.category === 'string'\n ? req.query.category\n : undefined,\n subcategory:\n typeof req.query.subcategory === 'string'\n ? (req.query.subcategory as never)\n : undefined,\n name:\n typeof req.query.name === 'string' ? req.query.name : undefined,\n }),\n );\n });\n\n router.get(\n '/exporter-git-configs/:id',\n async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const orgId =\n typeof req.query.orgId === 'string' ? req.query.orgId.trim() : '';\n if (!orgId) {\n res\n .status(400)\n .json({ message: 'orgId query parameter is required' });\n return;\n }\n\n const configId =\n typeof req.params.id === 'string' ? req.params.id.trim() : '';\n if (!configId) {\n res.status(400).json({ message: 'config id is required' });\n return;\n }\n\n const stackgenApis = getStackgenApiObjects(config);\n await proxyStackgenClientCall(\n res,\n logger,\n 'Exporter config detail proxy',\n async () => {\n const body = await stackgenApis.exporterConfigApiObj.getConfig({\n id: configId,\n orgId,\n });\n const parameters =\n body?.parameters && typeof body.parameters === 'object'\n ? body.parameters\n : {};\n return {\n id: body?.id ?? configId,\n name: body?.name,\n parameters,\n };\n },\n );\n },\n );\n\n router.get(\n '/exporter-git-configs',\n async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const orgId =\n typeof req.query.orgId === 'string' ? req.query.orgId : '';\n if (!orgId.trim()) {\n res\n .status(400)\n .json({ message: 'orgId query parameter is required' });\n return;\n }\n\n const appstackId =\n typeof req.query.appstackId === 'string'\n ? req.query.appstackId.trim()\n : '';\n const appstackName =\n typeof req.query.appstackName === 'string'\n ? req.query.appstackName.trim()\n : '';\n\n await proxyStackgenClientCall(\n res,\n logger,\n 'Exporter configs proxy',\n async () => {\n // Configs bind to appcd appstackId. Resolve from name/id via getAppStacks.\n let filterAppstackId = appstackId || undefined;\n if (appstackName || appstackId) {\n try {\n filterAppstackId = await resolveExporterAppstackId({\n config,\n teamId: orgId.trim(),\n appstackId: appstackId || undefined,\n appstackName: appstackName || undefined,\n logger,\n });\n } catch (error) {\n logger.warn(\n `Could not resolve exporter appstackId: ${await formatClientErrorMessage(error)}`,\n );\n filterAppstackId = undefined;\n }\n }\n\n return listGitExporterConfigs(\n config,\n {\n orgId: orgId.trim(),\n type: 'git',\n appstackId: filterAppstackId,\n },\n logger,\n );\n },\n );\n },\n );\n\n router.get('/export-history', async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const orgId =\n typeof req.query.orgId === 'string' ? req.query.orgId.trim() : '';\n const appstackName =\n typeof req.query.appstackName === 'string'\n ? req.query.appstackName.trim()\n : '';\n if (!orgId) {\n res\n .status(400)\n .json({ message: 'orgId query parameter is required' });\n return;\n }\n if (!appstackName) {\n res\n .status(400)\n .json({ message: 'appstackName query parameter is required' });\n return;\n }\n\n const limitRaw =\n typeof req.query.limit === 'string' ? Number(req.query.limit) : 1;\n const limit =\n Number.isFinite(limitRaw) && limitRaw > 0\n ? Math.min(Math.floor(limitRaw), 50)\n : 1;\n\n const stackgenApis = getStackgenApiObjects(config);\n await proxyStackgenClientCall(\n res,\n logger,\n 'Export history proxy',\n async () => {\n const topologyId = await resolveTopologyId({\n config,\n teamId: orgId,\n appstackName,\n logger,\n });\n const history =\n await stackgenApis.exporterApiObj.getExportHistory({\n orgId,\n topologyIds: [topologyId],\n limit,\n });\n const first = Array.isArray(history?.records)\n ? history.records[0]\n : undefined;\n const head =\n typeof first?.metadata?.head === 'string'\n ? first.metadata.head.trim()\n : '';\n return {\n topologyId,\n ...(head ? { head } : {}),\n };\n },\n );\n });\n\n /**\n * Proxies used by scaffolder custom field extensions\n * (EnvironmentSelect, UserGroupSelect, ModuleSelect, VariableSelect).\n */\n router.get(\n '/environment-profiles',\n async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const orgId =\n typeof req.query.orgId === 'string' ? req.query.orgId.trim() : '';\n let topologyId =\n typeof req.query.topologyId === 'string'\n ? req.query.topologyId.trim()\n : '';\n const appstackName =\n typeof req.query.appstackName === 'string'\n ? req.query.appstackName.trim()\n : '';\n\n await proxyStackgenClientCall(\n res,\n logger,\n 'Environment profiles proxy',\n async () => {\n if (!topologyId && orgId && appstackName) {\n topologyId = await resolveTopologyId({\n config,\n teamId: orgId,\n appstackName,\n logger,\n });\n }\n const stackgenApis = getStackgenApiObjects(config);\n return stackgenApis.v1EnvironmentProfileApiObj.getAllEnvProfiles(\n {\n orgId: orgId || undefined,\n topologyID: topologyId || undefined,\n },\n );\n },\n );\n },\n );\n\n router.get('/users', async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const orgId =\n typeof req.query.orgId === 'string' ? req.query.orgId.trim() : '';\n const stackgenApis = getStackgenApiObjects(config);\n await proxyStackgenClientCall(res, logger, 'Users proxy', () =>\n stackgenApis.usersApiObj.listUsers({\n orgID: orgId || undefined,\n }),\n );\n });\n\n router.get('/me', async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const stackgenApis = getStackgenApiObjects(config);\n await proxyStackgenClientCall(res, logger, 'Current user proxy', () =>\n stackgenApis.authenticationApiObject.getMe(),\n );\n });\n\n router.get('/user-groups', async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const includeMembers =\n typeof req.query.includeMembers === 'string'\n ? req.query.includeMembers === 'true'\n : true;\n const stackgenApis = getStackgenApiObjects(config);\n await proxyStackgenClientCall(res, logger, 'User groups proxy', () =>\n stackgenApis.userGroupApiObj.listUserGroups({\n includeMembers,\n }),\n );\n });\n\n router.get('/modules', async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n const orgId =\n typeof req.query.orgId === 'string' ? req.query.orgId.trim() : '';\n const pageRaw =\n typeof req.query.page === 'string' ? Number(req.query.page) : 1;\n const perPageRaw =\n typeof req.query.perPage === 'string'\n ? Number(req.query.perPage)\n : 100;\n const page =\n Number.isFinite(pageRaw) && pageRaw > 0 ? Math.floor(pageRaw) : 1;\n const perPage =\n Number.isFinite(perPageRaw) && perPageRaw > 0\n ? Math.min(Math.floor(perPageRaw), 100)\n : 100;\n\n const stackgenApis = getStackgenApiObjects(config);\n await proxyStackgenClientCall(res, logger, 'Modules proxy', () =>\n stackgenApis.v1CustomResourceTemplateApiObj.getAccessibleCustomResourceTemplates(\n {\n orgId: orgId || undefined,\n page,\n perPage,\n },\n ),\n );\n });\n\n router.get('/variables', async (req: Request, res: Response) => {\n try {\n await httpAuth.credentials(req, { allow: ['user'] });\n } catch {\n res.status(401).json({ message: 'Unauthorized' });\n return;\n }\n\n let topologyId =\n typeof req.query.topologyId === 'string'\n ? req.query.topologyId.trim()\n : '';\n const orgId =\n typeof req.query.orgId === 'string' ? req.query.orgId.trim() : '';\n const appstackName =\n typeof req.query.appstackName === 'string'\n ? req.query.appstackName.trim()\n : '';\n\n if (!topologyId && (!orgId || !appstackName)) {\n res.status(400).json({\n message:\n 'topologyId or both orgId and appstackName query parameters are required',\n });\n return;\n }\n\n await proxyStackgenClientCall(\n res,\n logger,\n 'Variables proxy',\n async () => {\n if (!topologyId) {\n topologyId = await resolveTopologyId({\n config,\n teamId: orgId,\n appstackName,\n logger,\n });\n }\n const stackgenApis = getStackgenApiObjects(config);\n return stackgenApis.v1TfBlocksApiObj.getTFVariables({\n topologyId,\n orgId: orgId || undefined,\n });\n },\n );\n });\n\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["readClientError","formatApiFailure","createBackendModule","coreServices","express","getStackgenApiObjects","resolveExporterAppstackId","formatClientErrorMessage","listGitExporterConfigs","resolveTopologyId"],"mappings":";;;;;;;;;;;;AAkBA,eAAe,uBAAA,CACb,GAAA,EACA,MAAA,EACA,SAAA,EACA,IAAA,EACe;AACf,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,EAAK;AACxB,IAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3B,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,WAAA,GAAc,MAAMA,0BAAA,CAAgB,KAAK,CAAA;AAC/C,IAAA,IAAI,YAAY,MAAA,KAAW,GAAA,IAAO,YAAY,IAAA,KAAS,MAAA,CAAO,KAAK,CAAA,EAAG;AACpE,MAAA,MAAA,CAAO,KAAA;AAAA,QACL,CAAA,EAAG,SAAS,CAAA,SAAA,EAAYC,2BAAA;AAAA,UACtB,WAAA,CAAY,MAAA;AAAA,UACZ,WAAA,CAAY,IAAA;AAAA,UACZ,WAAA,CAAY,IAAA;AAAA,UACZ,WAAA,CAAY;AAAA,SACb,CAAA;AAAA,OACH;AACA,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,OAAA,CAAA,EAAW,CAAA;AACvD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,YAAY,SAAA,EAAW;AACzB,MAAA,GAAA,CAAI,SAAA,CAAU,cAAA,EAAgB,WAAA,CAAY,SAAS,CAAA;AAAA,IACrD;AAEA,IAAA,MAAM,OAAA,GACJ,WAAA,CAAY,IAAA,IAAQ,OAAO,YAAY,IAAA,KAAS,QAAA,GAC5C,WAAA,CAAY,IAAA,GACZ,EAAE,OAAA,EAAS,WAAA,CAAY,IAAA,IAAQ,CAAA,EAAG,SAAS,CAAA,OAAA,CAAA,EAAU;AAC3D,IAAA,GAAA,CAAI,MAAA,CAAO,WAAA,CAAY,MAAM,CAAA,CAAE,KAAK,OAAO,CAAA;AAAA,EAC7C;AACF;AAQO,MAAM,0BAA0BC,oCAAA,CAAoB;AAAA,EACzD,QAAA,EAAU,UAAA;AAAA,EACV,QAAA,EAAU,qBAAA;AAAA,EACV,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,YAAA,CAAa;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,YAAYC,6BAAA,CAAa,UAAA;AAAA,QACzB,QAAQA,6BAAA,CAAa,UAAA;AAAA,QACrB,QAAQA,6BAAA,CAAa,MAAA;AAAA,QACrB,UAAUA,6BAAA,CAAa;AAAA,OACzB;AAAA,MACA,MAAM,IAAA,CAAK,EAAE,YAAY,MAAA,EAAQ,MAAA,EAAQ,UAAS,EAAG;AACnD,QAAA,MAAM,MAAA,GAASC,yBAAQ,MAAA,EAAO;AAC9B,QAAA,MAAA,CAAO,GAAA,CAAIA,wBAAA,CAAQ,IAAA,EAAM,CAAA;AAEzB,QAAA,MAAA,CAAO,GAAA,CAAI,gBAAA,EAAkB,OAAO,GAAA,EAAc,GAAA,KAAkB;AAClE,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,UACrD,CAAA,CAAA,MAAQ;AACN,YAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,KAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,KAAA,KAAU,WAAW,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK,GAAI,EAAA;AAEjE,UAAA,MAAM,YAAA,GAAeC,iCAAsB,MAAM,CAAA;AACjD,UAAA,MAAA,CAAO,KAAK,0CAA0C,CAAA;AACtD,UAAA,MAAM,uBAAA;AAAA,YAAwB,GAAA;AAAA,YAAK,MAAA;AAAA,YAAQ,qBAAA;AAAA,YAAuB,MAChE,YAAA,CAAa,iBAAA,CAAkB,UAAA,CAAW;AAAA,cACxC,OAAO,KAAA,IAAS,KAAA,CAAA;AAAA,cAChB,QAAA,EACE,OAAO,GAAA,CAAI,KAAA,CAAM,aAAa,QAAA,GAC1B,GAAA,CAAI,MAAM,QAAA,GACV,KAAA,CAAA;AAAA,cACN,WAAA,EACE,OAAO,GAAA,CAAI,KAAA,CAAM,gBAAgB,QAAA,GAC5B,GAAA,CAAI,MAAM,WAAA,GACX,KAAA,CAAA;AAAA,cACN,IAAA,EACE,OAAO,GAAA,CAAI,KAAA,CAAM,SAAS,QAAA,GAAW,GAAA,CAAI,MAAM,IAAA,GAAO,KAAA;AAAA,aACzD;AAAA,WACH;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAA,CAAO,GAAA;AAAA,UACL,2BAAA;AAAA,UACA,OAAO,KAAc,GAAA,KAAkB;AACrC,YAAA,IAAI;AACF,cAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,YACrD,CAAA,CAAA,MAAQ;AACN,cAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,KAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,KAAA,KAAU,WAAW,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK,GAAI,EAAA;AACjE,YAAA,IAAI,CAAC,KAAA,EAAO;AACV,cAAA,GAAA,CACG,OAAO,GAAG,CAAA,CACV,KAAK,EAAE,OAAA,EAAS,qCAAqC,CAAA;AACxD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,QAAA,GACJ,OAAO,GAAA,CAAI,MAAA,CAAO,EAAA,KAAO,WAAW,GAAA,CAAI,MAAA,CAAO,EAAA,CAAG,IAAA,EAAK,GAAI,EAAA;AAC7D,YAAA,IAAI,CAAC,QAAA,EAAU;AACb,cAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,yBAAyB,CAAA;AACzD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,YAAA,GAAeA,iCAAsB,MAAM,CAAA;AACjD,YAAA,MAAM,uBAAA;AAAA,cACJ,GAAA;AAAA,cACA,MAAA;AAAA,cACA,8BAAA;AAAA,cACA,YAAY;AACV,gBAAA,MAAM,IAAA,GAAO,MAAM,YAAA,CAAa,oBAAA,CAAqB,SAAA,CAAU;AAAA,kBAC7D,EAAA,EAAI,QAAA;AAAA,kBACJ;AAAA,iBACD,CAAA;AACD,gBAAA,MAAM,UAAA,GACJ,MAAM,UAAA,IAAc,OAAO,KAAK,UAAA,KAAe,QAAA,GAC3C,IAAA,CAAK,UAAA,GACL,EAAC;AACP,gBAAA,OAAO;AAAA,kBACL,EAAA,EAAI,MAAM,EAAA,IAAM,QAAA;AAAA,kBAChB,MAAM,IAAA,EAAM,IAAA;AAAA,kBACZ;AAAA,iBACF;AAAA,cACF;AAAA,aACF;AAAA,UACF;AAAA,SACF;AAEA,QAAA,MAAA,CAAO,GAAA;AAAA,UACL,uBAAA;AAAA,UACA,OAAO,KAAc,GAAA,KAAkB;AACrC,YAAA,IAAI;AACF,cAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,YACrD,CAAA,CAAA,MAAQ;AACN,cAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,KAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,UAAU,QAAA,GAAW,GAAA,CAAI,MAAM,KAAA,GAAQ,EAAA;AAC1D,YAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAK,EAAG;AACjB,cAAA,GAAA,CACG,OAAO,GAAG,CAAA,CACV,KAAK,EAAE,OAAA,EAAS,qCAAqC,CAAA;AACxD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,UAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,UAAA,KAAe,WAC5B,GAAA,CAAI,KAAA,CAAM,UAAA,CAAW,IAAA,EAAK,GAC1B,EAAA;AACN,YAAA,MAAM,YAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,YAAA,KAAiB,WAC9B,GAAA,CAAI,KAAA,CAAM,YAAA,CAAa,IAAA,EAAK,GAC5B,EAAA;AAEN,YAAA,MAAM,uBAAA;AAAA,cACJ,GAAA;AAAA,cACA,MAAA;AAAA,cACA,wBAAA;AAAA,cACA,YAAY;AAEV,gBAAA,IAAI,mBAAmB,UAAA,IAAc,KAAA,CAAA;AACrC,gBAAA,IAAI,gBAAgB,UAAA,EAAY;AAC9B,kBAAA,IAAI;AACF,oBAAA,gBAAA,GAAmB,MAAMC,yCAAA,CAA0B;AAAA,sBACjD,MAAA;AAAA,sBACA,MAAA,EAAQ,MAAM,IAAA,EAAK;AAAA,sBACnB,YAAY,UAAA,IAAc,KAAA,CAAA;AAAA,sBAC1B,cAAc,YAAA,IAAgB,KAAA,CAAA;AAAA,sBAC9B;AAAA,qBACD,CAAA;AAAA,kBACH,SAAS,KAAA,EAAO;AACd,oBAAA,MAAA,CAAO,IAAA;AAAA,sBACL,CAAA,uCAAA,EAA0C,MAAMC,mCAAA,CAAyB,KAAK,CAAC,CAAA;AAAA,qBACjF;AACA,oBAAA,gBAAA,GAAmB,KAAA,CAAA;AAAA,kBACrB;AAAA,gBACF;AAEA,gBAAA,OAAOC,4CAAA;AAAA,kBACL,MAAA;AAAA,kBACA;AAAA,oBACE,KAAA,EAAO,MAAM,IAAA,EAAK;AAAA,oBAClB,IAAA,EAAM,KAAA;AAAA,oBACN,UAAA,EAAY;AAAA,mBACd;AAAA,kBACA;AAAA,iBACF;AAAA,cACF;AAAA,aACF;AAAA,UACF;AAAA,SACF;AAEA,QAAA,MAAA,CAAO,GAAA,CAAI,iBAAA,EAAmB,OAAO,GAAA,EAAc,GAAA,KAAkB;AACnE,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,UACrD,CAAA,CAAA,MAAQ;AACN,YAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,KAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,KAAA,KAAU,WAAW,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK,GAAI,EAAA;AACjE,UAAA,MAAM,YAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,YAAA,KAAiB,WAC9B,GAAA,CAAI,KAAA,CAAM,YAAA,CAAa,IAAA,EAAK,GAC5B,EAAA;AACN,UAAA,IAAI,CAAC,KAAA,EAAO;AACV,YAAA,GAAA,CACG,OAAO,GAAG,CAAA,CACV,KAAK,EAAE,OAAA,EAAS,qCAAqC,CAAA;AACxD,YAAA;AAAA,UACF;AACA,UAAA,IAAI,CAAC,YAAA,EAAc;AACjB,YAAA,GAAA,CACG,OAAO,GAAG,CAAA,CACV,KAAK,EAAE,OAAA,EAAS,4CAA4C,CAAA;AAC/D,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,QAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,KAAA,KAAU,WAAW,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,GAAI,CAAA;AAClE,UAAA,MAAM,KAAA,GACJ,MAAA,CAAO,QAAA,CAAS,QAAQ,KAAK,QAAA,GAAW,CAAA,GACpC,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA,EAAG,EAAE,CAAA,GACjC,CAAA;AAEN,UAAA,MAAM,YAAA,GAAeH,iCAAsB,MAAM,CAAA;AACjD,UAAA,MAAM,uBAAA;AAAA,YACJ,GAAA;AAAA,YACA,MAAA;AAAA,YACA,sBAAA;AAAA,YACA,YAAY;AACV,cAAA,MAAM,UAAA,GAAa,MAAMI,iCAAA,CAAkB;AAAA,gBACzC,MAAA;AAAA,gBACA,MAAA,EAAQ,KAAA;AAAA,gBACR,YAAA;AAAA,gBACA;AAAA,eACD,CAAA;AACD,cAAA,MAAM,OAAA,GACJ,MAAM,YAAA,CAAa,cAAA,CAAe,gBAAA,CAAiB;AAAA,gBACjD,KAAA;AAAA,gBACA,WAAA,EAAa,CAAC,UAAU,CAAA;AAAA,gBACxB;AAAA,eACD,CAAA;AACH,cAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,OAAA,EAAS,OAAO,CAAA,GACxC,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,GACjB,KAAA,CAAA;AACJ,cAAA,MAAM,IAAA,GACJ,OAAO,KAAA,EAAO,QAAA,EAAU,IAAA,KAAS,WAC7B,KAAA,CAAM,QAAA,CAAS,IAAA,CAAK,IAAA,EAAK,GACzB,EAAA;AACN,cAAA,OAAO;AAAA,gBACL,UAAA;AAAA,gBACA,GAAI,IAAA,GAAO,EAAE,IAAA,KAAS;AAAC,eACzB;AAAA,YACF;AAAA,WACF;AAAA,QACF,CAAC,CAAA;AAMD,QAAA,MAAA,CAAO,GAAA;AAAA,UACL,uBAAA;AAAA,UACA,OAAO,KAAc,GAAA,KAAkB;AACrC,YAAA,IAAI;AACF,cAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,YACrD,CAAA,CAAA,MAAQ;AACN,cAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,KAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,KAAA,KAAU,WAAW,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK,GAAI,EAAA;AACjE,YAAA,IAAI,UAAA,GACF,OAAO,GAAA,CAAI,KAAA,CAAM,UAAA,KAAe,WAC5B,GAAA,CAAI,KAAA,CAAM,UAAA,CAAW,IAAA,EAAK,GAC1B,EAAA;AACN,YAAA,MAAM,YAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,YAAA,KAAiB,WAC9B,GAAA,CAAI,KAAA,CAAM,YAAA,CAAa,IAAA,EAAK,GAC5B,EAAA;AAEN,YAAA,MAAM,uBAAA;AAAA,cACJ,GAAA;AAAA,cACA,MAAA;AAAA,cACA,4BAAA;AAAA,cACA,YAAY;AACV,gBAAA,IAAI,CAAC,UAAA,IAAc,KAAA,IAAS,YAAA,EAAc;AACxC,kBAAA,UAAA,GAAa,MAAMA,iCAAA,CAAkB;AAAA,oBACnC,MAAA;AAAA,oBACA,MAAA,EAAQ,KAAA;AAAA,oBACR,YAAA;AAAA,oBACA;AAAA,mBACD,CAAA;AAAA,gBACH;AACA,gBAAA,MAAM,YAAA,GAAeJ,iCAAsB,MAAM,CAAA;AACjD,gBAAA,OAAO,aAAa,0BAAA,CAA2B,iBAAA;AAAA,kBAC7C;AAAA,oBACE,OAAO,KAAA,IAAS,KAAA,CAAA;AAAA,oBAChB,YAAY,UAAA,IAAc,KAAA;AAAA;AAC5B,iBACF;AAAA,cACF;AAAA,aACF;AAAA,UACF;AAAA,SACF;AAEA,QAAA,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,OAAO,GAAA,EAAc,GAAA,KAAkB;AAC1D,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,UACrD,CAAA,CAAA,MAAQ;AACN,YAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,KAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,KAAA,KAAU,WAAW,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK,GAAI,EAAA;AACjE,UAAA,MAAM,YAAA,GAAeA,iCAAsB,MAAM,CAAA;AACjD,UAAA,MAAM,uBAAA;AAAA,YAAwB,GAAA;AAAA,YAAK,MAAA;AAAA,YAAQ,aAAA;AAAA,YAAe,MACxD,YAAA,CAAa,WAAA,CAAY,SAAA,CAAU;AAAA,cACjC,OAAO,KAAA,IAAS,KAAA;AAAA,aACjB;AAAA,WACH;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,OAAO,GAAA,EAAc,GAAA,KAAkB;AACvD,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,UACrD,CAAA,CAAA,MAAQ;AACN,YAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,YAAA,GAAeA,iCAAsB,MAAM,CAAA;AACjD,UAAA,MAAM,uBAAA;AAAA,YAAwB,GAAA;AAAA,YAAK,MAAA;AAAA,YAAQ,oBAAA;AAAA,YAAsB,MAC/D,YAAA,CAAa,uBAAA,CAAwB,KAAA;AAAM,WAC7C;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAA,CAAO,GAAA,CAAI,cAAA,EAAgB,OAAO,GAAA,EAAc,GAAA,KAAkB;AAChE,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,UACrD,CAAA,CAAA,MAAQ;AACN,YAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,cAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,mBAAmB,QAAA,GAChC,GAAA,CAAI,KAAA,CAAM,cAAA,KAAmB,MAAA,GAC7B,IAAA;AACN,UAAA,MAAM,YAAA,GAAeA,iCAAsB,MAAM,CAAA;AACjD,UAAA,MAAM,uBAAA;AAAA,YAAwB,GAAA;AAAA,YAAK,MAAA;AAAA,YAAQ,mBAAA;AAAA,YAAqB,MAC9D,YAAA,CAAa,eAAA,CAAgB,cAAA,CAAe;AAAA,cAC1C;AAAA,aACD;AAAA,WACH;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,OAAO,GAAA,EAAc,GAAA,KAAkB;AAC5D,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,UACrD,CAAA,CAAA,MAAQ;AACN,YAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,KAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,KAAA,KAAU,WAAW,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK,GAAI,EAAA;AACjE,UAAA,MAAM,OAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,IAAA,KAAS,WAAW,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,GAAI,CAAA;AAChE,UAAA,MAAM,UAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,OAAA,KAAY,WACzB,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA,GACxB,GAAA;AACN,UAAA,MAAM,IAAA,GACJ,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,IAAK,UAAU,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA,GAAI,CAAA;AAClE,UAAA,MAAM,OAAA,GACJ,MAAA,CAAO,QAAA,CAAS,UAAU,KAAK,UAAA,GAAa,CAAA,GACxC,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA,EAAG,GAAG,CAAA,GACpC,GAAA;AAEN,UAAA,MAAM,YAAA,GAAeA,iCAAsB,MAAM,CAAA;AACjD,UAAA,MAAM,uBAAA;AAAA,YAAwB,GAAA;AAAA,YAAK,MAAA;AAAA,YAAQ,eAAA;AAAA,YAAiB,MAC1D,aAAa,8BAAA,CAA+B,oCAAA;AAAA,cAC1C;AAAA,gBACE,OAAO,KAAA,IAAS,KAAA,CAAA;AAAA,gBAChB,IAAA;AAAA,gBACA;AAAA;AACF;AACF,WACF;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAA,CAAO,GAAA,CAAI,YAAA,EAAc,OAAO,GAAA,EAAc,GAAA,KAAkB;AAC9D,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA;AAAA,UACrD,CAAA,CAAA,MAAQ;AACN,YAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAChD,YAAA;AAAA,UACF;AAEA,UAAA,IAAI,UAAA,GACF,OAAO,GAAA,CAAI,KAAA,CAAM,UAAA,KAAe,WAC5B,GAAA,CAAI,KAAA,CAAM,UAAA,CAAW,IAAA,EAAK,GAC1B,EAAA;AACN,UAAA,MAAM,KAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,KAAA,KAAU,WAAW,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK,GAAI,EAAA;AACjE,UAAA,MAAM,YAAA,GACJ,OAAO,GAAA,CAAI,KAAA,CAAM,YAAA,KAAiB,WAC9B,GAAA,CAAI,KAAA,CAAM,YAAA,CAAa,IAAA,EAAK,GAC5B,EAAA;AAEN,UAAA,IAAI,CAAC,UAAA,KAAe,CAAC,KAAA,IAAS,CAAC,YAAA,CAAA,EAAe;AAC5C,YAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,cACnB,OAAA,EACE;AAAA,aACH,CAAA;AACD,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,uBAAA;AAAA,YACJ,GAAA;AAAA,YACA,MAAA;AAAA,YACA,iBAAA;AAAA,YACA,YAAY;AACV,cAAA,IAAI,CAAC,UAAA,EAAY;AACf,gBAAA,UAAA,GAAa,MAAMI,iCAAA,CAAkB;AAAA,kBACnC,MAAA;AAAA,kBACA,MAAA,EAAQ,KAAA;AAAA,kBACR,YAAA;AAAA,kBACA;AAAA,iBACD,CAAA;AAAA,cACH;AACA,cAAA,MAAM,YAAA,GAAeJ,iCAAsB,MAAM,CAAA;AACjD,cAAA,OAAO,YAAA,CAAa,iBAAiB,cAAA,CAAe;AAAA,gBAClD,UAAA;AAAA,gBACA,OAAO,KAAA,IAAS,KAAA;AAAA,eACjB,CAAA;AAAA,YACH;AAAA,WACF;AAAA,QACF,CAAC,CAAA;AAED,QAAA,UAAA,CAAW,IAAI,MAAM,CAAA;AAAA,MACvB;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAC;;;;"}
@@ -0,0 +1,136 @@
1
+ 'use strict';
2
+
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
4
+ var path = require('path');
5
+ var router = require('./router.cjs.js');
6
+ var mappingsService = require('../services/MappingsService/mappingsService.cjs.js');
7
+ var stackgenService = require('../services/StackgenService/stackgenService.cjs.js');
8
+ var crypto = require('crypto');
9
+ var constants = require('../config/constants.cjs.js');
10
+
11
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
12
+
13
+ var path__default = /*#__PURE__*/_interopDefaultCompat(path);
14
+ var crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto);
15
+
16
+ async function applyDatabaseMigrations(knex) {
17
+ let migrationsDir;
18
+ try {
19
+ migrationsDir = backendPluginApi.resolvePackagePath(
20
+ "@stackgenhq/backstage-plugin-stackgen-backend",
21
+ "migrations"
22
+ );
23
+ } catch {
24
+ migrationsDir = path__default.default.resolve(__dirname, "../../migrations");
25
+ }
26
+ try {
27
+ await knex.migrate.latest({
28
+ directory: migrationsDir
29
+ });
30
+ const hasMappingsTable = await knex.schema.hasTable("mappings");
31
+ if (!hasMappingsTable) {
32
+ throw new Error("Mappings table was not created by migrations");
33
+ }
34
+ } catch (error) {
35
+ console.error("Migration failed:", error);
36
+ throw error;
37
+ }
38
+ }
39
+ async function initDefaultMapping(knex) {
40
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
41
+ const cloudProviderMappings = [
42
+ {
43
+ id: crypto__default.default.randomUUID(),
44
+ name: "default_aws",
45
+ cloudProvider: constants.AWSCloudProvider,
46
+ typeAssociations: [
47
+ { backstageType: "database", stackGenType: "aws_rds" },
48
+ { backstageType: "cache", stackGenType: "aws_elasticache" },
49
+ { backstageType: "service", stackGenType: "aws_ecs" }
50
+ ]
51
+ },
52
+ {
53
+ id: crypto__default.default.randomUUID(),
54
+ name: "default_gcp",
55
+ cloudProvider: constants.GCPCloudProvider,
56
+ typeAssociations: [
57
+ { backstageType: "database", stackGenType: "google_sql_db" },
58
+ { backstageType: "cache", stackGenType: "google_memcache_instance" },
59
+ {
60
+ backstageType: "service",
61
+ stackGenType: "google_cloud_run_v2_service"
62
+ }
63
+ ]
64
+ },
65
+ {
66
+ id: crypto__default.default.randomUUID(),
67
+ name: "default_azure",
68
+ cloudProvider: constants.AzureCloudProvider,
69
+ typeAssociations: [
70
+ {
71
+ backstageType: "database",
72
+ stackGenType: "azurerm_postgresql_database"
73
+ },
74
+ { backstageType: "cache", stackGenType: "azurerm_redis_cache" },
75
+ { backstageType: "service", stackGenType: "azurerm_linux_webapp" }
76
+ ]
77
+ },
78
+ {
79
+ id: crypto__default.default.randomUUID(),
80
+ name: "default_civo",
81
+ cloudProvider: constants.CIVOCloudProvider,
82
+ typeAssociations: [
83
+ { backstageType: "database", stackGenType: "civo_database" },
84
+ { backstageType: "service", stackGenType: "civo_kubernetes" }
85
+ ]
86
+ }
87
+ ];
88
+ for (const provider of cloudProviderMappings) {
89
+ const existingMapping = await knex("mappings").where({ name: provider.name }).first();
90
+ if (!existingMapping) {
91
+ await knex("mappings").insert({
92
+ id: provider.id,
93
+ name: provider.name,
94
+ cloud_provider: provider.cloudProvider,
95
+ type_associations: JSON.stringify(provider.typeAssociations),
96
+ created_by: "system",
97
+ created_at: timestamp,
98
+ updated_at: timestamp
99
+ });
100
+ }
101
+ }
102
+ }
103
+ const stackGenPlugin = backendPluginApi.createBackendPlugin({
104
+ pluginId: "stackgen",
105
+ register(env) {
106
+ env.registerInit({
107
+ deps: {
108
+ logger: backendPluginApi.coreServices.logger,
109
+ database: backendPluginApi.coreServices.database,
110
+ auth: backendPluginApi.coreServices.auth,
111
+ httpAuth: backendPluginApi.coreServices.httpAuth,
112
+ httpRouter: backendPluginApi.coreServices.httpRouter,
113
+ config: backendPluginApi.coreServices.rootConfig
114
+ },
115
+ async init({ logger, database, httpAuth, httpRouter, config }) {
116
+ const mappingService = await mappingsService.mappingsService({ logger, database });
117
+ const dbClient = await database.getClient();
118
+ await applyDatabaseMigrations(dbClient);
119
+ await initDefaultMapping(dbClient);
120
+ const stackgenService$1 = new stackgenService.StackGenService(config, logger);
121
+ httpRouter.use(
122
+ await router.createRouter({
123
+ httpAuth,
124
+ mappingService,
125
+ stackgenService: stackgenService$1
126
+ })
127
+ );
128
+ }
129
+ });
130
+ }
131
+ });
132
+
133
+ exports.applyDatabaseMigrations = applyDatabaseMigrations;
134
+ exports.initDefaultMapping = initDefaultMapping;
135
+ exports.stackGenPlugin = stackGenPlugin;
136
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["../../src/plugin/plugin.ts"],"sourcesContent":["import {\n coreServices,\n createBackendPlugin,\n resolvePackagePath,\n} from \"@backstage/backend-plugin-api\";\nimport path from \"path\";\nimport { createRouter } from \"./router\";\nimport { mappingsService } from \"../services/MappingsService\";\nimport { StackgenService } from \"../services/StackgenService\";\nimport { Knex } from \"knex\";\nimport crypto from \"crypto\";\nimport {\n AWSCloudProvider,\n AzureCloudProvider,\n CIVOCloudProvider,\n GCPCloudProvider,\n} from \"../config/constants\";\n\nexport async function applyDatabaseMigrations(knex: Knex): Promise<void> {\n let migrationsDir: string;\n try {\n migrationsDir = resolvePackagePath(\n \"@stackgenhq/backstage-plugin-stackgen-backend\",\n \"migrations\",\n );\n } catch {\n // Fallback for local/file-linked development where package name resolution may fail.\n // eslint-disable-next-line no-restricted-syntax -- intentional local/link fallback when resolvePackagePath fails\n migrationsDir = path.resolve(__dirname, \"../../migrations\");\n }\n\n try {\n // Run migrations\n await knex.migrate.latest({\n directory: migrationsDir,\n });\n\n // Verify mappings table exists\n const hasMappingsTable = await knex.schema.hasTable(\"mappings\");\n if (!hasMappingsTable) {\n throw new Error(\"Mappings table was not created by migrations\");\n }\n } catch (error) {\n console.error(\"Migration failed:\", error);\n throw error;\n }\n}\n\nexport async function initDefaultMapping(knex: Knex): Promise<void> {\n const timestamp = new Date().toISOString();\n\n const cloudProviderMappings = [\n {\n id: crypto.randomUUID(),\n name: \"default_aws\",\n cloudProvider: AWSCloudProvider,\n typeAssociations: [\n { backstageType: \"database\", stackGenType: \"aws_rds\" },\n { backstageType: \"cache\", stackGenType: \"aws_elasticache\" },\n { backstageType: \"service\", stackGenType: \"aws_ecs\" },\n ],\n },\n {\n id: crypto.randomUUID(),\n name: \"default_gcp\",\n cloudProvider: GCPCloudProvider,\n typeAssociations: [\n { backstageType: \"database\", stackGenType: \"google_sql_db\" },\n { backstageType: \"cache\", stackGenType: \"google_memcache_instance\" },\n {\n backstageType: \"service\",\n stackGenType: \"google_cloud_run_v2_service\",\n },\n ],\n },\n {\n id: crypto.randomUUID(),\n name: \"default_azure\",\n cloudProvider: AzureCloudProvider,\n typeAssociations: [\n {\n backstageType: \"database\",\n stackGenType: \"azurerm_postgresql_database\",\n },\n { backstageType: \"cache\", stackGenType: \"azurerm_redis_cache\" },\n { backstageType: \"service\", stackGenType: \"azurerm_linux_webapp\" },\n ],\n },\n {\n id: crypto.randomUUID(),\n name: \"default_civo\",\n cloudProvider: CIVOCloudProvider,\n typeAssociations: [\n { backstageType: \"database\", stackGenType: \"civo_database\" },\n { backstageType: \"service\", stackGenType: \"civo_kubernetes\" },\n ],\n },\n ];\n\n for (const provider of cloudProviderMappings) {\n const existingMapping = await knex(\"mappings\")\n .where({ name: provider.name })\n .first();\n\n if (!existingMapping) {\n await knex(\"mappings\").insert({\n id: provider.id,\n name: provider.name,\n cloud_provider: provider.cloudProvider,\n type_associations: JSON.stringify(provider.typeAssociations),\n created_by: \"system\",\n created_at: timestamp,\n updated_at: timestamp,\n });\n }\n }\n}\n\n/**\n * stackgenPlugin backend plugin\n *\n * @public\n */\nexport const stackGenPlugin = createBackendPlugin({\n pluginId: \"stackgen\",\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n database: coreServices.database,\n auth: coreServices.auth,\n httpAuth: coreServices.httpAuth,\n httpRouter: coreServices.httpRouter,\n config: coreServices.rootConfig,\n },\n async init({ logger, database, httpAuth, httpRouter, config }) {\n const mappingService = await mappingsService({ logger, database });\n\n const dbClient = await database.getClient();\n await applyDatabaseMigrations(dbClient);\n\n await initDefaultMapping(dbClient);\n const stackgenService = new StackgenService(config, logger);\n\n httpRouter.use(\n await createRouter({\n httpAuth,\n mappingService,\n stackgenService,\n })\n );\n },\n });\n },\n});\n"],"names":["resolvePackagePath","path","crypto","AWSCloudProvider","GCPCloudProvider","AzureCloudProvider","CIVOCloudProvider","createBackendPlugin","coreServices","mappingsService","stackgenService","StackgenService","createRouter"],"mappings":"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"}